mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
REFACTOR: Reformat code.
This commit is contained in:
@@ -51,7 +51,10 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
|
||||
internal class CompactDisc
|
||||
{
|
||||
internal static void Dump(Device dev, string devicePath, string outputPrefix, ushort retryPasses, bool force, bool dumpRaw, bool persistent, bool stopOnError, ref CICMMetadataType sidecar, ref MediaType dskType, bool separateSubchannel, ref Resume resume, ref DumpLog dumpLog, Alcohol120 alcohol, bool dumpLeadIn)
|
||||
internal static void Dump(Device dev, string devicePath, string outputPrefix, ushort retryPasses, bool force,
|
||||
bool dumpRaw, bool persistent, bool stopOnError, ref CICMMetadataType sidecar,
|
||||
ref MediaType dskType, bool separateSubchannel, ref Resume resume,
|
||||
ref DumpLog dumpLog, Alcohol120 alcohol, bool dumpLeadIn)
|
||||
{
|
||||
MHDDLog mhddLog;
|
||||
IBGLog ibgLog;
|
||||
@@ -76,10 +79,7 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
ulong errored = 0;
|
||||
DataFile dumpFile = null;
|
||||
bool aborted = false;
|
||||
System.Console.CancelKeyPress += (sender, e) =>
|
||||
{
|
||||
e.Cancel = aborted = true;
|
||||
};
|
||||
System.Console.CancelKeyPress += (sender, e) => { e.Cancel = aborted = true; };
|
||||
|
||||
// We discarded all discs that falsify a TOC before requesting a real TOC
|
||||
// No TOC, no CD (or an empty one)
|
||||
@@ -124,10 +124,13 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
}
|
||||
|
||||
dumpLog.WriteLine("Reading Disc Information");
|
||||
sense = dev.ReadDiscInformation(out cmdBuf, out senseBuf, MmcDiscInformationDataTypes.DiscInformation, dev.Timeout, out duration);
|
||||
sense = dev.ReadDiscInformation(out cmdBuf, out senseBuf,
|
||||
MmcDiscInformationDataTypes.DiscInformation, dev.Timeout,
|
||||
out duration);
|
||||
if(!sense)
|
||||
{
|
||||
Decoders.SCSI.MMC.DiscInformation.StandardDiscInformation? discInfo = Decoders.SCSI.MMC.DiscInformation.Decode000b(cmdBuf);
|
||||
Decoders.SCSI.MMC.DiscInformation.StandardDiscInformation? discInfo =
|
||||
Decoders.SCSI.MMC.DiscInformation.Decode000b(cmdBuf);
|
||||
if(discInfo.HasValue)
|
||||
{
|
||||
// If it is a read-only CD, check CD type if available
|
||||
@@ -172,21 +175,20 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
{
|
||||
foreach(FullTOC.TrackDataDescriptor track in toc.Value.TrackDescriptors)
|
||||
{
|
||||
if(track.TNO == 1 &&
|
||||
((TOC_CONTROL)(track.CONTROL & 0x0D) == TOC_CONTROL.DataTrack ||
|
||||
(TOC_CONTROL)(track.CONTROL & 0x0D) == TOC_CONTROL.DataTrackIncremental))
|
||||
if(track.TNO == 1 && ((TOC_CONTROL)(track.CONTROL & 0x0D) == TOC_CONTROL.DataTrack ||
|
||||
(TOC_CONTROL)(track.CONTROL & 0x0D) ==
|
||||
TOC_CONTROL.DataTrackIncremental))
|
||||
{
|
||||
allFirstSessionTracksAreAudio &= firstTrackLastSession != 1;
|
||||
}
|
||||
|
||||
if((TOC_CONTROL)(track.CONTROL & 0x0D) == TOC_CONTROL.DataTrack ||
|
||||
(TOC_CONTROL)(track.CONTROL & 0x0D) == TOC_CONTROL.DataTrackIncremental)
|
||||
(TOC_CONTROL)(track.CONTROL & 0x0D) == TOC_CONTROL.DataTrackIncremental)
|
||||
{
|
||||
hasDataTrack = true;
|
||||
allFirstSessionTracksAreAudio &= track.TNO >= firstTrackLastSession;
|
||||
}
|
||||
else
|
||||
hasAudioTrack = true;
|
||||
else hasAudioTrack = true;
|
||||
|
||||
hasVideoTrack |= track.ADR == 4;
|
||||
}
|
||||
@@ -194,12 +196,9 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
|
||||
if(hasDataTrack && hasAudioTrack && allFirstSessionTracksAreAudio && sessions == 2)
|
||||
dskType = MediaType.CDPLUS;
|
||||
if(!hasDataTrack && hasAudioTrack && sessions == 1)
|
||||
dskType = MediaType.CDDA;
|
||||
if(hasDataTrack && !hasAudioTrack && sessions == 1)
|
||||
dskType = MediaType.CDROM;
|
||||
if(hasVideoTrack && !hasDataTrack && sessions == 1)
|
||||
dskType = MediaType.CDV;
|
||||
if(!hasDataTrack && hasAudioTrack && sessions == 1) dskType = MediaType.CDDA;
|
||||
if(hasDataTrack && !hasAudioTrack && sessions == 1) dskType = MediaType.CDROM;
|
||||
if(hasVideoTrack && !hasDataTrack && sessions == 1) dskType = MediaType.CDV;
|
||||
}
|
||||
|
||||
dumpLog.WriteLine("Reading PMA");
|
||||
@@ -244,10 +243,8 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
blockSize = 2448;
|
||||
subSize = 96;
|
||||
int sectorSize;
|
||||
if(separateSubchannel)
|
||||
sectorSize = (int)(blockSize - subSize);
|
||||
else
|
||||
sectorSize = (int)blockSize;
|
||||
if(separateSubchannel) sectorSize = (int)(blockSize - subSize);
|
||||
else sectorSize = (int)blockSize;
|
||||
|
||||
if(toc == null)
|
||||
{
|
||||
@@ -271,15 +268,17 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
sessionsForAlcohol[trk.SessionNumber - 1].EndTrack = trk.POINT;
|
||||
}
|
||||
}
|
||||
|
||||
alcohol.AddSessions(sessionsForAlcohol);
|
||||
|
||||
foreach(FullTOC.TrackDataDescriptor trk in toc.Value.TrackDescriptors)
|
||||
{
|
||||
alcohol.AddTrack((byte)((trk.ADR << 4) & trk.CONTROL), trk.TNO, trk.POINT, trk.Min, trk.Sec, trk.Frame,
|
||||
trk.Zero, trk.PMIN, trk.PSEC, trk.PFRAME, trk.SessionNumber);
|
||||
trk.Zero, trk.PMIN, trk.PSEC, trk.PFRAME, trk.SessionNumber);
|
||||
}
|
||||
|
||||
FullTOC.TrackDataDescriptor[] sortedTracks = toc.Value.TrackDescriptors.OrderBy(track => track.POINT).ToArray();
|
||||
FullTOC.TrackDataDescriptor[] sortedTracks =
|
||||
toc.Value.TrackDescriptors.OrderBy(track => track.POINT).ToArray();
|
||||
List<TrackType> trackList = new List<TrackType>();
|
||||
long lastSector = 0;
|
||||
string lastMSF = null;
|
||||
@@ -291,22 +290,18 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
{
|
||||
TrackType track = new TrackType
|
||||
{
|
||||
Sequence = new TrackSequenceType
|
||||
{
|
||||
Session = trk.SessionNumber,
|
||||
TrackNumber = trk.POINT
|
||||
}
|
||||
Sequence = new TrackSequenceType {Session = trk.SessionNumber, TrackNumber = trk.POINT}
|
||||
};
|
||||
if((TOC_CONTROL)(trk.CONTROL & 0x0D) == TOC_CONTROL.DataTrack ||
|
||||
(TOC_CONTROL)(trk.CONTROL & 0x0D) == TOC_CONTROL.DataTrackIncremental)
|
||||
(TOC_CONTROL)(trk.CONTROL & 0x0D) == TOC_CONTROL.DataTrackIncremental)
|
||||
track.TrackType1 = TrackTypeTrackType.mode1;
|
||||
else
|
||||
track.TrackType1 = TrackTypeTrackType.audio;
|
||||
else track.TrackType1 = TrackTypeTrackType.audio;
|
||||
if(trk.PHOUR > 0)
|
||||
track.StartMSF = string.Format("{3:D2}:{0:D2}:{1:D2}:{2:D2}", trk.PMIN, trk.PSEC, trk.PFRAME, trk.PHOUR);
|
||||
else
|
||||
track.StartMSF = string.Format("{0:D2}:{1:D2}:{2:D2}", trk.PMIN, trk.PSEC, trk.PFRAME);
|
||||
track.StartSector = trk.PHOUR * 3600 * 75 + trk.PMIN * 60 * 75 + trk.PSEC * 75 + trk.PFRAME - 150;
|
||||
track.StartMSF = string.Format("{3:D2}:{0:D2}:{1:D2}:{2:D2}", trk.PMIN, trk.PSEC,
|
||||
trk.PFRAME, trk.PHOUR);
|
||||
else track.StartMSF = string.Format("{0:D2}:{1:D2}:{2:D2}", trk.PMIN, trk.PSEC, trk.PFRAME);
|
||||
track.StartSector = trk.PHOUR * 3600 * 75 + trk.PMIN * 60 * 75 + trk.PSEC * 75 + trk.PFRAME -
|
||||
150;
|
||||
trackList.Add(track);
|
||||
}
|
||||
else if(trk.POINT == 0xA2)
|
||||
@@ -346,17 +341,15 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
phour = trk.PHOUR;
|
||||
}
|
||||
|
||||
if(phour > 0)
|
||||
lastMSF = string.Format("{3:D2}:{0:D2}:{1:D2}:{2:D2}", pmin, psec, pframe, phour);
|
||||
else
|
||||
lastMSF = string.Format("{0:D2}:{1:D2}:{2:D2}", pmin, psec, pframe);
|
||||
if(phour > 0) lastMSF = string.Format("{3:D2}:{0:D2}:{1:D2}:{2:D2}", pmin, psec, pframe, phour);
|
||||
else lastMSF = string.Format("{0:D2}:{1:D2}:{2:D2}", pmin, psec, pframe);
|
||||
lastSector = phour * 3600 * 75 + pmin * 60 * 75 + psec * 75 + pframe - 150;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TrackType[] tracks = trackList.ToArray();
|
||||
for(int t = 1; t < tracks.Length;t++)
|
||||
for(int t = 1; t < tracks.Length; t++)
|
||||
{
|
||||
tracks[t - 1].EndSector = tracks[t].StartSector - 1;
|
||||
int phour = 0, pmin = 0, psec = 0;
|
||||
@@ -380,9 +373,9 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
|
||||
if(phour > 0)
|
||||
tracks[t - 1].EndMSF = string.Format("{3:D2}:{0:D2}:{1:D2}:{2:D2}", pmin, psec, pframe, phour);
|
||||
else
|
||||
tracks[t - 1].EndMSF = string.Format("{0:D2}:{1:D2}:{2:D2}", pmin, psec, pframe);
|
||||
else tracks[t - 1].EndMSF = string.Format("{0:D2}:{1:D2}:{2:D2}", pmin, psec, pframe);
|
||||
}
|
||||
|
||||
tracks[tracks.Length - 1].EndMSF = lastMSF;
|
||||
tracks[tracks.Length - 1].EndSector = lastSector;
|
||||
blocks = (ulong)(lastSector + 1);
|
||||
@@ -393,23 +386,21 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
return;
|
||||
}
|
||||
|
||||
if(dumpRaw)
|
||||
{
|
||||
throw new NotImplementedException("Raw CD dumping not yet implemented");
|
||||
}
|
||||
if(dumpRaw) { throw new NotImplementedException("Raw CD dumping not yet implemented"); }
|
||||
else
|
||||
{
|
||||
// TODO: Check subchannel capabilities
|
||||
readcd = !dev.ReadCd(out readBuffer, out senseBuf, 0, blockSize, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders,
|
||||
true, true, MmcErrorField.None, MmcSubchannel.Raw, dev.Timeout, out duration);
|
||||
readcd = !dev.ReadCd(out readBuffer, out senseBuf, 0, blockSize, 1, MmcSectorTypes.AllTypes, false,
|
||||
false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None,
|
||||
MmcSubchannel.Raw, dev.Timeout, out duration);
|
||||
|
||||
if(readcd)
|
||||
DicConsole.WriteLine("Using MMC READ CD command.");
|
||||
if(readcd) DicConsole.WriteLine("Using MMC READ CD command.");
|
||||
}
|
||||
|
||||
DumpHardwareType currentTry = null;
|
||||
ExtentsULong extents = null;
|
||||
ResumeSupport.Process(true, true, blocks, dev.Manufacturer, dev.Model, dev.Serial, dev.PlatformID, ref resume, ref currentTry, ref extents);
|
||||
ResumeSupport.Process(true, true, blocks, dev.Manufacturer, dev.Model, dev.Serial, dev.PlatformID,
|
||||
ref resume, ref currentTry, ref extents);
|
||||
if(currentTry == null || extents == null)
|
||||
throw new Exception("Could not process resume file, not continuing...");
|
||||
|
||||
@@ -503,14 +494,13 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
{
|
||||
if(readcd)
|
||||
{
|
||||
sense = dev.ReadCd(out readBuffer, out senseBuf, 0, blockSize, blocksToRead, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders,
|
||||
true, true, MmcErrorField.None, MmcSubchannel.Raw, dev.Timeout, out duration);
|
||||
if(dev.Error || sense)
|
||||
blocksToRead /= 2;
|
||||
sense = dev.ReadCd(out readBuffer, out senseBuf, 0, blockSize, blocksToRead,
|
||||
MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true,
|
||||
true, MmcErrorField.None, MmcSubchannel.Raw, dev.Timeout, out duration);
|
||||
if(dev.Error || sense) blocksToRead /= 2;
|
||||
}
|
||||
|
||||
if(!dev.Error || blocksToRead == 1)
|
||||
break;
|
||||
if(!dev.Error || blocksToRead == 1) break;
|
||||
}
|
||||
|
||||
if(dev.Error || sense)
|
||||
@@ -532,17 +522,14 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
dumpFile = new DataFile(outputPrefix + ".bin");
|
||||
alcohol.SetExtension(".bin");
|
||||
DataFile subFile = null;
|
||||
if(separateSubchannel)
|
||||
subFile = new DataFile(outputPrefix + ".sub");
|
||||
if(separateSubchannel) subFile = new DataFile(outputPrefix + ".sub");
|
||||
mhddLog = new MHDDLog(outputPrefix + ".mhddlog.bin", dev, blocks, blockSize, blocksToRead);
|
||||
ibgLog = new IBGLog(outputPrefix + ".ibg", 0x0008);
|
||||
|
||||
dumpFile.Seek(resume.NextBlock, (ulong)sectorSize);
|
||||
if(separateSubchannel)
|
||||
subFile.Seek(resume.NextBlock, subSize);
|
||||
if(separateSubchannel) subFile.Seek(resume.NextBlock, subSize);
|
||||
|
||||
if(resume.NextBlock > 0)
|
||||
dumpLog.WriteLine("Resuming from block {0}.", resume.NextBlock);
|
||||
if(resume.NextBlock > 0) dumpLog.WriteLine("Resuming from block {0}.", resume.NextBlock);
|
||||
|
||||
start = DateTime.UtcNow;
|
||||
for(int t = 0; t < tracks.Count(); t++)
|
||||
@@ -560,11 +547,7 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
tracks[t].Size = (tracks[t].EndSector - tracks[t].StartSector + 1) * sectorSize;
|
||||
tracks[t].SubChannel = new SubChannelType
|
||||
{
|
||||
Image = new ImageType
|
||||
{
|
||||
format = "rw_raw",
|
||||
offsetSpecified = true
|
||||
},
|
||||
Image = new ImageType {format = "rw_raw", offsetSpecified = true},
|
||||
Size = (tracks[t].EndSector - tracks[t].StartSector + 1) * subSize
|
||||
};
|
||||
if(separateSubchannel)
|
||||
@@ -578,8 +561,9 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
tracks[t].SubChannel.Image.Value = tracks[t].Image.Value;
|
||||
}
|
||||
|
||||
alcohol.SetTrackSizes((byte)(t + 1), sectorSize, tracks[t].StartSector, dumpFile.Position, (tracks[t].EndSector - tracks[t].StartSector + 1));
|
||||
|
||||
alcohol.SetTrackSizes((byte)(t + 1), sectorSize, tracks[t].StartSector, dumpFile.Position,
|
||||
(tracks[t].EndSector - tracks[t].StartSector + 1));
|
||||
|
||||
bool checkedDataFormat = false;
|
||||
|
||||
for(ulong i = resume.NextBlock; i <= (ulong)tracks[t].EndSector; i += blocksToRead)
|
||||
@@ -597,18 +581,18 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
blocksToRead = (uint)((ulong)tracks[t].EndSector + 1 - i);
|
||||
|
||||
#pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator
|
||||
if(currentSpeed > maxSpeed && currentSpeed != 0)
|
||||
maxSpeed = currentSpeed;
|
||||
if(currentSpeed < minSpeed && currentSpeed != 0)
|
||||
minSpeed = currentSpeed;
|
||||
if(currentSpeed > maxSpeed && currentSpeed != 0) maxSpeed = currentSpeed;
|
||||
if(currentSpeed < minSpeed && currentSpeed != 0) minSpeed = currentSpeed;
|
||||
#pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator
|
||||
|
||||
DicConsole.Write("\rReading sector {0} of {1} at track {3} ({2:F3} MiB/sec.)", i, blocks, currentSpeed, t + 1);
|
||||
DicConsole.Write("\rReading sector {0} of {1} at track {3} ({2:F3} MiB/sec.)", i, blocks,
|
||||
currentSpeed, t + 1);
|
||||
|
||||
if(readcd)
|
||||
{
|
||||
sense = dev.ReadCd(out readBuffer, out senseBuf, (uint)i, blockSize, blocksToRead, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders,
|
||||
true, true, MmcErrorField.None, MmcSubchannel.Raw, dev.Timeout, out cmdDuration);
|
||||
sense = dev.ReadCd(out readBuffer, out senseBuf, (uint)i, blockSize, blocksToRead,
|
||||
MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true,
|
||||
true, MmcErrorField.None, MmcSubchannel.Raw, dev.Timeout, out cmdDuration);
|
||||
totalDuration += cmdDuration;
|
||||
}
|
||||
|
||||
@@ -625,14 +609,12 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
subFile.Write(readBuffer, (int)(sectorSize + b * blockSize), (int)subSize);
|
||||
}
|
||||
}
|
||||
else
|
||||
dumpFile.Write(readBuffer);
|
||||
else dumpFile.Write(readBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Reset device after X errors
|
||||
if(stopOnError)
|
||||
return; // TODO: Return more cleanly
|
||||
if(stopOnError) return; // TODO: Return more cleanly
|
||||
|
||||
// Write empty data
|
||||
if(separateSubchannel)
|
||||
@@ -640,17 +622,15 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
dumpFile.Write(new byte[sectorSize * blocksToRead]);
|
||||
subFile.Write(new byte[subSize * blocksToRead]);
|
||||
}
|
||||
else
|
||||
dumpFile.Write(new byte[blockSize * blocksToRead]);
|
||||
else dumpFile.Write(new byte[blockSize * blocksToRead]);
|
||||
|
||||
errored += blocksToRead;
|
||||
for(ulong b = i; b < i + blocksToRead; b++)
|
||||
resume.BadBlocks.Add(b);
|
||||
DicConsole.DebugWriteLine("Dump-Media", "READ error:\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
|
||||
if(cmdDuration < 500)
|
||||
mhddLog.Write(i, 65535);
|
||||
else
|
||||
mhddLog.Write(i, cmdDuration);
|
||||
for(ulong b = i; b < i + blocksToRead; b++) resume.BadBlocks.Add(b);
|
||||
|
||||
DicConsole.DebugWriteLine("Dump-Media", "READ error:\n{0}",
|
||||
Decoders.SCSI.Sense.PrettifySense(senseBuf));
|
||||
if(cmdDuration < 500) mhddLog.Write(i, 65535);
|
||||
else mhddLog.Write(i, cmdDuration);
|
||||
|
||||
ibgLog.Write(i, 0);
|
||||
dumpLog.WriteLine("Error reading {0} sectors from sector {1}.", blocksToRead, i);
|
||||
@@ -660,7 +640,10 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
{
|
||||
byte[] sync = new byte[12];
|
||||
Array.Copy(readBuffer, 0, sync, 0, 12);
|
||||
if(sync.SequenceEqual(new byte[] { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 }))
|
||||
if(sync.SequenceEqual(new byte[]
|
||||
{
|
||||
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00
|
||||
}))
|
||||
{
|
||||
switch(readBuffer[15])
|
||||
{
|
||||
@@ -711,21 +694,25 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
case TrackTypeTrackType.mode0:
|
||||
trkType = ImagePlugins.TrackType.Data;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
default: throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
alcohol.SetTrackTypes((byte)(t + 1), trkType,
|
||||
separateSubchannel ? TrackSubchannelType.None : TrackSubchannelType.RawInterleaved);
|
||||
separateSubchannel
|
||||
? TrackSubchannelType.None
|
||||
: TrackSubchannelType.RawInterleaved);
|
||||
}
|
||||
|
||||
DicConsole.WriteLine();
|
||||
end = DateTime.UtcNow;
|
||||
mhddLog.Close();
|
||||
#pragma warning disable IDE0004 // Remove Unnecessary Cast
|
||||
ibgLog.Close(dev, blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024, (((double)blockSize * (double)(blocks + 1)) / 1024) / (totalDuration / 1000), devicePath);
|
||||
ibgLog.Close(dev, blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
|
||||
(((double)blockSize * (double)(blocks + 1)) / 1024) / (totalDuration / 1000), devicePath);
|
||||
#pragma warning restore IDE0004 // Remove Unnecessary Cast
|
||||
dumpLog.WriteLine("Dump finished in {0} seconds.", (end - start).TotalSeconds);
|
||||
dumpLog.WriteLine("Average dump speed {0:F3} KiB/sec.", (((double)blockSize * (double)(blocks + 1)) / 1024) / (totalDuration / 1000));
|
||||
dumpLog.WriteLine("Average dump speed {0:F3} KiB/sec.",
|
||||
(((double)blockSize * (double)(blocks + 1)) / 1024) / (totalDuration / 1000));
|
||||
|
||||
#region Compact Disc Error handling
|
||||
if(resume.BadBlocks.Count > 0 && !aborted)
|
||||
@@ -734,7 +721,7 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
bool forward = true;
|
||||
bool runningPersistent = false;
|
||||
|
||||
cdRepeatRetry:
|
||||
cdRepeatRetry:
|
||||
ulong[] tmpArray = resume.BadBlocks.ToArray();
|
||||
foreach(ulong badSector in tmpArray)
|
||||
{
|
||||
@@ -747,12 +734,15 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
|
||||
double cmdDuration = 0;
|
||||
|
||||
DicConsole.Write("\rRetrying sector {0}, pass {1}, {3}{2}", badSector, pass + 1, forward ? "forward" : "reverse", runningPersistent ? "recovering partial data, " : "");
|
||||
DicConsole.Write("\rRetrying sector {0}, pass {1}, {3}{2}", badSector, pass + 1,
|
||||
forward ? "forward" : "reverse",
|
||||
runningPersistent ? "recovering partial data, " : "");
|
||||
|
||||
if(readcd)
|
||||
{
|
||||
sense = dev.ReadCd(out readBuffer, out senseBuf, (uint)badSector, blockSize, blocksToRead, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders,
|
||||
true, true, MmcErrorField.None, MmcSubchannel.Raw, dev.Timeout, out cmdDuration);
|
||||
sense = dev.ReadCd(out readBuffer, out senseBuf, (uint)badSector, blockSize, blocksToRead,
|
||||
MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true,
|
||||
true, MmcErrorField.None, MmcSubchannel.Raw, dev.Timeout, out cmdDuration);
|
||||
totalDuration += cmdDuration;
|
||||
}
|
||||
|
||||
@@ -764,14 +754,13 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
extents.Add(badSector);
|
||||
dumpLog.WriteLine("Correctly retried sector {0} in pass {1}.", badSector, pass);
|
||||
}
|
||||
|
||||
|
||||
if(separateSubchannel)
|
||||
{
|
||||
dumpFile.WriteAt(readBuffer, badSector, (uint)sectorSize, 0, sectorSize);
|
||||
subFile.WriteAt(readBuffer, badSector, subSize, sectorSize, (int)subSize);
|
||||
}
|
||||
else
|
||||
dumpFile.WriteAt(readBuffer, badSector, blockSize);
|
||||
else dumpFile.WriteAt(readBuffer, badSector, blockSize);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -791,47 +780,39 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
|
||||
if(!runningPersistent && persistent)
|
||||
{
|
||||
sense = dev.ModeSense6(out readBuffer, out senseBuf, false, ScsiModeSensePageControl.Current, 0x01, dev.Timeout, out duration);
|
||||
sense = dev.ModeSense6(out readBuffer, out senseBuf, false, ScsiModeSensePageControl.Current, 0x01,
|
||||
dev.Timeout, out duration);
|
||||
if(sense)
|
||||
{
|
||||
sense = dev.ModeSense10(out readBuffer, out senseBuf, false, ScsiModeSensePageControl.Current, 0x01, dev.Timeout, out duration);
|
||||
if(!sense)
|
||||
currentMode = Decoders.SCSI.Modes.DecodeMode10(readBuffer, dev.SCSIType);
|
||||
sense = dev.ModeSense10(out readBuffer, out senseBuf, false, ScsiModeSensePageControl.Current,
|
||||
0x01, dev.Timeout, out duration);
|
||||
if(!sense) currentMode = Decoders.SCSI.Modes.DecodeMode10(readBuffer, dev.SCSIType);
|
||||
}
|
||||
else
|
||||
currentMode = Decoders.SCSI.Modes.DecodeMode6(readBuffer, dev.SCSIType);
|
||||
else currentMode = Decoders.SCSI.Modes.DecodeMode6(readBuffer, dev.SCSIType);
|
||||
|
||||
if(currentMode.HasValue)
|
||||
currentModePage = currentMode.Value.Pages[0];
|
||||
if(currentMode.HasValue) currentModePage = currentMode.Value.Pages[0];
|
||||
|
||||
Decoders.SCSI.Modes.ModePage_01_MMC pgMMC = new Decoders.SCSI.Modes.ModePage_01_MMC
|
||||
{
|
||||
PS = false,
|
||||
ReadRetryCount = 255,
|
||||
Parameter = 0x20
|
||||
};
|
||||
Decoders.SCSI.Modes.ModePage_01_MMC pgMMC =
|
||||
new Decoders.SCSI.Modes.ModePage_01_MMC {PS = false, ReadRetryCount = 255, Parameter = 0x20};
|
||||
Decoders.SCSI.Modes.DecodedMode md = new Decoders.SCSI.Modes.DecodedMode
|
||||
{
|
||||
Header = new Decoders.SCSI.Modes.ModeHeader(),
|
||||
Pages = new Decoders.SCSI.Modes.ModePage[]
|
||||
{
|
||||
new Decoders.SCSI.Modes.ModePage
|
||||
{
|
||||
Page = 0x01,
|
||||
Subpage = 0x00,
|
||||
PageResponse = Decoders.SCSI.Modes.EncodeModePage_01_MMC(pgMMC)
|
||||
}
|
||||
}
|
||||
{
|
||||
new Decoders.SCSI.Modes.ModePage
|
||||
{
|
||||
Page = 0x01,
|
||||
Subpage = 0x00,
|
||||
PageResponse = Decoders.SCSI.Modes.EncodeModePage_01_MMC(pgMMC)
|
||||
}
|
||||
}
|
||||
};
|
||||
md6 = Decoders.SCSI.Modes.EncodeMode6(md, dev.SCSIType);
|
||||
md10 = Decoders.SCSI.Modes.EncodeMode10(md, dev.SCSIType);
|
||||
|
||||
dumpLog.WriteLine("Sending MODE SELECT to drive.");
|
||||
sense = dev.ModeSelect(md6, out senseBuf, true, false, dev.Timeout, out duration);
|
||||
if(sense)
|
||||
{
|
||||
sense = dev.ModeSelect10(md10, out senseBuf, true, false, dev.Timeout, out duration);
|
||||
}
|
||||
if(sense) { sense = dev.ModeSelect10(md10, out senseBuf, true, false, dev.Timeout, out duration); }
|
||||
|
||||
runningPersistent = true;
|
||||
if(!sense && !dev.Error)
|
||||
@@ -845,32 +826,26 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
Decoders.SCSI.Modes.DecodedMode md = new Decoders.SCSI.Modes.DecodedMode
|
||||
{
|
||||
Header = new Decoders.SCSI.Modes.ModeHeader(),
|
||||
Pages = new Decoders.SCSI.Modes.ModePage[]
|
||||
{
|
||||
currentModePage.Value
|
||||
}
|
||||
Pages = new Decoders.SCSI.Modes.ModePage[] {currentModePage.Value}
|
||||
};
|
||||
md6 = Decoders.SCSI.Modes.EncodeMode6(md, dev.SCSIType);
|
||||
md10 = Decoders.SCSI.Modes.EncodeMode10(md, dev.SCSIType);
|
||||
|
||||
dumpLog.WriteLine("Sending MODE SELECT to drive.");
|
||||
sense = dev.ModeSelect(md6, out senseBuf, true, false, dev.Timeout, out duration);
|
||||
if(sense)
|
||||
{
|
||||
sense = dev.ModeSelect10(md10, out senseBuf, true, false, dev.Timeout, out duration);
|
||||
}
|
||||
if(sense) { sense = dev.ModeSelect10(md10, out senseBuf, true, false, dev.Timeout, out duration); }
|
||||
}
|
||||
|
||||
DicConsole.WriteLine();
|
||||
}
|
||||
#endregion Compact Disc Error handling
|
||||
|
||||
resume.BadBlocks.Sort();
|
||||
currentTry.Extents = Metadata.ExtentsConverter.ToMetadata(extents);
|
||||
|
||||
dataChk = new Checksum();
|
||||
dumpFile.Seek(0, SeekOrigin.Begin);
|
||||
if(separateSubchannel)
|
||||
subFile.Seek(0, SeekOrigin.Begin);
|
||||
if(separateSubchannel) subFile.Seek(0, SeekOrigin.Begin);
|
||||
blocksToRead = 500;
|
||||
|
||||
dumpLog.WriteLine("Checksum starts.");
|
||||
@@ -890,7 +865,8 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
if(((ulong)tracks[t].EndSector + 1 - i) < blocksToRead)
|
||||
blocksToRead = (uint)((ulong)tracks[t].EndSector + 1 - i);
|
||||
|
||||
DicConsole.Write("\rChecksumming sector {0} of {1} at track {3} ({2:F3} MiB/sec.)", i, blocks, currentSpeed, t + 1);
|
||||
DicConsole.Write("\rChecksumming sector {0} of {1} at track {3} ({2:F3} MiB/sec.)", i, blocks,
|
||||
currentSpeed, t + 1);
|
||||
|
||||
DateTime chkStart = DateTime.UtcNow;
|
||||
byte[] dataToCheck = new byte[blockSize * blocksToRead];
|
||||
@@ -913,6 +889,7 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
dataChk.Update(dataToCheck);
|
||||
trkChk.Update(dataToCheck);
|
||||
}
|
||||
|
||||
DateTime chkEnd = DateTime.UtcNow;
|
||||
|
||||
double chkDuration = (chkEnd - chkStart).TotalMilliseconds;
|
||||
@@ -924,16 +901,16 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
}
|
||||
|
||||
tracks[t].Checksums = trkChk.End().ToArray();
|
||||
if(separateSubchannel)
|
||||
tracks[t].SubChannel.Checksums = subChk.End().ToArray();
|
||||
else
|
||||
tracks[t].SubChannel.Checksums = tracks[t].Checksums;
|
||||
if(separateSubchannel) tracks[t].SubChannel.Checksums = subChk.End().ToArray();
|
||||
else tracks[t].SubChannel.Checksums = tracks[t].Checksums;
|
||||
}
|
||||
|
||||
DicConsole.WriteLine();
|
||||
dumpFile.Close();
|
||||
end = DateTime.UtcNow;
|
||||
dumpLog.WriteLine("Checksum finished in {0} seconds.", (end - start).TotalSeconds);
|
||||
dumpLog.WriteLine("Average checksum speed {0:F3} KiB/sec.", (((double)blockSize * (double)(blocks + 1)) / 1024) / (totalChkDuration / 1000));
|
||||
dumpLog.WriteLine("Average checksum speed {0:F3} KiB/sec.",
|
||||
(((double)blockSize * (double)(blocks + 1)) / 1024) / (totalChkDuration / 1000));
|
||||
|
||||
// TODO: Correct this
|
||||
sidecar.OpticalDisc[0].Checksums = dataChk.End().ToArray();
|
||||
@@ -944,7 +921,7 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
Value = outputPrefix + ".bin"
|
||||
};
|
||||
sidecar.OpticalDisc[0].Sessions = toc.Value.LastCompleteSession;
|
||||
sidecar.OpticalDisc[0].Tracks = new[] { tracks.Count() };
|
||||
sidecar.OpticalDisc[0].Tracks = new[] {tracks.Count()};
|
||||
sidecar.OpticalDisc[0].Track = tracks;
|
||||
sidecar.OpticalDisc[0].Dimensions = Metadata.Dimensions.DimensionsFromMediaType(dskType);
|
||||
Metadata.MediaType.MediaTypeToString(dskType, out string xmlDskTyp, out string xmlDskSubTyp);
|
||||
@@ -955,10 +932,10 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
{
|
||||
DicConsole.WriteLine("Writing metadata sidecar");
|
||||
|
||||
FileStream xmlFs = new FileStream(outputPrefix + ".cicm.xml",
|
||||
FileMode.Create);
|
||||
FileStream xmlFs = new FileStream(outputPrefix + ".cicm.xml", FileMode.Create);
|
||||
|
||||
System.Xml.Serialization.XmlSerializer xmlSer = new System.Xml.Serialization.XmlSerializer(typeof(CICMMetadataType));
|
||||
System.Xml.Serialization.XmlSerializer xmlSer =
|
||||
new System.Xml.Serialization.XmlSerializer(typeof(CICMMetadataType));
|
||||
xmlSer.Serialize(xmlFs, sidecar);
|
||||
xmlFs.Close();
|
||||
alcohol.Close();
|
||||
@@ -967,4 +944,4 @@ namespace DiscImageChef.Core.Devices.Dumping
|
||||
Statistics.AddMedia(dskType, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user