mIRC Homepage

DLL Unloading, Subclassing, and WM_CLOSE Bug

Posted By: NaquadaServ

DLL Unloading, Subclassing, and WM_CLOSE Bug - 22/03/06 04:00 AM

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...
Posted By: Khaled

Re: DLL Unloading, Subclassing, and WM_CLOSE Bug - 22/03/06 11:58 AM

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?
Posted By: Sat

Re: DLL Unloading, Subclassing, and WM_CLOSE Bug - 22/03/06 12:19 PM

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?
Posted By: Khaled

Re: DLL Unloading, Subclassing, and WM_CLOSE Bug - 22/03/06 01:31 PM

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.
Posted By: NaquadaServ

Re: DLL Unloading, Subclassing, and WM_CLOSE Bug - 22/03/06 02:32 PM

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
© 2020 mIRC Discussion Forums