ReactOS  0.4.13-dev-100-gc8611ae
detect.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Serial mouse driver
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: drivers/input/sermouse/detect.c
5  * PURPOSE: Detect serial mouse type
6  * PROGRAMMERS: Copyright Jason Filby (jasonfilby@yahoo.com)
7  Copyright Filip Navara (xnavara@volny.cz)
8  Copyright 2005-2006 Hervé Poussineau (hpoussin@reactos.org)
9  */
10 
11 #include "sermouse.h"
12 
13 #include <ntifs.h>
14 #include <debug.h>
15 
16 /* Most of this file is ripped from reactos/drivers/bus/serenum/detect.c */
17 
18 static NTSTATUS
21  IN ULONG CtlCode,
23  IN SIZE_T InputBufferSize,
25  IN OUT PSIZE_T OutputBufferSize)
26 {
27  KEVENT Event;
28  PIRP Irp;
31 
33 
37  (ULONG)InputBufferSize,
39  (OutputBufferSize) ? (ULONG)*OutputBufferSize : 0,
40  FALSE,
41  &Event,
42  &IoStatus);
43  if (Irp == NULL)
44  {
45  WARN_(SERMOUSE, "IoBuildDeviceIoControlRequest() failed\n");
47  }
48 
50 
51  if (Status == STATUS_PENDING)
52  {
53  INFO_(SERMOUSE, "Operation pending\n");
55  Status = IoStatus.Status;
56  }
57 
58  if (OutputBufferSize)
59  {
60  *OutputBufferSize = (SIZE_T)IoStatus.Information;
61  }
62 
63  return Status;
64 }
65 
66 static NTSTATUS
68  IN PDEVICE_OBJECT LowerDevice,
71  OUT PULONG_PTR FilledBytes)
72 {
73  PIRP Irp;
74  IO_STATUS_BLOCK ioStatus;
75  KEVENT event;
78 
80  zero.QuadPart = 0;
83  LowerDevice,
85  &zero,
86  &event,
87  &ioStatus);
88  if (!Irp)
89  return FALSE;
90 
91  Status = IoCallDriver(LowerDevice, Irp);
92  if (Status == STATUS_PENDING)
93  {
95  Status = ioStatus.Status;
96  }
97  INFO_(SERMOUSE, "Bytes received: %lu/%lu\n",
98  ioStatus.Information, BufferSize);
99  *FilledBytes = ioStatus.Information;
100  return Status;
101 }
102 
103 static NTSTATUS
105  IN ULONG milliseconds)
106 {
107  KTIMER Timer;
109 
110  DueTime.QuadPart = milliseconds * -10;
114 }
115 
118  IN PDEVICE_OBJECT LowerDevice)
119 {
120  HANDLE Handle;
121  ULONG Fcr, Mcr;
122  ULONG BaudRate;
123  ULONG Command;
124  SERIAL_TIMEOUTS Timeouts;
126  ULONG_PTR i, Count = 0;
127  UCHAR Buffer[16];
128  SERMOUSE_MOUSE_TYPE MouseType = mtNone;
130 
131  TRACE_(SERMOUSE, "SermouseDetectLegacyDevice(LowerDevice %p)\n", LowerDevice);
132 
133  RtlZeroMemory(Buffer, sizeof(Buffer));
134 
135  /* Open port */
137  LowerDevice,
139  NULL,
140  0,
141  NULL,
142  KernelMode,
143  &Handle);
144  if (!NT_SUCCESS(Status)) return mtNone;
145 
146  /* Reset UART */
147  TRACE_(SERMOUSE, "Reset UART\n");
148  Mcr = 0; /* MCR: DTR/RTS/OUT2 off */
150  &Mcr, sizeof(Mcr), NULL, NULL);
151  if (!NT_SUCCESS(Status)) goto ByeBye;
152 
153  /* Set communications parameters */
154  TRACE_(SERMOUSE, "Set communications parameters\n");
155  /* DLAB off */
156  Fcr = 0;
158  &Fcr, sizeof(Fcr), NULL, NULL);
159  if (!NT_SUCCESS(Status)) goto ByeBye;
160  /* Set serial port speed */
161  BaudRate = 1200;
163  &BaudRate, sizeof(BaudRate), NULL, NULL);
164  if (!NT_SUCCESS(Status)) goto ByeBye;
165  /* Set LCR */
166  LCR.WordLength = 7;
167  LCR.Parity = NO_PARITY;
168  LCR.StopBits = STOP_BITS_2;
170  &LCR, sizeof(LCR), NULL, NULL);
171  if (!NT_SUCCESS(Status)) goto ByeBye;
172 
173  /* Flush receive buffer */
174  TRACE_(SERMOUSE, "Flush receive buffer\n");
177  &Command, sizeof(Command), NULL, NULL);
178  if (!NT_SUCCESS(Status)) goto ByeBye;
179  /* Wait 100 ms */
180  Wait(100);
181 
182  /* Enable DTR/RTS */
183  TRACE_(SERMOUSE, "Enable DTR/RTS\n");
185  NULL, 0, NULL, NULL);
186  if (!NT_SUCCESS(Status)) goto ByeBye;
188  NULL, 0, NULL, NULL);
189  if (!NT_SUCCESS(Status)) goto ByeBye;
190 
191  /* Set timeout to 500 microseconds */
192  TRACE_(SERMOUSE, "Set timeout to 500 microseconds\n");
193  Timeouts.ReadIntervalTimeout = 100;
194  Timeouts.ReadTotalTimeoutMultiplier = 0;
195  Timeouts.ReadTotalTimeoutConstant = 500;
198  &Timeouts, sizeof(Timeouts), NULL, NULL);
199  if (!NT_SUCCESS(Status)) goto ByeBye;
200 
201  /* Fill the read buffer */
202  TRACE_(SERMOUSE, "Fill the read buffer\n");
203  Status = ReadBytes(LowerDevice, Buffer, sizeof(Buffer)/sizeof(Buffer[0]), &Count);
204  if (!NT_SUCCESS(Status)) goto ByeBye;
205 
206  for (i = 0; i < Count; i++)
207  {
208  if (Buffer[i] == 'B')
209  {
210  /* Sign for Microsoft Ballpoint */
211  ERR_(SERMOUSE, "Microsoft Ballpoint device detected. THIS DEVICE IS NOT YET SUPPORTED");
212  MouseType = mtNone;
213  goto ByeBye;
214  }
215  else if (Buffer[i] == 'M')
216  {
217  /* Sign for Microsoft Mouse protocol followed by button specifier */
218  if (i == sizeof(Buffer) - 1)
219  {
220  /* Overflow Error */
221  goto ByeBye;
222  }
223  switch (Buffer[i + 1])
224  {
225  case '3':
226  INFO_(SERMOUSE, "Microsoft Mouse with 3-buttons detected\n");
227  MouseType = mtLogitech;
228  break;
229  case 'Z':
230  INFO_(SERMOUSE, "Microsoft Wheel Mouse detected\n");
231  MouseType = mtWheelZ;
232  break;
233  default:
234  INFO_(SERMOUSE, "Microsoft Mouse with 2-buttons detected\n");
235  MouseType = mtMicrosoft;
236  break;
237  }
238  goto ByeBye;
239  }
240  }
241 
242 ByeBye:
243  /* Close port */
244  if (Handle)
245  ZwClose(Handle);
246  return MouseType;
247 }
#define SERIAL_PURGE_RXCLEAR
Definition: serial.c:96
#define IN
Definition: typedefs.h:38
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:281
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define INFO_(ch,...)
Definition: debug.h:159
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2650
PIRP NTAPI IoBuildSynchronousFsdRequest(IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER StartingOffset, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:1069
#define IOCTL_SERIAL_SET_BAUD_RATE
Definition: ntddser.h:82
ULONG WriteTotalTimeoutConstant
Definition: ntddser.h:307
SERMOUSE_MOUSE_TYPE
Definition: sermouse.h:19
_In_ PIRP Irp
Definition: csq.h:116
_In_ LARGE_INTEGER DueTime
Definition: kefuncs.h:524
#define IOCTL_SERIAL_SET_FIFO_CONTROL
Definition: ntddser.h:92
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
unsigned char * PUCHAR
Definition: retypes.h:3
ULONG ReadTotalTimeoutConstant
Definition: ntddser.h:305
#define ERR_(ch,...)
Definition: debug.h:156
LONG NTSTATUS
Definition: precomp.h:26
SERMOUSE_MOUSE_TYPE SermouseDetectLegacyDevice(IN PDEVICE_OBJECT LowerDevice)
Definition: detect.c:117
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
Definition: shell.h:41
NTSTATUS NTAPI ObOpenObjectByPointer(IN PVOID Object, IN ULONG HandleAttributes, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PHANDLE Handle)
Definition: obhandle.c:2739
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
CHAR InputBuffer[80]
Definition: conmgr.c:33
#define IOCTL_SERIAL_SET_LINE_CONTROL
Definition: ntddser.h:96
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define IOCTL_SERIAL_SET_DTR
Definition: ntddser.h:90
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
ULONG_PTR * PSIZE_T
Definition: typedefs.h:78
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:434
ULONG ReadTotalTimeoutMultiplier
Definition: ntddser.h:304
smooth NULL
Definition: ftsmooth.c:416
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
Definition: bufpool.h:45
_Must_inspect_result_ __drv_aliasesMem _In_ PDEVICE_OBJECT _In_opt_ PVOID _In_ ULONG _Out_opt_ PVOID OutputBuffer
Definition: iofuncs.h:713
static NTSTATUS ReadBytes(IN PDEVICE_OBJECT LowerDevice, OUT PUCHAR Buffer, IN ULONG BufferSize, OUT PULONG_PTR FilledBytes)
Definition: detect.c:67
#define TRACE_(x)
Definition: compat.h:66
_In_ HANDLE Handle
Definition: extypes.h:390
ULONG WriteTotalTimeoutMultiplier
Definition: ntddser.h:306
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
struct Command Command
ULONG ReadIntervalTimeout
Definition: ntddser.h:303
#define BufferSize
Definition: classpnp.h:419
#define LCR
Definition: serial_port.h:65
#define STOP_BITS_2
Definition: serial.c:87
unsigned char UCHAR
Definition: xmlstorage.h:181
static double zero
Definition: j0_y0.c:96
static NTSTATUS DeviceIoControl(IN PDEVICE_OBJECT DeviceObject, IN ULONG CtlCode, IN PVOID InputBuffer OPTIONAL, IN SIZE_T InputBufferSize, IN OUT PVOID OutputBuffer OPTIONAL, IN OUT PSIZE_T OutputBufferSize)
Definition: detect.c:19
struct _cl_event * event
Definition: glext.h:7739
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
ULONG_PTR SIZE_T
Definition: typedefs.h:78
UINT Timer
Definition: capclock.c:11
#define NO_PARITY
Definition: serial.c:89
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define IOCTL_SERIAL_SET_MODEM_CONTROL
Definition: ntddser.h:98
static NTSTATUS Wait(IN ULONG milliseconds)
Definition: detect.c:104
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
uint32_t * PULONG_PTR
Definition: typedefs.h:63
#define IOCTL_SERIAL_SET_RTS
Definition: ntddser.h:102
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define WARN_(ch,...)
Definition: debug.h:157
#define IOCTL_SERIAL_SET_TIMEOUTS
Definition: ntddser.h:104
LONGLONG QuadPart
Definition: typedefs.h:112
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68