close
Skip to content
This repository was archived by the owner on May 29, 2025. It is now read-only.

Commit fd4d0f3

Browse files
committed
Clean up input hook code
This cleans up the input hooking code with better comments, use of nullptr instead of 0, and more accurate error handling. The "more accurate error handling" is that previously if one hook was registered and the other one was not then the message pump would not be run, which could cause issues.
1 parent 88afed6 commit fd4d0f3

1 file changed

Lines changed: 38 additions & 25 deletions

File tree

‎UIforETW/KeyLoggerThread.cpp‎

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ LRESULT CALLBACK LowLevelKeyboardHook(int nCode, WPARAM wParam, LPARAM lParam)
165165
ETWKeyDown(code, keyDownDetails.c_str(), 0, 0);
166166
}
167167

168-
return CallNextHookEx(0, nCode, wParam, lParam);
168+
return CallNextHookEx(nullptr, nCode, wParam, lParam);
169169
}
170170

171171
_Pre_satisfies_(nCode == HC_ACTION)
@@ -228,7 +228,7 @@ LRESULT CALLBACK LowLevelMouseHook(int nCode, WPARAM wParam, LPARAM lParam) noex
228228
}
229229
}
230230

231-
return CallNextHookEx(0, nCode, wParam, lParam);
231+
return CallNextHookEx(nullptr, nCode, wParam, lParam);
232232
}
233233

234234

@@ -252,30 +252,43 @@ DWORD __stdcall InputThread(LPVOID) noexcept
252252
// processed in a timely manner or else bad things will happen. Doing this on a
253253
// separate thread is a good idea, but even then bad things will happen to your system
254254
// if you halt in a debugger. Even simple things like calling printf() from the hook
255-
// can easily cause system deadlocks which render the mouse unable to move!
256-
HHOOK keyHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardHook, NULL, 0);
257-
HHOOK mouseHook = SetWindowsHookEx(WH_MOUSE_LL, LowLevelMouseHook, NULL, 0);
258-
259-
if (!keyHook && !mouseHook)
260-
return 0;
261-
262-
// Run a message pump -- necessary so that the hooks will be processed
263-
BOOL bRet;
264-
MSG msg;
265-
// Keeping pumping messages until WM_QUIT is received. If this is opened
266-
// in a child thread then you can terminate it by using PostThreadMessage
267-
// to send WM_QUIT.
268-
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
255+
// can easily cause system deadlocks which cause all input to be processed
256+
// very slowly.
257+
// The default OS hook timeout seems to be 300 ms, which is long enough to
258+
// make input delays noticeable, but short enough to make the system sort of
259+
// usable. You can set a shorter timeout (10 ms in this case) with this
260+
// command:
261+
// reg add "HKCU\Control Panel\Desktop" /v LowLevelHooksTimeout /t REG_DWORD /f /d 10
262+
// Occasional input delays were, in one case, tracked down to an input hook
263+
// (unknown owner) that was briefly timing out. Twitter discussion is here:
264+
// https://twitter.com/BruceDawson0xB/status/1673375468127670273
265+
HHOOK keyHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardHook, nullptr, 0);
266+
HHOOK mouseHook = SetWindowsHookEx(WH_MOUSE_LL, LowLevelMouseHook, nullptr, 0);
267+
268+
// Run the message pump if either hook is successfully registered (they should
269+
// always both be registered).
270+
if (keyHook || mouseHook)
269271
{
270-
if (bRet == -1)
271-
{
272-
// handle the error and possibly exit
273-
break;
274-
}
275-
else
272+
// Run a message pump -- necessary so that the hooks will be processed
273+
BOOL bRet;
274+
MSG msg;
275+
// Keeping pumping messages until WM_QUIT is received. If this is running
276+
// in a child thread then you can terminate it by using PostThreadMessage
277+
// to send WM_QUIT.
278+
while ((bRet = GetMessageW(&msg, nullptr, 0, 0)) != 0)
276279
{
277-
TranslateMessage(&msg);
278-
DispatchMessage(&msg);
280+
// GetMessageW will normally only return when WM_QUIT is received, so this
281+
// loop normally doesn't ever run.
282+
if (bRet == -1)
283+
{
284+
// Unexpected error. Quit.
285+
break;
286+
}
287+
else
288+
{
289+
TranslateMessage(&msg);
290+
DispatchMessage(&msg);
291+
}
279292
}
280293
}
281294

@@ -312,7 +325,7 @@ void SetKeyloggingState(enum KeyLoggerState state) noexcept
312325
// it isn't running.
313326
if (!s_hThread)
314327
{
315-
s_hThread = CreateThread(NULL, 0, InputThread, NULL, 0, &s_threadID);
328+
s_hThread = CreateThread(nullptr, 0, InputThread, nullptr, 0, &s_threadID);
316329
}
317330

318331
switch (state)

0 commit comments

Comments
 (0)