OSDN Git Service

Added function to detect the OS architecture (x86 vs x64).
authorLoRd_MuldeR <mulder2@gmx.de>
Wed, 7 Aug 2019 19:47:20 +0000 (21:47 +0200)
committerLoRd_MuldeR <mulder2@gmx.de>
Wed, 7 Aug 2019 19:47:20 +0000 (21:47 +0200)
include/MUtils/OSSupport.h
src/OSSupport_Win32.cpp

index 2f2d7f2..92bbd85 100644 (file)
@@ -101,6 +101,16 @@ namespace MUtils
                }
 
                /**
                }
 
                /**
+               * \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
                */
                typedef enum
                * \brief This enumeration specifies "known" folder identifiers
                */
                typedef enum
@@ -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 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);
 
                //Get known Folder
                MUTILS_API const QString &known_folder(const known_folder_t folder_id);
index 1c506ae..a71bcd5 100644 (file)
@@ -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);
 }
 
        return ((a >= limit) || (b >= limit) || ((limit - a) <= b)) ? limit : (a + b);
 }
 
-
 static void initialize_os_version(OSVERSIONINFOEXW *const osInfo)
 {
        memset(osInfo, 0, sizeof(OSVERSIONINFOEXW));
 static void initialize_os_version(OSVERSIONINFOEXW *const osInfo)
 {
        memset(osInfo, 0, sizeof(OSVERSIONINFOEXW));
@@ -645,6 +644,60 @@ const char *MUtils::OS::os_friendly_name(const MUtils::OS::Version::os_version_t
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 }
 
 ///////////////////////////////////////////////////////////////////////////////
+// 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<IsWow64ProcessFun>(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
 ///////////////////////////////////////////////////////////////////////////////
 
 // WINE DETECTION
 ///////////////////////////////////////////////////////////////////////////////