From 900352bc6bd32c6524658083339ba119620be9c7 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 18 Apr 2011 14:14:40 +0200 Subject: [PATCH] server: Store a mapping instead of a file for process dlls. --- dlls/ntdll/loader.c | 20 +++++++++++++------- include/wine/server_protocol.h | 4 ++-- server/debugger.c | 8 +++++--- server/file.c | 6 ------ server/file.h | 3 ++- server/mapping.c | 6 ++++++ server/process.c | 18 +++++++++--------- server/process.h | 2 +- server/protocol.def | 2 +- server/request.h | 2 +- server/trace.c | 2 +- 11 files changed, 41 insertions(+), 32 deletions(-) diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index 19d484a51e..87571dedff 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -1452,7 +1452,7 @@ static void load_builtin_callback( void *module, const char *filename ) SERVER_START_REQ( load_dll ) { - req->handle = 0; + req->mapping = 0; req->base = wine_server_client_ptr( module ); req->size = nt->OptionalHeader.SizeOfImage; req->dbg_offset = nt->FileHeader.PointerToSymbolTable; @@ -1492,12 +1492,15 @@ static NTSTATUS load_native_dll( LPCWSTR load_path, LPCWSTR name, HANDLE file, module = NULL; status = NtMapViewOfSection( mapping, NtCurrentProcess(), &module, 0, 0, &size, &len, ViewShare, 0, PAGE_READONLY ); - NtClose( mapping ); - if (status < 0) return status; + if (status < 0) goto done; /* create the MODREF */ - if (!(wm = alloc_module( module, name ))) return STATUS_NO_MEMORY; + if (!(wm = alloc_module( module, name ))) + { + status = STATUS_NO_MEMORY; + goto done; + } /* fixup imports */ @@ -1516,7 +1519,7 @@ static NTSTATUS load_native_dll( LPCWSTR load_path, LPCWSTR name, HANDLE file, * around with no problems, so we don't care. * As these might reference our wm, we don't free it. */ - return status; + goto done; } } @@ -1526,7 +1529,7 @@ static NTSTATUS load_native_dll( LPCWSTR load_path, LPCWSTR name, HANDLE file, SERVER_START_REQ( load_dll ) { - req->handle = wine_server_obj_handle( file ); + req->mapping = wine_server_obj_handle( mapping ); req->base = wine_server_client_ptr( module ); req->size = nt->OptionalHeader.SizeOfImage; req->dbg_offset = nt->FileHeader.PointerToSymbolTable; @@ -1543,7 +1546,10 @@ static NTSTATUS load_native_dll( LPCWSTR load_path, LPCWSTR name, HANDLE file, wm->ldr.LoadCount = 1; *pwm = wm; - return STATUS_SUCCESS; + status = STATUS_SUCCESS; +done: + NtClose( mapping ); + return status; } diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index d321a80abe..e1015dd9c4 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -884,7 +884,7 @@ struct resume_thread_reply struct load_dll_request { struct request_header __header; - obj_handle_t handle; + obj_handle_t mapping; mod_handle_t base; client_ptr_t name; data_size_t size; @@ -5563,6 +5563,6 @@ union generic_reply struct set_cursor_reply set_cursor_reply; }; -#define SERVER_PROTOCOL_VERSION 419 +#define SERVER_PROTOCOL_VERSION 420 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/debugger.c b/server/debugger.c index 74c59f215f..c693c7dfe8 100644 --- a/server/debugger.c +++ b/server/debugger.c @@ -33,6 +33,7 @@ #include "winternl.h" #include "handle.h" +#include "file.h" #include "process.h" #include "thread.h" #include "request.h" @@ -157,9 +158,9 @@ static int fill_create_process_event( struct debug_event *event, const void *arg event->data.create_process.thread = handle; handle = 0; - if (exe_module->file && + if (exe_module->mapping && /* the doc says write access too, but this doesn't seem a good idea */ - !(handle = alloc_handle( debugger, exe_module->file, GENERIC_READ, 0 ))) + !(handle = open_mapping_file( debugger, exe_module->mapping, GENERIC_READ, 0 ))) { close_handle( debugger, event->data.create_process.process ); close_handle( debugger, event->data.create_process.thread ); @@ -196,7 +197,7 @@ static int fill_load_dll_event( struct debug_event *event, const void *arg ) const struct process_dll *dll = arg; obj_handle_t handle = 0; - if (dll->file && !(handle = alloc_handle( debugger, dll->file, GENERIC_READ, 0 ))) + if (dll->mapping && !(handle = open_mapping_file( debugger, dll->mapping, GENERIC_READ, 0 ))) return 0; event->data.load_dll.handle = handle; event->data.load_dll.base = dll->base; @@ -414,6 +415,7 @@ void generate_debug_event( struct thread *thread, int code, const void *arg ) suspend_process( thread->process ); release_object( event ); } + clear_error(); /* ignore errors */ } } diff --git a/server/file.c b/server/file.c index ce95576e2e..fe88495ec8 100644 --- a/server/file.c +++ b/server/file.c @@ -647,12 +647,6 @@ int get_file_unix_fd( struct file *file ) return get_unix_fd( file->fd ); } -struct file *grab_file_unless_removable( struct file *file ) -{ - if (is_fd_removable( file->fd )) return NULL; - return (struct file *)grab_object( file ); -} - /* create a file */ DECL_HANDLER(create_file) { diff --git a/server/file.h b/server/file.h index 772c9b8493..218b553498 100644 --- a/server/file.h +++ b/server/file.h @@ -24,6 +24,7 @@ #include "object.h" struct fd; +struct mapping; struct async_queue; struct completion; @@ -117,7 +118,6 @@ extern int get_file_unix_fd( struct file *file ); extern int is_same_file( struct file *file1, struct file *file2 ); extern struct file *create_file_for_fd( int fd, unsigned int access, unsigned int sharing ); extern struct file *create_file_for_fd_obj( struct fd *fd, unsigned int access, unsigned int sharing ); -extern struct file *grab_file_unless_removable( struct file *file ); extern void file_set_error(void); extern struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID *group ); extern mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner ); @@ -128,6 +128,7 @@ extern struct mapping *get_mapping_obj( struct process *process, obj_handle_t ha unsigned int access ); extern obj_handle_t open_mapping_file( struct process *process, struct mapping *mapping, unsigned int access, unsigned int sharing ); +extern struct mapping *grab_mapping_unless_removable( struct mapping *mapping ); extern int get_page_size(void); /* change notification functions */ diff --git a/server/mapping.c b/server/mapping.c index 01622e8bab..733dc89ad0 100644 --- a/server/mapping.c +++ b/server/mapping.c @@ -583,6 +583,12 @@ obj_handle_t open_mapping_file( struct process *process, struct mapping *mapping return handle; } +struct mapping *grab_mapping_unless_removable( struct mapping *mapping ) +{ + if (is_fd_removable( mapping->fd )) return NULL; + return (struct mapping *)grab_object( mapping ); +} + static void mapping_dump( struct object *obj, int verbose ) { struct mapping *mapping = (struct mapping *)obj; diff --git a/server/process.c b/server/process.c index d868d21f7d..797b4cf92d 100644 --- a/server/process.c +++ b/server/process.c @@ -515,7 +515,7 @@ static inline struct process_dll *find_process_dll( struct process *process, mod } /* add a dll to a process list */ -static struct process_dll *process_load_dll( struct process *process, struct file *file, +static struct process_dll *process_load_dll( struct process *process, struct mapping *mapping, mod_handle_t base, const WCHAR *filename, data_size_t name_len ) { @@ -530,7 +530,7 @@ static struct process_dll *process_load_dll( struct process *process, struct fil if ((dll = mem_alloc( sizeof(*dll) ))) { - dll->file = NULL; + dll->mapping = NULL; dll->base = base; dll->filename = NULL; dll->namelen = name_len; @@ -539,7 +539,7 @@ static struct process_dll *process_load_dll( struct process *process, struct fil free( dll ); return NULL; } - if (file) dll->file = grab_file_unless_removable( file ); + if (mapping) dll->mapping = grab_mapping_unless_removable( mapping ); list_add_tail( &process->dlls, &dll->entry ); } return dll; @@ -552,7 +552,7 @@ static void process_unload_dll( struct process *process, mod_handle_t base ) if (dll && (&dll->entry != list_head( &process->dlls ))) /* main exe can't be unloaded */ { - if (dll->file) release_object( dll->file ); + if (dll->mapping) release_object( dll->mapping ); free( dll->filename ); list_remove( &dll->entry ); free( dll ); @@ -637,7 +637,7 @@ static void process_killed( struct process *process ) while ((ptr = list_head( &process->dlls ))) { struct process_dll *dll = LIST_ENTRY( ptr, struct process_dll, entry ); - if (dll->file) release_object( dll->file ); + if (dll->mapping) release_object( dll->mapping ); free( dll->filename ); list_remove( &dll->entry ); free( dll ); @@ -1160,12 +1160,12 @@ DECL_HANDLER(write_process_memory) DECL_HANDLER(load_dll) { struct process_dll *dll; - struct file *file = NULL; + struct mapping *mapping = NULL; - if (req->handle && !(file = get_file_obj( current->process, req->handle, FILE_READ_DATA ))) + if (req->mapping && !(mapping = get_mapping_obj( current->process, req->mapping, SECTION_QUERY ))) return; - if ((dll = process_load_dll( current->process, file, req->base, + if ((dll = process_load_dll( current->process, mapping, req->base, get_req_data(), get_req_data_size() ))) { dll->size = req->size; @@ -1176,7 +1176,7 @@ DECL_HANDLER(load_dll) if (is_process_init_done( current->process )) generate_debug_event( current, LOAD_DLL_DEBUG_EVENT, dll ); } - if (file) release_object( file ); + if (mapping) release_object( mapping ); } /* notify the server that a dll is being unloaded */ diff --git a/server/process.h b/server/process.h index cee7be9381..da51a0ee4b 100644 --- a/server/process.h +++ b/server/process.h @@ -35,7 +35,7 @@ enum startup_state { STARTUP_IN_PROGRESS, STARTUP_DONE, STARTUP_ABORTED }; struct process_dll { struct list entry; /* entry in per-process dll list */ - struct file *file; /* dll file */ + struct mapping *mapping; /* dll file */ mod_handle_t base; /* dll base address (in process addr space) */ client_ptr_t name; /* ptr to ptr to name (in process addr space) */ data_size_t size; /* dll size */ diff --git a/server/protocol.def b/server/protocol.def index 8aaf2d3ff2..8e50ed9cbe 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -807,7 +807,7 @@ typedef union /* Notify the server that a dll has been loaded */ @REQ(load_dll) - obj_handle_t handle; /* file handle */ + obj_handle_t mapping; /* file mapping handle */ mod_handle_t base; /* base address */ client_ptr_t name; /* ptr to ptr to name (in process addr space) */ data_size_t size; /* dll size */ diff --git a/server/request.h b/server/request.h index 0133af7ad5..acf886fbb2 100644 --- a/server/request.h +++ b/server/request.h @@ -751,7 +751,7 @@ C_ASSERT( FIELD_OFFSET(struct resume_thread_request, handle) == 12 ); C_ASSERT( sizeof(struct resume_thread_request) == 16 ); C_ASSERT( FIELD_OFFSET(struct resume_thread_reply, count) == 8 ); C_ASSERT( sizeof(struct resume_thread_reply) == 16 ); -C_ASSERT( FIELD_OFFSET(struct load_dll_request, handle) == 12 ); +C_ASSERT( FIELD_OFFSET(struct load_dll_request, mapping) == 12 ); C_ASSERT( FIELD_OFFSET(struct load_dll_request, base) == 16 ); C_ASSERT( FIELD_OFFSET(struct load_dll_request, name) == 24 ); C_ASSERT( FIELD_OFFSET(struct load_dll_request, size) == 32 ); diff --git a/server/trace.c b/server/trace.c index 06fe545c55..a723c6c408 100644 --- a/server/trace.c +++ b/server/trace.c @@ -1263,7 +1263,7 @@ static void dump_resume_thread_reply( const struct resume_thread_reply *req ) static void dump_load_dll_request( const struct load_dll_request *req ) { - fprintf( stderr, " handle=%04x", req->handle ); + fprintf( stderr, " mapping=%04x", req->mapping ); dump_uint64( ", base=", &req->base ); dump_uint64( ", name=", &req->name ); fprintf( stderr, ", size=%u", req->size ); -- 2.32.0.93.g670b81a890