Add support for PD650 media.

This commit is contained in:
2019-05-16 23:29:54 +01:00
parent 3d7d50dc25
commit 8fefbb4d00
13 changed files with 290 additions and 153 deletions

View File

@@ -1542,7 +1542,12 @@ namespace DiscImageChef.CommonTypes
{
switch(mediumType)
{
case 0x00: return MediaType.CD;
case 0x00:
return blockSize == 512
? blocks == 1281856
? MediaType.PD650_WORM
: MediaType.PD650
: MediaType.CD;
case 0x01:
case 0x05: return MediaType.CDROM;
case 0x02:

View File

@@ -74,6 +74,9 @@ namespace DiscImageChef.Core.Devices.Dumping
case 0x0001:
dskType = MediaType.GENERIC_HDD;
goto default;
case 0x0002:
dskType = MediaType.PD650;
goto default;
case 0x0005:
dskType = MediaType.CDMO;
break;
@@ -175,6 +178,8 @@ namespace DiscImageChef.Core.Devices.Dumping
dumpLog.WriteLine("Device reports disc has {0} blocks", blocks);
Dictionary<MediaTagType, byte[]> mediaTags = new Dictionary<MediaTagType, byte[]>();
if(dskType == MediaType.PD650 && blocks == 1281856) dskType = MediaType.PD650_WORM;
#region Nintendo
switch(dskType)
{

View File

@@ -73,18 +73,18 @@ namespace DiscImageChef.Core.Devices.Dumping
fxSense = Sense.DecodeFixed(senseBuf, out string strSense);
InitProgress?.Invoke();
if(fxSense.HasValue && fxSense.Value.SenseKey != SenseKeys.NoSense)
if(fxSense.HasValue && fxSense?.SenseKey != SenseKeys.NoSense)
{
dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", fxSense.Value.SenseKey,
fxSense.Value.ASC, fxSense.Value.ASCQ);
dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", fxSense?.SenseKey,
fxSense?.ASC, fxSense?.ASCQ);
StoppingErrorMessage?.Invoke("Drive has status error, please correct. Sense follows..." +
Environment.NewLine + strSense);
return;
}
// Not in BOM/P
if(fxSense.HasValue && fxSense.Value.ASC == 0x00 && fxSense.Value.ASCQ != 0x00 &&
fxSense.Value.ASCQ != 0x04 && fxSense.Value.SenseKey != SenseKeys.IllegalRequest)
if(fxSense.HasValue && fxSense?.ASC == 0x00 && fxSense?.ASCQ != 0x00 && fxSense?.ASCQ != 0x04 &&
fxSense?.SenseKey != SenseKeys.IllegalRequest)
{
dumpLog.WriteLine("Rewinding, please wait...");
PulseProgress?.Invoke("Rewinding, please wait...");
@@ -99,21 +99,21 @@ namespace DiscImageChef.Core.Devices.Dumping
dev.RequestSense(out senseBuf, dev.Timeout, out duration);
fxSense = Sense.DecodeFixed(senseBuf, out strSense);
}
while(fxSense.HasValue && fxSense.Value.ASC == 0x00 &&
(fxSense.Value.ASCQ == 0x1A || fxSense.Value.ASCQ != 0x04 || fxSense.Value.ASCQ != 0x00));
while(fxSense.HasValue && fxSense?.ASC == 0x00 &&
(fxSense?.ASCQ == 0x1A || fxSense?.ASCQ != 0x04 || fxSense?.ASCQ != 0x00));
dev.RequestSense(out senseBuf, dev.Timeout, out duration);
fxSense = Sense.DecodeFixed(senseBuf, out strSense);
// And yet, did not rewind!
if(fxSense.HasValue &&
(fxSense.Value.ASC == 0x00 && fxSense.Value.ASCQ != 0x04 && fxSense.Value.ASCQ != 0x00 || fxSense.Value.ASC != 0x00))
if(fxSense.HasValue && (fxSense?.ASC == 0x00 && fxSense?.ASCQ != 0x04 && fxSense?.ASCQ != 0x00 ||
fxSense?.ASC != 0x00))
{
StoppingErrorMessage?.Invoke("Drive could not rewind, please correct. Sense follows..." +
Environment.NewLine + strSense);
dumpLog.WriteLine("Drive could not rewind, please correct. Sense follows...");
dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", fxSense.Value.SenseKey,
fxSense.Value.ASC, fxSense.Value.ASCQ);
dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", fxSense?.SenseKey,
fxSense?.ASC, fxSense?.ASCQ);
return;
}
}
@@ -128,15 +128,14 @@ namespace DiscImageChef.Core.Devices.Dumping
// Anyway, <=SCSI-1 tapes do not support partitions
fxSense = Sense.DecodeFixed(senseBuf, out strSense);
if(fxSense.HasValue && (fxSense.Value.ASC == 0x20 && fxSense.Value.ASCQ != 0x00 ||
fxSense.Value.ASC != 0x20 &&
fxSense.Value.SenseKey != SenseKeys.IllegalRequest))
if(fxSense.HasValue && (fxSense?.ASC == 0x20 && fxSense?.ASCQ != 0x00 ||
fxSense?.ASC != 0x20 && fxSense?.SenseKey != SenseKeys.IllegalRequest))
{
StoppingErrorMessage?.Invoke("Could not get position. Sense follows..." + Environment.NewLine +
strSense);
dumpLog.WriteLine("Could not get position. Sense follows...");
dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", fxSense.Value.SenseKey,
fxSense.Value.ASC, fxSense.Value.ASCQ);
dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", fxSense?.SenseKey,
fxSense?.ASC, fxSense?.ASCQ);
return;
}
}
@@ -155,8 +154,8 @@ namespace DiscImageChef.Core.Devices.Dumping
Environment.NewLine +
strSense);
dumpLog.WriteLine("Drive could not rewind, please correct. Sense follows...");
dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h",
fxSense.Value.SenseKey, fxSense.Value.ASC, fxSense.Value.ASCQ);
dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", fxSense?.SenseKey,
fxSense?.ASC, fxSense?.ASCQ);
return;
}
@@ -169,19 +168,18 @@ namespace DiscImageChef.Core.Devices.Dumping
dev.RequestSense(out senseBuf, dev.Timeout, out duration);
fxSense = Sense.DecodeFixed(senseBuf, out strSense);
}
while(fxSense.HasValue && fxSense.Value.ASC == 0x00 &&
(fxSense.Value.ASCQ == 0x1A || fxSense.Value.ASCQ == 0x19));
while(fxSense.HasValue && fxSense?.ASC == 0x00 && (fxSense?.ASCQ == 0x1A || fxSense?.ASCQ == 0x19));
// And yet, did not rewind!
if(fxSense.HasValue && (fxSense.Value.ASC == 0x00 && fxSense.Value.ASCQ != 0x04 && fxSense.Value.ASCQ != 0x00 ||
fxSense.Value.ASC != 0x00))
if(fxSense.HasValue && (fxSense?.ASC == 0x00 && fxSense?.ASCQ != 0x04 && fxSense?.ASCQ != 0x00 ||
fxSense?.ASC != 0x00))
{
StoppingErrorMessage?.Invoke("Drive could not rewind, please correct. Sense follows..." +
Environment.NewLine +
strSense);
dumpLog.WriteLine("Drive could not rewind, please correct. Sense follows...");
dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h",
fxSense.Value.SenseKey, fxSense.Value.ASC, fxSense.Value.ASCQ);
dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", fxSense?.SenseKey,
fxSense?.ASC, fxSense?.ASCQ);
return;
}
@@ -194,8 +192,8 @@ namespace DiscImageChef.Core.Devices.Dumping
Environment.NewLine +
strSense);
dumpLog.WriteLine("Drive could not rewind, please correct. Sense follows...");
dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h",
fxSense.Value.SenseKey, fxSense.Value.ASC, fxSense.Value.ASCQ);
dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", fxSense?.SenseKey,
fxSense?.ASC, fxSense?.ASCQ);
return;
}
@@ -285,20 +283,20 @@ namespace DiscImageChef.Core.Devices.Dumping
{
fxSense = Sense.DecodeFixed(senseBuf, out strSense);
if(fxSense.HasValue)
if(fxSense.Value.SenseKey == SenseKeys.IllegalRequest)
if(fxSense?.SenseKey == SenseKeys.IllegalRequest)
{
sense = dev.Space(out senseBuf, SscSpaceCodes.LogicalBlock, -1, dev.Timeout, out duration);
if(sense)
{
fxSense = Sense.DecodeFixed(senseBuf, out strSense);
if(!fxSense.HasValue || !fxSense.Value.EOM)
if(!fxSense.HasValue || !fxSense?.EOM == true)
{
StoppingErrorMessage?.Invoke("Drive could not return back. Sense follows..." +
Environment.NewLine +
strSense);
dumpLog.WriteLine("Drive could not return back. Sense follows...");
dumpLog.WriteLine("Device not ready. Sense {0} ASC {1:X2}h ASCQ {2:X2}h",
fxSense.Value.SenseKey, fxSense.Value.ASC, fxSense.Value.ASCQ);
fxSense?.SenseKey, fxSense?.ASC, fxSense?.ASCQ);
return;
}
}
@@ -313,13 +311,13 @@ namespace DiscImageChef.Core.Devices.Dumping
StoppingErrorMessage?.Invoke("Drive could not read. Sense follows..." +
Environment.NewLine + strSense);
dumpLog.WriteLine("Drive could not read. Sense follows...");
dumpLog.WriteLine("Device not ready. Sense {0} ASC {1:X2}h ASCQ {2:X2}h",
fxSense.Value.SenseKey, fxSense.Value.ASC, fxSense.Value.ASCQ);
dumpLog.WriteLine("Device not ready. Sense {0} ASC {1:X2}h ASCQ {2:X2}h", fxSense?.SenseKey,
fxSense?.ASC, fxSense?.ASCQ);
return;
}
}
else if(fxSense.Value.ASC == 0x00 && fxSense.Value.ASCQ == 0x00 && fxSense.Value.ILI &&
fxSense.Value.InformationValid)
else if(fxSense?.ASC == 0x00 && fxSense?.ASCQ == 0x00 && fxSense?.ILI == true &&
fxSense?.InformationValid == true)
{
blockSize = (uint)((int)blockSize -
BitConverter.ToInt32(BitConverter.GetBytes(fxSense.Value.Information), 0));
@@ -340,7 +338,7 @@ namespace DiscImageChef.Core.Devices.Dumping
strSense);
dumpLog.WriteLine("Drive could not go back one block. Sense follows...");
dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h",
fxSense.Value.SenseKey, fxSense.Value.ASC, fxSense.Value.ASCQ);
fxSense?.SenseKey, fxSense?.ASC, fxSense?.ASCQ);
return;
}
@@ -351,8 +349,8 @@ namespace DiscImageChef.Core.Devices.Dumping
StoppingErrorMessage?.Invoke("Drive could not read. Sense follows..." + Environment.NewLine +
strSense);
dumpLog.WriteLine("Drive could not read. Sense follows...");
dumpLog.WriteLine("Device not ready. Sense {0} ASC {1:X2}h ASCQ {2:X2}h",
fxSense.Value.SenseKey, fxSense.Value.ASC, fxSense.Value.ASCQ);
dumpLog.WriteLine("Device not ready. Sense {0} ASC {1:X2}h ASCQ {2:X2}h", fxSense?.SenseKey,
fxSense?.ASC, fxSense?.ASCQ);
return;
}
else
@@ -367,13 +365,13 @@ namespace DiscImageChef.Core.Devices.Dumping
if(sense)
{
fxSense = Sense.DecodeFixed(senseBuf, out strSense);
if(!fxSense.HasValue || !fxSense.Value.EOM)
if(!fxSense.HasValue || !fxSense?.EOM == true)
{
StoppingErrorMessage?.Invoke("Drive could not return back. Sense follows..." + Environment.NewLine +
strSense);
dumpLog.WriteLine("Drive could not return back. Sense follows...");
dumpLog.WriteLine("Device not ready. Sense {0} ASC {1:X2}h ASCQ {2:X2}h", fxSense.Value.SenseKey,
fxSense.Value.ASC, fxSense.Value.ASCQ);
dumpLog.WriteLine("Device not ready. Sense {0} ASC {1:X2}h ASCQ {2:X2}h", fxSense?.SenseKey,
fxSense?.ASC, fxSense?.ASCQ);
return;
}
}
@@ -596,18 +594,17 @@ namespace DiscImageChef.Core.Devices.Dumping
dev.RequestSense(out senseBuf, dev.Timeout, out duration);
fxSense = Sense.DecodeFixed(senseBuf, out strSense);
}
while(fxSense.HasValue && fxSense.Value.ASC == 0x00 &&
(fxSense.Value.ASCQ == 0x1A || fxSense.Value.ASCQ == 0x19));
while(fxSense.HasValue && fxSense?.ASC == 0x00 && (fxSense?.ASCQ == 0x1A || fxSense?.ASCQ == 0x19));
// And yet, did not rewind!
if(fxSense.HasValue &&
(fxSense.Value.ASC == 0x00 && fxSense.Value.ASCQ != 0x00 && fxSense.Value.ASCQ != 0x04 || fxSense.Value.ASC != 0x00))
if(fxSense.HasValue && (fxSense?.ASC == 0x00 && fxSense?.ASCQ != 0x00 && fxSense?.ASCQ != 0x04 ||
fxSense?.ASC != 0x00))
{
StoppingErrorMessage?.Invoke("Drive could not rewind, please correct. Sense follows..." +
Environment.NewLine + strSense);
dumpLog.WriteLine("Drive could not rewind, please correct. Sense follows...");
dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", fxSense.Value.SenseKey,
fxSense.Value.ASC, fxSense.Value.ASCQ);
dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", fxSense?.SenseKey,
fxSense?.ASC, fxSense?.ASCQ);
return;
}
}
@@ -721,11 +718,12 @@ namespace DiscImageChef.Core.Devices.Dumping
out duration);
totalDuration += duration;
if(sense)
if(sense && senseBuf?.Length != 0 && !ArrayHelpers.ArrayIsNullOrEmpty(senseBuf))
{
fxSense = Sense.DecodeFixed(senseBuf, out strSense);
if(fxSense.Value.ASC == 0x00 && fxSense.Value.ASCQ == 0x00 && fxSense.Value.ILI &&
fxSense.Value.InformationValid)
if(fxSense?.ASC == 0x00 && fxSense?.ASCQ == 0x00 && fxSense?.ILI == true &&
fxSense?.InformationValid == true)
{
blockSize = (uint)((int)blockSize -
BitConverter.ToInt32(BitConverter.GetBytes(fxSense.Value.Information), 0));
@@ -747,14 +745,14 @@ namespace DiscImageChef.Core.Devices.Dumping
outputPlugin.Close();
dumpLog.WriteLine("Drive could not go back one block. Sense follows...");
dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h",
fxSense.Value.SenseKey, fxSense.Value.ASC, fxSense.Value.ASCQ);
fxSense?.SenseKey, fxSense?.ASC, fxSense?.ASCQ);
return;
}
continue;
}
switch(fxSense.Value.SenseKey)
switch(fxSense?.SenseKey)
{
case SenseKeys.BlankCheck when currentBlock == 0:
StoppingErrorMessage?.Invoke("Cannot dump a blank tape...");
@@ -762,9 +760,9 @@ namespace DiscImageChef.Core.Devices.Dumping
dumpLog.WriteLine("Cannot dump a blank tape...");
return;
// For sure this is an end-of-tape/partition
case SenseKeys.BlankCheck when fxSense.Value.ASC == 0x00 &&
(fxSense.Value.ASCQ == 0x02 || fxSense.Value.ASCQ == 0x05 ||
fxSense.Value.EOM):
case SenseKeys.BlankCheck when fxSense?.ASC == 0x00 &&
(fxSense?.ASCQ == 0x02 || fxSense?.ASCQ == 0x05 ||
fxSense?.EOM == true):
// TODO: Detect end of partition
endOfMedia = true;
UpdateStatus?.Invoke("Found end-of-tape/partition...");
@@ -777,9 +775,9 @@ namespace DiscImageChef.Core.Devices.Dumping
continue;
}
if((fxSense.Value.SenseKey == SenseKeys.NoSense ||
fxSense.Value.SenseKey == SenseKeys.RecoveredError) &&
(fxSense.Value.ASCQ == 0x02 || fxSense.Value.ASCQ == 0x05 || fxSense.Value.EOM))
if((fxSense?.SenseKey == SenseKeys.NoSense ||
fxSense?.SenseKey == SenseKeys.RecoveredError) &&
(fxSense?.ASCQ == 0x02 || fxSense?.ASCQ == 0x05 || fxSense?.EOM == true))
{
// TODO: Detect end of partition
endOfMedia = true;
@@ -788,9 +786,8 @@ namespace DiscImageChef.Core.Devices.Dumping
continue;
}
if((fxSense.Value.SenseKey == SenseKeys.NoSense ||
fxSense.Value.SenseKey == SenseKeys.RecoveredError) &&
(fxSense.Value.ASCQ == 0x01 || fxSense.Value.Filemark))
if((fxSense?.SenseKey == SenseKeys.NoSense || fxSense?.SenseKey == SenseKeys.RecoveredError) &&
(fxSense?.ASCQ == 0x01 || fxSense?.Filemark == true))
{
currentTapeFile.LastBlock = currentBlock - 1;
(outputPlugin as IWritableTapeImage).AddFile(currentTapeFile);
@@ -806,12 +803,21 @@ namespace DiscImageChef.Core.Devices.Dumping
continue;
}
fxSense = Sense.DecodeFixed(senseBuf, out strSense);
if(fxSense is null)
{
StoppingErrorMessage
?.Invoke($"Drive could not read block ${currentBlock}. Sense follows...\n{fxSense.Value.SenseKey} {strSense}");
?.Invoke($"Drive could not read block ${currentBlock}. Sense cannot be decoded, look at log for dump...");
dumpLog.WriteLine($"Drive could not read block ${currentBlock}. Sense bytes follow...");
dumpLog.WriteLine(PrintHex.ByteArrayToHexArrayString(senseBuf, 32));
}
else
{
StoppingErrorMessage
?.Invoke($"Drive could not read block ${currentBlock}. Sense follows...\n{fxSense?.SenseKey} {strSense}");
dumpLog.WriteLine($"Drive could not read block ${currentBlock}. Sense follows...");
dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", fxSense.Value.SenseKey,
fxSense.Value.ASC, fxSense.Value.ASCQ);
dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", fxSense?.SenseKey,
fxSense?.ASC, fxSense?.ASCQ);
}
// TODO: Reset device after X errors
if(stopOnError) return; // TODO: Return more cleanly

View File

@@ -564,7 +564,8 @@ namespace DiscImageChef.Core.Devices.Report
}
if(mediaType.StartsWith("DVD-", StringComparison.Ordinal) ||
mediaType.StartsWith("HD DVD-", StringComparison.Ordinal))
mediaType.StartsWith("HD DVD-", StringComparison.Ordinal) ||
mediaType.StartsWith("PD-", StringComparison.Ordinal))
{
DicConsole.WriteLine("Querying DVD PFI...");
mediaTest.CanReadPFI = !dev.ReadDiscStructure(out buffer, out senseBuffer,
@@ -639,6 +640,7 @@ namespace DiscImageChef.Core.Devices.Report
case "DVD-RAM (1st gen, marked 2.6Gb or 5.2Gb)":
case "DVD-RAM (2nd gen, marked 4.7Gb or 9.4Gb)":
case "HD DVD-RAM":
case "PD-650":
mediaTest.CanReadDDS = !dev.ReadDiscStructure(out buffer, out senseBuffer,
MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.DvdramDds, 0, dev.Timeout,
@@ -755,25 +757,50 @@ namespace DiscImageChef.Core.Devices.Report
if(debug) mediaTest.BluPacData = buffer;
}
if(mediaType.StartsWith("PD-", StringComparison.Ordinal))
{
DicConsole.WriteLine("Trying SCSI READ (6)...");
mediaTest.SupportsRead6 = !dev.Read6(out buffer, out senseBuffer, 16, 512, dev.Timeout, out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsRead6);
if(debug) mediaTest.Read6Data = buffer;
DicConsole.WriteLine("Trying SCSI READ (10)...");
mediaTest.SupportsRead10 = !dev.Read10(out buffer, out senseBuffer, 0, false, true, false, false, 16,
512, 0, 1, dev.Timeout, out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsRead10);
if(debug) mediaTest.Read10Data = buffer;
DicConsole.WriteLine("Trying SCSI READ (12)...");
mediaTest.SupportsRead12 = !dev.Read12(out buffer, out senseBuffer, 0, false, true, false, false, 16,
512, 0, 1, false, dev.Timeout, out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsRead12);
if(debug) mediaTest.Read12Data = buffer;
DicConsole.WriteLine("Trying SCSI READ (16)...");
mediaTest.SupportsRead16 = !dev.Read16(out buffer, out senseBuffer, 0, false, true, false, 16, 512, 0,
1, false, dev.Timeout, out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsRead16);
if(debug) mediaTest.Read16Data = buffer;
}
else
{
DicConsole.WriteLine("Trying SCSI READ (6)...");
mediaTest.SupportsRead6 = !dev.Read6(out buffer, out senseBuffer, 16, 2048, dev.Timeout, out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsRead6);
if(debug) mediaTest.Read6Data = buffer;
DicConsole.WriteLine("Trying SCSI READ (10)...");
mediaTest.SupportsRead10 = !dev.Read10(out buffer, out senseBuffer, 0, false, true, false, false, 16, 2048,
0, 1, dev.Timeout, out _);
mediaTest.SupportsRead10 = !dev.Read10(out buffer, out senseBuffer, 0, false, true, false, false, 16,
2048, 0, 1, dev.Timeout, out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsRead10);
if(debug) mediaTest.Read10Data = buffer;
DicConsole.WriteLine("Trying SCSI READ (12)...");
mediaTest.SupportsRead12 = !dev.Read12(out buffer, out senseBuffer, 0, false, true, false, false, 16, 2048,
0, 1, false, dev.Timeout, out _);
mediaTest.SupportsRead12 = !dev.Read12(out buffer, out senseBuffer, 0, false, true, false, false, 16,
2048, 0, 1, false, dev.Timeout, out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsRead12);
if(debug) mediaTest.Read12Data = buffer;
DicConsole.WriteLine("Trying SCSI READ (16)...");
mediaTest.SupportsRead16 = !dev.Read16(out buffer, out senseBuffer, 0, false, true, false, 16, 2048, 0, 1,
false, dev.Timeout, out _);
mediaTest.SupportsRead16 = !dev.Read16(out buffer, out senseBuffer, 0, false, true, false, 16, 2048, 0,
1, false, dev.Timeout, out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsRead16);
if(debug) mediaTest.Read16Data = buffer;
}
if(mediaType.StartsWith("CD-", StringComparison.Ordinal) ||
mediaType.StartsWith("DDCD-", StringComparison.Ordinal) || mediaType == "Audio CD")

View File

@@ -43,19 +43,19 @@ namespace DiscImageChef.Core.Logging
/// </summary>
class IbgLog
{
CultureInfo ibgCulture;
readonly CultureInfo ibgCulture;
DateTime ibgDatePoint;
double ibgDivider;
readonly double ibgDivider;
ulong ibgIntSector;
double ibgIntSpeed;
double ibgMaxSpeed;
string ibgMediaType;
readonly string ibgMediaType;
int ibgSampleRate;
StringBuilder ibgSb;
readonly StringBuilder ibgSb;
int ibgSnaps;
bool ibgStartSet;
double ibgStartSpeed;
string logFile;
readonly string logFile;
/// <summary>
/// Initializes the IMGBurn log
@@ -82,6 +82,10 @@ namespace DiscImageChef.Core.Logging
ibgMediaType = "HDD";
ibgDivider = 1353;
break;
case 0x0002:
ibgMediaType = "PD-650";
ibgDivider = 150;
break;
case 0x0005:
ibgMediaType = "CD-MO";
ibgDivider = 150;

View File

@@ -307,6 +307,9 @@ namespace DiscImageChef.Core.Media.Info
case 0x0001:
MediaType = MediaType.GENERIC_HDD;
break;
case 0x0002:
MediaType = MediaType.PD650;
break;
case 0x0005:
MediaType = MediaType.CDMO;
break;
@@ -394,6 +397,8 @@ namespace DiscImageChef.Core.Media.Info
}
}
if(MediaType == MediaType.PD650 && Blocks == 1281856) MediaType = MediaType.PD650_WORM;
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.RecognizedFormatLayers, 0, dev.Timeout, out _);
if(sense)
@@ -1546,6 +1551,7 @@ namespace DiscImageChef.Core.Media.Info
break;
}
// TODO: Check for CD-i Ready
case MediaType.CDI: break;
case MediaType.DVDROM:
@@ -1758,6 +1764,7 @@ namespace DiscImageChef.Core.Media.Info
break;
}
// TODO: Check for CD-i Ready
case MediaType.CDI: break;
case MediaType.DVDROM:

View File

@@ -128,13 +128,13 @@ namespace DiscImageChef.DiscImages
MediaType.DVDROM, MediaType.DVDRW, MediaType.DVDRWDL, MediaType.EVD, MediaType.FDDVD,
MediaType.DTSCD, MediaType.FVD, MediaType.HDDVDR, MediaType.HDDVDRAM, MediaType.HDDVDRDL,
MediaType.HDDVDROM, MediaType.HDDVDRW, MediaType.HDDVDRWDL, MediaType.HDVMD, MediaType.HVD,
MediaType.JaguarCD, MediaType.MEGACD, MediaType.PD650, MediaType.PD650_WORM, MediaType.PS1CD,
MediaType.PS2CD, MediaType.PS2DVD, MediaType.PS3BD, MediaType.PS3DVD, MediaType.PS4BD,
MediaType.SuperCDROM2, MediaType.SVCD, MediaType.SVOD, MediaType.SATURNCD, MediaType.ThreeDO,
MediaType.UDO, MediaType.UDO2, MediaType.UDO2_WORM, MediaType.UMD, MediaType.VCD, MediaType.VCDHD,
MediaType.NeoGeoCD, MediaType.PCFX, MediaType.CDTV, MediaType.CD32, MediaType.Nuon,
MediaType.Playdia, MediaType.Pippin, MediaType.FMTOWNS, MediaType.MilCD, MediaType.VideoNow,
MediaType.VideoNowColor, MediaType.VideoNowXp
MediaType.JaguarCD, MediaType.MEGACD, MediaType.PS1CD, MediaType.PS2CD, MediaType.PS2DVD,
MediaType.PS3BD, MediaType.PS3DVD, MediaType.PS4BD, MediaType.SuperCDROM2, MediaType.SVCD,
MediaType.SVOD, MediaType.SATURNCD, MediaType.ThreeDO, MediaType.UDO, MediaType.UDO2,
MediaType.UDO2_WORM, MediaType.UMD, MediaType.VCD, MediaType.VCDHD, MediaType.NeoGeoCD,
MediaType.PCFX, MediaType.CDTV, MediaType.CD32, MediaType.Nuon, MediaType.Playdia, MediaType.Pippin,
MediaType.FMTOWNS, MediaType.MilCD, MediaType.VideoNow, MediaType.VideoNowColor,
MediaType.VideoNowXp
};
public IEnumerable<(string name, Type type, string description, object @default)> SupportedOptions =>
new (string name, Type type, string description, object @default)[] { };

View File

@@ -200,8 +200,6 @@ namespace DiscImageChef.DiscImages
case MediaType.DTSCD:
case MediaType.JaguarCD:
case MediaType.MEGACD:
case MediaType.PD650:
case MediaType.PD650_WORM:
case MediaType.PS1CD:
case MediaType.PS2CD:
case MediaType.SuperCDROM2:

View File

@@ -137,6 +137,8 @@ namespace DiscImageChef.DiscImages
case 533403648: return MediaType.ECMA_183;
case 596787200: return MediaType.ECMA_184_512;
case 654540800: return MediaType.ECMA_184;
case 656310272 when imageInfo.SectorSize == 512: return MediaType.PD650;
case 664829952 when imageInfo.SectorSize == 512: return MediaType.PD650;
case 1070617600: return MediaType.Jaz;
#region Commodore

View File

@@ -122,6 +122,8 @@ namespace DiscImageChef.DiscImages
? mode2
? "MODE2/2352"
: "MODE1/2352"
: imageInfo.MediaType == MediaType.PD650 || imageInfo.MediaType == MediaType.PD650_WORM
? "DATA/512"
: "MODE1/2048",
Size = imageInfo.Sectors * imageInfo.SectorSize
};

View File

@@ -376,8 +376,7 @@ namespace DiscImageChef.DiscImages
// Check for Xbox
if(mediaTags.TryGetValue(MediaTagType.DVD_DMI, out byte[] dmi))
if(DMI.IsXbox(dmi) || DMI.IsXbox360(dmi))
if(DMI.IsXbox(dmi))
imageInfo.MediaType = MediaType.XGD;
if(DMI.IsXbox(dmi)) imageInfo.MediaType = MediaType.XGD;
else if(DMI.IsXbox360(dmi))
{
imageInfo.MediaType = MediaType.XGD2;
@@ -900,6 +899,8 @@ namespace DiscImageChef.DiscImages
case MediaType.XGD:
case MediaType.XGD2:
case MediaType.XGD3:
case MediaType.PD650:
case MediaType.PD650_WORM:
imageInfo.XmlMediaType = XmlMediaType.OpticalDisc;
break;
default:
@@ -1151,6 +1152,7 @@ namespace DiscImageChef.DiscImages
sectorSkip = 2340;
break;
}
case SectorTagType.CdSectorHeader:
{
sectorOffset = 12;
@@ -1158,12 +1160,14 @@ namespace DiscImageChef.DiscImages
sectorSkip = 2336;
break;
}
case SectorTagType.CdSectorSubchannel:
{
sectorOffset = 2352;
sectorSize = 96;
break;
}
case SectorTagType.CdSectorSubHeader:
throw new ArgumentException("Unsupported tag requested for this track", nameof(tag));
case SectorTagType.CdSectorEcc:
@@ -1173,6 +1177,7 @@ namespace DiscImageChef.DiscImages
sectorSkip = 0;
break;
}
case SectorTagType.CdSectorEccP:
{
sectorOffset = 2076;
@@ -1180,6 +1185,7 @@ namespace DiscImageChef.DiscImages
sectorSkip = 104;
break;
}
case SectorTagType.CdSectorEccQ:
{
sectorOffset = 2248;
@@ -1187,6 +1193,7 @@ namespace DiscImageChef.DiscImages
sectorSkip = 0;
break;
}
case SectorTagType.CdSectorEdc:
{
sectorOffset = 2064;
@@ -1194,6 +1201,7 @@ namespace DiscImageChef.DiscImages
sectorSkip = 284;
break;
}
default: throw new ArgumentException("Unsupported tag requested", nameof(tag));
}

View File

@@ -36,6 +36,8 @@ namespace DiscImageChef.Filesystems.FAT
{
public partial class FAT
{
const int UMSDOS_MAXNAME = 220;
/// <summary>
/// BIOS Parameter Block as used by Atari ST GEMDOS on FAT12 volumes.
/// </summary>
@@ -911,6 +913,70 @@ namespace DiscImageChef.Filesystems.FAT
public readonly ushort zero;
}
/// <summary>
/// This structure is 256 bytes large, depending on the name, only part of it is written to disk
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct UmsdosDirectoryEntry
{
/// <summary>if == 0, then this entry is not used</summary>
public readonly byte name_len;
/// <summary>
/// UMSDOS_xxxx
/// </summary>
public readonly UmsdosFlags flags;
/// <summary>
/// How many hard links point to this entry
/// </summary>
public readonly ushort nlink;
/// <summary>
/// Owner user id
/// </summary>
public readonly int uid;
/// <summary>
/// Group id
/// </summary>
public readonly int gid;
/// <summary>
/// Access time
/// </summary>
public readonly int atime;
/// <summary>
/// Last modification time
/// </summary>
public readonly int mtime;
/// <summary>
/// Creation time
/// </summary>
public readonly int ctime;
/// <summary>
/// major and minor number of a device
/// </summary>
public readonly uint rdev;
/* */
/// <summary>
/// Standard UNIX permissions bits + type of
/// </summary>
public readonly ushort mode;
/// <summary>unused bytes for future extensions</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public readonly byte[] spare;
/// <summary>
/// Not '\0' terminated but '\0' padded, so it will allow for adding news fields in this record by reducing the
/// size of name[]
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = UMSDOS_MAXNAME)]
public readonly byte[] name;
}
enum UmsdosFlags : byte
{
/// <summary>Never show this entry in directory search</summary>
UMSDOS_HIDDEN = 1,
/// <summary>It is a (pseudo) hard link</summary>
UMSDOS_HLINK = 2
}
class CompleteDirectoryEntry
{
public DirectoryEntry Dirent;
@@ -918,11 +984,16 @@ namespace DiscImageChef.Filesystems.FAT
public HumanDirectoryEntry HumanDirent;
public string HumanName;
public string Lfn;
public UmsdosDirectoryEntry LinuxDirent;
public string LinuxName;
public string Longname;
public string Shortname;
public override string ToString()
{
// This ensures UMSDOS takes preference when present
if(!string.IsNullOrEmpty(LinuxName)) return LinuxName;
// This ensures LFN takes preference when eCS is in use
if(!string.IsNullOrEmpty(Lfn)) return Lfn;

View File

@@ -560,6 +560,8 @@ namespace DiscImageChef.Commands
}
}
if(dev.Model.StartsWith("PD-", StringComparison.Ordinal)) mediaTypes.Add("PD-650");
List<TestedMedia> mediaTests = new List<TestedMedia>();
foreach(string mediaType in mediaTypes)
{