public override void PerformStep() { logger.LogInformation("Fixing cloned OS registry."); string vhdFullName = $"{migrationData.VhdFileTemporaryFolder}\\{migrationData.VhdFileName}"; using (VirtualDiskDecorator disk = this.fileSystemHelper.OpenVhdx(vhdFullName)) { PartitionInfoDecorator clonedPartition = disk.Partitions[0]; using (Stream partitionStream = clonedPartition.Open()) { using (DiscFileSystem ntfs = this.fileSystemHelper.OpenNtfsFileSystem(partitionStream)) { if (ntfs is NtfsFileSystem) { (ntfs as NtfsFileSystem).NtfsOptions.HideSystemFiles = false; (ntfs as NtfsFileSystem).NtfsOptions.HideHiddenFiles = false; } // removes not necessary files from the image // Remove VSS snapshot files (can be very large) foreach (string filePath in ntfs.GetFiles(@"\System Volume Information", "*{3808876B-C176-4e48-B7AE-04046E6CC752}")) { ntfs.DeleteFile(filePath); } // Remove the page file if (ntfs.FileExists(@"\Pagefile.sys")) { ntfs.DeleteFile(@"\Pagefile.sys"); } // Remove the hibernation file if (ntfs.FileExists(@"\hiberfil.sys")) { ntfs.DeleteFile(@"\hiberfil.sys"); } using (Stream systemRegistryStream = ntfs.OpenFile(@"windows\system32\config\system", FileMode.Open)) { this.fileSystemHelper.ChangeSystemDriveMappingFromRegistry(systemRegistryStream); } } } if (migrationData.TemporaryVhdFileIsTheFinalOne) { char vhdLocationDriveLetter = migrationData.VhdFileTemporaryFolder[0]; var driveInfo = this.fileSystem.DriveInfo.FromDriveName(vhdLocationDriveLetter.ToString() + ":\\"); if (driveInfo.AvailableFreeSpace <= disk.Geometry.Capacity) { logger.LogWarning($"The image is located in a drive which has not enough free space for it to expand. If you will not free some space on drive '{driveInfo.Name}' then you will see BSOD when trying to boot from the created image."); } } } return; }
private void ValidateVhdVolumeSize() { string vhdFile = $"{migrationData.VhdFileTemporaryFolder}\\{migrationData.VhdFileName}"; using (VirtualDiskDecorator sourceVhd = this.fileSystemHelper.OpenVhdx(vhdFile)) { using (Stream inpuStream = sourceVhd.Partitions[0].Open()) { if (inpuStream.Length > migrationData.DestinationVhdMaxFileSize) { throw new Exception("Volume after shrink operation is too big to successfully migrate to system drive. Migration cannot continue."); } } } }
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; }
public override void PerformStep() { if (this.migrationData.TemporaryVhdFileIsTheFinalOne) { return; } logger.LogInformation("Copying partition data..."); this.sourceVhdFile = $"{migrationData.VhdFileTemporaryFolder}\\{migrationData.VhdFileName}"; this.destinationVhdFile = $"{migrationData.VhdFileDestinationFolder}\\{migrationData.VhdFileName}"; using (PrivilegeEnabler privEnabler = new PrivilegeEnabler(Privilege.Backup, Privilege.Restore)) { using (VirtualDiskDecorator sourceVhd = this.fileSystemHelper.OpenVhdx(this.sourceVhdFile)) { using (Stream inpuStream = sourceVhd.Partitions[0].Open()) { using (VirtualDiskDecorator destinationVhd = this.fileSystemHelper.OpenVhdx(this.destinationVhdFile)) { var partitionTable = destinationVhd.Partitions; int partIndex = partitionTable.CreatePrimaryBySector(1, (inpuStream.Length / destinationVhd.Geometry.BytesPerSector), BiosPartitionTypes.Ntfs, false); PartitionInfoDecorator partition = destinationVhd.Partitions[partIndex]; using (var outputStream = partition.Open()) { this.fileSystemHelper.CloneNtfsFileSystem(inpuStream, outputStream, logger); } } } } } if (migrationData.DeleteTemporaryVhdFile) { this.fileSystem.File.Delete(this.sourceVhdFile); } logger.LogInformation("Cloning temporary vhd to destination vhd completed."); }