|
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" |
|
54 | 55 | #ifdef _WIN32 |
55 | 56 | # include <VersionHelpers.h> |
56 | 57 | # include <windows.h> |
| 58 | +# include <winreg.h> |
57 | 59 | # include <io.h> |
58 | 60 | # include <msi.h> |
59 | 61 | # include <shlobj.h> |
@@ -1584,28 +1586,58 @@ static String UnameHelper(char type) |
1584 | 1586 | } |
1585 | 1587 | } |
1586 | 1588 | #endif /* _WIN32 */ |
| 1589 | + |
| 1590 | +#ifdef _WIN32 |
| 1591 | +struct RegistryString |
| 1592 | +{ |
| 1593 | + union { |
| 1594 | + BYTE AsBytes[512]; |
| 1595 | + char AsChars[1] = {0}; |
| 1596 | + } Data; |
| 1597 | + |
| 1598 | + DWORD Size = sizeof(Data); |
| 1599 | +}; |
| 1600 | + |
| 1601 | +static const char * const l_RegCurrentVersion = R"EOF(SOFTWARE\Microsoft\Windows NT\CurrentVersion)EOF"; |
| 1602 | +#endif /* _WIN32 */ |
| 1603 | + |
1587 | 1604 | static bool ReleaseHelper(String *platformName, String *platformVersion) |
1588 | 1605 | { |
1589 | 1606 | #ifdef _WIN32 |
1590 | 1607 | if (platformName) |
1591 | 1608 | *platformName = "Windows"; |
1592 | 1609 |
|
1593 | 1610 | if (platformVersion) { |
1594 | | - *platformVersion = "Vista"; |
1595 | | - if (IsWindowsVistaSP1OrGreater()) |
1596 | | - *platformVersion = "Vista SP1"; |
1597 | | - if (IsWindowsVistaSP2OrGreater()) |
1598 | | - *platformVersion = "Vista SP2"; |
1599 | | - if (IsWindows7OrGreater()) |
1600 | | - *platformVersion = "7"; |
1601 | | - if (IsWindows7SP1OrGreater()) |
1602 | | - *platformVersion = "7 SP1"; |
1603 | | - if (IsWindows8OrGreater()) |
1604 | | - *platformVersion = "8"; |
1605 | | - if (IsWindows8Point1OrGreater()) |
1606 | | - *platformVersion = "8.1 or greater"; |
1607 | | - if (IsWindowsServer()) |
1608 | | - *platformVersion += " (Server)"; |
| 1611 | + HKEY hKey; |
| 1612 | + auto err (RegOpenKeyExA(HKEY_LOCAL_MACHINE, l_RegCurrentVersion, 0, KEY_READ, &hKey)); |
| 1613 | + |
| 1614 | + if (err == ERROR_SUCCESS) { |
| 1615 | + Defer regCloseKey ([hKey]() { (void)RegCloseKey(hKey); }); |
| 1616 | + RegistryString productName; |
| 1617 | + auto err (RegQueryValueExA(hKey, "ProductName", nullptr, nullptr, productName.Data.AsBytes, &productName.Size)); |
| 1618 | + |
| 1619 | + if (err == ERROR_SUCCESS) { |
| 1620 | + *platformVersion = productName.Data.AsChars; |
| 1621 | + |
| 1622 | + RegistryString displayVersion; |
| 1623 | + |
| 1624 | + if (RegQueryValueExA(hKey, "DisplayVersion", nullptr, nullptr, displayVersion.Data.AsBytes, &displayVersion.Size) == ERROR_SUCCESS) { |
| 1625 | + *platformVersion += " "; |
| 1626 | + *platformVersion += displayVersion.Data.AsChars; |
| 1627 | + } else { |
| 1628 | + RegistryString releaseId; |
| 1629 | + |
| 1630 | + if (RegQueryValueExA(hKey, "ReleaseId", nullptr, nullptr, releaseId.Data.AsBytes, &releaseId.Size) == ERROR_SUCCESS) { |
| 1631 | + *platformVersion += " "; |
| 1632 | + *platformVersion += releaseId.Data.AsChars; |
| 1633 | + } |
| 1634 | + } |
| 1635 | + } else { |
| 1636 | + *platformVersion = "Unknown (Can't query HKEY_LOCAL_MACHINE\\" + (l_RegCurrentVersion + ("\\ProductName: " + Utility::FormatErrorNumber(err))) + ")"; |
| 1637 | + } |
| 1638 | + } else { |
| 1639 | + *platformVersion = "Unknown (Can't open HKEY_LOCAL_MACHINE\\" + (l_RegCurrentVersion + (": " + Utility::FormatErrorNumber(err))) + ")"; |
| 1640 | + } |
1609 | 1641 | } |
1610 | 1642 |
|
1611 | 1643 | return true; |
@@ -1703,14 +1735,28 @@ String Utility::GetPlatformKernel() |
1703 | 1735 | String Utility::GetPlatformKernelVersion() |
1704 | 1736 | { |
1705 | 1737 | #ifdef _WIN32 |
1706 | | - OSVERSIONINFO info; |
1707 | | - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); |
1708 | | - GetVersionEx(&info); |
| 1738 | + HKEY hKey; |
| 1739 | + auto err (RegOpenKeyExA(HKEY_LOCAL_MACHINE, l_RegCurrentVersion, 0, KEY_READ, &hKey)); |
1709 | 1740 |
|
1710 | | - std::ostringstream msgbuf; |
1711 | | - msgbuf << info.dwMajorVersion << "." << info.dwMinorVersion; |
| 1741 | + if (err == ERROR_SUCCESS) { |
| 1742 | + Defer regCloseKey ([hKey]() { (void)RegCloseKey(hKey); }); |
| 1743 | + RegistryString currentVersion; |
| 1744 | + auto err (RegQueryValueExA(hKey, "CurrentVersion", nullptr, nullptr, currentVersion.Data.AsBytes, ¤tVersion.Size)); |
1712 | 1745 |
|
1713 | | - return msgbuf.str(); |
| 1746 | + if (err == ERROR_SUCCESS) { |
| 1747 | + RegistryString currentBuildNumber; |
| 1748 | + |
| 1749 | + if (RegQueryValueExA(hKey, "CurrentBuildNumber", nullptr, nullptr, currentBuildNumber.Data.AsBytes, ¤tBuildNumber.Size) == ERROR_SUCCESS) { |
| 1750 | + return String(currentVersion.Data.AsChars) + "." + currentBuildNumber.Data.AsChars; |
| 1751 | + } else { |
| 1752 | + return currentVersion.Data.AsChars; |
| 1753 | + } |
| 1754 | + } else { |
| 1755 | + return "Unknown (Can't query HKEY_LOCAL_MACHINE\\" + (l_RegCurrentVersion + ("\\CurrentVersion: " + Utility::FormatErrorNumber(err))) + ")"; |
| 1756 | + } |
| 1757 | + } else { |
| 1758 | + return "Unknown (Can't open HKEY_LOCAL_MACHINE\\" + (l_RegCurrentVersion + (": " + Utility::FormatErrorNumber(err))) + ")"; |
| 1759 | + } |
1714 | 1760 | #else /* _WIN32 */ |
1715 | 1761 | return UnameHelper('r'); |
1716 | 1762 | #endif /* _WIN32 */ |
|
0 commit comments