Called by IE11.
Signed-off-by: Mohamad Al-Jaf mohamadaljaf@gmail.com
v4: Don't reimplement SHBindToParent.
-- v7: shell32/tests: Add SHBindToFolderIDListParent tests.
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
Signed-off-by: Mohamad Al-Jaf mohamadaljaf@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);
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
Signed-off-by: Mohamad Al-Jaf mohamadaljaf@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);
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
Called by IE11.
Signed-off-by: Mohamad Al-Jaf mohamadaljaf@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 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) diff --git a/include/shlobj.h b/include/shlobj.h index feee6cd9b98..724a2b66c11 100644 --- a/include/shlobj.h +++ b/include/shlobj.h @@ -1742,6 +1742,8 @@ HRESULT WINAPI SHGetFolderPathW(HWND hwnd, int nFolder, HANDLE hToken, DWORD dwF */ HRESULT WINAPI SHGetDesktopFolder(IShellFolder * *);
+HRESULT WINAPI SHBindToFolderIDListParent(IShellFolder *psf, LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCITEMIDLIST *ppidlLast); + /**************************************************************************** * SHBindToParent API */
From: Dmitry Timoshkov dmitry@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();
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=127103
Your paranoid android.
=== w10pro64 (64 bit report) ===
shell32: shlfolder.c:4994: Test failed: MKDIR: expected notification type 8, got: 40000
=== w10pro64_ar (64 bit report) ===
shell32: shlfolder.c:5011: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 2)
=== debian11 (32 bit zh:CN report) ===
shell32: autocomplete.c:614: Test failed: Expected (null), got L"ab" autocomplete.c:637: Test failed: Expected (null), got L"www.ax"
This merge request was approved by Mohamad Al-Jaf.
Just approving this because it contains a commit authored by someone else.
Can someone please review this MR? I'd like to get it merged before the code freeze and it's been 4 months since I created it.