Commit 38f2ee9d authored by Michael Jung's avatar Michael Jung Committed by Alexandre Julliard

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.
parent c834e6a9
...@@ -428,8 +428,14 @@ static LRESULT BrsFolder_Treeview_Expand( browse_info *info, NMTREEVIEWW *pnmtv ...@@ -428,8 +428,14 @@ static LRESULT BrsFolder_Treeview_Expand( browse_info *info, NMTREEVIEWW *pnmtv
if ((pnmtv->itemNew.state & TVIS_EXPANDEDONCE)) if ((pnmtv->itemNew.state & TVIS_EXPANDEDONCE))
return 0; return 0;
r = IShellFolder_BindToObject( lptvid->lpsfParent, lptvid->lpi, 0, if (lptvid->lpi && lptvid->lpi->mkid.cb) {
(REFIID)&IID_IShellFolder, (LPVOID *)&lpsf2 ); r = IShellFolder_BindToObject( lptvid->lpsfParent, lptvid->lpi, 0,
(REFIID)&IID_IShellFolder, (LPVOID *)&lpsf2 );
} else {
lpsf2 = lptvid->lpsfParent;
r = IShellFolder_AddRef(lpsf2);
}
if (SUCCEEDED(r)) if (SUCCEEDED(r))
FillTreeView( info, lpsf2, lptvid->lpifq, pnmtv->itemNew.hItem, lptvid->pEnumIL); FillTreeView( info, lpsf2, lptvid->lpifq, pnmtv->itemNew.hItem, lptvid->pEnumIL);
......
...@@ -239,10 +239,21 @@ HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot, LPCSTR pathRoot, ...@@ -239,10 +239,21 @@ HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot, LPCSTR pathRoot,
} }
/*********************************************************************** /***********************************************************************
* SHELL32_BindToChild * SHELL32_BindToChild [Internal]
* *
* Common code for IShellFolder_BindToObject. * 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, HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot,
LPCSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut) LPCSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut)
...@@ -252,7 +263,7 @@ HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot, ...@@ -252,7 +263,7 @@ HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot,
HRESULT hr; HRESULT hr;
LPITEMIDLIST pidlChild; LPITEMIDLIST pidlChild;
if (!pidlRoot || !ppvOut) if (!pidlRoot || !ppvOut || !pidlComplete || !pidlComplete->mkid.cb)
return E_INVALIDARG; return E_INVALIDARG;
*ppvOut = NULL; *ppvOut = NULL;
......
...@@ -150,6 +150,70 @@ void test_EnumObjects(IShellFolder *iFolder) ...@@ -150,6 +150,70 @@ void test_EnumObjects(IShellFolder *iFolder)
IMalloc_Free(ppM, idlArr[i]); 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) START_TEST(shlfolder)
{ {
...@@ -179,6 +243,7 @@ START_TEST(shlfolder) ...@@ -179,6 +243,7 @@ START_TEST(shlfolder)
ok(hr == S_OK, "BindToObject failed %08lx\n", hr); ok(hr == S_OK, "BindToObject failed %08lx\n", hr);
test_EnumObjects(testIShellFolder); test_EnumObjects(testIShellFolder);
test_BindToObject();
hr = IShellFolder_Release(testIShellFolder); hr = IShellFolder_Release(testIShellFolder);
ok(hr == S_OK, "IShellFolder_Release failed %08lx\n", hr); ok(hr == S_OK, "IShellFolder_Release failed %08lx\n", hr);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment