Alexandre Julliard : server: Pass full object attributes in the create_key request.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Jan 19 10:50:28 CST 2016


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Jan 19 15:03:37 2016 +0900

server: Pass full object attributes in the create_key request.

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

---

 dlls/ntdll/reg.c               | 11 +++++++----
 include/wine/server_protocol.h |  8 +++-----
 server/protocol.def            |  5 +----
 server/registry.c              | 37 +++++++++++++++++++------------------
 server/request.h               |  9 +++------
 server/trace.c                 |  7 ++-----
 6 files changed, 35 insertions(+), 42 deletions(-)

diff --git a/dlls/ntdll/reg.c b/dlls/ntdll/reg.c
index be95a2a..ed9d155 100644
--- a/dlls/ntdll/reg.c
+++ b/dlls/ntdll/reg.c
@@ -56,6 +56,8 @@ NTSTATUS WINAPI NtCreateKey( PHANDLE retkey, ACCESS_MASK access, const OBJECT_AT
                              PULONG dispos )
 {
     NTSTATUS ret;
+    data_size_t len;
+    struct object_attributes *objattr;
 
     if (!retkey || !attr) return STATUS_ACCESS_VIOLATION;
     if (attr->Length > sizeof(OBJECT_ATTRIBUTES)) return STATUS_INVALID_PARAMETER;
@@ -64,14 +66,13 @@ NTSTATUS WINAPI NtCreateKey( PHANDLE retkey, ACCESS_MASK access, const OBJECT_AT
     TRACE( "(%p,%s,%s,%x,%x,%p)\n", attr->RootDirectory, debugstr_us(attr->ObjectName),
            debugstr_us(class), options, access, retkey );
 
+    if ((ret = alloc_object_attributes( attr, &objattr, &len ))) return ret;
+
     SERVER_START_REQ( create_key )
     {
-        req->parent     = wine_server_obj_handle( attr->RootDirectory );
         req->access     = access;
-        req->attributes = attr->Attributes;
         req->options    = options;
-        req->namelen    = attr->ObjectName->Length;
-        wine_server_add_data( req, attr->ObjectName->Buffer, attr->ObjectName->Length );
+        wine_server_add_data( req, objattr, len );
         if (class) wine_server_add_data( req, class->Buffer, class->Length );
         if (!(ret = wine_server_call( req )))
         {
@@ -80,7 +81,9 @@ NTSTATUS WINAPI NtCreateKey( PHANDLE retkey, ACCESS_MASK access, const OBJECT_AT
         }
     }
     SERVER_END_REQ;
+
     TRACE("<- %p\n", *retkey);
+    RtlFreeHeap( GetProcessHeap(), 0, objattr );
     return ret;
 }
 
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 19ea2fc..caa2dc9 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -2393,13 +2393,11 @@ struct write_process_memory_reply
 struct create_key_request
 {
     struct request_header __header;
-    obj_handle_t parent;
     unsigned int access;
-    unsigned int attributes;
     unsigned int options;
-    data_size_t  namelen;
-    /* VARARG(name,unicode_str,namelen); */
+    /* VARARG(objattr,object_attributes); */
     /* VARARG(class,unicode_str); */
+    char __pad_20[4];
 };
 struct create_key_reply
 {
@@ -6159,6 +6157,6 @@ union generic_reply
     struct terminate_job_reply terminate_job_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 497
+#define SERVER_PROTOCOL_VERSION 498
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/protocol.def b/server/protocol.def
index 390651d..a391c88 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -1820,12 +1820,9 @@ enum char_info_mode
 
 /* Create a registry key */
 @REQ(create_key)
-    obj_handle_t parent;       /* handle to the parent key */
     unsigned int access;       /* desired access rights */
-    unsigned int attributes;   /* object attributes */
     unsigned int options;      /* creation options */
-    data_size_t  namelen;      /* length of key name in bytes */
-    VARARG(name,unicode_str,namelen);  /* key name */
+    VARARG(objattr,object_attributes); /* object attributes */
     VARARG(class,unicode_str);         /* class name */
 @REPLY
     obj_handle_t hkey;         /* handle to the created key */
diff --git a/server/registry.c b/server/registry.c
index a3c1390..adf2892 100644
--- a/server/registry.c
+++ b/server/registry.c
@@ -759,7 +759,8 @@ static struct key *open_key( struct key *key, const struct unicode_str *name, un
 /* create a subkey */
 static struct key *create_key( struct key *key, const struct unicode_str *name,
                                const struct unicode_str *class, unsigned int options,
-                               unsigned int access, unsigned int attributes, int *created )
+                               unsigned int access, unsigned int attributes,
+                               const struct security_descriptor *sd, int *created )
 {
     int index;
     struct unicode_str token, next;
@@ -807,6 +808,9 @@ static struct key *create_key( struct key *key, const struct unicode_str *name,
     if (options & REG_OPTION_VOLATILE) key->flags |= KEY_VOLATILE;
     else key->flags |= KEY_DIRTY;
 
+    if (sd) default_set_sd( &key->obj, sd, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
+                            DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION );
+
     if (debug_level > 1) dump_operation( key, NULL, "Create" );
     if (class && class->len)
     {
@@ -2021,33 +2025,30 @@ DECL_HANDLER(create_key)
     struct key *key = NULL, *parent;
     struct unicode_str name, class;
     unsigned int access = req->access;
+    const struct security_descriptor *sd;
+    const struct object_attributes *objattr = get_req_object_attributes( &sd, &name );
+
+    if (!objattr) return;
 
     if (!is_wow64_thread( current )) access = (access & ~KEY_WOW64_32KEY) | KEY_WOW64_64KEY;
 
-    reply->hkey = 0;
+    class.str = get_req_data_after_objattr( objattr, &class.len );
+    class.len = (class.len / sizeof(WCHAR)) * sizeof(WCHAR);
 
-    if (req->namelen > get_req_data_size())
-    {
-        set_error( STATUS_INVALID_PARAMETER );
-        return;
-    }
-    class.str = (const WCHAR *)get_req_data() + req->namelen / sizeof(WCHAR);
-    class.len = ((get_req_data_size() - req->namelen) / sizeof(WCHAR)) * sizeof(WCHAR);
-    get_req_path( &name, !req->parent );
-    if (name.str > class.str)
+    if (!objattr->rootdir && name.len >= sizeof(root_name) &&
+        !memicmpW( name.str, root_name, sizeof(root_name)/sizeof(WCHAR) ))
     {
-        set_error( STATUS_INVALID_PARAMETER );
-        return;
+        name.str += sizeof(root_name)/sizeof(WCHAR);
+        name.len -= sizeof(root_name);
     }
-    name.len = (class.str - name.str) * sizeof(WCHAR);
 
     /* NOTE: no access rights are required from the parent handle to create a key */
-    if ((parent = get_parent_hkey_obj( req->parent )))
+    if ((parent = get_parent_hkey_obj( objattr->rootdir )))
     {
         if ((key = create_key( parent, &name, &class, req->options, access,
-                               req->attributes, &reply->created )))
+                               objattr->attributes, sd, &reply->created )))
         {
-            reply->hkey = alloc_handle( current->process, key, access, req->attributes );
+            reply->hkey = alloc_handle( current->process, key, access, objattr->attributes );
             release_object( key );
         }
         release_object( parent );
@@ -2194,7 +2195,7 @@ DECL_HANDLER(load_registry)
     {
         int dummy;
         get_req_path( &name, !req->hkey );
-        if ((key = create_key( parent, &name, NULL, 0, KEY_WOW64_64KEY, 0, &dummy )))
+        if ((key = create_key( parent, &name, NULL, 0, KEY_WOW64_64KEY, 0, NULL, &dummy )))
         {
             load_registry( key, req->file );
             release_object( key );
diff --git a/server/request.h b/server/request.h
index caaa30e..87cae73 100644
--- a/server/request.h
+++ b/server/request.h
@@ -1287,12 +1287,9 @@ C_ASSERT( sizeof(struct read_process_memory_reply) == 8 );
 C_ASSERT( FIELD_OFFSET(struct write_process_memory_request, handle) == 12 );
 C_ASSERT( FIELD_OFFSET(struct write_process_memory_request, addr) == 16 );
 C_ASSERT( sizeof(struct write_process_memory_request) == 24 );
-C_ASSERT( FIELD_OFFSET(struct create_key_request, parent) == 12 );
-C_ASSERT( FIELD_OFFSET(struct create_key_request, access) == 16 );
-C_ASSERT( FIELD_OFFSET(struct create_key_request, attributes) == 20 );
-C_ASSERT( FIELD_OFFSET(struct create_key_request, options) == 24 );
-C_ASSERT( FIELD_OFFSET(struct create_key_request, namelen) == 28 );
-C_ASSERT( sizeof(struct create_key_request) == 32 );
+C_ASSERT( FIELD_OFFSET(struct create_key_request, access) == 12 );
+C_ASSERT( FIELD_OFFSET(struct create_key_request, options) == 16 );
+C_ASSERT( sizeof(struct create_key_request) == 24 );
 C_ASSERT( FIELD_OFFSET(struct create_key_reply, hkey) == 8 );
 C_ASSERT( FIELD_OFFSET(struct create_key_reply, created) == 12 );
 C_ASSERT( sizeof(struct create_key_reply) == 16 );
diff --git a/server/trace.c b/server/trace.c
index edbc8c9..89ecdfb 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -2308,12 +2308,9 @@ static void dump_write_process_memory_request( const struct write_process_memory
 
 static void dump_create_key_request( const struct create_key_request *req )
 {
-    fprintf( stderr, " parent=%04x", req->parent );
-    fprintf( stderr, ", access=%08x", req->access );
-    fprintf( stderr, ", attributes=%08x", req->attributes );
+    fprintf( stderr, " access=%08x", req->access );
     fprintf( stderr, ", options=%08x", req->options );
-    fprintf( stderr, ", namelen=%u", req->namelen );
-    dump_varargs_unicode_str( ", name=", min(cur_size,req->namelen) );
+    dump_varargs_object_attributes( ", objattr=", cur_size );
     dump_varargs_unicode_str( ", class=", cur_size );
 }
 




More information about the wine-cvs mailing list