Make copies of keys when creating, free them when done.

Use KEY_ALL_ACCESS when writing US reg values.
SHRegWriteUSValueW: Handle all flag combinations.
Make some A calls use the W version.
This commit is contained in:
Jon Griffiths 2004-03-17 20:48:03 +00:00 committed by Alexandre Julliard
parent 19271d7ae9
commit 919aa96d14
1 changed files with 199 additions and 200 deletions

View File

@ -47,11 +47,12 @@ static const WCHAR szExtensionW[] = { 'E', 'x', 't','e','n','s','i','o','n','\0'
/* internal structure of what the HUSKEY points to */ /* internal structure of what the HUSKEY points to */
typedef struct { typedef struct {
HKEY HKCUkey; /* HKEY of opened HKCU key */ HKEY HKCUstart; /* Start key in CU hive */
HKEY HKLMkey; /* HKEY of opened HKLM key */ HKEY HKCUkey; /* Opened key in CU hive */
HKEY start; /* HKEY of where to start */ HKEY HKLMstart; /* Start key in LM hive */
WCHAR key_string[MAX_PATH]; /* additional path from 'start' */ HKEY HKLMkey; /* Opened key in LM hive */
} Internal_HUSKEY, *LPInternal_HUSKEY; WCHAR lpszPath[MAX_PATH];
} SHUSKEY, *LPSHUSKEY;
DWORD WINAPI SHStringFromGUIDW(REFGUID,LPWSTR,INT); DWORD WINAPI SHStringFromGUIDW(REFGUID,LPWSTR,INT);
HRESULT WINAPI SHRegGetCLSIDKeyW(REFGUID,LPCWSTR,BOOL,BOOL,PHKEY); HRESULT WINAPI SHRegGetCLSIDKeyW(REFGUID,LPCWSTR,BOOL,BOOL,PHKEY);
@ -68,7 +69,7 @@ HRESULT WINAPI SHRegGetCLSIDKeyW(REFGUID,LPCWSTR,BOOL,BOOL,PHKEY);
static HKEY WINAPI REG_GetHKEYFromHUSKEY(HUSKEY hUSKey, BOOL which) static HKEY WINAPI REG_GetHKEYFromHUSKEY(HUSKEY hUSKey, BOOL which)
{ {
HKEY test = (HKEY) hUSKey; HKEY test = (HKEY) hUSKey;
LPInternal_HUSKEY mihk = (LPInternal_HUSKEY) hUSKey; LPSHUSKEY mihk = (LPSHUSKEY) hUSKey;
if ((test == HKEY_CLASSES_ROOT) || if ((test == HKEY_CLASSES_ROOT) ||
(test == HKEY_CURRENT_CONFIG) || (test == HKEY_CURRENT_CONFIG) ||
@ -89,72 +90,29 @@ static HKEY WINAPI REG_GetHKEYFromHUSKEY(HUSKEY hUSKey, BOOL which)
/************************************************************************* /*************************************************************************
* SHRegOpenUSKeyA [SHLWAPI.@] * SHRegOpenUSKeyA [SHLWAPI.@]
* *
* Opens a user-specific registry key * Open a user-specific registry key.
*
* PARAMS
* Path [I] Key name to open
* AccessType [I] Access type
* hRelativeUSKey [I] Relative user key
* phNewUSKey [O] Destination for created key
* fIgnoreHKCU [I] TRUE=Don't check HKEY_CURRENT_USER
* *
* RETURNS * RETURNS
* Success: ERROR_SUCCESS * Success: ERROR_SUCCESS
* Failure: An error code from RegOpenKeyExA(). * Failure: An error code from RegOpenKeyExA().
*/ */
LONG WINAPI SHRegOpenUSKeyA( LONG WINAPI SHRegOpenUSKeyA(LPCSTR Path, REGSAM AccessType, HUSKEY hRelativeUSKey,
LPCSTR Path, /* [I] Key name to open */ PHUSKEY phNewUSKey, BOOL fIgnoreHKCU)
REGSAM AccessType, /* [I] Access type */
HUSKEY hRelativeUSKey, /* [I] Relative user key */
PHUSKEY phNewUSKey, /* [O] Destination for created key */
BOOL fIgnoreHKCU) /* [I] TRUE=Don't check HKEY_CURRENT_USER */
{ {
HKEY openHKCUkey=0; WCHAR szPath[MAX_PATH];
HKEY openHKLMkey=0;
LONG ret2, ret1 = ~ERROR_SUCCESS;
LPInternal_HUSKEY ihky;
TRACE("(%s, 0x%lx, 0x%lx, %p, %s)\n", debugstr_a(Path), if (Path)
(LONG)AccessType, (LONG)hRelativeUSKey, phNewUSKey, MultiByteToWideChar(CP_ACP, 0, Path, -1, szPath, MAX_PATH);
(fIgnoreHKCU) ? "Ignoring HKCU" : "Process HKCU then HKLM");
/* now create the internal version of HUSKEY */ return SHRegOpenUSKeyW(Path ? szPath : NULL, AccessType, hRelativeUSKey,
ihky = (LPInternal_HUSKEY)HeapAlloc(GetProcessHeap(), 0 , phNewUSKey, fIgnoreHKCU);
sizeof(Internal_HUSKEY));
MultiByteToWideChar(0, 0, Path, -1, ihky->key_string,
sizeof(ihky->key_string)-1);
if (hRelativeUSKey) {
openHKCUkey = ((LPInternal_HUSKEY)hRelativeUSKey)->HKCUkey;
openHKLMkey = ((LPInternal_HUSKEY)hRelativeUSKey)->HKLMkey;
}
else {
openHKCUkey = HKEY_CURRENT_USER;
openHKLMkey = HKEY_LOCAL_MACHINE;
}
ihky->HKCUkey = 0;
ihky->HKLMkey = 0;
if (!fIgnoreHKCU) {
ret1 = RegOpenKeyExA(openHKCUkey, Path,
0, AccessType, &ihky->HKCUkey);
/* if successful, then save real starting point */
if (ret1 != ERROR_SUCCESS)
ihky->HKCUkey = 0;
}
ret2 = RegOpenKeyExA(openHKLMkey, Path,
0, AccessType, &ihky->HKLMkey);
if (ret2 != ERROR_SUCCESS)
ihky->HKLMkey = 0;
if ((ret1 != ERROR_SUCCESS) || (ret2 != ERROR_SUCCESS))
TRACE("one or more opens failed: HKCU=%ld HKLM=%ld\n", ret1, ret2);
/* if all attempts have failed then bail */
if ((ret1 != ERROR_SUCCESS) && (ret2 != ERROR_SUCCESS)) {
HeapFree(GetProcessHeap(), 0, ihky);
if (phNewUSKey)
*phNewUSKey = NULL;
return ret2;
}
TRACE("HUSKEY=%p\n", ihky);
if (phNewUSKey)
*phNewUSKey = (HUSKEY)ihky;
return ERROR_SUCCESS;
} }
/************************************************************************* /*************************************************************************
@ -162,64 +120,61 @@ LONG WINAPI SHRegOpenUSKeyA(
* *
* See SHRegOpenUSKeyA. * See SHRegOpenUSKeyA.
*/ */
LONG WINAPI SHRegOpenUSKeyW( LONG WINAPI SHRegOpenUSKeyW(LPCWSTR Path, REGSAM AccessType, HUSKEY hRelativeUSKey,
LPCWSTR Path, PHUSKEY phNewUSKey, BOOL fIgnoreHKCU)
REGSAM AccessType,
HUSKEY hRelativeUSKey,
PHUSKEY phNewUSKey,
BOOL fIgnoreHKCU)
{ {
HKEY openHKCUkey=0;
HKEY openHKLMkey=0;
LONG ret2, ret1 = ~ERROR_SUCCESS; LONG ret2, ret1 = ~ERROR_SUCCESS;
LPInternal_HUSKEY ihky; LPSHUSKEY hKey;
TRACE("(%s, 0x%lx, 0x%lx, %p, %s)\n", debugstr_w(Path), TRACE("(%s,0x%lx,%p,%p,%d)\n", debugstr_w(Path),(LONG)AccessType,
(LONG)AccessType, (LONG)hRelativeUSKey, phNewUSKey, hRelativeUSKey, phNewUSKey, fIgnoreHKCU);
(fIgnoreHKCU) ? "Ignoring HKCU" : "Process HKCU then HKLM");
/* now create the internal version of HUSKEY */
ihky = (LPInternal_HUSKEY)HeapAlloc(GetProcessHeap(), 0 ,
sizeof(Internal_HUSKEY));
lstrcpynW(ihky->key_string, Path, sizeof(ihky->key_string));
if (hRelativeUSKey) {
openHKCUkey = ((LPInternal_HUSKEY)hRelativeUSKey)->HKCUkey;
openHKLMkey = ((LPInternal_HUSKEY)hRelativeUSKey)->HKLMkey;
}
else {
openHKCUkey = HKEY_CURRENT_USER;
openHKLMkey = HKEY_LOCAL_MACHINE;
}
ihky->HKCUkey = 0;
ihky->HKLMkey = 0;
if (!fIgnoreHKCU) {
ret1 = RegOpenKeyExW(openHKCUkey, Path,
0, AccessType, &ihky->HKCUkey);
/* if successful, then save real starting point */
if (ret1 != ERROR_SUCCESS)
ihky->HKCUkey = 0;
}
ret2 = RegOpenKeyExW(openHKLMkey, Path,
0, AccessType, &ihky->HKLMkey);
if (ret2 != ERROR_SUCCESS)
ihky->HKLMkey = 0;
if ((ret1 != ERROR_SUCCESS) || (ret2 != ERROR_SUCCESS))
TRACE("one or more opens failed: HKCU=%ld HKLM=%ld\n", ret1, ret2);
/* if all attempts have failed then bail */
if ((ret1 != ERROR_SUCCESS) && (ret2 != ERROR_SUCCESS)) {
HeapFree(GetProcessHeap(), 0, ihky);
if (phNewUSKey) if (phNewUSKey)
*phNewUSKey = NULL; *phNewUSKey = NULL;
/* Create internal HUSKEY */
hKey = (LPSHUSKEY)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*hKey));
lstrcpynW(hKey->lpszPath, Path, sizeof(hKey->lpszPath));
if (hRelativeUSKey)
{
hKey->HKCUstart = SHRegDuplicateHKey(REG_GetHKEYFromHUSKEY(hRelativeUSKey, REG_HKCU));
hKey->HKLMstart = SHRegDuplicateHKey(REG_GetHKEYFromHUSKEY(hRelativeUSKey, REG_HKLM));
/* FIXME: if either of these keys is NULL, create the start key from
* the relative keys start+path
*/
}
else
{
hKey->HKCUstart = HKEY_CURRENT_USER;
hKey->HKLMstart = HKEY_LOCAL_MACHINE;
}
if (!fIgnoreHKCU)
{
ret1 = RegOpenKeyExW(hKey->HKCUstart, hKey->lpszPath, 0, AccessType, &hKey->HKCUkey);
if (ret1)
hKey->HKCUkey = 0;
}
ret2 = RegOpenKeyExW(hKey->HKLMstart, hKey->lpszPath, 0, AccessType, &hKey->HKLMkey);
if (ret2)
hKey->HKLMkey = 0;
if (ret1 || ret2)
TRACE("one or more opens failed: HKCU=%ld HKLM=%ld\n", ret1, ret2);
if (ret1 && ret2)
{
/* Neither open succeeded: fail */
SHRegCloseUSKey(hKey);
return ret2; return ret2;
} }
TRACE("HUSKEY=0x%08lx\n", (LONG)ihky); TRACE("HUSKEY=%p\n", hKey);
if (phNewUSKey) if (phNewUSKey)
*phNewUSKey = (HUSKEY)ihky; *phNewUSKey = (HUSKEY)hKey;
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
@ -235,14 +190,19 @@ LONG WINAPI SHRegOpenUSKeyW(
LONG WINAPI SHRegCloseUSKey( LONG WINAPI SHRegCloseUSKey(
HUSKEY hUSKey) /* [I] Key to close */ HUSKEY hUSKey) /* [I] Key to close */
{ {
LPInternal_HUSKEY mihk = (LPInternal_HUSKEY)hUSKey; LPSHUSKEY hKey = (LPSHUSKEY)hUSKey;
LONG ret = ERROR_SUCCESS; LONG ret = ERROR_SUCCESS;
if (mihk->HKCUkey) if (hKey->HKCUkey)
ret = RegCloseKey(mihk->HKCUkey); ret = RegCloseKey(hKey->HKCUkey);
if (mihk->HKLMkey) if (hKey->HKCUstart && hKey->HKCUstart != HKEY_CURRENT_USER)
ret = RegCloseKey(mihk->HKLMkey); ret = RegCloseKey(hKey->HKCUstart);
HeapFree(GetProcessHeap(), 0, mihk); if (hKey->HKLMkey)
ret = RegCloseKey(hKey->HKLMkey);
if (hKey->HKLMstart && hKey->HKLMstart != HKEY_LOCAL_MACHINE)
ret = RegCloseKey(hKey->HKCUstart);
HeapFree(GetProcessHeap(), 0, hKey);
return ret; return ret;
} }
@ -429,6 +389,14 @@ LONG WINAPI SHRegGetUSValueW(
* *
* Set a user-specific registry value. * Set a user-specific registry value.
* *
* PARAMS
* pszSubKey [I] Name of key to set the value in
* pszValue [I] Name of value under pszSubKey to set the value in
* dwType [I] Type of the value
* pvData [I] Data to set as the value
* cbData [I] length of pvData
* dwFlags [I] SHREGSET_ flags from "shlwapi.h"
*
* RETURNS * RETURNS
* Success: ERROR_SUCCESS * Success: ERROR_SUCCESS
* Failure: An error code from SHRegOpenUSKeyA() or SHRegWriteUSValueA(), or * Failure: An error code from SHRegOpenUSKeyA() or SHRegWriteUSValueA(), or
@ -437,29 +405,27 @@ LONG WINAPI SHRegGetUSValueW(
* NOTES * NOTES
* This function opens pszSubKey, sets the value, and then closes the key. * This function opens pszSubKey, sets the value, and then closes the key.
*/ */
LONG WINAPI SHRegSetUSValueA( LONG WINAPI SHRegSetUSValueA(LPCSTR pszSubKey, LPCSTR pszValue, DWORD dwType,
LPCSTR pszSubKey, /* [I] Name of key to set the value in */ LPVOID pvData, DWORD cbData, DWORD dwFlags)
LPCSTR pszValue, /* [I] Name of value under pszSubKey to set the value in */
DWORD dwType, /* [I] Type of the value */
LPVOID pvData, /* [I] Data to set as the value */
DWORD cbData, /* [I] length of pvData */
DWORD dwFlags) /* [I] SHREGSET_ flags from "shlwapi.h" */
{ {
HUSKEY myhuskey; BOOL ignoreHKCU = TRUE;
HUSKEY hkey;
LONG ret; LONG ret;
BOOL ignoreHKCU;
if (!pvData) return ERROR_INVALID_FUNCTION; TRACE("(%s,%s,%ld,%p,%ld,0x%08lx\n", debugstr_a(pszSubKey), debugstr_a(pszValue),
TRACE("key '%s', value '%s', datalen %ld\n", dwType, pvData, cbData, dwFlags);
debugstr_a(pszSubKey), debugstr_a(pszValue), cbData);
ignoreHKCU = ((dwFlags == SHREGSET_HKLM) || (dwFlags == SHREGSET_FORCE_HKLM)); if (!pvData)
return ERROR_INVALID_FUNCTION;
ret = SHRegOpenUSKeyA(pszSubKey, 0x1, 0, &myhuskey, ignoreHKCU); if (dwFlags & SHREGSET_HKCU || dwFlags & SHREGSET_FORCE_HKCU)
if (ret == ERROR_SUCCESS) { ignoreHKCU = FALSE;
ret = SHRegWriteUSValueA(myhuskey, pszValue, dwType, pvData,
cbData, dwFlags); ret = SHRegOpenUSKeyA(pszSubKey, KEY_ALL_ACCESS, 0, &hkey, ignoreHKCU);
SHRegCloseUSKey(myhuskey); if (ret == ERROR_SUCCESS)
{
ret = SHRegWriteUSValueA(hkey, pszValue, dwType, pvData, cbData, dwFlags);
SHRegCloseUSKey(hkey);
} }
return ret; return ret;
} }
@ -469,29 +435,27 @@ LONG WINAPI SHRegSetUSValueA(
* *
* See SHRegSetUSValueA. * See SHRegSetUSValueA.
*/ */
LONG WINAPI SHRegSetUSValueW( LONG WINAPI SHRegSetUSValueW(LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD dwType,
LPCWSTR pszSubKey, LPVOID pvData, DWORD cbData, DWORD dwFlags)
LPCWSTR pszValue,
DWORD dwType,
LPVOID pvData,
DWORD cbData,
DWORD dwFlags)
{ {
HUSKEY myhuskey; BOOL ignoreHKCU = TRUE;
HUSKEY hkey;
LONG ret; LONG ret;
BOOL ignoreHKCU;
if (!pvData) return ERROR_INVALID_FUNCTION; TRACE("(%s,%s,%ld,%p,%ld,0x%08lx\n", debugstr_w(pszSubKey), debugstr_w(pszValue),
TRACE("key '%s', value '%s', datalen %ld\n", dwType, pvData, cbData, dwFlags);
debugstr_w(pszSubKey), debugstr_w(pszValue), cbData);
ignoreHKCU = ((dwFlags == SHREGSET_HKLM) || (dwFlags == SHREGSET_FORCE_HKLM)); if (!pvData)
return ERROR_INVALID_FUNCTION;
ret = SHRegOpenUSKeyW(pszSubKey, 0x1, 0, &myhuskey, ignoreHKCU); if (dwFlags & SHREGSET_HKCU || dwFlags & SHREGSET_FORCE_HKCU)
if (ret == ERROR_SUCCESS) { ignoreHKCU = FALSE;
ret = SHRegWriteUSValueW(myhuskey, pszValue, dwType, pvData,
cbData, dwFlags); ret = SHRegOpenUSKeyW(pszSubKey, KEY_ALL_ACCESS, 0, &hkey, ignoreHKCU);
SHRegCloseUSKey(myhuskey); if (ret == ERROR_SUCCESS)
{
ret = SHRegWriteUSValueW(hkey, pszValue, dwType, pvData, cbData, dwFlags);
SHRegCloseUSKey(hkey);
} }
return ret; return ret;
} }
@ -801,31 +765,22 @@ LONG WINAPI SHRegEnumUSKeyW(
* *
* RETURNS * RETURNS
* Success: ERROR_SUCCESS. * Success: ERROR_SUCCESS.
* Failure: An error code from RegSetValueExA(). * Failure: ERROR_INVALID_PARAMETER, if any parameter is invalid, otherwise
* an error code from RegSetValueExA().
*
* NOTES
* dwFlags must have at least SHREGSET_FORCE_HKCU or SHREGSET_FORCE_HKLM set.
*/ */
LONG WINAPI SHRegWriteUSValueA(HUSKEY hUSKey, LPCSTR pszValue, DWORD dwType, LONG WINAPI SHRegWriteUSValueA(HUSKEY hUSKey, LPCSTR pszValue, DWORD dwType,
LPVOID pvData, DWORD cbData, DWORD dwFlags) LPVOID pvData, DWORD cbData, DWORD dwFlags)
{ {
HKEY dokey; WCHAR szValue[MAX_PATH];
TRACE("(%p,%s,%ld,%p,%ld,%ld)\n", if (pszValue)
hUSKey, debugstr_a(pszValue), dwType, pvData, cbData, dwFlags); MultiByteToWideChar(CP_ACP, 0, pszValue, -1, szValue, MAX_PATH);
if ((dwFlags & SHREGSET_FORCE_HKCU) && return SHRegWriteUSValueW(hUSKey, pszValue ? szValue : NULL, dwType,
(dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) { pvData, cbData, dwFlags);
RegSetValueExA(dokey, pszValue, 0, dwType, pvData, cbData);
}
if ((dwFlags & SHREGSET_FORCE_HKLM) &&
(dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) {
RegSetValueExA(dokey, pszValue, 0, dwType, pvData, cbData);
}
if (dwFlags & (SHREGSET_FORCE_HKCU | SHREGSET_FORCE_HKLM))
return ERROR_SUCCESS;
FIXME("SHREGSET_HKCU or SHREGSET_HKLM not supported\n");
return ERROR_SUCCESS;
} }
/************************************************************************* /*************************************************************************
@ -836,26 +791,70 @@ LONG WINAPI SHRegWriteUSValueA(HUSKEY hUSKey, LPCSTR pszValue, DWORD dwType,
LONG WINAPI SHRegWriteUSValueW(HUSKEY hUSKey, LPCWSTR pszValue, DWORD dwType, LONG WINAPI SHRegWriteUSValueW(HUSKEY hUSKey, LPCWSTR pszValue, DWORD dwType,
LPVOID pvData, DWORD cbData, DWORD dwFlags) LPVOID pvData, DWORD cbData, DWORD dwFlags)
{ {
HKEY dokey; LONG dummy;
LPSHUSKEY hKey = (LPSHUSKEY)hUSKey;
LONG ret = ERROR_SUCCESS;
TRACE("(%p,%s,%ld,%p,%ld,%ld)\n", TRACE("(%p,%s,%ld,%p,%ld,%ld)\n", hUSKey, debugstr_w(pszValue),
hUSKey, debugstr_w(pszValue), dwType, pvData, cbData, dwFlags); dwType, pvData, cbData, dwFlags);
if ((dwFlags & SHREGSET_FORCE_HKCU) && if (!hUSKey || IsBadWritePtr(hUSKey, sizeof(SHUSKEY)) ||
(dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) { !(dwFlags & (SHREGSET_FORCE_HKCU|SHREGSET_FORCE_HKLM)))
RegSetValueExW(dokey, pszValue, 0, dwType, pvData, cbData); return ERROR_INVALID_PARAMETER;
if (dwFlags & (SHREGSET_FORCE_HKCU|SHREGSET_HKCU))
{
if (!hKey->HKCUkey)
{
/* Create the key */
ret = RegCreateKeyW(hKey->HKCUstart, hKey->lpszPath, &hKey->HKCUkey);
TRACE("Creating HKCU key, ret = %ld\n", ret);
if (ret && (dwFlags & (SHREGSET_FORCE_HKCU)))
{
hKey->HKCUkey = 0;
return ret;
}
} }
if ((dwFlags & SHREGSET_FORCE_HKLM) && if (!ret)
(dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) { {
RegSetValueExW(dokey, pszValue, 0, dwType, pvData, cbData); if ((dwFlags & SHREGSET_FORCE_HKCU) ||
RegQueryValueExW(hKey->HKCUkey, pszValue, NULL, NULL, NULL, &dummy))
{
/* Doesn't exist or we are forcing: Write value */
ret = RegSetValueExW(hKey->HKCUkey, pszValue, 0, dwType, pvData, cbData);
TRACE("Writing HKCU value, ret = %ld\n", ret);
}
}
} }
if (dwFlags & (SHREGSET_FORCE_HKCU | SHREGSET_FORCE_HKLM)) if (dwFlags & (SHREGSET_FORCE_HKLM|SHREGSET_HKLM))
return ERROR_SUCCESS; {
if (!hKey->HKLMkey)
{
/* Create the key */
ret = RegCreateKeyW(hKey->HKLMstart, hKey->lpszPath, &hKey->HKLMkey);
TRACE("Creating HKLM key, ret = %ld\n", ret);
if (ret && (dwFlags & (SHREGSET_FORCE_HKLM)))
{
hKey->HKLMkey = 0;
return ret;
}
}
FIXME("SHREGSET_HKCU or SHREGSET_HKLM not supported\n"); if (!ret)
return ERROR_SUCCESS; {
if ((dwFlags & SHREGSET_FORCE_HKLM) ||
RegQueryValueExW(hKey->HKLMkey, pszValue, NULL, NULL, NULL, &dummy))
{
/* Doesn't exist or we are forcing: Write value */
ret = RegSetValueExW(hKey->HKLMkey, pszValue, 0, dwType, pvData, cbData);
TRACE("Writing HKLM value, ret = %ld\n", ret);
}
}
}
return ret;
} }
/************************************************************************* /*************************************************************************