mirror of
https://github.com/reactos/reactos.git
synced 2025-07-11 08:04:14 +00:00
Big move of driver input stack to a Plug-and-Play model:
- mouclass: Do non buffered IO. The pointer move should be smoother. Search non Plug-and-Play drivers in registry, instead of using their device name. - kbdclass: Full rewrite to support more than one keyboard. Use registry settings as specified in MSDN. (Info: kbdclass is now very similar to mouclass) - i8042prt: Keep it as a non Plug-and-Play driver, but register it in DEVICEMAP registry key. - USB controller: Enable USB keyboard/mouse I may have broken support for serial mice, i'll add it back in a few days... svn path=/trunk/; revision=18911
This commit is contained in:
parent
615b2d64a7
commit
5a77f871d4
11 changed files with 1019 additions and 384 deletions
|
@ -532,7 +532,6 @@ HKLM,"SYSTEM\CurrentControlSet\Services\mouclass","Start",0x00010001,0x00000001
|
||||||
HKLM,"SYSTEM\CurrentControlSet\Services\mouclass","Type",0x00010001,0x00000001
|
HKLM,"SYSTEM\CurrentControlSet\Services\mouclass","Type",0x00010001,0x00000001
|
||||||
HKLM,"SYSTEM\CurrentControlSet\Services\mouclass\Parameters","ConnectMultiplePorts",0x00010001,0x00000000
|
HKLM,"SYSTEM\CurrentControlSet\Services\mouclass\Parameters","ConnectMultiplePorts",0x00010001,0x00000000
|
||||||
HKLM,"SYSTEM\CurrentControlSet\Services\mouclass\Parameters","MouseDataQueueSize",0x00010001,0x00000064
|
HKLM,"SYSTEM\CurrentControlSet\Services\mouclass\Parameters","MouseDataQueueSize",0x00010001,0x00000064
|
||||||
HKLM,"SYSTEM\CurrentControlSet\Services\mouclass\Parameters","PointerDeviceBaseName",0x00000000,"PointerClassPnp"
|
|
||||||
HKLM,"SYSTEM\CurrentControlSet\Control\Class\{4D36E96F-E325-11CE-BFC1-08002BE10318}","UpperFilters",0x00010000,"mouclass"
|
HKLM,"SYSTEM\CurrentControlSet\Control\Class\{4D36E96F-E325-11CE-BFC1-08002BE10318}","UpperFilters",0x00010000,"mouclass"
|
||||||
|
|
||||||
; Mailslot filesystem driver
|
; Mailslot filesystem driver
|
||||||
|
|
|
@ -417,6 +417,7 @@ VOID STDCALL I8042SendHookWorkItem(PDEVICE_OBJECT DeviceObject,
|
||||||
goto hookworkitemdone;
|
goto hookworkitemdone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
Status = IoCallDriver(
|
Status = IoCallDriver(
|
||||||
WorkItemData->Target,
|
WorkItemData->Target,
|
||||||
NewIrp);
|
NewIrp);
|
||||||
|
@ -427,6 +428,7 @@ VOID STDCALL I8042SendHookWorkItem(PDEVICE_OBJECT DeviceObject,
|
||||||
KernelMode,
|
KernelMode,
|
||||||
FALSE,
|
FALSE,
|
||||||
NULL);
|
NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (IsKbd) {
|
if (IsKbd) {
|
||||||
/* Call the hooked initialization if it exists */
|
/* Call the hooked initialization if it exists */
|
||||||
|
@ -633,11 +635,58 @@ static NTSTATUS STDCALL I8042Initialize(PDEVICE_EXTENSION DevExt)
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS
|
||||||
|
AddRegistryEntry(
|
||||||
|
IN PCWSTR PortTypeName,
|
||||||
|
IN PUNICODE_STRING DeviceName,
|
||||||
|
IN PCWSTR RegistryPath)
|
||||||
|
{
|
||||||
|
UNICODE_STRING PathU = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\HARDWARE\\DEVICEMAP");
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
HANDLE hDeviceMapKey = (HANDLE)-1;
|
||||||
|
HANDLE hPortKey = (HANDLE)-1;
|
||||||
|
UNICODE_STRING PortTypeNameU;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes, &PathU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||||
|
Status = ZwOpenKey(&hDeviceMapKey, 0, &ObjectAttributes);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&PortTypeNameU, PortTypeName);
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes, &PortTypeNameU, OBJ_KERNEL_HANDLE, hDeviceMapKey, NULL);
|
||||||
|
Status = ZwCreateKey(&hPortKey, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = ZwSetValueKey(hPortKey, DeviceName, 0, REG_SZ, (PVOID)RegistryPath, wcslen(RegistryPath) * sizeof(WCHAR) + sizeof(UNICODE_NULL));
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (hDeviceMapKey != (HANDLE)-1)
|
||||||
|
ZwClose(hDeviceMapKey);
|
||||||
|
if (hPortKey != (HANDLE)-1)
|
||||||
|
ZwClose(hPortKey);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS STDCALL I8042AddDevice(PDRIVER_OBJECT DriverObject,
|
static NTSTATUS STDCALL I8042AddDevice(PDRIVER_OBJECT DriverObject,
|
||||||
PDEVICE_OBJECT Pdo)
|
PDEVICE_OBJECT Pdo)
|
||||||
{
|
{
|
||||||
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardClass0");
|
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardPort8042");
|
||||||
UNICODE_STRING MouseName = RTL_CONSTANT_STRING(L"\\Device\\PointerClass0");
|
UNICODE_STRING MouseName = RTL_CONSTANT_STRING(L"\\Device\\PointerPort8042");
|
||||||
ULONG MappedIrqKeyboard = 0, MappedIrqMouse = 0;
|
ULONG MappedIrqKeyboard = 0, MappedIrqMouse = 0;
|
||||||
KIRQL DirqlKeyboard = 0;
|
KIRQL DirqlKeyboard = 0;
|
||||||
KIRQL DirqlMouse = 0;
|
KIRQL DirqlMouse = 0;
|
||||||
|
@ -716,6 +765,7 @@ static NTSTATUS STDCALL I8042AddDevice(PDRIVER_OBJECT DriverObject,
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
AddRegistryEntry(L"KeyboardPort", &DeviceName, L"REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\i8042prt");
|
||||||
FdoDevExt = Fdo->DeviceExtension;
|
FdoDevExt = Fdo->DeviceExtension;
|
||||||
|
|
||||||
RtlZeroMemory(FdoDevExt, sizeof(FDO_DEVICE_EXTENSION));
|
RtlZeroMemory(FdoDevExt, sizeof(FDO_DEVICE_EXTENSION));
|
||||||
|
@ -764,6 +814,7 @@ static NTSTATUS STDCALL I8042AddDevice(PDRIVER_OBJECT DriverObject,
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
AddRegistryEntry(L"PointerPort", &MouseName, L"REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\i8042prt");
|
||||||
FdoDevExt = Fdo->DeviceExtension;
|
FdoDevExt = Fdo->DeviceExtension;
|
||||||
|
|
||||||
RtlZeroMemory(FdoDevExt, sizeof(FDO_DEVICE_EXTENSION));
|
RtlZeroMemory(FdoDevExt, sizeof(FDO_DEVICE_EXTENSION));
|
||||||
|
|
|
@ -1,302 +1,718 @@
|
||||||
/*
|
/*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS Keyboard class driver
|
||||||
* FILE: drivers/input/kbdclass/kbdclass.c
|
* FILE: drivers/kbdclass/kbdclass.c
|
||||||
* PURPOSE: Keyboard class driver
|
* PURPOSE: Keyboard class driver
|
||||||
* PROGRAMMER: Victor Kirhenshtein (sauros@iname.com)
|
*
|
||||||
* Jason Filby (jasonfilby@yahoo.com)
|
* PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
|
||||||
* Tinus_
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES ****************************************************************/
|
|
||||||
|
|
||||||
#include <ddk/ntddk.h>
|
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
#define INITGUID
|
||||||
#include "kbdclass.h"
|
#include "kbdclass.h"
|
||||||
|
|
||||||
/* GLOBALS *******************************************************************/
|
static VOID NTAPI
|
||||||
|
DriverUnload(IN PDRIVER_OBJECT DriverObject)
|
||||||
NTSTATUS STDCALL DriverEntry(PDRIVER_OBJECT DriverObject,
|
|
||||||
PUNICODE_STRING RegistryPath);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Driver data
|
|
||||||
*/
|
|
||||||
|
|
||||||
static BOOLEAN AlreadyOpened = FALSE;
|
|
||||||
|
|
||||||
static VOID STDCALL KbdCopyKeys(PDEVICE_OBJECT DeviceObject,
|
|
||||||
PIRP Irp)
|
|
||||||
{
|
{
|
||||||
PDEVICE_EXTENSION DevExt = DeviceObject->DeviceExtension;
|
// nothing to do here yet
|
||||||
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
|
}
|
||||||
ULONG NrToRead = stk->Parameters.Read.Length /
|
|
||||||
sizeof(KEYBOARD_INPUT_DATA);
|
|
||||||
ULONG NrRead = Irp->IoStatus.Information/sizeof(KEYBOARD_INPUT_DATA);
|
|
||||||
KEYBOARD_INPUT_DATA *Rec =
|
|
||||||
(KEYBOARD_INPUT_DATA *)Irp->AssociatedIrp.SystemBuffer;
|
|
||||||
|
|
||||||
while (DevExt->KeysInBuffer &&
|
static NTSTATUS NTAPI
|
||||||
NrRead < NrToRead) {
|
KbdclassCreate(
|
||||||
memcpy(&Rec[NrRead],
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
&DevExt->KbdBuffer[DevExt->BufHead],
|
IN PIRP Irp)
|
||||||
sizeof(KEYBOARD_INPUT_DATA));
|
{
|
||||||
|
DPRINT("IRP_MJ_CREATE\n");
|
||||||
|
|
||||||
if (++DevExt->BufHead >= KBD_BUFFER_SIZE)
|
if (!((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsClassDO)
|
||||||
DevExt->BufHead = 0;
|
return ForwardIrpAndForget(DeviceObject, Irp);
|
||||||
|
|
||||||
DevExt->KeysInBuffer--;
|
/* FIXME: open all associated Port devices */
|
||||||
NrRead++;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
Irp->IoStatus.Information = NrRead * sizeof(KEYBOARD_INPUT_DATA);
|
|
||||||
|
|
||||||
if (NrRead < NrToRead) {
|
static NTSTATUS NTAPI
|
||||||
Irp->IoStatus.Status = STATUS_PENDING;
|
KbdclassClose(
|
||||||
DPRINT("Pending... (NrRead %d, NrToRead %d\n", NrRead, NrToRead);
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
} else {
|
IN PIRP Irp)
|
||||||
DPRINT("Send scancode: %x\n", ((KEYBOARD_INPUT_DATA*)Irp->AssociatedIrp.SystemBuffer)->MakeCode);
|
{
|
||||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
DPRINT("IRP_MJ_CLOSE\n");
|
||||||
|
|
||||||
|
if (!((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsClassDO)
|
||||||
|
return ForwardIrpAndForget(DeviceObject, Irp);
|
||||||
|
|
||||||
|
/* FIXME: close all associated Port devices */
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS NTAPI
|
||||||
|
KbdclassRead(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
DPRINT("IRP_MJ_READ\n");
|
||||||
|
|
||||||
|
if (!((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsClassDO)
|
||||||
|
return ForwardIrpAndForget(DeviceObject, Irp);
|
||||||
|
|
||||||
|
if (IoGetCurrentIrpStackLocation(Irp)->Parameters.Read.Length < sizeof(KEYBOARD_INPUT_DATA))
|
||||||
|
{
|
||||||
|
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
IoStartNextPacket (DeviceObject, FALSE);
|
|
||||||
DPRINT("Success!\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static VOID STDCALL KbdClassServiceCallback (
|
return STATUS_BUFFER_TOO_SMALL;
|
||||||
PDEVICE_OBJECT DeviceObject,
|
|
||||||
PKEYBOARD_INPUT_DATA InputDataStart,
|
|
||||||
PKEYBOARD_INPUT_DATA InputDataEnd,
|
|
||||||
PULONG InputDataConsumed)
|
|
||||||
{
|
|
||||||
PDEVICE_EXTENSION DevExt = DeviceObject->DeviceExtension;
|
|
||||||
PKEYBOARD_INPUT_DATA CurrentInput = InputDataStart;
|
|
||||||
|
|
||||||
DPRINT("ServiceCallback called\n");
|
|
||||||
|
|
||||||
while (DevExt->KeysInBuffer < KBD_BUFFER_SIZE &&
|
|
||||||
CurrentInput < InputDataEnd) {
|
|
||||||
memcpy(&DevExt->KbdBuffer[DevExt->BufTail],
|
|
||||||
CurrentInput,
|
|
||||||
sizeof(KEYBOARD_INPUT_DATA));
|
|
||||||
|
|
||||||
if (++DevExt->BufTail >= KBD_BUFFER_SIZE)
|
|
||||||
DevExt->BufTail = 0;
|
|
||||||
DevExt->KeysInBuffer++;
|
|
||||||
|
|
||||||
CurrentInput++;
|
|
||||||
InputDataConsumed[0]++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CurrentInput < InputDataStart)
|
IoMarkIrpPending(Irp);
|
||||||
/* Copy the rest to the beginning, perhaps the keyboard
|
IoStartPacket(DeviceObject, Irp, NULL, NULL);
|
||||||
* can buffer it for us */
|
return STATUS_PENDING;
|
||||||
memmove(InputDataStart,
|
|
||||||
CurrentInput,
|
|
||||||
((char *)InputDataEnd - (char *)CurrentInput));
|
|
||||||
|
|
||||||
if (DeviceObject->CurrentIrp) {
|
|
||||||
PIRP Irp = DeviceObject->CurrentIrp;
|
|
||||||
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
|
|
||||||
if (stk->MajorFunction == IRP_MJ_READ)
|
|
||||||
KbdCopyKeys(DeviceObject, Irp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID STDCALL KbdStartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
static NTSTATUS NTAPI
|
||||||
|
KbdclassDeviceControl(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
/* We only do this for read irps */
|
|
||||||
DPRINT("KeyboardStartIo(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
|
|
||||||
KbdCopyKeys(DeviceObject, Irp);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* These are just passed down the stack but we must change the IOCTL to be
|
|
||||||
* INTERNAL. MSDN says there might be more...
|
|
||||||
*/
|
|
||||||
static NTSTATUS STDCALL KbdDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|
||||||
{
|
|
||||||
PDEVICE_EXTENSION DevExt = DeviceObject->DeviceExtension;
|
|
||||||
PIO_STACK_LOCATION Stk = IoGetCurrentIrpStackLocation(Irp);
|
|
||||||
PIO_STACK_LOCATION NextStk = IoGetNextIrpStackLocation(Irp);
|
|
||||||
|
|
||||||
DPRINT ("KbdDeviceControl %x\n", Stk->Parameters.DeviceIoControl.IoControlCode);
|
|
||||||
|
|
||||||
switch (Stk->Parameters.DeviceIoControl.IoControlCode) {
|
|
||||||
case IOCTL_KEYBOARD_QUERY_ATTRIBUTES:
|
|
||||||
case IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION:
|
|
||||||
case IOCTL_KEYBOARD_QUERY_INDICATORS:
|
|
||||||
case IOCTL_KEYBOARD_QUERY_TYPEMATIC:
|
|
||||||
case IOCTL_KEYBOARD_SET_INDICATORS:
|
|
||||||
case IOCTL_KEYBOARD_SET_TYPEMATIC: /* not in MSDN, would seem logical */
|
|
||||||
IoCopyCurrentIrpStackLocationToNext(Irp);
|
|
||||||
NextStk->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
|
|
||||||
|
|
||||||
return IoCallDriver(DevExt->I8042Device, Irp);
|
|
||||||
default:
|
|
||||||
return STATUS_INVALID_DEVICE_REQUEST;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static NTSTATUS STDCALL KbdInternalDeviceControl(PDEVICE_OBJECT DeviceObject,
|
|
||||||
PIRP Irp)
|
|
||||||
{
|
|
||||||
PDEVICE_EXTENSION DevExt = DeviceObject->DeviceExtension;
|
|
||||||
|
|
||||||
DPRINT ("KbdInternalDeviceControl\n");
|
|
||||||
|
|
||||||
IoSkipCurrentIrpStackLocation(Irp);
|
|
||||||
return IoCallDriver(DevExt->I8042Device, Irp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static NTSTATUS STDCALL KbdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|
||||||
{
|
|
||||||
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT("DeviceObject %x\n",DeviceObject);
|
DPRINT("IRP_MJ_DEVICE_CONTROL\n");
|
||||||
DPRINT("Irp %x\n",Irp);
|
|
||||||
|
if (!((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsClassDO)
|
||||||
|
return ForwardIrpAndForget(DeviceObject, Irp);
|
||||||
|
|
||||||
DPRINT("Dispatch: stk->MajorFunction %d\n", stk->MajorFunction);
|
switch (IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode)
|
||||||
DPRINT("AlreadyOpened %d\n",AlreadyOpened);
|
{
|
||||||
|
case IOCTL_KEYBOARD_QUERY_ATTRIBUTES:
|
||||||
switch (stk->MajorFunction) {
|
case IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION:
|
||||||
case IRP_MJ_CREATE:
|
case IOCTL_KEYBOARD_QUERY_INDICATORS:
|
||||||
if (AlreadyOpened == TRUE) {
|
case IOCTL_KEYBOARD_QUERY_TYPEMATIC:
|
||||||
CHECKPOINT;
|
case IOCTL_KEYBOARD_SET_INDICATORS:
|
||||||
Status = STATUS_UNSUCCESSFUL;
|
case IOCTL_KEYBOARD_SET_TYPEMATIC: /* not in MSDN, would seem logical */
|
||||||
DPRINT1("Keyboard is already open\n");
|
/* FIXME: send it to all associated Port devices */
|
||||||
} else {
|
Status = STATUS_NOT_SUPPORTED;
|
||||||
CHECKPOINT;
|
break;
|
||||||
Status = STATUS_SUCCESS;
|
default:
|
||||||
AlreadyOpened = TRUE;
|
DPRINT1("IRP_MJ_DEVICE_CONTROL / unknown I/O control code 0x%lx\n",
|
||||||
}
|
IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode);
|
||||||
break;
|
Status = STATUS_NOT_SUPPORTED;
|
||||||
|
|
||||||
case IRP_MJ_CLOSE:
|
|
||||||
Status = STATUS_SUCCESS;
|
|
||||||
AlreadyOpened = FALSE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IRP_MJ_READ:
|
|
||||||
DPRINT("Queueing packet\n");
|
|
||||||
IoMarkIrpPending(Irp);
|
|
||||||
IoStartPacket(DeviceObject,Irp,NULL,NULL);
|
|
||||||
return(STATUS_PENDING);
|
|
||||||
|
|
||||||
default:
|
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
IoCompleteRequest(Irp,IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
DPRINT("Status %d\n",Status);
|
|
||||||
return(Status);
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID STDCALL KbdClassSendConnect(PDEVICE_EXTENSION DevExt)
|
static NTSTATUS NTAPI
|
||||||
|
IrpStub(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
CONNECT_DATA ConnectData;
|
NTSTATUS Status = STATUS_NOT_SUPPORTED;
|
||||||
KEVENT Event;
|
|
||||||
IO_STATUS_BLOCK IoStatus;
|
if (!((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsClassDO)
|
||||||
|
{
|
||||||
|
/* Forward some IRPs to lower device */
|
||||||
|
switch (IoGetCurrentIrpStackLocation(Irp)->MajorFunction)
|
||||||
|
{
|
||||||
|
case IRP_MJ_INTERNAL_DEVICE_CONTROL:
|
||||||
|
return ForwardIrpAndForget(DeviceObject, Irp);
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
DPRINT1("Port DO stub for major function 0x%lx\n",
|
||||||
|
IoGetCurrentIrpStackLocation(Irp)->MajorFunction);
|
||||||
|
ASSERT(FALSE);
|
||||||
|
Status = Irp->IoStatus.Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT1("Class DO stub for major function 0x%lx\n",
|
||||||
|
IoGetCurrentIrpStackLocation(Irp)->MajorFunction);
|
||||||
|
ASSERT(FALSE);
|
||||||
|
Status = Irp->IoStatus.Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = Status;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS
|
||||||
|
ReadRegistryEntries(
|
||||||
|
IN PUNICODE_STRING RegistryPath,
|
||||||
|
IN PKBDCLASS_DRIVER_EXTENSION DriverExtension)
|
||||||
|
{
|
||||||
|
RTL_QUERY_REGISTRY_TABLE Parameters[4];
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
ULONG DefaultConnectMultiplePorts = 1;
|
||||||
|
ULONG DefaultKeyboardDataQueueSize = 0x64;
|
||||||
|
UNICODE_STRING DefaultKeyboardDeviceBaseName = RTL_CONSTANT_STRING(L"KeyboardClass");
|
||||||
|
|
||||||
|
RtlZeroMemory(Parameters, sizeof(Parameters));
|
||||||
|
|
||||||
|
Parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
||||||
|
Parameters[0].Name = L"ConnectMultiplePorts";
|
||||||
|
Parameters[0].EntryContext = &DriverExtension->ConnectMultiplePorts;
|
||||||
|
Parameters[0].DefaultType = REG_DWORD;
|
||||||
|
Parameters[0].DefaultData = &DefaultConnectMultiplePorts;
|
||||||
|
Parameters[0].DefaultLength = sizeof(ULONG);
|
||||||
|
|
||||||
|
Parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
||||||
|
Parameters[1].Name = L"KeyboardDataQueueSize";
|
||||||
|
Parameters[1].EntryContext = &DriverExtension->KeyboardDataQueueSize;
|
||||||
|
Parameters[1].DefaultType = REG_DWORD;
|
||||||
|
Parameters[1].DefaultData = &DefaultKeyboardDataQueueSize;
|
||||||
|
Parameters[1].DefaultLength = sizeof(ULONG);
|
||||||
|
|
||||||
|
Parameters[2].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
||||||
|
Parameters[2].Name = L"KeyboardDeviceBaseName";
|
||||||
|
Parameters[2].EntryContext = &DriverExtension->KeyboardDeviceBaseName;
|
||||||
|
Parameters[2].DefaultType = REG_SZ;
|
||||||
|
Parameters[2].DefaultData = &DefaultKeyboardDeviceBaseName;
|
||||||
|
Parameters[2].DefaultLength = sizeof(ULONG);
|
||||||
|
|
||||||
|
Status = RtlQueryRegistryValues(
|
||||||
|
RTL_REGISTRY_ABSOLUTE,
|
||||||
|
RegistryPath->Buffer,
|
||||||
|
Parameters,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Check values */
|
||||||
|
if (DriverExtension->ConnectMultiplePorts != 0
|
||||||
|
&& DriverExtension->ConnectMultiplePorts != 1)
|
||||||
|
{
|
||||||
|
DriverExtension->ConnectMultiplePorts = DefaultConnectMultiplePorts;
|
||||||
|
}
|
||||||
|
if (DriverExtension->KeyboardDataQueueSize == 0)
|
||||||
|
{
|
||||||
|
DriverExtension->KeyboardDataQueueSize = DefaultKeyboardDataQueueSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS
|
||||||
|
CreateKeyboardClassDeviceObject(
|
||||||
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
|
OUT PDEVICE_OBJECT *ClassDO OPTIONAL)
|
||||||
|
{
|
||||||
|
PKBDCLASS_DRIVER_EXTENSION DriverExtension;
|
||||||
|
ULONG DeviceId = 0;
|
||||||
|
ULONG PrefixLength;
|
||||||
|
UNICODE_STRING DeviceNameU;
|
||||||
|
PWSTR DeviceIdW = NULL; /* Pointer into DeviceNameU.Buffer */
|
||||||
|
PDEVICE_OBJECT Fdo;
|
||||||
|
PKBDCLASS_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
DPRINT("CreateKeyboardClassDeviceObject(0x%p)\n", DriverObject);
|
||||||
|
|
||||||
|
/* Create new device object */
|
||||||
|
DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
|
||||||
|
DeviceNameU.Length = 0;
|
||||||
|
DeviceNameU.MaximumLength =
|
||||||
|
wcslen(L"\\Device\\") * sizeof(WCHAR) /* "\Device\" */
|
||||||
|
+ DriverExtension->KeyboardDeviceBaseName.Length/* "KeyboardClass" */
|
||||||
|
+ 4 * sizeof(WCHAR) /* Id between 0 and 9999 */
|
||||||
|
+ sizeof(UNICODE_NULL); /* Final NULL char */
|
||||||
|
DeviceNameU.Buffer = ExAllocatePool(PagedPool, DeviceNameU.MaximumLength);
|
||||||
|
if (!DeviceNameU.Buffer)
|
||||||
|
{
|
||||||
|
DPRINT("ExAllocatePool() failed\n");
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
Status = RtlAppendUnicodeToString(&DeviceNameU, L"\\Device\\");
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("RtlAppendUnicodeToString() failed with status 0x%08lx\n", Status);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
Status = RtlAppendUnicodeStringToString(&DeviceNameU, &DriverExtension->KeyboardDeviceBaseName);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("RtlAppendUnicodeStringToString() failed with status 0x%08lx\n", Status);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
PrefixLength = DeviceNameU.MaximumLength - 4 * sizeof(WCHAR) - sizeof(UNICODE_NULL);
|
||||||
|
DeviceIdW = &DeviceNameU.Buffer[PrefixLength / sizeof(WCHAR)];
|
||||||
|
while (DeviceId < 9999)
|
||||||
|
{
|
||||||
|
DeviceNameU.Length = PrefixLength + swprintf(DeviceIdW, L"%lu", DeviceId) * sizeof(WCHAR);
|
||||||
|
Status = IoCreateDevice(
|
||||||
|
DriverObject,
|
||||||
|
sizeof(KBDCLASS_DEVICE_EXTENSION),
|
||||||
|
&DeviceNameU,
|
||||||
|
FILE_DEVICE_KEYBOARD,
|
||||||
|
FILE_DEVICE_SECURE_OPEN,
|
||||||
|
FALSE,
|
||||||
|
&Fdo);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
goto cleanup;
|
||||||
|
else if (Status != STATUS_OBJECT_NAME_COLLISION)
|
||||||
|
{
|
||||||
|
DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
DeviceId++;
|
||||||
|
}
|
||||||
|
DPRINT("Too much devices starting with '\\Device\\%wZ'\n", &DriverExtension->KeyboardDeviceBaseName);
|
||||||
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
|
cleanup:
|
||||||
|
ExFreePool(DeviceNameU.Buffer);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
DeviceExtension = (PKBDCLASS_DEVICE_EXTENSION)Fdo->DeviceExtension;
|
||||||
|
RtlZeroMemory(DeviceExtension, sizeof(KBDCLASS_DEVICE_EXTENSION));
|
||||||
|
DeviceExtension->Common.IsClassDO = TRUE;
|
||||||
|
DeviceExtension->DriverExtension = DriverExtension;
|
||||||
|
DeviceExtension->PnpState = dsStopped;
|
||||||
|
KeInitializeSpinLock(&(DeviceExtension->SpinLock));
|
||||||
|
DeviceExtension->ReadIsPending = FALSE;
|
||||||
|
DeviceExtension->InputCount = 0;
|
||||||
|
DeviceExtension->PortData = ExAllocatePool(NonPagedPool, DeviceExtension->DriverExtension->KeyboardDataQueueSize * sizeof(KEYBOARD_INPUT_DATA));
|
||||||
|
Fdo->Flags |= DO_POWER_PAGABLE;
|
||||||
|
Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||||
|
|
||||||
|
/* FIXME: create registry entry in HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP */
|
||||||
|
|
||||||
|
if (ClassDO)
|
||||||
|
*ClassDO = Fdo;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOLEAN
|
||||||
|
KbdclassCallback(
|
||||||
|
IN PDEVICE_OBJECT ClassDeviceObject,
|
||||||
|
IN OUT PKEYBOARD_INPUT_DATA KeyboardDataStart,
|
||||||
|
IN PKEYBOARD_INPUT_DATA KeyboardDataEnd,
|
||||||
|
IN OUT PULONG ConsumedCount)
|
||||||
|
{
|
||||||
|
PKBDCLASS_DEVICE_EXTENSION ClassDeviceExtension = ClassDeviceObject->DeviceExtension;
|
||||||
|
PIRP Irp = NULL;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
PIO_STACK_LOCATION Stack;
|
||||||
|
ULONG InputCount = KeyboardDataEnd - KeyboardDataStart;
|
||||||
|
ULONG ReadSize;
|
||||||
|
|
||||||
|
ASSERT(ClassDeviceExtension->Common.IsClassDO);
|
||||||
|
|
||||||
|
DPRINT("KbdclassCallback()\n");
|
||||||
|
/* A filter driver might have consumed all the data already; I'm
|
||||||
|
* not sure if they are supposed to move the packets when they
|
||||||
|
* consume them though.
|
||||||
|
*/
|
||||||
|
if (ClassDeviceExtension->ReadIsPending == TRUE && InputCount)
|
||||||
|
{
|
||||||
|
Irp = ClassDeviceObject->CurrentIrp;
|
||||||
|
ClassDeviceObject->CurrentIrp = NULL;
|
||||||
|
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
/* A read request is waiting for input, so go straight to it */
|
||||||
|
/* FIXME: use SEH */
|
||||||
|
RtlCopyMemory(
|
||||||
|
Irp->MdlAddress ? MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority) : Irp->UserBuffer,
|
||||||
|
KeyboardDataStart,
|
||||||
|
sizeof(KEYBOARD_INPUT_DATA));
|
||||||
|
|
||||||
|
/* Go to next packet and complete this request with STATUS_SUCCESS */
|
||||||
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
Irp->IoStatus.Information = sizeof(KEYBOARD_INPUT_DATA);
|
||||||
|
Stack->Parameters.Read.Length = sizeof(KEYBOARD_INPUT_DATA);
|
||||||
|
|
||||||
|
ClassDeviceExtension->ReadIsPending = FALSE;
|
||||||
|
|
||||||
|
/* Skip the packet we just sent away */
|
||||||
|
KeyboardDataStart++;
|
||||||
|
(*ConsumedCount)++;
|
||||||
|
InputCount--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we have data from the port driver and a higher service to send the data to */
|
||||||
|
if (InputCount != 0)
|
||||||
|
{
|
||||||
|
KeAcquireSpinLock(&ClassDeviceExtension->SpinLock, &OldIrql);
|
||||||
|
|
||||||
|
if (ClassDeviceExtension->InputCount + InputCount > ClassDeviceExtension->DriverExtension->KeyboardDataQueueSize)
|
||||||
|
ReadSize = ClassDeviceExtension->DriverExtension->KeyboardDataQueueSize - ClassDeviceExtension->InputCount;
|
||||||
|
else
|
||||||
|
ReadSize = InputCount;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIXME: If we exceed the buffer, keyboard data gets thrown away.. better
|
||||||
|
* solution?
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Move the keyboard input data from the port data queue to our class data
|
||||||
|
* queue.
|
||||||
|
*/
|
||||||
|
RtlMoveMemory(
|
||||||
|
ClassDeviceExtension->PortData,
|
||||||
|
(PCHAR)KeyboardDataStart,
|
||||||
|
sizeof(KEYBOARD_INPUT_DATA) * ReadSize);
|
||||||
|
|
||||||
|
/* Move the pointer and counter up */
|
||||||
|
ClassDeviceExtension->PortData += ReadSize;
|
||||||
|
ClassDeviceExtension->InputCount += ReadSize;
|
||||||
|
|
||||||
|
KeReleaseSpinLock(&ClassDeviceExtension->SpinLock, OldIrql);
|
||||||
|
(*ConsumedCount) += ReadSize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT("KbdclassCallBack() entered, InputCount = %lu - DOING NOTHING\n", InputCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Irp != NULL)
|
||||||
|
{
|
||||||
|
IoStartNextPacket(ClassDeviceObject, FALSE);
|
||||||
|
IoCompleteRequest(Irp, IO_KEYBOARD_INCREMENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT("Leaving KbdclassCallback()\n");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send IOCTL_INTERNAL_KEYBOARD_CONNECT to keyboard port */
|
||||||
|
static NTSTATUS
|
||||||
|
ConnectKeyboardPortDriver(
|
||||||
|
IN PDEVICE_OBJECT KeyboardPortDO,
|
||||||
|
IN PDEVICE_OBJECT KeyboardClassDO)
|
||||||
|
{
|
||||||
|
KEVENT Event;
|
||||||
PIRP Irp;
|
PIRP Irp;
|
||||||
|
IO_STATUS_BLOCK IoStatus;
|
||||||
|
CONNECT_DATA ConnectData;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||||
|
|
||||||
ConnectData.ClassDeviceObject = DevExt->DeviceObject;
|
ConnectData.ClassDeviceObject = KeyboardClassDO;
|
||||||
ConnectData.ClassService = KbdClassServiceCallback;
|
ConnectData.ClassService = KbdclassCallback;
|
||||||
|
|
||||||
Irp = IoBuildDeviceIoControlRequest(
|
Irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_KEYBOARD_CONNECT,
|
||||||
IOCTL_INTERNAL_KEYBOARD_CONNECT,
|
KeyboardPortDO,
|
||||||
DevExt->I8042Device,
|
&ConnectData, sizeof(CONNECT_DATA),
|
||||||
&ConnectData,
|
NULL, 0,
|
||||||
sizeof(CONNECT_DATA),
|
TRUE, &Event, &IoStatus);
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
TRUE,
|
|
||||||
&Event,
|
|
||||||
&IoStatus);
|
|
||||||
|
|
||||||
if (!Irp)
|
Status = IoCallDriver(KeyboardPortDO, Irp);
|
||||||
return;
|
|
||||||
|
|
||||||
Status = IoCallDriver(
|
if (Status == STATUS_PENDING)
|
||||||
DevExt->I8042Device,
|
KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
|
||||||
Irp);
|
else
|
||||||
DPRINT("SendConnect status: %x\n", Status);
|
IoStatus.Status = Status;
|
||||||
|
|
||||||
if (STATUS_PENDING ==Status)
|
return IoStatus.Status;
|
||||||
KeWaitForSingleObject(&Event,
|
|
||||||
Executive,
|
|
||||||
KernelMode,
|
|
||||||
FALSE,
|
|
||||||
NULL);
|
|
||||||
DPRINT("SendConnect done\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS STDCALL DriverEntry(PDRIVER_OBJECT DriverObject,
|
static NTSTATUS NTAPI
|
||||||
PUNICODE_STRING RegistryPath)
|
KbdclassAddDevice(
|
||||||
/*
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
* FUNCTION: Module entry point
|
IN PDEVICE_OBJECT Pdo)
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
PDEVICE_OBJECT DeviceObject;
|
PKBDCLASS_DRIVER_EXTENSION DriverExtension;
|
||||||
PDEVICE_EXTENSION DevExt;
|
PDEVICE_OBJECT Fdo;
|
||||||
PFILE_OBJECT I8042File;
|
PKBDCLASS_DEVICE_EXTENSION DeviceExtension;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\Keyboard");
|
|
||||||
UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\??\\Keyboard");
|
|
||||||
UNICODE_STRING I8042Name = RTL_CONSTANT_STRING(L"\\Device\\KeyboardClass0");
|
|
||||||
|
|
||||||
DPRINT("Keyboard Class Driver 0.0.1\n");
|
DPRINT("KbdclassAddDevice called. Pdo = 0x%p\n", Pdo);
|
||||||
|
|
||||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = KbdDispatch;
|
DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
|
||||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = KbdDispatch;
|
|
||||||
DriverObject->MajorFunction[IRP_MJ_READ] = KbdDispatch;
|
|
||||||
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] =
|
|
||||||
KbdInternalDeviceControl;
|
|
||||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = KbdDeviceControl;
|
|
||||||
|
|
||||||
DriverObject->DriverStartIo = KbdStartIo;
|
/* Create new device object */
|
||||||
|
Status = IoCreateDevice(
|
||||||
IoCreateDevice(DriverObject,
|
DriverObject,
|
||||||
sizeof(DEVICE_EXTENSION),
|
sizeof(KBDCLASS_DEVICE_EXTENSION),
|
||||||
&DeviceName,
|
NULL,
|
||||||
FILE_DEVICE_KEYBOARD,
|
Pdo->DeviceType,
|
||||||
0,
|
FILE_DEVICE_SECURE_OPEN,
|
||||||
TRUE,
|
FALSE,
|
||||||
&DeviceObject);
|
&Fdo);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
RtlZeroMemory(DeviceObject->DeviceExtension, sizeof(DEVICE_EXTENSION));
|
{
|
||||||
DevExt = DeviceObject->DeviceExtension;
|
DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status);
|
||||||
DevExt->DeviceObject = DeviceObject;
|
|
||||||
|
|
||||||
Status = IoGetDeviceObjectPointer(&I8042Name,
|
|
||||||
FILE_READ_DATA,
|
|
||||||
&I8042File,
|
|
||||||
&DevExt->I8042Device);
|
|
||||||
|
|
||||||
if (STATUS_SUCCESS != Status) {
|
|
||||||
DPRINT("Failed to open device: %x\n", Status);
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObReferenceObject(DevExt->I8042Device);
|
DeviceExtension = (PKBDCLASS_DEVICE_EXTENSION)Fdo->DeviceExtension;
|
||||||
ObDereferenceObject(I8042File);
|
RtlZeroMemory(DeviceExtension, sizeof(KBDCLASS_DEVICE_EXTENSION));
|
||||||
|
DeviceExtension->Common.IsClassDO = FALSE;
|
||||||
|
DeviceExtension->PnpState = dsStopped;
|
||||||
|
Fdo->Flags |= DO_POWER_PAGABLE;
|
||||||
|
Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
|
||||||
|
IoDeleteDevice(Fdo);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
Fdo->Flags |= DO_BUFFERED_IO;
|
||||||
|
Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||||
|
|
||||||
DeviceObject->Flags = DeviceObject->Flags | DO_BUFFERED_IO;
|
if (DriverExtension->ConnectMultiplePorts)
|
||||||
|
Status = ConnectKeyboardPortDriver(Fdo, DriverExtension->MainKbdclassDeviceObject);
|
||||||
|
else
|
||||||
|
Status = ConnectKeyboardPortDriver(Fdo, Fdo);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("ConnectKeyboardPortDriver() failed with status 0x%08lx\n", Status);
|
||||||
|
/* FIXME: why can't I cleanup without error? */
|
||||||
|
//IoDetachDevice(Fdo);
|
||||||
|
//IoDeleteDevice(Fdo);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
DeviceObject->StackSize = 1 + DevExt->I8042Device->StackSize;
|
/* Register GUID_DEVINTERFACE_KEYBOARD interface */
|
||||||
|
Status = IoRegisterDeviceInterface(
|
||||||
|
Pdo,
|
||||||
|
&GUID_DEVINTERFACE_KEYBOARD,
|
||||||
|
NULL,
|
||||||
|
&DeviceExtension->KeyboardInterfaceName);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("IoRegisterDeviceInterface() failed with status 0x%08lx\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
IoCreateSymbolicLink(&SymlinkName, &DeviceName);
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
KbdClassSendConnect(DevExt);
|
|
||||||
|
static VOID NTAPI
|
||||||
return(STATUS_SUCCESS);
|
KbdclassStartIo(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
PKBDCLASS_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
|
||||||
|
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
ASSERT(DeviceExtension->Common.IsClassDO);
|
||||||
|
|
||||||
|
if (DeviceExtension->InputCount > 0)
|
||||||
|
{
|
||||||
|
KIRQL oldIrql;
|
||||||
|
|
||||||
|
KeAcquireSpinLock(&DeviceExtension->SpinLock, &oldIrql);
|
||||||
|
|
||||||
|
/* FIXME: use SEH */
|
||||||
|
RtlCopyMemory(
|
||||||
|
Irp->MdlAddress ? MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority) : Irp->UserBuffer,
|
||||||
|
DeviceExtension->PortData - DeviceExtension->InputCount,
|
||||||
|
sizeof(KEYBOARD_INPUT_DATA));
|
||||||
|
|
||||||
|
if (DeviceExtension->InputCount > 1)
|
||||||
|
{
|
||||||
|
RtlMoveMemory(
|
||||||
|
DeviceExtension->PortData - DeviceExtension->InputCount,
|
||||||
|
DeviceExtension->PortData - DeviceExtension->InputCount + 1,
|
||||||
|
(DeviceExtension->InputCount - 1) * sizeof(KEYBOARD_INPUT_DATA));
|
||||||
|
}
|
||||||
|
DeviceExtension->PortData--;
|
||||||
|
DeviceExtension->InputCount--;
|
||||||
|
DeviceExtension->ReadIsPending = FALSE;
|
||||||
|
|
||||||
|
/* Go to next packet and complete this request with STATUS_SUCCESS */
|
||||||
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
Irp->IoStatus.Information = sizeof(KEYBOARD_INPUT_DATA);
|
||||||
|
Stack->Parameters.Read.Length = sizeof(KEYBOARD_INPUT_DATA);
|
||||||
|
IoCompleteRequest(Irp, IO_KEYBOARD_INCREMENT);
|
||||||
|
|
||||||
|
IoStartNextPacket(DeviceObject, FALSE);
|
||||||
|
KeReleaseSpinLock(&DeviceExtension->SpinLock, oldIrql);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DeviceExtension->ReadIsPending = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS
|
||||||
|
SearchForLegacyDrivers(
|
||||||
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
|
IN PKBDCLASS_DRIVER_EXTENSION DriverExtension)
|
||||||
|
{
|
||||||
|
UNICODE_STRING DeviceMapKeyU = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\HARDWARE\\DEVICEMAP");
|
||||||
|
UNICODE_STRING PortBaseName = {0, };
|
||||||
|
PKEY_VALUE_BASIC_INFORMATION KeyValueInformation = NULL;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
HANDLE hDeviceMapKey = (HANDLE)-1;
|
||||||
|
HANDLE hPortKey = (HANDLE)-1;
|
||||||
|
ULONG Index = 0;
|
||||||
|
ULONG Size, ResultLength;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* Create port base name, by replacing Class by Port at the end of the class base name */
|
||||||
|
Status = RtlDuplicateUnicodeString(
|
||||||
|
RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
|
||||||
|
&DriverExtension->KeyboardDeviceBaseName,
|
||||||
|
&PortBaseName);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("RtlDuplicateUnicodeString() failed with status 0x%08lx\n", Status);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
PortBaseName.Length -= (sizeof(L"Class") - sizeof(UNICODE_NULL));
|
||||||
|
RtlAppendUnicodeToString(&PortBaseName, L"Port");
|
||||||
|
|
||||||
|
/* Allocate memory */
|
||||||
|
Size = sizeof(KEY_VALUE_BASIC_INFORMATION) + MAX_PATH;
|
||||||
|
KeyValueInformation = ExAllocatePool(PagedPool, Size);
|
||||||
|
if (!KeyValueInformation)
|
||||||
|
{
|
||||||
|
DPRINT("ExAllocatePool() failed\n");
|
||||||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP */
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes, &DeviceMapKeyU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||||
|
Status = ZwOpenKey(&hDeviceMapKey, 0, &ObjectAttributes);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open sub key */
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes, &PortBaseName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, hDeviceMapKey, NULL);
|
||||||
|
Status = ZwOpenKey(&hPortKey, KEY_QUERY_VALUE, &ObjectAttributes);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
|
||||||
|
DPRINT1("ZwOpenKey() failed with status 0x%08lx\n", Status);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read each value name */
|
||||||
|
while (ZwEnumerateValueKey(hPortKey, Index++, KeyValueBasicInformation, KeyValueInformation, Size, &ResultLength) == STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
UNICODE_STRING PortName;
|
||||||
|
PDEVICE_OBJECT PortDeviceObject = NULL;
|
||||||
|
PFILE_OBJECT FileObject = NULL;
|
||||||
|
|
||||||
|
PortName.Length = PortName.MaximumLength = KeyValueInformation->NameLength;
|
||||||
|
PortName.Buffer = KeyValueInformation->Name;
|
||||||
|
|
||||||
|
/* Open the device object pointer */
|
||||||
|
Status = IoGetDeviceObjectPointer(&PortName, FILE_READ_ATTRIBUTES, &FileObject, &PortDeviceObject);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("IoGetDeviceObjectPointer(%wZ) failed with status 0x%08lx\n", Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Connect the port device object */
|
||||||
|
if (DriverExtension->ConnectMultiplePorts)
|
||||||
|
{
|
||||||
|
Status = ConnectKeyboardPortDriver(PortDeviceObject, DriverExtension->MainKbdclassDeviceObject);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* FIXME: Log the error */
|
||||||
|
DPRINT("ConnectKeyboardPortDriver() failed with status 0x%08lx\n", Status);
|
||||||
|
/* FIXME: cleanup */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PDEVICE_OBJECT ClassDO;
|
||||||
|
Status = CreateKeyboardClassDeviceObject(DriverObject, &ClassDO);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* FIXME: Log the error */
|
||||||
|
DPRINT("CreatePointerClassDeviceObject() failed with status 0x%08lx\n", Status);
|
||||||
|
/* FIXME: cleanup */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Status = ConnectKeyboardPortDriver(PortDeviceObject, ClassDO);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* FIXME: Log the error */
|
||||||
|
DPRINT("ConnectKeyboardPortDriver() failed with status 0x%08lx\n", Status);
|
||||||
|
/* FIXME: cleanup */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Status == STATUS_NO_MORE_ENTRIES)
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (KeyValueInformation != NULL)
|
||||||
|
ExFreePool(KeyValueInformation);
|
||||||
|
if (hDeviceMapKey != (HANDLE)-1)
|
||||||
|
ZwClose(hDeviceMapKey);
|
||||||
|
if (hPortKey != (HANDLE)-1)
|
||||||
|
ZwClose(hPortKey);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Standard DriverEntry method.
|
||||||
|
*/
|
||||||
|
NTSTATUS NTAPI
|
||||||
|
DriverEntry(
|
||||||
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
|
IN PUNICODE_STRING RegistryPath)
|
||||||
|
{
|
||||||
|
PKBDCLASS_DRIVER_EXTENSION DriverExtension;
|
||||||
|
ULONG i;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
Status = IoAllocateDriverObjectExtension(
|
||||||
|
DriverObject,
|
||||||
|
DriverObject,
|
||||||
|
sizeof(KBDCLASS_DRIVER_EXTENSION),
|
||||||
|
(PVOID*)&DriverExtension);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("IoAllocateDriverObjectExtension() failed with status 0x%08lx\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
RtlZeroMemory(DriverExtension, sizeof(KBDCLASS_DRIVER_EXTENSION));
|
||||||
|
|
||||||
|
Status = ReadRegistryEntries(RegistryPath, DriverExtension);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("ReadRegistryEntries() failed with status 0x%08lx\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DriverExtension->ConnectMultiplePorts == 1)
|
||||||
|
{
|
||||||
|
Status = CreateKeyboardClassDeviceObject(
|
||||||
|
DriverObject,
|
||||||
|
&DriverExtension->MainKbdclassDeviceObject);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("CreateKeyboardClassDeviceObject() failed with status 0x%08lx\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DriverObject->DriverExtension->AddDevice = KbdclassAddDevice;
|
||||||
|
DriverObject->DriverUnload = DriverUnload;
|
||||||
|
|
||||||
|
for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
|
||||||
|
DriverObject->MajorFunction[i] = IrpStub;
|
||||||
|
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_CREATE] = KbdclassCreate;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_CLOSE] = KbdclassClose;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_READ] = KbdclassRead;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = KbdclassDeviceControl;
|
||||||
|
DriverObject->DriverStartIo = KbdclassStartIo;
|
||||||
|
|
||||||
|
Status = SearchForLegacyDrivers(DriverObject, DriverExtension);
|
||||||
|
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,98 +1,65 @@
|
||||||
#ifndef _KEYBOARD_H_
|
#include <ntifs.h>
|
||||||
#define _KEYBOARD_H_
|
#include <kbdmou.h>
|
||||||
#include <ddk/ntddkbd.h>
|
#include <ntddkbd.h>
|
||||||
#include <ddk/ntdd8042.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#define KBD_BUFFER_SIZE 32
|
#if defined(__GNUC__)
|
||||||
#define KBD_WRAP_MASK 0x1F
|
NTSTATUS NTAPI
|
||||||
|
IoAttachDeviceToDeviceStackSafe(
|
||||||
|
IN PDEVICE_OBJECT SourceDevice,
|
||||||
|
IN PDEVICE_OBJECT TargetDevice,
|
||||||
|
OUT PDEVICE_OBJECT *AttachedToDeviceObject);
|
||||||
|
#else
|
||||||
|
#error Unknown compiler!
|
||||||
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------
|
typedef enum
|
||||||
* DeviceExtension
|
|
||||||
* --------------------------------------------------*/
|
|
||||||
typedef struct _DEVICE_EXTENSION
|
|
||||||
{
|
{
|
||||||
PDEVICE_OBJECT I8042Device;
|
dsStopped,
|
||||||
PDEVICE_OBJECT DeviceObject;
|
dsStarted,
|
||||||
|
dsPaused,
|
||||||
|
dsRemoved,
|
||||||
|
dsSurpriseRemoved
|
||||||
|
} KBDCLASS_DEVICE_STATE;
|
||||||
|
|
||||||
KEYBOARD_INPUT_DATA KbdBuffer[KBD_BUFFER_SIZE];
|
typedef struct _KBDCLASS_DRIVER_EXTENSION
|
||||||
int BufHead,BufTail;
|
{
|
||||||
int KeysInBuffer;
|
/* Registry settings */
|
||||||
|
ULONG ConnectMultiplePorts;
|
||||||
|
ULONG KeyboardDataQueueSize;
|
||||||
|
UNICODE_STRING KeyboardDeviceBaseName;
|
||||||
|
|
||||||
BOOLEAN AlreadyOpened;
|
PDEVICE_OBJECT MainKbdclassDeviceObject;
|
||||||
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
|
} KBDCLASS_DRIVER_EXTENSION, *PKBDCLASS_DRIVER_EXTENSION;
|
||||||
|
|
||||||
typedef struct _CONNECT_DATA {
|
typedef struct _COMMON_DEVICE_EXTENSION
|
||||||
PDEVICE_OBJECT ClassDeviceObject;
|
{
|
||||||
PVOID ClassService;
|
BOOLEAN IsClassDO;
|
||||||
} CONNECT_DATA, *PCONNECT_DATA;
|
} COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION;
|
||||||
|
|
||||||
/*
|
typedef struct _KBDPORT_DEVICE_EXTENSION
|
||||||
* Some defines
|
{
|
||||||
*/
|
COMMON_DEVICE_EXTENSION Common;
|
||||||
|
} KBDPORT_DEVICE_EXTENSION, *PKBDPORT_DEVICE_EXTENSION;
|
||||||
|
|
||||||
#define IOCTL_INTERNAL_KEYBOARD_CONNECT \
|
typedef struct _KBDCLASS_DEVICE_EXTENSION
|
||||||
CTL_CODE(FILE_DEVICE_KEYBOARD, 0x0080, METHOD_NEITHER, FILE_ANY_ACCESS)
|
{
|
||||||
|
COMMON_DEVICE_EXTENSION Common;
|
||||||
|
|
||||||
#define KEYBOARD_IRQ 1
|
KBDCLASS_DEVICE_STATE PnpState;
|
||||||
|
PKBDCLASS_DRIVER_EXTENSION DriverExtension;
|
||||||
|
PDEVICE_OBJECT LowerDevice;
|
||||||
|
UNICODE_STRING KeyboardInterfaceName;
|
||||||
|
|
||||||
#define disable() __asm__("cli\n\t")
|
KSPIN_LOCK SpinLock;
|
||||||
#define enable() __asm__("sti\n\t")
|
BOOLEAN ReadIsPending;
|
||||||
|
ULONG InputCount;
|
||||||
|
PKEYBOARD_INPUT_DATA PortData;
|
||||||
|
} KBDCLASS_DEVICE_EXTENSION, *PKBDCLASS_DEVICE_EXTENSION;
|
||||||
|
|
||||||
#define ALT_PRESSED (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)
|
/* misc.c */
|
||||||
#define CTRL_PRESSED (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)
|
|
||||||
|
|
||||||
|
NTSTATUS NTAPI
|
||||||
/*
|
ForwardIrpAndForget(
|
||||||
* Keyboard controller ports
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
*/
|
IN PIRP Irp);
|
||||||
|
|
||||||
#define KBD_DATA_PORT 0x60
|
|
||||||
#define KBD_CTRL_PORT 0x64
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Controller commands
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define KBD_READ_MODE 0x20
|
|
||||||
#define KBD_WRITE_MODE 0x60
|
|
||||||
#define KBD_SELF_TEST 0xAA
|
|
||||||
#define KBD_LINE_TEST 0xAB
|
|
||||||
#define KBD_CTRL_ENABLE 0xAE
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Keyboard commands
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define KBD_ENABLE 0xF4
|
|
||||||
#define KBD_DISABLE 0xF5
|
|
||||||
#define KBD_RESET 0xFF
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Keyboard responces
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define KBD_ACK 0xFA
|
|
||||||
#define KBD_BATCC 0xAA
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Controller status register bits
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define KBD_OBF 0x01
|
|
||||||
#define KBD_IBF 0x02
|
|
||||||
#define KBD_GTO 0x40
|
|
||||||
#define KBD_PERR 0x80
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* LED bits
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define KBD_LED_SCROLL 0x01
|
|
||||||
#define KBD_LED_NUM 0x02
|
|
||||||
#define KBD_LED_CAPS 0x04
|
|
||||||
|
|
||||||
#endif // _KEYBOARD_H_
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<module name="kbdclass" type="kernelmodedriver" installbase="system32/drivers" installname="kbdclass.sys">
|
<module name="kbdclass" type="kernelmodedriver" installbase="system32/drivers" installname="kbdclass.sys">
|
||||||
<bootstrap base="reactos" />
|
<bootstrap base="reactos" />
|
||||||
<include base="kbdclass">.</include>
|
|
||||||
<define name="__USE_W32API" />
|
<define name="__USE_W32API" />
|
||||||
<library>ntoskrnl</library>
|
<library>ntoskrnl</library>
|
||||||
<library>hal</library>
|
<library>hal</library>
|
||||||
<file>kbdclass.c</file>
|
<file>kbdclass.c</file>
|
||||||
|
<file>misc.c</file>
|
||||||
<file>kbdclass.rc</file>
|
<file>kbdclass.rc</file>
|
||||||
</module>
|
</module>
|
||||||
|
|
61
reactos/drivers/input/kbdclass/misc.c
Normal file
61
reactos/drivers/input/kbdclass/misc.c
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS Keyboard class driver
|
||||||
|
* FILE: drivers/input/kbdclass/misc.c
|
||||||
|
* PURPOSE: Misceallenous operations
|
||||||
|
*
|
||||||
|
* PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include "kbdclass.h"
|
||||||
|
|
||||||
|
static NTSTATUS NTAPI
|
||||||
|
ForwardIrpAndWaitCompletion(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN PVOID Context)
|
||||||
|
{
|
||||||
|
if (Irp->PendingReturned)
|
||||||
|
KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);
|
||||||
|
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
ForwardIrpAndWait(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
PDEVICE_OBJECT LowerDevice = ((PKBDCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
|
||||||
|
KEVENT Event;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||||
|
IoCopyCurrentIrpStackLocationToNext(Irp);
|
||||||
|
|
||||||
|
DPRINT("Calling lower device %p [%wZ]\n", LowerDevice, &LowerDevice->DriverObject->DriverName);
|
||||||
|
IoSetCompletionRoutine(Irp, ForwardIrpAndWaitCompletion, &Event, TRUE, TRUE, TRUE);
|
||||||
|
|
||||||
|
Status = IoCallDriver(LowerDevice, Irp);
|
||||||
|
if (Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
Status = KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
Status = Irp->IoStatus.Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS NTAPI
|
||||||
|
ForwardIrpAndForget(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
PDEVICE_OBJECT LowerDevice = ((PKBDCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
|
||||||
|
|
||||||
|
IoSkipCurrentIrpStackLocation(Irp);
|
||||||
|
return IoCallDriver(LowerDevice, Irp);
|
||||||
|
}
|
|
@ -94,10 +94,6 @@ IrpStub(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (IoGetCurrentIrpStackLocation(Irp)->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL) /* HACK FOR I8042PRT */
|
|
||||||
{
|
|
||||||
Status = STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DPRINT1("Class DO stub for major function 0x%lx\n",
|
DPRINT1("Class DO stub for major function 0x%lx\n",
|
||||||
|
@ -121,7 +117,7 @@ ReadRegistryEntries(
|
||||||
|
|
||||||
ULONG DefaultConnectMultiplePorts = 1;
|
ULONG DefaultConnectMultiplePorts = 1;
|
||||||
ULONG DefaultMouseDataQueueSize = 0x64;
|
ULONG DefaultMouseDataQueueSize = 0x64;
|
||||||
UNICODE_STRING DefaultPointerDeviceBaseName = RTL_CONSTANT_STRING(L"PointerClassPnp");
|
UNICODE_STRING DefaultPointerDeviceBaseName = RTL_CONSTANT_STRING(L"PointerClass");
|
||||||
|
|
||||||
RtlZeroMemory(Parameters, sizeof(Parameters));
|
RtlZeroMemory(Parameters, sizeof(Parameters));
|
||||||
|
|
||||||
|
@ -216,7 +212,7 @@ CreatePointerClassDeviceObject(
|
||||||
DeviceIdW = &DeviceNameU.Buffer[PrefixLength / sizeof(WCHAR)];
|
DeviceIdW = &DeviceNameU.Buffer[PrefixLength / sizeof(WCHAR)];
|
||||||
while (DeviceId < 9999)
|
while (DeviceId < 9999)
|
||||||
{
|
{
|
||||||
DeviceNameU.Length = PrefixLength + swprintf(DeviceIdW, L"%ld", DeviceId) * sizeof(WCHAR);
|
DeviceNameU.Length = PrefixLength + swprintf(DeviceIdW, L"%lu", DeviceId) * sizeof(WCHAR);
|
||||||
Status = IoCreateDevice(
|
Status = IoCreateDevice(
|
||||||
DriverObject,
|
DriverObject,
|
||||||
sizeof(MOUCLASS_DEVICE_EXTENSION),
|
sizeof(MOUCLASS_DEVICE_EXTENSION),
|
||||||
|
@ -251,7 +247,6 @@ cleanup:
|
||||||
DeviceExtension->InputCount = 0;
|
DeviceExtension->InputCount = 0;
|
||||||
DeviceExtension->PortData = ExAllocatePool(NonPagedPool, DeviceExtension->DriverExtension->MouseDataQueueSize * sizeof(MOUSE_INPUT_DATA));
|
DeviceExtension->PortData = ExAllocatePool(NonPagedPool, DeviceExtension->DriverExtension->MouseDataQueueSize * sizeof(MOUSE_INPUT_DATA));
|
||||||
Fdo->Flags |= DO_POWER_PAGABLE;
|
Fdo->Flags |= DO_POWER_PAGABLE;
|
||||||
Fdo->Flags |= DO_BUFFERED_IO;
|
|
||||||
Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||||
|
|
||||||
/* FIXME: create registry entry in HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP */
|
/* FIXME: create registry entry in HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP */
|
||||||
|
@ -290,8 +285,9 @@ MouclassCallback(
|
||||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
/* A read request is waiting for input, so go straight to it */
|
/* A read request is waiting for input, so go straight to it */
|
||||||
RtlMoveMemory(
|
/* FIXME: use SEH */
|
||||||
Irp->AssociatedIrp.SystemBuffer,
|
RtlCopyMemory(
|
||||||
|
Irp->MdlAddress ? MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority) : Irp->UserBuffer,
|
||||||
MouseDataStart,
|
MouseDataStart,
|
||||||
sizeof(MOUSE_INPUT_DATA));
|
sizeof(MOUSE_INPUT_DATA));
|
||||||
|
|
||||||
|
@ -475,8 +471,9 @@ MouclassStartIo(
|
||||||
|
|
||||||
KeAcquireSpinLock(&DeviceExtension->SpinLock, &oldIrql);
|
KeAcquireSpinLock(&DeviceExtension->SpinLock, &oldIrql);
|
||||||
|
|
||||||
RtlMoveMemory(
|
/* FIXME: use SEH */
|
||||||
Irp->AssociatedIrp.SystemBuffer,
|
RtlCopyMemory(
|
||||||
|
Irp->MdlAddress ? MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority) : Irp->UserBuffer,
|
||||||
DeviceExtension->PortData - DeviceExtension->InputCount,
|
DeviceExtension->PortData - DeviceExtension->InputCount,
|
||||||
sizeof(MOUSE_INPUT_DATA));
|
sizeof(MOUSE_INPUT_DATA));
|
||||||
|
|
||||||
|
@ -508,35 +505,120 @@ MouclassStartIo(
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
SearchForLegacyDrivers(
|
SearchForLegacyDrivers(
|
||||||
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
IN PMOUCLASS_DRIVER_EXTENSION DriverExtension)
|
IN PMOUCLASS_DRIVER_EXTENSION DriverExtension)
|
||||||
{
|
{
|
||||||
PDEVICE_OBJECT PortDeviceObject = NULL;
|
UNICODE_STRING DeviceMapKeyU = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\HARDWARE\\DEVICEMAP");
|
||||||
PFILE_OBJECT FileObject = NULL;
|
UNICODE_STRING PortBaseName = {0, };
|
||||||
UNICODE_STRING PortName = RTL_CONSTANT_STRING(L"\\Device\\PointerClass0");
|
PKEY_VALUE_BASIC_INFORMATION KeyValueInformation = NULL;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
HANDLE hDeviceMapKey = (HANDLE)-1;
|
||||||
|
HANDLE hPortKey = (HANDLE)-1;
|
||||||
|
ULONG Index = 0;
|
||||||
|
ULONG Size, ResultLength;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
/* FIXME: search for more than once legacy driver */
|
/* Create port base name, by replacing Class by Port at the end of the class base name */
|
||||||
|
Status = RtlDuplicateUnicodeString(
|
||||||
Status = IoGetDeviceObjectPointer(&PortName, FILE_READ_ATTRIBUTES, &FileObject, &PortDeviceObject);
|
RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
|
||||||
if(Status != STATUS_SUCCESS)
|
&DriverExtension->PointerDeviceBaseName,
|
||||||
{
|
&PortBaseName);
|
||||||
DPRINT("Could not open old device object (Status 0x%08lx)\n", Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DriverExtension->ConnectMultiplePorts)
|
|
||||||
Status = ConnectMousePortDriver(PortDeviceObject, DriverExtension->MainMouclassDeviceObject);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* What to do */
|
|
||||||
KEBUGCHECK(0);
|
|
||||||
}
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("ConnectMousePortDriver() failed with status 0x%08lx\n", Status);
|
DPRINT("RtlDuplicateUnicodeString() failed with status 0x%08lx\n", Status);
|
||||||
return Status;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
return STATUS_SUCCESS;
|
PortBaseName.Length -= (sizeof(L"Class") - sizeof(UNICODE_NULL));
|
||||||
|
RtlAppendUnicodeToString(&PortBaseName, L"Port");
|
||||||
|
|
||||||
|
/* Allocate memory */
|
||||||
|
Size = sizeof(KEY_VALUE_BASIC_INFORMATION) + MAX_PATH;
|
||||||
|
KeyValueInformation = ExAllocatePool(PagedPool, Size);
|
||||||
|
if (!KeyValueInformation)
|
||||||
|
{
|
||||||
|
DPRINT("ExAllocatePool() failed\n");
|
||||||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP */
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes, &DeviceMapKeyU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||||
|
Status = ZwOpenKey(&hDeviceMapKey, 0, &ObjectAttributes);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open sub key */
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes, &PortBaseName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, hDeviceMapKey, NULL);
|
||||||
|
Status = ZwOpenKey(&hPortKey, KEY_QUERY_VALUE, &ObjectAttributes);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
|
||||||
|
DPRINT1("ZwOpenKey() failed with status 0x%08lx\n", Status);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read each value name */
|
||||||
|
while (ZwEnumerateValueKey(hPortKey, Index++, KeyValueBasicInformation, KeyValueInformation, Size, &ResultLength) == STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
UNICODE_STRING PortName;
|
||||||
|
PDEVICE_OBJECT PortDeviceObject = NULL;
|
||||||
|
PFILE_OBJECT FileObject = NULL;
|
||||||
|
|
||||||
|
PortName.Length = PortName.MaximumLength = KeyValueInformation->NameLength;
|
||||||
|
PortName.Buffer = KeyValueInformation->Name;
|
||||||
|
|
||||||
|
/* Open the device object pointer */
|
||||||
|
Status = IoGetDeviceObjectPointer(&PortName, FILE_READ_ATTRIBUTES, &FileObject, &PortDeviceObject);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("IoGetDeviceObjectPointer(%wZ) failed with status 0x%08lx\n", Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Connect the port device object */
|
||||||
|
if (DriverExtension->ConnectMultiplePorts)
|
||||||
|
{
|
||||||
|
Status = ConnectMousePortDriver(PortDeviceObject, DriverExtension->MainMouclassDeviceObject);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* FIXME: Log the error */
|
||||||
|
DPRINT("ConnectMousePortDriver() failed with status 0x%08lx\n", Status);
|
||||||
|
/* FIXME: cleanup */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PDEVICE_OBJECT ClassDO;
|
||||||
|
Status = CreatePointerClassDeviceObject(DriverObject, &ClassDO);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* FIXME: Log the error */
|
||||||
|
DPRINT("CreatePointerClassDeviceObject() failed with status 0x%08lx\n", Status);
|
||||||
|
/* FIXME: cleanup */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Status = ConnectMousePortDriver(PortDeviceObject, ClassDO);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* FIXME: Log the error */
|
||||||
|
DPRINT("ConnectMousePortDriver() failed with status 0x%08lx\n", Status);
|
||||||
|
/* FIXME: cleanup */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Status == STATUS_NO_MORE_ENTRIES)
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (KeyValueInformation != NULL)
|
||||||
|
ExFreePool(KeyValueInformation);
|
||||||
|
if (hDeviceMapKey != (HANDLE)-1)
|
||||||
|
ZwClose(hDeviceMapKey);
|
||||||
|
if (hPortKey != (HANDLE)-1)
|
||||||
|
ZwClose(hPortKey);
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -593,7 +675,7 @@ DriverEntry(
|
||||||
DriverObject->MajorFunction[IRP_MJ_READ] = MouclassRead;
|
DriverObject->MajorFunction[IRP_MJ_READ] = MouclassRead;
|
||||||
DriverObject->DriverStartIo = MouclassStartIo;
|
DriverObject->DriverStartIo = MouclassStartIo;
|
||||||
|
|
||||||
SearchForLegacyDrivers(DriverExtension);
|
Status = SearchForLegacyDrivers(DriverObject, DriverExtension);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include <ntddk.h>
|
#include <ntifs.h>
|
||||||
#include <kbdmou.h>
|
#include <kbdmou.h>
|
||||||
#include <ntddmou.h>
|
#include <ntddmou.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
|
@ -64,16 +64,70 @@ CreateRootHubPdo(
|
||||||
*pPdo = Pdo;
|
*pPdo = Pdo;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
|
static NTSTATUS
|
||||||
|
AddRegistryEntry(
|
||||||
|
IN PCWSTR PortTypeName,
|
||||||
|
IN PUNICODE_STRING DeviceName,
|
||||||
|
IN PCWSTR RegistryPath)
|
||||||
|
{
|
||||||
|
UNICODE_STRING PathU = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\HARDWARE\\DEVICEMAP");
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
HANDLE hDeviceMapKey = (HANDLE)-1;
|
||||||
|
HANDLE hPortKey = (HANDLE)-1;
|
||||||
|
UNICODE_STRING PortTypeNameU;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes, &PathU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||||
|
Status = ZwOpenKey(&hDeviceMapKey, 0, &ObjectAttributes);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&PortTypeNameU, PortTypeName);
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes, &PortTypeNameU, OBJ_KERNEL_HANDLE, hDeviceMapKey, NULL);
|
||||||
|
Status = ZwCreateKey(&hPortKey, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = ZwSetValueKey(hPortKey, DeviceName, 0, REG_SZ, (PVOID)RegistryPath, wcslen(RegistryPath) * sizeof(WCHAR) + sizeof(UNICODE_NULL));
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (hDeviceMapKey != (HANDLE)-1)
|
||||||
|
ZwClose(hDeviceMapKey);
|
||||||
|
if (hPortKey != (HANDLE)-1)
|
||||||
|
ZwClose(hPortKey);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
AddDevice_Keyboard(
|
AddDevice_Keyboard(
|
||||||
IN PDRIVER_OBJECT DriverObject,
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
IN PDEVICE_OBJECT Pdo)
|
IN PDEVICE_OBJECT Pdo)
|
||||||
{
|
{
|
||||||
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardClass0");
|
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardPortUSB");
|
||||||
PDEVICE_OBJECT Fdo;
|
PDEVICE_OBJECT Fdo;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
Status = AddRegistryEntry(L"KeyboardPort", &DeviceName, L"REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\usbport");
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("USBMP: AddRegistryEntry() for usb keyboard driver failed with status 0x%08lx\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
Status = IoCreateDevice(DriverObject,
|
Status = IoCreateDevice(DriverObject,
|
||||||
8, // debug
|
8, // debug
|
||||||
&DeviceName,
|
&DeviceName,
|
||||||
|
@ -99,10 +153,17 @@ AddDevice_Mouse(
|
||||||
IN PDRIVER_OBJECT DriverObject,
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
IN PDEVICE_OBJECT Pdo)
|
IN PDEVICE_OBJECT Pdo)
|
||||||
{
|
{
|
||||||
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\PointerClass0");
|
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\PointerPortUSB");
|
||||||
PDEVICE_OBJECT Fdo;
|
PDEVICE_OBJECT Fdo;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
Status = AddRegistryEntry(L"PointerPort", &DeviceName, L"REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\usbport");
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("USBMP: AddRegistryEntry() for usb mouse driver failed with status 0x%08lx\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
Status = IoCreateDevice(DriverObject,
|
Status = IoCreateDevice(DriverObject,
|
||||||
8, // debug
|
8, // debug
|
||||||
&DeviceName,
|
&DeviceName,
|
||||||
|
@ -122,7 +183,6 @@ AddDevice_Mouse(
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
AddDevice(
|
AddDevice(
|
||||||
|
@ -230,12 +290,10 @@ AddDevice(
|
||||||
|
|
||||||
Status = IoCreateSymbolicLink(&LinkDeviceName, &DeviceName);
|
Status = IoCreateSymbolicLink(&LinkDeviceName, &DeviceName);
|
||||||
|
|
||||||
/*
|
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
Status = AddDevice_Keyboard(DriverObject, pdo);
|
Status = AddDevice_Keyboard(DriverObject, pdo);
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
Status = AddDevice_Mouse(DriverObject, pdo);
|
Status = AddDevice_Mouse(DriverObject, pdo);
|
||||||
*/
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,6 +17,7 @@ ClassGUID={00000000-0000-0000-0000-000000000000}
|
||||||
cdrom.inf
|
cdrom.inf
|
||||||
display.inf
|
display.inf
|
||||||
hdc.inf
|
hdc.inf
|
||||||
|
keyboard.inf
|
||||||
machine.inf
|
machine.inf
|
||||||
mouse.inf
|
mouse.inf
|
||||||
NET_NIC.inf
|
NET_NIC.inf
|
||||||
|
|
|
@ -151,7 +151,7 @@ ProcessMouseInputData(PMOUSE_INPUT_DATA Data, ULONG InputCount)
|
||||||
VOID STDCALL
|
VOID STDCALL
|
||||||
MouseThreadMain(PVOID StartContext)
|
MouseThreadMain(PVOID StartContext)
|
||||||
{
|
{
|
||||||
UNICODE_STRING MouseDeviceName = RTL_CONSTANT_STRING(L"\\Device\\PointerClassPnp0");
|
UNICODE_STRING MouseDeviceName = RTL_CONSTANT_STRING(L"\\Device\\PointerClass0");
|
||||||
OBJECT_ATTRIBUTES MouseObjectAttributes;
|
OBJECT_ATTRIBUTES MouseObjectAttributes;
|
||||||
IO_STATUS_BLOCK Iosb;
|
IO_STATUS_BLOCK Iosb;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
@ -404,7 +404,7 @@ co_IntKeyboardSendAltKeyMsg()
|
||||||
STATIC VOID STDCALL
|
STATIC VOID STDCALL
|
||||||
KeyboardThreadMain(PVOID StartContext)
|
KeyboardThreadMain(PVOID StartContext)
|
||||||
{
|
{
|
||||||
UNICODE_STRING KeyboardDeviceName = RTL_CONSTANT_STRING(L"\\??\\Keyboard");
|
UNICODE_STRING KeyboardDeviceName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardClass0");
|
||||||
OBJECT_ATTRIBUTES KeyboardObjectAttributes;
|
OBJECT_ATTRIBUTES KeyboardObjectAttributes;
|
||||||
IO_STATUS_BLOCK Iosb;
|
IO_STATUS_BLOCK Iosb;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue