In an attempt to develop a hard disk analytic tool, I'm trying to get the value of Load/Unload cycle count from my hard disk's S.M.A.R.T data, I'm wondering if anyone knows how to do this. What I'm trying:
MSStorageDriver_ATAPISmartData
class data where attribute number 193 is what i need (the attribute representing load/unload cycle count)I think I'm close, the data in red is the same as what Everest Home edition is showing when i run it, ideally i would want the last part which is (attribute called data)
Method for collecting this data:
static void doStuff()
{
try
{
byte TEMPERATURE_ATTRIBUTE = 193;
ManagementObjectSearcher searcher = new ManagementObjectSearcher(@"\root\WMI", "SELECT * FROM MSStorageDriver_ATAPISmartData");
//loop through all the hard disks
foreach (ManagementObject queryObj in searcher.Get())
{
byte[] arrVendorSpecific = (byte[])queryObj.GetPropertyValue("VendorSpecific");
int tempIndex = Array.IndexOf(arrVendorSpecific, TEMPERATURE_ATTRIBUTE);
Console.WriteLine("HDD TEMP: " + arrVendorSpecific[tempIndex + 5].ToString());
foreach (byte dat in arrVendorSpecific)
{
Console.Write(dat.ToString() + " ");
}
}
}
catch (Exception err) { Console.WriteLine(err.Message); }
}
P.S. this method works for collecting the HDD's temperature (that's what the Console.WriteLine("HDD TEMP: " + arrVendorSpecific[tempIndex + 5].ToString());
line is all about but I'm not sure why its tempIndex+5
The code which you are using is not correct, because you are using a secuencial search (Array.IndexOf) to find the S.M.A.R.T Attribute ID
(you can have false positives because that value can match with another in the array), the ID of these attibutes has an fixed position inside of an documented structure (SMART Attribute Overview
).
SMART Attribute Table
Offset Length Description
(bytes)
0 2 SMART structure version (this is vendor-specific)
2 12 Attribute entry 1
2+(12) 12 Attribute entry 2
. . .
2+(12*29) 12 Attribute entry 30
Entry in the Attribute Table
from here you can write a code to search the location of each attribute and get the values which you are looking for
using System;
using System.Collections.Generic;
using System.Management;
using System.Text;
using System.Runtime.InteropServices;
namespace GetWMI_Info
{
class Program
{
[StructLayout(LayoutKind.Sequential)]
public struct Attribute
{
public byte AttributeID;
public ushort Flags;
public byte Value;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] VendorData;
}
static void Main(string[] args)
{
try
{
Attribute AtributeInfo;
ManagementScope Scope = new ManagementScope(String.Format("\\\\{0}\\root\\WMI", "localhost"), null);
Scope.Connect();
ObjectQuery Query = new ObjectQuery("SELECT VendorSpecific FROM MSStorageDriver_ATAPISmartData");
ManagementObjectSearcher Searcher = new ManagementObjectSearcher(Scope, Query);
byte LoadCycleCount = 0xC1;
int Delta = 12;
foreach (ManagementObject WmiObject in Searcher.Get())
{
byte[] VendorSpecific = (byte[])WmiObject["VendorSpecific"];
for (int offset = 2; offset < VendorSpecific.Length; )
{
if (VendorSpecific[offset] == LoadCycleCount)
{
IntPtr buffer = IntPtr.Zero;
try
{
buffer = Marshal.AllocHGlobal(Delta);
Marshal.Copy(VendorSpecific, offset, buffer, Delta);
AtributeInfo = (Attribute)Marshal.PtrToStructure(buffer, typeof(Attribute));
Console.WriteLine("AttributeID {0}", AtributeInfo.AttributeID);
Console.WriteLine("Flags {0}", AtributeInfo.Flags);
Console.WriteLine("Value {0}", AtributeInfo.Value);
Console.WriteLine("Value {0}", BitConverter.ToString(AtributeInfo.VendorData));
}
finally
{
if (buffer != IntPtr.Zero)
{
Marshal.FreeHGlobal(buffer);
}
}
}
offset += Delta;
}
}
}
catch (Exception e)
{
Console.WriteLine(String.Format("Exception {0} Trace {1}",e.Message,e.StackTrace));
}
Console.WriteLine("Press Enter to exit");
Console.Read();
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With