Friday, August 17, 2007

How to monitor a harddrive with S.M.A.R.T.

{ .... }



type

TSmartData = array[0..527] of Byte;




{ .... }



procedure GetSmartData(var Data: TSmartData);

var

hdrive: Cardinal;

dwBytesReturned: DWORD;


ipar: array[0..31] of Byte;

opar: TSmartData;

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;

// Get first harddrive

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: TSmartData;
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;




1 comment:

Anonymous said...

nice one, but it is possible to extract hdd serial also?
Vlad