FAQ » Sprzęt

Jak odczytać temperaturę i inne informacje o dysku

W tym FAQ napiszę jak pobrać temperaturę i inne informacje o dysku twardym :)

Na początek wrzucamy na formę komponent TStringGrid i TTimer.
Komponentowi StringGrid ustalamy 2 kolumny (ColCount) i 17 rzędów (RowCount), a Timerowi właściwość interval 700.

Teraz przejdziemy do kodu. Deklarujemy typ:
smartdata=array[0..527] of byte;

Ok. Teraz napiszemy procedurę, która będzie pobierać informację.
procedure getsmartdata(var data:smartdata);
var
  hdrive:cardinal;
  dwBytesReturned : DWORD;
  ipar:array[0..31] of byte;
  opar:smartdata;
begin
  ipar[0]:=0;
  ipar[1]:=$02;
  ipar[2]:=0;
  ipar[3]:=0;
  ipar[4]:=$d0;
  ipar[5]:=$01;
  ipar[6]:=$01;
  ipar[7]:=$4f;
  ipar[8]:=$c2;
  ipar[9]:=$a0;
  ipar[10]:=$b0;
  ipar[11]:=0;
  ipar[12]:=0;
  ipar[13]:=0;
  ipar[14]:=0;
  ipar[15]:=0;
  ipar[16]:=$8c;
  ipar[17]:=$fd;
  ipar[18]:=$14;
  ipar[19]:=0;
  ipar[20]:=0;
  ipar[21]:=$02;
  ipar[22]:=0;
  ipar[23]:=0;
  ipar[24]:=$03;
  ipar[25]:=0;
  ipar[26]:=0;
  ipar[27]:=0;
  ipar[28]:=$03;
  ipar[29]:=0;
  ipar[30]:=0;
  ipar[31]:=0;
  hdrive:=CreateFile( PChar('\\.\PhysicalDrive0'), 3221225472, 3, nil, 3, 0, 0 ); // \\.\PhysicalDrive0 to twardziel ;]
  DeviceIoControl( hdrive, $0007C088, @ipar, 32, @opar, 528, dwBytesReturned, nil );
  closehandle(hdrive);
  data:=opar;
end;

Teraz procedura wykonywana przy uruchamianiu programu:
procedure TForm1.FormCreate(Sender: TObject);
begin
  stringgrid1.Cells[0,0]:='Description';
  stringgrid1.Cells[1,0]:='Value';
  stringgrid1.Cells[0,1]:='Spin Up Time';
  stringgrid1.Cells[0,2]:='Start/Stop Count';
  stringgrid1.Cells[0,3]:='Reallocated Sectors Count';
  stringgrid1.Cells[0,4]:='Read Channel Margin';
  stringgrid1.Cells[0,5]:='Seek Error Rate';
  stringgrid1.Cells[0,6]:='Seek Time Performance';
  stringgrid1.Cells[0,7]:='Power-On Minutes';
  stringgrid1.Cells[0,8]:='Spin Retry Count';
  stringgrid1.Cells[0,9]:='Recalibration Retries';
  stringgrid1.Cells[0,10]:='Device Power Cycle Count';
  stringgrid1.Cells[0,11]:='Load/Unload Cycle Count';
  stringgrid1.Cells[0,12]:='Temperature';
  stringgrid1.Cells[0,13]:='Reallocation Event Count';
  stringgrid1.Cells[0,14]:= 'Current Pending Sector Count';
  stringgrid1.Cells[0,15]:='Uncorrectable Sector Count';
  stringgrid1.Cells[0,16]:='UDMA CRC Error Count';
  stringgrid1.Cells[0,17]:='Write Error Rate';
end;

Ok. Została nam tylko procedura podpięta pod Timera.
procedure TForm1.Timer1Timer(Sender: TObject);
var
  smartdatavar:smartdata;
begin
  getsmartdata(smartdatavar);
  stringgrid1.Cells[1,1]:=inttostr(smartdatavar[24]*256+smartdatavar[23]);
  stringgrid1.Cells[1,2]:=inttostr(smartdatavar[36]*256+smartdatavar[35]);
  stringgrid1.Cells[1,3]:=inttostr(smartdatavar[48]*256+smartdatavar[47]);
  stringgrid1.Cells[1,4]:=inttostr(smartdatavar[60]*256+smartdatavar[59]);
  stringgrid1.Cells[1,5]:=inttostr(smartdatavar[72]*256+smartdatavar[71]);
  stringgrid1.Cells[1,6]:=inttostr(smartdatavar[84]*256+smartdatavar[83]);
  stringgrid1.Cells[1,7]:=inttostr(smartdatavar[96]*256+smartdatavar[95]);
  stringgrid1.Cells[1,8]:=inttostr(smartdatavar[108]*256+smartdatavar[107]);
  stringgrid1.Cells[1,9]:=inttostr(smartdatavar[120]*256+smartdatavar[119]);
  stringgrid1.Cells[1,10]:=inttostr(smartdatavar[132]*256+smartdatavar[131]);
  stringgrid1.Cells[1,11]:=inttostr(smartdatavar[156]*256+smartdatavar[155]);
  stringgrid1.Cells[1,12]:=inttostr(smartdatavar[168]*256+smartdatavar[167]);
  stringgrid1.Cells[1,13]:=inttostr(smartdatavar[192]*256+smartdatavar[191]);
  stringgrid1.Cells[1,14]:=inttostr(smartdatavar[204]*256+smartdatavar[203]);
  stringgrid1.Cells[1,15]:=inttostr(smartdatavar[216]*256+smartdatavar[215]);
  stringgrid1.Cells[1,16]:=inttostr(smartdatavar[228]*256+smartdatavar[227]);
  stringgrid1.Cells[1,17]:=inttostr(smartdatavar[240]*256+smartdatavar[239]);
end;

A teraz listing:
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, Grids;
 
type
  TForm1 = class(TForm)
    Timer1: TTimer;
    StringGrid1: TStringGrid;
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
  type smartdata=array[0..527] of byte;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
procedure getsmartdata(var data:smartdata);
var
  hdrive:cardinal;
  dwBytesReturned : DWORD;
  ipar:array[0..31] of byte;
  opar:smartdata;
begin
  ipar[0]:=0;
  ipar[1]:=$02;
  ipar[2]:=0;
  ipar[3]:=0;
  ipar[4]:=$d0;
  ipar[5]:=$01;
  ipar[6]:=$01;
  ipar[7]:=$4f;
  ipar[8]:=$c2;
  ipar[9]:=$a0;
  ipar[10]:=$b0;
  ipar[11]:=0;
  ipar[12]:=0;
  ipar[13]:=0;
  ipar[14]:=0;
  ipar[15]:=0;
  ipar[16]:=$8c;
  ipar[17]:=$fd;
  ipar[18]:=$14;
  ipar[19]:=0;
  ipar[20]:=0;
  ipar[21]:=$02;
  ipar[22]:=0;
  ipar[23]:=0;
  ipar[24]:=$03;
  ipar[25]:=0;
  ipar[26]:=0;
  ipar[27]:=0;
  ipar[28]:=$03;
  ipar[29]:=0;
  ipar[30]:=0;
  ipar[31]:=0;
  hdrive:=CreateFile( PChar('\\.\PhysicalDrive0'), 3221225472, 3, nil, 3, 0, 0 );
  DeviceIoControl( hdrive, $0007C088, @ipar, 32, @opar, 528, dwBytesReturned, nil );
  closehandle(hdrive);
  data:=opar;
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
stringgrid1.Cells[0,0]:='Description';
  stringgrid1.Cells[1,0]:='Value';
  stringgrid1.Cells[0,1]:='Spin Up Time';
  stringgrid1.Cells[0,2]:='Start/Stop Count';
  stringgrid1.Cells[0,3]:='Reallocated Sectors Count';
  stringgrid1.Cells[0,4]:='Read Channel Margin';
  stringgrid1.Cells[0,5]:='Seek Error Rate';
  stringgrid1.Cells[0,6]:='Seek Time Performance';
  stringgrid1.Cells[0,7]:='Power-On Minutes';
  stringgrid1.Cells[0,8]:='Spin Retry Count';
  stringgrid1.Cells[0,9]:='Recalibration Retries';
  stringgrid1.Cells[0,10]:='Device Power Cycle Count';
  stringgrid1.Cells[0,11]:='Load/Unload Cycle Count';
  stringgrid1.Cells[0,12]:='Temperature';
  stringgrid1.Cells[0,13]:='Reallocation Event Count';
  stringgrid1.Cells[0,14]:= 'Current Pending Sector Count';
  stringgrid1.Cells[0,15]:='Uncorrectable Sector Count';
  stringgrid1.Cells[0,16]:='UDMA CRC Error Count';
  stringgrid1.Cells[0,17]:='Write Error Rate';
  timer1.Interval:=700;
  timer1.Enabled:=true;
end;
 
procedure TForm1.Timer1Timer(Sender: TObject);
var
  smartdatavar:smartdata;
begin
  getsmartdata(smartdatavar);
  stringgrid1.Cells[1,1]:=inttostr(smartdatavar[24]*256+smartdatavar[23]);
  stringgrid1.Cells[1,2]:=inttostr(smartdatavar[36]*256+smartdatavar[35]);
  stringgrid1.Cells[1,3]:=inttostr(smartdatavar[48]*256+smartdatavar[47]);
  stringgrid1.Cells[1,4]:=inttostr(smartdatavar[60]*256+smartdatavar[59]);
  stringgrid1.Cells[1,5]:=inttostr(smartdatavar[72]*256+smartdatavar[71]);
  stringgrid1.Cells[1,6]:=inttostr(smartdatavar[84]*256+smartdatavar[83]);
  stringgrid1.Cells[1,7]:=inttostr(smartdatavar[96]*256+smartdatavar[95]);
  stringgrid1.Cells[1,8]:=inttostr(smartdatavar[108]*256+smartdatavar[107]);
  stringgrid1.Cells[1,9]:=inttostr(smartdatavar[120]*256+smartdatavar[119]);
  stringgrid1.Cells[1,10]:=inttostr(smartdatavar[132]*256+smartdatavar[131]);
  stringgrid1.Cells[1,11]:=inttostr(smartdatavar[156]*256+smartdatavar[155]);
  stringgrid1.Cells[1,12]:=inttostr(smartdatavar[168]*256+smartdatavar[167]);
  stringgrid1.Cells[1,13]:=inttostr(smartdatavar[192]*256+smartdatavar[191]);
  stringgrid1.Cells[1,14]:=inttostr(smartdatavar[204]*256+smartdatavar[203]);
  stringgrid1.Cells[1,15]:=inttostr(smartdatavar[216]*256+smartdatavar[215]);
  stringgrid1.Cells[1,16]:=inttostr(smartdatavar[228]*256+smartdatavar[227]);
  stringgrid1.Cells[1,17]:=inttostr(smartdatavar[240]*256+smartdatavar[239]);
end;
 
end.



Kod zaczerpnięty z Torry.net (dokładniej: s.m.a.r.t monitor v.1)