HID Lower Filter AND Upper Filter

Hi, I’m in the process of writing a filter driver for an HID mouse. I’d
like the filter driver to be able to intercept mouse motion and button
events and either alter them, or eat the events and generate a series of
new events instead. I have everything pretty much working in my mouclass
upper filter driver. The problem is my mouse has more than 5 buttons.
Thus, when I receive the MOUSE_INPUT_DATA data structures in the
MouseClassServiceCallback, I can only see when buttons 1-5 fire. I.e. the
ButtonFlags member of the MOUSE_INPUT_DATA struct only defines mouse button
flags for buttons 1-5. I realize userspace will never see an event when I
press button 6, 7, etc. on my mouse. But as an example, I’d like my driver
to be able intercept button 6, and then generate double left-click, or some
other series of mouse events.

So next I tried writing a mouhid lower filter driver that can intercept the
raw HID data in a EvtIoRead completion routine. At this level, I can see
when all the mouse buttons fire. However, it seems non-trivial to inject
new mouse events as a lower filter driver.

Then I thought perhaps I could load both the lower filter driver and the
upper filter driver at the same time. The lower filter driver would
capture all the mouse button events and then forward them to the upper
filter driver via an IO target. However, it doesn’t seem possible to have
both the lower filter and upper filter drivers loaded at the same time.

Does anyone have any advice on how to solve this problem? I know it’s
technically possible to create new mouse events as a mouhid lower filter
driver, but I was hoping there was an easier way. Is there an easy way to
call the system MouseClassServiceCallback from a mouhid lower filter? Or
what if I install my driver as a lower filter to MsHidKmdf. Would it be
easier to intercept and generate new mouse events there?

Thanks,
Tom

Tom Panfil wrote:

So next I tried writing a mouhid lower filter driver that can
intercept the raw HID data in a EvtIoRead completion routine. At this
level, I can see when all the mouse buttons fire. However, it seems
non-trivial to inject new mouse events as a lower filter driver.

That’s not hard. If you see one real event that needs to generate
multiple fake events, you just return the first event, and remember in
your context the list of pending fake events. The next time you see a
read request, you immediately return your next fake event instead of
forwarding the request down. Once you run out of pending fake events,
you send the request along as normal.

I just did this for a bar code scanner that needed a “back door” for
generating fake events.

Then I thought perhaps I could load both the lower filter driver and
the upper filter driver at the same time. The lower filter driver
would capture all the mouse button events and then forward them to the
upper filter driver via an IO target. However, it doesn’t seem
possible to have both the lower filter and upper filter drivers loaded
at the same time.

It certainly is possible to have a single driver act as lower and upper
filter, although you get two separate instances. I’ve done it. I’m not
sure it’s necessary here, however.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Thanks Tim! Your response is a big help. I didn’t realize you can install the same driver as an upper and lower filter. I’m going to try that approach first as I already have the upper filter almost fully implemented.

Tom