Fixed adding debug root directory entries in ISO9660. Fixes #267

This commit is contained in:
2020-01-07 06:39:55 +00:00
parent 75857860f2
commit 7c5b4418b5

View File

@@ -53,33 +53,46 @@ namespace DiscImageChef.Filesystems.ISO9660
byte[] vdMagic = new byte[5]; // Volume Descriptor magic "CD001" byte[] vdMagic = new byte[5]; // Volume Descriptor magic "CD001"
byte[] hsMagic = new byte[5]; // Volume Descriptor magic "CDROM" byte[] hsMagic = new byte[5]; // Volume Descriptor magic "CDROM"
if(options == null) options = GetDefaultOptions(); if(options == null)
if(options.TryGetValue("debug", out string debugString)) bool.TryParse(debugString, out debug); options = GetDefaultOptions();
if(options.TryGetValue("debug", out string debugString))
bool.TryParse(debugString, out debug);
if(options.TryGetValue("use_path_table", out string usePathTableString)) if(options.TryGetValue("use_path_table", out string usePathTableString))
bool.TryParse(usePathTableString, out usePathTable); bool.TryParse(usePathTableString, out usePathTable);
if(options.TryGetValue("use_trans_tbl", out string useTransTblString)) if(options.TryGetValue("use_trans_tbl", out string useTransTblString))
bool.TryParse(useTransTblString, out useTransTbl); bool.TryParse(useTransTblString, out useTransTbl);
if(options.TryGetValue("use_evd", out string useEvdString)) bool.TryParse(useEvdString, out useEvd);
if(options.TryGetValue("use_evd", out string useEvdString))
bool.TryParse(useEvdString, out useEvd);
// Default namespace // Default namespace
if(@namespace is null) @namespace = "joliet"; if(@namespace is null)
@namespace = "joliet";
switch(@namespace.ToLowerInvariant()) switch(@namespace.ToLowerInvariant())
{ {
case"normal": case"normal":
this.@namespace = Namespace.Normal; this.@namespace = Namespace.Normal;
break; break;
case"vms": case"vms":
this.@namespace = Namespace.Vms; this.@namespace = Namespace.Vms;
break; break;
case"joliet": case"joliet":
this.@namespace = Namespace.Joliet; this.@namespace = Namespace.Joliet;
break; break;
case"rrip": case"rrip":
this.@namespace = Namespace.Rrip; this.@namespace = Namespace.Rrip;
break; break;
case"romeo": case"romeo":
this.@namespace = Namespace.Romeo; this.@namespace = Namespace.Romeo;
break; break;
default: return Errno.InvalidArgument; default: return Errno.InvalidArgument;
} }
@@ -91,10 +104,12 @@ namespace DiscImageChef.Filesystems.ISO9660
FileStructureVolumeDescriptor? fsvd = null; FileStructureVolumeDescriptor? fsvd = null;
// ISO9660 is designed for 2048 bytes/sector devices // ISO9660 is designed for 2048 bytes/sector devices
if(imagePlugin.Info.SectorSize < 2048) return Errno.InvalidArgument; if(imagePlugin.Info.SectorSize < 2048)
return Errno.InvalidArgument;
// ISO9660 Primary Volume Descriptor starts at sector 16, so that's minimal size. // ISO9660 Primary Volume Descriptor starts at sector 16, so that's minimal size.
if(partition.End < 16) return Errno.InvalidArgument; if(partition.End < 16)
return Errno.InvalidArgument;
ulong counter = 0; ulong counter = 0;
@@ -103,7 +118,10 @@ namespace DiscImageChef.Filesystems.ISO9660
Array.Copy(vdSector, 0x009 + xaOff, hsMagic, 0, 5); Array.Copy(vdSector, 0x009 + xaOff, hsMagic, 0, 5);
highSierra = Encoding.GetString(hsMagic) == HIGH_SIERRA_MAGIC; highSierra = Encoding.GetString(hsMagic) == HIGH_SIERRA_MAGIC;
int hsOff = 0; int hsOff = 0;
if(highSierra) hsOff = 8;
if(highSierra)
hsOff = 8;
cdi = false; cdi = false;
List<ulong> bvdSectors = new List<ulong>(); List<ulong> bvdSectors = new List<ulong>();
List<ulong> pvdSectors = new List<ulong>(); List<ulong> pvdSectors = new List<ulong>();
@@ -114,6 +132,7 @@ namespace DiscImageChef.Filesystems.ISO9660
while(true) while(true)
{ {
DicConsole.DebugWriteLine("ISO9660 plugin", "Processing VD loop no. {0}", counter); DicConsole.DebugWriteLine("ISO9660 plugin", "Processing VD loop no. {0}", counter);
// Seek to Volume Descriptor // Seek to Volume Descriptor
DicConsole.DebugWriteLine("ISO9660 plugin", "Reading sector {0}", 16 + counter + partition.Start); DicConsole.DebugWriteLine("ISO9660 plugin", "Reading sector {0}", 16 + counter + partition.Start);
byte[] vdSectorTmp = imagePlugin.ReadSector(16 + counter + partition.Start); byte[] vdSectorTmp = imagePlugin.ReadSector(16 + counter + partition.Start);
@@ -125,7 +144,8 @@ namespace DiscImageChef.Filesystems.ISO9660
if(vdType == 255) // Supposedly we are in the PVD. if(vdType == 255) // Supposedly we are in the PVD.
{ {
if(counter == 0) return Errno.InvalidArgument; if(counter == 0)
return Errno.InvalidArgument;
break; break;
} }
@@ -133,11 +153,13 @@ namespace DiscImageChef.Filesystems.ISO9660
Array.Copy(vdSector, 0x001, vdMagic, 0, 5); Array.Copy(vdSector, 0x001, vdMagic, 0, 5);
Array.Copy(vdSector, 0x009, hsMagic, 0, 5); Array.Copy(vdSector, 0x009, hsMagic, 0, 5);
if(Encoding.GetString(vdMagic) != ISO_MAGIC && Encoding.GetString(hsMagic) != HIGH_SIERRA_MAGIC && if(Encoding.GetString(vdMagic) != ISO_MAGIC &&
Encoding.GetString(hsMagic) != HIGH_SIERRA_MAGIC &&
Encoding.GetString(vdMagic) != CDI_MAGIC Encoding.GetString(vdMagic) != CDI_MAGIC
) // Recognized, it is an ISO9660, now check for rest of data. ) // Recognized, it is an ISO9660, now check for rest of data.
{ {
if(counter == 0) return Errno.InvalidArgument; if(counter == 0)
return Errno.InvalidArgument;
break; break;
} }
@@ -148,7 +170,8 @@ namespace DiscImageChef.Filesystems.ISO9660
{ {
case 0: case 0:
{ {
if(debug) bvdSectors.Add(16 + counter + partition.Start); if(debug)
bvdSectors.Add(16 + counter + partition.Start);
break; break;
} }
@@ -156,13 +179,15 @@ namespace DiscImageChef.Filesystems.ISO9660
case 1: case 1:
{ {
if(highSierra) if(highSierra)
hsvd = Marshal hsvd = Marshal.
.ByteArrayToStructureLittleEndian<HighSierraPrimaryVolumeDescriptor>(vdSector); ByteArrayToStructureLittleEndian<HighSierraPrimaryVolumeDescriptor>(vdSector);
else if(cdi) else if(cdi)
fsvd = Marshal.ByteArrayToStructureBigEndian<FileStructureVolumeDescriptor>(vdSector); fsvd = Marshal.ByteArrayToStructureBigEndian<FileStructureVolumeDescriptor>(vdSector);
else pvd = Marshal.ByteArrayToStructureLittleEndian<PrimaryVolumeDescriptor>(vdSector); else
pvd = Marshal.ByteArrayToStructureLittleEndian<PrimaryVolumeDescriptor>(vdSector);
if(debug) pvdSectors.Add(16 + counter + partition.Start); if(debug)
pvdSectors.Add(16 + counter + partition.Start);
break; break;
} }
@@ -176,17 +201,23 @@ namespace DiscImageChef.Filesystems.ISO9660
// Check if this is Joliet // Check if this is Joliet
if(svd.version == 1) if(svd.version == 1)
{ {
if(svd.escape_sequences[0] == '%' && svd.escape_sequences[1] == '/') if(svd.escape_sequences[0] == '%' &&
if(svd.escape_sequences[2] == '@' || svd.escape_sequences[2] == 'C' || svd.escape_sequences[1] == '/')
svd.escape_sequences[2] == 'E') jolietvd = svd; if(svd.escape_sequences[2] == '@' ||
svd.escape_sequences[2] == 'C' ||
svd.escape_sequences[2] == 'E')
jolietvd = svd;
else else
DicConsole.WriteLine("ISO9660 plugin", DicConsole.WriteLine("ISO9660 plugin",
"Found unknown supplementary volume descriptor"); "Found unknown supplementary volume descriptor");
if(debug) svdSectors.Add(16 + counter + partition.Start);
if(debug)
svdSectors.Add(16 + counter + partition.Start);
} }
else else
{ {
if(debug) evdSectors.Add(16 + counter + partition.Start); if(debug)
evdSectors.Add(16 + counter + partition.Start);
if(useEvd) if(useEvd)
{ {
@@ -202,7 +233,8 @@ namespace DiscImageChef.Filesystems.ISO9660
case 3: case 3:
{ {
if(debug) vpdSectors.Add(16 + counter + partition.Start); if(debug)
vpdSectors.Add(16 + counter + partition.Start);
break; break;
} }
@@ -212,23 +244,31 @@ namespace DiscImageChef.Filesystems.ISO9660
} }
DecodedVolumeDescriptor decodedVd; DecodedVolumeDescriptor decodedVd;
DecodedVolumeDescriptor decodedJolietVd = new DecodedVolumeDescriptor(); var decodedJolietVd = new DecodedVolumeDescriptor();
XmlFsType = new FileSystemType(); XmlFsType = new FileSystemType();
if(pvd == null && hsvd == null && fsvd == null) if(pvd == null &&
hsvd == null &&
fsvd == null)
{ {
DicConsole.ErrorWriteLine("ERROR: Could not find primary volume descriptor"); DicConsole.ErrorWriteLine("ERROR: Could not find primary volume descriptor");
return Errno.InvalidArgument; return Errno.InvalidArgument;
} }
if(highSierra) decodedVd = DecodeVolumeDescriptor(hsvd.Value); if(highSierra)
else if(cdi) decodedVd = DecodeVolumeDescriptor(fsvd.Value); decodedVd = DecodeVolumeDescriptor(hsvd.Value);
else decodedVd = DecodeVolumeDescriptor(pvd.Value); else if(cdi)
decodedVd = DecodeVolumeDescriptor(fsvd.Value);
else
decodedVd = DecodeVolumeDescriptor(pvd.Value);
if(jolietvd != null) decodedJolietVd = DecodeJolietDescriptor(jolietvd.Value); if(jolietvd != null)
decodedJolietVd = DecodeJolietDescriptor(jolietvd.Value);
if(this.@namespace != Namespace.Romeo) Encoding = Encoding.ASCII; if(this.@namespace != Namespace.Romeo)
Encoding = Encoding.ASCII;
string fsFormat; string fsFormat;
byte[] pathTableData; byte[] pathTableData;
@@ -242,7 +282,9 @@ namespace DiscImageChef.Filesystems.ISO9660
if(highSierra) if(highSierra)
{ {
pathTableSizeInSectors = hsvd.Value.path_table_size / 2048; pathTableSizeInSectors = hsvd.Value.path_table_size / 2048;
if(hsvd.Value.path_table_size % 2048 > 0) pathTableSizeInSectors++;
if(hsvd.Value.path_table_size % 2048 > 0)
pathTableSizeInSectors++;
pathTableData = ReadSectors(Swapping.Swap(hsvd.Value.mandatory_path_table_msb), pathTableSizeInSectors); pathTableData = ReadSectors(Swapping.Swap(hsvd.Value.mandatory_path_table_msb), pathTableSizeInSectors);
@@ -254,7 +296,9 @@ namespace DiscImageChef.Filesystems.ISO9660
else if(cdi) else if(cdi)
{ {
pathTableSizeInSectors = fsvd.Value.path_table_size / 2048; pathTableSizeInSectors = fsvd.Value.path_table_size / 2048;
if(fsvd.Value.path_table_size % 2048 > 0) pathTableSizeInSectors++;
if(fsvd.Value.path_table_size % 2048 > 0)
pathTableSizeInSectors++;
pathTableData = ReadSectors(fsvd.Value.path_table_addr, pathTableSizeInSectors); pathTableData = ReadSectors(fsvd.Value.path_table_addr, pathTableSizeInSectors);
@@ -268,7 +312,9 @@ namespace DiscImageChef.Filesystems.ISO9660
else else
{ {
pathTableSizeInSectors = pvd.Value.path_table_size / 2048; pathTableSizeInSectors = pvd.Value.path_table_size / 2048;
if(pvd.Value.path_table_size % 2048 > 0) pathTableSizeInSectors++;
if(pvd.Value.path_table_size % 2048 > 0)
pathTableSizeInSectors++;
pathTableData = ReadSectors(Swapping.Swap(pvd.Value.type_m_path_table), pathTableSizeInSectors); pathTableData = ReadSectors(Swapping.Swap(pvd.Value.type_m_path_table), pathTableSizeInSectors);
@@ -281,10 +327,14 @@ namespace DiscImageChef.Filesystems.ISO9660
pathTable = highSierra ? DecodeHighSierraPathTable(pathTableData) : DecodePathTable(pathTableData); pathTable = highSierra ? DecodeHighSierraPathTable(pathTableData) : DecodePathTable(pathTableData);
// High Sierra and CD-i do not support Joliet or RRIP // High Sierra and CD-i do not support Joliet or RRIP
if((highSierra || cdi) && this.@namespace != Namespace.Normal && this.@namespace != Namespace.Vms) if((highSierra || cdi) &&
this.@namespace != Namespace.Normal &&
this.@namespace != Namespace.Vms)
this.@namespace = Namespace.Normal; this.@namespace = Namespace.Normal;
if(jolietvd is null && this.@namespace == Namespace.Joliet) this.@namespace = Namespace.Normal; if(jolietvd is null &&
this.@namespace == Namespace.Joliet)
this.@namespace = Namespace.Normal;
uint rootLocation; uint rootLocation;
uint rootSize; uint rootSize;
@@ -292,23 +342,25 @@ namespace DiscImageChef.Filesystems.ISO9660
if(!cdi) if(!cdi)
{ {
rootLocation = highSierra rootLocation = highSierra ? hsvd.Value.root_directory_record.extent
? hsvd.Value.root_directory_record.extent
: pvd.Value.root_directory_record.extent; : pvd.Value.root_directory_record.extent;
rootXattrLength = highSierra rootXattrLength = highSierra ? hsvd.Value.root_directory_record.xattr_len
? hsvd.Value.root_directory_record.xattr_len
: pvd.Value.root_directory_record.xattr_len; : pvd.Value.root_directory_record.xattr_len;
if(highSierra) if(highSierra)
{ {
rootSize = hsvd.Value.root_directory_record.size / hsvd.Value.logical_block_size; rootSize = hsvd.Value.root_directory_record.size / hsvd.Value.logical_block_size;
if(hsvd.Value.root_directory_record.size % hsvd.Value.logical_block_size > 0) rootSize++;
if(hsvd.Value.root_directory_record.size % hsvd.Value.logical_block_size > 0)
rootSize++;
} }
else else
{ {
rootSize = pvd.Value.root_directory_record.size / pvd.Value.logical_block_size; rootSize = pvd.Value.root_directory_record.size / pvd.Value.logical_block_size;
if(pvd.Value.root_directory_record.size % pvd.Value.logical_block_size > 0) rootSize++;
if(pvd.Value.root_directory_record.size % pvd.Value.logical_block_size > 0)
rootSize++;
} }
} }
else else
@@ -316,19 +368,25 @@ namespace DiscImageChef.Filesystems.ISO9660
rootLocation = pathTable[0].Extent; rootLocation = pathTable[0].Extent;
byte[] firstRootSector = ReadSectors(rootLocation, 1); byte[] firstRootSector = ReadSectors(rootLocation, 1);
CdiDirectoryRecord rootEntry = CdiDirectoryRecord rootEntry =
Marshal.ByteArrayToStructureBigEndian<CdiDirectoryRecord>(firstRootSector); Marshal.ByteArrayToStructureBigEndian<CdiDirectoryRecord>(firstRootSector);
rootSize = rootEntry.size / fsvd.Value.logical_block_size; rootSize = rootEntry.size / fsvd.Value.logical_block_size;
if(rootEntry.size % fsvd.Value.logical_block_size > 0) rootSize++;
if(rootEntry.size % fsvd.Value.logical_block_size > 0)
rootSize++;
usePathTable = usePathTable || pathTable.Length == 1; usePathTable = usePathTable || pathTable.Length == 1;
useTransTbl = false; useTransTbl = false;
} }
// In case the path table is incomplete // In case the path table is incomplete
if(usePathTable && pathTableData.Length == 1) usePathTable = false; if(usePathTable && pathTableData.Length == 1)
usePathTable = false;
if(rootLocation + rootSize >= imagePlugin.Info.Sectors) return Errno.InvalidArgument; if(rootLocation + rootSize >= imagePlugin.Info.Sectors)
return Errno.InvalidArgument;
byte[] rootDir = ReadSectors(rootLocation, rootSize); byte[] rootDir = ReadSectors(rootLocation, rootSize);
@@ -337,14 +395,16 @@ namespace DiscImageChef.Filesystems.ISO9660
Saturn.IPBin? saturn = Saturn.DecodeIPBin(ipbinSector); Saturn.IPBin? saturn = Saturn.DecodeIPBin(ipbinSector);
Dreamcast.IPBin? dreamcast = Dreamcast.DecodeIPBin(ipbinSector); Dreamcast.IPBin? dreamcast = Dreamcast.DecodeIPBin(ipbinSector);
if(this.@namespace == Namespace.Joliet || this.@namespace == Namespace.Rrip) if(this.@namespace == Namespace.Joliet ||
this.@namespace == Namespace.Rrip)
{ {
usePathTable = false; usePathTable = false;
useTransTbl = false; useTransTbl = false;
} }
// Cannot traverse path table if we substitute the names for the ones in TRANS.TBL // Cannot traverse path table if we substitute the names for the ones in TRANS.TBL
if(useTransTbl) usePathTable = false; if(useTransTbl)
usePathTable = false;
if(this.@namespace != Namespace.Joliet) if(this.@namespace != Namespace.Joliet)
rootDirectoryCache = cdi rootDirectoryCache = cdi
@@ -355,148 +415,19 @@ namespace DiscImageChef.Filesystems.ISO9660
XmlFsType.Type = fsFormat; XmlFsType.Type = fsFormat;
if(debug) if(jolietvd != null &&
{ (this.@namespace == Namespace.Joliet || this.@namespace == Namespace.Rrip))
rootDirectoryCache.Add("$",
new DecodedDirectoryEntry
{
Extents =
new List<(uint extent, uint size)>
{
(rootLocation, (uint)rootDir.Length)
},
Filename = "$",
Size = (uint)rootDir.Length,
Timestamp = decodedVd.CreationTime
});
if(!cdi)
rootDirectoryCache.Add("$PATH_TABLE.LSB",
new DecodedDirectoryEntry
{
Extents = new List<(uint extent, uint size)>
{
(pathTableLsbLocation, (uint)pathTableData.Length)
},
Filename = "$PATH_TABLE.LSB",
Size = (uint)pathTableData.Length,
Timestamp = decodedVd.CreationTime
});
rootDirectoryCache.Add("$PATH_TABLE.MSB",
new DecodedDirectoryEntry
{
Extents =
new List<(uint extent, uint size)>
{
(pathTableMsbLocation, (uint)pathTableData.Length)
},
Filename = "$PATH_TABLE.MSB",
Size = (uint)pathTableData.Length,
Timestamp = decodedVd.CreationTime
});
for(int i = 0; i < bvdSectors.Count; i++)
rootDirectoryCache.Add(i == 0 ? "$BOOT" : $"$BOOT_{i}",
new DecodedDirectoryEntry
{
Extents = new List<(uint extent, uint size)> {((uint)i, 2048)},
Filename = i == 0 ? "$BOOT" : $"$BOOT_{i}",
Size = 2048,
Timestamp = decodedVd.CreationTime
});
for(int i = 0; i < pvdSectors.Count; i++)
rootDirectoryCache.Add(i == 0 ? "$PVD" : $"$PVD{i}",
new DecodedDirectoryEntry
{
Extents = new List<(uint extent, uint size)> {((uint)i, 2048)},
Filename = i == 0 ? "$PVD" : $"PVD_{i}",
Size = 2048,
Timestamp = decodedVd.CreationTime
});
for(int i = 0; i < svdSectors.Count; i++)
rootDirectoryCache.Add(i == 0 ? "$SVD" : $"$SVD_{i}",
new DecodedDirectoryEntry
{
Extents = new List<(uint extent, uint size)> {((uint)i, 2048)},
Filename = i == 0 ? "$SVD" : $"$SVD_{i}",
Size = 2048,
Timestamp = decodedVd.CreationTime
});
for(int i = 0; i < evdSectors.Count; i++)
rootDirectoryCache.Add(i == 0 ? "$EVD" : $"$EVD_{i}",
new DecodedDirectoryEntry
{
Extents = new List<(uint extent, uint size)> {((uint)i, 2048)},
Filename = i == 0 ? "$EVD" : $"$EVD_{i}",
Size = 2048,
Timestamp = decodedVd.CreationTime
});
for(int i = 0; i < vpdSectors.Count; i++)
rootDirectoryCache.Add(i == 0 ? "$VPD" : $"$VPD_{i}",
new DecodedDirectoryEntry
{
Extents = new List<(uint extent, uint size)> {((uint)i, 2048)},
Filename = i == 0 ? "$VPD" : $"$VPD_{i}",
Size = 2048,
Timestamp = decodedVd.CreationTime
});
if(segaCd != null)
rootDirectoryCache.Add("$IP.BIN",
new DecodedDirectoryEntry
{
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
});
if(saturn != null)
rootDirectoryCache.Add("$IP.BIN",
new DecodedDirectoryEntry
{
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
});
if(dreamcast != null)
rootDirectoryCache.Add("$IP.BIN",
new DecodedDirectoryEntry
{
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
});
}
if(jolietvd != null && (this.@namespace == Namespace.Joliet || this.@namespace == Namespace.Rrip))
{ {
rootLocation = jolietvd.Value.root_directory_record.extent; rootLocation = jolietvd.Value.root_directory_record.extent;
rootXattrLength = jolietvd.Value.root_directory_record.xattr_len; rootXattrLength = jolietvd.Value.root_directory_record.xattr_len;
rootSize = jolietvd.Value.root_directory_record.size / jolietvd.Value.logical_block_size; 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) if(pvd.Value.root_directory_record.size % jolietvd.Value.logical_block_size > 0)
rootSize++; rootSize++;
if(rootLocation + rootSize >= imagePlugin.Info.Sectors) return Errno.InvalidArgument; if(rootLocation + rootSize >= imagePlugin.Info.Sectors)
return Errno.InvalidArgument;
joliet = true; joliet = true;
@@ -508,24 +439,21 @@ namespace DiscImageChef.Filesystems.ISO9660
decodedVd.SystemIdentifier.Length > decodedJolietVd.SystemIdentifier.Length) decodedVd.SystemIdentifier.Length > decodedJolietVd.SystemIdentifier.Length)
XmlFsType.SystemIdentifier = decodedVd.SystemIdentifier; XmlFsType.SystemIdentifier = decodedVd.SystemIdentifier;
else else
XmlFsType.SystemIdentifier = string.IsNullOrEmpty(decodedJolietVd.SystemIdentifier) XmlFsType.SystemIdentifier = string.IsNullOrEmpty(decodedJolietVd.SystemIdentifier) ? null
? null
: decodedJolietVd.SystemIdentifier; : decodedJolietVd.SystemIdentifier;
if(string.IsNullOrEmpty(decodedJolietVd.VolumeSetIdentifier) || decodedVd.VolumeSetIdentifier.Length > if(string.IsNullOrEmpty(decodedJolietVd.VolumeSetIdentifier) ||
decodedJolietVd.VolumeSetIdentifier.Length) decodedVd.VolumeSetIdentifier.Length > decodedJolietVd.VolumeSetIdentifier.Length)
XmlFsType.VolumeSetIdentifier = decodedVd.VolumeSetIdentifier; XmlFsType.VolumeSetIdentifier = decodedVd.VolumeSetIdentifier;
else else
XmlFsType.VolumeSetIdentifier = string.IsNullOrEmpty(decodedJolietVd.VolumeSetIdentifier) XmlFsType.VolumeSetIdentifier = string.IsNullOrEmpty(decodedJolietVd.VolumeSetIdentifier) ? null
? null
: decodedJolietVd.VolumeSetIdentifier; : decodedJolietVd.VolumeSetIdentifier;
if(string.IsNullOrEmpty(decodedJolietVd.PublisherIdentifier) || decodedVd.PublisherIdentifier.Length > if(string.IsNullOrEmpty(decodedJolietVd.PublisherIdentifier) ||
decodedJolietVd.PublisherIdentifier.Length) decodedVd.PublisherIdentifier.Length > decodedJolietVd.PublisherIdentifier.Length)
XmlFsType.PublisherIdentifier = decodedVd.PublisherIdentifier; XmlFsType.PublisherIdentifier = decodedVd.PublisherIdentifier;
else else
XmlFsType.PublisherIdentifier = string.IsNullOrEmpty(decodedJolietVd.PublisherIdentifier) XmlFsType.PublisherIdentifier = string.IsNullOrEmpty(decodedJolietVd.PublisherIdentifier) ? null
? null
: decodedJolietVd.PublisherIdentifier; : decodedJolietVd.PublisherIdentifier;
if(string.IsNullOrEmpty(decodedJolietVd.DataPreparerIdentifier) || if(string.IsNullOrEmpty(decodedJolietVd.DataPreparerIdentifier) ||
@@ -533,19 +461,18 @@ namespace DiscImageChef.Filesystems.ISO9660
XmlFsType.DataPreparerIdentifier = decodedVd.DataPreparerIdentifier; XmlFsType.DataPreparerIdentifier = decodedVd.DataPreparerIdentifier;
else else
XmlFsType.DataPreparerIdentifier = string.IsNullOrEmpty(decodedJolietVd.DataPreparerIdentifier) XmlFsType.DataPreparerIdentifier = string.IsNullOrEmpty(decodedJolietVd.DataPreparerIdentifier)
? null ? null : decodedJolietVd.DataPreparerIdentifier;
: decodedJolietVd.DataPreparerIdentifier;
if(string.IsNullOrEmpty(decodedJolietVd.ApplicationIdentifier) || if(string.IsNullOrEmpty(decodedJolietVd.ApplicationIdentifier) ||
decodedVd.ApplicationIdentifier.Length > decodedJolietVd.ApplicationIdentifier.Length) decodedVd.ApplicationIdentifier.Length > decodedJolietVd.ApplicationIdentifier.Length)
XmlFsType.ApplicationIdentifier = decodedVd.ApplicationIdentifier; XmlFsType.ApplicationIdentifier = decodedVd.ApplicationIdentifier;
else else
XmlFsType.ApplicationIdentifier = string.IsNullOrEmpty(decodedJolietVd.ApplicationIdentifier) XmlFsType.ApplicationIdentifier = string.IsNullOrEmpty(decodedJolietVd.ApplicationIdentifier) ? null
? null
: decodedJolietVd.ApplicationIdentifier; : decodedJolietVd.ApplicationIdentifier;
XmlFsType.CreationDate = decodedJolietVd.CreationTime; XmlFsType.CreationDate = decodedJolietVd.CreationTime;
XmlFsType.CreationDateSpecified = true; XmlFsType.CreationDateSpecified = true;
if(decodedJolietVd.HasModificationTime) if(decodedJolietVd.HasModificationTime)
{ {
XmlFsType.ModificationDate = decodedJolietVd.ModificationTime; XmlFsType.ModificationDate = decodedJolietVd.ModificationTime;
@@ -563,6 +490,8 @@ namespace DiscImageChef.Filesystems.ISO9660
XmlFsType.EffectiveDate = decodedJolietVd.EffectiveTime; XmlFsType.EffectiveDate = decodedJolietVd.EffectiveTime;
XmlFsType.EffectiveDateSpecified = true; XmlFsType.EffectiveDateSpecified = true;
} }
decodedVd = decodedJolietVd;
} }
else else
{ {
@@ -574,6 +503,7 @@ namespace DiscImageChef.Filesystems.ISO9660
XmlFsType.ApplicationIdentifier = decodedVd.ApplicationIdentifier; XmlFsType.ApplicationIdentifier = decodedVd.ApplicationIdentifier;
XmlFsType.CreationDate = decodedVd.CreationTime; XmlFsType.CreationDate = decodedVd.CreationTime;
XmlFsType.CreationDateSpecified = true; XmlFsType.CreationDateSpecified = true;
if(decodedVd.HasModificationTime) if(decodedVd.HasModificationTime)
{ {
XmlFsType.ModificationDate = decodedVd.ModificationTime; XmlFsType.ModificationDate = decodedVd.ModificationTime;
@@ -593,20 +523,132 @@ namespace DiscImageChef.Filesystems.ISO9660
} }
} }
if(debug)
{
rootDirectoryCache.Add("$", new DecodedDirectoryEntry
{
Extents = new List<(uint extent, uint size)>
{
(rootLocation, (uint)rootDir.Length)
},
Filename = "$", Size = (uint)rootDir.Length, Timestamp = decodedVd.CreationTime
});
if(!cdi)
rootDirectoryCache.Add("$PATH_TABLE.LSB", new DecodedDirectoryEntry
{
Extents = new List<(uint extent, uint size)>
{
(pathTableLsbLocation, (uint)pathTableData.Length)
},
Filename = "$PATH_TABLE.LSB", Size = (uint)pathTableData.Length,
Timestamp = decodedVd.CreationTime
});
rootDirectoryCache.Add("$PATH_TABLE.MSB", new DecodedDirectoryEntry
{
Extents = new List<(uint extent, uint size)>
{
(pathTableMsbLocation, (uint)pathTableData.Length)
},
Filename = "$PATH_TABLE.MSB", Size = (uint)pathTableData.Length, Timestamp = decodedVd.CreationTime
});
for(int i = 0; i < bvdSectors.Count; i++)
rootDirectoryCache.Add(i == 0 ? "$BOOT" : $"$BOOT_{i}", new DecodedDirectoryEntry
{
Extents = new List<(uint extent, uint size)>
{
((uint)i, 2048)
},
Filename = i == 0 ? "$BOOT" : $"$BOOT_{i}", Size = 2048, Timestamp = decodedVd.CreationTime
});
for(int i = 0; i < pvdSectors.Count; i++)
rootDirectoryCache.Add(i == 0 ? "$PVD" : $"$PVD{i}", new DecodedDirectoryEntry
{
Extents = new List<(uint extent, uint size)>
{
((uint)i, 2048)
},
Filename = i == 0 ? "$PVD" : $"PVD_{i}", Size = 2048, Timestamp = decodedVd.CreationTime
});
for(int i = 0; i < svdSectors.Count; i++)
rootDirectoryCache.Add(i == 0 ? "$SVD" : $"$SVD_{i}", new DecodedDirectoryEntry
{
Extents = new List<(uint extent, uint size)>
{
((uint)i, 2048)
},
Filename = i == 0 ? "$SVD" : $"$SVD_{i}", Size = 2048, Timestamp = decodedVd.CreationTime
});
for(int i = 0; i < evdSectors.Count; i++)
rootDirectoryCache.Add(i == 0 ? "$EVD" : $"$EVD_{i}", new DecodedDirectoryEntry
{
Extents = new List<(uint extent, uint size)>
{
((uint)i, 2048)
},
Filename = i == 0 ? "$EVD" : $"$EVD_{i}", Size = 2048, Timestamp = decodedVd.CreationTime
});
for(int i = 0; i < vpdSectors.Count; i++)
rootDirectoryCache.Add(i == 0 ? "$VPD" : $"$VPD_{i}", new DecodedDirectoryEntry
{
Extents = new List<(uint extent, uint size)>
{
((uint)i, 2048)
},
Filename = i == 0 ? "$VPD" : $"$VPD_{i}", Size = 2048, Timestamp = decodedVd.CreationTime
});
if(segaCd != null)
rootDirectoryCache.Add("$IP.BIN", new DecodedDirectoryEntry
{
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
});
if(saturn != null)
rootDirectoryCache.Add("$IP.BIN", new DecodedDirectoryEntry
{
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
});
if(dreamcast != null)
rootDirectoryCache.Add("$IP.BIN", new DecodedDirectoryEntry
{
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
});
}
XmlFsType.Bootable |= bvd != null || segaCd != null || saturn != null || dreamcast != null; XmlFsType.Bootable |= bvd != null || segaCd != null || saturn != null || dreamcast != null;
XmlFsType.Clusters = decodedVd.Blocks; XmlFsType.Clusters = decodedVd.Blocks;
XmlFsType.ClusterSize = decodedVd.BlockSize; XmlFsType.ClusterSize = decodedVd.BlockSize;
statfs = new FileSystemInfo statfs = new FileSystemInfo
{ {
Blocks = decodedVd.Blocks, Blocks = decodedVd.Blocks, FilenameLength =
FilenameLength = (ushort)(jolietvd != null (ushort)(jolietvd != null ? this.@namespace == Namespace.Joliet
? this.@namespace == Namespace.Joliet
? 110 ? 110
: 255 : 255 : 255),
: 255), PluginId = Id, Type = fsFormat
PluginId = Id,
Type = fsFormat
}; };
directoryCache = new Dictionary<string, Dictionary<string, DecodedDirectoryEntry>>(); directoryCache = new Dictionary<string, Dictionary<string, DecodedDirectoryEntry>>();
@@ -626,7 +668,8 @@ namespace DiscImageChef.Filesystems.ISO9660
public Errno Unmount() public Errno Unmount()
{ {
if(!mounted) return Errno.AccessDenied; if(!mounted)
return Errno.AccessDenied;
rootDirectoryCache = null; rootDirectoryCache = null;
directoryCache = null; directoryCache = null;
@@ -638,9 +681,12 @@ namespace DiscImageChef.Filesystems.ISO9660
public Errno StatFs(out FileSystemInfo stat) public Errno StatFs(out FileSystemInfo stat)
{ {
stat = null; stat = null;
if(!mounted) return Errno.AccessDenied;
if(!mounted)
return Errno.AccessDenied;
stat = statfs.ShallowCopy(); stat = statfs.ShallowCopy();
return Errno.NoError; return Errno.NoError;
} }
} }