[PATCH v2 1/2] server: Use normal key path handling also for the '\Registry' prefix.

Dmitry Timoshkov dmitry at baikal.ru
Wed Jan 26 10:18:42 CST 2022


Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
---
 dlls/ntdll/tests/reg.c |  3 ---
 server/registry.c      | 50 ++++++++++++------------------------------
 2 files changed, 14 insertions(+), 39 deletions(-)

diff --git a/dlls/ntdll/tests/reg.c b/dlls/ntdll/tests/reg.c
index 91b752ac069..445c05a02e1 100644
--- a/dlls/ntdll/tests/reg.c
+++ b/dlls/ntdll/tests/reg.c
@@ -386,7 +386,6 @@ todo_wine
     key = (HANDLE)0xdeadbeef;
     status = pNtOpenKey(&key, KEY_READ, &attr);
     todo_wine ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtOpenKey Failed: 0x%08x\n", status);
-todo_wine
     ok(!key, "key = %p\n", key);
     pRtlFreeUnicodeString( &str );
 
@@ -417,7 +416,6 @@ todo_wine
 
     pRtlCreateUnicodeStringFromAsciiz( &str, "\\Registry" );
     status = pNtOpenKey(&key, KEY_READ, &attr);
-    todo_wine
     ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08x\n", status );
     pNtClose( key );
     pRtlFreeUnicodeString( &str );
@@ -569,7 +567,6 @@ static void test_NtCreateKey(void)
 
     pRtlCreateUnicodeStringFromAsciiz( &str, "\\Registry" );
     status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 );
-    todo_wine
     ok( status == STATUS_SUCCESS || status == STATUS_ACCESS_DENIED,
         "NtCreateKey failed: 0x%08x\n", status );
     if (!status) pNtClose( subkey );
diff --git a/server/registry.c b/server/registry.c
index 93e8a309593..ebf8795432b 100644
--- a/server/registry.c
+++ b/server/registry.c
@@ -127,7 +127,7 @@ static const timeout_t save_period = 30 * -TICKS_PER_SEC;  /* delay between peri
 static struct timeout_user *save_timeout_user;  /* saving timer */
 static enum prefix_type { PREFIX_UNKNOWN, PREFIX_32BIT, PREFIX_64BIT } prefix_type;
 
-static const WCHAR root_name[] = { '\\','R','e','g','i','s','t','r','y','\\' };
+static const WCHAR root_name[] = { '\\','R','e','g','i','s','t','r','y' };
 static const WCHAR wow6432node[] = {'W','o','w','6','4','3','2','N','o','d','e'};
 static const WCHAR symlink_value[] = {'S','y','m','b','o','l','i','c','L','i','n','k','V','a','l','u','e'};
 static const struct unicode_str symlink_str = { symlink_value, sizeof(symlink_value) };
@@ -403,7 +403,7 @@ 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);
+    data_size_t len = 0;
     char *ret;
 
     if (key->flags & KEY_DELETED)
@@ -423,7 +423,6 @@ static WCHAR *key_get_full_name( struct object *obj, data_size_t *ret_len )
         len -= key->namelen + sizeof(WCHAR);
         memcpy( ret + len, &backslash, sizeof(WCHAR) );
     }
-    memcpy( ret, root_name, sizeof(root_name) - sizeof(WCHAR) );
     return (WCHAR *)ret;
 }
 
@@ -466,16 +465,10 @@ static void key_destroy( struct object *obj )
 }
 
 /* get the request vararg as registry path */
-static inline void get_req_path( struct unicode_str *str, int skip_root )
+static inline void get_req_path( struct unicode_str *str )
 {
     str->str = get_req_data();
     str->len = (get_req_data_size() / sizeof(WCHAR)) * sizeof(WCHAR);
-
-    if (skip_root && str->len >= sizeof(root_name) && !memicmp_strW( str->str, root_name, sizeof(root_name) ))
-    {
-        str->str += ARRAY_SIZE( root_name );
-        str->len -= sizeof(root_name);
-    }
 }
 
 /* return the next token in a given path */
@@ -486,19 +479,22 @@ static struct unicode_str *get_path_token( const struct unicode_str *path, struc
 
     if (!token->str)  /* first time */
     {
-        /* path cannot start with a backslash */
+        /* if path starts with a backslash it must be the Registry root */
         if (len && path->str[0] == '\\')
         {
-            set_error( STATUS_OBJECT_PATH_INVALID );
-            return NULL;
+            if (path->len < sizeof(root_name) || memicmp_strW( path->str, root_name, sizeof(root_name) ))
+            {
+                set_error( STATUS_OBJECT_PATH_INVALID );
+                return NULL;
+            }
         }
     }
     else
     {
         i = token->str - path->str;
         i += token->len / sizeof(WCHAR);
-        while (i < len && path->str[i] == '\\') i++;
     }
+    while (i < len && path->str[i] == '\\') i++;
     token->str = path->str + i;
     while (i < len && path->str[i] != '\\') i++;
     token->len = (path->str + i - token->str) * sizeof(WCHAR);
@@ -722,10 +718,6 @@ static struct key *follow_symlink( struct key *key, int iteration )
 
     path.str = value->data;
     path.len = (value->len / sizeof(WCHAR)) * sizeof(WCHAR);
-    if (path.len <= sizeof(root_name)) return NULL;
-    if (memicmp_strW( path.str, root_name, sizeof(root_name) )) return NULL;
-    path.str += ARRAY_SIZE( root_name );
-    path.len -= sizeof(root_name);
 
     key = root_key;
     token.str = NULL;
@@ -1834,8 +1826,8 @@ static void init_supported_machines(void)
 /* registry initialisation */
 void init_registry(void)
 {
-    static const WCHAR HKLM[] = { 'M','a','c','h','i','n','e' };
-    static const WCHAR HKU_default[] = { 'U','s','e','r','\\','.','D','e','f','a','u','l','t' };
+    static const WCHAR HKLM[] = { '\\','R','e','g','i','s','t','r','y','\\','M','a','c','h','i','n','e' };
+    static const WCHAR HKU_default[] = { '\\','R','e','g','i','s','t','r','y','\\','U','s','e','r','\\','.','D','e','f','a','u','l','t' };
     static const WCHAR classes_i386[] = {'S','o','f','t','w','a','r','e','\\',
                                          'C','l','a','s','s','e','s','\\',
                                          'W','o','w','6','4','3','2','N','o','d','e'};
@@ -2143,13 +2135,6 @@ DECL_HANDLER(create_key)
     class.str = get_req_data_after_objattr( objattr, &class.len );
     class.len = (class.len / sizeof(WCHAR)) * sizeof(WCHAR);
 
-    if (!objattr->rootdir && name.len >= sizeof(root_name) &&
-        !memicmp_strW( name.str, root_name, sizeof(root_name) ))
-    {
-        name.str += ARRAY_SIZE( root_name );
-        name.len -= sizeof(root_name);
-    }
-
     /* NOTE: no access rights are required from the parent handle to create a key */
     if ((parent = get_parent_hkey_obj( objattr->rootdir )))
     {
@@ -2176,7 +2161,7 @@ DECL_HANDLER(open_key)
     /* NOTE: no access rights are required to open the parent key, only the child key */
     if ((parent = get_parent_hkey_obj( req->parent )))
     {
-        get_req_path( &name, !req->parent );
+        get_req_path( &name );
         if ((key = open_key( parent, &name, access, req->attributes )))
         {
             reply->hkey = alloc_handle( current->process, key, access, req->attributes );
@@ -2301,13 +2286,6 @@ DECL_HANDLER(load_registry)
         return;
     }
 
-    if (!objattr->rootdir && name.len >= sizeof(root_name) &&
-        !memicmp_strW( name.str, root_name, sizeof(root_name) ))
-    {
-        name.str += ARRAY_SIZE( root_name );
-        name.len -= sizeof(root_name);
-    }
-
     if ((parent = get_parent_hkey_obj( objattr->rootdir )))
     {
         int dummy;
@@ -2336,7 +2314,7 @@ DECL_HANDLER(unload_registry)
 
     if ((parent = get_parent_hkey_obj( req->parent )))
     {
-        get_req_path( &name, !req->parent );
+        get_req_path( &name );
         if ((key = open_key( parent, &name, access, req->attributes )))
         {
             if (key->obj.handle_count)
-- 
2.34.1




More information about the wine-devel mailing list