241 lines
7.2 KiB
C++
241 lines
7.2 KiB
C++
/***
|
|
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
File: SWInfo.cpp
|
|
Date: 2022-1-25
|
|
Author: Reece
|
|
***/
|
|
#include <Source/RuntimeInternal.hpp>
|
|
#include "SWInfo.hpp"
|
|
|
|
#if defined(AURORA_PLATFORM_WIN32)
|
|
#include <VersionHelpers.h>
|
|
#include <winternl.h>
|
|
#endif
|
|
|
|
namespace Aurora::SWInfo
|
|
{
|
|
static AuUInt8 kWinVerNT4 = 0x0400;
|
|
static AuUInt8 kWinVerWIN2K = 0x0500;
|
|
static AuUInt8 kWinVerWINXP = 0x0501;
|
|
static AuUInt8 kWinVerWS03 = 0x0502;
|
|
static AuUInt8 kWinVerWIN6 = 0x0600;
|
|
static AuUInt8 kWinVerVISTA = 0x0600;
|
|
static AuUInt8 kWinVerWS08 = 0x0600;
|
|
static AuUInt8 kWinVerLONGHORN = 0x0600;
|
|
static AuUInt8 kWinVerWIN7 = 0x0601;
|
|
static AuUInt8 kWinVerWIN8 = 0x0602;
|
|
static AuUInt8 kWinVerWINBLUE = 0x0603;
|
|
static AuUInt8 kWinVerWIN10 = 0x0A00;
|
|
|
|
static AuUInt8 kWinVerWIN10 = 0x0A00;
|
|
static const AuString kDefaultStr;
|
|
static const OSInformation kDefaultInfo;
|
|
static OSInformation const *gInfo = &kDefaultInfo;
|
|
|
|
static AuString gKernelString;
|
|
static AuString gUserlandBrand;
|
|
static AuString gUserlandDesktopEnv;
|
|
static AuString gBuildString;
|
|
static OSInformation gTempInfo;
|
|
|
|
static void Reset()
|
|
{
|
|
gInfo = &kDefaultInfo;
|
|
}
|
|
|
|
AUKN_SYM const OSInformation &GetPlatformInfo()
|
|
{
|
|
return *gInfo;
|
|
}
|
|
|
|
#if defined(AURORA_PLATFORM_WIN32)
|
|
|
|
static bool IsWindowsEnterpriseBranch()
|
|
{
|
|
OSVERSIONINFOEXW osvi = {sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0, VER_SUITE_ENTERPRISE, 0};
|
|
DWORDLONG const dwlConditionMask = VerSetConditionMask(0, VER_SUITENAME, VER_EQUAL);
|
|
|
|
return !VerifyVersionInfoW(&osvi, VER_SUITENAME, dwlConditionMask);
|
|
}
|
|
|
|
auline bool Win32ReadRegistry(HKEY hKey, const wchar_t *key, AuString &strValue)
|
|
{
|
|
DWORD dwBufferSize {};
|
|
|
|
if (RegQueryValueExW(hKey, key, 0, NULL, NULL, &dwBufferSize) != ERROR_SUCCESS)
|
|
{
|
|
SysPushErrorUnavailableError("Couldn't access registery key");
|
|
return false;
|
|
}
|
|
|
|
std::wstring in;
|
|
|
|
if (!AuTryResize(in, dwBufferSize))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (RegQueryValueExW(hKey, key, 0, NULL, reinterpret_cast<LPBYTE>(in.data()), &dwBufferSize) != ERROR_SUCCESS)
|
|
{
|
|
SysPushErrorUnavailableError("Couldn't access registery key");
|
|
return false;
|
|
}
|
|
|
|
strValue = Locale::ConvertFromWChar(in.data(), in.size());
|
|
return strValue.size() == in.size();
|
|
}
|
|
|
|
#endif
|
|
|
|
void InitSwInfo()
|
|
{
|
|
Reset();
|
|
|
|
gTempInfo = AuMove(OSInformation(&gKernelString, &gUserlandBrand, &gUserlandDesktopEnv, &gBuildString, Aurora::Build::EPlatform::eEnumInvalid));
|
|
|
|
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
|
OSVERSIONINFOEX info {};
|
|
info.dwOSVersionInfoSize = sizeof(info);
|
|
|
|
|
|
#if defined(AURORA_PLATFORM_WIN32)
|
|
gTempInfo.bIsServer = IsWindowsServer();
|
|
gTempInfo.bIsEnterprise = IsWindowsEnterpriseBranch();
|
|
#else
|
|
gTempInfo.bIsServer = false;
|
|
gTempInfo.bIsEnterprise = false;
|
|
#endif
|
|
|
|
gUserlandDesktopEnv = "Desktop Window Manager";
|
|
|
|
if (GetVersionExA(reinterpret_cast<LPOSVERSIONINFOA>(&info)))
|
|
{
|
|
gTempInfo.uKernelPatch = info.dwBuildNumber;
|
|
gTempInfo.uKernelMinor = info.dwMinorVersion;
|
|
gTempInfo.uKernelMajor = info.dwMajorVersion;
|
|
|
|
gTempInfo.uUserlandMajor = gTempInfo.uKernelMajor;
|
|
gTempInfo.uUserlandMinor = info.wServicePackMajor;
|
|
gTempInfo.uUserlandPatch = info.wServicePackMinor;
|
|
}
|
|
|
|
#if defined(AURORA_PLATFORM_WIN32)
|
|
{
|
|
RTL_OSVERSIONINFOEXW ovi {};
|
|
ovi.dwOSVersionInfoSize = sizeof(ovi);
|
|
|
|
NTSTATUS(CALLBACK *pRtlGetVersion) (PRTL_OSVERSIONINFOW lpVersionInformation);
|
|
pRtlGetVersion = (decltype(pRtlGetVersion))GetProcAddress(LoadLibrary(TEXT("Ntdll.dll")), "RtlGetVersion");
|
|
|
|
if (pRtlGetVersion && pRtlGetVersion(reinterpret_cast<PRTL_OSVERSIONINFOW>(&ovi)) == 0)
|
|
{
|
|
gTempInfo.uKernelPatch = ovi.dwBuildNumber;
|
|
gTempInfo.uKernelMinor = ovi.dwMinorVersion;
|
|
gTempInfo.uKernelMajor = ovi.dwMajorVersion;
|
|
|
|
gTempInfo.uUserlandMajor = gTempInfo.uKernelMajor;
|
|
gTempInfo.uUserlandMinor = ovi.wServicePackMajor;
|
|
gTempInfo.uUserlandPatch = ovi.wServicePackMinor;
|
|
}
|
|
}
|
|
|
|
HKEY hKey;
|
|
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
|
|
{
|
|
if (!Win32ReadRegistry(hKey, L"BuildLabEx", gBuildString))
|
|
{
|
|
Win32ReadRegistry(hKey, L"BuildLab", gBuildString);
|
|
}
|
|
Win32ReadRegistry(hKey, L"ProductName", gUserlandBrand);
|
|
RegCloseKey(hKey);
|
|
}
|
|
#endif
|
|
|
|
if (gKernelString.empty())
|
|
{
|
|
gKernelString = fmt::format("Microsoft NT {}.{}.{}", gTempInfo.uKernelMajor, gTempInfo.uKernelMinor, gTempInfo.uKernelPatch);
|
|
}
|
|
|
|
if (gUserlandBrand.empty())
|
|
{
|
|
gUserlandBrand = fmt::format("NT Userland {}.{}.{}", gTempInfo.uUserlandMajor, gTempInfo.uUserlandMinor, gTempInfo.uUserlandPatch);
|
|
}
|
|
|
|
#endif
|
|
|
|
gTempInfo.ePlatform = Build::kCurrentPlatform;
|
|
|
|
gInfo = &gTempInfo;
|
|
}
|
|
|
|
static bool IsWindowsVersionOrGreater(AuUInt8 major, AuUInt8 ignored, AuUInt8 sp)
|
|
{
|
|
return gInfo->ePlatform == Build::EPlatform::ePlatformWin32 && gInfo->uKernelMajor >= major && gInfo->uUserlandMinor >= sp;
|
|
}
|
|
|
|
AUKN_SYM bool IsWindowsXPOrGreater()
|
|
{
|
|
return IsWindowsVersionOrGreater(kWinVerWINXP, kWinVerWINXP, 0);
|
|
}
|
|
|
|
AUKN_SYM bool IsWindowsXPSP1OrGreater()
|
|
{
|
|
return IsWindowsVersionOrGreater(kWinVerWINXP, kWinVerWINXP, 1);
|
|
}
|
|
|
|
AUKN_SYM bool IsWindowsXPSP2OrGreater()
|
|
{
|
|
return IsWindowsVersionOrGreater(kWinVerWINXP, kWinVerWINXP, 2);
|
|
}
|
|
|
|
AUKN_SYM bool IsWindowsXPSP3OrGreater()
|
|
{
|
|
return IsWindowsVersionOrGreater(kWinVerWINXP, kWinVerWINXP, 3);
|
|
}
|
|
|
|
AUKN_SYM bool IsWindowsVistaOrGreater()
|
|
{
|
|
return IsWindowsVersionOrGreater(kWinVerVISTA, kWinVerVISTA, 0);
|
|
}
|
|
|
|
AUKN_SYM bool IsWindowsVistaSP1OrGreater()
|
|
{
|
|
return IsWindowsVersionOrGreater(kWinVerVISTA, kWinVerVISTA, 1);
|
|
}
|
|
|
|
AUKN_SYM bool IsWindowsVistaSP2OrGreater()
|
|
{
|
|
return IsWindowsVersionOrGreater(kWinVerVISTA, kWinVerVISTA, 2);
|
|
}
|
|
|
|
AUKN_SYM bool IsWindows7OrGreater()
|
|
{
|
|
return IsWindowsVersionOrGreater(kWinVerWIN7, kWinVerWIN7, 0);
|
|
}
|
|
|
|
AUKN_SYM bool IsWindows7SP1OrGreater()
|
|
{
|
|
return IsWindowsVersionOrGreater(kWinVerWIN7, kWinVerWIN7, 1);
|
|
}
|
|
|
|
AUKN_SYM bool IsWindows8OrGreater()
|
|
{
|
|
return IsWindowsVersionOrGreater(kWinVerWIN8, kWinVerWIN8, 0);
|
|
}
|
|
|
|
AUKN_SYM bool IsWindows8Point1OrGreater()
|
|
{
|
|
return IsWindowsVersionOrGreater(kWinVerWINBLUE, kWinVerWINBLUE, 0);
|
|
}
|
|
|
|
AUKN_SYM bool IsWindows10OrGreater()
|
|
{
|
|
return IsWindowsVersionOrGreater(kWinVerWIN10, kWinVerWIN10, 0);
|
|
}
|
|
|
|
AUKN_SYM bool IsWindows11OrGreater()
|
|
{
|
|
return IsWindowsVersionOrGreater(kWinVerWIN10, kWinVerWIN10, 0) && gInfo->uKernelPatch >= 22000;
|
|
}
|
|
} |