From: Lev Stipakov
Properly detect process architecture and
machine architecture, including arm64.
Print process architecture and, if machine
architecture is different (we are running in
emulation), print that too.
Signed-off-by: Lev Stipakov
---
src/openvpn/win32.c | 123
1 file changed, 112 insertions(+), 11 deletions(-)
diff --git a/src/openvpn/win32.c b/src/openvpn/win32.c
index 82f0c73f..cfe4dbde 100644
--- a/src/openvpn/win32.c
+++ b/src/openvpn/win32.c
@@ -1345,18 +1345,106 @@ win32_version_info(void)
return WIN_10;
}
-bool
-win32_is_64bit(void)
+typedef enum {
+ARCH_X86,
+ARCH_AMD64,
+ARCH_ARM64,
+ARCH_NATIVE, /* means no emulation, makes sense for host arch */
+ARCH_UNKNOWN
+} arch_t;
+
+static void
+win32_get_arch(arch_t *process_arch, arch_t *host_arch)
{
-#if defined(_WIN64)
-return true; /* 64-bit programs run only on Win64 */
+*process_arch = ARCH_UNKNOWN;
+*host_arch = ARCH_NATIVE;
+
+typedef BOOL (__stdcall *is_wow64_process2_t)(HANDLE, USHORT *, USHORT *);
+is_wow64_process2_t is_wow64_process2 = (is_wow64_process2_t)
+
GetProcAddress(GetModuleHandle("Kernel32.dll"), "IsWow64Process2");
+
+USHORT process_machine = 0;
+USHORT native_machine = 0;
+BOOL is_wow64 = FALSE;
+
+#ifdef _ARM64_
+*process_arch = ARCH_ARM64;
+#elif defined(_WIN64)
+*process_arch = ARCH_AMD64;
+if (is_wow64_process2)
+{
+/* this could be amd64 on arm64 */
+BOOL is_wow64 = is_wow64_process2(GetCurrentProcess(),
+ _machine, _machine);
+if (is_wow64 && native_machine == IMAGE_FILE_MACHINE_ARM64)
+{
+*host_arch = ARCH_ARM64;
+}
+}
#elif defined(_WIN32)
-/* 32-bit programs run on both 32-bit and 64-bit Windows */
-BOOL f64 = FALSE;
-return IsWow64Process(GetCurrentProcess(), ) && f64;
-#else /* if defined(_WIN64) */
-return false; /* Win64 does not support Win16 */
-#endif
+*process_arch = ARCH_X86;
+
+if (is_wow64_process2)
+{
+/* check if we're running on arm64 or amd64 machine */
+is_wow64 = is_wow64_process2(GetCurrentProcess(),
+ _machine, _machine);
+if (is_wow64)
+{
+switch (native_machine)
+{
+case IMAGE_FILE_MACHINE_ARM64:
+*host_arch = ARCH_ARM64;
+break;
+
+case IMAGE_FILE_MACHINE_AMD64:
+*host_arch = ARCH_AMD64;
+break;
+
+default:
+*host_arch = ARCH_UNKNOWN;
+break;
+}
+}
+}
+else
+{
+BOOL w64 = FALSE;
+is_wow64 = IsWow64Process(GetCurrentProcess(), ) && w64;
+if (is_wow64)
+{
+/* we are unable to differentiate between arm64 and amd64
+ * machines here, so assume we are running on amd64 */
+*host_arch = ARCH_AMD64;
+}
+}
+#endif /* _ARM64_ */
+}
+
+static void
+win32_print_arch(arch_t arch, struct buffer *out)
+{
+switch (arch)
+{
+case ARCH_X86:
+buf_printf(out, "x86");
+break;
+
+case ARCH_AMD64:
+buf_printf(out, "amd64");
+break;
+
+case ARCH_ARM64:
+buf_printf(out, "arm64");
+break;
+
+case ARCH_UNKNOWN:
+buf_printf(out, "(unknown)");
+break;
+
+default:
+break;
+}
}
const char *
@@ -1397,7 +1485,20 @@ win32_version_string(struct gc_arena *gc, bool add_name)
break;
}
-buf_printf(, win32_is_64bit() ? " 64bit" : " 32bit");
+buf_printf(, ", ");
+
+arch_t process_arch, host_arch;
+win32_get_arch(_arch, _arch);
+win32_print_arch(process_arch, );
+
+buf_printf(, " executable");
+
+if (host_arch != ARCH_NATIVE)
+{
+buf_printf(, " running on ");
+win32_print_arch(host_arch, );
+buf_printf(, " host");
+}
return (const char *)out.data;
}
--
2.38.1.windows.1
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel