WM_DEVICECHANGE и все все все
Обложился USB-кардридерами, сую в них карточки и высовываю и чувствую, что схожу с ума.
Вот есть сообщение WM_DEVICECHANGE, оно прилетает
- когда я вставляю USB-флешку (не карту)
- когда я подключаю ридер (без карты)
- когда я подключаю ридер с заранее вставленной карточкой.
А вот если подключить ридер без карты (прилетит сообщение), а потом вставить карточку - на вставление карточки WM_DEVICECHANGE не прилетает.
Kaspersky Antivirus со мной солидарен, свое "обнаружен съемный диск" он показывает в случаях 1 и 3 (ну а второй - фильтрует, потому что устройство есть, но не ready), а если сначала подключить ридер, а потом сунуть карту - проверить ее не предлагают.
При этом сидюк (ну точнее Daemon Tools, где я в 2015-м году возьму сидюк) ведет себя нормально - на монтирование/размонтирование диска сообщения есть.
Windows Explorer и Adobe Bridge при этом сувание-вынимание карточки отрабатывают отлично, чуют.
ВОПРОСЫ МОИ
- ЧЯДНТ?
- Есть какие-то более здравые идеи, чем поллинг по списку removable drives раз в пару секунд с проверкой
То есть гугление показало, что я не первый, кто об эти грабли ударился, рекомендуют вот подписываться на обновления про USB-устройства (вот и еще вот), только вот радости это не принесло, второй пример - уверенно показывает подключение кардридера, но на вставление карточки в ридер никак не реагирует, а на какие GUID надо подписаться для вставления карты - я не понимаю, мне бы слова списать.
UPDATE (переношу историю из комментариев)
- В USB нет уведомлений "о вставке карты", поэтому поллинг - единственный вариант.
- Вот насколько мне кажется, этим поллингом занимается сама Windows, раз секунд в 6 (10 раз в минуту), во всяком случае устройство появляется в Explorer с задержкой до 8 секунд и вряд-ли все общения с ним (прочитать метку диска и т.п) занимают более двух.
- Поллинг GetVolumeInformation (по известной букве диска) раз в секунду - перестает возвращать ошибку ("нет диска") с такой же задержкой, что и устройство появляется в Explorer.
- Соответственно, есть основания думать, что поллингом Windows (как минимум, семерка) - занимается централизованно ("в ядре").
- Поллинг - разумное, получается, поведение. Естественно, надо делать так:
- Продолжать получать нотификации о появлении/удалении букв диска
- Поллить только те, про которые известно что они Removable (или ничего неизвестно - буква появилась, но никакой файловой системы там никогда не было, поэтому узнать нельзя).
- Вопрос, тем не менее, остается: если система централизованно поллит (?? уверенности нет, но если бы поллили юзерские программы независимо, то моя, с поллингом раз в секунду, получала бы информацию о диске за пару секунд, а не за 7-8 как и Explorer/Autoplay), то какого хрена WM_DEVICECHANGE не прилетает.
Comments
если я правильно сошёл с ума,
если я правильно сошёл с ума, всё ты верно понял.
"да, мы о***ли"(c), и так оно всё и есть.
А конструктив то где? Поллинг
А конструктив то где? Поллинг раз в пару секунд?
Ну, да, всё так и есть.
Ну, да, всё так и есть.
Интересно, кстати, подсмотреть, как это у MacOS X сделано.
Но штука-то именно в том, что USB девайс *по собственной воле* отправить мессаж хосту не может -- ну, кроме как переинициализировать коннекшн, что непросто, дорого и чревато, IIUC.
Ну вот когда вставляю
Ну вот когда вставляю карточку - что-то куда-то отправляется же? Иначе бы диск системой не находился, а он находится.
Что мешает это форвардить дальше, в WM_DEVICECHANGE - я просто не понимаю.
В макоси - коллбеки у Disk Arbitration:
DARegisterDiskDisappearedCallback
DARegisterDiskAppearedCallback
DARegisterDiskUnmountApprovalCallback
DARegisterDiskDescriptionChangedCallback
Но до макоси я еще не добрался, не исключено что там такое же говно (с другой стороны, простой мониторинг /Volumes на изменения (через fsevents или kqueue), - решает мою проблему /помониторить вставление-вынимание флешек/ практически полностью)
Сколь я понимаю, как раз таки
Сколь я понимаю, как раз таки *не* отправляется ничего, потому что неоткуда взяться.
Вот ридер карточек, ему
Вот ридер карточек, ему присвоена буква диска Q:
Я могу про него спросить GetVolumeInformation, если карточки нет - получу код ошибки (который анализирую на ERROR_NOT_READY, если она - карточки нет, если другая - считаю невалидной эту букву).
Сую карточку, больше ничего не трогаю, что происходит:
- в Disk Administrator - диск находится
- в эксплорере - появляется
- GetVolumeInformation - возвращает про эту букву приличные всякие слова (метку диска, serial number)
То есть винда как-то узнала, что карточку воткнули - и сходила почитала оттуда.
Есть, на самом деле, интерфейс про Portable Devices, пишут оттуда можно получить нотификацию, но он Vista и выше, не хочу использовать (WMI - тоже не хочу)
Ну так это и есть поллинг, то
Ну так это и есть поллинг, то, что ты описываешь. Когда ты вызывешь GVI винда сама обращается к ридеру. А пока хост к ридеру не обратится он должен молчать, вставили там в него карту или нет.
Он не "должен молчать" -- он
Он не "должен молчать" -- он не имеет возможности что-либо сказать, не выдали ему ;)
Ну, он может сделать
Ну, он может сделать отключение-подключение
И, более того, я видел ридер с 4-мя дырками который показывал буквы дисков только при вставлении карточки. Т.е. подключаешь его — и тишина. Суьёш карту — появляется буква диска. Одна. Сушёь вторую — появляется вторая. Вынимаешь — исчезает.
Ну, да я про это выше: http:/
Ну, да я про это выше: http://blog.lexa.ru/comment/42428#comment-42428 и писал.
Там много других граблей закопано, если я правильно всё понимаю.
Ну, сделали уродский протокол, а он и разползся, что уж теперь делать ;)
При том что что FireWire, что Thunderbolt -- объективно сильно лучше -- USB всё равно всех подебит.
FireWire в другом месте
FireWire в другом месте крупно прокололись. Технически. Так, кстати, по уму, кажется нигде и не исправлено.
Ты про неотключаемый DMA? Ну,
Ты про неотключаемый DMA? Ну, это *можно* было бы поправить. Только деманду нету, уже от слова совсем.
Скорее — про то, что везде
Скорее — про то, что везде сделали его жёстко-отключаемым а надо бы по адресам устройств, что бы вот данным конкретным внешним диском можно было бы пользоваться, а хакерская железка бы обломилась.
То есть (как и пишут ниже) -
То есть (как и пишут ниже) - винда делает поллинг?
Какого хрена результаты этого поллинга не прилетают по DEVICECHANGE?
Деелает explorer скорее всего
Деелает explorer скорее всего, а он вообще не обязан быть запущен.
Хотя ядро могло бы по результатам любого поллинга рассылать, да.
это мы одновременно про одно
это мы одновременно про одно разными словами ;)
Ну не только explorer. В
Ну не только explorer. В device list возникает, например.
Известно (ну то есть я прочитал, а вдаваться не стал в подробности) что можно получить нужное мне через WMI и WPD
А чем тебя, кстати, так
А чем тебя, кстати, так отвращает WMI? Вроде бы на фоне конкурентов довольно внятный...
Ну вот тем, что для
Ну вот тем, что для DEVICECHANGE код уже написан (тоже не без приколов - ему нужно окно, без окна не может).
А этот - надо разбираться и писать.
Ну и кроме того: Win32
Ну и кроме того: Win32_DeviceChangeEvent - Vista и выше. А у меня XP и выше.
судя по всему, поллитнг
судя по всему, поллитнг делает не ядро, а юзерлендовые программы.
FUSE они не сделали, короче ;-P
Ты думаешь,
Ты думаешь, GetVolumeInformation перечитывает диск каждый раз, а не берет кэшированное (в системе)?
Не знаю.
Не знаю.
Я бы (при отсутствии хинтов) кешировал бы не более чем на единицы секунд, иначе пытался бы дёргать physical device.
Я к тому клоню, что оно это
Я к тому клоню, что оно это делает "в ядре, само".
Ага. И притом применяет
Ага. И притом применяет неестественный интелект в зависимости от того, какое устройство является родителем носителя.
Очень consistent, ога.
Короче, у меня все работает
Короче, у меня все работает уже! (правда под семеркой, до XP еще не добрался).
А с мониторингом вставления карт - оказывается используют миллион методов, вплоть до разбора системных событий. Что говорит о том, что место - ГОВЕННОЕ.
Вот я и не буду его больше трогать. Поллинг - так поллинг.
Ну вот кстати. У меня дрочка
Ну вот кстати. У меня
дрочкаполлинг GetVolumeInformation - раз в секунду.При вставлении карты - оно думает где-то 7-8 секунд, появляется в эксплорере, всплывает окно автоплея и одновременно вот с автоплеем - появляется в моей программе.
То есть вот сдается мне, что там внутри централизованный поллинг, а GetVolumeInformation таки дает кэшированное.
Короче, поллинг работает.
Короче, поллинг работает. Хоть и противен мне.
Ну линукс как-то обнаруживает
Ну линукс как-то обнаруживает попадание карты в карт-ридер и тут же спрашивает, что мол делать.
Винда тоже видит это событие, но окошко мне не выдаёт (картридер, правда, встроенный в ноут). FAR вон буковку добавляет.
FAR, кстати, как реагирует на это? Если нормально- может заглянуть в код?
Far, да, хорошая идея.
Far, да, хорошая идея.
Пошел читать.
У Far нету этой проблемы. Там
У Far нету этой проблемы. Там если буква диска есть, на нее можно пойти (ну и получить ошибку, что нету ничего).
Соответственно, там просто WM_DEVICECHANGE, которой достаточно вполне для обновления списка буковок.
Я тоже изучал этот вопрос, но
Я тоже изучал этот вопрос, но несколько иначе. Во-первых, ситуация сильно разная для PCI-кардридеров и кардридеров, подключенных по USB. Для PCI аппаратные уведомления ходят. Для USB, как известно, нет и я запускал WinXP внутри VirtualBox, который помаргивает своим индикатором активности USB при наличии оной и прокидывал туда USB-кардридер из хоста.
И таки XP мигает индикатором USB постоянно, пока в неё кардридер прокинут, независимо от того, вставлена в него карточка или нет. Примерно три раза в 2 секунды. И при вставлении карточки Explorer реагирует на неё с этой самой задержкой поллинга.
Оппа! А в каких устройствах
Оппа! А в каких устройствах ты встречал PCI кардридеры? Все, что попадались мне -- на внутренних USB хабах.
я видел в старых ноутах Sony
я видел в старых ноутах Sony Vaio. TI'шный чип прямо на PCI с поддержкой SD и MS.
Вообще, SDHC-спецификация
Вообще, SDHC-спецификация прописывает хост-интерфейс и чипов, которые умеют её прямо на PCI есть. Можно посмотреть, например, что поддерживает FreeBSD -CURRENT :))))
Осталось найти это в жывой
Осталось найти это в жывой природе, ога.
;-P
Ну на чём-то авторы
Ну на чём-то авторы отлаживались :)
Как я понимаю, в ноутах по прежнему бывает.
В ноуте у меня стареньком.
В ноуте у меня стареньком.