From: Fabian Maurer <dark.shadow4(a)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(a)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 */ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/1456