Implement CD-i path table traversal

This commit is contained in:
2019-07-31 05:19:18 +01:00
parent bc8dd3a486
commit 738dcdbdba
3 changed files with 99 additions and 62 deletions

View File

@@ -866,7 +866,44 @@ namespace DiscImageChef.Filesystems.ISO9660
return tableEntries.ToArray(); return tableEntries.ToArray();
} }
DecodedDirectoryEntry[] GetSubdirsFromCdiPathTable(string path) => throw new NotImplementedException(); DecodedDirectoryEntry[] GetSubdirsFromCdiPathTable(string path)
{
PathTableEntryInternal[] tableEntries = GetPathTableEntries(path);
List<DecodedDirectoryEntry> entries = new List<DecodedDirectoryEntry>();
foreach(PathTableEntryInternal tEntry in tableEntries)
{
byte[] sector = image.ReadSector(tEntry.Extent);
CdiDirectoryRecord record =
Marshal.ByteArrayToStructureBigEndian<CdiDirectoryRecord>(sector, 0,
Marshal.SizeOf<CdiDirectoryRecord>());
if(record.length == 0) break;
DecodedDirectoryEntry entry = new DecodedDirectoryEntry
{
Extent = record.size == 0 ? 0 : record.start_lbn,
Size = record.size,
Filename = tEntry.Name,
VolumeSequenceNumber = record.volume_sequence_number,
Timestamp = DecodeHighSierraDateTime(record.date)
};
if(record.flags.HasFlag(CdiFileFlags.Hidden)) entry.Flags |= FileFlags.Hidden;
entry.CdiSystemArea =
Marshal.ByteArrayToStructureBigEndian<CdiSystemArea>(sector,
record.name_len +
Marshal.SizeOf<CdiDirectoryRecord>(),
Marshal.SizeOf<CdiSystemArea>());
if(entry.CdiSystemArea.Value.attributes.HasFlag(CdiAttributes.Directory))
entry.Flags |= FileFlags.Directory;
entries.Add(entry);
}
return entries.ToArray();
}
DecodedDirectoryEntry[] GetSubdirsFromIsoPathTable(string path) DecodedDirectoryEntry[] GetSubdirsFromIsoPathTable(string path)
{ {

View File

@@ -85,90 +85,89 @@ namespace DiscImageChef.Filesystems.ISO9660
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
struct FileStructureVolumeDescriptor struct FileStructureVolumeDescriptor
{ {
public byte type; public readonly byte type;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public byte[] id; public readonly byte[] id;
public byte version; public readonly byte version;
public CdiVolumeFlags flags; public readonly CdiVolumeFlags flags;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] system_id; public readonly byte[] system_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] volume_id; public readonly byte[] volume_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public byte[] reserved1; public readonly byte[] reserved1;
public uint volume_space_size; public readonly uint volume_space_size;
// Only used in SVDs // Only used in SVDs
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] escape_sequences; public readonly byte[] escape_sequences;
public ushort reserved2; public readonly ushort reserved2;
public ushort volume_set_size; public readonly ushort volume_set_size;
public ushort reserved3; public readonly ushort reserved3;
public ushort volume_sequence_number; public readonly ushort volume_sequence_number;
public ushort reserved4; public readonly ushort reserved4;
public ushort logical_block_size; public readonly ushort logical_block_size;
public uint reserved5; public readonly uint reserved5;
public uint path_table_size; public readonly uint path_table_size;
public ulong reserved6; public readonly ulong reserved6;
public uint path_table_addr; public readonly uint path_table_addr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 38)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 38)]
public byte[] reserved7; public readonly byte[] reserved7;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] volume_set_id; public readonly byte[] volume_set_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] publisher_id; public readonly byte[] publisher_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] preparer_id; public readonly byte[] preparer_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] application_id; public readonly byte[] application_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] copyright_file_id; public readonly byte[] copyright_file_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public byte[] reserved8; public readonly byte[] reserved8;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] abstract_file_id; public readonly byte[] abstract_file_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public byte[] reserved9; public readonly byte[] reserved9;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] bibliographic_file_id; public readonly byte[] bibliographic_file_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public byte[] reserved10; public readonly byte[] reserved10;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] creation_date; public readonly byte[] creation_date;
public byte reserved11; public readonly byte reserved11;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] modification_date; public readonly byte[] modification_date;
public byte reserved12; public readonly byte reserved12;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] expiration_date; public readonly byte[] expiration_date;
public byte reserved13; public readonly byte reserved13;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] effective_date; public readonly byte[] effective_date;
public byte reserved14; public readonly byte reserved14;
public byte file_structure_version; public readonly byte file_structure_version;
public byte reserved15; public readonly byte reserved15;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
public byte[] application_data; public readonly byte[] application_data;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 653)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 653)]
public byte[] reserved16; public readonly byte[] reserved16;
} }
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
struct CdiDirectoryRecord struct CdiDirectoryRecord
{ {
public byte length; public readonly byte length;
public byte xattr_len; public readonly byte xattr_len;
public uint reserved1; public readonly uint reserved1;
public uint start_lbn; public readonly uint start_lbn;
public uint reserved2; public readonly uint reserved2;
public uint size; public readonly uint size;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] public readonly HighSierraTimestamp date;
public byte[] date; public readonly byte reserved3;
public byte reserved3; public readonly CdiFileFlags flags;
public CdiFileFlags flags; public readonly ushort file_unit_size;
public ushort file_unit_size; public readonly ushort reserved4;
public ushort reserved4; public readonly ushort volume_sequence_number;
public ushort volume_sequence_number; public readonly byte name_len;
public byte name_len;
// Followed by name[name_len] and then CdiSystemArea until length arrives // Followed by name[name_len] and then CdiSystemArea until length arrives
} }
@@ -176,11 +175,11 @@ namespace DiscImageChef.Filesystems.ISO9660
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
struct CdiSystemArea struct CdiSystemArea
{ {
public uint owner; public readonly uint owner;
public CdiAttributes attributes; public readonly CdiAttributes attributes;
public ushort reserved1; public readonly ushort reserved1;
public byte file_no; public readonly byte file_no;
public byte reserved2; public readonly byte reserved2;
} }
} }
} }

View File

@@ -63,6 +63,7 @@ namespace DiscImageChef.Filesystems.ISO9660
public byte[] AppleIcon; public byte[] AppleIcon;
public ushort? AppleProDosType; public ushort? AppleProDosType;
public DecodedDirectoryEntry AssociatedFile; public DecodedDirectoryEntry AssociatedFile;
public CdiSystemArea? CdiSystemArea;
public uint Extent; public uint Extent;
public string Filename; public string Filename;
public byte FileUnitSize; public byte FileUnitSize;