• R/O
  • HTTP
  • SSH
  • HTTPS

MUtilities: 提交

MUtilities development repository


Commit MetaInfo

修订版2eb036fbadaa0dff4ec54f5bce547d25f1a2a59d (tree)
时间2021-12-24 05:04:46
作者LoRd_MuldeR <mulder2@gmx....>
CommiterLoRd_MuldeR

Log Message

Implemented detection of Windows 11 + workaround for DwmEnableBlurBehindWindow() not working on Windows 11.

更改概述

差异

--- a/include/MUtils/OSSupport.h
+++ b/include/MUtils/OSSupport.h
@@ -77,8 +77,6 @@ namespace MUtils
7777 unsigned int versionSPack; ///< The *service pack* version of the underlaying operating system
7878 bool overrideFlag;
7979
80- MUTILS_API bool operator== (const _os_version_t &rhs) const;
81- MUTILS_API bool operator!= (const _os_version_t &rhs) const;
8280 MUTILS_API bool operator> (const _os_version_t &rhs) const;
8381 MUTILS_API bool operator>= (const _os_version_t &rhs) const;
8482 MUTILS_API bool operator< (const _os_version_t &rhs) const;
@@ -94,7 +92,8 @@ namespace MUtils
9492 MUTILS_API extern const os_version_t WINDOWS_WIN70; ///< \brief Operating system version constant \details Microsoft(R) Windows 7
9593 MUTILS_API extern const os_version_t WINDOWS_WIN80; ///< \brief Operating system version constant \details Microsoft(R) Windows 8
9694 MUTILS_API extern const os_version_t WINDOWS_WIN81; ///< \brief Operating system version constant \details Microsoft(R) Windows 8.1
97- MUTILS_API extern const os_version_t WINDOWS_WN100; ///< \brief Operating system version constant \details Microsoft(R) Windows 10
95+ MUTILS_API extern const os_version_t WINDOWS_WIN10; ///< \brief Operating system version constant \details Microsoft(R) Windows 10
96+ MUTILS_API extern const os_version_t WINDOWS_WIN11; ///< \brief Operating system version constant \details Microsoft(R) Windows 11
9897
9998 //Unknown OS
10099 MUTILS_API extern const os_version_t UNKNOWN_OPSYS; ///< \brief Operating system version constant \details Unknown operating system version
--- a/src/GUI_Win32.cpp
+++ b/src/GUI_Win32.cpp
@@ -211,14 +211,17 @@ bool MUtils::GUI::sheet_of_glass(QWidget *const window)
211211 }
212212
213213 //Create and populate the Blur Behind structure
214- DWM_BLURBEHIND bb;
215- memset(&bb, 0, sizeof(DWM_BLURBEHIND));
216- bb.fEnable = TRUE;
217- bb.dwFlags = DWM_BB_ENABLE;
218- if(HRESULT hr = dwmEnableBlurBehindWindowFun(reinterpret_cast<HWND>(window->winId()), &bb))
214+ if (MUtils::OS::os_version() < MUtils::OS::Version::WINDOWS_WIN11)
219215 {
220- qWarning("DwmEnableBlurBehindWindow function has failed! (error %d)", hr);
221- return false;
216+ DWM_BLURBEHIND bb;
217+ memset(&bb, 0, sizeof(DWM_BLURBEHIND));
218+ bb.fEnable = TRUE;
219+ bb.dwFlags = DWM_BB_ENABLE;
220+ if (HRESULT hr = dwmEnableBlurBehindWindowFun(reinterpret_cast<HWND>(window->winId()), &bb))
221+ {
222+ qWarning("DwmEnableBlurBehindWindow function has failed! (error %d)", hr);
223+ return false;
224+ }
222225 }
223226
224227 //Required for Qt
--- a/src/OSSupport_Win32.cpp
+++ b/src/OSSupport_Win32.cpp
@@ -288,7 +288,8 @@ g_os_version_lut[] =
288288 { MUtils::OS::Version::WINDOWS_WIN70, "Windows 7 or Windows Server 2008 R2" }, //7
289289 { MUtils::OS::Version::WINDOWS_WIN80, "Windows 8 or Windows Server 2012" }, //8
290290 { MUtils::OS::Version::WINDOWS_WIN81, "Windows 8.1 or Windows Server 2012 R2" }, //8.1
291- { MUtils::OS::Version::WINDOWS_WN100, "Windows 10 or Windows Server 2016" }, //10
291+ { MUtils::OS::Version::WINDOWS_WIN10, "Windows 10 or Windows Server 2016/2019" }, //10
292+ { MUtils::OS::Version::WINDOWS_WIN11, "Windows 11 or Windows Server 2022" }, //11
292293 { MUtils::OS::Version::UNKNOWN_OPSYS, "N/A" }
293294 };
294295
@@ -300,12 +301,10 @@ namespace MUtils
300301 namespace Version
301302 {
302303 //Comparision operators for os_version_t
303- bool os_version_t::operator== (const os_version_t &rhs) const { return (type == rhs.type) && (versionMajor == rhs.versionMajor) && ((versionMinor == rhs.versionMinor)); }
304- bool os_version_t::operator!= (const os_version_t &rhs) const { return (type != rhs.type) || (versionMajor != rhs.versionMajor) || ((versionMinor != rhs.versionMinor)); }
305- bool os_version_t::operator> (const os_version_t &rhs) const { return (type == rhs.type) && ((versionMajor > rhs.versionMajor) || ((versionMajor == rhs.versionMajor) && (versionMinor > rhs.versionMinor))); }
306- bool os_version_t::operator>= (const os_version_t &rhs) const { return (type == rhs.type) && ((versionMajor > rhs.versionMajor) || ((versionMajor == rhs.versionMajor) && (versionMinor >= rhs.versionMinor))); }
307- bool os_version_t::operator< (const os_version_t &rhs) const { return (type == rhs.type) && ((versionMajor < rhs.versionMajor) || ((versionMajor == rhs.versionMajor) && (versionMinor < rhs.versionMinor))); }
308- bool os_version_t::operator<= (const os_version_t &rhs) const { return (type == rhs.type) && ((versionMajor < rhs.versionMajor) || ((versionMajor == rhs.versionMajor) && (versionMinor <= rhs.versionMinor))); }
304+ 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)); }
305+ 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)); }
306+ 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)); }
307+ 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)); }
309308
310309 //Known Windows NT versions
311310 const os_version_t WINDOWS_WIN2K = { OS_WINDOWS, 5, 0, 2195, 0 }; // 2000
@@ -315,7 +314,8 @@ namespace MUtils
315314 const os_version_t WINDOWS_WIN70 = { OS_WINDOWS, 6, 1, 7600, 0 }; // 7
316315 const os_version_t WINDOWS_WIN80 = { OS_WINDOWS, 6, 2, 9200, 0 }; // 8
317316 const os_version_t WINDOWS_WIN81 = { OS_WINDOWS, 6, 3, 9600, 0 }; // 8.1
318- const os_version_t WINDOWS_WN100 = { OS_WINDOWS, 10, 0, 10240, 0 }; // 10
317+ const os_version_t WINDOWS_WIN10 = { OS_WINDOWS, 10, 0, 10240, 0 }; // 10
318+ const os_version_t WINDOWS_WIN11 = { OS_WINDOWS, 10, 0, 20348, 0 }; // 11
319319
320320 //Unknown OS
321321 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)
369369
370370 #pragma warning(pop)
371371
372-static bool rtl_verify_version(OSVERSIONINFOEXW *const osInfo, const ULONG typeMask, const ULONGLONG condMask)
373-{
374- typedef LONG(__stdcall *RtlVerifyVersionInfo)(LPOSVERSIONINFOEXW, ULONG, ULONGLONG);
375- if (const HMODULE ntdll = GetModuleHandleW(L"ntdll"))
376- {
377- if (const RtlVerifyVersionInfo pRtlVerifyVersionInfo = (RtlVerifyVersionInfo)GetProcAddress(ntdll, "RtlVerifyVersionInfo"))
378- {
379- if (pRtlVerifyVersionInfo(osInfo, typeMask, condMask) == 0)
380- {
381- return true;
382- }
383- }
384- }
385-
386- //Fallback
387- return (VerifyVersionInfoW(osInfo, typeMask, condMask) != FALSE);
388-}
389-
390-static bool verify_os_version(const DWORD major, const DWORD minor)
391-{
392- OSVERSIONINFOEXW osvi;
393- DWORDLONG dwlConditionMask = 0;
394- initialize_os_version(&osvi);
395-
396- //Initialize the OSVERSIONINFOEX structure
397- osvi.dwMajorVersion = major;
398- osvi.dwMinorVersion = minor;
399- osvi.dwPlatformId = VER_PLATFORM_WIN32_NT;
400-
401- //Initialize the condition mask
402- VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
403- VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
404- VER_SET_CONDITION(dwlConditionMask, VER_PLATFORMID, VER_EQUAL);
405-
406- // Perform the test
407- const BOOL ret = rtl_verify_version(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_PLATFORMID, dwlConditionMask);
408-
409- //Error checking
410- if(!ret)
411- {
412- if(GetLastError() != ERROR_OLD_WIN_VERSION)
413- {
414- qWarning("VerifyVersionInfo() system call has failed!");
415- }
416- }
417-
418- return (ret != FALSE);
419-}
420-
421-static bool verify_os_build(const DWORD build)
422-{
423- OSVERSIONINFOEXW osvi;
424- DWORDLONG dwlConditionMask = 0;
425- initialize_os_version(&osvi);
426-
427- //Initialize the OSVERSIONINFOEX structure
428- osvi.dwBuildNumber = build;
429- osvi.dwPlatformId = VER_PLATFORM_WIN32_NT;
430-
431- //Initialize the condition mask
432- VER_SET_CONDITION(dwlConditionMask, VER_BUILDNUMBER, VER_GREATER_EQUAL);
433- VER_SET_CONDITION(dwlConditionMask, VER_PLATFORMID, VER_EQUAL);
434-
435- // Perform the test
436- const BOOL ret = rtl_verify_version(&osvi, VER_BUILDNUMBER | VER_PLATFORMID, dwlConditionMask);
437-
438- //Error checking
439- if (!ret)
440- {
441- if (GetLastError() != ERROR_OLD_WIN_VERSION)
442- {
443- qWarning("VerifyVersionInfo() system call has failed!");
444- }
445- }
446-
447- return (ret != FALSE);
448-}
449-
450-static bool verify_os_spack(const WORD spack)
451-{
452- OSVERSIONINFOEXW osvi;
453- DWORDLONG dwlConditionMask = 0;
454- initialize_os_version(&osvi);
455-
456- //Initialize the OSVERSIONINFOEX structure
457- osvi.wServicePackMajor = spack;
458- osvi.dwPlatformId = VER_PLATFORM_WIN32_NT;
459-
460- //Initialize the condition mask
461- VER_SET_CONDITION(dwlConditionMask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
462- VER_SET_CONDITION(dwlConditionMask, VER_PLATFORMID, VER_EQUAL);
463-
464- // Perform the test
465- const BOOL ret = rtl_verify_version(&osvi, VER_SERVICEPACKMAJOR | VER_PLATFORMID, dwlConditionMask);
466-
467- //Error checking
468- if (!ret)
469- {
470- if (GetLastError() != ERROR_OLD_WIN_VERSION)
471- {
472- qWarning("VerifyVersionInfo() system call has failed!");
473- }
474- }
475-
476- return (ret != FALSE);
477-}
478-
479372 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)
480373 {
481374 static const DWORD MAX_VERSION = MAXWORD;
@@ -491,14 +384,14 @@ static bool get_real_os_version(unsigned int *const major, unsigned int *const m
491384 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
492385
493386 //Try GetVersionEx() first
494- if(rtl_get_version(&osvi) == FALSE)
387+ if (!rtl_get_version(&osvi))
495388 {
496389 qWarning("GetVersionEx() has failed, cannot detect Windows version!");
497390 return false;
498391 }
499392
500393 //Make sure we are running on NT
501- if(osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
394+ if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
502395 {
503396 *major = osvi.dwMajorVersion;
504397 *minor = osvi.dwMinorVersion;
@@ -507,84 +400,8 @@ static bool get_real_os_version(unsigned int *const major, unsigned int *const m
507400 }
508401 else
509402 {
510- if (verify_os_version(4, 0))
511- {
512- *major = 4;
513- *build = 1381;
514- *pbOverride = true;
515- }
516- else
517- {
518- qWarning("Not running on Windows NT, unsupported operating system!");
519- return false;
520- }
521- }
522-
523- //Major Version
524- for (DWORD nextMajor = (*major) + 1; nextMajor <= MAX_VERSION; nextMajor++)
525- {
526- if (verify_os_version(nextMajor, 0))
527- {
528- *major = nextMajor;
529- *minor = 0;
530- *pbOverride = true;
531- continue;
532- }
533- break;
534- }
535-
536- //Minor Version
537- for (DWORD nextMinor = (*minor) + 1; nextMinor <= MAX_VERSION; nextMinor++)
538- {
539- if (verify_os_version((*major), nextMinor))
540- {
541- *minor = nextMinor;
542- *pbOverride = true;
543- continue;
544- }
545- break;
546- }
547-
548- //Build Version
549- if (verify_os_build(SAFE_ADD((*build), 1, MAX_BUILDNO)))
550- {
551- DWORD stepSize = initialize_step_size(MAX_BUILDNO);
552- for (DWORD nextBuildNo = SAFE_ADD((*build), stepSize, MAX_BUILDNO); (*build) < MAX_BUILDNO; nextBuildNo = SAFE_ADD((*build), stepSize, MAX_BUILDNO))
553- {
554- if (verify_os_build(nextBuildNo))
555- {
556- *build = nextBuildNo;
557- *pbOverride = true;
558- continue;
559- }
560- if (stepSize > 1)
561- {
562- stepSize = stepSize / 2;
563- continue;
564- }
565- break;
566- }
567- }
568-
569- //Service Pack
570- if (verify_os_spack(SAFE_ADD((*spack), 1, MAX_SRVCPCK)))
571- {
572- DWORD stepSize = initialize_step_size(MAX_SRVCPCK);
573- for (DWORD nextSPackNo = SAFE_ADD((*spack), stepSize, MAX_SRVCPCK); (*spack) < MAX_SRVCPCK; nextSPackNo = SAFE_ADD((*spack), stepSize, MAX_SRVCPCK))
574- {
575- if (verify_os_spack(nextSPackNo))
576- {
577- *build = nextSPackNo;
578- *pbOverride = true;
579- continue;
580- }
581- if (stepSize > 1)
582- {
583- stepSize = stepSize / 2;
584- continue;
585- }
586- break;
587- }
403+ qWarning("Not running on Windows NT, unsupported operating system!");
404+ return false;
588405 }
589406
590407 return true;
@@ -632,15 +449,18 @@ const MUtils::OS::Version::os_version_t &MUtils::OS::os_version(void)
632449
633450 const char *MUtils::OS::os_friendly_name(const MUtils::OS::Version::os_version_t &os_version)
634451 {
635- for(size_t i = 0; g_os_version_lut[i].version != MUtils::OS::Version::UNKNOWN_OPSYS; i++)
452+ const char *friendly_name = NULL;
453+ for(size_t i = 0; g_os_version_lut[i].version.type != MUtils::OS::Version::OS_UNKNOWN; i++)
636454 {
637- if(os_version == g_os_version_lut[i].version)
455+ if(os_version >= g_os_version_lut[i].version)
638456 {
639- return g_os_version_lut[i].friendlyName;
457+ friendly_name = g_os_version_lut[i].friendlyName;
458+ continue;
640459 }
460+ break;
641461 }
642462
643- return NULL;
463+ return friendly_name;
644464 }
645465
646466 ///////////////////////////////////////////////////////////////////////////////
--- 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
244244 static QMutex g_init_lock;
245245 static const char *const g_imageformats[] = {"bmp", "png", "jpg", "gif", "ico", "xpm", "svg", NULL};
246246
247-#define REQUIRE_OS(MIN_OS, MIN_SP) \
248- ((osVersion.type == MUtils::OS::Version::OS_WINDOWS) && ((osVersion > MUtils::OS::Version::MIN_OS) || \
249- ((osVersion == MUtils::OS::Version::MIN_OS) && (osVersion.versionSPack >= (MIN_SP)))))
247+#define CHECK_OSVER(MINREQ_OS) \
248+ ((osVersion.type == MUtils::OS::Version::OS_WINDOWS) && (osVersion >= MUtils::OS::Version::MINREQ_OS))
250249
251-#define REQUIRE_SP(OS_VER, MIN_SP) \
252- ((osVersion != MUtils::OS::Version::OS_VER) || (osVersion.versionSPack >= (MIN_SP)))
250+#define CHECK_SPACK(MIN_OS, MAX_OS, REQUIRED_SP) \
251+ ((osVersion < MUtils::OS::Version::MIN_OS) || (osVersion >= MUtils::OS::Version::MAX_OS) || (osVersion.versionSPack >= (REQUIRED_SP)))
253252
254253 static FORCE_INLINE QString getExecutableName(int &argc, char **argv)
255254 {
@@ -327,29 +326,37 @@ QApplication *MUtils::Startup::create_qt(int &argc, char **argv, const QString &
327326 //Check whether we are running on a supported Windows version
328327 if (xpSupport)
329328 {
330- if (!REQUIRE_OS(WINDOWS_WINXP, 3))
329+ if (!CHECK_OSVER(WINDOWS_WINXP))
331330 {
332- qFatal("%s", MUTILS_L1STR(QApplication::tr("Executable '%1' requires Windows XP with SP-3 or later.").arg(executableName)));
331+ qFatal("%s", MUTILS_L1STR(QApplication::tr("Executable '%1' requires Windows XP or later.").arg(executableName)));
333332 }
334- if (!REQUIRE_SP(WINDOWS_XPX64, 2))
333+ else if (!CHECK_SPACK(WINDOWS_WINXP, WINDOWS_XPX64, 3))
335334 {
336- qFatal("%s", MUTILS_L1STR(QApplication::tr("Executable '%1' requires Windows XP x64-Edition with SP-2 or later.").arg(executableName)));
335+ qFatal("%s", MUTILS_L1STR(QApplication::tr("Executable '%1' requires Service Pack 3 for Windows XP.").arg(executableName)));
336+ }
337+ else if (!CHECK_SPACK(WINDOWS_XPX64, WINDOWS_VISTA, 2))
338+ {
339+ qFatal("%s", MUTILS_L1STR(QApplication::tr("Executable '%1' requires Service Pack 2 for Windows XP x64-Edition.").arg(executableName)));
337340 }
338341 }
339342 else
340343 {
341- if (!REQUIRE_OS(WINDOWS_VISTA, 2))
344+ if (!CHECK_OSVER(WINDOWS_VISTA))
345+ {
346+ qFatal("%s", MUTILS_L1STR(QApplication::tr("Executable '%1' requires Windows Vista or later.").arg(executableName)));
347+ }
348+ else if (!CHECK_SPACK(WINDOWS_VISTA, WINDOWS_WIN70, 2))
342349 {
343- qFatal("%s", MUTILS_L1STR(QApplication::tr("Executable '%1' requires Windows Vista with SP-2 or later.").arg(executableName)));
350+ qFatal("%s", MUTILS_L1STR(QApplication::tr("Executable '%1' requires Service Pack 2 for Windows Vista.").arg(executableName)));
344351 }
345352 }
346- if (osVersion == MUtils::OS::Version::WINDOWS_WIN80)
353+ if ((osVersion >= MUtils::OS::Version::WINDOWS_WIN80) && (osVersion < MUtils::OS::Version::WINDOWS_WIN81))
347354 {
348355 qFatal("%s", MUTILS_L1STR(QApplication::tr("Executable '%1' requires Windows 8.1 or later.").arg(executableName)));
349356 }
350357
351358 //Check for compat mode
352- if(osVersion.overrideFlag && (osVersion <= MUtils::OS::Version::WINDOWS_WN100))
359+ if(osVersion.overrideFlag && (osVersion <= MUtils::OS::Version::WINDOWS_WIN10))
353360 {
354361 qWarning("Windows compatibility mode detected!");
355362 if(!arguments.contains("ignore-compat-mode"))
Show on old repository browser