From fae7b106ebc4d45db0d9a841691ca568ae93a1ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Fri, 13 Dec 2024 17:37:19 +0100 Subject: [PATCH] [I8042PRT] i8042prt.h, keyboard.c, registry.c: TAB -> 4-space formatting Effectively reverts commit 0560eef6e (r39553) that reverted commit a2feddeab (r39517). --- drivers/input/i8042prt/i8042prt.h | 356 +++---- drivers/input/i8042prt/keyboard.c | 1546 +++++++++++++++-------------- drivers/input/i8042prt/registry.c | 410 ++++---- 3 files changed, 1162 insertions(+), 1150 deletions(-) diff --git a/drivers/input/i8042prt/i8042prt.h b/drivers/input/i8042prt/i8042prt.h index 758b0b2bb63d7..2e67059990c41 100644 --- a/drivers/input/i8042prt/i8042prt.h +++ b/drivers/input/i8042prt/i8042prt.h @@ -1,5 +1,5 @@ -#ifndef _I8042PRT_PCH_ -#define _I8042PRT_PCH_ +#ifndef _I8042PRT_H_ +#define _I8042PRT_H_ #include #include @@ -13,48 +13,48 @@ typedef enum { - dsStopped, - dsStarted, - dsPaused, - dsRemoved, - dsSurpriseRemoved + dsStopped, + dsStarted, + dsPaused, + dsRemoved, + dsSurpriseRemoved } DEVICE_STATE; typedef struct _I8042_SETTINGS { - /* Registry settings */ - ULONG KeyboardDataQueueSize; /* done */ - UNICODE_STRING KeyboardDeviceBaseName; - ULONG MouseDataQueueSize; /* done */ - ULONG MouseResolution; - ULONG MouseSynchIn100ns; - ULONG NumberOfButtons; - UNICODE_STRING PointerDeviceBaseName; - ULONG PollStatusIterations; /* done */ - ULONG OverrideKeyboardType; - ULONG OverrideKeyboardSubtype; - ULONG PollingIterations; /* done */ - ULONG PollingIterationsMaximum; - ULONG ResendIterations; /* done */ - ULONG SampleRate; - ULONG CrashOnCtrlScroll; /* done */ + /* Registry settings */ + ULONG KeyboardDataQueueSize; /* done */ + UNICODE_STRING KeyboardDeviceBaseName; + ULONG MouseDataQueueSize; /* done */ + ULONG MouseResolution; + ULONG MouseSynchIn100ns; + ULONG NumberOfButtons; + UNICODE_STRING PointerDeviceBaseName; + ULONG PollStatusIterations; /* done */ + ULONG OverrideKeyboardType; + ULONG OverrideKeyboardSubtype; + ULONG PollingIterations; /* done */ + ULONG PollingIterationsMaximum; + ULONG ResendIterations; /* done */ + ULONG SampleRate; + ULONG CrashOnCtrlScroll; /* done */ } I8042_SETTINGS, *PI8042_SETTINGS; typedef enum _MOUSE_TIMEOUT_STATE { - NoChange, - TimeoutStart, - TimeoutCancel + NoChange, + TimeoutStart, + TimeoutCancel } MOUSE_TIMEOUT_STATE, *PMOUSE_TIMEOUT_STATE; typedef struct _INTERRUPT_DATA { - PKINTERRUPT Object; - ULONG Vector; - KIRQL Dirql; - KINTERRUPT_MODE InterruptMode; - BOOLEAN ShareInterrupt; - KAFFINITY Affinity; + PKINTERRUPT Object; + ULONG Vector; + KIRQL Dirql; + KINTERRUPT_MODE InterruptMode; + BOOLEAN ShareInterrupt; + KAFFINITY Affinity; } INTERRUPT_DATA, *PINTERRUPT_DATA; #define WHEEL_DELTA 120 @@ -76,132 +76,132 @@ typedef struct _I8042_MOUSE_EXTENSION *PI8042_MOUSE_EXTENSION; typedef struct _PORT_DEVICE_EXTENSION { - PUCHAR DataPort; /* Usually 0x60 */ - PUCHAR ControlPort; /* Usually 0x64 */ - I8042_SETTINGS Settings; - ULONG Flags; - - PI8042_KEYBOARD_EXTENSION KeyboardExtension; - INTERRUPT_DATA KeyboardInterrupt; - PI8042_MOUSE_EXTENSION MouseExtension; - INTERRUPT_DATA MouseInterrupt; - PKINTERRUPT HighestDIRQLInterrupt; - KSPIN_LOCK SpinLock; - KIRQL HighestDirql; - - OUTPUT_PACKET Packet; - ULONG PacketResends; - BOOLEAN PacketComplete; - NTSTATUS PacketResult; - UCHAR PacketBuffer[16]; - UCHAR PacketPort; - - PIRP CurrentIrp; - PDEVICE_OBJECT CurrentIrpDevice; + PUCHAR DataPort; /* Usually 0x60 */ + PUCHAR ControlPort; /* Usually 0x64 */ + I8042_SETTINGS Settings; + ULONG Flags; + + PI8042_KEYBOARD_EXTENSION KeyboardExtension; + INTERRUPT_DATA KeyboardInterrupt; + PI8042_MOUSE_EXTENSION MouseExtension; + INTERRUPT_DATA MouseInterrupt; + PKINTERRUPT HighestDIRQLInterrupt; + KSPIN_LOCK SpinLock; + KIRQL HighestDirql; + + OUTPUT_PACKET Packet; + ULONG PacketResends; + BOOLEAN PacketComplete; + NTSTATUS PacketResult; + UCHAR PacketBuffer[16]; + UCHAR PacketPort; + + PIRP CurrentIrp; + PDEVICE_OBJECT CurrentIrpDevice; } PORT_DEVICE_EXTENSION, *PPORT_DEVICE_EXTENSION; typedef struct _I8042_DRIVER_EXTENSION { - UNICODE_STRING RegistryPath; + UNICODE_STRING RegistryPath; - PORT_DEVICE_EXTENSION Port; - LIST_ENTRY DeviceListHead; - KSPIN_LOCK DeviceListLock; + PORT_DEVICE_EXTENSION Port; + LIST_ENTRY DeviceListHead; + KSPIN_LOCK DeviceListLock; } I8042_DRIVER_EXTENSION, *PI8042_DRIVER_EXTENSION; typedef enum _I8042_DEVICE_TYPE { - Unknown, - Keyboard, - Mouse, - PhysicalDeviceObject + Unknown, + Keyboard, + Mouse, + PhysicalDeviceObject } I8042_DEVICE_TYPE, *PI8042_DEVICE_TYPE; typedef struct _FDO_DEVICE_EXTENSION { - I8042_DEVICE_TYPE Type; - // Linkage in I8042_DRIVER_EXTENSION.DeviceListHead - LIST_ENTRY ListEntry; - // Associated device object (FDO) - PDEVICE_OBJECT Fdo; - // Associated device object (PDO) - PDEVICE_OBJECT Pdo; - // Lower device object - PDEVICE_OBJECT LowerDevice; - // Current state of the driver - DEVICE_STATE PnpState; - - PPORT_DEVICE_EXTENSION PortDeviceExtension; + I8042_DEVICE_TYPE Type; + // Linkage in I8042_DRIVER_EXTENSION.DeviceListHead + LIST_ENTRY ListEntry; + // Associated device object (FDO) + PDEVICE_OBJECT Fdo; + // Associated device object (PDO) + PDEVICE_OBJECT Pdo; + // Lower device object + PDEVICE_OBJECT LowerDevice; + // Current state of the driver + DEVICE_STATE PnpState; + + PPORT_DEVICE_EXTENSION PortDeviceExtension; } FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION; typedef struct _I8042_KEYBOARD_EXTENSION { - FDO_DEVICE_EXTENSION Common; - CONNECT_DATA KeyboardData; - INTERNAL_I8042_HOOK_KEYBOARD KeyboardHook; /* FIXME: IsrWritePort ignored */ - KDPC DpcKeyboard; - - KEYBOARD_ATTRIBUTES KeyboardAttributes; - - KEYBOARD_INDICATOR_PARAMETERS KeyboardIndicators; - - KEYBOARD_SCAN_STATE KeyboardScanState; - BOOLEAN KeyComplete; - PKEYBOARD_INPUT_DATA KeyboardBuffer; - ULONG KeysInBuffer; - - /* Power keys items */ - ULONG ReportedCaps; - ULONG NewCaps; - ULONG LastPowerKey; - UNICODE_STRING PowerInterfaceName; - PIO_WORKITEM PowerWorkItem; - PIRP PowerIrp; - - /* Debug items */ - ULONG ComboPosition; - PIO_WORKITEM DebugWorkItem; - BOOLEAN TabPressed; + FDO_DEVICE_EXTENSION Common; + CONNECT_DATA KeyboardData; + INTERNAL_I8042_HOOK_KEYBOARD KeyboardHook; /* FIXME: IsrWritePort ignored */ + KDPC DpcKeyboard; + + KEYBOARD_ATTRIBUTES KeyboardAttributes; + + KEYBOARD_INDICATOR_PARAMETERS KeyboardIndicators; + + KEYBOARD_SCAN_STATE KeyboardScanState; + BOOLEAN KeyComplete; + PKEYBOARD_INPUT_DATA KeyboardBuffer; + ULONG KeysInBuffer; + + /* Power keys items */ + ULONG ReportedCaps; + ULONG NewCaps; + ULONG LastPowerKey; + UNICODE_STRING PowerInterfaceName; + PIO_WORKITEM PowerWorkItem; + PIRP PowerIrp; + + /* Debug items */ + ULONG ComboPosition; + PIO_WORKITEM DebugWorkItem; + BOOLEAN TabPressed; } I8042_KEYBOARD_EXTENSION; typedef enum _I8042_MOUSE_TYPE { - GenericPS2, - Intellimouse, - IntellimouseExplorer, - Ps2pp + GenericPS2, + Intellimouse, + IntellimouseExplorer, + Ps2pp } I8042_MOUSE_TYPE, *PI8042_MOUSE_TYPE; typedef struct _I8042_MOUSE_EXTENSION { - FDO_DEVICE_EXTENSION Common; - CONNECT_DATA MouseData; - INTERNAL_I8042_HOOK_MOUSE MouseHook; - KDPC DpcMouse; - - MOUSE_ATTRIBUTES MouseAttributes; - - MOUSE_STATE MouseState; - BOOLEAN MouseComplete; - MOUSE_RESET_SUBSTATE MouseResetState; - PMOUSE_INPUT_DATA MouseBuffer; - ULONG MouseInBuffer; - USHORT MouseButtonState; - ULARGE_INTEGER MousePacketStartTime; - - KTIMER TimerMouseTimeout; - KDPC DpcMouseTimeout; - MOUSE_TIMEOUT_STATE MouseTimeoutState; - BOOLEAN MouseTimeoutActive; - - UCHAR MouseLogiBuffer[3]; - I8042_MOUSE_TYPE MouseType; + FDO_DEVICE_EXTENSION Common; + CONNECT_DATA MouseData; + INTERNAL_I8042_HOOK_MOUSE MouseHook; + KDPC DpcMouse; + + MOUSE_ATTRIBUTES MouseAttributes; + + MOUSE_STATE MouseState; + BOOLEAN MouseComplete; + MOUSE_RESET_SUBSTATE MouseResetState; + PMOUSE_INPUT_DATA MouseBuffer; + ULONG MouseInBuffer; + USHORT MouseButtonState; + ULARGE_INTEGER MousePacketStartTime; + + KTIMER TimerMouseTimeout; + KDPC DpcMouseTimeout; + MOUSE_TIMEOUT_STATE MouseTimeoutState; + BOOLEAN MouseTimeoutActive; + + UCHAR MouseLogiBuffer[3]; + I8042_MOUSE_TYPE MouseType; } I8042_MOUSE_EXTENSION; typedef struct _I8042_HOOK_WORKITEM { - PIO_WORKITEM WorkItem; - PIRP Irp; + PIO_WORKITEM WorkItem; + PIRP Irp; } I8042_HOOK_WORKITEM, *PI8042_HOOK_WORKITEM; /*----------------------------------------------------- @@ -307,9 +307,9 @@ DRIVER_DISPATCH i8042Close; NTSTATUS NTAPI i8042SynchWritePortKbd( - IN PVOID Context, - IN UCHAR Value, - IN BOOLEAN WaitForAck); + IN PVOID Context, + IN UCHAR Value, + IN BOOLEAN WaitForAck); DRIVER_STARTIO i8042KbdStartIo; @@ -325,16 +325,16 @@ DRIVER_ADD_DEVICE i8042AddDevice; BOOLEAN i8042PacketIsr( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN UCHAR Output); + IN PPORT_DEVICE_EXTENSION DeviceExtension, + IN UCHAR Output); NTSTATUS i8042StartPacket( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN PFDO_DEVICE_EXTENSION FdoDeviceExtension, - IN PUCHAR Bytes, - IN ULONG ByteCount, - IN PIRP Irp); + IN PPORT_DEVICE_EXTENSION DeviceExtension, + IN PFDO_DEVICE_EXTENSION FdoDeviceExtension, + IN PUCHAR Bytes, + IN ULONG ByteCount, + IN PIRP Irp); /* misc.c */ @@ -342,25 +342,25 @@ DRIVER_DISPATCH ForwardIrpAndForget; NTSTATUS DuplicateUnicodeString( - IN ULONG Flags, - IN PCUNICODE_STRING SourceString, - OUT PUNICODE_STRING DestinationString); + IN ULONG Flags, + IN PCUNICODE_STRING SourceString, + OUT PUNICODE_STRING DestinationString); /* mouse.c */ VOID i8042MouHandle( - IN PI8042_MOUSE_EXTENSION DeviceExtension, - IN UCHAR Output); + IN PI8042_MOUSE_EXTENSION DeviceExtension, + IN UCHAR Output); VOID i8042MouHandleButtons( - IN PI8042_MOUSE_EXTENSION DeviceExtension, - IN USHORT Mask); + IN PI8042_MOUSE_EXTENSION DeviceExtension, + IN USHORT Mask); NTSTATUS i8042MouInitialize( - IN PI8042_MOUSE_EXTENSION DeviceExtension); + IN PI8042_MOUSE_EXTENSION DeviceExtension); DRIVER_DISPATCH i8042MouInternalDeviceControl; @@ -370,9 +370,9 @@ KSERVICE_ROUTINE i8042MouInterruptService; BOOLEAN i8042ChangeMode( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN UCHAR FlagsToDisable, - IN UCHAR FlagsToEnable); + IN PPORT_DEVICE_EXTENSION DeviceExtension, + IN UCHAR FlagsToDisable, + IN UCHAR FlagsToEnable); _Dispatch_type_(IRP_MJ_PNP) DRIVER_DISPATCH i8042Pnp; @@ -380,66 +380,66 @@ DRIVER_DISPATCH i8042Pnp; /* ps2pp.c */ VOID i8042MouHandlePs2pp( - IN PI8042_MOUSE_EXTENSION DeviceExtension, - IN UCHAR Input); + IN PI8042_MOUSE_EXTENSION DeviceExtension, + IN UCHAR Input); /* readwrite.c */ VOID i8042Flush( - IN PPORT_DEVICE_EXTENSION DeviceExtension); + IN PPORT_DEVICE_EXTENSION DeviceExtension); BOOLEAN i8042IsrWritePort( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN UCHAR Value, - IN UCHAR SelectCmd OPTIONAL); + IN PPORT_DEVICE_EXTENSION DeviceExtension, + IN UCHAR Value, + IN UCHAR SelectCmd OPTIONAL); NTSTATUS i8042ReadData( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN UCHAR StatusFlags, - OUT PUCHAR Data); + IN PPORT_DEVICE_EXTENSION DeviceExtension, + IN UCHAR StatusFlags, + OUT PUCHAR Data); #define i8042ReadKeyboardData(DeviceExtension, Data) \ - i8042ReadData(DeviceExtension, KBD_OBF, Data) + i8042ReadData(DeviceExtension, KBD_OBF, Data) #define i8042ReadMouseData(DeviceExtension, Data) \ - i8042ReadData(DeviceExtension, MOU_OBF, Data) + i8042ReadData(DeviceExtension, MOU_OBF, Data) NTSTATUS i8042ReadDataWait( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - OUT PUCHAR Data); + IN PPORT_DEVICE_EXTENSION DeviceExtension, + OUT PUCHAR Data); NTSTATUS i8042ReadStatus( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - OUT PUCHAR Status); + IN PPORT_DEVICE_EXTENSION DeviceExtension, + OUT PUCHAR Status); NTSTATUS NTAPI i8042SynchReadPort( - IN PVOID Context, - OUT PUCHAR Value, - IN BOOLEAN WaitForAck); + IN PVOID Context, + OUT PUCHAR Value, + IN BOOLEAN WaitForAck); NTSTATUS NTAPI i8042SynchWritePort( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN UCHAR Port, - IN UCHAR Value, - IN BOOLEAN WaitForAck); + IN PPORT_DEVICE_EXTENSION DeviceExtension, + IN UCHAR Port, + IN UCHAR Value, + IN BOOLEAN WaitForAck); BOOLEAN i8042Write( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN PUCHAR addr, - IN UCHAR data); + IN PPORT_DEVICE_EXTENSION DeviceExtension, + IN PUCHAR addr, + IN UCHAR data); /* registry.c */ NTSTATUS ReadRegistryEntries( - IN PUNICODE_STRING RegistryPath, - OUT PI8042_SETTINGS Settings); + IN PUNICODE_STRING RegistryPath, + OUT PI8042_SETTINGS Settings); /* hwhacks.c */ @@ -456,4 +456,4 @@ enum _FLAGS extern ULONG i8042HwFlags; -#endif /* _I8042PRT_PCH_ */ +#endif /* _I8042PRT_H_ */ diff --git a/drivers/input/i8042prt/keyboard.c b/drivers/input/i8042prt/keyboard.c index e33ec89659b93..68f2a366c817c 100644 --- a/drivers/input/i8042prt/keyboard.c +++ b/drivers/input/i8042prt/keyboard.c @@ -24,15 +24,18 @@ static IO_WORKITEM_ROUTINE i8042PowerWorkItem; static KDEFERRED_ROUTINE i8042KbdDpcRoutine; /* This structure starts with the same layout as KEYBOARD_INDICATOR_TRANSLATION */ -typedef struct _LOCAL_KEYBOARD_INDICATOR_TRANSLATION { - USHORT NumberOfIndicatorKeys; - INDICATOR_LIST IndicatorList[3]; +typedef struct _LOCAL_KEYBOARD_INDICATOR_TRANSLATION +{ + USHORT NumberOfIndicatorKeys; + INDICATOR_LIST IndicatorList[3]; } LOCAL_KEYBOARD_INDICATOR_TRANSLATION, *PLOCAL_KEYBOARD_INDICATOR_TRANSLATION; -static LOCAL_KEYBOARD_INDICATOR_TRANSLATION IndicatorTranslation = { 3, { - {0x3A, KEYBOARD_CAPS_LOCK_ON}, - {0x45, KEYBOARD_NUM_LOCK_ON}, - {0x46, KEYBOARD_SCROLL_LOCK_ON}}}; +static LOCAL_KEYBOARD_INDICATOR_TRANSLATION IndicatorTranslation = +{ 3, { + {0x3A, KEYBOARD_CAPS_LOCK_ON}, + {0x45, KEYBOARD_NUM_LOCK_ON}, + {0x46, KEYBOARD_SCROLL_LOCK_ON} +}}; /* FUNCTIONS *****************************************************************/ @@ -42,41 +45,43 @@ static LOCAL_KEYBOARD_INDICATOR_TRANSLATION IndicatorTranslation = { 3, { */ /*static VOID NTAPI i8042KbdIsrWritePort( - IN PVOID Context, - IN UCHAR Value) + IN PVOID Context, + IN UCHAR Value) { - PI8042_KEYBOARD_EXTENSION DeviceExtension; - - DeviceExtension = (PI8042_KEYBOARD_EXTENSION)Context; - - if (DeviceExtension->KeyboardHook.IsrWritePort) - { - DeviceExtension->KeyboardHook.IsrWritePort( - DeviceExtension->KeyboardHook.CallContext, - Value); - } - else - i8042IsrWritePort(Context, Value, 0); + PI8042_KEYBOARD_EXTENSION DeviceExtension; + + DeviceExtension = (PI8042_KEYBOARD_EXTENSION)Context; + + if (DeviceExtension->KeyboardHook.IsrWritePort) + { + DeviceExtension->KeyboardHook.IsrWritePort( + DeviceExtension->KeyboardHook.CallContext, + Value); + } + else + { + i8042IsrWritePort(Context, Value, 0); + } }*/ static VOID NTAPI i8042KbdQueuePacket( - IN PVOID Context) + IN PVOID Context) { - PI8042_KEYBOARD_EXTENSION DeviceExtension; + PI8042_KEYBOARD_EXTENSION DeviceExtension; - DeviceExtension = (PI8042_KEYBOARD_EXTENSION)Context; + DeviceExtension = (PI8042_KEYBOARD_EXTENSION)Context; - DeviceExtension->KeyComplete = TRUE; - DeviceExtension->KeysInBuffer++; - if (DeviceExtension->KeysInBuffer > DeviceExtension->Common.PortDeviceExtension->Settings.KeyboardDataQueueSize) - { - WARN_(I8042PRT, "Keyboard buffer overflow\n"); - DeviceExtension->KeysInBuffer--; - } + DeviceExtension->KeyComplete = TRUE; + DeviceExtension->KeysInBuffer++; + if (DeviceExtension->KeysInBuffer > DeviceExtension->Common.PortDeviceExtension->Settings.KeyboardDataQueueSize) + { + WARN_(I8042PRT, "Keyboard buffer overflow\n"); + DeviceExtension->KeysInBuffer--; + } - TRACE_(I8042PRT, "Irq completes key\n"); - KeInsertQueueDpc(&DeviceExtension->DpcKeyboard, NULL, NULL); + TRACE_(I8042PRT, "Irq completes key\n"); + KeInsertQueueDpc(&DeviceExtension->DpcKeyboard, NULL, NULL); } /* @@ -85,15 +90,15 @@ i8042KbdQueuePacket( */ NTSTATUS NTAPI i8042SynchWritePortKbd( - IN PVOID Context, - IN UCHAR Value, - IN BOOLEAN WaitForAck) + IN PVOID Context, + IN UCHAR Value, + IN BOOLEAN WaitForAck) { - return i8042SynchWritePort( - (PPORT_DEVICE_EXTENSION)Context, - 0, - Value, - WaitForAck); + return i8042SynchWritePort( + (PPORT_DEVICE_EXTENSION)Context, + 0, + Value, + WaitForAck); } /* @@ -101,280 +106,279 @@ i8042SynchWritePortKbd( */ VOID NTAPI i8042KbdStartIo( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) { - PIO_STACK_LOCATION Stack; - PI8042_KEYBOARD_EXTENSION DeviceExtension; - PPORT_DEVICE_EXTENSION PortDeviceExtension; - - Stack = IoGetCurrentIrpStackLocation(Irp); - DeviceExtension = (PI8042_KEYBOARD_EXTENSION)DeviceObject->DeviceExtension; - PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; - - switch (Stack->Parameters.DeviceIoControl.IoControlCode) - { - case IOCTL_KEYBOARD_SET_INDICATORS: - { - TRACE_(I8042PRT, "IOCTL_KEYBOARD_SET_INDICATORS\n"); - INFO_(I8042PRT, "Leds: {%s%s%s }\n", - DeviceExtension->KeyboardIndicators.LedFlags & KEYBOARD_CAPS_LOCK_ON ? " CAPSLOCK" : "", - DeviceExtension->KeyboardIndicators.LedFlags & KEYBOARD_NUM_LOCK_ON ? " NUMLOCK" : "", - DeviceExtension->KeyboardIndicators.LedFlags & KEYBOARD_SCROLL_LOCK_ON ? " SCROLLLOCK" : ""); - - PortDeviceExtension->PacketBuffer[0] = KBD_CMD_SET_LEDS; - PortDeviceExtension->PacketBuffer[1] = 0; - if (DeviceExtension->KeyboardIndicators.LedFlags & KEYBOARD_CAPS_LOCK_ON) - PortDeviceExtension->PacketBuffer[1] |= KBD_LED_CAPS; - - if (DeviceExtension->KeyboardIndicators.LedFlags & KEYBOARD_NUM_LOCK_ON) - PortDeviceExtension->PacketBuffer[1] |= KBD_LED_NUM; - - if (DeviceExtension->KeyboardIndicators.LedFlags & KEYBOARD_SCROLL_LOCK_ON) - PortDeviceExtension->PacketBuffer[1] |= KBD_LED_SCROLL; - - i8042StartPacket( - PortDeviceExtension, - &DeviceExtension->Common, - PortDeviceExtension->PacketBuffer, - 2, - Irp); - break; - } - default: - { - ERR_(I8042PRT, "Unknown ioctl code 0x%lx\n", - Stack->Parameters.DeviceIoControl.IoControlCode); - ASSERT(FALSE); - } - } + PIO_STACK_LOCATION Stack; + PI8042_KEYBOARD_EXTENSION DeviceExtension; + PPORT_DEVICE_EXTENSION PortDeviceExtension; + + Stack = IoGetCurrentIrpStackLocation(Irp); + DeviceExtension = (PI8042_KEYBOARD_EXTENSION)DeviceObject->DeviceExtension; + PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; + + switch (Stack->Parameters.DeviceIoControl.IoControlCode) + { + case IOCTL_KEYBOARD_SET_INDICATORS: + { + TRACE_(I8042PRT, "IOCTL_KEYBOARD_SET_INDICATORS\n"); + INFO_(I8042PRT, "Leds: {%s%s%s}\n", + DeviceExtension->KeyboardIndicators.LedFlags & KEYBOARD_CAPS_LOCK_ON ? " CAPSLOCK" : "", + DeviceExtension->KeyboardIndicators.LedFlags & KEYBOARD_NUM_LOCK_ON ? " NUMLOCK" : "", + DeviceExtension->KeyboardIndicators.LedFlags & KEYBOARD_SCROLL_LOCK_ON ? " SCROLLLOCK" : ""); + + PortDeviceExtension->PacketBuffer[0] = KBD_CMD_SET_LEDS; + PortDeviceExtension->PacketBuffer[1] = 0; + if (DeviceExtension->KeyboardIndicators.LedFlags & KEYBOARD_CAPS_LOCK_ON) + PortDeviceExtension->PacketBuffer[1] |= KBD_LED_CAPS; + + if (DeviceExtension->KeyboardIndicators.LedFlags & KEYBOARD_NUM_LOCK_ON) + PortDeviceExtension->PacketBuffer[1] |= KBD_LED_NUM; + + if (DeviceExtension->KeyboardIndicators.LedFlags & KEYBOARD_SCROLL_LOCK_ON) + PortDeviceExtension->PacketBuffer[1] |= KBD_LED_SCROLL; + + i8042StartPacket( + PortDeviceExtension, + &DeviceExtension->Common, + PortDeviceExtension->PacketBuffer, + 2, + Irp); + break; + } + default: + { + ERR_(I8042PRT, "Unknown ioctl code 0x%lx\n", + Stack->Parameters.DeviceIoControl.IoControlCode); + ASSERT(FALSE); + } + } } static VOID i8042PacketDpc( - IN PPORT_DEVICE_EXTENSION DeviceExtension) + IN PPORT_DEVICE_EXTENSION DeviceExtension) { - BOOLEAN FinishIrp = FALSE; - KIRQL Irql; - NTSTATUS Result = STATUS_INTERNAL_ERROR; /* Shouldn't happen */ - - /* If the interrupt happens before this is setup, the key - * was already in the buffer. Too bad! */ - if (!DeviceExtension->HighestDIRQLInterrupt) - return; - - Irql = KeAcquireInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt); - - if (DeviceExtension->Packet.State == Idle - && DeviceExtension->PacketComplete) - { - FinishIrp = TRUE; - Result = DeviceExtension->PacketResult; - DeviceExtension->PacketComplete = FALSE; - } - - KeReleaseInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt, Irql); - - if (!FinishIrp) - return; - - if (DeviceExtension->CurrentIrp) - { - DeviceExtension->CurrentIrp->IoStatus.Status = Result; - IoCompleteRequest(DeviceExtension->CurrentIrp, IO_NO_INCREMENT); - IoStartNextPacket(DeviceExtension->CurrentIrpDevice, FALSE); - DeviceExtension->CurrentIrp = NULL; - DeviceExtension->CurrentIrpDevice = NULL; - } + BOOLEAN FinishIrp = FALSE; + KIRQL Irql; + NTSTATUS Result = STATUS_INTERNAL_ERROR; /* Shouldn't happen */ + + /* If the interrupt happens before this is setup, the key + * was already in the buffer. Too bad! */ + if (!DeviceExtension->HighestDIRQLInterrupt) + return; + + Irql = KeAcquireInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt); + + if (DeviceExtension->Packet.State == Idle + && DeviceExtension->PacketComplete) + { + FinishIrp = TRUE; + Result = DeviceExtension->PacketResult; + DeviceExtension->PacketComplete = FALSE; + } + + KeReleaseInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt, Irql); + + if (!FinishIrp) + return; + + if (DeviceExtension->CurrentIrp) + { + DeviceExtension->CurrentIrp->IoStatus.Status = Result; + IoCompleteRequest(DeviceExtension->CurrentIrp, IO_NO_INCREMENT); + IoStartNextPacket(DeviceExtension->CurrentIrpDevice, FALSE); + DeviceExtension->CurrentIrp = NULL; + DeviceExtension->CurrentIrpDevice = NULL; + } } static VOID NTAPI i8042PowerWorkItem( - IN PDEVICE_OBJECT DeviceObject, - IN PVOID Context) + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context) { - PI8042_KEYBOARD_EXTENSION DeviceExtension; - PIRP WaitingIrp; - NTSTATUS Status; - - UNREFERENCED_PARAMETER(DeviceObject); - - __analysis_assume(Context != NULL); - DeviceExtension = Context; - - /* See http://blogs.msdn.com/doronh/archive/2006/09/08/746961.aspx */ - - /* Register GUID_DEVICE_SYS_BUTTON interface and report capability */ - if (DeviceExtension->NewCaps != DeviceExtension->ReportedCaps) - { - WaitingIrp = InterlockedExchangePointer((PVOID)&DeviceExtension->PowerIrp, NULL); - if (WaitingIrp) - { - /* Cancel the current power irp, as capability changed */ - WaitingIrp->IoStatus.Status = STATUS_UNSUCCESSFUL; - WaitingIrp->IoStatus.Information = sizeof(ULONG); - IoCompleteRequest(WaitingIrp, IO_NO_INCREMENT); - } - - if (DeviceExtension->PowerInterfaceName.MaximumLength == 0) - { - /* We have never registered this interface ; do it */ - Status = IoRegisterDeviceInterface( - DeviceExtension->Common.Pdo, - &GUID_DEVICE_SYS_BUTTON, - NULL, - &DeviceExtension->PowerInterfaceName); - if (!NT_SUCCESS(Status)) - { - /* We can't do more yet, ignore the keypress... */ - WARN_(I8042PRT, "IoRegisterDeviceInterface(GUID_DEVICE_SYS_BUTTON) failed with status 0x%08lx\n", - Status); - DeviceExtension->PowerInterfaceName.MaximumLength = 0; - return; - } - } - else - { - /* Disable the interface. Once activated again, capabilities would be asked again */ - Status = IoSetDeviceInterfaceState( - &DeviceExtension->PowerInterfaceName, - FALSE); - if (!NT_SUCCESS(Status)) - { - /* Ignore the key press... */ - WARN_(I8042PRT, "Disabling interface %wZ failed with status 0x%08lx\n", - &DeviceExtension->PowerInterfaceName, Status); - return; - } - } - /* Enable the interface. This leads to receiving a IOCTL_GET_SYS_BUTTON_CAPS, - * so we can report new capability */ - Status = IoSetDeviceInterfaceState( - &DeviceExtension->PowerInterfaceName, - TRUE); - if (!NT_SUCCESS(Status)) - { - /* Ignore the key press... */ - WARN_(I8042PRT, "Enabling interface %wZ failed with status 0x%08lx\n", - &DeviceExtension->PowerInterfaceName, Status); - return; - } - } - - /* Directly complete the IOCTL_GET_SYS_BUTTON_EVENT Irp (if any) */ - WaitingIrp = InterlockedExchangePointer((PVOID)&DeviceExtension->PowerIrp, NULL); - if (WaitingIrp) - { - PULONG pEvent = (PULONG)WaitingIrp->AssociatedIrp.SystemBuffer; - - WaitingIrp->IoStatus.Status = STATUS_SUCCESS; - WaitingIrp->IoStatus.Information = sizeof(ULONG); - *pEvent = InterlockedExchange((PLONG)&DeviceExtension->LastPowerKey, 0); - IoCompleteRequest(WaitingIrp, IO_NO_INCREMENT); - } + PI8042_KEYBOARD_EXTENSION DeviceExtension; + PIRP WaitingIrp; + NTSTATUS Status; + + UNREFERENCED_PARAMETER(DeviceObject); + + __analysis_assume(Context != NULL); + DeviceExtension = Context; + + /* See http://blogs.msdn.com/doronh/archive/2006/09/08/746961.aspx */ + + /* Register GUID_DEVICE_SYS_BUTTON interface and report capability */ + if (DeviceExtension->NewCaps != DeviceExtension->ReportedCaps) + { + WaitingIrp = InterlockedExchangePointer((PVOID)&DeviceExtension->PowerIrp, NULL); + if (WaitingIrp) + { + /* Cancel the current power irp, as capability changed */ + WaitingIrp->IoStatus.Status = STATUS_UNSUCCESSFUL; + WaitingIrp->IoStatus.Information = sizeof(ULONG); + IoCompleteRequest(WaitingIrp, IO_NO_INCREMENT); + } + + if (DeviceExtension->PowerInterfaceName.MaximumLength == 0) + { + /* We have never registered this interface ; do it */ + Status = IoRegisterDeviceInterface( + DeviceExtension->Common.Pdo, + &GUID_DEVICE_SYS_BUTTON, + NULL, + &DeviceExtension->PowerInterfaceName); + if (!NT_SUCCESS(Status)) + { + /* We can't do more yet, ignore the keypress... */ + WARN_(I8042PRT, "IoRegisterDeviceInterface(GUID_DEVICE_SYS_BUTTON) failed with status 0x%08lx\n", + Status); + DeviceExtension->PowerInterfaceName.MaximumLength = 0; + return; + } + } + else + { + /* Disable the interface. Once activated again, capabilities would be asked again */ + Status = IoSetDeviceInterfaceState( + &DeviceExtension->PowerInterfaceName, + FALSE); + if (!NT_SUCCESS(Status)) + { + /* Ignore the key press... */ + WARN_(I8042PRT, "Disabling interface %wZ failed with status 0x%08lx\n", + &DeviceExtension->PowerInterfaceName, Status); + return; + } + } + /* Enable the interface. This leads to receiving a IOCTL_GET_SYS_BUTTON_CAPS, + * so we can report new capability */ + Status = IoSetDeviceInterfaceState( + &DeviceExtension->PowerInterfaceName, + TRUE); + if (!NT_SUCCESS(Status)) + { + /* Ignore the key press... */ + WARN_(I8042PRT, "Enabling interface %wZ failed with status 0x%08lx\n", + &DeviceExtension->PowerInterfaceName, Status); + return; + } + } + + /* Directly complete the IOCTL_GET_SYS_BUTTON_EVENT Irp (if any) */ + WaitingIrp = InterlockedExchangePointer((PVOID)&DeviceExtension->PowerIrp, NULL); + if (WaitingIrp) + { + PULONG pEvent = (PULONG)WaitingIrp->AssociatedIrp.SystemBuffer; + + WaitingIrp->IoStatus.Status = STATUS_SUCCESS; + WaitingIrp->IoStatus.Information = sizeof(ULONG); + *pEvent = InterlockedExchange((PLONG)&DeviceExtension->LastPowerKey, 0); + IoCompleteRequest(WaitingIrp, IO_NO_INCREMENT); + } } /* Return TRUE if it was a power key */ static BOOLEAN HandlePowerKeys( - IN PI8042_KEYBOARD_EXTENSION DeviceExtension) + IN PI8042_KEYBOARD_EXTENSION DeviceExtension) { - PKEYBOARD_INPUT_DATA InputData; - ULONG KeyPress; - - InputData = DeviceExtension->KeyboardBuffer + DeviceExtension->KeysInBuffer - 1; - if (!(InputData->Flags & KEY_E0)) - return FALSE; - - switch (InputData->MakeCode) - { - case KEYBOARD_POWER_CODE: - KeyPress = SYS_BUTTON_POWER; - break; - case KEYBOARD_SLEEP_CODE: - KeyPress = SYS_BUTTON_SLEEP; - break; - case KEYBOARD_WAKE_CODE: - KeyPress = SYS_BUTTON_WAKE; - break; - default: - return FALSE; - } + PKEYBOARD_INPUT_DATA InputData; + ULONG KeyPress; + + InputData = DeviceExtension->KeyboardBuffer + DeviceExtension->KeysInBuffer - 1; + if (!(InputData->Flags & KEY_E0)) + return FALSE; + + switch (InputData->MakeCode) + { + case KEYBOARD_POWER_CODE: + KeyPress = SYS_BUTTON_POWER; + break; + case KEYBOARD_SLEEP_CODE: + KeyPress = SYS_BUTTON_SLEEP; + break; + case KEYBOARD_WAKE_CODE: + KeyPress = SYS_BUTTON_WAKE; + break; + default: + return FALSE; + } if (InputData->Flags & KEY_BREAK) - /* We already took care of the key press */ - return TRUE; - - /* Our work can only be done at passive level, so use a workitem */ - DeviceExtension->NewCaps |= KeyPress; - InterlockedExchange((PLONG)&DeviceExtension->LastPowerKey, KeyPress); - IoQueueWorkItem( - DeviceExtension->PowerWorkItem, - &i8042PowerWorkItem, - DelayedWorkQueue, - DeviceExtension); - return TRUE; + return TRUE; /* We already took care of the key press */ + + /* Our work can only be done at passive level, so use a workitem */ + DeviceExtension->NewCaps |= KeyPress; + InterlockedExchange((PLONG)&DeviceExtension->LastPowerKey, KeyPress); + IoQueueWorkItem( + DeviceExtension->PowerWorkItem, + &i8042PowerWorkItem, + DelayedWorkQueue, + DeviceExtension); + return TRUE; } static VOID NTAPI i8042KbdDpcRoutine( - IN PKDPC Dpc, - IN PVOID DeferredContext, - IN PVOID SystemArgument1, - IN PVOID SystemArgument2) + IN PKDPC Dpc, + IN PVOID DeferredContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2) { - PI8042_KEYBOARD_EXTENSION DeviceExtension; - PPORT_DEVICE_EXTENSION PortDeviceExtension; - ULONG KeysTransferred = 0; - ULONG KeysInBufferCopy; - KIRQL Irql; - - UNREFERENCED_PARAMETER(Dpc); - UNREFERENCED_PARAMETER(SystemArgument1); - UNREFERENCED_PARAMETER(SystemArgument2); - - __analysis_assume(DeferredContext != NULL); - DeviceExtension = DeferredContext; - PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; - - if (HandlePowerKeys(DeviceExtension)) - { - DeviceExtension->KeyComplete = FALSE; - return; - } - - i8042PacketDpc(PortDeviceExtension); - if (!DeviceExtension->KeyComplete) - return; - /* We got the interrupt as it was being enabled, too bad */ - if (!PortDeviceExtension->HighestDIRQLInterrupt) - return; - - Irql = KeAcquireInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt); - - DeviceExtension->KeyComplete = FALSE; - KeysInBufferCopy = DeviceExtension->KeysInBuffer; - - KeReleaseInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt, Irql); - - TRACE_(I8042PRT, "Send a key\n"); - - if (!DeviceExtension->KeyboardData.ClassService) - return; - - INFO_(I8042PRT, "Sending %lu key(s)\n", KeysInBufferCopy); - (*(PSERVICE_CALLBACK_ROUTINE)DeviceExtension->KeyboardData.ClassService)( - DeviceExtension->KeyboardData.ClassDeviceObject, - DeviceExtension->KeyboardBuffer, - DeviceExtension->KeyboardBuffer + KeysInBufferCopy, - &KeysTransferred); - - /* Validate that the callback didn't change the Irql. */ - ASSERT(KeGetCurrentIrql() == Irql); - - Irql = KeAcquireInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt); - DeviceExtension->KeysInBuffer -= KeysTransferred; - KeReleaseInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt, Irql); + PI8042_KEYBOARD_EXTENSION DeviceExtension; + PPORT_DEVICE_EXTENSION PortDeviceExtension; + ULONG KeysTransferred = 0; + ULONG KeysInBufferCopy; + KIRQL Irql; + + UNREFERENCED_PARAMETER(Dpc); + UNREFERENCED_PARAMETER(SystemArgument1); + UNREFERENCED_PARAMETER(SystemArgument2); + + __analysis_assume(DeferredContext != NULL); + DeviceExtension = DeferredContext; + PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; + + if (HandlePowerKeys(DeviceExtension)) + { + DeviceExtension->KeyComplete = FALSE; + return; + } + + i8042PacketDpc(PortDeviceExtension); + if (!DeviceExtension->KeyComplete) + return; + /* We got the interrupt as it was being enabled, too bad */ + if (!PortDeviceExtension->HighestDIRQLInterrupt) + return; + + Irql = KeAcquireInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt); + + DeviceExtension->KeyComplete = FALSE; + KeysInBufferCopy = DeviceExtension->KeysInBuffer; + + KeReleaseInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt, Irql); + + TRACE_(I8042PRT, "Send a key\n"); + + if (!DeviceExtension->KeyboardData.ClassService) + return; + + INFO_(I8042PRT, "Sending %lu key(s)\n", KeysInBufferCopy); + (*(PSERVICE_CALLBACK_ROUTINE)DeviceExtension->KeyboardData.ClassService)( + DeviceExtension->KeyboardData.ClassDeviceObject, + DeviceExtension->KeyboardBuffer, + DeviceExtension->KeyboardBuffer + KeysInBufferCopy, + &KeysTransferred); + + /* Validate that the callback didn't change the Irql. */ + ASSERT(KeGetCurrentIrql() == Irql); + + Irql = KeAcquireInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt); + DeviceExtension->KeysInBuffer -= KeysTransferred; + KeReleaseInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt, Irql); } /* @@ -382,100 +386,104 @@ i8042KbdDpcRoutine( */ NTSTATUS NTAPI i8042KbdDeviceControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) { - PIO_STACK_LOCATION Stack; - PI8042_KEYBOARD_EXTENSION DeviceExtension; - NTSTATUS Status; - - Stack = IoGetCurrentIrpStackLocation(Irp); - Irp->IoStatus.Information = 0; - DeviceExtension = (PI8042_KEYBOARD_EXTENSION)DeviceObject->DeviceExtension; - - switch (Stack->Parameters.DeviceIoControl.IoControlCode) - { - case IOCTL_GET_SYS_BUTTON_CAPS: - { - /* Part of GUID_DEVICE_SYS_BUTTON interface */ - PULONG pCaps; - TRACE_(I8042PRT, "IOCTL_GET_SYS_BUTTON_CAPS\n"); - - if (Stack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(ULONG)) - Status = STATUS_INVALID_PARAMETER; - else - { - pCaps = (PULONG)Irp->AssociatedIrp.SystemBuffer; - *pCaps = DeviceExtension->NewCaps; - DeviceExtension->ReportedCaps = DeviceExtension->NewCaps; - Irp->IoStatus.Information = sizeof(ULONG); - Status = STATUS_SUCCESS; - } - break; - } - case IOCTL_GET_SYS_BUTTON_EVENT: - { - /* Part of GUID_DEVICE_SYS_BUTTON interface */ - PIRP WaitingIrp; - TRACE_(I8042PRT, "IOCTL_GET_SYS_BUTTON_EVENT\n"); - - if (Stack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(ULONG)) - Status = STATUS_INVALID_PARAMETER; - else - { - WaitingIrp = InterlockedCompareExchangePointer( - (PVOID)&DeviceExtension->PowerIrp, - Irp, - NULL); - /* Check if an Irp is already pending */ - if (WaitingIrp) - { - /* Unable to have a 2nd pending IRP for this IOCTL */ - WARN_(I8042PRT, "Unable to pend a second IRP for IOCTL_GET_SYS_BUTTON_EVENT\n"); - Status = STATUS_INVALID_PARAMETER; - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - } - else - { - ULONG PowerKey; - PowerKey = InterlockedExchange((PLONG)&DeviceExtension->LastPowerKey, 0); - if (PowerKey != 0) - { - (VOID)InterlockedCompareExchangePointer((PVOID)&DeviceExtension->PowerIrp, NULL, Irp); - *(PULONG)Irp->AssociatedIrp.SystemBuffer = PowerKey; - Status = STATUS_SUCCESS; - Irp->IoStatus.Status = Status; - Irp->IoStatus.Information = sizeof(ULONG); - IoCompleteRequest(Irp, IO_NO_INCREMENT); - } - else - { - TRACE_(I8042PRT, "Pending IOCTL_GET_SYS_BUTTON_EVENT\n"); - Status = STATUS_PENDING; - Irp->IoStatus.Status = Status; - IoMarkIrpPending(Irp); - } - } - return Status; - } - break; - } - default: - { - ERR_(I8042PRT, "IRP_MJ_DEVICE_CONTROL / unknown ioctl code 0x%lx\n", - Stack->Parameters.DeviceIoControl.IoControlCode); - return ForwardIrpAndForget(DeviceObject, Irp); - } - } - - if (Status != STATUS_PENDING) - { - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - } - - return Status; + PIO_STACK_LOCATION Stack; + PI8042_KEYBOARD_EXTENSION DeviceExtension; + NTSTATUS Status; + + Stack = IoGetCurrentIrpStackLocation(Irp); + Irp->IoStatus.Information = 0; + DeviceExtension = (PI8042_KEYBOARD_EXTENSION)DeviceObject->DeviceExtension; + + switch (Stack->Parameters.DeviceIoControl.IoControlCode) + { + case IOCTL_GET_SYS_BUTTON_CAPS: + { + /* Part of GUID_DEVICE_SYS_BUTTON interface */ + PULONG pCaps; + TRACE_(I8042PRT, "IOCTL_GET_SYS_BUTTON_CAPS\n"); + + if (Stack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(ULONG)) + { + Status = STATUS_INVALID_PARAMETER; + } + else + { + pCaps = (PULONG)Irp->AssociatedIrp.SystemBuffer; + *pCaps = DeviceExtension->NewCaps; + DeviceExtension->ReportedCaps = DeviceExtension->NewCaps; + Irp->IoStatus.Information = sizeof(ULONG); + Status = STATUS_SUCCESS; + } + break; + } + case IOCTL_GET_SYS_BUTTON_EVENT: + { + /* Part of GUID_DEVICE_SYS_BUTTON interface */ + PIRP WaitingIrp; + TRACE_(I8042PRT, "IOCTL_GET_SYS_BUTTON_EVENT\n"); + + if (Stack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(ULONG)) + { + Status = STATUS_INVALID_PARAMETER; + } + else + { + WaitingIrp = InterlockedCompareExchangePointer( + (PVOID)&DeviceExtension->PowerIrp, + Irp, + NULL); + /* Check if an Irp is already pending */ + if (WaitingIrp) + { + /* Unable to have a 2nd pending IRP for this IOCTL */ + WARN_(I8042PRT, "Unable to pend a second IRP for IOCTL_GET_SYS_BUTTON_EVENT\n"); + Status = STATUS_INVALID_PARAMETER; + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + } + else + { + ULONG PowerKey; + PowerKey = InterlockedExchange((PLONG)&DeviceExtension->LastPowerKey, 0); + if (PowerKey != 0) + { + (VOID)InterlockedCompareExchangePointer((PVOID)&DeviceExtension->PowerIrp, NULL, Irp); + *(PULONG)Irp->AssociatedIrp.SystemBuffer = PowerKey; + Status = STATUS_SUCCESS; + Irp->IoStatus.Status = Status; + Irp->IoStatus.Information = sizeof(ULONG); + IoCompleteRequest(Irp, IO_NO_INCREMENT); + } + else + { + TRACE_(I8042PRT, "Pending IOCTL_GET_SYS_BUTTON_EVENT\n"); + Status = STATUS_PENDING; + Irp->IoStatus.Status = Status; + IoMarkIrpPending(Irp); + } + } + return Status; + } + break; + } + default: + { + ERR_(I8042PRT, "IRP_MJ_DEVICE_CONTROL / unknown ioctl code 0x%lx\n", + Stack->Parameters.DeviceIoControl.IoControlCode); + return ForwardIrpAndForget(DeviceObject, Irp); + } + } + + if (Status != STATUS_PENDING) + { + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + } + + return Status; } VOID @@ -511,241 +519,241 @@ i8042InitializeKeyboardAttributes( */ NTSTATUS NTAPI i8042KbdInternalDeviceControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) { - PIO_STACK_LOCATION Stack; - PI8042_KEYBOARD_EXTENSION DeviceExtension; - NTSTATUS Status; - - Stack = IoGetCurrentIrpStackLocation(Irp); - Irp->IoStatus.Information = 0; - DeviceExtension = (PI8042_KEYBOARD_EXTENSION)DeviceObject->DeviceExtension; - - switch (Stack->Parameters.DeviceIoControl.IoControlCode) - { - case IOCTL_INTERNAL_KEYBOARD_CONNECT: - { - SIZE_T Size; - PIO_WORKITEM WorkItem = NULL; - PI8042_HOOK_WORKITEM WorkItemData = NULL; - - TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_KEYBOARD_CONNECT\n"); - if (Stack->Parameters.DeviceIoControl.InputBufferLength != sizeof(CONNECT_DATA)) - { - Status = STATUS_INVALID_PARAMETER; - goto cleanup; - } - - DeviceExtension->KeyboardData = - *((PCONNECT_DATA)Stack->Parameters.DeviceIoControl.Type3InputBuffer); - - /* Send IOCTL_INTERNAL_I8042_HOOK_KEYBOARD to device stack */ - WorkItem = IoAllocateWorkItem(DeviceObject); - if (!WorkItem) - { - WARN_(I8042PRT, "IoAllocateWorkItem() failed\n"); - Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; - } - WorkItemData = ExAllocatePoolWithTag( - NonPagedPool, - sizeof(I8042_HOOK_WORKITEM), - I8042PRT_TAG); - if (!WorkItemData) - { - WARN_(I8042PRT, "ExAllocatePoolWithTag() failed\n"); - Status = STATUS_NO_MEMORY; - goto cleanup; - } - WorkItemData->WorkItem = WorkItem; - WorkItemData->Irp = Irp; - - /* Initialize extension */ - DeviceExtension->Common.Type = Keyboard; - Size = DeviceExtension->Common.PortDeviceExtension->Settings.KeyboardDataQueueSize * sizeof(KEYBOARD_INPUT_DATA); - DeviceExtension->KeyboardBuffer = ExAllocatePoolWithTag( - NonPagedPool, - Size, - I8042PRT_TAG); - if (!DeviceExtension->KeyboardBuffer) - { - WARN_(I8042PRT, "ExAllocatePoolWithTag() failed\n"); - Status = STATUS_NO_MEMORY; - goto cleanup; - } - RtlZeroMemory(DeviceExtension->KeyboardBuffer, Size); - KeInitializeDpc( - &DeviceExtension->DpcKeyboard, - i8042KbdDpcRoutine, - DeviceExtension); - DeviceExtension->PowerWorkItem = IoAllocateWorkItem(DeviceObject); - if (!DeviceExtension->PowerWorkItem) - { - WARN_(I8042PRT, "IoAllocateWorkItem() failed\n"); - Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; - } - DeviceExtension->DebugWorkItem = IoAllocateWorkItem(DeviceObject); - if (!DeviceExtension->DebugWorkItem) - { - WARN_(I8042PRT, "IoAllocateWorkItem() failed\n"); - Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; - } - DeviceExtension->Common.PortDeviceExtension->KeyboardExtension = DeviceExtension; - DeviceExtension->Common.PortDeviceExtension->Flags |= KEYBOARD_CONNECTED; + PIO_STACK_LOCATION Stack; + PI8042_KEYBOARD_EXTENSION DeviceExtension; + NTSTATUS Status; + + Stack = IoGetCurrentIrpStackLocation(Irp); + Irp->IoStatus.Information = 0; + DeviceExtension = (PI8042_KEYBOARD_EXTENSION)DeviceObject->DeviceExtension; + + switch (Stack->Parameters.DeviceIoControl.IoControlCode) + { + case IOCTL_INTERNAL_KEYBOARD_CONNECT: + { + SIZE_T Size; + PIO_WORKITEM WorkItem = NULL; + PI8042_HOOK_WORKITEM WorkItemData = NULL; + + TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_KEYBOARD_CONNECT\n"); + if (Stack->Parameters.DeviceIoControl.InputBufferLength != sizeof(CONNECT_DATA)) + { + Status = STATUS_INVALID_PARAMETER; + goto cleanup; + } + + DeviceExtension->KeyboardData = + *((PCONNECT_DATA)Stack->Parameters.DeviceIoControl.Type3InputBuffer); + + /* Send IOCTL_INTERNAL_I8042_HOOK_KEYBOARD to device stack */ + WorkItem = IoAllocateWorkItem(DeviceObject); + if (!WorkItem) + { + WARN_(I8042PRT, "IoAllocateWorkItem() failed\n"); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto cleanup; + } + WorkItemData = ExAllocatePoolWithTag( + NonPagedPool, + sizeof(I8042_HOOK_WORKITEM), + I8042PRT_TAG); + if (!WorkItemData) + { + WARN_(I8042PRT, "ExAllocatePoolWithTag() failed\n"); + Status = STATUS_NO_MEMORY; + goto cleanup; + } + WorkItemData->WorkItem = WorkItem; + WorkItemData->Irp = Irp; + + /* Initialize extension */ + DeviceExtension->Common.Type = Keyboard; + Size = DeviceExtension->Common.PortDeviceExtension->Settings.KeyboardDataQueueSize * sizeof(KEYBOARD_INPUT_DATA); + DeviceExtension->KeyboardBuffer = ExAllocatePoolWithTag( + NonPagedPool, + Size, + I8042PRT_TAG); + if (!DeviceExtension->KeyboardBuffer) + { + WARN_(I8042PRT, "ExAllocatePoolWithTag() failed\n"); + Status = STATUS_NO_MEMORY; + goto cleanup; + } + RtlZeroMemory(DeviceExtension->KeyboardBuffer, Size); + KeInitializeDpc( + &DeviceExtension->DpcKeyboard, + i8042KbdDpcRoutine, + DeviceExtension); + DeviceExtension->PowerWorkItem = IoAllocateWorkItem(DeviceObject); + if (!DeviceExtension->PowerWorkItem) + { + WARN_(I8042PRT, "IoAllocateWorkItem() failed\n"); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto cleanup; + } + DeviceExtension->DebugWorkItem = IoAllocateWorkItem(DeviceObject); + if (!DeviceExtension->DebugWorkItem) + { + WARN_(I8042PRT, "IoAllocateWorkItem() failed\n"); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto cleanup; + } + DeviceExtension->Common.PortDeviceExtension->KeyboardExtension = DeviceExtension; + DeviceExtension->Common.PortDeviceExtension->Flags |= KEYBOARD_CONNECTED; i8042InitializeKeyboardAttributes(DeviceExtension); - IoMarkIrpPending(Irp); - /* FIXME: DeviceExtension->KeyboardHook.IsrWritePort = ; */ - DeviceExtension->KeyboardHook.QueueKeyboardPacket = i8042KbdQueuePacket; - DeviceExtension->KeyboardHook.CallContext = DeviceExtension; - IoQueueWorkItem(WorkItem, - i8042SendHookWorkItem, - DelayedWorkQueue, - WorkItemData); - Status = STATUS_PENDING; - break; + IoMarkIrpPending(Irp); + /* FIXME: DeviceExtension->KeyboardHook.IsrWritePort = ; */ + DeviceExtension->KeyboardHook.QueueKeyboardPacket = i8042KbdQueuePacket; + DeviceExtension->KeyboardHook.CallContext = DeviceExtension; + IoQueueWorkItem(WorkItem, + i8042SendHookWorkItem, + DelayedWorkQueue, + WorkItemData); + Status = STATUS_PENDING; + break; cleanup: - if (DeviceExtension->KeyboardBuffer) - ExFreePoolWithTag(DeviceExtension->KeyboardBuffer, I8042PRT_TAG); - if (DeviceExtension->PowerWorkItem) - IoFreeWorkItem(DeviceExtension->PowerWorkItem); - if (DeviceExtension->DebugWorkItem) - IoFreeWorkItem(DeviceExtension->DebugWorkItem); - if (WorkItem) - IoFreeWorkItem(WorkItem); - if (WorkItemData) - ExFreePoolWithTag(WorkItemData, I8042PRT_TAG); - break; - } - case IOCTL_INTERNAL_KEYBOARD_DISCONNECT: - { - TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_KEYBOARD_DISCONNECT\n"); - /* MSDN says that operation is to implemented. - * To implement it, we just have to do: - * DeviceExtension->KeyboardData.ClassService = NULL; - */ - Status = STATUS_NOT_IMPLEMENTED; - break; - } - case IOCTL_INTERNAL_I8042_HOOK_KEYBOARD: - { - TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_I8042_HOOK_KEYBOARD\n"); - /* Nothing to do here */ - Status = STATUS_SUCCESS; - break; - } - case IOCTL_KEYBOARD_QUERY_ATTRIBUTES: - { - PKEYBOARD_ATTRIBUTES KeyboardAttributes; + if (DeviceExtension->KeyboardBuffer) + ExFreePoolWithTag(DeviceExtension->KeyboardBuffer, I8042PRT_TAG); + if (DeviceExtension->PowerWorkItem) + IoFreeWorkItem(DeviceExtension->PowerWorkItem); + if (DeviceExtension->DebugWorkItem) + IoFreeWorkItem(DeviceExtension->DebugWorkItem); + if (WorkItem) + IoFreeWorkItem(WorkItem); + if (WorkItemData) + ExFreePoolWithTag(WorkItemData, I8042PRT_TAG); + break; + } + case IOCTL_INTERNAL_KEYBOARD_DISCONNECT: + { + TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_KEYBOARD_DISCONNECT\n"); + /* MSDN says that operation is to implemented. + * To implement it, we just have to do: + * DeviceExtension->KeyboardData.ClassService = NULL; + */ + Status = STATUS_NOT_IMPLEMENTED; + break; + } + case IOCTL_INTERNAL_I8042_HOOK_KEYBOARD: + { + TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_I8042_HOOK_KEYBOARD\n"); + /* Nothing to do here */ + Status = STATUS_SUCCESS; + break; + } + case IOCTL_KEYBOARD_QUERY_ATTRIBUTES: + { + PKEYBOARD_ATTRIBUTES KeyboardAttributes; /* FIXME: KeyboardAttributes are not initialized anywhere */ - TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_QUERY_ATTRIBUTES\n"); - if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KEYBOARD_ATTRIBUTES)) - { - Status = STATUS_BUFFER_TOO_SMALL; - break; - } + TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_QUERY_ATTRIBUTES\n"); + if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KEYBOARD_ATTRIBUTES)) + { + Status = STATUS_BUFFER_TOO_SMALL; + break; + } KeyboardAttributes = Irp->AssociatedIrp.SystemBuffer; *KeyboardAttributes = DeviceExtension->KeyboardAttributes; - Irp->IoStatus.Information = sizeof(KEYBOARD_ATTRIBUTES); - Status = STATUS_SUCCESS; - break; - } - case IOCTL_KEYBOARD_QUERY_TYPEMATIC: - { - DPRINT1("IOCTL_KEYBOARD_QUERY_TYPEMATIC not implemented\n"); - Status = STATUS_NOT_IMPLEMENTED; - break; - } - case IOCTL_KEYBOARD_SET_TYPEMATIC: - { - DPRINT1("IOCTL_KEYBOARD_SET_TYPEMATIC not implemented\n"); - Status = STATUS_NOT_IMPLEMENTED; - break; - } - case IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION: - { - TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION\n"); - - /* We should check the UnitID, but it's kind of pointless as - * all keyboards are supposed to have the same one - */ - if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION)) - { - Status = STATUS_BUFFER_TOO_SMALL; - } - else - { - RtlCopyMemory( - Irp->AssociatedIrp.SystemBuffer, - &IndicatorTranslation, - sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION)); - Irp->IoStatus.Information = sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION); - Status = STATUS_SUCCESS; - } - break; - } - case IOCTL_KEYBOARD_QUERY_INDICATORS: - { - TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_QUERY_INDICATORS\n"); - - if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KEYBOARD_INDICATOR_PARAMETERS)) - { - Status = STATUS_BUFFER_TOO_SMALL; - } - else - { - RtlCopyMemory( - Irp->AssociatedIrp.SystemBuffer, - &DeviceExtension->KeyboardIndicators, - sizeof(KEYBOARD_INDICATOR_PARAMETERS)); - Irp->IoStatus.Information = sizeof(KEYBOARD_INDICATOR_PARAMETERS); - Status = STATUS_SUCCESS; - } - break; - } - case IOCTL_KEYBOARD_SET_INDICATORS: - { - TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_SET_INDICATORS\n"); - - if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KEYBOARD_INDICATOR_PARAMETERS)) - { - Status = STATUS_BUFFER_TOO_SMALL; - } - else - { - RtlCopyMemory( - &DeviceExtension->KeyboardIndicators, - Irp->AssociatedIrp.SystemBuffer, - sizeof(KEYBOARD_INDICATOR_PARAMETERS)); - Status = STATUS_PENDING; - IoMarkIrpPending(Irp); - IoStartPacket(DeviceObject, Irp, NULL, NULL); - } - break; - } - default: - { - ERR_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / unknown ioctl code 0x%lx\n", - Stack->Parameters.DeviceIoControl.IoControlCode); - ASSERT(FALSE); - return ForwardIrpAndForget(DeviceObject, Irp); - } - } - - if (Status != STATUS_PENDING) - { - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - } - return Status; + Irp->IoStatus.Information = sizeof(KEYBOARD_ATTRIBUTES); + Status = STATUS_SUCCESS; + break; + } + case IOCTL_KEYBOARD_QUERY_TYPEMATIC: + { + DPRINT1("IOCTL_KEYBOARD_QUERY_TYPEMATIC not implemented\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + } + case IOCTL_KEYBOARD_SET_TYPEMATIC: + { + DPRINT1("IOCTL_KEYBOARD_SET_TYPEMATIC not implemented\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + } + case IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION: + { + TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION\n"); + + /* We should check the UnitID, but it's kind of pointless as + * all keyboards are supposed to have the same one + */ + if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION)) + { + Status = STATUS_BUFFER_TOO_SMALL; + } + else + { + RtlCopyMemory( + Irp->AssociatedIrp.SystemBuffer, + &IndicatorTranslation, + sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION)); + Irp->IoStatus.Information = sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION); + Status = STATUS_SUCCESS; + } + break; + } + case IOCTL_KEYBOARD_QUERY_INDICATORS: + { + TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_QUERY_INDICATORS\n"); + + if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KEYBOARD_INDICATOR_PARAMETERS)) + { + Status = STATUS_BUFFER_TOO_SMALL; + } + else + { + RtlCopyMemory( + Irp->AssociatedIrp.SystemBuffer, + &DeviceExtension->KeyboardIndicators, + sizeof(KEYBOARD_INDICATOR_PARAMETERS)); + Irp->IoStatus.Information = sizeof(KEYBOARD_INDICATOR_PARAMETERS); + Status = STATUS_SUCCESS; + } + break; + } + case IOCTL_KEYBOARD_SET_INDICATORS: + { + TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_SET_INDICATORS\n"); + + if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KEYBOARD_INDICATOR_PARAMETERS)) + { + Status = STATUS_BUFFER_TOO_SMALL; + } + else + { + RtlCopyMemory( + &DeviceExtension->KeyboardIndicators, + Irp->AssociatedIrp.SystemBuffer, + sizeof(KEYBOARD_INDICATOR_PARAMETERS)); + Status = STATUS_PENDING; + IoMarkIrpPending(Irp); + IoStartPacket(DeviceObject, Irp, NULL, NULL); + } + break; + } + default: + { + ERR_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / unknown ioctl code 0x%lx\n", + Stack->Parameters.DeviceIoControl.IoControlCode); + ASSERT(FALSE); + return ForwardIrpAndForget(DeviceObject, Irp); + } + } + + if (Status != STATUS_PENDING) + { + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + } + return Status; } /* @@ -756,104 +764,110 @@ i8042KbdInternalDeviceControl( */ static BOOLEAN i8042KbdCallIsrHook( - IN PI8042_KEYBOARD_EXTENSION DeviceExtension, - IN UCHAR Status, - IN UCHAR Input, - OUT PBOOLEAN ToReturn) + IN PI8042_KEYBOARD_EXTENSION DeviceExtension, + IN UCHAR Status, + IN UCHAR Input, + OUT PBOOLEAN ToReturn) { - BOOLEAN HookReturn, HookContinue; - - HookContinue = FALSE; - - if (DeviceExtension->KeyboardHook.IsrRoutine) - { - HookReturn = DeviceExtension->KeyboardHook.IsrRoutine( - DeviceExtension->KeyboardHook.Context, - DeviceExtension->KeyboardBuffer + DeviceExtension->KeysInBuffer, - &DeviceExtension->Common.PortDeviceExtension->Packet, - Status, - &Input, - &HookContinue, - &DeviceExtension->KeyboardScanState); - - if (!HookContinue) - { - *ToReturn = HookReturn; - return TRUE; - } - } - return FALSE; + BOOLEAN HookReturn, HookContinue; + + HookContinue = FALSE; + + if (DeviceExtension->KeyboardHook.IsrRoutine) + { + HookReturn = DeviceExtension->KeyboardHook.IsrRoutine( + DeviceExtension->KeyboardHook.Context, + DeviceExtension->KeyboardBuffer + DeviceExtension->KeysInBuffer, + &DeviceExtension->Common.PortDeviceExtension->Packet, + Status, + &Input, + &HookContinue, + &DeviceExtension->KeyboardScanState); + + if (!HookContinue) + { + *ToReturn = HookReturn; + return TRUE; + } + } + return FALSE; } BOOLEAN NTAPI i8042KbdInterruptService( - IN PKINTERRUPT Interrupt, - PVOID Context) + IN PKINTERRUPT Interrupt, + PVOID Context) { - PI8042_KEYBOARD_EXTENSION DeviceExtension; - PPORT_DEVICE_EXTENSION PortDeviceExtension; - PKEYBOARD_INPUT_DATA InputData; - ULONG Counter; - UCHAR PortStatus = 0, Output = 0; - BOOLEAN ToReturn = FALSE; - NTSTATUS Status; - - UNREFERENCED_PARAMETER(Interrupt); - - __analysis_assume(Context != NULL); - DeviceExtension = Context; - PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; - InputData = DeviceExtension->KeyboardBuffer + DeviceExtension->KeysInBuffer; - Counter = PortDeviceExtension->Settings.PollStatusIterations; - - while (Counter) - { - Status = i8042ReadStatus(PortDeviceExtension, &PortStatus); - if (!NT_SUCCESS(Status)) - { - WARN_(I8042PRT, "i8042ReadStatus() failed with status 0x%08lx\n", Status); - return FALSE; - } - Status = i8042ReadKeyboardData(PortDeviceExtension, &Output); - if (NT_SUCCESS(Status)) - break; - KeStallExecutionProcessor(1); - Counter--; - } - if (Counter == 0) - { - WARN_(I8042PRT, "Spurious i8042 keyboard interrupt\n"); - return FALSE; - } - - INFO_(I8042PRT, "Got: 0x%02x\n", Output); - - if (PortDeviceExtension->Settings.CrashOnCtrlScroll) - { - /* Test for CTRL + SCROLL LOCK twice */ - static const UCHAR ScanCodes[] = { 0x1d, 0x46, 0xc6, 0x46, 0 }; - - if (Output == ScanCodes[DeviceExtension->ComboPosition]) - { - DeviceExtension->ComboPosition++; - if (ScanCodes[DeviceExtension->ComboPosition] == 0) - KeBugCheck(MANUALLY_INITIATED_CRASH); - } - else if (Output == 0xfa) - { - /* Ignore ACK */ - } - else if (Output == ScanCodes[0]) - DeviceExtension->ComboPosition = 1; - else - DeviceExtension->ComboPosition = 0; - - /* Test for TAB + key combination */ - if (InputData->MakeCode == 0x0F) - DeviceExtension->TabPressed = !(InputData->Flags & KEY_BREAK); - else if (DeviceExtension->TabPressed) - { - DeviceExtension->TabPressed = FALSE; + PI8042_KEYBOARD_EXTENSION DeviceExtension; + PPORT_DEVICE_EXTENSION PortDeviceExtension; + PKEYBOARD_INPUT_DATA InputData; + ULONG Counter; + UCHAR PortStatus = 0, Output = 0; + BOOLEAN ToReturn = FALSE; + NTSTATUS Status; + + UNREFERENCED_PARAMETER(Interrupt); + + __analysis_assume(Context != NULL); + DeviceExtension = Context; + PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; + InputData = DeviceExtension->KeyboardBuffer + DeviceExtension->KeysInBuffer; + Counter = PortDeviceExtension->Settings.PollStatusIterations; + + while (Counter) + { + Status = i8042ReadStatus(PortDeviceExtension, &PortStatus); + if (!NT_SUCCESS(Status)) + { + WARN_(I8042PRT, "i8042ReadStatus() failed with status 0x%08lx\n", Status); + return FALSE; + } + Status = i8042ReadKeyboardData(PortDeviceExtension, &Output); + if (NT_SUCCESS(Status)) + break; + KeStallExecutionProcessor(1); + Counter--; + } + if (Counter == 0) + { + WARN_(I8042PRT, "Spurious i8042 keyboard interrupt\n"); + return FALSE; + } + + INFO_(I8042PRT, "Got: 0x%02x\n", Output); + + if (PortDeviceExtension->Settings.CrashOnCtrlScroll) + { + /* Test for CTRL + SCROLL LOCK twice */ + static const UCHAR ScanCodes[] = { 0x1d, 0x46, 0xc6, 0x46, 0 }; + + if (Output == ScanCodes[DeviceExtension->ComboPosition]) + { + DeviceExtension->ComboPosition++; + if (ScanCodes[DeviceExtension->ComboPosition] == 0) + KeBugCheck(MANUALLY_INITIATED_CRASH); + } + else if (Output == 0xfa) + { + /* Ignore ACK */ + } + else if (Output == ScanCodes[0]) + { + DeviceExtension->ComboPosition = 1; + } + else + { + DeviceExtension->ComboPosition = 0; + } + + /* Test for TAB + key combination */ + if (InputData->MakeCode == 0x0F) + { + DeviceExtension->TabPressed = !(InputData->Flags & KEY_BREAK); + } + else if (DeviceExtension->TabPressed) + { + DeviceExtension->TabPressed = FALSE; /* Check which action to do */ if (InputData->MakeCode == 0x25) @@ -868,72 +882,72 @@ i8042KbdInterruptService( } else { - /* Send request to the kernel debugger. - * Unknown requests will be ignored. */ - KdSystemDebugControl(' soR', - (PVOID)(ULONG_PTR)InputData->MakeCode, - 0, - NULL, - 0, - NULL, - KernelMode); + /* Send request to the kernel debugger. + * Unknown requests will be ignored. */ + KdSystemDebugControl(' soR', + (PVOID)(ULONG_PTR)InputData->MakeCode, + 0, + NULL, + 0, + NULL, + KernelMode); } - } - } - - if (i8042KbdCallIsrHook(DeviceExtension, PortStatus, Output, &ToReturn)) - return ToReturn; - - if (i8042PacketIsr(PortDeviceExtension, Output)) - { - if (PortDeviceExtension->PacketComplete) - { - TRACE_(I8042PRT, "Packet complete\n"); - KeInsertQueueDpc(&DeviceExtension->DpcKeyboard, NULL, NULL); - } - TRACE_(I8042PRT, "Irq eaten by packet\n"); - return TRUE; - } - - TRACE_(I8042PRT, "Irq is keyboard input\n"); - - if (DeviceExtension->KeyboardScanState == Normal) - { - switch (Output) - { - case 0xe0: - DeviceExtension->KeyboardScanState = GotE0; - return TRUE; - case 0xe1: - DeviceExtension->KeyboardScanState = GotE1; - return TRUE; - default: - break; - } - } - - /* Update InputData */ - InputData->Flags = 0; - switch (DeviceExtension->KeyboardScanState) - { - case GotE0: - InputData->Flags |= KEY_E0; - break; - case GotE1: - InputData->Flags |= KEY_E1; - break; - default: - break; - } - DeviceExtension->KeyboardScanState = Normal; - if (Output & 0x80) - InputData->Flags |= KEY_BREAK; - else - InputData->Flags |= KEY_MAKE; - InputData->MakeCode = Output & 0x7f; - InputData->Reserved = 0; - - DeviceExtension->KeyboardHook.QueueKeyboardPacket(DeviceExtension->KeyboardHook.CallContext); - - return TRUE; + } + } + + if (i8042KbdCallIsrHook(DeviceExtension, PortStatus, Output, &ToReturn)) + return ToReturn; + + if (i8042PacketIsr(PortDeviceExtension, Output)) + { + if (PortDeviceExtension->PacketComplete) + { + TRACE_(I8042PRT, "Packet complete\n"); + KeInsertQueueDpc(&DeviceExtension->DpcKeyboard, NULL, NULL); + } + TRACE_(I8042PRT, "Irq eaten by packet\n"); + return TRUE; + } + + TRACE_(I8042PRT, "Irq is keyboard input\n"); + + if (DeviceExtension->KeyboardScanState == Normal) + { + switch (Output) + { + case 0xe0: + DeviceExtension->KeyboardScanState = GotE0; + return TRUE; + case 0xe1: + DeviceExtension->KeyboardScanState = GotE1; + return TRUE; + default: + break; + } + } + + /* Update InputData */ + InputData->Flags = 0; + switch (DeviceExtension->KeyboardScanState) + { + case GotE0: + InputData->Flags |= KEY_E0; + break; + case GotE1: + InputData->Flags |= KEY_E1; + break; + default: + break; + } + DeviceExtension->KeyboardScanState = Normal; + if (Output & 0x80) + InputData->Flags |= KEY_BREAK; + else + InputData->Flags |= KEY_MAKE; + InputData->MakeCode = Output & 0x7f; + InputData->Reserved = 0; + + DeviceExtension->KeyboardHook.QueueKeyboardPacket(DeviceExtension->KeyboardHook.CallContext); + + return TRUE; } diff --git a/drivers/input/i8042prt/registry.c b/drivers/input/i8042prt/registry.c index 9a675daa7427d..bf1e4fa928cc8 100644 --- a/drivers/input/i8042prt/registry.c +++ b/drivers/input/i8042prt/registry.c @@ -19,215 +19,213 @@ NTSTATUS ReadRegistryEntries( - IN PUNICODE_STRING RegistryPath, - OUT PI8042_SETTINGS Settings) + IN PUNICODE_STRING RegistryPath, + OUT PI8042_SETTINGS Settings) { - RTL_QUERY_REGISTRY_TABLE Parameters[17]; - NTSTATUS Status; - - ULONG DefaultKeyboardDataQueueSize = 0x64; - PCWSTR DefaultKeyboardDeviceBaseName = L"KeyboardPort"; - ULONG DefaultMouseDataQueueSize = 0x64; - ULONG DefaultMouseResolution = 3; - ULONG DefaultMouseSynchIn100ns = 20000000; - ULONG DefaultNumberOfButtons = 2; - PCWSTR DefaultPointerDeviceBaseName = L"PointerPort"; - ULONG DefaultPollStatusIterations = 1; - ULONG DefaultOverrideKeyboardType = 4; - ULONG DefaultOverrideKeyboardSubtype = 0; - ULONG DefaultPollingIterations = 12000; - ULONG DefaultPollingIterationsMaximum = 12000; - ULONG DefaultResendIterations = 0x3; - ULONG DefaultSampleRate = 60; - ULONG DefaultCrashOnCtrlScroll; - - /* Default value for CrashOnCtrlScroll depends if we're - * running a debug build or a normal build. - */ + RTL_QUERY_REGISTRY_TABLE Parameters[17]; + NTSTATUS Status; + + ULONG DefaultKeyboardDataQueueSize = 0x64; + PCWSTR DefaultKeyboardDeviceBaseName = L"KeyboardPort"; + ULONG DefaultMouseDataQueueSize = 0x64; + ULONG DefaultMouseResolution = 3; + ULONG DefaultMouseSynchIn100ns = 20000000; + ULONG DefaultNumberOfButtons = 2; + PCWSTR DefaultPointerDeviceBaseName = L"PointerPort"; + ULONG DefaultPollStatusIterations = 1; + ULONG DefaultOverrideKeyboardType = 4; + ULONG DefaultOverrideKeyboardSubtype = 0; + ULONG DefaultPollingIterations = 12000; + ULONG DefaultPollingIterationsMaximum = 12000; + ULONG DefaultResendIterations = 0x3; + ULONG DefaultSampleRate = 60; + ULONG DefaultCrashOnCtrlScroll; + + /* Default value for CrashOnCtrlScroll depends if we're + * running a debug build or a normal build. + */ #if DBG - DefaultCrashOnCtrlScroll = 1; + DefaultCrashOnCtrlScroll = 1; #else - DefaultCrashOnCtrlScroll = 0; + DefaultCrashOnCtrlScroll = 0; #endif - RtlZeroMemory(Parameters, sizeof(Parameters)); - - Parameters[0].Flags = RTL_QUERY_REGISTRY_SUBKEY; - Parameters[0].Name = L"Parameters"; - - Parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[1].Name = L"KeyboardDataQueueSize"; - Parameters[1].EntryContext = &Settings->KeyboardDataQueueSize; - Parameters[1].DefaultType = REG_DWORD; - Parameters[1].DefaultData = &DefaultKeyboardDataQueueSize; - Parameters[1].DefaultLength = sizeof(ULONG); - - Parameters[2].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[2].Name = L"KeyboardDeviceBaseName"; - Parameters[2].EntryContext = &Settings->KeyboardDeviceBaseName; - Parameters[2].DefaultType = REG_SZ; - Parameters[2].DefaultData = (PVOID)DefaultKeyboardDeviceBaseName; - Parameters[2].DefaultLength = 0; - - Parameters[3].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[3].Name = L"MouseDataQueueSize"; - Parameters[3].EntryContext = &Settings->MouseDataQueueSize; - Parameters[3].DefaultType = REG_DWORD; - Parameters[3].DefaultData = &DefaultMouseDataQueueSize; - Parameters[3].DefaultLength = sizeof(ULONG); - - Parameters[4].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[4].Name = L"MouseResolution"; - Parameters[4].EntryContext = &Settings->MouseResolution; - Parameters[4].DefaultType = REG_DWORD; - Parameters[4].DefaultData = &DefaultMouseResolution; - Parameters[4].DefaultLength = sizeof(ULONG); - - Parameters[5].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[5].Name = L"MouseSynchIn100ns"; - Parameters[5].EntryContext = &Settings->MouseSynchIn100ns; - Parameters[5].DefaultType = REG_DWORD; - Parameters[5].DefaultData = &DefaultMouseSynchIn100ns; - Parameters[5].DefaultLength = sizeof(ULONG); - - Parameters[6].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[6].Name = L"NumberOfButtons"; - Parameters[6].EntryContext = &Settings->NumberOfButtons; - Parameters[6].DefaultType = REG_DWORD; - Parameters[6].DefaultData = &DefaultNumberOfButtons; - Parameters[6].DefaultLength = sizeof(ULONG); - - Parameters[7].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[7].Name = L"PointerDeviceBaseName"; - Parameters[7].EntryContext = &Settings->PointerDeviceBaseName; - Parameters[7].DefaultType = REG_SZ; - Parameters[7].DefaultData = (PVOID)DefaultPointerDeviceBaseName; - Parameters[7].DefaultLength = 0; - - Parameters[8].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[8].Name = L"PollStatusIterations"; - Parameters[8].EntryContext = &Settings->PollStatusIterations; - Parameters[8].DefaultType = REG_DWORD; - Parameters[8].DefaultData = &DefaultPollStatusIterations; - Parameters[8].DefaultLength = sizeof(ULONG); - - Parameters[9].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[9].Name = L"OverrideKeyboardType"; - Parameters[9].EntryContext = &Settings->OverrideKeyboardType; - Parameters[9].DefaultType = REG_DWORD; - Parameters[9].DefaultData = &DefaultOverrideKeyboardType; - Parameters[9].DefaultLength = sizeof(ULONG); - - Parameters[10].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[10].Name = L"OverrideKeyboardSubtype"; - Parameters[10].EntryContext = &Settings->OverrideKeyboardSubtype; - Parameters[10].DefaultType = REG_DWORD; - Parameters[10].DefaultData = &DefaultOverrideKeyboardSubtype; - Parameters[10].DefaultLength = sizeof(ULONG); - - Parameters[11].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[11].Name = L"PollingIterations"; - Parameters[11].EntryContext = &Settings->PollingIterations; - Parameters[11].DefaultType = REG_DWORD; - Parameters[11].DefaultData = &DefaultPollingIterations; - Parameters[11].DefaultLength = sizeof(ULONG); - - Parameters[12].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[12].Name = L"PollingIterationsMaximum"; - Parameters[12].EntryContext = &Settings->PollingIterationsMaximum; - Parameters[12].DefaultType = REG_DWORD; - Parameters[12].DefaultData = &DefaultPollingIterationsMaximum; - Parameters[12].DefaultLength = sizeof(ULONG); - - Parameters[13].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[13].Name = L"ResendIterations"; - Parameters[13].EntryContext = &Settings->ResendIterations; - Parameters[13].DefaultType = REG_DWORD; - Parameters[13].DefaultData = &DefaultResendIterations; - Parameters[13].DefaultLength = sizeof(ULONG); - - Parameters[14].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[14].Name = L"SampleRate"; - Parameters[14].EntryContext = &Settings->SampleRate; - Parameters[14].DefaultType = REG_DWORD; - Parameters[14].DefaultData = &DefaultSampleRate; - Parameters[14].DefaultLength = sizeof(ULONG); - - Parameters[15].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[15].Name = L"CrashOnCtrlScroll"; - Parameters[15].EntryContext = &Settings->CrashOnCtrlScroll; - Parameters[15].DefaultType = REG_DWORD; - Parameters[15].DefaultData = &DefaultCrashOnCtrlScroll; - Parameters[15].DefaultLength = sizeof(ULONG); - - Status = RtlQueryRegistryValues( - RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, - RegistryPath->Buffer, - Parameters, - NULL, - NULL); - - if (NT_SUCCESS(Status)) - { - /* Check values */ - if (Settings->KeyboardDataQueueSize < 1) - Settings->KeyboardDataQueueSize = DefaultKeyboardDataQueueSize; - if (Settings->MouseDataQueueSize < 1) - Settings->MouseDataQueueSize = DefaultMouseDataQueueSize; - if (Settings->NumberOfButtons < 1) - Settings->NumberOfButtons = DefaultNumberOfButtons; - if (Settings->PollingIterations < 0x400) - Settings->PollingIterations = DefaultPollingIterations; - if (Settings->PollingIterationsMaximum < 0x400) - Settings->PollingIterationsMaximum = DefaultPollingIterationsMaximum; - if (Settings->ResendIterations < 1) - Settings->ResendIterations = DefaultResendIterations; - } - else if (Status == STATUS_OBJECT_NAME_NOT_FOUND) - { - /* Registry path doesn't exist. Set defaults */ - Settings->KeyboardDataQueueSize = DefaultKeyboardDataQueueSize; - Settings->MouseDataQueueSize = DefaultMouseDataQueueSize; - Settings->MouseResolution = DefaultMouseResolution; - Settings->MouseSynchIn100ns = DefaultMouseSynchIn100ns; - Settings->NumberOfButtons = DefaultNumberOfButtons; - Settings->PollStatusIterations = DefaultPollStatusIterations; - Settings->OverrideKeyboardType = DefaultOverrideKeyboardType; - Settings->OverrideKeyboardSubtype = DefaultOverrideKeyboardSubtype; - Settings->PollingIterations = DefaultPollingIterations; - Settings->PollingIterationsMaximum = DefaultPollingIterationsMaximum; - Settings->ResendIterations = DefaultResendIterations; - Settings->SampleRate = DefaultSampleRate; - Settings->CrashOnCtrlScroll = DefaultCrashOnCtrlScroll; - if (!RtlCreateUnicodeString(&Settings->KeyboardDeviceBaseName, DefaultKeyboardDeviceBaseName) - || !RtlCreateUnicodeString(&Settings->PointerDeviceBaseName, DefaultPointerDeviceBaseName)) - { - WARN_(I8042PRT, "RtlCreateUnicodeString() failed\n"); - Status = STATUS_NO_MEMORY; - } - else - { - Status = STATUS_SUCCESS; - } - } - - if (NT_SUCCESS(Status)) - { - INFO_(I8042PRT, "KeyboardDataQueueSize : 0x%lx\n", Settings->KeyboardDataQueueSize); - INFO_(I8042PRT, "KeyboardDeviceBaseName : %wZ\n", &Settings->KeyboardDeviceBaseName); - INFO_(I8042PRT, "MouseDataQueueSize : 0x%lx\n", Settings->MouseDataQueueSize); - INFO_(I8042PRT, "MouseResolution : 0x%lx\n", Settings->MouseResolution); - INFO_(I8042PRT, "MouseSynchIn100ns : %lu\n", Settings->MouseSynchIn100ns); - INFO_(I8042PRT, "NumberOfButtons : 0x%lx\n", Settings->NumberOfButtons); - INFO_(I8042PRT, "PointerDeviceBaseName : %wZ\n", &Settings->PointerDeviceBaseName); - INFO_(I8042PRT, "PollStatusIterations : 0x%lx\n", Settings->PollStatusIterations); - INFO_(I8042PRT, "OverrideKeyboardType : 0x%lx\n", Settings->OverrideKeyboardType); - INFO_(I8042PRT, "OverrideKeyboardSubtype : 0x%lx\n", Settings->OverrideKeyboardSubtype); - INFO_(I8042PRT, "PollingIterations : 0x%lx\n", Settings->PollingIterations); - INFO_(I8042PRT, "PollingIterationsMaximum : %lu\n", Settings->PollingIterationsMaximum); - INFO_(I8042PRT, "ResendIterations : 0x%lx\n", Settings->ResendIterations); - INFO_(I8042PRT, "SampleRate : %lu\n", Settings->SampleRate); - } - - return Status; + RtlZeroMemory(Parameters, sizeof(Parameters)); + + Parameters[0].Flags = RTL_QUERY_REGISTRY_SUBKEY; + Parameters[0].Name = L"Parameters"; + + Parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT; + Parameters[1].Name = L"KeyboardDataQueueSize"; + Parameters[1].EntryContext = &Settings->KeyboardDataQueueSize; + Parameters[1].DefaultType = REG_DWORD; + Parameters[1].DefaultData = &DefaultKeyboardDataQueueSize; + Parameters[1].DefaultLength = sizeof(ULONG); + + Parameters[2].Flags = RTL_QUERY_REGISTRY_DIRECT; + Parameters[2].Name = L"KeyboardDeviceBaseName"; + Parameters[2].EntryContext = &Settings->KeyboardDeviceBaseName; + Parameters[2].DefaultType = REG_SZ; + Parameters[2].DefaultData = (PVOID)DefaultKeyboardDeviceBaseName; + Parameters[2].DefaultLength = 0; + + Parameters[3].Flags = RTL_QUERY_REGISTRY_DIRECT; + Parameters[3].Name = L"MouseDataQueueSize"; + Parameters[3].EntryContext = &Settings->MouseDataQueueSize; + Parameters[3].DefaultType = REG_DWORD; + Parameters[3].DefaultData = &DefaultMouseDataQueueSize; + Parameters[3].DefaultLength = sizeof(ULONG); + + Parameters[4].Flags = RTL_QUERY_REGISTRY_DIRECT; + Parameters[4].Name = L"MouseResolution"; + Parameters[4].EntryContext = &Settings->MouseResolution; + Parameters[4].DefaultType = REG_DWORD; + Parameters[4].DefaultData = &DefaultMouseResolution; + Parameters[4].DefaultLength = sizeof(ULONG); + + Parameters[5].Flags = RTL_QUERY_REGISTRY_DIRECT; + Parameters[5].Name = L"MouseSynchIn100ns"; + Parameters[5].EntryContext = &Settings->MouseSynchIn100ns; + Parameters[5].DefaultType = REG_DWORD; + Parameters[5].DefaultData = &DefaultMouseSynchIn100ns; + Parameters[5].DefaultLength = sizeof(ULONG); + + Parameters[6].Flags = RTL_QUERY_REGISTRY_DIRECT; + Parameters[6].Name = L"NumberOfButtons"; + Parameters[6].EntryContext = &Settings->NumberOfButtons; + Parameters[6].DefaultType = REG_DWORD; + Parameters[6].DefaultData = &DefaultNumberOfButtons; + Parameters[6].DefaultLength = sizeof(ULONG); + + Parameters[7].Flags = RTL_QUERY_REGISTRY_DIRECT; + Parameters[7].Name = L"PointerDeviceBaseName"; + Parameters[7].EntryContext = &Settings->PointerDeviceBaseName; + Parameters[7].DefaultType = REG_SZ; + Parameters[7].DefaultData = (PVOID)DefaultPointerDeviceBaseName; + Parameters[7].DefaultLength = 0; + + Parameters[8].Flags = RTL_QUERY_REGISTRY_DIRECT; + Parameters[8].Name = L"PollStatusIterations"; + Parameters[8].EntryContext = &Settings->PollStatusIterations; + Parameters[8].DefaultType = REG_DWORD; + Parameters[8].DefaultData = &DefaultPollStatusIterations; + Parameters[8].DefaultLength = sizeof(ULONG); + + Parameters[9].Flags = RTL_QUERY_REGISTRY_DIRECT; + Parameters[9].Name = L"OverrideKeyboardType"; + Parameters[9].EntryContext = &Settings->OverrideKeyboardType; + Parameters[9].DefaultType = REG_DWORD; + Parameters[9].DefaultData = &DefaultOverrideKeyboardType; + Parameters[9].DefaultLength = sizeof(ULONG); + + Parameters[10].Flags = RTL_QUERY_REGISTRY_DIRECT; + Parameters[10].Name = L"OverrideKeyboardSubtype"; + Parameters[10].EntryContext = &Settings->OverrideKeyboardSubtype; + Parameters[10].DefaultType = REG_DWORD; + Parameters[10].DefaultData = &DefaultOverrideKeyboardSubtype; + Parameters[10].DefaultLength = sizeof(ULONG); + + Parameters[11].Flags = RTL_QUERY_REGISTRY_DIRECT; + Parameters[11].Name = L"PollingIterations"; + Parameters[11].EntryContext = &Settings->PollingIterations; + Parameters[11].DefaultType = REG_DWORD; + Parameters[11].DefaultData = &DefaultPollingIterations; + Parameters[11].DefaultLength = sizeof(ULONG); + + Parameters[12].Flags = RTL_QUERY_REGISTRY_DIRECT; + Parameters[12].Name = L"PollingIterationsMaximum"; + Parameters[12].EntryContext = &Settings->PollingIterationsMaximum; + Parameters[12].DefaultType = REG_DWORD; + Parameters[12].DefaultData = &DefaultPollingIterationsMaximum; + Parameters[12].DefaultLength = sizeof(ULONG); + + Parameters[13].Flags = RTL_QUERY_REGISTRY_DIRECT; + Parameters[13].Name = L"ResendIterations"; + Parameters[13].EntryContext = &Settings->ResendIterations; + Parameters[13].DefaultType = REG_DWORD; + Parameters[13].DefaultData = &DefaultResendIterations; + Parameters[13].DefaultLength = sizeof(ULONG); + + Parameters[14].Flags = RTL_QUERY_REGISTRY_DIRECT; + Parameters[14].Name = L"SampleRate"; + Parameters[14].EntryContext = &Settings->SampleRate; + Parameters[14].DefaultType = REG_DWORD; + Parameters[14].DefaultData = &DefaultSampleRate; + Parameters[14].DefaultLength = sizeof(ULONG); + + Parameters[15].Flags = RTL_QUERY_REGISTRY_DIRECT; + Parameters[15].Name = L"CrashOnCtrlScroll"; + Parameters[15].EntryContext = &Settings->CrashOnCtrlScroll; + Parameters[15].DefaultType = REG_DWORD; + Parameters[15].DefaultData = &DefaultCrashOnCtrlScroll; + Parameters[15].DefaultLength = sizeof(ULONG); + + Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, + RegistryPath->Buffer, + Parameters, + NULL, + NULL); + if (NT_SUCCESS(Status)) + { + /* Check values */ + if (Settings->KeyboardDataQueueSize < 1) + Settings->KeyboardDataQueueSize = DefaultKeyboardDataQueueSize; + if (Settings->MouseDataQueueSize < 1) + Settings->MouseDataQueueSize = DefaultMouseDataQueueSize; + if (Settings->NumberOfButtons < 1) + Settings->NumberOfButtons = DefaultNumberOfButtons; + if (Settings->PollingIterations < 0x400) + Settings->PollingIterations = DefaultPollingIterations; + if (Settings->PollingIterationsMaximum < 0x400) + Settings->PollingIterationsMaximum = DefaultPollingIterationsMaximum; + if (Settings->ResendIterations < 1) + Settings->ResendIterations = DefaultResendIterations; + } + else if (Status == STATUS_OBJECT_NAME_NOT_FOUND) + { + /* Registry path doesn't exist. Set defaults */ + Settings->KeyboardDataQueueSize = DefaultKeyboardDataQueueSize; + Settings->MouseDataQueueSize = DefaultMouseDataQueueSize; + Settings->MouseResolution = DefaultMouseResolution; + Settings->MouseSynchIn100ns = DefaultMouseSynchIn100ns; + Settings->NumberOfButtons = DefaultNumberOfButtons; + Settings->PollStatusIterations = DefaultPollStatusIterations; + Settings->OverrideKeyboardType = DefaultOverrideKeyboardType; + Settings->OverrideKeyboardSubtype = DefaultOverrideKeyboardSubtype; + Settings->PollingIterations = DefaultPollingIterations; + Settings->PollingIterationsMaximum = DefaultPollingIterationsMaximum; + Settings->ResendIterations = DefaultResendIterations; + Settings->SampleRate = DefaultSampleRate; + Settings->CrashOnCtrlScroll = DefaultCrashOnCtrlScroll; + if (!RtlCreateUnicodeString(&Settings->KeyboardDeviceBaseName, DefaultKeyboardDeviceBaseName) + || !RtlCreateUnicodeString(&Settings->PointerDeviceBaseName, DefaultPointerDeviceBaseName)) + { + WARN_(I8042PRT, "RtlCreateUnicodeString() failed\n"); + Status = STATUS_NO_MEMORY; + } + else + { + Status = STATUS_SUCCESS; + } + } + + if (NT_SUCCESS(Status)) + { + INFO_(I8042PRT, "KeyboardDataQueueSize : 0x%lx\n", Settings->KeyboardDataQueueSize); + INFO_(I8042PRT, "KeyboardDeviceBaseName : %wZ\n", &Settings->KeyboardDeviceBaseName); + INFO_(I8042PRT, "MouseDataQueueSize : 0x%lx\n", Settings->MouseDataQueueSize); + INFO_(I8042PRT, "MouseResolution : 0x%lx\n", Settings->MouseResolution); + INFO_(I8042PRT, "MouseSynchIn100ns : %lu\n", Settings->MouseSynchIn100ns); + INFO_(I8042PRT, "NumberOfButtons : 0x%lx\n", Settings->NumberOfButtons); + INFO_(I8042PRT, "PointerDeviceBaseName : %wZ\n", &Settings->PointerDeviceBaseName); + INFO_(I8042PRT, "PollStatusIterations : 0x%lx\n", Settings->PollStatusIterations); + INFO_(I8042PRT, "OverrideKeyboardType : 0x%lx\n", Settings->OverrideKeyboardType); + INFO_(I8042PRT, "OverrideKeyboardSubtype : 0x%lx\n", Settings->OverrideKeyboardSubtype); + INFO_(I8042PRT, "PollingIterations : 0x%lx\n", Settings->PollingIterations); + INFO_(I8042PRT, "PollingIterationsMaximum : %lu\n", Settings->PollingIterationsMaximum); + INFO_(I8042PRT, "ResendIterations : 0x%lx\n", Settings->ResendIterations); + INFO_(I8042PRT, "SampleRate : %lu\n", Settings->SampleRate); + } + + return Status; }