Форум: "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.007 c