From 87d07db47c15dd39af27a46bd25e801a4aa71838 Mon Sep 17 00:00:00 2001 From: Eugene Ingerman Date: Fri, 30 Nov 2001 01:38:24 +0000 Subject: [PATCH] Fixed small bug in keyboard driver that prevented filter driver from working. Added keyboard hook. svn path=/trunk/; revision=2410 --- reactos/drivers/input/keyboard/keyboard.c | 103 ++++++++++++++++++++-- reactos/drivers/input/keyboard/keyboard.h | 20 +++++ reactos/include/ddk/ntdd8042.h | 98 ++++++++++++++++++++ reactos/include/ddk/ntddkbd.h | 19 ++++ 4 files changed, 232 insertions(+), 8 deletions(-) create mode 100644 reactos/include/ddk/ntdd8042.h create mode 100644 reactos/include/ddk/ntddkbd.h diff --git a/reactos/drivers/input/keyboard/keyboard.c b/reactos/drivers/input/keyboard/keyboard.c index f80785a9fec..9af7c0b2191 100644 --- a/reactos/drivers/input/keyboard/keyboard.c +++ b/reactos/drivers/input/keyboard/keyboard.c @@ -14,6 +14,9 @@ #include #include +#include +#include + #define NDEBUG #include @@ -440,7 +443,9 @@ KeyboardHandler(PKINTERRUPT Interrupt, BOOL isDown; static BYTE lastKey; CHAR Status; - + PDEVICE_OBJECT deviceObject = (PDEVICE_OBJECT) Context; + PDEVICE_EXTENSION deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension; + CHECKPOINT; /* @@ -454,6 +459,27 @@ KeyboardHandler(PKINTERRUPT Interrupt, // Read scan code thisKey=READ_PORT_UCHAR((PUCHAR)KBD_DATA_PORT); + + // Call hook routine. May change scancode value. + if (deviceExtension->IsrHookCallback) { + BOOLEAN cont = FALSE, ret; + //BUG BUG: rewrite to have valid CurrentScanState!!! + ret = (*deviceExtension->IsrHookCallback)( + deviceObject, + NULL,//&deviceExtension->CurrentInput, + NULL,//&deviceExtension->CurrentOutput, + Status, + &thisKey, //&scanCode, + &cont, + NULL //&deviceExtension->CurrentScanState + ); + + if (!cont) { + return ret; + } + } + + if ((thisKey==0xE0)||(thisKey==0xE1)) // Extended key { extKey=1; // Wait for next byte @@ -538,7 +564,8 @@ KeyboardHandler(PKINTERRUPT Interrupt, DPRINT("KeysRequired %d KeysRead %x\n",KeysRequired,KeysRead); if (KeysRead==KeysRequired) { - KeInsertQueueDpc(&KbdDpc,stk->DeviceObject,CurrentIrp); + PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT) Context; + KeInsertQueueDpc(&KbdDpc,DeviceObject,CurrentIrp); CurrentIrp=NULL; } CHECKPOINT; @@ -572,7 +599,7 @@ KeyboardHandler(PKINTERRUPT Interrupt, // // Initialize keyboard // -static void KeyboardConnectInterrupt(void) +static void KeyboardConnectInterrupt(PDEVICE_OBJECT DeviceObject) { ULONG MappedIrq; KIRQL Dirql; @@ -587,7 +614,7 @@ static void KeyboardConnectInterrupt(void) &Affinity); Status = IoConnectInterrupt(&KbdInterrupt, KeyboardHandler, - NULL, + (PVOID)DeviceObject, NULL, MappedIrq, Dirql, @@ -615,7 +642,7 @@ KbdClearInput(VOID) } } -static int InitializeKeyboard(void) +static int InitializeKeyboard(PDEVICE_OBJECT DeviceObject) { // Initialize variables bufHead=0; @@ -629,7 +656,7 @@ static int InitializeKeyboard(void) extKey=0; KbdClearInput(); - KeyboardConnectInterrupt(); + KeyboardConnectInterrupt(DeviceObject); KeInitializeDpc(&KbdDpc,KbdDpcRoutine,NULL); return 0; } @@ -691,6 +718,60 @@ VOID STDCALL KbdStartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp) DPRINT("KeysRequired %d\n",KeysRequired); } +NTSTATUS KbdInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) +{ + PIO_STACK_LOCATION stk; + PINTERNAL_I8042_HOOK_KEYBOARD hookKeyboard; + PDEVICE_EXTENSION DevExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; + NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST; + + Irp->IoStatus.Information = 0; + stk = IoGetCurrentIrpStackLocation(Irp); + + switch (stk->Parameters.DeviceIoControl.IoControlCode) + { + /*-----------------11/29/2001 4:12PM---------------- + * This internal ioctrl belongs in i8042 driver. Should be + * moved to the appropriate driver later. + * --------------------------------------------------*/ + case IOCTL_INTERNAL_I8042_HOOK_KEYBOARD: + + if (stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(INTERNAL_I8042_HOOK_KEYBOARD)) + { + DPRINT(("Keyboard IOCTL_INTERNAL_I8042_HOOK_KEYBOARD invalid buffer size\n")); + status = STATUS_INVALID_PARAMETER; + } + else { + // + // Copy the values if they are filled in + // + hookKeyboard = (PINTERNAL_I8042_HOOK_KEYBOARD) + stk->Parameters.DeviceIoControl.Type3InputBuffer; + + DevExt->HookContext = hookKeyboard->Context; + if (hookKeyboard->InitializationRoutine) { + DbgPrint("Keyboard: InitializationHookCallback NOT IMPLEMENTED\n"); + DevExt->InitializationHookCallback = + hookKeyboard->InitializationRoutine; + } + + if (hookKeyboard->IsrRoutine) { + DevExt->IsrHookCallback = hookKeyboard->IsrRoutine; + } + + status = STATUS_SUCCESS; + } + break; + default: + status = STATUS_INVALID_DEVICE_REQUEST; + break; + } + + Irp->IoStatus.Status = status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return status; +} + NTSTATUS STDCALL KbdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp); @@ -754,22 +835,28 @@ NTSTATUS STDCALL DriverEntry(PDRIVER_OBJECT DriverObject, UNICODE_STRING SymlinkName; DbgPrint("Keyboard Driver 0.0.4\n"); - InitializeKeyboard(); DriverObject->MajorFunction[IRP_MJ_CREATE] = KbdDispatch; DriverObject->MajorFunction[IRP_MJ_CLOSE] = KbdDispatch; DriverObject->MajorFunction[IRP_MJ_READ] = KbdDispatch; + DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = KbdInternalDeviceControl; + DriverObject->DriverStartIo = KbdStartIo; RtlInitUnicodeString(&DeviceName, L"\\Device\\Keyboard"); IoCreateDevice(DriverObject, - 0, + sizeof(DEVICE_EXTENSION), &DeviceName, FILE_DEVICE_KEYBOARD, 0, TRUE, &DeviceObject); + + RtlZeroMemory(DeviceObject->DeviceExtension, sizeof(DEVICE_EXTENSION)); + DeviceObject->Flags = DeviceObject->Flags | DO_BUFFERED_IO; + InitializeKeyboard( DeviceObject ); + RtlInitUnicodeString(&SymlinkName, L"\\??\\Keyboard"); IoCreateSymbolicLink(&SymlinkName, &DeviceName); diff --git a/reactos/drivers/input/keyboard/keyboard.h b/reactos/drivers/input/keyboard/keyboard.h index dbb63f66ef3..18885ceac13 100644 --- a/reactos/drivers/input/keyboard/keyboard.h +++ b/reactos/drivers/input/keyboard/keyboard.h @@ -1,3 +1,21 @@ +#ifndef _KEYBOARD_H_ +#define _KEYBOARD_H_ +#include +#include + + +/*----------------------------------------------------- + * DeviceExtension + * --------------------------------------------------*/ +typedef struct _DEVICE_EXTENSION +{ + + PI8042_KEYBOARD_INITIALIZATION_ROUTINE InitializationHookCallback; + PI8042_KEYBOARD_ISR IsrHookCallback; + PVOID HookContext; + +} DEVICE_EXTENSION, *PDEVICE_EXTENSION; + /* * Some defines */ @@ -65,3 +83,5 @@ #define KBD_LED_SCROLL 0x01 #define KBD_LED_NUM 0x02 #define KBD_LED_CAPS 0x04 + +#endif // _KEYBOARD_H_ diff --git a/reactos/include/ddk/ntdd8042.h b/reactos/include/ddk/ntdd8042.h new file mode 100644 index 00000000000..b57c487c166 --- /dev/null +++ b/reactos/include/ddk/ntdd8042.h @@ -0,0 +1,98 @@ +#ifndef _NTDD8042_ +#define _NTDD8042_ + +#define IOCTL_INTERNAL_I8042_HOOK_KEYBOARD CTL_CODE(FILE_DEVICE_KEYBOARD, 0x0FF0, METHOD_NEITHER, FILE_ANY_ACCESS) +#define IOCTL_INTERNAL_I8042_HOOK_MOUSE CTL_CODE(FILE_DEVICE_MOUSE, 0x0FF0, METHOD_NEITHER, FILE_ANY_ACCESS) + +typedef enum _KEYBOARD_SCAN_STATE { + Normal, + GotE0, + GotE1 +} KEYBOARD_SCAN_STATE, *PKEYBOARD_SCAN_STATE; + +typedef +NTSTATUS +(*PI8042_SYNCH_READ_PORT) ( + IN PVOID Context, + PUCHAR Value, + BOOLEAN WaitForACK + ); + +typedef +NTSTATUS +(*PI8042_SYNCH_WRITE_PORT) ( + IN PVOID Context, + UCHAR Value, + BOOLEAN WaitForACK + ); + +typedef enum _TRANSMIT_STATE { + Idle = 0, + SendingBytes +} TRANSMIT_STATE; + +typedef struct _OUTPUT_PACKET { + PUCHAR Bytes; + ULONG CurrentByte; + ULONG ByteCount; + TRANSMIT_STATE State; +} OUTPUT_PACKET, *POUTPUT_PACKET; + +typedef +NTSTATUS +(*PI8042_KEYBOARD_INITIALIZATION_ROUTINE) ( + IN PVOID InitializationContext, + IN PVOID SynchFuncContext, + IN PI8042_SYNCH_READ_PORT ReadPort, + IN PI8042_SYNCH_WRITE_PORT WritePort, + OUT PBOOLEAN TurnTranslationOn + ); + +typedef +BOOLEAN +(*PI8042_KEYBOARD_ISR) ( + PVOID IsrContext, + PKEYBOARD_INPUT_DATA CurrentInput, + POUTPUT_PACKET CurrentOutput, + UCHAR StatusByte, + PUCHAR Byte, + PBOOLEAN ContinueProcessing, + PKEYBOARD_SCAN_STATE ScanState + ); + +typedef struct _INTERNAL_I8042_HOOK_KEYBOARD { + + // + // Context variable for all callback routines + // + PVOID Context; + + // + // Routine to call after the mouse is reset + // + PI8042_KEYBOARD_INITIALIZATION_ROUTINE InitializationRoutine; + + // + // Routine to call when a byte is received via the interrupt + // + PI8042_KEYBOARD_ISR IsrRoutine; + + // + // Write function + // + //UNIMPLEMENTED PI8042_ISR_WRITE_PORT IsrWritePort; + + // + // Queue the current packet (ie the one passed into the isr callback hook) + // to be reported to the class driver + // + //UNIMPLEMENTED PI8042_QUEUE_PACKET QueueKeyboardPacket; + + // + // Context for IsrWritePort, QueueKeyboardPacket + // + //UNIMPLEMENTED PVOID CallContext; + +} INTERNAL_I8042_HOOK_KEYBOARD, *PINTERNAL_I8042_HOOK_KEYBOARD; + +#endif //_NTDD8042_ diff --git a/reactos/include/ddk/ntddkbd.h b/reactos/include/ddk/ntddkbd.h new file mode 100644 index 00000000000..527392c900c --- /dev/null +++ b/reactos/include/ddk/ntddkbd.h @@ -0,0 +1,19 @@ +#ifndef _NTDDKBD_ +#define _NTDDKBD_ + +typedef struct _KEYBOARD_INPUT_DATA { + + // + // Unit number. E.g., for \Device\KeyboardPort0 the unit is '0', + // for \Device\KeyboardPort1 the unit is '1', and so on. + // + + USHORT UnitId; + USHORT MakeCode; + USHORT Flags; + USHORT Reserved; + ULONG ExtraInformation; + +} KEYBOARD_INPUT_DATA, *PKEYBOARD_INPUT_DATA; + +#endif // _NTDDKBD_