mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Add support for negative sectors to read and write sector calls in images.
This commit is contained in:
@@ -339,6 +339,7 @@ public partial class Dump
|
||||
|
||||
outputFormat.WriteSectors(cmdBuf,
|
||||
i,
|
||||
false,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead)
|
||||
.ToArray());
|
||||
@@ -359,6 +360,7 @@ public partial class Dump
|
||||
|
||||
outputFormat.WriteSectors(new byte[blockSize * _skip],
|
||||
i,
|
||||
false,
|
||||
_skip,
|
||||
Enumerable.Repeat(SectorStatus.NotDumped, (int)blocksToRead)
|
||||
.ToArray());
|
||||
@@ -448,7 +450,7 @@ public partial class Dump
|
||||
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
extents.Add(badSector);
|
||||
outputFormat.WriteSector(cmdBuf, badSector, SectorStatus.Dumped);
|
||||
outputFormat.WriteSector(cmdBuf, badSector, false, SectorStatus.Dumped);
|
||||
_mediaGraph?.PaintSectorGood(badSector);
|
||||
}
|
||||
|
||||
@@ -516,7 +518,7 @@ public partial class Dump
|
||||
{
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
extents.Add(badSector);
|
||||
outputFormat.WriteSector(cmdBuf, badSector, SectorStatus.Dumped);
|
||||
outputFormat.WriteSector(cmdBuf, badSector, false, SectorStatus.Dumped);
|
||||
_mediaGraph?.PaintSectorGood(badSector);
|
||||
|
||||
UpdateStatus?.Invoke(string.Format(Localization.Core
|
||||
@@ -524,7 +526,8 @@ public partial class Dump
|
||||
badSector,
|
||||
pass));
|
||||
}
|
||||
else if(_persistent) outputFormat.WriteSector(cmdBuf, badSector, SectorStatus.Errored);
|
||||
else if(_persistent)
|
||||
outputFormat.WriteSector(cmdBuf, badSector, false, SectorStatus.Errored);
|
||||
}
|
||||
|
||||
if(pass < _retryPasses && !_aborted && _resume.BadBlocks.Count > 0)
|
||||
@@ -627,6 +630,7 @@ public partial class Dump
|
||||
|
||||
outputFormat.WriteSector(cmdBuf,
|
||||
(ulong)((cy * heads + hd) * sectors + (sc - 1)),
|
||||
false,
|
||||
SectorStatus.Dumped);
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
@@ -642,6 +646,7 @@ public partial class Dump
|
||||
|
||||
outputFormat.WriteSector(new byte[blockSize],
|
||||
(ulong)((cy * heads + hd) * sectors + (sc - 1)),
|
||||
false,
|
||||
SectorStatus.Errored);
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
|
||||
@@ -300,6 +300,7 @@ partial class Dump
|
||||
|
||||
outputOptical.WriteSectorsLong(data,
|
||||
i + r,
|
||||
false,
|
||||
1,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, 1).ToArray());
|
||||
|
||||
@@ -333,7 +334,7 @@ partial class Dump
|
||||
}
|
||||
}
|
||||
else
|
||||
outputOptical.WriteSectorsLong(cmdBuf, i + r, 1, [SectorStatus.Dumped]);
|
||||
outputOptical.WriteSectorsLong(cmdBuf, i + r, false, 1, [SectorStatus.Dumped]);
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
|
||||
@@ -410,6 +411,7 @@ partial class Dump
|
||||
|
||||
outputOptical.WriteSectorsLong(data,
|
||||
i,
|
||||
false,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead).ToArray());
|
||||
|
||||
@@ -466,16 +468,20 @@ partial class Dump
|
||||
|
||||
outputOptical.WriteSectorsLong(data,
|
||||
i,
|
||||
false,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead)
|
||||
.ToArray());
|
||||
}
|
||||
else
|
||||
{
|
||||
outputOptical.WriteSectorsLong(cmdBuf,
|
||||
i,
|
||||
false,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead)
|
||||
.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
|
||||
@@ -776,11 +776,14 @@ partial class Dump
|
||||
Array.Copy(cmdBuf, sectorSize, sub, 0, subSize);
|
||||
|
||||
if(supportsLongSectors)
|
||||
{
|
||||
outputFormat.WriteSectorsLong(data,
|
||||
i + r,
|
||||
false,
|
||||
1,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead)
|
||||
.ToArray());
|
||||
}
|
||||
else
|
||||
{
|
||||
var cooked = new MemoryStream();
|
||||
@@ -795,6 +798,7 @@ partial class Dump
|
||||
|
||||
outputFormat.WriteSectors(cooked.ToArray(),
|
||||
i,
|
||||
false,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead)
|
||||
.ToArray());
|
||||
@@ -844,7 +848,7 @@ partial class Dump
|
||||
else
|
||||
{
|
||||
if(supportsLongSectors)
|
||||
outputFormat.WriteSectorsLong(cmdBuf, i + r, 1, [SectorStatus.Dumped]);
|
||||
outputFormat.WriteSectorsLong(cmdBuf, i + r, false, 1, [SectorStatus.Dumped]);
|
||||
else
|
||||
{
|
||||
var cooked = new MemoryStream();
|
||||
@@ -859,6 +863,7 @@ partial class Dump
|
||||
|
||||
outputFormat.WriteSectors(cooked.ToArray(),
|
||||
i,
|
||||
false,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead)
|
||||
.ToArray());
|
||||
@@ -878,12 +883,17 @@ partial class Dump
|
||||
|
||||
if(supportedSubchannel != MmcSubchannel.None)
|
||||
{
|
||||
outputFormat.WriteSectorsLong(new byte[sectorSize], i + r, 1, [SectorStatus.Errored]);
|
||||
outputFormat.WriteSectorsLong(new byte[sectorSize],
|
||||
i + r,
|
||||
false,
|
||||
1,
|
||||
[SectorStatus.Errored]);
|
||||
|
||||
if(desiredSubchannel != MmcSubchannel.None)
|
||||
{
|
||||
outputFormat.WriteSectorsTag(new byte[subSize],
|
||||
i + r,
|
||||
false,
|
||||
1,
|
||||
SectorTagType.CdSectorSubchannel);
|
||||
}
|
||||
@@ -891,16 +901,23 @@ partial class Dump
|
||||
else
|
||||
{
|
||||
if(supportsLongSectors)
|
||||
outputFormat.WriteSectorsLong(new byte[blockSize], i + r, 1, [SectorStatus.Errored]);
|
||||
outputFormat.WriteSectorsLong(new byte[blockSize],
|
||||
i + r,
|
||||
false,
|
||||
1,
|
||||
[SectorStatus.Errored]);
|
||||
else
|
||||
{
|
||||
if(cmdBuf.Length % sectorSize == 0)
|
||||
outputFormat.WriteSectors(new byte[2048], i + r, 1, [SectorStatus.Errored]);
|
||||
outputFormat.WriteSectors(new byte[2048], i + r, false, 1, [SectorStatus.Errored]);
|
||||
else
|
||||
{
|
||||
outputFormat.WriteSectorsLong(new byte[blockSize],
|
||||
i + r,
|
||||
false,
|
||||
1,
|
||||
[SectorStatus.Errored]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -977,11 +994,14 @@ partial class Dump
|
||||
}
|
||||
|
||||
if(supportsLongSectors)
|
||||
{
|
||||
outputFormat.WriteSectorsLong(data,
|
||||
i,
|
||||
false,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead)
|
||||
.ToArray());
|
||||
}
|
||||
else
|
||||
{
|
||||
var cooked = new MemoryStream();
|
||||
@@ -996,6 +1016,7 @@ partial class Dump
|
||||
|
||||
outputFormat.WriteSectors(cooked.ToArray(),
|
||||
i,
|
||||
false,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead).ToArray());
|
||||
}
|
||||
@@ -1043,11 +1064,14 @@ partial class Dump
|
||||
else
|
||||
{
|
||||
if(supportsLongSectors)
|
||||
{
|
||||
outputFormat.WriteSectorsLong(cmdBuf,
|
||||
i,
|
||||
false,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead)
|
||||
.ToArray());
|
||||
}
|
||||
else
|
||||
{
|
||||
var cooked = new MemoryStream();
|
||||
@@ -1062,6 +1086,7 @@ partial class Dump
|
||||
|
||||
outputFormat.WriteSectors(cooked.ToArray(),
|
||||
i,
|
||||
false,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead).ToArray());
|
||||
}
|
||||
@@ -1097,6 +1122,7 @@ partial class Dump
|
||||
{
|
||||
outputFormat.WriteSectorsLong(new byte[sectorSize * _skip],
|
||||
i,
|
||||
false,
|
||||
_skip,
|
||||
Enumerable.Repeat(SectorStatus.NotDumped, (int)_skip).ToArray());
|
||||
|
||||
@@ -1104,6 +1130,7 @@ partial class Dump
|
||||
{
|
||||
outputFormat.WriteSectorsTag(new byte[subSize * _skip],
|
||||
i,
|
||||
false,
|
||||
_skip,
|
||||
SectorTagType.CdSectorSubchannel);
|
||||
}
|
||||
@@ -1111,23 +1138,32 @@ partial class Dump
|
||||
else
|
||||
{
|
||||
if(supportsLongSectors)
|
||||
{
|
||||
outputFormat.WriteSectorsLong(new byte[blockSize * _skip],
|
||||
i,
|
||||
false,
|
||||
_skip,
|
||||
Enumerable.Repeat(SectorStatus.NotDumped, (int)_skip).ToArray());
|
||||
}
|
||||
else
|
||||
{
|
||||
if(cmdBuf.Length % sectorSize == 0)
|
||||
{
|
||||
outputFormat.WriteSectors(new byte[2048 * _skip],
|
||||
i,
|
||||
false,
|
||||
_skip,
|
||||
Enumerable.Repeat(SectorStatus.NotDumped, (int)_skip).ToArray());
|
||||
}
|
||||
else
|
||||
{
|
||||
outputFormat.WriteSectorsLong(new byte[blockSize * _skip],
|
||||
i,
|
||||
false,
|
||||
_skip,
|
||||
Enumerable.Repeat(SectorStatus.NotDumped, (int)_skip)
|
||||
.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -87,21 +87,21 @@ sealed partial class Dump
|
||||
MhddLog mhddLog; // MHDD log
|
||||
double minSpeed = double.MaxValue; // Minimum speed
|
||||
bool newTrim; // Is trim a new one?
|
||||
int offsetBytes = 0; // Read offset
|
||||
bool read6 = false; // Device supports READ(6)
|
||||
bool read10 = false; // Device supports READ(10)
|
||||
bool read12 = false; // Device supports READ(12)
|
||||
bool read16 = false; // Device supports READ(16)
|
||||
bool readcd = true; // Device supports READ CD
|
||||
var offsetBytes = 0; // Read offset
|
||||
var read6 = false; // Device supports READ(6)
|
||||
var read10 = false; // Device supports READ(10)
|
||||
var read12 = false; // Device supports READ(12)
|
||||
var read16 = false; // Device supports READ(16)
|
||||
var readcd = true; // Device supports READ CD
|
||||
bool ret; // Image writing return status
|
||||
const uint sectorSize = 2352; // Full sector size
|
||||
int sectorsForOffset = 0; // Sectors needed to fix offset
|
||||
bool sense = true; // Sense indicator
|
||||
var sectorsForOffset = 0; // Sectors needed to fix offset
|
||||
var sense = true; // Sense indicator
|
||||
int sessions; // Number of sessions in disc
|
||||
SubchannelLog subLog = null; // Subchannel log
|
||||
uint subSize = 0; // Subchannel size in bytes
|
||||
TrackSubchannelType subType; // Track subchannel type
|
||||
bool supportsLongSectors = true; // Supports reading EDC and ECC
|
||||
var supportsLongSectors = true; // Supports reading EDC and ECC
|
||||
bool supportsPqSubchannel; // Supports reading PQ subchannel
|
||||
bool supportsRwSubchannel; // Supports reading RW subchannel
|
||||
byte[] tmpBuf; // Temporary buffer
|
||||
@@ -113,11 +113,11 @@ sealed partial class Dump
|
||||
bool hiddenTrack; // Disc has a hidden track before track 1
|
||||
MmcSubchannel supportedSubchannel; // Drive's maximum supported subchannel
|
||||
MmcSubchannel desiredSubchannel; // User requested subchannel
|
||||
bool bcdSubchannel = false; // Subchannel positioning is in BCD
|
||||
var bcdSubchannel = false; // Subchannel positioning is in BCD
|
||||
Dictionary<byte, string> isrcs = new();
|
||||
string mcn = null;
|
||||
HashSet<int> subchannelExtents = [];
|
||||
bool cdiReadyReadAsAudio = false;
|
||||
var cdiReadyReadAsAudio = false;
|
||||
uint firstLba;
|
||||
var outputOptical = _outputPlugin as IWritableOpticalImage;
|
||||
|
||||
@@ -541,7 +541,7 @@ sealed partial class Dump
|
||||
ErrorMessage?.Invoke(Localization.Core.Output_format_does_not_support_pregaps_continuing);
|
||||
}
|
||||
|
||||
for(int t = 1; t < tracks.Length; t++) tracks[t - 1].EndSector = tracks[t].StartSector - 1;
|
||||
for(var t = 1; t < tracks.Length; t++) tracks[t - 1].EndSector = tracks[t].StartSector - 1;
|
||||
|
||||
tracks[^1].EndSector = (ulong)lastSector;
|
||||
blocks = (ulong)(lastSector + 1);
|
||||
@@ -626,7 +626,7 @@ sealed partial class Dump
|
||||
|
||||
Tuple<ulong, ulong>[] dataExtentsArray = dataExtents.ToArray();
|
||||
|
||||
for(int i = 0; i < dataExtentsArray.Length - 1; i++)
|
||||
for(var i = 0; i < dataExtentsArray.Length - 1; i++)
|
||||
leadOutExtents.Add(dataExtentsArray[i].Item2 + 1, dataExtentsArray[i + 1].Item1 - 1);
|
||||
}
|
||||
|
||||
@@ -715,7 +715,7 @@ sealed partial class Dump
|
||||
continue;
|
||||
}
|
||||
|
||||
int bufOffset = 0;
|
||||
var bufOffset = 0;
|
||||
|
||||
while(cmdBuf[0 + bufOffset] != 0x00 ||
|
||||
cmdBuf[1 + bufOffset] != 0xFF ||
|
||||
@@ -928,7 +928,7 @@ sealed partial class Dump
|
||||
_dev.LastError));
|
||||
}
|
||||
|
||||
bool cdiWithHiddenTrack1 = false;
|
||||
var cdiWithHiddenTrack1 = false;
|
||||
|
||||
if(dskType is MediaType.CDIREADY && tracks.Min(t => t.Sequence) == 1)
|
||||
{
|
||||
@@ -978,7 +978,10 @@ sealed partial class Dump
|
||||
{
|
||||
foreach(Track imgTrack in outputOptical.Tracks)
|
||||
{
|
||||
errno = outputOptical.ReadSectorTag(imgTrack.Sequence, SectorTagType.CdTrackIsrc, out byte[] isrcBytes);
|
||||
errno = outputOptical.ReadSectorTag(imgTrack.Sequence,
|
||||
false,
|
||||
SectorTagType.CdTrackIsrc,
|
||||
out byte[] isrcBytes);
|
||||
|
||||
if(errno == ErrorNumber.NoError) isrcs[(byte)imgTrack.Sequence] = Encoding.ASCII.GetString(isrcBytes);
|
||||
|
||||
@@ -1041,7 +1044,7 @@ sealed partial class Dump
|
||||
|
||||
UpdateStatus?.Invoke(string.Format(Localization.Core.Setting_flags_for_track_0, track.Sequence));
|
||||
|
||||
outputOptical.WriteSectorTag([kvp.Value], kvp.Key, SectorTagType.CdTrackFlags);
|
||||
outputOptical.WriteSectorTag([kvp.Value], kvp.Key, false, SectorTagType.CdTrackFlags);
|
||||
}
|
||||
|
||||
// Set MCN
|
||||
@@ -1079,8 +1082,9 @@ sealed partial class Dump
|
||||
foreach(int sub in _resume.BadSubchannels) subchannelExtents.Add(sub);
|
||||
|
||||
if(_resume.NextBlock < blocks)
|
||||
for(ulong i = _resume.NextBlock; i < blocks; i++)
|
||||
subchannelExtents.Add((int)i);
|
||||
{
|
||||
for(ulong i = _resume.NextBlock; i < blocks; i++) subchannelExtents.Add((int)i);
|
||||
}
|
||||
}
|
||||
|
||||
if(_resume.NextBlock > 0)
|
||||
@@ -1495,8 +1499,9 @@ sealed partial class Dump
|
||||
supportsLongSectors);
|
||||
|
||||
foreach(Tuple<ulong, ulong> leadoutExtent in leadOutExtents.ToArray())
|
||||
for(ulong e = leadoutExtent.Item1; e <= leadoutExtent.Item2; e++)
|
||||
subchannelExtents.Remove((int)e);
|
||||
{
|
||||
for(ulong e = leadoutExtent.Item1; e <= leadoutExtent.Item2; e++) subchannelExtents.Remove((int)e);
|
||||
}
|
||||
|
||||
if(subchannelExtents.Count > 0 && _retryPasses > 0 && _retrySubchannel)
|
||||
{
|
||||
@@ -1583,7 +1588,10 @@ sealed partial class Dump
|
||||
foreach(KeyValuePair<byte, string> isrc in isrcs)
|
||||
{
|
||||
// TODO: Track tags
|
||||
if(!outputOptical.WriteSectorTag(Encoding.ASCII.GetBytes(isrc.Value), isrc.Key, SectorTagType.CdTrackIsrc))
|
||||
if(!outputOptical.WriteSectorTag(Encoding.ASCII.GetBytes(isrc.Value),
|
||||
isrc.Key,
|
||||
false,
|
||||
SectorTagType.CdTrackIsrc))
|
||||
continue;
|
||||
|
||||
UpdateStatus?.Invoke(string.Format(Localization.Core.Setting_ISRC_for_track_0_to_1, isrc.Key, isrc.Value));
|
||||
|
||||
@@ -466,9 +466,8 @@ partial class Dump
|
||||
|
||||
// MEDIUM ERROR, retry with ignore error below
|
||||
if(decSense is { ASC: 0x11 })
|
||||
{
|
||||
if(!sectorsNotEvenPartial.Contains(badSector)) sectorsNotEvenPartial.Add(badSector);
|
||||
}
|
||||
if(!sectorsNotEvenPartial.Contains(badSector))
|
||||
sectorsNotEvenPartial.Add(badSector);
|
||||
}
|
||||
|
||||
// Because one block has been partially used to fix the offset
|
||||
@@ -510,9 +509,9 @@ partial class Dump
|
||||
Array.Copy(cmdBuf, sectorSize, sub, 0, subSize);
|
||||
|
||||
if(supportsLongSectors)
|
||||
outputOptical.WriteSectorLong(data, badSector, SectorStatus.Dumped);
|
||||
outputOptical.WriteSectorLong(data, badSector, false, SectorStatus.Dumped);
|
||||
else
|
||||
outputOptical.WriteSector(Sector.GetUserData(data), badSector, SectorStatus.Dumped);
|
||||
outputOptical.WriteSector(Sector.GetUserData(data), badSector, false, SectorStatus.Dumped);
|
||||
|
||||
bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel,
|
||||
desiredSubchannel,
|
||||
@@ -543,9 +542,9 @@ partial class Dump
|
||||
else
|
||||
{
|
||||
if(supportsLongSectors)
|
||||
outputOptical.WriteSectorLong(cmdBuf, badSector, SectorStatus.Dumped);
|
||||
outputOptical.WriteSectorLong(cmdBuf, badSector, false, SectorStatus.Dumped);
|
||||
else
|
||||
outputOptical.WriteSector(Sector.GetUserData(cmdBuf), badSector, SectorStatus.Dumped);
|
||||
outputOptical.WriteSector(Sector.GetUserData(cmdBuf), badSector, false, SectorStatus.Dumped);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -663,9 +662,9 @@ partial class Dump
|
||||
Array.Copy(cmdBuf, sectorSize, sub, 0, subSize);
|
||||
|
||||
if(supportsLongSectors)
|
||||
outputOptical.WriteSectorLong(data, badSector, SectorStatus.Errored);
|
||||
outputOptical.WriteSectorLong(data, badSector, false, SectorStatus.Errored);
|
||||
else
|
||||
outputOptical.WriteSector(Sector.GetUserData(data), badSector, SectorStatus.Errored);
|
||||
outputOptical.WriteSector(Sector.GetUserData(data), badSector, false, SectorStatus.Errored);
|
||||
|
||||
bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel,
|
||||
desiredSubchannel,
|
||||
@@ -696,9 +695,12 @@ partial class Dump
|
||||
else
|
||||
{
|
||||
if(supportsLongSectors)
|
||||
outputOptical.WriteSectorLong(cmdBuf, badSector, SectorStatus.Errored);
|
||||
outputOptical.WriteSectorLong(cmdBuf, badSector, false, SectorStatus.Errored);
|
||||
else
|
||||
outputOptical.WriteSector(Sector.GetUserData(cmdBuf), badSector, SectorStatus.Errored);
|
||||
outputOptical.WriteSector(Sector.GetUserData(cmdBuf),
|
||||
badSector,
|
||||
false,
|
||||
SectorStatus.Errored);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -217,6 +217,7 @@ partial class Dump
|
||||
|
||||
outputOptical.WriteSectorsLong(data,
|
||||
i,
|
||||
false,
|
||||
_maximumReadable,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)_maximumReadable)
|
||||
.ToArray());
|
||||
@@ -251,11 +252,14 @@ partial class Dump
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
outputOptical.WriteSectors(cmdBuf,
|
||||
i,
|
||||
false,
|
||||
_maximumReadable,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)_maximumReadable)
|
||||
.ToArray());
|
||||
}
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
}
|
||||
@@ -271,15 +275,16 @@ partial class Dump
|
||||
|
||||
if(supportedSubchannel != MmcSubchannel.None)
|
||||
{
|
||||
outputOptical.WriteSectorsLong(new byte[sectorSize * _skip], i, 1, new SectorStatus[1]);
|
||||
outputOptical.WriteSectorsLong(new byte[sectorSize * _skip], i, false, 1, new SectorStatus[1]);
|
||||
|
||||
outputOptical.WriteSectorsTag(new byte[subSize * _skip],
|
||||
i,
|
||||
false,
|
||||
1,
|
||||
SectorTagType.CdSectorSubchannel);
|
||||
}
|
||||
else
|
||||
outputOptical.WriteSectors(new byte[blockSize * _skip], i, 1, new SectorStatus[1]);
|
||||
outputOptical.WriteSectors(new byte[blockSize * _skip], i, false, 1, new SectorStatus[1]);
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
|
||||
@@ -464,6 +469,7 @@ partial class Dump
|
||||
|
||||
outputOptical.WriteSectorsLong(data,
|
||||
i,
|
||||
false,
|
||||
_maximumReadable,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)_maximumReadable)
|
||||
.ToArray());
|
||||
@@ -498,11 +504,14 @@ partial class Dump
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
outputOptical.WriteSectors(cmdBuf,
|
||||
i,
|
||||
false,
|
||||
_maximumReadable,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)_maximumReadable)
|
||||
.ToArray());
|
||||
}
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
}
|
||||
@@ -518,18 +527,19 @@ partial class Dump
|
||||
|
||||
if(supportedSubchannel != MmcSubchannel.None)
|
||||
{
|
||||
outputOptical.WriteSectorsLong(new byte[sectorSize * _skip], i, 1, new SectorStatus[1]);
|
||||
outputOptical.WriteSectorsLong(new byte[sectorSize * _skip], i, false, 1, new SectorStatus[1]);
|
||||
|
||||
if(desiredSubchannel != MmcSubchannel.None)
|
||||
{
|
||||
outputOptical.WriteSectorsTag(new byte[subSize * _skip],
|
||||
i,
|
||||
false,
|
||||
1,
|
||||
SectorTagType.CdSectorSubchannel);
|
||||
}
|
||||
}
|
||||
else
|
||||
outputOptical.WriteSectors(new byte[blockSize * _skip], i, 1, new SectorStatus[1]);
|
||||
outputOptical.WriteSectors(new byte[blockSize * _skip], i, false, 1, new SectorStatus[1]);
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
|
||||
|
||||
@@ -102,9 +102,9 @@ partial class Dump
|
||||
}
|
||||
|
||||
if(supportsLongSectors)
|
||||
outputOptical.WriteSectorLong(sector, s, SectorStatus.Dumped);
|
||||
outputOptical.WriteSectorLong(sector, s, false, SectorStatus.Dumped);
|
||||
else
|
||||
outputOptical.WriteSector(Sector.GetUserData(sector), s, SectorStatus.Dumped);
|
||||
outputOptical.WriteSector(Sector.GetUserData(sector), s, false, SectorStatus.Dumped);
|
||||
|
||||
_resume.BadBlocks.Remove(s);
|
||||
extents.Add(s);
|
||||
@@ -145,7 +145,7 @@ partial class Dump
|
||||
|
||||
byte[] sub = Subchannel.Generate((int)s, track?.Sequence ?? 0, (int)pregap, (int)trackStart, flags, index);
|
||||
|
||||
outputOptical.WriteSectorsTag(sub, s, 1, SectorTagType.CdSectorSubchannel);
|
||||
outputOptical.WriteSectorsTag(sub, s, false, 1, SectorTagType.CdSectorSubchannel);
|
||||
|
||||
subLog?.WriteEntry(sub, true, (long)s, 1, true, false);
|
||||
subchannelExtents.Remove((int)s);
|
||||
|
||||
@@ -424,9 +424,9 @@ partial class Dump
|
||||
Array.Copy(cmdBuf, sectorSize, sub, 0, subSize);
|
||||
|
||||
if(supportsLongSectors)
|
||||
outputOptical.WriteSectorLong(data, badSector, SectorStatus.Dumped);
|
||||
outputOptical.WriteSectorLong(data, badSector, false, SectorStatus.Dumped);
|
||||
else
|
||||
outputOptical.WriteSector(Sector.GetUserData(data), badSector, SectorStatus.Dumped);
|
||||
outputOptical.WriteSector(Sector.GetUserData(data), badSector, false, SectorStatus.Dumped);
|
||||
|
||||
ulong trkStartBefore = track.StartSector;
|
||||
|
||||
@@ -468,9 +468,9 @@ partial class Dump
|
||||
}
|
||||
|
||||
if(supportsLongSectors)
|
||||
outputOptical.WriteSectorLong(cmdBuf, badSector, SectorStatus.Dumped);
|
||||
outputOptical.WriteSectorLong(cmdBuf, badSector, false, SectorStatus.Dumped);
|
||||
else
|
||||
outputOptical.WriteSector(Sector.GetUserData(cmdBuf), badSector, SectorStatus.Dumped);
|
||||
outputOptical.WriteSector(Sector.GetUserData(cmdBuf), badSector, false, SectorStatus.Dumped);
|
||||
}
|
||||
|
||||
_trimStopwatch.Stop();
|
||||
|
||||
@@ -377,6 +377,7 @@ partial class Dump
|
||||
|
||||
outputFormat.WriteSectors(readBuffer,
|
||||
i,
|
||||
false,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead).ToArray());
|
||||
|
||||
@@ -396,6 +397,7 @@ partial class Dump
|
||||
|
||||
outputFormat.WriteSectors(new byte[blockSize * _skip],
|
||||
i,
|
||||
false,
|
||||
_skip,
|
||||
Enumerable.Repeat(SectorStatus.NotDumped, (int)_skip).ToArray());
|
||||
|
||||
@@ -480,7 +482,7 @@ partial class Dump
|
||||
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
extents.Add(badSector);
|
||||
outputFormat.WriteSector(readBuffer, badSector, SectorStatus.Dumped);
|
||||
outputFormat.WriteSector(readBuffer, badSector, false, SectorStatus.Dumped);
|
||||
_mediaGraph?.PaintSectorGood(badSector);
|
||||
}
|
||||
|
||||
@@ -647,14 +649,14 @@ partial class Dump
|
||||
{
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
extents.Add(badSector);
|
||||
outputFormat.WriteSector(readBuffer, badSector, SectorStatus.Dumped);
|
||||
outputFormat.WriteSector(readBuffer, badSector, false, SectorStatus.Dumped);
|
||||
_mediaGraph?.PaintSectorGood(badSector);
|
||||
|
||||
UpdateStatus?.Invoke(string.Format(Localization.Core.Correctly_retried_block_0_in_pass_1,
|
||||
badSector,
|
||||
pass));
|
||||
}
|
||||
else if(runningPersistent) outputFormat.WriteSector(readBuffer, badSector, SectorStatus.Errored);
|
||||
else if(runningPersistent) outputFormat.WriteSector(readBuffer, badSector, false, SectorStatus.Errored);
|
||||
}
|
||||
|
||||
if(pass < _retryPasses && !_aborted && _resume.BadBlocks.Count > 0)
|
||||
|
||||
@@ -249,6 +249,7 @@ public partial class Dump
|
||||
|
||||
outputFormat.WriteSectors(readBuffer,
|
||||
i,
|
||||
false,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead).ToArray());
|
||||
|
||||
@@ -270,6 +271,7 @@ public partial class Dump
|
||||
|
||||
outputFormat.WriteSectors(new byte[blockSize * _skip],
|
||||
i,
|
||||
false,
|
||||
_skip,
|
||||
Enumerable.Repeat(SectorStatus.NotDumped, (int)_skip).ToArray());
|
||||
|
||||
@@ -373,7 +375,7 @@ public partial class Dump
|
||||
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
extents.Add(badSector);
|
||||
outputFormat.WriteSector(readBuffer, badSector, SectorStatus.Dumped);
|
||||
outputFormat.WriteSector(readBuffer, badSector, false, SectorStatus.Dumped);
|
||||
_mediaGraph?.PaintSectorGood(badSector);
|
||||
}
|
||||
|
||||
@@ -572,14 +574,14 @@ public partial class Dump
|
||||
{
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
extents.Add(badSector);
|
||||
outputFormat.WriteSector(readBuffer, badSector, SectorStatus.Dumped);
|
||||
outputFormat.WriteSector(readBuffer, badSector, false, SectorStatus.Dumped);
|
||||
_mediaGraph?.PaintSectorGood(badSector);
|
||||
|
||||
UpdateStatus?.Invoke(string.Format(Localization.Core.Correctly_retried_block_0_in_pass_1,
|
||||
badSector,
|
||||
pass));
|
||||
}
|
||||
else if(runningPersistent) outputFormat.WriteSector(readBuffer, badSector, SectorStatus.Errored);
|
||||
else if(runningPersistent) outputFormat.WriteSector(readBuffer, badSector, false, SectorStatus.Errored);
|
||||
}
|
||||
|
||||
if(pass < _retryPasses && !_aborted && _resume.BadBlocks.Count > 0)
|
||||
|
||||
@@ -288,6 +288,7 @@ public partial class Dump
|
||||
|
||||
outputOptical.WriteSectors(readBuffer,
|
||||
i,
|
||||
false,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead).ToArray());
|
||||
|
||||
@@ -307,6 +308,7 @@ public partial class Dump
|
||||
// Write empty data
|
||||
outputOptical.WriteSectors(new byte[blockSize * _skip],
|
||||
i,
|
||||
false,
|
||||
_skip,
|
||||
Enumerable.Repeat(SectorStatus.NotDumped, (int)_skip).ToArray());
|
||||
|
||||
@@ -409,7 +411,7 @@ public partial class Dump
|
||||
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
extents.Add(badSector);
|
||||
outputOptical.WriteSector(readBuffer, badSector, SectorStatus.Dumped);
|
||||
outputOptical.WriteSector(readBuffer, badSector, false, SectorStatus.Dumped);
|
||||
_mediaGraph?.PaintSectorGood(badSector);
|
||||
}
|
||||
|
||||
@@ -585,14 +587,15 @@ public partial class Dump
|
||||
{
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
extents.Add(badSector);
|
||||
outputOptical.WriteSector(readBuffer, badSector, SectorStatus.Dumped);
|
||||
outputOptical.WriteSector(readBuffer, badSector, false, SectorStatus.Dumped);
|
||||
_mediaGraph?.PaintSectorGood(badSector);
|
||||
|
||||
UpdateStatus?.Invoke(string.Format(Localization.Core.Correctly_retried_block_0_in_pass_1,
|
||||
badSector,
|
||||
pass));
|
||||
}
|
||||
else if(runningPersistent) outputOptical.WriteSector(readBuffer, badSector, SectorStatus.Errored);
|
||||
else if(runningPersistent)
|
||||
outputOptical.WriteSector(readBuffer, badSector, false, SectorStatus.Errored);
|
||||
}
|
||||
|
||||
if(pass < _retryPasses && !_aborted && _resume.BadBlocks.Count > 0)
|
||||
|
||||
@@ -285,8 +285,9 @@ partial class Dump
|
||||
Modes.DecodedMode? decMode = null;
|
||||
|
||||
if(!sense && !_dev.Error)
|
||||
if(Modes.DecodeMode10(cmdBuf, _dev.ScsiType).HasValue)
|
||||
decMode = Modes.DecodeMode10(cmdBuf, _dev.ScsiType);
|
||||
{
|
||||
if(Modes.DecodeMode10(cmdBuf, _dev.ScsiType).HasValue) decMode = Modes.DecodeMode10(cmdBuf, _dev.ScsiType);
|
||||
}
|
||||
|
||||
UpdateStatus?.Invoke(Localization.Core.Requesting_MODE_SENSE_6);
|
||||
|
||||
@@ -314,8 +315,9 @@ partial class Dump
|
||||
if(sense || _dev.Error) sense = _dev.ModeSense(out cmdBuf, out senseBuf, 5, out duration);
|
||||
|
||||
if(!sense && !_dev.Error)
|
||||
if(Modes.DecodeMode6(cmdBuf, _dev.ScsiType).HasValue)
|
||||
decMode = Modes.DecodeMode6(cmdBuf, _dev.ScsiType);
|
||||
{
|
||||
if(Modes.DecodeMode6(cmdBuf, _dev.ScsiType).HasValue) decMode = Modes.DecodeMode6(cmdBuf, _dev.ScsiType);
|
||||
}
|
||||
|
||||
// TODO: Check partitions page
|
||||
if(decMode.HasValue)
|
||||
@@ -1090,7 +1092,7 @@ partial class Dump
|
||||
|
||||
// Write empty data
|
||||
_writeStopwatch.Restart();
|
||||
outputTape.WriteSector(new byte[blockSize], currentBlock, SectorStatus.NotDumped);
|
||||
outputTape.WriteSector(new byte[blockSize], currentBlock, false, SectorStatus.NotDumped);
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
|
||||
mhddLog.Write(currentBlock, duration < 500 ? 65535 : duration);
|
||||
@@ -1102,7 +1104,7 @@ partial class Dump
|
||||
mhddLog.Write(currentBlock, duration);
|
||||
ibgLog.Write(currentBlock, currentSpeed * 1024);
|
||||
_writeStopwatch.Restart();
|
||||
outputTape.WriteSector(cmdBuf, currentBlock, SectorStatus.Dumped);
|
||||
outputTape.WriteSector(cmdBuf, currentBlock, false, SectorStatus.Dumped);
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
extents.Add(currentBlock, 1, true);
|
||||
}
|
||||
@@ -1297,13 +1299,13 @@ partial class Dump
|
||||
{
|
||||
_resume.BadBlocks.Remove(badBlock);
|
||||
extents.Add(badBlock);
|
||||
outputTape.WriteSector(cmdBuf, badBlock, SectorStatus.Dumped);
|
||||
outputTape.WriteSector(cmdBuf, badBlock, false, SectorStatus.Dumped);
|
||||
|
||||
UpdateStatus?.Invoke(string.Format(Localization.Core.Correctly_retried_block_0_in_pass_1,
|
||||
badBlock,
|
||||
pass));
|
||||
}
|
||||
else if(runningPersistent) outputTape.WriteSector(cmdBuf, badBlock, SectorStatus.Errored);
|
||||
else if(runningPersistent) outputTape.WriteSector(cmdBuf, badBlock, false, SectorStatus.Errored);
|
||||
}
|
||||
|
||||
if(pass < _retryPasses && !_aborted && _resume.BadBlocks.Count > 0)
|
||||
|
||||
@@ -126,7 +126,7 @@ partial class Dump
|
||||
|
||||
if(key.All(static k => k == 0))
|
||||
{
|
||||
outputFormat.WriteSectorTag([0, 0, 0, 0, 0], i + j, SectorTagType.DvdTitleKeyDecrypted);
|
||||
outputFormat.WriteSectorTag([0, 0, 0, 0, 0], i + j, false, SectorTagType.DvdTitleKeyDecrypted);
|
||||
|
||||
_resume.MissingTitleKeys?.Remove(i + j);
|
||||
|
||||
@@ -134,7 +134,7 @@ partial class Dump
|
||||
}
|
||||
|
||||
CSS.DecryptTitleKey(discKey, key, out tmpBuf);
|
||||
outputFormat.WriteSectorTag(tmpBuf, i + j, SectorTagType.DvdTitleKeyDecrypted);
|
||||
outputFormat.WriteSectorTag(tmpBuf, i + j, false, SectorTagType.DvdTitleKeyDecrypted);
|
||||
_resume.MissingTitleKeys?.Remove(i + j);
|
||||
|
||||
if(_storeEncrypted) continue;
|
||||
@@ -147,6 +147,7 @@ partial class Dump
|
||||
{
|
||||
ErrorNumber errno =
|
||||
outputFormat.ReadSectorsTag(i,
|
||||
false,
|
||||
blocksToRead,
|
||||
SectorTagType.DvdTitleKeyDecrypted,
|
||||
out byte[] titleKey);
|
||||
@@ -162,6 +163,7 @@ partial class Dump
|
||||
|
||||
outputFormat.WriteSectorsLong(buffer,
|
||||
i,
|
||||
false,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead).ToArray());
|
||||
|
||||
@@ -181,6 +183,7 @@ partial class Dump
|
||||
|
||||
outputFormat.WriteSectorsLong(new byte[blockSize * _skip],
|
||||
i,
|
||||
false,
|
||||
_skip,
|
||||
Enumerable.Repeat(SectorStatus.NotDumped, (int)_skip).ToArray());
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ partial class Dump
|
||||
CSS_CPRM.TitleKey? titleKey = CSS.DecodeTitleKey(tmpBuf, dvdDecrypt.BusKey);
|
||||
|
||||
if(titleKey.HasValue)
|
||||
outputFormat.WriteSectorTag([titleKey.Value.CMI], i + j, SectorTagType.DvdSectorCmi);
|
||||
outputFormat.WriteSectorTag([titleKey.Value.CMI], i + j, false, SectorTagType.DvdSectorCmi);
|
||||
else
|
||||
continue;
|
||||
|
||||
@@ -142,20 +142,23 @@ partial class Dump
|
||||
// not encrypted even if the CMI says it is.
|
||||
if(titleKey.Value.Key.All(static k => k == 0))
|
||||
{
|
||||
outputFormat.WriteSectorTag([0, 0, 0, 0, 0], i + j, SectorTagType.DvdSectorTitleKey);
|
||||
outputFormat.WriteSectorTag([0, 0, 0, 0, 0], i + j, false, SectorTagType.DvdSectorTitleKey);
|
||||
|
||||
outputFormat.WriteSectorTag([0, 0, 0, 0, 0], i + j, SectorTagType.DvdTitleKeyDecrypted);
|
||||
outputFormat.WriteSectorTag([0, 0, 0, 0, 0],
|
||||
i + j,
|
||||
false,
|
||||
SectorTagType.DvdTitleKeyDecrypted);
|
||||
|
||||
_resume.MissingTitleKeys.Remove(i + j);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
outputFormat.WriteSectorTag(titleKey.Value.Key, i + j, SectorTagType.DvdSectorTitleKey);
|
||||
outputFormat.WriteSectorTag(titleKey.Value.Key, i + j, false, SectorTagType.DvdSectorTitleKey);
|
||||
_resume.MissingTitleKeys.Remove(i + j);
|
||||
|
||||
CSS.DecryptTitleKey(discKey, titleKey.Value.Key, out tmpBuf);
|
||||
outputFormat.WriteSectorTag(tmpBuf, i + j, SectorTagType.DvdTitleKeyDecrypted);
|
||||
outputFormat.WriteSectorTag(tmpBuf, i + j, false, SectorTagType.DvdTitleKeyDecrypted);
|
||||
}
|
||||
|
||||
if(!_storeEncrypted)
|
||||
@@ -163,13 +166,18 @@ partial class Dump
|
||||
// Todo: Flag in the outputFormat that a sector has been decrypted
|
||||
{
|
||||
ErrorNumber errno =
|
||||
outputFormat.ReadSectorsTag(i, blocksToRead, SectorTagType.DvdSectorCmi, out byte[] cmi);
|
||||
outputFormat.ReadSectorsTag(i,
|
||||
false,
|
||||
blocksToRead,
|
||||
SectorTagType.DvdSectorCmi,
|
||||
out byte[] cmi);
|
||||
|
||||
if(errno != ErrorNumber.NoError)
|
||||
ErrorMessage?.Invoke(string.Format(Localization.Core.Error_retrieving_CMI_for_sector_0, i));
|
||||
else
|
||||
{
|
||||
errno = outputFormat.ReadSectorsTag(i,
|
||||
false,
|
||||
blocksToRead,
|
||||
SectorTagType.DvdTitleKeyDecrypted,
|
||||
out byte[] titleKey);
|
||||
@@ -192,6 +200,7 @@ partial class Dump
|
||||
|
||||
outputFormat.WriteSectors(buffer,
|
||||
i,
|
||||
false,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead).ToArray());
|
||||
|
||||
@@ -225,6 +234,7 @@ partial class Dump
|
||||
|
||||
outputFormat.WriteSectors(new byte[blockSize * _skip],
|
||||
i,
|
||||
false,
|
||||
_skip,
|
||||
Enumerable.Repeat(SectorStatus.NotDumped, (int)_skip).ToArray());
|
||||
|
||||
|
||||
@@ -316,14 +316,17 @@ partial class Dump
|
||||
|
||||
if(key.All(static k => k == 0))
|
||||
{
|
||||
outputFormat.WriteSectorTag([0, 0, 0, 0, 0], badSector, SectorTagType.DvdTitleKeyDecrypted);
|
||||
outputFormat.WriteSectorTag([0, 0, 0, 0, 0],
|
||||
badSector,
|
||||
false,
|
||||
SectorTagType.DvdTitleKeyDecrypted);
|
||||
|
||||
_resume.MissingTitleKeys?.Remove(badSector);
|
||||
}
|
||||
else
|
||||
{
|
||||
CSS.DecryptTitleKey(discKey, key, out byte[] tmpBuf);
|
||||
outputFormat.WriteSectorTag(tmpBuf, badSector, SectorTagType.DvdTitleKeyDecrypted);
|
||||
outputFormat.WriteSectorTag(tmpBuf, badSector, false, SectorTagType.DvdTitleKeyDecrypted);
|
||||
_resume.MissingTitleKeys?.Remove(badSector);
|
||||
|
||||
cmi[0] = buffer[6];
|
||||
@@ -333,6 +336,7 @@ partial class Dump
|
||||
{
|
||||
ErrorNumber errno =
|
||||
outputFormat.ReadSectorsTag(badSector,
|
||||
false,
|
||||
1,
|
||||
SectorTagType.DvdTitleKeyDecrypted,
|
||||
out byte[] titleKey);
|
||||
@@ -348,10 +352,10 @@ partial class Dump
|
||||
}
|
||||
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
outputFormat.WriteSectorLong(buffer, badSector, SectorStatus.Dumped);
|
||||
outputFormat.WriteSectorLong(buffer, badSector, false, SectorStatus.Dumped);
|
||||
}
|
||||
else
|
||||
outputFormat.WriteSector(buffer, badSector, SectorStatus.Dumped);
|
||||
outputFormat.WriteSector(buffer, badSector, false, SectorStatus.Dumped);
|
||||
|
||||
_mediaGraph?.PaintSectorGood(badSector);
|
||||
|
||||
@@ -359,7 +363,7 @@ partial class Dump
|
||||
badSector,
|
||||
pass));
|
||||
}
|
||||
else if(runningPersistent) outputFormat.WriteSector(buffer, badSector, SectorStatus.Errored);
|
||||
else if(runningPersistent) outputFormat.WriteSector(buffer, badSector, false, SectorStatus.Errored);
|
||||
}
|
||||
|
||||
if(pass < _retryPasses && !_aborted && _resume.BadBlocks.Count > 0)
|
||||
@@ -441,15 +445,15 @@ partial class Dump
|
||||
|
||||
if(!titleKey.HasValue) continue;
|
||||
|
||||
outputFormat.WriteSectorTag([titleKey.Value.CMI], missingKey, SectorTagType.DvdSectorCmi);
|
||||
outputFormat.WriteSectorTag([titleKey.Value.CMI], missingKey, false, 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([0, 0, 0, 0, 0], missingKey, SectorTagType.DvdSectorTitleKey);
|
||||
outputFormat.WriteSectorTag([0, 0, 0, 0, 0], missingKey, false, SectorTagType.DvdSectorTitleKey);
|
||||
|
||||
outputFormat.WriteSectorTag([0, 0, 0, 0, 0], missingKey, SectorTagType.DvdTitleKeyDecrypted);
|
||||
outputFormat.WriteSectorTag([0, 0, 0, 0, 0], missingKey, false, SectorTagType.DvdTitleKeyDecrypted);
|
||||
|
||||
_resume.MissingTitleKeys.Remove(missingKey);
|
||||
|
||||
@@ -459,13 +463,13 @@ partial class Dump
|
||||
}
|
||||
else
|
||||
{
|
||||
outputFormat.WriteSectorTag(titleKey.Value.Key, missingKey, SectorTagType.DvdSectorTitleKey);
|
||||
outputFormat.WriteSectorTag(titleKey.Value.Key, missingKey, false, SectorTagType.DvdSectorTitleKey);
|
||||
_resume.MissingTitleKeys.Remove(missingKey);
|
||||
|
||||
if(discKey != null)
|
||||
{
|
||||
CSS.DecryptTitleKey(discKey, titleKey.Value.Key, out buffer);
|
||||
outputFormat.WriteSectorTag(buffer, missingKey, SectorTagType.DvdTitleKeyDecrypted);
|
||||
outputFormat.WriteSectorTag(buffer, missingKey, false, SectorTagType.DvdTitleKeyDecrypted);
|
||||
}
|
||||
|
||||
UpdateStatus?.Invoke(string.Format(Localization.Core.Correctly_retried_title_key_0_in_pass_1,
|
||||
|
||||
@@ -180,8 +180,9 @@ 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);
|
||||
{
|
||||
for(ulong b = blank.Item1; b <= blank.Item2; b++) writtenExtents.Remove(b);
|
||||
}
|
||||
}
|
||||
|
||||
if(writtenExtents.Count == 0)
|
||||
@@ -239,6 +240,7 @@ partial class Dump
|
||||
|
||||
outputFormat.WriteSectors(buffer,
|
||||
i,
|
||||
false,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead).ToArray());
|
||||
|
||||
@@ -257,6 +259,7 @@ partial class Dump
|
||||
|
||||
outputFormat.WriteSectors(new byte[blockSize * _skip],
|
||||
i,
|
||||
false,
|
||||
_skip,
|
||||
Enumerable.Repeat(SectorStatus.NotDumped, (int)_skip).ToArray());
|
||||
|
||||
|
||||
@@ -107,14 +107,14 @@ partial class Dump
|
||||
|
||||
if(key.All(static k => k == 0))
|
||||
{
|
||||
outputFormat.WriteSectorTag([0, 0, 0, 0, 0], badSector, SectorTagType.DvdTitleKeyDecrypted);
|
||||
outputFormat.WriteSectorTag([0, 0, 0, 0, 0], badSector, false, SectorTagType.DvdTitleKeyDecrypted);
|
||||
|
||||
_resume.MissingTitleKeys?.Remove(badSector);
|
||||
}
|
||||
else
|
||||
{
|
||||
CSS.DecryptTitleKey(discKey, key, out byte[] tmpBuf);
|
||||
outputFormat.WriteSectorTag(tmpBuf, badSector, SectorTagType.DvdTitleKeyDecrypted);
|
||||
outputFormat.WriteSectorTag(tmpBuf, badSector, false, SectorTagType.DvdTitleKeyDecrypted);
|
||||
_resume.MissingTitleKeys?.Remove(badSector);
|
||||
|
||||
cmi[0] = buffer[6];
|
||||
@@ -124,6 +124,7 @@ partial class Dump
|
||||
{
|
||||
ErrorNumber errno =
|
||||
outputFormat.ReadSectorsTag(badSector,
|
||||
false,
|
||||
1,
|
||||
SectorTagType.DvdTitleKeyDecrypted,
|
||||
out byte[] titleKey);
|
||||
@@ -138,10 +139,10 @@ partial class Dump
|
||||
}
|
||||
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
outputFormat.WriteSectorLong(buffer, badSector, SectorStatus.Dumped);
|
||||
outputFormat.WriteSectorLong(buffer, badSector, false, SectorStatus.Dumped);
|
||||
}
|
||||
else
|
||||
outputFormat.WriteSector(buffer, badSector, SectorStatus.Dumped);
|
||||
outputFormat.WriteSector(buffer, badSector, false, SectorStatus.Dumped);
|
||||
|
||||
_mediaGraph?.PaintSectorGood(badSector);
|
||||
}
|
||||
|
||||
@@ -667,6 +667,7 @@ public partial class Dump
|
||||
|
||||
outputFormat.WriteSectors(cmdBuf,
|
||||
i,
|
||||
false,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, blocksToRead).ToArray());
|
||||
|
||||
@@ -689,6 +690,7 @@ public partial class Dump
|
||||
|
||||
outputFormat.WriteSectors(new byte[blockSize * _skip],
|
||||
i,
|
||||
false,
|
||||
_skip,
|
||||
Enumerable.Repeat(SectorStatus.NotDumped, (int)_skip).ToArray());
|
||||
|
||||
@@ -781,7 +783,7 @@ public partial class Dump
|
||||
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
extents.Add(badSector);
|
||||
outputFormat.WriteSector(cmdBuf, badSector, SectorStatus.Dumped);
|
||||
outputFormat.WriteSector(cmdBuf, badSector, false, SectorStatus.Dumped);
|
||||
_mediaGraph?.PaintSectorGood(badSector);
|
||||
}
|
||||
|
||||
@@ -842,7 +844,7 @@ public partial class Dump
|
||||
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
extents.Add(badSector);
|
||||
outputFormat.WriteSector(cmdBuf, badSector, SectorStatus.Dumped);
|
||||
outputFormat.WriteSector(cmdBuf, badSector, false, SectorStatus.Dumped);
|
||||
_mediaGraph?.PaintSectorGood(badSector);
|
||||
|
||||
UpdateStatus?.Invoke(string.Format(Localization.Core.Correctly_retried_block_0_in_pass_1,
|
||||
|
||||
@@ -686,6 +686,7 @@ partial class Dump
|
||||
|
||||
outputFormat.WriteSectors(readBuffer,
|
||||
i,
|
||||
false,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead).ToArray());
|
||||
|
||||
@@ -707,6 +708,7 @@ partial class Dump
|
||||
|
||||
outputFormat.WriteSectors(new byte[blockSize * _skip],
|
||||
i,
|
||||
false,
|
||||
_skip,
|
||||
Enumerable.Repeat(SectorStatus.NotDumped, (int)_skip).ToArray());
|
||||
|
||||
@@ -770,6 +772,7 @@ partial class Dump
|
||||
|
||||
outputFormat.WriteSectors(new byte[blockSize * blocksToRead],
|
||||
i,
|
||||
false,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead).ToArray());
|
||||
|
||||
@@ -820,6 +823,7 @@ partial class Dump
|
||||
|
||||
outputFormat.WriteSectors(new byte[blockSize * blocksToRead],
|
||||
middle + currentSector,
|
||||
false,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.NotDumped, (int)blocksToRead).ToArray());
|
||||
|
||||
@@ -910,6 +914,7 @@ partial class Dump
|
||||
|
||||
outputFormat.WriteSectors(readBuffer,
|
||||
currentSector,
|
||||
false,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead).ToArray());
|
||||
|
||||
@@ -929,6 +934,7 @@ partial class Dump
|
||||
|
||||
outputFormat.WriteSectors(new byte[blockSize * _skip],
|
||||
currentSector,
|
||||
false,
|
||||
_skip,
|
||||
Enumerable.Repeat(SectorStatus.NotDumped, (int)_skip).ToArray());
|
||||
|
||||
@@ -1060,7 +1066,7 @@ partial class Dump
|
||||
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
extents.Add(badSector);
|
||||
outputFormat.WriteSector(readBuffer, badSector, SectorStatus.Dumped);
|
||||
outputFormat.WriteSector(readBuffer, badSector, false, SectorStatus.Dumped);
|
||||
_mediaGraph?.PaintSectorGood(badSector);
|
||||
}
|
||||
|
||||
@@ -1080,9 +1086,8 @@ partial class Dump
|
||||
List<ulong> tmpList = [];
|
||||
|
||||
foreach(ulong ur in _resume.BadBlocks)
|
||||
{
|
||||
for(ulong i = ur; i < ur + blocksToRead; i++) tmpList.Add(i);
|
||||
}
|
||||
for(ulong i = ur; i < ur + blocksToRead; i++)
|
||||
tmpList.Add(i);
|
||||
|
||||
tmpList.Sort();
|
||||
|
||||
@@ -1261,14 +1266,14 @@ partial class Dump
|
||||
{
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
extents.Add(badSector);
|
||||
outputFormat.WriteSector(readBuffer, badSector, SectorStatus.Dumped);
|
||||
outputFormat.WriteSector(readBuffer, badSector, false, SectorStatus.Dumped);
|
||||
_mediaGraph?.PaintSectorGood(badSector);
|
||||
|
||||
UpdateStatus?.Invoke(string.Format(Localization.Core.Correctly_retried_block_0_in_pass_1,
|
||||
badSector,
|
||||
pass));
|
||||
}
|
||||
else if(runningPersistent) outputFormat.WriteSector(readBuffer, badSector, SectorStatus.Errored);
|
||||
else if(runningPersistent) outputFormat.WriteSector(readBuffer, badSector, false, SectorStatus.Errored);
|
||||
}
|
||||
|
||||
if(pass < _retryPasses && !_aborted && _resume.BadBlocks.Count > 0)
|
||||
|
||||
Reference in New Issue
Block a user