From 7bbcd5119d75803a97569c75918c2d401f70fe89 Mon Sep 17 00:00:00 2001 From: MaxXor Date: Sat, 22 Aug 2015 09:37:25 +0200 Subject: [PATCH] Improved OS architecture detection --- Client/Core/Helper/PlatformHelper.cs | 87 ++++++++++++-------------- Client/Core/Utilities/NativeMethods.cs | 12 +++- 2 files changed, 52 insertions(+), 47 deletions(-) diff --git a/Client/Core/Helper/PlatformHelper.cs b/Client/Core/Helper/PlatformHelper.cs index 629a3b3c..f73a4919 100644 --- a/Client/Core/Helper/PlatformHelper.cs +++ b/Client/Core/Helper/PlatformHelper.cs @@ -1,6 +1,7 @@ using System; using System.Management; using System.Text.RegularExpressions; +using xClient.Core.Utilities; namespace xClient.Core.Helper { @@ -33,68 +34,62 @@ namespace xClient.Core.Helper } Name = Regex.Replace(Name, "^.*(?=Windows)", "").TrimEnd().TrimStart(); // Remove everything before first match "Windows" and trim end & start + Architecture = (Is64BitOperatingSystem()) ? 64 : 32; } - //Credits: http://1code.codeplex.com/SourceControl/changeset/view/39074#842775 - public static int Is64BitOperatingSystem(string machineName, - string domain, string userName, string password) + /// + /// The function determines whether the current operating system is a + /// 64-bit operating system. + /// + /// + /// The function returns true if the operating system is 64-bit; + /// otherwise, it returns false. + /// + static bool Is64BitOperatingSystem() { - ConnectionOptions options = null; - if (!string.IsNullOrEmpty(userName)) + if (IntPtr.Size == 8) // 64-bit programs run only on Win64 { - // Build a ConnectionOptions object for the remote connection - // if you plan to connect to the remote with a different user - // name and password than the one you are currently using. - options = new ConnectionOptions(); - options.Username = userName; - options.Password = password; - options.Authority = "NTLMDOMAIN:" + domain; + return true; } - // Else the connection will use the currently logged-on user - - // Make a connection to the target computer. - ManagementScope scope = new ManagementScope("\\\\" + - (string.IsNullOrEmpty(machineName) ? "." : machineName) + - "\\root\\cimv2", options); - scope.Connect(); - - // Query Win32_Processor.AddressWidth which dicates the current - // operating mode of the processor (on a 32-bit OS, it would be - // "32"; on a 64-bit OS, it would be "64"). - // Note: Win32_Processor.DataWidth indicates the capability of - // the processor. On a 64-bit processor, it is "64". - // Note: Win32_OperatingSystem.OSArchitecture tells the bitness - // of OS too. On a 32-bit OS, it would be "32-bit". However, it - // is only available on Windows Vista and newer OS. - ObjectQuery query = new ObjectQuery( - "SELECT AddressWidth FROM Win32_Processor"); - - // Perform the query and get the result. - using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query)) + else // 32-bit programs run on both 32-bit and 64-bit Windows { - using (ManagementObjectCollection queryCollection = searcher.Get()) - { - foreach (ManagementObject queryObj in queryCollection) - { - if (queryObj["AddressWidth"].ToString() == "64") - { - return 64; - } - } - return 32; - } + // Detect whether the current process is a 32-bit process + // running on a 64-bit system. + bool flag; + return ((DoesWin32MethodExist("kernel32.dll", "IsWow64Process") && + NativeMethods.IsWow64Process(NativeMethods.GetCurrentProcess(), out flag)) && flag); } } + /// + /// The function determins whether a method exists in the export + /// table of a certain module. + /// + /// The name of the module + /// The name of the method + /// + /// The function returns true if the method specified by methodName + /// exists in the export table of the module specified by moduleName. + /// + static bool DoesWin32MethodExist(string moduleName, string methodName) + { + IntPtr moduleHandle = NativeMethods.GetModuleHandle(moduleName); + if (moduleHandle == IntPtr.Zero) + { + return false; + } + return (NativeMethods.GetProcAddress(moduleHandle, methodName) != IntPtr.Zero); + } + /// /// Gets the name of the operating system running on this computer (including the edition). /// public static string Name { get; private set; } /// - /// Determines if the current application is 32 or 64-bit. + /// Determines whether the operating system is 32 or 64-bit. /// - public static int Architecture { get {return Is64BitOperatingSystem(".", null, null, null); } } + public static int Architecture { get; private set; } /// /// Returns a indicating whether the application is running in Mono runtime. diff --git a/Client/Core/Utilities/NativeMethods.cs b/Client/Core/Utilities/NativeMethods.cs index 9f768137..ed876db0 100644 --- a/Client/Core/Utilities/NativeMethods.cs +++ b/Client/Core/Utilities/NativeMethods.cs @@ -15,10 +15,20 @@ namespace xClient.Core.Utilities [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi)] public static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)]string lpFileName); - [DllImport("kernel32.dll", CharSet = CharSet.Auto)] + [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern IntPtr GetProcAddress(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)]string procName); + [DllImport("kernel32.dll")] + public static extern IntPtr GetCurrentProcess(); + + [DllImport("kernel32.dll", CharSet = CharSet.Auto)] + public static extern IntPtr GetModuleHandle(string moduleName); + + [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool IsWow64Process(IntPtr hProcess, out bool wow64Process); + [DllImport("user32.dll")] public static extern bool SetCursorPos(int x, int y);