Skip to content

Commit de04285

Browse files
authored
Windows: flush shell notifications when dismounting with /q (#1852)
* Windows: flush shell notifications when dismounting with /q * Windows: limit the /q notification flush to the command line dismount ProcessExitsAfterCommand was set while parsing /q and stayed set when the process went on as the background task (/q background, and /q preferences, which is also used at logon). Later interactive dismounts, automatic dismounts through DismountAll and the hotkeys then flushed as well, which would also delay the cache wipe that the force dismount and wipe hotkeys issue after DismountAll. Set the flag only for the dismount requested on the command line and clear it right after, whatever Silent is. Rename it to FlushDriveRemovalNotifications, as /q doesn't necessarily end the process. Reword the comments: according to the documentation, SHCNF_FLUSH makes SHChangeNotify return once the notification has been delivered, which doesn't mean that Explorer has finished updating its display, and the cause of the reported ghost drive letters hasn't been established.
1 parent 7eab121 commit de04285

3 files changed

Lines changed: 20 additions & 11 deletions

File tree

‎src/Common/Dlgcode.c‎

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,10 @@ HWND MainDlg = NULL;
162162
wchar_t *lpszTitle = NULL;
163163

164164
BOOL Silent = FALSE;
165+
/* Set by Mount.c only while it carries out a dismount requested on the command line
166+
with /q. UnmountVolumeBase and DismountAll then send the drive removal notification
167+
again with SHCNF_FLUSH, as they do when Silent is set. */
168+
BOOL FlushDriveRemovalNotifications = FALSE;
165169
BOOL bPreserveTimestamp = TRUE;
166170
BOOL bShowDisconnectedNetworkDrives = FALSE;
167171
BOOL bHideWaitingDialog = FALSE;
@@ -9826,13 +9830,13 @@ static BOOL UnmountVolumeBase (HWND hwndDlg, int nDosDriveNo, BOOL forceUnmount,
98269830

98279831
BroadcastDeviceChange (DBT_DEVICEREMOVECOMPLETE, nDosDriveNo, 0);
98289832

9829-
/* GH #337, GH #1426: When running in silent/CLI mode, the process may
9830-
exit immediately after unmount. BroadcastDeviceChange sends
9831-
SHChangeNotify asynchronously, so Explorer may not process the drive
9832-
removal before the process exits, leaving a ghost drive letter.
9833-
Re-send the notification with SHCNF_FLUSH to force synchronous
9834-
processing by Explorer before we return. */
9835-
if (Silent && !DeviceChangeBroadcastDisabled)
9833+
/* GH #337, GH #1426: ghost drive letters were reported after dismounts
9834+
requested on the command line; their cause hasn't been established.
9835+
When Silent or FlushDriveRemovalNotifications is set, the notification
9836+
is sent again with SHCNF_FLUSH. According to the documentation,
9837+
SHChangeNotify then returns only once it has been delivered, which
9838+
doesn't mean that Explorer has finished updating its display. */
9839+
if ((Silent || FlushDriveRemovalNotifications) && !DeviceChangeBroadcastDisabled)
98369840
{
98379841
wchar_t root[] = { (wchar_t) (nDosDriveNo + L'A'), L':', L'\\', 0 };
98389842
SHChangeNotify (SHCNE_DRIVEREMOVED, SHCNF_PATH | SHCNF_FLUSH, root, NULL);

‎src/Common/Dlgcode.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ extern int ScreenDPI;
133133
extern double DlgAspectRatio;
134134
extern HWND MainDlg;
135135
extern BOOL Silent;
136+
extern BOOL FlushDriveRemovalNotifications;
136137
extern BOOL bHistory;
137138
extern BOOL bPreserveTimestamp;
138139
extern BOOL bShowDisconnectedNetworkDrives;

‎src/Mount/Mount.c‎

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6351,10 +6351,9 @@ static BOOL DismountAll (HWND hwndDlg, BOOL forceUnmount, BOOL interact, int dis
63516351
if (removedDrives)
63526352
BroadcastDeviceChange (DBT_DEVICEREMOVECOMPLETE, 0, removedDrives);
63536353

6354-
/* GH #337, GH #1426: Flush shell notifications synchronously in
6355-
silent/CLI mode to prevent ghost drive letters when the process
6356-
exits immediately after dismount. */
6357-
if (Silent && !DeviceChangeBroadcastDisabled)
6354+
/* GH #337, GH #1426: as in UnmountVolumeBase, send the notifications again
6355+
with SHCNF_FLUSH when Silent or FlushDriveRemovalNotifications is set. */
6356+
if ((Silent || FlushDriveRemovalNotifications) && !DeviceChangeBroadcastDisabled)
63586357
{
63596358
for (i = 0; i < 26; i++)
63606359
{
@@ -8446,6 +8445,10 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
84468445
}
84478446

84488447
// Dismount
8448+
/* With /q, flush the drive removal notifications of this dismount even
8449+
without /s (see UnmountVolumeBase). Only for this request: a process
8450+
that goes on as the background task doesn't flush later dismounts. */
8451+
FlushDriveRemovalNotifications = Quit;
84498452
if (cmdUnmountDrive >= 0)
84508453
{
84518454
MOUNT_LIST_STRUCT mountList;
@@ -8467,6 +8470,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
84678470
if (!DismountAll (hwndDlg, bForceUnmount, !Silent, UNMOUNT_MAX_AUTO_RETRIES, UNMOUNT_AUTO_RETRY_DELAY))
84688471
exitCode = 1;
84698472
}
8473+
FlushDriveRemovalNotifications = FALSE;
84708474

84718475
// TaskBar icon
84728476
if (bEnableBkgTask)

0 commit comments

Comments
 (0)