C++ 找出哪个进程在USB设备句柄上具有独占锁

C++ 找出哪个进程在USB设备句柄上具有独占锁,c++,winapi,usb,hid,device,C++,Winapi,Usb,Hid,Device,我有一个使用CreateFile()API读取/写入USB设备的库。该设备碰巧实现了HID设备配置文件,因此它与Microsoft的HID类驱动程序兼容 系统上安装的其他一些应用程序正在以读/写模式打开设备,而没有共享模式。这会阻止我的库(以及任何使用它的东西)使用该设备。我想这就是HID兼容设备的问题所在——其他驱动程序软件(鼠标、控制器、PHIDGETS等)可能不合作 无论如何,设备文件路径的形式如下: 1: "\\?\hid#hpqremhiddevice&col01#5&21ff20e7

我有一个使用CreateFile()API读取/写入USB设备的库。该设备碰巧实现了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}".
我考虑过一个类似FileMon或SysInternals中的进程监视器的工具。但我似乎无法让它报告上面列出的设备文件句柄的使用情况。

这是我从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文档在几个地方基本上是错误的


[编辑]在这个问题上没有太多内容。下面是一个在底部的一条线中轻轻触及主题的例子。听起来可能是键盘或鼠标的问题,windows会专门抓住它。

酷-我会尝试这些选项,因为考虑到我的意图,它们可能是更好的默认设置。不幸的是,我知道我的设备在那里,以后我最终需要读/写访问权限(一旦我检查描述符并验证它实际上是我的设备)

这意味着我真正的目标是了解它的用途,这样我就可以通知客户/用户:“嘿,伙计,'iexplore.exe'当前正在使用你的SuperWidget设备。你必须关闭它才能使用SuperWidget应用程序。”(如果不是在应用程序级别,那么至少是在电话支持级别。)

我忘了提到GetLastError()报告的windows错误是:

0x20。进程无法访问该文件,因为其他进程正在使用该文件

(因此,您的共享备选方案可能会打开文件,假设没有文件\u共享\u不代表其他进程)

[编辑]

是的,很痛。我见过鼠标和键盘被窗户用来阅读的东西锁住。我还看到很多人在OS X上的Parallels这样的虚拟机中遇到问题,其中HID类驱动程序以独占方式打开设备,防止虚拟机使用标准USB请求

我看到一些代码重新创建了ProcessMonitor的功能。也许SysInternals只是选择忽略设备句柄,但是这里可以使用相同的方法(或稍微改变)来确定PID

迈克


您是否尝试过从sysinternals调用的工具


无论如何,windows都不会这样做(显示锁定设备的应用程序的名称):当您尝试弹出USB设备时,Windows只是说设备当前正在使用中,无法立即删除。

有一个技巧,您可以打开设备句柄,不请求读写权限,只使用功能报告与之交互。在她关于USB隐藏设备的书中提到了这个技巧。我相信这可以解决独占锁的问题,例如,当您试图打开Windows认为是系统键盘或鼠标的设备的句柄时,会遇到独占锁。即使无法读取或写入句柄,也可以使用向设备发送功能报告,并使用从设备读取报告。在这种情况下,我不知道如何立即读取输入报告或发送输出报告,也许这样做是不可能的,但您可能不需要这两种方法中的任何一种,特别是在您控制固件的意义上,如果设备是“您的”设备的话。严格地说,这并不能回答您提出的问题,但它似乎有潜在的相关性,所以我想我会把它扔出去。

这就是您需要的:
//Open file on the device
deviceHandle = 
    CreateFile (deviceDetail->DevicePath, 
    GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 
    NULL, OPEN_EXISTING, 0, NULL);