diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2025-06-17 15:54:58 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-17 09:54:58 +0200 |
| commit | 71220b7fef4466f98cc78b1d013755aca8e217c6 (patch) | |
| tree | 22e553abee39ed636e04a59d1b0e782a83cf739d | |
| parent | ae0c91dce0671c176321fc72bfa69f1731d4aa2e (diff) | |
| download | box64-71220b7fef4466f98cc78b1d013755aca8e217c6.tar.gz box64-71220b7fef4466f98cc78b1d013755aca8e217c6.zip | |
[WOW64] Finished host extension detection (#2755)
| -rw-r--r-- | src/os/hostext_wine.c | 31 | ||||
| -rw-r--r-- | wine/common/wrt.c | 71 | ||||
| -rw-r--r-- | wine/include/wine/compiler.h | 18 |
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) { |