Add support for CD drives (or devices pretending to) that don't report toc or leadout at all. Fixes #138.

This commit is contained in:
2018-06-19 22:48:51 +01:00
parent aec8ae2620
commit 4fb48e98c3

View File

@@ -117,6 +117,8 @@ namespace DiscImageChef.Core.Devices.Dumping
return; return;
} }
dskType = MediaType.CD;
// We discarded all discs that falsify a TOC before requesting a real TOC // We discarded all discs that falsify a TOC before requesting a real TOC
// No TOC, no CD (or an empty one) // No TOC, no CD (or an empty one)
dumpLog.WriteLine("Reading full TOC"); dumpLog.WriteLine("Reading full TOC");
@@ -300,6 +302,27 @@ namespace DiscImageChef.Core.Devices.Dumping
DicConsole.ErrorWriteLine("Cannot read from disc, not continuing..."); DicConsole.ErrorWriteLine("Cannot read from disc, not continuing...");
return; return;
} }
if(read6)
{
dumpLog.WriteLine("Drive supports READ(6)...");
DicConsole.WriteLine("Drive supports READ(6)...");
}
if(read10)
{
dumpLog.WriteLine("Drive supports READ(10)...");
DicConsole.WriteLine("Drive supports READ(10)...");
}
if(read12)
{
dumpLog.WriteLine("Drive supports READ(12)...");
DicConsole.WriteLine("Drive supports READ(12)...");
}
if(read16)
{
dumpLog.WriteLine("Drive supports READ(16)...");
DicConsole.WriteLine("Drive supports READ(16)...");
}
} }
dumpLog.WriteLine("Drive can only read without subchannel..."); dumpLog.WriteLine("Drive can only read without subchannel...");
@@ -503,6 +526,28 @@ namespace DiscImageChef.Core.Devices.Dumping
} }
if(lastSector == 0) if(lastSector == 0)
{
sense = dev.ReadCapacity16(out readBuffer, out senseBuf, dev.Timeout, out _);
if(!sense)
{
byte[] temp = new byte[8];
Array.Copy(cmdBuf, 0, temp, 0, 8);
Array.Reverse(temp);
lastSector = (long)BitConverter.ToUInt64(temp, 0);
blockSize = (uint)((cmdBuf[5] << 24) + (cmdBuf[5] << 16) + (cmdBuf[6] << 8) + cmdBuf[7]);
}
else
{
sense = dev.ReadCapacity(out cmdBuf, out senseBuf, dev.Timeout, out _);
if(!sense)
{
lastSector = (long)((cmdBuf[0] << 24) + (cmdBuf[1] << 16) + (cmdBuf[2] << 8) + cmdBuf[3]);
blockSize = (uint)((cmdBuf[5] << 24) + (cmdBuf[5] << 16) + (cmdBuf[6] << 8) + cmdBuf[7]);
}
}
if(lastSector <= 0)
{ {
if(!force) if(!force)
{ {
@@ -512,10 +557,12 @@ namespace DiscImageChef.Core.Devices.Dumping
return; return;
} }
DicConsole.WriteLine("WARNING: Could not find Lead-Out start, will try to read up to 360000 sectors, probably will fail before..."); DicConsole
.WriteLine("WARNING: Could not find Lead-Out start, will try to read up to 360000 sectors, probably will fail before...");
dumpLog.WriteLine("WARNING: Could not find Lead-Out start, will try to read up to 360000 sectors, probably will fail before..."); dumpLog.WriteLine("WARNING: Could not find Lead-Out start, will try to read up to 360000 sectors, probably will fail before...");
lastSector = 360000; lastSector = 360000;
} }
}
Track[] tracks = trackList.ToArray(); Track[] tracks = trackList.ToArray();
for(int t = 1; t < tracks.Length; t++) tracks[t - 1].TrackEndSector = tracks[t].TrackStartSector - 1; for(int t = 1; t < tracks.Length; t++) tracks[t - 1].TrackEndSector = tracks[t].TrackStartSector - 1;
@@ -543,14 +590,14 @@ namespace DiscImageChef.Core.Devices.Dumping
// Check mode for tracks // Check mode for tracks
for(int t = 0; t < tracks.Length; t++) for(int t = 0; t < tracks.Length; t++)
{ {
if(tracks[t].TrackType == TrackType.Audio) continue;
if(!readcd) if(!readcd)
{ {
tracks[t].TrackType = TrackType.CdMode1; tracks[t].TrackType = TrackType.CdMode1;
continue; continue;
} }
if(tracks[t].TrackType == TrackType.Audio) continue;
dumpLog.WriteLine("Checking mode for track {0}...", tracks[t].TrackSequence); dumpLog.WriteLine("Checking mode for track {0}...", tracks[t].TrackSequence);
DicConsole.WriteLine("Checking mode for track {0}...", tracks[t].TrackSequence); DicConsole.WriteLine("Checking mode for track {0}...", tracks[t].TrackSequence);
@@ -737,7 +784,7 @@ namespace DiscImageChef.Core.Devices.Dumping
MhddLog mhddLog = new MhddLog(outputPrefix + ".mhddlog.bin", dev, blocks, blockSize, blocksToRead); MhddLog mhddLog = new MhddLog(outputPrefix + ".mhddlog.bin", dev, blocks, blockSize, blocksToRead);
IbgLog ibgLog = new IbgLog(outputPrefix + ".ibg", 0x0008); IbgLog ibgLog = new IbgLog(outputPrefix + ".ibg", 0x0008);
bool ret = outputPlugin.Create(outputPath, dskType, formatOptions, blocks, SECTOR_SIZE); bool ret = outputPlugin.Create(outputPath, dskType, formatOptions, blocks, blockSize);
// Cannot create image // Cannot create image
if(!ret) if(!ret)
@@ -878,24 +925,20 @@ namespace DiscImageChef.Core.Devices.Dumping
{ {
sense = dev.Read16(out readBuffer, out senseBuf, 0, false, true, false, i, blockSize, 0, blocksToRead, false, sense = dev.Read16(out readBuffer, out senseBuf, 0, false, true, false, i, blockSize, 0, blocksToRead, false,
dev.Timeout, out cmdDuration); dev.Timeout, out cmdDuration);
if(dev.Error || sense) blocksToRead /= 2;
} }
else if(read12) else if(read12)
{ {
sense = dev.Read12(out readBuffer, out senseBuf, 0, false, true, false, false, (uint)i, blockSize, 0, blocksToRead, false, sense = dev.Read12(out readBuffer, out senseBuf, 0, false, true, false, false, (uint)i, blockSize, 0, blocksToRead, false,
dev.Timeout, out cmdDuration); dev.Timeout, out cmdDuration);
if(dev.Error || sense) blocksToRead /= 2;
} }
else if(read10) else if(read10)
{ {
sense = dev.Read10(out readBuffer, out senseBuf, 0, false, true, false, false, (uint)i, blockSize, 0, (ushort)blocksToRead, sense = dev.Read10(out readBuffer, out senseBuf, 0, false, true, false, false, (uint)i, blockSize, 0, (ushort)blocksToRead,
dev.Timeout, out cmdDuration); dev.Timeout, out cmdDuration);
if(dev.Error || sense) blocksToRead /= 2;
} }
else if(read6) else if(read6)
{ {
sense = dev.Read6(out readBuffer, out senseBuf, (uint)i, blockSize, (byte)blocksToRead, dev.Timeout, out cmdDuration); sense = dev.Read6(out readBuffer, out senseBuf, (uint)i, blockSize, (byte)blocksToRead, dev.Timeout, out cmdDuration);
if(dev.Error || sense) blocksToRead /= 2;
} }
if(!sense && !dev.Error) if(!sense && !dev.Error)
@@ -920,7 +963,7 @@ namespace DiscImageChef.Core.Devices.Dumping
outputPlugin.WriteSectorsLong(data, i, blocksToRead); outputPlugin.WriteSectorsLong(data, i, blocksToRead);
outputPlugin.WriteSectorsTag(sub, i, blocksToRead, SectorTagType.CdSectorSubchannel); outputPlugin.WriteSectorsTag(sub, i, blocksToRead, SectorTagType.CdSectorSubchannel);
} }
else outputPlugin.WriteSectorsLong(readBuffer, i, blocksToRead); else outputPlugin.WriteSectors(readBuffer, i, blocksToRead);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
} }
@@ -939,7 +982,7 @@ namespace DiscImageChef.Core.Devices.Dumping
outputPlugin.WriteSectorsTag(new byte[subSize * skip], i, skip, outputPlugin.WriteSectorsTag(new byte[subSize * skip], i, skip,
SectorTagType.CdSectorSubchannel); SectorTagType.CdSectorSubchannel);
} }
else outputPlugin.WriteSectorsLong(new byte[blockSize * skip], i, skip); else outputPlugin.WriteSectors(new byte[blockSize * skip], i, skip);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
@@ -1004,24 +1047,20 @@ namespace DiscImageChef.Core.Devices.Dumping
{ {
sense = dev.Read16(out readBuffer, out senseBuf, 0, false, true, false, badSector, blockSize, 0, blocksToRead, false, sense = dev.Read16(out readBuffer, out senseBuf, 0, false, true, false, badSector, blockSize, 0, blocksToRead, false,
dev.Timeout, out double cmdDuration); dev.Timeout, out double cmdDuration);
if(dev.Error || sense) blocksToRead /= 2;
} }
else if(read12) else if(read12)
{ {
sense = dev.Read12(out readBuffer, out senseBuf, 0, false, true, false, false, (uint)badSector, blockSize, 0, blocksToRead, false, sense = dev.Read12(out readBuffer, out senseBuf, 0, false, true, false, false, (uint)badSector, blockSize, 0, blocksToRead, false,
dev.Timeout, out double cmdDuration); dev.Timeout, out double cmdDuration);
if(dev.Error || sense) blocksToRead /= 2;
} }
else if(read10) else if(read10)
{ {
sense = dev.Read10(out readBuffer, out senseBuf, 0, false, true, false, false, (uint)badSector, blockSize, 0, (ushort)blocksToRead, sense = dev.Read10(out readBuffer, out senseBuf, 0, false, true, false, false, (uint)badSector, blockSize, 0, (ushort)blocksToRead,
dev.Timeout, out double cmdDuration); dev.Timeout, out double cmdDuration);
if(dev.Error || sense) blocksToRead /= 2;
} }
else if(read6) else if(read6)
{ {
sense = dev.Read6(out readBuffer, out senseBuf, (uint)badSector, blockSize, (byte)blocksToRead, dev.Timeout, out double cmdDuration); sense = dev.Read6(out readBuffer, out senseBuf, (uint)badSector, blockSize, (byte)blocksToRead, dev.Timeout, out double cmdDuration);
if(dev.Error || sense) blocksToRead /= 2;
} }
if(sense || dev.Error) continue; if(sense || dev.Error) continue;
@@ -1041,7 +1080,7 @@ namespace DiscImageChef.Core.Devices.Dumping
outputPlugin.WriteSectorLong(data, badSector); outputPlugin.WriteSectorLong(data, badSector);
outputPlugin.WriteSectorTag(sub, badSector, SectorTagType.CdSectorSubchannel); outputPlugin.WriteSectorTag(sub, badSector, SectorTagType.CdSectorSubchannel);
} }
else outputPlugin.WriteSectorLong(readBuffer, badSector); else outputPlugin.WriteSector(readBuffer, badSector);
} }
DicConsole.WriteLine(); DicConsole.WriteLine();