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 )
{
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;
}

View File

@ -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 */

View File

@ -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 */
}
}

View File

@ -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)
{

View File

@ -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 */

View File

@ -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;

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 */
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 */

View File

@ -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 */

View File

@ -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 */

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( 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 );

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 )
{
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 );