Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 25 additions & 2 deletions src/Files.App/Utils/Global/WindowsStorageDeviceWatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ private void Win32_OnDeviceRemoved(object? sender, DeviceEventArgs e)
private async void Win32_OnDeviceAdded(object? sender, DeviceEventArgs e)
{
var driveAdded = new DriveInfo(e.DeviceId);
if (!driveAdded.IsReady)
if (!driveAdded.IsReady && !IsUnauthorizedDrive(driveAdded))
Copy link
Copy Markdown
Member

@d2dyno1 d2dyno1 May 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be "or" condition (||).
If the drive is not ready, IsUnauthorizedDrive will still be called, causing an exception on an unready drive

Copy link
Copy Markdown
Contributor Author

@muko muko May 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IsUnauthorizedDrive() has all code paths wrapped in try-catch, so no exception will be thrown when IsReady == false.
In addition, with ||, a locked BitLocker drive (IsReady == false, IsUnauthorizedDrive() == true) and a normal drive (IsReady == true, IsUnauthorizedDrive() == false) would both incorrectly return early.

IsReady IsUnauthorizedDrive && (PR) || (suggested)
false false return return
false true continue return (WRONG)
true false continue return (WRONG)
true true continue continue

return;

var rootAdded = await FilesystemTasks.Wrap(() => StorageFolder.GetFolderFromPathAsync(e.DeviceId).AsTask());
Expand Down Expand Up @@ -101,7 +101,7 @@ private async void Watcher_Added(DeviceWatcher sender, DeviceInformation args)
{
// Check if this drive is associated with a drive letter
var driveAdded = new DriveInfo(root.Path);
if (!driveAdded.IsReady)
if (!driveAdded.IsReady && !IsUnauthorizedDrive(driveAdded))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

return;

type = DriveHelpers.GetDriveType(driveAdded);
Expand Down Expand Up @@ -139,5 +139,28 @@ public void Stop()
DeviceManager.Default.DeviceInserted -= Win32_OnDeviceEjectedOrInserted;
DeviceManager.Default.DeviceEjected -= Win32_OnDeviceEjectedOrInserted;
}

private bool IsUnauthorizedDrive(DriveInfo driveInfo)
{
try
{
_ = Directory.EnumerateFileSystemEntries(driveInfo.Name).FirstOrDefault();
return false;
}
catch (UnauthorizedAccessException)
{
// probably BitLocker locked drive.
return true;
}
catch (IOException ex) when (ex.HResult == unchecked((int)0x80310000)) // FVE_E_LOCKED_VOLUME
{
// BitLocker locked drive.
return true;
}
catch
{
return false;
}
}
}
}
Loading