[5/5] is actually not relevant to this serial, but my next serial will depend on it, so I submit it by the way first, so that I can avoid maintaining too many patches locally. :D
From: Jactry Zeng jzeng@codeweavers.com
--- dlls/shell32/tests/shfldr_special.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/dlls/shell32/tests/shfldr_special.c b/dlls/shell32/tests/shfldr_special.c index 22749c231f3..d9446dbbdc1 100644 --- a/dlls/shell32/tests/shfldr_special.c +++ b/dlls/shell32/tests/shfldr_special.c @@ -331,29 +331,30 @@ static void test_desktop_displaynameof(void) WCHAR name1[MAX_PATH], name2[MAX_PATH];
hr = IShellFolder_ParseDisplayName(desktop, NULL, NULL, folders[i], &eaten, &pidl, NULL); - ok(hr == S_OK, "IShellFolder::ParseDisplayName failed with error 0x%08lx\n", hr); + ok(hr == S_OK, "Test %d: got %#lx.\n", i, hr); if (FAILED(hr)) continue;
hr = IShellFolder_GetDisplayNameOf(desktop, pidl, SHGDN_INFOLDER, &strret); - ok(hr == S_OK, "IShellFolder::GetDisplayNameOf failed with error 0x%08lx\n", hr); + ok(hr == S_OK, "Test %d: got %#lx.\n", i, hr); hr = StrRetToBufW(&strret, pidl, name1, ARRAY_SIZE(name1)); - ok(hr == S_OK, "StrRetToBuf failed with error 0x%08lx\n", hr); + ok(hr == S_OK, "Test %d: got %#lx.\n", i, hr);
hr = IShellFolder_GetDisplayNameOf(desktop, pidl, SHGDN_INFOLDER | SHGDN_FORPARSING | SHGDN_FORADDRESSBAR, &strret); - ok(hr == S_OK, "IShellFolder::GetDisplayNameOf failed with error 0x%08lx\n", hr); + ok(hr == S_OK, "Test %d: got %#lx.\n", i, hr); hr = StrRetToBufW(&strret, pidl, name2, ARRAY_SIZE(name2)); - ok(hr == S_OK, "StrRetToBuf failed with error 0x%08lx\n", hr); + ok(hr == S_OK, "Test %d: got %#lx.\n", i, hr);
- ok(!lstrcmpW(name1, name2), "the display names are not equal: %s vs %s\n", wine_dbgstr_w(name1), wine_dbgstr_w(name2)); - ok(name1[0] != ':' || name1[1] != ':', "display name is a GUID: %s\n", wine_dbgstr_w(name1)); + ok(!lstrcmpW(name1, name2), "Test %d: the display names aren't equal: %s vs %s.\n", + i, wine_dbgstr_w(name1), wine_dbgstr_w(name2)); + ok(name1[0] != ':' || name1[1] != ':', "Test %d: display name is a GUID: %s.\n", i, wine_dbgstr_w(name1));
hr = IShellFolder_GetDisplayNameOf(desktop, pidl, SHGDN_INFOLDER | SHGDN_FORPARSING, &strret); - ok(hr == S_OK, "IShellFolder::GetDisplayNameOf failed with error 0x%08lx\n", hr); + ok(hr == S_OK, "Test %d: got %#lx.\n", i, hr); hr = StrRetToBufW(&strret, pidl, name1, ARRAY_SIZE(name1)); - ok(hr == S_OK, "StrRetToBuf failed with error 0x%08lx\n", hr); + ok(hr == S_OK, "Test %d: got %#lx.\n", i, hr);
- ok(lstrcmpW(name1, name2), "the display names are equal: %s\n", wine_dbgstr_w(name1)); - ok(name1[0] == ':' && name1[1] == ':', "display name is not a GUID: %s\n", wine_dbgstr_w(name1)); + ok(lstrcmpW(name1, name2), "Test %d: the display names are equal: %s.\n", i, wine_dbgstr_w(name1)); + ok(name1[0] == ':' && name1[1] == ':', "Test %d: display name is not a GUID: %s.\n", i, wine_dbgstr_w(name1));
ILFree(pidl); }
From: Jactry Zeng jzeng@codeweavers.com
--- dlls/shell32/tests/shfldr_special.c | 72 +++++++++++++++++++++++++---- 1 file changed, 62 insertions(+), 10 deletions(-)
diff --git a/dlls/shell32/tests/shfldr_special.c b/dlls/shell32/tests/shfldr_special.c index d9446dbbdc1..ca5a19d7e19 100644 --- a/dlls/shell32/tests/shfldr_special.c +++ b/dlls/shell32/tests/shfldr_special.c @@ -307,30 +307,78 @@ static void test_desktop_folder(void) IShellFolder_Release(psf); }
+static void get_localized_string(const WCHAR *clsid, WCHAR *output) +{ + WCHAR buffer[MAX_PATH], resource_id[8], *p; + DWORD type, size; + HMODULE module; + int lenght, id; + LONG result; + HKEY key; + + wsprintfW(buffer, L"CLSID\%s", clsid); + result = RegOpenKeyExW(HKEY_CLASSES_ROOT, buffer, 0, KEY_READ, &key); + ok(result == ERROR_SUCCESS, "RegOpenKeyExW failed %#lx.\n", result); + + type = REG_SZ; + size = sizeof(buffer); + result = RegQueryValueExW(key, L"LocalizedString", NULL, &type, (LPBYTE)&buffer, &size); + ok(result == ERROR_SUCCESS, "RegQueryValueExW failed %#lx.\n", result); + RegCloseKey(key); + + p = wcsrchr(buffer, L','); + lenght = p - buffer; + lstrcpynW(buffer, buffer + 1, lenght); + result = ExpandEnvironmentStringsW(buffer, buffer, MAX_PATH); + ok(!!result, "ExpandEnvironmentStringsW failed %#lx.\n", GetLastError()); + wcscpy(resource_id, p + 2); + id = _wtoi(resource_id); + + module = LoadLibraryExW(buffer, NULL, LOAD_LIBRARY_AS_DATAFILE); + ok(!!module, "LoadLibraryExW failed %#lx.\n", GetLastError()); + result = LoadStringW(module, id, output, MAX_PATH); + ok(!!result, "LoadStringW failed %#lx.\n", GetLastError()); + CloseHandle(module); +} + static void test_desktop_displaynameof(void) { - static WCHAR MyComputer[] = { ':',':','{','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 }; - static WCHAR MyDocuments[] = { ':',':','{','4','5','0','D','8','F','B','A','-','A','D','2','5','-','1','1','D','0','-','9','8','A','8','-','0','8','0','0','3','6','1','B','1','1','0','3','}', 0 }; - static WCHAR RecycleBin[] = { ':',':','{','6','4','5','F','F','0','4','0','-','5','0','8','1','-','1','0','1','B','-','9','F','0','8','-','0','0','A','A','0','0','2','F','9','5','4','E','}', 0 }; - static WCHAR ControlPanel[]= { ':',':','{','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','}','\', - ':',':','{','2','1','E','C','2','0','2','0','-','3','A','E','A','-','1','0','6','9','-','A','2','D','D','-','0','8','0','0','2','B','3','0','3','0','9','D','}', 0 }; - static WCHAR *folders[] = { MyComputer, MyDocuments, RecycleBin, ControlPanel }; + WCHAR buffer[MAX_PATH], name1[MAX_PATH], name2[MAX_PATH]; IShellFolder *desktop; ITEMIDLIST *pidl; + UINT i, lenght; STRRET strret; DWORD eaten; HRESULT hr; - UINT i; + struct folder_test + { + const CLSID clsid; + const CLSID sub_clsid; + } folder_tests[] = + { + { CLSID_MyComputer, CLSID_NULL }, + { CLSID_MyDocuments, CLSID_NULL }, + { CLSID_RecycleBin, CLSID_NULL }, + { CLSID_MyComputer, CLSID_ControlPanel }, + };
hr = SHGetDesktopFolder(&desktop); ok(hr == S_OK, "SHGetDesktopFolder failed with error 0x%08lx\n", hr); if (FAILED(hr)) return;
- for (i = 0; i < ARRAY_SIZE(folders); i++) + wcscpy(buffer, L"::"); + for (i = 0; i < ARRAY_SIZE(folder_tests); i++) { - WCHAR name1[MAX_PATH], name2[MAX_PATH]; + lenght = wcslen(L"::"); + StringFromGUID2(&folder_tests[i].clsid, buffer + lenght, MAX_PATH - lenght); + if (!IsEqualCLSID(&folder_tests[i].sub_clsid, &CLSID_NULL)) + { + StringFromGUID2(&folder_tests[i].sub_clsid, name2, MAX_PATH); + wsprintfW(buffer, L"%s\::%s", buffer, name2); + lenght = wcslen(buffer) - wcslen(name2); + }
- hr = IShellFolder_ParseDisplayName(desktop, NULL, NULL, folders[i], &eaten, &pidl, NULL); + hr = IShellFolder_ParseDisplayName(desktop, NULL, NULL, buffer, &eaten, &pidl, NULL); ok(hr == S_OK, "Test %d: got %#lx.\n", i, hr); if (FAILED(hr)) continue;
@@ -339,6 +387,10 @@ static void test_desktop_displaynameof(void) hr = StrRetToBufW(&strret, pidl, name1, ARRAY_SIZE(name1)); ok(hr == S_OK, "Test %d: got %#lx.\n", i, hr);
+ get_localized_string(buffer + lenght, name2); + ok(!lstrcmpW(name1, name2), "Test %d: got wrong display name %s, excepted %s.\n", + i, debugstr_w(name1), debugstr_w(name2)); + hr = IShellFolder_GetDisplayNameOf(desktop, pidl, SHGDN_INFOLDER | SHGDN_FORPARSING | SHGDN_FORADDRESSBAR, &strret); ok(hr == S_OK, "Test %d: got %#lx.\n", i, hr); hr = StrRetToBufW(&strret, pidl, name2, ARRAY_SIZE(name2));
From: Jactry Zeng jzeng@codeweavers.com
So that we can get "user friendly" diaplay names from IShellFolder_GetDisplayNameOf() for these CLSIDs. --- dlls/shell32/shell32.rc | 2 ++ dlls/shell32/shell32.rgs | 2 ++ dlls/shell32/shresdef.h | 2 ++ dlls/shell32/tests/shfldr_special.c | 2 ++ 4 files changed, 8 insertions(+)
diff --git a/dlls/shell32/shell32.rc b/dlls/shell32/shell32.rc index f899a27f12c..6c1798201fb 100644 --- a/dlls/shell32/shell32.rc +++ b/dlls/shell32/shell32.rc @@ -154,6 +154,8 @@ STRINGTABLE IDS_MYCOMPUTER "My Computer" IDS_RECYCLEBIN_FOLDER_NAME "Trash" IDS_CONTROLPANEL "Control Panel" + IDS_INTERNET "The Internet" + IDS_PRINTERS "Printers and Faxes"
/* context menus */ IDS_VIEW_LARGE "Lar&ge Icons" diff --git a/dlls/shell32/shell32.rgs b/dlls/shell32/shell32.rgs index 877be6bc814..1523fd52210 100644 --- a/dlls/shell32/shell32.rgs +++ b/dlls/shell32/shell32.rgs @@ -5,12 +5,14 @@ HKCR '{00021400-0000-0000-C000-000000000046}' { val LocalizedString = s '@%MODULE%,-20' } '{20D04FE0-3AEA-1069-A2D8-08002B30309D}' { val LocalizedString = s '@%MODULE%,-21' } '{21EC2020-3AEA-1069-A2DD-08002B30309D}' { val LocalizedString = s '@%MODULE%,-22' } + '{2227a280-3aea-1069-a2de-08002b30309d}' { val LocalizedString = s '@%MODULE%,-30' } '{450D8FBA-AD25-11D0-98A8-0800361B1103}' { val LocalizedString = s '@%MODULE%,-46' } '{645FF040-5081-101B-9F08-00AA002F954E}' { val LocalizedString = s '@%MODULE%,-8964' DefaultIcon = s '%MODULE%,-33' } + '{871c5380-42a0-1069-a2ea-08002b30309d}' { val LocalizedString = s '@%MODULE%,-29' } '{00021401-0000-0000-C000-000000000046}' { shellex { MayChangeDefaultMenu } } } } diff --git a/dlls/shell32/shresdef.h b/dlls/shell32/shresdef.h index af8eb46a09f..16cbf0fe5a4 100644 --- a/dlls/shell32/shresdef.h +++ b/dlls/shell32/shresdef.h @@ -55,6 +55,8 @@ #define IDS_VIEW_SMALL 26 #define IDS_VIEW_LIST 27 #define IDS_VIEW_DETAILS 28 +#define IDS_INTERNET 29 +#define IDS_PRINTERS 30
#define IDS_RESTART_TITLE 40 #define IDS_RESTART_PROMPT 41 diff --git a/dlls/shell32/tests/shfldr_special.c b/dlls/shell32/tests/shfldr_special.c index ca5a19d7e19..6f884d34a39 100644 --- a/dlls/shell32/tests/shfldr_special.c +++ b/dlls/shell32/tests/shfldr_special.c @@ -359,6 +359,8 @@ static void test_desktop_displaynameof(void) { CLSID_MyComputer, CLSID_NULL }, { CLSID_MyDocuments, CLSID_NULL }, { CLSID_RecycleBin, CLSID_NULL }, + { CLSID_Printers, CLSID_NULL }, + { CLSID_Internet, CLSID_NULL }, { CLSID_MyComputer, CLSID_ControlPanel }, };
From: Jactry Zeng jzeng@codeweavers.com
--- dlls/shell32/tests/shfldr_special.c | 49 +++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-)
diff --git a/dlls/shell32/tests/shfldr_special.c b/dlls/shell32/tests/shfldr_special.c index 6f884d34a39..b1fa6ee6782 100644 --- a/dlls/shell32/tests/shfldr_special.c +++ b/dlls/shell32/tests/shfldr_special.c @@ -344,9 +344,10 @@ static void get_localized_string(const WCHAR *clsid, WCHAR *output) static void test_desktop_displaynameof(void) { WCHAR buffer[MAX_PATH], name1[MAX_PATH], name2[MAX_PATH]; - IShellFolder *desktop; + IShellFolder *desktop, *parent; + LPCITEMIDLIST child; + UINT i, lenght, j; ITEMIDLIST *pidl; - UINT i, lenght; STRRET strret; DWORD eaten; HRESULT hr; @@ -363,6 +364,23 @@ static void test_desktop_displaynameof(void) { CLSID_Internet, CLSID_NULL }, { CLSID_MyComputer, CLSID_ControlPanel }, }; + static const SHGNO flags[] = + { + SHGDN_NORMAL, + SHGDN_INFOLDER, + SHGDN_FOREDITING, + SHGDN_FORADDRESSBAR, + SHGDN_INCLUDE_NONFILESYS, + SHGDN_FORPARSING | SHGDN_FORADDRESSBAR, + SHGDN_FORPARSING | SHGDN_FORADDRESSBAR | SHGDN_INFOLDER, + }, valid_flags[] = + { + SHGDN_FORPARSING, + SHGDN_FORPARSING | SHGDN_NORMAL, + SHGDN_FORPARSING | SHGDN_INFOLDER, + SHGDN_FORPARSING | SHGDN_FOREDITING, + SHGDN_FORPARSING | SHGDN_INCLUDE_NONFILESYS, + };
hr = SHGetDesktopFolder(&desktop); ok(hr == S_OK, "SHGetDesktopFolder failed with error 0x%08lx\n", hr); @@ -410,8 +428,35 @@ static void test_desktop_displaynameof(void) ok(lstrcmpW(name1, name2), "Test %d: the display names are equal: %s.\n", i, wine_dbgstr_w(name1)); ok(name1[0] == ':' && name1[1] == ':', "Test %d: display name is not a GUID: %s.\n", i, wine_dbgstr_w(name1));
+ for (j = 0; j < ARRAYSIZE(flags); j++) + { + hr = IShellFolder_GetDisplayNameOf(desktop, pidl, flags[j], &strret); + ok(hr == S_OK, "Test %d,%d: got %#lx.\n", i, j, hr); + } ILFree(pidl); } + + wcscpy(name1, L"shell:::{01234567-4321-1234-4321-ba9876543210}"); + hr = IShellFolder_ParseDisplayName(desktop, NULL, NULL, name1, NULL, &pidl, NULL); + ok(hr == S_OK, "Got %#lx.\n", hr); + hr = SHBindToParent(pidl, &IID_IShellFolder, (void **)&parent, &child); + ok(hr == S_OK, "Got %#lx.\n", hr); + for (i = 0; i < ARRAYSIZE(flags); i++) + { + hr = IShellFolder_GetDisplayNameOf(parent, child, flags[i], &strret); + todo_wine ok(hr == E_FAIL, "Test %d: got %#lx.\n", i, hr); + } + for (i = 0; i < ARRAYSIZE(valid_flags); i++) + { + hr = IShellFolder_GetDisplayNameOf(desktop, pidl, valid_flags[i], &strret); + ok(hr == S_OK, "Test %d: got %#lx.\n", i, hr); + hr = StrRetToBufW(&strret, pidl, name2, ARRAYSIZE(name2)); + ok(hr == S_OK, "Got %#lx.\n", hr); + ok(!wcsicmp(name2, L"::{01234567-4321-1234-4321-ba9876543210}"), + "Got wrong name %s.\n", debugstr_w(name2)); + } + IShellFolder_Release(parent); + IShellFolder_Release(desktop); }
From: Jactry Zeng jzeng@codeweavers.com
--- include/shlobj.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/include/shlobj.h b/include/shlobj.h index c00687e84d8..9158ba17111 100644 --- a/include/shlobj.h +++ b/include/shlobj.h @@ -1755,6 +1755,8 @@ WINSHELLAPI HRESULT WINAPI SHBindToFolderIDListParent(IShellFolder *psf, LPCITEM * SHBindToParent API */ WINSHELLAPI HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCITEMIDLIST *ppidlLast); +WINSHELLAPI HRESULT WINAPI SHBindToObject(IShellFolder *folder, LPCITEMIDLIST pidl, IBindCtx *context, + REFIID riid, void **object);
/**************************************************************************** * SHDefExtractIcon API