Esempio n. 1
0
        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;
                }
            }
        }
Esempio n. 2
0
        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;
            }
        }
Esempio n. 3
0
            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();
            }
Esempio n. 4
0
        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);
            }
        }
Esempio n. 5
0
        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;
        }
Esempio n. 6
0
        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;
            }
        }
Esempio n. 7
0
        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;
                }
            }
        }
Esempio n. 8
0
        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();
            }
        }
Esempio n. 9
0
        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);
        }