v2: Add tests.
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- .../api-ms-win-core-wow64-l1-1-1.spec | 1 + dlls/kernel32/kernel32.spec | 1 + dlls/kernel32/tests/process.c | 114 ++++++++++++++++++ dlls/kernelbase/kernelbase.spec | 2 +- dlls/kernelbase/process.c | 92 ++++++++++++++ include/winbase.h | 1 + 6 files changed, 210 insertions(+), 1 deletion(-)
diff --git a/dlls/api-ms-win-core-wow64-l1-1-1/api-ms-win-core-wow64-l1-1-1.spec b/dlls/api-ms-win-core-wow64-l1-1-1/api-ms-win-core-wow64-l1-1-1.spec index 08fa02c3fc..99ba713409 100644 --- a/dlls/api-ms-win-core-wow64-l1-1-1/api-ms-win-core-wow64-l1-1-1.spec +++ b/dlls/api-ms-win-core-wow64-l1-1-1/api-ms-win-core-wow64-l1-1-1.spec @@ -1,5 +1,6 @@ @ stdcall GetSystemWow64DirectoryA(ptr long) kernel32.GetSystemWow64DirectoryA @ stdcall GetSystemWow64DirectoryW(ptr long) kernel32.GetSystemWow64DirectoryW @ stdcall IsWow64Process(ptr ptr) kernel32.IsWow64Process +@ stdcall IsWow64Process2(ptr ptr ptr) kernel32.IsWow64Process2 @ stdcall Wow64DisableWow64FsRedirection(ptr) kernel32.Wow64DisableWow64FsRedirection @ stdcall Wow64RevertWow64FsRedirection(ptr) kernel32.Wow64RevertWow64FsRedirection diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec index 17322bcd90..e7a7f162b7 100644 --- a/dlls/kernel32/kernel32.spec +++ b/dlls/kernel32/kernel32.spec @@ -999,6 +999,7 @@ @ stdcall -import IsValidNLSVersion(long wstr ptr) # @ stub IsValidUILanguage @ stdcall -import IsWow64Process(ptr ptr) +@ stdcall -import IsWow64Process2(ptr ptr ptr) @ stdcall -import K32EmptyWorkingSet(long) @ stdcall -import K32EnumDeviceDrivers(ptr long ptr) @ stdcall -import K32EnumPageFilesA(ptr ptr) diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c index 82a5bdd85d..af585c4415 100644 --- a/dlls/kernel32/tests/process.c +++ b/dlls/kernel32/tests/process.c @@ -66,6 +66,7 @@ static HINSTANCE hkernel32, hntdll; static void (WINAPI *pGetNativeSystemInfo)(LPSYSTEM_INFO); static BOOL (WINAPI *pGetSystemRegistryQuota)(PDWORD, PDWORD); static BOOL (WINAPI *pIsWow64Process)(HANDLE,PBOOL); +static BOOL (WINAPI *pIsWow64Process2)(HANDLE, USHORT *, USHORT *); static LPVOID (WINAPI *pVirtualAllocEx)(HANDLE, LPVOID, SIZE_T, DWORD, DWORD); static BOOL (WINAPI *pVirtualFreeEx)(HANDLE, LPVOID, SIZE_T, DWORD); static BOOL (WINAPI *pQueryFullProcessImageNameA)(HANDLE hProcess, DWORD dwFlags, LPSTR lpExeName, PDWORD lpdwSize); @@ -249,6 +250,7 @@ static BOOL init(void) pGetNativeSystemInfo = (void *) GetProcAddress(hkernel32, "GetNativeSystemInfo"); pGetSystemRegistryQuota = (void *) GetProcAddress(hkernel32, "GetSystemRegistryQuota"); pIsWow64Process = (void *) GetProcAddress(hkernel32, "IsWow64Process"); + pIsWow64Process2 = (void *) GetProcAddress(hkernel32, "IsWow64Process2"); pVirtualAllocEx = (void *) GetProcAddress(hkernel32, "VirtualAllocEx"); pVirtualFreeEx = (void *) GetProcAddress(hkernel32, "VirtualFreeEx"); pQueryFullProcessImageNameA = (void *) GetProcAddress(hkernel32, "QueryFullProcessImageNameA"); @@ -2166,6 +2168,117 @@ static void test_IsWow64Process(void) } }
+static void test_IsWow64Process2(void) +{ + PROCESS_INFORMATION pi; + STARTUPINFOA si; + BOOL ret, is_wow64, is_win64; + USHORT machine, native_machine; + static char cmdline[] = "C:\Program Files\Internet Explorer\iexplore.exe"; + static char cmdline_wow64[] = "C:\Program Files (x86)\Internet Explorer\iexplore.exe"; + + if (!pIsWow64Process2) + { + skip("IsWow64Process2 is not available\n"); + return; + } + + memset(&si, 0, sizeof(si)); + si.cb = sizeof(si); + SetLastError(0xdeadbeef); + ret = CreateProcessA(cmdline_wow64, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi); + if (ret) + { + is_win64 = TRUE; + + SetLastError(0xdeadbeef); + machine = native_machine = 0xdead; + ret = pIsWow64Process2(pi.hProcess, &machine, &native_machine); + ok(ret, "IsWow64Process2 error %u\n", GetLastError()); + +#if defined(__i386__) || defined(__x86_64__) + ok(machine == IMAGE_FILE_MACHINE_I386, "got %#x\n", machine); + ok(native_machine == IMAGE_FILE_MACHINE_AMD64, "got %#x\n", native_machine); +#else + skip("not supportted architecture\n"); +#endif + + ret = TerminateProcess(pi.hProcess, 0); + ok(ret, "TerminateProcess error\n"); + + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + } + else + is_win64 = FALSE; + + memset(&si, 0, sizeof(si)); + si.cb = sizeof(si); + SetLastError(0xdeadbeef); + ret = CreateProcessA(cmdline, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi); + ok(ret, "CreateProcess error %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = pIsWow64Process(pi.hProcess, &is_wow64); + ok(ret, "IsWow64Process error %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + machine = native_machine = 0xdead; + ret = pIsWow64Process2(pi.hProcess, &machine, &native_machine); + ok(ret, "IsWow64Process2 error %u\n", GetLastError()); + + ok(machine == IMAGE_FILE_MACHINE_UNKNOWN, "got %#x\n", machine); +#ifdef __i386__ + if (is_win64) + ok(native_machine == IMAGE_FILE_MACHINE_AMD64, "got %#x\n", native_machine); + else + ok(native_machine == IMAGE_FILE_MACHINE_I386, "got %#x\n", native_machine); +#elif defined __x86_64__ + ok(native_machine == IMAGE_FILE_MACHINE_AMD64, "got %#x\n", native_machine); +#else + skip("not supportted architecture\n"); +#endif + + ret = TerminateProcess(pi.hProcess, 0); + ok(ret, "TerminateProcess error\n"); + + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + + SetLastError(0xdeadbeef); + ret = pIsWow64Process(GetCurrentProcess(), &is_wow64); + ok(ret, "IsWow64Process error %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + machine = native_machine = 0xdead; + ret = pIsWow64Process2(GetCurrentProcess(), &machine, &native_machine); + ok(ret, "IsWow64Process2 error %u\n", GetLastError()); + + if (is_wow64) + { +#if defined(__i386__) || defined(__x86_64__) + ok(machine == IMAGE_FILE_MACHINE_I386, "got %#x\n", machine); + ok(native_machine == IMAGE_FILE_MACHINE_AMD64, "got %#x\n", native_machine); +#else + skip("not supportted architecture\n"); +#endif + } + else + { + ok(machine == IMAGE_FILE_MACHINE_UNKNOWN, "got %#x\n", machine); +#ifdef __i386__ + if (is_win64) + ok(native_machine == IMAGE_FILE_MACHINE_AMD64, "got %#x\n", native_machine); + else + ok(native_machine == IMAGE_FILE_MACHINE_I386, "got %#x\n", native_machine); +#elif defined __x86_64__ + ok(native_machine == IMAGE_FILE_MACHINE_AMD64, "got %#x\n", native_machine); +#else + skip("not supportted architecture\n"); +#endif + } +} + static void test_SystemInfo(void) { SYSTEM_INFO si, nsi; @@ -4065,6 +4178,7 @@ START_TEST(process) test_QueryFullProcessImageNameW(); test_Handles(); test_IsWow64Process(); + test_IsWow64Process2(); test_SystemInfo(); test_RegistryQuota(); test_DuplicateHandle(); diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec index 5e177a4932..a05bf223e8 100644 --- a/dlls/kernelbase/kernelbase.spec +++ b/dlls/kernelbase/kernelbase.spec @@ -884,7 +884,7 @@ @ stdcall IsValidSid(ptr) @ stdcall IsWellKnownSid(ptr long) @ stdcall IsWow64Process(ptr ptr) -# @ stub IsWow64Process2 +@ stdcall IsWow64Process2(ptr ptr ptr) @ stdcall K32EmptyWorkingSet(long) @ stdcall K32EnumDeviceDrivers(ptr long ptr) @ stdcall K32EnumPageFilesA(ptr ptr) diff --git a/dlls/kernelbase/process.c b/dlls/kernelbase/process.c index a3b168543f..1076e2ea82 100644 --- a/dlls/kernelbase/process.c +++ b/dlls/kernelbase/process.c @@ -24,6 +24,7 @@ #include "ntstatus.h" #define WIN32_NO_STATUS #define NONAMELESSUNION +#define NONAMELESSSTRUCT #include "windef.h" #include "winbase.h" #include "winnls.h" @@ -882,6 +883,97 @@ BOOL WINAPI DECLSPEC_HOTPATCH IsProcessorFeaturePresent ( DWORD feature ) }
+/********************************************************************** + * IsWow64Process2 (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH IsWow64Process2( HANDLE process, USHORT *machine, USHORT *native_machine ) +{ + BOOL wow64; + SYSTEM_INFO si; + + TRACE( "(%p,%p,%p)\n", process, machine, native_machine ); + + if (!IsWow64Process( process, &wow64 )) + return FALSE; + + if (wow64) + { + GetNativeSystemInfo( &si ); + + if (process != GetCurrentProcess()) + { +#if defined(__i386__) || defined(__x86_64__) + *machine = IMAGE_FILE_MACHINE_I386; +#else + FIXME("not implemented for other process\n"); + *machine = IMAGE_FILE_MACHINE_UNKNOWN; +#endif + } + else + { + IMAGE_NT_HEADERS *nt; + nt = RtlImageNtHeader( NtCurrentTeb()->Peb->ImageBaseAddress ); + *machine = nt->FileHeader.Machine; + } + } + else + { +#ifdef _WIN64 + GetSystemInfo( &si ); +#else + GetNativeSystemInfo( &si ); +#endif + *machine = IMAGE_FILE_MACHINE_UNKNOWN; + } + + switch (si.u.s.wProcessorArchitecture) + { + case PROCESSOR_ARCHITECTURE_INTEL: + *native_machine = IMAGE_FILE_MACHINE_I386; + break; + + case PROCESSOR_ARCHITECTURE_ALPHA: + *native_machine = IMAGE_FILE_MACHINE_ALPHA; + break; + + case PROCESSOR_ARCHITECTURE_ARM: + *native_machine = IMAGE_FILE_MACHINE_ARM; + break; + + case PROCESSOR_ARCHITECTURE_IA64: + *native_machine = IMAGE_FILE_MACHINE_IA64; + break; + + case PROCESSOR_ARCHITECTURE_ALPHA64: + *native_machine = IMAGE_FILE_MACHINE_ALPHA64; + break; + + case PROCESSOR_ARCHITECTURE_AMD64: + *native_machine = IMAGE_FILE_MACHINE_AMD64; + break; + + case PROCESSOR_ARCHITECTURE_ARM64: + *native_machine = IMAGE_FILE_MACHINE_ARM64; + break; + + case PROCESSOR_ARCHITECTURE_MIPS: + case PROCESSOR_ARCHITECTURE_PPC: + case PROCESSOR_ARCHITECTURE_SHX: + case PROCESSOR_ARCHITECTURE_MSIL: + case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64: + case PROCESSOR_ARCHITECTURE_NEUTRAL: + case PROCESSOR_ARCHITECTURE_ARM32_ON_WIN64: + case PROCESSOR_ARCHITECTURE_IA32_ON_ARM64: + default: + FIXME("unknown architecture %u\n", si.u.s.wProcessorArchitecture); + *native_machine = IMAGE_FILE_MACHINE_UNKNOWN; + break; + } + + return TRUE; +} + + /********************************************************************** * IsWow64Process (kernelbase.@) */ diff --git a/include/winbase.h b/include/winbase.h index 39a4a9c9ac..981d4ea76a 100644 --- a/include/winbase.h +++ b/include/winbase.h @@ -2406,6 +2406,7 @@ WINADVAPI BOOL WINAPI IsValidSecurityDescriptor(PSECURITY_DESCRIPTOR); WINADVAPI BOOL WINAPI IsValidSid(PSID); WINADVAPI BOOL WINAPI IsWellKnownSid(PSID,WELL_KNOWN_SID_TYPE); WINBASEAPI BOOL WINAPI IsWow64Process(HANDLE,PBOOL); +WINBASEAPI BOOL WINAPI IsWow64Process2(HANDLE,USHORT*,USHORT*); WINADVAPI BOOL WINAPI ImpersonateLoggedOnUser(HANDLE); WINADVAPI BOOL WINAPI ImpersonateNamedPipeClient(HANDLE); WINADVAPI BOOL WINAPI ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL);
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=74282
Your paranoid android.
=== debiant (32 bit Chinese:China report) ===
kernel32: mailslot.c:327: Test failed: timeout too short 989
=== debiant (32 bit WoW report) ===
kernel32: mailslot.c:327: Test failed: timeout too short 987
=== debiant (64 bit WoW report) ===
kernel32: mailslot.c:327: Test failed: timeout too short 987