|
1 | 1 | /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
|
2 | 2 |
|
3 | 3 | #include "base/atomic-file.hpp"
|
| 4 | +#include "base/defer.hpp" |
4 | 5 | #include "base/utility.hpp"
|
5 | 6 | #include "base/convert.hpp"
|
6 | 7 | #include "base/application.hpp"
|
|
52 | 53 | #ifdef _WIN32
|
53 | 54 | # include <VersionHelpers.h>
|
54 | 55 | # include <windows.h>
|
| 56 | +# include <winreg.h> |
55 | 57 | # include <io.h>
|
56 | 58 | # include <msi.h>
|
57 | 59 | # include <shlobj.h>
|
@@ -1533,28 +1535,55 @@ static String UnameHelper(char type)
|
1533 | 1535 | }
|
1534 | 1536 | }
|
1535 | 1537 | #endif /* _WIN32 */
|
| 1538 | +struct RegistryString |
| 1539 | +{ |
| 1540 | + union { |
| 1541 | + BYTE AsBytes[512]; |
| 1542 | + char AsChars[1] = {0}; |
| 1543 | + } Data; |
| 1544 | + |
| 1545 | + DWORD Size = sizeof(Data); |
| 1546 | +}; |
| 1547 | + |
| 1548 | +static const char * const l_RegCurrentVersion = R"EOF(SOFTWARE\Microsoft\Windows NT\CurrentVersion)EOF"; |
| 1549 | + |
1536 | 1550 | static bool ReleaseHelper(String *platformName, String *platformVersion)
|
1537 | 1551 | {
|
1538 | 1552 | #ifdef _WIN32
|
1539 | 1553 | if (platformName)
|
1540 | 1554 | *platformName = "Windows";
|
1541 | 1555 |
|
1542 | 1556 | if (platformVersion) {
|
1543 |
| - *platformVersion = "Vista"; |
1544 |
| - if (IsWindowsVistaSP1OrGreater()) |
1545 |
| - *platformVersion = "Vista SP1"; |
1546 |
| - if (IsWindowsVistaSP2OrGreater()) |
1547 |
| - *platformVersion = "Vista SP2"; |
1548 |
| - if (IsWindows7OrGreater()) |
1549 |
| - *platformVersion = "7"; |
1550 |
| - if (IsWindows7SP1OrGreater()) |
1551 |
| - *platformVersion = "7 SP1"; |
1552 |
| - if (IsWindows8OrGreater()) |
1553 |
| - *platformVersion = "8"; |
1554 |
| - if (IsWindows8Point1OrGreater()) |
1555 |
| - *platformVersion = "8.1 or greater"; |
1556 |
| - if (IsWindowsServer()) |
1557 |
| - *platformVersion += " (Server)"; |
| 1557 | + HKEY hKey; |
| 1558 | + auto err (RegOpenKeyExA(HKEY_LOCAL_MACHINE, l_RegCurrentVersion, 0, KEY_READ, &hKey)); |
| 1559 | + |
| 1560 | + if (err == ERROR_SUCCESS) { |
| 1561 | + Defer regCloseKey ([hKey]() { (void)RegCloseKey(hKey); }); |
| 1562 | + RegistryString productName; |
| 1563 | + auto err (RegQueryValueExA(hKey, "ProductName", nullptr, nullptr, productName.Data.AsBytes, &productName.Size)); |
| 1564 | + |
| 1565 | + if (err == ERROR_SUCCESS) { |
| 1566 | + *platformVersion = productName.Data.AsChars; |
| 1567 | + |
| 1568 | + RegistryString displayVersion; |
| 1569 | + |
| 1570 | + if (RegQueryValueExA(hKey, "DisplayVersion", nullptr, nullptr, displayVersion.Data.AsBytes, &displayVersion.Size) == ERROR_SUCCESS) { |
| 1571 | + *platformVersion += " "; |
| 1572 | + *platformVersion += displayVersion.Data.AsChars; |
| 1573 | + } else { |
| 1574 | + RegistryString releaseId; |
| 1575 | + |
| 1576 | + if (RegQueryValueExA(hKey, "ReleaseId", nullptr, nullptr, releaseId.Data.AsBytes, &releaseId.Size) == ERROR_SUCCESS) { |
| 1577 | + *platformVersion += " "; |
| 1578 | + *platformVersion += releaseId.Data.AsChars; |
| 1579 | + } |
| 1580 | + } |
| 1581 | + } else { |
| 1582 | + *platformVersion = "Unknown (Can't query HKEY_LOCAL_MACHINE\\" + (l_RegCurrentVersion + ("\\ProductName: " + Utility::FormatErrorNumber(err))) + ")"; |
| 1583 | + } |
| 1584 | + } else { |
| 1585 | + *platformVersion = "Unknown (Can't open HKEY_LOCAL_MACHINE\\" + (l_RegCurrentVersion + (": " + Utility::FormatErrorNumber(err))) + ")"; |
| 1586 | + } |
1558 | 1587 | }
|
1559 | 1588 |
|
1560 | 1589 | return true;
|
@@ -1718,14 +1747,28 @@ String Utility::GetPlatformKernel()
|
1718 | 1747 | String Utility::GetPlatformKernelVersion()
|
1719 | 1748 | {
|
1720 | 1749 | #ifdef _WIN32
|
1721 |
| - OSVERSIONINFO info; |
1722 |
| - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); |
1723 |
| - GetVersionEx(&info); |
| 1750 | + HKEY hKey; |
| 1751 | + auto err (RegOpenKeyExA(HKEY_LOCAL_MACHINE, l_RegCurrentVersion, 0, KEY_READ, &hKey)); |
1724 | 1752 |
|
1725 |
| - std::ostringstream msgbuf; |
1726 |
| - msgbuf << info.dwMajorVersion << "." << info.dwMinorVersion; |
| 1753 | + if (err == ERROR_SUCCESS) { |
| 1754 | + Defer regCloseKey ([hKey]() { (void)RegCloseKey(hKey); }); |
| 1755 | + RegistryString currentVersion; |
| 1756 | + auto err (RegQueryValueExA(hKey, "CurrentVersion", nullptr, nullptr, currentVersion.Data.AsBytes, ¤tVersion.Size)); |
1727 | 1757 |
|
1728 |
| - return msgbuf.str(); |
| 1758 | + if (err == ERROR_SUCCESS) { |
| 1759 | + RegistryString currentBuildNumber; |
| 1760 | + |
| 1761 | + if (RegQueryValueExA(hKey, "CurrentBuildNumber", nullptr, nullptr, currentBuildNumber.Data.AsBytes, ¤tBuildNumber.Size) == ERROR_SUCCESS) { |
| 1762 | + return String(currentVersion.Data.AsChars) + "." + currentBuildNumber.Data.AsChars; |
| 1763 | + } else { |
| 1764 | + return currentVersion.Data.AsChars; |
| 1765 | + } |
| 1766 | + } else { |
| 1767 | + return "Unknown (Can't query HKEY_LOCAL_MACHINE\\" + (l_RegCurrentVersion + ("\\CurrentVersion: " + Utility::FormatErrorNumber(err))) + ")"; |
| 1768 | + } |
| 1769 | + } else { |
| 1770 | + return "Unknown (Can't open HKEY_LOCAL_MACHINE\\" + (l_RegCurrentVersion + (": " + Utility::FormatErrorNumber(err))) + ")"; |
| 1771 | + } |
1729 | 1772 | #else /* _WIN32 */
|
1730 | 1773 | return UnameHelper('r');
|
1731 | 1774 | #endif /* _WIN32 */
|
|
0 commit comments