Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> SMART API 
:(
    Опции темы
Dark Wanderer
Дата 28.2.2005, 23:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 119
Регистрация: 25.10.2004
Где: Кишинёв

Репутация: нет
Всего: нет



Снова...Не могу найти. smile Хотелось бы поподробней узнать как работать со smartvsd.vxd на Дельфи. Половина нета обрыл, но ничего стоящего не нашёл кроме уже известного мне модуля Alex'a Konshina'a для работы с диском. Неужели никто не занимался этим
smile

--------------------
  
PM MAIL   Вверх
p0s0l
Дата 1.3.2005, 15:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 14
Всего: 112



Читать SMART-атрибуты ты уже умеешь... Могу дать линк на список возможных атрибутов и их описание на русском: http://pcjs.chat.ru/smartdoc.html

Есть еще журналы и функции самоконтроля... Я этим не особо занимался...
Но немного порывшись, выяснил, что:

1. Самоконтроль делается через SMART_EXECUTE_OFFLINE_IMMEDIATE ($D4). Посмотри как делается DoReadAttributesCmd, только вместо SMART_READ_ATTRIBUTE_VALUES ставить надо SMART_EXECUTE_OFFLINE_IMMEDIATE. В № сектора указывается № подфункции (тип теста)... Результаты сохранятся либо в каких-то атрибутах, либо в журнале...

2. Читать журналы нужно через READ LOG SECTOR ($D5):
bSectorCountReg = 02 - первый сектор журнала, 03 - следующий сектор
bSectorNumberReg = № журнала

Описание журналов, форматов команд и регистров, атрибутов и др. можно найти на www.t13.org - поиском ищи, типа:
http://www.google.com/search?hl=en&lr=&q=+...LOG&btnG=Search

Это сообщение отредактировал(а) p0s0l - 1.3.2005, 15:56


--------------------
С уважением, г-н Посол.
PM   Вверх
Dark Wanderer
Дата 1.3.2005, 16:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 119
Регистрация: 25.10.2004
Где: Кишинёв

Репутация: нет
Всего: нет



Спасибо p0s0l. Опять выручаешь! Сейчас буду пробовать.
--------------------
  
PM MAIL   Вверх
Dark Wanderer
Дата 2.3.2005, 17:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 119
Регистрация: 25.10.2004
Где: Кишинёв

Репутация: нет
Всего: нет



p0s0l очень прошу покажи пару примеров по запуска одного (любого)теста и чтения текущего состояния регистров винта ERR,BSY, ...
Я всю ночь убил читая всю документацию. Так и не дошло до меня как это делается. smile
--------------------
  
PM MAIL   Вверх
p0s0l
Дата 3.3.2005, 00:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 14
Всего: 112



Цитата
чтения текущего состояния регистров винта ERR,BSY, ...

Интересно, что для посылки SMART-команды через DeviceIoControl, нужно заполнять структуру, содержащую IDE-регистры...
На выходе же имеет некую структуру SENDCMDOUTPARAMS, в ней содержится структура DriverStatus... Вот как описывается она в MSDN:
Код
DRIVERSTATUS = packed record
 bDriverError : BYTE;                 // Error code from driver, or 0 if no error.
 bIDEStatus   : BYTE;                 // Contents of IDE Error register. Only valid when bDriverError is SMART_IDE_ERROR.
 bReserved    : array[0..1] of BYTE;  // Reserved for future expansion.
 dwReserved   : array[0..1] of DWORD; // Reserved for future expansion.
end;

Первые два поля - расписаны, остальные - зарезервированы... Но если на них посмотреть, то сразу же в глаза бросилось наличие двух очень знакомых байт - это $4F и $C2. Кто не знает - это значение, которое нужно заносить в регистр цилиндра при посылке любой SMART-команды... Также есть байтик $B0 - это код IDE-команды "SMART"... Байтик $A0 - это значение регистра "Drive/Head" при посылке SMART-команды...
Т.е. было такое предположение: в этих байтах хранятся IDE-регистры...
Но в итоге, всё-таки, получился облом - тут хранятся только SecNum, Cyl, Head/Dev (или всё вместе - LBA) и Error регистры, остальных - нет... smile
Есть командочка RETURN STATUS, (регистр Feature = $DA), она возвращает IDE-регистры в структуре IDEREGS (в SENDCMDOUTPARAMS.bBuffer), но даже там нет нужного тебе регистра состояния... smile
(хотя использовать RETURN STATUS для чтения регистров - бред, т.к. при посылке этой команды мы сами же и их изменяем...)

Вопрос: зачем тебе нужно смотреть состояние регистров ? Ведь они постоянно меняются, т.к. программа работает в многозадачной среде... Поэтому понятие "текущее состояние" как-то не очень мне понятно...
Если надо смотреть состояние регистров именно на этот момент времени - то это только через порты ввода-вывода. В NT'ях можно с помощью небольшого своего драйверочка разрешить своему процессу доступ к портам, тогда можешь прочитать регистры...
Если же надо смотреть состояние регистров на момент окончания твоей команды (к примеру, SMART-команды), то через SMART_* IOCTL'ы это не сделать...
Как-то видал IOCTL_IDE_PASS_THROUGH: посылается структура, содержащая IDEREGS, размер буффера и сам буффер... Никогда это не пробовал, поэтому даже не знаю, какие IDE-команды можно послать через IDE_PASS_THROUGH, в каких условиях это всё будет работать и т.д. Но можешь попробовать... Я так полагаю, что структура IDEREGS после выполнения IOCTL'а заполниться новыми значениями регитров...
Возможно, сегодня-завтра сам попробую Ide Pass Through - самому интересно...

Цитата
запуска одного (любого)теста

Читаем доку, к примеру, у меня есть по ATA4:
SMART EXECUTE OFF-LINE IMMEDIATE
Регистры на входе:
Код
Features      = D4h
Sector Count  = n/a
Sector Number = n/a
Cylinder Low  = 4Fh
Cylinder High = C2h
Device/Head   = в 4-ом бите №устройства (0 или 1)
Command       = B0h

Мдя... smile А где выбирается тест ?... Короче, видимо, в ATA4 всего один-единственный тест...
Попробуй закачай описалово ATA5 или ATA6 (http://www.t13.org/project/d1410r3-ATA-ATAPI-6.zip) и погляди описание команды SMART... Где-то я видел, что вроде в Sector Number указывается № теста.
Засовывай в регистры нужные значения, посылай через DFP_SEND_DRIVE_COMMAND - и усё smile.
Подкоманды (вернее, уже под-подкоманды) для SMART EXECUTE OFFLINE (которые нужно указывать в Sector Count, имхо):
0 - Выполнить Offline routine в фоновом режиме
1 - Выполнить Short Self-test в фоновом режиме
2 - Выполнить Extended Self-test в фоновом режиме
129 - Выполнить Short Self-test в монопольном режиме
130 - Выполнить Extended Self-test в монопольном режиме

...

Сейчас проверил - запустил Short Self-Test, и всё ок smile
SMART READ DATA во время теста в "Self-test execution status byte" крутило проценты завершенности smile
У меня этот тест длился около 20-30 секунд... Extended тест не решился запустить...
А вот 129 не пошло smile

Код
const
 SMART_SEND_DRIVE_COMMAND = $0007c084;

var
 h : THandle;
 SCIP : SENDCMDINPARAMS;
 SCOP : SENDCMDOUTPARAMS;
 Returned : DWORD;
 
begin
 h := CreateFile (PChar('\\.\PhysicalDrive0'), GENERIC_READ or GENERIC_WRITE,
                  FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);

 FillChar (SCIP, SizeOf(SCIP), 0);
with SCIP do
begin
 cBufferSize  := 0;
 bDriveNumber := 0;
 with irDriveRegs do
 begin
  bFeaturesReg     := $D4;
  bSectorCountReg  := 0;
  bSectorNumberReg := 1; // подкоманда (тест)
  bCylLowReg       := $4F;
  bCylHighReg      := $C2;
  bDriveHeadReg    := $A0;
  bCommandReg      := $B0;
 end;
end;

 FillChar (SCOP, SizeOf(SCOP), 0);

 DeviceIoControl (h, SMART_SEND_DRIVE_COMMAND, @SCIP, SizeOf(SCIP)-1,
                  @SCOP, SizeOf(SCOP)-1, Returned, nil);

 CloseHandle(h);
end;
Структуры SENDCMDINPARAMS и SENDCMDOUTPARAMS определены в том же модуле Ioctl.pas...

Все остальные SMART-команды делаются аналогичным образом, только меняются значения в:
bFeaturesReg - это может быть:
Код
* $D0 - прочитать значения атрибутов (и некоторые доп. SMART-данные),
* $D1 - прочитать пределы атрибутов
* $D2 - включить/выключить автозапись атрибутов в энергонезависимую память,
        тогда в bSectorNumberReg указывается: $00 - выключить, $F1 - включить
* $D3 - записать значения атрибутов в энергонез. память
* $D4 - выполнить тест (bSectorNumberReg содержит подкоманду)
* $D5 - прочитать сектор журнала
* $D6 - записать сектор журнала
* $D8 - включить SMART-операции (если не включить, то почти ниодна команда работать не будет)
* $D9 - выключить SMART-операции (тогда будет работать только команда $D8)
* $DA - возвратить состояние

Остальные регистры - не изменются (bCylLowReg, bCylHighReg, bDriveHeadReg, bCommandReg)

Если это команды $D0, $D1, $D5 - то делай DeviceIoControl (h, SMART_RCV_DRIVE_DATA, ...)
иначе - DeviceIoControl (h, SMART_SEND_DRIVE_COMMAND, ...)
Код
const
 SMART_GET_VERSION        = $00074080;
 SMART_SEND_DRIVE_COMMAND = $0007c084;
 SMART_RCV_DRIVE_DATA     = $0007c088;


PS: возможно, я где-то что-то напутал, т.к. с доками разбирался навскорь...
Тебе же нужно закачать доки по ATA с www.t13.org, почитать описание и форматы команд...


Это сообщение отредактировал(а) p0s0l - 3.3.2005, 01:23


--------------------
С уважением, г-н Посол.
PM   Вверх
Dark Wanderer
Дата 3.3.2005, 23:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 119
Регистрация: 25.10.2004
Где: Кишинёв

Репутация: нет
Всего: нет



Очень помог. С примерами всегда легче
Цитата
с помощью небольшого своего драйверочка

А я то думал почему O&O Drive Lead устанавливает свой драйвер.

Цитата
Вопрос: зачем тебе нужно смотреть состояние регистров ?


Интересно было, что делает мой винт
smile

Маленький вопросик по журналам: как получить кол-во журналов и прочитать нужный мне по его названию(названия нашёл на "http://pcjs.chat.ru/smartdoc.html").

Это сообщение отредактировал(а) Dark Wanderer - 3.3.2005, 23:37
--------------------
  
PM MAIL   Вверх
p0s0l
Дата 4.3.2005, 01:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 14
Всего: 112



Цитата
Интересно было, что делает мой винт
Дык ведь есть уже море готовых программ для просмотра SMART'-аттрибутов, выполнения тестов... smile

Цитата
Маленький вопросик по журналам: как получить кол-во журналов и прочитать нужный мне по его названию(названия нашёл на "http://pcjs.chat.ru/smartdoc.html").
Читаешь нулевой журнал - это типа "каталога":
Код
Byte Descriptions
0-1 SMART Logging Version
2 Number of sectors in the log at log address 1
3 Reserved
4 Number of sectors in the log at log address 2
5 Reserved
… …
510 Number of sectors in the log at log address 255
511 Reserved
Т.е. можешь узнать, сколько секторов есть в каждом журнале... Далее, можешь читать журналы...
Назначения журналов определяется по таблице (см. доки по ATA)... У меня есть на винте дока по ATA-8, в предыдущих ATA поменьше будет этих журналов:
Код
Log address Content
00h Log directory
01h Summary SMART error log
02h Comprehensive SMART error log
03h Extended Comprehensive SMART error log
04h-05h Reserved
06h SMART self-test log
07h Extended SMART self-test log
08h Reserved
09h Selective Self-test log
0Ah-0Fh Reserved
10h-17h Reserved for Serial ATA
18h-1Fh Reserved
20h Streaming performance log
21h Write stream error log
22h Read stream error log
23h Delayed sector log
24h-7Fh Reserved
80h-9Fh Host vendor specific
A0h-BFh Device vendor specific
C0h-EFh Reserved
E0h-E1h Reserved for SCT [Editors Note: Need to fill in project number]
E2h-FFh Reserved
Формат каждого журнала - индивидуален...
К примеру, журнал №1 - Summary SMART error log:
Код
Byte Descriptions
0 SMART error log version
1 Error log index
2-91 First error log data structure
92-181 Second error log data structure
182-271 Third error log data structure
272-361 Fourth error log data structure
362-451 Fifth error log data structure
452-453 Device error count
454-510 Reserved
511 Data structure checksum
Он хранит 5 последних ошибок. Каждая ошибка описывается 5 командами, после которых произошла ошибка (команды описываются состоянием регистров и временем) и состоянием регистров после ошибки:
Код
n thru n+11 First command data structure
n+12 thru n+23 Second command data structure
n+24 thru n+35 Third command data structure
n+36 thru n+47 Fourth command data structure
n+48 thru n+59 Fifth command data structure
n+60 thru n+89 Error data structure
Вот формат команды (command data structure):
Код
Byte Descriptions
n Content of the Device Control register when the Command register was written.
n+1 Content of the Features register when the Command register was written.
n+2 Content of the Sector Count register when the Command register was written.
n+3 Content of the LBA Low register when the Command register was written.
n+4 Content of the LBA Mid register when the Command register was written.
n+5 Content of the LBA High register when the Command register was written.
n+6 Content of the Device register when the Command register was written.
n+7 Content written to the Command register.
n+8 Timestamp (least significant byte)
n+9 Timestamp (next least significant byte)
n+10 Timestamp (next most significant byte)
n+11 Timestamp (most significant byte)
Короче, всё это до ужаса просто, надо только заглянуть в доки по ATA, и посмотреть форматы...

Журнал 02h Comprehensive SMART error log - тоже наподобие первого журнала, формат полностью совпадает, только если первый журнал мог занимать только 1 сектор, то этот - до 51 секторов (51*5 = 515 ошибок хранит)...

Журнал 03h Extended Comprehensive SMART error log тоже хранит ошибки, только для 48-битной адресации (01 и 02 журналы - 24-битная адресация)...

Про остальные - почитай сам smile в доках по ATA... Там всё по полочкам разложено...
Некоторые журналы читаются через SMART READ LOG команду, некоторые - через READ LOG EXT, а некоторые могут и теми и другими командами читаться...
Смотри описание команды SMART, подфункция READ LOG... Там описаны SMART-Logging журналы...
Также смотри описание (если тебе нужны эти журналы) команды READ LOG EXT (это не подфункция команды SMART, а отдельная команда), там описаны General Purpose Logging журналы...



--------------------
С уважением, г-н Посол.
PM   Вверх
p0s0l
Дата 4.3.2005, 20:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 14
Всего: 112



Во, держи, накатал пример чтения LOG-сектора.
Только не все винты ведут журнал, так что может быть и облом...
В данном случае используется IDE PASS THROUGH... Через SMART IOCTL чтение журнала не идёт... Могу показать как делать через SCSI MINIPORT, но через минипорт у меня получалось читать только первые сектора журналов... Если же использовать IDE PASS THROUGH, то вроде читаются все сектора, но фиг знает... больно уж они у меня были пустые... Может так и надо, а может это глюки IDE PASS THROUGH...
Пытался еще через SPTI, команда ATA PASS THROUGH, но чего-то не вышло smile... Плохо, в таких случаях приходится гадать, что неправильно...
Осталось еще для кучи попробовать ATA PASS THROUGH (но, если верить слухам, в Win2kSP1..SP4, XP и XPsp1 это глючно работает или вообще не работает) и ATA PASS THROUGH команду через ASPI...

Код

type
 IDEREGS = packed record
   bFeaturesReg     : BYTE; // Used for specifying SMART "commands".
   bSectorCountReg  : BYTE; // IDE sector count register
   bSectorNumberReg : BYTE; // IDE sector number register
   bCylLowReg       : BYTE; // IDE low order cylinder value
   bCylHighReg      : BYTE; // IDE high order cylinder value
   bDriveHeadReg    : BYTE; // IDE drive/head register
   bCommandReg      : BYTE; // Actual IDE command.
   bReserved        : BYTE; // reserved for future use.  Must be zero.
 end;

 IDE_PASS_THROUGH = packed record
   IdeReg : IDEREGS;
   DataBufferSize : DWORD;
   DataBuffer : array [0..512*1-1] of BYTE;
 end;

const
 IOCTL_IDE_PASS_THROUGH            = $4D028;

procedure TForm1.Button1Click(Sender: TObject);
var
 Buf : IDE_PASS_THROUGH;
 St : boolean;
 h : THandle;
 dwBytesReturned : DWORD;
 s : string;
 i : integer;

begin
 h := CreateFile (PChar('\\.\PhysicalDrive0'), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);

 FillChar (Buf, SizeOf(Buf), $00);
 FillChar (Buf.DataBuffer, SizeOf(Buf.DataBuffer), $FF);
 Buf.DataBufferSize := SizeOf(Buf.DataBuffer);
 with Buf.IdeReg do
 begin
   bSectorNumberReg := $00; // № журнала
   bSectorCountReg  := $01; // сколько секторов читать
   bCommandReg      := $B0; // код команды "SMART"
   bFeaturesReg     := $D5; // подкоманда "READ LOG SECTOR"
   bCylLowReg       := $4F; //
   bCylHighReg      := $C2; //
 end;

 St := DeviceIoControl (h, IOCTL_IDE_PASS_THROUGH, @Buf, SizeOf(Buf), @Buf, SizeOf(Buf), dwBytesReturned, nil);
 CloseHandle (h);

 if St then // LOG-сектор прочитан
 begin
   s := '';
   for i := 0 to High(Buf.DataBuffer) do
   begin
     if (i and $1F) = 0 then s := s + #13;
     s := s + IntToHex(Buf.DataBuffer[i], 2) + ' ';
   end;
   MessageBox (0, PChar(s), 'LOG-сектор', MB_TASKMODAL);
 end;

end;

Добавлено @ 20:07
Еще бы почитать доки по SCSI... Как через него использовать SMART (если возможно) ? (без ATA PASS THROUGH)...


--------------------
С уважением, г-н Посол.
PM   Вверх
Dark Wanderer
Дата 6.3.2005, 15:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 119
Регистрация: 25.10.2004
Где: Кишинёв

Репутация: нет
Всего: нет



Цитата
были пустые...

Ты был прав большая часть действительно пустые. Почитаю документацию и помотрю почему.

Это сообщение отредактировал(а) Dark Wanderer - 6.3.2005, 15:15
--------------------
  
PM MAIL   Вверх
p0s0l
Дата 6.3.2005, 16:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 14
Всего: 112



Цитата
Ты был прав большая часть действительно пустые. Почитаю документацию и помотрю почему.
А у тебя сколько журналов ? И по сколько секторов ?
У меня к примеру, SMART-журналов только 2: 1-ый и 2-ой
1-ый - он всегда 1 сектор
2-ой - пять секторов:
первый сектор - полный, второй - полупустой, остальные - пустые...

Еще фишка такая: если хочешь прочитать три сектора, то в буфере надо выделять не 512*3 байтов, а (512*3 + 3) байтов...
4 сектора = (512*4 + 5) байтов
5 секторов = (512*5 + 7) байтов...
Иначе DeviceIoControl возвращает True, но буфер ничем не заполняется!

Странно это, на сектор не 512 байт надо, а 514... и причем это не относится к первому сектору...

А на счёт пустоты - это нормально... smile Так и должно быть...
К примеру, первый сектор содержит следующее:
01 07 00 00 ...
01 - версия журнала
07 - № записи в журнале, соотвествующей самой недавней ошибке... т.е. у меня всего 7 ошибок было... Также есть поле: 'Device error count', оно тоже содержит 7...

Вот, написал просмотрщик журнала "Comprehensive Error Log" (№2):
Код
const SectorCnt = 5; // ЧИСЛО СЕКТОРОВ В ЖУРНАЛЕ !!!!

type
 IDEREGS = packed record
   bFeaturesReg     : BYTE; // Used for specifying SMART "commands".
   bSectorCountReg  : BYTE; // IDE sector count register
   bSectorNumberReg : BYTE; // IDE sector number register
   bCylLowReg       : BYTE; // IDE low order cylinder value
   bCylHighReg      : BYTE; // IDE high order cylinder value
   bDriveHeadReg    : BYTE; // IDE drive/head register
   bCommandReg      : BYTE; // Actual IDE command.
   bReserved        : BYTE; // reserved for future use.  Must be zero.
 end;

type
 IDE_PASS_THROUGH = packed record
   IdeReg : IDEREGS;
   DataBufferSize : DWORD;
   DataBuffer : array [0..(514*SectorCnt)-3] of BYTE;
 end;

const
 IOCTL_IDE_PASS_THROUGH            = $4D028;

type
 TLogCommand = packed record
   DC, FR, SC, LL, LM, LH, DR, CR : byte;
   TimeStamp : dword;
 end;
 PLogCommand = ^TLogCommand;

 TLogError = packed record
   Reserved  : byte;
   ER, SC, LL, LM, LH, DR, SR : byte;
   Extended  : array [0..18] of byte;
   State     : byte;
   TimeStamp : word;
 end;

 TLogErrorData = packed record
   Commands : array [0..4] of TLogCommand;
   Error    : TLogError;
 end;
 PLogErrorData = ^TLogErrorData;

 TLogErrorSector = packed record
   LogVersion  : byte;
   LogIndex    : byte;
   Errors      : array [0..4] of TLogErrorData;
   ErrorCount  : word;
   Reserved    : array [0..56] of byte;
   Checksum    : byte;
 end;
 PLogErrorSector = ^TLogErrorSector;

procedure TForm1.Button1Click(Sender: TObject);
var
 Buf : IDE_PASS_THROUGH;
 St : boolean;
 h : THandle;
 dwBytesReturned : DWORD;
 s : string;
 i, j, sec : integer;
 ls : PLogErrorSector;
 er : PLogErrorData;
 cmd : PLogCommand;

begin
 h := CreateFile (PChar('\\.\PhysicalDrive0'), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);

 FillChar (Buf, SizeOf(Buf), $00);
 FillChar (Buf.DataBuffer, SizeOf(Buf.DataBuffer), $FF);
 Buf.DataBufferSize := SizeOf(Buf.DataBuffer);
 with Buf.IdeReg do
 begin
   bSectorNumberReg := $02; // № журнала
   bSectorCountReg  := SectorCnt; // сектор
   bCommandReg      := $B0; // код команды "SMART"
   bFeaturesReg     := $D5; // подкоманда "READ LOG SECTOR"
   bCylLowReg       := $4F; //
   bCylHighReg      := $C2; //
 end;

 St := DeviceIoControl (h, IOCTL_IDE_PASS_THROUGH, @Buf, SizeOf(Buf), @Buf, SizeOf(Buf), dwBytesReturned, nil);
 CloseHandle (h);

 if St then // LOG-сектор прочитан
 begin
   Memo1.Lines.Clear;

   for sec := 0 to SectorCnt-1 do
   begin
   Memo1.Lines.Add('Sector: ' + inttostr(sec));
   ls := @Buf.DataBuffer[sec*514];
   if sec = 0 then
   begin
     Memo1.Lines.Add('Error log version: ' + IntToStr(ls.LogVersion));
     Memo1.Lines.Add('Error log index: ' + IntToStr(ls.LogIndex));
     Memo1.Lines.Add('Device error count: ' + IntToStr(ls.ErrorCount));
   end;
   Memo1.Lines.Add('Checksum: ' + IntToStr(ls.Checksum));

   for i := 0 to High(ls.Errors) do
   begin
     Memo1.Lines.Add('Error №' + IntToStr(sec*5 + i + 1) + ' info');
     er := @ls.Errors[i];
     for j := 0 to High(er.Commands) do
     begin
       cmd := @er.Commands[j];
       s := 'DC=' + IntToHex(cmd.DC, 2);
       s := s + ' FR=' + IntToHex(cmd.FR, 2);
       s := s + ' SC=' + IntToHex(cmd.SC, 2);
       s := s + ' LL=' + IntToHex(cmd.LL, 2);
       s := s + ' LM=' + IntToHex(cmd.LM, 2);
       s := s + ' LH=' + IntToHex(cmd.LH, 2);
       s := s + ' DR=' + IntToHex(cmd.DR, 2);
       s := s + ' CR=' + IntToHex(cmd.CR, 2);
       s := s + ' @' + IntToStr(cmd.TimeStamp) + 'ms';
       Memo1.Lines.Add('Cmd' + IntToStr(j+1) + ': ' + s);
     end;

     s := 'Rsv=' + IntToHex(er.Error.Reserved, 2);
     s := s + ' ER=' + IntToHex(er.Error.ER, 2);
     s := s + ' SC=' + IntToHex(er.Error.SC, 2);
     s := s + ' LL=' + IntToHex(er.Error.LL, 2);
     s := s + ' LM=' + IntToHex(er.Error.LM, 2);
     s := s + ' LH=' + IntToHex(er.Error.LH, 2);
     s := s + ' DR=' + IntToHex(er.Error.DR, 2);
     s := s + ' SR=' + IntToHex(er.Error.SR, 2);
     s := s + ' St=' + IntToHex(er.Error.State, 2);
     s := s + ' @' + IntToStr(er.Error.TimeStamp) + 'h';
     Memo1.Lines.Add('Error: ' + s);
     s := '';
     for j := 0 to High(er.Error.Extended) do s := s + IntToHex(er.Error.Extended[j], 2) + ' ';
     Memo1.Lines.Add('Error extended: ' + s);
     Memo1.Lines.Add('');
   end;
   Memo1.Lines.Add('-------------------------------------------------');
   end;
 end;
end;
Выводит инфу в Memo1... Сделано на быструю руку, поэтому число секторов в журнале не считывается из нулевого журнала, а указывается в константе SectorCnt...


--------------------
С уважением, г-н Посол.
PM   Вверх
Dark Wanderer
Дата 7.3.2005, 13:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 119
Регистрация: 25.10.2004
Где: Кишинёв

Репутация: нет
Всего: нет



Не могу понять почему не работает процедура
Код

const
SMART_RCV_DRIVE_DATA= $0007c088;
type
Tbuffer=array[0..511] of byte;
var
h : THandle;
z:dword;
SCIP :  SENDCMDINPARAMS;

 i:integer;
DataBuffer : tbuffer;
begin
h := CreateFile (PChar('\\.\PhysicalDrive0'), GENERIC_READ or GENERIC_WRITE,
                 FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);


FillChar (scip,sizeof(scip),$00);
FillChar (DAtabuffer, SizeOf(databuffer), $00);
with SCIP do

with irDriveRegs do
begin
begin
 bFeaturesReg     := $D0;


 bCylLowReg       := $4F;
 bCylHighReg      := $C2;

 bCommandReg      := $B0;
end;
end;


DeviceIoControl (h,$0007c088, @SCIP, SizeOf(SCIP),
                 @DataBuffer, SizeOf(DataBuffer), z, nil);



memo1.Lines.Add(inttostr(databuffer[363]));

CloseHandle(h);

end;


Запускаю эту процедуру по таймеру 100ms и пытаюсь прочитать процент выполнения теста "Short Self-Test". Тест запускается (точно), но при попытке чтения прогресса все байты от 1..511 пустые. smile
--------------------
  
PM MAIL   Вверх
p0s0l
Дата 7.3.2005, 21:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 14
Всего: 112



Потому что на выходе требуется не просто array [0..511] of byte, а SENDCMDOUTPARAMS... При чем надо задавать на входе размер выходного буфера (хотя и без этого работает...):
Код
var
 DataBuffer : array [0..SizeOf(SENDCMDOUTPARAMS)-1 + 512] of byte;
 SCOP : SENDCMDOUTPARAMS absolute DataBuffer;
...
 FillChar (DataBuffer, SizeOf(DataBuffer), 0);
 SCOP.cBufferSize := 512;
...
 DeviceIoControl ...
...
 i := 363;
 memo1.Lines.Add(inttostr(SCOP.bBuffer[i]));



--------------------
С уважением, г-н Посол.
PM   Вверх
Dark Wanderer
Дата 7.3.2005, 22:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 119
Регистрация: 25.10.2004
Где: Кишинёв

Репутация: нет
Всего: нет



Всё заработало! Спасибо!
--------------------
  
PM MAIL   Вверх
Dark Wanderer
Дата 30.3.2005, 15:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 119
Регистрация: 25.10.2004
Где: Кишинёв

Репутация: нет
Всего: нет



Не хотел создавать новой темы поэтому решил спросить здесь. Понадобилось програмно узнать куда винт подключён (master/slave...).
Посмотрел доки по ATA (ATA-6), но там про это даже ничего не сказано. Решил закачать новые(ATA-8) на T13, но и там ничего не нашёл. smile
Как это можно сделать?
--------------------
  
PM MAIL   Вверх
p0s0l
Дата 30.3.2005, 19:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 14
Всего: 112



Код
var
  ver : TGetVersionOutParams;

DeviceIoControl (hDrive, SMART_GET_VERSION, nil, 0, @ver, SizeOf(ver), ..)
В ver.bIDEDeviceMap будет:
$01 - ATA Primary Master
$02 - ATA Primary Slave
$04 - ATA Secondary Mastera
$08 - ATA Secondary Slave
$10 - ATAPI Primary Master
$20 - ATAPI Primary Slave
$40 - ATAPI Secondary Master
$80 - ATAPI Secondary Slave

Но, насколько я слышал, такой способ определения не всегда будет работать... вернее работать будет, но определяться будет неправильно... У себя сейчас проверил (XP) - Primary Master выдал 04 smile

Тогда можно еще через ASPI - первые два SCSI-контроллера соответствуют Primary и Secondary IDE-контроллерам (Adapter=0 и Adapter=1), а устройство (Target) определяет Master это (0) или Slave (1)...



--------------------
С уважением, г-н Посол.
PM   Вверх
Dark Wanderer
Дата 31.3.2005, 11:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 119
Регистрация: 25.10.2004
Где: Кишинёв

Репутация: нет
Всего: нет



p0s0l Можешь поподробней про ASPI и SCSI. Доки, линки. Вобщем, что есть.


Это сообщение отредактировал(а) Dark Wanderer - 31.3.2005, 12:23
--------------------
  
PM MAIL   Вверх
Dark Wanderer
Дата 4.4.2005, 13:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 119
Регистрация: 25.10.2004
Где: Кишинёв

Репутация: нет
Всего: нет



p0s0l Выполнил твой код и получил 33 smile

Вобщем если кто интересуется данным вопросом кроме меня отрыл немного инфы в архиве:

http://www.zianet.com/jgray/dat/files/ASPISDK.exe

--------------------
  
PM MAIL   Вверх
p0s0l
Дата 4.4.2005, 22:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 14
Всего: 112



Цитата(Dark @ 31.3.2005, 11:09)
p0s0l Можешь поподробней про ASPI и SCSI. Доки, линки. Вобщем, что есть.
SCSI - www.t10.org
ASPI - в принципе, хватит и того, что ты уже нашёл smile (я точно с этого же начинал, конвертил .h в .pas smile )
но есть кое-что и для delphi:
http://www.torry.net/authorsmore.php?id=19...1931ca762e50f84


--------------------
С уважением, г-н Посол.
PM   Вверх
Dark Wanderer
Дата 5.4.2005, 15:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 119
Регистрация: 25.10.2004
Где: Кишинёв

Репутация: нет
Всего: нет



Круто! Иду разбираться smile

Реально ли прочитать те же SMART атрибуты только через ASPI?

Это сообщение отредактировал(а) Dark Wanderer - 5.4.2005, 17:09
--------------------
  
PM MAIL   Вверх
p0s0l
Дата 7.4.2005, 00:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 14
Всего: 112



Цитата(Dark @ 5.4.2005, 15:57)
Реально ли прочитать те же SMART атрибуты только через ASPI?
Честно говоря - хз... Не проверял... Но когда-то смотрел доки по SCSI, и видел команды чтения лог-страниц, среди которых есть температура, Start-Stop Cycle Count, Self-test результаты и др, что наводит на мысль о похожести их на SMART-атрибуты и журналы...
Если проверишь - обязательно дай знать smile







--------------------
С уважением, г-н Посол.
PM   Вверх
falcon39
Дата 5.6.2005, 23:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 103
Регистрация: 21.6.2004

Репутация: нет
Всего: 0



Как узнать температуру диска я узнал. А как узнать температуру процессора и чипсета?
--------------------
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0738 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.