Fixed small bug in keyboard driver that prevented filter driver from working. Added keyboard hook.

svn path=/trunk/; revision=2410
This commit is contained in:
Eugene Ingerman 2001-11-30 01:38:24 +00:00
parent 6be5fe1285
commit 87d07db47c
4 changed files with 232 additions and 8 deletions

View file

@ -14,6 +14,9 @@
#include <ntos/keyboard.h>
#include <ntos/minmax.h>
#include <ddk/ntddkbd.h>
#include <ddk/ntdd8042.h>
#define NDEBUG
#include <debug.h>
@ -440,6 +443,8 @@ 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);

View file

@ -1,3 +1,21 @@
#ifndef _KEYBOARD_H_
#define _KEYBOARD_H_
#include <ddk/ntddkbd.h>
#include <ddk/ntdd8042.h>
/*-----------------------------------------------------
* 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_

View file

@ -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_

View file

@ -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_