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;
string appBaseDirectory = AppDomain.CurrentDomain.BaseDirectory;
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"))
{
Trace.Assert(executableFile != null);
return executableFile;
}
else if (CheckExecutableFile(ref executableFile, appBaseDirectory, "x64"))
if (CheckExecutableFile(ref executableFile, appBaseDirectory, "x64"))
{
Trace.Assert(executableFile != null);
return executableFile;
@ -53,7 +61,7 @@ namespace com.muldersoft.slunkcrypt.gui.process
Trace.Assert(executableFile != null);
return executableFile;
}
else if (CheckExecutableFile(ref executableFile, appBaseDirectory, "i686"))
if (CheckExecutableFile(ref executableFile, appBaseDirectory, "i686"))
{
Trace.Assert(executableFile != null);
return executableFile;

View File

@ -860,7 +860,7 @@ namespace com.muldersoft.slunkcrypt.gui
.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(".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("Using “Silk” icons, by Mark James")
.ToString();

View File

@ -16,7 +16,8 @@ namespace com.muldersoft.slunkcrypt.gui.utils.cpu
public enum CPUArchitecture : uint
{
CPU_ARCH_X86 = 0x00000001,
CPU_ARCH_X64 = 0x00000002
CPU_ARCH_X64 = 0x00000002,
CPU_ARCH_A64 = 0x00000003
}
[Flags]
@ -193,6 +194,23 @@ namespace com.muldersoft.slunkcrypt.gui.utils.cpu
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
{
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_X64 = "cpu-capabilities-x64.dll";
const string DLL_KERNEL32 = "kernel32.dll";
/* GetCPUArchitecture() */
[DllImport(DLL_NAME_X64, CallingConvention = CallingConvention.Cdecl)]
@ -351,6 +370,12 @@ namespace com.muldersoft.slunkcrypt.gui.utils.cpu
public static extern uint GetCPULibraryVersionX64();
[DllImport(DLL_NAME_X86, CallingConvention = CallingConvention.Cdecl)]
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.ComponentModel;
using com.muldersoft.slunkcrypt.gui.utils.cpu;
namespace com.muldersoft.slunkcrypt.gui.process
{
struct CPUFeatures
{
public readonly bool x64;
public readonly bool hasSSE2;
public readonly bool hasAVX2;
public enum CPUArch
{
[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);
@ -21,26 +28,30 @@ namespace com.muldersoft.slunkcrypt.gui.process
get { return cpuFeatures.Value; }
}
public CPUFeatures(bool x64, bool sse2, bool avx2)
public CPUFeatures(CPUArch cpuArch, bool hasSSE2, bool hasAVX2)
{
this.x64 = x64;
this.hasSSE2 = sse2;
this.hasAVX2 = avx2;
this.cpuArch = cpuArch;
this.hasSSE2 = hasSSE2;
this.hasAVX2 = hasAVX2;
}
private static CPUFeatures DetectFeatures()
{
try
{
return new CPUFeatures(
CPU.Architecture.Equals(CPUArchitecture.CPU_ARCH_X64),
CPU.Capabilities.HasFlag(CPUCapabilities.CPU_SSE2),
CPU.Capabilities.HasFlag(CPUCapabilities.CPU_AVX2));
}
catch
{
return new CPUFeatures(false, false, false); /*fallback*/
CPUArchitecture cpuArchitecture = CPU.Architecture;
switch(cpuArchitecture)
{
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.ComponentModel;
using System.Reflection;
namespace com.muldersoft.slunkcrypt.gui.utils
{
@ -20,5 +22,25 @@ namespace com.muldersoft.slunkcrypt.gui.utils
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;
}
}
}