Alexandre Julliard : server: Implement link_name() for registry keys.

Alexandre Julliard julliard at winehq.org
Thu Jul 7 17:03:25 CDT 2022


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Jul  7 11:49:50 2022 +0200

server: Implement link_name() for registry keys.

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

---

 server/registry.c | 78 +++++++++++++++++++++++++++++++++----------------------
 1 file changed, 47 insertions(+), 31 deletions(-)

diff --git a/server/registry.c b/server/registry.c
index c7b56344bae..2c52ec85d29 100644
--- a/server/registry.c
+++ b/server/registry.c
@@ -164,6 +164,7 @@ static void key_dump( struct object *obj, int verbose );
 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_link_name( struct object *obj, struct object_name *name, struct object *parent );
 static void key_unlink_name( struct object *obj, struct object_name *name );
 static int key_close_handle( struct object *obj, struct process *process, obj_handle_t handle );
 static void key_destroy( struct object *obj );
@@ -184,7 +185,7 @@ static const struct object_ops key_ops =
     default_set_sd,          /* set_sd */
     key_get_full_name,       /* get_full_name */
     no_lookup_name,          /* lookup_name */
-    no_link_name,            /* link_name */
+    key_link_name,           /* link_name */
     key_unlink_name,         /* unlink_name */
     no_open_file,            /* open_file */
     no_kernel_obj_list,      /* get_kernel_obj_list */
@@ -202,6 +203,7 @@ static inline struct key *get_parent( const struct key *key )
 {
     struct object *parent = key->obj.name->parent;
 
+    if (!parent || parent->ops != &key_ops) return NULL;
     return (struct key *)parent;
 }
 
@@ -483,6 +485,40 @@ static WCHAR *key_get_full_name( struct object *obj, data_size_t *ret_len )
     return (WCHAR *)ret;
 }
 
+static int key_link_name( struct object *obj, struct object_name *name, struct object *parent )
+{
+    struct key *key = (struct key *)obj;
+    struct key *parent_key = (struct key *)parent;
+    struct unicode_str tmp;
+    int i, index;
+
+    if (parent->ops != &key_ops)
+    {
+        /* only the root key can be created inside a normal directory */
+        if (!root_key) return directory_link_name( obj, name, parent );
+        set_error( STATUS_OBJECT_NAME_NOT_FOUND );
+        return 0;
+    }
+
+    if (parent_key->last_subkey + 1 == parent_key->nb_subkeys)
+    {
+        /* need to grow the array */
+        if (!grow_subkeys( parent_key )) return 0;
+    }
+    tmp.str = name->name;
+    tmp.len = name->len;
+    find_subkey( parent_key, &tmp, &index );
+
+    for (i = ++parent_key->last_subkey; i > index; i--)
+        parent_key->subkeys[i] = parent_key->subkeys[i - 1];
+    parent_key->subkeys[index] = (struct key *)grab_object( key );
+    if (is_wow6432node( name->name, name->len ) &&
+        !is_wow6432node( parent_key->obj.name->name, parent_key->obj.name->len ))
+        parent_key->wow6432node = key;
+    name->parent = parent;
+    return 1;
+}
+
 static void key_unlink_name( struct object *obj, struct object_name *name )
 {
     struct key *key = (struct key *)obj;
@@ -676,33 +712,14 @@ static void touch_key( struct key *key, unsigned int change )
 }
 
 /* allocate a subkey for a given key, and return its index */
-static struct key *alloc_subkey( struct key *parent, const struct unicode_str *name,
-                                 int index, timeout_t modif )
+static struct key *alloc_subkey( struct key *parent, const struct unicode_str *name, timeout_t modif )
 {
     struct key *key;
-    int i;
 
-    if (name->len > MAX_NAME_LEN * sizeof(WCHAR))
-    {
-        set_error( STATUS_INVALID_PARAMETER );
-        return NULL;
-    }
-    if (parent->last_subkey + 1 == parent->nb_subkeys)
-    {
-        /* need to grow the array */
-        if (!grow_subkeys( parent )) return NULL;
-    }
-    if ((key = alloc_key( name, modif )) != NULL)
-    {
-        key->obj.name->parent = &parent->obj;
-        for (i = ++parent->last_subkey; i > index; i--)
-            parent->subkeys[i] = parent->subkeys[i-1];
-        parent->subkeys[index] = key;
-        if (is_wow6432node( key->obj.name->name, key->obj.name->len ) &&
-            !is_wow6432node( parent->obj.name->name, parent->obj.name->len ))
-            parent->wow6432node = key;
-    }
-    return key;
+    if (!(key = alloc_key( name, modif ))) return NULL;
+    if (key_link_name( &key->obj, key->obj.name, &parent->obj )) return key;
+    release_object( key );
+    return NULL;
 }
 
 /* return the wow64 variant of the key, or the key itself if none */
@@ -850,7 +867,7 @@ static struct key *create_key( struct key *key, const struct unicode_str *name,
         return NULL;
     }
     make_dirty( key );
-    if (!(key = alloc_subkey( key, &token, index, current_time ))) return NULL;
+    if (!(key = alloc_subkey( key, &token, current_time ))) return NULL;
 
     if (options & REG_OPTION_CREATE_LINK) key->flags |= KEY_SYMLINK;
     if (options & REG_OPTION_VOLATILE) key->flags |= KEY_VOLATILE;
@@ -895,14 +912,13 @@ static struct key *create_key_recursive( struct key *key, const struct unicode_s
 
     if (token.len)
     {
-        if (!(key = alloc_subkey( key, &token, index, modif ))) return NULL;
+        if (!(key = alloc_subkey( key, &token, modif ))) return NULL;
         base = key;
         for (;;)
         {
             get_path_token( name, &token );
             if (!token.len) break;
-            /* we know the index is always 0 in a new key */
-            if (!(key = alloc_subkey( key, &token, 0, modif )))
+            if (!(key = alloc_subkey( key, &token, modif )))
             {
                 unlink_named_object( &base->obj );
                 return NULL;
@@ -1076,11 +1092,11 @@ static int rename_key( struct key *key, const struct unicode_str *new_name )
 /* delete a key and its values */
 static int delete_key( struct key *key, int recurse )
 {
-    struct key *parent = get_parent( key );
+    struct key *parent;
 
     if (key->flags & KEY_DELETED) return 1;
 
-    if (!parent)
+    if (!(parent = get_parent( key )))
     {
         set_error( STATUS_ACCESS_DENIED );
         return 0;




More information about the wine-cvs mailing list