mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Implement support for ISO9660 Level 3, multiple extents in files.
This commit is contained in:
@@ -57,17 +57,34 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
if(!entry.Value.Flags.HasFlag(FileFlags.Directory)) return Errno.NotDirectory;
|
||||
|
||||
currentPath = p == 0 ? pieces[0] : $"{currentPath}/{pieces[p]}";
|
||||
uint currentExtent = entry.Value.Extent;
|
||||
|
||||
if(directoryCache.TryGetValue(currentPath, out currentDirectory)) continue;
|
||||
|
||||
if(currentExtent == 0) return Errno.InvalidArgument;
|
||||
if(entry.Value.Extents.Count == 0) return Errno.InvalidArgument;
|
||||
|
||||
// TODO: XA, High Sierra
|
||||
uint dirSizeInSectors = entry.Value.Size / 2048;
|
||||
if(entry.Value.Size % 2048 > 0) dirSizeInSectors++;
|
||||
byte[] directoryBuffer;
|
||||
if(entry.Value.Extents.Count == 1)
|
||||
{
|
||||
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();
|
||||
|
||||
byte[] directoryBuffer = ReadSectors(currentExtent, dirSizeInSectors);
|
||||
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();
|
||||
}
|
||||
|
||||
// TODO: Decode Joliet
|
||||
currentDirectory = cdi
|
||||
@@ -138,7 +155,6 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
|
||||
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,
|
||||
@@ -146,6 +162,9 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
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;
|
||||
@@ -197,7 +216,6 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
|
||||
DecodedDirectoryEntry entry = new DecodedDirectoryEntry
|
||||
{
|
||||
Extent = record.size == 0 ? 0 : record.extent,
|
||||
Size = record.size,
|
||||
Flags = record.flags,
|
||||
Interleave = record.interleave,
|
||||
@@ -207,6 +225,8 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
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;
|
||||
@@ -246,9 +266,8 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
|
||||
DecodedDirectoryEntry entry = new DecodedDirectoryEntry
|
||||
{
|
||||
Extent = record.size == 0 ? 0 : record.extent,
|
||||
Size = record.size,
|
||||
Flags = record.flags,
|
||||
Size = record.size,
|
||||
Flags = record.flags,
|
||||
Filename =
|
||||
joliet
|
||||
? Encoding.BigEndianUnicode.GetString(data, entryOff + DirectoryRecordSize,
|
||||
@@ -261,6 +280,8 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
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;
|
||||
@@ -294,19 +315,25 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
DecodeSystemArea(data, systemAreaStart, systemAreaStart + systemAreaLength, ref entry,
|
||||
out bool hasResourceFork);
|
||||
|
||||
// TODO: Multi-extent files
|
||||
if(entry.Flags.HasFlag(FileFlags.Associated))
|
||||
{
|
||||
if(entries.ContainsKey(entry.Filename))
|
||||
{
|
||||
if(hasResourceFork) entries[entry.Filename].ResourceFork = entry;
|
||||
else entries[entry.Filename].AssociatedFile = entry;
|
||||
if(hasResourceFork)
|
||||
{
|
||||
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
|
||||
{
|
||||
entries[entry.Filename] = new DecodedDirectoryEntry
|
||||
{
|
||||
Extent = 0,
|
||||
Size = 0,
|
||||
Flags = record.flags ^ FileFlags.Associated,
|
||||
FileUnitSize = 0,
|
||||
@@ -325,11 +352,24 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
{
|
||||
if(entries.ContainsKey(entry.Filename))
|
||||
{
|
||||
entry.AssociatedFile = entries[entry.Filename].AssociatedFile;
|
||||
entry.ResourceFork = entries[entry.Filename].ResourceFork;
|
||||
}
|
||||
entries[entry.Filename].Size += entry.Size;
|
||||
|
||||
entries[entry.Filename] = entry;
|
||||
// Can appear after an associated file
|
||||
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;
|
||||
}
|
||||
|
||||
entries[entry.Filename].Extents.Add(entry.Extents[0]);
|
||||
}
|
||||
else entries[entry.Filename] = entry;
|
||||
}
|
||||
|
||||
entryOff += record.length;
|
||||
@@ -352,10 +392,11 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
|
||||
if(transTblEntry.Value == null) return;
|
||||
|
||||
uint transTblSectors = transTblEntry.Value.Size / 2048;
|
||||
// The probability of a TRANS.TBL to be bigger than 2GiB is nil
|
||||
uint transTblSectors = (uint)transTblEntry.Value.Size / 2048;
|
||||
if(transTblEntry.Value.Size % 2048 > 0) transTblSectors++;
|
||||
|
||||
byte[] transTbl = ReadSectors(transTblEntry.Value.Extent, transTblSectors);
|
||||
byte[] transTbl = ReadSectors(transTblEntry.Value.Extents[0].extent, transTblSectors);
|
||||
|
||||
MemoryStream mr = new MemoryStream(transTbl, 0, (int)transTblEntry.Value.Size, false);
|
||||
StreamReader sr = new StreamReader(mr, Encoding);
|
||||
@@ -731,7 +772,8 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
|
||||
// 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.Extents =
|
||||
new List<(uint extent, uint size)> {(cl.child_dir_lba, childRecord.size)};
|
||||
entry.Size = childRecord.size;
|
||||
entry.Flags = childRecord.flags;
|
||||
entry.FileUnitSize = childRecord.file_unit_size;
|
||||
@@ -937,7 +979,6 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
|
||||
DecodedDirectoryEntry entry = new DecodedDirectoryEntry
|
||||
{
|
||||
Extent = record.size == 0 ? 0 : record.start_lbn,
|
||||
Size = record.size,
|
||||
Filename = tEntry.Name,
|
||||
VolumeSequenceNumber = record.volume_sequence_number,
|
||||
@@ -945,6 +986,9 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
XattrLength = tEntry.XattrLength
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
entry.CdiSystemArea =
|
||||
@@ -977,7 +1021,6 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
|
||||
DecodedDirectoryEntry entry = new DecodedDirectoryEntry
|
||||
{
|
||||
Extent = record.size == 0 ? 0 : record.extent,
|
||||
Size = record.size,
|
||||
Flags = record.flags,
|
||||
Filename = tEntry.Name,
|
||||
@@ -988,6 +1031,8 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
XattrLength = tEntry.XattrLength
|
||||
};
|
||||
|
||||
if(record.size != 0) entry.Extents = new List<(uint extent, uint size)> {(record.extent, record.size)};
|
||||
|
||||
// TODO: XA
|
||||
int systemAreaStart = record.name_len + Marshal.SizeOf<DirectoryRecord>();
|
||||
int systemAreaLength = record.length - record.name_len - Marshal.SizeOf<DirectoryRecord>();
|
||||
@@ -1022,7 +1067,6 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
|
||||
DecodedDirectoryEntry entry = new DecodedDirectoryEntry
|
||||
{
|
||||
Extent = record.size == 0 ? 0 : record.extent,
|
||||
Size = record.size,
|
||||
Flags = record.flags,
|
||||
Filename = tEntry.Name,
|
||||
@@ -1032,6 +1076,8 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
XattrLength = tEntry.XattrLength
|
||||
};
|
||||
|
||||
if(record.size != 0) entry.Extents = new List<(uint extent, uint size)> {(record.extent, record.size)};
|
||||
|
||||
entries.Add(entry);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,10 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
|
||||
if(entry.Flags.HasFlag(FileFlags.Directory) && !debug) return Errno.IsDirectory;
|
||||
|
||||
deviceBlock = entry.Extent + fileBlock;
|
||||
// TODO: Multi-extents
|
||||
if(entry.Extents.Count > 1) return Errno.NotImplemented;
|
||||
|
||||
deviceBlock = entry.Extents[0].extent + fileBlock;
|
||||
|
||||
return Errno.NoError;
|
||||
}
|
||||
@@ -51,15 +54,18 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
|
||||
if(entry.Flags.HasFlag(FileFlags.Directory) && !debug) return Errno.IsDirectory;
|
||||
|
||||
if(entry.Extents is null) return Errno.InvalidArgument;
|
||||
|
||||
if(entry.Size - entry.XattrLength == 0)
|
||||
{
|
||||
buf = new byte[0];
|
||||
return Errno.NoError;
|
||||
}
|
||||
|
||||
if(offset >= entry.Size - entry.XattrLength) return Errno.InvalidArgument;
|
||||
if(offset >= (long)entry.Size - entry.XattrLength) return Errno.InvalidArgument;
|
||||
|
||||
if(size + offset + entry.XattrLength >= entry.Size) size = entry.Size - offset - entry.XattrLength;
|
||||
if(size + offset + entry.XattrLength >= (long)entry.Size)
|
||||
size = (long)entry.Size - offset - entry.XattrLength;
|
||||
|
||||
offset += entry.XattrLength;
|
||||
|
||||
@@ -69,12 +75,18 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
long sizeInSectors = (size + offsetInSector) / 2048;
|
||||
if((size + offsetInSector) % 2048 > 0) sizeInSectors++;
|
||||
|
||||
// No need to check mode, if we know it is CD-DA
|
||||
byte[] buffer = entry.CdiSystemArea?.attributes.HasFlag(CdiAttributes.DigitalAudio) == true
|
||||
? image.ReadSectors((ulong)(entry.Extent + firstSector), (uint)sizeInSectors)
|
||||
: ReadSectors((ulong)(entry.Extent + firstSector), (uint)sizeInSectors);
|
||||
buf = new byte[size];
|
||||
Array.Copy(buffer, offsetInSector, buf, 0, size);
|
||||
if(entry.Extents.Count == 1)
|
||||
{
|
||||
// No need to check mode, if we know it is CD-DA
|
||||
byte[] buffer = entry.CdiSystemArea?.attributes.HasFlag(CdiAttributes.DigitalAudio) == true
|
||||
? image.ReadSectors((ulong)(entry.Extents[0].extent + firstSector),
|
||||
(uint)sizeInSectors)
|
||||
: ReadSectors((ulong)(entry.Extents[0].extent + firstSector), (uint)sizeInSectors);
|
||||
|
||||
buf = new byte[size];
|
||||
Array.Copy(buffer, offsetInSector, buf, 0, size);
|
||||
}
|
||||
else buf = ReadWithExtents(offset, size, entry.Extents);
|
||||
|
||||
return Errno.NoError;
|
||||
}
|
||||
@@ -90,10 +102,10 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
stat = new FileEntryInfo
|
||||
{
|
||||
Attributes = new FileAttributes(),
|
||||
Blocks = entry.Size / 2048, // TODO: XA
|
||||
Blocks = (long)(entry.Size / 2048), // TODO: XA
|
||||
BlockSize = 2048,
|
||||
Length = entry.Size - entry.XattrLength,
|
||||
Inode = entry.Extent,
|
||||
Length = (long)(entry.Size - entry.XattrLength),
|
||||
Inode = entry.Extents?[0].extent ?? 0,
|
||||
Links = 1,
|
||||
LastWriteTimeUtc = entry.Timestamp
|
||||
};
|
||||
@@ -219,7 +231,7 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
uint eaSizeInSectors = (uint)(entry.XattrLength / 2048);
|
||||
if(entry.XattrLength % 2048 > 0) eaSizeInSectors++;
|
||||
|
||||
byte[] ea = ReadSectors(entry.Extent, eaSizeInSectors);
|
||||
byte[] ea = ReadSectors(entry.Extents[0].extent, eaSizeInSectors);
|
||||
|
||||
ExtendedAttributeRecord ear = Marshal.ByteArrayToStructureLittleEndian<ExtendedAttributeRecord>(ea);
|
||||
|
||||
@@ -298,5 +310,54 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
entry = dirent.Value;
|
||||
return Errno.NoError;
|
||||
}
|
||||
|
||||
// Cannot think how to make this faster, as we don't know the mode sector until it is read, but we have size in bytes
|
||||
byte[] ReadWithExtents(long offset, long size, List<(uint extent, uint size)> extents)
|
||||
{
|
||||
MemoryStream ms = new MemoryStream();
|
||||
long currentFilePos = 0;
|
||||
|
||||
for(int i = 0; i < extents.Count; i++)
|
||||
{
|
||||
if(offset - currentFilePos >= extents[i].size)
|
||||
{
|
||||
currentFilePos += extents[i].size;
|
||||
continue;
|
||||
}
|
||||
|
||||
long leftExtentSize = extents[i].size;
|
||||
uint currentExtentSector = 0;
|
||||
|
||||
while(leftExtentSize > 0)
|
||||
{
|
||||
byte[] sector = ReadSectors(extents[i].extent + currentExtentSector, 1);
|
||||
|
||||
if(offset - currentFilePos > sector.Length)
|
||||
{
|
||||
currentExtentSector++;
|
||||
leftExtentSize -= sector.Length;
|
||||
currentFilePos += sector.Length;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(offset - currentFilePos > 0)
|
||||
ms.Write(sector, (int)(offset - currentFilePos),
|
||||
(int)(sector.Length - (offset - currentFilePos)));
|
||||
else ms.Write(sector, 0, sector.Length);
|
||||
|
||||
currentExtentSector++;
|
||||
leftExtentSize -= sector.Length;
|
||||
currentFilePos += sector.Length;
|
||||
|
||||
if(ms.Length >= size) break;
|
||||
}
|
||||
|
||||
if(ms.Length >= size) break;
|
||||
}
|
||||
|
||||
if(ms.Length >= size) ms.SetLength(size);
|
||||
|
||||
return ms.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,7 @@
|
||||
// ****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DiscImageChef.Filesystems.ISO9660
|
||||
{
|
||||
@@ -57,38 +58,38 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
|
||||
class DecodedDirectoryEntry
|
||||
{
|
||||
public byte[] AmigaComment;
|
||||
public AmigaProtection? AmigaProtection;
|
||||
public byte? AppleDosType;
|
||||
public byte[] AppleIcon;
|
||||
public ushort? AppleProDosType;
|
||||
public DecodedDirectoryEntry AssociatedFile;
|
||||
public CdiSystemArea? CdiSystemArea;
|
||||
public uint Extent;
|
||||
public string Filename;
|
||||
public byte FileUnitSize;
|
||||
public FinderInfo FinderInfo;
|
||||
public FileFlags Flags;
|
||||
public byte Interleave;
|
||||
public PosixAttributes? PosixAttributes;
|
||||
public PosixAttributesOld? PosixAttributesOld;
|
||||
public PosixDeviceNumber? PosixDeviceNumber;
|
||||
public DecodedDirectoryEntry ResourceFork;
|
||||
public byte[] RockRidgeAlternateName;
|
||||
public bool RockRidgeRelocated;
|
||||
public byte[] RripAccess;
|
||||
public byte[] RripAttributeChange;
|
||||
public byte[] RripBackup;
|
||||
public byte[] RripCreation;
|
||||
public byte[] RripEffective;
|
||||
public byte[] RripExpiration;
|
||||
public byte[] RripModify;
|
||||
public uint Size;
|
||||
public string SymbolicLink;
|
||||
public DateTime? Timestamp;
|
||||
public ushort VolumeSequenceNumber;
|
||||
public CdromXa? XA;
|
||||
public byte XattrLength;
|
||||
public byte[] AmigaComment;
|
||||
public AmigaProtection? AmigaProtection;
|
||||
public byte? AppleDosType;
|
||||
public byte[] AppleIcon;
|
||||
public ushort? AppleProDosType;
|
||||
public DecodedDirectoryEntry AssociatedFile;
|
||||
public CdiSystemArea? CdiSystemArea;
|
||||
public List<(uint extent, uint size)> Extents;
|
||||
public string Filename;
|
||||
public byte FileUnitSize;
|
||||
public FinderInfo FinderInfo;
|
||||
public FileFlags Flags;
|
||||
public byte Interleave;
|
||||
public PosixAttributes? PosixAttributes;
|
||||
public PosixAttributesOld? PosixAttributesOld;
|
||||
public PosixDeviceNumber? PosixDeviceNumber;
|
||||
public DecodedDirectoryEntry ResourceFork;
|
||||
public byte[] RockRidgeAlternateName;
|
||||
public bool RockRidgeRelocated;
|
||||
public byte[] RripAccess;
|
||||
public byte[] RripAttributeChange;
|
||||
public byte[] RripBackup;
|
||||
public byte[] RripCreation;
|
||||
public byte[] RripEffective;
|
||||
public byte[] RripExpiration;
|
||||
public byte[] RripModify;
|
||||
public ulong Size;
|
||||
public string SymbolicLink;
|
||||
public DateTime? Timestamp;
|
||||
public ushort VolumeSequenceNumber;
|
||||
public CdromXa? XA;
|
||||
public byte XattrLength;
|
||||
|
||||
public override string ToString() => Filename;
|
||||
}
|
||||
|
||||
@@ -327,9 +327,13 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
rootDirectoryCache.Add("$",
|
||||
new DecodedDirectoryEntry
|
||||
{
|
||||
Extent = rootLocation,
|
||||
Extents =
|
||||
new List<(uint extent, uint size)>
|
||||
{
|
||||
(rootLocation, (uint)rootDir.Length)
|
||||
},
|
||||
Filename = "$",
|
||||
Size = 2048,
|
||||
Size = (uint)rootDir.Length,
|
||||
Timestamp = decodedVd.CreationTime
|
||||
});
|
||||
|
||||
@@ -337,7 +341,11 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
rootDirectoryCache.Add("$PATH_TABLE.LSB",
|
||||
new DecodedDirectoryEntry
|
||||
{
|
||||
Extent = pathTableLsbLocation,
|
||||
Extents =
|
||||
new List<(uint extent, uint size)>
|
||||
{
|
||||
(rootLocation, (uint)pathTableData.Length)
|
||||
},
|
||||
Filename = "$PATH_TABLE.LSB",
|
||||
Size = (uint)pathTableData.Length,
|
||||
Timestamp = decodedVd.CreationTime
|
||||
@@ -346,7 +354,11 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
rootDirectoryCache.Add("$PATH_TABLE.MSB",
|
||||
new DecodedDirectoryEntry
|
||||
{
|
||||
Extent = pathTableMsbLocation,
|
||||
Extents =
|
||||
new List<(uint extent, uint size)>
|
||||
{
|
||||
(rootLocation, (uint)pathTableData.Length)
|
||||
},
|
||||
Filename = "$PATH_TABLE.MSB",
|
||||
Size = (uint)pathTableData.Length,
|
||||
Timestamp = decodedVd.CreationTime
|
||||
@@ -356,7 +368,7 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
rootDirectoryCache.Add(i == 0 ? "$BOOT" : $"$BOOT_{i}",
|
||||
new DecodedDirectoryEntry
|
||||
{
|
||||
Extent = (uint)i,
|
||||
Extents = new List<(uint extent, uint size)> {((uint)i, 2048)},
|
||||
Filename = i == 0 ? "$BOOT" : $"$BOOT_{i}",
|
||||
Size = 2048,
|
||||
Timestamp = decodedVd.CreationTime
|
||||
@@ -366,7 +378,7 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
rootDirectoryCache.Add(i == 0 ? "$PVD" : $"$PVD{i}",
|
||||
new DecodedDirectoryEntry
|
||||
{
|
||||
Extent = (uint)i,
|
||||
Extents = new List<(uint extent, uint size)> {((uint)i, 2048)},
|
||||
Filename = i == 0 ? "$PVD" : $"PVD_{i}",
|
||||
Size = 2048,
|
||||
Timestamp = decodedVd.CreationTime
|
||||
@@ -376,7 +388,7 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
rootDirectoryCache.Add(i == 0 ? "$SVD" : $"$SVD_{i}",
|
||||
new DecodedDirectoryEntry
|
||||
{
|
||||
Extent = (uint)i,
|
||||
Extents = new List<(uint extent, uint size)> {((uint)i, 2048)},
|
||||
Filename = i == 0 ? "$SVD" : $"$SVD_{i}",
|
||||
Size = 2048,
|
||||
Timestamp = decodedVd.CreationTime
|
||||
@@ -386,7 +398,7 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
rootDirectoryCache.Add(i == 0 ? "$EVD" : $"$EVD_{i}",
|
||||
new DecodedDirectoryEntry
|
||||
{
|
||||
Extent = (uint)i,
|
||||
Extents = new List<(uint extent, uint size)> {((uint)i, 2048)},
|
||||
Filename = i == 0 ? "$EVD" : $"$EVD_{i}",
|
||||
Size = 2048,
|
||||
Timestamp = decodedVd.CreationTime
|
||||
@@ -396,7 +408,7 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
rootDirectoryCache.Add(i == 0 ? "$VPD" : $"$VPD_{i}",
|
||||
new DecodedDirectoryEntry
|
||||
{
|
||||
Extent = (uint)i,
|
||||
Extents = new List<(uint extent, uint size)> {((uint)i, 2048)},
|
||||
Filename = i == 0 ? "$VPD" : $"$VPD_{i}",
|
||||
Size = 2048,
|
||||
Timestamp = decodedVd.CreationTime
|
||||
@@ -406,7 +418,10 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
rootDirectoryCache.Add("$IP.BIN",
|
||||
new DecodedDirectoryEntry
|
||||
{
|
||||
Extent = 0,
|
||||
Extents = new List<(uint extent, uint size)>
|
||||
{
|
||||
((uint)partition.Start, (uint)Marshal.SizeOf<CD.IPBin>())
|
||||
},
|
||||
Filename = "$IP.BIN",
|
||||
Size = (uint)Marshal.SizeOf<CD.IPBin>(),
|
||||
Timestamp = decodedVd.CreationTime
|
||||
@@ -416,7 +431,10 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
rootDirectoryCache.Add("$IP.BIN",
|
||||
new DecodedDirectoryEntry
|
||||
{
|
||||
Extent = 0,
|
||||
Extents = new List<(uint extent, uint size)>
|
||||
{
|
||||
((uint)partition.Start, (uint)Marshal.SizeOf<Saturn.IPBin>())
|
||||
},
|
||||
Filename = "$IP.BIN",
|
||||
Size = (uint)Marshal.SizeOf<Saturn.IPBin>(),
|
||||
Timestamp = decodedVd.CreationTime
|
||||
@@ -426,7 +444,11 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
rootDirectoryCache.Add("$IP.BIN",
|
||||
new DecodedDirectoryEntry
|
||||
{
|
||||
Extent = 0,
|
||||
Extents = new List<(uint extent, uint size)>
|
||||
{
|
||||
((uint)partition.Start,
|
||||
(uint)Marshal.SizeOf<Dreamcast.IPBin>())
|
||||
},
|
||||
Filename = "$IP.BIN",
|
||||
Size = (uint)Marshal.SizeOf<Dreamcast.IPBin>(),
|
||||
Timestamp = decodedVd.CreationTime
|
||||
|
||||
@@ -41,11 +41,13 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
case "org.iso.9660.ea":
|
||||
if(entry.XattrLength == 0) return Errno.NoSuchExtendedAttribute;
|
||||
|
||||
if(entry.Extents is null) return Errno.InvalidArgument;
|
||||
|
||||
// TODO: XA
|
||||
uint eaSizeInSectors = (uint)(entry.XattrLength / 2048);
|
||||
if(entry.XattrLength % 2048 > 0) eaSizeInSectors++;
|
||||
|
||||
byte[] ea = ReadSectors(entry.Extent, eaSizeInSectors);
|
||||
byte[] ea = ReadSectors(entry.Extents[0].extent, eaSizeInSectors);
|
||||
|
||||
buf = new byte[entry.AssociatedFile.Size];
|
||||
Array.Copy(ea, 0, buf, 0, buf.LongLength);
|
||||
@@ -54,7 +56,7 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
case "org.iso.9660.AssociatedFile":
|
||||
if(entry.AssociatedFile is null) return Errno.NoSuchExtendedAttribute;
|
||||
|
||||
if(entry.AssociatedFile.Extent == 0) return Errno.InvalidArgument;
|
||||
if(entry.AssociatedFile.Extents is null) return Errno.InvalidArgument;
|
||||
|
||||
if(entry.AssociatedFile.Size == 0)
|
||||
{
|
||||
@@ -62,14 +64,16 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
return Errno.NoError;
|
||||
}
|
||||
|
||||
// TODO: XA
|
||||
uint associatedFileSize = entry.AssociatedFile.Size / 2048;
|
||||
if(entry.AssociatedFile.Size % 2048 > 0) associatedFileSize++;
|
||||
if(entry.AssociatedFile.Extents.Count == 1)
|
||||
{
|
||||
uint associatedFileSize = (uint)(entry.AssociatedFile.Size / 2048);
|
||||
if(entry.AssociatedFile.Size % 2048 > 0) associatedFileSize++;
|
||||
byte[] buffer = ReadSectors(entry.AssociatedFile.Extents[0].extent, associatedFileSize);
|
||||
|
||||
byte[] associatedFile = ReadSectors(entry.AssociatedFile.Extent, associatedFileSize);
|
||||
|
||||
buf = new byte[entry.AssociatedFile.Size];
|
||||
Array.Copy(associatedFile, 0, buf, 0, buf.LongLength);
|
||||
buf = new byte[entry.AssociatedFile.Size];
|
||||
Array.Copy(buffer, 0, buf, 0, buf.LongLength);
|
||||
}
|
||||
else buf = ReadWithExtents(0, (long)entry.AssociatedFile.Size, entry.AssociatedFile.Extents);
|
||||
|
||||
return Errno.NoError;
|
||||
case "com.apple.dos.type":
|
||||
@@ -88,7 +92,7 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
case "com.apple.ResourceFork":
|
||||
if(entry.ResourceFork is null) return Errno.NoSuchExtendedAttribute;
|
||||
|
||||
if(entry.ResourceFork.Extent == 0) return Errno.InvalidArgument;
|
||||
if(entry.ResourceFork.Extents is null) return Errno.InvalidArgument;
|
||||
|
||||
if(entry.ResourceFork.Size == 0)
|
||||
{
|
||||
@@ -96,14 +100,16 @@ namespace DiscImageChef.Filesystems.ISO9660
|
||||
return Errno.NoError;
|
||||
}
|
||||
|
||||
// TODO: XA
|
||||
uint rsrcSizeInSectors = entry.ResourceFork.Size / 2048;
|
||||
if(entry.ResourceFork.Size % 2048 > 0) rsrcSizeInSectors++;
|
||||
if(entry.ResourceFork.Extents.Count == 1)
|
||||
{
|
||||
uint rsrcSizeInSectors = (uint)(entry.ResourceFork.Size / 2048);
|
||||
if(entry.AssociatedFile.Size % 2048 > 0) rsrcSizeInSectors++;
|
||||
byte[] buffer = ReadSectors(entry.ResourceFork.Extents[0].extent, rsrcSizeInSectors);
|
||||
|
||||
byte[] rsrc = ReadSectors(entry.ResourceFork.Extent, rsrcSizeInSectors);
|
||||
|
||||
buf = new byte[entry.ResourceFork.Size];
|
||||
Array.Copy(rsrc, 0, buf, 0, buf.LongLength);
|
||||
buf = new byte[entry.ResourceFork.Size];
|
||||
Array.Copy(buffer, 0, buf, 0, buf.LongLength);
|
||||
}
|
||||
else buf = ReadWithExtents(0, (long)entry.ResourceFork.Size, entry.ResourceFork.Extents);
|
||||
|
||||
return Errno.NoError;
|
||||
case "com.apple.FinderInfo":
|
||||
|
||||
Reference in New Issue
Block a user