Thread View: borland.public.cppbuilder.nativeapi
7 messages
7 total messages
Started by nicolasr
Thu, 27 Mar 2003 00:51
Hooking another application
Author: nicolasr
Date: Thu, 27 Mar 2003 00:51
Date: Thu, 27 Mar 2003 00:51
38 lines
2168 bytes
2168 bytes
Hi, I'm trying to hook a third party app to send it messages that can't be sent accross process boundaries (f.e. messages that have pointers as wParam/lParam, since the pointers are invalid in the other address space). I wrote a DLL, a client app and a test server (simulating the third party app) The DLL exports: SetHook(DWORD threadID) Unhook() and implements the hook callback function with the WH_GETMESSAGE hook type. The client uses CreateProcess() to launch the server, then loads the DLL and calls SetHook() with the threadID returned by CreateProcess(). I used MessageBeep() to confirm that the DLL is loaded in the address space of the server and that the hook callback is called for standard messages. The problem is: I want to send a custom message from the client to the server that should arrive in the DLLs callback. So I defined a custom message in both the client and the DLL: #define HOOK_WM_TEST (WM_USER + 100) Now I used FindWindow() in the client to get the window handle of the servers main window. Then I did: SendMessage(hwndServer, HOOK_WM_TEST, 0, 0); But this messages does not arrive in the DLL callback function. What am I doing wrong? Is WH_GETMESSAGE the correct hook type? thanks for any idea, Nick
Re: Hooking another application
Author: Remy Lebeau (TeamB)
Date: Thu, 27 Mar 2003 01:16
Date: Thu, 27 Mar 2003 01:16
23 lines
1841 bytes
1841 bytes
WH_GETMESSAGE hooks are only called when GetMessage() or PeekMessage() is called for retreiving messages from the calling thread's message queue. But, SendMessage() doesn't use the message queue at all, it sends the message directly to the window procedure of the target window. In order to track the message queue, you need to use PostMessage() instead of SendMessage(). Otherwise, your DLL needs to install a WH_CALLWNDPROC hook at well in order to support messagses sent with SendMessage() in addition to messages posted to the queue with PostMessage(). Gambit "nicolasr" <nicolasrATSIGNgmx.net> wrote in message news:3e824b00@newsgroups.borland.com... > and implements the hook callback function with the > WH_GETMESSAGE hook type. <snip> > SendMessage(hwndServer, HOOK_WM_TEST, 0, 0); > > But this messages does not arrive in the DLL callback > function.
Re: Hooking another application
Author: nicolasr
Date: Thu, 27 Mar 2003 19:17
Date: Thu, 27 Mar 2003 19:17
14 lines
1566 bytes
1566 bytes
thank you very much, Remy. I tried WH_GETMESSAGE together with PostMessage() as you suggested and this works well now. I think I will also need SendMessage(), though. So I tried a WH_CALLWNDPROC hook and this doesn't work. The hook callback is called for other messages (redraw etc.) but never for my SendMessage(). Which window proc is actually hooked, the main form, the application window? When setting the hook I only pass the thread ID of the server app. Then in my client I used FindWindow() to find the main form. But SendMessage() to this window seems to bypass the hook callback somehow. Any ideas? thanks, Nick
Re: Hooking another application
Author: Remy Lebeau (TeamB)
Date: Thu, 27 Mar 2003 20:36
Date: Thu, 27 Mar 2003 20:36
33 lines
2144 bytes
2144 bytes
"nicolasr" <nicolasrATSIGNgmx.net> wrote in message news:3e834e27$1@newsgroups.borland.com... > I tried WH_GETMESSAGE together with PostMessage() > as you suggested and this works well now. Just be careful with PostMessage(). Keep in mind that it returns immediately, it does not wait for the message to actually be processed. So if you're passing pointers, especially local ones as your earlier samples with COPYDATASTRUCT were doing, and your code exits and frees the data before the receiver gets a chance to process the message, the receiver is going to blow up from accessing invalid memory. > The hook callback is called for other messages (redraw > etc.) Those are posted to the message queue, thus the WH_GETMESSAGE hook would pick them up. > but never for my SendMessage(). Did you call SetWindowsHookEx() a second time to register the WH_CALLWNDPROC hook as well? > Which window proc is actually hooked, the main form, > the application window? All of the procedures for all of the windows associated with the thread ID you specified to SetWindowsHookEx(). Gambit
Re: Hooking another application
Author: nicolasr
Date: Fri, 28 Mar 2003 00:14
Date: Fri, 28 Mar 2003 00:14
78 lines
3082 bytes
3082 bytes
Hi,
thanks for your help!
> Just be careful with PostMessage(). Keep in mind that it returns
> immediately...
Thanks for the hint. I guess that is why I would prefer SendMessage(). On
the other hand with PostMessage() I maybe could implement a timeout
mechanism. I think it depends on the individual message. So it would be nice
to have both options.
> > The hook callback is called for other messages (redraw
> > etc.)
>
> Those are posted to the message queue, thus the WH_GETMESSAGE hook would
> pick them up.
>
> > but never for my SendMessage().
>
> Did you call SetWindowsHookEx() a second time to register the
WH_CALLWNDPROC
> hook as well?
>
Actually I have tried both ways separately yet. But I should do both in the
end. As I wrote the client calls SetHook(threadId) on the DLL which
currently looks like this:
bool SetHook(DWORD threadId)
{
hHook = SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)CallWndProc,
HInstance, threadId);
if(hHook == NULL)
return false;
else
return true;
}
I'm a little unsure about the parameters passed to SetWindowsHookEx? Must
the third parameter be NULL or not in my special case?
The callback in the DLL looks like this:
LRESULT CALLBACK CallWndProc(int code, WPARAM wParam, LPARAM lParam)
{
if(code == HC_ACTION)
{
CWPSTRUCT* msg = (CWPSTRUCT*)lParam;
switch(msg->message)
{
case HOOK_WM_TEST:
MessageBeep(-1); //never called ##########
break;
case WM_NCHITTEST:
MessageBeep(-1); //this is always called when I move the mouse
over the server window########
break;
}
}
return CallNextHookEx(hHook, code, wParam, lParam);
}
the call in the client looks like this:
void __fastcall TForm2::Button2Click(TObject *Sender)
{
if(hwnd) //hwnd returned from FindWindow for the servers main window
{
SendMessage(hwnd, HOOK_WM_TEST, 0, 0);
}
}
I really don't have any idea what could be wrong?
thanks,
Nick
Re: Hooking another application
Author: Remy Lebeau (TeamB)
Date: Fri, 28 Mar 2003 00:46
Date: Fri, 28 Mar 2003 00:46
28 lines
1945 bytes
1945 bytes
"nicolasr" <nicolasrATSIGNgmx.net> wrote in message news:3e83949f@newsgroups.borland.com... > On the other hand with PostMessage() I maybe could > implement a timeout mechanism. Have a look at the SendMessageTimeout() function. Then you can have both in a single call. > I'm a little unsure about the parameters passed to > SetWindowsHookEx? Must the third parameter be > NULL or not in my special case? You can't pass NULL since you're trying to hook another process. NULL is only valid if you are hooking your own process, in which case a DLL is not needed at all. But to hook another process, a DLL is required, and the third parameter is the instance handle for the DLL itself, not the application. > The callback in the DLL looks like this: <snip> You need to export your callback functions from the DLL, if you're not already. Gambit
Re: Hooking another application
Author: nicolasr
Date: Mon, 31 Mar 2003 00:52
Date: Mon, 31 Mar 2003 00:52
25 lines
2278 bytes
2278 bytes
Hi, first of all thanks for your help. I have tried everything that came to my mind. I also read former posts from you and others regarding this topic but nothing helps. The problem is: I installed WH_GETMESSAGE and WH_CALLWNDPROCRET hooks. WH_GETMESSAGE works as expected when I call PostMessage() from my client. But the WH_CALLWNDPROCRET hook (used with SendMessage) is only called for messages not sent by my client. In my client I did SendMessage() with my custom message but it does not arrive in the callback. Then I sent f.e. WM_PAINT, still no success. (I used MessageBeep() in the DLL to check whether it arrives) To check whether the message arrives at the server at all I overwrote it's WndProc and yes, the messages all arrive in the servers WndProc but not in the DLLs hook proc? So, if anyone has any idea I would really appreciate it. If not, I think I will have to stick with PostMessage(). The problem is that I then have to pass message return values via shared memory or WM_COPYDATA and take care of synchronization... thanks, Nick
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads