Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/ntoskrnl.exe/tests/driver.c | 70 ++++++++++++++++++++++++++++++ dlls/ntoskrnl.exe/tests/driver.h | 3 ++ dlls/ntoskrnl.exe/tests/ntoskrnl.c | 10 ++++- 3 files changed, 82 insertions(+), 1 deletion(-)
diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c index ba2b4d6ac8e..6e62990deec 100644 --- a/dlls/ntoskrnl.exe/tests/driver.c +++ b/dlls/ntoskrnl.exe/tests/driver.c @@ -2067,6 +2067,75 @@ static void test_dpc(void) KeRevertToUserAffinityThread(); }
+static void test_process_memory(const struct test_input *test_input) +{ + NTSTATUS (WINAPI *pMmCopyVirtualMemory)(PEPROCESS fromprocess, void *fromaddress, PEPROCESS toprocess, + void *toaddress, SIZE_T bufsize, KPROCESSOR_MODE mode, SIZE_T *copied); + char buffer[sizeof(teststr)]; + ULONG64 modified_value; + PEPROCESS process; + KAPC_STATE state; + NTSTATUS status; + SIZE_T size; + BYTE *base; + + pMmCopyVirtualMemory = get_proc_address("MmCopyVirtualMemory"); + + status = PsLookupProcessByProcessId((HANDLE)(ULONG_PTR)test_input->process_id, &process); + ok(status == STATUS_SUCCESS, "Got unexpected status %#x.\n", status); + + if (status) + return; + +#if 0 + /* Crashes on Windows. */ + PsGetProcessSectionBaseAddress(NULL); +#endif + + base = PsGetProcessSectionBaseAddress(process); + ok(!!base, "Got NULL base address.\n"); + + ok(process == PsGetCurrentProcess(), "Got unexpected process %p, PsGetCurrentProcess() %p.\n", + process, PsGetCurrentProcess()); + + modified_value = 0xdeadbeeffeedcafe; + if (pMmCopyVirtualMemory) + { + size = 0xdeadbeef; + status = pMmCopyVirtualMemory(process, base + test_input->teststr_offset, PsGetCurrentProcess(), + buffer, sizeof(buffer), UserMode, &size); + todo_wine ok(status == STATUS_ACCESS_VIOLATION, "Got unexpected status %#x.\n", status); + ok(!size, "Got unexpected size %#lx.\n", size); + + memset(buffer, 0, sizeof(buffer)); + size = 0xdeadbeef; +#if 0 + /* Passing NULL for the copied size address hangs Windows. */ + pMmCopyVirtualMemory(process, base + test_input->teststr_offset, PsGetCurrentProcess(), + buffer, sizeof(buffer), KernelMode, NULL); +#endif + status = pMmCopyVirtualMemory(process, base + test_input->teststr_offset, PsGetCurrentProcess(), + buffer, sizeof(buffer), KernelMode, &size); + todo_wine ok(status == STATUS_SUCCESS, "Got unexpected status %#x.\n", status); + todo_wine ok(size == sizeof(buffer), "Got unexpected size %lu.\n", size); + todo_wine ok(!strcmp(buffer, teststr), "Got unexpected test string.\n"); + } + else + { + win_skip("MmCopyVirtualMemory is not available.\n"); + } + + if (!test_input->running_under_wine) + { + KeStackAttachProcess((PKPROCESS)process, &state); + todo_wine ok(!strcmp(teststr, (char *)(base + test_input->teststr_offset)), + "Strings do not match.\n"); + *test_input->modified_value = modified_value; + KeUnstackDetachProcess(&state); + } + ObDereferenceObject(process); +} + static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *stack) { ULONG length = stack->Parameters.DeviceIoControl.OutputBufferLength; @@ -2122,6 +2191,7 @@ static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *st #endif test_affinity(); test_dpc(); + test_process_memory(test_input);
if (main_test_work_item) return STATUS_UNEXPECTED_IO_ERROR;
diff --git a/dlls/ntoskrnl.exe/tests/driver.h b/dlls/ntoskrnl.exe/tests/driver.h index aa9de674e2f..6012efc41c8 100644 --- a/dlls/ntoskrnl.exe/tests/driver.h +++ b/dlls/ntoskrnl.exe/tests/driver.h @@ -42,6 +42,9 @@ struct test_input int running_under_wine; int winetest_report_success; int winetest_debug; + DWORD process_id; + SIZE_T teststr_offset; + ULONG64 *modified_value; WCHAR path[1]; };
diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index 2535ed903e7..8d2da92455a 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -148,8 +148,9 @@ static void main_test(void) static const WCHAR dokW[] = {'d','o','k',0}; WCHAR temppathW[MAX_PATH], pathW[MAX_PATH]; struct test_input *test_input; - UNICODE_STRING pathU; DWORD len, written, read; + ULONG64 modified_value; + UNICODE_STRING pathU; LONG new_failures; char buffer[512]; HANDLE okfile; @@ -165,6 +166,11 @@ static void main_test(void) test_input->running_under_wine = !strcmp(winetest_platform, "wine"); test_input->winetest_report_success = winetest_report_success; test_input->winetest_debug = winetest_debug; + test_input->process_id = GetCurrentProcessId(); + test_input->teststr_offset = (SIZE_T)((BYTE *)&teststr - (BYTE *)NtCurrentTeb()->Peb->ImageBaseAddress); + test_input->modified_value = &modified_value; + modified_value = 0; + memcpy(test_input->path, pathU.Buffer, len); res = DeviceIoControl(device, IOCTL_WINETEST_MAIN_TEST, test_input, offsetof( struct test_input, path[len / sizeof(WCHAR)]), @@ -172,6 +178,8 @@ static void main_test(void) ok(res, "DeviceIoControl failed: %u\n", GetLastError()); ok(written == sizeof(new_failures), "got size %x\n", written);
+ todo_wine ok(modified_value == 0xdeadbeeffeedcafe, "Got unexpected value %#I64x.\n", modified_value); + okfile = CreateFileW(pathW, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); ok(okfile != INVALID_HANDLE_VALUE, "failed to create %s: %u\n", wine_dbgstr_w(pathW), GetLastError());