ReactOS  0.4.14-dev-991-g696cdc6
mouse.c File Reference
#include "i8042prt.h"
#include <debug.h>
Include dependency graph for mouse.c:

Go to the source code of this file.

Functions

static VOID NTAPI i8042MouIsrWritePort (IN PVOID Context, IN UCHAR Value)
 
static VOID NTAPI i8042MouQueuePacket (IN PVOID Context)
 
VOID i8042MouHandle (IN PI8042_MOUSE_EXTENSION DeviceExtension, IN UCHAR Output)
 
VOID i8042MouHandleButtons (IN PI8042_MOUSE_EXTENSION DeviceExtension, IN USHORT Mask)
 
NTSTATUS i8042MouInitialize (IN PI8042_MOUSE_EXTENSION DeviceExtension)
 
static VOID NTAPI i8042MouDpcRoutine (IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
 
static VOID NTAPI i8042DpcRoutineMouseTimeout (IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
 
NTSTATUS NTAPI i8042MouInternalDeviceControl (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
static VOID i8042MouInputTestTimeout (IN PI8042_MOUSE_EXTENSION DeviceExtension)
 
static BOOLEAN i8042MouCallIsrHook (IN PI8042_MOUSE_EXTENSION DeviceExtension, IN UCHAR Status, IN UCHAR Input, OUT PBOOLEAN ToReturn)
 
static BOOLEAN i8042MouResetIsr (IN PI8042_MOUSE_EXTENSION DeviceExtension, IN UCHAR Status, IN UCHAR Value)
 
BOOLEAN NTAPI i8042MouInterruptService (IN PKINTERRUPT Interrupt, PVOID Context)
 

Variables

static KDEFERRED_ROUTINE i8042MouDpcRoutine
 
static KDEFERRED_ROUTINE i8042DpcRoutineMouseTimeout
 

Function Documentation

◆ i8042DpcRoutineMouseTimeout()

static VOID NTAPI i8042DpcRoutineMouseTimeout ( IN PKDPC  Dpc,
IN PVOID  DeferredContext,
IN PVOID  SystemArgument1,
IN PVOID  SystemArgument2 
)
static

Definition at line 351 of file mouse.c.

356 {
357  PI8042_MOUSE_EXTENSION DeviceExtension;
358  PPORT_DEVICE_EXTENSION PortDeviceExtension;
359  KIRQL Irql;
360 
364 
366  DeviceExtension = DeferredContext;
367  PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension;
368 
369  Irql = KeAcquireInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt);
370 
371  WARN_(I8042PRT, "Mouse initialization timeout! (substate %x)\n",
372  DeviceExtension->MouseResetState);
373 
374  PortDeviceExtension->Flags &= ~MOUSE_PRESENT;
375 
377 }
#define MOUSE_PRESENT
Definition: i8042prt.h:72
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
PKINTERRUPT HighestDIRQLInterrupt
Definition: i8042prt.h:88
_Out_ PKIRQL Irql
Definition: csq.h:179
UCHAR KIRQL
Definition: env_spec_w32.h:591
VOID NTAPI KeReleaseInterruptSpinLock(IN PKINTERRUPT Interrupt, IN KIRQL OldIrql)
Definition: spinlock.c:165
#define __analysis_assume(expr)
Definition: sal.h:2893
smooth NULL
Definition: ftsmooth.c:416
FDO_DEVICE_EXTENSION Common
Definition: i8042prt.h:177
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:675
_In_ LARGE_INTEGER _In_opt_ PKDPC Dpc
Definition: kefuncs.h:511
KIRQL NTAPI KeAcquireInterruptSpinLock(IN PKINTERRUPT Interrupt)
Definition: spinlock.c:148
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:675
MOUSE_RESET_SUBSTATE MouseResetState
Definition: i8042prt.h:186
#define WARN_(ch,...)
Definition: debug.h:157
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:675

◆ i8042MouCallIsrHook()

static BOOLEAN i8042MouCallIsrHook ( IN PI8042_MOUSE_EXTENSION  DeviceExtension,
IN UCHAR  Status,
IN UCHAR  Input,
OUT PBOOLEAN  ToReturn 
)
static

Definition at line 598 of file mouse.c.

603 {
604  BOOLEAN HookReturn, HookContinue;
605 
606  HookContinue = FALSE;
607 
608  if (DeviceExtension->MouseHook.IsrRoutine)
609  {
610  HookReturn = DeviceExtension->MouseHook.IsrRoutine(
611  DeviceExtension->MouseHook.Context,
612  DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer,
613  &DeviceExtension->Common.PortDeviceExtension->Packet,
614  Status,
615  &Input,
616  &HookContinue,
617  &DeviceExtension->MouseState,
618  &DeviceExtension->MouseResetState);
619 
620  if (!HookContinue)
621  {
622  *ToReturn = HookReturn;
623  return TRUE;
624  }
625  }
626  return FALSE;
627 }
#define TRUE
Definition: types.h:120
Definition: arc.h:84
unsigned char BOOLEAN
Status
Definition: gdiplustypes.h:24

Referenced by i8042MouResetIsr().

◆ i8042MouDpcRoutine()

static VOID NTAPI i8042MouDpcRoutine ( IN PKDPC  Dpc,
IN PVOID  DeferredContext,
IN PVOID  SystemArgument1,
IN PVOID  SystemArgument2 
)
static

Definition at line 258 of file mouse.c.

263 {
264  PI8042_MOUSE_EXTENSION DeviceExtension;
265  PPORT_DEVICE_EXTENSION PortDeviceExtension;
266  ULONG MouseTransferred = 0;
267  ULONG MouseInBufferCopy;
268  KIRQL Irql;
270 
274 
276  DeviceExtension = DeferredContext;
277  PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension;
278 
279  switch (DeviceExtension->MouseTimeoutState)
280  {
281  case TimeoutStart:
282  {
283  DeviceExtension->MouseTimeoutState = NoChange;
284  if (DeviceExtension->MouseTimeoutActive &&
285  !KeCancelTimer(&DeviceExtension->TimerMouseTimeout))
286  {
287  /* The timer fired already, give up */
288  DeviceExtension->MouseTimeoutActive = FALSE;
289  return;
290  }
291 
292  Timeout.QuadPart = -15000000; /* 1.5 seconds, should be enough */
293 
294  KeSetTimer(
295  &DeviceExtension->TimerMouseTimeout,
296  Timeout,
297  &DeviceExtension->DpcMouseTimeout);
298  DeviceExtension->MouseTimeoutActive = TRUE;
299  return;
300  }
301 
302  case TimeoutCancel:
303  {
304  DeviceExtension->MouseTimeoutState = NoChange;
305  KeCancelTimer(&DeviceExtension->TimerMouseTimeout);
306  DeviceExtension->MouseTimeoutActive = FALSE;
307  }
308 
309  default:
310  ;/* nothing, don't want a warning */
311  }
312 
313  /* Should be unlikely */
314  if (!DeviceExtension->MouseComplete)
315  return;
316 
317  Irql = KeAcquireInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt);
318 
319  DeviceExtension->MouseComplete = FALSE;
320  MouseInBufferCopy = DeviceExtension->MouseInBuffer;
321 
323 
324  TRACE_(I8042PRT, "Send a mouse packet\n");
325 
326  if (!DeviceExtension->MouseData.ClassService)
327  return;
328 
329  INFO_(I8042PRT, "Sending %lu mouse move(s)\n", MouseInBufferCopy);
330  (*(PSERVICE_CALLBACK_ROUTINE)DeviceExtension->MouseData.ClassService)(
331  DeviceExtension->MouseData.ClassDeviceObject,
332  DeviceExtension->MouseBuffer,
333  DeviceExtension->MouseBuffer + MouseInBufferCopy,
334  &MouseTransferred);
335 
336  Irql = KeAcquireInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt);
337  DeviceExtension->MouseInBuffer -= MouseTransferred;
338  if (DeviceExtension->MouseInBuffer)
340  DeviceExtension->MouseBuffer,
341  DeviceExtension->MouseBuffer + MouseTransferred,
342  DeviceExtension->MouseInBuffer * sizeof(MOUSE_INPUT_DATA));
344 }
#define TRUE
Definition: types.h:120
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:281
#define INFO_(ch,...)
Definition: debug.h:159
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
PKINTERRUPT HighestDIRQLInterrupt
Definition: i8042prt.h:88
_Out_ PKIRQL Irql
Definition: csq.h:179
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
UCHAR KIRQL
Definition: env_spec_w32.h:591
VOID NTAPI KeReleaseInterruptSpinLock(IN PKINTERRUPT Interrupt, IN KIRQL OldIrql)
Definition: spinlock.c:165
#define __analysis_assume(expr)
Definition: sal.h:2893
smooth NULL
Definition: ftsmooth.c:416
FDO_DEVICE_EXTENSION Common
Definition: i8042prt.h:177
MOUSE_TIMEOUT_STATE MouseTimeoutState
Definition: i8042prt.h:194
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:675
#define TRACE_(x)
Definition: compat.h:66
_In_ LARGE_INTEGER _In_opt_ PKDPC Dpc
Definition: kefuncs.h:511
BOOLEAN NTAPI KeCancelTimer(IN OUT PKTIMER Timer)
Definition: timerobj.c:206
KIRQL NTAPI KeAcquireInterruptSpinLock(IN PKINTERRUPT Interrupt)
Definition: spinlock.c:148
PVOID ClassService
Definition: kbdmou.h:82
VOID(STDAPICALLTYPE * PSERVICE_CALLBACK_ROUTINE)(IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2, IN OUT PVOID SystemArgument3)
Definition: kbdmou.h:86
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:675
PMOUSE_INPUT_DATA MouseBuffer
Definition: i8042prt.h:187
static ULONG Timeout
Definition: ping.c:61
CONNECT_DATA MouseData
Definition: i8042prt.h:178
BOOLEAN MouseTimeoutActive
Definition: i8042prt.h:195
unsigned int ULONG
Definition: retypes.h:1
PDEVICE_OBJECT ClassDeviceObject
Definition: kbdmou.h:81
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:675

◆ i8042MouHandle()

VOID i8042MouHandle ( IN PI8042_MOUSE_EXTENSION  DeviceExtension,
IN UCHAR  Output 
)

Definition at line 68 of file mouse.c.

71 {
72  PMOUSE_INPUT_DATA MouseInput;
73  CHAR Scroll;
74 
75  MouseInput = DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer;
76 
77  switch (DeviceExtension->MouseState)
78  {
79  case MouseIdle:
80  /* This bit should be 1, if not drop the packet, we
81  * might be lucky and get in sync again
82  */
83  if (!(Output & 8)) {
84  WARN_(I8042PRT, "Bad input, dropping..\n");
85  return;
86  }
87 
88  MouseInput->Buttons = 0;
89  MouseInput->RawButtons = 0;
90  MouseInput->Flags = MOUSE_MOVE_RELATIVE;
91 
92  /* Note how we ignore the overflow bits, like Windows
93  * is said to do. There's no reasonable thing to do
94  * anyway.
95  */
96 
97  if (Output & 16)
98  MouseInput->LastX = 1;
99  else
100  MouseInput->LastX = 0;
101  if (Output & 32)
102  MouseInput->LastY = 1;
103  else
104  MouseInput->LastY = 0;
105 
106  if (Output & 1)
107  MouseInput->RawButtons |= MOUSE_LEFT_BUTTON_DOWN;
108  if (Output & 2)
109  MouseInput->RawButtons |= MOUSE_RIGHT_BUTTON_DOWN;
110  if (Output & 4)
111  MouseInput->RawButtons |= MOUSE_MIDDLE_BUTTON_DOWN;
112 
113  DeviceExtension->MouseState = XMovement;
114  break;
115 
116  case XMovement:
117  if (MouseInput->LastX)
118  MouseInput->LastX = (LONG) Output - 256;
119  else
120  MouseInput->LastX = Output;
121 
122  DeviceExtension->MouseState = YMovement;
123  break;
124 
125  case YMovement:
126  if (MouseInput->LastY)
127  MouseInput->LastY = (LONG)Output - 256;
128  else
129  MouseInput->LastY = (LONG)Output;
130 
131  /* Windows wants it the other way around */
132  MouseInput->LastY = -MouseInput->LastY;
133 
134  if (DeviceExtension->MouseType == GenericPS2 ||
135  DeviceExtension->MouseType == Ps2pp)
136  {
138  DeviceExtension,
142  DeviceExtension->MouseHook.QueueMousePacket(DeviceExtension->MouseHook.CallContext);
143  DeviceExtension->MouseState = MouseIdle;
144  }
145  else
146  {
147  DeviceExtension->MouseState = ZMovement;
148  }
149  break;
150 
151  case ZMovement:
152  Scroll = Output & 0x0f;
153  if (Scroll & 8)
154  Scroll |= 0xf0;
155 
156  if (Scroll)
157  {
158  MouseInput->RawButtons |= MOUSE_WHEEL;
159  MouseInput->ButtonData = (USHORT)(Scroll * -WHEEL_DELTA);
160  }
161 
162  if (DeviceExtension->MouseType == IntellimouseExplorer)
163  {
164  if (Output & 16)
165  MouseInput->RawButtons |= MOUSE_BUTTON_4_DOWN;
166  if (Output & 32)
167  MouseInput->RawButtons |= MOUSE_BUTTON_5_DOWN;
168  }
170  DeviceExtension,
176  DeviceExtension->MouseHook.QueueMousePacket(DeviceExtension->MouseHook.CallContext);
177  DeviceExtension->MouseState = MouseIdle;
178  break;
179 
180  default:
181  ERR_(I8042PRT, "Unexpected state 0x%lx!\n", DeviceExtension->MouseState);
182  ASSERT(FALSE);
183  }
184 }
#define MOUSE_MIDDLE_BUTTON_DOWN
Definition: ntddmou.h:50
#define MOUSE_LEFT_BUTTON_DOWN
Definition: ntddmou.h:46
#define MOUSE_WHEEL
Definition: ntddmou.h:56
char CHAR
Definition: xmlstorage.h:175
#define ERR_(ch,...)
Definition: debug.h:156
USHORT Flags
Definition: ntddmou.h:78
#define WHEEL_DELTA
Definition: treelist.c:99
ULONG RawButtons
Definition: ntddmou.h:86
long LONG
Definition: pedump.c:60
#define MOUSE_BUTTON_4_DOWN
Definition: ntddmou.h:52
#define MOUSE_MOVE_RELATIVE
Definition: ntddmou.h:67
#define MOUSE_RIGHT_BUTTON_DOWN
Definition: ntddmou.h:48
USHORT ButtonData
Definition: ntddmou.h:83
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Definition: arc.h:85
unsigned short USHORT
Definition: pedump.c:61
#define MOUSE_BUTTON_5_DOWN
Definition: ntddmou.h:54
#define WARN_(ch,...)
Definition: debug.h:157
VOID i8042MouHandleButtons(IN PI8042_MOUSE_EXTENSION DeviceExtension, IN USHORT Mask)
Definition: mouse.c:191

Referenced by i8042MouHandlePs2pp(), and i8042MouInterruptService().

◆ i8042MouHandleButtons()

VOID i8042MouHandleButtons ( IN PI8042_MOUSE_EXTENSION  DeviceExtension,
IN USHORT  Mask 
)

Definition at line 191 of file mouse.c.

194 {
195  PMOUSE_INPUT_DATA MouseInput;
196  USHORT NewButtonData;
197  USHORT ButtonDiff;
198 
199  MouseInput = DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer;
200  NewButtonData = (USHORT)(MouseInput->RawButtons & Mask);
201  ButtonDiff = (NewButtonData ^ DeviceExtension->MouseButtonState) & Mask;
202 
203  /* Note that the defines are such:
204  * MOUSE_LEFT_BUTTON_DOWN 1
205  * MOUSE_LEFT_BUTTON_UP 2
206  */
207  MouseInput->ButtonFlags |= (NewButtonData & ButtonDiff) |
208  (((~(NewButtonData)) << 1) & (ButtonDiff << 1)) |
209  (MouseInput->RawButtons & 0xfc00);
210 
211  INFO_(I8042PRT, "Left raw/up/down: %u/%u/%u\n",
212  MouseInput->RawButtons & MOUSE_LEFT_BUTTON_DOWN,
213  MouseInput->ButtonFlags & MOUSE_LEFT_BUTTON_DOWN,
214  MouseInput->ButtonFlags & MOUSE_LEFT_BUTTON_UP);
215 
216  DeviceExtension->MouseButtonState =
217  (DeviceExtension->MouseButtonState & ~Mask) | (NewButtonData & Mask);
218 }
#define MOUSE_LEFT_BUTTON_DOWN
Definition: ntddmou.h:46
#define INFO_(ch,...)
Definition: debug.h:159
ULONG RawButtons
Definition: ntddmou.h:86
#define MOUSE_LEFT_BUTTON_UP
Definition: ntddmou.h:47
USHORT ButtonFlags
Definition: ntddmou.h:82
unsigned short USHORT
Definition: pedump.c:61

Referenced by i8042MouHandle(), and i8042MouHandlePs2pp().

◆ i8042MouInitialize()

NTSTATUS i8042MouInitialize ( IN PI8042_MOUSE_EXTENSION  DeviceExtension)

Definition at line 224 of file mouse.c.

226 {
228  UCHAR Value;
229 
230  /* Enable the PS/2 mouse port */
231  i8042Write(DeviceExtension->Common.PortDeviceExtension, DeviceExtension->Common.PortDeviceExtension->ControlPort, MOUSE_ENAB);
232 
233  /* Enable the mouse */
234  if(!i8042IsrWritePort(DeviceExtension->Common.PortDeviceExtension, MOU_ENAB, CTRL_WRITE_MOUSE))
235  {
236  WARN_(I8042PRT, "Failed to enable mouse!\n");
237  return STATUS_IO_DEVICE_ERROR;
238  }
239 
240  Status = i8042ReadDataWait(DeviceExtension->Common.PortDeviceExtension, &Value);
241  if (!NT_SUCCESS(Status))
242  {
243  WARN_(I8042PRT, "Failed to read the response of MOU_ENAB, status 0x%08lx\n", Status);
244  return Status;
245  }
246 
247  if(Value == MOUSE_ACK)
248  {
249  INFO_(I8042PRT, "Mouse was enabled successfully!\n");
250  return STATUS_SUCCESS;
251  }
252 
253  WARN_(I8042PRT, "Got 0x%02x instead of 0xFA\n", Value);
254  return STATUS_IO_DEVICE_ERROR;
255 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2374
#define INFO_(ch,...)
Definition: debug.h:159
#define MOU_ENAB
Definition: i8042prt.h:278
LONG NTSTATUS
Definition: precomp.h:26
#define MOUSE_ENAB
Definition: i8042prt.h:223
BOOLEAN i8042Write(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN PUCHAR addr, IN UCHAR data)
Definition: readwrite.c:199
BOOLEAN i8042IsrWritePort(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR Value, IN UCHAR SelectCmd OPTIONAL)
Definition: readwrite.c:40
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
unsigned char UCHAR
Definition: xmlstorage.h:181
#define MOUSE_ACK
Definition: i8042prt.h:285
Status
Definition: gdiplustypes.h:24
NTSTATUS i8042ReadDataWait(IN PPORT_DEVICE_EXTENSION DeviceExtension, OUT PUCHAR Data)
Definition: readwrite.c:95
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define WARN_(ch,...)
Definition: debug.h:157
#define CTRL_WRITE_MOUSE
Definition: i8042prt.h:228

Referenced by i8042ConnectMouseInterrupt().

◆ i8042MouInputTestTimeout()

static VOID i8042MouInputTestTimeout ( IN PI8042_MOUSE_EXTENSION  DeviceExtension)
static

Definition at line 566 of file mouse.c.

568 {
570 
571  if (DeviceExtension->MouseState == MouseExpectingACK ||
572  DeviceExtension->MouseState == MouseResetting)
573  return;
574 
575  Now.QuadPart = KeQueryInterruptTime();
576 
577  if (DeviceExtension->MouseState != MouseIdle) {
578  /* Check if the last byte came too long ago */
579  if (Now.QuadPart - DeviceExtension->MousePacketStartTime.QuadPart >
580  DeviceExtension->Common.PortDeviceExtension->Settings.MouseSynchIn100ns)
581  {
582  WARN_(I8042PRT, "Mouse input packet timeout\n");
583  DeviceExtension->MouseState = MouseIdle;
584  }
585  }
586 
587  if (DeviceExtension->MouseState == MouseIdle)
588  DeviceExtension->MousePacketStartTime.QuadPart = Now.QuadPart;
589 }
struct tm * Now
Definition: output.c:19
#define WARN_(ch,...)
Definition: debug.h:157
ULONGLONG NTAPI KeQueryInterruptTime(VOID)
Definition: clock.c:203

Referenced by i8042MouInterruptService().

◆ i8042MouInternalDeviceControl()

NTSTATUS NTAPI i8042MouInternalDeviceControl ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 383 of file mouse.c.

386 {
387  PIO_STACK_LOCATION Stack;
388  PI8042_MOUSE_EXTENSION DeviceExtension;
390 
392  Irp->IoStatus.Information = 0;
394 
395  switch (Stack->Parameters.DeviceIoControl.IoControlCode)
396  {
398  {
399  SIZE_T Size;
400  PIO_WORKITEM WorkItem = NULL;
401  PI8042_HOOK_WORKITEM WorkItemData = NULL;
402 
403  TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_MOUSE_CONNECT\n");
404  if (Stack->Parameters.DeviceIoControl.InputBufferLength != sizeof(CONNECT_DATA))
405  {
407  goto cleanup;
408  }
409 
410  DeviceExtension->MouseData =
411  *((PCONNECT_DATA)Stack->Parameters.DeviceIoControl.Type3InputBuffer);
412 
413  /* Send IOCTL_INTERNAL_I8042_HOOK_MOUSE to device stack */
414  WorkItem = IoAllocateWorkItem(DeviceObject);
415  if (!WorkItem)
416  {
417  WARN_(I8042PRT, "IoAllocateWorkItem() failed\n");
419  goto cleanup;
420  }
421  WorkItemData = ExAllocatePoolWithTag(
422  NonPagedPool,
423  sizeof(I8042_HOOK_WORKITEM),
424  I8042PRT_TAG);
425  if (!WorkItemData)
426  {
427  WARN_(I8042PRT, "ExAllocatePoolWithTag() failed\n");
429  goto cleanup;
430  }
431  WorkItemData->WorkItem = WorkItem;
432  WorkItemData->Irp = Irp;
433 
434  /* Initialize extension */
435  DeviceExtension->Common.Type = Mouse;
436  Size = DeviceExtension->Common.PortDeviceExtension->Settings.MouseDataQueueSize * sizeof(MOUSE_INPUT_DATA);
437  DeviceExtension->MouseBuffer = ExAllocatePoolWithTag(
438  NonPagedPool,
439  Size,
440  I8042PRT_TAG);
441  if (!DeviceExtension->MouseBuffer)
442  {
443  WARN_(I8042PRT, "ExAllocatePoolWithTag() failed\n");
445  goto cleanup;
446  }
447  RtlZeroMemory(DeviceExtension->MouseBuffer, Size);
448  DeviceExtension->MouseAttributes.InputDataQueueLength =
449  DeviceExtension->Common.PortDeviceExtension->Settings.MouseDataQueueSize;
451  &DeviceExtension->DpcMouse,
453  DeviceExtension);
455  &DeviceExtension->DpcMouseTimeout,
457  DeviceExtension);
458  KeInitializeTimer(&DeviceExtension->TimerMouseTimeout);
459  DeviceExtension->Common.PortDeviceExtension->MouseExtension = DeviceExtension;
460  DeviceExtension->Common.PortDeviceExtension->Flags |= MOUSE_CONNECTED;
461 
463  DeviceExtension->MouseState = MouseResetting;
464  DeviceExtension->MouseResetState = ExpectingReset;
465  DeviceExtension->MouseHook.IsrWritePort = i8042MouIsrWritePort;
467  DeviceExtension->MouseHook.CallContext = DeviceExtension;
468  IoQueueWorkItem(WorkItem,
471  WorkItemData);
473  break;
474 
475 cleanup:
476  if (DeviceExtension->MouseBuffer)
477  ExFreePoolWithTag(DeviceExtension->MouseBuffer, I8042PRT_TAG);
478  if (WorkItem)
479  IoFreeWorkItem(WorkItem);
480  if (WorkItemData)
481  ExFreePoolWithTag(WorkItemData, I8042PRT_TAG);
482  break;
483  }
485  {
486  TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_MOUSE_DISCONNECT\n");
487  /* MSDN says that operation is to implemented.
488  * To implement it, we just have to do:
489  * DeviceExtension->MouseData.ClassService = NULL;
490  */
492  break;
493  }
495  {
496  PINTERNAL_I8042_HOOK_MOUSE MouseHook;
497  TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_I8042_HOOK_MOUSE\n");
498  if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(INTERNAL_I8042_HOOK_MOUSE))
499  {
501  break;
502  }
503  MouseHook = (PINTERNAL_I8042_HOOK_MOUSE)Stack->Parameters.DeviceIoControl.Type3InputBuffer;
504 
505  DeviceExtension->MouseHook.Context = MouseHook->Context;
506  if (MouseHook->IsrRoutine)
507  DeviceExtension->MouseHook.IsrRoutine = MouseHook->IsrRoutine;
508 
510  break;
511  }
513  {
514  DPRINT1("IOCTL_INTERNAL_I8042_MOUSE_WRITE_BUFFER not implemented\n");
516  break;
517  }
519  {
520  DPRINT1("IOCTL_INTERNAL_I8042_MOUSE_START_INFORMATION not implemented\n");
522  break;
523  }
525  {
526  TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_MOUSE_QUERY_ATTRIBUTES\n");
527  if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUSE_ATTRIBUTES))
528  {
530  break;
531  }
532 
533  *(PMOUSE_ATTRIBUTES) Irp->AssociatedIrp.SystemBuffer = DeviceExtension->MouseAttributes;
534  Irp->IoStatus.Information = sizeof(MOUSE_ATTRIBUTES);
536  break;
537  }
538  default:
539  {
540  ERR_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / unknown ioctl code 0x%lx\n",
541  Stack->Parameters.DeviceIoControl.IoControlCode);
542  ASSERT(FALSE);
544  }
545  }
546 
547  if (Status != STATUS_PENDING)
548  {
549  Irp->IoStatus.Status = Status;
551  }
552  return Status;
553 }
static VOID NTAPI i8042MouQueuePacket(IN PVOID Context)
Definition: mouse.c:48
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
static VOID NTAPI i8042MouIsrWritePort(IN PVOID Context, IN UCHAR Value)
Definition: mouse.c:29
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
PIO_WORKITEM WorkItem
Definition: i8042prt.h:203
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
DRIVER_DISPATCH ForwardIrpAndForget
Definition: i8042prt.h:341
#define ERR_(ch,...)
Definition: debug.h:156
LONG NTSTATUS
Definition: precomp.h:26
struct _MOUSE_INPUT_DATA MOUSE_INPUT_DATA
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
#define I8042PRT_TAG
Definition: i8042prt.h:12
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
ULONG InputDataQueueLength
Definition: ntddmou.h:112
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
FDO_DEVICE_EXTENSION Common
Definition: i8042prt.h:177
switch(r->id)
Definition: btrfs.c:2904
#define TRACE_(x)
Definition: compat.h:66
#define IOCTL_INTERNAL_I8042_MOUSE_WRITE_BUFFER
Definition: ntdd8042.h:51
MOUSE_ATTRIBUTES MouseAttributes
Definition: i8042prt.h:182
if(!(yy_init))
Definition: macro.lex.yy.c:714
static KDEFERRED_ROUTINE i8042MouDpcRoutine
Definition: mouse.c:21
#define STATUS_PENDING
Definition: ntstatus.h:82
struct _MOUSE_ATTRIBUTES * PMOUSE_ATTRIBUTES
static KDEFERRED_ROUTINE i8042DpcRoutineMouseTimeout
Definition: mouse.c:22
#define IOCTL_INTERNAL_MOUSE_DISCONNECT
Definition: kbdmou.h:71
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define IOCTL_INTERNAL_MOUSE_CONNECT
Definition: kbdmou.h:68
IO_WORKITEM_ROUTINE i8042SendHookWorkItem
Definition: i8042prt.h:295
#define MOUSE_CONNECTED
Definition: i8042prt.h:73
INTERNAL_I8042_HOOK_MOUSE MouseHook
Definition: i8042prt.h:179
#define IOCTL_MOUSE_QUERY_ATTRIBUTES
Definition: ntddmou.h:32
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
Status
Definition: gdiplustypes.h:24
PMOUSE_INPUT_DATA MouseBuffer
Definition: i8042prt.h:187
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
Definition: iowork.c:40
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
ULONG_PTR SIZE_T
Definition: typedefs.h:79
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define IOCTL_INTERNAL_I8042_MOUSE_START_INFORMATION
Definition: ntdd8042.h:48
#define IOCTL_INTERNAL_I8042_HOOK_MOUSE
Definition: ntdd8042.h:45
MOUSE_STATE MouseState
Definition: i8042prt.h:184
CONNECT_DATA MouseData
Definition: i8042prt.h:178
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
MOUSE_RESET_SUBSTATE MouseResetState
Definition: i8042prt.h:186
OUT PI8042_MOUSE_ISR IsrRoutine
Definition: ntdd8042.h:198
#define DPRINT1
Definition: precomp.h:8
#define IO_NO_INCREMENT
Definition: iotypes.h:566
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
char * cleanup(char *str)
Definition: wpickclick.c:99
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:711
struct _CONNECT_DATA * PCONNECT_DATA
return STATUS_SUCCESS
Definition: btrfs.c:2938
IoMarkIrpPending(Irp)
IN PI8042_QUEUE_PACKET QueueMousePacket
Definition: ntdd8042.h:200
struct _INTERNAL_I8042_HOOK_MOUSE * PINTERNAL_I8042_HOOK_MOUSE
#define WARN_(ch,...)
Definition: debug.h:157
struct _I8042_MOUSE_EXTENSION * PI8042_MOUSE_EXTENSION
Definition: i8042prt.h:65
IN PI8042_ISR_WRITE_PORT IsrWritePort
Definition: ntdd8042.h:199

◆ i8042MouInterruptService()

BOOLEAN NTAPI i8042MouInterruptService ( IN PKINTERRUPT  Interrupt,
PVOID  Context 
)

Definition at line 904 of file mouse.c.

907 {
908  PI8042_MOUSE_EXTENSION DeviceExtension;
909  PPORT_DEVICE_EXTENSION PortDeviceExtension;
910  ULONG Counter;
911  UCHAR Output = 0, PortStatus = 0;
913 
914  UNREFERENCED_PARAMETER(Interrupt);
915 
917  DeviceExtension = Context;
918  PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension;
919  Counter = PortDeviceExtension->Settings.PollStatusIterations;
920 
921  while (Counter)
922  {
923  Status = i8042ReadStatus(PortDeviceExtension, &PortStatus);
924  if (!NT_SUCCESS(Status))
925  {
926  WARN_(I8042PRT, "i8042ReadStatus() failed with status 0x%08lx\n", Status);
927  return FALSE;
928  }
929  Status = i8042ReadMouseData(PortDeviceExtension, &Output);
930  if (NT_SUCCESS(Status))
931  break;
933  Counter--;
934  }
935  if (Counter == 0)
936  {
937  WARN_(I8042PRT, "Spurious i8042 mouse interrupt\n");
938  return FALSE;
939  }
940 
941  INFO_(I8042PRT, "Got: 0x%02x\n", Output);
942 
943  if (i8042PacketIsr(PortDeviceExtension, Output))
944  {
945  if (PortDeviceExtension->PacketComplete)
946  {
947  TRACE_(I8042PRT, "Packet complete\n");
948  KeInsertQueueDpc(&DeviceExtension->DpcMouse, NULL, NULL);
949  }
950  TRACE_(I8042PRT, "Irq eaten by packet\n");
951  return TRUE;
952  }
953 
954  TRACE_(I8042PRT, "Irq is mouse input\n");
955 
956  i8042MouInputTestTimeout(DeviceExtension);
957 
958  if (i8042MouResetIsr(DeviceExtension, PortStatus, Output))
959  {
960  TRACE_(I8042PRT, "Handled by ResetIsr or hooked Isr\n");
961  if (NoChange != DeviceExtension->MouseTimeoutState) {
962  KeInsertQueueDpc(&DeviceExtension->DpcMouse, NULL, NULL);
963  }
964  return TRUE;
965  }
966 
967  if (DeviceExtension->MouseType == Ps2pp)
968  i8042MouHandlePs2pp(DeviceExtension, Output);
969  else
970  i8042MouHandle(DeviceExtension, Output);
971 
972  return TRUE;
973 }
NTSTATUS i8042ReadStatus(IN PPORT_DEVICE_EXTENSION DeviceExtension, OUT PUCHAR Status)
Definition: readwrite.c:82
#define TRUE
Definition: types.h:120
#define INFO_(ch,...)
Definition: debug.h:159
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
I8042_MOUSE_TYPE MouseType
Definition: i8042prt.h:198
VOID i8042MouHandlePs2pp(IN PI8042_MOUSE_EXTENSION DeviceExtension, IN UCHAR Input)
Definition: ps2pp.c:19
BOOLEAN NTAPI KeInsertQueueDpc(IN PKDPC Dpc, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: dpc.c:724
LONG NTSTATUS
Definition: precomp.h:26
I8042_SETTINGS Settings
Definition: i8042prt.h:81
VOID i8042MouHandle(IN PI8042_MOUSE_EXTENSION DeviceExtension, IN UCHAR Output)
Definition: mouse.c:68
#define __analysis_assume(expr)
Definition: sal.h:2893
smooth NULL
Definition: ftsmooth.c:416
FDO_DEVICE_EXTENSION Common
Definition: i8042prt.h:177
MOUSE_TIMEOUT_STATE MouseTimeoutState
Definition: i8042prt.h:194
BOOLEAN i8042PacketIsr(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR Output)
Definition: i8042prt.c:272
#define TRACE_(x)
Definition: compat.h:66
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
unsigned char UCHAR
Definition: xmlstorage.h:181
Definition: arc.h:85
static VOID i8042MouInputTestTimeout(IN PI8042_MOUSE_EXTENSION DeviceExtension)
Definition: mouse.c:566
_Outptr_ PUSB_DEVICE_HANDLE _In_ PUSB_DEVICE_HANDLE _In_ USHORT PortStatus
Definition: hubbusif.h:40
static BOOLEAN i8042MouResetIsr(IN PI8042_MOUSE_EXTENSION DeviceExtension, IN UCHAR Status, IN UCHAR Value)
Definition: mouse.c:630
BOOLEAN PacketComplete
Definition: i8042prt.h:94
Status
Definition: gdiplustypes.h:24
#define i8042ReadMouseData(DeviceExtension, Data)
Definition: i8042prt.h:407
static LARGE_INTEGER Counter
Definition: clock.c:43
ULONG PollStatusIterations
Definition: i8042prt.h:33
struct tagContext Context
Definition: acpixf.h:1034
unsigned int ULONG
Definition: retypes.h:1
#define WARN_(ch,...)
Definition: debug.h:157
VOID NTAPI KeStallExecutionProcessor(IN ULONG MicroSeconds)
Definition: ntoskrnl.c:95

◆ i8042MouIsrWritePort()

static VOID NTAPI i8042MouIsrWritePort ( IN PVOID  Context,
IN UCHAR  Value 
)
static

Definition at line 29 of file mouse.c.

32 {
33  PI8042_MOUSE_EXTENSION DeviceExtension;
34 
35  DeviceExtension = (PI8042_MOUSE_EXTENSION)Context;
36 
37  if (DeviceExtension->MouseHook.IsrWritePort != i8042MouIsrWritePort)
38  {
39  DeviceExtension->MouseHook.IsrWritePort(
40  DeviceExtension->MouseHook.CallContext,
41  Value);
42  }
43  else
44  i8042IsrWritePort(DeviceExtension->Common.PortDeviceExtension, Value, CTRL_WRITE_MOUSE);
45 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2374
static VOID NTAPI i8042MouIsrWritePort(IN PVOID Context, IN UCHAR Value)
Definition: mouse.c:29
BOOLEAN i8042IsrWritePort(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR Value, IN UCHAR SelectCmd OPTIONAL)
Definition: readwrite.c:40
FDO_DEVICE_EXTENSION Common
Definition: i8042prt.h:177
INTERNAL_I8042_HOOK_MOUSE MouseHook
Definition: i8042prt.h:179
struct _I8042_MOUSE_EXTENSION * PI8042_MOUSE_EXTENSION
Definition: i8042prt.h:65
IN PI8042_ISR_WRITE_PORT IsrWritePort
Definition: ntdd8042.h:199
#define CTRL_WRITE_MOUSE
Definition: i8042prt.h:228

Referenced by i8042MouInternalDeviceControl().

◆ i8042MouQueuePacket()

static VOID NTAPI i8042MouQueuePacket ( IN PVOID  Context)
static

Definition at line 48 of file mouse.c.

50 {
51  PI8042_MOUSE_EXTENSION DeviceExtension;
52 
53  DeviceExtension = (PI8042_MOUSE_EXTENSION)Context;
54 
55  DeviceExtension->MouseComplete = TRUE;
56  DeviceExtension->MouseInBuffer++;
57  if (DeviceExtension->MouseInBuffer >= DeviceExtension->Common.PortDeviceExtension->Settings.MouseDataQueueSize)
58  {
59  WARN_(I8042PRT, "Mouse buffer overflow\n");
60  DeviceExtension->MouseInBuffer--;
61  }
62 
63  TRACE_(I8042PRT, "Irq completes mouse packet\n");
64  KeInsertQueueDpc(&DeviceExtension->DpcMouse, NULL, NULL);
65 }
#define TRUE
Definition: types.h:120
BOOLEAN NTAPI KeInsertQueueDpc(IN PKDPC Dpc, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: dpc.c:724
smooth NULL
Definition: ftsmooth.c:416
FDO_DEVICE_EXTENSION Common
Definition: i8042prt.h:177
#define TRACE_(x)
Definition: compat.h:66
#define WARN_(ch,...)
Definition: debug.h:157
struct _I8042_MOUSE_EXTENSION * PI8042_MOUSE_EXTENSION
Definition: i8042prt.h:65

Referenced by i8042MouInternalDeviceControl().

◆ i8042MouResetIsr()

static BOOLEAN i8042MouResetIsr ( IN PI8042_MOUSE_EXTENSION  DeviceExtension,
IN UCHAR  Status,
IN UCHAR  Value 
)
static

Definition at line 630 of file mouse.c.

634 {
635  PPORT_DEVICE_EXTENSION PortDeviceExtension;
636  BOOLEAN ToReturn = FALSE;
637 
638  if (i8042MouCallIsrHook(DeviceExtension, Status, Value, &ToReturn))
639  return ToReturn;
640 
641  if (MouseIdle == DeviceExtension->MouseState)
642  {
643  /* Magic packet value that indicates a reset */
644  if (0xAA == Value)
645  {
646  WARN_(I8042PRT, "Hot plugged mouse!\n");
647  DeviceExtension->MouseState = MouseResetting;
648  DeviceExtension->MouseResetState = ExpectingReset;
649  }
650  else
651  return FALSE;
652  }
653  else if (MouseResetting != DeviceExtension->MouseState)
654  return FALSE;
655 
656  DeviceExtension->MouseTimeoutState = TimeoutStart;
657  PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension;
658 
659  switch ((ULONG)DeviceExtension->MouseResetState)
660  {
661  case ExpectingReset:
662  if (MOUSE_ACK == Value)
663  {
664  WARN_(I8042PRT, "Dropping extra ACK\n");
665  return TRUE;
666  }
667 
668  /* First, 0xFF is sent. The mouse is supposed to say AA00 if ok, FC00 if not. */
669  if (0xAA == Value)
670  {
671  DeviceExtension->MouseResetState++;
672  }
673  else
674  {
675  PortDeviceExtension->Flags &= ~MOUSE_PRESENT;
676  DeviceExtension->MouseState = MouseIdle;
677  WARN_(I8042PRT, "Mouse returned bad reset reply: %x (expected aa)\n", Value);
678  }
679  return TRUE;
680  case ExpectingResetId:
681  if (MOUSE_ACK == Value)
682  {
683  WARN_(I8042PRT, "Dropping extra ACK #2\n");
684  return TRUE;
685  }
686 
687  if (0x00 == Value)
688  {
689  DeviceExtension->MouseResetState++;
690  DeviceExtension->MouseType = GenericPS2;
691  DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF2);
692  }
693  else
694  {
695  PortDeviceExtension->Flags &= ~MOUSE_PRESENT;
696  DeviceExtension->MouseState = MouseIdle;
697  WARN_(I8042PRT, "Mouse returned bad reset reply part two: %x (expected 0)\n", Value);
698  }
699  return TRUE;
701  if (MOUSE_ACK == Value)
702  {
703  DeviceExtension->MouseResetState++;
704  }
705  else if (MOUSE_NACK == Value || MOUSE_ERROR == Value)
706  {
707  DeviceExtension->MouseResetState++;
708  /* Act as if 00 (normal mouse) was received */
709  WARN_(I8042PRT, "Mouse doesn't support 0xd2, (returns %x, expected %x), faking\n", Value, MOUSE_ACK);
710  i8042MouResetIsr(DeviceExtension, Status, 0);
711  }
712  return TRUE;
714  switch (Value)
715  {
716  case 0x02:
717  DeviceExtension->MouseAttributes.MouseIdentifier =
719  break;
720  case 0x03:
721  case 0x04:
722  DeviceExtension->MouseAttributes.MouseIdentifier =
724  break;
725  default:
726  DeviceExtension->MouseAttributes.MouseIdentifier =
728  }
729  DeviceExtension->MouseResetState++;
730  DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xE8);
731  return TRUE;
733  DeviceExtension->MouseResetState++;
734  DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0x00);
735  return TRUE;
737  DeviceExtension->MouseResetState = ExpectingSetScaling1to1ACK;
738  DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xE6);
739  return TRUE;
742  DeviceExtension->MouseResetState++;
743  DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xE6);
744  return TRUE;
746  DeviceExtension->MouseResetState++;
747  DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xE9);
748  return TRUE;
750  DeviceExtension->MouseResetState++;
751  return TRUE;
753  DeviceExtension->MouseLogiBuffer[0] = Value;
754  DeviceExtension->MouseResetState++;
755  return TRUE;
757  DeviceExtension->MouseLogiBuffer[1] = Value;
758  DeviceExtension->MouseResetState++;
759  return TRUE;
761  DeviceExtension->MouseLogiBuffer[2] = Value;
762  /* Now MouseLogiBuffer is a set of info. If the second
763  * byte is 0, the mouse didn't understand the magic
764  * code. Otherwise, it it a Logitech and the second byte
765  * is the number of buttons, bit 7 of the first byte tells
766  * if it understands special E7 commands, the rest is an ID.
767  */
768  if (DeviceExtension->MouseLogiBuffer[1])
769  {
770  DeviceExtension->MouseAttributes.NumberOfButtons =
771  DeviceExtension->MouseLogiBuffer[1];
772  DeviceExtension->MouseType = Ps2pp;
773  DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF3);
774  DeviceExtension->MouseResetState = ExpectingSetSamplingRateACK;
775  /* TODO: Go through EnableWheel and Enable5Buttons */
776  return TRUE;
777  }
778  DeviceExtension->MouseResetState = EnableWheel;
779  i8042MouResetIsr(DeviceExtension, Status, Value);
780  return TRUE;
781  case EnableWheel:
782  DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF3);
783  DeviceExtension->MouseResetState = 1001;
784  return TRUE;
785  case 1001:
786  DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xC8);
787  DeviceExtension->MouseResetState++;
788  return TRUE;
789  case 1002:
790  case 1004:
791  DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF3);
792  DeviceExtension->MouseResetState++;
793  return TRUE;
794  case 1003:
795  DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0x64);
796  DeviceExtension->MouseResetState++;
797  return TRUE;
798  case 1005:
799  DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0x50);
800  DeviceExtension->MouseResetState++;
801  return TRUE;
802  case 1006:
803  DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF2);
804  DeviceExtension->MouseResetState++;
805  return TRUE;
806  case 1007:
807  /* Ignore ACK */
808  DeviceExtension->MouseResetState++;
809  return TRUE;
810  case 1008:
811  if (0x03 == Value) {
812  /* It's either an Intellimouse or Intellimouse Explorer. */
813  DeviceExtension->MouseAttributes.NumberOfButtons = 3;
814  DeviceExtension->MouseAttributes.MouseIdentifier =
816  DeviceExtension->MouseType = Intellimouse;
817  DeviceExtension->MouseResetState = Enable5Buttons;
818  i8042MouResetIsr(DeviceExtension, Status, Value);
819  }
820  else
821  {
822  /* Just set the default settings and be done */
823  DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF3);
824  DeviceExtension->MouseResetState = ExpectingSetSamplingRateACK;
825  }
826  return TRUE;
827  case Enable5Buttons:
828  DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF3);
829  DeviceExtension->MouseResetState = 1021;
830  return TRUE;
831  case 1022:
832  case 1024:
833  DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF3);
834  DeviceExtension->MouseResetState++;
835  return TRUE;
836  case 1021:
837  case 1023:
838  DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xC8);
839  DeviceExtension->MouseResetState++;
840  return TRUE;
841  case 1025:
842  DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0x50);
843  DeviceExtension->MouseResetState++;
844  return TRUE;
845  case 1026:
846  DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF2);
847  DeviceExtension->MouseResetState++;
848  return TRUE;
849  case 1027:
850  if (0x04 == Value)
851  {
852  DeviceExtension->MouseAttributes.NumberOfButtons = 5;
853  DeviceExtension->MouseAttributes.MouseIdentifier =
855  DeviceExtension->MouseType = IntellimouseExplorer;
856  }
857  DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF3);
858  DeviceExtension->MouseResetState = ExpectingSetSamplingRateACK;
859  return TRUE;
861  DeviceExtension->MouseHook.IsrWritePort(
862  DeviceExtension->MouseHook.CallContext,
863  (UCHAR)DeviceExtension->MouseAttributes.SampleRate);
864  DeviceExtension->MouseResetState++;
865  return TRUE;
867  if (MOUSE_NACK == Value)
868  {
869  DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0x3C);
870  DeviceExtension->MouseAttributes.SampleRate = (USHORT)PortDeviceExtension->Settings.SampleRate;
871  DeviceExtension->MouseResetState = 1040;
872  return TRUE;
873  }
874  case 1040: /* Fallthrough */
875  DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xE8);
876  DeviceExtension->MouseResetState = ExpectingFinalResolutionACK;
877  return TRUE;
879  DeviceExtension->MouseHook.IsrWritePort(
880  DeviceExtension->MouseHook.CallContext,
881  (UCHAR)(PortDeviceExtension->Settings.MouseResolution & 0xff));
882  INFO_(I8042PRT, "Mouse resolution %lu\n",
883  PortDeviceExtension->Settings.MouseResolution);
884  DeviceExtension->MouseResetState = ExpectingFinalResolutionValueACK;
885  return TRUE;
887  DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF4);
888  DeviceExtension->MouseResetState = ExpectingEnableACK;
889  return TRUE;
890  case ExpectingEnableACK:
891  PortDeviceExtension->Flags |= MOUSE_PRESENT;
892  DeviceExtension->MouseState = MouseIdle;
893  DeviceExtension->MouseTimeoutState = TimeoutCancel;
894  INFO_(I8042PRT, "Mouse type = %u\n", DeviceExtension->MouseType);
895  return TRUE;
896  default:
897  if (DeviceExtension->MouseResetState < 100 || DeviceExtension->MouseResetState > 999)
898  ERR_(I8042PRT, "MouseResetState went out of range: %lu\n", DeviceExtension->MouseResetState);
899  return FALSE;
900  }
901 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2374
#define MOUSE_PRESENT
Definition: i8042prt.h:72
#define TRUE
Definition: types.h:120
#define INFO_(ch,...)
Definition: debug.h:159
#define MOUSE_I8042_HARDWARE
Definition: ntddmou.h:98
COMMON_DEVICE_EXTENSION Common
Definition: kbdclass.h:42
#define ERR_(ch,...)
Definition: debug.h:156
I8042_SETTINGS Settings
Definition: i8042prt.h:81
#define MOUSE_NACK
Definition: i8042prt.h:287
#define BALLPOINT_I8042_HARDWARE
Definition: ntddmou.h:100
unsigned char BOOLEAN
#define WHEELMOUSE_I8042_HARDWARE
Definition: ntddmou.h:102
#define MOUSE_ERROR
Definition: i8042prt.h:286
unsigned char UCHAR
Definition: xmlstorage.h:181
#define MOUSE_ACK
Definition: i8042prt.h:285
static BOOLEAN i8042MouResetIsr(IN PI8042_MOUSE_EXTENSION DeviceExtension, IN UCHAR Status, IN UCHAR Value)
Definition: mouse.c:630
Status
Definition: gdiplustypes.h:24
ULONG SampleRate
Definition: i8042prt.h:39
unsigned short USHORT
Definition: pedump.c:61
unsigned int ULONG
Definition: retypes.h:1
static BOOLEAN i8042MouCallIsrHook(IN PI8042_MOUSE_EXTENSION DeviceExtension, IN UCHAR Status, IN UCHAR Input, OUT PBOOLEAN ToReturn)
Definition: mouse.c:598
#define WARN_(ch,...)
Definition: debug.h:157
ULONG MouseResolution
Definition: i8042prt.h:29

Referenced by i8042MouInterruptService().

Variable Documentation

◆ i8042DpcRoutineMouseTimeout

KDEFERRED_ROUTINE i8042DpcRoutineMouseTimeout
static

Definition at line 22 of file mouse.c.

Referenced by i8042MouInternalDeviceControl().

◆ i8042MouDpcRoutine

KDEFERRED_ROUTINE i8042MouDpcRoutine
static

Definition at line 21 of file mouse.c.

Referenced by i8042MouInternalDeviceControl().