From 258ba629a2dc1af61b2fade1e040830080ffcc57 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Fri, 26 Dec 2014 16:53:55 +0100 Subject: Windows: workaround freezing of waiting dialog but setting its parent to the desktop and making all mount calls in a separate thread. DeviceIoControl is making our like hard because it doesn't behave as a normal system call and it blocks our window message loop even when called from a separate thread. --- src/Common/Common.rc | 3 ++- src/Common/Dlgcode.c | 4 ++-- src/Mount/Mount.c | 59 +++++++++++++++++++++++++++++++++++++++++++++------- src/Mount/Mount.h | 9 ++++++++ 4 files changed, 65 insertions(+), 10 deletions(-) diff --git a/src/Common/Common.rc b/src/Common/Common.rc index 4f4dfb32..fcb7aaab 100644 --- a/src/Common/Common.rc +++ b/src/Common/Common.rc @@ -310,7 +310,8 @@ BEGIN END IDD_STATIC_MODAL_WAIT_DLG DIALOGEX 0, 0, 292, 61 -STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION +STYLE DS_SYSMODAL | DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION +EXSTYLE WS_EX_TOPMOST CAPTION "VeraCrypt" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c index f7d86cfb..844cda9b 100644 --- a/src/Common/Dlgcode.c +++ b/src/Common/Dlgcode.c @@ -6369,9 +6369,9 @@ retry: threadParam.pmount = &mount; threadParam.pbResult = &bResult; threadParam.pdwResult = &dwResult; - + DialogBoxParamW (hInst, - MAKEINTRESOURCEW (IDD_STATIC_MODAL_WAIT_DLG), hwndDlg, + MAKEINTRESOURCEW (IDD_STATIC_MODAL_WAIT_DLG), GetDesktopWindow(), (DLGPROC) MountWaitDlgProc, (LPARAM) &threadParam); } else diff --git a/src/Mount/Mount.c b/src/Mount/Mount.c index 969b43dc..263cce99 100644 --- a/src/Mount/Mount.c +++ b/src/Mount/Mount.c @@ -3707,6 +3707,16 @@ static BOOL Dismount (HWND hwndDlg, int nDosDriveNo) return status; } +void __cdecl mountThreadFunction (void *hwndDlgArg) +{ + HWND hwndDlg =(HWND) hwndDlgArg; + // Disable parent dialog during processing to avoid user interaction + EnableWindow(hwndDlg, FALSE); + finally_do_arg (HWND, hwndDlg, { EnableWindow(finally_arg, TRUE); }); + + Mount (hwndDlg, 0, 0); +} + static BOOL DismountAll (HWND hwndDlg, BOOL forceUnmount, BOOL interact, int dismountMaxRetries, int dismountAutoRetryDelay) { BOOL status = TRUE; @@ -5745,7 +5755,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa } if (CheckMountList (FALSE)) - Mount (hwndDlg, 0, 0); + _beginthread(mountThreadFunction, 0, hwndDlg); } return 1; } @@ -5872,7 +5882,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa bPrebootPasswordDlgMode = FALSE; if (CheckMountList (FALSE)) - Mount (hwndDlg, 0, 0); + _beginthread(mountThreadFunction, 0, hwndDlg); } break; @@ -6015,7 +6025,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa bPrebootPasswordDlgMode = TRUE; if (CheckMountList (FALSE)) - Mount (hwndDlg, 0, 0); + _beginthread(mountThreadFunction, 0, hwndDlg); bPrebootPasswordDlgMode = FALSE; } @@ -6627,7 +6637,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa if (lw == IDM_MOUNT_FAVORITE_VOLUMES) { - MountFavoriteVolumes(); + _beginthread(mountFavoriteVolumeThreadFunction, 0, NULL); return 1; } @@ -6680,7 +6690,15 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa NormalCursor(); } else - MountFavoriteVolumes (FALSE, FALSE, FALSE, FavoriteVolumes[favoriteIndex]); + { + mountFavoriteVolumeThreadParam* pParam = (mountFavoriteVolumeThreadParam*) calloc(1, sizeof(mountFavoriteVolumeThreadParam)); + pParam->systemFavorites = FALSE; + pParam->logOnMount = FALSE; + pParam->hotKeyMount = FALSE; + pParam->favoriteVolumeToMount = &FavoriteVolumes[favoriteIndex]; + + _beginthread(mountFavoriteVolumeThreadFunction, 0, pParam); + } } return 1; @@ -7501,6 +7519,26 @@ skipMount: return status; } +void __cdecl mountFavoriteVolumeThreadFunction (void *pArg) +{ + mountFavoriteVolumeThreadParam* pParam = (mountFavoriteVolumeThreadParam*) pArg; + // Disable main dialog during processing to avoid user interaction + EnableWindow(MainDlg, FALSE); + finally_do ({ EnableWindow(MainDlg, TRUE); }); + + if (pParam) + { + if (pParam->favoriteVolumeToMount) + MountFavoriteVolumes (pParam->systemFavorites, pParam->logOnMount, pParam->hotKeyMount, *(pParam->favoriteVolumeToMount)); + else + MountFavoriteVolumes (pParam->systemFavorites, pParam->logOnMount, pParam->hotKeyMount); + + free(pParam); + } + else + MountFavoriteVolumes (); +} + static void SaveDefaultKeyFilesParam (void) { @@ -7633,7 +7671,14 @@ static void HandleHotKey (HWND hwndDlg, WPARAM wParam) break; case HK_MOUNT_FAVORITE_VOLUMES: - MountFavoriteVolumes (FALSE, FALSE, TRUE); + { + mountFavoriteVolumeThreadParam* pParam = (mountFavoriteVolumeThreadParam*) calloc(1, sizeof(mountFavoriteVolumeThreadParam)); + pParam->systemFavorites = FALSE; + pParam->logOnMount = FALSE; + pParam->hotKeyMount = TRUE; + + _beginthread(mountFavoriteVolumeThreadFunction, 0, pParam); + } break; case HK_SHOW_HIDE_MAIN_WINDOW: @@ -8797,7 +8842,7 @@ void MountSelectedVolume (HWND hwndDlg, BOOL mountWithOptions) } if (CheckMountList (FALSE)) - Mount (hwndDlg, 0, 0); + _beginthread (mountThreadFunction, 0, hwndDlg); } else Warning ("SELECT_FREE_DRIVE"); diff --git a/src/Mount/Mount.h b/src/Mount/Mount.h index e982de81..9b320a8c 100644 --- a/src/Mount/Mount.h +++ b/src/Mount/Mount.h @@ -113,8 +113,17 @@ static BOOL HandleDriveListMouseWheelEvent (UINT uMsg, WPARAM wParam, LPARAM lPa #ifdef __cplusplus } +typedef struct +{ + BOOL systemFavorites; + BOOL logOnMount; + BOOL hotKeyMount; + VeraCrypt::FavoriteVolume* favoriteVolumeToMount; +} mountFavoriteVolumeThreadParam; + void SetDriverConfigurationFlag (uint32 flag, BOOL state); BOOL MountFavoriteVolumes (BOOL systemFavorites = FALSE, BOOL logOnMount = FALSE, BOOL hotKeyMount = FALSE, const VeraCrypt::FavoriteVolume &favoriteVolumeToMount = VeraCrypt::FavoriteVolume()); +void __cdecl mountFavoriteVolumeThreadFunction (void *pArg); BOOL GetExecutableImageInformation (const string &path, string &version, string &description, string &companyName, string &productName); #endif -- cgit v1.2.3