Clarify interface usage.

This commit is contained in:
2021-12-28 00:14:33 +00:00
parent d10607ef29
commit 4de10d0c34
29 changed files with 419 additions and 392 deletions

View File

@@ -1,7 +1,7 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="Aaru" type="DotNetProject" factoryName=".NET Project"> <configuration default="false" name="Aaru" type="DotNetProject" factoryName=".NET Project">
<option name="EXE_PATH" value="$PROJECT_DIR$/Aaru/bin/Debug/net6/aaru" /> <option name="EXE_PATH" value="$PROJECT_DIR$/Aaru/bin/Debug/net6/aaru" />
<option name="PROGRAM_PARAMETERS" value="i info &quot;Addams Family Values (Europe) (En,Fr,De).sfc&quot;" /> <option name="PROGRAM_PARAMETERS" value="m dump /dev/sda foo.sfc" />
<option name="WORKING_DIRECTORY" value="$USER_HOME$/Desktop" /> <option name="WORKING_DIRECTORY" value="$USER_HOME$/Desktop" />
<option name="PASS_PARENT_ENVS" value="1" /> <option name="PASS_PARENT_ENVS" value="1" />
<option name="USE_EXTERNAL_CONSOLE" value="0" /> <option name="USE_EXTERNAL_CONSOLE" value="0" />

View File

@@ -71,6 +71,7 @@
<Compile Include="Devices\Dumping\CompactDisc\Tracks.cs" /> <Compile Include="Devices\Dumping\CompactDisc\Tracks.cs" />
<Compile Include="Devices\Dumping\CompactDisc\Trim.cs" /> <Compile Include="Devices\Dumping\CompactDisc\Trim.cs" />
<Compile Include="Devices\Dumping\Dump.cs" /> <Compile Include="Devices\Dumping\Dump.cs" />
<Compile Include="Devices\Dumping\LinearMemory\Retrode.cs" />
<Compile Include="Devices\Dumping\Metadata.cs" /> <Compile Include="Devices\Dumping\Metadata.cs" />
<Compile Include="Devices\Dumping\MiniDisc.cs" /> <Compile Include="Devices\Dumping\MiniDisc.cs" />
<Compile Include="Devices\Dumping\PlayStationPortable\MemoryStick.cs" /> <Compile Include="Devices\Dumping\PlayStationPortable\MemoryStick.cs" />

View File

@@ -57,6 +57,7 @@ namespace Aaru.Core.Devices.Dumping
void Ata() void Ata()
{ {
bool recoveredError; bool recoveredError;
var outputFormat = _outputPlugin as IWritableImage;
if(_dumpRaw) if(_dumpRaw)
{ {
@@ -183,7 +184,7 @@ namespace Aaru.Core.Devices.Dumping
if(_dev.IsUsb && if(_dev.IsUsb &&
_dev.UsbDescriptors != null && _dev.UsbDescriptors != null &&
!_outputPlugin.SupportedMediaTags.Contains(MediaTagType.USB_Descriptors)) !outputFormat.SupportedMediaTags.Contains(MediaTagType.USB_Descriptors))
{ {
ret = false; ret = false;
_dumpLog.WriteLine("Output format does not support USB descriptors."); _dumpLog.WriteLine("Output format does not support USB descriptors.");
@@ -192,14 +193,14 @@ namespace Aaru.Core.Devices.Dumping
if(_dev.IsPcmcia && if(_dev.IsPcmcia &&
_dev.Cis != null && _dev.Cis != null &&
!_outputPlugin.SupportedMediaTags.Contains(MediaTagType.PCMCIA_CIS)) !outputFormat.SupportedMediaTags.Contains(MediaTagType.PCMCIA_CIS))
{ {
ret = false; ret = false;
_dumpLog.WriteLine("Output format does not support PCMCIA CIS descriptors."); _dumpLog.WriteLine("Output format does not support PCMCIA CIS descriptors.");
ErrorMessage("Output format does not support PCMCIA CIS descriptors."); ErrorMessage("Output format does not support PCMCIA CIS descriptors.");
} }
if(!_outputPlugin.SupportedMediaTags.Contains(MediaTagType.ATA_IDENTIFY)) if(!outputFormat.SupportedMediaTags.Contains(MediaTagType.ATA_IDENTIFY))
{ {
ret = false; ret = false;
_dumpLog.WriteLine("Output format does not support ATA IDENTIFY."); _dumpLog.WriteLine("Output format does not support ATA IDENTIFY.");
@@ -223,22 +224,22 @@ namespace Aaru.Core.Devices.Dumping
mediaType = MediaTypeFromDevice.GetFromAta(_dev.Manufacturer, _dev.Model, _dev.IsRemovable, mediaType = MediaTypeFromDevice.GetFromAta(_dev.Manufacturer, _dev.Model, _dev.IsRemovable,
_dev.IsCompactFlash, _dev.IsPcmcia, blocks); _dev.IsCompactFlash, _dev.IsPcmcia, blocks);
ret = _outputPlugin.Create(_outputPath, mediaType, _formatOptions, blocks, blockSize); ret = outputFormat.Create(_outputPath, mediaType, _formatOptions, blocks, blockSize);
// Cannot create image // Cannot create image
if(!ret) if(!ret)
{ {
_dumpLog.WriteLine("Error creating output image, not continuing."); _dumpLog.WriteLine("Error creating output image, not continuing.");
_dumpLog.WriteLine(_outputPlugin.ErrorMessage); _dumpLog.WriteLine(outputFormat.ErrorMessage);
StoppingErrorMessage?.Invoke("Error creating output image, not continuing." + StoppingErrorMessage?.Invoke("Error creating output image, not continuing." +
Environment.NewLine + _outputPlugin.ErrorMessage); Environment.NewLine + outputFormat.ErrorMessage);
return; return;
} }
// Setting geometry // Setting geometry
_outputPlugin.SetGeometry(cylinders, heads, sectors); outputFormat.SetGeometry(cylinders, heads, sectors);
if(ataReader.IsLba) if(ataReader.IsLba)
{ {
@@ -297,7 +298,7 @@ namespace Aaru.Core.Devices.Dumping
mhddLog.Write(i, duration); mhddLog.Write(i, duration);
ibgLog.Write(i, currentSpeed * 1024); ibgLog.Write(i, currentSpeed * 1024);
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
_outputPlugin.WriteSectors(cmdBuf, i, blocksToRead); outputFormat.WriteSectors(cmdBuf, i, blocksToRead);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
extents.Add(i, blocksToRead, true); extents.Add(i, blocksToRead, true);
} }
@@ -313,7 +314,7 @@ namespace Aaru.Core.Devices.Dumping
ibgLog.Write(i, 0); ibgLog.Write(i, 0);
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
_outputPlugin.WriteSectors(new byte[blockSize * _skip], i, _skip); outputFormat.WriteSectors(new byte[blockSize * _skip], i, _skip);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
_dumpLog.WriteLine("Skipping {0} blocks from errored block {1}.", _skip, i); _dumpLog.WriteLine("Skipping {0} blocks from errored block {1}.", _skip, i);
i += _skip - blocksToRead; i += _skip - blocksToRead;
@@ -394,7 +395,7 @@ namespace Aaru.Core.Devices.Dumping
_resume.BadBlocks.Remove(badSector); _resume.BadBlocks.Remove(badSector);
extents.Add(badSector); extents.Add(badSector);
_outputPlugin.WriteSector(cmdBuf, badSector); outputFormat.WriteSector(cmdBuf, badSector);
} }
EndProgress?.Invoke(); EndProgress?.Invoke();
@@ -440,12 +441,12 @@ namespace Aaru.Core.Devices.Dumping
{ {
_resume.BadBlocks.Remove(badSector); _resume.BadBlocks.Remove(badSector);
extents.Add(badSector); extents.Add(badSector);
_outputPlugin.WriteSector(cmdBuf, badSector); outputFormat.WriteSector(cmdBuf, badSector);
UpdateStatus?.Invoke($"Correctly retried block {badSector} in pass {pass}."); UpdateStatus?.Invoke($"Correctly retried block {badSector} in pass {pass}.");
_dumpLog.WriteLine("Correctly retried block {0} in pass {1}.", badSector, pass); _dumpLog.WriteLine("Correctly retried block {0} in pass {1}.", badSector, pass);
} }
else if(_persistent) else if(_persistent)
_outputPlugin.WriteSector(cmdBuf, badSector); outputFormat.WriteSector(cmdBuf, badSector);
} }
if(pass < _retryPasses && if(pass < _retryPasses &&
@@ -519,7 +520,7 @@ namespace Aaru.Core.Devices.Dumping
ibgLog.Write(currentBlock, currentSpeed * 1024); ibgLog.Write(currentBlock, currentSpeed * 1024);
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
_outputPlugin.WriteSector(cmdBuf, outputFormat.WriteSector(cmdBuf,
(ulong)((((cy * heads) + hd) * sectors) + (sc - 1))); (ulong)((((cy * heads) + hd) * sectors) + (sc - 1)));
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
@@ -536,7 +537,7 @@ namespace Aaru.Core.Devices.Dumping
ibgLog.Write(currentBlock, 0); ibgLog.Write(currentBlock, 0);
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
_outputPlugin.WriteSector(new byte[blockSize], outputFormat.WriteSector(new byte[blockSize],
(ulong)((((cy * heads) + hd) * sectors) + (sc - 1))); (ulong)((((cy * heads) + hd) * sectors) + (sc - 1)));
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
@@ -586,7 +587,7 @@ namespace Aaru.Core.Devices.Dumping
foreach(ulong bad in _resume.BadBlocks) foreach(ulong bad in _resume.BadBlocks)
_dumpLog.WriteLine("Sector {0} could not be read.", bad); _dumpLog.WriteLine("Sector {0} could not be read.", bad);
_outputPlugin.SetDumpHardware(_resume.Tries); outputFormat.SetDumpHardware(_resume.Tries);
// TODO: Non-removable // TODO: Non-removable
var metadata = new CommonTypes.Structs.ImageInfo var metadata = new CommonTypes.Structs.ImageInfo
@@ -595,17 +596,17 @@ namespace Aaru.Core.Devices.Dumping
ApplicationVersion = Version.GetVersion() ApplicationVersion = Version.GetVersion()
}; };
if(!_outputPlugin.SetMetadata(metadata)) if(!outputFormat.SetMetadata(metadata))
ErrorMessage?.Invoke("Error {0} setting metadata, continuing..." + Environment.NewLine + ErrorMessage?.Invoke("Error {0} setting metadata, continuing..." + Environment.NewLine +
_outputPlugin.ErrorMessage); outputFormat.ErrorMessage);
if(_preSidecar != null) if(_preSidecar != null)
_outputPlugin.SetCicmMetadata(_preSidecar); outputFormat.SetCicmMetadata(_preSidecar);
_dumpLog.WriteLine("Closing output file."); _dumpLog.WriteLine("Closing output file.");
UpdateStatus?.Invoke("Closing output file."); UpdateStatus?.Invoke("Closing output file.");
DateTime closeStart = DateTime.Now; DateTime closeStart = DateTime.Now;
_outputPlugin.Close(); outputFormat.Close();
DateTime closeEnd = DateTime.Now; DateTime closeEnd = DateTime.Now;
UpdateStatus?.Invoke($"Closed in {(closeEnd - closeStart).TotalSeconds} seconds."); UpdateStatus?.Invoke($"Closed in {(closeEnd - closeStart).TotalSeconds} seconds.");
_dumpLog.WriteLine("Closed in {0} seconds.", (closeEnd - closeStart).TotalSeconds); _dumpLog.WriteLine("Closed in {0} seconds.", (closeEnd - closeStart).TotalSeconds);
@@ -620,15 +621,15 @@ namespace Aaru.Core.Devices.Dumping
double totalChkDuration = 0; double totalChkDuration = 0;
_outputPlugin.WriteMediaTag(ataIdentify, MediaTagType.ATA_IDENTIFY); outputFormat.WriteMediaTag(ataIdentify, MediaTagType.ATA_IDENTIFY);
if(_dev.IsUsb && if(_dev.IsUsb &&
_dev.UsbDescriptors != null) _dev.UsbDescriptors != null)
_outputPlugin.WriteMediaTag(_dev.UsbDescriptors, MediaTagType.USB_Descriptors); outputFormat.WriteMediaTag(_dev.UsbDescriptors, MediaTagType.USB_Descriptors);
if(_dev.IsPcmcia && if(_dev.IsPcmcia &&
_dev.Cis != null) _dev.Cis != null)
_outputPlugin.WriteMediaTag(_dev.Cis, MediaTagType.PCMCIA_CIS); outputFormat.WriteMediaTag(_dev.Cis, MediaTagType.PCMCIA_CIS);
if(_metadata) if(_metadata)
{ {

View File

@@ -163,6 +163,7 @@ namespace Aaru.Core.Devices.Dumping
const uint sectorSize = 2352; // Full sector size const uint sectorSize = 2352; // Full sector size
Track firstTrack = tracks.FirstOrDefault(t => t.Sequence == 1); Track firstTrack = tracks.FirstOrDefault(t => t.Sequence == 1);
uint blocksToRead; // How many sectors to read at once uint blocksToRead; // How many sectors to read at once
var outputOptical = _outputPlugin as IWritableOpticalImage;
if(firstTrack is null) if(firstTrack is null)
return; return;
@@ -264,17 +265,17 @@ namespace Aaru.Core.Devices.Dumping
if(cdiReadyReadAsAudio) if(cdiReadyReadAsAudio)
data = Sector.Scramble(data); data = Sector.Scramble(data);
_outputPlugin.WriteSectorsLong(data, i + r, 1); outputOptical.WriteSectorsLong(data, i + r, 1);
bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel, bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel,
desiredSubchannel, sub, i + r, 1, subLog, isrcs, 1, ref mcn, tracks, desiredSubchannel, sub, i + r, 1, subLog, isrcs, 1, ref mcn, tracks,
subchannelExtents, _fixSubchannelPosition, _outputPlugin, _fixSubchannel, subchannelExtents, _fixSubchannelPosition, outputOptical, _fixSubchannel,
_fixSubchannelCrc, _dumpLog, UpdateStatus, smallestPregapLbaPerTrack, true); _fixSubchannelCrc, _dumpLog, UpdateStatus, smallestPregapLbaPerTrack, true);
// Set tracks and go back // Set tracks and go back
if(indexesChanged) if(indexesChanged)
{ {
(_outputPlugin as IWritableOpticalImage).SetTracks(tracks.ToList()); (outputOptical as IWritableOpticalImage).SetTracks(tracks.ToList());
i -= _maximumReadable; i -= _maximumReadable;
continue; continue;
@@ -282,7 +283,7 @@ namespace Aaru.Core.Devices.Dumping
} }
else else
{ {
_outputPlugin.WriteSectorsLong(cmdBuf, i + r, 1); outputOptical.WriteSectorsLong(cmdBuf, i + r, 1);
} }
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
@@ -349,17 +350,17 @@ namespace Aaru.Core.Devices.Dumping
Array.Copy(cmdBuf, (int)(sectorSize + (b * blockSize)), sub, subSize * b, subSize); Array.Copy(cmdBuf, (int)(sectorSize + (b * blockSize)), sub, subSize * b, subSize);
} }
_outputPlugin.WriteSectorsLong(data, i, blocksToRead); outputOptical.WriteSectorsLong(data, i, blocksToRead);
bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel, bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel,
desiredSubchannel, sub, i, blocksToRead, subLog, isrcs, 1, ref mcn, tracks, desiredSubchannel, sub, i, blocksToRead, subLog, isrcs, 1, ref mcn, tracks,
subchannelExtents, _fixSubchannelPosition, _outputPlugin, _fixSubchannel, subchannelExtents, _fixSubchannelPosition, outputOptical, _fixSubchannel,
_fixSubchannelCrc, _dumpLog, UpdateStatus, smallestPregapLbaPerTrack, true); _fixSubchannelCrc, _dumpLog, UpdateStatus, smallestPregapLbaPerTrack, true);
// Set tracks and go back // Set tracks and go back
if(indexesChanged) if(indexesChanged)
{ {
(_outputPlugin as IWritableOpticalImage).SetTracks(tracks.ToList()); (outputOptical as IWritableOpticalImage).SetTracks(tracks.ToList());
i -= blocksToRead; i -= blocksToRead;
continue; continue;
@@ -379,10 +380,10 @@ namespace Aaru.Core.Devices.Dumping
Array.Copy(tmpData, 0, data, sectorSize * b, sectorSize); Array.Copy(tmpData, 0, data, sectorSize * b, sectorSize);
} }
_outputPlugin.WriteSectorsLong(data, i, blocksToRead); outputOptical.WriteSectorsLong(data, i, blocksToRead);
} }
else else
_outputPlugin.WriteSectorsLong(cmdBuf, i, blocksToRead); outputOptical.WriteSectorsLong(cmdBuf, i, blocksToRead);
} }
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;

View File

@@ -107,6 +107,7 @@ namespace Aaru.Core.Devices.Dumping
const uint sectorSize = 2352; // Full sector size const uint sectorSize = 2352; // Full sector size
newTrim = false; newTrim = false;
PlextorSubchannel supportedPlextorSubchannel; PlextorSubchannel supportedPlextorSubchannel;
var outputFormat = _outputPlugin as IWritableImage;
switch(supportedSubchannel) switch(supportedSubchannel)
{ {
@@ -487,7 +488,7 @@ namespace Aaru.Core.Devices.Dumping
Array.Copy(cmdBuf, sectorSize, sub, 0, subSize); Array.Copy(cmdBuf, sectorSize, sub, 0, subSize);
if(supportsLongSectors) if(supportsLongSectors)
_outputPlugin.WriteSectorsLong(data, i + r, 1); outputFormat.WriteSectorsLong(data, i + r, 1);
else else
{ {
var cooked = new MemoryStream(); var cooked = new MemoryStream();
@@ -500,19 +501,19 @@ namespace Aaru.Core.Devices.Dumping
cooked.Write(cookedSector, 0, cookedSector.Length); cooked.Write(cookedSector, 0, cookedSector.Length);
} }
_outputPlugin.WriteSectors(cooked.ToArray(), i, blocksToRead); outputFormat.WriteSectors(cooked.ToArray(), i, blocksToRead);
} }
bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel, bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel,
desiredSubchannel, sub, i + r, 1, subLog, isrcs, (byte)track.Sequence, desiredSubchannel, sub, i + r, 1, subLog, isrcs, (byte)track.Sequence,
ref mcn, tracks, subchannelExtents, _fixSubchannelPosition, _outputPlugin, ref mcn, tracks, subchannelExtents, _fixSubchannelPosition, outputFormat as IWritableOpticalImage,
_fixSubchannel, _fixSubchannelCrc, _dumpLog, UpdateStatus, _fixSubchannel, _fixSubchannelCrc, _dumpLog, UpdateStatus,
smallestPregapLbaPerTrack, true); smallestPregapLbaPerTrack, true);
// Set tracks and go back // Set tracks and go back
if(indexesChanged) if(indexesChanged)
{ {
(_outputPlugin as IWritableOpticalImage).SetTracks(tracks.ToList()); (outputFormat as IWritableOpticalImage).SetTracks(tracks.ToList());
i -= blocksToRead; i -= blocksToRead;
continue; continue;
@@ -521,7 +522,7 @@ namespace Aaru.Core.Devices.Dumping
else else
{ {
if(supportsLongSectors) if(supportsLongSectors)
_outputPlugin.WriteSectorsLong(cmdBuf, i + r, 1); outputFormat.WriteSectorsLong(cmdBuf, i + r, 1);
else else
{ {
var cooked = new MemoryStream(); var cooked = new MemoryStream();
@@ -534,7 +535,7 @@ namespace Aaru.Core.Devices.Dumping
cooked.Write(cookedSector, 0, cookedSector.Length); cooked.Write(cookedSector, 0, cookedSector.Length);
} }
_outputPlugin.WriteSectors(cooked.ToArray(), i, blocksToRead); outputFormat.WriteSectors(cooked.ToArray(), i, blocksToRead);
} }
} }
@@ -549,22 +550,22 @@ namespace Aaru.Core.Devices.Dumping
if(supportedSubchannel != MmcSubchannel.None) if(supportedSubchannel != MmcSubchannel.None)
{ {
_outputPlugin.WriteSectorsLong(new byte[sectorSize], i + r, 1); outputFormat.WriteSectorsLong(new byte[sectorSize], i + r, 1);
if(desiredSubchannel != MmcSubchannel.None) if(desiredSubchannel != MmcSubchannel.None)
_outputPlugin.WriteSectorsTag(new byte[subSize], i + r, 1, outputFormat.WriteSectorsTag(new byte[subSize], i + r, 1,
SectorTagType.CdSectorSubchannel); SectorTagType.CdSectorSubchannel);
} }
else else
{ {
if(supportsLongSectors) if(supportsLongSectors)
_outputPlugin.WriteSectorsLong(new byte[blockSize], i + r, 1); outputFormat.WriteSectorsLong(new byte[blockSize], i + r, 1);
else else
{ {
if(cmdBuf.Length % sectorSize == 0) if(cmdBuf.Length % sectorSize == 0)
_outputPlugin.WriteSectors(new byte[2048], i + r, 1); outputFormat.WriteSectors(new byte[2048], i + r, 1);
else else
_outputPlugin.WriteSectorsLong(new byte[blockSize], i + r, 1); outputFormat.WriteSectorsLong(new byte[blockSize], i + r, 1);
} }
} }
@@ -631,7 +632,7 @@ namespace Aaru.Core.Devices.Dumping
} }
if(supportsLongSectors) if(supportsLongSectors)
_outputPlugin.WriteSectorsLong(data, i, blocksToRead); outputFormat.WriteSectorsLong(data, i, blocksToRead);
else else
{ {
var cooked = new MemoryStream(); var cooked = new MemoryStream();
@@ -644,19 +645,19 @@ namespace Aaru.Core.Devices.Dumping
cooked.Write(cookedSector, 0, cookedSector.Length); cooked.Write(cookedSector, 0, cookedSector.Length);
} }
_outputPlugin.WriteSectors(cooked.ToArray(), i, blocksToRead); outputFormat.WriteSectors(cooked.ToArray(), i, blocksToRead);
} }
bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel, bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel,
desiredSubchannel, sub, i, blocksToRead, subLog, isrcs, (byte)track.Sequence, desiredSubchannel, sub, i, blocksToRead, subLog, isrcs, (byte)track.Sequence,
ref mcn, tracks, subchannelExtents, _fixSubchannelPosition, _outputPlugin, ref mcn, tracks, subchannelExtents, _fixSubchannelPosition, outputFormat as IWritableOpticalImage,
_fixSubchannel, _fixSubchannelCrc, _dumpLog, UpdateStatus, smallestPregapLbaPerTrack, _fixSubchannel, _fixSubchannelCrc, _dumpLog, UpdateStatus, smallestPregapLbaPerTrack,
true); true);
// Set tracks and go back // Set tracks and go back
if(indexesChanged) if(indexesChanged)
{ {
(_outputPlugin as IWritableOpticalImage).SetTracks(tracks.ToList()); (outputFormat as IWritableOpticalImage).SetTracks(tracks.ToList());
i -= blocksToRead; i -= blocksToRead;
continue; continue;
@@ -665,7 +666,7 @@ namespace Aaru.Core.Devices.Dumping
else else
{ {
if(supportsLongSectors) if(supportsLongSectors)
_outputPlugin.WriteSectorsLong(cmdBuf, i, blocksToRead); outputFormat.WriteSectorsLong(cmdBuf, i, blocksToRead);
else else
{ {
var cooked = new MemoryStream(); var cooked = new MemoryStream();
@@ -678,7 +679,7 @@ namespace Aaru.Core.Devices.Dumping
cooked.Write(cookedSector, 0, cookedSector.Length); cooked.Write(cookedSector, 0, cookedSector.Length);
} }
_outputPlugin.WriteSectors(cooked.ToArray(), i, blocksToRead); outputFormat.WriteSectors(cooked.ToArray(), i, blocksToRead);
} }
} }
@@ -711,24 +712,24 @@ namespace Aaru.Core.Devices.Dumping
if(supportedSubchannel != MmcSubchannel.None) if(supportedSubchannel != MmcSubchannel.None)
{ {
_outputPlugin.WriteSectorsLong(new byte[sectorSize * _skip], i, _skip); outputFormat.WriteSectorsLong(new byte[sectorSize * _skip], i, _skip);
if(desiredSubchannel != MmcSubchannel.None) if(desiredSubchannel != MmcSubchannel.None)
_outputPlugin.WriteSectorsTag(new byte[subSize * _skip], i, _skip, outputFormat.WriteSectorsTag(new byte[subSize * _skip], i, _skip,
SectorTagType.CdSectorSubchannel); SectorTagType.CdSectorSubchannel);
} }
else else
{ {
if(supportsLongSectors) if(supportsLongSectors)
{ {
_outputPlugin.WriteSectorsLong(new byte[blockSize * _skip], i, _skip); outputFormat.WriteSectorsLong(new byte[blockSize * _skip], i, _skip);
} }
else else
{ {
if(cmdBuf.Length % sectorSize == 0) if(cmdBuf.Length % sectorSize == 0)
_outputPlugin.WriteSectors(new byte[2048 * _skip], i, _skip); outputFormat.WriteSectors(new byte[2048 * _skip], i, _skip);
else else
_outputPlugin.WriteSectorsLong(new byte[blockSize * _skip], i, _skip); outputFormat.WriteSectorsLong(new byte[blockSize * _skip], i, _skip);
} }
} }

View File

@@ -117,6 +117,7 @@ namespace Aaru.Core.Devices.Dumping
HashSet<int> subchannelExtents = new(); HashSet<int> subchannelExtents = new();
bool cdiReadyReadAsAudio = false; bool cdiReadyReadAsAudio = false;
uint firstLba; uint firstLba;
var outputOptical = _outputPlugin as IWritableOpticalImage;
Dictionary<MediaTagType, byte[]> mediaTags = new(); // Media tags Dictionary<MediaTagType, byte[]> mediaTags = new(); // Media tags
Dictionary<byte, int> smallestPregapLbaPerTrack = new(); Dictionary<byte, int> smallestPregapLbaPerTrack = new();
@@ -221,7 +222,7 @@ namespace Aaru.Core.Devices.Dumping
supportedSubchannel = MmcSubchannel.Q16; supportedSubchannel = MmcSubchannel.Q16;
// Check if output format supports subchannels // Check if output format supports subchannels
if(!_outputPlugin.SupportedSectorTags.Contains(SectorTagType.CdSectorSubchannel) && if(!outputOptical.SupportedSectorTags.Contains(SectorTagType.CdSectorSubchannel) &&
desiredSubchannel != MmcSubchannel.None) desiredSubchannel != MmcSubchannel.None)
{ {
if(_force || _subchannel == DumpSubchannel.None) if(_force || _subchannel == DumpSubchannel.None)
@@ -416,7 +417,7 @@ namespace Aaru.Core.Devices.Dumping
Invoke("WARNING: The drive has returned incorrect Q positioning when calculating pregaps. A best effort has been tried but they may be incorrect."); Invoke("WARNING: The drive has returned incorrect Q positioning when calculating pregaps. A best effort has been tried but they may be incorrect.");
} }
if(!(_outputPlugin as IWritableOpticalImage).OpticalCapabilities.HasFlag(OpticalImageCapabilities. if(!(outputOptical as IWritableOpticalImage).OpticalCapabilities.HasFlag(OpticalImageCapabilities.
CanStoreRawData)) CanStoreRawData))
{ {
if(!_force) if(!_force)
@@ -435,7 +436,7 @@ namespace Aaru.Core.Devices.Dumping
Invoke("Output format does not support storing raw data, this may end in a loss of data, continuing..."); Invoke("Output format does not support storing raw data, this may end in a loss of data, continuing...");
} }
if(!(_outputPlugin as IWritableOpticalImage).OpticalCapabilities.HasFlag(OpticalImageCapabilities. if(!(outputOptical as IWritableOpticalImage).OpticalCapabilities.HasFlag(OpticalImageCapabilities.
CanStoreAudioTracks) && CanStoreAudioTracks) &&
tracks.Any(track => track.Type == TrackType.Audio)) tracks.Any(track => track.Type == TrackType.Audio))
{ {
@@ -446,7 +447,7 @@ namespace Aaru.Core.Devices.Dumping
return; return;
} }
if(!(_outputPlugin as IWritableOpticalImage).OpticalCapabilities.HasFlag(OpticalImageCapabilities. if(!(outputOptical as IWritableOpticalImage).OpticalCapabilities.HasFlag(OpticalImageCapabilities.
CanStorePregaps) && CanStorePregaps) &&
tracks.Where(track => track.Sequence != tracks.First(t => t.Session == track.Session).Sequence). tracks.Where(track => track.Sequence != tracks.First(t => t.Session == track.Session).Sequence).
Any(track => track.Pregap > 0)) Any(track => track.Pregap > 0))
@@ -494,7 +495,7 @@ namespace Aaru.Core.Devices.Dumping
// Read media tags // Read media tags
ReadCdTags(ref dskType, mediaTags, out sessions, out firstTrackLastSession); ReadCdTags(ref dskType, mediaTags, out sessions, out firstTrackLastSession);
if(!(_outputPlugin as IWritableOpticalImage).OpticalCapabilities.HasFlag(OpticalImageCapabilities. if(!(outputOptical as IWritableOpticalImage).OpticalCapabilities.HasFlag(OpticalImageCapabilities.
CanStoreSessions) && CanStoreSessions) &&
sessions > 1) sessions > 1)
{ {
@@ -516,7 +517,7 @@ namespace Aaru.Core.Devices.Dumping
} }
// Check if output format supports all disc tags we have retrieved so far // Check if output format supports all disc tags we have retrieved so far
foreach(MediaTagType tag in mediaTags.Keys.Where(tag => !_outputPlugin.SupportedMediaTags.Contains(tag))) foreach(MediaTagType tag in mediaTags.Keys.Where(tag => !outputOptical.SupportedMediaTags.Contains(tag)))
{ {
if(_force) if(_force)
{ {
@@ -687,7 +688,7 @@ namespace Aaru.Core.Devices.Dumping
} }
} }
if(_outputPlugin.Id == new Guid("12345678-AAAA-BBBB-CCCC-123456789000")) if(outputOptical.Id == new Guid("12345678-AAAA-BBBB-CCCC-123456789000"))
{ {
if(tracks.Length > 1) if(tracks.Length > 1)
{ {
@@ -719,7 +720,7 @@ namespace Aaru.Core.Devices.Dumping
// Check if something prevents from dumping the first track pregap // Check if something prevents from dumping the first track pregap
if(_dumpFirstTrackPregap && readcd) if(_dumpFirstTrackPregap && readcd)
{ {
if(!_outputPlugin.SupportedMediaTags.Contains(MediaTagType.CD_FirstTrackPregap)) if(!outputOptical.SupportedMediaTags.Contains(MediaTagType.CD_FirstTrackPregap))
{ {
if(_force) if(_force)
{ {
@@ -814,30 +815,30 @@ namespace Aaru.Core.Devices.Dumping
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}.");
ret = _outputPlugin.Create(_outputPath, dskType, _formatOptions, blocks, ret = outputOptical.Create(_outputPath, dskType, _formatOptions, blocks,
supportsLongSectors ? blockSize : 2048); supportsLongSectors ? blockSize : 2048);
// Cannot create image // Cannot create image
if(!ret) if(!ret)
{ {
_dumpLog.WriteLine("Error creating output image, not continuing."); _dumpLog.WriteLine("Error creating output image, not continuing.");
_dumpLog.WriteLine(_outputPlugin.ErrorMessage); _dumpLog.WriteLine(outputOptical.ErrorMessage);
StoppingErrorMessage?.Invoke("Error creating output image, not continuing." + Environment.NewLine + StoppingErrorMessage?.Invoke("Error creating output image, not continuing." + Environment.NewLine +
_outputPlugin.ErrorMessage); outputOptical.ErrorMessage);
return; return;
} }
ErrorNumber errno = _outputPlugin.ReadMediaTag(MediaTagType.CD_MCN, out byte[] mcnBytes); ErrorNumber errno = outputOptical.ReadMediaTag(MediaTagType.CD_MCN, out byte[] mcnBytes);
if(errno == ErrorNumber.NoError) if(errno == ErrorNumber.NoError)
mcn = Encoding.ASCII.GetString(mcnBytes); mcn = Encoding.ASCII.GetString(mcnBytes);
if((_outputPlugin as IWritableOpticalImage).Tracks != null) if((outputOptical as IWritableOpticalImage).Tracks != null)
foreach(Track imgTrack in (_outputPlugin as IWritableOpticalImage).Tracks) foreach(Track imgTrack in (outputOptical as IWritableOpticalImage).Tracks)
{ {
errno = (_outputPlugin as IWritableOpticalImage).ReadSectorTag(imgTrack.Sequence, errno = (outputOptical as IWritableOpticalImage).ReadSectorTag(imgTrack.Sequence,
SectorTagType.CdTrackIsrc, out byte[] isrcBytes); SectorTagType.CdTrackIsrc, out byte[] isrcBytes);
if(errno == ErrorNumber.NoError) if(errno == ErrorNumber.NoError)
@@ -857,23 +858,23 @@ namespace Aaru.Core.Devices.Dumping
} }
// Send track list to output plugin. This may fail if subchannel is set but unsupported. // Send track list to output plugin. This may fail if subchannel is set but unsupported.
ret = (_outputPlugin as IWritableOpticalImage).SetTracks(tracks.ToList()); ret = (outputOptical as IWritableOpticalImage).SetTracks(tracks.ToList());
if(!ret && if(!ret &&
desiredSubchannel == MmcSubchannel.None) desiredSubchannel == MmcSubchannel.None)
{ {
_dumpLog.WriteLine("Error sending tracks to output image, not continuing."); _dumpLog.WriteLine("Error sending tracks to output image, not continuing.");
_dumpLog.WriteLine(_outputPlugin.ErrorMessage); _dumpLog.WriteLine(outputOptical.ErrorMessage);
StoppingErrorMessage?.Invoke("Error sending tracks to output image, not continuing." + StoppingErrorMessage?.Invoke("Error sending tracks to output image, not continuing." +
Environment.NewLine + _outputPlugin.ErrorMessage); Environment.NewLine + outputOptical.ErrorMessage);
return; return;
} }
// If a subchannel is supported, check if output plugin allows us to write it. // If a subchannel is supported, check if output plugin allows us to write it.
if(desiredSubchannel != MmcSubchannel.None && if(desiredSubchannel != MmcSubchannel.None &&
!(_outputPlugin as IWritableOpticalImage).OpticalCapabilities.HasFlag(OpticalImageCapabilities. !(outputOptical as IWritableOpticalImage).OpticalCapabilities.HasFlag(OpticalImageCapabilities.
CanStoreSubchannelRw)) CanStoreSubchannelRw))
{ {
_dumpLog.WriteLine("Output image does not support subchannels, {0}continuing...", _force ? "" : "not "); _dumpLog.WriteLine("Output image does not support subchannels, {0}continuing...", _force ? "" : "not ");
@@ -905,7 +906,7 @@ namespace Aaru.Core.Devices.Dumping
_dumpLog.WriteLine("Setting flags for track {0}...", track.Sequence); _dumpLog.WriteLine("Setting flags for track {0}...", track.Sequence);
UpdateStatus?.Invoke($"Setting flags for track {track.Sequence}..."); UpdateStatus?.Invoke($"Setting flags for track {track.Sequence}...");
_outputPlugin.WriteSectorTag(new[] outputOptical.WriteSectorTag(new[]
{ {
kvp.Value kvp.Value
}, kvp.Key, SectorTagType.CdTrackFlags); }, kvp.Key, SectorTagType.CdTrackFlags);
@@ -1282,14 +1283,14 @@ namespace Aaru.Core.Devices.Dumping
continue; continue;
} }
ret = _outputPlugin.WriteMediaTag(tag.Value, tag.Key); ret = outputOptical.WriteMediaTag(tag.Value, tag.Key);
if(ret || _force) if(ret || _force)
continue; continue;
// Cannot write tag to image // Cannot write tag to image
_dumpLog.WriteLine($"Cannot write tag {tag.Key}."); _dumpLog.WriteLine($"Cannot write tag {tag.Key}.");
StoppingErrorMessage?.Invoke(_outputPlugin.ErrorMessage); StoppingErrorMessage?.Invoke(outputOptical.ErrorMessage);
return; return;
} }
@@ -1306,10 +1307,10 @@ namespace Aaru.Core.Devices.Dumping
_resume.BadSubchannels.Sort(); _resume.BadSubchannels.Sort();
if(_generateSubchannels && if(_generateSubchannels &&
_outputPlugin.SupportedSectorTags.Contains(SectorTagType.CdSectorSubchannel) && outputOptical.SupportedSectorTags.Contains(SectorTagType.CdSectorSubchannel) &&
!_aborted) !_aborted)
Media.CompactDisc.GenerateSubchannels(subchannelExtents, tracks, trackFlags, blocks, subLog, _dumpLog, Media.CompactDisc.GenerateSubchannels(subchannelExtents, tracks, trackFlags, blocks, subLog, _dumpLog,
InitProgress, UpdateProgress, EndProgress, _outputPlugin); InitProgress, UpdateProgress, EndProgress, outputOptical);
// TODO: Disc ID // TODO: Disc ID
var metadata = new CommonTypes.Structs.ImageInfo var metadata = new CommonTypes.Structs.ImageInfo
@@ -1318,19 +1319,19 @@ namespace Aaru.Core.Devices.Dumping
ApplicationVersion = Version.GetVersion() ApplicationVersion = Version.GetVersion()
}; };
if(!_outputPlugin.SetMetadata(metadata)) if(!outputOptical.SetMetadata(metadata))
ErrorMessage?.Invoke("Error {0} setting metadata, continuing..." + Environment.NewLine + ErrorMessage?.Invoke("Error {0} setting metadata, continuing..." + Environment.NewLine +
_outputPlugin.ErrorMessage); outputOptical.ErrorMessage);
_outputPlugin.SetDumpHardware(_resume.Tries); outputOptical.SetDumpHardware(_resume.Tries);
if(_preSidecar != null) if(_preSidecar != null)
_outputPlugin.SetCicmMetadata(_preSidecar); outputOptical.SetCicmMetadata(_preSidecar);
foreach(KeyValuePair<byte, string> isrc in isrcs) foreach(KeyValuePair<byte, string> isrc in isrcs)
{ {
// TODO: Track tags // TODO: Track tags
if(!_outputPlugin.WriteSectorTag(Encoding.ASCII.GetBytes(isrc.Value), isrc.Key, if(!outputOptical.WriteSectorTag(Encoding.ASCII.GetBytes(isrc.Value), isrc.Key,
SectorTagType.CdTrackIsrc)) SectorTagType.CdTrackIsrc))
continue; continue;
@@ -1339,7 +1340,7 @@ namespace Aaru.Core.Devices.Dumping
} }
if(mcn != null && if(mcn != null &&
_outputPlugin.WriteMediaTag(Encoding.ASCII.GetBytes(mcn), MediaTagType.CD_MCN)) outputOptical.WriteMediaTag(Encoding.ASCII.GetBytes(mcn), MediaTagType.CD_MCN))
{ {
UpdateStatus?.Invoke($"Setting disc Media Catalogue Number to {mcn}"); UpdateStatus?.Invoke($"Setting disc Media Catalogue Number to {mcn}");
_dumpLog.WriteLine("Setting disc Media Catalogue Number to {0}", mcn); _dumpLog.WriteLine("Setting disc Media Catalogue Number to {0}", mcn);
@@ -1366,12 +1367,12 @@ namespace Aaru.Core.Devices.Dumping
trk.Indexes.Remove(0); trk.Indexes.Remove(0);
} }
(_outputPlugin as IWritableOpticalImage).SetTracks(tracks.ToList()); (outputOptical as IWritableOpticalImage).SetTracks(tracks.ToList());
_dumpLog.WriteLine("Closing output file."); _dumpLog.WriteLine("Closing output file.");
UpdateStatus?.Invoke("Closing output file."); UpdateStatus?.Invoke("Closing output file.");
DateTime closeStart = DateTime.Now; DateTime closeStart = DateTime.Now;
_outputPlugin.Close(); outputOptical.Close();
DateTime closeEnd = DateTime.Now; DateTime closeEnd = DateTime.Now;
UpdateStatus?.Invoke($"Closed in {(closeEnd - closeStart).TotalSeconds} seconds."); UpdateStatus?.Invoke($"Closed in {(closeEnd - closeStart).TotalSeconds} seconds.");

View File

@@ -85,6 +85,7 @@ namespace Aaru.Core.Devices.Dumping
const uint sectorSize = 2352; // Full sector size const uint sectorSize = 2352; // Full sector size
byte[] senseBuf = null; // Sense buffer byte[] senseBuf = null; // Sense buffer
PlextorSubchannel supportedPlextorSubchannel; PlextorSubchannel supportedPlextorSubchannel;
var outputOptical = _outputPlugin as IWritableOpticalImage;
switch(supportedSubchannel) switch(supportedSubchannel)
{ {
@@ -360,28 +361,28 @@ namespace Aaru.Core.Devices.Dumping
Array.Copy(cmdBuf, sectorSize, sub, 0, subSize); Array.Copy(cmdBuf, sectorSize, sub, 0, subSize);
if(supportsLongSectors) if(supportsLongSectors)
_outputPlugin.WriteSectorLong(data, badSector); outputOptical.WriteSectorLong(data, badSector);
else else
_outputPlugin.WriteSector(Sector.GetUserData(data), badSector); outputOptical.WriteSector(Sector.GetUserData(data), badSector);
bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel, bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel,
desiredSubchannel, sub, badSector, 1, subLog, isrcs, (byte)track.Sequence, ref mcn, desiredSubchannel, sub, badSector, 1, subLog, isrcs, (byte)track.Sequence, ref mcn,
tracks, subchannelExtents, _fixSubchannelPosition, _outputPlugin, _fixSubchannel, tracks, subchannelExtents, _fixSubchannelPosition, outputOptical, _fixSubchannel,
_fixSubchannelCrc, _dumpLog, UpdateStatus, smallestPregapLbaPerTrack, true); _fixSubchannelCrc, _dumpLog, UpdateStatus, smallestPregapLbaPerTrack, true);
// Set tracks and go back // Set tracks and go back
if(!indexesChanged) if(!indexesChanged)
continue; continue;
(_outputPlugin as IWritableOpticalImage).SetTracks(tracks.ToList()); (outputOptical as IWritableOpticalImage).SetTracks(tracks.ToList());
i--; i--;
} }
else else
{ {
if(supportsLongSectors) if(supportsLongSectors)
_outputPlugin.WriteSectorLong(cmdBuf, badSector); outputOptical.WriteSectorLong(cmdBuf, badSector);
else else
_outputPlugin.WriteSector(Sector.GetUserData(cmdBuf), badSector); outputOptical.WriteSector(Sector.GetUserData(cmdBuf), badSector);
} }
} }
@@ -491,29 +492,29 @@ namespace Aaru.Core.Devices.Dumping
Array.Copy(cmdBuf, sectorSize, sub, 0, subSize); Array.Copy(cmdBuf, sectorSize, sub, 0, subSize);
if(supportsLongSectors) if(supportsLongSectors)
_outputPlugin.WriteSectorLong(data, badSector); outputOptical.WriteSectorLong(data, badSector);
else else
_outputPlugin.WriteSector(Sector.GetUserData(data), badSector); outputOptical.WriteSector(Sector.GetUserData(data), badSector);
bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel, bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel,
desiredSubchannel, sub, badSector, 1, subLog, isrcs, (byte)track.Sequence, desiredSubchannel, sub, badSector, 1, subLog, isrcs, (byte)track.Sequence,
ref mcn, tracks, subchannelExtents, _fixSubchannelPosition, _outputPlugin, ref mcn, tracks, subchannelExtents, _fixSubchannelPosition, outputOptical,
_fixSubchannel, _fixSubchannelCrc, _dumpLog, UpdateStatus, _fixSubchannel, _fixSubchannelCrc, _dumpLog, UpdateStatus,
smallestPregapLbaPerTrack, true); smallestPregapLbaPerTrack, true);
// Set tracks and go back // Set tracks and go back
if(indexesChanged) if(indexesChanged)
{ {
(_outputPlugin as IWritableOpticalImage).SetTracks(tracks.ToList()); (outputOptical as IWritableOpticalImage).SetTracks(tracks.ToList());
i--; i--;
} }
} }
else else
{ {
if(supportsLongSectors) if(supportsLongSectors)
_outputPlugin.WriteSectorLong(cmdBuf, badSector); outputOptical.WriteSectorLong(cmdBuf, badSector);
else else
_outputPlugin.WriteSector(Sector.GetUserData(cmdBuf), badSector); outputOptical.WriteSector(Sector.GetUserData(cmdBuf), badSector);
} }
} }
@@ -567,6 +568,7 @@ namespace Aaru.Core.Devices.Dumping
double cmdDuration; // Command execution time double cmdDuration; // Command execution time
byte[] senseBuf = null; // Sense buffer byte[] senseBuf = null; // Sense buffer
PlextorSubchannel supportedPlextorSubchannel; PlextorSubchannel supportedPlextorSubchannel;
var outputOptical = _outputPlugin as IWritableOpticalImage;
if(supportedSubchannel == MmcSubchannel.None || if(supportedSubchannel == MmcSubchannel.None ||
desiredSubchannel == MmcSubchannel.None) desiredSubchannel == MmcSubchannel.None)
@@ -660,7 +662,7 @@ namespace Aaru.Core.Devices.Dumping
Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, cmdBuf, badSector, 5, Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, cmdBuf, badSector, 5,
subLog, isrcs, (byte)track.Sequence, ref mcn, tracks, subLog, isrcs, (byte)track.Sequence, ref mcn, tracks,
subchannelExtents, _fixSubchannelPosition, _outputPlugin, subchannelExtents, _fixSubchannelPosition, outputOptical,
_fixSubchannel, _fixSubchannelCrc, _dumpLog, UpdateStatus, _fixSubchannel, _fixSubchannelCrc, _dumpLog, UpdateStatus,
smallestPregapLbaPerTrack, true); smallestPregapLbaPerTrack, true);

View File

@@ -83,10 +83,11 @@ namespace Aaru.Core.Devices.Dumping
Dictionary<byte, string> isrcs, ref string mcn, Track[] tracks, Dictionary<byte, string> isrcs, ref string mcn, Track[] tracks,
HashSet<int> subchannelExtents, Dictionary<byte, int> smallestPregapLbaPerTrack) HashSet<int> subchannelExtents, Dictionary<byte, int> smallestPregapLbaPerTrack)
{ {
byte[] cmdBuf = null; // Data buffer byte[] cmdBuf = null; // Data buffer
const uint sectorSize = 2352; // Full sector size const uint sectorSize = 2352; // Full sector size
bool sense = true; // Sense indicator bool sense = true; // Sense indicator
byte[] senseBuf = null; byte[] senseBuf = null;
var outputOptical = _outputPlugin as IWritableOpticalImage;
UpdateStatus?.Invoke("Reading lead-outs"); UpdateStatus?.Invoke("Reading lead-outs");
_dumpLog.WriteLine("Reading lead-outs"); _dumpLog.WriteLine("Reading lead-outs");
@@ -158,24 +159,24 @@ namespace Aaru.Core.Devices.Dumping
Array.Copy(cmdBuf, (int)(sectorSize + (b * blockSize)), sub, subSize * b, subSize); Array.Copy(cmdBuf, (int)(sectorSize + (b * blockSize)), sub, subSize * b, subSize);
} }
_outputPlugin.WriteSectorsLong(data, i, _maximumReadable); outputOptical.WriteSectorsLong(data, i, _maximumReadable);
bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel, bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel,
desiredSubchannel, sub, i, _maximumReadable, subLog, isrcs, 0xAA, ref mcn, tracks, desiredSubchannel, sub, i, _maximumReadable, subLog, isrcs, 0xAA, ref mcn, tracks,
subchannelExtents, _fixSubchannelPosition, _outputPlugin, _fixSubchannel, subchannelExtents, _fixSubchannelPosition, outputOptical, _fixSubchannel,
_fixSubchannelCrc, _dumpLog, UpdateStatus, smallestPregapLbaPerTrack, true); _fixSubchannelCrc, _dumpLog, UpdateStatus, smallestPregapLbaPerTrack, true);
// Set tracks and go back // Set tracks and go back
if(indexesChanged) if(indexesChanged)
{ {
(_outputPlugin as IWritableOpticalImage).SetTracks(tracks.ToList()); (outputOptical as IWritableOpticalImage).SetTracks(tracks.ToList());
i--; i--;
continue; continue;
} }
} }
else else
_outputPlugin.WriteSectors(cmdBuf, i, _maximumReadable); outputOptical.WriteSectors(cmdBuf, i, _maximumReadable);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
} }
@@ -192,13 +193,13 @@ namespace Aaru.Core.Devices.Dumping
if(supportedSubchannel != MmcSubchannel.None) if(supportedSubchannel != MmcSubchannel.None)
{ {
_outputPlugin.WriteSectorsLong(new byte[sectorSize * _skip], i, 1); outputOptical.WriteSectorsLong(new byte[sectorSize * _skip], i, 1);
_outputPlugin.WriteSectorsTag(new byte[subSize * _skip], i, 1, outputOptical.WriteSectorsTag(new byte[subSize * _skip], i, 1,
SectorTagType.CdSectorSubchannel); SectorTagType.CdSectorSubchannel);
} }
else else
_outputPlugin.WriteSectors(new byte[blockSize * _skip], i, 1); outputOptical.WriteSectors(new byte[blockSize * _skip], i, 1);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
@@ -252,10 +253,11 @@ namespace Aaru.Core.Devices.Dumping
Dictionary<byte, string> isrcs, ref string mcn, Track[] tracks, Dictionary<byte, string> isrcs, ref string mcn, Track[] tracks,
HashSet<int> subchannelExtents, Dictionary<byte, int> smallestPregapLbaPerTrack) HashSet<int> subchannelExtents, Dictionary<byte, int> smallestPregapLbaPerTrack)
{ {
byte[] cmdBuf = null; // Data buffer byte[] cmdBuf = null; // Data buffer
const uint sectorSize = 2352; // Full sector size const uint sectorSize = 2352; // Full sector size
bool sense = true; // Sense indicator bool sense = true; // Sense indicator
byte[] senseBuf = null; byte[] senseBuf = null;
var outputOptical = _outputPlugin as IWritableOpticalImage;
_dumpLog.WriteLine("Retrying lead-outs"); _dumpLog.WriteLine("Retrying lead-outs");
@@ -326,24 +328,24 @@ namespace Aaru.Core.Devices.Dumping
Array.Copy(cmdBuf, (int)(sectorSize + (b * blockSize)), sub, subSize * b, subSize); Array.Copy(cmdBuf, (int)(sectorSize + (b * blockSize)), sub, subSize * b, subSize);
} }
_outputPlugin.WriteSectorsLong(data, i, _maximumReadable); outputOptical.WriteSectorsLong(data, i, _maximumReadable);
bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel, bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel,
desiredSubchannel, sub, i, _maximumReadable, subLog, isrcs, 0xAA, ref mcn, tracks, desiredSubchannel, sub, i, _maximumReadable, subLog, isrcs, 0xAA, ref mcn, tracks,
subchannelExtents, _fixSubchannelPosition, _outputPlugin, _fixSubchannel, subchannelExtents, _fixSubchannelPosition, outputOptical, _fixSubchannel,
_fixSubchannelCrc, _dumpLog, UpdateStatus, smallestPregapLbaPerTrack, true); _fixSubchannelCrc, _dumpLog, UpdateStatus, smallestPregapLbaPerTrack, true);
// Set tracks and go back // Set tracks and go back
if(indexesChanged) if(indexesChanged)
{ {
(_outputPlugin as IWritableOpticalImage).SetTracks(tracks.ToList()); (outputOptical as IWritableOpticalImage).SetTracks(tracks.ToList());
i--; i--;
continue; continue;
} }
} }
else else
_outputPlugin.WriteSectors(cmdBuf, i, _maximumReadable); outputOptical.WriteSectors(cmdBuf, i, _maximumReadable);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
} }
@@ -360,14 +362,14 @@ namespace Aaru.Core.Devices.Dumping
if(supportedSubchannel != MmcSubchannel.None) if(supportedSubchannel != MmcSubchannel.None)
{ {
_outputPlugin.WriteSectorsLong(new byte[sectorSize * _skip], i, 1); outputOptical.WriteSectorsLong(new byte[sectorSize * _skip], i, 1);
if(desiredSubchannel != MmcSubchannel.None) if(desiredSubchannel != MmcSubchannel.None)
_outputPlugin.WriteSectorsTag(new byte[subSize * _skip], i, 1, outputOptical.WriteSectorsTag(new byte[subSize * _skip], i, 1,
SectorTagType.CdSectorSubchannel); SectorTagType.CdSectorSubchannel);
} }
else else
_outputPlugin.WriteSectors(new byte[blockSize * _skip], i, 1); outputOptical.WriteSectors(new byte[blockSize * _skip], i, 1);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;

View File

@@ -89,7 +89,8 @@ namespace Aaru.Core.Devices.Dumping
double cmdDuration = 0; // Command execution time double cmdDuration = 0; // Command execution time
const uint sectorSize = 2352; // Full sector size const uint sectorSize = 2352; // Full sector size
PlextorSubchannel supportedPlextorSubchannel; PlextorSubchannel supportedPlextorSubchannel;
byte[] senseBuf = null; byte[] senseBuf = null;
var outputOptical = _outputPlugin as IWritableOpticalImage;
switch(supportedSubchannel) switch(supportedSubchannel)
{ {
@@ -262,22 +263,22 @@ namespace Aaru.Core.Devices.Dumping
Array.Copy(cmdBuf, sectorSize, sub, 0, subSize); Array.Copy(cmdBuf, sectorSize, sub, 0, subSize);
if(supportsLongSectors) if(supportsLongSectors)
_outputPlugin.WriteSectorLong(data, badSector); outputOptical.WriteSectorLong(data, badSector);
else else
_outputPlugin.WriteSector(Sector.GetUserData(data), badSector); outputOptical.WriteSector(Sector.GetUserData(data), badSector);
ulong trkStartBefore = track.StartSector; ulong trkStartBefore = track.StartSector;
bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel, bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel,
desiredSubchannel, sub, badSector, 1, subLog, isrcs, (byte)track.Sequence, ref mcn, desiredSubchannel, sub, badSector, 1, subLog, isrcs, (byte)track.Sequence, ref mcn,
tracks, subchannelExtents, _fixSubchannelPosition, _outputPlugin, _fixSubchannel, tracks, subchannelExtents, _fixSubchannelPosition, outputOptical, _fixSubchannel,
_fixSubchannelCrc, _dumpLog, UpdateStatus, smallestPregapLbaPerTrack, true); _fixSubchannelCrc, _dumpLog, UpdateStatus, smallestPregapLbaPerTrack, true);
// Set tracks and go back // Set tracks and go back
if(!indexesChanged) if(!indexesChanged)
continue; continue;
(_outputPlugin as IWritableOpticalImage).SetTracks(tracks.ToList()); (outputOptical as IWritableOpticalImage).SetTracks(tracks.ToList());
if(track.StartSector != trkStartBefore && if(track.StartSector != trkStartBefore &&
!_resume.BadBlocks.Contains(track.StartSector)) !_resume.BadBlocks.Contains(track.StartSector))
@@ -293,9 +294,9 @@ namespace Aaru.Core.Devices.Dumping
} }
if(supportsLongSectors) if(supportsLongSectors)
_outputPlugin.WriteSectorLong(cmdBuf, badSector); outputOptical.WriteSectorLong(cmdBuf, badSector);
else else
_outputPlugin.WriteSector(Sector.GetUserData(cmdBuf), badSector); outputOptical.WriteSector(Sector.GetUserData(cmdBuf), badSector);
} }
EndProgress?.Invoke(); EndProgress?.Invoke();

View File

@@ -81,7 +81,7 @@ namespace Aaru.Core.Devices.Dumping
readonly bool _generateSubchannels; readonly bool _generateSubchannels;
readonly bool _metadata; readonly bool _metadata;
readonly string _outputPath; readonly string _outputPath;
readonly IWritableImage _outputPlugin; readonly IBaseWritableImage _outputPlugin;
readonly string _outputPrefix; readonly string _outputPrefix;
readonly bool _persistent; readonly bool _persistent;
readonly CICMMetadataType _preSidecar; readonly CICMMetadataType _preSidecar;
@@ -148,7 +148,7 @@ namespace Aaru.Core.Devices.Dumping
/// </param> /// </param>
/// <param name="storeEncrypted">Store encrypted data as is</param> /// <param name="storeEncrypted">Store encrypted data as is</param>
/// <param name="titleKeys">Dump DVD CSS title keys</param> /// <param name="titleKeys">Dump DVD CSS title keys</param>
public Dump(bool doResume, Device dev, string devicePath, IWritableImage outputPlugin, ushort retryPasses, public Dump(bool doResume, Device dev, string devicePath, IBaseWritableImage outputPlugin, ushort retryPasses,
bool force, bool dumpRaw, bool persistent, bool stopOnError, Resume resume, DumpLog dumpLog, bool force, bool dumpRaw, bool persistent, bool stopOnError, Resume resume, DumpLog dumpLog,
Encoding encoding, string outputPrefix, string outputPath, Dictionary<string, string> formatOptions, Encoding encoding, string outputPrefix, string outputPath, Dictionary<string, string> formatOptions,
CICMMetadataType preSidecar, uint skip, bool metadata, bool trim, bool dumpFirstTrackPregap, CICMMetadataType preSidecar, uint skip, bool metadata, bool trim, bool dumpFirstTrackPregap,

View File

@@ -72,6 +72,7 @@ namespace Aaru.Core.Devices.Dumping
Dictionary<MediaTagType, byte[]> mediaTags = new(); Dictionary<MediaTagType, byte[]> mediaTags = new();
byte[] cmdBuf; byte[] cmdBuf;
bool ret; bool ret;
var outputFormat = _outputPlugin as IWritableImage;
_dumpLog.WriteLine("Initializing reader."); _dumpLog.WriteLine("Initializing reader.");
var scsiReader = new Reader(_dev, _dev.Timeout, null, _errorLog); var scsiReader = new Reader(_dev, _dev.Timeout, null, _errorLog);
@@ -208,7 +209,7 @@ namespace Aaru.Core.Devices.Dumping
ret = true; ret = true;
foreach(MediaTagType tag in mediaTags.Keys.Where(tag => !_outputPlugin.SupportedMediaTags.Contains(tag))) foreach(MediaTagType tag in mediaTags.Keys.Where(tag => !outputFormat.SupportedMediaTags.Contains(tag)))
{ {
ret = false; ret = false;
_dumpLog.WriteLine($"Output format does not support {tag}."); _dumpLog.WriteLine($"Output format does not support {tag}.");
@@ -236,16 +237,16 @@ namespace Aaru.Core.Devices.Dumping
var mhddLog = new MhddLog(_outputPrefix + ".mhddlog.bin", _dev, blocks, blockSize, blocksToRead, _private); var mhddLog = new MhddLog(_outputPrefix + ".mhddlog.bin", _dev, blocks, blockSize, blocksToRead, _private);
var ibgLog = new IbgLog(_outputPrefix + ".ibg", sbcProfile); var ibgLog = new IbgLog(_outputPrefix + ".ibg", sbcProfile);
ret = _outputPlugin.Create(_outputPath, dskType, _formatOptions, blocks, blockSize); ret = outputFormat.Create(_outputPath, dskType, _formatOptions, blocks, blockSize);
// Cannot create image // Cannot create image
if(!ret) if(!ret)
{ {
_dumpLog.WriteLine("Error creating output image, not continuing."); _dumpLog.WriteLine("Error creating output image, not continuing.");
_dumpLog.WriteLine(_outputPlugin.ErrorMessage); _dumpLog.WriteLine(outputFormat.ErrorMessage);
StoppingErrorMessage?.Invoke("Error creating output image, not continuing." + Environment.NewLine + StoppingErrorMessage?.Invoke("Error creating output image, not continuing." + Environment.NewLine +
_outputPlugin.ErrorMessage); outputFormat.ErrorMessage);
return; return;
} }
@@ -273,7 +274,7 @@ namespace Aaru.Core.Devices.Dumping
UpdateStatus?. UpdateStatus?.
Invoke($"Setting geometry to {rigidPage.Value.Cylinders} cylinders, {rigidPage.Value.Heads} heads, {(uint)(blocks / (rigidPage.Value.Cylinders * rigidPage.Value.Heads))} sectors per track"); Invoke($"Setting geometry to {rigidPage.Value.Cylinders} cylinders, {rigidPage.Value.Heads} heads, {(uint)(blocks / (rigidPage.Value.Cylinders * rigidPage.Value.Heads))} sectors per track");
_outputPlugin.SetGeometry(rigidPage.Value.Cylinders, rigidPage.Value.Heads, outputFormat.SetGeometry(rigidPage.Value.Cylinders, rigidPage.Value.Heads,
(uint)(blocks / (rigidPage.Value.Cylinders * rigidPage.Value.Heads))); (uint)(blocks / (rigidPage.Value.Cylinders * rigidPage.Value.Heads)));
setGeometry = true; setGeometry = true;
@@ -293,7 +294,7 @@ namespace Aaru.Core.Devices.Dumping
UpdateStatus?. UpdateStatus?.
Invoke($"Setting geometry to {flexiblePage.Value.Cylinders} cylinders, {flexiblePage.Value.Heads} heads, {flexiblePage.Value.SectorsPerTrack} sectors per track"); Invoke($"Setting geometry to {flexiblePage.Value.Cylinders} cylinders, {flexiblePage.Value.Heads} heads, {flexiblePage.Value.SectorsPerTrack} sectors per track");
_outputPlugin.SetGeometry(flexiblePage.Value.Cylinders, flexiblePage.Value.Heads, outputFormat.SetGeometry(flexiblePage.Value.Cylinders, flexiblePage.Value.Heads,
flexiblePage.Value.SectorsPerTrack); flexiblePage.Value.SectorsPerTrack);
setGeometry = true; setGeometry = true;
@@ -362,7 +363,7 @@ namespace Aaru.Core.Devices.Dumping
mhddLog.Write(i, cmdDuration); mhddLog.Write(i, cmdDuration);
ibgLog.Write(i, currentSpeed * 1024); ibgLog.Write(i, currentSpeed * 1024);
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
_outputPlugin.WriteSectors(readBuffer, i, blocksToRead); outputFormat.WriteSectors(readBuffer, i, blocksToRead);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
extents.Add(i, blocksToRead, true); extents.Add(i, blocksToRead, true);
} }
@@ -377,7 +378,7 @@ namespace Aaru.Core.Devices.Dumping
// Write empty data // Write empty data
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
_outputPlugin.WriteSectors(new byte[blockSize * _skip], i, _skip); outputFormat.WriteSectors(new byte[blockSize * _skip], i, _skip);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
for(ulong b = i; b < i + _skip; b++) for(ulong b = i; b < i + _skip; b++)
@@ -463,7 +464,7 @@ namespace Aaru.Core.Devices.Dumping
_resume.BadBlocks.Remove(badSector); _resume.BadBlocks.Remove(badSector);
extents.Add(badSector); extents.Add(badSector);
_outputPlugin.WriteSector(readBuffer, badSector); outputFormat.WriteSector(readBuffer, badSector);
} }
EndProgress?.Invoke(); EndProgress?.Invoke();
@@ -603,12 +604,12 @@ namespace Aaru.Core.Devices.Dumping
{ {
_resume.BadBlocks.Remove(badSector); _resume.BadBlocks.Remove(badSector);
extents.Add(badSector); extents.Add(badSector);
_outputPlugin.WriteSector(readBuffer, badSector); outputFormat.WriteSector(readBuffer, badSector);
UpdateStatus?.Invoke($"Correctly retried block {badSector} in pass {pass}."); UpdateStatus?.Invoke($"Correctly retried block {badSector} in pass {pass}.");
_dumpLog.WriteLine("Correctly retried block {0} in pass {1}.", badSector, pass); _dumpLog.WriteLine("Correctly retried block {0} in pass {1}.", badSector, pass);
} }
else if(runningPersistent) else if(runningPersistent)
_outputPlugin.WriteSector(readBuffer, badSector); outputFormat.WriteSector(readBuffer, badSector);
} }
if(pass < _retryPasses && if(pass < _retryPasses &&
@@ -654,7 +655,7 @@ namespace Aaru.Core.Devices.Dumping
currentTry.Extents = ExtentsConverter.ToMetadata(extents); currentTry.Extents = ExtentsConverter.ToMetadata(extents);
_outputPlugin.SetDumpHardware(_resume.Tries); outputFormat.SetDumpHardware(_resume.Tries);
var metadata = new CommonTypes.Structs.ImageInfo var metadata = new CommonTypes.Structs.ImageInfo
{ {
@@ -662,17 +663,17 @@ namespace Aaru.Core.Devices.Dumping
ApplicationVersion = Version.GetVersion() ApplicationVersion = Version.GetVersion()
}; };
if(!_outputPlugin.SetMetadata(metadata)) if(!outputFormat.SetMetadata(metadata))
ErrorMessage?.Invoke("Error {0} setting metadata, continuing..." + Environment.NewLine + ErrorMessage?.Invoke("Error {0} setting metadata, continuing..." + Environment.NewLine +
_outputPlugin.ErrorMessage); outputFormat.ErrorMessage);
if(_preSidecar != null) if(_preSidecar != null)
_outputPlugin.SetCicmMetadata(_preSidecar); outputFormat.SetCicmMetadata(_preSidecar);
_dumpLog.WriteLine("Closing output file."); _dumpLog.WriteLine("Closing output file.");
UpdateStatus?.Invoke("Closing output file."); UpdateStatus?.Invoke("Closing output file.");
DateTime closeStart = DateTime.Now; DateTime closeStart = DateTime.Now;
_outputPlugin.Close(); outputFormat.Close();
DateTime closeEnd = DateTime.Now; DateTime closeEnd = DateTime.Now;
UpdateStatus?.Invoke($"Closed in {(closeEnd - closeStart).TotalSeconds} seconds."); UpdateStatus?.Invoke($"Closed in {(closeEnd - closeStart).TotalSeconds} seconds.");
_dumpLog.WriteLine("Closed in {0} seconds.", (closeEnd - closeStart).TotalSeconds); _dumpLog.WriteLine("Closed in {0} seconds.", (closeEnd - closeStart).TotalSeconds);

View File

@@ -69,6 +69,7 @@ namespace Aaru.Core.Devices.Dumping
MediaType dskType; MediaType dskType;
bool sense; bool sense;
byte[] senseBuf; byte[] senseBuf;
var outputFormat = _outputPlugin as IWritableImage;
sense = _dev.ReadCapacity(out byte[] readBuffer, out _, _dev.Timeout, out _); sense = _dev.ReadCapacity(out byte[] readBuffer, out _, _dev.Timeout, out _);
@@ -132,16 +133,16 @@ namespace Aaru.Core.Devices.Dumping
var mhddLog = new MhddLog(_outputPrefix + ".mhddlog.bin", _dev, blocks, blockSize, blocksToRead, _private); var mhddLog = new MhddLog(_outputPrefix + ".mhddlog.bin", _dev, blocks, blockSize, blocksToRead, _private);
var ibgLog = new IbgLog(_outputPrefix + ".ibg", sbcProfile); var ibgLog = new IbgLog(_outputPrefix + ".ibg", sbcProfile);
ret = _outputPlugin.Create(_outputPath, dskType, _formatOptions, blocks, blockSize); ret = outputFormat.Create(_outputPath, dskType, _formatOptions, blocks, blockSize);
// Cannot create image // Cannot create image
if(!ret) if(!ret)
{ {
_dumpLog.WriteLine("Error creating output image, not continuing."); _dumpLog.WriteLine("Error creating output image, not continuing.");
_dumpLog.WriteLine(_outputPlugin.ErrorMessage); _dumpLog.WriteLine(outputFormat.ErrorMessage);
StoppingErrorMessage?.Invoke("Error creating output image, not continuing." + Environment.NewLine + StoppingErrorMessage?.Invoke("Error creating output image, not continuing." + Environment.NewLine +
_outputPlugin.ErrorMessage); outputFormat.ErrorMessage);
return; return;
} }
@@ -208,7 +209,7 @@ namespace Aaru.Core.Devices.Dumping
mhddLog.Write(i, cmdDuration); mhddLog.Write(i, cmdDuration);
ibgLog.Write(i, currentSpeed * 1024); ibgLog.Write(i, currentSpeed * 1024);
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
_outputPlugin.WriteSectors(readBuffer, i, blocksToRead); outputFormat.WriteSectors(readBuffer, i, blocksToRead);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
extents.Add(i, blocksToRead, true); extents.Add(i, blocksToRead, true);
} }
@@ -225,7 +226,7 @@ namespace Aaru.Core.Devices.Dumping
// Write empty data // Write empty data
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
_outputPlugin.WriteSectors(new byte[blockSize * _skip], i, _skip); outputFormat.WriteSectors(new byte[blockSize * _skip], i, _skip);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
for(ulong b = i; b < i + _skip; b++) for(ulong b = i; b < i + _skip; b++)
@@ -315,7 +316,7 @@ namespace Aaru.Core.Devices.Dumping
_resume.BadBlocks.Remove(badSector); _resume.BadBlocks.Remove(badSector);
extents.Add(badSector); extents.Add(badSector);
_outputPlugin.WriteSector(readBuffer, badSector); outputFormat.WriteSector(readBuffer, badSector);
} }
EndProgress?.Invoke(); EndProgress?.Invoke();
@@ -471,12 +472,12 @@ namespace Aaru.Core.Devices.Dumping
{ {
_resume.BadBlocks.Remove(badSector); _resume.BadBlocks.Remove(badSector);
extents.Add(badSector); extents.Add(badSector);
_outputPlugin.WriteSector(readBuffer, badSector); outputFormat.WriteSector(readBuffer, badSector);
UpdateStatus?.Invoke($"Correctly retried block {badSector} in pass {pass}."); UpdateStatus?.Invoke($"Correctly retried block {badSector} in pass {pass}.");
_dumpLog.WriteLine("Correctly retried block {0} in pass {1}.", badSector, pass); _dumpLog.WriteLine("Correctly retried block {0} in pass {1}.", badSector, pass);
} }
else if(runningPersistent) else if(runningPersistent)
_outputPlugin.WriteSector(readBuffer, badSector); outputFormat.WriteSector(readBuffer, badSector);
} }
if(pass < _retryPasses && if(pass < _retryPasses &&
@@ -528,19 +529,19 @@ namespace Aaru.Core.Devices.Dumping
ApplicationVersion = Version.GetVersion() ApplicationVersion = Version.GetVersion()
}; };
if(!_outputPlugin.SetMetadata(metadata)) if(!outputFormat.SetMetadata(metadata))
ErrorMessage?.Invoke("Error {0} setting metadata, continuing..." + Environment.NewLine + ErrorMessage?.Invoke("Error {0} setting metadata, continuing..." + Environment.NewLine +
_outputPlugin.ErrorMessage); outputFormat.ErrorMessage);
_outputPlugin.SetDumpHardware(_resume.Tries); outputFormat.SetDumpHardware(_resume.Tries);
if(_preSidecar != null) if(_preSidecar != null)
_outputPlugin.SetCicmMetadata(_preSidecar); outputFormat.SetCicmMetadata(_preSidecar);
_dumpLog.WriteLine("Closing output file."); _dumpLog.WriteLine("Closing output file.");
UpdateStatus?.Invoke("Closing output file."); UpdateStatus?.Invoke("Closing output file.");
DateTime closeStart = DateTime.Now; DateTime closeStart = DateTime.Now;
_outputPlugin.Close(); outputFormat.Close();
DateTime closeEnd = DateTime.Now; DateTime closeEnd = DateTime.Now;
UpdateStatus?.Invoke($"Closed in {(closeEnd - closeStart).TotalSeconds} seconds."); UpdateStatus?.Invoke($"Closed in {(closeEnd - closeStart).TotalSeconds} seconds.");
_dumpLog.WriteLine("Closed in {0} seconds.", (closeEnd - closeStart).TotalSeconds); _dumpLog.WriteLine("Closed in {0} seconds.", (closeEnd - closeStart).TotalSeconds);

View File

@@ -65,6 +65,7 @@ namespace Aaru.Core.Devices.Dumping
DateTime start; DateTime start;
DateTime end; DateTime end;
byte[] senseBuf; byte[] senseBuf;
var outputOptical = _outputPlugin as IWritableOpticalImage;
bool sense = _dev.Read12(out byte[] readBuffer, out _, 0, false, true, false, false, 0, 512, 0, 1, false, bool sense = _dev.Read12(out byte[] readBuffer, out _, 0, false, true, false, false, 0, 512, 0, 1, false,
_dev.Timeout, out _); _dev.Timeout, out _);
@@ -138,16 +139,16 @@ namespace Aaru.Core.Devices.Dumping
var mhddLog = new MhddLog(_outputPrefix + ".mhddlog.bin", _dev, blocks, blockSize, blocksToRead, _private); var mhddLog = new MhddLog(_outputPrefix + ".mhddlog.bin", _dev, blocks, blockSize, blocksToRead, _private);
var ibgLog = new IbgLog(_outputPrefix + ".ibg", 0x0010); var ibgLog = new IbgLog(_outputPrefix + ".ibg", 0x0010);
ret = _outputPlugin.Create(_outputPath, dskType, _formatOptions, blocks, blockSize); ret = outputOptical.Create(_outputPath, dskType, _formatOptions, blocks, blockSize);
// Cannot create image // Cannot create image
if(!ret) if(!ret)
{ {
_dumpLog.WriteLine("Error creating output image, not continuing."); _dumpLog.WriteLine("Error creating output image, not continuing.");
_dumpLog.WriteLine(_outputPlugin.ErrorMessage); _dumpLog.WriteLine(outputOptical.ErrorMessage);
StoppingErrorMessage?.Invoke("Error creating output image, not continuing." + Environment.NewLine + StoppingErrorMessage?.Invoke("Error creating output image, not continuing." + Environment.NewLine +
_outputPlugin.ErrorMessage); outputOptical.ErrorMessage);
return; return;
} }
@@ -155,7 +156,7 @@ namespace Aaru.Core.Devices.Dumping
start = DateTime.UtcNow; start = DateTime.UtcNow;
double imageWriteDuration = 0; double imageWriteDuration = 0;
(_outputPlugin as IWritableOpticalImage)?.SetTracks(new List<Track> (outputOptical as IWritableOpticalImage)?.SetTracks(new List<Track>
{ {
new Track new Track
{ {
@@ -230,7 +231,7 @@ namespace Aaru.Core.Devices.Dumping
mhddLog.Write(i, cmdDuration); mhddLog.Write(i, cmdDuration);
ibgLog.Write(i, currentSpeed * 1024); ibgLog.Write(i, currentSpeed * 1024);
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
_outputPlugin.WriteSectors(readBuffer, i, blocksToRead); outputOptical.WriteSectors(readBuffer, i, blocksToRead);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
extents.Add(i, blocksToRead, true); extents.Add(i, blocksToRead, true);
} }
@@ -247,7 +248,7 @@ namespace Aaru.Core.Devices.Dumping
// Write empty data // Write empty data
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
_outputPlugin.WriteSectors(new byte[blockSize * _skip], i, _skip); outputOptical.WriteSectors(new byte[blockSize * _skip], i, _skip);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
for(ulong b = i; b < i + _skip; b++) for(ulong b = i; b < i + _skip; b++)
@@ -336,7 +337,7 @@ namespace Aaru.Core.Devices.Dumping
_resume.BadBlocks.Remove(badSector); _resume.BadBlocks.Remove(badSector);
extents.Add(badSector); extents.Add(badSector);
_outputPlugin.WriteSector(readBuffer, badSector); outputOptical.WriteSector(readBuffer, badSector);
} }
EndProgress?.Invoke(); EndProgress?.Invoke();
@@ -476,14 +477,14 @@ namespace Aaru.Core.Devices.Dumping
{ {
_resume.BadBlocks.Remove(badSector); _resume.BadBlocks.Remove(badSector);
extents.Add(badSector); extents.Add(badSector);
_outputPlugin.WriteSector(readBuffer, badSector); outputOptical.WriteSector(readBuffer, badSector);
UpdateStatus?.Invoke($"Correctly retried block {badSector} in pass {pass}."); UpdateStatus?.Invoke($"Correctly retried block {badSector} in pass {pass}.");
_dumpLog.WriteLine("Correctly retried block {0} in pass {1}.", badSector, pass); _dumpLog.WriteLine("Correctly retried block {0} in pass {1}.", badSector, pass);
} }
else if(runningPersistent) else if(runningPersistent)
_outputPlugin.WriteSector(readBuffer, badSector); outputOptical.WriteSector(readBuffer, badSector);
} }
if(pass < _retryPasses && if(pass < _retryPasses &&
@@ -536,19 +537,19 @@ namespace Aaru.Core.Devices.Dumping
MediaPartNumber = mediaPartNumber MediaPartNumber = mediaPartNumber
}; };
if(!_outputPlugin.SetMetadata(metadata)) if(!outputOptical.SetMetadata(metadata))
ErrorMessage?.Invoke("Error {0} setting metadata, continuing..." + Environment.NewLine + ErrorMessage?.Invoke("Error {0} setting metadata, continuing..." + Environment.NewLine +
_outputPlugin.ErrorMessage); outputOptical.ErrorMessage);
_outputPlugin.SetDumpHardware(_resume.Tries); outputOptical.SetDumpHardware(_resume.Tries);
if(_preSidecar != null) if(_preSidecar != null)
_outputPlugin.SetCicmMetadata(_preSidecar); outputOptical.SetCicmMetadata(_preSidecar);
_dumpLog.WriteLine("Closing output file."); _dumpLog.WriteLine("Closing output file.");
UpdateStatus?.Invoke("Closing output file."); UpdateStatus?.Invoke("Closing output file.");
DateTime closeStart = DateTime.Now; DateTime closeStart = DateTime.Now;
_outputPlugin.Close(); outputOptical.Close();
DateTime closeEnd = DateTime.Now; DateTime closeEnd = DateTime.Now;
_dumpLog.WriteLine("Closed in {0} seconds.", (closeEnd - closeStart).TotalSeconds); _dumpLog.WriteLine("Closed in {0} seconds.", (closeEnd - closeStart).TotalSeconds);

View File

@@ -71,6 +71,7 @@ namespace Aaru.Core.Devices.Dumping
double currentSpeed = 0; double currentSpeed = 0;
double maxSpeed = double.MinValue; double maxSpeed = double.MinValue;
double minSpeed = double.MaxValue; double minSpeed = double.MaxValue;
var outputTape = _outputPlugin as IWritableTapeImage;
_dev.RequestSense(out byte[] senseBuf, _dev.Timeout, out double duration); _dev.RequestSense(out byte[] senseBuf, _dev.Timeout, out double duration);
decSense = Sense.Decode(senseBuf); decSense = Sense.Decode(senseBuf);
@@ -757,30 +758,30 @@ namespace Aaru.Core.Devices.Dumping
} }
} }
bool ret = (_outputPlugin as IWritableTapeImage).SetTape(); bool ret = outputTape.SetTape();
// Cannot set image to tape mode // Cannot set image to tape mode
if(!ret) if(!ret)
{ {
_dumpLog.WriteLine("Error setting output image in tape mode, not continuing."); _dumpLog.WriteLine("Error setting output image in tape mode, not continuing.");
_dumpLog.WriteLine(_outputPlugin.ErrorMessage); _dumpLog.WriteLine(outputTape.ErrorMessage);
StoppingErrorMessage?.Invoke("Error setting output image in tape mode, not continuing." + StoppingErrorMessage?.Invoke("Error setting output image in tape mode, not continuing." +
Environment.NewLine + _outputPlugin.ErrorMessage); Environment.NewLine + outputTape.ErrorMessage);
return; return;
} }
ret = _outputPlugin.Create(_outputPath, dskType, _formatOptions, 0, 0); ret = outputTape.Create(_outputPath, dskType, _formatOptions, 0, 0);
// Cannot create image // Cannot create image
if(!ret) if(!ret)
{ {
_dumpLog.WriteLine("Error creating output image, not continuing."); _dumpLog.WriteLine("Error creating output image, not continuing.");
_dumpLog.WriteLine(_outputPlugin.ErrorMessage); _dumpLog.WriteLine(outputTape.ErrorMessage);
StoppingErrorMessage?.Invoke("Error creating output image, not continuing." + Environment.NewLine + StoppingErrorMessage?.Invoke("Error creating output image, not continuing." + Environment.NewLine +
_outputPlugin.ErrorMessage); outputTape.ErrorMessage);
return; return;
} }
@@ -808,21 +809,20 @@ namespace Aaru.Core.Devices.Dumping
currentBlock = _resume.NextBlock; currentBlock = _resume.NextBlock;
currentTapeFile = currentTapeFile =
(_outputPlugin as IWritableTapeImage).Files.FirstOrDefault(f => f.LastBlock == outputTape.Files.FirstOrDefault(f => f.LastBlock ==
(_outputPlugin as outputTape?.
IWritableTapeImage)?. Files.Max(g => g.LastBlock));
Files.Max(g => g.LastBlock));
currentTapePartition = currentTapePartition =
(_outputPlugin as IWritableTapeImage).TapePartitions.FirstOrDefault(p => p.LastBlock == outputTape.TapePartitions.FirstOrDefault(p => p.LastBlock ==
(_outputPlugin as IWritableTapeImage)?.TapePartitions.Max(g => g.LastBlock)); outputTape?.TapePartitions.Max(g => g.LastBlock));
} }
if(mode6Data != null) if(mode6Data != null)
_outputPlugin.WriteMediaTag(mode6Data, MediaTagType.SCSI_MODESENSE_6); outputTape.WriteMediaTag(mode6Data, MediaTagType.SCSI_MODESENSE_6);
if(mode10Data != null) if(mode10Data != null)
_outputPlugin.WriteMediaTag(mode10Data, MediaTagType.SCSI_MODESENSE_10); outputTape.WriteMediaTag(mode10Data, MediaTagType.SCSI_MODESENSE_10);
DateTime timeSpeedStart = DateTime.UtcNow; DateTime timeSpeedStart = DateTime.UtcNow;
ulong currentSpeedSize = 0; ulong currentSpeedSize = 0;
@@ -849,10 +849,10 @@ namespace Aaru.Core.Devices.Dumping
currentTapeFile.LastBlock = currentBlock - 1; currentTapeFile.LastBlock = currentBlock - 1;
if(currentTapeFile.LastBlock > currentTapeFile.FirstBlock) if(currentTapeFile.LastBlock > currentTapeFile.FirstBlock)
(_outputPlugin as IWritableTapeImage).AddFile(currentTapeFile); outputTape.AddFile(currentTapeFile);
currentTapePartition.LastBlock = currentBlock - 1; currentTapePartition.LastBlock = currentBlock - 1;
(_outputPlugin as IWritableTapeImage).AddPartition(currentTapePartition); outputTape.AddPartition(currentTapePartition);
currentPartition++; currentPartition++;
@@ -945,7 +945,7 @@ namespace Aaru.Core.Devices.Dumping
StoppingErrorMessage?.Invoke("Drive could not go back one block. Sense follows..." + StoppingErrorMessage?.Invoke("Drive could not go back one block. Sense follows..." +
Environment.NewLine + decSense.Value.Description); Environment.NewLine + decSense.Value.Description);
_outputPlugin.Close(); outputTape.Close();
_dumpLog.WriteLine("Drive could not go back one block. Sense follows..."); _dumpLog.WriteLine("Drive could not go back one block. Sense follows...");
_dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", _dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h",
@@ -961,7 +961,7 @@ namespace Aaru.Core.Devices.Dumping
{ {
case SenseKeys.BlankCheck when currentBlock == 0: case SenseKeys.BlankCheck when currentBlock == 0:
StoppingErrorMessage?.Invoke("Cannot dump a blank tape..."); StoppingErrorMessage?.Invoke("Cannot dump a blank tape...");
_outputPlugin.Close(); outputTape.Close();
_dumpLog.WriteLine("Cannot dump a blank tape..."); _dumpLog.WriteLine("Cannot dump a blank tape...");
return; return;
@@ -1001,7 +1001,7 @@ namespace Aaru.Core.Devices.Dumping
(decSense.Value.ASCQ == 0x01 || filemark)) (decSense.Value.ASCQ == 0x01 || filemark))
{ {
currentTapeFile.LastBlock = currentBlock - 1; currentTapeFile.LastBlock = currentBlock - 1;
(_outputPlugin as IWritableTapeImage).AddFile(currentTapeFile); outputTape.AddFile(currentTapeFile);
currentFile++; currentFile++;
@@ -1043,7 +1043,7 @@ namespace Aaru.Core.Devices.Dumping
// Write empty data // Write empty data
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
_outputPlugin.WriteSector(new byte[blockSize], currentBlock); outputTape.WriteSector(new byte[blockSize], currentBlock);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
mhddLog.Write(currentBlock, duration < 500 ? 65535 : duration); mhddLog.Write(currentBlock, duration < 500 ? 65535 : duration);
@@ -1055,7 +1055,7 @@ namespace Aaru.Core.Devices.Dumping
mhddLog.Write(currentBlock, duration); mhddLog.Write(currentBlock, duration);
ibgLog.Write(currentBlock, currentSpeed * 1024); ibgLog.Write(currentBlock, currentSpeed * 1024);
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
_outputPlugin.WriteSector(cmdBuf, currentBlock); outputTape.WriteSector(cmdBuf, currentBlock);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
extents.Add(currentBlock, 1, true); extents.Add(currentBlock, 1, true);
} }
@@ -1082,10 +1082,10 @@ namespace Aaru.Core.Devices.Dumping
if(_aborted) if(_aborted)
{ {
currentTapeFile.LastBlock = currentBlock - 1; currentTapeFile.LastBlock = currentBlock - 1;
(_outputPlugin as IWritableTapeImage).AddFile(currentTapeFile); outputTape.AddFile(currentTapeFile);
currentTapePartition.LastBlock = currentBlock - 1; currentTapePartition.LastBlock = currentBlock - 1;
(_outputPlugin as IWritableTapeImage).AddPartition(currentTapePartition); outputTape.AddPartition(currentTapePartition);
} }
EndProgress?.Invoke(); EndProgress?.Invoke();
@@ -1228,12 +1228,12 @@ namespace Aaru.Core.Devices.Dumping
{ {
_resume.BadBlocks.Remove(badBlock); _resume.BadBlocks.Remove(badBlock);
extents.Add(badBlock); extents.Add(badBlock);
_outputPlugin.WriteSector(cmdBuf, badBlock); outputTape.WriteSector(cmdBuf, badBlock);
UpdateStatus?.Invoke($"Correctly retried block {badBlock} in pass {pass}."); UpdateStatus?.Invoke($"Correctly retried block {badBlock} in pass {pass}.");
_dumpLog.WriteLine("Correctly retried block {0} in pass {1}.", badBlock, pass); _dumpLog.WriteLine("Correctly retried block {0} in pass {1}.", badBlock, pass);
} }
else if(runningPersistent) else if(runningPersistent)
_outputPlugin.WriteSector(cmdBuf, badBlock); outputTape.WriteSector(cmdBuf, badBlock);
} }
if(pass < _retryPasses && if(pass < _retryPasses &&
@@ -1266,7 +1266,7 @@ namespace Aaru.Core.Devices.Dumping
currentTry.Extents = ExtentsConverter.ToMetadata(extents); currentTry.Extents = ExtentsConverter.ToMetadata(extents);
_outputPlugin.SetDumpHardware(_resume.Tries); outputTape.SetDumpHardware(_resume.Tries);
// TODO: Media Serial Number // TODO: Media Serial Number
var metadata = new CommonTypes.Structs.ImageInfo var metadata = new CommonTypes.Structs.ImageInfo
@@ -1275,17 +1275,17 @@ namespace Aaru.Core.Devices.Dumping
ApplicationVersion = Version.GetVersion() ApplicationVersion = Version.GetVersion()
}; };
if(!_outputPlugin.SetMetadata(metadata)) if(!outputTape.SetMetadata(metadata))
ErrorMessage?.Invoke("Error {0} setting metadata, continuing..." + Environment.NewLine + ErrorMessage?.Invoke("Error {0} setting metadata, continuing..." + Environment.NewLine +
_outputPlugin.ErrorMessage); outputTape.ErrorMessage);
if(_preSidecar != null) if(_preSidecar != null)
_outputPlugin.SetCicmMetadata(_preSidecar); outputTape.SetCicmMetadata(_preSidecar);
_dumpLog.WriteLine("Closing output file."); _dumpLog.WriteLine("Closing output file.");
UpdateStatus?.Invoke("Closing output file."); UpdateStatus?.Invoke("Closing output file.");
DateTime closeStart = DateTime.Now; DateTime closeStart = DateTime.Now;
_outputPlugin.Close(); outputTape.Close();
DateTime closeEnd = DateTime.Now; DateTime closeEnd = DateTime.Now;
UpdateStatus?.Invoke($"Closed in {(closeEnd - closeStart).TotalSeconds} seconds."); UpdateStatus?.Invoke($"Closed in {(closeEnd - closeStart).TotalSeconds} seconds.");
_dumpLog.WriteLine("Closed in {0} seconds.", (closeEnd - closeStart).TotalSeconds); _dumpLog.WriteLine("Closed in {0} seconds.", (closeEnd - closeStart).TotalSeconds);

View File

@@ -29,6 +29,7 @@ using System;
using System.Linq; using System.Linq;
using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Extents; using Aaru.CommonTypes.Extents;
using Aaru.CommonTypes.Interfaces;
using Aaru.Core.Logging; using Aaru.Core.Logging;
using Aaru.Decoders.DVD; using Aaru.Decoders.DVD;
using Aaru.Decryption; using Aaru.Decryption;
@@ -71,6 +72,7 @@ namespace Aaru.Core.Devices.Dumping
DateTime timeSpeedStart = DateTime.UtcNow; DateTime timeSpeedStart = DateTime.UtcNow;
byte[] buffer; byte[] buffer;
uint blocksToRead = maxBlocksToRead; uint blocksToRead = maxBlocksToRead;
var outputFormat = _outputPlugin as IWritableImage;
InitProgress?.Invoke(); InitProgress?.Invoke();
@@ -129,7 +131,7 @@ namespace Aaru.Core.Devices.Dumping
CSS_CPRM.TitleKey? titleKey = CSS.DecodeTitleKey(tmpBuf, dvdDecrypt.BusKey); CSS_CPRM.TitleKey? titleKey = CSS.DecodeTitleKey(tmpBuf, dvdDecrypt.BusKey);
if(titleKey.HasValue) if(titleKey.HasValue)
_outputPlugin.WriteSectorTag(new[] outputFormat.WriteSectorTag(new[]
{ {
titleKey.Value.CMI titleKey.Value.CMI
}, i + j, SectorTagType.DvdCmi); }, i + j, SectorTagType.DvdCmi);
@@ -140,12 +142,12 @@ namespace Aaru.Core.Devices.Dumping
if((titleKey.Value.CMI & 0x80) >> 7 == 0) if((titleKey.Value.CMI & 0x80) >> 7 == 0)
{ {
// The CMI indicates this sector is not encrypted. // The CMI indicates this sector is not encrypted.
_outputPlugin.WriteSectorTag(new byte[] outputFormat.WriteSectorTag(new byte[]
{ {
0, 0, 0, 0, 0 0, 0, 0, 0, 0
}, i + j, SectorTagType.DvdTitleKey); }, i + j, SectorTagType.DvdTitleKey);
_outputPlugin.WriteSectorTag(new byte[] outputFormat.WriteSectorTag(new byte[]
{ {
0, 0, 0, 0, 0 0, 0, 0, 0, 0
}, i + j, SectorTagType.DvdTitleKeyDecrypted); }, i + j, SectorTagType.DvdTitleKeyDecrypted);
@@ -159,12 +161,12 @@ namespace Aaru.Core.Devices.Dumping
// not encrypted even if the CMI says it is. // not encrypted even if the CMI says it is.
if(titleKey.Value.Key.All(k => k == 0)) if(titleKey.Value.Key.All(k => k == 0))
{ {
_outputPlugin.WriteSectorTag(new byte[] outputFormat.WriteSectorTag(new byte[]
{ {
0, 0, 0, 0, 0 0, 0, 0, 0, 0
}, i + j, SectorTagType.DvdTitleKey); }, i + j, SectorTagType.DvdTitleKey);
_outputPlugin.WriteSectorTag(new byte[] outputFormat.WriteSectorTag(new byte[]
{ {
0, 0, 0, 0, 0 0, 0, 0, 0, 0
}, i + j, SectorTagType.DvdTitleKeyDecrypted); }, i + j, SectorTagType.DvdTitleKeyDecrypted);
@@ -174,26 +176,26 @@ namespace Aaru.Core.Devices.Dumping
continue; continue;
} }
_outputPlugin.WriteSectorTag(titleKey.Value.Key, i + j, SectorTagType.DvdTitleKey); outputFormat.WriteSectorTag(titleKey.Value.Key, i + j, SectorTagType.DvdTitleKey);
_resume.MissingTitleKeys.Remove(i + j); _resume.MissingTitleKeys.Remove(i + j);
CSS.DecryptTitleKey(0, discKey, titleKey.Value.Key, out tmpBuf); CSS.DecryptTitleKey(0, discKey, titleKey.Value.Key, out tmpBuf);
_outputPlugin.WriteSectorTag(tmpBuf, i + j, SectorTagType.DvdTitleKeyDecrypted); outputFormat.WriteSectorTag(tmpBuf, i + j, SectorTagType.DvdTitleKeyDecrypted);
} }
} }
if(!_storeEncrypted) if(!_storeEncrypted)
// Todo: Flag in the _outputPlugin that a sector has been decrypted // Todo: Flag in the outputFormat that a sector has been decrypted
{ {
ErrorNumber errno = ErrorNumber errno =
_outputPlugin.ReadSectorsTag(i, blocksToRead, SectorTagType.DvdCmi, out byte[] cmi); outputFormat.ReadSectorsTag(i, blocksToRead, SectorTagType.DvdCmi, out byte[] cmi);
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
ErrorMessage?.Invoke($"Error retrieving CMI for sector {i}"); ErrorMessage?.Invoke($"Error retrieving CMI for sector {i}");
else else
{ {
errno = _outputPlugin.ReadSectorsTag(i, blocksToRead, errno = outputFormat.ReadSectorsTag(i, blocksToRead,
SectorTagType.DvdTitleKeyDecrypted, SectorTagType.DvdTitleKeyDecrypted,
out byte[] titleKey); out byte[] titleKey);
@@ -208,7 +210,7 @@ namespace Aaru.Core.Devices.Dumping
mhddLog.Write(i, cmdDuration); mhddLog.Write(i, cmdDuration);
ibgLog.Write(i, currentSpeed * 1024); ibgLog.Write(i, currentSpeed * 1024);
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
_outputPlugin.WriteSectors(buffer, i, blocksToRead); outputFormat.WriteSectors(buffer, i, blocksToRead);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
extents.Add(i, blocksToRead, true); extents.Add(i, blocksToRead, true);
} }
@@ -239,7 +241,7 @@ namespace Aaru.Core.Devices.Dumping
// Write empty data // Write empty data
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
_outputPlugin.WriteSectors(new byte[blockSize * _skip], i, _skip); outputFormat.WriteSectors(new byte[blockSize * _skip], i, _skip);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
for(ulong b = i; b < i + _skip; b++) for(ulong b = i; b < i + _skip; b++)

View File

@@ -87,6 +87,7 @@ namespace Aaru.Core.Devices.Dumping
Modes.DecodedMode? decMode = null; Modes.DecodedMode? decMode = null;
bool ret; bool ret;
ExtentsULong blankExtents = null; ExtentsULong blankExtents = null;
var outputFormat = _outputPlugin as IWritableImage;
if(opticalDisc) if(opticalDisc)
switch(dskType) switch(dskType)
@@ -317,7 +318,7 @@ namespace Aaru.Core.Devices.Dumping
ret = true; ret = true;
foreach(MediaTagType tag in mediaTags.Keys.Where(tag => !_outputPlugin.SupportedMediaTags.Contains(tag))) foreach(MediaTagType tag in mediaTags.Keys.Where(tag => !outputFormat.SupportedMediaTags.Contains(tag)))
{ {
ret = false; ret = false;
_dumpLog.WriteLine($"Output format does not support {tag}."); _dumpLog.WriteLine($"Output format does not support {tag}.");
@@ -349,16 +350,16 @@ namespace Aaru.Core.Devices.Dumping
if(!opticalDisc) if(!opticalDisc)
{ {
ret = _outputPlugin.Create(_outputPath, dskType, _formatOptions, blocks, blockSize); ret = outputFormat.Create(_outputPath, dskType, _formatOptions, blocks, blockSize);
// Cannot create image // Cannot create image
if(!ret) if(!ret)
{ {
_dumpLog.WriteLine("Error creating output image, not continuing."); _dumpLog.WriteLine("Error creating output image, not continuing.");
_dumpLog.WriteLine(_outputPlugin.ErrorMessage); _dumpLog.WriteLine(outputFormat.ErrorMessage);
StoppingErrorMessage?.Invoke("Error creating output image, not continuing." + Environment.NewLine + StoppingErrorMessage?.Invoke("Error creating output image, not continuing." + Environment.NewLine +
_outputPlugin.ErrorMessage); outputFormat.ErrorMessage);
return; return;
} }
@@ -372,7 +373,7 @@ namespace Aaru.Core.Devices.Dumping
if(opticalDisc) if(opticalDisc)
{ {
if(_outputPlugin is IWritableOpticalImage opticalPlugin) if(outputFormat is IWritableOpticalImage opticalPlugin)
{ {
sense = _dev.ReadDiscInformation(out readBuffer, out _, MmcDiscInformationDataTypes.DiscInformation, sense = _dev.ReadDiscInformation(out readBuffer, out _, MmcDiscInformationDataTypes.DiscInformation,
_dev.Timeout, out _); _dev.Timeout, out _);
@@ -505,16 +506,16 @@ namespace Aaru.Core.Devices.Dumping
else else
tracks = tracks.OrderBy(t => t.Sequence).ToList(); tracks = tracks.OrderBy(t => t.Sequence).ToList();
ret = _outputPlugin.Create(_outputPath, dskType, _formatOptions, blocks, blockSize); ret = outputFormat.Create(_outputPath, dskType, _formatOptions, blocks, blockSize);
// Cannot create image // Cannot create image
if(!ret) if(!ret)
{ {
_dumpLog.WriteLine("Error creating output image, not continuing."); _dumpLog.WriteLine("Error creating output image, not continuing.");
_dumpLog.WriteLine(_outputPlugin.ErrorMessage); _dumpLog.WriteLine(outputFormat.ErrorMessage);
StoppingErrorMessage?.Invoke("Error creating output image, not continuing." + StoppingErrorMessage?.Invoke("Error creating output image, not continuing." +
Environment.NewLine + _outputPlugin.ErrorMessage); Environment.NewLine + outputFormat.ErrorMessage);
return; return;
} }
@@ -588,7 +589,7 @@ namespace Aaru.Core.Devices.Dumping
UpdateStatus?. UpdateStatus?.
Invoke($"Setting geometry to {rigidPage.Value.Cylinders} cylinders, {rigidPage.Value.Heads} heads, {(uint)(blocks / (rigidPage.Value.Cylinders * rigidPage.Value.Heads))} sectors per track"); Invoke($"Setting geometry to {rigidPage.Value.Cylinders} cylinders, {rigidPage.Value.Heads} heads, {(uint)(blocks / (rigidPage.Value.Cylinders * rigidPage.Value.Heads))} sectors per track");
_outputPlugin.SetGeometry(rigidPage.Value.Cylinders, rigidPage.Value.Heads, outputFormat.SetGeometry(rigidPage.Value.Cylinders, rigidPage.Value.Heads,
(uint)(blocks / (rigidPage.Value.Cylinders * rigidPage.Value.Heads))); (uint)(blocks / (rigidPage.Value.Cylinders * rigidPage.Value.Heads)));
setGeometry = true; setGeometry = true;
@@ -608,7 +609,7 @@ namespace Aaru.Core.Devices.Dumping
UpdateStatus?. UpdateStatus?.
Invoke($"Setting geometry to {flexiblePage.Value.Cylinders} cylinders, {flexiblePage.Value.Heads} heads, {flexiblePage.Value.SectorsPerTrack} sectors per track"); Invoke($"Setting geometry to {flexiblePage.Value.Cylinders} cylinders, {flexiblePage.Value.Heads} heads, {flexiblePage.Value.SectorsPerTrack} sectors per track");
_outputPlugin.SetGeometry(flexiblePage.Value.Cylinders, flexiblePage.Value.Heads, outputFormat.SetGeometry(flexiblePage.Value.Cylinders, flexiblePage.Value.Heads,
flexiblePage.Value.SectorsPerTrack); flexiblePage.Value.SectorsPerTrack);
setGeometry = true; setGeometry = true;
@@ -617,16 +618,16 @@ namespace Aaru.Core.Devices.Dumping
if(!imageCreated) if(!imageCreated)
{ {
ret = _outputPlugin.Create(_outputPath, dskType, _formatOptions, blocks, blockSize); ret = outputFormat.Create(_outputPath, dskType, _formatOptions, blocks, blockSize);
// Cannot create image // Cannot create image
if(!ret) if(!ret)
{ {
_dumpLog.WriteLine("Error creating output image, not continuing."); _dumpLog.WriteLine("Error creating output image, not continuing.");
_dumpLog.WriteLine(_outputPlugin.ErrorMessage); _dumpLog.WriteLine(outputFormat.ErrorMessage);
StoppingErrorMessage?.Invoke("Error creating output image, not continuing." + Environment.NewLine + StoppingErrorMessage?.Invoke("Error creating output image, not continuing." + Environment.NewLine +
_outputPlugin.ErrorMessage); outputFormat.ErrorMessage);
return; return;
} }
@@ -637,7 +638,7 @@ namespace Aaru.Core.Devices.Dumping
UpdateStatus?.Invoke("Creating single track as could not retrieve track list from drive."); UpdateStatus?.Invoke("Creating single track as could not retrieve track list from drive.");
(_outputPlugin as IWritableOpticalImage)?.SetTracks(new List<Track> (outputFormat as IWritableOpticalImage)?.SetTracks(new List<Track>
{ {
new() new()
{ {
@@ -784,7 +785,7 @@ namespace Aaru.Core.Devices.Dumping
continue; continue;
} }
ret = _outputPlugin.WriteMediaTag(tag.Value, tag.Key); ret = outputFormat.WriteMediaTag(tag.Value, tag.Key);
if(ret || _force) if(ret || _force)
continue; continue;
@@ -793,7 +794,7 @@ namespace Aaru.Core.Devices.Dumping
StoppingErrorMessage?.Invoke($"Cannot write tag {tag.Key}."); StoppingErrorMessage?.Invoke($"Cannot write tag {tag.Key}.");
_dumpLog.WriteLine($"Cannot write tag {tag.Key}." + Environment.NewLine + _dumpLog.WriteLine($"Cannot write tag {tag.Key}." + Environment.NewLine +
_outputPlugin.ErrorMessage); outputFormat.ErrorMessage);
return; return;
} }
@@ -808,7 +809,7 @@ namespace Aaru.Core.Devices.Dumping
{ {
UpdateStatus?.Invoke("Reading USB descriptors."); UpdateStatus?.Invoke("Reading USB descriptors.");
_dumpLog.WriteLine("Reading USB descriptors."); _dumpLog.WriteLine("Reading USB descriptors.");
ret = _outputPlugin.WriteMediaTag(_dev.UsbDescriptors, MediaTagType.USB_Descriptors); ret = outputFormat.WriteMediaTag(_dev.UsbDescriptors, MediaTagType.USB_Descriptors);
if(!ret && if(!ret &&
!_force) !_force)
@@ -816,7 +817,7 @@ namespace Aaru.Core.Devices.Dumping
_dumpLog.WriteLine("Cannot write USB descriptors."); _dumpLog.WriteLine("Cannot write USB descriptors.");
StoppingErrorMessage?.Invoke("Cannot write USB descriptors." + Environment.NewLine + StoppingErrorMessage?.Invoke("Cannot write USB descriptors." + Environment.NewLine +
_outputPlugin.ErrorMessage); outputFormat.ErrorMessage);
return; return;
} }
@@ -835,7 +836,7 @@ namespace Aaru.Core.Devices.Dumping
if(_private) if(_private)
cmdBuf = DeviceReport.ClearIdentify(cmdBuf); cmdBuf = DeviceReport.ClearIdentify(cmdBuf);
ret = _outputPlugin.WriteMediaTag(cmdBuf, MediaTagType.ATAPI_IDENTIFY); ret = outputFormat.WriteMediaTag(cmdBuf, MediaTagType.ATAPI_IDENTIFY);
if(!ret && if(!ret &&
!_force) !_force)
@@ -843,7 +844,7 @@ namespace Aaru.Core.Devices.Dumping
_dumpLog.WriteLine("Cannot write ATAPI IDENTIFY PACKET DEVICE."); _dumpLog.WriteLine("Cannot write ATAPI IDENTIFY PACKET DEVICE.");
StoppingErrorMessage?.Invoke("Cannot write ATAPI IDENTIFY PACKET DEVICE." + StoppingErrorMessage?.Invoke("Cannot write ATAPI IDENTIFY PACKET DEVICE." +
Environment.NewLine + _outputPlugin.ErrorMessage); Environment.NewLine + outputFormat.ErrorMessage);
return; return;
} }
@@ -856,7 +857,7 @@ namespace Aaru.Core.Devices.Dumping
{ {
UpdateStatus?.Invoke("Requesting SCSI INQUIRY."); UpdateStatus?.Invoke("Requesting SCSI INQUIRY.");
_dumpLog.WriteLine("Requesting SCSI INQUIRY."); _dumpLog.WriteLine("Requesting SCSI INQUIRY.");
ret = _outputPlugin.WriteMediaTag(cmdBuf, MediaTagType.SCSI_INQUIRY); ret = outputFormat.WriteMediaTag(cmdBuf, MediaTagType.SCSI_INQUIRY);
if(!ret && if(!ret &&
!_force) !_force)
@@ -864,7 +865,7 @@ namespace Aaru.Core.Devices.Dumping
StoppingErrorMessage?.Invoke("Cannot write SCSI INQUIRY."); StoppingErrorMessage?.Invoke("Cannot write SCSI INQUIRY.");
_dumpLog.WriteLine("Cannot write SCSI INQUIRY." + Environment.NewLine + _dumpLog.WriteLine("Cannot write SCSI INQUIRY." + Environment.NewLine +
_outputPlugin.ErrorMessage); outputFormat.ErrorMessage);
return; return;
} }
@@ -884,7 +885,7 @@ namespace Aaru.Core.Devices.Dumping
!_dev.Error) !_dev.Error)
if(Modes.DecodeMode10(cmdBuf, _dev.ScsiType).HasValue) if(Modes.DecodeMode10(cmdBuf, _dev.ScsiType).HasValue)
{ {
ret = _outputPlugin.WriteMediaTag(cmdBuf, MediaTagType.SCSI_MODESENSE_10); ret = outputFormat.WriteMediaTag(cmdBuf, MediaTagType.SCSI_MODESENSE_10);
if(!ret && if(!ret &&
!_force) !_force)
@@ -892,7 +893,7 @@ namespace Aaru.Core.Devices.Dumping
_dumpLog.WriteLine("Cannot write SCSI MODE SENSE (10)."); _dumpLog.WriteLine("Cannot write SCSI MODE SENSE (10).");
StoppingErrorMessage?.Invoke("Cannot write SCSI MODE SENSE (10)." + StoppingErrorMessage?.Invoke("Cannot write SCSI MODE SENSE (10)." +
Environment.NewLine + _outputPlugin.ErrorMessage); Environment.NewLine + outputFormat.ErrorMessage);
return; return;
} }
@@ -915,7 +916,7 @@ namespace Aaru.Core.Devices.Dumping
!_dev.Error) !_dev.Error)
if(Modes.DecodeMode6(cmdBuf, _dev.ScsiType).HasValue) if(Modes.DecodeMode6(cmdBuf, _dev.ScsiType).HasValue)
{ {
ret = _outputPlugin.WriteMediaTag(cmdBuf, MediaTagType.SCSI_MODESENSE_6); ret = outputFormat.WriteMediaTag(cmdBuf, MediaTagType.SCSI_MODESENSE_6);
if(!ret && if(!ret &&
!_force) !_force)
@@ -923,7 +924,7 @@ namespace Aaru.Core.Devices.Dumping
_dumpLog.WriteLine("Cannot write SCSI MODE SENSE (6)."); _dumpLog.WriteLine("Cannot write SCSI MODE SENSE (6).");
StoppingErrorMessage?.Invoke("Cannot write SCSI MODE SENSE (6)." + StoppingErrorMessage?.Invoke("Cannot write SCSI MODE SENSE (6)." +
Environment.NewLine + _outputPlugin.ErrorMessage); Environment.NewLine + outputFormat.ErrorMessage);
return; return;
} }
@@ -939,7 +940,7 @@ namespace Aaru.Core.Devices.Dumping
currentTry.Extents = ExtentsConverter.ToMetadata(extents); currentTry.Extents = ExtentsConverter.ToMetadata(extents);
_outputPlugin.SetDumpHardware(_resume.Tries); outputFormat.SetDumpHardware(_resume.Tries);
// TODO: Media Serial Number // TODO: Media Serial Number
// TODO: Non-removable drive information // TODO: Non-removable drive information
@@ -949,17 +950,17 @@ namespace Aaru.Core.Devices.Dumping
ApplicationVersion = Version.GetVersion() ApplicationVersion = Version.GetVersion()
}; };
if(!_outputPlugin.SetMetadata(metadata)) if(!outputFormat.SetMetadata(metadata))
ErrorMessage?.Invoke("Error {0} setting metadata, continuing..." + Environment.NewLine + ErrorMessage?.Invoke("Error {0} setting metadata, continuing..." + Environment.NewLine +
_outputPlugin.ErrorMessage); outputFormat.ErrorMessage);
if(_preSidecar != null) if(_preSidecar != null)
_outputPlugin.SetCicmMetadata(_preSidecar); outputFormat.SetCicmMetadata(_preSidecar);
_dumpLog.WriteLine("Closing output file."); _dumpLog.WriteLine("Closing output file.");
UpdateStatus?.Invoke("Closing output file."); UpdateStatus?.Invoke("Closing output file.");
DateTime closeStart = DateTime.Now; DateTime closeStart = DateTime.Now;
_outputPlugin.Close(); outputFormat.Close();
DateTime closeEnd = DateTime.Now; DateTime closeEnd = DateTime.Now;
UpdateStatus?.Invoke($"Closed in {(closeEnd - closeStart).TotalSeconds} seconds."); UpdateStatus?.Invoke($"Closed in {(closeEnd - closeStart).TotalSeconds} seconds.");
_dumpLog.WriteLine("Closed in {0} seconds.", (closeEnd - closeStart).TotalSeconds); _dumpLog.WriteLine("Closed in {0} seconds.", (closeEnd - closeStart).TotalSeconds);
@@ -1032,7 +1033,7 @@ namespace Aaru.Core.Devices.Dumping
{ {
if(_dev.IsUsb && if(_dev.IsUsb &&
_dev.UsbDescriptors != null) _dev.UsbDescriptors != null)
if(_outputPlugin.SupportedMediaTags.Contains(MediaTagType.USB_Descriptors)) if(outputFormat.SupportedMediaTags.Contains(MediaTagType.USB_Descriptors))
sidecar.BlockMedia[0].USB = new USBType sidecar.BlockMedia[0].USB = new USBType
{ {
ProductID = _dev.UsbProductId, ProductID = _dev.UsbProductId,
@@ -1052,7 +1053,7 @@ namespace Aaru.Core.Devices.Dumping
sense = _dev.AtapiIdentify(out cmdBuf, out _); sense = _dev.AtapiIdentify(out cmdBuf, out _);
if(!sense) if(!sense)
if(_outputPlugin.SupportedMediaTags.Contains(MediaTagType.ATAPI_IDENTIFY)) if(outputFormat.SupportedMediaTags.Contains(MediaTagType.ATAPI_IDENTIFY))
sidecar.BlockMedia[0].ATA = new ATAType sidecar.BlockMedia[0].ATA = new ATAType
{ {
Identify = new DumpType Identify = new DumpType
@@ -1068,7 +1069,7 @@ namespace Aaru.Core.Devices.Dumping
if(!sense) if(!sense)
{ {
if(_outputPlugin.SupportedMediaTags.Contains(MediaTagType.SCSI_INQUIRY)) if(outputFormat.SupportedMediaTags.Contains(MediaTagType.SCSI_INQUIRY))
sidecar.BlockMedia[0].SCSI = new SCSIType sidecar.BlockMedia[0].SCSI = new SCSIType
{ {
Inquiry = new DumpType Inquiry = new DumpType
@@ -1127,7 +1128,7 @@ namespace Aaru.Core.Devices.Dumping
if(!sense && if(!sense &&
!_dev.Error) !_dev.Error)
if(Modes.DecodeMode10(cmdBuf, _dev.ScsiType).HasValue) if(Modes.DecodeMode10(cmdBuf, _dev.ScsiType).HasValue)
if(_outputPlugin.SupportedMediaTags.Contains(MediaTagType.SCSI_MODESENSE_10)) if(outputFormat.SupportedMediaTags.Contains(MediaTagType.SCSI_MODESENSE_10))
sidecar.BlockMedia[0].SCSI.ModeSense10 = new DumpType sidecar.BlockMedia[0].SCSI.ModeSense10 = new DumpType
{ {
Image = _outputPath, Image = _outputPath,
@@ -1151,7 +1152,7 @@ namespace Aaru.Core.Devices.Dumping
if(!sense && if(!sense &&
!_dev.Error) !_dev.Error)
if(Modes.DecodeMode6(cmdBuf, _dev.ScsiType).HasValue) if(Modes.DecodeMode6(cmdBuf, _dev.ScsiType).HasValue)
if(_outputPlugin.SupportedMediaTags.Contains(MediaTagType.SCSI_MODESENSE_6)) if(outputFormat.SupportedMediaTags.Contains(MediaTagType.SCSI_MODESENSE_6))
sidecar.BlockMedia[0].SCSI.ModeSense = new DumpType sidecar.BlockMedia[0].SCSI.ModeSense = new DumpType
{ {
Image = _outputPath, Image = _outputPath,

View File

@@ -28,6 +28,7 @@
using System.Linq; using System.Linq;
using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Extents; using Aaru.CommonTypes.Extents;
using Aaru.CommonTypes.Interfaces;
using Aaru.CommonTypes.Structs.Devices.SCSI; using Aaru.CommonTypes.Structs.Devices.SCSI;
using Aaru.Console; using Aaru.Console;
using Aaru.Decoders.DVD; using Aaru.Decoders.DVD;
@@ -65,7 +66,8 @@ namespace Aaru.Core.Devices.Dumping
byte[] md6; byte[] md6;
byte[] md10; byte[] md10;
bool blankCheck; bool blankCheck;
bool newBlank = false; bool newBlank = false;
var outputFormat = _outputPlugin as IWritableImage;
if(_persistent) if(_persistent)
{ {
@@ -265,13 +267,13 @@ namespace Aaru.Core.Devices.Dumping
{ {
_resume.BadBlocks.Remove(badSector); _resume.BadBlocks.Remove(badSector);
extents.Add(badSector); extents.Add(badSector);
_outputPlugin.WriteSector(buffer, badSector); outputFormat.WriteSector(buffer, badSector);
UpdateStatus?.Invoke($"Correctly retried block {badSector} in pass {pass}."); UpdateStatus?.Invoke($"Correctly retried block {badSector} in pass {pass}.");
_dumpLog.WriteLine("Correctly retried block {0} in pass {1}.", badSector, pass); _dumpLog.WriteLine("Correctly retried block {0} in pass {1}.", badSector, pass);
} }
else if(runningPersistent) else if(runningPersistent)
{ {
_outputPlugin.WriteSector(buffer, badSector); outputFormat.WriteSector(buffer, badSector);
} }
} }
@@ -323,6 +325,7 @@ namespace Aaru.Core.Devices.Dumping
bool forward = true; bool forward = true;
bool sense; bool sense;
byte[] buffer; byte[] buffer;
var outputFormat = _outputPlugin as IWritableImage;
InitProgress?.Invoke(); InitProgress?.Invoke();
@@ -354,7 +357,7 @@ namespace Aaru.Core.Devices.Dumping
if(titleKey.HasValue) if(titleKey.HasValue)
{ {
_outputPlugin.WriteSectorTag(new[] outputFormat.WriteSectorTag(new[]
{ {
titleKey.Value.CMI titleKey.Value.CMI
}, missingKey, SectorTagType.DvdCmi); }, missingKey, SectorTagType.DvdCmi);
@@ -364,12 +367,12 @@ namespace Aaru.Core.Devices.Dumping
if((titleKey.Value.CMI & 0x80) >> 7 == 0 || if((titleKey.Value.CMI & 0x80) >> 7 == 0 ||
titleKey.Value.Key.All(k => k == 0)) titleKey.Value.Key.All(k => k == 0))
{ {
_outputPlugin.WriteSectorTag(new byte[] outputFormat.WriteSectorTag(new byte[]
{ {
0, 0, 0, 0, 0 0, 0, 0, 0, 0
}, missingKey, SectorTagType.DvdTitleKey); }, missingKey, SectorTagType.DvdTitleKey);
_outputPlugin.WriteSectorTag(new byte[] outputFormat.WriteSectorTag(new byte[]
{ {
0, 0, 0, 0, 0 0, 0, 0, 0, 0
}, missingKey, SectorTagType.DvdTitleKeyDecrypted); }, missingKey, SectorTagType.DvdTitleKeyDecrypted);
@@ -380,13 +383,13 @@ namespace Aaru.Core.Devices.Dumping
} }
else else
{ {
_outputPlugin.WriteSectorTag(titleKey.Value.Key, missingKey, SectorTagType.DvdTitleKey); outputFormat.WriteSectorTag(titleKey.Value.Key, missingKey, SectorTagType.DvdTitleKey);
_resume.MissingTitleKeys.Remove(missingKey); _resume.MissingTitleKeys.Remove(missingKey);
if(discKey != null) if(discKey != null)
{ {
CSS.DecryptTitleKey(0, discKey, titleKey.Value.Key, out buffer); CSS.DecryptTitleKey(0, discKey, titleKey.Value.Key, out buffer);
_outputPlugin.WriteSectorTag(buffer, missingKey, SectorTagType.DvdTitleKeyDecrypted); outputFormat.WriteSectorTag(buffer, missingKey, SectorTagType.DvdTitleKeyDecrypted);
} }
UpdateStatus?.Invoke($"Correctly retried title key {missingKey} in pass {pass}."); UpdateStatus?.Invoke($"Correctly retried title key {missingKey} in pass {pass}.");

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.Linq; using System.Linq;
using Aaru.CommonTypes.Extents; using Aaru.CommonTypes.Extents;
using Aaru.CommonTypes.Interfaces;
using Aaru.Console; using Aaru.Console;
using Aaru.Core.Logging; using Aaru.Core.Logging;
using Aaru.Decoders.SCSI; using Aaru.Decoders.SCSI;
@@ -52,6 +53,7 @@ namespace Aaru.Core.Devices.Dumping
ulong sectorSpeedStart = 0; ulong sectorSpeedStart = 0;
DateTime timeSpeedStart = DateTime.UtcNow; DateTime timeSpeedStart = DateTime.UtcNow;
bool canMediumScan = true; bool canMediumScan = true;
var outputFormat = _outputPlugin as IWritableImage;
InitProgress?.Invoke(); InitProgress?.Invoke();
@@ -217,7 +219,7 @@ namespace Aaru.Core.Devices.Dumping
mhddLog.Write(i, cmdDuration); mhddLog.Write(i, cmdDuration);
ibgLog.Write(i, currentSpeed * 1024); ibgLog.Write(i, currentSpeed * 1024);
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
_outputPlugin.WriteSectors(buffer, i, blocksToRead); outputFormat.WriteSectors(buffer, i, blocksToRead);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
extents.Add(i, blocksToRead, true); extents.Add(i, blocksToRead, true);
} }
@@ -232,7 +234,7 @@ namespace Aaru.Core.Devices.Dumping
// Write empty data // Write empty data
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
_outputPlugin.WriteSectors(new byte[blockSize * _skip], i, _skip); outputFormat.WriteSectors(new byte[blockSize * _skip], i, _skip);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
for(ulong b = i; b < i + _skip; b++) for(ulong b = i; b < i + _skip; b++)

View File

@@ -25,6 +25,7 @@
// ****************************************************************************/ // ****************************************************************************/
using Aaru.CommonTypes.Extents; using Aaru.CommonTypes.Extents;
using Aaru.CommonTypes.Interfaces;
using Schemas; using Schemas;
// ReSharper disable JoinDeclarationAndInitializer // ReSharper disable JoinDeclarationAndInitializer
@@ -48,7 +49,8 @@ namespace Aaru.Core.Devices.Dumping
bool recoveredError; bool recoveredError;
bool blankCheck; bool blankCheck;
byte[] buffer; byte[] buffer;
bool newBlank = false; bool newBlank = false;
var outputFormat = _outputPlugin as IWritableImage;
foreach(ulong badSector in tmpArray) foreach(ulong badSector in tmpArray)
{ {
@@ -83,7 +85,7 @@ namespace Aaru.Core.Devices.Dumping
_resume.BadBlocks.Remove(badSector); _resume.BadBlocks.Remove(badSector);
extents.Add(badSector); extents.Add(badSector);
_outputPlugin.WriteSector(buffer, badSector); outputFormat.WriteSector(buffer, badSector);
} }
if(newBlank) if(newBlank)

View File

@@ -88,6 +88,7 @@ namespace Aaru.Core.Devices.Dumping
bool byteAddressed = true; bool byteAddressed = true;
uint[] response; uint[] response;
bool supportsCmd23 = false; bool supportsCmd23 = false;
var outputFormat = _outputPlugin as IWritableImage;
Dictionary<MediaTagType, byte[]> mediaTags = new(); Dictionary<MediaTagType, byte[]> mediaTags = new();
@@ -422,7 +423,7 @@ namespace Aaru.Core.Devices.Dumping
bool ret = true; bool ret = true;
foreach(MediaTagType tag in mediaTags.Keys.Where(tag => !_outputPlugin.SupportedMediaTags.Contains(tag))) foreach(MediaTagType tag in mediaTags.Keys.Where(tag => !outputFormat.SupportedMediaTags.Contains(tag)))
{ {
ret = false; ret = false;
_dumpLog.WriteLine($"Output format does not support {tag}."); _dumpLog.WriteLine($"Output format does not support {tag}.");
@@ -448,7 +449,7 @@ namespace Aaru.Core.Devices.Dumping
var mhddLog = new MhddLog(_outputPrefix + ".mhddlog.bin", _dev, blocks, blockSize, blocksToRead, _private); var mhddLog = new MhddLog(_outputPrefix + ".mhddlog.bin", _dev, blocks, blockSize, blocksToRead, _private);
var ibgLog = new IbgLog(_outputPrefix + ".ibg", sdProfile); var ibgLog = new IbgLog(_outputPrefix + ".ibg", sdProfile);
ret = _outputPlugin.Create(_outputPath, ret = outputFormat.Create(_outputPath,
_dev.Type == DeviceType.SecureDigital ? MediaType.SecureDigital : MediaType.MMC, _dev.Type == DeviceType.SecureDigital ? MediaType.SecureDigital : MediaType.MMC,
_formatOptions, blocks, blockSize); _formatOptions, blocks, blockSize);
@@ -456,10 +457,10 @@ namespace Aaru.Core.Devices.Dumping
if(!ret) if(!ret)
{ {
_dumpLog.WriteLine("Error creating output image, not continuing."); _dumpLog.WriteLine("Error creating output image, not continuing.");
_dumpLog.WriteLine(_outputPlugin.ErrorMessage); _dumpLog.WriteLine(outputFormat.ErrorMessage);
StoppingErrorMessage?.Invoke("Error creating output image, not continuing." + Environment.NewLine + StoppingErrorMessage?.Invoke("Error creating output image, not continuing." + Environment.NewLine +
_outputPlugin.ErrorMessage); outputFormat.ErrorMessage);
return; return;
} }
@@ -487,7 +488,7 @@ namespace Aaru.Core.Devices.Dumping
} }
ret = ret =
_outputPlugin.WriteMediaTag(cid, outputFormat.WriteMediaTag(cid,
_dev.Type == DeviceType.SecureDigital ? MediaTagType.SD_CID _dev.Type == DeviceType.SecureDigital ? MediaTagType.SD_CID
: MediaTagType.MMC_CID); : MediaTagType.MMC_CID);
@@ -498,7 +499,7 @@ namespace Aaru.Core.Devices.Dumping
_dumpLog.WriteLine("Cannot write CID to output image."); _dumpLog.WriteLine("Cannot write CID to output image.");
StoppingErrorMessage?.Invoke("Cannot write CID to output image." + Environment.NewLine + StoppingErrorMessage?.Invoke("Cannot write CID to output image." + Environment.NewLine +
_outputPlugin.ErrorMessage); outputFormat.ErrorMessage);
return; return;
} }
@@ -507,7 +508,7 @@ namespace Aaru.Core.Devices.Dumping
if(csd != null) if(csd != null)
{ {
ret = ret =
_outputPlugin.WriteMediaTag(csd, outputFormat.WriteMediaTag(csd,
_dev.Type == DeviceType.SecureDigital ? MediaTagType.SD_CSD _dev.Type == DeviceType.SecureDigital ? MediaTagType.SD_CSD
: MediaTagType.MMC_CSD); : MediaTagType.MMC_CSD);
@@ -518,7 +519,7 @@ namespace Aaru.Core.Devices.Dumping
_dumpLog.WriteLine("Cannot write CSD to output image."); _dumpLog.WriteLine("Cannot write CSD to output image.");
StoppingErrorMessage?.Invoke("Cannot write CSD to output image." + Environment.NewLine + StoppingErrorMessage?.Invoke("Cannot write CSD to output image." + Environment.NewLine +
_outputPlugin.ErrorMessage); outputFormat.ErrorMessage);
return; return;
} }
@@ -526,7 +527,7 @@ namespace Aaru.Core.Devices.Dumping
if(ecsd != null) if(ecsd != null)
{ {
ret = _outputPlugin.WriteMediaTag(ecsd, MediaTagType.MMC_ExtendedCSD); ret = outputFormat.WriteMediaTag(ecsd, MediaTagType.MMC_ExtendedCSD);
// Cannot write Extended CSD to image // Cannot write Extended CSD to image
if(!ret && if(!ret &&
@@ -535,7 +536,7 @@ namespace Aaru.Core.Devices.Dumping
_dumpLog.WriteLine("Cannot write Extended CSD to output image."); _dumpLog.WriteLine("Cannot write Extended CSD to output image.");
StoppingErrorMessage?.Invoke("Cannot write Extended CSD to output image." + Environment.NewLine + StoppingErrorMessage?.Invoke("Cannot write Extended CSD to output image." + Environment.NewLine +
_outputPlugin.ErrorMessage); outputFormat.ErrorMessage);
return; return;
} }
@@ -544,7 +545,7 @@ namespace Aaru.Core.Devices.Dumping
if(ocr != null) if(ocr != null)
{ {
ret = ret =
_outputPlugin.WriteMediaTag(ocr, outputFormat.WriteMediaTag(ocr,
_dev.Type == DeviceType.SecureDigital ? MediaTagType.SD_OCR _dev.Type == DeviceType.SecureDigital ? MediaTagType.SD_OCR
: MediaTagType.MMC_OCR); : MediaTagType.MMC_OCR);
@@ -555,7 +556,7 @@ namespace Aaru.Core.Devices.Dumping
_dumpLog.WriteLine("Cannot write OCR to output image."); _dumpLog.WriteLine("Cannot write OCR to output image.");
StoppingErrorMessage?.Invoke("Cannot write OCR to output image." + Environment.NewLine + StoppingErrorMessage?.Invoke("Cannot write OCR to output image." + Environment.NewLine +
_outputPlugin.ErrorMessage); outputFormat.ErrorMessage);
return; return;
} }
@@ -563,7 +564,7 @@ namespace Aaru.Core.Devices.Dumping
if(scr != null) if(scr != null)
{ {
ret = _outputPlugin.WriteMediaTag(scr, MediaTagType.SD_SCR); ret = outputFormat.WriteMediaTag(scr, MediaTagType.SD_SCR);
// Cannot write SCR to image // Cannot write SCR to image
if(!ret && if(!ret &&
@@ -572,7 +573,7 @@ namespace Aaru.Core.Devices.Dumping
_dumpLog.WriteLine("Cannot write SCR to output image."); _dumpLog.WriteLine("Cannot write SCR to output image.");
StoppingErrorMessage?.Invoke("Cannot write SCR to output image." + Environment.NewLine + StoppingErrorMessage?.Invoke("Cannot write SCR to output image." + Environment.NewLine +
_outputPlugin.ErrorMessage); outputFormat.ErrorMessage);
return; return;
} }
@@ -635,7 +636,7 @@ namespace Aaru.Core.Devices.Dumping
mhddLog.Write(i, duration); mhddLog.Write(i, duration);
ibgLog.Write(i, currentSpeed * 1024); ibgLog.Write(i, currentSpeed * 1024);
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
_outputPlugin.WriteSectors(cmdBuf, i, blocksToRead); outputFormat.WriteSectors(cmdBuf, i, blocksToRead);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
extents.Add(i, blocksToRead, true); extents.Add(i, blocksToRead, true);
} }
@@ -653,7 +654,7 @@ namespace Aaru.Core.Devices.Dumping
ibgLog.Write(i, 0); ibgLog.Write(i, 0);
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
_outputPlugin.WriteSectors(new byte[blockSize * _skip], i, _skip); outputFormat.WriteSectors(new byte[blockSize * _skip], i, _skip);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
_dumpLog.WriteLine("Skipping {0} blocks from errored block {1}.", _skip, i); _dumpLog.WriteLine("Skipping {0} blocks from errored block {1}.", _skip, i);
i += _skip - blocksToRead; i += _skip - blocksToRead;
@@ -738,7 +739,7 @@ namespace Aaru.Core.Devices.Dumping
_resume.BadBlocks.Remove(badSector); _resume.BadBlocks.Remove(badSector);
extents.Add(badSector); extents.Add(badSector);
_outputPlugin.WriteSector(cmdBuf, badSector); outputFormat.WriteSector(cmdBuf, badSector);
} }
EndProgress?.Invoke(); EndProgress?.Invoke();
@@ -788,12 +789,12 @@ namespace Aaru.Core.Devices.Dumping
{ {
_resume.BadBlocks.Remove(badSector); _resume.BadBlocks.Remove(badSector);
extents.Add(badSector); extents.Add(badSector);
_outputPlugin.WriteSector(cmdBuf, badSector); outputFormat.WriteSector(cmdBuf, badSector);
UpdateStatus?.Invoke($"Correctly retried block {badSector} in pass {pass}."); UpdateStatus?.Invoke($"Correctly retried block {badSector} in pass {pass}.");
_dumpLog.WriteLine("Correctly retried block {0} in pass {1}.", badSector, pass); _dumpLog.WriteLine("Correctly retried block {0} in pass {1}.", badSector, pass);
} }
else if(runningPersistent) else if(runningPersistent)
_outputPlugin.WriteSector(cmdBuf, badSector); outputFormat.WriteSector(cmdBuf, badSector);
} }
if(pass < _retryPasses && if(pass < _retryPasses &&
@@ -816,7 +817,7 @@ namespace Aaru.Core.Devices.Dumping
currentTry.Extents = ExtentsConverter.ToMetadata(extents); currentTry.Extents = ExtentsConverter.ToMetadata(extents);
_outputPlugin.SetDumpHardware(_resume.Tries); outputFormat.SetDumpHardware(_resume.Tries);
// TODO: Drive info // TODO: Drive info
var metadata = new CommonTypes.Structs.ImageInfo var metadata = new CommonTypes.Structs.ImageInfo
@@ -825,17 +826,17 @@ namespace Aaru.Core.Devices.Dumping
ApplicationVersion = Version.GetVersion() ApplicationVersion = Version.GetVersion()
}; };
if(!_outputPlugin.SetMetadata(metadata)) if(!outputFormat.SetMetadata(metadata))
ErrorMessage?.Invoke("Error {0} setting metadata, continuing..." + Environment.NewLine + ErrorMessage?.Invoke("Error {0} setting metadata, continuing..." + Environment.NewLine +
_outputPlugin.ErrorMessage); outputFormat.ErrorMessage);
if(_preSidecar != null) if(_preSidecar != null)
_outputPlugin.SetCicmMetadata(_preSidecar); outputFormat.SetCicmMetadata(_preSidecar);
_dumpLog.WriteLine("Closing output file."); _dumpLog.WriteLine("Closing output file.");
UpdateStatus?.Invoke("Closing output file."); UpdateStatus?.Invoke("Closing output file.");
DateTime closeStart = DateTime.Now; DateTime closeStart = DateTime.Now;
_outputPlugin.Close(); outputFormat.Close();
DateTime closeEnd = DateTime.Now; DateTime closeEnd = DateTime.Now;
UpdateStatus?.Invoke($"Closed in {(closeEnd - closeStart).TotalSeconds} seconds."); UpdateStatus?.Invoke($"Closed in {(closeEnd - closeStart).TotalSeconds} seconds.");
_dumpLog.WriteLine("Closed in {0} seconds.", (closeEnd - closeStart).TotalSeconds); _dumpLog.WriteLine("Closed in {0} seconds.", (closeEnd - closeStart).TotalSeconds);

View File

@@ -72,6 +72,7 @@ namespace Aaru.Core.Devices.Dumping
double currentSpeed = 0; double currentSpeed = 0;
double maxSpeed = double.MinValue; double maxSpeed = double.MinValue;
double minSpeed = double.MaxValue; double minSpeed = double.MaxValue;
var outputFormat = _outputPlugin as IWritableImage;
if(DetectOS.GetRealPlatformID() != PlatformID.Win32NT) if(DetectOS.GetRealPlatformID() != PlatformID.Win32NT)
{ {
@@ -443,7 +444,7 @@ namespace Aaru.Core.Devices.Dumping
bool ret = true; bool ret = true;
foreach(MediaTagType tag in mediaTags.Keys.Where(tag => !_outputPlugin.SupportedMediaTags.Contains(tag))) foreach(MediaTagType tag in mediaTags.Keys.Where(tag => !outputFormat.SupportedMediaTags.Contains(tag)))
{ {
ret = false; ret = false;
_dumpLog.WriteLine($"Output format does not support {tag}."); _dumpLog.WriteLine($"Output format does not support {tag}.");
@@ -471,16 +472,16 @@ namespace Aaru.Core.Devices.Dumping
var mhddLog = new MhddLog(_outputPrefix + ".mhddlog.bin", _dev, blocks, blockSize, blocksToRead, _private); var mhddLog = new MhddLog(_outputPrefix + ".mhddlog.bin", _dev, blocks, blockSize, blocksToRead, _private);
var ibgLog = new IbgLog(_outputPrefix + ".ibg", 0x0010); var ibgLog = new IbgLog(_outputPrefix + ".ibg", 0x0010);
ret = _outputPlugin.Create(_outputPath, dskType, _formatOptions, blocks, blockSize); ret = outputFormat.Create(_outputPath, dskType, _formatOptions, blocks, blockSize);
// Cannot create image // Cannot create image
if(!ret) if(!ret)
{ {
_dumpLog.WriteLine("Error creating output image, not continuing."); _dumpLog.WriteLine("Error creating output image, not continuing.");
_dumpLog.WriteLine(_outputPlugin.ErrorMessage); _dumpLog.WriteLine(outputFormat.ErrorMessage);
StoppingErrorMessage?.Invoke("Error creating output image, not continuing." + Environment.NewLine + StoppingErrorMessage?.Invoke("Error creating output image, not continuing." + Environment.NewLine +
_outputPlugin.ErrorMessage); outputFormat.ErrorMessage);
return; return;
} }
@@ -500,7 +501,7 @@ namespace Aaru.Core.Devices.Dumping
extents == null) extents == null)
StoppingErrorMessage?.Invoke("Could not process resume file, not continuing..."); StoppingErrorMessage?.Invoke("Could not process resume file, not continuing...");
(_outputPlugin as IWritableOpticalImage).SetTracks(new List<Track> (outputFormat as IWritableOpticalImage).SetTracks(new List<Track>
{ {
new Track new Track
{ {
@@ -611,7 +612,7 @@ namespace Aaru.Core.Devices.Dumping
mhddLog.Write(i, cmdDuration); mhddLog.Write(i, cmdDuration);
ibgLog.Write(i, currentSpeed * 1024); ibgLog.Write(i, currentSpeed * 1024);
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
_outputPlugin.WriteSectors(readBuffer, i, blocksToRead); outputFormat.WriteSectors(readBuffer, i, blocksToRead);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
extents.Add(i, blocksToRead, true); extents.Add(i, blocksToRead, true);
} }
@@ -628,7 +629,7 @@ namespace Aaru.Core.Devices.Dumping
// Write empty data // Write empty data
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
_outputPlugin.WriteSectors(new byte[blockSize * _skip], i, _skip); outputFormat.WriteSectors(new byte[blockSize * _skip], i, _skip);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
for(ulong b = i; b < i + _skip; b++) for(ulong b = i; b < i + _skip; b++)
@@ -689,7 +690,7 @@ namespace Aaru.Core.Devices.Dumping
// Write empty data // Write empty data
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
_outputPlugin.WriteSectors(new byte[blockSize * blocksToRead], i, blocksToRead); outputFormat.WriteSectors(new byte[blockSize * blocksToRead], i, blocksToRead);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
blocksToRead = saveBlocksToRead; blocksToRead = saveBlocksToRead;
extents.Add(i, blocksToRead, true); extents.Add(i, blocksToRead, true);
@@ -733,7 +734,7 @@ namespace Aaru.Core.Devices.Dumping
// Write empty data // Write empty data
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
_outputPlugin.WriteSectors(new byte[blockSize * blocksToRead], middle + currentSector, blocksToRead); outputFormat.WriteSectors(new byte[blockSize * blocksToRead], middle + currentSector, blocksToRead);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
extents.Add(currentSector, blocksToRead, true); extents.Add(currentSector, blocksToRead, true);
@@ -807,7 +808,7 @@ namespace Aaru.Core.Devices.Dumping
mhddLog.Write(currentSector, cmdDuration); mhddLog.Write(currentSector, cmdDuration);
ibgLog.Write(currentSector, currentSpeed * 1024); ibgLog.Write(currentSector, currentSpeed * 1024);
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
_outputPlugin.WriteSectors(readBuffer, currentSector, blocksToRead); outputFormat.WriteSectors(readBuffer, currentSector, blocksToRead);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
extents.Add(currentSector, blocksToRead, true); extents.Add(currentSector, blocksToRead, true);
} }
@@ -821,7 +822,7 @@ namespace Aaru.Core.Devices.Dumping
// Write empty data // Write empty data
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
_outputPlugin.WriteSectors(new byte[blockSize * _skip], currentSector, _skip); outputFormat.WriteSectors(new byte[blockSize * _skip], currentSector, _skip);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
// TODO: Handle errors in video partition // TODO: Handle errors in video partition
@@ -943,7 +944,7 @@ namespace Aaru.Core.Devices.Dumping
_resume.BadBlocks.Remove(badSector); _resume.BadBlocks.Remove(badSector);
extents.Add(badSector); extents.Add(badSector);
_outputPlugin.WriteSector(readBuffer, badSector); outputFormat.WriteSector(readBuffer, badSector);
} }
EndProgress?.Invoke(); EndProgress?.Invoke();
@@ -1103,12 +1104,12 @@ namespace Aaru.Core.Devices.Dumping
{ {
_resume.BadBlocks.Remove(badSector); _resume.BadBlocks.Remove(badSector);
extents.Add(badSector); extents.Add(badSector);
_outputPlugin.WriteSector(readBuffer, badSector); outputFormat.WriteSector(readBuffer, badSector);
UpdateStatus?.Invoke($"Correctly retried block {badSector} in pass {pass}."); UpdateStatus?.Invoke($"Correctly retried block {badSector} in pass {pass}.");
_dumpLog.WriteLine("Correctly retried block {0} in pass {1}.", badSector, pass); _dumpLog.WriteLine("Correctly retried block {0} in pass {1}.", badSector, pass);
} }
else if(runningPersistent) else if(runningPersistent)
_outputPlugin.WriteSector(readBuffer, badSector); outputFormat.WriteSector(readBuffer, badSector);
} }
if(pass < _retryPasses && if(pass < _retryPasses &&
@@ -1163,7 +1164,7 @@ namespace Aaru.Core.Devices.Dumping
continue; continue;
} }
ret = _outputPlugin.WriteMediaTag(tag.Value, tag.Key); ret = outputFormat.WriteMediaTag(tag.Value, tag.Key);
if(ret || _force) if(ret || _force)
continue; continue;
@@ -1172,7 +1173,7 @@ namespace Aaru.Core.Devices.Dumping
_dumpLog.WriteLine($"Cannot write tag {tag.Key}."); _dumpLog.WriteLine($"Cannot write tag {tag.Key}.");
StoppingErrorMessage?.Invoke($"Cannot write tag {tag.Key}." + Environment.NewLine + StoppingErrorMessage?.Invoke($"Cannot write tag {tag.Key}." + Environment.NewLine +
_outputPlugin.ErrorMessage); outputFormat.ErrorMessage);
return; return;
} }
@@ -1184,7 +1185,7 @@ namespace Aaru.Core.Devices.Dumping
currentTry.Extents = ExtentsConverter.ToMetadata(extents); currentTry.Extents = ExtentsConverter.ToMetadata(extents);
_outputPlugin.SetDumpHardware(_resume.Tries); outputFormat.SetDumpHardware(_resume.Tries);
var metadata = new CommonTypes.Structs.ImageInfo var metadata = new CommonTypes.Structs.ImageInfo
{ {
@@ -1192,17 +1193,17 @@ namespace Aaru.Core.Devices.Dumping
ApplicationVersion = Version.GetVersion() ApplicationVersion = Version.GetVersion()
}; };
if(!_outputPlugin.SetMetadata(metadata)) if(!outputFormat.SetMetadata(metadata))
ErrorMessage?.Invoke("Error {0} setting metadata, continuing..." + Environment.NewLine + ErrorMessage?.Invoke("Error {0} setting metadata, continuing..." + Environment.NewLine +
_outputPlugin.ErrorMessage); outputFormat.ErrorMessage);
if(_preSidecar != null) if(_preSidecar != null)
_outputPlugin.SetCicmMetadata(_preSidecar); outputFormat.SetCicmMetadata(_preSidecar);
_dumpLog.WriteLine("Closing output file."); _dumpLog.WriteLine("Closing output file.");
UpdateStatus?.Invoke("Closing output file."); UpdateStatus?.Invoke("Closing output file.");
DateTime closeStart = DateTime.Now; DateTime closeStart = DateTime.Now;
_outputPlugin.Close(); outputFormat.Close();
DateTime closeEnd = DateTime.Now; DateTime closeEnd = DateTime.Now;
UpdateStatus?.Invoke($"Closed in {(closeEnd - closeStart).TotalSeconds} seconds."); UpdateStatus?.Invoke($"Closed in {(closeEnd - closeStart).TotalSeconds} seconds.");
_dumpLog.WriteLine("Closed in {0} seconds.", (closeEnd - closeStart).TotalSeconds); _dumpLog.WriteLine("Closed in {0} seconds.", (closeEnd - closeStart).TotalSeconds);

View File

@@ -69,7 +69,7 @@ namespace Aaru.Core.Media
byte[] sub, ulong sectorAddress, uint length, SubchannelLog subLog, byte[] sub, ulong sectorAddress, uint length, SubchannelLog subLog,
Dictionary<byte, string> isrcs, byte currentTrack, ref string mcn, Dictionary<byte, string> isrcs, byte currentTrack, ref string mcn,
Track[] tracks, HashSet<int> subchannelExtents, Track[] tracks, HashSet<int> subchannelExtents,
bool fixSubchannelPosition, IWritableImage outputPlugin, bool fixSubchannelPosition, IWritableOpticalImage outputPlugin,
bool fixSubchannel, bool fixSubchannelCrc, DumpLog dumpLog, bool fixSubchannel, bool fixSubchannelCrc, DumpLog dumpLog,
UpdateStatusHandler updateStatus, UpdateStatusHandler updateStatus,
Dictionary<byte, int> smallestPregapLbaPerTrack, bool dumping) Dictionary<byte, int> smallestPregapLbaPerTrack, bool dumping)

View File

@@ -1173,7 +1173,7 @@ namespace Aaru.Gui.ViewModels.Windows
bool indexesChanged = CompactDisc.WriteSubchannelToImage(MmcSubchannel.Raw, bool indexesChanged = CompactDisc.WriteSubchannelToImage(MmcSubchannel.Raw,
MmcSubchannel.Raw, sector, doneSectors, 1, null, isrcs, MmcSubchannel.Raw, sector, doneSectors, 1, null, isrcs,
(byte)track.Sequence, ref mcn, tracks.ToArray(), subchannelExtents, false, (byte)track.Sequence, ref mcn, tracks.ToArray(), subchannelExtents, false,
outputFormat, false, false, null, null, smallestPregapLbaPerTrack, false); outputFormat as IWritableOpticalImage, false, false, null, null, smallestPregapLbaPerTrack, false);
if(indexesChanged) if(indexesChanged)
outputOptical.SetTracks(tracks.ToList()); outputOptical.SetTracks(tracks.ToList());
@@ -1224,7 +1224,7 @@ namespace Aaru.Gui.ViewModels.Windows
bool indexesChanged = CompactDisc.WriteSubchannelToImage(MmcSubchannel.Raw, bool indexesChanged = CompactDisc.WriteSubchannelToImage(MmcSubchannel.Raw,
MmcSubchannel.Raw, sector, doneSectors, sectorsToDo, null, isrcs, MmcSubchannel.Raw, sector, doneSectors, sectorsToDo, null, isrcs,
(byte)track.Sequence, ref mcn, tracks.ToArray(), subchannelExtents, false, (byte)track.Sequence, ref mcn, tracks.ToArray(), subchannelExtents, false,
outputFormat, false, false, null, null, smallestPregapLbaPerTrack, false); outputFormat as IWritableOpticalImage, false, false, null, null, smallestPregapLbaPerTrack, false);
if(indexesChanged) if(indexesChanged)
outputOptical.SetTracks(tracks.ToList()); outputOptical.SetTracks(tracks.ToList());

View File

@@ -82,7 +82,7 @@ public sealed class Register : IPluginRegister
/// <inheritdoc /> /// <inheritdoc />
public List<Type> GetAllWritableImagePlugins() => Assembly.GetExecutingAssembly().GetTypes(). public List<Type> GetAllWritableImagePlugins() => Assembly.GetExecutingAssembly().GetTypes().
Where(t => t.GetInterfaces(). Where(t => t.GetInterfaces().
Contains(typeof(IWritableImage))). Contains(typeof(IBaseWritableImage))).
Where(t => t.IsClass).ToList(); Where(t => t.IsClass).ToList();
/// <inheritdoc /> /// <inheritdoc />

View File

@@ -141,7 +141,7 @@ namespace Aaru.Commands
table.AddColumn("Media image format"); table.AddColumn("Media image format");
foreach(KeyValuePair<string, IWritableImage> kvp in plugins.WritableImages) foreach(KeyValuePair<string, IBaseWritableImage> kvp in plugins.WritableImages)
if(verbose) if(verbose)
table.AddRow(kvp.Value.Id.ToString(), Markup.Escape(kvp.Value.Name)); table.AddRow(kvp.Value.Id.ToString(), Markup.Escape(kvp.Value.Name));
else else

View File

@@ -559,7 +559,7 @@ internal sealed class ConvertImageCommand : Command
return (int)ErrorNumber.CannotOpenFormat; return (int)ErrorNumber.CannotOpenFormat;
} }
List<IWritableImage> candidates = new(); List<IBaseWritableImage> candidates = new();
// Try extension // Try extension
if(string.IsNullOrEmpty(format)) if(string.IsNullOrEmpty(format))
@@ -591,7 +591,7 @@ internal sealed class ConvertImageCommand : Command
return (int)ErrorNumber.TooManyFormats; return (int)ErrorNumber.TooManyFormats;
} }
IWritableImage outputFormat = candidates[0]; IBaseWritableImage outputFormat = candidates[0];
if(verbose) if(verbose)
AaruConsole.VerboseWriteLine("Output image format: {0} ({1}).", outputFormat.Name, outputFormat.Id); AaruConsole.VerboseWriteLine("Output image format: {0} ({1}).", outputFormat.Name, outputFormat.Id);
@@ -761,7 +761,7 @@ internal sealed class ConvertImageCommand : Command
return; return;
} }
if(outputFormat.WriteMediaTag(tag, mediaTag)) if((outputFormat as IWritableImage)?.WriteMediaTag(tag, mediaTag) == true)
return; return;
if(force) if(force)
@@ -789,7 +789,7 @@ internal sealed class ConvertImageCommand : Command
{ {
if(!outputOptical.SetTracks(inputOptical.Tracks)) if(!outputOptical.SetTracks(inputOptical.Tracks))
{ {
AaruConsole.ErrorWriteLine("Error {0} sending tracks list to output image.", outputFormat.ErrorMessage); AaruConsole.ErrorWriteLine("Error {0} sending tracks list to output image.", outputOptical.ErrorMessage);
return (int)ErrorNumber.WriteError; return (int)ErrorNumber.WriteError;
} }
@@ -834,16 +834,16 @@ internal sealed class ConvertImageCommand : Command
if(useLong) if(useLong)
{ {
errno = sectorsToDo == 1 errno = sectorsToDo == 1
? inputFormat.ReadSectorLong(doneSectors + track.StartSector, ? inputOptical.ReadSectorLong(doneSectors + track.StartSector,
out sector) out sector)
: inputFormat.ReadSectorsLong(doneSectors + track.StartSector, : inputOptical.ReadSectorsLong(doneSectors + track.StartSector,
sectorsToDo, out sector); sectorsToDo, out sector);
if(errno == ErrorNumber.NoError) if(errno == ErrorNumber.NoError)
result = sectorsToDo == 1 result = sectorsToDo == 1
? outputFormat.WriteSectorLong(sector, ? outputOptical.WriteSectorLong(sector,
doneSectors + track.StartSector) doneSectors + track.StartSector)
: outputFormat.WriteSectorsLong(sector, : outputOptical.WriteSectorsLong(sector,
doneSectors + track.StartSector, sectorsToDo); doneSectors + track.StartSector, sectorsToDo);
else else
{ {
@@ -885,17 +885,17 @@ internal sealed class ConvertImageCommand : Command
if(!useLong || useNotLong) if(!useLong || useNotLong)
{ {
errno = sectorsToDo == 1 errno = sectorsToDo == 1
? inputFormat.ReadSector(doneSectors + track.StartSector, ? inputOptical.ReadSector(doneSectors + track.StartSector,
out sector) out sector)
: inputFormat.ReadSectors(doneSectors + track.StartSector, : inputOptical.ReadSectors(doneSectors + track.StartSector,
sectorsToDo, out sector); sectorsToDo, out sector);
if(errno == ErrorNumber.NoError) if(errno == ErrorNumber.NoError)
{ {
result = sectorsToDo == 1 result = sectorsToDo == 1
? outputFormat.WriteSector(sector, ? outputOptical.WriteSector(sector,
doneSectors + track.StartSector) doneSectors + track.StartSector)
: outputFormat.WriteSectors(sector, : outputOptical.WriteSectors(sector,
doneSectors + track.StartSector, sectorsToDo); doneSectors + track.StartSector, sectorsToDo);
} }
else else
@@ -922,13 +922,13 @@ internal sealed class ConvertImageCommand : Command
if(!result) if(!result)
if(force) if(force)
AaruConsole.ErrorWriteLine("Error {0} writing sector {1}, continuing...", AaruConsole.ErrorWriteLine("Error {0} writing sector {1}, continuing...",
outputFormat.ErrorMessage, outputOptical.ErrorMessage,
doneSectors + track.StartSector); doneSectors + track.StartSector);
else else
{ {
AaruConsole. AaruConsole.
ErrorWriteLine("Error {0} writing sector {1}, not continuing...", ErrorWriteLine("Error {0} writing sector {1}, not continuing...",
outputFormat.ErrorMessage, outputOptical.ErrorMessage,
doneSectors + track.StartSector); doneSectors + track.StartSector);
errno = ErrorNumber.WriteError; errno = ErrorNumber.WriteError;
@@ -976,12 +976,12 @@ internal sealed class ConvertImageCommand : Command
tracks[i].Indexes[idx.Key] = idx.Value; tracks[i].Indexes[idx.Key] = idx.Value;
} }
foreach(SectorTagType tag in inputFormat.Info.ReadableSectorTags.Where(t => t == SectorTagType.CdTrackIsrc). foreach(SectorTagType tag in inputOptical.Info.ReadableSectorTags.Where(t => t == SectorTagType.CdTrackIsrc).
OrderBy(t => t)) OrderBy(t => t))
{ {
foreach(Track track in tracks) foreach(Track track in tracks)
{ {
errno = inputFormat.ReadSectorTag(track.Sequence, tag, out byte[] isrc); errno = inputOptical.ReadSectorTag(track.Sequence, tag, out byte[] isrc);
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
continue; continue;
@@ -990,12 +990,12 @@ internal sealed class ConvertImageCommand : Command
} }
} }
foreach(SectorTagType tag in inputFormat.Info.ReadableSectorTags. foreach(SectorTagType tag in inputOptical.Info.ReadableSectorTags.
Where(t => t == SectorTagType.CdTrackFlags).OrderBy(t => t)) Where(t => t == SectorTagType.CdTrackFlags).OrderBy(t => t))
{ {
foreach(Track track in tracks) foreach(Track track in tracks)
{ {
errno = inputFormat.ReadSectorTag(track.Sequence, tag, out byte[] flags); errno = inputOptical.ReadSectorTag(track.Sequence, tag, out byte[] flags);
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
continue; continue;
@@ -1004,7 +1004,7 @@ internal sealed class ConvertImageCommand : Command
} }
} }
for(ulong s = 0; s < inputFormat.Info.Sectors; s++) for(ulong s = 0; s < inputOptical.Info.Sectors; s++)
{ {
if(s > int.MaxValue) if(s > int.MaxValue)
break; break;
@@ -1012,7 +1012,7 @@ internal sealed class ConvertImageCommand : Command
subchannelExtents.Add((int)s); subchannelExtents.Add((int)s);
} }
foreach(SectorTagType tag in inputFormat.Info.ReadableSectorTags.OrderBy(t => t).TakeWhile(tag => useLong)) foreach(SectorTagType tag in inputOptical.Info.ReadableSectorTags.OrderBy(t => t).TakeWhile(tag => useLong))
{ {
switch(tag) switch(tag)
{ {
@@ -1028,7 +1028,7 @@ internal sealed class ConvertImageCommand : Command
continue; continue;
} }
if(force && !outputFormat.SupportedSectorTags.Contains(tag)) if(force && !outputOptical.SupportedSectorTags.Contains(tag))
continue; continue;
errno = ErrorNumber.NoError; errno = ErrorNumber.NoError;
@@ -1054,7 +1054,7 @@ internal sealed class ConvertImageCommand : Command
{ {
case SectorTagType.CdTrackFlags: case SectorTagType.CdTrackFlags:
case SectorTagType.CdTrackIsrc: case SectorTagType.CdTrackIsrc:
errno = inputFormat.ReadSectorTag(track.Sequence, tag, out sector); errno = inputOptical.ReadSectorTag(track.Sequence, tag, out sector);
if(errno == ErrorNumber.NoData) if(errno == ErrorNumber.NoData)
{ {
@@ -1064,19 +1064,19 @@ internal sealed class ConvertImageCommand : Command
} }
if(errno == ErrorNumber.NoError) if(errno == ErrorNumber.NoError)
result = outputFormat.WriteSectorTag(sector, track.Sequence, tag); result = outputOptical.WriteSectorTag(sector, track.Sequence, tag);
else else
{ {
if(force) if(force)
{ {
AaruConsole.ErrorWriteLine("Error {0} writing tag, continuing...", AaruConsole.ErrorWriteLine("Error {0} writing tag, continuing...",
outputFormat.ErrorMessage); outputOptical.ErrorMessage);
continue; continue;
} }
AaruConsole.ErrorWriteLine("Error {0} writing tag, not continuing...", AaruConsole.ErrorWriteLine("Error {0} writing tag, not continuing...",
outputFormat.ErrorMessage); outputOptical.ErrorMessage);
errno = ErrorNumber.WriteError; errno = ErrorNumber.WriteError;
@@ -1086,12 +1086,12 @@ internal sealed class ConvertImageCommand : Command
if(!result) if(!result)
if(force) if(force)
AaruConsole.ErrorWriteLine("Error {0} writing tag, continuing...", AaruConsole.ErrorWriteLine("Error {0} writing tag, continuing...",
outputFormat.ErrorMessage); outputOptical.ErrorMessage);
else else
{ {
AaruConsole. AaruConsole.
ErrorWriteLine("Error {0} writing tag, not continuing...", ErrorWriteLine("Error {0} writing tag, not continuing...",
outputFormat.ErrorMessage); outputOptical.ErrorMessage);
errno = ErrorNumber.WriteError; errno = ErrorNumber.WriteError;
@@ -1121,7 +1121,7 @@ internal sealed class ConvertImageCommand : Command
if(sectorsToDo == 1) if(sectorsToDo == 1)
{ {
errno = inputFormat.ReadSectorTag(doneSectors + track.StartSector, tag, errno = inputOptical.ReadSectorTag(doneSectors + track.StartSector, tag,
out sector); out sector);
if(errno == ErrorNumber.NoError) if(errno == ErrorNumber.NoError)
@@ -1133,7 +1133,7 @@ internal sealed class ConvertImageCommand : Command
MmcSubchannel.Raw, sector, MmcSubchannel.Raw, sector,
doneSectors + track.StartSector, 1, null, isrcs, doneSectors + track.StartSector, 1, null, isrcs,
(byte)track.Sequence, ref mcn, tracks, (byte)track.Sequence, ref mcn, tracks,
subchannelExtents, fixSubchannelPosition, outputFormat, subchannelExtents, fixSubchannelPosition, outputOptical,
fixSubchannel, fixSubchannelCrc, null, null, fixSubchannel, fixSubchannelCrc, null, null,
smallestPregapLbaPerTrack, false); smallestPregapLbaPerTrack, false);
@@ -1144,7 +1144,7 @@ internal sealed class ConvertImageCommand : Command
} }
else else
result = result =
outputFormat.WriteSectorTag(sector, outputOptical.WriteSectorTag(sector,
doneSectors + track.StartSector, tag); doneSectors + track.StartSector, tag);
} }
else else
@@ -1167,7 +1167,7 @@ internal sealed class ConvertImageCommand : Command
} }
else else
{ {
errno = inputFormat.ReadSectorsTag(doneSectors + track.StartSector, errno = inputOptical.ReadSectorsTag(doneSectors + track.StartSector,
sectorsToDo, tag, out sector); sectorsToDo, tag, out sector);
if(errno == ErrorNumber.NoError) if(errno == ErrorNumber.NoError)
@@ -1179,7 +1179,7 @@ internal sealed class ConvertImageCommand : Command
MmcSubchannel.Raw, sector, MmcSubchannel.Raw, sector,
doneSectors + track.StartSector, sectorsToDo, null, doneSectors + track.StartSector, sectorsToDo, null,
isrcs, (byte)track.Sequence, ref mcn, tracks, isrcs, (byte)track.Sequence, ref mcn, tracks,
subchannelExtents, fixSubchannelPosition, outputFormat, subchannelExtents, fixSubchannelPosition, outputOptical,
fixSubchannel, fixSubchannelCrc, null, null, fixSubchannel, fixSubchannelCrc, null, null,
smallestPregapLbaPerTrack, false); smallestPregapLbaPerTrack, false);
@@ -1190,7 +1190,7 @@ internal sealed class ConvertImageCommand : Command
} }
else else
result = result =
outputFormat.WriteSectorsTag(sector, outputOptical.WriteSectorsTag(sector,
doneSectors + track.StartSector, sectorsToDo, tag); doneSectors + track.StartSector, sectorsToDo, tag);
} }
else else
@@ -1216,13 +1216,13 @@ internal sealed class ConvertImageCommand : Command
if(force) if(force)
AaruConsole. AaruConsole.
ErrorWriteLine("Error {0} writing tag for sector {1}, continuing...", ErrorWriteLine("Error {0} writing tag for sector {1}, continuing...",
outputFormat.ErrorMessage, outputOptical.ErrorMessage,
doneSectors + track.StartSector); doneSectors + track.StartSector);
else else
{ {
AaruConsole. AaruConsole.
ErrorWriteLine("Error {0} writing tag for sector {1}, not continuing...", ErrorWriteLine("Error {0} writing tag for sector {1}, not continuing...",
outputFormat.ErrorMessage, outputOptical.ErrorMessage,
doneSectors + track.StartSector); doneSectors + track.StartSector);
errno = ErrorNumber.WriteError; errno = ErrorNumber.WriteError;
@@ -1260,40 +1260,42 @@ internal sealed class ConvertImageCommand : Command
outputOptical.WriteMediaTag(Encoding.UTF8.GetBytes(mcn), MediaTagType.CD_MCN); outputOptical.WriteMediaTag(Encoding.UTF8.GetBytes(mcn), MediaTagType.CD_MCN);
// TODO: Progress // TODO: Progress
if((inputFormat.Info.MediaType == MediaType.CD || inputFormat.Info.MediaType == MediaType.CDDA || if((inputOptical.Info.MediaType == MediaType.CD || inputOptical.Info.MediaType == MediaType.CDDA ||
inputFormat.Info.MediaType == MediaType.CDG || inputFormat.Info.MediaType == MediaType.CDEG || inputOptical.Info.MediaType == MediaType.CDG || inputOptical.Info.MediaType == MediaType.CDEG ||
inputFormat.Info.MediaType == MediaType.CDI || inputFormat.Info.MediaType == MediaType.CDROM || inputOptical.Info.MediaType == MediaType.CDI || inputOptical.Info.MediaType == MediaType.CDROM ||
inputFormat.Info.MediaType == MediaType.CDROMXA || inputFormat.Info.MediaType == MediaType.CDPLUS || inputOptical.Info.MediaType == MediaType.CDROMXA || inputOptical.Info.MediaType == MediaType.CDPLUS ||
inputFormat.Info.MediaType == MediaType.CDMO || inputFormat.Info.MediaType == MediaType.CDR || inputOptical.Info.MediaType == MediaType.CDMO || inputOptical.Info.MediaType == MediaType.CDR ||
inputFormat.Info.MediaType == MediaType.CDRW || inputFormat.Info.MediaType == MediaType.CDMRW || inputOptical.Info.MediaType == MediaType.CDRW || inputOptical.Info.MediaType == MediaType.CDMRW ||
inputFormat.Info.MediaType == MediaType.VCD || inputFormat.Info.MediaType == MediaType.SVCD || inputOptical.Info.MediaType == MediaType.VCD || inputOptical.Info.MediaType == MediaType.SVCD ||
inputFormat.Info.MediaType == MediaType.PCD || inputFormat.Info.MediaType == MediaType.DTSCD || inputOptical.Info.MediaType == MediaType.PCD || inputOptical.Info.MediaType == MediaType.DTSCD ||
inputFormat.Info.MediaType == MediaType.CDMIDI || inputFormat.Info.MediaType == MediaType.CDV || inputOptical.Info.MediaType == MediaType.CDMIDI || inputOptical.Info.MediaType == MediaType.CDV ||
inputFormat.Info.MediaType == MediaType.CDIREADY || inputFormat.Info.MediaType == MediaType.FMTOWNS || inputOptical.Info.MediaType == MediaType.CDIREADY || inputOptical.Info.MediaType == MediaType.FMTOWNS ||
inputFormat.Info.MediaType == MediaType.PS1CD || inputFormat.Info.MediaType == MediaType.PS2CD || inputOptical.Info.MediaType == MediaType.PS1CD || inputOptical.Info.MediaType == MediaType.PS2CD ||
inputFormat.Info.MediaType == MediaType.MEGACD || inputFormat.Info.MediaType == MediaType.SATURNCD || inputOptical.Info.MediaType == MediaType.MEGACD || inputOptical.Info.MediaType == MediaType.SATURNCD ||
inputFormat.Info.MediaType == MediaType.GDROM || inputFormat.Info.MediaType == MediaType.GDR || inputOptical.Info.MediaType == MediaType.GDROM || inputOptical.Info.MediaType == MediaType.GDR ||
inputFormat.Info.MediaType == MediaType.MilCD || inputFormat.Info.MediaType == MediaType.SuperCDROM2 || inputOptical.Info.MediaType == MediaType.MilCD || inputOptical.Info.MediaType == MediaType.SuperCDROM2 ||
inputFormat.Info.MediaType == MediaType.JaguarCD || inputFormat.Info.MediaType == MediaType.ThreeDO || inputOptical.Info.MediaType == MediaType.JaguarCD || inputOptical.Info.MediaType == MediaType.ThreeDO ||
inputFormat.Info.MediaType == MediaType.PCFX || inputFormat.Info.MediaType == MediaType.NeoGeoCD || inputOptical.Info.MediaType == MediaType.PCFX || inputOptical.Info.MediaType == MediaType.NeoGeoCD ||
inputFormat.Info.MediaType == MediaType.CDTV || inputFormat.Info.MediaType == MediaType.CD32 || inputOptical.Info.MediaType == MediaType.CDTV || inputOptical.Info.MediaType == MediaType.CD32 ||
inputFormat.Info.MediaType == MediaType.Playdia || inputFormat.Info.MediaType == MediaType.Pippin || inputOptical.Info.MediaType == MediaType.Playdia || inputOptical.Info.MediaType == MediaType.Pippin ||
inputFormat.Info.MediaType == MediaType.VideoNow || inputOptical.Info.MediaType == MediaType.VideoNow ||
inputFormat.Info.MediaType == MediaType.VideoNowColor || inputOptical.Info.MediaType == MediaType.VideoNowColor ||
inputFormat.Info.MediaType == MediaType.VideoNowXp || inputFormat.Info.MediaType == MediaType.CVD) && inputOptical.Info.MediaType == MediaType.VideoNowXp || inputOptical.Info.MediaType == MediaType.CVD) &&
generateSubchannels) generateSubchannels)
{ {
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Generating subchannels...").IsIndeterminate(); ctx.AddTask("Generating subchannels...").IsIndeterminate();
CompactDisc.GenerateSubchannels(subchannelExtents, tracks, trackFlags, inputFormat.Info.Sectors, CompactDisc.GenerateSubchannels(subchannelExtents, tracks, trackFlags, inputOptical.Info.Sectors,
null, null, null, null, null, outputFormat); null, null, null, null, null, outputOptical);
}); });
} }
} }
else else
{ {
var outputMedia = outputFormat as IWritableImage;
if(inputTape == null || if(inputTape == null ||
outputTape == null || outputTape == null ||
!inputTape.IsTape) !inputTape.IsTape)
@@ -1306,9 +1308,9 @@ internal sealed class ConvertImageCommand : Command
AaruConsole.WriteLine("Setting geometry to {0} cylinders, {1} heads and {2} sectors per track", AaruConsole.WriteLine("Setting geometry to {0} cylinders, {1} heads and {2} sectors per track",
chs.cylinders, chs.heads, chs.sectors); chs.cylinders, chs.heads, chs.sectors);
if(!outputFormat.SetGeometry(chs.cylinders, chs.heads, chs.sectors)) if(!outputMedia.SetGeometry(chs.cylinders, chs.heads, chs.sectors))
AaruConsole.ErrorWriteLine("Error {0} setting geometry, image may be incorrect, continuing...", AaruConsole.ErrorWriteLine("Error {0} setting geometry, image may be incorrect, continuing...",
outputFormat.ErrorMessage); outputMedia.ErrorMessage);
} }
ErrorNumber errno = ErrorNumber.NoError; ErrorNumber errno = ErrorNumber.NoError;
@@ -1344,8 +1346,8 @@ internal sealed class ConvertImageCommand : Command
: inputFormat.ReadSectorsLong(doneSectors, sectorsToDo, out sector); : inputFormat.ReadSectorsLong(doneSectors, sectorsToDo, out sector);
if(errno == ErrorNumber.NoError) if(errno == ErrorNumber.NoError)
result = sectorsToDo == 1 ? outputFormat.WriteSectorLong(sector, doneSectors) result = sectorsToDo == 1 ? outputMedia.WriteSectorLong(sector, doneSectors)
: outputFormat.WriteSectorsLong(sector, doneSectors, sectorsToDo); : outputMedia.WriteSectorsLong(sector, doneSectors, sectorsToDo);
else else
{ {
result = true; result = true;
@@ -1369,8 +1371,8 @@ internal sealed class ConvertImageCommand : Command
: inputFormat.ReadSectors(doneSectors, sectorsToDo, out sector); : inputFormat.ReadSectors(doneSectors, sectorsToDo, out sector);
if(errno == ErrorNumber.NoError) if(errno == ErrorNumber.NoError)
result = sectorsToDo == 1 ? outputFormat.WriteSector(sector, doneSectors) result = sectorsToDo == 1 ? outputMedia.WriteSector(sector, doneSectors)
: outputFormat.WriteSectors(sector, doneSectors, sectorsToDo); : outputMedia.WriteSectors(sector, doneSectors, sectorsToDo);
else else
{ {
result = true; result = true;
@@ -1392,11 +1394,11 @@ internal sealed class ConvertImageCommand : Command
if(!result) if(!result)
if(force) if(force)
AaruConsole.ErrorWriteLine("Error {0} writing sector {1}, continuing...", AaruConsole.ErrorWriteLine("Error {0} writing sector {1}, continuing...",
outputFormat.ErrorMessage, doneSectors); outputMedia.ErrorMessage, doneSectors);
else else
{ {
AaruConsole.ErrorWriteLine("Error {0} writing sector {1}, not continuing...", AaruConsole.ErrorWriteLine("Error {0} writing sector {1}, not continuing...",
outputFormat.ErrorMessage, doneSectors); outputMedia.ErrorMessage, doneSectors);
errno = ErrorNumber.WriteError; errno = ErrorNumber.WriteError;
@@ -1425,7 +1427,7 @@ internal sealed class ConvertImageCommand : Command
continue; continue;
} }
if(force && !outputFormat.SupportedSectorTags.Contains(tag)) if(force && !outputMedia.SupportedSectorTags.Contains(tag))
continue; continue;
doneSectors = 0; doneSectors = 0;
@@ -1455,8 +1457,8 @@ internal sealed class ConvertImageCommand : Command
if(errno == ErrorNumber.NoError) if(errno == ErrorNumber.NoError)
result = sectorsToDo == 1 result = sectorsToDo == 1
? outputFormat.WriteSectorTag(sector, doneSectors, tag) ? outputMedia.WriteSectorTag(sector, doneSectors, tag)
: outputFormat.WriteSectorsTag(sector, doneSectors, sectorsToDo, : outputMedia.WriteSectorsTag(sector, doneSectors, sectorsToDo,
tag); tag);
else else
{ {
@@ -1478,12 +1480,12 @@ internal sealed class ConvertImageCommand : Command
if(!result) if(!result)
if(force) if(force)
AaruConsole.ErrorWriteLine("Error {0} writing sector {1}, continuing...", AaruConsole.ErrorWriteLine("Error {0} writing sector {1}, continuing...",
outputFormat.ErrorMessage, doneSectors); outputMedia.ErrorMessage, doneSectors);
else else
{ {
AaruConsole. AaruConsole.
ErrorWriteLine("Error {0} writing sector {1}, not continuing...", ErrorWriteLine("Error {0} writing sector {1}, not continuing...",
outputFormat.ErrorMessage, doneSectors); outputMedia.ErrorMessage, doneSectors);
errno = ErrorNumber.WriteError; errno = ErrorNumber.WriteError;

View File

@@ -87,7 +87,7 @@ namespace Aaru.Commands.Image
AaruConsole.WriteLine("Read/Write media images options:"); AaruConsole.WriteLine("Read/Write media images options:");
foreach(KeyValuePair<string, IWritableImage> kvp in plugins.WritableImages) foreach(KeyValuePair<string, IBaseWritableImage> kvp in plugins.WritableImages)
{ {
List<(string name, Type type, string description, object @default)> options = List<(string name, Type type, string description, object @default)> options =
kvp.Value.SupportedOptions.ToList(); kvp.Value.SupportedOptions.ToList();

View File

@@ -467,9 +467,9 @@ namespace Aaru.Commands.Media
if(isResponse) if(isResponse)
eject = true; eject = true;
PluginBase plugins = GetPluginBase.Instance; PluginBase plugins = GetPluginBase.Instance;
List<IWritableImage> candidates = new(); List<IBaseWritableImage> candidates = new();
string extension = Path.GetExtension(outputPath); string extension = Path.GetExtension(outputPath);
// Try extension // Try extension
if(string.IsNullOrEmpty(format)) if(string.IsNullOrEmpty(format))
@@ -642,7 +642,7 @@ namespace Aaru.Commands.Media
} }
plugins = GetPluginBase.Instance; plugins = GetPluginBase.Instance;
candidates = new List<IWritableImage>(); candidates = new List<IBaseWritableImage>();
// Try extension // Try extension
if(string.IsNullOrEmpty(format)) if(string.IsNullOrEmpty(format))
@@ -661,7 +661,7 @@ namespace Aaru.Commands.Media
StringComparison. StringComparison.
InvariantCultureIgnoreCase))); InvariantCultureIgnoreCase)));
IWritableImage outputFormat = candidates[0]; IBaseWritableImage outputFormat = candidates[0];
var dumpLog = new DumpLog(outputPrefix + ".log", dev, @private); var dumpLog = new DumpLog(outputPrefix + ".log", dev, @private);