From 333d1e43109e014766166e7da3c06603b307cc92 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Mon, 18 Apr 2022 15:37:36 +0100 Subject: [PATCH] Handle dumping CD-i discs with audio tracks and a hidden data track 1. Fixes #703 --- .../Devices/Dumping/CompactDisc/CdiReady.cs | 12 ++++++------ Aaru.Core/Devices/Dumping/CompactDisc/Dump.cs | 17 +++++++++++++---- Aaru.Core/Media/Detection/MMC.cs | 6 ++++-- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/Aaru.Core/Devices/Dumping/CompactDisc/CdiReady.cs b/Aaru.Core/Devices/Dumping/CompactDisc/CdiReady.cs index 1f4c32ab1..8b129aadf 100644 --- a/Aaru.Core/Devices/Dumping/CompactDisc/CdiReady.cs +++ b/Aaru.Core/Devices/Dumping/CompactDisc/CdiReady.cs @@ -161,7 +161,7 @@ partial class Dump byte[] senseBuf; // Sense buffer double cmdDuration; // Command execution time const uint sectorSize = 2352; // Full sector size - Track firstTrack = tracks.FirstOrDefault(t => t.Sequence == 1); + Track firstTrack = tracks.FirstOrDefault(); uint blocksToRead; // How many sectors to read at once var outputOptical = _outputPlugin as IWritableOpticalImage; @@ -178,7 +178,7 @@ partial class Dump InitProgress?.Invoke(); - for(ulong i = _resume.NextBlock; i < firstTrack.StartSector; i += blocksToRead) + for(ulong i = _resume.NextBlock; i <= firstTrack.EndSector; i += blocksToRead) { if(_aborted) { @@ -287,13 +287,13 @@ partial class Dump { _errorLog?.WriteLine(i + r, _dev.Error, _dev.LastError, senseBuf); - leadOutExtents.Add(i + r, firstTrack.StartSector - 1); + leadOutExtents.Add(i + r, firstTrack.EndSector); UpdateStatus?. - Invoke($"Adding CD-i Ready hole from LBA {i + r} to {firstTrack.StartSector - 1} inclusive."); + Invoke($"Adding CD-i Ready hole from LBA {i + r} to {firstTrack.EndSector} inclusive."); _dumpLog.WriteLine("Adding CD-i Ready hole from LBA {0} to {1} inclusive.", i + r, - firstTrack.StartSector - 1); + firstTrack.EndSector); break; } @@ -397,7 +397,7 @@ partial class Dump { _errorLog?.WriteLine(i, _dev.Error, _dev.LastError, senseBuf); - _resume.NextBlock = firstTrack.StartSector; + _resume.NextBlock = firstTrack.EndSector + 1; break; } diff --git a/Aaru.Core/Devices/Dumping/CompactDisc/Dump.cs b/Aaru.Core/Devices/Dumping/CompactDisc/Dump.cs index 03b988a8d..5fca8e601 100644 --- a/Aaru.Core/Devices/Dumping/CompactDisc/Dump.cs +++ b/Aaru.Core/Devices/Dumping/CompactDisc/Dump.cs @@ -562,14 +562,14 @@ sealed partial class Dump { new Track { - Sequence = 0, + Sequence = (uint)(tracks.Any(t => t.Sequence == 1) ? 0 : 1), Session = 1, Type = hiddenData ? TrackType.Data : TrackType.Audio, StartSector = 0, BytesPerSector = (int)sectorSize, RawBytesPerSector = (int)sectorSize, SubchannelType = subType, - EndSector = tracks.First(t => t.Sequence == 1).StartSector - 1 + EndSector = tracks.First(t => t.Sequence >= 1).StartSector - 1 } }; @@ -785,6 +785,15 @@ sealed partial class Dump StoppingErrorMessage?.Invoke($"Device error {_dev.LastError} trying to guess ideal transfer length."); } + var cdiWithHiddenTrack1 = false; + + if(dskType is MediaType.CDIREADY && + tracks.Min(t => t.Sequence) == 1) + { + cdiWithHiddenTrack1 = true; + dskType = MediaType.CDI; + } + // Try to read the first track pregap if(_dumpFirstTrackPregap && readcd) ReadCdFirstTrackPregap(blockSize, ref currentSpeed, mediaTags, supportedSubchannel, ref totalDuration); @@ -1099,9 +1108,9 @@ sealed partial class Dump // Start reading start = DateTime.UtcNow; - if(dskType == MediaType.CDIREADY) + if(dskType == MediaType.CDIREADY || cdiWithHiddenTrack1) { - Track track0 = tracks.FirstOrDefault(t => t.Sequence == 0); + Track track0 = tracks.FirstOrDefault(t => t.Sequence is 0 or 1); track0.Type = TrackType.CdMode2Formless; diff --git a/Aaru.Core/Media/Detection/MMC.cs b/Aaru.Core/Media/Detection/MMC.cs index 7f855872c..0d91b2896 100644 --- a/Aaru.Core/Media/Detection/MMC.cs +++ b/Aaru.Core/Media/Detection/MMC.cs @@ -670,9 +670,11 @@ public static class MMC Array.Copy(cmdBuf, 0, videoNowColorFrame, i * 2352, 2352); } - FullTOC.TrackDataDescriptor? firstTrack = decodedToc?.TrackDescriptors.FirstOrDefault(t => t.POINT == 1); + FullTOC.TrackDataDescriptor? firstTrack = + decodedToc?.TrackDescriptors.FirstOrDefault(t => t.POINT == + decodedToc.Value.TrackDescriptors.Min(m => m.POINT)); - if(firstTrack?.POINT == 1) + if(firstTrack?.POINT is >= 1 and < 0xA0) { var firstTrackSector = (uint)(firstTrack.Value.PHOUR * 3600 * 75 + firstTrack.Value.PMIN * 60 * 75 + firstTrack.Value.PSEC * 75 + firstTrack.Value.PFRAME - 150);