DLL中的子类化窗口导致DLL卸载时崩溃

时间:2017-02-11 13:10:43

标签: c++ winapi dll subclassing

我有一个在程序工作期间动态加载的DLL(特别是:mIRC的DLL插件)。加载DLL后,我将程序的窗口和编辑框子类化,以捕获一些消息:

LRESULT CALLBACK ChatWndProc(HWND hWnd, UINT uMsg, WPARAM wParam,
    LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) {
    return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}


LRESULT CALLBACK EditBoxProc(HWND hWnd, UINT uMsg, WPARAM wParam,
    LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) {
    return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}

...

//wndMirc and channelEditBox acquired elsewhere
SetWindowSubclass(channelEditBox, EditBoxProc, EditBoxProcId, nullptr);
SetWindowSubclass(wndMirc, ChatWndProc, ChannelWndProcId, nullptr);

在DLL卸载时,我删除了子类:

RemoveWindowSubclass(wndMirc, ChatWndProc, ChannelWndProcId);
RemoveWindowSubclass(channelEditBox, EditBoxProc, EditBoxProcId);

之后,程序完全崩溃,除了调试器Exception thrown at 0x0FAA3559 in mIRC.exe: 0xC0000005: Access violation executing location 0x0FAA3559.

之外只有异常可见

但是,如果我没有继承窗口,只有编辑框,一切都很好(除了我不能截取窗口的消息)。在这两种情况下GetLastError都没有表明任何问题。

我已经读过你的程序并不拥有的子类化窗口并不是一个好主意,但是有了钩子我会得到更多更丑陋的代码+我无法拦截某些消息(比如编辑框中的WM_KEYDOWN)。任何帮助表示赞赏。

编辑:澄清事情,卸载分两个阶段进行:首先从mIRC内部int __stdcall UnloadDll(int isTimeout)调用,我删除子类;然后使用BOOL APIENTRY DllMain(HMODULE hDllHandle, DWORD dwReason, LPVOID lpReserved)调用dwReason==DLL_PROCESS_DETACH - 在第二阶段之后,程序崩溃。

编辑2:崩溃现场的堆栈跟踪:

0f7e3559()  Unknown
[Frames below may be incorrect and/or missing]  
comctl32.dll!71f1f5ee() Unknown
user32.dll!752871be()   Unknown
user32.dll!75286238()   Unknown
user32.dll!752868ea()   Unknown
user32.dll!752878b0()   Unknown
user32.dll!75287d31()   Unknown
user32.dll!75287dfa()   Unknown
mIRC.exe!01107f9f() Unknown
mIRC.exe!0110e0e9() Unknown
mIRC.exe!011eec7c() Unknown
kernel32.dll!759d33aa() Unknown
ntdll.dll!77049f72()    Unknown
ntdll.dll!77049f45()    Unknown

0 个答案:

没有答案