about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2025-06-17 15:54:58 +0800
committerGitHub <noreply@github.com>2025-06-17 09:54:58 +0200
commit71220b7fef4466f98cc78b1d013755aca8e217c6 (patch)
tree22e553abee39ed636e04a59d1b0e782a83cf739d
parentae0c91dce0671c176321fc72bfa69f1731d4aa2e (diff)
downloadbox64-71220b7fef4466f98cc78b1d013755aca8e217c6.tar.gz
box64-71220b7fef4466f98cc78b1d013755aca8e217c6.zip
[WOW64] Finished host extension detection (#2755)
-rw-r--r--src/os/hostext_wine.c31
-rw-r--r--wine/common/wrt.c71
-rw-r--r--wine/include/wine/compiler.h18
3 files changed, 118 insertions, 2 deletions
diff --git a/src/os/hostext_wine.c b/src/os/hostext_wine.c
index 3b6d5663..3dd9551b 100644
--- a/src/os/hostext_wine.c
+++ b/src/os/hostext_wine.c
@@ -1,4 +1,5 @@
 #include <winternl.h>
+#include <stdio.h>
 
 #include "debug.h"
 #include "wine/compiler.h"
@@ -14,7 +15,33 @@ int DetectHostCpuFeatures(void)
     if (IsProcessorFeaturePresent(PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE))
         cpuext.atomics = 1;
 
-    // TODO
-    cpuext.uscat = cpuext.flagm = cpuext.flagm2 = cpuext.frintts = cpuext.afp = cpuext.rndr = 0;
+    // Read from the registry to get the rest, consider as a success even if it fails
+    HKEY key;
+    ULONGLONG value;
+    DWORD size = sizeof(value);
+    if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0, KEY_READ, &key))
+        return 1;
+
+    if (RegQueryValueExA(key, "CP 4030" /* ID_AA64ISAR0_EL1 */, NULL, NULL, (LPBYTE)&value, &size) == ERROR_SUCCESS) {
+        // TS, bits[55:52]
+        cpuext.flagm = !!((value >> 52) & 0x1);
+        cpuext.flagm2 = !!((value >> 53) & 0x1);
+        // PRINTTS, bits[35:32]
+        cpuext.frintts = !!((value >> 32) & 0x1);
+        // RND, bits[63:60]
+        cpuext.rndr = !!((value >> 60) & 0x1);
+    }
+    size = sizeof(value);
+    if (RegQueryValueExA(key, "CP 4039" /* ID_AA64MMFR1_EL1 */, NULL, NULL, (LPBYTE)&value, &size) == ERROR_SUCCESS) {
+        // AFP, bits[47:44]
+        cpuext.afp = !!((value >> 44) & 0x1);
+    }
+    size = sizeof(value);
+    if (RegQueryValueExA(key, "CP 403A" /* ID_AA64MMFR2_EL1 */, NULL, NULL, (LPBYTE)&value, &size) == ERROR_SUCCESS) {
+        // AT, bits[35:32]
+        cpuext.uscat = !!((value >> 32) & 0x1);
+    }
+
+    RegCloseKey(key);
     return 1;
 }
diff --git a/wine/common/wrt.c b/wine/common/wrt.c
index 82477c1f..188b1da7 100644
--- a/wine/common/wrt.c
+++ b/wine/common/wrt.c
@@ -1,3 +1,4 @@
+#include <stddef.h>
 #include <windows.h>
 #include <ntstatus.h>
 #include <winternl.h>
@@ -239,3 +240,73 @@ BOOL WINAPI IsProcessorFeaturePresent(DWORD feature)
 {
     return RtlIsProcessorFeaturePresent(feature);
 }
+
+LSTATUS WINAPI RegOpenKeyExA(HKEY hkey, LPCSTR name, DWORD options, REGSAM access, PHKEY retkey)
+{
+    if (hkey != HKEY_LOCAL_MACHINE) {
+        printf_log(LOG_NONE, "Unsupported registry key %p\n", hkey);
+        return ERROR_INVALID_HANDLE;
+    }
+
+    UNICODE_STRING rootkeyU;
+    UNICODE_STRING nameU;
+    OBJECT_ATTRIBUTES attr;
+    NTSTATUS status;
+    HANDLE handle;
+    RtlInitUnicodeString(&rootkeyU, L"\\Registry\\Machine");
+    InitializeObjectAttributes(&attr, &rootkeyU, OBJ_CASE_INSENSITIVE, 0, NULL);
+    if (NtOpenKey(&handle, access, &attr)) return RtlNtStatusToDosError(status);
+
+    RtlCreateUnicodeStringFromAsciiz(&nameU, name);
+    InitializeObjectAttributes(&attr, &nameU, OBJ_CASE_INSENSITIVE, handle, NULL);
+    status = NtOpenKey((HANDLE*)retkey, access, &attr);
+    RtlFreeUnicodeString(&nameU);
+    NtClose(handle);
+    return RtlNtStatusToDosError(status);
+}
+
+LSTATUS WINAPI RegQueryValueExA(HKEY hkey, LPCSTR name, LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count)
+{
+    NTSTATUS status;
+    ANSI_STRING nameA;
+    UNICODE_STRING nameW;
+    DWORD total_size, datalen = 0;
+    char buffer[256];
+    KEY_VALUE_PARTIAL_INFORMATION* info = (KEY_VALUE_PARTIAL_INFORMATION*)buffer;
+    static const int info_size = offsetof(KEY_VALUE_PARTIAL_INFORMATION, Data);
+
+    if ((data && !count) || reserved) return ERROR_INVALID_PARAMETER;
+
+    if (count) datalen = *count;
+    if (!data && count) *count = 0;
+
+    RtlInitAnsiString(&nameA, name);
+    if ((status = RtlAnsiStringToUnicodeString(&nameW, &nameA, TRUE)))
+        return RtlNtStatusToDosError(status);
+
+    status = NtQueryValueKey(hkey, &nameW, KeyValuePartialInformation, buffer, sizeof(buffer), &total_size);
+    if (status) {
+        RtlFreeUnicodeString(&nameW);
+        return RtlNtStatusToDosError(status);
+    }
+
+    if (data) {
+        if (total_size - info_size > datalen)
+            status = STATUS_BUFFER_OVERFLOW;
+        else
+            memcpy(data, buffer + info_size, total_size - info_size);
+    } else
+        status = STATUS_SUCCESS;
+
+    if (type) *type = info->Type;
+    if (count) *count = total_size - info_size;
+
+    RtlFreeUnicodeString(&nameW);
+    return RtlNtStatusToDosError(status);
+}
+
+LSTATUS WINAPI RegCloseKey(HKEY hkey)
+{
+    if (!hkey) return ERROR_INVALID_HANDLE;
+    return RtlNtStatusToDosError(NtClose(hkey));
+}
diff --git a/wine/include/wine/compiler.h b/wine/include/wine/compiler.h
index ca7aedf4..b585d152 100644
--- a/wine/include/wine/compiler.h
+++ b/wine/include/wine/compiler.h
@@ -72,6 +72,22 @@ typedef struct _SYSTEM_BASIC_INFORMATION__ {
     BYTE NumberOfProcessors;
 } SYSTEM_BASIC_INFORMATION__, *PSYSTEM_BASIC_INFORMATION__;
 
+typedef struct _KEY_VALUE_PARTIAL_INFORMATION {
+    ULONG TitleIndex;
+    ULONG Type;
+    ULONG DataLength;
+    UCHAR Data[1];
+} KEY_VALUE_PARTIAL_INFORMATION, *PKEY_VALUE_PARTIAL_INFORMATION;
+
+typedef enum _KEY_VALUE_INFORMATION_CLASS {
+    KeyValueBasicInformation,
+    KeyValueFullInformation,
+    KeyValuePartialInformation,
+    KeyValueFullInformationAlign64,
+    KeyValuePartialInformationAlign64,
+    KeyValueLayerInformation,
+} KEY_VALUE_INFORMATION_CLASS;
+
 #define NtCurrentProcess() ((HANDLE)(LONG_PTR) - 1)
 
 NTSTATUS WINAPI RtlWow64GetCurrentCpuArea(USHORT*, void**, void**);
@@ -93,6 +109,8 @@ NTSTATUS WINAPI NtAllocateVirtualMemory(HANDLE, PVOID*, ULONG_PTR, SIZE_T*, ULON
 PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T);
 NTSTATUS WINAPI NtFreeVirtualMemory(HANDLE, PVOID*, SIZE_T*, ULONG);
 BOOLEAN WINAPI RtlIsProcessorFeaturePresent(UINT feature);
+NTSTATUS WINAPI NtOpenKey(HANDLE*, ACCESS_MASK, const OBJECT_ATTRIBUTES*);
+NTSYSAPI NTSTATUS WINAPI NtQueryValueKey(HANDLE, const UNICODE_STRING*, KEY_VALUE_INFORMATION_CLASS, void*, DWORD, DWORD*);
 
 static inline uintptr_t calculate_fs(void)
 {