diff --git a/dlls/ntdll/process.c b/dlls/ntdll/process.c index 633a668ea3b..3defb6eb352 100644 --- a/dlls/ntdll/process.c +++ b/dlls/ntdll/process.c @@ -403,10 +403,13 @@ NTSTATUS WINAPI NtQueryInformationProcess( break; case ProcessWow64Information: - len = sizeof(DWORD); - if (ProcessInformationLength == len) + len = sizeof(ULONG_PTR); + if (ProcessInformationLength != len) ret = STATUS_INFO_LENGTH_MISMATCH; + else if (!ProcessInformation) ret = STATUS_ACCESS_VIOLATION; + else if(!ProcessHandle) ret = STATUS_INVALID_HANDLE; + else { - DWORD val = 0; + ULONG_PTR val = 0; if (ProcessHandle == GetCurrentProcess()) val = is_wow64; else if (server_cpus & (1 << CPU_x86_64)) @@ -418,9 +421,8 @@ NTSTATUS WINAPI NtQueryInformationProcess( } SERVER_END_REQ; } - *(DWORD *)ProcessInformation = val; + *(ULONG_PTR *)ProcessInformation = val; } - else ret = STATUS_INFO_LENGTH_MISMATCH; break; case ProcessImageFileName: /* FIXME: this will return a DOS path. Windows returns an NT path. Changing this would require also changing kernel32.QueryFullProcessImageName. diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c index af0040166f8..5fff4908683 100644 --- a/dlls/ntdll/tests/info.c +++ b/dlls/ntdll/tests/info.c @@ -737,6 +737,84 @@ static void test_query_processor_power_info(void) HeapFree(GetProcessHeap(), 0, ppi); } +static void test_query_process_wow64(void) +{ + NTSTATUS status; + ULONG ReturnLength; + ULONG_PTR pbi[2], dummy; + + memset(&dummy, 0xcc, sizeof(dummy)); + + /* Do not give a handle and buffer */ + status = pNtQueryInformationProcess(NULL, ProcessWow64Information, NULL, 0, NULL); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status); + + /* Use a correct info class and buffer size, but still no handle and buffer */ + status = pNtQueryInformationProcess(NULL, ProcessWow64Information, NULL, sizeof(ULONG_PTR), NULL); + ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_HANDLE, + "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE, got %08x\n", status); + + /* Use a correct info class, buffer size and handle, but no buffer */ + status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information, NULL, sizeof(ULONG_PTR), NULL); + ok( status == STATUS_ACCESS_VIOLATION , "Expected STATUS_ACCESS_VIOLATION, got %08x\n", status); + + /* Use a correct info class, buffer and buffer size, but no handle */ + pbi[0] = pbi[1] = dummy; + status = pNtQueryInformationProcess(NULL, ProcessWow64Information, pbi, sizeof(ULONG_PTR), NULL); + ok( status == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got %08x\n", status); + ok( pbi[0] == dummy, "pbi[0] changed to %lx\n", pbi[0]); + ok( pbi[1] == dummy, "pbi[1] changed to %lx\n", pbi[1]); + + /* Use a greater buffer size */ + pbi[0] = pbi[1] = dummy; + status = pNtQueryInformationProcess(NULL, ProcessWow64Information, pbi, sizeof(ULONG_PTR) + 1, NULL); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status); + ok( pbi[0] == dummy, "pbi[0] changed to %lx\n", pbi[0]); + ok( pbi[1] == dummy, "pbi[1] changed to %lx\n", pbi[1]); + + /* Use no ReturnLength */ + pbi[0] = pbi[1] = dummy; + status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information, pbi, sizeof(ULONG_PTR), NULL); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status); + trace( "Platform is_wow64 %d, ProcessInformation of ProcessWow64Information %lx\n", is_wow64, pbi[0]); + ok( is_wow64 == (pbi[0] != 0), "is_wow64 %x, pbi[0] %lx\n", is_wow64, pbi[0]); + ok( pbi[0] != dummy, "pbi[0] %lx\n", pbi[0]); + ok( pbi[1] == dummy, "pbi[1] changed to %lx\n", pbi[1]); + /* Test written size on 64 bit by checking high 32 bit buffer */ + if (sizeof(ULONG_PTR) > sizeof(DWORD)) + { + DWORD *ptr = (DWORD *)pbi; + ok( ptr[1] != (DWORD)dummy, "ptr[1] unchanged!\n"); + } + + /* Finally some correct calls */ + pbi[0] = pbi[1] = dummy; + ReturnLength = 0xdeadbeef; + status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information, pbi, sizeof(ULONG_PTR), &ReturnLength); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status); + ok( is_wow64 == (pbi[0] != 0), "is_wow64 %x, pbi[0] %lx\n", is_wow64, pbi[0]); + ok( pbi[1] == dummy, "pbi[1] changed to %lx\n", pbi[1]); + ok( ReturnLength == sizeof(ULONG_PTR), "Inconsistent length %d\n", ReturnLength); + + /* Everything is correct except a too small buffer size */ + pbi[0] = pbi[1] = dummy; + ReturnLength = 0xdeadbeef; + status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information, pbi, sizeof(ULONG_PTR) - 1, &ReturnLength); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status); + ok( pbi[0] == dummy, "pbi[0] changed to %lx\n", pbi[0]); + ok( pbi[1] == dummy, "pbi[1] changed to %lx\n", pbi[1]); + todo_wine ok( ReturnLength == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", ReturnLength); + + /* Everything is correct except a too large buffer size */ + pbi[0] = pbi[1] = dummy; + ReturnLength = 0xdeadbeef; + status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information, pbi, sizeof(ULONG_PTR) + 1, &ReturnLength); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status); + ok( pbi[0] == dummy, "pbi[0] changed to %lx\n", pbi[0]); + ok( pbi[1] == dummy, "pbi[1] changed to %lx\n", pbi[1]); + todo_wine ok( ReturnLength == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", ReturnLength); +} + static void test_query_process_basic(void) { NTSTATUS status; @@ -1714,6 +1792,10 @@ START_TEST(info) trace("Starting test_query_process_handlecount()\n"); test_query_process_handlecount(); + /* 0x1A ProcessWow64Information */ + trace("Starting test_query_process_wow64()\n"); + test_query_process_wow64(); + /* 0x1B ProcessImageFileName */ trace("Starting test_query_process_image_file_name()\n"); test_query_process_image_file_name();