diff options
| author | Shawn Hoffman <godisgovernment@gmail.com> | 2023-01-17 01:23:44 -0800 |
|---|---|---|
| committer | Shawn Hoffman <godisgovernment@gmail.com> | 2023-01-17 01:38:00 -0800 |
| commit | dff7f20f9db6210c4b9fe1f0bdd6332abde9f7d9 (patch) | |
| tree | 990e7794ee72d6163c0860a4f90828f7bc494a68 /Source/Core | |
| parent | 10fd76889854e2367c39d902d70abf70e1d920f6 (diff) | |
windows: prefer os version from registry
this value is not modified by compatibility mode
drop reporting service pack numbers. no longer used
Diffstat (limited to 'Source/Core')
| -rw-r--r-- | Source/Core/Common/ArmCPUDetect.cpp | 24 | ||||
| -rw-r--r-- | Source/Core/Common/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | Source/Core/Common/WindowsRegistry.cpp | 72 | ||||
| -rw-r--r-- | Source/Core/Common/WindowsRegistry.h | 15 | ||||
| -rw-r--r-- | Source/Core/Core/DolphinAnalytics.cpp | 22 | ||||
| -rw-r--r-- | Source/Core/DolphinLib.props | 2 | ||||
| -rw-r--r-- | Source/Core/WinUpdater/Platform.cpp | 11 |
7 files changed, 102 insertions, 45 deletions
diff --git a/Source/Core/Common/ArmCPUDetect.cpp b/Source/Core/Common/ArmCPUDetect.cpp index 7fe2d14220..43c0063f78 100644 --- a/Source/Core/Common/ArmCPUDetect.cpp +++ b/Source/Core/Common/ArmCPUDetect.cpp @@ -14,6 +14,7 @@ #elif defined(_WIN32) #include <Windows.h> #include <arm64intr.h> +#include "Common/WindowsRegistry.h" #else #ifndef __FreeBSD__ #include <asm/hwcap.h> @@ -55,33 +56,14 @@ static constexpr char SUBKEY_CORE0[] = R"(HARDWARE\DESCRIPTION\System\CentralPro // There are some other maybe-interesting values nearby, BIOS info etc. static bool ReadProcessorString(std::string* value, const std::string& name) { - const DWORD flags = RRF_RT_REG_SZ | RRF_NOEXPAND; - DWORD value_len = 0; - auto status = RegGetValueA(HKEY_LOCAL_MACHINE, SUBKEY_CORE0, name.c_str(), flags, nullptr, - nullptr, &value_len); - if (status != ERROR_SUCCESS && status != ERROR_MORE_DATA) - return false; - - value->resize(value_len); - status = RegGetValueA(HKEY_LOCAL_MACHINE, SUBKEY_CORE0, name.c_str(), flags, nullptr, - value->data(), &value_len); - if (status != ERROR_SUCCESS) - { - value->clear(); - return false; - } - - TruncateToCString(value); - return true; + return WindowsRegistry::ReadValue(value, SUBKEY_CORE0, name); } // Read cached register values from the registry static bool ReadPrivilegedCPReg(u64* value, u32 reg) { - DWORD value_len = sizeof(*value); // Not sure if the value name is padded or not - return RegGetValueA(HKEY_LOCAL_MACHINE, SUBKEY_CORE0, fmt::format("CP {:x}", reg).c_str(), - RRF_RT_REG_QWORD, nullptr, value, &value_len) == ERROR_SUCCESS; + return WindowsRegistry::ReadValue(value, SUBKEY_CORE0, fmt::format("CP {:x}", reg).c_str()); } static bool Read_MIDR_EL1(u64* value) diff --git a/Source/Core/Common/CMakeLists.txt b/Source/Core/Common/CMakeLists.txt index 2ae474ab64..5d9290549c 100644 --- a/Source/Core/Common/CMakeLists.txt +++ b/Source/Core/Common/CMakeLists.txt @@ -270,6 +270,7 @@ if(WIN32) CompatPatches.cpp GL/GLInterface/WGL.cpp GL/GLInterface/WGL.h + WindowsRegistry.cpp ) elseif(APPLE) target_sources(common PRIVATE diff --git a/Source/Core/Common/WindowsRegistry.cpp b/Source/Core/Common/WindowsRegistry.cpp new file mode 100644 index 0000000000..4b6f1f2c24 --- /dev/null +++ b/Source/Core/Common/WindowsRegistry.cpp @@ -0,0 +1,72 @@ +#include "Common/WindowsRegistry.h" + +#include <Windows.h> +#include <string> +#include <type_traits> +#include "Common/StringUtil.h" + +namespace WindowsRegistry +{ +template <typename T> +bool ReadValue(T* value, const std::string& subkey, const std::string& name) +{ + DWORD flags = 0; + static_assert(std::is_integral_v<T> && (sizeof(T) == sizeof(u32) || sizeof(T) == sizeof(u64)), + "Unsupported type"); + if constexpr (sizeof(T) == sizeof(u32)) + flags = RRF_RT_REG_DWORD; + else if constexpr (sizeof(T) == sizeof(u64)) + flags = RRF_RT_REG_QWORD; + + DWORD value_len = sizeof(*value); + return RegGetValueA(HKEY_LOCAL_MACHINE, subkey.c_str(), name.c_str(), flags, nullptr, value, + &value_len) == ERROR_SUCCESS; +} + +template <> +bool ReadValue(std::string* value, const std::string& subkey, const std::string& name) +{ + const DWORD flags = RRF_RT_REG_SZ | RRF_NOEXPAND; + DWORD value_len = 0; + auto status = RegGetValueA(HKEY_LOCAL_MACHINE, subkey.c_str(), name.c_str(), flags, nullptr, + nullptr, &value_len); + if (status != ERROR_SUCCESS && status != ERROR_MORE_DATA) + return false; + + value->resize(value_len); + status = RegGetValueA(HKEY_LOCAL_MACHINE, subkey.c_str(), name.c_str(), flags, nullptr, + value->data(), &value_len); + if (status != ERROR_SUCCESS) + { + value->clear(); + return false; + } + + TruncateToCString(value); + return true; +} + +OSVERSIONINFOW GetOSVersion() +{ + // PEB may have faked data if the binary is launched with "compatibility mode" enabled. + // Try to read real OS version from registry. + const char* subkey = R"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)"; + OSVERSIONINFOW info{.dwOSVersionInfoSize = sizeof(info)}; + std::string build_str; + if (!ReadValue(&info.dwMajorVersion, subkey, "CurrentMajorVersionNumber") || + !ReadValue(&info.dwMinorVersion, subkey, "CurrentMinorVersionNumber") || + !ReadValue(&build_str, subkey, "CurrentBuildNumber") || + !TryParse(build_str, &info.dwBuildNumber)) + { + // Fallback to version from PEB + typedef DWORD(WINAPI * RtlGetVersion_t)(PRTL_OSVERSIONINFOW); + auto RtlGetVersion = + (RtlGetVersion_t)GetProcAddress(GetModuleHandle(TEXT("ntdll")), "RtlGetVersion"); + RtlGetVersion(&info); + // Clear fields which would not be filled in by registry query + info.dwPlatformId = 0; + info.szCSDVersion[0] = L'\0'; + } + return info; +} +}; // namespace WindowsRegistry diff --git a/Source/Core/Common/WindowsRegistry.h b/Source/Core/Common/WindowsRegistry.h new file mode 100644 index 0000000000..4472a37e0e --- /dev/null +++ b/Source/Core/Common/WindowsRegistry.h @@ -0,0 +1,15 @@ +#pragma once + +#include <Windows.h> + +namespace WindowsRegistry +{ +template <typename T> +bool ReadValue(T* value, const std::string& subkey, const std::string& name); +template bool ReadValue(u32* value, const std::string& subkey, const std::string& name); +template bool ReadValue(u64* value, const std::string& subkey, const std::string& name); +template <> +bool ReadValue(std::string* value, const std::string& subkey, const std::string& name); + +OSVERSIONINFOW GetOSVersion(); +}; // namespace WindowsRegistry diff --git a/Source/Core/Core/DolphinAnalytics.cpp b/Source/Core/Core/DolphinAnalytics.cpp index ea551143ec..b999b55e2a 100644 --- a/Source/Core/Core/DolphinAnalytics.cpp +++ b/Source/Core/Core/DolphinAnalytics.cpp @@ -12,7 +12,8 @@ #include <fmt/format.h> #if defined(_WIN32) -#include <windows.h> +#include <Windows.h> +#include "Common/WindowsRegistry.h" #elif defined(__APPLE__) #include <objc/message.h> #elif defined(ANDROID) @@ -265,21 +266,10 @@ void DolphinAnalytics::MakeBaseBuilder() #if defined(_WIN32) builder.AddData("os-type", "windows"); - // Windows 8 removes support for GetVersionEx and such. Stupid. - DWORD(WINAPI * RtlGetVersion)(LPOSVERSIONINFOEXW); - *(FARPROC*)&RtlGetVersion = GetProcAddress(GetModuleHandle(TEXT("ntdll")), "RtlGetVersion"); - - OSVERSIONINFOEXW winver; - winver.dwOSVersionInfoSize = sizeof(winver); - if (RtlGetVersion != nullptr) - { - RtlGetVersion(&winver); - builder.AddData("win-ver-major", static_cast<u32>(winver.dwMajorVersion)); - builder.AddData("win-ver-minor", static_cast<u32>(winver.dwMinorVersion)); - builder.AddData("win-ver-build", static_cast<u32>(winver.dwBuildNumber)); - builder.AddData("win-ver-spmajor", static_cast<u32>(winver.wServicePackMajor)); - builder.AddData("win-ver-spminor", static_cast<u32>(winver.wServicePackMinor)); - } + const auto winver = WindowsRegistry::GetOSVersion(); + builder.AddData("win-ver-major", static_cast<u32>(winver.dwMajorVersion)); + builder.AddData("win-ver-minor", static_cast<u32>(winver.dwMinorVersion)); + builder.AddData("win-ver-build", static_cast<u32>(winver.dwBuildNumber)); #elif defined(ANDROID) builder.AddData("os-type", "android"); builder.AddData("android-manufacturer", s_get_val_func("DEVICE_MANUFACTURER")); diff --git a/Source/Core/DolphinLib.props b/Source/Core/DolphinLib.props index 1ae8d7212a..ebe61a1560 100644 --- a/Source/Core/DolphinLib.props +++ b/Source/Core/DolphinLib.props @@ -157,6 +157,7 @@ <ClInclude Include="Common\UPnP.h" /> <ClInclude Include="Common\VariantUtil.h" /> <ClInclude Include="Common\Version.h" /> + <ClInclude Include="Common\WindowsRegistry.h" /> <ClInclude Include="Common\WindowSystemInfo.h" /> <ClInclude Include="Common\WorkQueueThread.h" /> <ClInclude Include="Core\ActionReplay.h" /> @@ -778,6 +779,7 @@ <ClCompile Include="Common\Timer.cpp" /> <ClCompile Include="Common\TraversalClient.cpp" /> <ClCompile Include="Common\UPnP.cpp" /> + <ClCompile Include="Common\WindowsRegistry.cpp" /> <ClCompile Include="Common\Version.cpp" /> <ClCompile Include="Core\ActionReplay.cpp" /> <ClCompile Include="Core\ARDecrypt.cpp" /> diff --git a/Source/Core/WinUpdater/Platform.cpp b/Source/Core/WinUpdater/Platform.cpp index 565d53c413..f60a6621c0 100644 --- a/Source/Core/WinUpdater/Platform.cpp +++ b/Source/Core/WinUpdater/Platform.cpp @@ -10,6 +10,7 @@ #include "Common/IOFile.h" #include "Common/ScopeGuard.h" #include "Common/StringUtil.h" +#include "Common/WindowsRegistry.h" #include "UpdaterCommon/Platform.h" #include "UpdaterCommon/UI.h" @@ -133,9 +134,7 @@ static const char* VCRuntimeRegistrySubkey() static bool ReadVCRuntimeVersionField(u32* value, const char* name) { - DWORD value_len = sizeof(*value); - return RegGetValueA(HKEY_LOCAL_MACHINE, VCRuntimeRegistrySubkey(), name, RRF_RT_REG_DWORD, - nullptr, value, &value_len) == ERROR_SUCCESS; + return WindowsRegistry::ReadValue(value, VCRuntimeRegistrySubkey(), name); } static std::optional<BuildVersion> GetInstalledVCRuntimeVersion() @@ -219,11 +218,7 @@ static bool VCRuntimeUpdate(const BuildInfo& build_info) static BuildVersion CurrentOSVersion() { - typedef DWORD(WINAPI * RtlGetVersion_t)(PRTL_OSVERSIONINFOW); - auto RtlGetVersion = - (RtlGetVersion_t)GetProcAddress(GetModuleHandle(TEXT("ntdll")), "RtlGetVersion"); - RTL_OSVERSIONINFOW info{.dwOSVersionInfoSize = sizeof(info)}; - RtlGetVersion(&info); + OSVERSIONINFOW info = WindowsRegistry::GetOSVersion(); return {.major = info.dwMajorVersion, .minor = info.dwMinorVersion, .build = info.dwBuildNumber}; } |
