/* * BP Size in bytes Description * 1 1 Name size * 2 1 Extended Attribute record length * 3 4 Directory block address * 7 2 Parent Directory number * 9 n Directory file name */ public static List <CDIPathNode> ParsePathTable(Stream s, int PathTableSize) { EndianBitConverter bc = EndianBitConverter.CreateForLittleEndian(); EndianBitConverter bcBig = EndianBitConverter.CreateForBigEndian(); byte[] buffer = new byte[ISOFile.SECTOR_SIZE]; // Read the entire structure s.Read(buffer, 0, ISOFile.SECTOR_SIZE); int startCursor = 0; List <CDIPathNode> pathNodes = new List <CDIPathNode>(); int pad = 0; do { CDIPathNode node = new CDIPathNode(); byte[] data = bc.ReadBytes(buffer, startCursor, ISOFile.SECTOR_SIZE - startCursor); node.NameLength = data[0]; node.ExtendedAttribRecordLength = data[1]; node.DirectoryBlockAddress = bcBig.ReadIntValue(data, 2, 4); node.ParentDirectoryNumber = bcBig.ReadIntValue(data, 6, 2); node.Name = Encoding.ASCII.GetString(bc.ReadBytes(data, 8, data[0])); // if nameLength is odd a padding byte must be added if (node.NameLength % 2 != 0) { pad = 1; } pathNodes.Add(node); startCursor += node.NameLength + 8; } while (startCursor < PathTableSize + pad); return(pathNodes); }
public void ParseCDInteractive(Stream s) { /* From the Green Book Spec * BP (byte position) obviously is n+1 * * BP Size in Bytes Description * 1 1 Disc Label Record Type * 2 5 Volume Structure Standard ID * 7 1 Volume Structure Version number * 8 1 Volume flags * 9 32 System identifier * 41 32 Volume identifier * 73 12 Reserved * 85 4 Volume space size * 89 32 Coded Character Set identifier * 121 2 Reserved * 123 2 Number of Volumes in Album * 125 2 Reserved * 127 2 Album Set Sequence number * 129 2 Reserved * 131 2 Logical Block size * 133 4 Reserved * 137 4 Path Table size * 141 8 Reserved * 149 4 Address of Path Table * 153 38 Reserved * 191 128 Album identifier * 319 128 Publisher identifier * 447 128 Data Preparer identifier * 575 128 Application identifier * 703 32 Copyright file name * 735 5 Reserved * 740 32 Abstract file name * 772 5 Reserved * 777 32 Bibliographic file name * 809 5 Reserved * 814 16 Creation date and time * 830 1 Reserved * 831 16 Modification date and time * 847 1 Reserved * 848 16 Expiration date and time * 864 1 Reserved * 865 16 Effective date and time * 881 1 Reserved * 882 1 File Structure Standard Version number * 883 1 Reserved * 884 512 Application use * 1396 653 Reserved */ long startPosition = s.Position; byte[] buffer = new byte[ISOFile.SECTOR_SIZE]; s.Position = startPosition - ISOFile.SECTOR_SIZE; // Read the entire structure s.Read(buffer, 0, ISOFile.SECTOR_SIZE); // Get the type this.Type = buffer[0]; // Handle the primary volume information if (this.Type == 1) { this.VolumeFlags = buffer[7]; this.SystemIdentifier = bc.ReadBytes(buffer, 8, LENGTH_SHORT_IDENTIFIER); this.VolumeIdentifier = bc.ReadBytes(buffer, 40, LENGTH_SHORT_IDENTIFIER); this.NumberOfSectors = bcBig.ReadIntValue(buffer, 84, 4); this.CodedCharSetIdent = bc.ReadBytes(buffer, 88, LENGTH_SHORT_IDENTIFIER); this.VolumeSetSize = bcBig.ReadIntValue(buffer, 122, 2); this.VolumeSequenceNumber = bcBig.ReadIntValue(buffer, 126, 2); this.SectorSize = bcBig.ReadIntValue(buffer, 130, 2); this.PathTableSize = bcBig.ReadIntValue(buffer, 136, 4); this.AddressOfPathTable = bcBig.ReadIntValue(buffer, 148, 4); this.VolumeSetIdentifier = bc.ReadBytes(buffer, 190, LENGTH_LONG_IDENTIFIER); this.PublisherIdentifier = bc.ReadBytes(buffer, 318, LENGTH_LONG_IDENTIFIER); this.DataPreparerIdentifier = bc.ReadBytes(buffer, 446, LENGTH_LONG_IDENTIFIER); this.ApplicationIdentifier = bc.ReadBytes(buffer, 574, LENGTH_LONG_IDENTIFIER); this.CopyrightFileIdentifier = bc.ReadBytes(buffer, 702, LENGTH_SHORT_IDENTIFIER); this.AbstractFileIdentifier = bc.ReadBytes(buffer, 739, LENGTH_SHORT_IDENTIFIER); this.BibliographicalFileIdentifier = bc.ReadBytes(buffer, 776, LENGTH_SHORT_IDENTIFIER); this.VolumeCreationDateTime = bc.ReadBytes(buffer, 813, 16); this.LastModifiedDateTime = bc.ReadBytes(buffer, 830, 16); this.ExpirationDateTime = bc.ReadBytes(buffer, 847, 16); this.EffectiveDateTime = bc.ReadBytes(buffer, 864, 16); // save current position long pos = s.Position; // get path table records s.Position = ISOFile.SECTOR_SIZE * this.AddressOfPathTable; ISOFile.CDIPathTable = CDIPathNode.ParsePathTable(s, this.PathTableSize); // read the root dir record s.Position = ISOFile.SECTOR_SIZE * ISOFile.CDIPathTable[0].DirectoryBlockAddress; s.Read(buffer, 0, ISOFile.SECTOR_SIZE); this.RootDirectoryRecord.Parse(buffer, 0); // go back to where we were s.Position = pos; } }