mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Add support for dumping ISRC and MCN.
This commit is contained in:
@@ -57,7 +57,7 @@ namespace DiscImageChef.Core.Devices.Dumping
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implement dumping Compact Discs
|
/// Implement dumping Compact Discs
|
||||||
/// </summary>
|
/// </summary>
|
||||||
// TODO: ISRC, MCN and pregaps
|
// TODO: Barcode and pregaps
|
||||||
static class CompactDisc
|
static class CompactDisc
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -757,6 +757,29 @@ namespace DiscImageChef.Core.Devices.Dumping
|
|||||||
outputPlugin.WriteSectorTag(new[] {kvp.Value}, track.TrackStartSector, SectorTagType.CdTrackFlags);
|
outputPlugin.WriteSectorTag(new[] {kvp.Value}, track.TrackStartSector, SectorTagType.CdTrackFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set MCN
|
||||||
|
sense = dev.ReadMcn(out string mcn, out _, out _, dev.Timeout, out _);
|
||||||
|
if(!sense && mcn != null && mcn != "0000000000000")
|
||||||
|
if(outputPlugin.WriteMediaTag(Encoding.ASCII.GetBytes(mcn), MediaTagType.CD_MCN))
|
||||||
|
{
|
||||||
|
DicConsole.WriteLine("Setting disc Media Catalogue Number to {0}", mcn);
|
||||||
|
dumpLog.WriteLine("Setting disc Media Catalogue Number to {0}", mcn);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set ISRCs
|
||||||
|
foreach(Track trk in tracks)
|
||||||
|
{
|
||||||
|
sense = dev.ReadIsrc((byte)trk.TrackSequence, out string isrc, out _, out _, dev.Timeout, out _);
|
||||||
|
if(sense || isrc == null || isrc == "000000000000") continue;
|
||||||
|
|
||||||
|
if(outputPlugin.WriteSectorTag(Encoding.ASCII.GetBytes(isrc), trk.TrackStartSector,
|
||||||
|
SectorTagType.CdTrackIsrc))
|
||||||
|
{
|
||||||
|
DicConsole.WriteLine("Setting ISRC for track {0} to {1}", trk.TrackSequence, isrc);
|
||||||
|
dumpLog.WriteLine("Setting ISRC for track {0} to {1}", trk.TrackSequence, isrc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(resume.NextBlock > 0) dumpLog.WriteLine("Resuming from block {0}.", resume.NextBlock);
|
if(resume.NextBlock > 0) dumpLog.WriteLine("Resuming from block {0}.", resume.NextBlock);
|
||||||
|
|
||||||
double imageWriteDuration = 0;
|
double imageWriteDuration = 0;
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
// ****************************************************************************/
|
// ****************************************************************************/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Text;
|
||||||
using DiscImageChef.Console;
|
using DiscImageChef.Console;
|
||||||
|
|
||||||
namespace DiscImageChef.Devices
|
namespace DiscImageChef.Devices
|
||||||
@@ -60,11 +61,11 @@ namespace DiscImageChef.Devices
|
|||||||
/// <param name="startingFeatureNumber">Feature number where the feature list should start from</param>
|
/// <param name="startingFeatureNumber">Feature number where the feature list should start from</param>
|
||||||
/// <param name="timeout">Timeout in seconds.</param>
|
/// <param name="timeout">Timeout in seconds.</param>
|
||||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||||
public bool GetConfiguration(out byte[] buffer, out byte[] senseBuffer, ushort startingFeatureNumber,
|
public bool GetConfiguration(out byte[] buffer, out byte[] senseBuffer, ushort startingFeatureNumber,
|
||||||
uint timeout, out double duration)
|
uint timeout, out double duration)
|
||||||
{
|
{
|
||||||
return GetConfiguration(out buffer, out senseBuffer, startingFeatureNumber, MmcGetConfigurationRt.All,
|
return GetConfiguration(out buffer, out senseBuffer, startingFeatureNumber, MmcGetConfigurationRt.All,
|
||||||
timeout, out duration);
|
timeout, out duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -77,19 +78,19 @@ namespace DiscImageChef.Devices
|
|||||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||||
/// <param name="startingFeatureNumber">Starting Feature number.</param>
|
/// <param name="startingFeatureNumber">Starting Feature number.</param>
|
||||||
/// <param name="rt">Return type, <see cref="MmcGetConfigurationRt" />.</param>
|
/// <param name="rt">Return type, <see cref="MmcGetConfigurationRt" />.</param>
|
||||||
public bool GetConfiguration(out byte[] buffer, out byte[] senseBuffer, ushort startingFeatureNumber,
|
public bool GetConfiguration(out byte[] buffer, out byte[] senseBuffer, ushort startingFeatureNumber,
|
||||||
MmcGetConfigurationRt rt, uint timeout, out double duration)
|
MmcGetConfigurationRt rt, uint timeout, out double duration)
|
||||||
{
|
{
|
||||||
senseBuffer = new byte[32];
|
senseBuffer = new byte[32];
|
||||||
byte[] cdb = new byte[10];
|
byte[] cdb = new byte[10];
|
||||||
buffer = new byte[8];
|
buffer = new byte[8];
|
||||||
|
|
||||||
cdb[0] = (byte)ScsiCommands.GetConfiguration;
|
cdb[0] = (byte)ScsiCommands.GetConfiguration;
|
||||||
cdb[1] = (byte)((byte)rt & 0x03);
|
cdb[1] = (byte)((byte)rt & 0x03);
|
||||||
cdb[2] = (byte)((startingFeatureNumber & 0xFF00) >> 8);
|
cdb[2] = (byte)((startingFeatureNumber & 0xFF00) >> 8);
|
||||||
cdb[3] = (byte)(startingFeatureNumber & 0xFF);
|
cdb[3] = (byte)(startingFeatureNumber & 0xFF);
|
||||||
cdb[7] = (byte)((buffer.Length & 0xFF00) >> 8);
|
cdb[7] = (byte)((buffer.Length & 0xFF00) >> 8);
|
||||||
cdb[8] = (byte)(buffer.Length & 0xFF);
|
cdb[8] = (byte)(buffer.Length & 0xFF);
|
||||||
cdb[9] = 0;
|
cdb[9] = 0;
|
||||||
|
|
||||||
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||||
@@ -99,10 +100,10 @@ namespace DiscImageChef.Devices
|
|||||||
if(sense) return true;
|
if(sense) return true;
|
||||||
|
|
||||||
ushort confLength = (ushort)((buffer[2] << 8) + buffer[3] + 4);
|
ushort confLength = (ushort)((buffer[2] << 8) + buffer[3] + 4);
|
||||||
buffer = new byte[confLength];
|
buffer = new byte[confLength];
|
||||||
cdb[7] = (byte)((buffer.Length & 0xFF00) >> 8);
|
cdb[7] = (byte)((buffer.Length & 0xFF00) >> 8);
|
||||||
cdb[8] = (byte)(buffer.Length & 0xFF);
|
cdb[8] = (byte)(buffer.Length & 0xFF);
|
||||||
senseBuffer = new byte[32];
|
senseBuffer = new byte[32];
|
||||||
|
|
||||||
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||||
out sense);
|
out sense);
|
||||||
@@ -127,24 +128,25 @@ namespace DiscImageChef.Devices
|
|||||||
/// <param name="agid">AGID used in medium copy protection</param>
|
/// <param name="agid">AGID used in medium copy protection</param>
|
||||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||||
public bool ReadDiscStructure(out byte[] buffer, out byte[] senseBuffer, MmcDiscStructureMediaType mediaType,
|
public bool ReadDiscStructure(out byte[] buffer, out byte[] senseBuffer, MmcDiscStructureMediaType mediaType,
|
||||||
uint address, byte layerNumber, MmcDiscStructureFormat format, byte agid,
|
uint address, byte layerNumber, MmcDiscStructureFormat format,
|
||||||
uint timeout, out double duration)
|
byte agid,
|
||||||
|
uint timeout, out double duration)
|
||||||
{
|
{
|
||||||
senseBuffer = new byte[32];
|
senseBuffer = new byte[32];
|
||||||
byte[] cdb = new byte[12];
|
byte[] cdb = new byte[12];
|
||||||
buffer = new byte[8];
|
buffer = new byte[8];
|
||||||
|
|
||||||
cdb[0] = (byte)ScsiCommands.ReadDiscStructure;
|
cdb[0] = (byte)ScsiCommands.ReadDiscStructure;
|
||||||
cdb[1] = (byte)((byte)mediaType & 0x0F);
|
cdb[1] = (byte)((byte)mediaType & 0x0F);
|
||||||
cdb[2] = (byte)((address & 0xFF000000) >> 24);
|
cdb[2] = (byte)((address & 0xFF000000) >> 24);
|
||||||
cdb[3] = (byte)((address & 0xFF0000) >> 16);
|
cdb[3] = (byte)((address & 0xFF0000) >> 16);
|
||||||
cdb[4] = (byte)((address & 0xFF00) >> 8);
|
cdb[4] = (byte)((address & 0xFF00) >> 8);
|
||||||
cdb[5] = (byte)(address & 0xFF);
|
cdb[5] = (byte)(address & 0xFF);
|
||||||
cdb[6] = layerNumber;
|
cdb[6] = layerNumber;
|
||||||
cdb[7] = (byte)format;
|
cdb[7] = (byte)format;
|
||||||
cdb[8] = (byte)((buffer.Length & 0xFF00) >> 8);
|
cdb[8] = (byte)((buffer.Length & 0xFF00) >> 8);
|
||||||
cdb[9] = (byte)(buffer.Length & 0xFF);
|
cdb[9] = (byte)(buffer.Length & 0xFF);
|
||||||
cdb[10] = (byte)((agid & 0x03) << 6);
|
cdb[10] = (byte)((agid & 0x03) << 6);
|
||||||
|
|
||||||
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||||
out bool sense);
|
out bool sense);
|
||||||
@@ -153,10 +155,10 @@ namespace DiscImageChef.Devices
|
|||||||
if(sense) return true;
|
if(sense) return true;
|
||||||
|
|
||||||
ushort strctLength = (ushort)((buffer[0] << 8) + buffer[1] + 2);
|
ushort strctLength = (ushort)((buffer[0] << 8) + buffer[1] + 2);
|
||||||
buffer = new byte[strctLength];
|
buffer = new byte[strctLength];
|
||||||
cdb[8] = (byte)((buffer.Length & 0xFF00) >> 8);
|
cdb[8] = (byte)((buffer.Length & 0xFF00) >> 8);
|
||||||
cdb[9] = (byte)(buffer.Length & 0xFF);
|
cdb[9] = (byte)(buffer.Length & 0xFF);
|
||||||
senseBuffer = new byte[32];
|
senseBuffer = new byte[32];
|
||||||
|
|
||||||
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||||
out sense);
|
out sense);
|
||||||
@@ -290,27 +292,27 @@ namespace DiscImageChef.Devices
|
|||||||
/// <param name="trackSessionNumber">Track/Session number</param>
|
/// <param name="trackSessionNumber">Track/Session number</param>
|
||||||
/// <param name="timeout">Timeout in seconds.</param>
|
/// <param name="timeout">Timeout in seconds.</param>
|
||||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||||
public bool ReadTocPmaAtip(out byte[] buffer, out byte[] senseBuffer, bool msf, byte format,
|
public bool ReadTocPmaAtip(out byte[] buffer, out byte[] senseBuffer, bool msf, byte format,
|
||||||
byte trackSessionNumber, uint timeout, out double duration)
|
byte trackSessionNumber, uint timeout, out double duration)
|
||||||
{
|
{
|
||||||
senseBuffer = new byte[32];
|
senseBuffer = new byte[32];
|
||||||
byte[] cdb = new byte[10];
|
byte[] cdb = new byte[10];
|
||||||
|
|
||||||
byte[] tmpBuffer = (format & 0x0F) == 5 ? new byte[32768] : new byte[1024];
|
byte[] tmpBuffer = (format & 0x0F) == 5 ? new byte[32768] : new byte[1024];
|
||||||
|
|
||||||
cdb[0] = (byte)ScsiCommands.ReadTocPmaAtip;
|
cdb[0] = (byte)ScsiCommands.ReadTocPmaAtip;
|
||||||
if(msf) cdb[1] = 0x02;
|
if(msf) cdb[1] = 0x02;
|
||||||
cdb[2] = (byte)(format & 0x0F);
|
cdb[2] = (byte)(format & 0x0F);
|
||||||
cdb[6] = trackSessionNumber;
|
cdb[6] = trackSessionNumber;
|
||||||
cdb[7] = (byte)((tmpBuffer.Length & 0xFF00) >> 8);
|
cdb[7] = (byte)((tmpBuffer.Length & 0xFF00) >> 8);
|
||||||
cdb[8] = (byte)(tmpBuffer.Length & 0xFF);
|
cdb[8] = (byte)(tmpBuffer.Length & 0xFF);
|
||||||
|
|
||||||
LastError = SendScsiCommand(cdb, ref tmpBuffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
LastError = SendScsiCommand(cdb, ref tmpBuffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||||
out bool sense);
|
out bool sense);
|
||||||
Error = LastError != 0;
|
Error = LastError != 0;
|
||||||
|
|
||||||
uint strctLength = (uint)((tmpBuffer[0] << 8) + tmpBuffer[1] + 2);
|
uint strctLength = (uint)((tmpBuffer[0] << 8) + tmpBuffer[1] + 2);
|
||||||
buffer = new byte[strctLength];
|
buffer = new byte[strctLength];
|
||||||
|
|
||||||
if(buffer.Length <= tmpBuffer.Length)
|
if(buffer.Length <= tmpBuffer.Length)
|
||||||
{
|
{
|
||||||
@@ -341,7 +343,7 @@ namespace DiscImageChef.Devices
|
|||||||
public bool ReadDiscInformation(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
|
public bool ReadDiscInformation(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
|
||||||
{
|
{
|
||||||
return ReadDiscInformation(out buffer, out senseBuffer, MmcDiscInformationDataTypes.DiscInformation,
|
return ReadDiscInformation(out buffer, out senseBuffer, MmcDiscInformationDataTypes.DiscInformation,
|
||||||
timeout, out duration);
|
timeout, out duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -353,24 +355,25 @@ namespace DiscImageChef.Devices
|
|||||||
/// <param name="dataType">Which disc information to read</param>
|
/// <param name="dataType">Which disc information to read</param>
|
||||||
/// <param name="timeout">Timeout in seconds.</param>
|
/// <param name="timeout">Timeout in seconds.</param>
|
||||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||||
public bool ReadDiscInformation(out byte[] buffer, out byte[] senseBuffer, MmcDiscInformationDataTypes dataType,
|
public bool ReadDiscInformation(out byte[] buffer, out byte[] senseBuffer,
|
||||||
uint timeout, out double duration)
|
MmcDiscInformationDataTypes dataType,
|
||||||
|
uint timeout, out double duration)
|
||||||
{
|
{
|
||||||
senseBuffer = new byte[32];
|
senseBuffer = new byte[32];
|
||||||
byte[] cdb = new byte[10];
|
byte[] cdb = new byte[10];
|
||||||
byte[] tmpBuffer = new byte[804];
|
byte[] tmpBuffer = new byte[804];
|
||||||
|
|
||||||
cdb[0] = (byte)ScsiCommands.ReadDiscInformation;
|
cdb[0] = (byte)ScsiCommands.ReadDiscInformation;
|
||||||
cdb[1] = (byte)dataType;
|
cdb[1] = (byte)dataType;
|
||||||
cdb[7] = (byte)((tmpBuffer.Length & 0xFF00) >> 8);
|
cdb[7] = (byte)((tmpBuffer.Length & 0xFF00) >> 8);
|
||||||
cdb[8] = (byte)(tmpBuffer.Length & 0xFF);
|
cdb[8] = (byte)(tmpBuffer.Length & 0xFF);
|
||||||
|
|
||||||
LastError = SendScsiCommand(cdb, ref tmpBuffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
LastError = SendScsiCommand(cdb, ref tmpBuffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||||
out bool sense);
|
out bool sense);
|
||||||
Error = LastError != 0;
|
Error = LastError != 0;
|
||||||
|
|
||||||
uint strctLength = (uint)((tmpBuffer[0] << 8) + tmpBuffer[1] + 2);
|
uint strctLength = (uint)((tmpBuffer[0] << 8) + tmpBuffer[1] + 2);
|
||||||
buffer = new byte[strctLength];
|
buffer = new byte[strctLength];
|
||||||
Array.Copy(tmpBuffer, 0, buffer, 0, buffer.Length);
|
Array.Copy(tmpBuffer, 0, buffer, 0, buffer.Length);
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("SCSI Device", "READ DISC INFORMATION took {0} ms.", duration);
|
DicConsole.DebugWriteLine("SCSI Device", "READ DISC INFORMATION took {0} ms.", duration);
|
||||||
@@ -398,31 +401,32 @@ namespace DiscImageChef.Devices
|
|||||||
/// <param name="edcEcc">If set to <c>true</c> we request the EDC/ECC fields for data sectors.</param>
|
/// <param name="edcEcc">If set to <c>true</c> we request the EDC/ECC fields for data sectors.</param>
|
||||||
/// <param name="c2Error">C2 error options.</param>
|
/// <param name="c2Error">C2 error options.</param>
|
||||||
/// <param name="subchannel">Subchannel selection.</param>
|
/// <param name="subchannel">Subchannel selection.</param>
|
||||||
public bool ReadCd(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize, uint transferLength,
|
public bool ReadCd(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize,
|
||||||
MmcSectorTypes expectedSectorType, bool dap, bool relAddr, bool sync,
|
uint transferLength,
|
||||||
MmcHeaderCodes headerCodes, bool userData, bool edcEcc, MmcErrorField c2Error,
|
MmcSectorTypes expectedSectorType, bool dap, bool relAddr, bool sync,
|
||||||
MmcSubchannel subchannel, uint timeout, out double duration)
|
MmcHeaderCodes headerCodes, bool userData, bool edcEcc, MmcErrorField c2Error,
|
||||||
|
MmcSubchannel subchannel, uint timeout, out double duration)
|
||||||
{
|
{
|
||||||
senseBuffer = new byte[32];
|
senseBuffer = new byte[32];
|
||||||
byte[] cdb = new byte[12];
|
byte[] cdb = new byte[12];
|
||||||
|
|
||||||
cdb[0] = (byte)ScsiCommands.ReadCd;
|
cdb[0] = (byte)ScsiCommands.ReadCd;
|
||||||
cdb[1] = (byte)((byte)expectedSectorType << 2);
|
cdb[1] = (byte)((byte)expectedSectorType << 2);
|
||||||
if(dap) cdb[1] += 0x02;
|
if(dap) cdb[1] += 0x02;
|
||||||
if(relAddr) cdb[1] += 0x01;
|
if(relAddr) cdb[1] += 0x01;
|
||||||
cdb[2] = (byte)((lba & 0xFF000000) >> 24);
|
cdb[2] = (byte)((lba & 0xFF000000) >> 24);
|
||||||
cdb[3] = (byte)((lba & 0xFF0000) >> 16);
|
cdb[3] = (byte)((lba & 0xFF0000) >> 16);
|
||||||
cdb[4] = (byte)((lba & 0xFF00) >> 8);
|
cdb[4] = (byte)((lba & 0xFF00) >> 8);
|
||||||
cdb[5] = (byte)(lba & 0xFF);
|
cdb[5] = (byte)(lba & 0xFF);
|
||||||
cdb[6] = (byte)((transferLength & 0xFF0000) >> 16);
|
cdb[6] = (byte)((transferLength & 0xFF0000) >> 16);
|
||||||
cdb[7] = (byte)((transferLength & 0xFF00) >> 8);
|
cdb[7] = (byte)((transferLength & 0xFF00) >> 8);
|
||||||
cdb[8] = (byte)(transferLength & 0xFF);
|
cdb[8] = (byte)(transferLength & 0xFF);
|
||||||
cdb[9] = (byte)((byte)c2Error << 1);
|
cdb[9] = (byte)((byte)c2Error << 1);
|
||||||
cdb[9] += (byte)((byte)headerCodes << 5);
|
cdb[9] += (byte)((byte)headerCodes << 5);
|
||||||
if(sync) cdb[9] += 0x80;
|
if(sync) cdb[9] += 0x80;
|
||||||
if(userData) cdb[9] += 0x10;
|
if(userData) cdb[9] += 0x10;
|
||||||
if(edcEcc) cdb[9] += 0x08;
|
if(edcEcc) cdb[9] += 0x08;
|
||||||
cdb[10] = (byte)subchannel;
|
cdb[10] = (byte)subchannel;
|
||||||
|
|
||||||
buffer = new byte[blockSize * transferLength];
|
buffer = new byte[blockSize * transferLength];
|
||||||
|
|
||||||
@@ -454,29 +458,32 @@ namespace DiscImageChef.Devices
|
|||||||
/// <param name="edcEcc">If set to <c>true</c> we request the EDC/ECC fields for data sectors.</param>
|
/// <param name="edcEcc">If set to <c>true</c> we request the EDC/ECC fields for data sectors.</param>
|
||||||
/// <param name="c2Error">C2 error options.</param>
|
/// <param name="c2Error">C2 error options.</param>
|
||||||
/// <param name="subchannel">Subchannel selection.</param>
|
/// <param name="subchannel">Subchannel selection.</param>
|
||||||
public bool ReadCdMsf(out byte[] buffer, out byte[] senseBuffer, uint startMsf, uint endMsf, uint blockSize,
|
public bool ReadCdMsf(out byte[] buffer, out byte[] senseBuffer, uint startMsf,
|
||||||
MmcSectorTypes expectedSectorType, bool dap, bool sync, MmcHeaderCodes headerCodes,
|
uint endMsf, uint blockSize,
|
||||||
bool userData, bool edcEcc, MmcErrorField c2Error, MmcSubchannel subchannel, uint timeout,
|
MmcSectorTypes expectedSectorType, bool dap, bool sync,
|
||||||
out double duration)
|
MmcHeaderCodes headerCodes,
|
||||||
|
bool userData, bool edcEcc, MmcErrorField c2Error,
|
||||||
|
MmcSubchannel subchannel, uint timeout,
|
||||||
|
out double duration)
|
||||||
{
|
{
|
||||||
senseBuffer = new byte[32];
|
senseBuffer = new byte[32];
|
||||||
byte[] cdb = new byte[12];
|
byte[] cdb = new byte[12];
|
||||||
|
|
||||||
cdb[0] = (byte)ScsiCommands.ReadCdMsf;
|
cdb[0] = (byte)ScsiCommands.ReadCdMsf;
|
||||||
cdb[1] = (byte)((byte)expectedSectorType << 2);
|
cdb[1] = (byte)((byte)expectedSectorType << 2);
|
||||||
if(dap) cdb[1] += 0x02;
|
if(dap) cdb[1] += 0x02;
|
||||||
cdb[3] = (byte)((startMsf & 0xFF0000) >> 16);
|
cdb[3] = (byte)((startMsf & 0xFF0000) >> 16);
|
||||||
cdb[4] = (byte)((startMsf & 0xFF00) >> 8);
|
cdb[4] = (byte)((startMsf & 0xFF00) >> 8);
|
||||||
cdb[5] = (byte)(startMsf & 0xFF);
|
cdb[5] = (byte)(startMsf & 0xFF);
|
||||||
cdb[6] = (byte)((endMsf & 0xFF0000) >> 16);
|
cdb[6] = (byte)((endMsf & 0xFF0000) >> 16);
|
||||||
cdb[7] = (byte)((endMsf & 0xFF00) >> 8);
|
cdb[7] = (byte)((endMsf & 0xFF00) >> 8);
|
||||||
cdb[8] = (byte)(endMsf & 0xFF);
|
cdb[8] = (byte)(endMsf & 0xFF);
|
||||||
cdb[9] = (byte)((byte)c2Error << 1);
|
cdb[9] = (byte)((byte)c2Error << 1);
|
||||||
cdb[9] += (byte)((byte)headerCodes << 5);
|
cdb[9] += (byte)((byte)headerCodes << 5);
|
||||||
if(sync) cdb[9] += 0x80;
|
if(sync) cdb[9] += 0x80;
|
||||||
if(userData) cdb[9] += 0x10;
|
if(userData) cdb[9] += 0x10;
|
||||||
if(edcEcc) cdb[9] += 0x08;
|
if(edcEcc) cdb[9] += 0x08;
|
||||||
cdb[10] = (byte)subchannel;
|
cdb[10] = (byte)subchannel;
|
||||||
|
|
||||||
uint transferLength = (uint)((cdb[6] - cdb[3]) * 60 * 75 + (cdb[7] - cdb[4]) * 75 + (cdb[8] - cdb[5]));
|
uint transferLength = (uint)((cdb[6] - cdb[3]) * 60 * 75 + (cdb[7] - cdb[4]) * 75 + (cdb[8] - cdb[5]));
|
||||||
|
|
||||||
@@ -504,12 +511,12 @@ namespace DiscImageChef.Devices
|
|||||||
public bool PreventAllowMediumRemoval(out byte[] senseBuffer, bool persistent, bool prevent, uint timeout,
|
public bool PreventAllowMediumRemoval(out byte[] senseBuffer, bool persistent, bool prevent, uint timeout,
|
||||||
out double duration)
|
out double duration)
|
||||||
{
|
{
|
||||||
senseBuffer = new byte[32];
|
senseBuffer = new byte[32];
|
||||||
byte[] cdb = new byte[6];
|
byte[] cdb = new byte[6];
|
||||||
byte[] buffer = new byte[0];
|
byte[] buffer = new byte[0];
|
||||||
|
|
||||||
cdb[0] = (byte)ScsiCommands.PreventAllowMediumRemoval;
|
cdb[0] = (byte)ScsiCommands.PreventAllowMediumRemoval;
|
||||||
if(prevent) cdb[4] += 0x01;
|
if(prevent) cdb[4] += 0x01;
|
||||||
if(persistent) cdb[4] += 0x02;
|
if(persistent) cdb[4] += 0x02;
|
||||||
|
|
||||||
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration,
|
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration,
|
||||||
@@ -541,25 +548,27 @@ namespace DiscImageChef.Devices
|
|||||||
return StartStopUnit(out senseBuffer, false, 0, 0, false, false, false, timeout, out duration);
|
return StartStopUnit(out senseBuffer, false, 0, 0, false, false, false, timeout, out duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool StartStopUnit(out byte[] senseBuffer, bool immediate, byte formatLayer, byte powerConditions,
|
public bool StartStopUnit(out byte[] senseBuffer, bool immediate, byte formatLayer, byte powerConditions,
|
||||||
bool changeFormatLayer, bool loadEject, bool start, uint timeout, out double duration)
|
bool changeFormatLayer, bool loadEject, bool start, uint timeout,
|
||||||
|
out double duration)
|
||||||
{
|
{
|
||||||
senseBuffer = new byte[32];
|
senseBuffer = new byte[32];
|
||||||
byte[] cdb = new byte[6];
|
byte[] cdb = new byte[6];
|
||||||
byte[] buffer = new byte[0];
|
byte[] buffer = new byte[0];
|
||||||
|
|
||||||
cdb[0] = (byte)ScsiCommands.StartStopUnit;
|
cdb[0] = (byte)ScsiCommands.StartStopUnit;
|
||||||
if(immediate) cdb[1] += 0x01;
|
if(immediate) cdb[1] += 0x01;
|
||||||
if(changeFormatLayer)
|
if(changeFormatLayer)
|
||||||
{
|
{
|
||||||
cdb[3] = (byte)(formatLayer & 0x03);
|
cdb[3] = (byte)(formatLayer & 0x03);
|
||||||
cdb[4] += 0x04;
|
cdb[4] += 0x04;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(loadEject) cdb[4] += 0x02;
|
if(loadEject) cdb[4] += 0x02;
|
||||||
if(start) cdb[4] += 0x01;
|
if(start) cdb[4] += 0x01;
|
||||||
}
|
}
|
||||||
|
|
||||||
cdb[4] += (byte)((powerConditions & 0x0F) << 4);
|
cdb[4] += (byte)((powerConditions & 0x0F) << 4);
|
||||||
|
|
||||||
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration,
|
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration,
|
||||||
@@ -570,5 +579,60 @@ namespace DiscImageChef.Devices
|
|||||||
|
|
||||||
return sense;
|
return sense;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool ReadMcn(out string mcn, out byte[] buffer, out byte[] senseBuffer, uint timeout,
|
||||||
|
out double duration)
|
||||||
|
{
|
||||||
|
senseBuffer = new byte[32];
|
||||||
|
byte[] cdb = new byte[10];
|
||||||
|
mcn = null;
|
||||||
|
|
||||||
|
cdb[0] = (byte)ScsiCommands.ReadSubChannel;
|
||||||
|
cdb[1] = 0;
|
||||||
|
cdb[2] = 0x40;
|
||||||
|
cdb[3] = 0x02;
|
||||||
|
cdb[7] = (23 & 0xFF00) >> 8;
|
||||||
|
cdb[8] = 23 & 0xFF;
|
||||||
|
|
||||||
|
buffer = new byte[23];
|
||||||
|
|
||||||
|
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||||
|
out bool sense);
|
||||||
|
Error = LastError != 0;
|
||||||
|
|
||||||
|
DicConsole.DebugWriteLine("SCSI Device", "READ READ SUB-CHANNEL (MCN) took {0} ms.", duration);
|
||||||
|
|
||||||
|
if(!sense && (buffer[8] & 0x80) == 0x80) mcn = Encoding.ASCII.GetString(buffer, 9, 13);
|
||||||
|
|
||||||
|
return sense;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ReadIsrc(byte trackNumber, out string isrc, out byte[] buffer, out byte[] senseBuffer, uint timeout,
|
||||||
|
out double duration)
|
||||||
|
{
|
||||||
|
senseBuffer = new byte[32];
|
||||||
|
byte[] cdb = new byte[10];
|
||||||
|
isrc = null;
|
||||||
|
|
||||||
|
cdb[0] = (byte)ScsiCommands.ReadSubChannel;
|
||||||
|
cdb[1] = 0;
|
||||||
|
cdb[2] = 0x40;
|
||||||
|
cdb[3] = 0x03;
|
||||||
|
cdb[6] = trackNumber;
|
||||||
|
cdb[7] = (23 & 0xFF00) >> 8;
|
||||||
|
cdb[8] = 23 & 0xFF;
|
||||||
|
|
||||||
|
buffer = new byte[23];
|
||||||
|
|
||||||
|
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||||
|
out bool sense);
|
||||||
|
Error = LastError != 0;
|
||||||
|
|
||||||
|
DicConsole.DebugWriteLine("SCSI Device", "READ READ SUB-CHANNEL (ISRC) took {0} ms.", duration);
|
||||||
|
|
||||||
|
if(!sense && (buffer[8] & 0x80) == 0x80) isrc = Encoding.ASCII.GetString(buffer, 9, 12);
|
||||||
|
|
||||||
|
return sense;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -56,9 +56,9 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
internal static void DoMediaInfo(MediaInfoOptions options)
|
internal static void DoMediaInfo(MediaInfoOptions options)
|
||||||
{
|
{
|
||||||
DicConsole.DebugWriteLine("Media-Info command", "--debug={0}", options.Debug);
|
DicConsole.DebugWriteLine("Media-Info command", "--debug={0}", options.Debug);
|
||||||
DicConsole.DebugWriteLine("Media-Info command", "--verbose={0}", options.Verbose);
|
DicConsole.DebugWriteLine("Media-Info command", "--verbose={0}", options.Verbose);
|
||||||
DicConsole.DebugWriteLine("Media-Info command", "--device={0}", options.DevicePath);
|
DicConsole.DebugWriteLine("Media-Info command", "--device={0}", options.DevicePath);
|
||||||
DicConsole.DebugWriteLine("Media-Info command", "--output-prefix={0}", options.OutputPrefix);
|
DicConsole.DebugWriteLine("Media-Info command", "--output-prefix={0}", options.OutputPrefix);
|
||||||
|
|
||||||
if(options.DevicePath.Length == 2 && options.DevicePath[1] == ':' && options.DevicePath[0] != '/' &&
|
if(options.DevicePath.Length == 2 && options.DevicePath[1] == ':' && options.DevicePath[0] != '/' &&
|
||||||
@@ -114,13 +114,13 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
static void DoScsiMediaInfo(string outputPrefix, Device dev)
|
static void DoScsiMediaInfo(string outputPrefix, Device dev)
|
||||||
{
|
{
|
||||||
byte[] cmdBuf;
|
byte[] cmdBuf;
|
||||||
byte[] senseBuf;
|
byte[] senseBuf;
|
||||||
bool sense;
|
bool sense;
|
||||||
MediaType dskType = MediaType.Unknown;
|
MediaType dskType = MediaType.Unknown;
|
||||||
ulong blocks = 0;
|
ulong blocks = 0;
|
||||||
uint blockSize = 0;
|
uint blockSize = 0;
|
||||||
int resets = 0;
|
int resets = 0;
|
||||||
|
|
||||||
if(dev.IsRemovable)
|
if(dev.IsRemovable)
|
||||||
{
|
{
|
||||||
@@ -192,7 +192,7 @@ namespace DiscImageChef.Commands
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Modes.DecodedMode? decMode = null;
|
Modes.DecodedMode? decMode = null;
|
||||||
PeripheralDeviceTypes devType = dev.ScsiType;
|
PeripheralDeviceTypes devType = dev.ScsiType;
|
||||||
|
|
||||||
sense = dev.ModeSense10(out byte[] modeBuf, out senseBuf, false, true, ScsiModeSensePageControl.Current,
|
sense = dev.ModeSense10(out byte[] modeBuf, out senseBuf, false, true, ScsiModeSensePageControl.Current,
|
||||||
@@ -218,8 +218,8 @@ namespace DiscImageChef.Commands
|
|||||||
if(!sense)
|
if(!sense)
|
||||||
DataFile.WriteTo("Media-Info command", outputPrefix, "_scsi_modesense.bin", "SCSI MODE SENSE", modeBuf);
|
DataFile.WriteTo("Media-Info command", outputPrefix, "_scsi_modesense.bin", "SCSI MODE SENSE", modeBuf);
|
||||||
|
|
||||||
byte scsiMediumType = 0;
|
byte scsiMediumType = 0;
|
||||||
byte scsiDensityCode = 0;
|
byte scsiDensityCode = 0;
|
||||||
bool containsFloppyPage = false;
|
bool containsFloppyPage = false;
|
||||||
|
|
||||||
if(decMode.HasValue)
|
if(decMode.HasValue)
|
||||||
@@ -246,15 +246,15 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
DataFile.WriteTo("Media-Info command", outputPrefix, "_readcapacity.bin", "SCSI READ CAPACITY",
|
DataFile.WriteTo("Media-Info command", outputPrefix, "_readcapacity.bin", "SCSI READ CAPACITY",
|
||||||
cmdBuf);
|
cmdBuf);
|
||||||
blocks = (ulong)((cmdBuf[0] << 24) + (cmdBuf[1] << 16) + (cmdBuf[2] << 8) + cmdBuf[3]);
|
blocks = (ulong)((cmdBuf[0] << 24) + (cmdBuf[1] << 16) + (cmdBuf[2] << 8) + cmdBuf[3]);
|
||||||
blockSize = (uint)((cmdBuf[5] << 24) + (cmdBuf[5] << 16) + (cmdBuf[6] << 8) + cmdBuf[7]);
|
blockSize = (uint)((cmdBuf[5] << 24) + (cmdBuf[5] << 16) + (cmdBuf[6] << 8) + cmdBuf[7]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sense || blocks == 0xFFFFFFFF)
|
if(sense || blocks == 0xFFFFFFFF)
|
||||||
{
|
{
|
||||||
sense = dev.ReadCapacity16(out cmdBuf, out senseBuf, dev.Timeout, out _);
|
sense = dev.ReadCapacity16(out cmdBuf, out senseBuf, dev.Timeout, out _);
|
||||||
|
|
||||||
if(sense && blocks == 0)
|
if(sense && blocks == 0)
|
||||||
if(dev.ScsiType != PeripheralDeviceTypes.MultiMediaDevice)
|
if(dev.ScsiType != PeripheralDeviceTypes.MultiMediaDevice)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Unable to get media capacity");
|
DicConsole.ErrorWriteLine("Unable to get media capacity");
|
||||||
@@ -269,7 +269,7 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
Array.Copy(cmdBuf, 0, temp, 0, 8);
|
Array.Copy(cmdBuf, 0, temp, 0, 8);
|
||||||
Array.Reverse(temp);
|
Array.Reverse(temp);
|
||||||
blocks = BitConverter.ToUInt64(temp, 0);
|
blocks = BitConverter.ToUInt64(temp, 0);
|
||||||
blockSize = (uint)((cmdBuf[5] << 24) + (cmdBuf[5] << 16) + (cmdBuf[6] << 8) + cmdBuf[7]);
|
blockSize = (uint)((cmdBuf[5] << 24) + (cmdBuf[5] << 16) + (cmdBuf[6] << 8) + cmdBuf[7]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -280,6 +280,7 @@ namespace DiscImageChef.Commands
|
|||||||
DicConsole.WriteLine("Media has {0} blocks of {1} bytes/each. (for a total of {2} bytes)",
|
DicConsole.WriteLine("Media has {0} blocks of {1} bytes/each. (for a total of {2} bytes)",
|
||||||
blocks, blockSize, blocks * blockSize);
|
blocks, blockSize, blocks * blockSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case PeripheralDeviceTypes.SequentialAccess:
|
case PeripheralDeviceTypes.SequentialAccess:
|
||||||
byte[] medBuf;
|
byte[] medBuf;
|
||||||
@@ -318,6 +319,7 @@ namespace DiscImageChef.Commands
|
|||||||
DicConsole.WriteLine("Medium types currently inserted in device:");
|
DicConsole.WriteLine("Medium types currently inserted in device:");
|
||||||
DicConsole.WriteLine(DensitySupport.PrettifyMediumType(meds));
|
DicConsole.WriteLine(DensitySupport.PrettifyMediumType(meds));
|
||||||
}
|
}
|
||||||
|
|
||||||
DicConsole.WriteLine(DensitySupport.PrettifyMediumType(seqBuf));
|
DicConsole.WriteLine(DensitySupport.PrettifyMediumType(seqBuf));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -472,12 +474,12 @@ namespace DiscImageChef.Commands
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#region All DVD and HD DVD types
|
#region All DVD and HD DVD types
|
||||||
if(dskType == MediaType.DVDDownload || dskType == MediaType.DVDPR || dskType == MediaType.DVDPRDL ||
|
if(dskType == MediaType.DVDDownload || dskType == MediaType.DVDPR || dskType == MediaType.DVDPRDL ||
|
||||||
dskType == MediaType.DVDPRW || dskType == MediaType.DVDPRWDL || dskType == MediaType.DVDR ||
|
dskType == MediaType.DVDPRW || dskType == MediaType.DVDPRWDL || dskType == MediaType.DVDR ||
|
||||||
dskType == MediaType.DVDRAM || dskType == MediaType.DVDRDL || dskType == MediaType.DVDROM ||
|
dskType == MediaType.DVDRAM || dskType == MediaType.DVDRDL || dskType == MediaType.DVDROM ||
|
||||||
dskType == MediaType.DVDRW || dskType == MediaType.DVDRWDL || dskType == MediaType.HDDVDR ||
|
dskType == MediaType.DVDRW || dskType == MediaType.DVDRWDL || dskType == MediaType.HDDVDR ||
|
||||||
dskType == MediaType.HDDVDRAM || dskType == MediaType.HDDVDRDL || dskType == MediaType.HDDVDROM ||
|
dskType == MediaType.HDDVDRAM || dskType == MediaType.HDDVDRDL || dskType == MediaType.HDDVDROM ||
|
||||||
dskType == MediaType.HDDVDRW || dskType == MediaType.HDDVDRWDL)
|
dskType == MediaType.HDDVDRW || dskType == MediaType.HDDVDRWDL)
|
||||||
{
|
{
|
||||||
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.Dvd, 0, 0,
|
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.Dvd, 0, 0,
|
||||||
MmcDiscStructureFormat.PhysicalInformation, 0, dev.Timeout, out _);
|
MmcDiscStructureFormat.PhysicalInformation, 0, dev.Timeout, out _);
|
||||||
@@ -566,9 +568,9 @@ namespace DiscImageChef.Commands
|
|||||||
DicConsole.WriteLine("Xbox 360 DMI:\n{0}", DMI.PrettifyXbox360(cmdBuf));
|
DicConsole.WriteLine("Xbox 360 DMI:\n{0}", DMI.PrettifyXbox360(cmdBuf));
|
||||||
|
|
||||||
// All XGD3 all have the same number of blocks
|
// All XGD3 all have the same number of blocks
|
||||||
if(blocks == 25063 || // Locked (or non compatible drive)
|
if(blocks == 25063 || // Locked (or non compatible drive)
|
||||||
blocks == 4229664 || // Xtreme unlock
|
blocks == 4229664 || // Xtreme unlock
|
||||||
blocks == 4246304) // Wxripper unlock
|
blocks == 4246304) // Wxripper unlock
|
||||||
dskType = MediaType.XGD3;
|
dskType = MediaType.XGD3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -628,6 +630,7 @@ namespace DiscImageChef.Commands
|
|||||||
"SCSI READ DISC STRUCTURE", cmdBuf);
|
"SCSI READ DISC STRUCTURE", cmdBuf);
|
||||||
DicConsole.WriteLine("Disc Definition Structure:\n{0}", DDS.Prettify(cmdBuf));
|
DicConsole.WriteLine("Disc Definition Structure:\n{0}", DDS.Prettify(cmdBuf));
|
||||||
}
|
}
|
||||||
|
|
||||||
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.Dvd, 0, 0,
|
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.Dvd, 0, 0,
|
||||||
MmcDiscStructureFormat.DvdramMediumStatus, 0, dev.Timeout, out _);
|
MmcDiscStructureFormat.DvdramMediumStatus, 0, dev.Timeout, out _);
|
||||||
if(sense)
|
if(sense)
|
||||||
@@ -639,6 +642,7 @@ namespace DiscImageChef.Commands
|
|||||||
"SCSI READ DISC STRUCTURE", cmdBuf);
|
"SCSI READ DISC STRUCTURE", cmdBuf);
|
||||||
DicConsole.WriteLine("Medium Status:\n{0}", Cartridge.Prettify(cmdBuf));
|
DicConsole.WriteLine("Medium Status:\n{0}", Cartridge.Prettify(cmdBuf));
|
||||||
}
|
}
|
||||||
|
|
||||||
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.Dvd, 0, 0,
|
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.Dvd, 0, 0,
|
||||||
MmcDiscStructureFormat.DvdramSpareAreaInformation, 0, dev.Timeout,
|
MmcDiscStructureFormat.DvdramSpareAreaInformation, 0, dev.Timeout,
|
||||||
out _);
|
out _);
|
||||||
@@ -651,6 +655,7 @@ namespace DiscImageChef.Commands
|
|||||||
"SCSI READ DISC STRUCTURE", cmdBuf);
|
"SCSI READ DISC STRUCTURE", cmdBuf);
|
||||||
DicConsole.WriteLine("Spare Area Information:\n{0}", Spare.Prettify(cmdBuf));
|
DicConsole.WriteLine("Spare Area Information:\n{0}", Spare.Prettify(cmdBuf));
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case MediaType.DVDR:
|
case MediaType.DVDR:
|
||||||
case MediaType.HDDVDR:
|
case MediaType.HDDVDR:
|
||||||
@@ -914,6 +919,7 @@ namespace DiscImageChef.Commands
|
|||||||
"SCSI READ DISC STRUCTURE", cmdBuf);
|
"SCSI READ DISC STRUCTURE", cmdBuf);
|
||||||
DicConsole.WriteLine("Blu-ray Disc Information:\n{0}", DI.Prettify(cmdBuf));
|
DicConsole.WriteLine("Blu-ray Disc Information:\n{0}", DI.Prettify(cmdBuf));
|
||||||
}
|
}
|
||||||
|
|
||||||
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.Bd, 0, 0,
|
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.Bd, 0, 0,
|
||||||
MmcDiscStructureFormat.Pac, 0, dev.Timeout, out _);
|
MmcDiscStructureFormat.Pac, 0, dev.Timeout, out _);
|
||||||
if(sense)
|
if(sense)
|
||||||
@@ -941,6 +947,7 @@ namespace DiscImageChef.Commands
|
|||||||
"SCSI READ DISC STRUCTURE", cmdBuf);
|
"SCSI READ DISC STRUCTURE", cmdBuf);
|
||||||
DicConsole.WriteLine("Blu-ray Burst Cutting Area:\n{0}", BCA.Prettify(cmdBuf));
|
DicConsole.WriteLine("Blu-ray Burst Cutting Area:\n{0}", BCA.Prettify(cmdBuf));
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
#endregion BD-ROM only
|
#endregion BD-ROM only
|
||||||
|
|
||||||
@@ -961,6 +968,7 @@ namespace DiscImageChef.Commands
|
|||||||
DicConsole.WriteLine("Blu-ray Disc Definition Structure:\n{0}",
|
DicConsole.WriteLine("Blu-ray Disc Definition Structure:\n{0}",
|
||||||
Decoders.Bluray.DDS.Prettify(cmdBuf));
|
Decoders.Bluray.DDS.Prettify(cmdBuf));
|
||||||
}
|
}
|
||||||
|
|
||||||
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.Bd, 0, 0,
|
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.Bd, 0, 0,
|
||||||
MmcDiscStructureFormat.CartridgeStatus, 0, dev.Timeout, out _);
|
MmcDiscStructureFormat.CartridgeStatus, 0, dev.Timeout, out _);
|
||||||
if(sense)
|
if(sense)
|
||||||
@@ -973,6 +981,7 @@ namespace DiscImageChef.Commands
|
|||||||
"SCSI READ DISC STRUCTURE", cmdBuf);
|
"SCSI READ DISC STRUCTURE", cmdBuf);
|
||||||
DicConsole.WriteLine("Blu-ray Cartridge Status:\n{0}", DI.Prettify(cmdBuf));
|
DicConsole.WriteLine("Blu-ray Cartridge Status:\n{0}", DI.Prettify(cmdBuf));
|
||||||
}
|
}
|
||||||
|
|
||||||
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.Bd, 0, 0,
|
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.Bd, 0, 0,
|
||||||
MmcDiscStructureFormat.BdSpareAreaInformation, 0, dev.Timeout,
|
MmcDiscStructureFormat.BdSpareAreaInformation, 0, dev.Timeout,
|
||||||
out _);
|
out _);
|
||||||
@@ -986,6 +995,7 @@ namespace DiscImageChef.Commands
|
|||||||
"SCSI READ DISC STRUCTURE", cmdBuf);
|
"SCSI READ DISC STRUCTURE", cmdBuf);
|
||||||
DicConsole.WriteLine("Blu-ray Spare Area Information:\n{0}", DI.Prettify(cmdBuf));
|
DicConsole.WriteLine("Blu-ray Spare Area Information:\n{0}", DI.Prettify(cmdBuf));
|
||||||
}
|
}
|
||||||
|
|
||||||
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.Bd, 0, 0,
|
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.Bd, 0, 0,
|
||||||
MmcDiscStructureFormat.RawDfl, 0, dev.Timeout, out _);
|
MmcDiscStructureFormat.RawDfl, 0, dev.Timeout, out _);
|
||||||
if(sense)
|
if(sense)
|
||||||
@@ -1005,6 +1015,7 @@ namespace DiscImageChef.Commands
|
|||||||
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscinformation_001b.bin",
|
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscinformation_001b.bin",
|
||||||
"SCSI READ DISC INFORMATION", cmdBuf);
|
"SCSI READ DISC INFORMATION", cmdBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
sense = dev.ReadDiscInformation(out cmdBuf, out senseBuf,
|
sense = dev.ReadDiscInformation(out cmdBuf, out senseBuf,
|
||||||
MmcDiscInformationDataTypes.PowResources, dev.Timeout, out _);
|
MmcDiscInformationDataTypes.PowResources, dev.Timeout, out _);
|
||||||
if(sense)
|
if(sense)
|
||||||
@@ -1016,6 +1027,7 @@ namespace DiscImageChef.Commands
|
|||||||
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscinformation_010b.bin",
|
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscinformation_010b.bin",
|
||||||
"SCSI READ DISC INFORMATION", cmdBuf);
|
"SCSI READ DISC INFORMATION", cmdBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
#endregion Writable Blu-ray only
|
#endregion Writable Blu-ray only
|
||||||
|
|
||||||
@@ -1096,7 +1108,7 @@ namespace DiscImageChef.Commands
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int sessions = 1;
|
int sessions = 1;
|
||||||
int firstTrackLastSession = 0;
|
int firstTrackLastSession = 0;
|
||||||
|
|
||||||
sense = dev.ReadSessionInfo(out cmdBuf, out senseBuf, dev.Timeout, out _);
|
sense = dev.ReadSessionInfo(out cmdBuf, out senseBuf, dev.Timeout, out _);
|
||||||
@@ -1111,30 +1123,32 @@ namespace DiscImageChef.Commands
|
|||||||
DicConsole.WriteLine("Session information:\n{0}", Session.Prettify(session));
|
DicConsole.WriteLine("Session information:\n{0}", Session.Prettify(session));
|
||||||
if(session.HasValue)
|
if(session.HasValue)
|
||||||
{
|
{
|
||||||
sessions = session.Value.LastCompleteSession;
|
sessions = session.Value.LastCompleteSession;
|
||||||
firstTrackLastSession = session.Value.TrackDescriptors[0].TrackNumber;
|
firstTrackLastSession = session.Value.TrackDescriptors[0].TrackNumber;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dskType == MediaType.CD)
|
if(dskType == MediaType.CD)
|
||||||
{
|
{
|
||||||
bool hasDataTrack = false;
|
bool hasDataTrack = false;
|
||||||
bool hasAudioTrack = false;
|
bool hasAudioTrack = false;
|
||||||
bool allFirstSessionTracksAreAudio = true;
|
bool allFirstSessionTracksAreAudio = true;
|
||||||
bool hasVideoTrack = false;
|
bool hasVideoTrack = false;
|
||||||
|
|
||||||
if(toc.HasValue)
|
if(toc.HasValue)
|
||||||
foreach(TOC.CDTOCTrackDataDescriptor track in toc.Value.TrackDescriptors)
|
foreach(TOC.CDTOCTrackDataDescriptor track in toc.Value.TrackDescriptors)
|
||||||
{
|
{
|
||||||
if(track.TrackNumber == 1 &&
|
if(track.TrackNumber == 1 &&
|
||||||
((TocControl)(track.CONTROL & 0x0D) == TocControl.DataTrack ||
|
((TocControl)(track.CONTROL & 0x0D) ==
|
||||||
(TocControl)(track.CONTROL & 0x0D) == TocControl.DataTrackIncremental))
|
TocControl.DataTrack ||
|
||||||
|
(TocControl)(track.CONTROL & 0x0D) ==
|
||||||
|
TocControl.DataTrackIncremental))
|
||||||
allFirstSessionTracksAreAudio &= firstTrackLastSession != 1;
|
allFirstSessionTracksAreAudio &= firstTrackLastSession != 1;
|
||||||
|
|
||||||
if((TocControl)(track.CONTROL & 0x0D) == TocControl.DataTrack ||
|
if((TocControl)(track.CONTROL & 0x0D) == TocControl.DataTrack ||
|
||||||
(TocControl)(track.CONTROL & 0x0D) == TocControl.DataTrackIncremental)
|
(TocControl)(track.CONTROL & 0x0D) == TocControl.DataTrackIncremental)
|
||||||
{
|
{
|
||||||
hasDataTrack = true;
|
hasDataTrack = true;
|
||||||
allFirstSessionTracksAreAudio &= track.TrackNumber >= firstTrackLastSession;
|
allFirstSessionTracksAreAudio &= track.TrackNumber >= firstTrackLastSession;
|
||||||
}
|
}
|
||||||
else hasAudioTrack = true;
|
else hasAudioTrack = true;
|
||||||
@@ -1143,10 +1157,10 @@ namespace DiscImageChef.Commands
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(hasDataTrack && hasAudioTrack && allFirstSessionTracksAreAudio && sessions == 2)
|
if(hasDataTrack && hasAudioTrack && allFirstSessionTracksAreAudio && sessions == 2)
|
||||||
dskType = MediaType.CDPLUS;
|
dskType = MediaType.CDPLUS;
|
||||||
if(!hasDataTrack && hasAudioTrack && sessions == 1) dskType = MediaType.CDDA;
|
if(!hasDataTrack && hasAudioTrack && sessions == 1) dskType = MediaType.CDDA;
|
||||||
if(hasDataTrack && !hasAudioTrack && sessions == 1) dskType = MediaType.CDROM;
|
if(hasDataTrack && !hasAudioTrack && sessions == 1) dskType = MediaType.CDROM;
|
||||||
if(hasVideoTrack && !hasDataTrack && sessions == 1) dskType = MediaType.CDV;
|
if(hasVideoTrack && !hasDataTrack && sessions == 1) dskType = MediaType.CDV;
|
||||||
}
|
}
|
||||||
|
|
||||||
sense = dev.ReadRawToc(out cmdBuf, out senseBuf, 1, dev.Timeout, out _);
|
sense = dev.ReadRawToc(out cmdBuf, out senseBuf, 1, dev.Timeout, out _);
|
||||||
@@ -1163,9 +1177,9 @@ namespace DiscImageChef.Commands
|
|||||||
if(fullToc.HasValue)
|
if(fullToc.HasValue)
|
||||||
{
|
{
|
||||||
FullTOC.TrackDataDescriptor a0Track =
|
FullTOC.TrackDataDescriptor a0Track =
|
||||||
fullToc.Value.TrackDescriptors.FirstOrDefault(t => t.POINT == 0xA0 && t.ADR == 1);
|
fullToc.Value.TrackDescriptors
|
||||||
if(a0Track.POINT == 0xA0)
|
.FirstOrDefault(t => t.POINT == 0xA0 && t.ADR == 1);
|
||||||
{
|
if(a0Track.POINT == 0xA0)
|
||||||
switch(a0Track.PSEC)
|
switch(a0Track.PSEC)
|
||||||
{
|
{
|
||||||
case 0x10:
|
case 0x10:
|
||||||
@@ -1175,9 +1189,9 @@ namespace DiscImageChef.Commands
|
|||||||
dskType = MediaType.CDROMXA;
|
dskType = MediaType.CDROMXA;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sense = dev.ReadPma(out cmdBuf, out senseBuf, dev.Timeout, out _);
|
sense = dev.ReadPma(out cmdBuf, out senseBuf, dev.Timeout, out _);
|
||||||
if(sense)
|
if(sense)
|
||||||
DicConsole.DebugWriteLine("Media-Info command", "READ TOC/PMA/ATIP: PMA\n{0}",
|
DicConsole.DebugWriteLine("Media-Info command", "READ TOC/PMA/ATIP: PMA\n{0}",
|
||||||
@@ -1200,6 +1214,16 @@ namespace DiscImageChef.Commands
|
|||||||
if(CDTextOnLeadIn.Decode(cmdBuf).HasValue)
|
if(CDTextOnLeadIn.Decode(cmdBuf).HasValue)
|
||||||
DicConsole.WriteLine("CD-TEXT on Lead-In:\n{0}", CDTextOnLeadIn.Prettify(cmdBuf));
|
DicConsole.WriteLine("CD-TEXT on Lead-In:\n{0}", CDTextOnLeadIn.Prettify(cmdBuf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sense = dev.ReadMcn(out string mcn, out _, out _, dev.Timeout, out _);
|
||||||
|
if(!sense && mcn != null && mcn != "0000000000000") DicConsole.WriteLine("MCN: {0}", mcn);
|
||||||
|
|
||||||
|
for(byte i = toc.Value.FirstTrack; i <= toc.Value.LastTrack; i++)
|
||||||
|
{
|
||||||
|
sense = dev.ReadIsrc(i, out string isrc, out _, out _, dev.Timeout, out _);
|
||||||
|
if(!sense && isrc != null && isrc != "000000000000")
|
||||||
|
DicConsole.WriteLine("Track's {0} ISRC: {1}", i, isrc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -1223,7 +1247,7 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
DicConsole.WriteLine("PFI:\n{0}", PFI.Prettify(cmdBuf));
|
DicConsole.WriteLine("PFI:\n{0}", PFI.Prettify(cmdBuf));
|
||||||
if(nintendoPfi.Value.DiskCategory == DiskCategory.Nintendo &&
|
if(nintendoPfi.Value.DiskCategory == DiskCategory.Nintendo &&
|
||||||
nintendoPfi.Value.PartVersion == 15)
|
nintendoPfi.Value.PartVersion == 15)
|
||||||
switch(nintendoPfi.Value.DiscSize)
|
switch(nintendoPfi.Value.DiscSize)
|
||||||
{
|
{
|
||||||
case DVDSize.Eighty:
|
case DVDSize.Eighty:
|
||||||
@@ -1294,8 +1318,9 @@ namespace DiscImageChef.Commands
|
|||||||
}
|
}
|
||||||
|
|
||||||
totalSize = (ulong)((cmdBuf[0] << 24) + (cmdBuf[1] << 16) + (cmdBuf[2] << 8) + cmdBuf[3]);
|
totalSize = (ulong)((cmdBuf[0] << 24) + (cmdBuf[1] << 16) + (cmdBuf[2] << 8) + cmdBuf[3]);
|
||||||
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.Dvd, 0, 0,
|
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.Dvd,
|
||||||
MmcDiscStructureFormat.PhysicalInformation, 0, 0, out _);
|
0, 0,
|
||||||
|
MmcDiscStructureFormat.PhysicalInformation, 0, 0, out _);
|
||||||
if(sense)
|
if(sense)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Cannot get PFI.");
|
DicConsole.ErrorWriteLine("Cannot get PFI.");
|
||||||
@@ -1304,9 +1329,9 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
DicConsole.DebugWriteLine("Dump-media command", "Video partition total size: {0} sectors",
|
DicConsole.DebugWriteLine("Dump-media command", "Video partition total size: {0} sectors",
|
||||||
totalSize);
|
totalSize);
|
||||||
l0Video = PFI.Decode(cmdBuf).Value.Layer0EndPSN -
|
l0Video = PFI.Decode(cmdBuf).Value.Layer0EndPSN -
|
||||||
PFI.Decode(cmdBuf).Value.DataAreaStartPSN + 1;
|
PFI.Decode(cmdBuf).Value.DataAreaStartPSN + 1;
|
||||||
l1Video = totalSize - l0Video + 1;
|
l1Video = totalSize - l0Video + 1;
|
||||||
|
|
||||||
// Get game partition size
|
// Get game partition size
|
||||||
DicConsole.DebugWriteLine("Dump-media command", "Getting game partition size");
|
DicConsole.DebugWriteLine("Dump-media command", "Getting game partition size");
|
||||||
@@ -1346,8 +1371,9 @@ namespace DiscImageChef.Commands
|
|||||||
}
|
}
|
||||||
|
|
||||||
totalSize = (ulong)((cmdBuf[0] << 24) + (cmdBuf[1] << 16) + (cmdBuf[2] << 8) + cmdBuf[3]);
|
totalSize = (ulong)((cmdBuf[0] << 24) + (cmdBuf[1] << 16) + (cmdBuf[2] << 8) + cmdBuf[3]);
|
||||||
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.Dvd, 0, 0,
|
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.Dvd,
|
||||||
MmcDiscStructureFormat.PhysicalInformation, 0, 0, out _);
|
0, 0,
|
||||||
|
MmcDiscStructureFormat.PhysicalInformation, 0, 0, out _);
|
||||||
if(sense)
|
if(sense)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Cannot get PFI.");
|
DicConsole.ErrorWriteLine("Cannot get PFI.");
|
||||||
@@ -1357,18 +1383,20 @@ namespace DiscImageChef.Commands
|
|||||||
DicConsole.DebugWriteLine("Dump-media command", "Unlocked total size: {0} sectors",
|
DicConsole.DebugWriteLine("Dump-media command", "Unlocked total size: {0} sectors",
|
||||||
totalSize);
|
totalSize);
|
||||||
middleZone =
|
middleZone =
|
||||||
totalSize - (PFI.Decode(cmdBuf).Value.Layer0EndPSN -
|
totalSize -
|
||||||
PFI.Decode(cmdBuf).Value.DataAreaStartPSN + 1) - gameSize + 1;
|
(PFI.Decode(cmdBuf).Value.Layer0EndPSN -
|
||||||
|
PFI.Decode(cmdBuf).Value.DataAreaStartPSN + 1) -
|
||||||
|
gameSize + 1;
|
||||||
|
|
||||||
totalSize = l0Video + l1Video + middleZone * 2 + gameSize;
|
totalSize = l0Video + l1Video + middleZone * 2 + gameSize;
|
||||||
layerBreak = l0Video + middleZone + gameSize / 2;
|
layerBreak = l0Video + middleZone + gameSize / 2;
|
||||||
|
|
||||||
DicConsole.WriteLine("Video layer 0 size: {0} sectors", l0Video);
|
DicConsole.WriteLine("Video layer 0 size: {0} sectors", l0Video);
|
||||||
DicConsole.WriteLine("Video layer 1 size: {0} sectors", l1Video);
|
DicConsole.WriteLine("Video layer 1 size: {0} sectors", l1Video);
|
||||||
DicConsole.WriteLine("Middle zone size: {0} sectors", middleZone);
|
DicConsole.WriteLine("Middle zone size: {0} sectors", middleZone);
|
||||||
DicConsole.WriteLine("Game data size: {0} sectors", gameSize);
|
DicConsole.WriteLine("Game data size: {0} sectors", gameSize);
|
||||||
DicConsole.WriteLine("Total size: {0} sectors", totalSize);
|
DicConsole.WriteLine("Total size: {0} sectors", totalSize);
|
||||||
DicConsole.WriteLine("Real layer break: {0}", layerBreak);
|
DicConsole.WriteLine("Real layer break: {0}", layerBreak);
|
||||||
DicConsole.WriteLine();
|
DicConsole.WriteLine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user