From c104a51d5af44b9d14660b4d71c3b481caf9b7e6 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Fri, 23 Oct 2020 04:01:55 +0100 Subject: [PATCH] Add support for dumping CDs to images that only support cooked user data. Fixes #378 --- Aaru.Core/Devices/Dumping/CompactDisc/Data.cs | 76 ++++++++++++------- Aaru.Core/Devices/Dumping/CompactDisc/Dump.cs | 2 +- .../Devices/Dumping/CompactDisc/Error.cs | 58 +++++++------- Aaru.Core/Devices/Dumping/CompactDisc/Trim.cs | 31 +++----- 4 files changed, 89 insertions(+), 78 deletions(-) diff --git a/Aaru.Core/Devices/Dumping/CompactDisc/Data.cs b/Aaru.Core/Devices/Dumping/CompactDisc/Data.cs index 025c72b5b..e96a77e8c 100644 --- a/Aaru.Core/Devices/Dumping/CompactDisc/Data.cs +++ b/Aaru.Core/Devices/Dumping/CompactDisc/Data.cs @@ -32,6 +32,7 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Extents; @@ -395,7 +396,22 @@ namespace Aaru.Core.Devices.Dumping Array.Copy(cmdBuf, sectorSize, sub, 0, subSize); - _outputPlugin.WriteSectorsLong(data, i + r, 1); + if(supportsLongSectors) + _outputPlugin.WriteSectorsLong(data, i + r, 1); + else + { + var cooked = new MemoryStream(); + byte[] sector = new byte[sectorSize]; + + for(int b = 0; b < blocksToRead; b++) + { + Array.Copy(cmdBuf, (int)(0 + (b * blockSize)), sector, 0, sectorSize); + byte[] cookedSector = Sector.GetUserData(sector); + cooked.Write(cookedSector, 0, cookedSector.Length); + } + + _outputPlugin.WriteSectors(cooked.ToArray(), i, blocksToRead); + } bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, i + r, 1, subLog, isrcs, (byte)track.TrackSequence, @@ -415,23 +431,20 @@ namespace Aaru.Core.Devices.Dumping else { if(supportsLongSectors) - { _outputPlugin.WriteSectorsLong(cmdBuf, i + r, 1); - } else { - if(cmdBuf.Length % sectorSize == 0) - { - byte[] data = new byte[2048]; + var cooked = new MemoryStream(); + byte[] sector = new byte[sectorSize]; - Array.Copy(cmdBuf, 16, data, 2048, 2048); - - _outputPlugin.WriteSectors(data, i + r, 1); - } - else + for(int b = 0; b < blocksToRead; b++) { - _outputPlugin.WriteSectorsLong(cmdBuf, i + r, 1); + Array.Copy(cmdBuf, (int)(b * sectorSize), sector, 0, sectorSize); + byte[] cookedSector = Sector.GetUserData(sector); + cooked.Write(cookedSector, 0, cookedSector.Length); } + + _outputPlugin.WriteSectors(cooked.ToArray(), i, blocksToRead); } } @@ -455,9 +468,7 @@ namespace Aaru.Core.Devices.Dumping else { if(supportsLongSectors) - { _outputPlugin.WriteSectorsLong(new byte[blockSize], i + r, 1); - } else { if(cmdBuf.Length % sectorSize == 0) @@ -529,7 +540,22 @@ namespace Aaru.Core.Devices.Dumping Array.Copy(cmdBuf, (int)(sectorSize + (b * blockSize)), sub, subSize * b, subSize); } - _outputPlugin.WriteSectorsLong(data, i, blocksToRead); + if(supportsLongSectors) + _outputPlugin.WriteSectorsLong(data, i, blocksToRead); + else + { + var cooked = new MemoryStream(); + byte[] sector = new byte[sectorSize]; + + for(int b = 0; b < blocksToRead; b++) + { + Array.Copy(cmdBuf, (int)(0 + (b * blockSize)), sector, 0, sectorSize); + byte[] cookedSector = Sector.GetUserData(sector); + cooked.Write(cookedSector, 0, cookedSector.Length); + } + + _outputPlugin.WriteSectors(cooked.ToArray(), i, blocksToRead); + } bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, sub, i, blocksToRead, subLog, isrcs, (byte)track.TrackSequence, @@ -548,24 +574,20 @@ namespace Aaru.Core.Devices.Dumping else { if(supportsLongSectors) - { _outputPlugin.WriteSectorsLong(cmdBuf, i, blocksToRead); - } else { - if(cmdBuf.Length % sectorSize == 0) - { - byte[] data = new byte[2048 * blocksToRead]; + var cooked = new MemoryStream(); + byte[] sector = new byte[sectorSize]; - for(int b = 0; b < blocksToRead; b++) - Array.Copy(cmdBuf, (int)(16 + (b * blockSize)), data, 2048 * b, 2048); - - _outputPlugin.WriteSectors(data, i, blocksToRead); - } - else + for(int b = 0; b < blocksToRead; b++) { - _outputPlugin.WriteSectorsLong(cmdBuf, i, blocksToRead); + Array.Copy(cmdBuf, (int)(b * sectorSize), sector, 0, sectorSize); + byte[] cookedSector = Sector.GetUserData(sector); + cooked.Write(cookedSector, 0, cookedSector.Length); } + + _outputPlugin.WriteSectors(cooked.ToArray(), i, blocksToRead); } } diff --git a/Aaru.Core/Devices/Dumping/CompactDisc/Dump.cs b/Aaru.Core/Devices/Dumping/CompactDisc/Dump.cs index 9c9ade761..a54d7206e 100644 --- a/Aaru.Core/Devices/Dumping/CompactDisc/Dump.cs +++ b/Aaru.Core/Devices/Dumping/CompactDisc/Dump.cs @@ -1168,7 +1168,7 @@ namespace Aaru.Core.Devices.Dumping RetryCdUserData(audioExtents, blockSize, currentTry, extents, offsetBytes, readcd, sectorsForOffset, subSize, supportedSubchannel, ref totalDuration, subLog, desiredSubchannel, tracks, isrcs, - ref mcn, subchannelExtents, smallestPregapLbaPerTrack); + ref mcn, subchannelExtents, smallestPregapLbaPerTrack, supportsLongSectors); foreach(Tuple leadoutExtent in leadOutExtents.ToArray()) { diff --git a/Aaru.Core/Devices/Dumping/CompactDisc/Error.cs b/Aaru.Core/Devices/Dumping/CompactDisc/Error.cs index a7a406fc8..f027159f0 100644 --- a/Aaru.Core/Devices/Dumping/CompactDisc/Error.cs +++ b/Aaru.Core/Devices/Dumping/CompactDisc/Error.cs @@ -39,6 +39,7 @@ using Aaru.CommonTypes.Structs; using Aaru.CommonTypes.Structs.Devices.SCSI; using Aaru.Console; using Aaru.Core.Logging; +using Aaru.Decoders.CD; using Aaru.Decoders.SCSI; using Aaru.Devices; using Schemas; @@ -56,7 +57,7 @@ namespace Aaru.Core.Devices.Dumping MmcSubchannel supportedSubchannel, ref double totalDuration, SubchannelLog subLog, MmcSubchannel desiredSubchannel, Track[] tracks, Dictionary isrcs, ref string mcn, HashSet subchannelExtents, - Dictionary smallestPregapLbaPerTrack) + Dictionary smallestPregapLbaPerTrack, bool supportsLongSectors) { bool sense = true; // Sense indicator byte[] cmdBuf = null; // Data buffer @@ -121,8 +122,7 @@ namespace Aaru.Core.Devices.Dumping if(dcMode10?.Pages != null) foreach(Modes.ModePage modePage in dcMode10.Value.Pages.Where(modePage => - modePage.Page == 0x01 && - modePage.Subpage == 0x00)) + modePage.Page == 0x01 && modePage.Subpage == 0x00)) currentModePage = modePage; } } @@ -132,8 +132,7 @@ namespace Aaru.Core.Devices.Dumping if(dcMode6?.Pages != null) foreach(Modes.ModePage modePage in dcMode6.Value.Pages.Where(modePage => - modePage.Page == 0x01 && - modePage.Subpage == 0x00)) + modePage.Page == 0x01 && modePage.Subpage == 0x00)) currentModePage = modePage; } @@ -300,18 +299,16 @@ namespace Aaru.Core.Devices.Dumping byte[] sub = new byte[subSize]; Array.Copy(cmdBuf, 0, data, 0, sectorSize); Array.Copy(cmdBuf, sectorSize, sub, 0, subSize); - _outputPlugin.WriteSectorLong(data, badSector); + + if(supportsLongSectors) + _outputPlugin.WriteSectorLong(data, badSector); + else + _outputPlugin.WriteSector(Sector.GetUserData(data), badSector); bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel, - desiredSubchannel, sub, badSector, 1, - subLog, isrcs, - (byte)track.TrackSequence, ref mcn, - tracks, subchannelExtents, - _fixSubchannelPosition, - _outputPlugin, _fixSubchannel, - _fixSubchannelCrc, _dumpLog, - UpdateStatus, - smallestPregapLbaPerTrack); + desiredSubchannel, sub, badSector, 1, subLog, isrcs, (byte)track.TrackSequence, ref mcn, + tracks, subchannelExtents, _fixSubchannelPosition, _outputPlugin, _fixSubchannel, + _fixSubchannelCrc, _dumpLog, UpdateStatus, smallestPregapLbaPerTrack); // Set tracks and go back if(indexesChanged) @@ -322,7 +319,10 @@ namespace Aaru.Core.Devices.Dumping } else { - _outputPlugin.WriteSectorLong(cmdBuf, badSector); + if(supportsLongSectors) + _outputPlugin.WriteSectorLong(cmdBuf, badSector); + else + _outputPlugin.WriteSector(Sector.GetUserData(cmdBuf), badSector); } } @@ -430,20 +430,17 @@ namespace Aaru.Core.Devices.Dumping byte[] sub = new byte[subSize]; Array.Copy(cmdBuf, 0, data, 0, sectorSize); Array.Copy(cmdBuf, sectorSize, sub, 0, subSize); - _outputPlugin.WriteSectorLong(data, badSector); + + if(supportsLongSectors) + _outputPlugin.WriteSectorLong(data, badSector); + else + _outputPlugin.WriteSector(Sector.GetUserData(data), badSector); bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel, - desiredSubchannel, sub, - badSector, 1, subLog, isrcs, - (byte)track.TrackSequence, - ref mcn, tracks, - subchannelExtents, - _fixSubchannelPosition, - _outputPlugin, - _fixSubchannel, - _fixSubchannelCrc, _dumpLog, - UpdateStatus, - smallestPregapLbaPerTrack); + desiredSubchannel, sub, badSector, 1, subLog, isrcs, (byte)track.TrackSequence, + ref mcn, tracks, subchannelExtents, _fixSubchannelPosition, _outputPlugin, + _fixSubchannel, _fixSubchannelCrc, _dumpLog, UpdateStatus, + smallestPregapLbaPerTrack); // Set tracks and go back if(indexesChanged) @@ -454,7 +451,10 @@ namespace Aaru.Core.Devices.Dumping } else { - _outputPlugin.WriteSectorLong(cmdBuf, badSector); + if(supportsLongSectors) + _outputPlugin.WriteSectorLong(cmdBuf, badSector); + else + _outputPlugin.WriteSector(Sector.GetUserData(cmdBuf), badSector); } } diff --git a/Aaru.Core/Devices/Dumping/CompactDisc/Trim.cs b/Aaru.Core/Devices/Dumping/CompactDisc/Trim.cs index 503053f98..c844d0163 100644 --- a/Aaru.Core/Devices/Dumping/CompactDisc/Trim.cs +++ b/Aaru.Core/Devices/Dumping/CompactDisc/Trim.cs @@ -37,6 +37,7 @@ 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; @@ -192,18 +193,16 @@ namespace Aaru.Core.Devices.Dumping byte[] sub = new byte[subSize]; Array.Copy(cmdBuf, 0, data, 0, sectorSize); Array.Copy(cmdBuf, sectorSize, sub, 0, subSize); - _outputPlugin.WriteSectorLong(data, badSector); + + if(supportsLongSectors) + _outputPlugin.WriteSectorLong(data, badSector); + else + _outputPlugin.WriteSector(Sector.GetUserData(data), badSector); bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel, - desiredSubchannel, sub, badSector, 1, - subLog, isrcs, - (byte)track.TrackSequence, ref mcn, - tracks, subchannelExtents, - _fixSubchannelPosition, - _outputPlugin, _fixSubchannel, - _fixSubchannelCrc, _dumpLog, - UpdateStatus, - smallestPregapLbaPerTrack); + desiredSubchannel, sub, badSector, 1, subLog, isrcs, (byte)track.TrackSequence, ref mcn, + tracks, subchannelExtents, _fixSubchannelPosition, _outputPlugin, _fixSubchannel, + _fixSubchannelCrc, _dumpLog, UpdateStatus, smallestPregapLbaPerTrack); // Set tracks and go back if(!indexesChanged) @@ -218,17 +217,7 @@ namespace Aaru.Core.Devices.Dumping if(supportsLongSectors) _outputPlugin.WriteSectorLong(cmdBuf, badSector); else - { - if(cmdBuf.Length % sectorSize == 0) - { - byte[] data = new byte[2048]; - Array.Copy(cmdBuf, 16, data, 0, 2048); - - _outputPlugin.WriteSector(data, badSector); - } - else - _outputPlugin.WriteSectorLong(cmdBuf, badSector); - } + _outputPlugin.WriteSector(Sector.GetUserData(cmdBuf), badSector); } EndProgress?.Invoke();