From 1bf1daa189acd5aa21fb3c13bfdcccf992b05a30 Mon Sep 17 00:00:00 2001
From: verhoek <30193551+verhoek@users.noreply.github.com>
Date: Sat, 27 Oct 2018 12:29:39 +0200
Subject: [PATCH] Moved alphaleonis stuff to VSS wrapper objects in Libary.IO.
---
.../Library/Snapshots/WindowsSnapshot.cs | 171 ++----------------
1 file changed, 18 insertions(+), 153 deletions(-)
diff --git a/Duplicati/Library/Snapshots/WindowsSnapshot.cs b/Duplicati/Library/Snapshots/WindowsSnapshot.cs
index c209e900a..ff478da1b 100644
--- a/Duplicati/Library/Snapshots/WindowsSnapshot.cs
+++ b/Duplicati/Library/Snapshots/WindowsSnapshot.cs
@@ -1,4 +1,4 @@
-#region Disclaimer / License
+#region Disclaimer / License
// Copyright (C) 2015, The Duplicati Team
// http://www.duplicati.com, info@duplicati.com
//
@@ -23,7 +23,6 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
-using Alphaleonis.Win32.Vss;
using Duplicati.Library.IO;
namespace Duplicati.Library.Snapshots
@@ -45,35 +44,7 @@ namespace Duplicati.Library.Snapshots
///
/// The main reference to the backup controller
///
- private IVssBackupComponents m_backup;
-
- ///
- /// The list of snapshot ids for each volume, key is the path root, eg C:\.
- /// The dictionary is case insensitive
- ///
- private readonly Dictionary m_volumes;
-
- ///
- /// The mapping of snapshot sources to their snapshot entries , key is the path root, eg C:\.
- /// The dictionary is case insensitive
- ///
- private readonly Dictionary m_volumeMap;
-
- ///
- /// The mapping of snapshot sources to their snapshot entries , key is the path root, eg C:\.
- /// The dictionary is case insensitive
- ///
- private readonly Dictionary m_volumeReverseMap;
-
- ///
- /// A list of mapped drives
- ///
- private List m_mappedDrives;
-
- ///
- /// Commonly used string element
- ///
- private static string SLASH = Path.DirectorySeparatorChar.ToString();
+ private VssBackupComponents _vssBackupComponents;
///
/// Constructs a new backup snapshot, using all the required disks
@@ -85,10 +56,9 @@ namespace Duplicati.Library.Snapshots
try
{
//Prepare the backup
- m_backup = SystemIOWindows.CreateVssBackupComponents();
- m_backup.InitializeForBackup(null);
- m_backup.SetContext(VssSnapshotContext.Backup);
- m_backup.SetBackupState(false, true, VssBackupType.Full, false);
+ //m_backup = VssBackupComponentsHelper.GetVssBackupComponents();
+ _vssBackupComponents = new VssBackupComponents();
+
// Default to exclude the System State writer
var excludedWriters = new Guid[] { new Guid("{e8132975-6f93-4464-a53e-1050253ae220}") };
@@ -100,68 +70,16 @@ namespace Duplicati.Library.Snapshots
.Select(x => new Guid(x))
.ToArray();
}
+ _vssBackupComponents.SetupWriters(null, excludedWriters);
- if (excludedWriters.Length > 0)
- m_backup.DisableWriterClasses(excludedWriters.ToArray());
-
- try
- {
- m_backup.GatherWriterMetadata();
- }
- finally
- {
- m_backup.FreeWriterMetadata();
- }
+ _vssBackupComponents.InitShadowVolumes(sources);
- m_backup.StartSnapshotSet();
-
- //Figure out which volumes are in the set
- m_volumes = new Dictionary(StringComparer.OrdinalIgnoreCase);
- foreach (var s in sources)
- {
- var drive = SystemIO.IO_WIN.GetPathRoot(s);
- if (!m_volumes.ContainsKey(drive))
- {
- //TODO: that seems a bit harsh... we could fall-back to not using VSS for that volume only
- if (!m_backup.IsVolumeSupported(drive))
- throw new VssVolumeNotSupportedException(drive);
-
- m_volumes.Add(drive, m_backup.AddToSnapshotSet(drive));
- }
- }
-
- //Make all writers aware that we are going to do the backup
- m_backup.PrepareForBackup();
-
- //Create the shadow volumes
- m_backup.DoSnapshotSet();
-
- //Make a little lookup table for faster translation
- m_volumeMap = new Dictionary(StringComparer.OrdinalIgnoreCase);
- foreach (var kvp in m_volumes)
- {
- m_volumeMap.Add(kvp.Key, m_backup.GetSnapshotProperties(kvp.Value).SnapshotDeviceObject);
- }
-
- m_volumeReverseMap = m_volumeMap.ToDictionary(x => x.Value, x => x.Key);
+ _vssBackupComponents.MapVolumesToSnapShots();
//If we should map the drives, we do that now and update the volumeMap
if (Utility.Utility.ParseBoolOption(options, "vss-use-mapping"))
{
- m_mappedDrives = new List();
- foreach (var k in new List(m_volumeMap.Keys))
- {
- try
- {
- DefineDosDevice d;
- m_mappedDrives.Add(d = new DefineDosDevice(m_volumeMap[k]));
- m_volumeMap[k] = Utility.Utility.AppendDirSeparator(d.Drive);
- }
- catch(Exception ex)
- {
- Logging.Log.WriteVerboseMessage(LOGTAG, "SubstMappingfailed", ex, "Failed to map VSS path {0} to drive", k);
- }
- }
+ _vssBackupComponents.MapDrives();
}
}
catch
@@ -190,8 +108,8 @@ namespace Duplicati.Library.Snapshots
/// A list of non-shadow paths
protected override string[] ListFolders(string localFolderPath)
{
- var root = Utility.Utility.AppendDirSeparator(SystemIO.IO_WIN.GetPathRoot(localFolderPath));
- var volumePath = Utility.Utility.AppendDirSeparator(ConvertToSnapshotPath(root));
+ var root = Util.AppendDirSeparator(SystemIO.IO_WIN.GetPathRoot(localFolderPath));
+ var volumePath = Util.AppendDirSeparator(ConvertToSnapshotPath(root));
string[] tmp = null;
var spath = ConvertToSnapshotPath(localFolderPath);
@@ -233,8 +151,8 @@ namespace Duplicati.Library.Snapshots
/// A list of non-shadow paths
protected override string[] ListFiles(string localFolderPath)
{
- var root = Utility.Utility.AppendDirSeparator(SystemIO.IO_WIN.GetPathRoot(localFolderPath));
- var volumePath = Utility.Utility.AppendDirSeparator(ConvertToSnapshotPath(root));
+ var root = Util.AppendDirSeparator(SystemIO.IO_WIN.GetPathRoot(localFolderPath));
+ var volumePath = Util.AppendDirSeparator(ConvertToSnapshotPath(root));
string[] tmp = null;
var spath = ConvertToSnapshotPath(localFolderPath);
@@ -381,7 +299,7 @@ namespace Duplicati.Library.Snapshots
if (!Path.IsPathRooted(snapshotPath))
throw new InvalidOperationException();
- foreach (var kvp in m_volumeReverseMap)
+ foreach (var kvp in _vssBackupComponents.SnapshotDeviceAndVolumes)
{
if (snapshotPath.StartsWith(kvp.Key, Utility.Utility.ClientFilenameStringComparison))
return Path.Combine(kvp.Value, snapshotPath.Substring(kvp.Key.Length));
@@ -397,14 +315,13 @@ namespace Duplicati.Library.Snapshots
throw new InvalidOperationException();
var root = SystemIO.IO_WIN.GetPathRoot(localPath);
- if (!m_volumeMap.TryGetValue(root, out var volumePath))
- throw new InvalidOperationException();
+ var volumePath = _vssBackupComponents.GetVolumeFromCache(root);
// Note: Do NOT use Path.Combine as it strips the UNC path prefix
var subPath = localPath.Substring(root.Length);
- if (!subPath.StartsWith(SLASH, StringComparison.Ordinal))
+ if (!subPath.StartsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal))
{
- volumePath = Duplicati.Library.Utility.Utility.AppendDirSeparator(volumePath, SLASH);
+ volumePath = IO.Util.AppendDirSeparator(volumePath, Path.DirectorySeparatorChar.ToString());
}
var mappedPath = volumePath + subPath;
@@ -433,59 +350,7 @@ namespace Duplicati.Library.Snapshots
{
if (disposing)
{
- try
- {
- if (m_mappedDrives != null)
- {
- foreach (var d in m_mappedDrives)
- {
- d.Dispose();
- }
-
- m_mappedDrives = null;
- }
- }
- catch (Exception ex)
- {
- Logging.Log.WriteVerboseMessage(LOGTAG, "MappedDriveCleanupError", ex, "Failed during VSS mapped drive unmapping");
- }
-
- try
- {
- m_backup?.BackupComplete();
- }
- catch (Exception ex)
- {
- Logging.Log.WriteVerboseMessage(LOGTAG, "VSSTerminateError", ex, "Failed to signal VSS completion");
- }
-
- try
- {
- if (m_backup != null)
- {
- foreach (var g in m_volumes.Values)
- {
- try
- {
- m_backup.DeleteSnapshot(g, false);
- }
- catch (Exception ex)
- {
- Logging.Log.WriteVerboseMessage(LOGTAG, "VSSSnapShotDeleteError", ex, "Failed to close VSS snapshot");
- }
- }
- }
- }
- catch (Exception ex)
- {
- Logging.Log.WriteVerboseMessage(LOGTAG, "VSSSnapShotDeleteCleanError", ex, "Failed during VSS esnapshot closing");
- }
-
- if (m_backup != null)
- {
- m_backup.Dispose();
- m_backup = null;
- }
+ _vssBackupComponents.Dispose();
}
base.Dispose(disposing);