c++ - Descubre qué proceso tiene un bloqueo exclusivo en el mango de un dispositivo USB
winapi hid (4)
Tengo una biblioteca que lee / escribe en un dispositivo USB usando la API CreateFile (). El dispositivo implementa el perfil del dispositivo HID, de modo que es compatible con el controlador de clase HID de Microsoft.
Alguna otra aplicación instalada en el sistema está abriendo el dispositivo en modo lectura / escritura sin modo compartir. Lo que impide que mi biblioteca (y todo lo que la consume) funcione con el dispositivo. Supongo que ese es el problema de ser un dispositivo compatible con HID: otro software de controlador (ratones, controladores, PHIDGETS, etc.) puede ser poco cooperativo.
De todos modos, la ruta del archivo del dispositivo es de la forma:
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}".
Y estoy tratando de abrirlo usando código, como:
// 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);
He considerado una herramienta como FileMon o Process Monitor de SysInternals. Pero parece que no puedo informar el uso en los identificadores de archivos del dispositivo como el que se menciona arriba.
Esto es lo que uso para leer desde un lector de tarjetas Magtek:
//Open file on the device
deviceHandle =
CreateFile (deviceDetail->DevicePath,
GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);
Pruebe esas opciones y vea si al menos puede leer desde el dispositivo.
Entiendo tu dolor aquí ... Encontré que la documentación de USB HID es básicamente incorrecta en varios lugares.
[Editar] No hay mucho por ahí sobre este problema. Aquí hay un enlace de proyecto de código que toca ligeramente el tema en un hilo en la parte inferior. Suena como si tal vez si se trata de un teclado o una ventana del mouse lo agarrara exclusivamente.
Genial - Probaré esas opciones, ya que probablemente sean mejores por defecto dado mis intenciones. Desafortunadamente, sé que mi dispositivo está allí y eventualmente necesitaré acceso de lectura / escritura más adelante (una vez que inspeccione los descriptores y haya verificado que de hecho es mi dispositivo).
Lo que significa que mi objetivo real ES saber qué lo está usando, así que puedo informar al cliente / usuario: "Hey man, ''iexplore.exe'' está utilizando actualmente su dispositivo SuperWidget. Tendrás que cerrarlo para usar Aplicación SuperWidget ". (Si no en el nivel de aplicación, al menos en el nivel de soporte del teléfono).
Olvidé mencionar que el error de Windows reportado por GetLastError () es:
0x20. El proceso no puede acceder al archivo porque lo está usando otro proceso.
(Así que sus alternativas de intercambio probablemente abrirán el archivo, suponiendo que no haya FILE_SHARE_NONE en nombre del otro proceso).
[editar]
Sí, es doloroso, está bien. He visto que los mouse y los teclados se bloquean con lo que Windows usa para leer de ellos. También he visto a muchas personas tener problemas dentro de una máquina virtual como Paralells en OS X, donde el controlador de clase HID tiene el dispositivo abierto que impide exclusivamente que la VM use solicitudes USB estándar.
He visto un código que recrea lo que ProcessMonitor hace. Tal vez SysInternals simplemente opte por ignorar los identificadores de dispositivo, pero el mismo método (o una pequeña variación) se puede emplear aquí para determinar el PID.
Micro
¿Has probado la herramienta llamada handle from sysinternals?
De todos modos, ninguna de las ventanas hace esto (muestra el nombre de la aplicación que bloqueó el dispositivo): cuando intentas expulsar un dispositivo USB, Windows simplemente dice que el dispositivo está actualmente en uso y no se puede quitar en este momento.
Hay un truco que puedes hacer cuando abres el identificador del dispositivo y no solicitas permiso de lectura ni de escritura, e interactúas solo con informes de funciones. Jan Axelson menciona este truco en sus libros sobre dispositivos USB HID. Creo que esto soluciona el problema con el bloqueo exclusivo, que se encontraría (por ejemplo) al intentar abrir un identificador de un dispositivo que Windows considera que es un teclado o mouse del sistema. Aunque no puede leer o escribir el identificador, aún puede enviar un informe de función al dispositivo usando HidD_SetFeature
y leer un informe desde el dispositivo usando HidD_GetFeature
. No sé de ninguna manera leer informes de entrada o enviar informes de salida en estas circunstancias, y tal vez sea imposible hacerlo, pero es posible que no necesite ninguno de estos, especialmente si el dispositivo es "su" dispositivo en el sentido que controlas el firmware. Estrictamente hablando, esto no hace nada para responder a su pregunta como se le preguntó, pero parecía potencialmente relevante, así que pensé que lo lanzaría allí.