//
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.