WH_KEYBOARD_LL hook not called in UMDF driver, but works in example console app

195 views Asked by At

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

0

There are 0 answers