From 2c5b094ca5cae279876e649b208dabbb41538316 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Fri, 24 Feb 2006 13:38:14 +0000 Subject: [PATCH] Send IOCTL_* to the port device objects. Keyboard LEDs should now work Simplify code in SearchForLegacyDrivers svn path=/trunk/; revision=21188 --- reactos/drivers/input/kbdclass/kbdclass.c | 92 +++++++++++++++-------- reactos/drivers/input/kbdclass/kbdclass.h | 9 +++ reactos/drivers/input/mouclass/mouclass.c | 73 ++++++++++-------- reactos/drivers/input/mouclass/mouclass.h | 10 +++ 4 files changed, 118 insertions(+), 66 deletions(-) diff --git a/reactos/drivers/input/kbdclass/kbdclass.c b/reactos/drivers/input/kbdclass/kbdclass.c index 716c96e8b5e..73082641554 100644 --- a/reactos/drivers/input/kbdclass/kbdclass.c +++ b/reactos/drivers/input/kbdclass/kbdclass.c @@ -96,7 +96,7 @@ ClassDeviceControl( IN PIRP Irp) { PCLASS_DEVICE_EXTENSION DeviceExtension; - NTSTATUS Status; + NTSTATUS Status = Irp->IoStatus.Status; DPRINT("IRP_MJ_DEVICE_CONTROL\n"); @@ -111,15 +111,44 @@ ClassDeviceControl( case IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION: case IOCTL_KEYBOARD_QUERY_INDICATORS: case IOCTL_KEYBOARD_QUERY_TYPEMATIC: + { + /* FIXME: We hope that all devices will return the same result. + * Ask only the first one */ + PLIST_ENTRY Head = &((PCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->ListHead; + if (Head->Flink != Head) + { + /* We have at least one keyboard */ + PPORT_DEVICE_EXTENSION DevExt = CONTAINING_RECORD(Head->Flink, PORT_DEVICE_EXTENSION, ListEntry); + IoGetCurrentIrpStackLocation(Irp)->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(DevExt->DeviceObject, Irp); + } + break; + } 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; + { + /* Send it to all associated Port devices */ + PLIST_ENTRY Head = &((PCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->ListHead; + PLIST_ENTRY Entry = Head->Flink; + Status = STATUS_SUCCESS; + while (Entry != Head) + { + PPORT_DEVICE_EXTENSION DevExt = CONTAINING_RECORD(Entry, PORT_DEVICE_EXTENSION, ListEntry); + NTSTATUS IntermediateStatus; + + IoGetCurrentIrpStackLocation(Irp)->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; + IntermediateStatus = ForwardIrpAndWait(DevExt->DeviceObject, Irp); + if (!NT_SUCCESS(IntermediateStatus)) + Status = IntermediateStatus; + Entry = Entry->Flink; + } break; + } default: DPRINT1("IRP_MJ_DEVICE_CONTROL / unknown I/O control code 0x%lx\n", IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode); - Status = STATUS_NOT_SUPPORTED; + break; } Irp->IoStatus.Status = Status; @@ -141,6 +170,7 @@ IrpStub( /* Forward some IRPs to lower device */ switch (IoGetCurrentIrpStackLocation(Irp)->MajorFunction) { + case IRP_MJ_PNP: case IRP_MJ_INTERNAL_DEVICE_CONTROL: return ForwardIrpAndForget(DeviceObject, Irp); default: @@ -325,7 +355,9 @@ cleanup: RtlZeroMemory(DeviceExtension, sizeof(CLASS_DEVICE_EXTENSION)); DeviceExtension->Common.IsClassDO = TRUE; DeviceExtension->DriverExtension = DriverExtension; - KeInitializeSpinLock(&(DeviceExtension->SpinLock)); + InitializeListHead(&DeviceExtension->ListHead); + KeInitializeSpinLock(&DeviceExtension->ListSpinLock); + KeInitializeSpinLock(&DeviceExtension->SpinLock); DeviceExtension->ReadIsPending = FALSE; DeviceExtension->InputCount = 0; DeviceExtension->PortData = ExAllocatePool(NonPagedPool, DeviceExtension->DriverExtension->DataQueueSize * sizeof(KEYBOARD_INPUT_DATA)); @@ -478,7 +510,20 @@ ConnectPortDriver( IoStatus.Status = Status; if (NT_SUCCESS(IoStatus.Status)) + { ObReferenceObject(PortDO); + ExInterlockedInsertTailList( + &((PCLASS_DEVICE_EXTENSION)ClassDO->DeviceExtension)->ListHead, + &((PPORT_DEVICE_EXTENSION)PortDO->DeviceExtension)->ListEntry, + &((PCLASS_DEVICE_EXTENSION)ClassDO->DeviceExtension)->ListSpinLock); + if (ClassDO->StackSize <= PortDO->StackSize) + { + /* Increase the stack size, in case we have to + * forward some IRPs to the port device object + */ + ClassDO->StackSize = PortDO->StackSize + 1; + } + } return IoStatus.Status; } @@ -520,6 +565,7 @@ ClassAddDevice( DeviceExtension = (PPORT_DEVICE_EXTENSION)Fdo->DeviceExtension; RtlZeroMemory(DeviceExtension, sizeof(CLASS_DEVICE_EXTENSION)); DeviceExtension->Common.IsClassDO = FALSE; + DeviceExtension->DeviceObject = Fdo; DeviceExtension->PnpState = dsStopped; Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice); if (!NT_SUCCESS(Status)) @@ -541,8 +587,8 @@ ClassAddDevice( { DPRINT("ConnectPortDriver() failed with status 0x%08lx\n", Status); IoDetachDevice(DeviceExtension->LowerDevice); - /* FIXME: why can't I cleanup without error? */ - //IoDeleteDevice(Fdo); + ObDereferenceObject(Fdo); + IoDeleteDevice(Fdo); return Status; } Fdo->Flags &= ~DO_DEVICE_INITIALIZING; @@ -698,35 +744,14 @@ SearchForLegacyDrivers( if (!NT_SUCCESS(Status)) { DPRINT("IoGetDeviceObjectPointer(%wZ) failed with status 0x%08lx\n", Status); + continue; } - /* Connect the port device object */ - if (DriverExtension->ConnectMultiplePorts) + Status = ClassAddDevice(DriverObject, PortDeviceObject); + if (!NT_SUCCESS(Status)) { - Status = ConnectPortDriver(PortDeviceObject, DriverExtension->MainClassDeviceObject); - if (!NT_SUCCESS(Status)) - { - /* FIXME: Log the error */ - DPRINT("ConnectPortDriver() failed with status 0x%08lx\n", Status); - } - } - else - { - 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) @@ -806,6 +831,7 @@ DriverEntry( DriverObject->MajorFunction[IRP_MJ_CLEANUP] = ClassCleanup; DriverObject->MajorFunction[IRP_MJ_READ] = ClassRead; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ClassDeviceControl; + DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = ForwardIrpAndForget; DriverObject->DriverStartIo = ClassStartIo; return STATUS_SUCCESS; diff --git a/reactos/drivers/input/kbdclass/kbdclass.h b/reactos/drivers/input/kbdclass/kbdclass.h index 442807699fb..b0fc2107a8b 100644 --- a/reactos/drivers/input/kbdclass/kbdclass.h +++ b/reactos/drivers/input/kbdclass/kbdclass.h @@ -35,6 +35,8 @@ typedef struct _PORT_DEVICE_EXTENSION { COMMON_DEVICE_EXTENSION Common; + LIST_ENTRY ListEntry; + PDEVICE_OBJECT DeviceObject; PORT_DEVICE_STATE PnpState; PDEVICE_OBJECT LowerDevice; UNICODE_STRING InterfaceName; @@ -46,6 +48,8 @@ typedef struct _CLASS_DEVICE_EXTENSION PCLASS_DRIVER_EXTENSION DriverExtension; + LIST_ENTRY ListHead; + KSPIN_LOCK ListSpinLock; KSPIN_LOCK SpinLock; BOOLEAN ReadIsPending; ULONG InputCount; @@ -54,6 +58,11 @@ typedef struct _CLASS_DEVICE_EXTENSION /* misc.c */ +NTSTATUS +ForwardIrpAndWait( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + NTSTATUS NTAPI ForwardIrpAndForget( IN PDEVICE_OBJECT DeviceObject, diff --git a/reactos/drivers/input/mouclass/mouclass.c b/reactos/drivers/input/mouclass/mouclass.c index a50b10304b0..4441468a4f9 100644 --- a/reactos/drivers/input/mouclass/mouclass.c +++ b/reactos/drivers/input/mouclass/mouclass.c @@ -96,7 +96,7 @@ ClassDeviceControl( IN PIRP Irp) { PCLASS_DEVICE_EXTENSION DeviceExtension; - NTSTATUS Status; + NTSTATUS Status = Irp->IoStatus.Status; DPRINT("IRP_MJ_DEVICE_CONTROL\n"); @@ -108,13 +108,24 @@ ClassDeviceControl( switch (IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_MOUSE_QUERY_ATTRIBUTES: - /* FIXME */ - Status = STATUS_NOT_SUPPORTED; + { + /* FIXME: We hope that all devices will return the same result. + * Ask only the first one */ + PLIST_ENTRY Head = &((PCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->ListHead; + if (Head->Flink != Head) + { + /* We have at least one keyboard */ + PPORT_DEVICE_EXTENSION DevExt = CONTAINING_RECORD(Head->Flink, PORT_DEVICE_EXTENSION, ListEntry); + IoGetCurrentIrpStackLocation(Irp)->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(DevExt->DeviceObject, Irp); + } break; + } default: DPRINT1("IRP_MJ_DEVICE_CONTROL / unknown I/O control code 0x%lx\n", IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode); - Status = STATUS_NOT_SUPPORTED; + break; } Irp->IoStatus.Status = Status; @@ -320,7 +331,9 @@ cleanup: RtlZeroMemory(DeviceExtension, sizeof(CLASS_DEVICE_EXTENSION)); DeviceExtension->Common.IsClassDO = TRUE; DeviceExtension->DriverExtension = DriverExtension; - KeInitializeSpinLock(&(DeviceExtension->SpinLock)); + InitializeListHead(&DeviceExtension->ListHead); + KeInitializeSpinLock(&DeviceExtension->ListSpinLock); + KeInitializeSpinLock(&DeviceExtension->SpinLock); DeviceExtension->ReadIsPending = FALSE; DeviceExtension->InputCount = 0; DeviceExtension->PortData = ExAllocatePool(NonPagedPool, DeviceExtension->DriverExtension->DataQueueSize * sizeof(MOUSE_INPUT_DATA)); @@ -469,7 +482,20 @@ ConnectPortDriver( IoStatus.Status = Status; if (NT_SUCCESS(IoStatus.Status)) + { ObReferenceObject(PortDO); + ExInterlockedInsertTailList( + &((PCLASS_DEVICE_EXTENSION)ClassDO->DeviceExtension)->ListHead, + &((PPORT_DEVICE_EXTENSION)PortDO->DeviceExtension)->ListEntry, + &((PCLASS_DEVICE_EXTENSION)ClassDO->DeviceExtension)->ListSpinLock); + if (ClassDO->StackSize <= PortDO->StackSize) + { + /* Increase the stack size, in case we have to + * forward some IRPs to the port device object + */ + ClassDO->StackSize = PortDO->StackSize + 1; + } + } return IoStatus.Status; } @@ -511,6 +537,7 @@ ClassAddDevice( DeviceExtension = (PPORT_DEVICE_EXTENSION)Fdo->DeviceExtension; RtlZeroMemory(DeviceExtension, sizeof(CLASS_DEVICE_EXTENSION)); DeviceExtension->Common.IsClassDO = FALSE; + DeviceExtension->DeviceObject = Fdo; DeviceExtension->PnpState = dsStopped; Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice); if (!NT_SUCCESS(Status)) @@ -532,8 +559,8 @@ ClassAddDevice( { DPRINT("ConnectPortDriver() failed with status 0x%08lx\n", Status); IoDetachDevice(DeviceExtension->LowerDevice); - /* FIXME: why can't I cleanup without error? */ - //IoDeleteDevice(Fdo); + ObDereferenceObject(Fdo); + IoDeleteDevice(Fdo); return Status; } Fdo->Flags &= ~DO_DEVICE_INITIALIZING; @@ -689,35 +716,14 @@ SearchForLegacyDrivers( if (!NT_SUCCESS(Status)) { DPRINT("IoGetDeviceObjectPointer(%wZ) failed with status 0x%08lx\n", Status); + continue; } - /* Connect the port device object */ - if (DriverExtension->ConnectMultiplePorts) + Status = ClassAddDevice(DriverObject, PortDeviceObject); + if (!NT_SUCCESS(Status)) { - Status = ConnectPortDriver(PortDeviceObject, DriverExtension->MainClassDeviceObject); - if (!NT_SUCCESS(Status)) - { - /* FIXME: Log the error */ - DPRINT("ConnectPortDriver() failed with status 0x%08lx\n", Status); - } - } - else - { - 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) @@ -797,6 +803,7 @@ DriverEntry( DriverObject->MajorFunction[IRP_MJ_CLEANUP] = ClassCleanup; DriverObject->MajorFunction[IRP_MJ_READ] = ClassRead; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ClassDeviceControl; + DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = ForwardIrpAndForget; DriverObject->DriverStartIo = ClassStartIo; return STATUS_SUCCESS; diff --git a/reactos/drivers/input/mouclass/mouclass.h b/reactos/drivers/input/mouclass/mouclass.h index dd763691049..c9e35eb91ad 100644 --- a/reactos/drivers/input/mouclass/mouclass.h +++ b/reactos/drivers/input/mouclass/mouclass.h @@ -4,6 +4,7 @@ #include #define MAX_PATH 260 + typedef enum { dsStopped, @@ -34,6 +35,8 @@ typedef struct _PORT_DEVICE_EXTENSION { COMMON_DEVICE_EXTENSION Common; + LIST_ENTRY ListEntry; + PDEVICE_OBJECT DeviceObject; PORT_DEVICE_STATE PnpState; PDEVICE_OBJECT LowerDevice; UNICODE_STRING InterfaceName; @@ -45,6 +48,8 @@ typedef struct _CLASS_DEVICE_EXTENSION PCLASS_DRIVER_EXTENSION DriverExtension; + LIST_ENTRY ListHead; + KSPIN_LOCK ListSpinLock; KSPIN_LOCK SpinLock; BOOLEAN ReadIsPending; ULONG InputCount; @@ -53,6 +58,11 @@ typedef struct _CLASS_DEVICE_EXTENSION /* misc.c */ +NTSTATUS +ForwardIrpAndWait( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + NTSTATUS NTAPI ForwardIrpAndForget( IN PDEVICE_OBJECT DeviceObject,