From fd693b3a0c324a38fc25d24f03e5c86008574b09 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Tue, 20 Mar 2018 00:15:15 +0100 Subject: Windows: Fix some cases of external applications freezing during mount/dismount by using an internal window as parent to the waiting dialog instead of the desktop window. --- src/Common/Dlgcode.c | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) (limited to 'src/Common') diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c index eed087aa..56938518 100644 --- a/src/Common/Dlgcode.c +++ b/src/Common/Dlgcode.c @@ -7616,9 +7616,14 @@ void BringToForeground(HWND hWnd) #endif } +static LRESULT CALLBACK ShowWaitDialogParentWndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + return DefWindowProcW (hWnd, message, wParam, lParam); +} + + void ShowWaitDialog(HWND hwnd, BOOL bUseHwndAsParent, WaitThreadProc callback, void* pArg) { - HWND hParent = (hwnd && bUseHwndAsParent)? hwnd : GetDesktopWindow(); BOOL bEffectiveHideWaitingDialog = bCmdHideWaitingDialogValid? bCmdHideWaitingDialog : bHideWaitingDialog; WaitThreadParam threadParam; threadParam.callback = callback; @@ -7632,9 +7637,12 @@ void ShowWaitDialog(HWND hwnd, BOOL bUseHwndAsParent, WaitThreadProc callback, v } else { + const wchar_t *className = L"VeraCryptShowWaitDialogParent"; BOOL bIsForeground = FALSE; HWND creatorWnd = hwnd? hwnd : MainDlg; WaitDialogDisplaying = TRUE; + HWND hParent = NULL; + if (creatorWnd) { if (GetForegroundWindow () == creatorWnd) @@ -7642,6 +7650,28 @@ void ShowWaitDialog(HWND hwnd, BOOL bUseHwndAsParent, WaitThreadProc callback, v EnableWindow (creatorWnd, FALSE); } + if (hwnd && bUseHwndAsParent) + hParent = hwnd; + else + { + /* create invisible window and use it as parent */ + WNDCLASSEXW winClass; + + memset (&winClass, 0, sizeof (winClass)); + winClass.cbSize = sizeof (WNDCLASSEX); + winClass.lpfnWndProc = (WNDPROC) ShowWaitDialogParentWndProc; + winClass.hInstance = hInst; + winClass.lpszClassName = className; + RegisterClassExW (&winClass); + + hParent = CreateWindowExW (WS_EX_TOOLWINDOW | WS_EX_LAYERED, className, L"VeraCrypt ShowWaitDialog Parent", 0, 0, 0, 1, 1, NULL, NULL, hInst, NULL); + if (hParent) + { + SetLayeredWindowAttributes (hParent, 0, 1, LWA_ALPHA); + ShowWindow (hParent, SW_SHOWNORMAL); + } + } + finally_do_arg2 (HWND, creatorWnd, BOOL, bIsForeground, { if (finally_arg) { EnableWindow(finally_arg, TRUE); if (finally_arg2) BringToForeground (finally_arg);}}); DialogBoxParamW (hInst, @@ -7649,6 +7679,13 @@ void ShowWaitDialog(HWND hwnd, BOOL bUseHwndAsParent, WaitThreadProc callback, v (DLGPROC) WaitDlgProc, (LPARAM) &threadParam); WaitDialogDisplaying = FALSE; + + if (!(hwnd && bUseHwndAsParent)) + { + if (hParent) + DestroyWindow (hParent); + UnregisterClassW (className, hInst); + } } } -- cgit v1.2.3