Global KeyboardHook Problem

Started by
8 comments, last by b1gjo3 14 years, 10 months ago
Hi all, i have a global keyboardhook library being opened by my main program through my dll file. im using it so that whenever a user would hit a key combination they specify in the app, it would take a certain action that they specify. it works perfect except that whenever the user tries to hit any key, or deletes a file, or does anything related to windows explorer, explorer freezes. the only way i can unfreeze it is by terminating the program through task manager anyone have any ideas why this is, i would much appreciate some insight on this
Advertisement
Are you sure a global keyboard hook is what you need? It sounds like you want to catch key combos in your app, not in every user mode process. Perhaps your hook is failing to pass key hits along to explorer.
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
sure because what if the user set key "Ctrl+F12" to be the key to automatically save a screenshot of a game they were playing to a directory of their choosing, wouldnt i have to have a global hook for that?

and i do CallNextHookEx() on every condition in the keyboardproc, so thats why im confused
Post your complete code; otherwise the best we can do is randomly speculate [wink]

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

all my main program does is SetKeyboardHook, then goes into an infinite looping checking for GetHookState(), and loops out when GetHookState() == -1, then UnsetsKeyboardHook, terminates program

#include <windows.h>#pragma data_seg("SharedBlock")	HINSTANCE	hInst = NULL;	HHOOK		keyHook = NULL;	int		hookState = -1;	char		sequence[256];#pragma data_seg()#pragma comment(linker, "/section:SharedBlock,RWS")extern "C" __declspec (dllexport) int _stdcall GetHookState(){	return hookState;}extern "C" __declspec (dllexport) char* _stdcall GetKeySequence(){	return sequence;}extern "C" __declspec (dllexport) LRESULT CALLBACK __stdcall KeyboardProc(int code, WPARAM wParam, LPARAM lParam){	// dont do anything with these yet	if ( (code < 0) || (wParam >= VK_F1 && wParam <= VK_F10))	{		hookState = 1;		return CallNextHookEx(keyHook, code, wParam, lParam);	}	// i temporarily have ctrl+f11 to set hookstate = -1 so that        // i have a way of exiting infinite loop	if ( (GetKeyState(VK_CONTROL) & 0x8000) && (GetKeyState(VK_F11) & 0x8000) )	{		hookState = -1;		return CallNextHookEx(keyHook, code, wParam, lParam);	}	// this is the button sequence to set hookstate to 0 (Ctrl + F12)	// main program waits for hookstate to be 0 to determine action	if ( (GetKeyState(VK_CONTROL) & 0x8000) && (GetKeyState(VK_F12) & 0x8000) )	{		hookState = 0;		//to let main program know user has entered ctrl+f12 key sequence		sequence = "Ctrl+F12";		return CallNextHookEx(keyHook, code, wParam, lParam);	}	return  CallNextHookEx(keyHook, code, wParam, lParam);}extern "C" int __declspec (dllexport) __stdcall SetKeyboardHook(){	keyHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, hInst, 0); 	if (keyHook == NULL)	{		hookState = -1;		return -1;	}	else	{		hookState = 1;		return 0;	}}extern "C" int __declspec (dllexport) __stdcall UnsetKeyboardHook(){	//unhook	UnhookWindowsHookEx(keyHook);	hookState = -1;	return 0;}extern "C" BOOL __declspec (dllexport) __stdcall DllMain (HINSTANCE hInstance, DWORD reason, LPVOID reserved){	switch (reason)	{		case DLL_PROCESS_ATTACH:		{			hInst = hInstance;			break;		}		case DLL_PROCESS_DETACH:			break;    }    return TRUE;}
Anybody see why windows explorer would freeze?
You might want to try RegisterHotKey() for a simpler way to implement a global keyboard shortcut.
Quote:Original post by Adam_42
You might want to try RegisterHotKey() for a simpler way to implement a global keyboard shortcut.


wow i didnt even realize there was a function like that, thanks this helps a bunch
Regarding your code, it might crash on ctrl+f12 because of the string

sequence = "Ctrl+F12";

The string on the right hand side is stored in the dll and the values of each character are hopefully transferred in the assignment to the shared sequence array variable. If that doesn't happen. If sequence is simply made to point to the string literal, then even though that string literal is stored in the dll and even though the dll is loaded into both your hook launcher app and the target app, you might get an error because the dll isn't loaded into the same address in both programs. When crossing process boundary lines, it's important to remember that each process has it's own memory address space and that a particular dll doesn't always load at the same address in every process. That means that passing string literals between process isn't a good idea. An address that is valid in one process is not guaranteed to be valid in every other process.

If the assignment of the string literal operates as a complete copy (ala old fashioned strcpy), it should work.

If you're not sure, the WM_COPYDATA message can be used to transfer string data between processes. For an idea of how to send that message from inside a hook dll, check out this demo I wrote a few years ago: GlobalMessageHook.

And since you're applying a kb hook, consider using the low level hook, WH_KEYBOARD_LL, it lets you get away with more, as this demo, keylog, shows. It lets you hook into the kb without having to fuss with a dll.
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
Just for future reference, i learned that since i was using a 32-bit dll, i was going to encounter issues on a 64-bit machine, which is probably why explorer crashes. So i went to test it on my 32-bit xp machine and it works perfect

Now that i have compiled my dll/program in 64-bit, my application just crashes, it always sais something about failed to read memory location etc..

any thoughts?

----EDIT

I found the solution to my problem yet im not going to attempt a solution atm. Its not just that my OS is a 64-bit process, any 64-bit process will freeze with my 32-bit hook dll.

The solution is to write a 32-bit and 64-bit dll, each one checking the process of the currently selected application, if they are not the same process (32-bit or 64-bit) then do nothing.

[Edited by - b1gjo3 on July 10, 2009 7:34:22 PM]

This topic is closed to new replies.

Advertisement