mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Fix reading ISO9660, CD-i and HSF directories that span several sectors.
This commit is contained in:
@@ -94,35 +94,17 @@ namespace DiscImageChef.Filesystems.ISO9660
|
|||||||
|
|
||||||
if(entry.Value.Extents.Count == 0) return Errno.InvalidArgument;
|
if(entry.Value.Extents.Count == 0) return Errno.InvalidArgument;
|
||||||
|
|
||||||
byte[] directoryBuffer;
|
uint dirSizeInSectors = entry.Value.Extents[0].size / 2048;
|
||||||
if(entry.Value.Extents.Count == 1)
|
if(entry.Value.Size % 2048 > 0) dirSizeInSectors++;
|
||||||
{
|
|
||||||
uint dirSizeInSectors = entry.Value.Extents[0].size / 2048;
|
|
||||||
if(entry.Value.Size % 2048 > 0) dirSizeInSectors++;
|
|
||||||
directoryBuffer = ReadSectors(entry.Value.Extents[0].extent, dirSizeInSectors);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MemoryStream ms = new MemoryStream();
|
|
||||||
|
|
||||||
foreach((uint extent, uint size) extent in entry.Value.Extents)
|
|
||||||
{
|
|
||||||
uint extentSizeInSectors = extent.size / 2048;
|
|
||||||
if(extent.size % 2048 > 0) extentSizeInSectors++;
|
|
||||||
|
|
||||||
byte[] extentData = ReadSectors(extent.extent, extentSizeInSectors);
|
|
||||||
|
|
||||||
ms.Write(extentData, 0, extentData.Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
directoryBuffer = ms.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
currentDirectory = cdi
|
currentDirectory = cdi
|
||||||
? DecodeCdiDirectory(directoryBuffer, entry.Value.XattrLength)
|
? DecodeCdiDirectory(entry.Value.Extents[0].extent, dirSizeInSectors,
|
||||||
|
entry.Value.XattrLength)
|
||||||
: highSierra
|
: highSierra
|
||||||
? DecodeHighSierraDirectory(directoryBuffer, entry.Value.XattrLength)
|
? DecodeHighSierraDirectory(entry.Value.Extents[0].extent, dirSizeInSectors,
|
||||||
: DecodeIsoDirectory(directoryBuffer, entry.Value.XattrLength);
|
entry.Value.XattrLength)
|
||||||
|
: DecodeIsoDirectory(entry.Value.Extents[0].extent, dirSizeInSectors,
|
||||||
|
entry.Value.XattrLength);
|
||||||
|
|
||||||
if(usePathTable)
|
if(usePathTable)
|
||||||
foreach(DecodedDirectoryEntry subDirectory in cdi
|
foreach(DecodedDirectoryEntry subDirectory in cdi
|
||||||
@@ -163,107 +145,125 @@ namespace DiscImageChef.Filesystems.ISO9660
|
|||||||
return contents;
|
return contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
Dictionary<string, DecodedDirectoryEntry> DecodeCdiDirectory(byte[] data, byte xattrLength)
|
Dictionary<string, DecodedDirectoryEntry> DecodeCdiDirectory(ulong start, uint count, byte xattrLength)
|
||||||
{
|
{
|
||||||
Dictionary<string, DecodedDirectoryEntry> entries = new Dictionary<string, DecodedDirectoryEntry>();
|
Dictionary<string, DecodedDirectoryEntry> entries = new Dictionary<string, DecodedDirectoryEntry>();
|
||||||
int entryOff = xattrLength;
|
int entryOff = xattrLength;
|
||||||
|
|
||||||
while(entryOff + CdiDirectoryRecordSize < data.Length)
|
for(ulong sector = start; sector < start + count; sector++)
|
||||||
{
|
{
|
||||||
CdiDirectoryRecord record =
|
byte[] data = ReadSectors(sector, 1);
|
||||||
Marshal.ByteArrayToStructureBigEndian<CdiDirectoryRecord>(data, entryOff, CdiDirectoryRecordSize);
|
|
||||||
|
|
||||||
if(record.length == 0) break;
|
while(entryOff + CdiDirectoryRecordSize < data.Length)
|
||||||
|
{
|
||||||
|
CdiDirectoryRecord record =
|
||||||
|
Marshal.ByteArrayToStructureBigEndian<CdiDirectoryRecord>(data, entryOff,
|
||||||
|
CdiDirectoryRecordSize);
|
||||||
|
|
||||||
// Special entries for current and parent directories, skip them
|
if(record.length == 0) break;
|
||||||
if(record.name_len == 1)
|
|
||||||
if(data[entryOff + DirectoryRecordSize] == 0 || data[entryOff + DirectoryRecordSize] == 1)
|
// 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
|
||||||
{
|
{
|
||||||
entryOff += record.length;
|
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.size != 0)
|
||||||
|
entry.Extents = new List<(uint extent, uint size)> {(record.start_lbn, record.size)};
|
||||||
|
|
||||||
|
if(record.flags.HasFlag(CdiFileFlags.Hidden))
|
||||||
|
{
|
||||||
|
entry.Flags |= FileFlags.Hidden;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
DecodedDirectoryEntry entry = new DecodedDirectoryEntry
|
entry.CdiSystemArea =
|
||||||
{
|
Marshal.ByteArrayToStructureBigEndian<CdiSystemArea>(data,
|
||||||
Size = record.size,
|
entryOff + record.name_len +
|
||||||
Filename = Encoding.GetString(data, entryOff + DirectoryRecordSize, record.name_len),
|
CdiDirectoryRecordSize, CdiSystemAreaSize);
|
||||||
VolumeSequenceNumber = record.volume_sequence_number,
|
|
||||||
Timestamp = DecodeHighSierraDateTime(record.date),
|
|
||||||
XattrLength = record.xattr_len
|
|
||||||
};
|
|
||||||
|
|
||||||
if(record.size != 0)
|
if(entry.CdiSystemArea.Value.attributes.HasFlag(CdiAttributes.Directory))
|
||||||
entry.Extents = new List<(uint extent, uint size)> {(record.start_lbn, record.size)};
|
{
|
||||||
|
entry.Flags |= FileFlags.Directory;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if(record.flags.HasFlag(CdiFileFlags.Hidden))
|
if(!entry.CdiSystemArea.Value.attributes.HasFlag(CdiAttributes.Directory) || !usePathTable)
|
||||||
{
|
entries[entry.Filename] = entry;
|
||||||
entry.Flags |= FileFlags.Hidden;
|
|
||||||
continue;
|
entryOff += record.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry.CdiSystemArea =
|
entryOff = 0;
|
||||||
Marshal.ByteArrayToStructureBigEndian<CdiSystemArea>(data,
|
|
||||||
entryOff + record.name_len +
|
|
||||||
CdiDirectoryRecordSize, CdiSystemAreaSize);
|
|
||||||
|
|
||||||
if(entry.CdiSystemArea.Value.attributes.HasFlag(CdiAttributes.Directory))
|
|
||||||
{
|
|
||||||
entry.Flags |= FileFlags.Directory;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!entry.CdiSystemArea.Value.attributes.HasFlag(CdiAttributes.Directory) || !usePathTable)
|
|
||||||
entries[entry.Filename] = entry;
|
|
||||||
|
|
||||||
entryOff += record.length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return entries;
|
return entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
Dictionary<string, DecodedDirectoryEntry> DecodeHighSierraDirectory(byte[] data, byte xattrLength)
|
Dictionary<string, DecodedDirectoryEntry> DecodeHighSierraDirectory(ulong start, uint count, byte xattrLength)
|
||||||
{
|
{
|
||||||
Dictionary<string, DecodedDirectoryEntry> entries = new Dictionary<string, DecodedDirectoryEntry>();
|
Dictionary<string, DecodedDirectoryEntry> entries = new Dictionary<string, DecodedDirectoryEntry>();
|
||||||
int entryOff = xattrLength;
|
int entryOff = xattrLength;
|
||||||
|
|
||||||
while(entryOff + DirectoryRecordSize < data.Length)
|
for(ulong sector = start; sector < start + count; sector++)
|
||||||
{
|
{
|
||||||
HighSierraDirectoryRecord record =
|
byte[] data = ReadSectors(sector, 1);
|
||||||
Marshal.ByteArrayToStructureLittleEndian<HighSierraDirectoryRecord>(data, entryOff,
|
|
||||||
HighSierraDirectoryRecordSize);
|
|
||||||
|
|
||||||
if(record.length == 0) break;
|
while(entryOff + DirectoryRecordSize < data.Length)
|
||||||
|
{
|
||||||
|
HighSierraDirectoryRecord record =
|
||||||
|
Marshal.ByteArrayToStructureLittleEndian<HighSierraDirectoryRecord>(data, entryOff,
|
||||||
|
HighSierraDirectoryRecordSize);
|
||||||
|
|
||||||
// Special entries for current and parent directories, skip them
|
if(record.length == 0) break;
|
||||||
if(record.name_len == 1)
|
|
||||||
if(data[entryOff + DirectoryRecordSize] == 0 || data[entryOff + DirectoryRecordSize] == 1)
|
// 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
|
||||||
|
{
|
||||||
|
Size = record.size,
|
||||||
|
Flags = record.flags,
|
||||||
|
Interleave = record.interleave,
|
||||||
|
VolumeSequenceNumber = record.volume_sequence_number,
|
||||||
|
Filename =
|
||||||
|
Encoding.GetString(data, entryOff + DirectoryRecordSize, record.name_len),
|
||||||
|
Timestamp = DecodeHighSierraDateTime(record.date),
|
||||||
|
XattrLength = record.xattr_len
|
||||||
|
};
|
||||||
|
|
||||||
|
if(record.size != 0)
|
||||||
|
entry.Extents = new List<(uint extent, uint size)> {(record.extent, record.size)};
|
||||||
|
|
||||||
|
if(entry.Flags.HasFlag(FileFlags.Directory) && usePathTable)
|
||||||
{
|
{
|
||||||
entryOff += record.length;
|
entryOff += record.length;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
DecodedDirectoryEntry entry = new DecodedDirectoryEntry
|
if(!entries.ContainsKey(entry.Filename)) entries.Add(entry.Filename, entry);
|
||||||
{
|
|
||||||
Size = record.size,
|
|
||||||
Flags = record.flags,
|
|
||||||
Interleave = record.interleave,
|
|
||||||
VolumeSequenceNumber = record.volume_sequence_number,
|
|
||||||
Filename = Encoding.GetString(data, entryOff + DirectoryRecordSize, record.name_len),
|
|
||||||
Timestamp = DecodeHighSierraDateTime(record.date),
|
|
||||||
XattrLength = record.xattr_len
|
|
||||||
};
|
|
||||||
|
|
||||||
if(record.size != 0) entry.Extents = new List<(uint extent, uint size)> {(record.extent, record.size)};
|
|
||||||
|
|
||||||
if(entry.Flags.HasFlag(FileFlags.Directory) && usePathTable)
|
|
||||||
{
|
|
||||||
entryOff += record.length;
|
entryOff += record.length;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!entries.ContainsKey(entry.Filename)) entries.Add(entry.Filename, entry);
|
entryOff = 0;
|
||||||
|
|
||||||
entryOff += record.length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(useTransTbl) DecodeTransTable(entries);
|
if(useTransTbl) DecodeTransTable(entries);
|
||||||
@@ -271,134 +271,142 @@ namespace DiscImageChef.Filesystems.ISO9660
|
|||||||
return entries;
|
return entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
Dictionary<string, DecodedDirectoryEntry> DecodeIsoDirectory(byte[] data, byte xattrLength)
|
Dictionary<string, DecodedDirectoryEntry> DecodeIsoDirectory(ulong start, uint count, byte xattrLength)
|
||||||
{
|
{
|
||||||
Dictionary<string, DecodedDirectoryEntry> entries = new Dictionary<string, DecodedDirectoryEntry>();
|
Dictionary<string, DecodedDirectoryEntry> entries = new Dictionary<string, DecodedDirectoryEntry>();
|
||||||
int entryOff = xattrLength;
|
int entryOff = xattrLength;
|
||||||
|
|
||||||
while(entryOff + DirectoryRecordSize < data.Length)
|
for(ulong sector = start; sector < start + count; sector++)
|
||||||
{
|
{
|
||||||
DirectoryRecord record =
|
byte[] data = ReadSectors(sector, 1);
|
||||||
Marshal.ByteArrayToStructureLittleEndian<DirectoryRecord>(data, entryOff, DirectoryRecordSize);
|
|
||||||
|
|
||||||
if(record.length == 0) break;
|
while(entryOff + DirectoryRecordSize < data.Length)
|
||||||
|
{
|
||||||
|
DirectoryRecord record =
|
||||||
|
Marshal.ByteArrayToStructureLittleEndian<DirectoryRecord>(data, entryOff, DirectoryRecordSize);
|
||||||
|
|
||||||
// Special entries for current and parent directories, skip them
|
if(record.length == 0) break;
|
||||||
if(record.name_len == 1)
|
|
||||||
if(data[entryOff + DirectoryRecordSize] == 0 || data[entryOff + DirectoryRecordSize] == 1)
|
// 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
|
||||||
|
{
|
||||||
|
Size = record.size,
|
||||||
|
Flags = record.flags,
|
||||||
|
Filename =
|
||||||
|
joliet
|
||||||
|
? Encoding.BigEndianUnicode.GetString(data, entryOff + DirectoryRecordSize,
|
||||||
|
record.name_len)
|
||||||
|
: Encoding.GetString(data, entryOff + DirectoryRecordSize, record.name_len),
|
||||||
|
FileUnitSize = record.file_unit_size,
|
||||||
|
Interleave = record.interleave,
|
||||||
|
VolumeSequenceNumber = record.volume_sequence_number,
|
||||||
|
Timestamp = DecodeIsoDateTime(record.date),
|
||||||
|
XattrLength = record.xattr_len
|
||||||
|
};
|
||||||
|
|
||||||
|
if(record.size != 0)
|
||||||
|
entry.Extents = new List<(uint extent, uint size)> {(record.extent, record.size)};
|
||||||
|
|
||||||
|
if(entry.Flags.HasFlag(FileFlags.Directory) && usePathTable)
|
||||||
{
|
{
|
||||||
entryOff += record.length;
|
entryOff += record.length;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
DecodedDirectoryEntry entry = new DecodedDirectoryEntry
|
// Mac OS can use slashes, we cannot
|
||||||
{
|
entry.Filename = entry.Filename.Replace('/', '\u2215');
|
||||||
Size = record.size,
|
|
||||||
Flags = record.flags,
|
|
||||||
Filename =
|
|
||||||
joliet
|
|
||||||
? Encoding.BigEndianUnicode.GetString(data, entryOff + DirectoryRecordSize,
|
|
||||||
record.name_len)
|
|
||||||
: Encoding.GetString(data, entryOff + DirectoryRecordSize, record.name_len),
|
|
||||||
FileUnitSize = record.file_unit_size,
|
|
||||||
Interleave = record.interleave,
|
|
||||||
VolumeSequenceNumber = record.volume_sequence_number,
|
|
||||||
Timestamp = DecodeIsoDateTime(record.date),
|
|
||||||
XattrLength = record.xattr_len
|
|
||||||
};
|
|
||||||
|
|
||||||
if(record.size != 0) entry.Extents = new List<(uint extent, uint size)> {(record.extent, record.size)};
|
// Tailing '.' is only allowed on RRIP. If present it will be recreated below with the alternate name
|
||||||
|
if(entry.Filename.EndsWith(".", StringComparison.Ordinal))
|
||||||
|
entry.Filename = entry.Filename.Substring(0, entry.Filename.Length - 1);
|
||||||
|
|
||||||
if(entry.Flags.HasFlag(FileFlags.Directory) && usePathTable)
|
if(entry.Filename.EndsWith(".;1", StringComparison.Ordinal))
|
||||||
{
|
entry.Filename = entry.Filename.Substring(0, entry.Filename.Length - 3) + ";1";
|
||||||
entryOff += record.length;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mac OS can use slashes, we cannot
|
// This is a legal Joliet name, different from VMS version fields, but Nero MAX incorrectly creates these filenames
|
||||||
entry.Filename = entry.Filename.Replace('/', '\u2215');
|
if(joliet && entry.Filename.EndsWith(";1", StringComparison.Ordinal))
|
||||||
|
entry.Filename = entry.Filename.Substring(0, entry.Filename.Length - 2);
|
||||||
|
|
||||||
// Tailing '.' is only allowed on RRIP. If present it will be recreated below with the alternate name
|
int systemAreaStart = entryOff + record.name_len + DirectoryRecordSize;
|
||||||
if(entry.Filename.EndsWith(".", StringComparison.Ordinal))
|
int systemAreaLength = record.length - record.name_len - DirectoryRecordSize;
|
||||||
entry.Filename = entry.Filename.Substring(0, entry.Filename.Length - 1);
|
|
||||||
|
|
||||||
if(entry.Filename.EndsWith(".;1", StringComparison.Ordinal))
|
if(systemAreaStart % 2 != 0)
|
||||||
entry.Filename = entry.Filename.Substring(0, entry.Filename.Length - 3) + ";1";
|
|
||||||
|
|
||||||
// This is a legal Joliet name, different from VMS version fields, but Nero MAX incorrectly creates these filenames
|
|
||||||
if(joliet && entry.Filename.EndsWith(";1", StringComparison.Ordinal))
|
|
||||||
entry.Filename = entry.Filename.Substring(0, entry.Filename.Length - 2);
|
|
||||||
|
|
||||||
int systemAreaStart = entryOff + record.name_len + DirectoryRecordSize;
|
|
||||||
int systemAreaLength = record.length - record.name_len - DirectoryRecordSize;
|
|
||||||
|
|
||||||
if(systemAreaStart % 2 != 0)
|
|
||||||
{
|
|
||||||
systemAreaStart++;
|
|
||||||
systemAreaLength--;
|
|
||||||
}
|
|
||||||
|
|
||||||
DecodeSystemArea(data, systemAreaStart, systemAreaStart + systemAreaLength, ref entry,
|
|
||||||
out bool hasResourceFork);
|
|
||||||
|
|
||||||
if(entry.Flags.HasFlag(FileFlags.Associated))
|
|
||||||
{
|
|
||||||
if(entries.ContainsKey(entry.Filename))
|
|
||||||
{
|
{
|
||||||
if(hasResourceFork)
|
systemAreaStart++;
|
||||||
|
systemAreaLength--;
|
||||||
|
}
|
||||||
|
|
||||||
|
DecodeSystemArea(data, systemAreaStart, systemAreaStart + systemAreaLength, ref entry,
|
||||||
|
out bool hasResourceFork);
|
||||||
|
|
||||||
|
if(entry.Flags.HasFlag(FileFlags.Associated))
|
||||||
|
{
|
||||||
|
if(entries.ContainsKey(entry.Filename))
|
||||||
{
|
{
|
||||||
entries[entry.Filename].ResourceFork.Size += entry.Size;
|
if(hasResourceFork)
|
||||||
entries[entry.Filename].ResourceFork.Extents.Add(entry.Extents[0]);
|
{
|
||||||
|
entries[entry.Filename].ResourceFork.Size += entry.Size;
|
||||||
|
entries[entry.Filename].ResourceFork.Extents.Add(entry.Extents[0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
entries[entry.Filename].AssociatedFile.Size += entry.Size;
|
||||||
|
entries[entry.Filename].AssociatedFile.Extents.Add(entry.Extents[0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
entries[entry.Filename].AssociatedFile.Size += entry.Size;
|
entries[entry.Filename] = new DecodedDirectoryEntry
|
||||||
entries[entry.Filename].AssociatedFile.Extents.Add(entry.Extents[0]);
|
{
|
||||||
|
Size = 0,
|
||||||
|
Flags = record.flags ^ FileFlags.Associated,
|
||||||
|
FileUnitSize = 0,
|
||||||
|
Interleave = 0,
|
||||||
|
VolumeSequenceNumber = record.volume_sequence_number,
|
||||||
|
Filename = entry.Filename,
|
||||||
|
Timestamp = DecodeIsoDateTime(record.date),
|
||||||
|
XattrLength = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
if(hasResourceFork) entries[entry.Filename].ResourceFork = entry;
|
||||||
|
else entries[entry.Filename].AssociatedFile = entry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
entries[entry.Filename] = new DecodedDirectoryEntry
|
if(entries.ContainsKey(entry.Filename))
|
||||||
{
|
{
|
||||||
Size = 0,
|
entries[entry.Filename].Size += entry.Size;
|
||||||
Flags = record.flags ^ FileFlags.Associated,
|
|
||||||
FileUnitSize = 0,
|
|
||||||
Interleave = 0,
|
|
||||||
VolumeSequenceNumber = record.volume_sequence_number,
|
|
||||||
Filename = entry.Filename,
|
|
||||||
Timestamp = DecodeIsoDateTime(record.date),
|
|
||||||
XattrLength = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
if(hasResourceFork) entries[entry.Filename].ResourceFork = entry;
|
// Can appear after an associated file
|
||||||
else entries[entry.Filename].AssociatedFile = entry;
|
if(entries[entry.Filename].Extents is null)
|
||||||
}
|
{
|
||||||
}
|
entries[entry.Filename].Extents = new List<(uint extent, uint size)>();
|
||||||
else
|
entries[entry.Filename].Flags = entry.Flags;
|
||||||
{
|
entries[entry.Filename].FileUnitSize = entry.FileUnitSize;
|
||||||
if(entries.ContainsKey(entry.Filename))
|
entries[entry.Filename].Interleave = entry.Interleave;
|
||||||
{
|
entries[entry.Filename].VolumeSequenceNumber = entry.VolumeSequenceNumber;
|
||||||
entries[entry.Filename].Size += entry.Size;
|
entries[entry.Filename].Filename = entry.Filename;
|
||||||
|
entries[entry.Filename].Timestamp = entry.Timestamp;
|
||||||
|
entries[entry.Filename].XattrLength = entry.XattrLength;
|
||||||
|
}
|
||||||
|
|
||||||
// Can appear after an associated file
|
entries[entry.Filename].Extents.Add(entry.Extents[0]);
|
||||||
if(entries[entry.Filename].Extents is null)
|
|
||||||
{
|
|
||||||
entries[entry.Filename].Extents = new List<(uint extent, uint size)>();
|
|
||||||
entries[entry.Filename].Flags = entry.Flags;
|
|
||||||
entries[entry.Filename].FileUnitSize = entry.FileUnitSize;
|
|
||||||
entries[entry.Filename].Interleave = entry.Interleave;
|
|
||||||
entries[entry.Filename].VolumeSequenceNumber = entry.VolumeSequenceNumber;
|
|
||||||
entries[entry.Filename].Filename = entry.Filename;
|
|
||||||
entries[entry.Filename].Timestamp = entry.Timestamp;
|
|
||||||
entries[entry.Filename].XattrLength = entry.XattrLength;
|
|
||||||
}
|
}
|
||||||
|
else entries[entry.Filename] = entry;
|
||||||
entries[entry.Filename].Extents.Add(entry.Extents[0]);
|
|
||||||
}
|
}
|
||||||
else entries[entry.Filename] = entry;
|
|
||||||
|
entryOff += record.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
entryOff += record.length;
|
entryOff = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(useTransTbl) DecodeTransTable(entries);
|
if(useTransTbl) DecodeTransTable(entries);
|
||||||
|
|||||||
@@ -348,10 +348,10 @@ namespace DiscImageChef.Filesystems.ISO9660
|
|||||||
|
|
||||||
if(this.@namespace != Namespace.Joliet)
|
if(this.@namespace != Namespace.Joliet)
|
||||||
rootDirectoryCache = cdi
|
rootDirectoryCache = cdi
|
||||||
? DecodeCdiDirectory(rootDir, rootXattrLength)
|
? DecodeCdiDirectory(rootLocation, rootSize, rootXattrLength)
|
||||||
: highSierra
|
: highSierra
|
||||||
? DecodeHighSierraDirectory(rootDir, rootXattrLength)
|
? DecodeHighSierraDirectory(rootLocation, rootSize, rootXattrLength)
|
||||||
: DecodeIsoDirectory(rootDir, rootXattrLength);
|
: DecodeIsoDirectory(rootLocation, rootSize, rootXattrLength);
|
||||||
|
|
||||||
XmlFsType.Type = fsFormat;
|
XmlFsType.Type = fsFormat;
|
||||||
|
|
||||||
@@ -500,9 +500,7 @@ namespace DiscImageChef.Filesystems.ISO9660
|
|||||||
|
|
||||||
joliet = true;
|
joliet = true;
|
||||||
|
|
||||||
rootDir = ReadSectors(rootLocation, rootSize);
|
rootDirectoryCache = DecodeIsoDirectory(rootLocation, rootSize, rootXattrLength);
|
||||||
|
|
||||||
rootDirectoryCache = DecodeIsoDirectory(rootDir, rootXattrLength);
|
|
||||||
|
|
||||||
XmlFsType.VolumeName = decodedJolietVd.VolumeIdentifier;
|
XmlFsType.VolumeName = decodedJolietVd.VolumeIdentifier;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user