NtClose(Handle); \
}
#define IsPredefKey(HKey) \
- (((ULONG)(HKey) & 0xF0000000) == 0x80000000)
+ (((ULONG_PTR)(HKey) & 0xF0000000) == 0x80000000)
#define GetPredefKeyIndex(HKey) \
- ((ULONG)(HKey) & 0x0FFFFFFF)
+ ((ULONG_PTR)(HKey) & 0x0FFFFFFF)
static NTSTATUS OpenClassesRootKey(PHANDLE KeyHandle);
static NTSTATUS OpenLocalMachineKey (PHANDLE KeyHandle);
{
DWORD cbExpect = 0;
- if ((dwFlags & RRF_RT_DWORD) == RRF_RT_DWORD)
+ if ((dwFlags & RRF_RT_ANY) == RRF_RT_DWORD)
cbExpect = 4;
- else if ((dwFlags & RRF_RT_QWORD) == RRF_RT_QWORD)
+ else if ((dwFlags & RRF_RT_ANY) == RRF_RT_QWORD)
cbExpect = 8;
if (cbExpect && cbData != cbExpect)
status = NtEnumerateValueKey( KeyHandle, index, KeyValueFullInformation,
buffer, total_size, &total_size );
- if (status && status != STATUS_BUFFER_OVERFLOW) goto done;
+ if (status && (status != STATUS_BUFFER_OVERFLOW) && (status != STATUS_BUFFER_TOO_SMALL)) goto done;
/* 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)
+ while ((status == STATUS_BUFFER_OVERFLOW) || (status == STATUS_BUFFER_TOO_SMALL))
{
if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
if (!(buf_ptr = HeapAlloc( GetProcessHeap(), 0, total_size )))
{
ULONG len;
RtlUnicodeToMultiByteSize( &len, (WCHAR *)(buf_ptr + info->DataOffset),
- total_size - info->DataOffset );
+ info->DataLength );
if (data && len)
{
if (len > *count) status = STATUS_BUFFER_OVERFLOW;
else
{
RtlUnicodeToMultiByteN( (PCHAR)data, len, NULL, (WCHAR *)(buf_ptr + info->DataOffset),
- total_size - info->DataOffset );
+ info->DataLength );
/* 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;
}
else if (data)
{
- if (total_size - info->DataOffset > *count) status = STATUS_BUFFER_OVERFLOW;
- else memcpy( data, buf_ptr + info->DataOffset, total_size - info->DataOffset );
+ if (info->DataLength > *count) status = STATUS_BUFFER_OVERFLOW;
+ else memcpy( data, buf_ptr + info->DataOffset, info->DataLength );
}
if (value && !status)
status = NtEnumerateValueKey( KeyHandle, index, KeyValueFullInformation,
buffer, total_size, &total_size );
- if (status && status != STATUS_BUFFER_OVERFLOW) goto done;
+ if (status && (status != STATUS_BUFFER_OVERFLOW) && (status != STATUS_BUFFER_TOO_SMALL)) goto done;
if (value || data)
{
/* retry with a dynamically allocated buffer */
- while (status == STATUS_BUFFER_OVERFLOW)
+ while ((status == STATUS_BUFFER_OVERFLOW) || (status == STATUS_BUFFER_TOO_SMALL))
{
if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
if (!(buf_ptr = HeapAlloc( GetProcessHeap(), 0, total_size )))
if (data)
{
- if (total_size - info->DataOffset > *count)
+ if (info->DataLength > *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))
+ memcpy( data, buf_ptr + info->DataOffset, info->DataLength );
+ if (is_string(info->Type) && info->DataLength <= *count - sizeof(WCHAR))
{
/* 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);
+ WCHAR *ptr = (WCHAR *)(data + info->DataLength);
if (ptr > (WCHAR *)data && ptr[-1]) *ptr = 0;
}
}
LPDWORD lpcbData)
{
UNICODE_STRING ValueName;
- UNICODE_STRING ValueData;
+ LPWSTR lpValueBuffer;
LONG ErrorCode;
DWORD Length;
DWORD Type;
return ERROR_INVALID_PARAMETER;
}
+ Length = (lpcbData == NULL || lpData == NULL) ? 0 : *lpcbData * sizeof(WCHAR);
+
if (lpData)
{
- ValueData.Length = 0;
- ValueData.MaximumLength = (*lpcbData + 1) * sizeof(WCHAR);
- ValueData.Buffer = RtlAllocateHeap(ProcessHeap,
- 0,
- ValueData.MaximumLength);
- if (!ValueData.Buffer)
+ lpValueBuffer = RtlAllocateHeap(ProcessHeap,
+ 0,
+ Length + sizeof(WCHAR));
+ if (!lpValueBuffer)
{
return ERROR_OUTOFMEMORY;
}
}
else
{
- ValueData.Buffer = NULL;
- ValueData.Length = 0;
- ValueData.MaximumLength = 0;
+ lpValueBuffer = NULL;
if (lpcbData)
*lpcbData = 0;
}
- RtlCreateUnicodeStringFromAsciiz(&ValueName,
- (LPSTR)lpValueName);
+ if(!RtlCreateUnicodeStringFromAsciiz(&ValueName,
+ (LPSTR)lpValueName))
+ {
+ ERR("RtlCreateUnicodeStringFromAsciiz failed!\n");
+ ErrorCode = ERROR_OUTOFMEMORY;
+ goto cleanup;
+ }
- Length = (lpcbData == NULL) ? 0 : *lpcbData * sizeof(WCHAR);
ErrorCode = RegQueryValueExW(hKey,
ValueName.Buffer,
lpReserved,
&Type,
- (lpData == NULL) ? NULL : (LPBYTE)ValueData.Buffer,
+ (LPBYTE)lpValueBuffer,
&Length);
TRACE("ErrorCode %lu\n", ErrorCode);
+
RtlFreeUnicodeString(&ValueName);
if (ErrorCode == ERROR_SUCCESS ||
if (is_string(Type))
{
- if (ErrorCode == ERROR_SUCCESS && ValueData.Buffer != NULL)
+ if (ErrorCode == ERROR_SUCCESS && lpValueBuffer != NULL)
{
- Status = RtlUnicodeToMultiByteN((PCHAR)lpData, *lpcbData, &Index, (PWCHAR)ValueData.Buffer, Length);
+ Status = RtlUnicodeToMultiByteN((PCHAR)lpData, *lpcbData, &Index, (PWCHAR)lpValueBuffer, Length);
if (NT_SUCCESS(Status))
{
PCHAR szData = (PCHAR)lpData;
Length = Length / sizeof(WCHAR);
}
- else if (ErrorCode == ERROR_SUCCESS && ValueData.Buffer != NULL)
+ else if (ErrorCode == ERROR_SUCCESS && lpValueBuffer != NULL)
{
if (*lpcbData < Length)
{
}
else
{
- RtlMoveMemory(lpData, ValueData.Buffer, Length);
+ RtlMoveMemory(lpData, lpValueBuffer, Length);
}
}
*lpType = Type;
}
- if (ValueData.Buffer != NULL)
+cleanup:
+ if (lpValueBuffer != NULL)
{
- RtlFreeHeap(ProcessHeap, 0, ValueData.Buffer);
+ RtlFreeHeap(ProcessHeap, 0, lpValueBuffer);
}
return ErrorCode;
return RtlNtStatusToDosError(Status);
}
- if (lpValueName != NULL)
- {
- RtlInitUnicodeString(&ValueName,
- lpValueName);
- }
- else
- {
- RtlInitUnicodeString(&ValueName, L"");
- }
+ RtlInitUnicodeString(&ValueName, lpValueName);
pValueName = &ValueName;
if (is_string(dwType) && (cbData != 0))