Add support for negative and overflow sectors in image creation

This commit is contained in:
2025-10-23 11:21:47 +01:00
parent 23873fb2f5
commit e2d4ea76b8
55 changed files with 223 additions and 150 deletions

View File

@@ -240,7 +240,8 @@ public partial class Dump
_dev.IsPcmcia,
blocks);
ret = outputFormat.Create(_outputPath, mediaType, _formatOptions, blocks, blockSize);
// TODO: HPA
ret = outputFormat.Create(_outputPath, mediaType, _formatOptions, blocks, 0, 0, blockSize);
// Cannot create image
if(!ret)

View File

@@ -955,6 +955,14 @@ sealed partial class Dump
dskType,
_formatOptions,
blocks,
(uint)(outputOptical.OpticalCapabilities.HasFlag(OpticalImageCapabilities
.CanStoreNegativeSectors)
? 2750
: 0),
(uint)(outputOptical.OpticalCapabilities.HasFlag(OpticalImageCapabilities
.CanStoreOverflowSectors)
? 2750
: 0),
supportsLongSectors ? blockSize : 2048);
// Cannot create image
@@ -1082,9 +1090,8 @@ 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)
@@ -1499,9 +1506,8 @@ 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)
{

View File

@@ -213,7 +213,7 @@ partial class Dump
_dimensions);
var ibgLog = new IbgLog(_outputPrefix + ".ibg", sbcProfile);
ret = outputFormat.Create(_outputPath, dskType, _formatOptions, blocks, blockSize);
ret = outputFormat.Create(_outputPath, dskType, _formatOptions, blocks, 0, 0, blockSize);
// Cannot create image
if(!ret)

View File

@@ -132,7 +132,7 @@ public partial class Dump
_dimensions);
var ibgLog = new IbgLog(_outputPrefix + ".ibg", sbcProfile);
ret = outputFormat.Create(_outputPath, dskType, _formatOptions, blocks, blockSize);
ret = outputFormat.Create(_outputPath, dskType, _formatOptions, blocks, 0, 0, blockSize);
// Cannot create image
if(!ret)

View File

@@ -157,7 +157,9 @@ public partial class Dump
_dimensions);
var ibgLog = new IbgLog(_outputPrefix + ".ibg", 0x0010);
ret = outputOptical.Create(_outputPath, dskType, _formatOptions, blocks, blockSize);
// TODO: Get the PFI from the UMD
ret = outputOptical.Create(_outputPath, dskType, _formatOptions, blocks, 0, 0, blockSize);
// Cannot create image
if(!ret)

View File

@@ -285,9 +285,8 @@ 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);
@@ -315,9 +314,8 @@ 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)
@@ -826,7 +824,7 @@ partial class Dump
return;
}
ret = outputTape.Create(_outputPath, dskType, _formatOptions, 0, 0);
ret = outputTape.Create(_outputPath, dskType, _formatOptions, 0, 0, 0, 0);
// Cannot create image
if(!ret)

View File

@@ -78,7 +78,7 @@ partial class Dump
bool sense;
byte scsiMediumType = 0;
byte scsiDensityCode = 0;
bool containsFloppyPage = false;
var containsFloppyPage = false;
const ushort sbcProfile = 0x0001;
double totalDuration = 0;
double currentSpeed = 0;
@@ -366,12 +366,12 @@ partial class Dump
_private,
_dimensions);
var ibgLog = new IbgLog(_outputPrefix + ".ibg", sbcProfile);
bool imageCreated = false;
var ibgLog = new IbgLog(_outputPrefix + ".ibg", sbcProfile);
var imageCreated = false;
if(!opticalDisc)
{
ret = outputFormat.Create(_outputPath, dskType, _formatOptions, blocks, blockSize);
ret = outputFormat.Create(_outputPath, dskType, _formatOptions, blocks, 0, 0, blockSize);
// Cannot create image
if(!ret)
@@ -388,12 +388,23 @@ partial class Dump
_dumpStopwatch.Restart();
double imageWriteDuration = 0;
bool writeSingleOpticalTrack = true;
var writeSingleOpticalTrack = true;
uint nominalNegativeSectors = 0;
if(opticalDisc)
{
if(outputFormat is IWritableOpticalImage opticalPlugin)
{
mediaTags.TryGetValue(MediaTagType.DVD_PFI, out byte[] pfi);
PFI.PhysicalFormatInformation? decodedPfi = PFI.Decode(pfi, dskType);
if(decodedPfi.HasValue) nominalNegativeSectors = decodedPfi.Value.DataAreaStartPSN;
mediaTags.TryGetValue(MediaTagType.BD_DI, out byte[] di);
DI.DiscInformation? decodedDi = DI.Decode(di);
if(decodedDi.HasValue) nominalNegativeSectors = decodedDi.Value.Units[0].FirstAun;
sense = _dev.ReadDiscInformation(out byte[] readBuffer,
out _,
MmcDiscInformationDataTypes.DiscInformation,
@@ -515,7 +526,19 @@ partial class Dump
else
tracks = tracks.OrderBy(t => t.Sequence).ToList();
ret = outputFormat.Create(_outputPath, dskType, _formatOptions, blocks, blockSize);
ret = outputFormat.Create(_outputPath,
dskType,
_formatOptions,
blocks,
(outputFormat as IWritableOpticalImage).OpticalCapabilities
.HasFlag(OpticalImageCapabilities.CanStoreNegativeSectors)
? nominalNegativeSectors
: 0,
(outputFormat as IWritableOpticalImage).OpticalCapabilities
.HasFlag(OpticalImageCapabilities.CanStoreOverflowSectors)
? 15000u
: 0,
blockSize);
// Cannot create image
if(!ret)
@@ -582,7 +605,7 @@ partial class Dump
}
else if(decMode?.Pages != null)
{
bool setGeometry = false;
var setGeometry = false;
foreach(Modes.ModePage page in decMode.Value.Pages)
{
@@ -636,7 +659,21 @@ partial class Dump
if(!imageCreated)
{
ret = outputFormat.Create(_outputPath, dskType, _formatOptions, blocks, blockSize);
ret = outputFormat.Create(_outputPath,
dskType,
_formatOptions,
blocks,
(outputFormat as IWritableOpticalImage).OpticalCapabilities
.HasFlag(OpticalImageCapabilities
.CanStoreNegativeSectors)
? nominalNegativeSectors
: 0,
(outputFormat as IWritableOpticalImage).OpticalCapabilities
.HasFlag(OpticalImageCapabilities
.CanStoreOverflowSectors)
? 15000u
: 0,
blockSize);
// Cannot create image
if(!ret)
@@ -736,7 +773,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 &&

View File

@@ -446,6 +446,8 @@ public partial class Dump
_dev.Type == DeviceType.SecureDigital ? MediaType.SecureDigital : MediaType.MMC,
_formatOptions,
blocks,
0,
0,
blockSize);
// Cannot create image

View File

@@ -506,7 +506,7 @@ partial class Dump
_dimensions);
var ibgLog = new IbgLog(_outputPrefix + ".ibg", 0x0010);
ret = outputFormat.Create(_outputPath, dskType, _formatOptions, blocks, blockSize);
ret = outputFormat.Create(_outputPath, dskType, _formatOptions, blocks, 0, 0, blockSize);
// Cannot create image
if(!ret)
@@ -1086,8 +1086,9 @@ 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();