ReactOS 0.4.17-dev-683-g0dafdc5
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
21static KDEFERRED_ROUTINE i8042MouDpcRoutine;
22static KDEFERRED_ROUTINE i8042DpcRoutineMouseTimeout;
23
24/*
25 * These functions are callbacks for filter driver custom interrupt
26 * service routines.
27 */
28static VOID NTAPI
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
45}
46
47static 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
67VOID
69 IN PI8042_MOUSE_EXTENSION DeviceExtension,
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)
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, except when the
132 * host's PS/2 emulation already reports it that way
133 * (Hyper-V on Windows 11 24H2+, see CORE-20561) */
135 MouseInput->LastY = -MouseInput->LastY;
136
137 if (DeviceExtension->MouseType == GenericPS2 ||
138 DeviceExtension->MouseType == Ps2pp)
139 {
141 DeviceExtension,
145 DeviceExtension->MouseHook.QueueMousePacket(DeviceExtension->MouseHook.CallContext);
146 DeviceExtension->MouseState = MouseIdle;
147 }
148 else
149 {
150 DeviceExtension->MouseState = ZMovement;
151 }
152 break;
153
154 case ZMovement:
155 Scroll = Output & 0x0f;
156 if (Scroll & 8)
157 Scroll |= 0xf0;
158
159 if (Scroll)
160 {
161 MouseInput->RawButtons |= MOUSE_WHEEL;
162 MouseInput->ButtonData = (USHORT)(Scroll * -WHEEL_DELTA);
163 }
164
165 if (DeviceExtension->MouseType == IntellimouseExplorer)
166 {
167 if (Output & 16)
168 MouseInput->RawButtons |= MOUSE_BUTTON_4_DOWN;
169 if (Output & 32)
170 MouseInput->RawButtons |= MOUSE_BUTTON_5_DOWN;
171 }
173 DeviceExtension,
179 DeviceExtension->MouseHook.QueueMousePacket(DeviceExtension->MouseHook.CallContext);
180 DeviceExtension->MouseState = MouseIdle;
181 break;
182
183 default:
184 ERR_(I8042PRT, "Unexpected state 0x%lx!\n", DeviceExtension->MouseState);
185 ASSERT(FALSE);
186 }
187}
188
189/*
190 * Updates ButtonFlags according to RawButtons and a saved state;
191 * Only takes in account the bits that are set in Mask
192 */
193VOID
195 IN PI8042_MOUSE_EXTENSION DeviceExtension,
196 IN USHORT Mask)
197{
198 PMOUSE_INPUT_DATA MouseInput;
199 USHORT NewButtonData;
200 USHORT ButtonDiff;
201
202 MouseInput = DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer;
203 NewButtonData = (USHORT)(MouseInput->RawButtons & Mask);
204 ButtonDiff = (NewButtonData ^ DeviceExtension->MouseButtonState) & Mask;
205
206 /* Note that the defines are such:
207 * MOUSE_LEFT_BUTTON_DOWN 1
208 * MOUSE_LEFT_BUTTON_UP 2
209 */
210 MouseInput->ButtonFlags |= (NewButtonData & ButtonDiff) |
211 (((~(NewButtonData)) << 1) & (ButtonDiff << 1)) |
212 (MouseInput->RawButtons & 0xfc00);
213
214 INFO_(I8042PRT, "Left raw/up/down: %u/%u/%u\n",
217 MouseInput->ButtonFlags & MOUSE_LEFT_BUTTON_UP);
218
219 DeviceExtension->MouseButtonState =
220 (DeviceExtension->MouseButtonState & ~Mask) | (NewButtonData & Mask);
221}
222
223/* Does final initializations for the mouse. This method
224 * is called just before connecting the interrupt.
225 */
228 IN PI8042_MOUSE_EXTENSION DeviceExtension)
229{
231 UCHAR Value;
232
233 /* Enable the PS/2 mouse port */
234 i8042Write(DeviceExtension->Common.PortDeviceExtension, DeviceExtension->Common.PortDeviceExtension->ControlPort, MOUSE_ENAB);
235
236 /* Enable the mouse */
237 if(!i8042IsrWritePort(DeviceExtension->Common.PortDeviceExtension, MOU_ENAB, CTRL_WRITE_MOUSE))
238 {
239 WARN_(I8042PRT, "Failed to enable mouse!\n");
241 }
242
243 Status = i8042ReadDataWait(DeviceExtension->Common.PortDeviceExtension, &Value);
244 if (!NT_SUCCESS(Status))
245 {
246 WARN_(I8042PRT, "Failed to read the response of MOU_ENAB, status 0x%08lx\n", Status);
247 return Status;
248 }
249
250 if(Value == MOUSE_ACK)
251 {
252 INFO_(I8042PRT, "Mouse was enabled successfully!\n");
253 return STATUS_SUCCESS;
254 }
255
256 WARN_(I8042PRT, "Got 0x%02x instead of 0xFA\n", Value);
258}
259
260static VOID NTAPI
262 IN PKDPC Dpc,
266{
267 PI8042_MOUSE_EXTENSION DeviceExtension;
268 PPORT_DEVICE_EXTENSION PortDeviceExtension;
269 ULONG MouseTransferred = 0;
270 ULONG MouseInBufferCopy;
271 KIRQL Irql;
273
277
279 DeviceExtension = DeferredContext;
280 PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension;
281
282 switch (DeviceExtension->MouseTimeoutState)
283 {
284 case TimeoutStart:
285 {
286 DeviceExtension->MouseTimeoutState = NoChange;
287 if (DeviceExtension->MouseTimeoutActive &&
288 !KeCancelTimer(&DeviceExtension->TimerMouseTimeout))
289 {
290 /* The timer fired already, give up */
291 DeviceExtension->MouseTimeoutActive = FALSE;
292 return;
293 }
294
295 Timeout.QuadPart = -15000000; /* 1.5 seconds, should be enough */
296
298 &DeviceExtension->TimerMouseTimeout,
299 Timeout,
300 &DeviceExtension->DpcMouseTimeout);
301 DeviceExtension->MouseTimeoutActive = TRUE;
302 return;
303 }
304
305 case TimeoutCancel:
306 {
307 DeviceExtension->MouseTimeoutState = NoChange;
308 KeCancelTimer(&DeviceExtension->TimerMouseTimeout);
309 DeviceExtension->MouseTimeoutActive = FALSE;
310 }
311
312 default:
313 ;/* nothing, don't want a warning */
314 }
315
316 /* Should be unlikely */
317 if (!DeviceExtension->MouseComplete)
318 return;
319
321
322 DeviceExtension->MouseComplete = FALSE;
323 MouseInBufferCopy = DeviceExtension->MouseInBuffer;
324
326
327 TRACE_(I8042PRT, "Send a mouse packet\n");
328
329 if (!DeviceExtension->MouseData.ClassService)
330 return;
331
332 INFO_(I8042PRT, "Sending %lu mouse move(s)\n", MouseInBufferCopy);
334 DeviceExtension->MouseData.ClassDeviceObject,
335 DeviceExtension->MouseBuffer,
336 DeviceExtension->MouseBuffer + MouseInBufferCopy,
337 &MouseTransferred);
338
340 DeviceExtension->MouseInBuffer -= MouseTransferred;
341 if (DeviceExtension->MouseInBuffer)
343 DeviceExtension->MouseBuffer,
344 DeviceExtension->MouseBuffer + MouseTransferred,
345 DeviceExtension->MouseInBuffer * sizeof(MOUSE_INPUT_DATA));
347}
348
349/* This timer DPC will be called when the mouse reset times out.
350 * I'll just send the 'disable mouse port' command to the controller
351 * and say the mouse doesn't exist.
352 */
353static VOID NTAPI
355 IN PKDPC Dpc,
359{
360 PI8042_MOUSE_EXTENSION DeviceExtension;
361 PPORT_DEVICE_EXTENSION PortDeviceExtension;
362 KIRQL Irql;
363
367
369 DeviceExtension = DeferredContext;
370 PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension;
371
373
374 WARN_(I8042PRT, "Mouse initialization timeout! (substate %x)\n",
375 DeviceExtension->MouseResetState);
376
377 PortDeviceExtension->Flags &= ~MOUSE_PRESENT;
378
380}
381
382/*
383 * Runs the mouse IOCTL_INTERNAL dispatch.
384 */
388 IN PIRP Irp)
389{
391 PI8042_MOUSE_EXTENSION DeviceExtension;
393
395 Irp->IoStatus.Information = 0;
396 DeviceExtension = (PI8042_MOUSE_EXTENSION)DeviceObject->DeviceExtension;
397
398 switch (Stack->Parameters.DeviceIoControl.IoControlCode)
399 {
401 {
402 SIZE_T Size;
404 PI8042_HOOK_WORKITEM WorkItemData = NULL;
405
406 TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_MOUSE_CONNECT\n");
407 if (Stack->Parameters.DeviceIoControl.InputBufferLength != sizeof(CONNECT_DATA))
408 {
410 goto cleanup;
411 }
412
413 DeviceExtension->MouseData =
414 *((PCONNECT_DATA)Stack->Parameters.DeviceIoControl.Type3InputBuffer);
415
416 /* Send IOCTL_INTERNAL_I8042_HOOK_MOUSE to device stack */
418 if (!WorkItem)
419 {
420 WARN_(I8042PRT, "IoAllocateWorkItem() failed\n");
422 goto cleanup;
423 }
424 WorkItemData = ExAllocatePoolWithTag(
426 sizeof(I8042_HOOK_WORKITEM),
428 if (!WorkItemData)
429 {
430 WARN_(I8042PRT, "ExAllocatePoolWithTag() failed\n");
432 goto cleanup;
433 }
434 WorkItemData->WorkItem = WorkItem;
435 WorkItemData->Irp = Irp;
436
437 /* Initialize extension */
438 DeviceExtension->Common.Type = Mouse;
440 DeviceExtension->MouseBuffer = ExAllocatePoolWithTag(
442 Size,
444 if (!DeviceExtension->MouseBuffer)
445 {
446 WARN_(I8042PRT, "ExAllocatePoolWithTag() failed\n");
448 goto cleanup;
449 }
450 RtlZeroMemory(DeviceExtension->MouseBuffer, Size);
451 DeviceExtension->MouseAttributes.InputDataQueueLength =
454 &DeviceExtension->DpcMouse,
456 DeviceExtension);
458 &DeviceExtension->DpcMouseTimeout,
460 DeviceExtension);
461 KeInitializeTimer(&DeviceExtension->TimerMouseTimeout);
462 DeviceExtension->Common.PortDeviceExtension->MouseExtension = DeviceExtension;
463 DeviceExtension->Common.PortDeviceExtension->Flags |= MOUSE_CONNECTED;
464
466 DeviceExtension->MouseState = MouseResetting;
467 DeviceExtension->MouseResetState = ExpectingReset;
470 DeviceExtension->MouseHook.CallContext = DeviceExtension;
474 WorkItemData);
476 break;
477
478cleanup:
479 if (DeviceExtension->MouseBuffer)
480 ExFreePoolWithTag(DeviceExtension->MouseBuffer, I8042PRT_TAG);
481 if (WorkItem)
483 if (WorkItemData)
484 ExFreePoolWithTag(WorkItemData, I8042PRT_TAG);
485 break;
486 }
488 {
489 TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_MOUSE_DISCONNECT\n");
490 /* MSDN says that operation is to implemented.
491 * To implement it, we just have to do:
492 * DeviceExtension->MouseData.ClassService = NULL;
493 */
495 break;
496 }
498 {
500 TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_I8042_HOOK_MOUSE\n");
501 if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(INTERNAL_I8042_HOOK_MOUSE))
502 {
504 break;
505 }
506 MouseHook = (PINTERNAL_I8042_HOOK_MOUSE)Stack->Parameters.DeviceIoControl.Type3InputBuffer;
507
508 DeviceExtension->MouseHook.Context = MouseHook->Context;
509 if (MouseHook->IsrRoutine)
510 DeviceExtension->MouseHook.IsrRoutine = MouseHook->IsrRoutine;
511
513 break;
514 }
516 {
517 DPRINT1("IOCTL_INTERNAL_I8042_MOUSE_WRITE_BUFFER not implemented\n");
519 break;
520 }
522 {
523 DPRINT1("IOCTL_INTERNAL_I8042_MOUSE_START_INFORMATION not implemented\n");
525 break;
526 }
528 {
529 TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_MOUSE_QUERY_ATTRIBUTES\n");
530 if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUSE_ATTRIBUTES))
531 {
533 break;
534 }
535
536 *(PMOUSE_ATTRIBUTES) Irp->AssociatedIrp.SystemBuffer = DeviceExtension->MouseAttributes;
537 Irp->IoStatus.Information = sizeof(MOUSE_ATTRIBUTES);
539 break;
540 }
541 default:
542 {
543 ERR_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / unknown ioctl code 0x%lx\n",
544 Stack->Parameters.DeviceIoControl.IoControlCode);
545 ASSERT(FALSE);
547 }
548 }
549
550 if (Status != STATUS_PENDING)
551 {
552 Irp->IoStatus.Status = Status;
554 }
555 return Status;
556}
557
558/* Test if packets are taking too long to come in. If they do, we
559 * might have gotten out of sync and should just drop what we have.
560 *
561 * If we want to be totally right, we'd also have to keep a count of
562 * errors, and totally reset the mouse after too much of them (can
563 * happen if the user is using a KVM switch and an OS on another port
564 * resets the mouse, or if the user hotplugs the mouse, or if we're just
565 * generally unlucky). Also note the input parsing routine where we
566 * drop invalid input packets.
567 */
568static VOID
570 IN PI8042_MOUSE_EXTENSION DeviceExtension)
571{
573
574 if (DeviceExtension->MouseState == MouseExpectingACK ||
575 DeviceExtension->MouseState == MouseResetting)
576 return;
577
578 Now.QuadPart = KeQueryInterruptTime();
579
580 if (DeviceExtension->MouseState != MouseIdle) {
581 /* Check if the last byte came too long ago */
582 if (Now.QuadPart - DeviceExtension->MousePacketStartTime.QuadPart >
583 DeviceExtension->Common.PortDeviceExtension->Settings.MouseSynchIn100ns)
584 {
585 WARN_(I8042PRT, "Mouse input packet timeout\n");
586 DeviceExtension->MouseState = MouseIdle;
587 }
588 }
589
590 if (DeviceExtension->MouseState == MouseIdle)
591 DeviceExtension->MousePacketStartTime.QuadPart = Now.QuadPart;
592}
593
594/*
595 * Call the customization hook. The ToReturn parameter is about wether
596 * we should go on with the interrupt. The return value is what
597 * we should return (indicating to the system wether someone else
598 * should try to handle the interrupt)
599 */
600static BOOLEAN
602 IN PI8042_MOUSE_EXTENSION DeviceExtension,
604 IN UCHAR Input,
605 OUT PBOOLEAN ToReturn)
606{
607 BOOLEAN HookReturn, HookContinue;
608
609 HookContinue = FALSE;
610
611 if (DeviceExtension->MouseHook.IsrRoutine)
612 {
613 HookReturn = DeviceExtension->MouseHook.IsrRoutine(
614 DeviceExtension->MouseHook.Context,
615 DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer,
616 &DeviceExtension->Common.PortDeviceExtension->Packet,
617 Status,
618 &Input,
619 &HookContinue,
620 &DeviceExtension->MouseState,
621 &DeviceExtension->MouseResetState);
622
623 if (!HookContinue)
624 {
625 *ToReturn = HookReturn;
626 return TRUE;
627 }
628 }
629 return FALSE;
630}
631
632static BOOLEAN
634 IN PI8042_MOUSE_EXTENSION DeviceExtension,
636 IN UCHAR Value)
637{
638 PPORT_DEVICE_EXTENSION PortDeviceExtension;
639 BOOLEAN ToReturn = FALSE;
640
641 if (i8042MouCallIsrHook(DeviceExtension, Status, Value, &ToReturn))
642 return ToReturn;
643
644 if (MouseIdle == DeviceExtension->MouseState)
645 {
646 /* Magic packet value that indicates a reset */
647 if (0xAA == Value)
648 {
649 WARN_(I8042PRT, "Hot plugged mouse!\n");
650 DeviceExtension->MouseState = MouseResetting;
651 DeviceExtension->MouseResetState = ExpectingReset;
652 }
653 else
654 return FALSE;
655 }
656 else if (MouseResetting != DeviceExtension->MouseState)
657 return FALSE;
658
659 DeviceExtension->MouseTimeoutState = TimeoutStart;
660 PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension;
661
662 switch ((ULONG)DeviceExtension->MouseResetState)
663 {
664 case ExpectingReset:
665 if (MOUSE_ACK == Value)
666 {
667 WARN_(I8042PRT, "Dropping extra ACK\n");
668 return TRUE;
669 }
670
671 /* First, 0xFF is sent. The mouse is supposed to say AA00 if ok, FC00 if not. */
672 if (0xAA == Value)
673 {
674 DeviceExtension->MouseResetState++;
675 }
676 else
677 {
678 PortDeviceExtension->Flags &= ~MOUSE_PRESENT;
679 DeviceExtension->MouseState = MouseIdle;
680 WARN_(I8042PRT, "Mouse returned bad reset reply: %x (expected aa)\n", Value);
681 }
682 return TRUE;
683 case ExpectingResetId:
684 if (MOUSE_ACK == Value)
685 {
686 WARN_(I8042PRT, "Dropping extra ACK #2\n");
687 return TRUE;
688 }
689
690 if (0x00 == Value)
691 {
692 DeviceExtension->MouseResetState++;
693 DeviceExtension->MouseType = GenericPS2;
694 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF2);
695 }
696 else
697 {
698 PortDeviceExtension->Flags &= ~MOUSE_PRESENT;
699 DeviceExtension->MouseState = MouseIdle;
700 WARN_(I8042PRT, "Mouse returned bad reset reply part two: %x (expected 0)\n", Value);
701 }
702 return TRUE;
704 if (MOUSE_ACK == Value)
705 {
706 DeviceExtension->MouseResetState++;
707 }
708 else if (MOUSE_NACK == Value || MOUSE_ERROR == Value)
709 {
710 DeviceExtension->MouseResetState++;
711 /* Act as if 00 (normal mouse) was received */
712 WARN_(I8042PRT, "Mouse doesn't support 0xd2, (returns %x, expected %x), faking\n", Value, MOUSE_ACK);
713 i8042MouResetIsr(DeviceExtension, Status, 0);
714 }
715 return TRUE;
717 switch (Value)
718 {
719 case 0x02:
720 DeviceExtension->MouseAttributes.MouseIdentifier =
722 break;
723 case 0x03:
724 case 0x04:
725 DeviceExtension->MouseAttributes.MouseIdentifier =
727 break;
728 default:
729 DeviceExtension->MouseAttributes.MouseIdentifier =
731 }
732 DeviceExtension->MouseResetState++;
733 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xE8);
734 return TRUE;
736 DeviceExtension->MouseResetState++;
737 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0x00);
738 return TRUE;
740 DeviceExtension->MouseResetState = ExpectingSetScaling1to1ACK;
741 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xE6);
742 return TRUE;
745 DeviceExtension->MouseResetState++;
746 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xE6);
747 return TRUE;
749 DeviceExtension->MouseResetState++;
750 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xE9);
751 return TRUE;
753 DeviceExtension->MouseResetState++;
754 return TRUE;
756 DeviceExtension->MouseLogiBuffer[0] = Value;
757 DeviceExtension->MouseResetState++;
758 return TRUE;
760 DeviceExtension->MouseLogiBuffer[1] = Value;
761 DeviceExtension->MouseResetState++;
762 return TRUE;
764 DeviceExtension->MouseLogiBuffer[2] = Value;
765 /* Now MouseLogiBuffer is a set of info. If the second
766 * byte is 0, the mouse didn't understand the magic
767 * code. Otherwise, it it a Logitech and the second byte
768 * is the number of buttons, bit 7 of the first byte tells
769 * if it understands special E7 commands, the rest is an ID.
770 */
771 if (DeviceExtension->MouseLogiBuffer[1])
772 {
773 DeviceExtension->MouseAttributes.NumberOfButtons =
774 DeviceExtension->MouseLogiBuffer[1];
775 DeviceExtension->MouseType = Ps2pp;
776 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF3);
777 DeviceExtension->MouseResetState = ExpectingSetSamplingRateACK;
778 /* TODO: Go through EnableWheel and Enable5Buttons */
779 return TRUE;
780 }
781 DeviceExtension->MouseResetState = EnableWheel;
782 i8042MouResetIsr(DeviceExtension, Status, Value);
783 return TRUE;
784 case EnableWheel:
785 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF3);
786 DeviceExtension->MouseResetState = 1001;
787 return TRUE;
788 case 1001:
789 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xC8);
790 DeviceExtension->MouseResetState++;
791 return TRUE;
792 case 1002:
793 case 1004:
794 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF3);
795 DeviceExtension->MouseResetState++;
796 return TRUE;
797 case 1003:
798 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0x64);
799 DeviceExtension->MouseResetState++;
800 return TRUE;
801 case 1005:
802 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0x50);
803 DeviceExtension->MouseResetState++;
804 return TRUE;
805 case 1006:
806 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF2);
807 DeviceExtension->MouseResetState++;
808 return TRUE;
809 case 1007:
810 /* Ignore ACK */
811 DeviceExtension->MouseResetState++;
812 return TRUE;
813 case 1008:
814 if (0x03 == Value) {
815 /* It's either an Intellimouse or Intellimouse Explorer. */
816 DeviceExtension->MouseAttributes.NumberOfButtons = 3;
817 DeviceExtension->MouseAttributes.MouseIdentifier =
819 DeviceExtension->MouseType = Intellimouse;
820 DeviceExtension->MouseResetState = Enable5Buttons;
821 i8042MouResetIsr(DeviceExtension, Status, Value);
822 }
823 else
824 {
825 /* Just set the default settings and be done */
826 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF3);
827 DeviceExtension->MouseResetState = ExpectingSetSamplingRateACK;
828 }
829 return TRUE;
830 case Enable5Buttons:
831 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF3);
832 DeviceExtension->MouseResetState = 1021;
833 return TRUE;
834 case 1022:
835 case 1024:
836 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF3);
837 DeviceExtension->MouseResetState++;
838 return TRUE;
839 case 1021:
840 case 1023:
841 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xC8);
842 DeviceExtension->MouseResetState++;
843 return TRUE;
844 case 1025:
845 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0x50);
846 DeviceExtension->MouseResetState++;
847 return TRUE;
848 case 1026:
849 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF2);
850 DeviceExtension->MouseResetState++;
851 return TRUE;
852 case 1027:
853 if (0x04 == Value)
854 {
855 DeviceExtension->MouseAttributes.NumberOfButtons = 5;
856 DeviceExtension->MouseAttributes.MouseIdentifier =
858 DeviceExtension->MouseType = IntellimouseExplorer;
859 }
860 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF3);
861 DeviceExtension->MouseResetState = ExpectingSetSamplingRateACK;
862 return TRUE;
864 DeviceExtension->MouseHook.IsrWritePort(
865 DeviceExtension->MouseHook.CallContext,
866 (UCHAR)DeviceExtension->MouseAttributes.SampleRate);
867 DeviceExtension->MouseResetState++;
868 return TRUE;
870 if (MOUSE_NACK == Value)
871 {
872 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0x3C);
873 DeviceExtension->MouseAttributes.SampleRate = (USHORT)PortDeviceExtension->Settings.SampleRate;
874 DeviceExtension->MouseResetState = 1040;
875 return TRUE;
876 }
877 case 1040: /* Fallthrough */
878 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xE8);
879 DeviceExtension->MouseResetState = ExpectingFinalResolutionACK;
880 return TRUE;
882 DeviceExtension->MouseHook.IsrWritePort(
883 DeviceExtension->MouseHook.CallContext,
884 (UCHAR)(PortDeviceExtension->Settings.MouseResolution & 0xff));
885 INFO_(I8042PRT, "Mouse resolution %lu\n",
886 PortDeviceExtension->Settings.MouseResolution);
887 DeviceExtension->MouseResetState = ExpectingFinalResolutionValueACK;
888 return TRUE;
890 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF4);
891 DeviceExtension->MouseResetState = ExpectingEnableACK;
892 return TRUE;
894 PortDeviceExtension->Flags |= MOUSE_PRESENT;
895 DeviceExtension->MouseState = MouseIdle;
896 DeviceExtension->MouseTimeoutState = TimeoutCancel;
897 INFO_(I8042PRT, "Mouse type = %u\n", DeviceExtension->MouseType);
898 return TRUE;
899 default:
900 if (DeviceExtension->MouseResetState < 100 || DeviceExtension->MouseResetState > 999)
901 ERR_(I8042PRT, "MouseResetState went out of range: %lu\n", DeviceExtension->MouseResetState);
902 return FALSE;
903 }
904}
905
910{
911 PI8042_MOUSE_EXTENSION DeviceExtension;
912 PPORT_DEVICE_EXTENSION PortDeviceExtension;
914 UCHAR Output = 0, PortStatus = 0;
916
918
920 DeviceExtension = Context;
921 PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension;
922 Counter = PortDeviceExtension->Settings.PollStatusIterations;
923
924 while (Counter)
925 {
926 Status = i8042ReadStatus(PortDeviceExtension, &PortStatus);
927 if (!NT_SUCCESS(Status))
928 {
929 WARN_(I8042PRT, "i8042ReadStatus() failed with status 0x%08lx\n", Status);
930 return FALSE;
931 }
932 Status = i8042ReadMouseData(PortDeviceExtension, &Output);
933 if (NT_SUCCESS(Status))
934 break;
936 Counter--;
937 }
938 if (Counter == 0)
939 {
940 WARN_(I8042PRT, "Spurious i8042 mouse interrupt\n");
941 return FALSE;
942 }
943
944 INFO_(I8042PRT, "Got: 0x%02x\n", Output);
945
946 if (i8042PacketIsr(PortDeviceExtension, Output))
947 {
948 if (PortDeviceExtension->PacketComplete)
949 {
950 TRACE_(I8042PRT, "Packet complete\n");
951 KeInsertQueueDpc(&DeviceExtension->DpcMouse, NULL, NULL);
952 }
953 TRACE_(I8042PRT, "Irq eaten by packet\n");
954 return TRUE;
955 }
956
957 TRACE_(I8042PRT, "Irq is mouse input\n");
958
959 i8042MouInputTestTimeout(DeviceExtension);
960
961 if (i8042MouResetIsr(DeviceExtension, PortStatus, Output))
962 {
963 TRACE_(I8042PRT, "Handled by ResetIsr or hooked Isr\n");
964 if (NoChange != DeviceExtension->MouseTimeoutState) {
965 KeInsertQueueDpc(&DeviceExtension->DpcMouse, NULL, NULL);
966 }
967 return TRUE;
968 }
969
970 if (DeviceExtension->MouseType == Ps2pp)
971 i8042MouHandlePs2pp(DeviceExtension, Output);
972 else
973 i8042MouHandle(DeviceExtension, Output);
974
975 return TRUE;
976}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
unsigned char BOOLEAN
Definition: actypes.h:127
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
_In_ PIRP Irp
Definition: csq.h:116
_Out_ PKIRQL Irql
Definition: csq.h:179
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define TRACE_(x)
Definition: compat.h:76
static void cleanup(void)
Definition: main.c:1335
BOOLEAN NTAPI KeInsertQueueDpc(IN PKDPC Dpc, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: dpc.c:725
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:712
switch(r->id)
Definition: btrfs.c:3046
static VOID NTAPI i8042MouQueuePacket(IN PVOID Context)
Definition: mouse.c:48
static BOOLEAN i8042MouCallIsrHook(IN PI8042_MOUSE_EXTENSION DeviceExtension, IN UCHAR Status, IN UCHAR Input, OUT PBOOLEAN ToReturn)
Definition: mouse.c:601
static KDEFERRED_ROUTINE i8042DpcRoutineMouseTimeout
Definition: mouse.c:22
NTSTATUS i8042MouInitialize(IN PI8042_MOUSE_EXTENSION DeviceExtension)
Definition: mouse.c:227
static KDEFERRED_ROUTINE i8042MouDpcRoutine
Definition: mouse.c:21
static VOID NTAPI i8042MouIsrWritePort(IN PVOID Context, IN UCHAR Value)
Definition: mouse.c:29
static VOID i8042MouInputTestTimeout(IN PI8042_MOUSE_EXTENSION DeviceExtension)
Definition: mouse.c:569
VOID i8042MouHandle(IN PI8042_MOUSE_EXTENSION DeviceExtension, IN UCHAR Output)
Definition: mouse.c:68
static BOOLEAN i8042MouResetIsr(IN PI8042_MOUSE_EXTENSION DeviceExtension, IN UCHAR Status, IN UCHAR Value)
Definition: mouse.c:633
VOID i8042MouHandleButtons(IN PI8042_MOUSE_EXTENSION DeviceExtension, IN USHORT Mask)
Definition: mouse.c:194
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define NonPagedPool
Definition: env_spec_w32.h:307
unsigned int Mask
Definition: fpcontrol.c:82
Status
Definition: gdiplustypes.h:24
_Outptr_ PUSB_DEVICE_HANDLE _In_ PUSB_DEVICE_HANDLE _In_ USHORT PortStatus
Definition: hubbusif.h:42
ULONG i8042HwFlags
Definition: hwhacks.c:23
BOOLEAN i8042PacketIsr(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR Output)
Definition: i8042prt.c:271
#define MOUSE_ACK
Definition: i8042prt.h:285
#define MOU_ENAB
Definition: i8042prt.h:278
#define i8042ReadMouseData(DeviceExtension, Data)
Definition: i8042prt.h:405
NTSTATUS i8042ReadDataWait(IN PPORT_DEVICE_EXTENSION DeviceExtension, OUT PUCHAR Data)
Definition: readwrite.c:95
KSERVICE_ROUTINE i8042MouInterruptService
Definition: i8042prt.h:367
#define MOUSE_CONNECTED
Definition: i8042prt.h:73
#define CTRL_WRITE_MOUSE
Definition: i8042prt.h:228
#define MOUSE_PRESENT
Definition: i8042prt.h:72
DRIVER_DISPATCH i8042MouInternalDeviceControl
Definition: i8042prt.h:365
@ Intellimouse
Definition: i8042prt.h:170
@ GenericPS2
Definition: i8042prt.h:169
@ Ps2pp
Definition: i8042prt.h:172
@ IntellimouseExplorer
Definition: i8042prt.h:171
struct _I8042_MOUSE_EXTENSION * PI8042_MOUSE_EXTENSION
Definition: i8042prt.h:65
IO_WORKITEM_ROUTINE i8042SendHookWorkItem
Definition: i8042prt.h:295
VOID i8042MouHandlePs2pp(IN PI8042_MOUSE_EXTENSION DeviceExtension, IN UCHAR Input)
Definition: ps2pp.c:19
#define MOUSE_ERROR
Definition: i8042prt.h:286
BOOLEAN i8042IsrWritePort(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR Value, IN UCHAR SelectCmd OPTIONAL)
Definition: readwrite.c:40
@ FL_HYPERV_SKIP_Y_NEGATION
Definition: i8042prt.h:456
DRIVER_DISPATCH ForwardIrpAndForget
Definition: i8042prt.h:341
#define MOUSE_ENAB
Definition: i8042prt.h:223
@ TimeoutStart
Definition: i8042prt.h:46
@ TimeoutCancel
Definition: i8042prt.h:47
@ NoChange
Definition: i8042prt.h:45
NTSTATUS i8042ReadStatus(IN PPORT_DEVICE_EXTENSION DeviceExtension, OUT PUCHAR Status)
Definition: readwrite.c:82
@ Mouse
Definition: i8042prt.h:116
#define I8042PRT_TAG
Definition: i8042prt.h:12
BOOLEAN i8042Write(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN PUCHAR addr, IN UCHAR data)
Definition: readwrite.c:199
#define MOUSE_NACK
Definition: i8042prt.h:287
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
Definition: iowork.c:40
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75
IoMarkIrpPending(Irp)
struct _CONNECT_DATA * PCONNECT_DATA
VOID(STDAPICALLTYPE * PSERVICE_CALLBACK_ROUTINE)(IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2, IN OUT PVOID SystemArgument3)
Definition: kbdmou.h:86
#define IOCTL_INTERNAL_MOUSE_DISCONNECT
Definition: kbdmou.h:71
#define IOCTL_INTERNAL_MOUSE_CONNECT
Definition: kbdmou.h:68
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define KeStallExecutionProcessor(MicroSeconds)
Definition: precomp.h:27
#define __analysis_assume(expr)
Definition: ms_sal.h:2893
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
#define IOCTL_INTERNAL_I8042_HOOK_MOUSE
Definition: ntdd8042.h:45
@ MouseResetting
Definition: ntdd8042.h:85
@ XMovement
Definition: ntdd8042.h:81
@ YMovement
Definition: ntdd8042.h:82
@ MouseExpectingACK
Definition: ntdd8042.h:84
@ ZMovement
Definition: ntdd8042.h:83
@ MouseIdle
Definition: ntdd8042.h:80
@ ExpectingReadMouseStatusACK
Definition: ntdd8042.h:100
@ ExpectingReadMouseStatusByte1
Definition: ntdd8042.h:101
@ ExpectingSetScaling1to1ACK3
Definition: ntdd8042.h:99
@ Enable5Buttons
Definition: ntdd8042.h:115
@ ExpectingGetDeviceIdValue
Definition: ntdd8042.h:92
@ ExpectingFinalResolutionValueACK
Definition: ntdd8042.h:122
@ ExpectingSetSamplingRateValueACK
Definition: ntdd8042.h:119
@ ExpectingSetResolutionDefaultACK
Definition: ntdd8042.h:93
@ ExpectingSetScaling1to1ACK
Definition: ntdd8042.h:97
@ ExpectingReadMouseStatusByte3
Definition: ntdd8042.h:103
@ ExpectingSetResolutionDefaultValueACK
Definition: ntdd8042.h:94
@ ExpectingReset
Definition: ntdd8042.h:89
@ ExpectingReadMouseStatusByte2
Definition: ntdd8042.h:102
@ ExpectingSetScaling1to1ACK2
Definition: ntdd8042.h:98
@ ExpectingSetSamplingRateACK
Definition: ntdd8042.h:118
@ ExpectingGetDeviceIdACK
Definition: ntdd8042.h:91
@ ExpectingEnableACK
Definition: ntdd8042.h:120
@ ExpectingResetId
Definition: ntdd8042.h:90
@ ExpectingFinalResolutionACK
Definition: ntdd8042.h:121
@ EnableWheel
Definition: ntdd8042.h:114
#define IOCTL_INTERNAL_I8042_MOUSE_START_INFORMATION
Definition: ntdd8042.h:48
struct _INTERNAL_I8042_HOOK_MOUSE * PINTERNAL_I8042_HOOK_MOUSE
#define IOCTL_INTERNAL_I8042_MOUSE_WRITE_BUFFER
Definition: ntdd8042.h:51
#define MOUSE_LEFT_BUTTON_DOWN
Definition: ntddmou.h:46
struct _MOUSE_ATTRIBUTES * PMOUSE_ATTRIBUTES
#define MOUSE_LEFT_BUTTON_UP
Definition: ntddmou.h:47
#define WHEELMOUSE_I8042_HARDWARE
Definition: ntddmou.h:102
#define MOUSE_MIDDLE_BUTTON_DOWN
Definition: ntddmou.h:50
#define BALLPOINT_I8042_HARDWARE
Definition: ntddmou.h:100
#define MOUSE_I8042_HARDWARE
Definition: ntddmou.h:98
#define MOUSE_BUTTON_4_DOWN
Definition: ntddmou.h:52
#define MOUSE_WHEEL
Definition: ntddmou.h:56
struct _MOUSE_INPUT_DATA MOUSE_INPUT_DATA
#define IOCTL_MOUSE_QUERY_ATTRIBUTES
Definition: ntddmou.h:32
#define MOUSE_BUTTON_5_DOWN
Definition: ntddmou.h:54
#define MOUSE_MOVE_RELATIVE
Definition: ntddmou.h:67
#define MOUSE_RIGHT_BUTTON_DOWN
Definition: ntddmou.h:48
#define IoCompleteRequest
Definition: irp.c:1272
KIRQL NTAPI KeAcquireInterruptSpinLock(IN PKINTERRUPT Interrupt)
Definition: spinlock.c:154
VOID NTAPI KeReleaseInterruptSpinLock(IN PKINTERRUPT Interrupt, IN KIRQL OldIrql)
Definition: spinlock.c:171
struct tm * Now
Definition: output.c:19
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
char CHAR
Definition: pedump.c:57
static ULONG Timeout
Definition: ping.c:61
@ Input
Definition: arc.h:93
@ Output
Definition: arc.h:94
#define INFO_(ch,...)
Definition: debug.h:159
#define ERR_(ch,...)
Definition: debug.h:156
#define WARN_(ch,...)
Definition: debug.h:157
#define KeQueryInterruptTime()
Definition: ke.h:37
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
_In_ PVOID Context
Definition: storport.h:2269
PVOID ClassService
Definition: kbdmou.h:82
PDEVICE_OBJECT ClassDeviceObject
Definition: kbdmou.h:81
I8042_DEVICE_TYPE Type
Definition: i8042prt.h:122
PPORT_DEVICE_EXTENSION PortDeviceExtension
Definition: i8042prt.h:134
PIO_WORKITEM WorkItem
Definition: i8042prt.h:203
FDO_DEVICE_EXTENSION Common
Definition: i8042prt.h:177
MOUSE_ATTRIBUTES MouseAttributes
Definition: i8042prt.h:182
I8042_MOUSE_TYPE MouseType
Definition: i8042prt.h:198
MOUSE_TIMEOUT_STATE MouseTimeoutState
Definition: i8042prt.h:194
PMOUSE_INPUT_DATA MouseBuffer
Definition: i8042prt.h:187
BOOLEAN MouseTimeoutActive
Definition: i8042prt.h:195
CONNECT_DATA MouseData
Definition: i8042prt.h:178
INTERNAL_I8042_HOOK_MOUSE MouseHook
Definition: i8042prt.h:179
MOUSE_STATE MouseState
Definition: i8042prt.h:184
MOUSE_RESET_SUBSTATE MouseResetState
Definition: i8042prt.h:186
ULONG MouseDataQueueSize
Definition: i8042prt.h:28
ULONG PollStatusIterations
Definition: i8042prt.h:33
ULONG SampleRate
Definition: i8042prt.h:39
ULONG MouseResolution
Definition: i8042prt.h:29
OUT PI8042_MOUSE_ISR IsrRoutine
Definition: ntdd8042.h:198
IN PI8042_QUEUE_PACKET QueueMousePacket
Definition: ntdd8042.h:200
IN PI8042_ISR_WRITE_PORT IsrWritePort
Definition: ntdd8042.h:199
Definition: ketypes.h:767
ULONG InputDataQueueLength
Definition: ntddmou.h:112
ULONG RawButtons
Definition: ntddmou.h:86
USHORT ButtonData
Definition: ntddmou.h:83
USHORT ButtonFlags
Definition: ntddmou.h:82
USHORT Flags
Definition: ntddmou.h:78
PKINTERRUPT HighestDIRQLInterrupt
Definition: i8042prt.h:88
I8042_SETTINGS Settings
Definition: i8042prt.h:81
PI8042_MOUSE_EXTENSION MouseExtension
Definition: i8042prt.h:86
BOOLEAN PacketComplete
Definition: i8042prt.h:94
COMMON_DEVICE_EXTENSION Common
Definition: kbdclass.h:42
static LARGE_INTEGER Counter
Definition: clock.c:43
#define STATUS_PENDING
Definition: telnetd.h:14
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:282
BOOLEAN NTAPI KeCancelTimer(IN OUT PKTIMER Timer)
Definition: timerobj.c:206
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
#define WHEEL_DELTA
Definition: treelist.c:99
unsigned char UCHAR
Definition: typedefs.h:53
unsigned char * PBOOLEAN
Definition: typedefs.h:53
#define NTAPI
Definition: typedefs.h:36
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2061
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
_Must_inspect_result_ _In_ PWDF_DPC_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFDPC * Dpc
Definition: wdfdpc.h:112
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_INTERRUPT_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFINTERRUPT * Interrupt
Definition: wdfinterrupt.h:379
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
_Must_inspect_result_ _In_ PWDF_WORKITEM_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWORKITEM * WorkItem
Definition: wdfworkitem.h:115
@ DelayedWorkQueue
Definition: extypes.h:190
#define IO_NO_INCREMENT
Definition: iotypes.h:598
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:756
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:755
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:757