diff --git a/.idea/.idea.DiscImageChef/.idea/contentModel.xml b/.idea/.idea.DiscImageChef/.idea/contentModel.xml
index 3b6db496f..65dba0460 100644
--- a/.idea/.idea.DiscImageChef/.idea/contentModel.xml
+++ b/.idea/.idea.DiscImageChef/.idea/contentModel.xml
@@ -1311,6 +1311,7 @@
+
diff --git a/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj b/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj
index f1bc91d6a..6cc354ec2 100644
--- a/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj
+++ b/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj
@@ -75,6 +75,7 @@
+
diff --git a/DiscImageChef.Filesystems/ISO9660/Consts/Internal.cs b/DiscImageChef.Filesystems/ISO9660/Consts/Internal.cs
index 41b41f5b4..359b2314d 100644
--- a/DiscImageChef.Filesystems/ISO9660/Consts/Internal.cs
+++ b/DiscImageChef.Filesystems/ISO9660/Consts/Internal.cs
@@ -36,7 +36,8 @@ namespace DiscImageChef.Filesystems.ISO9660
{
public partial class ISO9660
{
- static readonly int DirectoryRecordSize = Marshal.SizeOf();
+ const byte MODE2_FORM2 = 0x20;
+ static readonly int DirectoryRecordSize = Marshal.SizeOf();
enum Namespace
{
diff --git a/DiscImageChef.Filesystems/ISO9660/Dir.cs b/DiscImageChef.Filesystems/ISO9660/Dir.cs
index d6e9e1336..7711bce2c 100644
--- a/DiscImageChef.Filesystems/ISO9660/Dir.cs
+++ b/DiscImageChef.Filesystems/ISO9660/Dir.cs
@@ -67,7 +67,7 @@ namespace DiscImageChef.Filesystems.ISO9660
uint dirSizeInSectors = entry.Value.Size / 2048;
if(entry.Value.Size % 2048 > 0) dirSizeInSectors++;
- byte[] directoryBuffer = image.ReadSectors(currentExtent, dirSizeInSectors);
+ byte[] directoryBuffer = ReadSectors(currentExtent, dirSizeInSectors);
// TODO: Decode Joliet
currentDirectory = cdi
@@ -349,7 +349,7 @@ namespace DiscImageChef.Filesystems.ISO9660
uint transTblSectors = transTblEntry.Value.Size / 2048;
if(transTblEntry.Value.Size % 2048 > 0) transTblSectors++;
- byte[] transTbl = image.ReadSectors(transTblEntry.Value.Extent, transTblSectors);
+ byte[] transTbl = ReadSectors(transTblEntry.Value.Extent, transTblSectors);
MemoryStream mr = new MemoryStream(transTbl, 0, (int)transTblEntry.Value.Size, false);
StreamReader sr = new StreamReader(mr, Encoding);
@@ -719,7 +719,7 @@ namespace DiscImageChef.Filesystems.ISO9660
Marshal.ByteArrayToStructureLittleEndian(data, systemAreaOff,
Marshal.SizeOf());
- byte[] childSector = image.ReadSector(cl.child_dir_lba);
+ byte[] childSector = ReadSectors(cl.child_dir_lba, 1);
DirectoryRecord childRecord =
Marshal.ByteArrayToStructureLittleEndian(childSector);
@@ -829,7 +829,7 @@ namespace DiscImageChef.Filesystems.ISO9660
uint caLenInSectors = ca.ca_length / 2048;
if((ca.ca_length + caOff) % 2048 > 0) caLenInSectors++;
- byte[] caData = image.ReadSectors(ca.block + caOffSector, caLenInSectors);
+ byte[] caData = ReadSectors(ca.block + caOffSector, caLenInSectors);
DecodeSystemArea(caData, (int)caOff, (int)(caOff + ca.ca_length), ref entry,
out hasResourceFork);
@@ -922,7 +922,7 @@ namespace DiscImageChef.Filesystems.ISO9660
List entries = new List();
foreach(PathTableEntryInternal tEntry in tableEntries)
{
- byte[] sector = image.ReadSector(tEntry.Extent);
+ byte[] sector = ReadSectors(tEntry.Extent, 1);
CdiDirectoryRecord record =
Marshal.ByteArrayToStructureBigEndian(sector, tEntry.XattrLength,
Marshal.SizeOf());
@@ -962,7 +962,7 @@ namespace DiscImageChef.Filesystems.ISO9660
List entries = new List();
foreach(PathTableEntryInternal tEntry in tableEntries)
{
- byte[] sector = image.ReadSector(tEntry.Extent);
+ byte[] sector = ReadSectors(tEntry.Extent, 1);
DirectoryRecord record =
Marshal.ByteArrayToStructureLittleEndian(sector, tEntry.XattrLength,
Marshal.SizeOf());
@@ -1006,7 +1006,7 @@ namespace DiscImageChef.Filesystems.ISO9660
List entries = new List();
foreach(PathTableEntryInternal tEntry in tableEntries)
{
- byte[] sector = image.ReadSector(tEntry.Extent);
+ byte[] sector = ReadSectors(tEntry.Extent, 1);
HighSierraDirectoryRecord record =
Marshal.ByteArrayToStructureLittleEndian(sector, tEntry.XattrLength,
Marshal
diff --git a/DiscImageChef.Filesystems/ISO9660/File.cs b/DiscImageChef.Filesystems/ISO9660/File.cs
index 21b2e9db3..9b154ec9e 100644
--- a/DiscImageChef.Filesystems/ISO9660/File.cs
+++ b/DiscImageChef.Filesystems/ISO9660/File.cs
@@ -71,7 +71,7 @@ namespace DiscImageChef.Filesystems.ISO9660
MemoryStream ms = new MemoryStream();
- byte[] buffer = image.ReadSectors((ulong)(entry.Extent + firstSector), (uint)sizeInSectors);
+ byte[] buffer = ReadSectors((ulong)(entry.Extent + firstSector), (uint)sizeInSectors);
buf = new byte[size];
Array.Copy(buffer, offsetInSector, buf, 0, size);
@@ -206,7 +206,7 @@ namespace DiscImageChef.Filesystems.ISO9660
uint eaSizeInSectors = (uint)(entry.XattrLength / 2048);
if(entry.XattrLength % 2048 > 0) eaSizeInSectors++;
- byte[] ea = image.ReadSectors(entry.Extent, eaSizeInSectors);
+ byte[] ea = ReadSectors(entry.Extent, eaSizeInSectors);
ExtendedAttributeRecord ear = Marshal.ByteArrayToStructureLittleEndian(ea);
diff --git a/DiscImageChef.Filesystems/ISO9660/Mode2.cs b/DiscImageChef.Filesystems/ISO9660/Mode2.cs
new file mode 100644
index 000000000..a68999715
--- /dev/null
+++ b/DiscImageChef.Filesystems/ISO9660/Mode2.cs
@@ -0,0 +1,81 @@
+using System.IO;
+
+namespace DiscImageChef.Filesystems.ISO9660
+{
+ public partial class ISO9660
+ {
+ byte[] ReadSectors(ulong start, uint count)
+ {
+ MemoryStream ms = new MemoryStream();
+
+ for(ulong sector = start; sector < start + count; sector++)
+ {
+ byte[] data = image.ReadSector(sector);
+
+ switch(data.Length)
+ {
+ case 2048:
+ // Mode 1 sector
+ ms.Write(data, 0, 2048);
+ break;
+ case 2352:
+ // Not a data sector
+ if(data[0] != 0 || data[1] != 0xFF || data[2] != 0xFF || data[3] != 0xFF ||
+ data[4] != 0xFF ||
+ data[5] != 0xFF || data[6] != 0xFF || data[7] != 0xFF || data[8] != 0xFF ||
+ data[9] != 0xFF || data[10] != 0xFF || data[11] != 0x00)
+ {
+ ms.Write(data, 0, 2352);
+ break;
+ }
+
+ switch(data[15])
+ {
+ // Mode 0 sector
+ case 0:
+ ms.Write(new byte[2048], 0, 2048);
+ break;
+ // Mode 1 sector
+ case 1:
+ ms.Write(data, 16, 2048);
+ break;
+ case 2:
+ // Mode 2 form 1 sector
+ if((data[16] & MODE2_FORM2) != 0)
+ {
+ ms.Write(data, 24, 2048);
+ break;
+ }
+
+ // Mode 2 form 2 sector
+ ms.Write(data, 24, 2324);
+ break;
+ // Unknown, audio?
+ default:
+ ms.Write(data, 0, 2352);
+ break;
+ }
+
+ break;
+ case 2336:
+ // Mode 2 form 1 sector
+ if((data[16] & MODE2_FORM2) == 0)
+ {
+ ms.Write(data, 8, 2048);
+ break;
+ }
+
+ // Mode 2 form 2 sector
+ ms.Write(data, 8, 2324);
+ break;
+ // Should not happen, but, just in case
+ default:
+ ms.Write(data, 0, data.Length);
+ break;
+ }
+ }
+
+ return ms.ToArray();
+ }
+ }
+}
\ No newline at end of file
diff --git a/DiscImageChef.Filesystems/ISO9660/Super.cs b/DiscImageChef.Filesystems/ISO9660/Super.cs
index 7ac914fd2..c4c97d81e 100644
--- a/DiscImageChef.Filesystems/ISO9660/Super.cs
+++ b/DiscImageChef.Filesystems/ISO9660/Super.cs
@@ -204,13 +204,14 @@ namespace DiscImageChef.Filesystems.ISO9660
uint pathTableMsbLocation;
uint pathTableLsbLocation;
+ image = imagePlugin;
+
if(highSierra)
{
pathTableSizeInSectors = hsvd.Value.path_table_size / 2048;
if(hsvd.Value.path_table_size % 2048 > 0) pathTableSizeInSectors++;
- pathTableData =
- imagePlugin.ReadSectors(Swapping.Swap(hsvd.Value.mandatory_path_table_msb), pathTableSizeInSectors);
+ pathTableData = ReadSectors(Swapping.Swap(hsvd.Value.mandatory_path_table_msb), pathTableSizeInSectors);
fsFormat = "High Sierra Format";
@@ -222,7 +223,7 @@ namespace DiscImageChef.Filesystems.ISO9660
pathTableSizeInSectors = fsvd.Value.path_table_size / 2048;
if(fsvd.Value.path_table_size % 2048 > 0) pathTableSizeInSectors++;
- pathTableData = imagePlugin.ReadSectors(fsvd.Value.path_table_addr, pathTableSizeInSectors);
+ pathTableData = ReadSectors(fsvd.Value.path_table_addr, pathTableSizeInSectors);
fsFormat = "CD-i";
@@ -239,8 +240,7 @@ namespace DiscImageChef.Filesystems.ISO9660
pathTableSizeInSectors = pvd.Value.path_table_size / 2048;
if(pvd.Value.path_table_size % 2048 > 0) pathTableSizeInSectors++;
- pathTableData =
- imagePlugin.ReadSectors(Swapping.Swap(pvd.Value.type_m_path_table), pathTableSizeInSectors);
+ pathTableData = ReadSectors(Swapping.Swap(pvd.Value.type_m_path_table), pathTableSizeInSectors);
fsFormat = "ISO9660";
@@ -285,7 +285,7 @@ namespace DiscImageChef.Filesystems.ISO9660
{
rootLocation = pathTable[0].Extent;
- byte[] firstRootSector = imagePlugin.ReadSector(rootLocation);
+ byte[] firstRootSector = ReadSectors(rootLocation, 1);
CdiDirectoryRecord rootEntry =
Marshal.ByteArrayToStructureBigEndian(firstRootSector);
rootSize = rootEntry.size / fsvd.Value.logical_block_size;
@@ -297,9 +297,9 @@ namespace DiscImageChef.Filesystems.ISO9660
if(rootLocation + rootSize >= imagePlugin.Info.Sectors) return Errno.InvalidArgument;
- byte[] rootDir = imagePlugin.ReadSectors(rootLocation, rootSize);
+ byte[] rootDir = ReadSectors(rootLocation, rootSize);
- byte[] ipbinSector = imagePlugin.ReadSector(partition.Start);
+ byte[] ipbinSector = ReadSectors(partition.Start, 1);
CD.IPBin? segaCd = CD.DecodeIPBin(ipbinSector);
Saturn.IPBin? saturn = Saturn.DecodeIPBin(ipbinSector);
Dreamcast.IPBin? dreamcast = Dreamcast.DecodeIPBin(ipbinSector);
@@ -446,7 +446,7 @@ namespace DiscImageChef.Filesystems.ISO9660
joliet = true;
- rootDir = imagePlugin.ReadSectors(rootLocation, rootSize);
+ rootDir = ReadSectors(rootLocation, rootSize);
rootDirectoryCache = DecodeIsoDirectory(rootDir, rootXattrLength);
@@ -558,7 +558,6 @@ namespace DiscImageChef.Filesystems.ISO9660
};
directoryCache = new Dictionary>();
- image = imagePlugin;
if(usePathTable)
foreach(DecodedDirectoryEntry subDirectory in cdi
diff --git a/DiscImageChef.Filesystems/ISO9660/Xattr.cs b/DiscImageChef.Filesystems/ISO9660/Xattr.cs
index a20489695..1f33ef5bc 100644
--- a/DiscImageChef.Filesystems/ISO9660/Xattr.cs
+++ b/DiscImageChef.Filesystems/ISO9660/Xattr.cs
@@ -45,7 +45,7 @@ namespace DiscImageChef.Filesystems.ISO9660
uint eaSizeInSectors = (uint)(entry.XattrLength / 2048);
if(entry.XattrLength % 2048 > 0) eaSizeInSectors++;
- byte[] ea = image.ReadSectors(entry.Extent, eaSizeInSectors);
+ byte[] ea = ReadSectors(entry.Extent, eaSizeInSectors);
buf = new byte[entry.AssociatedFile.Size];
Array.Copy(ea, 0, buf, 0, buf.LongLength);
@@ -66,7 +66,7 @@ namespace DiscImageChef.Filesystems.ISO9660
uint associatedFileSize = entry.AssociatedFile.Size / 2048;
if(entry.AssociatedFile.Size % 2048 > 0) associatedFileSize++;
- byte[] associatedFile = image.ReadSectors(entry.AssociatedFile.Extent, associatedFileSize);
+ byte[] associatedFile = ReadSectors(entry.AssociatedFile.Extent, associatedFileSize);
buf = new byte[entry.AssociatedFile.Size];
Array.Copy(associatedFile, 0, buf, 0, buf.LongLength);
@@ -100,7 +100,7 @@ namespace DiscImageChef.Filesystems.ISO9660
uint rsrcSizeInSectors = entry.ResourceFork.Size / 2048;
if(entry.ResourceFork.Size % 2048 > 0) rsrcSizeInSectors++;
- byte[] rsrc = image.ReadSectors(entry.ResourceFork.Extent, rsrcSizeInSectors);
+ byte[] rsrc = ReadSectors(entry.ResourceFork.Extent, rsrcSizeInSectors);
buf = new byte[entry.ResourceFork.Size];
Array.Copy(rsrc, 0, buf, 0, buf.LongLength);