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