// /*************************************************************************** // Aaru Data Preservation Suite // ---------------------------------------------------------------------------- // // Filename : ResumeSupport.cs // Author(s) : Natalia Portillo // // Component : Core algorithms. // // --[ Description ] ---------------------------------------------------------- // // Contains logic to support dump resuming. // // --[ 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 System; using System.Collections.Generic; using Aaru.CommonTypes.Extents; using Aaru.CommonTypes.Metadata; using Schemas; using PlatformID = Aaru.CommonTypes.Interop.PlatformID; using Version = Aaru.CommonTypes.Interop.Version; namespace Aaru.Core.Devices.Dumping { /// Implements resume support internal static class ResumeSupport { /// Process resume /// If drive is LBA /// If media is removable from device /// Media blocks /// Device manufacturer /// Device model /// Device serial /// Platform where the dump is made /// Previous resume, or null /// Current dumping hardware /// Dumped extents /// Firmware revision /// Set to true if device is a streaming tape, false otherwise /// Disable saving paths or serial numbers in images and logs /// Force dump enabled /// If device uses CHS addressing /// /// If the provided resume does not correspond with the current in /// progress dump /// internal static void Process(bool isLba, bool removable, ulong blocks, string manufacturer, string model, string serial, PlatformID platform, ref Resume resume, ref DumpHardwareType currentTry, ref ExtentsULong extents, string firmware, bool @private, bool force, bool isTape = false) { if(@private) serial = null; if(resume != null) { if(!isLba) throw new NotImplementedException("Resuming CHS devices is currently not supported."); if(resume.Tape != isTape) throw new InvalidOperationException($"Resume file specifies a {(resume.Tape ? "tape" : "not tape")} device but you're requesting to dump a {(isTape ? "tape" : "not tape")} device, not continuing..."); if(resume.Removable != removable && !force) throw new InvalidOperationException($"Resume file specifies a {(resume.Removable ? "removable" : "non removable")} device but you're requesting to dump a {(removable ? "removable" : "non removable")} device, not continuing..."); if(!isTape && resume.LastBlock != blocks - 1 && !force) throw new InvalidOperationException($"Resume file specifies a device with {resume.LastBlock + 1} blocks but you're requesting to dump one with {blocks} blocks, not continuing..."); foreach(DumpHardwareType oldTry in resume.Tries) { if(!removable && !force) { if(oldTry.Manufacturer != manufacturer) throw new InvalidOperationException($"Resume file specifies a device manufactured by {oldTry.Manufacturer} but you're requesting to dump one by {manufacturer}, not continuing..."); if(oldTry.Model != model) throw new InvalidOperationException($"Resume file specifies a device model {oldTry.Model} but you're requesting to dump model {model}, not continuing..."); if(oldTry.Serial != serial) throw new InvalidOperationException($"Resume file specifies a device with serial {oldTry.Serial} but you're requesting to dump one with serial {serial}, not continuing..."); if(oldTry.Firmware != firmware) throw new InvalidOperationException($"Resume file specifies a device with firmware version {oldTry.Firmware} but you're requesting to dump one with firmware version {firmware}, not continuing..."); } if(oldTry.Software == null) throw new InvalidOperationException("Found corrupt resume file, cannot continue..."); if(oldTry.Software.Name != "Aaru" || oldTry.Software.OperatingSystem != platform.ToString() || oldTry.Software.Version != Version.GetVersion()) continue; if(removable && (oldTry.Manufacturer != manufacturer || oldTry.Model != model || oldTry.Serial != serial || oldTry.Firmware != firmware)) continue; currentTry = oldTry; extents = ExtentsConverter.FromMetadata(currentTry.Extents); break; } if(currentTry != null) return; currentTry = new DumpHardwareType { Software = CommonTypes.Metadata.Version.GetSoftwareType(), Manufacturer = manufacturer, Model = model, Serial = serial, Firmware = firmware }; resume.Tries.Add(currentTry); extents = new ExtentsULong(); } else { resume = new Resume { Tries = new List(), CreationDate = DateTime.UtcNow, BadBlocks = new List(), LastBlock = isTape ? 0 : blocks - 1, Tape = isTape }; currentTry = new DumpHardwareType { Software = CommonTypes.Metadata.Version.GetSoftwareType(), Manufacturer = manufacturer, Model = model, Serial = serial, Firmware = firmware }; resume.Tries.Add(currentTry); extents = new ExtentsULong(); resume.Removable = removable; } } } }