From: Santino Mazza smazza@codeweavers.com
Pass filename instead of openning a file handle and passing it to wineserver. This will help to simplify future implementations for load_key where we have to keep track of the file to lock it, save it, etc. For example, with application hives. --- dlls/ntdll/unix/registry.c | 12 ++------ include/wine/server_protocol.h | 5 ++-- server/protocol.def | 2 +- server/registry.c | 53 +++++++++++++++++++--------------- server/request.h | 5 ++-- server/trace.c | 4 +-- 6 files changed, 39 insertions(+), 42 deletions(-)
diff --git a/dlls/ntdll/unix/registry.c b/dlls/ntdll/unix/registry.c index 1643bff5da4..b53ee35f488 100644 --- a/dlls/ntdll/unix/registry.c +++ b/dlls/ntdll/unix/registry.c @@ -700,7 +700,7 @@ NTSTATUS WINAPI NtLoadKeyEx( const OBJECT_ATTRIBUTES *attr, OBJECT_ATTRIBUTES *f HANDLE event, ACCESS_MASK access, HANDLE *roothandle, IO_STATUS_BLOCK *iostatus ) { NTSTATUS ret; - HANDLE keyfilename, key; + HANDLE key; data_size_t len; struct object_attributes *objattr; char *unix_name; @@ -717,12 +717,7 @@ NTSTATUS WINAPI NtLoadKeyEx( const OBJECT_ATTRIBUTES *attr, OBJECT_ATTRIBUTES *f if (roothandle) *roothandle = NULL;
get_redirect( &new_attr, &nt_name ); - if (!(ret = nt_to_unix_file_name( &new_attr, &unix_name, FILE_OPEN ))) - { - ret = open_unix_file( &keyfilename, unix_name, GENERIC_READ | SYNCHRONIZE, - &new_attr, 0, 0, FILE_OPEN, 0, NULL, 0 ); - free( unix_name ); - } + ret = nt_to_unix_file_name( &new_attr, &unix_name, FILE_OPEN ); free( nt_name.Buffer );
if (ret) return ret; @@ -732,9 +727,9 @@ NTSTATUS WINAPI NtLoadKeyEx( const OBJECT_ATTRIBUTES *attr, OBJECT_ATTRIBUTES *f
SERVER_START_REQ( load_registry ) { - req->file = wine_server_obj_handle( keyfilename ); req->access = access; wine_server_add_data( req, objattr, len ); + wine_server_add_data( req, unix_name, strlen(unix_name) + 1 ); ret = wine_server_call( req ); key = wine_server_ptr_handle( reply->hkey ); if (ret == STATUS_OBJECT_NAME_EXISTS) ret = STATUS_SUCCESS; @@ -743,7 +738,6 @@ NTSTATUS WINAPI NtLoadKeyEx( const OBJECT_ATTRIBUTES *attr, OBJECT_ATTRIBUTES *f
if (roothandle) *roothandle = key; else NtClose(key); - NtClose( keyfilename ); free( objattr ); return ret; } diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 0fc9cbcafbb..2aa2dc1880f 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -2360,10 +2360,9 @@ struct delete_key_value_reply struct load_registry_request { struct request_header __header; - obj_handle_t file; unsigned int access; /* VARARG(objattr,object_attributes); */ - char __pad_20[4]; + /* VARARG(filename,string); */ }; struct load_registry_reply { @@ -6328,7 +6327,7 @@ union generic_reply
/* ### protocol_version begin ### */
-#define SERVER_PROTOCOL_VERSION 756 +#define SERVER_PROTOCOL_VERSION 758
/* ### protocol_version end ### */
diff --git a/server/protocol.def b/server/protocol.def index 470242187cd..a5a8105bf06 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1825,9 +1825,9 @@ 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 */ + VARARG(filename,string); /* file to load name */ @REPLY obj_handle_t hkey; /* handle to root key */ @END diff --git a/server/registry.c b/server/registry.c index 2817db327e0..22856e62b5e 100644 --- a/server/registry.c +++ b/server/registry.c @@ -90,6 +90,7 @@ struct key unsigned int flags; /* flags */ timeout_t modif; /* last modification time */ struct list notify_list; /* list of notifications */ + FILE *file; /* loaded file */ };
/* key flags */ @@ -637,15 +638,6 @@ static void key_unlink_name( struct object *obj, struct object_name *name ) } }
-/* close the notification associated with a handle */ -static int key_close_handle( struct object *obj, struct process *process, obj_handle_t handle ) -{ - struct key * key = (struct key *) obj; - struct notify *notify = find_notify( key, process, handle ); - if (notify) do_notification( key, notify, 1 ); - return 1; /* ok to close */ -} - static void key_destroy( struct object *obj ) { int i; @@ -699,6 +691,7 @@ static struct key *create_key_object( struct object *parent, const struct unicod key->last_value = -1; key->values = NULL; key->modif = modif; + key->file = NULL; list_init( &key->notify_list );
if (options & REG_OPTION_CREATE_LINK) key->flags |= KEY_SYMLINK; @@ -1747,24 +1740,17 @@ static void load_keys( struct key *key, const char *filename, FILE *f, int prefi }
/* load a part of the registry from a file */ -static void load_registry( struct key *key, obj_handle_t handle ) +static void load_registry( struct key *key, const char *filename ) { - struct file *file; - int fd; + FILE *f;
- if (!(file = get_file_obj( current->process, handle, FILE_READ_DATA ))) return; - fd = dup( get_file_unix_fd( file ) ); - release_object( file ); - if (fd != -1) + f = fopen( filename, "r" ); + if (f) { - FILE *f = fdopen( fd, "r" ); - if (f) - { - load_keys( key, NULL, f, -1 ); - fclose( f ); - } - else file_set_error(); + load_keys( key, NULL, f, -1 ); + fclose( f ); } + else file_set_error(); }
/* load one of the initial registry files */ @@ -2119,6 +2105,22 @@ void flush_registry(void) if (fchdir( server_dir_fd ) == -1) fatal_error( "chdir to server dir: %s\n", strerror( errno )); }
+/* close the notification associated with a handle */ +static int key_close_handle( struct object *obj, struct process *process, obj_handle_t handle ) +{ + struct key * key = (struct key *) obj; + struct notify *notify = find_notify( key, process, handle ); + if (notify) do_notification( key, notify, 1 ); + if (key->file) + { + save_all_subkeys(key, key->file); + funlockfile(key->file); + if (fclose(key->file)) file_set_error(); + delete_key(key, 1); + } + return 1; /* ok to close */ +} + /* determine if the thread is wow64 (32-bit client running on 64-bit prefix) */ static int is_wow64_thread( struct thread *thread ) { @@ -2280,8 +2282,11 @@ DECL_HANDLER(load_registry) { struct key *key, *parent = NULL; struct unicode_str name; + const char *filename; + data_size_t filename_len; const struct security_descriptor *sd; const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, NULL ); + filename = get_req_data_after_objattr(objattr, &filename_len);
if (!objattr) return;
@@ -2297,7 +2302,7 @@ DECL_HANDLER(load_registry)
if ((key = create_key( parent, &name, 0, KEY_WOW64_64KEY, 0, sd ))) { - load_registry( key, req->file ); + load_registry( key, filename ); reply->hkey = alloc_handle( current->process, key, req->access, objattr->attributes ); release_object( key ); } diff --git a/server/request.h b/server/request.h index edb69ee137d..10fbddc0852 100644 --- a/server/request.h +++ b/server/request.h @@ -1230,9 +1230,8 @@ C_ASSERT( FIELD_OFFSET(struct enum_key_value_reply, namelen) == 16 ); 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( FIELD_OFFSET(struct load_registry_request, access) == 16 ); -C_ASSERT( sizeof(struct load_registry_request) == 24 ); +C_ASSERT( FIELD_OFFSET(struct load_registry_request, access) == 12 ); +C_ASSERT( sizeof(struct load_registry_request) == 16 ); 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 ); diff --git a/server/trace.c b/server/trace.c index 329ee3a7b9f..c96b4addffe 100644 --- a/server/trace.c +++ b/server/trace.c @@ -2406,9 +2406,9 @@ 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 ); + fprintf( stderr, " access=%08x", req->access ); dump_varargs_object_attributes( ", objattr=", cur_size ); + dump_varargs_string( ", filename=", cur_size ); }
static void dump_load_registry_reply( const struct load_registry_reply *req )