diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index d293b42ee771673fa7f9503eb18984838becd859..4e28b1333f091a4d92f21075e5d50f18611839c4 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -964,8 +964,7 @@ NTSTATUS WINAPI NtQueryVolumeInformationFile( HANDLE handle, PIO_STATUS_BLOCK io
 {
     int fd;
 
-    if ((io->u.Status = wine_server_handle_to_fd( handle, GENERIC_READ,
-                                                  &fd, NULL, NULL )) != STATUS_SUCCESS)
+    if ((io->u.Status = wine_server_handle_to_fd( handle, 0, &fd, NULL, NULL )) != STATUS_SUCCESS)
         return io->u.Status;
 
     io->u.Status = STATUS_NOT_IMPLEMENTED;
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 97d0d6f6af283f369dbbf31c59c310b93883da74..01704c37f5872c7543d87854044a6c5a96154cf6 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -1227,6 +1227,9 @@ static NTSTATUS load_native_dll( LPCWSTR load_path, LPCWSTR name, HANDLE file,
 
     nt = RtlImageNtHeader( module );
 
+    /* don't keep the file open if the mapping is from removable media */
+    if (!VIRTUAL_HasMapping( module )) file = 0;
+
     SERVER_START_REQ( load_dll )
     {
         req->handle     = file;
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index 42af347fb3b21d9a88e782156c893a046164bc8f..ce0efeb0a534acf18bb80fc2bb9b3cdcdb715e6a 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -94,6 +94,7 @@ extern NTSTATUS FILE_GetNtStatus(void);
 typedef BOOL (*HANDLERPROC)(LPVOID, LPCVOID);
 extern BOOL VIRTUAL_SetFaultHandler(LPCVOID addr, HANDLERPROC proc, LPVOID arg);
 extern DWORD VIRTUAL_HandleFault(LPCVOID addr);
+extern BOOL VIRTUAL_HasMapping( LPCVOID addr );
 
 /* code pages */
 extern int ntdll_umbstowcs(DWORD flags, const char* src, int srclen, WCHAR* dst, int dstlen);
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index c8986d7f74786fd017970c826b849ebfe31dd2a7..22898399e4d787a331cc549a131a0b7f06c9258d 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -43,6 +43,7 @@
 #include "ntstatus.h"
 #include "thread.h"
 #include "winternl.h"
+#include "winioctl.h"
 #include "wine/library.h"
 #include "wine/server.h"
 #include "wine/debug.h"
@@ -877,6 +878,22 @@ DWORD VIRTUAL_HandleFault( LPCVOID addr )
     return ret;
 }
 
+/***********************************************************************
+ *           VIRTUAL_HasMapping
+ *
+ * Check if the specified view has an associated file mapping.
+ */
+BOOL VIRTUAL_HasMapping( LPCVOID addr )
+{
+    FILE_VIEW *view;
+    BOOL ret = FALSE;
+
+    RtlEnterCriticalSection( &csVirtual );
+    if ((view = VIRTUAL_FindView( addr ))) ret = (view->mapping != 0);
+    RtlLeaveCriticalSection( &csVirtual );
+    return ret;
+}
+
 
 
 /***********************************************************************
@@ -1434,6 +1451,8 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
                                     ULONG commit_size, const LARGE_INTEGER *offset, ULONG *size_ptr,
                                     SECTION_INHERIT inherit, ULONG alloc_type, ULONG protect )
 {
+    IO_STATUS_BLOCK io;
+    FILE_FS_DEVICE_INFORMATION device_info;
     NTSTATUS res;
     UINT size = 0;
     int flags = MAP_PRIVATE;
@@ -1442,7 +1461,7 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
     void *base, *ptr = (void *)-1, *ret;
     DWORD size_low, size_high, header_size, shared_size;
     HANDLE shared_file;
-    BOOL removable;
+    BOOL removable = FALSE;
 
     if (!is_current_process( process ))
     {
@@ -1470,13 +1489,16 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
         header_size = reply->header_size;
         shared_file = reply->shared_file;
         shared_size = reply->shared_size;
-        removable   = reply->removable;
     }
     SERVER_END_REQ;
     if (res) return res;
 
     if ((res = wine_server_handle_to_fd( handle, 0, &unix_handle, NULL, NULL ))) return res;
 
+    if (NtQueryVolumeInformationFile( handle, &io, &device_info, sizeof(device_info),
+                                      FileFsDeviceInformation ) == STATUS_SUCCESS)
+        removable = device_info.Characteristics & FILE_REMOVABLE_MEDIA;
+
     if (prot & VPROT_IMAGE)
     {
         if (shared_file)
diff --git a/include/winternl.h b/include/winternl.h
index 7595d29527627656db55329e8ed47c90f6bb5eec..96f208f982fa5bc56e6d62a90953051005eda832 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -1165,6 +1165,7 @@ NTSTATUS  WINAPI NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS,PVOID,ULONG,P
 NTSTATUS  WINAPI NtQuerySystemTime(PLARGE_INTEGER);
 NTSTATUS  WINAPI NtQueryValueKey(HKEY,const UNICODE_STRING *,KEY_VALUE_INFORMATION_CLASS,void *,DWORD,DWORD *);
 NTSTATUS  WINAPI NtQueryVirtualMemory(HANDLE,LPCVOID,MEMORY_INFORMATION_CLASS,PVOID,ULONG,ULONG*);
+NTSTATUS  WINAPI NtQueryVolumeInformationFile(HANDLE,PIO_STATUS_BLOCK,PVOID,ULONG,FS_INFORMATION_CLASS);
 void      WINAPI NtRaiseException(PEXCEPTION_RECORD,PCONTEXT,BOOL);
 NTSTATUS  WINAPI NtReadFile(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,PVOID,ULONG,PLARGE_INTEGER,PULONG);
 NTSTATUS  WINAPI NtReadVirtualMemory(HANDLE,const void*,void*,SIZE_T,SIZE_T*);
diff --git a/server/process.c b/server/process.c
index 092755946e945d5d8572c81f98b7f41cd3fcc002..6afc0b294d0e660f3b1965f2adcb5e6f712de44e 100644
--- a/server/process.c
+++ b/server/process.c
@@ -1121,15 +1121,8 @@ DECL_HANDLER(load_dll)
     struct process_dll *dll;
     struct file *file = NULL;
 
-    if (req->handle)
-    {
-        if (!(file = get_file_obj( current->process, req->handle, GENERIC_READ ))) return;
-        if (is_file_removable( file ))  /* don't keep the file open on removable media */
-        {
-            release_object( file );
-            file = NULL;
-        }
-    }
+    if (req->handle && !(file = get_file_obj( current->process, req->handle, GENERIC_READ )))
+        return;
 
     if ((dll = process_load_dll( current->process, file, req->base,
                                  get_req_data(), get_req_data_size() )))