server: Store a mapping instead of a file for process dlls.
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 19d484a..87571de 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -1452,7 +1452,7 @@
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 @@
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 @@
* 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 @@
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 @@
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 d321a80..e1015dd 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -884,7 +884,7 @@
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 @@
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 74c59f2..c693c7d 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 @@
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 @@
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 @@
suspend_process( thread->process );
release_object( event );
}
+ clear_error(); /* ignore errors */
}
}
diff --git a/server/file.c b/server/file.c
index ce95576..fe88495 100644
--- a/server/file.c
+++ b/server/file.c
@@ -647,12 +647,6 @@
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 772c9b8..218b553 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 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 @@
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 01622e8..733dc89 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -583,6 +583,12 @@
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 d868d21..797b4cf 100644
--- a/server/process.c
+++ b/server/process.c
@@ -515,7 +515,7 @@
}
/* 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 @@
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 @@
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 @@
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 @@
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(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 @@
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 cee7be9..da51a0e 100644
--- a/server/process.h
+++ b/server/process.h
@@ -35,7 +35,7 @@
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 8aaf2d3..8e50ed9 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -807,7 +807,7 @@
/* 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 0133af7..acf886f 100644
--- a/server/request.h
+++ b/server/request.h
@@ -751,7 +751,7 @@
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 06fe545..a723c6c 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -1263,7 +1263,7 @@
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 );