Ожидание загрузки всех USB-накопителей

В настоящее время я работаю с приложением, которое имеет логику ветвления в зависимости от того, вставлен ли в систему конкретный USB-накопитель. Это делается путем опроса всех букв дисков в поисках пути в корне каждого диска.

Это работает для большинства машин, но часто это приложение запускается при запуске со вставленным USB-накопителем. Кроме того, некоторые машины работают особенно медленно, и после загрузки Windows на загрузку USB-накопителя требуется хорошая минута. В этих машинах код достигает проверки, существует ли этот диск, он не может найти диск, и выполняется неправильная ветвь.

Перед проверкой дисков можно подождать минуту. Я бы предпочел, чтобы приложение ожидало загрузки всех USB-устройств (или просто только запоминающих устройств), прежде чем проверять диски, или что-то еще более интеллектуальное.

К сожалению, я не знаком с методами, необходимыми для ожидания завершения загрузки всех USB-устройств, и с DDK в целом. Я могу увидеть, что можно зарегистрировать окно для уведомлений устройства с помощью GUID_DEVINTERFACE_USB_DEVICE < / a>, возможно получение сообщений типа _ 2_, _ 3_ и _ 4_, отличия которого я не знаю.

Однако USB-накопитель, скорее всего, уже будет вставлен и обнаружен (но без буквы диска) в системе до выполнения программы. Таким образом, регистрироваться для получения всех уведомлений об изменении устройства не имеет смысла. Если возможно идентифицировать устройства, которые вставлены, но не загружены (возможно, с помощью SetupDiEnumDeviceInterfaces), а затем зарегистрируйтесь для получения" загруженных "уведомлений на всех этих устройствах, это может сработать. Я ничего не знаю об этом, поэтому указатели (или пример кода) были бы чрезвычайно полезны.


person Alyssa Haroldsen    schedule 20.07.2016    source источник
comment
Я бы предпочел, чтобы приложение ожидало всех USB-устройств - для этого вам потребуется краткая спецификация того, что включает в себя все USB-устройства. Поскольку USB-устройства могут поддерживать горячее подключение, это довольно сложно указать. Кроме того, отображение 1: 1 между USB-накопителями и буквами дисков неверно. USB-устройству может быть назначено ноль или более букв дисков. Буквы дисков назначаются каждому пользователю. Так что иметь дело с буквами дисков в сервисе бессмысленно. (Предполагая, что вы пишете службу, поскольку вы говорите об инициализации во время загрузки.)   -  person IInspectable    schedule 20.07.2016
comment
@IInspectable: на самом деле буквы дисков представляют собой объединение общесистемных назначений (локальные диски) и назначений для каждого сеанса (удаленные общие ресурсы с использованием учетных данных пользователя). USB-диск является локальным. Но есть небольшая магия IIRC, позволяющая избежать выбора буквы, которая уже используется для удаленного общего ресурса.   -  person MSalters    schedule 20.07.2016
comment
@IInspectable Предположим, что перечисляются только съемные тома, независимо от того, есть ли у них буква диска. К ним по-прежнему нельзя получить доступ по GUID тома. Диски также содержат ровно один полный NTFS-раздел.   -  person Alyssa Haroldsen    schedule 20.07.2016
comment
Как я уже сказал, вам нужна краткая спецификация. Повторение all мало что объясняет, поскольку горячее подключение делает доступность функцией с течением времени.   -  person IInspectable    schedule 20.07.2016
comment
Я прошу эквивалент API для определения того, показывает ли в настоящее время установка программного обеспечения диска в области уведомлений какие-либо загружаемые в данный момент устройства, и чтобы получить уведомление, когда устройства, перечисленные в настоящее время, доступны для использования (когда появляется буква диска ), или если устройства отключены. Я не уверен в точном (и кратком) определении, которое объясняло бы то, что мне нужно. Я хочу знать, подключены ли запоминающие устройства USB, но загрузка еще не завершена, и получать уведомление, когда том может быть доступен (или диск отключен).   -  person Alyssa Haroldsen    schedule 20.07.2016
comment
@Kupiakos: наличие ровно одного полного диска NTFS-раздела - это не то, что Windows знает заранее. Он откроет эти вещи только поэтапно. На самом деле, держу пари, на вашем диске вообще не будет раздела - USB-накопители обычно не разбиты на разделы. Скорее всего, он просто содержит одну файловую систему NTFS. Мелкие детали, конечно, но Windows имеет дело со всеми такими вещами. Драйвер NTFS должен знать, начинать ли с абсолютного 0 или с первого блока данных внутри первого раздела. А без таблицы разделов как Windows вообще узнает, что это система NTFS? Метод проб и ошибок, IIRC.   -  person MSalters    schedule 20.07.2016
comment
@MSalters Я говорю, что точно знаю, что подключаемые диски гарантированно будут иметь таблицу разделов MBR с одним полнодисковым разделом в формате NTFS. Я не спрашиваю, когда Windows узнает об этом (хотя, честно говоря, я ни разу не видел USB-диск без разделов). Я хочу знать, когда диск будет полностью доступен для использования по назначению, а все связанные тома будут готовы к доступу. Это управляемый специализированный сценарий.   -  person Alyssa Haroldsen    schedule 20.07.2016


Ответы (2)


Я не думаю, что ты сможешь.

Проблема в том, что вы пытаетесь различить два случая, которые на самом деле не отличаются: подключение USB-устройства во время загрузки и подключение его позже.

Вы должны знать, что USB - это протокол, который требует нетривиального интеллекта в ведомых USB-устройствах. Они обмениваются несколькими сообщениями с USB-хостом (то есть с вашей ОС). Этот обмен не мгновенный. Например, ваш жесткий диск USB должен запросить разрешение на потребление энергии более 100 мА. Чтобы ответить на этот вопрос, драйверы питания Windows должны быть запущены. Физический диск может раскручиваться только тогда, когда приходит ответ.

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

Когда вы перечисляете устройства в то время, когда устройства активно добавляются, вы действительно напрашиваетесь на проблемы. SetupDiEnumDeviceInterfaces API не работает со снимком (что мы знаем, потому что нет метода Close); вы запрашиваете N-е устройство, пока не получите ошибку «Нет больше устройств», а вы знаете, что N слишком велико. Но когда устройства все еще активно добавляются, N меняется. И я не вижу гарантии, что список упорядочен по возрасту; устройства также могут быть добавлены посередине.

person MSalters    schedule 20.07.2016
comment
Я предполагаю, что я прошу эквивалент API для определения того, показывает ли в настоящее время установка программного обеспечения диска в области уведомлений какие-либо загружаемые в данный момент устройства, и для получения уведомления, когда устройства, перечисленные в настоящее время, доступны для использования (когда диск появляется буква). - person Alyssa Haroldsen; 20.07.2016

Я не думаю, что получение уведомлений об установленных драйверах для вновь подключенных устройств могло бы вам сильно помочь. Когда вы подключаете одно и то же устройство несколько раз, драйверы обычно устанавливаются только в первый раз.

Кроме того, флэш-накопитель USB, хотя физически выглядит как одно компактное устройство, в Windows представлен как минимум тремя устройствами PnP: запоминающим устройством USB (представляет собой конечную точку USB), дисковым устройством (представляет собой физический диск внутри флэш-накопителя. ) и одно или несколько устройств Volume (каждое из них представляет собой один том = раздел в вашем случае). Буквы дисков могут быть назначены устройствам Тома.

Что вы можете сделать, так это отслеживать прибытие и удаление устройств Volume (RegisterDeviceNotification для GUID_DEVINTERFACE_VOLUME) и проверять каждое поступающее устройство тома (я считаю, что Setup API позволяет отслеживать его «родителей» в стеке USB).

person Martin Drab    schedule 20.07.2016