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>
This commit is contained in:
amail80
2026-04-13 11:07:32 +05:00
committed by GitHub
parent adfc768813
commit 1ea0556cbe
2 changed files with 28 additions and 0 deletions

View File

@@ -9357,6 +9357,18 @@ retry:
BroadcastDeviceChange (DBT_DEVICEREMOVECOMPLETE, nDosDriveNo, 0);
/* GH #337, GH #1426: When running in silent/CLI mode, 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)
{
wchar_t root[] = { (wchar_t) (nDosDriveNo + L'A'), L':', L'\\', 0 };
SHChangeNotify (SHCNE_DRIVEREMOVED, SHCNF_PATH | SHCNF_FLUSH, root, NULL);
}
return TRUE;
}

View File

@@ -5763,6 +5763,22 @@ retry:
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)
{
DWORD removedDrives = prevMountList.ulMountedDrives & ~mountList.ulMountedDrives;
for (i = 0; i < 26; i++)
{
if (removedDrives & (1 << i))
{
wchar_t root[] = { (wchar_t) (i + L'A'), L':', L'\\', 0 };
SHChangeNotify (SHCNE_DRIVEREMOVED, SHCNF_PATH | SHCNF_FLUSH, root, NULL);
}
}
}
RefreshMainDlg (hwndDlg);
NormalCursor();