Keyboard input packet misses

Hi,

I’m verifying an application to retrieve a keyboard input from a WDF keyboard class upper filter driver. The application calls an overlapped ReadFile request to the driver and calls GetOverlappedResult to wait for the result. The driver pushes the read request to a manual queue and retrieves the request from the queue and completes the request when its service callback function is called. Once the application returns from calling GetOverlappedResult, it calls ReadFile again to retrieve the next keyboard input packet.

The result indicates that the application misses some keyboard input packets. It’s easily observed if I pressed two different buttons in turn fastly. The driver retrieves the request from the manual queue. If the queue is empty, it handles the next packet so the application may misses this packet.

The problem is that I don’t know how to fix this issue. Should I have a input data queue to queue up the packet if the queue is empty? Or is there any framework wide machanism available to avoid this happen?

Thanks,
Marshall

> The problem is that I don’t know how to fix this issue. Should I have a input data queue to queue up

the packet if the queue is empty?

Yes.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

When there is no read request to complete, do you want the keyboard data to still be reported to the system ? Also, send down more than one read at a time

d

debt from my phone


From: xxxxx@hotmail.com
Sent: 12/1/2011 1:49 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Keyboard input packet misses

Hi,

I’m verifying an application to retrieve a keyboard input from a WDF keyboard class upper filter driver. The application calls an overlapped ReadFile request to the driver and calls GetOverlappedResult to wait for the result. The driver pushes the read request to a manual queue and retrieves the request from the queue and completes the request when its service callback function is called. Once the application returns from calling GetOverlappedResult, it calls ReadFile again to retrieve the next keyboard input packet.

The result indicates that the application misses some keyboard input packets. It’s easily observed if I pressed two different buttons in turn fastly. The driver retrieves the request from the manual queue. If the queue is empty, it handles the next packet so the application may misses this packet.

The problem is that I don’t know how to fix this issue. Should I have a input data queue to queue up the packet if the queue is empty? Or is there any framework wide machanism available to avoid this happen?

Thanks,
Marshall


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

Hi Doron,

When there is no read request to complete, I DON’T want the keyboard data to
still be reported to the system. In this case, per my observation, the service callback will resend the packet if I don’t return the total number of the InputDataCurrent - InputDataStart, right?

The code of the service callback function is as below:

VOID
RzKbd_ServiceCallback(
IN PDEVICE_OBJECT DeviceObject,
IN PKEYBOARD_INPUT_DATA pInputDataStart,
IN PKEYBOARD_INPUT_DATA pInputDataEnd,
IN OUT PULONG pInputDataConsumed
)
{
… …
do
{
if (bInputRedirect == TRUE)
{
status = RzKbd_ProcessReadRequest(Device, pCurrentInput);
IfFailGoToExit(status, RZ_KBD_INPUT, L"RzKbd_ProcessReadRequest failed");
}
else
{
(*(PSERVICE_CALLBACK_ROUTINE)(ULONG_PTR)pDeviceContext->UpperConnectData.ClassService)(
pDeviceContext->UpperConnectData.ClassDeviceObject,
pCurrentInput,
pCurrentInput + 1,
&ulConsumed
);
}

pCurrentInput++;

} while (pCurrentInput < pInputDataEnd);

Exit:
//
// Tell the Win32 subsystem the number of the consumed packets.
// The kernel will resend the rest packets if the number does
// equal to the pInputDataEnd - pInputDataStart.
//
*pInputDataConsumed = (ULONG)(ULONG_PTR)(pCurrentInput - pInputDataStart);

RzFilterTraceFuncExit();
}

Can you see anything wrong here? Or I will have to send more than one read request one time?

Thanks,
Marshall

The ps2 stack will reinvoke the callback later and has queue of unreported input packets that it keeps for this purpose. The hid stack does not have such a queue. It might invoke a timer to call into the callback later, might not. But even if it does, it doesn’t have a queue of packets to report so you will probably permanently miss input. If you don’t have a read, you should have your own queue of inputs and put the input into it and indicate to the lower driver that the input was consumed. You then process that queued input when receive a new read request

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@hotmail.com
Sent: Thursday, December 01, 2011 3:33 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Keyboard input packet misses

Hi Doron,

When there is no read request to complete, I DON’T want the keyboard data to still be reported to the system. In this case, per my observation, the service callback will resend the packet if I don’t return the total number of the InputDataCurrent - InputDataStart, right?

The code of the service callback function is as below:

VOID
RzKbd_ServiceCallback(
IN PDEVICE_OBJECT DeviceObject,
IN PKEYBOARD_INPUT_DATA pInputDataStart,
IN PKEYBOARD_INPUT_DATA pInputDataEnd,
IN OUT PULONG pInputDataConsumed
)
{
… …
do
{
if (bInputRedirect == TRUE)
{
status = RzKbd_ProcessReadRequest(Device, pCurrentInput);
IfFailGoToExit(status, RZ_KBD_INPUT, L"RzKbd_ProcessReadRequest failed");
}
else
{
(*(PSERVICE_CALLBACK_ROUTINE)(ULONG_PTR)pDeviceContext->UpperConnectData.ClassService)(
pDeviceContext->UpperConnectData.ClassDeviceObject,
pCurrentInput,
pCurrentInput + 1,
&ulConsumed
);
}

pCurrentInput++;

} while (pCurrentInput < pInputDataEnd);

Exit:
//
// Tell the Win32 subsystem the number of the consumed packets.
// The kernel will resend the rest packets if the number does
// equal to the pInputDataEnd - pInputDataStart.
//
*pInputDataConsumed = (ULONG)(ULONG_PTR)(pCurrentInput - pInputDataStart);

RzFilterTraceFuncExit();
}

Can you see anything wrong here? Or I will have to send more than one read request one time?

Thanks,
Marshall


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