diff --git a/include/MUtils/OSSupport.h b/include/MUtils/OSSupport.h index 8fe4d96..4c80094 100644 --- a/include/MUtils/OSSupport.h +++ b/include/MUtils/OSSupport.h @@ -77,8 +77,6 @@ namespace MUtils unsigned int versionSPack; ///< The *service pack* version of the underlaying operating system bool overrideFlag; - MUTILS_API bool operator== (const _os_version_t &rhs) const; - MUTILS_API bool operator!= (const _os_version_t &rhs) const; MUTILS_API bool operator> (const _os_version_t &rhs) const; MUTILS_API bool operator>= (const _os_version_t &rhs) const; MUTILS_API bool operator< (const _os_version_t &rhs) const; @@ -94,7 +92,8 @@ namespace MUtils MUTILS_API extern const os_version_t WINDOWS_WIN70; ///< \brief Operating system version constant \details Microsoft(R) Windows 7 MUTILS_API extern const os_version_t WINDOWS_WIN80; ///< \brief Operating system version constant \details Microsoft(R) Windows 8 MUTILS_API extern const os_version_t WINDOWS_WIN81; ///< \brief Operating system version constant \details Microsoft(R) Windows 8.1 - MUTILS_API extern const os_version_t WINDOWS_WN100; ///< \brief Operating system version constant \details Microsoft(R) Windows 10 + MUTILS_API extern const os_version_t WINDOWS_WIN10; ///< \brief Operating system version constant \details Microsoft(R) Windows 10 + MUTILS_API extern const os_version_t WINDOWS_WIN11; ///< \brief Operating system version constant \details Microsoft(R) Windows 11 //Unknown OS MUTILS_API extern const os_version_t UNKNOWN_OPSYS; ///< \brief Operating system version constant \details Unknown operating system version diff --git a/src/GUI_Win32.cpp b/src/GUI_Win32.cpp index 6d600a7..3338e9a 100644 --- a/src/GUI_Win32.cpp +++ b/src/GUI_Win32.cpp @@ -211,14 +211,17 @@ bool MUtils::GUI::sheet_of_glass(QWidget *const window) } //Create and populate the Blur Behind structure - DWM_BLURBEHIND bb; - memset(&bb, 0, sizeof(DWM_BLURBEHIND)); - bb.fEnable = TRUE; - bb.dwFlags = DWM_BB_ENABLE; - if(HRESULT hr = dwmEnableBlurBehindWindowFun(reinterpret_cast(window->winId()), &bb)) + if (MUtils::OS::os_version() < MUtils::OS::Version::WINDOWS_WIN11) { - qWarning("DwmEnableBlurBehindWindow function has failed! (error %d)", hr); - return false; + DWM_BLURBEHIND bb; + memset(&bb, 0, sizeof(DWM_BLURBEHIND)); + bb.fEnable = TRUE; + bb.dwFlags = DWM_BB_ENABLE; + if (HRESULT hr = dwmEnableBlurBehindWindowFun(reinterpret_cast(window->winId()), &bb)) + { + qWarning("DwmEnableBlurBehindWindow function has failed! (error %d)", hr); + return false; + } } //Required for Qt diff --git a/src/OSSupport_Win32.cpp b/src/OSSupport_Win32.cpp index 8351641..78bdcb3 100644 --- a/src/OSSupport_Win32.cpp +++ b/src/OSSupport_Win32.cpp @@ -288,7 +288,8 @@ g_os_version_lut[] = { MUtils::OS::Version::WINDOWS_WIN70, "Windows 7 or Windows Server 2008 R2" }, //7 { MUtils::OS::Version::WINDOWS_WIN80, "Windows 8 or Windows Server 2012" }, //8 { MUtils::OS::Version::WINDOWS_WIN81, "Windows 8.1 or Windows Server 2012 R2" }, //8.1 - { MUtils::OS::Version::WINDOWS_WN100, "Windows 10 or Windows Server 2016" }, //10 + { MUtils::OS::Version::WINDOWS_WIN10, "Windows 10 or Windows Server 2016/2019" }, //10 + { MUtils::OS::Version::WINDOWS_WIN11, "Windows 11 or Windows Server 2022" }, //11 { MUtils::OS::Version::UNKNOWN_OPSYS, "N/A" } }; @@ -300,12 +301,10 @@ namespace MUtils namespace Version { //Comparision operators for os_version_t - bool os_version_t::operator== (const os_version_t &rhs) const { return (type == rhs.type) && (versionMajor == rhs.versionMajor) && ((versionMinor == rhs.versionMinor)); } - bool os_version_t::operator!= (const os_version_t &rhs) const { return (type != rhs.type) || (versionMajor != rhs.versionMajor) || ((versionMinor != rhs.versionMinor)); } - bool os_version_t::operator> (const os_version_t &rhs) const { return (type == rhs.type) && ((versionMajor > rhs.versionMajor) || ((versionMajor == rhs.versionMajor) && (versionMinor > rhs.versionMinor))); } - bool os_version_t::operator>= (const os_version_t &rhs) const { return (type == rhs.type) && ((versionMajor > rhs.versionMajor) || ((versionMajor == rhs.versionMajor) && (versionMinor >= rhs.versionMinor))); } - bool os_version_t::operator< (const os_version_t &rhs) const { return (type == rhs.type) && ((versionMajor < rhs.versionMajor) || ((versionMajor == rhs.versionMajor) && (versionMinor < rhs.versionMinor))); } - bool os_version_t::operator<= (const os_version_t &rhs) const { return (type == rhs.type) && ((versionMajor < rhs.versionMajor) || ((versionMajor == rhs.versionMajor) && (versionMinor <= rhs.versionMinor))); } + bool os_version_t::operator> (const os_version_t &rhs) const { return (versionMajor > rhs.versionMajor) || ((versionMajor == rhs.versionMajor) && (versionMinor > rhs.versionMinor)) || ((versionMajor == rhs.versionMajor) && (versionMinor == rhs.versionMinor) && (versionBuild > rhs.versionBuild)); } + bool os_version_t::operator>= (const os_version_t &rhs) const { return (versionMajor > rhs.versionMajor) || ((versionMajor == rhs.versionMajor) && (versionMinor > rhs.versionMinor)) || ((versionMajor == rhs.versionMajor) && (versionMinor == rhs.versionMinor) && (versionBuild >= rhs.versionBuild)); } + bool os_version_t::operator< (const os_version_t &rhs) const { return (versionMajor < rhs.versionMajor) || ((versionMajor == rhs.versionMajor) && (versionMinor < rhs.versionMinor)) || ((versionMajor == rhs.versionMajor) && (versionMinor == rhs.versionMinor) && (versionBuild < rhs.versionBuild)); } + bool os_version_t::operator<= (const os_version_t &rhs) const { return (versionMajor < rhs.versionMajor) || ((versionMajor == rhs.versionMajor) && (versionMinor < rhs.versionMinor)) || ((versionMajor == rhs.versionMajor) && (versionMinor == rhs.versionMinor) && (versionBuild <= rhs.versionBuild)); } //Known Windows NT versions const os_version_t WINDOWS_WIN2K = { OS_WINDOWS, 5, 0, 2195, 0 }; // 2000 @@ -315,7 +314,8 @@ namespace MUtils const os_version_t WINDOWS_WIN70 = { OS_WINDOWS, 6, 1, 7600, 0 }; // 7 const os_version_t WINDOWS_WIN80 = { OS_WINDOWS, 6, 2, 9200, 0 }; // 8 const os_version_t WINDOWS_WIN81 = { OS_WINDOWS, 6, 3, 9600, 0 }; // 8.1 - const os_version_t WINDOWS_WN100 = { OS_WINDOWS, 10, 0, 10240, 0 }; // 10 + const os_version_t WINDOWS_WIN10 = { OS_WINDOWS, 10, 0, 10240, 0 }; // 10 + const os_version_t WINDOWS_WIN11 = { OS_WINDOWS, 10, 0, 20348, 0 }; // 11 //Unknown OS const os_version_t UNKNOWN_OPSYS = { OS_UNKNOWN, 0, 0, 0, 0 }; // N/A @@ -369,113 +369,6 @@ static bool rtl_get_version(OSVERSIONINFOEXW *const osInfo) #pragma warning(pop) -static bool rtl_verify_version(OSVERSIONINFOEXW *const osInfo, const ULONG typeMask, const ULONGLONG condMask) -{ - typedef LONG(__stdcall *RtlVerifyVersionInfo)(LPOSVERSIONINFOEXW, ULONG, ULONGLONG); - if (const HMODULE ntdll = GetModuleHandleW(L"ntdll")) - { - if (const RtlVerifyVersionInfo pRtlVerifyVersionInfo = (RtlVerifyVersionInfo)GetProcAddress(ntdll, "RtlVerifyVersionInfo")) - { - if (pRtlVerifyVersionInfo(osInfo, typeMask, condMask) == 0) - { - return true; - } - } - } - - //Fallback - return (VerifyVersionInfoW(osInfo, typeMask, condMask) != FALSE); -} - -static bool verify_os_version(const DWORD major, const DWORD minor) -{ - OSVERSIONINFOEXW osvi; - DWORDLONG dwlConditionMask = 0; - initialize_os_version(&osvi); - - //Initialize the OSVERSIONINFOEX structure - osvi.dwMajorVersion = major; - osvi.dwMinorVersion = minor; - osvi.dwPlatformId = VER_PLATFORM_WIN32_NT; - - //Initialize the condition mask - VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL); - VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_GREATER_EQUAL); - VER_SET_CONDITION(dwlConditionMask, VER_PLATFORMID, VER_EQUAL); - - // Perform the test - const BOOL ret = rtl_verify_version(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_PLATFORMID, dwlConditionMask); - - //Error checking - if(!ret) - { - if(GetLastError() != ERROR_OLD_WIN_VERSION) - { - qWarning("VerifyVersionInfo() system call has failed!"); - } - } - - return (ret != FALSE); -} - -static bool verify_os_build(const DWORD build) -{ - OSVERSIONINFOEXW osvi; - DWORDLONG dwlConditionMask = 0; - initialize_os_version(&osvi); - - //Initialize the OSVERSIONINFOEX structure - osvi.dwBuildNumber = build; - osvi.dwPlatformId = VER_PLATFORM_WIN32_NT; - - //Initialize the condition mask - VER_SET_CONDITION(dwlConditionMask, VER_BUILDNUMBER, VER_GREATER_EQUAL); - VER_SET_CONDITION(dwlConditionMask, VER_PLATFORMID, VER_EQUAL); - - // Perform the test - const BOOL ret = rtl_verify_version(&osvi, VER_BUILDNUMBER | VER_PLATFORMID, dwlConditionMask); - - //Error checking - if (!ret) - { - if (GetLastError() != ERROR_OLD_WIN_VERSION) - { - qWarning("VerifyVersionInfo() system call has failed!"); - } - } - - return (ret != FALSE); -} - -static bool verify_os_spack(const WORD spack) -{ - OSVERSIONINFOEXW osvi; - DWORDLONG dwlConditionMask = 0; - initialize_os_version(&osvi); - - //Initialize the OSVERSIONINFOEX structure - osvi.wServicePackMajor = spack; - osvi.dwPlatformId = VER_PLATFORM_WIN32_NT; - - //Initialize the condition mask - VER_SET_CONDITION(dwlConditionMask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); - VER_SET_CONDITION(dwlConditionMask, VER_PLATFORMID, VER_EQUAL); - - // Perform the test - const BOOL ret = rtl_verify_version(&osvi, VER_SERVICEPACKMAJOR | VER_PLATFORMID, dwlConditionMask); - - //Error checking - if (!ret) - { - if (GetLastError() != ERROR_OLD_WIN_VERSION) - { - qWarning("VerifyVersionInfo() system call has failed!"); - } - } - - return (ret != FALSE); -} - static bool get_real_os_version(unsigned int *const major, unsigned int *const minor, unsigned int *const build, unsigned int *const spack, bool *const pbOverride) { static const DWORD MAX_VERSION = MAXWORD; @@ -491,14 +384,14 @@ static bool get_real_os_version(unsigned int *const major, unsigned int *const m osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW); //Try GetVersionEx() first - if(rtl_get_version(&osvi) == FALSE) + if (!rtl_get_version(&osvi)) { qWarning("GetVersionEx() has failed, cannot detect Windows version!"); return false; } //Make sure we are running on NT - if(osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) + if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) { *major = osvi.dwMajorVersion; *minor = osvi.dwMinorVersion; @@ -507,84 +400,8 @@ static bool get_real_os_version(unsigned int *const major, unsigned int *const m } else { - if (verify_os_version(4, 0)) - { - *major = 4; - *build = 1381; - *pbOverride = true; - } - else - { - qWarning("Not running on Windows NT, unsupported operating system!"); - return false; - } - } - - //Major Version - for (DWORD nextMajor = (*major) + 1; nextMajor <= MAX_VERSION; nextMajor++) - { - if (verify_os_version(nextMajor, 0)) - { - *major = nextMajor; - *minor = 0; - *pbOverride = true; - continue; - } - break; - } - - //Minor Version - for (DWORD nextMinor = (*minor) + 1; nextMinor <= MAX_VERSION; nextMinor++) - { - if (verify_os_version((*major), nextMinor)) - { - *minor = nextMinor; - *pbOverride = true; - continue; - } - break; - } - - //Build Version - if (verify_os_build(SAFE_ADD((*build), 1, MAX_BUILDNO))) - { - DWORD stepSize = initialize_step_size(MAX_BUILDNO); - for (DWORD nextBuildNo = SAFE_ADD((*build), stepSize, MAX_BUILDNO); (*build) < MAX_BUILDNO; nextBuildNo = SAFE_ADD((*build), stepSize, MAX_BUILDNO)) - { - if (verify_os_build(nextBuildNo)) - { - *build = nextBuildNo; - *pbOverride = true; - continue; - } - if (stepSize > 1) - { - stepSize = stepSize / 2; - continue; - } - break; - } - } - - //Service Pack - if (verify_os_spack(SAFE_ADD((*spack), 1, MAX_SRVCPCK))) - { - DWORD stepSize = initialize_step_size(MAX_SRVCPCK); - for (DWORD nextSPackNo = SAFE_ADD((*spack), stepSize, MAX_SRVCPCK); (*spack) < MAX_SRVCPCK; nextSPackNo = SAFE_ADD((*spack), stepSize, MAX_SRVCPCK)) - { - if (verify_os_spack(nextSPackNo)) - { - *build = nextSPackNo; - *pbOverride = true; - continue; - } - if (stepSize > 1) - { - stepSize = stepSize / 2; - continue; - } - break; - } + qWarning("Not running on Windows NT, unsupported operating system!"); + return false; } return true; @@ -632,15 +449,18 @@ const MUtils::OS::Version::os_version_t &MUtils::OS::os_version(void) const char *MUtils::OS::os_friendly_name(const MUtils::OS::Version::os_version_t &os_version) { - for(size_t i = 0; g_os_version_lut[i].version != MUtils::OS::Version::UNKNOWN_OPSYS; i++) + const char *friendly_name = NULL; + for(size_t i = 0; g_os_version_lut[i].version.type != MUtils::OS::Version::OS_UNKNOWN; i++) { - if(os_version == g_os_version_lut[i].version) + if(os_version >= g_os_version_lut[i].version) { - return g_os_version_lut[i].friendlyName; + friendly_name = g_os_version_lut[i].friendlyName; + continue; } + break; } - return NULL; + return friendly_name; } /////////////////////////////////////////////////////////////////////////////// diff --git a/src/Startup.cpp b/src/Startup.cpp index 5e3f5f8..35350a6 100644 --- a/src/Startup.cpp +++ b/src/Startup.cpp @@ -244,12 +244,11 @@ int MUtils::Startup::startup(int &argc, char **argv, main_function_t *const entr static QMutex g_init_lock; static const char *const g_imageformats[] = {"bmp", "png", "jpg", "gif", "ico", "xpm", "svg", NULL}; -#define REQUIRE_OS(MIN_OS, MIN_SP) \ - ((osVersion.type == MUtils::OS::Version::OS_WINDOWS) && ((osVersion > MUtils::OS::Version::MIN_OS) || \ - ((osVersion == MUtils::OS::Version::MIN_OS) && (osVersion.versionSPack >= (MIN_SP))))) +#define CHECK_OSVER(MINREQ_OS) \ + ((osVersion.type == MUtils::OS::Version::OS_WINDOWS) && (osVersion >= MUtils::OS::Version::MINREQ_OS)) -#define REQUIRE_SP(OS_VER, MIN_SP) \ - ((osVersion != MUtils::OS::Version::OS_VER) || (osVersion.versionSPack >= (MIN_SP))) +#define CHECK_SPACK(MIN_OS, MAX_OS, REQUIRED_SP) \ + ((osVersion < MUtils::OS::Version::MIN_OS) || (osVersion >= MUtils::OS::Version::MAX_OS) || (osVersion.versionSPack >= (REQUIRED_SP))) static FORCE_INLINE QString getExecutableName(int &argc, char **argv) { @@ -327,29 +326,37 @@ QApplication *MUtils::Startup::create_qt(int &argc, char **argv, const QString & //Check whether we are running on a supported Windows version if (xpSupport) { - if (!REQUIRE_OS(WINDOWS_WINXP, 3)) + if (!CHECK_OSVER(WINDOWS_WINXP)) { - qFatal("%s", MUTILS_L1STR(QApplication::tr("Executable '%1' requires Windows XP with SP-3 or later.").arg(executableName))); + qFatal("%s", MUTILS_L1STR(QApplication::tr("Executable '%1' requires Windows XP or later.").arg(executableName))); } - if (!REQUIRE_SP(WINDOWS_XPX64, 2)) + else if (!CHECK_SPACK(WINDOWS_WINXP, WINDOWS_XPX64, 3)) { - qFatal("%s", MUTILS_L1STR(QApplication::tr("Executable '%1' requires Windows XP x64-Edition with SP-2 or later.").arg(executableName))); + qFatal("%s", MUTILS_L1STR(QApplication::tr("Executable '%1' requires Service Pack 3 for Windows XP.").arg(executableName))); + } + else if (!CHECK_SPACK(WINDOWS_XPX64, WINDOWS_VISTA, 2)) + { + qFatal("%s", MUTILS_L1STR(QApplication::tr("Executable '%1' requires Service Pack 2 for Windows XP x64-Edition.").arg(executableName))); } } else { - if (!REQUIRE_OS(WINDOWS_VISTA, 2)) + if (!CHECK_OSVER(WINDOWS_VISTA)) { - qFatal("%s", MUTILS_L1STR(QApplication::tr("Executable '%1' requires Windows Vista with SP-2 or later.").arg(executableName))); + qFatal("%s", MUTILS_L1STR(QApplication::tr("Executable '%1' requires Windows Vista or later.").arg(executableName))); + } + else if (!CHECK_SPACK(WINDOWS_VISTA, WINDOWS_WIN70, 2)) + { + qFatal("%s", MUTILS_L1STR(QApplication::tr("Executable '%1' requires Service Pack 2 for Windows Vista.").arg(executableName))); } } - if (osVersion == MUtils::OS::Version::WINDOWS_WIN80) + if ((osVersion >= MUtils::OS::Version::WINDOWS_WIN80) && (osVersion < MUtils::OS::Version::WINDOWS_WIN81)) { qFatal("%s", MUTILS_L1STR(QApplication::tr("Executable '%1' requires Windows 8.1 or later.").arg(executableName))); } //Check for compat mode - if(osVersion.overrideFlag && (osVersion <= MUtils::OS::Version::WINDOWS_WN100)) + if(osVersion.overrideFlag && (osVersion <= MUtils::OS::Version::WINDOWS_WIN10)) { qWarning("Windows compatibility mode detected!"); if(!arguments.contains("ignore-compat-mode"))