Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2008.10.05;
Скачать: [xml.tar.bz2];

Вниз

spindown by DeviceIoControl   Найти похожие ветки 

 
kernel ©   (2007-11-05 17:16) [0]

Доброго времени суток, уважаемые Delphi-кодеры :)
Необходимо остановить шпиндель жесткого диска с помощью DeviceIoControl. Прыгать в нулевое кольцо и посылать там в порт $0E6 не хочется, тем более вся программа построена на DeviceIoControl.

Думал, все обойдется посылкой $0E6 в регистр "command", дык не получается :: сложилось впечатление, что винту из-под DeviceIoControl можно посылать ограниченное число команд.

На десерт неработающий кусок кода:

SCIP_PM.cBufferSize:=0;
SCIP_PM.irDriveRegs.bFeaturesReg:=0;
SCIP_PM.irDriveRegs.bSectorCountReg:=0;
SCIP_PM.irDriveRegs.bSectorNumberReg:=0;
SCIP_PM.irDriveRegs.bCylLowReg:=0;
SCIP_PM.irDriveRegs.bCylHighReg:=0;
SCIP_PM.irDriveRegs.bDriveHeadReg:=$E0;//пробовал $A0 or ((DRVNUM and 1) shl 4);
SCIP_PM.irDriveRegs.bCommandReg:=$E6;
SCIP_PM.bDriveNumber:=DRVNUM;
if not DeviceIoControl(hSMARTIOCTL[DRVNUM], DFP_SEND_DRIVE_COMMAND,
@SCIP_PM, sizeof(TSENDCMDINPARAMS)-1, @SCOP_PM[DRVNUM],
 sizeof(TSENDCMDOUTPARAMS)-1 + SCIP_PM.cBufferSize, c, nil) then showmessage(PChar("Message: "+SysErrorMessage(GetLastError)+
   " | Code: "+IntToStr(GetLastError)));


Всем заранее спасибо :)


 
Dib@zol ©   (2007-11-05 19:45) [1]

Up.
Немного сомневаюсь, что винда вообще даст это сделать из-под ДивайсИоКонтрола, так как функция замедления/остановки шпинделя в большинстве случаев нужна только дровам ХДД. Тут только разве что вручную собрать реостат с управлением от ЮСБ и подключить его к шнуру питания винта :)

Впрочем, я где-то в Инете натыкался на любопытную прогу уменьшения скорости сидюшного дисковода, вроде даже опенсорсную... А CD привод он вроде как тоже SCSI. Вощем, гугль в руки и бегом ;)


 
kernel ©   (2007-11-05 19:52) [2]

Вырубить ч\з DevIOCtl, вроде, должно быть можно. Насколько мне известно, ограничений на команды управления винтом быть не должно (ч\з регистры). А гугль ничего мне не дал :(


 
Dimaxx ©   (2007-11-05 20:56) [3]

Вообще-то в примерах везде видел (получение СМАРТ, получение инфы о винте и т.п.)

SCIP_PM.irDriveRegs.bSectorCountReg:=1;
SCIP_PM.irDriveRegs.bSectorNumberReg:=1;

почему ты пытался с 0 - не ясно.


 
Dimaxx ©   (2007-11-05 21:13) [4]

Ты не перепутал с командами?

E0 (Standby Mode)

Выключает двигатель шпинделя, при доступе снова автоматически включается.

E1 (Idle Mode)

Выключает двигатель шпинделя.

E2 (Auto Power Down)

Выключает двигатель шпинделя, после доступа снова автоматически выключается, время устанавливается шагами по 5 секунд (1F2h).

E3 (Auto Power Down)

Включает двигатель шпинделя и далее как команда E2h.

E5 (Read Power Mode)

Читает в 1F2h состояние двигателя шпинделя.

E6 (Sleep Mode)

Выключает накопитель, включение только через сброс (программный или аппаратный).


Е6 тебе не даст выполнить драйвер HDD. Да и остальные команды управления движком тоже.


 
Dimaxx ©   (2007-11-05 21:19) [5]

Даже если тебе удасться нормально заставлять винт выключать движок и включать его - не советую этим пользоваться. Может я и ошибаюсь, но ты хочешь выключать винт на время его "неиспользования". Спешу тебя огорчить - частые включения/выключения сильно снижают срок службы накопителя. Пусть уж лучше он работает круглые сутки.


 
kernel ©   (2007-11-06 14:01) [6]


> Е6 тебе не даст выполнить драйвер HDD. Да и остальные команды
> управления движком тоже.

Зачем же тогда придумали структуру IDERegs? Чтобы половину команд в регистры нельзя было заслать что-ли? :)


 
Dimaxx ©   (2007-11-06 14:58) [7]

А зачем вырубать накопитель в винде, да еще так, что его можно включить только по сбросу?? Пиши драйвер свой, чтобы был полный доступ.


 
Dimaxx ©   (2007-11-06 15:00) [8]

По крайней мере инфа со служебного сектора винта по команде $EC (вроде такая) нормально получается. Значит, что-то можно, а что-то нельзя.


 
kernel ©   (2007-11-06 15:40) [9]

при подаче команды в винт, пишется:
Message: Область данных, переданная по системному вызову, слишком мала
Code: 122


 
Dib@zol ©   (2007-11-06 15:48) [10]

Любопытно... А может это вовсе и не запрещение на посыл команды? Попробуй сделать цикл вызовов с размером этой самой области данных от 1 скажем до high(DWORD). И анализируй возвращённый результат. Если он не 122, то ура - нужный размер найден.
ЗЫ Такой способ однажды помог мне экспериментально выяснить размер структуры под системный диалог открытия файла. И только потом я дотумкал посмотреть как это реализовано в VCL :)


 
kernel ©   (2007-11-06 16:08) [11]

Dimaxx, с командой я не ошибся ($E6)

> Dimaxx ©   (05.11.07 20:56) [3]
>
> Вообще-то в примерах везде видел (получение СМАРТ, получение
> инфы о винте и т.п.)
>
> SCIP_PM.irDriveRegs.bSectorCountReg:=1;
> SCIP_PM.irDriveRegs.bSectorNumberReg:=1;
>
> почему ты пытался с 0 - не ясно.

Ставил 0, т.к. это то состояние регистров ч\з которое мне удавалось вырубить винт (через hddl21)
А дело было было в том, что я не мог найти IOCTL_ код, для этой команды (в DeviceIoControl(hDevice, IOCTL_...)
В общем всем огроооооооомное спасибо, вот работающий код (случайно наткнулся на http://www.delphi-forum.de/printview.php?t=75438&start=0&sid=cd1c3a8937a3e6a42aff7df3fcee434d):

Type  
TIDERegs = 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;  
 IDEREGS   = TIDERegs;  
 PIDERegs  = ^TIDERegs;  

TIdSector = packed record  
   wGenConfig                 : Word; //00  
   wNumCyls                   : Word;  
   wReserved                  : Word;  
   wNumHeads                  : Word;  
   wBytesPerTrack             : Word;  
   wBytesPerSector            : Word;  
   wSectorsPerTrack           : Word;  
   wVendorUnique              : Array[0..2] of Word;  
   sSerialNumber              : Array[0..19] of Char; //10-19  
   wBufferType                : Word;  
   wBufferSize                : Word;  
   wECCSize                   : Word;  
   sFirmwareRev               : Array[0..7] of Char;  //23-26  
   sModelNumber               : Array[0..39] of Char; //27-46  
   wMoreVendorUnique          : Word;  
   wDoubleWordIO              : Word;  
   wCapabilities              : Word;  
   wReserved1                 : Word;  
   wPIOTiming                 : Word;  
   wDMATiming                 : Word;  
   wBS                        : Word;  
   wNumCurrentCyls            : Word;  
   wNumCurrentHeads           : Word;  
   wNumCurrentSectorsPerTrack : Word;  
   ulCurrentSectorCapacity    : ULONG; //57-58  
   wMultSectorStuff           : Word;  
   ulTotalAddressableSectors  : ULONG; //60-61  
   wSingleWordDMA             : Word;  
   wMultiWordDMA              : Word;  //63  
   wFlowControlPIOSupported   : Word;  //64  
   wMinimumMultiWordDMA       : Word;  //65  
   wRecommendedMultiWordDMA   : Word;  //66  
   wMinimumPIOCycleWOFlow     : Word;  //67  
   wMinimumPIOCycleIORDYFlow  : Word;  //68  
   bReserved1                 : Array[0..21] of Byte; //69-79  
   wMajorVersionNumber        : Word;  //80  
   wMinorVersionNumber        : Word;  //81  
   wCommandSetSupported       : Word;  //82  
   wCommandSetSupported2      : Word;  //83  
   wCommandSetExtension       : Word;  //84  
   wCommandSetFeatureEnabled1 : Word;  //85  
   wCommandSetFeatureEnabled2 : Word;  //86  
   wCommandSetFeatureEnabled3 : Word;  //87  
   wUltraDMAMode              : Word;  //88  
   wTimeRequiredErase         : Word;  //89  
   wTimeRequiredEnhancedErase : Word;  //90  
   wAbleMode                  : Word;  //91  
   bReserved2                 : Array[0..71] of Byte; //92-127  
   wSecurityModeFeature       : Word;  //128  
   wCurrentFeatureOption      : Word;  //129  
   wReserved2                 : Word;  //130  
   wInitialPowerMode          : Word;  //131  
   bReserved3                 : Array[0..247] of Byte; //132-255  
 end;  
 PIdSector = ^TIdSector;

const  
 BufferSize = SizeOf(TIDERegs)+4;  
 IOCTL_IDE_PASS_THROUGH        = $0004d028;

implementation

{$R *.dfm}

Function IdeRegPassThrough(Device: String; var ideregs: TIDERegs ): Boolean;  
var  
 ret:BOOL;  
 hDevice : THandle;  
 cbBytesReturned : DWORD;  
 pInData : PIDERegs;  
 pOutData : Pointer;  
 Buffer : Array[0..BufferSize-1] of Byte;  
begin  
 Result := False;  
 FillChar(Buffer,BufferSize,#0);  

 hDevice := CreateFile( PChar(Device), GENERIC_READ or GENERIC_WRITE,  
   FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0 );  
 if hDevice=INVALID_HANDLE_VALUE then Exit;  
 try  
   pInData := @Buffer;  
    pOutData := pInData;  
   pInData^ := ideregs;  
   ret := DeviceIoControl( hDevice, IOCTL_IDE_PASS_THROUGH, @Buffer, BufferSize, @Buffer, BufferSize, cbBytesReturned, nil );  
   if not ret then begin  
     Exit;  
   end;  
   ideregs := PIDERegs(pOutData)^;  
 finally  
   CloseHandle(hDevice);  
 end;  
 Result := True;  
end;  

function SendToSleep(Device: String): Boolean;
var  
 ideregs : TIDERegs;  
begin  
 Result := False;  
 with ideregs do  
 begin  
   bFeaturesReg     := 0;  
   bSectorCountReg  := 0;  
   bSectorNumberReg := 0;  
   bCylLowReg       := 0;  
   bCylHighReg      := 0;  
   bDriveHeadReg    := $A0;  
   bCommandReg      := $E6;  
   bReserved        := 0;  
 end;  
 if not IdeRegPassThrough(Device, ideregs ) then Exit else Result := True;  
end;

//Label1.caption:= BoolToStr(SendToSleep("\\.\PhysicalDrive0"));


 
Dimaxx ©   (2007-11-06 16:18) [12]


> с командой я не ошибся ($E6)

Но ты так и не сказал для чего тебе это нужно было... :)


 
kernel ©   (2007-11-06 16:58) [13]

Завалялся винт у меня (SAMSUNG SP0802) - с трупнутой поверхностью. Думаю куда-нибудь двигатель его применить...


 
Andrey_rus ©   (2007-11-06 17:06) [14]


> IOCTL_IDE_PASS_THROUGH


Не будет работать с драверами отличными от стандартных. Например - NVIDIA (nForce). Хотя... Если у кого-нибудь есть возможность проверьте пожалуйста.


 
kernel ©   (2007-11-06 17:23) [15]

проверял на NVIDIA nForce 430B (6150)  -  все нормально :)


 
Dimaxx ©   (2007-11-06 21:13) [16]

Надо смотреть. Если стоит "Стандартный двухканальный PCI-IDE контроллер", то будет работать. А если стоит родной драйвер - фиг. У меня на JMicron"e ни каким образом нельзя было получить служебный сектор - ни через SCSI, ни через IDE. Откатил на стандартный драйвер - с полпинка заработало.


 
kernel ©   (2007-11-07 10:25) [17]

теперь не знаю как его снова запустить :(


 
tesseract ©   (2007-11-07 14:41) [18]


> теперь не знаю как его снова запустить :(


Молодец.


 
kernel ©   (2007-11-07 15:05) [19]


> tesseract ©   (07.11.07 14:41) [18]
> > теперь не знаю как его снова запустить :(Молодец.

?


 
Andrey_rus ©   (2007-11-07 18:26) [20]


> проверял на NVIDIA nForce 430B (6150)  -  все нормально


Драйвера такие?

disk.sys
nvata.sys
idecoi.dll
idecoiins.dll
nvcoi.dll


или такие?

disk.sys
atapi.sys
storprop.dl
intelide.sys
pciidex.sys


 
Dimaxx ©   (2007-11-07 18:54) [21]


> теперь не знаю как его снова запустить :(

Я ж сказал, что не та команда. Ты послал в sleep-режим накопитель. Прочитай в [4] что написано про команду $E6.


 
kernel ©   (2007-11-07 19:41) [22]


> Драйвера такие?
>
> disk.sys
> nvata.sys
> idecoi.dll
> idecoiins.dll
> nvcoi.dll
>
> или такие?
>
> disk.sys
> atapi.sys
> storprop.dl
> intelide.sys
> pciidex.sys


Проверял на NVIDIA nForce 430B (6150) со стандартным ATA-драйвером - все отлично работало.
Проверял на NVIDIA nForce 4 с драйвером NVIDIA SW (nvata.sys) - все отлично работало.


> Я ж сказал, что не та команда. Ты послал в sleep-режим накопитель.
>  Прочитай в [4] что написано про команду $E6.


Дык мне и нужно его в слип ставить, чтобы при первом доступе он не завелся. Для запуска (после $e6) пойдут только команды Recalibrate ($10-$1F).

В общем, решение проблемы с запуском ([17]) :: использовать $10 (или любой другой до $1F) вместо $E6
:)


 
Andrey_rus ©   (2007-11-07 20:13) [23]


> Проверял на NVIDIA nForce 4 с драйвером NVIDIA SW (nvata.
> sys) - все отлично работало.


Мистика. Дело в том, что IOCTL_IDE_PASS_THROUGH недокументированная возможность стандартных драйверов и она не реализованна у разработчиков третьих фирм.


 
Dimaxx ©   (2007-11-07 20:28) [24]

Значит кто-то их реализует, а кто-то нет... :)


 
kernel ©   (2007-11-08 09:40) [25]


> Мистика. Дело в том, что IOCTL_IDE_PASS_THROUGH недокументированная
> возможность стандартных драйверов и она не реализованна
> у разработчиков третьих фирм.


Вероятно, зависит от версии драйверов (по крайней мере у NVIDIA). Натыкался в интернете - на форуме каком-то писали, что на nForce 2 с драйверами какой-то версии работало, а с более старыми драйверами - нет. Видимо, как разработчики дров реализуют совместимость со стандартным ATA драйвером, так и будет IOCTL_IDE_PASS_THROUGH работать :)


 
Dimaxx ©   (2007-11-08 10:13) [26]

Но если не работает с IDE, то со SCSI должно работать. А не работает... :D


 
kernel ©   (2007-11-08 11:38) [27]


> Но если не работает с IDE, то со SCSI должно работать. А
> не работает... :D


IOCTL_SCSI_PASS_THROUGH ?


 
Dimaxx ©   (2007-11-08 12:58) [28]

Угу. На SATA винтах работает (давно мучал - не помню какую юзал команду - IDE или SCSI), а вот на внешних IDE-контроллерах работает только если драйвер стоит дефолтный.


 
Dimaxx ©   (2007-11-08 13:01) [29]

Самое интересное, что на JMicron"е висел еще привод DVD. И его модель нормально получалась. А вот при обращении к IDE-винту выдавал ошибку. Поставил дефолтный драйвер - все заработало.


 
kernel ©   (2007-11-08 13:55) [30]

У себя на SATA проверял - работает нормально :)

Может быть существует более универсальный аналог IOCTL_ATA(SCSI)_PASS_THROUGH?


 
Dimaxx ©   (2007-11-09 01:09) [31]

Существует... Это драйвер... :) И делай в нем что хошь!


 
kernel ©   (2007-11-09 08:07) [32]


> Существует... Это драйвер... :) И делай в нем что хошь!


Эх... Если бы я сразу начал делать через драйвер, а сейчас, когда все приложение построено на DeviceIOControl, уже поздно... :(


 
Andrey_rus   (2007-12-09 09:33) [33]


> Проверял на NVIDIA nForce 4 с драйвером NVIDIA SW (nvata.sys) - все отлично работало.


Мистика... Скачай небольшую прогу (46кб) - http://www.smarthdd.com/rus/SMARTHDD.exe и нажми на кнопку тюнинг. Программа говорит - тюнинг блокируется драйвером? Какая у тебя OS?


 
kernel ©   (2007-12-10 20:00) [34]


> Мистика... Скачай небольшую прогу (46кб) - http://www.smarthdd.
> com/rus/SMARTHDD.exe и нажми на кнопку тюнинг. Программа
> говорит - тюнинг блокируется драйвером? Какая у тебя OS?

OS у меня WinXP (SP2)

Запустился "Волшебный диск". Вот что пишет:

Торговая марка - Hitachi
Модель - Hitachi HDS721616PLA380
Серийный номер - PVB300D2R7K0BD
Емкость - 153.3 Гб
Логические диски - C: D:
Среднее время доступа - 19.1 мс
Средняя скорость чтения - 74 Мб/с
Текущая температура - 38 °C
Наивысшая температура - 38 °C
Подключений к питанию - 1277
Отработано часов - ?
Состояние - исправен
Начало анализа - 10.12.2007


После нажатия тюнинг появился MessageBox:

---------------------------
Волшебный диск :: Информация
---------------------------
Эта функциональность заблокирована в этой версии программы.

Хотите разблокировать?
---------------------------
Да   Нет  
---------------------------


Только что-то Касперский на него ругаться начал...


 
Andrey_rus   (2007-12-10 20:58) [35]


> После нажатия тюнинг появился - Эта функциональность заблокирована в этой версии программы.

Следовательно, программа может осуществлять прямой доступ к накопителю при установленных у вас драйверах контроллера ATA.
Нажмите на кнопку "режим эксперта" и скопируйте сюда список файлов драйвера с их версиями.


 
Andrey_rus   (2007-12-10 21:09) [36]

> Только что-то Касперский на него ругаться начал...
Это проактивная защита, которая носит лишь вероятностный характер. Не беспокойтесь, я знаяю ребят пишущих эту программу - это не те люди. Хотя, конечно, решать Вам.


> После нажатия тюнинг появился - Эта функциональность заблокирована
> в этой версии программы.

Если хотите - можно и разблокировать. :)


 
kernel ©   (2007-12-11 15:45) [37]

...
Контроллер:
Standard Dual Channel PCI IDE Controller
Ревизия - F2

Файлы драйверов:
c:\windows\system32\drivers\disk.sys (5.1.2600.2180)
c:\windows\system32\drivers\atapi.sys (5.1.2600.2180)
c:\windows\system32\storprop.dll (5.1.2600.2180)
c:\windows\system32\drivers\pciidex.sys (5.1.2600.2180)
c:\windows\system32\drivers\pciide.sys (5.1.2600.0)


Хм, теперь понял. У меня установлено NVidia nForce4 Sata Controller и Standard Dual Channel PCI IDE Controller вместе. У nForce4 Sata используется nvata.sys. Но как оказалось, программы работают от Standard Dual Channel PCI IDE Controller. Теперь все встало на свои места :)



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2008.10.05;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.57 MB
Время: 0.009 c
15-1218627697
Альф
2008-08-13 15:41
2008.10.05
Выбор построителя отчетов


2-1219778976
dar
2008-08-26 23:29
2008.10.05
canvas под углом


15-1218807721
@!!ex
2008-08-15 17:42
2008.10.05
Как заменить рисунок в TImage?


2-1219393623
Jimmy
2008-08-22 12:27
2008.10.05
Инсталляция шрифтов


11-1194302140
tigra
2007-11-06 01:35
2008.10.05
form.caption





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский