Re: Global Hook DLL and Hook Initator Application Communication,...
On Fri, 21 Dec 2007 22:49:40 +0100, "Kerem GLmrLkcL"
<kareem114@hotmail.com> wrote:
Hi Doug,
the communication should be unidirectional which means that
i want to signal the dll that it should load a specific xml data
into a dll maintained internal (double) linked string list. Yes this
could be a boolean value. I mean i can work with signals on
global shared memory areas or with wait objects, events,
message broadcasts. There are a lot of ways to do this, but
what would others recommend. The dlls has to reload the
xml into its internal list on a signal,...thats all,...
I know that there is the process boundary, but it is not a real
boundary, where you can work e.g. with WM_COPYDATA,
global shared memory, pipes, some of ipc,....but what would
you recommend?
The thing is, a DLL is not sitting there waiting on some sort of event, at
least not without blocking the thread that called into it. I don't think
your hook DLL should be starting threads for this purpose inside all the
processes that load it.
This is what I did for a global mouse hook DLL that needed to reload
configuration data due to user input:
http://www.eluent.com/wheeler.htm
The program wheeler_run.exe installs and uninstalls the hook. It's a very
simple, small, UI-less program and remains resident so that it can respond
to requests from wheeler_cfg.exe, which is the GUI configuration program.
When wheeler_cfg wants to update the configuration, remove the hook, or
otherwise communicate with wheeler_run.exe, it can find that program by
calling functions defined by wheeler_hook.dll. The hook DLL maintains a
very tiny amount of shared data, just the hook handle and wheeler_run's
process ID. I also use a named event object for communication.
Thus, wheeler_run.exe solves the problem of communicating with all the
instances of the hook DLL. Here's the end of its WinMain function:
*****
if (!Wheeler::InstallHook())
{
MsgBox(IDS_INSTALL_HOOK_FAILURE, MB_OK | MB_ICONEXCLAMATION);
return 1;
}
do
{
MSG msg;
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
} while (MsgWaitForMultipleObjects(1, &hEvent, false, INFINITE,
QS_ALLINPUT) != WAIT_OBJECT_0);
Wheeler::RemoveHook();
// The following helps hooked applications unmap the hook DLL.
DWORD_PTR res;
SendMessageTimeout(HWND_BROADCAST, WM_NULL, 0, 0, SMTO_NORMAL, 1000,
&res);
*****
To update the configuration, wheeler_cfg signals wheeler_run's quit-event,
causing it to exit its message loop. It removes the hook, and the program
terminates. To cause the new configuration to take effect, wheeler_cfg
restarts wheeler_run, and the new data is used as wheeler_hook.dll is
reloaded into processes as they receive mouse input. This was the simplest
approach I was able to devise, and it works transparently. As each instance
of the DLL has its own copy of the data, it avoids trying to share complex
data structures between instances of the DLL, along with all the
synchronization issues that presents.
--
Doug Harrison
Visual C++ MVP