Обработка подключения и отключения съемного накопителя
С расширением рынка переносных устройств и USB-накопителей становится актуальной задача по обработке их взаимодействия с компьютером. Сегодня разберем обработку подключения и отключения съемных накопителей, таких как Flash-диски, карты памяти и USB-диски. Начинаем с теории. При подключении или отключении съемного накопителя система посылает всем окнам (через глобальный хэндл HWND_BROADCAST) сообщение WM_DEVICECHANGE. Но это сообщение всего лишь о самом факте изменения состояния съемного накопителя, а более подробные значения содержатся в параметрах lParam и wParam этого сообщения. В wParam приходит расшифровка произошедшего события: подключение, отключение, изменения состояния, отмена отключения и т.п. Нас пока интересует только два: DBT_DEVICEARRIVAL - подключение сменного накопителя и DBT_DEVICEREMOVECOMPLETE - извлечение накопителя. Основной обработчик событий приложения ничем не отличается от обычных обработчиков. Нам также понадобятся несколько констант, которые по умолчанию не определены в FASM:Code (Assembler) : Убрать нумерацию
- DBT_DEVICEARRIVAL = 0x8000
- DBT_DEVICEREMOVECOMPLETE = 0x8004
- DBT_DEVTYP_VOLUME = 0x00000002
Code (Assembler) : Убрать нумерацию
- proc DialogProc hwnddlg,msg,wparam,lparam
- push ebx esi edi
- ...
- ; Пришло сообщение об изменении состояния съемного накопителя
- cmp [msg],WM_DEVICECHANGE
- je update_usb
- ...
- update_usb:
- ; Устройство подключено?
- cmp [wparam],DBT_DEVICEARRIVAL
- je usb_connected
- ; Устройство извлечено?
- cmp [wparam],DBT_DEVICEREMOVECOMPLETE
- je usb_disconnected
- jmp processed
- usb_connected:
- ; Обработка подключения устройства
- ...
- jmp processed
- usb_disconnected:
- ; Обработка отключения устройства
- ...
- jmp processed
- ...
- processed:
- mov eax,1
- finish:
- pop edi esi ebx
- ret
- endp
Структура состоит из двух частей: заголовка и информационной части. В заголовке содержится общая информация, а информационная часть может различаться в зависимости от типа устройства, на котором произошло событие. Для съемных дисков она будет следующая:
Code (Assembler) : Убрать нумерацию
- struct DEV_BROADCAST
- ; Заголовок структуры
- dbch_size dd ?
- dbch_devicetype dd ?
- dbch_reserved dd ?
- ; Информационная часть структуры
- dbcv_unitmask dd ?
- dbcv_flags dd ?
- ends
Чтобы узнать букву диска, которую система присвоила съемному носителю, надо разобрать значение dbcv_unitmask из информационной части структуры. Это битовая маска, где каждый отдельный бит соответствует определенной букве: бит 0 соответствует диску A, бит 1 - диску B, бит 2 - диску C и так далее. Я нашел несколько вариантов преобразования такой маски в человеко-понятную букву, но решил сделать свой, обойдясь двумя ассемблерными командами:
Code (Assembler) : Убрать нумерацию
- ; Получить букву диска из битовой маски (маска в регистре EAX)
- bsr eax,eax
- ; В регистре AL буква диска
- add al,'A'
В приложении пример программы, записывающей в свой лог все сообщения о подключении и отключении съемных носителей с указанием букв дисков.
Просмотров: 7224 | Комментариев: 19
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
ManHunter
(04.05.2016 в 12:11):
Да мне и спасибо достаточно :) Рад, что пригодилось.
вадя
(03.05.2016 в 01:47):
спасибо очень помогло перепрограммировали свой вейп спасибо еще раз как скинуть вам на пиво
X
(07.02.2013 в 19:20):
Спасибо. Буду разбираться.
ManHunter
(07.02.2013 в 19:00):
Потрудись хотя бы открыть приведенную ссылку и внимательно там все прочитать.
1. RegisterClassEx -> WNDCLASSEX -> lpfnWndProc
2. CreateWindowEx с зарегистрированным классом
1. RegisterClassEx -> WNDCLASSEX -> lpfnWndProc
2. CreateWindowEx с зарегистрированным классом
X
(07.02.2013 в 18:48):
В примере программы создается модальное окно с помощью DialogBoxParam и ведется обработка всех сообщений в DialogProc функции. Если использовать CreateWindowEx для создания невидимого окна, то как указать функцию для обработки сообщений?
ManHunter
(07.02.2013 в 18:45):
CreateWindowEx в MSDN
X
(07.02.2013 в 18:42):
Где посмотреть пример создания невидимого окна-перехватчика на FASMe?
ManHunter
(07.02.2013 в 18:36):
А что мешает консольной программе создать невидимое окно-перехватчик (Message-Only Window), как это делают все нормальные приложения?
http://msdn.microsoft.com/en-u...message_only
http://msdn.microsoft.com/en-u...message_only
X
(07.02.2013 в 18:34):
Возможно ли осуществить обработку подключения/отключения съемного накопителя в консольном приложении без создания окна?
Евлампий
(26.09.2011 в 19:39):
респект
спс за инфу
спс за инфу
zummenix
(18.04.2011 в 17:18):
:) Насчет
bsr eax,eax
add al,'A'
Красивое и элегантное решение, мне нравится!
bsr eax,eax
add al,'A'
Красивое и элегантное решение, мне нравится!
ManHunter
(18.04.2011 в 16:47):
zummenix, http://lurkmore.ru/%D0%9D%D0%95%D0%A5 детектед :)
zummenix
(18.04.2011 в 16:46):
Странно, сегодня у меня тоже нормально работает.
ManHunter
(18.04.2011 в 11:09):
Проверил на чистой WinXP, тоже все прекрасно появляется.
ManHunter
(17.04.2011 в 16:06):
Я проверял на Win7 - появляется. Завтра на работе проверю на WinXP.
zummenix
(17.04.2011 в 15:50):
Видимо нужно возвращать 0 после обработки usb_connected, иначе не появляется безопасное извлечение устройства в трее.
ManHunter
(17.04.2011 в 11:26):
На PHP решение заняло бы пару мегабайт, на JavaScript и SQL такие задачи не решаются, а на других языках я не пишу. А вообще толсто :)
Gideon Vi
(17.04.2011 в 07:47):
Пардон, а асм в решении подобных задач - реальная необходимость или разминка для извилин?
Добавить комментарий
Заполните форму для добавления комментария
invoke CreateWindowEx, 0,_class,0,0,0,0,0,0,HWND_MESSAGE,0,0,0
а вот так работает
invoke CreateWindowEx, 0,_class,0,0,0,0,0,0,0,0,0,0
в msdn написано A message-only window ... does not receive broadcast messages
https://msdn.microsoft.com/en-...message_only