示例#1
0
        static void CheckGdromReadability(string devPath, Device dev)
        {
            string strDev;
            int    item;
            bool   tocIsNotBcd = false;
            bool   sense;

            byte[] buffer;
            byte[] senseBuffer;
            int    retries;

start:
            System.Console.Clear();

            AaruConsole.WriteLine("Ejecting disc...");

            dev.AllowMediumRemoval(out _, dev.Timeout, out _);
            dev.EjectTray(out _, dev.Timeout, out _);

            AaruConsole.WriteLine("Please insert trap disc inside...");
            AaruConsole.WriteLine("Press any key to continue...");
            System.Console.ReadLine();

            AaruConsole.WriteLine("Sending READ FULL TOC to the device...");

            retries = 0;

            do
            {
                retries++;
                sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _);

                if (!sense)
                {
                    break;
                }

                var decodedSense = Sense.Decode(senseBuffer);

                if (decodedSense.Value.ASC != 0x04)
                {
                    break;
                }

                if (decodedSense.Value.ASCQ != 0x01)
                {
                    break;
                }

                Thread.Sleep(2000);
            } while(retries < 25);

            sense = dev.ReadRawToc(out buffer, out senseBuffer, 1, dev.Timeout, out _);

            if (sense)
            {
                AaruConsole.WriteLine("READ FULL TOC failed...");
                AaruConsole.WriteLine("{0}", Sense.PrettifySense(senseBuffer));
                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadLine();

                return;
            }

            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();

                return;
            }

            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();

                return;
            }

            int min = 0, sec, frame;

            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 sectors = ((min * 60 * 75) + (sec * 75) + frame) - 150;

            AaruConsole.WriteLine("Trap disc shows {0} sectors...", sectors);

            if (sectors < 450000)
            {
                AaruConsole.WriteLine("Trap disc doesn't have enough sectors...");
                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadLine();

                return;
            }

            AaruConsole.WriteLine("Stopping motor...");

            dev.StopUnit(out _, dev.Timeout, out _);

            AaruConsole.WriteLine("Please MANUALLY get the trap disc out and put the GD-ROM 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...");

            retries = 0;

            do
            {
                retries++;
                sense = dev.ReadRawToc(out buffer, out senseBuffer, 1, dev.Timeout, out _);

                if (!sense)
                {
                    break;
                }

                var decodedSense = Sense.Decode(senseBuffer);

                if (decodedSense.Value.ASC != 0x04)
                {
                    break;
                }

                if (decodedSense.Value.ASCQ != 0x01)
                {
                    break;
                }
            } while(retries < 25);

            if (sense)
            {
                AaruConsole.WriteLine("READ FULL TOC failed...");
                AaruConsole.WriteLine("{0}", Sense.PrettifySense(senseBuffer));
                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadLine();

                return;
            }

            decodedToc = FullTOC.Decode(buffer);

            if (decodedToc is null)
            {
                AaruConsole.WriteLine("Could not decode TOC...");
                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadLine();

                return;
            }

            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();

                return;
            }

            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();

                return;
            }

            dev.SetCdSpeed(out _, RotationalControl.PureCav, 170, 0, dev.Timeout, out _);

            AaruConsole.Write("Reading LBA 0... ");

            bool lba0Result = dev.ReadCd(out byte[] lba0Buffer, out byte[] lba0Sense, 0, 2352, 1,
                                         MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true,
                                         true, MmcErrorField.None, MmcSubchannel.None, dev.Timeout, out _);

            AaruConsole.WriteLine(lba0Result ? "FAIL!" : "Success!");

            AaruConsole.Write("Reading LBA 0 as audio (scrambled)... ");

            bool lba0ScrambledResult = dev.ReadCd(out byte[] lba0ScrambledBuffer, out byte[] lba0ScrambledSense, 0,
                                                  2352, 1, MmcSectorTypes.Cdda, false, false, false,
                                                  MmcHeaderCodes.None, true, false, MmcErrorField.None,
                                                  MmcSubchannel.None, dev.Timeout, out _);

            AaruConsole.WriteLine(lba0ScrambledResult ? "FAIL!" : "Success!");

            AaruConsole.Write("Reading LBA 100000... ");

            bool lba100000Result = dev.ReadCd(out byte[] lba100000Buffer, out byte[] lba100000Sense, 100000, 2352, 1,
                                              MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders,
                                              true, true, MmcErrorField.None, MmcSubchannel.None, dev.Timeout, out _);

            AaruConsole.WriteLine(lba100000Result ? "FAIL!" : "Success!");

            AaruConsole.Write("Reading LBA 50000... ");

            bool lba50000Result = dev.ReadCd(out byte[] lba50000Buffer, out byte[] lba50000Sense, 50000, 2352, 1,
                                             MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders,
                                             true, true, MmcErrorField.None, MmcSubchannel.None, dev.Timeout, out _);

            AaruConsole.WriteLine(lba50000Result ? "FAIL!" : "Success!");

            AaruConsole.Write("Reading LBA 450000... ");

            bool lba450000Result = dev.ReadCd(out byte[] lba450000Buffer, out byte[] lba450000Sense, 450000, 2352, 1,
                                              MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders,
                                              true, true, MmcErrorField.None, MmcSubchannel.None, dev.Timeout, out _);

            AaruConsole.WriteLine(lba450000Result ? "FAIL!" : "Success!");

            AaruConsole.Write("Reading LBA 400000... ");

            bool lba400000Result = dev.ReadCd(out byte[] lba400000Buffer, out byte[] lba400000Sense, 400000, 2352, 1,
                                              MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders,
                                              true, true, MmcErrorField.None, MmcSubchannel.None, dev.Timeout, out _);

            AaruConsole.WriteLine(lba400000Result ? "FAIL!" : "Success!");

            AaruConsole.Write("Reading LBA 45000... ");

            bool lba45000Result = dev.ReadCd(out byte[] lba45000Buffer, out byte[] lba45000Sense, 45000, 2352, 1,
                                             MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders,
                                             true, true, MmcErrorField.None, MmcSubchannel.None, dev.Timeout, out _);

            AaruConsole.WriteLine(lba45000Result ? "FAIL!" : "Success!");

            AaruConsole.Write("Reading LBA 44990... ");

            bool lba44990Result = dev.ReadCd(out byte[] lba44990Buffer, out byte[] lba44990Sense, 44990, 2352, 1,
                                             MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders,
                                             true, true, MmcErrorField.None, MmcSubchannel.None, dev.Timeout, out _);

            AaruConsole.WriteLine(lba44990Result ? "FAIL!" : "Success!");

menu:
            System.Console.Clear();
            AaruConsole.WriteLine("Device: {0}", devPath);
            AaruConsole.WriteLine("Device {0} read HD area.", lba450000Result ? "cannot" : "can");

            AaruConsole.WriteLine("LBA 0 sense is {0}, buffer is {1}, sense buffer is {2}.", lba0Result,
                                  lba0Buffer is null
                                      ? "null"
                                      : ArrayHelpers.ArrayIsNullOrEmpty(lba0Buffer)
                                          ? "empty"
                                          : $"{lba0Buffer.Length} bytes", lba0Sense is null
                                                                              ? "null"
                                                                              : ArrayHelpers.
                                  ArrayIsNullOrEmpty(lba0Sense)
                                                                                  ? "empty"
                                                                                  : $"{lba0Sense.Length}");

            AaruConsole.WriteLine("LBA 0 (scrambled) sense is {0}, buffer is {1}, sense buffer is {2}.",
                                  lba0ScrambledResult, lba0ScrambledBuffer is null
                                                           ? "null"
                                                           : ArrayHelpers.ArrayIsNullOrEmpty(lba0ScrambledBuffer)
                                                               ? "empty"
                                                               : $"{lba0ScrambledBuffer.Length} bytes",
                                  lba0ScrambledSense is null
                                      ? "null"
                                      : ArrayHelpers.ArrayIsNullOrEmpty(lba0ScrambledSense)
                                          ? "empty"
                                          : $"{lba0ScrambledSense.Length}");

            AaruConsole.WriteLine("LBA 44990 sense is {0}, buffer is {1}, sense buffer is {2}.", lba44990Result,
                                  lba44990Buffer is null
                                      ? "null"
                                      : ArrayHelpers.ArrayIsNullOrEmpty(lba44990Buffer)
                                          ? "empty"
                                          : $"{lba44990Buffer.Length} bytes", lba44990Sense is null
                                                                                  ? "null"
                                                                                  : ArrayHelpers.
                                  ArrayIsNullOrEmpty(lba44990Sense)
                                                                                      ? "empty"
                                                                                      : $"{lba44990Sense.Length}");

            AaruConsole.WriteLine("LBA 45000 sense is {0}, buffer is {1}, sense buffer is {2}.", lba45000Result,
                                  lba45000Buffer is null
                                      ? "null"
                                      : ArrayHelpers.ArrayIsNullOrEmpty(lba45000Buffer)
                                          ? "empty"
                                          : $"{lba45000Buffer.Length} bytes", lba45000Sense is null
                                                                                  ? "null"
                                                                                  : ArrayHelpers.
                                  ArrayIsNullOrEmpty(lba45000Sense)
                                                                                      ? "empty"
                                                                                      : $"{lba45000Sense.Length}");

            AaruConsole.WriteLine("LBA 50000 sense is {0}, buffer is {1}, sense buffer is {2}.", lba50000Result,
                                  lba50000Buffer is null
                                      ? "null"
                                      : ArrayHelpers.ArrayIsNullOrEmpty(lba50000Buffer)
                                          ? "empty"
                                          : $"{lba50000Buffer.Length} bytes", lba50000Sense is null
                                                                                  ? "null"
                                                                                  : ArrayHelpers.
                                  ArrayIsNullOrEmpty(lba50000Sense)
                                                                                      ? "empty"
                                                                                      : $"{lba50000Sense.Length}");

            AaruConsole.WriteLine("LBA 100000 sense is {0}, buffer is {1}, sense buffer is {2}.", lba100000Result,
                                  lba100000Buffer is null
                                      ? "null"
                                      : ArrayHelpers.ArrayIsNullOrEmpty(lba100000Buffer)
                                          ? "empty"
                                          : $"{lba100000Buffer.Length} bytes", lba100000Sense is null
                                                                                   ? "null"
                                                                                   : ArrayHelpers.
                                  ArrayIsNullOrEmpty(lba100000Sense)
                                                                                       ? "empty"
                                                                                       : $"{lba100000Sense.Length}");

            AaruConsole.WriteLine("LBA 400000 sense is {0}, buffer is {1}, sense buffer is {2}.", lba400000Result,
                                  lba400000Buffer is null
                                      ? "null"
                                      : ArrayHelpers.ArrayIsNullOrEmpty(lba400000Buffer)
                                          ? "empty"
                                          : $"{lba400000Buffer.Length} bytes", lba400000Sense is null
                                                                                   ? "null"
                                                                                   : ArrayHelpers.
                                  ArrayIsNullOrEmpty(lba400000Sense)
                                                                                       ? "empty"
                                                                                       : $"{lba400000Sense.Length}");

            AaruConsole.WriteLine("LBA 450000 sense is {0}, buffer is {1}, sense buffer is {2}.", lba450000Result,
                                  lba450000Buffer is null
                                      ? "null"
                                      : ArrayHelpers.ArrayIsNullOrEmpty(lba450000Buffer)
                                          ? "empty"
                                          : $"{lba450000Buffer.Length} bytes", lba450000Sense is null
                                                                                   ? "null"
                                                                                   : ArrayHelpers.
                                  ArrayIsNullOrEmpty(lba450000Sense)
                                                                                       ? "empty"
                                                                                       : $"{lba450000Sense.Length}");

            AaruConsole.WriteLine();
            AaruConsole.WriteLine("Choose what to do:");
            AaruConsole.WriteLine("1.- Print LBA 0 buffer.");
            AaruConsole.WriteLine("2.- Print LBA 0 sense buffer.");
            AaruConsole.WriteLine("3.- Decode LBA 0 sense buffer.");
            AaruConsole.WriteLine("4.- Print LBA 0 (scrambled) buffer.");
            AaruConsole.WriteLine("5.- Print LBA 0 (scrambled) sense buffer.");
            AaruConsole.WriteLine("6.- Decode LBA 0 (scrambled) sense buffer.");
            AaruConsole.WriteLine("7.- Print LBA 44990 buffer.");
            AaruConsole.WriteLine("8.- Print LBA 44990 sense buffer.");
            AaruConsole.WriteLine("9.- Decode LBA 44990 sense buffer.");
            AaruConsole.WriteLine("10.- Print LBA 45000 buffer.");
            AaruConsole.WriteLine("11.- Print LBA 45000 sense buffer.");
            AaruConsole.WriteLine("12.- Decode LBA 45000 sense buffer.");
            AaruConsole.WriteLine("13.- Print LBA 50000 buffer.");
            AaruConsole.WriteLine("14.- Print LBA 50000 sense buffer.");
            AaruConsole.WriteLine("15.- Decode LBA 50000 sense buffer.");
            AaruConsole.WriteLine("16.- Print LBA 100000 buffer.");
            AaruConsole.WriteLine("17.- Print LBA 100000 sense buffer.");
            AaruConsole.WriteLine("18.- Decode LBA 100000 sense buffer.");
            AaruConsole.WriteLine("19.- Print LBA 400000 buffer.");
            AaruConsole.WriteLine("20.- Print LBA 400000 sense buffer.");
            AaruConsole.WriteLine("21.- Decode LBA 400000 sense buffer.");
            AaruConsole.WriteLine("22.- Print LBA 450000 buffer.");
            AaruConsole.WriteLine("23.- Print LBA 450000 sense buffer.");
            AaruConsole.WriteLine("24.- Decode LBA 450000 sense buffer.");
            AaruConsole.WriteLine("25.- 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:");

                if (buffer != null)
                {
                    PrintHex.PrintHexArray(lba0Buffer, 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:");

                if (senseBuffer != null)
                {
                    PrintHex.PrintHexArray(lba0Sense, 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:");
                AaruConsole.Write("{0}", Sense.PrettifySense(lba0Sense));
                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:");

                if (buffer != null)
                {
                    PrintHex.PrintHexArray(lba0ScrambledBuffer, 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:");

                if (senseBuffer != null)
                {
                    PrintHex.PrintHexArray(lba0ScrambledSense, 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:");
                AaruConsole.Write("{0}", Sense.PrettifySense(lba0ScrambledSense));
                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 44990 response:");

                if (buffer != null)
                {
                    PrintHex.PrintHexArray(lba44990Buffer, 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 44990 sense:");

                if (senseBuffer != null)
                {
                    PrintHex.PrintHexArray(lba44990Sense, 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 44990 decoded sense:");
                AaruConsole.Write("{0}", Sense.PrettifySense(lba44990Sense));
                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 45000 response:");

                if (buffer != null)
                {
                    PrintHex.PrintHexArray(lba45000Buffer, 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 45000 sense:");

                if (senseBuffer != null)
                {
                    PrintHex.PrintHexArray(lba45000Sense, 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 45000 decoded sense:");
                AaruConsole.Write("{0}", Sense.PrettifySense(lba45000Sense));
                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();

                goto menu;

            case 13:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("LBA 50000 response:");

                if (buffer != null)
                {
                    PrintHex.PrintHexArray(lba50000Buffer, 64);
                }

                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();

                goto menu;

            case 14:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("LBA 50000 sense:");

                if (senseBuffer != null)
                {
                    PrintHex.PrintHexArray(lba50000Sense, 64);
                }

                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();

                goto menu;

            case 15:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("LBA 50000 decoded sense:");
                AaruConsole.Write("{0}", Sense.PrettifySense(lba50000Sense));
                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();

                goto menu;

            case 16:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("LBA 100000 response:");

                if (buffer != null)
                {
                    PrintHex.PrintHexArray(lba100000Buffer, 64);
                }

                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();

                goto menu;

            case 17:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("LBA 100000 sense:");

                if (senseBuffer != null)
                {
                    PrintHex.PrintHexArray(lba100000Sense, 64);
                }

                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();

                goto menu;

            case 18:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("LBA 100000 decoded sense:");
                AaruConsole.Write("{0}", Sense.PrettifySense(lba100000Sense));
                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();

                goto menu;

            case 19:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("LBA 400000 response:");

                if (buffer != null)
                {
                    PrintHex.PrintHexArray(lba400000Buffer, 64);
                }

                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();

                goto menu;

            case 20:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("LBA 400000 sense:");

                if (senseBuffer != null)
                {
                    PrintHex.PrintHexArray(lba400000Sense, 64);
                }

                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();

                goto menu;

            case 21:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("LBA 400000 decoded sense:");
                AaruConsole.Write("{0}", Sense.PrettifySense(lba400000Sense));
                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();

                goto menu;

            case 22:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("LBA 450000 response:");

                if (buffer != null)
                {
                    PrintHex.PrintHexArray(lba450000Buffer, 64);
                }

                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();

                goto menu;

            case 23:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("LBA 450000 sense:");

                if (senseBuffer != null)
                {
                    PrintHex.PrintHexArray(lba450000Sense, 64);
                }

                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();

                goto menu;

            case 24:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("LBA 450000 decoded sense:");
                AaruConsole.Write("{0}", Sense.PrettifySense(lba450000Sense));
                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();

                goto menu;

            case 25: goto start;

            default:
                AaruConsole.WriteLine("Incorrect option. Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();

                goto menu;
            }
        }
示例#2
0
        public bool Close()
        {
            if (!IsWriting)
            {
                ErrorMessage = "Image is not opened for writing";

                return(false);
            }

            _dataStream.Flush();
            _dataStream.Close();

            _subStream?.Flush();
            _subStream?.Close();

            FullTOC.CDFullTOC?nullableToc = null;
            FullTOC.CDFullTOC toc;

            // Easy, just decode the real toc
            if (_fulltoc != null)
            {
                byte[] tmp = new byte[_fulltoc.Length + 2];
                Array.Copy(BigEndianBitConverter.GetBytes((ushort)_fulltoc.Length), 0, tmp, 0, 2);
                Array.Copy(_fulltoc, 0, tmp, 2, _fulltoc.Length);
                nullableToc = FullTOC.Decode(tmp);
            }

            // Not easy, create a toc from scratch
            if (nullableToc == null)
            {
                toc = new FullTOC.CDFullTOC();
                Dictionary <byte, byte> sessionEndingTrack = new Dictionary <byte, byte>();
                toc.FirstCompleteSession = byte.MaxValue;
                toc.LastCompleteSession  = byte.MinValue;
                List <FullTOC.TrackDataDescriptor> trackDescriptors = new List <FullTOC.TrackDataDescriptor>();
                byte currentTrack = 0;

                foreach (Track track in Tracks.OrderBy(t => t.TrackSession).ThenBy(t => t.TrackSequence))
                {
                    if (track.TrackSession < toc.FirstCompleteSession)
                    {
                        toc.FirstCompleteSession = (byte)track.TrackSession;
                    }

                    if (track.TrackSession <= toc.LastCompleteSession)
                    {
                        currentTrack = (byte)track.TrackSequence;

                        continue;
                    }

                    if (toc.LastCompleteSession > 0)
                    {
                        sessionEndingTrack.Add(toc.LastCompleteSession, currentTrack);
                    }

                    toc.LastCompleteSession = (byte)track.TrackSession;
                }

                byte currentSession = 0;

                foreach (Track track in Tracks.OrderBy(t => t.TrackSession).ThenBy(t => t.TrackSequence))
                {
                    _trackFlags.TryGetValue((byte)track.TrackSequence, out byte trackControl);

                    if (trackControl == 0 &&
                        track.TrackType != TrackType.Audio)
                    {
                        trackControl = (byte)CdFlags.DataTrack;
                    }

                    // Lead-Out
                    if (track.TrackSession > currentSession &&
                        currentSession != 0)
                    {
                        (byte minute, byte second, byte frame)leadoutAmsf = LbaToMsf(track.TrackStartSector - 150);

                        (byte minute, byte second, byte frame)leadoutPmsf =
                            LbaToMsf(Tracks.OrderBy(t => t.TrackSession).ThenBy(t => t.TrackSequence).Last().
                                     TrackStartSector);

                        // Lead-out
                        trackDescriptors.Add(new FullTOC.TrackDataDescriptor
                        {
                            SessionNumber = currentSession,
                            POINT         = 0xB0,
                            ADR           = 5,
                            CONTROL       = 0,
                            HOUR          = 0,
                            Min           = leadoutAmsf.minute,
                            Sec           = leadoutAmsf.second,
                            Frame         = leadoutAmsf.frame,
                            PHOUR         = 2,
                            PMIN          = leadoutPmsf.minute,
                            PSEC          = leadoutPmsf.second,
                            PFRAME        = leadoutPmsf.frame
                        });

                        // This seems to be constant? It should not exist on CD-ROM but CloneCD creates them anyway
                        // Format seems like ATIP, but ATIP should not be as 0xC0 in TOC...
                        trackDescriptors.Add(new FullTOC.TrackDataDescriptor
                        {
                            SessionNumber = currentSession,
                            POINT         = 0xC0,
                            ADR           = 5,
                            CONTROL       = 0,
                            Min           = 128,
                            PMIN          = 97,
                            PSEC          = 25
                        });
                    }

                    // Lead-in
                    if (track.TrackSession > currentSession)
                    {
                        currentSession = (byte)track.TrackSession;
                        sessionEndingTrack.TryGetValue(currentSession, out byte endingTrackNumber);

                        (byte minute, byte second, byte frame)leadinPmsf =
                            LbaToMsf(Tracks.FirstOrDefault(t => t.TrackSequence == endingTrackNumber)?.TrackEndSector ??
                                     0 + 1);

                        // Starting track
                        trackDescriptors.Add(new FullTOC.TrackDataDescriptor
                        {
                            SessionNumber = currentSession,
                            POINT         = 0xA0,
                            ADR           = 1,
                            CONTROL       = trackControl,
                            PMIN          = (byte)track.TrackSequence
                        });

                        // Ending track
                        trackDescriptors.Add(new FullTOC.TrackDataDescriptor
                        {
                            SessionNumber = currentSession,
                            POINT         = 0xA1,
                            ADR           = 1,
                            CONTROL       = trackControl,
                            PMIN          = endingTrackNumber
                        });

                        // Lead-out start
                        trackDescriptors.Add(new FullTOC.TrackDataDescriptor
                        {
                            SessionNumber = currentSession,
                            POINT         = 0xA2,
                            ADR           = 1,
                            CONTROL       = trackControl,
                            PHOUR         = 0,
                            PMIN          = leadinPmsf.minute,
                            PSEC          = leadinPmsf.second,
                            PFRAME        = leadinPmsf.frame
                        });
                    }

                    (byte minute, byte second, byte frame)pmsf = LbaToMsf(track.TrackStartSector);

                    // Track
                    trackDescriptors.Add(new FullTOC.TrackDataDescriptor
                    {
                        SessionNumber = (byte)track.TrackSession,
                        POINT         = (byte)track.TrackSequence,
                        ADR           = 1,
                        CONTROL       = trackControl,
                        PHOUR         = 0,
                        PMIN          = pmsf.minute,
                        PSEC          = pmsf.second,
                        PFRAME        = pmsf.frame
                    });
                }

                toc.TrackDescriptors = trackDescriptors.ToArray();
            }
            else
            {
                toc = nullableToc.Value;
            }

            _descriptorStream.WriteLine("[CloneCD]");
            _descriptorStream.WriteLine("Version=2");
            _descriptorStream.WriteLine("[Disc]");
            _descriptorStream.WriteLine("TocEntries={0}", toc.TrackDescriptors.Length);
            _descriptorStream.WriteLine("Sessions={0}", toc.LastCompleteSession);
            _descriptorStream.WriteLine("DataTracksScrambled=0");
            _descriptorStream.WriteLine("CDTextLength=0");

            if (!string.IsNullOrEmpty(_catalog))
            {
                _descriptorStream.WriteLine("CATALOG={0}", _catalog);
            }

            for (int i = 1; i <= toc.LastCompleteSession; i++)
            {
                _descriptorStream.WriteLine("[Session {0}]", i);

                Track firstSessionTrack = Tracks.FirstOrDefault(t => t.TrackSession == i);

                switch (firstSessionTrack?.TrackType)
                {
                case TrackType.Audio:
                    // CloneCD always writes this value for first track in disc, however the Rainbow Books
                    // say the first track pregap is no different from other session pregaps, same mode as
                    // the track they belong to.
                    _descriptorStream.WriteLine("PreGapMode=0");

                    break;

                case TrackType.Data:
                case TrackType.CdMode1:
                    _descriptorStream.WriteLine("PreGapMode=1");

                    break;

                case TrackType.CdMode2Formless:
                case TrackType.CdMode2Form1:
                case TrackType.CdMode2Form2:
                    _descriptorStream.WriteLine("PreGapMode=2");

                    break;

                default: throw new ArgumentOutOfRangeException();
                }

                _descriptorStream.WriteLine("PreGapSubC=0");
            }

            for (int i = 0; i < toc.TrackDescriptors.Length; i++)
            {
                long alba = MsfToLba((toc.TrackDescriptors[i].Min, toc.TrackDescriptors[i].Sec,
                                      toc.TrackDescriptors[i].Frame));

                long plba = MsfToLba((toc.TrackDescriptors[i].PMIN, toc.TrackDescriptors[i].PSEC,
                                      toc.TrackDescriptors[i].PFRAME));

                if (alba > 405000)
                {
                    alba = ((alba - 405000) + 300) * -1;
                }

                if (plba > 405000)
                {
                    plba = ((plba - 405000) + 300) * -1;
                }

                _descriptorStream.WriteLine("[Entry {0}]", i);
                _descriptorStream.WriteLine("Session={0}", toc.TrackDescriptors[i].SessionNumber);
                _descriptorStream.WriteLine("Point=0x{0:x2}", toc.TrackDescriptors[i].POINT);
                _descriptorStream.WriteLine("ADR=0x{0:x2}", toc.TrackDescriptors[i].ADR);
                _descriptorStream.WriteLine("Control=0x{0:x2}", toc.TrackDescriptors[i].CONTROL);
                _descriptorStream.WriteLine("TrackNo={0}", toc.TrackDescriptors[i].TNO);
                _descriptorStream.WriteLine("AMin={0}", toc.TrackDescriptors[i].Min);
                _descriptorStream.WriteLine("ASec={0}", toc.TrackDescriptors[i].Sec);
                _descriptorStream.WriteLine("AFrame={0}", toc.TrackDescriptors[i].Frame);
                _descriptorStream.WriteLine("ALBA={0}", alba);

                _descriptorStream.WriteLine("Zero={0}",
                                            ((toc.TrackDescriptors[i].HOUR & 0x0F) << 4) +
                                            (toc.TrackDescriptors[i].PHOUR & 0x0F));

                _descriptorStream.WriteLine("PMin={0}", toc.TrackDescriptors[i].PMIN);
                _descriptorStream.WriteLine("PSec={0}", toc.TrackDescriptors[i].PSEC);
                _descriptorStream.WriteLine("PFrame={0}", toc.TrackDescriptors[i].PFRAME);
                _descriptorStream.WriteLine("PLBA={0}", plba);
            }

            _descriptorStream.Flush();
            _descriptorStream.Close();

            IsWriting    = false;
            ErrorMessage = "";

            return(true);
        }
示例#3
0
        public bool Close()
        {
            if (!IsWriting)
            {
                ErrorMessage = "Image is not opened for writing";
                return(false);
            }

            dataStream.Flush();
            dataStream.Close();

            subStream?.Flush();
            subStream?.Close();

            FullTOC.CDFullTOC?nullableToc = null;
            FullTOC.CDFullTOC toc;

            // Easy, just decode the real toc
            if (fulltoc != null)
            {
                nullableToc = FullTOC.Decode(fulltoc);
            }

            // Not easy, create a toc from scratch
            if (nullableToc == null)
            {
                toc = new FullTOC.CDFullTOC();
                Dictionary <byte, byte> sessionEndingTrack = new Dictionary <byte, byte>();
                toc.FirstCompleteSession = byte.MaxValue;
                toc.LastCompleteSession  = byte.MinValue;
                List <FullTOC.TrackDataDescriptor> trackDescriptors = new List <FullTOC.TrackDataDescriptor>();
                byte currentTrack = 0;

                foreach (Track track in Tracks.OrderBy(t => t.TrackSession).ThenBy(t => t.TrackSequence))
                {
                    if (track.TrackSession < toc.FirstCompleteSession)
                    {
                        toc.FirstCompleteSession = (byte)track.TrackSession;
                    }

                    if (track.TrackSession <= toc.LastCompleteSession)
                    {
                        currentTrack = (byte)track.TrackSequence;
                        continue;
                    }

                    if (toc.LastCompleteSession > 0)
                    {
                        sessionEndingTrack.Add(toc.LastCompleteSession, currentTrack);
                    }

                    toc.LastCompleteSession = (byte)track.TrackSession;
                }

                byte currentSession = 0;

                foreach (Track track in Tracks.OrderBy(t => t.TrackSession).ThenBy(t => t.TrackSequence))
                {
                    trackFlags.TryGetValue((byte)track.TrackSequence, out byte trackControl);

                    if (trackControl == 0 && track.TrackType != TrackType.Audio)
                    {
                        trackControl = (byte)CdFlags.DataTrack;
                    }

                    // Lead-Out
                    if (track.TrackSession > currentSession && currentSession != 0)
                    {
                        (byte minute, byte second, byte frame)leadoutAmsf = LbaToMsf(track.TrackStartSector - 150);
                        (byte minute, byte second, byte frame)leadoutPmsf =
                            LbaToMsf(Tracks.OrderBy(t => t.TrackSession).ThenBy(t => t.TrackSequence).Last()
                                     .TrackStartSector);

                        // Lead-out
                        trackDescriptors.Add(new FullTOC.TrackDataDescriptor
                        {
                            SessionNumber = currentSession,
                            POINT         = 0xB0,
                            ADR           = 5,
                            CONTROL       = 0,
                            HOUR          = 0,
                            Min           = leadoutAmsf.minute,
                            Sec           = leadoutAmsf.second,
                            Frame         = leadoutAmsf.frame,
                            PHOUR         = 2,
                            PMIN          = leadoutPmsf.minute,
                            PSEC          = leadoutPmsf.second,
                            PFRAME        = leadoutPmsf.frame
                        });

                        // This seems to be constant? It should not exist on CD-ROM but CloneCD creates them anyway
                        // Format seems like ATIP, but ATIP should not be as 0xC0 in TOC...
                        trackDescriptors.Add(new FullTOC.TrackDataDescriptor
                        {
                            SessionNumber = currentSession,
                            POINT         = 0xC0,
                            ADR           = 5,
                            CONTROL       = 0,
                            Min           = 128,
                            PMIN          = 97,
                            PSEC          = 25
                        });
                    }

                    // Lead-in
                    if (track.TrackSession > currentSession)
                    {
                        currentSession = (byte)track.TrackSession;
                        sessionEndingTrack.TryGetValue(currentSession, out byte endingTrackNumber);
                        (byte minute, byte second, byte frame)leadinPmsf =
                            LbaToMsf(Tracks.FirstOrDefault(t => t.TrackSequence == endingTrackNumber).TrackEndSector +
                                     1);

                        // Starting track
                        trackDescriptors.Add(new FullTOC.TrackDataDescriptor
                        {
                            SessionNumber = currentSession,
                            POINT         = 0xA0,
                            ADR           = 1,
                            CONTROL       = trackControl,
                            PMIN          = (byte)track.TrackSequence
                        });

                        // Ending track
                        trackDescriptors.Add(new FullTOC.TrackDataDescriptor
                        {
                            SessionNumber = currentSession,
                            POINT         = 0xA1,
                            ADR           = 1,
                            CONTROL       = trackControl,
                            PMIN          = endingTrackNumber
                        });

                        // Lead-out start
                        trackDescriptors.Add(new FullTOC.TrackDataDescriptor
                        {
                            SessionNumber = currentSession,
                            POINT         = 0xA2,
                            ADR           = 1,
                            CONTROL       = trackControl,
                            PHOUR         = 0,
                            PMIN          = leadinPmsf.minute,
                            PSEC          = leadinPmsf.second,
                            PFRAME        = leadinPmsf.frame
                        });
                    }

                    (byte minute, byte second, byte frame)pmsf = LbaToMsf(track.TrackStartSector);

                    // Track
                    trackDescriptors.Add(new FullTOC.TrackDataDescriptor
                    {
                        SessionNumber = (byte)track.TrackSession,
                        POINT         = (byte)track.TrackSequence,
                        ADR           = 1,
                        CONTROL       = trackControl,
                        PHOUR         = 0,
                        PMIN          = pmsf.minute,
                        PSEC          = pmsf.second,
                        PFRAME        = pmsf.frame
                    });
                }

                toc.TrackDescriptors = trackDescriptors.ToArray();
            }
            else
            {
                toc = nullableToc.Value;
            }

            descriptorStream.WriteLine("[CloneCD]");
            descriptorStream.WriteLine("Version=2");
            descriptorStream.WriteLine("[Disc]");
            descriptorStream.WriteLine("TocEntries={0}", toc.TrackDescriptors.Length);
            descriptorStream.WriteLine("Sessions={0}", toc.LastCompleteSession);
            descriptorStream.WriteLine("DataTracksScrambled=0");
            descriptorStream.WriteLine("CDTextLength=0");
            if (!string.IsNullOrEmpty(catalog))
            {
                descriptorStream.WriteLine("CATALOG={0}", catalog);
            }
            for (int i = 1; i <= toc.LastCompleteSession; i++)
            {
                // TODO: Use first track of session info
                descriptorStream.WriteLine("[Session {0}]", i);
                descriptorStream.WriteLine("PreGapMode=0");
                descriptorStream.WriteLine("PreGapSubC=0");
            }

            for (int i = 0; i < toc.TrackDescriptors.Length; i++)
            {
                long alba = MsfToLba((toc.TrackDescriptors[i].Min, toc.TrackDescriptors[i].Sec,
                                      toc.TrackDescriptors[i].Frame));
                long plba = MsfToLba((toc.TrackDescriptors[i].PMIN, toc.TrackDescriptors[i].PSEC,
                                      toc.TrackDescriptors[i].PFRAME));

                if (alba > 405000)
                {
                    alba = (alba - 405000 + 300) * -1;
                }
                if (plba > 405000)
                {
                    plba = (plba - 405000 + 300) * -1;
                }

                descriptorStream.WriteLine("[Entry {0}]", i);
                descriptorStream.WriteLine("Session={0}", toc.TrackDescriptors[i].SessionNumber);
                descriptorStream.WriteLine("Point=0x{0:x2}", toc.TrackDescriptors[i].POINT);
                descriptorStream.WriteLine("ADR=0x{0:x2}", toc.TrackDescriptors[i].ADR);
                descriptorStream.WriteLine("Control=0x{0:x2}", toc.TrackDescriptors[i].CONTROL);
                descriptorStream.WriteLine("TrackNo={0}", toc.TrackDescriptors[i].TNO);
                descriptorStream.WriteLine("AMin={0}", toc.TrackDescriptors[i].Min);
                descriptorStream.WriteLine("ASec={0}", toc.TrackDescriptors[i].Sec);
                descriptorStream.WriteLine("AFrame={0}", toc.TrackDescriptors[i].Frame);
                descriptorStream.WriteLine("ALBA={0}", alba);
                descriptorStream.WriteLine("Zero={0}",
                                           ((toc.TrackDescriptors[i].HOUR & 0x0F) << 4) +
                                           (toc.TrackDescriptors[i].PHOUR & 0x0F));
                descriptorStream.WriteLine("PMin={0}", toc.TrackDescriptors[i].PMIN);
                descriptorStream.WriteLine("PSec={0}", toc.TrackDescriptors[i].PSEC);
                descriptorStream.WriteLine("PFrame={0}", toc.TrackDescriptors[i].PFRAME);
                descriptorStream.WriteLine("PLBA={0}", plba);
            }

            descriptorStream.Flush();
            descriptorStream.Close();

            IsWriting    = false;
            ErrorMessage = "";
            return(true);
        }
示例#4
0
        static void ReadLeadOutUsingTrapDisc(string devPath, Device dev)
        {
            string strDev;
            int    item;
            bool   tocIsNotBcd = false;
            bool   sense;

            byte[] buffer;
            byte[] senseBuffer;
            int    retries;

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("Sending READ FULL TOC to the device...");

            retries = 0;

            do
            {
                retries++;
                sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _);

                if (!sense)
                {
                    break;
                }

                DecodedSense?decodedSense = Sense.Decode(senseBuffer);

                if (decodedSense.Value.ASC != 0x04)
                {
                    break;
                }

                if (decodedSense.Value.ASCQ != 0x01)
                {
                    break;
                }

                Thread.Sleep(2000);
            } while(retries < 25);

            sense = dev.ReadRawToc(out buffer, out senseBuffer, 1, dev.Timeout, out _);

            if (sense)
            {
                AaruConsole.WriteLine("READ FULL TOC failed...");
                AaruConsole.WriteLine("{0}", Sense.PrettifySense(senseBuffer));
                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadLine();

                return;
            }

            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();

                return;
            }

            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();

                return;
            }

            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("Sending READ FULL TOC to the device...");

            retries = 0;

            do
            {
                retries++;
                sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _);

                if (!sense)
                {
                    break;
                }

                DecodedSense?decodedSense = Sense.Decode(senseBuffer);

                if (decodedSense.Value.ASC != 0x04)
                {
                    break;
                }

                if (decodedSense.Value.ASCQ != 0x01)
                {
                    break;
                }

                Thread.Sleep(2000);
            } while(retries < 25);

            sense = dev.ReadRawToc(out buffer, out senseBuffer, 1, dev.Timeout, out _);

            if (sense)
            {
                AaruConsole.WriteLine("READ FULL TOC failed...");
                AaruConsole.WriteLine("{0}", Sense.PrettifySense(senseBuffer));
                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadLine();

                return;
            }

            decodedToc = FullTOC.Decode(buffer);

            if (decodedToc is null)
            {
                AaruConsole.WriteLine("Could not decode TOC...");
                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadLine();

                return;
            }

            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();

                return;
            }

            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();

                return;
            }

            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...");

            retries = 0;

            do
            {
                retries++;
                sense = dev.ReadRawToc(out buffer, out senseBuffer, 1, dev.Timeout, out _);

                if (!sense)
                {
                    break;
                }

                DecodedSense?decodedSense = Sense.Decode(senseBuffer);

                if (decodedSense.Value.ASC != 0x04)
                {
                    break;
                }

                if (decodedSense.Value.ASCQ != 0x01)
                {
                    break;
                }
            } while(retries < 25);

            if (sense)
            {
                AaruConsole.WriteLine("READ FULL TOC failed...");
                AaruConsole.WriteLine("{0}", Sense.PrettifySense(senseBuffer));
                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadLine();

                return;
            }

            decodedToc = FullTOC.Decode(buffer);

            if (decodedToc is null)
            {
                AaruConsole.WriteLine("Could not decode TOC...");
                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadLine();

                return;
            }

            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();

                return;
            }

            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();

                return;
            }

            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,
                                  rwResult, 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;
            }
        }
示例#5
0
        public async void Init(AaruFormat image, bool autoPlay = false)
        {
            this.Image = image;

            if (await Task.Run(() => image.Info.ReadableMediaTags?.Contains(MediaTagType.CD_FullTOC)) != true)
            {
                Console.WriteLine("Full TOC not found");
                return;
            }

            byte[] tocBytes = await Task.Run(() => image.ReadDiskTag(MediaTagType.CD_FullTOC));

            if ((tocBytes?.Length ?? 0) == 0)
            {
                Console.WriteLine("Error reading TOC from disc image");
                return;
            }

            if (Swapping.Swap(BitConverter.ToUInt16(tocBytes, 0)) + 2 != tocBytes.Length)
            {
                byte[] tmp = new byte[tocBytes.Length + 2];
                Array.Copy(tocBytes, 0, tmp, 2, tocBytes.Length);
                tmp[0]   = (byte)((tocBytes.Length & 0xFF00) >> 8);
                tmp[1]   = (byte)(tocBytes.Length & 0xFF);
                tocBytes = tmp;
            }

            FullTOC.CDFullTOC?nullableToc = await Task.Run(() => FullTOC.Decode(tocBytes));

            if (nullableToc == null)
            {
                Console.WriteLine("Error decoding TOC");
                return;
            }

            toc = nullableToc.Value;

            Console.WriteLine(FullTOC.Prettify(toc));

            if (deEmphasisFilterLeft == null)
            {
                deEmphasisFilterLeft  = new DeEmphasisFilter();
                deEmphasisFilterRight = new DeEmphasisFilter();
            }
            else
            {
                deEmphasisFilterLeft.Reset();
                deEmphasisFilterRight.Reset();
            }

            if (source == null)
            {
                source = new PlayerSource(ProviderRead);

                soundOut = new ALSoundOut(100);
                soundOut.Initialize(source);
            }
            else
            {
                soundOut.Stop();
            }

            CurrentTrack = 0;
            LoadTrack(0);

            if (autoPlay)
            {
                soundOut.Play();
            }
            else
            {
                TotalIndexes = 0;
            }

            TotalTracks = image.Tracks.Count;
            TrackDataDescriptor firstTrack = toc.TrackDescriptors.First(d => d.ADR == 1 && d.POINT == 1);

            TimeOffset = (ulong)(firstTrack.PMIN * 60 * 75 + firstTrack.PSEC * 75 + firstTrack.PFRAME);
            TotalTime  = TimeOffset + image.Tracks.Last().TrackEndSector;

            Volume = App.Settings.Volume;

            Initialized = true;

            source.Start();
        }