diff --git a/DiscImageChef.Filesystems/ISO9660/Dir.cs b/DiscImageChef.Filesystems/ISO9660/Dir.cs index abce2a7c3..f90c56146 100644 --- a/DiscImageChef.Filesystems/ISO9660/Dir.cs +++ b/DiscImageChef.Filesystems/ISO9660/Dir.cs @@ -115,8 +115,57 @@ namespace DiscImageChef.Filesystems.ISO9660 return contents; } - Dictionary DecodeCdiDirectory(byte[] data) => - throw new NotImplementedException(); + Dictionary DecodeCdiDirectory(byte[] data) + { + Dictionary entries = new Dictionary(); + int entryOff = 0; + + while(entryOff + DirectoryRecordSize < data.Length) + { + CdiDirectoryRecord record = + Marshal.ByteArrayToStructureBigEndian(data, entryOff, + Marshal.SizeOf()); + + if(record.length == 0) break; + + // Special entries for current and parent directories, skip them + if(record.name_len == 1) + if(data[entryOff + DirectoryRecordSize] == 0 || data[entryOff + DirectoryRecordSize] == 1) + { + entryOff += record.length; + continue; + } + + DecodedDirectoryEntry entry = new DecodedDirectoryEntry + { + Extent = record.size == 0 ? 0 : record.start_lbn, + Size = record.size, + Filename = Encoding.GetString(data, entryOff + DirectoryRecordSize, record.name_len), + VolumeSequenceNumber = record.volume_sequence_number, + Timestamp = DecodeHighSierraDateTime(record.date), + XattrLength = record.xattr_len + }; + + if(record.flags.HasFlag(CdiFileFlags.Hidden)) + { + entry.Flags |= FileFlags.Hidden; + continue; + } + + entry.CdiSystemArea = + Marshal.ByteArrayToStructureBigEndian(data, + entryOff + record.name_len + + Marshal.SizeOf(), + Marshal.SizeOf()); + + if(!entry.CdiSystemArea.Value.attributes.HasFlag(CdiAttributes.Directory) || !usePathTable) + entries[entry.Filename] = entry; + + entryOff += record.length; + } + + return entries; + } Dictionary DecodeHighSierraDirectory(byte[] data) {