|
2 | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
3 | 3 |
|
4 | 4 | #include "base/atomic-file.hpp" |
| 5 | +#include "base/defer.hpp" |
5 | 6 | #include "base/utility.hpp" |
6 | 7 | #include "base/convert.hpp" |
7 | 8 | #include "base/application.hpp" |
|
55 | 56 | #ifdef _WIN32 |
56 | 57 | # include <VersionHelpers.h> |
57 | 58 | # include <windows.h> |
| 59 | +# include <winreg.h> |
58 | 60 | # include <io.h> |
59 | 61 | # include <msi.h> |
60 | 62 | # include <shlobj.h> |
@@ -1625,28 +1627,56 @@ static String UnameHelper(char type) |
1625 | 1627 | } |
1626 | 1628 | } |
1627 | 1629 | #endif /* _WIN32 */ |
| 1630 | + |
| 1631 | +#ifdef _WIN32 |
| 1632 | +struct RegistryString |
| 1633 | +{ |
| 1634 | + char Data[512] = {0}; |
| 1635 | + DWORD Size = sizeof(Data); |
| 1636 | + |
| 1637 | + BYTE* AsBytes() { return reinterpret_cast<BYTE*>(&Data); } |
| 1638 | +}; |
| 1639 | + |
| 1640 | +static const char * const l_RegCurrentVersion = R"EOF(SOFTWARE\Microsoft\Windows NT\CurrentVersion)EOF"; |
| 1641 | +#endif /* _WIN32 */ |
| 1642 | + |
1628 | 1643 | static bool ReleaseHelper(String *platformName, String *platformVersion) |
1629 | 1644 | { |
1630 | 1645 | #ifdef _WIN32 |
1631 | 1646 | if (platformName) |
1632 | 1647 | *platformName = "Windows"; |
1633 | 1648 |
|
1634 | 1649 | if (platformVersion) { |
1635 | | - *platformVersion = "Vista"; |
1636 | | - if (IsWindowsVistaSP1OrGreater()) |
1637 | | - *platformVersion = "Vista SP1"; |
1638 | | - if (IsWindowsVistaSP2OrGreater()) |
1639 | | - *platformVersion = "Vista SP2"; |
1640 | | - if (IsWindows7OrGreater()) |
1641 | | - *platformVersion = "7"; |
1642 | | - if (IsWindows7SP1OrGreater()) |
1643 | | - *platformVersion = "7 SP1"; |
1644 | | - if (IsWindows8OrGreater()) |
1645 | | - *platformVersion = "8"; |
1646 | | - if (IsWindows8Point1OrGreater()) |
1647 | | - *platformVersion = "8.1 or greater"; |
1648 | | - if (IsWindowsServer()) |
1649 | | - *platformVersion += " (Server)"; |
| 1650 | + HKEY hKey; |
| 1651 | + auto err (RegOpenKeyExA(HKEY_LOCAL_MACHINE, l_RegCurrentVersion, 0, KEY_READ, &hKey)); |
| 1652 | + |
| 1653 | + if (err == ERROR_SUCCESS) { |
| 1654 | + Defer regCloseKey ([hKey]() { (void)RegCloseKey(hKey); }); |
| 1655 | + RegistryString productName; |
| 1656 | + auto err (RegQueryValueExA(hKey, "ProductName", nullptr, nullptr, productName.AsBytes(), &productName.Size)); |
| 1657 | + |
| 1658 | + if (err == ERROR_SUCCESS) { |
| 1659 | + *platformVersion = productName.Data; |
| 1660 | + |
| 1661 | + RegistryString displayVersion; |
| 1662 | + |
| 1663 | + if (RegQueryValueExA(hKey, "DisplayVersion", nullptr, nullptr, displayVersion.AsBytes(), &displayVersion.Size) == ERROR_SUCCESS) { |
| 1664 | + *platformVersion += " "; |
| 1665 | + *platformVersion += displayVersion.Data; |
| 1666 | + } else { |
| 1667 | + RegistryString releaseId; |
| 1668 | + |
| 1669 | + if (RegQueryValueExA(hKey, "ReleaseId", nullptr, nullptr, releaseId.AsBytes(), &releaseId.Size) == ERROR_SUCCESS) { |
| 1670 | + *platformVersion += " "; |
| 1671 | + *platformVersion += releaseId.Data; |
| 1672 | + } |
| 1673 | + } |
| 1674 | + } else { |
| 1675 | + *platformVersion = "Unknown (Can't query HKEY_LOCAL_MACHINE\\" + (l_RegCurrentVersion + ("\\ProductName: " + Utility::FormatErrorNumber(err))) + ")"; |
| 1676 | + } |
| 1677 | + } else { |
| 1678 | + *platformVersion = "Unknown (Can't open HKEY_LOCAL_MACHINE\\" + (l_RegCurrentVersion + (": " + Utility::FormatErrorNumber(err))) + ")"; |
| 1679 | + } |
1650 | 1680 | } |
1651 | 1681 |
|
1652 | 1682 | return true; |
@@ -1744,14 +1774,28 @@ String Utility::GetPlatformKernel() |
1744 | 1774 | String Utility::GetPlatformKernelVersion() |
1745 | 1775 | { |
1746 | 1776 | #ifdef _WIN32 |
1747 | | - OSVERSIONINFO info; |
1748 | | - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); |
1749 | | - GetVersionEx(&info); |
| 1777 | + HKEY hKey; |
| 1778 | + auto err (RegOpenKeyExA(HKEY_LOCAL_MACHINE, l_RegCurrentVersion, 0, KEY_READ, &hKey)); |
1750 | 1779 |
|
1751 | | - std::ostringstream msgbuf; |
1752 | | - msgbuf << info.dwMajorVersion << "." << info.dwMinorVersion; |
| 1780 | + if (err == ERROR_SUCCESS) { |
| 1781 | + Defer regCloseKey ([hKey]() { (void)RegCloseKey(hKey); }); |
| 1782 | + RegistryString currentVersion; |
| 1783 | + auto err (RegQueryValueExA(hKey, "CurrentVersion", nullptr, nullptr, currentVersion.AsBytes(), ¤tVersion.Size)); |
1753 | 1784 |
|
1754 | | - return msgbuf.str(); |
| 1785 | + if (err == ERROR_SUCCESS) { |
| 1786 | + RegistryString currentBuildNumber; |
| 1787 | + |
| 1788 | + if (RegQueryValueExA(hKey, "CurrentBuildNumber", nullptr, nullptr, currentBuildNumber.AsBytes(), ¤tBuildNumber.Size) == ERROR_SUCCESS) { |
| 1789 | + return String(currentVersion.Data) + "." + currentBuildNumber.Data; |
| 1790 | + } else { |
| 1791 | + return currentVersion.Data; |
| 1792 | + } |
| 1793 | + } else { |
| 1794 | + return "Unknown (Can't query HKEY_LOCAL_MACHINE\\" + (l_RegCurrentVersion + ("\\CurrentVersion: " + Utility::FormatErrorNumber(err))) + ")"; |
| 1795 | + } |
| 1796 | + } else { |
| 1797 | + return "Unknown (Can't open HKEY_LOCAL_MACHINE\\" + (l_RegCurrentVersion + (": " + Utility::FormatErrorNumber(err))) + ")"; |
| 1798 | + } |
1755 | 1799 | #else /* _WIN32 */ |
1756 | 1800 | return UnameHelper('r'); |
1757 | 1801 | #endif /* _WIN32 */ |
|
0 commit comments