ntdll: More complete implementation of NtAreMappedFilesTheSame.

oldstable
Alexandre Julliard 2010-10-19 16:14:40 +02:00
parent 31d37b3489
commit e7c67c0cb1
2 changed files with 60 additions and 9 deletions

View File

@ -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 );

View File

@ -1012,6 +1012,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
*
@ -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;
}