diff options
author | Frederik Gladhorn <frederik.gladhorn@theqtcompany.com> | 2015-01-19 13:49:52 +0100 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@theqtcompany.com> | 2015-01-21 11:10:14 +0100 |
commit | b6191b16d41459ed73cea738dfaf8e25e81ae22b (patch) | |
tree | 6ad0952af507bf1ab8df9612023d6e224db8d7e2 /src/corelib/global/qglobal.cpp | |
parent | b2883a6acc7a8d8372a815cc91dd1a8449f25723 (diff) | |
parent | 9087df6bd2dd5198ccf101a237aadee331e51ec3 (diff) |
Merge remote-tracking branch 'origin/5.4' into dev
Conflicts:
src/corelib/global/global.pri
src/corelib/global/qcompilerdetection.h
src/corelib/global/qglobal.h
src/corelib/tools/qdatetime.cpp
src/plugins/platforms/xcb/qxcbscreen.h
src/plugins/platforms/xcb/qxcbwindow.h
src/widgets/dialogs/qcolordialog.cpp
src/widgets/dialogs/qcolordialog_p.h
tools/configure/configureapp.cpp
Change-Id: Ie9d6e9df13e570da0a90a67745a0d05f46c532af
Diffstat (limited to 'src/corelib/global/qglobal.cpp')
-rw-r--r-- | src/corelib/global/qglobal.cpp | 78 |
1 files changed, 68 insertions, 10 deletions
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 4895bf6dd9..0a9e2f97db 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -41,6 +41,8 @@ #include "qdatetime.h" #include <private/qlocale_tools_p.h> +#include <private/qsystemlibrary_p.h> + #ifndef QT_NO_QOBJECT #include <private/qthread_p.h> #endif @@ -1876,6 +1878,70 @@ QT_BEGIN_INCLUDE_NAMESPACE QT_END_INCLUDE_NAMESPACE #ifndef Q_OS_WINRT + +# ifndef Q_OS_WINCE + +// Determine Windows versions >= 8 by querying the version of kernel32.dll. +static inline bool determineWinOsVersionPost8(OSVERSIONINFO *result) +{ + typedef WORD (WINAPI* PtrGetFileVersionInfoSizeW)(LPCWSTR, LPDWORD); + typedef BOOL (WINAPI* PtrVerQueryValueW)(LPCVOID, LPCWSTR, LPVOID, PUINT); + typedef BOOL (WINAPI* PtrGetFileVersionInfoW)(LPCWSTR, DWORD, DWORD, LPVOID); + + QSystemLibrary versionLib(QStringLiteral("version")); + if (!versionLib.load()) + return false; + PtrGetFileVersionInfoSizeW getFileVersionInfoSizeW = (PtrGetFileVersionInfoSizeW)versionLib.resolve("GetFileVersionInfoSizeW"); + PtrVerQueryValueW verQueryValueW = (PtrVerQueryValueW)versionLib.resolve("VerQueryValueW"); + PtrGetFileVersionInfoW getFileVersionInfoW = (PtrGetFileVersionInfoW)versionLib.resolve("GetFileVersionInfoW"); + if (!getFileVersionInfoSizeW || !verQueryValueW || !getFileVersionInfoW) + return false; + + const wchar_t kernel32Dll[] = L"kernel32.dll"; + DWORD handle; + const DWORD size = getFileVersionInfoSizeW(kernel32Dll, &handle); + if (!size) + return false; + QScopedArrayPointer<BYTE> versionInfo(new BYTE[size]); + if (!getFileVersionInfoW(kernel32Dll, handle, size, versionInfo.data())) + return false; + UINT uLen; + VS_FIXEDFILEINFO *fileInfo = Q_NULLPTR; + if (!verQueryValueW(versionInfo.data(), L"\\", (LPVOID *)&fileInfo, &uLen)) + return false; + const DWORD fileVersionMS = fileInfo->dwFileVersionMS; + const DWORD fileVersionLS = fileInfo->dwFileVersionLS; + result->dwMajorVersion = HIWORD(fileVersionMS); + result->dwMinorVersion = LOWORD(fileVersionMS); + result->dwBuildNumber = HIWORD(fileVersionLS); + return true; +} + +// Fallback for determining Windows versions >= 8 by looping using the +// version check macros. Note that it will return build number=0 to avoid +// inefficient looping. +static inline void determineWinOsVersionFallbackPost8(OSVERSIONINFO *result) +{ + result->dwBuildNumber = 0; + DWORDLONG conditionMask = 0; + VER_SET_CONDITION(conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL); + VER_SET_CONDITION(conditionMask, VER_PLATFORMID, VER_EQUAL); + OSVERSIONINFOEX checkVersion = { sizeof(OSVERSIONINFOEX), result->dwMajorVersion, 0, + result->dwBuildNumber, result->dwPlatformId, {'\0'}, 0, 0, 0, 0, 0 }; + for ( ; VerifyVersionInfo(&checkVersion, VER_MAJORVERSION | VER_PLATFORMID, conditionMask); ++checkVersion.dwMajorVersion) + result->dwMajorVersion = checkVersion.dwMajorVersion; + conditionMask = 0; + checkVersion.dwMajorVersion = result->dwMajorVersion; + checkVersion.dwMinorVersion = 0; + VER_SET_CONDITION(conditionMask, VER_MAJORVERSION, VER_EQUAL); + VER_SET_CONDITION(conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL); + VER_SET_CONDITION(conditionMask, VER_PLATFORMID, VER_EQUAL); + for ( ; VerifyVersionInfo(&checkVersion, VER_MAJORVERSION | VER_MINORVERSION | VER_PLATFORMID, conditionMask); ++checkVersion.dwMinorVersion) + result->dwMinorVersion = checkVersion.dwMinorVersion; +} + +# endif // !Q_OS_WINCE + static inline OSVERSIONINFO winOsVersion() { OSVERSIONINFO result = { sizeof(OSVERSIONINFO), 0, 0, 0, 0, {'\0'}}; @@ -1891,16 +1957,8 @@ static inline OSVERSIONINFO winOsVersion() # endif # ifndef Q_OS_WINCE if (result.dwMajorVersion == 6 && result.dwMinorVersion == 2) { - // This could be Windows 8.1 or higher. Note that as of Windows 9, - // the major version needs to be checked as well. - DWORDLONG conditionMask = 0; - VER_SET_CONDITION(conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL); - VER_SET_CONDITION(conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL); - VER_SET_CONDITION(conditionMask, VER_PLATFORMID, VER_EQUAL); - OSVERSIONINFOEX checkVersion = { sizeof(OSVERSIONINFOEX), result.dwMajorVersion, result.dwMinorVersion, - result.dwBuildNumber, result.dwPlatformId, {'\0'}, 0, 0, 0, 0, 0 }; - for ( ; VerifyVersionInfo(&checkVersion, VER_MAJORVERSION | VER_MINORVERSION | VER_PLATFORMID, conditionMask); ++checkVersion.dwMinorVersion) - result.dwMinorVersion = checkVersion.dwMinorVersion; + if (!determineWinOsVersionPost8(&result)) + determineWinOsVersionFallbackPost8(&result); } # endif // !Q_OS_WINCE return result; |