ntdll: Add a partial implementation of NtMapViewOfSectionEx().
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
bc69f50575
commit
dc5d76b3af
|
@ -253,6 +253,7 @@
|
|||
# @ stub NtMapUserPhysicalPages
|
||||
# @ stub NtMapUserPhysicalPagesScatter
|
||||
@ stdcall -syscall NtMapViewOfSection(long long ptr long long ptr ptr long long long)
|
||||
@ stdcall -syscall NtMapViewOfSectionEx(long long ptr ptr ptr long long ptr long)
|
||||
# @ stub NtModifyBootEntry
|
||||
@ stdcall -syscall NtNotifyChangeDirectoryFile(long long ptr ptr ptr ptr long long long)
|
||||
@ stdcall -syscall NtNotifyChangeKey(long long ptr ptr ptr long long ptr long long)
|
||||
|
@ -1279,6 +1280,7 @@
|
|||
# @ stub ZwMapUserPhysicalPages
|
||||
# @ stub ZwMapUserPhysicalPagesScatter
|
||||
@ stdcall -private -syscall ZwMapViewOfSection(long long ptr long long ptr ptr long long long) NtMapViewOfSection
|
||||
@ stdcall -private -syscall ZwMapViewOfSectionEx(long long ptr ptr ptr long long ptr long) NtMapViewOfSectionEx
|
||||
# @ stub ZwModifyBootEntry
|
||||
@ stdcall -private -syscall ZwNotifyChangeDirectoryFile(long long ptr ptr ptr ptr long long long) NtNotifyChangeDirectoryFile
|
||||
@ stdcall -private -syscall ZwNotifyChangeKey(long long ptr ptr ptr long long ptr long long) NtNotifyChangeKey
|
||||
|
|
|
@ -39,6 +39,9 @@ static void * (WINAPI *pRtlFindExportedRoutineByName)(HMODULE,const char*);
|
|||
static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
|
||||
static NTSTATUS (WINAPI *pNtAllocateVirtualMemoryEx)(HANDLE, PVOID *, SIZE_T *, ULONG, ULONG,
|
||||
MEM_EXTENDED_PARAMETER *, ULONG);
|
||||
static NTSTATUS (WINAPI *pNtMapViewOfSectionEx)(HANDLE, HANDLE, PVOID *, const LARGE_INTEGER *, SIZE_T *,
|
||||
ULONG, ULONG, MEM_EXTENDED_PARAMETER *, ULONG);
|
||||
|
||||
static const BOOL is_win64 = sizeof(void*) != sizeof(int);
|
||||
static BOOL is_wow64;
|
||||
|
||||
|
@ -908,6 +911,150 @@ static void test_NtMapViewOfSection(void)
|
|||
CloseHandle(process);
|
||||
}
|
||||
|
||||
static void test_NtMapViewOfSectionEx(void)
|
||||
{
|
||||
static const char testfile[] = "testfile.xxx";
|
||||
static const char data[] = "test data for NtMapViewOfSectionEx";
|
||||
char buffer[sizeof(data)];
|
||||
HANDLE file, mapping, process;
|
||||
DWORD status, written;
|
||||
SIZE_T size, result;
|
||||
LARGE_INTEGER offset;
|
||||
void *ptr, *ptr2;
|
||||
BOOL ret;
|
||||
|
||||
if (!pNtMapViewOfSectionEx)
|
||||
{
|
||||
win_skip("NtMapViewOfSectionEx() is not supported.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pIsWow64Process || !pIsWow64Process(NtCurrentProcess(), &is_wow64)) is_wow64 = FALSE;
|
||||
|
||||
file = CreateFileA(testfile, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
|
||||
ok(file != INVALID_HANDLE_VALUE, "Failed to create test file\n");
|
||||
WriteFile(file, data, sizeof(data), &written, NULL);
|
||||
SetFilePointer(file, 4096, NULL, FILE_BEGIN);
|
||||
SetEndOfFile(file);
|
||||
|
||||
/* read/write mapping */
|
||||
|
||||
mapping = CreateFileMappingA(file, NULL, PAGE_READWRITE, 0, 4096, NULL);
|
||||
ok(mapping != 0, "CreateFileMapping failed\n");
|
||||
|
||||
process = create_target_process("sleep");
|
||||
ok(process != NULL, "Can't start process\n");
|
||||
|
||||
ptr = NULL;
|
||||
size = 0;
|
||||
offset.QuadPart = 0;
|
||||
status = pNtMapViewOfSectionEx(mapping, process, &ptr, &offset, &size, 0, PAGE_READWRITE, NULL, 0);
|
||||
ok(status == STATUS_SUCCESS, "Unexpected status %08lx\n", status);
|
||||
ok(!((ULONG_PTR)ptr & 0xffff), "returned memory %p is not aligned to 64k\n", ptr);
|
||||
|
||||
ret = ReadProcessMemory(process, ptr, buffer, sizeof(buffer), &result);
|
||||
ok(ret, "ReadProcessMemory failed\n");
|
||||
ok(result == sizeof(buffer), "ReadProcessMemory didn't read all data (%Ix)\n", result);
|
||||
ok(!memcmp(buffer, data, sizeof(buffer)), "Wrong data read\n");
|
||||
|
||||
/* mapping at the same page conflicts */
|
||||
ptr2 = ptr;
|
||||
size = 0;
|
||||
offset.QuadPart = 0;
|
||||
status = pNtMapViewOfSectionEx(mapping, process, &ptr2, &offset, &size, 0, PAGE_READWRITE, NULL, 0);
|
||||
ok(status == STATUS_CONFLICTING_ADDRESSES, "Unexpected status %08lx\n", status);
|
||||
|
||||
/* offset has to be aligned */
|
||||
ptr2 = ptr;
|
||||
size = 0;
|
||||
offset.QuadPart = 1;
|
||||
status = pNtMapViewOfSectionEx(mapping, process, &ptr2, &offset, &size, 0, PAGE_READWRITE, NULL, 0);
|
||||
ok(status == STATUS_MAPPED_ALIGNMENT, "Unexpected status %08lx\n", status);
|
||||
|
||||
/* ptr has to be aligned */
|
||||
ptr2 = (char *)ptr + 42;
|
||||
size = 0;
|
||||
offset.QuadPart = 0;
|
||||
status = pNtMapViewOfSectionEx(mapping, process, &ptr2, &offset, &size, 0, PAGE_READWRITE, NULL, 0);
|
||||
ok(status == STATUS_MAPPED_ALIGNMENT, "Unexpected status %08lx\n", status);
|
||||
|
||||
/* still not 64k aligned */
|
||||
ptr2 = (char *)ptr + 0x1000;
|
||||
size = 0;
|
||||
offset.QuadPart = 0;
|
||||
status = pNtMapViewOfSectionEx(mapping, process, &ptr2, &offset, &size, 0, PAGE_READWRITE, NULL, 0);
|
||||
ok(status == STATUS_MAPPED_ALIGNMENT, "Unexpected status %08lx\n", status);
|
||||
|
||||
if (!is_win64 && !is_wow64)
|
||||
{
|
||||
/* new memory region conflicts with previous mapping */
|
||||
ptr2 = ptr;
|
||||
size = 0;
|
||||
offset.QuadPart = 0;
|
||||
status = pNtMapViewOfSectionEx(mapping, process, &ptr2, &offset, &size, AT_ROUND_TO_PAGE, PAGE_READWRITE, NULL, 0);
|
||||
ok(status == STATUS_CONFLICTING_ADDRESSES, "Unexpected status %08lx\n", status);
|
||||
|
||||
ptr2 = (char *)ptr + 42;
|
||||
size = 0;
|
||||
offset.QuadPart = 0;
|
||||
status = pNtMapViewOfSectionEx(mapping, process, &ptr2, &offset, &size, AT_ROUND_TO_PAGE, PAGE_READWRITE, NULL, 0);
|
||||
ok(status == STATUS_CONFLICTING_ADDRESSES, "Unexpected status %08lx\n", status);
|
||||
|
||||
/* in contrary to regular NtMapViewOfSection, only 4kb align is enforced */
|
||||
ptr2 = (char *)ptr + 0x1000;
|
||||
size = 0;
|
||||
offset.QuadPart = 0;
|
||||
status = pNtMapViewOfSectionEx(mapping, process, &ptr2, &offset, &size, AT_ROUND_TO_PAGE, PAGE_READWRITE, NULL, 0);
|
||||
ok(status == STATUS_SUCCESS, "Unexpected status %08lx\n", status);
|
||||
ok((char *)ptr2 == (char *)ptr + 0x1000,
|
||||
"expected address %p, got %p\n", (char *)ptr + 0x1000, ptr2);
|
||||
status = NtUnmapViewOfSection(process, ptr2);
|
||||
ok(status == STATUS_SUCCESS, "NtUnmapViewOfSection returned %08lx\n", status);
|
||||
|
||||
/* the address is rounded down if not on a page boundary */
|
||||
ptr2 = (char *)ptr + 0x1001;
|
||||
size = 0;
|
||||
offset.QuadPart = 0;
|
||||
status = pNtMapViewOfSectionEx(mapping, process, &ptr2, &offset, &size, AT_ROUND_TO_PAGE, PAGE_READWRITE, NULL, 0);
|
||||
ok(status == STATUS_SUCCESS, "Unexpected status %08lx\n", status);
|
||||
ok((char *)ptr2 == (char *)ptr + 0x1000,
|
||||
"expected address %p, got %p\n", (char *)ptr + 0x1000, ptr2);
|
||||
status = NtUnmapViewOfSection(process, ptr2);
|
||||
ok(status == STATUS_SUCCESS, "NtUnmapViewOfSection returned %08lx\n", status);
|
||||
|
||||
ptr2 = (char *)ptr + 0x2000;
|
||||
size = 0;
|
||||
offset.QuadPart = 0;
|
||||
status = pNtMapViewOfSectionEx(mapping, process, &ptr2, &offset, &size, AT_ROUND_TO_PAGE, PAGE_READWRITE, NULL, 0);
|
||||
ok(status == STATUS_SUCCESS, "Unexpected status %08lx\n", status);
|
||||
ok((char *)ptr2 == (char *)ptr + 0x2000,
|
||||
"expected address %p, got %p\n", (char *)ptr + 0x2000, ptr2);
|
||||
status = NtUnmapViewOfSection(process, ptr2);
|
||||
ok(status == STATUS_SUCCESS, "NtUnmapViewOfSection returned %08lx\n", status);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr2 = (char *)ptr + 0x1000;
|
||||
size = 0;
|
||||
offset.QuadPart = 0;
|
||||
status = pNtMapViewOfSectionEx(mapping, process, &ptr2, &offset, &size, AT_ROUND_TO_PAGE, PAGE_READWRITE, NULL, 0);
|
||||
todo_wine
|
||||
ok(status == STATUS_INVALID_PARAMETER_9 || status == STATUS_INVALID_PARAMETER,
|
||||
"NtMapViewOfSection returned %08lx\n", status);
|
||||
}
|
||||
|
||||
status = NtUnmapViewOfSection(process, ptr);
|
||||
ok(status == STATUS_SUCCESS, "NtUnmapViewOfSection returned %08lx\n", status);
|
||||
|
||||
NtClose(mapping);
|
||||
|
||||
CloseHandle(file);
|
||||
DeleteFileA(testfile);
|
||||
|
||||
TerminateProcess(process, 0);
|
||||
CloseHandle(process);
|
||||
}
|
||||
|
||||
#define SUPPORTED_XSTATE_FEATURES ((1 << XSTATE_LEGACY_FLOATING_POINT) | (1 << XSTATE_LEGACY_SSE) | (1 << XSTATE_AVX))
|
||||
|
||||
static void test_user_shared_data(void)
|
||||
|
@ -1160,6 +1307,7 @@ START_TEST(virtual)
|
|||
pRtlFindExportedRoutineByName = (void *)GetProcAddress(mod, "RtlFindExportedRoutineByName");
|
||||
pRtlGetEnabledExtendedFeatures = (void *)GetProcAddress(mod, "RtlGetEnabledExtendedFeatures");
|
||||
pNtAllocateVirtualMemoryEx = (void *)GetProcAddress(mod, "NtAllocateVirtualMemoryEx");
|
||||
pNtMapViewOfSectionEx = (void *)GetProcAddress(mod, "NtMapViewOfSectionEx");
|
||||
|
||||
NtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi), NULL);
|
||||
trace("system page size %#lx\n", sbi.PageSize);
|
||||
|
@ -1169,6 +1317,7 @@ START_TEST(virtual)
|
|||
test_NtAllocateVirtualMemory();
|
||||
test_RtlCreateUserStack();
|
||||
test_NtMapViewOfSection();
|
||||
test_NtMapViewOfSectionEx();
|
||||
test_user_shared_data();
|
||||
test_syscalls();
|
||||
}
|
||||
|
|
|
@ -207,6 +207,7 @@ static void * const syscalls[] =
|
|||
NtLockVirtualMemory,
|
||||
NtMakeTemporaryObject,
|
||||
NtMapViewOfSection,
|
||||
NtMapViewOfSectionEx,
|
||||
NtNotifyChangeDirectoryFile,
|
||||
NtNotifyChangeKey,
|
||||
NtNotifyChangeMultipleKeys,
|
||||
|
|
|
@ -4536,6 +4536,18 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
|
|||
offset_ptr, size_ptr, alloc_type, protect );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NtMapViewOfSectionEx (NTDLL.@)
|
||||
* ZwMapViewOfSectionEx (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtMapViewOfSectionEx( HANDLE handle, HANDLE process, PVOID *addr_ptr, const LARGE_INTEGER *offset_ptr,
|
||||
SIZE_T *size_ptr, ULONG alloc_type, ULONG protect, MEM_EXTENDED_PARAMETER *params, ULONG params_count )
|
||||
{
|
||||
if (params)
|
||||
FIXME("Ignoring extended parameters.\n");
|
||||
|
||||
return NtMapViewOfSection( handle, process, addr_ptr, 0, 0, offset_ptr, size_ptr, ViewShare, alloc_type, protect );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NtUnmapViewOfSection (NTDLL.@)
|
||||
|
|
|
@ -108,6 +108,7 @@
|
|||
SYSCALL_ENTRY( NtLockVirtualMemory ) \
|
||||
SYSCALL_ENTRY( NtMakeTemporaryObject ) \
|
||||
SYSCALL_ENTRY( NtMapViewOfSection ) \
|
||||
SYSCALL_ENTRY( NtMapViewOfSectionEx ) \
|
||||
SYSCALL_ENTRY( NtNotifyChangeDirectoryFile ) \
|
||||
SYSCALL_ENTRY( NtNotifyChangeKey ) \
|
||||
SYSCALL_ENTRY( NtNotifyChangeMultipleKeys ) \
|
||||
|
|
|
@ -287,6 +287,40 @@ NTSTATUS WINAPI wow64_NtMapViewOfSection( UINT *args )
|
|||
return status;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* wow64_NtMapViewOfSectionEx
|
||||
*/
|
||||
NTSTATUS WINAPI wow64_NtMapViewOfSectionEx( UINT *args )
|
||||
{
|
||||
HANDLE handle = get_handle( &args );
|
||||
HANDLE process = get_handle( &args );
|
||||
ULONG *addr32 = get_ptr( &args );
|
||||
const LARGE_INTEGER *offset = get_ptr( &args );
|
||||
ULONG *size32 = get_ptr( &args );
|
||||
ULONG alloc = get_ulong( &args );
|
||||
ULONG protect = get_ulong( &args );
|
||||
MEM_EXTENDED_PARAMETER *params = get_ptr( &args );
|
||||
ULONG params_count = get_ulong( &args );
|
||||
|
||||
void *addr;
|
||||
SIZE_T size;
|
||||
NTSTATUS status;
|
||||
|
||||
status = NtMapViewOfSectionEx( handle, process, addr_32to64( &addr, addr32 ), offset, size_32to64( &size, size32 ), alloc,
|
||||
protect, params, params_count );
|
||||
if (NT_SUCCESS(status))
|
||||
{
|
||||
SECTION_IMAGE_INFORMATION info;
|
||||
|
||||
if (!NtQuerySection( handle, SectionImageInformation, &info, sizeof(info), NULL ))
|
||||
{
|
||||
if (info.Machine == current_machine) init_image_mapping( addr );
|
||||
}
|
||||
put_addr( addr32, addr );
|
||||
put_size( size32, size );
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* wow64_NtProtectVirtualMemory
|
||||
|
|
|
@ -4007,6 +4007,7 @@ NTSYSAPI NTSTATUS WINAPI NtLockFile(HANDLE,HANDLE,PIO_APC_ROUTINE,void*,PIO_STA
|
|||
NTSYSAPI NTSTATUS WINAPI NtLockVirtualMemory(HANDLE,PVOID*,SIZE_T*,ULONG);
|
||||
NTSYSAPI NTSTATUS WINAPI NtMakeTemporaryObject(HANDLE);
|
||||
NTSYSAPI NTSTATUS WINAPI NtMapViewOfSection(HANDLE,HANDLE,PVOID*,ULONG_PTR,SIZE_T,const LARGE_INTEGER*,SIZE_T*,SECTION_INHERIT,ULONG,ULONG);
|
||||
NTSYSAPI NTSTATUS WINAPI NtMapViewOfSectionEx(HANDLE,HANDLE,PVOID*,const LARGE_INTEGER*,SIZE_T*,ULONG,ULONG,MEM_EXTENDED_PARAMETER*,ULONG);
|
||||
NTSYSAPI NTSTATUS WINAPI NtNotifyChangeDirectoryFile(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,PVOID,ULONG,ULONG,BOOLEAN);
|
||||
NTSYSAPI NTSTATUS WINAPI NtNotifyChangeKey(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,ULONG,BOOLEAN,PVOID,ULONG,BOOLEAN);
|
||||
NTSYSAPI NTSTATUS WINAPI NtNotifyChangeMultipleKeys(HANDLE,ULONG,OBJECT_ATTRIBUTES*,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,ULONG,BOOLEAN,PVOID,ULONG,BOOLEAN);
|
||||
|
|
Loading…
Reference in New Issue