Akihiro Sagawa : server: KeyNameInformation returns the full name of the key.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Oct 15 11:37:25 CDT 2014


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

Author: Akihiro Sagawa <sagawa.aki at gmail.com>
Date:   Tue Oct 14 00:25:00 2014 +0900

server: KeyNameInformation returns the full name of the key.

---

 dlls/ntdll/tests/reg.c | 19 ++++++++++++++-----
 server/registry.c      | 25 ++++++++++++++++++++++++-
 2 files changed, 38 insertions(+), 6 deletions(-)

diff --git a/dlls/ntdll/tests/reg.c b/dlls/ntdll/tests/reg.c
index 22048f9..08af73e 100644
--- a/dlls/ntdll/tests/reg.c
+++ b/dlls/ntdll/tests/reg.c
@@ -1285,7 +1285,7 @@ static void test_NtQueryKey(void)
     HANDLE key;
     NTSTATUS status;
     OBJECT_ATTRIBUTES attr;
-    ULONG len;
+    ULONG length, len;
     KEY_NAME_INFORMATION *info = NULL;
     UNICODE_STRING str;
 
@@ -1293,21 +1293,30 @@ static void test_NtQueryKey(void)
     status = pNtOpenKey(&key, KEY_READ, &attr);
     ok(status == STATUS_SUCCESS, "NtOpenKey Failed: 0x%08x\n", status);
 
-    status = pNtQueryKey(key, KeyNameInformation, NULL, 0, &len);
+    status = pNtQueryKey(key, KeyNameInformation, NULL, 0, &length);
     if (status == STATUS_INVALID_PARAMETER) {
         win_skip("KeyNameInformation is not supported\n");
         pNtClose(key);
         return;
     }
     todo_wine ok(status == STATUS_BUFFER_TOO_SMALL, "NtQueryKey Failed: 0x%08x\n", status);
+    info = HeapAlloc(GetProcessHeap(), 0, length);
 
-    info = HeapAlloc(GetProcessHeap(), 0, len);
-    status = pNtQueryKey(key, KeyNameInformation, info, len, &len);
+    /* non-zero buffer size, but insufficient */
+    status = pNtQueryKey(key, KeyNameInformation, info, sizeof(*info), &len);
+    ok(status == STATUS_BUFFER_OVERFLOW, "NtQueryKey Failed: 0x%08x\n", status);
+    ok(length == len, "got %d, expected %d\n", len, length);
+    ok(info->NameLength == winetestpath.Length, "got %d, expected %d\n",
+       info->NameLength, winetestpath.Length);
+
+    /* correct buffer size */
+    status = pNtQueryKey(key, KeyNameInformation, info, length, &len);
     ok(status == STATUS_SUCCESS, "NtQueryKey Failed: 0x%08x\n", status);
+    ok(length == len, "got %d, expected %d\n", len, length);
 
     str.Buffer = info->Name;
     str.Length = info->NameLength;
-    todo_wine ok(pRtlCompareUnicodeString(&winetestpath, &str, TRUE) == 0,
+    ok(pRtlCompareUnicodeString(&winetestpath, &str, TRUE) == 0,
        "got %s, expected %s\n",
        wine_dbgstr_wn(str.Buffer, str.Length/sizeof(WCHAR)),
        wine_dbgstr_wn(winetestpath.Buffer, winetestpath.Length/sizeof(WCHAR)));
diff --git a/server/registry.c b/server/registry.c
index 1436bfe..4aaaf03 100644
--- a/server/registry.c
+++ b/server/registry.c
@@ -864,10 +864,12 @@ static struct key *create_key_recursive( struct key *key, const struct unicode_s
 static void enum_key( const struct key *key, int index, int info_class,
                       struct enum_key_reply *reply )
 {
+    static const WCHAR backslash[] = { '\\' };
     int i;
     data_size_t len, namelen, classlen;
     data_size_t max_subkey = 0, max_class = 0;
     data_size_t max_value = 0, max_data = 0;
+    const struct key *k;
     char *data;
 
     if (index != -1)  /* -1 means use the specified key directly */
@@ -885,8 +887,14 @@ static void enum_key( const struct key *key, int index, int info_class,
 
     switch(info_class)
     {
-    case KeyBasicInformation:
     case KeyNameInformation:
+        namelen = 0;
+        for (k = key; k != root_key; k = k->parent)
+            namelen += k->namelen + sizeof(backslash);
+        if (!namelen) return;
+        namelen += sizeof(root_name) - sizeof(backslash);
+        /* fall through */
+    case KeyBasicInformation:
         classlen = 0; /* only return the name */
         /* fall through */
     case KeyNodeInformation:
@@ -935,6 +943,21 @@ static void enum_key( const struct key *key, int index, int info_class,
             memcpy( data, key->name, namelen );
             memcpy( data + namelen, key->class, len - namelen );
         }
+        else if (info_class == KeyNameInformation)
+        {
+            data_size_t pos = namelen;
+            reply->namelen = namelen;
+            for (k = key; k != root_key; k = k->parent)
+            {
+                pos -= k->namelen;
+                if (pos < len) memcpy( data + namelen, k->name,
+                                       min( k->namelen, len - pos ) );
+                pos -= sizeof(backslash);
+                if (pos < len) memcpy( data + namelen, backslash,
+                                       min( sizeof(backslash), len - pos ) );
+            }
+            memcpy( data, root_name, min( sizeof(root_name) - sizeof(backslash), len ) );
+        }
         else
         {
             reply->namelen = len;




More information about the wine-cvs mailing list