From 57c96da91405b77519e9b67dcfee9dc1c0a11972 Mon Sep 17 00:00:00 2001 From: verhoek <30193551+verhoek@users.noreply.github.com> Date: Wed, 28 Nov 2018 16:21:11 +0100 Subject: [PATCH 1/4] Reducing duplicate code. --- .../Library/Common/IO/SystemIOWindows.cs | 583 +++++------------- 1 file changed, 165 insertions(+), 418 deletions(-) diff --git a/Duplicati/Library/Common/IO/SystemIOWindows.cs b/Duplicati/Library/Common/IO/SystemIOWindows.cs index 84398407d..7e817fcf5 100644 --- a/Duplicati/Library/Common/IO/SystemIOWindows.cs +++ b/Duplicati/Library/Common/IO/SystemIOWindows.cs @@ -19,6 +19,7 @@ using System; using System.Collections.Generic; using System.Security.AccessControl; using System.IO; +using System.Linq; using AlphaFS = Alphaleonis.Win32.Filesystem; using Duplicati.Library.Interface; @@ -34,10 +35,7 @@ namespace Duplicati.Library.Common.IO private static bool IsPathTooLong(string path) { - if (path.StartsWith(UNCPREFIX, StringComparison.Ordinal) || path.StartsWith(UNCPREFIX_SERVER, StringComparison.Ordinal) || path.Length > 260) - return true; - - return false; + return path.StartsWith(UNCPREFIX, StringComparison.Ordinal) || path.StartsWith(UNCPREFIX_SERVER, StringComparison.Ordinal) || path.Length > 260; } public static string PrefixWithUNC(string path) @@ -48,209 +46,145 @@ namespace Duplicati.Library.Common.IO if (path.StartsWith(UNCPREFIX, StringComparison.Ordinal)) return path; - if (path.StartsWith(PATHPREFIX_SERVER, StringComparison.Ordinal)) - return UNCPREFIX_SERVER + path.Remove(0, PATHPREFIX_SERVER.Length); - - return UNCPREFIX + path; + return path.StartsWith(PATHPREFIX_SERVER, StringComparison.Ordinal) + ? UNCPREFIX_SERVER + path.Remove(0, PATHPREFIX_SERVER.Length) + : UNCPREFIX + path; } public static string StripUNCPrefix(string path) { - if (path.StartsWith(UNCPREFIX, StringComparison.Ordinal)) - return path.Substring(UNCPREFIX.Length); - else - return path; + return path.StartsWith(UNCPREFIX, StringComparison.Ordinal) ? path.Substring(UNCPREFIX.Length) : path; + } + + private static void PathTooLongVoidFuncWrapper(Func nativeIOFunc, + Func alternativeIOFunc, + string path, bool prefixWithUnc = false) + { + // Wrap void into bool return type to avoid code duplication. Code at anytime available for replacement. + PathTooLongFuncWrapper(p => { nativeIOFunc(p); return true; }, p => { alternativeIOFunc(p); return true; } , path, prefixWithUnc); + } + + private static void PathTooLongActionWrapper(Action nativeIOFunc, + Action alternativeIOFunc, + string path, bool prefixWithUnc = false) + { + // Wrap void into bool return type to avoid code duplication. Code at anytime available for replacement. + PathTooLongFuncWrapper(p => { nativeIOFunc(p); return true; }, p => { alternativeIOFunc(p); return true; }, path, prefixWithUnc); + } + + private static T PathTooLongFuncWrapper(Func nativeIOFunc, + Func alternativeIOFunc, + string path, bool prefixWithUnc = false) + { + if (!IsPathTooLong(path)) + try { return nativeIOFunc(path); } + catch (System.IO.PathTooLongException) { } + catch (System.ArgumentException) { } + + return !prefixWithUnc ? alternativeIOFunc(path) : alternativeIOFunc(PrefixWithUNC(path)); } #region ISystemIO implementation public void DirectoryDelete(string path) { - if (!IsPathTooLong(path)) - try - { - System.IO.Directory.Delete(path); - return; - } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - - Alphaleonis.Win32.Filesystem.Directory.Delete(PrefixWithUNC(path)); + PathTooLongActionWrapper(System.IO.Directory.Delete, + Alphaleonis.Win32.Filesystem.Directory.Delete, path, true); } public void DirectoryCreate(string path) { - if (!IsPathTooLong(path)) - try - { - System.IO.Directory.CreateDirectory(path); - return; - } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - - Alphaleonis.Win32.Filesystem.Directory.CreateDirectory(PrefixWithUNC(path)); + PathTooLongVoidFuncWrapper(System.IO.Directory.CreateDirectory, + Alphaleonis.Win32.Filesystem.Directory.CreateDirectory, path, true); } public bool DirectoryExists(string path) { - if (!IsPathTooLong(path)) - try { return System.IO.Directory.Exists(path); } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - - return Alphaleonis.Win32.Filesystem.Directory.Exists(PrefixWithUNC(path)); + return PathTooLongFuncWrapper(System.IO.Directory.Exists, + Alphaleonis.Win32.Filesystem.Directory.Exists, path, true); } public void FileDelete(string path) { - if (!IsPathTooLong(path)) - try - { - System.IO.File.Delete(path); - return; - } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - - Alphaleonis.Win32.Filesystem.File.Delete(PrefixWithUNC(path)); + PathTooLongActionWrapper(System.IO.File.Delete, + Alphaleonis.Win32.Filesystem.File.Delete, path, true); } public void FileSetLastWriteTimeUtc(string path, DateTime time) { - if (!IsPathTooLong(path)) - try - { - System.IO.File.SetLastWriteTimeUtc(path, time); - return; - } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - - Alphaleonis.Win32.Filesystem.File.SetLastWriteTimeUtc(PrefixWithUNC(path), time); + PathTooLongActionWrapper(p => System.IO.File.SetLastWriteTimeUtc(p, time), + p => Alphaleonis.Win32.Filesystem.File.SetLastWriteTimeUtc(p, time), path, true); } public void FileSetCreationTimeUtc(string path, DateTime time) { - if (!IsPathTooLong(path)) - try - { - System.IO.File.SetCreationTimeUtc(path, time); - return; - } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - - Alphaleonis.Win32.Filesystem.File.SetCreationTimeUtc(PrefixWithUNC(path), time); + PathTooLongActionWrapper(p => System.IO.File.SetCreationTimeUtc(p, time), + p => Alphaleonis.Win32.Filesystem.File.SetCreationTimeUtc(p, time), path, true); } public DateTime FileGetLastWriteTimeUtc(string path) { - if (!IsPathTooLong(path)) - try - { - return System.IO.File.GetLastWriteTimeUtc(path); - } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - - return Alphaleonis.Win32.Filesystem.File.GetLastWriteTimeUtc(PrefixWithUNC(path)); + return PathTooLongFuncWrapper(System.IO.File.GetLastWriteTimeUtc, + Alphaleonis.Win32.Filesystem.File.GetLastWriteTimeUtc, path, true); } public DateTime FileGetCreationTimeUtc(string path) { - if (!IsPathTooLong(path)) - try - { - return System.IO.File.GetCreationTimeUtc(path); - } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - - return Alphaleonis.Win32.Filesystem.File.GetCreationTimeUtc(PrefixWithUNC(path)); + return PathTooLongFuncWrapper(System.IO.File.GetCreationTimeUtc, + Alphaleonis.Win32.Filesystem.File.GetCreationTimeUtc, path, true); } public bool FileExists(string path) { - if (!IsPathTooLong(path)) - try { return System.IO.File.Exists(path); } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - - return Alphaleonis.Win32.Filesystem.File.Exists(PrefixWithUNC(path)); + return PathTooLongFuncWrapper(System.IO.File.Exists, + Alphaleonis.Win32.Filesystem.File.Exists, path, true); } public System.IO.FileStream FileOpenRead(string path) { - if (!IsPathTooLong(path)) - try { return System.IO.File.Open(path, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.ReadWrite); } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - - return Alphaleonis.Win32.Filesystem.File.Open(PrefixWithUNC(path), FileMode.Open, FileAccess.Read, FileShare.ReadWrite); + return PathTooLongFuncWrapper(p => System.IO.File.Open(p, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.ReadWrite), + p => Alphaleonis.Win32.Filesystem.File.Open(p, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.ReadWrite), + path, true); } public System.IO.FileStream FileOpenWrite(string path) { - if (!IsPathTooLong(path)) - try { return System.IO.File.OpenWrite(path); } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - - if (FileExists(path)) - return Alphaleonis.Win32.Filesystem.File.OpenWrite(PrefixWithUNC(path)); - else - return FileCreate(path); + return !FileExists(path) + ? FileCreate(path) + : PathTooLongFuncWrapper(System.IO.File.OpenWrite, Alphaleonis.Win32.Filesystem.File.OpenWrite, path, true); } public System.IO.FileStream FileOpenReadWrite(string path) { - if (!IsPathTooLong(path)) - try { return System.IO.File.Open(path, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite, System.IO.FileShare.Read); } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - - return Alphaleonis.Win32.Filesystem.File.Open(PrefixWithUNC(path), FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read); + return PathTooLongFuncWrapper(p => System.IO.File.Open(p, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite, System.IO.FileShare.Read), + p => Alphaleonis.Win32.Filesystem.File.Open(p, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read), path, true); } public System.IO.FileStream FileCreate(string path) { - if (!IsPathTooLong(path)) - try { return System.IO.File.Create(path); } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - - return Alphaleonis.Win32.Filesystem.File.Create(PrefixWithUNC(path)); + return PathTooLongFuncWrapper(System.IO.File.Create, Alphaleonis.Win32.Filesystem.File.Create, path, true); } public System.IO.FileAttributes GetFileAttributes(string path) { - if (!IsPathTooLong(path)) - try { return System.IO.File.GetAttributes(path); } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - - return (System.IO.FileAttributes)Alphaleonis.Win32.Filesystem.File.GetAttributes(PrefixWithUNC(path)); + return PathTooLongFuncWrapper(System.IO.File.GetAttributes, + (Func)Alphaleonis.Win32.Filesystem.File.GetAttributes, path, true); } public void SetFileAttributes(string path, System.IO.FileAttributes attributes) { - if (!IsPathTooLong(path)) - try - { - System.IO.File.SetAttributes(path, attributes); - return; - } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - - Alphaleonis.Win32.Filesystem.File.SetAttributes(PrefixWithUNC(path), (FileAttributes)attributes); + PathTooLongActionWrapper(p => System.IO.File.SetAttributes(p, attributes), + p => Alphaleonis.Win32.Filesystem.File.SetAttributes(p, attributes), path, true); } public void CreateSymlink(string symlinkfile, string target, bool asDir) { if (FileExists(symlinkfile) || DirectoryExists(symlinkfile)) throw new System.IO.IOException(string.Format("File already exists: {0}", symlinkfile)); - Alphaleonis.Win32.Filesystem.File.CreateSymbolicLink(PrefixWithUNC(symlinkfile), target, asDir ? Alphaleonis.Win32.Filesystem.SymbolicLinkTarget.Directory : Alphaleonis.Win32.Filesystem.SymbolicLinkTarget.File, AlphaFS.PathFormat.LongFullPath); + + Alphaleonis.Win32.Filesystem.File.CreateSymbolicLink(PrefixWithUNC(symlinkfile), + target, + asDir ? Alphaleonis.Win32.Filesystem.SymbolicLinkTarget.Directory : Alphaleonis.Win32.Filesystem.SymbolicLinkTarget.File, + AlphaFS.PathFormat.LongFullPath); //Sadly we do not get a notification if the creation fails :( System.IO.FileAttributes attr = 0; @@ -271,13 +205,7 @@ namespace Duplicati.Library.Common.IO { try { - try - { - return AlphaFS.File.GetLinkTargetInfo(file).PrintName; - } - catch (PathTooLongException) { } - - return AlphaFS.File.GetLinkTargetInfo(SystemIOWindows.PrefixWithUNC(file)).PrintName; + return PathTooLongFuncWrapper(AlphaFS.File.GetLinkTargetInfo, AlphaFS.File.GetLinkTargetInfo, file, true).PrintName; } catch (AlphaFS.NotAReparsePointException) { } catch (AlphaFS.UnrecognizedReparsePointException) { } @@ -288,85 +216,46 @@ namespace Duplicati.Library.Common.IO return null; } - private static T TryNativeFirst(Func nativeIOFunc, Func alternativeIOFunc, string path) - { - if (!IsPathTooLong(path)) - try { return nativeIOFunc(path); } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - - return alternativeIOFunc(path); - } - public IEnumerable EnumerateFileSystemEntries(string path) { - IEnumerable alphaFS(string _path) - { - var r = Alphaleonis.Win32.Filesystem.Directory.GetFileSystemEntries(PrefixWithUNC(_path)); - for (var i = 0; i < r.Length; i++) - r[i] = StripUNCPrefix(r[i]); - - return r; - } - - return TryNativeFirst(System.IO.Directory.EnumerateFileSystemEntries, alphaFS, path); + return PathTooLongFuncWrapper(System.IO.Directory.EnumerateFileSystemEntries, + Alphaleonis.Win32.Filesystem.Directory.GetFileSystemEntries, + path, true).Select(StripUNCPrefix).AsEnumerable(); } public IEnumerable EnumerateFiles(string path) { - if (!IsPathTooLong(path)) - { - try { return System.IO.Directory.EnumerateFiles(path); } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - } - - var r = Alphaleonis.Win32.Filesystem.Directory.GetFiles(PrefixWithUNC(path)); - for (var i = 0; i < r.Length; i++) - r[i] = StripUNCPrefix(r[i]); - - return r; + return PathTooLongFuncWrapper(System.IO.Directory.EnumerateFiles, + Alphaleonis.Win32.Filesystem.Directory.GetFiles, path, + true).Select(StripUNCPrefix).AsEnumerable(); } - public string PathGetFileName(string path) { - if (!IsPathTooLong(path)) - try { return System.IO.Path.GetFileName(path); } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - - return StripUNCPrefix(Alphaleonis.Win32.Filesystem.Path.GetFileName(PrefixWithUNC(path))); + return StripUNCPrefix(PathTooLongFuncWrapper(System.IO.Path.GetFileName, + Alphaleonis.Win32.Filesystem.Path.GetFileName, + path, true)); } public string PathGetDirectoryName(string path) { - if (!IsPathTooLong(path)) - try { return System.IO.Path.GetDirectoryName(path); } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - - return StripUNCPrefix(Alphaleonis.Win32.Filesystem.Path.GetDirectoryName(PrefixWithUNC(path))); + return StripUNCPrefix(PathTooLongFuncWrapper(System.IO.Path.GetDirectoryName, + Alphaleonis.Win32.Filesystem.Path.GetDirectoryName, + path, true)); } public string PathGetExtension(string path) { - if (!IsPathTooLong(path)) - try { return System.IO.Path.GetExtension(path); } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - - return StripUNCPrefix(Alphaleonis.Win32.Filesystem.Path.GetExtension(PrefixWithUNC(path))); + return StripUNCPrefix(PathTooLongFuncWrapper(System.IO.Path.GetExtension, + Alphaleonis.Win32.Filesystem.Path.GetExtension, + path, true)); } public string PathChangeExtension(string path, string extension) { - if (!IsPathTooLong(path)) - try { return System.IO.Path.ChangeExtension(path, extension); } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - - return StripUNCPrefix(Alphaleonis.Win32.Filesystem.Path.ChangeExtension(PrefixWithUNC(path), extension)); + return StripUNCPrefix(PathTooLongFuncWrapper(p => System.IO.Path.ChangeExtension(p, extension), + p => Alphaleonis.Win32.Filesystem.Path.ChangeExtension(p, extension), + path, true)); } public string PathCombine(params string[] paths) @@ -386,7 +275,8 @@ namespace Duplicati.Library.Common.IO { combinedPath = Path.Combine(combinedPath, paths[i]); } - catch (Exception ex) when (ex is System.IO.PathTooLongException || ex is System.ArgumentException) { + catch (Exception ex) when (ex is System.IO.PathTooLongException || ex is System.ArgumentException) + { //TODO: Explain why we need to keep prefixing and stripping UNC's. combinedPath = StripUNCPrefix(Alphaleonis.Win32.Filesystem.Path.Combine(PrefixWithUNC(combinedPath), paths[i])); } @@ -399,95 +289,48 @@ namespace Duplicati.Library.Common.IO public void DirectorySetLastWriteTimeUtc(string path, DateTime time) { - if (!IsPathTooLong(path)) - try - { - System.IO.Directory.SetLastWriteTimeUtc(path, time); - return; - } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - - - Alphaleonis.Win32.Filesystem.File.SetLastWriteTimeUtc(PrefixWithUNC(path), time); + PathTooLongActionWrapper(p => System.IO.Directory.SetLastWriteTimeUtc(p, time), + p => Alphaleonis.Win32.Filesystem.File.SetLastWriteTimeUtc(p, time), path, true); } public void DirectorySetCreationTimeUtc(string path, DateTime time) { - if (!IsPathTooLong(path)) - try - { - System.IO.Directory.SetCreationTimeUtc(path, time); - return; - } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - - Alphaleonis.Win32.Filesystem.File.SetCreationTimeUtc(PrefixWithUNC(path), time); + PathTooLongActionWrapper(p => System.IO.Directory.SetCreationTimeUtc(p, time), + p => Alphaleonis.Win32.Filesystem.File.SetCreationTimeUtc(p, time), path, true); } public DateTime DirectoryGetLastWriteTimeUtc(string path) { - if (!IsPathTooLong(path)) - try - { - return System.IO.Directory.GetLastWriteTimeUtc(path); - } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - - return Alphaleonis.Win32.Filesystem.Directory.GetLastWriteTimeUtc(PrefixWithUNC(path)); + return PathTooLongFuncWrapper(System.IO.Directory.GetLastWriteTimeUtc, + Alphaleonis.Win32.Filesystem.Directory.GetLastWriteTimeUtc, path, true); } public DateTime DirectoryGetCreationTimeUtc(string path) { - if (!IsPathTooLong(path)) - try - { - return System.IO.Directory.GetCreationTimeUtc(path); - } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - - return Alphaleonis.Win32.Filesystem.Directory.GetCreationTimeUtc(PrefixWithUNC(path)); + return PathTooLongFuncWrapper(System.IO.Directory.GetCreationTimeUtc, + Alphaleonis.Win32.Filesystem.Directory.GetCreationTimeUtc, path, true); } public void FileMove(string source, string target) { - if (!IsPathTooLong(source) && !IsPathTooLong(target)) - try - { - System.IO.File.Move(source, target); - return; - } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - - Alphaleonis.Win32.Filesystem.File.Move(PrefixWithUNC(source), PrefixWithUNC(target)); + // We do not check if path is too long on target. If so, then we catch an exception. + PathTooLongActionWrapper(p => System.IO.File.Move(p, target), + p => Alphaleonis.Win32.Filesystem.File.Move(p, PrefixWithUNC(target)), + source, true); } public long FileLength(string path) { - if (!IsPathTooLong(path)) - try { return new System.IO.FileInfo(path).Length; } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - - return new Alphaleonis.Win32.Filesystem.FileInfo(PrefixWithUNC(path)).Length; + return PathTooLongFuncWrapper(p => new System.IO.FileInfo(p).Length, + p => new Alphaleonis.Win32.Filesystem.FileInfo(p).Length, + path, true); } public void DirectoryDelete(string path, bool recursive) { - if (!IsPathTooLong(path)) - try - { - System.IO.Directory.Delete(path, recursive); - return; - } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - - Alphaleonis.Win32.Filesystem.Directory.Delete(PrefixWithUNC(path), recursive); + PathTooLongActionWrapper(p => System.IO.Directory.Delete(p, recursive), + p => Alphaleonis.Win32.Filesystem.Directory.Delete(p, recursive), + path, true); } private class FileSystemAccess @@ -527,9 +370,9 @@ namespace Duplicati.Library.Common.IO private string SerializeObject(T o) { - using(var tw = new System.IO.StringWriter()) + using (var tw = new System.IO.StringWriter()) { - Newtonsoft.Json.JsonSerializer.Create(new Newtonsoft.Json.JsonSerializerSettings() { Culture = System.Globalization.CultureInfo.InvariantCulture }).Serialize(tw, o); + Newtonsoft.Json.JsonSerializer.Create(new Newtonsoft.Json.JsonSerializerSettings { Culture = System.Globalization.CultureInfo.InvariantCulture }).Serialize(tw, o); tw.Flush(); return tw.ToString(); } @@ -537,57 +380,35 @@ namespace Duplicati.Library.Common.IO private T DeserializeObject(string data) { - using(var tr = new System.IO.StringReader(data)) - return (T)Newtonsoft.Json.JsonSerializer.Create(new Newtonsoft.Json.JsonSerializerSettings() { Culture = System.Globalization.CultureInfo.InvariantCulture }).Deserialize(tr, typeof(T)); + using (var tr = new System.IO.StringReader(data)) + return (T)Newtonsoft.Json.JsonSerializer.Create(new Newtonsoft.Json.JsonSerializerSettings { Culture = System.Globalization.CultureInfo.InvariantCulture }).Deserialize(tr, typeof(T)); } private System.Security.AccessControl.FileSystemSecurity GetAccessControlDir(string path) { - if (!IsPathTooLong(path)) - try { return System.IO.Directory.GetAccessControl(path); } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - - return Alphaleonis.Win32.Filesystem.Directory.GetAccessControl(PrefixWithUNC(path)); + return PathTooLongFuncWrapper(System.IO.Directory.GetAccessControl, + Alphaleonis.Win32.Filesystem.Directory.GetAccessControl, path, true); } private System.Security.AccessControl.FileSystemSecurity GetAccessControlFile(string path) { - if (!IsPathTooLong(path)) - try { return System.IO.File.GetAccessControl(path); } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - - return Alphaleonis.Win32.Filesystem.File.GetAccessControl(PrefixWithUNC(path)); + return PathTooLongFuncWrapper(System.IO.File.GetAccessControl, + Alphaleonis.Win32.Filesystem.File.GetAccessControl, path, true); } private void SetAccessControlFile(string path, FileSecurity rules) { - if (!IsPathTooLong(path)) - try - { - System.IO.File.SetAccessControl(path, rules); - return; - } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - - Alphaleonis.Win32.Filesystem.File.SetAccessControl(PrefixWithUNC(path), rules, AccessControlSections.All); + PathTooLongActionWrapper(p => System.IO.File.SetAccessControl(p, rules), + p => Alphaleonis.Win32.Filesystem.File.SetAccessControl(p, rules, AccessControlSections.All), + path, true); } private void SetAccessControlDir(string path, DirectorySecurity rules) { - if (!IsPathTooLong(path)) - try - { - System.IO.Directory.SetAccessControl(path, rules); - return; - } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - - Alphaleonis.Win32.Filesystem.Directory.SetAccessControl(PrefixWithUNC(path), rules, AccessControlSections.All); + PathTooLongActionWrapper(p => System.IO.Directory.SetAccessControl(p, rules), + p => Alphaleonis.Win32.Filesystem.Directory.SetAccessControl(p, rules, AccessControlSections.All), + path, true); } public Dictionary GetMetadata(string path, bool isSymlink, bool followSymlink) @@ -596,15 +417,9 @@ namespace Duplicati.Library.Common.IO var targetpath = isDirTarget ? path.Substring(0, path.Length - 1) : path; var dict = new Dictionary(); - System.Security.AccessControl.FileSystemSecurity rules; - - if (isDirTarget) - rules = GetAccessControlDir(targetpath); - else - rules = GetAccessControlFile(targetpath); - + FileSystemSecurity rules = isDirTarget ? GetAccessControlDir(targetpath) : GetAccessControlFile(targetpath); var objs = new List(); - foreach(var f in rules.GetAccessRules(true, false, typeof(System.Security.Principal.SecurityIdentifier))) + foreach (var f in rules.GetAccessRules(true, false, typeof(System.Security.Principal.SecurityIdentifier))) objs.Add(new FileSystemAccess((FileSystemAccessRule)f)); dict["win-ext:accessrules"] = SerializeObject(objs); @@ -617,18 +432,12 @@ namespace Duplicati.Library.Common.IO var isDirTarget = path.EndsWith(DIRSEP, StringComparison.Ordinal); var targetpath = isDirTarget ? path.Substring(0, path.Length - 1) : path; - System.Security.AccessControl.FileSystemSecurity rules; - - if (isDirTarget) - rules = GetAccessControlDir(targetpath); - else - rules = GetAccessControlFile(targetpath); - + FileSystemSecurity rules = isDirTarget ? GetAccessControlDir(targetpath) : GetAccessControlFile(targetpath); if (restorePermissions && data.ContainsKey("win-ext:accessrules")) { var content = DeserializeObject(data["win-ext:accessrules"]); var c = rules.GetAccessRules(true, false, typeof(System.Security.Principal.SecurityIdentifier)); - for(var i = c.Count - 1; i >= 0; i--) + for (var i = c.Count - 1; i >= 0; i--) rules.RemoveAccessRule((System.Security.AccessControl.FileSystemAccessRule)c[i]); Exception ex = null; @@ -640,7 +449,7 @@ namespace Duplicati.Library.Common.IO { rules.AddAccessRule((System.Security.AccessControl.FileSystemAccessRule)r.Create(rules)); } - catch(Exception e) + catch (Exception e) { ex = e; } @@ -658,149 +467,87 @@ namespace Duplicati.Library.Common.IO public string GetPathRoot(string path) { - if (!IsPathTooLong(path)) - { - try { return Path.GetPathRoot(path); } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - } - return AlphaFS.Path.GetPathRoot(path); + return PathTooLongFuncWrapper(Path.GetPathRoot, AlphaFS.Path.GetPathRoot, path, false); } public string[] GetDirectories(string path) { - if (!IsPathTooLong(path)) - { - try { return Directory.GetDirectories(path); } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - } - - return AlphaFS.Directory.GetDirectories(path); + return PathTooLongFuncWrapper(Directory.GetDirectories, AlphaFS.Directory.GetDirectories, path, false); } public string[] GetFiles(string path) { - if (!IsPathTooLong(path)) - { - try { return Directory.GetFiles(path); } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - } - - return AlphaFS.Directory.GetFiles(path); + return PathTooLongFuncWrapper(Directory.GetFiles, AlphaFS.Directory.GetFiles, path, false); } public string[] GetFiles(string path, string searchPattern) { - if (!IsPathTooLong(path)) - { - try { return Directory.GetFiles(path, searchPattern); } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - } - - return AlphaFS.Directory.GetFiles(path, searchPattern); + return PathTooLongFuncWrapper(p => Directory.GetFiles(p, searchPattern), p => AlphaFS.Directory.GetFiles(p, searchPattern), path, false); } public DateTime GetCreationTimeUtc(string path) { - if (!IsPathTooLong(path)) - { - try { return Directory.GetCreationTimeUtc(path); } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - } - - return AlphaFS.File.GetCreationTimeUtc(path); + return PathTooLongFuncWrapper(Directory.GetCreationTimeUtc, AlphaFS.File.GetCreationTimeUtc, path, false); } public DateTime GetLastWriteTimeUtc(string path) { - if (!IsPathTooLong(path)) - { - try { return Directory.GetLastWriteTimeUtc(path); } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - } - - return AlphaFS.File.GetLastWriteTimeUtc(path); + return PathTooLongFuncWrapper(Directory.GetLastWriteTimeUtc, AlphaFS.File.GetLastWriteTimeUtc, path, false); } public IEnumerable EnumerateDirectories(string path) { - if (!IsPathTooLong(path)) - { - try { return Directory.EnumerateDirectories(path); } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - } - - return AlphaFS.Directory.EnumerateDirectories(path); + return PathTooLongFuncWrapper(Directory.EnumerateDirectories, AlphaFS.Directory.EnumerateDirectories, path, false); } public void FileCopy(string source, string target, bool overwrite) { - if (!IsPathTooLong(source) && !IsPathTooLong(target)) - { - try { File.Copy(source, target, overwrite); } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - } - - AlphaFS.File.Copy(source, target, overwrite); + // We do not check if path is too long on target. If so, then we catch an exception. + PathTooLongActionWrapper(p => File.Copy(p, target, overwrite), p => AlphaFS.File.Copy(p, target, overwrite), source, false); } public string PathGetFullPath(string path) { - if (!IsPathTooLong(path)) - { - try { return System.IO.Path.GetFullPath(path); } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } - } - - return AlphaFS.Path.GetFullPath(path); + return PathTooLongFuncWrapper(System.IO.Path.GetFullPath, AlphaFS.Path.GetFullPath, path, false); } public IFileEntry DirectoryEntry(string path) - { - if (!IsPathTooLong(path)) - { - try + { + IFileEntry DirectoryEntryNative(string p) { + var dInfo = new DirectoryInfo(p); + return new FileEntry(dInfo.Name, 0, dInfo.LastAccessTime, dInfo.LastWriteTime) { - var dInfo = new DirectoryInfo(path); - return new FileEntry(dInfo.Name, 0, dInfo.LastAccessTime, dInfo.LastWriteTime) - { - IsFolder = true - }; - } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } + IsFolder = true + }; } - - var dInfoAlphaFS = new AlphaFS.DirectoryInfo(path); - return new FileEntry(dInfoAlphaFS.Name, 0, dInfoAlphaFS.LastAccessTime, dInfoAlphaFS.LastWriteTime) + + IFileEntry DirectoryEntryAlphaFS(string p) { - IsFolder = true - }; + var dInfoAlphaFS = new AlphaFS.DirectoryInfo(p); + return new FileEntry(dInfoAlphaFS.Name, 0, dInfoAlphaFS.LastAccessTime, dInfoAlphaFS.LastWriteTime) + { + IsFolder = true + }; + } + + return PathTooLongFuncWrapper(DirectoryEntryNative, DirectoryEntryAlphaFS, path, false); } public IFileEntry FileEntry(string path) - { - if (!IsPathTooLong(path)) + { + IFileEntry FileEntryNative(string p) { - try - { - var fileInfo = new FileInfo(path); - return new FileEntry(fileInfo.Name, fileInfo.Length, fileInfo.LastAccessTime, fileInfo.LastWriteTime); - } - catch (System.IO.PathTooLongException) { } - catch (System.ArgumentException) { } + var fileInfo = new FileInfo(p); + return new FileEntry(fileInfo.Name, fileInfo.Length, fileInfo.LastAccessTime, fileInfo.LastWriteTime); } - var fInfoAlphaFS = new AlphaFS.FileInfo(path); - return new FileEntry(fInfoAlphaFS.Name, fInfoAlphaFS.Length, fInfoAlphaFS.LastAccessTime, fInfoAlphaFS.LastWriteTime); + IFileEntry FileEntryAlphaFS(string p) + { + var fInfoAlphaFS = new AlphaFS.FileInfo(p); + return new FileEntry(fInfoAlphaFS.Name, fInfoAlphaFS.Length, fInfoAlphaFS.LastAccessTime, fInfoAlphaFS.LastWriteTime); + } + + return PathTooLongFuncWrapper(FileEntryNative, FileEntryAlphaFS, path, false); } #endregion From bb7062d34b7c9006d515f67fc726cb83292b831e Mon Sep 17 00:00:00 2001 From: verhoek <30193551+verhoek@users.noreply.github.com> Date: Thu, 29 Nov 2018 09:13:13 +0100 Subject: [PATCH 2/4] Regrouped methods. --- .../Library/Common/IO/SystemIOWindows.cs | 326 +++++++++--------- 1 file changed, 163 insertions(+), 163 deletions(-) diff --git a/Duplicati/Library/Common/IO/SystemIOWindows.cs b/Duplicati/Library/Common/IO/SystemIOWindows.cs index 7e817fcf5..0f8ddcc13 100644 --- a/Duplicati/Library/Common/IO/SystemIOWindows.cs +++ b/Duplicati/Library/Common/IO/SystemIOWindows.cs @@ -56,6 +56,85 @@ namespace Duplicati.Library.Common.IO return path.StartsWith(UNCPREFIX, StringComparison.Ordinal) ? path.Substring(UNCPREFIX.Length) : path; } + private class FileSystemAccess + { + public FileSystemRights Rights; + public AccessControlType ControlType; + public string SID; + public bool Inherited; + public InheritanceFlags Inheritance; + public PropagationFlags Propagation; + + public FileSystemAccess() + { + } + + public FileSystemAccess(FileSystemAccessRule rule) + { + Rights = rule.FileSystemRights; + ControlType = rule.AccessControlType; + SID = rule.IdentityReference.Value; + Inherited = rule.IsInherited; + Inheritance = rule.InheritanceFlags; + Propagation = rule.PropagationFlags; + } + + public FileSystemAccessRule Create(System.Security.AccessControl.FileSystemSecurity owner) + { + return (FileSystemAccessRule)owner.AccessRuleFactory( + new System.Security.Principal.SecurityIdentifier(SID), + (int)Rights, + Inherited, + Inheritance, + Propagation, + ControlType); + } + } + + private string SerializeObject(T o) + { + using (var tw = new System.IO.StringWriter()) + { + Newtonsoft.Json.JsonSerializer.Create(new Newtonsoft.Json.JsonSerializerSettings { Culture = System.Globalization.CultureInfo.InvariantCulture }).Serialize(tw, o); + tw.Flush(); + return tw.ToString(); + } + } + + private T DeserializeObject(string data) + { + using (var tr = new System.IO.StringReader(data)) + return (T)Newtonsoft.Json.JsonSerializer.Create(new Newtonsoft.Json.JsonSerializerSettings { Culture = System.Globalization.CultureInfo.InvariantCulture }).Deserialize(tr, typeof(T)); + + } + + private System.Security.AccessControl.FileSystemSecurity GetAccessControlDir(string path) + { + return PathTooLongFuncWrapper(System.IO.Directory.GetAccessControl, + Alphaleonis.Win32.Filesystem.Directory.GetAccessControl, path, true); + } + + private System.Security.AccessControl.FileSystemSecurity GetAccessControlFile(string path) + { + return PathTooLongFuncWrapper(System.IO.File.GetAccessControl, + Alphaleonis.Win32.Filesystem.File.GetAccessControl, path, true); + } + + private void SetAccessControlFile(string path, FileSecurity rules) + { + PathTooLongActionWrapper(p => System.IO.File.SetAccessControl(p, rules), + p => Alphaleonis.Win32.Filesystem.File.SetAccessControl(p, rules, AccessControlSections.All), + path, true); + } + + private void SetAccessControlDir(string path, DirectorySecurity rules) + { + PathTooLongActionWrapper(p => System.IO.Directory.SetAccessControl(p, rules), + p => Alphaleonis.Win32.Filesystem.Directory.SetAccessControl(p, rules, AccessControlSections.All), + path, true); + } + + private static void PathTooLongVoidFuncWrapper(Func nativeIOFunc, Func alternativeIOFunc, string path, bool prefixWithUnc = false) @@ -258,35 +337,6 @@ namespace Duplicati.Library.Common.IO path, true)); } - public string PathCombine(params string[] paths) - { - var combinedPath = ""; - for (int i = 0; i < paths.Length; i++) - { - if (i == 0) - { - combinedPath = paths[i]; - } - else - { - if (!IsPathTooLong(combinedPath + "\\" + paths[i])) - { - try - { - combinedPath = Path.Combine(combinedPath, paths[i]); - } - catch (Exception ex) when (ex is System.IO.PathTooLongException || ex is System.ArgumentException) - { - //TODO: Explain why we need to keep prefixing and stripping UNC's. - combinedPath = StripUNCPrefix(Alphaleonis.Win32.Filesystem.Path.Combine(PrefixWithUNC(combinedPath), paths[i])); - } - } - } - } - - return combinedPath; - } - public void DirectorySetLastWriteTimeUtc(string path, DateTime time) { PathTooLongActionWrapper(p => System.IO.Directory.SetLastWriteTimeUtc(p, time), @@ -332,138 +382,6 @@ namespace Duplicati.Library.Common.IO p => Alphaleonis.Win32.Filesystem.Directory.Delete(p, recursive), path, true); } - - private class FileSystemAccess - { - public FileSystemRights Rights; - public AccessControlType ControlType; - public string SID; - public bool Inherited; - public InheritanceFlags Inheritance; - public PropagationFlags Propagation; - - public FileSystemAccess() - { - } - - public FileSystemAccess(FileSystemAccessRule rule) - { - Rights = rule.FileSystemRights; - ControlType = rule.AccessControlType; - SID = rule.IdentityReference.Value; - Inherited = rule.IsInherited; - Inheritance = rule.InheritanceFlags; - Propagation = rule.PropagationFlags; - } - - public FileSystemAccessRule Create(System.Security.AccessControl.FileSystemSecurity owner) - { - return (FileSystemAccessRule)owner.AccessRuleFactory( - new System.Security.Principal.SecurityIdentifier(SID), - (int)Rights, - Inherited, - Inheritance, - Propagation, - ControlType); - } - } - - private string SerializeObject(T o) - { - using (var tw = new System.IO.StringWriter()) - { - Newtonsoft.Json.JsonSerializer.Create(new Newtonsoft.Json.JsonSerializerSettings { Culture = System.Globalization.CultureInfo.InvariantCulture }).Serialize(tw, o); - tw.Flush(); - return tw.ToString(); - } - } - - private T DeserializeObject(string data) - { - using (var tr = new System.IO.StringReader(data)) - return (T)Newtonsoft.Json.JsonSerializer.Create(new Newtonsoft.Json.JsonSerializerSettings { Culture = System.Globalization.CultureInfo.InvariantCulture }).Deserialize(tr, typeof(T)); - - } - - private System.Security.AccessControl.FileSystemSecurity GetAccessControlDir(string path) - { - return PathTooLongFuncWrapper(System.IO.Directory.GetAccessControl, - Alphaleonis.Win32.Filesystem.Directory.GetAccessControl, path, true); - } - - private System.Security.AccessControl.FileSystemSecurity GetAccessControlFile(string path) - { - return PathTooLongFuncWrapper(System.IO.File.GetAccessControl, - Alphaleonis.Win32.Filesystem.File.GetAccessControl, path, true); - } - - private void SetAccessControlFile(string path, FileSecurity rules) - { - PathTooLongActionWrapper(p => System.IO.File.SetAccessControl(p, rules), - p => Alphaleonis.Win32.Filesystem.File.SetAccessControl(p, rules, AccessControlSections.All), - path, true); - } - - private void SetAccessControlDir(string path, DirectorySecurity rules) - { - PathTooLongActionWrapper(p => System.IO.Directory.SetAccessControl(p, rules), - p => Alphaleonis.Win32.Filesystem.Directory.SetAccessControl(p, rules, AccessControlSections.All), - path, true); - } - - public Dictionary GetMetadata(string path, bool isSymlink, bool followSymlink) - { - var isDirTarget = path.EndsWith(DIRSEP, StringComparison.Ordinal); - var targetpath = isDirTarget ? path.Substring(0, path.Length - 1) : path; - var dict = new Dictionary(); - - FileSystemSecurity rules = isDirTarget ? GetAccessControlDir(targetpath) : GetAccessControlFile(targetpath); - var objs = new List(); - foreach (var f in rules.GetAccessRules(true, false, typeof(System.Security.Principal.SecurityIdentifier))) - objs.Add(new FileSystemAccess((FileSystemAccessRule)f)); - - dict["win-ext:accessrules"] = SerializeObject(objs); - - return dict; - } - - public void SetMetadata(string path, Dictionary data, bool restorePermissions) - { - var isDirTarget = path.EndsWith(DIRSEP, StringComparison.Ordinal); - var targetpath = isDirTarget ? path.Substring(0, path.Length - 1) : path; - - FileSystemSecurity rules = isDirTarget ? GetAccessControlDir(targetpath) : GetAccessControlFile(targetpath); - if (restorePermissions && data.ContainsKey("win-ext:accessrules")) - { - var content = DeserializeObject(data["win-ext:accessrules"]); - var c = rules.GetAccessRules(true, false, typeof(System.Security.Principal.SecurityIdentifier)); - for (var i = c.Count - 1; i >= 0; i--) - rules.RemoveAccessRule((System.Security.AccessControl.FileSystemAccessRule)c[i]); - - Exception ex = null; - - foreach (var r in content) - { - // Attempt to apply as many rules as we can - try - { - rules.AddAccessRule((System.Security.AccessControl.FileSystemAccessRule)r.Create(rules)); - } - catch (Exception e) - { - ex = e; - } - } - - if (ex != null) - throw ex; - - if (isDirTarget) - SetAccessControlDir(targetpath, (DirectorySecurity)rules); - else - SetAccessControlFile(targetpath, (FileSecurity)rules); - } - } public string GetPathRoot(string path) { @@ -548,8 +466,90 @@ namespace Duplicati.Library.Common.IO } return PathTooLongFuncWrapper(FileEntryNative, FileEntryAlphaFS, path, false); - } - + } + + public Dictionary GetMetadata(string path, bool isSymlink, bool followSymlink) + { + var isDirTarget = path.EndsWith(DIRSEP, StringComparison.Ordinal); + var targetpath = isDirTarget ? path.Substring(0, path.Length - 1) : path; + var dict = new Dictionary(); + + FileSystemSecurity rules = isDirTarget ? GetAccessControlDir(targetpath) : GetAccessControlFile(targetpath); + var objs = new List(); + foreach (var f in rules.GetAccessRules(true, false, typeof(System.Security.Principal.SecurityIdentifier))) + objs.Add(new FileSystemAccess((FileSystemAccessRule)f)); + + dict["win-ext:accessrules"] = SerializeObject(objs); + + return dict; + } + + public void SetMetadata(string path, Dictionary data, bool restorePermissions) + { + var isDirTarget = path.EndsWith(DIRSEP, StringComparison.Ordinal); + var targetpath = isDirTarget ? path.Substring(0, path.Length - 1) : path; + + FileSystemSecurity rules = isDirTarget ? GetAccessControlDir(targetpath) : GetAccessControlFile(targetpath); + if (restorePermissions && data.ContainsKey("win-ext:accessrules")) + { + var content = DeserializeObject(data["win-ext:accessrules"]); + var c = rules.GetAccessRules(true, false, typeof(System.Security.Principal.SecurityIdentifier)); + for (var i = c.Count - 1; i >= 0; i--) + rules.RemoveAccessRule((System.Security.AccessControl.FileSystemAccessRule)c[i]); + + Exception ex = null; + + foreach (var r in content) + { + // Attempt to apply as many rules as we can + try + { + rules.AddAccessRule((System.Security.AccessControl.FileSystemAccessRule)r.Create(rules)); + } + catch (Exception e) + { + ex = e; + } + } + + if (ex != null) + throw ex; + + if (isDirTarget) + SetAccessControlDir(targetpath, (DirectorySecurity)rules); + else + SetAccessControlFile(targetpath, (FileSecurity)rules); + } + } + + public string PathCombine(params string[] paths) + { + var combinedPath = ""; + for (int i = 0; i < paths.Length; i++) + { + if (i == 0) + { + combinedPath = paths[i]; + } + else + { + if (!IsPathTooLong(combinedPath + "\\" + paths[i])) + { + try + { + combinedPath = Path.Combine(combinedPath, paths[i]); + } + catch (Exception ex) when (ex is System.IO.PathTooLongException || ex is System.ArgumentException) + { + //TODO: Explain why we need to keep prefixing and stripping UNC's. + combinedPath = StripUNCPrefix(Alphaleonis.Win32.Filesystem.Path.Combine(PrefixWithUNC(combinedPath), paths[i])); + } + } + } + } + + return combinedPath; + } #endregion } } From 9ce8471bdec56b94c5129ba1e9e42490f8629b9d Mon Sep 17 00:00:00 2001 From: verhoek <30193551+verhoek@users.noreply.github.com> Date: Thu, 29 Nov 2018 09:32:42 +0100 Subject: [PATCH 3/4] Cache serializer. --- .../Library/Common/IO/SystemIOWindows.cs | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/Duplicati/Library/Common/IO/SystemIOWindows.cs b/Duplicati/Library/Common/IO/SystemIOWindows.cs index 0f8ddcc13..e7694a812 100644 --- a/Duplicati/Library/Common/IO/SystemIOWindows.cs +++ b/Duplicati/Library/Common/IO/SystemIOWindows.cs @@ -91,11 +91,29 @@ namespace Duplicati.Library.Common.IO } } + private static Newtonsoft.Json.JsonSerializer _cachedSerializer; + + private Newtonsoft.Json.JsonSerializer Serializer + { + get + { + if (_cachedSerializer != null) + { + return _cachedSerializer; + } + + _cachedSerializer = Newtonsoft.Json.JsonSerializer.Create( + new Newtonsoft.Json.JsonSerializerSettings { Culture = System.Globalization.CultureInfo.InvariantCulture }); + + return _cachedSerializer; + } + } + private string SerializeObject(T o) { using (var tw = new System.IO.StringWriter()) { - Newtonsoft.Json.JsonSerializer.Create(new Newtonsoft.Json.JsonSerializerSettings { Culture = System.Globalization.CultureInfo.InvariantCulture }).Serialize(tw, o); + Serializer.Serialize(tw, o); tw.Flush(); return tw.ToString(); } @@ -104,8 +122,9 @@ namespace Duplicati.Library.Common.IO private T DeserializeObject(string data) { using (var tr = new System.IO.StringReader(data)) - return (T)Newtonsoft.Json.JsonSerializer.Create(new Newtonsoft.Json.JsonSerializerSettings { Culture = System.Globalization.CultureInfo.InvariantCulture }).Deserialize(tr, typeof(T)); - + { + return (T)Serializer.Deserialize(tr, typeof(T)); + } } private System.Security.AccessControl.FileSystemSecurity GetAccessControlDir(string path) @@ -134,7 +153,6 @@ namespace Duplicati.Library.Common.IO path, true); } - private static void PathTooLongVoidFuncWrapper(Func nativeIOFunc, Func alternativeIOFunc, string path, bool prefixWithUnc = false) From e2c2bc1a79c4385673599c08a00cd95df24773e3 Mon Sep 17 00:00:00 2001 From: verhoek <30193551+verhoek@users.noreply.github.com> Date: Thu, 29 Nov 2018 09:37:10 +0100 Subject: [PATCH 4/4] Moved method to bottom to let the PathTooLong* methods group together. --- .../Library/Common/IO/SystemIOWindows.cs | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/Duplicati/Library/Common/IO/SystemIOWindows.cs b/Duplicati/Library/Common/IO/SystemIOWindows.cs index e7694a812..b48e7a8c1 100644 --- a/Duplicati/Library/Common/IO/SystemIOWindows.cs +++ b/Duplicati/Library/Common/IO/SystemIOWindows.cs @@ -273,26 +273,6 @@ namespace Duplicati.Library.Common.IO p => Alphaleonis.Win32.Filesystem.File.SetAttributes(p, attributes), path, true); } - public void CreateSymlink(string symlinkfile, string target, bool asDir) - { - if (FileExists(symlinkfile) || DirectoryExists(symlinkfile)) - throw new System.IO.IOException(string.Format("File already exists: {0}", symlinkfile)); - - Alphaleonis.Win32.Filesystem.File.CreateSymbolicLink(PrefixWithUNC(symlinkfile), - target, - asDir ? Alphaleonis.Win32.Filesystem.SymbolicLinkTarget.Directory : Alphaleonis.Win32.Filesystem.SymbolicLinkTarget.File, - AlphaFS.PathFormat.LongFullPath); - - //Sadly we do not get a notification if the creation fails :( - System.IO.FileAttributes attr = 0; - if ((!asDir && FileExists(symlinkfile)) || (asDir && DirectoryExists(symlinkfile))) - try { attr = GetFileAttributes(symlinkfile); } - catch { } - - if ((attr & System.IO.FileAttributes.ReparsePoint) == 0) - throw new System.IO.IOException(string.Format("Unable to create symlink, check account permissions: {0}", symlinkfile)); - } - /// /// Returns the symlink target if the entry is a symlink, and null otherwise /// @@ -568,6 +548,26 @@ namespace Duplicati.Library.Common.IO return combinedPath; } + + public void CreateSymlink(string symlinkfile, string target, bool asDir) + { + if (FileExists(symlinkfile) || DirectoryExists(symlinkfile)) + throw new System.IO.IOException(string.Format("File already exists: {0}", symlinkfile)); + + Alphaleonis.Win32.Filesystem.File.CreateSymbolicLink(PrefixWithUNC(symlinkfile), + target, + asDir ? Alphaleonis.Win32.Filesystem.SymbolicLinkTarget.Directory : Alphaleonis.Win32.Filesystem.SymbolicLinkTarget.File, + AlphaFS.PathFormat.LongFullPath); + + //Sadly we do not get a notification if the creation fails :( + System.IO.FileAttributes attr = 0; + if ((!asDir && FileExists(symlinkfile)) || (asDir && DirectoryExists(symlinkfile))) + try { attr = GetFileAttributes(symlinkfile); } + catch { } + + if ((attr & System.IO.FileAttributes.ReparsePoint) == 0) + throw new System.IO.IOException(string.Format("Unable to create symlink, check account permissions: {0}", symlinkfile)); + } #endregion } }