[PATCH v8 0/4] MR566: shell32: Implement SHBindToFolderIDListParent.
Called by IE11. Signed-off-by: Mohamad Al-Jaf <mohamadaljaf(a)gmail.com> v4: Don't reimplement SHBindToParent. -- v8: shell32/tests: Add SHBindToFolderIDListParent tests. shell32: Implement SHBindToFolderIDListParent. shell32: Fix error handling in SHBindToParent. shell32/tests: Test SHBindToParent last parameter behavior. https://gitlab.winehq.org/wine/wine/-/merge_requests/566
From: Mohamad Al-Jaf <mohamadaljaf(a)gmail.com> Signed-off-by: Mohamad Al-Jaf <mohamadaljaf(a)gmail.com> --- dlls/shell32/tests/shlfolder.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c index 248fbd1df62..1d24827b8a4 100644 --- a/dlls/shell32/tests/shlfolder.c +++ b/dlls/shell32/tests/shlfolder.c @@ -773,9 +773,11 @@ static void test_GetDisplayName(void) ok (!lstrcmpiW(wszTestFile, wszTestFile2), "SHGetPathFromIDListW returns incorrect path!\n"); /* SHBindToParent fails, if called with a NULL PIDL. */ + pidlLast = (LPITEMIDLIST)0xdeadbeef; hr = SHBindToParent(NULL, &IID_IShellFolder, (void **)&psfPersonal, &pidlLast); ok (hr == E_INVALIDARG || broken(hr == E_OUTOFMEMORY) /* XP */, "SHBindToParent(NULL) should fail! hr = %08lx\n", hr); + todo_wine ok(pidlLast == NULL, "got %p\n", pidlLast); /* But it succeeds with an empty PIDL. */ hr = SHBindToParent(pidlEmpty, &IID_IShellFolder, (void **)&psfPersonal, &pidlLast); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/566
From: Mohamad Al-Jaf <mohamadaljaf(a)gmail.com> Signed-off-by: Mohamad Al-Jaf <mohamadaljaf(a)gmail.com> --- dlls/shell32/pidl.c | 9 +++++---- dlls/shell32/tests/shlfolder.c | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/dlls/shell32/pidl.c b/dlls/shell32/pidl.c index f9c91a79132..4294f24c736 100644 --- a/dlls/shell32/pidl.c +++ b/dlls/shell32/pidl.c @@ -1295,13 +1295,14 @@ HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCI TRACE_(shell)("pidl=%p\n", pidl); pdump(pidl); - + + if (ppidlLast) + *ppidlLast = NULL; + if (!pidl || !ppv) return E_INVALIDARG; - + *ppv = NULL; - if (ppidlLast) - *ppidlLast = NULL; hr = SHGetDesktopFolder(&psfDesktop); if (FAILED(hr)) diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c index 1d24827b8a4..2dbe7ec323a 100644 --- a/dlls/shell32/tests/shlfolder.c +++ b/dlls/shell32/tests/shlfolder.c @@ -777,7 +777,7 @@ static void test_GetDisplayName(void) hr = SHBindToParent(NULL, &IID_IShellFolder, (void **)&psfPersonal, &pidlLast); ok (hr == E_INVALIDARG || broken(hr == E_OUTOFMEMORY) /* XP */, "SHBindToParent(NULL) should fail! hr = %08lx\n", hr); - todo_wine ok(pidlLast == NULL, "got %p\n", pidlLast); + ok(pidlLast == NULL, "got %p\n", pidlLast); /* But it succeeds with an empty PIDL. */ hr = SHBindToParent(pidlEmpty, &IID_IShellFolder, (void **)&psfPersonal, &pidlLast); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/566
From: Mohamad Al-Jaf <mohamadaljaf(a)gmail.com> Called by IE11. Signed-off-by: Mohamad Al-Jaf <mohamadaljaf(a)gmail.com> --- dlls/shell32/pidl.c | 50 +++++++++++++++++++++++++++++++++++++++ dlls/shell32/shell32.spec | 1 + include/shlobj.h | 2 ++ 3 files changed, 53 insertions(+) diff --git a/dlls/shell32/pidl.c b/dlls/shell32/pidl.c index 4294f24c736..67103eeb0ef 100644 --- a/dlls/shell32/pidl.c +++ b/dlls/shell32/pidl.c @@ -1285,6 +1285,56 @@ BOOL WINAPI SHGetPathFromIDListEx(LPCITEMIDLIST pidl, WCHAR *path, DWORD path_si return SUCCEEDED(hr); } +/************************************************************************* + * SHBindToFolderIDListParent [SHELL32.@] + */ +HRESULT WINAPI SHBindToFolderIDListParent(IShellFolder *psf, LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCITEMIDLIST *ppidlLast) +{ + IShellFolder *psfDesktop = NULL; + HRESULT hr; + + TRACE_(shell)("%p,%p,%s\n", psf, pidl, debugstr_guid(riid)); + pdump(pidl); + + if (ppidlLast) + *ppidlLast = NULL; + + if (!pidl || !ppv) + return E_INVALIDARG; + + *ppv = NULL; + + if (!psf) + { + hr = SHGetDesktopFolder(&psfDesktop); + if (FAILED(hr)) + return hr; + psf = psfDesktop; + } + + if (_ILIsPidlSimple(pidl)) + { + /* we are on desktop level */ + hr = IShellFolder_QueryInterface(psf, riid, ppv); + } + else + { + LPITEMIDLIST pidlParent = ILClone(pidl); + ILRemoveLastID(pidlParent); + hr = IShellFolder_BindToObject(psf, pidlParent, NULL, riid, ppv); + SHFree (pidlParent); + } + + if (psfDesktop) + IShellFolder_Release(psfDesktop); + + if (SUCCEEDED(hr) && ppidlLast) + *ppidlLast = ILFindLastID(pidl); + + TRACE_(shell)("-- ppv=%p pidl=%p ret=0x%08lx\n", *ppv, (ppidlLast)?*ppidlLast:NULL, hr); + return hr; +} + /************************************************************************* * SHBindToParent [shell version 5.0] */ diff --git a/dlls/shell32/shell32.spec b/dlls/shell32/shell32.spec index 59285c89c57..c22429cb3bc 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) diff --git a/include/shlobj.h b/include/shlobj.h index c7452cf5f0a..4cb7375bb59 100644 --- a/include/shlobj.h +++ b/include/shlobj.h @@ -1748,6 +1748,8 @@ WINSHELLAPI HRESULT WINAPI SHGetFolderPathW(HWND hwnd, int nFolder, HANDLE hToke */ WINSHELLAPI HRESULT WINAPI SHGetDesktopFolder(IShellFolder * *); +HRESULT WINAPI SHBindToFolderIDListParent(IShellFolder *psf, LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCITEMIDLIST *ppidlLast); + /**************************************************************************** * SHBindToParent API */ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/566
From: Dmitry Timoshkov <dmitry(a)baikal.ru> --- dlls/shell32/tests/shlfolder.c | 53 ++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c index 2dbe7ec323a..c9e79aa9b36 100644 --- a/dlls/shell32/tests/shlfolder.c +++ b/dlls/shell32/tests/shlfolder.c @@ -60,6 +60,7 @@ static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL); static HRESULT (WINAPI *pSHCreateDefaultContextMenu)(const DEFCONTEXTMENU*,REFIID,void**); static BOOL (WINAPI *pSHGetPathFromIDListEx)(PCIDLIST_ABSOLUTE,WCHAR*,DWORD,GPFIDL_FLAGS); static HRESULT (WINAPI *pSHGetSetFolderCustomSettings)(LPSHFOLDERCUSTOMSETTINGS,PCWSTR,DWORD); +static HRESULT (WINAPI *pSHBindToFolderIDListParent)(IShellFolder*,LPCITEMIDLIST,REFIID,void **,LPCITEMIDLIST*); static WCHAR *make_wstr(const char *str) { @@ -120,6 +121,7 @@ static void init_function_pointers(void) hmod = GetModuleHandleA("shell32.dll"); #define MAKEFUNC(f) (p##f = (void*)GetProcAddress(hmod, #f)) + MAKEFUNC(SHBindToFolderIDListParent); MAKEFUNC(SHCreateItemFromIDList); MAKEFUNC(SHCreateItemFromParsingName); MAKEFUNC(SHCreateItemFromRelativeName); @@ -5499,6 +5501,56 @@ static void test_SHOpenFolderAndSelectItems(void) ILFree(folder); } +static void test_SHBindToFolderIDListParent(void) +{ + IShellFolder *psf_desktop; + LPITEMIDLIST pidl; + HRESULT hr; + WCHAR path[MAX_PATH]; + SHITEMID empty_item = { 0, { 0 } }; + LPITEMIDLIST pidl_empty = (LPITEMIDLIST)&empty_item; + LPCITEMIDLIST pidl_last; + IShellFolder *psf; + + if (!pSHBindToFolderIDListParent) + { + win_skip("SHBindToFolderIDListParent not available\n"); + return; + } + + GetTempPathW(ARRAY_SIZE(path), path); + SHGetDesktopFolder(&psf_desktop); + + hr = IShellFolder_ParseDisplayName(psf_desktop, NULL, NULL, path, NULL, &pidl, 0); + ok(hr == S_OK, "got %#lx\n", hr); + + pidl_last = NULL; + hr = pSHBindToFolderIDListParent(psf_desktop, pidl, &IID_IShellFolder, (void **)&psf, &pidl_last); + ok(hr == S_OK, "got %#lx\n", hr); + ok(pidl_last != NULL, "got %p\n", pidl_last); + IShellFolder_Release(psf); + + hr = pSHBindToFolderIDListParent(NULL, pidl_empty, &IID_IShellFolder, (void **)&psf, &pidl_last); + ok(hr == S_OK, "got %#lx\n", hr); + ok(pidl_last == pidl_empty, "got %p\n", pidl_last); + IShellFolder_Release(psf); + + hr = pSHBindToFolderIDListParent(NULL, pidl, &IID_IShellFolder, (void **)&psf, NULL); + ok(hr == S_OK, "got %#lx\n", hr); + IShellFolder_Release(psf); + + if (0) /* crashes under Windows */ + hr = pSHBindToFolderIDListParent(NULL, pidl, &IID_IShellFolder, NULL, NULL); + + ILFree(pidl); + IShellFolder_Release(psf_desktop); + + pidl_last = (LPITEMIDLIST)0xdeadbeef; + hr = pSHBindToFolderIDListParent(NULL, NULL, &IID_IShellFolder, (void **)&psf, &pidl_last); + ok(hr == E_INVALIDARG, "got %#lx\n", hr); + ok(pidl_last == NULL, "got %p\n", pidl_last); +} + START_TEST(shlfolder) { init_function_pointers(); @@ -5506,6 +5558,7 @@ START_TEST(shlfolder) CO_E_NOTINITIALIZED for malformed directory names */ OleInitialize(NULL); + test_SHBindToFolderIDListParent(); test_ParseDisplayName(); test_SHParseDisplayName(); test_BindToObject(); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/566
Hi, It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated. The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details: The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=127437 Your paranoid android. === w1064v1809 (64 bit report) === shell32: shlfolder.c:5011: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 2) === w10pro64 (64 bit report) === shell32: shlfolder.c:4994: Test failed: RMDIR: expected notification type 10, got: 40000 === w10pro64_en_AE_u8 (64 bit report) === shell32: shlfolder.c:4994: Test failed: MKDIR: expected notification type 8, got: 40000 shlfolder.c:5011: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 2) === w10pro64_ja (64 bit report) === shell32: shlfolder.c:4994: Test failed: RMDIR: expected notification type 10, got: 40000
participants (4)
-
Dmitry Timoshkov -
Marvin -
Mohamad Al-Jaf -
Mohamad Al-Jaf (@maljaf)