Delphi → S.M.A.R.T. + Delphi
Большинство современных жестких дисков поддерживают технологию S.M.A.R.T. – Self-Monitoring, Analysis and Reporting Technology (Технология самодиагностики, анализа и отчёта), благодаря которой возможно предсказать появление сбоев в работе жесткого диска, и позволить пользователю своевременно сделать резервную копию диска или же полностью его заменить.
Существует множество программ, дающих возможность следить за состоянием винчестера посредством технологии S.M.A.R.T., однако большинство из них – платные. Например, Hard Drive Inspector 1.6 стоит $29,95; Active SMART 2.4 – $24,95; SiGuardian 1.6 – $14.
В своей статье я постараюсь рассказать о том, как встроенными средствами операционной системы Windows и с помощью языка Object Pascal вы сможете написать программу подобного рода и потом использовать её абсолютно бесплатно.
Я в основном буду опираться на документ «Small Form Factor Committee. Specification for Self-Monitoring, Analysis and Reporting Technology», изданный в апреле 1996 года и утверждённый такими компаниями, как Compaq Computer Corporation, Hitachi Ltd., IBM Storage Products Company, Maxtor Corporation, Quantum Corporation, Seagate Technology, Toshiba Corporation и Western Digital Corporation. Большинство положений этого документа актуально и по сей день.
Следует также отметить, что на сегодняшний день стандарт на технологию S.M.A.R.T. не утверждён. Однако в стандарте ATA, начиная с версии 3, описан обязательный минимум для технологии S.M.A.R.T., и если ваш жёсткий диск соответствует ATA (3-8), то он будет поддерживать данную технологию в соответствии с этим стандартом.
Анализ состояния диска мы будем проводить посредством изучения атрибутов S.M.A.R.T. Максимальное количество атрибутов на одном диске зависит от производителя и не превышает 30. Атрибуты могут принимать значения в диапазоне от 1 до 253. Для каждого атрибута существует пороговое значение, основываясь на котором можно судить о близости момента выхода привода из строя.
Перейдём непосредственно к коду.
Для начала необходимо создать дескриптор для работы с функциями S.M.A.R.T. посредством DeviceIoControl.
В качестве передаваемого параметра данной функции выступает номер физического диска. Максимальное количество IDE-дисков – 4. Этот параметр игнорируется, если программа запущена в операционной системе Win9х.
Немного поясню. В операционных системах Windows 95 OSR, 98, 98SE, Me за работу со S.M.A.R.T. отвечает драйвер виртуального устройства SMARTVSD.VXD, который находится в папке …WINDOWSSYSTEMIOSUBSYS. В операционных системах линейки NT работа с устройствами (как физическими, так и виртуальными) построена иным образом, поэтому при работе с S.M.A.R.T. в этих операционных системах необходимо открывать дескриптор доступа к физическому диску.
Переменная OSVersionInfo является глобальной, и ее тип определен как TOSVersionInfo. Она заполняется до вызова функции OpenSMART.
Получив дескриптор S.M.A.R.T., мы должны определить версию S.M.A.R.T. IOCTL. За это отвечает следующая функция:
В качестве параметра передаётся дескриптор S.M.A.R.T. Функция возвращает структуру типа TGetVersionOutParams.
Константа DFP_GET_VERSION = $00074080 является командой получения версии S.M.A.R.T. IOCTL.
Следующий шаг – найти IDE-диски и попытаться активировать на них S.M.A.R.T.
Перед тем как рассказать о функции, отвечающей за активацию S.M.A.R.T., необходимо описать структуры, которые нам понадобятся для её реализации.
Тип TIDERegs описывает регистры IDE-диска. Допустимые значения параметра bCommandReg:
Параметры bCylLowReg и bCylHighReg должны быть обязательно равны $4F (SMART_CYL_LOW) и $C2 (SMART_CYL_HI) соответственно.
Тип TSendCmdInParams содержит входные параметры для функции, которая посылает команды диску.
Тип TDriverStatus предназначен для отслеживания ошибок драйвера. Если параметр bDriverError содержит значение, отличное от нуля, значит, произошла ошибка.
Тип TSendCmdOutParams предназначен для некоторых команд, которые возвращают через него данные.
Теперь собственно функция активации S.M.A.R.T.:
Следует сказать пару слов о передаваемых параметрах. В качестве параметров pSCIP и pSCOP передаются обнулённые структуры TSendCmdInParams и TSendCmdOutParams, соответственно. Параметр bDriveNum – это номер диска в пределах от 0 до 3. После заполнения необходимых параметров структуры PSENDCMDOUTPARAMS выполняем функцию DeviceIoControl с управляющим кодом DFP_SEND_DRIVE_COMMAND ($0007C084). Если функция выполнена успешно, возвращаемый результат – TRUE.
Приведу код, который определяет тип диска и пытается активировать S.M.A.R.T.:
Поговорим непосредственно о чтении атрибутов S.M.A.R.T. Как уже упоминалось в начале статьи, чтобы провести анализ состояния привода, необходимо знать текущие и пороговые значения атрибутов. Создадим два типа для чтения этих значений. Первый – для чтения значений атрибутов:
Параметр wStatusFlags может принимать следующие значения либо их комбинации:
Второй тип предназначен для чтения пороговых значений:
Функция чтения значений атрибутов выглядит следующим образом:
Думаю, смысл передаваемых в функцию параметров объяснять не надо. Они аналогичны параметрам функции DoEnableSMART, как и большинство параметров структуры PSENDCMDINPARAMS. Различия лишь в размере буфера и в подкоманде S.M.A.R.T. В качестве управляющего кода функции DeviceIoControl передаётся константа DFP_RECEIVE_DRIVE_DATA ($0007C088).
Функция для чтения пороговых значений (назовём её DoReadThresholdsCmd) будет выглядеть аналогично, за тем лишь исключением, что параметр bFeaturesReg будет иметь значение $D1.
Пример чтения текущих и пороговых значений атрибутов диска «i» приведён ниже:
Неизвестной для нас здесь является процедура DoPrintData.
В данной процедуре переменная pAttrNames – это массив строковых значений, содержащих название атрибута в соответствии со своим порядковым номером в массиве.
Вот, собственно говоря, и всё. Описание атрибутов можно найти в Интернете или послав запрос производителю вашего привода. Пару слов скажу лишь об атрибуте под названием Temperature (Температура). Его идентификатор – 194 или 231. Как ясно следует из его названия, он показывает температуру винчестера, которая измеряется в градусах Цельсия. Чтобы её вычислить, воспользуйтесь нижеприведённым кодом:
Исходный код программы, демонстрирующей основные принципы работы с S.M.A.R.T., вы также можете скачать по адресу: http://fominov.boom.ru/
Эта программа тестировалась в операционных системах Windows 98 и Windows XP. Программа не работает со SCSI-приводами и RAID-массивами.
Существует множество программ, дающих возможность следить за состоянием винчестера посредством технологии S.M.A.R.T., однако большинство из них – платные. Например, Hard Drive Inspector 1.6 стоит $29,95; Active SMART 2.4 – $24,95; SiGuardian 1.6 – $14.
В своей статье я постараюсь рассказать о том, как встроенными средствами операционной системы Windows и с помощью языка Object Pascal вы сможете написать программу подобного рода и потом использовать её абсолютно бесплатно.
Я в основном буду опираться на документ «Small Form Factor Committee. Specification for Self-Monitoring, Analysis and Reporting Technology», изданный в апреле 1996 года и утверждённый такими компаниями, как Compaq Computer Corporation, Hitachi Ltd., IBM Storage Products Company, Maxtor Corporation, Quantum Corporation, Seagate Technology, Toshiba Corporation и Western Digital Corporation. Большинство положений этого документа актуально и по сей день.
Следует также отметить, что на сегодняшний день стандарт на технологию S.M.A.R.T. не утверждён. Однако в стандарте ATA, начиная с версии 3, описан обязательный минимум для технологии S.M.A.R.T., и если ваш жёсткий диск соответствует ATA (3-8), то он будет поддерживать данную технологию в соответствии с этим стандартом.
Анализ состояния диска мы будем проводить посредством изучения атрибутов S.M.A.R.T. Максимальное количество атрибутов на одном диске зависит от производителя и не превышает 30. Атрибуты могут принимать значения в диапазоне от 1 до 253. Для каждого атрибута существует пороговое значение, основываясь на котором можно судить о близости момента выхода привода из строя.
Перейдём непосредственно к коду.
Для начала необходимо создать дескриптор для работы с функциями S.M.A.R.T. посредством DeviceIoControl.
function OpenSMART(DrvNum:Byte): THandle;
var
hSMARTIOCTL: THandle;
begin
// Если у нас Windows семейства NT
if OSVersionInfo.dwPlatformId = VER_PLATFORM_WIN32_NT then
hSMARTIOCTL := CreateFile(PChar('\.PhysicalDrive' + inttostr(DrvNum)),
GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE,
nil, OPEN_EXISTING, 0, 0);
else // Если у нас Windows семейства 9х
begin
hSMARTIOCTL := CreateFile('\.SMARTVSD', 0, 0, nil, CREATE_NEW, 0, 0);
if hSMARTIOCTL = INVALID_HANDLE_VALUE then
ShowMessage('Невозможно открыть SMARTVSD, код ошибки: '
+ inttostr(GetLastError) + ' - ' + SysErrorMessage(GetLastError))
end;
result := hSMARTIOCTL;
end;
В качестве передаваемого параметра данной функции выступает номер физического диска. Максимальное количество IDE-дисков – 4. Этот параметр игнорируется, если программа запущена в операционной системе Win9х.
Немного поясню. В операционных системах Windows 95 OSR, 98, 98SE, Me за работу со S.M.A.R.T. отвечает драйвер виртуального устройства SMARTVSD.VXD, который находится в папке …WINDOWSSYSTEMIOSUBSYS. В операционных системах линейки NT работа с устройствами (как физическими, так и виртуальными) построена иным образом, поэтому при работе с S.M.A.R.T. в этих операционных системах необходимо открывать дескриптор доступа к физическому диску.
Переменная OSVersionInfo является глобальной, и ее тип определен как TOSVersionInfo. Она заполняется до вызова функции OpenSMART.
Получив дескриптор S.M.A.R.T., мы должны определить версию S.M.A.R.T. IOCTL. За это отвечает следующая функция:
function GetVersionSMART(hSMARTIOCTL: THandle):TGetVersionOutParams;
var
VersionParams: TGetVersionOutParams;
cbBytesReturned: DWORD;
begin
ZeroMemory(@VersionParams, sizeof(TGetVersionOutParams));
if not DeviceIoControl (hSMARTIOCTL, DFP_GET_VERSION, nil, 0,
@VersionParams, sizeof(VersionParams), cbBytesReturned, nil)
then
ShowMessage(SysErrorMessage(GetLastError));
Result := VersionParams;
end;
В качестве параметра передаётся дескриптор S.M.A.R.T. Функция возвращает структуру типа TGetVersionOutParams.
type
TGetVersionOutParams = packed record
bVersion: BYTE; // Бинарная версия драйвера.
bRevision: BYTE; // Бинарная подверсия драйвера.
bReserved: BYTE; // Не используется.
bIDEDeviceMap: BYTE; // Битовый массив IDE - устройств.
fCapabilities: DWORD; // Битовая маска возможностей драйвера.
// Зарезервировано для будущего использования.
dwReserved: array [0..3] of DWORD;
end;
GETVERSIONOUTPARAMS = TGetVersionOutParams;
PGetVersionOutParams = ^TGetVersionOutParams;
Константа DFP_GET_VERSION = $00074080 является командой получения версии S.M.A.R.T. IOCTL.
Следующий шаг – найти IDE-диски и попытаться активировать на них S.M.A.R.T.
Перед тем как рассказать о функции, отвечающей за активацию S.M.A.R.T., необходимо описать структуры, которые нам понадобятся для её реализации.
type
TIDERegs = packed record
// Используется для определения "подкоманды" S.M.A.R.T.
bFeaturesReg: BYTE;
// Регистр количества секторов IDE
bSectorCountReg: BYTE;
// Регистр номера сектора IDE
bSectorNumberReg: BYTE;
// Младший разряд номера цилиндра IDE
bCylLowReg: BYTE;
// Старший разряд номера цилиндра IDE
bCylHighReg: BYTE;
// Регистр диска/головки IDE
bDriveHeadReg: BYTE;
// Фактическая команда IDE
bCommandReg: BYTE;
// Зарезервировано для будущего использования. Должно быть 0.
bReserved: BYTE;
end;
IDEREGS = TIDERegs;
PIDERegs = ^TIDERegs;
Тип TIDERegs описывает регистры IDE-диска. Допустимые значения параметра bCommandReg:
const
// Возвращает ID сектора для ATAPI.
IDE_ATAPI_ID = $A1;
// Возвращает ID сектора для ATA.
IDE_ID_FUNCTION = $EC;
// Выполняет команду SMART. Требует правильных значений для параметров
// bFeaturesReg, bCylLowReg, bCylHighReg.
IDE_EXECUTE_SMART_FUNCTION = $B0;
Параметры bCylLowReg и bCylHighReg должны быть обязательно равны $4F (SMART_CYL_LOW) и $C2 (SMART_CYL_HI) соответственно.
type
TSendCmdInParams = packed record
// Размер буфера в байтах.
cBufferSize: DWORD;
// Структура со значениями регистров диска.
irDriveRegs: TIDERegs;
// Физический номер диска для выполнения команд.
bDriveNumber: BYTE;
// Зарезервировано для будущего расширения.
bReserved: array [0..2] of Byte;
// Зарезервировано для будущего использования.
dwReserved: array [0..3] of DWORD;
// Входной буфер.
bBuffer: array [0..0] of Byte;
end;
SENDCMDINPARAMS = TSendCmdInParams;
PSendCmdInParams = ^TSendCmdInParams;
Тип TSendCmdInParams содержит входные параметры для функции, которая посылает команды диску.
type
TDriverStatus = packed record
// Код ошибки драйвера.
bDriverError: Byte;
// Содержание регистра ошибки. Правильно, только когда
// bDriverError = SMART_IDE_ERROR (1).
bIDEStatus: Byte;
// Зарезервировано для будущего расширения.
bReserved: array [0..1] of Byte;
// Зарезервировано для будущего расширения.
dwReserved: array [0..1] of DWORD;
end;
DRIVERSTATUS = TDriverStatus;
PDriverStatus = ^TDriverStatus;
Тип TDriverStatus предназначен для отслеживания ошибок драйвера. Если параметр bDriverError содержит значение, отличное от нуля, значит, произошла ошибка.
type
TSendCmdOutParams = packed record
// Размер bBuffer в байтах
cBufferSize: DWORD;
// Структура состояния драйвера.
DriverStatus: TDriverStatus;
// Буфер произвольной длины для сохранения данных, прочитанных с диска.
bBuffer: array [0..0] of BYTE;
end;
SENDCMDOUTPARAMS = TSendCmdOutParams;
PSendCmdOutParams = ^TSendCmdOutParams;
Тип TSendCmdOutParams предназначен для некоторых команд, которые возвращают через него данные.
Теперь собственно функция активации S.M.A.R.T.:
function DoEnableSMART (hSMARTIOCTL: THandle; pSCIP: PSENDCMDINPARAMS;
pSCOP: PSENDCMDOUTPARAMS; bDriveNum: BYTE): BOOL;
var
lpcbBytesReturned: DWORD;
begin
pSCIP.cBufferSize:= 0;
// Активировать S.M.A.R.T.
pSCIP.irDriveRegs.bFeaturesReg := SMART_ENABLE_SMART_OPERATIONS ($D8);
pSCIP.irDriveRegs.bSectorCountReg := 1;
pSCIP.irDriveRegs.bSectorNumberReg := 1;
pSCIP.irDriveRegs.bCylLowReg := SMART_CYL_LOW;
pSCIP.irDriveRegs.bCylHighReg := SMART_CYL_HI;
// Вычисляем номер накопителя.
pSCIP.irDriveRegs.bDriveHeadReg := $A0 or ((bDriveNum and 1) shl 4);
// Выполнить функцию S.M.A.R.T.
pSCIP.irDriveRegs.bCommandReg := IDE_EXECUTE_SMART_FUNCTION;
pSCIP.bDriveNumber := bDriveNum;
result := DeviceIoControl (hSMARTIOCTL, DFP_SEND_DRIVE_COMMAND, pSCIP,
sizeof(SENDCMDINPARAMS) - 1, pSCOP, sizeof(SENDCMDOUTPARAMS) - 1,
lpcbBytesReturned, nil);
end;
Следует сказать пару слов о передаваемых параметрах. В качестве параметров pSCIP и pSCOP передаются обнулённые структуры TSendCmdInParams и TSendCmdOutParams, соответственно. Параметр bDriveNum – это номер диска в пределах от 0 до 3. После заполнения необходимых параметров структуры PSENDCMDOUTPARAMS выполняем функцию DeviceIoControl с управляющим кодом DFP_SEND_DRIVE_COMMAND ($0007C084). Если функция выполнена успешно, возвращаемый результат – TRUE.
Приведу код, который определяет тип диска и пытается активировать S.M.A.R.T.:
for i := 0 to 3 do
// Количество и тип устройств определяется параметром bIDEDeviceMap
// структуры TGetVersionOutParams
begin
// Если устройство с номером "i" - IDE, передаём ему команды.
if VersionParams.bIDEDeviceMap shr i and 1 = 1 then
begin
// Игнорируем ATAPI - устройства.
if VersionParams.bIDEDeviceMap shr i and $10 = 0 then
begin
ZeroMemory(@scip, sizeof(scip)); // Обнуляем TSendCmdInParams
ZeroMemory(@OutCmd, sizeof(OutCmd)); // Обнуляем TSendCmdOutParams
// Пытаемся активировать SMART.
if DoEnableSMART(hSMARTIOCTL, @scip, @OutCmd, i) then
ShowMessage ('Команда запуска S.M.A.R.T. выполнена, диск: '
+ inttostr(i))
else ShowMessage ('Команда запуска S.M.A.R.T. не выполнена, диск: '
+ inttostr(i));
end;
end;
end;
Поговорим непосредственно о чтении атрибутов S.M.A.R.T. Как уже упоминалось в начале статьи, чтобы провести анализ состояния привода, необходимо знать текущие и пороговые значения атрибутов. Создадим два типа для чтения этих значений. Первый – для чтения значений атрибутов:
type
TDriveAttribute = packed record
bAttrID: BYTE; // Идентификатор атрибута
wStatusFlags: WORD; // Флаги состояния
bAttrValue: BYTE; // Текущее нормализованное значение
bWorstValue: BYTE; // Худшее значение
bRawValue: array [0..5] of BYTE; // Текущее ненормализованное значение
bReserved: BYTE; // Зарезервировано
end;
DRIVEATTRIBUTE = TDriveAttribute;
PDriveAttribute = ^TDriveAttribute;
Параметр wStatusFlags может принимать следующие значения либо их комбинации:
const
// Жизненно важный
PRE_FAILURE_WARRANTY = $01;
// Коллекция реального времени
ON_LINE_COLLECTION = $02;
// Атрибут, отражающий производительность диска
PERFORMANCE_ATTRIBUTE = $04;
// Атрибут, отражающий частоту появления ошибок
ERROR_RATE_ATTRIBUTE = $08;
// Счётчик событий
EVENT_COUNT_ATTRIBUTE = $10;
// Самосохраняющийся атрибут
SELF_PRESERVING_ATTRIBUTE = $20;
Второй тип предназначен для чтения пороговых значений:
type
TAttrThreshold = packed record
bAttrID: BYTE; // Идентификатор атрибута
bWarrantyThreshold: BYTE; // Пороговое значение
bReserved: array [0..9] of BYTE; // Зарезервировано
end;
ATTRTHRESHOLD = TAttrThreshold;
PAttrThreshold = ^TAttrThreshold;
Функция чтения значений атрибутов выглядит следующим образом:
function DoReadAttributesCmd (hSMARTIOCTL: THandle; pSCIP: PSENDCMDINPARAMS;
pSCOP: PSENDCMDOUTPARAMS; bDriveNum: BYTE): BOOL;
var
cbBytesReturned: DWORD;
begin
// Константа = 512
pSCIP.cBufferSize := READ_ATTRIBUTE_BUFFER_SIZE;
// Константа = $D0
pSCIP.irDriveRegs.bFeaturesReg := SMART_READ_ATTRIBUTE_VALUES;
pSCIP.irDriveRegs.bSectorCountReg := 1;
pSCIP.irDriveRegs.bSectorNumberReg := 1;
pSCIP.irDriveRegs.bCylLowReg := SMART_CYL_LOW;
pSCIP.irDriveRegs.bCylHighReg := SMART_CYL_HI;
// Вычисляем номер накопителя.
pSCIP.irDriveRegs.bDriveHeadReg := $A0 or ((bDriveNum and 1) shl 4);
pSCIP.irDriveRegs.bCommandReg := IDE_EXECUTE_SMART_FUNCTION;
pSCIP.bDriveNumber := bDriveNum;
result := DeviceIoControl (hSMARTIOCTL, DFP_RECEIVE_DRIVE_DATA,
pSCIP, sizeof(SENDCMDINPARAMS) - 1, pSCOP, sizeof(SENDCMDOUTPARAMS)
+ READ_ATTRIBUTE_BUFFER_SIZE - 1, cbBytesReturned, nil);
end;
Думаю, смысл передаваемых в функцию параметров объяснять не надо. Они аналогичны параметрам функции DoEnableSMART, как и большинство параметров структуры PSENDCMDINPARAMS. Различия лишь в размере буфера и в подкоманде S.M.A.R.T. В качестве управляющего кода функции DeviceIoControl передаётся константа DFP_RECEIVE_DRIVE_DATA ($0007C088).
Функция для чтения пороговых значений (назовём её DoReadThresholdsCmd) будет выглядеть аналогично, за тем лишь исключением, что параметр bFeaturesReg будет иметь значение $D1.
Пример чтения текущих и пороговых значений атрибутов диска «i» приведён ниже:
var
// Два буфера для получения данных
AttrOutCmd, ThreshOutCmd: array [0..(sizeof(SENDCMDOUTPARAMS) - 1)
+ (READ_ATTRIBUTE_BUFFER_SIZE - 1) ] of BYTE;
bSuccess: bool;
begin
ZeroMemory(@AttrOutCmd, sizeof(AttrOutCmd));
ZeroMemory(@ThreshOutCmd, sizeof(ThreshOutCmd));
bSuccess := DoReadAttributesCmd (hSMARTIOCTL, @scip,
PSENDCMDOUTPARAMS(@AttrOutCmd), i);
if bSuccess = false then ShowMessage(
'Ошибка при выполнении команды чтения атрибутов S.M.A.R.T. на диске: '
+ inttostr(i))
// Команда чтения атрибутов выполнена успешно.
// Пытаемся прочитать пороговые значения атрибутов.
else if not DoReadThresholdsCmd (hSMARTIOCTL, @scip,
PSENDCMDOUTPARAMS(@ThreshOutCmd), i)
then
ShowMessage(
'Ошибка при выполнении команды чтения пороговых значений '
+ 'атрибутов S.M.A.R.T. на диске: ' + inttostr(i));
if bSuccess <> false then
// Выводим информацию об атрибутах и их пороговых значениях
DoPrintData(@PSENDCMDOUTPARAMS(@AttrOutCmd).bBuffer,
@PSENDCMDOUTPARAMS(@ThreshOutCmd).bBuffer);
end;
Неизвестной для нас здесь является процедура DoPrintData.
procedure TForm1.DoPrintData(pAttrBuffer: PCHAR; pThrsBuffer: PCHAR);
var
i: integer;
pDA: PDRIVEATTRIBUTE;
pAT: PATTRTHRESHOLD;
begin
Label8.Caption := 'Версия структуры атрибутов: '
+ inttostr(WORD(pAttrBuffer[0]));
Label9.Caption := 'Версия структуры пороговых значений атрибутов: '
+ inttostr(WORD(pThrsBuffer[0]));
pDA := PDRIVEATTRIBUTE(@pAttrBuffer[2]);
pAT := PATTRTHRESHOLD(@pThrsBuffer[2]);
for I := 0 to 29 do
begin
// Выводим информацию:
// Идентификатор атрибута
StringGrid1.Rows[i + 1].Strings[0] := inttostr(pDA.bAttrID);
// Его название
StringGrid1.Rows[i + 1].Strings[1] := pAttrNames[pDA.bAttrID];
// Текущее значение
StringGrid1.Rows[i + 1].Strings[2] := inttostr(pDA.bAttrValue);
// Пороговое значение
StringGrid1.Rows[i + 1].Strings[3] := inttostr(pAT.bWarrantyThreshold);
// Худшее значение
StringGrid1.Rows[i + 1].Strings[4] := inttostr(pDA.bWorstValue);
inc(pDA);
inc(pAT);
end;
end;
В данной процедуре переменная pAttrNames – это массив строковых значений, содержащих название атрибута в соответствии со своим порядковым номером в массиве.
Вот, собственно говоря, и всё. Описание атрибутов можно найти в Интернете или послав запрос производителю вашего привода. Пару слов скажу лишь об атрибуте под названием Temperature (Температура). Его идентификатор – 194 или 231. Как ясно следует из его названия, он показывает температуру винчестера, которая измеряется в градусах Цельсия. Чтобы её вычислить, воспользуйтесь нижеприведённым кодом:
if (pDA.bAttrID = 194) or (pDA.bAttrID = 231) then
Label7.Caption := 'Температура: '
+ inttostr((84 - (pDA.bAttrValue - 1) div 3)) + #176 + 'C'
Исходный код программы, демонстрирующей основные принципы работы с S.M.A.R.T., вы также можете скачать по адресу: http://fominov.boom.ru/
Эта программа тестировалась в операционных системах Windows 98 и Windows XP. Программа не работает со SCSI-приводами и RAID-массивами.
Добавил: javavirys ( 2017-04-19 21:33:34 )
Теги:
Просмотров: 2686