![]() |
Re: SMART-Werte lesen
Hallo,
der Code von Muetze1 funktioniert ja, aber inzwischen gab es in dieser Experten-Diskussion (da kann ich nicht mithalten :stupid: ) doch ein paar Verbesserungen. Gibt es nun für den Code ein Update, oder kann man die alte Version gefahrlos nutzen? ;-) Gruß, ManuMF |
Re: SMART-Werte lesen
Gib's morgen, heute abend bin ich gesellschaftlich verpflichtet. Ansonsten will ich noch einen anderen Ansatz über das SPTI Interface machen, welches dann auch S-ATA mit bedienen kann.
|
Re: SMART-Werte lesen
Hallo,
cool, danke! Ich habe aber noch mal eine Frage zu folgendem Code (mit der Ergänzung von Daniel G):
Delphi-Quellcode:
Ich möchte mir das ganze so umschreiben, dass ich später die Werte einzeln auslesen kann (aus einer StringList). Dazu verwende ich dann aus der CodeLibrary eine Funktion, um einen String anhand eines Trennzeichens zu zerlegen. Jetzt ist meine Frage: Wie muss der Format-String lauten, um statt der Leerzeichen jeweils einmal das Trennzeichen auszugeben? Mit Format habe ich immer noch so meine Probleme.
AOut.Add(Format('%.2X %-29s%d%20s%d%20s%d', [lDA^.bAttrID,
coAttrNames[lAttr], lDA^.bAttrValue, ' ', lAT^.bWarrantyThreshold, ' ', lDA^.bRAWValue[0]])); Gruß, ManuMF |
Re: SMART-Werte lesen
Warum legst du dir nicht lieber einen Record oder ein Objekt an, welches jeweils ein Attribut mit allen Merkmalen hält. Dieses kannst du zu dem jeweiligen Eintrag in z.B. einer ListBox mit vermerken. Ich halte grundlegend und absolut nix davon, binäre Daten in einen String zu verfrachten um dann das ganze wieder zurück zu den Daten zu verwandeln. Das ist doch Humbuck - Du hast die Daten ordentlich vorliegen, also nimm diese und nutze sie weiter.
|
Re: SMART-Werte lesen
Hallo,
mir sind die Umwege schon klar, aber ich möchte es so machen, damit ich deinen Code nicht komplett umschreiben muss. Außerdem soll das Programm für mich sein, und wenn ich mir die falschen Daten auslese, werde ich mich selbst für Schäden wohl kaum belangen, falls es darum geht ;-) Also noch einmal, mit großem "Bitte" ;-) : Wie lautet der Format-String? Gruß, ManuMF |
Re: SMART-Werte lesen
Zitat:
Und warum nicht meinen Code umstellen? Irgendein plausibler Grund, warum man das nicht umschreiben sollte?
Delphi-Quellcode:
Und das sind nicht alle Werte die in der Struktur pro Attribut zurück geliefert werden sondern nur ein Auszug. Ich hoffe das ist dir bewusst.
Format('%d;%s;%d;%d;%d', [lDA^.bAttrID,
coAttrNames[lAttr], lDA^.bAttrValue, lAT^.bWarrantyThreshold, lDA^.bRAWValue[0]]); |
Re: SMART-Werte lesen
Hallo,
ja, es ist mir bewusst. Ich prüfe dann anhand z.B. SpeedFan, welche Werte ich nehme, etwa bei der Temperatur der RAW-Wert. Es ging mir eigentlich nur darum, dass ich u.a. gesehen hatte, dass die ID nicht direkt als Dezimalzahl formatiert wird, deshalb war ich ein wenig verwirrt. Habe es jetzt so gelöst (mit #7 als Trennzeichen):
Delphi-Quellcode:
Gruß,
AOut.Add(Format('%.2x%s%s%s%d%s%d%s%d', [lDA^.bAttrID,
#7, coAttrNames[lAttr], #7, lDA^.bAttrValue, #7, lAT^.bWarrantyThreshold, #7, lDA^.bRAWValue[0]])); ManuMF |
Re: SMART-Werte lesen
Warum nicht einfach die #7 in den String anstatt ihn einfügen zu lassen?
Sprich: '%.2x'#7'%s'#7'%d'#7'%d'#7'%d' ? Ansonsten ein Crashkurs: %.2x%s%s%s%d%s%d%s%d ergibt folgende Teile: 1. %.2x 2.-4. %s 5. %d 6. %s 7. %d 8. %s 9. %d 2., 3., 4., 6. und 8. sind jeweils ein Platzhalter für eine Zeichenkette die eingefügt wird. 5., 7., 9. sind Platzhalter für einen ganzzahligen Wert, welcher dezimal ausgegegebn wird und ein Vorkomma haben kann. 1. ist ein Platzhalter für einen ganzzahligen Wert, welcher in hexadezimaler Schreibweise ausgegeben wird (das x besagt die hexadezimale Schreibweise in kleinen Buchstaben, ein grosses X würde grosse Buchstaben erzeugen) und der Punkt gibt an, dass du die Breite der Ausgabe festlegen willst. Die 2 nach dem Punkt sagt dann, dass die Ausgabe immer 2 Zeichen breit sein soll. Wenn nun also die hexadezimale Zahl kürzer ist, wird mit Leerzeichen vor der Zahl aufgefüllt. Hättest du die Leerzeichen lieber nach der Zahl, dann hättest du -2 schreiben sollen. Hättest du anstatt Leerzeichen lieber Nullen vor der Zahl, dann hättest du 02 schreiben müssen. |
Re: SMART-Werte lesen
Hallo,
danke, jetzt wird mir einiges klar. :-D Und stimmt, ich hätte die Zeichen direkt reinschreiben können, warum auch immer ich es nicht habe :gruebel: |
Re: SMART-Werte lesen
Ihr geht doch jetzt auch mehrere \\.\PhysicalDriveX durch?
Hab jetzt mal bemerkt, daß meine IDE-Platte doch S.M.A.R.T kann (obwohl das BIOS immernoch sagt dort sei es "disabled" :gruebel: Die Demo aus ![]() Ist also (wie ich grad bemerkte) das selbe "Problem" wie in ![]()
Code:
//WinNT+
unit Mainform; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Memo1: TMemo; procedure Button1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} Uses SmartIOCTL, SmartFunc; Procedure TForm1.Button1Click(Sender: TObject); Var lSmartHandle: THandle; lError: LongWord; lVersionInfo: TGetVersionOutParams; [color=red]i, i2: Integer;[/color] lBytesReturned: LongWord; lSuccess: Boolean; bIDCmd, bDfpDriveMap : Byte; lInCmd: TSendCmdInParams; lOutCmd: TSendCmdOutParams; lIdOutCmd: Pointer; lAttrOutCmd: Pointer; lThreshOutCmd: Pointer; Begin Memo1.Lines.Clear; [color=red]For i2 := 0 to 0 Do Begin[/color] bDfpDriveMap := 0; [color=red]lSmartHandle := CreateFile(PChar('\\.\PhysicalDrive' + IntToStr(i2)), GENERIC_READ Or GENERIC_WRITE, FILE_SHARE_READ Or FILE_SHARE_WRITE, Nil, OPEN_EXISTING, 0, 0);[/color] If ( lSmartHandle = INVALID_HANDLE_VALUE ) Then Begin lError := GetLastError; If ( Win32Platform = VER_PLATFORM_WIN32_WINDOWS ) Then Memo1.Lines.Add(format('Unable to open SMARTVSD, error code: 0x%.08X (%s)', [lError, SysErrorMessage(lError)])) Else If ( Win32Platform = VER_PLATFORM_WIN32_NT ) Then Memo1.Lines.Add(format('Unable to open physical drive, error code: 0x%.08X (%s)', [lError, SysErrorMessage(lError)])); Exit; End Else Memo1.Lines.Add('SMART interface opened...'); GetMem(lIdOutCmd, SizeOf(TSendCmdOutParams) + IDENTIFY_BUFFER_SIZE - 1); GetMem(lAttrOutCmd, SizeOf(TSendCmdOutParams) + READ_ATTRIBUTE_BUFFER_SIZE - 1); GetMem(lThreshOutCmd, SizeOf(TSendCmdOutParams) + READ_THRESHOLD_BUFFER_SIZE - 1); Try If GetSMARTVersionInfo(lSmartHandle, lVersionInfo) Then Begin Memo1.Lines.Add('DFP_GET_VERSION returned:'); Memo1.Lines.Add(format(' bVersion = %d', [lVersionInfo.bVersion])); Memo1.Lines.Add(format(' bRevision = %d', [lVersionInfo.bRevision])); Memo1.Lines.Add(format(' fCapabilities = 0x%.08x', [lVersionInfo.fCapabilities])); Memo1.Lines.Add(format(' bReserved = 0x%x', [lVersionInfo.bReserved])); Memo1.Lines.Add(format(' bIDEDeviceMap = 0x%x', [lVersionInfo.bIDEDeviceMap])); // Memo1.Lines.Add(format(' cbBytesReturned = %d', cbBytesReturned); End Else Memo1.Lines.Add('DFP_GET_VERSION failed.'); For i := 0 To MAX_IDE_DRIVES Do Begin // // If there is a IDE device at number "i" issue commands // to the device. // If ( ( ( lVersionInfo.bIDEDeviceMap Shr i ) And 1 ) <> 0 ) Then Begin // // Try to enable SMART so we can tell if a drive supports it. // Ignore ATAPI devices. // If ( ( ( lVersionInfo.bIDEDeviceMap Shr i ) And $10 ) = 0 ) Then Begin FillChar(lInCmd, SizeOf(lInCmd), 0); FillChar(lOutCmd, SizeOf(lOutCmd), 0); If ( DoEnableSMART(lSmartHandle, @lInCmd, @lOutCmd, i, lBytesReturned) ) Then Begin Memo1.Lines.Add(format('SMART enabled on drive: %d', [i])); // // Mark the drive as SMART enabled // bDfpDriveMap := bDfpDriveMap Or ( 1 Shl i ); End Else Begin Memo1.Lines.Add(format('SMART Enable Command Failed, Drive: %d', [i])); Memo1.Lines.Add(format(' DriverStatus: bDriverError=0x%.08X, bIDEStatus=0x%.08X', [ lOutCmd.DriverStatus.bDriverError, lOutCmd.DriverStatus.bIDEStatus])); End; Memo1.Lines.Add(Format(' cbBytesReturned: %d', [lBytesReturned])); End; // // Now, get the ID sector for all IDE devices in the system. // If the device is ATAPI use the IDE_ATAPI_ID command, // otherwise use the IDE_ID_FUNCTION command. // If ( ( ( lVersionInfo.bIDEDeviceMap Shr i ) And $10 ) <> 0 ) Then bIDCmd := IDE_ATAPI_ID Else bIDCmd := IDE_ID_FUNCTION; FillChar(lInCmd, SizeOf(lInCmd), 0); FillChar(lIdOutCmd^, SizeOf(TSendCmdOutParams) + IDENTIFY_BUFFER_SIZE - 1, 0); If ( DoIDENTIFY(lSmartHandle, @lInCmd, lIdOutCmd, bIDCmd, i, lBytesReturned) ) Then Begin DisplayIdInfo(Memo1.Lines, PIDSector(@(PSendCmdOutParams(lIdOutCmd)^.bBuffer[0]))^, lInCmd, bIDCmd, bDfpDriveMap, i); End Else Begin Memo1.Lines.Add(format('Identify Command Failed on Drive: %d', [i])); Memo1.Lines.Add(format(' DriverStatus: bDriverError=0x%.08X, bIDEStatus=0x%.08X', [ PSendCmdOutParams(lIdOutCmd)^.DriverStatus.bDriverError, PSendCmdOutParams(lIdOutCmd)^.DriverStatus.bIDEStatus])); End; Memo1.Lines.Add(format(' cbBytesReturned: %d', [lBytesReturned])); End; End; // // Loop through all possible IDE drives and send commands to the ones that support SMART. // For i := 0 To MAX_IDE_DRIVES Do Begin If ( ( ( bDfpDriveMap Shr i ) And 1 ) <> 0 ) Then Begin FillChar(lAttrOutCmd^, SizeOf(TSendCmdOutParams) + READ_ATTRIBUTE_BUFFER_SIZE - 1, 0); FillChar(lThreshOutCmd^, SizeOf(TSendCmdOutParams) + READ_THRESHOLD_BUFFER_SIZE - 1, 0); lSuccess := DoReadAttributesCmd( lSmartHandle, @lInCmd, lAttrOutCmd, i); If ( Not lSuccess ) Then Begin Memo1.Lines.Add(format('SMART Read Attr Command Failed on Drive: %d', [i])); Memo1.Lines.Add(format(' DriverStatus: bDriverError=0x%.08X, bIDEStatus=0x%.08X', [ PSendCmdOutParams(lAttrOutCmd)^.DriverStatus.bDriverError, PSendCmdOutParams(lAttrOutCmd)^.DriverStatus.bIDEStatus])); End // ReadAttributes worked. Try ReadThresholds. Else If ( Not DoReadThresholdsCmd( lSmartHandle, @lInCmd, lThreshOutCmd, i) ) Then Begin lSuccess := False; Memo1.Lines.Add(format('SMART Read Thresh Command Failed on Drive: %d', [i])); Memo1.Lines.Add(format(' DriverStatus: bDriverError=0x%.08X, bIDEStatus=0x%.08X', [ PSendCmdOutParams(lAttrOutCmd)^.DriverStatus.bDriverError, PSendCmdOutParams(lAttrOutCmd)^.DriverStatus.bIDEStatus])); End Else lSuccess := True; // // The following report will print if ReadAttributes works. // If ReadThresholds works, the report will also show values for // Threshold values. // If ( lSuccess ) Then Begin DoPrintData( Memo1.Lines, @(PSendCmdOutParams(lAttrOutCmd)^.bBuffer[0]), @(PSendCmdOutParams(lThreshOutCmd)^.bBuffer[0]), i); End; End; End; Finally [color=red]CloseHandle(lSmartHandle);[/color] FreeMem(lIdOutCmd); FreeMem(lAttrOutCmd); FreeMem(lThreshOutCmd); End; [color=red]Memo1.Lines.Add(''); Memo1.Lines.Add(''); Memo1.Lines.Add(''); End;[/color] End; End. [add] und ihr seid euch sicher, daß Zitat:
meine S-ATA is ja an Port 0 und in der Systemsteuerung steht sie als "Primary Master", aber SMARTAppD7 meint "SMART enabled on drive: 2" ... also "Secondary Master" Bei der IDE stimmt die 0.
Code:
SMART interface opened...
DFP_GET_VERSION returned: bVersion = 1 bRevision = 1 fCapabilities = 0x00000007 bReserved = 0x0 bIDEDeviceMap = 0x4 SMART enabled on drive: 2 cbBytesReturned: 16 Drive 2 is an IDE Hard drive that supports SMART #Cylinders: 16383, #Heads: 16, #Sectors per Track: 63 IDE TASK FILE REGISTERS: bFeaturesReg = 0x0 bSectorCountReg = 0x1 bSectorNumberReg = 0x1 bCylLowReg = 0x0 bCylHighReg = 0x0 bDriveHeadReg = 0xA0 Status = 0xEC Model number: Maxtor 6V250F0 Firmware rev: VA11163 Serial number: V594J4NG cbBytesReturned: 528 Data for Drive Number 2 Attribute Structure Revision Threshold Structure Revision 32 32 -Attribute Name- -Attribute Value- -Threshold Value- 03 Spin Up Time 191 63 04 Start/Stop Count 253 0 05 Reallocated Sector Count 253 63 07 Seek Error Rate 253 0 08 Seek Time Performance 249 187 09 Power On Hours Count 253 0 0A Spin Retry Count 253 157 0B Calibration Retry Count 253 223 0C Power Cycle Count 253 0 BD (Unknown attribute) 100 0 BE (Unknown attribute) 50 0 C0 (Unknown attribute) 253 0 C1 (Unknown attribute) 253 0 C2 (Unknown attribute) 48 0 C3 (Unknown attribute) 253 0 C4 (Unknown attribute) 253 0 C5 (Unknown attribute) 253 0 C6 (Unknown attribute) 253 0 C7 (Unknown attribute) 199 0 C8 (Unknown attribute) 253 0 C9 (Unknown attribute) 253 0 CA (Unknown attribute) 253 0 CB (Unknown attribute) 253 180 CC (Unknown attribute) 253 0 CD (Unknown attribute) 253 0 CF (Unknown attribute) 253 0 D0 (Unknown attribute) 253 0 D2 (Unknown attribute) 253 0 D3 (Unknown attribute) 253 0 D4 (Unknown attribute) 253 0 SMART interface opened... DFP_GET_VERSION returned: bVersion = 1 bRevision = 1 fCapabilities = 0x00000007 bReserved = 0x0 bIDEDeviceMap = 0x1 SMART enabled on drive: 0 cbBytesReturned: 16 Drive 0 is an IDE Hard drive that supports SMART #Cylinders: 16383, #Heads: 16, #Sectors per Track: 63 IDE TASK FILE REGISTERS: bFeaturesReg = 0x0 bSectorCountReg = 0x1 bSectorNumberReg = 0x1 bCylLowReg = 0x0 bCylHighReg = 0x0 bDriveHeadReg = 0xA0 Status = 0xEC Model number: MAXTOR 4K040H2 Firmware rev: A08.150B Serial number: 572123615033 cbBytesReturned: 528 Data for Drive Number 0 Attribute Structure Revision Threshold Structure Revision 11 11 -Attribute Name- -Attribute Value- -Threshold Value- 01 Raw Read Error Rate 100 20 03 Spin Up Time 87 20 04 Start/Stop Count 96 8 05 Reallocated Sector Count 98 20 07 Seek Error Rate 100 23 09 Power On Hours Count 72 1 0A Spin Retry Count 100 0 0B Calibration Retry Count 100 20 0C Power Cycle Count 96 8 0D (Unknown attribute) 100 23 C2 (Unknown attribute) 85 42 C3 (Unknown attribute) 100 0 C4 (Unknown attribute) 100 20 C5 (Unknown attribute) 100 20 C6 (Unknown attribute) 100 0 C7 (Unknown attribute) 126 0 Unable to open physical drive, error code: 0x00000002 (Das System kann die angegebene Datei nicht finden) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:40 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz