diff --git a/lib/base/utility.cpp b/lib/base/utility.cpp index 207c63fc482..8f2ec21288f 100644 --- a/lib/base/utility.cpp +++ b/lib/base/utility.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "base/atomic-file.hpp" +#include "base/defer.hpp" #include "base/utility.hpp" #include "base/convert.hpp" #include "base/application.hpp" @@ -55,6 +56,7 @@ #ifdef _WIN32 # include # include +# include # include # include # include @@ -1625,6 +1627,19 @@ static String UnameHelper(char type) } } #endif /* _WIN32 */ + +#ifdef _WIN32 +struct RegistryString +{ + char Data[512] = {0}; + DWORD Size = sizeof(Data); + + BYTE* AsBytes() { return reinterpret_cast(&Data); } +}; + +static const char * const l_RegCurrentVersion = R"EOF(SOFTWARE\Microsoft\Windows NT\CurrentVersion)EOF"; +#endif /* _WIN32 */ + static bool ReleaseHelper(String *platformName, String *platformVersion) { #ifdef _WIN32 @@ -1632,21 +1647,36 @@ static bool ReleaseHelper(String *platformName, String *platformVersion) *platformName = "Windows"; if (platformVersion) { - *platformVersion = "Vista"; - if (IsWindowsVistaSP1OrGreater()) - *platformVersion = "Vista SP1"; - if (IsWindowsVistaSP2OrGreater()) - *platformVersion = "Vista SP2"; - if (IsWindows7OrGreater()) - *platformVersion = "7"; - if (IsWindows7SP1OrGreater()) - *platformVersion = "7 SP1"; - if (IsWindows8OrGreater()) - *platformVersion = "8"; - if (IsWindows8Point1OrGreater()) - *platformVersion = "8.1 or greater"; - if (IsWindowsServer()) - *platformVersion += " (Server)"; + HKEY hKey; + auto err (RegOpenKeyExA(HKEY_LOCAL_MACHINE, l_RegCurrentVersion, 0, KEY_READ, &hKey)); + + if (err == ERROR_SUCCESS) { + Defer regCloseKey ([hKey]() { (void)RegCloseKey(hKey); }); + RegistryString productName; + auto err (RegQueryValueExA(hKey, "ProductName", nullptr, nullptr, productName.AsBytes(), &productName.Size)); + + if (err == ERROR_SUCCESS) { + *platformVersion = productName.Data; + + RegistryString displayVersion; + + if (RegQueryValueExA(hKey, "DisplayVersion", nullptr, nullptr, displayVersion.AsBytes(), &displayVersion.Size) == ERROR_SUCCESS) { + *platformVersion += " "; + *platformVersion += displayVersion.Data; + } else { + RegistryString releaseId; + + if (RegQueryValueExA(hKey, "ReleaseId", nullptr, nullptr, releaseId.AsBytes(), &releaseId.Size) == ERROR_SUCCESS) { + *platformVersion += " "; + *platformVersion += releaseId.Data; + } + } + } else { + *platformVersion = "Unknown (Can't query HKEY_LOCAL_MACHINE\\" + (l_RegCurrentVersion + ("\\ProductName: " + Utility::FormatErrorNumber(err))) + ")"; + } + } else { + *platformVersion = "Unknown (Can't open HKEY_LOCAL_MACHINE\\" + (l_RegCurrentVersion + (": " + Utility::FormatErrorNumber(err))) + ")"; + } } return true; @@ -1744,14 +1774,28 @@ String Utility::GetPlatformKernel() String Utility::GetPlatformKernelVersion() { #ifdef _WIN32 - OSVERSIONINFO info; - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx(&info); + HKEY hKey; + auto err (RegOpenKeyExA(HKEY_LOCAL_MACHINE, l_RegCurrentVersion, 0, KEY_READ, &hKey)); - std::ostringstream msgbuf; - msgbuf << info.dwMajorVersion << "." << info.dwMinorVersion; + if (err == ERROR_SUCCESS) { + Defer regCloseKey ([hKey]() { (void)RegCloseKey(hKey); }); + RegistryString currentVersion; + auto err (RegQueryValueExA(hKey, "CurrentVersion", nullptr, nullptr, currentVersion.AsBytes(), ¤tVersion.Size)); - return msgbuf.str(); + if (err == ERROR_SUCCESS) { + RegistryString currentBuildNumber; + + if (RegQueryValueExA(hKey, "CurrentBuildNumber", nullptr, nullptr, currentBuildNumber.AsBytes(), ¤tBuildNumber.Size) == ERROR_SUCCESS) { + return String(currentVersion.Data) + "." + currentBuildNumber.Data; + } else { + return currentVersion.Data; + } + } else { + return "Unknown (Can't query HKEY_LOCAL_MACHINE\\" + (l_RegCurrentVersion + ("\\CurrentVersion: " + Utility::FormatErrorNumber(err))) + ")"; + } + } else { + return "Unknown (Can't open HKEY_LOCAL_MACHINE\\" + (l_RegCurrentVersion + (": " + Utility::FormatErrorNumber(err))) + ")"; + } #else /* _WIN32 */ return UnameHelper('r'); #endif /* _WIN32 */