Skip to content

Commit

Permalink
** WIP ** [I8042PRT] Add support for SysRq debugging key
Browse files Browse the repository at this point in the history
  • Loading branch information
HBelusca committed Dec 19, 2024
1 parent 9a10756 commit 1cd8811
Show file tree
Hide file tree
Showing 3 changed files with 184 additions and 118 deletions.
6 changes: 6 additions & 0 deletions drivers/input/i8042prt/i8042prt.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ typedef struct _I8042_SETTINGS
ULONG PollingIterationsMaximum;
ULONG ResendIterations; /* done */
ULONG SampleRate;
ULONG BreakOnSysRq; /* done */
ULONG KdEnableOnCtrlSysRq; /* done */
ULONG CrashOnCtrlScroll; /* done */
} I8042_SETTINGS, *PI8042_SETTINGS;

Expand Down Expand Up @@ -210,6 +212,10 @@ typedef struct _I8042_HOOK_WORKITEM

#define MAX(a, b) ((a) >= (b) ? (a) : (b))

// #define KEYBOARD_BREAK_CODE 0xF0
#define KEYBOARD_DEBUG_HOTKEY_ENH 0x37 // SysReq (Alt+PrtSc) scan code for Enhanced Keyboard
#define KEYBOARD_DEBUG_HOTKEY_AT 0x54 // SysReq scan code for 84-key Keyboard

#define KEYBOARD_POWER_CODE 0x5E
#define KEYBOARD_SLEEP_CODE 0x5F
#define KEYBOARD_WAKE_CODE 0x63
Expand Down
46 changes: 43 additions & 3 deletions drivers/input/i8042prt/keyboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -836,10 +836,38 @@ i8042KbdInterruptService(

INFO_(I8042PRT, "Got: 0x%02x\n", Output);


/* Check for SysRq debugging support */
if (!(InputData->Flags & KEY_BREAK) &&
PortDeviceExtension->Settings.BreakOnSysRq &&
!KD_DEBUGGER_NOT_PRESENT && KD_DEBUGGER_ENABLED)
{
BOOLEAN isEnh = ENHANCED_KEYBOARD(DeviceExtension->KeyboardAttributes.KeyboardIdentifier);

/* On Enhanced 101 keyboard, SysReq key is 0xE0 0x37
* On 84-key AT keyboard, SysReq key is 0xE0 0x54. */
if ((InputData->Flags & KEY_E0) &&
(InputData->MakeCode == isEnh ? KEYBOARD_DEBUG_HOTKEY_ENH : KEYBOARD_DEBUG_HOTKEY_AT))
{
/* Wrap in SEH so we don't crash if there is
* no debugger or it gets disconnected. */
_SEH2_TRY
{
DbgBreakPointWithStatus(DBG_STATUS_SYSRQ);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
_SEH2_END;
}
}


// See commit cba6f25d3 (r44743)
if (PortDeviceExtension->Settings.CrashOnCtrlScroll)
{
/* Test for CTRL + SCROLL LOCK twice */
static const UCHAR ScanCodes[] = { 0x1d, 0x46, 0xc6, 0x46, 0 };
static const UCHAR ScanCodes[] = { /*0xe0,*/ 0x1d, 0x46, 0xc6, 0x46, 0 };

if (Output == ScanCodes[DeviceExtension->ComboPosition])
{
Expand All @@ -861,6 +889,8 @@ i8042KbdInterruptService(
}

/* Test for TAB + key combination */
// HISTORICAL NOTE: TAB + key was introduced in commit
// 3273c9317 (r2469) in replacement of SysRq + key.
if (InputData->MakeCode == 0x0F)
{
DeviceExtension->TabPressed = !(InputData->Flags & KEY_BREAK);
Expand All @@ -870,10 +900,20 @@ i8042KbdInterruptService(
DeviceExtension->TabPressed = FALSE;

/* Check which action to do */
if (InputData->MakeCode == 0x25)
if (!KD_DEBUGGER_NOT_PRESENT && (InputData->MakeCode == 0x25))
{
/* k - Breakpoint */
DbgBreakPointWithStatus(DBG_STATUS_SYSRQ);

/* Wrap in SEH so we don't crash if there is
* no debugger or it gets disconnected. */
_SEH2_TRY
{
DbgBreakPointWithStatus(DBG_STATUS_SYSRQ);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
_SEH2_END;
}
else if (InputData->MakeCode == 0x30)
{
Expand Down
250 changes: 135 additions & 115 deletions drivers/input/i8042prt/registry.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ ReadRegistryEntries(
IN PUNICODE_STRING RegistryPath,
OUT PI8042_SETTINGS Settings)
{
RTL_QUERY_REGISTRY_TABLE Parameters[17];
NTSTATUS Status;
ULONG i;
RTL_QUERY_REGISTRY_TABLE Parameters[19];

ULONG DefaultKeyboardDataQueueSize = 0x64;
PCWSTR DefaultKeyboardDeviceBaseName = L"KeyboardPort";
Expand All @@ -39,126 +40,143 @@ ReadRegistryEntries(
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.
*/
ULONG DefaultBreakOnSysRq = 1;

/* Default values depending on whether we are
* running a debug build or a normal build. */
#if DBG
DefaultCrashOnCtrlScroll = 1;
ULONG DefaultKdEnableOnCtrlSysRq = 1;
ULONG DefaultCrashOnCtrlScroll = 1;
#else
DefaultCrashOnCtrlScroll = 0;
ULONG DefaultKdEnableOnCtrlSysRq = 0;
ULONG 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);
i = 0;

Parameters[i].Flags = RTL_QUERY_REGISTRY_SUBKEY;
Parameters[i].Name = L"Parameters";

Parameters[++i].Flags = RTL_QUERY_REGISTRY_DIRECT;
Parameters[i].Name = L"KeyboardDataQueueSize";
Parameters[i].EntryContext = &Settings->KeyboardDataQueueSize;
Parameters[i].DefaultType = REG_DWORD;
Parameters[i].DefaultData = &DefaultKeyboardDataQueueSize;
Parameters[i].DefaultLength = sizeof(ULONG);

Parameters[++i].Flags = RTL_QUERY_REGISTRY_DIRECT;
Parameters[i].Name = L"KeyboardDeviceBaseName";
Parameters[i].EntryContext = &Settings->KeyboardDeviceBaseName;
Parameters[i].DefaultType = REG_SZ;
Parameters[i].DefaultData = (PVOID)DefaultKeyboardDeviceBaseName;
Parameters[i].DefaultLength = 0;

Parameters[++i].Flags = RTL_QUERY_REGISTRY_DIRECT;
Parameters[i].Name = L"MouseDataQueueSize";
Parameters[i].EntryContext = &Settings->MouseDataQueueSize;
Parameters[i].DefaultType = REG_DWORD;
Parameters[i].DefaultData = &DefaultMouseDataQueueSize;
Parameters[i].DefaultLength = sizeof(ULONG);

Parameters[++i].Flags = RTL_QUERY_REGISTRY_DIRECT;
Parameters[i].Name = L"MouseResolution";
Parameters[i].EntryContext = &Settings->MouseResolution;
Parameters[i].DefaultType = REG_DWORD;
Parameters[i].DefaultData = &DefaultMouseResolution;
Parameters[i].DefaultLength = sizeof(ULONG);

Parameters[++i].Flags = RTL_QUERY_REGISTRY_DIRECT;
Parameters[i].Name = L"MouseSynchIn100ns";
Parameters[i].EntryContext = &Settings->MouseSynchIn100ns;
Parameters[i].DefaultType = REG_DWORD;
Parameters[i].DefaultData = &DefaultMouseSynchIn100ns;
Parameters[i].DefaultLength = sizeof(ULONG);

Parameters[++i].Flags = RTL_QUERY_REGISTRY_DIRECT;
Parameters[i].Name = L"NumberOfButtons";
Parameters[i].EntryContext = &Settings->NumberOfButtons;
Parameters[i].DefaultType = REG_DWORD;
Parameters[i].DefaultData = &DefaultNumberOfButtons;
Parameters[i].DefaultLength = sizeof(ULONG);

Parameters[++i].Flags = RTL_QUERY_REGISTRY_DIRECT;
Parameters[i].Name = L"PointerDeviceBaseName";
Parameters[i].EntryContext = &Settings->PointerDeviceBaseName;
Parameters[i].DefaultType = REG_SZ;
Parameters[i].DefaultData = (PVOID)DefaultPointerDeviceBaseName;
Parameters[i].DefaultLength = 0;

Parameters[++i].Flags = RTL_QUERY_REGISTRY_DIRECT;
Parameters[i].Name = L"PollStatusIterations";
Parameters[i].EntryContext = &Settings->PollStatusIterations;
Parameters[i].DefaultType = REG_DWORD;
Parameters[i].DefaultData = &DefaultPollStatusIterations;
Parameters[i].DefaultLength = sizeof(ULONG);

Parameters[++i].Flags = RTL_QUERY_REGISTRY_DIRECT;
Parameters[i].Name = L"OverrideKeyboardType";
Parameters[i].EntryContext = &Settings->OverrideKeyboardType;
Parameters[i].DefaultType = REG_DWORD;
Parameters[i].DefaultData = &DefaultOverrideKeyboardType;
Parameters[i].DefaultLength = sizeof(ULONG);

Parameters[++i].Flags = RTL_QUERY_REGISTRY_DIRECT;
Parameters[i].Name = L"OverrideKeyboardSubtype";
Parameters[i].EntryContext = &Settings->OverrideKeyboardSubtype;
Parameters[i].DefaultType = REG_DWORD;
Parameters[i].DefaultData = &DefaultOverrideKeyboardSubtype;
Parameters[i].DefaultLength = sizeof(ULONG);

Parameters[++i].Flags = RTL_QUERY_REGISTRY_DIRECT;
Parameters[i].Name = L"PollingIterations";
Parameters[i].EntryContext = &Settings->PollingIterations;
Parameters[i].DefaultType = REG_DWORD;
Parameters[i].DefaultData = &DefaultPollingIterations;
Parameters[i].DefaultLength = sizeof(ULONG);

Parameters[++i].Flags = RTL_QUERY_REGISTRY_DIRECT;
Parameters[i].Name = L"PollingIterationsMaximum";
Parameters[i].EntryContext = &Settings->PollingIterationsMaximum;
Parameters[i].DefaultType = REG_DWORD;
Parameters[i].DefaultData = &DefaultPollingIterationsMaximum;
Parameters[i].DefaultLength = sizeof(ULONG);

Parameters[++i].Flags = RTL_QUERY_REGISTRY_DIRECT;
Parameters[i].Name = L"ResendIterations";
Parameters[i].EntryContext = &Settings->ResendIterations;
Parameters[i].DefaultType = REG_DWORD;
Parameters[i].DefaultData = &DefaultResendIterations;
Parameters[i].DefaultLength = sizeof(ULONG);

Parameters[++i].Flags = RTL_QUERY_REGISTRY_DIRECT;
Parameters[i].Name = L"SampleRate";
Parameters[i].EntryContext = &Settings->SampleRate;
Parameters[i].DefaultType = REG_DWORD;
Parameters[i].DefaultData = &DefaultSampleRate;
Parameters[i].DefaultLength = sizeof(ULONG);

Parameters[++i].Flags = RTL_QUERY_REGISTRY_DIRECT;
Parameters[i].Name = L"BreakOnSysRq";
Parameters[i].EntryContext = &Settings->BreakOnSysRq;
Parameters[i].DefaultType = REG_DWORD;
Parameters[i].DefaultData = &DefaultBreakOnSysRq;
Parameters[i].DefaultLength = sizeof(ULONG);

Parameters[++i].Flags = RTL_QUERY_REGISTRY_DIRECT;
Parameters[i].Name = L"KdEnableOnCtrlSysRq";
Parameters[i].EntryContext = &Settings->KdEnableOnCtrlSysRq;
Parameters[i].DefaultType = REG_DWORD;
Parameters[i].DefaultData = &DefaultKdEnableOnCtrlSysRq;
Parameters[i].DefaultLength = sizeof(ULONG);

Parameters[++i].Flags = RTL_QUERY_REGISTRY_DIRECT;
Parameters[i].Name = L"CrashOnCtrlScroll";
Parameters[i].EntryContext = &Settings->CrashOnCtrlScroll;
Parameters[i].DefaultType = REG_DWORD;
Parameters[i].DefaultData = &DefaultCrashOnCtrlScroll;
Parameters[i].DefaultLength = sizeof(ULONG);

Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
RegistryPath->Buffer,
Expand Down Expand Up @@ -196,6 +214,8 @@ ReadRegistryEntries(
Settings->PollingIterationsMaximum = DefaultPollingIterationsMaximum;
Settings->ResendIterations = DefaultResendIterations;
Settings->SampleRate = DefaultSampleRate;
Settings->BreakOnSysRq = DefaultBreakOnSysRq;
Settings->KdEnableOnCtrlSysRq = DefaultKdEnableOnCtrlSysRq;
Settings->CrashOnCtrlScroll = DefaultCrashOnCtrlScroll;
if (!RtlCreateUnicodeString(&Settings->KeyboardDeviceBaseName, DefaultKeyboardDeviceBaseName)
|| !RtlCreateUnicodeString(&Settings->PointerDeviceBaseName, DefaultPointerDeviceBaseName))
Expand Down

0 comments on commit 1cd8811

Please sign in to comment.