From 9b29f4e071b38ab4c97c96f0f979979fa170c124 Mon Sep 17 00:00:00 2001 From: Phyxion Date: Mon, 9 Sep 2019 20:15:57 +0200 Subject: [PATCH] Expose more information in the library --- Hardware/ATI/ADL.cs | 41 +- Hardware/ATI/ATIGroup.cs | 18 +- Hardware/Aquacomputer/AquacomputerGroup.cs | 1 - Hardware/Aquacomputer/AquastreamXT.cs | 2 - Hardware/CPU/AMD0FCPU.cs | 1 - Hardware/CPU/AMD17CPU.cs | 3 - Hardware/CPU/CPUID.cs | 276 ++-- Hardware/CPU/GenericCPU.cs | 85 +- Hardware/Computer.cs | 1 - Hardware/Control.cs | 1 - Hardware/FirmwareTable.cs | 1 - Hardware/HDD/ATAStorage.cs | 61 +- Hardware/HDD/AbstractStorage.cs | 18 +- Hardware/HDD/DebugSmart.cs | 18 +- .../HDD/{HDDGeneric.cs => GenericHarddisk.cs} | 236 ++-- Hardware/HDD/INVMeDrive.cs | 4 +- Hardware/HDD/ISmart.cs | 6 +- Hardware/HDD/NVMeGeneric.cs | 21 +- Hardware/HDD/NVMeHealthInfo.cs | 4 +- Hardware/HDD/NVMeInfo.cs | 2 +- Hardware/HDD/NVMeIntel.cs | 81 +- Hardware/HDD/NVMeIntelRST.cs | 78 +- Hardware/HDD/NVMeSamsung.cs | 102 +- Hardware/HDD/NVMeSmart.cs | 48 +- Hardware/HDD/NVMeWindows.cs | 68 +- Hardware/HDD/SSDSandforce.cs | 12 +- Hardware/HDD/SmartAttribute.cs | 6 +- Hardware/HDD/SmartNames.cs | 2 +- Hardware/HDD/StorageInfo.cs | 2 +- Hardware/HDD/WindowsSmart.cs | 79 +- Hardware/HDD/WindowsStorage.cs | 10 +- Hardware/HexStringArray.cs | 1 - Hardware/IOControlCode.cs | 1 - Hardware/Mainboard/GigabyteTAMG.cs | 2 - Hardware/Mainboard/Mainboard.cs | 7 +- Hardware/Nic/Nic.cs | 1 - Hardware/RAM/GenericRAM.cs | 16 +- Hardware/RAM/RAMGroup.cs | 1 - Hardware/SensorVisitor.cs | 1 - Hardware/TBalancer/TBalancer.cs | 1 - Interop/Kernel32.cs | 1131 ++++++++--------- OpenHardwareMonitorLib.csproj | 2 +- Software/OperatingSystem.cs | 1 - 43 files changed, 1212 insertions(+), 1241 deletions(-) rename Hardware/HDD/{HDDGeneric.cs => GenericHarddisk.cs} (94%) diff --git a/Hardware/ATI/ADL.cs b/Hardware/ATI/ADL.cs index fe25f76..56f9ab5 100644 --- a/Hardware/ATI/ADL.cs +++ b/Hardware/ATI/ADL.cs @@ -11,6 +11,7 @@ using System; using System.Runtime.InteropServices; using System.Text.RegularExpressions; +using OpenHardwareMonitor.Interop; namespace OpenHardwareMonitor.Hardware.ATI { @@ -100,40 +101,42 @@ namespace OpenHardwareMonitor.Hardware.ATI { public const int ATI_VENDOR_ID = 0x1002; - internal const string Atiadlxx_FileName = "atiadlxx.dll"; - [DllImport(Atiadlxx_FileName, CallingConvention = CallingConvention.Cdecl)] + internal const string DllName = "atiadlxx.dll"; + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern int ADL_Main_Control_Create(ADL_Main_Memory_AllocDelegate callback, int enumConnectedAdapters); - [DllImport(Atiadlxx_FileName, CallingConvention = CallingConvention.Cdecl)] + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern int ADL_Main_Control_Destroy(); - [DllImport(Atiadlxx_FileName, CallingConvention = CallingConvention.Cdecl)] + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern int ADL_Adapter_AdapterInfo_Get(IntPtr info, int size); - [DllImport(Atiadlxx_FileName, CallingConvention = CallingConvention.Cdecl)] + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern int ADL_Adapter_NumberOfAdapters_Get(); - [DllImport(Atiadlxx_FileName, CallingConvention = CallingConvention.Cdecl)] + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern int ADL_Adapter_NumberOfAdapters_Get(ref int numAdapters); - [DllImport(Atiadlxx_FileName, CallingConvention = CallingConvention.Cdecl)] - public static extern int ADL_Adapter_ID_Get(int adapterIndex, out int adapterID); - [DllImport(Atiadlxx_FileName, CallingConvention = CallingConvention.Cdecl)] - public static extern int ADL_Display_AdapterID_Get(int adapterIndex, out int adapterID); - [DllImport(Atiadlxx_FileName, CallingConvention = CallingConvention.Cdecl)] + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] + public static extern int ADL_Adapter_ID_Get(int adapterIndex, out int adapterId); + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] + public static extern int ADL_Display_AdapterID_Get(int adapterIndex, out int adapterId); + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern int ADL_Adapter_Active_Get(int adapterIndex, out int status); - [DllImport(Atiadlxx_FileName, CallingConvention = CallingConvention.Cdecl)] + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern int ADL_Overdrive5_CurrentActivity_Get(int iAdapterIndex, ref ADLPMActivity activity); - [DllImport(Atiadlxx_FileName, CallingConvention = CallingConvention.Cdecl)] + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern int ADL_Overdrive5_Temperature_Get(int adapterIndex, int thermalControllerIndex, ref ADLTemperature temperature); - [DllImport(Atiadlxx_FileName, CallingConvention = CallingConvention.Cdecl)] + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern int ADL_Overdrive5_FanSpeed_Get(int adapterIndex, int thermalControllerIndex, ref ADLFanSpeedValue fanSpeedValue); - [DllImport(Atiadlxx_FileName, CallingConvention = CallingConvention.Cdecl)] + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern int ADL_Overdrive5_FanSpeedInfo_Get(int adapterIndex, int thermalControllerIndex, ref ADLFanSpeedInfo fanSpeedInfo); - [DllImport(Atiadlxx_FileName, CallingConvention = CallingConvention.Cdecl)] + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern int ADL_Overdrive5_FanSpeedToDefault_Set(int adapterIndex, int thermalControllerIndex); - [DllImport(Atiadlxx_FileName, CallingConvention = CallingConvention.Cdecl)] + [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern int ADL_Overdrive5_FanSpeed_Set(int adapterIndex, int thermalControllerIndex, ref ADLFanSpeedValue fanSpeedValue); public static int ADL_Main_Control_Create(int enumConnectedAdapters) { try { - return ADL_Main_Control_Create(Main_Memory_Alloc, - enumConnectedAdapters); + if (Kernel32.LoadLibrary(DllName) != IntPtr.Zero) + return ADL_Main_Control_Create(Main_Memory_Alloc, enumConnectedAdapters); + + return ADL_ERR; } catch { return ADL_ERR; } diff --git a/Hardware/ATI/ATIGroup.cs b/Hardware/ATI/ATIGroup.cs index fb375cb..32047b1 100644 --- a/Hardware/ATI/ATIGroup.cs +++ b/Hardware/ATI/ATIGroup.cs @@ -12,16 +12,17 @@ using System; using System.Collections.Generic; using System.Globalization; using System.Text; +using OpenHardwareMonitor.Interop; namespace OpenHardwareMonitor.Hardware.ATI { internal class ATIGroup : IGroup { private readonly List hardware = new List(); private readonly StringBuilder report = new StringBuilder(); - + private readonly int status; public ATIGroup(ISettings settings) { try { - int status = ADL.ADL_Main_Control_Create(1); + status = ADL.ADL_Main_Control_Create(1); report.AppendLine("AMD Display Library"); report.AppendLine(); @@ -42,12 +43,8 @@ namespace OpenHardwareMonitor.Hardware.ATI { ADLAdapterInfo[] adapterInfo = new ADLAdapterInfo[numberOfAdapters]; if (ADL.ADL_Adapter_AdapterInfo_Get(adapterInfo) == ADL.ADL_OK) for (int i = 0; i < numberOfAdapters; i++) { - int isActive; - ADL.ADL_Adapter_Active_Get(adapterInfo[i].AdapterIndex, - out isActive); - int adapterID; - ADL.ADL_Adapter_ID_Get(adapterInfo[i].AdapterIndex, - out adapterID); + ADL.ADL_Adapter_Active_Get(adapterInfo[i].AdapterIndex, out var isActive); + ADL.ADL_Adapter_ID_Get(adapterInfo[i].AdapterIndex, out var adapterId); report.Append("AdapterIndex: "); report.AppendLine(i.ToString(CultureInfo.InvariantCulture)); @@ -73,7 +70,7 @@ namespace OpenHardwareMonitor.Hardware.ATI { report.AppendLine(adapterInfo[i].FunctionNumber.ToString( CultureInfo.InvariantCulture)); report.Append("AdapterID: 0x"); - report.AppendLine(adapterID.ToString("X", + report.AppendLine(adapterId.ToString("X", CultureInfo.InvariantCulture)); if (!string.IsNullOrEmpty(adapterInfo[i].UDID) && @@ -116,7 +113,8 @@ namespace OpenHardwareMonitor.Hardware.ATI { try { foreach (ATIGPU gpu in hardware) gpu.Close(); - ADL.ADL_Main_Control_Destroy(); + if (status == ADL.ADL_OK) + ADL.ADL_Main_Control_Destroy(); } catch (Exception) { } } } diff --git a/Hardware/Aquacomputer/AquacomputerGroup.cs b/Hardware/Aquacomputer/AquacomputerGroup.cs index d1e5930..9873825 100644 --- a/Hardware/Aquacomputer/AquacomputerGroup.cs +++ b/Hardware/Aquacomputer/AquacomputerGroup.cs @@ -1,5 +1,4 @@ using HidLibrary; -using System; using System.Collections.Generic; using System.Text; diff --git a/Hardware/Aquacomputer/AquastreamXT.cs b/Hardware/Aquacomputer/AquastreamXT.cs index 1648062..4035f7e 100644 --- a/Hardware/Aquacomputer/AquastreamXT.cs +++ b/Hardware/Aquacomputer/AquastreamXT.cs @@ -1,6 +1,4 @@ using System; -using System.Collections.Generic; -using System.Text; using HidLibrary; namespace OpenHardwareMonitor.Hardware.Aquacomputer diff --git a/Hardware/CPU/AMD0FCPU.cs b/Hardware/CPU/AMD0FCPU.cs index ed2ad80..526815a 100644 --- a/Hardware/CPU/AMD0FCPU.cs +++ b/Hardware/CPU/AMD0FCPU.cs @@ -9,7 +9,6 @@ */ -using System; using System.Globalization; using System.Text; using System.Threading; diff --git a/Hardware/CPU/AMD17CPU.cs b/Hardware/CPU/AMD17CPU.cs index 627e8fc..92aba6d 100644 --- a/Hardware/CPU/AMD17CPU.cs +++ b/Hardware/CPU/AMD17CPU.cs @@ -6,12 +6,9 @@ using System; using System.Collections.Generic; -using System.Diagnostics; -using System.Globalization; using System.IO; using System.Linq; using System.Text; -using System.Threading; namespace OpenHardwareMonitor.Hardware.CPU { diff --git a/Hardware/CPU/CPUID.cs b/Hardware/CPU/CPUID.cs index fed0aa5..6907218 100644 --- a/Hardware/CPU/CPUID.cs +++ b/Hardware/CPU/CPUID.cs @@ -12,80 +12,45 @@ using System; using System.Text; namespace OpenHardwareMonitor.Hardware.CPU { - public enum Vendor { + public enum Vendor { Unknown, Intel, - AMD, + AMD } - public class CPUID { - - private readonly int thread; - - private readonly Vendor vendor = Vendor.Unknown; - - private readonly string cpuBrandString = ""; - private readonly string name = ""; - - private readonly uint[,] cpuidData = new uint[0, 0]; - private readonly uint[,] cpuidExtData = new uint[0, 0]; - - private readonly uint family; - private readonly uint model; - private readonly uint stepping; - - private readonly uint apicId; - - private readonly uint threadMaskWith; - private readonly uint coreMaskWith; - - private readonly uint processorId; - private readonly uint coreId; - private readonly uint threadId; - + public class CPUID { public const uint CPUID_0 = 0; public const uint CPUID_EXT = 0x80000000; - - private static void AppendRegister(StringBuilder b, uint value) { - b.Append((char)((value) & 0xff)); - b.Append((char)((value >> 8) & 0xff)); - b.Append((char)((value >> 16) & 0xff)); - b.Append((char)((value >> 24) & 0xff)); - } - - private static uint NextLog2(long x) { - if (x <= 0) - return 0; - - x--; - uint count = 0; - while (x > 0) { - x >>= 1; - count++; - } - - return count; - } + private readonly uint coreMaskWith; + private readonly uint threadMaskWith; public CPUID(int thread) { - this.thread = thread; - - uint maxCpuid = 0; - uint maxCpuidExt = 0; + Thread = thread; + uint maxCpuidExt; uint eax, ebx, ecx, edx; if (thread >= 64) throw new ArgumentOutOfRangeException("thread"); + + ulong mask = 1UL << thread; - if (Opcode.CpuidTx(CPUID_0, 0, - out eax, out ebx, out ecx, out edx, mask)) { + + uint maxCpuid; + if (Opcode.CpuidTx(CPUID_0, + 0, + out eax, + out ebx, + out ecx, + out edx, + mask)) { if (eax > 0) maxCpuid = eax; else return; + StringBuilder vendorBuilder = new StringBuilder(); AppendRegister(vendorBuilder, ebx); AppendRegister(vendorBuilder, edx); @@ -93,18 +58,24 @@ namespace OpenHardwareMonitor.Hardware.CPU { string cpuVendor = vendorBuilder.ToString(); switch (cpuVendor) { case "GenuineIntel": - vendor = Vendor.Intel; + Vendor = Vendor.Intel; break; case "AuthenticAMD": - vendor = Vendor.AMD; + Vendor = Vendor.AMD; break; default: - vendor = Vendor.Unknown; + Vendor = Vendor.Unknown; break; } + eax = ebx = ecx = edx = 0; - if (Opcode.CpuidTx(CPUID_EXT, 0, - out eax, out ebx, out ecx, out edx, mask)) { + if (Opcode.CpuidTx(CPUID_EXT, + 0, + out eax, + out ebx, + out ecx, + out edx, + mask)) { if (eax > CPUID_EXT) maxCpuidExt = eax - CPUID_EXT; else @@ -117,33 +88,46 @@ namespace OpenHardwareMonitor.Hardware.CPU { } maxCpuid = Math.Min(maxCpuid, 1024); - maxCpuidExt = Math.Min(maxCpuidExt, 1024); + maxCpuidExt = Math.Min(maxCpuidExt, 1024); - cpuidData = new uint[maxCpuid + 1, 4]; + Data = new uint[maxCpuid + 1, 4]; for (uint i = 0; i < (maxCpuid + 1); i++) - Opcode.CpuidTx(CPUID_0 + i, 0, - out cpuidData[i, 0], out cpuidData[i, 1], - out cpuidData[i, 2], out cpuidData[i, 3], mask); + Opcode.CpuidTx(CPUID_0 + i, + 0, + out Data[i, 0], + out Data[i, 1], + out Data[i, 2], + out Data[i, 3], + mask); - cpuidExtData = new uint[maxCpuidExt + 1, 4]; + ExtData = new uint[maxCpuidExt + 1, 4]; for (uint i = 0; i < (maxCpuidExt + 1); i++) - Opcode.CpuidTx(CPUID_EXT + i, 0, - out cpuidExtData[i, 0], out cpuidExtData[i, 1], - out cpuidExtData[i, 2], out cpuidExtData[i, 3], mask); + Opcode.CpuidTx(CPUID_EXT + i, + 0, + out ExtData[i, 0], + out ExtData[i, 1], + out ExtData[i, 2], + out ExtData[i, 3], + mask); StringBuilder nameBuilder = new StringBuilder(); for (uint i = 2; i <= 4; i++) { - if (Opcode.CpuidTx(CPUID_EXT + i, 0, - out eax, out ebx, out ecx, out edx, mask)) - { + if (Opcode.CpuidTx(CPUID_EXT + i, + 0, + out eax, + out ebx, + out ecx, + out edx, + mask)) { AppendRegister(nameBuilder, eax); AppendRegister(nameBuilder, ebx); AppendRegister(nameBuilder, ecx); AppendRegister(nameBuilder, edx); } } + nameBuilder.Replace('\0', ' '); - cpuBrandString = nameBuilder.ToString().Trim(); + BrandString = nameBuilder.ToString().Trim(); nameBuilder.Replace("(R)", " "); nameBuilder.Replace("(TM)", " "); nameBuilder.Replace("(tm)", ""); @@ -152,60 +136,65 @@ namespace OpenHardwareMonitor.Hardware.CPU { nameBuilder.Replace("Six-Core Processor", ""); nameBuilder.Replace("Eight-Core Processor", ""); for (int i = 0; i < 10; i++) nameBuilder.Replace(" ", " "); - name = nameBuilder.ToString(); - if (name.Contains("@")) - name = name.Remove(name.LastIndexOf('@')); - name = name.Trim(); + Name = nameBuilder.ToString(); + if (Name.Contains("@")) + Name = Name.Remove(Name.LastIndexOf('@')); - this.family = ((cpuidData[1, 0] & 0x0FF00000) >> 20) + - ((cpuidData[1, 0] & 0x0F00) >> 8); - this.model = ((cpuidData[1, 0] & 0x0F0000) >> 12) + - ((cpuidData[1, 0] & 0xF0) >> 4); - this.stepping = (cpuidData[1, 0] & 0x0F); + Name = Name.Trim(); - this.apicId = (cpuidData[1, 1] >> 24) & 0xFF; + Family = ((Data[1, 0] & 0x0FF00000) >> 20) + + ((Data[1, 0] & 0x0F00) >> 8); - switch (vendor) { + Model = ((Data[1, 0] & 0x0F0000) >> 12) + + ((Data[1, 0] & 0xF0) >> 4); + + Stepping = (Data[1, 0] & 0x0F); + + ApicId = (Data[1, 1] >> 24) & 0xFF; + + switch (Vendor) { case Vendor.Intel: - uint maxCoreAndThreadIdPerPackage = (cpuidData[1, 1] >> 16) & 0xFF; + uint maxCoreAndThreadIdPerPackage = (Data[1, 1] >> 16) & 0xFF; uint maxCoreIdPerPackage; if (maxCpuid >= 4) - maxCoreIdPerPackage = ((cpuidData[4, 0] >> 26) & 0x3F) + 1; + maxCoreIdPerPackage = ((Data[4, 0] >> 26) & 0x3F) + 1; else maxCoreIdPerPackage = 1; - threadMaskWith = + + threadMaskWith = NextLog2(maxCoreAndThreadIdPerPackage / maxCoreIdPerPackage); + coreMaskWith = NextLog2(maxCoreIdPerPackage); break; case Vendor.AMD: uint corePerPackage; if (maxCpuidExt >= 8) - corePerPackage = (cpuidExtData[8, 2] & 0xFF) + 1; + corePerPackage = (ExtData[8, 2] & 0xFF) + 1; else corePerPackage = 1; + threadMaskWith = 0; coreMaskWith = NextLog2(corePerPackage); - - if (this.family == 0x17) - { + + if (Family == 0x17) { // ApicIdCoreIdSize: APIC ID size. // cores per DIE // we need this for Ryzen 5 (4 cores, 8 threads) ans Ryzen 6 (6 cores, 12 threads) // Ryzen 5: [core0][core1][dummy][dummy][core2][core3] (Core0 EBX = 00080800, Core2 EBX = 08080800) - uint max_cores_per_die = (cpuidExtData[8, 2] >> 12) & 0xF; - switch (max_cores_per_die) - { + uint max_cores_per_die = (ExtData[8, 2] >> 12) & 0xF; + switch (max_cores_per_die) { case 0x04: // Ryzen coreMaskWith = NextLog2(16); break; - case 0x05:// Threadripper + case 0x05: // Threadripper coreMaskWith = NextLog2(32); break; - case 0x06:// Epic + case 0x06: // Epic coreMaskWith = NextLog2(64); break; } } + break; default: threadMaskWith = 0; @@ -213,64 +202,57 @@ namespace OpenHardwareMonitor.Hardware.CPU { break; } - processorId = (apicId >> (int)(coreMaskWith + threadMaskWith)); - coreId = ((apicId >> (int)(threadMaskWith)) - - (processorId << (int)(coreMaskWith))); - threadId = apicId - - (processorId << (int)(coreMaskWith + threadMaskWith)) - - (coreId << (int)(threadMaskWith)); + ProcessorId = (ApicId >> (int) (coreMaskWith + threadMaskWith)); + CoreId = ((ApicId >> (int) (threadMaskWith)) - (ProcessorId << (int) (coreMaskWith))); + ThreadId = ApicId - (ProcessorId << (int) (coreMaskWith + threadMaskWith)) - (CoreId << (int) (threadMaskWith)); } - public string Name { - get { return name; } + public uint ApicId { get; } + + public string BrandString { get; } = ""; + + public uint CoreId { get; } + + public uint[,] Data { get; } = new uint[0, 0]; + + public uint[,] ExtData { get; } = new uint[0, 0]; + + public uint Family { get; } + + public uint Model { get; } + + public string Name { get; } = ""; + + public uint ProcessorId { get; } + + public uint Stepping { get; } + + public int Thread { get; } + + public uint ThreadId { get; } + + public Vendor Vendor { get; } = Vendor.Unknown; + + private static void AppendRegister(StringBuilder b, uint value) { + b.Append((char) ((value) & 0xff)); + b.Append((char) ((value >> 8) & 0xff)); + b.Append((char) ((value >> 16) & 0xff)); + b.Append((char) ((value >> 24) & 0xff)); } - public string BrandString { - get { return cpuBrandString; } - } + private static uint NextLog2(long x) { + if (x <= 0) + return 0; - public int Thread { - get { return thread; } - } - public Vendor Vendor { - get { return vendor; } - } + x--; + uint count = 0; + while (x > 0) { + x >>= 1; + count++; + } - public uint Family { - get { return family; } - } - - public uint Model { - get { return model; } - } - - public uint Stepping { - get { return stepping; } - } - - public uint ApicId { - get { return apicId; } - } - - public uint ProcessorId { - get { return processorId; } - } - - public uint CoreId { - get { return coreId; } - } - - public uint ThreadId { - get { return threadId; } - } - - public uint[,] Data { - get { return cpuidData; } - } - - public uint[,] ExtData { - get { return cpuidExtData; } + return count; } } -} +} \ No newline at end of file diff --git a/Hardware/CPU/GenericCPU.cs b/Hardware/CPU/GenericCPU.cs index ecf91d4..fc63e62 100644 --- a/Hardware/CPU/GenericCPU.cs +++ b/Hardware/CPU/GenericCPU.cs @@ -9,12 +9,9 @@ */ using System; -using System.Collections.Generic; using System.Diagnostics; using System.Globalization; -using System.Runtime.InteropServices; using System.Text; -using System.Threading; namespace OpenHardwareMonitor.Hardware.CPU { public class GenericCPU : Hardware { @@ -28,17 +25,12 @@ namespace OpenHardwareMonitor.Hardware.CPU { protected readonly int processorIndex; protected readonly int coreCount; - private readonly bool hasModelSpecificRegisters; - - private readonly bool hasTimeStampCounter; private readonly bool isInvariantTimeStampCounter; private readonly double estimatedTimeStampCounterFrequency; private readonly double estimatedTimeStampCounterFrequencyError; private ulong lastTimeStampCount; private long lastTime; - private double timeStampCounterFrequency; - private readonly Vendor vendor; @@ -46,6 +38,11 @@ namespace OpenHardwareMonitor.Hardware.CPU { private readonly Sensor totalLoad; private readonly Sensor[] coreLoads; + /// + /// Gets the CPUID. + /// + public CPUID[][] CPUID => cpuid; + protected string CoreString(int i) { if (coreCount == 1) return "CPU Core"; @@ -59,28 +56,28 @@ namespace OpenHardwareMonitor.Hardware.CPU { { this.cpuid = cpuid; - this.vendor = cpuid[0][0].Vendor; + vendor = cpuid[0][0].Vendor; - this.family = cpuid[0][0].Family; - this.model = cpuid[0][0].Model; - this.stepping = cpuid[0][0].Stepping; + family = cpuid[0][0].Family; + model = cpuid[0][0].Model; + stepping = cpuid[0][0].Stepping; this.processorIndex = processorIndex; - this.coreCount = cpuid.Length; + coreCount = cpuid.Length; // check if processor has MSRs if (cpuid[0][0].Data.GetLength(0) > 1 && (cpuid[0][0].Data[1, 3] & 0x20) != 0) - hasModelSpecificRegisters = true; + HasModelSpecificRegisters = true; else - hasModelSpecificRegisters = false; + HasModelSpecificRegisters = false; // check if processor has a TSC if (cpuid[0][0].Data.GetLength(0) > 1 && (cpuid[0][0].Data[1, 3] & 0x10) != 0) - hasTimeStampCounter = true; + HasTimeStampCounter = true; else - hasTimeStampCounter = false; + HasTimeStampCounter = false; // check if processor supports an invariant TSC if (cpuid[0][0].ExtData.GetLength(0) > 7 @@ -105,7 +102,7 @@ namespace OpenHardwareMonitor.Hardware.CPU { ActivateSensor(totalLoad); } - if (hasTimeStampCounter) { + if (HasTimeStampCounter) { ulong mask = ThreadAffinity.Set(1UL << cpuid[0][0].Thread); EstimateTimeStampCounterFrequency( @@ -117,7 +114,7 @@ namespace OpenHardwareMonitor.Hardware.CPU { estimatedTimeStampCounterFrequency = 0; } - timeStampCounterFrequency = estimatedTimeStampCounterFrequency; + TimeStampCounterFrequency = estimatedTimeStampCounterFrequency; } private static Identifier CreateIdentifier(Vendor vendor, @@ -158,13 +155,13 @@ namespace OpenHardwareMonitor.Hardware.CPU { } private void EstimateTimeStampCounterFrequency(double timeWindow, - out double frequency, out double error) + out double frequency, out double error) { long ticks = (long)(timeWindow * Stopwatch.Frequency); ulong countBegin, countEnd; long timeBegin = Stopwatch.GetTimestamp() + - (long)Math.Ceiling(0.001 * ticks); + (long)Math.Ceiling(0.001 * ticks); long timeEnd = timeBegin + ticks; while (Stopwatch.GetTimestamp() < timeBegin) { } @@ -177,7 +174,7 @@ namespace OpenHardwareMonitor.Hardware.CPU { double delta = (timeEnd - timeBegin); frequency = 1e-6 * - (((double)(countEnd - countBegin)) * Stopwatch.Frequency) / delta; + (((double)(countEnd - countBegin)) * Stopwatch.Frequency) / delta; double beginError = (afterBegin - timeBegin) / delta; double endError = (afterEnd - timeEnd) / delta; @@ -214,23 +211,23 @@ namespace OpenHardwareMonitor.Hardware.CPU { r.AppendLine(); r.AppendFormat("Name: {0}{1}", name, Environment.NewLine); r.AppendFormat("Number of Cores: {0}{1}", coreCount, - Environment.NewLine); + Environment.NewLine); r.AppendFormat("Threads per Core: {0}{1}", cpuid[0].Length, - Environment.NewLine); + Environment.NewLine); r.AppendLine(string.Format(CultureInfo.InvariantCulture, - "Timer Frequency: {0} MHz", Stopwatch.Frequency * 1e-6)); - r.AppendLine("Time Stamp Counter: " + (hasTimeStampCounter ? ( - isInvariantTimeStampCounter ? "Invariant" : "Not Invariant") : "None")); + "Timer Frequency: {0} MHz", Stopwatch.Frequency * 1e-6)); + r.AppendLine("Time Stamp Counter: " + (HasTimeStampCounter ? ( + isInvariantTimeStampCounter ? "Invariant" : "Not Invariant") : "None")); r.AppendLine(string.Format(CultureInfo.InvariantCulture, - "Estimated Time Stamp Counter Frequency: {0} MHz", - Math.Round(estimatedTimeStampCounterFrequency * 100) * 0.01)); + "Estimated Time Stamp Counter Frequency: {0} MHz", + Math.Round(estimatedTimeStampCounterFrequency * 100) * 0.01)); r.AppendLine(string.Format(CultureInfo.InvariantCulture, - "Estimated Time Stamp Counter Frequency Error: {0} Mhz", - Math.Round(estimatedTimeStampCounterFrequency * - estimatedTimeStampCounterFrequencyError * 1e5) * 1e-5)); + "Estimated Time Stamp Counter Frequency Error: {0} Mhz", + Math.Round(estimatedTimeStampCounterFrequency * + estimatedTimeStampCounterFrequencyError * 1e5) * 1e-5)); r.AppendLine(string.Format(CultureInfo.InvariantCulture, - "Time Stamp Counter Frequency: {0} MHz", - Math.Round(timeStampCounterFrequency * 100) * 0.01)); + "Time Stamp Counter Frequency: {0} MHz", + Math.Round(TimeStampCounterFrequency * 100) * 0.01)); r.AppendLine(); uint[] msrArray = GetMSRs(); @@ -248,24 +245,16 @@ namespace OpenHardwareMonitor.Hardware.CPU { return r.ToString(); } - public override HardwareType HardwareType { - get { return HardwareType.CPU; } - } + public override HardwareType HardwareType => HardwareType.CPU; - public bool HasModelSpecificRegisters { - get { return hasModelSpecificRegisters; } - } + public bool HasModelSpecificRegisters { get; } - public bool HasTimeStampCounter { - get { return hasTimeStampCounter; } - } + public bool HasTimeStampCounter { get; } - public double TimeStampCounterFrequency { - get { return timeStampCounterFrequency; } - } + public double TimeStampCounterFrequency { get; private set; } public override void Update() { - if (hasTimeStampCounter && isInvariantTimeStampCounter) { + if (HasTimeStampCounter && isInvariantTimeStampCounter) { // make sure always the same thread is used ulong mask = ThreadAffinity.Set(1UL << cpuid[0][0].Thread); @@ -289,7 +278,7 @@ namespace OpenHardwareMonitor.Hardware.CPU { if (lastTime != 0 && delta > 0.5 && delta < 2) { // update the TSC frequency with the new value - timeStampCounterFrequency = + TimeStampCounterFrequency = (timeStampCount - lastTimeStampCount) / (1e6 * delta); } diff --git a/Hardware/Computer.cs b/Hardware/Computer.cs index c1946b1..0520a4c 100644 --- a/Hardware/Computer.cs +++ b/Hardware/Computer.cs @@ -13,7 +13,6 @@ using System.Collections.Generic; using System.Globalization; using System.IO; using System.Security.Permissions; -using System.Reflection; using System.Net.NetworkInformation; namespace OpenHardwareMonitor.Hardware { diff --git a/Hardware/Control.cs b/Hardware/Control.cs index fc8b769..b46476a 100644 --- a/Hardware/Control.cs +++ b/Hardware/Control.cs @@ -8,7 +8,6 @@ */ -using System; using System.Globalization; namespace OpenHardwareMonitor.Hardware { diff --git a/Hardware/FirmwareTable.cs b/Hardware/FirmwareTable.cs index 21db6f2..79ecb49 100644 --- a/Hardware/FirmwareTable.cs +++ b/Hardware/FirmwareTable.cs @@ -9,7 +9,6 @@ */ using System; -using System.ComponentModel; using System.Runtime.InteropServices; using System.Text; diff --git a/Hardware/HDD/ATAStorage.cs b/Hardware/HDD/ATAStorage.cs index 326ef05..674be59 100644 --- a/Hardware/HDD/ATAStorage.cs +++ b/Hardware/HDD/ATAStorage.cs @@ -8,33 +8,44 @@ using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; +using System.Reflection; using System.Text; using OpenHardwareMonitor.Interop; namespace OpenHardwareMonitor.Hardware.HDD { - internal abstract class ATAStorage : AbstractStorage { + public abstract class ATAStorage : AbstractStorage { // array of all harddrive types, matching type is searched in this order private static readonly Type[] hddTypes = { typeof(SSDPlextor), typeof(SSDIntel), typeof(SSDSandforce), typeof(SSDIndilinx), typeof(SSDSamsung), typeof(SSDMicron), typeof(GenericHarddisk) }; private readonly ISmart smart; - private readonly IList smartAttributes; + private readonly List smartAttributes; private IDictionary sensors; - protected ATAStorage(StorageInfo storageInfo, ISmart smart, string name, string firmwareRevision, string id, int index, IEnumerable smartAttributes, ISettings settings) + /// + /// Gets the SMART data. + /// + public ISmart Smart => smart; + + /// + /// Gets the SMART attributes. + /// + public IReadOnlyList SmartAttributes => smartAttributes; + + internal ATAStorage(StorageInfo storageInfo, ISmart smart, string name, string firmwareRevision, string id, int index, IEnumerable smartAttributes, ISettings settings) : base(storageInfo, name, firmwareRevision, id, index, settings) { this.smart = smart; if (smart.IsValid) smart.EnableSmart(); - + this.smartAttributes = new List(smartAttributes); CreateSensors(); } - public static AbstractStorage CreateInstance(StorageInfo info, ISettings settings) { + internal static AbstractStorage CreateInstance(StorageInfo info, ISettings settings) { ISmart smart = new WindowsSmart(info.Index); string name = null; string firmwareRevision = null; - Kernel32.DriveAttributeValue[] values = { }; + Kernel32.SMART_ATTRIBUTE[] values = { }; if (smart.IsValid) { bool nameValid = smart.ReadNameAndFirmwareRevision(out name, out firmwareRevision); @@ -88,8 +99,8 @@ namespace OpenHardwareMonitor.Hardware.HDD { bool allRequiredAttributesFound = true; foreach (var requireAttribute in requiredAttributes) { bool attributeFound = false; - foreach (Kernel32.DriveAttributeValue value in values) { - if (value.Identifier == requireAttribute.AttributeId) { + foreach (Kernel32.SMART_ATTRIBUTE value in values) { + if (value.Id == requireAttribute.AttributeId) { attributeFound = true; break; } @@ -108,8 +119,10 @@ namespace OpenHardwareMonitor.Hardware.HDD { // check if there is a matching name prefix for this type foreach (NamePrefixAttribute prefix in namePrefixes) { - if (name.StartsWith(prefix.Prefix, StringComparison.InvariantCulture)) - return Activator.CreateInstance(type, info, smart, name, firmwareRevision, info.Index, settings) as ATAStorage; + if (name.StartsWith(prefix.Prefix, StringComparison.InvariantCulture)) { + var flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance; + return Activator.CreateInstance(type, flags, null, new object[] { info, smart, name, firmwareRevision, info.Index, settings }, null) as ATAStorage; + } } } @@ -122,7 +135,7 @@ namespace OpenHardwareMonitor.Hardware.HDD { sensors = new Dictionary(); if (smart.IsValid) { - var smartIds = smart.ReadSmartData().Select(attrValue => attrValue.Identifier); + var smartIds = smart.ReadSmartData().Select(attrValue => attrValue.Id); // unique attributes by SensorType and SensorChannel. var uniqueAttributes = smartAttributes @@ -147,16 +160,16 @@ namespace OpenHardwareMonitor.Hardware.HDD { base.CreateSensors(); } - protected virtual void UpdateAdditionalSensors(Kernel32.DriveAttributeValue[] values) { } + protected virtual void UpdateAdditionalSensors(Kernel32.SMART_ATTRIBUTE[] values) { } protected override void UpdateSensors() { if (smart.IsValid) { - Kernel32.DriveAttributeValue[] values = smart.ReadSmartData(); + Kernel32.SMART_ATTRIBUTE[] values = smart.ReadSmartData(); foreach (KeyValuePair keyValuePair in sensors) { SmartAttribute attribute = keyValuePair.Key; - foreach (Kernel32.DriveAttributeValue value in values) { - if (value.Identifier == attribute.Identifier) { + foreach (Kernel32.SMART_ATTRIBUTE value in values) { + if (value.Id == attribute.Identifier) { Sensor sensor = keyValuePair.Value; sensor.Value = attribute.ConvertValue(value, sensor.Parameters); } @@ -169,8 +182,8 @@ namespace OpenHardwareMonitor.Hardware.HDD { protected override void GetReport(StringBuilder r) { if (smart.IsValid) { - Kernel32.DriveAttributeValue[] values = smart.ReadSmartData(); - Kernel32.DriveThresholdValue[] thresholds = smart.ReadSmartThresholds(); + Kernel32.SMART_ATTRIBUTE[] values = smart.ReadSmartData(); + Kernel32.SMART_THRESHOLD[] thresholds = smart.ReadSmartThresholds(); if (values.Length > 0) { r.AppendFormat(CultureInfo.InvariantCulture, @@ -184,14 +197,14 @@ namespace OpenHardwareMonitor.Hardware.HDD { "Physical".PadRight(8), Environment.NewLine); - foreach (Kernel32.DriveAttributeValue value in values) { - if (value.Identifier == 0x00) + foreach (Kernel32.SMART_ATTRIBUTE value in values) { + if (value.Id == 0x00) break; byte? threshold = null; - foreach (Kernel32.DriveThresholdValue t in thresholds) { - if (t.Identifier == value.Identifier) { + foreach (Kernel32.SMART_THRESHOLD t in thresholds) { + if (t.Id == value.Id) { threshold = t.Threshold; } } @@ -199,7 +212,7 @@ namespace OpenHardwareMonitor.Hardware.HDD { string description = "Unknown"; float? physical = null; foreach (SmartAttribute a in smartAttributes) { - if (a.Identifier == value.Identifier) { + if (a.Identifier == value.Id) { description = a.Name; if (a.HasRawValueConversion | a.SensorType.HasValue) physical = a.ConvertValue(value, null); @@ -211,11 +224,11 @@ namespace OpenHardwareMonitor.Hardware.HDD { string raw = BitConverter.ToString(value.RawValue); r.AppendFormat(CultureInfo.InvariantCulture, " {0}{1}{2}{3}{4}{5}{6}{7}", - value.Identifier.ToString("X2").PadRight(3), + value.Id.ToString("X2").PadRight(3), description.PadRight(35), raw.Replace("-", "").PadRight(13), value.WorstValue.ToString(CultureInfo.InvariantCulture).PadRight(6), - value.AttrValue.ToString(CultureInfo.InvariantCulture).PadRight(6), + value.CurrentValue.ToString(CultureInfo.InvariantCulture).PadRight(6), (threshold.HasValue ? threshold.Value.ToString(CultureInfo.InvariantCulture) : "-").PadRight(6), diff --git a/Hardware/HDD/AbstractStorage.cs b/Hardware/HDD/AbstractStorage.cs index da1fc61..c6061dc 100644 --- a/Hardware/HDD/AbstractStorage.cs +++ b/Hardware/HDD/AbstractStorage.cs @@ -13,7 +13,7 @@ using System.Text; using OpenHardwareMonitor.Interop; namespace OpenHardwareMonitor.Hardware.HDD { - internal abstract class AbstractStorage : Hardware { + public abstract class AbstractStorage : Hardware { private readonly PerformanceValue perfTotal = new PerformanceValue(); private readonly PerformanceValue perfWrite = new PerformanceValue(); private readonly StorageInfo storageInfo; @@ -30,7 +30,7 @@ namespace OpenHardwareMonitor.Hardware.HDD { private Sensor usageSensor; private ulong writeRateCounterlast; - protected AbstractStorage(StorageInfo storageInfo, string name, string firmwareRevision, string id, int index, ISettings settings) + internal AbstractStorage(StorageInfo storageInfo, string name, string firmwareRevision, string id, int index, ISettings settings) : base(name, new Identifier(id, index.ToString(CultureInfo.InvariantCulture)), settings) { this.storageInfo = storageInfo; FirmwareRevision = firmwareRevision; @@ -51,11 +51,11 @@ namespace OpenHardwareMonitor.Hardware.HDD { public DriveInfo[] DriveInfos { get; } - public string FirmwareRevision { get; set; } + public string FirmwareRevision { get; } public override HardwareType HardwareType => HardwareType.HDD; - public int Index { get; set; } + public int Index { get; } public static AbstractStorage CreateInstance(string deviceId, uint driveNumber, ulong diskSize, int scsiPort, ISettings settings) { StorageInfo info = WindowsStorage.GetStorageInfo(deviceId, driveNumber); @@ -63,21 +63,21 @@ namespace OpenHardwareMonitor.Hardware.HDD { info.DeviceId = deviceId; info.Scsi = $@"\\.\SCSI{scsiPort}:"; - if (info.Removable || info.BusType == Kernel32.StorageBusType.BusTypeVirtual || info.BusType == Kernel32.StorageBusType.BusTypeFileBackedVirtual) + if (info.Removable || info.BusType == Kernel32.STORAGE_BUS_TYPE.BusTypeVirtual || info.BusType == Kernel32.STORAGE_BUS_TYPE.BusTypeFileBackedVirtual) return null; //fallback, when it is not possible to read out with the nvme implementation, //try it with the sata smart implementation - if (info.BusType == Kernel32.StorageBusType.BusTypeNvme) { + if (info.BusType == Kernel32.STORAGE_BUS_TYPE.BusTypeNvme) { var x = NVMeGeneric.CreateInstance(info, settings); if (x != null) return x; } - if (info.BusType == Kernel32.StorageBusType.BusTypeAta || - info.BusType == Kernel32.StorageBusType.BusTypeSata || - info.BusType == Kernel32.StorageBusType.BusTypeNvme) { + if (info.BusType == Kernel32.STORAGE_BUS_TYPE.BusTypeAta || + info.BusType == Kernel32.STORAGE_BUS_TYPE.BusTypeSata || + info.BusType == Kernel32.STORAGE_BUS_TYPE.BusTypeNvme) { return ATAStorage.CreateInstance(info, settings); } diff --git a/Hardware/HDD/DebugSmart.cs b/Hardware/HDD/DebugSmart.cs index 473cd9c..22e0abe 100644 --- a/Hardware/HDD/DebugSmart.cs +++ b/Hardware/HDD/DebugSmart.cs @@ -361,7 +361,7 @@ namespace OpenHardwareMonitor.Hardware.HDD { return true; } - public Kernel32.DriveAttributeValue[] ReadSmartData() { + public Kernel32.SMART_ATTRIBUTE[] ReadSmartData() { if (driveNumber < 0) throw new ObjectDisposedException(nameof(DebugSmart)); @@ -369,7 +369,7 @@ namespace OpenHardwareMonitor.Hardware.HDD { return drives[driveNumber].DriveAttributeValues; } - public Kernel32.DriveThresholdValue[] ReadSmartThresholds() { + public Kernel32.SMART_THRESHOLD[] ReadSmartThresholds() { if (driveNumber < 0) throw new ObjectDisposedException(nameof(DebugSmart)); @@ -404,8 +404,8 @@ namespace OpenHardwareMonitor.Hardware.HDD { string[] lines = value.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); - DriveAttributeValues = new Kernel32.DriveAttributeValue[lines.Length]; - var thresholds = new List(); + DriveAttributeValues = new Kernel32.SMART_ATTRIBUTE[lines.Length]; + var thresholds = new List(); for (int i = 0; i < lines.Length; i++) { string[] array = lines[i].Split(new[] { ' ' }, @@ -415,19 +415,19 @@ namespace OpenHardwareMonitor.Hardware.HDD { throw new Exception(); - var v = new Kernel32.DriveAttributeValue { Identifier = Convert.ToByte(array[0], idBase), RawValue = new byte[6] }; + var v = new Kernel32.SMART_ATTRIBUTE { Id = Convert.ToByte(array[0], idBase), RawValue = new byte[6] }; for (int j = 0; j < 6; j++) { v.RawValue[j] = Convert.ToByte(array[1].Substring(2 * j, 2), 16); } v.WorstValue = Convert.ToByte(array[2], 10); - v.AttrValue = Convert.ToByte(array[3], 10); + v.CurrentValue = Convert.ToByte(array[3], 10); DriveAttributeValues[i] = v; if (array.Length == 5) { - var t = new Kernel32.DriveThresholdValue { Identifier = v.Identifier, Threshold = Convert.ToByte(array[4], 10) }; + var t = new Kernel32.SMART_THRESHOLD { Id = v.Id, Threshold = Convert.ToByte(array[4], 10) }; thresholds.Add(t); } } @@ -435,9 +435,9 @@ namespace OpenHardwareMonitor.Hardware.HDD { DriveThresholdValues = thresholds.ToArray(); } - public Kernel32.DriveAttributeValue[] DriveAttributeValues { get; } + public Kernel32.SMART_ATTRIBUTE[] DriveAttributeValues { get; } - public Kernel32.DriveThresholdValue[] DriveThresholdValues { get; } + public Kernel32.SMART_THRESHOLD[] DriveThresholdValues { get; } public string FirmwareVersion { get; } diff --git a/Hardware/HDD/HDDGeneric.cs b/Hardware/HDD/GenericHarddisk.cs similarity index 94% rename from Hardware/HDD/HDDGeneric.cs rename to Hardware/HDD/GenericHarddisk.cs index 52a8efb..e5982c1 100644 --- a/Hardware/HDD/HDDGeneric.cs +++ b/Hardware/HDD/GenericHarddisk.cs @@ -1,119 +1,119 @@ -// Mozilla Public License 2.0 -// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. -// Copyright (C) LibreHardwareMonitor and Contributors -// All Rights Reserved - -using System.Collections.Generic; - -namespace OpenHardwareMonitor.Hardware.HDD { - [NamePrefix("")] - internal class GenericHarddisk : ATAStorage { - private static readonly List smartAttributes = - new List { - new SmartAttribute(0x01, SmartNames.ReadErrorRate), - new SmartAttribute(0x02, SmartNames.ThroughputPerformance), - new SmartAttribute(0x03, SmartNames.SpinUpTime), - new SmartAttribute(0x04, SmartNames.StartStopCount, RawToInt), - new SmartAttribute(0x05, SmartNames.ReallocatedSectorsCount), - new SmartAttribute(0x06, SmartNames.ReadChannelMargin), - new SmartAttribute(0x07, SmartNames.SeekErrorRate), - new SmartAttribute(0x08, SmartNames.SeekTimePerformance), - new SmartAttribute(0x09, SmartNames.PowerOnHours, RawToInt), - new SmartAttribute(0x0A, SmartNames.SpinRetryCount), - new SmartAttribute(0x0B, SmartNames.RecalibrationRetries), - new SmartAttribute(0x0C, SmartNames.PowerCycleCount, RawToInt), - new SmartAttribute(0x0D, SmartNames.SoftReadErrorRate), - new SmartAttribute(0xAA, SmartNames.Unknown), - new SmartAttribute(0xAB, SmartNames.Unknown), - new SmartAttribute(0xAC, SmartNames.Unknown), - new SmartAttribute(0xB7, SmartNames.SataDownshiftErrorCount, RawToInt), - new SmartAttribute(0xB8, SmartNames.EndToEndError), - new SmartAttribute(0xB9, SmartNames.HeadStability), - new SmartAttribute(0xBA, SmartNames.InducedOpVibrationDetection), - new SmartAttribute(0xBB, SmartNames.ReportedUncorrectableErrors, RawToInt), - new SmartAttribute(0xBC, SmartNames.CommandTimeout, RawToInt), - new SmartAttribute(0xBD, SmartNames.HighFlyWrites), - new SmartAttribute(0xBF, SmartNames.GSenseErrorRate), - new SmartAttribute(0xC0, SmartNames.EmergencyRetractCycleCount), - new SmartAttribute(0xC1, SmartNames.LoadCycleCount), - new SmartAttribute(0xC3, SmartNames.HardwareEccRecovered), - new SmartAttribute(0xC4, SmartNames.ReallocationEventCount), - new SmartAttribute(0xC5, SmartNames.CurrentPendingSectorCount), - new SmartAttribute(0xC6, SmartNames.UncorrectableSectorCount), - new SmartAttribute(0xC7, SmartNames.UltraDmaCrcErrorCount), - new SmartAttribute(0xC8, SmartNames.WriteErrorRate), - new SmartAttribute(0xCA, SmartNames.DataAddressMarkErrors), - new SmartAttribute(0xCB, SmartNames.RunOutCancel), - new SmartAttribute(0xCC, SmartNames.SoftEccCorrection), - new SmartAttribute(0xCD, SmartNames.ThermalAsperityRate), - new SmartAttribute(0xCE, SmartNames.FlyingHeight), - new SmartAttribute(0xCF, SmartNames.SpinHighCurrent), - new SmartAttribute(0xD0, SmartNames.SpinBuzz), - new SmartAttribute(0xD1, SmartNames.OfflineSeekPerformance), - new SmartAttribute(0xD3, SmartNames.VibrationDuringWrite), - new SmartAttribute(0xD4, SmartNames.ShockDuringWrite), - new SmartAttribute(0xDC, SmartNames.DiskShift), - new SmartAttribute(0xDD, SmartNames.AlternativeGSenseErrorRate), - new SmartAttribute(0xDE, SmartNames.LoadedHours), - new SmartAttribute(0xDF, SmartNames.LoadUnloadRetryCount), - new SmartAttribute(0xE0, SmartNames.LoadFriction), - new SmartAttribute(0xE1, SmartNames.LoadUnloadCycleCount), - new SmartAttribute(0xE2, SmartNames.LoadInTime), - new SmartAttribute(0xE3, SmartNames.TorqueAmplificationCount), - new SmartAttribute(0xE4, SmartNames.PowerOffRetractCycle), - new SmartAttribute(0xE6, SmartNames.GmrHeadAmplitude), - new SmartAttribute(0xE8, SmartNames.EnduranceRemaining), - new SmartAttribute(0xE9, SmartNames.PowerOnHours), - new SmartAttribute(0xF0, SmartNames.HeadFlyingHours), - new SmartAttribute(0xF1, SmartNames.TotalLbasWritten), - new SmartAttribute(0xF2, SmartNames.TotalLbasRead), - new SmartAttribute(0xFA, SmartNames.ReadErrorRetryRate), - new SmartAttribute(0xFE, SmartNames.FreeFallProtection), - new SmartAttribute(0xC2, - SmartNames.Temperature, - (r, v, p) - => r[0] + (p?[0].Value ?? 0), - SensorType.Temperature, - 0, - SmartNames.Temperature, - false, - new[] { - new ParameterDescription("Offset [°C]", - "Temperature offset of the thermal sensor.\n" + - "Temperature = Value + Offset.", - 0) - }), - new SmartAttribute(0xE7, - SmartNames.Temperature, - (r, v, p) - => r[0] + (p?[0].Value ?? 0), - SensorType.Temperature, - 0, - SmartNames.Temperature, - false, - new[] { - new ParameterDescription("Offset [°C]", - "Temperature offset of the thermal sensor.\n" + - "Temperature = Value + Offset.", - 0) - }), - new SmartAttribute(0xBE, - SmartNames.TemperatureDifferenceFrom100, - (r, v, p) - => r[0] + (p?[0].Value ?? 0), - SensorType.Temperature, - 0, - "Temperature", - false, - new[] { - new ParameterDescription("Offset [°C]", - "Temperature offset of the thermal sensor.\n" + - "Temperature = Value + Offset.", - 0) - }) - }; - - public GenericHarddisk(StorageInfo _storageInfo, ISmart smart, string name, string firmwareRevision, int index, ISettings settings) - : base(_storageInfo, smart, name, firmwareRevision, "hdd", index, smartAttributes, settings) { } - } +// Mozilla Public License 2.0 +// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// Copyright (C) LibreHardwareMonitor and Contributors +// All Rights Reserved + +using System.Collections.Generic; + +namespace OpenHardwareMonitor.Hardware.HDD { + [NamePrefix("")] + public class GenericHarddisk : ATAStorage { + private static readonly List smartAttributes = + new List { + new SmartAttribute(0x01, SmartNames.ReadErrorRate), + new SmartAttribute(0x02, SmartNames.ThroughputPerformance), + new SmartAttribute(0x03, SmartNames.SpinUpTime), + new SmartAttribute(0x04, SmartNames.StartStopCount, RawToInt), + new SmartAttribute(0x05, SmartNames.ReallocatedSectorsCount), + new SmartAttribute(0x06, SmartNames.ReadChannelMargin), + new SmartAttribute(0x07, SmartNames.SeekErrorRate), + new SmartAttribute(0x08, SmartNames.SeekTimePerformance), + new SmartAttribute(0x09, SmartNames.PowerOnHours, RawToInt), + new SmartAttribute(0x0A, SmartNames.SpinRetryCount), + new SmartAttribute(0x0B, SmartNames.RecalibrationRetries), + new SmartAttribute(0x0C, SmartNames.PowerCycleCount, RawToInt), + new SmartAttribute(0x0D, SmartNames.SoftReadErrorRate), + new SmartAttribute(0xAA, SmartNames.Unknown), + new SmartAttribute(0xAB, SmartNames.Unknown), + new SmartAttribute(0xAC, SmartNames.Unknown), + new SmartAttribute(0xB7, SmartNames.SataDownshiftErrorCount, RawToInt), + new SmartAttribute(0xB8, SmartNames.EndToEndError), + new SmartAttribute(0xB9, SmartNames.HeadStability), + new SmartAttribute(0xBA, SmartNames.InducedOpVibrationDetection), + new SmartAttribute(0xBB, SmartNames.ReportedUncorrectableErrors, RawToInt), + new SmartAttribute(0xBC, SmartNames.CommandTimeout, RawToInt), + new SmartAttribute(0xBD, SmartNames.HighFlyWrites), + new SmartAttribute(0xBF, SmartNames.GSenseErrorRate), + new SmartAttribute(0xC0, SmartNames.EmergencyRetractCycleCount), + new SmartAttribute(0xC1, SmartNames.LoadCycleCount), + new SmartAttribute(0xC3, SmartNames.HardwareEccRecovered), + new SmartAttribute(0xC4, SmartNames.ReallocationEventCount), + new SmartAttribute(0xC5, SmartNames.CurrentPendingSectorCount), + new SmartAttribute(0xC6, SmartNames.UncorrectableSectorCount), + new SmartAttribute(0xC7, SmartNames.UltraDmaCrcErrorCount), + new SmartAttribute(0xC8, SmartNames.WriteErrorRate), + new SmartAttribute(0xCA, SmartNames.DataAddressMarkErrors), + new SmartAttribute(0xCB, SmartNames.RunOutCancel), + new SmartAttribute(0xCC, SmartNames.SoftEccCorrection), + new SmartAttribute(0xCD, SmartNames.ThermalAsperityRate), + new SmartAttribute(0xCE, SmartNames.FlyingHeight), + new SmartAttribute(0xCF, SmartNames.SpinHighCurrent), + new SmartAttribute(0xD0, SmartNames.SpinBuzz), + new SmartAttribute(0xD1, SmartNames.OfflineSeekPerformance), + new SmartAttribute(0xD3, SmartNames.VibrationDuringWrite), + new SmartAttribute(0xD4, SmartNames.ShockDuringWrite), + new SmartAttribute(0xDC, SmartNames.DiskShift), + new SmartAttribute(0xDD, SmartNames.AlternativeGSenseErrorRate), + new SmartAttribute(0xDE, SmartNames.LoadedHours), + new SmartAttribute(0xDF, SmartNames.LoadUnloadRetryCount), + new SmartAttribute(0xE0, SmartNames.LoadFriction), + new SmartAttribute(0xE1, SmartNames.LoadUnloadCycleCount), + new SmartAttribute(0xE2, SmartNames.LoadInTime), + new SmartAttribute(0xE3, SmartNames.TorqueAmplificationCount), + new SmartAttribute(0xE4, SmartNames.PowerOffRetractCycle), + new SmartAttribute(0xE6, SmartNames.GmrHeadAmplitude), + new SmartAttribute(0xE8, SmartNames.EnduranceRemaining), + new SmartAttribute(0xE9, SmartNames.PowerOnHours), + new SmartAttribute(0xF0, SmartNames.HeadFlyingHours), + new SmartAttribute(0xF1, SmartNames.TotalLbasWritten), + new SmartAttribute(0xF2, SmartNames.TotalLbasRead), + new SmartAttribute(0xFA, SmartNames.ReadErrorRetryRate), + new SmartAttribute(0xFE, SmartNames.FreeFallProtection), + new SmartAttribute(0xC2, + SmartNames.Temperature, + (r, v, p) + => r[0] + (p?[0].Value ?? 0), + SensorType.Temperature, + 0, + SmartNames.Temperature, + false, + new[] { + new ParameterDescription("Offset [°C]", + "Temperature offset of the thermal sensor.\n" + + "Temperature = Value + Offset.", + 0) + }), + new SmartAttribute(0xE7, + SmartNames.Temperature, + (r, v, p) + => r[0] + (p?[0].Value ?? 0), + SensorType.Temperature, + 0, + SmartNames.Temperature, + false, + new[] { + new ParameterDescription("Offset [°C]", + "Temperature offset of the thermal sensor.\n" + + "Temperature = Value + Offset.", + 0) + }), + new SmartAttribute(0xBE, + SmartNames.TemperatureDifferenceFrom100, + (r, v, p) + => r[0] + (p?[0].Value ?? 0), + SensorType.Temperature, + 0, + "Temperature", + false, + new[] { + new ParameterDescription("Offset [°C]", + "Temperature offset of the thermal sensor.\n" + + "Temperature = Value + Offset.", + 0) + }) + }; + + internal GenericHarddisk(StorageInfo storageInfo, ISmart smart, string name, string firmwareRevision, int index, ISettings settings) + : base(storageInfo, smart, name, firmwareRevision, "hdd", index, smartAttributes, settings) { } + } } \ No newline at end of file diff --git a/Hardware/HDD/INVMeDrive.cs b/Hardware/HDD/INVMeDrive.cs index dba8624..5fd9682 100644 --- a/Hardware/HDD/INVMeDrive.cs +++ b/Hardware/HDD/INVMeDrive.cs @@ -10,8 +10,8 @@ namespace OpenHardwareMonitor.Hardware.HDD { internal interface INVMeDrive { SafeHandle Identify(StorageInfo storageInfo); - bool IdentifyController(SafeHandle hDevice, out Kernel32.NVMeIdentifyControllerData data); + bool IdentifyController(SafeHandle hDevice, out Kernel32.NVME_IDENTIFY_CONTROLLER_DATA data); - bool HealthInfoLog(SafeHandle hDevice, out Kernel32.NVMeHealthInfoLog data); + bool HealthInfoLog(SafeHandle hDevice, out Kernel32.NVME_HEALTH_INFO_LOG data); } } \ No newline at end of file diff --git a/Hardware/HDD/ISmart.cs b/Hardware/HDD/ISmart.cs index 4839322..ad29000 100644 --- a/Hardware/HDD/ISmart.cs +++ b/Hardware/HDD/ISmart.cs @@ -7,16 +7,16 @@ using System; using OpenHardwareMonitor.Interop; namespace OpenHardwareMonitor.Hardware.HDD { - internal interface ISmart : IDisposable { + public interface ISmart : IDisposable { bool IsValid { get; } void Close(); bool EnableSmart(); - Kernel32.DriveAttributeValue[] ReadSmartData(); + Kernel32.SMART_ATTRIBUTE[] ReadSmartData(); - Kernel32.DriveThresholdValue[] ReadSmartThresholds(); + Kernel32.SMART_THRESHOLD[] ReadSmartThresholds(); bool ReadNameAndFirmwareRevision(out string name, out string firmwareRevision); } diff --git a/Hardware/HDD/NVMeGeneric.cs b/Hardware/HDD/NVMeGeneric.cs index 2e041e2..99bbc6e 100644 --- a/Hardware/HDD/NVMeGeneric.cs +++ b/Hardware/HDD/NVMeGeneric.cs @@ -8,7 +8,7 @@ using System.Text; using OpenHardwareMonitor.Interop; namespace OpenHardwareMonitor.Hardware.HDD { - internal sealed class NVMeGeneric : AbstractStorage { + public sealed class NVMeGeneric : AbstractStorage { private const ulong Scale = 1000000; private const ulong Units = 512; @@ -16,6 +16,11 @@ namespace OpenHardwareMonitor.Hardware.HDD { private readonly List sensors = new List(); private readonly NVMeSmart smart; + /// + /// Gets the SMART data. + /// + public NVMeSmart Smart => smart; + private NVMeGeneric(StorageInfo storageInfo, NVMeInfo info, int index, ISettings settings) : base(storageInfo, info.Model, info.Revision, "nvme", index, settings) { smart = new NVMeSmart(storageInfo); @@ -29,7 +34,7 @@ namespace OpenHardwareMonitor.Hardware.HDD { return info; } - public static AbstractStorage CreateInstance(StorageInfo storageInfo, ISettings settings) { + internal static AbstractStorage CreateInstance(StorageInfo storageInfo, ISettings settings) { NVMeInfo nvmeInfo = GetDeviceInfo(storageInfo); return nvmeInfo == null ? null : new NVMeGeneric(storageInfo, nvmeInfo, storageInfo.Index, settings); } @@ -95,22 +100,22 @@ namespace OpenHardwareMonitor.Hardware.HDD { return; - if (health.CriticalWarning == Kernel32.NVMeCriticalWarning.None) + if (health.CriticalWarning == Kernel32.NVME_CRITICAL_WARNING.None) r.AppendLine("Critical Warning: -"); else { - if ((health.CriticalWarning & Kernel32.NVMeCriticalWarning.AvailableSpaceLow) != 0) + if ((health.CriticalWarning & Kernel32.NVME_CRITICAL_WARNING.AvailableSpaceLow) != 0) r.AppendLine("Critical Warning: the available spare space has fallen below the threshold."); - if ((health.CriticalWarning & Kernel32.NVMeCriticalWarning.TemperatureThreshold) != 0) + if ((health.CriticalWarning & Kernel32.NVME_CRITICAL_WARNING.TemperatureThreshold) != 0) r.AppendLine("Critical Warning: a temperature is above an over temperature threshold or below an under temperature threshold."); - if ((health.CriticalWarning & Kernel32.NVMeCriticalWarning.ReliabilityDegraded) != 0) + if ((health.CriticalWarning & Kernel32.NVME_CRITICAL_WARNING.ReliabilityDegraded) != 0) r.AppendLine("Critical Warning: the device reliability has been degraded due to significant media related errors or any internal error that degrades device reliability."); - if ((health.CriticalWarning & Kernel32.NVMeCriticalWarning.ReadOnly) != 0) + if ((health.CriticalWarning & Kernel32.NVME_CRITICAL_WARNING.ReadOnly) != 0) r.AppendLine("Critical Warning: the media has been placed in read only mode."); - if ((health.CriticalWarning & Kernel32.NVMeCriticalWarning.VolatileMemoryBackupDeviceFailed) != 0) + if ((health.CriticalWarning & Kernel32.NVME_CRITICAL_WARNING.VolatileMemoryBackupDeviceFailed) != 0) r.AppendLine("Critical Warning: the volatile memory backup device has failed."); } diff --git a/Hardware/HDD/NVMeHealthInfo.cs b/Hardware/HDD/NVMeHealthInfo.cs index 005a9ea..86645ba 100644 --- a/Hardware/HDD/NVMeHealthInfo.cs +++ b/Hardware/HDD/NVMeHealthInfo.cs @@ -6,7 +6,7 @@ using OpenHardwareMonitor.Interop; namespace OpenHardwareMonitor.Hardware.HDD { - internal abstract class NVMeHealthInfo { + public abstract class NVMeHealthInfo { public byte AvailableSpare { get; protected set; } public byte AvailableSpareThreshold { get; protected set; } @@ -15,7 +15,7 @@ namespace OpenHardwareMonitor.Hardware.HDD { public uint CriticalCompositeTemperatureTime { get; protected set; } - public Kernel32.NVMeCriticalWarning CriticalWarning { get; protected set; } + public Kernel32.NVME_CRITICAL_WARNING CriticalWarning { get; protected set; } public ulong DataUnitRead { get; protected set; } diff --git a/Hardware/HDD/NVMeInfo.cs b/Hardware/HDD/NVMeInfo.cs index 5db6d2c..617862b 100644 --- a/Hardware/HDD/NVMeInfo.cs +++ b/Hardware/HDD/NVMeInfo.cs @@ -4,7 +4,7 @@ // All Rights Reserved namespace OpenHardwareMonitor.Hardware.HDD { - internal abstract class NVMeInfo { + public abstract class NVMeInfo { public ushort ControllerId { get; protected set; } public byte[] IEEE { get; protected set; } diff --git a/Hardware/HDD/NVMeIntel.cs b/Hardware/HDD/NVMeIntel.cs index 01cc9dd..4284f89 100644 --- a/Hardware/HDD/NVMeIntel.cs +++ b/Hardware/HDD/NVMeIntel.cs @@ -16,8 +16,8 @@ namespace OpenHardwareMonitor.Hardware.HDD { return NVMeWindows.IdentifyDevice(storageInfo); } - public bool IdentifyController(SafeHandle hDevice, out Kernel32.NVMeIdentifyControllerData data) { - data = Kernel32.CreateStruct(); + public bool IdentifyController(SafeHandle hDevice, out Kernel32.NVME_IDENTIFY_CONTROLLER_DATA data) { + data = Kernel32.CreateStruct(); if (hDevice == null || hDevice.IsInvalid) return false; @@ -25,38 +25,38 @@ namespace OpenHardwareMonitor.Hardware.HDD { bool result = false; IntPtr buffer; - Kernel32.NVMePassThrough passThrough = Kernel32.CreateStruct(); - passThrough.srb.HeaderLenght = (uint) Marshal.SizeOf(); + Kernel32.NVME_PASS_THROUGH_IOCTL passThrough = Kernel32.CreateStruct(); + passThrough.srb.HeaderLenght = (uint) Marshal.SizeOf(); passThrough.srb.Signature = Encoding.ASCII.GetBytes(Kernel32.IntelNVMeMiniPortSignature1); passThrough.srb.Timeout = 10; passThrough.srb.ControlCode = Kernel32.NVMePassThroughSrbIoCode; passThrough.srb.ReturnCode = 0; - passThrough.srb.Length = (uint) Marshal.SizeOf() - (uint) Marshal.SizeOf(); + passThrough.srb.Length = (uint) Marshal.SizeOf() - (uint) Marshal.SizeOf(); passThrough.NVMeCmd = new uint[16]; passThrough.NVMeCmd[0] = 6; //identify passThrough.NVMeCmd[10] = 1; //return to host - passThrough.Direction = Kernel32.NVMePassThroughDirection.In; - passThrough.Queue = Kernel32.NVMePassThroughQueue.AdminQ; - passThrough.DataBufferLen = (uint) passThrough.DataBuf.Length; + passThrough.Direction = Kernel32.NVME_DIRECTION.NVME_FROM_DEV_TO_HOST; + passThrough.QueueId = 0; + passThrough.DataBufferLen = (uint) passThrough.DataBuffer.Length; passThrough.MetaDataLen = 0; - passThrough.ReturnBufferLen = (uint) Marshal.SizeOf(); + passThrough.ReturnBufferLen = (uint) Marshal.SizeOf(); - var length = Marshal.SizeOf(); + var length = Marshal.SizeOf(); buffer = Marshal.AllocHGlobal(length); Marshal.StructureToPtr(passThrough, buffer, false); - var validTransfer = Kernel32.DeviceIoControl(hDevice, Kernel32.Command.IOCTL_SCSI_MINIPORT, buffer, length, buffer, length, out _, IntPtr.Zero); + var validTransfer = Kernel32.DeviceIoControl(hDevice, Kernel32.IOCTL.IOCTL_SCSI_MINIPORT, buffer, length, buffer, length, out _, IntPtr.Zero); if (validTransfer) { - var offset = Marshal.OffsetOf(nameof(Kernel32.NVMePassThrough.DataBuf)); + var offset = Marshal.OffsetOf(nameof(Kernel32.NVME_PASS_THROUGH_IOCTL.DataBuffer)); var newPtr = IntPtr.Add(buffer, offset.ToInt32()); - int finalSize = Marshal.SizeOf(); - var ptr = Marshal.AllocHGlobal(Marshal.SizeOf()); + int finalSize = Marshal.SizeOf(); + var ptr = Marshal.AllocHGlobal(Marshal.SizeOf()); Kernel32.RtlZeroMemory(ptr, finalSize); - int len = Math.Min(finalSize, passThrough.DataBuf.Length); + int len = Math.Min(finalSize, passThrough.DataBuffer.Length); Kernel32.CopyMemory(ptr, newPtr, (uint) len); Marshal.FreeHGlobal(buffer); - var item = Marshal.PtrToStructure(ptr); + var item = Marshal.PtrToStructure(ptr); data = item; Marshal.FreeHGlobal(ptr); result = true; @@ -67,40 +67,39 @@ namespace OpenHardwareMonitor.Hardware.HDD { return result; } - public bool HealthInfoLog(SafeHandle hDevice, out Kernel32.NVMeHealthInfoLog data) { - data = Kernel32.CreateStruct(); + public bool HealthInfoLog(SafeHandle hDevice, out Kernel32.NVME_HEALTH_INFO_LOG data) { + data = Kernel32.CreateStruct(); if (hDevice == null || hDevice.IsInvalid) return false; bool result = false; - IntPtr buffer; - Kernel32.NVMePassThrough passThrough = Kernel32.CreateStruct(); - passThrough.srb.HeaderLenght = (uint) Marshal.SizeOf(); + Kernel32.NVME_PASS_THROUGH_IOCTL passThrough = Kernel32.CreateStruct(); + passThrough.srb.HeaderLenght = (uint) Marshal.SizeOf(); passThrough.srb.Signature = Encoding.ASCII.GetBytes(Kernel32.IntelNVMeMiniPortSignature1); passThrough.srb.Timeout = 10; passThrough.srb.ControlCode = Kernel32.NVMePassThroughSrbIoCode; passThrough.srb.ReturnCode = 0; - passThrough.srb.Length = (uint) Marshal.SizeOf() - (uint) Marshal.SizeOf(); - passThrough.NVMeCmd[0] = (uint) Kernel32.StorageProtocolNVMeDataType.NVMeDataTypeLogPage; // GetLogPage + passThrough.srb.Length = (uint) Marshal.SizeOf() - (uint) Marshal.SizeOf(); + passThrough.NVMeCmd[0] = (uint) Kernel32.STORAGE_PROTOCOL_NVME_DATA_TYPE.NVMeDataTypeLogPage; // GetLogPage passThrough.NVMeCmd[1] = 0xFFFFFFFF; // address passThrough.NVMeCmd[10] = 0x007f0002; // uint cdw10 = 0x000000002 | (((size / 4) - 1) << 16); - passThrough.Direction = Kernel32.NVMePassThroughDirection.In; - passThrough.Queue = Kernel32.NVMePassThroughQueue.AdminQ; - passThrough.DataBufferLen = (uint) passThrough.DataBuf.Length; + passThrough.Direction = Kernel32.NVME_DIRECTION.NVME_FROM_DEV_TO_HOST; + passThrough.QueueId = 0; + passThrough.DataBufferLen = (uint) passThrough.DataBuffer.Length; passThrough.MetaDataLen = 0; - passThrough.ReturnBufferLen = (uint) Marshal.SizeOf(); + passThrough.ReturnBufferLen = (uint) Marshal.SizeOf(); - var length = Marshal.SizeOf(); - buffer = Marshal.AllocHGlobal(length); + var length = Marshal.SizeOf(); + var buffer = Marshal.AllocHGlobal(length); Marshal.StructureToPtr(passThrough, buffer, false); - var validTransfer = Kernel32.DeviceIoControl(hDevice, Kernel32.Command.IOCTL_SCSI_MINIPORT, buffer, length, buffer, length, out _, IntPtr.Zero); + var validTransfer = Kernel32.DeviceIoControl(hDevice, Kernel32.IOCTL.IOCTL_SCSI_MINIPORT, buffer, length, buffer, length, out _, IntPtr.Zero); if (validTransfer) { - var offset = Marshal.OffsetOf(nameof(Kernel32.NVMePassThrough.DataBuf)); + var offset = Marshal.OffsetOf(nameof(Kernel32.NVME_PASS_THROUGH_IOCTL.DataBuffer)); var newPtr = IntPtr.Add(buffer, offset.ToInt32()); - var item = Marshal.PtrToStructure(newPtr); + var item = Marshal.PtrToStructure(newPtr); data = item; Marshal.FreeHGlobal(buffer); result = true; @@ -120,27 +119,27 @@ namespace OpenHardwareMonitor.Hardware.HDD { bool validTransfer; IntPtr buffer; - Kernel32.NVMePassThrough passThrough = Kernel32.CreateStruct(); - passThrough.srb.HeaderLenght = (uint) Marshal.SizeOf(); + Kernel32.NVME_PASS_THROUGH_IOCTL passThrough = Kernel32.CreateStruct(); + passThrough.srb.HeaderLenght = (uint) Marshal.SizeOf(); passThrough.srb.Signature = Encoding.ASCII.GetBytes(Kernel32.IntelNVMeMiniPortSignature1); passThrough.srb.Timeout = 10; passThrough.srb.ControlCode = Kernel32.NVMePassThroughSrbIoCode; passThrough.srb.ReturnCode = 0; - passThrough.srb.Length = (uint) Marshal.SizeOf() - (uint) Marshal.SizeOf(); + passThrough.srb.Length = (uint) Marshal.SizeOf() - (uint) Marshal.SizeOf(); passThrough.NVMeCmd = new uint[16]; passThrough.NVMeCmd[0] = 6; //identify passThrough.NVMeCmd[10] = 1; //return to host - passThrough.Direction = Kernel32.NVMePassThroughDirection.In; - passThrough.Queue = Kernel32.NVMePassThroughQueue.AdminQ; - passThrough.DataBufferLen = (uint) passThrough.DataBuf.Length; + passThrough.Direction = Kernel32.NVME_DIRECTION.NVME_FROM_DEV_TO_HOST; + passThrough.QueueId = 0; + passThrough.DataBufferLen = (uint) passThrough.DataBuffer.Length; passThrough.MetaDataLen = 0; - passThrough.ReturnBufferLen = (uint) Marshal.SizeOf(); + passThrough.ReturnBufferLen = (uint) Marshal.SizeOf(); - var length = Marshal.SizeOf(); + var length = Marshal.SizeOf(); buffer = Marshal.AllocHGlobal(length); Marshal.StructureToPtr(passThrough, buffer, false); - validTransfer = Kernel32.DeviceIoControl(handle, Kernel32.Command.IOCTL_SCSI_MINIPORT, buffer, length, buffer, length, out _, IntPtr.Zero); + validTransfer = Kernel32.DeviceIoControl(handle, Kernel32.IOCTL.IOCTL_SCSI_MINIPORT, buffer, length, buffer, length, out _, IntPtr.Zero); Marshal.FreeHGlobal(buffer); if (validTransfer) { } else { diff --git a/Hardware/HDD/NVMeIntelRST.cs b/Hardware/HDD/NVMeIntelRST.cs index e99d786..b90de56 100644 --- a/Hardware/HDD/NVMeIntelRST.cs +++ b/Hardware/HDD/NVMeIntelRST.cs @@ -16,8 +16,8 @@ namespace OpenHardwareMonitor.Hardware.HDD { return NVMeWindows.IdentifyDevice(storageInfo); } - public bool IdentifyController(SafeHandle hDevice, out Kernel32.NVMeIdentifyControllerData data) { - data = Kernel32.CreateStruct(); + public bool IdentifyController(SafeHandle hDevice, out Kernel32.NVME_IDENTIFY_CONTROLLER_DATA data) { + data = Kernel32.CreateStruct(); if (hDevice == null || hDevice.IsInvalid) return false; @@ -25,38 +25,38 @@ namespace OpenHardwareMonitor.Hardware.HDD { bool result = false; IntPtr buffer; - Kernel32.NVMePassThrough passThrough = Kernel32.CreateStruct(); - passThrough.srb.HeaderLenght = (uint) Marshal.SizeOf(); + Kernel32.NVME_PASS_THROUGH_IOCTL passThrough = Kernel32.CreateStruct(); + passThrough.srb.HeaderLenght = (uint) Marshal.SizeOf(); passThrough.srb.Signature = Encoding.ASCII.GetBytes(Kernel32.IntelNVMeMiniPortSignature2); passThrough.srb.Timeout = 10; passThrough.srb.ControlCode = Kernel32.NVMePassThroughSrbIoCode; passThrough.srb.ReturnCode = 0; - passThrough.srb.Length = (uint) Marshal.SizeOf() - (uint) Marshal.SizeOf(); + passThrough.srb.Length = (uint) Marshal.SizeOf() - (uint) Marshal.SizeOf(); passThrough.NVMeCmd = new uint[16]; passThrough.NVMeCmd[0] = 6; //identify passThrough.NVMeCmd[10] = 1; //return to host - passThrough.Direction = Kernel32.NVMePassThroughDirection.In; - passThrough.Queue = Kernel32.NVMePassThroughQueue.AdminQ; - passThrough.DataBufferLen = (uint) passThrough.DataBuf.Length; + passThrough.Direction = Kernel32.NVME_DIRECTION.NVME_FROM_DEV_TO_HOST; + passThrough.QueueId = 0; + passThrough.DataBufferLen = (uint) passThrough.DataBuffer.Length; passThrough.MetaDataLen = 0; - passThrough.ReturnBufferLen = (uint) Marshal.SizeOf(); + passThrough.ReturnBufferLen = (uint) Marshal.SizeOf(); - var length = Marshal.SizeOf(); + var length = Marshal.SizeOf(); buffer = Marshal.AllocHGlobal(length); Marshal.StructureToPtr(passThrough, buffer, false); - var validTransfer = Kernel32.DeviceIoControl(hDevice, Kernel32.Command.IOCTL_SCSI_MINIPORT, buffer, length, buffer, length, out _, IntPtr.Zero); + var validTransfer = Kernel32.DeviceIoControl(hDevice, Kernel32.IOCTL.IOCTL_SCSI_MINIPORT, buffer, length, buffer, length, out _, IntPtr.Zero); if (validTransfer) { - var offset = Marshal.OffsetOf(nameof(Kernel32.NVMePassThrough.DataBuf)); + var offset = Marshal.OffsetOf(nameof(Kernel32.NVME_PASS_THROUGH_IOCTL.DataBuffer)); IntPtr newPtr = IntPtr.Add(buffer, offset.ToInt32()); - int finalSize = Marshal.SizeOf(); - var ptr = Marshal.AllocHGlobal(Marshal.SizeOf()); + int finalSize = Marshal.SizeOf(); + var ptr = Marshal.AllocHGlobal(Marshal.SizeOf()); Kernel32.RtlZeroMemory(ptr, finalSize); - int len = Math.Min(finalSize, passThrough.DataBuf.Length); + int len = Math.Min(finalSize, passThrough.DataBuffer.Length); Kernel32.CopyMemory(ptr, newPtr, (uint) len); Marshal.FreeHGlobal(buffer); - var item = Marshal.PtrToStructure(ptr); + var item = Marshal.PtrToStructure(ptr); data = item; Marshal.FreeHGlobal(ptr); result = true; @@ -67,8 +67,8 @@ namespace OpenHardwareMonitor.Hardware.HDD { return result; } - public bool HealthInfoLog(SafeHandle hDevice, out Kernel32.NVMeHealthInfoLog data) { - data = Kernel32.CreateStruct(); + public bool HealthInfoLog(SafeHandle hDevice, out Kernel32.NVME_HEALTH_INFO_LOG data) { + data = Kernel32.CreateStruct(); if (hDevice == null || hDevice.IsInvalid) return false; @@ -76,31 +76,31 @@ namespace OpenHardwareMonitor.Hardware.HDD { bool result = false; IntPtr buffer; - Kernel32.NVMePassThrough passThrough = Kernel32.CreateStruct(); - passThrough.srb.HeaderLenght = (uint) Marshal.SizeOf(); + Kernel32.NVME_PASS_THROUGH_IOCTL passThrough = Kernel32.CreateStruct(); + passThrough.srb.HeaderLenght = (uint) Marshal.SizeOf(); passThrough.srb.Signature = Encoding.ASCII.GetBytes(Kernel32.IntelNVMeMiniPortSignature2); passThrough.srb.Timeout = 10; passThrough.srb.ControlCode = Kernel32.NVMePassThroughSrbIoCode; passThrough.srb.ReturnCode = 0; - passThrough.srb.Length = (uint) Marshal.SizeOf() - (uint) Marshal.SizeOf(); - passThrough.NVMeCmd[0] = (uint) Kernel32.StorageProtocolNVMeDataType.NVMeDataTypeLogPage; // GetLogPage + passThrough.srb.Length = (uint) Marshal.SizeOf() - (uint) Marshal.SizeOf(); + passThrough.NVMeCmd[0] = (uint) Kernel32.STORAGE_PROTOCOL_NVME_DATA_TYPE.NVMeDataTypeLogPage; // GetLogPage passThrough.NVMeCmd[1] = 0xFFFFFFFF; // address passThrough.NVMeCmd[10] = 0x007f0002; // uint cdw10 = 0x000000002 | (((size / 4) - 1) << 16); - passThrough.Direction = Kernel32.NVMePassThroughDirection.In; - passThrough.Queue = Kernel32.NVMePassThroughQueue.AdminQ; - passThrough.DataBufferLen = (uint) passThrough.DataBuf.Length; + passThrough.Direction = Kernel32.NVME_DIRECTION.NVME_FROM_DEV_TO_HOST; + passThrough.QueueId = 0; + passThrough.DataBufferLen = (uint) passThrough.DataBuffer.Length; passThrough.MetaDataLen = 0; - passThrough.ReturnBufferLen = (uint) Marshal.SizeOf(); + passThrough.ReturnBufferLen = (uint) Marshal.SizeOf(); - var length = Marshal.SizeOf(); + var length = Marshal.SizeOf(); buffer = Marshal.AllocHGlobal(length); Marshal.StructureToPtr(passThrough, buffer, false); - var validTransfer = Kernel32.DeviceIoControl(hDevice, Kernel32.Command.IOCTL_SCSI_MINIPORT, buffer, length, buffer, length, out _, IntPtr.Zero); + var validTransfer = Kernel32.DeviceIoControl(hDevice, Kernel32.IOCTL.IOCTL_SCSI_MINIPORT, buffer, length, buffer, length, out _, IntPtr.Zero); if (validTransfer) { - var offset = Marshal.OffsetOf(nameof(Kernel32.NVMePassThrough.DataBuf)); + var offset = Marshal.OffsetOf(nameof(Kernel32.NVME_PASS_THROUGH_IOCTL.DataBuffer)); IntPtr newPtr = IntPtr.Add(buffer, offset.ToInt32()); - var item = Marshal.PtrToStructure(newPtr); + var item = Marshal.PtrToStructure(newPtr); data = item; Marshal.FreeHGlobal(buffer); result = true; @@ -120,27 +120,27 @@ namespace OpenHardwareMonitor.Hardware.HDD { bool validTransfer; IntPtr buffer; - Kernel32.NVMePassThrough passThrough = Kernel32.CreateStruct(); - passThrough.srb.HeaderLenght = (uint) Marshal.SizeOf(); + Kernel32.NVME_PASS_THROUGH_IOCTL passThrough = Kernel32.CreateStruct(); + passThrough.srb.HeaderLenght = (uint) Marshal.SizeOf(); passThrough.srb.Signature = Encoding.ASCII.GetBytes(Kernel32.IntelNVMeMiniPortSignature2); passThrough.srb.Timeout = 10; passThrough.srb.ControlCode = Kernel32.NVMePassThroughSrbIoCode; passThrough.srb.ReturnCode = 0; - passThrough.srb.Length = (uint) Marshal.SizeOf() - (uint) Marshal.SizeOf(); + passThrough.srb.Length = (uint) Marshal.SizeOf() - (uint) Marshal.SizeOf(); passThrough.NVMeCmd = new uint[16]; passThrough.NVMeCmd[0] = 6; //identify passThrough.NVMeCmd[10] = 1; //return to host - passThrough.Direction = Kernel32.NVMePassThroughDirection.In; - passThrough.Queue = Kernel32.NVMePassThroughQueue.AdminQ; - passThrough.DataBufferLen = (uint) passThrough.DataBuf.Length; + passThrough.Direction = Kernel32.NVME_DIRECTION.NVME_FROM_DEV_TO_HOST; + passThrough.QueueId = 0; + passThrough.DataBufferLen = (uint) passThrough.DataBuffer.Length; passThrough.MetaDataLen = 0; - passThrough.ReturnBufferLen = (uint) Marshal.SizeOf(); + passThrough.ReturnBufferLen = (uint) Marshal.SizeOf(); - var length = Marshal.SizeOf(); + var length = Marshal.SizeOf(); buffer = Marshal.AllocHGlobal(length); Marshal.StructureToPtr(passThrough, buffer, false); - validTransfer = Kernel32.DeviceIoControl(handle, Kernel32.Command.IOCTL_SCSI_MINIPORT, buffer, length, buffer, length, out _, IntPtr.Zero); + validTransfer = Kernel32.DeviceIoControl(handle, Kernel32.IOCTL.IOCTL_SCSI_MINIPORT, buffer, length, buffer, length, out _, IntPtr.Zero); Marshal.FreeHGlobal(buffer); if (validTransfer) { } else { diff --git a/Hardware/HDD/NVMeSamsung.cs b/Hardware/HDD/NVMeSamsung.cs index 3558172..fff114d 100644 --- a/Hardware/HDD/NVMeSamsung.cs +++ b/Hardware/HDD/NVMeSamsung.cs @@ -17,69 +17,69 @@ namespace OpenHardwareMonitor.Hardware.HDD { return NVMeWindows.IdentifyDevice(storageInfo); } - public bool IdentifyController(SafeHandle hDevice, out Kernel32.NVMeIdentifyControllerData data) { - data = Kernel32.CreateStruct(); + public bool IdentifyController(SafeHandle hDevice, out Kernel32.NVME_IDENTIFY_CONTROLLER_DATA data) { + data = Kernel32.CreateStruct(); if (hDevice == null || hDevice.IsInvalid) return false; bool result = false; IntPtr buffer; - Kernel32.SPTWith512Buffer sptwb = Kernel32.CreateStruct(); + Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS sptwb = Kernel32.CreateStruct(); sptwb.Spt.Length = (ushort) Marshal.SizeOf(); sptwb.Spt.PathId = 0; sptwb.Spt.TargetId = 0; sptwb.Spt.Lun = 0; sptwb.Spt.SenseInfoLength = 24; - sptwb.Spt.DataTransferLength = Kernel32.IDENTIFY_BUFFER_SIZE; + sptwb.Spt.DataTransferLength = Kernel32.SCSI_PASS_THROUGH_BUFFER_SIZE; sptwb.Spt.TimeOutValue = 2; - sptwb.Spt.DataBufferOffset = Marshal.OffsetOf(typeof(Kernel32.SPTWith512Buffer), nameof(Kernel32.SPTWith512Buffer.DataBuf)); - sptwb.Spt.SenseInfoOffset = (uint) Marshal.OffsetOf(typeof(Kernel32.SPTWith512Buffer), nameof(Kernel32.SPTWith512Buffer.SenseBuf)); + sptwb.Spt.DataBufferOffset = Marshal.OffsetOf(typeof(Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS), nameof(Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS.DataBuf)); + sptwb.Spt.SenseInfoOffset = (uint) Marshal.OffsetOf(typeof(Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS), nameof(Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS.SenseBuf)); sptwb.Spt.CdbLength = 16; sptwb.Spt.Cdb[0] = 0xB5; // SECURITY PROTOCOL IN sptwb.Spt.Cdb[1] = 0xFE; // Samsung Protocol sptwb.Spt.Cdb[3] = 5; // Identify sptwb.Spt.Cdb[8] = 0; // Transfer Length sptwb.Spt.Cdb[9] = 0x40; // Transfer Length - sptwb.Spt.DataIn = Kernel32.SCSI_IOCTL_DATA_OUT; + sptwb.Spt.DataIn = (byte) Kernel32.SCSI_IOCTL_DATA.SCSI_IOCTL_DATA_OUT; sptwb.DataBuf[0] = 1; - var length = Marshal.SizeOf(); + var length = Marshal.SizeOf(); buffer = Marshal.AllocHGlobal(length); Marshal.StructureToPtr(sptwb, buffer, false); - var validTransfer = Kernel32.DeviceIoControl(hDevice, Kernel32.Command.IOCTL_SCSI_PASS_THROUGH, buffer, length, buffer, length, out _, IntPtr.Zero); + var validTransfer = Kernel32.DeviceIoControl(hDevice, Kernel32.IOCTL.IOCTL_SCSI_PASS_THROUGH, buffer, length, buffer, length, out _, IntPtr.Zero); Marshal.FreeHGlobal(buffer); if (validTransfer) { //read data from samsung SSD - sptwb = Kernel32.CreateStruct(); + sptwb = Kernel32.CreateStruct(); sptwb.Spt.Length = (ushort) Marshal.SizeOf(); sptwb.Spt.PathId = 0; sptwb.Spt.TargetId = 0; sptwb.Spt.Lun = 0; sptwb.Spt.SenseInfoLength = 24; - sptwb.Spt.DataTransferLength = Kernel32.IDENTIFY_BUFFER_SIZE; + sptwb.Spt.DataTransferLength = Kernel32.SCSI_PASS_THROUGH_BUFFER_SIZE; sptwb.Spt.TimeOutValue = 2; - sptwb.Spt.DataBufferOffset = Marshal.OffsetOf(nameof(Kernel32.SPTWith512Buffer.DataBuf)); - sptwb.Spt.SenseInfoOffset = (uint) Marshal.OffsetOf(nameof(Kernel32.SPTWith512Buffer.SenseBuf)); + sptwb.Spt.DataBufferOffset = Marshal.OffsetOf(nameof(Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS.DataBuf)); + sptwb.Spt.SenseInfoOffset = (uint) Marshal.OffsetOf(nameof(Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS.SenseBuf)); sptwb.Spt.CdbLength = 16; sptwb.Spt.Cdb[0] = 0xA2; // SECURITY PROTOCOL IN sptwb.Spt.Cdb[1] = 0xFE; // Samsung Protocol sptwb.Spt.Cdb[3] = 5; // Identify sptwb.Spt.Cdb[8] = 2; // Transfer Length (high) sptwb.Spt.Cdb[9] = 0; // Transfer Length (low) - sptwb.Spt.DataIn = Kernel32.SCSI_IOCTL_DATA_IN; + sptwb.Spt.DataIn = (byte) Kernel32.SCSI_IOCTL_DATA.SCSI_IOCTL_DATA_IN; - length = Marshal.SizeOf(); + length = Marshal.SizeOf(); buffer = Marshal.AllocHGlobal(length); Marshal.StructureToPtr(sptwb, buffer, false); - validTransfer = Kernel32.DeviceIoControl(hDevice, Kernel32.Command.IOCTL_SCSI_PASS_THROUGH, buffer, length, buffer, length, out _, IntPtr.Zero); + validTransfer = Kernel32.DeviceIoControl(hDevice, Kernel32.IOCTL.IOCTL_SCSI_PASS_THROUGH, buffer, length, buffer, length, out _, IntPtr.Zero); if (validTransfer) { - var offset = Marshal.OffsetOf(nameof(Kernel32.SPTWith512Buffer.DataBuf)); + var offset = Marshal.OffsetOf(nameof(Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS.DataBuf)); IntPtr newPtr = IntPtr.Add(buffer, offset.ToInt32()); - var item = Marshal.PtrToStructure(newPtr); + var item = Marshal.PtrToStructure(newPtr); data = item; Marshal.FreeHGlobal(buffer); result = true; @@ -91,73 +91,73 @@ namespace OpenHardwareMonitor.Hardware.HDD { return result; } - public bool HealthInfoLog(SafeHandle hDevice, out Kernel32.NVMeHealthInfoLog data) { - data = Kernel32.CreateStruct(); + public bool HealthInfoLog(SafeHandle hDevice, out Kernel32.NVME_HEALTH_INFO_LOG data) { + data = Kernel32.CreateStruct(); if (hDevice == null || hDevice.IsInvalid) return false; bool result = false; IntPtr buffer; - Kernel32.SPTWith512Buffer sptwb = Kernel32.CreateStruct(); + Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS sptwb = Kernel32.CreateStruct(); sptwb.Spt.Length = (ushort) Marshal.SizeOf(); sptwb.Spt.PathId = 0; sptwb.Spt.TargetId = 0; sptwb.Spt.Lun = 0; sptwb.Spt.SenseInfoLength = 24; - sptwb.Spt.DataTransferLength = Kernel32.IDENTIFY_BUFFER_SIZE; + sptwb.Spt.DataTransferLength = Kernel32.SCSI_PASS_THROUGH_BUFFER_SIZE; sptwb.Spt.TimeOutValue = 2; - sptwb.Spt.DataBufferOffset = Marshal.OffsetOf(nameof(Kernel32.SPTWith512Buffer.DataBuf)); - sptwb.Spt.SenseInfoOffset = (uint) Marshal.OffsetOf(nameof(Kernel32.SPTWith512Buffer.SenseBuf)); + sptwb.Spt.DataBufferOffset = Marshal.OffsetOf(nameof(Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS.DataBuf)); + sptwb.Spt.SenseInfoOffset = (uint) Marshal.OffsetOf(nameof(Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS.SenseBuf)); sptwb.Spt.CdbLength = 16; sptwb.Spt.Cdb[0] = 0xB5; // SECURITY PROTOCOL IN sptwb.Spt.Cdb[1] = 0xFE; // Samsung Protocol sptwb.Spt.Cdb[3] = 6; // Log Data sptwb.Spt.Cdb[8] = 0; // Transfer Length sptwb.Spt.Cdb[9] = 0x40; // Transfer Length - sptwb.Spt.DataIn = Kernel32.SCSI_IOCTL_DATA_OUT; + sptwb.Spt.DataIn = (byte) Kernel32.SCSI_IOCTL_DATA.SCSI_IOCTL_DATA_OUT; sptwb.DataBuf[0] = 2; sptwb.DataBuf[4] = 0xff; sptwb.DataBuf[5] = 0xff; sptwb.DataBuf[6] = 0xff; sptwb.DataBuf[7] = 0xff; - var length = Marshal.SizeOf(); + var length = Marshal.SizeOf(); buffer = Marshal.AllocHGlobal(length); Marshal.StructureToPtr(sptwb, buffer, false); - var validTransfer = Kernel32.DeviceIoControl(hDevice, Kernel32.Command.IOCTL_SCSI_PASS_THROUGH, buffer, length, buffer, length, out _, IntPtr.Zero); + var validTransfer = Kernel32.DeviceIoControl(hDevice, Kernel32.IOCTL.IOCTL_SCSI_PASS_THROUGH, buffer, length, buffer, length, out _, IntPtr.Zero); Marshal.FreeHGlobal(buffer); if (validTransfer) { //read data from samsung SSD - sptwb = Kernel32.CreateStruct(); + sptwb = Kernel32.CreateStruct(); sptwb.Spt.Length = (ushort) Marshal.SizeOf(); sptwb.Spt.PathId = 0; sptwb.Spt.TargetId = 0; sptwb.Spt.Lun = 0; sptwb.Spt.SenseInfoLength = 24; - sptwb.Spt.DataTransferLength = Kernel32.IDENTIFY_BUFFER_SIZE; + sptwb.Spt.DataTransferLength = Kernel32.SCSI_PASS_THROUGH_BUFFER_SIZE; sptwb.Spt.TimeOutValue = 2; - sptwb.Spt.DataBufferOffset = Marshal.OffsetOf(nameof(Kernel32.SPTWith512Buffer.DataBuf)); - sptwb.Spt.SenseInfoOffset = (uint) Marshal.OffsetOf(nameof(Kernel32.SPTWith512Buffer.SenseBuf)); + sptwb.Spt.DataBufferOffset = Marshal.OffsetOf(nameof(Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS.DataBuf)); + sptwb.Spt.SenseInfoOffset = (uint) Marshal.OffsetOf(nameof(Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS.SenseBuf)); sptwb.Spt.CdbLength = 16; sptwb.Spt.Cdb[0] = 0xA2; // SECURITY PROTOCOL IN sptwb.Spt.Cdb[1] = 0xFE; // Samsung Protocol sptwb.Spt.Cdb[3] = 6; // Log Data sptwb.Spt.Cdb[8] = 2; // Transfer Length (high) sptwb.Spt.Cdb[9] = 0; // Transfer Length (low) - sptwb.Spt.DataIn = Kernel32.SCSI_IOCTL_DATA_IN; + sptwb.Spt.DataIn = (byte) Kernel32.SCSI_IOCTL_DATA.SCSI_IOCTL_DATA_IN; - length = Marshal.SizeOf(); + length = Marshal.SizeOf(); buffer = Marshal.AllocHGlobal(length); Marshal.StructureToPtr(sptwb, buffer, false); - validTransfer = Kernel32.DeviceIoControl(hDevice, Kernel32.Command.IOCTL_SCSI_PASS_THROUGH, buffer, length, buffer, length, out _, IntPtr.Zero); + validTransfer = Kernel32.DeviceIoControl(hDevice, Kernel32.IOCTL.IOCTL_SCSI_PASS_THROUGH, buffer, length, buffer, length, out _, IntPtr.Zero); if (validTransfer) { - var offset = Marshal.OffsetOf(nameof(Kernel32.SPTWith512Buffer.DataBuf)); + var offset = Marshal.OffsetOf(nameof(Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS.DataBuf)); IntPtr newPtr = IntPtr.Add(buffer, offset.ToInt32()); - var item = Marshal.PtrToStructure(newPtr); + var item = Marshal.PtrToStructure(newPtr); data = item; Marshal.FreeHGlobal(buffer); result = true; @@ -176,59 +176,59 @@ namespace OpenHardwareMonitor.Hardware.HDD { IntPtr buffer; - Kernel32.SPTWith512Buffer sptwb = Kernel32.CreateStruct(); + Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS sptwb = Kernel32.CreateStruct(); sptwb.Spt.Length = (ushort) Marshal.SizeOf(); sptwb.Spt.PathId = 0; sptwb.Spt.TargetId = 0; sptwb.Spt.Lun = 0; sptwb.Spt.SenseInfoLength = 24; - sptwb.Spt.DataTransferLength = Kernel32.IDENTIFY_BUFFER_SIZE; + sptwb.Spt.DataTransferLength = Kernel32.SCSI_PASS_THROUGH_BUFFER_SIZE; sptwb.Spt.TimeOutValue = 2; - sptwb.Spt.DataBufferOffset = Marshal.OffsetOf(typeof(Kernel32.SPTWith512Buffer), nameof(Kernel32.SPTWith512Buffer.DataBuf)); - sptwb.Spt.SenseInfoOffset = (uint) Marshal.OffsetOf(typeof(Kernel32.SPTWith512Buffer), nameof(Kernel32.SPTWith512Buffer.SenseBuf)); + sptwb.Spt.DataBufferOffset = Marshal.OffsetOf(typeof(Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS), nameof(Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS.DataBuf)); + sptwb.Spt.SenseInfoOffset = (uint) Marshal.OffsetOf(typeof(Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS), nameof(Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS.SenseBuf)); sptwb.Spt.CdbLength = 16; sptwb.Spt.Cdb[0] = 0xB5; // SECURITY PROTOCOL IN sptwb.Spt.Cdb[1] = 0xFE; // Samsung Protocol sptwb.Spt.Cdb[3] = 5; // Identify sptwb.Spt.Cdb[8] = 0; // Transfer Length sptwb.Spt.Cdb[9] = 0x40; - sptwb.Spt.DataIn = Kernel32.SCSI_IOCTL_DATA_OUT; + sptwb.Spt.DataIn = (byte) Kernel32.SCSI_IOCTL_DATA.SCSI_IOCTL_DATA_OUT; sptwb.DataBuf[0] = 1; - var length = Marshal.SizeOf(); + var length = Marshal.SizeOf(); buffer = Marshal.AllocHGlobal(length); Marshal.StructureToPtr(sptwb, buffer, false); - var validTransfer = Kernel32.DeviceIoControl(handle, Kernel32.Command.IOCTL_SCSI_PASS_THROUGH, buffer, length, buffer, length, out _, IntPtr.Zero); + var validTransfer = Kernel32.DeviceIoControl(handle, Kernel32.IOCTL.IOCTL_SCSI_PASS_THROUGH, buffer, length, buffer, length, out _, IntPtr.Zero); Marshal.FreeHGlobal(buffer); if (validTransfer) { //read data from samsung SSD - sptwb = Kernel32.CreateStruct(); + sptwb = Kernel32.CreateStruct(); sptwb.Spt.Length = (ushort) Marshal.SizeOf(); sptwb.Spt.PathId = 0; sptwb.Spt.TargetId = 0; sptwb.Spt.Lun = 0; sptwb.Spt.SenseInfoLength = 24; - sptwb.Spt.DataTransferLength = Kernel32.IDENTIFY_BUFFER_SIZE; + sptwb.Spt.DataTransferLength = Kernel32.SCSI_PASS_THROUGH_BUFFER_SIZE; sptwb.Spt.TimeOutValue = 2; - sptwb.Spt.DataBufferOffset = Marshal.OffsetOf(typeof(Kernel32.SPTWith512Buffer), nameof(Kernel32.SPTWith512Buffer.DataBuf)); - sptwb.Spt.SenseInfoOffset = (uint) Marshal.OffsetOf(typeof(Kernel32.SPTWith512Buffer), nameof(Kernel32.SPTWith512Buffer.SenseBuf)); + sptwb.Spt.DataBufferOffset = Marshal.OffsetOf(typeof(Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS), nameof(Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS.DataBuf)); + sptwb.Spt.SenseInfoOffset = (uint) Marshal.OffsetOf(typeof(Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS), nameof(Kernel32.SCSI_PASS_THROUGH_WITH_BUFFERS.SenseBuf)); sptwb.Spt.CdbLength = 16; sptwb.Spt.Cdb[0] = 0xA2; // SECURITY PROTOCOL IN sptwb.Spt.Cdb[1] = 0xFE; // Samsung Protocol sptwb.Spt.Cdb[3] = 5; // Identify sptwb.Spt.Cdb[8] = 2; // Transfer Length sptwb.Spt.Cdb[9] = 0; - sptwb.Spt.DataIn = Kernel32.SCSI_IOCTL_DATA_IN; + sptwb.Spt.DataIn = (byte) Kernel32.SCSI_IOCTL_DATA.SCSI_IOCTL_DATA_IN; - length = Marshal.SizeOf(); + length = Marshal.SizeOf(); buffer = Marshal.AllocHGlobal(length); Marshal.StructureToPtr(sptwb, buffer, false); - validTransfer = Kernel32.DeviceIoControl(handle, Kernel32.Command.IOCTL_SCSI_PASS_THROUGH, buffer, length, buffer, length, out _, IntPtr.Zero); + validTransfer = Kernel32.DeviceIoControl(handle, Kernel32.IOCTL.IOCTL_SCSI_PASS_THROUGH, buffer, length, buffer, length, out _, IntPtr.Zero); if (validTransfer) { - Marshal.PtrToStructure(buffer); + Marshal.PtrToStructure(buffer); Marshal.FreeHGlobal(buffer); } else { Marshal.FreeHGlobal(buffer); diff --git a/Hardware/HDD/NVMeSmart.cs b/Hardware/HDD/NVMeSmart.cs index 941397f..cfd7f60 100644 --- a/Hardware/HDD/NVMeSmart.cs +++ b/Hardware/HDD/NVMeSmart.cs @@ -9,11 +9,11 @@ using System.Text; using OpenHardwareMonitor.Interop; namespace OpenHardwareMonitor.Hardware.HDD { - internal class NVMeSmart : IDisposable { + public class NVMeSmart : IDisposable { private readonly int driveNumber; private readonly SafeHandle handle; - public NVMeSmart(StorageInfo storageInfo) { + internal NVMeSmart(StorageInfo storageInfo) { driveNumber = storageInfo.Index; NVMeDrive = null; @@ -60,7 +60,7 @@ namespace OpenHardwareMonitor.Hardware.HDD { } } - public INVMeDrive NVMeDrive { get; } + internal INVMeDrive NVMeDrive { get; } public void Dispose() { Close(); @@ -96,7 +96,7 @@ namespace OpenHardwareMonitor.Hardware.HDD { bool valid = false; - var data = new Kernel32.NVMeIdentifyControllerData(); + var data = new Kernel32.NVME_IDENTIFY_CONTROLLER_DATA(); if (NVMeDrive != null) valid = NVMeDrive.IdentifyController(handle, out data); @@ -113,7 +113,7 @@ namespace OpenHardwareMonitor.Hardware.HDD { bool valid = false; - var data = new Kernel32.NVMeHealthInfoLog(); + var data = new Kernel32.NVME_HEALTH_INFO_LOG(); if (NVMeDrive != null) valid = NVMeDrive.HealthInfoLog(handle, out data); @@ -125,25 +125,25 @@ namespace OpenHardwareMonitor.Hardware.HDD { } private class NVMeInfo : HDD.NVMeInfo { - public NVMeInfo(int index, Kernel32.NVMeIdentifyControllerData data) { + public NVMeInfo(int index, Kernel32.NVME_IDENTIFY_CONTROLLER_DATA data) { Index = index; - VID = data.vid; - SSVID = data.ssvid; - Serial = GetString(data.sn); - Model = GetString(data.mn); - Revision = GetString(data.fr); - IEEE = data.ieee; - TotalCapacity = BitConverter.ToUInt64(data.tnvmcap, 0); // 128bit little endian - UnallocatedCapacity = BitConverter.ToUInt64(data.unvmcap, 0); - ControllerId = data.cntlid; - NumberNamespaces = data.nn; + VID = data.VID; + SSVID = data.SSVID; + Serial = GetString(data.SN); + Model = GetString(data.MN); + Revision = GetString(data.FR); + IEEE = data.IEEE; + TotalCapacity = BitConverter.ToUInt64(data.TNVMCAP, 0); // 128bit little endian + UnallocatedCapacity = BitConverter.ToUInt64(data.UNVMCAP, 0); + ControllerId = data.CNTLID; + NumberNamespaces = data.NN; } } private class NVMeHealthInfo : HDD.NVMeHealthInfo { - public NVMeHealthInfo(Kernel32.NVMeHealthInfoLog log) { - CriticalWarning = (Kernel32.NVMeCriticalWarning) log.CriticalWarning; - Temperature = KelvinToCelsius(log.CompositeTemperature); + public NVMeHealthInfo(Kernel32.NVME_HEALTH_INFO_LOG log) { + CriticalWarning = (Kernel32.NVME_CRITICAL_WARNING) log.CriticalWarning; + Temperature = KelvinToCelsius(log.CompositeTemp); AvailableSpare = log.AvailableSpare; AvailableSpareThreshold = log.AvailableSpareThreshold; PercentageUsed = log.PercentageUsed; @@ -152,17 +152,17 @@ namespace OpenHardwareMonitor.Hardware.HDD { HostReadCommands = BitConverter.ToUInt64(log.HostReadCommands, 0); HostWriteCommands = BitConverter.ToUInt64(log.HostWriteCommands, 0); ControllerBusyTime = BitConverter.ToUInt64(log.ControllerBusyTime, 0); - PowerCycle = BitConverter.ToUInt64(log.PowerCycle, 0); + PowerCycle = BitConverter.ToUInt64(log.PowerCycles, 0); PowerOnHours = BitConverter.ToUInt64(log.PowerOnHours, 0); UnsafeShutdowns = BitConverter.ToUInt64(log.UnsafeShutdowns, 0); - MediaErrors = BitConverter.ToUInt64(log.MediaErrors, 0); - ErrorInfoLogEntryCount = BitConverter.ToUInt64(log.ErrorInfoLogEntryCount, 0); + MediaErrors = BitConverter.ToUInt64(log.MediaAndDataIntegrityErrors, 0); + ErrorInfoLogEntryCount = BitConverter.ToUInt64(log.NumberErrorInformationLogEntries, 0); WarningCompositeTemperatureTime = log.WarningCompositeTemperatureTime; CriticalCompositeTemperatureTime = log.CriticalCompositeTemperatureTime; - TemperatureSensors = new short[log.TemperatureSensors.Length]; + TemperatureSensors = new short[log.TemperatureSensor.Length]; for (int i = 0; i < TemperatureSensors.Length; i++) - TemperatureSensors[i] = KelvinToCelsius(log.TemperatureSensors[i]); + TemperatureSensors[i] = KelvinToCelsius(log.TemperatureSensor[i]); } } } diff --git a/Hardware/HDD/NVMeWindows.cs b/Hardware/HDD/NVMeWindows.cs index 3d15f9b..f9d3e1c 100644 --- a/Hardware/HDD/NVMeWindows.cs +++ b/Hardware/HDD/NVMeWindows.cs @@ -15,8 +15,8 @@ namespace OpenHardwareMonitor.Hardware.HDD { return IdentifyDevice(storageInfo); } - public bool IdentifyController(SafeHandle hDevice, out Kernel32.NVMeIdentifyControllerData data) { - data = Kernel32.CreateStruct(); + public bool IdentifyController(SafeHandle hDevice, out Kernel32.NVME_IDENTIFY_CONTROLLER_DATA data) { + data = Kernel32.CreateStruct(); if (hDevice == null || hDevice.IsInvalid) return false; @@ -24,23 +24,23 @@ namespace OpenHardwareMonitor.Hardware.HDD { bool result = false; IntPtr buffer; - Kernel32.StorageQueryWithBuffer nptwb = Kernel32.CreateStruct(); - nptwb.ProtocolSpecific.ProtocolType = Kernel32.TStroageProtocolType.ProtocolTypeNvme; - nptwb.ProtocolSpecific.DataType = (uint) Kernel32.StorageProtocolNVMeDataType.NVMeDataTypeIdentify; - nptwb.ProtocolSpecific.ProtocolDataOffset = (uint) Marshal.SizeOf(); + Kernel32.STORAGE_QUERY_BUFFER nptwb = Kernel32.CreateStruct(); + nptwb.ProtocolSpecific.ProtocolType = Kernel32.STORAGE_PROTOCOL_TYPE.ProtocolTypeNvme; + nptwb.ProtocolSpecific.DataType = (uint) Kernel32.STORAGE_PROTOCOL_NVME_DATA_TYPE.NVMeDataTypeIdentify; + nptwb.ProtocolSpecific.ProtocolDataOffset = (uint) Marshal.SizeOf(); nptwb.ProtocolSpecific.ProtocolDataLength = (uint) nptwb.Buffer.Length; - nptwb.Query.PropertyId = Kernel32.StoragePropertyId.StorageAdapterProtocolSpecificProperty; - nptwb.Query.QueryType = Kernel32.StorageQueryType.PropertyStandardQuery; + nptwb.PropertyId = Kernel32.STORAGE_PROPERTY_ID.StorageAdapterProtocolSpecificProperty; + nptwb.QueryType = Kernel32.STORAGE_QUERY_TYPE.PropertyStandardQuery; - var length = Marshal.SizeOf(); + var length = Marshal.SizeOf(); buffer = Marshal.AllocHGlobal(length); Marshal.StructureToPtr(nptwb, buffer, false); - var validTransfer = Kernel32.DeviceIoControl(hDevice, Kernel32.Command.IOCTL_STORAGE_QUERY_PROPERTY, buffer, length, buffer, length, out _, IntPtr.Zero); + var validTransfer = Kernel32.DeviceIoControl(hDevice, Kernel32.IOCTL.IOCTL_STORAGE_QUERY_PROPERTY, buffer, length, buffer, length, out _, IntPtr.Zero); if (validTransfer) { - //map NVMeIdentifyControllerData to nptwb.Buffer - var offset = Marshal.OffsetOf(nameof(Kernel32.StorageQueryWithBuffer.Buffer)); + //map NVME_IDENTIFY_CONTROLLER_DATA to nptwb.Buffer + var offset = Marshal.OffsetOf(nameof(Kernel32.STORAGE_QUERY_BUFFER.Buffer)); var newPtr = IntPtr.Add(buffer, offset.ToInt32()); - var item = Marshal.PtrToStructure(newPtr); + var item = Marshal.PtrToStructure(newPtr); data = item; Marshal.FreeHGlobal(buffer); result = true; @@ -51,8 +51,8 @@ namespace OpenHardwareMonitor.Hardware.HDD { return result; } - public bool HealthInfoLog(SafeHandle hDevice, out Kernel32.NVMeHealthInfoLog data) { - data = Kernel32.CreateStruct(); + public bool HealthInfoLog(SafeHandle hDevice, out Kernel32.NVME_HEALTH_INFO_LOG data) { + data = Kernel32.CreateStruct(); if (hDevice == null || hDevice.IsInvalid) return false; @@ -60,24 +60,24 @@ namespace OpenHardwareMonitor.Hardware.HDD { bool result = false; IntPtr buffer; - Kernel32.StorageQueryWithBuffer nptwb = Kernel32.CreateStruct(); - nptwb.ProtocolSpecific.ProtocolType = Kernel32.TStroageProtocolType.ProtocolTypeNvme; - nptwb.ProtocolSpecific.DataType = (uint) Kernel32.StorageProtocolNVMeDataType.NVMeDataTypeLogPage; + Kernel32.STORAGE_QUERY_BUFFER nptwb = Kernel32.CreateStruct(); + nptwb.ProtocolSpecific.ProtocolType = Kernel32.STORAGE_PROTOCOL_TYPE.ProtocolTypeNvme; + nptwb.ProtocolSpecific.DataType = (uint) Kernel32.STORAGE_PROTOCOL_NVME_DATA_TYPE.NVMeDataTypeLogPage; nptwb.ProtocolSpecific.ProtocolDataRequestValue = (uint) Kernel32.NVME_LOG_PAGES.NVME_LOG_PAGE_HEALTH_INFO; - nptwb.ProtocolSpecific.ProtocolDataOffset = (uint) Marshal.SizeOf(); + nptwb.ProtocolSpecific.ProtocolDataOffset = (uint) Marshal.SizeOf(); nptwb.ProtocolSpecific.ProtocolDataLength = (uint) nptwb.Buffer.Length; - nptwb.Query.PropertyId = Kernel32.StoragePropertyId.StorageAdapterProtocolSpecificProperty; - nptwb.Query.QueryType = Kernel32.StorageQueryType.PropertyStandardQuery; + nptwb.PropertyId = Kernel32.STORAGE_PROPERTY_ID.StorageAdapterProtocolSpecificProperty; + nptwb.QueryType = Kernel32.STORAGE_QUERY_TYPE.PropertyStandardQuery; - var length = Marshal.SizeOf(); + var length = Marshal.SizeOf(); buffer = Marshal.AllocHGlobal(length); Marshal.StructureToPtr(nptwb, buffer, false); - var validTransfer = Kernel32.DeviceIoControl(hDevice, Kernel32.Command.IOCTL_STORAGE_QUERY_PROPERTY, buffer, length, buffer, length, out _, IntPtr.Zero); + var validTransfer = Kernel32.DeviceIoControl(hDevice, Kernel32.IOCTL.IOCTL_STORAGE_QUERY_PROPERTY, buffer, length, buffer, length, out _, IntPtr.Zero); if (validTransfer) { - //map NVMeHealthInfoLog to nptwb.Buffer - var offset = Marshal.OffsetOf(nameof(Kernel32.StorageQueryWithBuffer.Buffer)); + //map NVME_HEALTH_INFO_LOG to nptwb.Buffer + var offset = Marshal.OffsetOf(nameof(Kernel32.STORAGE_QUERY_BUFFER.Buffer)); var newPtr = IntPtr.Add(buffer, offset.ToInt32()); - var item = Marshal.PtrToStructure(newPtr); + var item = Marshal.PtrToStructure(newPtr); data = item; Marshal.FreeHGlobal(buffer); result = true; @@ -96,18 +96,18 @@ namespace OpenHardwareMonitor.Hardware.HDD { IntPtr buffer; - Kernel32.StorageQueryWithBuffer nptwb = Kernel32.CreateStruct(); - nptwb.ProtocolSpecific.ProtocolType = Kernel32.TStroageProtocolType.ProtocolTypeNvme; - nptwb.ProtocolSpecific.DataType = (uint) Kernel32.StorageProtocolNVMeDataType.NVMeDataTypeIdentify; - nptwb.ProtocolSpecific.ProtocolDataOffset = (uint) Marshal.SizeOf(); + Kernel32.STORAGE_QUERY_BUFFER nptwb = Kernel32.CreateStruct(); + nptwb.ProtocolSpecific.ProtocolType = Kernel32.STORAGE_PROTOCOL_TYPE.ProtocolTypeNvme; + nptwb.ProtocolSpecific.DataType = (uint) Kernel32.STORAGE_PROTOCOL_NVME_DATA_TYPE.NVMeDataTypeIdentify; + nptwb.ProtocolSpecific.ProtocolDataOffset = (uint) Marshal.SizeOf(); nptwb.ProtocolSpecific.ProtocolDataLength = (uint) nptwb.Buffer.Length; - nptwb.Query.PropertyId = Kernel32.StoragePropertyId.StorageAdapterProtocolSpecificProperty; - nptwb.Query.QueryType = Kernel32.StorageQueryType.PropertyStandardQuery; + nptwb.PropertyId = Kernel32.STORAGE_PROPERTY_ID.StorageAdapterProtocolSpecificProperty; + nptwb.QueryType = Kernel32.STORAGE_QUERY_TYPE.PropertyStandardQuery; - var length = Marshal.SizeOf(); + var length = Marshal.SizeOf(); buffer = Marshal.AllocHGlobal(length); Marshal.StructureToPtr(nptwb, buffer, false); - var validTransfer = Kernel32.DeviceIoControl(handle, Kernel32.Command.IOCTL_STORAGE_QUERY_PROPERTY, buffer, length, buffer, length, out _, IntPtr.Zero); + var validTransfer = Kernel32.DeviceIoControl(handle, Kernel32.IOCTL.IOCTL_STORAGE_QUERY_PROPERTY, buffer, length, buffer, length, out _, IntPtr.Zero); if (validTransfer) { Marshal.FreeHGlobal(buffer); } else { diff --git a/Hardware/HDD/SSDSandforce.cs b/Hardware/HDD/SSDSandforce.cs index 7171273..7a7e43c 100644 --- a/Hardware/HDD/SSDSandforce.cs +++ b/Hardware/HDD/SSDSandforce.cs @@ -52,15 +52,15 @@ namespace OpenHardwareMonitor.Hardware.HDD { writeAmplification = new Sensor("Write Amplification", 1, SensorType.Factor, this, settings); } - protected override void UpdateAdditionalSensors(Kernel32.DriveAttributeValue[] values) { + protected override void UpdateAdditionalSensors(Kernel32.SMART_ATTRIBUTE[] values) { float? controllerWritesToNand = null; float? hostWritesToController = null; - foreach (Kernel32.DriveAttributeValue value in values) { - if (value.Identifier == 0xE9) - controllerWritesToNand = RawToInt(value.RawValue, value.AttrValue, null); + foreach (Kernel32.SMART_ATTRIBUTE value in values) { + if (value.Id == 0xE9) + controllerWritesToNand = RawToInt(value.RawValue, value.CurrentValue, null); - if (value.Identifier == 0xEA) - hostWritesToController = RawToInt(value.RawValue, value.AttrValue, null); + if (value.Id == 0xEA) + hostWritesToController = RawToInt(value.RawValue, value.CurrentValue, null); } if (controllerWritesToNand.HasValue && hostWritesToController.HasValue) { diff --git a/Hardware/HDD/SmartAttribute.cs b/Hardware/HDD/SmartAttribute.cs index 21e4fc9..1d13784 100644 --- a/Hardware/HDD/SmartAttribute.cs +++ b/Hardware/HDD/SmartAttribute.cs @@ -102,12 +102,12 @@ namespace OpenHardwareMonitor.Hardware.HDD { public SensorType? SensorType { get; } - internal float ConvertValue(Kernel32.DriveAttributeValue value, IReadOnlyList parameters) { + internal float ConvertValue(Kernel32.SMART_ATTRIBUTE value, IReadOnlyList parameters) { if (rawValueConversion == null) { - return value.AttrValue; + return value.CurrentValue; } - return rawValueConversion(value.RawValue, value.AttrValue, parameters); + return rawValueConversion(value.RawValue, value.CurrentValue, parameters); } } } \ No newline at end of file diff --git a/Hardware/HDD/SmartNames.cs b/Hardware/HDD/SmartNames.cs index 0c20a68..f36aa32 100644 --- a/Hardware/HDD/SmartNames.cs +++ b/Hardware/HDD/SmartNames.cs @@ -7,7 +7,7 @@ namespace OpenHardwareMonitor.Hardware.HDD { /// /// Localization class for SMART attribute names. /// - internal static class SmartNames { + public static class SmartNames { public static string AirflowTemperature => "Airflow Temperature"; public static string AlternativeEraseFailCount => "Alternative Erase Fail Count"; diff --git a/Hardware/HDD/StorageInfo.cs b/Hardware/HDD/StorageInfo.cs index c8bb1d9..29f0798 100644 --- a/Hardware/HDD/StorageInfo.cs +++ b/Hardware/HDD/StorageInfo.cs @@ -7,7 +7,7 @@ using OpenHardwareMonitor.Interop; namespace OpenHardwareMonitor.Hardware.HDD { internal abstract class StorageInfo { - public Kernel32.StorageBusType BusType { get; protected set; } + public Kernel32.STORAGE_BUS_TYPE BusType { get; protected set; } public string DeviceId { get; set; } diff --git a/Hardware/HDD/WindowsSmart.cs b/Hardware/HDD/WindowsSmart.cs index ec62100..2fc9f7e 100644 --- a/Hardware/HDD/WindowsSmart.cs +++ b/Hardware/HDD/WindowsSmart.cs @@ -40,82 +40,81 @@ namespace OpenHardwareMonitor.Hardware.HDD { throw new ObjectDisposedException("WindowsATASmart"); - var parameter = new Kernel32.DriveCommandParameter { - DriveNumber = (byte) driveNumber, - Registers = { - Features = Kernel32.RegisterFeature.SmartEnableOperations, - LBAMid = Kernel32.SMART_LBA_MID, - LBAHigh = Kernel32.SMART_LBA_HI, - Command = Kernel32.RegisterCommand.SmartCmd + var parameter = new Kernel32.SENDCMDINPARAMS { + bDriveNumber = (byte) driveNumber, + irDriveRegs = { + bFeaturesReg = Kernel32.SMART_FEATURES.ENABLE_SMART, + bCylLowReg = Kernel32.SMART_LBA_MID, + bCylHighReg = Kernel32.SMART_LBA_HI, + bCommandReg = Kernel32.ATA_COMMAND.ATA_SMART } }; - return Kernel32.DeviceIoControl( - handle, - Kernel32.DriveCommand.SendDriveCommand, + return Kernel32.DeviceIoControl(handle, + Kernel32.DFP.DFP_SEND_DRIVE_COMMAND, ref parameter, Marshal.SizeOf(parameter), - out Kernel32.DriveCommandResult _, - Marshal.SizeOf(), + out Kernel32.SENDCMDOUTPARAMS _, + Marshal.SizeOf(), out _, IntPtr.Zero); } - public Kernel32.DriveAttributeValue[] ReadSmartData() { + public Kernel32.SMART_ATTRIBUTE[] ReadSmartData() { if (handle.IsClosed) throw new ObjectDisposedException("WindowsATASmart"); - var parameter = new Kernel32.DriveCommandParameter { - DriveNumber = (byte) driveNumber, - Registers = { - Features = Kernel32.RegisterFeature.SmartReadData, - LBAMid = Kernel32.SMART_LBA_MID, - LBAHigh = Kernel32.SMART_LBA_HI, - Command = Kernel32.RegisterCommand.SmartCmd + var parameter = new Kernel32.SENDCMDINPARAMS { + bDriveNumber = (byte) driveNumber, + irDriveRegs = { + bFeaturesReg = Kernel32.SMART_FEATURES.SMART_READ_DATA, + bCylLowReg = Kernel32.SMART_LBA_MID, + bCylHighReg = Kernel32.SMART_LBA_HI, + bCommandReg = Kernel32.ATA_COMMAND.ATA_SMART } }; bool isValid = Kernel32.DeviceIoControl(handle, - Kernel32.DriveCommand.ReceiveDriveData, + Kernel32.DFP.DFP_RECEIVE_DRIVE_DATA, ref parameter, Marshal.SizeOf(parameter), - out Kernel32.DriveSmartReadDataResult result, - Marshal.SizeOf(), + out Kernel32.ATTRIBUTECMDOUTPARAMS result, + Marshal.SizeOf(), out _, IntPtr.Zero); - return (isValid) ? result.Attributes : new Kernel32.DriveAttributeValue[0]; + return (isValid) ? result.Attributes : new Kernel32.SMART_ATTRIBUTE[0]; } - public Kernel32.DriveThresholdValue[] ReadSmartThresholds() { + public Kernel32.SMART_THRESHOLD[] ReadSmartThresholds() { if (handle.IsClosed) throw new ObjectDisposedException("WindowsATASmart"); - var parameter = new Kernel32.DriveCommandParameter { - DriveNumber = (byte) driveNumber, - Registers = { - Features = Kernel32.RegisterFeature.SmartReadThresholds, - LBAMid = Kernel32.SMART_LBA_MID, - LBAHigh = Kernel32.SMART_LBA_HI, - Command = Kernel32.RegisterCommand.SmartCmd + var parameter = new Kernel32.SENDCMDINPARAMS { + bDriveNumber = (byte) driveNumber, + irDriveRegs = { + bFeaturesReg = Kernel32.SMART_FEATURES.READ_THRESHOLDS, + bCylLowReg = Kernel32.SMART_LBA_MID, + bCylHighReg = Kernel32.SMART_LBA_HI, + bCommandReg = Kernel32.ATA_COMMAND.ATA_SMART } }; bool isValid = Kernel32.DeviceIoControl(handle, - Kernel32.DriveCommand.ReceiveDriveData, + Kernel32.DFP.DFP_RECEIVE_DRIVE_DATA, ref parameter, Marshal.SizeOf(parameter), - out Kernel32.DriveSmartReadThresholdsResult result, - Marshal.SizeOf(), + out Kernel32.THRESHOLDCMDOUTPARAMS result, + Marshal.SizeOf(), out _, IntPtr.Zero); - return (isValid) ? result.Thresholds : new Kernel32.DriveThresholdValue[0]; + return (isValid) ? result.Thresholds : new Kernel32.SMART_THRESHOLD[0]; } public bool ReadNameAndFirmwareRevision(out string name, out string firmwareRevision) { @@ -123,15 +122,15 @@ namespace OpenHardwareMonitor.Hardware.HDD { throw new ObjectDisposedException("WindowsATASmart"); - var parameter = new Kernel32.DriveCommandParameter { DriveNumber = (byte) driveNumber, Registers = { Command = Kernel32.RegisterCommand.IdCmd } }; + var parameter = new Kernel32.SENDCMDINPARAMS { bDriveNumber = (byte) driveNumber, irDriveRegs = { bCommandReg = Kernel32.ATA_COMMAND.ATA_IDENTIFY_DEVICE } }; bool valid = Kernel32.DeviceIoControl(handle, - Kernel32.DriveCommand.ReceiveDriveData, + Kernel32.DFP.DFP_RECEIVE_DRIVE_DATA, ref parameter, Marshal.SizeOf(parameter), - out Kernel32.DriveIdentifyResult result, - Marshal.SizeOf(), + out Kernel32.IDENTIFYCMDOUTPARAMS result, + Marshal.SizeOf(), out _, IntPtr.Zero); diff --git a/Hardware/HDD/WindowsStorage.cs b/Hardware/HDD/WindowsStorage.cs index 9267033..b28c73e 100644 --- a/Hardware/HDD/WindowsStorage.cs +++ b/Hardware/HDD/WindowsStorage.cs @@ -17,15 +17,15 @@ namespace OpenHardwareMonitor.Hardware.HDD { return null; - var query = new Kernel32.StoragePropertyQuery { PropertyId = Kernel32.StoragePropertyId.StorageDeviceProperty, QueryType = Kernel32.StorageQueryType.PropertyStandardQuery }; + var query = new Kernel32.STORAGE_PROPERTY_QUERY { PropertyId = Kernel32.STORAGE_PROPERTY_ID.StorageDeviceProperty, QueryType = Kernel32.STORAGE_QUERY_TYPE.PropertyStandardQuery }; if (!Kernel32.DeviceIoControl(handle, - Kernel32.StorageCommand.QueryProperty, + Kernel32.IOCTL.IOCTL_STORAGE_QUERY_PROPERTY, ref query, Marshal.SizeOf(query), out var header, - Marshal.SizeOf(), + Marshal.SizeOf(), out _, IntPtr.Zero)) return null; @@ -33,7 +33,7 @@ namespace OpenHardwareMonitor.Hardware.HDD { IntPtr descriptorPtr = Marshal.AllocHGlobal((int) header.Size); try { - if (!Kernel32.DeviceIoControl(handle, Kernel32.StorageCommand.QueryProperty, ref query, Marshal.SizeOf(query), descriptorPtr, header.Size, out _, IntPtr.Zero)) + if (!Kernel32.DeviceIoControl(handle, Kernel32.IOCTL.IOCTL_STORAGE_QUERY_PROPERTY, ref query, Marshal.SizeOf(query), descriptorPtr, header.Size, out _, IntPtr.Zero)) return null; @@ -66,7 +66,7 @@ namespace OpenHardwareMonitor.Hardware.HDD { private class StorageInfo : HDD.StorageInfo { public StorageInfo(int index, IntPtr descriptorPtr) { - Kernel32.StorageDeviceDescriptor descriptor = Marshal.PtrToStructure(descriptorPtr); + Kernel32.STORAGE_DEVICE_DESCRIPTOR descriptor = Marshal.PtrToStructure(descriptorPtr); Index = index; Vendor = GetString(descriptorPtr, descriptor.VendorIdOffset); Product = GetString(descriptorPtr, descriptor.ProductIdOffset); diff --git a/Hardware/HexStringArray.cs b/Hardware/HexStringArray.cs index 64b573f..15a4988 100644 --- a/Hardware/HexStringArray.cs +++ b/Hardware/HexStringArray.cs @@ -9,7 +9,6 @@ */ using System; -using System.Collections.Generic; namespace OpenHardwareMonitor.Hardware { internal static class HexStringArray { diff --git a/Hardware/IOControlCode.cs b/Hardware/IOControlCode.cs index 7cf9d95..2376a66 100644 --- a/Hardware/IOControlCode.cs +++ b/Hardware/IOControlCode.cs @@ -8,7 +8,6 @@ */ -using System; using System.Runtime.InteropServices; namespace OpenHardwareMonitor.Hardware { diff --git a/Hardware/Mainboard/GigabyteTAMG.cs b/Hardware/Mainboard/GigabyteTAMG.cs index c141691..12ca9f0 100644 --- a/Hardware/Mainboard/GigabyteTAMG.cs +++ b/Hardware/Mainboard/GigabyteTAMG.cs @@ -9,10 +9,8 @@ */ using System; -using System.Collections.Generic; using System.IO; using System.IO.Compression; -using System.Runtime.InteropServices; using System.Text; namespace OpenHardwareMonitor.Hardware.Mainboard { diff --git a/Hardware/Mainboard/Mainboard.cs b/Hardware/Mainboard/Mainboard.cs index 377371c..969a328 100644 --- a/Hardware/Mainboard/Mainboard.cs +++ b/Hardware/Mainboard/Mainboard.cs @@ -13,7 +13,7 @@ using System.Text; using OpenHardwareMonitor.Hardware.LPC; namespace OpenHardwareMonitor.Hardware.Mainboard { - internal class Mainboard : IHardware { + public class Mainboard : IHardware { private readonly SMBIOS smbios; private readonly string name; private string customName; @@ -22,6 +22,11 @@ namespace OpenHardwareMonitor.Hardware.Mainboard { private readonly LMSensors lmSensors; private readonly Hardware[] superIOHardware; + /// + /// Gets the SMBIOS information. + /// + public SMBIOS SMBIOS => smbios; + public Mainboard(SMBIOS smbios, ISettings settings) { this.settings = settings; this.smbios = smbios; diff --git a/Hardware/Nic/Nic.cs b/Hardware/Nic/Nic.cs index 9f66010..3f53d51 100644 --- a/Hardware/Nic/Nic.cs +++ b/Hardware/Nic/Nic.cs @@ -5,7 +5,6 @@ using System; using System.Diagnostics; -using System.Globalization; using System.Net.NetworkInformation; namespace OpenHardwareMonitor.Hardware.Nic { diff --git a/Hardware/RAM/GenericRAM.cs b/Hardware/RAM/GenericRAM.cs index 1f93968..13ee2cc 100644 --- a/Hardware/RAM/GenericRAM.cs +++ b/Hardware/RAM/GenericRAM.cs @@ -45,19 +45,19 @@ namespace OpenHardwareMonitor.Hardware.RAM { } public override void Update() { - Kernel32.MemoryStatusEx status = new Kernel32.MemoryStatusEx(); - status.Length = (uint)Marshal.SizeOf(); + Kernel32.MEMORYSTATUSEX status = new Kernel32.MEMORYSTATUSEX(); + status.dwLength = (uint)Marshal.SizeOf(); if (!Kernel32.GlobalMemoryStatusEx(ref status)) return; - physicalMemoryUsed.Value = (float)(status.TotalPhysicalMemory - status.AvailablePhysicalMemory) / (1024 * 1024 * 1024); - physicalMemoryAvailable.Value = (float)status.AvailablePhysicalMemory / (1024 * 1024 * 1024); - physicalMemoryLoad.Value = 100.0f - (100.0f * status.AvailablePhysicalMemory) / status.TotalPhysicalMemory; + physicalMemoryUsed.Value = (float)(status.ullTotalPhys - status.ullAvailPhys) / (1024 * 1024 * 1024); + physicalMemoryAvailable.Value = (float)status.ullAvailPhys / (1024 * 1024 * 1024); + physicalMemoryLoad.Value = 100.0f - (100.0f * status.ullAvailPhys) / status.ullTotalPhys; - virtualMemoryUsed.Value = (float)(status.TotalPageFile - status.AvailPageFile) / (1024 * 1024 * 1024); - virtualMemoryAvailable.Value = (float)status.AvailPageFile / (1024 * 1024 * 1024); - virtualMemoryLoad.Value = 100.0f - (100.0f * status.AvailPageFile) / status.TotalPageFile; + virtualMemoryUsed.Value = (float)(status.ullTotalPageFile - status.ullAvailPageFile) / (1024 * 1024 * 1024); + virtualMemoryAvailable.Value = (float)status.ullAvailPageFile / (1024 * 1024 * 1024); + virtualMemoryLoad.Value = 100.0f - (100.0f * status.ullAvailPageFile) / status.ullTotalPageFile; } } } \ No newline at end of file diff --git a/Hardware/RAM/RAMGroup.cs b/Hardware/RAM/RAMGroup.cs index 7179b4f..d018846 100644 --- a/Hardware/RAM/RAMGroup.cs +++ b/Hardware/RAM/RAMGroup.cs @@ -3,7 +3,6 @@ // Copyright (C) LibreHardwareMonitor and Contributors // All Rights Reserved -using System; using System.Collections.Generic; namespace OpenHardwareMonitor.Hardware.RAM { diff --git a/Hardware/SensorVisitor.cs b/Hardware/SensorVisitor.cs index 4687ec3..fd9ab1d 100644 --- a/Hardware/SensorVisitor.cs +++ b/Hardware/SensorVisitor.cs @@ -9,7 +9,6 @@ */ using System; -using System.Collections.Generic; namespace OpenHardwareMonitor.Hardware { diff --git a/Hardware/TBalancer/TBalancer.cs b/Hardware/TBalancer/TBalancer.cs index abbe052..7ccc784 100644 --- a/Hardware/TBalancer/TBalancer.cs +++ b/Hardware/TBalancer/TBalancer.cs @@ -8,7 +8,6 @@ */ -using System; using System.Collections.Generic; using System.Globalization; using System.Text; diff --git a/Interop/Kernel32.cs b/Interop/Kernel32.cs index 8fca175..c485235 100644 --- a/Interop/Kernel32.cs +++ b/Interop/Kernel32.cs @@ -8,265 +8,145 @@ using System.IO; using System.Runtime.InteropServices; using Microsoft.Win32.SafeHandles; +// ReSharper disable InconsistentNaming + namespace OpenHardwareMonitor.Interop { - internal class Kernel32 { - private const string KERNEL = "kernel32.dll"; - public const byte SMART_LBA_MID = 0x4F; - public const byte SMART_LBA_HI = 0xC2; - public const int MAX_DRIVE_ATTRIBUTES = 512; - public const string IntelNVMeMiniPortSignature1 = "NvmeMini"; - public const string IntelNVMeMiniPortSignature2 = "IntelNvm"; - public const uint NVMePassThroughSrbIoCode = 0xe0002000; - public const int IDENTIFY_BUFFER_SIZE = 512; - public const int SCSI_IOCTL_DATA_OUT = 0; - public const int SCSI_IOCTL_DATA_IN = 1; - public const int SCSI_IOCTL_DATA_UNSPECIFIED = 2; + public class Kernel32 { + internal const string IntelNVMeMiniPortSignature1 = "NvmeMini"; + internal const string IntelNVMeMiniPortSignature2 = "IntelNvm"; + internal const int MAX_DRIVE_ATTRIBUTES = 512; + internal const uint NVMePassThroughSrbIoCode = 0xe0002000; + internal const int SCSI_PASS_THROUGH_BUFFER_SIZE = 512; + internal const byte SMART_LBA_HI = 0xC2; + internal const byte SMART_LBA_MID = 0x4F; - #region MemoryStatusEx - [StructLayout(LayoutKind.Sequential)] - public struct MemoryStatusEx { - public uint Length; - public uint MemoryLoad; - public ulong TotalPhysicalMemory; - public ulong AvailablePhysicalMemory; - public ulong TotalPageFile; - public ulong AvailPageFile; - public ulong TotalVirtual; - public ulong AvailVirtual; - public ulong AvailExtendedVirtual; + private const string DllName = "kernel32.dll"; + + internal enum DFP : uint { + DFP_GET_VERSION = 0x00074080, + DFP_SEND_DRIVE_COMMAND = 0x0007c084, + DFP_RECEIVE_DRIVE_DATA = 0x0007c088 } - #endregion - #region DriveAttributeValue - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct DriveAttributeValue { - public byte Identifier; - public short StatusFlags; - public byte AttrValue; - public byte WorstValue; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] - public byte[] RawValue; - public byte Reserved; + internal enum IOCTL : uint { + IOCTL_SCSI_PASS_THROUGH = 0x04d004, + IOCTL_SCSI_MINIPORT = 0x04d008, + IOCTL_SCSI_PASS_THROUGH_DIRECT = 0x04d014, + IOCTL_SCSI_GET_ADDRESS = 0x41018, + IOCTL_STORAGE_QUERY_PROPERTY = 0x2D1400 } - #endregion - #region DriveThresholdValue - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct DriveThresholdValue { - public byte Identifier; - public byte Threshold; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] - public byte[] Unknown; + [Flags] + public enum NVME_CRITICAL_WARNING { + None = 0x00, + AvailableSpaceLow = 0x01, // If set to 1, then the available spare space has fallen below the threshold. + TemperatureThreshold = 0x02, // If set to 1, then a temperature is above an over temperature threshold or below an under temperature threshold. + ReliabilityDegraded = 0x04, // If set to 1, then the device reliability has been degraded due to significant media related errors or any internal error that degrades device reliability. + ReadOnly = 0x08, // If set to 1, then the media has been placed in read only mode + VolatileMemoryBackupDeviceFailed = 0x10 // If set to 1, then the volatile memory backup device has failed. This field is only valid if the controller has a volatile memory backup solution. } - #endregion - #region DriveCommand - public enum DriveCommand : uint { - GetVersion = 0x00074080, - SendDriveCommand = 0x0007c084, - ReceiveDriveData = 0x0007c088 + [Flags] + internal enum NVME_DIRECTION : uint { + NVME_FROM_HOST_TO_DEV = 1, + NVME_FROM_DEV_TO_HOST = 2, + NVME_BI_DIRECTION = NVME_FROM_DEV_TO_HOST | NVME_FROM_HOST_TO_DEV } - #endregion - #region RegisterCommand - public enum RegisterCommand : byte { + internal enum NVME_LOG_PAGES { + NVME_LOG_PAGE_ERROR_INFO = 0x01, + NVME_LOG_PAGE_HEALTH_INFO = 0x02, + NVME_LOG_PAGE_FIRMWARE_SLOT_INFO = 0x03, + NVME_LOG_PAGE_CHANGED_NAMESPACE_LIST = 0x04, + NVME_LOG_PAGE_COMMAND_EFFECTS = 0x05, + NVME_LOG_PAGE_DEVICE_SELF_TEST = 0x06, + NVME_LOG_PAGE_TELEMETRY_HOST_INITIATED = 0x07, + NVME_LOG_PAGE_TELEMETRY_CTLR_INITIATED = 0x08, + NVME_LOG_PAGE_RESERVATION_NOTIFICATION = 0x80, + NVME_LOG_PAGE_SANITIZE_STATUS = 0x81 + } + + internal enum ATA_COMMAND : byte { /// /// SMART data requested. /// - SmartCmd = 0xB0, + ATA_SMART = 0xB0, /// /// Identify data is requested. /// - IdCmd = 0xEC, + ATA_IDENTIFY_DEVICE = 0xEC } - #endregion - #region RegisterFeature - public enum RegisterFeature : byte { + internal enum SCSI_IOCTL_DATA { + SCSI_IOCTL_DATA_OUT = 0, + SCSI_IOCTL_DATA_IN = 1, + SCSI_IOCTL_DATA_UNSPECIFIED = 2 + } + + internal enum SMART_FEATURES : byte { /// /// Read SMART data. /// - SmartReadData = 0xD0, + SMART_READ_DATA = 0xD0, /// /// Read SMART thresholds. /// - SmartReadThresholds = 0xD1, /* obsolete */ + READ_THRESHOLDS = 0xD1, /* obsolete */ /// /// Autosave SMART data. /// - SmartAutosave = 0xD2, + ENABLE_DISABLE_AUTOSAVE = 0xD2, /// /// Save SMART attributes. /// - SmartSaveAttr = 0xD3, + SAVE_ATTRIBUTE_VALUES = 0xD3, /// /// Set SMART to offline immediately. /// - SmartImmediateOffline = 0xD4, + EXECUTE_OFFLINE_DIAGS = 0xD4, /// /// Read SMART log. /// - SmartReadLog = 0xD5, + SMART_READ_LOG = 0xD5, /// /// Write SMART log. /// - SmartWriteLog = 0xD6, + SMART_WRITE_LOG = 0xD6, /// /// Write SMART thresholds. /// - SmartWriteThresholds = 0xD7, /* obsolete */ + WRITE_THRESHOLDS = 0xD7, /* obsolete */ /// /// Enable SMART. /// - SmartEnableOperations = 0xD8, + ENABLE_SMART = 0xD8, /// /// Disable SMART. /// - SmartDisableOperations = 0xD9, + DISABLE_SMART = 0xD9, /// /// Get SMART status. /// - SmartStatus = 0xDA, + RETURN_SMART_STATUS = 0xDA, /// /// Set SMART to offline automatically. /// - SmartAutoOffline = 0xDB, /* obsolete */ + ENABLE_DISABLE_AUTO_OFFLINE = 0xDB /* obsolete */ } - #endregion - #region CommandBlockRegisters - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct CommandBlockRegisters { - public RegisterFeature Features; - public byte SectorCount; - public byte LBALow; - public byte LBAMid; - public byte LBAHigh; - public byte Device; - public RegisterCommand Command; - public byte Reserved; - } - #endregion - - #region DriveCommandParameter - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct DriveCommandParameter { - public uint BufferSize; - public CommandBlockRegisters Registers; - public byte DriveNumber; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] - public byte[] Reserved; - } - #endregion - - #region DriverStatus - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct DriverStatus { - public byte DriverError; - public byte IDEError; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] - public byte[] Reserved; - } - #endregion - - #region DriveCommandResult - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct DriveCommandResult { - public uint BufferSize; - public DriverStatus DriverStatus; - } - #endregion - - #region DriveSmartReadDataResult - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct DriveSmartReadDataResult { - public uint BufferSize; - public DriverStatus DriverStatus; - public byte Version; - public byte Reserved; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DRIVE_ATTRIBUTES)] - public DriveAttributeValue[] Attributes; - } - #endregion - - #region DriveSmartReadThresholdsResult - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct DriveSmartReadThresholdsResult { - public uint BufferSize; - public DriverStatus DriverStatus; - public byte Version; - public byte Reserved; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DRIVE_ATTRIBUTES)] - public DriveThresholdValue[] Thresholds; - } - #endregion - - #region Identify - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct Identify { - public ushort GeneralConfiguration; - public ushort NumberOfCylinders; - public ushort Reserved; - public ushort NumberOfHeads; - public ushort UnformattedBytesPerTrack; - public ushort UnformattedBytesPerSector; - public ushort SectorsPerTrack; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] - public ushort[] VendorUnique; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] - public byte[] SerialNumber; - public ushort BufferType; - public ushort BufferSectorSize; - public ushort NumberOfEccBytes; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] - public byte[] FirmwareRevision; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)] - public byte[] ModelNumber; - public ushort MoreVendorUnique; - public ushort DoubleWordIo; - public ushort Capabilities; - public ushort MoreReserved; - public ushort PioCycleTimingMode; - public ushort DmaCycleTimingMode; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 406)] - public byte[] More; - } - #endregion - - #region DriveIdentifyResult - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct DriveIdentifyResult { - public uint BufferSize; - public DriverStatus DriverStatus; - public Identify Identify; - } - #endregion - - #region SCSI_ADDRESS - [StructLayout(LayoutKind.Sequential)] - public struct SCSI_ADDRESS { - public uint Length; - public byte PortNumber; - public byte PathId; - public byte TargetId; - public byte Lun; - } - #endregion - - #region StorageBusType - public enum StorageBusType { + internal enum STORAGE_BUS_TYPE { BusTypeUnknown = 0x00, BusTypeScsi, BusTypeAtapi, @@ -287,27 +167,10 @@ namespace OpenHardwareMonitor.Interop { BusTypeNvme, BusTypeSCM, BusTypeMax, - BusTypeMaxReserved = 0x7F, + BusTypeMaxReserved = 0x7F } - #endregion - #region StorageCommand - public enum StorageCommand : uint { - QueryProperty = 0x002d1400, - } - #endregion - - #region StorageQueryType - public enum StorageQueryType { - PropertyStandardQuery = 0, - PropertyExistsQuery, - PropertyMaskQuery, - PropertyQueryMaxDefined, - } - #endregion - - #region StoragePropertyId - public enum StoragePropertyId { + internal enum STORAGE_PROPERTY_ID { StorageDeviceProperty = 0, StorageAdapterProperty, StorageDeviceIdProperty, @@ -335,142 +198,406 @@ namespace OpenHardwareMonitor.Interop { StorageDeviceAttributesProperty, StorageDeviceManagementStatus, StorageAdapterSerialNumberProperty, - StorageDeviceLocationProperty, + StorageDeviceLocationProperty } - #endregion - #region StoragePropertyQuery + internal enum STORAGE_PROTOCOL_NVME_DATA_TYPE { + NVMeDataTypeUnknown = 0, + NVMeDataTypeIdentify, + NVMeDataTypeLogPage, + NVMeDataTypeFeature + } + + internal enum STORAGE_PROTOCOL_TYPE { + ProtocolTypeUnknown = 0x00, + ProtocolTypeScsi, + ProtocolTypeAta, + ProtocolTypeNvme, + ProtocolTypeSd, + ProtocolTypeProprietary = 0x7E, + ProtocolTypeMaxReserved = 0x7F + } + + internal enum STORAGE_QUERY_TYPE { + PropertyStandardQuery = 0, + PropertyExistsQuery, + PropertyMaskQuery, + PropertyQueryMaxDefined + } + + /// + /// Create a instance from a struct with zero initialized memory arrays + /// no need to init every inner array with the correct sizes + /// + /// type of struct that is needed + /// + internal static T CreateStruct() { + int size = Marshal.SizeOf(); + var ptr = Marshal.AllocHGlobal(size); + RtlZeroMemory(ptr, size); + var result = Marshal.PtrToStructure(ptr); + Marshal.FreeHGlobal(ptr); + return result; + } + + internal static SafeHandle OpenDevice(string devicePath) { + SafeHandle hDevice = CreateFile(devicePath, FileAccess.ReadWrite, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, FileAttributes.Normal, IntPtr.Zero); + if (hDevice.IsInvalid || hDevice.IsClosed) + hDevice = null; + + return hDevice; + } + + [DllImport(DllName, CharSet = CharSet.Auto, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool GlobalMemoryStatusEx(ref MEMORYSTATUSEX lpBuffer); + + [DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)] + internal static extern SafeFileHandle CreateFile + ( + [MarshalAs(UnmanagedType.LPTStr)] string lpFileName, + [MarshalAs(UnmanagedType.U4)] FileAccess dwDesiredAccess, + [MarshalAs(UnmanagedType.U4)] FileShare dwShareMode, + IntPtr lpSecurityAttributes, + [MarshalAs(UnmanagedType.U4)] FileMode dwCreationDisposition, + [MarshalAs(UnmanagedType.U4)] FileAttributes dwFlagsAndAttributes, + IntPtr hTemplateFile); + + [DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool DeviceIoControl + ( + SafeHandle hDevice, + DFP dwIoControlCode, + ref SENDCMDINPARAMS lpInBuffer, + int nInBufferSize, + out ATTRIBUTECMDOUTPARAMS lpOutBuffer, + int nOutBufferSize, + out uint lpBytesReturned, + IntPtr lpOverlapped); + + [DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool DeviceIoControl + ( + SafeHandle hDevice, + DFP dwIoControlCode, + ref SENDCMDINPARAMS lpInBuffer, + int nInBufferSize, + out THRESHOLDCMDOUTPARAMS lpOutBuffer, + int nOutBufferSize, + out uint lpBytesReturned, + IntPtr lpOverlapped); + + [DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool DeviceIoControl + ( + SafeHandle hDevice, + DFP dwIoControlCode, + ref SENDCMDINPARAMS lpInBuffer, + int nInBufferSize, + out SENDCMDOUTPARAMS lpOutBuffer, + int nOutBufferSize, + out uint lpBytesReturned, + IntPtr lpOverlapped); + + [DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool DeviceIoControl + ( + SafeHandle hDevice, + DFP dwIoControlCode, + ref SENDCMDINPARAMS lpInBuffer, + int nInBufferSize, + out IDENTIFYCMDOUTPARAMS lpOutBuffer, + int nOutBufferSize, + out uint lpBytesReturned, + IntPtr lpOverlapped); + + [DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool DeviceIoControl + ( + SafeHandle hDevice, + IOCTL dwIoControlCode, + ref STORAGE_PROPERTY_QUERY lpInBuffer, + int nInBufferSize, + out STORAGE_DEVICE_DESCRIPTOR_HEADER lpOutBuffer, + int nOutBufferSize, + out uint lpBytesReturned, + IntPtr lpOverlapped); + + [DllImport(DllName, + CallingConvention = CallingConvention.Winapi, + CharSet = CharSet.Auto, + SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool DeviceIoControl + ( + SafeHandle hDevice, + IOCTL dwIoControlCode, + ref STORAGE_PROPERTY_QUERY lpInBuffer, + int nInBufferSize, + IntPtr lpOutBuffer, + uint nOutBufferSize, + out uint lpBytesReturned, + IntPtr lpOverlapped); + + [DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool DeviceIoControl + ( + SafeHandle hDevice, + IOCTL dwIoControlCode, + IntPtr lpInBuffer, + int nInBufferSize, + IntPtr lpOutBuffer, + int nOutBufferSize, + out uint lpBytesReturned, + IntPtr lpOverlapped); + + [DllImport(DllName, SetLastError = true)] + internal static extern void RtlZeroMemory(IntPtr Destination, int Length); + + [DllImport(DllName, EntryPoint = "CopyMemory", SetLastError = false)] + internal static extern void CopyMemory(IntPtr Destination, IntPtr Source, uint Length); + + [DllImport(DllName, SetLastError = true)] + internal static extern IntPtr LoadLibrary(string lpFileName); + [StructLayout(LayoutKind.Sequential)] - public struct StoragePropertyQuery { - public StoragePropertyId PropertyId; - public StorageQueryType QueryType; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x1)] + internal struct MEMORYSTATUSEX { + public uint dwLength; + public uint dwMemoryLoad; + public ulong ullTotalPhys; + public ulong ullAvailPhys; + public ulong ullTotalPageFile; + public ulong ullAvailPageFile; + public ulong ullTotalVirtual; + public ulong ullAvailVirtual; + public ulong ullAvailExtendedVirtual; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct SMART_ATTRIBUTE { + public byte Id; + public short Flags; + public byte CurrentValue; + public byte WorstValue; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public byte[] RawValue; + + public byte Reserved; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct SMART_THRESHOLD { + public byte Id; + public byte Threshold; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] + public byte[] Reserved; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + internal struct SENDCMDINPARAMS { + public uint cBufferSize; + public IDEREGS irDriveRegs; + public byte bDriveNumber; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public byte[] bReserved; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public uint[] dwReserved; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public byte[] bBuffer; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + internal struct IDEREGS { + public SMART_FEATURES bFeaturesReg; + public byte bSectorCountReg; + public byte bSectorNumberReg; + public byte bCylLowReg; + public byte bCylHighReg; + public byte bDriveHeadReg; + public ATA_COMMAND bCommandReg; + public byte bReserved; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + internal struct DRIVERSTATUS { + public byte bDriverError; + public byte bIDEError; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] + public byte[] Reserved; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + internal struct SENDCMDOUTPARAMS { + public uint cBufferSize; + public DRIVERSTATUS DriverStatus; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public byte[] bBuffer; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + internal struct ATTRIBUTECMDOUTPARAMS { + public uint cBufferSize; + public DRIVERSTATUS DriverStatus; + public byte Version; + public byte Reserved; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DRIVE_ATTRIBUTES)] + public SMART_ATTRIBUTE[] Attributes; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + internal struct THRESHOLDCMDOUTPARAMS { + public uint cBufferSize; + public DRIVERSTATUS DriverStatus; + public byte Version; + public byte Reserved; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DRIVE_ATTRIBUTES)] + public SMART_THRESHOLD[] Thresholds; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + internal struct IDENTIFY_DATA { + public ushort GeneralConfiguration; + public ushort NumberOfCylinders; + public ushort Reserved1; + public ushort NumberOfHeads; + public ushort UnformattedBytesPerTrack; + public ushort UnformattedBytesPerSector; + public ushort SectorsPerTrack; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public ushort[] VendorUnique; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] + public byte[] SerialNumber; + + public ushort BufferType; + public ushort BufferSectorSize; + public ushort NumberOfEccBytes; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] + public byte[] FirmwareRevision; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)] + public byte[] ModelNumber; + + public byte MaximumBlockTransfer; + public byte VendorUnique2; + public ushort DoubleWordIo; + public ushort Capabilities; + public ushort Reserved2; + public byte VendorUnique3; + public byte PioCycleTimingMode; + public byte VendorUnique4; + public byte DmaCycleTimingMode; + public ushort TranslationFieldsValid; + public ushort NumberOfCurrentCylinders; + public ushort NumberOfCurrentHeads; + public ushort CurrentSectorsPerTrack; + public uint CurrentSectorCapacity; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 197)] + public ushort[] Reserved3; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + internal struct IDENTIFYCMDOUTPARAMS { + public uint cBufferSize; + public DRIVERSTATUS DriverStatus; + public IDENTIFY_DATA Identify; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct STORAGE_PROPERTY_QUERY { + public STORAGE_PROPERTY_ID PropertyId; + public STORAGE_QUERY_TYPE QueryType; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] public byte[] AdditionalParameters; } - #endregion - #region StoragePropertyQuery1 [StructLayout(LayoutKind.Sequential)] - public struct StoragePropertyQuery1 { - public StoragePropertyId PropertyId; - public StorageQueryType QueryType; - } - #endregion - - #region StorageDescriptorHeader - [StructLayout(LayoutKind.Sequential)] - public struct StorageDescriptorHeader { + internal struct STORAGE_DEVICE_DESCRIPTOR_HEADER { public uint Version; public uint Size; } - #endregion - #region StorageDeviceDescriptor [StructLayout(LayoutKind.Sequential)] - public struct StorageDeviceDescriptor { + internal struct STORAGE_DEVICE_DESCRIPTOR { public uint Version; public uint Size; public byte DeviceType; public byte DeviceTypeModifier; + [MarshalAs(UnmanagedType.U1)] public bool RemovableMedia; + [MarshalAs(UnmanagedType.U1)] public bool CommandQueueing; + public uint VendorIdOffset; public uint ProductIdOffset; public uint ProductRevisionOffset; public uint SerialNumberOffset; - public StorageBusType BusType; + public STORAGE_BUS_TYPE BusType; public uint RawPropertiesLength; } - #endregion - #region NVMeCriticalWarning - [Flags] - public enum NVMeCriticalWarning { - None = 0x00, - AvailableSpaceLow = 0x01, // If set to 1, then the available spare space has fallen below the threshold. - TemperatureThreshold = 0x02, // If set to 1, then a temperature is above an over temperature threshold or below an under temperature threshold. - ReliabilityDegraded = 0x04, // If set to 1, then the device reliability has been degraded due to significant media related errors or any internal error that degrades device reliability. - ReadOnly = 0x08, // If set to 1, then the media has been placed in read only mode - VolatileMemoryBackupDeviceFailed = 0x10, // If set to 1, then the volatile memory backup device has failed. This field is only valid if the controller has a volatile memory backup solution. - } - #endregion - - #region Command - public enum Command : uint { - IOCTL_SCSI_PASS_THROUGH = 0x04d004, - IOCTL_SCSI_MINIPORT = 0x04d008, - IOCTL_SCSI_PASS_THROUGH_DIRECT = 0x04d014, - IOCTL_SCSI_GET_ADDRESS = 0x41018, - IOCTL_STORAGE_QUERY_PROPERTY = 0x2D1400, - } - #endregion - - #region NVMePassThroughOpcode - public enum NVMePassThroughOpcode : uint { - AdminGetLogPage = 0x02, - AdminIdentify = 0x06, - } - #endregion - - #region NVMePassThroughDirection - [Flags] - public enum NVMePassThroughDirection : uint { - None = 0, - Out = 1, - In = 2, - InOut = In | Out, - } - #endregion - - #region NVMePassThroughQueue - public enum NVMePassThroughQueue : uint { - AdminQ = 0, - } - #endregion - - #region SrbIoControl [StructLayout(LayoutKind.Sequential)] - public struct SrbIoControl { + internal struct SRB_IO_CONTROL { public uint HeaderLenght; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] Signature; + public uint Timeout; public uint ControlCode; public uint ReturnCode; public uint Length; } - #endregion - #region NVMePassThrough [StructLayout(LayoutKind.Sequential)] - public struct NVMePassThrough { - public SrbIoControl srb; + internal struct NVME_PASS_THROUGH_IOCTL { + public SRB_IO_CONTROL srb; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] public uint[] VendorSpecific; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public uint[] NVMeCmd; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public uint[] CplEntry; - public NVMePassThroughDirection Direction; - public NVMePassThroughQueue Queue; + + public NVME_DIRECTION Direction; + public uint QueueId; public uint DataBufferLen; public uint MetaDataLen; public uint ReturnBufferLen; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4096)] - public byte[] DataBuf; - } - #endregion - #region SCSI_PASS_THROUGH - /// - /// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/ntddscsi/ns-ntddscsi-_scsi_pass_through - /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4096)] + public byte[] DataBuffer; + } + [StructLayout(LayoutKind.Sequential)] - public struct SCSI_PASS_THROUGH { + internal struct SCSI_PASS_THROUGH { [MarshalAs(UnmanagedType.U2)] public ushort Length; + public byte ScsiStatus; public byte PathId; public byte TargetId; @@ -482,356 +609,226 @@ namespace OpenHardwareMonitor.Interop { public uint TimeOutValue; public IntPtr DataBufferOffset; public uint SenseInfoOffset; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] Cdb; } - #endregion - #region SPTWith512Buffer [StructLayout(LayoutKind.Sequential)] - public struct SPTWith512Buffer { + internal struct SCSI_PASS_THROUGH_WITH_BUFFERS { public SCSI_PASS_THROUGH Spt; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)] + public uint Filler; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] SenseBuf; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)] + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = SCSI_PASS_THROUGH_BUFFER_SIZE)] public byte[] DataBuf; } - #endregion - #region NVMePowerStateDesc [StructLayout(LayoutKind.Sequential)] - public struct NVMePowerStateDesc { - public ushort mp; // bit 0:15 Maximum Power (MP) in centiwatts + internal struct NVME_POWER_STATE_DESC { + public ushort MP; // bit 0:15 Maximum Power (MP) in centiwatts public byte Reserved0; // bit 16:23 - public byte mps_nops; // bit 24 Max Power Scale (MPS), bit 25 Non-Operational State (NOPS) - public uint enlat; // bit 32:63 Entry Latency (ENLAT) in microseconds - public uint exlat; // bit 64:95 Exit Latency (EXLAT) in microseconds - public byte rrt; // bit 96:100 Relative Read Throughput (RRT) - public byte rrl; // bit 104:108 Relative Read Latency (RRL) - public byte rwt; // bit 112:116 Relative Write Throughput (RWT) - public byte rwl; // bit 120:124 Relative Write Latency (RWL) - public ushort idlp; // bit 128:143 Idle Power (IDLP) - public byte ips; // bit 150:151 Idle Power Scale (IPS) + public byte MPS_NOPS; // bit 24 Max Power Scale (MPS), bit 25 Non-Operational State (NOPS) + public uint ENLAT; // bit 32:63 Entry Latency (ENLAT) in microseconds + public uint EXLAT; // bit 64:95 Exit Latency (EXLAT) in microseconds + public byte RRT; // bit 96:100 Relative Read Throughput (RRT) + public byte RRL; // bit 104:108 Relative Read Latency (RRL) + public byte RWT; // bit 112:116 Relative Write Throughput (RWT) + public byte RWL; // bit 120:124 Relative Write Latency (RWL) + public ushort IDLP; // bit 128:143 Idle Power (IDLP) + public byte IPS; // bit 150:151 Idle Power Scale (IPS) public byte Reserved7; // bit 152:159 - public ushort actp; // bit 160:175 Active Power (ACTP) - public byte apw_aps; // bit 176:178 Active Power Workload (APW), bit 182:183 Active Power Scale (APS) + public ushort ACTP; // bit 160:175 Active Power (ACTP) + public byte APW_APS; // bit 176:178 Active Power Workload (APW), bit 182:183 Active Power Scale (APS) + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 9)] public byte[] Reserved9; // bit 184:255. } - #endregion - #region NVMeIdentifyControllerData [StructLayout(LayoutKind.Sequential)] - public struct NVMeIdentifyControllerData { - public ushort vid; // byte 0:1 M - PCI Vendor ID (VID) - public ushort ssvid; // byte 2:3 M - PCI Subsystem Vendor ID (SSVID) + internal struct NVME_IDENTIFY_CONTROLLER_DATA { + public ushort VID; // byte 0:1 M - PCI Vendor ID (VID) + public ushort SSVID; // byte 2:3 M - PCI Subsystem Vendor ID (SSVID) + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] - public byte[] sn; // byte 4: 23 M - Serial Number (SN) + public byte[] SN; // byte 4: 23 M - Serial Number (SN) + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)] - public byte[] mn; // byte 24:63 M - Model Number (MN) + public byte[] MN; // byte 24:63 M - Model Number (MN) + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] - public byte[] fr; // byte 64:71 M - Firmware Revision (FR) - public byte rab; // byte 72 M - Recommended Arbitration Burst (RAB) + public byte[] FR; // byte 64:71 M - Firmware Revision (FR) + + public byte RAB; // byte 72 M - Recommended Arbitration Burst (RAB) + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] - public byte[] ieee; // byte 73:75 M - IEEE OUI Identifier (IEEE). Controller Vendor code. - public byte cmic; // byte 76 O - Controller Multi-Path I/O and Namespace Sharing Capabilities (CMIC) - public byte mdts; // byte 77 M - Maximum Data Transfer Size (MDTS) - public ushort cntlid; // byte 78:79 M - Controller ID (CNTLID) - public uint ver; // byte 80:83 M - Version (VER) - public uint rtd3r; // byte 84:87 M - RTD3 Resume Latency (RTD3R) - public uint rtd3e; // byte 88:91 M - RTD3 Entry Latency (RTD3E) - public uint oaes; // byte 92:95 M - Optional Asynchronous Events Supported (OAES) + public byte[] IEEE; // byte 73:75 M - IEEE OUI Identifier (IEEE). Controller Vendor code. + + public byte CMIC; // byte 76 O - Controller Multi-Path I/O and Namespace Sharing Capabilities (CMIC) + public byte MDTS; // byte 77 M - Maximum Data Transfer Size (MDTS) + public ushort CNTLID; // byte 78:79 M - Controller ID (CNTLID) + public uint VER; // byte 80:83 M - Version (VER) + public uint RTD3R; // byte 84:87 M - RTD3 Resume Latency (RTD3R) + public uint RTD3E; // byte 88:91 M - RTD3 Entry Latency (RTD3E) + public uint OAES; // byte 92:95 M - Optional Asynchronous Events Supported (OAES) + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 144)] public byte[] Reserved0; // byte 96:239. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] ReservedForManagement; // byte 240:255. Refer to the NVMe Management Interface Specification for definition. - public ushort oacs; // byte 256:257 M - Optional Admin Command Support (OACS) - public byte acl; // byte 258 M - Abort Command Limit (ACL) - public byte aerl; // byte 259 M - Asynchronous Event Request Limit (AERL) - public byte frmw; // byte 260 M - Firmware Updates (FRMW) - public byte lpa; // byte 261 M - Log Page Attributes (LPA) - public byte elpe; // byte 262 M - Error Log Page Entries (ELPE) - public byte npss; // byte 263 M - Number of Power States Support (NPSS) - public byte avscc; // byte 264 M - Admin Vendor Specific Command Configuration (AVSCC) - public byte apsta; // byte 265 O - Autonomous Power State Transition Attributes (APSTA) - public ushort wctemp; // byte 266:267 M - Warning Composite Temperature Threshold (WCTEMP) - public ushort cctemp; // byte 268:269 M - Critical Composite Temperature Threshold (CCTEMP) - public ushort mtfa; // byte 270:271 O - Maximum Time for Firmware Activation (MTFA) - public uint hmpre; // byte 272:275 O - Host Memory Buffer Preferred Size (HMPRE) - public uint hmmin; // byte 276:279 O - Host Memory Buffer Minimum Size (HMMIN) + + public ushort OACS; // byte 256:257 M - Optional Admin Command Support (OACS) + public byte ACL; // byte 258 M - Abort Command Limit (ACL) + public byte AERL; // byte 259 M - Asynchronous Event Request Limit (AERL) + public byte FRMW; // byte 260 M - Firmware Updates (FRMW) + public byte LPA; // byte 261 M - Log Page Attributes (LPA) + public byte ELPE; // byte 262 M - Error Log Page Entries (ELPE) + public byte NPSS; // byte 263 M - Number of Power States Support (NPSS) + public byte AVSCC; // byte 264 M - Admin Vendor Specific Command Configuration (AVSCC) + public byte APSTA; // byte 265 O - Autonomous Power State Transition Attributes (APSTA) + public ushort WCTEMP; // byte 266:267 M - Warning Composite Temperature Threshold (WCTEMP) + public ushort CCTEMP; // byte 268:269 M - Critical Composite Temperature Threshold (CCTEMP) + public ushort MTFA; // byte 270:271 O - Maximum Time for Firmware Activation (MTFA) + public uint HMPRE; // byte 272:275 O - Host Memory Buffer Preferred Size (HMPRE) + public uint HMMIN; // byte 276:279 O - Host Memory Buffer Minimum Size (HMMIN) + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] - public byte[] tnvmcap; // byte 280:295 O - Total NVM Capacity (TNVMCAP) + public byte[] TNVMCAP; // byte 280:295 O - Total NVM Capacity (TNVMCAP) + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] - public byte[] unvmcap; // byte 296:311 O - Unallocated NVM Capacity (UNVMCAP) - public uint rpmbs; // byte 312:315 O - Replay Protected Memory Block Support (RPMBS) + public byte[] UNVMCAP; // byte 296:311 O - Unallocated NVM Capacity (UNVMCAP) + + public uint RPMBS; // byte 312:315 O - Replay Protected Memory Block Support (RPMBS) + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 196)] public byte[] Reserved1; // byte 316:511 - public byte sqes; // byte 512 M - Submission Queue Entry Size (SQES) - public byte cqes; // byte 513 M - Completion Queue Entry Size (CQES) + + public byte SQES; // byte 512 M - Submission Queue Entry Size (SQES) + public byte CQES; // byte 513 M - Completion Queue Entry Size (CQES) + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public byte[] Reserved2; // byte 514:515 - public uint nn; // byte 516:519 M - Number of Namespaces (NN) - public ushort oncs; // byte 520:521 M - Optional NVM Command Support (ONCS) - public ushort fuses; // byte 522:523 M - Fused Operation Support (FUSES) - public byte fna; // byte 524 M - Format NVM Attributes (FNA) - public byte vwc; // byte 525 M - Volatile Write Cache (VWC) - public ushort awun; // byte 526:527 M - Atomic Write Unit Normal (AWUN) - public ushort awupf; // byte 528:529 M - Atomic Write Unit Power Fail (AWUPF) - public byte nvscc; // byte 530 M - NVM Vendor Specific Command Configuration (NVSCC) + + public uint NN; // byte 516:519 M - Number of Namespaces (NN) + public ushort ONCS; // byte 520:521 M - Optional NVM Command Support (ONCS) + public ushort FUSES; // byte 522:523 M - Fused Operation Support (FUSES) + public byte FNA; // byte 524 M - Format NVM Attributes (FNA) + public byte VWC; // byte 525 M - Volatile Write Cache (VWC) + public ushort AWUN; // byte 526:527 M - Atomic Write Unit Normal (AWUN) + public ushort AWUPF; // byte 528:529 M - Atomic Write Unit Power Fail (AWUPF) + public byte NVSCC; // byte 530 M - NVM Vendor Specific Command Configuration (NVSCC) public byte Reserved3; // byte 531 - public ushort acwu; // byte 532:533 O - Atomic Compare & Write Unit (ACWU) + public ushort ACWU; // byte 532:533 O - Atomic Compare & Write Unit (ACWU) + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public byte[] Reserved4; // byte 534:535 - public uint sgls; // byte 536:539 O - SGL Support (SGLS) + + public uint SGLS; // byte 536:539 O - SGL Support (SGLS) + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 164)] public byte[] Reserved5; // byte 540:703 + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1344)] public byte[] Reserved6; // byte 704:2047 + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] - public NVMePowerStateDesc[] pds; // byte 2048:3071 Power State Descriptors + public NVME_POWER_STATE_DESC[] PDS; // byte 2048:3071 Power State Descriptors + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1024)] - public byte[] vs; // byte 3072:4095 Vendor Specific + public byte[] VS; // byte 3072:4095 Vendor Specific } - #endregion - #region NVMeLBAFormat [StructLayout(LayoutKind.Sequential)] - public struct NVMeLBAFormat { - public ushort ms; // bit 0:15 Metadata Size (MS) - public byte lbads; // bit 16:23 LBA Data Size (LBADS) - public byte rp; // bit 24:25 Relative Performance (RP) - } - #endregion - - #region NVMeHealthInfoLog - [StructLayout(LayoutKind.Sequential)] - public struct NVMeHealthInfoLog { + internal struct NVME_HEALTH_INFO_LOG { public byte CriticalWarning; // This field indicates critical warnings for the state of the controller. Each bit corresponds to a critical warning type; multiple bits may be set. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] - public byte[] CompositeTemperature; // Composite Temperature: Contains the temperature of the overall device (controller and NVM included) in units of Kelvin. + public byte[] CompositeTemp; // Composite Temperature: Contains the temperature of the overall device (controller and NVM included) in units of Kelvin. + public byte AvailableSpare; // Available Spare: Contains a normalized percentage (0 to 100%) of the remaining spare capacity available - public byte AvailableSpareThreshold; // Available Spare Threshold: When the Available Spare falls below the threshold indicated in this field, an asynchronous event completion may occur. The value is indicated as a normalized percentage (0 to 100%). - public byte PercentageUsed; // Percentage Used: Contains a vendor specific estimate of the percentage of NVM subsystem life used based on the actual usage and the manufacturer’s prediction of NVM life. A value of 100 indicates that the estimated endurance of the NVM in the NVM subsystem has been consumed, but may not indicate an NVM subsystem failure. The value is allowed to exceed 100. + + public byte + AvailableSpareThreshold; // Available Spare Threshold: When the Available Spare falls below the threshold indicated in this field, an asynchronous event completion may occur. The value is indicated as a normalized percentage (0 to 100%). + + public byte + PercentageUsed; // Percentage Used: Contains a vendor specific estimate of the percentage of NVM subsystem life used based on the actual usage and the manufacturer’s prediction of NVM life. A value of 100 indicates that the estimated endurance of the NVM in the NVM subsystem has been consumed, but may not indicate an NVM subsystem failure. The value is allowed to exceed 100. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 26)] - public byte[] Reserved0; + public byte[] Reserved1; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] - public byte[] DataUnitRead; // Data Units Read: Contains the number of 512 byte data units the host has read from the controller; this value does not include metadata. This value is reported in thousands (i.e., a value of 1 corresponds to 1000 units of 512 bytes read) and is rounded up. + public byte[] + DataUnitRead; // Data Units Read: Contains the number of 512 byte data units the host has read from the controller; this value does not include metadata. This value is reported in thousands (i.e., a value of 1 corresponds to 1000 units of 512 bytes read) and is rounded up. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] - public byte[] DataUnitWritten; // Data Units Written: Contains the number of 512 byte data units the host has written to the controller; this value does not include metadata. This value is reported in thousands (i.e., a value of 1 corresponds to 1000 units of 512 bytes written) and is rounded up. + public byte[] + DataUnitWritten; // Data Units Written: Contains the number of 512 byte data units the host has written to the controller; this value does not include metadata. This value is reported in thousands (i.e., a value of 1 corresponds to 1000 units of 512 bytes written) and is rounded up. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] - public byte[] HostReadCommands; // Host Read Commands: Contains the number of read commands completed by the controller. For the NVM command set, this is the number of Compare and Read commands. + public byte[] + HostReadCommands; // Host Read Commands: Contains the number of read commands completed by the controller. For the NVM command set, this is the number of Compare and Read commands. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] HostWriteCommands; // Host Write Commands: Contains the number of write commands completed by the controller. For the NVM command set, this is the number of Write commands. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] ControllerBusyTime; // Controller Busy Time: Contains the amount of time the controller is busy with I/O commands. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] - public byte[] PowerCycle; // Power Cycles: Contains the number of power cycles. + public byte[] PowerCycles; // Power Cycles: Contains the number of power cycles. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] PowerOnHours; // Power On Hours: Contains the number of power-on hours. This does not include time that the controller was powered and in a low power state condition. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] UnsafeShutdowns; // Unsafe Shutdowns: Contains the number of unsafe shutdowns. This count is incremented when a shutdown notification is not received prior to loss of power. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] - public byte[] MediaErrors; // Media Errors: Contains the number of occurrences where the controller detected an unrecovered data integrity error. Errors such as uncorrectable ECC, CRC checksum failure, or LBA tag mismatch are included in this field. + public byte[] + MediaAndDataIntegrityErrors; // Media Errors: Contains the number of occurrences where the controller detected an unrecoverable data integrity error. Errors such as uncorrectable ECC, CRC checksum failure, or LBA tag mismatch are included in this field. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] - public byte[] ErrorInfoLogEntryCount; // Number of Error Information Log Entries: Contains the number of Error Information log entries over the life of the controller - public uint WarningCompositeTemperatureTime; // Warning Composite Temperature Time: Contains the amount of time in minutes that the controller is operational and the Composite Temperature is greater than or equal to the Warning Composite Temperature Threshold. - public uint CriticalCompositeTemperatureTime; // Critical Composite Temperature Time: Contains the amount of time in minutes that the controller is operational and the Composite Temperature is greater than the Critical Composite Temperature Threshold. + public byte[] NumberErrorInformationLogEntries; // Number of Error Information Log Entries: Contains the number of Error Information log entries over the life of the controller + + public uint + WarningCompositeTemperatureTime; // Warning Composite Temperature Time: Contains the amount of time in minutes that the controller is operational and the Composite Temperature is greater than or equal to the Warning Composite Temperature Threshold. + + public uint + CriticalCompositeTemperatureTime; // Critical Composite Temperature Time: Contains the amount of time in minutes that the controller is operational and the Composite Temperature is greater than the Critical Composite Temperature Threshold. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] - public ushort[] TemperatureSensors; // Contains the current temperature reported by temperature sensor 1-8. + public ushort[] TemperatureSensor; // Contains the current temperature reported by temperature sensor 1-8. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 296)] - public byte[] Reserved1; + internal byte[] Reserved2; } - #endregion - #region StorageProtocolNVMeDataType - public enum StorageProtocolNVMeDataType { - NVMeDataTypeUnknown = 0, - NVMeDataTypeIdentify, - NVMeDataTypeLogPage, - NVMeDataTypeFeature, - } - #endregion - - #region TStroageProtocolType - public enum TStroageProtocolType { - ProtocolTypeUnknown = 0x00, - ProtocolTypeScsi, - ProtocolTypeAta, - ProtocolTypeNvme, - ProtocolTypeSd, - ProtocolTypeProprietary = 0x7E, - ProtocolTypeMaxReserved = 0x7F - } - #endregion - - #region NVME_LOG_PAGES - public enum NVME_LOG_PAGES { - NVME_LOG_PAGE_ERROR_INFO = 0x01, - NVME_LOG_PAGE_HEALTH_INFO = 0x02, - NVME_LOG_PAGE_FIRMWARE_SLOT_INFO = 0x03, - NVME_LOG_PAGE_CHANGED_NAMESPACE_LIST = 0x04, - NVME_LOG_PAGE_COMMAND_EFFECTS = 0x05, - NVME_LOG_PAGE_DEVICE_SELF_TEST = 0x06, - NVME_LOG_PAGE_TELEMETRY_HOST_INITIATED = 0x07, - NVME_LOG_PAGE_TELEMETRY_CTLR_INITIATED = 0x08, - NVME_LOG_PAGE_RESERVATION_NOTIFICATION = 0x80, - NVME_LOG_PAGE_SANITIZE_STATUS = 0x81, - } - #endregion - - #region StorageProtocolSpecificData [StructLayout(LayoutKind.Sequential)] - public struct StorageProtocolSpecificData { - public TStroageProtocolType ProtocolType; + internal struct STORAGE_PROTOCOL_SPECIFIC_DATA { + public STORAGE_PROTOCOL_TYPE ProtocolType; public uint DataType; public uint ProtocolDataRequestValue; public uint ProtocolDataRequestSubValue; public uint ProtocolDataOffset; public uint ProtocolDataLength; public uint FixedProtocolReturnData; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] - public uint[] Reserved; + public uint ProtocolDataRequestSubValue2; + public uint ProtocolDataRequestSubValue3; + public uint Reserved; } - #endregion - #region StorageQueryWithBuffer [StructLayout(LayoutKind.Sequential)] - public struct StorageQueryWithBuffer { - public StoragePropertyQuery1 Query; - public StorageProtocolSpecificData ProtocolSpecific; + internal struct STORAGE_QUERY_BUFFER { + public STORAGE_PROPERTY_ID PropertyId; + public STORAGE_QUERY_TYPE QueryType; + public STORAGE_PROTOCOL_SPECIFIC_DATA ProtocolSpecific; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4096)] - public byte[] Buffer; + internal byte[] Buffer; } - #endregion - - #region PhysicalPathToSCSIPath - public static string PhysicalPathToSCSIPath(SafeHandle pysicalDeviceHandle) { - string result = string.Empty; - uint bytesReturned = 0; - int length = (int)Marshal.SizeOf(typeof(SCSI_ADDRESS)); - IntPtr pBuffer = Marshal.AllocHGlobal(length); - bool valid = DeviceIoControl(pysicalDeviceHandle, Command.IOCTL_SCSI_GET_ADDRESS, IntPtr.Zero, 0, pBuffer, length, out bytesReturned, IntPtr.Zero); - if (valid) { - var item = Marshal.PtrToStructure(pBuffer); - result = string.Format(@"\\.\SCSI{0}:", item.PortNumber); - } - Marshal.FreeHGlobal(pBuffer); - return result; - } - #endregion - - #region CreateStruct - /// - /// CreateStruct - /// create a instance from a struct with zero initilized memory arrays - /// no need to init every inner array with the correct sizes - /// - /// type of struct that is needed - /// - public static T CreateStruct() { - int size = Marshal.SizeOf(); - var ptr = Marshal.AllocHGlobal(size); - RtlZeroMemory(ptr, size); - T result = Marshal.PtrToStructure(ptr); - Marshal.FreeHGlobal(ptr); - return result; - } - #endregion - - #region OpenDevice - public static SafeHandle OpenDevice(string deivcePath) { - SafeHandle hDevice = null; - hDevice = CreateFile(deivcePath, FileAccess.ReadWrite, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, FileAttributes.Normal, IntPtr.Zero); - if (hDevice.IsInvalid || hDevice.IsClosed) - hDevice = null; - return hDevice; - } - #endregion - - #region WIN32 - - [DllImport(KERNEL, CharSet = CharSet.Auto, SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool GlobalMemoryStatusEx(ref MemoryStatusEx buffer); - - [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)] - public static extern SafeFileHandle CreateFile( - [MarshalAs(UnmanagedType.LPTStr)] string filename, - [MarshalAs(UnmanagedType.U4)] FileAccess access, - [MarshalAs(UnmanagedType.U4)] FileShare share, - IntPtr securityAttributes, - [MarshalAs(UnmanagedType.U4)] FileMode creationDisposition, - [MarshalAs(UnmanagedType.U4)]FileAttributes flagsAndAttributes, - IntPtr templateFile); - - [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)] - [return: MarshalAsAttribute(UnmanagedType.Bool)] - public static extern bool DeviceIoControl( - SafeHandle handle, - DriveCommand command, ref DriveCommandParameter parameter, - int parameterSize, out DriveSmartReadDataResult result, int resultSize, - out uint bytesReturned, IntPtr overlapped); - - [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)] - [return: MarshalAsAttribute(UnmanagedType.Bool)] - public static extern bool DeviceIoControl( - SafeHandle handle, - DriveCommand command, ref DriveCommandParameter parameter, - int parameterSize, out DriveSmartReadThresholdsResult result, - int resultSize, out uint bytesReturned, IntPtr overlapped); - - [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)] - [return: MarshalAsAttribute(UnmanagedType.Bool)] - public static extern bool DeviceIoControl( - SafeHandle handle, - DriveCommand command, ref DriveCommandParameter parameter, - int parameterSize, out DriveCommandResult result, int resultSize, - out uint bytesReturned, IntPtr overlapped); - - [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)] - [return: MarshalAsAttribute(UnmanagedType.Bool)] - public static extern bool DeviceIoControl( - SafeHandle handle, - DriveCommand command, ref DriveCommandParameter parameter, - int parameterSize, out DriveIdentifyResult result, int resultSize, - out uint bytesReturned, IntPtr overlapped); - - - [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool DeviceIoControl( - SafeHandle handle, StorageCommand command, - ref StoragePropertyQuery query, int querySize, - out StorageDescriptorHeader descriptorHeader, - int descriptorHeaderSize, - out uint bytesReturned, IntPtr overlapped); - - [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi, - CharSet = CharSet.Auto, SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool DeviceIoControl( - SafeHandle handle, StorageCommand command, - ref StoragePropertyQuery query, int querySize, - IntPtr descriptor, uint descriptorSize, - out uint bytesReturned, IntPtr overlapped); - - [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)] - [return: MarshalAsAttribute(UnmanagedType.Bool)] - public static extern bool DeviceIoControl(SafeHandle handle, - Command command, IntPtr dataIn, int dataInSize, - IntPtr dataOut, int dataOutSize, out uint bytesReturned, - IntPtr overlapped); - - [DllImport(KERNEL, SetLastError = true)] - public static extern void RtlZeroMemory(IntPtr dst, int length); - - [DllImport(KERNEL, EntryPoint = "CopyMemory", SetLastError = false)] - public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count); - - [DllImport(KERNEL)] - public static extern uint GetLastError(); - - #endregion } } \ No newline at end of file diff --git a/OpenHardwareMonitorLib.csproj b/OpenHardwareMonitorLib.csproj index b046155..f661a61 100644 --- a/OpenHardwareMonitorLib.csproj +++ b/OpenHardwareMonitorLib.csproj @@ -41,7 +41,7 @@ - + diff --git a/Software/OperatingSystem.cs b/Software/OperatingSystem.cs index 87104c3..b560241 100644 --- a/Software/OperatingSystem.cs +++ b/Software/OperatingSystem.cs @@ -1,5 +1,4 @@ using System; -using System.Diagnostics; using System.Runtime.InteropServices; namespace OpenHardwareMonitor.Software {