Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/psapi/tests/psapi_main.c | 156 ++++++++++++++++++++++++++++------ 1 file changed, 128 insertions(+), 28 deletions(-)
diff --git a/dlls/psapi/tests/psapi_main.c b/dlls/psapi/tests/psapi_main.c index c4a740310a4..e383168fde1 100644 --- a/dlls/psapi/tests/psapi_main.c +++ b/dlls/psapi/tests/psapi_main.c @@ -55,7 +55,7 @@ static BOOL init_func_ptrs(void) return TRUE; }
-static HANDLE hpSR, hpQI, hpVR, hpQV; +static HANDLE hpSR, hpQI, hpVR, hpQV, hp_vm_op; static const HANDLE hBad = (HANDLE)0xdeadbeef;
static void test_EnumProcesses(void) @@ -693,14 +693,65 @@ static void test_GetModuleBaseName(void) "szModPath="%s" szModBaseName="%s"\n", szModPath, szModBaseName); }
+static PSAPI_WS_WATCH_INFORMATION wswi[4096]; + +static void ws_get_watches(void) +{ + BOOL ret; + + SetLastError(0xdeadbeef); + ret = GetWsChanges(hpQI, wswi, sizeof(wswi)); + ok(ret == 1, "Got unexpected ret %u, error %u.\n", ret, GetLastError()); +} + +#define ws_watch_check_page(a, b, c, d) ws_watch_check_page_(__LINE__, a, b, c, d) +static void ws_watch_check_page_(unsigned int line, void *addr, void *pc_start, void *pc_end, BOOL expect) +{ + static const ULONG_PTR mask = ~(ULONG_PTR)0xfff; + unsigned int i; + + for(i = 0; wswi[i].FaultingVa; i++) + { + if (((ULONG_PTR)wswi[i].FaultingVa & mask) == ((ULONG_PTR)addr & mask)) + { + ok_(__FILE__, line)(expect, "Got unexpected FaultingVa %p.\n", wswi[i].FaultingVa); + if (expect) + { + ok_(__FILE__, line)((void *)wswi[i].FaultingVa == addr, "Got unexpected addr %p, expected %p.\n", + (void *)wswi[i].FaultingVa, addr); + } + ok_(__FILE__, line)(wswi[i].FaultingPc >= pc_start && wswi[i].FaultingPc < pc_end, + "Got unexpected FaultingPc %p, start %p.\n", wswi[i].FaultingPc, pc_start); + return; + } + } + ok_(__FILE__, line)(!expect, "Page not found.\n"); +} + static void test_ws_functions(void) { - PSAPI_WS_WATCH_INFORMATION wswi[4096]; + static const BOOL is_win32 = sizeof(void *) == sizeof(int); + static const unsigned int page_count = 16; + void *kernel_start, *kernel_end; + unsigned int value; HANDLE ws_handle; - char *addr; unsigned int i; + HANDLE file; + DWORD size; + char *addr; BOOL ret;
+ if (is_win32) + { + kernel_start = (void *)0x80000000; + kernel_end = (void *)0xffffffff; + } + else + { + kernel_start = (void *)0xffff000000000000; + kernel_end = (void *)0xffffffffffffffff; + } + ws_handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_SET_QUOTA | PROCESS_SET_INFORMATION, FALSE, GetCurrentProcessId()); ok(!!ws_handle, "got error %u\n", GetLastError()); @@ -717,6 +768,10 @@ static void test_ws_functions(void) ret = EmptyWorkingSet(ws_handle); ok(ret == 1, "failed with %d\n", GetLastError());
+ addr = VirtualAlloc(NULL, page_count * 0x1000, MEM_COMMIT, PAGE_READWRITE); + ok(!!addr, "VirtualAlloc failed, error %u.\n", GetLastError()); + addr[0x1002] = 0; + SetLastError( 0xdeadbeef ); ret = InitializeProcessForWsWatch( NULL ); todo_wine ok( !ret, "InitializeProcessForWsWatch succeeded\n" ); @@ -732,35 +787,77 @@ static void test_ws_functions(void) SetLastError(0xdeadbeef); ret = InitializeProcessForWsWatch(ws_handle); ok(ret == 1, "failed with %d\n", GetLastError()); - - addr = VirtualAlloc(NULL, 1, MEM_COMMIT, PAGE_READWRITE); - if(!addr) + + ret = GetWsChanges(hpQI, wswi, sizeof(wswi)); + todo_wine ok(ret == 1 || (!ret && GetLastError() == ERROR_NO_MORE_ITEMS), "failed with %d\n", GetLastError()); + if (!ret && GetLastError() != ERROR_NO_MORE_ITEMS) return;
- *addr = 0; /* make sure it's paged in (needed on wow64) */ - if(!VirtualLock(addr, 1)) - { - trace("locking failed (error=%d) - skipping test\n", GetLastError()); - goto free_page; - } + file = CreateFileA("test.tmp", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL); + ok(file != INVALID_HANDLE_VALUE, "CreateFile failed, GetLastError() %u.\n", GetLastError()); + ws_get_watches(); + + ws_watch_check_page(addr + 0x1003, test_ws_functions, (char *)test_ws_functions + 0x10000, FALSE); + + *addr = 0; + addr[0x1002] = 0; + value = addr[0x2fff]; + ok(!value, "Got unexpected value %#x.\n", value); + + ret = ReadProcessMemory(hpVR, addr + 0x3002, &value, sizeof(value), NULL); + ok(ret, "Got unexpected ret %u, error %u.\n", ret, GetLastError()); + ret = WriteProcessMemory(hp_vm_op, addr + 0x4000, &value, 1, NULL); + ok(ret, "Got unexpected ret %u, error %u.\n", ret, GetLastError()); + + ret = WriteFile(file, addr + 0x5000, 1, &size, NULL); + ok(ret, "Got unexpected ret %u, error %u.\n", ret, GetLastError()); + + ret = ReadFile(file, addr + 0x6002, 2, &size, NULL); + ok(ret, "Got unexpected ret %u, error %u.\n", ret, GetLastError()); + ok(!size, "Got unexpected size %u.\n", size); + + ws_get_watches(); + ws_watch_check_page(addr + 1, test_ws_functions, (char *)test_ws_functions + 0x10000, TRUE); + /* Faulted before InitializeProcessForWsWatch(). */ + ws_watch_check_page(addr + 0x1003, NULL, NULL, FALSE); + ws_watch_check_page(addr + 0x2fff, test_ws_functions, (char *)test_ws_functions + 0x10000, TRUE); + ws_watch_check_page(addr + (is_win32 ? 0x3003 : 0x3005), kernel_start, kernel_end, !wow64); + ws_watch_check_page(addr + 0x4001, kernel_start, kernel_end, !wow64); + ws_watch_check_page(addr + 0x5001, kernel_start, kernel_end, !wow64); + ws_watch_check_page(addr + 0x6003, kernel_start, kernel_end, !wow64); + for (i = 7; i < page_count; ++i) + ws_watch_check_page(addr + 0x1000 * i, NULL, NULL, FALSE); + + ret = VirtualFree(addr, page_count * 0x1000, MEM_DECOMMIT); + ok(ret, "Got unexpected ret %u, error %u.\n", ret, GetLastError()); + + addr = VirtualAlloc(addr, page_count * 0x1000, MEM_COMMIT, PAGE_READWRITE); + ok(!!addr, "VirtualAlloc failed, error %u.\n", GetLastError()); + + *addr = 0; + addr[0x1000] = 1; + ws_get_watches(); + ws_watch_check_page(addr + 1, test_ws_functions, (char *)test_ws_functions + 0x10000, TRUE); + ws_watch_check_page(addr + 0x1001, test_ws_functions, (char *)test_ws_functions + 0x10000, TRUE); + for (i = 2; i < page_count; ++i) + ws_watch_check_page(addr + 0x1000 * i, NULL, NULL, FALSE); + + ret = VirtualLock(addr, 1); + ok(ret, "Got unexpected ret %u, error %u.\n", ret, GetLastError()); + + ret = EmptyWorkingSet(ws_handle); + ok(ret, "Got unexpected ret %u, error %u.\n", ret, GetLastError()); + *addr = 0; + addr[0x1000] = 1; + ws_get_watches(); + ws_watch_check_page(addr, NULL, NULL, FALSE); + ws_watch_check_page(addr + 0x1001, test_ws_functions, (char *)test_ws_functions + 0x10000, TRUE); + for (i = 2; i < page_count; ++i) + ws_watch_check_page(addr + 0x1000 * i, NULL, NULL, FALSE);
- SetLastError(0xdeadbeef); - ret = GetWsChanges(hpQI, wswi, sizeof(wswi)); - todo_wine ok(ret == 1, "failed with %d\n", GetLastError()); - if(ret == 1) - { - for(i = 0; wswi[i].FaultingVa; i++) - if(((ULONG_PTR)wswi[i].FaultingVa & ~0xfffL) == (ULONG_PTR)addr) - { - todo_wine ok(ret == 1, "GetWsChanges found our page\n"); - goto free_page; - } - - todo_wine ok(0, "GetWsChanges didn't find our page\n"); - } - -free_page: VirtualFree(addr, 0, MEM_RELEASE); + CloseHandle(file); + DeleteFileA("test.tmp"); }
static void check_QueryWorkingSetEx(PVOID addr, const char *desc, DWORD expected_valid, @@ -859,6 +956,9 @@ START_TEST(psapi_main) if (pIsWow64Process) IsWow64Process(GetCurrentProcess(), &wow64);
+ hp_vm_op = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, pid); + ok(!!hp_vm_op, "got error %u\n", GetLastError()); + hpSR = OpenProcess(STANDARD_RIGHTS_REQUIRED, FALSE, pid); ok(!!hpSR, "got error %u\n", GetLastError()); hpQI = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=103669
Your paranoid android.
=== w10pro64_ja (64 bit report) ===
psapi: psapi_main.c:875: Test failed: exe expected Valid=1 but got 0 psapi_main.c:879: Test failed: exe expected Win32Protection=2 but got 0