https://bugs.winehq.org/show_bug.cgi?id=39148
Piotr Caban piotr.caban@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |piotr.caban@gmail.com
--- Comment #8 from Piotr Caban piotr.caban@gmail.com --- The error in Dragon Age demo is caused by DestroyWindow call in imm32.dll when winex11.drv has already received THREAD_DETACH. One solution is to avoid DestroyWindow calls in imm32 DETACH_THREAD but there still may be an application that will not work.
It's possible to write following program to demonstrate the problem when only user32.dll is used. It will look like this: test.exe source: int main() { LoadLibrary(L"user32.dll"); HMODULE test = LoadLibrary(L"test_dll.dll"); HANDLE thread = CreateThread(0, 0, thread_proc, 0, 0, 0); WaitForSingleObject(thread, INFINITE); return 0; }
test_dll.dll source: BOOL DllMain(HMODULE module, DWORD reason, void *res) { switch (ul_reason_for_call) { case DLL_THREAD_ATTACH: user = LoadLibraryA("user32.dll"); pCreateWindowExA = GetProcAddress(user, "CreateWindowExA"); pDestroyWindow = GetProcAddress(user, "DestroyWindow");
win = pCreateWindowExA(0, "button", "button", WS_VISIBLE|WS_POPUP, 10, 10, 100, 100, 0, 0, 0, 0); break; case DLL_THREAD_DETACH: pDestroyWindow(win); FreeLibrary(user); break; case DLL_PROCESS_DETACH: break; } return TRUE; } In this case winex11drv.dll is unloaded first, test_dll next and then user32. I don't know yet how to fix it, maybe it will be acceptable to add a driver_detach driver call and instead of cleaning everything in winex11drv.dll->DllMain(THREAD_DETACH) doing it in user32.dll->DllMain(THREAD_DETACH)->driver_detach?