summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorShawn Hoffman <godisgovernment@gmail.com>2023-01-17 01:23:44 -0800
committerShawn Hoffman <godisgovernment@gmail.com>2023-01-17 01:38:00 -0800
commitdff7f20f9db6210c4b9fe1f0bdd6332abde9f7d9 (patch)
tree990e7794ee72d6163c0860a4f90828f7bc494a68 /Source/Core
parent10fd76889854e2367c39d902d70abf70e1d920f6 (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.cpp24
-rw-r--r--Source/Core/Common/CMakeLists.txt1
-rw-r--r--Source/Core/Common/WindowsRegistry.cpp72
-rw-r--r--Source/Core/Common/WindowsRegistry.h15
-rw-r--r--Source/Core/Core/DolphinAnalytics.cpp22
-rw-r--r--Source/Core/DolphinLib.props2
-rw-r--r--Source/Core/WinUpdater/Platform.cpp11
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};
}