/*** Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: SWInfo.cpp Date: 2022-1-25 Author: Reece ***/ #include #include "SWInfo.hpp" #if defined(AURORA_PLATFORM_WIN32) #include #include 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(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(&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(&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; } }