2017-06-12 22:59:47 +01:00
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : ResumeSupport.cs
2017-12-19 03:50:57 +00:00
// Author(s) : Natalia Portillo <claunia@claunia.com>
2017-06-12 22:59:47 +01:00
//
2017-12-19 03:50:57 +00:00
// Component : Core algorithms.
2017-06-12 22:59:47 +01:00
//
// --[ Description ] ----------------------------------------------------------
//
2017-12-19 03:50:57 +00:00
// Contains logic to support dump resuming.
2017-06-12 22:59:47 +01:00
//
// --[ 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 <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
2017-12-19 03:50:57 +00:00
// Copyright © 2011-2018 Natalia Portillo
2017-06-12 22:59:47 +01:00
// ****************************************************************************/
2017-12-19 03:50:57 +00:00
using System ;
2017-06-20 05:48:09 +01:00
using System.Collections.Generic ;
using DiscImageChef.Metadata ;
using Extents ;
using Schemas ;
2017-12-21 14:30:38 +00:00
using PlatformID = DiscImageChef . Interop . PlatformID ;
2017-06-20 05:48:09 +01:00
2017-06-12 22:59:47 +01:00
namespace DiscImageChef.Core.Devices.Dumping
{
2017-12-23 01:46:08 +00:00
/// <summary>
2017-12-23 17:41:23 +00:00
/// Implements resume support
2017-12-23 01:46:08 +00:00
/// </summary>
2017-12-20 02:08:37 +00:00
static class ResumeSupport
2017-06-12 22:59:47 +01:00
{
2017-12-23 01:46:08 +00:00
/// <summary>
2017-12-23 17:41:23 +00:00
/// Process resume
2017-12-23 01:46:08 +00:00
/// </summary>
/// <param name="isLba">If drive is LBA</param>
/// <param name="removable">If media is removable from device</param>
/// <param name="blocks">Media blocks</param>
/// <param name="manufacturer">Device manufacturer</param>
/// <param name="model">Device model</param>
/// <param name="serial">Device serial</param>
/// <param name="platform">Platform where the dump is made</param>
/// <param name="resume">Previous resume, or null</param>
/// <param name="currentTry">Current dumping hardware</param>
/// <param name="extents">Dumped extents</param>
2017-12-23 17:41:23 +00:00
/// <exception cref="System.NotImplementedException">If device uses CHS addressing</exception>
/// <exception cref="System.InvalidOperationException">
/// If the provided resume does not correspond with the current in
/// progress dump
/// </exception>
2017-12-20 17:15:26 +00:00
internal static void Process ( bool isLba , bool removable , ulong blocks , string manufacturer , string model ,
2017-12-23 17:41:23 +00:00
string serial , PlatformID platform , ref Resume resume ,
ref DumpHardwareType currentTry , ref ExtentsULong extents )
2017-06-12 22:59:47 +01:00
{
2017-06-20 05:48:09 +01:00
if ( resume ! = null )
{
2017-12-19 20:33:03 +00:00
if ( ! isLba ) throw new NotImplementedException ( "Resuming CHS devices is currently not supported." ) ;
2017-06-20 05:48:09 +01:00
if ( resume . Removable ! = removable )
2017-12-19 20:33:03 +00:00
throw new
2017-12-23 01:46:08 +00:00
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..." ) ;
2017-06-20 05:48:09 +01:00
if ( resume . LastBlock ! = blocks - 1 )
2017-12-19 20:33:03 +00:00
throw new
2017-12-23 01:46:08 +00:00
InvalidOperationException ( $"Resume file specifies a device with {resume.LastBlock + 1} blocks but you're requesting to dump one with {blocks} blocks, not continuing..." ) ;
2017-06-20 05:48:09 +01:00
foreach ( DumpHardwareType oldtry in resume . Tries )
{
2017-12-23 01:46:08 +00:00
if ( ! removable )
{
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..." ) ;
2017-06-20 05:48:09 +01:00
2017-12-23 01:46:08 +00:00
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..." ) ;
2017-06-20 05:48:09 +01:00
2017-12-23 01:46:08 +00:00
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..." ) ;
}
2017-06-20 05:48:09 +01:00
2017-12-23 17:41:23 +00:00
if ( oldtry . Software = = null )
throw new InvalidOperationException ( "Found corrupt resume file, cannot continue..." ) ;
2017-06-20 05:48:09 +01:00
2017-12-21 06:06:19 +00:00
if ( oldtry . Software . Name ! = "DiscImageChef" | |
oldtry . Software . OperatingSystem ! = platform . ToString ( ) | |
oldtry . Software . Version ! = Version . GetVersion ( ) ) continue ;
2017-12-19 20:33:03 +00:00
2017-12-21 06:06:19 +00:00
if ( removable & & ( oldtry . Manufacturer ! = manufacturer | | oldtry . Model ! = model | |
oldtry . Serial ! = serial ) ) continue ;
currentTry = oldtry ;
extents = ExtentsConverter . FromMetadata ( currentTry . Extents ) ;
break ;
2017-06-20 05:48:09 +01:00
}
2017-12-21 06:06:19 +00:00
if ( currentTry ! = null ) return ;
currentTry = new DumpHardwareType
2017-06-20 05:48:09 +01:00
{
2017-12-21 06:06:19 +00:00
Software = Version . GetSoftwareType ( platform ) ,
Manufacturer = manufacturer ,
Model = model ,
Serial = serial
} ;
resume . Tries . Add ( currentTry ) ;
extents = new ExtentsULong ( ) ;
2017-06-20 05:48:09 +01:00
}
else
{
resume = new Resume
{
Tries = new List < DumpHardwareType > ( ) ,
CreationDate = DateTime . UtcNow ,
BadBlocks = new List < ulong > ( ) ,
LastBlock = blocks - 1
} ;
currentTry = new DumpHardwareType
{
Software = Version . GetSoftwareType ( platform ) ,
2017-12-20 17:15:26 +00:00
Manufacturer = manufacturer ,
Model = model ,
Serial = serial
2017-06-20 05:48:09 +01:00
} ;
resume . Tries . Add ( currentTry ) ;
extents = new ExtentsULong ( ) ;
resume . Removable = removable ;
}
2017-06-12 22:59:47 +01:00
}
}
2017-12-19 20:33:03 +00:00
}