mirror of
https://github.com/reactos/reactos.git
synced 2024-08-20 18:35:32 +00:00
Port RegGetValue() from WINE
patch by Thomas Weidenmueller svn path=/trunk/; revision=22491
This commit is contained in:
parent
6c16a39783
commit
2747b47c79
|
@ -494,6 +494,8 @@ RegEnumValueA@32
|
||||||
RegEnumValueW@32
|
RegEnumValueW@32
|
||||||
RegFlushKey@4
|
RegFlushKey@4
|
||||||
RegGetKeySecurity@16
|
RegGetKeySecurity@16
|
||||||
|
RegGetValueA@28
|
||||||
|
RegGetValueW@28
|
||||||
RegLoadKeyA@12
|
RegLoadKeyA@12
|
||||||
RegLoadKeyW@12
|
RegLoadKeyW@12
|
||||||
RegLoadMUIStringA@24
|
RegLoadMUIStringA@24
|
||||||
|
|
|
@ -1680,6 +1680,258 @@ RegEnableReflectionKey(IN HKEY hBase)
|
||||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* RegpApplyRestrictions [internal]
|
||||||
|
*
|
||||||
|
* Helper function for RegGetValueA/W.
|
||||||
|
*/
|
||||||
|
static VOID
|
||||||
|
RegpApplyRestrictions( DWORD dwFlags, DWORD dwType, DWORD cbData,
|
||||||
|
PLONG ret )
|
||||||
|
{
|
||||||
|
/* Check if the type is restricted by the passed flags */
|
||||||
|
if (*ret == ERROR_SUCCESS || *ret == ERROR_MORE_DATA)
|
||||||
|
{
|
||||||
|
DWORD dwMask = 0;
|
||||||
|
|
||||||
|
switch (dwType)
|
||||||
|
{
|
||||||
|
case REG_NONE: dwMask = RRF_RT_REG_NONE; break;
|
||||||
|
case REG_SZ: dwMask = RRF_RT_REG_SZ; break;
|
||||||
|
case REG_EXPAND_SZ: dwMask = RRF_RT_REG_EXPAND_SZ; break;
|
||||||
|
case REG_MULTI_SZ: dwMask = RRF_RT_REG_MULTI_SZ; break;
|
||||||
|
case REG_BINARY: dwMask = RRF_RT_REG_BINARY; break;
|
||||||
|
case REG_DWORD: dwMask = RRF_RT_REG_DWORD; break;
|
||||||
|
case REG_QWORD: dwMask = RRF_RT_REG_QWORD; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dwFlags & dwMask)
|
||||||
|
{
|
||||||
|
/* Type is not restricted, check for size mismatch */
|
||||||
|
if (dwType == REG_BINARY)
|
||||||
|
{
|
||||||
|
DWORD cbExpect = 0;
|
||||||
|
|
||||||
|
if ((dwFlags & RRF_RT_DWORD) == RRF_RT_DWORD)
|
||||||
|
cbExpect = 4;
|
||||||
|
else if ((dwFlags & RRF_RT_DWORD) == RRF_RT_QWORD)
|
||||||
|
cbExpect = 8;
|
||||||
|
|
||||||
|
if (cbExpect && cbData != cbExpect)
|
||||||
|
*ret = ERROR_DATATYPE_MISMATCH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else *ret = ERROR_UNSUPPORTED_TYPE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* RegGetValueW [ADVAPI32.@]
|
||||||
|
*
|
||||||
|
* Retrieves the type and data for a value name associated with a key
|
||||||
|
* optionally expanding it's content and restricting it's type.
|
||||||
|
*
|
||||||
|
* PARAMS
|
||||||
|
* hKey [I] Handle to an open key.
|
||||||
|
* pszSubKey [I] Name of the subkey of hKey.
|
||||||
|
* pszValue [I] Name of value under hKey/szSubKey to query.
|
||||||
|
* dwFlags [I] Flags restricting the value type to retrieve.
|
||||||
|
* pdwType [O] Destination for the values type, may be NULL.
|
||||||
|
* pvData [O] Destination for the values content, may be NULL.
|
||||||
|
* pcbData [I/O] Size of pvData, updated with the size required to
|
||||||
|
* retrieve the whole content.
|
||||||
|
*
|
||||||
|
* RETURNS
|
||||||
|
* Success: ERROR_SUCCESS
|
||||||
|
* Failure: nonzero error code from Winerror.h
|
||||||
|
*
|
||||||
|
* NOTES
|
||||||
|
* - Unless RRF_NOEXPAND is specified REG_EXPAND_SZ is automatically expanded
|
||||||
|
* and REG_SZ is retrieved instead.
|
||||||
|
* - Restrictions are applied after expanding, using RRF_RT_REG_EXPAND_SZ
|
||||||
|
* without RRF_NOEXPAND is thus not allowed.
|
||||||
|
*/
|
||||||
|
LONG WINAPI
|
||||||
|
RegGetValueW( HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue,
|
||||||
|
DWORD dwFlags, LPDWORD pdwType, PVOID pvData,
|
||||||
|
LPDWORD pcbData )
|
||||||
|
{
|
||||||
|
DWORD dwType, cbData = pcbData ? *pcbData : 0;
|
||||||
|
PVOID pvBuf = NULL;
|
||||||
|
LONG ret;
|
||||||
|
|
||||||
|
TRACE("(%p,%s,%s,%ld,%p,%p,%p=%ld)\n",
|
||||||
|
hKey, debugstr_w(pszSubKey), debugstr_w(pszValue), dwFlags, pdwType,
|
||||||
|
pvData, pcbData, cbData);
|
||||||
|
|
||||||
|
if ((dwFlags & RRF_RT_REG_EXPAND_SZ) && !(dwFlags & RRF_NOEXPAND))
|
||||||
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if (pszSubKey && pszSubKey[0])
|
||||||
|
{
|
||||||
|
ret = RegOpenKeyExW(hKey, pszSubKey, 0, KEY_QUERY_VALUE, &hKey);
|
||||||
|
if (ret != ERROR_SUCCESS) return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = RegQueryValueExW(hKey, pszValue, NULL, &dwType, pvData, &cbData);
|
||||||
|
|
||||||
|
/* If we are going to expand we need to read in the whole the value even
|
||||||
|
* if the passed buffer was too small as the expanded string might be
|
||||||
|
* smaller than the unexpanded one and could fit into cbData bytes. */
|
||||||
|
if ((ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA) &&
|
||||||
|
(dwType == REG_EXPAND_SZ && !(dwFlags & RRF_NOEXPAND)))
|
||||||
|
{
|
||||||
|
do {
|
||||||
|
if (pvBuf) HeapFree(GetProcessHeap(), 0, pvBuf);
|
||||||
|
|
||||||
|
pvBuf = HeapAlloc(GetProcessHeap(), 0, cbData);
|
||||||
|
if (!pvBuf)
|
||||||
|
{
|
||||||
|
ret = ERROR_NOT_ENOUGH_MEMORY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == ERROR_MORE_DATA)
|
||||||
|
ret = RegQueryValueExW(hKey, pszValue, NULL,
|
||||||
|
&dwType, pvBuf, &cbData);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Even if cbData was large enough we have to copy the
|
||||||
|
* string since ExpandEnvironmentStrings can't handle
|
||||||
|
* overlapping buffers. */
|
||||||
|
CopyMemory(pvBuf, pvData, cbData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Both the type or the value itself could have been modified in
|
||||||
|
* between so we have to keep retrying until the buffer is large
|
||||||
|
* enough or we no longer have to expand the value. */
|
||||||
|
} while (dwType == REG_EXPAND_SZ && ret == ERROR_MORE_DATA);
|
||||||
|
|
||||||
|
if (ret == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
if (dwType == REG_EXPAND_SZ)
|
||||||
|
{
|
||||||
|
cbData = ExpandEnvironmentStringsW(pvBuf, pvData,
|
||||||
|
pcbData ? *pcbData : 0);
|
||||||
|
dwType = REG_SZ;
|
||||||
|
if(pcbData && cbData > *pcbData)
|
||||||
|
ret = ERROR_MORE_DATA;
|
||||||
|
}
|
||||||
|
else if (pcbData)
|
||||||
|
CopyMemory(pvData, pvBuf, *pcbData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pvBuf) HeapFree(GetProcessHeap(), 0, pvBuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pszSubKey && pszSubKey[0])
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
|
||||||
|
RegpApplyRestrictions(dwFlags, dwType, cbData, &ret);
|
||||||
|
|
||||||
|
if (pcbData && ret != ERROR_SUCCESS && (dwFlags & RRF_ZEROONFAILURE))
|
||||||
|
ZeroMemory(pvData, *pcbData);
|
||||||
|
|
||||||
|
if (pdwType) *pdwType = dwType;
|
||||||
|
if (pcbData) *pcbData = cbData;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* RegGetValueA [ADVAPI32.@]
|
||||||
|
*
|
||||||
|
* See RegGetValueW.
|
||||||
|
*/
|
||||||
|
LONG WINAPI
|
||||||
|
RegGetValueA( HKEY hKey, LPCSTR pszSubKey, LPCSTR pszValue,
|
||||||
|
DWORD dwFlags, LPDWORD pdwType, PVOID pvData,
|
||||||
|
LPDWORD pcbData )
|
||||||
|
{
|
||||||
|
DWORD dwType, cbData = pcbData ? *pcbData : 0;
|
||||||
|
PVOID pvBuf = NULL;
|
||||||
|
LONG ret;
|
||||||
|
|
||||||
|
TRACE("(%p,%s,%s,%ld,%p,%p,%p=%ld)\n",
|
||||||
|
hKey, pszSubKey, pszValue, dwFlags, pdwType, pvData, pcbData,
|
||||||
|
cbData);
|
||||||
|
|
||||||
|
if ((dwFlags & RRF_RT_REG_EXPAND_SZ) && !(dwFlags & RRF_NOEXPAND))
|
||||||
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if (pszSubKey && pszSubKey[0])
|
||||||
|
{
|
||||||
|
ret = RegOpenKeyExA(hKey, pszSubKey, 0, KEY_QUERY_VALUE, &hKey);
|
||||||
|
if (ret != ERROR_SUCCESS) return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = RegQueryValueExA(hKey, pszValue, NULL, &dwType, pvData, &cbData);
|
||||||
|
|
||||||
|
/* If we are going to expand we need to read in the whole the value even
|
||||||
|
* if the passed buffer was too small as the expanded string might be
|
||||||
|
* smaller than the unexpanded one and could fit into cbData bytes. */
|
||||||
|
if ((ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA) &&
|
||||||
|
(dwType == REG_EXPAND_SZ && !(dwFlags & RRF_NOEXPAND)))
|
||||||
|
{
|
||||||
|
do {
|
||||||
|
if (pvBuf) HeapFree(GetProcessHeap(), 0, pvBuf);
|
||||||
|
|
||||||
|
pvBuf = HeapAlloc(GetProcessHeap(), 0, cbData);
|
||||||
|
if (!pvBuf)
|
||||||
|
{
|
||||||
|
ret = ERROR_NOT_ENOUGH_MEMORY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == ERROR_MORE_DATA)
|
||||||
|
ret = RegQueryValueExA(hKey, pszValue, NULL,
|
||||||
|
&dwType, pvBuf, &cbData);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Even if cbData was large enough we have to copy the
|
||||||
|
* string since ExpandEnvironmentStrings can't handle
|
||||||
|
* overlapping buffers. */
|
||||||
|
CopyMemory(pvBuf, pvData, cbData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Both the type or the value itself could have been modified in
|
||||||
|
* between so we have to keep retrying until the buffer is large
|
||||||
|
* enough or we no longer have to expand the value. */
|
||||||
|
} while (dwType == REG_EXPAND_SZ && ret == ERROR_MORE_DATA);
|
||||||
|
|
||||||
|
if (ret == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
if (dwType == REG_EXPAND_SZ)
|
||||||
|
{
|
||||||
|
cbData = ExpandEnvironmentStringsA(pvBuf, pvData,
|
||||||
|
pcbData ? *pcbData : 0);
|
||||||
|
dwType = REG_SZ;
|
||||||
|
if(pcbData && cbData > *pcbData)
|
||||||
|
ret = ERROR_MORE_DATA;
|
||||||
|
}
|
||||||
|
else if (pcbData)
|
||||||
|
CopyMemory(pvData, pvBuf, *pcbData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pvBuf) HeapFree(GetProcessHeap(), 0, pvBuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pszSubKey && pszSubKey[0])
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
|
||||||
|
RegpApplyRestrictions(dwFlags, dwType, cbData, &ret);
|
||||||
|
|
||||||
|
if (pcbData && ret != ERROR_SUCCESS && (dwFlags & RRF_ZEROONFAILURE))
|
||||||
|
ZeroMemory(pvData, *pcbData);
|
||||||
|
|
||||||
|
if (pdwType) *pdwType = dwType;
|
||||||
|
if (pcbData) *pcbData = cbData;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* RegSetKeyValueW
|
* RegSetKeyValueW
|
||||||
|
|
Loading…
Reference in a new issue