Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.65/68: Рейтинг темы: голосов - 68, средняя оценка - 4.65
12 / 11 / 2
Регистрация: 03.04.2016
Сообщений: 502

Грабли с WM_DEVICECHANGE

03.10.2016, 22:16. Показов 15757. Ответов 63

Студворк — интернет-сервис помощи студентам
Потратил кучу времени на изучение структур связанных с WM_DEVICECHANGE. Все работает как надо wParam == DBT_DEVICEARRIVAL , отлавливает сообщение о новом диске, lParam передает информацию о букве и т д. Но WM_DEVICECHANGE ловит сообщения только о монтировании нового диска! Но если есть встроенный картридер и пользователь вставляет в него карточку, то сообщение не приходит, так как диск уже смонтирован, а наличие карты не проверяется! На форумах самый умный совет - повесить таймер на картридер. Получаем грабли, зачем все эти манипуляции, если можно таймер повесить изначально на GetVolumeInformation? Получается в результате функция не полноценна так как пользователь может обойти любые ограничения, просто вставив карту в картридер. Что делать то ??
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
03.10.2016, 22:16
Ответы с готовыми решениями:

WM_DEVICECHANGE
Здравствуйте, при подключении или отключении usb устройства сообщение "WM_DEVICECHANGE" приходить несколько раз: Remove - ...

WinAPI C++ WM_DEVICECHANGE
Вообщем цель определить любое воткнутое USB устройство. Выбрал WIN API поскольку жрет мало ресурсов, выбрал С++ потому что он не тащит за...

Перехват wm_devicechange
Здравствуйте написал простенькую программку по отлову сообщений вставки usb носителей. Собственно данный код отлавливает события.Приходит и...

63
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
09.10.2016, 17:58
Студворк — интернет-сервис помощи студентам
Любопытно. То есть, в системе появляется новый том (диск E, например),
изменяется конфигурация оборудования (должна быть новая запись в разделе
оборудования "тома запоминающих устройств" и у mount manager-а), но
при этом WM_DEVICECHANGE не приходит вообще?
0
12 / 11 / 2
Регистрация: 03.04.2016
Сообщений: 502
09.10.2016, 18:07  [ТС]
Убежденный, Вот смотрите. Я беру съемный USB картридер, в нем три слота под карты. Вставляю его в комп. Мне приходит три сообщения от WM_DEVICECHANGE, о монтировании новых дисков в системе. Если после этого вставить sd карту в него, то сообщения не приходят, так как диски уже есть в системе, не происходит монтирования новых дисков !
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
09.10.2016, 19:04
Цитата Сообщение от zombivadim Посмотреть сообщение
Мне приходит три сообщения от WM_DEVICECHANGE, о монтировании новых дисков в системе.
И сами диски в этот момент уже появляются в системе?
Я имею в виду тома (volumes) с буквами, т.е. E:, F:, G: и т.д.

Если да, то что будет, если зайти из проводника на один из таких дисков?
0
12 / 11 / 2
Регистрация: 03.04.2016
Сообщений: 502
09.10.2016, 20:20  [ТС]
Цитата Сообщение от Убежденный Посмотреть сообщение
И сами диски в этот момент уже появляются в системе?
Ну конечно диски появляются в системе, появляется в моем случае три новых диска, зайти на них нельзя ,при попытке пишет (вставьте диск
в устройство "Съемный диск L:")

Добавлено через 18 минут
Если конечно вставить карточку, то зайти можно)

Добавлено через 4 минуты
Цитата Сообщение от Убежденный Посмотреть сообщение
На некоторых форумах советуют кроме WM_DEVICECHANGE пробовать вот это:
SHChangeNotifyRegister function
https://msdn.microsoft.com/en-... s.85).aspx
Это совершенно новая для меня функция, примеров по ней крайне мало. Действительно на одном форуме пользователь пишет что решил проблему с ее помощью, однако никаких решений не приводит. Как ее прикрутить к данному примеру?Я думаю
если вы не поможете, то вопрос этот так и не решится никогда.
0
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18035 / 7738 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
09.10.2016, 22:51
Я спрашивал у автора USBDLM. В его программе подключение флеш к кард-ридеру детектируется.
Он мне ответил, что:

WM_DEVICECHANGE + DBT_DEVICEARRIVAL and
db_hdr->dbch_devicetype == DBT_DEVTYP_VOLUME should come
for any drive with a drive letter. But no drive letter, no message.

To receive a notification for any volume, even without a
drive letter you have to go for custom notification
(RegisterDeviceNotification with GUID_DEVINTERFACE_VOLUME).
Here is an example:
http://www.codeproject.com/Art... fid=317355

In the notification you get the device path of the volume.
Then get the mountpoints by means of GetVolumePathNamesForVolumeName.
Я попробовал добавить:
C++
1
Flt.dbcc_classguid = GUID_DEVINTERFACE_VOLUME;
Но что-то все равно не генерирует сообщение. Наверное, я что-нибудь не учёл.
0
12 / 11 / 2
Регистрация: 03.04.2016
Сообщений: 502
09.10.2016, 23:23  [ТС]
Dragokas, Ого два лучших специалиста в теме, возможно решение найдется таки!!
Еще раз отмечу, что касперский не предлагает проверить карту , если она вставлена в встроенный картридер или в USB картридер, после его инициализации. Значит там решения не нашли.
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
09.10.2016, 23:26
Попробовал SHChangeNotifyRegister, но толку от нее не много.
Для других устройств, например CD-ROM, все ок, приходят сообщения
SHCNE_MEDIAINSERTED и SHCNE_MEDIAREMOVED, но для SD-карты
нет, только SHCNE_DRIVEADD и SHCNE_DRIVEREMOVED.
0
 Аватар для prokl9tiy
21 / 21 / 9
Регистрация: 09.10.2016
Сообщений: 113
09.10.2016, 23:41
Цитата Сообщение от zombivadim Посмотреть сообщение
Ну конечно диски появляются в системе
а проверять не пробовал на готовность
C++
1
2
GetVolumeInformation(L"E:", 0, 0, 0, 0, 0, 0, 0);
    if (!GetLastError() == 21) // work with card
0
12 / 11 / 2
Регистрация: 03.04.2016
Сообщений: 502
09.10.2016, 23:43  [ТС]
Цитата Сообщение от Dragokas Посмотреть сообщение
Я спрашивал у автора USBDLM
Скачал программу , реально работает, чудеса какие то.
0
 Аватар для prokl9tiy
21 / 21 / 9
Регистрация: 09.10.2016
Сообщений: 113
09.10.2016, 23:47
Цитата Сообщение от prokl9tiy Посмотреть сообщение
GetVolumeInformation(L"E:", 0, 0, 0, 0, 0, 0, 0)
не дописались 2 обратных слеша после E:, если что
0
12 / 11 / 2
Регистрация: 03.04.2016
Сообщений: 502
09.10.2016, 23:47  [ТС]
prokl9tiy, Конечно я знаю как их проверить на готовность причем здесь это вообще? Мне надо получить от них уведомление!
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
09.10.2016, 23:48
Цитата Сообщение от zombivadim Посмотреть сообщение
Скачал программу , реально работает, чудеса какие то.
Скорее всего, там что-то типа этого:

повесить таймер на картридер
0
12 / 11 / 2
Регистрация: 03.04.2016
Сообщений: 502
09.10.2016, 23:56  [ТС]
Убежденный, Незнаю, вот последнее что я смог найти, автор пишет на делфи
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
Регистрируем уведомление типа DBT_DEVTYP_HANDLE.
Функция возвращает хэндл зарегистрированного уведомления. Сравнив потом с этими хэндлами для каждого диска, хэндл полученный в сообщении можно определить, какой диск их присл
 
function RegNotif( Wnd: HWND; DriveChar: Char; 
                   var Fltr: TDevBroadcastHandle): HDEVNOTIFY;
var
  PhysDrvH: THandle;
  PhysDrvName: String;
  PhysDrvNum: Integer;
begin
  Result := nil;
  FillChar(Fltr, SizeOf(Fltr), 0);
  //*** находим номер физического диска
  PhysDrvNum := GetFirstPhysicalDriveNumber(DriveChar);
  if PhysDrvNum = -1 then Exit;
  //*** имя физического диска
  PhysDrvName := \'\\\\.\\PhysicalDrive\'+IntToStr(PhysDrvNum);
  //*** открываем диск (неважно, вставлена ли карточка)
  PhysDrvH := CreateFile(PChar(PhysDrvName), 0, FILE_SHARE_WRITE, 
                         nil, OPEN_EXISTING, 0, 0);
  //*** заполняем структуру TDevBroadcastHandle
  Fltr.dbch_size := SizeOf(Fltr);
  Fltr.dbch_devicetype := DBT_DEVTYP_HANDLE;  // тип
  Fltr.dbch_handle := PhysDrvH;  // хэндл диска
  //*** регистрируем для окна Wnd
  Result := RegisterDeviceNotification( Wnd, @Fltr, 
                         DEVICE_NOTIFY_WINDOW_HANDLE );
  //*** освобождаем хэндл диска
  CloseHandle(PhysDrvH);
end;
 
Обрабатываем WM_DEVICECHANGE.
Ловим событие DBT_CUSTOMEVENT с GUID-ами GUID_IO_MEDIA_ARRIVAL и GUID_IO_MEDIA_REMOVAL.
 
procedure TForm1.WMDeviceChange(var Msg: TWMDeviceChange);
begin
  if (Msg.Event = DBT_CUSTOMEVENT) then
    with PDevBroadcastHandle(Msg.dwData)^ do begin
      if (dbch_devicetype = DBT_DEVTYP_HANDLE) then begin
        if IsEqualGUID( dbch_eventguid, GUID_IO_MEDIA_ARRIVAL) 
          then begin
          //*** карточку воткнули
          Label1.Caption := \'Inserted\';
          end
        else if IsEqualGUID( dbch_eventguid, GUID_IO_MEDIA_REMOVAL) 
          then begin
          //*** карточку выдернули
          Label1.Caption := \'Removed\';
          end;
        end;
      end;
end;
Тоже тупик?
0
 Аватар для prokl9tiy
21 / 21 / 9
Регистрация: 09.10.2016
Сообщений: 113
10.10.2016, 00:05
Цитата Сообщение от zombivadim Посмотреть сообщение
Мне надо получить от них уведомление!
ах да, если кардридер уже подключен...
ну тогда по таймеру проверять остается
Цитата Сообщение от zombivadim Посмотреть сообщение
Скачал программу , реально работает, чудеса какие то.
может он тоже по таймеру шурил
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
10.10.2016, 00:06
Цитата Сообщение от zombivadim Посмотреть сообщение
Тоже тупик?
Не знаю, надо пробовать.
У менять проверять бессмысленно, т.к. SD-ридер так "странно" себя не ведет.
0
12 / 11 / 2
Регистрация: 03.04.2016
Сообщений: 502
10.10.2016, 00:09  [ТС]
Цитата Сообщение от Убежденный Посмотреть сообщение
У менять проверять бессмысленно, т.к. SD-ридер так "странно" себя не ведет.
Как я понял он не странно себя ведет, просто некоторые устройства посылают сообщение о монтировании диска, а другим на это все равно. Как я понял тем которым все равно 90%
0
10.10.2016, 00:11

Не по теме:


Цитата Сообщение от Убежденный Посмотреть сообщение
Скорее всего, там что-то типа этого:
Не, там именно событийная схема.
Я его службу использую в своём AntiHidden сейчас.

0
12 / 11 / 2
Регистрация: 03.04.2016
Сообщений: 502
10.10.2016, 00:29  [ТС]
Убежденный, Попробуйте пожалуйста пример который я указал выше, вы специалист и сразу определите работает или нет , а мне придется долгое время на это потратить!

Добавлено через 16 минут
Цитата Сообщение от Dragokas Посмотреть сообщение
Ого я натыкался на этот пример, только не понял чем он может мне помочь.
0
 Аватар для prokl9tiy
21 / 21 / 9
Регистрация: 09.10.2016
Сообщений: 113
10.10.2016, 00:36
zombivadim, неужели это не работает?
C++
1
2
case WM_DEVICECHANGE:
        if(wParam== DBT_DEVICEARRIVAL)
0
12 / 11 / 2
Регистрация: 03.04.2016
Сообщений: 502
10.10.2016, 00:40  [ТС]
prokl9tiy, Что вы у меня спрашиваете проверите сами, не работает. Или вам надо сообщений в теме увеличить?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
10.10.2016, 00:40

WM_DEVICECHANGE RegisterDeviceNotification PDEV_BROADCAST_HDR
При приведении происходит исключение System.OverflowException что-то там переполнение из-за чего так? case DBT_DEVICEARRIVAL: { ...

Как обработать WM_DEVICECHANGE?
Нужна помощь, как заделать хук на событие - вставка изъятие USB-устройства???? Алгоритм такой воткнул/вынул флешку и получил месэдж от...

Не могу разобраться с WM_DEVICECHANGE
Здравствуйте! Необходимо перертсовать дерево со списком дисков в системе, когда в(из) USB разъем(а) вставляется (вынимается) флешка или...

RegisterDeviceNotification / WM_DEVICECHANGE / VID _ PID
Не могу подписаться на WM_DEVICECHANGE какие-то неизвестные ошибки не пойму что не так virtual void WndProc(Message% m) override ...

Обработка события подключения и отключения USB(WM_DEVICECHANGE)
Всем привет . Такая задача, требуется отследить подключение и отключение USB. Следующий код работает но выдает одно и тоже в события...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
GitHub Copilot в JetBrains: модель по умолчанию, Fix и контроль MCP
and_y87 12.10.2026
10 октября 2026 года GitHub обновил Copilot для JetBrains: добавил настройки стартовой модели, исправления из диагностики и управление автозапуском MCP. Поддержка IDE 2025. 1 прекращена — требуется. . .
День 5 из 28: Codex подсказывает следующий запрос
and_y87 12.10.2026
9 октября 2026 года OpenAI запустила бету Composer predictions — подсказок следующего сообщения в текущем диалоге Codex. Это помощь с формулировкой запроса, а не автоматическое продолжение задачи. . . .
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет! За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru