AuroraRuntime/Source/SWInfo/AuSWInfo.NT.cpp

175 lines
5.2 KiB
C++

/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: AuSWInfo.NT.cpp
Date: 2022-2-1
Author: Reece
***/
#include <Source/RuntimeInternal.hpp>
#include "AuSWInfo.hpp"
#include "AuSWInfo.NT.hpp"
#if defined(AURORA_PLATFORM_WIN32)
#include <VersionHelpers.h>
#include <winternl.h>
#endif
namespace Aurora::SWInfo
{
static AuString gKernelString;
static AuString gUserlandBrand;
static AuString gUserlandDesktopEnv;
static AuString gBuildString;
#if defined(AURORA_PLATFORM_WIN32)
static bool IsWindowsEnterpriseBranch()
{
if (!pVerifyVersionInfoW)
{
return false;
}
if (!pVerSetConditionMask)
{
return false;
}
OSVERSIONINFOEXW osvi = {sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0, VER_SUITE_ENTERPRISE, 0, 0};
DWORDLONG const dwlConditionMask = pVerSetConditionMask(0, VER_SUITENAME, VER_EQUAL);
return !pVerifyVersionInfoW(&osvi, VER_SUITENAME, dwlConditionMask);
}
auline bool Win32ReadRegistry(HKEY hKey, const wchar_t *pWideKey, AuString &strValue)
{
DWORD dwBufferSize {};
if (!pRegQueryValueExW ||
pRegQueryValueExW(hKey, pWideKey, 0, NULL, NULL, &dwBufferSize) != ERROR_SUCCESS)
{
SysPushErrorUnavailableError("Couldn't access registery key");
return false;
}
std::wstring in;
if (!AuTryResize(in, dwBufferSize / sizeof(wchar_t)))
{
SysPushErrorMem();
return false;
}
if (!pRegQueryValueExW ||
pRegQueryValueExW(hKey, pWideKey, 0, NULL, reinterpret_cast<LPBYTE>(in.data()), &dwBufferSize) != ERROR_SUCCESS)
{
SysPushErrorUnavailableError("Couldn't access registery key");
return false;
}
auto c = dwBufferSize / sizeof(wchar_t);
if (c) c--;
strValue = Locale::ConvertFromWChar(in.data(), c);
return strValue.size();
}
static void Win32SetIsServer(OSInformation &osInfo)
{
if (!pVerSetConditionMask ||
!pVerifyVersionInfoW)
{
return;
}
OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0, 0, VER_NT_WORKSTATION };
const DWORDLONG dwlConditionMask = pVerSetConditionMask(0, VER_PRODUCT_TYPE, VER_EQUAL);
osInfo.bIsServer = !pVerifyVersionInfoW(&osvi, VER_PRODUCT_TYPE, dwlConditionMask);
}
#endif
void InitNTInfoNoAllocate(OSInformation &osInfo)
{
OSVERSIONINFOEX info {};
info.dwOSVersionInfoSize = sizeof(info);
#if defined(AURORA_PLATFORM_WIN32)
Win32SetIsServer(osInfo);
osInfo.bIsEnterprise = osInfo.bIsServer;//IsWindowsEnterpriseBranch();
#else
osInfo.bIsServer = false;
osInfo.bIsEnterprise = false;
#endif
if (GetVersionExA(reinterpret_cast<LPOSVERSIONINFOA>(&info)))
{
osInfo.uKernelPatch = info.dwBuildNumber;
osInfo.uKernelMinor = info.dwMinorVersion;
osInfo.uKernelMajor = info.dwMajorVersion;
osInfo.uUserlandMajor = osInfo.uKernelMajor;
osInfo.uUserlandMinor = info.wServicePackMajor;
osInfo.uUserlandPatch = info.wServicePackMinor;
}
#if defined(AURORA_PLATFORM_WIN32)
RTL_OSVERSIONINFOEXW ovi {};
ovi.dwOSVersionInfoSize = sizeof(ovi);
if (pRtlGetVersion &&
pRtlGetVersion(reinterpret_cast<PRTL_OSVERSIONINFOW>(&ovi)) == 0)
{
osInfo.uKernelPatch = ovi.dwBuildNumber;
osInfo.uKernelMinor = ovi.dwMinorVersion;
osInfo.uKernelMajor = ovi.dwMajorVersion;
osInfo.uUserlandMajor = osInfo.uKernelMajor;
osInfo.uUserlandMinor = ovi.wServicePackMajor;
osInfo.uUserlandPatch = ovi.wServicePackMinor;
}
#endif
}
void InitNTInfo(OSInformation &osInfo)
{
osInfo = AuMove(OSInformation(&gKernelString, &gUserlandBrand, &gUserlandDesktopEnv, &gBuildString, Aurora::Build::EPlatform::eEnumInvalid));
InitNTInfoNoAllocate(osInfo);
gUserlandDesktopEnv = "Desktop Window Manager";
#if defined(AURORA_PLATFORM_WIN32)
HKEY hKey;
if (pRegOpenKeyExW &&
pRegOpenKeyExW(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);
if (pRegCloseKey)
{
pRegCloseKey(hKey);
}
}
#endif
osInfo.bIsEnterprise |= AuStringContains(gUserlandBrand, "nterprise");
if (gKernelString.empty())
{
gKernelString = fmt::format("Microsoft NT {}.{}.{}", osInfo.uKernelMajor, osInfo.uKernelMinor, osInfo.uKernelPatch);
}
if (gUserlandBrand.empty())
{
gUserlandBrand = fmt::format("NT Userland {}.{}.{}", osInfo.uUserlandMajor, osInfo.uUserlandMinor, osInfo.uUserlandPatch);
}
}
}