M
Mel
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);
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);