/// <summary> /// Gets the logical volumes held across the set of managed disks. /// </summary> /// <returns>An array of logical volumes.</returns> public LogicalVolumeInfo[] GetLogicalVolumes() { List <LogicalVolumeInfo> result = new List <LogicalVolumeInfo>(); foreach (var vg in _volumeGroups) { foreach (var lv in vg.LogicalVolumes) { var pvs = new Dictionary <string, PhysicalVolume>(); bool allPvsAvailable = true; bool segmentTypesSupported = true; foreach (var segment in lv.Segments) { if (segment.Type != SegmentType.Striped) { segmentTypesSupported = false; } foreach (var stripe in segment.Stripes) { var pvAlias = stripe.PhysicalVolumeName; if (!pvs.ContainsKey(pvAlias)) { var pvm = GetPhysicalVolumeMetadata(pvAlias); if (pvm == null) { allPvsAvailable = false; break; } var pv = GetPhysicalVolume(pvm.Id); if (pv == null) { allPvsAvailable = false; break; } pvs.Add(pvm.Name, pv); } } if (!allPvsAvailable || !segmentTypesSupported) { break; } } if (allPvsAvailable && segmentTypesSupported) { LogicalVolumeInfo lvi = new LogicalVolumeInfo( lv.Identity, null, lv.Open(pvs, vg.ExtentSize), lv.ExtentCount * (long)vg.ExtentSize * PhysicalVolume.SECTOR_SIZE, 0, DiscUtils.LogicalVolumeStatus.Healthy); result.Add(lvi); } } } return(result.ToArray()); }
private void GetChildren(string path, bool recurse, bool namesOnly) { if (string.IsNullOrEmpty(path)) { return; } object obj = FindItemByPath(path, false, true); if (obj is VirtualDisk) { VirtualDisk vd = (VirtualDisk)obj; EnumerateDisk(vd, path, recurse, namesOnly); } else if (obj is LogicalVolumeInfo) { LogicalVolumeInfo lvi = (LogicalVolumeInfo)obj; bool dispose; DiscFileSystem fs = GetFileSystem(lvi, out dispose); try { if (fs != null) { EnumerateDirectory(fs.Root, path, recurse, namesOnly); } } finally { if (dispose && fs != null) { fs.Dispose(); } } } else if (obj is DiscDirectoryInfo) { DiscDirectoryInfo ddi = (DiscDirectoryInfo)obj; EnumerateDirectory(ddi, path, recurse, namesOnly); } else { WriteError(new ErrorRecord( new InvalidOperationException("Unrecognized object type: " + (obj != null ? obj.GetType() : null)), "UnknownObjectType", ErrorCategory.ParserError, obj)); } }
/// <summary> /// Dump the FileEntries from a Logical Volume asynchronously /// </summary> /// <param name="volume">The Volume to dump</param> /// <param name="parentPath">The Path to the parent Disc</param> /// <param name="options">Extractor Options to use</param> /// <param name="governor">Resource Governor to use</param> /// <param name="Context">Extractor context to use</param> /// <param name="parent">The Parent FilEntry</param> /// <returns></returns> public static async IAsyncEnumerable <FileEntry> DumpLogicalVolumeAsync(LogicalVolumeInfo volume, string parentPath, ExtractorOptions options, ResourceGovernor governor, Extractor Context, FileEntry?parent = null) { DiscUtils.FileSystemInfo[]? fsInfos = null; try { fsInfos = FileSystemManager.DetectFileSystems(volume); } catch (Exception e) { Logger.Debug("Failed to get file systems from logical volume {0} Image {1} ({2}:{3})", volume.Identity, parentPath, e.GetType(), e.Message); } foreach (var fsInfo in fsInfos ?? Array.Empty <DiscUtils.FileSystemInfo>()) { using var fs = fsInfo.Open(volume); var diskFiles = fs.GetFiles(fs.Root.FullName, "*.*", SearchOption.AllDirectories).ToList(); foreach (var file in diskFiles) { Stream? fileStream = null; DiscFileInfo?fi = null; try { fi = fs.GetFileInfo(file); governor.CheckResourceGovernor(fi.Length); fileStream = fi.OpenRead(); } catch (Exception e) { Logger.Debug(e, "Failed to open {0} in volume {1}", file, volume.Identity); } if (fileStream != null && fi != null) { var newFileEntry = await FileEntry.FromStreamAsync($"{volume.Identity}{Path.DirectorySeparatorChar}{fi.FullName}", fileStream, parent); var entries = Context.ExtractAsync(newFileEntry, options, governor); await foreach (var entry in entries) { yield return(entry); } } } } }
/// <summary> /// Gets the logical volumes held across the set of managed disks. /// </summary> /// <returns>An array of logical volumes.</returns> public LogicalVolumeInfo[] GetLogicalVolumes() { List <LogicalVolumeInfo> result = new List <LogicalVolumeInfo>(); foreach (DynamicDiskGroup group in _groups.Values) { foreach (DynamicVolume volume in group.GetVolumes()) { LogicalVolumeInfo lvi = new LogicalVolumeInfo( volume.Identity, null, volume.Open, volume.Length, volume.BiosType, volume.Status); result.Add(lvi); } } return(result.ToArray()); }
public IEnumerable <FileEntry> DumpLogicalVolume(LogicalVolumeInfo volume, string parentPath, FileEntry parent = null) { DiscUtils.FileSystemInfo[] fsInfos = null; try { fsInfos = FileSystemManager.DetectFileSystems(volume); } catch (Exception e) { Logger.Debug("Failed to get file systems from logical volume {0} Image {1} ({2}:{3})", volume.Identity, parentPath, e.GetType(), e.Message); } foreach (var fsInfo in fsInfos ?? new DiscUtils.FileSystemInfo[] { }) { using (var fs = fsInfo.Open(volume)) { var diskFiles = fs.GetFiles(fs.Root.FullName, "*.*", SearchOption.AllDirectories).ToList(); foreach (var file in diskFiles) { Stream fileStream = null; DiscFileInfo fi = null; try { fi = fs.GetFileInfo(file); fileStream = fi.OpenRead(); } catch (Exception e) { Logger.Debug(e, "Failed to open {0} in volume {1}", file, volume.Identity); } if (fileStream != null && fi != null) { yield return(FileEntry.FromStream($"{volume.Identity}{Path.DirectorySeparatorChar}{fi.FullName}", fileStream, parent)); } } } } }
/// <summary> /// Gets the logical volumes held across the set of managed disks. /// </summary> /// <returns>An array of logical volumes</returns> public LogicalVolumeInfo[] GetLogicalVolumes() { List<LogicalVolumeInfo> result = new List<LogicalVolumeInfo>(); foreach (var group in _groups.Values) { foreach (var volume in group.GetVolumes()) { LogicalVolumeInfo lvi = new LogicalVolumeInfo( volume.Identity, null, volume.Open, volume.Length, volume.BiosType, volume.Status); result.Add(lvi); } } return result.ToArray(); }
/// <summary> /// Dump the FileEntries from a Logical Volume /// </summary> /// <param name="volume">The Volume to dump</param> /// <param name="parentPath">The Path to the parent Disc</param> /// <param name="options">Extractor Options to use</param> /// <param name="governor">Resource Governor to use</param> /// <param name="Context">Extractor context to use</param> /// <param name="parent">The Parent FilEntry</param> /// <returns></returns> public static IEnumerable <FileEntry> DumpLogicalVolume(LogicalVolumeInfo volume, string parentPath, ExtractorOptions options, ResourceGovernor governor, Extractor Context, FileEntry?parent = null) { DiscUtils.FileSystemInfo[]? fsInfos = null; try { fsInfos = FileSystemManager.DetectFileSystems(volume); } catch (Exception e) { Logger.Debug("Failed to get file systems from logical volume {0} Image {1} ({2}:{3})", volume.Identity, parentPath, e.GetType(), e.Message); } foreach (var fsInfo in fsInfos ?? Array.Empty <DiscUtils.FileSystemInfo>()) { using var fs = fsInfo.Open(volume); var diskFiles = fs.GetFiles(fs.Root.FullName, "*.*", SearchOption.AllDirectories).ToList(); if (options.Parallel) { var files = new ConcurrentStack <FileEntry>(); while (diskFiles.Any()) { var batchSize = Math.Min(options.BatchSize, diskFiles.Count); var range = diskFiles.GetRange(0, batchSize); var fileinfos = new List <(DiscFileInfo, Stream)>(); long totalLength = 0; foreach (var r in range) { try { var fi = fs.GetFileInfo(r); totalLength += fi.Length; fileinfos.Add((fi, fi.OpenRead())); } catch (Exception e) { Logger.Debug("Failed to get FileInfo from {0} in Volume {1} @ {2} ({3}:{4})", r, volume.Identity, parentPath, e.GetType(), e.Message); } } governor.CheckResourceGovernor(totalLength); fileinfos.AsParallel().ForAll(file => { if (file.Item2 != null) { var newFileEntry = new FileEntry($"{volume.Identity}{Path.DirectorySeparatorChar}{file.Item1.FullName}", file.Item2, parent); var entries = Context.ExtractFile(newFileEntry, options, governor); files.PushRange(entries.ToArray()); } }); diskFiles.RemoveRange(0, batchSize); while (files.TryPop(out var result)) { if (result != null) { yield return(result); } } } } else { foreach (var file in diskFiles) { Stream?fileStream = null; try { var fi = fs.GetFileInfo(file); governor.CheckResourceGovernor(fi.Length); fileStream = fi.OpenRead(); } catch (Exception e) { Logger.Debug(e, "Failed to open {0} in volume {1}", file, volume.Identity); } if (fileStream != null) { var newFileEntry = new FileEntry($"{volume.Identity}{Path.DirectorySeparatorChar}{file}", fileStream, parent); var entries = Context.ExtractFile(newFileEntry, options, governor); foreach (var entry in entries) { yield return(entry); } } } } } }