From b1c2ecee3f1cc160920c6a701081857311dd7894 Mon Sep 17 00:00:00 2001 From: LoRd_MuldeR Date: Sun, 21 Jun 2015 16:37:03 +0200 Subject: [PATCH] Added get_file_version() function + workaround to make get_real_os_version() give the correct result on Windows 10+. --- MUtilities_VS2013.vcxproj | 4 +-- include/MUtils/OSSupport.h | 3 ++ src/Config.h | 2 +- src/OSSupport_Win32.cpp | 68 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 74 insertions(+), 3 deletions(-) diff --git a/MUtilities_VS2013.vcxproj b/MUtilities_VS2013.vcxproj index 1eccd5d..9abfbd0 100644 --- a/MUtilities_VS2013.vcxproj +++ b/MUtilities_VS2013.vcxproj @@ -164,7 +164,7 @@ Windows true $(SolutionDir)\..\Prerequisites\Qt4\MSVC-2013\Debug\lib;$(SolutionDir)\..\Prerequisites\VisualLeakDetector\lib\Win32 - QtCored4.lib;QtGuid4.lib;Winmm.lib;Psapi.lib;Sensapi.lib;PowrProf.lib;Shlwapi.lib;%(AdditionalDependencies) + QtCored4.lib;QtGuid4.lib;Winmm.lib;Psapi.lib;Sensapi.lib;PowrProf.lib;Shlwapi.lib;Version.lib;%(AdditionalDependencies) @@ -193,7 +193,7 @@ true true $(SolutionDir)\..\Prerequisites\Qt4\MSVC-2013\Shared\lib;$(SolutionDir)\..\Prerequisites\VisualLeakDetector\lib\Win32 - QtCore4.lib;QtGui4.lib;Winmm.lib;Psapi.lib;Sensapi.lib;PowrProf.lib;Shlwapi.lib;%(AdditionalDependencies) + QtCore4.lib;QtGui4.lib;Winmm.lib;Psapi.lib;Sensapi.lib;PowrProf.lib;Shlwapi.lib;Version.lib;%(AdditionalDependencies) false diff --git a/include/MUtils/OSSupport.h b/include/MUtils/OSSupport.h index 359af2b..5499929 100644 --- a/include/MUtils/OSSupport.h +++ b/include/MUtils/OSSupport.h @@ -108,6 +108,9 @@ namespace MUtils typedef bool (*progress_callback_t)(const double &progress, void *const userData); MUTILS_API bool copy_file(const QString &sourcePath, const QString &outputPath, const bool &overwrite = true, const progress_callback_t callback = NULL, void *const userData = NULL); + //Get file version + MUTILS_API bool get_file_version(const QString fileName, quint16 *const major = NULL, quint16 *const minor = NULL, quint16 *const patch = NULL, quint16 *const build = NULL); + //Get the OS version MUTILS_API const Version::os_version_t &os_version(void); MUTILS_API const char *os_friendly_name(const MUtils::OS::Version::os_version_t &os_version); diff --git a/src/Config.h b/src/Config.h index e55910d..3a39d56 100644 --- a/src/Config.h +++ b/src/Config.h @@ -31,4 +31,4 @@ #define VER_MUTILS_MAJOR 1 #define VER_MUTILS_MINOR_HI 0 -#define VER_MUTILS_MINOR_LO 3 +#define VER_MUTILS_MINOR_LO 4 diff --git a/src/OSSupport_Win32.cpp b/src/OSSupport_Win32.cpp index 9046edb..1ceac1b 100644 --- a/src/OSSupport_Win32.cpp +++ b/src/OSSupport_Win32.cpp @@ -176,6 +176,59 @@ MUTILS_API bool MUtils::OS::copy_file(const QString &sourcePath, const QString & return (result != FALSE); } +/////////////////////////////////////////////////////////////////////////////// +// GET FILE VERSION +/////////////////////////////////////////////////////////////////////////////// + +static bool get_file_version_helper(const QString fileName, PVOID buffer, const size_t &size, quint16 *const major, quint16 *const minor, quint16 *const patch, quint16 *const build) +{ + if(!GetFileVersionInfo(MUTILS_WCHR(fileName), 0, size, buffer)) + { + qWarning("GetFileVersionInfo() has failed, file version cannot be determined!"); + return false; + } + + VS_FIXEDFILEINFO *verInfo; + UINT verInfoLen; + if(!VerQueryValue(buffer, L"\\", (LPVOID*)(&verInfo), &verInfoLen)) + { + qWarning("VerQueryValue() has failed, file version cannot be determined!"); + return false; + } + + if(major) *major = quint16((verInfo->dwFileVersionMS >> 16) & 0x0000FFFF); + if(minor) *minor = quint16((verInfo->dwFileVersionMS) & 0x0000FFFF); + if(patch) *patch = quint16((verInfo->dwFileVersionLS >> 16) & 0x0000FFFF); + if(build) *build = quint16((verInfo->dwFileVersionLS) & 0x0000FFFF); + + return true; +} + +bool MUtils::OS::get_file_version(const QString fileName, quint16 *const major, quint16 *const minor, quint16 *const patch, quint16 *const build) +{ + if(major) *major = 0U; if(minor) *minor = 0U; + if(patch) *patch = 0U; if(build) *build = 0U; + + const DWORD size = GetFileVersionInfoSize(MUTILS_WCHR(fileName), NULL); + if(size < 1) + { + qWarning("GetFileVersionInfoSize() has failed, file version cannot be determined!"); + return false; + } + + PVOID buffer = _malloca(size); + if(!buffer) + { + qWarning("Memory allocation has failed!"); + return false; + } + + const bool success = get_file_version_helper(fileName, buffer, size, major, minor, patch, build); + + _freea(buffer); + return success; +} + /////////////////////////////////////////////////////////////////////////////// // OS VERSION DETECTION /////////////////////////////////////////////////////////////////////////////// @@ -322,6 +375,21 @@ static bool get_real_os_version(unsigned int *major, unsigned int *minor, bool * break; } + //Workaround for the mess that is sometimes referred to as "Windows 10" + if(((*major) > 6) || (((*major) == 6) && ((*minor) >= 2))) + { + quint16 kernel32_major, kernel32_minor; + if(MUtils::OS::get_file_version(QLatin1String("kernel32"), &kernel32_major, &kernel32_minor)) + { + if((kernel32_major > (*major)) || ((kernel32_major == (*major)) && (kernel32_minor > (*minor)))) + { + *major = kernel32_major; + *minor = kernel32_minor; + *pbOverride = true; + } + } + } + return true; }