server: Store a mapping instead of a file for process dlls.

This commit is contained in:
Alexandre Julliard 2011-04-18 14:14:40 +02:00
parent eb2fe39d63
commit 900352bc6b
11 changed files with 41 additions and 32 deletions

View File

@ -1452,7 +1452,7 @@ static void load_builtin_callback( void *module, const char *filename )
SERVER_START_REQ( load_dll ) SERVER_START_REQ( load_dll )
{ {
req->handle = 0; req->mapping = 0;
req->base = wine_server_client_ptr( module ); req->base = wine_server_client_ptr( module );
req->size = nt->OptionalHeader.SizeOfImage; req->size = nt->OptionalHeader.SizeOfImage;
req->dbg_offset = nt->FileHeader.PointerToSymbolTable; req->dbg_offset = nt->FileHeader.PointerToSymbolTable;
@ -1492,12 +1492,15 @@ static NTSTATUS load_native_dll( LPCWSTR load_path, LPCWSTR name, HANDLE file,
module = NULL; module = NULL;
status = NtMapViewOfSection( mapping, NtCurrentProcess(), status = NtMapViewOfSection( mapping, NtCurrentProcess(),
&module, 0, 0, &size, &len, ViewShare, 0, PAGE_READONLY ); &module, 0, 0, &size, &len, ViewShare, 0, PAGE_READONLY );
NtClose( mapping ); if (status < 0) goto done;
if (status < 0) return status;
/* create the MODREF */ /* 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 */ /* 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. * around with no problems, so we don't care.
* As these might reference our wm, we don't free it. * 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 ) 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->base = wine_server_client_ptr( module );
req->size = nt->OptionalHeader.SizeOfImage; req->size = nt->OptionalHeader.SizeOfImage;
req->dbg_offset = nt->FileHeader.PointerToSymbolTable; 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; wm->ldr.LoadCount = 1;
*pwm = wm; *pwm = wm;
return STATUS_SUCCESS; status = STATUS_SUCCESS;
done:
NtClose( mapping );
return status;
} }

View File

@ -884,7 +884,7 @@ struct resume_thread_reply
struct load_dll_request struct load_dll_request
{ {
struct request_header __header; struct request_header __header;
obj_handle_t handle; obj_handle_t mapping;
mod_handle_t base; mod_handle_t base;
client_ptr_t name; client_ptr_t name;
data_size_t size; data_size_t size;
@ -5563,6 +5563,6 @@ union generic_reply
struct set_cursor_reply set_cursor_reply; struct set_cursor_reply set_cursor_reply;
}; };
#define SERVER_PROTOCOL_VERSION 419 #define SERVER_PROTOCOL_VERSION 420
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -33,6 +33,7 @@
#include "winternl.h" #include "winternl.h"
#include "handle.h" #include "handle.h"
#include "file.h"
#include "process.h" #include "process.h"
#include "thread.h" #include "thread.h"
#include "request.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; event->data.create_process.thread = handle;
handle = 0; handle = 0;
if (exe_module->file && if (exe_module->mapping &&
/* the doc says write access too, but this doesn't seem a good idea */ /* 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.process );
close_handle( debugger, event->data.create_process.thread ); 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; const struct process_dll *dll = arg;
obj_handle_t handle = 0; 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; return 0;
event->data.load_dll.handle = handle; event->data.load_dll.handle = handle;
event->data.load_dll.base = dll->base; 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 ); suspend_process( thread->process );
release_object( event ); release_object( event );
} }
clear_error(); /* ignore errors */
} }
} }

View File

@ -647,12 +647,6 @@ int get_file_unix_fd( struct file *file )
return get_unix_fd( file->fd ); 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 */ /* create a file */
DECL_HANDLER(create_file) DECL_HANDLER(create_file)
{ {

View File

@ -24,6 +24,7 @@
#include "object.h" #include "object.h"
struct fd; struct fd;
struct mapping;
struct async_queue; struct async_queue;
struct completion; 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 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( 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 *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 void file_set_error(void);
extern struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID *group ); 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 ); 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 ); unsigned int access );
extern obj_handle_t open_mapping_file( struct process *process, struct mapping *mapping, extern obj_handle_t open_mapping_file( struct process *process, struct mapping *mapping,
unsigned int access, unsigned int sharing ); unsigned int access, unsigned int sharing );
extern struct mapping *grab_mapping_unless_removable( struct mapping *mapping );
extern int get_page_size(void); extern int get_page_size(void);
/* change notification functions */ /* change notification functions */

View File

@ -583,6 +583,12 @@ obj_handle_t open_mapping_file( struct process *process, struct mapping *mapping
return handle; 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 ) static void mapping_dump( struct object *obj, int verbose )
{ {
struct mapping *mapping = (struct mapping *)obj; struct mapping *mapping = (struct mapping *)obj;

View File

@ -515,7 +515,7 @@ static inline struct process_dll *find_process_dll( struct process *process, mod
} }
/* add a dll to a process list */ /* 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, mod_handle_t base, const WCHAR *filename,
data_size_t name_len ) 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) ))) if ((dll = mem_alloc( sizeof(*dll) )))
{ {
dll->file = NULL; dll->mapping = NULL;
dll->base = base; dll->base = base;
dll->filename = NULL; dll->filename = NULL;
dll->namelen = name_len; dll->namelen = name_len;
@ -539,7 +539,7 @@ static struct process_dll *process_load_dll( struct process *process, struct fil
free( dll ); free( dll );
return NULL; 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 ); list_add_tail( &process->dlls, &dll->entry );
} }
return dll; 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 && (&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 ); free( dll->filename );
list_remove( &dll->entry ); list_remove( &dll->entry );
free( dll ); free( dll );
@ -637,7 +637,7 @@ static void process_killed( struct process *process )
while ((ptr = list_head( &process->dlls ))) while ((ptr = list_head( &process->dlls )))
{ {
struct process_dll *dll = LIST_ENTRY( ptr, struct process_dll, entry ); 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 ); free( dll->filename );
list_remove( &dll->entry ); list_remove( &dll->entry );
free( dll ); free( dll );
@ -1160,12 +1160,12 @@ DECL_HANDLER(write_process_memory)
DECL_HANDLER(load_dll) DECL_HANDLER(load_dll)
{ {
struct process_dll *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; 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() ))) get_req_data(), get_req_data_size() )))
{ {
dll->size = req->size; dll->size = req->size;
@ -1176,7 +1176,7 @@ DECL_HANDLER(load_dll)
if (is_process_init_done( current->process )) if (is_process_init_done( current->process ))
generate_debug_event( current, LOAD_DLL_DEBUG_EVENT, dll ); 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 */ /* notify the server that a dll is being unloaded */

View File

@ -35,7 +35,7 @@ enum startup_state { STARTUP_IN_PROGRESS, STARTUP_DONE, STARTUP_ABORTED };
struct process_dll struct process_dll
{ {
struct list entry; /* entry in per-process dll list */ 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) */ mod_handle_t base; /* dll base address (in process addr space) */
client_ptr_t name; /* ptr to ptr to name (in process addr space) */ client_ptr_t name; /* ptr to ptr to name (in process addr space) */
data_size_t size; /* dll size */ data_size_t size; /* dll size */

View File

@ -807,7 +807,7 @@ typedef union
/* Notify the server that a dll has been loaded */ /* Notify the server that a dll has been loaded */
@REQ(load_dll) @REQ(load_dll)
obj_handle_t handle; /* file handle */ obj_handle_t mapping; /* file mapping handle */
mod_handle_t base; /* base address */ mod_handle_t base; /* base address */
client_ptr_t name; /* ptr to ptr to name (in process addr space) */ client_ptr_t name; /* ptr to ptr to name (in process addr space) */
data_size_t size; /* dll size */ data_size_t size; /* dll size */

View File

@ -751,7 +751,7 @@ C_ASSERT( FIELD_OFFSET(struct resume_thread_request, handle) == 12 );
C_ASSERT( sizeof(struct resume_thread_request) == 16 ); C_ASSERT( sizeof(struct resume_thread_request) == 16 );
C_ASSERT( FIELD_OFFSET(struct resume_thread_reply, count) == 8 ); C_ASSERT( FIELD_OFFSET(struct resume_thread_reply, count) == 8 );
C_ASSERT( sizeof(struct resume_thread_reply) == 16 ); 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, base) == 16 );
C_ASSERT( FIELD_OFFSET(struct load_dll_request, name) == 24 ); C_ASSERT( FIELD_OFFSET(struct load_dll_request, name) == 24 );
C_ASSERT( FIELD_OFFSET(struct load_dll_request, size) == 32 ); C_ASSERT( FIELD_OFFSET(struct load_dll_request, size) == 32 );

View File

@ -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 ) 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( ", base=", &req->base );
dump_uint64( ", name=", &req->name ); dump_uint64( ", name=", &req->name );
fprintf( stderr, ", size=%u", req->size ); fprintf( stderr, ", size=%u", req->size );