libusb

时间:2015-09-25 06:46:20

标签: ip usb

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

1 个答案:

答案 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;
}