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 与连接的 USB 设备通信?