-- v2: shell32: Handle drive letters properly when parsing MyComputer. shell32/tests: Test drive letters parsing for My Computer.
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/shell32/tests/shfldr_special.c | 71 +++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+)
diff --git a/dlls/shell32/tests/shfldr_special.c b/dlls/shell32/tests/shfldr_special.c index cc0bb20ff33..99d6e8c62a4 100644 --- a/dlls/shell32/tests/shfldr_special.c +++ b/dlls/shell32/tests/shfldr_special.c @@ -39,6 +39,76 @@ static inline BOOL SHELL_OsIsUnicode(void) return !(GetVersion() & 0x80000000); }
+/* Tests for My Computer */ +static void test_parse_for_my_computer(void) +{ + WCHAR path[] = { '\','\','?','\','C',':','\',0 }; + IShellFolder *mycomp, *sf; + WCHAR *drive = path + 4; + ITEMIDLIST *pidl; + DWORD eaten; + HRESULT hr; + + hr = SHGetDesktopFolder(&sf); + ok(hr == S_OK, "SHGetDesktopFolder failed with error 0x%lx\n", hr); + if (hr != S_OK) return; + hr = SHGetSpecialFolderLocation(NULL, CSIDL_DRIVES, &pidl); + ok(hr == S_OK, "SHGetSpecialFolderLocation failed with error 0x%lx\n", hr); + if (hr != S_OK) + { + IShellFolder_Release(sf); + return; + } + hr = IShellFolder_BindToObject(sf, pidl, NULL, &IID_IShellFolder, (void**)&mycomp); + ok(hr == S_OK, "IShellFolder::BindToObject failed with error 0x%lx\n", hr); + IShellFolder_Release(sf); + ILFree(pidl); + if (hr != S_OK) return; + + while (drive[0] <= 'Z' && GetDriveTypeW(drive) == DRIVE_NO_ROOT_DIR) drive[0]++; + if (drive[0] > 'Z') + { + skip("No drive found, skipping My Computer tests...\n"); + goto done; + } + + pidl = NULL; + eaten = 0xdeadbeef; + hr = IShellFolder_ParseDisplayName(mycomp, NULL, NULL, drive, &eaten, &pidl, NULL); + ok(hr == S_OK, "IShellFolder::ParseDisplayName failed with error 0x%lx\n", hr); + todo_wine + ok(eaten == 0xdeadbeef, "eaten should not have been set to %lu\n", eaten); + ok(pidl != NULL, "pidl is NULL\n"); + ILFree(pidl); + + /* \?\ prefix is not valid */ + pidl = NULL; + eaten = 0xdeadbeef; + hr = IShellFolder_ParseDisplayName(mycomp, NULL, NULL, path, &eaten, &pidl, NULL); + todo_wine + ok(hr == E_INVALIDARG, "IShellFolder::ParseDisplayName should have failed with E_INVALIDARG, got 0x%08lx\n", hr); + todo_wine + ok(eaten == 0xdeadbeef, "eaten should not have been set to %lu\n", eaten); + ok(pidl == NULL, "pidl is not NULL\n"); + ILFree(pidl); + + /* Try without backslash */ + drive[2] = '\0'; + pidl = NULL; + eaten = 0xdeadbeef; + hr = IShellFolder_ParseDisplayName(mycomp, NULL, NULL, drive, &eaten, &pidl, NULL); + ok(hr == S_OK || broken(hr == E_INVALIDARG) /* WinXP */, + "IShellFolder::ParseDisplayName failed with error 0x%lx\n", hr); + todo_wine + ok(eaten == 0xdeadbeef, "eaten should not have been set to %lu\n", eaten); + todo_wine + ok(pidl != NULL || broken(!pidl) /* WinXP */, "pidl is NULL\n"); + ILFree(pidl); + +done: + IShellFolder_Release(mycomp); +} + /* Tests for My Network Places */ static void test_parse_for_entire_network(void) { @@ -294,6 +364,7 @@ static void test_desktop_displaynameof(void)
START_TEST(shfldr_special) { + test_parse_for_my_computer(); test_parse_for_entire_network(); test_parse_for_control_panel(); test_printers_folder();
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Besides PathGetDriveNumber being dangerous and having a completely messed up result with \?\ prefix, a backslash is not required anymore on newer Windows versions. So e.g. C: should succeed to be parsed.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/shell32/shfldr_desktop.c | 5 +++-- dlls/shell32/shfldr_mycomp.c | 20 ++++++++++++-------- dlls/shell32/tests/shfldr_special.c | 2 -- dlls/shell32/tests/shlfolder.c | 4 ++-- 4 files changed, 17 insertions(+), 14 deletions(-)
diff --git a/dlls/shell32/shfldr_desktop.c b/dlls/shell32/shfldr_desktop.c index f8672836da9..f8870d58103 100644 --- a/dlls/shell32/shfldr_desktop.c +++ b/dlls/shell32/shfldr_desktop.c @@ -150,7 +150,7 @@ static HRESULT WINAPI ISF_Desktop_fnParseDisplayName (IShellFolder2 * iface, DWORD * pchEaten, LPITEMIDLIST * ppidl, DWORD * pdwAttributes) { IDesktopFolderImpl *This = impl_from_IShellFolder2(iface); - WCHAR szElement[MAX_PATH]; + WCHAR c, szElement[MAX_PATH]; LPCWSTR szNext = NULL; LPITEMIDLIST pidlTemp = NULL; PARSEDURLW urldata; @@ -178,7 +178,8 @@ static HRESULT WINAPI ISF_Desktop_fnParseDisplayName (IShellFolder2 * iface, SHCLSIDFromStringW (szElement + 2, &clsid); pidlTemp = _ILCreateGuid (PT_GUID, &clsid); } - else if (PathGetDriveNumberW (lpszDisplayName) >= 0) + /* we can't use PathGetDriveNumberW because we can't have the \?\ prefix */ + else if ((c = towupper(lpszDisplayName[0])) >= 'A' && c <= 'Z' && lpszDisplayName[1] == ':') { /* it's a filesystem path with a drive. Let MyComputer/UnixDosFolder parse it */ pidlTemp = _ILCreateMyComputer (); diff --git a/dlls/shell32/shfldr_mycomp.c b/dlls/shell32/shfldr_mycomp.c index 5b90458e145..2f4ebd580c1 100644 --- a/dlls/shell32/shfldr_mycomp.c +++ b/dlls/shell32/shfldr_mycomp.c @@ -189,7 +189,7 @@ static HRESULT WINAPI ISF_MyComputer_fnParseDisplayName (IShellFolder2 *iface, IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface); HRESULT hr = E_INVALIDARG; LPCWSTR szNext = NULL; - WCHAR szElement[MAX_PATH]; + WCHAR c, szElement[MAX_PATH]; LPITEMIDLIST pidlTemp = NULL; CLSID clsid;
@@ -209,13 +209,17 @@ static HRESULT WINAPI ISF_MyComputer_fnParseDisplayName (IShellFolder2 *iface, SHCLSIDFromStringW (szElement + 2, &clsid); pidlTemp = _ILCreateGuid (PT_GUID, &clsid); } - /* do we have an absolute path name ? */ - else if (PathGetDriveNumberW (lpszDisplayName) >= 0 && - lpszDisplayName[2] == (WCHAR) '\') + /* we can't use PathGetDriveNumberW because we can't have the \?\ prefix */ + else if ((c = towupper(lpszDisplayName[0])) >= 'A' && c <= 'Z' && + lpszDisplayName[1] == ':' && + (lpszDisplayName[2] == '\' || lpszDisplayName[2] == '\0')) { - szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH); - /* make drive letter uppercase to enable PIDL comparison */ - szElement[0] = toupper(szElement[0]); + /* drive letter has to be uppercase to enable PIDL comparison */ + szElement[0] = c; + szElement[1] = ':'; + szElement[2] = '\'; + szElement[3] = '\0'; + szNext = &lpszDisplayName[2] + (lpszDisplayName[2] == '\'); pidlTemp = _ILCreateDrive (szElement); }
@@ -224,7 +228,7 @@ static HRESULT WINAPI ISF_MyComputer_fnParseDisplayName (IShellFolder2 *iface, hr = SHELL32_ParseNextElement (iface, hwndOwner, pbc, &pidlTemp, (LPOLESTR) szNext, pchEaten, pdwAttributes); } - else + else if (pidlTemp) { if (pdwAttributes && *pdwAttributes) SHELL32_GetItemAttributes (&This->IShellFolder2_iface, pidlTemp, pdwAttributes); diff --git a/dlls/shell32/tests/shfldr_special.c b/dlls/shell32/tests/shfldr_special.c index 99d6e8c62a4..22749c231f3 100644 --- a/dlls/shell32/tests/shfldr_special.c +++ b/dlls/shell32/tests/shfldr_special.c @@ -85,7 +85,6 @@ static void test_parse_for_my_computer(void) pidl = NULL; eaten = 0xdeadbeef; hr = IShellFolder_ParseDisplayName(mycomp, NULL, NULL, path, &eaten, &pidl, NULL); - todo_wine ok(hr == E_INVALIDARG, "IShellFolder::ParseDisplayName should have failed with E_INVALIDARG, got 0x%08lx\n", hr); todo_wine ok(eaten == 0xdeadbeef, "eaten should not have been set to %lu\n", eaten); @@ -101,7 +100,6 @@ static void test_parse_for_my_computer(void) "IShellFolder::ParseDisplayName failed with error 0x%lx\n", hr); todo_wine ok(eaten == 0xdeadbeef, "eaten should not have been set to %lu\n", eaten); - todo_wine ok(pidl != NULL || broken(!pidl) /* WinXP */, "pidl is NULL\n"); ILFree(pidl);
diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c index 02a5c0dfb2d..248fbd1df62 100644 --- a/dlls/shell32/tests/shlfolder.c +++ b/dlls/shell32/tests/shlfolder.c @@ -199,8 +199,8 @@ static struct {{'c',':','\',0}, S_OK}, {{'c',':','\','\',0}, E_INVALIDARG, 1}, {{'c',':','\','f','a','k','e',0}, 0x80070002}, /* ERROR_FILE_NOT_FOUND */ - {{'c',':','f','a','k','e',0}, E_INVALIDARG, 1}, - {{'c',':','/',0}, E_INVALIDARG, 1}, + {{'c',':','f','a','k','e',0}, E_INVALIDARG}, + {{'c',':','/',0}, E_INVALIDARG}, {{'c',':','\','w','i','n','d','o','w','s',0}, S_OK}, {{'c',':','\','w','i','n','d','o','w','s','\',0}, S_OK}, {{'c',':','\','w','i','n','d','o','w','s','\','.',0}, E_INVALIDARG, 1},
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=124866
Your paranoid android.
=== w1064v1809 (32 bit report) ===
shell32: shlfolder.c:4990: Test failed: RMDIR: expected notification type 10, got: 40000
=== w10pro64 (32 bit report) ===
shell32: shlfolder.c:4990: Test failed: MKDIR: expected notification type 8, got: 4000000 shlfolder.c:4998: Test failed: Expected PIDL to be NULL
=== w1064_tsign (64 bit report) ===
shell32: shlfolder.c:5007: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 2)
=== w10pro64 (64 bit report) ===
shell32: shlfolder.c:4990: Test failed: RMDIR: expected notification type 10, got: 4000000 shlfolder.c:4998: Test failed: Expected PIDL to be NULL
=== w10pro64_zh_CN (64 bit report) ===
shell32: shlfolder.c:4990: Test failed: MKDIR: expected notification type 8, got: 40000
=== 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"
=== debian11 (build log) ===
Use of uninitialized value $Flaky in addition (+) at /home/testbot/lib/WineTestBot/LogUtils.pm line 720, <$LogFile> line 24691. Use of uninitialized value $Flaky in addition (+) at /home/testbot/lib/WineTestBot/LogUtils.pm line 720, <$LogFile> line 24691. Use of uninitialized value $Flaky in addition (+) at /home/testbot/lib/WineTestBot/LogUtils.pm line 720, <$LogFile> line 24691.