Added: trunk/reactos/drivers/input/sermouse/
Added: trunk/reactos/drivers/input/sermouse/createclose.c
Added: trunk/reactos/drivers/input/sermouse/detect.c
Added: trunk/reactos/drivers/input/sermouse/fdo.c
Added: trunk/reactos/drivers/input/sermouse/internaldevctl.c
Added: trunk/reactos/drivers/input/sermouse/misc.c
Added: trunk/reactos/drivers/input/sermouse/readmouse.c
Added: trunk/reactos/drivers/input/sermouse/sermouse.c
Added: trunk/reactos/drivers/input/sermouse/sermouse.h
Added: trunk/reactos/drivers/input/sermouse/sermouse.rc
Added: trunk/reactos/drivers/input/sermouse/sermouse.txt
Added: trunk/reactos/drivers/input/sermouse/sermouse.xml
--- trunk/reactos/drivers/input/sermouse/createclose.c 2005-11-09 11:54:53 UTC (rev 19099)
+++ trunk/reactos/drivers/input/sermouse/createclose.c 2005-11-09 11:57:58 UTC (rev 19100)
@@ -0,0 +1,58 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Serial mouse driver
+ * FILE: drivers/input/sermouse/fdo.c
+ * PURPOSE: IRP_MJ_CREATE and IRP_MJ_CLOSE operations
+ *
+ * PROGRAMMERS: HervÚ Poussineau (hpoussin@reactos.org)
+ */
+
+#define NDEBUG
+#include <debug.h>
+
+#include "sermouse.h"
+
+NTSTATUS NTAPI
+SermouseStartDevice(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp); /* FIXME: remove the declaration */
+
+NTSTATUS NTAPI
+SermouseCreate(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ DPRINT("IRP_MJ_CREATE\n");
+ ASSERT(((PSERMOUSE_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->PnpState == dsStarted);
+
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS NTAPI
+SermouseClose(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ DPRINT("IRP_MJ_CLOSE\n");
+
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS NTAPI
+SermouseCleanup(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ DPRINT("IRP_MJ_CLEANUP\n");
+
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+}
Property changes on: trunk/reactos/drivers/input/sermouse/createclose.c
___________________________________________________________________
Name: svn:eol-style
+ native
--- trunk/reactos/drivers/input/sermouse/detect.c 2005-11-09 11:54:53 UTC (rev 19099)
+++ trunk/reactos/drivers/input/sermouse/detect.c 2005-11-09 11:57:58 UTC (rev 19100)
@@ -0,0 +1,282 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Serial mouse driver
+ * FILE: drivers/input/sermouse/detect.c
+ * PURPOSE: Detect serial mouse type
+ *
+ * PROGRAMMERS: Jason Filby (jasonfilby@yahoo.com)
+ * Filip Navara (xnavara@volny.cz)
+ * HervÚ Poussineau (hpoussin@reactos.org)
+ */
+
+#define NDEBUG
+#include <debug.h>
+
+#include "sermouse.h"
+
+/* Most of this file is ripped from reactos/drivers/bus/serenum/detect.c */
+
+static NTSTATUS
+SermouseDeviceIoControl(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN ULONG CtlCode,
+ IN PVOID InputBuffer OPTIONAL,
+ IN ULONG InputBufferSize,
+ IN OUT PVOID OutputBuffer OPTIONAL,
+ IN OUT PULONG OutputBufferSize)
+{
+ KEVENT Event;
+ PIRP Irp;
+ IO_STATUS_BLOCK IoStatus;
+ NTSTATUS Status;
+
+ KeInitializeEvent (&Event, NotificationEvent, FALSE);
+
+ Irp = IoBuildDeviceIoControlRequest(CtlCode,
+ DeviceObject,
+ InputBuffer,
+ InputBufferSize,
+ OutputBuffer,
+ (OutputBufferSize) ? *OutputBufferSize : 0,
+ FALSE,
+ &Event,
+ &IoStatus);
+ if (Irp == NULL)
+ {
+ DPRINT("IoBuildDeviceIoControlRequest() failed\n");
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ Status = IoCallDriver(DeviceObject, Irp);
+
+ if (Status == STATUS_PENDING)
+ {
+ DPRINT("Operation pending\n");
+ KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
+ Status = IoStatus.Status;
+ }
+
+ if (OutputBufferSize)
+ {
+ *OutputBufferSize = IoStatus.Information;
+ }
+
+ return Status;
+}
+
+static NTSTATUS
+SermouseSendIrp(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN ULONG MajorFunction)
+{
+ KEVENT Event;
+ PIRP Irp;
+ IO_STATUS_BLOCK IoStatus;
+ NTSTATUS Status;
+
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
+ Irp = IoBuildSynchronousFsdRequest(
+ MajorFunction,
+ DeviceObject,
+ NULL,
+ 0,
+ NULL,
+ &Event,
+ &IoStatus);
+ if (Irp == NULL)
+ {
+ DPRINT("IoBuildSynchronousFsdRequest() failed\n");
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ Status = IoCallDriver(DeviceObject, Irp);
+
+ if (Status == STATUS_PENDING)
+ {
+ DPRINT("Operation pending\n");
+ KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
+ Status = IoStatus.Status;
+ }
+
+ return Status;
+}
+
+static NTSTATUS
+ReadBytes(
+ IN PDEVICE_OBJECT LowerDevice,
+ OUT PUCHAR Buffer,
+ IN ULONG BufferSize,
+ OUT PULONG FilledBytes)
+{
+ PIRP Irp;
+ IO_STATUS_BLOCK ioStatus;
+ KEVENT event;
+ LARGE_INTEGER zero;
+ NTSTATUS Status;
+
+ KeInitializeEvent(&event, NotificationEvent, FALSE);
+ zero.QuadPart = 0;
+ Irp = IoBuildSynchronousFsdRequest(
+ IRP_MJ_READ,
+ LowerDevice,
+ Buffer, BufferSize,
+ &zero,
+ &event,
+ &ioStatus);
+ if (!Irp)
+ return FALSE;
+
+ Status = IoCallDriver(LowerDevice, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ KeWaitForSingleObject(&event, Suspended, KernelMode, FALSE, NULL);
+ Status = ioStatus.Status;
+ }
+ DPRINT("Bytes received: %lu/%lu\n",
+ ioStatus.Information, BufferSize);
+ *FilledBytes = ioStatus.Information;
+ return Status;
+}
+
+static NTSTATUS
+SermouseWait(ULONG milliseconds)
+{
+ KTIMER Timer;
+ LARGE_INTEGER DueTime;
+
+ DueTime.QuadPart = milliseconds * -10;
+ KeInitializeTimer(&Timer);
+ KeSetTimer(&Timer, DueTime, NULL);
+ return KeWaitForSingleObject(&Timer, Executive, KernelMode, FALSE, NULL);
+}
+
+SERMOUSE_MOUSE_TYPE
+SermouseDetectLegacyDevice(
+ IN PDEVICE_OBJECT LowerDevice)
+{
+ ULONG Fcr, Mcr;
+ ULONG BaudRate;
+ ULONG Command;
+ SERIAL_TIMEOUTS Timeouts;
+ SERIAL_LINE_CONTROL LCR;
+ ULONG i, Count;
+ UCHAR Buffer[16];
+ SERMOUSE_MOUSE_TYPE MouseType = mtNone;
+ NTSTATUS Status;
+
+ RtlZeroMemory(Buffer, sizeof(Buffer));
+
+ /* Open port */
+ Status = SermouseSendIrp(LowerDevice, IRP_MJ_CREATE);
+ if (!NT_SUCCESS(Status)) return mtNone;
+
+ /* Reset UART */
+ CHECKPOINT;
+ Mcr = 0; /* MCR: DTR/RTS/OUT2 off */
+ Status = SermouseDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_MODEM_CONTROL,
+ &Mcr, sizeof(Mcr), NULL, NULL);
+ if (!NT_SUCCESS(Status)) goto ByeBye;
+
+ /* Set communications parameters */
+ CHECKPOINT;
+ /* DLAB off */
+ Fcr = 0;
+ Status = SermouseDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_FIFO_CONTROL,
+ &Fcr, sizeof(Fcr), NULL, NULL);
+ if (!NT_SUCCESS(Status)) goto ByeBye;
+ /* Set serial port speed */
+ BaudRate = SERIAL_BAUD_1200;
+ Status = SermouseDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_BAUD_RATE,
+ &BaudRate, sizeof(BaudRate), NULL, NULL);
+ if (!NT_SUCCESS(Status)) goto ByeBye;
+ /* Set LCR */
+ LCR.WordLength = 7;
+ LCR.Parity = NO_PARITY;
+ LCR.StopBits = STOP_BITS_2;
+ Status = SermouseDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_LINE_CONTROL,
+ &LCR, sizeof(LCR), NULL, NULL);
+ if (!NT_SUCCESS(Status)) goto ByeBye;
+
+ /* Disable DTR/RTS */
+ CHECKPOINT;
+ Status = SermouseDeviceIoControl(LowerDevice, IOCTL_SERIAL_CLR_DTR,
+ NULL, 0, NULL, NULL);
+ if (!NT_SUCCESS(Status)) goto ByeBye;
+ Status = SermouseDeviceIoControl(LowerDevice, IOCTL_SERIAL_CLR_RTS,
+ NULL, 0, NULL, NULL);
+ if (!NT_SUCCESS(Status)) goto ByeBye;
+
+ /* Flush receive buffer */
+ CHECKPOINT;
+ Command = SERIAL_PURGE_RXCLEAR;
+ Status = SermouseDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_MODEM_CONTROL,
+ &Command, sizeof(Command), NULL, NULL);
+ if (!NT_SUCCESS(Status)) goto ByeBye;
+ /* Wait 100 ms */
+ SermouseWait(100);
+
+ /* Enable DTR/RTS */
+ CHECKPOINT;
+ Status = SermouseDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_DTR,
+ NULL, 0, NULL, NULL);
+ if (!NT_SUCCESS(Status)) goto ByeBye;
+ SermouseWait(200);
+ Status = SermouseDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_RTS,
+ NULL, 0, NULL, NULL);
+ if (!NT_SUCCESS(Status)) goto ByeBye;
+
+ /* Set timeout to 500 microseconds */
+ CHECKPOINT;
+ Timeouts.ReadIntervalTimeout = 0;
+ Timeouts.ReadTotalTimeoutMultiplier = 0;
+ Timeouts.ReadTotalTimeoutConstant = 500;
+ Timeouts.WriteTotalTimeoutMultiplier = Timeouts.WriteTotalTimeoutConstant = 0;
+ Status = SermouseDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_TIMEOUTS,
+ &Timeouts, sizeof(Timeouts), NULL, NULL);
+ if (!NT_SUCCESS(Status)) goto ByeBye;
+
+ /* Fill the read buffer */
+ CHECKPOINT;
+ Status = ReadBytes(LowerDevice, Buffer, sizeof(Buffer)/sizeof(Buffer[0]), &Count);
+ if (!NT_SUCCESS(Status)) goto ByeBye;
+
+ for (i = 0; i < Count; i++)
+ {
+ if (Buffer[i] == 'B')
+ {
+ /* Sign for Microsoft Ballpoint */
+ DPRINT1("Microsoft Ballpoint device detected. THIS DEVICE IS NOT YET SUPPORTED");
+ MouseType = mtNone;
+ goto ByeBye;
+ }
+ else if (Buffer[i] == 'M')
+ {
+ /* Sign for Microsoft Mouse protocol followed by button specifier */
+ if (i == sizeof(Buffer) - 1)
+ {
+ /* Overflow Error */
+ goto ByeBye;
+ }
+ switch (Buffer[i + 1])
+ {
+ case '3':
+ DPRINT("Microsoft Mouse with 3-buttons detected\n");
+ MouseType = mtLogitech;
+ case 'Z':
+ DPRINT("Microsoft Wheel Mouse detected\n");
+ MouseType = mtWheelZ;
+ default:
+ DPRINT("Microsoft Mouse with 2-buttons detected\n");
+ MouseType = mtMicrosoft;
+ }
+ goto ByeBye;
+ }
+ }
+
+ByeBye:
+ /* Close port */
+ SermouseSendIrp(LowerDevice, IRP_MJ_CLOSE);
+ SermouseSendIrp(LowerDevice, IRP_MJ_CLEANUP);
+ return MouseType;
+}
Property changes on: trunk/reactos/drivers/input/sermouse/detect.c
___________________________________________________________________
Name: svn:eol-style
+ native
--- trunk/reactos/drivers/input/sermouse/fdo.c 2005-11-09 11:54:53 UTC (rev 19099)
+++ trunk/reactos/drivers/input/sermouse/fdo.c 2005-11-09 11:57:58 UTC (rev 19100)
@@ -0,0 +1,239 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Serial mouse driver
+ * FILE: drivers/input/sermouse/fdo.c
+ * PURPOSE: IRP_MJ_PNP operations for FDOs
+ *
+ * PROGRAMMERS: HervÚ Poussineau (hpoussin@reactos.org)
+ */
+
+#define NDEBUG
+#include <debug.h>
+
+#include "sermouse.h"
+
+NTSTATUS NTAPI
+SermouseAddDevice(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PDEVICE_OBJECT Pdo)
+{
+ PSERMOUSE_DRIVER_EXTENSION DriverExtension;
+ ULONG DeviceId = 0;
+ ULONG PrefixLength;
+ UNICODE_STRING DeviceNameU;
+ PWSTR DeviceIdW = NULL; /* Pointer into DeviceNameU.Buffer */
+ PDEVICE_OBJECT Fdo;
+ PSERMOUSE_DEVICE_EXTENSION DeviceExtension;
+ NTSTATUS Status;
+
+ DPRINT("SermouseAddDevice called. Pdo = 0x%p\n", Pdo);
+
+ /* Create new device object */
+ DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
+ DeviceNameU.Length = 0;
+ DeviceNameU.MaximumLength =
+ wcslen(L"\\Device\\") * sizeof(WCHAR) /* "\Device\" */
+ + DriverExtension->PointerDeviceBaseName.Length /* "PointerPort" */
+ + 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"%lu", DeviceId) * sizeof(WCHAR);
+ Status = IoCreateDevice(
+ DriverObject,
+ sizeof(SERMOUSE_DEVICE_EXTENSION),
+ &DeviceNameU,
+ FILE_DEVICE_SERIAL_MOUSE_PORT,
+ FILE_DEVICE_SECURE_OPEN,
+ TRUE,
+ &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:
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePool(DeviceNameU.Buffer);
+ return Status;
+ }
+
+ DeviceExtension = (PSERMOUSE_DEVICE_EXTENSION)Fdo->DeviceExtension;
+ RtlZeroMemory(DeviceExtension, sizeof(SERMOUSE_DEVICE_EXTENSION));
+ DeviceExtension->MouseType = mtNone;
+ DeviceExtension->PnpState = dsStopped;
+ DeviceExtension->DriverExtension = DriverExtension;
+ KeInitializeEvent(&DeviceExtension->StopWorkerThreadEvent, NotificationEvent, FALSE);
+ DeviceExtension->MouseInputData[0] = ExAllocatePool(NonPagedPool, DeviceExtension->DriverExtension->MouseDataQueueSize * sizeof(MOUSE_INPUT_DATA));
+ if (!DeviceExtension->MouseInputData[0])
+ {
+ DPRINT("ExAllocatePool() failed\n");
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto cleanupFDO;
+ }
+ DeviceExtension->MouseInputData[1] = ExAllocatePool(NonPagedPool, DeviceExtension->DriverExtension->MouseDataQueueSize * sizeof(MOUSE_INPUT_DATA));
+ if (!DeviceExtension->MouseInputData[1])
+ {
+ DPRINT("ExAllocatePool() failed\n");
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto cleanupFDO;
+ }
+ Fdo->Flags |= DO_POWER_PAGABLE;
+ Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
+ goto cleanupFDO;
+ }
+ Fdo->Flags |= DO_BUFFERED_IO;
+ Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
+
+ /* FIXME: create registry entry in HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP */
+
+ ExFreePool(DeviceNameU.Buffer);
+
+ return STATUS_SUCCESS;
+
+cleanupFDO:
+ if (DeviceExtension)
+ {
+ ExFreePool(DeviceExtension->MouseInputData[0]);
+ ExFreePool(DeviceExtension->MouseInputData[1]);
+ }
+ if (Fdo)
+ {
+ IoDeleteDevice(Fdo);
+ }
+ return Status;
+}
+
+NTSTATUS NTAPI
+SermouseStartDevice(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PSERMOUSE_DEVICE_EXTENSION DeviceExtension;
+ SERMOUSE_MOUSE_TYPE MouseType;
+
+ DeviceExtension = (PSERMOUSE_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+ ASSERT(DeviceExtension->PnpState == dsStopped);
+ ASSERT(DeviceExtension->LowerDevice);
+ MouseType = SermouseDetectLegacyDevice(DeviceExtension->LowerDevice);
+ if (MouseType == mtNone)
+ {
+ DPRINT("No mouse connected to Fdo %p\n",
+ DeviceExtension->LowerDevice);
+ return STATUS_DEVICE_NOT_CONNECTED;
+ }
+
+ switch (MouseType)
+ {
+ case mtMicrosoft:
+ DeviceExtension->AttributesInformation.MouseIdentifier = MOUSE_SERIAL_HARDWARE;
+ DeviceExtension->AttributesInformation.NumberOfButtons = 2;
+ break;
+ case mtLogitech:
+ DeviceExtension->AttributesInformation.MouseIdentifier = MOUSE_SERIAL_HARDWARE;
+ DeviceExtension->AttributesInformation.NumberOfButtons = 3;
+ break;
+ case mtWheelZ:
+ DeviceExtension->AttributesInformation.MouseIdentifier = WHEELMOUSE_SERIAL_HARDWARE;
+ DeviceExtension->AttributesInformation.NumberOfButtons = 3;
+ break;
+ default:
+ CHECKPOINT;
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ if (DeviceExtension->DriverExtension->NumberOfButtons != 0)
+ /* Override the number of buttons */
+ DeviceExtension->AttributesInformation.NumberOfButtons = DeviceExtension->DriverExtension->NumberOfButtons;
+
+ DeviceExtension->AttributesInformation.SampleRate = 1200 / 8;
+ DeviceExtension->AttributesInformation.InputDataQueueLength = DeviceExtension->DriverExtension->MouseDataQueueSize;
+ DeviceExtension->MouseType = MouseType;
+ DeviceExtension->PnpState = dsStarted;
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS NTAPI
+SermousePnp(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ ULONG MinorFunction;
+ PIO_STACK_LOCATION Stack;
+ ULONG Information = 0;
+ NTSTATUS Status;
+
+ Stack = IoGetCurrentIrpStackLocation(Irp);
+ MinorFunction = Stack->MinorFunction;
+
+ switch (MinorFunction)
+ {
+ /* FIXME: do all these minor functions
+ IRP_MN_QUERY_REMOVE_DEVICE 0x1
+ IRP_MN_REMOVE_DEVICE 0x2
+ IRP_MN_CANCEL_REMOVE_DEVICE 0x3
+ IRP_MN_STOP_DEVICE 0x4
+ IRP_MN_QUERY_STOP_DEVICE 0x5
+ IRP_MN_CANCEL_STOP_DEVICE 0x6
+ IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations (optional) 0x7
+ IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations (optional) 0x7
+ IRP_MN_QUERY_INTERFACE (optional) 0x8
+ IRP_MN_QUERY_CAPABILITIES (optional) 0x9
+ IRP_MN_FILTER_RESOURCE_REQUIREMENTS (optional or required) 0xd
+ IRP_MN_QUERY_PNP_DEVICE_STATE (optional) 0x14
+ IRP_MN_DEVICE_USAGE_NOTIFICATION (required or optional) 0x16
+ IRP_MN_SURPRISE_REMOVAL 0x17
+ */
+ case IRP_MN_START_DEVICE: /* 0x0 */
+ {
+ DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
+ /* Call lower driver */
+ Status = ForwardIrpAndWait(DeviceObject, Irp);
+ if (NT_SUCCESS(Status))
+ Status = SermouseStartDevice(DeviceObject, Irp);
+ break;
+ }
+ default:
+ {
+ DPRINT1("IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction);
+ return ForwardIrpAndForget(DeviceObject, Irp);
+ }
+ }
+
+ Irp->IoStatus.Information = Information;
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return Status;
+}
Property changes on: trunk/reactos/drivers/input/sermouse/fdo.c
___________________________________________________________________
Name: svn:eol-style
+ native
--- trunk/reactos/drivers/input/sermouse/internaldevctl.c 2005-11-09 11:54:53 UTC (rev 19099)
+++ trunk/reactos/drivers/input/sermouse/internaldevctl.c 2005-11-09 11:57:58 UTC (rev 19100)
@@ -0,0 +1,89 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Serial mouse driver
+ * FILE: drivers/input/sermouse/internaldevctl.c
+ * PURPOSE: IRP_MJ_INTERNAL_DEVICE_CONTROL operations
+ *
+ * PROGRAMMERS: HervÚ Poussineau (hpoussin@reactos.org)
+ */
+
+#define NDEBUG
+#include <debug.h>
+
+#include "sermouse.h"
+
+NTSTATUS NTAPI
+SermouseInternalDeviceControl(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PSERMOUSE_DEVICE_EXTENSION DeviceExtension;
+ PIO_STACK_LOCATION Stack;
+ NTSTATUS Status;
+
+ DeviceExtension = (PSERMOUSE_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ Stack = IoGetCurrentIrpStackLocation(Irp);
+
+ switch (Stack->Parameters.DeviceIoControl.IoControlCode)
+ {
+ case IOCTL_INTERNAL_MOUSE_CONNECT:
+ {
+ DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_MOUSE_CONNECT\n");
+ DeviceExtension->ConnectData =
+ *((PCONNECT_DATA)Stack->Parameters.DeviceIoControl.Type3InputBuffer);
+
+ /* Start read loop */
+ Status = PsCreateSystemThread(
+ &DeviceExtension->WorkerThreadHandle,
+ (ACCESS_MASK)0L,
+ NULL,
+ NULL,
+ NULL,
+ SermouseDeviceWorker,
+ DeviceObject);
+ break;
+ }
+ case IOCTL_INTERNAL_MOUSE_DISCONNECT:
+ {
+ DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_MOUSE_DISCONNECT\n");
+
+ /* Ask read loop to end */
+ KeSetEvent(&DeviceExtension->StopWorkerThreadEvent, (KPRIORITY)0, FALSE);
+ break;
+ }
+ case IOCTL_MOUSE_QUERY_ATTRIBUTES:
+ {
+ DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_MOUSE_QUERY_ATTRIBUTES\n");
+ if (Stack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(MOUSE_ATTRIBUTES))
+ {
+ *(PMOUSE_ATTRIBUTES)Irp->AssociatedIrp.SystemBuffer =
+ DeviceExtension->AttributesInformation;
+ Irp->IoStatus.Information = sizeof(MOUSE_ATTRIBUTES);
+ Status = STATUS_SUCCESS;
+ } else {
+ Status = STATUS_BUFFER_TOO_SMALL;
+ }
+ break;
+ }
+ default:
+ {
+ DPRINT1("IRP_MJ_INTERNAL_DEVICE_CONTROL / unknown ioctl code 0x%lx\n",
+ Stack->Parameters.DeviceIoControl.IoControlCode);
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ break;
+ }
+ }
+
+ Irp->IoStatus.Status = Status;
+ if (Status == STATUS_PENDING)
+ {
+ IoMarkIrpPending(Irp);
+ IoStartPacket(DeviceObject, Irp, NULL, NULL);
+ }
+ else
+ {
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ }
+
+ return Status;
+}
Property changes on: trunk/reactos/drivers/input/sermouse/internaldevctl.c
___________________________________________________________________
Name: svn:eol-style
+ native
--- trunk/reactos/drivers/input/sermouse/misc.c 2005-11-09 11:54:53 UTC (rev 19099)
+++ trunk/reactos/drivers/input/sermouse/misc.c 2005-11-09 11:57:58 UTC (rev 19100)
@@ -0,0 +1,61 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Serial mouse driver
+ * FILE: drivers/input/sermouse/misc.c
+ * PURPOSE: Misceallenous operations
+ *
+ * PROGRAMMERS: HervÚ Poussineau (hpoussin@reactos.org)
+ */
+
+#define NDEBUG
+#include <debug.h>
+
+#include "sermouse.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 = ((PSERMOUSE_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 = ((PSERMOUSE_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
+
+ IoSkipCurrentIrpStackLocation(Irp);
+ return IoCallDriver(LowerDevice, Irp);
+}
Property changes on: trunk/reactos/drivers/input/sermouse/misc.c
___________________________________________________________________
Name: svn:eol-style
+ native
--- trunk/reactos/drivers/input/sermouse/readmouse.c 2005-11-09 11:54:53 UTC (rev 19099)
+++ trunk/reactos/drivers/input/sermouse/readmouse.c 2005-11-09 11:57:58 UTC (rev 19100)
@@ -0,0 +1,277 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Serial mouse driver
+ * FILE: drivers/input/sermouse/readmouse.c
+ * PURPOSE: Read mouse moves and send them to mouclass
+ *
+ * PROGRAMMERS: Jason Filby (jasonfilby@yahoo.com)
+ * Filip Navara (xnavara@volny.cz)
+ * HervÚ Poussineau (hpoussin@reactos.org)
+ */
+
+#define NDEBUG
+#include <debug.h>
+
+#include "sermouse.h"
+
+static NTSTATUS
+SermouseDeviceIoControl(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN ULONG CtlCode,
+ IN PVOID InputBuffer OPTIONAL,
+ IN ULONG InputBufferSize,
+ IN OUT PVOID OutputBuffer OPTIONAL,
+ IN OUT PULONG OutputBufferSize)
+{
+ KEVENT Event;
+ PIRP Irp;
+ IO_STATUS_BLOCK IoStatus;
+ NTSTATUS Status;
+
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
+ Irp = IoBuildDeviceIoControlRequest(CtlCode,
+ DeviceObject,
+ InputBuffer,
+ InputBufferSize,
+ OutputBuffer,
+ (OutputBufferSize) ? *OutputBufferSize : 0,
+ FALSE,
+ &Event,
+ &IoStatus);
+ if (Irp == NULL)
+ {
+ DPRINT("IoBuildDeviceIoControlRequest() failed\n");
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ Status = IoCallDriver(DeviceObject, Irp);
+
+ if (Status == STATUS_PENDING)
+ {
+ DPRINT("Operation pending\n");
+ KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
+ Status = IoStatus.Status;
+ }
+
+ if (OutputBufferSize)
+ {
+ *OutputBufferSize = IoStatus.Information;
+ }
+
+ return Status;
+}
+
+VOID NTAPI
+SermouseDeviceWorker(
+ PVOID Context)
+{
+ PSERMOUSE_DEVICE_EXTENSION DeviceExtension;
+ PDEVICE_OBJECT LowerDevice;
+ UCHAR Buffer[PACKET_BUFFER_SIZE];
+ PIRP Irp;
+ IO_STATUS_BLOCK ioStatus;
+ KEVENT event;
+ PUCHAR PacketBuffer;
+ UCHAR ReceivedByte;
+ ULONG Queue;
+ PMOUSE_INPUT_DATA Input;
+ ULONG ButtonsDifference;
+ KIRQL OldIrql;
+ ULONG i;
+ ULONG Fcr;
+ ULONG BaudRate;
+ SERIAL_TIMEOUTS Timeouts;
+ SERIAL_LINE_CONTROL LCR;
+ LARGE_INTEGER Zero;
+ NTSTATUS Status;
+
+ DPRINT("SermouseDeviceWorker() called\n");
+
+ DeviceExtension = (PSERMOUSE_DEVICE_EXTENSION)((PDEVICE_OBJECT)Context)->DeviceExtension;
+ LowerDevice = DeviceExtension->LowerDevice;
+ Zero.QuadPart = 0;
+ PacketBuffer = DeviceExtension->PacketBuffer;
+
+ ASSERT(LowerDevice);
+
+ /* Initialize device extension */
+ DeviceExtension->ActiveQueue = 0;
+ DeviceExtension->PacketBufferPosition = 0;
+ DeviceExtension->PreviousButtons = 0;
+
+ /* Initialize serial port */
+ Fcr = 0;
+ Status = SermouseDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_FIFO_CONTROL,
+ &Fcr, sizeof(Fcr), NULL, NULL);
+ if (!NT_SUCCESS(Status)) PsTerminateSystemThread(Status);
+ /* Set serial port speed */
+ BaudRate = DeviceExtension->DriverExtension->SampleRate;
+ Status = SermouseDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_BAUD_RATE,
+ &BaudRate, sizeof(BaudRate), NULL, NULL);
+ if (!NT_SUCCESS(Status)) PsTerminateSystemThread(Status);
+ /* Set LCR */
+ LCR.WordLength = 7;
+ LCR.Parity = NO_PARITY;
+ LCR.StopBits = STOP_BIT_1;
+ Status = SermouseDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_LINE_CONTROL,
+ &LCR, sizeof(LCR), NULL, NULL);
+ if (!NT_SUCCESS(Status)) PsTerminateSystemThread(Status);
+
+ /* Set timeouts */
+ Timeouts.ReadTotalTimeoutConstant = Timeouts.ReadTotalTimeoutMultiplier = 0;
+ Timeouts.ReadIntervalTimeout = 100;
+ Timeouts.WriteTotalTimeoutMultiplier = Timeouts.WriteTotalTimeoutConstant = 0;
+ Status = SermouseDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_TIMEOUTS,
+ &Timeouts, sizeof(Timeouts), NULL, NULL);
+ if (!NT_SUCCESS(Status)) PsTerminateSystemThread(Status);
+
+ /* main read loop */
+ while (TRUE)
+ {
+ Status = KeWaitForSingleObject(
+ &DeviceExtension->StopWorkerThreadEvent,
+ Executive,
+ KernelMode,
+ TRUE,
+ &Zero);
+ if (Status != STATUS_TIMEOUT)
+ {
+ /* we need to stop the worker thread */
+ KeResetEvent(&DeviceExtension->StopWorkerThreadEvent);
+ break;
+ }
+
+ KeInitializeEvent(&event, NotificationEvent, FALSE);
+ Irp = IoBuildSynchronousFsdRequest(
+ IRP_MJ_READ,
+ LowerDevice,
+ Buffer, PACKET_BUFFER_SIZE,
+ &Zero,
+ &event,
+ &ioStatus);
+ if (!Irp)
+ {
+ /* no memory actually, try later */
+ CHECKPOINT;
+ KeStallExecutionProcessor(10);
+ continue;
+ }
+
+ Status = IoCallDriver(LowerDevice, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ KeWaitForSingleObject(&event, Suspended, KernelMode, FALSE, NULL);
+ Status = ioStatus.Status;
+ }
+
+ if (!NT_SUCCESS(Status))
+ continue;
+
+ /* Read all available data and process */
+ for (i = 0; i < ioStatus.Information; i++)
+ {
+ ReceivedByte = Buffer[i];
+ DPRINT1("ReceivedByte 0x%02x\n", ReceivedByte);
+
+ /* Synchronize */
+ if ((ReceivedByte & 0x40) == 0x40)
+ DeviceExtension->PacketBufferPosition = 0;
+
+ PacketBuffer[DeviceExtension->PacketBufferPosition] = ReceivedByte & 0x7f;
+ DeviceExtension->PacketBufferPosition++;
+
+ /* Process packet if complete */
+ if (DeviceExtension->PacketBufferPosition >= 3)
+ {
+ Queue = DeviceExtension->ActiveQueue % 2;
+
+ /* Prevent buffer overflow */
+ if (DeviceExtension->InputDataCount[Queue] == DeviceExtension->DriverExtension->MouseDataQueueSize)
+ continue;
+
+ Input = &DeviceExtension->MouseInputData[Queue][DeviceExtension->InputDataCount[Queue]];
+
+ if (DeviceExtension->PacketBufferPosition == 3)
+ {
+ /* Retrieve change in x and y from packet */
+ Input->LastX = (signed char)(PacketBuffer[1] | ((PacketBuffer[0] & 0x03) << 6));
+ Input->LastY = (signed char)(PacketBuffer[2] | ((PacketBuffer[0] & 0x0c) << 4));
+
+ /* Determine the current state of the buttons */
+ Input->RawButtons = (DeviceExtension->PreviousButtons & MOUSE_BUTTON_MIDDLE) |
+ ((UCHAR)(PacketBuffer[0] & LEFT_BUTTON_MASK) >> LEFT_BUTTON_SHIFT) |
+ ((UCHAR)(PacketBuffer[0] & RIGHT_BUTTON_MASK) >> RIGHT_BUTTON_SHIFT);
+ }
+ else if (DeviceExtension->PacketBufferPosition == 4)
+ {
+ DeviceExtension->PacketBufferPosition = 0;
+ /* If middle button state changed than report event */
+ if (((UCHAR)(PacketBuffer[3] & MIDDLE_BUTTON_MASK) >> MIDDLE_BUTTON_SHIFT) ^
+ (DeviceExtension->PreviousButtons & MOUSE_BUTTON_MIDDLE))
+ {
+ Input->RawButtons ^= MOUSE_BUTTON_MIDDLE;
+ Input->LastX = 0;
+ Input->LastY = 0;
+ }
+ else
+ {
+ continue;
+ }
+ }
[truncated at 1000 lines; 526 more skipped]