From 06fb2139b007a7ee9ece6f9d95db3c92d7b3f316 Mon Sep 17 00:00:00 2001 From: "Guy L. Albertelli" Date: Sun, 21 Oct 2001 15:09:36 +0000 Subject: [PATCH] - Implement HUSKEY design. - Implement functions: SHRegOpenUSKey{A|W}, SHRegCloseUSKey, SHRegGetUSValue{A|W}, SHRegQueryInfoUSKey{A|W} --- dlls/shlwapi/reg.c | 284 ++++++++++++++++++++++++++++++++++++++------- include/shlwapi.h | 23 ++++ 2 files changed, 264 insertions(+), 43 deletions(-) diff --git a/dlls/shlwapi/reg.c b/dlls/shlwapi/reg.c index 429109c23e8..483bee0b9df 100644 --- a/dlls/shlwapi/reg.c +++ b/dlls/shlwapi/reg.c @@ -8,6 +8,7 @@ #include "wingdi.h" #include "winuser.h" #include "winerror.h" +#include "winnls.h" #include "winreg.h" #include "debugtools.h" #include "shlwapi.h" @@ -18,6 +19,143 @@ DEFAULT_DEBUG_CHANNEL(shell); static const char *lpszContentTypeA = "Content Type"; static const WCHAR lpszContentTypeW[] = { 'C','o','n','t','e','n','t',' ','T','y','p','e','\0'}; +/* internal structure of what the HUSKEY points to */ +typedef struct { + HKEY realkey; /* HKEY of opened key */ + HKEY start; /* HKEY of where to start */ + WCHAR key_string[MAX_PATH]; /* additional path from 'start' */ +} Internal_HUSKEY, *LPInternal_HUSKEY; + + +/************************************************************************* + * SHRegOpenUSKeyA [SHLWAPI.@] + * + * Opens a user-specific registry key + */ +LONG WINAPI SHRegOpenUSKeyA( + LPCSTR Path, + REGSAM AccessType, + HUSKEY hRelativeUSKey, + PHUSKEY phNewUSKey, + BOOL fIgnoreHKCU) +{ + HKEY startpoint, openkey; + LONG ret = ~ERROR_SUCCESS; + LPInternal_HUSKEY ihky; + + TRACE("(%s, 0x%lx, 0x%lx, %p, %s)\n", debugstr_a(Path), + (LONG)AccessType, (LONG)hRelativeUSKey, phNewUSKey, + (fIgnoreHKCU) ? "Ignoring HKCU" : "Process HKCU then HKLM"); + if (hRelativeUSKey) + startpoint = ((LPInternal_HUSKEY)hRelativeUSKey)->realkey; + else { + startpoint = HKEY_LOCAL_MACHINE; + if (!fIgnoreHKCU) { + ret = RegOpenKeyExA(HKEY_CURRENT_USER, Path, + 0, AccessType, &openkey); + /* if successful, then save real starting point */ + if (ret == ERROR_SUCCESS) + startpoint = HKEY_CURRENT_USER; + } + } + + /* if current_user didn't have it, or have relative start point, + * try it. + */ + if (ret != ERROR_SUCCESS) + ret = RegOpenKeyExA(startpoint, Path, 0, AccessType, &openkey); + + /* if all attempts have failed then bail */ + if (ret != ERROR_SUCCESS) { + TRACE("failed %ld\n", ret); + return ret; + } + + /* now create the internal version of HUSKEY */ + ihky = (LPInternal_HUSKEY)HeapAlloc(GetProcessHeap(), 0 , + sizeof(Internal_HUSKEY)); + ihky->realkey = openkey; + ihky->start = startpoint; + MultiByteToWideChar(0, 0, Path, -1, ihky->key_string, + sizeof(ihky->key_string)-1); + TRACE("HUSKEY=0x%08lx\n", (LONG)ihky); + if (phNewUSKey) + *phNewUSKey = (HUSKEY)ihky; + return ERROR_SUCCESS; +} + +/************************************************************************* + * SHRegOpenUSKeyW [SHLWAPI.@] + * + * Opens a user-specific registry key + */ +LONG WINAPI SHRegOpenUSKeyW( + LPCWSTR Path, + REGSAM AccessType, + HUSKEY hRelativeUSKey, + PHUSKEY phNewUSKey, + BOOL fIgnoreHKCU) +{ + HKEY startpoint, openkey; + LONG ret = ~ERROR_SUCCESS; + LPInternal_HUSKEY ihky; + + TRACE("(%s, 0x%lx, 0x%lx, %p, %s)\n", debugstr_w(Path), + (LONG)AccessType, (LONG)hRelativeUSKey, phNewUSKey, + (fIgnoreHKCU) ? "Ignoring HKCU" : "Process HKCU then HKLM"); + if (hRelativeUSKey) + startpoint = ((LPInternal_HUSKEY)hRelativeUSKey)->realkey; + else { + startpoint = HKEY_LOCAL_MACHINE; + if (!fIgnoreHKCU) { + ret = RegOpenKeyExW(HKEY_CURRENT_USER, Path, + 0, AccessType, &openkey); + /* if successful, then save real starting point */ + if (ret == ERROR_SUCCESS) + startpoint = HKEY_CURRENT_USER; + } + } + + /* if current_user didn't have it, or have relative start point, + * try it. + */ + if (ret != ERROR_SUCCESS) + ret = RegOpenKeyExW(startpoint, Path, 0, AccessType, &openkey); + + /* if all attempts have failed then bail */ + if (ret != ERROR_SUCCESS) { + TRACE("failed %ld\n", ret); + return ret; + } + + /* now create the internal version of HUSKEY */ + ihky = (LPInternal_HUSKEY)HeapAlloc(GetProcessHeap(), 0 , + sizeof(Internal_HUSKEY)); + ihky->realkey = openkey; + ihky->start = startpoint; + lstrcpynW(ihky->key_string, Path, sizeof(ihky->key_string)); + TRACE("HUSKEY=0x%08lx\n", (LONG)ihky); + if (phNewUSKey) + *phNewUSKey = (HUSKEY)ihky; + return ERROR_SUCCESS; +} + +/************************************************************************* + * SHRegCloseUSKey [SHLWAPI.@] + * + * Closes a user-specific registry key + */ +LONG WINAPI SHRegCloseUSKey( + HUSKEY hUSKey) +{ + LPInternal_HUSKEY mihk = (LPInternal_HUSKEY)hUSKey; + LONG ret; + + ret = RegCloseKey(mihk->realkey); + HeapFree(GetProcessHeap(), 0, mihk); + return ret; +} + /************************************************************************* * SHRegGetUSValueA [SHLWAPI.@] * @@ -28,13 +166,40 @@ LONG WINAPI SHRegGetUSValueA( LPCSTR pValue, LPDWORD pwType, LPVOID pvData, - LPDWORD pbData, - BOOL fIgnoreHKCU, + LPDWORD pcbData, + BOOL flagIgnoreHKCU, LPVOID pDefaultData, DWORD wDefaultDataSize) { - FIXME("(%p),stub!\n", pSubKey); - return ERROR_SUCCESS; /* return success */ + HUSKEY myhuskey; + LPInternal_HUSKEY mihk; + LONG ret, maxmove, i; + CHAR *src, *dst; + + if (!pvData || !pcbData) return ERROR_INVALID_FUNCTION; /* FIXME:wrong*/ + TRACE("key '%s', value '%s', datalen %ld, %s\n", + debugstr_a(pSubKey), debugstr_a(pValue), *pcbData, + (flagIgnoreHKCU) ? "Ignoring HKCU" : "Trys HKCU then HKLM"); + + ret = SHRegOpenUSKeyA(pSubKey, 0x1, 0, &myhuskey, flagIgnoreHKCU); + if (ret == ERROR_SUCCESS) { + mihk = (LPInternal_HUSKEY) myhuskey; + ret = RegQueryValueExA(mihk->realkey, pValue, 0, pwType, + (LPBYTE)pvData, pcbData); + SHRegCloseUSKey(myhuskey); + } + if (ret != ERROR_SUCCESS) { + if (pDefaultData && (wDefaultDataSize != 0)) { + maxmove = (wDefaultDataSize >= *pcbData) ? *pcbData : wDefaultDataSize; + src = (CHAR*)pDefaultData; + dst = (CHAR*)pvData; + for(i=0; irealkey, pValue, 0, pwType, + (LPBYTE)pvData, pcbData); + SHRegCloseUSKey(myhuskey); + } + if (ret != ERROR_SUCCESS) { + if (pDefaultData && (wDefaultDataSize != 0)) { + maxmove = (wDefaultDataSize >= *pcbData) ? *pcbData : wDefaultDataSize; + src = (CHAR*)pDefaultData; + dst = (CHAR*)pvData; + for(i=0; irealkey, 0, 0, 0, + pcSubKeys, pcchMaxSubKeyLen, 0, + pcValues, pcchMaxValueNameLen, 0, 0, 0); +} + +/************************************************************************* + * SHRegQueryInfoUSKeyW [SHLWAPI.@] + */ +DWORD WINAPI SHRegQueryInfoUSKeyW( + HUSKEY hUSKey, /* [in] FIXME: HUSKEY */ + LPDWORD pcSubKeys, + LPDWORD pcchMaxSubKeyLen, + LPDWORD pcValues, + LPDWORD pcchMaxValueNameLen, + SHREGENUM_FLAGS enumRegFlags) +{ + TRACE("(0x%lx,%p,%p,%p,%p,%d)\n", + (LONG)hUSKey,pcSubKeys,pcchMaxSubKeyLen,pcValues, + pcchMaxValueNameLen,enumRegFlags); + return RegQueryInfoKeyW(((LPInternal_HUSKEY)hUSKey)->realkey, 0, 0, 0, + pcSubKeys, pcchMaxSubKeyLen, 0, + pcValues, pcchMaxValueNameLen, 0, 0, 0); +} + /************************************************************************* * SHRegEnumUSKeyA [SHLWAPI.@] */ LONG WINAPI SHRegEnumUSKeyA( - HKEY hUSKey, /* [in] FIXME: HUSKEY */ + HUSKEY hUSKey, /* [in] */ DWORD dwIndex, LPSTR pszName, LPDWORD pcchValueNameLen, - DWORD enumRegFlags) /* [in] FIXME: SHREGENUM_FLAGS */ + SHREGENUM_FLAGS enumRegFlags) /* [in] */ { FIXME("%s stub\n",debugstr_a(pszName)); return ERROR_NO_MORE_ITEMS; @@ -166,11 +364,11 @@ LONG WINAPI SHRegEnumUSKeyA( * SHRegEnumUSKeyW [SHLWAPI.@] */ LONG WINAPI SHRegEnumUSKeyW( - HKEY hUSKey, /* [in] FIXME: HUSKEY */ + HUSKEY hUSKey, /* [in] */ DWORD dwIndex, LPWSTR pszName, LPDWORD pcchValueNameLen, - DWORD enumRegFlags) /* [in] FIXME: SHREGENUM_FLAGS */ + SHREGENUM_FLAGS enumRegFlags) /* [in] */ { FIXME("%s stub\n",debugstr_w(pszName)); return ERROR_NO_MORE_ITEMS; diff --git a/include/shlwapi.h b/include/shlwapi.h index 1de8c3876f1..e403fb27390 100644 --- a/include/shlwapi.h +++ b/include/shlwapi.h @@ -214,6 +214,9 @@ HRESULT WINAPI StrRetToBufA(struct _STRRET *src, const struct _ITEMIDLIST *pidl, HRESULT WINAPI StrRetToBufW(struct _STRRET *src, const struct _ITEMIDLIST *pidl, LPWSTR dest, DWORD len); #define StrRetToBuf WINELIB_NAME_AW(StrRetToBuf) + +/* Shell Registry interfaces */ + HRESULT WINAPI SHQueryValueExA(HKEY hkey, LPSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData); HRESULT WINAPI SHQueryValueExW(HKEY hkey, LPWSTR pszValue, LPDWORD pdwReserved, LPDWORD pdwType, LPVOID pvData, LPDWORD pcbData); #define SHQueryValueEx WINELIB_NAME_AW(SHQueryValueEx) @@ -226,6 +229,26 @@ DWORD WINAPI SHDeleteEmptyKeyA(HKEY hKey, LPCSTR lpszSubKey); DWORD WINAPI SHDeleteEmptyKeyW(HKEY hKey, LPCWSTR lpszSubKey); #define SHDeleteEmptyKey WINELIB_NAME_AW(SHDeleteEmptyKey) + +typedef HANDLE HUSKEY; +typedef HUSKEY *PHUSKEY; + +typedef enum { + SHREGDEL_DEFAULT = 0, /* delete HKCU if found or HKLM if not */ + SHREGDEL_HKCU = 0x01, /* delete HKCU */ + SHREGDEL_HKLM = 0x10, /* delete HKLM */ + SHREGDEL_BOTH = 0x11, /* delete HKCU *and* HKLM */ +} SHREGDEL_FLAGS; + +typedef enum { + SHREGENUM_DEFAULT = 0, /* do HKCU or HKLM if not found */ + SHREGENUM_HKCU = 0x01, /* do HKCU only */ + SHREGENUM_HKLM = 0x10, /* do HKLM only */ + SHREGENUM_BOTH = 0x11, /* do both HKCU and HKLM without dups */ +} SHREGENUM_FLAGS; + + + HRESULT WINAPI UrlCanonicalizeA(LPCSTR pszUrl, LPSTR pszCanonicalized, LPDWORD pcchCanonicalized, DWORD dwFlags); HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized,