diff --git a/Aaru.Core/Devices/Dumping/CompactDisc/Error.cs b/Aaru.Core/Devices/Dumping/CompactDisc/Error.cs index 1d3046da7..b1982aa5f 100644 --- a/Aaru.Core/Devices/Dumping/CompactDisc/Error.cs +++ b/Aaru.Core/Devices/Dumping/CompactDisc/Error.cs @@ -213,10 +213,23 @@ partial class Dump } InitProgress?.Invoke(); + var firstTry = true; + cdRepeatRetry: ulong[] tmpArray = _resume.BadBlocks.ToArray(); List sectorsNotEvenPartial = []; + if(firstTry) + { + if(_startReverse) + { + tmpArray = tmpArray.Reverse().ToArray(); + forward = false; + } + + firstTry = false; + } + for(var i = 0; i < tmpArray.Length; i++) { ulong badSector = tmpArray[i]; @@ -465,9 +478,8 @@ partial class Dump // MEDIUM ERROR, retry with ignore error below if(decSense is { ASC: 0x11 }) - { - if(!sectorsNotEvenPartial.Contains(badSector)) sectorsNotEvenPartial.Add(badSector); - } + if(!sectorsNotEvenPartial.Contains(badSector)) + sectorsNotEvenPartial.Add(badSector); } // Because one block has been partially used to fix the offset diff --git a/Aaru.Core/Devices/Dumping/Dump.cs b/Aaru.Core/Devices/Dumping/Dump.cs index 08b6e0a9e..194ed510d 100644 --- a/Aaru.Core/Devices/Dumping/Dump.cs +++ b/Aaru.Core/Devices/Dumping/Dump.cs @@ -71,6 +71,7 @@ public partial class Dump const string PREGAP_MODULE_NAME = "Pregap calculator"; const string MODULE_NAME = "Media dumping"; static readonly TimeSpan _oneSecond = 1.Seconds(); + readonly bool _bypassWiiDecryption; readonly bool _createGraph; readonly bool _cureParanoia; readonly bool _debug; @@ -104,7 +105,6 @@ public partial class Dump readonly Stopwatch _speedStopwatch; readonly bool _stopOnError; readonly bool _storeEncrypted; - readonly bool _bypassWiiDecryption; readonly DumpSubchannel _subchannel; readonly bool _titleKeys; readonly bool _trim; @@ -115,16 +115,17 @@ public partial class Dump Database.Models.Device _dbDev; // Device database entry bool _dumpFirstTrackPregap; bool _fixOffset; - HashSet _missingTitleKeysLookup; - bool _missingTitleKeysDirty; uint _maximumReadable; // Maximum number of sectors drive can read at once IMediaGraph _mediaGraph; + bool _missingTitleKeysDirty; + HashSet _missingTitleKeysLookup; Resume _resume; Sidecar _sidecarClass; uint _skip; bool _skipCdireadyHole; int _speed; int _speedMultiplier; + readonly bool _startReverse; bool _supportsPlextorD8; bool _useBufferedReads; @@ -173,6 +174,7 @@ public partial class Dump /// Check sectors integrity before writing to image /// Try to fix sectors integrity /// When dumping Wii (WOD), skip partition AES decryption and store encrypted data + /// Start error retrying in reverse public Dump(bool doResume, Device dev, string devicePath, IBaseWritableImage outputPlugin, ushort retryPasses, bool force, bool dumpRaw, bool persistent, bool stopOnError, Resume resume, Encoding encoding, string outputPrefix, string outputPath, Dictionary formatOptions, Metadata preSidecar, @@ -181,7 +183,7 @@ public partial class Dump bool fixSubchannel, bool fixSubchannelCrc, bool skipCdireadyHole, ErrorLog errorLog, bool generateSubchannels, uint maximumReadable, bool useBufferedReads, bool storeEncrypted, bool titleKeys, uint ignoreCdrRunOuts, bool createGraph, uint dimensions, bool paranoia, - bool cureParanoia, bool bypassWiiDecryption) + bool cureParanoia, bool bypassWiiDecryption, bool startReverse) { _doResume = doResume; _dev = dev; @@ -226,6 +228,7 @@ public partial class Dump _paranoia = paranoia; _cureParanoia = cureParanoia; _bypassWiiDecryption = bypassWiiDecryption; + _startReverse = startReverse; _dumpStopwatch = new Stopwatch(); _sidecarStopwatch = new Stopwatch(); _speedStopwatch = new Stopwatch(); diff --git a/Aaru.Core/Devices/Dumping/Sbc/Error.cs b/Aaru.Core/Devices/Dumping/Sbc/Error.cs index e3126e549..9fd2f0139 100644 --- a/Aaru.Core/Devices/Dumping/Sbc/Error.cs +++ b/Aaru.Core/Devices/Dumping/Sbc/Error.cs @@ -238,9 +238,22 @@ partial class Dump } InitProgress?.Invoke(); + + var firstTry = true; repeatRetry: ulong[] tmpArray = _resume.BadBlocks.ToArray(); + if(firstTry) + { + if(_startReverse) + { + tmpArray = tmpArray.Reverse().ToArray(); + forward = false; + } + + firstTry = false; + } + foreach(ulong badSector in tmpArray) { if(_aborted) @@ -308,7 +321,8 @@ partial class Dump if(outputFormat is null) { - ErrorMessage?.Invoke(string.Format(Localization.Core.Cannot_write_retried_sector_0_no_writable_output_image, + ErrorMessage?.Invoke(string.Format(Localization.Core + .Cannot_write_retried_sector_0_no_writable_output_image, badSector)); continue; @@ -331,7 +345,10 @@ partial class Dump if(key.All(static k => k == 0)) { - outputFormat.WriteSectorTag(new byte[5], badSector, false, SectorTagType.DvdTitleKeyDecrypted); + outputFormat.WriteSectorTag(new byte[5], + badSector, + false, + SectorTagType.DvdTitleKeyDecrypted); MarkTitleKeyDumped(badSector); } @@ -356,7 +373,7 @@ partial class Dump if(errno != ErrorNumber.NoError) { ErrorMessage?.Invoke(string.Format(Localization.Core - .Error_retrieving_title_key_for_sector_0, + .Error_retrieving_title_key_for_sector_0, badSector)); } else @@ -380,7 +397,8 @@ partial class Dump { if(outputFormat is null) { - ErrorMessage?.Invoke(string.Format(Localization.Core.Cannot_write_retried_sector_0_no_writable_output_image, + ErrorMessage?.Invoke(string.Format(Localization.Core + .Cannot_write_retried_sector_0_no_writable_output_image, badSector)); continue; diff --git a/Aaru.Gui/ViewModels/Windows/MediaDumpViewModel.cs b/Aaru.Gui/ViewModels/Windows/MediaDumpViewModel.cs index 601c838af..f2b651f52 100644 --- a/Aaru.Gui/ViewModels/Windows/MediaDumpViewModel.cs +++ b/Aaru.Gui/ViewModels/Windows/MediaDumpViewModel.cs @@ -761,7 +761,8 @@ public sealed partial class MediaDumpViewModel : ViewModelBase 1080, Paranoia, CureParanoia, - BypassWiiDecryption); + BypassWiiDecryption, + false); new Thread(DoWork).Start(); } diff --git a/Aaru.Localization/UI.Designer.cs b/Aaru.Localization/UI.Designer.cs index 6dc5f54bc..2ef6e5706 100644 --- a/Aaru.Localization/UI.Designer.cs +++ b/Aaru.Localization/UI.Designer.cs @@ -11225,5 +11225,11 @@ namespace Aaru.Localization { return ResourceManager.GetString("No_files_in_0_overlap_the_affected_sectors", resourceCulture); } } + + public static string Start_reverse_error_retry { + get { + return ResourceManager.GetString("Start_reverse_error_retry", resourceCulture); + } + } } } diff --git a/Aaru.Localization/UI.es.resx b/Aaru.Localization/UI.es.resx index da4b732dd..d15987146 100644 --- a/Aaru.Localization/UI.es.resx +++ b/Aaru.Localization/UI.es.resx @@ -5608,4 +5608,7 @@ Probadores: Ningún archivo en {0} se superpone con los sectores afectados. + + Comenzar reintentos de errores al revés. + \ No newline at end of file diff --git a/Aaru.Localization/UI.resx b/Aaru.Localization/UI.resx index 55643449d..21b9bc461 100644 --- a/Aaru.Localization/UI.resx +++ b/Aaru.Localization/UI.resx @@ -5692,4 +5692,7 @@ Do you want to continue? No files in {0} overlap the affected sectors. + + Start error retrying in reverse. + \ No newline at end of file diff --git a/Aaru/Commands/Media/Dump.cs b/Aaru/Commands/Media/Dump.cs index 151d09372..d86175fa9 100644 --- a/Aaru/Commands/Media/Dump.cs +++ b/Aaru/Commands/Media/Dump.cs @@ -125,6 +125,7 @@ sealed class DumpMediaCommand : Command AaruLogging.Debug(MODULE_NAME, "--paranoia={0}", settings.Paranoia); AaruLogging.Debug(MODULE_NAME, "--cure-paranoia={0}", settings.CureParanoia); AaruLogging.Debug(MODULE_NAME, "--raw={0}", settings.Raw); + AaruLogging.Debug(MODULE_NAME, "--start-reverse={0}", settings.StartReverse); Dictionary parsedOptions = Options.Parse(settings.Options); AaruLogging.Debug(MODULE_NAME, UI.Parsed_options); @@ -528,7 +529,8 @@ sealed class DumpMediaCommand : Command (uint)settings.Dimensions, settings.Paranoia, settings.CureParanoia, - settings.BypassWiiDecryption); + settings.BypassWiiDecryption, + settings.StartReverse); AnsiConsole.Progress() .AutoClear(true) @@ -801,6 +803,9 @@ sealed class DumpMediaCommand : Command [LocalizedDescription(nameof(UI.Output_image_path_Dump_help))] [CommandArgument(1, "")] public string OutputPath { get; init; } + [LocalizedDescription(nameof(UI.Start_reverse_error_retry))] + [CommandOption("--start-reverse")] + public bool StartReverse { get; init; } } #endregion