Форум: "Система";
Текущий архив: 2004.04.11;
Скачать: [xml.tar.bz2];
ВнизEnable disk / Disable disk в Device Manager. HELP!! Найти похожие ветки
← →
незнайка © (2004-01-16 12:05) [0]В Device Manager есть функция Enable/Disable, которую можно применить к разным устройствам и дискам. Диски и интересуют. Как программным путем можно отключить диск (аналог mount/Unmount в юниксе)
← →
Незнайка © (2004-01-16 15:21) [1]хм.. и все же.. как отключить диск, чтоб он перестал видtться системой?
← →
Kerk © (2004-01-16 15:29) [2]Конкретных апи сейчас не скажу, но что если удалить соответствующий симлинк?
← →
Styx (2004-01-16 15:30) [3]mountvol.exe
← →
незнайка © (2004-01-16 16:06) [4]Kerk: Нет, думаю, что это не пройдет.. нужен именно аналог Disable (когда выключаешь его в ручную)
Styx: Нужно отключить диск полностью, чтоб все кеши очистились полностью... система не должна видеть этот диск вообще..
← →
незнайка © (2004-01-16 16:29) [5]Нашел несколько запросов к драйверу: IRP_MN_STOP_DEVICE, IRP_MN_REMOVE_DEVICE и т.п.. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/kmarch/hh/kmarch/pnp-irps_4noy.asp
Но.. ни кодов, ни где они описанны, ничего.. может кто знает?
← →
N169 (2004-01-16 17:45) [6]Может, Setup API поможет? (группа ф-й, имена которых начинаются с SetupDi....)
← →
Alex Konshin © (2004-01-16 21:31) [7]IRP_MN_STOP_DEVICE и т.п. тебе точно не поможет - это не тот уровень.
Нужно сделать что-то типа того, что делает эта команда:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ddtools/hh/ddtools/devcon_34vn.asp
Можешь попробовать его поисследовать и дисассемблировать :-)
Хотя вполне возможно, что в DDK есть его исходники. Дойду до дома - посмотрю.
Может, тебе будет просто достаточно зарезервировать устройство (если это работает для IDE)? http://msdn.microsoft.com/library/en-us/storage/hh/storage/k307_6p0y.asp
PS: Я тут мимоходом обнаружил, что теперь команды вроде IOCTL_ATA_PASS_THROUGH задокументированы. Хм, получается, что теперь можно читать-писать напрямую.
← →
Незнайка © (2004-01-16 22:15) [8]Alex Konshin: Вот то, что делает эта команда (Devcon) судя по всему то, что нужно... но исходники , конечно, предпочтительней :). Дело вот в чем.. это продолжение предыдущей задачи.. после того, как я записал сектора на диск (и в это время к системе не подключен тот диск с которого я снимал эти сектора, то кеш нормально читается по новой и все ok.. НО.. если эти сектора я снимаю с диска и тут же пишу на другой и после окончания работы даю команду IOCTL_DISK_UPDATE_PROPERTIES, то система вываливается в синий экран.. судя по всему win не может разобраться с присутствием одновременно совершенно идентичных дисков в системе.. поэтому и возникла идея перед командой обновления кеша отключить тот диск, с которого сектора взяты.
IOCTL_STORAGE_RESERVE - эта команда на scsi не проходит. Сегодня уже пробовал... у меня выдает ошибку..
М-да.. тоже посмотрел... две команды IOCTL_ATA_ задокументировали :)
← →
Alex Konshin © (2004-01-16 22:39) [9]Дело вот в чем.. это продолжение предыдущей задачи..
Это я догадался.
Такое ощущение, что ты пишешь свой Ghost.
НО.. если эти сектора я снимаю с диска и тут же пишу на другой и после окончания работы даю команду IOCTL_DISK_UPDATE_PROPERTIES, то система вываливается в синий экран..
Может, дело и не в том, что ты не резервировал.
У тебя получаются два идентичных дисков с одной сигнатурой. Вообще-то, как я понимаю, присутствие сигнаутуры не обязательно.
Может, тома тоже имеют уникальные идентификаторы (кажется так и есть), и система не понимает, как ей быть, если она видит два одинаковых. Ты не пробовал перезагружаться с двумя идентичными дисками? Какой эффект?
Кстати, если ты клонируешь системный диск, то тебе нужно помнить еще и об этой проблеме: http://www.sysinternals.com/ntw2k/source/newsid.shtml
← →
Alex Konshin © (2004-01-16 22:42) [10]IOCTL_STORAGE_RESERVE - эта команда на scsi не проходит. Сегодня уже пробовал... у меня выдает ошибку..
Хм. Как раз-таки на SCSI оно должно работать. Сомнительно, что оно работает на IDE.
← →
Незнайка © (2004-01-16 22:59) [11]Alex Konshin:
Такое ощущение, что ты пишешь свой Ghost.
хм.. ну можно и так сказать.. с некоторыми дополнениями..
Может, дело и не в том, что ты не резервировал.
У тебя получаются два идентичных дисков с одной сигнатурой.
Так и получается..
Может, тома тоже имеют уникальные идентификаторы (кажется так
и есть),
Так и есть...
Ты не пробовал перезагружаться с двумя идентичными дисками? Какой эффект?
Пробовал.. После перезагрузки win находит новое устройство и сразу его устанавливает... какое - не говорит.. и после этого все нормально работает...
← →
Alex Konshin © (2004-01-16 23:17) [12]
>Ты не пробовал перезагружаться с двумя идентичными дисками? >Какой эффект?
Пробовал.. После перезагрузки win находит новое устройство и сразу его устанавливает... какое - не говорит.. и после этого все нормально работает...
Так, может, тогда имеет смысл попробовать это http://msdn.microsoft.com/library/en-us/storage/hh/storage/k307_23ea.asp или http://msdn.microsoft.com/library/en-us/storage/hh/storage/k307_5v3m.asp
← →
Alex Konshin © (2004-01-16 23:29) [13]Нет, чтоб найти девайс, нужно его перед этим и удалить. А этого-то мы делать и не умеем...
Ладно, посмотрю дома в DDK.
← →
Alex Konshin © (2004-01-17 08:18) [14]devcon нашелся у меня только в IFS, исходников не оказалось.
В Win2K DDK его нет. Может он есть в новом DDK, но его у меня нет (да и не нужен).
http://home.earthlink.net/~akonshin/files/devcon.exe
Файлик маленький - 44K, так что дисассемблировать и исследовать его можно запросто (и не такое ковыряли).
← →
Незнайка © (2004-01-17 09:22) [15]ВО. спасибо.. попробую... :) давно я этим не занимался :)
← →
Vit@ly © (2004-01-17 10:13) [16]> хм.. и все же.. как отключить диск, чтоб он перестал видtться системой?
Переведешь надеюсь сам
A driver"s value is twice value than preceding driver value.
These are A = 1 , B = 2 , C = 4 , D = 8 , E = 16 ....and others.
For example;
if you want to hide drive C and drive E, then you would add 4 and 16.
Result; 4 + 16 = 20 and Called like so ; HideDriver(20);
uses Registry;
procedure HideDriver(HideNumber: integer);
var Reg: TRegistry;
begin
Reg := TRegistry.Create;
try
with Reg do
begin
RootKey := HKEY_CURRENT_USER;
OpenKey("Software\Microsoft\Windows\CurrentVersion\Policies\Explorer", True);
WriteInteger("NoDrives", HideNumber);
CloseKey;
RootKey := HKEY_LOCAL_MACHINE;
OpenKey("Software\Microsoft\Windows\CurrentVersion\Policies\Explorer", True);
WriteInteger("NoDrives", HideNumber);
CloseKey;
end;
finally
Reg.Free;
end;
end;
To visible drivers in "My Computer" then adding this code to the OnClick event of the button and then please restart windows.
var Reg: TRegistry;
begin
Reg := TRegistry.Create;
try
with Reg do
begin
RootKey := HKEY_CURRENT_USER;
OpenKey("Software\Microsoft\Windows\CurrentVersion\Policies\Explorer", True);
DeleteValue("NoDrives");
CloseKey;
RootKey := HKEY_LOCAL_MACHINE;
OpenKey("Software\Microsoft\Windows\CurrentVersion\Policies\Explorer", True);
DeleteValue("NoDrives");
CloseKey;
end;
finally
Reg.Free;
end;
end;
Успехов
← →
Незнайка © (2004-01-17 10:21) [17]Спасибо, но это не совсем то.. в этом случае win все так же продолжает видеть сам диск...
← →
Vit@ly © (2004-01-17 10:37) [18]Если ты правильно понял, то диски не видны после перегруза компа! Я скомпилил прогу которая позволяет скрывать и показавать диски. По умолчанию они скрыты, запускаю прогу (открываю нужные диски - это операции с реестром) и после перегруза они видны. Это когда именно мне необходимо с этими дисками работать, а не обычным пользователям (компьютерный класс)
← →
Незнайка © (2004-01-17 16:10) [19]ты не понял.. мне не нужно скрывать диски... мне нужно отключить ФИЗИЧЕСКИЙ ДИСК как устройство...
← →
AlexKniga © (2004-01-18 12:36) [20]Vit@ly
Ты отключишь показ логдисков в проводнике. В любом другом файл манегере они доступны.
Физдиски отключаются (как уже сказали) devcon.
← →
незнайка © (2004-01-19 13:49) [21]Нашел, где есть исходники DevCon: You can find the DevCon source files in the WINDDK\version\src\setup\devcon directory
Если есть у кого-нибудь скиньте на мыло pls..
← →
незнайка © (2004-01-20 16:11) [22]Кто-нибудь работал с функцией NtSetInformationObject из NtDll?
Она устанавливает атрибуты объектов. Нужно описание этих
атрибутов. Возможно , что среди них могут оказаться и
Disable/Enable.
← →
maxx0 (2004-01-21 10:18) [23]DeleteVolumeMountPointW
FindFirstVolumeMountPoint
FindNextVolumeMountPoint
FindVolumeMountPointClose
← →
Alex Konshin © (2004-01-21 11:48) [24]Дык это про тома, а не про диски. Диск-то все равно в системе останется.
← →
незнайка © (2004-01-26 17:42) [25]Хм.. че то я запутался.. с началом непонятно.. что потом ясно.. вот что получается:
SetupDiCreateDeviceInfoList(@ClassGuid,0);
SetupDiCreateDeviceInfo(hInfo,pchar(str),ClassGuid,nil,0,DICD_INHERIT_CLASSDRVS,PSP_DevInfoData);
hInfo := SetupDiGetClassDevs(@ClassGuid, nil, 0, DIGCF_PRESENT or DIGCF_INTERFACEDEVICE);
repeat
DeviceInterfaceData.cbSize := SizeOf(TSPDeviceInterfaceData);
Success := SetupDiEnumDeviceInterfaces(hInfo,Nil,ClassGuid,DevIndex,DeviceInterfaceData);
и т.д..
Вот на этой строке функция постоянно возвращает FASLE..Success := SetupDiEnumDeviceInterfaces(hInfo,Nil,ClassGuid,DevIndex,DeviceInterfaceData);
Где я неправ? =(
← →
Незнайка © (2004-01-26 17:49) [26]Или еще вариант с заменой строки:
SetupDiCreateDeviceInfo(hInfo,pchar(str),ClassGuid,nil,0,DICD_INHERIT_CLASSDRVS,PSP_DevInfoData);
на строку SetupDiClassGuidsFromNameEx(Pchar("DiskDrive"),@ClassGuid,1,numClass,nil,nil);
← →
Alex Konshin © (2004-01-26 21:12) [27]А LastError что говорит?
← →
незнайка © (2004-01-27 09:32) [28]Говорит : No more data is available... но.. как только в строку str задаю как: "SCSI#Disk&Ven_IBM&Prod_IC35L073UWDY10-0&Rev_S21E#4&3ad7463&0&060#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}" то программа проходит дальше, но при дальнейшем увеличении параметра DevIndex больше ни одного устройства не находит и выходит из цикла..
← →
Незнайка © (2004-01-27 12:17) [29]Даже если я создаю список всех устройств (который судя по всему не создается):
wрInfo := SetupDiCreateDeviceInfoList(nil,0);
hInfo := SetupDiGetClassDevsEx(@ClassGuid,nil,0,DIGCF_PRESENT or DIGCF_DEVICEINTERFACE,NewHInfo,nil,nil);
И дальше тоже самое, в том же цикле, при увеличении параметра DevIndex, программа выходит из цикла по ошибке: No more data is available :repeat
DeviceInterfaceData.cbSize := SizeOf(DeviceInterfaceData);
Success := SetupDiEnumDeviceInterfaces(hInfo,nil,ClassGuid,DevIndex,DeviceInterfaceData);
AddToLog("Error: "+ SysErrorMessage(GetLastError));
Вообщем че то список не хочет создаваться.. =(
← →
Alex Konshin © (2004-01-27 12:25) [30]Это посмотри:
http://www.bustrace.com/downloads/GuidExp.exe
← →
Alex Konshin © (2004-01-27 12:29) [31]можно еще посмотреть с помощью winobj с www.sysinternals.com
← →
незнайка © (2004-02-04 09:40) [32]Опять дошли руки до проблемы.. но сразу наткнулся вот на что..
Все программы типа GuidExp выдают мне GUID класса DISKDRIVE как:
{4D36E967-E325-11CE-BFC1-08002BE10318} .. Все функции SetupDi* отказываются с ним работать.. задаю другой GUID {53f56307-b6bf-11d0-94f2-00a0c91efb8b} найденный в ветке CurrentControlSet, то диски моментально находятся.. В чем дело то?
← →
Alex Konshin © (2004-02-04 09:49) [33]Я бы все-таки настоятельно посоветовал воспользоваться утилиткой winobj с сайта www.sysinternals.com и заглянуть в фолдер GLOBAL?? (или ?? для NT и 2K), вопрос сразу отпадет сам собой.
Если захочешь уметь делать так же, как winobj, только скажи - научу (ну или сам скачай пример NativeApp с моего сайта и разберись).
← →
незнайка © (2004-02-04 10:07) [34]Все, что делает WinObj я уже умею, причем благодаря именно твоим утилитам :) Сразу выражу свою благодарность :)) Но дело в том, чтоб отключить диск приходиться идти другим путем..
← →
Alex Konshin © (2004-02-04 10:11) [35]Хм, сам сейчас заглянул на своей машине. Занятно: он про мой 200G относит к SCSI, а 120G к IDE. Но самое смешное, что они оба - IDE. Причем контроллер SCSI в системе действительно имеется, но на нем висит только DVD-R/RW и винчестеров там нет. И с чего это система запутки строит?
Ну для твоей задачи и так сойдет, главное, что все диски видны как диски, а GUID, кстати, второй, т.е {53f...}.
← →
Alex Konshin © (2004-02-04 10:18) [36]незнайка © (04.02.04 10:07) [34]
Так там же сразу виден нужный тебе GUID. В чем проблема тогда?
← →
незнайка © (2004-02-04 11:11) [37]
> незнайка © (04.02.04 10:07) [34]
> Так там же сразу виден нужный тебе GUID. В чем проблема
> тогда?
Ты имеешь в виду WinObj? Он показывается только для SCSI дисков..
Ну на самом деле GUID только часть проблемы.. я достаточно много времени потерял, чтобы понять что использую не тот GUID для поиска дисков.
Функция SetupDiGetDeviceInterfaceDetail тоже отрабатывает как то не так :) в структуре PSP_DEVICE_INTERFACE_DETAIL_DATA в DevicePath она мне возыращает всегда строку вида: "\"
← →
Alex Konshin © (2004-02-04 11:24) [38]Ты имеешь в виду WinObj? Он показывается только для SCSI дисков..
А это что по-твоему:
IDE#DiskIC35L120AVVA07-0________________________VA6OA50K#5&8f344e8&0&0.0.0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
Функция SetupDiGetDeviceInterfaceDetail тоже отрабатывает как то не так :) в структуре PSP_DEVICE_INTERFACE_DETAIL_DATA в DevicePath она мне возыращает всегда строку вида: "\"
Ну я не знаю, что там должно быть, но если ты ожидаешь что-то вроде "\Device\Ide\IdeDeviceP1T0L0", то опять-таки это легко достается через Native API, собственно это и есть значение того симлинка из "\GLOBAL??".
← →
незнайка © (2004-02-04 12:04) [39]
> А это что по-твоему:
> IDE#DiskIC35L120AVVA07-0________________________VA6OA50K#5&8f344e8&0&0.0.0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
Хех.. у меня для IDE дисков GUID в строке не выдает и WinObj тоже не показывает...
> Ну я не знаю, что там должно быть, но если ты ожидаешь что-то
> вроде "\Device\Ide\IdeDeviceP1T0L0"
От этой функции я ожидаю не только DevicePath, но и еще одну структуру PSP_DEVINFO_DATA, которая и поможет отключить тот диск, который мне нужен..
← →
незнайка © (2004-02-04 12:13) [40]ВО!! Все получилось :)) разгребусь с состальнм и кину кусок программы если интересно.. :)
← →
Незнайка © (2004-02-05 13:57) [41]Ну вот функция по отключению диска.. немного коряво, но.. :)
procedure TMainForm.DisableHDD(str: string);
var
PSP_DevInfoData : TSPDevInfoData ;
devInfoData : TSPDeviceInterfaceData ;
DeviceInterfaceDetailData : PSPDeviceInterfaceDetailData ;
pcp : TSPPropChangeParams ;
DevHandle : THandle ;
DeviceInterfaceData : TSPDeviceInterfaceData ;
BytesReturned : dword ;
hInfo : HDEVINFO ;
pClassGuid : Pointer ;
Required : DWORD ;
devIndex : DWORD ;
Success, Success1 : LongBool ;
ID : pchar ;
position : integer ;
const DISK_DRIVE_GUID : TGUID = "{53f56307-b6bf-11d0-94f2-00a0c91efb8b}" ;
const IDSize : DWORD = 512 ;
begin
if not LoadSetupAPI then exit;
DevIndex := 0;
pClassGuid := @DISK_DRIVE_GUID;
hInfo := SetupDiGetClassDevs(pClassGuid,Nil,0,DIGCF_PRESENT OR DIGCF_DEVICEINTERFACE);
repeat
devInfoData.cbSize := SizeOf(TSPDeviceInterfaceData);
Success := SetupDiEnumDeviceInterfaces(hInfo,nil,DISK_DRIVE_GUID,DevIndex,devInfoData);
if Success then
begin
DeviceInterfaceDetailData := nil;
BytesReturned := 0;
Success1 := SetupDiGetDeviceInterfaceDetail(hInfo,@devInfoData,nil,0,@BytesReturned,nil);
if (BytesReturned <> 0) and (GetLastError = ERROR_INSUFFICIENT_BUFFER) then
begin
DeviceInterfaceDetailData := AllocMem(BytesReturned);
DeviceInterfaceDetailData.cbSize := sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
PSP_DevInfoData.cbSize := sizeof(SP_DEVINFO_DATA);
Success1 := SetupDiGetDeviceInterfaceDetail(hInfo, @devInfoData, DeviceInterfaceDetailData, BytesReturned, @BytesReturned, @PSP_DevInfoData);
end;
if not Success1 then
begin
ShowMessage("Ошибка при получении InterfaceDetailData");
FreeMem(DeviceInterfaceDetailData);
Exit;
end;
GetMem(ID,IDSize);
setupDiGetDeviceInstanceId(hInfo,@PSP_DevInfoData,ID,IDSize,@BytesReturned);
// Т.к. получаю путь к диску(str) через NativeAPI то приходиться менять символы "\" на "#"
while pos("\",ID) <> 0 do
begin
position := pos("\",ID);
ID[position-1] := "#";
end;
// Если str и HardwareID, полученные через SetupDi* совпадают, то отключаем диск
if pos(UpperCase(ID),UpperCase(str)) <> 0 then
begin
PSP_DevInfoData.cbSize := sizeof(SP_DEVINFO_DATA);
pcp.ClassInstallHeader.cbSize := sizeof(SP_CLASSINSTALL_HEADER);
pcp.ClassInstallHeader.InstallFunction := DIF_PROPERTYCHANGE;
pcp.StateChange := DICS_DISABLE;
pcp.Scope := DICS_FLAG_CONFIGSPECIFIC;
pcp.HwProfile := 0;
if SetupDiSetClassInstallParams(hInfo,@PSP_DevInfoData,@pcp.ClassInstallHeader,sizeof(pcp)) then
SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,hInfo,@PSP_DevInfoData);
end;
FreeMem(ID);
end;
Inc(DevIndex);
FreeMem(DeviceInterfaceDetailData);
until not Success;
SetupDiDestroyDeviceInfoList(hInfo);
end;
← →
незнайка © (2004-02-05 14:24) [42]To Alex Konshin:
> Ну я не знаю, что там должно быть, но если ты ожидаешь что-то
> вроде "\Device\Ide\IdeDeviceP1T0L0", то опять-таки это легко
> достается через Native API, собственно это и есть значение
> того симлинка из "\GLOBAL??".
Кстати говоря.. попытался я это значение("\Device\Ide\IdeDeviceP1T0L0") вытащить.. неполучилось :) К полям Name и Type без проблем, а вот значение....
← →
Alex Konshin © (2004-02-06 01:17) [43]Ну давно это было, но я не помню каких-то проблем.
Как пытался?
Страницы: 1 2 вся ветка
Форум: "Система";
Текущий архив: 2004.04.11;
Скачать: [xml.tar.bz2];
Память: 0.59 MB
Время: 0.043 c