AuroraRuntime/Source/SWInfo/SWInfo.cpp
Reece 7eb6900e9f [+] Added shared pointer extension, begin experimenting defining throw-on-null mechanic
[+] AuRemoveConst
[*] Support circular reference in Aurora pipelines Include, added support for early Aurora::Build AuroraEnum
[+] Added SWInfo API
[+] AU_COPY_MOVE, AU_MOVE, AU_COPY to go with AU_NO_... variants
[+] Adding GetProcessId
2022-01-26 00:22:02 +00:00

163 lines
4.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>
NTSYSAPI NTSTATUS RtlGetVersion(
PRTL_OSVERSIONINFOW lpVersionInformation
);
#endif
namespace Aurora::SWInfo
{
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;
}
}