From ec7b5cd7e63bf78fa98c9b9713846b99b835dd71 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Wed, 9 Sep 2015 15:53:18 +0200 Subject: Windows: Implement waiting dialog for Dismount operations to avoid freezing GUI when dismounting takes long time. --- src/Mount/Mount.c | 133 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 93 insertions(+), 40 deletions(-) (limited to 'src/Mount/Mount.c') diff --git a/src/Mount/Mount.c b/src/Mount/Mount.c index 0d8cace2..5c28bf93 100644 --- a/src/Mount/Mount.c +++ b/src/Mount/Mount.c @@ -4584,6 +4584,81 @@ void __cdecl mountThreadFunction (void *hwndDlgArg) 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) { BOOL status = TRUE; @@ -4593,6 +4668,7 @@ static BOOL DismountAll (HWND hwndDlg, BOOL forceUnmount, BOOL interact, int dis BOOL bResult; MOUNT_LIST_STRUCT prevMountList = {0}; int i; + DismountAllThreadParam dismountAllThreadParam; retry: WaitCursor(); @@ -4620,51 +4696,28 @@ retry: unmount.nDosDriveNo = 0; unmount.ignoreOpenFiles = forceUnmount; + + 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; - do + 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 - || (unmount.ignoreOpenFiles != TRUE && unmount.ignoreOpenFiles != FALSE) - || (unmount.HiddenVolumeProtectionTriggered != TRUE && unmount.HiddenVolumeProtectionTriggered != FALSE) - || (unmount.nReturnCode < 0) - ) - { - if (bResult) - SetLastError (ERROR_INTERNAL_ERROR); - 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; - } + ShowWaitDialog (hwndDlg, TRUE, DismountAllThreadProc, &dismountAllThreadParam); + } + else + DismountAllThreadProc (&dismountAllThreadParam, hwndDlg); - if (unmount.nReturnCode == ERR_FILES_OPEN) - Sleep (dismountAutoRetryDelay); - else - break; + SetLastError (dismountAllThreadParam.dwLastError); - } while (--dismountMaxRetries > 0); + if (!dismountAllThreadParam.bReturn) + return FALSE; memset (&mountList, 0, sizeof (mountList)); DeviceIoControl (hDriver, TC_IOCTL_GET_MOUNTED_VOLUMES, &mountList, sizeof (mountList), &mountList, sizeof (mountList), &dwResult, NULL); -- cgit v1.2.3