Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/duplicati/duplicati.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwarwickmm <warwickmm@users.noreply.github.com>2021-11-13 04:52:02 +0300
committerGitHub <noreply@github.com>2021-11-13 04:52:02 +0300
commita4a02ff884d59a964a0a9d9cdc3945db0560c8e6 (patch)
tree427629286d7f796f507fb6c51e411ec7092e6ded
parentea98145f8b992ff53adf704ff2d399e7760fbb39 (diff)
parentc50223eafe6107ea87e34ee9f46e5bb19d36d78c (diff)
Merge pull request #4640 from dferreyra/prefix_rename
Use consistent names for Windows extended device path prefixes.
-rw-r--r--Duplicati/Library/Common/IO/SystemIOWindows.cs167
-rw-r--r--Duplicati/Library/Snapshots/NoSnapshotWindows.cs14
-rw-r--r--Duplicati/Library/Snapshots/WindowsSnapshot.cs24
-rw-r--r--Duplicati/UnitTest/IOTests.cs16
4 files changed, 119 insertions, 102 deletions
diff --git a/Duplicati/Library/Common/IO/SystemIOWindows.cs b/Duplicati/Library/Common/IO/SystemIOWindows.cs
index 52f316576..adf797d2a 100644
--- a/Duplicati/Library/Common/IO/SystemIOWindows.cs
+++ b/Duplicati/Library/Common/IO/SystemIOWindows.cs
@@ -29,20 +29,24 @@ namespace Duplicati.Library.Common.IO
{
public struct SystemIOWindows : ISystemIO
{
- private const string UNCPREFIX = PathInternalWindows.ExtendedDevicePathPrefix;
- private const string UNCPREFIX_SERVER = PathInternalWindows.UncExtendedPathPrefix;
- private const string PATHPREFIX_SERVER = PathInternalWindows.UncPathPrefix;
- private const string PATHPREFIX_SERVER_ALT = @"//";
+ // Based on the constant names used in
+ // https://github.com/dotnet/runtime/blob/v5.0.12/src/libraries/Common/src/System/IO/PathInternal.Windows.cs
+ private const string ExtendedDevicePathPrefix = @"\\?\";
+ private const string UncPathPrefix = @"\\";
+ private const string AltUncPathPrefix = @"//";
+ private const string UncExtendedPathPrefix = @"\\?\UNC\";
+
private static readonly string DIRSEP = Util.DirectorySeparatorString;
/// <summary>
- /// Prefix path with one of the UNC prefixes, but only if it's a fully
- /// qualified path with no relative components (i.e., with no "." or
- /// ".." as part of the path).
+ /// Prefix path with one of the extended device path prefixes
+ /// (@"\\?\" or @"\\?\UNC\") but only if it's a fully qualified
+ /// path with no relative components (i.e., with no "." or ".."
+ /// as part of the path).
/// </summary>
- public static string PrefixWithUNC(string path)
+ public static string AddExtendedDevicePathPrefix(string path)
{
- if (IsPrefixedWithUNC(path))
+ if (IsPrefixedWithExtendedDevicePathPrefix(path))
{
// For example: \\?\C:\Temp\foo.txt or \\?\UNC\example.com\share\foo.txt
return path;
@@ -50,36 +54,44 @@ namespace Duplicati.Library.Common.IO
else
{
var hasRelativePathComponents = HasRelativePathComponents(path);
- if (IsPrefixedWithBasicUNC(path) && !hasRelativePathComponents)
+ if (IsPrefixedWithUncPathPrefix(path) && !hasRelativePathComponents)
{
// For example: \\example.com\share\foo.txt or //example.com/share/foo.txt
- return UNCPREFIX_SERVER + ConvertSlashes(path.Substring(PATHPREFIX_SERVER.Length));
+ return UncExtendedPathPrefix + ConvertSlashes(path.Substring(UncPathPrefix.Length));
}
else if (DotNetRuntimePathWindows.IsPathFullyQualified(path) && !hasRelativePathComponents)
{
// For example: C:\Temp\foo.txt or C:/Temp/foo.txt
- return UNCPREFIX + ConvertSlashes(path);
+ return ExtendedDevicePathPrefix + ConvertSlashes(path);
}
else
{
// A relative path or a fully qualified path with relative
- // path components so the UNC prefix cannot be applied.
+ // path components so the extended device path prefixes
+ // cannot be applied.
+ //
// For example: foo.txt or C:\Temp\..\foo.txt
return path;
}
}
}
-
- private static bool IsPrefixedWithBasicUNC(string path)
+
+ /// <summary>
+ /// Returns true if prefixed with @"\\" or @"//".
+ /// </summary>
+ private static bool IsPrefixedWithUncPathPrefix(string path)
{
- return path.StartsWith(PATHPREFIX_SERVER, StringComparison.Ordinal) ||
- path.StartsWith(PATHPREFIX_SERVER_ALT, StringComparison.Ordinal);
+ return path.StartsWith(UncPathPrefix, StringComparison.Ordinal) ||
+ path.StartsWith(AltUncPathPrefix, StringComparison.Ordinal);
}
- private static bool IsPrefixedWithUNC(string path)
+ /// <summary>
+ /// Returns true if prefixed with @"\\?\UNC\" or @"\\?\".
+ /// </summary>
+ private static bool IsPrefixedWithExtendedDevicePathPrefix(string path)
{
- return path.StartsWith(UNCPREFIX_SERVER, StringComparison.Ordinal) ||
- path.StartsWith(UNCPREFIX, StringComparison.Ordinal);
+ return path.StartsWith(UncExtendedPathPrefix, StringComparison.Ordinal) ||
+ path.StartsWith(ExtendedDevicePathPrefix, StringComparison.Ordinal);
}
private static string[] relativePathComponents = new[] { ".", ".." };
@@ -108,17 +120,22 @@ namespace Duplicati.Library.Common.IO
}
}
- public static string StripUNCPrefix(string path)
+ /// <summary>
+ /// Removes either of the extended device path prefixes
+ /// (@"\\?\" or @"\\?\UNC\") if <paramref name="path"/> is prefixed
+ /// with one of them.
+ /// </summary>
+ public static string RemoveExtendedDevicePathPrefix(string path)
{
- if (path.StartsWith(UNCPREFIX_SERVER, StringComparison.Ordinal))
+ if (path.StartsWith(UncExtendedPathPrefix, StringComparison.Ordinal))
{
// @"\\?\UNC\example.com\share\file.txt" to @"\\example.com\share\file.txt"
- return PATHPREFIX_SERVER + path.Substring(UNCPREFIX_SERVER.Length);
+ return UncPathPrefix + path.Substring(UncExtendedPathPrefix.Length);
}
- else if (path.StartsWith(UNCPREFIX, StringComparison.Ordinal))
+ else if (path.StartsWith(ExtendedDevicePathPrefix, StringComparison.Ordinal))
{
// @"\\?\C:\file.txt" to @"C:\file.txt"
- return path.Substring(UNCPREFIX.Length);
+ return path.Substring(ExtendedDevicePathPrefix.Length);
}
else
{
@@ -216,100 +233,100 @@ namespace Duplicati.Library.Common.IO
private System.Security.AccessControl.FileSystemSecurity GetAccessControlDir(string path)
{
- return System.IO.Directory.GetAccessControl(PrefixWithUNC(path));
+ return System.IO.Directory.GetAccessControl(AddExtendedDevicePathPrefix(path));
}
private System.Security.AccessControl.FileSystemSecurity GetAccessControlFile(string path)
{
- return System.IO.File.GetAccessControl(PrefixWithUNC(path));
+ return System.IO.File.GetAccessControl(AddExtendedDevicePathPrefix(path));
}
private void SetAccessControlFile(string path, FileSecurity rules)
{
- System.IO.File.SetAccessControl(PrefixWithUNC(path), rules);
+ System.IO.File.SetAccessControl(AddExtendedDevicePathPrefix(path), rules);
}
private void SetAccessControlDir(string path, DirectorySecurity rules)
{
- System.IO.Directory.SetAccessControl(PrefixWithUNC(path), rules);
+ System.IO.Directory.SetAccessControl(AddExtendedDevicePathPrefix(path), rules);
}
#region ISystemIO implementation
public void DirectoryCreate(string path)
{
- System.IO.Directory.CreateDirectory(PrefixWithUNC(path));
+ System.IO.Directory.CreateDirectory(AddExtendedDevicePathPrefix(path));
}
public void DirectoryDelete(string path, bool recursive)
{
- System.IO.Directory.Delete(PrefixWithUNC(path), recursive);
+ System.IO.Directory.Delete(AddExtendedDevicePathPrefix(path), recursive);
}
public bool DirectoryExists(string path)
{
- return System.IO.Directory.Exists(PrefixWithUNC(path));
+ return System.IO.Directory.Exists(AddExtendedDevicePathPrefix(path));
}
public void DirectoryMove(string sourceDirName, string destDirName)
{
- System.IO.Directory.Move(PrefixWithUNC(sourceDirName), PrefixWithUNC(destDirName));
+ System.IO.Directory.Move(AddExtendedDevicePathPrefix(sourceDirName), AddExtendedDevicePathPrefix(destDirName));
}
public void FileDelete(string path)
{
- System.IO.File.Delete(PrefixWithUNC(path));
+ System.IO.File.Delete(AddExtendedDevicePathPrefix(path));
}
public void FileSetLastWriteTimeUtc(string path, DateTime time)
{
- System.IO.File.SetLastWriteTimeUtc(PrefixWithUNC(path), time);
+ System.IO.File.SetLastWriteTimeUtc(AddExtendedDevicePathPrefix(path), time);
}
public void FileSetCreationTimeUtc(string path, DateTime time)
{
- System.IO.File.SetCreationTimeUtc(PrefixWithUNC(path), time);
+ System.IO.File.SetCreationTimeUtc(AddExtendedDevicePathPrefix(path), time);
}
public DateTime FileGetLastWriteTimeUtc(string path)
{
- return System.IO.File.GetLastWriteTimeUtc(PrefixWithUNC(path));
+ return System.IO.File.GetLastWriteTimeUtc(AddExtendedDevicePathPrefix(path));
}
public DateTime FileGetCreationTimeUtc(string path)
{
- return System.IO.File.GetCreationTimeUtc(PrefixWithUNC(path));
+ return System.IO.File.GetCreationTimeUtc(AddExtendedDevicePathPrefix(path));
}
public bool FileExists(string path)
{
- return System.IO.File.Exists(PrefixWithUNC(path));
+ return System.IO.File.Exists(AddExtendedDevicePathPrefix(path));
}
public System.IO.FileStream FileOpenRead(string path)
{
- return System.IO.File.Open(PrefixWithUNC(path), System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.ReadWrite);
+ return System.IO.File.Open(AddExtendedDevicePathPrefix(path), System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.ReadWrite);
}
public System.IO.FileStream FileOpenWrite(string path)
{
return !FileExists(path)
? FileCreate(path)
- : System.IO.File.OpenWrite(PrefixWithUNC(path));
+ : System.IO.File.OpenWrite(AddExtendedDevicePathPrefix(path));
}
public System.IO.FileStream FileCreate(string path)
{
- return System.IO.File.Create(PrefixWithUNC(path));
+ return System.IO.File.Create(AddExtendedDevicePathPrefix(path));
}
public System.IO.FileAttributes GetFileAttributes(string path)
{
- return System.IO.File.GetAttributes(PrefixWithUNC(path));
+ return System.IO.File.GetAttributes(AddExtendedDevicePathPrefix(path));
}
public void SetFileAttributes(string path, System.IO.FileAttributes attributes)
{
- System.IO.File.SetAttributes(PrefixWithUNC(path), attributes);
+ System.IO.File.SetAttributes(AddExtendedDevicePathPrefix(path), attributes);
}
/// <summary>
@@ -321,7 +338,7 @@ namespace Duplicati.Library.Common.IO
{
try
{
- return AlphaFS.File.GetLinkTargetInfo(PrefixWithUNC(file)).PrintName;
+ return AlphaFS.File.GetLinkTargetInfo(AddExtendedDevicePathPrefix(file)).PrintName;
}
catch (AlphaFS.NotAReparsePointException) { }
catch (AlphaFS.UnrecognizedReparsePointException) { }
@@ -334,132 +351,132 @@ namespace Duplicati.Library.Common.IO
public IEnumerable<string> EnumerateFileSystemEntries(string path)
{
- return System.IO.Directory.EnumerateFileSystemEntries(PrefixWithUNC(path)).Select(StripUNCPrefix);
+ return System.IO.Directory.EnumerateFileSystemEntries(AddExtendedDevicePathPrefix(path)).Select(RemoveExtendedDevicePathPrefix);
}
public IEnumerable<string> EnumerateFiles(string path)
{
- return System.IO.Directory.EnumerateFiles(PrefixWithUNC(path)).Select(StripUNCPrefix);
+ return System.IO.Directory.EnumerateFiles(AddExtendedDevicePathPrefix(path)).Select(RemoveExtendedDevicePathPrefix);
}
public IEnumerable<string> EnumerateFiles(string path, string searchPattern, SearchOption searchOption)
{
- return System.IO.Directory.EnumerateFiles(PrefixWithUNC(path), searchPattern, searchOption).Select(StripUNCPrefix);
+ return System.IO.Directory.EnumerateFiles(AddExtendedDevicePathPrefix(path), searchPattern, searchOption).Select(RemoveExtendedDevicePathPrefix);
}
public string PathGetFileName(string path)
{
- return StripUNCPrefix(System.IO.Path.GetFileName(PrefixWithUNC(path)));
+ return RemoveExtendedDevicePathPrefix(System.IO.Path.GetFileName(AddExtendedDevicePathPrefix(path)));
}
public string PathGetDirectoryName(string path)
{
- return StripUNCPrefix(System.IO.Path.GetDirectoryName(PrefixWithUNC(path)));
+ return RemoveExtendedDevicePathPrefix(System.IO.Path.GetDirectoryName(AddExtendedDevicePathPrefix(path)));
}
public string PathGetExtension(string path)
{
- return StripUNCPrefix(System.IO.Path.GetExtension(PrefixWithUNC(path)));
+ return RemoveExtendedDevicePathPrefix(System.IO.Path.GetExtension(AddExtendedDevicePathPrefix(path)));
}
public string PathChangeExtension(string path, string extension)
{
- return StripUNCPrefix(System.IO.Path.ChangeExtension(PrefixWithUNC(path), extension));
+ return RemoveExtendedDevicePathPrefix(System.IO.Path.ChangeExtension(AddExtendedDevicePathPrefix(path), extension));
}
public void DirectorySetLastWriteTimeUtc(string path, DateTime time)
{
- System.IO.Directory.SetLastWriteTimeUtc(PrefixWithUNC(path), time);
+ System.IO.Directory.SetLastWriteTimeUtc(AddExtendedDevicePathPrefix(path), time);
}
public void DirectorySetCreationTimeUtc(string path, DateTime time)
{
- System.IO.Directory.SetCreationTimeUtc(PrefixWithUNC(path), time);
+ System.IO.Directory.SetCreationTimeUtc(AddExtendedDevicePathPrefix(path), time);
}
public void FileMove(string source, string target)
{
- System.IO.File.Move(PrefixWithUNC(source), PrefixWithUNC(target));
+ System.IO.File.Move(AddExtendedDevicePathPrefix(source), AddExtendedDevicePathPrefix(target));
}
public long FileLength(string path)
{
- return new System.IO.FileInfo(PrefixWithUNC(path)).Length;
+ return new System.IO.FileInfo(AddExtendedDevicePathPrefix(path)).Length;
}
public string GetPathRoot(string path)
{
- if (IsPrefixedWithUNC(path))
+ if (IsPrefixedWithExtendedDevicePathPrefix(path))
{
return Path.GetPathRoot(path);
}
else
{
- return StripUNCPrefix(Path.GetPathRoot(PrefixWithUNC(path)));
+ return RemoveExtendedDevicePathPrefix(Path.GetPathRoot(AddExtendedDevicePathPrefix(path)));
}
}
public string[] GetDirectories(string path)
{
- if (IsPrefixedWithUNC(path))
+ if (IsPrefixedWithExtendedDevicePathPrefix(path))
{
return Directory.GetDirectories(path);
}
else
{
- return Directory.GetDirectories(PrefixWithUNC(path)).Select(StripUNCPrefix).ToArray();
+ return Directory.GetDirectories(AddExtendedDevicePathPrefix(path)).Select(RemoveExtendedDevicePathPrefix).ToArray();
}
}
public string[] GetFiles(string path)
{
- if (IsPrefixedWithUNC(path))
+ if (IsPrefixedWithExtendedDevicePathPrefix(path))
{
return Directory.GetFiles(path);
}
else
{
- return Directory.GetFiles(PrefixWithUNC(path)).Select(StripUNCPrefix).ToArray();
+ return Directory.GetFiles(AddExtendedDevicePathPrefix(path)).Select(RemoveExtendedDevicePathPrefix).ToArray();
}
}
public string[] GetFiles(string path, string searchPattern)
{
- if (IsPrefixedWithUNC(path))
+ if (IsPrefixedWithExtendedDevicePathPrefix(path))
{
return Directory.GetFiles(path, searchPattern);
}
else
{
- return Directory.GetFiles(PrefixWithUNC(path), searchPattern).Select(StripUNCPrefix).ToArray();
+ return Directory.GetFiles(AddExtendedDevicePathPrefix(path), searchPattern).Select(RemoveExtendedDevicePathPrefix).ToArray();
}
}
public DateTime GetCreationTimeUtc(string path)
{
- return Directory.GetCreationTimeUtc(PrefixWithUNC(path));
+ return Directory.GetCreationTimeUtc(AddExtendedDevicePathPrefix(path));
}
public DateTime GetLastWriteTimeUtc(string path)
{
- return Directory.GetLastWriteTimeUtc(PrefixWithUNC(path));
+ return Directory.GetLastWriteTimeUtc(AddExtendedDevicePathPrefix(path));
}
public IEnumerable<string> EnumerateDirectories(string path)
{
- if (IsPrefixedWithUNC(path))
+ if (IsPrefixedWithExtendedDevicePathPrefix(path))
{
return Directory.EnumerateDirectories(path);
}
else
{
- return Directory.EnumerateDirectories(PrefixWithUNC(path)).Select(StripUNCPrefix);
+ return Directory.EnumerateDirectories(AddExtendedDevicePathPrefix(path)).Select(RemoveExtendedDevicePathPrefix);
}
}
public void FileCopy(string source, string target, bool overwrite)
{
- File.Copy(PrefixWithUNC(source), PrefixWithUNC(target), overwrite);
+ File.Copy(AddExtendedDevicePathPrefix(source), AddExtendedDevicePathPrefix(target), overwrite);
}
public string PathGetFullPath(string path)
@@ -469,19 +486,19 @@ namespace Duplicati.Library.Common.IO
// 2. If path is not already prefixed with \\?\, the return value should also not be prefixed
// 3. If path is relative or has relative components, that should be resolved by calling Path.GetFullPath()
// 4. If path is not relative and has no relative components, prefix with \\?\ to prevent normalization from munging "problematic Windows paths"
- if (IsPrefixedWithUNC(path))
+ if (IsPrefixedWithExtendedDevicePathPrefix(path))
{
return path;
}
else
{
- return StripUNCPrefix(Path.GetFullPath(PrefixWithUNC(path)));
+ return RemoveExtendedDevicePathPrefix(Path.GetFullPath(AddExtendedDevicePathPrefix(path)));
}
}
public IFileEntry DirectoryEntry(string path)
{
- var dInfo = new DirectoryInfo(PrefixWithUNC(path));
+ var dInfo = new DirectoryInfo(AddExtendedDevicePathPrefix(path));
return new FileEntry(dInfo.Name, 0, dInfo.LastAccessTime, dInfo.LastWriteTime)
{
IsFolder = true
@@ -490,7 +507,7 @@ namespace Duplicati.Library.Common.IO
public IFileEntry FileEntry(string path)
{
- var fileInfo = new FileInfo(PrefixWithUNC(path));
+ var fileInfo = new FileInfo(AddExtendedDevicePathPrefix(path));
return new FileEntry(fileInfo.Name, fileInfo.Length, fileInfo.LastAccessTime, fileInfo.LastWriteTime);
}
@@ -582,11 +599,11 @@ namespace Duplicati.Library.Common.IO
if (asDir)
{
- Alphaleonis.Win32.Filesystem.Directory.CreateSymbolicLink(PrefixWithUNC(symlinkfile), target, AlphaFS.PathFormat.LongFullPath);
+ Alphaleonis.Win32.Filesystem.Directory.CreateSymbolicLink(AddExtendedDevicePathPrefix(symlinkfile), target, AlphaFS.PathFormat.LongFullPath);
}
else
{
- Alphaleonis.Win32.Filesystem.File.CreateSymbolicLink(PrefixWithUNC(symlinkfile), target, AlphaFS.PathFormat.LongFullPath);
+ Alphaleonis.Win32.Filesystem.File.CreateSymbolicLink(AddExtendedDevicePathPrefix(symlinkfile), target, AlphaFS.PathFormat.LongFullPath);
}
//Sadly we do not get a notification if the creation fails :(
diff --git a/Duplicati/Library/Snapshots/NoSnapshotWindows.cs b/Duplicati/Library/Snapshots/NoSnapshotWindows.cs
index 59e1230c2..385b182b6 100644
--- a/Duplicati/Library/Snapshots/NoSnapshotWindows.cs
+++ b/Duplicati/Library/Snapshots/NoSnapshotWindows.cs
@@ -65,8 +65,8 @@ namespace Duplicati.Library.Snapshots
/// <param name="errorCallback">The callback used to report errors</param>
public override IEnumerable<string> EnumerateFilesAndFolders(IEnumerable<string> sources, Utility.Utility.EnumerationFilterDelegate callback, Utility.Utility.ReportAccessError errorCallback)
{
- // For Windows, ensure we don't store paths with UNC prefix
- return base.EnumerateFilesAndFolders(sources.Select(SystemIOWindows.StripUNCPrefix), callback, errorCallback);
+ // For Windows, ensure we don't store paths with extended device path prefixes (i.e., @"\\?\" or @"\\?\UNC\")
+ return base.EnumerateFilesAndFolders(sources.Select(SystemIOWindows.RemoveExtendedDevicePathPrefix), callback, errorCallback);
}
/// <summary>
@@ -109,7 +109,7 @@ namespace Duplicati.Library.Snapshots
string[] tmp = SystemIO.IO_WIN.GetFiles(localFolderPath);
string[] res = new string[tmp.Length];
for(int i = 0; i < tmp.Length; i++)
- res[i] = SystemIOWindows.StripUNCPrefix(tmp[i]);
+ res[i] = SystemIOWindows.RemoveExtendedDevicePathPrefix(tmp[i]);
return res;
}
@@ -122,10 +122,10 @@ namespace Duplicati.Library.Snapshots
/// <param name='localFolderPath'>The folder to examinate</param>
protected override string[] ListFolders (string localFolderPath)
{
- string[] tmp = SystemIO.IO_WIN.GetDirectories(SystemIOWindows.PrefixWithUNC(localFolderPath));
+ string[] tmp = SystemIO.IO_WIN.GetDirectories(SystemIOWindows.AddExtendedDevicePathPrefix(localFolderPath));
string[] res = new string[tmp.Length];
for (int i = 0; i < tmp.Length; i++)
- res[i] = SystemIOWindows.StripUNCPrefix(tmp[i]);
+ res[i] = SystemIOWindows.RemoveExtendedDevicePathPrefix(tmp[i]);
return res;
}
@@ -151,8 +151,8 @@ namespace Duplicati.Library.Snapshots
/// <inheritdoc />
public override string ConvertToSnapshotPath(string localPath)
{
- // For Windows, ensure we don't store paths with UNC prefix
- return SystemIOWindows.StripUNCPrefix(localPath);
+ // For Windows, ensure we don't store paths with extended device path prefixes (i.e., @"\\?\" or @"\\?\UNC\")
+ return SystemIOWindows.RemoveExtendedDevicePathPrefix(localPath);
}
}
}
diff --git a/Duplicati/Library/Snapshots/WindowsSnapshot.cs b/Duplicati/Library/Snapshots/WindowsSnapshot.cs
index 3d77e749e..8b32ac8ca 100644
--- a/Duplicati/Library/Snapshots/WindowsSnapshot.cs
+++ b/Duplicati/Library/Snapshots/WindowsSnapshot.cs
@@ -53,8 +53,8 @@ namespace Duplicati.Library.Snapshots
/// <param name="options">A set of commandline options</param>
public WindowsSnapshot(IEnumerable<string> sources, IDictionary<string, string> options)
{
- // For Windows, ensure we don't store paths with UNC prefix
- sources = sources.Select(SystemIOWindows.StripUNCPrefix);
+ // For Windows, ensure we don't store paths with extended device path prefixes (i.e., @"\\?\" or @"\\?\UNC\")
+ sources = sources.Select(SystemIOWindows.RemoveExtendedDevicePathPrefix);
try
{
_vssBackupComponents = new VssBackupComponents();
@@ -115,11 +115,11 @@ namespace Duplicati.Library.Snapshots
tmp = SystemIO.IO_WIN.GetDirectories(spath);
var root = Util.AppendDirSeparator(SystemIO.IO_WIN.GetPathRoot(localFolderPath));
var volumePath = Util.AppendDirSeparator(ConvertToSnapshotPath(root));
- volumePath = SystemIOWindows.PrefixWithUNC(volumePath);
+ volumePath = SystemIOWindows.AddExtendedDevicePathPrefix(volumePath);
for (var i = 0; i < tmp.Length; i++)
{
- tmp[i] = root + SystemIOWindows.PrefixWithUNC(tmp[i]).Substring(volumePath.Length);
+ tmp[i] = root + SystemIOWindows.AddExtendedDevicePathPrefix(tmp[i]).Substring(volumePath.Length);
}
return tmp;
@@ -142,11 +142,11 @@ namespace Duplicati.Library.Snapshots
// convert back to non-shadow, i.e., non-vss version
var root = Util.AppendDirSeparator(SystemIO.IO_WIN.GetPathRoot(localFolderPath));
var volumePath = Util.AppendDirSeparator(ConvertToSnapshotPath(root));
- volumePath = SystemIOWindows.PrefixWithUNC(volumePath);
+ volumePath = SystemIOWindows.AddExtendedDevicePathPrefix(volumePath);
for (var i = 0; i < files.Length; i++)
{
- files[i] = root + SystemIOWindows.PrefixWithUNC(files[i]).Substring(volumePath.Length);
+ files[i] = root + SystemIOWindows.AddExtendedDevicePathPrefix(files[i]).Substring(volumePath.Length);
}
return files;
@@ -163,8 +163,8 @@ namespace Duplicati.Library.Snapshots
/// <param name="errorCallback">The callback used to report errors</param>
public override IEnumerable<string> EnumerateFilesAndFolders(IEnumerable<string> sources, Utility.Utility.EnumerationFilterDelegate callback, Utility.Utility.ReportAccessError errorCallback)
{
- // For Windows, ensure we don't store paths with UNC prefix
- return base.EnumerateFilesAndFolders(sources.Select(SystemIOWindows.StripUNCPrefix), callback, errorCallback);
+ // For Windows, ensure we don't store paths with extended device path prefixes (i.e., @"\\?\" or @"\\?\UNC\")
+ return base.EnumerateFilesAndFolders(sources.Select(SystemIOWindows.RemoveExtendedDevicePathPrefix), callback, errorCallback);
}
/// <summary>
@@ -176,7 +176,7 @@ namespace Duplicati.Library.Snapshots
{
var spath = ConvertToSnapshotPath(localPath);
- return SystemIO.IO_WIN.GetLastWriteTimeUtc(SystemIOWindows.PrefixWithUNC(spath));
+ return SystemIO.IO_WIN.GetLastWriteTimeUtc(SystemIOWindows.AddExtendedDevicePathPrefix(spath));
}
/// <summary>
@@ -188,7 +188,7 @@ namespace Duplicati.Library.Snapshots
{
var spath = ConvertToSnapshotPath(localPath);
- return SystemIO.IO_WIN.GetCreationTimeUtc(SystemIOWindows.PrefixWithUNC(spath));
+ return SystemIO.IO_WIN.GetCreationTimeUtc(SystemIOWindows.AddExtendedDevicePathPrefix(spath));
}
/// <summary>
@@ -274,8 +274,8 @@ namespace Duplicati.Library.Snapshots
/// <inheritdoc />
public override string ConvertToSnapshotPath(string localPath)
{
- // For Windows, ensure we don't store paths with UNC prefix
- localPath = SystemIOWindows.StripUNCPrefix(localPath);
+ // For Windows, ensure we don't store paths with extended device path prefixes (i.e., @"\\?\" or @"\\?\UNC\")
+ localPath = SystemIOWindows.RemoveExtendedDevicePathPrefix(localPath);
if (!Path.IsPathRooted(localPath))
throw new InvalidOperationException();
diff --git a/Duplicati/UnitTest/IOTests.cs b/Duplicati/UnitTest/IOTests.cs
index 6c18f27f6..5c834c385 100644
--- a/Duplicati/UnitTest/IOTests.cs
+++ b/Duplicati/UnitTest/IOTests.cs
@@ -55,14 +55,14 @@ namespace Duplicati.UnitTest
var root = @"C:" + Util.DirectorySeparatorString;
var filename = "test.txt";
var filePath = root + filename;
- var filePathWithUNC = SystemIOWindows.PrefixWithUNC(filePath);
+ var filePathWithExtendedDevicePathPrefix = SystemIOWindows.AddExtendedDevicePathPrefix(filePath);
- var filePathWithUNCRoot = SystemIO.IO_WIN.GetPathRoot(filePathWithUNC);
+ var filePathWithExtendedDevicePathPrefixRoot = SystemIO.IO_WIN.GetPathRoot(filePathWithExtendedDevicePathPrefix);
- //Prefixed with UNC remains prefixed
- Assert.AreEqual(SystemIOWindows.PrefixWithUNC(root), filePathWithUNCRoot);
+ //Prefixed with extended device path prefix remains prefixed
+ Assert.AreEqual(SystemIOWindows.AddExtendedDevicePathPrefix(root), filePathWithExtendedDevicePathPrefixRoot);
- //Without UNC prefixed, no prefix.
+ //Without extended device path prefix, no prefix.
var filePathRoot = SystemIO.IO_WIN.GetPathRoot(filePath);
Assert.AreEqual(root, filePathRoot);
}
@@ -98,7 +98,7 @@ namespace Duplicati.UnitTest
}
[Test]
- public void TestPrefixWithUNCInWindowsClient()
+ public void TestAddExtendedDevicePathPrefixInWindowsClient()
{
if (!Platform.IsClientWindows)
{
@@ -156,7 +156,7 @@ namespace Duplicati.UnitTest
};
foreach (var path in testCasesLeavingPathUnchanged)
{
- var actual = SystemIOWindows.PrefixWithUNC(path);
+ var actual = SystemIOWindows.AddExtendedDevicePathPrefix(path);
var expected = path;
Assert.AreEqual(expected, actual, $"Path: {path}");
}
@@ -199,7 +199,7 @@ namespace Duplicati.UnitTest
foreach (var keyValuePair in testCasesWherePrefixIsApplied)
{
var path = keyValuePair.Key;
- var actual = SystemIOWindows.PrefixWithUNC(path);
+ var actual = SystemIOWindows.AddExtendedDevicePathPrefix(path);
var expected = keyValuePair.Value;
Assert.AreEqual(expected, actual, $"Path: {path}");
}