48
48
#include " qstringlist.h"
49
49
#include " qdatetime.h"
50
50
51
+ #include < private/qsystemlibrary_p.h>
52
+
51
53
#ifndef QT_NO_QOBJECT
52
54
#include < private/qthread_p.h>
53
55
#endif
@@ -1691,6 +1693,69 @@ QT_BEGIN_INCLUDE_NAMESPACE
1691
1693
#include " qt_windows.h"
1692
1694
QT_END_INCLUDE_NAMESPACE
1693
1695
1696
+ # ifndef Q_OS_WINCE
1697
+
1698
+ // Determine Windows versions >= 8 by querying the version of kernel32.dll.
1699
+ static inline bool determineWinOsVersionPost8 (OSVERSIONINFO *result)
1700
+ {
1701
+ typedef WORD (WINAPI* PtrGetFileVersionInfoSizeW)(LPCWSTR, LPDWORD);
1702
+ typedef BOOL (WINAPI* PtrVerQueryValueW)(LPCVOID, LPCWSTR, LPVOID, PUINT);
1703
+ typedef BOOL (WINAPI* PtrGetFileVersionInfoW)(LPCWSTR, DWORD, DWORD, LPVOID);
1704
+
1705
+ QSystemLibrary versionLib (QLatin1String (" version" ));
1706
+ if (!versionLib.load ())
1707
+ return false ;
1708
+ PtrGetFileVersionInfoSizeW getFileVersionInfoSizeW = (PtrGetFileVersionInfoSizeW)versionLib.resolve (" GetFileVersionInfoSizeW" );
1709
+ PtrVerQueryValueW verQueryValueW = (PtrVerQueryValueW)versionLib.resolve (" VerQueryValueW" );
1710
+ PtrGetFileVersionInfoW getFileVersionInfoW = (PtrGetFileVersionInfoW)versionLib.resolve (" GetFileVersionInfoW" );
1711
+ if (!getFileVersionInfoSizeW || !verQueryValueW || !getFileVersionInfoW)
1712
+ return false ;
1713
+
1714
+ const wchar_t kernel32Dll[] = L" kernel32.dll" ;
1715
+ DWORD handle;
1716
+ const DWORD size = getFileVersionInfoSizeW (kernel32Dll, &handle);
1717
+ if (!size)
1718
+ return false ;
1719
+ QScopedArrayPointer<BYTE> versionInfo (new BYTE[size]);
1720
+ if (!getFileVersionInfoW (kernel32Dll, handle, size, versionInfo.data ()))
1721
+ return false ;
1722
+ UINT uLen;
1723
+ VS_FIXEDFILEINFO *fileInfo = 0 ;
1724
+ if (!verQueryValueW (versionInfo.data (), L" \\ " , (LPVOID *)&fileInfo, &uLen))
1725
+ return false ;
1726
+ const DWORD fileVersionMS = fileInfo->dwFileVersionMS ;
1727
+ const DWORD fileVersionLS = fileInfo->dwFileVersionLS ;
1728
+ result->dwMajorVersion = HIWORD (fileVersionMS);
1729
+ result->dwMinorVersion = LOWORD (fileVersionMS);
1730
+ result->dwBuildNumber = HIWORD (fileVersionLS);
1731
+ return true ;
1732
+ }
1733
+
1734
+ // Fallback for determining Windows versions >= 8 by looping using the
1735
+ // version check macros. Note that it will return build number=0 to avoid
1736
+ // inefficient looping.
1737
+ static inline void determineWinOsVersionFallbackPost8 (OSVERSIONINFO *result)
1738
+ {
1739
+ result->dwBuildNumber = 0 ;
1740
+ DWORDLONG conditionMask = 0 ;
1741
+ VER_SET_CONDITION (conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
1742
+ VER_SET_CONDITION (conditionMask, VER_PLATFORMID, VER_EQUAL);
1743
+ OSVERSIONINFOEX checkVersion = { sizeof (OSVERSIONINFOEX), result->dwMajorVersion , 0 ,
1744
+ result->dwBuildNumber , result->dwPlatformId , {' \0 ' }, 0 , 0 , 0 , 0 , 0 };
1745
+ for ( ; VerifyVersionInfo (&checkVersion, VER_MAJORVERSION | VER_PLATFORMID, conditionMask); ++checkVersion.dwMajorVersion )
1746
+ result->dwMajorVersion = checkVersion.dwMajorVersion ;
1747
+ conditionMask = 0 ;
1748
+ checkVersion.dwMajorVersion = result->dwMajorVersion ;
1749
+ checkVersion.dwMinorVersion = 0 ;
1750
+ VER_SET_CONDITION (conditionMask, VER_MAJORVERSION, VER_EQUAL);
1751
+ VER_SET_CONDITION (conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
1752
+ VER_SET_CONDITION (conditionMask, VER_PLATFORMID, VER_EQUAL);
1753
+ for ( ; VerifyVersionInfo (&checkVersion, VER_MAJORVERSION | VER_MINORVERSION | VER_PLATFORMID, conditionMask); ++checkVersion.dwMinorVersion )
1754
+ result->dwMinorVersion = checkVersion.dwMinorVersion ;
1755
+ }
1756
+
1757
+ # endif // !Q_OS_WINCE
1758
+
1694
1759
static inline OSVERSIONINFO winOsVersion ()
1695
1760
{
1696
1761
OSVERSIONINFO result = { sizeof (OSVERSIONINFO), 0 , 0 , 0 , 0 , {' \0 ' }};
@@ -1706,16 +1771,8 @@ static inline OSVERSIONINFO winOsVersion()
1706
1771
# endif
1707
1772
# ifndef Q_OS_WINCE
1708
1773
if (result.dwMajorVersion == 6 && result.dwMinorVersion == 2 ) {
1709
- // This could be Windows 8.1 or higher. Note that as of Windows 9,
1710
- // the major version needs to be checked as well.
1711
- DWORDLONG conditionMask = 0 ;
1712
- VER_SET_CONDITION (conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
1713
- VER_SET_CONDITION (conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
1714
- VER_SET_CONDITION (conditionMask, VER_PLATFORMID, VER_EQUAL);
1715
- OSVERSIONINFOEX checkVersion = { sizeof (OSVERSIONINFOEX), result.dwMajorVersion , result.dwMinorVersion ,
1716
- result.dwBuildNumber , result.dwPlatformId , {' \0 ' }, 0 , 0 , 0 , 0 , 0 };
1717
- for ( ; VerifyVersionInfo (&checkVersion, VER_MAJORVERSION | VER_MINORVERSION | VER_PLATFORMID, conditionMask); ++checkVersion.dwMinorVersion )
1718
- result.dwMinorVersion = checkVersion.dwMinorVersion ;
1774
+ if (!determineWinOsVersionPost8 (&result))
1775
+ determineWinOsVersionFallbackPost8 (&result);
1719
1776
}
1720
1777
# endif // !Q_OS_WINCE
1721
1778
return result;
0 commit comments