shlwapi: Implement SHGetShellKey
Samuel Lidén Borell
samuellb at bredband.net
Wed Aug 9 15:57:53 CDT 2006
This patch implements SHGetShellKey. It's used by
SKAlloc/Delete/Get/SetValueW which I'm implementing and testing right now.
The function is documented here:
http://members.ozemail.com.au/~geoffch/samples/win32/shell/shlwapi/functions/shellkey/getkey.htm
I've made a simple GUI to test this function (as well as
SKAlloc/GetValueW), and tested it on WinXP SP2.
http://hem.bredband.net/lidsam/shellkeys.tar.bz2
---
dlls/shlwapi/ordinal.c | 167
++++++++++++++++++++++++++++++++++++++++++++-
dlls/shlwapi/shlwapi.spec | 2 -
2 files changed, 163 insertions(+), 6 deletions(-)
ffceaabd6babadf89075199de2cce1c779eb6d7d
diff --git a/dlls/shlwapi/ordinal.c b/dlls/shlwapi/ordinal.c
index 669cff0..e4cfea6 100644
--- a/dlls/shlwapi/ordinal.c
+++ b/dlls/shlwapi/ordinal.c
@@ -4306,13 +4306,170 @@ BOOL WINAPI SHSkipJunction(IBindCtx *pbc
return bRet;
}
-/***********************************************************************
- * SHGetShellKey (SHLWAPI.@)
+/*************************************************************************
+ * SHGetShellKey [SHLWAPI.491]
+ *
+ * This function creates a HKEY from an Shell-related registry key
+ * (SHELLKEY). This function is said to cache the keys on native Windows
+ * somehow, but we don't do that yet. The caching is NOT vital since the
+ * function always returns a new HKEY each time (on WinXP SP2).
+ *
+ * Geoff Chappell has documented this function here:
+ *
http://members.ozemail.com.au/~geoffch/samples/win32/shell/shlwapi/functions/shellkey/getkey.htm
+ *
+ * PARAMS
+ * nShellKey [I] Combination of a root key, key and subkey. See below
+ * pszSubKey [I] Optional name of a sub key
+ * bCreate [I] Whether the key should be created if non-existant
+ *
+ * Known nShellKey combinations:
+ * Mask Value Interpretation
+ * 0x0000000F (root) 0x00000001 HKEY_CURRENT_USER
+ * 0x00000002 HKEY_LOCAL_MACHINE
+ * 0x00000FF0 (key) 0x00000000
Software\Microsoft\Windows\CurrentVersion\Explorer
+ * 0x00000010 Software\Microsoft\Windows\Shell
+ * 0x00000020 Software\Microsoft\Windows\ShellNoRoam
+ * 0x00000030 Software\Classes
+ * 0x000FF000 (subkey) 0x00000000 (no subkey)
+ * 0x00001000 LocalizedResourceName
+ * 0x00002000 Handlers
+ * 0x00003000 Associations
+ * 0x00004000 Volatile
+ * 0x00005000 MUICache
+ * 0x00006000 FileExts
+ *
+ * RETURNS
+ * Success: The registry key.
+ * Failure: NULL, error value can be retrived using GetLastError
+ * The error value is E_INVALIDARG when an invalid nShellKey
+ * is used. If the key does not exist and bCreate is false,
+ * then the error value becomes ERROR_FILE_NOT_FOUND.
*/
-DWORD WINAPI SHGetShellKey(DWORD a, DWORD b, DWORD c)
+HKEY WINAPI SHGetShellKey(DWORD nShellKey, LPCWSTR pszSubKey, BOOL bCreate)
{
- FIXME("(%lx, %lx, %lx): stub\n", a, b, c);
- return 0x50;
+ /* Keys */
+ static const WCHAR SK_KEY_EXPLORER[] = {
+ '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'
+ };
+ static const WCHAR SK_KEY_SHELL[] = {
+ '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','\0'
+ };
+ static const WCHAR SK_KEY_SHELLNOROAM[] = {
+ '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','\0'
+ };
+ static const WCHAR SK_KEY_CLASSES[] = {
+ 'S','o','f','t','w','a','r','e','\\','C','l','a','s','s','e','s','\0'
+ };
+ static const WCHAR *SK_KEYS[] = {
+ SK_KEY_EXPLORER,
+ SK_KEY_SHELL,
+ SK_KEY_SHELLNOROAM,
+ SK_KEY_CLASSES
+ };
+ /* Subkeys */
+ static const WCHAR SK_SUBKEY_NONE[] = {
+ '\0'
+ };
+ static const WCHAR SK_SUBKEY_RESNAME[] = {
+
'\\','L','o','c','a','l','i','z','e','d','R','e','s','o','u','r','c','e',
+ 'N','a','m','e','\0'
+ };
+ static const WCHAR SK_SUBKEY_HANDLERS[] = {
+ '\\','H','a','n','d','l','e','r','s','\0'
+ };
+ static const WCHAR SK_SUBKEY_ASSOCIATIONS[] = {
+ '\\','A','s','s','o','c','i','a','t','i','o','n','s','\0'
+ };
+ static const WCHAR SK_SUBKEY_VOLATILE[] = {
+ '\\','V','o','l','a','t','i','l','e','\0'
+ };
+ static const WCHAR SK_SUBKEY_MUICACHE[] = {
+ '\\','M','U','I','C','a','c','h','e','\0'
+ };
+ static const WCHAR SK_SUBKEY_FILEEXTS[] = {
+ '\\','F','i','l','e','E','x','t','s','\0'
+ };
+ static const WCHAR *SK_SUBKEYS[] = {
+ SK_SUBKEY_NONE,
+ SK_SUBKEY_RESNAME,
+ SK_SUBKEY_HANDLERS,
+ SK_SUBKEY_ASSOCIATIONS,
+ SK_SUBKEY_VOLATILE,
+ SK_SUBKEY_MUICACHE,
+ SK_SUBKEY_FILEEXTS
+ };
+
+ HKEY hRootKey = 0;
+ HKEY hKey = 0;
+ HKEY hFinalKey = 0;
+ DWORD dwDummy, dwRet;
+
+ /* Longest possible key + NULL:
+
Software\Microsoft\Windows\CurrentVersion\Explorer\LocalizedResourceName */
+ WCHAR subkey[73];
+
+ TRACE("(%lx, %s, %s)\n", nShellKey, debugstr_w(pszSubKey), bCreate ?
"TRUE" : "FALSE");
+
+ /* Root key */
+ if ((nShellKey & 0x0000000F) == 0x00000001)
+ hRootKey = HKEY_CURRENT_USER;
+ else if ((nShellKey & 0x0000000F) == 0x00000002)
+ hRootKey = HKEY_LOCAL_MACHINE;
+ else
+ {
+ FIXME("Unknown root key: %lx. Falling back to HKCU\n", (nShellKey &
0x0000000F));
+ hRootKey = HKEY_CURRENT_USER;
+ }
+
+ /* Check for invalid values */
+ if (((nShellKey & 0x00000FF0) > 0x00000030) ||
+ ((nShellKey & 0x000FF000) > 0x00006000))
+ {
+ FIXME("Unsupported nShellKey %lx\n", nShellKey);
+ SetLastError(E_INVALIDARG);
+ return NULL;
+ }
+
+ /* Create subkey string */
+ lstrcpyW((WCHAR*)&subkey, SK_KEYS[(nShellKey & 0x00000FF0) >> 4]);
+ lstrcatW((WCHAR*)&subkey, SK_SUBKEYS[(nShellKey & 0x000FF000) >> 12]);
+
+ if (!bCreate)
+ dwRet = RegOpenKeyExW(hRootKey, subkey, 0, KEY_ALL_ACCESS, &hKey);
+ else
+ dwRet = RegCreateKeyExW(hRootKey, subkey, 0, NULL, 0,
+ KEY_ALL_ACCESS, NULL, &hKey, &dwDummy);
+ if (dwRet)
+ {
+ SetLastError(ERROR_FILE_NOT_FOUND);
+ return NULL;
+ }
+ if ((!pszSubKey) || (*pszSubKey == '\0'))
+ {
+ SetLastError(ERROR_SUCCESS);
+ return hKey;
+ }
+
+ /* Open pszSubKey */
+ if (!bCreate)
+ dwRet = RegOpenKeyExW(hKey, pszSubKey, 0, KEY_ALL_ACCESS, &hFinalKey);
+ else
+ dwRet = RegCreateKeyExW(hKey, pszSubKey, 0, NULL, 0,
+ KEY_ALL_ACCESS, NULL, &hFinalKey, &dwDummy);
+ RegCloseKey(hKey);
+ if (dwRet)
+ {
+ SetLastError(ERROR_FILE_NOT_FOUND);
+ return NULL;
+ }
+
+ SetLastError(ERROR_SUCCESS);
+ return hFinalKey;
}
/***********************************************************************
diff --git a/dlls/shlwapi/shlwapi.spec b/dlls/shlwapi/shlwapi.spec
index 0295e1b..ae42e85 100644
--- a/dlls/shlwapi/shlwapi.spec
+++ b/dlls/shlwapi/shlwapi.spec
@@ -488,7 +488,7 @@
488 stub -noname SHConvertGraphicsFile
489 stub -noname GlobalAddAtomWrapW
490 stub -noname GlobalFindAtomWrapW
-491 stdcall -noname SHGetShellKey(long long long)
+491 stdcall -noname SHGetShellKey(long wstr long)
492 stub -noname PrettifyFileDescriptionW
493 stub -noname SHPropertyBag_ReadType
494 stub -noname SHPropertyBag_ReadStr
--
1.2.4
More information about the wine-patches
mailing list