Rob Shearman : ntdll: Fix NtQueryValueKey for KeyValueBasicInformation.

Alexandre Julliard julliard at winehq.org
Mon Jan 7 16:24:58 CST 2008


Module: wine
Branch: master
Commit: 526cb8c375022fd2f2339401abe7e31e2e99984f
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=526cb8c375022fd2f2339401abe7e31e2e99984f

Author: Rob Shearman <rob at 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);




More information about the wine-cvs mailing list