From a2314ff9d525a57bcb7b6fc70251e172c1eec3c8 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Mon, 29 Jul 2019 14:04:30 +0100 Subject: [PATCH] Decode "CL", "PL" and "RE" system areas. --- DiscImageChef.Filesystems/ISO9660/Dir.cs | 36 +++++++++++++++++-- .../ISO9660/Structs/Internal.cs | 1 + 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/DiscImageChef.Filesystems/ISO9660/Dir.cs b/DiscImageChef.Filesystems/ISO9660/Dir.cs index 33f39dfdc..97199e371 100644 --- a/DiscImageChef.Filesystems/ISO9660/Dir.cs +++ b/DiscImageChef.Filesystems/ISO9660/Dir.cs @@ -274,7 +274,10 @@ namespace DiscImageChef.Filesystems.ISO9660 entryOff += record.length; } - return entries; + // Relocated directories should be shown in correct place when using Rock Ridge namespace + return @namespace == Namespace.Rrip + ? entries.Where(e => !e.Value.RockRidgeRelocated).ToDictionary(x => x.Key, x => x.Value) + : entries; } void DecodeSystemArea(byte[] data, int start, int end, ref DecodedDirectoryEntry entry, @@ -590,20 +593,47 @@ namespace DiscImageChef.Filesystems.ISO9660 case RRIP_CHILDLINK: // TODO byte clLength = data[systemAreaOff + 2]; + + // If we are not in Rock Ridge namespace, or we are using the Path Table, skip it + if(@namespace != Namespace.Rrip || usePathTable) + { + systemAreaOff += clLength; + break; + } + + ChildLink cl = + Marshal.ByteArrayToStructureLittleEndian(data, systemAreaOff, + Marshal.SizeOf()); + + byte[] childSector = image.ReadSector(cl.child_dir_lba); + DirectoryRecord childRecord = + Marshal.ByteArrayToStructureLittleEndian(childSector); + + // As per RRIP 4.1.5.1, we leave name as in previous entry, substitute location with the one in + // the CL, and replace all other fields with the ones found in the first entry of the child + entry.Extent = cl.child_dir_lba; + entry.Size = childRecord.size; + entry.Flags = childRecord.flags; + entry.FileUnitSize = childRecord.file_unit_size; + entry.Interleave = childRecord.interleave; + entry.VolumeSequenceNumber = childRecord.volume_sequence_number; + entry.Timestamp = DecodeIsoDateTime(childRecord.date); + systemAreaOff += clLength; break; case RRIP_PARENTLINK: - // TODO + // SKip, we don't need it byte plLength = data[systemAreaOff + 2]; systemAreaOff += plLength; break; case RRIP_RELOCATED_DIR: - // TODO byte reLength = data[systemAreaOff + 2]; systemAreaOff += reLength; + entry.RockRidgeRelocated = true; + break; case RRIP_TIMESTAMPS: byte tfLength = data[systemAreaOff + 2]; diff --git a/DiscImageChef.Filesystems/ISO9660/Structs/Internal.cs b/DiscImageChef.Filesystems/ISO9660/Structs/Internal.cs index 48cd64875..68a26c988 100644 --- a/DiscImageChef.Filesystems/ISO9660/Structs/Internal.cs +++ b/DiscImageChef.Filesystems/ISO9660/Structs/Internal.cs @@ -74,6 +74,7 @@ namespace DiscImageChef.Filesystems.ISO9660 public PosixDeviceNumber? PosixDeviceNumber; public DecodedDirectoryEntry ResourceFork; public byte[] RockRidgeAlternateName; + public bool RockRidgeRelocated; public byte[] RripAccess; public byte[] RripAttributeChange; public byte[] RripBackup;