Dmitry Timoshkov : kernel32: Implement IsWow64Process2.

Alexandre Julliard julliard at winehq.org
Tue Jun 30 14:55:05 CDT 2020


Module: wine
Branch: master
Commit: c70a303cd44e3463772ab9ecd2c6f4e73df676cd
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=c70a303cd44e3463772ab9ecd2c6f4e73df676cd

Author: Dmitry Timoshkov <dmitry at baikal.ru>
Date:   Fri Jun 26 12:42:47 2020 +0800

kernel32: Implement IsWow64Process2.

Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 .../api-ms-win-core-wow64-l1-1-1.spec              |   1 +
 dlls/kernel32/kernel32.spec                        |   1 +
 dlls/kernel32/tests/process.c                      | 100 +++++++++++++++++++++
 dlls/kernelbase/kernelbase.spec                    |   2 +-
 dlls/kernelbase/process.c                          |  68 ++++++++++++++
 include/winbase.h                                  |   1 +
 6 files changed, 172 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..eaa5da2e95 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,103 @@ static void test_IsWow64Process(void)
     }
 }
 
+static void test_IsWow64Process2(void)
+{
+    PROCESS_INFORMATION pi;
+    STARTUPINFOA si;
+    BOOL ret, is_wow64;
+    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";
+#ifdef __i386__
+    USHORT expect_native = IMAGE_FILE_MACHINE_I386;
+#elif defined __x86_64__
+    USHORT expect_native = IMAGE_FILE_MACHINE_AMD64;
+#elif defined __arm__
+    USHORT expect_native = IMAGE_FILE_MACHINE_ARM;
+#elif defined __aarch64__
+    USHORT expect_native = IMAGE_FILE_MACHINE_ARM;
+#else
+    USHORT expect_native = 0;
+#endif
+
+    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)
+    {
+        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);
+        expect_native = IMAGE_FILE_MACHINE_AMD64;
+#else
+        skip("not supported architecture\n");
+#endif
+        ok(native_machine == expect_native, "got %#x\n", native_machine);
+
+        ret = TerminateProcess(pi.hProcess, 0);
+        ok(ret, "TerminateProcess error\n");
+
+        CloseHandle(pi.hProcess);
+        CloseHandle(pi.hThread);
+    }
+
+    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);
+    ok(native_machine == expect_native, "got %#x\n", native_machine);
+
+    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)
+    {
+        ok(machine == IMAGE_FILE_MACHINE_I386, "got %#x\n", machine);
+        ok(native_machine == expect_native, "got %#x\n", native_machine);
+    }
+    else
+    {
+        ok(machine == IMAGE_FILE_MACHINE_UNKNOWN, "got %#x\n", machine);
+        ok(native_machine == expect_native, "got %#x\n", native_machine);
+    }
+}
+
 static void test_SystemInfo(void)
 {
     SYSTEM_INFO si, nsi;
@@ -4065,6 +4164,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..58fba52415 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,73 @@ 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_ARM:
+        *native_machine = IMAGE_FILE_MACHINE_ARM;
+        break;
+    case PROCESSOR_ARCHITECTURE_AMD64:
+        *native_machine = IMAGE_FILE_MACHINE_AMD64;
+        break;
+    case PROCESSOR_ARCHITECTURE_ARM64:
+        *native_machine = IMAGE_FILE_MACHINE_ARM64;
+        break;
+    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);




More information about the wine-cvs mailing list