private void ReadExtentDescriptors(LongAllocationDescriptor lad, long filePos) { byte[] allocExtDescBin = UdfUtilities.ReadExtent(_context, lad); ExtentAllocationDescriptor allocExtDesc = Utilities.ToStruct <ExtentAllocationDescriptor>(allocExtDescBin, 0); int i = 0; long extentLengths = 0; var activeBuffer = allocExtDesc.AllocationDescriptors; while (i < activeBuffer.Length) { LongAllocationDescriptor extentLongAllocationDescriptor = Utilities.ToStruct <LongAllocationDescriptor>(activeBuffer, i); if (extentLongAllocationDescriptor.ExtentLength == 0) { break; } if (extentLongAllocationDescriptor.Flags == ShortAllocationFlags.RecordedAndAllocated) { CookedExtent newExtent = new CookedExtent { FileContentOffset = filePos + extentLengths, Partition = extentLongAllocationDescriptor.ExtentLocation.Partition, StartPos = extentLongAllocationDescriptor.ExtentLocation.LogicalBlock * (long)_blockSize, Length = extentLongAllocationDescriptor.ExtentLength }; _extents.Add(newExtent); extentLengths += newExtent.Length; } else if (extentLongAllocationDescriptor.Flags == ShortAllocationFlags.NextExtentOfAllocationDescriptors) { ReadExtentDescriptors(extentLongAllocationDescriptor, filePos + extentLengths); } i += extentLongAllocationDescriptor.Size; } }
public static File FromDescriptor(UdfContext context, LongAllocationDescriptor icb) { LogicalPartition partition = context.LogicalPartitions[icb.ExtentLocation.Partition]; byte[] rootDirData = UdfUtilities.ReadExtent(context, icb); DescriptorTag rootDirTag = EndianUtilities.ToStruct <DescriptorTag>(rootDirData, 0); if (rootDirTag.TagIdentifier == TagIdentifier.ExtendedFileEntry) { ExtendedFileEntry fileEntry = EndianUtilities.ToStruct <ExtendedFileEntry>(rootDirData, 0); if (fileEntry.InformationControlBlock.FileType == FileType.Directory) { return(new Directory(context, partition, fileEntry)); } return(new File(context, partition, fileEntry, (uint)partition.LogicalBlockSize)); } if (rootDirTag.TagIdentifier == TagIdentifier.FileEntry) { FileEntry fileEntry = EndianUtilities.ToStruct <FileEntry>(rootDirData, 0); if (fileEntry.InformationControlBlock.FileType == FileType.Directory) { return(new Directory(context, partition, fileEntry)); } return(new File(context, partition, fileEntry, (uint)partition.LogicalBlockSize)); } throw new NotImplementedException("Only ExtendedFileEntries implemented"); }
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); } }