ReactOS 0.4.17-dev-653-g1d6dae3
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 354 of file mouse.c.

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}
_Out_ PKIRQL Irql
Definition: csq.h:179
#define NULL
Definition: types.h:112
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define __analysis_assume(expr)
Definition: ms_sal.h:2893
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
KIRQL NTAPI KeAcquireInterruptSpinLock(IN PKINTERRUPT Interrupt)
Definition: spinlock.c:154
VOID NTAPI KeReleaseInterruptSpinLock(IN PKINTERRUPT Interrupt, IN KIRQL OldIrql)
Definition: spinlock.c:171
#define WARN_(ch,...)
Definition: debug.h:157
PPORT_DEVICE_EXTENSION PortDeviceExtension
Definition: i8042prt.h:134
FDO_DEVICE_EXTENSION Common
Definition: i8042prt.h:177
MOUSE_RESET_SUBSTATE MouseResetState
Definition: i8042prt.h:186
PKINTERRUPT HighestDIRQLInterrupt
Definition: i8042prt.h:88
_Must_inspect_result_ _In_ PWDF_DPC_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFDPC * Dpc
Definition: wdfdpc.h:112
_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

◆ i8042MouCallIsrHook()

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

Definition at line 601 of file mouse.c.

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}
unsigned char BOOLEAN
Definition: actypes.h:127
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
Status
Definition: gdiplustypes.h:24
@ Input
Definition: arc.h:93

Referenced by i8042MouResetIsr().

◆ i8042MouDpcRoutine()

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

Definition at line 261 of file mouse.c.

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}
#define TRACE_(x)
Definition: compat.h:76
@ TimeoutStart
Definition: i8042prt.h:46
@ TimeoutCancel
Definition: i8042prt.h:47
@ NoChange
Definition: i8042prt.h:45
VOID(STDAPICALLTYPE * PSERVICE_CALLBACK_ROUTINE)(IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2, IN OUT PVOID SystemArgument3)
Definition: kbdmou.h:86
static ULONG Timeout
Definition: ping.c:61
#define INFO_(ch,...)
Definition: debug.h:159
PVOID ClassService
Definition: kbdmou.h:82
PDEVICE_OBJECT ClassDeviceObject
Definition: kbdmou.h:81
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
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
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint32_t ULONG
Definition: typedefs.h:59

◆ 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)
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}
VOID i8042MouHandleButtons(IN PI8042_MOUSE_EXTENSION DeviceExtension, IN USHORT Mask)
Definition: mouse.c:194
ULONG i8042HwFlags
Definition: hwhacks.c:23
@ GenericPS2
Definition: i8042prt.h:169
@ Ps2pp
Definition: i8042prt.h:172
@ IntellimouseExplorer
Definition: i8042prt.h:171
@ FL_HYPERV_SKIP_Y_NEGATION
Definition: i8042prt.h:456
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
@ XMovement
Definition: ntdd8042.h:81
@ YMovement
Definition: ntdd8042.h:82
@ ZMovement
Definition: ntdd8042.h:83
@ MouseIdle
Definition: ntdd8042.h:80
#define MOUSE_LEFT_BUTTON_DOWN
Definition: ntddmou.h:46
#define MOUSE_MIDDLE_BUTTON_DOWN
Definition: ntddmou.h:50
#define MOUSE_BUTTON_4_DOWN
Definition: ntddmou.h:52
#define MOUSE_WHEEL
Definition: ntddmou.h:56
#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
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
char CHAR
Definition: pedump.c:57
@ Output
Definition: arc.h:94
#define ERR_(ch,...)
Definition: debug.h:156
ULONG RawButtons
Definition: ntddmou.h:86
USHORT ButtonData
Definition: ntddmou.h:83
USHORT Flags
Definition: ntddmou.h:78
#define WHEEL_DELTA
Definition: treelist.c:99

Referenced by i8042MouHandlePs2pp(), and i8042MouInterruptService().

◆ i8042MouHandleButtons()

VOID i8042MouHandleButtons ( IN PI8042_MOUSE_EXTENSION  DeviceExtension,
IN USHORT  Mask 
)

Definition at line 194 of file mouse.c.

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}
unsigned int Mask
Definition: fpcontrol.c:82
#define MOUSE_LEFT_BUTTON_UP
Definition: ntddmou.h:47
USHORT ButtonFlags
Definition: ntddmou.h:82

Referenced by i8042MouHandle(), and i8042MouHandlePs2pp().

◆ i8042MouInitialize()

NTSTATUS i8042MouInitialize ( IN PI8042_MOUSE_EXTENSION  DeviceExtension)

Definition at line 227 of file mouse.c.

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}
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define MOUSE_ACK
Definition: i8042prt.h:285
#define MOU_ENAB
Definition: i8042prt.h:278
NTSTATUS i8042ReadDataWait(IN PPORT_DEVICE_EXTENSION DeviceExtension, OUT PUCHAR Data)
Definition: readwrite.c:95
#define CTRL_WRITE_MOUSE
Definition: i8042prt.h:228
BOOLEAN i8042IsrWritePort(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR Value, IN UCHAR SelectCmd OPTIONAL)
Definition: readwrite.c:40
#define MOUSE_ENAB
Definition: i8042prt.h:223
BOOLEAN i8042Write(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN PUCHAR addr, IN UCHAR data)
Definition: readwrite.c:199
#define STATUS_SUCCESS
Definition: shellext.h:65
unsigned char UCHAR
Definition: typedefs.h:53
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413

Referenced by i8042ConnectMouseInterrupt().

◆ i8042MouInputTestTimeout()

static VOID i8042MouInputTestTimeout ( IN PI8042_MOUSE_EXTENSION  DeviceExtension)
static

Definition at line 569 of file mouse.c.

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}
@ MouseResetting
Definition: ntdd8042.h:85
@ MouseExpectingACK
Definition: ntdd8042.h:84
struct tm * Now
Definition: output.c:19
#define KeQueryInterruptTime()
Definition: ke.h:37

Referenced by i8042MouInterruptService().

◆ i8042MouInternalDeviceControl()

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

Definition at line 386 of file mouse.c.

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}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define DPRINT1
Definition: precomp.h:8
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
static void cleanup(void)
Definition: main.c:1335
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 KDEFERRED_ROUTINE i8042DpcRoutineMouseTimeout
Definition: mouse.c:22
static KDEFERRED_ROUTINE i8042MouDpcRoutine
Definition: mouse.c:21
static VOID NTAPI i8042MouIsrWritePort(IN PVOID Context, IN UCHAR Value)
Definition: mouse.c:29
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NonPagedPool
Definition: env_spec_w32.h:307
#define MOUSE_CONNECTED
Definition: i8042prt.h:73
struct _I8042_MOUSE_EXTENSION * PI8042_MOUSE_EXTENSION
Definition: i8042prt.h:65
IO_WORKITEM_ROUTINE i8042SendHookWorkItem
Definition: i8042prt.h:295
DRIVER_DISPATCH ForwardIrpAndForget
Definition: i8042prt.h:341
@ Mouse
Definition: i8042prt.h:116
#define I8042PRT_TAG
Definition: i8042prt.h:12
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
#define IOCTL_INTERNAL_MOUSE_DISCONNECT
Definition: kbdmou.h:71
#define IOCTL_INTERNAL_MOUSE_CONNECT
Definition: kbdmou.h:68
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define IOCTL_INTERNAL_I8042_HOOK_MOUSE
Definition: ntdd8042.h:45
@ ExpectingReset
Definition: ntdd8042.h:89
#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
struct _MOUSE_ATTRIBUTES * PMOUSE_ATTRIBUTES
struct _MOUSE_INPUT_DATA MOUSE_INPUT_DATA
#define IOCTL_MOUSE_QUERY_ATTRIBUTES
Definition: ntddmou.h:32
#define IoCompleteRequest
Definition: irp.c:1272
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
I8042_DEVICE_TYPE Type
Definition: i8042prt.h:122
PIO_WORKITEM WorkItem
Definition: i8042prt.h:203
MOUSE_ATTRIBUTES MouseAttributes
Definition: i8042prt.h:182
INTERNAL_I8042_HOOK_MOUSE MouseHook
Definition: i8042prt.h:179
MOUSE_STATE MouseState
Definition: i8042prt.h:184
ULONG MouseDataQueueSize
Definition: i8042prt.h:28
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
ULONG InputDataQueueLength
Definition: ntddmou.h:112
I8042_SETTINGS Settings
Definition: i8042prt.h:81
PI8042_MOUSE_EXTENSION MouseExtension
Definition: i8042prt.h:86
#define STATUS_PENDING
Definition: telnetd.h:14
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#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
_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

◆ i8042MouInterruptService()

BOOLEAN NTAPI i8042MouInterruptService ( IN PKINTERRUPT  Interrupt,
PVOID  Context 
)

Definition at line 907 of file mouse.c.

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}
BOOLEAN NTAPI KeInsertQueueDpc(IN PKDPC Dpc, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: dpc.c:725
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
_Outptr_ PUSB_DEVICE_HANDLE _In_ PUSB_DEVICE_HANDLE _In_ USHORT PortStatus
Definition: hubbusif.h:42
BOOLEAN i8042PacketIsr(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR Output)
Definition: i8042prt.c:271
#define i8042ReadMouseData(DeviceExtension, Data)
Definition: i8042prt.h:405
VOID i8042MouHandlePs2pp(IN PI8042_MOUSE_EXTENSION DeviceExtension, IN UCHAR Input)
Definition: ps2pp.c:19
NTSTATUS i8042ReadStatus(IN PPORT_DEVICE_EXTENSION DeviceExtension, OUT PUCHAR Status)
Definition: readwrite.c:82
#define KeStallExecutionProcessor(MicroSeconds)
Definition: precomp.h:27
_In_ PVOID Context
Definition: storport.h:2269
I8042_MOUSE_TYPE MouseType
Definition: i8042prt.h:198
ULONG PollStatusIterations
Definition: i8042prt.h:33
BOOLEAN PacketComplete
Definition: i8042prt.h:94
static LARGE_INTEGER Counter
Definition: clock.c:43
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_INTERRUPT_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFINTERRUPT * Interrupt
Definition: wdfinterrupt.h:379

◆ 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
45}

Referenced by i8042MouInternalDeviceControl(), and i8042MouIsrWritePort().

◆ 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}

Referenced by i8042MouInternalDeviceControl().

◆ i8042MouResetIsr()

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

Definition at line 633 of file mouse.c.

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}
static BOOLEAN i8042MouCallIsrHook(IN PI8042_MOUSE_EXTENSION DeviceExtension, IN UCHAR Status, IN UCHAR Input, OUT PBOOLEAN ToReturn)
Definition: mouse.c:601
#define MOUSE_PRESENT
Definition: i8042prt.h:72
@ Intellimouse
Definition: i8042prt.h:170
#define MOUSE_ERROR
Definition: i8042prt.h:286
#define MOUSE_NACK
Definition: i8042prt.h:287
@ 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
@ 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 WHEELMOUSE_I8042_HARDWARE
Definition: ntddmou.h:102
#define BALLPOINT_I8042_HARDWARE
Definition: ntddmou.h:100
#define MOUSE_I8042_HARDWARE
Definition: ntddmou.h:98
ULONG SampleRate
Definition: i8042prt.h:39
ULONG MouseResolution
Definition: i8042prt.h:29
COMMON_DEVICE_EXTENSION Common
Definition: kbdclass.h:42

Referenced by i8042MouInterruptService(), and i8042MouResetIsr().

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().