Support ISO9660 with a block size different from 2048 bytes. Fixes #410

This commit is contained in:
2020-11-06 23:51:08 +00:00
parent ddb93f7401
commit d30a6d18cd
6 changed files with 159 additions and 59 deletions

View File

@@ -124,7 +124,8 @@ namespace Aaru.Filesystems
offset += entry.XattrLength;
if(entry.CdiSystemArea?.attributes.HasFlag(CdiAttributes.DigitalAudio) == true && entry.Extents.Count == 1)
if(entry.CdiSystemArea?.attributes.HasFlag(CdiAttributes.DigitalAudio) == true &&
entry.Extents.Count == 1)
{
try
{
@@ -568,7 +569,7 @@ namespace Aaru.Filesystems
try
{
byte[] fullSector =
_image.ReadSectorTag(extents[i].extent + currentExtentSector,
_image.ReadSectorTag(((extents[i].extent + currentExtentSector) * _blockSize) / 2048,
SectorTagType.CdSectorSubHeader);
ms.Write(fullSector, copy ? 0 : 4, 4);

View File

@@ -58,6 +58,7 @@ namespace Aaru.Filesystems
bool _useEvd;
bool _usePathTable;
bool _useTransTbl;
ushort _blockSize;
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }

View File

@@ -31,6 +31,8 @@
// In the loving memory of Facunda "Tata" Suárez Domínguez, R.I.P. 2019/07/24
// ****************************************************************************/
using System;
using System.IO;
using Aaru.Console;
using Aaru.Decoders.CD;
@@ -40,61 +42,158 @@ namespace Aaru.Filesystems
{
byte[] ReadSector(ulong sector, bool interleaved = false, byte fileNumber = 0)
{
ulong realSector;
uint sectorCount;
sectorCount = (uint)_blockSize / 2048;
if(_blockSize % 2048 > 0)
sectorCount++;
realSector = (sector * _blockSize) / 2048;
ulong offset = (sector * _blockSize) % 2048;
byte[] data;
// TODO: No more exceptions
try
if(sectorCount == 1)
{
data = _image.ReadSectorLong(sector);
// TODO: No more exceptions
try
{
data = _image.ReadSectorLong(realSector);
}
catch
{
data = _image.ReadSector(realSector);
}
if(_debug)
{
switch(data.Length)
{
case 2048:
AaruConsole.DebugWriteLine("ISO9660 Plugin", "Sector {0}, Cooked, Mode 0/1 / Mode 2 Form 1",
realSector);
break;
case 2324:
AaruConsole.DebugWriteLine("ISO9660 Plugin", "Sector {0}, Cooked, Mode 2 Form 2",
realSector);
break;
case 2336:
AaruConsole.DebugWriteLine("ISO9660 Plugin",
"Sector {0}, Cooked, Mode 2 Form {1}, File Number {2}, Channel Number {3}, Submode {4}, Coding Information {5}",
realSector,
((Mode2Submode)data[2]).HasFlag(Mode2Submode.Form2) ? 2 : 1,
data[0], data[1], (Mode2Submode)data[2], data[3]);
break;
case 2352 when data[0] != 0x00 || 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:
AaruConsole.DebugWriteLine("ISO9660 Plugin", "Sector {0}, Raw, Audio", realSector);
break;
case 2352 when data[15] != 2:
AaruConsole.DebugWriteLine("ISO9660 Plugin",
"Sector {0} ({1:X2}:{2:X2}:{3:X2}), Raw, Mode {4}", realSector,
data[12], data[13], data[14], data[15]);
break;
case 2352:
AaruConsole.DebugWriteLine("ISO9660 Plugin",
"Sector {0} ({1:X2}:{2:X2}:{3:X2}), Raw, Mode 2 Form {4}, File Number {5}, Channel Number {6}, Submode {7}, Coding Information {8}",
realSector, data[12], data[13], data[14],
((Mode2Submode)data[18]).HasFlag(Mode2Submode.Form2) ? 2 : 1,
data[16], data[17], (Mode2Submode)data[18], data[19]);
break;
}
}
if(_blockSize == 2048)
return Sector.GetUserData(data, interleaved, fileNumber);
byte[] tmp = new byte[_blockSize];
Array.Copy(Sector.GetUserData(data, interleaved, fileNumber), (int)offset, tmp, 0, _blockSize);
return tmp;
}
catch
else
{
data = _image.ReadSector(sector);
var ms = new MemoryStream();
for(uint i = 0; i < sectorCount; i++)
{
ulong dstSector = realSector + 1;
// TODO: No more exceptions
try
{
data = _image.ReadSectorLong(dstSector);
}
catch
{
data = _image.ReadSector(dstSector);
}
if(_debug)
{
switch(data.Length)
{
case 2048:
AaruConsole.DebugWriteLine("ISO9660 Plugin",
"Sector {0}, Cooked, Mode 0/1 / Mode 2 Form 1", dstSector);
break;
case 2324:
AaruConsole.DebugWriteLine("ISO9660 Plugin", "Sector {0}, Cooked, Mode 2 Form 2",
dstSector);
break;
case 2336:
AaruConsole.DebugWriteLine("ISO9660 Plugin",
"Sector {0}, Cooked, Mode 2 Form {1}, File Number {2}, Channel Number {3}, Submode {4}, Coding Information {5}",
dstSector,
((Mode2Submode)data[2]).HasFlag(Mode2Submode.Form2) ? 2 : 1,
data[0], data[1], (Mode2Submode)data[2], data[3]);
break;
case 2352 when data[0] != 0x00 || 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:
AaruConsole.DebugWriteLine("ISO9660 Plugin", "Sector {0}, Raw, Audio", dstSector);
break;
case 2352 when data[15] != 2:
AaruConsole.DebugWriteLine("ISO9660 Plugin",
"Sector {0} ({1:X2}:{2:X2}:{3:X2}), Raw, Mode {4}",
dstSector, data[12], data[13], data[14], data[15]);
break;
case 2352:
AaruConsole.DebugWriteLine("ISO9660 Plugin",
"Sector {0} ({1:X2}:{2:X2}:{3:X2}), Raw, Mode 2 Form {4}, File Number {5}, Channel Number {6}, Submode {7}, Coding Information {8}",
dstSector, data[12], data[13], data[14],
((Mode2Submode)data[18]).HasFlag(Mode2Submode.Form2) ? 2 : 1,
data[16], data[17], (Mode2Submode)data[18], data[19]);
break;
}
}
byte[] sectorData = Sector.GetUserData(data, interleaved, fileNumber);
ms.Write(sectorData, 0, sectorData.Length);
}
byte[] tmp = new byte[_blockSize];
Array.Copy(Sector.GetUserData(ms.ToArray(), interleaved, fileNumber), 0, tmp, 0, _blockSize);
return tmp;
}
if(!_debug)
return Sector.GetUserData(data, interleaved, fileNumber);
switch(data.Length)
{
case 2048:
AaruConsole.DebugWriteLine("ISO9660 Plugin", "Sector {0}, Cooked, Mode 0/1 / Mode 2 Form 1",
sector);
break;
case 2324:
AaruConsole.DebugWriteLine("ISO9660 Plugin", "Sector {0}, Cooked, Mode 2 Form 2", sector);
break;
case 2336:
AaruConsole.DebugWriteLine("ISO9660 Plugin",
"Sector {0}, Cooked, Mode 2 Form {1}, File Number {2}, Channel Number {3}, Submode {4}, Coding Information {5}",
sector, ((Mode2Submode)data[2]).HasFlag(Mode2Submode.Form2) ? 2 : 1,
data[0], data[1], (Mode2Submode)data[2], data[3]);
break;
case 2352 when data[0] != 0x00 || 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:
AaruConsole.DebugWriteLine("ISO9660 Plugin", "Sector {0}, Raw, Audio", sector);
break;
case 2352 when data[15] != 2:
AaruConsole.DebugWriteLine("ISO9660 Plugin", "Sector {0} ({1:X2}:{2:X2}:{3:X2}), Raw, Mode {4}",
sector, data[12], data[13], data[14], data[15]);
break;
case 2352:
AaruConsole.DebugWriteLine("ISO9660 Plugin",
"Sector {0} ({1:X2}:{2:X2}:{3:X2}), Raw, Mode 2 Form {4}, File Number {5}, Channel Number {6}, Submode {7}, Coding Information {8}",
sector, data[12], data[13], data[14],
((Mode2Submode)data[18]).HasFlag(Mode2Submode.Form2) ? 2 : 1, data[16],
data[17], (Mode2Submode)data[18], data[19]);
break;
}
return Sector.GetUserData(data, interleaved, fileNumber);
}
}
}

View File

@@ -278,6 +278,8 @@ namespace Aaru.Filesystems
if(_highSierra)
{
_blockSize = hsvd.Value.logical_block_size;
pathTableData = ReadSingleExtent(0, hsvd.Value.path_table_size,
Swapping.Swap(hsvd.Value.mandatory_path_table_msb));
@@ -288,6 +290,8 @@ namespace Aaru.Filesystems
}
else if(_cdi)
{
_blockSize = fsvd.Value.logical_block_size;
pathTableData = ReadSingleExtent(0, fsvd.Value.path_table_size, fsvd.Value.path_table_addr);
fsFormat = "CD-i";
@@ -299,6 +303,8 @@ namespace Aaru.Filesystems
}
else
{
_blockSize = pvd.Value.logical_block_size;
pathTableData =
ReadSingleExtent(0, pvd.Value.path_table_size, Swapping.Swap(pvd.Value.type_m_path_table));

View File

@@ -83,7 +83,7 @@ namespace Aaru.Filesystems
entry.Extents.Count == 0)
return Errno.NoError;
byte[] sector = _image.ReadSectorLong(entry.Extents[0].extent);
byte[] sector = _image.ReadSectorLong((entry.Extents[0].extent * _blockSize) / 2048);
if(sector[15] != 2)
return Errno.NoError;