Window hooks - How do they work? - windows

I've got no idea how window hooks work at the "system level". MSDN only touches what's going on very briefly:
A hook is a point in the system message-handling mechanism where an
application can install a subroutine to monitor the message traffic in
the system and process certain types of messages before they reach the
target window procedure.
My best guess is something like below:
Before each message is added to the message queue for a window, it'll first send the message to the global/local hooks, which may do something, depending on their hook procedures. After all global hooks and local hooks, the message is finally added to the window message queue.
However, MSDN says that for some of the types of hooks, it will monitor events, notifications etc.
An example is the WH_MOUSE_LL hook:
Installs a hook procedure that monitors low-level mouse
input events. For more information, see the LowLevelMouseProc hook
procedure.
When they say events, are we talking window messages, or do they mean something else?
Am I all wrong?

Yes, this is a mechanism for windows messages, you can process this data (messages) before they reach target window procedure (message loop).
If you want hook other process windows you can simply do this in DLL, and use DLL injection for inject your library to other process.

Related

How to ban other threads from sending/posting messages

Or how to determine if a given message was posted/sent programmatically by another thread or simply another process?
By post and send I mean functions PostMessage and SendMessage
The Windows API does not keep track of the originator of a message. So the only way to know where a message comes from would be to directly hook the (Post|Send)Message functions in every running process.

How to shut down external application gracefully?

I have a program that shuts down another application when certain conditions are met. Now most of the time everything works out fine, but sometimes the app is writing to a file and leaves it in a half finished state and has no way of recovering it on restart. I thought that one could send soft close signals and escalate after certain timeouts to more aggressive close signals, going trough a list like this:
1. WM_CLOSE
2. WM_QUIT
3. WM_DESTROY
4. TerminateProcess().
Now I know that the program has no code to handle any signal it receives. Is there a possibility that certain FileHandler under Windows react gracefully on such soft signals or is there no use to sending those, if the app does not handle them explicitly?
This article says:
NOTE: A console application's response to WM_CLOSE depends on whether or not it has installed a control handler.
Does this mean if no control handler is installed sending 1-4 is just as good as sending 4 directly?

Can a message-only window receive WM_QUERYENDSESSION?

In the debug version of the program, I create a visible window, and the WM_QUERYENDSESSION message is received by its WNDPROC. In the release version, the window is supposed to be message-only, so I specify HWND_MESSAGE as the hWndParent when calling CreateWindowEx(). Unfortunately, I then don't receive the WM_QUERYENDSESSION message anymore.
Is WM_QUERYENDSESSION one of those broadcast messages mentioned here?
A message-only window [...] does not receive broadcast messages.
MSDN gives a decent definition of a "message-only window":
A message-only window enables you to send and receive messages. It is not visible, has no z-order, cannot be enumerated, and does not receive broadcast messages. The window simply dispatches messages.
Relevant detail highlighted.
You use them to take advantage of the message dispatch mechanism in your own code. Most typically to get a worker thread to talk to the UI thread in a thread-safe way. A message loop is the universal solution to the producer-consumer problem. Apartment marshaling in COM is implemented with a message-only window for example. Clearly such a window should be hidden and only get the messages that are defined by the app.
Don't use HWND_MESSAGE as hWndParent when calling CreateWindowEx.
Replace HWND_MESSAGE with NULL for hWndParent and you should get the behavior you intend.
Per Raymond Chen's blog:
What kind of messages can a message-only window receive?
...
The point of a message-only window is that it receives only messages sent or posted specifically to it. You use it to set up a private channel between the sender and the window. After creating a message-only window, you can put messages in the window’s queue by calling Post­Message and passing that window handle, or you can send a non-queued message by calling Send­Message and passing that window handle.
What makes a message-only window interesting is that it doesn’t particpate in broadcast messages.
Many window messages are sent to all top-level windows. WM_QUERY­END­SESSION, WM_SETTING­CHANGE, WM_DDE_INITIATE. and anything sent with HWND_BROADCAST. These messages don’t reach message-only windows.
Internally, message-only windows are treated as child windows of a system-managed common parent window called HWND_MESSAGE. This system-managed common parent window is permanently invisible, which results in message-only windows being permanently invisible. And that’s also how message-only windows are invisible to enumeration and broadcasts: Enumeration and broadcasting is done to top-level windows, but message-only windows are internally treated as child windows of HWND_MESSAGE and therefore are not considered top-level.

Windows Messages in Library Code

I am porting a library to Windows. In a function I need to block on the arrival of a WM_DEVICECHANGE message.
What options are available for doing this? As my code resides in a library I have little-to-no information on the current set-up (so if it is a Console application, a regular GUI application, if my code is being run in a spawned thread, and so on). Therefore what is the best way to wait for the arrival of a specific message?
Blocking and receiving Windows messages are mutually incompatible. You get messages by pumping a message loop. Since you cannot rely on the app pumping one, you'll need to do this yourself.
You will need to create a thread. Create a hidden window in that thread then run the standard message loop. The window procedure for that window can see the WM_DEVICECHANGE message. It can do what ever it needs to do, within the constraints of running inside a separate thread. Like setting an event to signal that a function should stop blocking.
The message is probably sent using BroadcastSystemMessage(). You could create a hidden top-level window and its window proc would probably get this message. I'm not sure; but that's what I'd try first.

Win32 API analog of sending/catching SIGTERM

Under POSIX OS there is signal API that allows to send a signal to process to shut it down
with kill and you can catch it with sigaction and do what you need;
However, Win32 is not POSIX system, so:
How can I handle shutdown events that may come, for example from "End Process" in "Task manager"?
What is the standard API for sending shutdown signal to Win32 application?
I'm not talking about GUI, I'm talking about TCP/IP server that should be nicely shutdown. that does not run like windows service.
MSDNs Unix Code Migration Guide has a chapter about Win32 code conversion and signal handling.
Although Microsoft has decided to archive this brilliant guide, it is very useful.
Three methods are described:
Native signals
Event objects
Messages
You get a WM_QUIT message on your first created thread.
When you don't handle that, your process is forcibly shutdown.
So just implement a message queue in your first thread, which looks for the WM_QUIT message
May be Windows Power Management from MSDN would be helpful. But it deals with system events rather than per process.
For a process, you would be able to detect termination with WM_CLOSE. You would need to handle windows messages. If it's a console application you would need to install a control handler; take a look at SetConsoleCtrlHandler on MSDN

Resources