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 bool TryFromStream(Stream stream, out DescriptorTag result) { byte[] next = Utilities.ReadFully(stream, 512); if (!DescriptorTag.IsValid(next, 0)) { result = null; return(false); } DescriptorTag dt = new DescriptorTag(); dt.ReadFrom(next, 0); result = dt; return(true); }
public int ReadFrom(byte[] buffer, int offset) { if (!DescriptorTag.IsValid(buffer, offset)) { throw new InvalidDataException("Invalid Anchor Volume Descriptor Pointer (invalid tag)"); } Tag = new DescriptorTag(); Tag.ReadFrom(buffer, offset); if (UdfUtilities.ComputeCrc(buffer, offset + Tag.Size, Tag.DescriptorCrcLength) != Tag.DescriptorCrc) { throw new InvalidDataException("Invalid Anchor Volume Descriptor Pointer (invalid CRC)"); } return(Parse(buffer, offset)); }
private void Initialize() { Context = new UdfContext() { PhysicalPartitions = new Dictionary <ushort, PhysicalPartition>(), PhysicalSectorSize = (int)_sectorSize, LogicalPartitions = new List <LogicalPartition>(), }; IBuffer dataBuffer = new StreamBuffer(_data, Ownership.None); AnchorVolumeDescriptorPointer avdp = AnchorVolumeDescriptorPointer.FromStream(_data, 256, _sectorSize); uint sector = avdp.MainDescriptorSequence.Location; bool terminatorFound = false; while (!terminatorFound) { _data.Position = sector * (long)_sectorSize; DescriptorTag dt; if (!DescriptorTag.TryFromStream(_data, out dt)) { break; } switch (dt.TagIdentifier) { case TagIdentifier.PrimaryVolumeDescriptor: _pvd = PrimaryVolumeDescriptor.FromStream(_data, sector, _sectorSize); break; case TagIdentifier.ImplementationUseVolumeDescriptor: // Not used break; case TagIdentifier.PartitionDescriptor: PartitionDescriptor pd = PartitionDescriptor.FromStream(_data, sector, _sectorSize); if (Context.PhysicalPartitions.ContainsKey(pd.PartitionNumber)) { throw new IOException("Duplicate partition number reading UDF Partition Descriptor"); } Context.PhysicalPartitions[pd.PartitionNumber] = new PhysicalPartition(pd, dataBuffer, _sectorSize); break; case TagIdentifier.LogicalVolumeDescriptor: _lvd = LogicalVolumeDescriptor.FromStream(_data, sector, _sectorSize); break; case TagIdentifier.UnallocatedSpaceDescriptor: // Not used for reading break; case TagIdentifier.TerminatingDescriptor: terminatorFound = true; break; default: break; } sector++; } // Convert logical partition descriptors into actual partition objects for (int i = 0; i < _lvd.PartitionMaps.Length; ++i) { Context.LogicalPartitions.Add(LogicalPartition.FromDescriptor(Context, _lvd, i)); } byte[] fsdBuffer = UdfUtilities.ReadExtent(Context, _lvd.FileSetDescriptorLocation); if (DescriptorTag.IsValid(fsdBuffer, 0)) { FileSetDescriptor fsd = Utilities.ToStruct <FileSetDescriptor>(fsdBuffer, 0); RootDirectory = (Directory)File.FromDescriptor(Context, fsd.RootDirectoryIcb); } }