gdk/win32: Consolidate CPU detection in one place

This consolidates the check for the running CPU in one single location,
to make things a bit cleaner, as:

* We can make use of IsWow64Process2(), if available, to check both
  whether we are running on an ARM64 CPU, and whether we are running as
  a WOW64 process.  This is also the function to use to properly check
  whether we are running as a WOW64 process on ARM64 systems, as
  IsWow64Process() does not work as we want on ARM64 systems.

* If we don't have IsWow64Process2() (which is absent from Windows prior
  to Windows 10 1511, where ARM64 Windows is introduced), we can fall
  back to  IsWow64Process(), which will tell us whether we are running
  as an WOW64 process (but clearly not on an ARM64 system).

Also clean up things a bit so that we can reduce reliance on global
variables.
This commit is contained in:
Chun-wei Fan 2020-10-16 18:22:01 +08:00 committed by Philip Zander
parent aa3e6bb0a3
commit 4a55c527d7
4 changed files with 48 additions and 33 deletions

View File

@ -1034,42 +1034,70 @@ _gdk_win32_enable_hidpi (GdkWin32Display *display)
}
}
#if 0
/* Keep code around in case we need to check for running on ARM64 in the future */
static void
_gdk_win32_check_on_arm64 (GdkWin32Display *display)
gboolean
_gdk_win32_check_processor (GdkWin32ProcessorCheckType check_type)
{
static gsize checked = 0;
static gboolean is_arm64 = FALSE;
static gboolean is_wow64 = FALSE;
if (g_once_init_enter (&checked))
{
gboolean fallback_wow64_check = FALSE;
HMODULE kernel32 = LoadLibraryW (L"kernel32.dll");
if (kernel32 != NULL)
{
display->cpu_funcs.isWow64Process2 =
GdkWin32KernelCPUFuncs cpu_funcs = {0};
cpu_funcs.isWow64Process2 =
(funcIsWow64Process2) GetProcAddress (kernel32, "IsWow64Process2");
if (display->cpu_funcs.isWow64Process2 != NULL)
if (cpu_funcs.isWow64Process2 != NULL)
{
USHORT proc_cpu = 0;
USHORT native_cpu = 0;
display->cpu_funcs.isWow64Process2 (GetCurrentProcess (),
&proc_cpu,
&native_cpu);
cpu_funcs.isWow64Process2 (GetCurrentProcess (),
&proc_cpu,
&native_cpu);
if (native_cpu == IMAGE_FILE_MACHINE_ARM64)
display->running_on_arm64 = TRUE;
is_arm64 = TRUE;
if (native_cpu != IMAGE_FILE_MACHINE_UNKNOWN)
is_wow64 = TRUE;
}
else
fallback_wow64_check = TRUE;
FreeLibrary (kernel32);
}
else
fallback_wow64_check = TRUE;
if (fallback_wow64_check)
IsWow64Process (GetCurrentProcess (), &is_wow64);
g_once_init_leave (&checked, 1);
}
switch (check_type)
{
case GDK_WIN32_ARM64:
return is_arm64;
break;
case GDK_WIN32_WOW64:
return is_wow64;
break;
default:
g_warning ("unknown CPU check type");
return FALSE;
break;
}
}
#endif
static void
gdk_win32_display_init (GdkWin32Display *display)

View File

@ -124,7 +124,6 @@ struct _GdkWin32Display
GdkWin32User32DPIFuncs user32_dpi_funcs;
/* Running CPU items */
GdkWin32KernelCPUFuncs cpu_funcs;
};
struct _GdkWin32DisplayClass

View File

@ -80,26 +80,6 @@ static GdkKeymap *default_keymap = NULL;
static void update_keymap (GdkWin32Keymap *gdk_keymap);
static void clear_keyboard_layout_info (gpointer data);
#ifndef _WIN64
static BOOL
is_wow64 (void)
{
typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
BOOL bIsWow64 = FALSE;
LPFN_ISWOW64PROCESS fnIsWow64Process;
fnIsWow64Process = (LPFN_ISWOW64PROCESS)
GetProcAddress (GetModuleHandle (TEXT("kernel32")),
"IsWow64Process");
if (fnIsWow64Process != NULL)
fnIsWow64Process (GetCurrentProcess (), &bIsWow64);
return bIsWow64;
}
#endif
static void
gdk_win32_keymap_init (GdkWin32Keymap *keymap)
{
@ -122,7 +102,7 @@ gdk_win32_keymap_init (GdkWin32Keymap *keymap)
keymap->gdkwin32_keymap_impl = &gdkwin32_keymap_impl;
#ifndef _WIN64
if (is_wow64())
if (_gdk_win32_check_processor (GDK_WIN32_WOW64))
keymap->gdkwin32_keymap_impl = &gdkwin32_keymap_impl_wow64;
#endif

View File

@ -542,4 +542,12 @@ void _gdk_win32_windowing_init (void);
void _gdk_dnd_init (void);
void _gdk_events_init (GdkDisplay *display);
typedef enum _GdkWin32ProcessorCheckType
{
GDK_WIN32_ARM64,
GDK_WIN32_WOW64,
} GdkWin32ProcessorCheckType;
gboolean _gdk_win32_check_processor (GdkWin32ProcessorCheckType check_type);
#endif /* __GDK_PRIVATE_WIN32_H__ */