2015-09-25 2 views
1

Имеется инструмент USB/IP, который позволяет обмениваться доступом к устройствам USB через сеть TCP/IP. USB-устройство, подключенное к ПК Linux, на котором работает TCP-сервер и ПК с ОС Windows с драйвером VHCI, который подключается к Linux. Этот подход позволяет эмулировать любое устройство USB без оборудования вообще. Все, что вам нужно, это написать TCP-сервер, который будет обрабатывать запросы USB. (например, here)Эмулированное устройство USB/IP, не указанное libusb

Но проблема с этим, что эмулируемое устройство не совсем правильное. Когда вы попытаетесь перечислить подключенные USB-устройства с помощью libusb, вы получите сообщение об ошибке 'unlisted ancestor for ..', так как эмулированное устройство не имеет родителя в дереве устройств. С другой стороны некоторые инструменты, такие как Zadig показывают эмулируемое устройство.

Описанная проблема here и никакое реальное решение.

Вопрос в том, что это ошибка в драйвере USB/IP-драйверов? Может ли кто-нибудь, кто сталкивался с разработкой драйверов Windows, помогает? Что такое сделка с родительским устройством? Почему это так важно?

Любой намек будет очень оценен! Большое спасибо за любую помощь

UDPATE: технически проблема заключается в том, что родительский элемент эмулируемого устройства (перечислитель USB/IP), не признанный libusb как HUB. Это приводит к тому, что эмулированные устройства игнорируются из-за родителя NULL. Так вопрос в том, как пропатчить драйвер USB/IP, чтобы быть видимым libusb в обычном режиме USB HUB

ответ

1

Проблема заключалась в том, что драйвер USB/IP v0.2.0.0 окна не отвечает на IRP_MN_QUERY_CAPABILITIES МЦА. Он отправляет только 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; 
} 
+0

Не могли бы вы поделиться источником с этими изменениями? Куча средств отладки USB, похоже, не работает или не видит, как в вашем случае, с USB/IP, и я пытаюсь имитировать устройство с ним. – crazysim

+0

Спасибо! Это очень полезно. – crazysim

+0

Это 'Bus_PDO_QueryDeviceCaps'? – crazysim

Смежные вопросы