59 WARN_(I8042PRT,
"Mouse buffer overflow\n");
63 TRACE_(I8042PRT,
"Irq completes mouse packet\n");
75 MouseInput = DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer;
77 switch (DeviceExtension->MouseState)
84 WARN_(I8042PRT,
"Bad input, dropping..\n");
98 MouseInput->
LastX = 1;
100 MouseInput->
LastX = 0;
102 MouseInput->
LastY = 1;
104 MouseInput->
LastY = 0;
117 if (MouseInput->
LastX)
126 if (MouseInput->
LastY)
138 DeviceExtension->MouseType ==
Ps2pp)
145 DeviceExtension->MouseHook.QueueMousePacket(DeviceExtension->MouseHook.CallContext);
179 DeviceExtension->MouseHook.QueueMousePacket(DeviceExtension->MouseHook.CallContext);
184 ERR_(I8042PRT,
"Unexpected state 0x%lx!\n", DeviceExtension->MouseState);
202 MouseInput = DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer;
204 ButtonDiff = (NewButtonData ^ DeviceExtension->MouseButtonState) &
Mask;
210 MouseInput->
ButtonFlags |= (NewButtonData & ButtonDiff) |
211 (((~(NewButtonData)) << 1) & (ButtonDiff << 1)) |
214 INFO_(I8042PRT,
"Left raw/up/down: %u/%u/%u\n",
219 DeviceExtension->MouseButtonState =
220 (DeviceExtension->MouseButtonState & ~Mask) | (NewButtonData &
Mask);
234 i8042Write(DeviceExtension->Common.PortDeviceExtension, DeviceExtension->Common.PortDeviceExtension->ControlPort,
MOUSE_ENAB);
239 WARN_(I8042PRT,
"Failed to enable mouse!\n");
246 WARN_(I8042PRT,
"Failed to read the response of MOU_ENAB, status 0x%08lx\n",
Status);
252 INFO_(I8042PRT,
"Mouse was enabled successfully!\n");
256 WARN_(I8042PRT,
"Got 0x%02x instead of 0xFA\n",
Value);
269 ULONG MouseTransferred = 0;
270 ULONG MouseInBufferCopy;
327 TRACE_(I8042PRT,
"Send a mouse packet\n");
332 INFO_(I8042PRT,
"Sending %lu mouse move(s)\n", MouseInBufferCopy);
374 WARN_(I8042PRT,
"Mouse initialization timeout! (substate %x)\n",
377 PortDeviceExtension->
Flags &= ~MOUSE_PRESENT;
395 Irp->IoStatus.Information = 0;
398 switch (
Stack->Parameters.DeviceIoControl.IoControlCode)
406 TRACE_(I8042PRT,
"IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_MOUSE_CONNECT\n");
420 WARN_(I8042PRT,
"IoAllocateWorkItem() failed\n");
430 WARN_(I8042PRT,
"ExAllocatePoolWithTag() failed\n");
446 WARN_(I8042PRT,
"ExAllocatePoolWithTag() failed\n");
489 TRACE_(I8042PRT,
"IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_MOUSE_DISCONNECT\n");
500 TRACE_(I8042PRT,
"IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_I8042_HOOK_MOUSE\n");
517 DPRINT1(
"IOCTL_INTERNAL_I8042_MOUSE_WRITE_BUFFER not implemented\n");
523 DPRINT1(
"IOCTL_INTERNAL_I8042_MOUSE_START_INFORMATION not implemented\n");
529 TRACE_(I8042PRT,
"IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_MOUSE_QUERY_ATTRIBUTES\n");
543 ERR_(I8042PRT,
"IRP_MJ_INTERNAL_DEVICE_CONTROL / unknown ioctl code 0x%lx\n",
544 Stack->Parameters.DeviceIoControl.IoControlCode);
580 if (DeviceExtension->MouseState !=
MouseIdle) {
582 if (
Now.QuadPart - DeviceExtension->MousePacketStartTime.QuadPart >
583 DeviceExtension->Common.PortDeviceExtension->Settings.MouseSynchIn100ns)
585 WARN_(I8042PRT,
"Mouse input packet timeout\n");
590 if (DeviceExtension->MouseState ==
MouseIdle)
591 DeviceExtension->MousePacketStartTime.QuadPart =
Now.QuadPart;
607 BOOLEAN HookReturn, HookContinue;
609 HookContinue =
FALSE;
611 if (DeviceExtension->MouseHook.IsrRoutine)
613 HookReturn = DeviceExtension->MouseHook.IsrRoutine(
614 DeviceExtension->MouseHook.Context,
615 DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer,
616 &DeviceExtension->Common.PortDeviceExtension->Packet,
620 &DeviceExtension->MouseState,
621 &DeviceExtension->MouseResetState);
625 *ToReturn = HookReturn;
644 if (
MouseIdle == DeviceExtension->MouseState)
649 WARN_(I8042PRT,
"Hot plugged mouse!\n");
660 PortDeviceExtension = DeviceExtension->
Common.PortDeviceExtension;
662 switch ((
ULONG)DeviceExtension->MouseResetState)
667 WARN_(I8042PRT,
"Dropping extra ACK\n");
674 DeviceExtension->MouseResetState++;
678 PortDeviceExtension->
Flags &= ~MOUSE_PRESENT;
680 WARN_(I8042PRT,
"Mouse returned bad reset reply: %x (expected aa)\n",
Value);
686 WARN_(I8042PRT,
"Dropping extra ACK #2\n");
692 DeviceExtension->MouseResetState++;
694 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF2);
698 PortDeviceExtension->
Flags &= ~MOUSE_PRESENT;
700 WARN_(I8042PRT,
"Mouse returned bad reset reply part two: %x (expected 0)\n",
Value);
706 DeviceExtension->MouseResetState++;
710 DeviceExtension->MouseResetState++;
712 WARN_(I8042PRT,
"Mouse doesn't support 0xd2, (returns %x, expected %x), faking\n",
Value,
MOUSE_ACK);
720 DeviceExtension->MouseAttributes.MouseIdentifier =
725 DeviceExtension->MouseAttributes.MouseIdentifier =
729 DeviceExtension->MouseAttributes.MouseIdentifier =
732 DeviceExtension->MouseResetState++;
733 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xE8);
736 DeviceExtension->MouseResetState++;
737 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0x00);
741 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xE6);
745 DeviceExtension->MouseResetState++;
746 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xE6);
749 DeviceExtension->MouseResetState++;
750 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xE9);
753 DeviceExtension->MouseResetState++;
756 DeviceExtension->MouseLogiBuffer[0] =
Value;
757 DeviceExtension->MouseResetState++;
760 DeviceExtension->MouseLogiBuffer[1] =
Value;
761 DeviceExtension->MouseResetState++;
764 DeviceExtension->MouseLogiBuffer[2] =
Value;
771 if (DeviceExtension->MouseLogiBuffer[1])
773 DeviceExtension->MouseAttributes.NumberOfButtons =
774 DeviceExtension->MouseLogiBuffer[1];
775 DeviceExtension->MouseType =
Ps2pp;
776 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF3);
785 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF3);
786 DeviceExtension->MouseResetState = 1001;
789 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xC8);
790 DeviceExtension->MouseResetState++;
794 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF3);
795 DeviceExtension->MouseResetState++;
798 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0x64);
799 DeviceExtension->MouseResetState++;
802 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0x50);
803 DeviceExtension->MouseResetState++;
806 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF2);
807 DeviceExtension->MouseResetState++;
811 DeviceExtension->MouseResetState++;
816 DeviceExtension->MouseAttributes.NumberOfButtons = 3;
817 DeviceExtension->MouseAttributes.MouseIdentifier =
826 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF3);
831 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF3);
832 DeviceExtension->MouseResetState = 1021;
836 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF3);
837 DeviceExtension->MouseResetState++;
841 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xC8);
842 DeviceExtension->MouseResetState++;
845 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0x50);
846 DeviceExtension->MouseResetState++;
849 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF2);
850 DeviceExtension->MouseResetState++;
855 DeviceExtension->MouseAttributes.NumberOfButtons = 5;
856 DeviceExtension->MouseAttributes.MouseIdentifier =
860 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF3);
864 DeviceExtension->MouseHook.IsrWritePort(
865 DeviceExtension->MouseHook.CallContext,
866 (
UCHAR)DeviceExtension->MouseAttributes.SampleRate);
867 DeviceExtension->MouseResetState++;
872 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0x3C);
874 DeviceExtension->MouseResetState = 1040;
878 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xE8);
882 DeviceExtension->MouseHook.IsrWritePort(
883 DeviceExtension->MouseHook.CallContext,
885 INFO_(I8042PRT,
"Mouse resolution %lu\n",
890 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF4);
897 INFO_(I8042PRT,
"Mouse type = %u\n", DeviceExtension->MouseType);
900 if (DeviceExtension->MouseResetState < 100 || DeviceExtension->MouseResetState > 999)
901 ERR_(I8042PRT,
"MouseResetState went out of range: %lu\n", DeviceExtension->MouseResetState);
929 WARN_(I8042PRT,
"i8042ReadStatus() failed with status 0x%08lx\n",
Status);
940 WARN_(I8042PRT,
"Spurious i8042 mouse interrupt\n");
950 TRACE_(I8042PRT,
"Packet complete\n");
953 TRACE_(I8042PRT,
"Irq eaten by packet\n");
957 TRACE_(I8042PRT,
"Irq is mouse input\n");
963 TRACE_(I8042PRT,
"Handled by ResetIsr or hooked Isr\n");
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define STATUS_NOT_IMPLEMENTED
#define NT_SUCCESS(StatCode)
static void cleanup(void)
BOOLEAN NTAPI KeInsertQueueDpc(IN PKDPC Dpc, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
#define ExAllocatePoolWithTag(hernya, size, tag)
_Outptr_ PUSB_DEVICE_HANDLE _In_ PUSB_DEVICE_HANDLE _In_ USHORT PortStatus
BOOLEAN i8042PacketIsr(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR Output)
#define i8042ReadMouseData(DeviceExtension, Data)
NTSTATUS i8042ReadDataWait(IN PPORT_DEVICE_EXTENSION DeviceExtension, OUT PUCHAR Data)
KSERVICE_ROUTINE i8042MouInterruptService
DRIVER_DISPATCH i8042MouInternalDeviceControl
struct _I8042_MOUSE_EXTENSION * PI8042_MOUSE_EXTENSION
IO_WORKITEM_ROUTINE i8042SendHookWorkItem
VOID i8042MouHandlePs2pp(IN PI8042_MOUSE_EXTENSION DeviceExtension, IN UCHAR Input)
BOOLEAN i8042IsrWritePort(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR Value, IN UCHAR SelectCmd OPTIONAL)
@ FL_HYPERV_SKIP_Y_NEGATION
DRIVER_DISPATCH ForwardIrpAndForget
NTSTATUS i8042ReadStatus(IN PPORT_DEVICE_EXTENSION DeviceExtension, OUT PUCHAR Status)
BOOLEAN i8042Write(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN PUCHAR addr, IN UCHAR data)
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
struct _CONNECT_DATA * PCONNECT_DATA
VOID(STDAPICALLTYPE * PSERVICE_CALLBACK_ROUTINE)(IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2, IN OUT PVOID SystemArgument3)
#define IOCTL_INTERNAL_MOUSE_DISCONNECT
#define IOCTL_INTERNAL_MOUSE_CONNECT
#define ExFreePoolWithTag(_P, _T)
#define KeStallExecutionProcessor(MicroSeconds)
#define __analysis_assume(expr)
#define UNREFERENCED_PARAMETER(P)
#define IOCTL_INTERNAL_I8042_HOOK_MOUSE
@ ExpectingReadMouseStatusACK
@ ExpectingReadMouseStatusByte1
@ ExpectingSetScaling1to1ACK3
@ ExpectingGetDeviceIdValue
@ ExpectingFinalResolutionValueACK
@ ExpectingSetSamplingRateValueACK
@ ExpectingSetResolutionDefaultACK
@ ExpectingSetScaling1to1ACK
@ ExpectingReadMouseStatusByte3
@ ExpectingSetResolutionDefaultValueACK
@ ExpectingReadMouseStatusByte2
@ ExpectingSetScaling1to1ACK2
@ ExpectingSetSamplingRateACK
@ ExpectingGetDeviceIdACK
@ ExpectingFinalResolutionACK
#define IOCTL_INTERNAL_I8042_MOUSE_START_INFORMATION
struct _INTERNAL_I8042_HOOK_MOUSE * PINTERNAL_I8042_HOOK_MOUSE
#define IOCTL_INTERNAL_I8042_MOUSE_WRITE_BUFFER
#define MOUSE_LEFT_BUTTON_DOWN
struct _MOUSE_ATTRIBUTES * PMOUSE_ATTRIBUTES
#define MOUSE_LEFT_BUTTON_UP
#define WHEELMOUSE_I8042_HARDWARE
#define MOUSE_MIDDLE_BUTTON_DOWN
#define BALLPOINT_I8042_HARDWARE
#define MOUSE_I8042_HARDWARE
#define MOUSE_BUTTON_4_DOWN
struct _MOUSE_INPUT_DATA MOUSE_INPUT_DATA
#define IOCTL_MOUSE_QUERY_ATTRIBUTES
#define MOUSE_BUTTON_5_DOWN
#define MOUSE_MOVE_RELATIVE
#define MOUSE_RIGHT_BUTTON_DOWN
#define IoCompleteRequest
KIRQL NTAPI KeAcquireInterruptSpinLock(IN PKINTERRUPT Interrupt)
VOID NTAPI KeReleaseInterruptSpinLock(IN PKINTERRUPT Interrupt, IN KIRQL OldIrql)
#define KeQueryInterruptTime()
#define STATUS_BUFFER_TOO_SMALL
PDEVICE_OBJECT ClassDeviceObject
PPORT_DEVICE_EXTENSION PortDeviceExtension
FDO_DEVICE_EXTENSION Common
MOUSE_ATTRIBUTES MouseAttributes
I8042_MOUSE_TYPE MouseType
MOUSE_TIMEOUT_STATE MouseTimeoutState
PMOUSE_INPUT_DATA MouseBuffer
BOOLEAN MouseTimeoutActive
INTERNAL_I8042_HOOK_MOUSE MouseHook
MOUSE_RESET_SUBSTATE MouseResetState
ULONG PollStatusIterations
OUT PI8042_MOUSE_ISR IsrRoutine
IN PI8042_QUEUE_PACKET QueueMousePacket
IN PI8042_ISR_WRITE_PORT IsrWritePort
ULONG InputDataQueueLength
PKINTERRUPT HighestDIRQLInterrupt
PI8042_MOUSE_EXTENSION MouseExtension
COMMON_DEVICE_EXTENSION Common
static LARGE_INTEGER Counter
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
BOOLEAN NTAPI KeCancelTimer(IN OUT PKTIMER Timer)
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
#define RtlZeroMemory(Destination, Length)
#define RtlMoveMemory(Destination, Source, Length)
#define STATUS_IO_DEVICE_ERROR
#define STATUS_INVALID_PARAMETER
#define STATUS_INSUFFICIENT_RESOURCES
_In_ PDEVICE_OBJECT DeviceObject
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
_Must_inspect_result_ _In_ PWDF_DPC_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFDPC * Dpc
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_INTERRUPT_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFINTERRUPT * Interrupt
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
_Must_inspect_result_ _In_ PWDF_WORKITEM_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWORKITEM * WorkItem
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
_In_opt_ PVOID DeferredContext
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2