🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.cppbuilder.nativeapi
7 messages
7 total messages Started by nicolasr Thu, 27 Mar 2003 00:51
Hooking another application
#17391
Author: nicolasr
Date: Thu, 27 Mar 2003 00:51
38 lines
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
#17410
Author: Remy Lebeau (TeamB)
Date: Thu, 27 Mar 2003 01:16
23 lines
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
#17280
Author: nicolasr
Date: Thu, 27 Mar 2003 19:17
14 lines
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
#17282
Author: Remy Lebeau (TeamB)
Date: Thu, 27 Mar 2003 20:36
33 lines
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
#17290
Author: nicolasr
Date: Fri, 28 Mar 2003 00:14
78 lines
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
#17293
Author: Remy Lebeau (TeamB)
Date: Fri, 28 Mar 2003 00:46
28 lines
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
#17233
Author: nicolasr
Date: Mon, 31 Mar 2003 00:52
25 lines
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