vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#

https://www.vbarchiv.net
Rubrik: Dateisystem · Laufwerke   |   VB-Versionen: VB2005, VB200818.07.08
S.M.A.R.T. Attribute auslesen

Mit diesem Code lassen sich die S.M.A.R.T. Eigenschaften und Werte der Festplatte auslesen.

Autor:   Christian ZechBewertung:  Views:  18.490 
ohne HomepageSystem:  Win2k, WinXP, Win7, Win8, Win10, Win11 Beispielprojekt auf CD 

Mit diesem Code lassen sich die S.M.A.R.T. Eigenschaften und Werte der Festplatte auslesen.

Als erstes wird eine Form benötigt, mit einem Button, der das Auslesen startet, und einem Listview. Das Listview enthält 4 Spalten: Eigenschaft | Wert | schlechtester Wert | RAW-Value

Public Class Form1
  Private Sub Button1_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles Button1.Click
 
    With ListView1
      .Items.Clear()
      .Groups.Clear()
 
      ' Laufwerke ermitteln
      Dim j As Integer = GetPhysicalDrives() - 1
 
      ' S.M.A.R.T. Eigenschaften auslesen und ins Listview eintragen
      For i As Integer = 0 To j
        Select Case ReadSmart(Drives(i))
          Case ReadSmart_Results.SUCCEEDED
            ' S.M.A.R.T.-Werte wurden ausgelesen und werden 
            ' ins Listview eingetragen
            .Groups.Add("LW" & i, Names(i) & "  (" & Drives(i) & ")")
            AddSmartToListView(Me.ListView1, i)
          Case ReadSmart_Results.NO_SMART_AVAILABLE
            ' S.M.A.R.T. ist für dieses Laufwerk nicht verfügbar
            .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)
            .Items.Add(lvi)
          Case ReadSmart_Results.ACCESS_DENIED
            ' Zugriff uafs Laufwerk verweigert, wahrscheinlich fehlen 
            ' Adminrechte (v.a. unter Vista)
            .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)
            .Items.Add(lvi)
          Case ReadSmart_Results.DRIVE_DOES_NOT_EXIST
            ' Das angegebene Laufwerk existiert nicht
            ' nichts ausgeben
        End Select
      Next
    End With
  End Sub
 
End Class

Für die Funktionen wird noch ein Modul benötigt:

Imports System.Runtime.InteropServices
 
Public Module Smart
 
  Public Enum ReadSmart_Results
    DRIVE_DOES_NOT_EXIST
    ACCESS_DENIED
    NO_SMART_AVAILABLE
    SUCCEEDED
  End Enum
#Region "S.M.A.R.T. Attributsnamen"
  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
    ' Fequency of mistakes as a result of impact loads
    SMART_ATTRIB_AIRFLOW_TEMPERATURE = 190
    ' Fequency 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
    ' Drive’s 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
#End Region
#Region "Konstanten"
  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
#End Region
#Region "DLL Deklarationen"
  <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
#End Region
  Public Drives As String()
  Public Names As String()
  Public SmartData As STORAGE_PREDICT_FAILURE
  ' Festplatten (und auch USB-Laufwerke) per WMI ermitteln
  Public Function GetPhysicalDrives()
    Dim objWMIService, colItems, objItem As Object
    Dim i As Integer
 
    objWMIService = GetObject("winmgmts:" & _
      "{impersonationLevel=impersonate}!\\.\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
 
    ' Anzahl der Laufwerke zurückgeben
    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
 
    ' Laufwerk öffnen
    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 = 2 Then
        'Z ugriff verweigert, wahrscheinlich fehlen Adminrechte
        Return ReadSmart_Results.ACCESS_DENIED
      Else
        ' das angegebene Laufwerk existiert nicht
        Return ReadSmart_Results.DRIVE_DOES_NOT_EXIST
      End If
    End If
 
    ' S.M.A.R.T. auslesen
    Result = DeviceIoControl(Device, _
      IOCTL_STORAGE_PREDICT_FAILURE, _
      IntPtr.Zero, _
      0, _
      SmartData, _
      Marshal.SizeOf(SmartData), _
      ReturnedBytes, _
      IntPtr.Zero)
 
    CloseHandle(Device)
 
    If Result Then
      ' erfolgreich
      Return ReadSmart_Results.SUCCEEDED
    Else
      ' es konnten keine S.M.A.R.T. Eigenschaften gelesen werden
      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
    ' Wenn outString noch numerisch ist, dann ist kein 
    ' Beschreibungstext in der Definition angegeben, 
    ' Ersatztext wird ausgegeben
    If IsNumeric(outString) Then outString = "<Herstellerspezifisch>"
 
    Return outString
  End Function
  ' Smart-Wert auswerten, 12Byte beginnend ab Offset
  ' Offset = X * 12 + 2
  Public Sub GetSmartValue(ByVal Offset As Integer, _
    ByRef Attribut As Integer, _
    ByRef Value As Long, _
    ByRef Worst As Long, _
    ByRef Data As Long)
 
    ' 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 Long
 
    For i As Integer = 0 To 29
      GetSmartValue(i * 12 + 2, Attribut, Value, Worst, Data)
      ' 0 ist kein gültiger Wert, d.h. dieser Speicherblock enthält
      ' kein Attribut
      If Not Attribut = Attributes.SMART_ATTRIB_Invalid Then
        ' ins Listview eintragen
        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
#Region "Hilfsklasse zur Zwischenspeicherung"
<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
#End Region



Anzeige

Kauftipp Unser Dauerbrenner!Diesen und auch alle anderen Tipps & Tricks finden Sie auch auf unserer aktuellen vb@rchiv  Vol.6
(einschl. Beispielprojekt!)

Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv!
- nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten
- Symbol-Galerie mit mehr als 3.200 Icons im modernen Look
Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m.
 
 
Copyright ©2000-2024 vb@rchiv Dieter OtterAlle Rechte vorbehalten.


Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.