private void btnMount_Click(object sender, EventArgs e) { VssSnapshotProperties snapshot = GetVssSnapshotFromTime(DateTime.Parse(lvRestorePoints.Items[lvRestorePoints.SelectedIndices[0]].Text)); if (snapshot != null) { string[] path = snapshot.SnapshotDeviceObject.Split('\\'); string mountPoint = systemDrive + path[path.Length - 1]; // Create the hardlink bool symResult = VolumeNativeMethods.CreateSymbolicLink(mountPoint, snapshot.SnapshotDeviceObject + @"\", 1); if (symResult) { // Start explorer at the mount point ProcessStartInfo explorer = new System.Diagnostics.ProcessStartInfo(); explorer.FileName = "explorer.exe"; explorer.Arguments = mountPoint; Process.Start(explorer); btnMount.Enabled = false; btnUnmount.Enabled = true; tsmiMount.Enabled = false; tsmiUnmount.Enabled = true; } } }
private void CreateVssSnapshotOfSystemVolume(IVssBackupComponents backupComponents) { try { logger.LogInformation($"Creating VSS snapshot for drive {migrationData.OperatingSystemDriveLetter}:\\"); backupComponents.InitializeForBackup(null); backupComponents.GatherWriterMetadata(); backupComponents.SetContext(VssVolumeSnapshotAttributes.Persistent | VssVolumeSnapshotAttributes.NoAutoRelease); this.vssSnapshotSetId = backupComponents.StartSnapshotSet(); this.vssSnapshotId = backupComponents.AddToSnapshotSet($"{migrationData.OperatingSystemDriveLetter}:\\"); backupComponents.SetBackupState(false, true, VssBackupType.Differential, false); backupComponents.PrepareForBackup(); backupComponents.DoSnapshotSet(); VssSnapshotProperties snapshotInfo = backupComponents.GetSnapshotProperties(this.vssSnapshotId); logger.LogDebug($"VSS snapshot created. Root Path: {snapshotInfo.SnapshotDeviceObject}"); } catch (Exception ex) { logger.LogError(ex, "An error occured during VSS snapshot creation"); if (this.vssSnapshotId != Guid.Empty) { backupComponents.DeleteSnapshot(this.vssSnapshotId, true); this.vssSnapshotId = Guid.Empty; this.vssSnapshotSetId = Guid.Empty; } throw; } }
private void Initialize(string Volume, bool IncludeBootableSystemState) { //string filename = @"C:\Windows\system32\config\sam"; //FileInfo fiSource = new FileInfo(filename); //String Volume = fiSource.Directory.Root.Name; // VSS step 1: Initialize IVssImplementation vss = VssUtils.LoadImplementation(); IVssBackupComponents backup = vss.CreateVssBackupComponents(); backup.InitializeForBackup(null); // VSS step 2: Getting Metadata from all the VSS writers backup.GatherWriterMetadata(); // VSS step 3: VSS Configuration backup.SetContext((VssVolumeSnapshotAttributes)0); backup.SetBackupState(false, IncludeBootableSystemState, Alphaleonis.Win32.Vss.VssBackupType.Full, false); // VSS step 4: Declaring the Volumes that we need to use in this beckup. // The Snapshot is a volume element (hence the name "Volume Shadow-Copy"). // For each file that we nee to copy we have to make sure that the proper volume is included in the "Snapshot Set". Guid SetGuid = backup.StartSnapshotSet(); Guid VolumeGuid = backup.AddToSnapshotSet(Volume, Guid.Empty); // VSS step 5: Preparation (Writers & Provaiders need to start preparation) backup.PrepareForBackup(); // VSS step 6: Create a Snapshot For each volume in the "Snapshot Set" backup.DoSnapshotSet(); /*********************************** * /* At this point we have a snapshot! * /* This action should not take more then 60 second, regardless of file or disk size. * /* The snapshot is not a backup or any copy! * /* please more information at http://technet.microsoft.com/en-us/library/ee923636.aspx * /***********************************/ // VSS step 7: Expose Snapshot /*********************************** * /* Snapshot path look like: * \\?\Volume{011682bf-23d7-11e2-93e7-806e6f6e6963}\ * The build in method System.IO.File.Copy do not work with path like this, * Therefore, we are going to Expose the Snapshot to our application, * by mapping the Snapshot to new virtual volume * - Make sure that you are using a volume that is not already exist * - This is only for learning purposes. usually we will use the snapshot directly as i show in the next example in the blog * /***********************************/ VssSnapshotProperties SnapshotProperties = backup.GetSnapshotProperties(VolumeGuid); DirectoryInfo diShadowRoot = new DirectoryInfo(SnapshotProperties.SnapshotDeviceObject); DirectoryInfo[] Folders = diShadowRoot.GetDirectories(); }
private void RemoveVssSnapshotOfSystemVolume(IVssBackupComponents backupComponents) { if (this.vssSnapshotId != Guid.Empty) { try { backupComponents.BackupComplete(); } catch (VssBadStateException) { } VssSnapshotProperties snapshotInfo = backupComponents.GetSnapshotProperties(this.vssSnapshotId); logger.LogDebug($"Removing snapshot {snapshotInfo.SnapshotDeviceObject}"); backupComponents.DeleteSnapshot(this.vssSnapshotId, true); } }
public override void PerformStep() { logger.LogInformation("Cloning operating system."); using (IVssBackupComponents backupComponents = vss.CreateVssBackupComponents()) { this.CreateVssSnapshotOfSystemVolume(backupComponents); try { logger.LogInformation("Copying system partition data..."); using (PrivilegeEnabler privEnabler = new PrivilegeEnabler(Privilege.Backup, Privilege.Restore)) { VssSnapshotProperties snapshotInfo = backupComponents.GetSnapshotProperties(this.vssSnapshotId); using (Stream rawVolStream = this.fileSystemHelper.OpenRawDiskStream(snapshotInfo.SnapshotDeviceObject)) { string vhdFullName = $"{migrationData.VhdFileTemporaryFolder}\\{migrationData.VhdFileName}"; using (VirtualDiskDecorator disk = this.fileSystemHelper.OpenVhdx(vhdFullName)) { var partitionTable = disk.Partitions; if (partitionTable != null) { int partIndex = partitionTable.CreatePrimaryBySector(1, (rawVolStream.Length / disk.Geometry.BytesPerSector), BiosPartitionTypes.Ntfs, false); PartitionInfoDecorator partition = disk.Partitions[partIndex]; using (var vhdPartitionStream = partition.Open()) { this.fileSystemHelper.CloneNtfsFileSystem(rawVolStream, vhdPartitionStream, logger); } } else { logger.LogError("VHD disk does not contain BIOS partition table. Other partitions tables are not supported."); } } } } } finally { this.RemoveVssSnapshotOfSystemVolume(backupComponents); //always remove the VSS snapshot, either after success or failure } logger.LogInformation("Cloning operating system completed."); } return; }
private void btnUnmount_Click(object sender, EventArgs e) { VssSnapshotProperties snapshot = GetVssSnapshotFromTime(DateTime.Parse(lvRestorePoints.Items[lvRestorePoints.SelectedIndices[0]].Text)); if (snapshot != null) { string[] path = snapshot.SnapshotDeviceObject.Split('\\'); string mountPoint = systemDrive + path[path.Length - 1]; Directory.Delete(mountPoint); btnMount.Enabled = true; btnUnmount.Enabled = false; tsmiMount.Enabled = true; tsmiUnmount.Enabled = false; } }
private void lvRestorePoints_SelectedIndexChanged(object sender, EventArgs e) { if (lvRestorePoints.SelectedItems.Count > 0) { btnDelete.Enabled = true; try { VssSnapshotProperties snapshot = GetVssSnapshotFromTime(DateTime.Parse(lvRestorePoints.Items[lvRestorePoints.SelectedIndices[0]].Text)); if (snapshot != null) { string[] path = snapshot.SnapshotDeviceObject.Split('\\'); string mountPoint = systemDrive + path[path.Length - 1]; if (Directory.Exists(mountPoint)) { btnMount.Enabled = false; btnUnmount.Enabled = true; tsmiMount.Enabled = false; tsmiUnmount.Enabled = true; } else { btnMount.Enabled = true; btnUnmount.Enabled = false; tsmiMount.Enabled = true; tsmiUnmount.Enabled = false; } } } catch (Exception) { btnMount.Enabled = true; btnUnmount.Enabled = false; tsmiMount.Enabled = true; tsmiUnmount.Enabled = false; } } }
private static void Zip() { Log2 vssLog = new Log2(nameof(AddonsBackup) + " - VSS Service"); // get free drive letter string driveLetter = new string[] { "P:", "Q:", "R:", "S:", "T:", "U:", "V:", "W:" }.FirstOrDefault(l => !DriveInfo.GetDrives().Select(m => m.RootDirectory.Name).Contains(l)); if (driveLetter == default(string)) { throw new IOException("Can't find free drive letter!"); } vssLog.Info($"Free drive letter: {driveLetter}"); // making VSS snapshot IVssImplementation vssImplementation = VssUtils.LoadImplementation(); IVssBackupComponents backupComponents = vssImplementation.CreateVssBackupComponents(); backupComponents.InitializeForBackup(null); vssLog.Info("VssBackupComponents is initialized"); Guid backupGuid1 = Guid.Empty; try { backupComponents.GatherWriterMetadata(); backupComponents.SetContext(VssVolumeSnapshotAttributes.Persistent | VssVolumeSnapshotAttributes.NoAutoRelease); backupComponents.SetBackupState(false, true, VssBackupType.Full, false); vssLog.Info("VssBackupComponents is set up"); backupComponents.StartSnapshotSet(); backupGuid1 = backupComponents.AddToSnapshotSet(new DirectoryInfo(_settings.WoWDirectory).Root.Name, Guid.Empty); backupComponents.PrepareForBackup(); backupComponents.DoSnapshotSet(); vssLog.Info("Snapshot is taken"); backupComponents.ExposeSnapshot(backupGuid1, null, VssVolumeSnapshotAttributes.ExposedLocally, driveLetter); // zipping string zipPath = $"{_settings.WoWAddonsBackupPath}\\AddonsBackup_{DateTime.UtcNow:yyyyMMdd_HHmmss}.zip"; log.Info("Zipping to file: " + zipPath); using (ZipFile zip = new ZipFile(zipPath, Encoding.UTF8)) { zip.CompressionLevel = (CompressionLevel)_settings.WoWAddonsBackupCompressionLevel; foreach (string dirName in FoldersToArchive) { zip.AddDirectory(_settings.WoWDirectory.Replace(new DirectoryInfo(_settings.WoWDirectory).Root.Name, $"{driveLetter}\\") + "\\" + dirName, "\\" + dirName); } zip.SaveProgress += AddonsBackup_SaveProgress; var processPriority = Process.GetCurrentProcess().PriorityClass; Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.BelowNormal; zip.Save(); Process.GetCurrentProcess().PriorityClass = processPriority; zip.SaveProgress -= AddonsBackup_SaveProgress; } } finally { VssSnapshotProperties existingSnapshot = backupComponents.QuerySnapshots().FirstOrDefault(l => l.SnapshotId == backupGuid1); if (existingSnapshot == default(VssSnapshotProperties)) { vssLog.Error($"Can't delete snapshot {backupGuid1}"); } else { backupComponents.DeleteSnapshot(existingSnapshot.SnapshotId, true); backupComponents.Dispose(); vssLog.Info($"Snapshot is deleted ({existingSnapshot.SnapshotId})"); } GC.Collect(); } }
public void PerformStepTest_ShouldDeleteSnapshotOnError() { //arrange MigrationFlowData flowData = new MigrationFlowData(); flowData.VhdFileTemporaryFolder = "temporary\\folder"; flowData.OperatingSystemDriveLetter = 'C'; flowData.VhdFileName = "test.vhdx"; Mock <VirtualDiskDecorator> diskMock = new Mock <VirtualDiskDecorator>(); Mock <BiosPartitionTableDecorator> partitionTableMock = new Mock <BiosPartitionTableDecorator>(); diskMock.Setup(x => x.Partitions) .Returns(partitionTableMock.Object); MemoryStream streamMock = new MemoryStream(); StreamWriter swMock = new StreamWriter(streamMock); VssSnapshotProperties fakeSnapshotDetails = new VssSnapshotProperties(Guid.NewGuid(), Guid.NewGuid(), 1, "snapshotDeviceObject", "C:", "unit-testing", "unit-testing", null, null, Guid.NewGuid(), VssVolumeSnapshotAttributes.Differential, DateTime.Now, VssSnapshotState.Created); this.vssBackupComponentsMock.Setup(x => x.InitializeForBackup(It.IsAny <string>())).Verifiable(); this.vssBackupComponentsMock.Setup(x => x.GatherWriterMetadata()).Verifiable(); this.vssBackupComponentsMock.Setup(x => x.SetContext(It.IsAny <VssVolumeSnapshotAttributes>())).Verifiable(); this.vssBackupComponentsMock.Setup(x => x.StartSnapshotSet()) .Returns(fakeSnapshotDetails.SnapshotSetId) .Verifiable(); this.vssBackupComponentsMock.Setup(x => x.AddToSnapshotSet(It.Is <string>((param) => param == $"{flowData.OperatingSystemDriveLetter}:\\"))) .Returns(fakeSnapshotDetails.SnapshotId) .Verifiable(); this.vssBackupComponentsMock.Setup(x => x.PrepareForBackup()).Verifiable(); this.vssBackupComponentsMock.Setup(x => x.DoSnapshotSet()) .Throws <Exception>() .Verifiable(); this.vssBackupComponentsMock.Setup(x => x.DeleteSnapshot(It.Is <Guid>((snapshotId) => snapshotId == fakeSnapshotDetails.SnapshotId), It.IsAny <bool>())).Verifiable(); this.vssBackupComponentsMock.Setup(x => x.GetSnapshotProperties(It.Is <Guid>((snapshotId) => snapshotId == fakeSnapshotDetails.SnapshotId))) .Returns(fakeSnapshotDetails) .Verifiable(); this.fileSystemHelperMock.Setup(x => x.OpenRawDiskStream(It.Is <string>(snapshotPath => snapshotPath == fakeSnapshotDetails.SnapshotDeviceObject))) .Returns(streamMock) .Verifiable(); this.fileSystemHelperMock.Setup(x => x.OpenVhdx(It.Is <string>(snapshotPath => snapshotPath == $"{flowData.VhdFileTemporaryFolder}\\{flowData.VhdFileName}"))) .Returns(diskMock.Object) .Verifiable(); this.fileSystemHelperMock.Setup(x => x.CloneNtfsFileSystem(It.IsAny <Stream>(), It.IsAny <Stream>(), It.IsAny <ILogger>())) .Verifiable(); CloneOSMigrationStep step = new CloneOSMigrationStep(loggerMock.Object, osHelperMock.Object, fileSystemHelperMock.Object, flowData, vssImplementationMock.Object); //act Assert.Throws <Exception>(() => { step.PerformStep(); }); swMock.Dispose(); //assert this.vssBackupComponentsMock.Verify(x => x.InitializeForBackup(It.IsAny <string>()), Times.Once); this.vssBackupComponentsMock.Verify(x => x.GatherWriterMetadata(), Times.Once); this.vssBackupComponentsMock.Verify(x => x.SetContext(It.IsAny <VssVolumeSnapshotAttributes>()), Times.Once); this.vssBackupComponentsMock.Verify(x => x.StartSnapshotSet(), Times.Once); this.vssBackupComponentsMock.Verify(x => x.AddToSnapshotSet(It.Is <string>((param) => param == $"{flowData.OperatingSystemDriveLetter}:\\")), Times.Once); this.vssBackupComponentsMock.Verify(x => x.PrepareForBackup(), Times.Once); this.vssBackupComponentsMock.Verify(x => x.DoSnapshotSet(), Times.Once); this.vssBackupComponentsMock.Verify(x => x.DeleteSnapshot(It.Is <Guid>((snapshotId) => snapshotId == fakeSnapshotDetails.SnapshotId), It.IsAny <bool>()), Times.Once); this.fileSystemHelperMock.Verify(x => x.OpenVhdx(It.Is <string>(snapshotPath => snapshotPath == $"{flowData.VhdFileTemporaryFolder}\\{flowData.VhdFileName}")), Times.Never); this.fileSystemHelperMock.Verify(x => x.CloneNtfsFileSystem(It.IsAny <Stream>(), It.IsAny <Stream>(), It.IsAny <ILogger>()), Times.Never); }
/// <summary> /// Makes a recursive snapshot of the directory as it is. /// </summary> /// <param name="baseDirectory">The directory to start in.</param> /// <returns>A file system snapshot</returns> public static SnapshotFilesystem MakeFsSnapshot(System.IO.DirectoryInfo baseDirectory) { DirectoryInfo baseDir = new DirectoryInfo(baseDirectory.FullName); if (!baseDir.Exists) { throw new ArgumentException("Base directory doesn't exist"); } SnapshotFilesystem res = new SnapshotFilesystem(); if (!baseDir.FullName.EndsWith(Path.DirectorySeparatorChar) && !baseDir.FullName.EndsWith(Path.AltDirectorySeparatorChar)) { // Add ending slash to get a uniform output baseDir = new DirectoryInfo(baseDir.FullName + Path.DirectorySeparatorChar); } res.BasePath = baseDir.FullName; res.Items = new LinkedList <SnapshotFilesystemItem>(); // Make VSS // Sequence of calls: http://us.generation-nt.com/answer/volume-shadow-copy-backupcomplete-vss-e-bad-state-help-29094302.html IVssImplementation vssImplementation = VssUtils.LoadImplementation(); IVssBackupComponents backupComponents = vssImplementation.CreateVssBackupComponents(); backupComponents.InitializeForBackup(null); backupComponents.SetContext(VssSnapshotContext.Backup); backupComponents.SetBackupState(false, false, VssBackupType.Copy, false); backupComponents.GatherWriterMetadata(); try { Guid snapshotSetGuid = backupComponents.StartSnapshotSet(); Guid backupVolumeGuid = backupComponents.AddToSnapshotSet(baseDir.Root.FullName); backupComponents.PrepareForBackup(); backupComponents.DoSnapshotSet(); VssSnapshotProperties properties = backupComponents.GetSnapshotProperties(backupVolumeGuid); DirectoryInfo shadowCopyBase = new DirectoryInfo(Path.Combine(properties.SnapshotDeviceObject, Path.GetDirectoryNameWithoutRoot(baseDir.FullName))); if (!shadowCopyBase.FullName.EndsWith(Path.DirectorySeparatorChar) && !shadowCopyBase.FullName.EndsWith(Path.AltDirectorySeparatorChar)) { // Add ending slash to get a uniform output shadowCopyBase = new DirectoryInfo(shadowCopyBase.FullName + Path.DirectorySeparatorChar); } // Do stuff DoFsSnapshot(shadowCopyBase, shadowCopyBase, res.Items); // Delete snapshot backupComponents.BackupComplete(); backupComponents.DeleteSnapshotSet(snapshotSetGuid, false); } catch (Exception) { backupComponents.AbortBackup(); } //DoFsSnapshot(baseDirectory, baseDirectory, res.Items); return(res); }