Alexandre Julliard : server: Disallow all operations on deleted registry keys.

Alexandre Julliard julliard at winehq.org
Fri Apr 2 10:17:11 CDT 2010


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri Apr  2 12:43:31 2010 +0200

server: Disallow all operations on deleted registry keys.

---

 dlls/advapi32/tests/registry.c |   19 +++++++++++++++----
 server/registry.c              |   33 +++++++++++++--------------------
 2 files changed, 28 insertions(+), 24 deletions(-)

diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c
index ea036e8..30dda7e 100644
--- a/dlls/advapi32/tests/registry.c
+++ b/dlls/advapi32/tests/registry.c
@@ -1924,16 +1924,24 @@ static void test_deleted_key(void)
 
     delete_key( hkey_main );
 
-    val_count = 20;
+    val_count = sizeof(value);
     type = 0;
     res = RegEnumValueA( hkey, 0, value, &val_count, NULL, &type, 0, 0 );
-    todo_wine ok(res == ERROR_KEY_DELETED, "expect ERROR_KEY_DELETED, got %i\n", res);
+    ok(res == ERROR_KEY_DELETED, "expect ERROR_KEY_DELETED, got %i\n", res);
+
+    res = RegEnumKeyA( hkey, 0, value, sizeof(value) );
+    ok(res == ERROR_KEY_DELETED, "expect ERROR_KEY_DELETED, got %i\n", res);
+
+    val_count = sizeof(value);
+    type = 0;
+    res = RegQueryValueExA( hkey, "test", NULL, &type, (BYTE *)value, &val_count );
+    ok(res == ERROR_KEY_DELETED, "expect ERROR_KEY_DELETED, got %i\n", res);
 
     res = RegSetValueExA( hkey, "test", 0, REG_SZ, (const BYTE*)"value", 6);
-    todo_wine ok(res == ERROR_KEY_DELETED, "expect ERROR_KEY_DELETED, got %i\n", res);
+    ok(res == ERROR_KEY_DELETED, "expect ERROR_KEY_DELETED, got %i\n", res);
 
     res = RegOpenKeyA( hkey, "test", &hkey2 );
-    todo_wine ok(res == ERROR_KEY_DELETED, "expect ERROR_KEY_DELETED, got %i\n", res);
+    ok(res == ERROR_KEY_DELETED, "expect ERROR_KEY_DELETED, got %i\n", res);
     if (res == 0)
         RegCloseKey( hkey2 );
 
@@ -1942,6 +1950,9 @@ static void test_deleted_key(void)
     if (res == 0)
         RegCloseKey( hkey2 );
 
+    res = RegFlushKey( hkey );
+    ok(res == ERROR_KEY_DELETED, "expect ERROR_KEY_DELETED, got %i\n", res);
+
     RegCloseKey( hkey );
 
     setup_main_key();
diff --git a/server/registry.c b/server/registry.c
index 574f2e4..f4dbf8e 100644
--- a/server/registry.c
+++ b/server/registry.c
@@ -712,12 +712,6 @@ static struct key *create_key( struct key *key, const struct unicode_str *name,
     int index;
     struct unicode_str token, next;
 
-    if (key->flags & KEY_DELETED) /* we cannot create a subkey under a deleted key */
-    {
-        set_error( STATUS_KEY_DELETED );
-        return NULL;
-    }
-
     *created = 0;
     if (!(key = open_key_prefix( key, name, access, &token, &index ))) return NULL;
 
@@ -902,7 +896,7 @@ static void enum_key( const struct key *key, int index, int info_class,
 static int delete_key( struct key *key, int recurse )
 {
     int index;
-    struct key *parent;
+    struct key *parent = key->parent;
 
     /* must find parent and index */
     if (key == root_key)
@@ -910,11 +904,7 @@ static int delete_key( struct key *key, int recurse )
         set_error( STATUS_ACCESS_DENIED );
         return -1;
     }
-    if (!(parent = key->parent) || (key->flags & KEY_DELETED))
-    {
-        set_error( STATUS_KEY_DELETED );
-        return -1;
-    }
+    assert( parent );
 
     while (recurse && (key->last_subkey>=0))
         if (0 > delete_key(key->subkeys[key->last_subkey], 1))
@@ -1165,16 +1155,24 @@ static void delete_value( struct key *key, const struct unicode_str *name )
 }
 
 /* get the registry key corresponding to an hkey handle */
-static inline struct key *get_hkey_obj( obj_handle_t hkey, unsigned int access )
+static struct key *get_hkey_obj( obj_handle_t hkey, unsigned int access )
 {
-    return (struct key *)get_handle_obj( current->process, hkey, access, &key_ops );
+    struct key *key = (struct key *)get_handle_obj( current->process, hkey, access, &key_ops );
+
+    if (key && key->flags & KEY_DELETED)
+    {
+        set_error( STATUS_KEY_DELETED );
+        release_object( key );
+        key = NULL;
+    }
+    return key;
 }
 
 /* get the registry key corresponding to a parent key handle */
 static inline struct key *get_parent_hkey_obj( obj_handle_t hkey )
 {
     if (!hkey) return (struct key *)grab_object( root_key );
-    return (struct key *)get_handle_obj( current->process, hkey, 0, &key_ops );
+    return get_hkey_obj( hkey, 0 );
 }
 
 /* read a line from the input file */
@@ -1698,11 +1696,6 @@ static void save_registry( struct key *key, obj_handle_t handle )
     struct file *file;
     int fd;
 
-    if (key->flags & KEY_DELETED)
-    {
-        set_error( STATUS_KEY_DELETED );
-        return;
-    }
     if (!(file = get_file_obj( current->process, handle, FILE_WRITE_DATA ))) return;
     fd = dup( get_file_unix_fd( file ) );
     release_object( file );




More information about the wine-cvs mailing list