Fixing HID Keyboard Quirks 2

Hello List,

i am trying to write a filter driver for an apple keyboard to change some keycodes (see “fixing hid keyboard quirks”). Mr. Oney suggested using a lower filter driver to HIDUSB, and judging from its inf file apple did this, too.
Based on toaster’s filter sourcecode i added code to handle the Internal Device Control message.
In this dispatch function i have access to the urb via pIrp->Parameters.Others.Argument1.
The urb’s TransferBuffer(pointer) is equal to pIrp->UserBuffer, it holds the hid data i am looking for. Changing the buffers values here seems to have no effect.
So i register a Completionroutine (copy-paste from DeviceUsageNotificationCompletionRoutine), wherein i change the values in pIrp->Userbuffer. This works, but not as expected: if i press the key to be replaced, nothing happens. If i press any other key afterwards, that key gets replaced. Why? And how can i fix that?
Thanks,
Lenard Wiedenroth

post the code in your completion routine which modifies the data

d

Sent from my phone with no t9, all spilling mistakes are not intentional.

-----Original Message-----
From: xxxxx@wiedenroth.org
Sent: Sunday, June 21, 2009 1:29 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Fixing HID Keyboard Quirks 2

Hello List,

i am trying to write a filter driver for an apple keyboard to change some keycodes (see “fixing hid keyboard quirks”). Mr. Oney suggested using a lower filter driver to HIDUSB, and judging from its inf file apple did this, too.
Based on toaster’s filter sourcecode i added code to handle the Internal Device Control message.
In this dispatch function i have access to the urb via pIrp->Parameters.Others.Argument1.
The urb’s TransferBuffer(pointer) is equal to pIrp->UserBuffer, it holds the hid data i am looking for. Changing the buffers values here seems to have no effect.
So i register a Completionroutine (copy-paste from DeviceUsageNotificationCompletionRoutine), wherein i change the values in pIrp->Userbuffer. This works, but not as expected: if i press the key to be replaced, nothing happens. If i press any other key afterwards, that key gets replaced. Why? And how can i fix that?
Thanks,
Lenard Wiedenroth


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

NTSTATUS CompleteIDC( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
{
PDEVICE_EXTENSION deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

PBYTE buffer = (PBYTE)Irp->UserBuffer;
BYTE KeyVal = (BYTE)Context;

if( KeyVal != 0x00 )
buffer[2] = KeyVal;

if (Irp->PendingReturned) {
IoMarkIrpPending(Irp);
}
if (!(deviceExtension->NextLowerDriver->Flags & DO_POWER_PAGABLE)) {
DeviceObject->Flags &= ~DO_POWER_PAGABLE;
}
IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp);

return STATUS_CONTINUE_COMPLETION;
}

Do you always set the context to a non zero value? Under what conditions would it change? Also since you are filtering usb traffic, it would probably be more resilient long term to pull the buffer out of the urb vs UserBuffer which is a hidclass quirk.

Btw all of this is not needed in the io path

if (Irp->PendingReturned) {
IoMarkIrpPending(Irp);
}
if (!(deviceExtension->NextLowerDriver->Flags & DO_POWER_PAGABLE)) {
DeviceObject->Flags &= ~DO_POWER_PAGABLE;
}

d

Sent from my phone with no t9, all spilling mistakes are not intentional.

-----Original Message-----
From: xxxxx@wiedenroth.org
Sent: Sunday, June 21, 2009 2:08 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Fixing HID Keyboard Quirks 2

NTSTATUS CompleteIDC( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
{
PDEVICE_EXTENSION deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

PBYTE buffer = (PBYTE)Irp->UserBuffer;
BYTE KeyVal = (BYTE)Context;

if( KeyVal != 0x00 )
buffer[2] = KeyVal;

if (Irp->PendingReturned) {
IoMarkIrpPending(Irp);
}
if (!(deviceExtension->NextLowerDriver->Flags & DO_POWER_PAGABLE)) {
DeviceObject->Flags &= ~DO_POWER_PAGABLE;
}
IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp);

return STATUS_CONTINUE_COMPLETION;
}


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Depending on the key combinations the Context value can be zero, but only in this quick’n’dirty code. The context value holds the USB scancode of the replacement key, so it changes when other keys are pressed. I get these from an array whose index is the original scancode and the value is the replacement scancode. Right now most of the values are zeroes, ie. “don’t change”.
I changed the code, but it still triggers on the second keypress only:

NTSTATUS CompleteIDC( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
{
PDEVICE_EXTENSION deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
PBYTE buffer = (PBYTE)((PURB)stack->Parameters.Others.Argument1)
->UrbBulkOrInterruptTransfer.TransferBuffer;

BYTE KeyVal = (BYTE)Context;

if( KeyVal != 0x00 )
buffer[2] = KeyVal;

IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp);

return STATUS_CONTINUE_COMPLETION;
}