Add test for reading Lead-Out using a trap disc.

This commit is contained in:
2020-07-09 21:35:31 +01:00
parent 813cd27a5d
commit ab124c8056
4 changed files with 546 additions and 0 deletions

View File

@@ -2196,6 +2196,7 @@
<e p="SCSI.cs" t="Include" /> <e p="SCSI.cs" t="Include" />
<e p="SCSI_MMC" t="Include"> <e p="SCSI_MMC" t="Include">
<e p="GdRom.cs" t="Include" /> <e p="GdRom.cs" t="Include" />
<e p="LeadOutTrap.cs" t="Include" />
<e p="MediaTek.cs" t="Include" /> <e p="MediaTek.cs" t="Include" />
<e p="SCSI_MMC.cs" t="Include" /> <e p="SCSI_MMC.cs" t="Include" />
</e> </e>

View File

@@ -54,6 +54,7 @@
<Compile Include="ATA.cs" /> <Compile Include="ATA.cs" />
<Compile Include="NVMe.cs" /> <Compile Include="NVMe.cs" />
<Compile Include="SCSI_MMC\GdRom.cs" /> <Compile Include="SCSI_MMC\GdRom.cs" />
<Compile Include="SCSI_MMC\LeadOutTrap.cs" />
<Compile Include="SCSI_MMC\MediaTek.cs" /> <Compile Include="SCSI_MMC\MediaTek.cs" />
<Compile Include="SCSI_MMC\SCSI_MMC.cs" /> <Compile Include="SCSI_MMC\SCSI_MMC.cs" />
<Compile Include="SecureDigital.cs" /> <Compile Include="SecureDigital.cs" />

View File

@@ -0,0 +1,539 @@
using System.Linq;
using System.Threading;
using Aaru.Console;
using Aaru.Decoders.CD;
using Aaru.Decoders.SCSI;
using Aaru.Devices;
namespace Aaru.Tests.Devices
{
internal static partial class ScsiMmc
{
static void ReadLeadOutUsingTrapDisc(string devPath, Device dev)
{
string strDev;
int item;
bool tocIsNotBcd = false;
parameters:
while(true)
{
System.Console.Clear();
AaruConsole.WriteLine("Device: {0}", devPath);
AaruConsole.WriteLine();
AaruConsole.WriteLine("Choose what to do:");
AaruConsole.WriteLine("1.- Try to read Lead-Out using a trap disc.");
AaruConsole.WriteLine("0.- Return to special SCSI MultiMedia Commands menu.");
strDev = System.Console.ReadLine();
if(!int.TryParse(strDev, out item))
{
AaruConsole.WriteLine("Not a number. Press any key to continue...");
System.Console.ReadKey();
continue;
}
switch(item)
{
case 0:
AaruConsole.WriteLine("Returning to special SCSI MultiMedia Commands menu...");
return;
case 1: goto start;
}
}
start:
System.Console.Clear();
AaruConsole.WriteLine("Ejecting disc...");
dev.AllowMediumRemoval(out _, dev.Timeout, out _);
dev.EjectTray(out _, dev.Timeout, out _);
AaruConsole.WriteLine("Please insert a data only disc inside...");
AaruConsole.WriteLine("Press any key to continue...");
System.Console.ReadLine();
AaruConsole.WriteLine("Waiting 5 seconds...");
Thread.Sleep(5000);
AaruConsole.WriteLine("Sending READ FULL TOC to the device...");
dev.ScsiTestUnitReady(out _, dev.Timeout, out _);
bool sense = dev.ReadRawToc(out byte[] buffer, out byte[] senseBuffer, 1, dev.Timeout, out _);
if(sense)
{
AaruConsole.WriteLine("READ FULL TOC failed...");
AaruConsole.WriteLine("Press any key to continue...");
System.Console.ReadLine();
goto parameters;
}
FullTOC.CDFullTOC? decodedToc = FullTOC.Decode(buffer);
if(decodedToc is null)
{
AaruConsole.WriteLine("Could not decode TOC...");
AaruConsole.WriteLine("Press any key to continue...");
System.Console.ReadLine();
goto parameters;
}
FullTOC.CDFullTOC toc = decodedToc.Value;
FullTOC.TrackDataDescriptor leadOutTrack = toc.TrackDescriptors.FirstOrDefault(t => t.POINT == 0xA2);
if(leadOutTrack.POINT != 0xA2)
{
AaruConsole.WriteLine("Cannot find lead-out...");
AaruConsole.WriteLine("Press any key to continue...");
System.Console.ReadLine();
goto parameters;
}
int min = ((leadOutTrack.PMIN >> 4) * 10) + (leadOutTrack.PMIN & 0x0F);
int sec = ((leadOutTrack.PSEC >> 4) * 10) + (leadOutTrack.PSEC & 0x0F);
int frame = ((leadOutTrack.PFRAME >> 4) * 10) + (leadOutTrack.PFRAME & 0x0F);
int sectors = ((min * 60 * 75) + (sec * 75) + frame) - 150;
AaruConsole.WriteLine("Data disc shows {0} sectors...", sectors);
AaruConsole.WriteLine("Ejecting disc...");
dev.AllowMediumRemoval(out _, dev.Timeout, out _);
dev.EjectTray(out _, dev.Timeout, out _);
AaruConsole.WriteLine("Please insert the trap disc inside...");
AaruConsole.WriteLine("Press any key to continue...");
System.Console.ReadLine();
AaruConsole.WriteLine("Waiting 5 seconds...");
Thread.Sleep(5000);
AaruConsole.WriteLine("Sending READ FULL TOC to the device...");
dev.ScsiTestUnitReady(out _, dev.Timeout, out _);
sense = dev.ReadRawToc(out buffer, out senseBuffer, 1, dev.Timeout, out _);
if(sense)
{
AaruConsole.WriteLine("READ FULL TOC failed...");
AaruConsole.WriteLine("Press any key to continue...");
System.Console.ReadLine();
goto parameters;
}
decodedToc = FullTOC.Decode(buffer);
if(decodedToc is null)
{
AaruConsole.WriteLine("Could not decode TOC...");
AaruConsole.WriteLine("Press any key to continue...");
System.Console.ReadLine();
goto parameters;
}
toc = decodedToc.Value;
leadOutTrack = toc.TrackDescriptors.FirstOrDefault(t => t.POINT == 0xA2);
if(leadOutTrack.POINT != 0xA2)
{
AaruConsole.WriteLine("Cannot find lead-out...");
AaruConsole.WriteLine("Press any key to continue...");
System.Console.ReadLine();
goto parameters;
}
min = 0;
if(leadOutTrack.PMIN == 122)
tocIsNotBcd = true;
if(leadOutTrack.PMIN >= 0xA0 &&
!tocIsNotBcd)
{
min += 90;
leadOutTrack.PMIN -= 0x90;
}
if(tocIsNotBcd)
{
min = leadOutTrack.PMIN;
sec = leadOutTrack.PSEC;
frame = leadOutTrack.PFRAME;
}
else
{
min += ((leadOutTrack.PMIN >> 4) * 10) + (leadOutTrack.PMIN & 0x0F);
sec = ((leadOutTrack.PSEC >> 4) * 10) + (leadOutTrack.PSEC & 0x0F);
frame = ((leadOutTrack.PFRAME >> 4) * 10) + (leadOutTrack.PFRAME & 0x0F);
}
int trapSectors = ((min * 60 * 75) + (sec * 75) + frame) - 150;
AaruConsole.WriteLine("Trap disc shows {0} sectors...", trapSectors);
if(trapSectors < sectors + 100)
{
AaruConsole.WriteLine("Trap disc doesn't have enough sectors...");
AaruConsole.WriteLine("Press any key to continue...");
System.Console.ReadLine();
goto parameters;
}
AaruConsole.WriteLine("Stopping motor...");
dev.StopUnit(out _, dev.Timeout, out _);
AaruConsole.WriteLine("Please MANUALLY get the trap disc out and put the data disc back inside...");
AaruConsole.WriteLine("Press any key to continue...");
System.Console.ReadLine();
AaruConsole.WriteLine("Waiting 5 seconds...");
Thread.Sleep(5000);
AaruConsole.WriteLine("Sending READ FULL TOC to the device...");
sense = dev.ReadRawToc(out buffer, out senseBuffer, 1, dev.Timeout, out _);
// Just try again to clear any "disc changed" events
if(sense)
sense = dev.ReadRawToc(out buffer, out senseBuffer, 1, dev.Timeout, out _);
if(sense)
{
AaruConsole.WriteLine("READ FULL TOC failed...");
AaruConsole.WriteLine("Press any key to continue...");
System.Console.ReadLine();
goto parameters;
}
decodedToc = FullTOC.Decode(buffer);
if(decodedToc is null)
{
AaruConsole.WriteLine("Could not decode TOC...");
AaruConsole.WriteLine("Press any key to continue...");
System.Console.ReadLine();
goto parameters;
}
toc = decodedToc.Value;
FullTOC.TrackDataDescriptor newLeadOutTrack = toc.TrackDescriptors.FirstOrDefault(t => t.POINT == 0xA2);
if(newLeadOutTrack.POINT != 0xA2)
{
AaruConsole.WriteLine("Cannot find lead-out...");
AaruConsole.WriteLine("Press any key to continue...");
System.Console.ReadLine();
goto parameters;
}
if(newLeadOutTrack.PMIN >= 0xA0 &&
!tocIsNotBcd)
newLeadOutTrack.PMIN -= 0x90;
if(newLeadOutTrack.PMIN != leadOutTrack.PMIN ||
newLeadOutTrack.PSEC != leadOutTrack.PSEC ||
newLeadOutTrack.PFRAME != leadOutTrack.PFRAME)
{
AaruConsole.WriteLine("Lead-out has changed, this drive does not support hot swapping discs...");
AaruConsole.WriteLine("Press any key to continue...");
System.Console.ReadLine();
goto parameters;
}
AaruConsole.Write("Reading LBA {0}... ", sectors + 5);
bool dataResult = dev.ReadCd(out byte[] dataBuffer, out byte[] dataSense, (uint)(sectors + 5), 2352, 1,
MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true,
true, MmcErrorField.None, MmcSubchannel.None, dev.Timeout, out _);
AaruConsole.WriteLine(dataResult ? "FAIL!" : "Success!");
AaruConsole.Write("Reading LBA {0} as audio (scrambled)... ", sectors + 5);
bool scrambledResult = dev.ReadCd(out byte[] scrambledBuffer, out byte[] scrambledSense,
(uint)(sectors + 5), 2352, 1, MmcSectorTypes.Cdda, false, false, false,
MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.None,
dev.Timeout, out _);
AaruConsole.WriteLine(scrambledResult ? "FAIL!" : "Success!");
AaruConsole.Write("Reading LBA {0}'s PQ subchannel... ", sectors + 5);
bool pqResult = dev.ReadCd(out byte[] pqBuffer, out byte[] pqSense, (uint)(sectors + 5), 16, 1,
MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, false, false,
MmcErrorField.None, MmcSubchannel.Q16, dev.Timeout, out _);
if(pqResult)
pqResult = dev.ReadCd(out pqBuffer, out pqSense, (uint)(sectors + 5), 16, 1, MmcSectorTypes.AllTypes,
false, false, false, MmcHeaderCodes.None, false, false, MmcErrorField.None,
MmcSubchannel.Q16, dev.Timeout, out _);
AaruConsole.WriteLine(pqResult ? "FAIL!" : "Success!");
AaruConsole.Write("Reading LBA {0}'s PQ subchannel... ", sectors + 5);
bool rwResult = dev.ReadCd(out byte[] rwBuffer, out byte[] rwSense, (uint)(sectors + 5), 16, 1,
MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, false, false,
MmcErrorField.None, MmcSubchannel.Rw, dev.Timeout, out _);
if(rwResult)
rwResult = dev.ReadCd(out rwBuffer, out rwSense, (uint)(sectors + 5), 16, 1, MmcSectorTypes.Cdda, false,
false, false, MmcHeaderCodes.None, false, false, MmcErrorField.None,
MmcSubchannel.Rw, dev.Timeout, out _);
AaruConsole.WriteLine(pqResult ? "FAIL!" : "Success!");
menu:
System.Console.Clear();
AaruConsole.WriteLine("Device: {0}", devPath);
AaruConsole.WriteLine("Device {0} read Lead-Out.", dataResult && scrambledResult ? "cannot" : "can");
AaruConsole.WriteLine("LBA {0} sense is {1}, buffer is {2}, sense buffer is {3}.", sectors + 5, dataResult,
dataBuffer is null
? "null"
: ArrayHelpers.ArrayIsNullOrEmpty(dataBuffer)
? "empty"
: $"{dataBuffer.Length} bytes", dataSense is null
? "null"
: ArrayHelpers.
ArrayIsNullOrEmpty(dataSense)
? "empty"
: $"{dataSense.Length}");
AaruConsole.WriteLine("LBA {0} (scrambled) sense is {1}, buffer is {2}, sense buffer is {3}.", sectors + 5,
scrambledResult, scrambledBuffer is null
? "null"
: ArrayHelpers.ArrayIsNullOrEmpty(scrambledBuffer)
? "empty"
: $"{scrambledBuffer.Length} bytes", scrambledSense is null
? "null"
: ArrayHelpers.
ArrayIsNullOrEmpty(scrambledSense)
? "empty"
: $"{scrambledSense.Length}");
AaruConsole.WriteLine("LBA {0}'s PQ sense is {1}, buffer is {2}, sense buffer is {3}.", sectors + 5,
pqResult, pqBuffer is null
? "null"
: ArrayHelpers.ArrayIsNullOrEmpty(pqBuffer)
? "empty"
: $"{pqBuffer.Length} bytes", pqSense is null
? "null"
: ArrayHelpers.
ArrayIsNullOrEmpty(pqSense)
? "empty"
: $"{pqSense.Length}");
AaruConsole.WriteLine("LBA {0}'s RW sense is {1}, buffer is {2}, sense buffer is {3}.", sectors + 5,
dataResult, rwBuffer is null
? "null"
: ArrayHelpers.ArrayIsNullOrEmpty(rwBuffer)
? "empty"
: $"{rwBuffer.Length} bytes", rwSense is null
? "null"
: ArrayHelpers.
ArrayIsNullOrEmpty(rwSense)
? "empty"
: $"{rwSense.Length}");
AaruConsole.WriteLine();
AaruConsole.WriteLine("Choose what to do:");
AaruConsole.WriteLine("1.- Print LBA {0} buffer.", sectors + 5);
AaruConsole.WriteLine("2.- Print LBA {0} sense buffer.", sectors + 5);
AaruConsole.WriteLine("3.- Decode LBA {0} sense buffer.", sectors + 5);
AaruConsole.WriteLine("4.- Print LBA {0} (scrambled) buffer.", sectors + 5);
AaruConsole.WriteLine("5.- Print LBA {0} (scrambled) sense buffer.", sectors + 5);
AaruConsole.WriteLine("6.- Decode LBA {0} (scrambled) sense buffer.", sectors + 5);
AaruConsole.WriteLine("7.- Print LBA {0}'s PQ buffer.", sectors + 5);
AaruConsole.WriteLine("8.- Print LBA {0}'s PQ sense buffer.", sectors + 5);
AaruConsole.WriteLine("9.- Decode LBA {0}'s PQ sense buffer.", sectors + 5);
AaruConsole.WriteLine("10.- Print LBA {0}'s RW buffer.", sectors + 5);
AaruConsole.WriteLine("11.- Print LBA {0}'s RW sense buffer.", sectors + 5);
AaruConsole.WriteLine("12.- Decode LBA {0}'s RW sense buffer.", sectors + 5);
AaruConsole.WriteLine("13.- Send command again.");
AaruConsole.WriteLine("0.- Return to special SCSI MultiMedia Commands menu.");
AaruConsole.Write("Choose: ");
strDev = System.Console.ReadLine();
if(!int.TryParse(strDev, out item))
{
AaruConsole.WriteLine("Not a number. Press any key to continue...");
System.Console.ReadKey();
System.Console.Clear();
goto menu;
}
switch(item)
{
case 0:
AaruConsole.WriteLine("Returning to special SCSI MultiMedia Commands menu...");
return;
case 1:
System.Console.Clear();
AaruConsole.WriteLine("Device: {0}", devPath);
AaruConsole.WriteLine("LBA {0} response:", sectors + 5);
if(buffer != null)
PrintHex.PrintHexArray(dataBuffer, 64);
AaruConsole.WriteLine("Press any key to continue...");
System.Console.ReadKey();
goto menu;
case 2:
System.Console.Clear();
AaruConsole.WriteLine("Device: {0}", devPath);
AaruConsole.WriteLine("LBA {0} sense:", sectors + 5);
if(senseBuffer != null)
PrintHex.PrintHexArray(dataSense, 64);
AaruConsole.WriteLine("Press any key to continue...");
System.Console.ReadKey();
goto menu;
case 3:
System.Console.Clear();
AaruConsole.WriteLine("Device: {0}", devPath);
AaruConsole.WriteLine("LBA {0} decoded sense:", sectors + 5);
AaruConsole.Write("{0}", Sense.PrettifySense(dataSense));
AaruConsole.WriteLine("Press any key to continue...");
System.Console.ReadKey();
goto menu;
case 4:
System.Console.Clear();
AaruConsole.WriteLine("Device: {0}", devPath);
AaruConsole.WriteLine("LBA {0} (scrambled) response:", sectors + 5);
if(buffer != null)
PrintHex.PrintHexArray(scrambledBuffer, 64);
AaruConsole.WriteLine("Press any key to continue...");
System.Console.ReadKey();
goto menu;
case 5:
System.Console.Clear();
AaruConsole.WriteLine("Device: {0}", devPath);
AaruConsole.WriteLine("LBA {0} (scrambled) sense:", sectors + 5);
if(senseBuffer != null)
PrintHex.PrintHexArray(scrambledSense, 64);
AaruConsole.WriteLine("Press any key to continue...");
System.Console.ReadKey();
goto menu;
case 6:
System.Console.Clear();
AaruConsole.WriteLine("Device: {0}", devPath);
AaruConsole.WriteLine("LBA {0} (scrambled) decoded sense:", sectors + 5);
AaruConsole.Write("{0}", Sense.PrettifySense(scrambledSense));
AaruConsole.WriteLine("Press any key to continue...");
System.Console.ReadKey();
goto menu;
case 7:
System.Console.Clear();
AaruConsole.WriteLine("Device: {0}", devPath);
AaruConsole.WriteLine("LBA's PQ {0} response:", sectors + 5);
if(buffer != null)
PrintHex.PrintHexArray(pqBuffer, 64);
AaruConsole.WriteLine("Press any key to continue...");
System.Console.ReadKey();
goto menu;
case 8:
System.Console.Clear();
AaruConsole.WriteLine("Device: {0}", devPath);
AaruConsole.WriteLine("LBA's PQ {0} sense:", sectors + 5);
if(senseBuffer != null)
PrintHex.PrintHexArray(pqSense, 64);
AaruConsole.WriteLine("Press any key to continue...");
System.Console.ReadKey();
goto menu;
case 9:
System.Console.Clear();
AaruConsole.WriteLine("Device: {0}", devPath);
AaruConsole.WriteLine("LBA's PQ {0} decoded sense:", sectors + 5);
AaruConsole.Write("{0}", Sense.PrettifySense(pqSense));
AaruConsole.WriteLine("Press any key to continue...");
System.Console.ReadKey();
goto menu;
case 10:
System.Console.Clear();
AaruConsole.WriteLine("Device: {0}", devPath);
AaruConsole.WriteLine("LBA's RW {0} response:", sectors + 5);
if(buffer != null)
PrintHex.PrintHexArray(rwBuffer, 64);
AaruConsole.WriteLine("Press any key to continue...");
System.Console.ReadKey();
goto menu;
case 11:
System.Console.Clear();
AaruConsole.WriteLine("Device: {0}", devPath);
AaruConsole.WriteLine("LBA's RW {0} sense:", sectors + 5);
if(senseBuffer != null)
PrintHex.PrintHexArray(rwSense, 64);
AaruConsole.WriteLine("Press any key to continue...");
System.Console.ReadKey();
goto menu;
case 12:
System.Console.Clear();
AaruConsole.WriteLine("Device: {0}", devPath);
AaruConsole.WriteLine("LBA's RW {0} decoded sense:", sectors + 5);
AaruConsole.Write("{0}", Sense.PrettifySense(rwSense));
AaruConsole.WriteLine("Press any key to continue...");
System.Console.ReadKey();
goto menu;
case 13: goto start;
default:
AaruConsole.WriteLine("Incorrect option. Press any key to continue...");
System.Console.ReadKey();
System.Console.Clear();
goto menu;
}
}
}
}

View File

@@ -45,6 +45,7 @@ namespace Aaru.Tests.Devices
WriteLine("1.- Try to read the cache data from a device with a MediaTek chipset (F1h command 06h subcommand)."); WriteLine("1.- Try to read the cache data from a device with a MediaTek chipset (F1h command 06h subcommand).");
AaruConsole.WriteLine("2.- Try to read a GD-ROM using a trap disc."); AaruConsole.WriteLine("2.- Try to read a GD-ROM using a trap disc.");
AaruConsole.WriteLine("3.- Try to read Lead-Out using a trap disc.");
AaruConsole.WriteLine("0.- Return to command class menu."); AaruConsole.WriteLine("0.- Return to command class menu.");
AaruConsole.Write("Choose: "); AaruConsole.Write("Choose: ");
@@ -72,6 +73,10 @@ namespace Aaru.Tests.Devices
case 2: case 2:
CheckGdromReadability(devPath, dev); CheckGdromReadability(devPath, dev);
continue;
case 3:
ReadLeadOutUsingTrapDisc(devPath, dev);
continue; continue;
default: default:
AaruConsole.WriteLine("Incorrect option. Press any key to continue..."); AaruConsole.WriteLine("Incorrect option. Press any key to continue...");