[Aaru.Core] Reformat and cleanup.

This commit is contained in:
2023-10-03 22:57:50 +01:00
parent 57853b0d2a
commit af659f3fcb
85 changed files with 3303 additions and 1961 deletions

View File

@@ -63,16 +63,16 @@ partial class Dump
/// <param name="newTrim">Set if we need to start a trim</param>
/// <param name="dvdDecrypt">DVD CSS decryption module</param>
/// <param name="discKey">The DVD disc key</param>
void ReadSbcData(in ulong blocks, in uint maxBlocksToRead, in uint blockSize, DumpHardware currentTry,
void ReadSbcData(in ulong blocks, in uint maxBlocksToRead, in uint blockSize, DumpHardware currentTry,
ExtentsULong extents, ref double currentSpeed, ref double minSpeed, ref double maxSpeed,
ref double totalDuration, Reader scsiReader, MhddLog mhddLog, IbgLog ibgLog,
ref double imageWriteDuration, ref bool newTrim, ref DVDDecryption dvdDecrypt, byte[] discKey)
ref double totalDuration, Reader scsiReader, MhddLog mhddLog, IbgLog ibgLog,
ref double imageWriteDuration, ref bool newTrim, ref DVDDecryption dvdDecrypt, byte[] discKey)
{
ulong sectorSpeedStart = 0;
bool sense;
byte[] buffer;
uint blocksToRead = maxBlocksToRead;
var outputFormat = _outputPlugin as IWritableImage;
ulong sectorSpeedStart = 0;
bool sense;
byte[] buffer;
uint blocksToRead = maxBlocksToRead;
var outputFormat = _outputPlugin as IWritableImage;
InitProgress?.Invoke();
@@ -99,8 +99,10 @@ partial class Dump
minSpeed = currentSpeed;
UpdateProgress?.
Invoke(string.Format(Localization.Core.Reading_sector_0_of_1_2, i, blocks, ByteSize.FromMegabytes(currentSpeed).Per(_oneSecond).Humanize()),
(long)i, (long)blocks);
Invoke(
string.Format(Localization.Core.Reading_sector_0_of_1_2, i, blocks,
ByteSize.FromMegabytes(currentSpeed).Per(_oneSecond).Humanize()),
(long)i, (long)blocks);
sense = scsiReader.ReadBlocks(out buffer, i, blocksToRead, out double cmdDuration, out _, out _);
totalDuration += cmdDuration;
@@ -133,10 +135,10 @@ partial class Dump
CSS_CPRM.TitleKey? titleKey = CSS.DecodeTitleKey(tmpBuf, dvdDecrypt.BusKey);
if(titleKey.HasValue)
outputFormat.WriteSectorTag(new[]
{
titleKey.Value.CMI
}, i + j, SectorTagType.DvdSectorCmi);
{
outputFormat.WriteSectorTag(new[] { titleKey.Value.CMI }, i + j,
SectorTagType.DvdSectorCmi);
}
else
continue;
@@ -144,15 +146,11 @@ partial class Dump
if((titleKey.Value.CMI & 0x80) >> 7 == 0)
{
// The CMI indicates this sector is not encrypted.
outputFormat.WriteSectorTag(new byte[]
{
0, 0, 0, 0, 0
}, i + j, SectorTagType.DvdSectorTitleKey);
outputFormat.WriteSectorTag(new byte[] { 0, 0, 0, 0, 0 }, i + j,
SectorTagType.DvdSectorTitleKey);
outputFormat.WriteSectorTag(new byte[]
{
0, 0, 0, 0, 0
}, i + j, SectorTagType.DvdTitleKeyDecrypted);
outputFormat.WriteSectorTag(new byte[] { 0, 0, 0, 0, 0 }, i + j,
SectorTagType.DvdTitleKeyDecrypted);
_resume.MissingTitleKeys.Remove(i + j);
@@ -163,15 +161,11 @@ partial class Dump
// not encrypted even if the CMI says it is.
if(titleKey.Value.Key.All(k => k == 0))
{
outputFormat.WriteSectorTag(new byte[]
{
0, 0, 0, 0, 0
}, i + j, SectorTagType.DvdSectorTitleKey);
outputFormat.WriteSectorTag(new byte[] { 0, 0, 0, 0, 0 }, i + j,
SectorTagType.DvdSectorTitleKey);
outputFormat.WriteSectorTag(new byte[]
{
0, 0, 0, 0, 0
}, i + j, SectorTagType.DvdTitleKeyDecrypted);
outputFormat.WriteSectorTag(new byte[] { 0, 0, 0, 0, 0 }, i + j,
SectorTagType.DvdTitleKeyDecrypted);
_resume.MissingTitleKeys.Remove(i + j);
@@ -200,8 +194,10 @@ partial class Dump
out byte[] titleKey);
if(errno != ErrorNumber.NoError)
{
ErrorMessage?.
Invoke(string.Format(Localization.Core.Error_retrieving_title_key_for_sector_0, i));
}
else
buffer = CSS.DecryptSector(buffer, titleKey, cmi, blocksToRead, blockSize);
}

View File

@@ -73,12 +73,12 @@ partial class Dump
/// <param name="dskType">Disc type as detected in SCSI or MMC layer</param>
/// <param name="dvdDecrypt">DVD CSS decryption module</param>
void Sbc(Dictionary<MediaTagType, byte[]> mediaTags, MediaType dskType, bool opticalDisc,
DVDDecryption dvdDecrypt = null)
DVDDecryption dvdDecrypt = null)
{
bool sense;
byte scsiMediumType = 0;
byte scsiDensityCode = 0;
bool containsFloppyPage = false;
var containsFloppyPage = false;
const ushort sbcProfile = 0x0001;
double totalDuration = 0;
double currentSpeed = 0;
@@ -90,6 +90,7 @@ partial class Dump
var outputFormat = _outputPlugin as IWritableImage;
if(opticalDisc)
{
switch(dskType)
{
case MediaType.REV35:
@@ -99,6 +100,7 @@ partial class Dump
break;
}
}
_dumpLog.WriteLine(Localization.Core.Initializing_reader);
var scsiReader = new Reader(_dev, _dev.Timeout, null, _errorLog, _dumpRaw);
@@ -137,16 +139,20 @@ partial class Dump
if(!sense ||
_dev.Error)
{
sense = _dev.ModeSense10(out cmdBuf, out _, false, true, ScsiModeSensePageControl.Current, 0x3F,
0x00, 5, out _);
}
if(!sense &&
!_dev.Error)
{
if(Modes.DecodeMode10(cmdBuf, _dev.ScsiType).HasValue)
{
mediaTags.Add(MediaTagType.SCSI_MODESENSE_10, cmdBuf);
decMode = Modes.DecodeMode10(cmdBuf, _dev.ScsiType);
}
}
_dumpLog.WriteLine(Localization.Core.Requesting_MODE_SENSE_6);
UpdateStatus?.Invoke(Localization.Core.Requesting_MODE_SENSE_6);
@@ -155,19 +161,23 @@ partial class Dump
out _);
if(sense || _dev.Error)
{
sense = _dev.ModeSense6(out cmdBuf, out _, false, ScsiModeSensePageControl.Current, 0x3F, 0x00, 5,
out _);
}
if(sense || _dev.Error)
sense = _dev.ModeSense(out cmdBuf, out _, 5, out _);
if(!sense &&
!_dev.Error)
{
if(Modes.DecodeMode6(cmdBuf, _dev.ScsiType).HasValue)
{
mediaTags.Add(MediaTagType.SCSI_MODESENSE_6, cmdBuf);
decMode = Modes.DecodeMode6(cmdBuf, _dev.ScsiType);
}
}
if(decMode.HasValue)
{
@@ -179,15 +189,17 @@ partial class Dump
// TODO: Fix this
containsFloppyPage = decMode.Value.Pages?.Aggregate(containsFloppyPage,
(current, modePage) =>
current | (modePage.Page == 0x05)) == true;
current | modePage.Page == 0x05) == true;
}
}
}
if(dskType == MediaType.Unknown)
{
dskType = MediaTypeFromDevice.GetFromScsi((byte)_dev.ScsiType, _dev.Manufacturer, _dev.Model,
scsiMediumType, scsiDensityCode, blocks + 1, blockSize,
_dev.IsUsb, opticalDisc);
}
if(_dev.ScsiType == PeripheralDeviceTypes.MultiMediaDevice)
MMC.DetectDiscType(ref dskType, 1, null, _dev, out _, out _, 0, blocks + 1);
@@ -253,31 +265,32 @@ partial class Dump
UpdateStatus?.Invoke(string.Format(Localization.Core.Device_reports_0_blocks_1_bytes, blocks,
blocks * blockSize));
UpdateStatus?.Invoke(string.Format(Localization.Core.Device_can_read_0_blocks_at_a_time, blocksToRead));
UpdateStatus?.Invoke(string.Format(Localization.Core.Device_can_read_0_blocks_at_a_time, blocksToRead));
UpdateStatus?.Invoke(string.Format(Localization.Core.Device_reports_0_bytes_per_logical_block, blockSize));
UpdateStatus?.Invoke(string.Format(Localization.Core.Device_reports_0_bytes_per_physical_block,
scsiReader.LongBlockSize));
UpdateStatus?.Invoke(string.Format(Localization.Core.SCSI_device_type_0, _dev.ScsiType));
UpdateStatus?.Invoke(string.Format(Localization.Core.SCSI_medium_type_0, scsiMediumType));
UpdateStatus?.Invoke(string.Format(Localization.Core.SCSI_density_type_0, scsiDensityCode));
UpdateStatus?.Invoke(string.Format(Localization.Core.SCSI_device_type_0, _dev.ScsiType));
UpdateStatus?.Invoke(string.Format(Localization.Core.SCSI_medium_type_0, scsiMediumType));
UpdateStatus?.Invoke(string.Format(Localization.Core.SCSI_density_type_0, scsiDensityCode));
UpdateStatus?.Invoke(string.Format(Localization.Core.SCSI_floppy_mode_page_present_0, containsFloppyPage));
UpdateStatus?.Invoke(string.Format(Localization.Core.Media_identified_as_0, dskType));
UpdateStatus?.Invoke(string.Format(Localization.Core.Media_identified_as_0, dskType));
_dumpLog.WriteLine(Localization.Core.Device_reports_0_blocks_1_bytes, blocks, blocks * blockSize);
_dumpLog.WriteLine(Localization.Core.Device_can_read_0_blocks_at_a_time, blocksToRead);
_dumpLog.WriteLine(Localization.Core.Device_reports_0_bytes_per_logical_block, blockSize);
_dumpLog.WriteLine(Localization.Core.Device_reports_0_blocks_1_bytes, blocks, blocks * blockSize);
_dumpLog.WriteLine(Localization.Core.Device_can_read_0_blocks_at_a_time, blocksToRead);
_dumpLog.WriteLine(Localization.Core.Device_reports_0_bytes_per_logical_block, blockSize);
_dumpLog.WriteLine(Localization.Core.Device_reports_0_bytes_per_physical_block, scsiReader.LongBlockSize);
_dumpLog.WriteLine(Localization.Core.SCSI_device_type_0, _dev.ScsiType);
_dumpLog.WriteLine(Localization.Core.SCSI_medium_type_0, scsiMediumType);
_dumpLog.WriteLine(Localization.Core.SCSI_density_type_0, scsiDensityCode);
_dumpLog.WriteLine(Localization.Core.SCSI_floppy_mode_page_present_0, containsFloppyPage);
_dumpLog.WriteLine(Localization.Core.Media_identified_as_0, dskType);
_dumpLog.WriteLine(Localization.Core.SCSI_device_type_0, _dev.ScsiType);
_dumpLog.WriteLine(Localization.Core.SCSI_medium_type_0, scsiMediumType);
_dumpLog.WriteLine(Localization.Core.SCSI_density_type_0, scsiDensityCode);
_dumpLog.WriteLine(Localization.Core.SCSI_floppy_mode_page_present_0, containsFloppyPage);
_dumpLog.WriteLine(Localization.Core.Media_identified_as_0, dskType);
uint longBlockSize = scsiReader.LongBlockSize;
if(_dumpRaw)
{
if(blockSize == longBlockSize)
{
ErrorMessage?.Invoke(!scsiReader.CanReadRaw
@@ -307,13 +320,14 @@ partial class Dump
physicalBlockSize = longBlockSize;
blockSize = longBlockSize;
}
}
ret = true;
foreach(MediaTagType tag in mediaTags.Keys.Where(tag => !outputFormat.SupportedMediaTags.Contains(tag)))
{
ret = false;
_dumpLog.WriteLine(string.Format(Localization.Core.Output_format_does_not_support_0, tag));
_dumpLog.WriteLine(string.Format(Localization.Core.Output_format_does_not_support_0, tag));
ErrorMessage?.Invoke(string.Format(Localization.Core.Output_format_does_not_support_0, tag));
}
@@ -339,8 +353,8 @@ partial class Dump
var mhddLog = new MhddLog(_outputPrefix + ".mhddlog.bin", _dev, blocks, blockSize, blocksToRead, _private,
_dimensions);
var ibgLog = new IbgLog(_outputPrefix + ".ibg", sbcProfile);
bool imageCreated = false;
var ibgLog = new IbgLog(_outputPrefix + ".ibg", sbcProfile);
var imageCreated = false;
if(!opticalDisc)
{
@@ -363,7 +377,7 @@ partial class Dump
_dumpStopwatch.Restart();
double imageWriteDuration = 0;
bool writeSingleOpticalTrack = true;
var writeSingleOpticalTrack = true;
if(opticalDisc)
{
@@ -441,7 +455,8 @@ partial class Dump
List<Track> tracks = new();
for(ushort tno = discInformation.Value.FirstTrackNumber;
tno <= discInformation?.LastTrackLastSession; tno++)
tno <= discInformation?.LastTrackLastSession;
tno++)
{
sense = _dev.ReadTrackInformation(out readBuffer, out _, false,
TrackInformationType.LogicalTrackNumber, tno,
@@ -486,6 +501,7 @@ partial class Dump
}
if(tracks.Count == 0)
{
tracks.Add(new Track
{
BytesPerSector = (int)blockSize,
@@ -496,6 +512,7 @@ partial class Dump
Session = 1,
Type = TrackType.Data
});
}
else
tracks = tracks.OrderBy(t => t.Sequence).ToList();
@@ -517,9 +534,11 @@ partial class Dump
#if DEBUG
foreach(Track trk in tracks)
{
UpdateStatus?.
Invoke(string.Format(Localization.Core.Track_0_starts_at_LBA_1_and_ends_at_LBA_2,
trk.Sequence, trk.StartSector, trk.EndSector));
}
#endif
if(canStoreNotCdTracks)
@@ -541,6 +560,7 @@ partial class Dump
}
}
else
{
opticalPlugin.SetTracks(new List<Track>
{
new()
@@ -554,6 +574,7 @@ partial class Dump
Type = TrackType.Data
}
});
}
}
}
}
@@ -569,9 +590,10 @@ partial class Dump
}
else if(decMode?.Pages != null)
{
bool setGeometry = false;
var setGeometry = false;
foreach(Modes.ModePage page in decMode.Value.Pages)
{
switch(page.Page)
{
case 0x04 when page.Subpage == 0x00:
@@ -588,9 +610,11 @@ partial class Dump
UpdateStatus?.
Invoke(string.
Format(Localization.Core.Setting_geometry_to_0_cylinders_1_heads_2_sectors_per_track,
rigidPage.Value.Cylinders, rigidPage.Value.Heads,
(uint)(blocks / (rigidPage.Value.Cylinders * rigidPage.Value.Heads))));
Format(
Localization.Core.
Setting_geometry_to_0_cylinders_1_heads_2_sectors_per_track,
rigidPage.Value.Cylinders, rigidPage.Value.Heads,
(uint)(blocks / (rigidPage.Value.Cylinders * rigidPage.Value.Heads))));
outputFormat.SetGeometry(rigidPage.Value.Cylinders, rigidPage.Value.Heads,
(uint)(blocks / (rigidPage.Value.Cylinders * rigidPage.Value.Heads)));
@@ -613,9 +637,11 @@ partial class Dump
UpdateStatus?.
Invoke(string.
Format(Localization.Core.Setting_geometry_to_0_cylinders_1_heads_2_sectors_per_track,
flexiblePage.Value.Cylinders, flexiblePage.Value.Heads,
flexiblePage.Value.SectorsPerTrack));
Format(
Localization.Core.
Setting_geometry_to_0_cylinders_1_heads_2_sectors_per_track,
flexiblePage.Value.Cylinders, flexiblePage.Value.Heads,
flexiblePage.Value.SectorsPerTrack));
outputFormat.SetGeometry(flexiblePage.Value.Cylinders, flexiblePage.Value.Heads,
flexiblePage.Value.SectorsPerTrack);
@@ -625,6 +651,7 @@ partial class Dump
break;
}
}
}
}
if(!imageCreated)
@@ -676,10 +703,10 @@ partial class Dump
if(_createGraph)
{
bool discIs80Mm =
(mediaTags?.TryGetValue(MediaTagType.DVD_PFI, out byte[] pfiBytes) == true &&
PFI.Decode(pfiBytes, dskType)?.DiscSize == DVDSize.Eighty) ||
(mediaTags?.TryGetValue(MediaTagType.BD_DI, out byte[] diBytes) == true && DI.
Decode(diBytes)?.Units?.Any(s => s.DiscSize == DI.BluSize.Eighty) == true);
mediaTags?.TryGetValue(MediaTagType.DVD_PFI, out byte[] pfiBytes) == true &&
PFI.Decode(pfiBytes, dskType)?.DiscSize == DVDSize.Eighty ||
mediaTags?.TryGetValue(MediaTagType.BD_DI, out byte[] diBytes) == true && DI.
Decode(diBytes)?.Units?.Any(s => s.DiscSize == DI.BluSize.Eighty) == true;
Spiral.DiscParameters discSpiralParameters = Spiral.DiscParametersFromMediaType(dskType, discIs80Mm);
@@ -689,8 +716,10 @@ partial class Dump
_mediaGraph = new BlockMap((int)_dimensions, (int)_dimensions, blocks);
if(_mediaGraph is not null)
{
foreach(Tuple<ulong, ulong> e in extents.ToArray())
_mediaGraph?.PaintSectorsGood(e.Item1, (uint)(e.Item2 - e.Item1 + 2));
}
_mediaGraph?.PaintSectorsBad(_resume.BadBlocks);
}
@@ -719,7 +748,7 @@ partial class Dump
}
else
{
_dumpLog.WriteLine(string.Format(Localization.Core.Setting_speed_to_0_x, _speed));
_dumpLog.WriteLine(string.Format(Localization.Core.Setting_speed_to_0_x, _speed));
UpdateStatus?.Invoke(string.Format(Localization.Core.Setting_speed_to_0_x, _speed));
}
@@ -734,7 +763,7 @@ partial class Dump
if(_resume?.BlankExtents != null)
blankExtents = ExtentsConverter.FromMetadata(_resume.BlankExtents);
bool newTrim = false;
var newTrim = false;
if(mediaTags.TryGetValue(MediaTagType.DVD_CMI, out byte[] cmi) &&
Settings.Settings.Current.EnableDecryption &&
@@ -747,15 +776,20 @@ partial class Dump
}
if(_dev.ScsiType == PeripheralDeviceTypes.OpticalDevice)
ReadOpticalData(blocks, blocksToRead, blockSize, currentTry, extents, ref currentSpeed, ref minSpeed,
{
ReadOpticalData(blocks, blocksToRead, blockSize, currentTry, extents, ref currentSpeed, ref minSpeed,
ref maxSpeed, ref totalDuration, scsiReader, mhddLog, ibgLog, ref imageWriteDuration,
ref newTrim, ref blankExtents);
ref newTrim, ref blankExtents);
}
else
ReadSbcData(blocks, blocksToRead, blockSize, currentTry, extents, ref currentSpeed, ref minSpeed,
{
ReadSbcData(blocks, blocksToRead, blockSize, currentTry, extents, ref currentSpeed, ref minSpeed,
ref maxSpeed, ref totalDuration, scsiReader, mhddLog, ibgLog, ref imageWriteDuration,
ref newTrim, ref dvdDecrypt,
ref newTrim, ref dvdDecrypt,
mediaTags.ContainsKey(MediaTagType.DVD_DiscKey_Decrypted)
? mediaTags[MediaTagType.DVD_DiscKey_Decrypted] : null);
? mediaTags[MediaTagType.DVD_DiscKey_Decrypted]
: null);
}
_dumpStopwatch.Stop();
mhddLog.Close();
@@ -785,7 +819,8 @@ partial class Dump
ByteSize.FromBytes(blockSize * (blocks + 1)).
Per(imageWriteDuration.Seconds())));
#region Trimming
#region Trimming
if(_resume.BadBlocks.Count > 0 &&
!_aborted &&
_trim &&
@@ -810,9 +845,11 @@ partial class Dump
_trimStopwatch.Stop();
}
#endregion Trimming
#region Error handling
#endregion Trimming
#region Error handling
if(_resume.BadBlocks.Count > 0 &&
!_aborted &&
_retryPasses > 0)
@@ -825,9 +862,11 @@ partial class Dump
_titleKeys &&
mediaTags.ContainsKey(MediaTagType.DVD_DiscKey_Decrypted))
RetryTitleKeys(dvdDecrypt, mediaTags[MediaTagType.DVD_DiscKey_Decrypted], ref totalDuration);
#endregion Error handling
#endregion Error handling
if(opticalDisc)
{
foreach(KeyValuePair<MediaTagType, byte[]> tag in mediaTags)
{
if(tag.Value is null)
@@ -850,6 +889,7 @@ partial class Dump
return;
}
}
else
{
if(!_dev.IsRemovable ||
@@ -929,11 +969,14 @@ partial class Dump
if(!sense ||
_dev.Error)
{
sense = _dev.ModeSense10(out cmdBuf, out _, false, true, ScsiModeSensePageControl.Current, 0x3F,
0x00, 5, out _);
}
if(!sense &&
!_dev.Error)
{
if(Modes.DecodeMode10(cmdBuf, _dev.ScsiType).HasValue)
{
ret = outputFormat.WriteMediaTag(cmdBuf, MediaTagType.SCSI_MODESENSE_10);
@@ -949,6 +992,7 @@ partial class Dump
return;
}
}
}
UpdateStatus?.Invoke(Localization.Core.Requesting_MODE_SENSE_6);
_dumpLog.WriteLine(Localization.Core.Requesting_MODE_SENSE_6);
@@ -957,14 +1001,17 @@ partial class Dump
out _);
if(sense || _dev.Error)
{
sense = _dev.ModeSense6(out cmdBuf, out _, false, ScsiModeSensePageControl.Current, 0x3F, 0x00,
5, out _);
}
if(sense || _dev.Error)
sense = _dev.ModeSense(out cmdBuf, out _, 5, out _);
if(!sense &&
!_dev.Error)
{
if(Modes.DecodeMode6(cmdBuf, _dev.ScsiType).HasValue)
{
ret = outputFormat.WriteMediaTag(cmdBuf, MediaTagType.SCSI_MODESENSE_6);
@@ -980,6 +1027,7 @@ partial class Dump
return;
}
}
}
}
}
}
@@ -1002,8 +1050,10 @@ partial class Dump
};
if(!outputFormat.SetImageInfo(metadata))
{
ErrorMessage?.Invoke(Localization.Core.Error_0_setting_metadata + Environment.NewLine +
outputFormat.ErrorMessage);
}
if(_preSidecar != null)
outputFormat.SetMetadata(_preSidecar);
@@ -1094,7 +1144,9 @@ partial class Dump
{
if(_dev.IsUsb &&
_dev.UsbDescriptors != null)
{
if(outputFormat.SupportedMediaTags.Contains(MediaTagType.USB_Descriptors))
{
sidecar.BlockMedias[0].Usb = new Usb
{
ProductID = _dev.UsbProductId,
@@ -1106,6 +1158,8 @@ partial class Dump
Checksums = Checksum.GetChecksums(_dev.UsbDescriptors)
}
};
}
}
byte[] cmdBuf;
@@ -1114,7 +1168,9 @@ partial class Dump
sense = _dev.AtapiIdentify(out cmdBuf, out _);
if(!sense)
{
if(outputFormat.SupportedMediaTags.Contains(MediaTagType.ATAPI_IDENTIFY))
{
sidecar.BlockMedias[0].ATA = new ATA
{
Identify = new CommonTypes.AaruMetadata.Dump
@@ -1124,6 +1180,8 @@ partial class Dump
Checksums = Checksum.GetChecksums(cmdBuf)
}
};
}
}
}
sense = _dev.ScsiInquiry(out cmdBuf, out _);
@@ -1131,6 +1189,7 @@ partial class Dump
if(!sense)
{
if(outputFormat.SupportedMediaTags.Contains(MediaTagType.SCSI_INQUIRY))
{
sidecar.BlockMedias[0].SCSI = new SCSI
{
Inquiry = new CommonTypes.AaruMetadata.Dump
@@ -1140,6 +1199,7 @@ partial class Dump
Checksums = Checksum.GetChecksums(cmdBuf)
}
};
}
// TODO: SCSI Extended Vendor Page descriptors
/*
@@ -1183,19 +1243,27 @@ partial class Dump
if(!sense ||
_dev.Error)
{
sense = _dev.ModeSense10(out cmdBuf, out _, false, true,
ScsiModeSensePageControl.Current, 0x3F, 0x00, 5, out _);
}
if(!sense &&
!_dev.Error)
{
if(Modes.DecodeMode10(cmdBuf, _dev.ScsiType).HasValue)
{
if(outputFormat.SupportedMediaTags.Contains(MediaTagType.SCSI_MODESENSE_10))
{
sidecar.BlockMedias[0].SCSI.ModeSense10 = new CommonTypes.AaruMetadata.Dump
{
Image = _outputPath,
Size = (ulong)cmdBuf.Length,
Checksums = Checksum.GetChecksums(cmdBuf)
};
}
}
}
UpdateStatus?.Invoke(Localization.Core.Requesting_MODE_SENSE_6);
_dumpLog.WriteLine(Localization.Core.Requesting_MODE_SENSE_6);
@@ -1204,34 +1272,45 @@ partial class Dump
0x00, 5, out _);
if(sense || _dev.Error)
{
sense = _dev.ModeSense6(out cmdBuf, out _, false, ScsiModeSensePageControl.Current,
0x3F, 0x00, 5, out _);
}
if(sense || _dev.Error)
sense = _dev.ModeSense(out cmdBuf, out _, 5, out _);
if(!sense &&
!_dev.Error)
{
if(Modes.DecodeMode6(cmdBuf, _dev.ScsiType).HasValue)
{
if(outputFormat.SupportedMediaTags.Contains(MediaTagType.SCSI_MODESENSE_6))
{
sidecar.BlockMedias[0].SCSI.ModeSense = new CommonTypes.AaruMetadata.Dump
{
Image = _outputPath,
Size = (ulong)cmdBuf.Length,
Checksums = Checksum.GetChecksums(cmdBuf)
};
}
}
}
}
}
List<(ulong start, string type)> filesystems = new();
if(sidecar.BlockMedias[0].FileSystemInformation != null)
{
filesystems.AddRange(from partition in sidecar.BlockMedias[0].FileSystemInformation
where partition.FileSystems != null
from fileSystem in partition.FileSystems
select (partition.StartSector, fileSystem.Type));
}
if(filesystems.Count > 0)
{
foreach(var filesystem in filesystems.Select(o => new
{
o.start,
@@ -1244,6 +1323,7 @@ partial class Dump
_dumpLog.WriteLine(Localization.Core.Found_filesystem_0_at_sector_1, filesystem.type,
filesystem.start);
}
}
sidecar.BlockMedias[0].Dimensions = Dimensions.FromMediaType(dskType);
@@ -1255,6 +1335,7 @@ partial class Dump
// TODO: Implement device firmware revision
if(!_dev.IsRemovable ||
_dev.IsUsb)
{
if(_dev.Type == DeviceType.ATAPI)
sidecar.BlockMedias[0].Interface = "ATAPI";
else if(_dev.IsUsb)
@@ -1263,6 +1344,7 @@ partial class Dump
sidecar.BlockMedias[0].Interface = "FireWire";
else
sidecar.BlockMedias[0].Interface = "SCSI";
}
sidecar.BlockMedias[0].LogicalBlocks = blocks;
sidecar.BlockMedias[0].PhysicalBlockSize = physicalBlockSize;
@@ -1295,24 +1377,29 @@ partial class Dump
UpdateStatus?.Invoke("");
UpdateStatus?.
Invoke(string.Format(Localization.Core.Took_a_total_of_0_1_processing_commands_2_checksumming_3_writing_4_closing,
_dumpStopwatch.Elapsed.Humanize(minUnit: TimeUnit.Second),
totalDuration.Milliseconds().Humanize(minUnit: TimeUnit.Second),
totalChkDuration.Milliseconds().Humanize(minUnit: TimeUnit.Second),
imageWriteDuration.Seconds().Humanize(minUnit: TimeUnit.Second),
_imageCloseStopwatch.Elapsed.Humanize(minUnit: TimeUnit.Second)));
Invoke(string.Format(
Localization.Core.Took_a_total_of_0_1_processing_commands_2_checksumming_3_writing_4_closing,
_dumpStopwatch.Elapsed.Humanize(minUnit: TimeUnit.Second),
totalDuration.Milliseconds().Humanize(minUnit: TimeUnit.Second),
totalChkDuration.Milliseconds().Humanize(minUnit: TimeUnit.Second),
imageWriteDuration.Seconds().Humanize(minUnit: TimeUnit.Second),
_imageCloseStopwatch.Elapsed.Humanize(minUnit: TimeUnit.Second)));
UpdateStatus?.Invoke(string.Format(Localization.Core.Average_speed_0,
ByteSize.FromBytes(blockSize * (blocks + 1)).
Per(totalDuration.Milliseconds())).Humanize());
if(maxSpeed > 0)
{
UpdateStatus?.Invoke(string.Format(Localization.Core.Fastest_speed_burst_0,
ByteSize.FromMegabytes(maxSpeed).Per(_oneSecond).Humanize()));
}
if(minSpeed is > 0 and < double.MaxValue)
{
UpdateStatus?.Invoke(string.Format(Localization.Core.Slowest_speed_burst_0,
ByteSize.FromMegabytes(minSpeed).Per(_oneSecond).Humanize()));
}
UpdateStatus?.Invoke(string.Format(Localization.Core._0_sectors_could_not_be_read, _resume.BadBlocks.Count));
UpdateStatus?.Invoke("");

View File

@@ -53,12 +53,12 @@ partial class Dump
/// <param name="totalDuration">Total time spent in commands</param>
/// <param name="scsiReader">SCSI reader</param>
/// <param name="blankExtents">Blank extents</param>
void RetrySbcData(Reader scsiReader, DumpHardware currentTry, ExtentsULong extents, ref double totalDuration,
void RetrySbcData(Reader scsiReader, DumpHardware currentTry, ExtentsULong extents, ref double totalDuration,
ExtentsULong blankExtents)
{
int pass = 1;
bool forward = true;
bool runningPersistent = false;
var pass = 1;
var forward = true;
var runningPersistent = false;
bool sense;
byte[] buffer;
bool recoveredError;
@@ -66,7 +66,7 @@ partial class Dump
byte[] md6;
byte[] md10;
bool blankCheck;
bool newBlank = false;
var newBlank = false;
var outputFormat = _outputPlugin as IWritableImage;
if(_persistent)
@@ -87,9 +87,11 @@ partial class Dump
Modes.DecodedMode? dcMode10 = Modes.DecodeMode10(buffer, _dev.ScsiType);
if(dcMode10?.Pages != null)
{
foreach(Modes.ModePage modePage in dcMode10.Value.Pages.Where(modePage =>
modePage is { Page: 0x01, Subpage: 0x00 }))
currentModePage = modePage;
}
}
}
else
@@ -97,9 +99,11 @@ partial class Dump
Modes.DecodedMode? dcMode6 = Modes.DecodeMode6(buffer, _dev.ScsiType);
if(dcMode6?.Pages != null)
{
foreach(Modes.ModePage modePage in dcMode6.Value.Pages.Where(modePage =>
modePage is { Page: 0x01, Subpage: 0x00 }))
currentModePage = modePage;
}
}
if(currentModePage == null)
@@ -227,7 +231,7 @@ partial class Dump
}
InitProgress?.Invoke();
repeatRetry:
repeatRetry:
ulong[] tmpArray = _resume.BadBlocks.ToArray();
foreach(ulong badSector in tmpArray)
@@ -242,19 +246,27 @@ partial class Dump
}
if(forward)
{
PulseProgress?.Invoke(runningPersistent
? string.
Format(Localization.Core.Retrying_sector_0_pass_1_recovering_partial_data_forward,
badSector, pass)
Format(
Localization.Core.
Retrying_sector_0_pass_1_recovering_partial_data_forward,
badSector, pass)
: string.Format(Localization.Core.Retrying_sector_0_pass_1_forward, badSector,
pass));
}
else
{
PulseProgress?.Invoke(runningPersistent
? string.
Format(Localization.Core.Retrying_sector_0_pass_1_recovering_partial_data_reverse,
badSector, pass)
Format(
Localization.Core.
Retrying_sector_0_pass_1_recovering_partial_data_reverse,
badSector, pass)
: string.Format(Localization.Core.Retrying_sector_0_pass_1_reverse, badSector,
pass));
}
sense = scsiReader.ReadBlock(out buffer, badSector, out double cmdDuration, out recoveredError,
out blankCheck);
@@ -273,7 +285,7 @@ partial class Dump
continue;
}
if((!sense && !_dev.Error) || recoveredError)
if(!sense && !_dev.Error || recoveredError)
{
_resume.BadBlocks.Remove(badSector);
extents.Add(badSector);
@@ -308,10 +320,7 @@ partial class Dump
var md = new Modes.DecodedMode
{
Header = new Modes.ModeHeader(),
Pages = new[]
{
currentModePage.Value
}
Pages = new[] { currentModePage.Value }
};
md6 = Modes.EncodeMode6(md, _dev.ScsiType);
@@ -333,8 +342,8 @@ partial class Dump
void RetryTitleKeys(DVDDecryption dvdDecrypt, byte[] discKey, ref double totalDuration)
{
int pass = 1;
bool forward = true;
var pass = 1;
var forward = true;
bool sense;
byte[] buffer;
@@ -343,7 +352,7 @@ partial class Dump
InitProgress?.Invoke();
repeatRetry:
repeatRetry:
ulong[] tmpArray = _resume.MissingTitleKeys.ToArray();
foreach(ulong missingKey in tmpArray)
@@ -375,25 +384,17 @@ partial class Dump
if(!titleKey.HasValue)
continue;
outputFormat.WriteSectorTag(new[]
{
titleKey.Value.CMI
}, missingKey, SectorTagType.DvdSectorCmi);
outputFormat.WriteSectorTag(new[] { titleKey.Value.CMI }, missingKey, SectorTagType.DvdSectorCmi);
// If the CMI bit is 1, the sector is using copy protection, else it is not
// If the decoded title key is zeroed, there should be no copy protection
if((titleKey.Value.CMI & 0x80) >> 7 == 0 ||
titleKey.Value.Key.All(k => k == 0))
{
outputFormat.WriteSectorTag(new byte[]
{
0, 0, 0, 0, 0
}, missingKey, SectorTagType.DvdSectorTitleKey);
outputFormat.WriteSectorTag(new byte[] { 0, 0, 0, 0, 0 }, missingKey, SectorTagType.DvdSectorTitleKey);
outputFormat.WriteSectorTag(new byte[]
{
0, 0, 0, 0, 0
}, missingKey, SectorTagType.DvdTitleKeyDecrypted);
outputFormat.WriteSectorTag(new byte[] { 0, 0, 0, 0, 0 }, missingKey,
SectorTagType.DvdTitleKeyDecrypted);
_resume.MissingTitleKeys.Remove(missingKey);

View File

@@ -37,10 +37,10 @@ partial class Dump
/// <param name="imageWriteDuration">Total time spent writing to image</param>
/// <param name="newTrim">Set if we need to start a trim</param>
/// <param name="blankExtents">Blank extents</param>
void ReadOpticalData(in ulong blocks, in uint maxBlocksToRead, in uint blockSize, DumpHardware currentTry,
void ReadOpticalData(in ulong blocks, in uint maxBlocksToRead, in uint blockSize, DumpHardware currentTry,
ExtentsULong extents, ref double currentSpeed, ref double minSpeed, ref double maxSpeed,
ref double totalDuration, Reader scsiReader, MhddLog mhddLog, IbgLog ibgLog,
ref double imageWriteDuration, ref bool newTrim, ref ExtentsULong blankExtents)
ref double totalDuration, Reader scsiReader, MhddLog mhddLog, IbgLog ibgLog,
ref double imageWriteDuration, ref bool newTrim, ref ExtentsULong blankExtents)
{
const uint maxBlocks = 256;
var writtenExtents = new ExtentsULong();
@@ -53,7 +53,7 @@ partial class Dump
bool sense;
byte[] buffer;
ulong sectorSpeedStart = 0;
bool canMediumScan = true;
var canMediumScan = true;
var outputFormat = _outputPlugin as IWritableImage;
InitProgress?.Invoke();
@@ -115,8 +115,11 @@ partial class Dump
c = (uint)(blocks - b);
UpdateProgress?.
Invoke(written ? string.Format(Localization.Core.Scanning_for_0_written_blocks_starting_in_block_1, c, b) : string.Format(Localization.Core.Scanning_for_0_blank_blocks_starting_in_block_1, c, b),
b, (long)blocks);
Invoke(
written
? string.Format(Localization.Core.Scanning_for_0_written_blocks_starting_in_block_1, c, b)
: string.Format(Localization.Core.Scanning_for_0_blank_blocks_starting_in_block_1, c, b),
b, (long)blocks);
conditionMet = _dev.MediumScan(out _, written, false, false, false, false, b, c, c, out _, out _,
uint.MaxValue, out _);
@@ -158,8 +161,10 @@ partial class Dump
writtenExtents.Add(0, blocks - 1);
foreach(Tuple<ulong, ulong> blank in blankExtents.ToArray())
{
for(ulong b = blank.Item1; b <= blank.Item2; b++)
writtenExtents.Remove(b);
}
}
if(writtenExtents.Count == 0)
@@ -209,8 +214,10 @@ partial class Dump
minSpeed = currentSpeed;
UpdateProgress?.
Invoke(string.Format(Localization.Core.Reading_sector_0_of_1_2, i, blocks, ByteSize.FromMegabytes(currentSpeed).Per(_oneSecond).Humanize()),
(long)i, (long)blocks);
Invoke(
string.Format(Localization.Core.Reading_sector_0_of_1_2, i, blocks,
ByteSize.FromMegabytes(currentSpeed).Per(_oneSecond).Humanize()),
(long)i, (long)blocks);
sense = scsiReader.ReadBlocks(out buffer, i, blocksToRead, out double cmdDuration, out _, out _);
totalDuration += cmdDuration;

View File

@@ -48,7 +48,7 @@ partial class Dump
bool recoveredError;
bool blankCheck;
byte[] buffer;
bool newBlank = false;
var newBlank = false;
if(_outputPlugin is not IWritableImage outputFormat)
{