ReactOS  0.4.13-dev-464-g6b95727
mouse.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: drivers/input/i8042prt/mouse.c
5  * PURPOSE: Mouse specific functions
6  * PROGRAMMERS: Copyright Victor Kirhenshtein (sauros@iname.com)
7  Copyright Jason Filby (jasonfilby@yahoo.com)
8  Copyright Martijn Vernooij (o112w8r02@sneakemail.com)
9  Copyright 2006-2007 Hervé Poussineau (hpoussin@reactos.org)
10  Copyright 2008 Colin Finck (mail@colinfinck.de)
11  */
12 
13 /* INCLUDES ****************************************************************/
14 
15 #include "i8042prt.h"
16 
17 #include <debug.h>
18 
19 /* FUNCTIONS *****************************************************************/
20 
21 static KDEFERRED_ROUTINE i8042MouDpcRoutine;
22 static KDEFERRED_ROUTINE i8042DpcRoutineMouseTimeout;
23 
24 /*
25  * These functions are callbacks for filter driver custom interrupt
26  * service routines.
27  */
28 static VOID NTAPI
31  IN UCHAR Value)
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 }
46 
47 static VOID NTAPI
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 }
66 
67 VOID
69  IN PI8042_MOUSE_EXTENSION DeviceExtension,
70  IN UCHAR Output)
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 }
185 
186 /*
187  * Updates ButtonFlags according to RawButtons and a saved state;
188  * Only takes in account the bits that are set in Mask
189  */
190 VOID
192  IN PI8042_MOUSE_EXTENSION DeviceExtension,
193  IN USHORT Mask)
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 }
219 
220 /* Does final initializations for the mouse. This method
221  * is called just before connecting the interrupt.
222  */
223 NTSTATUS
225  IN PI8042_MOUSE_EXTENSION DeviceExtension)
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 }
256 
257 static VOID NTAPI
259  IN PKDPC Dpc,
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 }
345 
346 /* This timer DPC will be called when the mouse reset times out.
347  * I'll just send the 'disable mouse port' command to the controller
348  * and say the mouse doesn't exist.
349  */
350 static VOID NTAPI
352  IN PKDPC Dpc,
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 }
378 
379 /*
380  * Runs the mouse IOCTL_INTERNAL dispatch.
381  */
385  IN PIRP Irp)
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 }
554 
555 /* Test if packets are taking too long to come in. If they do, we
556  * might have gotten out of sync and should just drop what we have.
557  *
558  * If we want to be totally right, we'd also have to keep a count of
559  * errors, and totally reset the mouse after too much of them (can
560  * happen if the user is using a KVM switch and an OS on another port
561  * resets the mouse, or if the user hotplugs the mouse, or if we're just
562  * generally unlucky). Also note the input parsing routine where we
563  * drop invalid input packets.
564  */
565 static VOID
567  IN PI8042_MOUSE_EXTENSION DeviceExtension)
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 }
590 
591 /*
592  * Call the customization hook. The ToReturn parameter is about wether
593  * we should go on with the interrupt. The return value is what
594  * we should return (indicating to the system wether someone else
595  * should try to handle the interrupt)
596  */
597 static BOOLEAN
599  IN PI8042_MOUSE_EXTENSION DeviceExtension,
600  IN UCHAR Status,
601  IN UCHAR Input,
602  OUT PBOOLEAN ToReturn)
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 }
628 
629 static BOOLEAN
631  IN PI8042_MOUSE_EXTENSION DeviceExtension,
632  IN UCHAR Status,
633  IN UCHAR Value)
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 }
902 
905  IN PKINTERRUPT Interrupt,
906  PVOID Context)
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 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2327
#define MOUSE_PRESENT
Definition: i8042prt.h:72
NTSTATUS i8042ReadStatus(IN PPORT_DEVICE_EXTENSION DeviceExtension, OUT PUCHAR Status)
Definition: readwrite.c:82
#define IN
Definition: typedefs.h:38
#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
static VOID NTAPI i8042MouQueuePacket(IN PVOID Context)
Definition: mouse.c:48
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define MOUSE_MIDDLE_BUTTON_DOWN
Definition: ntddmou.h:50
#define MOUSE_LEFT_BUTTON_DOWN
Definition: ntddmou.h:46
#define INFO_(ch,...)
Definition: debug.h:159
#define MOU_ENAB
Definition: i8042prt.h:278
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 UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
I8042_MOUSE_TYPE MouseType
Definition: i8042prt.h:198
#define MOUSE_WHEEL
Definition: ntddmou.h:56
char CHAR
Definition: xmlstorage.h:175
#define MOUSE_I8042_HARDWARE
Definition: ntddmou.h:98
COMMON_DEVICE_EXTENSION Common
Definition: kbdclass.h:42
VOID i8042MouHandlePs2pp(IN PI8042_MOUSE_EXTENSION DeviceExtension, IN UCHAR Input)
Definition: ps2pp.c:19
PKINTERRUPT HighestDIRQLInterrupt
Definition: i8042prt.h:88
DRIVER_DISPATCH ForwardIrpAndForget
Definition: i8042prt.h:341
#define ERR_(ch,...)
Definition: debug.h:156
BOOLEAN NTAPI KeInsertQueueDpc(IN PKDPC Dpc, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: dpc.c:724
LONG NTSTATUS
Definition: precomp.h:26
Definition: arc.h:84
#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
struct _MOUSE_INPUT_DATA MOUSE_INPUT_DATA
I8042_SETTINGS Settings
Definition: i8042prt.h:81
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75
_Out_ PKIRQL Irql
Definition: csq.h:179
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
#define I8042PRT_TAG
Definition: i8042prt.h:12
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
USHORT Flags
Definition: ntddmou.h:78
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define MOUSE_NACK
Definition: i8042prt.h:287
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define WHEEL_DELTA
Definition: treelist.c:99
#define BALLPOINT_I8042_HARDWARE
Definition: ntddmou.h:100
VOID i8042MouHandle(IN PI8042_MOUSE_EXTENSION DeviceExtension, IN UCHAR Output)
Definition: mouse.c:68
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
ULONG RawButtons
Definition: ntddmou.h:86
long LONG
Definition: pedump.c:60
ULONG InputDataQueueLength
Definition: ntddmou.h:112
#define MOUSE_BUTTON_4_DOWN
Definition: ntddmou.h:52
VOID NTAPI KeReleaseInterruptSpinLock(IN PKINTERRUPT Interrupt, IN KIRQL OldIrql)
Definition: spinlock.c:165
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
#define __analysis_assume(expr)
Definition: sal.h:1111
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
MOUSE_TIMEOUT_STATE MouseTimeoutState
Definition: i8042prt.h:194
switch(r->id)
Definition: btrfs.c:2743
BOOLEAN i8042PacketIsr(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR Output)
Definition: i8042prt.c:272
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:675
#define TRACE_(x)
Definition: compat.h:66
#define IOCTL_INTERNAL_I8042_MOUSE_WRITE_BUFFER
Definition: ntdd8042.h:51
_In_ LARGE_INTEGER _In_opt_ PKDPC Dpc
Definition: kefuncs.h:524
BOOLEAN NTAPI KeCancelTimer(IN OUT PKTIMER Timer)
Definition: timerobj.c:206
MOUSE_ATTRIBUTES MouseAttributes
Definition: i8042prt.h:182
NTSTATUS i8042MouInitialize(IN PI8042_MOUSE_EXTENSION DeviceExtension)
Definition: mouse.c:224
#define WHEELMOUSE_I8042_HARDWARE
Definition: ntddmou.h:102
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define MOUSE_MOVE_RELATIVE
Definition: ntddmou.h:67
static KDEFERRED_ROUTINE i8042MouDpcRoutine
Definition: mouse.c:21
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
struct _MOUSE_ATTRIBUTES * PMOUSE_ATTRIBUTES
static KDEFERRED_ROUTINE i8042DpcRoutineMouseTimeout
Definition: mouse.c:22
#define MOUSE_LEFT_BUTTON_UP
Definition: ntddmou.h:47
#define IOCTL_INTERNAL_MOUSE_DISCONNECT
Definition: kbdmou.h:71
#define MOUSE_ERROR
Definition: i8042prt.h:286
#define MOUSE_RIGHT_BUTTON_DOWN
Definition: ntddmou.h:48
KIRQL NTAPI KeAcquireInterruptSpinLock(IN PKINTERRUPT Interrupt)
Definition: spinlock.c:148
PVOID ClassService
Definition: kbdmou.h:82
USHORT ButtonData
Definition: ntddmou.h:83
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
unsigned char UCHAR
Definition: xmlstorage.h:181
char * PBOOLEAN
Definition: retypes.h:11
VOID(STDAPICALLTYPE * PSERVICE_CALLBACK_ROUTINE)(IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2, IN OUT PVOID SystemArgument3)
Definition: kbdmou.h:86
#define MOUSE_CONNECTED
Definition: i8042prt.h:73
USHORT ButtonFlags
Definition: ntddmou.h:82
Definition: ketypes.h:687
INTERNAL_I8042_HOOK_MOUSE MouseHook
Definition: i8042prt.h:179
Definition: arc.h:85
static VOID i8042MouInputTestTimeout(IN PI8042_MOUSE_EXTENSION DeviceExtension)
Definition: mouse.c:566
#define MOUSE_ACK
Definition: i8042prt.h:285
struct tm * Now
Definition: output.c:19
#define IOCTL_MOUSE_QUERY_ATTRIBUTES
Definition: ntddmou.h:32
BOOLEAN NTAPI i8042MouInterruptService(IN PKINTERRUPT Interrupt, PVOID Context)
Definition: mouse.c:904
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
_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
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:675
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:78
__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
ULONG SampleRate
Definition: i8042prt.h:39
static ULONG Timeout
Definition: ping.c:61
#define IOCTL_INTERNAL_I8042_HOOK_MOUSE
Definition: ntdd8042.h:45
unsigned short USHORT
Definition: pedump.c:61
MOUSE_STATE MouseState
Definition: i8042prt.h:184
CONNECT_DATA MouseData
Definition: i8042prt.h:178
#define i8042ReadMouseData(DeviceExtension, Data)
Definition: i8042prt.h:407
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
MOUSE_RESET_SUBSTATE MouseResetState
Definition: i8042prt.h:186
BOOLEAN MouseTimeoutActive
Definition: i8042prt.h:195
OUT PI8042_MOUSE_ISR IsrRoutine
Definition: ntdd8042.h:198
#define DPRINT1
Definition: precomp.h:8
static LARGE_INTEGER Counter
Definition: clock.c:43
ULONG PollStatusIterations
Definition: i8042prt.h:33
#define OUT
Definition: typedefs.h:39
struct tagContext Context
Definition: acpixf.h:1012
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:565
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
char * cleanup(char *str)
Definition: wpickclick.c:99
NTSTATUS i8042ReadDataWait(IN PPORT_DEVICE_EXTENSION DeviceExtension, OUT PUCHAR Data)
Definition: readwrite.c:95
NTSTATUS NTAPI i8042MouInternalDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: mouse.c:383
#define MOUSE_BUTTON_5_DOWN
Definition: ntddmou.h:54
static BOOLEAN i8042MouCallIsrHook(IN PI8042_MOUSE_EXTENSION DeviceExtension, IN UCHAR Status, IN UCHAR Input, OUT PBOOLEAN ToReturn)
Definition: mouse.c:598
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
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:2777
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
ULONGLONG NTAPI KeQueryInterruptTime(VOID)
Definition: clock.c:203
VOID NTAPI KeStallExecutionProcessor(IN ULONG MicroSeconds)
Definition: ntoskrnl.c:99
IN PI8042_ISR_WRITE_PORT IsrWritePort
Definition: ntdd8042.h:199
#define CTRL_WRITE_MOUSE
Definition: i8042prt.h:228
ULONG MouseResolution
Definition: i8042prt.h:29
VOID i8042MouHandleButtons(IN PI8042_MOUSE_EXTENSION DeviceExtension, IN USHORT Mask)
Definition: mouse.c:191
PDEVICE_OBJECT ClassDeviceObject
Definition: kbdmou.h:81
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:675