Advertisement
shornby

HD SMART Lookup For Windows via (native) WMI and NET.cs

May 4th, 2013
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.79 KB | None | 0 0
  1. // (c) Microsoft Corporation
  2. // Author: Clemens Vasters (clemensv@microsoft.com)
  3. // Code subject to MS-PL: http://opensource.org/licenses/ms-pl.html
  4. // SMART Attributes and Background: http://en.wikipedia.org/wiki/S.M.A.R.T.
  5. // SMART Attributes Overview: http://www.t13.org/Documents/UploadedDocuments/docs2005/e05171r0-ACS-SMARTAttributes_Overview.pdf
  6.  
  7. namespace SmartDataApp
  8. {
  9.     using System;
  10.     using System.Collections.Generic;
  11.     using System.Management;
  12.     using System.Runtime.InteropServices;
  13.  
  14.     public enum SmartAttributeType : byte
  15.     {
  16.         ReadErrorRate = 0x01,
  17.         ThroughputPerformance = 0x02,
  18.         SpinUpTime = 0x03,
  19.         StartStopCount = 0x04,
  20.         ReallocatedSectorsCount = 0x05,
  21.         ReadChannelMargin = 0x06,
  22.         SeekErrorRate = 0x07,
  23.         SeekTimePerformance = 0x08,
  24.         PowerOnHoursPOH = 0x09,
  25.         SpinRetryCount = 0x0A,
  26.         CalibrationRetryCount = 0x0B,
  27.         PowerCycleCount = 0x0C,
  28.         SoftReadErrorRate = 0x0D,
  29.         SATADownshiftErrorCount = 0xB7,
  30.         EndtoEnderror = 0xB8,
  31.         HeadStability = 0xB9,
  32.         InducedOpVibrationDetection = 0xBA,
  33.         ReportedUncorrectableErrors = 0xBB,
  34.         CommandTimeout = 0xBC,
  35.         HighFlyWrites = 0xBD,
  36.         AirflowTemperatureWDC = 0xBE,
  37.         TemperatureDifferencefrom100 = 0xBE,
  38.         GSenseErrorRate = 0xBF,
  39.         PoweroffRetractCount = 0xC0,
  40.         LoadCycleCount = 0xC1,
  41.         Temperature = 0xC2,
  42.         HardwareECCRecovered = 0xC3,
  43.         ReallocationEventCount = 0xC4,
  44.         CurrentPendingSectorCount = 0xC5,
  45.         UncorrectableSectorCount = 0xC6,
  46.         UltraDMACRCErrorCount = 0xC7,
  47.         MultiZoneErrorRate = 0xC8,
  48.         WriteErrorRateFujitsu = 0xC8,
  49.         OffTrackSoftReadErrorRate = 0xC9,
  50.         DataAddressMarkerrors = 0xCA,
  51.         RunOutCancel = 0xCB,
  52.         SoftECCCorrection = 0xCC,
  53.         ThermalAsperityRateTAR = 0xCD,
  54.         FlyingHeight = 0xCE,
  55.         SpinHighCurrent = 0xCF,
  56.         SpinBuzz = 0xD0,
  57.         OfflineSeekPerformance = 0xD1,
  58.         VibrationDuringWrite = 0xD3,
  59.         ShockDuringWrite = 0xD4,
  60.         DiskShift = 0xDC,
  61.         GSenseErrorRateAlt = 0xDD,
  62.         LoadedHours = 0xDE,
  63.         LoadUnloadRetryCount = 0xDF,
  64.         LoadFriction = 0xE0,
  65.         LoadUnloadCycleCount = 0xE1,
  66.         LoadInTime = 0xE2,
  67.         TorqueAmplificationCount = 0xE3,
  68.         PowerOffRetractCycle = 0xE4,
  69.         GMRHeadAmplitude = 0xE6,
  70.         DriveTemperature = 0xE7,
  71.         HeadFlyingHours = 0xF0,
  72.         TransferErrorRateFujitsu = 0xF0,
  73.         TotalLBAsWritten = 0xF1,
  74.         TotalLBAsRead = 0xF2,
  75.         ReadErrorRetryRate = 0xFA,
  76.         FreeFallProtection = 0xFE,
  77.     }
  78.  
  79.     public class SmartData
  80.     {
  81.         readonly Dictionary<SmartAttributeType, SmartAttribute> attributes;
  82.         readonly ushort structureVersion;
  83.  
  84.         public SmartData(byte[] arrVendorSpecific)
  85.         {
  86.             attributes = new Dictionary<SmartAttributeType, SmartAttribute>();
  87.             for (int offset = 2; offset < arrVendorSpecific.Length; )
  88.             {
  89.                 var a = FromBytes<SmartAttribute>(arrVendorSpecific, ref offset, 12);
  90.                 // Attribute values 0x00, 0xfe, 0xff are invalid
  91.                 if (a.AttributeType != 0x00 && (byte)a.AttributeType != 0xfe && (byte)a.AttributeType != 0xff)
  92.                 {
  93.                     attributes[a.AttributeType] = a;
  94.                 }
  95.             }
  96.             structureVersion = (ushort)(arrVendorSpecific[0] * 256 + arrVendorSpecific[1]);
  97.         }
  98.  
  99.         public ushort StructureVersion
  100.         {
  101.             get
  102.             {
  103.                 return this.structureVersion;
  104.             }
  105.         }
  106.  
  107.         public SmartAttribute this[SmartAttributeType v]
  108.         {
  109.             get
  110.             {
  111.                 return this.attributes[v];
  112.             }
  113.         }
  114.  
  115.         public IEnumerable<SmartAttribute> Attributes
  116.         {
  117.             get
  118.             {
  119.                 return this.attributes.Values;
  120.             }
  121.         }
  122.  
  123.         static T FromBytes<T>(byte[] bytearray, ref int offset, int count)
  124.         {
  125.             IntPtr ptr = IntPtr.Zero;
  126.  
  127.             try
  128.             {
  129.                 ptr = Marshal.AllocHGlobal(count);
  130.                 Marshal.Copy(bytearray, offset, ptr, count);
  131.                 offset += count;
  132.                 return (T)Marshal.PtrToStructure(ptr, typeof(T));
  133.             }
  134.             finally
  135.             {
  136.                 if (ptr != IntPtr.Zero)
  137.                 {
  138.                     Marshal.FreeHGlobal(ptr);
  139.                 }
  140.             }
  141.         }
  142.     }
  143.  
  144.     [StructLayout(LayoutKind.Sequential)]
  145.     public struct SmartAttribute
  146.     {
  147.         public SmartAttributeType AttributeType;
  148.         public ushort Flags;
  149.         public byte Value;
  150.         [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
  151.         public byte[] VendorData;
  152.  
  153.         public bool Advisory
  154.         {
  155.             get
  156.             {
  157.                 return (Flags & 0x1) == 0x0; // Bit 0 unset?
  158.             }
  159.         }
  160.         public bool FailureImminent
  161.         {
  162.             get
  163.             {
  164.                 return (Flags & 0x1) == 0x1; // Bit 0 set?
  165.             }
  166.         }
  167.         public bool OnlineDataCollection
  168.         {
  169.             get
  170.             {
  171.                 return (Flags & 0x2) == 0x2; // Bit 0 set?
  172.             }
  173.         }
  174.  
  175.     }
  176.  
  177.     public class Program
  178.     {
  179.         public static void Main()
  180.         {
  181.             try
  182.             {
  183.                 var searcher = new ManagementObjectSearcher("root\\WMI", "SELECT * FROM MSStorageDriver_ATAPISmartData");
  184.  
  185.                 foreach (ManagementObject queryObj in searcher.Get())
  186.                 {
  187.                     Console.WriteLine("-----------------------------------");
  188.                     Console.WriteLine("MSStorageDriver_ATAPISmartData instance");
  189.                     Console.WriteLine("-----------------------------------");
  190.  
  191.                     var arrVendorSpecific = (byte[])queryObj.GetPropertyValue("VendorSpecific");
  192.  
  193.                     // Create SMART data from 'vendor specific' array
  194.                     var d = new SmartData(arrVendorSpecific);
  195.                     foreach (var b in d.Attributes)
  196.                     {
  197.                         Console.Write("{0} :{1} : ", b.AttributeType, b.Value);
  198.                         foreach (byte vendorByte in b.VendorData)
  199.                         {
  200.                             Console.Write("{0:x} ", vendorByte);
  201.                         }
  202.                         Console.WriteLine();
  203.                     }
  204.  
  205.                 }
  206.             }
  207.             catch (ManagementException e)
  208.             {
  209.                 Console.WriteLine("An error occurred while querying for WMI data: " + e.Message);
  210.             }
  211.         }
  212.     }
  213. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement