From: Fabian Maurer dark.shadow4@web.de
We need to make sure all (important) cleanup is finished when we exit DllMain, otherwise we might already unload krnl386 and deadlock Since we can't have a synchronous DestroyWindow, use an extra message
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52511 Signed-off-by: Fabian Maurer dark.shadow4@web.de --- dlls/imm32/imm.c | 21 ++++++++++++++------- dlls/user32/misc.c | 2 +- dlls/user32/user_main.c | 1 + dlls/user32/user_private.h | 2 ++ 4 files changed, 18 insertions(+), 8 deletions(-)
diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c index 780d544c0e9..3a334bc0de5 100644 --- a/dlls/imm32/imm.c +++ b/dlls/imm32/imm.c @@ -51,6 +51,7 @@ static UINT WM_MSIME_RECONVERTREQUEST; static UINT WM_MSIME_RECONVERT; static UINT WM_MSIME_QUERYPOSITION; static UINT WM_MSIME_DOCUMENTFEED; +static UINT WM_WINE_IME_DESTROY;
typedef struct _tagImmHkl{ struct list entry; @@ -554,7 +555,10 @@ static void IMM_FreeAllImmHkl(void) FreeLibrary(ptr->hIME); } if (ptr->UIWnd) + { + SendMessageA(ptr->UIWnd, WM_WINE_IME_DESTROY, 0, 0); DestroyWindow(ptr->UIWnd); + } HeapFree(GetProcessHeap(),0,ptr); } } @@ -3185,6 +3189,7 @@ static void init_messages(void) WM_MSIME_RECONVERT = RegisterWindowMessageW(L"MSIMEReconvert"); WM_MSIME_QUERYPOSITION = RegisterWindowMessageW(L"MSIMEQueryPosition"); WM_MSIME_DOCUMENTFEED = RegisterWindowMessageW(L"MSIMEDocumentFeed"); + WM_WINE_IME_DESTROY = RegisterWindowMessageW(L"__WINE_IME_DESTROY"); initialized = TRUE; }
@@ -3198,16 +3203,18 @@ LRESULT WINAPI __wine_ime_wnd_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lp init_messages(); return TRUE;
- case WM_DESTROY: + case WM_IME_INTERNAL: + return ime_internal_msg(wparam, lparam); + } + + if (msg == WM_WINE_IME_DESTROY) + { + HWND default_hwnd = ImmGetDefaultIMEWnd(0); + if (!default_hwnd || hwnd == default_hwnd) { - HWND default_hwnd = ImmGetDefaultIMEWnd(0); - if (!default_hwnd || hwnd == default_hwnd) - imm_couninit_thread(TRUE); + imm_couninit_thread(TRUE); } return TRUE; - - case WM_IME_INTERNAL: - return ime_internal_msg(wparam, lparam); }
if (is_ime_ui_msg(msg)) diff --git a/dlls/user32/misc.c b/dlls/user32/misc.c index 879e8b32a0f..3b822ec047f 100644 --- a/dlls/user32/misc.c +++ b/dlls/user32/misc.c @@ -38,7 +38,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(win); BOOL WINAPI ImmSetActiveContext(HWND, HIMC, BOOL);
#define IMM_INIT_MAGIC 0x19650412 -static LRESULT (WINAPI *imm_ime_wnd_proc)( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, BOOL ansi); +LRESULT (WINAPI *imm_ime_wnd_proc)( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, BOOL ansi);
/* USER signal proc flags and codes */ /* See UserSignalProc for comments */ diff --git a/dlls/user32/user_main.c b/dlls/user32/user_main.c index 0ddbd710b6b..4a429540541 100644 --- a/dlls/user32/user_main.c +++ b/dlls/user32/user_main.c @@ -276,6 +276,7 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved ) thread_detach(); break; case DLL_PROCESS_DETACH: + imm_ime_wnd_proc = 0; /* Make sure we don't call into imm32 anymore */ FreeLibrary(imm32_module); break; } diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index 430ac826f7e..e22d4fecc24 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -184,4 +184,6 @@ static inline void mirror_rect( const RECT *window_rect, RECT *rect ) rect->right = width - tmp; }
+extern LRESULT (WINAPI *imm_ime_wnd_proc)( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, BOOL ansi); + #endif /* __WINE_USER_PRIVATE_H */