Author: hpoussin
Date: Tue Jul 18 02:13:40 2006
New Revision: 23129
URL:
http://svn.reactos.org/svn/reactos?rev=23129&view=rev
Log:
- 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.
Modified:
trunk/reactos/drivers/input/kbdclass/kbdclass.c
trunk/reactos/drivers/input/kbdclass/kbdclass.h
trunk/reactos/drivers/input/mouclass/mouclass.c
trunk/reactos/drivers/input/mouclass/mouclass.h
Modified: trunk/reactos/drivers/input/kbdclass/kbdclass.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/input/kbdclass/kbd…
==============================================================================
--- trunk/reactos/drivers/input/kbdclass/kbdclass.c (original)
+++ trunk/reactos/drivers/input/kbdclass/kbdclass.c Tue Jul 18 02:13:40 2006
@@ -126,7 +126,7 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
RtlCopyMemory(
DestAddress,
DataStart,
- sizeof(KEYBOARD_INPUT_DATA));
+ NumberOfEntries * sizeof(KEYBOARD_INPUT_DATA));
}
else
Status = STATUS_UNSUCCESSFUL;
@@ -431,7 +431,7 @@
RtlCopyMemory(
Irp->UserBuffer,
DataStart,
- sizeof(KEYBOARD_INPUT_DATA));
+ NumberOfEntries * sizeof(KEYBOARD_INPUT_DATA));
}
_SEH_HANDLE
{
@@ -453,7 +453,6 @@
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 @@
*/
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 @@
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 @@
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 @@
}
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 @@
IN PIRP Irp)
{
PCLASS_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
- PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
ASSERT(DeviceExtension->Common.IsClassDO);
@@ -734,29 +765,34 @@
{
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 */
Modified: trunk/reactos/drivers/input/kbdclass/kbdclass.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/input/kbdclass/kbd…
==============================================================================
--- trunk/reactos/drivers/input/kbdclass/kbdclass.h (original)
+++ trunk/reactos/drivers/input/kbdclass/kbdclass.h Tue Jul 18 02:13:40 2006
@@ -5,6 +5,8 @@
#include <stdio.h>
#define MAX_PATH 260
+
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
typedef enum
{
@@ -56,6 +58,7 @@
BOOLEAN ReadIsPending;
ULONG InputCount;
PKEYBOARD_INPUT_DATA PortData;
+ LPCWSTR DeviceName;
} CLASS_DEVICE_EXTENSION, *PCLASS_DEVICE_EXTENSION;
/* misc.c */
Modified: trunk/reactos/drivers/input/mouclass/mouclass.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/input/mouclass/mou…
==============================================================================
--- trunk/reactos/drivers/input/mouclass/mouclass.c (original)
+++ trunk/reactos/drivers/input/mouclass/mouclass.c Tue Jul 18 02:13:40 2006
@@ -123,7 +123,7 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
RtlCopyMemory(
DestAddress,
DataStart,
- sizeof(MOUSE_INPUT_DATA));
+ NumberOfEntries * sizeof(MOUSE_INPUT_DATA));
}
else
Status = STATUS_UNSUCCESSFUL;
@@ -407,7 +407,7 @@
RtlCopyMemory(
Irp->UserBuffer,
DataStart,
- sizeof(MOUSE_INPUT_DATA));
+ NumberOfEntries * sizeof(MOUSE_INPUT_DATA));
}
_SEH_HANDLE
{
@@ -429,7 +429,6 @@
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 @@
*/
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 @@
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 @@
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 @@
}
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 @@
IN PIRP Irp)
{
PCLASS_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
- PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
ASSERT(DeviceExtension->Common.IsClassDO);
@@ -710,29 +741,34 @@
{
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 */
Modified: trunk/reactos/drivers/input/mouclass/mouclass.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/input/mouclass/mou…
==============================================================================
--- trunk/reactos/drivers/input/mouclass/mouclass.h (original)
+++ trunk/reactos/drivers/input/mouclass/mouclass.h Tue Jul 18 02:13:40 2006
@@ -5,6 +5,8 @@
#include <stdio.h>
#define MAX_PATH 260
+
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
typedef enum
{
@@ -56,6 +58,7 @@
BOOLEAN ReadIsPending;
ULONG InputCount;
PMOUSE_INPUT_DATA PortData;
+ LPCWSTR DeviceName;
} CLASS_DEVICE_EXTENSION, *PCLASS_DEVICE_EXTENSION;
/* misc.c */