- 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
This commit is contained in:
Hervé Poussineau 2006-07-17 22:13:40 +00:00
parent de3f42794a
commit 2c59aa9330
4 changed files with 205 additions and 127 deletions

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */