How to alter a HID report in a filter driver

Dear,

I started developping a lower filter for a mouse device, thanks to advices picked from this thread I posted a week ago :

http://social.msdn.microsoft.com/Forums/en/wdk/thread/8159c403-283a-46d7-9418-a591639e1b6f

I went for the lower filter as it seemed to be simpler to me for now, due to my little understanding of the framework. I started from the filter toaster sample.

For the moment, I’m simply trying to invert left/right click by altering a HID report. Presently I’m doing the following :

  • Registering EvtIoRead in the default queue : ioQueueConfig.EvtIoRead = FilterEvtIoRead;

  • Printing the request buffer content, then trying to alter the buffer content, then printing the new buffer :

typedef struct __MOUSE_REPORT
{
unsigned char a;
unsigned char b;
unsigned char c;
unsigned char d;
unsigned char e;
unsigned char f;
unsigned char g;
}
MOUSE_REPORT, *PMOUSE_REPORT;

/* … */

VOID
FilterEvtIoRead (
IN WDFQUEUE Queue,
IN WDFREQUEST Request,
IN size_t Length
)
{
NTSTATUS status = STATUS_SUCCESS;
WDFDEVICE device;
PMOUSE_REPORT buffer;

UNREFERENCED_PARAMETER(Queue);
UNREFERENCED_PARAMETER(Request);
UNREFERENCED_PARAMETER(Length);

device = WdfIoQueueGetDevice(Queue);

// Get buffer out of WDFREQUEST
status = WdfRequestRetrieveOutputBuffer(Request,
sizeof(MOUSE_REPORT),
&buffer,
NULL);

if(!NT_SUCCESS(status)){
KdPrint((“WdfRequestRetrieveInputBuffer failed %x\n”, status));
}

KdPrint((“IoRead \t\t– %x %x %x %x %x %x %x\n”, buffer->a, buffer->b, buffer->c, buffer->d, buffer->e, buffer->f, buffer->g));

// Alter buffer : left click <-> right click.
if(buffer->b == 1)
buffer->b = 2;
else if(buffer->b == 2)
buffer->b = 1;

KdPrint((“IoRead ALT \t– %x %x %x %x %x %x %x\n”, buffer->a, buffer->b, buffer->c, buffer->d, buffer->e, buffer->f, buffer->g));

if (!NT_SUCCESS(status)) {
WdfRequestComplete(Request, status);
return;
}

FilterForwardRequest(Request, WdfDeviceGetIoTarget(device));
}

The initial buffer is precisely what I except it to be, ie. the HID report sent by the mouse. However, the way I modify it does not change anything to the way the mouse works. I suspect I’m modifying a temporary buffer.

Could you please tell me what’s the correct way to do this job ?

Best regards,

xxxxx@gmail.com wrote:

I started developping a lower filter for a mouse device, thanks to advices picked from this thread I posted a week ago :

http://social.msdn.microsoft.com/Forums/en/wdk/thread/8159c403-283a-46d7-9418-a591639e1b6f

I went for the lower filter as it seemed to be simpler to me for now, due to my little understanding of the framework. I started from the filter toaster sample.

For the moment, I’m simply trying to invert left/right click by altering a HID report. Presently I’m doing the following :

  • Registering EvtIoRead in the default queue : ioQueueConfig.EvtIoRead = FilterEvtIoRead;

  • Printing the request buffer content, then trying to alter the buffer content, then printing the new buffer :

    The initial buffer is precisely what I except it to be, ie. the HID report sent by the mouse. However, the way I modify it does not change anything to the way the mouse works. I suspect I’m modifying a temporary buffer.

You are changing the output buffer in a read request before any other
driver has had a chance to handle the request. At that point, there’s
nothing in the output buffer. What you are probably seeing in the
buffer is just left over from some previous request.

You need to forward the request to the next driver, with a completion
routine that calls you back when the request has actually been handled.
THEN you can modify the output buffer.

When you are handling a request, you ALWAYS need to bear in mind which
direction it is going. Is this going DOWN the stack, or is it coming
back UP the stack?


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

1 Like

So I guess I’ll need to use something like :
FilterForwardRequestWithCompletionRoutine(…).

Thank for your advice.

However, would you mind telling me or pointing any article that would explain me the classic path HID requests/reports will follow ?

In my mouse firmware, I’m just sending reports from the mouse to the computer (using the HID usb stack). From the computer point of view, I though the data was only going from the bottom of the stack to the top, then user mode ?

Thank you !

xxxxx@gmail.com wrote:

So I guess I’ll need to use something like :
FilterForwardRequestWithCompletionRoutine(…).

Thank for your advice.

However, would you mind telling me or pointing any article that would explain me the classic path HID requests/reports will follow ?

In my mouse firmware, I’m just sending reports from the mouse to the computer (using the HID usb stack). From the computer point of view, I though the data was only going from the bottom of the stack to the top, then user mode ?

IRPs never go from the bottom up. All I/O requests in Windows start at
the top and go down the stack until they are handled, then they bubble
back up.

Also, USB devices never transmit data on their own. It’s not allowed
USB is a master/slave bus, entirely driven by the host. The only time
your device is allowed to send anything is when the host controller asks
it to. The host controller will only do so if it has a request from
some upper level driver.


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

Everything’s clear. Working perfectly !
Thanks a lot for your help, this was precise and begginer friendly.

Best regards,