2
votes

I have code that has been working without any reported issues for a few years. It sets up a low level keyboard hook that the user uses to activate the application.

m_hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeybHookFn, GetModuleHandle(NULL), 0);

For one user all of a sudden (it worked for him before for years as well), the keyboard hook isn't working. Upon investigation, I can see that SetWindowsHookEx() is returning NULL and GetLastError() is returning 0x00000597, which is ERROR_HOOK_NOT_INSTALLED.

I can't find any documentation on what this means.

What are possibilities for why this might happen? System security settings? User account privileges? The user is using Windows 7.

I need a specific answer to how to make this error occur so that I can solve the user's problem

1
Proper error checking is never tested. My crystal ball says that you call UnhookWindowHookEx() when this code fails. - Hans Passant
Once you move that line of code into a DLL, GetModuleHandle(NULL) no longer returns the module handle to the module that contains the hook procedure. Using the __ImageBase pseudo linker variable will fix this issue. - IInspectable
@HansPassant I'm not sure what you're suggesting. Call UnhookWindowHookEx() on which handle? SetWindowsHookEx() is returning NULL - Nicholas
@IInspectable the code is not in a DLL. WH_KEYBOARD_LL does not have to be used from a DLL. Again, this has all been working on thousands of computers for years. - Nicholas
You should still use __ImageBase because that's the right thing to do. - David Heffernan

1 Answers

1
votes

Looking at http://blogs.msdn.com/b/alejacma/archive/2010/10/14/global-hooks-getting-lost-on-windows-7.aspx, it seems that it might occur if the CPU load is high.

Another thought: did this break when upgrading to 64-bit windows? I don't know if applies to LL hooks, but you cannot inject a 32-bit DLL in a 64-bit process.

Finally: LL hooks won't capture input in a UAC-elevated process if the hook was not installed from a UAC-elevated process (a lower privilege level process cannot capture input of a higher privilege level one)