有USB/IP工具允许通过TCP / IP网络共享USB设备。 USB设备连接到运行TCP服务器的Linux PC和运行连接到Linux的VHCI驱动程序的Windows PC。 这种方法可以在没有硬件的情况下模拟任何USB设备。您只需编写TCP服务器即可处理USB请求。 (如here)
但是模拟设备的问题并不正确。当您尝试使用 libusb 列出已连接的USB设备时,您将收到错误的'未列出的祖先...' ,因为模拟设备没有设备树中的父级。 另一方面,像Zadig这样的工具会显示模拟设备。
正好讨论了问题here并且没有提供真正的解决方案。
所以问题是USB / IP Windows驱动程序中的错误?有没有经验丰富的Windows驱动程序开发有帮助?关于父设备的交易是什么?为什么这么重要?
任何提示都将非常感激!非常感谢您提供任何帮助
UDPATE:技术问题是libusb无法将仿真设备(USB / IP枚举器)的父节点识别为HUB。这使得模拟设备因NULL父项而被忽略。所以问题是如何修补USB / IP驱动程序,以便libusb将其视为普通的USB HUB
答案 0 :(得分: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设备。
UPD:
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;
}