VB.NET-Tipp 0093: S.M.A.R.T-Werte der Festplatten auslesen
von ZoNeNjUnGe
Beschreibung
Mit der Self-Monitoring, Analysis and Reporting Technology (SMART) ist es möglich allerlei Kennzahlen der Festplatte auszulesen, welche dazu verwendet werden können vor drohendem Datenverlust zu warnen. Dieser Tipp demonstriert, wie die entsprechenden Werte ausgelesen werden können. Dabei ist die Auswertung der 8 Byte Daten herstellerspezifisch und hier an Samsung-Festplatten orientiert.
Zur Ausführung werden Administratorrechte benötigt!
Schwierigkeitsgrad: | Framework-Version(en): .NET Framework 1.1, .NET Framework 2.0, .NET Framework 3.0, .NET Framework 3.5 | .NET-Version(en): Visual Basic 2003, Visual Basic 2005, Visual Basic 2008 | Download: |
' Dieser Quellcode stammt von http://www.activevb.de ' und kann frei verwendet werden. Für eventuelle Schäden ' wird nicht gehaftet. ' Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum. ' Ansonsten viel Spaß und Erfolg mit diesem Source! ' Projektversion: Visual Studio 2005 ' ' Referenzen: ' - System ' - System.Data ' - System.Deployment ' - System.Drawing ' - System.Windows.Forms ' - System.Xml ' ' Imports: ' - Microsoft.VisualBasic ' - System ' - System.Collections ' - System.Collections.Generic ' - System.Data ' - System.Drawing ' - System.Diagnostics ' - System.Windows.Forms ' ' ############################################################################## ' ################################# Smart.vb ################################### ' ############################################################################## Imports System.Runtime.InteropServices Public Module Smart Public Enum ReadSmart_Results DRIVE_DOES_NOT_EXIST ACCESS_DENIED NO_SMART_AVAILABLE SUCCEEDED End Enum Public Enum Attributes ' Invalid attribute identifier SMART_ATTRIB_Invalid = 0 ' Frequency of errors while reading raw data SMART_ATTRIB_RAW_READ_ERROR_RATE = 1 ' Average efficiency of a hard disk SMART_ATTRIB_THROUGHPUT_PERFORMANCE = 2 ' needed to spin up SMART_ATTRIB_SPIN_UP_TIME = 3 ' Number of spindle start/stop cycles SMART_ATTRIB_START_STOP_COUNT = 4 ' Quantity of remapped sectors SMART_ATTRIB_REALLOCATION_SECTOR_COUNT = 5 ' Reserve of channel while reading SMART_ATTRIB_Read_Channel_Margin = 6 ' Frequency of errors while positioning SMART_ATTRIB_SEEK_ERROR_RATE = 7 ' Average efficiency of operations while positioning SMART_ATTRIB_Seek_TimerPerformance = 8 ' Number of hours elapsed in the power-on state SMART_ATTRIB_POWER_ON_HOURS_COUNT = 9 ' Number of retry attempts to spin up SMART_ATTRIB_SPIN_RETRY_COUNT = 10 ' Count number of attempts to calibrate the device SMART_ATTRIB_RECALIBRATION_RETRIES = 11 ' Number of power-on events SMART_ATTRIB_DEVICE_POWER_CYCLE_COUNT = 12 ' Frequency of program errors while reading from a disk SMART_ATTRIB_SOFT_READ_ERROR_RATE = 13 ' Frequency of mistakes as a result of impact loads SMART_ATTRIB_AIRFLOW_TEMPERATURE = 190 ' Frequency of mistakes as a result of impact loads SMART_ATTRIB_G_Sense_Error_Rate = 191 ' Number of power-off or emergency retract cycles SMART_ATTRIB_Power_Off_Retract_Count = 192 ' Number of cycles into landing zone position SMART_ATTRIB_LOAD_UNLOAD_CYCLE_COUNT = 193 ' Temperature of a hard disk assembly SMART_ATTRIB_HDA_TEMPERATURE = 194 ' Number of ECC on-the-fly errors SMART_ATTRIB_Hardware_ECC_Recovered = 195 ' Number of remapping operations SMART_ATTRIB_REALLOCATION_COUNT = 196 ' Number of unstable sectors (waiting for remapping) SMART_ATTRIB_CURRENT_PENDING_SECTOR_COUNT = 197 ' Number of uncorrected errors SMART_ATTRIB_UNCORRECTABLE_SECTOR_COUNT = 198 ' Number of CRC errors during UDMA mode SMART_ATTRIB_ULTRA_DMA_CRC_ERROR_COUNT = 199 ' Number of errors while writing to disk (or) multi-zone error ' rate (or) flying height SMART_ATTRIB_WRITE_ERROR_RATE = 200 ' Number of off-track errors SMART_ATTRIB_Soft_Read_Error_Count = 201 ' Number of Data Address Mark (DAM) errors (or) vendor-specific SMART_ATTRIB_Data_Address_Mark_Errors = 202 ' Number of ECC errors SMART_ATTRIB_Run_Out_Cancel = 203 ' Number of errors corrected by software ECC SMART_ATTRIB_Soft_ECC_Correction = 204 ' Number of thermal asperity errors SMART_ATTRIB_Thermal_Asperity_Rate = 205 ' Height of heads above the disk surface SMART_ATTRIB_Flying_Height = 206 ' Amount of high current used to spin up the drive SMART_ATTRIB_Spin_High_Current = 207 ' Number of buzz routines to spin up the drive SMART_ATTRIB_Spin_Buzz = 208 ' Drives seek performance during offline operations SMART_ATTRIB_Offline_Seek_Performance = 209 ' Shift of disk is possible as a result of strong shock loading in the ' store, as a result of falling (or) temperature SMART_ATTRIB_Disk_Shift = 220 ' Number of errors as a result of impact loads as detected by ' a shock sensor SMART_ATTRIB_G_SENSE_ERROR_Count = 221 ' Number of hours in general operational state SMART_ATTRIB_Loaded_Hours = 222 ' Loading on drive caused by numerous recurrences of operations, like ' reading, recording, positioning of heads, etc. SMART_ATTRIB_Load_Unload_Retry_Count = 223 ' Load on drive caused by friction in mechanical parts of the store SMART_ATTRIB_Load_Friction = 224 ' Total number of load cycles SMART_ATTRIB_Load_Unload_Cycle_Count1 = 225 ' General time for loading in a drive SMART_ATTRIB_Load_In_Time = 226 ' Quantity efforts of the rotating moment of a drive SMART_ATTRIB_Torque_Amplification_Count = 227 ' Number of power-off retract events. SMART_ATTRIB_POWER_OFF_RETRACT_COUNT1 = 228 ' Amplitude of heads trembling (GMR-head) in running mode SMART_ATTRIB_GMR_Head_Amplitude = 230 ' Temperature of a drive SMART_ATTRIB_Drive_Temperature = 231 ' Time while head is positioning SMART_ATTRIB_Head_Flying_Hours = 240 ' Number of errors while reading from a disk SMART_ATTRIB_Read_Error_Retry_Rate = 250 End Enum Private Const IOCTL_STORAGE_PREDICT_FAILURE As Integer = &H2D1100 Private Const STATUS_INVALID_DEVICE_REQUEST As Integer = &HC0000010 Private Const FILE_SHARE_NONE As Short = 0 Private Const OPEN_EXISTING As Short = 3 Private Const INVALID_HANDLE_VALUE As Short = -1 Private Const GENERIC_READ As Integer = &H80000000 Private Const GENERIC_WRITE As Integer = &H40000000 Private Const FILE_SHARE_READ As Integer = 1 Private Const FILE_SHARE_WRITE As Integer = 2 <DllImport("kernel32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _ Private Function CreateFile(ByVal lpFileName As String, _ ByVal dwDesiredAccess As Integer, _ ByVal dwShareMode As Integer, _ ByVal lpSecurityAttributes As IntPtr, _ ByVal dwCreationDisposition As Integer, _ ByVal dwFlagsAndAttributes As Integer, _ ByVal hTemplateFile As IntPtr) As IntPtr End Function <DllImport("kernel32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _ Private Function CloseHandle(ByVal hObject As IntPtr) As Boolean End Function <DllImport("kernel32.dll", ExactSpelling:=True, SetLastError:=True, _ CharSet:=CharSet.Auto)> _ Private Function DeviceIoControl(ByVal hDevice As IntPtr, _ ByVal dwIoControlCode As Integer, _ ByVal lpInBuffer As IntPtr, _ ByVal nInBufferSize As Integer, _ <Out()> ByVal lpOutBuffer As STORAGE_PREDICT_FAILURE, _ ByVal nOutBufferSize As Integer, _ ByRef lpBytesReturned As Integer, _ ByVal lpOverlapped As IntPtr) As Integer End Function Public Drives As String() Public Names As String() Public SmartData As STORAGE_PREDICT_FAILURE ' Alle Festplatten ermitteln Public Function GetPhysicalDrives() Dim objWMIService, colItems, objItem As Object Dim i As Integer ' winmgmts:{impersonationLevel=impersonate}!\\ objWMIService = GetObject("winmgmts:\\.\root\cimv2") colItems = objWMIService.ExecQuery("SELECT * FROM Win32_DiskDrive") Drives = New String(colItems.count - 1) {} Names = New String(colItems.count - 1) {} i = 0 For Each objItem In colItems Drives(i) = objItem.deviceid() Names(i) = objItem.caption i += 1 Next Return colItems.Count End Function ' Smart-Werte für angegebenes Laufwerk lesen, stehen danach in ' SmartData zur Verfügung Public Function ReadSmart(ByVal Drive As String) As ReadSmart_Results Dim Device As IntPtr Dim Result As Boolean Dim ReturnedBytes As Integer SmartData = New STORAGE_PREDICT_FAILURE Device = CreateFile(Drive, _ GENERIC_READ, _ FILE_SHARE_READ, _ IntPtr.Zero, _ OPEN_EXISTING, _ 0, _ IntPtr.Zero) If Device.ToInt32 = INVALID_HANDLE_VALUE Then If Marshal.GetLastWin32Error = 5 Then Return ReadSmart_Results.ACCESS_DENIED Else Return ReadSmart_Results.DRIVE_DOES_NOT_EXIST End If End If Result = DeviceIoControl(Device, _ IOCTL_STORAGE_PREDICT_FAILURE, _ IntPtr.Zero, _ 0, _ SmartData, _ Marshal.SizeOf(SmartData), _ ReturnedBytes, _ IntPtr.Zero) CloseHandle(Device) If Result Then Return ReadSmart_Results.SUCCEEDED Else Return ReadSmart_Results.NO_SMART_AVAILABLE End If End Function ' Attributsnamen (falls vohanden) ausgeben Public Function GetAttribute(ByVal Index As Attributes) As String Dim outString As String outString = Index.ToString If IsNumeric(outString) Then outString = "<Herstellerspezifisch>" Return outString End Function ' Smart-Wert auswerten, 12Byte beginnend ab Offset = X * 12 + 2 Public Sub GetSmartValue(ByVal Offset As Integer, _ ByRef Attribut As Integer, ByRef Value As Integer, _ ByRef Worst As Integer, ByRef Data As Integer) ' Der S.M.A.R.T.-Wert setzt sich aus 12Byte zusammen ' 1. Byte - Attributesnamen Attribut = SmartData.VendorSpecific(Offset) ' 2./3. Byte - Herstellerspezifisch ' interessant ist hier das 1. Bit, falls der Wert dieses Smartwertes ' unter dem Grenzwert liegt, gibt dieses Bit an, ob die Festplatte ' innerhalb der nächsten 24h ausfallen wird! ' 4. Byte - Wert Value = SmartData.VendorSpecific(Offset + 3) ' 5.-12. Byte - RAW-Value (herstellerspezifisch) Worst = SmartData.VendorSpecific(Offset + 4) Dim str As String = "" For i As Integer = 11 To 5 Step -1 str &= Hex(SmartData.VendorSpecific(Offset + i)) Next Data = Convert.ToInt64(str, 16) End Sub ' Werte aus SmartData in Listview eintragen Public Sub AddSmartToListView(ByVal lv As ListView, ByVal Index As Integer) Dim Attribut, Value, Worst, Data As Integer For i As Integer = 0 To 29 GetSmartValue(i * 12 + 2, Attribut, Value, Worst, Data) '0 ist kein gültiger Wert! If Not Attribut = Attributes.SMART_ATTRIB_Invalid Then Dim lvi As New ListViewItem lvi.Text = Attribut & " - " & GetAttribute(Attribut) lvi.SubItems.Add(Value) lvi.SubItems.Add(Worst) lvi.SubItems.Add(Data) For j As Integer = 0 To lv.Groups.Count - 1 If lv.Groups(j).Name = "LW" & Index Then _ lvi.Group = lv.Groups(j) Next lv.Items.Add(lvi) End If Next End Sub End Module <StructLayout(LayoutKind.Sequential)> _ Public Class STORAGE_PREDICT_FAILURE Public PredictFailure As Integer <MarshalAs(UnmanagedType.ByValArray, SizeConst:=512)> _ Public VendorSpecific() As Byte Sub New() VendorSpecific = New Byte(511) {} End Sub End Class ' ############################################################################## ' ################################ Testform.vb ################################# ' ############################################################################## Public Class Testform Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click ListView1.Items.Clear() ListView1.Groups.Clear() Dim j As Integer = GetPhysicalDrives() - 1 For i As Integer = 0 To j Select Case ReadSmart(Drives(i)) Case ReadSmart_Results.SUCCEEDED ListView1.Groups.Add("LW" & i, Names(i) & _ " (" & Drives(i) & ")") AddSmartToListView(Me.ListView1, i) Case ReadSmart_Results.NO_SMART_AVAILABLE ListView1.Groups.Add("LW" & i, Names(i) & _ " (" & Drives(i) & ")") Dim lvi As New ListViewItem lvi.Text = "S.M.A.R.T. not available" lvi.Group = ListView1.Groups(i) ListView1.Items.Add(lvi) Case ReadSmart_Results.ACCESS_DENIED ListView1.Groups.Add("LW" & i, Names(i) & _ " (" & Drives(i) & ")") Dim lvi As New ListViewItem lvi.Text = _ "Zugriff verweigert, Administratorrechte benötigt!" lvi.Group = ListView1.Groups(i) ListView1.Items.Add(lvi) Case ReadSmart_Results.DRIVE_DOES_NOT_EXIST 'Das angegebene Laufwerk existiert nicht 'nicht ausgeben End Select Next End Sub Private Sub Testform_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load ListView1.Columns(0).Width = 360 ListView1.Columns(1).Width = 100 ListView1.Columns(2).Width = 100 ListView1.Columns(3).Width = 150 End Sub End Class
Ihre Meinung
Falls Sie Fragen zu diesem Artikel haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.
Archivierte Nutzerkommentare
Klicken Sie diesen Text an, wenn Sie die 2 archivierten Kommentare ansehen möchten.
Diese stammen noch von der Zeit, als es noch keine direkte Forenunterstützung für Fragen und Kommentare zu einzelnen Artikeln gab.
Aus Gründen der Vollständigkeit können Sie sich die ausgeblendeten Kommentare zu diesem Artikel aber gerne weiterhin ansehen.
Kommentar von Henning Paschke am 26.05.2010 um 18:52
Wie kann ich aus STORAGE_PREDICT_FAILURE die Grenze für ein SMART-Attribut auslesen. Auch der Attribut-Type wäre wichtig. Bei den smartmontools hat die Tabelle folgende Werte
ID, ATTRIBUTE_NAME, FLAG, VALUE, WORST, THRESH, TYPE, UPDATED, WHEN_FAILED, RAW_VALUE
Wo finde ich die entsprechenden Werte?
Kommentar von Carsten am 02.06.2009 um 01:31
Und wie könnte man andere Festplatten damit überwachen? Gibt es dafür schon eine Routine?
Vielen Dank!