mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Decode ISO9660 path tables.
This commit is contained in:
@@ -75,6 +75,7 @@
|
||||
<Compile Include="ISO9660\Date.cs" />
|
||||
<Compile Include="ISO9660\Dir.cs" />
|
||||
<Compile Include="ISO9660\File.cs" />
|
||||
<Compile Include="ISO9660\PathTable.cs" />
|
||||
<Compile Include="ISO9660\Super.cs" />
|
||||
<Compile Include="ISO9660\Xattr.cs" />
|
||||
<Compile Include="PCFX.cs" />
|
||||
|
||||
@@ -49,6 +49,7 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
bool joliet;
|
||||
bool mounted;
|
||||
Namespace @namespace;
|
||||
PathTableEntryInternal[] pathTable;
|
||||
Dictionary<string, DecodedDirectoryEntry> rootDirectoryCache;
|
||||
FileSystemInfo statfs;
|
||||
|
||||
|
||||
39
DiscImageChef.Filesystems/ISO9660/PathTable.cs
Normal file
39
DiscImageChef.Filesystems/ISO9660/PathTable.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using System.Collections.Generic;
|
||||
using DiscImageChef.Helpers;
|
||||
|
||||
namespace DiscImageChef.Filesystems.ISO9660
|
||||
{
|
||||
public partial class ISO9660
|
||||
{
|
||||
PathTableEntryInternal[] DecodePathTable(byte[] data)
|
||||
{
|
||||
if(data is null) return null;
|
||||
|
||||
List<PathTableEntryInternal> table = new List<PathTableEntryInternal>();
|
||||
|
||||
int off = 0;
|
||||
while(off < data.Length)
|
||||
{
|
||||
PathTableEntry entry =
|
||||
Marshal.ByteArrayToStructureBigEndian<PathTableEntry>(data, off, Marshal.SizeOf<PathTableEntry>());
|
||||
|
||||
if(entry.name_len == 0) break;
|
||||
|
||||
off += Marshal.SizeOf<PathTableEntry>();
|
||||
|
||||
string name = Encoding.GetString(data, off, entry.name_len);
|
||||
|
||||
table.Add(new PathTableEntryInternal
|
||||
{
|
||||
Extent = entry.start_lbn, Name = name, Parent = entry.parent_dirno
|
||||
});
|
||||
|
||||
off += entry.name_len;
|
||||
|
||||
if(entry.name_len % 2 != 0) off++;
|
||||
}
|
||||
|
||||
return table.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -123,5 +123,14 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
public Point fdLocation;
|
||||
public uint fdType;
|
||||
}
|
||||
|
||||
class PathTableEntryInternal
|
||||
{
|
||||
public uint Extent;
|
||||
public string Name;
|
||||
public ushort Parent;
|
||||
|
||||
public override string ToString() => Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -160,15 +160,44 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
|
||||
if(jolietvd != null) decodedJolietVd = DecodeJolietDescriptor(jolietvd.Value);
|
||||
|
||||
if(this.@namespace != Namespace.Romeo) Encoding = Encoding.ASCII;
|
||||
|
||||
string fsFormat;
|
||||
if(highSierra) fsFormat = "High Sierra Format";
|
||||
byte[] pathTableData;
|
||||
uint pathTableSizeInSectors = 0;
|
||||
if(highSierra)
|
||||
{
|
||||
pathTableSizeInSectors = hsvd.Value.path_table_size / 2048;
|
||||
if(hsvd.Value.path_table_size % 2048 > 0) pathTableSizeInSectors++;
|
||||
|
||||
pathTableData =
|
||||
imagePlugin.ReadSectors(Swapping.Swap(hsvd.Value.mandatory_path_table_msb), pathTableSizeInSectors);
|
||||
|
||||
fsFormat = "High Sierra Format";
|
||||
}
|
||||
else if(cdi)
|
||||
{
|
||||
pathTableSizeInSectors = fsvd.Value.path_table_size / 2048;
|
||||
if(fsvd.Value.path_table_size % 2048 > 0) pathTableSizeInSectors++;
|
||||
|
||||
pathTableData = imagePlugin.ReadSectors(fsvd.Value.path_table_addr, pathTableSizeInSectors);
|
||||
|
||||
fsFormat = "CD-i";
|
||||
// TODO: Implement CD-i
|
||||
return Errno.NotImplemented;
|
||||
}
|
||||
else fsFormat = "ISO9660";
|
||||
else
|
||||
{
|
||||
pathTableSizeInSectors = pvd.Value.path_table_size / 2048;
|
||||
if(pvd.Value.path_table_size % 2048 > 0) pathTableSizeInSectors++;
|
||||
|
||||
pathTableData =
|
||||
imagePlugin.ReadSectors(Swapping.Swap(pvd.Value.type_m_path_table), pathTableSizeInSectors);
|
||||
|
||||
fsFormat = "ISO9660";
|
||||
}
|
||||
|
||||
pathTable = DecodePathTable(pathTableData);
|
||||
|
||||
// High Sierra and CD-i do not support Joliet or RRIP
|
||||
if((highSierra || cdi) && this.@namespace != Namespace.Normal && this.@namespace != Namespace.Vms)
|
||||
@@ -179,7 +208,6 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
uint rootLocation = 0;
|
||||
uint rootSize = 0;
|
||||
|
||||
// TODO: Read CD-i root directory
|
||||
if(!cdi)
|
||||
{
|
||||
rootLocation = highSierra
|
||||
@@ -197,6 +225,16 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
if(pvd.Value.root_directory_record.size % pvd.Value.logical_block_size > 0) rootSize++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rootLocation = pathTable[0].Extent;
|
||||
|
||||
byte[] firstRootSector = imagePlugin.ReadSector(rootLocation);
|
||||
CdiDirectoryRecord rootEntry =
|
||||
Marshal.ByteArrayToStructureBigEndian<CdiDirectoryRecord>(firstRootSector);
|
||||
rootSize = rootEntry.size / fsvd.Value.logical_block_size;
|
||||
if(rootEntry.size % fsvd.Value.logical_block_size > 0) rootSize++;
|
||||
}
|
||||
|
||||
if(rootLocation + rootSize >= imagePlugin.Info.Sectors) return Errno.InvalidArgument;
|
||||
|
||||
@@ -210,8 +248,6 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
// TODO: Add IP.BIN to debug root directory
|
||||
// TODO: Add volume descriptors to debug root directory
|
||||
|
||||
if(this.@namespace != Namespace.Romeo) Encoding = Encoding.ASCII;
|
||||
|
||||
if(this.@namespace != Namespace.Joliet)
|
||||
rootDirectoryCache = cdi
|
||||
? DecodeCdiDirectory(rootDir)
|
||||
|
||||
Reference in New Issue
Block a user