From 21044c6319f70585b9a0fe2232d71f941b8e4fdb Mon Sep 17 00:00:00 2001
From: Alexandre Julliard <julliard@winehq.org>
Date: Tue, 10 Apr 2001 21:18:17 +0000
Subject: [PATCH] Fixed handling of \\Registry prefix.

---
 dlls/ntdll/reg.c  | 18 ------------------
 server/registry.c | 20 +++++++++++---------
 2 files changed, 11 insertions(+), 27 deletions(-)

diff --git a/dlls/ntdll/reg.c b/dlls/ntdll/reg.c
index 3a67bd8b147..52b33eebc6c 100644
--- a/dlls/ntdll/reg.c
+++ b/dlls/ntdll/reg.c
@@ -22,28 +22,10 @@
 
 DEFAULT_DEBUG_CHANNEL(reg);
 
-static const WCHAR root_name[] = { '\\','R','e','g','i','s','t','r','y','\\',0 };
-static const UNICODE_STRING root_path =
-{
-    sizeof(root_name)-sizeof(WCHAR),  /* Length */
-    sizeof(root_name),                /* MaximumLength */
-    (LPWSTR)root_name                 /* Buffer */
-};
-
 /* maximum length of a key/value name in bytes (without terminating null) */
 #define MAX_NAME_LENGTH ((MAX_PATH-1) * sizeof(WCHAR))
 
 
-/* copy a key name into the request buffer */
-static inline NTSTATUS copy_nameU( LPWSTR Dest, const UNICODE_STRING *name, UINT max )
-{
-    if (name->Length >= max) return STATUS_BUFFER_OVERFLOW;
-    if (name->Length) memcpy( Dest, name->Buffer, name->Length );
-    Dest[name->Length / sizeof(WCHAR)] = 0;
-    return STATUS_SUCCESS;
-}
-
-
 /******************************************************************************
  * NtCreateKey [NTDLL]
  * ZwCreateKey
diff --git a/server/registry.c b/server/registry.c
index f6a3f5e4eb1..961f441606a 100644
--- a/server/registry.c
+++ b/server/registry.c
@@ -287,9 +287,10 @@ static void key_destroy( struct object *obj )
 
 /* duplicate a key path from the request buffer */
 /* returns a pointer to a static buffer, so only useable once per request */
-static WCHAR *copy_path( const WCHAR *path, size_t len )
+static WCHAR *copy_path( const WCHAR *path, size_t len, int skip_root )
 {
     static WCHAR buffer[MAX_PATH+1];
+    static const WCHAR root_name[] = { '\\','R','e','g','i','s','t','r','y','\\',0 };
 
     if (len > sizeof(buffer)-sizeof(buffer[0]))
     {
@@ -298,11 +299,12 @@ static WCHAR *copy_path( const WCHAR *path, size_t len )
     }
     memcpy( buffer, path, len );
     buffer[len / sizeof(WCHAR)] = 0;
+    if (skip_root && !strncmpiW( buffer, root_name, 10 )) return buffer + 10;
     return buffer;
 }
 
 /* copy a path from the request buffer, in cases where the length is stored in front of the path */
-static WCHAR *copy_req_path( void *req, size_t *len )
+static WCHAR *copy_req_path( void *req, size_t *len, int skip_root )
 {
     const WCHAR *name_ptr = get_req_data(req);
     if ((*len = sizeof(WCHAR) + *name_ptr++) > get_req_data_size(req))
@@ -311,7 +313,7 @@ static WCHAR *copy_req_path( void *req, size_t *len )
                               *len, get_req_data_size(req) );
         return NULL;
     }
-    return copy_path( name_ptr, *len - sizeof(WCHAR) );
+    return copy_path( name_ptr, *len - sizeof(WCHAR), skip_root );
 }
 
 /* return the next token in a given path */
@@ -1127,7 +1129,7 @@ static struct key *load_key( struct key *base, const char *buffer, unsigned int
         /* empty key name, return base key */
         return (struct key *)grab_object( base );
     }
-    if (!(name = copy_path( p, len - ((char *)p - info->tmp) )))
+    if (!(name = copy_path( p, len - ((char *)p - info->tmp), 0 )))
     {
         file_read_error( "Key is too long", info );
         return NULL;
@@ -1385,7 +1387,7 @@ void init_registry(void)
         int dummy;
 
         /* create the config key */
-        if (!(key = create_key( root_key, copy_path( config_name, sizeof(config_name) ),
+        if (!(key = create_key( root_key, copy_path( config_name, sizeof(config_name), 0 ),
                                 NULL, 0, time(NULL), &dummy )))
             fatal_error( "could not create config key\n" );
         key->flags |= KEY_VOLATILE;
@@ -1587,7 +1589,7 @@ DECL_HANDLER(create_key)
 
     if (access & MAXIMUM_ALLOWED) access = KEY_ALL_ACCESS;  /* FIXME: needs general solution */
     req->hkey = 0;
-    if (!(name = copy_req_path( req, &len ))) return;
+    if (!(name = copy_req_path( req, &len, !req->parent ))) return;
     if ((parent = get_hkey_obj( req->parent, 0 /*FIXME*/ )))
     {
         if (len == get_req_data_size(req))  /* no class specified */
@@ -1624,7 +1626,7 @@ DECL_HANDLER(open_key)
     req->hkey = 0;
     if ((parent = get_hkey_obj( req->parent, 0 /*FIXME*/ )))
     {
-        WCHAR *name = copy_path( get_req_data(req), get_req_data_size(req) );
+        WCHAR *name = copy_path( get_req_data(req), get_req_data_size(req), !req->parent );
         if (name && (key = open_key( parent, name )))
         {
             req->hkey = alloc_handle( current->process, key, access, 0 );
@@ -1668,7 +1670,7 @@ DECL_HANDLER(set_key_value)
     WCHAR *name;
     size_t len;
 
-    if (!(name = copy_req_path( req, &len ))) return;
+    if (!(name = copy_req_path( req, &len, 0 ))) return;
     if ((key = get_hkey_obj( req->hkey, KEY_SET_VALUE )))
     {
         size_t datalen = get_req_data_size(req) - len;
@@ -1687,7 +1689,7 @@ DECL_HANDLER(get_key_value)
     size_t len = 0, tmp;
 
     req->len = 0;
-    if (!(name = copy_req_path( req, &tmp ))) return;
+    if (!(name = copy_req_path( req, &tmp, 0 ))) return;
     if ((key = get_hkey_obj( req->hkey, KEY_QUERY_VALUE )))
     {
         len = get_value( key, name, req->offset, get_req_data_size(req),
-- 
GitLab