mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Add option to select desired subchannel to dump.
This commit is contained in:
@@ -152,44 +152,93 @@ namespace DiscImageChef.Core.Devices.Dumping
|
|||||||
UpdateStatus?.Invoke($"CD reading offset is {cdOffset.Offset} samples.");
|
UpdateStatus?.Invoke($"CD reading offset is {cdOffset.Offset} samples.");
|
||||||
}
|
}
|
||||||
|
|
||||||
supportedSubchannel = MmcSubchannel.Raw;
|
switch(_subchannel)
|
||||||
_dumpLog.WriteLine("Checking if drive supports full raw subchannel reading...");
|
|
||||||
UpdateStatus?.Invoke("Checking if drive supports full raw subchannel reading...");
|
|
||||||
|
|
||||||
readcd = !_dev.ReadCd(out cmdBuf, out senseBuf, 0, sectorSize + 96, 1, MmcSectorTypes.AllTypes, false,
|
|
||||||
false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None,
|
|
||||||
supportedSubchannel, _dev.Timeout, out _);
|
|
||||||
|
|
||||||
if(readcd)
|
|
||||||
{
|
{
|
||||||
_dumpLog.WriteLine("Full raw subchannel reading supported...");
|
case DumpSubchannel.Any:
|
||||||
UpdateStatus?.Invoke("Full raw subchannel reading supported...");
|
if(SupportsRwSubchannel())
|
||||||
subSize = 96;
|
supportedSubchannel = MmcSubchannel.Raw;
|
||||||
|
else if(SupportsPqSubchannel())
|
||||||
|
supportedSubchannel = MmcSubchannel.Q16;
|
||||||
|
else
|
||||||
|
supportedSubchannel = MmcSubchannel.None;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case DumpSubchannel.Rw:
|
||||||
|
if(SupportsRwSubchannel())
|
||||||
|
supportedSubchannel = MmcSubchannel.Raw;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_dumpLog.WriteLine("Drive does not support the requested subchannel format, not continuing...");
|
||||||
|
|
||||||
|
StoppingErrorMessage?.
|
||||||
|
Invoke("Drive does not support the requested subchannel format, not continuing...");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case DumpSubchannel.RwOrPq:
|
||||||
|
if(SupportsRwSubchannel())
|
||||||
|
supportedSubchannel = MmcSubchannel.Raw;
|
||||||
|
else if(SupportsPqSubchannel())
|
||||||
|
supportedSubchannel = MmcSubchannel.Q16;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_dumpLog.WriteLine("Drive does not support the requested subchannel format, not continuing...");
|
||||||
|
|
||||||
|
StoppingErrorMessage?.
|
||||||
|
Invoke("Drive does not support the requested subchannel format, not continuing...");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case DumpSubchannel.Pq:
|
||||||
|
if(SupportsPqSubchannel())
|
||||||
|
supportedSubchannel = MmcSubchannel.Q16;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_dumpLog.WriteLine("Drive does not support the requested subchannel format, not continuing...");
|
||||||
|
|
||||||
|
StoppingErrorMessage?.
|
||||||
|
Invoke("Drive does not support the requested subchannel format, not continuing...");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case DumpSubchannel.None:
|
||||||
|
supportedSubchannel = MmcSubchannel.None;
|
||||||
|
|
||||||
|
break;
|
||||||
|
default: throw new ArgumentOutOfRangeException();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
// Check if output format supports subchannels
|
||||||
|
if(!_outputPlugin.SupportedSectorTags.Contains(SectorTagType.CdSectorSubchannel) &&
|
||||||
|
supportedSubchannel != MmcSubchannel.None)
|
||||||
{
|
{
|
||||||
supportedSubchannel = MmcSubchannel.Q16;
|
if(!_force ||
|
||||||
_dumpLog.WriteLine("Checking if drive supports PQ subchannel reading...");
|
_subchannel != DumpSubchannel.Any)
|
||||||
UpdateStatus?.Invoke("Checking if drive supports PQ subchannel reading...");
|
|
||||||
|
|
||||||
readcd = !_dev.ReadCd(out cmdBuf, out senseBuf, 0, sectorSize + 16, 1, MmcSectorTypes.AllTypes, false,
|
|
||||||
false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None,
|
|
||||||
supportedSubchannel, _dev.Timeout, out _);
|
|
||||||
|
|
||||||
if(readcd)
|
|
||||||
{
|
{
|
||||||
_dumpLog.WriteLine("PQ subchannel reading supported...");
|
_dumpLog.WriteLine("Output format does not support subchannels, continuing...");
|
||||||
_dumpLog.WriteLine("WARNING: If disc says CD+G, CD+EG, CD-MIDI, CD Graphics or CD Enhanced Graphics, dump will be incorrect!");
|
UpdateStatus?.Invoke("Output format does not support subchannels, continuing...");
|
||||||
UpdateStatus?.Invoke("PQ subchannel reading supported...");
|
|
||||||
|
|
||||||
UpdateStatus?.
|
|
||||||
Invoke("WARNING: If disc says CD+G, CD+EG, CD-MIDI, CD Graphics or CD Enhanced Graphics, dump will be incorrect!");
|
|
||||||
|
|
||||||
subSize = 16;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
supportedSubchannel = MmcSubchannel.None;
|
_dumpLog.WriteLine("Output format does not support subchannels, not continuing...");
|
||||||
|
StoppingErrorMessage?.Invoke("Output format does not support subchannels, not continuing...");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
supportedSubchannel = MmcSubchannel.None;
|
||||||
|
subSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(supportedSubchannel)
|
||||||
|
{
|
||||||
|
case MmcSubchannel.None:
|
||||||
_dumpLog.WriteLine("Checking if drive supports reading without subchannel...");
|
_dumpLog.WriteLine("Checking if drive supports reading without subchannel...");
|
||||||
UpdateStatus?.Invoke("Checking if drive supports reading without subchannel...");
|
UpdateStatus?.Invoke("Checking if drive supports reading without subchannel...");
|
||||||
|
|
||||||
@@ -259,52 +308,36 @@ namespace DiscImageChef.Core.Devices.Dumping
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_dumpLog.WriteLine("Drive can only read without subchannel...");
|
_dumpLog.WriteLine("Drive can read without subchannel...");
|
||||||
_dumpLog.WriteLine("WARNING: If disc says CD+G, CD+EG, CD-MIDI, CD Graphics or CD Enhanced Graphics, dump will be incorrect!");
|
_dumpLog.WriteLine("WARNING: If disc says CD+G, CD+EG, CD-MIDI, CD Graphics or CD Enhanced Graphics, dump will be incorrect!");
|
||||||
UpdateStatus?.Invoke("Drive can only read without subchannel...");
|
UpdateStatus?.Invoke("Drive can read without subchannel...");
|
||||||
|
|
||||||
UpdateStatus?.
|
UpdateStatus?.
|
||||||
Invoke("WARNING: If disc says CD+G, CD+EG, CD-MIDI, CD Graphics or CD Enhanced Graphics, dump will be incorrect!");
|
Invoke("WARNING: If disc says CD+G, CD+EG, CD-MIDI, CD Graphics or CD Enhanced Graphics, dump will be incorrect!");
|
||||||
|
|
||||||
subSize = 0;
|
subSize = 0;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if output format supports subchannels
|
|
||||||
if(!_outputPlugin.SupportedSectorTags.Contains(SectorTagType.CdSectorSubchannel) &&
|
|
||||||
supportedSubchannel != MmcSubchannel.None)
|
|
||||||
{
|
|
||||||
if(!_force)
|
|
||||||
{
|
|
||||||
_dumpLog.WriteLine("Output format does not support subchannels, continuing...");
|
|
||||||
UpdateStatus?.Invoke("Output format does not support subchannels, continuing...");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_dumpLog.WriteLine("Output format does not support subchannels, not continuing...");
|
|
||||||
StoppingErrorMessage?.Invoke("Output format does not support subchannels, not continuing...");
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
supportedSubchannel = MmcSubchannel.None;
|
|
||||||
subSize = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
blockSize = sectorSize + subSize;
|
|
||||||
|
|
||||||
switch(supportedSubchannel)
|
|
||||||
{
|
|
||||||
case MmcSubchannel.None:
|
|
||||||
subType = TrackSubchannelType.None;
|
subType = TrackSubchannelType.None;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case MmcSubchannel.Raw:
|
case MmcSubchannel.Raw:
|
||||||
|
_dumpLog.WriteLine("Full raw subchannel reading supported...");
|
||||||
|
UpdateStatus?.Invoke("Full raw subchannel reading supported...");
|
||||||
subType = TrackSubchannelType.Raw;
|
subType = TrackSubchannelType.Raw;
|
||||||
|
subSize = 96;
|
||||||
|
readcd = true;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case MmcSubchannel.Q16:
|
case MmcSubchannel.Q16:
|
||||||
|
_dumpLog.WriteLine("PQ subchannel reading supported...");
|
||||||
|
_dumpLog.WriteLine("WARNING: If disc says CD+G, CD+EG, CD-MIDI, CD Graphics or CD Enhanced Graphics, dump will be incorrect!");
|
||||||
|
UpdateStatus?.Invoke("PQ subchannel reading supported...");
|
||||||
|
|
||||||
|
UpdateStatus?.
|
||||||
|
Invoke("WARNING: If disc says CD+G, CD+EG, CD-MIDI, CD Graphics or CD Enhanced Graphics, dump will be incorrect!");
|
||||||
|
|
||||||
subType = TrackSubchannelType.Q16;
|
subType = TrackSubchannelType.Q16;
|
||||||
|
subSize = 16;
|
||||||
|
readcd = true;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -316,6 +349,8 @@ namespace DiscImageChef.Core.Devices.Dumping
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
blockSize = sectorSize + subSize;
|
||||||
|
|
||||||
// We discarded all discs that falsify a TOC before requesting a real TOC
|
// We discarded all discs that falsify a TOC before requesting a real TOC
|
||||||
// No TOC, no CD (or an empty one)
|
// No TOC, no CD (or an empty one)
|
||||||
_dumpLog.WriteLine("Reading full TOC");
|
_dumpLog.WriteLine("Reading full TOC");
|
||||||
@@ -2649,5 +2684,25 @@ namespace DiscImageChef.Core.Devices.Dumping
|
|||||||
|
|
||||||
Statistics.AddMedia(dskType, true);
|
Statistics.AddMedia(dskType, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SupportsRwSubchannel()
|
||||||
|
{
|
||||||
|
_dumpLog.WriteLine("Checking if drive supports full raw subchannel reading...");
|
||||||
|
UpdateStatus?.Invoke("Checking if drive supports full raw subchannel reading...");
|
||||||
|
|
||||||
|
return!_dev.ReadCd(out _, out _, 0, 2352 + 96, 1, MmcSectorTypes.AllTypes, false, false, true,
|
||||||
|
MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.Raw,
|
||||||
|
_dev.Timeout, out _);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SupportsPqSubchannel()
|
||||||
|
{
|
||||||
|
_dumpLog.WriteLine("Checking if drive supports PQ subchannel reading...");
|
||||||
|
UpdateStatus?.Invoke("Checking if drive supports PQ subchannel reading...");
|
||||||
|
|
||||||
|
return!_dev.ReadCd(out _, out _, 0, 2352 + 16, 1, MmcSectorTypes.AllTypes, false, false, true,
|
||||||
|
MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.Q16,
|
||||||
|
_dev.Timeout, out _);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -14,6 +14,12 @@ using Schemas;
|
|||||||
|
|
||||||
namespace DiscImageChef.Core.Devices.Dumping
|
namespace DiscImageChef.Core.Devices.Dumping
|
||||||
{
|
{
|
||||||
|
public enum DumpSubchannel
|
||||||
|
{
|
||||||
|
Any, Rw, RwOrPq,
|
||||||
|
Pq, None
|
||||||
|
}
|
||||||
|
|
||||||
public partial class Dump
|
public partial class Dump
|
||||||
{
|
{
|
||||||
readonly bool _debug;
|
readonly bool _debug;
|
||||||
@@ -43,6 +49,7 @@ namespace DiscImageChef.Core.Devices.Dumping
|
|||||||
Resume _resume;
|
Resume _resume;
|
||||||
Sidecar _sidecarClass;
|
Sidecar _sidecarClass;
|
||||||
uint _skip;
|
uint _skip;
|
||||||
|
readonly DumpSubchannel _subchannel;
|
||||||
|
|
||||||
/// <summary>Initializes dumpers</summary>
|
/// <summary>Initializes dumpers</summary>
|
||||||
/// <param name="doResume">Should resume?</param>
|
/// <param name="doResume">Should resume?</param>
|
||||||
@@ -69,7 +76,7 @@ namespace DiscImageChef.Core.Devices.Dumping
|
|||||||
bool force, bool dumpRaw, bool persistent, bool stopOnError, Resume resume, DumpLog dumpLog,
|
bool force, bool dumpRaw, bool persistent, bool stopOnError, Resume resume, DumpLog dumpLog,
|
||||||
Encoding encoding, string outputPrefix, string outputPath, Dictionary<string, string> formatOptions,
|
Encoding encoding, string outputPrefix, string outputPath, Dictionary<string, string> formatOptions,
|
||||||
CICMMetadataType preSidecar, uint skip, bool nometadata, bool notrim, bool dumpFirstTrackPregap,
|
CICMMetadataType preSidecar, uint skip, bool nometadata, bool notrim, bool dumpFirstTrackPregap,
|
||||||
bool fixOffset, bool debug)
|
bool fixOffset, bool debug, DumpSubchannel subchannel)
|
||||||
{
|
{
|
||||||
_doResume = doResume;
|
_doResume = doResume;
|
||||||
_dev = dev;
|
_dev = dev;
|
||||||
@@ -95,6 +102,7 @@ namespace DiscImageChef.Core.Devices.Dumping
|
|||||||
_fixOffset = fixOffset;
|
_fixOffset = fixOffset;
|
||||||
_debug = debug;
|
_debug = debug;
|
||||||
_maximumReadable = 64;
|
_maximumReadable = 64;
|
||||||
|
_subchannel = subchannel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Starts dumping with the stablished fields and autodetecting the device type</summary>
|
/// <summary>Starts dumping with the stablished fields and autodetecting the device type</summary>
|
||||||
|
|||||||
@@ -527,7 +527,7 @@ namespace DiscImageChef.Gui.Forms
|
|||||||
chkStopOnError.Checked == true, _resume, dumpLog, encoding, _outputPrefix,
|
chkStopOnError.Checked == true, _resume, dumpLog, encoding, _outputPrefix,
|
||||||
txtDestination.Text, parsedOptions, _sidecar, (uint)stpSkipped.Value,
|
txtDestination.Text, parsedOptions, _sidecar, (uint)stpSkipped.Value,
|
||||||
chkExistingMetadata.Checked == false, chkTrim.Checked == false,
|
chkExistingMetadata.Checked == false, chkTrim.Checked == false,
|
||||||
chkTrack1Pregap.Checked == true, true, false);
|
chkTrack1Pregap.Checked == true, true, false, DumpSubchannel.Any);
|
||||||
|
|
||||||
new Thread(DoWork).Start();
|
new Thread(DoWork).Start();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ namespace DiscImageChef.Commands
|
|||||||
int _skip = 512;
|
int _skip = 512;
|
||||||
bool _stopOnError;
|
bool _stopOnError;
|
||||||
string _wantedOutputFormat;
|
string _wantedOutputFormat;
|
||||||
|
string _wantedSubchannel;
|
||||||
|
|
||||||
public DumpMediaCommand() : base("dump-media", "Dumps the media inserted on a device to a media image.")
|
public DumpMediaCommand() : base("dump-media", "Dumps the media inserted on a device to a media image.")
|
||||||
{
|
{
|
||||||
@@ -118,6 +119,10 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
Options.Add("help|h|?", "Show this message and exit.", v => _showHelp = v != null);
|
Options.Add("help|h|?", "Show this message and exit.", v => _showHelp = v != null);
|
||||||
|
|
||||||
|
Options.Add("subchannel",
|
||||||
|
"Subchannel to dump. Only applicable to CD/GD. Values: any, rw, rw-or-pq, pq, none",
|
||||||
|
s => _wantedSubchannel = s);
|
||||||
|
|
||||||
/* TODO: Disabled temporarily
|
/* TODO: Disabled temporarily
|
||||||
Options.Add("raw|r", "Dump sectors with tags included. For optical media, dump scrambled sectors.", (b) => raw = b != null);*/
|
Options.Add("raw|r", "Dump sectors with tags included. For optical media, dump scrambled sectors.", (b) => raw = b != null);*/
|
||||||
}
|
}
|
||||||
@@ -177,6 +182,7 @@ namespace DiscImageChef.Commands
|
|||||||
DicConsole.DebugWriteLine("Dump-Media command", "--skip={0}", _skip);
|
DicConsole.DebugWriteLine("Dump-Media command", "--skip={0}", _skip);
|
||||||
DicConsole.DebugWriteLine("Dump-Media command", "--stop-on-error={0}", _stopOnError);
|
DicConsole.DebugWriteLine("Dump-Media command", "--stop-on-error={0}", _stopOnError);
|
||||||
DicConsole.DebugWriteLine("Dump-Media command", "--verbose={0}", MainClass.Verbose);
|
DicConsole.DebugWriteLine("Dump-Media command", "--verbose={0}", MainClass.Verbose);
|
||||||
|
DicConsole.DebugWriteLine("Dump-Media command", "--subchannel={0}", _wantedSubchannel);
|
||||||
|
|
||||||
// TODO: Disabled temporarily
|
// TODO: Disabled temporarily
|
||||||
//DicConsole.DebugWriteLine("Dump-Media command", "--raw={0}", raw);
|
//DicConsole.DebugWriteLine("Dump-Media command", "--raw={0}", raw);
|
||||||
@@ -204,6 +210,37 @@ namespace DiscImageChef.Commands
|
|||||||
return(int)ErrorNumber.EncodingUnknown;
|
return(int)ErrorNumber.EncodingUnknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DumpSubchannel subchannel = DumpSubchannel.Any;
|
||||||
|
|
||||||
|
switch(_wantedSubchannel?.ToLowerInvariant())
|
||||||
|
{
|
||||||
|
case"any":
|
||||||
|
case null:
|
||||||
|
subchannel = DumpSubchannel.Any;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case"rw":
|
||||||
|
subchannel = DumpSubchannel.Rw;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case"rw-or-pq":
|
||||||
|
subchannel = DumpSubchannel.RwOrPq;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case"pq":
|
||||||
|
subchannel = DumpSubchannel.Pq;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case"none":
|
||||||
|
subchannel = DumpSubchannel.None;
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DicConsole.WriteLine("Incorrect subchannel type \"{0}\" requested.", _wantedSubchannel);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if(_devicePath.Length == 2 &&
|
if(_devicePath.Length == 2 &&
|
||||||
_devicePath[1] == ':' &&
|
_devicePath[1] == ':' &&
|
||||||
_devicePath[0] != '/' &&
|
_devicePath[0] != '/' &&
|
||||||
@@ -344,7 +381,7 @@ namespace DiscImageChef.Commands
|
|||||||
var dumper = new Dump(_doResume, dev, _devicePath, outputFormat, _retryPasses, _force, false, _persistent,
|
var dumper = new Dump(_doResume, dev, _devicePath, outputFormat, _retryPasses, _force, false, _persistent,
|
||||||
_stopOnError, resume, dumpLog, encoding, outputPrefix, _outputFile, parsedOptions,
|
_stopOnError, resume, dumpLog, encoding, outputPrefix, _outputFile, parsedOptions,
|
||||||
sidecar, (uint)_skip, _noMetadata, _noTrim, _firstTrackPregap, _fixOffset,
|
sidecar, (uint)_skip, _noMetadata, _noTrim, _firstTrackPregap, _fixOffset,
|
||||||
MainClass.Debug);
|
MainClass.Debug, subchannel);
|
||||||
|
|
||||||
dumper.UpdateStatus += Progress.UpdateStatus;
|
dumper.UpdateStatus += Progress.UpdateStatus;
|
||||||
dumper.ErrorMessage += Progress.ErrorMessage;
|
dumper.ErrorMessage += Progress.ErrorMessage;
|
||||||
|
|||||||
Reference in New Issue
Block a user