Based on SHBindToParent and SHBindToObject implementations.
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/shell32/pidl.c | 56 +++++++++++++++++++++++++++++++++++++++ dlls/shell32/shell32.spec | 1 + 2 files changed, 57 insertions(+)
diff --git a/dlls/shell32/pidl.c b/dlls/shell32/pidl.c index f9c91a79132..f004b2ff1b6 100644 --- a/dlls/shell32/pidl.c +++ b/dlls/shell32/pidl.c @@ -1364,6 +1364,62 @@ HRESULT WINAPI SHBindToObject(IShellFolder *psf, LPCITEMIDLIST pidl, IBindCtx *p }
+HRESULT WINAPI SHBindToFolderIDListParent(IShellFolder *psf, LPCITEMIDLIST pidl, + REFIID riid, void **ppv, LPCITEMIDLIST *ppidlLast) +{ + IShellFolder *psfDesktop = NULL; + LPITEMIDLIST pidlChild; + LPITEMIDLIST pidlParent; + HRESULT hr; + + TRACE_(shell)("%p,%p,%s,%p,%p\n", psf, pidl, debugstr_guid(riid), ppv, ppidlLast); + pdump(pidl); + + if (!ppv) + return E_INVALIDARG; + + *ppv = NULL; + + if (!psf) + { + hr = SHGetDesktopFolder(&psfDesktop); + if (FAILED(hr)) + return hr; + psf = psfDesktop; + } + + if (ppidlLast) + *ppidlLast = NULL; + + if (_ILIsPidlSimple(pidl)) + { + /* we are on desktop level */ + if (ppidlLast) + *ppidlLast = ILClone(pidl); + hr = SHGetDesktopFolder((IShellFolder **)ppv); + } + else + { + pidlChild = ILClone(ILFindLastID(pidl)); + pidlParent = ILClone(pidl); + ILRemoveLastID(pidlParent); + + hr = IShellFolder_BindToObject(psf, pidlParent, NULL, riid, ppv); + if (SUCCEEDED(hr) && ppidlLast) + *ppidlLast = pidlChild; + else + ILFree(pidlChild); + ILFree(pidlParent); + } + + if (psfDesktop) + IShellFolder_Release(psfDesktop); + + TRACE_(shell)("-- ppv=%p ret=0x%08lx\n", *ppv, hr); + return hr; +} + + /************************************************************************* * SHParseDisplayName [SHELL32.@] */ diff --git a/dlls/shell32/shell32.spec b/dlls/shell32/shell32.spec index f8bf8f246e8..5b812774e1f 100644 --- a/dlls/shell32/shell32.spec +++ b/dlls/shell32/shell32.spec @@ -334,6 +334,7 @@ @ stdcall SHAssocEnumHandlers(wstr long ptr) @ stdcall SHBindToObject(ptr ptr ptr ptr ptr) @ stdcall SHBindToParent(ptr ptr ptr ptr) +@ stdcall SHBindToFolderIDListParent(ptr ptr ptr ptr ptr) @ stdcall SHBrowseForFolder(ptr) SHBrowseForFolderA @ stdcall SHBrowseForFolderA(ptr) @ stdcall SHBrowseForFolderW(ptr)
On 6/9/22 14:47, Dmitry Timoshkov wrote:
Based on SHBindToParent and SHBindToObject implementations.
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru
dlls/shell32/pidl.c | 56 +++++++++++++++++++++++++++++++++++++++ dlls/shell32/shell32.spec | 1 + 2 files changed, 57 insertions(+)
diff --git a/dlls/shell32/pidl.c b/dlls/shell32/pidl.c index f9c91a79132..f004b2ff1b6 100644 --- a/dlls/shell32/pidl.c +++ b/dlls/shell32/pidl.c @@ -1364,6 +1364,62 @@ HRESULT WINAPI SHBindToObject(IShellFolder *psf, LPCITEMIDLIST pidl, IBindCtx *p }
+HRESULT WINAPI SHBindToFolderIDListParent(IShellFolder *psf, LPCITEMIDLIST pidl,
- REFIID riid, void **ppv, LPCITEMIDLIST *ppidlLast)
+{
- IShellFolder *psfDesktop = NULL;
- LPITEMIDLIST pidlChild;
- LPITEMIDLIST pidlParent;
- HRESULT hr;
- TRACE_(shell)("%p,%p,%s,%p,%p\n", psf, pidl, debugstr_guid(riid), ppv, ppidlLast);
- pdump(pidl);
- if (!ppv)
return E_INVALIDARG;
- *ppv = NULL;
- if (!psf)
- {
hr = SHGetDesktopFolder(&psfDesktop);
if (FAILED(hr))
return hr;
psf = psfDesktop;
- }
- if (ppidlLast)
*ppidlLast = NULL;
- if (_ILIsPidlSimple(pidl))
- {
/* we are on desktop level */
if (ppidlLast)
*ppidlLast = ILClone(pidl);
hr = SHGetDesktopFolder((IShellFolder **)ppv);
- }
- else
- {
pidlChild = ILClone(ILFindLastID(pidl));
pidlParent = ILClone(pidl);
ILRemoveLastID(pidlParent);
hr = IShellFolder_BindToObject(psf, pidlParent, NULL, riid, ppv);
if (SUCCEEDED(hr) && ppidlLast)
*ppidlLast = pidlChild;
else
ILFree(pidlChild);
ILFree(pidlParent);
- }
This could use a test. For example, passed root folder ignored for simple pidl case, riid is ignored there as well. Returned last pidls are allocated, and they are not allocated in SHBindToParent().
- if (psfDesktop)
IShellFolder_Release(psfDesktop);
- TRACE_(shell)("-- ppv=%p ret=0x%08lx\n", *ppv, hr);
- return hr;
+}
- /*************************************************************************
*/
- SHParseDisplayName [SHELL32.@]
diff --git a/dlls/shell32/shell32.spec b/dlls/shell32/shell32.spec index f8bf8f246e8..5b812774e1f 100644 --- a/dlls/shell32/shell32.spec +++ b/dlls/shell32/shell32.spec @@ -334,6 +334,7 @@ @ stdcall SHAssocEnumHandlers(wstr long ptr) @ stdcall SHBindToObject(ptr ptr ptr ptr ptr) @ stdcall SHBindToParent(ptr ptr ptr ptr) +@ stdcall SHBindToFolderIDListParent(ptr ptr ptr ptr ptr) @ stdcall SHBrowseForFolder(ptr) SHBrowseForFolderA @ stdcall SHBrowseForFolderA(ptr) @ stdcall SHBrowseForFolderW(ptr)
Nikolay Sivov nsivov@codeweavers.com wrote:
This could use a test. For example, passed root folder ignored for simple pidl case, riid is ignored there as well. Returned last pidls are allocated, and they are not allocated in SHBindToParent().
Thanks for the good points, I somehow missed them.