PathTable ReadPathTable(BasicVolumeDescriptor descriptor, Endian endian) { Assert.IsNotNull(descriptor, nameof(descriptor)); Assert.IsTrue(endian == Endian.BigEndian || endian == Endian.LittleEndian, "Endian must be set to either little or big."); if (endian == Endian.BigEndian) { Reader.Position = descriptor.TypeMPathTableLocation * DefaultSectorSize; } else { Reader.Position = descriptor.TypeLPathTableLocation * DefaultSectorSize; } var buffer = Reader.ReadBytes((Int32)descriptor.PathTableSize); var pathtable = new PathTable(endian); for (var offset = 0; offset < buffer.Length;) { var namelength = buffer[offset + 0]; var extendedsectors = buffer[offset + 1]; var sector = BinaryIO.ReadUInt32FromBuffer(buffer, offset + 2, endian); var parentindex = BinaryIO.ReadUInt16FromBuffer(buffer, offset + 6, endian); var name = Encodings.ASCII.GetString(buffer, offset + 8, namelength).Trim(' '); pathtable.Items.Add(new PathTableItem(name, sector, parentindex)); offset += MathUtil.RoundUp(8 + namelength, 2); } return(pathtable); }
void WriteBasicVolumeDescriptor(BinaryWriter writer, BasicVolumeDescriptor descriptor) { Assert.IsNotNull(writer, nameof(writer)); Assert.IsNotNull(descriptor, nameof(descriptor)); var buffer = new Byte[DefaultSectorSize]; buffer[0] = (Byte)descriptor.VolumeDescriptorType; BinaryIO.WriteIntoBuffer(buffer, 1, Encodings.ASCII, descriptor.StandardIdentifier, 5, ' '); buffer[6] = descriptor.VolumeDescriptorVersion; BinaryIO.WriteIntoBuffer(buffer, 8, Encodings.ASCII, descriptor.SystemIdentifier, 32, ' '); BinaryIO.WriteIntoBuffer(buffer, 40, Encodings.ASCII, descriptor.VolumeIdentifier, 32, ' '); BinaryIO.WriteIntoBuffer(buffer, 80, descriptor.VolumeSpaceSize, Endian.LittleEndian); BinaryIO.WriteIntoBuffer(buffer, 84, descriptor.VolumeSpaceSize, Endian.BigEndian); BinaryIO.WriteIntoBuffer(buffer, 120, descriptor.VolumeSetSize, Endian.LittleEndian); BinaryIO.WriteIntoBuffer(buffer, 122, descriptor.VolumeSetSize, Endian.BigEndian); BinaryIO.WriteIntoBuffer(buffer, 124, descriptor.VolumeSequenceNumber, Endian.LittleEndian); BinaryIO.WriteIntoBuffer(buffer, 126, descriptor.VolumeSequenceNumber, Endian.BigEndian); BinaryIO.WriteIntoBuffer(buffer, 128, descriptor.LogicalBlockSize, Endian.LittleEndian); BinaryIO.WriteIntoBuffer(buffer, 130, descriptor.LogicalBlockSize, Endian.BigEndian); BinaryIO.WriteIntoBuffer(buffer, 132, descriptor.PathTableSize, Endian.LittleEndian); BinaryIO.WriteIntoBuffer(buffer, 136, descriptor.PathTableSize, Endian.BigEndian); BinaryIO.WriteIntoBuffer(buffer, 140, descriptor.TypeLPathTableLocation, Endian.LittleEndian); BinaryIO.WriteIntoBuffer(buffer, 144, descriptor.OptionalTypeLPathTableLocation, Endian.LittleEndian); BinaryIO.WriteIntoBuffer(buffer, 148, descriptor.TypeMPathTableLocation, Endian.BigEndian); BinaryIO.WriteIntoBuffer(buffer, 152, descriptor.OptionalTypeMPathTableLocation, Endian.BigEndian); WriteDirectoryRecord(buffer, 156, descriptor.RootDirectory); BinaryIO.WriteIntoBuffer(buffer, 190, Encodings.ASCII, descriptor.VolumeSetIdentifier, 128, ' '); BinaryIO.WriteIntoBuffer(buffer, 318, Encodings.ASCII, descriptor.PublisherIdentifier, 128, ' '); BinaryIO.WriteIntoBuffer(buffer, 446, Encodings.ASCII, descriptor.DataPreparerIdentifier, 128, ' '); BinaryIO.WriteIntoBuffer(buffer, 574, Encodings.ASCII, descriptor.ApplicationIdentifier, 128, ' '); BinaryIO.WriteIntoBuffer(buffer, 702, Encodings.ASCII, descriptor.CopyrightFileIdentifier, 37, ' '); BinaryIO.WriteIntoBuffer(buffer, 739, Encodings.ASCII, descriptor.AbstractFileIdentifier, 37, ' '); BinaryIO.WriteIntoBuffer(buffer, 776, Encodings.ASCII, descriptor.BibliographicFileIdentifier, 37, ' '); WriteVolumeDescriptorDateTime(buffer, 813, descriptor.CreationDateAndTime); WriteVolumeDescriptorDateTime(buffer, 830, descriptor.ModificationDateAndTime); WriteVolumeDescriptorDateTime(buffer, 847, descriptor.ExpirationDateAndTime); WriteVolumeDescriptorDateTime(buffer, 864, descriptor.EffectiveDateAndTime); buffer[881] = descriptor.FileStructureVersion; writer.Write(buffer); }
/// <summary> /// Reads the <see cref="VolumeDescriptor"/> at the current position of the image file. /// </summary> /// <returns>The <see cref="VolumeDescriptor"/> located at the current file position.</returns> VolumeDescriptor ReadVolumeDescriptor() { var buffer = Reader.ReadBytes(DefaultSectorSize); var type = (VolumeDescriptorType)buffer[0]; if (type == VolumeDescriptorType.Primary) { var descriptor = new BasicVolumeDescriptor(); descriptor.VolumeDescriptorType = type; descriptor.StandardIdentifier = Encodings.ASCII.GetString(buffer, 1, 5); descriptor.VolumeDescriptorVersion = buffer[6]; descriptor.SystemIdentifier = Encodings.ASCII.GetString(buffer, 8, 32).Trim(' '); descriptor.VolumeIdentifier = Encodings.ASCII.GetString(buffer, 40, 32).Trim(' '); descriptor.VolumeSpaceSize = BinaryIO.ReadUInt32FromBuffer(buffer, 80, Endian.LittleEndian); descriptor.VolumeSetSize = BinaryIO.ReadUInt16FromBuffer(buffer, 120, Endian.LittleEndian); descriptor.VolumeSequenceNumber = BinaryIO.ReadUInt16FromBuffer(buffer, 124, Endian.LittleEndian); descriptor.LogicalBlockSize = BinaryIO.ReadUInt16FromBuffer(buffer, 128, Endian.LittleEndian); descriptor.PathTableSize = BinaryIO.ReadUInt32FromBuffer(buffer, 132, Endian.LittleEndian); descriptor.TypeLPathTableLocation = BinaryIO.ReadUInt32FromBuffer(buffer, 140, Endian.LittleEndian); descriptor.OptionalTypeLPathTableLocation = BinaryIO.ReadUInt32FromBuffer(buffer, 144, Endian.LittleEndian); descriptor.TypeMPathTableLocation = BinaryIO.ReadUInt32FromBuffer(buffer, 148, Endian.BigEndian); descriptor.OptionalTypeMPathTableLocation = BinaryIO.ReadUInt32FromBuffer(buffer, 152, Endian.BigEndian); descriptor.RootDirectory = ReadDirectoryRecord(buffer, 156); descriptor.VolumeSetIdentifier = Encodings.ASCII.GetString(buffer, 190, 128).Trim(' '); descriptor.PublisherIdentifier = Encodings.ASCII.GetString(buffer, 318, 128).Trim(' '); descriptor.DataPreparerIdentifier = Encodings.ASCII.GetString(buffer, 446, 128).Trim(' '); descriptor.ApplicationIdentifier = Encodings.ASCII.GetString(buffer, 574, 128).Trim(' '); descriptor.CopyrightFileIdentifier = Encodings.ASCII.GetString(buffer, 702, 37).Trim(' '); descriptor.AbstractFileIdentifier = Encodings.ASCII.GetString(buffer, 739, 37).Trim(' '); descriptor.BibliographicFileIdentifier = Encodings.ASCII.GetString(buffer, 776, 37).Trim(' '); descriptor.CreationDateAndTime = ReadVolumeDescriptorDateTime(buffer, 813); descriptor.ModificationDateAndTime = ReadVolumeDescriptorDateTime(buffer, 830); descriptor.ExpirationDateAndTime = ReadVolumeDescriptorDateTime(buffer, 847); descriptor.EffectiveDateAndTime = ReadVolumeDescriptorDateTime(buffer, 864); descriptor.FileStructureVersion = buffer[881]; return(descriptor); } if (type == VolumeDescriptorType.SetTerminator) { var descriptor = new SetTerminatorVolumeDescriptor(); descriptor.VolumeDescriptorType = type; descriptor.StandardIdentifier = Encodings.ASCII.GetString(buffer, 1, 5); descriptor.VolumeDescriptorVersion = buffer[6]; return(descriptor); } throw new Exception(); }
Dictionary <DirectoryRecord, List <DirectoryRecord> > ReadDirectoryRecords(BasicVolumeDescriptor descriptor) { Assert.IsNotNull(descriptor, nameof(descriptor)); var directorytree = new Dictionary <DirectoryRecord, List <DirectoryRecord> >(); var workinglist = new Stack <DirectoryRecord>(); workinglist.Push(descriptor.RootDirectory); while (workinglist.Count > 0) { var dir = workinglist.Pop(); var children = ReadChildrenDirectoryRecords(dir); var sectorobj = new DirectoryRecordSector(); sectorobj.Records.AddRange(children); SectorMap[dir.SectorNumber] = sectorobj; directorytree[dir] = new List <DirectoryRecord>(); foreach (var child in children.Skip(2)) { if ((child.Flags & DirectoryRecordFlags.Directory) == DirectoryRecordFlags.Directory) { workinglist.Push(child); } else { SectorMap[child.SectorNumber] = new FileSector(child, () => FileSectorReadFunc((Int32)child.SectorNumber, (Int32)child.DataLength)); } directorytree[dir].Add(child); } } return(directorytree); }