Rewrite mouclass, so it can now handle more than one mouse.
win32k: try to open the keyboard/mouse in a loop, as they can not be
present at startup
Modified: trunk/reactos/bootdata/hivesys.inf
Added: trunk/reactos/drivers/input/mouclass/misc.c
Modified: trunk/reactos/drivers/input/mouclass/mouclass.c
Modified: trunk/reactos/drivers/input/mouclass/mouclass.h
Modified: trunk/reactos/drivers/input/mouclass/mouclass.xml
Modified: trunk/reactos/subsys/win32k/ntuser/input.c
_____
Modified: trunk/reactos/bootdata/hivesys.inf
--- trunk/reactos/bootdata/hivesys.inf 2005-10-31 00:10:32 UTC (rev
18905)
+++ trunk/reactos/bootdata/hivesys.inf 2005-10-31 00:14:45 UTC (rev
18906)
@@ -532,7 +532,7 @@
HKLM,"SYSTEM\CurrentControlSet\Services\mouclass","Type",0x00010001,0x00
000001
HKLM,"SYSTEM\CurrentControlSet\Services\mouclass\Parameters","ConnectMul
tiplePorts",0x00010001,0x00000000
HKLM,"SYSTEM\CurrentControlSet\Services\mouclass\Parameters","MouseDataQ
ueueSize",0x00010001,0x00000064
-HKLM,"SYSTEM\CurrentControlSet\Services\mouclass\Parameters","PointerDe
viceBaseName",0x00000000,"PointerClass"
+HKLM,"SYSTEM\CurrentControlSet\Services\mouclass\Parameters","PointerDe
viceBaseName",0x00000000,"PointerClassPnp"
HKLM,"SYSTEM\CurrentControlSet\Control\Class\{4D36E96F-E325-11CE-BFC1-08
002BE10318}","UpperFilters",0x00010000,"mouclass"
; Mailslot filesystem driver
_____
Added: trunk/reactos/drivers/input/mouclass/misc.c
--- trunk/reactos/drivers/input/mouclass/misc.c 2005-10-31 00:10:32 UTC
(rev 18905)
+++ trunk/reactos/drivers/input/mouclass/misc.c 2005-10-31 00:14:45 UTC
(rev 18906)
@@ -0,0 +1,61 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Mouse class driver
+ * FILE: drivers/input/mouclass/misc.c
+ * PURPOSE: Misceallenous operations
+ *
+ * PROGRAMMERS: HervÚ Poussineau (hpoussin(a)reactos.org)
+ */
+
+#define NDEBUG
+#include <debug.h>
+
+#include "mouclass.h"
+
+static NTSTATUS NTAPI
+ForwardIrpAndWaitCompletion(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context)
+{
+ if (Irp->PendingReturned)
+ KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);
+ return STATUS_MORE_PROCESSING_REQUIRED;
+}
+
+NTSTATUS
+ForwardIrpAndWait(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PDEVICE_OBJECT LowerDevice =
((PMOUCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice
;
+ KEVENT Event;
+ NTSTATUS Status;
+
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+
+ DPRINT("Calling lower device %p [%wZ]\n", LowerDevice,
&LowerDevice->DriverObject->DriverName);
+ IoSetCompletionRoutine(Irp, ForwardIrpAndWaitCompletion, &Event,
TRUE, TRUE, TRUE);
+
+ Status = IoCallDriver(LowerDevice, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ Status = KeWaitForSingleObject(&Event, Suspended,
KernelMode, FALSE, NULL);
+ if (NT_SUCCESS(Status))
+ Status = Irp->IoStatus.Status;
+ }
+
+ return Status;
+}
+
+NTSTATUS NTAPI
+ForwardIrpAndForget(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PDEVICE_OBJECT LowerDevice =
((PMOUCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice
;
+
+ IoSkipCurrentIrpStackLocation(Irp);
+ return IoCallDriver(LowerDevice, Irp);
+}
Property changes on: trunk/reactos/drivers/input/mouclass/misc.c
___________________________________________________________________
Name: svn:eol-style
+ native
_____
Modified: trunk/reactos/drivers/input/mouclass/mouclass.c
--- trunk/reactos/drivers/input/mouclass/mouclass.c 2005-10-31
00:10:32 UTC (rev 18905)
+++ trunk/reactos/drivers/input/mouclass/mouclass.c 2005-10-31
00:14:45 UTC (rev 18906)
@@ -1,277 +1,599 @@
-/*
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Mouse class driver
+ * FILE: drivers/mouclass/mouclass.c
+ * PURPOSE: Mouse class driver
+ *
+ * PROGRAMMERS: HervÚ Poussineau (hpoussin(a)reactos.org)
+ */
- ** Mouse class driver 0.0.1
- ** Written by Jason Filby (jasonfilby(a)yahoo.com)
- ** For ReactOS (
www.reactos.com)
+#define NDEBUG
+#include <debug.h>
- ** The class driver between win32k and the various mouse port drivers
+#define INITGUID
+#include "mouclass.h"
- ** FIXME: Support IRP cancellation properly.
-*/
+static VOID NTAPI
+DriverUnload(IN PDRIVER_OBJECT DriverObject)
+{
+ // nothing to do here yet
+}
-#include <ddk/ntddk.h>
-#include <ddk/ntddmou.h>
-#include <ddk/kbdmou.h>
-#include "mouclass.h"
+static NTSTATUS NTAPI
+MouclassCreate(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ DPRINT("IRP_MJ_CREATE\n");
-#define NDEBUG
-#include <debug.h>
+ if
(!((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsClassDO)
+ return ForwardIrpAndForget(DeviceObject, Irp);
-NTSTATUS STDCALL
-DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
+ /* FIXME: open all associated Port devices */
+ return STATUS_SUCCESS;
+}
-PDEVICE_OBJECT MouclassDeviceObject;
+static NTSTATUS NTAPI
+MouclassClose(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ DPRINT("IRP_MJ_CLOSE\n");
-static BOOLEAN MouseClassCallBack(
- PDEVICE_OBJECT ClassDeviceObject, PMOUSE_INPUT_DATA MouseDataStart,
- PMOUSE_INPUT_DATA MouseDataEnd, PULONG ConsumedCount)
+ if
(!((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsClassDO)
+ return ForwardIrpAndForget(DeviceObject, Irp);
+
+ /* FIXME: close all associated Port devices */
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS NTAPI
+MouclassRead(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
{
- PDEVICE_EXTENSION ClassDeviceExtension =
ClassDeviceObject->DeviceExtension;
- PIRP Irp = NULL;
- KIRQL OldIrql;
- PIO_STACK_LOCATION Stack;
- ULONG InputCount = MouseDataEnd - MouseDataStart;
- ULONG ReadSize;
+ DPRINT("IRP_MJ_READ\n");
- DPRINT("Entering MouseClassCallBack\n");
- /* A filter driver might have consumed all the data already; I'm
- * not sure if they are supposed to move the packets when they
- * consume them though.
- */
- if (ClassDeviceExtension->ReadIsPending == TRUE &&
- InputCount)
- {
- Irp = ClassDeviceObject->CurrentIrp;
- ClassDeviceObject->CurrentIrp = NULL;
- Stack = IoGetCurrentIrpStackLocation(Irp);
+ if
(!((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsClassDO)
+ return ForwardIrpAndForget(DeviceObject, Irp);
- /* A read request is waiting for input, so go straight to it */
- RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer, MouseDataStart,
- sizeof(MOUSE_INPUT_DATA));
+ if (IoGetCurrentIrpStackLocation(Irp)->Parameters.Read.Length <
sizeof(MOUSE_INPUT_DATA))
+ {
+ Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
- /* 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);
+ return STATUS_BUFFER_TOO_SMALL;
+ }
- ClassDeviceExtension->ReadIsPending = FALSE;
+ IoMarkIrpPending(Irp);
+ IoStartPacket(DeviceObject, Irp, NULL, NULL);
+ return STATUS_PENDING;
+}
- /* Skip the packet we just sent away */
- MouseDataStart++;
- (*ConsumedCount)++;
- InputCount--;
- }
+static NTSTATUS NTAPI
+IrpStub(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ NTSTATUS Status = STATUS_NOT_SUPPORTED;
- /* If we have data from the port driver and a higher service to send
the data to */
- if (InputCount != 0)
- {
- KeAcquireSpinLock(&ClassDeviceExtension->SpinLock, &OldIrql);
+ if
(!((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsClassDO)
+ {
+ /* Forward some IRPs to lower device */
+ switch
(IoGetCurrentIrpStackLocation(Irp)->MajorFunction)
+ {
+ case IRP_MJ_INTERNAL_DEVICE_CONTROL:
+ return ForwardIrpAndForget(DeviceObject,
Irp);
+ default:
+ {
+ DPRINT1("Port DO stub for major function
0x%lx\n",
+
IoGetCurrentIrpStackLocation(Irp)->MajorFunction);
+ ASSERT(FALSE);
+ Status = Irp->IoStatus.Status;
+ }
+ }
+ }
+ else if (IoGetCurrentIrpStackLocation(Irp)->MajorFunction ==
IRP_MJ_INTERNAL_DEVICE_CONTROL) /* HACK FOR I8042PRT */
+ {
+ Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ DPRINT1("Class DO stub for major function 0x%lx\n",
+
IoGetCurrentIrpStackLocation(Irp)->MajorFunction);
+ ASSERT(FALSE);
+ Status = Irp->IoStatus.Status;
+ }
- if (ClassDeviceExtension->InputCount + InputCount >
MOUSE_BUFFER_SIZE)
- {
- ReadSize = MOUSE_BUFFER_SIZE -
ClassDeviceExtension->InputCount;
- } else {
- ReadSize = InputCount;
- }
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return Status;
+}
- /*
- * FIXME: If we exceed the buffer, mouse data gets thrown away..
better
- * solution?
- */
+static NTSTATUS
+ReadRegistryEntries(
+ IN PUNICODE_STRING RegistryPath,
+ IN PMOUCLASS_DRIVER_EXTENSION DriverExtension)
+{
+ RTL_QUERY_REGISTRY_TABLE Parameters[4];
+ NTSTATUS Status;
- /*
- * Move the mouse input data from the port data queue to our
class data
- * queue.
- */
- RtlMoveMemory(ClassDeviceExtension->PortData,
(PCHAR)MouseDataStart,
- sizeof(MOUSE_INPUT_DATA) * ReadSize);
+ ULONG DefaultConnectMultiplePorts = 1;
+ ULONG DefaultMouseDataQueueSize = 0x64;
+ UNICODE_STRING DefaultPointerDeviceBaseName =
RTL_CONSTANT_STRING(L"PointerClassPnp");
- /* Move the pointer and counter up */
- ClassDeviceExtension->PortData += ReadSize;
- ClassDeviceExtension->InputCount += ReadSize;
+ RtlZeroMemory(Parameters, sizeof(Parameters));
- KeReleaseSpinLock(&ClassDeviceExtension->SpinLock, OldIrql);
- (*ConsumedCount) += ReadSize;
- } else {
- DPRINT("MouseClassCallBack() entered, InputCount = %d - DOING
NOTHING\n", InputCount);
- }
+ Parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT |
RTL_REGISTRY_OPTIONAL;
+ Parameters[0].Name = L"ConnectMultiplePorts";
+ Parameters[0].EntryContext =
&DriverExtension->ConnectMultiplePorts;
+ Parameters[0].DefaultType = REG_DWORD;
+ Parameters[0].DefaultData = &DefaultConnectMultiplePorts;
+ Parameters[0].DefaultLength = sizeof(ULONG);
+
+ Parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT |
RTL_REGISTRY_OPTIONAL;
+ Parameters[1].Name = L"MouseDataQueueSize";
+ Parameters[1].EntryContext =
&DriverExtension->MouseDataQueueSize;
+ Parameters[1].DefaultType = REG_DWORD;
+ Parameters[1].DefaultData = &DefaultMouseDataQueueSize;
+ Parameters[1].DefaultLength = sizeof(ULONG);
+
+ Parameters[2].Flags = RTL_QUERY_REGISTRY_DIRECT |
RTL_REGISTRY_OPTIONAL;
+ Parameters[2].Name = L"PointerDeviceBaseName";
+ Parameters[2].EntryContext =
&DriverExtension->PointerDeviceBaseName;
+ Parameters[2].DefaultType = REG_SZ;
+ Parameters[2].DefaultData = &DefaultPointerDeviceBaseName;
+ Parameters[2].DefaultLength = sizeof(ULONG);
- if (Irp != NULL)
- {
- IoStartNextPacket(ClassDeviceObject, FALSE);
- IoCompleteRequest(Irp, IO_MOUSE_INCREMENT);
- }
+ Status = RtlQueryRegistryValues(
+ RTL_REGISTRY_ABSOLUTE,
+ RegistryPath->Buffer,
+ Parameters,
+ NULL,
+ NULL);
- DPRINT("Leaving MouseClassCallBack\n");
- return TRUE;
+ if (NT_SUCCESS(Status))
+ {
+ /* Check values */
+ if (DriverExtension->ConnectMultiplePorts != 0
+ && DriverExtension->ConnectMultiplePorts != 1)
+ {
+ DriverExtension->ConnectMultiplePorts =
DefaultConnectMultiplePorts;
+ }
+ if (DriverExtension->MouseDataQueueSize == 0)
+ {
+ DriverExtension->MouseDataQueueSize =
DefaultMouseDataQueueSize;
+ }
+ }
+
+ return Status;
}
-static NTSTATUS ConnectMousePortDriver(PDEVICE_OBJECT
ClassDeviceObject)
+static NTSTATUS
+CreatePointerClassDeviceObject(
+ IN PDRIVER_OBJECT DriverObject,
+ OUT PDEVICE_OBJECT *ClassDO OPTIONAL)
{
- PDEVICE_OBJECT PortDeviceObject = NULL;
- PFILE_OBJECT FileObject = NULL;
- NTSTATUS status;
- UNICODE_STRING PortName =
RTL_CONSTANT_STRING(L"\\Device\\PointerClass0");
- IO_STATUS_BLOCK ioStatus;
- KEVENT event;
- PIRP irp;
- CONNECT_DATA ClassInformation;
- PDEVICE_EXTENSION DeviceExtension =
ClassDeviceObject->DeviceExtension;
+ PMOUCLASS_DRIVER_EXTENSION DriverExtension;
+ ULONG DeviceId = 0;
+ ULONG PrefixLength;
+ UNICODE_STRING DeviceNameU;
+ PWSTR DeviceIdW = NULL; /* Pointer into DeviceNameU.Buffer */
+ PDEVICE_OBJECT Fdo;
+ PMOUCLASS_DEVICE_EXTENSION DeviceExtension;
+ NTSTATUS Status;
- // Get the port driver's DeviceObject
- // FIXME: The name might change.. find a way to be more dynamic?
+ DPRINT("CreatePointerClassDeviceObject(0x%p)\n", DriverObject);
- status = IoGetDeviceObjectPointer(&PortName, FILE_READ_ATTRIBUTES,
&FileObject, &PortDeviceObject);
+ /* Create new device object */
+ DriverExtension = IoGetDriverObjectExtension(DriverObject,
DriverObject);
+ DeviceNameU.Length = 0;
+ DeviceNameU.MaximumLength =
+ wcslen(L"\\Device\\") * sizeof(WCHAR) /*
"\Device\" */
+ + DriverExtension->PointerDeviceBaseName.Length /*
"PointerClass" */
+ + 4 * sizeof(WCHAR) /* Id
between 0 and 9999 */
+ + sizeof(UNICODE_NULL); /* Final
NULL char */
+ DeviceNameU.Buffer = ExAllocatePool(PagedPool,
DeviceNameU.MaximumLength);
+ if (!DeviceNameU.Buffer)
+ {
+ DPRINT("ExAllocatePool() failed\n");
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ Status = RtlAppendUnicodeToString(&DeviceNameU, L"\\Device\\");
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("RtlAppendUnicodeToString() failed with status
0x%08lx\n", Status);
+ goto cleanup;
+ }
+ Status = RtlAppendUnicodeStringToString(&DeviceNameU,
&DriverExtension->PointerDeviceBaseName);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("RtlAppendUnicodeStringToString() failed with
status 0x%08lx\n", Status);
+ goto cleanup;
+ }
+ PrefixLength = DeviceNameU.MaximumLength - 4 * sizeof(WCHAR) -
sizeof(UNICODE_NULL);
+ DeviceIdW = &DeviceNameU.Buffer[PrefixLength / sizeof(WCHAR)];
+ while (DeviceId < 9999)
+ {
+ DeviceNameU.Length = PrefixLength + swprintf(DeviceIdW,
L"%ld", DeviceId) * sizeof(WCHAR);
+ Status = IoCreateDevice(
+ DriverObject,
+ sizeof(MOUCLASS_DEVICE_EXTENSION),
+ &DeviceNameU,
+ FILE_DEVICE_MOUSE,
+ FILE_DEVICE_SECURE_OPEN,
+ FALSE,
+ &Fdo);
+ if (NT_SUCCESS(Status))
+ goto cleanup;
+ else if (Status != STATUS_OBJECT_NAME_COLLISION)
+ {
+ DPRINT("IoCreateDevice() failed with status
0x%08lx\n", Status);
+ goto cleanup;
+ }
+ DeviceId++;
+ }
+ DPRINT("Too much devices starting with '\\Device\\%wZ'\n",
&DriverExtension->PointerDeviceBaseName);
+ Status = STATUS_UNSUCCESSFUL;
+cleanup:
+ ExFreePool(DeviceNameU.Buffer);
+ if (!NT_SUCCESS(Status))
+ return Status;
- if(status != STATUS_SUCCESS)
- {
- DPRINT("MOUCLASS: Could not connect to mouse port driver\n");
- DPRINT("Status: %x\n", status);
- return status;
- }
+ DeviceExtension =
(PMOUCLASS_DEVICE_EXTENSION)Fdo->DeviceExtension;
+ RtlZeroMemory(DeviceExtension,
sizeof(MOUCLASS_DEVICE_EXTENSION));
+ DeviceExtension->Common.IsClassDO = TRUE;
+ DeviceExtension->DriverExtension = DriverExtension;
+ DeviceExtension->PnpState = dsStopped;
+ KeInitializeSpinLock(&(DeviceExtension->SpinLock));
+ DeviceExtension->ReadIsPending = FALSE;
+ DeviceExtension->InputCount = 0;
+ DeviceExtension->PortData = ExAllocatePool(NonPagedPool,
DeviceExtension->DriverExtension->MouseDataQueueSize *
sizeof(MOUSE_INPUT_DATA));
+ Fdo->Flags |= DO_POWER_PAGABLE;
+ Fdo->Flags |= DO_BUFFERED_IO;
+ Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
- DeviceExtension->PortDeviceObject = PortDeviceObject;
- DeviceExtension->PortData = ExAllocatePool(NonPagedPool,
MOUSE_BUFFER_SIZE * sizeof(MOUSE_INPUT_DATA));
- DeviceExtension->InputCount = 0;
- DeviceExtension->ReadIsPending = FALSE;
- DeviceExtension->WorkItem = NULL;
- KeInitializeSpinLock(&(DeviceExtension->SpinLock));
- DeviceExtension->PassiveCallbackQueued = FALSE;
+ /* FIXME: create registry entry in
HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP */
- // Connect our callback to the port driver
+ if (ClassDO)
+ *ClassDO = Fdo;
- KeInitializeEvent(&event, NotificationEvent, FALSE);
+ return STATUS_SUCCESS;
+}
- ClassInformation.ClassDeviceObject = ClassDeviceObject;
- ClassInformation.ClassService = MouseClassCallBack;
+static BOOLEAN
+MouclassCallback(
+ IN PDEVICE_OBJECT ClassDeviceObject,
+ IN OUT PMOUSE_INPUT_DATA MouseDataStart,
+ IN PMOUSE_INPUT_DATA MouseDataEnd,
+ IN OUT PULONG ConsumedCount)
+{
+ PMOUCLASS_DEVICE_EXTENSION ClassDeviceExtension =
ClassDeviceObject->DeviceExtension;
+ PIRP Irp = NULL;
+ KIRQL OldIrql;
+ PIO_STACK_LOCATION Stack;
+ ULONG InputCount = MouseDataEnd - MouseDataStart;
+ ULONG ReadSize;
- irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_MOUSE_CONNECT,
- PortDeviceObject, &ClassInformation, sizeof(CONNECT_DATA), NULL,
0, TRUE, &event, &ioStatus);
+ ASSERT(ClassDeviceExtension->Common.IsClassDO);
- status = IoCallDriver(DeviceExtension->PortDeviceObject, irp);
+ DPRINT("MouclassCallback()\n");
+ /* A filter driver might have consumed all the data already; I'm
+ * not sure if they are supposed to move the packets when they
+ * consume them though.
+ */
+ if (ClassDeviceExtension->ReadIsPending == TRUE && InputCount)
+ {
+ Irp = ClassDeviceObject->CurrentIrp;
+ ClassDeviceObject->CurrentIrp = NULL;
+ Stack = IoGetCurrentIrpStackLocation(Irp);
- if (status == STATUS_PENDING) {
- KeWaitForSingleObject(&event, Suspended, KernelMode, FALSE,
NULL);
- } else {
- ioStatus.Status = status;
- }
+ /* A read request is waiting for input, so go straight
to it */
+ RtlMoveMemory(
+ Irp->AssociatedIrp.SystemBuffer,
+ MouseDataStart,
+ sizeof(MOUSE_INPUT_DATA));
- return ioStatus.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);
+
+ ClassDeviceExtension->ReadIsPending = FALSE;
+
+ /* Skip the packet we just sent away */
+ MouseDataStart++;
+ (*ConsumedCount)++;
+ InputCount--;
+ }
+
+ /* If we have data from the port driver and a higher service to
send the data to */
+ if (InputCount != 0)
+ {
+ KeAcquireSpinLock(&ClassDeviceExtension->SpinLock,
&OldIrql);
+
+ if (ClassDeviceExtension->InputCount + InputCount >
ClassDeviceExtension->DriverExtension->MouseDataQueueSize)
+ ReadSize =
ClassDeviceExtension->DriverExtension->MouseDataQueueSize -
ClassDeviceExtension->InputCount;
+ else
+ ReadSize = InputCount;
+
+ /*
+ * FIXME: If we exceed the buffer, mouse data gets
thrown away.. better
+ * solution?
+ */
+
+ /*
+ * Move the mouse input data from the port data queue to
our class data
+ * queue.
+ */
+ RtlMoveMemory(
+ ClassDeviceExtension->PortData,
+ (PCHAR)MouseDataStart,
+ sizeof(MOUSE_INPUT_DATA) * ReadSize);
+
+ /* Move the pointer and counter up */
+ ClassDeviceExtension->PortData += ReadSize;
+ ClassDeviceExtension->InputCount += ReadSize;
+
+ KeReleaseSpinLock(&ClassDeviceExtension->SpinLock,
OldIrql);
+ (*ConsumedCount) += ReadSize;
+ }
+ else
+ {
+ DPRINT("MouclassCallBack() entered, InputCount = %lu -
DOING NOTHING\n", InputCount);
+ }
+
+ if (Irp != NULL)
+ {
+ IoStartNextPacket(ClassDeviceObject, FALSE);
+ IoCompleteRequest(Irp, IO_MOUSE_INCREMENT);
+ }
+
+ DPRINT("Leaving MouclassCallback()\n");
+ return TRUE;
}
-static NTSTATUS STDCALL MouseClassDispatch(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
+/* Send IOCTL_INTERNAL_MOUSE_CONNECT to pointer port */
+static NTSTATUS
+ConnectMousePortDriver(
+ IN PDEVICE_OBJECT PointerPortDO,
+ IN PDEVICE_OBJECT PointerClassDO)
{
- PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
- NTSTATUS Status;
+ KEVENT Event;
+ PIRP Irp;
+ IO_STATUS_BLOCK IoStatus;
+ CONNECT_DATA ConnectData;
+ NTSTATUS Status;
- switch (Stack->MajorFunction)
- {
- case IRP_MJ_CREATE:
- Status = ConnectMousePortDriver(MouclassDeviceObject);
- break;
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
- case IRP_MJ_CLOSE:
- Status = STATUS_SUCCESS;
- break;
+ ConnectData.ClassDeviceObject = PointerClassDO;
+ ConnectData.ClassService = MouclassCallback;
- case IRP_MJ_READ:
- if (Stack->Parameters.Read.Length < sizeof(MOUSE_INPUT_DATA))
- {
- Status = STATUS_BUFFER_TOO_SMALL;
- break;
- }
- IoMarkIrpPending(Irp);
- IoStartPacket(DeviceObject, Irp, NULL, NULL);
- return STATUS_PENDING;
+ Irp =
IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_MOUSE_CONNECT,
+ PointerPortDO,
+ &ConnectData, sizeof(CONNECT_DATA),
+ NULL, 0,
+ TRUE, &Event, &IoStatus);
- default:
- DPRINT1("NOT IMPLEMENTED\n");
- Status = STATUS_NOT_IMPLEMENTED;
- break;
- }
+ Status = IoCallDriver(PointerPortDO, Irp);
- Irp->IoStatus.Status = Status;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ if (Status == STATUS_PENDING)
+ KeWaitForSingleObject(&Event, Suspended, KernelMode,
FALSE, NULL);
+ else
+ IoStatus.Status = Status;
- return Status;
+ return IoStatus.Status;
}
-static VOID STDCALL
-MouseClassStartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+static NTSTATUS NTAPI
+MouclassAddDevice(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PDEVICE_OBJECT Pdo)
{
- PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
- PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
+ PMOUCLASS_DRIVER_EXTENSION DriverExtension;
+ PDEVICE_OBJECT Fdo;
+ PMOUCLASS_DEVICE_EXTENSION DeviceExtension;
+ NTSTATUS Status;
- if (DeviceExtension->InputCount > 0)
- {
- KIRQL oldIrql;
+ DPRINT("MouclassAddDevice called. Pdo = 0x%p\n", Pdo);
- KeAcquireSpinLock(&DeviceExtension->SpinLock, &oldIrql);
+ DriverExtension = IoGetDriverObjectExtension(DriverObject,
DriverObject);
- RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer,
- DeviceExtension->PortData -
DeviceExtension->InputCount,
- sizeof(MOUSE_INPUT_DATA));
+ /* Create new device object */
+ Status = IoCreateDevice(
+ DriverObject,
+ sizeof(MOUCLASS_DEVICE_EXTENSION),
+ NULL,
+ Pdo->DeviceType,
+ FILE_DEVICE_SECURE_OPEN,
+ FALSE,
+ &Fdo);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("IoCreateDevice() failed with status 0x%08lx\n",
Status);
+ return Status;
+ }
- if (DeviceExtension->InputCount > 1)
- {
- RtlMoveMemory(
- DeviceExtension->PortData - DeviceExtension->InputCount,
- DeviceExtension->PortData - DeviceExtension->InputCount +
1,
- (DeviceExtension->InputCount - 1) *
sizeof(MOUSE_INPUT_DATA));
- }
- DeviceExtension->PortData--;
- DeviceExtension->InputCount--;
- DeviceExtension->ReadIsPending = FALSE;
+ DeviceExtension =
(PMOUCLASS_DEVICE_EXTENSION)Fdo->DeviceExtension;
+ RtlZeroMemory(DeviceExtension,
sizeof(MOUCLASS_DEVICE_EXTENSION));
+ DeviceExtension->Common.IsClassDO = FALSE;
+ DeviceExtension->PnpState = dsStopped;
+ Fdo->Flags |= DO_POWER_PAGABLE;
+ Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo,
&DeviceExtension->LowerDevice);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("IoAttachDeviceToDeviceStackSafe() failed with
status 0x%08lx\n", Status);
+ IoDeleteDevice(Fdo);
+ return Status;
+ }
+ Fdo->Flags |= DO_BUFFERED_IO;
+ Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
- /* 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);
- IoCompleteRequest(Irp, IO_MOUSE_INCREMENT);
+ if (DriverExtension->ConnectMultiplePorts)
+ Status = ConnectMousePortDriver(Fdo,
DriverExtension->MainMouclassDeviceObject);
+ else
+ Status = ConnectMousePortDriver(Fdo, Fdo);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ConnectMousePortDriver() failed with status
0x%08lx\n", Status);
+ /* FIXME: why can't I cleanup without error? */
+ //IoDetachDevice(Fdo);
+ //IoDeleteDevice(Fdo);
+ return Status;
+ }
- IoStartNextPacket(DeviceObject, FALSE);
- KeReleaseSpinLock(&DeviceExtension->SpinLock, oldIrql);
- } else {
- DeviceExtension->ReadIsPending = TRUE;
- }
+ /* Register GUID_DEVINTERFACE_MOUSE interface */
+ Status = IoRegisterDeviceInterface(
+ Pdo,
+ &GUID_DEVINTERFACE_MOUSE,
+ NULL,
+ &DeviceExtension->MouseInterfaceName);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("IoRegisterDeviceInterface() failed with status
0x%08lx\n", Status);
+ return Status;
+ }
+
+ return STATUS_SUCCESS;
}
-NTSTATUS STDCALL
-DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
+static VOID NTAPI
+MouclassStartIo(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
{
- PDEVICE_OBJECT DeviceObject;
- UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\Mouse");
- UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\??\\Mouse");
- NTSTATUS Status;
+ PMOUCLASS_DEVICE_EXTENSION DeviceExtension =
DeviceObject->DeviceExtension;
+ PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
- DriverObject->MajorFunction[IRP_MJ_CREATE] = MouseClassDispatch;
- DriverObject->MajorFunction[IRP_MJ_CLOSE] = MouseClassDispatch;
- DriverObject->MajorFunction[IRP_MJ_READ] = MouseClassDispatch;
- DriverObject->DriverStartIo = MouseClassStartIo;
+ ASSERT(DeviceExtension->Common.IsClassDO);
- Status = IoCreateDevice(DriverObject,
- sizeof(DEVICE_EXTENSION),
- &DeviceName,
- FILE_DEVICE_MOUSE,
- 0,
- TRUE,
- &DeviceObject);
- if (!NT_SUCCESS(Status))
- {
- return(Status);
- }
+ if (DeviceExtension->InputCount > 0)
+ {
+ KIRQL oldIrql;
- DeviceObject->Flags = DeviceObject->Flags | DO_BUFFERED_IO;
+ KeAcquireSpinLock(&DeviceExtension->SpinLock, &oldIrql);
- Status = IoCreateSymbolicLink(&SymlinkName, &DeviceName);
- if (!NT_SUCCESS(Status))
- {
- IoDeleteDevice(DeviceObject);
- return Status;
- }
+ RtlMoveMemory(
+ Irp->AssociatedIrp.SystemBuffer,
+ DeviceExtension->PortData -
DeviceExtension->InputCount,
+ sizeof(MOUSE_INPUT_DATA));
- MouclassDeviceObject = DeviceObject;
+ if (DeviceExtension->InputCount > 1)
+ {
+ RtlMoveMemory(
+ DeviceExtension->PortData -
DeviceExtension->InputCount,
+ DeviceExtension->PortData -
DeviceExtension->InputCount + 1,
+ (DeviceExtension->InputCount - 1) *
sizeof(MOUSE_INPUT_DATA));
+ }
+ DeviceExtension->PortData--;
+ DeviceExtension->InputCount--;
+ DeviceExtension->ReadIsPending = FALSE;
- return STATUS_SUCCESS;
+ /* 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);
+ IoCompleteRequest(Irp, IO_MOUSE_INCREMENT);
+
+ IoStartNextPacket(DeviceObject, FALSE);
+ KeReleaseSpinLock(&DeviceExtension->SpinLock, oldIrql);
+ }
+ else
+ {
+ DeviceExtension->ReadIsPending = TRUE;
+ }
}
+
+static NTSTATUS
+SearchForLegacyDrivers(
+ IN PMOUCLASS_DRIVER_EXTENSION DriverExtension)
+{
+ PDEVICE_OBJECT PortDeviceObject = NULL;
+ PFILE_OBJECT FileObject = NULL;
+ UNICODE_STRING PortName =
RTL_CONSTANT_STRING(L"\\Device\\PointerClass0");
+ NTSTATUS Status;
+
+ /* FIXME: search for more than once legacy driver */
+
+ Status = IoGetDeviceObjectPointer(&PortName,
FILE_READ_ATTRIBUTES, &FileObject, &PortDeviceObject);
+ if(Status != STATUS_SUCCESS)
+ {
+ DPRINT("Could not open old device object (Status
0x%08lx)\n", Status);
+ return Status;
+ }
+
+ if (DriverExtension->ConnectMultiplePorts)
+ Status = ConnectMousePortDriver(PortDeviceObject,
DriverExtension->MainMouclassDeviceObject);
+ else
+ {
+ /* What to do */
+ KEBUGCHECK(0);
+ }
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ConnectMousePortDriver() failed with status
0x%08lx\n", Status);
+ return Status;
+ }
+ return STATUS_SUCCESS;
+}
+
+/*
+ * Standard DriverEntry method.
+ */
+NTSTATUS NTAPI
+DriverEntry(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath)
+{
+ PMOUCLASS_DRIVER_EXTENSION DriverExtension;
+ ULONG i;
+ NTSTATUS Status;
+
+ Status = IoAllocateDriverObjectExtension(
+ DriverObject,
+ DriverObject,
+ sizeof(MOUCLASS_DRIVER_EXTENSION),
+ (PVOID*)&DriverExtension);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("IoAllocateDriverObjectExtension() failed with
status 0x%08lx\n", Status);
+ return Status;
+ }
+ RtlZeroMemory(DriverExtension,
sizeof(MOUCLASS_DRIVER_EXTENSION));
+
+ Status = ReadRegistryEntries(RegistryPath, DriverExtension);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ReadRegistryEntries() failed with status
0x%08lx\n", Status);
+ return Status;
+ }
+
+ if (DriverExtension->ConnectMultiplePorts == 1)
+ {
+ Status = CreatePointerClassDeviceObject(
+ DriverObject,
+ &DriverExtension->MainMouclassDeviceObject);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("CreatePointerClassDeviceObject() failed
with status 0x%08lx\n", Status);
+ return Status;
+ }
+ }
+
+ DriverObject->DriverExtension->AddDevice = MouclassAddDevice;
+ DriverObject->DriverUnload = DriverUnload;
+
+ for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
+ DriverObject->MajorFunction[i] = IrpStub;
+
+ DriverObject->MajorFunction[IRP_MJ_CREATE] = MouclassCreate;
+ DriverObject->MajorFunction[IRP_MJ_CLOSE] = MouclassClose;
+ DriverObject->MajorFunction[IRP_MJ_READ] = MouclassRead;
+ DriverObject->DriverStartIo = MouclassStartIo;
+
+ SearchForLegacyDrivers(DriverExtension);
+
+ return STATUS_SUCCESS;
+}
_____
Modified: trunk/reactos/drivers/input/mouclass/mouclass.h
--- trunk/reactos/drivers/input/mouclass/mouclass.h 2005-10-31
00:10:32 UTC (rev 18905)
+++ trunk/reactos/drivers/input/mouclass/mouclass.h 2005-10-31
00:14:45 UTC (rev 18906)
@@ -1,11 +1,65 @@
-#define MOUSE_BUFFER_SIZE 100
+#include <ntddk.h>
+#include <kbdmou.h>
+#include <ntddmou.h>
+#include <stdio.h>
-typedef struct _DEVICE_EXTENSION {
- PIO_WORKITEM WorkItem;
- KSPIN_LOCK SpinLock;
- BOOLEAN PassiveCallbackQueued;
- BOOLEAN ReadIsPending;
- ULONG InputCount;
- PMOUSE_INPUT_DATA PortData;
- PDEVICE_OBJECT PortDeviceObject; // FIXME: Expand this to handle
multiple port drivers (make *PortDeviceObject)
-} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
+#if defined(__GNUC__)
+ NTSTATUS NTAPI
+ IoAttachDeviceToDeviceStackSafe(
+ IN PDEVICE_OBJECT SourceDevice,
+ IN PDEVICE_OBJECT TargetDevice,
+ OUT PDEVICE_OBJECT *AttachedToDeviceObject);
+#else
+ #error Unknown compiler!
+#endif
+
+typedef enum
+{
+ dsStopped,
+ dsStarted,
+ dsPaused,
+ dsRemoved,
+ dsSurpriseRemoved
+} MOUCLASS_DEVICE_STATE;
+
+typedef struct _MOUCLASS_DRIVER_EXTENSION
+{
+ /* Registry settings */
+ ULONG ConnectMultiplePorts;
+ ULONG MouseDataQueueSize;
+ UNICODE_STRING PointerDeviceBaseName;
+
+ PDEVICE_OBJECT MainMouclassDeviceObject;
+} MOUCLASS_DRIVER_EXTENSION, *PMOUCLASS_DRIVER_EXTENSION;
+
+typedef struct _COMMON_DEVICE_EXTENSION
+{
+ BOOLEAN IsClassDO;
+} COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION;
+
+typedef struct _MOUPORT_DEVICE_EXTENSION
+{
+ COMMON_DEVICE_EXTENSION Common;
+} MOUPORT_DEVICE_EXTENSION, *PMOUPORT_DEVICE_EXTENSION;
+
+typedef struct _MOUCLASS_DEVICE_EXTENSION
+{
+ COMMON_DEVICE_EXTENSION Common;
+
+ MOUCLASS_DEVICE_STATE PnpState;
+ PMOUCLASS_DRIVER_EXTENSION DriverExtension;
+ PDEVICE_OBJECT LowerDevice;
+ UNICODE_STRING MouseInterfaceName;
+
+ KSPIN_LOCK SpinLock;
+ BOOLEAN ReadIsPending;
+ ULONG InputCount;
+ PMOUSE_INPUT_DATA PortData;
+} MOUCLASS_DEVICE_EXTENSION, *PMOUCLASS_DEVICE_EXTENSION;
+
+/* misc.c */
+
+NTSTATUS NTAPI
+ForwardIrpAndForget(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
_____
Modified: trunk/reactos/drivers/input/mouclass/mouclass.xml
--- trunk/reactos/drivers/input/mouclass/mouclass.xml 2005-10-31
00:10:32 UTC (rev 18905)
+++ trunk/reactos/drivers/input/mouclass/mouclass.xml 2005-10-31
00:14:45 UTC (rev 18906)
@@ -3,6 +3,7 @@
<define name="__USE_W32API" />
<library>ntoskrnl</library>
<library>hal</library>
+ <file>misc.c</file>
<file>mouclass.c</file>
<file>mouclass.rc</file>
</module>
_____
Modified: trunk/reactos/subsys/win32k/ntuser/input.c
--- trunk/reactos/subsys/win32k/ntuser/input.c 2005-10-31 00:10:32 UTC
(rev 18905)
+++ trunk/reactos/subsys/win32k/ntuser/input.c 2005-10-31 00:14:45 UTC
(rev 18906)
@@ -151,7 +151,7 @@
VOID STDCALL
MouseThreadMain(PVOID StartContext)
{
[truncated at 1000 lines; 59 more skipped]