[PATCH] ntdll/tests: Add tests for ProcessWorkingSetWatch[Ex] process info class.

Paul Gofman pgofman at codeweavers.com
Thu Dec 9 05:31:51 CST 2021


Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
---
 dlls/ntdll/tests/virtual.c | 116 +++++++++++++++++++++++++++++++++++++
 1 file changed, 116 insertions(+)

diff --git a/dlls/ntdll/tests/virtual.c b/dlls/ntdll/tests/virtual.c
index adc9b1ae6dc..c41a50c5da7 100644
--- a/dlls/ntdll/tests/virtual.c
+++ b/dlls/ntdll/tests/virtual.c
@@ -24,6 +24,7 @@
 #define WIN32_NO_STATUS
 #include "windef.h"
 #include "winternl.h"
+#include "psapi.h"
 #include "wine/test.h"
 #include "ddk/wdm.h"
 
@@ -1132,6 +1133,120 @@ static void test_syscalls(void)
     UnmapViewOfFile( ptr );
 }
 
+#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 *info, unsigned int info_count, BOOL extended)
+{
+    static const ULONG_PTR mask = ~(ULONG_PTR)0xfff;
+    PSAPI_WS_WATCH_INFORMATION_EX *ws;
+    unsigned int i, size;
+
+    size = extended ? sizeof(PSAPI_WS_WATCH_INFORMATION_EX) : sizeof(PSAPI_WS_WATCH_INFORMATION);
+
+    ok_(__FILE__, line)(info_count, "Got zero info_count.\n");
+    if (!info_count)
+        return;
+    ws = (PSAPI_WS_WATCH_INFORMATION_EX *)((char *)info + size * (info_count - 1));
+    ok_(__FILE__, line)(!ws->BasicInfo.FaultingVa || broken(ws->BasicInfo.FaultingVa == (void *)1) /* Win8 */,
+            "Got unexpected FaultingVa %p.\n", ws->BasicInfo.FaultingVa);
+    ok_(__FILE__, line)(!ws->BasicInfo.FaultingPc, "Got unexpected FaultingPc %p.\n", ws->BasicInfo.FaultingPc);
+    if (extended)
+    {
+        ok_(__FILE__, line)(!ws->Flags, "Got unexpected Flags %#lx.\n", ws->Flags);
+        ok_(__FILE__, line)(!ws->FaultingThreadId, "Got unexpected Flags %#lx.\n", ws->FaultingThreadId);
+    }
+
+    for(i = 0; i < info_count; ++i)
+    {
+        ws = (PSAPI_WS_WATCH_INFORMATION_EX *)((char *)info + size * i);
+        if (((ULONG_PTR)ws->BasicInfo.FaultingVa & mask) != ((ULONG_PTR)addr & mask))
+            continue;
+
+        if (extended)
+        {
+            ok_(__FILE__, line)(!ws->Flags, "Got unexpected flags %#lx.\n", ws->Flags);
+            ok_(__FILE__, line)(ws->FaultingThreadId == GetCurrentThreadId(),
+                    "Got unexpected FaultingThreadId %#lx.\n", ws->FaultingThreadId);
+        }
+        return;
+    }
+    ok_(__FILE__, line)(0, "Page not found.\n");
+}
+
+static void test_ws_watches(void)
+{
+    PSAPI_WS_WATCH_INFORMATION_EX ws_ex[1024];
+    PSAPI_WS_WATCH_INFORMATION *ws;
+    unsigned int value;
+    NTSTATUS status;
+    ULONG size;
+    char *addr;
+    BOOL ret;
+
+    status = NtSetInformationProcess(GetCurrentProcess(), ProcessWorkingSetWatch, (void *)0xdeadbeef, 1);
+    todo_wine ok(status == STATUS_DATATYPE_MISALIGNMENT, "Got unexpected status %#x.\n", status);
+
+    status = NtSetInformationProcess(GetCurrentProcess(), ProcessWorkingSetWatchEx, (void *)0xdeadbeef, 1);
+    todo_wine ok(status == STATUS_DATATYPE_MISALIGNMENT, "Got unexpected status %#x.\n", status);
+
+    status = NtSetInformationProcess(GetCurrentProcess(), ProcessWorkingSetWatch, (void *)0xdeadbee8, 1);
+    todo_wine ok(!status || broken(status == STATUS_ACCESS_VIOLATION) /* before Win10 */,
+            "Got unexpected status %#x.\n", status);
+
+    status = NtSetInformationProcess(GetCurrentProcess(), ProcessWorkingSetWatch, (void *)0xdeadbee8, 0);
+    todo_wine ok(status == STATUS_PORT_ALREADY_SET || broken(!status) /* before Win10, as previous attempt failed */,
+            "Got unexpected status %#x.\n", status);
+
+    status = NtSetInformationProcess(GetCurrentProcess(), ProcessWorkingSetWatchEx, NULL, 0);
+    todo_wine ok(status == STATUS_PORT_ALREADY_SET, "Got unexpected status %#x.\n", status);
+
+    addr = VirtualAlloc(NULL, 4 * 0x1000, MEM_COMMIT, PAGE_READWRITE);
+    ok(!!addr, "VirtualAlloc failed, error %u.\n", GetLastError());
+
+    *addr = 1;
+    ret = ReadProcessMemory(GetCurrentProcess(), addr + 0x1000, &value, sizeof(value), NULL);
+    ok(ret, "Got unexpected ret %u, error %u.\n", ret, GetLastError());
+    addr[0x2000] = 3;
+
+    ws = (PSAPI_WS_WATCH_INFORMATION *)ws_ex;
+
+    size = 0xdeadbeef;
+    status = NtQueryInformationProcess(GetCurrentProcess(), ProcessWorkingSetWatchEx, NULL, 0, &size);
+    todo_wine ok(status == STATUS_BUFFER_TOO_SMALL, "Got unexpected status %#x.\n", status);
+    todo_wine ok(size && !(size % sizeof(PSAPI_WS_WATCH_INFORMATION_EX)), "Got unexpected size %u.\n", size);
+
+    size = 0xdeadbeef;
+    status = NtQueryInformationProcess(GetCurrentProcess(), ProcessWorkingSetWatch, NULL, 0, &size);
+    todo_wine ok(status == STATUS_BUFFER_TOO_SMALL, "Got unexpected status %#x.\n", status);
+    todo_wine ok(size && !(size % sizeof(PSAPI_WS_WATCH_INFORMATION)), "Got unexpected size %u.\n", size);
+
+    memset(ws, 0xcc, sizeof(*ws));
+    status = NtQueryInformationProcess(GetCurrentProcess(), ProcessWorkingSetWatch, ws,
+            sizeof(PSAPI_WS_WATCH_INFORMATION), &size);
+    todo_wine ok(status == STATUS_BUFFER_TOO_SMALL, "Got unexpected status %#x.\n", status);
+    ok(ws->FaultingVa == (void *)(ULONG_PTR)0xcccccccccccccccc, "Got unexpected FaultingVa %p.\n", ws->FaultingVa);
+
+    memset(ws_ex, 0xcc, sizeof(ws_ex));
+    size = 0;
+    status = NtQueryInformationProcess(GetCurrentProcess(), ProcessWorkingSetWatchEx, ws_ex, sizeof(ws_ex), &size);
+    todo_wine ok(!status, "Got unexpected status %#x.\n", status);
+    todo_wine ws_watch_check_page(addr, ws_ex, size / sizeof(PSAPI_WS_WATCH_INFORMATION_EX), TRUE);
+    if (!is_wow64)
+        todo_wine ws_watch_check_page(addr + 0x1000, ws_ex, size / sizeof(PSAPI_WS_WATCH_INFORMATION_EX), TRUE);
+    todo_wine ws_watch_check_page(addr + 0x2000, ws_ex, size / sizeof(PSAPI_WS_WATCH_INFORMATION_EX), TRUE);
+
+    EmptyWorkingSet(GetCurrentProcess());
+
+    ok(*addr == 1, "Got unexpected *addr %#x.\n", *addr);
+    ok(addr[0x2000] == 3, "Got unexpected *addr %#x.\n", *addr);
+    memset(ws_ex, 0xcc, sizeof(ws_ex));
+    status = NtQueryInformationProcess(GetCurrentProcess(), ProcessWorkingSetWatch, ws, sizeof(ws_ex), &size);
+    todo_wine ok(!status, "Got unexpected status %#x.\n", status);
+    todo_wine ws_watch_check_page(addr, ws_ex, size / sizeof(PSAPI_WS_WATCH_INFORMATION), FALSE);
+    todo_wine ws_watch_check_page(addr + 0x2000, ws_ex, size / sizeof(PSAPI_WS_WATCH_INFORMATION), FALSE);
+
+    VirtualFree(addr, 0, MEM_RELEASE);
+}
+
 START_TEST(virtual)
 {
     HMODULE mod;
@@ -1171,4 +1286,5 @@ START_TEST(virtual)
     test_NtMapViewOfSection();
     test_user_shared_data();
     test_syscalls();
+    test_ws_watches();
 }
-- 
2.33.1




More information about the wine-devel mailing list