Merge pull request #11458 from shuffle2/winuver
windows: prefer os version from registry
This commit is contained in:
commit
8d477c65c9
|
@ -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)
|
||||
|
|
|
@ -270,6 +270,7 @@ if(WIN32)
|
|||
CompatPatches.cpp
|
||||
GL/GLInterface/WGL.cpp
|
||||
GL/GLInterface/WGL.h
|
||||
WindowsRegistry.cpp
|
||||
)
|
||||
elseif(APPLE)
|
||||
target_sources(common PRIVATE
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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"));
|
||||
|
|
|
@ -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" />
|
||||
|
@ -777,6 +778,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" />
|
||||
|
|
|
@ -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};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue