RegOpenKey, RegOpenKeyEx A/W imported and ported from WINE. This keeps the current test set in advapi32_test registry on 85/0 level

svn path=/trunk/; revision=14969
This commit is contained in:
Aleksey Bragin 2005-05-04 15:53:54 +00:00
parent 8460c6e770
commit d534342503

View file

@ -8,6 +8,7 @@
* UPDATE HISTORY: * UPDATE HISTORY:
* Created 01/11/98 * Created 01/11/98
* 19990309 EA Stubs * 19990309 EA Stubs
* 20050502 Fireball imported some stuff from WINE
*/ */
/* INCLUDES *****************************************************************/ /* INCLUDES *****************************************************************/
@ -22,6 +23,9 @@
#define REG_MAX_NAME_SIZE 256 #define REG_MAX_NAME_SIZE 256
#define REG_MAX_DATA_SIZE 2048 #define REG_MAX_DATA_SIZE 2048
/* FIXME: should go into msvcrt.h header? */
#define offsetof(s,m) (size_t)&(((s*)NULL)->m)
/* GLOBALS ******************************************************************/ /* GLOBALS ******************************************************************/
static RTL_CRITICAL_SECTION HandleTableCS; static RTL_CRITICAL_SECTION HandleTableCS;
@ -40,6 +44,11 @@ static NTSTATUS OpenCurrentConfigKey(PHANDLE KeyHandle);
/* FUNCTIONS ****************************************************************/ /* 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 * RegInitDefaultHandles
@ -1161,417 +1170,226 @@ RegEnumKeyExW (HKEY hKey,
return ErrorCode; return ErrorCode;
} }
/************************************************************************ /************************************************************************
* RegEnumValueA * RegEnumValueA
* *
* @implemented * @implemented
*/ */
LONG STDCALL LONG STDCALL
RegEnumValueA (HKEY hKey, RegEnumValueA( HKEY hKey, DWORD index, LPSTR value, LPDWORD val_count,
DWORD dwIndex, LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count )
LPSTR lpValueName,
LPDWORD lpcbValueName, // lpValueName buffer len
LPDWORD lpReserved,
LPDWORD lpType,
LPBYTE lpData,
LPDWORD lpcbData) // lpData buffer len
{ {
union
{
KEY_VALUE_FULL_INFORMATION Full;
KEY_VALUE_BASIC_INFORMATION Basic;
} *ValueInfo;
ULONG NameLength;
ULONG BufferSize;
ULONG DataLength = 0;
ULONG ResultSize;
HANDLE KeyHandle; HANDLE KeyHandle;
LONG ErrorCode; NTSTATUS status;
NTSTATUS Status; DWORD total_size;
UNICODE_STRING StringU; char buffer[256], *buf_ptr = buffer;
ANSI_STRING StringA; KEY_VALUE_FULL_INFORMATION *info = (KEY_VALUE_FULL_INFORMATION *)buffer;
BOOL IsStringType; 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); /* NT only checks count, not val_count */
if (!NT_SUCCESS(Status)) 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); SetLastError (ErrorCode);
return ErrorCode; return ErrorCode;
} }
if (*lpcbValueName > 0) total_size = info_size + (MAX_PATH + 1) * sizeof(WCHAR);
NameLength = min (*lpcbValueName - 1, REG_MAX_NAME_SIZE) * sizeof(WCHAR); if (data) total_size += *count;
else total_size = min( sizeof(buffer), total_size );
NameLength = 0;
if (lpData) status = NtEnumerateValueKey( KeyHandle, index, KeyValueFullInformation,
{ buffer, total_size, &total_size );
DataLength = min (*lpcbData * sizeof(WCHAR), REG_MAX_DATA_SIZE); if (status && status != STATUS_BUFFER_OVERFLOW) goto done;
BufferSize = ((sizeof(KEY_VALUE_FULL_INFORMATION) + NameLength + 3) & ~3) + DataLength;
}
else
{
BufferSize = sizeof(KEY_VALUE_BASIC_INFORMATION) + NameLength;
}
ValueInfo = RtlAllocateHeap (ProcessHeap, 0, BufferSize); /* we need to fetch the contents for a string type even if not requested,
if (ValueInfo == NULL) * because we need to compute the length of the ASCII string. */
{ if (value || data || is_string(info->Type))
SetLastError(ERROR_OUTOFMEMORY); {
return ERROR_OUTOFMEMORY; /* 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, if (status) goto done;
(ULONG)dwIndex,
lpData ? KeyValueFullInformation : KeyValueBasicInformation,
ValueInfo,
BufferSize,
&ResultSize);
DPRINT("NtEnumerateValueKey() returned status 0x%X\n", Status); if (is_string(info->Type))
if (!NT_SUCCESS(Status)) {
{ DWORD len;
ErrorCode = RtlNtStatusToDosError (Status); 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 if (value && !status)
// we must let caller know the minimum accepted size {
// and value type DWORD len;
if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL)
{
ErrorCode = ERROR_MORE_DATA;
// query now with the sufficient buffer size RtlUnicodeToMultiByteSize( &len, info->Name, info->NameLength );
RtlFreeHeap (ProcessHeap, 0, ValueInfo); if (len >= *val_count)
BufferSize = ResultSize; {
ValueInfo = RtlAllocateHeap (ProcessHeap, 0, BufferSize); // will be freed at the bottom, as usual status = STATUS_BUFFER_OVERFLOW;
if (ValueInfo == NULL) if (*val_count)
{ {
SetLastError(ERROR_OUTOFMEMORY); len = *val_count - 1;
return ERROR_OUTOFMEMORY; 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, if (type) *type = info->Type;
(ULONG)dwIndex, if (count) *count = info->DataLength;
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 (lpData) done:
{ if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
if (lpcbData) return RtlNtStatusToDosError(status);
{
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;
} }
/******************************************************************************
/************************************************************************ * RegEnumValueW [ADVAPI32.@]
* RegEnumValueW
*
* @implemented * @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 LONG STDCALL
RegEnumValueW (HKEY hKey, RegEnumValueW( HKEY hKey, DWORD index, LPWSTR value, PDWORD val_count,
DWORD dwIndex, PDWORD reserved, PDWORD type, LPBYTE data, PDWORD count )
LPWSTR lpValueName,
LPDWORD lpcbValueName,
LPDWORD lpReserved,
LPDWORD lpType,
LPBYTE lpData,
LPDWORD lpcbData)
{ {
union
{
KEY_VALUE_FULL_INFORMATION Full;
KEY_VALUE_BASIC_INFORMATION Basic;
} *ValueInfo;
ULONG NameLength;
ULONG BufferSize;
ULONG DataLength = 0;
ULONG ResultSize;
HANDLE KeyHandle; 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); /* NT only checks count, not val_count */
if (!NT_SUCCESS(Status)) 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); SetLastError (ErrorCode);
return ErrorCode; return ErrorCode;
} }
if (*lpcbValueName > 0) total_size = info_size + (MAX_PATH + 1) * sizeof(WCHAR);
NameLength = min (*lpcbValueName - 1, REG_MAX_NAME_SIZE) * sizeof(WCHAR); if (data) total_size += *count;
else total_size = min( sizeof(buffer), total_size );
NameLength = 0;
if (lpData) status = NtEnumerateValueKey( KeyHandle, index, KeyValueFullInformation,
{ buffer, total_size, &total_size );
DataLength = min(*lpcbData, REG_MAX_DATA_SIZE); if (status && status != STATUS_BUFFER_OVERFLOW) goto done;
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);
DPRINT("NtEnumerateValueKey() returned status 0x%X\n", Status); if (value || data)
if (!NT_SUCCESS(Status)) {
{ /* retry with a dynamically allocated buffer */
ErrorCode = RtlNtStatusToDosError (Status); 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 if (status) goto done;
// 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;
// query now with the sufficient buffer size if (value)
RtlFreeHeap (ProcessHeap, 0, ValueInfo); {
BufferSize = ResultSize; if (info->NameLength/sizeof(WCHAR) >= *val_count)
ValueInfo = RtlAllocateHeap (ProcessHeap, 0, BufferSize); // will be freed at the bottom, as usual {
if (ValueInfo == NULL) status = STATUS_BUFFER_OVERFLOW;
{ goto overflow;
SetLastError(ERROR_OUTOFMEMORY); }
return ERROR_OUTOFMEMORY; memcpy( value, info->Name, info->NameLength );
} *val_count = info->NameLength / sizeof(WCHAR);
value[*val_count] = 0;
}
Status = NtEnumerateValueKey (KeyHandle, if (data)
(ULONG)dwIndex, {
lpData ? KeyValueFullInformation : KeyValueBasicInformation, if (total_size - info->DataOffset > *count)
ValueInfo, {
BufferSize, status = STATUS_BUFFER_OVERFLOW;
&ResultSize); goto overflow;
if (!NT_SUCCESS(Status)) }
{ memcpy( data, buf_ptr + info->DataOffset, total_size - info->DataOffset );
// ok, some other error if (total_size - info->DataOffset <= *count-sizeof(WCHAR) && is_string(info->Type))
ErrorCode = RtlNtStatusToDosError (Status); {
} /* if the type is REG_SZ and data is not 0-terminated
else * and there is enough space in the buffer NT appends a \0 */
{ WCHAR *ptr = (WCHAR *)(data + total_size - info->DataOffset);
// we have information now, pass it to the caller if (ptr > (WCHAR *)data && ptr[-1]) *ptr = 0;
// but don't touch valueName length here }
if (lpData && lpcbData) }
*lpcbData = ValueInfo->Full.DataLength; }
else status = STATUS_SUCCESS;
// pass type also overflow:
if (lpType) if (type) *type = info->Type;
*lpType = lpData ? ValueInfo->Full.Type : ValueInfo->Basic.Type; if (count) *count = info->DataLength;
}
}
}
else
{
if (lpData)
{
if (ValueInfo->Full.DataLength > DataLength ||
ValueInfo->Full.NameLength > NameLength)
{
// overflow data
ErrorCode = ERROR_MORE_DATA;
// return correct information for data length and type done:
if (lpcbData) if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
*lpcbData = ValueInfo->Full.DataLength; return RtlNtStatusToDosError(status);
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;
} }
/************************************************************************ /************************************************************************
* RegFlushKey * RegFlushKey
* *
@ -1818,6 +1636,8 @@ RegNotifyChangeKeyValue (HKEY hKey,
/************************************************************************ /************************************************************************
* RegOpenKeyA * RegOpenKeyA
* *
* 20050503 Fireball - imported from WINE
*
* @implemented * @implemented
*/ */
LONG STDCALL LONG STDCALL
@ -1825,45 +1645,15 @@ RegOpenKeyA (HKEY hKey,
LPCSTR lpSubKey, LPCSTR lpSubKey,
PHKEY phkResult) PHKEY phkResult)
{ {
OBJECT_ATTRIBUTES ObjectAttributes; DPRINT("RegOpenKeyA hKey 0x%x lpSubKey %s phkResult %p\n", hKey, lpSubKey, phkResult);
UNICODE_STRING SubKeyString;
HANDLE KeyHandle;
LONG ErrorCode;
NTSTATUS Status;
DPRINT("RegOpenKeyA hKey 0x%x lpSubKey %s phkResult %p\n", hKey, lpSubKey, phkResult); if (!lpSubKey || !*lpSubKey)
{
*phkResult = hKey;
return ERROR_SUCCESS;
}
// Check input params return RegOpenKeyExA( hKey, lpSubKey, 0, KEY_ALL_ACCESS, phkResult);
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;
} }
@ -1872,6 +1662,7 @@ RegOpenKeyA (HKEY hKey,
* *
* 19981101 Ariadne * 19981101 Ariadne
* 19990525 EA * 19990525 EA
* 20050503 Fireball - imported from WINE
* *
* @implemented * @implemented
*/ */
@ -1880,44 +1671,14 @@ RegOpenKeyW (HKEY hKey,
LPCWSTR lpSubKey, LPCWSTR lpSubKey,
PHKEY phkResult) PHKEY phkResult)
{ {
OBJECT_ATTRIBUTES ObjectAttributes; DPRINT("RegOpenKeyW hKey 0x%x lpSubKey %S phkResult %p\n", hKey, lpSubKey, phkResult);
UNICODE_STRING SubKeyString;
HANDLE KeyHandle;
LONG ErrorCode;
NTSTATUS Status;
DPRINT("RegOpenKeyW hKey 0x%x lpSubKey %S phkResult %p\n", hKey, lpSubKey, phkResult); if (!lpSubKey || !*lpSubKey)
{
// Check input params *phkResult = hKey;
if (phkResult == NULL) return ERROR_INVALID_PARAMETER; return ERROR_SUCCESS;
}
Status = MapDefaultKey (&KeyHandle, return RegOpenKeyExW(hKey, lpSubKey, 0, KEY_ALL_ACCESS, phkResult);
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;
} }
@ -1933,42 +1694,40 @@ RegOpenKeyExA (HKEY hKey,
REGSAM samDesired, REGSAM samDesired,
PHKEY phkResult) PHKEY phkResult)
{ {
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING SubKeyString; UNICODE_STRING SubKeyString;
HANDLE KeyHandle; HANDLE KeyHandle;
LONG ErrorCode; LONG ErrorCode;
NTSTATUS Status; NTSTATUS Status;
DPRINT("RegOpenKeyExA hKey 0x%x lpSubKey %s ulOptions 0x%x samDesired 0x%x phkResult %p\n", DPRINT("RegOpenKeyExA hKey 0x%x lpSubKey %s ulOptions 0x%x samDesired 0x%x phkResult %p\n",
hKey, lpSubKey, ulOptions, samDesired, phkResult); hKey, lpSubKey, ulOptions, samDesired, phkResult);
Status = MapDefaultKey (&KeyHandle,
hKey);
if (!NT_SUCCESS(Status))
{
ErrorCode = RtlNtStatusToDosError (Status);
SetLastError (ErrorCode);
return ErrorCode;
}
RtlCreateUnicodeStringFromAsciiz (&SubKeyString, Status = MapDefaultKey (&KeyHandle, hKey);
(LPSTR)lpSubKey); if (!NT_SUCCESS(Status))
InitializeObjectAttributes (&ObjectAttributes, {
&SubKeyString, ErrorCode = RtlNtStatusToDosError (Status);
OBJ_CASE_INSENSITIVE, SetLastError (ErrorCode);
KeyHandle, return ErrorCode;
NULL); }
Status = NtOpenKey ((PHANDLE)phkResult,
samDesired,
&ObjectAttributes);
RtlFreeUnicodeString (&SubKeyString);
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, REGSAM samDesired,
PHKEY phkResult) PHKEY phkResult)
{ {
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING SubKeyString; UNICODE_STRING SubKeyString;
HANDLE KeyHandle; HANDLE KeyHandle;
LONG ErrorCode; LONG ErrorCode;
NTSTATUS Status; NTSTATUS Status;
DPRINT("RegOpenKeyExW hKey 0x%x lpSubKey %S ulOptions 0x%x samDesired 0x%x phkResult %p\n", DPRINT("RegOpenKeyExW hKey 0x%x lpSubKey %S ulOptions 0x%x samDesired 0x%x phkResult %p\n",
hKey, lpSubKey, ulOptions, samDesired, phkResult); hKey, lpSubKey, ulOptions, samDesired, phkResult);
Status = MapDefaultKey (&KeyHandle,
hKey); Status = MapDefaultKey (&KeyHandle, hKey);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
ErrorCode = RtlNtStatusToDosError (Status); ErrorCode = RtlNtStatusToDosError (Status);
SetLastError (ErrorCode); SetLastError (ErrorCode);
return ErrorCode; return ErrorCode;
} }
if (lpSubKey != NULL) if (lpSubKey != NULL)
{ RtlInitUnicodeString (&SubKeyString, (LPWSTR)lpSubKey);
RtlInitUnicodeString (&SubKeyString, else
(LPWSTR)lpSubKey); RtlInitUnicodeString (&SubKeyString, (LPWSTR)L"");
}
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;
}
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;
} }