libusb 未列出的 USB/IP 仿真设备

Posted

技术标签:

【中文标题】libusb 未列出的 USB/IP 仿真设备【英文标题】:USB/IP emulated device not listed by libusb 【发布时间】:2015-09-25 06:46:19 【问题描述】:

USB/IP 工具允许通过 TCP/IP 网络共享访问 USB 设备。 USB 设备连接到运行 TCP 服务器的 Linux PC 和运行 VHCI 驱动程序的 Windows PC 连接到 Linux。 这种方法可以在完全没有硬件的情况下模拟任何 USB 设备。您所需要的只是编写将处理 USB 请求的 TCP 服务器。 (如here)

但是模拟设备的问题并不真正正确。当您尝试使用 libusb 列出连接的 USB 设备时,您将收到错误 'unlisted parents for..',因为模拟设备在设备树中没有父设备。 另一方面,Zadig 等一些工具显示模拟设备。

here 讨论的正是问题,但没有提供真正的解决方案。

那么问题是 USB/IP Windows 驱动程序中的错误吗?任何有 Windows 驱动程序开发经验的人都可以提供帮助吗?父设备有什么关系?为什么它如此重要?

任何提示将不胜感激!非常感谢您的任何帮助

UDPATE:技术上的问题是 libusb 无法将模拟设备(USB/IP 枚举器)的父级识别为 HUB。这使得模拟设备由于 NULL 父级而被忽略。所以问题是如何修补 USB/IP 驱动程序以使 libusb 作为普通 USB HUB 可见

【问题讨论】:

【参考方案1】:

问题在于 USB/IP windows 驱动程序 v0.2.0.0 不回复 IRP_MN_QUERY_CAPABILITIES IRP。它仅调度针对模拟设备的IRP_MN_QUERY_CAPABILITIES,而不调度到总线驱动程序本身。 我已将 IRP_MN_QUERY_CAPABILITIES 处理添加到 USB/IP 驱动程序,现在它被 libusb 检测为普通 USB HUB 设备。

更新:

pnp.c方法内

 NTSTATUS Bus_FDO_PnP (
    __in PDEVICE_OBJECT       DeviceObject,
    __in PIRP                 Irp,
    __in PIO_STACK_LOCATION   IrpStack,
    __in PFDO_DEVICE_DATA     DeviceData )

我在switch (IrpStack->MinorFunction) 中添加了新的“案例”:

case IRP_MN_QUERY_CAPABILITIES:

    status = _PDO_QueryDeviceCaps(DeviceData, Irp);

    Irp->iostatus.Status = status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    Bus_DecIoCount(DeviceData);
    return status;

UPD2:还有这个:

NTSTATUS _PDO_QueryDeviceCaps(__in PFDO_DEVICE_DATA DeviceData, __in PIRP Irp)

PIO_STACK_LOCATION      stack;
PDEVICE_CAPABILITIES    deviceCapabilities;
DEVICE_CAPABILITIES     parentCapabilities;

PAGED_CODE();

stack = IoGetCurrentIrpStackLocation(Irp);
deviceCapabilities = stack->Parameters.DeviceCapabilities.Capabilities;

if (deviceCapabilities->Version != 1 || deviceCapabilities->Size < sizeof(DEVICE_CAPABILITIES))

    return STATUS_UNSUCCESSFUL;


deviceCapabilities->DeviceState[PowerSystemWorking] = PowerDeviceD0;

if (deviceCapabilities->DeviceState[PowerSystemSleeping1] != PowerDeviceD0)
    deviceCapabilities->DeviceState[PowerSystemSleeping1] = PowerDeviceD1;

if (deviceCapabilities->DeviceState[PowerSystemSleeping2] != PowerDeviceD0)
    deviceCapabilities->DeviceState[PowerSystemSleeping2] = PowerDeviceD3;

if (deviceCapabilities->DeviceState[PowerSystemSleeping3] != PowerDeviceD0)
    deviceCapabilities->DeviceState[PowerSystemSleeping3] = PowerDeviceD3;

deviceCapabilities->DeviceWake = PowerDeviceD1;

deviceCapabilities->DeviceD1 = TRUE; // Yes we can
deviceCapabilities->DeviceD2 = FALSE;

deviceCapabilities->WakeFromD0 = FALSE;
deviceCapabilities->WakeFromD1 = TRUE; 
deviceCapabilities->WakeFromD2 = FALSE;
deviceCapabilities->WakeFromD3 = FALSE;

deviceCapabilities->D1Latency = 0;
deviceCapabilities->D2Latency = 0;
deviceCapabilities->D3Latency = 0;

deviceCapabilities->EjectSupported = FALSE;
deviceCapabilities->HardwareDisabled = FALSE;
deviceCapabilities->Removable = TRUE;

deviceCapabilities->SurpriseRemovalOK = TRUE;
deviceCapabilities->UniqueID = FALSE;
deviceCapabilities->SilentInstall = FALSE;
deviceCapabilities->Address = 1;
deviceCapabilities->UINumber = 1;

return STATUS_SUCCESS;

【讨论】:

您愿意分享该更改的来源吗?一堆 USB 调试工具似乎无法使用 USB/IP,就像您的情况一样,我正在尝试使用它来模拟设备。 谢谢!这非常有帮助。 那是Bus_PDO_QueryDeviceCaps吗? 不,它是从 Bus_PnP() 调用的 Bus_FDO_PnP()。或者你是什么意思? status = _PDO_QueryDeviceCaps 的行。 _PDO_QueryDeviceCaps 定义了吗?

以上是关于libusb 未列出的 USB/IP 仿真设备的主要内容,如果未能解决你的问题,请参考以下文章

已安装 libusb - 但未找到 pyUSB 后端

如何最正确地使用 libusb 与连接的 USB 设备通信?

linux / libusb 获取usb设备路径

以非 root 用户身份使用 libusb-1.0 访问 USB 设备

通过 libusb 与 USB 设备通信的蛮力方法

在 QT 中使用 libusb 检测 MAC 上的 USB 设备