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

Alexandre Julliard julliard at winehq.org
Wed Jul 6 16:55:53 CDT 2022


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Jul  6 15:53:05 2022 +0200

server: Implement unlink_name() for registry keys.

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

---

 dlls/ntdll/tests/reg.c |   2 +-
 server/registry.c      | 104 ++++++++++++++++++++++++-------------------------
 2 files changed, 51 insertions(+), 55 deletions(-)

diff --git a/dlls/ntdll/tests/reg.c b/dlls/ntdll/tests/reg.c
index 54e9b10e530..5e141b1370d 100644
--- a/dlls/ntdll/tests/reg.c
+++ b/dlls/ntdll/tests/reg.c
@@ -940,7 +940,7 @@ static void test_NtDeleteKey(void)
     ok(status == STATUS_KEY_DELETED, "got %#lx\n", status);
 
     status = pNtDeleteKey(hkey);
-    todo_wine ok(!status, "got %#lx\n", status);
+    ok(!status, "got %#lx\n", status);
 
     RtlInitUnicodeString(&string, L"subkey");
     InitializeObjectAttributes(&attr, &string, OBJ_CASE_INSENSITIVE, hkey, NULL);
diff --git a/server/registry.c b/server/registry.c
index 985c124179a..b32b4eb08a0 100644
--- a/server/registry.c
+++ b/server/registry.c
@@ -434,6 +434,37 @@ static WCHAR *key_get_full_name( struct object *obj, data_size_t *ret_len )
 
 static void key_unlink_name( struct object *obj, struct object_name *name )
 {
+    struct key *key = (struct key *)obj;
+    struct key *parent = (struct key *)name->parent;
+    int i, nb_subkeys;
+
+    if (!parent) return;
+
+    if (parent->obj.ops != &key_ops)
+    {
+        default_unlink_name( obj, name );
+        return;
+    }
+
+    for (i = 0; i <= parent->last_subkey; i++) if (parent->subkeys[i] == key) break;
+    assert( i <= parent->last_subkey );
+    for ( ; i < parent->last_subkey; i++) parent->subkeys[i] = parent->subkeys[i + 1];
+    parent->last_subkey--;
+    name->parent = NULL;
+    if (parent->wow6432node == key) parent->wow6432node = NULL;
+    release_object( key );
+
+    /* try to shrink the array */
+    nb_subkeys = parent->nb_subkeys;
+    if (nb_subkeys > MIN_SUBKEYS && parent->last_subkey < nb_subkeys / 2)
+    {
+        struct key **new_subkeys;
+        nb_subkeys -= nb_subkeys / 3;  /* shrink by 33% */
+        if (nb_subkeys < MIN_SUBKEYS) nb_subkeys = MIN_SUBKEYS;
+        if (!(new_subkeys = realloc( parent->subkeys, nb_subkeys * sizeof(*new_subkeys) ))) return;
+        parent->subkeys = new_subkeys;
+        parent->nb_subkeys = nb_subkeys;
+    }
 }
 
 /* close the notification associated with a handle */
@@ -648,36 +679,6 @@ static struct key *alloc_subkey( struct key *parent, const struct unicode_str *n
     return key;
 }
 
-/* free a subkey of a given key */
-static void free_subkey( struct key *parent, int index )
-{
-    struct key *key;
-    int i, nb_subkeys;
-
-    assert( index >= 0 );
-    assert( index <= parent->last_subkey );
-
-    key = parent->subkeys[index];
-    for (i = index; i < parent->last_subkey; i++) parent->subkeys[i] = parent->subkeys[i + 1];
-    parent->last_subkey--;
-    key->flags |= KEY_DELETED;
-    key->obj.name->parent = NULL;
-    if (parent->wow6432node == key) parent->wow6432node = NULL;
-    release_object( key );
-
-    /* try to shrink the array */
-    nb_subkeys = parent->nb_subkeys;
-    if (nb_subkeys > MIN_SUBKEYS && parent->last_subkey < nb_subkeys / 2)
-    {
-        struct key **new_subkeys;
-        nb_subkeys -= nb_subkeys / 3;  /* shrink by 33% */
-        if (nb_subkeys < MIN_SUBKEYS) nb_subkeys = MIN_SUBKEYS;
-        if (!(new_subkeys = realloc( parent->subkeys, nb_subkeys * sizeof(*new_subkeys) ))) return;
-        parent->subkeys = new_subkeys;
-        parent->nb_subkeys = nb_subkeys;
-    }
-}
-
 /* find the named child of a given key and return its index */
 static struct key *find_subkey( const struct key *key, const struct unicode_str *name, int *index )
 {
@@ -903,7 +904,7 @@ static struct key *create_key_recursive( struct key *key, const struct unicode_s
             /* we know the index is always 0 in a new key */
             if (!(key = alloc_subkey( key, &token, 0, modif )))
             {
-                free_subkey( base, index );
+                unlink_named_object( &base->obj );
                 return NULL;
             }
         }
@@ -1075,42 +1076,37 @@ 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 )
 {
-    int index;
     struct key *parent = get_parent( key );
 
-    /* must find parent and index */
-    if (key == root_key)
+    if (key->flags & KEY_DELETED) return 1;
+
+    if (!parent)
     {
         set_error( STATUS_ACCESS_DENIED );
-        return -1;
+        return 0;
     }
-    assert( parent );
-
     if (key->flags & KEY_PREDEF)
     {
         set_error( STATUS_INVALID_HANDLE );
-        return -1;
+        return 0;
     }
 
-    while (recurse && (key->last_subkey>=0))
-        if (0 > delete_key(key->subkeys[key->last_subkey], 1))
-            return -1;
-
-    for (index = 0; index <= parent->last_subkey; index++)
-        if (parent->subkeys[index] == key) break;
-    assert( index <= parent->last_subkey );
-
-    /* we can only delete a key that has no subkeys */
-    if (key->last_subkey >= 0)
+    if (recurse)
+    {
+        while (key->last_subkey >= 0)
+            if (!delete_key( key->subkeys[key->last_subkey], 1 )) return 0;
+    }
+    else if (key->last_subkey >= 0)  /* we can only delete a key that has no subkeys */
     {
         set_error( STATUS_ACCESS_DENIED );
-        return -1;
+        return 0;
     }
 
     if (debug_level > 1) dump_operation( key, NULL, "Delete" );
-    free_subkey( parent, index );
+    key->flags |= KEY_DELETED;
+    unlink_named_object( &key->obj );
     touch_key( parent, REG_NOTIFY_CHANGE_NAME );
-    return 0;
+    return 1;
 }
 
 /* try to grow the array of values; return 1 if OK, 0 on error */
@@ -2254,11 +2250,11 @@ DECL_HANDLER(open_key)
 /* delete a registry key */
 DECL_HANDLER(delete_key)
 {
-    struct key *key;
+    struct key *key = (struct key *)get_handle_obj( current->process, req->hkey, DELETE, &key_ops );
 
-    if ((key = get_hkey_obj( req->hkey, DELETE )))
+    if (key)
     {
-        delete_key( key, 0);
+        delete_key( key, 0 );
         release_object( key );
     }
 }




More information about the wine-cvs mailing list