2017-06-20 47 views

回答

0

我找到了答案:)這很簡單。要獲得閾值,必須在特徵寄存器中使用0xD1,並將其餘配置爲0xD0(SMART_READ_DATA)命令。我沒有找到它,因爲0xD1它是一個過時的功能......但它似乎仍然使用,即使在新的硬盤驅動器。

爲結果的結構可以是這樣的:

SMART_ATTRIBUTE = packed record 
    ID: Byte; 
    case byte of 
    0: (Flags: Word; 
     CurrValue: Byte; 
     WorstValue: Byte; 
     RawData: array [0..5] of Byte; 
     Reserved0: Byte;); 
    1: (Threshold: Byte; 
     Reserved1: array [0..9] of Byte;); 
    end; 

    SMART_DATA = packed record 
    Version: Word; 
    Attribute: array [0..29] of SMART_ATTRIBUTE; 
    end; 

以及用於獲取功能屬性的閾值:

function GetSMARTData(Drive:Byte; Feature:Byte; var SMARTData:SMART_DATA):Boolean; 
var hDrive: THandle; 
    atpexb: ATA_PASS_THROUGH_EX_WITH_BUFFERS; 
    bytesRet: DWord; 
begin 
//Result:=false; 
hDrive:=CreateFile(PWideChar('\\.\PhysicalDrive'+IntToStr(Drive)), GENERIC_READ or GENERIC_WRITE, 
    FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0); 
if hDrive = INVALID_HANDLE_VALUE then RaiseLastOSError; 
try 
    bytesRet:=0; 
    FillChar(atpexb,SizeOf(atpexb),0); 
    atpexb.Length:=SizeOf(ATA_PASS_THROUGH_EX); 
    atpexb.AtaFlags:=ATA_FLAGS_DATA_IN; 
    atpexb.DataTransferLength:=512; 
    atpexb.TimeOutValue:=1; 
    atpexb.DataBufferOffset:=SizeOf(ATA_PASS_THROUGH_EX); 
    atpexb.CurrentTaskFile.Command:=WIN_SMART; 
    atpexb.CurrentTaskFile.Features:=Feature; 
    atpexb.CurrentTaskFile.LBA_Mid:=$4F; 
    atpexb.CurrentTaskFile.LBA_High:=$C2; 

    if not DeviceIoControl(hDrive, IOCTL_ATA_PASS_THROUGH, @atpexb, SizeOf(ATA_PASS_THROUGH_EX), 
    @atpexb, SizeOf(atpexb), bytesRet, nil) then RaiseLastOSError; 

    Result:=(atpexb.CurrentTaskFile.Command and 1)=0; 
    if Result then Move(atpexb.DataBuff, SMARTData, SizeOf(SMART_DATA)); 

finally 
    CloseHandle(hDrive); 
end; 
end; 
相關問題