diff options
author | Kenneth Skovhede <kenneth@hexad.dk> | 2018-06-30 19:50:06 +0300 |
---|---|---|
committer | Kenneth Skovhede <kenneth@hexad.dk> | 2018-06-30 19:50:06 +0300 |
commit | 06d6352aca385fd0d1bfb3dfef6501dc2998478e (patch) | |
tree | fc350d7d80174bfaed26405d81db2647a933c30d /Duplicati/Library/Snapshots/WindowsSnapshot.cs | |
parent | 9bfcab73bca138e2c8a83d067e2f1c3733577eec (diff) |
Tested and fixed the VSS mapping problem caused by using `Path.Combine` with a `\?\\GLOBALROOT\` prefixed path.
Diffstat (limited to 'Duplicati/Library/Snapshots/WindowsSnapshot.cs')
-rw-r--r-- | Duplicati/Library/Snapshots/WindowsSnapshot.cs | 47 |
1 files changed, 32 insertions, 15 deletions
diff --git a/Duplicati/Library/Snapshots/WindowsSnapshot.cs b/Duplicati/Library/Snapshots/WindowsSnapshot.cs index 542376b9d..29b7fbc26 100644 --- a/Duplicati/Library/Snapshots/WindowsSnapshot.cs +++ b/Duplicati/Library/Snapshots/WindowsSnapshot.cs @@ -76,6 +76,11 @@ namespace Duplicati.Library.Snapshots private static SystemIOWindows IO_WIN = new SystemIOWindows();
/// <summary>
+ /// Commonly used string element
+ /// </summary>
+ private static string SLASH = Path.DirectorySeparatorChar.ToString();
+
+ /// <summary>
/// Constructs a new backup snapshot, using all the required disks
/// </summary>
/// <param name="sources">Sources to determine which volumes to include in snapshot</param>
@@ -399,21 +404,33 @@ namespace Duplicati.Library.Snapshots throw new InvalidOperationException();
}
+ /// <summary>
+ /// Cache element to speed up returning the same paths
+ /// </summary>
+ private KeyValuePair<string, string> m_lastLookup;
+
/// <inheritdoc />
public override string ConvertToSnapshotPath(string localPath)
{
+ // Hot cache, we tend to call the same conversion multiple times
+ var m = m_lastLookup;
+ if (m.Key == localPath)
+ return m.Value;
+
if (!Path.IsPathRooted(localPath))
throw new InvalidOperationException();
var root = AlphaFS.Path.GetPathRoot(localPath);
-
if (!m_volumeMap.TryGetValue(root, out var volumePath))
throw new InvalidOperationException();
- var mappedPath = IO_WIN.PathCombine(volumePath, localPath.Substring(root.Length));
- if (localPath.EndsWith("\\", StringComparison.Ordinal))
- return Library.Utility.Utility.AppendDirSeparator(mappedPath);
+ // Note: Do NOT use Path.Combine as it strips the UNC path prefix
+ var subPath = localPath.Replace(root, String.Empty);
+ if (!volumePath.EndsWith(SLASH, StringComparison.Ordinal) && !subPath.StartsWith(SLASH, StringComparison.Ordinal))
+ subPath = subPath.Insert(0, SLASH);
+ var mappedPath = subPath.Insert(0, volumePath);
+ m_lastLookup = new KeyValuePair<string, string>(localPath, mappedPath);
return mappedPath;
}
@@ -454,13 +471,13 @@ namespace Duplicati.Library.Snapshots catch (Exception ex)
{
Logging.Log.WriteVerboseMessage(LOGTAG, "MappedDriveCleanupError", ex, "Failed during VSS mapped drive unmapping");
- } - - try - { - m_backup?.BackupComplete(); + }
+
+ try
+ {
+ m_backup?.BackupComplete();
}
- catch (Exception ex) + catch (Exception ex)
{
Logging.Log.WriteVerboseMessage(LOGTAG, "VSSTerminateError", ex, "Failed to signal VSS completion");
}
@@ -470,12 +487,12 @@ namespace Duplicati.Library.Snapshots if (m_backup != null)
{
foreach (var g in m_volumes.Values)
- { - try - { - m_backup.DeleteSnapshot(g, false); + {
+ try
+ {
+ m_backup.DeleteSnapshot(g, false);
}
- catch (Exception ex) + catch (Exception ex)
{
Logging.Log.WriteVerboseMessage(LOGTAG, "VSSSnapShotDeleteError", ex, "Failed to close VSS snapshot");
}
|