diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c index ed03e5b4df..32421a17f6 100644 --- a/src/Common/Dlgcode.c +++ b/src/Common/Dlgcode.c @@ -162,6 +162,12 @@ HWND MainDlg = NULL; wchar_t *lpszTitle = NULL; BOOL Silent = FALSE; +/* TRUE when the process terminates as soon as the command line request has been + carried out (/q). Shell notifications must then be delivered synchronously, + otherwise the process is gone before Explorer processes them. Note that this + is independent of Silent: /q controls whether we exit, /s only suppresses the + user interface, and either may be given without the other. */ +BOOL ProcessExitsAfterCommand = FALSE; BOOL bPreserveTimestamp = TRUE; BOOL bShowDisconnectedNetworkDrives = FALSE; BOOL bHideWaitingDialog = FALSE; @@ -9789,13 +9795,16 @@ static BOOL UnmountVolumeBase (HWND hwndDlg, int nDosDriveNo, BOOL forceUnmount, BroadcastDeviceChange (DBT_DEVICEREMOVECOMPLETE, nDosDriveNo, 0); - /* GH #337, GH #1426: When running in silent/CLI mode, the process may + /* GH #337, GH #1426: When running from the command line, the process may exit immediately after unmount. BroadcastDeviceChange sends SHChangeNotify asynchronously, so Explorer may not process the drive removal before the process exits, leaving a ghost drive letter. Re-send the notification with SHCNF_FLUSH to force synchronous - processing by Explorer before we return. */ - if (Silent) + processing by Explorer before we return. + ProcessExitsAfterCommand covers /q, which is what actually makes the + process exit; testing Silent alone missed "VeraCrypt /d X: /q" because + /q does not imply /s. */ + if (Silent || ProcessExitsAfterCommand) { wchar_t root[] = { (wchar_t) (nDosDriveNo + L'A'), L':', L'\\', 0 }; SHChangeNotify (SHCNE_DRIVEREMOVED, SHCNF_PATH | SHCNF_FLUSH, root, NULL); diff --git a/src/Common/Dlgcode.h b/src/Common/Dlgcode.h index 6ebb6c538c..30f0c7cb0a 100644 --- a/src/Common/Dlgcode.h +++ b/src/Common/Dlgcode.h @@ -133,6 +133,7 @@ extern int ScreenDPI; extern double DlgAspectRatio; extern HWND MainDlg; extern BOOL Silent; +extern BOOL ProcessExitsAfterCommand; extern BOOL bHistory; extern BOOL bPreserveTimestamp; extern BOOL bShowDisconnectedNetworkDrives; diff --git a/src/Mount/Mount.c b/src/Mount/Mount.c index 8d72805d73..0f8c8c0721 100644 --- a/src/Mount/Mount.c +++ b/src/Mount/Mount.c @@ -6316,10 +6316,12 @@ static BOOL DismountAll (HWND hwndDlg, BOOL forceUnmount, BOOL interact, int dis BroadcastDeviceChange (DBT_DEVICEREMOVECOMPLETE, 0, prevMountList.ulMountedDrives & ~mountList.ulMountedDrives); - /* GH #337, GH #1426: Flush shell notifications synchronously in - silent/CLI mode to prevent ghost drive letters when the process - exits immediately after dismount. */ - if (Silent) + /* GH #337, GH #1426: Flush shell notifications synchronously when running + from the command line, to prevent ghost drive letters when the process + exits immediately after dismount. ProcessExitsAfterCommand covers /q, + which is what actually makes the process exit; testing Silent alone + missed "VeraCrypt /d /q" because /q does not imply /s. */ + if (Silent || ProcessExitsAfterCommand) { DWORD removedDrives = prevMountList.ulMountedDrives & ~mountList.ulMountedDrives; for (i = 0; i < 26; i++) @@ -10577,6 +10579,7 @@ void ExtractCommandLine (HWND hwndDlg, wchar_t *lpszCommandLine) else if (!_wcsicmp (szTmp, L"preferences")) { Quit = TRUE; + ProcessExitsAfterCommand = TRUE; UsePreferences = TRUE; break; } @@ -10589,6 +10592,7 @@ void ExtractCommandLine (HWND hwndDlg, wchar_t *lpszCommandLine) } Quit = TRUE; + ProcessExitsAfterCommand = TRUE; UsePreferences = FALSE; } break;