Delphi-PRAXiS
Seite 5 von 6   « Erste     345 6      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi SMART-Werte lesen (https://www.delphipraxis.net/72013-smart-werte-lesen.html)

ManuMF 14. Jul 2006 11:45

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

Muetze1 14. Jul 2006 11:57

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.

ManuMF 14. Jul 2006 14:11

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:
AOut.Add(Format('%.2X %-29s%d%20s%d%20s%d', [lDA^.bAttrID,
                                             coAttrNames[lAttr],
                                             lDA^.bAttrValue,
                                             ' ',
                                             lAT^.bWarrantyThreshold,
                                             ' ',
                                             lDA^.bRAWValue[0]]));
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.

Gruß,
ManuMF

Muetze1 14. Jul 2006 14:18

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.

ManuMF 14. Jul 2006 14:27

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

Muetze1 14. Jul 2006 14:39

Re: SMART-Werte lesen
 
Zitat:

Zitat von ManuMF
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 ;-)

Gerade wenn es ein privates Projekt ist: Lern zu programmieren und das in einer effektiven, ordentlichen Weise. Wenn du dir das jetzt so angewöhnst, dann wirste nachher im Beruf lange brauchen um dir diese schlechten Angewohnheit wieder abzugewöhnen. Vor allem wirst du feststellen, dass es leichter ist mit Erweiterungen, etc.

Und warum nicht meinen Code umstellen? Irgendein plausibler Grund, warum man das nicht umschreiben sollte?

Delphi-Quellcode:
Format('%d;%s;%d;%d;%d', [lDA^.bAttrID,
                          coAttrNames[lAttr],
                          lDA^.bAttrValue,
                          lAT^.bWarrantyThreshold,
                          lDA^.bRAWValue[0]]);
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.

ManuMF 14. Jul 2006 14:50

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:
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]]));
Gruß,
ManuMF

Muetze1 14. Jul 2006 15:02

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.

ManuMF 14. Jul 2006 15:09

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:

himitsu 14. Jul 2006 20:21

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 Beitrag #4 fand ja auch nur die S-ATA-Platte, aber jetzt werden alle Plättchen entdeckt :)

Ist also (wie ich grad bemerkte) das selbe "Problem" wie in Beitrag #20 (denk ich mal).

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:

Bit 0 = Primary Master
Bit 1 = Primary Slave
Bit 2 = Secondary Master
Bit 3 = Secondary Slave
stimmt?

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.
Seite 5 von 6   « Erste     345 6      

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