add stuff
This commit is contained in:
parent
8000c946bd
commit
ab38aa8ed4
|
@ -4,7 +4,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||||
-->
|
-->
|
||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<History>True|2023-04-16T21:56:35.5065135Z;True|2023-04-17T09:22:54.8607008+12:00;True|2023-04-17T08:27:16.5281469+12:00;True|2023-04-17T08:22:02.0531219+12:00;</History>
|
<History>True|2023-04-17T12:00:51.4131559Z;True|2023-04-17T09:56:35.5065135+12:00;True|2023-04-17T09:22:54.8607008+12:00;True|2023-04-17T08:27:16.5281469+12:00;True|2023-04-17T08:22:02.0531219+12:00;</History>
|
||||||
<LastFailureDetails />
|
<LastFailureDetails />
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -1,15 +0,0 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
<Import Project="../common-library.props" />
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<Description>Implementation of the ISO, UDF, FAT and NTFS file systems is now fairly stable. VHD, XVA, VMDK and VDI disk formats are implemented, as well as read/write Registry support. The library also includes a simple iSCSI initiator, for accessing disks via iSCSI and an NFS client implementation.</Description>
|
|
||||||
<AssemblyTitle>DiscUtils (for .NET and .NET Core), core library that supports parts of DiscUtils</AssemblyTitle>
|
|
||||||
<Authors>Kenneth Bell;Quamotion;LordMike</Authors>
|
|
||||||
<PackageTags>DiscUtils;VHD;VDI;XVA;VMDK;ISO;NTFS;EXT2FS</PackageTags>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\DiscUtils.Streams\DiscUtils.Streams.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
|
@ -32,14 +32,12 @@ namespace DiscUtils.Iso9660
|
||||||
public readonly string StandardIdentifier;
|
public readonly string StandardIdentifier;
|
||||||
public readonly VolumeDescriptorType VolumeDescriptorType;
|
public readonly VolumeDescriptorType VolumeDescriptorType;
|
||||||
public readonly byte VolumeDescriptorVersion;
|
public readonly byte VolumeDescriptorVersion;
|
||||||
private int SectorSize;
|
|
||||||
|
|
||||||
public BaseVolumeDescriptor(VolumeDescriptorType type, byte version, int sectorSize)
|
public BaseVolumeDescriptor(VolumeDescriptorType type, byte version)
|
||||||
{
|
{
|
||||||
VolumeDescriptorType = type;
|
VolumeDescriptorType = type;
|
||||||
StandardIdentifier = "CD001";
|
StandardIdentifier = "CD001";
|
||||||
VolumeDescriptorVersion = version;
|
VolumeDescriptorVersion = version;
|
||||||
SectorSize = sectorSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public BaseVolumeDescriptor(byte[] src, int offset)
|
public BaseVolumeDescriptor(byte[] src, int offset)
|
||||||
|
@ -51,7 +49,7 @@ namespace DiscUtils.Iso9660
|
||||||
|
|
||||||
internal virtual void WriteTo(byte[] buffer, int offset)
|
internal virtual void WriteTo(byte[] buffer, int offset)
|
||||||
{
|
{
|
||||||
Array.Clear(buffer, offset, SectorSize);
|
Array.Clear(buffer, offset, IsoUtilities.SectorSize);
|
||||||
buffer[offset] = (byte)VolumeDescriptorType;
|
buffer[offset] = (byte)VolumeDescriptorType;
|
||||||
IsoUtilities.WriteAChars(buffer, offset + 1, 5, StandardIdentifier);
|
IsoUtilities.WriteAChars(buffer, offset + 1, 5, StandardIdentifier);
|
||||||
buffer[offset + 6] = VolumeDescriptorVersion;
|
buffer[offset + 6] = VolumeDescriptorVersion;
|
||||||
|
|
|
@ -28,8 +28,8 @@ namespace DiscUtils.Iso9660
|
||||||
{
|
{
|
||||||
public const string ElToritoSystemIdentifier = "EL TORITO SPECIFICATION";
|
public const string ElToritoSystemIdentifier = "EL TORITO SPECIFICATION";
|
||||||
|
|
||||||
public BootVolumeDescriptor(uint catalogSector, int sectorSize)
|
public BootVolumeDescriptor(uint catalogSector)
|
||||||
: base(VolumeDescriptorType.Boot, 1, sectorSize)
|
: base(VolumeDescriptorType.Boot, 1)
|
||||||
{
|
{
|
||||||
CatalogSector = catalogSector;
|
CatalogSector = catalogSector;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,15 +26,15 @@ namespace DiscUtils.Iso9660
|
||||||
{
|
{
|
||||||
private readonly BootVolumeDescriptor _descriptor;
|
private readonly BootVolumeDescriptor _descriptor;
|
||||||
|
|
||||||
public BootVolumeDescriptorRegion(BootVolumeDescriptor descriptor, long start, int sectorSize)
|
public BootVolumeDescriptorRegion(BootVolumeDescriptor descriptor, long start)
|
||||||
: base(start, sectorSize)
|
: base(start)
|
||||||
{
|
{
|
||||||
_descriptor = descriptor;
|
_descriptor = descriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override byte[] GetBlockData()
|
protected override byte[] GetBlockData()
|
||||||
{
|
{
|
||||||
byte[] buffer = new byte[Length];
|
byte[] buffer = new byte[IsoUtilities.SectorSize];
|
||||||
_descriptor.WriteTo(buffer, 0);
|
_descriptor.WriteTo(buffer, 0);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,15 +39,13 @@ namespace DiscUtils.Iso9660
|
||||||
|
|
||||||
private readonly BuildDirectoryInfo _parent;
|
private readonly BuildDirectoryInfo _parent;
|
||||||
private List<BuildDirectoryMember> _sortedMembers;
|
private List<BuildDirectoryMember> _sortedMembers;
|
||||||
private int _sectorSize;
|
|
||||||
|
|
||||||
internal BuildDirectoryInfo(string name, BuildDirectoryInfo parent, int sectorSize)
|
internal BuildDirectoryInfo(string name, BuildDirectoryInfo parent)
|
||||||
: base(name, MakeShortDirName(name, parent))
|
: base(name, MakeShortDirName(name, parent))
|
||||||
{
|
{
|
||||||
_parent = parent == null ? this : parent;
|
_parent = parent == null ? this : parent;
|
||||||
HierarchyDepth = parent == null ? 0 : parent.HierarchyDepth + 1;
|
HierarchyDepth = parent == null ? 0 : parent.HierarchyDepth + 1;
|
||||||
_members = new Dictionary<string, BuildDirectoryMember>();
|
_members = new Dictionary<string, BuildDirectoryMember>();
|
||||||
_sectorSize = sectorSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal int HierarchyDepth { get; }
|
internal int HierarchyDepth { get; }
|
||||||
|
@ -89,16 +87,16 @@ namespace DiscUtils.Iso9660
|
||||||
|
|
||||||
// If this record would span a sector boundary, then the current sector is
|
// If this record would span a sector boundary, then the current sector is
|
||||||
// zero-padded, and the record goes at the start of the next sector.
|
// zero-padded, and the record goes at the start of the next sector.
|
||||||
if (total % _sectorSize + recordSize > _sectorSize)
|
if (total % IsoUtilities.SectorSize + recordSize > IsoUtilities.SectorSize)
|
||||||
{
|
{
|
||||||
long padLength = _sectorSize - total % _sectorSize;
|
long padLength = IsoUtilities.SectorSize - total % IsoUtilities.SectorSize;
|
||||||
total += padLength;
|
total += padLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
total += recordSize;
|
total += recordSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
return MathUtilities.RoundUp(total, _sectorSize);
|
return MathUtilities.RoundUp(total, IsoUtilities.SectorSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal uint GetPathTableEntrySize(Encoding enc)
|
internal uint GetPathTableEntrySize(Encoding enc)
|
||||||
|
@ -115,31 +113,31 @@ namespace DiscUtils.Iso9660
|
||||||
List<BuildDirectoryMember> sorted = GetSortedMembers();
|
List<BuildDirectoryMember> sorted = GetSortedMembers();
|
||||||
|
|
||||||
// Two pseudo entries, effectively '.' and '..'
|
// Two pseudo entries, effectively '.' and '..'
|
||||||
pos += WriteMember(this, "\0", Encoding.ASCII, buffer, offset + pos, locationTable, enc, _sectorSize);
|
pos += WriteMember(this, "\0", Encoding.ASCII, buffer, offset + pos, locationTable, enc);
|
||||||
pos += WriteMember(_parent, "\x01", Encoding.ASCII, buffer, offset + pos, locationTable, enc, _sectorSize);
|
pos += WriteMember(_parent, "\x01", Encoding.ASCII, buffer, offset + pos, locationTable, enc);
|
||||||
|
|
||||||
foreach (BuildDirectoryMember m in sorted)
|
foreach (BuildDirectoryMember m in sorted)
|
||||||
{
|
{
|
||||||
uint recordSize = m.GetDirectoryRecordSize(enc);
|
uint recordSize = m.GetDirectoryRecordSize(enc);
|
||||||
|
|
||||||
if (pos % _sectorSize + recordSize > _sectorSize)
|
if (pos % IsoUtilities.SectorSize + recordSize > IsoUtilities.SectorSize)
|
||||||
{
|
{
|
||||||
int padLength = _sectorSize - pos % _sectorSize;
|
int padLength = IsoUtilities.SectorSize - pos % IsoUtilities.SectorSize;
|
||||||
Array.Clear(buffer, offset + pos, padLength);
|
Array.Clear(buffer, offset + pos, padLength);
|
||||||
pos += padLength;
|
pos += padLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
pos += WriteMember(m, null, enc, buffer, offset + pos, locationTable, enc, _sectorSize);
|
pos += WriteMember(m, null, enc, buffer, offset + pos, locationTable, enc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure final padding data is zero'd
|
// Ensure final padding data is zero'd
|
||||||
int finalPadLength = MathUtilities.RoundUp(pos, _sectorSize) - pos;
|
int finalPadLength = MathUtilities.RoundUp(pos, IsoUtilities.SectorSize) - pos;
|
||||||
Array.Clear(buffer, offset + pos, finalPadLength);
|
Array.Clear(buffer, offset + pos, finalPadLength);
|
||||||
|
|
||||||
return pos + finalPadLength;
|
return pos + finalPadLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int WriteMember(BuildDirectoryMember m, string nameOverride, Encoding nameEnc, byte[] buffer, int offset, Dictionary<BuildDirectoryMember, uint> locationTable, Encoding dataEnc, int sectorSize)
|
private static int WriteMember(BuildDirectoryMember m, string nameOverride, Encoding nameEnc, byte[] buffer, int offset, Dictionary<BuildDirectoryMember, uint> locationTable, Encoding dataEnc)
|
||||||
{
|
{
|
||||||
DirectoryRecord dr = new DirectoryRecord();
|
DirectoryRecord dr = new DirectoryRecord();
|
||||||
dr.FileIdentifier = m.PickName(nameOverride, nameEnc);
|
dr.FileIdentifier = m.PickName(nameOverride, nameEnc);
|
||||||
|
|
|
@ -28,11 +28,8 @@ namespace DiscUtils.Iso9660
|
||||||
{
|
{
|
||||||
VolumeIdentifier = string.Empty;
|
VolumeIdentifier = string.Empty;
|
||||||
UseJoliet = true;
|
UseJoliet = true;
|
||||||
SectorSize = 2048;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int SectorSize { get; set; }
|
|
||||||
|
|
||||||
public bool UseJoliet { get; set; }
|
public bool UseJoliet { get; set; }
|
||||||
|
|
||||||
public string VolumeIdentifier { get; set; }
|
public string VolumeIdentifier { get; set; }
|
||||||
|
|
|
@ -51,7 +51,6 @@ namespace DiscUtils.Iso9660
|
||||||
|
|
||||||
private readonly List<BuildFileInfo> _files;
|
private readonly List<BuildFileInfo> _files;
|
||||||
private readonly BuildDirectoryInfo _rootDirectory;
|
private readonly BuildDirectoryInfo _rootDirectory;
|
||||||
private readonly int _sectorSize;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the CDBuilder class.
|
/// Initializes a new instance of the CDBuilder class.
|
||||||
|
@ -60,24 +59,7 @@ namespace DiscUtils.Iso9660
|
||||||
{
|
{
|
||||||
_files = new List<BuildFileInfo>();
|
_files = new List<BuildFileInfo>();
|
||||||
_dirs = new List<BuildDirectoryInfo>();
|
_dirs = new List<BuildDirectoryInfo>();
|
||||||
_sectorSize = 2048;
|
_rootDirectory = new BuildDirectoryInfo("\0", null);
|
||||||
_rootDirectory = new BuildDirectoryInfo("\0", null, _sectorSize);
|
|
||||||
_dirs.Add(_rootDirectory);
|
|
||||||
|
|
||||||
_buildParams = new BuildParameters();
|
|
||||||
_buildParams.UseJoliet = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the CDBuilder class.
|
|
||||||
/// </summary>
|
|
||||||
public CDBuilder(int sectorSize)
|
|
||||||
{
|
|
||||||
_files = new List<BuildFileInfo>();
|
|
||||||
_dirs = new List<BuildDirectoryInfo>();
|
|
||||||
_sectorSize = sectorSize;
|
|
||||||
_rootDirectory = new BuildDirectoryInfo("\0", null, _sectorSize);
|
|
||||||
_dirs.Add(_rootDirectory);
|
_dirs.Add(_rootDirectory);
|
||||||
|
|
||||||
_buildParams = new BuildParameters();
|
_buildParams = new BuildParameters();
|
||||||
|
@ -270,10 +252,10 @@ namespace DiscUtils.Iso9660
|
||||||
Dictionary<BuildDirectoryMember, uint> supplementaryLocationTable =
|
Dictionary<BuildDirectoryMember, uint> supplementaryLocationTable =
|
||||||
new Dictionary<BuildDirectoryMember, uint>();
|
new Dictionary<BuildDirectoryMember, uint>();
|
||||||
|
|
||||||
long focus = DiskStart + 3 * _buildParams.SectorSize; // Primary, Supplementary, End (fixed at end...)
|
long focus = DiskStart + 3 * IsoUtilities.SectorSize; // Primary, Supplementary, End (fixed at end...)
|
||||||
if (_bootEntry != null)
|
if (_bootEntry != null)
|
||||||
{
|
{
|
||||||
focus += _buildParams.SectorSize;
|
focus += IsoUtilities.SectorSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ####################################################################
|
// ####################################################################
|
||||||
|
@ -283,21 +265,21 @@ namespace DiscUtils.Iso9660
|
||||||
if (_bootEntry != null)
|
if (_bootEntry != null)
|
||||||
{
|
{
|
||||||
long bootImagePos = focus;
|
long bootImagePos = focus;
|
||||||
Stream realBootImage = PatchBootImage(_bootImage, (uint)(DiskStart / _buildParams.SectorSize),
|
Stream realBootImage = PatchBootImage(_bootImage, (uint)(DiskStart / IsoUtilities.SectorSize),
|
||||||
(uint)(bootImagePos / _buildParams.SectorSize));
|
(uint)(bootImagePos / IsoUtilities.SectorSize));
|
||||||
BuilderStreamExtent bootImageExtent = new BuilderStreamExtent(focus, realBootImage);
|
BuilderStreamExtent bootImageExtent = new BuilderStreamExtent(focus, realBootImage);
|
||||||
fixedRegions.Add(bootImageExtent);
|
fixedRegions.Add(bootImageExtent);
|
||||||
focus += MathUtilities.RoundUp(bootImageExtent.Length, _buildParams.SectorSize);
|
focus += MathUtilities.RoundUp(bootImageExtent.Length, IsoUtilities.SectorSize);
|
||||||
|
|
||||||
bootCatalogPos = focus;
|
bootCatalogPos = focus;
|
||||||
byte[] bootCatalog = new byte[_buildParams.SectorSize];
|
byte[] bootCatalog = new byte[IsoUtilities.SectorSize];
|
||||||
BootValidationEntry bve = new BootValidationEntry();
|
BootValidationEntry bve = new BootValidationEntry();
|
||||||
bve.WriteTo(bootCatalog, 0x00);
|
bve.WriteTo(bootCatalog, 0x00);
|
||||||
_bootEntry.ImageStart = (uint)MathUtilities.Ceil(bootImagePos, _buildParams.SectorSize);
|
_bootEntry.ImageStart = (uint)MathUtilities.Ceil(bootImagePos, IsoUtilities.SectorSize);
|
||||||
_bootEntry.SectorCount = (ushort)MathUtilities.Ceil(_bootImage.Length, Sizes.Sector);
|
_bootEntry.SectorCount = (ushort)MathUtilities.Ceil(_bootImage.Length, Sizes.Sector);
|
||||||
_bootEntry.WriteTo(bootCatalog, 0x20);
|
_bootEntry.WriteTo(bootCatalog, 0x20);
|
||||||
fixedRegions.Add(new BuilderBufferExtent(bootCatalogPos, bootCatalog));
|
fixedRegions.Add(new BuilderBufferExtent(bootCatalogPos, bootCatalog));
|
||||||
focus += _buildParams.SectorSize;
|
focus += IsoUtilities.SectorSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ####################################################################
|
// ####################################################################
|
||||||
|
@ -307,8 +289,8 @@ namespace DiscUtils.Iso9660
|
||||||
// Find end of the file data, fixing the files in place as we go
|
// Find end of the file data, fixing the files in place as we go
|
||||||
foreach (BuildFileInfo fi in _files)
|
foreach (BuildFileInfo fi in _files)
|
||||||
{
|
{
|
||||||
primaryLocationTable.Add(fi, (uint)(focus / _buildParams.SectorSize));
|
primaryLocationTable.Add(fi, (uint)(focus / IsoUtilities.SectorSize));
|
||||||
supplementaryLocationTable.Add(fi, (uint)(focus / _buildParams.SectorSize));
|
supplementaryLocationTable.Add(fi, (uint)(focus / IsoUtilities.SectorSize));
|
||||||
FileExtent extent = new FileExtent(fi, focus);
|
FileExtent extent = new FileExtent(fi, focus);
|
||||||
|
|
||||||
// Only remember files of non-zero length (otherwise we'll stomp on a valid file)
|
// Only remember files of non-zero length (otherwise we'll stomp on a valid file)
|
||||||
|
@ -317,7 +299,7 @@ namespace DiscUtils.Iso9660
|
||||||
fixedRegions.Add(extent);
|
fixedRegions.Add(extent);
|
||||||
}
|
}
|
||||||
|
|
||||||
focus += MathUtilities.RoundUp(extent.Length, _buildParams.SectorSize);
|
focus += MathUtilities.RoundUp(extent.Length, IsoUtilities.SectorSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ####################################################################
|
// ####################################################################
|
||||||
|
@ -332,20 +314,20 @@ namespace DiscUtils.Iso9660
|
||||||
long startOfFirstDirData = focus;
|
long startOfFirstDirData = focus;
|
||||||
foreach (BuildDirectoryInfo di in _dirs)
|
foreach (BuildDirectoryInfo di in _dirs)
|
||||||
{
|
{
|
||||||
primaryLocationTable.Add(di, (uint)(focus / _buildParams.SectorSize));
|
primaryLocationTable.Add(di, (uint)(focus / IsoUtilities.SectorSize));
|
||||||
DirectoryExtent extent = new DirectoryExtent(di, primaryLocationTable, Encoding.ASCII, focus);
|
DirectoryExtent extent = new DirectoryExtent(di, primaryLocationTable, Encoding.ASCII, focus);
|
||||||
fixedRegions.Add(extent);
|
fixedRegions.Add(extent);
|
||||||
focus += MathUtilities.RoundUp(extent.Length, _buildParams.SectorSize);
|
focus += MathUtilities.RoundUp(extent.Length, IsoUtilities.SectorSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find end of the second directory table, fixing supplementary directories in place.
|
// Find end of the second directory table, fixing supplementary directories in place.
|
||||||
long startOfSecondDirData = focus;
|
long startOfSecondDirData = focus;
|
||||||
foreach (BuildDirectoryInfo di in _dirs)
|
foreach (BuildDirectoryInfo di in _dirs)
|
||||||
{
|
{
|
||||||
supplementaryLocationTable.Add(di, (uint)(focus / _buildParams.SectorSize));
|
supplementaryLocationTable.Add(di, (uint)(focus / IsoUtilities.SectorSize));
|
||||||
DirectoryExtent extent = new DirectoryExtent(di, supplementaryLocationTable, suppEncoding, focus);
|
DirectoryExtent extent = new DirectoryExtent(di, supplementaryLocationTable, suppEncoding, focus);
|
||||||
fixedRegions.Add(extent);
|
fixedRegions.Add(extent);
|
||||||
focus += MathUtilities.RoundUp(extent.Length, _buildParams.SectorSize);
|
focus += MathUtilities.RoundUp(extent.Length, IsoUtilities.SectorSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ####################################################################
|
// ####################################################################
|
||||||
|
@ -362,24 +344,24 @@ namespace DiscUtils.Iso9660
|
||||||
long startOfFirstPathTable = focus;
|
long startOfFirstPathTable = focus;
|
||||||
PathTable pathTable = new PathTable(false, Encoding.ASCII, _dirs, primaryLocationTable, focus);
|
PathTable pathTable = new PathTable(false, Encoding.ASCII, _dirs, primaryLocationTable, focus);
|
||||||
fixedRegions.Add(pathTable);
|
fixedRegions.Add(pathTable);
|
||||||
focus += MathUtilities.RoundUp(pathTable.Length, _buildParams.SectorSize);
|
focus += MathUtilities.RoundUp(pathTable.Length, IsoUtilities.SectorSize);
|
||||||
long primaryPathTableLength = pathTable.Length;
|
long primaryPathTableLength = pathTable.Length;
|
||||||
|
|
||||||
long startOfSecondPathTable = focus;
|
long startOfSecondPathTable = focus;
|
||||||
pathTable = new PathTable(true, Encoding.ASCII, _dirs, primaryLocationTable, focus);
|
pathTable = new PathTable(true, Encoding.ASCII, _dirs, primaryLocationTable, focus);
|
||||||
fixedRegions.Add(pathTable);
|
fixedRegions.Add(pathTable);
|
||||||
focus += MathUtilities.RoundUp(pathTable.Length, _buildParams.SectorSize);
|
focus += MathUtilities.RoundUp(pathTable.Length, IsoUtilities.SectorSize);
|
||||||
|
|
||||||
long startOfThirdPathTable = focus;
|
long startOfThirdPathTable = focus;
|
||||||
pathTable = new PathTable(false, suppEncoding, _dirs, supplementaryLocationTable, focus);
|
pathTable = new PathTable(false, suppEncoding, _dirs, supplementaryLocationTable, focus);
|
||||||
fixedRegions.Add(pathTable);
|
fixedRegions.Add(pathTable);
|
||||||
focus += MathUtilities.RoundUp(pathTable.Length, _buildParams.SectorSize);
|
focus += MathUtilities.RoundUp(pathTable.Length, IsoUtilities.SectorSize);
|
||||||
long supplementaryPathTableLength = pathTable.Length;
|
long supplementaryPathTableLength = pathTable.Length;
|
||||||
|
|
||||||
long startOfFourthPathTable = focus;
|
long startOfFourthPathTable = focus;
|
||||||
pathTable = new PathTable(true, suppEncoding, _dirs, supplementaryLocationTable, focus);
|
pathTable = new PathTable(true, suppEncoding, _dirs, supplementaryLocationTable, focus);
|
||||||
fixedRegions.Add(pathTable);
|
fixedRegions.Add(pathTable);
|
||||||
focus += MathUtilities.RoundUp(pathTable.Length, _buildParams.SectorSize);
|
focus += MathUtilities.RoundUp(pathTable.Length, IsoUtilities.SectorSize);
|
||||||
|
|
||||||
// Find the end of the disk
|
// Find the end of the disk
|
||||||
totalLength = focus;
|
totalLength = focus;
|
||||||
|
@ -390,45 +372,43 @@ namespace DiscUtils.Iso9660
|
||||||
int regionIdx = 0;
|
int regionIdx = 0;
|
||||||
focus = DiskStart;
|
focus = DiskStart;
|
||||||
PrimaryVolumeDescriptor pvDesc = new PrimaryVolumeDescriptor(
|
PrimaryVolumeDescriptor pvDesc = new PrimaryVolumeDescriptor(
|
||||||
(uint)(totalLength / _buildParams.SectorSize), // VolumeSpaceSize
|
(uint)(totalLength / IsoUtilities.SectorSize), // VolumeSpaceSize
|
||||||
(uint)primaryPathTableLength, // PathTableSize
|
(uint)primaryPathTableLength, // PathTableSize
|
||||||
(uint)(startOfFirstPathTable / _buildParams.SectorSize), // TypeLPathTableLocation
|
(uint)(startOfFirstPathTable / IsoUtilities.SectorSize), // TypeLPathTableLocation
|
||||||
(uint)(startOfSecondPathTable / _buildParams.SectorSize), // TypeMPathTableLocation
|
(uint)(startOfSecondPathTable / IsoUtilities.SectorSize), // TypeMPathTableLocation
|
||||||
(uint)(startOfFirstDirData / _buildParams.SectorSize), // RootDirectory.LocationOfExtent
|
(uint)(startOfFirstDirData / IsoUtilities.SectorSize), // RootDirectory.LocationOfExtent
|
||||||
(uint)_rootDirectory.GetDataSize(Encoding.ASCII), // RootDirectory.DataLength
|
(uint)_rootDirectory.GetDataSize(Encoding.ASCII), // RootDirectory.DataLength
|
||||||
buildTime,
|
buildTime);
|
||||||
_sectorSize);
|
|
||||||
pvDesc.VolumeIdentifier = _buildParams.VolumeIdentifier;
|
pvDesc.VolumeIdentifier = _buildParams.VolumeIdentifier;
|
||||||
PrimaryVolumeDescriptorRegion pvdr = new PrimaryVolumeDescriptorRegion(pvDesc, focus, _sectorSize);
|
PrimaryVolumeDescriptorRegion pvdr = new PrimaryVolumeDescriptorRegion(pvDesc, focus);
|
||||||
fixedRegions.Insert(regionIdx++, pvdr);
|
fixedRegions.Insert(regionIdx++, pvdr);
|
||||||
focus += _buildParams.SectorSize;
|
focus += IsoUtilities.SectorSize;
|
||||||
|
|
||||||
if (_bootEntry != null)
|
if (_bootEntry != null)
|
||||||
{
|
{
|
||||||
BootVolumeDescriptor bvDesc = new BootVolumeDescriptor(
|
BootVolumeDescriptor bvDesc = new BootVolumeDescriptor(
|
||||||
(uint)(bootCatalogPos / _buildParams.SectorSize), _buildParams.SectorSize);
|
(uint)(bootCatalogPos / IsoUtilities.SectorSize));
|
||||||
BootVolumeDescriptorRegion bvdr = new BootVolumeDescriptorRegion(bvDesc, focus, _buildParams.SectorSize);
|
BootVolumeDescriptorRegion bvdr = new BootVolumeDescriptorRegion(bvDesc, focus);
|
||||||
fixedRegions.Insert(regionIdx++, bvdr);
|
fixedRegions.Insert(regionIdx++, bvdr);
|
||||||
focus += _buildParams.SectorSize;
|
focus += IsoUtilities.SectorSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
SupplementaryVolumeDescriptor svDesc = new SupplementaryVolumeDescriptor(
|
SupplementaryVolumeDescriptor svDesc = new SupplementaryVolumeDescriptor(
|
||||||
(uint)(totalLength / _buildParams.SectorSize), // VolumeSpaceSize
|
(uint)(totalLength / IsoUtilities.SectorSize), // VolumeSpaceSize
|
||||||
(uint)supplementaryPathTableLength, // PathTableSize
|
(uint)supplementaryPathTableLength, // PathTableSize
|
||||||
(uint)(startOfThirdPathTable / _buildParams.SectorSize), // TypeLPathTableLocation
|
(uint)(startOfThirdPathTable / IsoUtilities.SectorSize), // TypeLPathTableLocation
|
||||||
(uint)(startOfFourthPathTable / _buildParams.SectorSize), // TypeMPathTableLocation
|
(uint)(startOfFourthPathTable / IsoUtilities.SectorSize), // TypeMPathTableLocation
|
||||||
(uint)(startOfSecondDirData / _buildParams.SectorSize), // RootDirectory.LocationOfExtent
|
(uint)(startOfSecondDirData / IsoUtilities.SectorSize), // RootDirectory.LocationOfExtent
|
||||||
(uint)_rootDirectory.GetDataSize(suppEncoding), // RootDirectory.DataLength
|
(uint)_rootDirectory.GetDataSize(suppEncoding), // RootDirectory.DataLength
|
||||||
buildTime,
|
buildTime,
|
||||||
suppEncoding,
|
suppEncoding);
|
||||||
_sectorSize);
|
|
||||||
svDesc.VolumeIdentifier = _buildParams.VolumeIdentifier;
|
svDesc.VolumeIdentifier = _buildParams.VolumeIdentifier;
|
||||||
SupplementaryVolumeDescriptorRegion svdr = new SupplementaryVolumeDescriptorRegion(svDesc, focus, _sectorSize);
|
SupplementaryVolumeDescriptorRegion svdr = new SupplementaryVolumeDescriptorRegion(svDesc, focus);
|
||||||
fixedRegions.Insert(regionIdx++, svdr);
|
fixedRegions.Insert(regionIdx++, svdr);
|
||||||
focus += _buildParams.SectorSize;
|
focus += IsoUtilities.SectorSize;
|
||||||
|
|
||||||
VolumeDescriptorSetTerminator evDesc = new VolumeDescriptorSetTerminator(_sectorSize);
|
VolumeDescriptorSetTerminator evDesc = new VolumeDescriptorSetTerminator();
|
||||||
VolumeDescriptorSetTerminatorRegion evdr = new VolumeDescriptorSetTerminatorRegion(evDesc, focus, _sectorSize);
|
VolumeDescriptorSetTerminatorRegion evdr = new VolumeDescriptorSetTerminatorRegion(evDesc, focus);
|
||||||
fixedRegions.Insert(regionIdx++, evdr);
|
fixedRegions.Insert(regionIdx++, evdr);
|
||||||
|
|
||||||
return fixedRegions;
|
return fixedRegions;
|
||||||
|
@ -491,7 +471,7 @@ namespace DiscUtils.Iso9660
|
||||||
if (createMissing)
|
if (createMissing)
|
||||||
{
|
{
|
||||||
// This directory doesn't exist, create it...
|
// This directory doesn't exist, create it...
|
||||||
BuildDirectoryInfo di = new BuildDirectoryInfo(path[i], focus, _sectorSize);
|
BuildDirectoryInfo di = new BuildDirectoryInfo(path[i], focus);
|
||||||
focus.Add(di);
|
focus.Add(di);
|
||||||
_dirs.Add(di);
|
_dirs.Add(di);
|
||||||
focus = di;
|
focus = di;
|
||||||
|
|
|
@ -37,9 +37,7 @@ namespace DiscUtils.Iso9660
|
||||||
/// <param name="data">The stream to read the ISO image from.</param>
|
/// <param name="data">The stream to read the ISO image from.</param>
|
||||||
/// <param name="joliet">Whether to read Joliet extensions.</param>
|
/// <param name="joliet">Whether to read Joliet extensions.</param>
|
||||||
public CDReader(Stream data, bool joliet)
|
public CDReader(Stream data, bool joliet)
|
||||||
: base(new VfsCDReader(data, joliet, false, 2048))
|
: base(new VfsCDReader(data, joliet, false)) {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the CDReader class.
|
/// Initializes a new instance of the CDReader class.
|
||||||
|
@ -48,27 +46,7 @@ namespace DiscUtils.Iso9660
|
||||||
/// <param name="joliet">Whether to read Joliet extensions.</param>
|
/// <param name="joliet">Whether to read Joliet extensions.</param>
|
||||||
/// <param name="hideVersions">Hides version numbers (e.g. ";1") from the end of files.</param>
|
/// <param name="hideVersions">Hides version numbers (e.g. ";1") from the end of files.</param>
|
||||||
public CDReader(Stream data, bool joliet, bool hideVersions)
|
public CDReader(Stream data, bool joliet, bool hideVersions)
|
||||||
: base(new VfsCDReader(data, joliet, hideVersions, 2048)) { }
|
: base(new VfsCDReader(data, joliet, hideVersions)) {}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the CDReader class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="data">The stream to read the ISO image from.</param>
|
|
||||||
/// <param name="joliet">Whether to read Joliet extensions.</param>
|
|
||||||
/// <param name="sectorSize">The size of a sector</param>
|
|
||||||
public CDReader(Stream data, bool joliet, int sectorSize)
|
|
||||||
: base(new VfsCDReader(data, joliet, false, sectorSize)) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the CDReader class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="data">The stream to read the ISO image from.</param>
|
|
||||||
/// <param name="joliet">Whether to read Joliet extensions.</param>
|
|
||||||
/// <param name="hideVersions">Hides version numbers (e.g. ";1") from the end of files.</param>
|
|
||||||
public CDReader(Stream data, bool joliet, bool hideVersions, int sectorSize)
|
|
||||||
: base(new VfsCDReader(data, joliet, hideVersions, sectorSize)) {}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets which of the Iso9660 variants is being used.
|
/// Gets which of the Iso9660 variants is being used.
|
||||||
|
@ -196,18 +174,18 @@ namespace DiscUtils.Iso9660
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="data">The stream to inspect.</param>
|
/// <param name="data">The stream to inspect.</param>
|
||||||
/// <returns><c>true</c> if the stream contains an ISO file system, else false.</returns>
|
/// <returns><c>true</c> if the stream contains an ISO file system, else false.</returns>
|
||||||
public static bool Detect(Stream data, int sectorSize)
|
public static bool Detect(Stream data)
|
||||||
{
|
{
|
||||||
byte[] buffer = new byte[sectorSize];
|
byte[] buffer = new byte[IsoUtilities.SectorSize];
|
||||||
|
|
||||||
if (data.Length < 0x8000 + sectorSize)
|
if (data.Length < 0x8000 + IsoUtilities.SectorSize)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
data.Position = 0x8000;
|
data.Position = 0x8000;
|
||||||
int numRead = StreamUtilities.ReadMaximum(data, buffer, 0, sectorSize);
|
int numRead = StreamUtilities.ReadMaximum(data, buffer, 0, IsoUtilities.SectorSize);
|
||||||
if (numRead != sectorSize)
|
if (numRead != IsoUtilities.SectorSize)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,9 +97,8 @@ namespace DiscUtils.Iso9660
|
||||||
uint rootDirExtentLocation,
|
uint rootDirExtentLocation,
|
||||||
uint rootDirDataLength,
|
uint rootDirDataLength,
|
||||||
DateTime buildTime,
|
DateTime buildTime,
|
||||||
Encoding enc,
|
Encoding enc)
|
||||||
int sectorSize)
|
: base(type, version)
|
||||||
: base(type, version, sectorSize)
|
|
||||||
{
|
{
|
||||||
CharacterEncoding = enc;
|
CharacterEncoding = enc;
|
||||||
|
|
||||||
|
@ -108,7 +107,7 @@ namespace DiscUtils.Iso9660
|
||||||
VolumeSpaceSize = volumeSpaceSize;
|
VolumeSpaceSize = volumeSpaceSize;
|
||||||
VolumeSetSize = 1;
|
VolumeSetSize = 1;
|
||||||
VolumeSequenceNumber = 1;
|
VolumeSequenceNumber = 1;
|
||||||
LogicalBlockSize = (ushort)sectorSize;
|
LogicalBlockSize = IsoUtilities.SectorSize;
|
||||||
PathTableSize = pathTableSize;
|
PathTableSize = pathTableSize;
|
||||||
TypeLPathTableLocation = typeLPathTableLocation;
|
TypeLPathTableLocation = typeLPathTableLocation;
|
||||||
////OptionalTypeLPathTableLocation = 0;
|
////OptionalTypeLPathTableLocation = 0;
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
<Import Project="../common-library.props" />
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<Description>DiscUtils Iso9660</Description>
|
|
||||||
<Authors>Kenneth Bell;LordMike</Authors>
|
|
||||||
<PackageTags>DiscUtils;Optical;Iso9660</PackageTags>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\DiscUtils.Core\DiscUtils.Core.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
|
@ -35,17 +35,15 @@ namespace DiscUtils.Iso9660
|
||||||
private long _position;
|
private long _position;
|
||||||
|
|
||||||
private readonly uint _startBlock;
|
private readonly uint _startBlock;
|
||||||
private readonly int _sectorSize;
|
|
||||||
|
|
||||||
public ExtentStream(Stream isoStream, uint startBlock, uint dataLength, byte fileUnitSize,
|
public ExtentStream(Stream isoStream, uint startBlock, uint dataLength, byte fileUnitSize,
|
||||||
byte interleaveGapSize, int sectorSize)
|
byte interleaveGapSize)
|
||||||
{
|
{
|
||||||
_isoStream = isoStream;
|
_isoStream = isoStream;
|
||||||
_startBlock = startBlock;
|
_startBlock = startBlock;
|
||||||
_dataLength = dataLength;
|
_dataLength = dataLength;
|
||||||
_fileUnitSize = fileUnitSize;
|
_fileUnitSize = fileUnitSize;
|
||||||
_interleaveGapSize = interleaveGapSize;
|
_interleaveGapSize = interleaveGapSize;
|
||||||
_sectorSize = sectorSize;
|
|
||||||
|
|
||||||
if (_fileUnitSize != 0 || _interleaveGapSize != 0)
|
if (_fileUnitSize != 0 || _interleaveGapSize != 0)
|
||||||
{
|
{
|
||||||
|
@ -90,7 +88,7 @@ namespace DiscUtils.Iso9660
|
||||||
|
|
||||||
int toRead = (int)Math.Min((uint)count, _dataLength - _position);
|
int toRead = (int)Math.Min((uint)count, _dataLength - _position);
|
||||||
|
|
||||||
_isoStream.Position = _position + _startBlock * (long)_sectorSize;
|
_isoStream.Position = _position + _startBlock * (long)IsoUtilities.SectorSize;
|
||||||
int numRead = _isoStream.Read(buffer, offset, toRead);
|
int numRead = _isoStream.Read(buffer, offset, toRead);
|
||||||
_position += numRead;
|
_position += numRead;
|
||||||
return numRead;
|
return numRead;
|
||||||
|
|
|
@ -111,7 +111,7 @@ namespace DiscUtils.Iso9660
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
ExtentStream es = new ExtentStream(_context.DataStream, _dirEntry.Record.LocationOfExtent,
|
ExtentStream es = new ExtentStream(_context.DataStream, _dirEntry.Record.LocationOfExtent,
|
||||||
_dirEntry.Record.DataLength, _dirEntry.Record.FileUnitSize, _dirEntry.Record.InterleaveGapSize, _context.SectorSize);
|
_dirEntry.Record.DataLength, _dirEntry.Record.FileUnitSize, _dirEntry.Record.InterleaveGapSize);
|
||||||
return new StreamBuffer(es, Ownership.Dispose);
|
return new StreamBuffer(es, Ownership.Dispose);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,19 +28,12 @@ namespace DiscUtils.Iso9660
|
||||||
{
|
{
|
||||||
internal class IsoContext : VfsContext
|
internal class IsoContext : VfsContext
|
||||||
{
|
{
|
||||||
public IsoContext(int sectorSize)
|
|
||||||
{
|
|
||||||
SectorSize = sectorSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Stream DataStream { get; set; }
|
public Stream DataStream { get; set; }
|
||||||
|
|
||||||
public string RockRidgeIdentifier { get; set; }
|
public string RockRidgeIdentifier { get; set; }
|
||||||
|
|
||||||
public bool SuspDetected { get; set; }
|
public bool SuspDetected { get; set; }
|
||||||
|
|
||||||
public int SectorSize { get; set; }
|
|
||||||
|
|
||||||
public List<SuspExtension> SuspExtensions { get; set; }
|
public List<SuspExtension> SuspExtensions { get; set; }
|
||||||
|
|
||||||
public int SuspSkipBytes { get; set; }
|
public int SuspSkipBytes { get; set; }
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace DiscUtils.Iso9660
|
||||||
{
|
{
|
||||||
internal static class IsoUtilities
|
internal static class IsoUtilities
|
||||||
{
|
{
|
||||||
//public const int SectorSize = 2048;
|
public const int SectorSize = 2048;
|
||||||
|
|
||||||
public static uint ToUInt32FromBoth(byte[] data, int offset)
|
public static uint ToUInt32FromBoth(byte[] data, int offset)
|
||||||
{
|
{
|
||||||
|
|
|
@ -38,11 +38,10 @@ namespace DiscUtils.Iso9660
|
||||||
uint typeMPathTableLocation,
|
uint typeMPathTableLocation,
|
||||||
uint rootDirExtentLocation,
|
uint rootDirExtentLocation,
|
||||||
uint rootDirDataLength,
|
uint rootDirDataLength,
|
||||||
DateTime buildTime,
|
DateTime buildTime)
|
||||||
int sectorSize)
|
|
||||||
: base(
|
: base(
|
||||||
VolumeDescriptorType.Primary, 1, volumeSpaceSize, pathTableSize, typeLPathTableLocation,
|
VolumeDescriptorType.Primary, 1, volumeSpaceSize, pathTableSize, typeLPathTableLocation,
|
||||||
typeMPathTableLocation, rootDirExtentLocation, rootDirDataLength, buildTime, Encoding.ASCII, sectorSize) {}
|
typeMPathTableLocation, rootDirExtentLocation, rootDirDataLength, buildTime, Encoding.ASCII) {}
|
||||||
|
|
||||||
internal override void WriteTo(byte[] buffer, int offset)
|
internal override void WriteTo(byte[] buffer, int offset)
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,15 +26,15 @@ namespace DiscUtils.Iso9660
|
||||||
{
|
{
|
||||||
private readonly PrimaryVolumeDescriptor _descriptor;
|
private readonly PrimaryVolumeDescriptor _descriptor;
|
||||||
|
|
||||||
public PrimaryVolumeDescriptorRegion(PrimaryVolumeDescriptor descriptor, long start, int sectorSize)
|
public PrimaryVolumeDescriptorRegion(PrimaryVolumeDescriptor descriptor, long start)
|
||||||
: base(start, sectorSize)
|
: base(start)
|
||||||
{
|
{
|
||||||
_descriptor = descriptor;
|
_descriptor = descriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override byte[] GetBlockData()
|
protected override byte[] GetBlockData()
|
||||||
{
|
{
|
||||||
byte[] buffer = new byte[Length];
|
byte[] buffer = new byte[IsoUtilities.SectorSize];
|
||||||
_descriptor.WriteTo(buffer, 0);
|
_descriptor.WriteTo(buffer, 0);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,8 +37,8 @@ namespace DiscUtils.Iso9660
|
||||||
public ReaderDirectory(IsoContext context, ReaderDirEntry dirEntry)
|
public ReaderDirectory(IsoContext context, ReaderDirEntry dirEntry)
|
||||||
: base(context, dirEntry)
|
: base(context, dirEntry)
|
||||||
{
|
{
|
||||||
byte[] buffer = new byte[context.SectorSize];
|
byte[] buffer = new byte[IsoUtilities.SectorSize];
|
||||||
Stream extent = new ExtentStream(_context.DataStream, dirEntry.Record.LocationOfExtent, uint.MaxValue, 0, 0, context.SectorSize);
|
Stream extent = new ExtentStream(_context.DataStream, dirEntry.Record.LocationOfExtent, uint.MaxValue, 0, 0);
|
||||||
|
|
||||||
_records = new List<ReaderDirEntry>();
|
_records = new List<ReaderDirEntry>();
|
||||||
|
|
||||||
|
@ -48,8 +48,6 @@ namespace DiscUtils.Iso9660
|
||||||
{
|
{
|
||||||
int bytesRead = (int)Math.Min(buffer.Length, totalLength - totalRead);
|
int bytesRead = (int)Math.Min(buffer.Length, totalLength - totalRead);
|
||||||
|
|
||||||
extent.Seek(24, SeekOrigin.Current);
|
|
||||||
|
|
||||||
StreamUtilities.ReadExact(extent, buffer, 0, bytesRead);
|
StreamUtilities.ReadExact(extent, buffer, 0, bytesRead);
|
||||||
totalRead += (uint)bytesRead;
|
totalRead += (uint)bytesRead;
|
||||||
|
|
||||||
|
|
|
@ -39,11 +39,10 @@ namespace DiscUtils.Iso9660
|
||||||
uint rootDirExtentLocation,
|
uint rootDirExtentLocation,
|
||||||
uint rootDirDataLength,
|
uint rootDirDataLength,
|
||||||
DateTime buildTime,
|
DateTime buildTime,
|
||||||
Encoding enc,
|
Encoding enc)
|
||||||
int sectorSize)
|
|
||||||
: base(
|
: base(
|
||||||
VolumeDescriptorType.Supplementary, 1, volumeSpaceSize, pathTableSize, typeLPathTableLocation,
|
VolumeDescriptorType.Supplementary, 1, volumeSpaceSize, pathTableSize, typeLPathTableLocation,
|
||||||
typeMPathTableLocation, rootDirExtentLocation, rootDirDataLength, buildTime, enc, sectorSize) {}
|
typeMPathTableLocation, rootDirExtentLocation, rootDirDataLength, buildTime, enc) {}
|
||||||
|
|
||||||
internal override void WriteTo(byte[] buffer, int offset)
|
internal override void WriteTo(byte[] buffer, int offset)
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,15 +26,15 @@ namespace DiscUtils.Iso9660
|
||||||
{
|
{
|
||||||
private readonly SupplementaryVolumeDescriptor _descriptor;
|
private readonly SupplementaryVolumeDescriptor _descriptor;
|
||||||
|
|
||||||
public SupplementaryVolumeDescriptorRegion(SupplementaryVolumeDescriptor descriptor, long start, int sectorSize)
|
public SupplementaryVolumeDescriptorRegion(SupplementaryVolumeDescriptor descriptor, long start)
|
||||||
: base(start, sectorSize)
|
: base(start)
|
||||||
{
|
{
|
||||||
_descriptor = descriptor;
|
_descriptor = descriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override byte[] GetBlockData()
|
protected override byte[] GetBlockData()
|
||||||
{
|
{
|
||||||
byte[] buffer = new byte[Length];
|
byte[] buffer = new byte[IsoUtilities.SectorSize];
|
||||||
_descriptor.WriteTo(buffer, 0);
|
_descriptor.WriteTo(buffer, 0);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,6 @@ namespace DiscUtils.Iso9660
|
||||||
|
|
||||||
private readonly Stream _data;
|
private readonly Stream _data;
|
||||||
private readonly bool _hideVersions;
|
private readonly bool _hideVersions;
|
||||||
protected readonly int _sectorSize;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the VfsCDReader class.
|
/// Initializes a new instance of the VfsCDReader class.
|
||||||
|
@ -48,9 +47,8 @@ namespace DiscUtils.Iso9660
|
||||||
/// <param name="data">The stream to read the ISO image from.</param>
|
/// <param name="data">The stream to read the ISO image from.</param>
|
||||||
/// <param name="joliet">Whether to read Joliet extensions.</param>
|
/// <param name="joliet">Whether to read Joliet extensions.</param>
|
||||||
/// <param name="hideVersions">Hides version numbers (e.g. ";1") from the end of files.</param>
|
/// <param name="hideVersions">Hides version numbers (e.g. ";1") from the end of files.</param>
|
||||||
public VfsCDReader(Stream data, bool joliet, bool hideVersions, int sectorSize)
|
public VfsCDReader(Stream data, bool joliet, bool hideVersions)
|
||||||
: this(data, joliet ? DefaultVariantsWithJoliet : DefaultVariantsNoJoliet, hideVersions, sectorSize) {
|
: this(data, joliet ? DefaultVariantsWithJoliet : DefaultVariantsNoJoliet, hideVersions) {}
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the VfsCDReader class.
|
/// Initializes a new instance of the VfsCDReader class.
|
||||||
|
@ -70,16 +68,15 @@ namespace DiscUtils.Iso9660
|
||||||
/// <para>The Iso9660 variant should normally be specified as the final entry in the list. Placing it earlier
|
/// <para>The Iso9660 variant should normally be specified as the final entry in the list. Placing it earlier
|
||||||
/// in the list will effectively mask later items and not including it may prevent some ISOs from being read.</para>
|
/// in the list will effectively mask later items and not including it may prevent some ISOs from being read.</para>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public VfsCDReader(Stream data, Iso9660Variant[] variantPriorities, bool hideVersions, int sectorSize)
|
public VfsCDReader(Stream data, Iso9660Variant[] variantPriorities, bool hideVersions)
|
||||||
: base(new DiscFileSystemOptions())
|
: base(new DiscFileSystemOptions())
|
||||||
{
|
{
|
||||||
_data = data;
|
_data = data;
|
||||||
_sectorSize = sectorSize;
|
|
||||||
_hideVersions = hideVersions;
|
_hideVersions = hideVersions;
|
||||||
|
|
||||||
long vdpos = _sectorSize * 16; // Skip lead-in
|
long vdpos = 0x8000; // Skip lead-in
|
||||||
|
|
||||||
byte[] buffer = new byte[_sectorSize];
|
byte[] buffer = new byte[IsoUtilities.SectorSize];
|
||||||
|
|
||||||
long pvdPos = 0;
|
long pvdPos = 0;
|
||||||
long svdPos = 0;
|
long svdPos = 0;
|
||||||
|
@ -88,15 +85,13 @@ namespace DiscUtils.Iso9660
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
data.Position = vdpos;
|
data.Position = vdpos;
|
||||||
int numRead = data.Read(buffer, 0, _sectorSize);
|
int numRead = data.Read(buffer, 0, IsoUtilities.SectorSize);
|
||||||
if (numRead != _sectorSize)
|
if (numRead != IsoUtilities.SectorSize)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var offset = 24;
|
bvd = new BaseVolumeDescriptor(buffer, 0);
|
||||||
|
|
||||||
bvd = new BaseVolumeDescriptor(buffer, offset);
|
|
||||||
|
|
||||||
if (bvd.StandardIdentifier != BaseVolumeDescriptor.Iso9660StandardIdentifier)
|
if (bvd.StandardIdentifier != BaseVolumeDescriptor.Iso9660StandardIdentifier)
|
||||||
{
|
{
|
||||||
|
@ -106,7 +101,7 @@ namespace DiscUtils.Iso9660
|
||||||
switch (bvd.VolumeDescriptorType)
|
switch (bvd.VolumeDescriptorType)
|
||||||
{
|
{
|
||||||
case VolumeDescriptorType.Boot:
|
case VolumeDescriptorType.Boot:
|
||||||
_bootVolDesc = new BootVolumeDescriptor(buffer, offset);
|
_bootVolDesc = new BootVolumeDescriptor(buffer, 0);
|
||||||
if (_bootVolDesc.SystemId != BootVolumeDescriptor.ElToritoSystemIdentifier)
|
if (_bootVolDesc.SystemId != BootVolumeDescriptor.ElToritoSystemIdentifier)
|
||||||
{
|
{
|
||||||
_bootVolDesc = null;
|
_bootVolDesc = null;
|
||||||
|
@ -128,7 +123,7 @@ namespace DiscUtils.Iso9660
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
vdpos += _sectorSize;
|
vdpos += IsoUtilities.SectorSize;
|
||||||
} while (bvd.VolumeDescriptorType != VolumeDescriptorType.SetTerminator);
|
} while (bvd.VolumeDescriptorType != VolumeDescriptorType.SetTerminator);
|
||||||
|
|
||||||
ActiveVariant = Iso9660Variant.None;
|
ActiveVariant = Iso9660Variant.None;
|
||||||
|
@ -140,10 +135,10 @@ namespace DiscUtils.Iso9660
|
||||||
if (svdPos != 0)
|
if (svdPos != 0)
|
||||||
{
|
{
|
||||||
data.Position = svdPos;
|
data.Position = svdPos;
|
||||||
data.Read(buffer, 0, _sectorSize);
|
data.Read(buffer, 0, IsoUtilities.SectorSize);
|
||||||
SupplementaryVolumeDescriptor volDesc = new SupplementaryVolumeDescriptor(buffer, 0);
|
SupplementaryVolumeDescriptor volDesc = new SupplementaryVolumeDescriptor(buffer, 0);
|
||||||
|
|
||||||
Context = new IsoContext(_sectorSize) { VolumeDescriptor = volDesc, DataStream = _data };
|
Context = new IsoContext { VolumeDescriptor = volDesc, DataStream = _data };
|
||||||
RootDirectory = new ReaderDirectory(Context,
|
RootDirectory = new ReaderDirectory(Context,
|
||||||
new ReaderDirEntry(Context, volDesc.RootDirectory));
|
new ReaderDirEntry(Context, volDesc.RootDirectory));
|
||||||
ActiveVariant = Iso9660Variant.Iso9660;
|
ActiveVariant = Iso9660Variant.Iso9660;
|
||||||
|
@ -155,13 +150,11 @@ namespace DiscUtils.Iso9660
|
||||||
case Iso9660Variant.Iso9660:
|
case Iso9660Variant.Iso9660:
|
||||||
if (pvdPos != 0)
|
if (pvdPos != 0)
|
||||||
{
|
{
|
||||||
data.Position = pvdPos + 24;
|
data.Position = pvdPos;
|
||||||
data.Read(buffer, 0, _sectorSize);
|
data.Read(buffer, 0, IsoUtilities.SectorSize);
|
||||||
PrimaryVolumeDescriptor volDesc = new PrimaryVolumeDescriptor(buffer, 0);
|
PrimaryVolumeDescriptor volDesc = new PrimaryVolumeDescriptor(buffer, 0);
|
||||||
|
|
||||||
volDesc.LogicalBlockSize = 2352;
|
IsoContext context = new IsoContext { VolumeDescriptor = volDesc, DataStream = _data };
|
||||||
|
|
||||||
IsoContext context = new IsoContext(_sectorSize) { VolumeDescriptor = volDesc, DataStream = _data };
|
|
||||||
DirectoryRecord rootSelfRecord = ReadRootSelfRecord(context);
|
DirectoryRecord rootSelfRecord = ReadRootSelfRecord(context);
|
||||||
|
|
||||||
InitializeSusp(context, rootSelfRecord);
|
InitializeSusp(context, rootSelfRecord);
|
||||||
|
@ -215,7 +208,7 @@ namespace DiscUtils.Iso9660
|
||||||
BootInitialEntry initialEntry = GetBootInitialEntry();
|
BootInitialEntry initialEntry = GetBootInitialEntry();
|
||||||
if (initialEntry != null)
|
if (initialEntry != null)
|
||||||
{
|
{
|
||||||
return initialEntry.ImageStart * _sectorSize;
|
return initialEntry.ImageStart * IsoUtilities.SectorSize;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -273,7 +266,7 @@ namespace DiscUtils.Iso9660
|
||||||
|
|
||||||
public long ClusterSize
|
public long ClusterSize
|
||||||
{
|
{
|
||||||
get { return _sectorSize; }
|
get { return IsoUtilities.SectorSize; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public long TotalClusters
|
public long TotalClusters
|
||||||
|
@ -331,7 +324,7 @@ namespace DiscUtils.Iso9660
|
||||||
return new[]
|
return new[]
|
||||||
{
|
{
|
||||||
new Range<long, long>(entry.Record.LocationOfExtent,
|
new Range<long, long>(entry.Record.LocationOfExtent,
|
||||||
MathUtilities.Ceil(entry.Record.DataLength, _sectorSize))
|
MathUtilities.Ceil(entry.Record.DataLength, IsoUtilities.SectorSize))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -349,7 +342,7 @@ namespace DiscUtils.Iso9660
|
||||||
}
|
}
|
||||||
|
|
||||||
return new[]
|
return new[]
|
||||||
{ new StreamExtent(entry.Record.LocationOfExtent * _sectorSize, entry.Record.DataLength) };
|
{ new StreamExtent(entry.Record.LocationOfExtent * IsoUtilities.SectorSize, entry.Record.DataLength) };
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClusterMap BuildClusterMap()
|
public ClusterMap BuildClusterMap()
|
||||||
|
@ -386,7 +379,7 @@ namespace DiscUtils.Iso9660
|
||||||
throw new NotSupportedException("Non-contiguous extents not supported");
|
throw new NotSupportedException("Non-contiguous extents not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
long clusters = MathUtilities.Ceil(entry.Record.DataLength, _sectorSize);
|
long clusters = MathUtilities.Ceil(entry.Record.DataLength, IsoUtilities.SectorSize);
|
||||||
for (long i = 0; i < clusters; ++i)
|
for (long i = 0; i < clusters; ++i)
|
||||||
{
|
{
|
||||||
clusterToRole[i + entry.Record.LocationOfExtent] = ClusterRoles.DataFile;
|
clusterToRole[i + entry.Record.LocationOfExtent] = ClusterRoles.DataFile;
|
||||||
|
@ -408,7 +401,7 @@ namespace DiscUtils.Iso9660
|
||||||
BootInitialEntry initialEntry = GetBootInitialEntry();
|
BootInitialEntry initialEntry = GetBootInitialEntry();
|
||||||
if (initialEntry != null)
|
if (initialEntry != null)
|
||||||
{
|
{
|
||||||
return new SubStream(_data, initialEntry.ImageStart * _sectorSize,
|
return new SubStream(_data, initialEntry.ImageStart * IsoUtilities.SectorSize,
|
||||||
initialEntry.SectorCount * Sizes.Sector);
|
initialEntry.SectorCount * Sizes.Sector);
|
||||||
}
|
}
|
||||||
throw new InvalidOperationException("No valid boot image");
|
throw new InvalidOperationException("No valid boot image");
|
||||||
|
@ -491,7 +484,7 @@ namespace DiscUtils.Iso9660
|
||||||
private static DirectoryRecord ReadRootSelfRecord(IsoContext context)
|
private static DirectoryRecord ReadRootSelfRecord(IsoContext context)
|
||||||
{
|
{
|
||||||
context.DataStream.Position = context.VolumeDescriptor.RootDirectory.LocationOfExtent *
|
context.DataStream.Position = context.VolumeDescriptor.RootDirectory.LocationOfExtent *
|
||||||
context.VolumeDescriptor.LogicalBlockSize + 24;
|
context.VolumeDescriptor.LogicalBlockSize;
|
||||||
byte[] firstSector = StreamUtilities.ReadExact(context.DataStream, context.VolumeDescriptor.LogicalBlockSize);
|
byte[] firstSector = StreamUtilities.ReadExact(context.DataStream, context.VolumeDescriptor.LogicalBlockSize);
|
||||||
|
|
||||||
DirectoryRecord rootSelfRecord;
|
DirectoryRecord rootSelfRecord;
|
||||||
|
@ -520,8 +513,8 @@ namespace DiscUtils.Iso9660
|
||||||
{
|
{
|
||||||
if (_bootCatalog == null && _bootVolDesc != null)
|
if (_bootCatalog == null && _bootVolDesc != null)
|
||||||
{
|
{
|
||||||
_data.Position = _bootVolDesc.CatalogSector * _sectorSize;
|
_data.Position = _bootVolDesc.CatalogSector * IsoUtilities.SectorSize;
|
||||||
_bootCatalog = StreamUtilities.ReadExact(_data, _sectorSize);
|
_bootCatalog = StreamUtilities.ReadExact(_data, IsoUtilities.SectorSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
return _bootCatalog;
|
return _bootCatalog;
|
||||||
|
|
|
@ -29,8 +29,8 @@ namespace DiscUtils.Iso9660
|
||||||
{
|
{
|
||||||
private byte[] _readCache;
|
private byte[] _readCache;
|
||||||
|
|
||||||
public VolumeDescriptorDiskRegion(long start, int sectorSize)
|
public VolumeDescriptorDiskRegion(long start)
|
||||||
: base(start, sectorSize) {}
|
: base(start, IsoUtilities.SectorSize) {}
|
||||||
|
|
||||||
public override void Dispose() {}
|
public override void Dispose() {}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace DiscUtils.Iso9660
|
||||||
{
|
{
|
||||||
internal class VolumeDescriptorSetTerminator : BaseVolumeDescriptor
|
internal class VolumeDescriptorSetTerminator : BaseVolumeDescriptor
|
||||||
{
|
{
|
||||||
public VolumeDescriptorSetTerminator(int sectorSize)
|
public VolumeDescriptorSetTerminator()
|
||||||
: base(VolumeDescriptorType.SetTerminator, 1, sectorSize) {}
|
: base(VolumeDescriptorType.SetTerminator, 1) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -26,15 +26,15 @@ namespace DiscUtils.Iso9660
|
||||||
{
|
{
|
||||||
private readonly VolumeDescriptorSetTerminator _descriptor;
|
private readonly VolumeDescriptorSetTerminator _descriptor;
|
||||||
|
|
||||||
public VolumeDescriptorSetTerminatorRegion(VolumeDescriptorSetTerminator descriptor, long start, int sectorSize)
|
public VolumeDescriptorSetTerminatorRegion(VolumeDescriptorSetTerminator descriptor, long start)
|
||||||
: base(start, sectorSize)
|
: base(start)
|
||||||
{
|
{
|
||||||
_descriptor = descriptor;
|
_descriptor = descriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override byte[] GetBlockData()
|
protected override byte[] GetBlockData()
|
||||||
{
|
{
|
||||||
byte[] buffer = new byte[Length];
|
byte[] buffer = new byte[IsoUtilities.SectorSize];
|
||||||
_descriptor.WriteTo(buffer, 0);
|
_descriptor.WriteTo(buffer, 0);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
//
|
||||||
|
// Copyright (c) 2008-2011, Kenneth Bell
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace DiscUtils.Iso9660Ps1
|
||||||
|
{
|
||||||
|
internal class BaseVolumeDescriptor
|
||||||
|
{
|
||||||
|
public const string Iso9660StandardIdentifier = "CD001";
|
||||||
|
|
||||||
|
public readonly string StandardIdentifier;
|
||||||
|
public readonly VolumeDescriptorType VolumeDescriptorType;
|
||||||
|
public readonly byte VolumeDescriptorVersion;
|
||||||
|
private int SectorSize;
|
||||||
|
|
||||||
|
public BaseVolumeDescriptor(VolumeDescriptorType type, byte version, int sectorSize)
|
||||||
|
{
|
||||||
|
VolumeDescriptorType = type;
|
||||||
|
StandardIdentifier = "CD001";
|
||||||
|
VolumeDescriptorVersion = version;
|
||||||
|
SectorSize = sectorSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BaseVolumeDescriptor(byte[] src, int offset)
|
||||||
|
{
|
||||||
|
VolumeDescriptorType = (VolumeDescriptorType)src[offset + 0];
|
||||||
|
StandardIdentifier = Encoding.ASCII.GetString(src, offset + 1, 5);
|
||||||
|
VolumeDescriptorVersion = src[offset + 6];
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
//
|
||||||
|
// Copyright (c) 2008-2011, Kenneth Bell
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
namespace DiscUtils.Iso9660Ps1
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Enumeration of boot device emulation modes.
|
||||||
|
/// </summary>
|
||||||
|
public enum BootDeviceEmulation : byte
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// No emulation, the boot image is just loaded and executed.
|
||||||
|
/// </summary>
|
||||||
|
NoEmulation = 0x0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Emulates 1.2MB diskette image as drive A.
|
||||||
|
/// </summary>
|
||||||
|
Diskette1200KiB = 0x1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Emulates 1.44MB diskette image as drive A.
|
||||||
|
/// </summary>
|
||||||
|
Diskette1440KiB = 0x2,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Emulates 2.88MB diskette image as drive A.
|
||||||
|
/// </summary>
|
||||||
|
Diskette2880KiB = 0x3,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Emulates hard disk image as drive C.
|
||||||
|
/// </summary>
|
||||||
|
HardDisk = 0x4
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
//
|
||||||
|
// Copyright (c) 2008-2011, Kenneth Bell
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using DiscUtils.Streams;
|
||||||
|
|
||||||
|
namespace DiscUtils.Iso9660Ps1
|
||||||
|
{
|
||||||
|
internal class BootInitialEntry
|
||||||
|
{
|
||||||
|
public byte BootIndicator;
|
||||||
|
public BootDeviceEmulation BootMediaType;
|
||||||
|
public uint ImageStart;
|
||||||
|
public ushort LoadSegment;
|
||||||
|
public ushort SectorCount;
|
||||||
|
public byte SystemType;
|
||||||
|
|
||||||
|
public BootInitialEntry() {}
|
||||||
|
|
||||||
|
public BootInitialEntry(byte[] buffer, int offset)
|
||||||
|
{
|
||||||
|
BootIndicator = buffer[offset + 0x00];
|
||||||
|
BootMediaType = (BootDeviceEmulation)buffer[offset + 0x01];
|
||||||
|
LoadSegment = EndianUtilities.ToUInt16LittleEndian(buffer, offset + 0x02);
|
||||||
|
SystemType = buffer[offset + 0x04];
|
||||||
|
SectorCount = EndianUtilities.ToUInt16LittleEndian(buffer, offset + 0x06);
|
||||||
|
ImageStart = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 0x08);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void WriteTo(byte[] buffer, int offset)
|
||||||
|
{
|
||||||
|
Array.Clear(buffer, offset, 0x20);
|
||||||
|
buffer[offset + 0x00] = BootIndicator;
|
||||||
|
buffer[offset + 0x01] = (byte)BootMediaType;
|
||||||
|
EndianUtilities.WriteBytesLittleEndian(LoadSegment, buffer, offset + 0x02);
|
||||||
|
buffer[offset + 0x04] = SystemType;
|
||||||
|
EndianUtilities.WriteBytesLittleEndian(SectorCount, buffer, offset + 0x06);
|
||||||
|
EndianUtilities.WriteBytesLittleEndian(ImageStart, buffer, offset + 0x08);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
//
|
||||||
|
// Copyright (c) 2008-2011, Kenneth Bell
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using DiscUtils.Streams;
|
||||||
|
|
||||||
|
namespace DiscUtils.Iso9660Ps1
|
||||||
|
{
|
||||||
|
internal class BootValidationEntry
|
||||||
|
{
|
||||||
|
private readonly byte[] _data;
|
||||||
|
public byte HeaderId;
|
||||||
|
public string ManfId;
|
||||||
|
public byte PlatformId;
|
||||||
|
|
||||||
|
public BootValidationEntry()
|
||||||
|
{
|
||||||
|
HeaderId = 1;
|
||||||
|
PlatformId = 0;
|
||||||
|
ManfId = ".Net DiscUtils";
|
||||||
|
}
|
||||||
|
|
||||||
|
public BootValidationEntry(byte[] src, int offset)
|
||||||
|
{
|
||||||
|
_data = new byte[32];
|
||||||
|
Array.Copy(src, offset, _data, 0, 32);
|
||||||
|
|
||||||
|
HeaderId = _data[0];
|
||||||
|
PlatformId = _data[1];
|
||||||
|
ManfId = EndianUtilities.BytesToString(_data, 4, 24).TrimEnd('\0').TrimEnd(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ChecksumValid
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
ushort total = 0;
|
||||||
|
for (int i = 0; i < 16; ++i)
|
||||||
|
{
|
||||||
|
total += EndianUtilities.ToUInt16LittleEndian(_data, i * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return total == 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void WriteTo(byte[] buffer, int offset)
|
||||||
|
{
|
||||||
|
Array.Clear(buffer, offset, 0x20);
|
||||||
|
buffer[offset + 0x00] = HeaderId;
|
||||||
|
buffer[offset + 0x01] = PlatformId;
|
||||||
|
EndianUtilities.StringToBytes(ManfId, buffer, offset + 0x04, 24);
|
||||||
|
buffer[offset + 0x1E] = 0x55;
|
||||||
|
buffer[offset + 0x1F] = 0xAA;
|
||||||
|
EndianUtilities.WriteBytesLittleEndian(CalcChecksum(buffer, offset), buffer, offset + 0x1C);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ushort CalcChecksum(byte[] buffer, int offset)
|
||||||
|
{
|
||||||
|
ushort total = 0;
|
||||||
|
for (int i = 0; i < 16; ++i)
|
||||||
|
{
|
||||||
|
total += EndianUtilities.ToUInt16LittleEndian(buffer, offset + i * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (ushort)(0 - total);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
//
|
||||||
|
// Copyright (c) 2008-2011, Kenneth Bell
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
using DiscUtils.Streams;
|
||||||
|
|
||||||
|
namespace DiscUtils.Iso9660Ps1
|
||||||
|
{
|
||||||
|
internal class BootVolumeDescriptor : BaseVolumeDescriptor
|
||||||
|
{
|
||||||
|
public const string ElToritoSystemIdentifier = "EL TORITO SPECIFICATION";
|
||||||
|
|
||||||
|
public BootVolumeDescriptor(uint catalogSector, int sectorSize)
|
||||||
|
: base(VolumeDescriptorType.Boot, 1, sectorSize)
|
||||||
|
{
|
||||||
|
CatalogSector = catalogSector;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BootVolumeDescriptor(byte[] src, int offset)
|
||||||
|
: base(src, offset)
|
||||||
|
{
|
||||||
|
SystemId = EndianUtilities.BytesToString(src, offset + 0x7, 0x20).TrimEnd('\0');
|
||||||
|
CatalogSector = EndianUtilities.ToUInt32LittleEndian(src, offset + 0x47);
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint CatalogSector { get; }
|
||||||
|
|
||||||
|
public string SystemId { get; }
|
||||||
|
|
||||||
|
internal override void WriteTo(byte[] buffer, int offset)
|
||||||
|
{
|
||||||
|
base.WriteTo(buffer, offset);
|
||||||
|
|
||||||
|
EndianUtilities.StringToBytes(ElToritoSystemIdentifier, buffer, offset + 7, 0x20);
|
||||||
|
EndianUtilities.WriteBytesLittleEndian(CatalogSector, buffer, offset + 0x47);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue