Hi all,
I have to find a method to simulate keystrokes from a user mode application without having the “injected” flag set, which is happening if using keybd_event. I am trying right now to prepare a keyboard filter driver that would accomplish this, using custom IOCTLs. I started from the kbfiltr sample in the DDK, then made the changes as described in http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q262305 in order to allow custom IOCTLs. Here is my modified FilterDispatchIo function that processes one custom IOCTL called IOCTL_KEYBOARD_SIMULATE_KEY:
#define IOCTL_KEYBOARD_SIMULATE_KEY CTL_CODE(FILE_DEVICE_KEYBOARD, 0x0F00, METHOD_NEITHER, FILE_ANY_ACCESS)
NTSTATUS
FilterDispatchIo(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PIO_STACK_LOCATION irpStack;
NTSTATUS status;
PDEVICE_EXTENSION devExt;
KEYBOARD_INPUT_DATA data;
PKEYBOARD_INPUT_DATA InputDataStart;
PKEYBOARD_INPUT_DATA InputDataEnd;
ULONG InputDataConsumed;
KIRQL prevIrql;
// PAGED_CODE();
devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
//
// Please note that this is a common dispatch point for controlobject and
// filter deviceobject attached to the pnp stack.
//
if(DeviceObject != ControlDeviceObject)
{
//
// We will just the request down as we are not interested in handling
// requests that come on the PnP stack.
//
return KbFilter_DispatchPassThrough(DeviceObject, Irp);
}
//
// Else this is targeted at our control deviceobject so let’s handle it.
// Here we will handle the IOCTl requests that come from the app.
//
status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
irpStack = IoGetCurrentIrpStackLocation (Irp);
switch (irpStack->MajorFunction)
{
case IRP_MJ_CREATE:
DebugPrint((“Create \n”));
break;
case IRP_MJ_CLOSE:
DebugPrint((“Close \n”));
break;
case IRP_MJ_CLEANUP:
DebugPrint((“Cleanup \n”));
break;
case IRP_MJ_DEVICE_CONTROL:
DebugPrint((“DeviceIoControl\n”));
switch (irpStack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_KEYBOARD_SIMULATE_KEY:
{
InputDataStart = (KEYBOARD_INPUT_DATA*)irpStack->Parameters.DeviceIoControl.Type3InputBuffer;
InputDataEnd = InputDataStart + irpStack->Parameters.DeviceIoControl.InputBufferLength / sizeof(KEYBOARD_INPUT_DATA);
KeRaiseIrql(DISPATCH_LEVEL, &prevIrql);
InputDataConsumed = 0;
(*(PSERVICE_CALLBACK_ROUTINE) devExt->UpperConnectData.ClassService)(
devExt->UpperConnectData.ClassDeviceObject,
InputDataStart,
InputDataEnd,
& InputDataConsumed);
KeLowerIrql(prevIrql);
}
break;
default:
status = STATUS_INVALID_PARAMETER;
break;
}
default:
break;
}
Irp->IoStatus.Status = status;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return status;
}
I am using DeviceIoControl with IOCTL_KEYBOARD_SIMULATE_KEY from an application to simulate keystrokes in this way. The problem is that the filter driver always crashes at the PSERVICE_CALLBACK_ROUTINE call. WinDbg shows something like this:
*** Fatal System Error: 0x000000d1
(0x00000000,0x00000002,0x00000001,0x81AAB78C)
Break instruction exception - code 80000003 (first chance)
I have checked that the simulated keystrokes reach the filter driver just fine via the custom IOCTL, the problem is that I don’t seem to do what’s right in order to pass them next as real keystrokes.
I am new to windows drivers, any ideas would be greatly appreciated.
Thanks,
Adrian