Big move of driver input stack to a Plug-and-Play model:
authorHervé Poussineau <hpoussin@reactos.org>
Mon, 31 Oct 2005 16:46:46 +0000 (16:46 +0000)
committerHervé Poussineau <hpoussin@reactos.org>
Mon, 31 Oct 2005 16:46:46 +0000 (16:46 +0000)
- 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

reactos/bootdata/hivesys.inf
reactos/drivers/input/i8042prt/i8042prt.c
reactos/drivers/input/kbdclass/kbdclass.c
reactos/drivers/input/kbdclass/kbdclass.h
reactos/drivers/input/kbdclass/kbdclass.xml
reactos/drivers/input/kbdclass/misc.c [new file with mode: 0644]
reactos/drivers/input/mouclass/mouclass.c
reactos/drivers/input/mouclass/mouclass.h
reactos/drivers/usb/miniport/common/main.c
reactos/media/inf/syssetup.inf
reactos/subsys/win32k/ntuser/input.c

index a32b115..ca38bf9 100644 (file)
@@ -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\Parameters","ConnectMultiplePorts",0x00010001,0x00000000
 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"
 
 ; Mailslot filesystem driver
index 208916d..0a62770 100644 (file)
@@ -417,6 +417,7 @@ VOID STDCALL I8042SendHookWorkItem(PDEVICE_OBJECT DeviceObject,
                goto hookworkitemdone;
        }
 
+#if 0
        Status = IoCallDriver(
                        WorkItemData->Target,
                        NewIrp);
@@ -427,6 +428,7 @@ VOID STDCALL I8042SendHookWorkItem(PDEVICE_OBJECT DeviceObject,
                                      KernelMode,
                                      FALSE,
                                      NULL);
+#endif
 
        if (IsKbd) {
                /* Call the hooked initialization if it exists */
@@ -633,11 +635,58 @@ static NTSTATUS STDCALL I8042Initialize(PDEVICE_EXTENSION DevExt)
        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,
                                        PDEVICE_OBJECT Pdo)
 {
-       UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardClass0");
-       UNICODE_STRING MouseName = RTL_CONSTANT_STRING(L"\\Device\\PointerClass0");
+       UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardPort8042");
+       UNICODE_STRING MouseName = RTL_CONSTANT_STRING(L"\\Device\\PointerPort8042");
        ULONG MappedIrqKeyboard = 0, MappedIrqMouse = 0;
        KIRQL DirqlKeyboard = 0;
        KIRQL DirqlMouse = 0;
@@ -716,6 +765,7 @@ static NTSTATUS STDCALL I8042AddDevice(PDRIVER_OBJECT DriverObject,
 
                if (NT_SUCCESS(Status))
                {
+                       AddRegistryEntry(L"KeyboardPort", &DeviceName, L"REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\i8042prt");
                        FdoDevExt = Fdo->DeviceExtension;
 
                        RtlZeroMemory(FdoDevExt, sizeof(FDO_DEVICE_EXTENSION));
@@ -764,6 +814,7 @@ static NTSTATUS STDCALL I8042AddDevice(PDRIVER_OBJECT DriverObject,
 
                if (NT_SUCCESS(Status))
                {
+                       AddRegistryEntry(L"PointerPort", &MouseName, L"REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\i8042prt");
                        FdoDevExt = Fdo->DeviceExtension;
 
                        RtlZeroMemory(FdoDevExt, sizeof(FDO_DEVICE_EXTENSION));
index 9e45254..7fde290 100644 (file)
-/*
- * COPYRIGHT:        See COPYING in the top level directory
- * PROJECT:          ReactOS kernel
- * FILE:             drivers/input/kbdclass/kbdclass.c
- * PURPOSE:          Keyboard class driver
- * PROGRAMMER:       Victor Kirhenshtein (sauros@iname.com)
- *                   Jason Filby (jasonfilby@yahoo.com)
- *                   Tinus_
+/* 
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS Keyboard class driver
+ * FILE:            drivers/kbdclass/kbdclass.c
+ * PURPOSE:         Keyboard class driver
+ * 
+ * PROGRAMMERS:     Hervé Poussineau (hpoussin@reactos.org)
  */
 
-/* INCLUDES ****************************************************************/
-
-#include <ddk/ntddk.h>
-
 #define NDEBUG
 #include <debug.h>
 
+#define INITGUID
 #include "kbdclass.h"
 
-/* GLOBALS *******************************************************************/
+static VOID NTAPI
+DriverUnload(IN PDRIVER_OBJECT DriverObject)
+{
+       // nothing to do here yet
+}
 
-NTSTATUS STDCALL DriverEntry(PDRIVER_OBJECT DriverObject,
-                            PUNICODE_STRING RegistryPath);
+static NTSTATUS NTAPI
+KbdclassCreate(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp)
+{
+       DPRINT("IRP_MJ_CREATE\n");
 
-/*
- * Driver data
- */
+       if (!((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsClassDO)
+               return ForwardIrpAndForget(DeviceObject, Irp);
 
-static BOOLEAN AlreadyOpened = FALSE;
+       /* FIXME: open all associated Port devices */
+       return STATUS_SUCCESS;
+}
 
-static VOID STDCALL KbdCopyKeys(PDEVICE_OBJECT DeviceObject,
-                           PIRP Irp)
+static NTSTATUS NTAPI
+KbdclassClose(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp)
 {
-       PDEVICE_EXTENSION DevExt = DeviceObject->DeviceExtension;
-       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 &&
-              NrRead < NrToRead) {
-               memcpy(&Rec[NrRead],
-                      &DevExt->KbdBuffer[DevExt->BufHead],
-                      sizeof(KEYBOARD_INPUT_DATA));
-
-               if (++DevExt->BufHead >= KBD_BUFFER_SIZE)
-                       DevExt->BufHead = 0;
-
-               DevExt->KeysInBuffer--;
-               NrRead++;
-       }
-       Irp->IoStatus.Information = NrRead * sizeof(KEYBOARD_INPUT_DATA);
+       DPRINT("IRP_MJ_CLOSE\n");
 
-       if (NrRead < NrToRead) {
-               Irp->IoStatus.Status = STATUS_PENDING;
-               DPRINT("Pending... (NrRead %d, NrToRead %d\n", NrRead, NrToRead);
-       } else {
-               DPRINT("Send scancode: %x\n", ((KEYBOARD_INPUT_DATA*)Irp->AssociatedIrp.SystemBuffer)->MakeCode);
-               Irp->IoStatus.Status = STATUS_SUCCESS;
-               IoCompleteRequest(Irp, IO_NO_INCREMENT);
-               IoStartNextPacket (DeviceObject, FALSE);
-               DPRINT("Success!\n");
-       }
+       if (!((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsClassDO)
+               return ForwardIrpAndForget(DeviceObject, Irp);
+
+       /* FIXME: close all associated Port devices */
+       return STATUS_SUCCESS;
 }
 
-static VOID STDCALL KbdClassServiceCallback (
-                                      PDEVICE_OBJECT DeviceObject,
-                                      PKEYBOARD_INPUT_DATA InputDataStart,
-                                      PKEYBOARD_INPUT_DATA InputDataEnd,
-                                      PULONG InputDataConsumed)
+static NTSTATUS NTAPI
+KbdclassRead(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp)
 {
-       PDEVICE_EXTENSION DevExt = DeviceObject->DeviceExtension;
-       PKEYBOARD_INPUT_DATA CurrentInput = InputDataStart;
-
-       DPRINT("ServiceCallback called\n");
+       DPRINT("IRP_MJ_READ\n");
 
-       while (DevExt->KeysInBuffer < KBD_BUFFER_SIZE &&
-              CurrentInput < InputDataEnd) {
-               memcpy(&DevExt->KbdBuffer[DevExt->BufTail],
-                      CurrentInput,
-                      sizeof(KEYBOARD_INPUT_DATA));
+       if (!((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsClassDO)
+               return ForwardIrpAndForget(DeviceObject, Irp);
 
-               if (++DevExt->BufTail >= KBD_BUFFER_SIZE)
-                       DevExt->BufTail = 0;
-               DevExt->KeysInBuffer++;
+       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);
 
-               CurrentInput++;
-               InputDataConsumed[0]++;
+               return STATUS_BUFFER_TOO_SMALL;
        }
 
-       if (CurrentInput < InputDataStart)
-               /* Copy the rest to the beginning, perhaps the keyboard
-                * can buffer it for us */
-               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);
-       }
+       IoMarkIrpPending(Irp);
+       IoStartPacket(DeviceObject, Irp, NULL, NULL);
+       return STATUS_PENDING;
 }
 
-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);
-}
+       NTSTATUS Status;
 
+       DPRINT("IRP_MJ_DEVICE_CONTROL\n");
+       
+       if (!((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsClassDO)
+               return ForwardIrpAndForget(DeviceObject, Irp);
+
+       switch (IoGetCurrentIrpStackLocation(Irp)->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 */
+                       /* FIXME: send it to all associated Port devices */
+                       Status = STATUS_NOT_SUPPORTED;
+                       break;
+               default:
+                       DPRINT1("IRP_MJ_DEVICE_CONTROL / unknown I/O control code 0x%lx\n",
+                               IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode);
+                       Status = STATUS_NOT_SUPPORTED;
+       }
 
-/*
- * 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)
+       Irp->IoStatus.Status = Status;
+       Irp->IoStatus.Information = 0;
+       IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+       return Status;
+}
+
+static NTSTATUS NTAPI
+IrpStub(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN 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;
+       NTSTATUS Status = STATUS_NOT_SUPPORTED;
+
+       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 STDCALL KbdInternalDeviceControl(PDEVICE_OBJECT DeviceObject,
-                                                 PIRP Irp)
+static NTSTATUS
+ReadRegistryEntries(
+       IN PUNICODE_STRING RegistryPath,
+       IN PKBDCLASS_DRIVER_EXTENSION DriverExtension)
 {
-       PDEVICE_EXTENSION DevExt = DeviceObject->DeviceExtension;
+       RTL_QUERY_REGISTRY_TABLE Parameters[4];
+       NTSTATUS Status;
 
-       DPRINT ("KbdInternalDeviceControl\n");
+       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;
+               }
+       }
 
-       IoSkipCurrentIrpStackLocation(Irp);
-       return IoCallDriver(DevExt->I8042Device, Irp);
+       return Status;
 }
 
-static NTSTATUS STDCALL KbdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+static NTSTATUS
+CreateKeyboardClassDeviceObject(
+       IN PDRIVER_OBJECT DriverObject,
+       OUT PDEVICE_OBJECT *ClassDO OPTIONAL)
 {
-       PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
+       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("DeviceObject %x\n",DeviceObject);
-       DPRINT("Irp %x\n",Irp);
-
-       DPRINT("Dispatch: stk->MajorFunction %d\n", stk->MajorFunction);
-       DPRINT("AlreadyOpened %d\n",AlreadyOpened);
-
-       switch (stk->MajorFunction) {
-       case IRP_MJ_CREATE:
-               if (AlreadyOpened == TRUE) {
-                       CHECKPOINT;
-                       Status = STATUS_UNSUCCESSFUL;
-                       DPRINT1("Keyboard is already open\n");
-               } else {
-                       CHECKPOINT;
-                       Status = STATUS_SUCCESS;
-                       AlreadyOpened = TRUE;
+       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;
                }
-               break;
+               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;
 
-       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;
+       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--;
        }
 
-       Irp->IoStatus.Status = Status;
-       Irp->IoStatus.Information = 0;
-       IoCompleteRequest(Irp,IO_NO_INCREMENT);
-       DPRINT("Status %d\n",Status);
-       return(Status);
+       /* 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;
 }
 
-static VOID STDCALL KbdClassSendConnect(PDEVICE_EXTENSION DevExt)
+/* Send IOCTL_INTERNAL_KEYBOARD_CONNECT to keyboard port */
+static NTSTATUS
+ConnectKeyboardPortDriver(
+       IN PDEVICE_OBJECT KeyboardPortDO,
+       IN PDEVICE_OBJECT KeyboardClassDO)
 {
-       CONNECT_DATA ConnectData;
        KEVENT Event;
+       PIRP Irp;
        IO_STATUS_BLOCK IoStatus;
+       CONNECT_DATA ConnectData;
        NTSTATUS Status;
-       PIRP Irp;
 
        KeInitializeEvent(&Event, NotificationEvent, FALSE);
 
-       ConnectData.ClassDeviceObject = DevExt->DeviceObject;
-       ConnectData.ClassService = KbdClassServiceCallback;
-
-       Irp = IoBuildDeviceIoControlRequest(
-                       IOCTL_INTERNAL_KEYBOARD_CONNECT,
-                       DevExt->I8042Device,
-                       &ConnectData,
-                       sizeof(CONNECT_DATA),
-                       NULL,
-                       0,
-                       TRUE,
-                       &Event,
-                       &IoStatus);
-
-       if (!Irp)
-               return;
-
-       Status = IoCallDriver(
-                       DevExt->I8042Device,
-                       Irp);
-       DPRINT("SendConnect status: %x\n", Status);
-
-       if (STATUS_PENDING ==Status)
-               KeWaitForSingleObject(&Event,
-                                     Executive,
-                                     KernelMode,
-                                     FALSE,
-                                     NULL);
-       DPRINT("SendConnect done\n");
+       ConnectData.ClassDeviceObject = KeyboardClassDO;
+       ConnectData.ClassService      = KbdclassCallback;
+
+       Irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_KEYBOARD_CONNECT,
+               KeyboardPortDO,
+               &ConnectData, sizeof(CONNECT_DATA),
+               NULL, 0,
+               TRUE, &Event, &IoStatus);
+
+       Status = IoCallDriver(KeyboardPortDO, Irp);
+
+       if (Status == STATUS_PENDING)
+               KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
+       else
+               IoStatus.Status = Status;
+
+       return IoStatus.Status;
+}
+
+static NTSTATUS NTAPI
+KbdclassAddDevice(
+       IN PDRIVER_OBJECT DriverObject,
+       IN PDEVICE_OBJECT Pdo)
+{
+       PKBDCLASS_DRIVER_EXTENSION DriverExtension;
+       PDEVICE_OBJECT Fdo;
+       PKBDCLASS_DEVICE_EXTENSION DeviceExtension;
+       NTSTATUS Status;
+
+       DPRINT("KbdclassAddDevice called. Pdo = 0x%p\n", Pdo);
+
+       DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
+
+       /* Create new device object */
+       Status = IoCreateDevice(
+               DriverObject,
+               sizeof(KBDCLASS_DEVICE_EXTENSION),
+               NULL,
+               Pdo->DeviceType,
+               FILE_DEVICE_SECURE_OPEN,
+               FALSE,
+               &Fdo);
+       if (!NT_SUCCESS(Status))
+       {
+               DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status);
+               return Status;
+       }
+
+       DeviceExtension = (PKBDCLASS_DEVICE_EXTENSION)Fdo->DeviceExtension;
+       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;
+
+       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;
+       }
+
+       /* 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;
+       }
+
+       return STATUS_SUCCESS;
+}
+
+static VOID NTAPI
+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;
 }
 
-NTSTATUS STDCALL DriverEntry(PDRIVER_OBJECT DriverObject,
-                            PUNICODE_STRING RegistryPath)
 /*
- * FUNCTION: Module entry point
+ * Standard DriverEntry method.
  */
+NTSTATUS NTAPI
+DriverEntry(
+       IN PDRIVER_OBJECT DriverObject,
+       IN PUNICODE_STRING RegistryPath)
 {
-       PDEVICE_OBJECT DeviceObject;
-       PDEVICE_EXTENSION DevExt;
-       PFILE_OBJECT I8042File;
+       PKBDCLASS_DRIVER_EXTENSION DriverExtension;
+       ULONG i;
        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");
-
-       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->MajorFunction[IRP_MJ_DEVICE_CONTROL] = KbdDeviceControl;
-
-       DriverObject->DriverStartIo = KbdStartIo;
-
-       IoCreateDevice(DriverObject,
-                      sizeof(DEVICE_EXTENSION),
-                      &DeviceName,
-                      FILE_DEVICE_KEYBOARD,
-                      0,
-                      TRUE,
-                      &DeviceObject);
-
-       RtlZeroMemory(DeviceObject->DeviceExtension, sizeof(DEVICE_EXTENSION));
-       DevExt = DeviceObject->DeviceExtension;
-       DevExt->DeviceObject = DeviceObject;
-
-       Status = IoGetDeviceObjectPointer(&I8042Name,
-                                         FILE_READ_DATA,
-                                         &I8042File,
-                                         &DevExt->I8042Device);
-
-       if (STATUS_SUCCESS != Status) {
-               DPRINT("Failed to open device: %x\n", 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));
 
-       ObReferenceObject(DevExt->I8042Device);
-       ObDereferenceObject(I8042File);
+       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;
+               }
+       }
 
-       DeviceObject->Flags = DeviceObject->Flags | DO_BUFFERED_IO;
+       DriverObject->DriverExtension->AddDevice = KbdclassAddDevice;
+       DriverObject->DriverUnload = DriverUnload;
 
-       DeviceObject->StackSize = 1 + DevExt->I8042Device->StackSize;
+       for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
+               DriverObject->MajorFunction[i] = IrpStub;
 
-       IoCreateSymbolicLink(&SymlinkName, &DeviceName);
+       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;
 
-       KbdClassSendConnect(DevExt);
+       Status = SearchForLegacyDrivers(DriverObject, DriverExtension);
 
-       return(STATUS_SUCCESS);
+       return Status;
 }
index a96273d..d79edda 100644 (file)
@@ -1,98 +1,65 @@
-#ifndef _KEYBOARD_H_
-#define _KEYBOARD_H_
-#include <ddk/ntddkbd.h>
-#include <ddk/ntdd8042.h>
-
-#define KBD_BUFFER_SIZE    32
-#define KBD_WRAP_MASK      0x1F
-
-/*-----------------------------------------------------
- *  DeviceExtension
- * --------------------------------------------------*/
-typedef struct _DEVICE_EXTENSION
+#include <ntifs.h>
+#include <kbdmou.h>
+#include <ntddkbd.h>
+#include <stdio.h>
+
+#if defined(__GNUC__)
+  NTSTATUS NTAPI
+  IoAttachDeviceToDeviceStackSafe(
+    IN PDEVICE_OBJECT SourceDevice,
+    IN PDEVICE_OBJECT TargetDevice,
+    OUT PDEVICE_OBJECT *AttachedToDeviceObject);
+#else
+  #error Unknown compiler!
+#endif
+
+typedef enum
 {
-       PDEVICE_OBJECT I8042Device;
-       PDEVICE_OBJECT DeviceObject;
-
-       KEYBOARD_INPUT_DATA KbdBuffer[KBD_BUFFER_SIZE];
-       int BufHead,BufTail;
-       int KeysInBuffer;
-
-       BOOLEAN AlreadyOpened;
-} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
-
-typedef struct _CONNECT_DATA {
-       PDEVICE_OBJECT ClassDeviceObject;
-       PVOID ClassService;
-} CONNECT_DATA, *PCONNECT_DATA;
-
-/*
- * Some defines
- */
-
-#define IOCTL_INTERNAL_KEYBOARD_CONNECT \
-   CTL_CODE(FILE_DEVICE_KEYBOARD, 0x0080, METHOD_NEITHER, FILE_ANY_ACCESS)
-
-#define KEYBOARD_IRQ       1
-
-#define disable()          __asm__("cli\n\t")
-#define enable()           __asm__("sti\n\t")
-
-#define ALT_PRESSED                    (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)
-#define CTRL_PRESSED                   (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)
-
-
-/*
- * Keyboard controller ports
- */
-
-#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
- */
+       dsStopped,
+       dsStarted,
+       dsPaused,
+       dsRemoved,
+       dsSurpriseRemoved
+} KBDCLASS_DEVICE_STATE;
+
+typedef struct _KBDCLASS_DRIVER_EXTENSION
+{
+       /* Registry settings */
+       ULONG ConnectMultiplePorts;
+       ULONG KeyboardDataQueueSize;
+       UNICODE_STRING KeyboardDeviceBaseName;
 
-#define KBD_ACK            0xFA
-#define KBD_BATCC          0xAA
+       PDEVICE_OBJECT MainKbdclassDeviceObject;
+} KBDCLASS_DRIVER_EXTENSION, *PKBDCLASS_DRIVER_EXTENSION;
 
+typedef struct _COMMON_DEVICE_EXTENSION
+{
+       BOOLEAN IsClassDO;
+} COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION;
 
-/*
- * Controller status register bits
- */
+typedef struct _KBDPORT_DEVICE_EXTENSION
+{
+       COMMON_DEVICE_EXTENSION Common;
+} KBDPORT_DEVICE_EXTENSION, *PKBDPORT_DEVICE_EXTENSION;
 
-#define KBD_OBF            0x01
-#define KBD_IBF            0x02
-#define KBD_GTO            0x40
-#define KBD_PERR           0x80
+typedef struct _KBDCLASS_DEVICE_EXTENSION
+{
+       COMMON_DEVICE_EXTENSION Common;
 
+       KBDCLASS_DEVICE_STATE PnpState;
+       PKBDCLASS_DRIVER_EXTENSION DriverExtension;
+       PDEVICE_OBJECT LowerDevice;
+       UNICODE_STRING KeyboardInterfaceName;
 
-/*
- * LED bits
- */
+       KSPIN_LOCK SpinLock;
+       BOOLEAN ReadIsPending;
+       ULONG InputCount;
+       PKEYBOARD_INPUT_DATA PortData;
+} KBDCLASS_DEVICE_EXTENSION, *PKBDCLASS_DEVICE_EXTENSION;
 
-#define KBD_LED_SCROLL     0x01
-#define KBD_LED_NUM        0x02
-#define KBD_LED_CAPS       0x04
+/* misc.c */
 
-#endif // _KEYBOARD_H_
+NTSTATUS NTAPI
+ForwardIrpAndForget(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp);
index b0c8348..9c66104 100644 (file)
@@ -1,9 +1,9 @@
 <module name="kbdclass" type="kernelmodedriver" installbase="system32/drivers" installname="kbdclass.sys">
        <bootstrap base="reactos" />
-       <include base="kbdclass">.</include>
        <define name="__USE_W32API" />
        <library>ntoskrnl</library>
        <library>hal</library>
        <file>kbdclass.c</file>
+       <file>misc.c</file>
        <file>kbdclass.rc</file>
 </module>
diff --git a/reactos/drivers/input/kbdclass/misc.c b/reactos/drivers/input/kbdclass/misc.c
new file mode 100644 (file)
index 0000000..e1d46fa
--- /dev/null
@@ -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);
+}
index e1b2bf8..bbeaecd 100644 (file)
@@ -94,10 +94,6 @@ IrpStub(
                        }
                }
        }
-       else if (IoGetCurrentIrpStackLocation(Irp)->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL) /* HACK FOR I8042PRT */
-       {
-               Status = STATUS_SUCCESS;
-       }
        else
        {
                DPRINT1("Class DO stub for major function 0x%lx\n",
@@ -121,7 +117,7 @@ ReadRegistryEntries(
 
        ULONG DefaultConnectMultiplePorts = 1;
        ULONG DefaultMouseDataQueueSize = 0x64;
-       UNICODE_STRING DefaultPointerDeviceBaseName = RTL_CONSTANT_STRING(L"PointerClassPnp");
+       UNICODE_STRING DefaultPointerDeviceBaseName = RTL_CONSTANT_STRING(L"PointerClass");
 
        RtlZeroMemory(Parameters, sizeof(Parameters));
 
@@ -216,7 +212,7 @@ CreatePointerClassDeviceObject(
        DeviceIdW = &DeviceNameU.Buffer[PrefixLength / sizeof(WCHAR)];
        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(
                        DriverObject,
                        sizeof(MOUCLASS_DEVICE_EXTENSION),
@@ -251,7 +247,6 @@ cleanup:
        DeviceExtension->InputCount = 0;
        DeviceExtension->PortData = ExAllocatePool(NonPagedPool, DeviceExtension->DriverExtension->MouseDataQueueSize * sizeof(MOUSE_INPUT_DATA));
        Fdo->Flags |= DO_POWER_PAGABLE;
-       Fdo->Flags |= DO_BUFFERED_IO;
        Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
 
        /* FIXME: create registry entry in HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP */
@@ -290,8 +285,9 @@ MouclassCallback(
                Stack = IoGetCurrentIrpStackLocation(Irp);
 
                /* A read request is waiting for input, so go straight to it */
-               RtlMoveMemory(
-                       Irp->AssociatedIrp.SystemBuffer,
+               /* FIXME: use SEH */
+               RtlCopyMemory(
+                       Irp->MdlAddress ? MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority) : Irp->UserBuffer,
                        MouseDataStart,
                        sizeof(MOUSE_INPUT_DATA));
 
@@ -475,8 +471,9 @@ MouclassStartIo(
 
                KeAcquireSpinLock(&DeviceExtension->SpinLock, &oldIrql);
 
-               RtlMoveMemory(
-                       Irp->AssociatedIrp.SystemBuffer,
+               /* FIXME: use SEH */
+               RtlCopyMemory(
+                       Irp->MdlAddress ? MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority) : Irp->UserBuffer,
                        DeviceExtension->PortData - DeviceExtension->InputCount,
                        sizeof(MOUSE_INPUT_DATA));
 
@@ -508,35 +505,120 @@ MouclassStartIo(
 
 static NTSTATUS
 SearchForLegacyDrivers(
+       IN PDRIVER_OBJECT DriverObject,
        IN PMOUCLASS_DRIVER_EXTENSION DriverExtension)
 {
-       PDEVICE_OBJECT PortDeviceObject = NULL;
-       PFILE_OBJECT FileObject = NULL;
-       UNICODE_STRING PortName = RTL_CONSTANT_STRING(L"\\Device\\PointerClass0");
+       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;
 
-       /* 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(
+               RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
+               &DriverExtension->PointerDeviceBaseName,
+               &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");
 
-       Status = IoGetDeviceObjectPointer(&PortName, FILE_READ_ATTRIBUTES, &FileObject, &PortDeviceObject);
-       if(Status != STATUS_SUCCESS)
+       /* Allocate memory */
+       Size = sizeof(KEY_VALUE_BASIC_INFORMATION) + MAX_PATH;
+       KeyValueInformation = ExAllocatePool(PagedPool, Size);
+       if (!KeyValueInformation)
        {
-               DPRINT("Could not open old device object (Status 0x%08lx)\n", Status);
-               return Status;
+               DPRINT("ExAllocatePool() failed\n");
+               Status = STATUS_INSUFFICIENT_RESOURCES;
+               goto cleanup;
        }
 
-       if (DriverExtension->ConnectMultiplePorts)
-               Status = ConnectMousePortDriver(PortDeviceObject, DriverExtension->MainMouclassDeviceObject);
-       else
+       /* 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))
        {
-               /* What to do */
-               KEBUGCHECK(0);
+               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("ConnectMousePortDriver() failed with status 0x%08lx\n", Status);
-               return Status;
+               DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
+               DPRINT1("ZwOpenKey() failed with status 0x%08lx\n", Status);
+               goto cleanup;
        }
-       return STATUS_SUCCESS;
+
+       /* 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->DriverStartIo                = MouclassStartIo;
 
-       SearchForLegacyDrivers(DriverExtension);
+       Status = SearchForLegacyDrivers(DriverObject, DriverExtension);
 
-       return STATUS_SUCCESS;
+       return Status;
 }
index f073f16..d80f463 100644 (file)
@@ -1,4 +1,4 @@
-#include <ntddk.h>
+#include <ntifs.h>
 #include <kbdmou.h>
 #include <ntddmou.h>
 #include <stdio.h>
index 38b1873..38efc99 100644 (file)
@@ -64,16 +64,70 @@ CreateRootHubPdo(
        *pPdo = Pdo;
        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
 AddDevice_Keyboard(
        IN PDRIVER_OBJECT DriverObject,
        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;
        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,
                8, // debug
                &DeviceName,
@@ -99,10 +153,17 @@ AddDevice_Mouse(
        IN PDRIVER_OBJECT DriverObject,
        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;
        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,
                8, // debug
                &DeviceName,
@@ -122,7 +183,6 @@ AddDevice_Mouse(
 
        return STATUS_SUCCESS;
 }
-#endif
 
 NTSTATUS STDCALL
 AddDevice(
@@ -230,12 +290,10 @@ AddDevice(
 
        Status = IoCreateSymbolicLink(&LinkDeviceName, &DeviceName);
 
-       /*
        if (NT_SUCCESS(Status))
                Status = AddDevice_Keyboard(DriverObject, pdo);
        if (NT_SUCCESS(Status))
                Status = AddDevice_Mouse(DriverObject, pdo);
-       */
 
        if (!NT_SUCCESS(Status))
        {
index 371ca8a..971d0ac 100644 (file)
@@ -17,6 +17,7 @@ ClassGUID={00000000-0000-0000-0000-000000000000}
 cdrom.inf
 display.inf
 hdc.inf
+keyboard.inf
 machine.inf
 mouse.inf
 NET_NIC.inf
index db69e28..5860b49 100644 (file)
@@ -151,7 +151,7 @@ ProcessMouseInputData(PMOUSE_INPUT_DATA Data, ULONG InputCount)
 VOID STDCALL
 MouseThreadMain(PVOID StartContext)
 {
-   UNICODE_STRING MouseDeviceName = RTL_CONSTANT_STRING(L"\\Device\\PointerClassPnp0");
+   UNICODE_STRING MouseDeviceName = RTL_CONSTANT_STRING(L"\\Device\\PointerClass0");
    OBJECT_ATTRIBUTES MouseObjectAttributes;
    IO_STATUS_BLOCK Iosb;
    NTSTATUS Status;
@@ -404,7 +404,7 @@ co_IntKeyboardSendAltKeyMsg()
 STATIC VOID STDCALL
 KeyboardThreadMain(PVOID StartContext)
 {
-   UNICODE_STRING KeyboardDeviceName = RTL_CONSTANT_STRING(L"\\??\\Keyboard");
+   UNICODE_STRING KeyboardDeviceName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardClass0");
    OBJECT_ATTRIBUTES KeyboardObjectAttributes;
    IO_STATUS_BLOCK Iosb;
    NTSTATUS Status;