📄 reg.c
字号:
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
*
* @implemented
*/
LONG STDCALL
RegSetKeyValueW(IN HKEY hKey,
IN LPCWSTR lpSubKey OPTIONAL,
IN LPCWSTR lpValueName OPTIONAL,
IN DWORD dwType,
IN LPCVOID lpData OPTIONAL,
IN DWORD cbData)
{
HANDLE KeyHandle, CurKey, SubKeyHandle = NULL;
NTSTATUS Status;
LONG Ret;
Status = MapDefaultKey(&KeyHandle,
hKey);
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError(Status);
}
if (lpSubKey != NULL)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING SubKeyName;
RtlInitUnicodeString(&SubKeyName,
(LPWSTR)lpSubKey);
InitializeObjectAttributes(&ObjectAttributes,
&SubKeyName,
OBJ_CASE_INSENSITIVE,
KeyHandle,
NULL);
Status = NtOpenKey(&SubKeyHandle,
KEY_SET_VALUE,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
Ret = RtlNtStatusToDosError(Status);
goto Cleanup;
}
CurKey = SubKeyHandle;
}
else
CurKey = KeyHandle;
Ret = RegSetValueExW(CurKey,
lpValueName,
0,
dwType,
lpData,
cbData);
if (SubKeyHandle != NULL)
{
NtClose(SubKeyHandle);
}
Cleanup:
ClosePredefKey(KeyHandle);
return Ret;
}
/************************************************************************
* RegSetKeyValueA
*
* @implemented
*/
LONG STDCALL
RegSetKeyValueA(IN HKEY hKey,
IN LPCSTR lpSubKey OPTIONAL,
IN LPCSTR lpValueName OPTIONAL,
IN DWORD dwType,
IN LPCVOID lpData OPTIONAL,
IN DWORD cbData)
{
HANDLE KeyHandle, CurKey, SubKeyHandle = NULL;
NTSTATUS Status;
LONG Ret;
Status = MapDefaultKey(&KeyHandle,
hKey);
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError(Status);
}
if (lpSubKey != NULL)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING SubKeyName;
if (!RtlCreateUnicodeStringFromAsciiz(&SubKeyName,
(LPSTR)lpSubKey))
{
Ret = ERROR_NOT_ENOUGH_MEMORY;
goto Cleanup;
}
InitializeObjectAttributes(&ObjectAttributes,
&SubKeyName,
OBJ_CASE_INSENSITIVE,
KeyHandle,
NULL);
Status = NtOpenKey(&SubKeyHandle,
KEY_SET_VALUE,
&ObjectAttributes);
RtlFreeUnicodeString(&SubKeyName);
if (!NT_SUCCESS(Status))
{
Ret = RtlNtStatusToDosError(Status);
goto Cleanup;
}
CurKey = SubKeyHandle;
}
else
CurKey = KeyHandle;
Ret = RegSetValueExA(CurKey,
lpValueName,
0,
dwType,
lpData,
cbData);
if (SubKeyHandle != NULL)
{
NtClose(SubKeyHandle);
}
Cleanup:
ClosePredefKey(KeyHandle);
return Ret;
}
/************************************************************************
* RegDeleteValueA
*
* @implemented
*/
LONG STDCALL
RegDeleteValueA (HKEY hKey,
LPCSTR lpValueName)
{
UNICODE_STRING ValueName;
HANDLE KeyHandle;
NTSTATUS Status;
Status = MapDefaultKey (&KeyHandle,
hKey);
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
}
RtlCreateUnicodeStringFromAsciiz (&ValueName,
(LPSTR)lpValueName);
Status = NtDeleteValueKey (KeyHandle,
&ValueName);
RtlFreeUnicodeString (&ValueName);
ClosePredefKey(KeyHandle);
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
}
return ERROR_SUCCESS;
}
/************************************************************************
* RegDeleteValueW
*
* @implemented
*/
LONG STDCALL
RegDeleteValueW (HKEY hKey,
LPCWSTR lpValueName)
{
UNICODE_STRING ValueName;
NTSTATUS Status;
HANDLE KeyHandle;
Status = MapDefaultKey (&KeyHandle,
hKey);
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
}
RtlInitUnicodeString (&ValueName,
(LPWSTR)lpValueName);
Status = NtDeleteValueKey (KeyHandle,
&ValueName);
ClosePredefKey(KeyHandle);
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
}
return ERROR_SUCCESS;
}
/************************************************************************
* RegEnumKeyA
*
* @implemented
*/
LONG STDCALL
RegEnumKeyA (HKEY hKey,
DWORD dwIndex,
LPSTR lpName,
DWORD cbName)
{
DWORD dwLength;
dwLength = cbName;
return RegEnumKeyExA (hKey,
dwIndex,
lpName,
&dwLength,
NULL,
NULL,
NULL,
NULL);
}
/************************************************************************
* RegEnumKeyW
*
* @implemented
*/
LONG STDCALL
RegEnumKeyW (HKEY hKey,
DWORD dwIndex,
LPWSTR lpName,
DWORD cbName)
{
DWORD dwLength;
dwLength = cbName;
return RegEnumKeyExW (hKey,
dwIndex,
lpName,
&dwLength,
NULL,
NULL,
NULL,
NULL);
}
/************************************************************************
* RegEnumKeyExA
*
* @implemented
*/
LONG STDCALL
RegEnumKeyExA (HKEY hKey,
DWORD dwIndex,
LPSTR lpName,
LPDWORD lpcbName,
LPDWORD lpReserved,
LPSTR lpClass,
LPDWORD lpcbClass,
PFILETIME lpftLastWriteTime)
{
union
{
KEY_NODE_INFORMATION Node;
KEY_BASIC_INFORMATION Basic;
} *KeyInfo;
UNICODE_STRING StringU;
ANSI_STRING StringA;
LONG ErrorCode = ERROR_SUCCESS;
DWORD NameLength;
DWORD ClassLength = 0;
DWORD BufferSize;
DWORD ResultSize;
HANDLE KeyHandle;
NTSTATUS Status;
TRACE("RegEnumKeyExA(hKey 0x%x, dwIndex %d, lpName 0x%x, *lpcbName %d, lpClass 0x%x, lpcbClass %d)\n",
hKey, dwIndex, lpName, *lpcbName, lpClass, lpcbClass ? *lpcbClass : 0);
if ((lpClass) && (!lpcbClass))
{
return ERROR_INVALID_PARAMETER;
}
Status = MapDefaultKey(&KeyHandle, hKey);
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
}
if (*lpcbName > 0)
{
NameLength = min (*lpcbName - 1 , REG_MAX_NAME_SIZE) * sizeof (WCHAR);
}
else
{
NameLength = 0;
}
if (lpClass)
{
if (*lpcbClass > 0)
{
ClassLength = min (*lpcbClass -1, REG_MAX_NAME_SIZE) * sizeof(WCHAR);
}
else
{
ClassLength = 0;
}
/* The class name should start at a dword boundary */
BufferSize = ((sizeof(KEY_NODE_INFORMATION) + NameLength + 3) & ~3) + ClassLength;
}
else
{
BufferSize = sizeof(KEY_BASIC_INFORMATION) + NameLength;
}
KeyInfo = RtlAllocateHeap (ProcessHeap, 0, BufferSize);
if (KeyInfo == NULL)
{
ErrorCode = ERROR_OUTOFMEMORY;
goto Cleanup;
}
Status = NtEnumerateKey (KeyHandle,
(ULONG)dwIndex,
lpClass == NULL ? KeyBasicInformation : KeyNodeInformation,
KeyInfo,
BufferSize,
&ResultSize);
TRACE("NtEnumerateKey() returned status 0x%X\n", Status);
if (!NT_SUCCESS(Status))
{
ErrorCode = RtlNtStatusToDosError (Status);
}
else
{
if (lpClass == NULL)
{
if (KeyInfo->Basic.NameLength > NameLength)
{
ErrorCode = ERROR_BUFFER_OVERFLOW;
}
els
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -