Module: wine Branch: master Commit: 526cb8c375022fd2f2339401abe7e31e2e99984f URL: http://source.winehq.org/git/wine.git/?a=commit;h=526cb8c375022fd2f2339401ab...
Author: Rob Shearman rob@codeweavers.com Date: Sun Jan 6 15:36:11 2008 +0000
ntdll: Fix NtQueryValueKey for KeyValueBasicInformation.
Add some tests for this.
---
dlls/ntdll/reg.c | 14 +++++++++++--- dlls/ntdll/tests/reg.c | 27 +++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/reg.c b/dlls/ntdll/reg.c index e2a3b91..9c9509d 100644 --- a/dlls/ntdll/reg.c +++ b/dlls/ntdll/reg.c @@ -481,9 +481,17 @@ NTSTATUS WINAPI NtQueryValueKey( HANDLE handle, const UNICODE_STRING *name, switch(info_class) { 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; break; + } case KeyValueFullInformation: { KEY_VALUE_FULL_INFORMATION *full_info = info; @@ -509,12 +517,12 @@ NTSTATUS WINAPI NtQueryValueKey( HANDLE handle, const UNICODE_STRING *name, { req->hkey = handle; 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 ))) { copy_key_value_info( info_class, info, length, reply->type, 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; } } diff --git a/dlls/ntdll/tests/reg.c b/dlls/ntdll/tests/reg.c index 3b983ee..14cc79f 100644 --- a/dlls/ntdll/tests/reg.c +++ b/dlls/ntdll/tests/reg.c @@ -67,6 +67,13 @@ typedef struct _RTL_QUERY_REGISTRY_TABLE { ULONG DefaultLength; } 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 { ULONG TitleIndex; ULONG Type; @@ -464,6 +471,7 @@ static void test_NtQueryValueKey(void) NTSTATUS status; OBJECT_ATTRIBUTES attr; UNICODE_STRING ValName; + KEY_VALUE_BASIC_INFORMATION *basic_info; KEY_VALUE_PARTIAL_INFORMATION *partial_info; KEY_VALUE_FULL_INFORMATION *full_info; DWORD len; @@ -474,6 +482,25 @@ static void test_NtQueryValueKey(void) status = pNtOpenKey(&key, KEY_READ, &attr); 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]); partial_info = HeapAlloc(GetProcessHeap(), 0, len); status = pNtQueryValueKey(key, &ValName, KeyValuePartialInformation, partial_info, len, &len);