Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results


More Info on Driver Writing and Debugging

The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.

Check out The OSR Learning Library at:

Before Posting...

Please check out the Community Guidelines in the Announcements and Administration Category.

Inject additional IPRs in lower filter driver

pwillypwilly Member Posts: 16

We have a well working LowerFilter HIDclass filter driver.

For various reasons we like to inject additional IRPs on the way up to the HIDclass driver, for example to simulate momentum scrolling or a mouse button lift.

Right now we park one IRP and complete it when needed. But if we park more than one IRP the device doesn't work any more as we don't get any new IRPs in, so this is a doggy solution.

Is it somehow possible to inject additional IRPs on the way up? What would be the best way to do this?

If it's not possible would it be possible to redirect IRPs from the PDO sideband communication into the actual device stream? How could this be done?

Any guidance is appreciated.


  • pwillypwilly Member Posts: 16

    Well, I used the wrong terminology in my question. Of course I mean a WDF-Request, not an IPR.

  • Doron_HolanDoron_Holan Member - All Emails Posts: 10,612
    If you want to inject keyboard and mouse packets in a simple way you are too far down in the stack. Instead you should be a device upper filter in the hid keyboard and mouse stacks and you can easily inject data via the service callback without messing around with io requests.

    The only effective way to IMMEDIATELY inject as a lower filter below the mini port is to
    1 send you own requests down to the hardware
    2 when the hw request completes if there are no queued hid requests, queue the data. If there are pended hid requests, complete one with the data
    3 for incoming hid requests, if there is queued data, complete it with the data. If no data is queued, queue the request
    4 When you want to inject data, complete the pended hid request with it. If no pended hid request, queue the data and add logic to 3 to check for it.
  • pwillypwilly Member Posts: 16

    Thanks Doran, your help is much appreciated.

    The lower filter driver has to be in place to make the raw input stream HID compliant, there is no way around this.

    Using an additional upper filter driver would require syncing both drivers (injecting the additional input at the right time).

    Not sure what is wiser in terms of maintenance and complexity:

    • Having two different drivers and syncing both with some kind of inter-driver-communication.

    • Have only the lower filter driver and sending down WDF requests to the hardware as Doran suggests.

  • Doron_HolanDoron_Holan Member - All Emails Posts: 10,612
    IMHO one driver working on its own is far simpler than two drivers trying to coordinate state.
  • pwillypwilly Member Posts: 16

    Thanks again Doran. My gut feeling tells me that as well. Will try to stay with the one lower filter driver.

    One more question about sending down my own requests to the hardware, as there isn't much in the documentation. Is this correct:

    1. Create my own requests with WdfRequestCreateFromIrp() using a IRP from the HID request,
    2. Send it down to the hardware with my own completion routine.
    3. In the completion routine, buffer the data and then use WdfObjectDelete().
    4. Copy the data into the initial HID request and call WdfRequestComplete() for the HID request.

    Or in 1. must I use WdfRequestCreate() to built the request from scratch?

  • Doron_HolanDoron_Holan Member - All Emails Posts: 10,612

    Is this a USB device? If so, your implementation will be much simpler as you can use the continuous reader functionality in WDFUSBPIPE, . The trick as a lower filter is create the WDFUSBDEVICE with the select config that is sent down by hidclass and not selecting a config on your own.

    If you are not controlling a usb device, step one is to create your own request (or perhaps 2) and start sending it in EvtDeviceSelfManagedIoInit. When the request completes, your simplest choice is to reuse the request (WdfRequestReuse), not delete it. In the completion routine, you check to see if you have a queued HID request from above. If yes, copy the data and complete it. If there is no queued HID request from above, you must copy the data into your own storage and then when the hid request from above arrives, copy the data into it in the dispatch routine

  • pwillypwilly Member Posts: 16

    It's a hybrid device: USB or Bluetooth, the user can choose what connection to use. The filter driver handles the URB and BRB processing currently in a very similar way. There is unfortunately no Bluetooth continuous reader, but we'll figure it out, if you have a link to some example code that would be great (haven't search for it yet).

    Again thanks for all your advice, it really helps a lot.

  • Doron_HolanDoron_Holan Member - All Emails Posts: 10,612

    I can't think of a good continuous reader example on which you can start from. You should use a WDFQUEUE to pend all of the upper HID requests that are sent to your driver.

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Upcoming OSR Seminars
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead!
Developing Minifilters 24 May 2021 Live, Online
Writing WDF Drivers 14 June 2021 Live, Online
Internals & Software Drivers 27 September 2021 Live, Online
Kernel Debugging 15 November 2021 Live, Online