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