diff --git a/include/MUtils/OSSupport.h b/include/MUtils/OSSupport.h index 2f2d7f2..92bbd85 100644 --- a/include/MUtils/OSSupport.h +++ b/include/MUtils/OSSupport.h @@ -100,6 +100,16 @@ namespace MUtils MUTILS_API extern const os_version_t UNKNOWN_OPSYS; ///< \brief Operating system version constant \details Unknown operating system version } + /** + * \brief This enumeration specifies possible operating system architectures + */ + typedef enum + { + ARCH_X86 = 1, ///< Intel x86 or compatible [32-bit] + ARCH_X64 = 2 ///< x86-64, aka AMD64, aka Intel 64 [64-bit] + } + os_arch_t; + /** * \brief This enumeration specifies "known" folder identifiers */ @@ -174,6 +184,7 @@ namespace MUtils 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); MUTILS_API const bool &running_on_wine(void); + MUTILS_API const os_arch_t &os_architecture(void); //Get known Folder MUTILS_API const QString &known_folder(const known_folder_t folder_id); diff --git a/src/OSSupport_Win32.cpp b/src/OSSupport_Win32.cpp index 1c506ae..a71bcd5 100644 --- a/src/OSSupport_Win32.cpp +++ b/src/OSSupport_Win32.cpp @@ -328,7 +328,6 @@ static inline DWORD SAFE_ADD(const DWORD &a, const DWORD &b, const DWORD &limit return ((a >= limit) || (b >= limit) || ((limit - a) <= b)) ? limit : (a + b); } - static void initialize_os_version(OSVERSIONINFOEXW *const osInfo) { memset(osInfo, 0, sizeof(OSVERSIONINFOEXW)); @@ -644,6 +643,60 @@ const char *MUtils::OS::os_friendly_name(const MUtils::OS::Version::os_version_t return NULL; } +/////////////////////////////////////////////////////////////////////////////// +// OS ARCHITECTURE DETECTION +/////////////////////////////////////////////////////////////////////////////// + +static bool g_os_arch_initialized = false; +static MUtils::OS::os_arch_t g_os_arch = MUtils::OS::os_arch_t(0); +static QReadWriteLock g_os_arch_lock; + +static MUtils::OS::os_arch_t detect_os_arch(void) +{ +#if (!(defined(_M_X64) || defined(_M_IA64))) + typedef BOOL(WINAPI * IsWow64ProcessFun)(__in HANDLE hProcess, __out PBOOL Wow64Process); + const IsWow64ProcessFun isWow64ProcessPtr = MUtils::Win32Utils::resolve(QLatin1String("kernel32"), QLatin1String("IsWow64Process")); + if (isWow64ProcessPtr) + { + BOOL x64flag = FALSE; + if (isWow64ProcessPtr(GetCurrentProcess(), &x64flag)) + { + if (x64flag) + { + return MUtils::OS::ARCH_X64; + } + } + } + return MUtils::OS::ARCH_X86; +#else + return MUtils::OS::ARCH_X64; +#endif +} + +const MUtils::OS::os_arch_t &MUtils::OS::os_architecture(void) +{ + QReadLocker readLock(&g_os_arch_lock); + + //Already initialized? + if (g_os_arch_initialized) + { + return g_os_arch; + } + + readLock.unlock(); + QWriteLocker writeLock(&g_os_arch_lock); + + //Initialized now? + if (g_os_arch_initialized) + { + return g_os_arch; + } + + g_os_arch = detect_os_arch(); + g_os_arch_initialized = MUTILS_BOOLIFY(g_os_arch); + return g_os_arch; +} + /////////////////////////////////////////////////////////////////////////////// // WINE DETECTION ///////////////////////////////////////////////////////////////////////////////