Move device database lookup to Dump class wide.

This commit is contained in:
2019-12-26 01:34:24 +00:00
parent 271cee4d93
commit 0d86e70f2e
2 changed files with 61 additions and 60 deletions

View File

@@ -45,14 +45,12 @@ using DiscImageChef.CommonTypes.Structs;
using DiscImageChef.Console; using DiscImageChef.Console;
using DiscImageChef.Core.Logging; using DiscImageChef.Core.Logging;
using DiscImageChef.Core.Media.Detection; using DiscImageChef.Core.Media.Detection;
using DiscImageChef.Database;
using DiscImageChef.Decoders.CD; using DiscImageChef.Decoders.CD;
using DiscImageChef.Decoders.SCSI; using DiscImageChef.Decoders.SCSI;
using DiscImageChef.Decoders.SCSI.MMC; using DiscImageChef.Decoders.SCSI.MMC;
using DiscImageChef.Devices; using DiscImageChef.Devices;
using Schemas; using Schemas;
using CdOffset = DiscImageChef.Database.Models.CdOffset; using CdOffset = DiscImageChef.Database.Models.CdOffset;
using Device = DiscImageChef.Database.Models.Device;
using MediaType = DiscImageChef.CommonTypes.MediaType; using MediaType = DiscImageChef.CommonTypes.MediaType;
using PlatformID = DiscImageChef.CommonTypes.Interop.PlatformID; using PlatformID = DiscImageChef.CommonTypes.Interop.PlatformID;
using Session = DiscImageChef.Decoders.CD.Session; using Session = DiscImageChef.Decoders.CD.Session;
@@ -80,12 +78,10 @@ namespace DiscImageChef.Core.Devices.Dumping
uint blocksToRead = 0; // How many sectors to read at once uint blocksToRead = 0; // How many sectors to read at once
CdOffset cdOffset; // Read offset from database CdOffset cdOffset; // Read offset from database
byte[] cmdBuf; // Data buffer byte[] cmdBuf; // Data buffer
double cmdDuration = 0; // Command execution time double cmdDuration = 0; // Command execution time
DicContext ctx; // Master database context
DumpHardwareType currentTry = null; // Current dump hardware try DumpHardwareType currentTry = null; // Current dump hardware try
double currentSpeed = 0; // Current read speed double currentSpeed = 0; // Current read speed
Device dbDev; // Device database entry DateTime dumpStart = DateTime.UtcNow; // Time of dump start
DateTime dumpStart = DateTime.UtcNow; // Time of dump start
DateTime end; // Time of operation end DateTime end; // Time of operation end
ExtentsULong extents = null; // Extents ExtentsULong extents = null; // Extents
TrackType firstTrackType = TrackType.Audio; // Type of first track TrackType firstTrackType = TrackType.Audio; // Type of first track
@@ -132,8 +128,6 @@ namespace DiscImageChef.Core.Devices.Dumping
DateTime timeSpeedStart; // Time of start for speed calculation DateTime timeSpeedStart; // Time of start for speed calculation
uint maximumReadable = 64; // Maximum number of sectors drive can read at once
dskType = MediaType.CD; dskType = MediaType.CD;
if(_dumpRaw) if(_dumpRaw)
@@ -144,31 +138,8 @@ namespace DiscImageChef.Core.Devices.Dumping
return; return;
} }
// Open master database
ctx = DicContext.Create(Settings.Settings.MasterDbPath);
// Search for device in master database
dbDev = ctx.Devices.FirstOrDefault(d => d.Manufacturer == _dev.Manufacturer && d.Model == _dev.Model &&
d.Revision == _dev.Revision);
if(dbDev is null)
{
_dumpLog.WriteLine("Device not in database, please create a device report and attach it to a Github issue.");
UpdateStatus?.
Invoke("Device not in database, please create a device report and attach it to a Github issue.");
}
else
{
_dumpLog.WriteLine($"Device in database since {dbDev.LastSynchronized}.");
UpdateStatus?.Invoke($"Device in database since {dbDev.LastSynchronized}.");
if(dbDev.OptimalMultipleSectorsRead > 0)
maximumReadable = (uint)dbDev.OptimalMultipleSectorsRead;
}
// Search for read offset in master database // Search for read offset in master database
cdOffset = ctx.CdOffsets.FirstOrDefault(d => d.Manufacturer == _dev.Manufacturer && d.Model == _dev.Model); cdOffset = _ctx.CdOffsets.FirstOrDefault(d => d.Manufacturer == _dev.Manufacturer && d.Model == _dev.Model);
if(cdOffset is null) if(cdOffset is null)
{ {
@@ -1099,48 +1070,48 @@ namespace DiscImageChef.Core.Devices.Dumping
{ {
if(readcd) if(readcd)
{ {
sense = _dev.ReadCd(out cmdBuf, out senseBuf, 0, blockSize, maximumReadable, sense = _dev.ReadCd(out cmdBuf, out senseBuf, 0, blockSize, _maximumReadable,
MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true,
true, MmcErrorField.None, supportedSubchannel, _dev.Timeout, out _); true, MmcErrorField.None, supportedSubchannel, _dev.Timeout, out _);
if(_dev.Error || sense) if(_dev.Error || sense)
maximumReadable /= 2; _maximumReadable /= 2;
} }
else if(read16) else if(read16)
{ {
sense = _dev.Read16(out cmdBuf, out senseBuf, 0, false, true, false, 0, blockSize, 0, sense = _dev.Read16(out cmdBuf, out senseBuf, 0, false, true, false, 0, blockSize, 0,
maximumReadable, false, _dev.Timeout, out _); _maximumReadable, false, _dev.Timeout, out _);
if(_dev.Error || sense) if(_dev.Error || sense)
maximumReadable /= 2; _maximumReadable /= 2;
} }
else if(read12) else if(read12)
{ {
sense = _dev.Read12(out cmdBuf, out senseBuf, 0, false, true, false, false, 0, blockSize, 0, sense = _dev.Read12(out cmdBuf, out senseBuf, 0, false, true, false, false, 0, blockSize, 0,
maximumReadable, false, _dev.Timeout, out _); _maximumReadable, false, _dev.Timeout, out _);
if(_dev.Error || sense) if(_dev.Error || sense)
maximumReadable /= 2; _maximumReadable /= 2;
} }
else if(read10) else if(read10)
{ {
sense = _dev.Read10(out cmdBuf, out senseBuf, 0, false, true, false, false, 0, blockSize, 0, sense = _dev.Read10(out cmdBuf, out senseBuf, 0, false, true, false, false, 0, blockSize, 0,
(ushort)maximumReadable, _dev.Timeout, out _); (ushort)_maximumReadable, _dev.Timeout, out _);
if(_dev.Error || sense) if(_dev.Error || sense)
maximumReadable /= 2; _maximumReadable /= 2;
} }
else if(read6) else if(read6)
{ {
sense = _dev.Read6(out cmdBuf, out senseBuf, 0, blockSize, (byte)maximumReadable, _dev.Timeout, sense = _dev.Read6(out cmdBuf, out senseBuf, 0, blockSize, (byte)_maximumReadable, _dev.Timeout,
out _); out _);
if(_dev.Error || sense) if(_dev.Error || sense)
maximumReadable /= 2; _maximumReadable /= 2;
} }
if(!_dev.Error || if(!_dev.Error ||
maximumReadable == 1) _maximumReadable == 1)
break; break;
} }
@@ -1150,16 +1121,16 @@ namespace DiscImageChef.Core.Devices.Dumping
StoppingErrorMessage?.Invoke($"Device error {_dev.LastError} trying to guess ideal transfer length."); StoppingErrorMessage?.Invoke($"Device error {_dev.LastError} trying to guess ideal transfer length.");
} }
_dumpLog.WriteLine("Reading {0} sectors at a time.", maximumReadable); _dumpLog.WriteLine("Reading {0} sectors at a time.", _maximumReadable);
_dumpLog.WriteLine("Device reports {0} blocks ({1} bytes).", blocks, blocks * blockSize); _dumpLog.WriteLine("Device reports {0} blocks ({1} bytes).", blocks, blocks * blockSize);
_dumpLog.WriteLine("Device can read {0} blocks at a time.", maximumReadable); _dumpLog.WriteLine("Device can read {0} blocks at a time.", _maximumReadable);
_dumpLog.WriteLine("Device reports {0} bytes per logical block.", blockSize); _dumpLog.WriteLine("Device reports {0} bytes per logical block.", blockSize);
_dumpLog.WriteLine("SCSI device type: {0}.", _dev.ScsiType); _dumpLog.WriteLine("SCSI device type: {0}.", _dev.ScsiType);
_dumpLog.WriteLine("Media identified as {0}.", dskType); _dumpLog.WriteLine("Media identified as {0}.", dskType);
UpdateStatus?.Invoke($"Reading {maximumReadable} sectors at a time."); UpdateStatus?.Invoke($"Reading {_maximumReadable} sectors at a time.");
UpdateStatus?.Invoke($"Device reports {blocks} blocks ({blocks * blockSize} bytes)."); UpdateStatus?.Invoke($"Device reports {blocks} blocks ({blocks * blockSize} bytes).");
UpdateStatus?.Invoke($"Device can read {maximumReadable} blocks at a time."); UpdateStatus?.Invoke($"Device can read {_maximumReadable} blocks at a time.");
UpdateStatus?.Invoke($"Device reports {blockSize} bytes per logical block."); UpdateStatus?.Invoke($"Device reports {blockSize} bytes per logical block.");
UpdateStatus?.Invoke($"SCSI device type: {_dev.ScsiType}."); UpdateStatus?.Invoke($"SCSI device type: {_dev.ScsiType}.");
UpdateStatus?.Invoke($"Media identified as {dskType}."); UpdateStatus?.Invoke($"Media identified as {dskType}.");
@@ -1303,8 +1274,8 @@ namespace DiscImageChef.Core.Devices.Dumping
_dumpLog.WriteLine("Resuming from block {0}.", _resume.NextBlock); _dumpLog.WriteLine("Resuming from block {0}.", _resume.NextBlock);
} }
if(_skip < maximumReadable) if(_skip < _maximumReadable)
_skip = maximumReadable; _skip = _maximumReadable;
#if DEBUG #if DEBUG
foreach(Track trk in tracks) foreach(Track trk in tracks)
@@ -1380,8 +1351,9 @@ namespace DiscImageChef.Core.Devices.Dumping
tmpBuf = new byte[sectorSync.Length]; tmpBuf = new byte[sectorSync.Length];
// Plextor READ CDDA // Plextor READ CDDA
if(dbDev?.ATAPI?.RemovableMedias?.Any(d => d.SupportsPlextorReadCDDA == true) == true || if(_dbDev?.ATAPI?.RemovableMedias?.Any(d => d.SupportsPlextorReadCDDA == true) ==
dbDev?.SCSI?.RemovableMedias?.Any(d => d.SupportsPlextorReadCDDA == true) == true || true ||
_dbDev?.SCSI?.RemovableMedias?.Any(d => d.SupportsPlextorReadCDDA == true) == true ||
_dev.Manufacturer.ToLowerInvariant() == _dev.Manufacturer.ToLowerInvariant() ==
"plextor") "plextor")
{ {
@@ -1407,10 +1379,10 @@ namespace DiscImageChef.Core.Devices.Dumping
} }
} }
if(_debug || if(_debug ||
dbDev?.ATAPI?.RemovableMedias?.Any(d => d.CanReadCdScrambled == true) == true || _dbDev?.ATAPI?.RemovableMedias?.Any(d => d.CanReadCdScrambled == true) == true ||
dbDev?.SCSI?.RemovableMedias?.Any(d => d.CanReadCdScrambled == true) == true || _dbDev?.SCSI?.RemovableMedias?.Any(d => d.CanReadCdScrambled == true) == true ||
_dev.Manufacturer.ToLowerInvariant() == "hl-dt-st") _dev.Manufacturer.ToLowerInvariant() == "hl-dt-st")
{ {
sense = _dev.ReadCd(out cmdBuf, out senseBuf, (uint)(dataTrack.TrackEndSector - 2), sense = _dev.ReadCd(out cmdBuf, out senseBuf, (uint)(dataTrack.TrackEndSector - 2),
sectorSize, 3, MmcSectorTypes.Cdda, false, false, false, sectorSize, 3, MmcSectorTypes.Cdda, false, false, false,
@@ -1522,7 +1494,7 @@ namespace DiscImageChef.Core.Devices.Dumping
UpdateStatus?.Invoke("There are audio tracks and offset fixing is disabled, dump may not be correct."); UpdateStatus?.Invoke("There are audio tracks and offset fixing is disabled, dump may not be correct.");
} }
mhddLog = new MhddLog(_outputPrefix + ".mhddlog.bin", _dev, blocks, blockSize, maximumReadable); mhddLog = new MhddLog(_outputPrefix + ".mhddlog.bin", _dev, blocks, blockSize, _maximumReadable);
ibgLog = new IbgLog(_outputPrefix + ".ibg", 0x0008); ibgLog = new IbgLog(_outputPrefix + ".ibg", 0x0008);
audioExtents = new ExtentsULong(); audioExtents = new ExtentsULong();
@@ -1553,13 +1525,13 @@ namespace DiscImageChef.Core.Devices.Dumping
uint firstSectorToRead = (uint)i; uint firstSectorToRead = (uint)i;
if((lastSector + 1) - (long)i < maximumReadable) if((lastSector + 1) - (long)i < _maximumReadable)
maximumReadable = (uint)((lastSector + 1) - (long)i); _maximumReadable = (uint)((lastSector + 1) - (long)i);
blocksToRead = 0; blocksToRead = 0;
bool inData = nextData; bool inData = nextData;
for(ulong j = i; j < i + maximumReadable; j++) for(ulong j = i; j < i + _maximumReadable; j++)
{ {
if(nextData) if(nextData)
{ {

View File

@@ -1,12 +1,14 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Text; using System.Text;
using System.Xml.Serialization; using System.Xml.Serialization;
using DiscImageChef.CommonTypes.Enums; using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.CommonTypes.Interfaces; using DiscImageChef.CommonTypes.Interfaces;
using DiscImageChef.CommonTypes.Metadata; using DiscImageChef.CommonTypes.Metadata;
using DiscImageChef.Core.Logging; using DiscImageChef.Core.Logging;
using DiscImageChef.Database;
using DiscImageChef.Devices; using DiscImageChef.Devices;
using Schemas; using Schemas;
@@ -14,6 +16,7 @@ namespace DiscImageChef.Core.Devices.Dumping
{ {
public partial class Dump public partial class Dump
{ {
readonly bool _debug;
readonly Device _dev; readonly Device _dev;
readonly string _devicePath; readonly string _devicePath;
readonly bool _doResume; readonly bool _doResume;
@@ -32,9 +35,11 @@ namespace DiscImageChef.Core.Devices.Dumping
readonly ushort _retryPasses; readonly ushort _retryPasses;
readonly bool _stopOnError; readonly bool _stopOnError;
bool _aborted; bool _aborted;
readonly bool _debug; DicContext _ctx; // Master database context
Database.Models.Device _dbDev; // Device database entry
bool _dumpFirstTrackPregap; bool _dumpFirstTrackPregap;
bool _fixOffset; bool _fixOffset;
uint _maximumReadable; // Maximum number of sectors drive can read at once
Resume _resume; Resume _resume;
Sidecar _sidecarClass; Sidecar _sidecarClass;
uint _skip; uint _skip;
@@ -89,11 +94,35 @@ namespace DiscImageChef.Core.Devices.Dumping
_aborted = false; _aborted = false;
_fixOffset = fixOffset; _fixOffset = fixOffset;
_debug = debug; _debug = debug;
_maximumReadable = 64;
} }
/// <summary>Starts dumping with the stablished fields and autodetecting the device type</summary> /// <summary>Starts dumping with the stablished fields and autodetecting the device type</summary>
public void Start() public void Start()
{ {
// Open master database
_ctx = DicContext.Create(Settings.Settings.MasterDbPath);
// Search for device in master database
_dbDev = _ctx.Devices.FirstOrDefault(d => d.Manufacturer == _dev.Manufacturer && d.Model == _dev.Model &&
d.Revision == _dev.Revision);
if(_dbDev is null)
{
_dumpLog.WriteLine("Device not in database, please create a device report and attach it to a Github issue.");
UpdateStatus?.
Invoke("Device not in database, please create a device report and attach it to a Github issue.");
}
else
{
_dumpLog.WriteLine($"Device in database since {_dbDev.LastSynchronized}.");
UpdateStatus?.Invoke($"Device in database since {_dbDev.LastSynchronized}.");
if(_dbDev.OptimalMultipleSectorsRead > 0)
_maximumReadable = (uint)_dbDev.OptimalMultipleSectorsRead;
}
if(_dev.IsUsb && if(_dev.IsUsb &&
_dev.UsbVendorId == 0x054C && _dev.UsbVendorId == 0x054C &&
(_dev.UsbProductId == 0x01C8 || _dev.UsbProductId == 0x01C9 || _dev.UsbProductId == 0x02D2)) (_dev.UsbProductId == 0x01C8 || _dev.UsbProductId == 0x01C9 || _dev.UsbProductId == 0x02D2))