Thread View: borland.public.cppbuilder.nativeapi
9 messages
9 total messages
Started by Mike Collins
Sun, 11 Jun 2006 15:11
Message-Only Invisible Window
Author: Mike Collins
Date: Sun, 11 Jun 2006 15:11
Date: Sun, 11 Jun 2006 15:11
52 lines
3625 bytes
3625 bytes
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
Author: Bob Gonder
Date: Sun, 11 Jun 2006 15:39
Date: Sun, 11 Jun 2006 15:39
43 lines
2911 bytes
2911 bytes
Mike Collins wrote: >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. >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. >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 >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
Author: JD
Date: Sun, 11 Jun 2006 17:32
Date: Sun, 11 Jun 2006 17:32
8 lines
1020 bytes
1020 bytes
Bob Gonder <notbg@notmindspring.invalid> 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
Author: Bob Gonder
Date: Sun, 11 Jun 2006 18:08
Date: Sun, 11 Jun 2006 18:08
8 lines
1243 bytes
1243 bytes
JD wrote: >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
Author: Mike Collins
Date: Sun, 11 Jun 2006 23:57
Date: Sun, 11 Jun 2006 23:57
35 lines
2443 bytes
2443 bytes
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" <nospam@nospam.com> wrote in message news:448c53ad$1@newsgroups.borland.com... > > Bob Gonder <notbg@notmindspring.invalid> 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
Author: Dennis Jones
Date: Mon, 12 Jun 2006 03:53
Date: Mon, 12 Jun 2006 03:53
110 lines
5349 bytes
5349 bytes
"Mike Collins" <its@TheBottomOfThePost.com> wrote in message
news:448c3299@newsgroups.borland.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
Re: Message-Only Invisible Window
Author: JD
Date: Mon, 12 Jun 2006 11:51
Date: Mon, 12 Jun 2006 11:51
13 lines
1469 bytes
1469 bytes
"Mike Collins" <its@TheBottomOfThePost.com> wrote: > > Ok guys, not a virus - would like to think [...] Don't mind me. I just went a round with a particularly nasty 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
Author: Mike Collins
Date: Mon, 12 Jun 2006 14:32
Date: Mon, 12 Jun 2006 14:32
22 lines
1992 bytes
1992 bytes
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 porn 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 abreast 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" <nospam@nospam.com> wrote in message news:448d552a$1@newsgroups.borland.com... > > "Mike Collins" <its@TheBottomOfThePost.com> wrote: >> >> Ok guys, not a virus - would like to think [...] >
Re: Message-Only Invisible Window
Author: Mike Collins
Date: Mon, 12 Jun 2006 14:37
Date: Mon, 12 Jun 2006 14:37
136 lines
6487 bytes
6487 bytes
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" <nospam@nospam.com> wrote in message
news:448ce553$1@newsgroups.borland.com...
>
> "Mike Collins" <its@TheBottomOfThePost.com> wrote in message
> news:448c3299@newsgroups.borland.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
>
>
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