[PATCH v5 3/6] ntdll/tests: Move NtMapViewOfSection tests from kernel32/tests
Rémi Bernon
rbernon at codeweavers.com
Thu Jun 20 09:05:36 CDT 2019
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
dlls/kernel32/tests/virtual.c | 198 -----------------------------
dlls/ntdll/tests/virtual.c | 227 ++++++++++++++++++++++++++++++++++
2 files changed, 227 insertions(+), 198 deletions(-)
diff --git a/dlls/kernel32/tests/virtual.c b/dlls/kernel32/tests/virtual.c
index dc013fa2995..402ab6b0b58 100644
--- a/dlls/kernel32/tests/virtual.c
+++ b/dlls/kernel32/tests/virtual.c
@@ -73,20 +73,6 @@ static HANDLE create_target_process(const char *arg)
return pi.hProcess;
}
-static UINT_PTR get_zero_bits(UINT_PTR p)
-{
- UINT_PTR z = 0;
-
-#ifdef __x86_64__
- if (p >= 0xffffffff)
- return (~(UINT_PTR)0) >> get_zero_bits(p >> 32);
-#endif
-
- if (p == 0) return 32;
- while ((p >> (31 - z)) != 1) z++;
- return z;
-}
-
static void test_VirtualAllocEx(void)
{
const unsigned int alloc_size = 1<<15;
@@ -1228,189 +1214,6 @@ static void test_MapViewOfFile(void)
DeleteFileA(testfile);
}
-static void test_NtMapViewOfSection(void)
-{
- HANDLE hProcess;
-
- static const char testfile[] = "testfile.xxx";
- static const char data[] = "test data for NtMapViewOfSection";
- char buffer[sizeof(data)];
- HANDLE file, mapping;
- void *ptr, *ptr2;
- BOOL is_wow64, ret;
- DWORD status, written;
- SIZE_T size, result;
- LARGE_INTEGER offset;
-
- if (!pNtMapViewOfSection || !pNtUnmapViewOfSection)
- {
- win_skip( "NtMapViewOfSection not available\n" );
- return;
- }
-
- 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" );
-
- hProcess = create_target_process("sleep");
- ok(hProcess != NULL, "Can't start process\n");
-
- ptr = NULL;
- size = 0;
- offset.QuadPart = 0;
- status = pNtMapViewOfSection( mapping, hProcess, &ptr, 0, 0, &offset, &size, 1, 0, PAGE_READWRITE );
- ok( !status, "NtMapViewOfSection failed status %x\n", status );
- ok( !((ULONG_PTR)ptr & 0xffff), "returned memory %p is not aligned to 64k\n", ptr );
-
- ret = ReadProcessMemory( hProcess, ptr, buffer, sizeof(buffer), &result );
- ok( ret, "ReadProcessMemory failed\n" );
- ok( result == sizeof(buffer), "ReadProcessMemory didn't read all data (%lx)\n", result );
- ok( !memcmp( buffer, data, sizeof(buffer) ), "Wrong data read\n" );
-
- ptr2 = NULL;
- size = 0;
- offset.QuadPart = 0;
- status = pNtMapViewOfSection( mapping, hProcess, &ptr2, 1, 0, &offset, &size, 1, 0, PAGE_READWRITE );
- ok( status == STATUS_SUCCESS || status == STATUS_NO_MEMORY,
- "NtMapViewOfSection returned %x\n", status );
- if (status == STATUS_SUCCESS)
- {
- status = pNtUnmapViewOfSection( hProcess, ptr2 );
- ok( !status, "NtUnmapViewOfSection failed status %x\n", status );
- }
-
- /* 22 zero bits isn't acceptable */
- ptr2 = NULL;
- size = 0;
- status = pNtMapViewOfSection( mapping, hProcess, &ptr2, 22, 0, &offset, &size, 1, 0, PAGE_READWRITE );
- ok( status == STATUS_INVALID_PARAMETER_4 || status == STATUS_INVALID_PARAMETER,
- "NtMapViewOfSection returned %x\n", status );
-
- /* mapping at the same page conflicts */
- ptr2 = ptr;
- size = 0;
- offset.QuadPart = 0;
- status = pNtMapViewOfSection( mapping, hProcess, &ptr2, 0, 0, &offset, &size, 1, 0, PAGE_READWRITE );
- ok( status == STATUS_CONFLICTING_ADDRESSES, "NtMapViewOfSection returned %x\n", status );
-
- /* offset has to be aligned */
- ptr2 = ptr;
- size = 0;
- offset.QuadPart = 1;
- status = pNtMapViewOfSection( mapping, hProcess, &ptr2, 0, 0, &offset, &size, 1, 0, PAGE_READWRITE );
- ok( status == STATUS_MAPPED_ALIGNMENT, "NtMapViewOfSection returned %x\n", status );
-
- /* ptr has to be aligned */
- ptr2 = (char *)ptr + 42;
- size = 0;
- offset.QuadPart = 0;
- status = pNtMapViewOfSection( mapping, hProcess, &ptr2, 0, 0, &offset, &size, 1, 0, PAGE_READWRITE );
- ok( status == STATUS_MAPPED_ALIGNMENT, "NtMapViewOfSection returned %x\n", status );
-
- /* still not 64k aligned */
- ptr2 = (char *)ptr + 0x1000;
- size = 0;
- offset.QuadPart = 0;
- status = pNtMapViewOfSection( mapping, hProcess, &ptr2, 0, 0, &offset, &size, 1, 0, PAGE_READWRITE );
- ok( status == STATUS_MAPPED_ALIGNMENT, "NtMapViewOfSection returned %x\n", status );
-
- /* when an address is passed, it has to satisfy the provided number of zero bits */
- ptr2 = (char *)ptr + 0x1000;
- size = 0;
- offset.QuadPart = 0;
- status = pNtMapViewOfSection( mapping, hProcess, &ptr2, get_zero_bits(((UINT_PTR)ptr2) >> 1), 0, &offset, &size, 1, 0, PAGE_READWRITE );
- ok( status == STATUS_INVALID_PARAMETER_4 || status == STATUS_INVALID_PARAMETER,
- "NtMapViewOfSection returned %x\n", status );
-
- ptr2 = (char *)ptr + 0x1000;
- size = 0;
- offset.QuadPart = 0;
- status = pNtMapViewOfSection( mapping, hProcess, &ptr2, get_zero_bits((UINT_PTR)ptr2), 0, &offset, &size, 1, 0, PAGE_READWRITE );
- todo_wine
- ok( status == STATUS_MAPPED_ALIGNMENT, "NtMapViewOfSection returned %x\n", status );
-
- if (sizeof(void *) == sizeof(int) && (!pIsWow64Process ||
- !pIsWow64Process( GetCurrentProcess(), &is_wow64 ) || !is_wow64))
- {
- /* new memory region conflicts with previous mapping */
- ptr2 = ptr;
- size = 0;
- offset.QuadPart = 0;
- status = pNtMapViewOfSection( mapping, hProcess, &ptr2, 0, 0, &offset,
- &size, 1, AT_ROUND_TO_PAGE, PAGE_READWRITE );
- ok( status == STATUS_CONFLICTING_ADDRESSES, "NtMapViewOfSection returned %x\n", status );
-
- ptr2 = (char *)ptr + 42;
- size = 0;
- offset.QuadPart = 0;
- status = pNtMapViewOfSection( mapping, hProcess, &ptr2, 0, 0, &offset,
- &size, 1, AT_ROUND_TO_PAGE, PAGE_READWRITE );
- ok( status == STATUS_CONFLICTING_ADDRESSES, "NtMapViewOfSection returned %x\n", status );
-
- /* in contrary to regular NtMapViewOfSection, only 4kb align is enforced */
- ptr2 = (char *)ptr + 0x1000;
- size = 0;
- offset.QuadPart = 0;
- status = pNtMapViewOfSection( mapping, hProcess, &ptr2, 0, 0, &offset,
- &size, 1, AT_ROUND_TO_PAGE, PAGE_READWRITE );
- ok( status == STATUS_SUCCESS, "NtMapViewOfSection returned %x\n", status );
- ok( (char *)ptr2 == (char *)ptr + 0x1000,
- "expected address %p, got %p\n", (char *)ptr + 0x1000, ptr2 );
- status = pNtUnmapViewOfSection( hProcess, ptr2 );
- ok( !status, "NtUnmapViewOfSection failed status %x\n", status );
-
- /* the address is rounded down if not on a page boundary */
- ptr2 = (char *)ptr + 0x1001;
- size = 0;
- offset.QuadPart = 0;
- status = pNtMapViewOfSection( mapping, hProcess, &ptr2, 0, 0, &offset,
- &size, 1, AT_ROUND_TO_PAGE, PAGE_READWRITE );
- ok( status == STATUS_SUCCESS, "NtMapViewOfSection returned %x\n", status );
- ok( (char *)ptr2 == (char *)ptr + 0x1000,
- "expected address %p, got %p\n", (char *)ptr + 0x1000, ptr2 );
- status = pNtUnmapViewOfSection( hProcess, ptr2 );
- ok( !status, "NtUnmapViewOfSection failed status %x\n", status );
-
- ptr2 = (char *)ptr + 0x2000;
- size = 0;
- offset.QuadPart = 0;
- status = pNtMapViewOfSection( mapping, hProcess, &ptr2, 0, 0, &offset,
- &size, 1, AT_ROUND_TO_PAGE, PAGE_READWRITE );
- ok( status == STATUS_SUCCESS, "NtMapViewOfSection returned %x\n", status );
- ok( (char *)ptr2 == (char *)ptr + 0x2000,
- "expected address %p, got %p\n", (char *)ptr + 0x2000, ptr2 );
- status = pNtUnmapViewOfSection( hProcess, ptr2 );
- ok( !status, "NtUnmapViewOfSection failed status %x\n", status );
- }
- else
- {
- ptr2 = (char *)ptr + 0x1000;
- size = 0;
- offset.QuadPart = 0;
- status = pNtMapViewOfSection( mapping, hProcess, &ptr2, 0, 0, &offset,
- &size, 1, AT_ROUND_TO_PAGE, PAGE_READWRITE );
- todo_wine
- ok( status == STATUS_INVALID_PARAMETER_9 || status == STATUS_INVALID_PARAMETER,
- "NtMapViewOfSection returned %x\n", status );
- }
-
- status = pNtUnmapViewOfSection( hProcess, ptr );
- ok( !status, "NtUnmapViewOfSection failed status %x\n", status );
-
- CloseHandle( mapping );
- CloseHandle( file );
- DeleteFileA( testfile );
-
- TerminateProcess(hProcess, 0);
- CloseHandle(hProcess);
-}
static void test_NtAreMappedFilesTheSame(void)
{
@@ -4395,7 +4198,6 @@ START_TEST(virtual)
test_VirtualAllocEx();
test_VirtualAlloc();
test_MapViewOfFile();
- test_NtMapViewOfSection();
test_NtAreMappedFilesTheSame();
test_CreateFileMapping();
test_IsBadReadPtr();
diff --git a/dlls/ntdll/tests/virtual.c b/dlls/ntdll/tests/virtual.c
index a5477177ce8..5ca73435541 100644
--- a/dlls/ntdll/tests/virtual.c
+++ b/dlls/ntdll/tests/virtual.c
@@ -32,6 +32,38 @@ static NTSTATUS (WINAPI *pRtlCreateUserStack)(SIZE_T, SIZE_T, ULONG, SIZE_T, SIZ
static NTSTATUS (WINAPI *pRtlFreeUserStack)(void *);
static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
+static HANDLE create_target_process(const char *arg)
+{
+ char **argv;
+ char cmdline[MAX_PATH];
+ PROCESS_INFORMATION pi;
+ BOOL ret;
+ STARTUPINFOA si = { 0 };
+ si.cb = sizeof(si);
+
+ winetest_get_mainargs(&argv);
+ sprintf(cmdline, "%s %s %s", argv[0], argv[1], arg);
+ ret = CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
+ ok(ret, "error: %u\n", GetLastError());
+ ret = CloseHandle(pi.hThread);
+ ok(ret, "error %u\n", GetLastError());
+ return pi.hProcess;
+}
+
+static UINT_PTR get_zero_bits(UINT_PTR p)
+{
+ UINT_PTR z = 0;
+
+#ifdef __x86_64__
+ if (p >= 0xffffffff)
+ return (~(UINT_PTR)0) >> get_zero_bits(p >> 32);
+#endif
+
+ if (p == 0) return 32;
+ while ((p >> (31 - z)) != 1) z++;
+ return z;
+}
+
static void test_NtAllocateVirtualMemory(void)
{
void *addr1, *addr2;
@@ -228,11 +260,205 @@ static void test_RtlCreateUserStack(void)
ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
}
+static void test_NtMapViewOfSection(void)
+{
+ static const char testfile[] = "testfile.xxx";
+ static const char data[] = "test data for NtMapViewOfSection";
+ char buffer[sizeof(data)];
+ HANDLE file, mapping, process;
+ void *ptr, *ptr2;
+ BOOL is_wow64, ret;
+ DWORD status, written;
+ SIZE_T size, result;
+ LARGE_INTEGER offset;
+ ULONG zero_bits;
+
+ 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 = NtMapViewOfSection(mapping, process, &ptr, 0, 0, &offset, &size, 1, 0, PAGE_READWRITE);
+ ok(status == STATUS_SUCCESS, "NtMapViewOfSection returned %08x\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 (%lx)\n", result);
+ ok(!memcmp(buffer, data, sizeof(buffer)), "Wrong data read\n");
+
+ ptr2 = NULL;
+ size = 0;
+ offset.QuadPart = 0;
+ status = NtMapViewOfSection(mapping, process, &ptr2, 1, 0, &offset, &size, 1, 0, PAGE_READWRITE);
+ ok(status == STATUS_SUCCESS || status == STATUS_NO_MEMORY,
+ "NtMapViewOfSection returned %08x\n", status);
+ if (status == STATUS_SUCCESS)
+ {
+ status = NtUnmapViewOfSection(process, ptr2);
+ ok(status == STATUS_SUCCESS, "NtUnmapViewOfSection returned %08x\n", status);
+ }
+
+ /* 22 zero bits isn't acceptable */
+ ptr2 = NULL;
+ size = 0;
+ status = NtMapViewOfSection(mapping, process, &ptr2, 22, 0, &offset, &size, 1, 0, PAGE_READWRITE);
+ ok(status == STATUS_INVALID_PARAMETER_4 || status == STATUS_INVALID_PARAMETER,
+ "NtMapViewOfSection returned %08x\n", status);
+
+ /* mapping at the same page conflicts */
+ ptr2 = ptr;
+ size = 0;
+ offset.QuadPart = 0;
+ status = NtMapViewOfSection(mapping, process, &ptr2, 0, 0, &offset, &size, 1, 0, PAGE_READWRITE);
+ ok(status == STATUS_CONFLICTING_ADDRESSES, "NtMapViewOfSection returned %08x\n", status);
+
+ /* offset has to be aligned */
+ ptr2 = ptr;
+ size = 0;
+ offset.QuadPart = 1;
+ status = NtMapViewOfSection(mapping, process, &ptr2, 0, 0, &offset, &size, 1, 0, PAGE_READWRITE);
+ ok(status == STATUS_MAPPED_ALIGNMENT, "NtMapViewOfSection returned %08x\n", status);
+
+ /* ptr has to be aligned */
+ ptr2 = (char *)ptr + 42;
+ size = 0;
+ offset.QuadPart = 0;
+ status = NtMapViewOfSection(mapping, process, &ptr2, 0, 0, &offset, &size, 1, 0, PAGE_READWRITE);
+ ok(status == STATUS_MAPPED_ALIGNMENT, "NtMapViewOfSection returned %08x\n", status);
+
+ /* still not 64k aligned */
+ ptr2 = (char *)ptr + 0x1000;
+ size = 0;
+ offset.QuadPart = 0;
+ status = NtMapViewOfSection(mapping, process, &ptr2, 0, 0, &offset, &size, 1, 0, PAGE_READWRITE);
+ ok(status == STATUS_MAPPED_ALIGNMENT, "NtMapViewOfSection returned %08x\n", status);
+
+ /* when an address is passed, it has to satisfy the provided number of zero bits */
+ ptr2 = (char *)ptr + 0x1000;
+ size = 0;
+ offset.QuadPart = 0;
+ zero_bits = get_zero_bits(((UINT_PTR)ptr2) >> 1);
+ status = NtMapViewOfSection(mapping, process, &ptr2, zero_bits, 0, &offset, &size, 1, 0, PAGE_READWRITE);
+ ok(status == STATUS_INVALID_PARAMETER_4 || status == STATUS_INVALID_PARAMETER,
+ "NtMapViewOfSection returned %08x\n", status);
+
+ ptr2 = (char *)ptr + 0x1000;
+ size = 0;
+ offset.QuadPart = 0;
+ zero_bits = get_zero_bits((UINT_PTR)ptr2);
+ status = NtMapViewOfSection(mapping, process, &ptr2, zero_bits, 0, &offset, &size, 1, 0, PAGE_READWRITE);
+ todo_wine
+ ok(status == STATUS_MAPPED_ALIGNMENT, "NtMapViewOfSection returned %08x\n", status);
+
+ if (sizeof(void *) == sizeof(int) && (!pIsWow64Process ||
+ !pIsWow64Process(NtCurrentProcess(), &is_wow64) || !is_wow64))
+ {
+ /* new memory region conflicts with previous mapping */
+ ptr2 = ptr;
+ size = 0;
+ offset.QuadPart = 0;
+ status = NtMapViewOfSection(mapping, process, &ptr2, 0, 0, &offset,
+ &size, 1, AT_ROUND_TO_PAGE, PAGE_READWRITE);
+ ok(status == STATUS_CONFLICTING_ADDRESSES, "NtMapViewOfSection returned %08x\n", status);
+
+ ptr2 = (char *)ptr + 42;
+ size = 0;
+ offset.QuadPart = 0;
+ status = NtMapViewOfSection(mapping, process, &ptr2, 0, 0, &offset,
+ &size, 1, AT_ROUND_TO_PAGE, PAGE_READWRITE);
+ ok(status == STATUS_CONFLICTING_ADDRESSES, "NtMapViewOfSection returned %08x\n", status);
+
+ /* in contrary to regular NtMapViewOfSection, only 4kb align is enforced */
+ ptr2 = (char *)ptr + 0x1000;
+ size = 0;
+ offset.QuadPart = 0;
+ status = NtMapViewOfSection(mapping, process, &ptr2, 0, 0, &offset,
+ &size, 1, AT_ROUND_TO_PAGE, PAGE_READWRITE);
+ ok(status == STATUS_SUCCESS, "NtMapViewOfSection returned %08x\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 %08x\n", status);
+
+ /* the address is rounded down if not on a page boundary */
+ ptr2 = (char *)ptr + 0x1001;
+ size = 0;
+ offset.QuadPart = 0;
+ status = NtMapViewOfSection(mapping, process, &ptr2, 0, 0, &offset,
+ &size, 1, AT_ROUND_TO_PAGE, PAGE_READWRITE);
+ ok(status == STATUS_SUCCESS, "NtMapViewOfSection returned %08x\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 %08x\n", status);
+
+ ptr2 = (char *)ptr + 0x2000;
+ size = 0;
+ offset.QuadPart = 0;
+ status = NtMapViewOfSection(mapping, process, &ptr2, 0, 0, &offset,
+ &size, 1, AT_ROUND_TO_PAGE, PAGE_READWRITE);
+ ok(status == STATUS_SUCCESS, "NtMapViewOfSection returned %08x\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 %08x\n", status);
+ }
+ else
+ {
+ ptr2 = (char *)ptr + 0x1000;
+ size = 0;
+ offset.QuadPart = 0;
+ status = NtMapViewOfSection(mapping, process, &ptr2, 0, 0, &offset,
+ &size, 1, AT_ROUND_TO_PAGE, PAGE_READWRITE);
+ todo_wine
+ ok(status == STATUS_INVALID_PARAMETER_9 || status == STATUS_INVALID_PARAMETER,
+ "NtMapViewOfSection returned %08x\n", status);
+ }
+
+ status = NtUnmapViewOfSection(process, ptr);
+ ok(status == STATUS_SUCCESS, "NtUnmapViewOfSection returned %08x\n", status);
+
+ NtClose(mapping);
+
+ CloseHandle(file);
+ DeleteFileA(testfile);
+
+ TerminateProcess(process, 0);
+ CloseHandle(process);
+}
+
START_TEST(virtual)
{
SYSTEM_BASIC_INFORMATION sbi;
HMODULE mod;
+ int argc;
+ char **argv;
+ argc = winetest_get_mainargs(&argv);
+
+ if (argc >= 3)
+ {
+ if (!strcmp(argv[2], "sleep"))
+ {
+ Sleep(5000); /* spawned process runs for at most 5 seconds */
+ return;
+ }
+ return;
+ }
+
mod = GetModuleHandleA("kernel32.dll");
pIsWow64Process = (void *)GetProcAddress(mod, "IsWow64Process");
@@ -246,4 +472,5 @@ START_TEST(virtual)
test_NtAllocateVirtualMemory();
test_RtlCreateUserStack();
+ test_NtMapViewOfSection();
}
--
2.20.1
More information about the wine-devel
mailing list