mIRC Home    About    Download    Register    News    Help

Print Thread
Joined: Dec 2002
Posts: 580
N
Fjord artisan
OP Offline
Fjord artisan
N
Joined: Dec 2002
Posts: 580
Ok, I'm going to venture out and say this is a fixable bug with mIRC. It's been bugging me for years now. I finally understand the problem well enough to document it and a solution. I started to document the problem here -> Problem Description

Solution: WM_CLOSE must not unload DLL's. WM_CLOSE needs to return, so that if the mIRC app window is subclassed, it can be removed from the WNDPROC chain properly. mIRCProc for WM_CLOSE should only post it's WM_DESTROY. Then on WM_DESTROY, unload the DLL and send all children WM_DESTROY/WM_MDIDESTROY, etc...


NaquadaBomb
www.mirc-dll.com
Joined: Dec 2002
Posts: 5,411
Hoopy frood
Offline
Hoopy frood
Joined: Dec 2002
Posts: 5,411
I've read your previous posts on the issue and did take a look at my code to see if this is possible, unfortunately it's not that simple...

Many routines are called to cleanup/save settings/etc. when mIRC exits; going through all of them to make sure that they work in the WM_DESTROY event will take quite a bit of work after years of designing everything so that it works properly in the WM_CLOSE event. I can't simply assume that they will all work unfortunately... one issue that comes to mind is that the main mIRC window is hidden by WM_DESTROY before mIRC receives it, resulting in mIRC being unable to save mIRC's display state.

Since mIRC closes DLLs in a specific order during cleanup to enable the DLLs access to mIRC's current state, I can't simply move just the closing of DLLs to WM_DESTROY.

Is there no way for your DLL to safely remove the WNDPROC when mIRC calls the UnloadDLL routine?

Joined: Apr 2004
Posts: 871
Sat Offline
Hoopy frood
Offline
Hoopy frood
Joined: Apr 2004
Posts: 871
Quote:
Is there no way for your DLL to safely remove the WNDPROC when mIRC calls the UnloadDLL routine?


No, because UnloadDll will be called from the WM_CLOSE message handler function that is in turn called from the WNDPROC; therefore a subclass-wndproc from a DLL will still be on the call stack after the DLL is unloaded.

DLLs cannot take proper countermeasures against this (such as the LoadLibrary-on-itself trick or VirtualAlloc'ing a special zone to put the subclass-wndproc on) because there's no way of telling whether the UnloadDll function was called in response to mIRC exiting or the user doing /dll -u. In the latter case, the DLL would not want to leave anything behind.

To me, it seems like the easiest solution is for mIRC to not actually FreeLibrary() the DLLs from WM_CLOSE, but instead either wait with this until after the main message loop is exited, or even just let Windows do it automatically when mIRC itself actually terminates. Thoughts?


Saturn, QuakeNet staff
Joined: Dec 2002
Posts: 5,411
Hoopy frood
Offline
Hoopy frood
Joined: Dec 2002
Posts: 5,411
If delaying the FreeLibrary() is all it will take, I'll implement that. However mIRC will still call the UnloadDll() during the WM_CLOSE event.

Joined: Dec 2002
Posts: 580
N
Fjord artisan
OP Offline
Fjord artisan
N
Joined: Dec 2002
Posts: 580
Quote:
If delaying the FreeLibrary() is all it will take, I'll implement that. However mIRC will still call the UnloadDll() during the WM_CLOSE event.


That probably will work. I'm not 100% sure, but I believe that will fix the problem.

Thanks! smile


NaquadaBomb
www.mirc-dll.com

Link Copied to Clipboard