#pragma once #include #define VERSIONHELPERAPI inline bool #define _WIN32_WINNT_NT4 0x0400 #define _WIN32_WINNT_WIN2K 0x0500 #define _WIN32_WINNT_WINXP 0x0501 #define _WIN32_WINNT_WS03 0x0502 #define _WIN32_WINNT_WIN6 0x0600 #define _WIN32_WINNT_VISTA 0x0600 #define _WIN32_WINNT_WS08 0x0600 #define _WIN32_WINNT_LONGHORN 0x0600 #define _WIN32_WINNT_WIN7 0x0601 #define _WIN32_WINNT_WIN8 0x0602 #define _WIN32_WINNT_WINBLUE 0x0603 #define _WIN32_WINNT_WIN10 0x0A00 using fnRtlGetVersion = NTSTATUS( NTAPI* )(PRTL_OSVERSIONINFOEXW lpVersionInformation); enum eBuildThreshold { Build_RS0 = 10586, Build_RS1 = 14393, Build_RS2 = 15063, Build_RS3 = 16299, Build_RS4 = 17134, Build_RS5 = 17763, Build_RS_MAX = 99999, }; enum eVerShort { WinUnsupported, // Unsupported OS WinXP, // Windows XP Win7, // Windows 7 Win8, // Windows 8 Win8Point1, // Windows 8.1 Win10, // Windows 10 Win10_RS1, // Windows 10 Anniversary update Win10_RS2, // Windows 10 Creators update Win10_RS3, // Windows 10 Fall Creators update Win10_RS4, // Windows 10 Spring Creators update Win10_RS5, // Windows 10 October 2018 update }; struct WinVersion { eVerShort ver = WinUnsupported; uint32_t revision = 0; RTL_OSVERSIONINFOEXW native = { }; }; BLACKBONE_API inline WinVersion& WinVer() { static WinVersion g_WinVer; return g_WinVer; } BLACKBONE_API inline uint32_t GetRevision() { HKEY hKey = NULL; if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_QUERY_VALUE, &hKey ) == 0) { wchar_t data[MAX_PATH] = {}; DWORD dataSize = sizeof( data ); DWORD type = REG_SZ; if (RegQueryValueExW( hKey, L"BuildLabEx", nullptr, &type, reinterpret_cast(data), &dataSize ) == 0) { std::wstring buildStr = data; size_t first = buildStr.find( L'.' ); size_t second = buildStr.find( L'.', first + 1 ); if (second > first && first != buildStr.npos) { RegCloseKey( hKey ); return std::wcstol( buildStr.substr( first + 1, second - first - 1 ).c_str(), nullptr, 10 ); } } RegCloseKey( hKey ); } return 0; } BLACKBONE_API inline void InitVersion() { auto& g_WinVer = WinVer(); g_WinVer.native.dwOSVersionInfoSize = sizeof( g_WinVer.native ); auto RtlGetVersion = (fnRtlGetVersion)GetProcAddress( GetModuleHandleW( L"ntdll.dll" ), "RtlGetVersion" ); if (RtlGetVersion) { RtlGetVersion( &g_WinVer.native ); } if (g_WinVer.native.dwMajorVersion != 0) { auto fullver = (g_WinVer.native.dwMajorVersion << 8) | g_WinVer.native.dwMinorVersion; switch (fullver) { case _WIN32_WINNT_WIN10: if (g_WinVer.native.dwBuildNumber >= Build_RS5) g_WinVer.ver = Win10_RS5; else if (g_WinVer.native.dwBuildNumber >= Build_RS4) g_WinVer.ver = Win10_RS4; else if (g_WinVer.native.dwBuildNumber >= Build_RS3) g_WinVer.ver = Win10_RS3; else if (g_WinVer.native.dwBuildNumber >= Build_RS2) g_WinVer.ver = Win10_RS2; else if (g_WinVer.native.dwBuildNumber >= Build_RS1) g_WinVer.ver = Win10_RS1; else if (g_WinVer.native.dwBuildNumber >= Build_RS0) g_WinVer.ver = Win10; break; case _WIN32_WINNT_WINBLUE: g_WinVer.ver = Win8Point1; break; case _WIN32_WINNT_WIN8: g_WinVer.ver = Win8; break; case _WIN32_WINNT_WIN7: g_WinVer.ver = Win7; break; case _WIN32_WINNT_WINXP: g_WinVer.ver = WinXP; break; default: g_WinVer.ver = WinUnsupported; } } g_WinVer.revision = GetRevision(); } VERSIONHELPERAPI IsWindowsVersionOrGreater( WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor, DWORD dwBuild ) { auto& g_WinVer = WinVer(); if (g_WinVer.native.dwMajorVersion != 0) { if (g_WinVer.native.dwMajorVersion > wMajorVersion) return true; else if (g_WinVer.native.dwMajorVersion < wMajorVersion) return false; if (g_WinVer.native.dwMinorVersion > wMinorVersion) return true; else if (g_WinVer.native.dwMinorVersion < wMinorVersion) return false; if (g_WinVer.native.wServicePackMajor > wServicePackMajor) return true; else if (g_WinVer.native.wServicePackMajor < wServicePackMajor) return false; if (g_WinVer.native.dwBuildNumber >= dwBuild) return true; } return false; } BLACKBONE_API VERSIONHELPERAPI IsWindowsXPOrGreater() { return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WINXP ), LOBYTE( _WIN32_WINNT_WINXP ), 0, 0 ); } VERSIONHELPERAPI IsWindowsXPSP1OrGreater() { return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WINXP ), LOBYTE( _WIN32_WINNT_WINXP ), 1, 0 ); } VERSIONHELPERAPI IsWindowsXPSP2OrGreater() { return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WINXP ), LOBYTE( _WIN32_WINNT_WINXP ), 2, 0 ); } VERSIONHELPERAPI IsWindowsXPSP3OrGreater() { return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WINXP ), LOBYTE( _WIN32_WINNT_WINXP ), 3, 0 ); } VERSIONHELPERAPI IsWindowsVistaOrGreater() { return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_VISTA ), LOBYTE( _WIN32_WINNT_VISTA ), 0, 0 ); } VERSIONHELPERAPI IsWindowsVistaSP1OrGreater() { return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_VISTA ), LOBYTE( _WIN32_WINNT_VISTA ), 1, 0 ); } VERSIONHELPERAPI IsWindowsVistaSP2OrGreater() { return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_VISTA ), LOBYTE( _WIN32_WINNT_VISTA ), 2, 0 ); } VERSIONHELPERAPI IsWindows7OrGreater() { return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WIN7 ), LOBYTE( _WIN32_WINNT_WIN7 ), 0, 0 ); } VERSIONHELPERAPI IsWindows7SP1OrGreater() { return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WIN7 ), LOBYTE( _WIN32_WINNT_WIN7 ), 1, 0 ); } VERSIONHELPERAPI IsWindows8OrGreater() { return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WIN8 ), LOBYTE( _WIN32_WINNT_WIN8 ), 0, 0 ); } VERSIONHELPERAPI IsWindows8Point1OrGreater() { return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WINBLUE ), LOBYTE( _WIN32_WINNT_WINBLUE ), 0, 0 ); } VERSIONHELPERAPI IsWindows10OrGreater() { return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WIN10 ), LOBYTE( _WIN32_WINNT_WIN10 ), 0, 0 ); } VERSIONHELPERAPI IsWindows10RS1OrGreater() { return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WIN10 ), LOBYTE( _WIN32_WINNT_WIN10 ), 0, Build_RS1 ); } VERSIONHELPERAPI IsWindows10RS2OrGreater() { return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WIN10 ), LOBYTE( _WIN32_WINNT_WIN10 ), 0, Build_RS2 ); } VERSIONHELPERAPI IsWindows10RS3OrGreater() { return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WIN10 ), LOBYTE( _WIN32_WINNT_WIN10 ), 0, Build_RS3 ); } VERSIONHELPERAPI IsWindows10RS4OrGreater() { return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WIN10 ), LOBYTE( _WIN32_WINNT_WIN10 ), 0, Build_RS4 ); } VERSIONHELPERAPI IsWindows10RS5OrGreater() { return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WIN10 ), LOBYTE( _WIN32_WINNT_WIN10 ), 0, Build_RS5 ); } VERSIONHELPERAPI IsWindowsServer() { OSVERSIONINFOEXW osvi = { sizeof( osvi ), 0, 0, 0, 0, { 0 }, 0, 0, 0, VER_NT_WORKSTATION }; DWORDLONG const dwlConditionMask = VerSetConditionMask( 0, VER_PRODUCT_TYPE, VER_EQUAL ); return !VerifyVersionInfoW( &osvi, VER_PRODUCT_TYPE, dwlConditionMask ); }