Alexandre Julliard : server: Implement NtAreMappedFilesTheSame functionality on the server side.

Alexandre Julliard julliard at winehq.org
Tue Sep 26 14:56:16 CDT 2017


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Sep 26 14:55:13 2017 +0200

server: Implement NtAreMappedFilesTheSame functionality on the server side.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/virtual.c           | 35 ++++++++++-------------------------
 include/wine/server_protocol.h | 19 ++++++++++++++++++-
 server/mapping.c               | 13 +++++++++++++
 server/protocol.def            |  7 +++++++
 server/request.h               |  5 +++++
 server/trace.c                 | 10 ++++++++++
 6 files changed, 63 insertions(+), 26 deletions(-)

diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index d6ccddc..c2492d9 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -1306,25 +1306,6 @@ static NTSTATUS allocate_dos_memory( struct file_view **view, unsigned int vprot
 
 
 /***********************************************************************
- *           stat_mapping_file
- *
- * Stat the underlying file for a memory view.
- */
-static NTSTATUS stat_mapping_file( struct file_view *view, struct stat *st )
-{
-    NTSTATUS status;
-    int unix_fd, needs_close;
-
-    if (!view->mapping) return STATUS_NOT_MAPPED_VIEW;
-    if (!(status = server_get_unix_fd( view->mapping, 0, &unix_fd, &needs_close, NULL, NULL )))
-    {
-        if (fstat( unix_fd, st ) == -1) status = FILE_GetNtStatus();
-        if (needs_close) close( unix_fd );
-    }
-    return status;
-}
-
-/***********************************************************************
  *           map_image
  *
  * Map an executable (PE format) image into memory.
@@ -3337,7 +3318,6 @@ NTSTATUS WINAPI NtWriteVirtualMemory( HANDLE process, void *addr, const void *bu
 NTSTATUS WINAPI NtAreMappedFilesTheSame(PVOID addr1, PVOID addr2)
 {
     struct file_view *view1, *view2;
-    struct stat st1, st2;
     NTSTATUS status;
     sigset_t sigset;
 
@@ -3354,13 +3334,18 @@ NTSTATUS WINAPI NtAreMappedFilesTheSame(PVOID addr1, PVOID addr2)
         status = STATUS_CONFLICTING_ADDRESSES;
     else if (view1 == view2)
         status = STATUS_SUCCESS;
-    else if (!(view1->protect & SEC_IMAGE) || !(view2->protect & SEC_IMAGE))
+    else if ((view1->protect & VPROT_SYSTEM) || (view2->protect & VPROT_SYSTEM))
         status = STATUS_NOT_SAME_DEVICE;
-    else if (!stat_mapping_file( view1, &st1 ) && !stat_mapping_file( view2, &st2 ) &&
-             st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino)
-        status = STATUS_SUCCESS;
     else
-        status = STATUS_NOT_SAME_DEVICE;
+    {
+        SERVER_START_REQ( is_same_mapping )
+        {
+            req->base1 = wine_server_client_ptr( view1->base );
+            req->base2 = wine_server_client_ptr( view2->base );
+            status = wine_server_call( req );
+        }
+        SERVER_END_REQ;
+    }
 
     server_leave_uninterrupted_section( &csVirtual, &sigset );
     return status;
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index ff0cb1e..5e42e1a 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -2289,6 +2289,20 @@ struct add_mapping_committed_range_reply
 };
 
 
+
+struct is_same_mapping_request
+{
+    struct request_header __header;
+    char __pad_12[4];
+    client_ptr_t base1;
+    client_ptr_t base2;
+};
+struct is_same_mapping_reply
+{
+    struct reply_header __header;
+};
+
+
 #define SNAP_PROCESS    0x00000001
 #define SNAP_THREAD     0x00000002
 
@@ -5662,6 +5676,7 @@ enum request
     REQ_unmap_view,
     REQ_get_mapping_committed_range,
     REQ_add_mapping_committed_range,
+    REQ_is_same_mapping,
     REQ_create_snapshot,
     REQ_next_process,
     REQ_next_thread,
@@ -5955,6 +5970,7 @@ union generic_request
     struct unmap_view_request unmap_view_request;
     struct get_mapping_committed_range_request get_mapping_committed_range_request;
     struct add_mapping_committed_range_request add_mapping_committed_range_request;
+    struct is_same_mapping_request is_same_mapping_request;
     struct create_snapshot_request create_snapshot_request;
     struct next_process_request next_process_request;
     struct next_thread_request next_thread_request;
@@ -6246,6 +6262,7 @@ union generic_reply
     struct unmap_view_reply unmap_view_reply;
     struct get_mapping_committed_range_reply get_mapping_committed_range_reply;
     struct add_mapping_committed_range_reply add_mapping_committed_range_reply;
+    struct is_same_mapping_reply is_same_mapping_reply;
     struct create_snapshot_reply create_snapshot_reply;
     struct next_process_reply next_process_reply;
     struct next_thread_reply next_thread_reply;
@@ -6446,6 +6463,6 @@ union generic_reply
     struct terminate_job_reply terminate_job_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 539
+#define SERVER_PROTOCOL_VERSION 540
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/mapping.c b/server/mapping.c
index 03cffd1..b7ddbf5 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -961,3 +961,16 @@ DECL_HANDLER(add_mapping_committed_range)
 
     if (view) add_committed_range( view, req->offset, req->offset + req->size );
 }
+
+/* check if two memory maps are for the same file */
+DECL_HANDLER(is_same_mapping)
+{
+    struct memory_view *view1 = find_mapped_view( current->process, req->base1 );
+    struct memory_view *view2 = find_mapped_view( current->process, req->base2 );
+
+    if (!view1 || !view2) return;
+    if (!view1->fd || !view2->fd ||
+        !(view1->flags & SEC_IMAGE) || !(view2->flags & SEC_IMAGE) ||
+        !is_same_file_fd( view1->fd, view2->fd ))
+        set_error( STATUS_NOT_SAME_DEVICE );
+}
diff --git a/server/protocol.def b/server/protocol.def
index ed0cf7d..dd18031 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -1760,6 +1760,13 @@ enum char_info_mode
 @END
 
 
+/* Check if two memory maps are for the same file */
+ at REQ(is_same_mapping)
+    client_ptr_t base1;         /* first view base address */
+    client_ptr_t base2;         /* second view base address */
+ at END
+
+
 #define SNAP_PROCESS    0x00000001
 #define SNAP_THREAD     0x00000002
 /* Create a snapshot */
diff --git a/server/request.h b/server/request.h
index 10a708e..69fbfd3 100644
--- a/server/request.h
+++ b/server/request.h
@@ -200,6 +200,7 @@ DECL_HANDLER(map_view);
 DECL_HANDLER(unmap_view);
 DECL_HANDLER(get_mapping_committed_range);
 DECL_HANDLER(add_mapping_committed_range);
+DECL_HANDLER(is_same_mapping);
 DECL_HANDLER(create_snapshot);
 DECL_HANDLER(next_process);
 DECL_HANDLER(next_thread);
@@ -492,6 +493,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
     (req_handler)req_unmap_view,
     (req_handler)req_get_mapping_committed_range,
     (req_handler)req_add_mapping_committed_range,
+    (req_handler)req_is_same_mapping,
     (req_handler)req_create_snapshot,
     (req_handler)req_next_process,
     (req_handler)req_next_thread,
@@ -1288,6 +1290,9 @@ C_ASSERT( FIELD_OFFSET(struct add_mapping_committed_range_request, base) == 16 )
 C_ASSERT( FIELD_OFFSET(struct add_mapping_committed_range_request, offset) == 24 );
 C_ASSERT( FIELD_OFFSET(struct add_mapping_committed_range_request, size) == 32 );
 C_ASSERT( sizeof(struct add_mapping_committed_range_request) == 40 );
+C_ASSERT( FIELD_OFFSET(struct is_same_mapping_request, base1) == 16 );
+C_ASSERT( FIELD_OFFSET(struct is_same_mapping_request, base2) == 24 );
+C_ASSERT( sizeof(struct is_same_mapping_request) == 32 );
 C_ASSERT( FIELD_OFFSET(struct create_snapshot_request, attributes) == 12 );
 C_ASSERT( FIELD_OFFSET(struct create_snapshot_request, flags) == 16 );
 C_ASSERT( sizeof(struct create_snapshot_request) == 24 );
diff --git a/server/trace.c b/server/trace.c
index a3acdab..0f034fa 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -2276,6 +2276,12 @@ static void dump_add_mapping_committed_range_request( const struct add_mapping_c
     dump_uint64( ", size=", &req->size );
 }
 
+static void dump_is_same_mapping_request( const struct is_same_mapping_request *req )
+{
+    dump_uint64( " base1=", &req->base1 );
+    dump_uint64( ", base2=", &req->base2 );
+}
+
 static void dump_create_snapshot_request( const struct create_snapshot_request *req )
 {
     fprintf( stderr, " attributes=%08x", req->attributes );
@@ -4571,6 +4577,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_unmap_view_request,
     (dump_func)dump_get_mapping_committed_range_request,
     (dump_func)dump_add_mapping_committed_range_request,
+    (dump_func)dump_is_same_mapping_request,
     (dump_func)dump_create_snapshot_request,
     (dump_func)dump_next_process_request,
     (dump_func)dump_next_thread_request,
@@ -4860,6 +4867,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
     NULL,
     (dump_func)dump_get_mapping_committed_range_reply,
     NULL,
+    NULL,
     (dump_func)dump_create_snapshot_reply,
     (dump_func)dump_next_process_reply,
     (dump_func)dump_next_thread_reply,
@@ -5149,6 +5157,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
     "unmap_view",
     "get_mapping_committed_range",
     "add_mapping_committed_range",
+    "is_same_mapping",
     "create_snapshot",
     "next_process",
     "next_thread",
@@ -5429,6 +5438,7 @@ static const struct
     { "NOT_IMPLEMENTED",             STATUS_NOT_IMPLEMENTED },
     { "NOT_MAPPED_VIEW",             STATUS_NOT_MAPPED_VIEW },
     { "NOT_REGISTRY_FILE",           STATUS_NOT_REGISTRY_FILE },
+    { "NOT_SAME_DEVICE",             STATUS_NOT_SAME_DEVICE },
     { "NOT_SUPPORTED",               STATUS_NOT_SUPPORTED },
     { "NO_DATA_DETECTED",            STATUS_NO_DATA_DETECTED },
     { "NO_IMPERSONATION_TOKEN",      STATUS_NO_IMPERSONATION_TOKEN },




More information about the wine-cvs mailing list