Commit 526cb8c3 authored by Rob Shearman's avatar Rob Shearman Committed by Alexandre Julliard

ntdll: Fix NtQueryValueKey for KeyValueBasicInformation.

Add some tests for this.
parent e958a570
...@@ -481,9 +481,17 @@ NTSTATUS WINAPI NtQueryValueKey( HANDLE handle, const UNICODE_STRING *name, ...@@ -481,9 +481,17 @@ NTSTATUS WINAPI NtQueryValueKey( HANDLE handle, const UNICODE_STRING *name,
switch(info_class) switch(info_class)
{ {
case KeyValueBasicInformation: case KeyValueBasicInformation:
fixed_size = (char *)((KEY_VALUE_BASIC_INFORMATION *)info)->Name - (char *)info; {
KEY_VALUE_BASIC_INFORMATION *basic_info = info;
if (FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name) < length)
{
memcpy(basic_info->Name, name->Buffer,
min(length - FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name), name->Length));
}
fixed_size = FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name) + name->Length;
data_ptr = NULL; data_ptr = NULL;
break; break;
}
case KeyValueFullInformation: case KeyValueFullInformation:
{ {
KEY_VALUE_FULL_INFORMATION *full_info = info; KEY_VALUE_FULL_INFORMATION *full_info = info;
...@@ -509,12 +517,12 @@ NTSTATUS WINAPI NtQueryValueKey( HANDLE handle, const UNICODE_STRING *name, ...@@ -509,12 +517,12 @@ NTSTATUS WINAPI NtQueryValueKey( HANDLE handle, const UNICODE_STRING *name,
{ {
req->hkey = handle; req->hkey = handle;
wine_server_add_data( req, name->Buffer, name->Length ); wine_server_add_data( req, name->Buffer, name->Length );
if (length > fixed_size) wine_server_set_reply( req, data_ptr, length - fixed_size ); if (length > fixed_size && data_ptr) wine_server_set_reply( req, data_ptr, length - fixed_size );
if (!(ret = wine_server_call( req ))) if (!(ret = wine_server_call( req )))
{ {
copy_key_value_info( info_class, info, length, reply->type, copy_key_value_info( info_class, info, length, reply->type,
name->Length, reply->total ); name->Length, reply->total );
*result_len = fixed_size + reply->total; *result_len = fixed_size + (info_class == KeyValueBasicInformation ? 0 : reply->total);
if (length < *result_len) ret = STATUS_BUFFER_OVERFLOW; if (length < *result_len) ret = STATUS_BUFFER_OVERFLOW;
} }
} }
......
...@@ -67,6 +67,13 @@ typedef struct _RTL_QUERY_REGISTRY_TABLE { ...@@ -67,6 +67,13 @@ typedef struct _RTL_QUERY_REGISTRY_TABLE {
ULONG DefaultLength; ULONG DefaultLength;
} RTL_QUERY_REGISTRY_TABLE, *PRTL_QUERY_REGISTRY_TABLE; } RTL_QUERY_REGISTRY_TABLE, *PRTL_QUERY_REGISTRY_TABLE;
typedef struct _KEY_VALUE_BASIC_INFORMATION {
ULONG TitleIndex;
ULONG Type;
ULONG NameLength;
WCHAR Name[1];
} KEY_VALUE_BASIC_INFORMATION, *PKEY_VALUE_BASIC_INFORMATION;
typedef struct _KEY_VALUE_PARTIAL_INFORMATION { typedef struct _KEY_VALUE_PARTIAL_INFORMATION {
ULONG TitleIndex; ULONG TitleIndex;
ULONG Type; ULONG Type;
...@@ -464,6 +471,7 @@ static void test_NtQueryValueKey(void) ...@@ -464,6 +471,7 @@ static void test_NtQueryValueKey(void)
NTSTATUS status; NTSTATUS status;
OBJECT_ATTRIBUTES attr; OBJECT_ATTRIBUTES attr;
UNICODE_STRING ValName; UNICODE_STRING ValName;
KEY_VALUE_BASIC_INFORMATION *basic_info;
KEY_VALUE_PARTIAL_INFORMATION *partial_info; KEY_VALUE_PARTIAL_INFORMATION *partial_info;
KEY_VALUE_FULL_INFORMATION *full_info; KEY_VALUE_FULL_INFORMATION *full_info;
DWORD len; DWORD len;
...@@ -474,6 +482,25 @@ static void test_NtQueryValueKey(void) ...@@ -474,6 +482,25 @@ static void test_NtQueryValueKey(void)
status = pNtOpenKey(&key, KEY_READ, &attr); status = pNtOpenKey(&key, KEY_READ, &attr);
ok(status == STATUS_SUCCESS, "NtOpenKey Failed: 0x%08x\n", status); ok(status == STATUS_SUCCESS, "NtOpenKey Failed: 0x%08x\n", status);
len = FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name[0]);
basic_info = HeapAlloc(GetProcessHeap(), 0, len);
status = pNtQueryValueKey(key, &ValName, KeyValueBasicInformation, basic_info, len, &len);
ok(status == STATUS_BUFFER_OVERFLOW, "NtQueryValueKey should have returned STATUS_BUFFER_OVERFLOW instead of 0x%08x\n", status);
ok(basic_info->TitleIndex == 0, "NtQueryValueKey returned wrong TitleIndex %d\n", basic_info->Type);
ok(basic_info->Type == REG_DWORD, "NtQueryValueKey returned wrong Type %d\n", basic_info->Type);
ok(basic_info->NameLength == 20, "NtQueryValueKey returned wrong NameLength %d\n", basic_info->NameLength);
ok(len == FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name[basic_info->NameLength/sizeof(WCHAR)]), "NtQueryValueKey returned wrong len %d\n", len);
basic_info = HeapReAlloc(GetProcessHeap(), 0, basic_info, len);
status = pNtQueryValueKey(key, &ValName, KeyValueBasicInformation, basic_info, len, &len);
ok(status == STATUS_SUCCESS, "NtQueryValueKey should have returned STATUS_SUCCESS instead of 0x%08x\n", status);
ok(basic_info->TitleIndex == 0, "NtQueryValueKey returned wrong TitleIndex %d\n", basic_info->Type);
ok(basic_info->Type == REG_DWORD, "NtQueryValueKey returned wrong Type %d\n", basic_info->Type);
ok(basic_info->NameLength == 20, "NtQueryValueKey returned wrong NameLength %d\n", basic_info->NameLength);
ok(len == FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name[basic_info->NameLength/sizeof(WCHAR)]), "NtQueryValueKey returned wrong len %d\n", len);
ok(!memcmp(basic_info->Name, ValName.Buffer, ValName.Length), "incorrect Name returned\n");
HeapFree(GetProcessHeap(), 0, basic_info);
len = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]); len = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]);
partial_info = HeapAlloc(GetProcessHeap(), 0, len); partial_info = HeapAlloc(GetProcessHeap(), 0, len);
status = pNtQueryValueKey(key, &ValName, KeyValuePartialInformation, partial_info, len, &len); status = pNtQueryValueKey(key, &ValName, KeyValuePartialInformation, partial_info, len, &len);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment