![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Enable disk / Disable disk в Device Manager. HELP!! [D7, WinXP]
незнайка © (2004-01-16 12:05:00)В Device Manager есть функция Enable/Disable, которую можно применить к разным устройствам и дискам. Диски и интересуют. Как программным путем можно отключить диск (аналог mount/Unmount в юниксе)
Alex Konshin (2004-02-06 01:17:00) [1]Ну давно это было, но я не помню каких-то проблем.
Как пытался?
незнайка (2004-02-05 14:24:00) [2]To Alex Konshin:
> Ну я не знаю, что там должно быть, но если ты ожидаешь что-то
> вроде '\Device\Ide\IdeDeviceP1T0L0', то опять-таки это легко
> достается через Native API, собственно это и есть значение
> того симлинка из '\GLOBAL??'.
Кстати говоря.. попытался я это значение('\Device\Ide\IdeDeviceP1T0L0') вытащить.. неполучилось :) К полям Name и Type без проблем, а вот значение....
Незнайка (2004-02-05 13:57:00) [3]Ну вот функция по отключению диска.. немного коряво, но.. :)
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-04 12:13:00) [4]ВО!! Все получилось :))разгребусь с состальнм и кину кусок программы если интересно.. :)
незнайка (2004-02-04 12:04:00) [5]
> А это что по-твоему:
> 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, которая и поможет отключить тот диск, который мне нужен..
Alex Konshin (2004-02-04 11:24:00) [6]Ты имеешь в виду 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 11:11:00) [7]
> незнайка © (04.02.04 10:07) [34]
> Так там же сразу виден нужный тебе GUID. В чем проблема
> тогда?
Ты имеешь в виду WinObj? Он показывается только для SCSI дисков..
Ну на самом деле GUID только часть проблемы.. я достаточно много времени потерял, чтобы понять что использую не тот GUID для поиска дисков.
Функция SetupDiGetDeviceInterfaceDetailтоже отрабатывает как то не так :) в структуре PSP_DEVICE_INTERFACE_DETAIL_DATA в DevicePath она мне возыращает всегда строку вида: '\'
Alex Konshin (2004-02-04 10:18:00) [8]незнайка © (04.02.04 10:07) [34]
Так там же сразу виден нужный тебе GUID. В чем проблема тогда?
Alex Konshin (2004-02-04 10:11:00) [9]Хм, сам сейчас заглянул на своей машине. Занятно: он про мой 200G относит к SCSI, а 120G к IDE. Но самое смешное, что они оба - IDE. Причем контроллер SCSI в системе действительно имеется, но на нем висит только DVD-R/RW и винчестеров там нет. И с чего это система запутки строит?
Ну для твоей задачи и так сойдет, главное, что все диски видны как диски, а GUID, кстати, второй, т.е {53f...}.
незнайка (2004-02-04 10:07:00) [10]Все, что делает WinObj я уже умею, причем благодаря именно твоим утилитам :) Сразу выражу свою благодарность :)) Но дело в том, чтоб отключить диск приходиться идти другим путем..
Alex Konshin (2004-02-04 09:49:00) [11]Я бы все-таки настоятельно посоветовал воспользоваться утилиткой winobj с сайта www.sysinternals.com и заглянуть в фолдер GLOBAL?? (или ?? для NT и 2K), вопрос сразу отпадет сам собой.
Если захочешь уметь делать так же, как winobj, только скажи - научу (ну или сам скачай пример NativeApp с моего сайта и разберись).
незнайка (2004-02-04 09:40:00) [12]Опять дошли руки до проблемы.. но сразу наткнулся вот на что..
Все программы типа GuidExp выдают мне GUID класса DISKDRIVE как:
{4D36E967-E325-11CE-BFC1-08002BE10318}.. Все функции SetupDi* отказываются с ним работать.. задаю другой GUID {53f56307-b6bf-11d0-94f2-00a0c91efb8b}найденный в ветке CurrentControlSet, то диски моментально находятся.. В чем дело то?
Alex Konshin (2004-01-27 12:29:00) [13]можно еще посмотреть с помощью winobj с www.sysinternals.com
Alex Konshin (2004-01-27 12:25:00) [14]Это посмотри:
http://www.bustrace.com/downloads/GuidExp.exe
Незнайка (2004-01-27 12:17:00) [15]Даже если я создаю список всех устройств (который судя по всему не создается):
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));
Вообщем че то список не хочет создаваться.. =(
незнайка (2004-01-27 09:32:00) [16]Говорит : 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больше ни одного устройства не находит и выходит из цикла..
Alex Konshin (2004-01-26 21:12:00) [17]А LastError что говорит?
Незнайка (2004-01-26 17:49:00) [18]Или еще вариант с заменой строки:
SetupDiCreateDeviceInfo(hInfo,pchar(str),ClassGuid,nil,0,DICD_INHERIT_CLASSDRVS,PSP_DevInfoData);
на строку SetupDiClassGuidsFromNameEx(Pchar('DiskDrive'),@ClassGuid,1,numClass,nil,nil);
незнайка (2004-01-26 17:42:00) [19]Хм.. че то я запутался.. с началом непонятно.. что потом ясно.. вот что получается:
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);Где я неправ? =(
Alex Konshin (2004-01-21 11:48:00) [20]Дык это про тома, а не про диски. Диск-то все равно в системе останется.