Alexandre Julliard : server: Implement object name information for registry keys.

Alexandre Julliard julliard at winehq.org
Tue Sep 22 15:46:41 CDT 2020


Module: wine
Branch: master
Commit: 96dcee64307b63ed3c07d13832fee15c3dc21ff1
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=96dcee64307b63ed3c07d13832fee15c3dc21ff1

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Sep 22 16:57:04 2020 +0200

server: Implement object name information for registry keys.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/tests/om.c |  2 +-
 server/registry.c     | 51 ++++++++++++++++++++++++++++++---------------------
 2 files changed, 31 insertions(+), 22 deletions(-)

diff --git a/dlls/ntdll/tests/om.c b/dlls/ntdll/tests/om.c
index 15f905330e..d3b932bec1 100644
--- a/dlls/ntdll/tests/om.c
+++ b/dlls/ntdll/tests/om.c
@@ -1470,7 +1470,7 @@ static void test_query_object(void)
     status = pNtCreateKey( &handle, KEY_READ, &attr, 0, 0, 0, 0 );
     ok( status == STATUS_SUCCESS, "NtCreateKey failed status %x\n", status );
 
-    test_object_name( handle, L"\\REGISTRY\\MACHINE", TRUE );
+    test_object_name( handle, L"\\REGISTRY\\MACHINE", FALSE );
     test_object_type( handle, L"Key" );
 
     pNtClose( handle );
diff --git a/server/registry.c b/server/registry.c
index f4386d9bfb..438ec6c6fc 100644
--- a/server/registry.c
+++ b/server/registry.c
@@ -148,6 +148,7 @@ static void key_dump( struct object *obj, int verbose );
 static struct object_type *key_get_type( struct object *obj );
 static unsigned int key_map_access( struct object *obj, unsigned int access );
 static struct security_descriptor *key_get_sd( struct object *obj );
+static WCHAR *key_get_full_name( struct object *obj, data_size_t *len );
 static int key_close_handle( struct object *obj, struct process *process, obj_handle_t handle );
 static void key_destroy( struct object *obj );
 
@@ -165,7 +166,7 @@ static const struct object_ops key_ops =
     key_map_access,          /* map_access */
     key_get_sd,              /* get_sd */
     default_set_sd,          /* set_sd */
-    no_get_full_name,        /* get_full_name */
+    key_get_full_name,       /* get_full_name */
     no_lookup_name,          /* lookup_name */
     no_link_name,            /* link_name */
     NULL,                    /* unlink_name */
@@ -394,6 +395,29 @@ static struct security_descriptor *key_get_sd( struct object *obj )
     return key_default_sd;
 }
 
+static WCHAR *key_get_full_name( struct object *obj, data_size_t *ret_len )
+{
+    static const WCHAR backslash = '\\';
+    struct key *key = (struct key *) obj;
+    data_size_t len = sizeof(root_name) - sizeof(WCHAR);
+    char *ret;
+
+    for (key = (struct key *)obj; key != root_key; key = key->parent) len += key->namelen + sizeof(WCHAR);
+    if (!(ret = malloc( len ))) return NULL;
+
+    *ret_len = len;
+    key = (struct key *)obj;
+    for (key = (struct key *)obj; key != root_key; key = key->parent)
+    {
+        memcpy( ret + len - key->namelen, key->name, key->namelen );
+        dump_strW( (WCHAR *)(ret + len - key->namelen), key->namelen, stderr, "" );
+        len -= key->namelen + sizeof(WCHAR);
+        memcpy( ret + len, &backslash, sizeof(WCHAR) );
+    }
+    memcpy( ret, root_name, sizeof(root_name) - sizeof(WCHAR) );
+    return (WCHAR *)ret;
+}
+
 /* close the notification associated with a handle */
 static int key_close_handle( struct object *obj, struct process *process, obj_handle_t handle )
 {
@@ -876,15 +900,13 @@ static struct key *create_key_recursive( struct key *key, const struct unicode_s
 }
 
 /* query information about a key or a subkey */
-static void enum_key( const struct key *key, int index, int info_class,
-                      struct enum_key_reply *reply )
+static void enum_key( 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;
+    WCHAR *fullname = NULL;
     char *data;
 
     if (index != -1)  /* -1 means use the specified key directly */
@@ -903,11 +925,7 @@ static void enum_key( const struct key *key, int index, int info_class,
     switch(info_class)
     {
     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);
+        if (!(fullname = key->obj.ops->get_full_name( &key->obj, &namelen ))) return;
         /* fall through */
     case KeyBasicInformation:
         classlen = 0; /* only return the name */
@@ -959,18 +977,8 @@ static void enum_key( const struct key *key, int index, int info_class,
         }
         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 + pos, k->name,
-                                       min( k->namelen, len - pos ) );
-                pos -= sizeof(backslash);
-                if (pos < len) memcpy( data + pos, backslash,
-                                       min( sizeof(backslash), len - pos ) );
-            }
-            memcpy( data, root_name, min( sizeof(root_name) - sizeof(backslash), len ) );
+            memcpy( data, fullname, namelen );
         }
         else
         {
@@ -978,6 +986,7 @@ static void enum_key( const struct key *key, int index, int info_class,
             memcpy( data, key->name, len );
         }
     }
+    free( fullname );
     if (debug_level > 1) dump_operation( key, NULL, "Enum" );
 }
 




More information about the wine-cvs mailing list