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/keyboard.h>
|
||||||
#include <ntos/minmax.h>
|
#include <ntos/minmax.h>
|
||||||
|
|
||||||
|
#include <ddk/ntddkbd.h>
|
||||||
|
#include <ddk/ntdd8042.h>
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
@ -440,7 +443,9 @@ KeyboardHandler(PKINTERRUPT Interrupt,
|
||||||
BOOL isDown;
|
BOOL isDown;
|
||||||
static BYTE lastKey;
|
static BYTE lastKey;
|
||||||
CHAR Status;
|
CHAR Status;
|
||||||
|
PDEVICE_OBJECT deviceObject = (PDEVICE_OBJECT) Context;
|
||||||
|
PDEVICE_EXTENSION deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension;
|
||||||
|
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -454,6 +459,27 @@ KeyboardHandler(PKINTERRUPT Interrupt,
|
||||||
|
|
||||||
// Read scan code
|
// Read scan code
|
||||||
thisKey=READ_PORT_UCHAR((PUCHAR)KBD_DATA_PORT);
|
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
|
if ((thisKey==0xE0)||(thisKey==0xE1)) // Extended key
|
||||||
{
|
{
|
||||||
extKey=1; // Wait for next byte
|
extKey=1; // Wait for next byte
|
||||||
|
@ -538,7 +564,8 @@ KeyboardHandler(PKINTERRUPT Interrupt,
|
||||||
DPRINT("KeysRequired %d KeysRead %x\n",KeysRequired,KeysRead);
|
DPRINT("KeysRequired %d KeysRead %x\n",KeysRequired,KeysRead);
|
||||||
if (KeysRead==KeysRequired)
|
if (KeysRead==KeysRequired)
|
||||||
{
|
{
|
||||||
KeInsertQueueDpc(&KbdDpc,stk->DeviceObject,CurrentIrp);
|
PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT) Context;
|
||||||
|
KeInsertQueueDpc(&KbdDpc,DeviceObject,CurrentIrp);
|
||||||
CurrentIrp=NULL;
|
CurrentIrp=NULL;
|
||||||
}
|
}
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
|
@ -572,7 +599,7 @@ KeyboardHandler(PKINTERRUPT Interrupt,
|
||||||
//
|
//
|
||||||
// Initialize keyboard
|
// Initialize keyboard
|
||||||
//
|
//
|
||||||
static void KeyboardConnectInterrupt(void)
|
static void KeyboardConnectInterrupt(PDEVICE_OBJECT DeviceObject)
|
||||||
{
|
{
|
||||||
ULONG MappedIrq;
|
ULONG MappedIrq;
|
||||||
KIRQL Dirql;
|
KIRQL Dirql;
|
||||||
|
@ -587,7 +614,7 @@ static void KeyboardConnectInterrupt(void)
|
||||||
&Affinity);
|
&Affinity);
|
||||||
Status = IoConnectInterrupt(&KbdInterrupt,
|
Status = IoConnectInterrupt(&KbdInterrupt,
|
||||||
KeyboardHandler,
|
KeyboardHandler,
|
||||||
NULL,
|
(PVOID)DeviceObject,
|
||||||
NULL,
|
NULL,
|
||||||
MappedIrq,
|
MappedIrq,
|
||||||
Dirql,
|
Dirql,
|
||||||
|
@ -615,7 +642,7 @@ KbdClearInput(VOID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int InitializeKeyboard(void)
|
static int InitializeKeyboard(PDEVICE_OBJECT DeviceObject)
|
||||||
{
|
{
|
||||||
// Initialize variables
|
// Initialize variables
|
||||||
bufHead=0;
|
bufHead=0;
|
||||||
|
@ -629,7 +656,7 @@ static int InitializeKeyboard(void)
|
||||||
extKey=0;
|
extKey=0;
|
||||||
|
|
||||||
KbdClearInput();
|
KbdClearInput();
|
||||||
KeyboardConnectInterrupt();
|
KeyboardConnectInterrupt(DeviceObject);
|
||||||
KeInitializeDpc(&KbdDpc,KbdDpcRoutine,NULL);
|
KeInitializeDpc(&KbdDpc,KbdDpcRoutine,NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -691,6 +718,60 @@ VOID STDCALL KbdStartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
DPRINT("KeysRequired %d\n",KeysRequired);
|
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)
|
NTSTATUS STDCALL KbdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
|
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
@ -754,22 +835,28 @@ NTSTATUS STDCALL DriverEntry(PDRIVER_OBJECT DriverObject,
|
||||||
UNICODE_STRING SymlinkName;
|
UNICODE_STRING SymlinkName;
|
||||||
|
|
||||||
DbgPrint("Keyboard Driver 0.0.4\n");
|
DbgPrint("Keyboard Driver 0.0.4\n");
|
||||||
InitializeKeyboard();
|
|
||||||
|
|
||||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = KbdDispatch;
|
DriverObject->MajorFunction[IRP_MJ_CREATE] = KbdDispatch;
|
||||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = KbdDispatch;
|
DriverObject->MajorFunction[IRP_MJ_CLOSE] = KbdDispatch;
|
||||||
DriverObject->MajorFunction[IRP_MJ_READ] = KbdDispatch;
|
DriverObject->MajorFunction[IRP_MJ_READ] = KbdDispatch;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = KbdInternalDeviceControl;
|
||||||
|
|
||||||
DriverObject->DriverStartIo = KbdStartIo;
|
DriverObject->DriverStartIo = KbdStartIo;
|
||||||
|
|
||||||
RtlInitUnicodeString(&DeviceName, L"\\Device\\Keyboard");
|
RtlInitUnicodeString(&DeviceName, L"\\Device\\Keyboard");
|
||||||
IoCreateDevice(DriverObject,
|
IoCreateDevice(DriverObject,
|
||||||
0,
|
sizeof(DEVICE_EXTENSION),
|
||||||
&DeviceName,
|
&DeviceName,
|
||||||
FILE_DEVICE_KEYBOARD,
|
FILE_DEVICE_KEYBOARD,
|
||||||
0,
|
0,
|
||||||
TRUE,
|
TRUE,
|
||||||
&DeviceObject);
|
&DeviceObject);
|
||||||
|
|
||||||
|
RtlZeroMemory(DeviceObject->DeviceExtension, sizeof(DEVICE_EXTENSION));
|
||||||
|
|
||||||
DeviceObject->Flags = DeviceObject->Flags | DO_BUFFERED_IO;
|
DeviceObject->Flags = DeviceObject->Flags | DO_BUFFERED_IO;
|
||||||
|
InitializeKeyboard( DeviceObject );
|
||||||
|
|
||||||
|
|
||||||
RtlInitUnicodeString(&SymlinkName, L"\\??\\Keyboard");
|
RtlInitUnicodeString(&SymlinkName, L"\\??\\Keyboard");
|
||||||
IoCreateSymbolicLink(&SymlinkName, &DeviceName);
|
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
|
* Some defines
|
||||||
*/
|
*/
|
||||||
|
@ -65,3 +83,5 @@
|
||||||
#define KBD_LED_SCROLL 0x01
|
#define KBD_LED_SCROLL 0x01
|
||||||
#define KBD_LED_NUM 0x02
|
#define KBD_LED_NUM 0x02
|
||||||
#define KBD_LED_CAPS 0x04
|
#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