private ContinuationSystemUseEntry Parse(IsoContext context, byte[] data, int offset)
        {
            ContinuationSystemUseEntry contEntry = null;
            SuspExtension extension = null;

            if (context.SuspExtensions != null && context.SuspExtensions.Count > 0)
            {
                extension = context.SuspExtensions[0];
            }

            int pos = offset;

            while (data.Length - pos > 4)
            {
                byte           len;
                SystemUseEntry entry = SystemUseEntry.Parse(data, pos, context.VolumeDescriptor.CharacterEncoding,
                                                            extension, out len);
                pos += len;

                if (entry == null)
                {
                    // A null entry indicates SUSP parsing must terminate.
                    // This will occur if a termination record is found,
                    // or if there is a problem with the SUSP data.
                    return(contEntry);
                }

                switch (entry.Name)
                {
                case "CE":
                    contEntry = (ContinuationSystemUseEntry)entry;
                    break;

                case "ES":
                    ExtensionSelectSystemUseEntry esEntry = (ExtensionSelectSystemUseEntry)entry;
                    extension = context.SuspExtensions[esEntry.SelectedExtension];
                    break;

                case "PD":
                    break;

                case "SP":
                case "ER":
                    StoreEntry(null, entry);
                    break;

                default:
                    StoreEntry(extension, entry);
                    break;
                }
            }

            return(contEntry);
        }
        public ReaderDirectory(IsoContext context, ReaderDirEntry dirEntry)
            : base(context, dirEntry)
        {
            byte[] buffer = new byte[context.SectorSize];
            Stream extent = new ExtentStream(_context.DataStream, dirEntry.Record.LocationOfExtent, uint.MaxValue, 0, 0, context.SectorSize);

            _records = new List <ReaderDirEntry>();

            uint totalLength = dirEntry.Record.DataLength;
            uint totalRead   = 0;

            while (totalRead < totalLength)
            {
                int bytesRead = (int)Math.Min(buffer.Length, totalLength - totalRead);

                extent.Seek(24, SeekOrigin.Current);

                StreamUtilities.ReadExact(extent, buffer, 0, bytesRead);
                totalRead += (uint)bytesRead;

                uint pos = 0;
                while (pos < bytesRead && buffer[pos] != 0)
                {
                    DirectoryRecord dr;
                    uint            length = (uint)DirectoryRecord.ReadFrom(buffer, (int)pos, context.VolumeDescriptor.CharacterEncoding, out dr);

                    if (!IsoUtilities.IsSpecialDirectory(dr))
                    {
                        ReaderDirEntry childDirEntry = new ReaderDirEntry(_context, dr);

                        if (context.SuspDetected && !string.IsNullOrEmpty(context.RockRidgeIdentifier))
                        {
                            if (childDirEntry.SuspRecords == null || !childDirEntry.SuspRecords.HasEntry(context.RockRidgeIdentifier, "RE"))
                            {
                                _records.Add(childDirEntry);
                            }
                        }
                        else
                        {
                            _records.Add(childDirEntry);
                        }
                    }
                    else if (dr.FileIdentifier == "\0")
                    {
                        Self = new ReaderDirEntry(_context, dr);
                    }

                    pos += length;
                }
            }
        }
        public SuspRecords(IsoContext context, byte[] data, int offset)
        {
            _records = new Dictionary <string, Dictionary <string, List <SystemUseEntry> > >();

            ContinuationSystemUseEntry contEntry = Parse(context, data, offset + context.SuspSkipBytes);

            while (contEntry != null)
            {
                context.DataStream.Position = contEntry.Block * (long)context.VolumeDescriptor.LogicalBlockSize +
                                              contEntry.BlockOffset;
                byte[] contData = StreamUtilities.ReadExact(context.DataStream, (int)contEntry.Length);

                contEntry = Parse(context, contData, 0);
            }
        }
示例#4
0
 public File(IsoContext context, ReaderDirEntry dirEntry)
 {
     _context  = context;
     _dirEntry = dirEntry;
 }
示例#5
0
        public ReaderDirEntry(IsoContext context, DirectoryRecord dirRecord)
        {
            _context  = context;
            _record   = dirRecord;
            _fileName = _record.FileIdentifier;

            bool rockRidge = !string.IsNullOrEmpty(_context.RockRidgeIdentifier);

            if (context.SuspDetected && _record.SystemUseData != null)
            {
                SuspRecords = new SuspRecords(_context, _record.SystemUseData, 0);
            }

            if (rockRidge && SuspRecords != null)
            {
                // The full name is taken from this record, even if it's a child-link record
                List <SystemUseEntry> nameEntries = SuspRecords.GetEntries(_context.RockRidgeIdentifier, "NM");
                StringBuilder         rrName      = new StringBuilder();
                if (nameEntries != null && nameEntries.Count > 0)
                {
                    foreach (PosixNameSystemUseEntry nameEntry in nameEntries)
                    {
                        rrName.Append(nameEntry.NameData);
                    }

                    _fileName = rrName.ToString();
                }

                // If this is a Rock Ridge child link, replace the dir record with that from the 'self' record
                // in the child directory.
                ChildLinkSystemUseEntry clEntry =
                    SuspRecords.GetEntry <ChildLinkSystemUseEntry>(_context.RockRidgeIdentifier, "CL");
                if (clEntry != null)
                {
                    _context.DataStream.Position = clEntry.ChildDirLocation * _context.VolumeDescriptor.LogicalBlockSize;
                    byte[] firstSector = StreamUtilities.ReadExact(_context.DataStream,
                                                                   _context.VolumeDescriptor.LogicalBlockSize);

                    DirectoryRecord.ReadFrom(firstSector, 0, _context.VolumeDescriptor.CharacterEncoding, out _record);
                    if (_record.SystemUseData != null)
                    {
                        SuspRecords = new SuspRecords(_context, _record.SystemUseData, 0);
                    }
                }
            }

            LastAccessTimeUtc = _record.RecordingDateAndTime;
            LastWriteTimeUtc  = _record.RecordingDateAndTime;
            CreationTimeUtc   = _record.RecordingDateAndTime;

            if (rockRidge && SuspRecords != null)
            {
                FileTimeSystemUseEntry tfEntry =
                    SuspRecords.GetEntry <FileTimeSystemUseEntry>(_context.RockRidgeIdentifier, "TF");

                if (tfEntry != null)
                {
                    if ((tfEntry.TimestampsPresent & FileTimeSystemUseEntry.Timestamps.Access) != 0)
                    {
                        LastAccessTimeUtc = tfEntry.AccessTime;
                    }

                    if ((tfEntry.TimestampsPresent & FileTimeSystemUseEntry.Timestamps.Modify) != 0)
                    {
                        LastWriteTimeUtc = tfEntry.ModifyTime;
                    }

                    if ((tfEntry.TimestampsPresent & FileTimeSystemUseEntry.Timestamps.Creation) != 0)
                    {
                        CreationTimeUtc = tfEntry.CreationTime;
                    }
                }
            }
        }