views:

68

answers:

3

I need to call API

CallWindowProc((WNDPROC)lpfnOldProc, hWnd, Message, wParam, lParam);

Now how can I make sure that lpfnOldProc still valid ?

Basically,lpfnOldProc is procedure in another dll and if that dll is unloaded then lpfnOldProc will still be pointing to something but not valid memory?

Are there some memory API's through which I can verify validity of lpfnOldProc?

+1  A: 

You can't check. You can set up structured exception handling to catch the fault that will result of the DLL in question has gone away or been replaced by a copy of the Encyclopedia Brittanica mapped into memory.

bmargulies
+4  A: 

Don't worry. You're in a hook proc obviously. Now, even in your absence the program would crash if the original window proc was unloaded and called. It doesn't matter that you're now the caller instead of Windows.

A Window Proc should remain in memory as long as there are existing windows using it. The responsibility for this check lies fully with the code considering the unload, not the callers of the Window Proc (i.e. you). This responsibility can be summarized in one line: "Don't unload anything still in use."

MSalters
Okay, I am the last one to call that WindProc . If I can confirm the validity of that proc before calling it, my application will not crash.Is it possible to check that validity?
Alien01
No, there is no way to test if *any* pointer, whether to a function or to data, is valid. You're supposed to *know* this, and avoid using pointers that don't point to valid data.
jalf
I see I need to phrase the last bit more explicitly.
MSalters
MSalters is correct, you should not be in a situation where the procedure you want to call is in a dll that's not available. Someone needs to either a) not unload the dll, b) stop the hook/subclass at the time of the dll unloading, and restore the original proc.
Ian Boyd
And for checking the validity of lpfnOldProc, it should be set to NULL when it is no longer needed/available. So your check becomes if (lpfnOldProc != NULL) {...}
Ian Boyd
+1 - if the pointer goes bad, the problem lies elsewhere, someone unloading the DLL before the window is destroyed. (I did run into this situation before).
peterchen
@Ian boyd: That's not needed, if you look at the larger context. You'd only set `Hook::lpfnOldProc` to NULL when the original Window Proc is unloaded, which is after the last window of that type is destroyed. But at that point, since there are no more windows of that type, there's no longer a need to hook them either, and thus you can destroy the entire Hook object including `Hook::lpfnOldProc`
MSalters
A: 

Happened something similar in the pass, name two or more dll trying to override a window proc. Normally as part of the process shutdown, or a plugin unload, they try to restore the "oldWndProc", but since they are not aware of each other they may end up overriding a good pointer with an invalid pointer and then crash happens.

If you have access to the source code the best you can do is to have only one dll responsible for hooking a window proc, and then the rest can implement a kind of delegate, so when unloding it can be set to null, and the hooking dll can check and if it is null skip the call.

If you don't have access to the source code, perhaps because you are trying to make your dll work with an already very popular (and buggy) plugin, you may try to find a repeteable procedure so you can detect this case of corruption before it happens (check some of messages before your crash), and workaround it with a custom message notifying your wndproc.

Ismael