Let BindToObject fail, if called with empty relative pidl.

Tests to show that it should do so.
Fix SHBrowseForFolder to not pass an empty pidl to BindToObject.
This commit is contained in:
Michael Jung 2005-06-06 10:04:15 +00:00 committed by Alexandre Julliard
parent c834e6a96f
commit 38f2ee9d04
3 changed files with 87 additions and 5 deletions

View File

@ -428,8 +428,14 @@ static LRESULT BrsFolder_Treeview_Expand( browse_info *info, NMTREEVIEWW *pnmtv
if ((pnmtv->itemNew.state & TVIS_EXPANDEDONCE))
return 0;
r = IShellFolder_BindToObject( lptvid->lpsfParent, lptvid->lpi, 0,
(REFIID)&IID_IShellFolder, (LPVOID *)&lpsf2 );
if (lptvid->lpi && lptvid->lpi->mkid.cb) {
r = IShellFolder_BindToObject( lptvid->lpsfParent, lptvid->lpi, 0,
(REFIID)&IID_IShellFolder, (LPVOID *)&lpsf2 );
} else {
lpsf2 = lptvid->lpsfParent;
r = IShellFolder_AddRef(lpsf2);
}
if (SUCCEEDED(r))
FillTreeView( info, lpsf2, lptvid->lpifq, pnmtv->itemNew.hItem, lptvid->pEnumIL);

View File

@ -239,10 +239,21 @@ HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot, LPCSTR pathRoot,
}
/***********************************************************************
* SHELL32_BindToChild
* SHELL32_BindToChild [Internal]
*
* Common code for IShellFolder_BindToObject.
* Creates a shell folder by binding to a root pidl.
*
* PARAMS
* pidlRoot [I] The parent shell folder's absolute pidl.
* pathRoot [I] Absolute dos path of the parent shell folder.
* pidlComplete [I] PIDL of the child. Relative to pidlRoot.
* riid [I] GUID of the interface, which ppvOut shall be bound to.
* ppvOut [O] A reference to the child's interface (riid).
*
* NOTES
* pidlComplete has to contain at least one non empty SHITEMID.
* This function makes special assumptions on the shell namespace, which
* means you probably can't use it for your IShellFolder implementation.
*/
HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot,
LPCSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut)
@ -252,7 +263,7 @@ HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot,
HRESULT hr;
LPITEMIDLIST pidlChild;
if (!pidlRoot || !ppvOut)
if (!pidlRoot || !ppvOut || !pidlComplete || !pidlComplete->mkid.cb)
return E_INVALIDARG;
*ppvOut = NULL;

View File

@ -150,6 +150,70 @@ void test_EnumObjects(IShellFolder *iFolder)
IMalloc_Free(ppM, idlArr[i]);
}
void test_BindToObject()
{
HRESULT hr;
UINT cChars;
IShellFolder *psfDesktop, *psfChild, *psfMyComputer, *psfSystemDir;
SHITEMID emptyitem = { 0, { 0 } };
LPITEMIDLIST pidlMyComputer, pidlSystemDir, pidlEmpty = (LPITEMIDLIST)&emptyitem;
WCHAR wszSystemDir[MAX_PATH];
WCHAR wszMyComputer[] = {
':',':','{','2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-',
'A','2','D','8','-','0','8','0','0','2','B','3','0','3','0','9','D','}',0 };
/* The following tests shows that BindToObject should fail with E_INVALIDARG if called
* with an empty pidl. This is tested for Desktop, MyComputer and the FS ShellFolder
*/
hr = SHGetDesktopFolder(&psfDesktop);
ok (SUCCEEDED(hr), "SHGetDesktopFolder failed! hr = %08lx\n", hr);
if (FAILED(hr)) return;
hr = IShellFolder_BindToObject(psfDesktop, pidlEmpty, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
ok (hr == E_INVALIDARG, "Desktop's BindToObject should fail, when called with empty pidl! hr = %08lx\n", hr);
hr = IShellFolder_ParseDisplayName(psfDesktop, NULL, NULL, wszMyComputer, NULL, &pidlMyComputer, NULL);
ok (SUCCEEDED(hr), "Desktop's ParseDisplayName failed to parse MyComputer's CLSID! hr = %08lx\n", hr);
if (FAILED(hr)) {
IShellFolder_Release(psfDesktop);
return;
}
hr = IShellFolder_BindToObject(psfDesktop, pidlMyComputer, NULL, &IID_IShellFolder, (LPVOID*)&psfMyComputer);
ok (SUCCEEDED(hr), "Desktop failed to bind to MyComputer object! hr = %08lx\n", hr);
IShellFolder_Release(psfDesktop);
ILFree(pidlMyComputer);
if (FAILED(hr)) return;
hr = IShellFolder_BindToObject(psfMyComputer, pidlEmpty, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
ok (hr == E_INVALIDARG, "MyComputers's BindToObject should fail, when called with empty pidl! hr = %08lx\n", hr);
cChars = GetSystemDirectoryW(wszSystemDir, MAX_PATH);
ok (cChars > 0 && cChars < MAX_PATH, "GetSystemDirectoryW failed! LastError: %08lx\n", GetLastError());
if (cChars == 0 || cChars >= MAX_PATH) {
IShellFolder_Release(psfMyComputer);
return;
}
hr = IShellFolder_ParseDisplayName(psfMyComputer, NULL, NULL, wszSystemDir, NULL, &pidlSystemDir, NULL);
ok (SUCCEEDED(hr), "MyComputers's ParseDisplayName failed to parse the SystemDirectory! hr = %08lx\n", hr);
if (FAILED(hr)) {
IShellFolder_Release(psfMyComputer);
return;
}
hr = IShellFolder_BindToObject(psfMyComputer, pidlSystemDir, NULL, &IID_IShellFolder, (LPVOID*)&psfSystemDir);
ok (SUCCEEDED(hr), "MyComputer failed to bind to a FileSystem ShellFolder! hr = %08lx\n", hr);
IShellFolder_Release(psfMyComputer);
ILFree(pidlSystemDir);
if (FAILED(hr)) return;
hr = IShellFolder_BindToObject(psfSystemDir, pidlEmpty, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
ok (hr == E_INVALIDARG,
"FileSystem ShellFolder's BindToObject should fail, when called with empty pidl! hr = %08lx\n", hr);
IShellFolder_Release(psfSystemDir);
}
START_TEST(shlfolder)
{
@ -179,6 +243,7 @@ START_TEST(shlfolder)
ok(hr == S_OK, "BindToObject failed %08lx\n", hr);
test_EnumObjects(testIShellFolder);
test_BindToObject();
hr = IShellFolder_Release(testIShellFolder);
ok(hr == S_OK, "IShellFolder_Release failed %08lx\n", hr);