kbdclass and mouclass:
authorHervé Poussineau <hpoussin@reactos.org>
Sun, 16 Apr 2006 07:17:34 +0000 (07:17 +0000)
committerHervé Poussineau <hpoussin@reactos.org>
Sun, 16 Apr 2006 07:17:34 +0000 (07:17 +0000)
- Better synchronization of code between kbdclass and mouclass
- Better cleanup in ClassAddDevice in case of error
- Better support of legacy devices
kbdclass only:
- Send IOCTLs to lower device

svn path=/trunk/; revision=21599

reactos/drivers/input/kbdclass/kbdclass.c
reactos/drivers/input/kbdclass/kbdclass.h
reactos/drivers/input/mouclass/mouclass.c
reactos/drivers/input/mouclass/mouclass.h

index 7086678..3b01962 100644 (file)
@@ -107,7 +107,6 @@ ClassDeviceControl(
 
        switch (IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode)
        {
-#if 0
                case IOCTL_KEYBOARD_QUERY_ATTRIBUTES:
                case IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION:
                case IOCTL_KEYBOARD_QUERY_INDICATORS:
@@ -146,10 +145,10 @@ ClassDeviceControl(
                        }
                        break;
                }
-#endif
                default:
                        DPRINT1("IRP_MJ_DEVICE_CONTROL / unknown I/O control code 0x%lx\n",
                                IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode);
+                       ASSERT(FALSE);
                        break;
        }
 
@@ -536,8 +535,8 @@ ClassAddDevice(
        IN PDEVICE_OBJECT Pdo)
 {
        PCLASS_DRIVER_EXTENSION DriverExtension;
-       PDEVICE_OBJECT Fdo;
-       PPORT_DEVICE_EXTENSION DeviceExtension;
+       PDEVICE_OBJECT Fdo = NULL;
+       PPORT_DEVICE_EXTENSION DeviceExtension = NULL;
        NTSTATUS Status;
 
        DPRINT("ClassAddDevice called. Pdo = 0x%p\n", Pdo);
@@ -561,7 +560,7 @@ ClassAddDevice(
        if (!NT_SUCCESS(Status))
        {
                DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status);
-               return Status;
+               goto cleanup;
        }
 
        DeviceExtension = (PPORT_DEVICE_EXTENSION)Fdo->DeviceExtension;
@@ -573,8 +572,7 @@ ClassAddDevice(
        if (!NT_SUCCESS(Status))
        {
                DPRINT("IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
-               IoDeleteDevice(Fdo);
-               return Status;
+               goto cleanup;
        }
        if (DeviceExtension->LowerDevice->Flags & DO_POWER_PAGABLE)
                Fdo->Flags |= DO_POWER_PAGABLE;
@@ -582,16 +580,25 @@ ClassAddDevice(
                Fdo->Flags |= DO_BUFFERED_IO;
 
        if (DriverExtension->ConnectMultiplePorts)
-               Status = ConnectPortDriver(Fdo, DriverExtension->MainClassDeviceObject);
+               DeviceExtension->ClassDO = DriverExtension->MainClassDeviceObject;
        else
-               Status = ConnectPortDriver(Fdo, Fdo);
+       {
+               /* We need a new class device object for this Fdo */
+               Status = CreateClassDeviceObject(
+                       DriverObject,
+                       &DeviceExtension->ClassDO);
+               if (!NT_SUCCESS(Status))
+               {
+                       DPRINT("CreateClassDeviceObject() failed with status 0x%08lx\n", Status);
+                       goto cleanup;
+               }
+       }
+       Status = ConnectPortDriver(Fdo, DeviceExtension->ClassDO);
        if (!NT_SUCCESS(Status))
        {
                DPRINT("ConnectPortDriver() failed with status 0x%08lx\n", Status);
-               IoDetachDevice(DeviceExtension->LowerDevice);
                ObDereferenceObject(Fdo);
-               IoDeleteDevice(Fdo);
-               return Status;
+               goto cleanup;
        }
        Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
 
@@ -601,13 +608,35 @@ ClassAddDevice(
                &GUID_DEVINTERFACE_KEYBOARD,
                NULL,
                &DeviceExtension->InterfaceName);
-       if (!NT_SUCCESS(Status))
+       if (Status == STATUS_INVALID_PARAMETER_1)
+       {
+               /* The Pdo was a strange one ; maybe it is a legacy device.
+                * Ignore the error. */
+               return STATUS_SUCCESS;
+       }
+       else if (!NT_SUCCESS(Status))
        {
                DPRINT("IoRegisterDeviceInterface() failed with status 0x%08lx\n", Status);
-               return Status;
+               goto cleanup;
        }
 
        return STATUS_SUCCESS;
+
+cleanup:
+       if (DeviceExtension)
+       {
+               if (DeviceExtension->LowerDevice)
+                       IoDetachDevice(DeviceExtension->LowerDevice);
+               if (DriverExtension->ConnectMultiplePorts && DeviceExtension->ClassDO)
+               {
+                       PCLASS_DEVICE_EXTENSION ClassDeviceExtension;
+                       ClassDeviceExtension = (PCLASS_DEVICE_EXTENSION)DeviceExtension->ClassDO->DeviceExtension;
+                       ExFreePool(ClassDeviceExtension->PortData);
+               }
+       }
+       if (Fdo)
+               IoDeleteDevice(Fdo);
+       return Status;
 }
 
 static VOID NTAPI
@@ -748,34 +777,13 @@ SearchForLegacyDrivers(
                        DPRINT("IoGetDeviceObjectPointer(%wZ) failed with status 0x%08lx\n", Status);
                        continue;
                }
+               DPRINT("Legacy driver found: %wZ\n", &PortDeviceObject->DriverObject->DriverName);
 
-               /* Connect the port device object */
-               if (DriverExtension->ConnectMultiplePorts)
-               {
-                       Status = ConnectPortDriver(PortDeviceObject, DriverExtension->MainClassDeviceObject);
-                       if (!NT_SUCCESS(Status))
-                       {
-                               /* FIXME: Log the error */
-                               DPRINT("ConnectPortDriver() failed with status 0x%08lx\n", Status);
-                       }
-               }
-               else
+               Status = ClassAddDevice(DriverObject, PortDeviceObject);
+               if (!NT_SUCCESS(Status))
                {
-                       PDEVICE_OBJECT ClassDO;
-                       Status = CreateClassDeviceObject(DriverObject, &ClassDO);
-                       if (!NT_SUCCESS(Status))
-                       {
-                               /* FIXME: Log the error */
-                               DPRINT("CreatePointerClassDeviceObject() failed with status 0x%08lx\n", Status);
-                               continue;
-                       }
-                       Status = ConnectPortDriver(PortDeviceObject, ClassDO);
-                       if (!NT_SUCCESS(Status))
-                       {
-                               /* FIXME: Log the error */
-                               DPRINT("ConnectPortDriver() failed with status 0x%08lx\n", Status);
-                               IoDeleteDevice(ClassDO);
-                       }
+                       /* FIXME: Log the error */
+                       DPRINT("ClassAddDevice() failed with status 0x%08lx\n", Status);
                }
        }
        if (Status == STATUS_NO_MORE_ENTRIES)
index b0fc210..f6af437 100644 (file)
@@ -39,6 +39,7 @@ typedef struct _PORT_DEVICE_EXTENSION
        PDEVICE_OBJECT DeviceObject;
        PORT_DEVICE_STATE PnpState;
        PDEVICE_OBJECT LowerDevice;
+       PDEVICE_OBJECT ClassDO;
        UNICODE_STRING InterfaceName;
 } PORT_DEVICE_EXTENSION, *PPORT_DEVICE_EXTENSION;
 
index 4441468..e7981a8 100644 (file)
@@ -125,6 +125,7 @@ ClassDeviceControl(
                default:
                        DPRINT1("IRP_MJ_DEVICE_CONTROL / unknown I/O control code 0x%lx\n",
                                IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode);
+                       ASSERT(FALSE);
                        break;
        }
 
@@ -506,8 +507,8 @@ ClassAddDevice(
        IN PDEVICE_OBJECT Pdo)
 {
        PCLASS_DRIVER_EXTENSION DriverExtension;
-       PDEVICE_OBJECT Fdo;
-       PPORT_DEVICE_EXTENSION DeviceExtension;
+       PDEVICE_OBJECT Fdo = NULL;
+       PPORT_DEVICE_EXTENSION DeviceExtension = NULL;
        NTSTATUS Status;
 
        DPRINT("ClassAddDevice called. Pdo = 0x%p\n", Pdo);
@@ -531,7 +532,7 @@ ClassAddDevice(
        if (!NT_SUCCESS(Status))
        {
                DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status);
-               return Status;
+               goto cleanup;
        }
 
        DeviceExtension = (PPORT_DEVICE_EXTENSION)Fdo->DeviceExtension;
@@ -543,8 +544,7 @@ ClassAddDevice(
        if (!NT_SUCCESS(Status))
        {
                DPRINT("IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
-               IoDeleteDevice(Fdo);
-               return Status;
+               goto cleanup;
        }
        if (DeviceExtension->LowerDevice->Flags & DO_POWER_PAGABLE)
                Fdo->Flags |= DO_POWER_PAGABLE;
@@ -552,16 +552,25 @@ ClassAddDevice(
                Fdo->Flags |= DO_BUFFERED_IO;
 
        if (DriverExtension->ConnectMultiplePorts)
-               Status = ConnectPortDriver(Fdo, DriverExtension->MainClassDeviceObject);
+               DeviceExtension->ClassDO = DriverExtension->MainClassDeviceObject;
        else
-               Status = ConnectPortDriver(Fdo, Fdo);
+       {
+               /* We need a new class device object for this Fdo */
+               Status = CreateClassDeviceObject(
+                       DriverObject,
+                       &DeviceExtension->ClassDO);
+               if (!NT_SUCCESS(Status))
+               {
+                       DPRINT("CreateClassDeviceObject() failed with status 0x%08lx\n", Status);
+                       goto cleanup;
+               }
+       }
+       Status = ConnectPortDriver(Fdo, DeviceExtension->ClassDO);
        if (!NT_SUCCESS(Status))
        {
                DPRINT("ConnectPortDriver() failed with status 0x%08lx\n", Status);
-               IoDetachDevice(DeviceExtension->LowerDevice);
                ObDereferenceObject(Fdo);
-               IoDeleteDevice(Fdo);
-               return Status;
+               goto cleanup;
        }
        Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
 
@@ -571,13 +580,35 @@ ClassAddDevice(
                &GUID_DEVINTERFACE_MOUSE,
                NULL,
                &DeviceExtension->InterfaceName);
-       if (!NT_SUCCESS(Status))
+       if (Status == STATUS_INVALID_PARAMETER_1)
+       {
+               /* The Pdo was a strange one ; maybe it is a legacy device.
+                * Ignore the error. */
+               return STATUS_SUCCESS;
+       }
+       else if (!NT_SUCCESS(Status))
        {
                DPRINT("IoRegisterDeviceInterface() failed with status 0x%08lx\n", Status);
-               return Status;
+               goto cleanup;
        }
 
        return STATUS_SUCCESS;
+
+cleanup:
+       if (DeviceExtension)
+       {
+               if (DeviceExtension->LowerDevice)
+                       IoDetachDevice(DeviceExtension->LowerDevice);
+               if (DriverExtension->ConnectMultiplePorts && DeviceExtension->ClassDO)
+               {
+                       PCLASS_DEVICE_EXTENSION ClassDeviceExtension;
+                       ClassDeviceExtension = (PCLASS_DEVICE_EXTENSION)DeviceExtension->ClassDO->DeviceExtension;
+                       ExFreePool(ClassDeviceExtension->PortData);
+               }
+       }
+       if (Fdo)
+               IoDeleteDevice(Fdo);
+       return Status;
 }
 
 static VOID NTAPI
@@ -718,6 +749,7 @@ SearchForLegacyDrivers(
                        DPRINT("IoGetDeviceObjectPointer(%wZ) failed with status 0x%08lx\n", Status);
                        continue;
                }
+               DPRINT("Legacy driver found: %wZ\n", &PortDeviceObject->DriverObject->DriverName);
 
                Status = ClassAddDevice(DriverObject, PortDeviceObject);
                if (!NT_SUCCESS(Status))
index c9e35eb..897c3f5 100644 (file)
@@ -39,6 +39,7 @@ typedef struct _PORT_DEVICE_EXTENSION
        PDEVICE_OBJECT DeviceObject;
        PORT_DEVICE_STATE PnpState;
        PDEVICE_OBJECT LowerDevice;
+       PDEVICE_OBJECT ClassDO;
        UNICODE_STRING InterfaceName;
 } PORT_DEVICE_EXTENSION, *PPORT_DEVICE_EXTENSION;