【问题标题】:Find out which process has an exclusive lock on a USB device handle找出哪个进程在 USB 设备句柄上有独占锁
【发布时间】:2010-09-06 14:18:33
【问题描述】:

我有一个使用 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}”。

我正在尝试使用代码打开它,例如:

//  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);

我考虑过像 SysInternals 的 FileMon 或 Process Monitor 这样的工具。但我似乎无法让它报告上面列出的设备文件句柄的使用情况。

【问题讨论】:

    标签: c++ winapi usb hid device


    【解决方案1】:

    您是否尝试过来自 sysinternals 的名为 handle 的工具?

    无论如何,Windows 都不会这样做(显示锁定设备的应用程序的名称):当您尝试弹出 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 文档在几个地方基本上是错误的。

      [编辑] 这个问题没有太多的内容。这是一个codeproject link,它在底部的一个线程中轻轻地触及了这个主题。听起来可能是键盘或鼠标窗口专门抓取它。

      【讨论】:

        【解决方案3】:

        您可以使用一个技巧来打开设备句柄,请求既不读取也不请求写入权限,并仅使用功能报告与之交互。 Jan Axelson 在她关于 USB HID 设备的书中提到了这个技巧。我相信这可以解决排他锁的问题,例如,当您尝试打开 Windows 认为是系统键盘或鼠标的设备的句柄时会遇到该问题。即使您无法读取或写入句柄,您仍然可以使用HidD_SetFeature 向设备发送功能报告,并使用HidD_GetFeature 从设备读取报告。我不知道在这些情况下读取输入报告或发送输出报告的临时方法,也许不可能这样做,但您可能不需要其中任何一个,特别是如果设备在某种意义上是“你的”设备你控制固件。严格来说,这对回答您提出的问题没有任何帮助,但它似乎可能相关,所以我想我会把它扔在那里。

        【讨论】:

          【解决方案4】:

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

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

          忘了说GetLastError()报的windows错误是:

          0x20。该进程无法访问该文件,因为它正被另一个进程使用。

          (因此您的共享选项可能会打开文件,假设没有代表其他进程的 FILE_SHARE_NONE)。

          [编辑]

          是的,这很痛苦。我已经看到鼠标和键盘被 Windows 用来读取它们的任何东西锁定。我还看到很多人在 OS X 上的 Parallels 等 VM 中遇到问题,其中 HID 类驱动程序使设备以独占方式打开,从而阻止 VM 使用标准 USB 请求。

          我见过一些代码重新创建了 ProcessMonitor 所做的事情。也许 SysInternals 只是选择忽略设备句柄,但这里可以使用相同的方法(或稍有变化)来确定 PID。

          迈克

          【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-05-26
          • 2017-10-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多