From 590b203bb631c7cd5ba7a2dd693ab86625c8b5e9 Mon Sep 17 00:00:00 2001 From: Alan Collins Date: Fri, 28 Jan 2022 17:02:13 -0600 Subject: [PATCH] Adjusted the Windows LongPath support check for valid segment lengths Closes #1512 (cherry picked from commit 52c6bc5549ab998ccc018d138c55f8f924eed6d3) --- src/NzbDrone.Common/Disk/LongPathSupport.cs | 64 +++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/src/NzbDrone.Common/Disk/LongPathSupport.cs b/src/NzbDrone.Common/Disk/LongPathSupport.cs index 916123f8d..e001c96aa 100644 --- a/src/NzbDrone.Common/Disk/LongPathSupport.cs +++ b/src/NzbDrone.Common/Disk/LongPathSupport.cs @@ -1,15 +1,79 @@ using System; +using System.IO; +using NzbDrone.Common.EnvironmentInfo; namespace NzbDrone.Common.Disk { public static class LongPathSupport { + private static int MAX_PATH; + private static int MAX_NAME; + public static void Enable() { // Mono has an issue with enabling long path support via app.config. // This works for both mono and .net on Windows. AppContext.SetSwitch("Switch.System.IO.UseLegacyPathHandling", false); AppContext.SetSwitch("Switch.System.IO.BlockLongPaths", false); + + DetectLongPathLimits(); + } + + private static void DetectLongPathLimits() + { + if (!int.TryParse(Environment.GetEnvironmentVariable("MAX_PATH"), out MAX_PATH)) + { + if (OsInfo.IsLinux) + { + MAX_PATH = 4096; + } + else + { + try + { + // Windows paths can be up to 32,767 characters long, but each component of the path must be less than 255. + // If the OS does not have Long Path enabled, then the following will throw an exception + // ref: https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation + Path.GetDirectoryName($@"C:\{new string('a', 254)}\{new string('a', 254)}"); + MAX_PATH = 4096; + } + catch + { + MAX_PATH = 260 - 1; + } + } + } + + if (!int.TryParse(Environment.GetEnvironmentVariable("MAX_NAME"), out MAX_NAME)) + { + MAX_NAME = 255; + } + } + + public static int MaxFilePathLength + { + get + { + if (MAX_PATH == 0) + { + DetectLongPathLimits(); + } + + return MAX_PATH; + } + } + + public static int MaxFileNameLength + { + get + { + if (MAX_NAME == 0) + { + DetectLongPathLimits(); + } + + return MAX_NAME; + } } } }