Delphi: Работа с устройствами в Windows - Безопасное извлечение устройства
ОГЛАВЛЕНИЕ
Безопасное извлечение устройства
Итак, с включением/отключением устройств мы разобрались. А как безопасно извлекать устройство? Безопасное извлечение устройства осуществляет функция CM_Request_Device_Eject. Вот её описание:
CMAPI CONFIGRET WINAPI
CM_Request_Device_Eject(
IN DEVINST dnDevInst,
OUT PPNP_VETO_TYPE pVetoType,
OUT LPTSTR pszVetoName,
IN ULONG ulNameLength,
IN ULONG ulFlags
);
Первый параметр это хендл устройства. Второй параметр это указатель на переменную, в которую будет сохранён код причины при неудаче. Третий параметр это указатель на строку, в которую будет сохранена причина неудачи при неудачном вызове. Оба этих параметра опциональны и могут быть равны нулю. Пятый параметр это максимальная длина строки. Шестой не используется. Если pszVetoName равен нулю, то при неудаче сообщение выведет сама система. Вот и сама функция, которая осуществляет безопасное извлечение устройства.
procedure RemoveDrive(index:integer);
var
DrivesPnPHandle: HDEVINFO;
DevInfo: SP_DEVINFO_DATA;
i: Integer;
Parent: DWORD;
VetoName:array[0..MAX_PATH] of char;
begin
DevInfo.cbSize := sizeof(SP_DEVINFO_DATA);
DrivesPnPHandle := SetupDiGetClassDevsA(@GUID_DEVCLASS_DISKDRIVE, nil, 0, 2);
if DrivesPnPHandle = INVALID_HANDLE_VALUE then exit;
if SetupDiEnumDeviceInfo(DrivesPnPHandle, index, DevInfo) then
begin
if (IsUSBDevice(DevInfo.DevInst)) and (CM_Get_Parent(Parent, DevInfo.DevInst, 0) = CR_SUCCESS)
then
begin
CM_Request_Device_Eject(Parent, nil, @VetoName, MAX_PATH, 0);
if VetoName=” then
ShowMessage(’устройство можно извлечь’)
else
ShowMessage(’устройство нельзя извлечь’);
end
else
ShowMessage(’Не USB устройство’);
end;
SetupDiDestroyDeviceInfoList(DrivesPnPHandle);
end;
Единственный параметр передаваемой функции это индекс дискового устройства в списке дисковых устройств. Единственное что модет быть здесь непонятно - это функция CM_Get_Parent. Она получает родитель устройства. Ведь любая «флешка» или внешний дисковый накопитель это составное устройство и отключать надо именно родительское устройство. Код функции IsUSBDevice есть в исходнике, который прилагается к статье.