Handle when ISO9660 directories have extended attributes.

This commit is contained in:
2019-07-31 05:47:28 +01:00
parent 7b07c1e243
commit 4616f59a6b
4 changed files with 42 additions and 25 deletions

View File

@@ -71,10 +71,10 @@ namespace DiscImageChef.Filesystems.ISO9660
// TODO: Decode Joliet
currentDirectory = cdi
? DecodeCdiDirectory(directoryBuffer)
? DecodeCdiDirectory(directoryBuffer, entry.Value.XattrLength)
: highSierra
? DecodeHighSierraDirectory(directoryBuffer)
: DecodeIsoDirectory(directoryBuffer);
? DecodeHighSierraDirectory(directoryBuffer, entry.Value.XattrLength)
: DecodeIsoDirectory(directoryBuffer, entry.Value.XattrLength);
if(usePathTable)
foreach(DecodedDirectoryEntry subDirectory in cdi
@@ -115,10 +115,10 @@ namespace DiscImageChef.Filesystems.ISO9660
return contents;
}
Dictionary<string, DecodedDirectoryEntry> DecodeCdiDirectory(byte[] data)
Dictionary<string, DecodedDirectoryEntry> DecodeCdiDirectory(byte[] data, byte XattrLength)
{
Dictionary<string, DecodedDirectoryEntry> entries = new Dictionary<string, DecodedDirectoryEntry>();
int entryOff = 0;
int entryOff = XattrLength;
while(entryOff + DirectoryRecordSize < data.Length)
{
@@ -167,10 +167,10 @@ namespace DiscImageChef.Filesystems.ISO9660
return entries;
}
Dictionary<string, DecodedDirectoryEntry> DecodeHighSierraDirectory(byte[] data)
Dictionary<string, DecodedDirectoryEntry> DecodeHighSierraDirectory(byte[] data, byte XattrLength)
{
Dictionary<string, DecodedDirectoryEntry> entries = new Dictionary<string, DecodedDirectoryEntry>();
int entryOff = 0;
int entryOff = XattrLength;
while(entryOff + DirectoryRecordSize < data.Length)
{
@@ -217,10 +217,10 @@ namespace DiscImageChef.Filesystems.ISO9660
return entries;
}
Dictionary<string, DecodedDirectoryEntry> DecodeIsoDirectory(byte[] data)
Dictionary<string, DecodedDirectoryEntry> DecodeIsoDirectory(byte[] data, byte XattrLength)
{
Dictionary<string, DecodedDirectoryEntry> entries = new Dictionary<string, DecodedDirectoryEntry>();
int entryOff = 0;
int entryOff = XattrLength;
while(entryOff + DirectoryRecordSize < data.Length)
{
@@ -732,6 +732,7 @@ namespace DiscImageChef.Filesystems.ISO9660
entry.Interleave = childRecord.interleave;
entry.VolumeSequenceNumber = childRecord.volume_sequence_number;
entry.Timestamp = DecodeIsoDateTime(childRecord.date);
entry.XattrLength = childRecord.xattr_len;
systemAreaOff += clLength;
@@ -923,7 +924,7 @@ namespace DiscImageChef.Filesystems.ISO9660
{
byte[] sector = image.ReadSector(tEntry.Extent);
CdiDirectoryRecord record =
Marshal.ByteArrayToStructureBigEndian<CdiDirectoryRecord>(sector, 0,
Marshal.ByteArrayToStructureBigEndian<CdiDirectoryRecord>(sector, tEntry.XattrLength,
Marshal.SizeOf<CdiDirectoryRecord>());
if(record.length == 0) break;
@@ -934,7 +935,8 @@ namespace DiscImageChef.Filesystems.ISO9660
Size = record.size,
Filename = tEntry.Name,
VolumeSequenceNumber = record.volume_sequence_number,
Timestamp = DecodeHighSierraDateTime(record.date)
Timestamp = DecodeHighSierraDateTime(record.date),
XattrLength = tEntry.XattrLength
};
if(record.flags.HasFlag(CdiFileFlags.Hidden)) entry.Flags |= FileFlags.Hidden;
@@ -962,7 +964,7 @@ namespace DiscImageChef.Filesystems.ISO9660
{
byte[] sector = image.ReadSector(tEntry.Extent);
DirectoryRecord record =
Marshal.ByteArrayToStructureLittleEndian<DirectoryRecord>(sector, 0,
Marshal.ByteArrayToStructureLittleEndian<DirectoryRecord>(sector, tEntry.XattrLength,
Marshal.SizeOf<DirectoryRecord>());
if(record.length == 0) break;
@@ -976,7 +978,8 @@ namespace DiscImageChef.Filesystems.ISO9660
FileUnitSize = record.file_unit_size,
Interleave = record.interleave,
VolumeSequenceNumber = record.volume_sequence_number,
Timestamp = DecodeIsoDateTime(record.date)
Timestamp = DecodeIsoDateTime(record.date),
XattrLength = tEntry.XattrLength
};
// TODO: XA
@@ -1005,7 +1008,7 @@ namespace DiscImageChef.Filesystems.ISO9660
{
byte[] sector = image.ReadSector(tEntry.Extent);
HighSierraDirectoryRecord record =
Marshal.ByteArrayToStructureLittleEndian<HighSierraDirectoryRecord>(sector, 0,
Marshal.ByteArrayToStructureLittleEndian<HighSierraDirectoryRecord>(sector, tEntry.XattrLength,
Marshal
.SizeOf<
HighSierraDirectoryRecord
@@ -1019,7 +1022,8 @@ namespace DiscImageChef.Filesystems.ISO9660
Filename = tEntry.Name,
Interleave = record.interleave,
VolumeSequenceNumber = record.volume_sequence_number,
Timestamp = DecodeHighSierraDateTime(record.date)
Timestamp = DecodeHighSierraDateTime(record.date),
XattrLength = tEntry.XattrLength
};
entries.Add(entry);

View File

@@ -25,7 +25,10 @@ namespace DiscImageChef.Filesystems.ISO9660
table.Add(new PathTableEntryInternal
{
Extent = entry.start_lbn, Name = name, Parent = entry.parent_dirno
Extent = entry.start_lbn,
Name = name,
Parent = entry.parent_dirno,
XattrLength = entry.xattr_len
});
off += entry.name_len;
@@ -59,7 +62,10 @@ namespace DiscImageChef.Filesystems.ISO9660
table.Add(new PathTableEntryInternal
{
Extent = entry.start_lbn, Name = name, Parent = entry.parent_dirno
Extent = entry.start_lbn,
Name = name,
Parent = entry.parent_dirno,
XattrLength = entry.xattr_len
});
off += entry.name_len;

View File

@@ -132,6 +132,7 @@ namespace DiscImageChef.Filesystems.ISO9660
public uint Extent;
public string Name;
public ushort Parent;
public byte XattrLength;
public override string ToString() => Name;
}

View File

@@ -229,7 +229,7 @@ namespace DiscImageChef.Filesystems.ISO9660
pathTableMsbLocation = fsvd.Value.path_table_addr;
// TODO: Until escape sequences are implemented this is the default CD-i encoding.
Encoding = System.Text.Encoding.GetEncoding("iso8859-1");
Encoding = Encoding.GetEncoding("iso8859-1");
// TODO: Implement CD-i
return Errno.NotImplemented;
@@ -258,6 +258,7 @@ namespace DiscImageChef.Filesystems.ISO9660
uint rootLocation = 0;
uint rootSize = 0;
byte rootXattrLength = 0;
if(!cdi)
{
@@ -265,6 +266,10 @@ namespace DiscImageChef.Filesystems.ISO9660
? hsvd.Value.root_directory_record.extent
: pvd.Value.root_directory_record.extent;
rootXattrLength = highSierra
? hsvd.Value.root_directory_record.xattr_len
: pvd.Value.root_directory_record.xattr_len;
if(highSierra)
{
rootSize = hsvd.Value.root_directory_record.size / hsvd.Value.logical_block_size;
@@ -310,10 +315,10 @@ namespace DiscImageChef.Filesystems.ISO9660
if(this.@namespace != Namespace.Joliet)
rootDirectoryCache = cdi
? DecodeCdiDirectory(rootDir)
? DecodeCdiDirectory(rootDir, rootXattrLength)
: highSierra
? DecodeHighSierraDirectory(rootDir)
: DecodeIsoDirectory(rootDir);
? DecodeHighSierraDirectory(rootDir, rootXattrLength)
: DecodeIsoDirectory(rootDir, rootXattrLength);
XmlFsType.Type = fsFormat;
@@ -431,6 +436,7 @@ namespace DiscImageChef.Filesystems.ISO9660
if(jolietvd != null && (this.@namespace == Namespace.Joliet || this.@namespace == Namespace.Rrip))
{
rootLocation = jolietvd.Value.root_directory_record.extent;
rootXattrLength = jolietvd.Value.root_directory_record.xattr_len;
rootSize = jolietvd.Value.root_directory_record.size / jolietvd.Value.logical_block_size;
if(pvd.Value.root_directory_record.size % jolietvd.Value.logical_block_size > 0)
@@ -442,7 +448,7 @@ namespace DiscImageChef.Filesystems.ISO9660
rootDir = imagePlugin.ReadSectors(rootLocation, rootSize);
rootDirectoryCache = DecodeIsoDirectory(rootDir);
rootDirectoryCache = DecodeIsoDirectory(rootDir, rootXattrLength);
XmlFsType.VolumeName = decodedJolietVd.VolumeIdentifier;