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:
@@ -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 (¶m, hwndDlg);
|
||||||
|
}
|
||||||
if (result == ERR_FILES_OPEN)
|
|
||||||
Sleep (retryDelay);
|
|
||||||
else
|
else
|
||||||
break;
|
{
|
||||||
|
ShowWaitDialog (hwndDlg, TRUE, UnmountWaitThreadProc, ¶m);
|
||||||
|
}
|
||||||
|
|
||||||
} while (--dismountMaxRetries > 0);
|
SetLastError (param.dwLastError);
|
||||||
|
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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;
|
||||||
bResult = DeviceIoControl (hDriver, TC_IOCTL_DISMOUNT_ALL_VOLUMES, &unmount,
|
dismountAllThreadParam.dismountMaxRetries = dismountMaxRetries;
|
||||||
sizeof (unmount), &unmount, sizeof (unmount), &dwResult, NULL);
|
dismountAllThreadParam.dismountAutoRetryDelay = dismountAutoRetryDelay;
|
||||||
|
dismountAllThreadParam.pbResult = &bResult;
|
||||||
|
dismountAllThreadParam.pdwResult = &dwResult;
|
||||||
|
dismountAllThreadParam.dwLastError = ERROR_SUCCESS;
|
||||||
|
dismountAllThreadParam.bReturn = TRUE;
|
||||||
|
|
||||||
if ( unmount.nDosDriveNo < 0 || unmount.nDosDriveNo > 25
|
if (interact && !Silent)
|
||||||
|| (unmount.ignoreOpenFiles != TRUE && unmount.ignoreOpenFiles != FALSE)
|
|
||||||
|| (unmount.HiddenVolumeProtectionTriggered != TRUE && unmount.HiddenVolumeProtectionTriggered != FALSE)
|
|
||||||
|| (unmount.nReturnCode < 0)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if (bResult)
|
|
||||||
SetLastError (ERROR_INTERNAL_ERROR);
|
ShowWaitDialog (hwndDlg, TRUE, DismountAllThreadProc, &dismountAllThreadParam);
|
||||||
bResult = FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bResult == FALSE)
|
|
||||||
{
|
|
||||||
NormalCursor();
|
|
||||||
handleWin32Error (hwndDlg, SRC_POS);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unmount.nReturnCode == ERR_SUCCESS
|
|
||||||
&& unmount.HiddenVolumeProtectionTriggered
|
|
||||||
&& !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
|
else
|
||||||
break;
|
DismountAllThreadProc (&dismountAllThreadParam, hwndDlg);
|
||||||
|
|
||||||
} while (--dismountMaxRetries > 0);
|
SetLastError (dismountAllThreadParam.dwLastError);
|
||||||
|
|
||||||
|
if (!dismountAllThreadParam.bReturn)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
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);
|
||||||
|
|||||||
Reference in New Issue
Block a user