Пример #1
0
        /*
         *      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);
        }
Пример #2
0
        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;
            }
        }