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)
134 if (DeviceExtension->MouseType ==
GenericPS2 ||
135 DeviceExtension->MouseType ==
Ps2pp)
142 DeviceExtension->MouseHook.QueueMousePacket(DeviceExtension->MouseHook.CallContext);
176 DeviceExtension->MouseHook.QueueMousePacket(DeviceExtension->MouseHook.CallContext);
181 ERR_(I8042PRT,
"Unexpected state 0x%lx!\n", DeviceExtension->MouseState);
199 MouseInput = DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer;
201 ButtonDiff = (NewButtonData ^ DeviceExtension->MouseButtonState) &
Mask;
207 MouseInput->
ButtonFlags |= (NewButtonData & ButtonDiff) |
208 (((~(NewButtonData)) << 1) & (ButtonDiff << 1)) |
211 INFO_(I8042PRT,
"Left raw/up/down: %u/%u/%u\n",
216 DeviceExtension->MouseButtonState =
217 (DeviceExtension->MouseButtonState & ~Mask) | (NewButtonData &
Mask);
231 i8042Write(DeviceExtension->Common.PortDeviceExtension, DeviceExtension->Common.PortDeviceExtension->ControlPort,
MOUSE_ENAB);
236 WARN_(I8042PRT,
"Failed to enable mouse!\n");
243 WARN_(I8042PRT,
"Failed to read the response of MOU_ENAB, status 0x%08lx\n",
Status);
249 INFO_(I8042PRT,
"Mouse was enabled successfully!\n");
253 WARN_(I8042PRT,
"Got 0x%02x instead of 0xFA\n",
Value);
266 ULONG MouseTransferred = 0;
267 ULONG MouseInBufferCopy;
324 TRACE_(I8042PRT,
"Send a mouse packet\n");
329 INFO_(I8042PRT,
"Sending %lu mouse move(s)\n", MouseInBufferCopy);
371 WARN_(I8042PRT,
"Mouse initialization timeout! (substate %x)\n",
374 PortDeviceExtension->
Flags &= ~MOUSE_PRESENT;
392 Irp->IoStatus.Information = 0;
395 switch (
Stack->Parameters.DeviceIoControl.IoControlCode)
403 TRACE_(I8042PRT,
"IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_MOUSE_CONNECT\n");
417 WARN_(I8042PRT,
"IoAllocateWorkItem() failed\n");
427 WARN_(I8042PRT,
"ExAllocatePoolWithTag() failed\n");
443 WARN_(I8042PRT,
"ExAllocatePoolWithTag() failed\n");
486 TRACE_(I8042PRT,
"IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_MOUSE_DISCONNECT\n");
497 TRACE_(I8042PRT,
"IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_I8042_HOOK_MOUSE\n");
514 DPRINT1(
"IOCTL_INTERNAL_I8042_MOUSE_WRITE_BUFFER not implemented\n");
520 DPRINT1(
"IOCTL_INTERNAL_I8042_MOUSE_START_INFORMATION not implemented\n");
526 TRACE_(I8042PRT,
"IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_MOUSE_QUERY_ATTRIBUTES\n");
540 ERR_(I8042PRT,
"IRP_MJ_INTERNAL_DEVICE_CONTROL / unknown ioctl code 0x%lx\n",
541 Stack->Parameters.DeviceIoControl.IoControlCode);
577 if (DeviceExtension->MouseState !=
MouseIdle) {
579 if (
Now.QuadPart - DeviceExtension->MousePacketStartTime.QuadPart >
580 DeviceExtension->Common.PortDeviceExtension->Settings.MouseSynchIn100ns)
582 WARN_(I8042PRT,
"Mouse input packet timeout\n");
587 if (DeviceExtension->MouseState ==
MouseIdle)
588 DeviceExtension->MousePacketStartTime.QuadPart =
Now.QuadPart;
604 BOOLEAN HookReturn, HookContinue;
606 HookContinue =
FALSE;
608 if (DeviceExtension->MouseHook.IsrRoutine)
610 HookReturn = DeviceExtension->MouseHook.IsrRoutine(
611 DeviceExtension->MouseHook.Context,
612 DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer,
613 &DeviceExtension->Common.PortDeviceExtension->Packet,
617 &DeviceExtension->MouseState,
618 &DeviceExtension->MouseResetState);
622 *ToReturn = HookReturn;
641 if (
MouseIdle == DeviceExtension->MouseState)
646 WARN_(I8042PRT,
"Hot plugged mouse!\n");
657 PortDeviceExtension = DeviceExtension->
Common.PortDeviceExtension;
659 switch ((
ULONG)DeviceExtension->MouseResetState)
664 WARN_(I8042PRT,
"Dropping extra ACK\n");
671 DeviceExtension->MouseResetState++;
675 PortDeviceExtension->
Flags &= ~MOUSE_PRESENT;
677 WARN_(I8042PRT,
"Mouse returned bad reset reply: %x (expected aa)\n",
Value);
683 WARN_(I8042PRT,
"Dropping extra ACK #2\n");
689 DeviceExtension->MouseResetState++;
691 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF2);
695 PortDeviceExtension->
Flags &= ~MOUSE_PRESENT;
697 WARN_(I8042PRT,
"Mouse returned bad reset reply part two: %x (expected 0)\n",
Value);
703 DeviceExtension->MouseResetState++;
707 DeviceExtension->MouseResetState++;
709 WARN_(I8042PRT,
"Mouse doesn't support 0xd2, (returns %x, expected %x), faking\n",
Value,
MOUSE_ACK);
717 DeviceExtension->MouseAttributes.MouseIdentifier =
722 DeviceExtension->MouseAttributes.MouseIdentifier =
726 DeviceExtension->MouseAttributes.MouseIdentifier =
729 DeviceExtension->MouseResetState++;
730 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xE8);
733 DeviceExtension->MouseResetState++;
734 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0x00);
738 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xE6);
742 DeviceExtension->MouseResetState++;
743 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xE6);
746 DeviceExtension->MouseResetState++;
747 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xE9);
750 DeviceExtension->MouseResetState++;
753 DeviceExtension->MouseLogiBuffer[0] =
Value;
754 DeviceExtension->MouseResetState++;
757 DeviceExtension->MouseLogiBuffer[1] =
Value;
758 DeviceExtension->MouseResetState++;
761 DeviceExtension->MouseLogiBuffer[2] =
Value;
768 if (DeviceExtension->MouseLogiBuffer[1])
770 DeviceExtension->MouseAttributes.NumberOfButtons =
771 DeviceExtension->MouseLogiBuffer[1];
772 DeviceExtension->MouseType =
Ps2pp;
773 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF3);
782 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF3);
783 DeviceExtension->MouseResetState = 1001;
786 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xC8);
787 DeviceExtension->MouseResetState++;
791 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF3);
792 DeviceExtension->MouseResetState++;
795 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0x64);
796 DeviceExtension->MouseResetState++;
799 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0x50);
800 DeviceExtension->MouseResetState++;
803 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF2);
804 DeviceExtension->MouseResetState++;
808 DeviceExtension->MouseResetState++;
813 DeviceExtension->MouseAttributes.NumberOfButtons = 3;
814 DeviceExtension->MouseAttributes.MouseIdentifier =
823 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF3);
828 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF3);
829 DeviceExtension->MouseResetState = 1021;
833 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF3);
834 DeviceExtension->MouseResetState++;
838 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xC8);
839 DeviceExtension->MouseResetState++;
842 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0x50);
843 DeviceExtension->MouseResetState++;
846 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF2);
847 DeviceExtension->MouseResetState++;
852 DeviceExtension->MouseAttributes.NumberOfButtons = 5;
853 DeviceExtension->MouseAttributes.MouseIdentifier =
857 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF3);
861 DeviceExtension->MouseHook.IsrWritePort(
862 DeviceExtension->MouseHook.CallContext,
863 (
UCHAR)DeviceExtension->MouseAttributes.SampleRate);
864 DeviceExtension->MouseResetState++;
869 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0x3C);
871 DeviceExtension->MouseResetState = 1040;
875 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xE8);
879 DeviceExtension->MouseHook.IsrWritePort(
880 DeviceExtension->MouseHook.CallContext,
882 INFO_(I8042PRT,
"Mouse resolution %lu\n",
887 DeviceExtension->MouseHook.IsrWritePort(DeviceExtension->MouseHook.CallContext, 0xF4);
894 INFO_(I8042PRT,
"Mouse type = %u\n", DeviceExtension->MouseType);
897 if (DeviceExtension->MouseResetState < 100 || DeviceExtension->MouseResetState > 999)
898 ERR_(I8042PRT,
"MouseResetState went out of range: %lu\n", DeviceExtension->MouseResetState);
926 WARN_(I8042PRT,
"i8042ReadStatus() failed with status 0x%08lx\n",
Status);
937 WARN_(I8042PRT,
"Spurious i8042 mouse interrupt\n");
947 TRACE_(I8042PRT,
"Packet complete\n");
950 TRACE_(I8042PRT,
"Irq eaten by packet\n");
954 TRACE_(I8042PRT,
"Irq is mouse input\n");
960 TRACE_(I8042PRT,
"Handled by ResetIsr or hooked Isr\n");
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#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)
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 STATUS_NOT_IMPLEMENTED
#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