Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendetect.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
1.7.6.1
|