Piotr Caban : shlwapi: Improved SHGetShellKey implementation.
Alexandre Julliard
julliard at winehq.org
Tue Oct 12 11:27:01 CDT 2010
Module: wine
Branch: master
Commit: c2f25a2206d4786888fbd2191952cf3d80da6689
URL: http://source.winehq.org/git/wine.git/?a=commit;h=c2f25a2206d4786888fbd2191952cf3d80da6689
Author: Piotr Caban <piotr at codeweavers.com>
Date: Tue Oct 12 16:35:35 2010 +0200
shlwapi: Improved SHGetShellKey implementation.
---
dlls/shlwapi/ordinal.c | 127 +++++++++++++++++++++++++++++++++++++-----
dlls/shlwapi/tests/ordinal.c | 65 ++++++++++++++-------
2 files changed, 156 insertions(+), 36 deletions(-)
diff --git a/dlls/shlwapi/ordinal.c b/dlls/shlwapi/ordinal.c
index 3edb116..63fffb2 100644
--- a/dlls/shlwapi/ordinal.c
+++ b/dlls/shlwapi/ordinal.c
@@ -4406,36 +4406,135 @@ BOOL WINAPI SHSkipJunction(IBindCtx *pbc, const CLSID *pclsid)
HKEY WINAPI SHGetShellKey(DWORD flags, LPCWSTR sub_key, BOOL create)
{
enum _shellkey_flags {
- SHKEY_Explorer = 0x00,
- SHKEY_Root_HKCU = 0x01
+ SHKEY_Root_HKCU = 0x1,
+ SHKEY_Root_HKLM = 0x2,
+ SHKEY_Key_Explorer = 0x00,
+ SHKEY_Key_Shell = 0x10,
+ SHKEY_Key_ShellNoRoam = 0x20,
+ SHKEY_Key_Classes = 0x30,
+ SHKEY_Subkey_Default = 0x0000,
+ SHKEY_Subkey_ResourceName = 0x1000,
+ SHKEY_Subkey_Handlers = 0x2000,
+ SHKEY_Subkey_Associations = 0x3000,
+ SHKEY_Subkey_Volatile = 0x4000,
+ SHKEY_Subkey_MUICache = 0x5000,
+ SHKEY_Subkey_FileExts = 0x6000
};
static const WCHAR explorerW[] = {'S','o','f','t','w','a','r','e','\\',
'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
- 'E','x','p','l','o','r','e','r',0};
- HKEY hroot, hkey = NULL;
+ 'E','x','p','l','o','r','e','r','\\'};
+ static const WCHAR shellW[] = {'S','o','f','t','w','a','r','e','\\',
+ 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
+ 'S','h','e','l','l','\\'};
+ static const WCHAR shell_no_roamW[] = {'S','o','f','t','w','a','r','e','\\',
+ 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
+ 'S','h','e','l','l','N','o','R','o','a','m','\\'};
+ static const WCHAR classesW[] = {'S','o','f','t','w','a','r','e','\\',
+ 'C','l','a','s','s','e','s','\\'};
+
+ static const WCHAR localized_resource_nameW[] = {'L','o','c','a','l','i','z','e','d',
+ 'R','e','s','o','u','r','c','e','N','a','m','e','\\'};
+ static const WCHAR handlersW[] = {'H','a','n','d','l','e','r','s','\\'};
+ static const WCHAR associationsW[] = {'A','s','s','o','c','i','a','t','i','o','n','s','\\'};
+ static const WCHAR volatileW[] = {'V','o','l','a','t','i','l','e','\\'};
+ static const WCHAR mui_cacheW[] = {'M','U','I','C','a','c','h','e','\\'};
+ static const WCHAR file_extsW[] = {'F','i','l','e','E','x','t','s','\\'};
+
+ WCHAR *path;
+ const WCHAR *key, *subkey;
+ int size_key, size_subkey, size_user;
+ HKEY hkey = NULL;
TRACE("(0x%08x, %s, %d)\n", flags, debugstr_w(sub_key), create);
- switch (flags)
- {
- case SHKEY_Explorer | SHKEY_Root_HKCU:
- RegOpenKeyExW(HKEY_CURRENT_USER, explorerW, 0, MAXIMUM_ALLOWED, &hroot);
+ /* For compatibility with Vista+ */
+ if(flags == 0x1ffff)
+ flags = 0x21;
+
+ switch(flags&0xff0) {
+ case SHKEY_Key_Explorer:
+ key = explorerW;
+ size_key = sizeof(explorerW);
+ break;
+ case SHKEY_Key_Shell:
+ key = shellW;
+ size_key = sizeof(shellW);
+ break;
+ case SHKEY_Key_ShellNoRoam:
+ key = shell_no_roamW;
+ size_key = sizeof(shell_no_roamW);
+ break;
+ case SHKEY_Key_Classes:
+ key = classesW;
+ size_key = sizeof(classesW);
break;
- case 0:
+ default:
+ FIXME("unsupported flags (0x%08x)\n", flags);
return NULL;
+ }
+
+ switch(flags&0xff000) {
+ case SHKEY_Subkey_Default:
+ subkey = NULL;
+ size_subkey = 0;
+ break;
+ case SHKEY_Subkey_ResourceName:
+ subkey = localized_resource_nameW;
+ size_subkey = sizeof(localized_resource_nameW);
+ break;
+ case SHKEY_Subkey_Handlers:
+ subkey = handlersW;
+ size_subkey = sizeof(handlersW);
+ break;
+ case SHKEY_Subkey_Associations:
+ subkey = associationsW;
+ size_subkey = sizeof(associationsW);
+ break;
+ case SHKEY_Subkey_Volatile:
+ subkey = volatileW;
+ size_subkey = sizeof(volatileW);
+ break;
+ case SHKEY_Subkey_MUICache:
+ subkey = mui_cacheW;
+ size_subkey = sizeof(mui_cacheW);
+ break;
+ case SHKEY_Subkey_FileExts:
+ subkey = file_extsW;
+ size_subkey = sizeof(file_extsW);
+ break;
default:
FIXME("unsupported flags (0x%08x)\n", flags);
- return (HKEY)0xdeadbeef;
+ return NULL;
}
- if (create)
- RegCreateKeyExW(hroot, sub_key, 0, NULL, 0, MAXIMUM_ALLOWED, NULL, &hkey, NULL);
+ if(sub_key)
+ size_user = lstrlenW(sub_key)*sizeof(WCHAR);
+ else
+ size_user = 0;
+
+ path = HeapAlloc(GetProcessHeap(), 0, size_key+size_subkey+size_user);
+ if(!path) {
+ ERR("Out of memory\n");
+ return NULL;
+ }
+
+ memcpy(path, key, size_key);
+ if(subkey)
+ memcpy(path+size_key/sizeof(WCHAR), subkey, size_subkey);
+ if(sub_key)
+ memcpy(path+(size_key+size_subkey)/sizeof(WCHAR), sub_key, size_user);
+ path[(size_key+size_subkey+size_user)/sizeof(WCHAR)] = '\0';
+
+ if(create)
+ RegCreateKeyExW((flags&0xf)==SHKEY_Root_HKLM?HKEY_LOCAL_MACHINE:HKEY_CURRENT_USER,
+ path, 0, NULL, 0, MAXIMUM_ALLOWED, NULL, &hkey, NULL);
else
- RegOpenKeyExW(hroot, sub_key, 0, MAXIMUM_ALLOWED, &hkey);
+ RegOpenKeyExW((flags&0xf)==SHKEY_Root_HKLM?HKEY_LOCAL_MACHINE:HKEY_CURRENT_USER,
+ path, 0, MAXIMUM_ALLOWED, &hkey);
- RegCloseKey(hroot);
+ HeapFree(GetProcessHeap(), 0, path);
return hkey;
}
diff --git a/dlls/shlwapi/tests/ordinal.c b/dlls/shlwapi/tests/ordinal.c
index dfee9bf..1937cb0 100644
--- a/dlls/shlwapi/tests/ordinal.c
+++ b/dlls/shlwapi/tests/ordinal.c
@@ -61,7 +61,7 @@ static HWND (WINAPI *pSHCreateWorkerWindowA)(LONG, HWND, DWORD, DWORD, HMENU,
static HRESULT (WINAPI *pSHIShellFolder_EnumObjects)(LPSHELLFOLDER, HWND, SHCONTF, IEnumIDList**);
static DWORD (WINAPI *pSHGetIniStringW)(LPCWSTR, LPCWSTR, LPWSTR, DWORD, LPCWSTR);
static BOOL (WINAPI *pSHSetIniStringW)(LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR);
-static HKEY (WINAPI *pSHGetShellKey)(DWORD, LPWSTR, BOOL);
+static HKEY (WINAPI *pSHGetShellKey)(DWORD, LPCWSTR, BOOL);
static HMODULE hmlang;
static HRESULT (WINAPI *pLcidToRfc1766A)(LCID, LPSTR, INT);
@@ -2680,15 +2680,28 @@ static void test_SHSetIniString(void)
}
enum _shellkey_flags {
- SHKEY_Explorer = 0x00,
- SHKEY_Root_HKCU = 0x01
+ SHKEY_Root_HKCU = 0x1,
+ SHKEY_Root_HKLM = 0x2,
+ SHKEY_Key_Explorer = 0x00,
+ SHKEY_Key_Shell = 0x10,
+ SHKEY_Key_ShellNoRoam = 0x20,
+ SHKEY_Key_Classes = 0x30,
+ SHKEY_Subkey_Default = 0x0000,
+ SHKEY_Subkey_ResourceName = 0x1000,
+ SHKEY_Subkey_Handlers = 0x2000,
+ SHKEY_Subkey_Associations = 0x3000,
+ SHKEY_Subkey_Volatile = 0x4000,
+ SHKEY_Subkey_MUICache = 0x5000,
+ SHKEY_Subkey_FileExts = 0x6000
};
static void test_SHGetShellKey(void)
{
+ static const WCHAR ShellFoldersW[] = { 'S','h','e','l','l',' ','F','o','l','d','e','r','s',0 };
+ static const WCHAR WineTestW[] = { 'W','i','n','e','T','e','s','t',0 };
+
void *pPathBuildRootW = GetProcAddress(hShlwapi, "PathBuildRootW");
- HKEY hkey, hkey2;
- DWORD ret;
+ HKEY hkey;
if (!pSHGetShellKey)
{
@@ -2709,30 +2722,38 @@ static void test_SHGetShellKey(void)
return;
}
- /* marking broken cause latest Vista+ versions fail here */
+ /* Vista+ limits SHKEY enumeration values */
SetLastError(0xdeadbeef);
- hkey = pSHGetShellKey(SHKEY_Explorer, NULL, FALSE);
- ok(hkey == NULL || broken(hkey != NULL), "got %p\n", hkey);
+ hkey = pSHGetShellKey(SHKEY_Key_Explorer, ShellFoldersW, FALSE);
if (hkey)
{
- hkey2 = 0;
- ret = RegOpenKeyExA(hkey, "Shell Folders", 0, KEY_READ, &hkey2);
- ok(ret == ERROR_SUCCESS, "got %d\n", ret);
- ok(hkey2 != NULL, "got %p\n", hkey2);
- RegCloseKey( hkey2 );
- RegCloseKey( hkey );
+ /* Tests not working on Vista+ */
+ RegCloseKey(hkey);
+
+ hkey = pSHGetShellKey(SHKEY_Root_HKLM|SHKEY_Key_Classes, NULL, FALSE);
+ ok(hkey != NULL, "hkey = NULL\n");
+ RegCloseKey(hkey);
}
- hkey = pSHGetShellKey(SHKEY_Explorer | SHKEY_Root_HKCU, NULL, FALSE);
- ok(hkey != NULL, "got %p\n", hkey);
+ hkey = pSHGetShellKey(SHKEY_Root_HKCU|SHKEY_Key_Explorer, ShellFoldersW, FALSE);
+ ok(hkey != NULL, "hkey = NULL\n");
+ RegCloseKey(hkey);
+
+ hkey = pSHGetShellKey(SHKEY_Root_HKLM|SHKEY_Key_Explorer, ShellFoldersW, FALSE);
+ ok(hkey != NULL, "hkey = NULL\n");
+ RegCloseKey(hkey);
+
+ hkey = pSHGetShellKey(SHKEY_Root_HKLM, WineTestW, FALSE);
+ ok(hkey == NULL, "hkey != NULL\n");
- hkey2 = 0;
- ret = RegOpenKeyExA(hkey, "Shell Folders", 0, KEY_READ, &hkey2);
- ok(ret == ERROR_SUCCESS, "got %d\n", ret);
- ok(hkey2 != NULL, "got %p\n", hkey2);
- RegCloseKey( hkey2 );
+ hkey = pSHGetShellKey(SHKEY_Root_HKLM, WineTestW, TRUE);
+ ok(hkey != NULL, "Can't create key\n");
+ RegCloseKey(hkey);
- RegCloseKey( hkey );
+ hkey = pSHGetShellKey(SHKEY_Root_HKLM, NULL, FALSE);
+ ok(hkey != NULL, "Can't create key\n");
+ ok(SUCCEEDED(RegDeleteKeyW(hkey, WineTestW)), "Can't delte key\n");
+ RegCloseKey(hkey);
}
static void init_pointers(void)
More information about the wine-cvs
mailing list