From: Santino Mazza smazza@codeweavers.com
--- dlls/ntdll/unix/registry.c | 10 +++++++--- include/wine/server_protocol.h | 6 +++++- server/protocol.def | 3 +++ server/registry.c | 1 + server/request.h | 5 ++++- server/trace.c | 8 +++++++- 6 files changed, 27 insertions(+), 6 deletions(-)
diff --git a/dlls/ntdll/unix/registry.c b/dlls/ntdll/unix/registry.c index f61b892875f..f1e5305cecb 100644 --- a/dlls/ntdll/unix/registry.c +++ b/dlls/ntdll/unix/registry.c @@ -700,7 +700,7 @@ NTSTATUS WINAPI NtLoadKeyEx( const OBJECT_ATTRIBUTES *key_attr, OBJECT_ATTRIBUTE HANDLE event, ACCESS_MASK access, HANDLE *roothandle, IO_STATUS_BLOCK *iostatus ) { NTSTATUS ret; - HANDLE file; + HANDLE file, key; data_size_t len; struct object_attributes *objattr; char *unix_name; @@ -712,10 +712,10 @@ NTSTATUS WINAPI NtLoadKeyEx( const OBJECT_ATTRIBUTES *key_attr, OBJECT_ATTRIBUTE if (flags) FIXME( "flags %x not handled\n", flags ); if (trustkey) FIXME("trustkey parameter not supported\n"); if (event) FIXME("event parameter not supported\n"); - if (access) FIXME("access parameter not supported\n"); - if (roothandle) FIXME("roothandle is not filled\n"); if (iostatus) FIXME("iostatus is not filled\n");
+ if (roothandle && !(flags & REG_LOAD_APP_KEY)) return STATUS_INVALID_PARAMETER_7; + get_redirect( &new_attr, &nt_name ); if (!(ret = nt_to_unix_file_name( &new_attr, &unix_name, FILE_OPEN ))) { @@ -733,12 +733,16 @@ NTSTATUS WINAPI NtLoadKeyEx( const OBJECT_ATTRIBUTES *key_attr, OBJECT_ATTRIBUTE SERVER_START_REQ( load_registry ) { req->file = wine_server_obj_handle( file ); + req->access = access; wine_server_add_data( req, objattr, len ); ret = wine_server_call( req ); + key = wine_server_ptr_handle( reply->hkey ); if (ret == STATUS_OBJECT_NAME_EXISTS) ret = STATUS_SUCCESS; } SERVER_END_REQ;
+ if (roothandle) *roothandle = key; + else NtClose( key ); NtClose( file ); free( objattr ); return ret; diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index fb3168c4a6a..0fc9cbcafbb 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -2361,11 +2361,15 @@ struct load_registry_request { struct request_header __header; obj_handle_t file; + unsigned int access; /* VARARG(objattr,object_attributes); */ + char __pad_20[4]; }; struct load_registry_reply { struct reply_header __header; + obj_handle_t hkey; + char __pad_12[4]; };
@@ -6324,7 +6328,7 @@ union generic_reply
/* ### protocol_version begin ### */
-#define SERVER_PROTOCOL_VERSION 755 +#define SERVER_PROTOCOL_VERSION 756
/* ### protocol_version end ### */
diff --git a/server/protocol.def b/server/protocol.def index d828d41d1f7..470242187cd 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1826,7 +1826,10 @@ struct process_info /* Load a registry branch from a file */ @REQ(load_registry) obj_handle_t file; /* file to load from */ + unsigned int access; /* wanted access rights */ VARARG(objattr,object_attributes); /* object attributes */ +@REPLY + obj_handle_t hkey; /* handle to root key */ @END
diff --git a/server/registry.c b/server/registry.c index 96ba18a0a5a..2817db327e0 100644 --- a/server/registry.c +++ b/server/registry.c @@ -2298,6 +2298,7 @@ DECL_HANDLER(load_registry) if ((key = create_key( parent, &name, 0, KEY_WOW64_64KEY, 0, sd ))) { load_registry( key, req->file ); + reply->hkey = alloc_handle( current->process, key, req->access, objattr->attributes ); release_object( key ); } if (parent) release_object( parent ); diff --git a/server/request.h b/server/request.h index 9e943cceb3c..edb69ee137d 100644 --- a/server/request.h +++ b/server/request.h @@ -1231,7 +1231,10 @@ C_ASSERT( sizeof(struct enum_key_value_reply) == 24 ); C_ASSERT( FIELD_OFFSET(struct delete_key_value_request, hkey) == 12 ); C_ASSERT( sizeof(struct delete_key_value_request) == 16 ); C_ASSERT( FIELD_OFFSET(struct load_registry_request, file) == 12 ); -C_ASSERT( sizeof(struct load_registry_request) == 16 ); +C_ASSERT( FIELD_OFFSET(struct load_registry_request, access) == 16 ); +C_ASSERT( sizeof(struct load_registry_request) == 24 ); +C_ASSERT( FIELD_OFFSET(struct load_registry_reply, hkey) == 8 ); +C_ASSERT( sizeof(struct load_registry_reply) == 16 ); C_ASSERT( FIELD_OFFSET(struct unload_registry_request, parent) == 12 ); C_ASSERT( FIELD_OFFSET(struct unload_registry_request, attributes) == 16 ); C_ASSERT( sizeof(struct unload_registry_request) == 24 ); diff --git a/server/trace.c b/server/trace.c index c6a324bb905..329ee3a7b9f 100644 --- a/server/trace.c +++ b/server/trace.c @@ -2407,9 +2407,15 @@ static void dump_delete_key_value_request( const struct delete_key_value_request static void dump_load_registry_request( const struct load_registry_request *req ) { fprintf( stderr, " file=%04x", req->file ); + fprintf( stderr, ", access=%08x", req->access ); dump_varargs_object_attributes( ", objattr=", cur_size ); }
+static void dump_load_registry_reply( const struct load_registry_reply *req ) +{ + fprintf( stderr, " hkey=%04x", req->hkey ); +} + static void dump_unload_registry_request( const struct unload_registry_request *req ) { fprintf( stderr, " parent=%04x", req->parent ); @@ -4869,7 +4875,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_get_key_value_reply, (dump_func)dump_enum_key_value_reply, NULL, - NULL, + (dump_func)dump_load_registry_reply, NULL, NULL, NULL,