Пример #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
        /// <summary>
        /// Start parsing the volume descriptor header.
        /// </summary>
        /// <param name="s">The stream to parse from.</param>
        public bool Parse(Stream s)
        {
            long startPosition = s.Position;

            byte[] buffer = new byte[ISOFile.SECTOR_SIZE];

            // Read the entire structure
            s.Read(buffer, 0, ISOFile.SECTOR_SIZE);

            // Parse based on format
            byte[] header = bc.ReadBytes(buffer, 0, ISOFile.SECTOR_SIZE);
            if (GetISO9660(header))
            {
                ParseISO9660(s);
                return(true);
            }
            if (GetCDI(header))
            {
                ParseCDInteractive(s);
                return(true);
            }

            return(false);
        }
Пример #3
0
        /// <summary>
        /// Parse the node record from the given CD-I stream.
        /// </summary>
        /// <param name="s">The stream to parse from.</param>
        public void ParseCDInteractive(Stream s)
        {
            /*
             * BP      Size in bytes   Description
             * 1       1               Record length
             * 2       1               Extended Attribute record length
             * 3       4               Reserved
             * 7       4               File beginning LBN
             * 11      4               Reserved
             * 15      4               File size
             * 19      6               Creation date
             * 25      1               Reserved
             * 26      1               File flags
             * 27      2               Interleave
             * 29      2               Reserved
             * 31      2               Album Set Sequence number
             * 33      1               File name size
             * 34      (n)             File name
             * 34+n    4               Owner ID
             * 38+n    2               Attributes
             * 40+n    2               Reserved
             * 42+n    1               File number
             * 43+n    1               Reserved
             *      43+n            Total
             */

            EndianBitConverter bc    = EndianBitConverter.CreateForLittleEndian();
            EndianBitConverter bcBig = EndianBitConverter.CreateForBigEndian();
            long startPosition       = s.Position;

            byte[] buffer = new byte[ISOFile.SECTOR_SIZE];

            // Read the entire structure
            s.Read(buffer, 0, ISOFile.SECTOR_SIZE);
            s.Position -= ISOFile.SECTOR_SIZE;

            // Get the record length
            this.Length = buffer[0];

            // extended attribute record length
            this.ExtendedAttribRecordLength = buffer[1];

            // Read Data Offset
            this.OffsetOfData = bcBig.ReadIntValue(buffer, 6, 4);

            // Read Data Length
            this.LengthOfData = bcBig.ReadIntValue(buffer, 14, 4);

            // Read the time
            var ti = bc.ReadBytes(buffer, 18, 6);

            this.Year   = ti[0];
            this.Month  = ti[1];
            this.Day    = ti[2];
            this.Hour   = ti[3];
            this.Minute = ti[4];
            this.Second = ti[5];

            // read interleave - still to do

            // read album (volume) set sequence number (we are ignoring this)

            // Read the name length
            this.NameLength = buffer[32];

            // Read the file/directory name
            var name = bc.ReadBytes(buffer, 33, this.NameLength);

            if (this.NameLength == 1 && (name[0] == 0 || name[0] == 1))
            {
                if (name[0] == 0)
                {
                    this.Name = ISONodeRecord.CURRENT_DIRECTORY;
                }
                else
                {
                    this.Name = ISONodeRecord.PARENT_DIRECTORY;
                }
            }
            else
            {
                this.Name = ASCIIEncoding.ASCII.GetString(name, 0, this.NameLength);
            }

            // skip ownerID for now

            // read the flags - only really interested in the directory attribute (bit 15)
            // (confusingly these are called 'attributes' in CD-I. the CD-I 'File Flags' entry is something else entirely)
            this.Flags = buffer[37 + this.NameLength];

            // skip filenumber
            //this.FileNumber = buffer[41 + this.NameLength];

            // Seek to end
            s.Seek(startPosition + this.Length, SeekOrigin.Begin);
        }