Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Как отловить подключение съемного носителя


Автор: WolfAlone 25.1.2010, 12:20
Здравствуйте! Собственно сабж! Интересует вопрос, как отловить событие подключение CD/DVD, "флэшек" и пр. съемных носителей к системе на Windows XP/Vista.

P.S. Аналогичные действия проводит антивирус Касперского, при вставке "флэшки" - появляется окно, с надписью типа "Обнаружен съёмный диск"

Автор: WolfAlone 25.1.2010, 12:37
Перелопатил гору информации, но так и нигде не нашёл внятного объяснения что к чему... Вариант исходника на 1000+ строк кода, без комментариев, который ещё к тому же и не компилируется - меня в корне не устроил! Подскажите пожалуйста, кто знает толковую информацию по этому поводу, в которой было бы всё подробно расписано!

Автор: kami 25.1.2010, 14:02
Имхо, начать надо с этого: http://msdn.microsoft.com/en-us/library/aa363431(VS.85).aspx
Вполне возможно, уже есть готовые компоненты/классы...

Автор: WolfAlone 25.1.2010, 14:13
Может быть кто-нибудь обладает уже готовым модулем для перехвата события подключения "флэшки" в ПК? (USB)

Автор: WolfAlone 25.1.2010, 16:50
Почитал про "RegisterDeviceNotification", почитал про "WM_DEVICECHANGE"... Скажите пожалуйста, может кто-нибудь встречал подробное описание этих функций на русском языке?

Автор: transserg 25.1.2010, 17:24
WolfAlone в аттаче проект с примером в мемо выводи букву подключенного диска=)

Автор: WolfAlone 25.1.2010, 18:06
Уважаемый transserg, спасибо огромное! Получил именно то, что нужно. Реагирует даже на воткнутые диски, это очень хорошо!

Теперь остался последний вопрос, по поводу того, как бы почитать внятную документацию на родном языке что куда и к чему в этом исходнике  smile ...

Автор: transserg 25.1.2010, 18:17
WolfAlone все где я это иска это DRKB и MSDN+Translate.google.ru а вообще в сообщении WM_DEVICECHANGE

WParam это константа например DBT_DEVICEARRIVAL что говорит о том что было подключено новое устройство а в lParam содержится указатель на сруктуру в нашем случае это http://msdn.microsoft.com/en-us/library/aa363249(VS.85).aspx 
Код

typedef struct _DEV_BROADCAST_VOLUME {
  DWORD dbcv_size; // РАзмер структуры 
  DWORD dbcv_devicetype; // Тип устройства 
  DWORD dbcv_reserved; // зарезервированный параметр
  DWORD dbcv_unitmask; // маска устройства первый бит биск А второй бит диск В третий бит Диск С и так далее
  WORD  dbcv_flags; // как я понял показывает какой диск сетевой или локальный подключили
} DEV_BROADCAST_VOLUME, *PDEV_BROADCAST_VOLUME;


Автор: kami 26.1.2010, 00:19
Цитата(WolfAlone @  25.1.2010,  18:06 Найти цитируемый пост)
почитать внятную документацию на родном языке

Я прошу прощения за  smile , но родной язык для программиста под Windows - тот, на котором написан MSDN (native).  smile 

Автор: Keeper89 26.1.2010, 02:09
Я уже сам http://forum.vingrad.ru/forum/topic-276108/unread-1/kw-devicechange-usb.html заводил эту тему smile

Автор: ~FoX~ 26.1.2010, 09:20
WM_DEVICE_CHANGE, дома есть рабочий пример, есле еще будет актуально скину код в тему поле 18.00 по московскому времени 

Автор: WolfAlone 26.1.2010, 11:51
Уважаемый ~FoX~ буду признателен за любые примеры и помощь. Можно в принципе по мимо дельфи примеры на С++, не суть smile

Автор: ~FoX~ 26.1.2010, 18:01
Вот, как и обещал, рабочий код, ловит все и флешки и сд и даже подключение сетевого драйва...
Код

//...............
 private
     procedure WMDeviceChange(var Msg: TMessage); message WM_DeviceChange;
//...............
const
   DBT_DeviceArrival = $8000;
   DBT_DeviceRemoveComplete = $8004;

type
   PDevBroadcastVolume = ^TDevBroadcastVolume; //Если честно не помню точно, но помоему эта структура описана не полностью...
   TDevBroadcastVolume = packed record
     dbcv_size: DWORD;
     dbcv_devicetype: DWORD;
     dbcv_reserved: DWORD;
     dbcv_unitmask: DWORD;
     dbcv_flags: Word;
   end;
   function GetDrive(pDBVol: PDevBroadcastVolume): string;

//...............
function GetDrive(pDBVol: PDevBroadcastVolume): string; //Получаем букву драйва из структуры PDevBroadcastVolume
var
  i: Byte;
  Maske: DWORD;
begin
  Maske := pDBVol^.dbcv_unitmask;
  for i := 0 to 25 do begin
    if (Maske and 1) = 1 then Result := Char(i + Ord('A')) + ':';
    Maske := Maske shr 1;
  end;
end;


procedure TForm1.WMDeviceChange(var Msg: TMessage); //собственно ловим инсерт/еджект драйвов
var
  Drive: string;
begin
  Application.ProcessMessages;
  if Msg.wParam = DBT_DeviceArrival then begin //если засунули
    Drive := GetDrive(PDevBroadcastVolume(Msg.lParam));
     ShowMessage(Drive);
  end
  else if  Msg.wParam = DBT_DeviceRemoveComplete then begin //если выдернули
    Drive := GetDrive(PDevBroadcastVolume(Msg.lParam));
    ShowMessage(Drive);
  end;
end;


Автор: WolfAlone 26.1.2010, 18:22
Спасибо всем огромное! Разобрался чуть по чуть, задно подтянул знания WinAPI.

Как выяснилось, в константах со значениями типа "$8000" в принципе нет необходимости, это скорее удобство. А в С++ как оказалось, даже есть заголовочный файл со всеми этими константами...  smile 

Осталось ещё чуть покумекать, глядишь ещё чуть поумнею  smile 

Автор: ~FoX~ 26.1.2010, 18:35
Цитата(WolfAlone @  26.1.2010,  19:22 Найти цитируемый пост)
Как выяснилось, в константах со значениями типа "$8000" в принципе нет необходимости

В принципе во всех константах нету необходимости  smile  smile  

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)