Alexandre Julliard : ntdll: More complete implementation of NtAreMappedFilesTheSame.

Alexandre Julliard julliard at winehq.org
Tue Oct 19 13:03:48 CDT 2010


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Oct 19 16:14:40 2010 +0200

ntdll: More complete implementation of NtAreMappedFilesTheSame.

---

 dlls/kernel32/tests/virtual.c |   22 ++++++++++++-------
 dlls/ntdll/virtual.c          |   47 ++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 60 insertions(+), 9 deletions(-)

diff --git a/dlls/kernel32/tests/virtual.c b/dlls/kernel32/tests/virtual.c
index d4c4827..e7b0b77 100644
--- a/dlls/kernel32/tests/virtual.c
+++ b/dlls/kernel32/tests/virtual.c
@@ -901,26 +901,21 @@ static void test_NtAreMappedFilesTheSame(void)
     ok( status == STATUS_NOT_SAME_DEVICE, "NtAreMappedFilesTheSame returned %x\n", status );
 
     status = pNtAreMappedFilesTheSame( ptr, (void *)0xdeadbeef );
-    todo_wine
     ok( status == STATUS_CONFLICTING_ADDRESSES || status == STATUS_INVALID_ADDRESS,
         "NtAreMappedFilesTheSame returned %x\n", status );
 
     status = pNtAreMappedFilesTheSame( ptr, NULL );
-    todo_wine
     ok( status == STATUS_INVALID_ADDRESS, "NtAreMappedFilesTheSame returned %x\n", status );
 
-    status = pNtAreMappedFilesTheSame( ptr, (void *)0x10000 );
-    todo_wine
+    status = pNtAreMappedFilesTheSame( ptr, (void *)GetProcessHeap() );
     ok( status == STATUS_CONFLICTING_ADDRESSES, "NtAreMappedFilesTheSame returned %x\n", status );
 
     status = pNtAreMappedFilesTheSame( NULL, NULL );
-    todo_wine
     ok( status == STATUS_INVALID_ADDRESS, "NtAreMappedFilesTheSame returned %x\n", status );
 
     ptr2 = VirtualAlloc( NULL, 0x10000, MEM_COMMIT, PAGE_READWRITE );
     ok( ptr2 != NULL, "VirtualAlloc error %u\n", GetLastError() );
     status = pNtAreMappedFilesTheSame( ptr, ptr2 );
-    todo_wine
     ok( status == STATUS_CONFLICTING_ADDRESSES, "NtAreMappedFilesTheSame returned %x\n", status );
     VirtualFree( ptr2, 0, MEM_RELEASE );
 
@@ -933,11 +928,9 @@ static void test_NtAreMappedFilesTheSame(void)
     ok( status == STATUS_NOT_SAME_DEVICE, "NtAreMappedFilesTheSame returned %x\n", status );
     status = pNtAreMappedFilesTheSame( GetModuleHandleA("kernel32.dll"),
                                        GetModuleHandleA("kernel32.dll") );
-    todo_wine
     ok( status == STATUS_SUCCESS, "NtAreMappedFilesTheSame returned %x\n", status );
     status = pNtAreMappedFilesTheSame( GetModuleHandleA("kernel32.dll"),
                                        (char *)GetModuleHandleA("kernel32.dll") + 4096 );
-    todo_wine
     ok( status == STATUS_SUCCESS, "NtAreMappedFilesTheSame returned %x\n", status );
 
     GetSystemDirectoryA( path, MAX_PATH );
@@ -961,6 +954,19 @@ static void test_NtAreMappedFilesTheSame(void)
     status = pNtAreMappedFilesTheSame( ptr, GetModuleHandleA("kernel32.dll") );
     todo_wine
     ok( status == STATUS_SUCCESS, "NtAreMappedFilesTheSame returned %x\n", status );
+
+    file2 = CreateFileA( path, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 );
+    ok( file2 != INVALID_HANDLE_VALUE, "CreateFile error %u\n", GetLastError() );
+    map2 = CreateFileMappingA( file2, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, NULL );
+    ok( map2 != 0, "CreateFileMapping error %u\n", GetLastError() );
+    ptr2 = MapViewOfFile( map2, FILE_MAP_READ, 0, 0, 0 );
+    ok( ptr2 != NULL, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
+    status = pNtAreMappedFilesTheSame( ptr, ptr2 );
+    ok( status == STATUS_SUCCESS, "NtAreMappedFilesTheSame returned %x\n", status );
+    UnmapViewOfFile( ptr2 );
+    CloseHandle( map2 );
+    CloseHandle( file2 );
+
     UnmapViewOfFile( ptr );
     CloseHandle( mapping );
 
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index 3ab3eb3..a1faabf 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -1013,6 +1013,26 @@ 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.
@@ -2780,7 +2800,32 @@ 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;
+
     TRACE("%p %p\n", addr1, addr2);
 
-    return STATUS_NOT_SAME_DEVICE;
+    server_enter_uninterrupted_section( &csVirtual, &sigset );
+
+    view1 = VIRTUAL_FindView( addr1, 0 );
+    view2 = VIRTUAL_FindView( addr2, 0 );
+
+    if (!view1 || !view2)
+        status = STATUS_INVALID_ADDRESS;
+    else if ((view1->protect & VPROT_VALLOC) || (view2->protect & VPROT_VALLOC))
+        status = STATUS_CONFLICTING_ADDRESSES;
+    else if (!(view1->protect & VPROT_IMAGE) || !(view2->protect & VPROT_IMAGE))
+        status = STATUS_NOT_SAME_DEVICE;
+    else if (view1 == view2)
+        status = STATUS_SUCCESS;
+    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_leave_uninterrupted_section( &csVirtual, &sigset );
+    return status;
 }




More information about the wine-cvs mailing list