From 67eb49b66e0d65019a410f3939714ab4d1df1ac8 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Tue, 24 Nov 2015 00:40:33 +0000 Subject: [PATCH] * DiscImageChef.CommonTypes/DiskType.cs: Added DVD-RW DL, DVD-Download, HD DVD-R DL and HD DVD-RW DL. * DiscImageChef.Decoders/CD/ATIP.cs: ATIP not always contain S4. Corrected typo. * DiscImageChef.Decoders/CD/Session.cs: Added missing newlines. * DiscImageChef.Decoders/CD/TOC.cs: Added missing newlines. Recognize Lead-Out track. * DiscImageChef.Decoders/SCSI/MMC/DiscInformation.cs: Added structures for Disc Informations 001b and 010b. * DiscImageChef.Devices/Device/ScsiCommands.cs: On READ TOC/PMA/ATIP and READ DISC INFORMATION if trying small buffer and then real-sized buffer, some drives send garbage, so get a big enough buffer and return only the applicable data size. * DiscImageChef/Commands/MediaInfo.cs: Check current profile and prettify TOC, PMA, ATIP, Session and CD-TEXT. --- DiscImageChef.CommonTypes/ChangeLog | 5 + DiscImageChef.CommonTypes/DiskType.cs | 8 + DiscImageChef.Decoders/CD/ATIP.cs | 19 ++- DiscImageChef.Decoders/CD/Session.cs | 4 +- DiscImageChef.Decoders/CD/TOC.cs | 7 +- DiscImageChef.Decoders/ChangeLog | 16 ++ .../SCSI/MMC/DiscInformation.cs | 85 ++++++++++- DiscImageChef.Devices/ChangeLog | 8 + DiscImageChef.Devices/Device/ScsiCommands.cs | 40 ++--- DiscImageChef/ChangeLog | 6 + DiscImageChef/Commands/MediaInfo.cs | 143 ++++++++++++++++-- 11 files changed, 287 insertions(+), 54 deletions(-) diff --git a/DiscImageChef.CommonTypes/ChangeLog b/DiscImageChef.CommonTypes/ChangeLog index 5d4c348c1..decfced16 100644 --- a/DiscImageChef.CommonTypes/ChangeLog +++ b/DiscImageChef.CommonTypes/ChangeLog @@ -1,3 +1,8 @@ +2015-11-24 Natalia Portillo + + * DiskType.cs: + Added DVD-RW DL, DVD-Download, HD DVD-R DL and HD DVD-RW DL. + 2015-11-23 Natalia Portillo * DiskType.cs: diff --git a/DiscImageChef.CommonTypes/DiskType.cs b/DiscImageChef.CommonTypes/DiskType.cs index c9751d374..d88395eae 100644 --- a/DiscImageChef.CommonTypes/DiskType.cs +++ b/DiscImageChef.CommonTypes/DiskType.cs @@ -108,6 +108,10 @@ namespace DiscImageChef.CommonTypes DVDPRDL, /// DVD-RAM DVDRAM, + /// DVD-RW DL + DVDRWDL, + /// DVD-Download + DVDDownload, // Standard HD-DVD formats /// HD DVD-ROM (applies to HD DVD Video) @@ -118,6 +122,10 @@ namespace DiscImageChef.CommonTypes HDDVDR, /// HD DVD-RW HDDVDRW, + /// HD DVD-R DL + HDDVDRDL, + /// HD DVD-RW DL + HDDVDRWDL, // Standard Blu-ray formats /// BD-ROM (and BD Video) diff --git a/DiscImageChef.Decoders/CD/ATIP.cs b/DiscImageChef.Decoders/CD/ATIP.cs index 32bbb6d2e..d9bd5c63a 100644 --- a/DiscImageChef.Decoders/CD/ATIP.cs +++ b/DiscImageChef.Decoders/CD/ATIP.cs @@ -231,7 +231,7 @@ namespace DiscImageChef.Decoders.CD BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian; - if (CDATIPResponse.Length != 32) + if (CDATIPResponse.Length != 32 && CDATIPResponse.Length != 28) { DicConsole.DebugWriteLine("CD ATIP decoder", "Expected CD ATIP size (32 bytes) is not received size ({0} bytes), not decoding", CDATIPResponse.Length); return null; @@ -267,17 +267,21 @@ namespace DiscImageChef.Decoders.CD decoded.A1Values = new byte[3]; decoded.A2Values = new byte[3]; decoded.A3Values = new byte[3]; - decoded.S4Values = new byte[3]; Array.Copy(CDATIPResponse, 16, decoded.A1Values, 0, 3); - Array.Copy(CDATIPResponse, 20, decoded.A1Values, 0, 3); - Array.Copy(CDATIPResponse, 24, decoded.A1Values, 0, 3); - Array.Copy(CDATIPResponse, 28, decoded.A1Values, 0, 3); + Array.Copy(CDATIPResponse, 20, decoded.A2Values, 0, 3); + Array.Copy(CDATIPResponse, 24, decoded.A3Values, 0, 3); decoded.Reserved7 = CDATIPResponse[19]; decoded.Reserved8 = CDATIPResponse[23]; decoded.Reserved9 = CDATIPResponse[27]; - decoded.Reserved10 = CDATIPResponse[31]; + + if (CDATIPResponse.Length >= 32) + { + decoded.S4Values = new byte[3]; + Array.Copy(CDATIPResponse, 28, decoded.S4Values, 0, 3); + decoded.Reserved10 = CDATIPResponse[31]; + } return decoded; } @@ -365,7 +369,8 @@ namespace DiscImageChef.Decoders.CD sb.AppendFormat("A2 value: 0x{0:X6}", (response.A2Values[0] << 16) + (response.A2Values[1] << 8) + response.A2Values[2]).AppendLine(); if(response.A3Valid) sb.AppendFormat("A3 value: 0x{0:X6}", (response.A3Values[0] << 16) + (response.A3Values[1] << 8) + response.A3Values[2]).AppendLine(); - sb.AppendFormat("S4 value: 0x{0:X6}", (response.S4Values[0] << 16) + (response.S4Values[1] << 8) + response.S4Values[2]).AppendLine(); + if(response.S4Values != null) + sb.AppendFormat("S4 value: 0x{0:X6}", (response.S4Values[0] << 16) + (response.S4Values[1] << 8) + response.S4Values[2]).AppendLine(); } return sb.ToString(); diff --git a/DiscImageChef.Decoders/CD/Session.cs b/DiscImageChef.Decoders/CD/Session.cs index 24b00ec24..cf6f9c417 100644 --- a/DiscImageChef.Decoders/CD/Session.cs +++ b/DiscImageChef.Decoders/CD/Session.cs @@ -158,11 +158,11 @@ namespace DiscImageChef.Decoders.CD sb.AppendFormat("Last complete session number: {0}", response.LastCompleteSession).AppendLine(); foreach (TrackDataDescriptor descriptor in response.TrackDescriptors) { - sb.AppendFormat("First track number in last complete session: {0}", descriptor.TrackNumber); + sb.AppendFormat("First track number in last complete session: {0}", descriptor.TrackNumber).AppendLine(); sb.AppendFormat("Track starts at LBA {0}, or MSF {1:X2}:{2:X2}:{3:X2}", descriptor.TrackStartAddress, (descriptor.TrackStartAddress & 0x0000FF00) >> 8, (descriptor.TrackStartAddress & 0x00FF0000) >> 16, - (descriptor.TrackStartAddress & 0xFF000000) >> 24); + (descriptor.TrackStartAddress & 0xFF000000) >> 24).AppendLine(); switch ((TOC_ADR)descriptor.ADR) { diff --git a/DiscImageChef.Decoders/CD/TOC.cs b/DiscImageChef.Decoders/CD/TOC.cs index 08d9ad11d..7ff0ebea5 100644 --- a/DiscImageChef.Decoders/CD/TOC.cs +++ b/DiscImageChef.Decoders/CD/TOC.cs @@ -158,11 +158,14 @@ namespace DiscImageChef.Decoders.CD sb.AppendFormat("Last track number in last complete session: {0}", response.LastTrack).AppendLine(); foreach (CDTOCTrackDataDescriptor descriptor in response.TrackDescriptors) { - sb.AppendFormat("Track number: {0}", descriptor.TrackNumber); + if (descriptor.TrackNumber == 0xAA) + sb.AppendLine("Track number: Lead-Out"); + else + sb.AppendFormat("Track number: {0}", descriptor.TrackNumber).AppendLine(); sb.AppendFormat("Track starts at LBA {0}, or MSF {1:X2}:{2:X2}:{3:X2}", descriptor.TrackStartAddress, (descriptor.TrackStartAddress & 0x0000FF00) >> 8, (descriptor.TrackStartAddress & 0x00FF0000) >> 16, - (descriptor.TrackStartAddress & 0xFF000000) >> 24); + (descriptor.TrackStartAddress & 0xFF000000) >> 24).AppendLine(); switch ((TOC_ADR)descriptor.ADR) { diff --git a/DiscImageChef.Decoders/ChangeLog b/DiscImageChef.Decoders/ChangeLog index 146cdee6c..fbd295f65 100644 --- a/DiscImageChef.Decoders/ChangeLog +++ b/DiscImageChef.Decoders/ChangeLog @@ -1,3 +1,19 @@ +2015-11-24 Natalia Portillo + + * CD/ATIP.cs: + ATIP not always contain S4. + Corrected typo. + + * CD/Session.cs: + Added missing newlines. + + * CD/TOC.cs: + Added missing newlines. + Recognize Lead-Out track. + + * SCSI/MMC/DiscInformation.cs: + Added structures for Disc Informations 001b and 010b. + 2015-11-23 Natalia Portillo * SCSI/Sense.cs: diff --git a/DiscImageChef.Decoders/SCSI/MMC/DiscInformation.cs b/DiscImageChef.Decoders/SCSI/MMC/DiscInformation.cs index 9e0ec88b5..f223f2c94 100644 --- a/DiscImageChef.Decoders/SCSI/MMC/DiscInformation.cs +++ b/DiscImageChef.Decoders/SCSI/MMC/DiscInformation.cs @@ -56,7 +56,7 @@ namespace DiscImageChef.Decoders.SCSI.MMC /// public static class DiscInformation { - public struct DiscInformationResponse + public struct StandardDiscInformation { /// /// Bytes 0 to 1 @@ -193,6 +193,89 @@ namespace DiscImageChef.Decoders.SCSI.MMC /// public byte[] OPCValues; } + + public struct TrackResourcesInformation + { + /// + /// Bytes 0 to 1 + /// 10 + /// + public UInt16 DataLength; + /// + /// Byte 2, bits 7 to 5 + /// 001b + /// + public byte DataType; + /// + /// Byte 2, bits 4 to 0 + /// Reserved + /// + public byte Reserved1; + /// + /// Byte 3 + /// Reserved + /// + public byte Reserved2; + /// + /// Bytes 4 to 5 + /// Maximum possible number of the tracks on the disc + /// + public UInt16 MaxTracks; + /// + /// Bytes 6 to 7 + /// Number of the assigned tracks on the disc + /// + public UInt16 AssignedTracks; + /// + /// Bytes 8 to 9 + /// Maximum possible number of appendable tracks on the disc + /// + public UInt16 MaxAppendableTracks; + /// + /// Bytes 10 to 11 + /// Current number of appendable tracks on the disc + /// + public UInt16 AppendableTracks; + } + + public struct POWResourcesInformation + { + /// + /// Bytes 0 to 1 + /// 14 + /// + public UInt16 DataLength; + /// + /// Byte 2, bits 7 to 5 + /// 010b + /// + public byte DataType; + /// + /// Byte 2, bits 4 to 0 + /// Reserved + /// + public byte Reserved1; + /// + /// Byte 3 + /// Reserved + /// + public byte Reserved2; + /// + /// Bytes 4 to 7 + /// Remaining POW replacements + /// + public UInt32 RemainingPOWReplacements; + /// + /// Bytes 8 to 11 + /// Remaining POW reallocation map entries + /// + public UInt32 RemainingPOWReallocation; + /// + /// Bytes 12 to 15 + /// Number of remaining POW updates + /// + public UInt32 RemainingPOWUpdates; + } } } diff --git a/DiscImageChef.Devices/ChangeLog b/DiscImageChef.Devices/ChangeLog index 38640d6d8..2256727eb 100644 --- a/DiscImageChef.Devices/ChangeLog +++ b/DiscImageChef.Devices/ChangeLog @@ -1,3 +1,11 @@ +2015-11-24 Natalia Portillo + + * Device/ScsiCommands.cs: + On READ TOC/PMA/ATIP and READ DISC INFORMATION if trying + small buffer and then real-sized buffer, some drives send + garbage, so get a big enough buffer and return only the + applicable data size. + 2015-11-23 Natalia Portillo * Enums.cs: diff --git a/DiscImageChef.Devices/Device/ScsiCommands.cs b/DiscImageChef.Devices/Device/ScsiCommands.cs index 94b612552..755c3c5e2 100644 --- a/DiscImageChef.Devices/Device/ScsiCommands.cs +++ b/DiscImageChef.Devices/Device/ScsiCommands.cs @@ -846,7 +846,7 @@ namespace DiscImageChef.Devices { senseBuffer = new byte[32]; byte[] cdb = new byte[10]; - buffer = new byte[2]; + byte[] tmpBuffer = new byte[804]; bool sense; cdb[0] = (byte)ScsiCommands.ReadTocPmaAtip; @@ -854,23 +854,15 @@ namespace DiscImageChef.Devices cdb[1] = 0x02; cdb[2] = (byte)(format & 0x0F); cdb[6] = trackSessionNumber; - cdb[7] = (byte)((buffer.Length & 0xFF00) >> 8); - cdb[8] = (byte)(buffer.Length & 0xFF); + cdb[7] = (byte)((tmpBuffer.Length & 0xFF00) >> 8); + cdb[8] = (byte)(tmpBuffer.Length & 0xFF); - lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense); + lastError = SendScsiCommand(cdb, ref tmpBuffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense); error = lastError != 0; - if (sense) - return true; - - uint strctLength = (uint)(((int)buffer[0] << 8) + buffer[1] + 2); - cdb[7] = (byte)((buffer.Length & 0xFF00) >> 8); - cdb[8] = (byte)(buffer.Length & 0xFF); + uint strctLength = (uint)(((int)tmpBuffer[0] << 8) + tmpBuffer[1] + 2); buffer = new byte[strctLength]; - senseBuffer = new byte[32]; - - lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense); - error = lastError != 0; + Array.Copy(tmpBuffer, 0, buffer, 0, buffer.Length); DicConsole.DebugWriteLine("SCSI Device", "READ TOC/PMA/ATIP took {0} ms.", duration); @@ -903,28 +895,20 @@ namespace DiscImageChef.Devices { senseBuffer = new byte[32]; byte[] cdb = new byte[10]; - buffer = new byte[2]; + byte[] tmpBuffer = new byte[804]; bool sense; cdb[0] = (byte)ScsiCommands.ReadDiscInformation; cdb[1] = (byte)dataType; - cdb[7] = (byte)((buffer.Length & 0xFF00) >> 8); - cdb[8] = (byte)(buffer.Length & 0xFF); + cdb[7] = (byte)((tmpBuffer.Length & 0xFF00) >> 8); + cdb[8] = (byte)(tmpBuffer.Length & 0xFF); - lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense); + lastError = SendScsiCommand(cdb, ref tmpBuffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense); error = lastError != 0; - if (sense) - return true; - - uint strctLength = (uint)(((int)buffer[0] << 8) + buffer[1] + 2); - cdb[7] = (byte)((buffer.Length & 0xFF00) >> 8); - cdb[8] = (byte)(buffer.Length & 0xFF); + uint strctLength = (uint)(((int)tmpBuffer[0] << 8) + tmpBuffer[1] + 2); buffer = new byte[strctLength]; - senseBuffer = new byte[32]; - - lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense); - error = lastError != 0; + Array.Copy(tmpBuffer, 0, buffer, 0, buffer.Length); DicConsole.DebugWriteLine("SCSI Device", "READ DISC INFORMATION took {0} ms.", duration); diff --git a/DiscImageChef/ChangeLog b/DiscImageChef/ChangeLog index 5d3083cca..020eeb0e0 100644 --- a/DiscImageChef/ChangeLog +++ b/DiscImageChef/ChangeLog @@ -1,3 +1,9 @@ +2015-11-24 Natalia Portillo + + * Commands/MediaInfo.cs: + Check current profile and prettify TOC, PMA, ATIP, Session + and CD-TEXT. + 2015-11-23 Natalia Portillo * Main.cs: diff --git a/DiscImageChef/Commands/MediaInfo.cs b/DiscImageChef/Commands/MediaInfo.cs index 2cf509cc3..35e0c578b 100644 --- a/DiscImageChef/Commands/MediaInfo.cs +++ b/DiscImageChef/Commands/MediaInfo.cs @@ -39,6 +39,7 @@ using System; using DiscImageChef.Console; using System.IO; using DiscImageChef.Devices; +using DiscImageChef.CommonTypes; namespace DiscImageChef.Commands { @@ -107,6 +108,7 @@ namespace DiscImageChef.Commands byte[] senseBuf; bool sense; double duration; + DiskType dskType = DiskType.Unknown; if (dev.SCSIType == DiscImageChef.Decoders.SCSI.PeripheralDeviceTypes.DirectAccess || dev.SCSIType == DiscImageChef.Decoders.SCSI.PeripheralDeviceTypes.MultiMediaDevice || @@ -175,13 +177,117 @@ namespace DiscImageChef.Commands Decoders.SCSI.MMC.Features.SeparatedFeatures ftr = Decoders.SCSI.MMC.Features.Separate(cmdBuf); DicConsole.DebugWriteLine("Media-Info command", "GET CONFIGURATION current profile is {0:X4}h", ftr.CurrentProfile); + + switch (ftr.CurrentProfile) + { + case 0x0001: + dskType = DiskType.GENERIC_HDD; + break; + case 0x0005: + dskType = DiskType.CDMO; + break; + case 0x0008: + dskType = DiskType.CDROM; + break; + case 0x0009: + dskType = DiskType.CDR; + break; + case 0x000A: + dskType = DiskType.CDRW; + break; + case 0x0010: + dskType = DiskType.DVDROM; + break; + case 0x0011: + dskType = DiskType.DVDR; + break; + case 0x0012: + dskType = DiskType.DVDRAM; + break; + case 0x0013: + case 0x0014: + dskType = DiskType.DVDRW; + break; + case 0x0015: + case 0x0016: + dskType = DiskType.DVDRDL; + break; + case 0x0017: + dskType = DiskType.DVDRWDL; + break; + case 0x0018: + dskType = DiskType.DVDDownload; + break; + case 0x001A: + dskType = DiskType.DVDPRW; + break; + case 0x001B: + dskType = DiskType.DVDPR; + break; + case 0x0020: + dskType = DiskType.DDCD; + break; + case 0x0021: + dskType = DiskType.DDCDR; + break; + case 0x0022: + dskType = DiskType.DDCDRW; + break; + case 0x002A: + dskType = DiskType.DVDPRWDL; + break; + case 0x002B: + dskType = DiskType.DVDPRDL; + break; + case 0x0040: + dskType = DiskType.BDROM; + break; + case 0x0041: + case 0x0042: + dskType = DiskType.BDR; + break; + case 0x0043: + dskType = DiskType.BDRE; + break; + case 0x0050: + dskType = DiskType.HDDVDROM; + break; + case 0x0051: + dskType = DiskType.HDDVDR; + break; + case 0x0052: + dskType = DiskType.HDDVDRAM; + break; + case 0x0053: + dskType = DiskType.HDDVDRW; + break; + case 0x0058: + dskType = DiskType.HDDVDRDL; + break; + case 0x005A: + dskType = DiskType.HDDVDRWDL; + break; + } + } + + DicConsole.WriteLine("{0}", dskType); + + sense = dev.ReadTocPmaAtip(out cmdBuf, out senseBuf, false, 0, 0, dev.Timeout, out duration); + if (sense) + DicConsole.ErrorWriteLine("READ TOC/PMA/ATIP: TOC\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf)); + else + { + DicConsole.WriteLine("TOC:\n{0}", Decoders.CD.TOC.Prettify(cmdBuf)); + doWriteFile(outputPrefix, "_toc.bin", "SCSI READ TOC/PMA/ATIP", cmdBuf); } sense = dev.ReadDiscInformation(out cmdBuf, out senseBuf, MmcDiscInformationDataTypes.DiscInformation, dev.Timeout, out duration); - if(sense) + if (sense) DicConsole.ErrorWriteLine("READ DISC INFORMATION 000b\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf)); else + { doWriteFile(outputPrefix, "_readdiscinformation_000b.bin", "SCSI READ DISC INFORMATION", cmdBuf); + } sense = dev.ReadDiscInformation(out cmdBuf, out senseBuf, MmcDiscInformationDataTypes.TrackResources, dev.Timeout, out duration); if(sense) @@ -195,8 +301,6 @@ namespace DiscImageChef.Commands else doWriteFile(outputPrefix, "_readdiscinformation_010b.bin", "SCSI READ DISC INFORMATION", cmdBuf); - - sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.AACSVolId, 0, dev.Timeout, out duration); if(sense) DicConsole.ErrorWriteLine("READ DISC STRUCTURE: AACS Volume ID\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf)); @@ -433,36 +537,47 @@ namespace DiscImageChef.Commands doWriteFile(outputPrefix, "_readdiscstructure_bd_pac.bin", "SCSI READ DISC STRUCTURE", cmdBuf); - sense = dev.ReadToc(out cmdBuf, out senseBuf, 0, dev.Timeout, out duration); - if(sense) - DicConsole.ErrorWriteLine("READ TOC/PMA/ATIP: TOC\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf)); - else - doWriteFile(outputPrefix, "_toc.bin", "SCSI READ TOC/PMA/ATIP", cmdBuf); sense = dev.ReadSessionInfo(out cmdBuf, out senseBuf, dev.Timeout, out duration); - if(sense) + if (sense) DicConsole.ErrorWriteLine("READ TOC/PMA/ATIP: Session info\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf)); else + { doWriteFile(outputPrefix, "_session.bin", "SCSI READ TOC/PMA/ATIP", cmdBuf); - sense = dev.ReadRawToc(out cmdBuf, out senseBuf, 0, dev.Timeout, out duration); - if(sense) + DicConsole.WriteLine("Session information:\n{0}", Decoders.CD.Session.Prettify(cmdBuf)); + } + sense = dev.ReadRawToc(out cmdBuf, out senseBuf, 1, dev.Timeout, out duration); + if (sense) DicConsole.ErrorWriteLine("READ TOC/PMA/ATIP: Raw TOC\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf)); else + { doWriteFile(outputPrefix, "_rawtoc.bin", "SCSI READ TOC/PMA/ATIP", cmdBuf); + DicConsole.WriteLine("Raw TOC:\n{0}", Decoders.CD.FullTOC.Prettify(cmdBuf)); + } sense = dev.ReadPma(out cmdBuf, out senseBuf, dev.Timeout, out duration); - if(sense) + if (sense) DicConsole.ErrorWriteLine("READ TOC/PMA/ATIP: PMA\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf)); else + { doWriteFile(outputPrefix, "_pma.bin", "SCSI READ TOC/PMA/ATIP", cmdBuf); + DicConsole.WriteLine("PMA:\n{0}", Decoders.CD.PMA.Prettify(cmdBuf)); + } sense = dev.ReadAtip(out cmdBuf, out senseBuf, dev.Timeout, out duration); - if(sense) + if (sense) DicConsole.ErrorWriteLine("READ TOC/PMA/ATIP: ATIP\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf)); else + { doWriteFile(outputPrefix, "_atip.bin", "SCSI READ TOC/PMA/ATIP", cmdBuf); + DicConsole.WriteLine("ATIP:\n{0}", Decoders.CD.ATIP.Prettify(cmdBuf)); + } + sense = dev.ReadCdText(out cmdBuf, out senseBuf, dev.Timeout, out duration); - if(sense) + if (sense) DicConsole.ErrorWriteLine("READ TOC/PMA/ATIP: CD-TEXT\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf)); else + { doWriteFile(outputPrefix, "_cdtext.bin", "SCSI READ TOC/PMA/ATIP", cmdBuf); + DicConsole.WriteLine("CD-TEXT on Lead-In:\n{0}", Decoders.CD.CDTextOnLeadIn.Prettify(cmdBuf)); + } } }