Hello,

I'm new to driver development, in fact I have never written
a real mode sys file nor a driver. Now I have to accomplish the following
task:
A program generates virtual key events to control a directx game.
Because directx directly reads out the keyboard I can't simply use the
WinAPI keybd_event or a simple SendKeys function. So the best way
seems to be to send the keystrokes from my application (can be delphi, c++
or vb)
to the keyboard filter driver that creates the keystroke.

Therefore I register a new keyboardchain filter KbdFilterInit

Then I'd like to feed keys into the keyboard chain to simulate button press
events. Therefore I create KeyData packets.

To process the keyboard chain I implement proper dispatch
function for reading
NTSTATUS
KbdDispatchRead(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)

So my questions are:
Is there already something similar out there that I can use?
Is it possible to create such a driver file without getting 1000s of
blue screens?
What's the easiest way to do this.
How can I send some bytes from my app to the driver? (My app tells the
driver to generate an 'F1' keystroke...)
Is my theory correct?

I hope to get some help from you.
Thanks for any hints
Mel

NTSTATUS
KbdFilterInit(
IN PDRIVER_OBJECT DriverObject
)
/*++

Routine Description:

Create a device object and attaches it to the
first keyboard device chain

Arguments:

DeviceObject - pointer to a device object.

Return Value:

NT Status code

--*/


{
UNICODE_STRING ntUnicodeString;
NTSTATUS ntStatus;
PDEVICE_OBJECT DeviceObject = NULL;

//
// Only hook onto the first keyboard's chain.
//
RtlInitUnicodeString( &ntUnicodeString, L"\\Device\\KeyboardClass0" );
//
// Create device object for the keyboard.
//
ntStatus = IoCreateDevice( DriverObject,
0,
NULL,
FILE_DEVICE_KEYBOARD,
0,
FALSE,
&DeviceObject );

if( !NT_SUCCESS(ntStatus) ) {
JKBD_DbgPrint(("JKBD: Keyboard hook failed to create device!\n"));
return ntStatus;
}
//
// Keyboard uses buffered I/O so we must as well.
//
DeviceObject->Flags |= DO_BUFFERED_IO;
//
// Attach to the keyboard chain.
//
ntStatus = IoAttachDevice( DeviceObject, &ntUnicodeString,
&pGlobalDevExt->KbdDevice );
if( !NT_SUCCESS(ntStatus) ) {
JKBD_DbgPrint(("JKBD: Connect with keyboard failed!\n"));
IoDeleteDevice( DeviceObject );
return ntStatus;
}
pGlobalDevExt->KbdFilterDevice = DeviceObject;

return STATUS_SUCCESS;
}



//
// Create a keyboard packet
//
KeyData = pGlobalDevExt->RawKbdIrp->AssociatedIrp.SystemBuffer;

RtlZeroMemory(KeyData, 2*sizeof(KEYBOARD_INPUT_DATA));
KeyData[numKeys].Flags = 0; //down
KeyData[numKeys+1].Flags = 1; //up
KeyData[numKeys].MakeCode = 0x1e; // character a
KeyData[numKeys+1].MakeCode = 0x1e; // character a
numKeys += 2;
KeyData += numKeys*sizeof(KEYBOARD_INPUT_DATA);
pGlobalDevExt->RawKbdIrp->IoStatus.Status = STATUS_SUCCESS;
pGlobalDevExt->RawKbdIrp->IoStatus.Information =
numKeys*sizeof(KEYBOARD_INPUT_DATA);
pGlobalDevExt->RawKbdIrpPending = FALSE;
IoCompleteRequest(pGlobalDevExt->RawKbdIrp, IO_KEYBOARD_INCREMENT);

Re: Keyboard filter to simulate keys by Arkady

Arkady
Tue Sep 21 07:36:37 CDT 2004

Look at DDK\DDKXP\src\input\kbfiltr example and how
app talk to driver with IOCTL (
http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q262305 )
Arkady

"Mel" <Mel_Olonsky@gmx.net> wrote in message
news:ufHn2H9nEHA.3224@tk2msftngp13.phx.gbl...
> Hello,
>
> I'm new to driver development, in fact I have never written
> a real mode sys file nor a driver. Now I have to accomplish the following
> task:
> A program generates virtual key events to control a directx game.
> Because directx directly reads out the keyboard I can't simply use the
> WinAPI keybd_event or a simple SendKeys function. So the best way
> seems to be to send the keystrokes from my application (can be delphi, c++
> or vb)
> to the keyboard filter driver that creates the keystroke.
>
> Therefore I register a new keyboardchain filter KbdFilterInit
>
> Then I'd like to feed keys into the keyboard chain to simulate button
press
> events. Therefore I create KeyData packets.
>
> To process the keyboard chain I implement proper dispatch
> function for reading
> NTSTATUS
> KbdDispatchRead(
> IN PDEVICE_OBJECT DeviceObject,
> IN PIRP Irp
> )
>
> So my questions are:
> Is there already something similar out there that I can use?
> Is it possible to create such a driver file without getting 1000s of
> blue screens?
> What's the easiest way to do this.
> How can I send some bytes from my app to the driver? (My app tells the
> driver to generate an 'F1' keystroke...)
> Is my theory correct?
>
> I hope to get some help from you.
> Thanks for any hints
> Mel
>
> NTSTATUS
> KbdFilterInit(
> IN PDRIVER_OBJECT DriverObject
> )
> /*++
>
> Routine Description:
>
> Create a device object and attaches it to the
> first keyboard device chain
>
> Arguments:
>
> DeviceObject - pointer to a device object.
>
> Return Value:
>
> NT Status code
>
> --*/
>
>
> {
> UNICODE_STRING ntUnicodeString;
> NTSTATUS ntStatus;
> PDEVICE_OBJECT DeviceObject = NULL;
>
> //
> // Only hook onto the first keyboard's chain.
> //
> RtlInitUnicodeString( &ntUnicodeString, L"\\Device\\KeyboardClass0" );
> //
> // Create device object for the keyboard.
> //
> ntStatus = IoCreateDevice( DriverObject,
> 0,
> NULL,
> FILE_DEVICE_KEYBOARD,
> 0,
> FALSE,
> &DeviceObject );
>
> if( !NT_SUCCESS(ntStatus) ) {
> JKBD_DbgPrint(("JKBD: Keyboard hook failed to create device!\n"));
> return ntStatus;
> }
> //
> // Keyboard uses buffered I/O so we must as well.
> //
> DeviceObject->Flags |= DO_BUFFERED_IO;
> //
> // Attach to the keyboard chain.
> //
> ntStatus = IoAttachDevice( DeviceObject, &ntUnicodeString,
> &pGlobalDevExt->KbdDevice );
> if( !NT_SUCCESS(ntStatus) ) {
> JKBD_DbgPrint(("JKBD: Connect with keyboard failed!\n"));
> IoDeleteDevice( DeviceObject );
> return ntStatus;
> }
> pGlobalDevExt->KbdFilterDevice = DeviceObject;
>
> return STATUS_SUCCESS;
> }
>
>
>
> //
> // Create a keyboard packet
> //
> KeyData = pGlobalDevExt->RawKbdIrp->AssociatedIrp.SystemBuffer;
>
> RtlZeroMemory(KeyData, 2*sizeof(KEYBOARD_INPUT_DATA));
> KeyData[numKeys].Flags = 0; //down
> KeyData[numKeys+1].Flags = 1; //up
> KeyData[numKeys].MakeCode = 0x1e; // character a
> KeyData[numKeys+1].MakeCode = 0x1e; // character a
> numKeys += 2;
> KeyData += numKeys*sizeof(KEYBOARD_INPUT_DATA);
> pGlobalDevExt->RawKbdIrp->IoStatus.Status = STATUS_SUCCESS;
> pGlobalDevExt->RawKbdIrp->IoStatus.Information =
> numKeys*sizeof(KEYBOARD_INPUT_DATA);
> pGlobalDevExt->RawKbdIrpPending = FALSE;
> IoCompleteRequest(pGlobalDevExt->RawKbdIrp,
IO_KEYBOARD_INCREMENT);
>
>
>



Re: Keyboard filter to simulate keys by Doron

Doron
Tue Sep 21 10:23:32 CDT 2004

which OS do you need this to work on? if it is win2k and forward, you can
just use SendInput() from user mode.

d

--
Please do not send e-mail directly to this alias. this alias is for
newsgroup purposes only.
This posting is provided "AS IS" with no warranties, and confers no rights.


"Mel" <Mel_Olonsky@gmx.net> wrote in message
news:ufHn2H9nEHA.3224@tk2msftngp13.phx.gbl...
> Hello,
>
> I'm new to driver development, in fact I have never written
> a real mode sys file nor a driver. Now I have to accomplish the following
> task:
> A program generates virtual key events to control a directx game.
> Because directx directly reads out the keyboard I can't simply use the
> WinAPI keybd_event or a simple SendKeys function. So the best way
> seems to be to send the keystrokes from my application (can be delphi, c++
> or vb)
> to the keyboard filter driver that creates the keystroke.
>
> Therefore I register a new keyboardchain filter KbdFilterInit
>
> Then I'd like to feed keys into the keyboard chain to simulate button
> press
> events. Therefore I create KeyData packets.
>
> To process the keyboard chain I implement proper dispatch
> function for reading
> NTSTATUS
> KbdDispatchRead(
> IN PDEVICE_OBJECT DeviceObject,
> IN PIRP Irp
> )
>
> So my questions are:
> Is there already something similar out there that I can use?
> Is it possible to create such a driver file without getting 1000s of
> blue screens?
> What's the easiest way to do this.
> How can I send some bytes from my app to the driver? (My app tells the
> driver to generate an 'F1' keystroke...)
> Is my theory correct?
>
> I hope to get some help from you.
> Thanks for any hints
> Mel
>
> NTSTATUS
> KbdFilterInit(
> IN PDRIVER_OBJECT DriverObject
> )
> /*++
>
> Routine Description:
>
> Create a device object and attaches it to the
> first keyboard device chain
>
> Arguments:
>
> DeviceObject - pointer to a device object.
>
> Return Value:
>
> NT Status code
>
> --*/
>
>
> {
> UNICODE_STRING ntUnicodeString;
> NTSTATUS ntStatus;
> PDEVICE_OBJECT DeviceObject = NULL;
>
> //
> // Only hook onto the first keyboard's chain.
> //
> RtlInitUnicodeString( &ntUnicodeString, L"\\Device\\KeyboardClass0" );
> //
> // Create device object for the keyboard.
> //
> ntStatus = IoCreateDevice( DriverObject,
> 0,
> NULL,
> FILE_DEVICE_KEYBOARD,
> 0,
> FALSE,
> &DeviceObject );
>
> if( !NT_SUCCESS(ntStatus) ) {
> JKBD_DbgPrint(("JKBD: Keyboard hook failed to create device!\n"));
> return ntStatus;
> }
> //
> // Keyboard uses buffered I/O so we must as well.
> //
> DeviceObject->Flags |= DO_BUFFERED_IO;
> //
> // Attach to the keyboard chain.
> //
> ntStatus = IoAttachDevice( DeviceObject, &ntUnicodeString,
> &pGlobalDevExt->KbdDevice );
> if( !NT_SUCCESS(ntStatus) ) {
> JKBD_DbgPrint(("JKBD: Connect with keyboard failed!\n"));
> IoDeleteDevice( DeviceObject );
> return ntStatus;
> }
> pGlobalDevExt->KbdFilterDevice = DeviceObject;
>
> return STATUS_SUCCESS;
> }
>
>
>
> //
> // Create a keyboard packet
> //
> KeyData = pGlobalDevExt->RawKbdIrp->AssociatedIrp.SystemBuffer;
>
> RtlZeroMemory(KeyData, 2*sizeof(KEYBOARD_INPUT_DATA));
> KeyData[numKeys].Flags = 0; //down
> KeyData[numKeys+1].Flags = 1; //up
> KeyData[numKeys].MakeCode = 0x1e; // character a
> KeyData[numKeys+1].MakeCode = 0x1e; // character a
> numKeys += 2;
> KeyData += numKeys*sizeof(KEYBOARD_INPUT_DATA);
> pGlobalDevExt->RawKbdIrp->IoStatus.Status = STATUS_SUCCESS;
> pGlobalDevExt->RawKbdIrp->IoStatus.Information =
> numKeys*sizeof(KEYBOARD_INPUT_DATA);
> pGlobalDevExt->RawKbdIrpPending = FALSE;
> IoCompleteRequest(pGlobalDevExt->RawKbdIrp, IO_KEYBOARD_INCREMENT);
>
>
>



Re: Keyboard filter to simulate keys by Mel

Mel
Tue Sep 21 15:16:13 CDT 2004

Thanks for your help.
SendInput sounds really easy, too easy.
Some forums mention that directx really reads
the keyboard events directly from the keyboard
and things like keybd_event or SendInput wont work.

There is a way to hook the Directx Api function SendDeviceData and
inject keystrokes there. But therefgore you have to replace the directx dll
with your own.

I work with win2k and winxp.

Thanks for your tips.
-Mel

"Doron Holan [MS]" <doronh@nospam.microsoft.com> wrote in message
news:OfLi17%23nEHA.1608@TK2MSFTNGP15.phx.gbl...
which OS do you need this to work on? if it is win2k and forward, you can
just use SendInput() from user mode.

d

--
Please do not send e-mail directly to this alias. this alias is for
newsgroup purposes only.
This posting is provided "AS IS" with no warranties, and confers no rights.


"Mel" <Mel_Olonsky@gmx.net> wrote in message
news:ufHn2H9nEHA.3224@tk2msftngp13.phx.gbl...
> Hello,
>
> I'm new to driver development, in fact I have never written
> a real mode sys file nor a driver. Now I have to accomplish the following
> task:
> A program generates virtual key events to control a directx game.
> Because directx directly reads out the keyboard I can't simply use the
> WinAPI keybd_event or a simple SendKeys function. So the best way
> seems to be to send the keystrokes from my application (can be delphi, c++
> or vb)
> to the keyboard filter driver that creates the keystroke.
>
> Therefore I register a new keyboardchain filter KbdFilterInit
>
> Then I'd like to feed keys into the keyboard chain to simulate button
> press
> events. Therefore I create KeyData packets.
>
> To process the keyboard chain I implement proper dispatch
> function for reading
> NTSTATUS
> KbdDispatchRead(
> IN PDEVICE_OBJECT DeviceObject,
> IN PIRP Irp
> )
>
> So my questions are:
> Is there already something similar out there that I can use?
> Is it possible to create such a driver file without getting 1000s of
> blue screens?
> What's the easiest way to do this.
> How can I send some bytes from my app to the driver? (My app tells the
> driver to generate an 'F1' keystroke...)
> Is my theory correct?
>
> I hope to get some help from you.
> Thanks for any hints
> Mel
>
> NTSTATUS
> KbdFilterInit(
> IN PDRIVER_OBJECT DriverObject
> )
> /*++
>
> Routine Description:
>
> Create a device object and attaches it to the
> first keyboard device chain
>
> Arguments:
>
> DeviceObject - pointer to a device object.
>
> Return Value:
>
> NT Status code
>
> --*/
>
>
> {
> UNICODE_STRING ntUnicodeString;
> NTSTATUS ntStatus;
> PDEVICE_OBJECT DeviceObject = NULL;
>
> //
> // Only hook onto the first keyboard's chain.
> //
> RtlInitUnicodeString( &ntUnicodeString, L"\\Device\\KeyboardClass0" );
> //
> // Create device object for the keyboard.
> //
> ntStatus = IoCreateDevice( DriverObject,
> 0,
> NULL,
> FILE_DEVICE_KEYBOARD,
> 0,
> FALSE,
> &DeviceObject );
>
> if( !NT_SUCCESS(ntStatus) ) {
> JKBD_DbgPrint(("JKBD: Keyboard hook failed to create device!\n"));
> return ntStatus;
> }
> //
> // Keyboard uses buffered I/O so we must as well.
> //
> DeviceObject->Flags |= DO_BUFFERED_IO;
> //
> // Attach to the keyboard chain.
> //
> ntStatus = IoAttachDevice( DeviceObject, &ntUnicodeString,
> &pGlobalDevExt->KbdDevice );
> if( !NT_SUCCESS(ntStatus) ) {
> JKBD_DbgPrint(("JKBD: Connect with keyboard failed!\n"));
> IoDeleteDevice( DeviceObject );
> return ntStatus;
> }
> pGlobalDevExt->KbdFilterDevice = DeviceObject;
>
> return STATUS_SUCCESS;
> }
>
>
>
> //
> // Create a keyboard packet
> //
> KeyData = pGlobalDevExt->RawKbdIrp->AssociatedIrp.SystemBuffer;
>
> RtlZeroMemory(KeyData, 2*sizeof(KEYBOARD_INPUT_DATA));
> KeyData[numKeys].Flags = 0; //down
> KeyData[numKeys+1].Flags = 1; //up
> KeyData[numKeys].MakeCode = 0x1e; // character a
> KeyData[numKeys+1].MakeCode = 0x1e; // character a
> numKeys += 2;
> KeyData += numKeys*sizeof(KEYBOARD_INPUT_DATA);
> pGlobalDevExt->RawKbdIrp->IoStatus.Status = STATUS_SUCCESS;
> pGlobalDevExt->RawKbdIrp->IoStatus.Information =
> numKeys*sizeof(KEYBOARD_INPUT_DATA);
> pGlobalDevExt->RawKbdIrpPending = FALSE;
> IoCompleteRequest(pGlobalDevExt->RawKbdIrp, IO_KEYBOARD_INCREMENT);
>
>
>




Re: Keyboard filter to simulate keys by Ray

Ray
Tue Sep 21 17:59:56 CDT 2004

Well, don't believe everything you read here (including this :-).

SendInput works fine with DirectInput on 2k and XP.

Of course, it may be possible to create a situation where it doesn't
work, like some app opening a *specific* keyboard instead of the
meta-keyboard GUID_SysKeyboard (I haven't verified this scenario). But
even with a filter, you're going to have that problem, because you can't
send your keys to *all* keyboards with a filter, just to one particular
one (otherwise you'd end up with duplicate key presses, which you
probably don't want).

Mel wrote:
> Thanks for your help.
> SendInput sounds really easy, too easy.
> Some forums mention that directx really reads
> the keyboard events directly from the keyboard
> and things like keybd_event or SendInput wont work.
>
> There is a way to hook the Directx Api function SendDeviceData and
> inject keystrokes there. But therefgore you have to replace the directx dll
> with your own.
>
> I work with win2k and winxp.
>
> Thanks for your tips.
> -Mel
>
> "Doron Holan [MS]" <doronh@nospam.microsoft.com> wrote in message
> news:OfLi17%23nEHA.1608@TK2MSFTNGP15.phx.gbl...
> which OS do you need this to work on? if it is win2k and forward, you can
> just use SendInput() from user mode.
>
> d
>

--
../ray\..

Please remove ".spamblock" from my email address if you need to contact
me outside the newsgroup.

Re: Keyboard filter to simulate keys by Doron

Doron
Tue Sep 21 22:32:25 CDT 2004

ray's right. SendInput() will work just fine for you. no need for a
driver.

d

--
Please do not send e-mail directly to this alias. this alias is for
newsgroup purposes only.
This posting is provided "AS IS" with no warranties, and confers no rights.


"Ray Trent" <rat@synaptics.spamblock.com> wrote in message
news:u1H586CoEHA.2808@TK2MSFTNGP10.phx.gbl...
> Well, don't believe everything you read here (including this :-).
>
> SendInput works fine with DirectInput on 2k and XP.
>
> Of course, it may be possible to create a situation where it doesn't work,
> like some app opening a *specific* keyboard instead of the meta-keyboard
> GUID_SysKeyboard (I haven't verified this scenario). But even with a
> filter, you're going to have that problem, because you can't send your
> keys to *all* keyboards with a filter, just to one particular one
> (otherwise you'd end up with duplicate key presses, which you probably
> don't want).
>
> Mel wrote:
>> Thanks for your help.
>> SendInput sounds really easy, too easy.
>> Some forums mention that directx really reads
>> the keyboard events directly from the keyboard
>> and things like keybd_event or SendInput wont work.
>>
>> There is a way to hook the Directx Api function SendDeviceData and
>> inject keystrokes there. But therefgore you have to replace the directx
>> dll
>> with your own.
>>
>> I work with win2k and winxp.
>>
>> Thanks for your tips.
>> -Mel
>>
>> "Doron Holan [MS]" <doronh@nospam.microsoft.com> wrote in message
>> news:OfLi17%23nEHA.1608@TK2MSFTNGP15.phx.gbl...
>> which OS do you need this to work on? if it is win2k and forward, you can
>> just use SendInput() from user mode.
>>
>> d
>>
>
> --
> ../ray\..
>
> Please remove ".spamblock" from my email address if you need to contact me
> outside the newsgroup.



Re: Keyboard filter to simulate keys by Mel

Mel
Wed Sep 22 16:08:35 CDT 2004


Thanks for your opinions. I will implement the SendInput option,
this really saves me a lot of work.
In one or two days I will know if it works with DirectX or not.

Thanks
Mel


"Doron Holan [MS]" <doronh@nospam.microsoft.com> wrote in message
news:OfLi17%23nEHA.1608@TK2MSFTNGP15.phx.gbl...
which OS do you need this to work on? if it is win2k and forward, you can
just use SendInput() from user mode.

d

--
Please do not send e-mail directly to this alias. this alias is for
newsgroup purposes only.
This posting is provided "AS IS" with no warranties, and confers no rights.


"Mel" <Mel_Olonsky@gmx.net> wrote in message
news:ufHn2H9nEHA.3224@tk2msftngp13.phx.gbl...
> Hello,
>
> I'm new to driver development, in fact I have never written
> a real mode sys file nor a driver. Now I have to accomplish the following
> task:
> A program generates virtual key events to control a directx game.
> Because directx directly reads out the keyboard I can't simply use the
> WinAPI keybd_event or a simple SendKeys function. So the best way
> seems to be to send the keystrokes from my application (can be delphi, c++
> or vb)
> to the keyboard filter driver that creates the keystroke.
>
> Therefore I register a new keyboardchain filter KbdFilterInit
>
> Then I'd like to feed keys into the keyboard chain to simulate button
> press
> events. Therefore I create KeyData packets.
>
> To process the keyboard chain I implement proper dispatch
> function for reading
> NTSTATUS
> KbdDispatchRead(
> IN PDEVICE_OBJECT DeviceObject,
> IN PIRP Irp
> )
>
> So my questions are:
> Is there already something similar out there that I can use?
> Is it possible to create such a driver file without getting 1000s of
> blue screens?
> What's the easiest way to do this.
> How can I send some bytes from my app to the driver? (My app tells the
> driver to generate an 'F1' keystroke...)
> Is my theory correct?
>
> I hope to get some help from you.
> Thanks for any hints
> Mel
>
> NTSTATUS
> KbdFilterInit(
> IN PDRIVER_OBJECT DriverObject
> )
> /*++
>
> Routine Description:
>
> Create a device object and attaches it to the
> first keyboard device chain
>
> Arguments:
>
> DeviceObject - pointer to a device object.
>
> Return Value:
>
> NT Status code
>
> --*/
>
>
> {
> UNICODE_STRING ntUnicodeString;
> NTSTATUS ntStatus;
> PDEVICE_OBJECT DeviceObject = NULL;
>
> //
> // Only hook onto the first keyboard's chain.
> //
> RtlInitUnicodeString( &ntUnicodeString, L"\\Device\\KeyboardClass0" );
> //
> // Create device object for the keyboard.
> //
> ntStatus = IoCreateDevice( DriverObject,
> 0,
> NULL,
> FILE_DEVICE_KEYBOARD,
> 0,
> FALSE,
> &DeviceObject );
>
> if( !NT_SUCCESS(ntStatus) ) {
> JKBD_DbgPrint(("JKBD: Keyboard hook failed to create device!\n"));
> return ntStatus;
> }
> //
> // Keyboard uses buffered I/O so we must as well.
> //
> DeviceObject->Flags |= DO_BUFFERED_IO;
> //
> // Attach to the keyboard chain.
> //
> ntStatus = IoAttachDevice( DeviceObject, &ntUnicodeString,
> &pGlobalDevExt->KbdDevice );
> if( !NT_SUCCESS(ntStatus) ) {
> JKBD_DbgPrint(("JKBD: Connect with keyboard failed!\n"));
> IoDeleteDevice( DeviceObject );
> return ntStatus;
> }
> pGlobalDevExt->KbdFilterDevice = DeviceObject;
>
> return STATUS_SUCCESS;
> }
>
>
>
> //
> // Create a keyboard packet
> //
> KeyData = pGlobalDevExt->RawKbdIrp->AssociatedIrp.SystemBuffer;
>
> RtlZeroMemory(KeyData, 2*sizeof(KEYBOARD_INPUT_DATA));
> KeyData[numKeys].Flags = 0; //down
> KeyData[numKeys+1].Flags = 1; //up
> KeyData[numKeys].MakeCode = 0x1e; // character a
> KeyData[numKeys+1].MakeCode = 0x1e; // character a
> numKeys += 2;
> KeyData += numKeys*sizeof(KEYBOARD_INPUT_DATA);
> pGlobalDevExt->RawKbdIrp->IoStatus.Status = STATUS_SUCCESS;
> pGlobalDevExt->RawKbdIrp->IoStatus.Information =
> numKeys*sizeof(KEYBOARD_INPUT_DATA);
> pGlobalDevExt->RawKbdIrpPending = FALSE;
> IoCompleteRequest(pGlobalDevExt->RawKbdIrp, IO_KEYBOARD_INCREMENT);
>
>
>