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\Date.cs" />
|
||||||
<Compile Include="ISO9660\Dir.cs" />
|
<Compile Include="ISO9660\Dir.cs" />
|
||||||
<Compile Include="ISO9660\File.cs" />
|
<Compile Include="ISO9660\File.cs" />
|
||||||
|
<Compile Include="ISO9660\PathTable.cs" />
|
||||||
<Compile Include="ISO9660\Super.cs" />
|
<Compile Include="ISO9660\Super.cs" />
|
||||||
<Compile Include="ISO9660\Xattr.cs" />
|
<Compile Include="ISO9660\Xattr.cs" />
|
||||||
<Compile Include="PCFX.cs" />
|
<Compile Include="PCFX.cs" />
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ namespace DiscImageChef.Filesystems.ISO9660
|
|||||||
bool joliet;
|
bool joliet;
|
||||||
bool mounted;
|
bool mounted;
|
||||||
Namespace @namespace;
|
Namespace @namespace;
|
||||||
|
PathTableEntryInternal[] pathTable;
|
||||||
Dictionary<string, DecodedDirectoryEntry> rootDirectoryCache;
|
Dictionary<string, DecodedDirectoryEntry> rootDirectoryCache;
|
||||||
FileSystemInfo statfs;
|
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 Point fdLocation;
|
||||||
public uint fdType;
|
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(jolietvd != null) decodedJolietVd = DecodeJolietDescriptor(jolietvd.Value);
|
||||||
|
|
||||||
|
if(this.@namespace != Namespace.Romeo) Encoding = Encoding.ASCII;
|
||||||
|
|
||||||
string fsFormat;
|
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)
|
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";
|
fsFormat = "CD-i";
|
||||||
// TODO: Implement CD-i
|
// TODO: Implement CD-i
|
||||||
return Errno.NotImplemented;
|
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
|
// High Sierra and CD-i do not support Joliet or RRIP
|
||||||
if((highSierra || cdi) && this.@namespace != Namespace.Normal && this.@namespace != Namespace.Vms)
|
if((highSierra || cdi) && this.@namespace != Namespace.Normal && this.@namespace != Namespace.Vms)
|
||||||
@@ -179,7 +208,6 @@ namespace DiscImageChef.Filesystems.ISO9660
|
|||||||
uint rootLocation = 0;
|
uint rootLocation = 0;
|
||||||
uint rootSize = 0;
|
uint rootSize = 0;
|
||||||
|
|
||||||
// TODO: Read CD-i root directory
|
|
||||||
if(!cdi)
|
if(!cdi)
|
||||||
{
|
{
|
||||||
rootLocation = highSierra
|
rootLocation = highSierra
|
||||||
@@ -197,6 +225,16 @@ namespace DiscImageChef.Filesystems.ISO9660
|
|||||||
if(pvd.Value.root_directory_record.size % pvd.Value.logical_block_size > 0) rootSize++;
|
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;
|
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 IP.BIN to debug root directory
|
||||||
// TODO: Add volume descriptors 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)
|
if(this.@namespace != Namespace.Joliet)
|
||||||
rootDirectoryCache = cdi
|
rootDirectoryCache = cdi
|
||||||
? DecodeCdiDirectory(rootDir)
|
? DecodeCdiDirectory(rootDir)
|
||||||
|
|||||||
Reference in New Issue
Block a user