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); } }
public File(IsoContext context, ReaderDirEntry dirEntry) { _context = context; _dirEntry = dirEntry; }
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; } } } }