Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52394
-- v2: shell32: Fix SHChangeNotify test failures. shell32: Add partial ControlPanel GetAttributesOf implementation. shell32: Store NameSpace registry path in global variable.
From: Piotr Caban piotr@codeweavers.com
--- dlls/shell32/cpanelfolder.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/dlls/shell32/cpanelfolder.c b/dlls/shell32/cpanelfolder.c index 122c3180dd4..9619128d8b0 100644 --- a/dlls/shell32/cpanelfolder.c +++ b/dlls/shell32/cpanelfolder.c @@ -66,6 +66,8 @@ typedef struct { int dwAttributes; /* attributes returned by GetAttributesOf FIXME: use it */ } ICPanelImpl;
+static const WCHAR name_spaceW[] = L"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ControlPanel\NameSpace"; + static const IShellFolder2Vtbl vt_ShellFolder2; static const IPersistFolder2Vtbl vt_PersistFolder2; static const IShellExecuteHookWVtbl vt_ShellExecuteHookW; @@ -355,14 +357,14 @@ static int SHELL_RegisterRegistryCPanelApps(IEnumIDListImpl *list, HKEY hkey_roo return cnt; }
-static int SHELL_RegisterCPanelFolders(IEnumIDListImpl *list, HKEY hkey_root, LPCSTR szRepPath) +static int SHELL_RegisterCPanelFolders(IEnumIDListImpl *list, HKEY hkey_root, const WCHAR *reg_path) { char name[MAX_PATH]; HKEY hkey;
int cnt = 0;
- if (RegOpenKeyA(hkey_root, szRepPath, &hkey) == ERROR_SUCCESS) + if (RegOpenKeyW(hkey_root, reg_path, &hkey) == ERROR_SUCCESS) { int idx = 0; for(;; ++idx) @@ -398,8 +400,7 @@ static BOOL CreateCPanelEnumList(IEnumIDListImpl *list, DWORD dwFlags)
/* enumerate control panel folders */ if (dwFlags & SHCONTF_FOLDERS) - SHELL_RegisterCPanelFolders(list, HKEY_LOCAL_MACHINE, - "SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ControlPanel\NameSpace"); + SHELL_RegisterCPanelFolders(list, HKEY_LOCAL_MACHINE, name_spaceW);
/* enumerate the control panel applets */ if (dwFlags & SHCONTF_NONFOLDERS)
From: Piotr Caban piotr@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52394 --- dlls/shell32/cpanelfolder.c | 39 +++++++++++++++++++++++-- dlls/shell32/tests/shlfolder.c | 53 ++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 3 deletions(-)
diff --git a/dlls/shell32/cpanelfolder.c b/dlls/shell32/cpanelfolder.c index 9619128d8b0..a45d36f35b0 100644 --- a/dlls/shell32/cpanelfolder.c +++ b/dlls/shell32/cpanelfolder.c @@ -536,6 +536,34 @@ static HRESULT WINAPI ISF_ControlPanel_fnCreateViewObject(IShellFolder2 *iface, return hr; }
+static BOOL validate_name_space(const ITEMIDLIST *pidl) +{ + HKEY hkey, hitem; + WCHAR *guidW; + GUID *guid; + LSTATUS r; + + if (!_ILIsPidlSimple(pidl)) + return FALSE; + + guid = _ILGetGUIDPointer(pidl); + if (!guid) + return FALSE; + if (StringFromCLSID(guid, &guidW) != S_OK) + return FALSE; + + r = RegOpenKeyW(HKEY_LOCAL_MACHINE, name_spaceW, &hkey); + if (r == ERROR_SUCCESS) + { + r = RegOpenKeyW(hkey, guidW, &hitem); + if (r == ERROR_SUCCESS) + RegCloseKey(hitem); + RegCloseKey(hkey); + } + CoTaskMemFree(guidW); + return r == ERROR_SUCCESS; +} + /************************************************************************** * ISF_ControlPanel_fnGetAttributesOf */ @@ -559,12 +587,17 @@ static HRESULT WINAPI ISF_ControlPanel_fnGetAttributesOf(IShellFolder2 *iface, U
while(cidl > 0 && *apidl) { pdump(*apidl); - SHELL32_GetItemAttributes(&This->IShellFolder2_iface, *apidl, rgfInOut); + + /* TODO: panel with GUID can contain sub-items but we don't support it yet */ + if (!(*rgfInOut & SFGAO_VALIDATE) || _ILGetCPanelPointer(*apidl) + || validate_name_space(*apidl)) + *rgfInOut &= SFGAO_CANLINK; + else + *rgfInOut &= SFGAO_VALIDATE; + apidl++; cidl--; } - /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */ - *rgfInOut &= ~SFGAO_VALIDATE;
TRACE("-- result=0x%08lx\n", *rgfInOut); return hr; diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c index 248fbd1df62..98064140107 100644 --- a/dlls/shell32/tests/shlfolder.c +++ b/dlls/shell32/tests/shlfolder.c @@ -956,6 +956,8 @@ static void test_GetAttributesOf(void) static WCHAR cTestDirW[] = {'t','e','s','t','d','i','r',0}; IShellFolder *IDesktopFolder, *testIShellFolder; ITEMIDLIST *newPIDL; + IEnumIDList *list; + ULONG fetch; int len;
hr = SHGetDesktopFolder(&psfDesktop); @@ -1070,6 +1072,57 @@ static void test_GetAttributesOf(void)
Cleanup();
+ /* test Control Panel elements */ + hr = IShellFolder_ParseDisplayName(IDesktopFolder, NULL, NULL, + (WCHAR *)L"::{21EC2020-3AEA-1069-A2DD-08002B30309D}", NULL, &newPIDL, 0); + ok(hr == S_OK, "ParseDisplayName failed %08lx\n", hr); + hr = IShellFolder_BindToObject(IDesktopFolder, newPIDL, NULL, + &IID_IShellFolder, (void**)&testIShellFolder); + ok(hr == S_OK, "BindToObject failed %08lx\n", hr); + ILFree(newPIDL); + + hr = IShellFolder_EnumObjects(testIShellFolder, NULL, SHCONTF_NONFOLDERS, &list); + ok(hr == S_OK, "EnumObjects failed %08lx\n", hr); + + while (IEnumIDList_Next(list, 1, &newPIDL, &fetch) == S_OK) + { + WCHAR name[256]; + STRRET strret; + + hr = IShellFolder_GetDisplayNameOf(testIShellFolder, newPIDL, SHGDN_FORPARSING, &strret); + ok(hr == S_OK, "GetDisplayNameOf failed %08lx\n", hr); + StrRetToBufW(&strret, newPIDL, name, ARRAY_SIZE(name)); + + dwFlags = ~0; + hr = IShellFolder_GetAttributesOf(testIShellFolder, 1, + (LPCITEMIDLIST*)&newPIDL, &dwFlags); + ok(hr == S_OK, "ControlPanel->GetAttributesOf failed %08lx\n", hr); + ok(dwFlags == SFGAO_CANLINK || + broken(!wcsncmp(L"::{26EE0668-A00A-44D7-9371-BEB064C98683}\", name, 41) + && dwFlags == SFGAO_VALIDATE), + "%s dwFlags = %08lx\n", debugstr_w(name), dwFlags); + ILFree(newPIDL); + } + IEnumIDList_Release(list); + + hr = IShellFolder_ParseDisplayName(IDesktopFolder, NULL, NULL, + (WCHAR*)L"c:\", NULL, &newPIDL, 0); + ok(hr == S_OK, "ParseDisplayName failed %08lx\n", hr); + + dwFlags = ~0; + hr = IShellFolder_GetAttributesOf(testIShellFolder, 1, + (LPCITEMIDLIST*)&newPIDL, &dwFlags); + ok(hr == S_OK, "ControlPanel->GetAttributesOf failed %08lx\n", hr); + ok(dwFlags == SFGAO_VALIDATE, "dwFlags = %08lx\n", dwFlags); + + dwFlags = ~0 & ~SFGAO_VALIDATE; + hr = IShellFolder_GetAttributesOf(testIShellFolder, 1, + (LPCITEMIDLIST*)&newPIDL, &dwFlags); + ok(hr == S_OK, "ControlPanel->GetAttributesOf failed %08lx\n", hr); + ok(dwFlags == SFGAO_CANLINK, "dwFlags = %08lx\n", dwFlags); + + ILFree(newPIDL); + IShellFolder_Release(testIShellFolder); IShellFolder_Release(IDesktopFolder); }
From: Piotr Caban piotr@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53222 --- dlls/shell32/tests/shlfolder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c index 98064140107..dc0b6cb2ee2 100644 --- a/dlls/shell32/tests/shlfolder.c +++ b/dlls/shell32/tests/shlfolder.c @@ -5133,7 +5133,7 @@ static void test_SHChangeNotify(BOOL test_new_delivery) entries[0].fRecursive = TRUE;
notifyID = SHChangeNotifyRegister(wnd, !test_new_delivery ? SHCNRF_ShellLevel : SHCNRF_ShellLevel|SHCNRF_NewDelivery, - SHCNE_ALLEVENTS, WM_USER_NOTIFY, 1, entries); + SHCNE_MKDIR | SHCNE_CREATE | SHCNE_RMDIR, WM_USER_NOTIFY, 1, entries); ok(notifyID != 0, "Failed to register a window for change notifications\n");
for (i = 0; i < ARRAY_SIZE(chnotify_tests); ++i)