From 2c59aa933045139f17e0407cd4d824da05d91121 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Mon, 17 Jul 2006 22:13:40 +0000 Subject: [PATCH] - kbdclass/mouclass should be able to return more than one keystroke/mouse move during a IRP_MJ_READ. - Better cleanup in case of error in ClassAddDevice - Registering the interface is optional. Don't fail in case of error. svn path=/trunk/; revision=23129 --- reactos/drivers/input/kbdclass/kbdclass.c | 162 ++++++++++++--------- reactos/drivers/input/kbdclass/kbdclass.h | 3 + reactos/drivers/input/mouclass/mouclass.c | 164 +++++++++++++--------- reactos/drivers/input/mouclass/mouclass.h | 3 + 4 files changed, 205 insertions(+), 127 deletions(-) diff --git a/reactos/drivers/input/kbdclass/kbdclass.c b/reactos/drivers/input/kbdclass/kbdclass.c index 60cc85a32e7..d64a20936f5 100644 --- a/reactos/drivers/input/kbdclass/kbdclass.c +++ b/reactos/drivers/input/kbdclass/kbdclass.c @@ -126,7 +126,7 @@ ClassDeviceControl( PLIST_ENTRY Head = &((PCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->ListHead; if (Head->Flink != Head) { - /* We have at least one keyboard */ + /* We have at least one device */ PPORT_DEVICE_EXTENSION DevExt = CONTAINING_RECORD(Head->Flink, PORT_DEVICE_EXTENSION, ListEntry); IoGetCurrentIrpStackLocation(Irp)->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; IoSkipCurrentIrpStackLocation(Irp); @@ -375,6 +375,7 @@ cleanup: ExFreePool(DeviceNameU.Buffer); return STATUS_INSUFFICIENT_RESOURCES; } + DeviceExtension->DeviceName = DeviceNameU.Buffer; Fdo->Flags |= DO_POWER_PAGABLE; Fdo->Flags |= DO_BUFFERED_IO; /* FIXME: Why is it needed for 1st stage setup? */ Fdo->Flags &= ~DO_DEVICE_INITIALIZING; @@ -383,13 +384,11 @@ cleanup: RtlWriteRegistryValue( RTL_REGISTRY_DEVICEMAP, DriverExtension->DeviceBaseName.Buffer, - DeviceNameU.Buffer, + DeviceExtension->DeviceName, REG_SZ, DriverExtension->RegistryPath.Buffer, DriverExtension->RegistryPath.MaximumLength); - ExFreePool(DeviceNameU.Buffer); - if (ClassDO) *ClassDO = Fdo; @@ -397,10 +396,11 @@ cleanup: } static NTSTATUS -FillOneEntry( +FillEntries( IN PDEVICE_OBJECT ClassDeviceObject, IN PIRP Irp, - IN PKEYBOARD_INPUT_DATA DataStart) + IN PKEYBOARD_INPUT_DATA DataStart, + IN SIZE_T NumberOfEntries) { NTSTATUS Status = STATUS_SUCCESS; @@ -409,7 +409,7 @@ FillOneEntry( RtlCopyMemory( Irp->AssociatedIrp.SystemBuffer, DataStart, - sizeof(KEYBOARD_INPUT_DATA)); + NumberOfEntries * sizeof(KEYBOARD_INPUT_DATA)); } else if (ClassDeviceObject->Flags & DO_DIRECT_IO) { @@ -419,7 +419,7 @@ FillOneEntry( RtlCopyMemory( DestAddress, DataStart, - sizeof(KEYBOARD_INPUT_DATA)); + NumberOfEntries * sizeof(KEYBOARD_INPUT_DATA)); } else Status = STATUS_UNSUCCESSFUL; @@ -431,7 +431,7 @@ FillOneEntry( RtlCopyMemory( Irp->UserBuffer, DataStart, - sizeof(KEYBOARD_INPUT_DATA)); + NumberOfEntries * sizeof(KEYBOARD_INPUT_DATA)); } _SEH_HANDLE { @@ -453,7 +453,6 @@ ClassCallback( PCLASS_DEVICE_EXTENSION ClassDeviceExtension = ClassDeviceObject->DeviceExtension; PIRP Irp = NULL; KIRQL OldIrql; - PIO_STACK_LOCATION Stack; ULONG InputCount = DataEnd - DataStart; ULONG ReadSize; @@ -468,31 +467,35 @@ ClassCallback( */ if (ClassDeviceExtension->ReadIsPending == TRUE && InputCount) { + /* A read request is waiting for input, so go straight to it */ NTSTATUS Status; + SIZE_T NumberOfEntries; Irp = ClassDeviceObject->CurrentIrp; ClassDeviceObject->CurrentIrp = NULL; - Stack = IoGetCurrentIrpStackLocation(Irp); - /* A read request is waiting for input, so go straight to it */ - Status = FillOneEntry( + NumberOfEntries = MIN( + InputCount, + IoGetCurrentIrpStackLocation(Irp)->Parameters.Read.Length / sizeof(KEYBOARD_INPUT_DATA)); + + Status = FillEntries( ClassDeviceObject, Irp, - DataStart); + DataStart, + NumberOfEntries); if (NT_SUCCESS(Status)) { /* 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); + Irp->IoStatus.Information = NumberOfEntries * sizeof(KEYBOARD_INPUT_DATA); ClassDeviceExtension->ReadIsPending = FALSE; /* Skip the packet we just sent away */ - DataStart++; - (*ConsumedCount)++; - InputCount--; + DataStart += NumberOfEntries; + (*ConsumedCount) += NumberOfEntries; + InputCount -= NumberOfEntries; } } @@ -561,11 +564,14 @@ ConnectPortDriver( ConnectData.ClassDeviceObject = ClassDO; ConnectData.ClassService = ClassCallback; - Irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_KEYBOARD_CONNECT, + Irp = IoBuildDeviceIoControlRequest( + IOCTL_INTERNAL_KEYBOARD_CONNECT, PortDO, &ConnectData, sizeof(CONNECT_DATA), NULL, 0, TRUE, &Event, &IoStatus); + if (!Irp) + return STATUS_INSUFFICIENT_RESOURCES; Status = IoCallDriver(PortDO, Irp); @@ -593,16 +599,65 @@ ConnectPortDriver( return IoStatus.Status; } -/* Send IOCTL_INTERNAL_*_DISCONNECT to port */ -static NTSTATUS -DisconnectPortDriver( +/* Send IOCTL_INTERNAL_*_DISCONNECT to port + destroy the Port DO */ +static VOID +DestroyPortDriver( IN PDEVICE_OBJECT PortDO) { - DPRINT("Disconnecting PortDO %p [%wZ]\n", + PPORT_DEVICE_EXTENSION DeviceExtension; + PCLASS_DEVICE_EXTENSION ClassDeviceExtension; + PCLASS_DRIVER_EXTENSION DriverExtension; + KEVENT Event; + PIRP Irp; + IO_STATUS_BLOCK IoStatus; + KIRQL OldIrql; + NTSTATUS Status; + + DPRINT("Destroying PortDO %p [%wZ]\n", PortDO, &PortDO->DriverObject->DriverName); - DPRINT1("FIXME: Need to send IOCTL_INTERNAL_*_DISCONNECT\n"); - return STATUS_NOT_IMPLEMENTED; + DeviceExtension = (PPORT_DEVICE_EXTENSION)PortDO->DeviceExtension; + ClassDeviceExtension = DeviceExtension->ClassDO->DeviceExtension; + DriverExtension = IoGetDriverObjectExtension(PortDO->DriverObject, PortDO->DriverObject); + + /* Send IOCTL_INTERNAL_*_DISCONNECT */ + KeInitializeEvent(&Event, NotificationEvent, FALSE); + Irp = IoBuildDeviceIoControlRequest( + IOCTL_INTERNAL_KEYBOARD_DISCONNECT, + PortDO, + NULL, 0, + NULL, 0, + TRUE, &Event, &IoStatus); + if (Irp) + { + Status = IoCallDriver(PortDO, Irp); + if (Status == STATUS_PENDING) + KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL); + } + + /* Remove from ClassDeviceExtension->ListHead list */ + KeAcquireSpinLock(&ClassDeviceExtension->ListSpinLock, &OldIrql); + RemoveHeadList(DeviceExtension->ListEntry.Blink); + KeReleaseSpinLock(&ClassDeviceExtension->ListSpinLock, OldIrql); + + /* Remove entry from HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\[DeviceBaseName] */ + RtlDeleteRegistryValue( + RTL_REGISTRY_DEVICEMAP, + DriverExtension->DeviceBaseName.Buffer, + ClassDeviceExtension->DeviceName); + + if (DeviceExtension->LowerDevice) + IoDetachDevice(DeviceExtension->LowerDevice); + ObDereferenceObject(PortDO); + + if (!DriverExtension->ConnectMultiplePorts && DeviceExtension->ClassDO) + { + ExFreePool(ClassDeviceExtension->PortData); + ExFreePool((PVOID)ClassDeviceExtension->DeviceName); + IoDeleteDevice(DeviceExtension->ClassDO); + } + + IoDeleteDevice(PortDO); } static NTSTATUS NTAPI @@ -679,44 +734,21 @@ ClassAddDevice( } Fdo->Flags &= ~DO_DEVICE_INITIALIZING; - /* Register interface */ + /* Register interface ; ignore the error (if any) as having + * a registred interface is not so important... */ Status = IoRegisterDeviceInterface( Pdo, &GUID_DEVINTERFACE_KEYBOARD, NULL, &DeviceExtension->InterfaceName); - 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); - goto cleanup; - } + if (!NT_SUCCESS(Status)) + DeviceExtension->InterfaceName.Length = 0; return STATUS_SUCCESS; cleanup: - if (!(Fdo->Flags & DO_DEVICE_INITIALIZING)) - DisconnectPortDriver(Fdo); - 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); - /* FIXME BSOD for second boot when u press on finsih buttom or wait timeout */ - //IoDeleteDevice(DeviceExtension->ClassDO); - } - } if (Fdo) - IoDeleteDevice(Fdo); + DestroyPortDriver(Fdo); return Status; } @@ -726,7 +758,6 @@ ClassStartIo( IN PIRP Irp) { PCLASS_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; - PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp); ASSERT(DeviceExtension->Common.IsClassDO); @@ -734,29 +765,34 @@ ClassStartIo( { KIRQL oldIrql; NTSTATUS Status; + SIZE_T NumberOfEntries; + + NumberOfEntries = MIN( + DeviceExtension->InputCount, + IoGetCurrentIrpStackLocation(Irp)->Parameters.Read.Length / sizeof(KEYBOARD_INPUT_DATA)); KeAcquireSpinLock(&DeviceExtension->SpinLock, &oldIrql); - Status = FillOneEntry( + Status = FillEntries( DeviceObject, Irp, - &DeviceExtension->PortData[DeviceExtension->InputCount - 1]); + DeviceExtension->PortData, + NumberOfEntries); if (NT_SUCCESS(Status)) { - if (DeviceExtension->InputCount > 1) + if (DeviceExtension->InputCount > NumberOfEntries) { RtlMoveMemory( - &DeviceExtension->PortData[1], &DeviceExtension->PortData[0], - (DeviceExtension->InputCount - 1) * sizeof(KEYBOARD_INPUT_DATA)); + &DeviceExtension->PortData[NumberOfEntries], + (DeviceExtension->InputCount - NumberOfEntries) * sizeof(KEYBOARD_INPUT_DATA)); } - DeviceExtension->InputCount--; + DeviceExtension->InputCount -= NumberOfEntries; DeviceExtension->ReadIsPending = FALSE; - Irp->IoStatus.Information = sizeof(KEYBOARD_INPUT_DATA); - Stack->Parameters.Read.Length = sizeof(KEYBOARD_INPUT_DATA); + Irp->IoStatus.Information = NumberOfEntries * sizeof(KEYBOARD_INPUT_DATA); } /* Go to next packet and complete this request */ diff --git a/reactos/drivers/input/kbdclass/kbdclass.h b/reactos/drivers/input/kbdclass/kbdclass.h index 1e129cfe5be..55b025bfc69 100644 --- a/reactos/drivers/input/kbdclass/kbdclass.h +++ b/reactos/drivers/input/kbdclass/kbdclass.h @@ -6,6 +6,8 @@ #define MAX_PATH 260 +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + typedef enum { dsStopped, @@ -56,6 +58,7 @@ typedef struct _CLASS_DEVICE_EXTENSION BOOLEAN ReadIsPending; ULONG InputCount; PKEYBOARD_INPUT_DATA PortData; + LPCWSTR DeviceName; } CLASS_DEVICE_EXTENSION, *PCLASS_DEVICE_EXTENSION; /* misc.c */ diff --git a/reactos/drivers/input/mouclass/mouclass.c b/reactos/drivers/input/mouclass/mouclass.c index 8f400764f20..b1bd516039c 100644 --- a/reactos/drivers/input/mouclass/mouclass.c +++ b/reactos/drivers/input/mouclass/mouclass.c @@ -123,7 +123,7 @@ ClassDeviceControl( PLIST_ENTRY Head = &((PCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->ListHead; if (Head->Flink != Head) { - /* We have at least one mouse */ + /* We have at least one device */ PPORT_DEVICE_EXTENSION DevExt = CONTAINING_RECORD(Head->Flink, PORT_DEVICE_EXTENSION, ListEntry); IoGetCurrentIrpStackLocation(Irp)->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; IoSkipCurrentIrpStackLocation(Irp); @@ -352,6 +352,7 @@ cleanup: ExFreePool(DeviceNameU.Buffer); return STATUS_INSUFFICIENT_RESOURCES; } + DeviceExtension->DeviceName = DeviceNameU.Buffer; Fdo->Flags |= DO_POWER_PAGABLE; Fdo->Flags &= ~DO_DEVICE_INITIALIZING; @@ -359,13 +360,11 @@ cleanup: RtlWriteRegistryValue( RTL_REGISTRY_DEVICEMAP, DriverExtension->DeviceBaseName.Buffer, - DeviceNameU.Buffer, + DeviceExtension->DeviceName, REG_SZ, DriverExtension->RegistryPath.Buffer, DriverExtension->RegistryPath.MaximumLength); - ExFreePool(DeviceNameU.Buffer); - if (ClassDO) *ClassDO = Fdo; @@ -373,10 +372,11 @@ cleanup: } static NTSTATUS -FillOneEntry( +FillEntries( IN PDEVICE_OBJECT ClassDeviceObject, IN PIRP Irp, - IN PMOUSE_INPUT_DATA DataStart) + IN PMOUSE_INPUT_DATA DataStart, + IN SIZE_T NumberOfEntries) { NTSTATUS Status = STATUS_SUCCESS; @@ -385,7 +385,7 @@ FillOneEntry( RtlCopyMemory( Irp->AssociatedIrp.SystemBuffer, DataStart, - sizeof(MOUSE_INPUT_DATA)); + NumberOfEntries * sizeof(MOUSE_INPUT_DATA)); } else if (ClassDeviceObject->Flags & DO_DIRECT_IO) { @@ -395,7 +395,7 @@ FillOneEntry( RtlCopyMemory( DestAddress, DataStart, - sizeof(MOUSE_INPUT_DATA)); + NumberOfEntries * sizeof(MOUSE_INPUT_DATA)); } else Status = STATUS_UNSUCCESSFUL; @@ -407,7 +407,7 @@ FillOneEntry( RtlCopyMemory( Irp->UserBuffer, DataStart, - sizeof(MOUSE_INPUT_DATA)); + NumberOfEntries * sizeof(MOUSE_INPUT_DATA)); } _SEH_HANDLE { @@ -429,7 +429,6 @@ ClassCallback( PCLASS_DEVICE_EXTENSION ClassDeviceExtension = ClassDeviceObject->DeviceExtension; PIRP Irp = NULL; KIRQL OldIrql; - PIO_STACK_LOCATION Stack; ULONG InputCount = DataEnd - DataStart; ULONG ReadSize; @@ -444,31 +443,35 @@ ClassCallback( */ if (ClassDeviceExtension->ReadIsPending == TRUE && InputCount) { + /* A read request is waiting for input, so go straight to it */ NTSTATUS Status; + SIZE_T NumberOfEntries; Irp = ClassDeviceObject->CurrentIrp; ClassDeviceObject->CurrentIrp = NULL; - Stack = IoGetCurrentIrpStackLocation(Irp); - /* A read request is waiting for input, so go straight to it */ - Status = FillOneEntry( + NumberOfEntries = MIN( + InputCount, + IoGetCurrentIrpStackLocation(Irp)->Parameters.Read.Length / sizeof(MOUSE_INPUT_DATA)); + + Status = FillEntries( ClassDeviceObject, Irp, - DataStart); + DataStart, + NumberOfEntries); if (NT_SUCCESS(Status)) { /* Go to next packet and complete this request with STATUS_SUCCESS */ Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = sizeof(MOUSE_INPUT_DATA); - Stack->Parameters.Read.Length = sizeof(MOUSE_INPUT_DATA); + Irp->IoStatus.Information = NumberOfEntries * sizeof(MOUSE_INPUT_DATA); ClassDeviceExtension->ReadIsPending = FALSE; /* Skip the packet we just sent away */ - DataStart++; - (*ConsumedCount)++; - InputCount--; + DataStart += NumberOfEntries; + (*ConsumedCount) += NumberOfEntries; + InputCount -= NumberOfEntries; } } @@ -537,11 +540,14 @@ ConnectPortDriver( ConnectData.ClassDeviceObject = ClassDO; ConnectData.ClassService = ClassCallback; - Irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_MOUSE_CONNECT, + Irp = IoBuildDeviceIoControlRequest( + IOCTL_INTERNAL_MOUSE_CONNECT, PortDO, &ConnectData, sizeof(CONNECT_DATA), NULL, 0, TRUE, &Event, &IoStatus); + if (!Irp) + return STATUS_INSUFFICIENT_RESOURCES; Status = IoCallDriver(PortDO, Irp); @@ -569,16 +575,65 @@ ConnectPortDriver( return IoStatus.Status; } -/* Send IOCTL_INTERNAL_*_DISCONNECT to port */ -static NTSTATUS -DisconnectPortDriver( +/* Send IOCTL_INTERNAL_*_DISCONNECT to port + destroy the Port DO */ +static VOID +DestroyPortDriver( IN PDEVICE_OBJECT PortDO) { - DPRINT("Disconnecting PortDO %p [%wZ]\n", + PPORT_DEVICE_EXTENSION DeviceExtension; + PCLASS_DEVICE_EXTENSION ClassDeviceExtension; + PCLASS_DRIVER_EXTENSION DriverExtension; + KEVENT Event; + PIRP Irp; + IO_STATUS_BLOCK IoStatus; + KIRQL OldIrql; + NTSTATUS Status; + + DPRINT("Destroying PortDO %p [%wZ]\n", PortDO, &PortDO->DriverObject->DriverName); - DPRINT1("FIXME: Need to send IOCTL_INTERNAL_*_DISCONNECT\n"); - return STATUS_NOT_IMPLEMENTED; + DeviceExtension = (PPORT_DEVICE_EXTENSION)PortDO->DeviceExtension; + ClassDeviceExtension = DeviceExtension->ClassDO->DeviceExtension; + DriverExtension = IoGetDriverObjectExtension(PortDO->DriverObject, PortDO->DriverObject); + + /* Send IOCTL_INTERNAL_*_DISCONNECT */ + KeInitializeEvent(&Event, NotificationEvent, FALSE); + Irp = IoBuildDeviceIoControlRequest( + IOCTL_INTERNAL_MOUSE_DISCONNECT, + PortDO, + NULL, 0, + NULL, 0, + TRUE, &Event, &IoStatus); + if (Irp) + { + Status = IoCallDriver(PortDO, Irp); + if (Status == STATUS_PENDING) + KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL); + } + + /* Remove from ClassDeviceExtension->ListHead list */ + KeAcquireSpinLock(&ClassDeviceExtension->ListSpinLock, &OldIrql); + RemoveHeadList(DeviceExtension->ListEntry.Blink); + KeReleaseSpinLock(&ClassDeviceExtension->ListSpinLock, OldIrql); + + /* Remove entry from HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\[DeviceBaseName] */ + RtlDeleteRegistryValue( + RTL_REGISTRY_DEVICEMAP, + DriverExtension->DeviceBaseName.Buffer, + ClassDeviceExtension->DeviceName); + + if (DeviceExtension->LowerDevice) + IoDetachDevice(DeviceExtension->LowerDevice); + ObDereferenceObject(PortDO); + + if (!DriverExtension->ConnectMultiplePorts && DeviceExtension->ClassDO) + { + ExFreePool(ClassDeviceExtension->PortData); + ExFreePool((PVOID)ClassDeviceExtension->DeviceName); + IoDeleteDevice(DeviceExtension->ClassDO); + } + + IoDeleteDevice(PortDO); } static NTSTATUS NTAPI @@ -655,44 +710,21 @@ ClassAddDevice( } Fdo->Flags &= ~DO_DEVICE_INITIALIZING; - /* Register interface */ - Status = IoRegisterDeviceInterface( + /* Register interface ; ignore the error (if any) as having + * a registred interface is not so important... */ + IoRegisterDeviceInterface( Pdo, &GUID_DEVINTERFACE_MOUSE, NULL, &DeviceExtension->InterfaceName); - 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); - goto cleanup; - } + if (!NT_SUCCESS(Status)) + DeviceExtension->InterfaceName.Length = 0; return STATUS_SUCCESS; cleanup: - if (!(Fdo->Flags & DO_DEVICE_INITIALIZING)) - DisconnectPortDriver(Fdo); - 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); - /* FIXME BSOD for second boot when u press on finsih buttom or wait timeout */ - // IoDeleteDevice(DeviceExtension->ClassDO); - } - } if (Fdo) - IoDeleteDevice(Fdo); + DestroyPortDriver(Fdo); return Status; } @@ -702,7 +734,6 @@ ClassStartIo( IN PIRP Irp) { PCLASS_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; - PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp); ASSERT(DeviceExtension->Common.IsClassDO); @@ -710,29 +741,34 @@ ClassStartIo( { KIRQL oldIrql; NTSTATUS Status; + SIZE_T NumberOfEntries; + + NumberOfEntries = MIN( + DeviceExtension->InputCount, + IoGetCurrentIrpStackLocation(Irp)->Parameters.Read.Length / sizeof(MOUSE_INPUT_DATA)); KeAcquireSpinLock(&DeviceExtension->SpinLock, &oldIrql); - Status = FillOneEntry( + Status = FillEntries( DeviceObject, Irp, - &DeviceExtension->PortData[DeviceExtension->InputCount - 1]); + DeviceExtension->PortData, + NumberOfEntries); if (NT_SUCCESS(Status)) { - if (DeviceExtension->InputCount > 1) + if (DeviceExtension->InputCount > NumberOfEntries) { RtlMoveMemory( - &DeviceExtension->PortData[1], &DeviceExtension->PortData[0], - (DeviceExtension->InputCount - 1) * sizeof(MOUSE_INPUT_DATA)); + &DeviceExtension->PortData[NumberOfEntries], + (DeviceExtension->InputCount - NumberOfEntries) * sizeof(MOUSE_INPUT_DATA)); } - DeviceExtension->InputCount--; + DeviceExtension->InputCount -= NumberOfEntries; DeviceExtension->ReadIsPending = FALSE; - Irp->IoStatus.Information = sizeof(MOUSE_INPUT_DATA); - Stack->Parameters.Read.Length = sizeof(MOUSE_INPUT_DATA); + Irp->IoStatus.Information = NumberOfEntries * sizeof(MOUSE_INPUT_DATA); } /* Go to next packet and complete this request */ diff --git a/reactos/drivers/input/mouclass/mouclass.h b/reactos/drivers/input/mouclass/mouclass.h index 2d1f7f40357..3a95c7b1937 100644 --- a/reactos/drivers/input/mouclass/mouclass.h +++ b/reactos/drivers/input/mouclass/mouclass.h @@ -6,6 +6,8 @@ #define MAX_PATH 260 +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + typedef enum { dsStopped, @@ -56,6 +58,7 @@ typedef struct _CLASS_DEVICE_EXTENSION BOOLEAN ReadIsPending; ULONG InputCount; PMOUSE_INPUT_DATA PortData; + LPCWSTR DeviceName; } CLASS_DEVICE_EXTENSION, *PCLASS_DEVICE_EXTENSION; /* misc.c */