From aa90910e93f568d9e8814996bff46614fbefdc22 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 26 Sep 2017 14:55:13 +0200 Subject: [PATCH] server: Implement NtAreMappedFilesTheSame functionality on the server side. Signed-off-by: Alexandre Julliard --- 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 d6ccddc3e6e..c2492d9faac 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 ff0cb1e73c9..5e42e1aa01c 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 03cffd1db95..b7ddbf506ed 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 ed0cf7d6981..dd180313e7c 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 */ +@REQ(is_same_mapping) + client_ptr_t base1; /* first view base address */ + client_ptr_t base2; /* second view base address */ +@END + + #define SNAP_PROCESS 0x00000001 #define SNAP_THREAD 0x00000002 /* Create a snapshot */ diff --git a/server/request.h b/server/request.h index 10a708e31cf..69fbfd36bac 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 a3acdab0971..0f034fa6986 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 }, -- 2.11.4.GIT