What do I have to do to make my WH_SHELL or WH_CBT hook procedure receive events from other processes? What do I have to do to make my WH_SHELL or WH_CBT hook procedure receive events from other processes? windows windows

What do I have to do to make my WH_SHELL or WH_CBT hook procedure receive events from other processes?


The problem is that your hook DLL is actually being loaded into several different address spaces. Any time Windows detects an event in some foreign process that must be processed by your hook, it loads the hook DLL into that process (if it's not already loaded, of course).

However, each process has its own address space. This means that the callback function pointer that you passed in InitHook() only makes sense in the context of your EXE (that's why it works for events in your app). In any other process that pointer is garbage; it may point to an invalid memory location or (worse) into some random code section. The result can either be an access violation or silent memory corruption.

Generally, the solution is to use some sort of interprocess communication (IPC) to properly notify your EXE. The most painless way for your case would be to post a message and cram the needed info (event and HWND) into its WPARAM/LPARAM. You could either use a WM_APP+n or create one with RegisterWindowMessage(). Make sure the message is posted and not sent, to avoid any deadlocks.


This might be tertiary to your question, but as you're seeing, hooks are very hard to get right - if you can avoid using this by any means, do it. You're going to run into all sorts of problems with them, especially on Vista where you'll have to deal with UIPI.


Just to clarify something that "efotinis" mentioned about posting messages back to your process - the wParam and lParam that you post to your main process can't be pointers, they can just be "numbers".

For example, lets say you hook the WM_WINDOWPOSCHANGING message, windows passes you a pointer to a WINDOWPOS in the lparam. You can't just post that lparam back to your main process because the memory the lparam is pointing to is only valid in the process that recieves the message.

This is what "efotinis" meant when he said " cram the needed info (event and HWND) into its WPARAM/LPARAM". If you want to pass more complex messages back your going to need to use some other IPC (like named pipes, TCP or memory mapped files).