【问题标题】:Creating a Virtual USB Device创建虚拟 USB 设备
【发布时间】:2011-06-28 07:57:39
【问题描述】:

我是一个新手,学习如何为 USB 设备编写 WDM 设备驱动程序,发现可用的材料太难理解了(DDK 在线文档是最难阅读的文档之一,WDM 设备驱动程序书由Oney 再好不过了)。

所以,我有一个简单的问题。如果我想创建一个用于测试/学习的虚拟 USB 设备(例如,一个看起来像连接到 USB 端口的真实 USB 鼠标的虚拟 USB 鼠标),我应该从哪里开始。

到目前为止,我所了解的是 HIDClass 驱动程序 (hidclass.sys) 有一个用于执行连接 USB 硬件枚举的 USB 总线 (hidusb.sys) 的微型驱动程序。那么,如果我想劫持硬件枚举过程并创建自己的虚拟硬件,我是否应该在某处包含一个过滤器驱动程序来拦截一些与硬件枚举过程相关的 IRP?

很抱歉,如果上述内容完全没有意义,因为我仍处于学习阶段,这实际上是我认为可以帮助我更好地学习编写 USB 设备驱动程序的练习之一。

【问题讨论】:

标签: usb device drivers


【解决方案1】:

提供您自己的总线类型和枚举器不是更有意义吗?

【讨论】:

  • 如果出于学习的目的,我想创建一个虚拟 USB 设备怎么办?
  • 我的意思是,为了学习的目的,最好从不涉及混淆操作系统的东西开始。如果您真的想引入虚拟 USB 设备,那么提供您自己的 USB 主机适配器是您的最佳选择。
  • 你不妨看看usbip.sourceforge.net项目是如何做到的。
【解决方案2】:

Windows 使用即插即用架构。 当您插入 USB 设备时,它会向设备发送低级 USB 请求,然后根据设备的响应决定加载什么驱动程序。通过将供应商 ID、产品 ID 等与 inf 文件部分进行比较来完成匹配。驱动程序以带有 xxx.inf 文件的编译 xxx.sys 的形式出现,并加载到内核空间。 Windows 根据设备驱动程序附带的 *.inf 文件决定加载哪个 xxx.sys。

这些文件有这样的部分:

[Manufacturer]
%Manufacturer% = DeviceInstall

[DeviceInstall]
"some usb dev"=OTHER_SECTION_DEV, USB\Vid_XXXX&Pid_yyyy

# This is where windows learns to match this information
# to your device, using the product id (Pid) and the 
# vendor id (Vid) that Windows gets back during the
# low level USB DeviceDescriptor request

[OTHER_SECTION_DEV]
CopyFiles = xxx.sys, 10,system32\drivers

(有关 inf 文件中内容的更详细说明,请参见 https://docs.microsoft.com/en-us/windows-hardware/drivers/install/inf-manufacturer-section


USB枚举过程详解(使用USB Logger):

  • USB 设备已插入
  • USB 总线驱动程序请求
    • GetDescriptor(设备)
    • GetDescriptor(配置)
    • GetDescriptor(String iSerialNumber),用作设备实例 ID
    • GetDescriptor(String iProduct),在“新硬件已识别”弹出窗口中使用
  • PNP(即插即用)管理器被告知总线驱动程序添加了一个设备。
  • PNP 管理器然后通过使用 PNP 请求向总线驱动程序询问设备信息,请求:
    • DeviceID 字符串,代表 USB 供应商和产品 ID,
    • HardwareIDs 字符串,
    • CompatibleIDs 字符串,代表 USB 设备的接口类、子类和协议,以及
    • InstanceID 字符串,表示该特定设备的 uid,该设备在与计算机连接的具有相同兼容 id 的所有实例集中。

对于任何连接的 USB 设备,您可以使用设备管理器查看这些字符串:

  • 打开设备管理器(windows 菜单 -> “设备管理器”,或控制面板 -> “系统” -> “硬件” -> “设备管理器”)
  • 然后使用“view”菜单切换到“Device by Connection”
  • 打开“ACPI [...]”->“PCI 总线”/“PCI Express Root Complex”->“[...] USB [...] 主机控制器”
  • 展开主机控制器下的任何条目,对于列出的任何设备,右键单击以获取其属性,打开“详细信息”选项卡,然后使用属性下拉菜单找到“硬件ID”,“ Compatible Ids”、“Device Instance ID”、“Matching Device Id”、“Service”等。

例如,我有一个连接了Device Id = usb\class_08&subclass_06&prot_50 的USB 存储设备,这个字符串可以匹配到第一次枚举后添加到已知设备列表中的.inf 文件。这个文件有一个字符串Service = USBSTOR,所以我们知道usbstor.sys是用来连接这个USB大容量存储设备的。

让我们继续匹配过程。

  • PNP 管理器尝试确定设备是否已“安装”:
    • 它在注册表中搜索与“DeviceInstance ID”匹配的键,以查看哪个服务处理与此设备的接口。具体来说,它会在 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB 中搜索此内容

对于钥匙上的磁盘,您可以看到如下内容:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\Vid_0781&Pid_5406\0775555ACA54ADE3]
"Service"="USBSTOR"
  • PNP 管理器然后根据 PNP 请求中的字符串与 .inf 数据库中的数据之间的匹配加载关联的驱动程序:
    • inf 数据库位于:C:\WINDOWS\inf\
    • 驱动程序 .sys 文件位于:C:\WINDOWS\system32\drivers
  • 如果 PNP 找不到匹配的字符串,您将收到提示显示 xxx.sys 和 xxx.inf 的路径

对于编写驱动程序,我的建议是:

  1. 不要从实现 HID(人机接口设备)设备开始,因为您可能会导致 Windows 使用您自定义的鼠标或键盘驱动程序而不是原始驱动程序,这将禁用您的鼠标或键盘,非常危险。
  2. 不要将驱动程序加载到您的开发机器中:
    1. 使用虚拟机并在那里安装驱动程序。为您的虚拟机设置内核调试器:http://www.codeproject.com/KB/winsdk/KernelModeDebuggerSetup.asp
    2. 或在其他测试机器上加载驱动程序。
  3. USB驱动的好学习平台是“OSR USB-FX2 Learning Kit”

【讨论】:

    【解决方案3】:

    【讨论】:

    • 感谢您回答我的老问题。 DSF 确实值得一看。
    【解决方案4】:

    您可以使用 USB/IP 项目来模拟您想要的任何设备。在我的博客中,我演示了如何使用 USB/IP 项目在 python 中模拟 USB 鼠标设备: http://breaking-the-system.blogspot.com/2014/08/emulating-usb-devices-in-python-with-no.html

    它不会帮助您了解如何创建虚拟 USB 设备(该过程在 USB/IP 驱动程序中完成,您可以阅读代码),但它将创建虚拟 USB HID 设备,您可以使用发送到 USB 驱动程序的 HID 参数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-02
      • 1970-01-01
      • 1970-01-01
      • 2014-01-03
      • 2011-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多