From eab4134434cf5f284c2c23db6b0d44503b633d07 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Thu, 16 Feb 2023 17:05:39 -0800 Subject: [PATCH] Fixed: USB drives mounted to folders are treated as different mounts Closes #3368 (cherry picked from commit 75378f7bde90b9d3d9b72404c25c017da2cd147c) --- src/NzbDrone.Common/Disk/DiskProviderBase.cs | 2 +- src/NzbDrone.Windows/Disk/DiskProvider.cs | 34 ++++++++++++++++++ src/NzbDrone.Windows/Disk/FolderMount.cs | 38 ++++++++++++++++++++ 3 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 src/NzbDrone.Windows/Disk/FolderMount.cs diff --git a/src/NzbDrone.Common/Disk/DiskProviderBase.cs b/src/NzbDrone.Common/Disk/DiskProviderBase.cs index 5e90d2294..10dc09060 100644 --- a/src/NzbDrone.Common/Disk/DiskProviderBase.cs +++ b/src/NzbDrone.Common/Disk/DiskProviderBase.cs @@ -360,7 +360,7 @@ namespace NzbDrone.Common.Disk } } - public string GetPathRoot(string path) + public virtual string GetPathRoot(string path) { Ensure.That(path, () => path).IsValidPath(); diff --git a/src/NzbDrone.Windows/Disk/DiskProvider.cs b/src/NzbDrone.Windows/Disk/DiskProvider.cs index f480eaf36..597c792ee 100644 --- a/src/NzbDrone.Windows/Disk/DiskProvider.cs +++ b/src/NzbDrone.Windows/Disk/DiskProvider.cs @@ -37,6 +37,22 @@ namespace NzbDrone.Windows.Disk { } + public override IMount GetMount(string path) + { + var reparsePoint = GetReparsePoint(path); + + return reparsePoint ?? base.GetMount(path); + } + + public override string GetPathRoot(string path) + { + Ensure.That(path, () => path).IsValidPath(); + + var reparsePoint = GetReparsePoint(path); + + return reparsePoint?.RootDirectory ?? base.GetPathRoot(path); + } + public override long? GetAvailableSpace(string path) { Ensure.That(path, () => path).IsValidPath(); @@ -182,5 +198,23 @@ namespace NzbDrone.Windows.Disk return false; } } + + private IMount GetReparsePoint(string path) + { + var di = new DirectoryInfo(path); + var isReparsePoint = di.Attributes.HasFlag(FileAttributes.ReparsePoint); + + while (!isReparsePoint && (di = di.Parent) != null) + { + isReparsePoint = di.Attributes.HasFlag(FileAttributes.ReparsePoint); + } + + if (isReparsePoint) + { + return new FolderMount(di); + } + + return null; + } } } diff --git a/src/NzbDrone.Windows/Disk/FolderMount.cs b/src/NzbDrone.Windows/Disk/FolderMount.cs new file mode 100644 index 000000000..65fbcf5de --- /dev/null +++ b/src/NzbDrone.Windows/Disk/FolderMount.cs @@ -0,0 +1,38 @@ +using System.IO; +using NzbDrone.Common.Disk; +using NzbDrone.Common.Extensions; + +namespace NzbDrone.Windows.Disk +{ + public class FolderMount : IMount + { + private readonly DirectoryInfo _directoryInfo; + + public FolderMount(DirectoryInfo directoryInfo) + { + _directoryInfo = directoryInfo; + } + + public long AvailableFreeSpace => 0; + + public string DriveFormat => "NTFS"; + + public DriveType DriveType => DriveType.Removable; + + public bool IsReady => true; + + public MountOptions MountOptions { get; private set; } + + public string Name => _directoryInfo.Name; + + public string RootDirectory => _directoryInfo.FullName; + + public long TotalFreeSpace => 0; + + public long TotalSize => 0; + + public string VolumeLabel => _directoryInfo.Name; + + public string VolumeName => Name; + } +}