Jump to content

SMART drive Analysis


ptrex
 Share

Recommended Posts

@LIMITER

I can't test it to simulate the behaviour because I don't have a floppy drive.

But you can experiment using a filter in the query statement.

First run the script as is and look what the "InstanceName" is retrieving.

Then limit the query to that instancename like this example.

SELECT * FROM MSStorageDriver_ATAPISmartData WHERE InstanceName LIKE 'IDE\\Disk%'

Regards

ptrex

Link to comment
Share on other sites

Just a couple of quick questions.

If you are actually checking floppy drives, Why?

What happens with this script if the user has S.M.A.R.T. checking disabled in the Bios?

For the first question. It's not needed

For the second. I realize that people who do this are being foolish but there are a lot of foolish people out there.

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Link to comment
Share on other sites

Well GEOSoft ... i have SMART disabled :) ... (because my hard is sooooo wrecked ... that win won't start if smart is enabled)

And by ypur response the script still works so I guess that answers that question. Are you getting the right information when you run the script. The reason I ask is I see this as being a good diagnostic tool for client systems.

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Link to comment
Share on other sites

Hi,

I am currently working on a project that collects hardware information. I also have the problem, that the FDD is checked every time I want to retrieve SMART information.

I already know the source of the problem: It's the function _DriveLetterToAntecedent (I renamed it). But when I try to implement a WHERE-clause, the WQL-Statement does not return any results. Here is my code:

Func _DriveLetterToAntecedent(ByRef Const $objWMIService, Const $S_LETTER)
;~  Local $colItems = $objWMIService.ExecQuery("SELECT Dependent,Antecedent FROM Win32_LogicalDiskToPartition", _
;~          "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
    Local $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_LogicalDiskToPartition WHERE Dependent = '\\" & _
            @ComputerName & '\root\cimv2:Win32_LogicalDisk.DeviceID="' & $S_LETTER & '"' & "'", _
            "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
    If IsObj($colItems) Then
        For $objItem In $colItems
            MsgBox(0, "", $objItem.Dependent & @CR & $objItem.Antecedent)
;~          If StringTrimRight(StringRight($objItem.Dependent, 3), 1) = $S_LETTER Then Return $objItem.Antecedent
        Next
    EndIf
    Return 0
EndFunc   ;==>_DriveLetterToAntecedent

Does anyone know how to fix the problem?

Link to comment
Share on other sites

Link to comment
Share on other sites

Thank you ptrex!

Here is my code (but the problem exists in all scripts in this thread!). It does not differs from the two scripts posted here!

#include <Array.au3>

Global Const $wbemFlagReturnImmediately = 0x10
Global Const $wbemFlagForwardOnly = 0x20
Global Const $strComputer = "."

Global Const $S_DRIVE = "C:"
Global $as_smart = _GetSmartData($S_DRIVE)
If $as_smart <> -1 Then
    _ArrayDisplay($as_smart, "S.M.A.R.T. Data for Drive " & $S_DRIVE)
Else
    MsgBox(64, "Please note", $S_DRIVE & " may not be S.M.A.R.T. capable!")
EndIf

Func _GetSmartData($vDrive = "C:")
    If DriveStatus($vDrive) = "INVALID" Then Return SetError(1, 0, -1)

    Local $iCnt, $iCheck, $vPartition, $vDeviceID, $vPNPID, $objWMIService, $oDict
    Local $strReserved, $strVendorSpecific, $strVendorSpecific4, $Output
    If StringLeft($vDrive, 1) <> '"' Then $vDrive = '"' & $vDrive
    If StringRight($vDrive, 1) <> '"' Then $vDrive &= '"'

    MsgBox(64, "Debug", "Still OK.")
    $vPartition = _LogicalToPartition($vDrive)
    MsgBox(16, "Debug", "FDD was checked!")
    If $vPartition = -1 Then Return -1
    $vDeviceID = _PartitionToPhysicalDriveID($vPartition)
    If $vDeviceID = -1 Then Return -1
    $vPNPID = _PNPIDFromPhysicalDriveID($vDeviceID)
    If $vPNPID = -1 Then Return -1

    $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\WMI")
    $colItems1 = $objWMIService.ExecQuery("SELECT * FROM MSStorageDriver_ATAPISmartData", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
    $colItems2 = $objWMIService.ExecQuery("SELECT * FROM MSStorageDriver_FailurePredictThresholds", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
    $colItems3 = $objWMIService.ExecQuery("SELECT * FROM MSStorageDriver_FailurePredictStatus", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)

    $iCnt = 1
    For $objItem In $colItems1
        If StringLeft($objItem.InstanceName, StringLen($vPNPID)) = String($vPNPID) Then
            $strReserved = $objItem.Reserved
            $strVendorSpecific = $objItem.VendorSpecific
            $strVendorSpecific4 = $objItem.VendorSpecific4
        Else
            $iCnt += 1
        EndIf
    Next

    $iCheck = 1
    For $objItem In $colItems2
        If $iCheck = $iCnt Then
            $strVendorSpecific2 = $objItem.VendorSpecific
        Else
            $iCheck += 1
        EndIf
    Next
    
    $iCheck = 1
    For $objItem In $colItems3
        If $iCheck = $iCnt Then
            $strVendorSpecific3 = $objItem.PredictFailure
            $strVendorSpecific3 = $objItem.Reason
        Else
            $iCheck += 1
        EndIf
    Next

    If Not IsArray($strVendorSpecific4) Then Return -1
    If Not IsArray($strVendorSpecific2) Then Return -1
    
    $oDict = ObjCreate("Scripting.Dictionary")
    _CreateDict($oDict)

    Local $Status[22]
    For $i = 1 To 21
        $Status[$i] = "Not OK"
    Next

    If $strVendorSpecific[5] >= $strVendorSpecific2[3] Then $Status[1] = "OK"
    If $strVendorSpecific[17] >= $strVendorSpecific2[15] Then $Status[2] = "OK"
    If $strVendorSpecific[29] >= $strVendorSpecific2[27] Then $Status[3] = "OK"
    If $strVendorSpecific[41] >= $strVendorSpecific2[39] Then $Status[4] = "OK"
    If $strVendorSpecific[53] >= $strVendorSpecific2[51] Then $Status[5] = "OK"
    If $strVendorSpecific[65] >= $strVendorSpecific2[63] Then $Status[6] = "OK"
    If $strVendorSpecific[77] >= $strVendorSpecific2[75] Then $Status[7] = "OK"
    If $strVendorSpecific[89] >= $strVendorSpecific2[87] Then $Status[8] = "OK"
    If $strVendorSpecific[101] >= $strVendorSpecific2[99] Then $Status[9] = "OK"
    If $strVendorSpecific[113] >= $strVendorSpecific2[111] Then $Status[10] = "OK"
    If $strVendorSpecific[125] >= $strVendorSpecific2[123] Then $Status[11] = "OK"
    If $strVendorSpecific[137] >= $strVendorSpecific2[135] Then $Status[12] = "OK"
    If $strVendorSpecific[149] >= $strVendorSpecific2[147] Then $Status[13] = "OK"
    If $strVendorSpecific[161] >= $strVendorSpecific2[159] Then $Status[14] = "OK"
    If $strVendorSpecific[173] >= $strVendorSpecific2[171] Then $Status[15] = "OK"
    If $strVendorSpecific[185] >= $strVendorSpecific2[183] Then $Status[16] = "OK"
    If $strVendorSpecific[197] >= $strVendorSpecific2[195] Then $Status[17] = "OK"
    If $strVendorSpecific[206] >= $strVendorSpecific2[204] Then $Status[18] = "OK"
    If $strVendorSpecific[218] >= $strVendorSpecific2[216] Then $Status[19] = "OK"
    If $strVendorSpecific[230] >= $strVendorSpecific2[228] Then $Status[20] = "OK"
    If $strVendorSpecific[242] >= $strVendorSpecific2[240] Then $Status[21] = "OK"

    Local $aSmartData[1][8] = [["ID", "Attribute", "Type", "Flag", "Threshold", "Value", "Worst", "Status"]]
    $iCnt = 1
    For $x = 2 To 242 Step 12
        If $strVendorSpecific[$x] <> 0 Then ;0 id is not valid for this Smart Device
            $NextRow = UBound($aSmartData)
            ReDim $aSmartData[$NextRow + 1][8]
            $aSmartData[$NextRow][0] = $strVendorSpecific[$x];ID
            $aSmartData[$NextRow][1] = $oDict.Item($strVendorSpecific[$x]);Attribute
            If $aSmartData[$NextRow][1] = "" Then $aSmartData[$NextRow][1] = "Unknown SMART Attribute"

            If Mod($strVendorSpecific[$x + 1], 2) Then ;Type If odd number then it is a pre-failure value
                $aSmartData[$NextRow][2] = "Pre-Failure"
            Else
                $aSmartData[$NextRow][2] = "Advisory"
            EndIf

            $aSmartData[$NextRow][3] = $strVendorSpecific[$x + 1];Flag
            $aSmartData[$NextRow][4] = $strVendorSpecific2[$x + 1];Threshold
            $aSmartData[$NextRow][5] = $strVendorSpecific[$x + 3];Value
            $aSmartData[$NextRow][6] = $strVendorSpecific[$x + 4];Worst
            $aSmartData[$NextRow][7] = $Status[$iCnt];Status
        EndIf
        $iCnt += 1
    Next
    
    Return $aSmartData
EndFunc   ;==>_GetSmartData

Func _PartitionToPhysicalDriveID($vPart)
    Local $objWMIService, $colItems
    $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
    $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_DiskDriveToDiskPartition", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
    If IsObj($colItems) Then
        For $objItem In $colItems
            If $objItem.Dependent = $vPart Then
                $vPdisk = $objItem.Antecedent
                Return StringReplace(StringReplace(StringTrimLeft($vPdisk, StringInStr($vPdisk, "=")), '"', ""), "\\", "\")
            EndIf
        Next
    EndIf
    Return -1
EndFunc   ;==>_PartitionToPhysicalDriveID

Func _PNPIDFromPhysicalDriveID($vDriveID)
    Local $objWMIService, $colItems
    $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
    $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_DiskDrive", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
    If IsObj($colItems) Then
        For $objItem In $colItems
            If $objItem.DeviceID = $vDriveID Then Return $objItem.PNPDeviceID
        Next
    EndIf
    Return -1
EndFunc   ;==>_PNPIDFromPhysicalDriveID

Func _LogicalToPartition($vDriveLet)
    Local $objWMIService, $colItems
    $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
    $colItems = $objWMIService.ExecQuery("SELECT Dependent,Antecedent FROM Win32_LogicalDiskToPartition", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
    If IsObj($colItems) Then
        For $objItem In $colItems
            If StringRight($objItem.Dependent, 4) = $vDriveLet Then Return $objItem.Antecedent
        Next
    EndIf
    Return -1
EndFunc   ;==>_LogicalToPartition

Func _CreateDict(ByRef $oDict)
    $oDict.Add(1, "Read Error Rate")
    $oDict.Add(2, "Throughput Performance")
    $oDict.Add(3, "Spin-Up Time")
    $oDict.Add(4, "Start/Stop Count")
    $oDict.Add(5, "Reallocated Sectors Count")
    $oDict.Add(6, "Read Channel Margin")
    $oDict.Add(7, "Seek Error Rate Rate")
    $oDict.Add(8, "Seek Time Performance")
    $oDict.Add(9, "Power-On Hours (POH)")
    $oDict.Add(10, "Spin Retry Count")
    $oDict.Add(11, "Recalibration Retries")
    $oDict.Add(12, "Device Power Cycle Count")
    $oDict.Add(13, "Soft Read Error Rate")
    $oDict.Add(191, "G-Sense Error Rate Frequency")
    $oDict.Add(192, "Power-Off Park Count")
    $oDict.Add(193, "Load/Unload Cycle")
    $oDict.Add(194, "HDA Temperature")
    $oDict.Add(195, "ECC Corrected Count")
    $oDict.Add(196, "Reallocated Event Count")
    $oDict.Add(197, "Current Pending Sector Count")
    $oDict.Add(198, "Uncorrectable Sector Count")
    $oDict.Add(199, "UltraDMA CRC Error Count")
    $oDict.Add(200, "Write Error Rate")
    $oDict.Add(201, "Soft Read Error Rate")
    $oDict.Add(202, "Address Mark Errors Frequency")
    $oDict.Add(203, "ECC errors (Maxtor: ECC Errors)")
    $oDict.Add(204, "Soft ECC Correction")
    $oDict.Add(205, "Thermal Asperity Rate (TAR)")
    $oDict.Add(206, "Flying Height")
    $oDict.Add(207, "Spin High Current")
    $oDict.Add(208, "Spin Buzz")
    $oDict.Add(209, "Offline Seek")
    $oDict.Add(220, "Disk Shift")
    $oDict.Add(221, "G-Sense Error Rate")
    $oDict.Add(222, "Loaded Hours")
    $oDict.Add(223, "Load/Unload Retry Count")
    $oDict.Add(224, "Load Friction")
    $oDict.Add(225, "/Unload Cycle Count")
    $oDict.Add(226, "Load 'In'-time")
    $oDict.Add(227, "Torque Amplification Count")
    $oDict.Add(228, "Power-Off Retract Cycle")
    $oDict.Add(230, "GMR Head Amplitude")
    $oDict.Add(231, "Temperature")
    $oDict.Add(240, "Head Flying Hours")
    $oDict.Add(250, "Read Error Retry Rate")
EndFunc   ;==>_CreateDict

PS: One further question: I did not really get how you can say the status is OK or not. What is the idea behind this?

Link to comment
Share on other sites

@tehhahn

I looked through your script but I can't visually see anything strange.

I can't test it because I don't have floppy. Maybe someone else can do some tests.

The only thing you should be aware of is that the WQL syntax for drives and Path uses DOUBLE \\ instead of 1.

Maybe there is a hint to look at.

regards

ptrex

Link to comment
Share on other sites

Hi again,

sorry I did not reply earlier but I was at the Cebit fair yesterday. I checked the syntax for WQL and of course you're right. The correct query is:

SELECT Antecedent FROM Win32_LogicalDiskToPartition WHERE Dependent = '\\\\AS106789\\root\\cimv2:Win32_LogicalDisk.DeviceID="C:"'

But the FDD is still checked! Is there any other possibility to retrieve the PNPDeviceID from the drive letter?

Link to comment
Share on other sites

If I modify Chris' code to the following it's not checking my floppy at all.

#Region;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseUpx=n
#EndRegion;**** Directives created by AutoIt3Wrapper_GUI ****

#include <array.au3>

Const $wbemFlagReturnImmediately = 0x10
Const $wbemFlagForwardOnly = 0x20

Dim $strComputer = "." 
Dim $objWMIService, $oMyError, $oDict, $oDictType
Dim $colItems, $strReserved, $strVendorSpecific, $strVendorSpecific4, $Output
$oMyError = ObjEvent("AutoIt.Error","MyErrFunc")


;$drive = "C:"
$Drives = DriveGetDrive("Fixed")
For $I = 1 To Ubound($Drives)-1
   $Drive = StringUpper($Drives[$I])
   $smartData = _GetSmartData($drive)
   If $smartData <> -1 then 
      _arrayDisplay($SmartData,"S.M.A.R.T. Data for Drive " & $drive)
   Else
    Msgbox(0,"",$drive & " may not be S.M.A.R.T. Capable")
   EndIf
Next

Func _GetSmartData($vDrive  = "C:")
    
    If DriveStatus ( $vDrive ) = "INVALID" then 
        SetError(1)
        Return -1
    EndIf
    
    If StringLeft($vDrive,1) <> '"' then $vDrive = '"' & $vDrive
    If StringRight($vDrive,1) <> '"' then $vDrive &= '"'
    
    Local $iCnt, $iCheck, $vPartition,$vDeviceID,$vPNPID
    
    $vPartition = _LogicalToPartition ($vDrive)
    If $vPartition = -1 then Return -1
    
    $vDeviceID = _PartitionToPhysicalDriveID($vPartition)
    If $vDeviceID = -1 then Return -1
    
    $vPNPID = _PNPIDFromPhysicalDriveID($vDeviceID)
    If $vPNPID = -1 then Return -1
    
        $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\WMI")
        $oDict = ObjCreate("Scripting.Dictionary")
        $oDictType = ObjCreate("Scripting.Dictionary")

        $colItems1 = $objWMIService.ExecQuery("SELECT * FROM MSStorageDriver_ATAPISmartData", "WQL", _
                                              $wbemFlagReturnImmediately + $wbemFlagForwardOnly)

        $colItems2 = $objWMIService.ExecQuery("SELECT * FROM MSStorageDriver_FailurePredictThresholds", "WQL", _
                                              $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
                                              
        $colItems3 = $objWMIService.ExecQuery("SELECT * FROM MSStorageDriver_FailurePredictStatus", "WQL", _
                                              $wbemFlagReturnImmediately + $wbemFlagForwardOnly)

        _CreateDict(); Create Dictionary
    ;_CreateTypeDict(); Create Type Dictionary (Not needed anymore)
        
        ConsoleWrite ($strComputer&@CR)                           
    
    $iCnt = 1
       For $objItem In $colItems1
           If StringLeft($objItem.InstanceName,StringLen($vPNPID)) = String($vPNPID) then 
              ConsoleWrite ("Active: " & $objItem.Active&@CR)
              ConsoleWrite ("Checksum: " & $objItem.Checksum&@CR)
              ConsoleWrite ("ErrorLogCapability: " & $objItem.ErrorLogCapability&@CR)
              ConsoleWrite ("ExtendedPollTimeInMinutes: " & $objItem.ExtendedPollTimeInMinutes&@CR)
              ConsoleWrite ("InstanceName: " & $objItem.InstanceName&@CR)
              ConsoleWrite ("Length: " & $objItem.Length&@CR)
              ConsoleWrite ("OfflineCollectCapability: " & $objItem.OfflineCollectCapability&@CR)
              ConsoleWrite ("OfflineCollectionStatus: " & $objItem.OfflineCollectionStatus&@CR)
                $strReserved = $objItem.Reserved
              ConsoleWrite ("Reserved: " & _ArrayToString($strReserved,",")&@CR)
              ConsoleWrite ("SelfTestStatus: " & $objItem.SelfTestStatus&@CR)
              ConsoleWrite ("ShortPollTimeInMinutes: " & $objItem.ShortPollTimeInMinutes&@CR)
              ConsoleWrite ("SmartCapability: " & $objItem.SmartCapability&@CR)
              ConsoleWrite ("TotalTime: " & $objItem.TotalTime&@CR)
                $strVendorSpecific = $objItem.VendorSpecific
            ;_arrayDisplay($strVendorSpecific,"$strVendorSpecific")
            ConsoleWrite ("VendorSpecific: " & _ArrayToString($strVendorSpecific,",")&@CR)
            ConsoleWrite ("VendorSpecific2: " & $objItem.VendorSpecific2&@CR)
            ConsoleWrite ("VendorSpecific3: " & $objItem.VendorSpecific3&@CR)
                $strVendorSpecific4 = $objItem.VendorSpecific4
            ;_arrayDisplay($strVendorSpecific4,"$strVendorSpecific4")
            ConsoleWrite ("VendorSpecific4: " & _ArrayToString($strVendorSpecific4,",")&@CR)
        Else
            
        $iCnt +=1
    EndIf
    
Next

    
    $iCheck = 1
        For $objItem In $colItems2
        If $iCheck = $iCnt then 
          $strVendorSpecific2 = $objItem.VendorSpecific
         ;_arrayDisplay($strVendorSpecific2,"$strVendorSpecific2")
          ConsoleWrite ("FailurePredictThresholds: " & _ArrayToString($strVendorSpecific2,",")&@CR)
              Else
                  $iCheck +=1
              EndIf
        Next
          
    $iCheck = 1
        For $objItem In $colItems3
            If $iCheck = $iCnt then 
              $strVendorSpecific3 = $objItem.PredictFailure
              ConsoleWrite ("PredictFailure: " & $strVendorSpecific3&@CR)
              $strVendorSpecific3 = $objItem.Reason
              ConsoleWrite ("PredictReason: " & $strVendorSpecific4&@CR)
                  Else
                      $iCheck +=1
                  EndIf
        Next

If NOT IsArray($strVendorSpecific4) then Return -1;Not a Smart capable drive
If NOT IsArray($strVendorSpecific2) then Return -1
    
    Dim $Status [22]
    For $i = 1 to 21
        $Status[$i] = "NotOk";default all status to "NotOK"
    Next

;if a status passes then Change it to OK
    If $strVendorSpecific[5] >= $strVendorSpecific2[3]  then $Status[1] = "OK"
    If $strVendorSpecific[17] >= $strVendorSpecific2[15] then $Status[2] = "OK"
    If $strVendorSpecific[29] >= $strVendorSpecific2[27] then $Status[3] = "OK"
    If $strVendorSpecific[41] >= $strVendorSpecific2[39] then $Status[4] = "OK"
    If $strVendorSpecific[53] >= $strVendorSpecific2[51] then $Status[5] = "OK"
    If $strVendorSpecific[65] >= $strVendorSpecific2[63] then $Status[6] = "OK"
    If $strVendorSpecific[77] >= $strVendorSpecific2[75] then $Status[7] = "OK"
    If $strVendorSpecific[89] >= $strVendorSpecific2[87] then $Status[8] = "OK"
    If $strVendorSpecific[101] >= $strVendorSpecific2[99] then $Status[9] = "OK"
    If $strVendorSpecific[113] >= $strVendorSpecific2[111] then $Status[10] = "OK"
    If $strVendorSpecific[125] >= $strVendorSpecific2[123] then $Status[11] = "OK"
    If $strVendorSpecific[137] >= $strVendorSpecific2[135] then $Status[12] = "OK"
    If $strVendorSpecific[149] >= $strVendorSpecific2[147] then $Status[13] = "OK"
    If $strVendorSpecific[161] >= $strVendorSpecific2[159] then $Status[14] = "OK"
    If $strVendorSpecific[173] >= $strVendorSpecific2[171] then $Status[15] = "OK"
    If $strVendorSpecific[185] >= $strVendorSpecific2[183] then $Status[16] = "OK"
    If $strVendorSpecific[197] >= $strVendorSpecific2[195] then $Status[17] = "OK"
    If $strVendorSpecific[206] >= $strVendorSpecific2[204] then $Status[18] = "OK"
    If $strVendorSpecific[218] >= $strVendorSpecific2[216] then $Status[19] = "OK"
    If $strVendorSpecific[230] >= $strVendorSpecific2[228] then $Status[20] = "OK"
    If $strVendorSpecific[242] >= $strVendorSpecific2[240] then $Status[21] = "OK"
    
    

    Dim $aSmartData[1][8] = [["ID","Attribute","Type","Flag","Threshold","Value","Worst","Status"]]
    $iCnt=1
    For $x = 2 to 242 Step 12 
        If $strVendorSpecific[$x] <> 0 then;0 id is not valid for this Smart Device
            $NextRow = Ubound($aSmartData)
            Redim $aSmartData[$NextRow +1][8]
                $aSmartData[$NextRow][0] = $strVendorSpecific[$x];ID
                $aSmartData[$NextRow][1] = $oDict.Item($strVendorSpecific[$x]);Attribute
                If $aSmartData[$NextRow][1] = "" then $aSmartData[$NextRow][1] = "Unknown SMART Attribute"
                
                If Mod($strVendorSpecific[$x +1],2) then;Type If odd number then it is a pre-failure value
                    $aSmartData[$NextRow][2] = "Pre-Failure" 
                Else
                    $aSmartData[$NextRow][2] = "Advisory" 
                EndIf
                #region
            ;Old method not needed now
            ;$aSmartData[$NextRow][2] = $oDictType.Item($strVendorSpecific[$x])
            ;If $aSmartData[$NextRow][2] = "" then $aSmartData[$NextRow][2] = "Advisory"
                #endregion
                $aSmartData[$NextRow][3] = $strVendorSpecific[$x +1];Flag
                $aSmartData[$NextRow][4] = $strVendorSpecific2[$x +1];Threshold
                $aSmartData[$NextRow][5] = $strVendorSpecific[$x +3];Value
                $aSmartData[$NextRow][6] = $strVendorSpecific[$x +4];Worst
                $aSmartData[$NextRow][7] = $Status[$iCnt];Status
            EndIf
            $iCnt+=1
    Next
        
            Return  $aSmartData
EndFunc

Func _PartitionToPhysicalDriveID($vPart)

    $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
    $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_DiskDriveToDiskPartition", "WQL", _
                                          $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
    If IsObj($colItems) then
       For $objItem In $colItems
           If $objItem.Dependent == $vPart then 
               $vPdisk = $objItem.Antecedent
               $vPdisk = StringReplace(StringTrimLeft($vPdisk,Stringinstr($vPdisk,"=")),'"',"")
               $strDeviceID = StringReplace($vPdisk, "\\", "\")
                Return $strDeviceID
            Endif
       Next
    Endif
    Return -1
EndFunc

Func _PNPIDFromPhysicalDriveID($vDriveID)
    
    $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_DiskDrive", "WQL", _
                                          $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
    If IsObj($colItems) then
       For $objItem In $colItems
        If $objItem.DeviceID == $vDriveID then
          Return $objItem.PNPDeviceID
        EndIf
      Next
    Endif
    Return -1
EndFunc

Func _LogicalToPartition ($vDriveLet)

    Local $objWMIService,$colItems,$vAntecedent,$vPartition
    
    $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
    $colItems = $objWMIService.ExecQuery("SELECT Dependent,Antecedent FROM Win32_LogicalDiskToPartition", "WQL", _
                                              $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
    If IsObj($colItems) then
       For $objItem In $colItems
           If StringRight($objItem.Dependent,4) == $vDriveLet then 
            $vAntecedent=$objItem.Antecedent
          Return $vAntecedent;$partition
        EndIf
       Next
    Endif
    Return -1
EndFunc


Func _CreateDict()
    $oDict.Add(1,"Read Error Rate")
    $oDict.Add(2,"Throughput Performance")
    $oDict.Add(3,"Spin-Up Time")
    $oDict.Add(4,"Start/Stop Count")
    $oDict.Add(5,"Reallocated Sectors Count")
    $oDict.Add(6,"Read Channel Margin")
    $oDict.Add(7,"Seek Error Rate Rate")
    $oDict.Add(8,"Seek Time Performance")
    $oDict.Add(9,"Power-On Hours (POH)")
    $oDict.Add(10,"Spin Retry Count")
    $oDict.Add(11,"Recalibration Retries")
    $oDict.Add(12,"Device Power Cycle Count")
    $oDict.Add(13,"Soft Read Error Rate")
    $oDict.Add(191,"G-Sense Error Rate Frequency")
    $oDict.Add(192,"Power-Off Park Count")
    $oDict.Add(193,"Load/Unload Cycle")
    $oDict.Add(194,"HDA Temperature")
    $oDict.Add(195,"ECC Corrected Count")
    $oDict.Add(196,"Reallocated Event Count")
    $oDict.Add(197,"Current Pending Sector Count")
    $oDict.Add(198,"Uncorrectable Sector Count")
    $oDict.Add(199,"UltraDMA CRC Error Count")
    $oDict.Add(200,"Write Error Rate")
    $oDict.Add(201,"Soft Read Error Rate")
    $oDict.Add(202,"Address Mark Errors Frequency")
    $oDict.Add(203,"ECC errors (Maxtor: ECC Errors)")
    $oDict.Add(204, "Soft ECC Correction")
    $oDict.Add(205, "Thermal Asperity Rate (TAR)")
    $oDict.Add(206, "Flying Height")
    $oDict.Add(207, "Spin High Current")
    $oDict.Add(208, "Spin Buzz")
    $oDict.Add(209, "Offline Seek")
    $oDict.Add(220, "Disk Shift")
    $oDict.Add(221, "G-Sense Error Rate")
    $oDict.Add(222, "Loaded Hours")
    $oDict.Add(223, "Load/Unload Retry Count")
    $oDict.Add(224, "Load Friction")
    $oDict.Add(225, "/Unload Cycle Count")
    $oDict.Add(226, "Load 'In'-time")
    $oDict.Add(227, "Torque Amplification Count")
    $oDict.Add(228, "Power-Off Retract Cycle")
    $oDict.Add(230, "GMR Head Amplitude")
    $oDict.Add(231, "Temperature")
    $oDict.Add(240, "Head Flying Hours")
    $oDict.Add(250, "Read Error Retry Rate")
EndFunc



;This is COM error handler
Func MyErrFunc()
  $HexNumber=hex($oMyError.number,8)
  Return
  Msgbox(0,"COM Error Test","We intercepted a COM Error !"     & @CRLF  & @CRLF & _
             "err.description is: " & @TAB & $oMyError.description  & @CRLF & _
             "err.windescription:"   & @TAB & $oMyError.windescription & @CRLF & _
             "err.number is: "       & @TAB & $HexNumber              & @CRLF & _
             "err.lastdllerror is: "   & @TAB & $oMyError.lastdllerror   & @CRLF & _
             "err.scriptline is: "   & @TAB & $oMyError.scriptline   & @CRLF & _
             "err.source is: "       & @TAB & $oMyError.source       & @CRLF & _
             "err.helpfile is: "       & @TAB & $oMyError.helpfile     & @CRLF & _
             "err.helpcontext is: " & @TAB & $oMyError.helpcontext _
            )
  SetError(1) ; to check for after this function returns
Endfunc

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Link to comment
Share on other sites

@GEOSoft

Good job !!

regards

ptrex

Thanks. I just hope that solves it for everyone. If not then I have a test version I'll post to see why it fails.

When I get a chance I'll work on a GUI version.

Edited by GEOSoft

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Link to comment
Share on other sites

@GEOSoft

Sorry to inform you but your version still checks my floppy drive

Thnx

Emiel

Thanks Emiel PM with test code is on the way. There has been a change also to the flags so don't jump when you see that. They are now in hex to make it more compatible with other tools of this nature.

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Link to comment
Share on other sites

@GEOSoft

Same as Emiel ... It checks the floppy for me too ...

You get the next test :)

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Link to comment
Share on other sites

I still have not found the floppy drive problem but as promised here is a GUI version that I threw together.

Features:

Select the drive to analyze from a Combobox

If the advisory type is Pre-Failure and the status is NOT OK then the row will be high-lighted in a light red and the row text will be red. There will also be a Large "Warning !" displayed in the bottom right.

If the advisory type is Advisory and the status is NOT OK then the row is high-lighted in yellow. No warning will appear.

The credits for the WMI portion of the code go to ptrex and ChrisL. I just made a few modifications to it and added the GUI.

EDIT: I know this can be shortened but like I said it was thrown together.

EDIT 2: If you want to try the compiled version then just click this link and you can run it from my site.

Smart_Analysis.exe

EDIT 3: Corrected undeclared variable when the drive was not S.M.A.R.T. capable. File on site has been fixed as well.

#cs
   This AutoIt script file was generated by Project Express 4.0.6.9 Mar 09 / 2008
   AutoIt Compiler Version:         3.2.11.1
   Language:        English (US)
   Platform:        All
   Author:      George Gedye
   Company:         GEOSoft Software
   E-Mail:      geog AT mvps DOT org
  ;
   PX Project Name:         Smart Analysis
   Project Description:         S.M.A.R.T.  Drive Analysis GUI
   Remarks                              WMI analysis code by ptrex and ChrisL
#ce
Opt ("GUICoordMode","2")
Const $wbemFlagReturnImmediately = 0x10
Const $wbemFlagForwardOnly = 0x20
Dim $strComputer = "." 
Dim $objWMIService, $oMyError, $oDict, $oDictType
Dim $colItems, $strReserved, $strVendorSpecific, $strVendorSpecific4, $Output
$oMyError = ObjEvent("AutoIt.Error","MyErrFunc")
$fWarn = False
$Drives = DriveGetDrive("Fixed")
$Comb_Data = StringUpper(_ArrayToString($Drives,"|", 1))
Local $Col_w1 = 190, $Col_w2 = 70, $Col_w3 = 70, $Col_w4 = 60, $Col_w5 = 40, $Col_w6 = 40,$Col_w7 = 60
$Frm_Main = GUICreate("S.M.A.R.T. Drive Analysis", 570,410)
GUISetFont(10)
$Lbl_Dsel = GUICtrlCreateLabel("Select Drive", 10,10, 80, 20)
$Combo_Dsel = GUICtrlCreateCombo("", 0,-1, 60, 30)
$Lbl_Proc = GUICtrlCreateLabel("", 20, -1, 280, 20)
GUICtrlSetData($Combo_Dsel, $Comb_Data, StringUpper($Drives[1]))
GuiSetCoord(10, 45)
$Lbl_Attrib = GUICtrlCreateLabel("Attribute", -1,-1, $Col_w1,30, 1)
$Lbl_Type = GUICtrlCreateLabel("Type", 3, -1,$Col_w2,-1,1)
$Lbl_Flag = GUICtrlCreateLabel("Flag", 3, -1, $Col_w3, -1,1)
$Lbl_Thresh = GUICtrlCreateLabel("Threshold", 3, -1, $Col_w4, -1,1)
$Lbl_Val = GUICtrlCreateLabel("Value", 3, -1, $Col_w5, -1,1)
$Lbl_Worst = GUICtrlCreateLabel("Worst", 3, -1, $Col_w6, -1,1)
$Lbl_Stat = GUICtrlCreateLabel("Status", 3, -1, $Col_w7, -1,1)
GuiSetCoord(10,65)
$Lbl_Attrib1 = GUICtrlCreateLabel("", -1,-1, $Col_w1,20)
$Lbl_Type1 = GUICtrlCreateLabel("", 3, -1,$Col_w2,-1,1)
$Lbl_Flag1 = GUICtrlCreateLabel("", 3, -1, $Col_w3, -1,1)
$Lbl_Thresh1 = GUICtrlCreateLabel("", 3, -1, $Col_w4, -1,1)
$Lbl_Val1 = GUICtrlCreateLabel("", 3, -1, $Col_w5, -1,1)
$Lbl_Worst1 = GUICtrlCreateLabel("", 3, -1, $Col_w6, -1,1)
$Lbl_Stat1 = GUICtrlCreateLabel("", 3, -1, $Col_w7, -1,1)
GUISetCoord(10,85)
$Lbl_Attrib2 = GUICtrlCreateLabel("", -1,-1, $Col_w1,20)
$Lbl_Type2 = GUICtrlCreateLabel("", 3, -1,$Col_w2,-1,1)
$Lbl_Flag2 = GUICtrlCreateLabel("", 3, -1, $Col_w3, -1,1)
$Lbl_Thresh2 = GUICtrlCreateLabel("", 3, -1, $Col_w4, -1,1)
$Lbl_Val2 = GUICtrlCreateLabel("", 3, -1, $Col_w5, -1,1)
$Lbl_Worst2 = GUICtrlCreateLabel("", 3, -1, $Col_w6, -1,1)
$Lbl_Stat2 = GUICtrlCreateLabel("", 3, -1, $Col_w7, -1,1)
GuiSetCoord(10,105)
$Lbl_Attrib3 = GUICtrlCreateLabel("", -1,-1, $Col_w1,20)
$Lbl_Type3 = GUICtrlCreateLabel("", 3, -1,$Col_w2,-1,1)
$Lbl_Flag3 = GUICtrlCreateLabel("", 3, -1, $Col_w3, -1,1)
$Lbl_Thresh3 = GUICtrlCreateLabel("", 3, -1, $Col_w4, -1,1)
$Lbl_Val3 = GUICtrlCreateLabel("", 3, -1, $Col_w5, -1,1)
$Lbl_Worst3 = GUICtrlCreateLabel("", 3, -1, $Col_w6, -1,1)
$Lbl_Stat3 = GUICtrlCreateLabel("", 3, -1, $Col_w7, -1,1)
GuiSetCoord(10, 125)
$Lbl_Attrib4 = GUICtrlCreateLabel("", -1,-1, $Col_w1,20)
$Lbl_Type4 = GUICtrlCreateLabel("", 3, -1,$Col_w2,-1,1)
$Lbl_Flag4 = GUICtrlCreateLabel("", 3, -1, $Col_w3, -1,1)
$Lbl_Thresh4 = GUICtrlCreateLabel("", 3, -1, $Col_w4, -1,1)
$Lbl_Val4 = GUICtrlCreateLabel("", 3, -1, $Col_w5, -1,1)
$Lbl_Worst4 = GUICtrlCreateLabel("", 3, -1, $Col_w6, -1,1)
$Lbl_Stat4 = GUICtrlCreateLabel("", 3, -1, $Col_w7, -1,1)
GuiSetCoord(10, 145)
$Lbl_Attrib5 = GUICtrlCreateLabel("", -1,-1, $Col_w1,20)
$Lbl_Type5 = GUICtrlCreateLabel("", 3, -1,$Col_w2,-1,1)
$Lbl_Flag5 = GUICtrlCreateLabel("", 3, -1, $Col_w3, -1,1)
$Lbl_Thresh5 = GUICtrlCreateLabel("", 3, -1, $Col_w4, -1,1)
$Lbl_Val5 = GUICtrlCreateLabel("", 3, -1, $Col_w5, -1,1)
$Lbl_Worst5 = GUICtrlCreateLabel("", 3, -1, $Col_w6, -1,1)
$Lbl_Stat5 = GUICtrlCreateLabel("", 3, -1, $Col_w7, -1,1)
GuiSetCoord(10, 165)
$Lbl_Attrib6 = GUICtrlCreateLabel("", -1,-1, $Col_w1,20)
$Lbl_Type6 = GUICtrlCreateLabel("", 3, -1,$Col_w2,-1,1)
$Lbl_Flag6 = GUICtrlCreateLabel("", 3, -1, $Col_w3, -1,1)
$Lbl_Thresh6 = GUICtrlCreateLabel("", 3, -1, $Col_w4, -1,1)
$Lbl_Val6 = GUICtrlCreateLabel("", 3, -1, $Col_w5, -1,1)
$Lbl_Worst6 = GUICtrlCreateLabel("", 3, -1, $Col_w6, -1,1)
$Lbl_Stat6 = GUICtrlCreateLabel("", 3, -1, $Col_w7, -1,1)
GuiSetCoord(10, 185)
$Lbl_Attrib7 = GUICtrlCreateLabel("", -1,-1, $Col_w1,20)
$Lbl_Type7 = GUICtrlCreateLabel("", 3, -1,$Col_w2,-1,1)
$Lbl_Flag7 = GUICtrlCreateLabel("", 3, -1, $Col_w3, -1,1)
$Lbl_Thresh7 = GUICtrlCreateLabel("", 3, -1, $Col_w4, -1,1)
$Lbl_Val7 = GUICtrlCreateLabel("", 3, -1, $Col_w5, -1,1)
$Lbl_Worst7 = GUICtrlCreateLabel("", 3, -1, $Col_w6, -1,1)
$Lbl_Stat7 = GUICtrlCreateLabel("", 3, -1, $Col_w7, -1,1)
GuiSetCoord(10, 205)
$Lbl_Attrib8 = GUICtrlCreateLabel("", -1,-1, $Col_w1,20)
$Lbl_Type8 = GUICtrlCreateLabel("", 3, -1,$Col_w2,-1,1)
$Lbl_Flag8 = GUICtrlCreateLabel("", 3, -1, $Col_w3, -1,1)
$Lbl_Thresh8 = GUICtrlCreateLabel("", 3, -1, $Col_w4, -1,1)
$Lbl_Val8 = GUICtrlCreateLabel("", 3, -1, $Col_w5, -1,1)
$Lbl_Worst8 = GUICtrlCreateLabel("", 3, -1, $Col_w6, -1,1)
$Lbl_Stat8 = GUICtrlCreateLabel("", 3, -1, $Col_w7, -1,1)
GuiSetCoord(10, 225)
$Lbl_Attrib9 = GUICtrlCreateLabel("", -1,-1, $Col_w1,20)
$Lbl_Type9 = GUICtrlCreateLabel("", 3, -1,$Col_w2,-1,1)
$Lbl_Flag9 = GUICtrlCreateLabel("", 3, -1, $Col_w3, -1,1)
$Lbl_Thresh9 = GUICtrlCreateLabel("", 3, -1, $Col_w4, -1,1)
$Lbl_Val9 = GUICtrlCreateLabel("", 3, -1, $Col_w5, -1,1)
$Lbl_Worst9 = GUICtrlCreateLabel("", 3, -1, $Col_w6, -1,1)
$Lbl_Stat9 = GUICtrlCreateLabel("", 3, -1, $Col_w7, -1,1)
GuiSetCoord(10, 245)
$Lbl_Attrib10 = GUICtrlCreateLabel("", -1,-1, $Col_w1,20)
$Lbl_Type10 = GUICtrlCreateLabel("", 3, -1,$Col_w2,-1,1)
$Lbl_Flag10 = GUICtrlCreateLabel("", 3, -1, $Col_w3, -1,1)
$Lbl_Thresh10 = GUICtrlCreateLabel("", 3, -1, $Col_w4, -1,1)
$Lbl_Val10 = GUICtrlCreateLabel("", 3, -1, $Col_w5, -1,1)
$Lbl_Worst10 = GUICtrlCreateLabel("", 3, -1, $Col_w6, -1,1)
$Lbl_Stat10 = GUICtrlCreateLabel("", 3, -1, $Col_w7, -1,1)
GuiSetCoord(10, 265)
$Lbl_Attrib11 = GUICtrlCreateLabel("", -1,-1, $Col_w1,20)
$Lbl_Type11 = GUICtrlCreateLabel("", 3, -1,$Col_w2,-1,1)
$Lbl_Flag11 = GUICtrlCreateLabel("", 3, -1, $Col_w3, -1,1)
$Lbl_Thresh11 = GUICtrlCreateLabel("", 3, -1, $Col_w4, -1,1)
$Lbl_Val11 = GUICtrlCreateLabel("", 3, -1, $Col_w5, -1,1)
$Lbl_Worst11 = GUICtrlCreateLabel("", 3, -1, $Col_w6, -1,1)
$Lbl_Stat11 = GUICtrlCreateLabel("", 3, -1, $Col_w7, -1,1)
GuiSetCoord(10, 285)
$Lbl_Attrib12 = GUICtrlCreateLabel("", -1,-1, $Col_w1,20)
$Lbl_Type12 = GUICtrlCreateLabel("", 3, -1,$Col_w2,-1,1)
$Lbl_Flag12 = GUICtrlCreateLabel("", 3, -1, $Col_w3, -1,1)
$Lbl_Thresh12 = GUICtrlCreateLabel("", 3, -1, $Col_w4, -1,1)
$Lbl_Val12 = GUICtrlCreateLabel("", 3, -1, $Col_w5, -1,1)
$Lbl_Worst12 = GUICtrlCreateLabel("", 3, -1, $Col_w6, -1,1)
$Lbl_Stat12 = GUICtrlCreateLabel("", 3, -1, $Col_w7, -1,1)
GuiSetCoord(10, 305)
$Lbl_Attrib13 = GUICtrlCreateLabel("", -1,-1, $Col_w1,20)
$Lbl_Type13 = GUICtrlCreateLabel("", 3, -1,$Col_w2,-1,1)
$Lbl_Flag13 = GUICtrlCreateLabel("", 3, -1, $Col_w3, -1,1)
$Lbl_Thresh13 = GUICtrlCreateLabel("", 3, -1, $Col_w4, -1,1)
$Lbl_Val13 = GUICtrlCreateLabel("", 3, -1, $Col_w5, -1,1)
$Lbl_Worst13 = GUICtrlCreateLabel("", 3, -1, $Col_w6, -1,1)
$Lbl_Stat13 = GUICtrlCreateLabel("", 3, -1, $Col_w7, -1,1)
GuiSetCoord(10, 325)
$Lbl_Attrib14 = GUICtrlCreateLabel("", -1,-1, $Col_w1,20)
$Lbl_Type14 = GUICtrlCreateLabel("", 3, -1,$Col_w2,-1,1)
$Lbl_Flag14 = GUICtrlCreateLabel("", 3, -1, $Col_w3, -1,1)
$Lbl_Thresh14 = GUICtrlCreateLabel("", 3, -1, $Col_w4, -1,1)
$Lbl_Val14 = GUICtrlCreateLabel("", 3, -1, $Col_w5, -1,1)
$Lbl_Worst14 = GUICtrlCreateLabel("", 3, -1, $Col_w6, -1,1)
$Lbl_Stat14 = GUICtrlCreateLabel("", 3, -1, $Col_w7, -1,1)
GuiSetCoord(10, 345)
$Lbl_Attrib15 = GUICtrlCreateLabel("", -1,-1, $Col_w1,20)
$Lbl_Type15 = GUICtrlCreateLabel("", 3, -1,$Col_w2,-1,1)
$Lbl_Flag15 = GUICtrlCreateLabel("", 3, -1, $Col_w3, -1,1)
$Lbl_Thresh15 = GUICtrlCreateLabel("", 3, -1, $Col_w4, -1,1)
$Lbl_Val15 = GUICtrlCreateLabel("", 3, -1, $Col_w5, -1,1)
$Lbl_Worst15 = GUICtrlCreateLabel("", 3, -1, $Col_w6, -1,1)
$Lbl_Stat15 = GUICtrlCreateLabel("", 3, -1, $Col_w7, -1,1)
GuiSetCoord(240, 370)
$Btn_Chk = GUICtrlCreateButton("Check Drive", -1, -1, 80, 30)
$Lbl_Warn = GUICtrlCreateLabel( "", 40, -1, 120, 30, 1)
GUICtrlSetFont($Lbl_Warn, 14, 600)
GUICtrlSetColor($Lbl_Warn, 0xFF0000)
For $I = $Lbl_Attrib To $Lbl_Stat
   GUICtrlSetBkColor($I,0x00FFFF)
Next
For $I = $Lbl_Attrib1 To $Lbl_Stat15
   GUICtrlSetBkColor($I, 0xBFFFB1)
Next
GUISetState()
While 1
   $Msg = GUIGetMsg()
   Switch $Msg
      Case -3
         Exit
      Case $Btn_Chk
         $Drive = GUICtrlRead($Combo_Dsel)
         GUICtrlSetState($Btn_Chk, 144)
         For $I = $Lbl_Attrib1 To $Lbl_Stat15
            GUICtrlSetBkColor($I, 0xBFFFB1)
            GUICtrlSetData($I, "")
            GUICtrlSetColor($I, 0x000000)
         Next
         GUICtrlSetData($Lbl_Warn, "")
         GUICtrlSetData($Lbl_Proc, "Checking S.M.A.R.T. Data For Drive...  " & $Drive & "\")
         
         $SmartData = _GetSmartData($Drive)
         
         GUICtrlSetData($Lbl_Proc,"")
         If $smartData <> -1 then 
            $sLbl = $Lbl_Attrib1
            For $I = 1 To Ubound($smartData) -1
               For $J = 1 To 7
                  GUICtrlSetData($sLbl, $smartData[$I][$J])
                  If $J = 7 AND $SmartData[$I][$J] = "NOT OK" Then
                     $rColor = 0xFAFCA0
                     $fColor = 0x000000
                     If $SmartData[$I][$J -5] = "Pre-Failure" Then
                        $rColor = 0xFFABFF
                        $fColor = 0xFF0000
                        $fWarn = True
                     EndIf
                     For $L = $sLbl -6 To $sLbl
                        GUICtrlSetBkColor($L, $rColor)
                        GUICtrlSetColor($L, $fColor)
                     Next
                  EndIf
                  $sLbl += 1
               Next
            Next
         Else
            Msgbox(0,"",Unable to check " & $drive & @CRLF & "The drive may not be S.M.A.R.T. capable")
         EndIf
         GUICtrlSetState($Btn_Chk, 80)
         If $fWarn Then GUICtrlSetData($Lbl_Warn, "WARNING !")
   EndSwitch
Wend


Func _GetSmartData($vDrive  = "C:")
   If DriveStatus ( $vDrive ) <> "Ready" then 
      SetError(1)
      Return -1
   EndIf
   
   If StringLeft($vDrive,1) <> '"' then $vDrive = '"' & $vDrive
   If StringRight($vDrive,1) <> '"' then $vDrive &= '"'
   
   Local $iCnt, $iCheck, $vPartition,$vDeviceID,$vPNPID
   
   $vPartition = _LogicalToPartition ($vDrive)
   If $vPartition = -1 then Return -1
   
   $vDeviceID = _PartitionToPhysicalDriveID($vPartition)
   If $vDeviceID = -1 then Return -1
   
   $vPNPID = _PNPIDFromPhysicalDriveID($vDeviceID)
   If $vPNPID = -1 then Return -1
   
   $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\WMI")
   $oDict = ObjCreate("Scripting.Dictionary")
   
   $colItems1 = $objWMIService.ExecQuery("SELECT * FROM MSStorageDriver_ATAPISmartData", "WQL", _
         $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
   
   $colItems2 = $objWMIService.ExecQuery("SELECT * FROM MSStorageDriver_FailurePredictThresholds", "WQL", _
         $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
   
   $colItems3 = $objWMIService.ExecQuery("SELECT * FROM MSStorageDriver_FailurePredictStatus", "WQL", _
         $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
   
   _CreateDict(); Create Dictionary
   ConsoleWrite ($strComputer&@CR)                            
   
   $iCnt = 1
   For $objItem In $colItems1
      If StringLeft($objItem.InstanceName,StringLen($vPNPID)) = String($vPNPID) AND StringLeft($objItem.InstanceName, 3) = "ide" then 
         ConsoleWrite ("Active: " & $objItem.Active&@CR)
         ConsoleWrite ("Checksum: " & $objItem.Checksum&@CR)
         ConsoleWrite ("ErrorLogCapability: " & $objItem.ErrorLogCapability&@CR)
         ConsoleWrite ("ExtendedPollTimeInMinutes: " & $objItem.ExtendedPollTimeInMinutes&@CR)
         ConsoleWrite ("InstanceName: " & $objItem.InstanceName&@CR)
         ConsoleWrite ("Length: " & $objItem.Length&@CR)
         ConsoleWrite ("OfflineCollectCapability: " & $objItem.OfflineCollectCapability&@CR)
         ConsoleWrite ("OfflineCollectionStatus: " & $objItem.OfflineCollectionStatus&@CR)
         $strReserved = $objItem.Reserved
         ConsoleWrite ("Reserved: " & _ArrayToString($strReserved,",")&@CR)
         ConsoleWrite ("SelfTestStatus: " & $objItem.SelfTestStatus&@CR)
         ConsoleWrite ("ShortPollTimeInMinutes: " & $objItem.ShortPollTimeInMinutes&@CR)
         ConsoleWrite ("SmartCapability: " & $objItem.SmartCapability&@CR)
         ConsoleWrite ("TotalTime: " & $objItem.TotalTime&@CR)
         $strVendorSpecific = $objItem.VendorSpecific
         ConsoleWrite ("VendorSpecific: " & _ArrayToString($strVendorSpecific,",")&@CR)
         ConsoleWrite ("VendorSpecific2: " & $objItem.VendorSpecific2&@CR)
         ConsoleWrite ("VendorSpecific3: " & $objItem.VendorSpecific3&@CR)
         $strVendorSpecific4 = $objItem.VendorSpecific4
         ConsoleWrite ("VendorSpecific4: " & _ArrayToString($strVendorSpecific4,",")&@CR)
      Else
         
         $iCnt +=1
      EndIf
      
   Next
   
   
   $iCheck = 1
   For $objItem In $colItems2
      If $iCheck = $iCnt then 
         $strVendorSpecific2 = $objItem.VendorSpecific
         ConsoleWrite ("FailurePredictThresholds: " & _ArrayToString($strVendorSpecific2,",")&@CR)
      Else
         $iCheck +=1
      EndIf
   Next
   
   $iCheck = 1
   For $objItem In $colItems3
      If $iCheck = $iCnt then 
         $strVendorSpecific3 = $objItem.PredictFailure
         ConsoleWrite ("PredictFailure: " & $strVendorSpecific3&@CR)
         $strVendorSpecific3 = $objItem.Reason
         ConsoleWrite ("PredictReason: " & $strVendorSpecific4&@CR)
      Else
         $iCheck +=1
      EndIf
   Next
   
   If NOT IsArray($strVendorSpecific4) then Return -1;Not a Smart capable drive
   If NOT IsArray($strVendorSpecific2) then Return -1
   
   Dim $Status [22]
   For $i = 1 to 21
      $Status[$i] = "NOT OK";default all status to "NOT OK"
   Next
   
  ;if a status passes then Change it to OK
   If $strVendorSpecific[5] >= $strVendorSpecific2[3]  then $Status[1] = "OK"
   If $strVendorSpecific[17] >= $strVendorSpecific2[15] then $Status[2] = "OK"
   If $strVendorSpecific[29] >= $strVendorSpecific2[27] then $Status[3] = "OK"
   If $strVendorSpecific[41] >= $strVendorSpecific2[39] then $Status[4] = "OK"
   If $strVendorSpecific[53] >= $strVendorSpecific2[51] then $Status[5] = "OK"
   If $strVendorSpecific[65] >= $strVendorSpecific2[63] then $Status[6] = "OK"
   If $strVendorSpecific[77] >= $strVendorSpecific2[75] then $Status[7] = "OK"
   If $strVendorSpecific[89] >= $strVendorSpecific2[87] then $Status[8] = "OK"
   If $strVendorSpecific[101] >= $strVendorSpecific2[99] then $Status[9] = "OK"
   If $strVendorSpecific[113] >= $strVendorSpecific2[111] then $Status[10] = "OK"
   If $strVendorSpecific[125] >= $strVendorSpecific2[123] then $Status[11] = "OK"
   If $strVendorSpecific[137] >= $strVendorSpecific2[135] then $Status[12] = "OK"
   If $strVendorSpecific[149] >= $strVendorSpecific2[147] then $Status[13] = "OK"
   If $strVendorSpecific[161] >= $strVendorSpecific2[159] then $Status[14] = "OK"
   If $strVendorSpecific[173] >= $strVendorSpecific2[171] then $Status[15] = "OK"
   If $strVendorSpecific[185] >= $strVendorSpecific2[183] then $Status[16] = "OK"
   If $strVendorSpecific[197] >= $strVendorSpecific2[195] then $Status[17] = "OK"
   If $strVendorSpecific[206] >= $strVendorSpecific2[204] then $Status[18] = "OK"
   If $strVendorSpecific[218] >= $strVendorSpecific2[216] then $Status[19] = "OK"
   If $strVendorSpecific[230] >= $strVendorSpecific2[228] then $Status[20] = "OK"
   If $strVendorSpecific[242] >= $strVendorSpecific2[240] then $Status[21] = "OK"
   
   
   
   Dim $aSmartData[1][8] = [["ID","Attribute","Type","Flag","Threshold","Value","Worst","Status"]]
   $iCnt=1
   For $x = 2 to 242 Step 12 
      If $strVendorSpecific[$x] <> 0 then;0 id is not valid for this Smart Device
         $NextRow = Ubound($aSmartData)
         Redim $aSmartData[$NextRow +1][8]
         $aSmartData[$NextRow][0] = $strVendorSpecific[$x];ID
         $aSmartData[$NextRow][1] = $oDict.Item($strVendorSpecific[$x]);Attribute
         If $aSmartData[$NextRow][1] = "" then $aSmartData[$NextRow][1] = "Unknown SMART Attribute"
         
         If Mod($strVendorSpecific[$x +1],2) then;Type If odd number then it is a pre-failure value
         $aSmartData[$NextRow][2] = "Pre-Failure" 
      Else
         $aSmartData[$NextRow][2] = "Advisory" 
      EndIf
      $aSmartData[$NextRow][3] = "0x" & Hex($strVendorSpecific[$x +1], 4);Flag
      $aSmartData[$NextRow][4] = $strVendorSpecific2[$x +1];Threshold
      $aSmartData[$NextRow][5] = $strVendorSpecific[$x +3];Value
      $aSmartData[$NextRow][6] = $strVendorSpecific[$x +4];Worst
      $aSmartData[$NextRow][7] = $Status[$iCnt];Status
   EndIf
      $iCnt+=1
   Next

   Return   $aSmartData
EndFunc  ;<==> _GetSmartData($vDrive  = "C:")

Func _PartitionToPhysicalDriveID($vPart)
   
   $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
   $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_DiskDriveToDiskPartition", "WQL", _
         $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
   If IsObj($colItems) then
      For $objItem In $colItems
         If $objItem.Dependent == $vPart then 
            $vPdisk = $objItem.Antecedent
            $vPdisk = StringReplace(StringTrimLeft($vPdisk,Stringinstr($vPdisk,"=")),'"',"")
            $strDeviceID = StringReplace($vPdisk, "\\", "\")
            Return $strDeviceID
         Endif
      Next
   Endif
   Return -1
EndFunc  ;<==> _PartitionToPhysicalDriveID($vPart)

Func _PNPIDFromPhysicalDriveID($vDriveID)
   
   $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_DiskDrive", "WQL", _
         $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
   If IsObj($colItems) then
      For $objItem In $colItems
         If $objItem.DeviceID == $vDriveID then
            Return $objItem.PNPDeviceID
         EndIf
      Next
   Endif
   Return -1
EndFunc  ;<==> _PNPIDFromPhysicalDriveID($vDriveID)

Func _LogicalToPartition ($vDriveLet)
   Local $objWMIService,$colItems,$vAntecedent,$vPartition
   
   $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
   $colItems = $objWMIService.ExecQuery("SELECT Dependent,Antecedent FROM Win32_LogicalDiskToPartition", "WQL", _
         $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
   If IsObj($colItems) then
      For $objItem In $colItems
         If StringRight($objItem.Dependent,4) == $vDriveLet then 
            $vAntecedent=$objItem.Antecedent
            $Output &= $vDriveLet & "  =  " & StringRight($objItem.Dependent,4) & @CRLF
            Return $vAntecedent;$partition
         EndIf
      Next
   Endif
   Return -1
EndFunc  ;<==> _LogicalToPartition ($vDriveLet)


Func _CreateDict()
   $oDict.Add(1,"Read Error Rate")
   $oDict.Add(2,"Throughput Performance")
   $oDict.Add(3,"Spin-Up Time")
   $oDict.Add(4,"Start/Stop Count")
   $oDict.Add(5,"Reallocated Sectors Count")
   $oDict.Add(6,"Read Channel Margin")
   $oDict.Add(7,"Seek Error Rate Rate")
   $oDict.Add(8,"Seek Time Performance")
   $oDict.Add(9,"Power-On Hours (POH)")
   $oDict.Add(10,"Spin Retry Count")
   $oDict.Add(11,"Recalibration Retries")
   $oDict.Add(12,"Device Power Cycle Count")
   $oDict.Add(13,"Soft Read Error Rate")
   $oDict.Add(191,"G-Sense Error Rate Frequency")
   $oDict.Add(192,"Power-Off Park Count")
   $oDict.Add(193,"Load/Unload Cycle")
   $oDict.Add(194,"HDA Temperature")
   $oDict.Add(195,"ECC Corrected Count")
   $oDict.Add(196,"Reallocated Event Count")
   $oDict.Add(197,"Current Pending Sector Count")
   $oDict.Add(198,"Uncorrectable Sector Count")
   $oDict.Add(199,"UltraDMA CRC Error Count")
   $oDict.Add(200,"Write Error Rate")
   $oDict.Add(201,"Soft Read Error Rate")
   $oDict.Add(202,"Address Mark Errors Frequency")
   $oDict.Add(203,"ECC errors (Maxtor: ECC Errors)")
   $oDict.Add(204, "Soft ECC Correction")
   $oDict.Add(205, "Thermal Asperity Rate (TAR)")
   $oDict.Add(206, "Flying Height")
   $oDict.Add(207, "Spin High Current")
   $oDict.Add(208, "Spin Buzz")
   $oDict.Add(209, "Offline Seek")
   $oDict.Add(220, "Disk Shift")
   $oDict.Add(221, "G-Sense Error Rate")
   $oDict.Add(222, "Loaded Hours")
   $oDict.Add(223, "Load/Unload Retry Count")
   $oDict.Add(224, "Load Friction")
   $oDict.Add(225, "/Unload Cycle Count")
   $oDict.Add(226, "Load 'In'-time")
   $oDict.Add(227, "Torque Amplification Count")
   $oDict.Add(228, "Power-Off Retract Cycle")
   $oDict.Add(230, "GMR Head Amplitude")
   $oDict.Add(231, "Temperature")
   $oDict.Add(240, "Head Flying Hours")
   $oDict.Add(250, "Read Error Retry Rate")
EndFunc  ;<==> _CreateDict()

Func _ArrayToString(Const ByRef $avArray, $sDelim = "|", $iStart = 0, $iEnd = 0)
    If Not IsArray($avArray) Then Return SetError(1, 0, "")

    Local $sResult, $iUBound = UBound($avArray) - 1

; Bounds checking
    If $iEnd < 1 Or $iEnd > $iUBound Then $iEnd = $iUBound
    If $iStart < 0 Then $iStart = 0
    If $iStart > $iEnd Then Return SetError(2, 0, "")

; Combine
    For $i = $iStart To $iEnd
        $sResult &= $avArray[$i] & $sDelim
    Next

    Return StringTrimRight($sResult, StringLen($sDelim))
EndFunc  ;==>_ArrayToString


;This is COM error handler
Func MyErrFunc()
   $HexNumber=hex($oMyError.number,8)
   Return
   Msgbox(0,"COM Error Test","We intercepted a COM Error !"    & @CRLF  & @CRLF & _
         "err.description is: " & @TAB & $oMyError.description  & @CRLF & _
         "err.windescription:"   & @TAB & $oMyError.windescription & @CRLF & _
         "err.number is: "       & @TAB & $HexNumber              & @CRLF & _
         "err.lastdllerror is: "   & @TAB & $oMyError.lastdllerror   & @CRLF & _
         "err.scriptline is: "   & @TAB & $oMyError.scriptline   & @CRLF & _
         "err.source is: "       & @TAB & $oMyError.source       & @CRLF & _
         "err.helpfile is: "       & @TAB & $oMyError.helpfile     & @CRLF & _
         "err.helpcontext is: " & @TAB & $oMyError.helpcontext _
         )
   SetError(1) ; to check for after this function returns
Endfunc  ;<==> MyErrFunc()
Edited by GEOSoft

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...