diff --git a/reactos/lib/advapi32/reg/reg.c b/reactos/lib/advapi32/reg/reg.c index 7ff80133da7..71038c5e0d9 100644 --- a/reactos/lib/advapi32/reg/reg.c +++ b/reactos/lib/advapi32/reg/reg.c @@ -8,6 +8,7 @@ * UPDATE HISTORY: * Created 01/11/98 * 19990309 EA Stubs + * 20050502 Fireball imported some stuff from WINE */ /* INCLUDES *****************************************************************/ @@ -22,6 +23,9 @@ #define REG_MAX_NAME_SIZE 256 #define REG_MAX_DATA_SIZE 2048 +/* FIXME: should go into msvcrt.h header? */ +#define offsetof(s,m) (size_t)&(((s*)NULL)->m) + /* GLOBALS ******************************************************************/ static RTL_CRITICAL_SECTION HandleTableCS; @@ -40,6 +44,11 @@ static NTSTATUS OpenCurrentConfigKey(PHANDLE KeyHandle); /* FUNCTIONS ****************************************************************/ +/* check if value type needs string conversion (Ansi<->Unicode) */ +inline static int is_string( DWORD type ) +{ + return (type == REG_SZ) || (type == REG_EXPAND_SZ) || (type == REG_MULTI_SZ); +} /************************************************************************ * RegInitDefaultHandles @@ -1161,417 +1170,226 @@ RegEnumKeyExW (HKEY hKey, return ErrorCode; } - /************************************************************************ * RegEnumValueA * * @implemented */ LONG STDCALL -RegEnumValueA (HKEY hKey, - DWORD dwIndex, - LPSTR lpValueName, - LPDWORD lpcbValueName, // lpValueName buffer len - LPDWORD lpReserved, - LPDWORD lpType, - LPBYTE lpData, - LPDWORD lpcbData) // lpData buffer len +RegEnumValueA( HKEY hKey, DWORD index, LPSTR value, LPDWORD val_count, + LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count ) { - union - { - KEY_VALUE_FULL_INFORMATION Full; - KEY_VALUE_BASIC_INFORMATION Basic; - } *ValueInfo; - - ULONG NameLength; - ULONG BufferSize; - ULONG DataLength = 0; - ULONG ResultSize; HANDLE KeyHandle; - LONG ErrorCode; - NTSTATUS Status; - UNICODE_STRING StringU; - ANSI_STRING StringA; - BOOL IsStringType; + NTSTATUS status; + DWORD total_size; + char buffer[256], *buf_ptr = buffer; + KEY_VALUE_FULL_INFORMATION *info = (KEY_VALUE_FULL_INFORMATION *)buffer; + static const int info_size = offsetof( KEY_VALUE_FULL_INFORMATION, Name ); - ErrorCode = ERROR_SUCCESS; + //TRACE("(%p,%ld,%p,%p,%p,%p,%p,%p)\n", + // hkey, index, value, val_count, reserved, type, data, count ); - Status = MapDefaultKey (&KeyHandle, hKey); - if (!NT_SUCCESS(Status)) + /* NT only checks count, not val_count */ + if ((data && !count) || reserved) return ERROR_INVALID_PARAMETER; + status = MapDefaultKey (&KeyHandle, hKey); + if (!NT_SUCCESS(status)) { - ErrorCode = RtlNtStatusToDosError (Status); + LONG ErrorCode; + ErrorCode = RtlNtStatusToDosError (status); SetLastError (ErrorCode); return ErrorCode; } - if (*lpcbValueName > 0) - NameLength = min (*lpcbValueName - 1, REG_MAX_NAME_SIZE) * sizeof(WCHAR); - else - NameLength = 0; + total_size = info_size + (MAX_PATH + 1) * sizeof(WCHAR); + if (data) total_size += *count; + total_size = min( sizeof(buffer), total_size ); - if (lpData) - { - DataLength = min (*lpcbData * sizeof(WCHAR), REG_MAX_DATA_SIZE); - BufferSize = ((sizeof(KEY_VALUE_FULL_INFORMATION) + NameLength + 3) & ~3) + DataLength; - } - else - { - BufferSize = sizeof(KEY_VALUE_BASIC_INFORMATION) + NameLength; - } + status = NtEnumerateValueKey( KeyHandle, index, KeyValueFullInformation, + buffer, total_size, &total_size ); + if (status && status != STATUS_BUFFER_OVERFLOW) goto done; - ValueInfo = RtlAllocateHeap (ProcessHeap, 0, BufferSize); - if (ValueInfo == NULL) - { - SetLastError(ERROR_OUTOFMEMORY); - return ERROR_OUTOFMEMORY; - } + /* we need to fetch the contents for a string type even if not requested, + * because we need to compute the length of the ASCII string. */ + if (value || data || is_string(info->Type)) + { + /* retry with a dynamically allocated buffer */ + while (status == STATUS_BUFFER_OVERFLOW) + { + if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr ); + if (!(buf_ptr = HeapAlloc( GetProcessHeap(), 0, total_size ))) + return ERROR_NOT_ENOUGH_MEMORY; + info = (KEY_VALUE_FULL_INFORMATION *)buf_ptr; + status = NtEnumerateValueKey( KeyHandle, index, KeyValueFullInformation, + buf_ptr, total_size, &total_size ); + } - Status = NtEnumerateValueKey (KeyHandle, - (ULONG)dwIndex, - lpData ? KeyValueFullInformation : KeyValueBasicInformation, - ValueInfo, - BufferSize, - &ResultSize); + if (status) goto done; - DPRINT("NtEnumerateValueKey() returned status 0x%X\n", Status); - if (!NT_SUCCESS(Status)) - { - ErrorCode = RtlNtStatusToDosError (Status); + if (is_string(info->Type)) + { + DWORD len; + RtlUnicodeToMultiByteSize( &len, (WCHAR *)(buf_ptr + info->DataOffset), + total_size - info->DataOffset ); + if (data && len) + { + if (len > *count) status = STATUS_BUFFER_OVERFLOW; + else + { + RtlUnicodeToMultiByteN( data, len, NULL, (WCHAR *)(buf_ptr + info->DataOffset), + total_size - info->DataOffset ); + /* if the type is REG_SZ and data is not 0-terminated + * and there is enough space in the buffer NT appends a \0 */ + if (len < *count && data[len-1]) data[len] = 0; + } + } + info->DataLength = len; + } + else if (data) + { + if (total_size - info->DataOffset > *count) status = STATUS_BUFFER_OVERFLOW; + else memcpy( data, buf_ptr + info->DataOffset, total_size - info->DataOffset ); + } - // handle case when BufferSize was too small - // we must let caller know the minimum accepted size - // and value type - if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL) - { - ErrorCode = ERROR_MORE_DATA; + if (value && !status) + { + DWORD len; - // query now with the sufficient buffer size - RtlFreeHeap (ProcessHeap, 0, ValueInfo); - BufferSize = ResultSize; - ValueInfo = RtlAllocateHeap (ProcessHeap, 0, BufferSize); // will be freed at the bottom, as usual - if (ValueInfo == NULL) - { - SetLastError(ERROR_OUTOFMEMORY); - return ERROR_OUTOFMEMORY; - } + RtlUnicodeToMultiByteSize( &len, info->Name, info->NameLength ); + if (len >= *val_count) + { + status = STATUS_BUFFER_OVERFLOW; + if (*val_count) + { + len = *val_count - 1; + RtlUnicodeToMultiByteN( value, len, NULL, info->Name, info->NameLength ); + value[len] = 0; + } + } + else + { + RtlUnicodeToMultiByteN( value, len, NULL, info->Name, info->NameLength ); + value[len] = 0; + *val_count = len; + } + } + } + else status = STATUS_SUCCESS; - Status = NtEnumerateValueKey (KeyHandle, - (ULONG)dwIndex, - lpData ? KeyValueFullInformation : KeyValueBasicInformation, - ValueInfo, - BufferSize, - &ResultSize); - if (!NT_SUCCESS(Status)) - { - // ok, some other error - ErrorCode = RtlNtStatusToDosError (Status); - } - else - { - // we have information now, pass it to the caller - // but don't touch valueName length here - IsStringType = (ValueInfo->Full.Type == REG_SZ) || - (ValueInfo->Full.Type == REG_MULTI_SZ) || - (ValueInfo->Full.Type == REG_EXPAND_SZ); //FIXME: Include REG_LINK ? + if (type) *type = info->Type; + if (count) *count = info->DataLength; - if (lpData) - { - if (lpcbData) - { - if (IsStringType) - *lpcbData = ValueInfo->Full.DataLength / sizeof(WCHAR); - else - *lpcbData = ValueInfo->Full.DataLength; - } - } - - // pass type also - if (lpType) - *lpType = lpData ? ValueInfo->Full.Type : ValueInfo->Basic.Type; - } - } - } - else - { - IsStringType = (ValueInfo->Full.Type == REG_SZ) || - (ValueInfo->Full.Type == REG_MULTI_SZ) || - (ValueInfo->Full.Type == REG_EXPAND_SZ); - if (lpData) - { - if (ValueInfo->Full.NameLength > NameLength || - (!IsStringType && ValueInfo->Full.DataLength > *lpcbData) || - ValueInfo->Full.DataLength > DataLength) - { - // overflow data - ErrorCode = ERROR_MORE_DATA; - - // return correct information for data length and type - if (lpcbData) - { - if (IsStringType) - *lpcbData = ValueInfo->Full.DataLength / sizeof(WCHAR); - else - *lpcbData = ValueInfo->Full.DataLength; - } - - if (lpType) - *lpType = ValueInfo->Full.Type; - } - else - { - if (IsStringType) - { - StringU.Buffer = (PWCHAR)((ULONG_PTR)ValueInfo + ValueInfo->Full.DataOffset); - StringU.Length = ValueInfo->Full.DataLength; - StringU.MaximumLength = DataLength; - StringA.Buffer = (PCHAR)lpData; - StringA.Length = 0; - StringA.MaximumLength = *lpcbData; - RtlUnicodeStringToAnsiString (&StringA, &StringU, FALSE); - *lpcbData = StringA.Length; - } - else - { - RtlCopyMemory (lpData, - (PVOID)((ULONG_PTR)ValueInfo + ValueInfo->Full.DataOffset), - ValueInfo->Full.DataLength); - *lpcbData = ValueInfo->Full.DataLength; - } - - StringU.Buffer = ValueInfo->Full.Name; - StringU.Length = ValueInfo->Full.NameLength; - StringU.MaximumLength = NameLength; - } - } - else - { - if (ValueInfo->Basic.NameLength > NameLength) - { - // overflow name - ErrorCode = ERROR_MORE_DATA; - - if (IsStringType) - *lpcbData = ValueInfo->Full.DataLength / sizeof(WCHAR); - else - *lpcbData = ValueInfo->Full.DataLength; - - if (lpType) - *lpType = ValueInfo->Basic.Type; - } - else - { - StringU.Buffer = ValueInfo->Basic.Name; - StringU.Length = ValueInfo->Basic.NameLength; - StringU.MaximumLength = NameLength; - } - } - - if (ErrorCode == ERROR_SUCCESS) - { - StringA.Buffer = (PCHAR)lpValueName; - StringA.Length = 0; - StringA.MaximumLength = *lpcbValueName; - RtlUnicodeStringToAnsiString (&StringA, &StringU, FALSE); - StringA.Buffer[StringA.Length] = 0; - *lpcbValueName = StringA.Length; - if (lpType) - { - *lpType = lpData ? ValueInfo->Full.Type : ValueInfo->Basic.Type; - } - } - } - - RtlFreeHeap (ProcessHeap, 0, ValueInfo); - - if (ErrorCode != ERROR_SUCCESS) - SetLastError(ErrorCode); - - return ErrorCode; + done: + if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr ); + return RtlNtStatusToDosError(status); } - -/************************************************************************ - * RegEnumValueW - * +/****************************************************************************** + * RegEnumValueW [ADVAPI32.@] * @implemented + * + * PARAMS + * hkey [I] Handle to key to query + * index [I] Index of value to query + * value [O] Value string + * val_count [I/O] Size of value buffer (in wchars) + * reserved [I] Reserved + * type [O] Type code + * data [O] Value data + * count [I/O] Size of data buffer (in bytes) + * + * RETURNS + * Success: ERROR_SUCCESS + * Failure: nonzero error code from Winerror.h */ LONG STDCALL -RegEnumValueW (HKEY hKey, - DWORD dwIndex, - LPWSTR lpValueName, - LPDWORD lpcbValueName, - LPDWORD lpReserved, - LPDWORD lpType, - LPBYTE lpData, - LPDWORD lpcbData) +RegEnumValueW( HKEY hKey, DWORD index, LPWSTR value, PDWORD val_count, + PDWORD reserved, PDWORD type, LPBYTE data, PDWORD count ) { - union - { - KEY_VALUE_FULL_INFORMATION Full; - KEY_VALUE_BASIC_INFORMATION Basic; - } *ValueInfo; - - ULONG NameLength; - ULONG BufferSize; - ULONG DataLength = 0; - ULONG ResultSize; HANDLE KeyHandle; - LONG ErrorCode; - NTSTATUS Status; + NTSTATUS status; + DWORD total_size; + char buffer[256], *buf_ptr = buffer; + KEY_VALUE_FULL_INFORMATION *info = (KEY_VALUE_FULL_INFORMATION *)buffer; + static const int info_size = offsetof( KEY_VALUE_FULL_INFORMATION, Name ); - ErrorCode = ERROR_SUCCESS; + //TRACE("(%p,%ld,%p,%p,%p,%p,%p,%p)\n", + // hkey, index, value, val_count, reserved, type, data, count ); - Status = MapDefaultKey (&KeyHandle, hKey); - if (!NT_SUCCESS(Status)) + /* NT only checks count, not val_count */ + if ((data && !count) || reserved) return ERROR_INVALID_PARAMETER; + + status = MapDefaultKey (&KeyHandle, hKey); + if (!NT_SUCCESS(status)) { - ErrorCode = RtlNtStatusToDosError (Status); + LONG ErrorCode; + ErrorCode = RtlNtStatusToDosError (status); SetLastError (ErrorCode); return ErrorCode; } - if (*lpcbValueName > 0) - NameLength = min (*lpcbValueName - 1, REG_MAX_NAME_SIZE) * sizeof(WCHAR); - else - NameLength = 0; + total_size = info_size + (MAX_PATH + 1) * sizeof(WCHAR); + if (data) total_size += *count; + total_size = min( sizeof(buffer), total_size ); - if (lpData) - { - DataLength = min(*lpcbData, REG_MAX_DATA_SIZE); - BufferSize = ((sizeof(KEY_VALUE_FULL_INFORMATION) + NameLength + 3) & ~3) + DataLength; - } - else - { - BufferSize = sizeof(KEY_VALUE_BASIC_INFORMATION) + NameLength; - } - ValueInfo = RtlAllocateHeap (ProcessHeap, 0, BufferSize); - if (ValueInfo == NULL) - { - SetLastError (ERROR_OUTOFMEMORY); - return ERROR_OUTOFMEMORY; - } - Status = NtEnumerateValueKey (KeyHandle, - (ULONG)dwIndex, - lpData ? KeyValueFullInformation : KeyValueBasicInformation, - ValueInfo, - BufferSize, - &ResultSize); + status = NtEnumerateValueKey( KeyHandle, index, KeyValueFullInformation, + buffer, total_size, &total_size ); + if (status && status != STATUS_BUFFER_OVERFLOW) goto done; - DPRINT("NtEnumerateValueKey() returned status 0x%X\n", Status); - if (!NT_SUCCESS(Status)) - { - ErrorCode = RtlNtStatusToDosError (Status); + if (value || data) + { + /* retry with a dynamically allocated buffer */ + while (status == STATUS_BUFFER_OVERFLOW) + { + if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr ); + if (!(buf_ptr = HeapAlloc( GetProcessHeap(), 0, total_size ))) + return ERROR_NOT_ENOUGH_MEMORY; + info = (KEY_VALUE_FULL_INFORMATION *)buf_ptr; + status = NtEnumerateValueKey( KeyHandle, index, KeyValueFullInformation, + buf_ptr, total_size, &total_size ); + } - // handle case when BufferSize was too small - // we must let caller know the minimum accepted size - // and value type - if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL) - { - ErrorCode = ERROR_MORE_DATA; + if (status) goto done; - // query now with the sufficient buffer size - RtlFreeHeap (ProcessHeap, 0, ValueInfo); - BufferSize = ResultSize; - ValueInfo = RtlAllocateHeap (ProcessHeap, 0, BufferSize); // will be freed at the bottom, as usual - if (ValueInfo == NULL) - { - SetLastError(ERROR_OUTOFMEMORY); - return ERROR_OUTOFMEMORY; - } + if (value) + { + if (info->NameLength/sizeof(WCHAR) >= *val_count) + { + status = STATUS_BUFFER_OVERFLOW; + goto overflow; + } + memcpy( value, info->Name, info->NameLength ); + *val_count = info->NameLength / sizeof(WCHAR); + value[*val_count] = 0; + } - Status = NtEnumerateValueKey (KeyHandle, - (ULONG)dwIndex, - lpData ? KeyValueFullInformation : KeyValueBasicInformation, - ValueInfo, - BufferSize, - &ResultSize); - if (!NT_SUCCESS(Status)) - { - // ok, some other error - ErrorCode = RtlNtStatusToDosError (Status); - } - else - { - // we have information now, pass it to the caller - // but don't touch valueName length here - if (lpData && lpcbData) - *lpcbData = ValueInfo->Full.DataLength; + if (data) + { + if (total_size - info->DataOffset > *count) + { + status = STATUS_BUFFER_OVERFLOW; + goto overflow; + } + memcpy( data, buf_ptr + info->DataOffset, total_size - info->DataOffset ); + if (total_size - info->DataOffset <= *count-sizeof(WCHAR) && is_string(info->Type)) + { + /* if the type is REG_SZ and data is not 0-terminated + * and there is enough space in the buffer NT appends a \0 */ + WCHAR *ptr = (WCHAR *)(data + total_size - info->DataOffset); + if (ptr > (WCHAR *)data && ptr[-1]) *ptr = 0; + } + } + } + else status = STATUS_SUCCESS; - // pass type also - if (lpType) - *lpType = lpData ? ValueInfo->Full.Type : ValueInfo->Basic.Type; - } - } - } - else - { - if (lpData) - { - if (ValueInfo->Full.DataLength > DataLength || - ValueInfo->Full.NameLength > NameLength) - { - // overflow data - ErrorCode = ERROR_MORE_DATA; + overflow: + if (type) *type = info->Type; + if (count) *count = info->DataLength; - // return correct information for data length and type - if (lpcbData) - *lpcbData = ValueInfo->Full.DataLength; - - if (lpType) - *lpType = ValueInfo->Full.Type; - } - else - { - RtlCopyMemory (lpValueName, ValueInfo->Full.Name, ValueInfo->Full.NameLength); - *lpcbValueName = (DWORD)(ValueInfo->Full.NameLength / sizeof(WCHAR)); - lpValueName[*lpcbValueName] = 0; - RtlCopyMemory (lpData, - (PVOID)((ULONG_PTR)ValueInfo + ValueInfo->Full.DataOffset), - ValueInfo->Full.DataLength); - *lpcbData = (DWORD)ValueInfo->Full.DataLength; - } - } - else - { - if (ValueInfo->Basic.NameLength > NameLength) - { - // overflow name - ErrorCode = ERROR_MORE_DATA; - - if (lpcbData) - *lpcbData = ValueInfo->Full.DataLength; - - if (lpType) - *lpType = ValueInfo->Basic.Type; - } - else - { - RtlCopyMemory (lpValueName, ValueInfo->Basic.Name, ValueInfo->Basic.NameLength); - *lpcbValueName = (DWORD)(ValueInfo->Basic.NameLength / sizeof(WCHAR)); - lpValueName[*lpcbValueName] = 0; - } - - if (NULL != lpcbData) - { - *lpcbData = (DWORD)ValueInfo->Full.DataLength; - DPRINT1("BUG: Using ValueInfo as FULL when it is really BASIC\n"); - } - } - - if (ErrorCode == ERROR_SUCCESS && lpType != NULL) - { - *lpType = lpData ? ValueInfo->Full.Type : ValueInfo->Basic.Type; - } - } - - RtlFreeHeap (ProcessHeap, 0, ValueInfo); - - if (ErrorCode != ERROR_SUCCESS) - SetLastError (ErrorCode); - - return ErrorCode; + done: + if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr ); + return RtlNtStatusToDosError(status); } - /************************************************************************ * RegFlushKey * @@ -1818,6 +1636,8 @@ RegNotifyChangeKeyValue (HKEY hKey, /************************************************************************ * RegOpenKeyA * + * 20050503 Fireball - imported from WINE + * * @implemented */ LONG STDCALL @@ -1825,45 +1645,15 @@ RegOpenKeyA (HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult) { - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING SubKeyString; - HANDLE KeyHandle; - LONG ErrorCode; - NTSTATUS Status; + DPRINT("RegOpenKeyA hKey 0x%x lpSubKey %s phkResult %p\n", hKey, lpSubKey, phkResult); - DPRINT("RegOpenKeyA hKey 0x%x lpSubKey %s phkResult %p\n", hKey, lpSubKey, phkResult); + if (!lpSubKey || !*lpSubKey) + { + *phkResult = hKey; + return ERROR_SUCCESS; + } - // Check input params - if (phkResult == NULL) return ERROR_INVALID_PARAMETER; - - Status = MapDefaultKey (&KeyHandle, - hKey); - if (!NT_SUCCESS(Status)) - { - ErrorCode = RtlNtStatusToDosError (Status); - SetLastError (ErrorCode); - return Status; - } - - RtlCreateUnicodeStringFromAsciiz (&SubKeyString, - (LPSTR)lpSubKey); - InitializeObjectAttributes (&ObjectAttributes, - &SubKeyString, - OBJ_CASE_INSENSITIVE, - KeyHandle, - NULL); - Status = NtOpenKey ((PHANDLE)phkResult, - MAXIMUM_ALLOWED, - &ObjectAttributes); - RtlFreeUnicodeString (&SubKeyString); - if (!NT_SUCCESS(Status)) - { - ErrorCode = RtlNtStatusToDosError (Status); - SetLastError (ErrorCode); - return ErrorCode; - } - - return ERROR_SUCCESS; + return RegOpenKeyExA( hKey, lpSubKey, 0, KEY_ALL_ACCESS, phkResult); } @@ -1872,6 +1662,7 @@ RegOpenKeyA (HKEY hKey, * * 19981101 Ariadne * 19990525 EA + * 20050503 Fireball - imported from WINE * * @implemented */ @@ -1880,44 +1671,14 @@ RegOpenKeyW (HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult) { - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING SubKeyString; - HANDLE KeyHandle; - LONG ErrorCode; - NTSTATUS Status; + DPRINT("RegOpenKeyW hKey 0x%x lpSubKey %S phkResult %p\n", hKey, lpSubKey, phkResult); - DPRINT("RegOpenKeyW hKey 0x%x lpSubKey %S phkResult %p\n", hKey, lpSubKey, phkResult); - - // Check input params - if (phkResult == NULL) return ERROR_INVALID_PARAMETER; - - Status = MapDefaultKey (&KeyHandle, - hKey); - if (!NT_SUCCESS(Status)) - { - ErrorCode = RtlNtStatusToDosError (Status); - SetLastError (ErrorCode); - return Status; - } - - RtlInitUnicodeString (&SubKeyString, - (LPWSTR)lpSubKey); - InitializeObjectAttributes (&ObjectAttributes, - &SubKeyString, - OBJ_CASE_INSENSITIVE, - KeyHandle, - NULL); - Status = NtOpenKey ((PHANDLE)phkResult, - MAXIMUM_ALLOWED, - &ObjectAttributes); - if (!NT_SUCCESS(Status)) - { - ErrorCode = RtlNtStatusToDosError (Status); - SetLastError(ErrorCode); - return ErrorCode; - } - - return ERROR_SUCCESS; + if (!lpSubKey || !*lpSubKey) + { + *phkResult = hKey; + return ERROR_SUCCESS; + } + return RegOpenKeyExW(hKey, lpSubKey, 0, KEY_ALL_ACCESS, phkResult); } @@ -1933,42 +1694,40 @@ RegOpenKeyExA (HKEY hKey, REGSAM samDesired, PHKEY phkResult) { - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING SubKeyString; - HANDLE KeyHandle; - LONG ErrorCode; - NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING SubKeyString; + HANDLE KeyHandle; + LONG ErrorCode; + NTSTATUS Status; - DPRINT("RegOpenKeyExA hKey 0x%x lpSubKey %s ulOptions 0x%x samDesired 0x%x phkResult %p\n", - hKey, lpSubKey, ulOptions, samDesired, phkResult); - Status = MapDefaultKey (&KeyHandle, - hKey); - if (!NT_SUCCESS(Status)) - { - ErrorCode = RtlNtStatusToDosError (Status); - SetLastError (ErrorCode); - return ErrorCode; - } + DPRINT("RegOpenKeyExA hKey 0x%x lpSubKey %s ulOptions 0x%x samDesired 0x%x phkResult %p\n", + hKey, lpSubKey, ulOptions, samDesired, phkResult); - RtlCreateUnicodeStringFromAsciiz (&SubKeyString, - (LPSTR)lpSubKey); - InitializeObjectAttributes (&ObjectAttributes, - &SubKeyString, - OBJ_CASE_INSENSITIVE, - KeyHandle, - NULL); - Status = NtOpenKey ((PHANDLE)phkResult, - samDesired, - &ObjectAttributes); - RtlFreeUnicodeString (&SubKeyString); - if (!NT_SUCCESS(Status)) - { - ErrorCode = RtlNtStatusToDosError (Status); - SetLastError (ErrorCode); - return ErrorCode; - } + Status = MapDefaultKey (&KeyHandle, hKey); + if (!NT_SUCCESS(Status)) + { + ErrorCode = RtlNtStatusToDosError (Status); + SetLastError (ErrorCode); + return ErrorCode; + } - return ERROR_SUCCESS; + RtlCreateUnicodeStringFromAsciiz (&SubKeyString, (LPSTR)lpSubKey); + InitializeObjectAttributes (&ObjectAttributes, + &SubKeyString, + OBJ_CASE_INSENSITIVE, + KeyHandle, + NULL); + + Status = NtOpenKey ((PHANDLE)phkResult, samDesired, &ObjectAttributes); + RtlFreeUnicodeString (&SubKeyString); + if (!NT_SUCCESS(Status)) + { + ErrorCode = RtlNtStatusToDosError (Status); + SetLastError (ErrorCode); + return ErrorCode; + } + + return ERROR_SUCCESS; } @@ -1984,49 +1743,44 @@ RegOpenKeyExW (HKEY hKey, REGSAM samDesired, PHKEY phkResult) { - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING SubKeyString; - HANDLE KeyHandle; - LONG ErrorCode; - NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING SubKeyString; + HANDLE KeyHandle; + LONG ErrorCode; + NTSTATUS Status; - DPRINT("RegOpenKeyExW hKey 0x%x lpSubKey %S ulOptions 0x%x samDesired 0x%x phkResult %p\n", - hKey, lpSubKey, ulOptions, samDesired, phkResult); - Status = MapDefaultKey (&KeyHandle, - hKey); - if (!NT_SUCCESS(Status)) - { - ErrorCode = RtlNtStatusToDosError (Status); - SetLastError (ErrorCode); - return ErrorCode; - } + DPRINT("RegOpenKeyExW hKey 0x%x lpSubKey %S ulOptions 0x%x samDesired 0x%x phkResult %p\n", + hKey, lpSubKey, ulOptions, samDesired, phkResult); + + Status = MapDefaultKey (&KeyHandle, hKey); + if (!NT_SUCCESS(Status)) + { + ErrorCode = RtlNtStatusToDosError (Status); + SetLastError (ErrorCode); + return ErrorCode; + } - if (lpSubKey != NULL) - { - RtlInitUnicodeString (&SubKeyString, - (LPWSTR)lpSubKey); - } - else - { - RtlInitUnicodeString (&SubKeyString, - (LPWSTR)L""); - } - InitializeObjectAttributes (&ObjectAttributes, - &SubKeyString, - OBJ_CASE_INSENSITIVE, - KeyHandle, - NULL); - Status = NtOpenKey ((PHANDLE)phkResult, - samDesired, - &ObjectAttributes); - if (!NT_SUCCESS(Status)) - { - ErrorCode = RtlNtStatusToDosError (Status); - SetLastError (ErrorCode); - return ErrorCode; - } + if (lpSubKey != NULL) + RtlInitUnicodeString (&SubKeyString, (LPWSTR)lpSubKey); + else + RtlInitUnicodeString (&SubKeyString, (LPWSTR)L""); - return ERROR_SUCCESS; + InitializeObjectAttributes (&ObjectAttributes, + &SubKeyString, + OBJ_CASE_INSENSITIVE, + KeyHandle, + NULL); + + Status = NtOpenKey ((PHANDLE)phkResult, samDesired, &ObjectAttributes); + + if (!NT_SUCCESS(Status)) + { + ErrorCode = RtlNtStatusToDosError (Status); + SetLastError (ErrorCode); + return ErrorCode; + } + + return ERROR_SUCCESS; }