Skip to content

Commit 1ea0556

Browse files
amail80Contributor
andauthored
Fix ghost drive letter after CLI dismount (GH #337, GH #1426) (#1658)
When dismounting via CLI (/d /q /s), SHChangeNotify is called without SHCNF_FLUSH flag, making it asynchronous. The process exits before Explorer processes the notification, leaving a phantom drive letter visible in Explorer as an inaccessible Local Disk until reboot. Add SHCNF_FLUSH in Silent (CLI) mode to force synchronous shell notification processing in both single-volume (UnmountVolumeBase) and dismount-all (DismountAll) code paths. The flush is only added in CLI mode to avoid adding latency to interactive GUI operations. Co-authored-by: Contributor <contributor@example.com>
1 parent adfc768 commit 1ea0556

2 files changed

Lines changed: 28 additions & 0 deletions

File tree

src/Common/Dlgcode.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9357,6 +9357,18 @@ static BOOL UnmountVolumeBase (HWND hwndDlg, int nDosDriveNo, BOOL forceUnmount,
93579357

93589358
BroadcastDeviceChange (DBT_DEVICEREMOVECOMPLETE, nDosDriveNo, 0);
93599359

9360+
/* GH #337, GH #1426: When running in silent/CLI mode, the process may
9361+
exit immediately after unmount. BroadcastDeviceChange sends
9362+
SHChangeNotify asynchronously, so Explorer may not process the drive
9363+
removal before the process exits, leaving a ghost drive letter.
9364+
Re-send the notification with SHCNF_FLUSH to force synchronous
9365+
processing by Explorer before we return. */
9366+
if (Silent)
9367+
{
9368+
wchar_t root[] = { (wchar_t) (nDosDriveNo + L'A'), L':', L'\\', 0 };
9369+
SHChangeNotify (SHCNE_DRIVEREMOVED, SHCNF_PATH | SHCNF_FLUSH, root, NULL);
9370+
}
9371+
93609372
return TRUE;
93619373
}
93629374

src/Mount/Mount.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5763,6 +5763,22 @@ static BOOL DismountAll (HWND hwndDlg, BOOL forceUnmount, BOOL interact, int dis
57635763

57645764
BroadcastDeviceChange (DBT_DEVICEREMOVECOMPLETE, 0, prevMountList.ulMountedDrives & ~mountList.ulMountedDrives);
57655765

5766+
/* GH #337, GH #1426: Flush shell notifications synchronously in
5767+
silent/CLI mode to prevent ghost drive letters when the process
5768+
exits immediately after dismount. */
5769+
if (Silent)
5770+
{
5771+
DWORD removedDrives = prevMountList.ulMountedDrives & ~mountList.ulMountedDrives;
5772+
for (i = 0; i < 26; i++)
5773+
{
5774+
if (removedDrives & (1 << i))
5775+
{
5776+
wchar_t root[] = { (wchar_t) (i + L'A'), L':', L'\\', 0 };
5777+
SHChangeNotify (SHCNE_DRIVEREMOVED, SHCNF_PATH | SHCNF_FLUSH, root, NULL);
5778+
}
5779+
}
5780+
}
5781+
57665782
RefreshMainDlg (hwndDlg);
57675783

57685784
NormalCursor();

0 commit comments

Comments
 (0)