none
Simulating HID devices RRS feed

  • Question

  • I am trying to simulate( virtualize ) PnP of HID devices like USB mouse and keyboard with the help of a KMDF bus driver on Win 10(Universal/ Desktop)  and VS 2015. I am aware that if we create a PDO with properties like hardware id, compatible ids, etc and call

    WdfFdoAddStaticChild(), that will create the child device and start loading the corresponding driver and will start the PnP operation. I have done this using non HID USB devices like printers(USBCCGP.sys). But in the case of HID devices, the child device is created but the internal device control callback that starts the PNP sequence requesting further descriptors is not getting called. I have overridden this callback during PDO creation in the PDO queue. Below is the relevant code of how I am creating the bus in DeviceAdd and specifying the device interface in PDO creation.


    // Creating the bus FDO

    status = MyBusDriverQueueInitialize(device);
                if (NT_SUCCESS(status))
                {
                    // Set the Bus attributes for the child list.
                    busInformation.BusNumber = 0;
                    busInformation.LegacyBusType = PNPBus;
                    busInformation.BusTypeGuid = GUID_BUS_TYPE_USB;
                    WdfDeviceSetBusInformationForChildren(device, &busInformation);
                }
    
    Creating child PDO

    WDF_IO_QUEUE_CONFIG queueConfig; WDFQUEUE queue; WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE( &queueConfig, WdfIoQueueDispatchParallel ); queueConfig.EvtIoInternalDeviceControl = MyBBusDriverEvtIoInternalDeviceControl; WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&objectAttributes, PDO_DEVICE_DATA); status = WdfDeviceCreate(&pDeviceInit, &objectAttributes, &wdfChildDevice); if (!NT_SUCCESS(status)) { goto Cleanup; } // Create the IO queue for the child PDO. status = WdfIoQueueCreate(wdfChildDevice, &queueConfig, WDF_NO_OBJECT_ATTRIBUTES, &queue); if (!NT_SUCCESS(status)) { return status; } // Set the device interface as USB RtlInitUnicodeString(&referenceString, L"Interface Reference"); status = WdfDeviceCreateDeviceInterface(wdfChildDevice, (LPGUID) &GUID_DEVINTERFACE_USB_DEVICE, &referenceString); if (!NT_SUCCESS(status)) { goto Cleanup; } WdfDeviceSetDeviceInterfaceState(wdfChildDevice, (LPGUID) &GUID_DEVINTERFACE_USB_DEVICE, &referenceString, TRUE); // add power capabilities etc. ........ ......... ........ // Add the PDO to the collection of child devices. status = WdfFdoAddStaticChild(Device, wdfChildDevice); if (!NT_SUCCESS(status)) { goto Cleanup; }


    Is there any difference in the PnP operation of HID USB devices from that of non HID devices. I understand that on adding the child device there will be  a request for device descriptor using internal device control  followed by config descriptor etc. until the device is configured/ installed . What am I missing ? Should we mention interface GUIDs for mouse, keyboard etc. specifically instead of just USB device interface wile creating the PDO. I tried that for a test but doesn't solve my issue. A child device is created under the bus driver but is created with error that the driver for this child device is not loaded since the internal device control is not called. Is the driver to be loaded HID class driver like UsbCCGP.sys ?



    • Edited by its_me_here Friday, January 1, 2016 7:20 PM
    Friday, January 1, 2016 7:10 PM

Answers

  • there should be nothing different for HIDs. BUT if your goal is to enumerate HIDs on the system, you don't need to simulate USB. you can write your own very simple HID miniport  and remove USB simulation all together.

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Saturday, January 2, 2016 12:57 AM

All replies

  • there should be nothing different for HIDs. BUT if your goal is to enumerate HIDs on the system, you don't need to simulate USB. you can write your own very simple HID miniport  and remove USB simulation all together.

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Saturday, January 2, 2016 12:57 AM
  • Thank you Doron. I shall definitely look into writing the miniport. But I have already done a KMDF bus driver that simulates USB devices and I was hoping to reuse that here by providing the descriptors etc. of the HID device. Isnt that also possible? If that's possible, naturally, one should get the internal device control that should be called on creating the PDO
    . This way I can simulate both USB devices and HID devices using one bus driver.
    • Edited by its_me_here Saturday, January 2, 2016 5:47 AM
    Saturday, January 2, 2016 5:44 AM
  • beyond the device interface guids and the IOCTLs, are you also handling the various IRP_MN_QUERY_INTERFACE related interfaces that the usb stack exposes?

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Saturday, January 2, 2016 7:41 AM
  • Thanks Doron. I am not handling IRP_MN_QUERY_INTERFACE now. I didn't have to handle It in the case of the KMSF bus driver I did for USB devices, and I was able configure/install virtual USB devise using this bus driver. I shall look into this IRP.
    Sunday, January 3, 2016 5:37 PM
  • the docs for IRP_MN_QUERY_INTERFACE are generic. the usb specific ones are listed under https://msdn.microsoft.com/en-us/library/windows/hardware/ff540160(v=vs.85).aspx ... all start with USB_BUS_Xxxx

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Monday, January 4, 2016 7:50 AM
  • Thank you Doron. I went through the link.   But I think I can take a look at the miniport driver as you suggested. I found that we will have to handle IOCTL_HID_GET_DEVICE_DESCRIPTOR , IOCTL_HID_GET_REPORT_DESCRIPTOR etc. as is illustrated in the hidusbfx2 sample in WDK. This requires a WDM driver which will be the FDO  and a KMDF filter driver. But I was also wondering if I could get the above IOCTLs directly in a bus driver.
    Monday, January 11, 2016 7:16 PM
  • you could eliminate the KMDF filter driver and handle the IOCTLs directly in the PDO. this in effect means the PDO is the HID implementation for the device.

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Monday, January 11, 2016 7:48 PM
  • Thank you Doron.  According to the HID spec, whether a device is an HID device is decided by the interface descriptor ( bInterfaceClass:      0x03 (HID )and not device descriptor. Hope this could be a lead. But HID spec also says that there can be HID devices with more than one interface. In this case,do we need to consider all the interfaces in order to first start the PnP?


    • Edited by its_me_here Tuesday, January 12, 2016 4:57 PM
    Tuesday, January 12, 2016 4:46 PM
  • I don't understand the question. the HID spec delineates exactly what you need to report

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Tuesday, January 12, 2016 8:16 PM
  • Thank you Doron. What I meant is, since  we can identify a HID device by its interface descriptor, as the spec says, I can create the PDO of the bus by specifiying hardware ids, compat ids , and also the class, subclass values of the interface descriptor. This way I am able to get further descriptor request like device descriptor. Earlier I was giving the class, subclass values in the device descriptor which seemed to be the issue. Now, if an HID device has more than one interface, then all the individual interfaces will have to be given.  So my question is , in order to start the PnP of such a device will we have to inspect all interface descriptors and check if the interfaceclass value is 3( so that PnP manager understands that an HID device has arrived) and then add the class, subclass values of each interface to PDO ? I need to know if there could be some other means to handle this situation in the case of HID devices with more than one interface.

    • Edited by its_me_here Wednesday, January 13, 2016 6:21 PM
    Wednesday, January 13, 2016 6:20 PM
  • you are really asking how you reimplement the generic parent driver (usbccgp.sys), nothing that you described is specific to HID, it is just a compound device problem.

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Wednesday, January 13, 2016 6:53 PM