Refactor rename "Revision" to "FirmwareRevision".

This commit is contained in:
2020-01-09 15:02:21 +00:00
parent 823b399932
commit 13ccbcb998
13 changed files with 726 additions and 468 deletions

View File

@@ -117,7 +117,7 @@ namespace DiscImageChef.Core.Devices.Dumping
// Search for device in master database // Search for device in master database
_dbDev = _ctx.Devices.FirstOrDefault(d => d.Manufacturer == _dev.Manufacturer && d.Model == _dev.Model && _dbDev = _ctx.Devices.FirstOrDefault(d => d.Manufacturer == _dev.Manufacturer && d.Model == _dev.Model &&
d.Revision == _dev.Revision); d.Revision == _dev.FirmwareRevision);
if(_dbDev is null) if(_dbDev is null)
{ {

View File

@@ -47,7 +47,7 @@ namespace DiscImageChef.Core.Devices.Info
Type = dev.Type; Type = dev.Type;
Manufacturer = dev.Manufacturer; Manufacturer = dev.Manufacturer;
Model = dev.Model; Model = dev.Model;
Revision = dev.Revision; FirmwareRevision = dev.FirmwareRevision;
Serial = dev.Serial; Serial = dev.Serial;
ScsiType = dev.ScsiType; ScsiType = dev.ScsiType;
IsRemovable = dev.IsRemovable; IsRemovable = dev.IsRemovable;
@@ -77,23 +77,31 @@ namespace DiscImageChef.Core.Devices.Info
if(sense) if(sense)
{ {
DicConsole.DebugWriteLine("Device-Info command", "STATUS = 0x{0:X2}", errorRegisters.Status); DicConsole.DebugWriteLine("Device-Info command", "STATUS = 0x{0:X2}", errorRegisters.Status);
DicConsole.DebugWriteLine("Device-Info command", "ERROR = 0x{0:X2}", errorRegisters.Error); DicConsole.DebugWriteLine("Device-Info command", "ERROR = 0x{0:X2}", errorRegisters.Error);
DicConsole.DebugWriteLine("Device-Info command", "NSECTOR = 0x{0:X2}", DicConsole.DebugWriteLine("Device-Info command", "NSECTOR = 0x{0:X2}",
errorRegisters.SectorCount); errorRegisters.SectorCount);
DicConsole.DebugWriteLine("Device-Info command", "SECTOR = 0x{0:X2}", errorRegisters.Sector); DicConsole.DebugWriteLine("Device-Info command", "SECTOR = 0x{0:X2}", errorRegisters.Sector);
DicConsole.DebugWriteLine("Device-Info command", "CYLHIGH = 0x{0:X2}", DicConsole.DebugWriteLine("Device-Info command", "CYLHIGH = 0x{0:X2}",
errorRegisters.CylinderHigh); errorRegisters.CylinderHigh);
DicConsole.DebugWriteLine("Device-Info command", "CYLLOW = 0x{0:X2}", DicConsole.DebugWriteLine("Device-Info command", "CYLLOW = 0x{0:X2}",
errorRegisters.CylinderLow); errorRegisters.CylinderLow);
DicConsole.DebugWriteLine("Device-Info command", "DEVICE = 0x{0:X2}", DicConsole.DebugWriteLine("Device-Info command", "DEVICE = 0x{0:X2}",
errorRegisters.DeviceHead); errorRegisters.DeviceHead);
DicConsole.DebugWriteLine("Device-Info command", "Error code = {0}", dev.LastError); DicConsole.DebugWriteLine("Device-Info command", "Error code = {0}", dev.LastError);
break; break;
} }
if(dev.Error) if(dev.Error)
{ {
DicConsole.ErrorWriteLine("Error {0} querying ATA IDENTIFY", dev.LastError); DicConsole.ErrorWriteLine("Error {0} querying ATA IDENTIFY", dev.LastError);
break; break;
} }
@@ -101,7 +109,8 @@ namespace DiscImageChef.Core.Devices.Info
dev.EnableMediaCardPassThrough(out errorRegisters, dev.Timeout, out _); dev.EnableMediaCardPassThrough(out errorRegisters, dev.Timeout, out _);
if(errorRegisters.Sector == 0xAA && errorRegisters.SectorCount == 0x55) if(errorRegisters.Sector == 0xAA &&
errorRegisters.SectorCount == 0x55)
AtaMcptError = errorRegisters; AtaMcptError = errorRegisters;
break; break;
@@ -114,22 +123,31 @@ namespace DiscImageChef.Core.Devices.Info
if(sense) if(sense)
{ {
DicConsole.DebugWriteLine("Device-Info command", "STATUS = 0x{0:X2}", errorRegisters.Status); DicConsole.DebugWriteLine("Device-Info command", "STATUS = 0x{0:X2}", errorRegisters.Status);
DicConsole.DebugWriteLine("Device-Info command", "ERROR = 0x{0:X2}", errorRegisters.Error); DicConsole.DebugWriteLine("Device-Info command", "ERROR = 0x{0:X2}", errorRegisters.Error);
DicConsole.DebugWriteLine("Device-Info command", "NSECTOR = 0x{0:X2}", DicConsole.DebugWriteLine("Device-Info command", "NSECTOR = 0x{0:X2}",
errorRegisters.SectorCount); errorRegisters.SectorCount);
DicConsole.DebugWriteLine("Device-Info command", "SECTOR = 0x{0:X2}", errorRegisters.Sector); DicConsole.DebugWriteLine("Device-Info command", "SECTOR = 0x{0:X2}", errorRegisters.Sector);
DicConsole.DebugWriteLine("Device-Info command", "CYLHIGH = 0x{0:X2}", DicConsole.DebugWriteLine("Device-Info command", "CYLHIGH = 0x{0:X2}",
errorRegisters.CylinderHigh); errorRegisters.CylinderHigh);
DicConsole.DebugWriteLine("Device-Info command", "CYLLOW = 0x{0:X2}", DicConsole.DebugWriteLine("Device-Info command", "CYLLOW = 0x{0:X2}",
errorRegisters.CylinderLow); errorRegisters.CylinderLow);
DicConsole.DebugWriteLine("Device-Info command", "DEVICE = 0x{0:X2}", DicConsole.DebugWriteLine("Device-Info command", "DEVICE = 0x{0:X2}",
errorRegisters.DeviceHead); errorRegisters.DeviceHead);
DicConsole.DebugWriteLine("Device-Info command", "Error code = {0}", dev.LastError); DicConsole.DebugWriteLine("Device-Info command", "Error code = {0}", dev.LastError);
break; break;
} }
if(!dev.Error) AtapiIdentify = ataBuf; if(!dev.Error)
else DicConsole.ErrorWriteLine("Error {0} querying ATA PACKET IDENTIFY", dev.LastError); AtapiIdentify = ataBuf;
else
DicConsole.ErrorWriteLine("Error {0} querying ATA PACKET IDENTIFY", dev.LastError);
// ATAPI devices are also SCSI devices // ATAPI devices are also SCSI devices
goto case DeviceType.SCSI; goto case DeviceType.SCSI;
@@ -142,6 +160,7 @@ namespace DiscImageChef.Core.Devices.Info
if(sense) if(sense)
{ {
DicConsole.ErrorWriteLine("SCSI error:\n{0}", Sense.PrettifySense(senseBuf)); DicConsole.ErrorWriteLine("SCSI error:\n{0}", Sense.PrettifySense(senseBuf));
break; break;
} }
@@ -160,50 +179,69 @@ namespace DiscImageChef.Core.Devices.Info
foreach(byte page in pages) foreach(byte page in pages)
{ {
sense = dev.ScsiInquiry(out inqBuf, out senseBuf, page); sense = dev.ScsiInquiry(out inqBuf, out senseBuf, page);
if(sense) continue;
if(sense)
continue;
ScsiEvpdPages.Add(page, inqBuf); ScsiEvpdPages.Add(page, inqBuf);
} }
} }
PeripheralDeviceTypes devType = (PeripheralDeviceTypes)ScsiInquiry.Value.PeripheralDeviceType; var devType = (PeripheralDeviceTypes)ScsiInquiry.Value.PeripheralDeviceType;
sense = dev.ModeSense10(out byte[] modeBuf, out senseBuf, false, true, sense = dev.ModeSense10(out byte[] modeBuf, out senseBuf, false, true,
ScsiModeSensePageControl.Current, 0x3F, 0xFF, 5, out _); ScsiModeSensePageControl.Current, 0x3F, 0xFF, 5, out _);
if(!sense && !dev.Error) ScsiModeSense10 = modeBuf; if(!sense &&
!dev.Error)
ScsiModeSense10 = modeBuf;
if(sense || dev.Error) if(sense || dev.Error)
{ {
sense = dev.ModeSense10(out modeBuf, out senseBuf, false, true, sense = dev.ModeSense10(out modeBuf, out senseBuf, false, true,
ScsiModeSensePageControl.Current, 0x3F, 0x00, 5, out _); ScsiModeSensePageControl.Current, 0x3F, 0x00, 5, out _);
if(!sense && !dev.Error) ScsiModeSense10 = modeBuf;
if(!sense &&
!dev.Error)
ScsiModeSense10 = modeBuf;
} }
if(!sense && !dev.Error) ScsiMode = Modes.DecodeMode10(modeBuf, devType); if(!sense &&
!dev.Error)
ScsiMode = Modes.DecodeMode10(modeBuf, devType);
bool useMode10 = !(sense || dev.Error || !ScsiMode.HasValue); bool useMode10 = !(sense || dev.Error || !ScsiMode.HasValue);
sense = dev.ModeSense6(out modeBuf, out senseBuf, false, ScsiModeSensePageControl.Current, 0x3F, sense = dev.ModeSense6(out modeBuf, out senseBuf, false, ScsiModeSensePageControl.Current, 0x3F,
0xFF, 5, out _); 0xFF, 5, out _);
if(!sense && !dev.Error) ScsiModeSense6 = modeBuf; if(!sense &&
!dev.Error)
ScsiModeSense6 = modeBuf;
if(sense || dev.Error) if(sense || dev.Error)
{ {
sense = dev.ModeSense6(out modeBuf, out senseBuf, false, ScsiModeSensePageControl.Current, 0x3F, sense = dev.ModeSense6(out modeBuf, out senseBuf, false, ScsiModeSensePageControl.Current, 0x3F,
0x00, 5, out _); 0x00, 5, out _);
if(!sense && !dev.Error) ScsiModeSense6 = modeBuf; if(!sense &&
!dev.Error)
ScsiModeSense6 = modeBuf;
} }
if(sense || dev.Error) if(sense || dev.Error)
{ {
sense = dev.ModeSense(out modeBuf, out senseBuf, 5, out _); sense = dev.ModeSense(out modeBuf, out senseBuf, 5, out _);
if(!sense && !dev.Error) ScsiModeSense6 = modeBuf;
if(!sense &&
!dev.Error)
ScsiModeSense6 = modeBuf;
} }
if(!sense && !dev.Error && !useMode10) ScsiMode = Modes.DecodeMode6(modeBuf, devType); if(!sense &&
!dev.Error &&
!useMode10)
ScsiMode = Modes.DecodeMode6(modeBuf, devType);
switch(devType) switch(devType)
{ {
@@ -211,7 +249,8 @@ namespace DiscImageChef.Core.Devices.Info
{ {
sense = dev.GetConfiguration(out byte[] confBuf, out senseBuf, dev.Timeout, out _); sense = dev.GetConfiguration(out byte[] confBuf, out senseBuf, dev.Timeout, out _);
if(!sense) MmcConfiguration = confBuf; if(!sense)
MmcConfiguration = confBuf;
// TODO: DVD drives respond correctly to BD status. // TODO: DVD drives respond correctly to BD status.
// While specification says if no medium is present // While specification says if no medium is present
@@ -267,31 +306,37 @@ namespace DiscImageChef.Core.Devices.Info
switch(dev.Model) switch(dev.Model)
{ {
case "DVDR PX-708A": case"DVDR PX-708A":
case "DVDR PX-708A2": case"DVDR PX-708A2":
case "DVDR PX-712A": case"DVDR PX-712A":
plxtDvd = true; plxtDvd = true;
plxtSense = dev.PlextorReadEeprom(out plxtBuf, out senseBuf, dev.Timeout, plxtSense = dev.PlextorReadEeprom(out plxtBuf, out senseBuf, dev.Timeout,
out _); out _);
break; break;
case "DVDR PX-714A": case"DVDR PX-714A":
case "DVDR PX-716A": case"DVDR PX-716A":
case "DVDR PX-716AL": case"DVDR PX-716AL":
case "DVDR PX-755A": case"DVDR PX-755A":
case "DVDR PX-760A": case"DVDR PX-760A":
{ {
plxtBuf = new byte[256 * 4]; plxtBuf = new byte[256 * 4];
for(byte i = 0; i < 4; i++) for(byte i = 0; i < 4; i++)
{ {
plxtSense = dev.PlextorReadEepromBlock(out byte[] plxtBufSmall, plxtSense = dev.PlextorReadEepromBlock(out byte[] plxtBufSmall,
out senseBuf, i, 256, dev.Timeout, out senseBuf, i, 256, dev.Timeout,
out _); out _);
if(plxtSense) break;
if(plxtSense)
break;
Array.Copy(plxtBufSmall, 0, plxtBuf, i * 256, 256); Array.Copy(plxtBufSmall, 0, plxtBuf, i * 256, 256);
} }
plxtDvd = true; plxtDvd = true;
break; break;
} }
@@ -300,11 +345,15 @@ namespace DiscImageChef.Core.Devices.Info
if(dev.Model.StartsWith("CD-R ", StringComparison.Ordinal)) if(dev.Model.StartsWith("CD-R ", StringComparison.Ordinal))
plxtSense = dev.PlextorReadEepromCdr(out plxtBuf, out senseBuf, dev.Timeout, plxtSense = dev.PlextorReadEepromCdr(out plxtBuf, out senseBuf, dev.Timeout,
out _); out _);
break; break;
} }
} }
PlextorFeatures = new Plextor {IsDvd = plxtDvd}; PlextorFeatures = new Plextor
{
IsDvd = plxtDvd
};
if(!plxtSense) if(!plxtSense)
{ {
@@ -328,6 +377,7 @@ namespace DiscImageChef.Core.Devices.Info
plxtSense = dev.PlextorGetPoweRec(out senseBuf, out bool plxtPwrRecEnabled, plxtSense = dev.PlextorGetPoweRec(out senseBuf, out bool plxtPwrRecEnabled,
out ushort plxtPwrRecSpeed, dev.Timeout, out _); out ushort plxtPwrRecSpeed, dev.Timeout, out _);
if(!plxtSense) if(!plxtSense)
{ {
PlextorFeatures.PoweRec = true; PlextorFeatures.PoweRec = true;
@@ -352,6 +402,7 @@ namespace DiscImageChef.Core.Devices.Info
// TODO: Check it with a drive // TODO: Check it with a drive
plxtSense = dev.PlextorGetSilentMode(out plxtBuf, out senseBuf, dev.Timeout, out _); plxtSense = dev.PlextorGetSilentMode(out plxtBuf, out senseBuf, dev.Timeout, out _);
if(!plxtSense) if(!plxtSense)
if(plxtBuf[0] == 1) if(plxtBuf[0] == 1)
{ {
@@ -374,44 +425,68 @@ namespace DiscImageChef.Core.Devices.Info
} }
plxtSense = dev.PlextorGetGigaRec(out plxtBuf, out senseBuf, dev.Timeout, out _); plxtSense = dev.PlextorGetGigaRec(out plxtBuf, out senseBuf, dev.Timeout, out _);
if(!plxtSense) PlextorFeatures.GigaRec = true;
if(!plxtSense)
PlextorFeatures.GigaRec = true;
plxtSense = dev.PlextorGetSecuRec(out plxtBuf, out senseBuf, dev.Timeout, out _); plxtSense = dev.PlextorGetSecuRec(out plxtBuf, out senseBuf, dev.Timeout, out _);
if(!plxtSense) PlextorFeatures.SecuRec = true;
if(!plxtSense)
PlextorFeatures.SecuRec = true;
plxtSense = dev.PlextorGetSpeedRead(out plxtBuf, out senseBuf, dev.Timeout, out _); plxtSense = dev.PlextorGetSpeedRead(out plxtBuf, out senseBuf, dev.Timeout, out _);
if(!plxtSense) if(!plxtSense)
{ {
PlextorFeatures.SpeedRead = true; PlextorFeatures.SpeedRead = true;
if((plxtBuf[2] & 0x01) == 0x01) PlextorFeatures.SpeedReadEnabled = true;
if((plxtBuf[2] & 0x01) == 0x01)
PlextorFeatures.SpeedReadEnabled = true;
} }
plxtSense = dev.PlextorGetHiding(out plxtBuf, out senseBuf, dev.Timeout, out _); plxtSense = dev.PlextorGetHiding(out plxtBuf, out senseBuf, dev.Timeout, out _);
if(!plxtSense) if(!plxtSense)
{ {
PlextorFeatures.Hiding = true; PlextorFeatures.Hiding = true;
if((plxtBuf[2] & 0x02) == 0x02) PlextorFeatures.HidesRecordables = true;
if((plxtBuf[2] & 0x01) == 0x01) PlextorFeatures.HidesSessions = true; if((plxtBuf[2] & 0x02) == 0x02)
PlextorFeatures.HidesRecordables = true;
if((plxtBuf[2] & 0x01) == 0x01)
PlextorFeatures.HidesSessions = true;
} }
plxtSense = dev.PlextorGetVariRec(out plxtBuf, out senseBuf, false, dev.Timeout, out _); plxtSense = dev.PlextorGetVariRec(out plxtBuf, out senseBuf, false, dev.Timeout, out _);
if(!plxtSense) PlextorFeatures.VariRec = true;
if(!plxtSense)
PlextorFeatures.VariRec = true;
if(plxtDvd) if(plxtDvd)
{ {
plxtSense = dev.PlextorGetVariRec(out plxtBuf, out senseBuf, true, dev.Timeout, plxtSense = dev.PlextorGetVariRec(out plxtBuf, out senseBuf, true, dev.Timeout,
out _); out _);
if(!plxtSense) PlextorFeatures.VariRecDvd = true;
if(!plxtSense)
PlextorFeatures.VariRecDvd = true;
plxtSense = dev.PlextorGetBitsetting(out plxtBuf, out senseBuf, false, dev.Timeout, plxtSense = dev.PlextorGetBitsetting(out plxtBuf, out senseBuf, false, dev.Timeout,
out _); out _);
if(!plxtSense) PlextorFeatures.BitSetting = true;
if(!plxtSense)
PlextorFeatures.BitSetting = true;
plxtSense = dev.PlextorGetBitsetting(out plxtBuf, out senseBuf, true, dev.Timeout, plxtSense = dev.PlextorGetBitsetting(out plxtBuf, out senseBuf, true, dev.Timeout,
out _); out _);
if(!plxtSense) PlextorFeatures.BitSettingDl = true;
if(!plxtSense)
PlextorFeatures.BitSettingDl = true;
plxtSense = dev.PlextorGetTestWriteDvdPlus(out plxtBuf, out senseBuf, dev.Timeout, plxtSense = dev.PlextorGetTestWriteDvdPlus(out plxtBuf, out senseBuf, dev.Timeout,
out _); out _);
if(!plxtSense) PlextorFeatures.DvdPlusWriteTest = true;
if(!plxtSense)
PlextorFeatures.DvdPlusWriteTest = true;
} }
} }
#endregion Plextor #endregion Plextor
@@ -420,17 +495,21 @@ namespace DiscImageChef.Core.Devices.Info
if(!dev.KreonGetFeatureList(out senseBuf, out KreonFeatures krFeatures, dev.Timeout, if(!dev.KreonGetFeatureList(out senseBuf, out KreonFeatures krFeatures, dev.Timeout,
out _)) out _))
KreonFeatures = krFeatures; KreonFeatures = krFeatures;
break; break;
} }
case PeripheralDeviceTypes.SequentialAccess: case PeripheralDeviceTypes.SequentialAccess:
{ {
sense = dev.ReadBlockLimits(out byte[] seqBuf, out senseBuf, dev.Timeout, out _); sense = dev.ReadBlockLimits(out byte[] seqBuf, out senseBuf, dev.Timeout, out _);
if(sense) if(sense)
DicConsole.ErrorWriteLine("READ BLOCK LIMITS:\n{0}", Sense.PrettifySense(senseBuf)); DicConsole.ErrorWriteLine("READ BLOCK LIMITS:\n{0}", Sense.PrettifySense(senseBuf));
else BlockLimits = seqBuf; else
BlockLimits = seqBuf;
sense = dev.ReportDensitySupport(out seqBuf, out senseBuf, dev.Timeout, out _); sense = dev.ReportDensitySupport(out seqBuf, out senseBuf, dev.Timeout, out _);
if(sense) if(sense)
DicConsole.ErrorWriteLine("REPORT DENSITY SUPPORT:\n{0}", DicConsole.ErrorWriteLine("REPORT DENSITY SUPPORT:\n{0}",
Sense.PrettifySense(senseBuf)); Sense.PrettifySense(senseBuf));
@@ -441,6 +520,7 @@ namespace DiscImageChef.Core.Devices.Info
} }
sense = dev.ReportDensitySupport(out seqBuf, out senseBuf, true, false, dev.Timeout, out _); sense = dev.ReportDensitySupport(out seqBuf, out senseBuf, true, false, dev.Timeout, out _);
if(sense) if(sense)
DicConsole.ErrorWriteLine("REPORT DENSITY SUPPORT (MEDIUM):\n{0}", DicConsole.ErrorWriteLine("REPORT DENSITY SUPPORT (MEDIUM):\n{0}",
Sense.PrettifySense(senseBuf)); Sense.PrettifySense(senseBuf));
@@ -459,36 +539,55 @@ namespace DiscImageChef.Core.Devices.Info
case DeviceType.MMC: case DeviceType.MMC:
{ {
bool sense = dev.ReadCid(out byte[] mmcBuf, out _, dev.Timeout, out _); bool sense = dev.ReadCid(out byte[] mmcBuf, out _, dev.Timeout, out _);
if(!sense) CID = mmcBuf;
if(!sense)
CID = mmcBuf;
sense = dev.ReadCsd(out mmcBuf, out _, dev.Timeout, out _); sense = dev.ReadCsd(out mmcBuf, out _, dev.Timeout, out _);
if(!sense) CSD = mmcBuf;
if(!sense)
CSD = mmcBuf;
sense = dev.ReadOcr(out mmcBuf, out _, dev.Timeout, out _); sense = dev.ReadOcr(out mmcBuf, out _, dev.Timeout, out _);
if(!sense) OCR = mmcBuf;
if(!sense)
OCR = mmcBuf;
sense = dev.ReadExtendedCsd(out mmcBuf, out _, dev.Timeout, out _); sense = dev.ReadExtendedCsd(out mmcBuf, out _, dev.Timeout, out _);
if(!sense) ExtendedCSD = mmcBuf;
if(!sense)
ExtendedCSD = mmcBuf;
} }
break; break;
case DeviceType.SecureDigital: case DeviceType.SecureDigital:
{ {
bool sense = dev.ReadCid(out byte[] sdBuf, out _, dev.Timeout, out _); bool sense = dev.ReadCid(out byte[] sdBuf, out _, dev.Timeout, out _);
if(!sense) CID = sdBuf;
if(!sense)
CID = sdBuf;
sense = dev.ReadCsd(out sdBuf, out _, dev.Timeout, out _); sense = dev.ReadCsd(out sdBuf, out _, dev.Timeout, out _);
if(!sense) CSD = sdBuf;
if(!sense)
CSD = sdBuf;
sense = dev.ReadSdocr(out sdBuf, out _, dev.Timeout, out _); sense = dev.ReadSdocr(out sdBuf, out _, dev.Timeout, out _);
if(!sense) OCR = sdBuf;
if(!sense)
OCR = sdBuf;
sense = dev.ReadScr(out sdBuf, out _, dev.Timeout, out _); sense = dev.ReadScr(out sdBuf, out _, dev.Timeout, out _);
if(!sense) SCR = sdBuf;
if(!sense)
SCR = sdBuf;
} }
break; break;
default: default:
DicConsole.ErrorWriteLine("Unknown device type {0}, cannot get information.", dev.Type); DicConsole.ErrorWriteLine("Unknown device type {0}, cannot get information.", dev.Type);
break; break;
} }
} }

View File

@@ -66,7 +66,7 @@ namespace DiscImageChef.Core.Devices.Info
public DeviceType Type { get; } public DeviceType Type { get; }
public string Manufacturer { get; } public string Manufacturer { get; }
public string Model { get; } public string Model { get; }
public string Revision { get; } public string FirmwareRevision { get; }
public string Serial { get; } public string Serial { get; }
public PeripheralDeviceTypes ScsiType { get; } public PeripheralDeviceTypes ScsiType { get; }
public bool IsRemovable { get; } public bool IsRemovable { get; }

View File

@@ -36,61 +36,67 @@ using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using DiscImageChef.CommonTypes.Interop; using DiscImageChef.CommonTypes.Interop;
using DiscImageChef.Devices; using DiscImageChef.Devices;
using PlatformID = DiscImageChef.CommonTypes.Interop.PlatformID;
using Version = DiscImageChef.CommonTypes.Interop.Version; using Version = DiscImageChef.CommonTypes.Interop.Version;
namespace DiscImageChef.Core.Logging namespace DiscImageChef.Core.Logging
{ {
/// <summary> /// <summary>Creates a dump log</summary>
/// Creates a dump log
/// </summary>
public class DumpLog public class DumpLog
{ {
private readonly StreamWriter logSw; readonly StreamWriter logSw;
/// <summary> /// <summary>Initializes the dump log</summary>
/// Initializes the dump log
/// </summary>
/// <param name="outputFile">Output log file</param> /// <param name="outputFile">Output log file</param>
/// <param name="dev">Device</param> /// <param name="dev">Device</param>
public DumpLog(string outputFile, Device dev) public DumpLog(string outputFile, Device dev)
{ {
if (string.IsNullOrEmpty(outputFile)) return; if(string.IsNullOrEmpty(outputFile))
return;
logSw = new StreamWriter(outputFile, true); logSw = new StreamWriter(outputFile, true);
logSw.WriteLine("Start logging at {0}", DateTime.Now); logSw.WriteLine("Start logging at {0}", DateTime.Now);
var platId = DetectOS.GetRealPlatformID(); PlatformID platId = DetectOS.GetRealPlatformID();
var platVer = DetectOS.GetVersion(); string platVer = DetectOS.GetVersion();
var assemblyVersion = var assemblyVersion =
Attribute.GetCustomAttribute(typeof(DumpLog).Assembly, typeof(AssemblyInformationalVersionAttribute)) as Attribute.GetCustomAttribute(typeof(DumpLog).Assembly, typeof(AssemblyInformationalVersionAttribute)) as
AssemblyInformationalVersionAttribute; AssemblyInformationalVersionAttribute;
logSw.WriteLine("################# System information #################"); logSw.WriteLine("################# System information #################");
logSw.WriteLine("{0} {1} ({2}-bit)", DetectOS.GetPlatformName(platId, platVer), platVer, logSw.WriteLine("{0} {1} ({2}-bit)", DetectOS.GetPlatformName(platId, platVer), platVer,
Environment.Is64BitOperatingSystem ? 64 : 32); Environment.Is64BitOperatingSystem ? 64 : 32);
if (DetectOS.IsMono) logSw.WriteLine("Mono {0}", Version.GetMonoVersion());
else if (DetectOS.IsNetCore) logSw.WriteLine(".NET Core {0}", Version.GetNetCoreVersion()); if(DetectOS.IsMono)
else logSw.WriteLine(RuntimeInformation.FrameworkDescription); logSw.WriteLine("Mono {0}", Version.GetMonoVersion());
else if(DetectOS.IsNetCore)
logSw.WriteLine(".NET Core {0}", Version.GetNetCoreVersion());
else
logSw.WriteLine(RuntimeInformation.FrameworkDescription);
logSw.WriteLine(); logSw.WriteLine();
logSw.WriteLine("################# Program information ################"); logSw.WriteLine("################# Program information ################");
logSw.WriteLine("DiscImageChef {0}", assemblyVersion?.InformationalVersion); logSw.WriteLine("DiscImageChef {0}", assemblyVersion?.InformationalVersion);
logSw.WriteLine("Running in {0}-bit", Environment.Is64BitProcess ? 64 : 32); logSw.WriteLine("Running in {0}-bit", Environment.Is64BitProcess ? 64 : 32);
#if DEBUG #if DEBUG
logSw.WriteLine("DEBUG version"); logSw.WriteLine("DEBUG version");
#endif #endif
logSw.WriteLine("Command line: {0}", Environment.CommandLine); logSw.WriteLine("Command line: {0}", Environment.CommandLine);
logSw.WriteLine(); logSw.WriteLine();
if (dev.IsRemote) if(dev.IsRemote)
{ {
logSw.WriteLine("################# Remote information #################"); logSw.WriteLine("################# Remote information #################");
logSw.WriteLine("Server: {0}", dev.RemoteApplication); logSw.WriteLine("Server: {0}", dev.RemoteApplication);
logSw.WriteLine("Version: {0}", dev.RemoteVersion); logSw.WriteLine("Version: {0}", dev.RemoteVersion);
logSw.WriteLine("Operating system: {0} {1}", dev.RemoteOperatingSystem, logSw.WriteLine("Operating system: {0} {1}", dev.RemoteOperatingSystem,
dev.RemoteOperatingSystemVersion); dev.RemoteOperatingSystemVersion);
logSw.WriteLine("Architecture: {0}", dev.RemoteArchitecture); logSw.WriteLine("Architecture: {0}", dev.RemoteArchitecture);
logSw.WriteLine("Protocol version: {0}", dev.RemoteProtocolVersion); logSw.WriteLine("Protocol version: {0}", dev.RemoteProtocolVersion);
logSw.WriteLine("######################################################"); logSw.WriteLine("######################################################");
@@ -99,14 +105,15 @@ namespace DiscImageChef.Core.Logging
logSw.WriteLine("################# Device information #################"); logSw.WriteLine("################# Device information #################");
logSw.WriteLine("Manufacturer: {0}", dev.Manufacturer); logSw.WriteLine("Manufacturer: {0}", dev.Manufacturer);
logSw.WriteLine("Model: {0}", dev.Model); logSw.WriteLine("Model: {0}", dev.Model);
logSw.WriteLine("Firmware revision: {0}", dev.Revision); logSw.WriteLine("Firmware revision: {0}", dev.FirmwareRevision);
logSw.WriteLine("Serial number: {0}", dev.Serial); logSw.WriteLine("Serial number: {0}", dev.Serial);
logSw.WriteLine("Removable device: {0}", dev.IsRemovable); logSw.WriteLine("Removable device: {0}", dev.IsRemovable);
logSw.WriteLine("Device type: {0}", dev.Type); logSw.WriteLine("Device type: {0}", dev.Type);
logSw.WriteLine("CompactFlash device: {0}", dev.IsCompactFlash); logSw.WriteLine("CompactFlash device: {0}", dev.IsCompactFlash);
logSw.WriteLine("PCMCIA device: {0}", dev.IsPcmcia); logSw.WriteLine("PCMCIA device: {0}", dev.IsPcmcia);
logSw.WriteLine("USB device: {0}", dev.IsUsb); logSw.WriteLine("USB device: {0}", dev.IsUsb);
if (dev.IsUsb)
if(dev.IsUsb)
{ {
logSw.WriteLine("USB manufacturer: {0}", dev.UsbManufacturerString); logSw.WriteLine("USB manufacturer: {0}", dev.UsbManufacturerString);
logSw.WriteLine("USB product: {0}", dev.UsbProductString); logSw.WriteLine("USB product: {0}", dev.UsbProductString);
@@ -116,7 +123,8 @@ namespace DiscImageChef.Core.Logging
} }
logSw.WriteLine("FireWire device: {0}", dev.IsFireWire); logSw.WriteLine("FireWire device: {0}", dev.IsFireWire);
if (dev.IsFireWire)
if(dev.IsFireWire)
{ {
logSw.WriteLine("FireWire vendor: {0}", dev.FireWireVendorName); logSw.WriteLine("FireWire vendor: {0}", dev.FireWireVendorName);
logSw.WriteLine("FireWire model: {0}", dev.FireWireModelName); logSw.WriteLine("FireWire model: {0}", dev.FireWireModelName);
@@ -132,23 +140,20 @@ namespace DiscImageChef.Core.Logging
logSw.Flush(); logSw.Flush();
} }
/// <summary> /// <summary>Adds a new line to the dump log</summary>
/// Adds a new line to the dump log
/// </summary>
/// <param name="format">Format string</param> /// <param name="format">Format string</param>
/// <param name="args">Arguments</param> /// <param name="args">Arguments</param>
public void WriteLine(string format, params object[] args) public void WriteLine(string format, params object[] args)
{ {
if (logSw == null) return; if(logSw == null)
return;
var text = string.Format(format, args); string text = string.Format(format, args);
logSw.WriteLine("{0:s} {1}", DateTime.Now, text); logSw.WriteLine("{0:s} {1}", DateTime.Now, text);
logSw.Flush(); logSw.Flush();
} }
/// <summary> /// <summary>Finishes and closes the dump log</summary>
/// Finishes and closes the dump log
/// </summary>
public void Close() public void Close()
{ {
logSw?.WriteLine("######################################################"); logSw?.WriteLine("######################################################");

View File

@@ -38,33 +38,30 @@ using DiscImageChef.Devices;
namespace DiscImageChef.Core.Logging namespace DiscImageChef.Core.Logging
{ {
/// <summary> /// <summary>Implements a log in the format used by IMGBurn</summary>
/// Implements a log in the format used by IMGBurn internal class IbgLog
/// </summary>
class IbgLog
{ {
readonly CultureInfo ibgCulture; readonly CultureInfo ibgCulture;
DateTime ibgDatePoint;
readonly double ibgDivider; readonly double ibgDivider;
readonly string ibgMediaType;
readonly StringBuilder ibgSb;
readonly string logFile;
DateTime ibgDatePoint;
ulong ibgIntSector; ulong ibgIntSector;
double ibgIntSpeed; double ibgIntSpeed;
double ibgMaxSpeed; double ibgMaxSpeed;
readonly string ibgMediaType;
int ibgSampleRate; int ibgSampleRate;
readonly StringBuilder ibgSb;
int ibgSnaps; int ibgSnaps;
bool ibgStartSet; bool ibgStartSet;
double ibgStartSpeed; double ibgStartSpeed;
readonly string logFile;
/// <summary> /// <summary>Initializes the IMGBurn log</summary>
/// Initializes the IMGBurn log
/// </summary>
/// <param name="outputFile">Log file</param> /// <param name="outputFile">Log file</param>
/// <param name="currentProfile">Profile as defined by SCSI MultiMedia Commands specification</param> /// <param name="currentProfile">Profile as defined by SCSI MultiMedia Commands specification</param>
internal IbgLog(string outputFile, ushort currentProfile) internal IbgLog(string outputFile, ushort currentProfile)
{ {
if(string.IsNullOrEmpty(outputFile)) return; if(string.IsNullOrEmpty(outputFile))
return;
logFile = outputFile; logFile = outputFile;
ibgSb = new StringBuilder(); ibgSb = new StringBuilder();
@@ -81,153 +78,186 @@ namespace DiscImageChef.Core.Logging
case 0x0001: case 0x0001:
ibgMediaType = "HDD"; ibgMediaType = "HDD";
ibgDivider = 1353; ibgDivider = 1353;
break; break;
case 0x0002: case 0x0002:
ibgMediaType = "PD-650"; ibgMediaType = "PD-650";
ibgDivider = 150; ibgDivider = 150;
break; break;
case 0x0005: case 0x0005:
ibgMediaType = "CD-MO"; ibgMediaType = "CD-MO";
ibgDivider = 150; ibgDivider = 150;
break; break;
case 0x0008: case 0x0008:
ibgMediaType = "CD-ROM"; ibgMediaType = "CD-ROM";
ibgDivider = 150; ibgDivider = 150;
break; break;
case 0x0009: case 0x0009:
ibgMediaType = "CD-R"; ibgMediaType = "CD-R";
ibgDivider = 150; ibgDivider = 150;
break; break;
case 0x000A: case 0x000A:
ibgMediaType = "CD-RW"; ibgMediaType = "CD-RW";
ibgDivider = 150; ibgDivider = 150;
break; break;
case 0x0010: case 0x0010:
ibgMediaType = "DVD-ROM"; ibgMediaType = "DVD-ROM";
ibgDivider = 1353; ibgDivider = 1353;
break; break;
case 0x0011: case 0x0011:
ibgMediaType = "DVD-R"; ibgMediaType = "DVD-R";
ibgDivider = 1353; ibgDivider = 1353;
break; break;
case 0x0012: case 0x0012:
ibgMediaType = "DVD-RAM"; ibgMediaType = "DVD-RAM";
ibgDivider = 1353; ibgDivider = 1353;
break; break;
case 0x0013: case 0x0013:
case 0x0014: case 0x0014:
ibgMediaType = "DVD-RW"; ibgMediaType = "DVD-RW";
ibgDivider = 1353; ibgDivider = 1353;
break; break;
case 0x0015: case 0x0015:
case 0x0016: case 0x0016:
ibgMediaType = "DVD-R DL"; ibgMediaType = "DVD-R DL";
ibgDivider = 1353; ibgDivider = 1353;
break; break;
case 0x0017: case 0x0017:
ibgMediaType = "DVD-RW DL"; ibgMediaType = "DVD-RW DL";
ibgDivider = 1353; ibgDivider = 1353;
break; break;
case 0x0018: case 0x0018:
ibgMediaType = "DVD-Download"; ibgMediaType = "DVD-Download";
ibgDivider = 1353; ibgDivider = 1353;
break; break;
case 0x001A: case 0x001A:
ibgMediaType = "DVD+RW"; ibgMediaType = "DVD+RW";
ibgDivider = 1353; ibgDivider = 1353;
break; break;
case 0x001B: case 0x001B:
ibgMediaType = "DVD+R"; ibgMediaType = "DVD+R";
ibgDivider = 1353; ibgDivider = 1353;
break; break;
case 0x0020: case 0x0020:
ibgMediaType = "DDCD-ROM"; ibgMediaType = "DDCD-ROM";
ibgDivider = 150; ibgDivider = 150;
break; break;
case 0x0021: case 0x0021:
ibgMediaType = "DDCD-R"; ibgMediaType = "DDCD-R";
ibgDivider = 150; ibgDivider = 150;
break; break;
case 0x0022: case 0x0022:
ibgMediaType = "DDCD-RW"; ibgMediaType = "DDCD-RW";
ibgDivider = 150; ibgDivider = 150;
break; break;
case 0x002A: case 0x002A:
ibgMediaType = "DVD+RW DL"; ibgMediaType = "DVD+RW DL";
ibgDivider = 1353; ibgDivider = 1353;
break; break;
case 0x002B: case 0x002B:
ibgMediaType = "DVD+R DL"; ibgMediaType = "DVD+R DL";
ibgDivider = 1353; ibgDivider = 1353;
break; break;
case 0x0040: case 0x0040:
ibgMediaType = "BD-ROM"; ibgMediaType = "BD-ROM";
ibgDivider = 4500; ibgDivider = 4500;
break; break;
case 0x0041: case 0x0041:
case 0x0042: case 0x0042:
ibgMediaType = "BD-R"; ibgMediaType = "BD-R";
ibgDivider = 4500; ibgDivider = 4500;
break; break;
case 0x0043: case 0x0043:
ibgMediaType = "BD-RE"; ibgMediaType = "BD-RE";
ibgDivider = 4500; ibgDivider = 4500;
break; break;
case 0x0050: case 0x0050:
ibgMediaType = "HD DVD-ROM"; ibgMediaType = "HD DVD-ROM";
ibgDivider = 4500; ibgDivider = 4500;
break; break;
case 0x0051: case 0x0051:
ibgMediaType = "HD DVD-R"; ibgMediaType = "HD DVD-R";
ibgDivider = 4500; ibgDivider = 4500;
break; break;
case 0x0052: case 0x0052:
ibgMediaType = "HD DVD-RAM"; ibgMediaType = "HD DVD-RAM";
ibgDivider = 4500; ibgDivider = 4500;
break; break;
case 0x0053: case 0x0053:
ibgMediaType = "HD DVD-RW"; ibgMediaType = "HD DVD-RW";
ibgDivider = 4500; ibgDivider = 4500;
break; break;
case 0x0058: case 0x0058:
ibgMediaType = "HD DVD-R DL"; ibgMediaType = "HD DVD-R DL";
ibgDivider = 4500; ibgDivider = 4500;
break; break;
case 0x005A: case 0x005A:
ibgMediaType = "HD DVD-RW DL"; ibgMediaType = "HD DVD-RW DL";
ibgDivider = 4500; ibgDivider = 4500;
break; break;
default: default:
ibgMediaType = "Unknown"; ibgMediaType = "Unknown";
ibgDivider = 1353; ibgDivider = 1353;
break; break;
} }
} }
/// <summary> /// <summary>Adds a new speed snapshot to the log</summary>
/// Adds a new speed snapshot to the log
/// </summary>
/// <param name="sector">Sector for the snapshot</param> /// <param name="sector">Sector for the snapshot</param>
/// <param name="currentSpeed">Current speed at the snapshot</param> /// <param name="currentSpeed">Current speed at the snapshot</param>
internal void Write(ulong sector, double currentSpeed) internal void Write(ulong sector, double currentSpeed)
{ {
if(logFile == null) return; if(logFile == null)
return;
ibgIntSpeed += currentSpeed; ibgIntSpeed += currentSpeed;
ibgSampleRate += (int)Math.Floor((DateTime.Now - ibgDatePoint).TotalMilliseconds); ibgSampleRate += (int)Math.Floor((DateTime.Now - ibgDatePoint).TotalMilliseconds);
ibgSnaps++; ibgSnaps++;
if(ibgSampleRate < 100) return; if(ibgSampleRate < 100)
return;
if(ibgIntSpeed > 0 && !ibgStartSet) if(ibgIntSpeed > 0 &&
!ibgStartSet)
{ {
ibgStartSpeed = ibgIntSpeed / ibgSnaps / ibgDivider; ibgStartSpeed = ibgIntSpeed / ibgSnaps / ibgDivider;
ibgStartSet = true; ibgStartSet = true;
} }
ibgSb.AppendFormat("{0:0.00},{1},{2:0},0", ibgIntSpeed / ibgSnaps / ibgDivider, ibgIntSector, ibgSampleRate) ibgSb.AppendFormat("{0:0.00},{1},{2:0},0", ibgIntSpeed / ibgSnaps / ibgDivider, ibgIntSector,
.AppendLine(); ibgSampleRate).AppendLine();
if(ibgIntSpeed / ibgSnaps / ibgDivider > ibgMaxSpeed) ibgMaxSpeed = ibgIntSpeed / ibgDivider;
if(ibgIntSpeed / ibgSnaps / ibgDivider > ibgMaxSpeed)
ibgMaxSpeed = ibgIntSpeed / ibgDivider;
ibgDatePoint = DateTime.Now; ibgDatePoint = DateTime.Now;
ibgIntSpeed = 0; ibgIntSpeed = 0;
@@ -236,9 +266,7 @@ namespace DiscImageChef.Core.Logging
ibgIntSector = sector; ibgIntSector = sector;
} }
/// <summary> /// <summary>Closes the IMGBurn log</summary>
/// Closes the IMGBurn log
/// </summary>
/// <param name="dev">Device</param> /// <param name="dev">Device</param>
/// <param name="blocks">Media blocks</param> /// <param name="blocks">Media blocks</param>
/// <param name="blockSize">Bytes per block</param> /// <param name="blockSize">Bytes per block</param>
@@ -246,19 +274,22 @@ namespace DiscImageChef.Core.Logging
/// <param name="currentSpeed">Speed at the end</param> /// <param name="currentSpeed">Speed at the end</param>
/// <param name="averageSpeed">Average speed</param> /// <param name="averageSpeed">Average speed</param>
/// <param name="devicePath">Device path</param> /// <param name="devicePath">Device path</param>
internal void Close(Device dev, ulong blocks, ulong blockSize, double totalSeconds, internal void Close(Device dev, ulong blocks, ulong blockSize, double totalSeconds, double currentSpeed,
double currentSpeed,
double averageSpeed, string devicePath) double averageSpeed, string devicePath)
{ {
if(logFile == null) return; if(logFile == null)
return;
FileStream ibgFs = new FileStream(logFile, FileMode.Create); var ibgFs = new FileStream(logFile, FileMode.Create);
StringBuilder ibgHeader = new StringBuilder(); var ibgHeader = new StringBuilder();
string ibgBusType; string ibgBusType;
if(dev.IsUsb) ibgBusType = "USB"; if(dev.IsUsb)
else if(dev.IsFireWire) ibgBusType = "FireWire"; ibgBusType = "USB";
else ibgBusType = dev.Type.ToString(); else if(dev.IsFireWire)
ibgBusType = "FireWire";
else
ibgBusType = dev.Type.ToString();
ibgHeader.AppendLine("IBGD"); ibgHeader.AppendLine("IBGD");
ibgHeader.AppendLine(); ibgHeader.AppendLine();
@@ -270,11 +301,13 @@ namespace DiscImageChef.Core.Logging
ibgHeader.AppendFormat("SAMPLE_RATE={0}", 100).AppendLine(); ibgHeader.AppendFormat("SAMPLE_RATE={0}", 100).AppendLine();
ibgHeader.AppendLine(); ibgHeader.AppendLine();
ibgHeader.AppendFormat("DEVICE=[0:0:0] {0} {1} ({2}) ({3})", dev.Manufacturer, dev.Model, devicePath, ibgHeader.AppendFormat("DEVICE=[0:0:0] {0} {1} ({2}) ({3})", dev.Manufacturer, dev.Model, devicePath,
ibgBusType).AppendLine(); ibgBusType).AppendLine();
ibgHeader.AppendLine("DEVICE_ADDRESS=0:0:0"); ibgHeader.AppendLine("DEVICE_ADDRESS=0:0:0");
ibgHeader.AppendFormat("DEVICE_MAKEMODEL={0} {1}", dev.Manufacturer, dev.Model).AppendLine(); ibgHeader.AppendFormat("DEVICE_MAKEMODEL={0} {1}", dev.Manufacturer, dev.Model).AppendLine();
ibgHeader.AppendFormat("DEVICE_FIRMWAREVERSION={0}", dev.Revision).AppendLine(); ibgHeader.AppendFormat("DEVICE_FIRMWAREVERSION={0}", dev.FirmwareRevision).AppendLine();
ibgHeader.AppendFormat("DEVICE_DRIVELETTER={0}", devicePath).AppendLine(); ibgHeader.AppendFormat("DEVICE_DRIVELETTER={0}", devicePath).AppendLine();
ibgHeader.AppendFormat("DEVICE_BUSTYPE={0}", ibgBusType).AppendLine(); ibgHeader.AppendFormat("DEVICE_BUSTYPE={0}", ibgBusType).AppendLine();
ibgHeader.AppendLine(); ibgHeader.AppendLine();
@@ -307,7 +340,7 @@ namespace DiscImageChef.Core.Logging
ibgHeader.AppendLine(); ibgHeader.AppendLine();
ibgHeader.Replace("\r\n", "\n").Replace("\r", "\n").Replace("\n", "\r\n"); ibgHeader.Replace("\r\n", "\n").Replace("\r", "\n").Replace("\n", "\r\n");
StreamWriter sr = new StreamWriter(ibgFs); var sr = new StreamWriter(ibgFs);
sr.Write(ibgHeader); sr.Write(ibgHeader);
sr.Close(); sr.Close();
ibgFs.Close(); ibgFs.Close();

View File

@@ -39,17 +39,13 @@ using DiscImageChef.Devices;
namespace DiscImageChef.Core.Logging namespace DiscImageChef.Core.Logging
{ {
/// <summary> /// <summary>Implements a log in the format used by MHDD</summary>
/// Implements a log in the format used by MHDD internal class MhddLog
/// </summary>
class MhddLog
{ {
string logFile; readonly string logFile;
MemoryStream mhddFs; readonly MemoryStream mhddFs;
/// <summary> /// <summary>Initializes the MHDD log</summary>
/// Initializes the MHDD log
/// </summary>
/// <param name="outputFile">Log file</param> /// <param name="outputFile">Log file</param>
/// <param name="dev">Device</param> /// <param name="dev">Device</param>
/// <param name="blocks">Blocks in media</param> /// <param name="blocks">Blocks in media</param>
@@ -57,7 +53,9 @@ namespace DiscImageChef.Core.Logging
/// <param name="blocksToRead">How many blocks read at once</param> /// <param name="blocksToRead">How many blocks read at once</param>
internal MhddLog(string outputFile, Device dev, ulong blocks, ulong blockSize, ulong blocksToRead) internal MhddLog(string outputFile, Device dev, ulong blocks, ulong blockSize, ulong blocksToRead)
{ {
if(dev == null || string.IsNullOrEmpty(outputFile)) return; if(dev == null ||
string.IsNullOrEmpty(outputFile))
return;
mhddFs = new MemoryStream(); mhddFs = new MemoryStream();
logFile = outputFile; logFile = outputFile;
@@ -69,31 +67,39 @@ namespace DiscImageChef.Core.Logging
case DeviceType.ATA: case DeviceType.ATA:
case DeviceType.ATAPI: case DeviceType.ATAPI:
mode = "MODE: IDE"; mode = "MODE: IDE";
break; break;
case DeviceType.SCSI: case DeviceType.SCSI:
mode = "MODE: SCSI"; mode = "MODE: SCSI";
break; break;
case DeviceType.MMC: case DeviceType.MMC:
mode = "MODE: MMC"; mode = "MODE: MMC";
break; break;
case DeviceType.NVMe: case DeviceType.NVMe:
mode = "MODE: NVMe"; mode = "MODE: NVMe";
break; break;
case DeviceType.SecureDigital: case DeviceType.SecureDigital:
mode = "MODE: SD"; mode = "MODE: SD";
break; break;
default: default:
mode = "MODE: IDE"; mode = "MODE: IDE";
break; break;
} }
string device = $"DEVICE: {dev.Manufacturer} {dev.Model}"; string device = $"DEVICE: {dev.Manufacturer} {dev.Model}";
string fw = $"F/W: {dev.Revision}"; string fw = $"F/W: {dev.FirmwareRevision}";
string sn = $"S/N: {dev.Serial}"; string sn = $"S/N: {dev.Serial}";
string sectors = string.Format(new CultureInfo("en-US"), "SECTORS: {0:n0}", blocks); string sectors = string.Format(new CultureInfo("en-US"), "SECTORS: {0:n0}", blocks);
string sectorsize = string.Format(new CultureInfo("en-US"), "SECTOR SIZE: {0:n0} bytes", blockSize); string sectorsize = string.Format(new CultureInfo("en-US"), "SECTOR SIZE: {0:n0} bytes", blockSize);
string scanblocksize = string scanblocksize =
string.Format(new CultureInfo("en-US"), "SCAN BLOCK SIZE: {0:n0} sectors", blocksToRead); string.Format(new CultureInfo("en-US"), "SCAN BLOCK SIZE: {0:n0} sectors", blocksToRead);
const string MHDD_VER = "VER:2 "; const string MHDD_VER = "VER:2 ";
byte[] deviceBytes = Encoding.ASCII.GetBytes(device); byte[] deviceBytes = Encoding.ASCII.GetBytes(device);
@@ -108,7 +114,7 @@ namespace DiscImageChef.Core.Logging
uint pointer = (uint)(deviceBytes.Length + modeBytes.Length + fwBytes.Length + uint pointer = (uint)(deviceBytes.Length + modeBytes.Length + fwBytes.Length +
snBytes.Length + snBytes.Length +
sectorsBytes.Length + sectorsizeBytes.Length + scanblocksizeBytes.Length + sectorsBytes.Length + sectorsizeBytes.Length + scanblocksizeBytes.Length +
verBytes.Length + 2 * 9 + // New lines verBytes.Length + (2 * 9) + // New lines
4); // Pointer 4); // Pointer
byte[] newLine = new byte[2]; byte[] newLine = new byte[2];
@@ -116,49 +122,47 @@ namespace DiscImageChef.Core.Logging
newLine[1] = 0x0A; newLine[1] = 0x0A;
mhddFs.Write(BitConverter.GetBytes(pointer), 0, 4); mhddFs.Write(BitConverter.GetBytes(pointer), 0, 4);
mhddFs.Write(newLine, 0, 2); mhddFs.Write(newLine, 0, 2);
mhddFs.Write(verBytes, 0, verBytes.Length); mhddFs.Write(verBytes, 0, verBytes.Length);
mhddFs.Write(newLine, 0, 2); mhddFs.Write(newLine, 0, 2);
mhddFs.Write(modeBytes, 0, modeBytes.Length); mhddFs.Write(modeBytes, 0, modeBytes.Length);
mhddFs.Write(newLine, 0, 2); mhddFs.Write(newLine, 0, 2);
mhddFs.Write(deviceBytes, 0, deviceBytes.Length); mhddFs.Write(deviceBytes, 0, deviceBytes.Length);
mhddFs.Write(newLine, 0, 2); mhddFs.Write(newLine, 0, 2);
mhddFs.Write(fwBytes, 0, fwBytes.Length); mhddFs.Write(fwBytes, 0, fwBytes.Length);
mhddFs.Write(newLine, 0, 2); mhddFs.Write(newLine, 0, 2);
mhddFs.Write(snBytes, 0, snBytes.Length); mhddFs.Write(snBytes, 0, snBytes.Length);
mhddFs.Write(newLine, 0, 2); mhddFs.Write(newLine, 0, 2);
mhddFs.Write(sectorsBytes, 0, sectorsBytes.Length); mhddFs.Write(sectorsBytes, 0, sectorsBytes.Length);
mhddFs.Write(newLine, 0, 2); mhddFs.Write(newLine, 0, 2);
mhddFs.Write(sectorsizeBytes, 0, sectorsizeBytes.Length); mhddFs.Write(sectorsizeBytes, 0, sectorsizeBytes.Length);
mhddFs.Write(newLine, 0, 2); mhddFs.Write(newLine, 0, 2);
mhddFs.Write(scanblocksizeBytes, 0, scanblocksizeBytes.Length); mhddFs.Write(scanblocksizeBytes, 0, scanblocksizeBytes.Length);
mhddFs.Write(newLine, 0, 2); mhddFs.Write(newLine, 0, 2);
} }
/// <summary> /// <summary>Logs a new read</summary>
/// Logs a new read
/// </summary>
/// <param name="sector">Starting sector</param> /// <param name="sector">Starting sector</param>
/// <param name="duration">Duration in milliseconds</param> /// <param name="duration">Duration in milliseconds</param>
internal void Write(ulong sector, double duration) internal void Write(ulong sector, double duration)
{ {
if(logFile == null) return; if(logFile == null)
return;
byte[] sectorBytes = BitConverter.GetBytes(sector); byte[] sectorBytes = BitConverter.GetBytes(sector);
byte[] durationBytes = BitConverter.GetBytes((ulong)(duration * 1000)); byte[] durationBytes = BitConverter.GetBytes((ulong)(duration * 1000));
mhddFs.Write(sectorBytes, 0, 8); mhddFs.Write(sectorBytes, 0, 8);
mhddFs.Write(durationBytes, 0, 8); mhddFs.Write(durationBytes, 0, 8);
} }
/// <summary> /// <summary>Closes and writes to file the MHDD log</summary>
/// Closes and writes to file the MHDD log
/// </summary>
internal void Close() internal void Close()
{ {
if(logFile == null) return; if(logFile == null)
return;
FileStream fs = new FileStream(logFile, FileMode.Create); var fs = new FileStream(logFile, FileMode.Create);
mhddFs.WriteTo(fs); mhddFs.WriteTo(fs);
mhddFs.Close(); mhddFs.Close();
fs.Close(); fs.Close();

View File

@@ -1272,7 +1272,8 @@ namespace DiscImageChef.Core
ctx.SeenDevices.Add(new DeviceStat ctx.SeenDevices.Add(new DeviceStat
{ {
Bus = deviceBus, Manufacturer = dev.Manufacturer, Model = dev.Model, Revision = dev.Revision, Bus = deviceBus, Manufacturer = dev.Manufacturer, Model = dev.Model,
Revision = dev.FirmwareRevision,
Synchronized = false Synchronized = false
}); });

File diff suppressed because it is too large Load Diff

View File

@@ -100,10 +100,10 @@ namespace DiscImageChef.Devices
public string Model { get; } public string Model { get; }
/// <summary> /// <summary>
/// Gets the device's revision. /// Gets the device's firmware version.
/// </summary> /// </summary>
/// <value>The revision.</value> /// <value>The firmware version.</value>
public string Revision { get; } public string FirmwareRevision { get; }
/// <summary> /// <summary>
/// Gets the device's serial number. /// Gets the device's serial number.

View File

@@ -43,7 +43,7 @@ namespace DiscImageChef.Gui.Panels
{ {
public class pnlDeviceInfo : Panel public class pnlDeviceInfo : Panel
{ {
DeviceInfo devInfo; readonly DeviceInfo devInfo;
public pnlDeviceInfo(DeviceInfo devInfo) public pnlDeviceInfo(DeviceInfo devInfo)
{ {
@@ -54,7 +54,7 @@ namespace DiscImageChef.Gui.Panels
txtType.Text = devInfo.Type.ToString(); txtType.Text = devInfo.Type.ToString();
txtManufacturer.Text = devInfo.Manufacturer; txtManufacturer.Text = devInfo.Manufacturer;
txtModel.Text = devInfo.Model; txtModel.Text = devInfo.Model;
txtRevision.Text = devInfo.Revision; txtRevision.Text = devInfo.FirmwareRevision;
txtSerial.Text = devInfo.Serial; txtSerial.Text = devInfo.Serial;
txtScsiType.Text = devInfo.ScsiType.ToString(); txtScsiType.Text = devInfo.ScsiType.ToString();
chkRemovable.Checked = devInfo.IsRemovable; chkRemovable.Checked = devInfo.IsRemovable;
@@ -83,14 +83,15 @@ namespace DiscImageChef.Gui.Panels
if(devInfo.IsPcmcia) if(devInfo.IsPcmcia)
{ {
tabPcmciaInfo tabPcmciaInfo = new tabPcmciaInfo(); var tabPcmciaInfo = new tabPcmciaInfo();
tabPcmciaInfo.LoadData(devInfo.Cis); tabPcmciaInfo.LoadData(devInfo.Cis);
tabInfos.Pages.Add(tabPcmciaInfo); tabInfos.Pages.Add(tabPcmciaInfo);
} }
if(devInfo.AtaIdentify != null || devInfo.AtapiIdentify != null) if(devInfo.AtaIdentify != null ||
devInfo.AtapiIdentify != null)
{ {
tabAtaInfo tabAtaInfo = new tabAtaInfo(); var tabAtaInfo = new tabAtaInfo();
tabAtaInfo.LoadData(devInfo.AtaIdentify, devInfo.AtapiIdentify, devInfo.AtaMcptError); tabAtaInfo.LoadData(devInfo.AtaIdentify, devInfo.AtapiIdentify, devInfo.AtaMcptError);
tabInfos.Pages.Add(tabAtaInfo); tabInfos.Pages.Add(tabAtaInfo);
@@ -98,7 +99,8 @@ namespace DiscImageChef.Gui.Panels
if(devInfo.ScsiInquiryData != null) if(devInfo.ScsiInquiryData != null)
{ {
tabScsiInfo tabScsiInfo = new tabScsiInfo(); var tabScsiInfo = new tabScsiInfo();
tabScsiInfo.LoadData(devInfo.ScsiInquiryData, devInfo.ScsiInquiry, devInfo.ScsiEvpdPages, tabScsiInfo.LoadData(devInfo.ScsiInquiryData, devInfo.ScsiInquiry, devInfo.ScsiEvpdPages,
devInfo.ScsiMode, devInfo.ScsiType, devInfo.ScsiModeSense6, devInfo.ScsiMode, devInfo.ScsiType, devInfo.ScsiModeSense6,
devInfo.ScsiModeSense10, devInfo.MmcConfiguration); devInfo.ScsiModeSense10, devInfo.MmcConfiguration);
@@ -108,18 +110,23 @@ namespace DiscImageChef.Gui.Panels
if(devInfo.PlextorFeatures != null) if(devInfo.PlextorFeatures != null)
{ {
tabPlextor.Visible = true; tabPlextor.Visible = true;
if(devInfo.PlextorFeatures.Eeprom != null) if(devInfo.PlextorFeatures.Eeprom != null)
{ {
stkPlextorEeprom.Visible = true; stkPlextorEeprom.Visible = true;
txtPlextorDiscs.Text = $"{devInfo.PlextorFeatures.Discs}"; txtPlextorDiscs.Text = $"{devInfo.PlextorFeatures.Discs}";
txtPlextorCdReadTime.Text = TimeSpan.FromSeconds(devInfo.PlextorFeatures.CdReadTime).ToString(); txtPlextorCdReadTime.Text = TimeSpan.FromSeconds(devInfo.PlextorFeatures.CdReadTime).ToString();
txtPlextorCdWriteTime.Text = txtPlextorCdWriteTime.Text =
TimeSpan.FromSeconds(devInfo.PlextorFeatures.CdWriteTime).ToString(); TimeSpan.FromSeconds(devInfo.PlextorFeatures.CdWriteTime).ToString();
if(devInfo.PlextorFeatures.IsDvd) if(devInfo.PlextorFeatures.IsDvd)
{ {
stkPlextorDvdTimes.Visible = true; stkPlextorDvdTimes.Visible = true;
txtPlextorDvdReadTime.Text = txtPlextorDvdReadTime.Text =
TimeSpan.FromSeconds(devInfo.PlextorFeatures.DvdReadTime).ToString(); TimeSpan.FromSeconds(devInfo.PlextorFeatures.DvdReadTime).ToString();
txtPlextorDvdWriteTime.Text = txtPlextorDvdWriteTime.Text =
TimeSpan.FromSeconds(devInfo.PlextorFeatures.DvdWriteTime).ToString(); TimeSpan.FromSeconds(devInfo.PlextorFeatures.DvdWriteTime).ToString();
} }
@@ -139,6 +146,7 @@ namespace DiscImageChef.Gui.Panels
if(devInfo.PlextorFeatures.PoweRecRecommendedSpeed > 0) if(devInfo.PlextorFeatures.PoweRecRecommendedSpeed > 0)
{ {
stkPlextorPoweRecRecommended.Visible = true; stkPlextorPoweRecRecommended.Visible = true;
txtPlextorPoweRecRecommended.Text = txtPlextorPoweRecRecommended.Text =
$"{devInfo.PlextorFeatures.PoweRecRecommendedSpeed} Kb/sec."; $"{devInfo.PlextorFeatures.PoweRecRecommendedSpeed} Kb/sec.";
} }
@@ -146,6 +154,7 @@ namespace DiscImageChef.Gui.Panels
if(devInfo.PlextorFeatures.PoweRecSelected > 0) if(devInfo.PlextorFeatures.PoweRecSelected > 0)
{ {
stkPlextorPoweRecSelected.Visible = true; stkPlextorPoweRecSelected.Visible = true;
txtPlextorPoweRecSelected.Text = txtPlextorPoweRecSelected.Text =
$"{devInfo.PlextorFeatures.PoweRecSelected} Kb/sec."; $"{devInfo.PlextorFeatures.PoweRecSelected} Kb/sec.";
} }
@@ -179,21 +188,19 @@ namespace DiscImageChef.Gui.Panels
txtPlextorSilentModeCdReadSpeedLimit.Text = txtPlextorSilentModeCdReadSpeedLimit.Text =
devInfo.PlextorFeatures.CdReadSpeedLimit > 0 devInfo.PlextorFeatures.CdReadSpeedLimit > 0
? $"{devInfo.PlextorFeatures.CdReadSpeedLimit}x" ? $"{devInfo.PlextorFeatures.CdReadSpeedLimit}x" : "unlimited";
: "unlimited";
txtPlextorSilentModeCdWriteSpeedLimit.Text = txtPlextorSilentModeCdWriteSpeedLimit.Text =
devInfo.PlextorFeatures.CdWriteSpeedLimit > 0 devInfo.PlextorFeatures.CdWriteSpeedLimit > 0
? $"{devInfo.PlextorFeatures.CdReadSpeedLimit}x" ? $"{devInfo.PlextorFeatures.CdReadSpeedLimit}x" : "unlimited";
: "unlimited";
if(devInfo.PlextorFeatures.IsDvd) if(devInfo.PlextorFeatures.IsDvd)
{ {
stkPlextorSilentModeDvdReadSpeedLimit.Visible = true; stkPlextorSilentModeDvdReadSpeedLimit.Visible = true;
txtPlextorSilentModeDvdReadSpeedLimit.Text = txtPlextorSilentModeDvdReadSpeedLimit.Text =
devInfo.PlextorFeatures.DvdReadSpeedLimit > 0 devInfo.PlextorFeatures.DvdReadSpeedLimit > 0
? $"{devInfo.PlextorFeatures.DvdReadSpeedLimit}x" ? $"{devInfo.PlextorFeatures.DvdReadSpeedLimit}x" : "unlimited";
: "unlimited";
} }
} }
} }
@@ -209,6 +216,7 @@ namespace DiscImageChef.Gui.Panels
} }
chkPlextorHiding.Checked = devInfo.PlextorFeatures.Hiding; chkPlextorHiding.Checked = devInfo.PlextorFeatures.Hiding;
if(devInfo.PlextorFeatures.Hiding) if(devInfo.PlextorFeatures.Hiding)
{ {
stkPlextorHiding.Visible = true; stkPlextorHiding.Visible = true;
@@ -235,8 +243,10 @@ namespace DiscImageChef.Gui.Panels
chkKreonDecryptSs.Checked = devInfo.KreonFeatures.HasFlag(KreonFeatures.DecryptSs); chkKreonDecryptSs.Checked = devInfo.KreonFeatures.HasFlag(KreonFeatures.DecryptSs);
chkKreonXtremeUnlock.Checked = devInfo.KreonFeatures.HasFlag(KreonFeatures.XtremeUnlock); chkKreonXtremeUnlock.Checked = devInfo.KreonFeatures.HasFlag(KreonFeatures.XtremeUnlock);
chkKreonWxripperUnlock.Checked = devInfo.KreonFeatures.HasFlag(KreonFeatures.WxripperUnlock); chkKreonWxripperUnlock.Checked = devInfo.KreonFeatures.HasFlag(KreonFeatures.WxripperUnlock);
chkKreonChallengeResponse360.Checked = chkKreonChallengeResponse360.Checked =
devInfo.KreonFeatures.HasFlag(KreonFeatures.ChallengeResponse360); devInfo.KreonFeatures.HasFlag(KreonFeatures.ChallengeResponse360);
chkKreonDecryptSs360.Checked = devInfo.KreonFeatures.HasFlag(KreonFeatures.DecryptSs360); chkKreonDecryptSs360.Checked = devInfo.KreonFeatures.HasFlag(KreonFeatures.DecryptSs360);
chkKreonXtremeUnlock360.Checked = devInfo.KreonFeatures.HasFlag(KreonFeatures.XtremeUnlock360); chkKreonXtremeUnlock360.Checked = devInfo.KreonFeatures.HasFlag(KreonFeatures.XtremeUnlock360);
chkKreonWxripperUnlock360.Checked = devInfo.KreonFeatures.HasFlag(KreonFeatures.WxripperUnlock360); chkKreonWxripperUnlock360.Checked = devInfo.KreonFeatures.HasFlag(KreonFeatures.WxripperUnlock360);
@@ -251,9 +261,11 @@ namespace DiscImageChef.Gui.Panels
if(blockLimits.HasValue) if(blockLimits.HasValue)
{ {
tabSsc.Visible = true; tabSsc.Visible = true;
if(blockLimits.Value.minBlockLen == blockLimits.Value.maxBlockLen) if(blockLimits.Value.minBlockLen == blockLimits.Value.maxBlockLen)
{ {
lblMinBlockSize.Visible = true; lblMinBlockSize.Visible = true;
lblMinBlockSize.Text = lblMinBlockSize.Text =
$"Device's block size is fixed at {blockLimits.Value.minBlockLen} bytes"; $"Device's block size is fixed at {blockLimits.Value.minBlockLen} bytes";
} }
@@ -265,12 +277,14 @@ namespace DiscImageChef.Gui.Panels
lblMaxBlockSize.Text = blockLimits.Value.maxBlockLen > 0 lblMaxBlockSize.Text = blockLimits.Value.maxBlockLen > 0
? $"Device's maximum block size is {blockLimits.Value.maxBlockLen} bytes" ? $"Device's maximum block size is {blockLimits.Value.maxBlockLen} bytes"
: "Device does not specify a maximum block size"; : "Device does not specify a maximum block size";
lblMinBlockSize.Text = lblMinBlockSize.Text =
$"Device's minimum block size is {blockLimits.Value.minBlockLen} bytes"; $"Device's minimum block size is {blockLimits.Value.minBlockLen} bytes";
if(blockLimits.Value.granularity > 0) if(blockLimits.Value.granularity > 0)
{ {
lblBlockSizeGranularity.Visible = true; lblBlockSizeGranularity.Visible = true;
lblBlockSizeGranularity.Text = lblBlockSizeGranularity.Text =
$"Device's needs a block size granularity of 2^{blockLimits.Value.granularity} ({Math.Pow(2, blockLimits.Value.granularity)}) bytes"; $"Device's needs a block size granularity of 2^{blockLimits.Value.granularity} ({Math.Pow(2, blockLimits.Value.granularity)}) bytes";
} }
@@ -298,7 +312,8 @@ namespace DiscImageChef.Gui.Panels
} }
} }
tabSdMmcInfo tabSdMmcInfo = new tabSdMmcInfo(); var tabSdMmcInfo = new tabSdMmcInfo();
tabSdMmcInfo.LoadData(devInfo.Type, devInfo.CID, devInfo.CSD, devInfo.OCR, devInfo.ExtendedCSD, tabSdMmcInfo.LoadData(devInfo.Type, devInfo.CID, devInfo.CSD, devInfo.OCR, devInfo.ExtendedCSD,
devInfo.SCR); devInfo.SCR);
@@ -307,13 +322,23 @@ namespace DiscImageChef.Gui.Panels
protected void OnBtnSaveUsbDescriptors(object sender, EventArgs e) protected void OnBtnSaveUsbDescriptors(object sender, EventArgs e)
{ {
SaveFileDialog dlgSaveBinary = new SaveFileDialog(); var dlgSaveBinary = new SaveFileDialog();
dlgSaveBinary.Filters.Add(new FileFilter {Extensions = new[] {"*.bin"}, Name = "Binary"});
dlgSaveBinary.Filters.Add(new FileFilter
{
Extensions = new[]
{
"*.bin"
},
Name = "Binary"
});
DialogResult result = dlgSaveBinary.ShowDialog(this); DialogResult result = dlgSaveBinary.ShowDialog(this);
if(result != DialogResult.Ok) return; if(result != DialogResult.Ok)
return;
FileStream saveFs = new FileStream(dlgSaveBinary.FileName, FileMode.Create); var saveFs = new FileStream(dlgSaveBinary.FileName, FileMode.Create);
saveFs.Write(devInfo.UsbDescriptors, 0, devInfo.UsbDescriptors.Length); saveFs.Write(devInfo.UsbDescriptors, 0, devInfo.UsbDescriptors.Length);
saveFs.Close(); saveFs.Close();

View File

@@ -129,19 +129,19 @@ namespace DiscImageChef.Commands.Device
var report = new DeviceReportV2 var report = new DeviceReportV2
{ {
Manufacturer = dev.Manufacturer, Model = dev.Model, Revision = dev.Revision, Type = dev.Type Manufacturer = dev.Manufacturer, Model = dev.Model, Revision = dev.FirmwareRevision, Type = dev.Type
}; };
bool removable = false; bool removable = false;
string jsonFile; string jsonFile;
if(!string.IsNullOrWhiteSpace(dev.Manufacturer) && if(!string.IsNullOrWhiteSpace(dev.Manufacturer) &&
!string.IsNullOrWhiteSpace(dev.Revision)) !string.IsNullOrWhiteSpace(dev.FirmwareRevision))
jsonFile = dev.Manufacturer + "_" + dev.Model + "_" + dev.Revision + ".json"; jsonFile = dev.Manufacturer + "_" + dev.Model + "_" + dev.FirmwareRevision + ".json";
else if(!string.IsNullOrWhiteSpace(dev.Manufacturer)) else if(!string.IsNullOrWhiteSpace(dev.Manufacturer))
jsonFile = dev.Manufacturer + "_" + dev.Model + ".json"; jsonFile = dev.Manufacturer + "_" + dev.Model + ".json";
else if(!string.IsNullOrWhiteSpace(dev.Revision)) else if(!string.IsNullOrWhiteSpace(dev.FirmwareRevision))
jsonFile = dev.Model + "_" + dev.Revision + ".json"; jsonFile = dev.Model + "_" + dev.FirmwareRevision + ".json";
else else
jsonFile = dev.Model + ".json"; jsonFile = dev.Model + ".json";

View File

@@ -1078,7 +1078,7 @@ namespace DiscImageChef.Commands.Device
// Search for device in master database // Search for device in master database
Database.Models.Device dbDev = Database.Models.Device dbDev =
ctx.Devices.FirstOrDefault(d => d.Manufacturer == dev.Manufacturer && d.Model == dev.Model && ctx.Devices.FirstOrDefault(d => d.Manufacturer == dev.Manufacturer && d.Model == dev.Model &&
d.Revision == dev.Revision); d.Revision == dev.FirmwareRevision);
if(dbDev is null) if(dbDev is null)
DicConsole.WriteLine("Device not in database, please create a device report and attach it to a Github issue."); DicConsole.WriteLine("Device not in database, please create a device report and attach it to a Github issue.");

View File

@@ -557,7 +557,7 @@ namespace DiscImageChef.Commands.Media
// Search for device in master database // Search for device in master database
Database.Models.Device dbDev = Database.Models.Device dbDev =
ctx.Devices.FirstOrDefault(d => d.Manufacturer == dev.Manufacturer && d.Model == dev.Model && ctx.Devices.FirstOrDefault(d => d.Manufacturer == dev.Manufacturer && d.Model == dev.Model &&
d.Revision == dev.Revision); d.Revision == dev.FirmwareRevision);
Dump.SolveTrackPregaps(dev, null, null, tracks, supportsPqSubchannel, supportsRwSubchannel, dbDev, Dump.SolveTrackPregaps(dev, null, null, tracks, supportsPqSubchannel, supportsRwSubchannel, dbDev,
out bool inexactPositioning); out bool inexactPositioning);