From aed167385524d6fac78671b6b9cbff77a168719e Mon Sep 17 00:00:00 2001 From: Yuhang Zhao <2546789017@qq.com> Date: Tue, 5 Jul 2022 10:36:34 +0800 Subject: [PATCH] win32: remove the limit to the manifest file Signed-off-by: Yuhang Zhao <2546789017@qq.com> --- .../Core/framelesshelpercore_global.h | 20 +++--- src/core/sysapiloader.cpp | 3 + src/core/utils_win.cpp | 65 ++++++++++--------- 3 files changed, 46 insertions(+), 42 deletions(-) diff --git a/include/FramelessHelper/Core/framelesshelpercore_global.h b/include/FramelessHelper/Core/framelesshelpercore_global.h index cd12f13..c067c26 100644 --- a/include/FramelessHelper/Core/framelesshelpercore_global.h +++ b/include/FramelessHelper/Core/framelesshelpercore_global.h @@ -332,17 +332,17 @@ struct VersionNumber int patch = 0; int tweak = 0; - [[nodiscard]] friend bool operator==(const VersionNumber &lhs, const VersionNumber &rhs) noexcept + [[nodiscard]] friend constexpr bool operator==(const VersionNumber &lhs, const VersionNumber &rhs) noexcept { return ((lhs.major == rhs.major) && (lhs.minor == rhs.minor) && (lhs.patch == rhs.patch) && (lhs.tweak == rhs.tweak)); } - [[nodiscard]] friend bool operator!=(const VersionNumber &lhs, const VersionNumber &rhs) noexcept + [[nodiscard]] friend constexpr bool operator!=(const VersionNumber &lhs, const VersionNumber &rhs) noexcept { - return !(lhs == rhs); + return !operator==(lhs, rhs); } - [[nodiscard]] friend bool operator>(const VersionNumber &lhs, const VersionNumber &rhs) noexcept + [[nodiscard]] friend constexpr bool operator>(const VersionNumber &lhs, const VersionNumber &rhs) noexcept { if (lhs.major > rhs.major) { return true; @@ -371,19 +371,19 @@ struct VersionNumber return false; } - [[nodiscard]] friend bool operator<(const VersionNumber &lhs, const VersionNumber &rhs) noexcept + [[nodiscard]] friend constexpr bool operator<(const VersionNumber &lhs, const VersionNumber &rhs) noexcept { - return ((lhs != rhs) && !(lhs > rhs)); + return (operator!=(lhs, rhs) && !operator>(lhs, rhs)); } - [[nodiscard]] friend bool operator>=(const VersionNumber &lhs, const VersionNumber &rhs) noexcept + [[nodiscard]] friend constexpr bool operator>=(const VersionNumber &lhs, const VersionNumber &rhs) noexcept { - return ((lhs > rhs) || (lhs == rhs)); + return (operator>(lhs, rhs) || operator==(lhs, rhs)); } - [[nodiscard]] friend bool operator<=(const VersionNumber &lhs, const VersionNumber &rhs) noexcept + [[nodiscard]] friend constexpr bool operator<=(const VersionNumber &lhs, const VersionNumber &rhs) noexcept { - return ((lhs < rhs) || (lhs == rhs)); + return (operator<(lhs, rhs) || operator==(lhs, rhs)); } }; diff --git a/src/core/sysapiloader.cpp b/src/core/sysapiloader.cpp index f50354b..468d8c8 100644 --- a/src/core/sysapiloader.cpp +++ b/src/core/sysapiloader.cpp @@ -23,6 +23,7 @@ */ #include "sysapiloader_p.h" +#include #ifdef Q_OS_WINDOWS # include #else @@ -72,8 +73,10 @@ bool SysApiLoader::isAvailable(const QString &library, const QString &function) QFunctionPointer symbol = SysApiLoader::resolve(library, function); if (symbol) { m_apiCache.insert(function, symbol); + qDebug() << "Successfully loaded" << function << "from" << library; return true; } + qWarning() << "Failed to load" << function << "from" << library; return false; } diff --git a/src/core/utils_win.cpp b/src/core/utils_win.cpp index 4a5ade2..6a10bc9 100644 --- a/src/core/utils_win.cpp +++ b/src/core/utils_win.cpp @@ -193,37 +193,40 @@ private: T *p = nullptr; }; -[[nodiscard]] static inline bool - doCompareWindowsVersion(const DWORD dwMajor, const DWORD dwMinor, const DWORD dwBuild) +[[nodiscard]] static inline bool doCompareWindowsVersion(const VersionNumber &targetOsVer) { -#if 0 - if (API_NT_AVAILABLE(RtlGetVersion)) { - using RtlGetVersionPtr = NTSTATUS(WINAPI *)(PRTL_OSVERSIONINFOW); - static const auto pRtlGetVersion = - reinterpret_cast( - SysApiLoader::instance()->get(kRtlGetVersion)); - RTL_OSVERSIONINFOEXW osvi; - SecureZeroMemory(&osvi, sizeof(osvi)); - osvi.dwOSVersionInfoSize = sizeof(osvi); - if (pRtlGetVersion(reinterpret_cast(&osvi)) == STATUS_SUCCESS) { - VersionNumber realOsVer = {}; - realOsVer.major = osvi.dwMajorVersion; - realOsVer.minor = osvi.dwMinorVersion; - realOsVer.patch = osvi.dwBuildNumber; - VersionNumber testOsVer = {}; - testOsVer.major = dwMajor; - testOsVer.minor = dwMinor; - testOsVer.tweak = dwBuild; - return (realOsVer >= testOsVer); + static const std::optional currentOsVer = []() -> std::optional { + if (API_NT_AVAILABLE(RtlGetVersion)) { + using RtlGetVersionPtr = NTSTATUS(WINAPI *)(PRTL_OSVERSIONINFOW); + const auto pRtlGetVersion = + reinterpret_cast(SysApiLoader::instance()->get(kRtlGetVersion)); + RTL_OSVERSIONINFOEXW osvi; + SecureZeroMemory(&osvi, sizeof(osvi)); + osvi.dwOSVersionInfoSize = sizeof(osvi); + if (pRtlGetVersion(reinterpret_cast(&osvi)) == STATUS_SUCCESS) { + return VersionNumber{int(osvi.dwMajorVersion), int(osvi.dwMinorVersion), int(osvi.dwBuildNumber)}; + } } + return std::nullopt; + }(); + if (currentOsVer.has_value()) { + return (currentOsVer >= targetOsVer); } -#endif + // We can fallback to "VerifyVersionInfoW" if we can't determine the current system + // version, but this function will be affected by the manifest file of your application. + // For example, if you don't claim your application supports Windows 10 explicitly + // in the manifest file, Windows will assume your application only supports up to Windows + // 8.1, so this function will be told the current system is at most Windows 8.1, to keep + // good backward-compatiability. This behavior usually won't cause any issues if you + // always use an appropriate manifest file for your application, however, it does cause + // some issues for people who don't use the manifest file at all. There have been some + // bug reports about it already. OSVERSIONINFOEXW osvi; SecureZeroMemory(&osvi, sizeof(osvi)); osvi.dwOSVersionInfoSize = sizeof(osvi); - osvi.dwMajorVersion = dwMajor; - osvi.dwMinorVersion = dwMinor; - osvi.dwBuildNumber = dwBuild; + osvi.dwMajorVersion = targetOsVer.major; + osvi.dwMinorVersion = targetOsVer.minor; + osvi.dwBuildNumber = targetOsVer.patch; DWORDLONG dwlConditionMask = 0; const auto op = VER_GREATER_EQUAL; VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, op); @@ -423,8 +426,7 @@ private: bool Utils::isWindowsVersionOrGreater(const WindowsVersion version) { - const VersionNumber ver = WindowsVersions[static_cast(version)]; - return doCompareWindowsVersion(ver.major, ver.minor, ver.patch); + return doCompareWindowsVersion(WindowsVersions[static_cast(version)]); } bool Utils::isDwmCompositionEnabled() @@ -818,9 +820,8 @@ quint32 Utils::getPrimaryScreenDpi(const bool horizontal) if (API_D2D_AVAILABLE(D2D1CreateFactory)) { using D2D1CreateFactoryPtr = HRESULT(WINAPI *)(D2D1_FACTORY_TYPE, REFIID, CONST D2D1_FACTORY_OPTIONS *, void **); - static const auto pD2D1CreateFactory = - reinterpret_cast( - SysApiLoader::instance()->get(kD2D1CreateFactory)); + const auto pD2D1CreateFactory = + reinterpret_cast(SysApiLoader::instance()->get(kD2D1CreateFactory)); HumbleComPtr d2dFactory = nullptr; HRESULT hr = pD2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory), nullptr, reinterpret_cast(&d2dFactory)); @@ -1442,10 +1443,10 @@ bool Utils::setBlurBehindWindowEnabled(const WId windowId, const BlurMode mode, qWarning() << "Failed to resolve DwmExtendFrameIntoClientArea() from DWMAPI.DLL."; return false; } - static const auto pSetWindowCompositionAttribute = + const auto pSetWindowCompositionAttribute = reinterpret_cast( SysApiLoader::instance()->get(kSetWindowCompositionAttribute)); - static const bool isBuild22523OrGreater = doCompareWindowsVersion(10, 0, 22523); + static const bool isBuild22523OrGreater = doCompareWindowsVersion({10, 0, 22523}); static const bool isWin11OrGreater = isWindowsVersionOrGreater(WindowsVersion::_11_21H2); static const bool isWin10OrGreater = isWindowsVersionOrGreater(WindowsVersion::_10_1507); const BlurMode blurMode = [mode]() -> BlurMode {