From 6dc95dd078a0c5ad553b58465ddaef7853ccec52 Mon Sep 17 00:00:00 2001 From: luci4 <142809264+l00sy4@users.noreply.github.com> Date: Sun, 12 Apr 2026 11:53:00 +0100 Subject: [PATCH] sysinfo.cpp: Remove registry helpers (#18557) The "caveat" is that said API bypasses compatibility shims so it will always show the true Windows version. --- rpcs3/util/sysinfo.cpp | 119 +++++------------------------------------ 1 file changed, 13 insertions(+), 106 deletions(-) diff --git a/rpcs3/util/sysinfo.cpp b/rpcs3/util/sysinfo.cpp index b894c9af0b..799d85aaca 100755 --- a/rpcs3/util/sysinfo.cpp +++ b/rpcs3/util/sysinfo.cpp @@ -78,91 +78,6 @@ namespace Darwin_ProcessInfo } #endif -#ifdef _WIN32 -#if !defined(ARCH_X64) -namespace utils -{ - // Some helpers for sanity - const auto read_reg_dword = [](HKEY hKey, std::string_view value_name) -> std::pair - { - DWORD val = 0; - DWORD len = sizeof(val); - if (ERROR_SUCCESS != RegQueryValueExA(hKey, value_name.data(), nullptr, nullptr, reinterpret_cast(&val), &len)) - { - return { false, 0 }; - } - return { true, val }; - }; - - const auto read_reg_sz = [](HKEY hKey, std::string_view value_name) -> std::pair - { - constexpr usz MAX_SZ_LEN = 255; - char sz[MAX_SZ_LEN + 1] {}; - DWORD sz_len = MAX_SZ_LEN; - - // Safety; null terminate - sz[0] = 0; - sz[MAX_SZ_LEN] = 0; - - // Read string - if (ERROR_SUCCESS != RegQueryValueExA(hKey, value_name.data(), nullptr, nullptr, reinterpret_cast(sz), &sz_len)) - { - return { false, "" }; - } - - // Safety, force null terminator - if (sz_len < MAX_SZ_LEN) - { - sz[sz_len] = 0; - } - return { true, sz }; - }; - - // Alternative way to read OS version using the registry. - static std::string get_fallback_windows_version() - { - HKEY hKey; - if (ERROR_SUCCESS != RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_READ, &hKey)) - { - return "Unknown Windows"; - } - - // ProductName (SZ) - Actual windows install name e.g Windows 10 Pro) - // CurrentMajorVersionNumber (DWORD) - e.g 10 for windows 10, 11 for windows 11 - // CurrentMinorVersionNumber (DWORD) - usually 0 for newer windows, pairs with major version - // CurrentBuildNumber (SZ) - Windows build number, e.g 19045, used to identify different releases like 23H2, 24H2, etc - // CurrentVersion (SZ) - NT kernel version, e.g 6.3 for Windows 10 - const auto [product_valid, product_name] = read_reg_sz(hKey, "ProductName"); - if (!product_valid) - { - RegCloseKey(hKey); - return "Unknown Windows"; - } - - const auto [check_major, version_major] = read_reg_dword(hKey, "CurrentMajorVersionNumber"); - const auto [check_minor, version_minor] = read_reg_dword(hKey, "CurrentMinorVersionNumber"); - const auto [check_build_no, build_no] = read_reg_sz(hKey, "CurrentBuildNumber"); - const auto [check_nt_ver, nt_ver] = read_reg_sz(hKey, "CurrentVersion"); - - // Close the registry key - RegCloseKey(hKey); - - std::string version_id = "Unknown"; - if (check_major && check_minor && check_build_no) - { - version_id = fmt::format("%u.%u.%s", version_major, version_minor, build_no); - if (check_nt_ver) - { - version_id += " NT" + nt_ver; - } - } - - return fmt::format("Operating system: %s, Version %s", product_name, version_id); - } -} -#endif -#endif - bool utils::has_ssse3() { #if defined(ARCH_X64) @@ -834,33 +749,25 @@ std::string utils::get_OS_version_string() { std::string output; #ifdef _WIN32 - // GetVersionEx is deprecated, RtlGetVersion is kernel-mode only and AnalyticsInfo is UWP only. - // So we're forced to read PEB instead to get Windows version info. It's ugly but works. -#if defined(ARCH_X64) - constexpr DWORD peb_offset = 0x60; - const INT_PTR peb = __readgsqword(peb_offset); - const DWORD version_major = *reinterpret_cast(peb + 0x118); - const DWORD version_minor = *reinterpret_cast(peb + 0x11c); - const WORD build = *reinterpret_cast(peb + 0x120); - const UNICODE_STRING service_pack = *reinterpret_cast(peb + 0x02E8); - const u64 compatibility_mode = *reinterpret_cast(peb + 0x02C8); // Two DWORDs, major & minor version + OSVERSIONINFOW osvi{}; + osvi.dwOSVersionInfoSize = sizeof(osvi); + RtlGetVersion(&osvi); - const bool has_sp = service_pack.Length > 0; - std::vector holder(service_pack.Length + 1, '\0'); + const bool has_sp = osvi.szCSDVersion[0] != L'\0'; + std::vector holder; if (has_sp) { - WideCharToMultiByte(CP_UTF8, 0, service_pack.Buffer, service_pack.Length, - static_cast(holder.data()), static_cast(holder.size()), nullptr, nullptr); + const int len = WideCharToMultiByte(CP_UTF8, 0, osvi.szCSDVersion, -1, + nullptr, 0, nullptr, nullptr); + holder.resize(len); + WideCharToMultiByte(CP_UTF8, 0, osvi.szCSDVersion, -1, + holder.data(), len, nullptr, nullptr); } fmt::append(output, - "Operating system: Windows, Major: %lu, Minor: %lu, Build: %u, Service Pack: %s, Compatibility mode: %llu", - version_major, version_minor, build, has_sp ? holder.data() : "none", compatibility_mode); -#else - // PEB cannot be easily accessed on ARM64, fall back to registry - static const auto s_windows_version = utils::get_fallback_windows_version(); - return s_windows_version; -#endif + "Operating system: Windows, Major: %lu, Minor: %lu, Build: %lu, Service Pack: %s", + osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber, + has_sp ? holder.data() : "none"); #elif defined (__APPLE__) const int major_version = Darwin_Version::getNSmajorVersion(); const int minor_version = Darwin_Version::getNSminorVersion();