// /*************************************************************************** // Aaru Data Preservation Suite // ---------------------------------------------------------------------------- // // Filename : Trim.cs // Author(s) : Natalia Portillo // // --[ License ] -------------------------------------------------------------- // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // ---------------------------------------------------------------------------- // Copyright © 2011-2021 Natalia Portillo // ****************************************************************************/ using Aaru.CommonTypes.Extents; using Schemas; // ReSharper disable JoinDeclarationAndInitializer // ReSharper disable InlineOutVariableDeclaration // ReSharper disable TooWideLocalVariableScope namespace Aaru.Core.Devices.Dumping { partial class Dump { /// Trims data when dumping from a SCSI Block Commands compliant device /// SCSI reader /// Correctly dump extents /// Resume information /// Blank extents void TrimSbcData(Reader scsiReader, ExtentsULong extents, DumpHardwareType currentTry, ExtentsULong blankExtents) { ulong[] tmpArray = _resume.BadBlocks.ToArray(); bool sense; bool recoveredError; bool blankCheck; byte[] buffer; bool newBlank = false; foreach(ulong badSector in tmpArray) { if(_aborted) { currentTry.Extents = ExtentsConverter.ToMetadata(extents); UpdateStatus?.Invoke("Aborted!"); _dumpLog.WriteLine("Aborted!"); break; } PulseProgress?.Invoke($"Trimming sector {badSector}"); sense = scsiReader.ReadBlock(out buffer, badSector, out double _, out recoveredError, out blankCheck); if(blankCheck) { blankExtents.Add(badSector, badSector); newBlank = true; _resume.BadBlocks.Remove(badSector); UpdateStatus?.Invoke($"Found blank block {badSector}."); _dumpLog.WriteLine("Found blank block {0}.", badSector); continue; } if((sense || _dev.Error) && !recoveredError) continue; _resume.BadBlocks.Remove(badSector); extents.Add(badSector); _outputPlugin.WriteSector(buffer, badSector); } if(newBlank) _resume.BlankExtents = ExtentsConverter.ToMetadata(blankExtents); } } }