1
0
mirror of https://github.com/veracrypt/VeraCrypt.git synced 2025-11-11 11:08:02 -06:00

Windows: Implement waiting dialog for Dismount operations to avoid freezing GUI when dismounting takes long time.

This commit is contained in:
Mounir IDRASSI
2015-09-09 15:53:18 +02:00
parent c55e08b31e
commit ec7b5cd7e6
2 changed files with 141 additions and 50 deletions

View File

@@ -6370,7 +6370,7 @@ int DriverUnmountVolume (HWND hwndDlg, int nDosDriveNo, BOOL forced)
unmount.ignoreOpenFiles = forced; unmount.ignoreOpenFiles = forced;
bResult = DeviceIoControl (hDriver, TC_IOCTL_DISMOUNT_VOLUME, &unmount, bResult = DeviceIoControl (hDriver, TC_IOCTL_DISMOUNT_VOLUME, &unmount,
sizeof (unmount), &unmount, sizeof (unmount), &dwResult, NULL); sizeof (unmount), &unmount, sizeof (unmount), &dwResult, NULL);
if (bResult == FALSE) if (bResult == FALSE)
{ {
@@ -6384,7 +6384,8 @@ int DriverUnmountVolume (HWND hwndDlg, int nDosDriveNo, BOOL forced)
if (unmount.nReturnCode == ERR_SUCCESS if (unmount.nReturnCode == ERR_SUCCESS
&& unmount.HiddenVolumeProtectionTriggered && unmount.HiddenVolumeProtectionTriggered
&& !VolumeNotificationsList.bHidVolDamagePrevReported [nDosDriveNo]) && !VolumeNotificationsList.bHidVolDamagePrevReported [nDosDriveNo]
&& !Silent)
{ {
wchar_t msg[4096]; wchar_t msg[4096];
@@ -7017,26 +7018,63 @@ retry:
return 1; return 1;
} }
typedef struct
{
int nDosDriveNo;
BOOL forced;
int dismountMaxRetries;
DWORD retryDelay;
int* presult;
DWORD dwLastError;
} UnmountThreadParam;
void CALLBACK UnmountWaitThreadProc(void* pArg, HWND hwnd)
{
UnmountThreadParam* pThreadParam = (UnmountThreadParam*) pArg;
int dismountMaxRetries = pThreadParam->dismountMaxRetries;
DWORD retryDelay = pThreadParam->retryDelay;
do
{
*pThreadParam->presult = DriverUnmountVolume (hwnd, pThreadParam->nDosDriveNo, pThreadParam->forced);
if (*pThreadParam->presult == ERR_FILES_OPEN)
Sleep (retryDelay);
else
break;
} while (--dismountMaxRetries > 0);
pThreadParam->dwLastError = GetLastError ();
}
static BOOL UnmountVolumeBase (HWND hwndDlg, int nDosDriveNo, BOOL forceUnmount, BOOL ntfsFormatCase) static BOOL UnmountVolumeBase (HWND hwndDlg, int nDosDriveNo, BOOL forceUnmount, BOOL ntfsFormatCase)
{ {
int result; int result;
BOOL forced = forceUnmount; BOOL forced = forceUnmount;
int dismountMaxRetries = ntfsFormatCase? 5 : UNMOUNT_MAX_AUTO_RETRIES; int dismountMaxRetries = ntfsFormatCase? 5 : UNMOUNT_MAX_AUTO_RETRIES;
DWORD retryDelay = ntfsFormatCase? 2000: UNMOUNT_AUTO_RETRY_DELAY; DWORD retryDelay = ntfsFormatCase? 2000: UNMOUNT_AUTO_RETRY_DELAY;
UnmountThreadParam param;
retry: retry:
BroadcastDeviceChange (DBT_DEVICEREMOVEPENDING, nDosDriveNo, 0); BroadcastDeviceChange (DBT_DEVICEREMOVEPENDING, nDosDriveNo, 0);
do param.nDosDriveNo = nDosDriveNo;
param.forced = forced;
param.dismountMaxRetries = dismountMaxRetries;
param.retryDelay = retryDelay;
param.presult = &result;
if (Silent)
{ {
result = DriverUnmountVolume (hwndDlg, nDosDriveNo, forced); UnmountWaitThreadProc (&param, hwndDlg);
}
else
{
ShowWaitDialog (hwndDlg, TRUE, UnmountWaitThreadProc, &param);
}
if (result == ERR_FILES_OPEN) SetLastError (param.dwLastError);
Sleep (retryDelay);
else
break;
} while (--dismountMaxRetries > 0);
if (result != 0) if (result != 0)
{ {

View File

@@ -4584,6 +4584,81 @@ void __cdecl mountThreadFunction (void *hwndDlgArg)
Mount (hwndDlg, 0, 0, -1); Mount (hwndDlg, 0, 0, -1);
} }
typedef struct
{
UNMOUNT_STRUCT* punmount;
BOOL interact;
int dismountMaxRetries;
int dismountAutoRetryDelay;
BOOL* pbResult;
DWORD* pdwResult;
DWORD dwLastError;
BOOL bReturn;
} DismountAllThreadParam;
void CALLBACK DismountAllThreadProc(void* pArg, HWND hwndDlg)
{
DismountAllThreadParam* pThreadParam = (DismountAllThreadParam*) pArg;
UNMOUNT_STRUCT* punmount = pThreadParam->punmount;
BOOL* pbResult = pThreadParam->pbResult;
DWORD* pdwResult = pThreadParam->pdwResult;
int dismountMaxRetries = pThreadParam->dismountMaxRetries;
int dismountAutoRetryDelay = pThreadParam->dismountAutoRetryDelay;
do
{
*pbResult = DeviceIoControl (hDriver, TC_IOCTL_DISMOUNT_ALL_VOLUMES, punmount,
sizeof (UNMOUNT_STRUCT), punmount, sizeof (UNMOUNT_STRUCT), pdwResult, NULL);
if ( punmount->nDosDriveNo < 0 || punmount->nDosDriveNo > 25
|| (punmount->ignoreOpenFiles != TRUE && punmount->ignoreOpenFiles != FALSE)
|| (punmount->HiddenVolumeProtectionTriggered != TRUE && punmount->HiddenVolumeProtectionTriggered != FALSE)
|| (punmount->nReturnCode < 0)
)
{
if (*pbResult)
SetLastError (ERROR_INTERNAL_ERROR);
*pbResult = FALSE;
}
if (*pbResult == FALSE)
{
NormalCursor();
handleWin32Error (hwndDlg, SRC_POS);
pThreadParam->dwLastError = GetLastError ();
pThreadParam->bReturn = FALSE;
return;
}
if (punmount->nReturnCode == ERR_SUCCESS
&& punmount->HiddenVolumeProtectionTriggered
&& !VolumeNotificationsList.bHidVolDamagePrevReported [punmount->nDosDriveNo]
&& pThreadParam->interact
&& !Silent)
{
wchar_t msg[4096];
VolumeNotificationsList.bHidVolDamagePrevReported [punmount->nDosDriveNo] = TRUE;
StringCbPrintfW (msg, sizeof(msg), GetString ("DAMAGE_TO_HIDDEN_VOLUME_PREVENTED"), punmount->nDosDriveNo + 'A');
SetForegroundWindow (hwndDlg);
MessageBoxW (hwndDlg, msg, lpszTitle, MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST);
punmount->HiddenVolumeProtectionTriggered = FALSE;
continue;
}
if (punmount->nReturnCode == ERR_FILES_OPEN)
Sleep (dismountAutoRetryDelay);
else
break;
} while (--dismountMaxRetries > 0);
pThreadParam->dwLastError = GetLastError ();
pThreadParam->bReturn = TRUE;
}
static BOOL DismountAll (HWND hwndDlg, BOOL forceUnmount, BOOL interact, int dismountMaxRetries, int dismountAutoRetryDelay) static BOOL DismountAll (HWND hwndDlg, BOOL forceUnmount, BOOL interact, int dismountMaxRetries, int dismountAutoRetryDelay)
{ {
BOOL status = TRUE; BOOL status = TRUE;
@@ -4593,6 +4668,7 @@ static BOOL DismountAll (HWND hwndDlg, BOOL forceUnmount, BOOL interact, int dis
BOOL bResult; BOOL bResult;
MOUNT_LIST_STRUCT prevMountList = {0}; MOUNT_LIST_STRUCT prevMountList = {0};
int i; int i;
DismountAllThreadParam dismountAllThreadParam;
retry: retry:
WaitCursor(); WaitCursor();
@@ -4621,50 +4697,27 @@ retry:
unmount.nDosDriveNo = 0; unmount.nDosDriveNo = 0;
unmount.ignoreOpenFiles = forceUnmount; unmount.ignoreOpenFiles = forceUnmount;
do dismountAllThreadParam.punmount = &unmount;
dismountAllThreadParam.interact = interact;
dismountAllThreadParam.dismountMaxRetries = dismountMaxRetries;
dismountAllThreadParam.dismountAutoRetryDelay = dismountAutoRetryDelay;
dismountAllThreadParam.pbResult = &bResult;
dismountAllThreadParam.pdwResult = &dwResult;
dismountAllThreadParam.dwLastError = ERROR_SUCCESS;
dismountAllThreadParam.bReturn = TRUE;
if (interact && !Silent)
{ {
bResult = DeviceIoControl (hDriver, TC_IOCTL_DISMOUNT_ALL_VOLUMES, &unmount,
sizeof (unmount), &unmount, sizeof (unmount), &dwResult, NULL);
if ( unmount.nDosDriveNo < 0 || unmount.nDosDriveNo > 25 ShowWaitDialog (hwndDlg, TRUE, DismountAllThreadProc, &dismountAllThreadParam);
|| (unmount.ignoreOpenFiles != TRUE && unmount.ignoreOpenFiles != FALSE) }
|| (unmount.HiddenVolumeProtectionTriggered != TRUE && unmount.HiddenVolumeProtectionTriggered != FALSE) else
|| (unmount.nReturnCode < 0) DismountAllThreadProc (&dismountAllThreadParam, hwndDlg);
)
{
if (bResult)
SetLastError (ERROR_INTERNAL_ERROR);
bResult = FALSE;
}
if (bResult == FALSE) SetLastError (dismountAllThreadParam.dwLastError);
{
NormalCursor();
handleWin32Error (hwndDlg, SRC_POS);
return FALSE;
}
if (unmount.nReturnCode == ERR_SUCCESS if (!dismountAllThreadParam.bReturn)
&& unmount.HiddenVolumeProtectionTriggered return FALSE;
&& !VolumeNotificationsList.bHidVolDamagePrevReported [unmount.nDosDriveNo])
{
wchar_t msg[4096];
VolumeNotificationsList.bHidVolDamagePrevReported [unmount.nDosDriveNo] = TRUE;
StringCbPrintfW (msg, sizeof(msg), GetString ("DAMAGE_TO_HIDDEN_VOLUME_PREVENTED"), unmount.nDosDriveNo + 'A');
SetForegroundWindow (hwndDlg);
MessageBoxW (hwndDlg, msg, lpszTitle, MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST);
unmount.HiddenVolumeProtectionTriggered = FALSE;
continue;
}
if (unmount.nReturnCode == ERR_FILES_OPEN)
Sleep (dismountAutoRetryDelay);
else
break;
} while (--dismountMaxRetries > 0);
memset (&mountList, 0, sizeof (mountList)); memset (&mountList, 0, sizeof (mountList));
DeviceIoControl (hDriver, TC_IOCTL_GET_MOUNTED_VOLUMES, &mountList, sizeof (mountList), &mountList, sizeof (mountList), &dwResult, NULL); DeviceIoControl (hDriver, TC_IOCTL_GET_MOUNTED_VOLUMES, &mountList, sizeof (mountList), &mountList, sizeof (mountList), &dwResult, NULL);