public static int ReadFrom(byte[] src, int offset, Encoding enc, out DirectoryRecord record) { int length = src[offset + 0]; record = new DirectoryRecord(); record.ExtendedAttributeRecordLength = src[offset + 1]; record.LocationOfExtent = IsoUtilities.ToUInt32FromBoth(src, offset + 2); record.DataLength = IsoUtilities.ToUInt32FromBoth(src, offset + 10); record.RecordingDateAndTime = IsoUtilities.ToUTCDateTimeFromDirectoryTime(src, offset + 18); record.Flags = (FileFlags)src[offset + 25]; record.FileUnitSize = src[offset + 26]; record.InterleaveGapSize = src[offset + 27]; record.VolumeSequenceNumber = IsoUtilities.ToUInt16FromBoth(src, offset + 28); byte lengthOfFileIdentifier = src[offset + 32]; record.FileIdentifier = IsoUtilities.ReadChars(src, offset + 33, lengthOfFileIdentifier, enc); int padding = (lengthOfFileIdentifier & 1) == 0 ? 1 : 0; int startSystemArea = lengthOfFileIdentifier + padding + 33; int lenSystemArea = length - startSystemArea; if (lenSystemArea > 0) { record.SystemUseData = new byte[lenSystemArea]; Array.Copy(src, offset + startSystemArea, record.SystemUseData, 0, lenSystemArea); } return(length); }
internal override void WriteTo(byte[] buffer, int offset) { base.WriteTo(buffer, offset); IsoUtilities.WriteA1Chars(buffer, offset + 8, 32, SystemIdentifier, CharacterEncoding); IsoUtilities.WriteString(buffer, offset + 40, 32, true, VolumeIdentifier, CharacterEncoding, true); IsoUtilities.ToBothFromUInt32(buffer, offset + 80, VolumeSpaceSize); IsoUtilities.EncodingToBytes(CharacterEncoding, buffer, offset + 88); IsoUtilities.ToBothFromUInt16(buffer, offset + 120, VolumeSetSize); IsoUtilities.ToBothFromUInt16(buffer, offset + 124, VolumeSequenceNumber); IsoUtilities.ToBothFromUInt16(buffer, offset + 128, LogicalBlockSize); IsoUtilities.ToBothFromUInt32(buffer, offset + 132, PathTableSize); IsoUtilities.ToBytesFromUInt32(buffer, offset + 140, TypeLPathTableLocation); IsoUtilities.ToBytesFromUInt32(buffer, offset + 144, OptionalTypeLPathTableLocation); IsoUtilities.ToBytesFromUInt32(buffer, offset + 148, Utilities.BitSwap(TypeMPathTableLocation)); IsoUtilities.ToBytesFromUInt32(buffer, offset + 152, Utilities.BitSwap(OptionalTypeMPathTableLocation)); RootDirectory.WriteTo(buffer, offset + 156, CharacterEncoding); IsoUtilities.WriteD1Chars(buffer, offset + 190, 129, VolumeSetIdentifier, CharacterEncoding); IsoUtilities.WriteA1Chars(buffer, offset + 318, 129, PublisherIdentifier, CharacterEncoding); IsoUtilities.WriteA1Chars(buffer, offset + 446, 129, DataPreparerIdentifier, CharacterEncoding); IsoUtilities.WriteA1Chars(buffer, offset + 574, 129, ApplicationIdentifier, CharacterEncoding); IsoUtilities.WriteD1Chars(buffer, offset + 702, 37, CopyrightFileIdentifier, CharacterEncoding); // FIXME!! IsoUtilities.WriteD1Chars(buffer, offset + 739, 37, AbstractFileIdentifier, CharacterEncoding); // FIXME!! IsoUtilities.WriteD1Chars(buffer, offset + 776, 37, BibliographicFileIdentifier, CharacterEncoding); // FIXME!! IsoUtilities.ToVolumeDescriptorTimeFromUTC(buffer, offset + 813, CreationDateAndTime); IsoUtilities.ToVolumeDescriptorTimeFromUTC(buffer, offset + 830, ModificationDateAndTime); IsoUtilities.ToVolumeDescriptorTimeFromUTC(buffer, offset + 847, ExpirationDateAndTime); IsoUtilities.ToVolumeDescriptorTimeFromUTC(buffer, offset + 864, EffectiveDateAndTime); buffer[offset + 881] = FileStructureVersion; }
internal int WriteTo(byte[] buffer, int offset, Encoding enc) { uint length = CalcLength(FileIdentifier, enc); buffer[offset] = (byte)length; buffer[offset + 1] = ExtendedAttributeRecordLength; IsoUtilities.ToBothFromUInt32(buffer, offset + 2, LocationOfExtent); IsoUtilities.ToBothFromUInt32(buffer, offset + 10, DataLength); IsoUtilities.ToDirectoryTimeFromUTC(buffer, offset + 18, RecordingDateAndTime); buffer[offset + 25] = (byte)Flags; buffer[offset + 26] = FileUnitSize; buffer[offset + 27] = InterleaveGapSize; IsoUtilities.ToBothFromUInt16(buffer, offset + 28, VolumeSequenceNumber); byte lengthOfFileIdentifier; if (FileIdentifier.Length == 1 && FileIdentifier[0] <= 1) { buffer[offset + 33] = (byte)FileIdentifier[0]; lengthOfFileIdentifier = 1; } else { lengthOfFileIdentifier = (byte)IsoUtilities.WriteString(buffer, offset + 33, (int)(length - 33), false, FileIdentifier, enc); } buffer[offset + 32] = lengthOfFileIdentifier; return((int)length); }
public CommonVolumeDescriptor(byte[] src, int offset, Encoding enc) : base(src, offset) { CharacterEncoding = enc; SystemIdentifier = IsoUtilities.ReadChars(src, offset + 8, 32, CharacterEncoding); VolumeIdentifier = IsoUtilities.ReadChars(src, offset + 40, 32, CharacterEncoding); VolumeSpaceSize = IsoUtilities.ToUInt32FromBoth(src, offset + 80); VolumeSetSize = IsoUtilities.ToUInt16FromBoth(src, offset + 120); VolumeSequenceNumber = IsoUtilities.ToUInt16FromBoth(src, offset + 124); LogicalBlockSize = IsoUtilities.ToUInt16FromBoth(src, offset + 128); PathTableSize = IsoUtilities.ToUInt32FromBoth(src, offset + 132); TypeLPathTableLocation = EndianUtilities.ToUInt32LittleEndian(src, offset + 140); OptionalTypeLPathTableLocation = EndianUtilities.ToUInt32LittleEndian(src, offset + 144); TypeMPathTableLocation = Utilities.BitSwap(EndianUtilities.ToUInt32LittleEndian(src, offset + 148)); OptionalTypeMPathTableLocation = Utilities.BitSwap(EndianUtilities.ToUInt32LittleEndian(src, offset + 152)); DirectoryRecord.ReadFrom(src, offset + 156, CharacterEncoding, out RootDirectory); VolumeSetIdentifier = IsoUtilities.ReadChars(src, offset + 190, 318 - 190, CharacterEncoding); PublisherIdentifier = IsoUtilities.ReadChars(src, offset + 318, 446 - 318, CharacterEncoding); DataPreparerIdentifier = IsoUtilities.ReadChars(src, offset + 446, 574 - 446, CharacterEncoding); ApplicationIdentifier = IsoUtilities.ReadChars(src, offset + 574, 702 - 574, CharacterEncoding); CopyrightFileIdentifier = IsoUtilities.ReadChars(src, offset + 702, 739 - 702, CharacterEncoding); AbstractFileIdentifier = IsoUtilities.ReadChars(src, offset + 739, 776 - 739, CharacterEncoding); BibliographicFileIdentifier = IsoUtilities.ReadChars(src, offset + 776, 813 - 776, CharacterEncoding); CreationDateAndTime = IsoUtilities.ToDateTimeFromVolumeDescriptorTime(src, offset + 813); ModificationDateAndTime = IsoUtilities.ToDateTimeFromVolumeDescriptorTime(src, offset + 830); ExpirationDateAndTime = IsoUtilities.ToDateTimeFromVolumeDescriptorTime(src, offset + 847); EffectiveDateAndTime = IsoUtilities.ToDateTimeFromVolumeDescriptorTime(src, offset + 864); FileStructureVersion = src[offset + 881]; }
internal BuildFileInfo(string name, BuildDirectoryInfo parent, byte[] content) : base(IsoUtilities.NormalizeFileName(name), MakeShortFileName(name, parent)) { _parent = parent; _contentData = content; _contentSize = content.LongLength; }
private static string MakeShortFileName(string longName, BuildDirectoryInfo dir) { if (IsoUtilities.IsValidFileName(longName)) { return(longName); } char[] shortNameChars = longName.ToUpper(CultureInfo.InvariantCulture).ToCharArray(); for (int i = 0; i < shortNameChars.Length; ++i) { if (!IsoUtilities.IsValidDChar(shortNameChars[i]) && shortNameChars[i] != '.' && shortNameChars[i] != ';') { shortNameChars[i] = '_'; } } string[] parts = IsoUtilities.SplitFileName(new string(shortNameChars)); if (parts[0].Length + parts[1].Length > 30) { parts[1] = parts[1].Substring(0, Math.Min(parts[1].Length, 3)); } if (parts[0].Length + parts[1].Length > 30) { parts[0] = parts[0].Substring(0, 30 - parts[1].Length); } string candidate = parts[0] + '.' + parts[1] + ';' + parts[2]; // TODO: Make unique return(candidate); }
internal virtual void WriteTo(byte[] buffer, int offset) { Array.Clear(buffer, offset, SectorSize); buffer[offset] = (byte)VolumeDescriptorType; IsoUtilities.WriteAChars(buffer, offset + 1, 5, StandardIdentifier); buffer[offset + 6] = VolumeDescriptorVersion; }
internal BuildFileInfo(string name, BuildDirectoryInfo parent, string content) : base(IsoUtilities.NormalizeFileName(name), MakeShortFileName(name, parent)) { _parent = parent; _contentPath = content; _contentSize = new FileInfo(_contentPath).Length; }
internal BuildFileInfo(string name, BuildDirectoryInfo parent, Stream source) : base(IsoUtilities.NormalizeFileName(name), MakeShortFileName(name, parent)) { _parent = parent; _contentStream = source; _contentSize = _contentStream.Length; }
public ReaderDirEntry GetEntryByName(string name) { bool anyVerMatch = name.IndexOf(';') < 0; string normName = IsoUtilities.NormalizeFileName(name).ToUpper(CultureInfo.InvariantCulture); if (anyVerMatch) { normName = normName.Substring(0, normName.LastIndexOf(';') + 1); } foreach (ReaderDirEntry r in _records) { string toComp = IsoUtilities.NormalizeFileName(r.FileName).ToUpper(CultureInfo.InvariantCulture); if (!anyVerMatch && toComp == normName) { return(r); } if (anyVerMatch && toComp.StartsWith(normName, StringComparison.Ordinal)) { return(r); } } return(null); }
public ChildLinkSystemUseEntry(byte[] data, int offset) { byte len = data[offset + 2]; Name = "CL"; Version = data[offset + 3]; CheckLengthAndVersion(len, 12, 1); ChildDirLocation = IsoUtilities.ToUInt32FromBoth(data, offset + 4); }
public ReaderDirectory(IsoContext context, ReaderDirEntry dirEntry) : base(context, dirEntry) { byte[] buffer = new byte[IsoUtilities.SectorSize]; Stream extent = new ExtentStream(_context.DataStream, dirEntry.Record.LocationOfExtent, uint.MaxValue, 0, 0); _records = new List <ReaderDirEntry>(); uint totalLength = dirEntry.Record.DataLength; uint totalRead = 0; while (totalRead < totalLength) { int toRead = (int)Math.Min(buffer.Length, totalLength - totalRead); uint bytesRead = (uint)Utilities.ReadFully(extent, buffer, 0, toRead); if (bytesRead != toRead) { throw new IOException("Failed to read whole directory"); } 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 ContinuationSystemUseEntry(byte[] data, int offset) { byte len = data[offset + 2]; Name = "CE"; Version = data[offset + 3]; CheckLengthAndVersion(len, 28, 1); Block = IsoUtilities.ToUInt32FromBoth(data, offset + 4); BlockOffset = IsoUtilities.ToUInt32FromBoth(data, offset + 12); Length = IsoUtilities.ToUInt32FromBoth(data, offset + 20); }
//public static int ReadFrom(byte[] src, int offset, bool byteSwap, Encoding enc, out PathTableRecord record) //{ // byte directoryIdentifierLength = src[offset + 0]; // record.ExtendedAttributeRecordLength = src[offset + 1]; // record.LocationOfExtent = Utilities.ToUInt32LittleEndian(src, offset + 2); // record.ParentDirectoryNumber = Utilities.ToUInt16LittleEndian(src, offset + 6); // record.DirectoryIdentifier = IsoUtilities.ReadChars(src, offset + 8, directoryIdentifierLength, enc); // if (byteSwap) // { // record.LocationOfExtent = Utilities.BitSwap(record.LocationOfExtent); // record.ParentDirectoryNumber = Utilities.BitSwap(record.ParentDirectoryNumber); // } // return directoryIdentifierLength + 8 + (((directoryIdentifierLength & 1) == 1) ? 1 : 0); //} internal int Write(bool byteSwap, Encoding enc, byte[] buffer, int offset) { int nameBytes = enc.GetByteCount(DirectoryIdentifier); buffer[offset + 0] = (byte)nameBytes; buffer[offset + 1] = 0; // ExtendedAttributeRecordLength; IsoUtilities.ToBytesFromUInt32(buffer, offset + 2, byteSwap ? Utilities.BitSwap(LocationOfExtent) : LocationOfExtent); IsoUtilities.ToBytesFromUInt16(buffer, offset + 6, byteSwap ? Utilities.BitSwap(ParentDirectoryNumber) : ParentDirectoryNumber); IsoUtilities.WriteString(buffer, offset + 8, nameBytes, false, DirectoryIdentifier, enc); if ((nameBytes & 1) == 1) { buffer[offset + 8 + nameBytes] = 0; } return((int)(8 + nameBytes + (((nameBytes & 0x1) == 1) ? 1 : 0))); }
private static string MakeShortDirName(string longName) { if (IsoUtilities.IsValidDirectoryName(longName)) { return(longName); } char[] shortNameChars = longName.ToUpper(CultureInfo.InvariantCulture).ToCharArray(); for (int i = 0; i < shortNameChars.Length; ++i) { if (!IsoUtilities.IsValidDChar(shortNameChars[i]) && shortNameChars[i] != '.' && shortNameChars[i] != ';') { shortNameChars[i] = '_'; } } return(new string(shortNameChars)); }
public static int ReadFrom(byte[] src, int offset, Encoding enc, out DirectoryRecord record) { int length = src[offset + 0]; record = new DirectoryRecord(); record.ExtendedAttributeRecordLength = src[offset + 1]; record.LocationOfExtent = IsoUtilities.ToUInt32FromBoth(src, offset + 2); record.DataLength = IsoUtilities.ToUInt32FromBoth(src, offset + 10); record.RecordingDateAndTime = IsoUtilities.ToUTCDateTimeFromDirectoryTime(src, offset + 18); record.Flags = (FileFlags)src[offset + 25]; record.FileUnitSize = src[offset + 26]; record.InterleaveGapSize = src[offset + 27]; record.VolumeSequenceNumber = IsoUtilities.ToUInt16FromBoth(src, offset + 28); byte lengthOfFileIdentifier = src[offset + 32]; record.FileIdentifier = IsoUtilities.ReadChars(src, offset + 33, lengthOfFileIdentifier, enc); return(length); }
public ExtensionSystemUseEntry(string name, byte length, byte version, byte[] data, int offset, Encoding encoding) { CheckAndSetCommonProperties(name, length, version, 8, 1); int lenId = data[offset + 4]; int lenDescriptor = data[offset + 5]; int lenSource = data[offset + 6]; ExtensionVersion = data[offset + 7]; if (length < 8 + lenId + lenDescriptor + lenSource) { throw new InvalidDataException("Invalid SUSP ER entry - too short, only " + length + " bytes - expected: " + (8 + lenId + lenDescriptor + lenSource)); } ExtensionIdentifier = IsoUtilities.ReadChars(data, offset + 8, lenId, encoding); ExtensionDescriptor = IsoUtilities.ReadChars(data, offset + 8 + lenId, lenDescriptor, encoding); ExtensionSource = IsoUtilities.ReadChars(data, offset + 8 + lenId + lenDescriptor, lenSource, encoding); }
private DateTime ReadTimestamp(Timestamps timestamp, byte[] data, bool longForm, ref int pos) { DateTime result = DateTime.MinValue; if ((TimestampsPresent & timestamp) != 0) { if (longForm) { result = IsoUtilities.ToDateTimeFromVolumeDescriptorTime(data, pos); pos += 17; } else { result = IsoUtilities.ToUTCDateTimeFromDirectoryTime(data, pos); pos += 7; } } return(result); }
public ExtensionSystemUseEntry(byte[] data, int offset, Encoding encoding) { byte len = data[offset + 2]; Name = "ER"; Version = data[offset + 3]; CheckLengthAndVersion(len, 8, 1); int lenId = data[offset + 4]; int lenDescriptor = data[offset + 5]; int lenSource = data[offset + 6]; ExtensionVersion = data[offset + 7]; if (len < 8 + lenId + lenDescriptor + lenSource) { throw new InvalidDataException("Invalid SUSP ER entry - too short, only " + len + " bytes - expected: " + (8 + lenId + lenDescriptor + lenSource)); } ExtensionIdentifier = IsoUtilities.ReadChars(data, offset + 8, lenId, encoding); ExtensionDescriptor = IsoUtilities.ReadChars(data, offset + 8 + lenId, lenDescriptor, encoding); ExtensionSource = IsoUtilities.ReadChars(data, offset + 8 + lenId + lenDescriptor, lenSource, encoding); }
public ReaderDirectory(IsoContext context, DirectoryRecord dirEntry) : base(context, dirEntry) { byte[] buffer = new byte[IsoUtilities.SectorSize]; Stream extent = new ExtentStream(_context.DataStream, dirEntry.LocationOfExtent, uint.MaxValue, 0, 0); _records = new List <DirectoryRecord>(); uint totalLength = dirEntry.DataLength; uint totalRead = 0; while (totalRead < totalLength) { int toRead = (int)Math.Min(buffer.Length, totalLength - totalRead); uint bytesRead = (uint)Utilities.ReadFully(extent, buffer, 0, toRead); if (bytesRead != toRead) { throw new IOException("Failed to read whole directory"); } 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)) { _records.Add(dr); } pos += length; } } }
public IEnumerable <ReaderDirEntry> GetEntriesByName(string name) { // It's possible that this file has multiple extents. Get them all bool anyVerMatch = name.IndexOf(';') < 0; string normName = IsoUtilities.NormalizeFileName(name).ToUpper(CultureInfo.InvariantCulture); if (anyVerMatch) { normName = normName.Substring(0, normName.LastIndexOf(';') + 1); } foreach (ReaderDirEntry r in _records) { string toComp = IsoUtilities.NormalizeFileName(r.FileName).ToUpper(CultureInfo.InvariantCulture); if (!anyVerMatch && toComp == normName) { yield return(r); } else if (anyVerMatch && toComp.StartsWith(normName, StringComparison.Ordinal)) { yield return(r); } } }
public SupplementaryVolumeDescriptor(byte[] src, int offset) : base(src, offset, IsoUtilities.EncodingFromBytes(src, offset + 88)) { }