I am writing a keyboard filter filter driver for Windows and I need to insert my user keystroke data into the Windows message queue. I managed to capture all the keys that the OnReadCompletion () function was pressed on, the feedback from IoSetCompletionRoutine () in my Read () function for my driver as follows:
NTSTATUS Read(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp, OnReadCompletion, DeviceObject, TRUE, TRUE, TRUE);
return IoCallDriver (deviceExtension->pKeyboardDevice, Irp);
}
NTSTATUS OnReadCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
{
}
This filter driver is connected to the kbdclass driver as follows:
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
CCHAR ntNameBuffer[64] = "\\Device\\KeyboardClass0";
status = IoAttachDevice(deviceObject, &uKeyboardDeviceName, &DeviceExtension->pKeyboardDevice);
}
So, I can catch all the keys pressed in OnReadCompletion (). But I need to insert my own information into the message flow from the keyboard. Here are two issues with this:
OnReadCompletion() . - , . ? ? (0x60 0x64) WRITE_PORT_UCHAR(), .
IRP OnReadCompletion(), , , , . - , ?
NTSTATUS OnReadCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
{
PIO_STACK_LOCATION IrpStackLocation = NULL;
INT BufferLength;
INT numKeys = 0, i = 0;
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
IrpStackLocation = IoGetCurrentIrpStackLocation(Irp);
BufferLength = IrpStackLocation->Parameters.Read.Length;
if(Irp->IoStatus.Status == STATUS_SUCCESS)
{
PCHAR newSystemBuffer, oldSystemBuffer;
PKEYBOARD_INPUT_DATA keys = (PKEYBOARD_INPUT_DATA)Irp->AssociatedIrp.SystemBuffer;
numKeys = Irp->IoStatus.Information / sizeof(KEYBOARD_INPUT_DATA);
for(i = 0; i < numKeys; i++)
{
DbgPrint("%s -- ScanCode: %x\n", __FUNCTION__, keys[i].MakeCode);
}
newSystemBuffer = ExAllocatePool(NonPagedPool, Irp->IoStatus.Information * 2);
RtlCopyMemory(newSystemBuffer, keys, Irp->IoStatus.Information);
RtlCopyMemory(newSystemBuffer + Irp->IoStatus.Information, keys, Irp->IoStatus.Information);
oldSystemBuffer = Irp->AssociatedIrp.SystemBuffer;
Irp->AssociatedIrp.SystemBuffer = newSystemBuffer;
Irp->IoStatus.Information *= 2;
ExFreePool(oldSystemBuffer);
}
if(Irp->PendingReturned)
IoMarkIrpPending(Irp);
return Irp->IoStatus.Status;
}
, , "", , , .
. !