Узнайте, какой процесс имеет эксклюзивную блокировку на ручке устройства USB

У меня есть библиотека, которая читает / пишет на USB-устройство с помощью API CreateFile (). Устройство, как оказалось, реализует профиль устройства HID, так что он совместим с драйвером класса Microsoft HID.

Некоторое другое приложение, установленное в системе, открывает устройство в режиме чтения / записи без режима общего доступа. Что мешает моей библиотеке (и всему, что ее потребляет) работать с устройством. Я полагаю, в этом и заключается проблема с тем, чтобы быть HID-совместимым устройством - другие драйверы (мыши, контроллеры, PHIDGETS и т. Д.) Могут не работать.

В любом случае, путь к файлу устройства имеет вид:

1: "\\? \ Hid # hpqremhiddevice & col01 # 5 & 21ff20e7 & 0 & 0000 # {4d1e55b2-f16f-11cf-88cb-001111000030}".

2: "\\? \ Hid # vid_045e & pid_0023 # 7 & 34aa9ece & 0 & 0000 # {4d1e55b2-f16f-11cf-88cb-001111000030}".

3: "\? \ Hid#vid_056a&pid_00b0&col01#6&5b05f29&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}".

И я пытаюсь открыть его с помощью кода, например:

//  First, open it with minimum permissions, this device may not be ours.
//  we'll re-open it later in read/write
hid_device_ref = CreateFile(
    device_path, GENERIC_READ,
    0, NULL, OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL, NULL);

Я рассмотрел такой инструмент, как FileMon или Process Monitor от SysInternals. Но я не могу заставить его сообщать об использовании файловых дескрипторов устройств, подобных перечисленным выше.

4 ответа

Вы пробовали инструмент под названием ручка от sysinternals?

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

Вот что я использую для чтения карт-ридеров Magtek:

//Open file on the device
deviceHandle = 
    CreateFile (deviceDetail->DevicePath, 
    GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 
    NULL, OPEN_EXISTING, 0, NULL);

Попробуйте эти варианты и посмотрите, сможете ли вы хотя бы прочитать данные с устройства.

Я понимаю вашу боль здесь... Я обнаружил, что документация по USB HID в нескольких местах неверна.

[Править] Там не так много по этой проблеме. Вот ссылка на кодпроект, которая слегка затрагивает тему в теме внизу. Похоже, может быть, если это клавиатура или мышь, окна захватывают его исключительно.

Есть хитрость, которую вы можете сделать, когда вы открываете дескриптор устройства, не запрашивая ни разрешения на чтение, ни запись, и взаимодействуете с ним только с помощью отчетов о функциях. Ян Аксельсон упоминает этот трюк в своих книгах о USB HID-устройствах. Я считаю, что это позволяет обойти проблему с эксклюзивной блокировкой, с которой вы можете столкнуться (например) при попытке открыть дескриптор устройства, которое Windows считает системной клавиатурой или мышью. Даже если вы не можете прочитать или написать дескриптор, вы все равно можете отправить отчет о функции на устройство с помощью HidD_SetFeature и читать отчет с устройства, используя HidD_GetFeature, Я не знаю, каким образом можно читать входные отчеты или отправлять выходные отчеты при таких обстоятельствах, и, возможно, это невозможно сделать, но вам может не понадобиться ни один из них, особенно если устройство является "вашим" устройством в смысле что вы контролируете прошивку. Строго говоря, это ничего не дает, чтобы ответить на ваш вопрос в том виде, в котором оно было задано, но оно показалось мне потенциально актуальным, поэтому я решил, что брошу его туда.

Круто - я попробую эти варианты, так как они, вероятно, лучше по умолчанию, учитывая мои намерения. К сожалению, я знаю, что мое устройство есть, и мне в конечном счете понадобится доступ для чтения / записи позже (как только я осмотрю дескрипторы и проверим, действительно ли это на моем устройстве).

Это означает, что моя настоящая цель - узнать, что его использует, поэтому я могу сообщить клиенту / пользователю: "Эй, парень, iexplore.exe в настоящее время использует ваше устройство SuperWidget. Вам придется закрыть его, чтобы использовать Приложение SuperWidget." (если не на уровне приложения, то хотя бы на уровне поддержки телефона.)

Я забыл упомянуть, что ошибка Windows, о которой сообщает GetLastError():

0x20. Процесс не может получить доступ к файлу, потому что он используется другим процессом.

(Таким образом, ваши альтернативы для совместного использования, вероятно, откроют файл, если не использовать FILE_SHARE_NONE от имени другого процесса).

[редактировать]

Да, это больно хорошо. Я видел, как мыши и клавиатуры были заблокированы тем, что Windows использует для чтения с них. Я также видел, что у многих людей возникают проблемы с виртуальной машиной, такой как Paralells на OS X, где драйвер класса HID имеет устройство, открытое исключительно, что не позволяет виртуальной машине использовать стандартные запросы USB.

Я видел некоторый код, который воссоздает то, что делает ProcessMonitor. Возможно, SysInternals просто выбирает игнорировать дескрипторы устройства, но тот же метод (или небольшое изменение) может быть использован здесь для определения PID.

Майк

Другие вопросы по тегам