ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

detect.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:     ReactOS Serial mouse driver
00003  * LICENSE:     GPL - See COPYING in the top level directory
00004  * FILE:        drivers/input/sermouse/detect.c
00005  * PURPOSE:     Detect serial mouse type
00006  * PROGRAMMERS: Copyright Jason Filby (jasonfilby@yahoo.com)
00007                 Copyright Filip Navara (xnavara@volny.cz)
00008                 Copyright 2005-2006 Hervé Poussineau (hpoussin@reactos.org)
00009  */
00010 
00011 #include "sermouse.h"
00012 
00013 /* Most of this file is ripped from reactos/drivers/bus/serenum/detect.c */
00014 
00015 static NTSTATUS
00016 DeviceIoControl(
00017     IN PDEVICE_OBJECT DeviceObject,
00018     IN ULONG CtlCode,
00019     IN PVOID InputBuffer OPTIONAL,
00020     IN SIZE_T InputBufferSize,
00021     IN OUT PVOID OutputBuffer OPTIONAL,
00022     IN OUT PSIZE_T OutputBufferSize)
00023 {
00024     KEVENT Event;
00025     PIRP Irp;
00026     IO_STATUS_BLOCK IoStatus;
00027     NTSTATUS Status;
00028 
00029     KeInitializeEvent (&Event, NotificationEvent, FALSE);
00030 
00031     Irp = IoBuildDeviceIoControlRequest(CtlCode,
00032         DeviceObject,
00033         InputBuffer,
00034         (ULONG)InputBufferSize,
00035         OutputBuffer,
00036         (OutputBufferSize) ? (ULONG)*OutputBufferSize : 0,
00037         FALSE,
00038         &Event,
00039         &IoStatus);
00040     if (Irp == NULL)
00041     {
00042         WARN_(SERMOUSE, "IoBuildDeviceIoControlRequest() failed\n");
00043         return STATUS_INSUFFICIENT_RESOURCES;
00044     }
00045 
00046     Status = IoCallDriver(DeviceObject, Irp);
00047 
00048     if (Status == STATUS_PENDING)
00049     {
00050         INFO_(SERMOUSE, "Operation pending\n");
00051         KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
00052         Status = IoStatus.Status;
00053     }
00054 
00055     if (OutputBufferSize)
00056     {
00057         *OutputBufferSize = (SIZE_T)IoStatus.Information;
00058     }
00059 
00060     return Status;
00061 }
00062 
00063 static NTSTATUS
00064 ReadBytes(
00065     IN PDEVICE_OBJECT LowerDevice,
00066     OUT PUCHAR Buffer,
00067     IN ULONG BufferSize,
00068     OUT PULONG_PTR FilledBytes)
00069 {
00070     PIRP Irp;
00071     IO_STATUS_BLOCK ioStatus;
00072     KEVENT event;
00073     LARGE_INTEGER zero;
00074     NTSTATUS Status;
00075 
00076     KeInitializeEvent(&event, NotificationEvent, FALSE);
00077     zero.QuadPart = 0;
00078     Irp = IoBuildSynchronousFsdRequest(
00079         IRP_MJ_READ,
00080         LowerDevice,
00081         Buffer, BufferSize,
00082         &zero,
00083         &event,
00084         &ioStatus);
00085     if (!Irp)
00086         return FALSE;
00087 
00088     Status = IoCallDriver(LowerDevice, Irp);
00089     if (Status == STATUS_PENDING)
00090     {
00091         KeWaitForSingleObject(&event, Suspended, KernelMode, FALSE, NULL);
00092         Status = ioStatus.Status;
00093     }
00094     INFO_(SERMOUSE, "Bytes received: %lu/%lu\n",
00095         ioStatus.Information, BufferSize);
00096     *FilledBytes = ioStatus.Information;
00097     return Status;
00098 }
00099 
00100 static NTSTATUS
00101 Wait(
00102     IN ULONG milliseconds)
00103 {
00104     KTIMER Timer;
00105     LARGE_INTEGER DueTime;
00106 
00107     DueTime.QuadPart = milliseconds * -10;
00108     KeInitializeTimer(&Timer);
00109     KeSetTimer(&Timer, DueTime, NULL);
00110     return KeWaitForSingleObject(&Timer, Executive, KernelMode, FALSE, NULL);
00111 }
00112 
00113 SERMOUSE_MOUSE_TYPE
00114 SermouseDetectLegacyDevice(
00115     IN PDEVICE_OBJECT LowerDevice)
00116 {
00117     HANDLE Handle;
00118     ULONG Fcr, Mcr;
00119     ULONG BaudRate;
00120     ULONG Command;
00121     SERIAL_TIMEOUTS Timeouts;
00122     SERIAL_LINE_CONTROL LCR;
00123     ULONG_PTR i, Count = 0;
00124     UCHAR Buffer[16];
00125     SERMOUSE_MOUSE_TYPE MouseType = mtNone;
00126     NTSTATUS Status;
00127 
00128     TRACE_(SERMOUSE, "SermouseDetectLegacyDevice(LowerDevice %p)\n", LowerDevice);
00129 
00130     RtlZeroMemory(Buffer, sizeof(Buffer));
00131 
00132     /* Open port */
00133     Status = ObOpenObjectByPointer(
00134         LowerDevice,
00135         OBJ_KERNEL_HANDLE,
00136         NULL,
00137         0,
00138         NULL,
00139         KernelMode,
00140         &Handle);
00141     if (!NT_SUCCESS(Status)) return mtNone;
00142 
00143     /* Reset UART */
00144     TRACE_(SERMOUSE, "Reset UART\n");
00145     Mcr = 0; /* MCR: DTR/RTS/OUT2 off */
00146     Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_MODEM_CONTROL,
00147         &Mcr, sizeof(Mcr), NULL, NULL);
00148     if (!NT_SUCCESS(Status)) goto ByeBye;
00149 
00150     /* Set communications parameters */
00151     TRACE_(SERMOUSE, "Set communications parameters\n");
00152     /* DLAB off */
00153     Fcr = 0;
00154     Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_FIFO_CONTROL,
00155         &Fcr, sizeof(Fcr), NULL, NULL);
00156     if (!NT_SUCCESS(Status)) goto ByeBye;
00157     /* Set serial port speed */
00158     BaudRate = 1200;
00159     Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_BAUD_RATE,
00160         &BaudRate, sizeof(BaudRate), NULL, NULL);
00161     if (!NT_SUCCESS(Status)) goto ByeBye;
00162     /* Set LCR */
00163     LCR.WordLength = 7;
00164     LCR.Parity = NO_PARITY;
00165     LCR.StopBits = STOP_BITS_2;
00166     Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_LINE_CONTROL,
00167         &LCR, sizeof(LCR), NULL, NULL);
00168     if (!NT_SUCCESS(Status)) goto ByeBye;
00169 
00170     /* Flush receive buffer */
00171     TRACE_(SERMOUSE, "Flush receive buffer\n");
00172     Command = SERIAL_PURGE_RXCLEAR;
00173     Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_MODEM_CONTROL,
00174         &Command, sizeof(Command), NULL, NULL);
00175     if (!NT_SUCCESS(Status)) goto ByeBye;
00176     /* Wait 100 ms */
00177     Wait(100);
00178 
00179     /* Enable DTR/RTS */
00180     TRACE_(SERMOUSE, "Enable DTR/RTS\n");
00181     Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_DTR,
00182         NULL, 0, NULL, NULL);
00183     if (!NT_SUCCESS(Status)) goto ByeBye;
00184     Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_RTS,
00185         NULL, 0, NULL, NULL);
00186     if (!NT_SUCCESS(Status)) goto ByeBye;
00187 
00188     /* Set timeout to 500 microseconds */
00189     TRACE_(SERMOUSE, "Set timeout to 500 microseconds\n");
00190     Timeouts.ReadIntervalTimeout = 100;
00191     Timeouts.ReadTotalTimeoutMultiplier = 0;
00192     Timeouts.ReadTotalTimeoutConstant = 500;
00193     Timeouts.WriteTotalTimeoutMultiplier = Timeouts.WriteTotalTimeoutConstant = 0;
00194     Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_TIMEOUTS,
00195         &Timeouts, sizeof(Timeouts), NULL, NULL);
00196     if (!NT_SUCCESS(Status)) goto ByeBye;
00197 
00198     /* Fill the read buffer */
00199     TRACE_(SERMOUSE, "Fill the read buffer\n");
00200     Status = ReadBytes(LowerDevice, Buffer, sizeof(Buffer)/sizeof(Buffer[0]), &Count);
00201     if (!NT_SUCCESS(Status)) goto ByeBye;
00202 
00203     for (i = 0; i < Count; i++)
00204     {
00205         if (Buffer[i] == 'B')
00206         {
00207             /* Sign for Microsoft Ballpoint */
00208             ERR_(SERMOUSE, "Microsoft Ballpoint device detected. THIS DEVICE IS NOT YET SUPPORTED");
00209             MouseType = mtNone;
00210             goto ByeBye;
00211         }
00212         else if (Buffer[i] == 'M')
00213         {
00214             /* Sign for Microsoft Mouse protocol followed by button specifier */
00215             if (i == sizeof(Buffer) - 1)
00216             {
00217                 /* Overflow Error */
00218                 goto ByeBye;
00219             }
00220             switch (Buffer[i + 1])
00221             {
00222                 case '3':
00223                     INFO_(SERMOUSE, "Microsoft Mouse with 3-buttons detected\n");
00224                     MouseType = mtLogitech;
00225                     break;
00226                 case 'Z':
00227                     INFO_(SERMOUSE, "Microsoft Wheel Mouse detected\n");
00228                     MouseType = mtWheelZ;
00229                     break;
00230                 default:
00231                     INFO_(SERMOUSE, "Microsoft Mouse with 2-buttons detected\n");
00232                     MouseType = mtMicrosoft;
00233                     break;
00234             }
00235             goto ByeBye;
00236         }
00237     }
00238 
00239 ByeBye:
00240     /* Close port */
00241     if (Handle)
00242         ZwClose(Handle);
00243     return MouseType;
00244 }

Generated on Sat May 26 2012 04:26:31 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.