#define _WIN32_WINNT 0x0400 #include <windows.h> HMODULE hookInstance = NULL; HHOOK mouseHook = NULL; HHOOK keyboardHook = NULL; HANDLE mouseHookThread = NULL; HANDLE keyboardHookThread = NULL; /* * DLL entry point for persisting the module handle */ BOOL WINAPI DllMain(HINSTANCE module, DWORD reason, LPVOID reserved) { if (reason == DLL_PROCESS_ATTACH) hookInstance = module; else if (reason == DLL_PROCESS_DETACH) { TerminateThread(mouseHookThread, 0); TerminateThread(keyboardHookThread, 0); mouseHookThread = NULL; keyboardHookThread = NULL; } return TRUE; } /* * Hook handler to mouse movements that will drop all locally generated * mouse movements */ LRESULT CALLBACK mouse_hook_handler(int code, WPARAM w, LPARAM l) { if (code == HC_ACTION) { MSLLHOOKSTRUCT *hook = (MSLLHOOKSTRUCT *)l; // Return the as if the mouse event had been passed if it's // generated by the mouse if (!(hook->flags & LLMHF_INJECTED)) return TRUE; } return CallNextHookEx(mouseHook, code, w, l); } /* * Handles mouse hook notifications */ DWORD mouse_hook_msg_thread(LPVOID na) { DWORD result = ERROR_SUCCESS; MSG msg; if (!(mouseHook = SetWindowsHookEx(WH_MOUSE_LL, mouse_hook_handler, hookInstance, 0))) result = GetLastError(); while (GetMessage(&msg, 0, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return result; } /* * Hook handler to keyboard events that will drop all locally generated * keyboard events */ LRESULT CALLBACK keyboard_hook_handler(int code, WPARAM w, LPARAM l) { if (code == HC_ACTION) { KBDLLHOOKSTRUCT *hook = (KBDLLHOOKSTRUCT *)l; // Return the as if the keyboard event had been passed if it's // generated by the keyboard if (!(hook->flags & LLMHF_INJECTED)) return TRUE; } return CallNextHookEx(keyboardHook, code, w, l); } /* * Handles keyboard hook notifications */ DWORD keyboard_hook_msg_thread(LPVOID na) { DWORD result = ERROR_SUCCESS; MSG msg; if (!(keyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, keyboard_hook_handler, hookInstance, 0))) result = GetLastError(); while (GetMessage(&msg, 0, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return result; } /* * Enable/disable mouse movement */ DWORD __declspec(dllexport) enable_mouse_input(BOOL enable) { DWORD result = ERROR_SUCCESS; // If the requestor would like to enable a mouse input and it's currently // disabled, enable it. if ((enable) && (mouseHook)) { if (!UnhookWindowsHookEx(mouseHook)) result = GetLastError(); TerminateThread(mouseHookThread, 0); mouseHookThread = NULL; } // Otherwise, if they would like to disable it but it's currently enabled, // disable it. else if ((!enable) && (!mouseHook)) { DWORD threadId; mouseHookThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)mouse_hook_msg_thread, NULL, 0, &threadId); } return result; } /* * Enable/disable keyboard movement */ DWORD __declspec(dllexport) enable_keyboard_input(BOOL enable) { DWORD result = ERROR_SUCCESS; // If the requestor would like to enable a keyboard input and it's currently // disabled, enable it. if ((enable) && (keyboardHook)) { if (!UnhookWindowsHookEx(keyboardHook)) result = GetLastError(); TerminateThread(keyboardHookThread, 0); keyboardHookThread = NULL; } // Otherwise, if they would like to disable it but it's currently enabled, // disable it. else if ((!enable) && (!keyboardHook)) { DWORD threadId; keyboardHookThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)keyboard_hook_msg_thread, NULL, 0, &threadId); } return result; }