public Type1Partition(UdfContext context, LogicalVolumeDescriptor volumeDescriptor, Type1PartitionMap partitionMap) : base(context, volumeDescriptor) { _partitionMap = partitionMap; _physical = context.PhysicalPartitions[partitionMap.PartitionNumber]; }
public MetadataPartition(UdfContext context, LogicalVolumeDescriptor volumeDescriptor, MetadataPartitionMap partitionMap) : base(context, volumeDescriptor) { _partitionMap = partitionMap; PhysicalPartition physical = context.PhysicalPartitions[partitionMap.PartitionNumber]; long fileEntryPos = partitionMap.MetadataFileLocation * (long)volumeDescriptor.LogicalBlockSize; byte[] entryData = Utilities.ReadFully(physical.Content, fileEntryPos, _context.PhysicalSectorSize); if (!DescriptorTag.IsValid(entryData, 0)) { throw new IOException("Invalid descriptor tag looking for Metadata file entry"); } DescriptorTag dt = Utilities.ToStruct<DescriptorTag>(entryData, 0); if (dt.TagIdentifier == TagIdentifier.ExtendedFileEntry) { ExtendedFileEntry efe = Utilities.ToStruct<ExtendedFileEntry>(entryData, 0); _metadataFile = new File(context, physical, efe, _volumeDescriptor.LogicalBlockSize); } else { throw new NotImplementedException("Only EFE implemented for Metadata file entry"); } }
public static LogicalPartition FromDescriptor(UdfContext context, LogicalVolumeDescriptor volumeDescriptor, int index) { PartitionMap map = volumeDescriptor.PartitionMaps[index]; Type1PartitionMap asType1 = map as Type1PartitionMap; if (asType1 != null) { return new Type1Partition(context, volumeDescriptor, asType1); } MetadataPartitionMap asMetadata = map as MetadataPartitionMap; if (asMetadata != null) { return new MetadataPartition(context, volumeDescriptor, asMetadata); } throw new NotImplementedException("Unrecognized partition map type"); }
public bool Identify(IMediaImage imagePlugin, Partition partition) { // UDF needs at least that if (partition.End - partition.Start < 256) { return(false); } // UDF needs at least that if (imagePlugin.Info.SectorSize < 512) { return(false); } byte[] sector; AnchorVolumeDescriptorPointer anchor = new AnchorVolumeDescriptorPointer(); // All positions where anchor may reside ulong[] positions = { 256, 512, partition.End - 256, partition.End }; bool anchorFound = false; foreach (ulong position in positions.Where(position => position + partition.Start < partition.End)) { sector = imagePlugin.ReadSector(position); anchor = new AnchorVolumeDescriptorPointer(); IntPtr anchorPtr = Marshal.AllocHGlobal(Marshal.SizeOf(anchor)); Marshal.Copy(sector, 0, anchorPtr, Marshal.SizeOf(anchor)); anchor = (AnchorVolumeDescriptorPointer)Marshal.PtrToStructure(anchorPtr, typeof(AnchorVolumeDescriptorPointer)); Marshal.FreeHGlobal(anchorPtr); DicConsole.DebugWriteLine("UDF Plugin", "anchor.tag.tagIdentifier = {0}", anchor.tag.tagIdentifier); DicConsole.DebugWriteLine("UDF Plugin", "anchor.tag.descriptorVersion = {0}", anchor.tag.descriptorVersion); DicConsole.DebugWriteLine("UDF Plugin", "anchor.tag.tagChecksum = 0x{0:X2}", anchor.tag.tagChecksum); DicConsole.DebugWriteLine("UDF Plugin", "anchor.tag.reserved = {0}", anchor.tag.reserved); DicConsole.DebugWriteLine("UDF Plugin", "anchor.tag.tagSerialNumber = {0}", anchor.tag.tagSerialNumber); DicConsole.DebugWriteLine("UDF Plugin", "anchor.tag.descriptorCrc = 0x{0:X4}", anchor.tag.descriptorCrc); DicConsole.DebugWriteLine("UDF Plugin", "anchor.tag.descriptorCrcLength = {0}", anchor.tag.descriptorCrcLength); DicConsole.DebugWriteLine("UDF Plugin", "anchor.tag.tagLocation = {0}", anchor.tag.tagLocation); DicConsole.DebugWriteLine("UDF Plugin", "anchor.mainVolumeDescriptorSequenceExtent.length = {0}", anchor.mainVolumeDescriptorSequenceExtent.length); DicConsole.DebugWriteLine("UDF Plugin", "anchor.mainVolumeDescriptorSequenceExtent.location = {0}", anchor.mainVolumeDescriptorSequenceExtent.location); DicConsole.DebugWriteLine("UDF Plugin", "anchor.reserveVolumeDescriptorSequenceExtent.length = {0}", anchor.reserveVolumeDescriptorSequenceExtent.length); DicConsole.DebugWriteLine("UDF Plugin", "anchor.reserveVolumeDescriptorSequenceExtent.location = {0}", anchor.reserveVolumeDescriptorSequenceExtent.location); if (anchor.tag.tagIdentifier != TagIdentifier.AnchorVolumeDescriptorPointer || anchor.tag.tagLocation != position || anchor.mainVolumeDescriptorSequenceExtent.location + partition.Start >= partition.End) { continue; } anchorFound = true; break; } if (!anchorFound) { return(false); } ulong count = 0; while (count < 256) { sector = imagePlugin.ReadSector(partition.Start + anchor.mainVolumeDescriptorSequenceExtent.location + count); TagIdentifier tagId = (TagIdentifier)BitConverter.ToUInt16(sector, 0); uint location = BitConverter.ToUInt32(sector, 0x0C); if (location == partition.Start + anchor.mainVolumeDescriptorSequenceExtent.location + count) { if (tagId == TagIdentifier.TerminatingDescriptor) { break; } if (tagId == TagIdentifier.LogicalVolumeDescriptor) { LogicalVolumeDescriptor lvd = new LogicalVolumeDescriptor(); IntPtr lvdPtr = Marshal.AllocHGlobal(Marshal.SizeOf(lvd)); Marshal.Copy(sector, 0, lvdPtr, Marshal.SizeOf(lvd)); lvd = (LogicalVolumeDescriptor)Marshal.PtrToStructure(lvdPtr, typeof(LogicalVolumeDescriptor)); Marshal.FreeHGlobal(lvdPtr); return(UDF_Magic.SequenceEqual(lvd.domainIdentifier.identifier)); } } else { break; } count++; } return(false); }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { // UDF is always UTF-8 Encoding = Encoding.UTF8; byte[] sector; StringBuilder sbInformation = new StringBuilder(); sbInformation.AppendLine("Universal Disk Format"); AnchorVolumeDescriptorPointer anchor = new AnchorVolumeDescriptorPointer(); // All positions where anchor may reside ulong[] positions = { 256, 512, partition.End - 256, partition.End }; foreach (ulong position in positions) { sector = imagePlugin.ReadSector(position); anchor = new AnchorVolumeDescriptorPointer(); IntPtr anchorPtr = Marshal.AllocHGlobal(Marshal.SizeOf(anchor)); Marshal.Copy(sector, 0, anchorPtr, Marshal.SizeOf(anchor)); anchor = (AnchorVolumeDescriptorPointer)Marshal.PtrToStructure(anchorPtr, typeof(AnchorVolumeDescriptorPointer)); Marshal.FreeHGlobal(anchorPtr); if (anchor.tag.tagIdentifier == TagIdentifier.AnchorVolumeDescriptorPointer && anchor.tag.tagLocation == position && anchor.mainVolumeDescriptorSequenceExtent.location + partition.Start < partition.End) { break; } } ulong count = 0; PrimaryVolumeDescriptor pvd = new PrimaryVolumeDescriptor(); LogicalVolumeDescriptor lvd = new LogicalVolumeDescriptor(); LogicalVolumeIntegrityDescriptor lvid = new LogicalVolumeIntegrityDescriptor(); LogicalVolumeIntegrityDescriptorImplementationUse lvidiu = new LogicalVolumeIntegrityDescriptorImplementationUse(); while (count < 256) { sector = imagePlugin.ReadSector(partition.Start + anchor.mainVolumeDescriptorSequenceExtent.location + count); TagIdentifier tagId = (TagIdentifier)BitConverter.ToUInt16(sector, 0); uint location = BitConverter.ToUInt32(sector, 0x0C); if (location == partition.Start + anchor.mainVolumeDescriptorSequenceExtent.location + count) { if (tagId == TagIdentifier.TerminatingDescriptor) { break; } switch (tagId) { case TagIdentifier.LogicalVolumeDescriptor: IntPtr lvdPtr = Marshal.AllocHGlobal(Marshal.SizeOf(lvd)); Marshal.Copy(sector, 0, lvdPtr, Marshal.SizeOf(lvd)); lvd = (LogicalVolumeDescriptor) Marshal.PtrToStructure(lvdPtr, typeof(LogicalVolumeDescriptor)); Marshal.FreeHGlobal(lvdPtr); break; case TagIdentifier.PrimaryVolumeDescriptor: IntPtr pvdPtr = Marshal.AllocHGlobal(Marshal.SizeOf(pvd)); Marshal.Copy(sector, 0, pvdPtr, Marshal.SizeOf(pvd)); pvd = (PrimaryVolumeDescriptor) Marshal.PtrToStructure(pvdPtr, typeof(PrimaryVolumeDescriptor)); Marshal.FreeHGlobal(pvdPtr); break; } } else { break; } count++; } sector = imagePlugin.ReadSector(lvd.integritySequenceExtent.location); IntPtr lvidPtr = Marshal.AllocHGlobal(Marshal.SizeOf(lvid)); Marshal.Copy(sector, 0, lvidPtr, Marshal.SizeOf(lvid)); lvid = (LogicalVolumeIntegrityDescriptor) Marshal.PtrToStructure(lvidPtr, typeof(LogicalVolumeIntegrityDescriptor)); Marshal.FreeHGlobal(lvidPtr); if (lvid.tag.tagIdentifier == TagIdentifier.LogicalVolumeIntegrityDescriptor && lvid.tag.tagLocation == lvd.integritySequenceExtent.location) { IntPtr lvidiuPtr = Marshal.AllocHGlobal(Marshal.SizeOf(lvidiu)); Marshal.Copy(sector, (int)(lvid.numberOfPartitions * 8 + 80), lvidiuPtr, Marshal.SizeOf(lvidiu)); lvidiu = (LogicalVolumeIntegrityDescriptorImplementationUse)Marshal.PtrToStructure(lvidiuPtr, typeof( LogicalVolumeIntegrityDescriptorImplementationUse )); Marshal.FreeHGlobal(lvidiuPtr); } else { lvid = new LogicalVolumeIntegrityDescriptor(); } sbInformation.AppendFormat("Volume is number {0} of {1}", pvd.volumeSequenceNumber, pvd.maximumVolumeSequenceNumber).AppendLine(); sbInformation.AppendFormat("Volume set identifier: {0}", StringHandlers.DecompressUnicode(pvd.volumeSetIdentifier)).AppendLine(); sbInformation .AppendFormat("Volume name: {0}", StringHandlers.DecompressUnicode(lvd.logicalVolumeIdentifier)) .AppendLine(); sbInformation.AppendFormat("Volume uses {0} bytes per block", lvd.logicalBlockSize).AppendLine(); sbInformation.AppendFormat("Volume was las written in {0}", EcmaToDateTime(lvid.recordingDateTime)) .AppendLine(); sbInformation.AppendFormat("Volume contains {0} partitions", lvid.numberOfPartitions).AppendLine(); sbInformation .AppendFormat("Volume contains {0} files and {1} directories", lvidiu.files, lvidiu.directories) .AppendLine(); sbInformation.AppendFormat("Volume conforms to {0}", Encoding.GetString(lvd.domainIdentifier.identifier).TrimEnd('\u0000')) .AppendLine(); sbInformation.AppendFormat("Volume was last written by: {0}", Encoding.GetString(pvd.implementationIdentifier.identifier).TrimEnd('\u0000')) .AppendLine(); sbInformation.AppendFormat("Volume requires UDF version {0}.{1:X2} to be read", Convert.ToInt32($"{(lvidiu.minimumReadUDF & 0xFF00) >> 8}", 10), Convert.ToInt32($"{lvidiu.minimumReadUDF & 0xFF}", 10)).AppendLine(); sbInformation.AppendFormat("Volume requires UDF version {0}.{1:X2} to be written to", Convert.ToInt32($"{(lvidiu.minimumWriteUDF & 0xFF00) >> 8}", 10), Convert.ToInt32($"{lvidiu.minimumWriteUDF & 0xFF}", 10)).AppendLine(); sbInformation.AppendFormat("Volume cannot be written by any UDF version higher than {0}.{1:X2}", Convert.ToInt32($"{(lvidiu.maximumWriteUDF & 0xFF00) >> 8}", 10), Convert.ToInt32($"{lvidiu.maximumWriteUDF & 0xFF}", 10)).AppendLine(); XmlFsType = new FileSystemType { Type = $"UDF v{Convert.ToInt32($"{(lvidiu.maximumWriteUDF & 0xFF00) >> 8}", 10)}.{Convert.ToInt32($"{lvidiu.maximumWriteUDF & 0xFF}", 10):X2}", ApplicationIdentifier = Encoding.GetString(pvd.implementationIdentifier.identifier).TrimEnd('\u0000'), ClusterSize = (int)lvd.logicalBlockSize, ModificationDate = EcmaToDateTime(lvid.recordingDateTime), ModificationDateSpecified = true, Files = lvidiu.files, FilesSpecified = true, VolumeName = StringHandlers.DecompressUnicode(lvd.logicalVolumeIdentifier), VolumeSetIdentifier = StringHandlers.DecompressUnicode(pvd.volumeSetIdentifier), SystemIdentifier = Encoding.GetString(pvd.implementationIdentifier.identifier).TrimEnd('\u0000') }; XmlFsType.Clusters = (long)((partition.End - partition.Start + 1) * imagePlugin.Info.SectorSize / (ulong)XmlFsType.ClusterSize); information = sbInformation.ToString(); }
protected LogicalPartition(UdfContext context, LogicalVolumeDescriptor volumeDescriptor) { _context = context; _volumeDescriptor = volumeDescriptor; }
public bool Identify(IMediaImage imagePlugin, Partition partition) { // UDF needs at least that if(partition.End - partition.Start < 256) return false; // UDF needs at least that if(imagePlugin.Info.SectorSize < 512) return false; byte[] sector; var anchor = new AnchorVolumeDescriptorPointer(); // All positions where anchor may reside, with the ratio between 512 and 2048bps ulong[][] positions = { new ulong[] { 256, 1 }, new ulong[] { 512, 1 }, new ulong[] { partition.End - 256, 1 }, new ulong[] { partition.End, 1 }, new ulong[] { 1024, 4 }, new ulong[] { 2048, 4 }, new ulong[] { partition.End - 1024, 4 }, new ulong[] { partition.End - 4, 4 } }; bool anchorFound = false; uint ratio = 1; foreach(ulong[] position in positions.Where(position => position[0] + partition.Start + position[1] <= partition.End && position[0] < partition.End)) { sector = imagePlugin.ReadSectors(position[0], (uint)position[1]); anchor = Marshal.ByteArrayToStructureLittleEndian<AnchorVolumeDescriptorPointer>(sector); AaruConsole.DebugWriteLine("UDF Plugin", "anchor.tag.tagIdentifier = {0}", anchor.tag.tagIdentifier); AaruConsole.DebugWriteLine("UDF Plugin", "anchor.tag.descriptorVersion = {0}", anchor.tag.descriptorVersion); AaruConsole.DebugWriteLine("UDF Plugin", "anchor.tag.tagChecksum = 0x{0:X2}", anchor.tag.tagChecksum); AaruConsole.DebugWriteLine("UDF Plugin", "anchor.tag.reserved = {0}", anchor.tag.reserved); AaruConsole.DebugWriteLine("UDF Plugin", "anchor.tag.tagSerialNumber = {0}", anchor.tag.tagSerialNumber); AaruConsole.DebugWriteLine("UDF Plugin", "anchor.tag.descriptorCrc = 0x{0:X4}", anchor.tag.descriptorCrc); AaruConsole.DebugWriteLine("UDF Plugin", "anchor.tag.descriptorCrcLength = {0}", anchor.tag.descriptorCrcLength); AaruConsole.DebugWriteLine("UDF Plugin", "anchor.tag.tagLocation = {0}", anchor.tag.tagLocation); AaruConsole.DebugWriteLine("UDF Plugin", "anchor.mainVolumeDescriptorSequenceExtent.length = {0}", anchor.mainVolumeDescriptorSequenceExtent.length); AaruConsole.DebugWriteLine("UDF Plugin", "anchor.mainVolumeDescriptorSequenceExtent.location = {0}", anchor.mainVolumeDescriptorSequenceExtent.location); AaruConsole.DebugWriteLine("UDF Plugin", "anchor.reserveVolumeDescriptorSequenceExtent.length = {0}", anchor.reserveVolumeDescriptorSequenceExtent.length); AaruConsole.DebugWriteLine("UDF Plugin", "anchor.reserveVolumeDescriptorSequenceExtent.location = {0}", anchor.reserveVolumeDescriptorSequenceExtent.location); if(anchor.tag.tagIdentifier != TagIdentifier.AnchorVolumeDescriptorPointer || anchor.tag.tagLocation != position[0] / position[1] || (anchor.mainVolumeDescriptorSequenceExtent.location * position[1]) + partition.Start >= partition.End) continue; anchorFound = true; ratio = (uint)position[1]; break; } if(!anchorFound) return false; ulong count = 0; while(count < 256) { sector = imagePlugin. ReadSectors(partition.Start + (anchor.mainVolumeDescriptorSequenceExtent.location * ratio) + (count * ratio), ratio); var tagId = (TagIdentifier)BitConverter.ToUInt16(sector, 0); uint location = BitConverter.ToUInt32(sector, 0x0C); if(location == (partition.Start / ratio) + anchor.mainVolumeDescriptorSequenceExtent.location + count) { if(tagId == TagIdentifier.TerminatingDescriptor) break; if(tagId == TagIdentifier.LogicalVolumeDescriptor) { LogicalVolumeDescriptor lvd = Marshal.ByteArrayToStructureLittleEndian<LogicalVolumeDescriptor>(sector); return _magic.SequenceEqual(lvd.domainIdentifier.identifier); } } else break; count++; } return false; }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { // UDF is always UTF-8 Encoding = Encoding.UTF8; byte[] sector; var sbInformation = new StringBuilder(); sbInformation.AppendLine("Universal Disk Format"); var anchor = new AnchorVolumeDescriptorPointer(); // All positions where anchor may reside, with the ratio between 512 and 2048bps ulong[][] positions = { new ulong[] { 256, 1 }, new ulong[] { 512, 1 }, new ulong[] { partition.End - 256, 1 }, new ulong[] { partition.End, 1 }, new ulong[] { 1024, 4 }, new ulong[] { 2048, 4 }, new ulong[] { partition.End - 1024, 4 }, new ulong[] { partition.End - 4, 4 } }; uint ratio = 1; foreach(ulong[] position in positions) { sector = imagePlugin.ReadSectors(position[0], (uint)position[1]); anchor = Marshal.ByteArrayToStructureLittleEndian<AnchorVolumeDescriptorPointer>(sector); if(anchor.tag.tagIdentifier != TagIdentifier.AnchorVolumeDescriptorPointer || anchor.tag.tagLocation != position[0] / position[1] || anchor.mainVolumeDescriptorSequenceExtent.location + partition.Start >= partition.End) continue; ratio = (uint)position[1]; break; } ulong count = 0; var pvd = new PrimaryVolumeDescriptor(); var lvd = new LogicalVolumeDescriptor(); var lvid = new LogicalVolumeIntegrityDescriptor(); var lvidiu = new LogicalVolumeIntegrityDescriptorImplementationUse(); while(count < 256) { sector = imagePlugin. ReadSectors(partition.Start + (anchor.mainVolumeDescriptorSequenceExtent.location * ratio) + (count * ratio), ratio); var tagId = (TagIdentifier)BitConverter.ToUInt16(sector, 0); uint location = BitConverter.ToUInt32(sector, 0x0C); if(location == (partition.Start / ratio) + anchor.mainVolumeDescriptorSequenceExtent.location + count) { if(tagId == TagIdentifier.TerminatingDescriptor) break; switch(tagId) { case TagIdentifier.LogicalVolumeDescriptor: lvd = Marshal.ByteArrayToStructureLittleEndian<LogicalVolumeDescriptor>(sector); break; case TagIdentifier.PrimaryVolumeDescriptor: pvd = Marshal.ByteArrayToStructureLittleEndian<PrimaryVolumeDescriptor>(sector); break; } } else break; count++; } sector = imagePlugin.ReadSectors(lvd.integritySequenceExtent.location * ratio, ratio); lvid = Marshal.ByteArrayToStructureLittleEndian<LogicalVolumeIntegrityDescriptor>(sector); if(lvid.tag.tagIdentifier == TagIdentifier.LogicalVolumeIntegrityDescriptor && lvid.tag.tagLocation == lvd.integritySequenceExtent.location) lvidiu = Marshal.ByteArrayToStructureLittleEndian<LogicalVolumeIntegrityDescriptorImplementationUse>(sector, (int)((lvid.numberOfPartitions * 8) + 80), System.Runtime.InteropServices.Marshal.SizeOf(lvidiu)); else lvid = new LogicalVolumeIntegrityDescriptor(); sbInformation.AppendFormat("Volume is number {0} of {1}", pvd.volumeSequenceNumber, pvd.maximumVolumeSequenceNumber).AppendLine(); sbInformation.AppendFormat("Volume set identifier: {0}", StringHandlers.DecompressUnicode(pvd.volumeSetIdentifier)).AppendLine(); sbInformation. AppendFormat("Volume name: {0}", StringHandlers.DecompressUnicode(lvd.logicalVolumeIdentifier)). AppendLine(); sbInformation.AppendFormat("Volume uses {0} bytes per block", lvd.logicalBlockSize).AppendLine(); sbInformation.AppendFormat("Volume was last written in {0}", EcmaToDateTime(lvid.recordingDateTime)). AppendLine(); sbInformation.AppendFormat("Volume contains {0} partitions", lvid.numberOfPartitions).AppendLine(); sbInformation. AppendFormat("Volume contains {0} files and {1} directories", lvidiu.files, lvidiu.directories). AppendLine(); sbInformation.AppendFormat("Volume conforms to {0}", Encoding.GetString(lvd.domainIdentifier.identifier).TrimEnd('\u0000')). AppendLine(); sbInformation.AppendFormat("Volume was last written by: {0}", Encoding.GetString(pvd.implementationIdentifier.identifier).TrimEnd('\u0000')). AppendLine(); sbInformation.AppendFormat("Volume requires UDF version {0}.{1:X2} to be read", Convert.ToInt32($"{(lvidiu.minimumReadUDF & 0xFF00) >> 8}", 10), Convert.ToInt32($"{lvidiu.minimumReadUDF & 0xFF}", 10)).AppendLine(); sbInformation.AppendFormat("Volume requires UDF version {0}.{1:X2} to be written to", Convert.ToInt32($"{(lvidiu.minimumWriteUDF & 0xFF00) >> 8}", 10), Convert.ToInt32($"{lvidiu.minimumWriteUDF & 0xFF}", 10)).AppendLine(); sbInformation.AppendFormat("Volume cannot be written by any UDF version higher than {0}.{1:X2}", Convert.ToInt32($"{(lvidiu.maximumWriteUDF & 0xFF00) >> 8}", 10), Convert.ToInt32($"{lvidiu.maximumWriteUDF & 0xFF}", 10)).AppendLine(); XmlFsType = new FileSystemType { Type = $"UDF v{Convert.ToInt32($"{(lvidiu.maximumWriteUDF & 0xFF00) >> 8}", 10)}.{Convert.ToInt32($"{lvidiu.maximumWriteUDF & 0xFF}", 10):X2}", ApplicationIdentifier = Encoding.GetString(pvd.implementationIdentifier.identifier).TrimEnd('\u0000'), ClusterSize = lvd.logicalBlockSize, ModificationDate = EcmaToDateTime(lvid.recordingDateTime), ModificationDateSpecified = true, Files = lvidiu.files, FilesSpecified = true, VolumeName = StringHandlers.DecompressUnicode(lvd.logicalVolumeIdentifier), VolumeSetIdentifier = StringHandlers.DecompressUnicode(pvd.volumeSetIdentifier), VolumeSerial = StringHandlers.DecompressUnicode(pvd.volumeSetIdentifier), SystemIdentifier = Encoding.GetString(pvd.implementationIdentifier.identifier).TrimEnd('\u0000') }; XmlFsType.Clusters = (partition.End - partition.Start + 1) * imagePlugin.Info.SectorSize / XmlFsType.ClusterSize; information = sbInformation.ToString(); }