From 634916230311eed9c6969aa516f4b9601438f9d3 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Sun, 14 Dec 2014 18:02:56 +0100 Subject: Windows: display a wait dialog during the lengthy opening of a volume. There is still a freeze in the GUI even though the call to DeviceIoControl is done in a separate thread which can't be explained. Maybe if we had an asynchronous Device Driver call, things would better. --- src/Common/Common.rc | 16 ++++++++++ src/Common/Dlgcode.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++-- src/Common/Resource.h | 3 +- 3 files changed, 101 insertions(+), 3 deletions(-) diff --git a/src/Common/Common.rc b/src/Common/Common.rc index 39f6f7a7..13b9f973 100644 --- a/src/Common/Common.rc +++ b/src/Common/Common.rc @@ -307,6 +307,14 @@ BEGIN LTEXT "Please wait. This process may take a long time...",IDT_STATIC_MODELESS_WAIT_DLG_INFO,9,8,274,9 END +IDD_STATIC_MODAL_WAIT_DLG DIALOGEX 0, 0, 292, 42 +STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION +CAPTION "VeraCrypt" +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + CTEXT "Please wait. This process may take a long time...",IDT_STATIC_MODELESS_WAIT_DLG_INFO,9,11,274,9 +END + ///////////////////////////////////////////////////////////////////////////// // @@ -439,6 +447,14 @@ BEGIN TOPMARGIN, 7 BOTTOMMARGIN, 35 END + + IDD_STATIC_MODAL_WAIT_DLG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 285 + TOPMARGIN, 7 + BOTTOMMARGIN, 35 + END END #endif // APSTUDIO_INVOKED diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c index 1a793517..bb84d377 100644 --- a/src/Common/Dlgcode.c +++ b/src/Common/Dlgcode.c @@ -6135,6 +6135,80 @@ void BroadcastDeviceChange (WPARAM message, int nDosDriveNo, DWORD driveMap) IgnoreWmDeviceChange = FALSE; } +/************************************************************/ +typedef struct +{ + HWND hwnd; + MOUNT_STRUCT* pmount; + BOOL* pbResult; + DWORD* pdwResult; +} MountThreadParam; + +static UINT g_wmMountWaitDlg = ::RegisterWindowMessage("VeraCryptMountWaitDlgMessage"); + +static DWORD WINAPI DeviceIoControlThread (void* pParam) +{ + MountThreadParam* pThreadParam = (MountThreadParam*) pParam; + + *(pThreadParam->pbResult) = DeviceIoControl (hDriver, TC_IOCTL_MOUNT_VOLUME, pThreadParam->pmount, + sizeof (MOUNT_STRUCT),pThreadParam->pmount, sizeof (MOUNT_STRUCT), pThreadParam->pdwResult, NULL); + + /* close the wait dialog */ + PostMessage (pThreadParam->hwnd, g_wmMountWaitDlg, 0, 0); + return 0; +} + +static BOOL CALLBACK MountWaitDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + WORD lw = LOWORD (wParam); + + switch (msg) + { + case WM_INITDIALOG: + { + MountThreadParam* thParam = (MountThreadParam*) lParam; + HANDLE hThread = NULL; + + thParam->hwnd = hwndDlg; + + // For now, we don't have system menu is the resources but we leave this code + // if it is enabled in the future + HMENU hSysMenu = GetSystemMenu(hwndDlg, FALSE); + if (hSysMenu) + { + //disable the X + EnableMenuItem(hSysMenu,SC_CLOSE, MF_BYCOMMAND|MF_GRAYED); + + // set icons + HICON hIcon = (HICON)::LoadImage(hInst, MAKEINTRESOURCE(IDI_TRUECRYPT_ICON), IMAGE_ICON, ::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON), LR_DEFAULTCOLOR); + ::SendMessage(hwndDlg, WM_SETICON, TRUE, (LPARAM)hIcon); + HICON hIconSmall = (HICON)::LoadImage(hInst, MAKEINTRESOURCE(IDI_TRUECRYPT_ICON), IMAGE_ICON, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR); + ::SendMessage(hwndDlg, WM_SETICON, FALSE, (LPARAM)hIconSmall); + } + + LocalizeDialog (hwndDlg, NULL); + hThread = CreateThread(NULL, 0, DeviceIoControlThread, (void*) thParam, 0, NULL); + SetWindowLongPtr(hwndDlg, GWL_USERDATA, (LONG_PTR) hThread); + return 0; + } + + case WM_COMMAND: + + if (lw == IDOK || lw == IDCANCEL) + return 1; + + default: + if (msg == g_wmMountWaitDlg) + { + HANDLE hThread = (HANDLE) GetWindowLongPtrA(hwndDlg, GWL_USERDATA); + CloseHandle(hThread); + EndDialog (hwndDlg, IDOK); + return 1; + } + return 0; + } +} + // Use only cached passwords if password = NULL // @@ -6278,8 +6352,15 @@ retry: mount.bPartitionInInactiveSysEncScope = TRUE; } - bResult = DeviceIoControl (hDriver, TC_IOCTL_MOUNT_VOLUME, &mount, - sizeof (mount), &mount, sizeof (mount), &dwResult, NULL); + MountThreadParam threadParam; + threadParam.hwnd = hwndDlg; + threadParam.pmount = &mount; + threadParam.pbResult = &bResult; + threadParam.pdwResult = &dwResult; + + DialogBoxParamW (hInst, + MAKEINTRESOURCEW (IDD_STATIC_MODAL_WAIT_DLG), hwndDlg, + (DLGPROC) MountWaitDlgProc, (LPARAM) &threadParam); burn (&mount.VolumePassword, sizeof (mount.VolumePassword)); burn (&mount.ProtectedHidVolPassword, sizeof (mount.ProtectedHidVolPassword)); diff --git a/src/Common/Resource.h b/src/Common/Resource.h index 3c6a09e8..eb2c5890 100644 --- a/src/Common/Resource.h +++ b/src/Common/Resource.h @@ -183,6 +183,7 @@ #define IDC_KEYFILES_SIZE 5121 #define IDC_KEYFILES_RANDOM_SIZE 5122 #define IDT_KEYFILES_SIZE 5123 +#define IDD_STATIC_MODAL_WAIT_DLG 5124 // Next default values for new objects // @@ -191,7 +192,7 @@ #define _APS_NO_MFC 1 #define _APS_NEXT_RESOURCE_VALUE 542 #define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 5124 +#define _APS_NEXT_CONTROL_VALUE 5125 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif -- cgit v1.2.3