Invert 'if' statements to reduce nesting.

This commit is contained in:
2022-11-13 21:14:18 +00:00
parent c316cef523
commit d64c48dc6d
23 changed files with 955 additions and 949 deletions

View File

@@ -842,16 +842,16 @@ public sealed class Checksum
dataChecksums.Add(chk); dataChecksums.Add(chk);
} }
if(enabled.HasFlag(EnableChecksum.Fletcher32)) if(!enabled.HasFlag(EnableChecksum.Fletcher32))
{ return dataChecksums;
chk = new ChecksumType
{
type = ChecksumTypeType.fletcher32,
Value = f32CtxData.End()
};
dataChecksums.Add(chk); chk = new ChecksumType
} {
type = ChecksumTypeType.fletcher32,
Value = f32CtxData.End()
};
dataChecksums.Add(chk);
return dataChecksums; return dataChecksums;
} }

View File

@@ -179,12 +179,12 @@ public partial class Dump
break; break;
} }
if(tmp.SequenceEqual(_gbaExtension)) if(!tmp.SequenceEqual(_gbaExtension))
{ continue;
gbaFound = true;
break; gbaFound = true;
}
break;
} }
if(!sfcFound && if(!sfcFound &&

View File

@@ -128,62 +128,62 @@ partial class Dump
bool tmpSense = dvdDecrypt.ReadTitleKey(out tmpBuf, out _, DvdCssKeyClass.DvdCssCppmOrCprm, bool tmpSense = dvdDecrypt.ReadTitleKey(out tmpBuf, out _, DvdCssKeyClass.DvdCssCppmOrCprm,
i + j, _dev.Timeout, out _); i + j, _dev.Timeout, out _);
if(!tmpSense) if(tmpSense)
continue;
CSS_CPRM.TitleKey? titleKey = CSS.DecodeTitleKey(tmpBuf, dvdDecrypt.BusKey);
if(titleKey.HasValue)
outputFormat.WriteSectorTag(new[]
{
titleKey.Value.CMI
}, i + j, SectorTagType.DvdCmi);
else
continue;
// If the CMI bit is 1, the sector is using copy protection, else it is not
if((titleKey.Value.CMI & 0x80) >> 7 == 0)
{ {
CSS_CPRM.TitleKey? titleKey = CSS.DecodeTitleKey(tmpBuf, dvdDecrypt.BusKey); // The CMI indicates this sector is not encrypted.
outputFormat.WriteSectorTag(new byte[]
if(titleKey.HasValue)
outputFormat.WriteSectorTag(new[]
{
titleKey.Value.CMI
}, i + j, SectorTagType.DvdCmi);
else
continue;
// If the CMI bit is 1, the sector is using copy protection, else it is not
if((titleKey.Value.CMI & 0x80) >> 7 == 0)
{ {
// The CMI indicates this sector is not encrypted. 0, 0, 0, 0, 0
outputFormat.WriteSectorTag(new byte[] }, i + j, SectorTagType.DvdTitleKey);
{
0, 0, 0, 0, 0
}, i + j, SectorTagType.DvdTitleKey);
outputFormat.WriteSectorTag(new byte[] outputFormat.WriteSectorTag(new byte[]
{
0, 0, 0, 0, 0
}, i + j, SectorTagType.DvdTitleKeyDecrypted);
_resume.MissingTitleKeys.Remove(i + j);
continue;
}
// According to libdvdcss, if the key is all zeroes, the sector is actually
// not encrypted even if the CMI says it is.
if(titleKey.Value.Key.All(k => k == 0))
{ {
outputFormat.WriteSectorTag(new byte[] 0, 0, 0, 0, 0
{ }, i + j, SectorTagType.DvdTitleKeyDecrypted);
0, 0, 0, 0, 0
}, i + j, SectorTagType.DvdTitleKey);
outputFormat.WriteSectorTag(new byte[] _resume.MissingTitleKeys.Remove(i + j);
{
0, 0, 0, 0, 0
}, i + j, SectorTagType.DvdTitleKeyDecrypted);
_resume.MissingTitleKeys.Remove(i + j); continue;
continue;
}
outputFormat.WriteSectorTag(titleKey.Value.Key, i + j, SectorTagType.DvdTitleKey);
_resume.MissingTitleKeys.Remove(i + j);
CSS.DecryptTitleKey(0, discKey, titleKey.Value.Key, out tmpBuf);
outputFormat.WriteSectorTag(tmpBuf, i + j, SectorTagType.DvdTitleKeyDecrypted);
} }
// According to libdvdcss, if the key is all zeroes, the sector is actually
// not encrypted even if the CMI says it is.
if(titleKey.Value.Key.All(k => k == 0))
{
outputFormat.WriteSectorTag(new byte[]
{
0, 0, 0, 0, 0
}, i + j, SectorTagType.DvdTitleKey);
outputFormat.WriteSectorTag(new byte[]
{
0, 0, 0, 0, 0
}, i + j, SectorTagType.DvdTitleKeyDecrypted);
_resume.MissingTitleKeys.Remove(i + j);
continue;
}
outputFormat.WriteSectorTag(titleKey.Value.Key, i + j, SectorTagType.DvdTitleKey);
_resume.MissingTitleKeys.Remove(i + j);
CSS.DecryptTitleKey(0, discKey, titleKey.Value.Key, out tmpBuf);
outputFormat.WriteSectorTag(tmpBuf, i + j, SectorTagType.DvdTitleKeyDecrypted);
} }
if(!_storeEncrypted) if(!_storeEncrypted)

View File

@@ -89,7 +89,7 @@ partial class Dump
if(dcMode10?.Pages != null) if(dcMode10?.Pages != null)
foreach(Modes.ModePage modePage in dcMode10.Value.Pages.Where(modePage => foreach(Modes.ModePage modePage in dcMode10.Value.Pages.Where(modePage =>
modePage.Page == 0x01 && modePage.Subpage == 0x00)) modePage.Page == 0x01 && modePage.Subpage == 0x00))
currentModePage = modePage; currentModePage = modePage;
} }
} }
@@ -99,7 +99,7 @@ partial class Dump
if(dcMode6?.Pages != null) if(dcMode6?.Pages != null)
foreach(Modes.ModePage modePage in dcMode6.Value.Pages.Where(modePage => modePage.Page == 0x01 && foreach(Modes.ModePage modePage in dcMode6.Value.Pages.Where(modePage => modePage.Page == 0x01 &&
modePage.Subpage == 0x00)) modePage.Subpage == 0x00))
currentModePage = modePage; currentModePage = modePage;
} }
@@ -347,52 +347,51 @@ partial class Dump
totalDuration += cmdDuration; totalDuration += cmdDuration;
if(!sense && if(sense || _dev.Error)
!_dev.Error) continue;
CSS_CPRM.TitleKey? titleKey = CSS.DecodeTitleKey(buffer, dvdDecrypt.BusKey);
if(!titleKey.HasValue)
continue;
outputFormat.WriteSectorTag(new[]
{ {
CSS_CPRM.TitleKey? titleKey = CSS.DecodeTitleKey(buffer, dvdDecrypt.BusKey); titleKey.Value.CMI
}, missingKey, SectorTagType.DvdCmi);
if(titleKey.HasValue) // If the CMI bit is 1, the sector is using copy protection, else it is not
// If the decoded title key is zeroed, there should be no copy protection
if((titleKey.Value.CMI & 0x80) >> 7 == 0 ||
titleKey.Value.Key.All(k => k == 0))
{
outputFormat.WriteSectorTag(new byte[]
{ {
outputFormat.WriteSectorTag(new[] 0, 0, 0, 0, 0
{ }, missingKey, SectorTagType.DvdTitleKey);
titleKey.Value.CMI
}, missingKey, SectorTagType.DvdCmi);
// If the CMI bit is 1, the sector is using copy protection, else it is not outputFormat.WriteSectorTag(new byte[]
// If the decoded title key is zeroed, there should be no copy protection {
if((titleKey.Value.CMI & 0x80) >> 7 == 0 || 0, 0, 0, 0, 0
titleKey.Value.Key.All(k => k == 0)) }, missingKey, SectorTagType.DvdTitleKeyDecrypted);
{
outputFormat.WriteSectorTag(new byte[]
{
0, 0, 0, 0, 0
}, missingKey, SectorTagType.DvdTitleKey);
outputFormat.WriteSectorTag(new byte[] _resume.MissingTitleKeys.Remove(missingKey);
{ UpdateStatus?.Invoke($"Correctly retried title key {missingKey} in pass {pass}.");
0, 0, 0, 0, 0 _dumpLog.WriteLine("Correctly retried title key {0} in pass {1}.", missingKey, pass);
}, missingKey, SectorTagType.DvdTitleKeyDecrypted); }
else
{
outputFormat.WriteSectorTag(titleKey.Value.Key, missingKey, SectorTagType.DvdTitleKey);
_resume.MissingTitleKeys.Remove(missingKey);
_resume.MissingTitleKeys.Remove(missingKey); if(discKey != null)
UpdateStatus?.Invoke($"Correctly retried title key {missingKey} in pass {pass}."); {
_dumpLog.WriteLine("Correctly retried title key {0} in pass {1}.", missingKey, pass); CSS.DecryptTitleKey(0, discKey, titleKey.Value.Key, out buffer);
} outputFormat.WriteSectorTag(buffer, missingKey, SectorTagType.DvdTitleKeyDecrypted);
else
{
outputFormat.WriteSectorTag(titleKey.Value.Key, missingKey, SectorTagType.DvdTitleKey);
_resume.MissingTitleKeys.Remove(missingKey);
if(discKey != null)
{
CSS.DecryptTitleKey(0, discKey, titleKey.Value.Key, out buffer);
outputFormat.WriteSectorTag(buffer, missingKey, SectorTagType.DvdTitleKeyDecrypted);
}
UpdateStatus?.Invoke($"Correctly retried title key {missingKey} in pass {pass}.");
_dumpLog.WriteLine("Correctly retried title key {0} in pass {1}.", missingKey, pass);
}
} }
UpdateStatus?.Invoke($"Correctly retried title key {missingKey} in pass {pass}.");
_dumpLog.WriteLine("Correctly retried title key {0} in pass {1}.", missingKey, pass);
} }
} }

View File

@@ -2022,83 +2022,83 @@ public sealed partial class DeviceReport
{ {
ctx.AddTask("Trying MediaTek READ DRAM command for Lead-Out...").IsIndeterminate(); ctx.AddTask("Trying MediaTek READ DRAM command for Lead-Out...").IsIndeterminate();
if(mediaTest.Blocks > 0) if(!(mediaTest.Blocks > 0))
return;
if(mediaType == "Audio CD" &&
mediaTest.SupportsReadCd == true)
{ {
if(mediaType == "Audio CD" && _dev.ReadCd(out _, out _, (uint)(mediaTest.Blocks + 1), 2352, 1, MmcSectorTypes.Cdda, false, false,
mediaTest.SupportsReadCd == true) false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.None,
{ _dev.Timeout, out _);
_dev.ReadCd(out _, out _, (uint)(mediaTest.Blocks + 1), 2352, 1, MmcSectorTypes.Cdda, false,
false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None,
MmcSubchannel.None, _dev.Timeout, out _);
triedLeadOut = true; triedLeadOut = true;
}
else if((mediaType.StartsWith("CD", StringComparison.OrdinalIgnoreCase) ||
mediaType == "Enhanced CD (aka E-CD, CD-Plus or CD+)") &&
mediaTest.SupportsReadCdRaw == true)
{
_dev.ReadCd(out _, out _, (uint)(mediaTest.Blocks + 1), 2352, 1, MmcSectorTypes.AllTypes, false,
false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None,
MmcSubchannel.None, _dev.Timeout, out _);
triedLeadOut = true;
}
else if((mediaType.StartsWith("CD", StringComparison.OrdinalIgnoreCase) ||
mediaType == "Enhanced CD (aka E-CD, CD-Plus or CD+)") &&
mediaTest.SupportsReadCd == true)
{
_dev.ReadCd(out _, out _, (uint)(mediaTest.Blocks + 1), 2048, 1, MmcSectorTypes.AllTypes, false,
false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None,
MmcSubchannel.None, _dev.Timeout, out _);
triedLeadOut = true;
}
else if(mediaTest.SupportsRead6 == true)
{
_dev.Read6(out _, out _, (uint)(mediaTest.Blocks + 1), 2048, _dev.Timeout, out _);
triedLeadOut = true;
}
else if(mediaTest.SupportsRead10 == true)
{
_dev.Read10(out _, out _, 0, false, true, false, false, (uint)(mediaTest.Blocks + 1), 2048, 0,
1, _dev.Timeout, out _);
triedLeadOut = true;
}
else if(mediaTest.SupportsRead12 == true)
{
_dev.Read12(out _, out _, 0, false, true, false, false, (uint)(mediaTest.Blocks + 1), 2048, 0,
1, false, _dev.Timeout, out _);
triedLeadOut = true;
}
else if(mediaTest.SupportsRead16 == true)
{
_dev.Read16(out _, out _, 0, false, true, false, (ulong)(mediaTest.Blocks + 1), 2048, 0, 1,
false, _dev.Timeout, out _);
triedLeadOut = true;
}
if(triedLeadOut)
{
mediaTest.CanReadF1_06LeadOut =
!_dev.MediaTekReadDram(out buffer, out senseBuffer, 0, 0xB00, _dev.Timeout, out _);
mediaTest.ReadF1_06LeadOutData = mediaTest.CanReadF1_06LeadOut == true ? buffer : senseBuffer;
// This means it has returned the same as previous read, so not really lead-out.
if(mediaTest.CanReadF1_06 == true &&
mediaTest.CanReadF1_06LeadOut == true &&
mediaTest.ReadF1_06Data.SequenceEqual(mediaTest.ReadF1_06LeadOutData))
{
mediaTest.CanReadF1_06LeadOut = false;
mediaTest.ReadF1_06LeadOutData = senseBuffer;
}
AaruConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadF1_06LeadOut);
}
} }
else if((mediaType.StartsWith("CD", StringComparison.OrdinalIgnoreCase) ||
mediaType == "Enhanced CD (aka E-CD, CD-Plus or CD+)") &&
mediaTest.SupportsReadCdRaw == true)
{
_dev.ReadCd(out _, out _, (uint)(mediaTest.Blocks + 1), 2352, 1, MmcSectorTypes.AllTypes, false,
false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None,
MmcSubchannel.None, _dev.Timeout, out _);
triedLeadOut = true;
}
else if((mediaType.StartsWith("CD", StringComparison.OrdinalIgnoreCase) ||
mediaType == "Enhanced CD (aka E-CD, CD-Plus or CD+)") &&
mediaTest.SupportsReadCd == true)
{
_dev.ReadCd(out _, out _, (uint)(mediaTest.Blocks + 1), 2048, 1, MmcSectorTypes.AllTypes, false,
false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.None,
_dev.Timeout, out _);
triedLeadOut = true;
}
else if(mediaTest.SupportsRead6 == true)
{
_dev.Read6(out _, out _, (uint)(mediaTest.Blocks + 1), 2048, _dev.Timeout, out _);
triedLeadOut = true;
}
else if(mediaTest.SupportsRead10 == true)
{
_dev.Read10(out _, out _, 0, false, true, false, false, (uint)(mediaTest.Blocks + 1), 2048, 0, 1,
_dev.Timeout, out _);
triedLeadOut = true;
}
else if(mediaTest.SupportsRead12 == true)
{
_dev.Read12(out _, out _, 0, false, true, false, false, (uint)(mediaTest.Blocks + 1), 2048, 0, 1,
false, _dev.Timeout, out _);
triedLeadOut = true;
}
else if(mediaTest.SupportsRead16 == true)
{
_dev.Read16(out _, out _, 0, false, true, false, (ulong)(mediaTest.Blocks + 1), 2048, 0, 1, false,
_dev.Timeout, out _);
triedLeadOut = true;
}
if(!triedLeadOut)
return;
mediaTest.CanReadF1_06LeadOut =
!_dev.MediaTekReadDram(out buffer, out senseBuffer, 0, 0xB00, _dev.Timeout, out _);
mediaTest.ReadF1_06LeadOutData = mediaTest.CanReadF1_06LeadOut == true ? buffer : senseBuffer;
// This means it has returned the same as previous read, so not really lead-out.
if(mediaTest.CanReadF1_06 == true &&
mediaTest.CanReadF1_06LeadOut == true &&
mediaTest.ReadF1_06Data.SequenceEqual(mediaTest.ReadF1_06LeadOutData))
{
mediaTest.CanReadF1_06LeadOut = false;
mediaTest.ReadF1_06LeadOutData = senseBuffer;
}
AaruConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadF1_06LeadOut);
}); });
} }
@@ -2177,25 +2177,23 @@ public sealed partial class DeviceReport
false, MmcErrorField.None, false, MmcErrorField.None,
MmcSubchannel.Raw, _dev.Timeout, out _); MmcSubchannel.Raw, _dev.Timeout, out _);
if(mediaTest.CanReadingIntersessionLeadOut != false)
return;
mediaTest.CanReadingIntersessionLeadOut = !_dev.ReadCd(out buffer, out senseBuffer,
firstSessionLeadOutLba, 2368, 1,
MmcSectorTypes.AllTypes, false, false,
false, MmcHeaderCodes.AllHeaders, true,
false, MmcErrorField.None,
MmcSubchannel.Q16, _dev.Timeout, out _);
if(mediaTest.CanReadingIntersessionLeadOut == false) if(mediaTest.CanReadingIntersessionLeadOut == false)
{
mediaTest.CanReadingIntersessionLeadOut = !_dev.ReadCd(out buffer, out senseBuffer, mediaTest.CanReadingIntersessionLeadOut = !_dev.ReadCd(out buffer, out senseBuffer,
firstSessionLeadOutLba, 2368, 1, firstSessionLeadOutLba, 2352, 1,
MmcSectorTypes.AllTypes, false, false, MmcSectorTypes.AllTypes, false, false,
false, MmcHeaderCodes.AllHeaders, true, false, MmcHeaderCodes.AllHeaders, true,
false, MmcErrorField.None, false, MmcErrorField.None,
MmcSubchannel.Q16, _dev.Timeout, out _); MmcSubchannel.None, _dev.Timeout, out _);
if(mediaTest.CanReadingIntersessionLeadOut == false)
mediaTest.CanReadingIntersessionLeadOut = !_dev.ReadCd(out buffer, out senseBuffer,
firstSessionLeadOutLba, 2352, 1,
MmcSectorTypes.AllTypes, false,
false, false,
MmcHeaderCodes.AllHeaders, true,
false, MmcErrorField.None,
MmcSubchannel.None, _dev.Timeout,
out _);
}
}); });
AaruConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadingIntersessionLeadOut); AaruConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadingIntersessionLeadOut);
@@ -2213,24 +2211,23 @@ public sealed partial class DeviceReport
false, MmcErrorField.None, false, MmcErrorField.None,
MmcSubchannel.Raw, _dev.Timeout, out _); MmcSubchannel.Raw, _dev.Timeout, out _);
if(mediaTest.CanReadingIntersessionLeadIn != false)
return;
mediaTest.CanReadingIntersessionLeadIn = !_dev.ReadCd(out buffer, out senseBuffer,
secondSessionLeadInLba, 2368, 1,
MmcSectorTypes.AllTypes, false, false,
false, MmcHeaderCodes.AllHeaders, true,
false, MmcErrorField.None,
MmcSubchannel.Q16, _dev.Timeout, out _);
if(mediaTest.CanReadingIntersessionLeadIn == false) if(mediaTest.CanReadingIntersessionLeadIn == false)
{
mediaTest.CanReadingIntersessionLeadIn = !_dev.ReadCd(out buffer, out senseBuffer, mediaTest.CanReadingIntersessionLeadIn = !_dev.ReadCd(out buffer, out senseBuffer,
secondSessionLeadInLba, 2368, 1, secondSessionLeadInLba, 2352, 1,
MmcSectorTypes.AllTypes, false, false, MmcSectorTypes.AllTypes, false, false,
false, MmcHeaderCodes.AllHeaders, true, false, MmcHeaderCodes.AllHeaders, true,
false, MmcErrorField.None, false, MmcErrorField.None,
MmcSubchannel.Q16, _dev.Timeout, out _); MmcSubchannel.None, _dev.Timeout, out _);
if(mediaTest.CanReadingIntersessionLeadIn == false)
mediaTest.CanReadingIntersessionLeadIn = !_dev.ReadCd(out buffer, out senseBuffer,
secondSessionLeadInLba, 2352, 1,
MmcSectorTypes.AllTypes, false, false,
false, MmcHeaderCodes.AllHeaders,
true, false, MmcErrorField.None,
MmcSubchannel.None, _dev.Timeout,
out _);
}
}); });
AaruConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadingIntersessionLeadIn); AaruConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadingIntersessionLeadIn);

View File

@@ -650,105 +650,107 @@ public sealed partial class DeviceReport
} }
} }
if((mediaTest.SupportsReadLong == true || mediaTest.SupportsReadLong16 == true) && if(mediaTest.SupportsReadLong != true && mediaTest.SupportsReadLong16 != true ||
mediaTest.LongBlockSize == mediaTest.BlockSize) mediaTest.LongBlockSize != mediaTest.BlockSize)
switch(mediaTest.BlockSize) return;
switch(mediaTest.BlockSize)
{
case 512:
{ {
case 512: foreach(ushort testSize in new ushort[]
{ {
foreach(ushort testSize in new ushort[] // Long sector sizes for floppies
{ 514,
// Long sector sizes for floppies
514,
// Long sector sizes for SuperDisk // Long sector sizes for SuperDisk
536, 558, 536, 558,
// Long sector sizes for 512-byte magneto-opticals // Long sector sizes for 512-byte magneto-opticals
600, 610, 630 600, 610, 630
}) })
{
sense = mediaTest.SupportsReadLong16 == true
? _dev.ReadLong16(out buffer, out senseBuffer, false, 0, testSize, _dev.Timeout,
out _) : _dev.ReadLong10(out buffer, out senseBuffer, false,
false, 0, testSize, _dev.Timeout, out _);
if(sense || _dev.Error)
continue;
mediaTest.LongBlockSize = testSize;
break;
}
break;
}
case 1024:
{
foreach(ushort testSize in new ushort[]
{
// Long sector sizes for floppies
1026,
// Long sector sizes for 1024-byte magneto-opticals
1200
})
{
sense = mediaTest.SupportsReadLong16 == true
? _dev.ReadLong16(out buffer, out senseBuffer, false, 0, testSize, _dev.Timeout,
out _) : _dev.ReadLong10(out buffer, out senseBuffer, false,
false, 0, testSize, _dev.Timeout, out _);
if(sense || _dev.Error)
continue;
mediaTest.LongBlockSize = testSize;
break;
}
break;
}
case 2048:
{ {
sense = mediaTest.SupportsReadLong16 == true sense = mediaTest.SupportsReadLong16 == true
? _dev.ReadLong16(out buffer, out senseBuffer, false, 0, 2380, _dev.Timeout, out _) ? _dev.ReadLong16(out buffer, out senseBuffer, false, 0, testSize, _dev.Timeout,
: _dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 2380, _dev.Timeout, out _) : _dev.ReadLong10(out buffer, out senseBuffer, false,
out _); false, 0, testSize, _dev.Timeout, out _);
if(!sense && if(sense || _dev.Error)
!_dev.Error) continue;
mediaTest.LongBlockSize = 2380;
mediaTest.LongBlockSize = testSize;
break; break;
} }
case 4096:
{
sense = mediaTest.SupportsReadLong16 == true
? _dev.ReadLong16(out buffer, out senseBuffer, false, 0, 4760, _dev.Timeout, out _)
: _dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 4760, _dev.Timeout,
out _);
if(!sense && break;
!_dev.Error)
mediaTest.LongBlockSize = 4760;
break;
}
case 8192:
{
sense = mediaTest.SupportsReadLong16 == true
? _dev.ReadLong16(out buffer, out senseBuffer, false, 0, 9424, _dev.Timeout, out _)
: _dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 9424, _dev.Timeout,
out _);
if(!sense &&
!_dev.Error)
mediaTest.LongBlockSize = 9424;
break;
}
} }
case 1024:
{
foreach(ushort testSize in new ushort[]
{
// Long sector sizes for floppies
1026,
// Long sector sizes for 1024-byte magneto-opticals
1200
})
{
sense = mediaTest.SupportsReadLong16 == true
? _dev.ReadLong16(out buffer, out senseBuffer, false, 0, testSize, _dev.Timeout,
out _) : _dev.ReadLong10(out buffer, out senseBuffer, false,
false, 0, testSize, _dev.Timeout, out _);
if(sense || _dev.Error)
continue;
mediaTest.LongBlockSize = testSize;
break;
}
break;
}
case 2048:
{
sense = mediaTest.SupportsReadLong16 == true
? _dev.ReadLong16(out buffer, out senseBuffer, false, 0, 2380, _dev.Timeout, out _)
: _dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 2380, _dev.Timeout,
out _);
if(!sense &&
!_dev.Error)
mediaTest.LongBlockSize = 2380;
break;
}
case 4096:
{
sense = mediaTest.SupportsReadLong16 == true
? _dev.ReadLong16(out buffer, out senseBuffer, false, 0, 4760, _dev.Timeout, out _)
: _dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 4760, _dev.Timeout,
out _);
if(!sense &&
!_dev.Error)
mediaTest.LongBlockSize = 4760;
break;
}
case 8192:
{
sense = mediaTest.SupportsReadLong16 == true
? _dev.ReadLong16(out buffer, out senseBuffer, false, 0, 9424, _dev.Timeout, out _)
: _dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 9424, _dev.Timeout,
out _);
if(!sense &&
!_dev.Error)
mediaTest.LongBlockSize = 9424;
break;
}
}
}); });
Spectre.ProgressSingleSpinner(ctx => Spectre.ProgressSingleSpinner(ctx =>

View File

@@ -2222,18 +2222,18 @@ public static class MMC
break; break;
} }
if(line.StartsWith("BOOT2=cdrom0:", StringComparison.InvariantCultureIgnoreCase)) if(!line.StartsWith("BOOT2=cdrom0:", StringComparison.InvariantCultureIgnoreCase))
{ continue;
ps2BootFile = line.Substring(13);
if(ps2BootFile.StartsWith('\\')) ps2BootFile = line.Substring(13);
ps2BootFile = ps2BootFile.Substring(1);
if(ps2BootFile.EndsWith(";1", StringComparison.InvariantCultureIgnoreCase)) if(ps2BootFile.StartsWith('\\'))
ps2BootFile = ps2BootFile.Substring(0, ps2BootFile.Length - 2); ps2BootFile = ps2BootFile.Substring(1);
break; if(ps2BootFile.EndsWith(";1", StringComparison.InvariantCultureIgnoreCase))
} ps2BootFile = ps2BootFile.Substring(0, ps2BootFile.Length - 2);
break;
} }
if(ps1BootFile != null && if(ps1BootFile != null &&

View File

@@ -216,11 +216,11 @@ public sealed partial class Device : Devices.Device
} }
#endregion FireWire #endregion FireWire
#region PCMCIA #region PCMCIA
if(dev._remote.GetPcmciaData(out byte[] cisBuf)) if(!dev._remote.GetPcmciaData(out byte[] cisBuf))
{ return dev;
dev.IsPcmcia = true;
dev.Cis = cisBuf; dev.IsPcmcia = true;
} dev.Cis = cisBuf;
#endregion PCMCIA #endregion PCMCIA
return dev; return dev;

View File

@@ -1238,15 +1238,15 @@ public class Remote : IDisposable
Array.Copy(res.ocr, 0, ocr, 0, res.ocr_len); Array.Copy(res.ocr, 0, ocr, 0, res.ocr_len);
} }
if(res.scr_len > 0) if(res.scr_len <= 0)
{ return res.isSdhci;
if(res.scr_len > 16)
res.scr_len = 16;
scr = new byte[res.scr_len]; if(res.scr_len > 16)
res.scr_len = 16;
Array.Copy(res.scr, 0, scr, 0, res.scr_len); scr = new byte[res.scr_len];
}
Array.Copy(res.scr, 0, scr, 0, res.scr_len);
return res.isSdhci; return res.isSdhci;
} }
@@ -1576,7 +1576,7 @@ public class Remote : IDisposable
/// <param name="sense">Set to <c>true</c> if any of the commands returned an error status, <c>false</c> otherwise</param> /// <param name="sense">Set to <c>true</c> if any of the commands returned an error status, <c>false</c> otherwise</param>
/// <param name="timeout">Maximum allowed time to execute a single command</param> /// <param name="timeout">Maximum allowed time to execute a single command</param>
/// <returns>0 if no error occurred, otherwise, errno</returns> /// <returns>0 if no error occurred, otherwise, errno</returns>
public int SendMultipleMmcCommands(Device.MmcSingleCommand[] commands, out double duration, out bool sense, public int SendMultipleMmcCommands(Devices.Device.MmcSingleCommand[] commands, out double duration, out bool sense,
uint timeout = 0) uint timeout = 0)
{ {
if(ServerProtocolVersion < 2) if(ServerProtocolVersion < 2)
@@ -1588,7 +1588,7 @@ public class Remote : IDisposable
long packetSize = Marshal.SizeOf<AaruPacketMultiCmdSdhci>() + long packetSize = Marshal.SizeOf<AaruPacketMultiCmdSdhci>() +
Marshal.SizeOf<AaruCmdSdhci>() * commands.LongLength; Marshal.SizeOf<AaruCmdSdhci>() * commands.LongLength;
foreach(Device.MmcSingleCommand command in commands) foreach(Devices.Device.MmcSingleCommand command in commands)
packetSize += command.buffer?.Length ?? 0; packetSize += command.buffer?.Length ?? 0;
var packet = new AaruPacketMultiCmdSdhci var packet = new AaruPacketMultiCmdSdhci
@@ -1630,7 +1630,7 @@ public class Remote : IDisposable
off += tmp.Length; off += tmp.Length;
} }
foreach(Device.MmcSingleCommand command in commands.Where(command => (command.buffer?.Length ?? 0) != 0)) foreach(Devices.Device.MmcSingleCommand command in commands.Where(command => (command.buffer?.Length ?? 0) != 0))
{ {
Array.Copy(command.buffer, 0, buf, off, command.buffer.Length); Array.Copy(command.buffer, 0, buf, off, command.buffer.Length);
@@ -1699,7 +1699,7 @@ public class Remote : IDisposable
var error = 0; var error = 0;
foreach(Device.MmcSingleCommand command in commands) foreach(Devices.Device.MmcSingleCommand command in commands)
{ {
AaruResSdhci cmdRes = AaruResSdhci cmdRes =
Marshal.ByteArrayToStructureLittleEndian<AaruResSdhci>(buf, off, Marshal.SizeOf<AaruResSdhci>()); Marshal.ByteArrayToStructureLittleEndian<AaruResSdhci>(buf, off, Marshal.SizeOf<AaruResSdhci>());
@@ -1720,7 +1720,7 @@ public class Remote : IDisposable
off += Marshal.SizeOf<AaruResSdhci>(); off += Marshal.SizeOf<AaruResSdhci>();
} }
foreach(Device.MmcSingleCommand command in commands) foreach(Devices.Device.MmcSingleCommand command in commands)
{ {
Array.Copy(buf, off, command.buffer, 0, command.buffer.Length); Array.Copy(buf, off, command.buffer, 0, command.buffer.Length);
off += command.buffer.Length; off += command.buffer.Length;
@@ -1738,13 +1738,13 @@ public class Remote : IDisposable
/// <param name="sense">Set to <c>true</c> if any of the commands returned an error status, <c>false</c> otherwise</param> /// <param name="sense">Set to <c>true</c> if any of the commands returned an error status, <c>false</c> otherwise</param>
/// <param name="timeout">Maximum allowed time to execute a single command</param> /// <param name="timeout">Maximum allowed time to execute a single command</param>
/// <returns>0 if no error occurred, otherwise, errno</returns> /// <returns>0 if no error occurred, otherwise, errno</returns>
int SendMultipleMmcCommandsV1(Device.MmcSingleCommand[] commands, out double duration, out bool sense, uint timeout) int SendMultipleMmcCommandsV1(Devices.Device.MmcSingleCommand[] commands, out double duration, out bool sense, uint timeout)
{ {
sense = false; sense = false;
duration = 0; duration = 0;
var error = 0; var error = 0;
foreach(Device.MmcSingleCommand command in commands) foreach(Devices.Device.MmcSingleCommand command in commands)
{ {
error = SendMmcCommand(command.command, command.write, command.isApplication, command.flags, error = SendMmcCommand(command.command, command.write, command.isApplication, command.flags,
command.argument, command.blockSize, command.blocks, ref command.buffer, command.argument, command.blockSize, command.blocks, ref command.buffer,

View File

@@ -785,28 +785,27 @@ public sealed partial class FAT
return BpbKind.Atari; return BpbKind.Atari;
} }
if(useApricotBpb) if(!useApricotBpb)
{ return BpbKind.None;
fakeBpb.bps = apricotBpb.mainBPB.bps;
fakeBpb.spc = apricotBpb.mainBPB.spc;
fakeBpb.rsectors = apricotBpb.mainBPB.rsectors;
fakeBpb.fats_no = apricotBpb.mainBPB.fats_no;
fakeBpb.root_ent = apricotBpb.mainBPB.root_ent;
fakeBpb.sectors = apricotBpb.mainBPB.sectors;
fakeBpb.media = apricotBpb.mainBPB.media;
fakeBpb.spfat = apricotBpb.mainBPB.spfat;
fakeBpb.sptrk = apricotBpb.spt;
bootable = apricotBpb.bootType > 0;
if(apricotBpb.bootLocation > 0 && fakeBpb.bps = apricotBpb.mainBPB.bps;
apricotBpb.bootLocation + apricotBpb.bootSize < imagePlugin.Info.Sectors) fakeBpb.spc = apricotBpb.mainBPB.spc;
imagePlugin.ReadSectors(apricotBpb.bootLocation, fakeBpb.rsectors = apricotBpb.mainBPB.rsectors;
(uint)(apricotBpb.sectorSize * apricotBpb.bootSize) / fakeBpb.fats_no = apricotBpb.mainBPB.fats_no;
imagePlugin.Info.SectorSize, out fakeBpb.boot_code); fakeBpb.root_ent = apricotBpb.mainBPB.root_ent;
fakeBpb.sectors = apricotBpb.mainBPB.sectors;
fakeBpb.media = apricotBpb.mainBPB.media;
fakeBpb.spfat = apricotBpb.mainBPB.spfat;
fakeBpb.sptrk = apricotBpb.spt;
bootable = apricotBpb.bootType > 0;
return BpbKind.Apricot; if(apricotBpb.bootLocation > 0 &&
} apricotBpb.bootLocation + apricotBpb.bootSize < imagePlugin.Info.Sectors)
imagePlugin.ReadSectors(apricotBpb.bootLocation,
(uint)(apricotBpb.sectorSize * apricotBpb.bootSize) / imagePlugin.Info.SectorSize,
out fakeBpb.boot_code);
return BpbKind.Apricot;
return BpbKind.None;
} }
} }

View File

@@ -127,35 +127,40 @@ public sealed partial class ISO9660
offset += entry.XattrLength * _blockSize; offset += entry.XattrLength * _blockSize;
if(entry.CdiSystemArea?.attributes.HasFlag(CdiAttributes.DigitalAudio) == true && if(entry.CdiSystemArea?.attributes.HasFlag(CdiAttributes.DigitalAudio) != true ||
entry.Extents.Count == 1) entry.Extents.Count != 1)
try return ReadWithExtents(offset, size, entry.Extents,
{ entry.XA?.signature == XA_MAGIC &&
long firstSector = offset / 2352; entry.XA?.attributes.HasFlag(XaAttributes.Interleaved) == true,
long offsetInSector = offset % 2352; entry.XA?.filenumber ?? 0, out buf);
long sizeInSectors = (size + offsetInSector) / 2352;
if((size + offsetInSector) % 2352 > 0) try
sizeInSectors++; {
long firstSector = offset / 2352;
long offsetInSector = offset % 2352;
long sizeInSectors = (size + offsetInSector) / 2352;
ErrorNumber errno = _image.ReadSectorsLong((ulong)(entry.Extents[0].extent + firstSector), if((size + offsetInSector) % 2352 > 0)
(uint)sizeInSectors, out byte[] buffer); sizeInSectors++;
if(errno != ErrorNumber.NoError) ErrorNumber errno = _image.ReadSectorsLong((ulong)(entry.Extents[0].extent + firstSector),
return errno; (uint)sizeInSectors, out byte[] buffer);
buf = new byte[size]; if(errno != ErrorNumber.NoError)
Array.Copy(buffer, offsetInSector, buf, 0, size); return errno;
return ErrorNumber.NoError; buf = new byte[size];
} Array.Copy(buffer, offsetInSector, buf, 0, size);
catch(Exception e)
{
AaruConsole.DebugWriteLine("ISO9660 plugin", "Exception reading CD-i audio file");
AaruConsole.DebugWriteLine("ISO9660 plugin", "{0}", e);
return ErrorNumber.UnexpectedException; return ErrorNumber.NoError;
} }
catch(Exception e)
{
AaruConsole.DebugWriteLine("ISO9660 plugin", "Exception reading CD-i audio file");
AaruConsole.DebugWriteLine("ISO9660 plugin", "{0}", e);
return ErrorNumber.UnexpectedException;
}
return ReadWithExtents(offset, size, entry.Extents, return ReadWithExtents(offset, size, entry.Extents,
entry.XA?.signature == XA_MAGIC && entry.XA?.signature == XA_MAGIC &&

View File

@@ -127,17 +127,16 @@ public sealed partial class ISO9660
if(entry.AssociatedFile.Extents is null) if(entry.AssociatedFile.Extents is null)
return ErrorNumber.InvalidArgument; return ErrorNumber.InvalidArgument;
if(entry.AssociatedFile.Size == 0) if(entry.AssociatedFile.Size != 0)
{ return ReadWithExtents(0, (long)entry.AssociatedFile.Size, entry.AssociatedFile.Extents,
buf = Array.Empty<byte>(); entry.AssociatedFile.XA?.signature == XA_MAGIC &&
entry.AssociatedFile.XA?.attributes.HasFlag(XaAttributes.Interleaved) ==
true, entry.AssociatedFile.XA?.filenumber ?? 0, out buf);
return ErrorNumber.NoError; buf = Array.Empty<byte>();
}
return ErrorNumber.NoError;
return ReadWithExtents(0, (long)entry.AssociatedFile.Size, entry.AssociatedFile.Extents,
entry.AssociatedFile.XA?.signature == XA_MAGIC &&
entry.AssociatedFile.XA?.attributes.HasFlag(XaAttributes.Interleaved) == true,
entry.AssociatedFile.XA?.filenumber ?? 0, out buf);
case "com.apple.dos.type": case "com.apple.dos.type":
if(entry.AppleDosType is null) if(entry.AppleDosType is null)
return ErrorNumber.NoSuchExtendedAttribute; return ErrorNumber.NoSuchExtendedAttribute;
@@ -160,17 +159,16 @@ public sealed partial class ISO9660
if(entry.ResourceFork.Extents is null) if(entry.ResourceFork.Extents is null)
return ErrorNumber.InvalidArgument; return ErrorNumber.InvalidArgument;
if(entry.ResourceFork.Size == 0) if(entry.ResourceFork.Size != 0)
{ return ReadWithExtents(0, (long)entry.ResourceFork.Size, entry.ResourceFork.Extents,
buf = Array.Empty<byte>(); entry.ResourceFork.XA?.signature == XA_MAGIC &&
entry.ResourceFork.XA?.attributes.HasFlag(XaAttributes.Interleaved) == true,
entry.ResourceFork.XA?.filenumber ?? 0, out buf);
return ErrorNumber.NoError; buf = Array.Empty<byte>();
}
return ErrorNumber.NoError;
return ReadWithExtents(0, (long)entry.ResourceFork.Size, entry.ResourceFork.Extents,
entry.ResourceFork.XA?.signature == XA_MAGIC &&
entry.ResourceFork.XA?.attributes.HasFlag(XaAttributes.Interleaved) == true,
entry.ResourceFork.XA?.filenumber ?? 0, out buf);
case "com.apple.FinderInfo": case "com.apple.FinderInfo":
if(entry.FinderInfo is null) if(entry.FinderInfo is null)
return ErrorNumber.NoSuchExtendedAttribute; return ErrorNumber.NoSuchExtendedAttribute;

View File

@@ -454,11 +454,11 @@ public sealed class BlockMap : ItemsControl
ctx.FillRectangle(new SolidColorBrush(color), new Rect(x, y, squareWidth, squareHeight)); ctx.FillRectangle(new SolidColorBrush(color), new Rect(x, y, squareWidth, squareHeight));
x += squareWidth + 2 * borderWidth; x += squareWidth + 2 * borderWidth;
if(x >= sideLength) if(x < sideLength)
{ continue;
x = 0;
y += squareHeight + 2 * borderWidth; x = 0;
} y += squareHeight + 2 * borderWidth;
} }
} }

View File

@@ -595,93 +595,93 @@ public sealed class ScsiInfoViewModel : ViewModelBase
}); });
} }
if(_configuration != null) if(_configuration == null)
{ return;
Features.SeparatedFeatures ftr = Features.Separate(_configuration);
AaruConsole.DebugWriteLine("Device-Info command", "GET CONFIGURATION length is {0} bytes", ftr.DataLength); Features.SeparatedFeatures ftr = Features.Separate(_configuration);
AaruConsole.DebugWriteLine("Device-Info command", "GET CONFIGURATION current profile is {0:X4}h", AaruConsole.DebugWriteLine("Device-Info command", "GET CONFIGURATION length is {0} bytes", ftr.DataLength);
ftr.CurrentProfile);
if(ftr.Descriptors != null) AaruConsole.DebugWriteLine("Device-Info command", "GET CONFIGURATION current profile is {0:X4}h",
foreach(Features.FeatureDescriptor desc in ftr.Descriptors) ftr.CurrentProfile);
if(ftr.Descriptors != null)
foreach(Features.FeatureDescriptor desc in ftr.Descriptors)
{
string featureNumber = $"Feature {desc.Code:X4}h";
AaruConsole.DebugWriteLine("Device-Info command", "Feature {0:X4}h", desc.Code);
string featureDescription = desc.Code switch
{
0x0000 => Features.Prettify_0000(desc.Data),
0x0001 => Features.Prettify_0001(desc.Data),
0x0002 => Features.Prettify_0002(desc.Data),
0x0003 => Features.Prettify_0003(desc.Data),
0x0004 => Features.Prettify_0004(desc.Data),
0x0010 => Features.Prettify_0010(desc.Data),
0x001D => Features.Prettify_001D(desc.Data),
0x001E => Features.Prettify_001E(desc.Data),
0x001F => Features.Prettify_001F(desc.Data),
0x0020 => Features.Prettify_0020(desc.Data),
0x0021 => Features.Prettify_0021(desc.Data),
0x0022 => Features.Prettify_0022(desc.Data),
0x0023 => Features.Prettify_0023(desc.Data),
0x0024 => Features.Prettify_0024(desc.Data),
0x0025 => Features.Prettify_0025(desc.Data),
0x0026 => Features.Prettify_0026(desc.Data),
0x0027 => Features.Prettify_0027(desc.Data),
0x0028 => Features.Prettify_0028(desc.Data),
0x0029 => Features.Prettify_0029(desc.Data),
0x002A => Features.Prettify_002A(desc.Data),
0x002B => Features.Prettify_002B(desc.Data),
0x002C => Features.Prettify_002C(desc.Data),
0x002D => Features.Prettify_002D(desc.Data),
0x002E => Features.Prettify_002E(desc.Data),
0x002F => Features.Prettify_002F(desc.Data),
0x0030 => Features.Prettify_0030(desc.Data),
0x0031 => Features.Prettify_0031(desc.Data),
0x0032 => Features.Prettify_0032(desc.Data),
0x0033 => Features.Prettify_0033(desc.Data),
0x0035 => Features.Prettify_0035(desc.Data),
0x0037 => Features.Prettify_0037(desc.Data),
0x0038 => Features.Prettify_0038(desc.Data),
0x003A => Features.Prettify_003A(desc.Data),
0x003B => Features.Prettify_003B(desc.Data),
0x0040 => Features.Prettify_0040(desc.Data),
0x0041 => Features.Prettify_0041(desc.Data),
0x0042 => Features.Prettify_0042(desc.Data),
0x0050 => Features.Prettify_0050(desc.Data),
0x0051 => Features.Prettify_0051(desc.Data),
0x0080 => Features.Prettify_0080(desc.Data),
0x0100 => Features.Prettify_0100(desc.Data),
0x0101 => Features.Prettify_0101(desc.Data),
0x0102 => Features.Prettify_0102(desc.Data),
0x0103 => Features.Prettify_0103(desc.Data),
0x0104 => Features.Prettify_0104(desc.Data),
0x0105 => Features.Prettify_0105(desc.Data),
0x0106 => Features.Prettify_0106(desc.Data),
0x0107 => Features.Prettify_0107(desc.Data),
0x0108 => Features.Prettify_0108(desc.Data),
0x0109 => Features.Prettify_0109(desc.Data),
0x010A => Features.Prettify_010A(desc.Data),
0x010B => Features.Prettify_010B(desc.Data),
0x010C => Features.Prettify_010C(desc.Data),
0x010D => Features.Prettify_010D(desc.Data),
0x010E => Features.Prettify_010E(desc.Data),
0x0110 => Features.Prettify_0110(desc.Data),
0x0113 => Features.Prettify_0113(desc.Data),
0x0142 => Features.Prettify_0142(desc.Data),
_ => "Unknown feature"
};
MmcFeatures.Add(new ScsiPageModel
{ {
string featureNumber = $"Feature {desc.Code:X4}h"; Page = featureNumber,
AaruConsole.DebugWriteLine("Device-Info command", "Feature {0:X4}h", desc.Code); Description = featureDescription
});
string featureDescription = desc.Code switch }
{ else
0x0000 => Features.Prettify_0000(desc.Data), AaruConsole.DebugWriteLine("Device-Info command", "GET CONFIGURATION returned no feature descriptors");
0x0001 => Features.Prettify_0001(desc.Data),
0x0002 => Features.Prettify_0002(desc.Data),
0x0003 => Features.Prettify_0003(desc.Data),
0x0004 => Features.Prettify_0004(desc.Data),
0x0010 => Features.Prettify_0010(desc.Data),
0x001D => Features.Prettify_001D(desc.Data),
0x001E => Features.Prettify_001E(desc.Data),
0x001F => Features.Prettify_001F(desc.Data),
0x0020 => Features.Prettify_0020(desc.Data),
0x0021 => Features.Prettify_0021(desc.Data),
0x0022 => Features.Prettify_0022(desc.Data),
0x0023 => Features.Prettify_0023(desc.Data),
0x0024 => Features.Prettify_0024(desc.Data),
0x0025 => Features.Prettify_0025(desc.Data),
0x0026 => Features.Prettify_0026(desc.Data),
0x0027 => Features.Prettify_0027(desc.Data),
0x0028 => Features.Prettify_0028(desc.Data),
0x0029 => Features.Prettify_0029(desc.Data),
0x002A => Features.Prettify_002A(desc.Data),
0x002B => Features.Prettify_002B(desc.Data),
0x002C => Features.Prettify_002C(desc.Data),
0x002D => Features.Prettify_002D(desc.Data),
0x002E => Features.Prettify_002E(desc.Data),
0x002F => Features.Prettify_002F(desc.Data),
0x0030 => Features.Prettify_0030(desc.Data),
0x0031 => Features.Prettify_0031(desc.Data),
0x0032 => Features.Prettify_0032(desc.Data),
0x0033 => Features.Prettify_0033(desc.Data),
0x0035 => Features.Prettify_0035(desc.Data),
0x0037 => Features.Prettify_0037(desc.Data),
0x0038 => Features.Prettify_0038(desc.Data),
0x003A => Features.Prettify_003A(desc.Data),
0x003B => Features.Prettify_003B(desc.Data),
0x0040 => Features.Prettify_0040(desc.Data),
0x0041 => Features.Prettify_0041(desc.Data),
0x0042 => Features.Prettify_0042(desc.Data),
0x0050 => Features.Prettify_0050(desc.Data),
0x0051 => Features.Prettify_0051(desc.Data),
0x0080 => Features.Prettify_0080(desc.Data),
0x0100 => Features.Prettify_0100(desc.Data),
0x0101 => Features.Prettify_0101(desc.Data),
0x0102 => Features.Prettify_0102(desc.Data),
0x0103 => Features.Prettify_0103(desc.Data),
0x0104 => Features.Prettify_0104(desc.Data),
0x0105 => Features.Prettify_0105(desc.Data),
0x0106 => Features.Prettify_0106(desc.Data),
0x0107 => Features.Prettify_0107(desc.Data),
0x0108 => Features.Prettify_0108(desc.Data),
0x0109 => Features.Prettify_0109(desc.Data),
0x010A => Features.Prettify_010A(desc.Data),
0x010B => Features.Prettify_010B(desc.Data),
0x010C => Features.Prettify_010C(desc.Data),
0x010D => Features.Prettify_010D(desc.Data),
0x010E => Features.Prettify_010E(desc.Data),
0x0110 => Features.Prettify_0110(desc.Data),
0x0113 => Features.Prettify_0113(desc.Data),
0x0142 => Features.Prettify_0142(desc.Data),
_ => "Unknown feature"
};
MmcFeatures.Add(new ScsiPageModel
{
Page = featureNumber,
Description = featureDescription
});
}
else
AaruConsole.DebugWriteLine("Device-Info command", "GET CONFIGURATION returned no feature descriptors");
}
} }
public byte[] InquiryData { get; } public byte[] InquiryData { get; }

View File

@@ -563,11 +563,11 @@ public sealed partial class Alcohol120
extraCount += _writingTracks.Count(t => t.Session == i); extraCount += _writingTracks.Count(t => t.Session == i);
if(i < sessions) if(i >= sessions)
{ continue;
currentExtraOffset += Marshal.SizeOf<Track>() * 2;
extraCount += 2; currentExtraOffset += Marshal.SizeOf<Track>() * 2;
} extraCount += 2;
} }
long footerOffset = currentExtraOffset + Marshal.SizeOf<TrackExtra>() * extraCount; long footerOffset = currentExtraOffset + Marshal.SizeOf<TrackExtra>() * extraCount;

View File

@@ -1302,14 +1302,16 @@ public sealed partial class BlindWrite5
AaruConsole.VerboseWriteLine("BlindWrite image describes a disc of type {0}", _imageInfo.MediaType); AaruConsole.VerboseWriteLine("BlindWrite image describes a disc of type {0}", _imageInfo.MediaType);
if(_header.profile != ProfileNumber.CDR && if(_header.profile == ProfileNumber.CDR ||
_header.profile != ProfileNumber.CDRW && _header.profile == ProfileNumber.CDRW ||
_header.profile != ProfileNumber.CDROM) _header.profile == ProfileNumber.CDROM)
foreach(Track track in Tracks) return ErrorNumber.NoError;
{
track.Pregap = 0; foreach(Track track in Tracks)
track.Indexes?.Clear(); {
} track.Pregap = 0;
track.Indexes?.Clear();
}
return ErrorNumber.NoError; return ErrorNumber.NoError;
} }

View File

@@ -726,229 +726,228 @@ public class GameBoy : IByteAddressableImage
[SuppressMessage("ReSharper", "StringLiteralTypo")] [SuppressMessage("ReSharper", "StringLiteralTypo")]
string DecodeLicensee(byte headerLicensee, byte[] headerLicenseeNew) string DecodeLicensee(byte headerLicensee, byte[] headerLicenseeNew)
{ {
if(headerLicensee == 0x33) if(headerLicensee != 0x33)
{ return headerLicensee switch
string licenseeNew = StringHandlers.CToString(headerLicenseeNew);
return licenseeNew switch
{ {
"00" => "none", 0x00 => "none",
"01" => "Nintendo R&D1", 0x01 => "nintendo",
"08" => "Capcom", 0x08 => "capcom",
"13" => "Electronic Arts", 0x09 => "hot-b",
"18" => "Hudson Soft", 0x0A => "jaleco",
"19" => "b-ai", 0x0B => "coconuts",
"20" => "kss", 0x0C => "elite systems",
"22" => "pow", 0x13 => "electronic arts",
"24" => "PCM Complete", 0x18 => "hudsonsoft",
"25" => "san-x", 0x19 => "itc entertainment",
"28" => "Kemco Japan", 0x1A => "yanoman",
"29" => "seta", 0x1D => "clary",
"30" => "Viacom", 0x1F => "virgin",
"31" => "Nintendo", 0x20 => "KSS",
"32" => "Bandai", 0x24 => "pcm complete",
"33" => "Ocean / Acclaim", 0x25 => "san-x",
"34" => "Konami", 0x28 => "kotobuki systems",
"35" => "Hector", 0x29 => "seta",
"37" => "Taito", 0x30 => "infogrames",
"38" => "Hudson", 0x31 => "nintendo",
"39" => "Banpresto", 0x32 => "bandai",
"41" => "Ubi Soft", 0x33 => "'''GBC - see above'''",
"42" => "Atlus", 0x34 => "konami",
"44" => "Malibu", 0x35 => "hector",
"46" => "angel", 0x38 => "Capcom",
"47" => "Bullet -Proof", 0x39 => "Banpresto",
"49" => "irem", 0x3C => "*entertainment i",
"50" => "Absolute", 0x3E => "gremlin",
"51" => "Acclaim", 0x41 => "Ubisoft",
"52" => "Activision", 0x42 => "Atlus",
"53" => "American sammy", 0x44 => "Malibu",
"54" => "Konami", 0x46 => "angel",
"55" => "Hi tech entertainment", 0x47 => "spectrum holoby",
"56" => "LJN", 0x49 => "irem",
"57" => "Matchbox", 0x4A => "virgin",
"58" => "Mattel", 0x4D => "malibu",
"59" => "Milton Bradley", 0x4F => "u.s. gold",
"60" => "Titus", 0x50 => "absolute",
"61" => "Virgin", 0x51 => "acclaim",
"64" => "LucasArts", 0x52 => "activision",
"67" => "Ocean", 0x53 => "american sammy",
"69" => "Electronic Arts", 0x54 => "gametek",
"70" => "Infogrames", 0x55 => "park place",
"71" => "Interplay", 0x56 => "ljn",
"72" => "Brøderbund", 0x57 => "matchbox",
"73" => "sculptured", 0x59 => "milton bradley",
"75" => "sci", 0x5A => "mindscape",
"78" => "THQ", 0x5B => "romstar",
"79" => "Accolade", 0x5C => "naxat soft",
"80" => "misawa", 0x5D => "tradewest",
"83" => "lozc", 0x60 => "titus",
"86" => "tokuma shoten i", 0x61 => "virgin",
"87" => "tsukuda ori", 0x67 => "ocean",
"91" => "Chunsoft", 0x69 => "electronic arts",
"92" => "Video system", 0x6E => "elite systems",
"93" => "Ocean / Acclaim", 0x6F => "electro brain",
"95" => "Varie", 0x70 => "Infogrammes",
"96" => "Yonezawa / s'pal", 0x71 => "Interplay",
"97" => "Kaneko", 0x72 => "broderbund",
"99" => "Pack in soft", 0x73 => "sculptered soft",
"A4" => "Konami", 0x75 => "the sales curve",
0x78 => "t*hq",
0x79 => "accolade",
0x7A => "triffix entertainment",
0x7C => "microprose",
0x7F => "kemco",
0x80 => "misawa entertainment",
0x83 => "lozc",
0x86 => "tokuma shoten intermedia",
0x8B => "bullet-proof software",
0x8C => "vic tokai",
0x8E => "ape",
0x8F => "i'max",
0x91 => "chun soft",
0x92 => "video system",
0x93 => "tsuburava",
0x95 => "varie",
0x96 => "yonezawa/s'pal",
0x97 => "kaneko",
0x99 => "arc",
0x9A => "nihon bussan",
0x9B => "Tecmo",
0x9C => "imagineer",
0x9D => "Banpresto",
0x9F => "nova",
0xA1 => "Hori electric",
0xA2 => "Bandai",
0xA4 => "Konami",
0xA6 => "kawada",
0xA7 => "takara",
0xA9 => "technos japan",
0xAA => "broderbund",
0xAC => "Toei animation",
0xAD => "toho",
0xAF => "Namco",
0xB0 => "Acclaim",
0xB1 => "ascii or nexoft",
0xB2 => "Bandai",
0xB4 => "Enix",
0xB6 => "HAL",
0xB7 => "SNK",
0xB9 => "pony canyon",
0xBA => "*culture brain o",
0xBB => "Sunsoft",
0xBD => "Sony imagesoft",
0xBF => "sammy",
0xC0 => "Taito",
0xC2 => "Kemco",
0xC3 => "Squaresoft",
0xC4 => "tokuma shoten intermedia",
0xC5 => "data east",
0xC6 => "tonkin house",
0xC8 => "koei",
0xC9 => "ufl",
0xCA => "ultra",
0xCB => "vap",
0xCC => "use",
0xCD => "meldac",
0xCE => "*pony canyon or",
0xCF => "angel",
0xD0 => "Taito",
0xD1 => "sofel",
0xD2 => "quest",
0xD3 => "sigma enterprises",
0xD4 => "ask kodansha",
0xD6 => "naxat soft",
0xD7 => "copya systems",
0xD9 => "Banpresto",
0xDA => "tomy",
0xDB => "ljn",
0xDD => "ncs",
0xDE => "human",
0xDF => "altron",
0xE0 => "jaleco",
0xE1 => "towachiki",
0xE2 => "uutaka",
0xE3 => "varie",
0xE5 => "epoch",
0xE7 => "athena",
0xE8 => "asmik",
0xE9 => "natsume",
0xEA => "king records",
0xEB => "atlus",
0xEC => "Epic/Sony records",
0xEE => "igs",
0xF0 => "a wave",
0xF3 => "extreme entertainment",
0xFF => "ljn",
_ => "Unknown" _ => "Unknown"
}; };
}
return headerLicensee switch string licenseeNew = StringHandlers.CToString(headerLicenseeNew);
return licenseeNew switch
{ {
0x00 => "none", "00" => "none",
0x01 => "nintendo", "01" => "Nintendo R&D1",
0x08 => "capcom", "08" => "Capcom",
0x09 => "hot-b", "13" => "Electronic Arts",
0x0A => "jaleco", "18" => "Hudson Soft",
0x0B => "coconuts", "19" => "b-ai",
0x0C => "elite systems", "20" => "kss",
0x13 => "electronic arts", "22" => "pow",
0x18 => "hudsonsoft", "24" => "PCM Complete",
0x19 => "itc entertainment", "25" => "san-x",
0x1A => "yanoman", "28" => "Kemco Japan",
0x1D => "clary", "29" => "seta",
0x1F => "virgin", "30" => "Viacom",
0x20 => "KSS", "31" => "Nintendo",
0x24 => "pcm complete", "32" => "Bandai",
0x25 => "san-x", "33" => "Ocean / Acclaim",
0x28 => "kotobuki systems", "34" => "Konami",
0x29 => "seta", "35" => "Hector",
0x30 => "infogrames", "37" => "Taito",
0x31 => "nintendo", "38" => "Hudson",
0x32 => "bandai", "39" => "Banpresto",
0x33 => "'''GBC - see above'''", "41" => "Ubi Soft",
0x34 => "konami", "42" => "Atlus",
0x35 => "hector", "44" => "Malibu",
0x38 => "Capcom", "46" => "angel",
0x39 => "Banpresto", "47" => "Bullet -Proof",
0x3C => "*entertainment i", "49" => "irem",
0x3E => "gremlin", "50" => "Absolute",
0x41 => "Ubisoft", "51" => "Acclaim",
0x42 => "Atlus", "52" => "Activision",
0x44 => "Malibu", "53" => "American sammy",
0x46 => "angel", "54" => "Konami",
0x47 => "spectrum holoby", "55" => "Hi tech entertainment",
0x49 => "irem", "56" => "LJN",
0x4A => "virgin", "57" => "Matchbox",
0x4D => "malibu", "58" => "Mattel",
0x4F => "u.s. gold", "59" => "Milton Bradley",
0x50 => "absolute", "60" => "Titus",
0x51 => "acclaim", "61" => "Virgin",
0x52 => "activision", "64" => "LucasArts",
0x53 => "american sammy", "67" => "Ocean",
0x54 => "gametek", "69" => "Electronic Arts",
0x55 => "park place", "70" => "Infogrames",
0x56 => "ljn", "71" => "Interplay",
0x57 => "matchbox", "72" => "Brøderbund",
0x59 => "milton bradley", "73" => "sculptured",
0x5A => "mindscape", "75" => "sci",
0x5B => "romstar", "78" => "THQ",
0x5C => "naxat soft", "79" => "Accolade",
0x5D => "tradewest", "80" => "misawa",
0x60 => "titus", "83" => "lozc",
0x61 => "virgin", "86" => "tokuma shoten i",
0x67 => "ocean", "87" => "tsukuda ori",
0x69 => "electronic arts", "91" => "Chunsoft",
0x6E => "elite systems", "92" => "Video system",
0x6F => "electro brain", "93" => "Ocean / Acclaim",
0x70 => "Infogrammes", "95" => "Varie",
0x71 => "Interplay", "96" => "Yonezawa / s'pal",
0x72 => "broderbund", "97" => "Kaneko",
0x73 => "sculptered soft", "99" => "Pack in soft",
0x75 => "the sales curve", "A4" => "Konami",
0x78 => "t*hq",
0x79 => "accolade",
0x7A => "triffix entertainment",
0x7C => "microprose",
0x7F => "kemco",
0x80 => "misawa entertainment",
0x83 => "lozc",
0x86 => "tokuma shoten intermedia",
0x8B => "bullet-proof software",
0x8C => "vic tokai",
0x8E => "ape",
0x8F => "i'max",
0x91 => "chun soft",
0x92 => "video system",
0x93 => "tsuburava",
0x95 => "varie",
0x96 => "yonezawa/s'pal",
0x97 => "kaneko",
0x99 => "arc",
0x9A => "nihon bussan",
0x9B => "Tecmo",
0x9C => "imagineer",
0x9D => "Banpresto",
0x9F => "nova",
0xA1 => "Hori electric",
0xA2 => "Bandai",
0xA4 => "Konami",
0xA6 => "kawada",
0xA7 => "takara",
0xA9 => "technos japan",
0xAA => "broderbund",
0xAC => "Toei animation",
0xAD => "toho",
0xAF => "Namco",
0xB0 => "Acclaim",
0xB1 => "ascii or nexoft",
0xB2 => "Bandai",
0xB4 => "Enix",
0xB6 => "HAL",
0xB7 => "SNK",
0xB9 => "pony canyon",
0xBA => "*culture brain o",
0xBB => "Sunsoft",
0xBD => "Sony imagesoft",
0xBF => "sammy",
0xC0 => "Taito",
0xC2 => "Kemco",
0xC3 => "Squaresoft",
0xC4 => "tokuma shoten intermedia",
0xC5 => "data east",
0xC6 => "tonkin house",
0xC8 => "koei",
0xC9 => "ufl",
0xCA => "ultra",
0xCB => "vap",
0xCC => "use",
0xCD => "meldac",
0xCE => "*pony canyon or",
0xCF => "angel",
0xD0 => "Taito",
0xD1 => "sofel",
0xD2 => "quest",
0xD3 => "sigma enterprises",
0xD4 => "ask kodansha",
0xD6 => "naxat soft",
0xD7 => "copya systems",
0xD9 => "Banpresto",
0xDA => "tomy",
0xDB => "ljn",
0xDD => "ncs",
0xDE => "human",
0xDF => "altron",
0xE0 => "jaleco",
0xE1 => "towachiki",
0xE2 => "uutaka",
0xE3 => "varie",
0xE5 => "epoch",
0xE7 => "athena",
0xE8 => "asmik",
0xE9 => "natsume",
0xEA => "king records",
0xEB => "atlus",
0xEC => "Epic/Sony records",
0xEE => "igs",
0xF0 => "a wave",
0xF3 => "extreme entertainment",
0xFF => "ljn",
_ => "Unknown" _ => "Unknown"
}; };
} }
static uint DecodeRomSize(byte headerRomType) => headerRomType switch static uint DecodeRomSize(byte headerRomType) => headerRomType switch

View File

@@ -83,12 +83,12 @@ public sealed partial class Gdi
if(lineNumber == 1) if(lineNumber == 1)
{ {
if(!int.TryParse(line, out _)) if(int.TryParse(line, out _))
{ continue;
AaruConsole.ErrorWriteLine("Not a correct Dreamcast GDI image");
return ErrorNumber.InvalidArgument; AaruConsole.ErrorWriteLine("Not a correct Dreamcast GDI image");
}
return ErrorNumber.InvalidArgument;
} }
else else
{ {

View File

@@ -168,101 +168,101 @@ public sealed class Xbox : IPartition
{ {
errno = imagePlugin.ReadSector((ulong)(XBOX_360DATA_OFF / imagePlugin.Info.SectorSize), out sector); errno = imagePlugin.ReadSector((ulong)(XBOX_360DATA_OFF / imagePlugin.Info.SectorSize), out sector);
if(errno == ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
return false;
temp = BitConverter.ToUInt32(sector, 0);
if(temp != XBOX_CIGAM)
return false;
var securityPart = new Partition
{ {
temp = BitConverter.ToUInt32(sector, 0); Description = "Security sectors",
Size = XBOX360_SECURITY_SECTOR_LEN,
Length = (ulong)(XBOX360_SECURITY_SECTOR_LEN / imagePlugin.Info.SectorSize),
Sequence = 1,
Offset = XBOX360_SECURITY_SECTOR_OFF,
Start = (ulong)(XBOX360_SECURITY_SECTOR_OFF / imagePlugin.Info.SectorSize),
Scheme = Name
};
if(temp != XBOX_CIGAM) var sysCachePart = new Partition
return false; {
Description = "System cache",
Size = XBOX360_SYSTEM_CACHE_LEN,
Length = (ulong)(XBOX360_SYSTEM_CACHE_LEN / imagePlugin.Info.SectorSize),
Sequence = 2,
Offset = XBOX360_SYSTEM_CACHE_OFF,
Start = (ulong)(XBOX360_SYSTEM_CACHE_OFF / imagePlugin.Info.SectorSize),
Scheme = Name
};
var securityPart = new Partition var gameCachePart = new Partition
{ {
Description = "Security sectors", Description = "Game cache",
Size = XBOX360_SECURITY_SECTOR_LEN, Size = XBOX360_GAME_CACHE_LEN,
Length = (ulong)(XBOX360_SECURITY_SECTOR_LEN / imagePlugin.Info.SectorSize), Length = (ulong)(XBOX360_GAME_CACHE_LEN / imagePlugin.Info.SectorSize),
Sequence = 1, Sequence = 3,
Offset = XBOX360_SECURITY_SECTOR_OFF, Offset = XBOX360_GAME_CACHE_OFF,
Start = (ulong)(XBOX360_SECURITY_SECTOR_OFF / imagePlugin.Info.SectorSize), Start = (ulong)(XBOX360_GAME_CACHE_OFF / imagePlugin.Info.SectorSize),
Scheme = Name Scheme = Name
}; };
var sysCachePart = new Partition var sysExtPart = new Partition
{ {
Description = "System cache", Description = "System volume",
Size = XBOX360_SYSTEM_CACHE_LEN, Size = XBOX368_SYS_EXT_LEN,
Length = (ulong)(XBOX360_SYSTEM_CACHE_LEN / imagePlugin.Info.SectorSize), Length = (ulong)(XBOX368_SYS_EXT_LEN / imagePlugin.Info.SectorSize),
Sequence = 2, Sequence = 4,
Offset = XBOX360_SYSTEM_CACHE_OFF, Offset = XBOX368_SYS_EXT_OFF,
Start = (ulong)(XBOX360_SYSTEM_CACHE_OFF / imagePlugin.Info.SectorSize), Start = (ulong)(XBOX368_SYS_EXT_OFF / imagePlugin.Info.SectorSize),
Scheme = Name Scheme = Name
}; };
var gameCachePart = new Partition var sysExt2Part = new Partition
{ {
Description = "Game cache", Description = "System volume 2",
Size = XBOX360_GAME_CACHE_LEN, Size = XBOX360_SYS_EXT2_LEN,
Length = (ulong)(XBOX360_GAME_CACHE_LEN / imagePlugin.Info.SectorSize), Length = (ulong)(XBOX360_SYS_EXT2_LEN / imagePlugin.Info.SectorSize),
Sequence = 3, Sequence = 5,
Offset = XBOX360_GAME_CACHE_OFF, Offset = XBOX360_SYS_EXT2_OFF,
Start = (ulong)(XBOX360_GAME_CACHE_OFF / imagePlugin.Info.SectorSize), Start = (ulong)(XBOX360_SYS_EXT2_OFF / imagePlugin.Info.SectorSize),
Scheme = Name Scheme = Name
}; };
var sysExtPart = new Partition var xbox1Part = new Partition
{ {
Description = "System volume", Description = "Xbox backwards compatibility",
Size = XBOX368_SYS_EXT_LEN, Size = XBOX360_COMPAT_LEN,
Length = (ulong)(XBOX368_SYS_EXT_LEN / imagePlugin.Info.SectorSize), Length = (ulong)(XBOX360_COMPAT_LEN / imagePlugin.Info.SectorSize),
Sequence = 4, Sequence = 6,
Offset = XBOX368_SYS_EXT_OFF, Offset = XBOX360_COMPAT_OFF,
Start = (ulong)(XBOX368_SYS_EXT_OFF / imagePlugin.Info.SectorSize), Start = (ulong)(XBOX360_COMPAT_OFF / imagePlugin.Info.SectorSize),
Scheme = Name Scheme = Name
}; };
var sysExt2Part = new Partition var dataPart = new Partition
{ {
Description = "System volume 2", Description = "Data volume",
Size = XBOX360_SYS_EXT2_LEN, Sequence = 7,
Length = (ulong)(XBOX360_SYS_EXT2_LEN / imagePlugin.Info.SectorSize), Offset = XBOX_360DATA_OFF,
Sequence = 5, Start = (ulong)(XBOX_360DATA_OFF / imagePlugin.Info.SectorSize),
Offset = XBOX360_SYS_EXT2_OFF, Scheme = Name
Start = (ulong)(XBOX360_SYS_EXT2_OFF / imagePlugin.Info.SectorSize), };
Scheme = Name
};
var xbox1Part = new Partition dataPart.Length = imagePlugin.Info.Sectors - dataPart.Start;
{ dataPart.Size = dataPart.Length * imagePlugin.Info.SectorSize;
Description = "Xbox backwards compatibility",
Size = XBOX360_COMPAT_LEN,
Length = (ulong)(XBOX360_COMPAT_LEN / imagePlugin.Info.SectorSize),
Sequence = 6,
Offset = XBOX360_COMPAT_OFF,
Start = (ulong)(XBOX360_COMPAT_OFF / imagePlugin.Info.SectorSize),
Scheme = Name
};
var dataPart = new Partition partitions.Add(securityPart);
{ partitions.Add(sysCachePart);
Description = "Data volume", partitions.Add(gameCachePart);
Sequence = 7, partitions.Add(sysExtPart);
Offset = XBOX_360DATA_OFF, partitions.Add(sysExt2Part);
Start = (ulong)(XBOX_360DATA_OFF / imagePlugin.Info.SectorSize), partitions.Add(xbox1Part);
Scheme = Name partitions.Add(dataPart);
};
dataPart.Length = imagePlugin.Info.Sectors - dataPart.Start; return true;
dataPart.Size = dataPart.Length * imagePlugin.Info.SectorSize;
partitions.Add(securityPart);
partitions.Add(sysCachePart);
partitions.Add(gameCachePart);
partitions.Add(sysExtPart);
partitions.Add(sysExt2Part);
partitions.Add(xbox1Part);
partitions.Add(dataPart);
return true;
}
} }
return false; return false;

View File

@@ -385,35 +385,35 @@ sealed class DecodeCommand : Command
break; break;
} }
if(sectorTags) if(!sectorTags)
return (int)ErrorNumber.NoError;
if(length.ToLowerInvariant() == "all") {}
else
{ {
if(length.ToLowerInvariant() == "all") {} if(!ulong.TryParse(length, out ulong _))
else
{ {
if(!ulong.TryParse(length, out ulong _)) AaruConsole.WriteLine("Value \"{0}\" is not a valid number for length.", length);
{ AaruConsole.WriteLine("Not decoding sectors tags");
AaruConsole.WriteLine("Value \"{0}\" is not a valid number for length.", length);
AaruConsole.WriteLine("Not decoding sectors tags");
return 3; return 3;
}
} }
if(inputFormat.Info.ReadableSectorTags.Count == 0)
AaruConsole.WriteLine("There are no sector tags in chosen disc image.");
else
foreach(SectorTagType tag in inputFormat.Info.ReadableSectorTags)
switch(tag)
{
default:
AaruConsole.WriteLine("Decoder for disk tag type \"{0}\" not yet implemented, sorry.", tag);
break;
}
// TODO: Not implemented
} }
if(inputFormat.Info.ReadableSectorTags.Count == 0)
AaruConsole.WriteLine("There are no sector tags in chosen disc image.");
else
foreach(SectorTagType tag in inputFormat.Info.ReadableSectorTags)
switch(tag)
{
default:
AaruConsole.WriteLine("Decoder for disk tag type \"{0}\" not yet implemented, sorry.", tag);
break;
}
// TODO: Not implemented
return (int)ErrorNumber.NoError; return (int)ErrorNumber.NoError;
} }
} }

View File

@@ -173,10 +173,12 @@ sealed class VerifyCommand : Command
return (int)ErrorNumber.NotVerifiable; return (int)ErrorNumber.NotVerifiable;
} }
TimeSpan checkTime;
if(verifyDisc && verifiableImage != null) if(verifyDisc && verifiableImage != null)
{ {
bool? discCheckStatus = null; bool? discCheckStatus = null;
TimeSpan checkTime = new(); checkTime = new TimeSpan();
Spectre.ProgressSingleSpinner(ctx => Spectre.ProgressSingleSpinner(ctx =>
{ {
@@ -208,110 +210,59 @@ sealed class VerifyCommand : Command
AaruConsole.VerboseWriteLine("Checking disc image checksums took {0} seconds", checkTime.TotalSeconds); AaruConsole.VerboseWriteLine("Checking disc image checksums took {0} seconds", checkTime.TotalSeconds);
} }
if(verifySectors) if(!verifySectors)
return correctImage switch
{
null => (int)ErrorNumber.NotVerifiable,
false => (int)ErrorNumber.BadImageSectorsNotVerified,
true => (int)ErrorNumber.CorrectImageSectorsNotVerified
};
DateTime startCheck = DateTime.Now;
DateTime endCheck = startCheck;
List<ulong> failingLbas = new();
List<ulong> unknownLbas = new();
if(verifiableSectorsImage is IOpticalMediaImage { Tracks: {} } opticalMediaImage)
{ {
DateTime startCheck = DateTime.Now; List<Track> inputTracks = opticalMediaImage.Tracks;
DateTime endCheck = startCheck; ulong currentSectorAll = 0;
List<ulong> failingLbas = new();
List<ulong> unknownLbas = new();
if(verifiableSectorsImage is IOpticalMediaImage { Tracks: {} } opticalMediaImage) startCheck = DateTime.UtcNow;
{
List<Track> inputTracks = opticalMediaImage.Tracks;
ulong currentSectorAll = 0;
startCheck = DateTime.UtcNow; AnsiConsole.Progress().AutoClear(true).HideCompleted(true).
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()).
Start(ctx =>
{
ProgressTask discTask = ctx.AddTask("Checking tracks...");
discTask.MaxValue = inputTracks.Count;
AnsiConsole.Progress().AutoClear(true).HideCompleted(true). foreach(Track currentTrack in inputTracks)
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()).
Start(ctx =>
{ {
ProgressTask discTask = ctx.AddTask("Checking tracks..."); discTask.Description = $"Checking track {discTask.Value + 1} of {inputTracks.Count}";
discTask.MaxValue = inputTracks.Count;
foreach(Track currentTrack in inputTracks) ulong remainingSectors = currentTrack.EndSector - currentTrack.StartSector + 1;
{
discTask.Description =
$"Checking track {discTask.Value + 1} of {inputTracks.Count}";
ulong remainingSectors = currentTrack.EndSector - currentTrack.StartSector + 1; ulong currentSector = 0;
ulong currentSector = 0; ProgressTask trackTask = ctx.AddTask("Checking sector");
trackTask.MaxValue = remainingSectors;
ProgressTask trackTask = ctx.AddTask("Checking sector");
trackTask.MaxValue = remainingSectors;
while(remainingSectors > 0)
{
trackTask.Description = $"Checking sector {currentSectorAll} of {
inputFormat.Info.Sectors}, on track {currentTrack.Sequence}";
List<ulong> tempFailingLbas;
List<ulong> tempUnknownLbas;
if(remainingSectors < 512)
opticalMediaImage.VerifySectors(currentSector, (uint)remainingSectors,
currentTrack.Sequence, out tempFailingLbas,
out tempUnknownLbas);
else
opticalMediaImage.VerifySectors(currentSector, 512, currentTrack.Sequence,
out tempFailingLbas, out tempUnknownLbas);
failingLbas.AddRange(tempFailingLbas);
unknownLbas.AddRange(tempUnknownLbas);
if(remainingSectors < 512)
{
currentSector += remainingSectors;
currentSectorAll += remainingSectors;
trackTask.Value += remainingSectors;
remainingSectors = 0;
}
else
{
currentSector += 512;
currentSectorAll += 512;
trackTask.Value += 512;
remainingSectors -= 512;
}
}
trackTask.StopTask();
discTask.Increment(1);
}
endCheck = DateTime.UtcNow;
});
}
else if(verifiableSectorsImage != null)
{
ulong remainingSectors = inputFormat.Info.Sectors;
ulong currentSector = 0;
AnsiConsole.Progress().AutoClear(true).HideCompleted(true).
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()).
Start(ctx =>
{
ProgressTask diskTask = ctx.AddTask("Checking sectors...");
diskTask.MaxValue = inputFormat.Info.Sectors;
startCheck = DateTime.UtcNow;
while(remainingSectors > 0) while(remainingSectors > 0)
{ {
diskTask.Description = trackTask.Description = $"Checking sector {currentSectorAll} of {
$"Checking sector {currentSector} of {inputFormat.Info.Sectors}"; inputFormat.Info.Sectors}, on track {currentTrack.Sequence}";
List<ulong> tempFailingLbas; List<ulong> tempFailingLbas;
List<ulong> tempUnknownLbas; List<ulong> tempUnknownLbas;
if(remainingSectors < 512) if(remainingSectors < 512)
verifiableSectorsImage.VerifySectors(currentSector, (uint)remainingSectors, opticalMediaImage.VerifySectors(currentSector, (uint)remainingSectors,
out tempFailingLbas, out tempUnknownLbas); currentTrack.Sequence, out tempFailingLbas,
out tempUnknownLbas);
else else
verifiableSectorsImage.VerifySectors(currentSector, 512, out tempFailingLbas, opticalMediaImage.VerifySectors(currentSector, 512, currentTrack.Sequence,
out tempUnknownLbas); out tempFailingLbas, out tempUnknownLbas);
failingLbas.AddRange(tempFailingLbas); failingLbas.AddRange(tempFailingLbas);
@@ -320,64 +271,118 @@ sealed class VerifyCommand : Command
if(remainingSectors < 512) if(remainingSectors < 512)
{ {
currentSector += remainingSectors; currentSector += remainingSectors;
diskTask.Value += remainingSectors; currentSectorAll += remainingSectors;
trackTask.Value += remainingSectors;
remainingSectors = 0; remainingSectors = 0;
} }
else else
{ {
currentSector += 512; currentSector += 512;
diskTask.Value += 512; currentSectorAll += 512;
trackTask.Value += 512;
remainingSectors -= 512; remainingSectors -= 512;
} }
} }
endCheck = DateTime.UtcNow; trackTask.StopTask();
}); discTask.Increment(1);
} }
TimeSpan checkTime = endCheck - startCheck; endCheck = DateTime.UtcNow;
});
if(unknownLbas.Count > 0)
AaruConsole.WriteLine("There is at least one sector that does not contain a checksum");
if(failingLbas.Count > 0)
AaruConsole.WriteLine("There is at least one sector with incorrect checksum or errors");
if(unknownLbas.Count == 0 &&
failingLbas.Count == 0)
AaruConsole.WriteLine("All sector checksums are correct");
AaruConsole.VerboseWriteLine("Checking sector checksums took {0} seconds", checkTime.TotalSeconds);
if(verbose)
{
AaruConsole.VerboseWriteLine("[red]LBAs with error:[/]");
if(failingLbas.Count == (int)inputFormat.Info.Sectors)
AaruConsole.VerboseWriteLine("\t[red]all sectors.[/]");
else
foreach(ulong t in failingLbas)
AaruConsole.VerboseWriteLine("\t{0}", t);
AaruConsole.WriteLine("[yellow3_1]LBAs without checksum:[/]");
if(unknownLbas.Count == (int)inputFormat.Info.Sectors)
AaruConsole.VerboseWriteLine("\t[yellow3_1]all sectors.[/]");
else
foreach(ulong t in unknownLbas)
AaruConsole.VerboseWriteLine("\t{0}", t);
}
AaruConsole.WriteLine("[italic]Total sectors...........[/] {0}", inputFormat.Info.Sectors);
AaruConsole.WriteLine("[italic]Total errors............[/] {0}", failingLbas.Count);
AaruConsole.WriteLine("[italic]Total unknowns..........[/] {0}", unknownLbas.Count);
AaruConsole.WriteLine("[italic]Total errors+unknowns...[/] {0}", failingLbas.Count + unknownLbas.Count);
if(failingLbas.Count > 0)
correctSectors = false;
else if((ulong)unknownLbas.Count < inputFormat.Info.Sectors)
correctSectors = true;
} }
else if(verifiableSectorsImage != null)
{
ulong remainingSectors = inputFormat.Info.Sectors;
ulong currentSector = 0;
AnsiConsole.Progress().AutoClear(true).HideCompleted(true).
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()).
Start(ctx =>
{
ProgressTask diskTask = ctx.AddTask("Checking sectors...");
diskTask.MaxValue = inputFormat.Info.Sectors;
startCheck = DateTime.UtcNow;
while(remainingSectors > 0)
{
diskTask.Description = $"Checking sector {currentSector} of {inputFormat.Info.Sectors}";
List<ulong> tempFailingLbas;
List<ulong> tempUnknownLbas;
if(remainingSectors < 512)
verifiableSectorsImage.VerifySectors(currentSector, (uint)remainingSectors,
out tempFailingLbas, out tempUnknownLbas);
else
verifiableSectorsImage.VerifySectors(currentSector, 512, out tempFailingLbas,
out tempUnknownLbas);
failingLbas.AddRange(tempFailingLbas);
unknownLbas.AddRange(tempUnknownLbas);
if(remainingSectors < 512)
{
currentSector += remainingSectors;
diskTask.Value += remainingSectors;
remainingSectors = 0;
}
else
{
currentSector += 512;
diskTask.Value += 512;
remainingSectors -= 512;
}
}
endCheck = DateTime.UtcNow;
});
}
checkTime = endCheck - startCheck;
if(unknownLbas.Count > 0)
AaruConsole.WriteLine("There is at least one sector that does not contain a checksum");
if(failingLbas.Count > 0)
AaruConsole.WriteLine("There is at least one sector with incorrect checksum or errors");
if(unknownLbas.Count == 0 &&
failingLbas.Count == 0)
AaruConsole.WriteLine("All sector checksums are correct");
AaruConsole.VerboseWriteLine("Checking sector checksums took {0} seconds", checkTime.TotalSeconds);
if(verbose)
{
AaruConsole.VerboseWriteLine("[red]LBAs with error:[/]");
if(failingLbas.Count == (int)inputFormat.Info.Sectors)
AaruConsole.VerboseWriteLine("\t[red]all sectors.[/]");
else
foreach(ulong t in failingLbas)
AaruConsole.VerboseWriteLine("\t{0}", t);
AaruConsole.WriteLine("[yellow3_1]LBAs without checksum:[/]");
if(unknownLbas.Count == (int)inputFormat.Info.Sectors)
AaruConsole.VerboseWriteLine("\t[yellow3_1]all sectors.[/]");
else
foreach(ulong t in unknownLbas)
AaruConsole.VerboseWriteLine("\t{0}", t);
}
AaruConsole.WriteLine("[italic]Total sectors...........[/] {0}", inputFormat.Info.Sectors);
AaruConsole.WriteLine("[italic]Total errors............[/] {0}", failingLbas.Count);
AaruConsole.WriteLine("[italic]Total unknowns..........[/] {0}", unknownLbas.Count);
AaruConsole.WriteLine("[italic]Total errors+unknowns...[/] {0}", failingLbas.Count + unknownLbas.Count);
if(failingLbas.Count > 0)
correctSectors = false;
else if((ulong)unknownLbas.Count < inputFormat.Info.Sectors)
correctSectors = true;
return correctImage switch return correctImage switch
{ {