diff --git a/Aaru.Core/Devices/Dumping/CompactDisc/Data.cs b/Aaru.Core/Devices/Dumping/CompactDisc/Data.cs index d91468ea0..e3a30fccc 100644 --- a/Aaru.Core/Devices/Dumping/CompactDisc/Data.cs +++ b/Aaru.Core/Devices/Dumping/CompactDisc/Data.cs @@ -35,6 +35,7 @@ using System.Collections.Generic; using System.Linq; using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Extents; +using Aaru.CommonTypes.Interfaces; using Aaru.CommonTypes.Structs; using Aaru.Console; using Aaru.Core.Logging; @@ -387,8 +388,18 @@ namespace Aaru.Core.Devices.Dumping _outputPlugin.WriteSectorsLong(data, i + r, 1); - WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, i + r, 1, subLog, - isrcs, (byte)track.TrackSequence, ref mcn); + bool indexesChanged = + WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, i + r, 1, + subLog, isrcs, (byte)track.TrackSequence, ref mcn, tracks); + + // Set tracks and go back + if(indexesChanged) + { + (_outputPlugin as IWritableOpticalImage).SetTracks(tracks.ToList()); + i -= blocksToRead; + + continue; + } } else { @@ -501,8 +512,18 @@ namespace Aaru.Core.Devices.Dumping _outputPlugin.WriteSectorsLong(data, i, blocksToRead); - WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, i, blocksToRead, subLog, - isrcs, (byte)track.TrackSequence, ref mcn); + bool indexesChanged = WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, i, + blocksToRead, subLog, isrcs, + (byte)track.TrackSequence, ref mcn, tracks); + + // Set tracks and go back + if(indexesChanged) + { + (_outputPlugin as IWritableOpticalImage).SetTracks(tracks.ToList()); + i -= blocksToRead; + + continue; + } } else { diff --git a/Aaru.Core/Devices/Dumping/CompactDisc/Dump.cs b/Aaru.Core/Devices/Dumping/CompactDisc/Dump.cs index 40641bcbf..fef287573 100644 --- a/Aaru.Core/Devices/Dumping/CompactDisc/Dump.cs +++ b/Aaru.Core/Devices/Dumping/CompactDisc/Dump.cs @@ -376,6 +376,9 @@ namespace Aaru.Core.Devices.Dumping if(tracks is null) return; + _dumpLog.WriteLine("Calculating pregaps, can take some time..."); + UpdateStatus?.Invoke("Calculating pregaps, can take some time..."); + SolveTrackPregaps(_dev, _dumpLog, UpdateStatus, tracks, supportsPqSubchannel, supportsRwSubchannel, _dbDev, out bool inexactPositioning); @@ -532,28 +535,18 @@ namespace Aaru.Core.Devices.Dumping _dumpLog.WriteLine("Checking mode for track {0}...", tracks[t].TrackSequence); UpdateStatus?.Invoke($"Checking mode for track {tracks[t].TrackSequence}..."); - sense = _dev.ReadCd(out cmdBuf, out _, (uint)tracks[t].TrackStartSector, blockSize, 1, - MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, - MmcErrorField.None, supportedSubchannel, _dev.Timeout, out _); + sense = _dev.ReadCd(out cmdBuf, out _, (uint)(tracks[t].TrackStartSector + tracks[t].TrackPregap), + blockSize, 1, MmcSectorTypes.AllTypes, false, false, true, + MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, supportedSubchannel, + _dev.Timeout, out _); if(sense) { - if(tracks[t].TrackPregap != 0) - sense = _dev.ReadCd(out cmdBuf, out _, - (uint)(tracks[t].TrackStartSector + tracks[t].TrackPregap), blockSize, 1, - MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, - true, true, MmcErrorField.None, supportedSubchannel, _dev.Timeout, out _); + _dumpLog.WriteLine("Unable to guess mode for track {0}, continuing...", tracks[t].TrackSequence); - if(sense) - { - _dumpLog.WriteLine("Unable to guess mode for track {0}, continuing...", - tracks[t].TrackSequence); + UpdateStatus?.Invoke($"Unable to guess mode for track {tracks[t].TrackSequence}, continuing..."); - UpdateStatus?. - Invoke($"Unable to guess mode for track {tracks[t].TrackSequence}, continuing..."); - - continue; - } + continue; } switch(cmdBuf[15]) @@ -1028,7 +1021,7 @@ namespace Aaru.Core.Devices.Dumping /* DumpCdLeadOuts(blocks, blockSize, ref currentSpeed, currentTry, extents, ibgLog, ref imageWriteDuration, leadOutExtents, ref maxSpeed, mhddLog, ref minSpeed, read6, read10, read12, read16, readcd, - supportedSubchannel, subSize, ref totalDuration, subLog, desiredSubchannel, isrcs, ref mcn); + supportedSubchannel, subSize, ref totalDuration, subLog, desiredSubchannel, isrcs, ref mcn, tracks); */ end = DateTime.UtcNow; diff --git a/Aaru.Core/Devices/Dumping/CompactDisc/Error.cs b/Aaru.Core/Devices/Dumping/CompactDisc/Error.cs index 9434b68c0..18d0a3257 100644 --- a/Aaru.Core/Devices/Dumping/CompactDisc/Error.cs +++ b/Aaru.Core/Devices/Dumping/CompactDisc/Error.cs @@ -34,6 +34,7 @@ using System; using System.Collections.Generic; using System.Linq; using Aaru.CommonTypes.Extents; +using Aaru.CommonTypes.Interfaces; using Aaru.CommonTypes.Structs; using Aaru.CommonTypes.Structs.Devices.SCSI; using Aaru.Console; @@ -194,8 +195,10 @@ namespace Aaru.Core.Devices.Dumping ulong[] tmpArray = _resume.BadBlocks.ToArray(); List sectorsNotEvenPartial = new List(); - foreach(ulong badSector in tmpArray) + for(int i = 0; i < tmpArray.Length; i++) { + ulong badSector = tmpArray[i]; + if(_aborted) { currentTry.Extents = ExtentsConverter.ToMetadata(extents); @@ -285,8 +288,16 @@ namespace Aaru.Core.Devices.Dumping Array.Copy(cmdBuf, sectorSize, sub, 0, subSize); _outputPlugin.WriteSectorLong(data, badSector); - WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, badSector, 1, subLog, isrcs, - (byte)track.TrackSequence, ref mcn); + bool indexesChanged = WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, badSector, + 1, subLog, isrcs, (byte)track.TrackSequence, ref mcn, + tracks); + + // Set tracks and go back + if(indexesChanged) + { + (_outputPlugin as IWritableOpticalImage).SetTracks(tracks.ToList()); + i--; + } } else { @@ -349,8 +360,10 @@ namespace Aaru.Core.Devices.Dumping InitProgress?.Invoke(); - foreach(ulong badSector in sectorsNotEvenPartial) + for(int i = 0; i < sectorsNotEvenPartial.Count; i++) { + ulong badSector = sectorsNotEvenPartial[i]; + if(_aborted) { currentTry.Extents = ExtentsConverter.ToMetadata(extents); @@ -387,8 +400,16 @@ namespace Aaru.Core.Devices.Dumping Array.Copy(cmdBuf, sectorSize, sub, 0, subSize); _outputPlugin.WriteSectorLong(data, badSector); - WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, badSector, 1, subLog, - isrcs, (byte)track.TrackSequence, ref mcn); + bool indexesChanged = WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, + badSector, 1, subLog, isrcs, + (byte)track.TrackSequence, ref mcn, tracks); + + // Set tracks and go back + if(indexesChanged) + { + (_outputPlugin as IWritableOpticalImage).SetTracks(tracks.ToList()); + i--; + } } else { diff --git a/Aaru.Core/Devices/Dumping/CompactDisc/LeadOuts.cs b/Aaru.Core/Devices/Dumping/CompactDisc/LeadOuts.cs index 43cb0b933..58dd225ac 100644 --- a/Aaru.Core/Devices/Dumping/CompactDisc/LeadOuts.cs +++ b/Aaru.Core/Devices/Dumping/CompactDisc/LeadOuts.cs @@ -32,8 +32,11 @@ using System; using System.Collections.Generic; +using System.Linq; using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Extents; +using Aaru.CommonTypes.Interfaces; +using Aaru.CommonTypes.Structs; using Aaru.Core.Logging; using Aaru.Devices; using Schemas; @@ -72,7 +75,7 @@ namespace Aaru.Core.Devices.Dumping bool read6, bool read10, bool read12, bool read16, bool readcd, MmcSubchannel supportedSubchannel, uint subSize, ref double totalDuration, SubchannelLog subLog, MmcSubchannel desiredSubchannel, Dictionary isrcs, - ref string mcn) + ref string mcn, Track[] tracks) { byte[] cmdBuf = null; // Data buffer const uint sectorSize = 2352; // Full sector size @@ -155,8 +158,18 @@ namespace Aaru.Core.Devices.Dumping _outputPlugin.WriteSectorsLong(data, i, _maximumReadable); - WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, i, _maximumReadable, - subLog, isrcs, 0xAA, ref mcn); + bool indexesChanged = WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, i, + _maximumReadable, subLog, isrcs, 0xAA, ref mcn, + tracks); + + // Set tracks and go back + if(indexesChanged) + { + (_outputPlugin as IWritableOpticalImage).SetTracks(tracks.ToList()); + i--; + + continue; + } } else _outputPlugin.WriteSectors(cmdBuf, i, _maximumReadable); @@ -226,7 +239,7 @@ namespace Aaru.Core.Devices.Dumping bool read6, bool read10, bool read12, bool read16, bool readcd, MmcSubchannel supportedSubchannel, uint subSize, ref double totalDuration, SubchannelLog subLog, MmcSubchannel desiredSubchannel, Dictionary isrcs, - ref string mcn) + ref string mcn, Track[] tracks) { byte[] cmdBuf = null; // Data buffer const uint sectorSize = 2352; // Full sector size @@ -309,8 +322,18 @@ namespace Aaru.Core.Devices.Dumping _outputPlugin.WriteSectorsLong(data, i, _maximumReadable); - WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, i, _maximumReadable, - subLog, isrcs, 0xAA, ref mcn); + bool indexesChanged = WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, i, + _maximumReadable, subLog, isrcs, 0xAA, ref mcn, + tracks); + + // Set tracks and go back + if(indexesChanged) + { + (_outputPlugin as IWritableOpticalImage).SetTracks(tracks.ToList()); + i--; + + continue; + } } else _outputPlugin.WriteSectors(cmdBuf, i, _maximumReadable); diff --git a/Aaru.Core/Devices/Dumping/CompactDisc/Subchannel.cs b/Aaru.Core/Devices/Dumping/CompactDisc/Subchannel.cs index b537ea8e7..cb7fef6b1 100644 --- a/Aaru.Core/Devices/Dumping/CompactDisc/Subchannel.cs +++ b/Aaru.Core/Devices/Dumping/CompactDisc/Subchannel.cs @@ -34,6 +34,7 @@ using System; using System.Collections.Generic; using Aaru.Checksums; using Aaru.CommonTypes.Enums; +using Aaru.CommonTypes.Structs; using Aaru.Core.Logging; using Aaru.Decoders.CD; using Aaru.Devices; @@ -66,9 +67,10 @@ namespace Aaru.Core.Devices.Dumping dev.Timeout, out _); } - void WriteSubchannelToImage(MmcSubchannel supportedSubchannel, MmcSubchannel desiredSubchannel, byte[] sub, + // Return true if indexes have changed + bool WriteSubchannelToImage(MmcSubchannel supportedSubchannel, MmcSubchannel desiredSubchannel, byte[] sub, ulong sectorAddress, uint length, SubchannelLog subLog, - Dictionary isrcs, byte currentTrack, ref string mcn) + Dictionary isrcs, byte currentTrack, ref string mcn, Track[] tracks) { if(supportedSubchannel == MmcSubchannel.Q16) sub = Subchannel.ConvertQToRaw(sub); @@ -86,6 +88,9 @@ namespace Aaru.Core.Devices.Dumping byte[] q = new byte[12]; Array.Copy(deSub, subPos + 12, q, 0, 12); + CRC16CCITTContext.Data(q, 10, out byte[] crc); + bool crcOk = crc[0] == q[10] && crc[1] == q[11]; + // ISRC if((q[0] & 0x3) == 3) { @@ -95,6 +100,9 @@ namespace Aaru.Core.Devices.Dumping isrc == "000000000000") continue; + if(!crcOk) + continue; + if(!isrcs.ContainsKey(currentTrack)) { _dumpLog?.WriteLine($"Found new ISRC {isrc} for track {currentTrack}."); @@ -102,14 +110,6 @@ namespace Aaru.Core.Devices.Dumping } else if(isrcs[currentTrack] != isrc) { - CRC16CCITTContext.Data(q, 10, out byte[] crc); - - if(crc[0] != q[10] || - crc[1] != q[11]) - { - continue; - } - _dumpLog?. WriteLine($"ISRC for track {currentTrack} changed from {isrcs[currentTrack]} to {isrc}."); @@ -127,6 +127,9 @@ namespace Aaru.Core.Devices.Dumping newMcn == "0000000000000") continue; + if(!crcOk) + continue; + if(mcn is null) { _dumpLog?.WriteLine($"Found new MCN {newMcn}."); @@ -134,22 +137,56 @@ namespace Aaru.Core.Devices.Dumping } else if(mcn != newMcn) { - CRC16CCITTContext.Data(q, 10, out byte[] crc); - - if(crc[0] != q[10] || - crc[1] != q[11]) - { - continue; - } - _dumpLog?.WriteLine($"MCN changed from {mcn} to {newMcn}."); - UpdateStatus?.Invoke($"MCN changed from {mcn} to {newMcn}."); } mcn = newMcn; } + else if((q[0] & 0x3) == 1) + { + // TODO: Indexes + + // Pregap + if(q[2] != 0) + continue; + + if(!crcOk) + continue; + + byte trackNo = (byte)(((q[1] / 16) * 10) + (q[1] & 0x0F)); + + for(int i = 0; i < tracks.Length; i++) + { + if(tracks[i].TrackSequence != trackNo || + trackNo == 1) + { + continue; + } + + byte pmin = (byte)(((q[3] / 16) * 10) + (q[3] & 0x0F)); + byte psec = (byte)(((q[4] / 16) * 10) + (q[4] & 0x0F)); + byte pframe = (byte)(((q[5] / 16) * 10) + (q[5] & 0x0F)); + int qPos = (pmin * 60 * 75) + (psec * 75) + pframe; + + if(tracks[i].TrackPregap >= (ulong)(qPos + 1)) + continue; + + tracks[i].TrackPregap = (ulong)(qPos + 1); + tracks[i].TrackStartSector -= tracks[i].TrackPregap; + + if(i > 0) + tracks[i - 1].TrackEndSector = tracks[i].TrackStartSector - 1; + + _dumpLog?.WriteLine($"Pregap for track {trackNo} set to {tracks[i].TrackPregap} sectors."); + UpdateStatus?.Invoke($"Pregap for track {trackNo} set to {tracks[i].TrackPregap} sectors."); + + return true; + } + } } + + return false; } } } \ No newline at end of file diff --git a/Aaru.Core/Devices/Dumping/CompactDisc/Trim.cs b/Aaru.Core/Devices/Dumping/CompactDisc/Trim.cs index b73fe3042..3afd25c7c 100644 --- a/Aaru.Core/Devices/Dumping/CompactDisc/Trim.cs +++ b/Aaru.Core/Devices/Dumping/CompactDisc/Trim.cs @@ -33,11 +33,10 @@ using System; using System.Collections.Generic; using System.Linq; -using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Extents; +using Aaru.CommonTypes.Interfaces; using Aaru.CommonTypes.Structs; using Aaru.Core.Logging; -using Aaru.Decoders.CD; using Aaru.Devices; using Schemas; @@ -101,8 +100,10 @@ namespace Aaru.Core.Devices.Dumping ulong[] tmpArray = _resume.BadBlocks.ToArray(); InitProgress?.Invoke(); - foreach(ulong badSector in tmpArray) + for(int b = 0; b < tmpArray.Length; b++) { + ulong badSector = tmpArray[b]; + if(_aborted) { currentTry.Extents = ExtentsConverter.ToMetadata(extents); @@ -187,35 +188,33 @@ namespace Aaru.Core.Devices.Dumping Array.Copy(cmdBuf, sectorSize, sub, 0, subSize); _outputPlugin.WriteSectorLong(data, badSector); - WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, badSector, 1, subLog, isrcs, - (byte)track.TrackSequence, ref mcn); + bool indexesChanged = WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, badSector, + 1, subLog, isrcs, (byte)track.TrackSequence, ref mcn, + tracks); - if(desiredSubchannel != MmcSubchannel.None) - { - if(supportedSubchannel == MmcSubchannel.Q16) - sub = Subchannel.ConvertQToRaw(sub); + // Set tracks and go back + if(!indexesChanged) + continue; - _outputPlugin.WriteSectorTag(sub, badSector, SectorTagType.CdSectorSubchannel); - } + (_outputPlugin as IWritableOpticalImage).SetTracks(tracks.ToList()); + b--; - subLog?.WriteEntry(sub, supportedSubchannel == MmcSubchannel.Raw, (long)badSector, 1); + continue; } + + if(supportsLongSectors) + _outputPlugin.WriteSectorLong(cmdBuf, badSector); else { - if(supportsLongSectors) - _outputPlugin.WriteSectorLong(cmdBuf, badSector); - else + if(cmdBuf.Length % sectorSize == 0) { - if(cmdBuf.Length % sectorSize == 0) - { - byte[] data = new byte[2048]; - Array.Copy(cmdBuf, 16, data, 0, 2048); + byte[] data = new byte[2048]; + Array.Copy(cmdBuf, 16, data, 0, 2048); - _outputPlugin.WriteSector(data, badSector); - } - else - _outputPlugin.WriteSectorLong(cmdBuf, badSector); + _outputPlugin.WriteSector(data, badSector); } + else + _outputPlugin.WriteSectorLong(cmdBuf, badSector); } }