Узнайте, какой процесс имеет исключительную блокировку на ручке устройства 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. Но я не могу заставить его сообщать об использовании в ручках файлов устройств, как указано выше.

Ответ 1

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

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

Ответ 2

Это то, что я использую для чтения с устройства чтения карт 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 в основном неправильной в нескольких местах.

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

Ответ 3

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

Ответ 4

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

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

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

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

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

[править]

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

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

Mike