GUI: Implemented detection of the ARM64 architecture via IsWow64Process2() function.

This commit is contained in:
LoRd_MuldeR 2022-05-23 22:38:24 +02:00
parent 17018e4f86
commit ae340c4070
Signed by: mulder
GPG Key ID: 2B5913365F57E03F
5 changed files with 86 additions and 20 deletions

View File

@ -35,14 +35,22 @@ namespace com.muldersoft.slunkcrypt.gui.process
FileStream executableFile = null; FileStream executableFile = null;
string appBaseDirectory = AppDomain.CurrentDomain.BaseDirectory; string appBaseDirectory = AppDomain.CurrentDomain.BaseDirectory;
CPUFeatures cpuFeatures = CPUFeatures.Features; CPUFeatures cpuFeatures = CPUFeatures.Features;
if (cpuFeatures.x64) if (cpuFeatures.cpuArch.Equals(CPUFeatures.CPUArch.a64))
{
if (CheckExecutableFile(ref executableFile, appBaseDirectory, "arm64"))
{
Trace.Assert(executableFile != null);
return executableFile;
}
}
if (cpuFeatures.cpuArch.Equals(CPUFeatures.CPUArch.x64))
{ {
if (cpuFeatures.hasAVX2 && CheckExecutableFile(ref executableFile, appBaseDirectory, "avx2")) if (cpuFeatures.hasAVX2 && CheckExecutableFile(ref executableFile, appBaseDirectory, "avx2"))
{ {
Trace.Assert(executableFile != null); Trace.Assert(executableFile != null);
return executableFile; return executableFile;
} }
else if (CheckExecutableFile(ref executableFile, appBaseDirectory, "x64")) if (CheckExecutableFile(ref executableFile, appBaseDirectory, "x64"))
{ {
Trace.Assert(executableFile != null); Trace.Assert(executableFile != null);
return executableFile; return executableFile;
@ -53,7 +61,7 @@ namespace com.muldersoft.slunkcrypt.gui.process
Trace.Assert(executableFile != null); Trace.Assert(executableFile != null);
return executableFile; return executableFile;
} }
else if (CheckExecutableFile(ref executableFile, appBaseDirectory, "i686")) if (CheckExecutableFile(ref executableFile, appBaseDirectory, "i686"))
{ {
Trace.Assert(executableFile != null); Trace.Assert(executableFile != null);
return executableFile; return executableFile;

View File

@ -860,7 +860,7 @@ namespace com.muldersoft.slunkcrypt.gui
.AppendLine(Environment.OSVersion.VersionString) .AppendLine(Environment.OSVersion.VersionString)
.AppendLine(string.Format("Operating System Bitness: {0:D}, Process Bitness: {1:D}", Environment.Is64BitOperatingSystem ? 64 : 32, Environment.Is64BitProcess ? 64 : 32)) .AppendLine(string.Format("Operating System Bitness: {0:D}, Process Bitness: {1:D}", Environment.Is64BitOperatingSystem ? 64 : 32, Environment.Is64BitProcess ? 64 : 32))
.AppendLine(".NET Runtime Version: " + Environment.Version) .AppendLine(".NET Runtime Version: " + Environment.Version)
.AppendLine(string.Format("CPU Count: {0:D}, Architecture: {1}, SSE2: {2}, AVX2: {3}", Environment.ProcessorCount, cpuFeatures.x64 ? "x64" : "x86", cpuFeatures.hasSSE2 ? "Yes" : "No", cpuFeatures.hasAVX2 ? "Yes" : "No")) .AppendLine(string.Format("CPU Count: {0:D}, Architecture: {1}, SSE2: {2}, AVX2: {3}", Environment.ProcessorCount, cpuFeatures.cpuArch.GetDescription(), cpuFeatures.hasSSE2 ? "Yes" : "No", cpuFeatures.hasAVX2 ? "Yes" : "No"))
.AppendLine() .AppendLine()
.AppendLine("Using “Silk” icons, by Mark James") .AppendLine("Using “Silk” icons, by Mark James")
.ToString(); .ToString();

View File

@ -16,7 +16,8 @@ namespace com.muldersoft.slunkcrypt.gui.utils.cpu
public enum CPUArchitecture : uint public enum CPUArchitecture : uint
{ {
CPU_ARCH_X86 = 0x00000001, CPU_ARCH_X86 = 0x00000001,
CPU_ARCH_X64 = 0x00000002 CPU_ARCH_X64 = 0x00000002,
CPU_ARCH_A64 = 0x00000003
} }
[Flags] [Flags]
@ -193,6 +194,23 @@ namespace com.muldersoft.slunkcrypt.gui.utils.cpu
private static CPUArchitecture GetCPUArchitecture() private static CPUArchitecture GetCPUArchitecture()
{ {
try
{
ushort processMachine, nativeMachine;
if (Internal.IsWow64Process2(Internal.GetCurrentProcess(), out processMachine, out nativeMachine))
{
switch(nativeMachine)
{
case 0x8664:
return CPUArchitecture.CPU_ARCH_X64;
case 0xAA64:
return CPUArchitecture.CPU_ARCH_A64;
default:
return CPUArchitecture.CPU_ARCH_X86;
}
}
}
catch { }
try try
{ {
VerifyLibraryVersion(); VerifyLibraryVersion();
@ -309,6 +327,7 @@ namespace com.muldersoft.slunkcrypt.gui.utils.cpu
{ {
const string DLL_NAME_X86 = "cpu-capabilities-x86.dll"; const string DLL_NAME_X86 = "cpu-capabilities-x86.dll";
const string DLL_NAME_X64 = "cpu-capabilities-x64.dll"; const string DLL_NAME_X64 = "cpu-capabilities-x64.dll";
const string DLL_KERNEL32 = "kernel32.dll";
/* GetCPUArchitecture() */ /* GetCPUArchitecture() */
[DllImport(DLL_NAME_X64, CallingConvention = CallingConvention.Cdecl)] [DllImport(DLL_NAME_X64, CallingConvention = CallingConvention.Cdecl)]
@ -351,6 +370,12 @@ namespace com.muldersoft.slunkcrypt.gui.utils.cpu
public static extern uint GetCPULibraryVersionX64(); public static extern uint GetCPULibraryVersionX64();
[DllImport(DLL_NAME_X86, CallingConvention = CallingConvention.Cdecl)] [DllImport(DLL_NAME_X86, CallingConvention = CallingConvention.Cdecl)]
public static extern uint GetCPULibraryVersionX86(); public static extern uint GetCPULibraryVersionX86();
/* IsWow64Process2() */
[DllImport(DLL_KERNEL32, SetLastError = true)]
public static extern bool IsWow64Process2(IntPtr process, out ushort processMachine, out ushort nativeMachine);
[DllImport(DLL_KERNEL32)]
public static extern IntPtr GetCurrentProcess();
} }
// ------------------------------------------------------------------ // ------------------------------------------------------------------

View File

@ -4,15 +4,22 @@
/******************************************************************************/ /******************************************************************************/
using System; using System;
using System.ComponentModel;
using com.muldersoft.slunkcrypt.gui.utils.cpu; using com.muldersoft.slunkcrypt.gui.utils.cpu;
namespace com.muldersoft.slunkcrypt.gui.process namespace com.muldersoft.slunkcrypt.gui.process
{ {
struct CPUFeatures struct CPUFeatures
{ {
public readonly bool x64; public enum CPUArch
public readonly bool hasSSE2; {
public readonly bool hasAVX2; [Description("x86")] x86 = 0x1,
[Description("x64")] x64 = 0x2,
[Description("ARM64")] a64 = 0x3
}
public readonly CPUArch cpuArch;
public readonly bool hasSSE2, hasAVX2;
private static readonly Lazy<CPUFeatures> cpuFeatures = new Lazy<CPUFeatures>(DetectFeatures); private static readonly Lazy<CPUFeatures> cpuFeatures = new Lazy<CPUFeatures>(DetectFeatures);
@ -21,26 +28,30 @@ namespace com.muldersoft.slunkcrypt.gui.process
get { return cpuFeatures.Value; } get { return cpuFeatures.Value; }
} }
public CPUFeatures(bool x64, bool sse2, bool avx2) public CPUFeatures(CPUArch cpuArch, bool hasSSE2, bool hasAVX2)
{ {
this.x64 = x64; this.cpuArch = cpuArch;
this.hasSSE2 = sse2; this.hasSSE2 = hasSSE2;
this.hasAVX2 = avx2; this.hasAVX2 = hasAVX2;
} }
private static CPUFeatures DetectFeatures() private static CPUFeatures DetectFeatures()
{ {
try try
{ {
return new CPUFeatures( CPUArchitecture cpuArchitecture = CPU.Architecture;
CPU.Architecture.Equals(CPUArchitecture.CPU_ARCH_X64), switch(cpuArchitecture)
CPU.Capabilities.HasFlag(CPUCapabilities.CPU_SSE2),
CPU.Capabilities.HasFlag(CPUCapabilities.CPU_AVX2));
}
catch
{ {
return new CPUFeatures(false, false, false); /*fallback*/ case CPUArchitecture.CPU_ARCH_X86:
return new CPUFeatures(CPUArch.x86, CPU.Capabilities.HasFlag(CPUCapabilities.CPU_SSE2), CPU.Capabilities.HasFlag(CPUCapabilities.CPU_AVX2));
case CPUArchitecture.CPU_ARCH_X64:
return new CPUFeatures(CPUArch.x64, CPU.Capabilities.HasFlag(CPUCapabilities.CPU_SSE2), CPU.Capabilities.HasFlag(CPUCapabilities.CPU_AVX2));
case CPUArchitecture.CPU_ARCH_A64:
return new CPUFeatures(CPUArch.a64, false, false);
} }
} }
catch { }
return new CPUFeatures(CPUArch.x86, false, false);
}
} }
} }

View File

@ -4,6 +4,8 @@
/******************************************************************************/ /******************************************************************************/
using System; using System;
using System.ComponentModel;
using System.Reflection;
namespace com.muldersoft.slunkcrypt.gui.utils namespace com.muldersoft.slunkcrypt.gui.utils
{ {
@ -20,5 +22,25 @@ namespace com.muldersoft.slunkcrypt.gui.utils
return false; return false;
} }
} }
public static string GetDescription(this Enum value)
{
Type type = value.GetType();
string name = Enum.GetName(type, value);
if (!string.IsNullOrEmpty(name))
{
FieldInfo field = type.GetField(name);
if (!ReferenceEquals(field, null))
{
DescriptionAttribute attr = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute;
if (!ReferenceEquals(attr, null))
{
return attr.Description;
}
}
return name;
}
return null;
}
} }
} }