I'm trying to detect all key presses and mouse events by registering WH_KEYBOARD_LL and WH_MOUSE_LL hooks. Apparently these low-level hooks don't require the hook procedure to reside in a separate DLL.
I have this working in the following example app (a console application).
#include <iostream>
#include <Windows.h>
#include <Winuser.h>
#include <thread>
#include <chrono>
#include <sstream>
#include <atomic>
#include <cassert>
LRESULT CALLBACK wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
std::cout << std::endl << "EVENT: " << hWnd << ", " << message << ", " << wParam << ", " << lParam << std::endl;
return 0;
}
LRESULT CALLBACK keyboardHook(
_In_ int nCode,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
std::cout << "Keyboard: " << nCode << ", " << wParam << ", " << lParam << std::endl;
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
LRESULT CALLBACK mouseHook(
_In_ int nCode,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
std::cout << "Mouse: " << nCode << ", " << wParam << ", " << lParam << std::endl;
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
int main()
{
const wchar_t pszClassName[] = L"MyMessageWindow";
auto hInstance = GetModuleHandle(NULL);
WNDCLASSEXW wcl;
ZeroMemory(&wcl, sizeof(WNDCLASSEXW));
wcl.cbSize = sizeof(WNDCLASSEXW);
wcl.hInstance = hInstance;
wcl.lpszClassName = pszClassName;
wcl.lpfnWndProc = wndProc;
assert(RegisterClassExW(&wcl) != 0);
auto hwnd = CreateWindowW(
pszClassName,
pszClassName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
HWND_MESSAGE,
NULL,
NULL,
NULL
);
auto threadId = 0;
std::thread t([hwnd, threadId]() {
auto keyboardHookHandle = SetWindowsHookEx(WH_KEYBOARD_LL, keyboardHook, NULL, threadId);
auto mouseHookHandle = SetWindowsHookEx(WH_MOUSE_LL, mouseHook, NULL, threadId);
while (true) {
MSG msg;
GetMessage(&msg, hwnd, 0, 0);
}
});
t.join();
return 0;
}
So this works, and I can see the keyboard and mouse events printed to the console regardless of what apps are in focus (if any), which is great.
However, when I do this inside a UMDF driver, the messages don't come through. The calls to SetWindowsHookEx appear to succeed without error.
I'm thinking of creating a minimal UMDF driver to test if it's possible, but thought I'd first ask here in case someone can tell me whether it's possible. If not, I have a few other approaches in mind.
Thanks