mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Allow to retry bad subchannel sectors.
This commit is contained in:
Submodule Aaru.CommonTypes updated: fbb7a2c3c0...fa999bfe45
@@ -86,7 +86,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
bool read12, bool read16, bool readcd, int sectorsForOffset, uint subSize,
|
||||
MmcSubchannel supportedSubchannel, bool supportsLongSectors, ref double totalDuration,
|
||||
Track[] tracks, SubchannelLog subLog, MmcSubchannel desiredSubchannel,
|
||||
Dictionary<byte, string> isrcs, ref string mcn)
|
||||
Dictionary<byte, string> isrcs, ref string mcn, ExtentsInt subchannelExtents)
|
||||
{
|
||||
ulong sectorSpeedStart = 0; // Used to calculate correct speed
|
||||
DateTime timeSpeedStart = DateTime.UtcNow; // Time of start for speed calculation
|
||||
@@ -390,7 +390,8 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
bool indexesChanged =
|
||||
WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, i + r, 1,
|
||||
subLog, isrcs, (byte)track.TrackSequence, ref mcn, tracks);
|
||||
subLog, isrcs, (byte)track.TrackSequence, ref mcn, tracks,
|
||||
subchannelExtents);
|
||||
|
||||
// Set tracks and go back
|
||||
if(indexesChanged)
|
||||
@@ -514,7 +515,8 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
bool indexesChanged = WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, i,
|
||||
blocksToRead, subLog, isrcs,
|
||||
(byte)track.TrackSequence, ref mcn, tracks);
|
||||
(byte)track.TrackSequence, ref mcn, tracks,
|
||||
subchannelExtents);
|
||||
|
||||
// Set tracks and go back
|
||||
if(indexesChanged)
|
||||
|
||||
@@ -112,9 +112,10 @@ namespace Aaru.Core.Devices.Dumping
|
||||
bool hiddenTrack; // Disc has a hidden track before track 1
|
||||
MmcSubchannel supportedSubchannel; // Drive's maximum supported subchannel
|
||||
MmcSubchannel desiredSubchannel; // User requested subchannel
|
||||
bool bcdSubchannel = false; // Subchannel positioning is in BCD
|
||||
Dictionary<byte, string> isrcs = new Dictionary<byte, string>();
|
||||
string mcn = null;
|
||||
bool bcdSubchannel = false; // Subchannel positioning is in BCD
|
||||
Dictionary<byte, string> isrcs = new Dictionary<byte, string>();
|
||||
string mcn = null;
|
||||
var subchannelExtents = new ExtentsInt();
|
||||
|
||||
Dictionary<MediaTagType, byte[]> mediaTags = new Dictionary<MediaTagType, byte[]>(); // Media tags
|
||||
|
||||
@@ -848,6 +849,20 @@ namespace Aaru.Core.Devices.Dumping
|
||||
_dumpLog.WriteLine($"Found ISRC for track {trk.TrackSequence}: {mcn}");
|
||||
}
|
||||
|
||||
if(supportedSubchannel != MmcSubchannel.None &&
|
||||
desiredSubchannel != MmcSubchannel.None)
|
||||
{
|
||||
subchannelExtents = new ExtentsInt();
|
||||
|
||||
_resume.BadSubchannels ??= new List<int>();
|
||||
|
||||
foreach(int sub in _resume.BadSubchannels)
|
||||
subchannelExtents.Add(sub);
|
||||
|
||||
if(_resume.NextBlock < blocks)
|
||||
subchannelExtents.Add((int)_resume.NextBlock, (int)(blocks - 1));
|
||||
}
|
||||
|
||||
if(_resume.NextBlock > 0)
|
||||
{
|
||||
UpdateStatus?.Invoke($"Resuming from block {_resume.NextBlock}.");
|
||||
@@ -1015,7 +1030,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
ref imageWriteDuration, lastSector, leadOutExtents, ref maxSpeed, mhddLog, ref minSpeed,
|
||||
out newTrim, tracks[0].TrackType != TrackType.Audio, offsetBytes, read6, read10, read12, read16,
|
||||
readcd, sectorsForOffset, subSize, supportedSubchannel, supportsLongSectors, ref totalDuration,
|
||||
tracks, subLog, desiredSubchannel, isrcs, ref mcn);
|
||||
tracks, subLog, desiredSubchannel, isrcs, ref mcn, subchannelExtents);
|
||||
|
||||
// TODO: Enable when underlying images support lead-outs
|
||||
/*
|
||||
@@ -1048,11 +1063,17 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
TrimCdUserData(audioExtents, blockSize, currentTry, extents, newTrim, offsetBytes, read6, read10, read12,
|
||||
read16, readcd, sectorsForOffset, subSize, supportedSubchannel, supportsLongSectors,
|
||||
ref totalDuration, subLog, desiredSubchannel, tracks, isrcs, ref mcn);
|
||||
ref totalDuration, subLog, desiredSubchannel, tracks, isrcs, ref mcn, subchannelExtents);
|
||||
|
||||
RetryCdUserData(audioExtents, blockSize, currentTry, extents, offsetBytes, readcd, sectorsForOffset,
|
||||
subSize, supportedSubchannel, ref totalDuration, subLog, desiredSubchannel, tracks, isrcs,
|
||||
ref mcn);
|
||||
ref mcn, subchannelExtents);
|
||||
|
||||
if(subchannelExtents.Count > 0 &&
|
||||
_retryPasses > 0 &&
|
||||
_retrySubchannel)
|
||||
RetrySubchannel(readcd, subSize, supportedSubchannel, ref totalDuration, subLog, desiredSubchannel,
|
||||
tracks, isrcs, ref mcn, subchannelExtents);
|
||||
|
||||
// Write media tags to image
|
||||
if(!_aborted)
|
||||
@@ -1084,6 +1105,21 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
currentTry.Extents = ExtentsConverter.ToMetadata(extents);
|
||||
|
||||
_resume.BadSubchannels = new List<int>();
|
||||
|
||||
foreach(Tuple<int, int> extent in subchannelExtents.ToArray())
|
||||
{
|
||||
for(int sub = extent.Item1; sub <= extent.Item2; sub++)
|
||||
{
|
||||
if(sub >= (int)_resume.NextBlock)
|
||||
continue;
|
||||
|
||||
_resume.BadSubchannels.Add(sub);
|
||||
}
|
||||
}
|
||||
|
||||
_resume.BadSubchannels.Sort();
|
||||
|
||||
// TODO: Disc ID
|
||||
var metadata = new CommonTypes.Structs.ImageInfo
|
||||
{
|
||||
@@ -1153,6 +1189,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
UpdateStatus?.Invoke($"Fastest speed burst: {maxSpeed:F3} MiB/sec.");
|
||||
UpdateStatus?.Invoke($"Slowest speed burst: {minSpeed:F3} MiB/sec.");
|
||||
UpdateStatus?.Invoke($"{_resume.BadBlocks.Count} sectors could not be read.");
|
||||
UpdateStatus?.Invoke($"{_resume.BadSubchannels.Count} subchannels could not be read.");
|
||||
UpdateStatus?.Invoke("");
|
||||
|
||||
Statistics.AddMedia(dskType, true);
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
ExtentsULong extents, int offsetBytes, bool readcd, int sectorsForOffset, uint subSize,
|
||||
MmcSubchannel supportedSubchannel, ref double totalDuration, SubchannelLog subLog,
|
||||
MmcSubchannel desiredSubchannel, Track[] tracks, Dictionary<byte, string> isrcs,
|
||||
ref string mcn)
|
||||
ref string mcn, ExtentsInt subchannelExtents)
|
||||
{
|
||||
bool sense = true; // Sense indicator
|
||||
byte[] cmdBuf = null; // Data buffer
|
||||
@@ -290,7 +290,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
bool indexesChanged = WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, badSector,
|
||||
1, subLog, isrcs, (byte)track.TrackSequence, ref mcn,
|
||||
tracks);
|
||||
tracks, subchannelExtents);
|
||||
|
||||
// Set tracks and go back
|
||||
if(indexesChanged)
|
||||
@@ -402,7 +402,8 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
bool indexesChanged = WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub,
|
||||
badSector, 1, subLog, isrcs,
|
||||
(byte)track.TrackSequence, ref mcn, tracks);
|
||||
(byte)track.TrackSequence, ref mcn, tracks,
|
||||
subchannelExtents);
|
||||
|
||||
// Set tracks and go back
|
||||
if(indexesChanged)
|
||||
@@ -443,5 +444,135 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
EndProgress?.Invoke();
|
||||
}
|
||||
|
||||
void RetrySubchannel(bool readcd, uint subSize, MmcSubchannel supportedSubchannel, ref double totalDuration,
|
||||
SubchannelLog subLog, MmcSubchannel desiredSubchannel, Track[] tracks,
|
||||
Dictionary<byte, string> isrcs, ref string mcn, ExtentsInt subchannelExtents)
|
||||
{
|
||||
bool sense = true; // Sense indicator
|
||||
byte[] cmdBuf = null; // Data buffer
|
||||
double cmdDuration; // Command execution time
|
||||
const uint sectorSize = 2352; // Full sector size
|
||||
byte[] senseBuf = null; // Sense buffer
|
||||
PlextorSubchannel supportedPlextorSubchannel;
|
||||
|
||||
if(supportedSubchannel == MmcSubchannel.None ||
|
||||
desiredSubchannel == MmcSubchannel.None)
|
||||
return;
|
||||
|
||||
switch(supportedSubchannel)
|
||||
{
|
||||
case MmcSubchannel.None:
|
||||
supportedPlextorSubchannel = PlextorSubchannel.None;
|
||||
|
||||
break;
|
||||
case MmcSubchannel.Raw:
|
||||
supportedPlextorSubchannel = PlextorSubchannel.All;
|
||||
|
||||
break;
|
||||
case MmcSubchannel.Q16:
|
||||
supportedPlextorSubchannel = PlextorSubchannel.Q16;
|
||||
|
||||
break;
|
||||
case MmcSubchannel.Rw:
|
||||
supportedPlextorSubchannel = PlextorSubchannel.Pack;
|
||||
|
||||
break;
|
||||
default:
|
||||
supportedPlextorSubchannel = PlextorSubchannel.None;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if(_aborted)
|
||||
return;
|
||||
|
||||
int pass = 1;
|
||||
bool forward = true;
|
||||
|
||||
InitProgress?.Invoke();
|
||||
|
||||
cdRepeatRetry:
|
||||
|
||||
_resume.BadSubchannels = new List<int>();
|
||||
|
||||
foreach(Tuple<int, int> extent in subchannelExtents.ToArray())
|
||||
{
|
||||
for(int sub = extent.Item1; sub <= extent.Item2; sub++)
|
||||
{
|
||||
if(sub >= (int)_resume.NextBlock)
|
||||
continue;
|
||||
|
||||
_resume.BadSubchannels.Add(sub);
|
||||
}
|
||||
}
|
||||
|
||||
_resume.BadSubchannels.Sort();
|
||||
|
||||
if(!forward)
|
||||
_resume.BadSubchannels.Reverse();
|
||||
|
||||
int[] tmpArray = _resume.BadSubchannels.ToArray();
|
||||
|
||||
for(int i = 0; i < tmpArray.Length; i++)
|
||||
{
|
||||
uint badSector = (uint)tmpArray[i];
|
||||
|
||||
Track track = tracks.OrderBy(t => t.TrackStartSector).
|
||||
LastOrDefault(t => badSector >= t.TrackStartSector);
|
||||
|
||||
if(_aborted)
|
||||
{
|
||||
_dumpLog.WriteLine("Aborted!");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
PulseProgress?.
|
||||
Invoke($"Retrying sector {badSector} subchannel, pass {pass}, {(forward ? "forward" : "reverse")}");
|
||||
|
||||
uint startSector = badSector - 2;
|
||||
|
||||
if(_supportsPlextorD8)
|
||||
{
|
||||
sense = _dev.PlextorReadCdDa(out cmdBuf, out senseBuf, startSector, subSize, 5,
|
||||
supportedPlextorSubchannel, 0, out cmdDuration);
|
||||
|
||||
totalDuration += cmdDuration;
|
||||
}
|
||||
else if(readcd)
|
||||
{
|
||||
sense = _dev.ReadCd(out cmdBuf, out senseBuf, startSector, subSize, 5, MmcSectorTypes.AllTypes,
|
||||
false, false, false, MmcHeaderCodes.None, false, false, MmcErrorField.None,
|
||||
supportedSubchannel, _dev.Timeout, out cmdDuration);
|
||||
|
||||
totalDuration += cmdDuration;
|
||||
}
|
||||
|
||||
if(sense || _dev.Error)
|
||||
continue;
|
||||
|
||||
WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, cmdBuf, badSector, 5, subLog, isrcs,
|
||||
(byte)track.TrackSequence, ref mcn, tracks, subchannelExtents);
|
||||
|
||||
if(subchannelExtents.Contains(tmpArray[i]))
|
||||
continue;
|
||||
|
||||
UpdateStatus?.Invoke($"Correctly retried sector {badSector} subchannel in pass {pass}.");
|
||||
_dumpLog.WriteLine("Correctly retried sector {0} subchannel in pass {1}.", badSector, pass);
|
||||
}
|
||||
|
||||
if(pass < _retryPasses &&
|
||||
!_aborted &&
|
||||
subchannelExtents.Count > 0)
|
||||
{
|
||||
pass++;
|
||||
forward = !forward;
|
||||
|
||||
goto cdRepeatRetry;
|
||||
}
|
||||
|
||||
EndProgress?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -75,7 +75,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
bool read6, bool read10, bool read12, bool read16, bool readcd,
|
||||
MmcSubchannel supportedSubchannel, uint subSize, ref double totalDuration,
|
||||
SubchannelLog subLog, MmcSubchannel desiredSubchannel, Dictionary<byte, string> isrcs,
|
||||
ref string mcn, Track[] tracks)
|
||||
ref string mcn, Track[] tracks, ExtentsInt subchannelExtents)
|
||||
{
|
||||
byte[] cmdBuf = null; // Data buffer
|
||||
const uint sectorSize = 2352; // Full sector size
|
||||
@@ -160,7 +160,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
bool indexesChanged = WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, i,
|
||||
_maximumReadable, subLog, isrcs, 0xAA, ref mcn,
|
||||
tracks);
|
||||
tracks, subchannelExtents);
|
||||
|
||||
// Set tracks and go back
|
||||
if(indexesChanged)
|
||||
@@ -239,7 +239,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
bool read6, bool read10, bool read12, bool read16, bool readcd,
|
||||
MmcSubchannel supportedSubchannel, uint subSize, ref double totalDuration,
|
||||
SubchannelLog subLog, MmcSubchannel desiredSubchannel, Dictionary<byte, string> isrcs,
|
||||
ref string mcn, Track[] tracks)
|
||||
ref string mcn, Track[] tracks, ExtentsInt subchannelExtents)
|
||||
{
|
||||
byte[] cmdBuf = null; // Data buffer
|
||||
const uint sectorSize = 2352; // Full sector size
|
||||
@@ -324,7 +324,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
bool indexesChanged = WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, i,
|
||||
_maximumReadable, subLog, isrcs, 0xAA, ref mcn,
|
||||
tracks);
|
||||
tracks, subchannelExtents);
|
||||
|
||||
// Set tracks and go back
|
||||
if(indexesChanged)
|
||||
|
||||
@@ -34,6 +34,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using Aaru.Checksums;
|
||||
using Aaru.CommonTypes.Enums;
|
||||
using Aaru.CommonTypes.Extents;
|
||||
using Aaru.CommonTypes.Structs;
|
||||
using Aaru.Core.Logging;
|
||||
using Aaru.Decoders.CD;
|
||||
@@ -70,7 +71,8 @@ namespace Aaru.Core.Devices.Dumping
|
||||
// Return true if indexes have changed
|
||||
bool WriteSubchannelToImage(MmcSubchannel supportedSubchannel, MmcSubchannel desiredSubchannel, byte[] sub,
|
||||
ulong sectorAddress, uint length, SubchannelLog subLog,
|
||||
Dictionary<byte, string> isrcs, byte currentTrack, ref string mcn, Track[] tracks)
|
||||
Dictionary<byte, string> isrcs, byte currentTrack, ref string mcn, Track[] tracks,
|
||||
ExtentsInt subchannelExtents)
|
||||
{
|
||||
if(supportedSubchannel == MmcSubchannel.Q16)
|
||||
sub = Subchannel.ConvertQToRaw(sub);
|
||||
@@ -85,6 +87,10 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
bool indexesChanged = CheckIndexesFromSubchannel(deSub, isrcs, currentTrack, ref mcn, tracks);
|
||||
|
||||
if(!_fixSubchannelPosition ||
|
||||
desiredSubchannel == MmcSubchannel.None)
|
||||
return indexesChanged;
|
||||
|
||||
int prePos = int.MinValue;
|
||||
|
||||
// Check subchannel
|
||||
@@ -96,12 +102,12 @@ namespace Aaru.Core.Devices.Dumping
|
||||
CRC16CCITTContext.Data(q, 10, out byte[] crc);
|
||||
bool crcOk = crc[0] == q[10] && crc[1] == q[11];
|
||||
|
||||
if(!_fixSubchannelPosition ||
|
||||
desiredSubchannel == MmcSubchannel.None)
|
||||
// TODO: Fix
|
||||
// TODO: Check P
|
||||
// TODO: Check R-W
|
||||
if(!crcOk)
|
||||
continue;
|
||||
|
||||
// TODO: Check CRC OK
|
||||
|
||||
int aPos = int.MinValue;
|
||||
|
||||
byte aframe = (byte)(((q[9] / 16) * 10) + (q[9] & 0x0F));
|
||||
@@ -137,10 +143,9 @@ namespace Aaru.Core.Devices.Dumping
|
||||
byte[] posSub = new byte[96];
|
||||
Array.Copy(deSub, subPos, posSub, 0, 96);
|
||||
posSub = Subchannel.Interleave(posSub);
|
||||
_outputPlugin.WriteSectorTag(posSub, (ulong)aPos, SectorTagType.CdSectorSubchannel);
|
||||
|
||||
if(!_fixSubchannelPosition &&
|
||||
desiredSubchannel != MmcSubchannel.None)
|
||||
_outputPlugin.WriteSectorTag(posSub, (ulong)aPos, SectorTagType.CdSectorSubchannel);
|
||||
subchannelExtents.Remove(aPos);
|
||||
}
|
||||
|
||||
return indexesChanged;
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
bool read16, bool readcd, int sectorsForOffset, uint subSize,
|
||||
MmcSubchannel supportedSubchannel, bool supportsLongSectors, ref double totalDuration,
|
||||
SubchannelLog subLog, MmcSubchannel desiredSubchannel, Track[] tracks,
|
||||
Dictionary<byte, string> isrcs, ref string mcn)
|
||||
Dictionary<byte, string> isrcs, ref string mcn, ExtentsInt subchannelExtents)
|
||||
{
|
||||
DateTime start;
|
||||
DateTime end;
|
||||
@@ -190,7 +190,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
bool indexesChanged = WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, badSector,
|
||||
1, subLog, isrcs, (byte)track.TrackSequence, ref mcn,
|
||||
tracks);
|
||||
tracks, subchannelExtents);
|
||||
|
||||
// Set tracks and go back
|
||||
if(!indexesChanged)
|
||||
|
||||
@@ -61,6 +61,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
readonly DumpLog _dumpLog;
|
||||
readonly bool _dumpRaw;
|
||||
readonly Encoding _encoding;
|
||||
readonly bool _fixSubchannelPosition;
|
||||
readonly bool _force;
|
||||
readonly Dictionary<string, string> _formatOptions;
|
||||
readonly bool _metadata;
|
||||
@@ -79,9 +80,9 @@ namespace Aaru.Core.Devices.Dumping
|
||||
Database.Models.Device _dbDev; // Device database entry
|
||||
bool _dumpFirstTrackPregap;
|
||||
bool _fixOffset;
|
||||
readonly bool _fixSubchannelPosition;
|
||||
uint _maximumReadable; // Maximum number of sectors drive can read at once
|
||||
Resume _resume;
|
||||
readonly bool _retrySubchannel;
|
||||
Sidecar _sidecarClass;
|
||||
uint _skip;
|
||||
int _speed;
|
||||
@@ -114,7 +115,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
Encoding encoding, string outputPrefix, string outputPath, Dictionary<string, string> formatOptions,
|
||||
CICMMetadataType preSidecar, uint skip, bool metadata, bool trim, bool dumpFirstTrackPregap,
|
||||
bool fixOffset, bool debug, DumpSubchannel subchannel, int speed, bool @private,
|
||||
bool fixSubchannelPosition)
|
||||
bool fixSubchannelPosition, bool retrySubchannel)
|
||||
{
|
||||
_doResume = doResume;
|
||||
_dev = dev;
|
||||
@@ -145,6 +146,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
_speed = speed;
|
||||
_private = @private;
|
||||
_fixSubchannelPosition = fixSubchannelPosition;
|
||||
_retrySubchannel = retrySubchannel;
|
||||
}
|
||||
|
||||
/// <summary>Starts dumping with the stablished fields and autodetecting the device type</summary>
|
||||
|
||||
@@ -800,7 +800,7 @@ namespace Aaru.Gui.ViewModels.Windows
|
||||
_dumper = new Dump(Resume, _dev, _devicePath, SelectedPlugin.Plugin, (ushort)Retries, Force, false,
|
||||
Persistent, StopOnError, _resume, dumpLog, encoding, _outputPrefix, Destination,
|
||||
parsedOptions, _sidecar, (uint)Skipped, ExistingMetadata == false, Trim == false,
|
||||
Track1Pregap, true, false, DumpSubchannel.Any, 0, false, false);
|
||||
Track1Pregap, true, false, DumpSubchannel.Any, 0, false, false, false);
|
||||
|
||||
new Thread(DoWork).Start();
|
||||
}
|
||||
|
||||
@@ -191,6 +191,14 @@ namespace Aaru.Commands.Media
|
||||
Argument = new Argument<bool>(() => true), Required = false
|
||||
});
|
||||
|
||||
Add(new Option(new[]
|
||||
{
|
||||
"--retry-subchannel"
|
||||
}, "Retry subchannel. Implies fixing subchannel position..")
|
||||
{
|
||||
Argument = new Argument<bool>(() => true), Required = false
|
||||
});
|
||||
|
||||
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
|
||||
}
|
||||
|
||||
@@ -198,7 +206,7 @@ namespace Aaru.Commands.Media
|
||||
string encoding, bool firstPregap, bool fixOffset, bool force, bool metadata,
|
||||
bool trim, string outputPath, string options, bool persistent, ushort retryPasses,
|
||||
uint skip, byte speed, bool stopOnError, string format, string subchannel,
|
||||
bool @private, bool fixSubchannelPosition)
|
||||
bool @private, bool fixSubchannelPosition, bool retrySubchannel)
|
||||
{
|
||||
MainClass.PrintCopyright();
|
||||
|
||||
@@ -208,6 +216,9 @@ namespace Aaru.Commands.Media
|
||||
if(verbose)
|
||||
AaruConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||
|
||||
if(retrySubchannel)
|
||||
fixSubchannelPosition = true;
|
||||
|
||||
Statistics.AddCommand("dump-media");
|
||||
|
||||
AaruConsole.DebugWriteLine("Dump-Media command", "--cicm-xml={0}", cicmXml);
|
||||
@@ -231,6 +242,7 @@ namespace Aaru.Commands.Media
|
||||
AaruConsole.DebugWriteLine("Dump-Media command", "--subchannel={0}", subchannel);
|
||||
AaruConsole.DebugWriteLine("Dump-Media command", "--private={0}", @private);
|
||||
AaruConsole.DebugWriteLine("Dump-Media command", "--fix-subchannel-position={0}", fixSubchannelPosition);
|
||||
AaruConsole.DebugWriteLine("Dump-Media command", "--retry-subchannel={0}", retrySubchannel);
|
||||
|
||||
// TODO: Disabled temporarily
|
||||
//AaruConsole.DebugWriteLine("Dump-Media command", "--raw={0}", raw);
|
||||
@@ -344,7 +356,8 @@ namespace Aaru.Commands.Media
|
||||
if(resumeClass != null &&
|
||||
resumeClass.NextBlock > resumeClass.LastBlock &&
|
||||
resumeClass.BadBlocks.Count == 0 &&
|
||||
!resumeClass.Tape)
|
||||
!resumeClass.Tape &&
|
||||
(resumeClass.BadSubchannels is null || resumeClass.BadSubchannels.Count == 0))
|
||||
{
|
||||
AaruConsole.WriteLine("Media already dumped correctly, not continuing...");
|
||||
|
||||
@@ -428,7 +441,7 @@ namespace Aaru.Commands.Media
|
||||
var dumper = new Dump(resume, dev, devicePath, outputFormat, retryPasses, force, false, persistent,
|
||||
stopOnError, resumeClass, dumpLog, encodingClass, outputPrefix, outputPath,
|
||||
parsedOptions, sidecar, skip, metadata, trim, firstPregap, fixOffset, debug,
|
||||
wantedSubchannel, speed, @private, fixSubchannelPosition);
|
||||
wantedSubchannel, speed, @private, fixSubchannelPosition, retrySubchannel);
|
||||
|
||||
dumper.UpdateStatus += Progress.UpdateStatus;
|
||||
dumper.ErrorMessage += Progress.ErrorMessage;
|
||||
|
||||
Reference in New Issue
Block a user