Add support for dumping CDs to images that only support cooked user data. Fixes #378

This commit is contained in:
2020-10-23 04:01:55 +01:00
parent c9ade37b6e
commit c104a51d5a
4 changed files with 89 additions and 78 deletions

View File

@@ -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);
}
}

View File

@@ -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<ulong, ulong> leadoutExtent in leadOutExtents.ToArray())
{

View File

@@ -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<byte, string> isrcs,
ref string mcn, HashSet<int> subchannelExtents,
Dictionary<byte, int> smallestPregapLbaPerTrack)
Dictionary<byte, int> 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);
}
}

View File

@@ -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();