From: Paul Gofman pgofman@codeweavers.com
--- dlls/ntdll/tests/info.c | 87 ++++++++++++++++++++++++++++++++++++--- dlls/ntdll/unix/process.c | 4 ++ dlls/wow64/process.c | 3 +- 3 files changed, 88 insertions(+), 6 deletions(-)
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c index 071aa2b026e..9b058eae20f 100644 --- a/dlls/ntdll/tests/info.c +++ b/dlls/ntdll/tests/info.c @@ -2443,6 +2443,7 @@ static void test_query_process_image_info(void)
static void test_query_process_debug_object_handle(int argc, char **argv) { + char buffer[sizeof(HANDLE) * 2]; char cmdline[MAX_PATH]; STARTUPINFOA si = {0}; PROCESS_INFORMATION pi; @@ -2482,6 +2483,22 @@ static void test_query_process_debug_object_handle(int argc, char **argv) ok(len == 0xdeadbeef || broken(len == 0xfffffffc || len == 0xffc), /* wow64 */ "len set to %lx\n", len );
+ status = NtQueryInformationProcess(GetCurrentProcess(), + ProcessDebugObjectHandle, (void *)0xdeadbea0, sizeof(debug_object), &len); + if (is_wow64) + { + todo_wine_if(old_wow64) + { + ok(status == STATUS_PORT_NOT_SET, "got %#lx\n", status); + ok(len == sizeof(HANDLE), "got %lu\n", len); + } + } + else + { + ok(status == STATUS_ACCESS_VIOLATION, "got %#lx\n", status); + ok(len == 0xdeadbeef, "got %lu\n", len ); + } + status = NtQueryInformationProcess(NULL, ProcessDebugObjectHandle, &debug_object, sizeof(debug_object), NULL); ok(status == STATUS_INVALID_HANDLE, @@ -2492,7 +2509,7 @@ static void test_query_process_debug_object_handle(int argc, char **argv) ProcessDebugObjectHandle, &debug_object, sizeof(debug_object) - 1, &len); ok(status == STATUS_INFO_LENGTH_MISMATCH, "Expected NtQueryInformationProcess to return STATUS_INFO_LENGTH_MISMATCH, got 0x%08lx\n", status); - ok(len == 0xdeadbeef || broken(len == 0xfffffffc || len == 0xffc), /* wow64 */ + ok(len == 0xdeadbeef || broken(len == 0xfffffffc || len == 0xffc || len == 4), /* wow64 */ "len set to %lx\n", len );
len = 0xdeadbeef; @@ -2500,7 +2517,7 @@ static void test_query_process_debug_object_handle(int argc, char **argv) ProcessDebugObjectHandle, &debug_object, sizeof(debug_object) + 1, &len); ok(status == STATUS_INFO_LENGTH_MISMATCH, "Expected NtQueryInformationProcess to return STATUS_INFO_LENGTH_MISMATCH, got 0x%08lx\n", status); - ok(len == 0xdeadbeef || broken(len == 0xfffffffc || len == 0xffc), /* wow64 */ + ok(len == 0xdeadbeef || broken(len == 0xfffffffc || len == 0xffc || len == 4), /* wow64 */ "len set to %lx\n", len );
len = 0xdeadbeef; @@ -2510,11 +2527,71 @@ static void test_query_process_debug_object_handle(int argc, char **argv) sizeof(debug_object), &len); ok(status == STATUS_PORT_NOT_SET, "Expected NtQueryInformationProcess to return STATUS_PORT_NOT_SET, got 0x%08lx\n", status); - ok(debug_object == NULL || - broken(debug_object == (HANDLE)0xdeadbeef), /* Wow64 */ - "Expected debug object handle to be NULL, got %p\n", debug_object); + todo_wine_if(is_wow64 && old_wow64) + ok((!is_wow64 && !debug_object) || (is_wow64 && debug_object == (HANDLE)0xdeadbeef), "got %p\n", debug_object); ok(len == sizeof(debug_object), "len set to %lx\n", len );
+ debug_object = (HANDLE)0xdeadbeef; + status = NtQueryInformationProcess(GetCurrentProcess(), ProcessDebugObjectHandle, &debug_object, + sizeof(debug_object), NULL); + ok(status == STATUS_PORT_NOT_SET, "got %#lx.\n", status); + todo_wine_if(is_wow64 && old_wow64) + ok((!is_wow64 && !debug_object) || (is_wow64 && debug_object == (HANDLE)0xdeadbeef), "got %p\n", debug_object); + + debug_object = (HANDLE)0xdeadbeef; + status = NtQueryInformationProcess(GetCurrentProcess(), ProcessDebugObjectHandle, &debug_object, + sizeof(debug_object), (void *)0xdeadbea0); + ok(status == STATUS_ACCESS_VIOLATION, "got %#lx.\n", status); + ok(debug_object == (HANDLE)0xdeadbeef, "got %p\n", debug_object); + + debug_object = (HANDLE)0xdeadbeef; + status = NtQueryInformationProcess(GetCurrentProcess(), ProcessDebugObjectHandle, &debug_object, + sizeof(debug_object), (void *)0xdeadbea1); + ok(status == STATUS_ACCESS_VIOLATION, "got %#lx.\n", status); + ok(debug_object == (HANDLE)0xdeadbeef, "got %p\n", debug_object); + + debug_object = (HANDLE)0xdeadbeef; + status = NtQueryInformationProcess(GetCurrentProcess(), ProcessDebugObjectHandle, &debug_object, + 0, (void *)0xdeadbea0); + ok(status == STATUS_ACCESS_VIOLATION, "got %#lx.\n", status); + ok(debug_object == (HANDLE)0xdeadbeef, "got %p\n", debug_object); + + memset(buffer, 0xcc, sizeof(buffer)); + status = NtQueryInformationProcess(GetCurrentProcess(), ProcessDebugObjectHandle, buffer + 1, sizeof(HANDLE), NULL); + todo_wine_if(is_wow64 && old_wow64) + ok((!is_wow64 && status == STATUS_DATATYPE_MISALIGNMENT) || (is_wow64 && status == STATUS_PORT_NOT_SET), + "got %#lx.\n", status); + ok(*(HANDLE *)(buffer + 1) == (HANDLE)(ULONG_PTR)0xcccccccccccccccc, "got %p\n", *(HANDLE *)(buffer + 1)); + + memset(buffer, 0xcc, sizeof(buffer)); + status = NtQueryInformationProcess(GetCurrentProcess(), ProcessDebugObjectHandle, buffer + 4, sizeof(HANDLE), NULL); + ok(status == STATUS_PORT_NOT_SET, "got %#lx.\n", status); + todo_wine_if(is_wow64 && old_wow64) + ok((!is_wow64 && !*(HANDLE *)(buffer + 4)) || (is_wow64 && *(HANDLE *)(buffer + 4) == (HANDLE)0xcccccccc), + "got %p\n", *(HANDLE *)(buffer + 4)); + + memset(buffer, 0xcc, sizeof(buffer)); + status = NtQueryInformationProcess(GetCurrentProcess(), ProcessDebugObjectHandle, buffer + 1, sizeof(HANDLE), + (void *)0xdeadbea0); + todo_wine_if(is_wow64 && old_wow64) + ok((!is_wow64 && status == STATUS_DATATYPE_MISALIGNMENT) || (is_wow64 && status == STATUS_ACCESS_VIOLATION), + "got %#lx.\n", status); + ok(*(HANDLE *)(buffer + 1) == (HANDLE)(ULONG_PTR)0xcccccccccccccccc, "got %p\n", *(HANDLE *)(buffer + 1)); + + memset(buffer, 0xcc, sizeof(buffer)); + status = NtQueryInformationProcess(GetCurrentProcess(), ProcessDebugObjectHandle, buffer + 1, 1, + (void *)0xdeadbea0); + todo_wine_if(is_wow64 && old_wow64) + ok((!is_wow64 && status == STATUS_DATATYPE_MISALIGNMENT) || (is_wow64 && status == STATUS_ACCESS_VIOLATION), + "got %#lx.\n", status); + ok(*(HANDLE *)(buffer + 1) == (HANDLE)(ULONG_PTR)0xcccccccccccccccc, "got %p\n", *(HANDLE *)(buffer + 1)); + + memset(buffer, 0xcc, sizeof(buffer)); + status = NtQueryInformationProcess(GetCurrentProcess(), ProcessDebugObjectHandle, buffer + 1, 0, + (void *)0xdeadbea0); + ok(status == STATUS_ACCESS_VIOLATION, "got %#lx.\n", status); + ok(*(HANDLE *)(buffer + 1) == (HANDLE)(ULONG_PTR)0xcccccccccccccccc, "got %p\n", *(HANDLE *)(buffer + 1)); + len = 0xdeadbeef; debug_object = (HANDLE)0xdeadbeef; status = NtQueryInformationProcess(pi.hProcess, ProcessDebugObjectHandle, diff --git a/dlls/ntdll/unix/process.c b/dlls/ntdll/unix/process.c index 4d5d23c47bb..e4e000d385a 100644 --- a/dlls/ntdll/unix/process.c +++ b/dlls/ntdll/unix/process.c @@ -1363,6 +1363,10 @@ NTSTATUS WINAPI NtQueryInformationProcess( HANDLE handle, PROCESSINFOCLASS class
case ProcessDebugObjectHandle: len = sizeof(HANDLE); + if (size && ((ULONG_PTR)info & 3)) return STATUS_DATATYPE_MISALIGNMENT; + /* STATUS_ACCESS_VIOLATION is returned on Windows for unaccessible ret_len even if ret_len is + * not going to be written. */ + if (ret_len) *(volatile ULONG *)ret_len |= 0; if (size != len) return STATUS_INFO_LENGTH_MISMATCH; SERVER_START_REQ(get_process_debug_info) { diff --git a/dlls/wow64/process.c b/dlls/wow64/process.c index be8c1fe2b03..1843bdf5e84 100644 --- a/dlls/wow64/process.c +++ b/dlls/wow64/process.c @@ -627,6 +627,7 @@ NTSTATUS WINAPI wow64_NtQueryInformationProcess( UINT *args ) case ProcessAffinityMask: /* ULONG_PTR */ case ProcessWow64Information: /* ULONG_PTR */ case ProcessDebugObjectHandle: /* HANDLE */ + if (retlen) *(volatile ULONG *)retlen |= 0; if (len == sizeof(ULONG)) { ULONG_PTR data; @@ -638,7 +639,7 @@ NTSTATUS WINAPI wow64_NtQueryInformationProcess( UINT *args ) } else if (status == STATUS_PORT_NOT_SET) { - *(ULONG *)ptr = 0; + if (!ptr) return STATUS_ACCESS_VIOLATION; if (retlen) *retlen = sizeof(ULONG); } return status;
Marvel Rivals now depends on that (only 64 bit part) after commit dc718fd33b23a6104a0fa2e971a358662bf766af ("ntdll: Add some missing Zw exports.").