Board index » cppbuilder » Message-Only Invisible Window

Message-Only Invisible Window


2006-06-11 11:11:18 PM
cppbuilder91
Hi all,
Just looking for a bit of information on creating hidden message windows for
a DLL. The background is that I have a bug in a DLL that i've written that
seems to stem from the fact that the calling process exports some functions
that are not thread safe.
Basically a ProcessA calls my DLL and makes available some functions for my
DLL by passing my DLL a pointer to a specific structure. My DLL has two
threads, it's main thread (threadM) and a secondary one that examines some
hardware (threadH). If a certain hardware condition occurs, I need to call
one of the functions in the calling processA. However, if threadH calls the
exported function, the whole system can, on occasion stop working correctly
or work sporadically.
For this reason my main DLL thread needs to create a message-only window so
the secondary hardware polling thread can inform it with a custom message,
of the hardware condition. In response to this, the main thread, threadM,
can then call the non-thread-safe function in ProcessA.
After reading MSDN, it seems that I can do this with CreateProcess and
CreateProcessEx, passing HWND_MESSAGE as the hWndParent. However, I'm not
100% sure what calls I need to implement in this particular case. Normally
when using CreateWindow I would do the following;
1) define a WndProc callback procedure for the intended window.
2) define and propagate a WNDCLASS or WNDCLASSEX class structure.
3) Register the class with a call to RegisterClass or RegisterClassEx.
4) If sucessfull, call CreateWindow or CreateWindowEx with the same
classname as used in WNDCLASS.
5) If a valid HWND is created, call ShowWindow() and UpdateWindow().
6) Enter a while(GetMessage()) loop.
However, the situation that I have is slightly different and I need to
confirm the following:
1) Are there any specific properties, other than HWND_MESSAGE as the
hWndParent, that I need to set in either WNDCLASS / WNDCLASSEX or
RegisterClass / RegisterClassEx in my specific situation?
2) Do I need to call ShowWindow() or UpdateWindow in this particular context
as I don't really have a window to show?
3) Do I specifically have code the while(GetMessage()) loop or can I rely on
the WndProc to detect and capture my custom messages? I only ask this
because it would seem to me that if I have a while loop in the start-up of
my DLL's main thread, it would then in effect pause the thread as it would
be sitting in that loop.
4) I want to ensure that no other processes can attempt to close or
terminate this hidden window - what is the best way to prevent this.
Any help or pointers would be great - google search is a bit limited on this
subject
 
 

Re:Message-Only Invisible Window

Mike Collins wrote:
Quote
Basically a ProcessA calls my DLL and makes available some functions for my
DLL by passing my DLL a pointer to a specific structure. My DLL has two
threads, it's main thread (threadM) and a secondary one that examines some
hardware (threadH). If a certain hardware condition occurs, I need to call
one of the functions in the calling processA. However, if threadH calls the
exported function, the whole system can, on occasion stop working correctly
or work sporadically.
So, really, your dll creates One thread (threadH), and your theadM is
actually ProcessA?
So, you want ProcessA to call the function.
You could tell the author of ProcessA to handle your special message.
Or you could create a global hook that gets injected into ProcessA's
message handling.
See SetWindowsHookEx()
You might Google for code that Remy has posted several times.
Quote
1) Are there any specific properties, other than HWND_MESSAGE as the
hWndParent, that I need to set in either WNDCLASS / WNDCLASSEX or
RegisterClass / RegisterClassEx in my specific situation?
I don't think so.
Quote
2) Do I need to call ShowWindow() or UpdateWindow in this particular context
as I don't really have a window to show?
I don't think so, or maybe with SW_SHOW_HIDDEN
Quote
3) Do I specifically have code the while(GetMessage()) loop or can I rely on
Yes
the WndProc to detect and capture my custom messages? I only ask this
No
because it would seem to me that if I have a while loop in the start-up of
my DLL's main thread, it would then in effect pause the thread as it would
be sitting in that loop.
Yes. That's why you used CreateProcess or CreateThread
4) I want to ensure that no other processes can attempt to close or
terminate this hidden window - what is the best way to prevent this.
Best way to prevent that is to not do it this way.
 

Re:Message-Only Invisible Window

Bob Gonder < XXXX@XXXXX.COM >wrote:
Quote

[...] Best way to prevent that is to not do it this way.
Sounds like a damn virus to me.
~ JD
 

{smallsort}

Re:Message-Only Invisible Window

JD wrote:
Quote
Bob Gonder wrote:
>
>[...] Best way to prevent that is to not do it this way.

Sounds like a damn virus to me.
Or good defensive programming for a public kiosk.
 

Re:Message-Only Invisible Window

Ok guys, not a virus - would like to think that i've asked enough stupid
questions here that people would know i'm not a virus writter.
I just didn't want to distract from the problem by going into a long
explaination of the exact problem. Basically I'm bug fixing a GinaStub
system that we have had in place for the last 9 months. I've just recently
started to recieve some errors. On careful examination and scowering MSDN,
I have found that the winlogon exported funtions are not thread safe. In my
main dll / thread I had a procedure that called a specific winlogon exported
function. My polling thread would call this procedure. However, this would
seem to be in the context of the polling thread, not the main thread.
So this is the reason for the message window. The polling thread would
SendMessage to the hidden window which would call the procedure in the
context of the main thread.
I've got a basic implimentation working now except it causes some strange
problems in Windows 2k3 i.e. seems to cause certain services not to start.
If i simply wanted to hide a window i would do it with ShowWindow....
Mike
"JD" < XXXX@XXXXX.COM >wrote in message
Quote

Bob Gonder < XXXX@XXXXX.COM >wrote:
>
>[...] Best way to prevent that is to not do it this way.

Sounds like a damn virus to me.

~ JD

 

Re:Message-Only Invisible Window

"Mike Collins" < XXXX@XXXXX.COM >wrote in message
Quote
After reading MSDN, it seems that I can do this with CreateProcess and
CreateProcessEx, passing HWND_MESSAGE as the hWndParent. However, I'm not
100% sure what calls I need to implement in this particular case.
Normally
when using CreateWindow I would do the following;

1) define a WndProc callback procedure for the intended window.
2) define and propagate a WNDCLASS or WNDCLASSEX class structure.
3) Register the class with a call to RegisterClass or RegisterClassEx.
4) If sucessfull, call CreateWindow or CreateWindowEx with the same
classname as used in WNDCLASS.
5) If a valid HWND is created, call ShowWindow() and UpdateWindow().
6) Enter a while(GetMessage()) loop.

However, the situation that I have is slightly different and I need to
confirm the following:

1) Are there any specific properties, other than HWND_MESSAGE as the
hWndParent, that I need to set in either WNDCLASS / WNDCLASSEX or
RegisterClass / RegisterClassEx in my specific situation?
2) Do I need to call ShowWindow() or UpdateWindow in this particular
context
as I don't really have a window to show?
3) Do I specifically have code the while(GetMessage()) loop or can I rely
on
the WndProc to detect and capture my custom messages? I only ask this
because it would seem to me that if I have a while loop in the start-up of
my DLL's main thread, it would then in effect pause the thread as it would
be sitting in that loop.
4) I want to ensure that no other processes can attempt to close or
terminate this hidden window - what is the best way to prevent this.
I can't answer your questions directly, but I can tell you that I managed to
create an invisible window to process messages in a service (a service does
not normally receive/process Windows messages, and I needed to handle the
WM_TIMECHANGE message, along with several custom messages). Basically, my
service follows your steps 1-4 to create a window via CreateWindow(). I do
not call ShowWindow/UpdateWindow nor do I have a GetMessage() loop, and yet,
my service receives and processes Windows messages.
Here is a code-snippet, just in case it proves to be helpful (keep in mind
that this code was implemented in a TService descendant class):
// Services cannot normally receive Windows messages because they do not
have windows associated
// with a desktop. This function registers a hidden window that is capable
of receiving broadcast
// Windows messages or self-posted messages.
bool TMyService::CreateMessageHandlerWnd( void )
{
WNDCLASSEX w;
memset(&w, 0, sizeof(w));
w.cbSize = sizeof(w);
w.hInstance = Forms::Application->Handle;
w.lpfnWndProc = MyServiceWindowProc;
w.lpszClassName = "MyServiceWindowClass";
ATOM atom = ::RegisterClassEx(&w);
if ( atom )
{
// TMyService::Handle is a static HWND data member
TMyService::Handle = ::CreateWindow( w.lpszClassName,
"",
WS_DISABLED,
0, 0, 0, 0,
NULL,
NULL,
w.hInstance,
NULL);
}
return (atom && TMyService::Handle);
}
And the WndProc function is quite simple:
// This is the message processing function. When the service receives
broadcast messages, or
// or messages posted by the service, they are handled and processed here.
LRESULT CALLBACK TMyService::MyServiceWindowProc( HWND hWnd,
UINT
uMsg,
WPARAM
wParam,
LPARAM
lParam )
{
TMessage msg;
msg.Msg = uMsg;
msg.WParam = wParam;
msg.LParam = lParam;
// don't try to handle messages until the service has been instantiated
if ( MyService )
{
switch( uMsg )
{
case WM_TIMECHANGE:
MyService->WMTimeChangeHandler( msg );
break;
// etc.
}
}
return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
}
- Dennis
 

Re:Message-Only Invisible Window

"Mike Collins" < XXXX@XXXXX.COM >wrote:
Quote

Ok guys, not a virus - would like to think [...]
Don't mind me. I just went a round with a particularly {*word*193}
one that worked exactly how you described ... 2 processes that
monitored the other so if you killed one process, the other
restarted it. It also renamed itself and set the file date to
years ago and monitored the registry as well so if you removed
it from there ... you get the idea.
~ JD
 

Re:Message-Only Invisible Window

Yeh, I know what you mean, it's a pity that some of these creative virus
writers couldn't put there skill to something more useful than popping {*word*40}
up on our desktops.
In reality, the methods that they adopt are usually pretty simplistic -
just creative use of the win api's. The real skill is in rootkiting and dll
inject - total system cloaking - but it's hard work and you need to stay
a{*word*78} of the windows updates. We have a system like this running and it's
pretty impressive - just looks like there's nothing there :) - but our
product is a legitimate one.....
I think i had explained myself badly in the first place...
No offence taken, regards
"JD" < XXXX@XXXXX.COM >wrote in message
Quote

"Mike Collins" < XXXX@XXXXX.COM >wrote:
>
>Ok guys, not a virus - would like to think [...]

 

Re:Message-Only Invisible Window

Thanks for the post - your code works pretty much as mine does. I've
upgraded it to use the Ex versions of RegisterClass and CreateWindow and it
works brilliantly. Obviously the while(GetMessage()) loop is used to
translate user input message and in my case this is not necessary AND blocks
the further flow of the dll's processing.
A point worth noting for you is that if you set the parent window handle to
HWND_MESSAGE - the message window does not appear when you enumerate windows
so it's a bit harder for others to find the handle and mess on with it. The
downside of this is that the window does not receive broadcast messages but
in my case that is now an issue.
"Dennis Jones" < XXXX@XXXXX.COM >wrote in message
Quote

"Mike Collins" < XXXX@XXXXX.COM >wrote in message
news: XXXX@XXXXX.COM ...

>After reading MSDN, it seems that I can do this with CreateProcess and
>CreateProcessEx, passing HWND_MESSAGE as the hWndParent. However, I'm
>not
>100% sure what calls I need to implement in this particular case.
Normally
>when using CreateWindow I would do the following;
>
>1) define a WndProc callback procedure for the intended window.
>2) define and propagate a WNDCLASS or WNDCLASSEX class structure.
>3) Register the class with a call to RegisterClass or RegisterClassEx.
>4) If sucessfull, call CreateWindow or CreateWindowEx with the same
>classname as used in WNDCLASS.
>5) If a valid HWND is created, call ShowWindow() and UpdateWindow().
>6) Enter a while(GetMessage()) loop.
>
>However, the situation that I have is slightly different and I need to
>confirm the following:
>
>1) Are there any specific properties, other than HWND_MESSAGE as the
>hWndParent, that I need to set in either WNDCLASS / WNDCLASSEX or
>RegisterClass / RegisterClassEx in my specific situation?
>2) Do I need to call ShowWindow() or UpdateWindow in this particular
context
>as I don't really have a window to show?
>3) Do I specifically have code the while(GetMessage()) loop or can I rely
on
>the WndProc to detect and capture my custom messages? I only ask this
>because it would seem to me that if I have a while loop in the start-up
>of
>my DLL's main thread, it would then in effect pause the thread as it
>would
>be sitting in that loop.
>4) I want to ensure that no other processes can attempt to close or
>terminate this hidden window - what is the best way to prevent this.

I can't answer your questions directly, but I can tell you that I managed
to
create an invisible window to process messages in a service (a service
does
not normally receive/process Windows messages, and I needed to handle the
WM_TIMECHANGE message, along with several custom messages). Basically, my
service follows your steps 1-4 to create a window via CreateWindow(). I
do
not call ShowWindow/UpdateWindow nor do I have a GetMessage() loop, and
yet,
my service receives and processes Windows messages.

Here is a code-snippet, just in case it proves to be helpful (keep in mind
that this code was implemented in a TService descendant class):

// Services cannot normally receive Windows messages because they do not
have windows associated
// with a desktop. This function registers a hidden window that is
capable
of receiving broadcast
// Windows messages or self-posted messages.
bool TMyService::CreateMessageHandlerWnd( void )
{
WNDCLASSEX w;
memset(&w, 0, sizeof(w));
w.cbSize = sizeof(w);
w.hInstance = Forms::Application->Handle;
w.lpfnWndProc = MyServiceWindowProc;
w.lpszClassName = "MyServiceWindowClass";
ATOM atom = ::RegisterClassEx(&w);
if ( atom )
{
// TMyService::Handle is a static HWND data member
TMyService::Handle = ::CreateWindow( w.lpszClassName,
"",
WS_DISABLED,
0, 0, 0, 0,
NULL,
NULL,
w.hInstance,
NULL);
}
return (atom && TMyService::Handle);
}

And the WndProc function is quite simple:

// This is the message processing function. When the service receives
broadcast messages, or
// or messages posted by the service, they are handled and processed here.
LRESULT CALLBACK TMyService::MyServiceWindowProc( HWND hWnd,
UINT
uMsg,
WPARAM
wParam,
LPARAM
lParam )
{
TMessage msg;
msg.Msg = uMsg;
msg.WParam = wParam;
msg.LParam = lParam;

// don't try to handle messages until the service has been instantiated
if ( MyService )
{
switch( uMsg )
{
case WM_TIMECHANGE:
MyService->WMTimeChangeHandler( msg );
break;

// etc.
}
}
return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
}

- Dennis