mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
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:
parent
6be5fe1285
commit
87d07db47c
4 changed files with 232 additions and 8 deletions
|
@ -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,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);
|
||||
|
|
|
@ -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_
|
||||
|
|
98
reactos/include/ddk/ntdd8042.h
Normal file
98
reactos/include/ddk/ntdd8042.h
Normal 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_
|
19
reactos/include/ddk/ntddkbd.h
Normal file
19
reactos/include/ddk/ntddkbd.h
Normal 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_
|
Loading…
Reference in a new issue