initial commit
This commit is contained in:
commit
1b60743303
274 changed files with 25866 additions and 0 deletions
199
ImageReader/ISO9660/DirectoryRecords/DirectoryRecord.cs
Normal file
199
ImageReader/ISO9660/DirectoryRecords/DirectoryRecord.cs
Normal file
|
@ -0,0 +1,199 @@
|
|||
// Decompiled with JetBrains decompiler
|
||||
// Type: ImageReader.ISO9660.DirectoryRecords.DirectoryRecord
|
||||
// Assembly: ImageReader, Version=1.5.2.0, Culture=neutral, PublicKeyToken=611be24fdeb07e08
|
||||
// MVID: E0717604-B50B-4CB4-B85C-C17F43D5C04B
|
||||
// Assembly location: ImageReader.dll
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace ImageReader.ISO9660.DirectoryRecords
|
||||
{
|
||||
public class DirectoryRecord
|
||||
{
|
||||
public static readonly char DIRECTORY_SEPARATOR_CHAR = Path.DirectorySeparatorChar;
|
||||
public static readonly string DIRECTORY_SEPARATOR = DirectoryRecord.DIRECTORY_SEPARATOR_CHAR.ToString();
|
||||
public static readonly string ROOT_DIRECTORY_NAME = DirectoryRecord.DIRECTORY_SEPARATOR_CHAR.ToString();
|
||||
public static readonly string SELF_DIRECTORY_NAME = ".";
|
||||
public static readonly string PARENT_DIRECTORY_NAME = "..";
|
||||
internal static readonly byte ROOT_OR_SELF_DIRECTORY_FILE_IDENTIFIER = 0;
|
||||
internal static readonly byte PARENT_DIRECTORY_FILE_IDENTIFIER = 1;
|
||||
internal ushort extendAttributeLength;
|
||||
internal uint extentTypeL;
|
||||
internal uint extentTypeM;
|
||||
internal uint extentSizeTypeL;
|
||||
internal uint extentSizeTypeM;
|
||||
internal ushort fileUnitSize;
|
||||
internal ushort fileGapSize;
|
||||
internal ushort volumeSequenceNumberTypeL;
|
||||
internal ushort volumeSequenceNumberTypeM;
|
||||
internal DirectoryRecord parent;
|
||||
internal List<DirectoryRecord> children;
|
||||
|
||||
public static string FindCommonPathPrefix(List<DirectoryRecord> directoryRecords)
|
||||
{
|
||||
if (directoryRecords.Count < 1)
|
||||
return (string) null;
|
||||
Dictionary<DirectoryRecord, string> source = new Dictionary<DirectoryRecord, string>();
|
||||
foreach (DirectoryRecord directoryRecord in directoryRecords)
|
||||
source[directoryRecord] = directoryRecord.IsDirectory ? directoryRecord.FullPath : Path.GetDirectoryName(directoryRecord.FullPath);
|
||||
int minDepth = source.Min<KeyValuePair<DirectoryRecord, string>>((Func<KeyValuePair<DirectoryRecord, string>, int>) (pkv => pkv.Value.Split(new char[1]
|
||||
{
|
||||
DirectoryRecord.DIRECTORY_SEPARATOR_CHAR
|
||||
}, StringSplitOptions.RemoveEmptyEntries).Length));
|
||||
string pathPrefix = source.First<KeyValuePair<DirectoryRecord, string>>((Func<KeyValuePair<DirectoryRecord, string>, bool>) (pkv => pkv.Value.Split(new char[1]
|
||||
{
|
||||
DirectoryRecord.DIRECTORY_SEPARATOR_CHAR
|
||||
}, StringSplitOptions.RemoveEmptyEntries).Length == minDepth)).Value;
|
||||
for (int index = 0; index < minDepth && !directoryRecords.TrueForAll((Predicate<DirectoryRecord>) (dr => dr.FullPath.StartsWith(pathPrefix))); ++index)
|
||||
pathPrefix = Path.GetDirectoryName(pathPrefix);
|
||||
if (directoryRecords.Count == 1 && directoryRecords[0].IsDirectory && !directoryRecords[0].IsRoot)
|
||||
pathPrefix = Path.GetDirectoryName(pathPrefix);
|
||||
return pathPrefix;
|
||||
}
|
||||
|
||||
internal DirectoryRecord() => this.children = new List<DirectoryRecord>();
|
||||
|
||||
public byte RecordLength { get; internal set; }
|
||||
|
||||
public string Name { get; internal set; }
|
||||
|
||||
public uint Extent => !BitConverter.IsLittleEndian ? this.extentTypeM : this.extentTypeL;
|
||||
|
||||
public uint ExtentSize => !BitConverter.IsLittleEndian ? this.extentSizeTypeM : this.extentSizeTypeL;
|
||||
|
||||
public DateTime? RecordingDateTime { get; internal set; }
|
||||
|
||||
public DirectoryRecordFlags Flags { get; internal set; }
|
||||
|
||||
public bool HasValidFileIdentifier { get; internal set; }
|
||||
|
||||
public ushort VolumeSequenceNumber => !BitConverter.IsLittleEndian ? this.volumeSequenceNumberTypeM : this.volumeSequenceNumberTypeL;
|
||||
|
||||
public int Depth
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.IsRoot)
|
||||
return 0;
|
||||
return this.FullPath.Split(new char[1]
|
||||
{
|
||||
Path.DirectorySeparatorChar
|
||||
}, StringSplitOptions.RemoveEmptyEntries).Length;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsHidden => (this.Flags & DirectoryRecordFlags.HIDDEN_FILE) != DirectoryRecordFlags.NONE;
|
||||
|
||||
public bool IsDirectory => (this.Flags & DirectoryRecordFlags.DIRECTORY) != DirectoryRecordFlags.NONE;
|
||||
|
||||
public bool IsAssociated => (this.Flags & DirectoryRecordFlags.ASSOCIATED_FILE) != DirectoryRecordFlags.NONE;
|
||||
|
||||
public bool HasExtentedAttributeRecord => (this.Flags & DirectoryRecordFlags.EXTENDED_ATTRIBUTE_RECORD) != DirectoryRecordFlags.NONE;
|
||||
|
||||
public bool HasOwnerAndGroupPermissions => (this.Flags & DirectoryRecordFlags.OWNER_AND_GROUP_PERMISSIONS) != DirectoryRecordFlags.NONE;
|
||||
|
||||
public bool HasReservedFlags => (this.Flags & DirectoryRecordFlags.RESERVED_FLAGS) != DirectoryRecordFlags.NONE;
|
||||
|
||||
public bool IsNotFinalRecord => (this.Flags & DirectoryRecordFlags.NOT_FINAL_RECORD) != DirectoryRecordFlags.NONE;
|
||||
|
||||
public bool IsFlagSet(DirectoryRecordFlags flags) => (this.Flags & flags) != DirectoryRecordFlags.NONE;
|
||||
|
||||
public bool IsRoot => this.parent == null;
|
||||
|
||||
public DirectoryRecord RootDirectory => this.IsRoot ? this : this.parent.RootDirectory;
|
||||
|
||||
public DirectoryRecord ParentDirectory => this.parent;
|
||||
|
||||
public List<DirectoryRecord> SubDirectories => this.children;
|
||||
|
||||
public List<DirectoryRecord> GetAllSubFolder()
|
||||
{
|
||||
List<DirectoryRecord> list = new List<DirectoryRecord>();
|
||||
this.GetAllSubDirectoriesRec(list, true, false);
|
||||
return list;
|
||||
}
|
||||
|
||||
public List<DirectoryRecord> GetAllSubFiles()
|
||||
{
|
||||
List<DirectoryRecord> list = new List<DirectoryRecord>();
|
||||
this.GetAllSubDirectoriesRec(list, false, true);
|
||||
return list;
|
||||
}
|
||||
|
||||
public List<DirectoryRecord> GetAllSubDirectories()
|
||||
{
|
||||
List<DirectoryRecord> list = new List<DirectoryRecord>();
|
||||
this.GetAllSubDirectoriesRec(list, true, true);
|
||||
return list;
|
||||
}
|
||||
|
||||
private void GetAllSubDirectoriesRec(
|
||||
List<DirectoryRecord> list,
|
||||
bool includeFolders,
|
||||
bool includeFiles)
|
||||
{
|
||||
foreach (DirectoryRecord child in this.children)
|
||||
{
|
||||
if (includeFolders && child.IsDirectory)
|
||||
list.Add(child);
|
||||
if (includeFiles && !child.IsDirectory)
|
||||
list.Add(child);
|
||||
child.GetAllSubDirectoriesRec(list, includeFolders, includeFiles);
|
||||
}
|
||||
}
|
||||
|
||||
public bool Contains(string directoryRecordName) => this.children.Find((Predicate<DirectoryRecord>) (directoryRecord => directoryRecord.Name.Equals(directoryRecordName))) != null;
|
||||
|
||||
public DirectoryRecord Find(DirectoryRecord directoryRecord)
|
||||
{
|
||||
if (directoryRecord == this)
|
||||
return this;
|
||||
DirectoryRecord directoryRecord1 = (DirectoryRecord) null;
|
||||
if (directoryRecord.FullPath.StartsWith(this.FullPath))
|
||||
{
|
||||
foreach (DirectoryRecord child in this.children)
|
||||
{
|
||||
directoryRecord1 = child.Find(directoryRecord);
|
||||
if (directoryRecord1 != null)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return directoryRecord1;
|
||||
}
|
||||
|
||||
public DirectoryRecord Find(string path)
|
||||
{
|
||||
if (this.FullPath.Equals(path))
|
||||
return this;
|
||||
DirectoryRecord directoryRecord = (DirectoryRecord) null;
|
||||
if (path.StartsWith(this.FullPath))
|
||||
{
|
||||
foreach (DirectoryRecord child in this.children)
|
||||
{
|
||||
directoryRecord = child.Find(path);
|
||||
if (directoryRecord != null)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return directoryRecord;
|
||||
}
|
||||
|
||||
public string FullPath => this.parent != null ? Path.Combine(this.parent.FullPath, this.Name) : this.Name;
|
||||
|
||||
public uint UsedSpace
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!this.IsDirectory)
|
||||
return this.ExtentSize;
|
||||
uint num = 0;
|
||||
foreach (DirectoryRecord child in this.children)
|
||||
num += child.UsedSpace;
|
||||
return num;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
114
ImageReader/ISO9660/DirectoryRecords/DirectoryRecordConverter.cs
Normal file
114
ImageReader/ISO9660/DirectoryRecords/DirectoryRecordConverter.cs
Normal file
|
@ -0,0 +1,114 @@
|
|||
// Decompiled with JetBrains decompiler
|
||||
// Type: ImageReader.ISO9660.DirectoryRecords.DirectoryRecordConverter
|
||||
// Assembly: ImageReader, Version=1.5.2.0, Culture=neutral, PublicKeyToken=611be24fdeb07e08
|
||||
// MVID: E0717604-B50B-4CB4-B85C-C17F43D5C04B
|
||||
// Assembly location: ImageReader.dll
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace ImageReader.ISO9660.DirectoryRecords
|
||||
{
|
||||
public class DirectoryRecordConverter
|
||||
{
|
||||
private static readonly Logger.ILog logger = Logger.CreateLog();
|
||||
private static readonly byte DIRECTORY_RECORD_MIN_SIZE = 34;
|
||||
private static readonly byte OFFSET_RECORD_LENGTH = 0;
|
||||
private static readonly byte OFFSET_EXTENDED_ATTRIBUTE_LENGTH = 1;
|
||||
private static readonly byte OFFSET_TYPE_L_EXTENT_LOCATION = 2;
|
||||
private static readonly byte OFFSET_TYPE_M_EXTENT_LOCATION = 6;
|
||||
private static readonly byte OFFSET_TYPE_L_EXTENT_SIZE = 10;
|
||||
private static readonly byte OFFSET_TYPE_M_EXTENT_SIZE = 14;
|
||||
private static readonly byte OFFSET_DATETIME = 18;
|
||||
private static readonly byte OFFSET_FLAGS = 25;
|
||||
private static readonly byte OFFSET_INTERLEAVED_FILE_UNIT_SIZE = 26;
|
||||
private static readonly byte OFFSET_INTERLEAVED_FILE_GAP_SIZE = 27;
|
||||
private static readonly byte OFFSET_TYPE_L_VOLUME_SEQUENCE_NUMBER = 28;
|
||||
private static readonly byte OFFSET_TYPE_M_VOLUME_SEQUENCE_NUMBER = 30;
|
||||
private static readonly byte OFFSET_FILE_IDENTIFIER_LENGTH = 32;
|
||||
private static readonly byte OFFSET_FILE_IDENTIFIER = 33;
|
||||
private static readonly Regex VALID_FILENAME = new Regex("[^A-Z0-9._]+", RegexOptions.IgnoreCase);
|
||||
|
||||
public static DirectoryRecord ToDirectoryRecord(byte[] buffer, int startIndex) => DirectoryRecordConverter.ToDirectoryRecord(buffer, startIndex, false);
|
||||
|
||||
public static DirectoryRecord ToRootDirectoryRecord(
|
||||
byte[] buffer,
|
||||
int startIndex)
|
||||
{
|
||||
return DirectoryRecordConverter.ToDirectoryRecord(buffer, startIndex, true);
|
||||
}
|
||||
|
||||
private static DirectoryRecord ToDirectoryRecord(
|
||||
byte[] buffer,
|
||||
int startIndex,
|
||||
bool isForRootDirectory)
|
||||
{
|
||||
byte num1 = buffer[startIndex + (int) DirectoryRecordConverter.OFFSET_RECORD_LENGTH];
|
||||
if (startIndex < 0 || buffer.Length - startIndex < (int) num1 || (int) num1 < (int) DirectoryRecordConverter.DIRECTORY_RECORD_MIN_SIZE)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
DirectoryRecord directoryRecord = new DirectoryRecord();
|
||||
directoryRecord.RecordLength = num1;
|
||||
directoryRecord.extendAttributeLength = (ushort) buffer[startIndex + (int) DirectoryRecordConverter.OFFSET_EXTENDED_ATTRIBUTE_LENGTH];
|
||||
directoryRecord.extentTypeL = BitConverter.ToUInt32(buffer, startIndex + (int) DirectoryRecordConverter.OFFSET_TYPE_L_EXTENT_LOCATION);
|
||||
directoryRecord.extentTypeM = BitConverter.ToUInt32(buffer, startIndex + (int) DirectoryRecordConverter.OFFSET_TYPE_M_EXTENT_LOCATION);
|
||||
directoryRecord.extentSizeTypeL = BitConverter.ToUInt32(buffer, startIndex + (int) DirectoryRecordConverter.OFFSET_TYPE_L_EXTENT_SIZE);
|
||||
directoryRecord.extentSizeTypeM = BitConverter.ToUInt32(buffer, startIndex + (int) DirectoryRecordConverter.OFFSET_TYPE_M_EXTENT_SIZE);
|
||||
directoryRecord.RecordingDateTime = DirectoryRecordConverter.DirectoryRecordDateTimeConverter.ToDateTime(buffer, startIndex + (int) DirectoryRecordConverter.OFFSET_DATETIME);
|
||||
directoryRecord.Flags = (DirectoryRecordFlags) buffer[startIndex + (int) DirectoryRecordConverter.OFFSET_FLAGS];
|
||||
directoryRecord.fileUnitSize = (ushort) buffer[startIndex + (int) DirectoryRecordConverter.OFFSET_INTERLEAVED_FILE_UNIT_SIZE];
|
||||
directoryRecord.fileGapSize = (ushort) buffer[startIndex + (int) DirectoryRecordConverter.OFFSET_INTERLEAVED_FILE_GAP_SIZE];
|
||||
directoryRecord.volumeSequenceNumberTypeL = BitConverter.ToUInt16(buffer, startIndex + (int) DirectoryRecordConverter.OFFSET_TYPE_L_VOLUME_SEQUENCE_NUMBER);
|
||||
directoryRecord.volumeSequenceNumberTypeM = BitConverter.ToUInt16(buffer, startIndex + (int) DirectoryRecordConverter.OFFSET_TYPE_M_VOLUME_SEQUENCE_NUMBER);
|
||||
byte num2 = buffer[startIndex + (int) DirectoryRecordConverter.OFFSET_FILE_IDENTIFIER_LENGTH];
|
||||
if ((int) buffer[startIndex + (int) DirectoryRecordConverter.OFFSET_FILE_IDENTIFIER] == (int) DirectoryRecord.ROOT_OR_SELF_DIRECTORY_FILE_IDENTIFIER)
|
||||
directoryRecord.Name = !isForRootDirectory ? DirectoryRecord.SELF_DIRECTORY_NAME : DirectoryRecord.ROOT_DIRECTORY_NAME;
|
||||
else if ((int) buffer[startIndex + (int) DirectoryRecordConverter.OFFSET_FILE_IDENTIFIER] == (int) DirectoryRecord.PARENT_DIRECTORY_FILE_IDENTIFIER)
|
||||
{
|
||||
directoryRecord.Name = DirectoryRecord.PARENT_DIRECTORY_NAME;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!directoryRecord.IsDirectory)
|
||||
num2 -= (byte) 2;
|
||||
string input = Encoding.Default.GetString(buffer, startIndex + (int) DirectoryRecordConverter.OFFSET_FILE_IDENTIFIER, (int) num2);
|
||||
directoryRecord.Name = DirectoryRecordConverter.VALID_FILENAME.Replace(input, "_invalid_");
|
||||
directoryRecord.HasValidFileIdentifier = directoryRecord.Name.Equals(input);
|
||||
}
|
||||
return directoryRecord;
|
||||
}
|
||||
|
||||
private sealed class DirectoryRecordDateTimeConverter
|
||||
{
|
||||
private static readonly byte DATETIME_SIZE = 7;
|
||||
private static readonly byte OFFSET_YEAR = 0;
|
||||
private static readonly byte OFFSET_MONTH = 1;
|
||||
private static readonly byte OFFSET_DAY = 2;
|
||||
private static readonly byte OFFSET_HOUR = 3;
|
||||
private static readonly byte OFFSET_MINUTE = 4;
|
||||
private static readonly byte OFFSET_SECOND = 5;
|
||||
private static readonly byte OFFSET_TIME_ZONE = 6;
|
||||
|
||||
internal static DateTime? ToDateTime(byte[] buffer, int startIndex)
|
||||
{
|
||||
if (startIndex < 0 || buffer.Length - startIndex < (int) DirectoryRecordConverter.DirectoryRecordDateTimeConverter.DATETIME_SIZE)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
byte num1 = buffer[startIndex + (int) DirectoryRecordConverter.DirectoryRecordDateTimeConverter.OFFSET_YEAR];
|
||||
byte num2 = buffer[startIndex + (int) DirectoryRecordConverter.DirectoryRecordDateTimeConverter.OFFSET_MONTH];
|
||||
byte num3 = buffer[startIndex + (int) DirectoryRecordConverter.DirectoryRecordDateTimeConverter.OFFSET_DAY];
|
||||
byte num4 = buffer[startIndex + (int) DirectoryRecordConverter.DirectoryRecordDateTimeConverter.OFFSET_HOUR];
|
||||
byte num5 = buffer[startIndex + (int) DirectoryRecordConverter.DirectoryRecordDateTimeConverter.OFFSET_MINUTE];
|
||||
byte num6 = buffer[startIndex + (int) DirectoryRecordConverter.DirectoryRecordDateTimeConverter.OFFSET_SECOND];
|
||||
try
|
||||
{
|
||||
return new DateTime?(new DateTime(1900 + (int) num1, (int) num2, (int) num3, (int) num4, (int) num5, (int) num6, DateTimeKind.Local));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error(ex);
|
||||
return new DateTime?();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
24
ImageReader/ISO9660/DirectoryRecords/DirectoryRecordFlags.cs
Normal file
24
ImageReader/ISO9660/DirectoryRecords/DirectoryRecordFlags.cs
Normal file
|
@ -0,0 +1,24 @@
|
|||
// Decompiled with JetBrains decompiler
|
||||
// Type: ImageReader.ISO9660.DirectoryRecords.DirectoryRecordFlags
|
||||
// Assembly: ImageReader, Version=1.5.2.0, Culture=neutral, PublicKeyToken=611be24fdeb07e08
|
||||
// MVID: E0717604-B50B-4CB4-B85C-C17F43D5C04B
|
||||
// Assembly location: ImageReader.dll
|
||||
|
||||
using System;
|
||||
|
||||
namespace ImageReader.ISO9660.DirectoryRecords
|
||||
{
|
||||
[Flags]
|
||||
public enum DirectoryRecordFlags : byte
|
||||
{
|
||||
NONE = 0,
|
||||
HIDDEN_FILE = 1,
|
||||
DIRECTORY = 2,
|
||||
ASSOCIATED_FILE = 4,
|
||||
EXTENDED_ATTRIBUTE_RECORD = 8,
|
||||
OWNER_AND_GROUP_PERMISSIONS = EXTENDED_ATTRIBUTE_RECORD | ASSOCIATED_FILE | DIRECTORY | HIDDEN_FILE, // 0x0F
|
||||
RESERVED_FLAGS = 48, // 0x30
|
||||
NOT_FINAL_RECORD = 64, // 0x40
|
||||
ANY = 255, // 0xFF
|
||||
}
|
||||
}
|
40
ImageReader/ISO9660/PathTable/PathTableEntry.cs
Normal file
40
ImageReader/ISO9660/PathTable/PathTableEntry.cs
Normal file
|
@ -0,0 +1,40 @@
|
|||
// Decompiled with JetBrains decompiler
|
||||
// Type: ImageReader.ISO9660.PathTable.PathTableEntry
|
||||
// Assembly: ImageReader, Version=1.5.2.0, Culture=neutral, PublicKeyToken=611be24fdeb07e08
|
||||
// MVID: E0717604-B50B-4CB4-B85C-C17F43D5C04B
|
||||
// Assembly location: ImageReader.dll
|
||||
|
||||
namespace ImageReader.ISO9660.PathTable
|
||||
{
|
||||
public class PathTableEntry
|
||||
{
|
||||
private byte extentAttributeRecordLength;
|
||||
private uint extent;
|
||||
private ushort parentDirectoryIndex;
|
||||
private string directoryIdentifier;
|
||||
|
||||
public byte ExtentAttributeRecordLength
|
||||
{
|
||||
get => this.extentAttributeRecordLength;
|
||||
internal set => this.extentAttributeRecordLength = value;
|
||||
}
|
||||
|
||||
public uint Extent
|
||||
{
|
||||
get => this.extent;
|
||||
internal set => this.extent = value;
|
||||
}
|
||||
|
||||
public ushort ParentDirectoryIndex
|
||||
{
|
||||
get => this.parentDirectoryIndex;
|
||||
internal set => this.parentDirectoryIndex = value;
|
||||
}
|
||||
|
||||
public string DirectoryIdentifier
|
||||
{
|
||||
get => this.directoryIdentifier;
|
||||
internal set => this.directoryIdentifier = value;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
// Decompiled with JetBrains decompiler
|
||||
// Type: ImageReader.ISO9660.VolumeDescriptors.PrimaryVolumeDescriptor
|
||||
// Assembly: ImageReader, Version=1.5.2.0, Culture=neutral, PublicKeyToken=611be24fdeb07e08
|
||||
// MVID: E0717604-B50B-4CB4-B85C-C17F43D5C04B
|
||||
// Assembly location: ImageReader.dll
|
||||
|
||||
using ImageReader.ISO9660.DirectoryRecords;
|
||||
using System;
|
||||
|
||||
namespace ImageReader.ISO9660.VolumeDescriptors
|
||||
{
|
||||
public class PrimaryVolumeDescriptor
|
||||
{
|
||||
internal uint volumeSpaceSizeTypeL;
|
||||
internal uint volumeSpaceSizeTypeM;
|
||||
internal ushort volumeSetSizeTypeL;
|
||||
internal ushort VolumeSetSizeTypeM;
|
||||
internal ushort volumeSequenceNumberTypeL;
|
||||
internal ushort volumeSequenceNumberTypeM;
|
||||
internal ushort logicalBlockSizeTypeL;
|
||||
internal ushort logicalBlockSizeTypeM;
|
||||
internal uint pathTableSizeTypeL;
|
||||
internal uint pathTableSizeTypeM;
|
||||
internal uint pathTableLocationTypeL;
|
||||
internal uint optionalPathTableLocationTypeL;
|
||||
internal uint pathTableLocationTypeM;
|
||||
internal uint optionalPathTableLocationTypeM;
|
||||
internal DirectoryRecord rootDirectoryRecord;
|
||||
|
||||
public VolumeDescriptorType Type { get; internal set; }
|
||||
|
||||
public string StandardIdentifier { get; internal set; }
|
||||
|
||||
public sbyte Version { get; internal set; }
|
||||
|
||||
public string SystemIdentifier { get; internal set; }
|
||||
|
||||
public string Identifier { get; internal set; }
|
||||
|
||||
public uint SpaceSize => !BitConverter.IsLittleEndian ? this.volumeSpaceSizeTypeM : this.volumeSpaceSizeTypeL;
|
||||
|
||||
public ushort SetSize => !BitConverter.IsLittleEndian ? this.VolumeSetSizeTypeM : this.volumeSetSizeTypeL;
|
||||
|
||||
public ushort SequenceNumber => !BitConverter.IsLittleEndian ? this.volumeSequenceNumberTypeM : this.volumeSequenceNumberTypeL;
|
||||
|
||||
public ushort LogicalBlockSize => !BitConverter.IsLittleEndian ? this.logicalBlockSizeTypeM : this.logicalBlockSizeTypeL;
|
||||
|
||||
public uint PathTableSize => !BitConverter.IsLittleEndian ? this.pathTableSizeTypeM : this.pathTableSizeTypeL;
|
||||
|
||||
public uint PathTableLocation => !BitConverter.IsLittleEndian ? this.pathTableLocationTypeM : this.pathTableLocationTypeL;
|
||||
|
||||
public bool HasOptionalPathTable => (BitConverter.IsLittleEndian ? (int) this.optionalPathTableLocationTypeL : (int) this.optionalPathTableLocationTypeM) != 0;
|
||||
|
||||
public uint OptionalPathTableLocation => !BitConverter.IsLittleEndian ? this.optionalPathTableLocationTypeM : this.optionalPathTableLocationTypeL;
|
||||
|
||||
public DirectoryRecord RootDirectoryRecord => this.rootDirectoryRecord;
|
||||
|
||||
public string SetIdentifier { get; internal set; }
|
||||
|
||||
public string PublisherIdentifier { get; internal set; }
|
||||
|
||||
public string PreparerIdentifier { get; internal set; }
|
||||
|
||||
public string ApplicationIdentifier { get; internal set; }
|
||||
|
||||
public string CopyrightFileIdentifier { get; internal set; }
|
||||
|
||||
public string AbstractFileIdentifier { get; internal set; }
|
||||
|
||||
public string BibliographicFileIdentifier { get; internal set; }
|
||||
|
||||
public DateTime? CreationDateTime { get; internal set; }
|
||||
|
||||
public DateTime? ModificationDateTime { get; internal set; }
|
||||
|
||||
public DateTime? ExpirationDateTime { get; internal set; }
|
||||
|
||||
public DateTime? EffectiveDateTime { get; internal set; }
|
||||
|
||||
public sbyte FileStructureVersion { get; internal set; }
|
||||
}
|
||||
}
|
23
ImageReader/ISO9660/VolumeDescriptors/VolumeDescriptor.cs
Normal file
23
ImageReader/ISO9660/VolumeDescriptors/VolumeDescriptor.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Decompiled with JetBrains decompiler
|
||||
// Type: ImageReader.ISO9660.VolumeDescriptors.VolumeDescriptor
|
||||
// Assembly: ImageReader, Version=1.5.2.0, Culture=neutral, PublicKeyToken=611be24fdeb07e08
|
||||
// MVID: E0717604-B50B-4CB4-B85C-C17F43D5C04B
|
||||
// Assembly location: ImageReader.dll
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace ImageReader.ISO9660.VolumeDescriptors
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct VolumeDescriptor
|
||||
{
|
||||
public const string VolumeDescriptorIdentifier = "CD001";
|
||||
public static readonly ushort VolumeDescriptorStartLba = 16;
|
||||
public static readonly ushort VolumeDescriptorSize = 2048;
|
||||
public static readonly byte VolumeDescriptorVersion = 1;
|
||||
public VolumeDescriptorType Type;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
|
||||
public byte[] StandardIdentifier;
|
||||
public byte Version;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
// Decompiled with JetBrains decompiler
|
||||
// Type: ImageReader.ISO9660.VolumeDescriptors.VolumeDescriptorConverter
|
||||
// Assembly: ImageReader, Version=1.5.2.0, Culture=neutral, PublicKeyToken=611be24fdeb07e08
|
||||
// MVID: E0717604-B50B-4CB4-B85C-C17F43D5C04B
|
||||
// Assembly location: ImageReader.dll
|
||||
|
||||
using ImageReader.ISO9660.DirectoryRecords;
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace ImageReader.ISO9660.VolumeDescriptors
|
||||
{
|
||||
public class VolumeDescriptorConverter
|
||||
{
|
||||
private static readonly string STANDARD_IDENTIFIER = "CD001";
|
||||
private static readonly byte VOLUME_DESCRIPTOR_VERSION = 1;
|
||||
private static readonly byte FILE_STRUCTURE_VERSION = 1;
|
||||
private static readonly ushort OFFSET_VOLUME_DESCRIPTOR_TYPE = 0;
|
||||
private static readonly ushort OFFSET_STANDARD_IDENTIFIER = 1;
|
||||
private static readonly ushort OFFSET_VOLUME_DESCRIPTOR_VERSION = 6;
|
||||
private static readonly ushort OFFSET_SYSTEM_IDENTIFIER = 8;
|
||||
private static readonly ushort OFFSET_VOLUME_IDENTIFIER = 40;
|
||||
private static readonly ushort OFFSET_TYPE_L_VOLUME_SPACE_SIZE = 80;
|
||||
private static readonly ushort OFFSET_TYPE_M_VOLUME_SPACE_SIZE = 84;
|
||||
private static readonly ushort OFFSET_TYPE_L_VOLUME_SET_SIZE = 120;
|
||||
private static readonly ushort OFFSET_TYPE_M_VOLUME_SET_SIZE = 122;
|
||||
private static readonly ushort OFFSET_TYPE_L_VOLUME_SEQUENCE_NUMBER = 124;
|
||||
private static readonly ushort OFFSET_TYPE_M_VOLUME_SEQUENCE_NUMBER = 126;
|
||||
private static readonly ushort OFFSET_TYPE_L_LOGICAL_BLOCK_SIZE = 128;
|
||||
private static readonly ushort OFFSET_TYPE_M_LOGICAL_BLOCK_SIZE = 130;
|
||||
private static readonly ushort OFFSET_TYPE_L_PATH_TABLE_SIZE = 132;
|
||||
private static readonly ushort OFFSET_TYPE_M_PATH_TABLE_SIZE = 136;
|
||||
private static readonly ushort OFFSET_TYPE_L_PATH_TABLE = 140;
|
||||
private static readonly ushort OFFSET_TYPE_L_OPTIONAL_PATH_TABLE = 144;
|
||||
private static readonly ushort OFFSET_TYPE_M_PATH_TABLE = 148;
|
||||
private static readonly ushort OFFSET_TYPE_M_OPTIONAL_PATH_TABLE = 152;
|
||||
private static readonly ushort OFFSET_ROOT_DIRECTORY_RECORD = 156;
|
||||
private static readonly ushort OFFSET_VOLUME_SET_IDENTIFIER = 190;
|
||||
private static readonly ushort OFFSET_PUBLISHER_IDENTIFIER = 318;
|
||||
private static readonly ushort OFFSET_PREPARER_IDENTIFIER = 446;
|
||||
private static readonly ushort OFFSET_APPLICATION_IDENTIFIER = 574;
|
||||
private static readonly ushort OFFSET_COPYRIGHT_FILE_IDENTIFIER = 702;
|
||||
private static readonly ushort OFFSET_ABSTRACT_FILE_IDENTIFIER = 739;
|
||||
private static readonly ushort OFFSET_BIBLIOGRAPHIC_FILE_IDENTIFIER = 776;
|
||||
private static readonly ushort OFFSET_VOLUME_CREATION_DATE = 813;
|
||||
private static readonly ushort OFFSET_VOLUME_MODIFICATION_DATE = 830;
|
||||
private static readonly ushort OFFSET_VOLUME_EXPIRATION_DATE = 847;
|
||||
private static readonly ushort OFFSET_VOLUME_EFFECTIVE_DATE = 864;
|
||||
private static readonly ushort OFFSET_FILE_STRUCTURE_VERSION = 881;
|
||||
|
||||
public static PrimaryVolumeDescriptor ToPrimaryVolumeDescriptor(
|
||||
byte[] buffer,
|
||||
int startIndex)
|
||||
{
|
||||
if (startIndex < 0 || buffer.Length - startIndex < (int) VolumeDescriptor.VolumeDescriptorSize)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
PrimaryVolumeDescriptor volumeDescriptor = new PrimaryVolumeDescriptor()
|
||||
{
|
||||
Type = (VolumeDescriptorType) buffer[startIndex + (int) VolumeDescriptorConverter.OFFSET_VOLUME_DESCRIPTOR_TYPE],
|
||||
StandardIdentifier = Encoding.Default.GetString(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_STANDARD_IDENTIFIER, 5),
|
||||
Version = (sbyte) buffer[startIndex + (int) VolumeDescriptorConverter.OFFSET_VOLUME_DESCRIPTOR_VERSION],
|
||||
SystemIdentifier = Encoding.Default.GetString(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_SYSTEM_IDENTIFIER, 32).Trim(),
|
||||
Identifier = Encoding.Default.GetString(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_VOLUME_IDENTIFIER, 32).Trim(),
|
||||
volumeSpaceSizeTypeL = BitConverter.ToUInt32(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_TYPE_L_VOLUME_SPACE_SIZE),
|
||||
volumeSpaceSizeTypeM = BitConverter.ToUInt32(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_TYPE_M_VOLUME_SPACE_SIZE),
|
||||
volumeSetSizeTypeL = BitConverter.ToUInt16(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_TYPE_L_VOLUME_SET_SIZE),
|
||||
VolumeSetSizeTypeM = BitConverter.ToUInt16(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_TYPE_M_VOLUME_SET_SIZE),
|
||||
volumeSequenceNumberTypeL = BitConverter.ToUInt16(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_TYPE_L_VOLUME_SEQUENCE_NUMBER),
|
||||
volumeSequenceNumberTypeM = BitConverter.ToUInt16(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_TYPE_M_VOLUME_SEQUENCE_NUMBER),
|
||||
logicalBlockSizeTypeL = BitConverter.ToUInt16(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_TYPE_L_LOGICAL_BLOCK_SIZE),
|
||||
logicalBlockSizeTypeM = BitConverter.ToUInt16(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_TYPE_M_LOGICAL_BLOCK_SIZE),
|
||||
pathTableSizeTypeL = BitConverter.ToUInt32(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_TYPE_L_PATH_TABLE_SIZE),
|
||||
pathTableSizeTypeM = BitConverter.ToUInt32(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_TYPE_M_PATH_TABLE_SIZE),
|
||||
pathTableLocationTypeL = BitConverter.ToUInt32(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_TYPE_L_PATH_TABLE),
|
||||
optionalPathTableLocationTypeL = BitConverter.ToUInt32(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_TYPE_L_OPTIONAL_PATH_TABLE),
|
||||
pathTableLocationTypeM = BitConverter.ToUInt32(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_TYPE_M_PATH_TABLE),
|
||||
optionalPathTableLocationTypeM = BitConverter.ToUInt32(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_TYPE_M_OPTIONAL_PATH_TABLE),
|
||||
SetIdentifier = Encoding.Default.GetString(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_VOLUME_SET_IDENTIFIER, 128).Trim(),
|
||||
PublisherIdentifier = Encoding.Default.GetString(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_PUBLISHER_IDENTIFIER, 128).Trim(),
|
||||
PreparerIdentifier = Encoding.Default.GetString(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_PREPARER_IDENTIFIER, 128).Trim(),
|
||||
ApplicationIdentifier = Encoding.Default.GetString(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_APPLICATION_IDENTIFIER, 128).Trim(),
|
||||
CopyrightFileIdentifier = Encoding.Default.GetString(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_COPYRIGHT_FILE_IDENTIFIER, 37).Trim(),
|
||||
AbstractFileIdentifier = Encoding.Default.GetString(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_ABSTRACT_FILE_IDENTIFIER, 37).Trim(),
|
||||
BibliographicFileIdentifier = Encoding.Default.GetString(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_BIBLIOGRAPHIC_FILE_IDENTIFIER, 37).Trim(),
|
||||
CreationDateTime = VolumeDescriptorConverter.VolumeDescriptorDateTimeConverter.ToDateTime(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_VOLUME_CREATION_DATE),
|
||||
ModificationDateTime = VolumeDescriptorConverter.VolumeDescriptorDateTimeConverter.ToDateTime(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_VOLUME_MODIFICATION_DATE),
|
||||
ExpirationDateTime = VolumeDescriptorConverter.VolumeDescriptorDateTimeConverter.ToDateTime(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_VOLUME_EXPIRATION_DATE),
|
||||
EffectiveDateTime = VolumeDescriptorConverter.VolumeDescriptorDateTimeConverter.ToDateTime(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_VOLUME_EFFECTIVE_DATE),
|
||||
FileStructureVersion = (sbyte) buffer[startIndex + (int) VolumeDescriptorConverter.OFFSET_FILE_STRUCTURE_VERSION]
|
||||
};
|
||||
volumeDescriptor.rootDirectoryRecord = DirectoryRecordConverter.ToRootDirectoryRecord(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_ROOT_DIRECTORY_RECORD);
|
||||
if (!VolumeDescriptorConverter.STANDARD_IDENTIFIER.Equals(volumeDescriptor.StandardIdentifier) || volumeDescriptor.Type != VolumeDescriptorType.PRIMARY_VOLUME_DESCRIPTOR || (int) volumeDescriptor.Version != (int) VolumeDescriptorConverter.VOLUME_DESCRIPTOR_VERSION)
|
||||
throw new FormatException();
|
||||
return volumeDescriptor;
|
||||
}
|
||||
|
||||
private sealed class VolumeDescriptorDateTimeConverter
|
||||
{
|
||||
private static readonly Logger.ILog logger = Logger.CreateLog();
|
||||
|
||||
private const int DATETIME_SIZE = 17;
|
||||
private const int OFFSET_YEAR = 0;
|
||||
private const int OFFSET_MONTH = 4;
|
||||
private const int OFFSET_DAY = 6;
|
||||
private const int OFFSET_HOUR = 8;
|
||||
private const int OFFSET_MINUTE = 10;
|
||||
private const int OFFSET_SECOND = 12;
|
||||
private const int OFFSET_HUNDREDTHS_OF_SECOND = 14;
|
||||
private const int OFFSET_TIME_ZONE = 16;
|
||||
|
||||
internal static DateTime? ToDateTime(byte[] buffer, int startIndex)
|
||||
{
|
||||
if (startIndex < 0 || buffer.Length - startIndex < 17)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
string str = Encoding.Default.GetString(buffer, startIndex, 16);
|
||||
ushort result1;
|
||||
ushort.TryParse(str.Substring(0, 4), out result1);
|
||||
byte result2;
|
||||
byte.TryParse(str.Substring(4, 2), out result2);
|
||||
byte result3;
|
||||
byte.TryParse(str.Substring(6, 2), out result3);
|
||||
byte result4;
|
||||
byte.TryParse(str.Substring(8, 2), out result4);
|
||||
byte result5;
|
||||
byte.TryParse(str.Substring(10, 2), out result5);
|
||||
byte result6;
|
||||
byte.TryParse(str.Substring(12, 2), out result6);
|
||||
byte result7;
|
||||
byte.TryParse(str.Substring(14, 2), out result7);
|
||||
try
|
||||
{
|
||||
return new DateTime?(new DateTime((int) result1, (int) result2, (int) result3, (int) result4, (int) result5, (int) result6, (int) result7 * 100, DateTimeKind.Local));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Warn(ex);
|
||||
return new DateTime?();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
// Decompiled with JetBrains decompiler
|
||||
// Type: ImageReader.ISO9660.VolumeDescriptors.VolumeDescriptorType
|
||||
// Assembly: ImageReader, Version=1.5.2.0, Culture=neutral, PublicKeyToken=611be24fdeb07e08
|
||||
// MVID: E0717604-B50B-4CB4-B85C-C17F43D5C04B
|
||||
// Assembly location: ImageReader.dll
|
||||
|
||||
namespace ImageReader.ISO9660.VolumeDescriptors
|
||||
{
|
||||
public enum VolumeDescriptorType : byte
|
||||
{
|
||||
BOOT_RECORD = 0,
|
||||
PRIMARY_VOLUME_DESCRIPTOR = 1,
|
||||
SUPPLEMENTARY_VOLUME_DESCRIPTOR = 2,
|
||||
VOLUME_PARTITION_DESCRIPTOR = 3,
|
||||
VOLUME_DESCRIPTION_SET_TERMINATOR = 255, // 0xFF
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue