Hook Trouble
-
Hi, im trying to learn about setting up system wide windows hooks, ibe written the .dll where the hookproc resides, and a simple test app. it actually works, as long as i dont try to call the test application from inside the hook proc, but if i do try to call it, then its not system wide any more!. i put the global variables inside the .dll in a shared section like this: #pragma data_seg(".HKT") HHOOK hTheHook=NULL; // the hook handle HNOTFN pTriggerFn=NULL; // Fn to tell the app the hook has been triggered LPVOID pUserData=NULL; // app specific pointer passed to the above function #pragma data_seg(); #pragma comment(linker, "/section:.HKT, rws") to set the hook, the .dll exports a function like this (there is also another one to remove it), wich is called by the test app: BOOL DLL_EXPORT SetTheHook(HNOTFN CalledFn, LPVOID UsrDta) { pTriggerFn=CalledFn; pUserData=UsrDta; hTheHook=SetWindowsHookEx(WH_KEYBOARD, MyHookProc, GetModuleHandle("HookLib.dll"), 0); return (hTheHook!=NULL); } CalledFn is typedeféd as this typedef void (CALLBACK* HNOTFN) (WPARAM, LPARAM, LPVOID); the test app´s main dialog has a static member function with this signature, wich is passed when the hook is set, so the .dll can "tell" the app when its been triggered, the LPVOID passed is the this pointer of the dialog itself, so the static function in the dialog can cast it to the dialog type, and call other non static functions. my hook proc in the .dll is this: LRESULT CALLBACK MyHookProc(int Code, WPARAM Wparam, LPARAM Lparam) { if(Code >= 0) { if(pTriggerFn) pTriggerFn(Wparam, Lparam, pUserData); } return CallNextHookEx(hTheHook, Code, Wparam, Lparam); } The Problem: if i compile / run the above, MyHookProc ONLY gets called when the test app has the focus, if i press any key with the app minimized(not having focus), it doesnt get called. (not a system-wide hook) However, if i just remove the call to pTriggerFn(), and place some other way of knowing its been called like MessageBox(NULL, "I was Called"), then the hook works as expected! even if the test app doesnt have the focus! any idea of what im doing wrong?? thanks for reading!
-
Hi, im trying to learn about setting up system wide windows hooks, ibe written the .dll where the hookproc resides, and a simple test app. it actually works, as long as i dont try to call the test application from inside the hook proc, but if i do try to call it, then its not system wide any more!. i put the global variables inside the .dll in a shared section like this: #pragma data_seg(".HKT") HHOOK hTheHook=NULL; // the hook handle HNOTFN pTriggerFn=NULL; // Fn to tell the app the hook has been triggered LPVOID pUserData=NULL; // app specific pointer passed to the above function #pragma data_seg(); #pragma comment(linker, "/section:.HKT, rws") to set the hook, the .dll exports a function like this (there is also another one to remove it), wich is called by the test app: BOOL DLL_EXPORT SetTheHook(HNOTFN CalledFn, LPVOID UsrDta) { pTriggerFn=CalledFn; pUserData=UsrDta; hTheHook=SetWindowsHookEx(WH_KEYBOARD, MyHookProc, GetModuleHandle("HookLib.dll"), 0); return (hTheHook!=NULL); } CalledFn is typedeféd as this typedef void (CALLBACK* HNOTFN) (WPARAM, LPARAM, LPVOID); the test app´s main dialog has a static member function with this signature, wich is passed when the hook is set, so the .dll can "tell" the app when its been triggered, the LPVOID passed is the this pointer of the dialog itself, so the static function in the dialog can cast it to the dialog type, and call other non static functions. my hook proc in the .dll is this: LRESULT CALLBACK MyHookProc(int Code, WPARAM Wparam, LPARAM Lparam) { if(Code >= 0) { if(pTriggerFn) pTriggerFn(Wparam, Lparam, pUserData); } return CallNextHookEx(hTheHook, Code, Wparam, Lparam); } The Problem: if i compile / run the above, MyHookProc ONLY gets called when the test app has the focus, if i press any key with the app minimized(not having focus), it doesnt get called. (not a system-wide hook) However, if i just remove the call to pTriggerFn(), and place some other way of knowing its been called like MessageBox(NULL, "I was Called"), then the hook works as expected! even if the test app doesnt have the focus! any idea of what im doing wrong?? thanks for reading!
The problem could be the way you use the user-defined function as a "callback". Where in your program is this function defined? Statically, it seems on first analysis. In order for it to work correctly this function *must* be inside the hook DLL, otherwise when your hook DLL is loaded into another process's address space, the hook procedure will try to call a function that does not exist in that address space, and "strange things" will happen. You have to devise some kind of inter-process communication to get this to work between processes. windows-messages, events, rpc etc are all valid options. Just a guess James
http://www.catch22.uk.net -
The problem could be the way you use the user-defined function as a "callback". Where in your program is this function defined? Statically, it seems on first analysis. In order for it to work correctly this function *must* be inside the hook DLL, otherwise when your hook DLL is loaded into another process's address space, the hook procedure will try to call a function that does not exist in that address space, and "strange things" will happen. You have to devise some kind of inter-process communication to get this to work between processes. windows-messages, events, rpc etc are all valid options. Just a guess James
http://www.catch22.uk.netThanks for your answer James, ibe just read Mr J. Newcomer´s article on hooks, and for what i understood, the whole "dll calls back the app by a function pointer" idea wont work, so i went for PostMessage() instead, the app passes its HWND to the dll in the call to set the hook, wich is stored in the dll´s shared section, and in the hook proc, the dll Posts a custom message to the app using this HWND. Worked like a charm! Thanks for reading