Alexandre Julliard : ntdll: Duplicate the mapping handle on the server side for NtMapViewOfSection.

Alexandre Julliard julliard at wine.codeweavers.com
Fri Jan 12 13:55:13 CST 2007


Module: wine
Branch: master
Commit: 4cbe867a8504a4aedd1ddc4f8a5429c1cc1aea3b
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=4cbe867a8504a4aedd1ddc4f8a5429c1cc1aea3b

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri Jan 12 14:55:31 2007 +0100

ntdll: Duplicate the mapping handle on the server side for NtMapViewOfSection.

---

 dlls/ntdll/virtual.c           |   39 ++++++++++++++++-----------------------
 include/wine/server_protocol.h |    3 ++-
 server/mapping.c               |   16 ++++++++++++++--
 server/protocol.def            |    1 +
 server/trace.c                 |    2 ++
 5 files changed, 35 insertions(+), 26 deletions(-)

diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index 2ad3cfb..64a8b8e 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -934,7 +934,7 @@ static int do_relocations( char *base, c
  * Map an executable (PE format) image into memory.
  */
 static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_size, SIZE_T mask,
-                           SIZE_T header_size, int shared_fd, BOOL removable, PVOID *addr_ptr )
+                           SIZE_T header_size, int shared_fd, HANDLE dup_mapping, PVOID *addr_ptr )
 {
     IMAGE_DOS_HEADER *dos;
     IMAGE_NT_HEADERS *nt;
@@ -975,7 +975,7 @@ static NTSTATUS map_image( HANDLE hmappi
     if (!st.st_size) goto error;
     header_size = min( header_size, st.st_size );
     if (map_file_into_view( view, fd, 0, header_size, 0, VPROT_COMMITTED | VPROT_READ | VPROT_WRITECOPY,
-                            removable ) != STATUS_SUCCESS) goto error;
+                            !dup_mapping ) != STATUS_SUCCESS) goto error;
     dos = (IMAGE_DOS_HEADER *)ptr;
     nt = (IMAGE_NT_HEADERS *)(ptr + dos->e_lfanew);
     header_end = ptr + ROUND_SIZE( 0, header_size );
@@ -1019,7 +1019,7 @@ static NTSTATUS map_image( HANDLE hmappi
         /* in that case Windows simply maps in the whole file */
 
         if (map_file_into_view( view, fd, 0, total_size, 0, VPROT_COMMITTED | VPROT_READ,
-                                removable ) != STATUS_SUCCESS) goto error;
+                                !dup_mapping ) != STATUS_SUCCESS) goto error;
 
         /* check that all sections are loaded at the right offset */
         if (nt->OptionalHeader.FileAlignment != nt->OptionalHeader.SectionAlignment) goto error;
@@ -1121,7 +1121,7 @@ static NTSTATUS map_image( HANDLE hmappi
             end < file_start ||
             map_file_into_view( view, fd, sec->VirtualAddress, file_size, file_start,
                                 VPROT_COMMITTED | VPROT_READ | VPROT_WRITECOPY,
-                                removable ) != STATUS_SUCCESS)
+                                !dup_mapping ) != STATUS_SUCCESS)
         {
             ERR_(module)( "Could not map section %.8s, file probably truncated\n", sec->Name );
             goto error;
@@ -1195,11 +1195,7 @@ static NTSTATUS map_image( HANDLE hmappi
     }
 
  done:
-    if (!removable)  /* don't keep handle open on removable media */
-        NtDuplicateObject( NtCurrentProcess(), hmapping,
-                           NtCurrentProcess(), &view->mapping,
-                           0, 0, DUPLICATE_SAME_ACCESS );
-
+    view->mapping = dup_mapping;
     RtlLeaveCriticalSection( &csVirtual );
 
     *addr_ptr = ptr;
@@ -1208,6 +1204,7 @@ static NTSTATUS map_image( HANDLE hmappi
  error:
     if (view) delete_view( view );
     RtlLeaveCriticalSection( &csVirtual );
+    if (dup_mapping) NtClose( dup_mapping );
     return status;
 }
 
@@ -1837,13 +1834,12 @@ NTSTATUS WINAPI NtMapViewOfSection( HAND
     NTSTATUS res;
     SIZE_T size = 0;
     SIZE_T mask = get_mask( zero_bits );
-    int unix_handle = -1, flags, needs_close;
+    int unix_handle = -1, needs_close;
     int prot;
     void *base;
     struct file_view *view;
     DWORD size_low, size_high, header_size, shared_size;
-    HANDLE shared_file;
-    BOOL removable = FALSE;
+    HANDLE dup_mapping, shared_file;
     LARGE_INTEGER offset;
 
     offset.QuadPart = offset_ptr ? offset_ptr->QuadPart : 0;
@@ -1871,14 +1867,14 @@ NTSTATUS WINAPI NtMapViewOfSection( HAND
         size_low    = reply->size_low;
         size_high   = reply->size_high;
         header_size = reply->header_size;
+        dup_mapping = reply->mapping;
         shared_file = reply->shared_file;
         shared_size = reply->shared_size;
     }
     SERVER_END_REQ;
     if (res) return res;
 
-    if ((res = server_get_unix_fd( handle, 0, &unix_handle, &needs_close, NULL, &flags ))) return res;
-    removable = (flags & FD_FLAG_REMOVABLE) != 0;
+    if ((res = server_get_unix_fd( handle, 0, &unix_handle, &needs_close, NULL, NULL ))) goto done;
 
     if (prot & VPROT_IMAGE)
     {
@@ -1889,14 +1885,14 @@ NTSTATUS WINAPI NtMapViewOfSection( HAND
             if ((res = server_get_unix_fd( shared_file, FILE_READ_DATA|FILE_WRITE_DATA,
                                            &shared_fd, &shared_needs_close, NULL, NULL ))) goto done;
             res = map_image( handle, unix_handle, base, size_low, mask, header_size,
-                             shared_fd, removable, addr_ptr );
+                             shared_fd, dup_mapping, addr_ptr );
             if (shared_needs_close) close( shared_fd );
             NtClose( shared_file );
         }
         else
         {
             res = map_image( handle, unix_handle, base, size_low, mask, header_size,
-                             -1, removable, addr_ptr );
+                             -1, dup_mapping, addr_ptr );
         }
         if (needs_close) close( unix_handle );
         if (!res) *size_ptr = size_low;
@@ -1926,7 +1922,6 @@ NTSTATUS WINAPI NtMapViewOfSection( HAND
             res = STATUS_INVALID_PARAMETER;
             goto done;
         }
-        removable = FALSE;
         /* fall through */
     case PAGE_READONLY:
     case PAGE_WRITECOPY:
@@ -1964,16 +1959,13 @@ NTSTATUS WINAPI NtMapViewOfSection( HAND
     TRACE("handle=%p size=%lx offset=%x%08x\n",
           handle, size, offset.u.HighPart, offset.u.LowPart );
 
-    res = map_file_into_view( view, unix_handle, 0, size, offset.QuadPart, prot, removable );
+    res = map_file_into_view( view, unix_handle, 0, size, offset.QuadPart, prot, !dup_mapping );
     if (res == STATUS_SUCCESS)
     {
-        if (!removable)  /* don't keep handle open on removable media */
-            NtDuplicateObject( NtCurrentProcess(), handle,
-                               NtCurrentProcess(), &view->mapping,
-                               0, 0, DUPLICATE_SAME_ACCESS );
-
         *addr_ptr = view->base;
         *size_ptr = size;
+        view->mapping = dup_mapping;
+        dup_mapping = 0;  /* don't close it */
     }
     else
     {
@@ -1985,6 +1977,7 @@ NTSTATUS WINAPI NtMapViewOfSection( HAND
     RtlLeaveCriticalSection( &csVirtual );
 
 done:
+    if (dup_mapping) NtClose( dup_mapping );
     if (needs_close) close( unix_handle );
     return res;
 }
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index ce55bf0..03969ff 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -1535,6 +1535,7 @@ struct get_mapping_info_reply
     int          protect;
     int          header_size;
     void*        base;
+    obj_handle_t mapping;
     obj_handle_t shared_file;
     int          shared_size;
 };
@@ -4436,6 +4437,6 @@ union generic_reply
     struct query_symlink_reply query_symlink_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 263
+#define SERVER_PROTOCOL_VERSION 264
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/mapping.c b/server/mapping.c
index fe99879..9b123e2 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -432,6 +432,7 @@ DECL_HANDLER(open_mapping)
 DECL_HANDLER(get_mapping_info)
 {
     struct mapping *mapping;
+    struct fd *fd;
 
     if ((mapping = (struct mapping *)get_handle_obj( current->process, req->handle,
                                                      0, &mapping_ops )))
@@ -443,9 +444,20 @@ DECL_HANDLER(get_mapping_info)
         reply->base        = mapping->base;
         reply->shared_file = 0;
         reply->shared_size = mapping->shared_size;
+        if ((fd = get_obj_fd( &mapping->obj )))
+        {
+            if (!is_fd_removable(fd))
+                reply->mapping = alloc_handle( current->process, mapping, 0, 0 );
+            release_object( fd );
+        }
         if (mapping->shared_file)
-            reply->shared_file = alloc_handle( current->process, mapping->shared_file,
-                                               GENERIC_READ|GENERIC_WRITE, 0 );
+        {
+            if (!(reply->shared_file = alloc_handle( current->process, mapping->shared_file,
+                                                     GENERIC_READ|GENERIC_WRITE, 0 )))
+            {
+                if (reply->mapping) close_handle( current->process, reply->mapping );
+            }
+        }
         release_object( mapping );
     }
 }
diff --git a/server/protocol.def b/server/protocol.def
index a71bcee..3f7fbd5 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -1159,6 +1159,7 @@ enum char_info_mode
     int          protect;       /* protection flags */
     int          header_size;   /* header size (for VPROT_IMAGE mapping) */
     void*        base;          /* default base addr (for VPROT_IMAGE mapping) */
+    obj_handle_t mapping;       /* duplicate mapping handle unless removable */
     obj_handle_t shared_file;   /* shared mapping file handle */
     int          shared_size;   /* shared mapping size */
 @END
diff --git a/server/trace.c b/server/trace.c
index 1770a6d..5defbda 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -1570,6 +1570,7 @@ static void dump_get_mapping_info_reply(
     fprintf( stderr, " protect=%d,", req->protect );
     fprintf( stderr, " header_size=%d,", req->header_size );
     fprintf( stderr, " base=%p,", req->base );
+    fprintf( stderr, " mapping=%p,", req->mapping );
     fprintf( stderr, " shared_file=%p,", req->shared_file );
     fprintf( stderr, " shared_size=%d", req->shared_size );
 }
@@ -3966,6 +3967,7 @@ static const struct
     { "FILE_LOCK_CONFLICT",          STATUS_FILE_LOCK_CONFLICT },
     { "HANDLES_CLOSED",              STATUS_HANDLES_CLOSED },
     { "HANDLE_NOT_CLOSABLE",         STATUS_HANDLE_NOT_CLOSABLE },
+    { "ILLEGAL_FUNCTION",            STATUS_ILLEGAL_FUNCTION },
     { "INSTANCE_NOT_AVAILABLE",      STATUS_INSTANCE_NOT_AVAILABLE },
     { "INVALID_CID",                 STATUS_INVALID_CID },
     { "INVALID_FILE_FOR_SECTION",    STATUS_INVALID_FILE_FOR_SECTION },




More information about the wine-cvs mailing list