0

我正在编写一个 SMART 监控工具,我设法使用 SMART_REA_DATA 命令获取 SMART 属性 [当前、最差、原始数据],但我也需要阈值,我搜索了ATA 文档,但我没有找到任何关于如何阅读阈值。有谁知道我可以从哪里得到这些值?

4

1 回答 1

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;
于 2017-06-20T19:57:23.237 回答