diff --git a/Aaru.Images/CDRWin/CDRWin.cs b/Aaru.Images/CDRWin/CDRWin.cs
index 578b4dda0..6a072a22e 100644
--- a/Aaru.Images/CDRWin/CDRWin.cs
+++ b/Aaru.Images/CDRWin/CDRWin.cs
@@ -50,6 +50,8 @@ namespace Aaru.DiscImages
ImageInfo _imageInfo;
Stream _imageStream;
bool _isCd;
+ uint _lostPregap;
+ bool _negativeEnd;
/// Dictionary, index is track #, value is TrackFile
Dictionary _offsetMap;
SectorBuilder _sectorBuilder;
diff --git a/Aaru.Images/CDRWin/Read.cs b/Aaru.Images/CDRWin/Read.cs
index fa80525cd..45dadb5f2 100644
--- a/Aaru.Images/CDRWin/Read.cs
+++ b/Aaru.Images/CDRWin/Read.cs
@@ -497,6 +497,8 @@ namespace Aaru.DiscImages
currentFile.Sequence = currentTrack.Sequence;
currentTrack.TrackFile = currentFile;
+ _negativeEnd = currentFile.DataFilter.GetLength() - (long)currentFile.Offset < 0;
+
currentTrack.Sectors =
((ulong)currentFile.DataFilter.GetLength() - currentFile.Offset) /
CdrWinTrackTypeToBytesPerSector(currentTrack.TrackType);
@@ -808,12 +810,55 @@ namespace Aaru.DiscImages
currentFile.Sequence = currentTrack.Sequence;
currentTrack.TrackFile = currentFile;
+ _negativeEnd = currentFile.DataFilter.GetLength() - (long)currentFile.Offset < 0;
+
currentTrack.Sectors = ((ulong)currentFile.DataFilter.GetLength() - currentFile.Offset) /
CdrWinTrackTypeToBytesPerSector(currentTrack.TrackType);
cueTracks[currentTrack.Sequence - 1] = currentTrack;
}
+ if(_negativeEnd)
+ {
+ string firstFile = cueTracks[0].TrackFile.DataFilter.GetPath();
+
+ if(cueTracks.Any(t => t.Session > 1 || t.TrackFile.DataFilter.GetPath() != firstFile) ||
+ cueTracks[0].Indexes.ContainsKey(0))
+ {
+ AaruConsole.
+ ErrorWriteLine("The data files are not correct according to the cuesheet file, cannot continue with this file.");
+
+ return false;
+ }
+
+ cueTracks[0].Pregap = cueTracks[0].Indexes[1];
+ int reduceOffset = cueTracks[0].Pregap * cueTracks[0].Bps;
+
+ foreach(CdrWinTrack track in cueTracks)
+ track.TrackFile.Offset -= (ulong)reduceOffset;
+
+ if(currentFile.DataFilter.GetLength() -
+ (long)cueTracks[currentTrack.Sequence - 1].TrackFile.Offset < 0)
+ {
+ AaruConsole.
+ ErrorWriteLine("The data files are not correct according to the cuesheet file, cannot continue with this file.");
+
+ return false;
+ }
+
+ cueTracks[currentTrack.Sequence - 1].Sectors =
+ ((ulong)currentFile.DataFilter.GetLength() -
+ cueTracks[currentTrack.Sequence - 1].TrackFile.Offset) /
+ cueTracks[currentTrack.Sequence - 1].Bps;
+
+ cueTracks[0].Indexes[0] = 0;
+ _lostPregap = (uint)cueTracks[0].Pregap;
+ cueTracks[0].Sectors += _lostPregap;
+
+ AaruConsole.
+ ErrorWriteLine("The data files are missing a pregap or hidden track contents, will do best effort to make the rest of the image readable.");
+ }
+
Session[] sessions = new Session[currentSession];
for(int s = 1; s <= sessions.Length; s++)
@@ -1588,6 +1633,27 @@ namespace Aaru.DiscImages
byte[] buffer = new byte[sectorSize * length];
+ // If it's the lost pregap
+ if(track == 1 &&
+ _lostPregap > 0)
+ {
+ if(sectorAddress < _lostPregap)
+ {
+ // If we need to mix lost with present data
+ if(sectorAddress + length <= _lostPregap)
+ return buffer;
+
+ ulong pregapPos = _lostPregap - sectorAddress;
+
+ byte[] presentData = ReadSectors(_lostPregap, (uint)(length - pregapPos), track);
+ Array.Copy(presentData, 0, buffer, (long)(pregapPos * sectorSize), presentData.Length);
+
+ return buffer;
+ }
+
+ sectorAddress -= _lostPregap;
+ }
+
_imageStream = aaruTrack.TrackFile.DataFilter.GetDataForkStream();
var br = new BinaryReader(_imageStream);
@@ -1815,6 +1881,27 @@ namespace Aaru.DiscImages
byte[] buffer = new byte[sectorSize * length];
+ // If it's the lost pregap
+ if(track == 1 &&
+ _lostPregap > 0)
+ {
+ if(sectorAddress < _lostPregap)
+ {
+ // If we need to mix lost with present data
+ if(sectorAddress + length <= _lostPregap)
+ return buffer;
+
+ ulong pregapPos = _lostPregap - sectorAddress;
+
+ byte[] presentData = ReadSectors(_lostPregap, (uint)(length - pregapPos), track);
+ Array.Copy(presentData, 0, buffer, (long)(pregapPos * sectorSize), presentData.Length);
+
+ return buffer;
+ }
+
+ sectorAddress -= _lostPregap;
+ }
+
_imageStream = aaruTrack.TrackFile.DataFilter.GetDataForkStream();
var br = new BinaryReader(_imageStream);
@@ -1932,6 +2019,27 @@ namespace Aaru.DiscImages
byte[] buffer = new byte[sectorSize * length];
+ // If it's the lost pregap
+ if(track == 1 &&
+ _lostPregap > 0)
+ {
+ if(sectorAddress < _lostPregap)
+ {
+ // If we need to mix lost with present data
+ if(sectorAddress + length <= _lostPregap)
+ return buffer;
+
+ ulong pregapPos = _lostPregap - sectorAddress;
+
+ byte[] presentData = ReadSectors(_lostPregap, (uint)(length - pregapPos), track);
+ Array.Copy(presentData, 0, buffer, (long)(pregapPos * sectorSize), presentData.Length);
+
+ return buffer;
+ }
+
+ sectorAddress -= _lostPregap;
+ }
+
_imageStream = aaruTrack.TrackFile.DataFilter.GetDataForkStream();
var br = new BinaryReader(_imageStream);