REFACTOR: Final cleanup of DiscImageChef.Core.

This commit is contained in:
2017-12-23 17:41:23 +00:00
parent e05de44620
commit 380dbad1a0
48 changed files with 986 additions and 1017 deletions

View File

@@ -62,7 +62,7 @@ namespace DiscImageChef.Core
} }
/// <summary> /// <summary>
/// Benchmarks the speed at which we can do checksums /// Benchmarks the speed at which we can do checksums
/// </summary> /// </summary>
public static class Benchmark public static class Benchmark
{ {
@@ -518,7 +518,8 @@ namespace DiscImageChef.Core
} }
EndProgress(); EndProgress();
double entropy = entTable.Select(l => (double)l / (double)bufferSize).Select(frequency => -(frequency * Math.Log(frequency, 2))).Sum(); double entropy = entTable.Select(l => (double)l / (double)bufferSize)
.Select(frequency => -(frequency * Math.Log(frequency, 2))).Sum();
end = DateTime.Now; end = DateTime.Now;
mem = GC.GetTotalMemory(false); mem = GC.GetTotalMemory(false);

View File

@@ -56,47 +56,44 @@ namespace DiscImageChef.Core
} }
/// <summary> /// <summary>
/// Checksums and hashes data, with different algorithms multithreaded /// Checksums and hashes data, with different algorithms multithreaded
/// </summary> /// </summary>
public class Checksum public class Checksum
{ {
Adler32Context adler32Ctx; Adler32Context adler32Ctx;
Crc16Context crc16Ctx;
Crc32Context crc32Ctx;
Crc64Context crc64Ctx;
Md5Context md5Ctx;
Ripemd160Context ripemd160Ctx;
Sha1Context sha1Ctx;
Sha256Context sha256Ctx;
Sha384Context sha384Ctx;
Sha512Context sha512Ctx;
SpamSumContext ssctx;
Thread adlerThread;
Thread crc16Thread;
Thread crc32Thread;
Thread crc64Thread;
Thread md5Thread;
Thread ripemd160Thread;
Thread sha1Thread;
Thread sha256Thread;
Thread sha384Thread;
Thread sha512Thread;
Thread spamsumThread;
AdlerPacket adlerPkt; AdlerPacket adlerPkt;
Thread adlerThread;
Crc16Context crc16Ctx;
Crc16Packet crc16Pkt; Crc16Packet crc16Pkt;
Thread crc16Thread;
Crc32Context crc32Ctx;
Crc32Packet crc32Pkt; Crc32Packet crc32Pkt;
Thread crc32Thread;
Crc64Context crc64Ctx;
Crc64Packet crc64Pkt; Crc64Packet crc64Pkt;
Md5Packet md5Pkt; Thread crc64Thread;
Ripemd160Packet ripemd160Pkt;
Sha1Packet sha1Pkt;
Sha256Packet sha256Pkt;
Sha384Packet sha384Pkt;
Sha512Packet sha512Pkt;
SpamsumPacket spamsumPkt;
EnableChecksum enabled; EnableChecksum enabled;
Md5Context md5Ctx;
Md5Packet md5Pkt;
Thread md5Thread;
Ripemd160Context ripemd160Ctx;
Ripemd160Packet ripemd160Pkt;
Thread ripemd160Thread;
Sha1Context sha1Ctx;
Sha1Packet sha1Pkt;
Thread sha1Thread;
Sha256Context sha256Ctx;
Sha256Packet sha256Pkt;
Thread sha256Thread;
Sha384Context sha384Ctx;
Sha384Packet sha384Pkt;
Thread sha384Thread;
Sha512Context sha512Ctx;
Sha512Packet sha512Pkt;
Thread sha512Thread;
SpamsumPacket spamsumPkt;
Thread spamsumThread;
SpamSumContext ssctx;
public Checksum(EnableChecksum enabled = EnableChecksum.All) public Checksum(EnableChecksum enabled = EnableChecksum.All)
{ {

View File

@@ -37,7 +37,7 @@ using DiscImageChef.Console;
namespace DiscImageChef.Core namespace DiscImageChef.Core
{ {
/// <summary> /// <summary>
/// Abstracts a datafile with a block based interface /// Abstracts a datafile with a block based interface
/// </summary> /// </summary>
[SuppressMessage("ReSharper", "UnusedMethodReturnValue.Global")] [SuppressMessage("ReSharper", "UnusedMethodReturnValue.Global")]
public class DataFile public class DataFile
@@ -45,7 +45,7 @@ namespace DiscImageChef.Core
FileStream dataFs; FileStream dataFs;
/// <summary> /// <summary>
/// Opens, or create, a new file /// Opens, or create, a new file
/// </summary> /// </summary>
/// <param name="outputFile">File</param> /// <param name="outputFile">File</param>
public DataFile(string outputFile) public DataFile(string outputFile)
@@ -54,7 +54,7 @@ namespace DiscImageChef.Core
} }
/// <summary> /// <summary>
/// Closes the file /// Closes the file
/// </summary> /// </summary>
public void Close() public void Close()
{ {
@@ -62,10 +62,10 @@ namespace DiscImageChef.Core
} }
/// <summary> /// <summary>
/// Reads bytes at current position /// Reads bytes at current position
/// </summary> /// </summary>
/// <param name="array">Array to place read data within</param> /// <param name="array">Array to place read data within</param>
/// <param name="offset">Offset of <see cref="array"/> where data will be read</param> /// <param name="offset">Offset of <see cref="array" /> where data will be read</param>
/// <param name="count">How many bytes to read</param> /// <param name="count">How many bytes to read</param>
/// <returns>How many bytes were read</returns> /// <returns>How many bytes were read</returns>
public int Read(byte[] array, int offset, int count) public int Read(byte[] array, int offset, int count)
@@ -74,7 +74,7 @@ namespace DiscImageChef.Core
} }
/// <summary> /// <summary>
/// Seeks to the specified block /// Seeks to the specified block
/// </summary> /// </summary>
/// <param name="block">Block to seek to</param> /// <param name="block">Block to seek to</param>
/// <param name="blockSize">Block size in bytes</param> /// <param name="blockSize">Block size in bytes</param>
@@ -85,7 +85,7 @@ namespace DiscImageChef.Core
} }
/// <summary> /// <summary>
/// Seeks to specified byte position /// Seeks to specified byte position
/// </summary> /// </summary>
/// <param name="offset">Byte position</param> /// <param name="offset">Byte position</param>
/// <param name="origin">Where to count for position</param> /// <param name="origin">Where to count for position</param>
@@ -96,7 +96,7 @@ namespace DiscImageChef.Core
} }
/// <summary> /// <summary>
/// Seeks to specified byte position /// Seeks to specified byte position
/// </summary> /// </summary>
/// <param name="offset">Byte position</param> /// <param name="offset">Byte position</param>
/// <param name="origin">Where to count for position</param> /// <param name="origin">Where to count for position</param>
@@ -107,7 +107,7 @@ namespace DiscImageChef.Core
} }
/// <summary> /// <summary>
/// Writes data at current position /// Writes data at current position
/// </summary> /// </summary>
/// <param name="data">Data</param> /// <param name="data">Data</param>
public void Write(byte[] data) public void Write(byte[] data)
@@ -116,7 +116,7 @@ namespace DiscImageChef.Core
} }
/// <summary> /// <summary>
/// Writes data at current position /// Writes data at current position
/// </summary> /// </summary>
/// <param name="data">Data</param> /// <param name="data">Data</param>
/// <param name="offset">Offset of data from where to start taking data to write</param> /// <param name="offset">Offset of data from where to start taking data to write</param>
@@ -127,7 +127,7 @@ namespace DiscImageChef.Core
} }
/// <summary> /// <summary>
/// Writes data at specified block /// Writes data at specified block
/// </summary> /// </summary>
/// <param name="data">Data</param> /// <param name="data">Data</param>
/// <param name="block">Block</param> /// <param name="block">Block</param>
@@ -138,7 +138,7 @@ namespace DiscImageChef.Core
} }
/// <summary> /// <summary>
/// Writes data at specified block /// Writes data at specified block
/// </summary> /// </summary>
/// <param name="data">Data</param> /// <param name="data">Data</param>
/// <param name="block">Block</param> /// <param name="block">Block</param>
@@ -152,26 +152,27 @@ namespace DiscImageChef.Core
} }
/// <summary> /// <summary>
/// Current file position /// Current file position
/// </summary> /// </summary>
public long Position => dataFs.Position; public long Position => dataFs.Position;
/// <summary> /// <summary>
/// Writes data to a newly created file /// Writes data to a newly created file
/// </summary> /// </summary>
/// <param name="who">Who asked the file to be written (class, plugin, etc.)</param> /// <param name="who">Who asked the file to be written (class, plugin, etc.)</param>
/// <param name="data">Data to write</param> /// <param name="data">Data to write</param>
/// <param name="outputPrefix">First part of the file name</param> /// <param name="outputPrefix">First part of the file name</param>
/// <param name="outputSuffix">Last part of the file name</param> /// <param name="outputSuffix">Last part of the file name</param>
/// <param name="whatWriting">What is the data about?</param> /// <param name="whatWriting">What is the data about?</param>
public static void WriteTo(string who, string outputPrefix, string outputSuffix, string whatWriting, byte[] data) public static void WriteTo(string who, string outputPrefix, string outputSuffix, string whatWriting,
byte[] data)
{ {
if(!string.IsNullOrEmpty(outputPrefix) && !string.IsNullOrEmpty(outputSuffix)) if(!string.IsNullOrEmpty(outputPrefix) && !string.IsNullOrEmpty(outputSuffix))
WriteTo(who, outputPrefix + outputSuffix, data, whatWriting); WriteTo(who, outputPrefix + outputSuffix, data, whatWriting);
} }
/// <summary> /// <summary>
/// Writes data to a newly created file /// Writes data to a newly created file
/// </summary> /// </summary>
/// <param name="who">Who asked the file to be written (class, plugin, etc.)</param> /// <param name="who">Who asked the file to be written (class, plugin, etc.)</param>
/// <param name="filename">Filename to create</param> /// <param name="filename">Filename to create</param>

View File

@@ -33,68 +33,68 @@
namespace DiscImageChef.Core namespace DiscImageChef.Core
{ {
/// <summary> /// <summary>
/// Initializates a progress indicator (e.g. makes a progress bar visible) /// Initializates a progress indicator (e.g. makes a progress bar visible)
/// </summary> /// </summary>
public delegate void InitProgressHandler(); public delegate void InitProgressHandler();
/// <summary> /// <summary>
/// Updates a progress indicator with text /// Updates a progress indicator with text
/// </summary> /// </summary>
public delegate void UpdateProgressHandler(string text, long current, long maximum); public delegate void UpdateProgressHandler(string text, long current, long maximum);
/// <summary> /// <summary>
/// Pulses a progress indicator with indeterminate boundaries /// Pulses a progress indicator with indeterminate boundaries
/// </summary> /// </summary>
public delegate void PulseProgressHandler(string text); public delegate void PulseProgressHandler(string text);
/// <summary> /// <summary>
/// Uninitializates a progress indicator (e.g. adds a newline to the console) /// Uninitializates a progress indicator (e.g. adds a newline to the console)
/// </summary> /// </summary>
public delegate void EndProgressHandler(); public delegate void EndProgressHandler();
/// <summary> /// <summary>
/// Initializates a secondary progress indicator (e.g. makes a progress bar visible) /// Initializates a secondary progress indicator (e.g. makes a progress bar visible)
/// </summary> /// </summary>
public delegate void InitProgressHandler2(); public delegate void InitProgressHandler2();
/// <summary> /// <summary>
/// Updates a secondary progress indicator with text /// Updates a secondary progress indicator with text
/// </summary> /// </summary>
public delegate void UpdateProgressHandler2(string text, long current, long maximum); public delegate void UpdateProgressHandler2(string text, long current, long maximum);
/// <summary> /// <summary>
/// Pulses a secondary progress indicator with indeterminate boundaries /// Pulses a secondary progress indicator with indeterminate boundaries
/// </summary> /// </summary>
public delegate void PulseProgressHandler2(string text); public delegate void PulseProgressHandler2(string text);
/// <summary> /// <summary>
/// Uninitializates a secondary progress indicator (e.g. adds a newline to the console) /// Uninitializates a secondary progress indicator (e.g. adds a newline to the console)
/// </summary> /// </summary>
public delegate void EndProgressHandler2(); public delegate void EndProgressHandler2();
/// <summary> /// <summary>
/// Initializates two progress indicators (e.g. makes a progress bar visible) /// Initializates two progress indicators (e.g. makes a progress bar visible)
/// </summary> /// </summary>
public delegate void InitTwoProgressHandler(); public delegate void InitTwoProgressHandler();
/// <summary> /// <summary>
/// Updates two progress indicators with text /// Updates two progress indicators with text
/// </summary> /// </summary>
public delegate void UpdateTwoProgressHandler(string text, long current, long maximum, string text2, long current2, public delegate void UpdateTwoProgressHandler(string text, long current, long maximum, string text2, long current2,
long maximum2); long maximum2);
/// <summary> /// <summary>
/// Pulses a progress indicator with indeterminate boundaries /// Pulses a progress indicator with indeterminate boundaries
/// </summary> /// </summary>
public delegate void PulseTwoProgressHandler(string text, string text2); public delegate void PulseTwoProgressHandler(string text, string text2);
/// <summary> /// <summary>
/// Uninitializates a progress indicator (e.g. adds a newline to the console) /// Uninitializates a progress indicator (e.g. adds a newline to the console)
/// </summary> /// </summary>
public delegate void EndTwoProgressHandler(); public delegate void EndTwoProgressHandler();
/// <summary> /// <summary>
/// Updates a status indicator /// Updates a status indicator
/// </summary> /// </summary>
public delegate void UpdateStatusHandler(string text); public delegate void UpdateStatusHandler(string text);
} }

View File

@@ -53,12 +53,12 @@ using Tuple = DiscImageChef.Decoders.PCMCIA.Tuple;
namespace DiscImageChef.Core.Devices.Dumping namespace DiscImageChef.Core.Devices.Dumping
{ {
/// <summary> /// <summary>
/// Implements dumping ATA devices /// Implements dumping ATA devices
/// </summary> /// </summary>
public class Ata public class Ata
{ {
/// <summary> /// <summary>
/// Dumps an ATA device /// Dumps an ATA device
/// </summary> /// </summary>
/// <param name="dev">Device</param> /// <param name="dev">Device</param>
/// <param name="devicePath">Path to the device</param> /// <param name="devicePath">Path to the device</param>
@@ -73,8 +73,8 @@ namespace DiscImageChef.Core.Devices.Dumping
/// <param name="encoding">Encoding to use when analyzing dump</param> /// <param name="encoding">Encoding to use when analyzing dump</param>
/// <exception cref="InvalidOperationException">If the resume file is invalid</exception> /// <exception cref="InvalidOperationException">If the resume file is invalid</exception>
public static void Dump(Device dev, string devicePath, string outputPrefix, ushort retryPasses, bool force, public static void Dump(Device dev, string devicePath, string outputPrefix, ushort retryPasses, bool force,
bool dumpRaw, bool persistent, bool stopOnError, ref Resume resume, bool dumpRaw, bool persistent, bool stopOnError, ref Resume resume, ref DumpLog dumpLog,
ref DumpLog dumpLog, Encoding encoding) Encoding encoding)
{ {
bool aborted; bool aborted;
@@ -99,11 +99,11 @@ namespace DiscImageChef.Core.Devices.Dumping
if(!sense && Identify.Decode(cmdBuf).HasValue) if(!sense && Identify.Decode(cmdBuf).HasValue)
{ {
Identify.IdentifyDevice? ataIdNullable = Identify.Decode(cmdBuf); Identify.IdentifyDevice? ataIdNullable = Identify.Decode(cmdBuf);
if(ataIdNullable != null) { if(ataIdNullable != null)
{
Identify.IdentifyDevice ataId = ataIdNullable.Value; Identify.IdentifyDevice ataId = ataIdNullable.Value;
CICMMetadataType sidecar = CICMMetadataType sidecar = new CICMMetadataType {BlockMedia = new[] {new BlockMediaType()}};
new CICMMetadataType {BlockMedia = new[] {new BlockMediaType()}};
if(dev.IsUsb) if(dev.IsUsb)
{ {
@@ -139,7 +139,8 @@ namespace DiscImageChef.Core.Devices.Dumping
Tuple[] tuples = CIS.GetTuples(dev.Cis); Tuple[] tuples = CIS.GetTuples(dev.Cis);
if(tuples != null) if(tuples != null)
foreach(Tuple tuple in tuples) foreach(Tuple tuple in tuples)
switch(tuple.Code) { switch(tuple.Code)
{
case TupleCodes.CISTPL_MANFID: case TupleCodes.CISTPL_MANFID:
ManufacturerIdentificationTuple manfid = ManufacturerIdentificationTuple manfid =
CIS.DecodeManufacturerIdentificationTuple(tuple); CIS.DecodeManufacturerIdentificationTuple(tuple);
@@ -161,7 +162,8 @@ namespace DiscImageChef.Core.Devices.Dumping
sidecar.BlockMedia[0].PCMCIA.ProductName = vers.Product; sidecar.BlockMedia[0].PCMCIA.ProductName = vers.Product;
sidecar.BlockMedia[0].PCMCIA.Compliance = sidecar.BlockMedia[0].PCMCIA.Compliance =
$"{vers.MajorVersion}.{vers.MinorVersion}"; $"{vers.MajorVersion}.{vers.MinorVersion}";
sidecar.BlockMedia[0].PCMCIA.AdditionalInformation = vers.AdditionalInformation; sidecar.BlockMedia[0].PCMCIA.AdditionalInformation =
vers.AdditionalInformation;
} }
break; break;
} }
@@ -233,8 +235,7 @@ namespace DiscImageChef.Core.Devices.Dumping
dumpLog.WriteLine("Device reports {0} bytes per physical block.", physicalsectorsize); dumpLog.WriteLine("Device reports {0} bytes per physical block.", physicalsectorsize);
bool removable = !dev.IsCompactFlash && bool removable = !dev.IsCompactFlash &&
ataId.GeneralConfiguration.HasFlag(Identify.GeneralConfigurationBit ataId.GeneralConfiguration.HasFlag(Identify.GeneralConfigurationBit.Removable);
.Removable);
DumpHardwareType currentTry = null; DumpHardwareType currentTry = null;
ExtentsULong extents = null; ExtentsULong extents = null;
ResumeSupport.Process(ataReader.IsLba, removable, blocks, dev.Manufacturer, dev.Model, dev.Serial, ResumeSupport.Process(ataReader.IsLba, removable, blocks, dev.Manufacturer, dev.Model, dev.Serial,
@@ -304,8 +305,7 @@ namespace DiscImageChef.Core.Devices.Dumping
DicConsole.WriteLine(); DicConsole.WriteLine();
mhddLog.Close(); mhddLog.Close();
ibgLog.Close(dev, blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024, ibgLog.Close(dev, blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000), blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000), devicePath);
devicePath);
dumpLog.WriteLine("Dump finished in {0} seconds.", (end - start).TotalSeconds); dumpLog.WriteLine("Dump finished in {0} seconds.", (end - start).TotalSeconds);
dumpLog.WriteLine("Average dump speed {0:F3} KiB/sec.", dumpLog.WriteLine("Average dump speed {0:F3} KiB/sec.",
(double)blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000)); (double)blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000));
@@ -388,8 +388,8 @@ namespace DiscImageChef.Core.Devices.Dumping
if(currentSpeed < minSpeed && currentSpeed != 0) minSpeed = currentSpeed; if(currentSpeed < minSpeed && currentSpeed != 0) minSpeed = currentSpeed;
#pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator #pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator
DicConsole.Write("\rReading cylinder {0} head {1} sector {2} ({3:F3} MiB/sec.)", cy, hd, DicConsole.Write("\rReading cylinder {0} head {1} sector {2} ({3:F3} MiB/sec.)", cy,
sc, currentSpeed); hd, sc, currentSpeed);
bool error = ataReader.ReadChs(out cmdBuf, cy, hd, sc, out duration); bool error = ataReader.ReadChs(out cmdBuf, cy, hd, sc, out duration);
@@ -401,7 +401,8 @@ namespace DiscImageChef.Core.Devices.Dumping
ibgLog.Write(currentBlock, currentSpeed * 1024); ibgLog.Write(currentBlock, currentSpeed * 1024);
dumpFile.Write(cmdBuf); dumpFile.Write(cmdBuf);
extents.Add(currentBlock); extents.Add(currentBlock);
dumpLog.WriteLine("Error reading cylinder {0} head {1} sector {2}.", cy, hd, sc); dumpLog.WriteLine("Error reading cylinder {0} head {1} sector {2}.", cy, hd,
sc);
} }
else else
{ {
@@ -424,8 +425,7 @@ namespace DiscImageChef.Core.Devices.Dumping
DicConsole.WriteLine(); DicConsole.WriteLine();
mhddLog.Close(); mhddLog.Close();
ibgLog.Close(dev, blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024, ibgLog.Close(dev, blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000), blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000), devicePath);
devicePath);
dumpLog.WriteLine("Dump finished in {0} seconds.", (end - start).TotalSeconds); dumpLog.WriteLine("Dump finished in {0} seconds.", (end - start).TotalSeconds);
dumpLog.WriteLine("Average dump speed {0:F3} KiB/sec.", dumpLog.WriteLine("Average dump speed {0:F3} KiB/sec.",
(double)blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000)); (double)blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000));
@@ -572,10 +572,12 @@ namespace DiscImageChef.Core.Devices.Dumping
sidecar.BlockMedia[0].Checksums = dataChk.End().ToArray(); sidecar.BlockMedia[0].Checksums = dataChk.End().ToArray();
string xmlDskTyp, xmlDskSubTyp; string xmlDskTyp, xmlDskSubTyp;
if(dev.IsCompactFlash) if(dev.IsCompactFlash)
MediaType.MediaTypeToString(CommonTypes.MediaType.CompactFlash, out xmlDskTyp, out xmlDskSubTyp); MediaType.MediaTypeToString(CommonTypes.MediaType.CompactFlash, out xmlDskTyp,
out xmlDskSubTyp);
else if(dev.IsPcmcia) else if(dev.IsPcmcia)
MediaType.MediaTypeToString(CommonTypes.MediaType.PCCardTypeI, out xmlDskTyp, out xmlDskSubTyp); MediaType.MediaTypeToString(CommonTypes.MediaType.PCCardTypeI, out xmlDskTyp, out xmlDskSubTyp);
else MediaType.MediaTypeToString(CommonTypes.MediaType.GENERIC_HDD, out xmlDskTyp, out xmlDskSubTyp); else
MediaType.MediaTypeToString(CommonTypes.MediaType.GENERIC_HDD, out xmlDskTyp, out xmlDskSubTyp);
sidecar.BlockMedia[0].DiskType = xmlDskTyp; sidecar.BlockMedia[0].DiskType = xmlDskTyp;
sidecar.BlockMedia[0].DiskSubType = xmlDskSubTyp; sidecar.BlockMedia[0].DiskSubType = xmlDskSubTyp;
// TODO: Implement device firmware revision // TODO: Implement device firmware revision
@@ -605,8 +607,9 @@ namespace DiscImageChef.Core.Devices.Dumping
DicConsole.WriteLine(); DicConsole.WriteLine();
DicConsole.WriteLine("Took a total of {0:F3} seconds ({1:F3} processing commands, {2:F3} checksumming).", DicConsole
(end - start).TotalSeconds, totalDuration / 1000, totalChkDuration / 1000); .WriteLine("Took a total of {0:F3} seconds ({1:F3} processing commands, {2:F3} checksumming).",
(end - start).TotalSeconds, totalDuration / 1000, totalChkDuration / 1000);
DicConsole.WriteLine("Avegare speed: {0:F3} MiB/sec.", DicConsole.WriteLine("Avegare speed: {0:F3} MiB/sec.",
(double)blockSize * (double)(blocks + 1) / 1048576 / (totalDuration / 1000)); (double)blockSize * (double)(blocks + 1) / 1048576 / (totalDuration / 1000));
DicConsole.WriteLine("Fastest speed burst: {0:F3} MiB/sec.", maxSpeed); DicConsole.WriteLine("Fastest speed burst: {0:F3} MiB/sec.", maxSpeed);
@@ -621,8 +624,7 @@ namespace DiscImageChef.Core.Devices.Dumping
FileStream xmlFs = new FileStream(outputPrefix + ".cicm.xml", FileMode.Create); FileStream xmlFs = new FileStream(outputPrefix + ".cicm.xml", FileMode.Create);
XmlSerializer xmlSer = XmlSerializer xmlSer = new XmlSerializer(typeof(CICMMetadataType));
new XmlSerializer(typeof(CICMMetadataType));
xmlSer.Serialize(xmlFs, sidecar); xmlSer.Serialize(xmlFs, sidecar);
xmlFs.Close(); xmlFs.Close();
} }

View File

@@ -44,120 +44,16 @@ namespace DiscImageChef.Core.Devices.Dumping
// TODO: For >4.0, this class must disappear // TODO: For >4.0, this class must disappear
class Alcohol120 class Alcohol120
{ {
#region Internal Structures
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct AlcoholHeader
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] public string signature;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public byte[] version;
public AlcoholMediumType type;
public ushort sessions;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public ushort[] unknown1;
public ushort bcaLength;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public uint[] unknown2;
public uint bcaOffset;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] public uint[] unknown3;
public uint structuresOffset;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public uint[] unknown4;
public uint sessionOffset;
public uint dpmOffset;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct AlcoholSession
{
public int sessionStart;
public int sessionEnd;
public ushort sessionSequence;
public byte allBlocks;
public byte nonTrackBlocks;
public ushort firstTrack;
public ushort lastTrack;
public uint unknown;
public uint trackOffset;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct AlcoholTrack
{
public AlcoholTrackMode mode;
public AlcoholSubchannelMode subMode;
public byte adrCtl;
public byte tno;
public byte point;
public byte min;
public byte sec;
public byte frame;
public byte zero;
public byte pmin;
public byte psec;
public byte pframe;
public uint extraOffset;
public ushort sectorSize;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 18)] public byte[] unknown;
public uint startLba;
public ulong startOffset;
public uint files;
public uint footerOffset;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)] public byte[] unknown2;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct AlcoholTrackExtra
{
public uint pregap;
public uint sectors;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct AlcoholFooter
{
public uint filenameOffset;
public uint widechar;
public uint unknown1;
public uint unknown2;
}
#endregion Internal Structures
#region Internal enumerations
enum AlcoholMediumType : ushort
{
Cd = 0x00,
Cdr = 0x01,
Cdrw = 0x02,
Dvd = 0x10,
Dvdr = 0x12
}
enum AlcoholTrackMode : byte
{
NoData = 0x00,
Dvd = 0x02,
Audio = 0xA9,
Mode1 = 0xAA,
Mode2 = 0xAB,
Mode2F1 = 0xAC,
Mode2F2 = 0xAD
}
enum AlcoholSubchannelMode : byte
{
None = 0x00,
Interleaved = 0x08
}
#endregion Internal enumerations
string outputPrefix;
string extension;
byte[] bca; byte[] bca;
byte[] pfi;
byte[] dmi; byte[] dmi;
string extension;
AlcoholFooter footer;
AlcoholHeader header; AlcoholHeader header;
List<AlcoholTrack> tracks; string outputPrefix;
byte[] pfi;
List<AlcoholSession> sessions; List<AlcoholSession> sessions;
Dictionary<byte, uint> trackLengths; Dictionary<byte, uint> trackLengths;
AlcoholFooter footer; List<AlcoholTrack> tracks;
internal Alcohol120(string outputPrefix) internal Alcohol120(string outputPrefix)
{ {
@@ -382,7 +278,7 @@ namespace DiscImageChef.Core.Devices.Dumping
firstTrack = (ushort)cdSession.StartTrack, firstTrack = (ushort)cdSession.StartTrack,
lastTrack = (ushort)cdSession.EndTrack, lastTrack = (ushort)cdSession.EndTrack,
sessionSequence = cdSession.SessionSequence sessionSequence = cdSession.SessionSequence
})) { sessions.Add(session); } })) sessions.Add(session);
} }
internal void SetTrackTypes(byte point, TrackType mode, TrackSubchannelType subMode) internal void SetTrackTypes(byte point, TrackType mode, TrackSubchannelType subMode)
@@ -470,7 +366,7 @@ namespace DiscImageChef.Core.Devices.Dumping
} }
internal void AddTrack(byte adrCtl, byte tno, byte point, byte min, byte sec, byte frame, byte zero, byte pmin, internal void AddTrack(byte adrCtl, byte tno, byte point, byte min, byte sec, byte frame, byte zero, byte pmin,
byte psec, byte pframe, byte session) byte psec, byte pframe, byte session)
{ {
AlcoholTrack trk = new AlcoholTrack AlcoholTrack trk = new AlcoholTrack
{ {
@@ -531,5 +427,108 @@ namespace DiscImageChef.Core.Devices.Dumping
{ {
this.extension = extension; this.extension = extension;
} }
#region Internal Structures
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct AlcoholHeader
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] public string signature;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public byte[] version;
public AlcoholMediumType type;
public ushort sessions;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public ushort[] unknown1;
public ushort bcaLength;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public uint[] unknown2;
public uint bcaOffset;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] public uint[] unknown3;
public uint structuresOffset;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public uint[] unknown4;
public uint sessionOffset;
public uint dpmOffset;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct AlcoholSession
{
public int sessionStart;
public int sessionEnd;
public ushort sessionSequence;
public byte allBlocks;
public byte nonTrackBlocks;
public ushort firstTrack;
public ushort lastTrack;
public uint unknown;
public uint trackOffset;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct AlcoholTrack
{
public AlcoholTrackMode mode;
public AlcoholSubchannelMode subMode;
public byte adrCtl;
public byte tno;
public byte point;
public byte min;
public byte sec;
public byte frame;
public byte zero;
public byte pmin;
public byte psec;
public byte pframe;
public uint extraOffset;
public ushort sectorSize;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 18)] public byte[] unknown;
public uint startLba;
public ulong startOffset;
public uint files;
public uint footerOffset;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)] public byte[] unknown2;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct AlcoholTrackExtra
{
public uint pregap;
public uint sectors;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct AlcoholFooter
{
public uint filenameOffset;
public uint widechar;
public uint unknown1;
public uint unknown2;
}
#endregion Internal Structures
#region Internal enumerations
enum AlcoholMediumType : ushort
{
Cd = 0x00,
Cdr = 0x01,
Cdrw = 0x02,
Dvd = 0x10,
Dvdr = 0x12
}
enum AlcoholTrackMode : byte
{
NoData = 0x00,
Dvd = 0x02,
Audio = 0xA9,
Mode1 = 0xAA,
Mode2 = 0xAB,
Mode2F1 = 0xAC,
Mode2F2 = 0xAD
}
enum AlcoholSubchannelMode : byte
{
None = 0x00,
Interleaved = 0x08
}
#endregion Internal enumerations
} }
} }

View File

@@ -53,12 +53,12 @@ using TrackType = Schemas.TrackType;
namespace DiscImageChef.Core.Devices.Dumping namespace DiscImageChef.Core.Devices.Dumping
{ {
/// <summary> /// <summary>
/// Implement dumping Compact Discs /// Implement dumping Compact Discs
/// </summary> /// </summary>
class CompactDisc class CompactDisc
{ {
/// <summary> /// <summary>
/// Dumps a compact disc /// Dumps a compact disc
/// </summary> /// </summary>
/// <param name="dev">Device</param> /// <param name="dev">Device</param>
/// <param name="devicePath">Path to the device</param> /// <param name="devicePath">Path to the device</param>
@@ -147,12 +147,10 @@ namespace DiscImageChef.Core.Devices.Dumping
dumpLog.WriteLine("Reading Disc Information"); dumpLog.WriteLine("Reading Disc Information");
sense = dev.ReadDiscInformation(out cmdBuf, out senseBuf, sense = dev.ReadDiscInformation(out cmdBuf, out senseBuf,
MmcDiscInformationDataTypes.DiscInformation, dev.Timeout, MmcDiscInformationDataTypes.DiscInformation, dev.Timeout, out _);
out _);
if(!sense) if(!sense)
{ {
DiscInformation.StandardDiscInformation? discInfo = DiscInformation.StandardDiscInformation? discInfo = DiscInformation.Decode000b(cmdBuf);
DiscInformation.Decode000b(cmdBuf);
if(discInfo.HasValue) if(discInfo.HasValue)
if(dskType == MediaType.CD) if(dskType == MediaType.CD)
switch(discInfo.Value.DiscType) switch(discInfo.Value.DiscType)
@@ -191,8 +189,8 @@ namespace DiscImageChef.Core.Devices.Dumping
foreach(FullTOC.TrackDataDescriptor track in toc.Value.TrackDescriptors) foreach(FullTOC.TrackDataDescriptor track in toc.Value.TrackDescriptors)
{ {
if(track.TNO == 1 && ((TocControl)(track.CONTROL & 0x0D) == TocControl.DataTrack || if(track.TNO == 1 && ((TocControl)(track.CONTROL & 0x0D) == TocControl.DataTrack ||
(TocControl)(track.CONTROL & 0x0D) == (TocControl)(track.CONTROL & 0x0D) == TocControl.DataTrackIncremental)
TocControl.DataTrackIncremental)) allFirstSessionTracksAreAudio &= firstTrackLastSession != 1; ) allFirstSessionTracksAreAudio &= firstTrackLastSession != 1;
if((TocControl)(track.CONTROL & 0x0D) == TocControl.DataTrack || if((TocControl)(track.CONTROL & 0x0D) == TocControl.DataTrack ||
(TocControl)(track.CONTROL & 0x0D) == TocControl.DataTrackIncremental) (TocControl)(track.CONTROL & 0x0D) == TocControl.DataTrackIncremental)
@@ -265,7 +263,10 @@ namespace DiscImageChef.Core.Devices.Dumping
sessionsForAlcohol[i].SessionSequence = (ushort)(i + 1); sessionsForAlcohol[i].SessionSequence = (ushort)(i + 1);
sessionsForAlcohol[i].StartTrack = ushort.MaxValue; sessionsForAlcohol[i].StartTrack = ushort.MaxValue;
} }
foreach(FullTOC.TrackDataDescriptor trk in toc.Value.TrackDescriptors.Where(trk => trk.POINT > 0 && trk.POINT < 0xA0 && trk.SessionNumber <= sessionsForAlcohol.Length)) { foreach(FullTOC.TrackDataDescriptor trk in
toc.Value.TrackDescriptors.Where(trk => trk.POINT > 0 && trk.POINT < 0xA0 &&
trk.SessionNumber <= sessionsForAlcohol.Length))
{
if(trk.POINT < sessionsForAlcohol[trk.SessionNumber - 1].StartTrack) if(trk.POINT < sessionsForAlcohol[trk.SessionNumber - 1].StartTrack)
sessionsForAlcohol[trk.SessionNumber - 1].StartTrack = trk.POINT; sessionsForAlcohol[trk.SessionNumber - 1].StartTrack = trk.POINT;
if(trk.POINT > sessionsForAlcohol[trk.SessionNumber - 1].EndTrack) if(trk.POINT > sessionsForAlcohol[trk.SessionNumber - 1].EndTrack)
@@ -283,7 +284,8 @@ namespace DiscImageChef.Core.Devices.Dumping
List<TrackType> trackList = new List<TrackType>(); List<TrackType> trackList = new List<TrackType>();
long lastSector = 0; long lastSector = 0;
string lastMsf = null; string lastMsf = null;
foreach(FullTOC.TrackDataDescriptor trk in sortedTracks.Where(trk => trk.ADR == 1 || trk.ADR == 4)) if(trk.POINT >= 0x01 && trk.POINT <= 0x63) foreach(FullTOC.TrackDataDescriptor trk in sortedTracks.Where(trk => trk.ADR == 1 || trk.ADR == 4))
if(trk.POINT >= 0x01 && trk.POINT <= 0x63)
{ {
TrackType track = new TrackType TrackType track = new TrackType
{ {
@@ -294,11 +296,10 @@ namespace DiscImageChef.Core.Devices.Dumping
track.TrackType1 = TrackTypeTrackType.mode1; track.TrackType1 = TrackTypeTrackType.mode1;
else track.TrackType1 = TrackTypeTrackType.audio; else track.TrackType1 = TrackTypeTrackType.audio;
if(trk.PHOUR > 0) if(trk.PHOUR > 0)
track.StartMSF = string.Format("{3:D2}:{0:D2}:{1:D2}:{2:D2}", trk.PMIN, trk.PSEC, track.StartMSF = string.Format("{3:D2}:{0:D2}:{1:D2}:{2:D2}", trk.PMIN, trk.PSEC, trk.PFRAME,
trk.PFRAME, trk.PHOUR); trk.PHOUR);
else track.StartMSF = $"{trk.PMIN:D2}:{trk.PSEC:D2}:{trk.PFRAME:D2}"; else track.StartMSF = $"{trk.PMIN:D2}:{trk.PSEC:D2}:{trk.PFRAME:D2}";
track.StartSector = trk.PHOUR * 3600 * 75 + trk.PMIN * 60 * 75 + trk.PSEC * 75 + trk.PFRAME - track.StartSector = trk.PHOUR * 3600 * 75 + trk.PMIN * 60 * 75 + trk.PSEC * 75 + trk.PFRAME - 150;
150;
trackList.Add(track); trackList.Add(track);
} }
else if(trk.POINT == 0xA2) else if(trk.POINT == 0xA2)
@@ -338,7 +339,9 @@ namespace DiscImageChef.Core.Devices.Dumping
phour = trk.PHOUR; phour = trk.PHOUR;
} }
lastMsf = phour > 0 ? $"{phour:D2}:{pmin:D2}:{psec:D2}:{pframe:D2}" : $"{pmin:D2}:{psec:D2}:{pframe:D2}"; lastMsf = phour > 0
? $"{phour:D2}:{pmin:D2}:{psec:D2}:{pframe:D2}"
: $"{pmin:D2}:{psec:D2}:{pframe:D2}";
lastSector = phour * 3600 * 75 + pmin * 60 * 75 + psec * 75 + pframe - 150; lastSector = phour * 3600 * 75 + pmin * 60 * 75 + psec * 75 + pframe - 150;
} }
@@ -365,7 +368,9 @@ namespace DiscImageChef.Core.Devices.Dumping
pframe -= psec * 75; pframe -= psec * 75;
} }
tracks[t - 1].EndMSF = phour > 0 ? $"{phour:D2}:{pmin:D2}:{psec:D2}:{pframe:D2}" : $"{pmin:D2}:{psec:D2}:{pframe:D2}"; tracks[t - 1].EndMSF = phour > 0
? $"{phour:D2}:{pmin:D2}:{psec:D2}:{pframe:D2}"
: $"{pmin:D2}:{psec:D2}:{pframe:D2}";
} }
tracks[tracks.Length - 1].EndMSF = lastMsf; tracks[tracks.Length - 1].EndMSF = lastMsf;
@@ -608,8 +613,7 @@ namespace DiscImageChef.Core.Devices.Dumping
for(ulong b = i; b < i + blocksToRead; b++) resume.BadBlocks.Add(b); for(ulong b = i; b < i + blocksToRead; b++) resume.BadBlocks.Add(b);
DicConsole.DebugWriteLine("Dump-Media", "READ error:\n{0}", DicConsole.DebugWriteLine("Dump-Media", "READ error:\n{0}", Sense.PrettifySense(senseBuf));
Sense.PrettifySense(senseBuf));
mhddLog.Write(i, cmdDuration < 500 ? 65535 : cmdDuration); mhddLog.Write(i, cmdDuration < 500 ? 65535 : cmdDuration);
ibgLog.Write(i, 0); ibgLog.Write(i, 0);
@@ -715,7 +719,8 @@ namespace DiscImageChef.Core.Devices.Dumping
{ {
sense = dev.ReadCd(out readBuffer, out senseBuf, (uint)badSector, blockSize, blocksToRead, sense = dev.ReadCd(out readBuffer, out senseBuf, (uint)badSector, blockSize, blocksToRead,
MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true,
true, MmcErrorField.None, MmcSubchannel.Raw, dev.Timeout, out double cmdDuration); true, MmcErrorField.None, MmcSubchannel.Raw, dev.Timeout,
out double cmdDuration);
totalDuration += cmdDuration; totalDuration += cmdDuration;
} }
@@ -891,8 +896,7 @@ namespace DiscImageChef.Core.Devices.Dumping
FileStream xmlFs = new FileStream(outputPrefix + ".cicm.xml", FileMode.Create); FileStream xmlFs = new FileStream(outputPrefix + ".cicm.xml", FileMode.Create);
XmlSerializer xmlSer = XmlSerializer xmlSer = new XmlSerializer(typeof(CICMMetadataType));
new XmlSerializer(typeof(CICMMetadataType));
xmlSer.Serialize(xmlFs, sidecar); xmlSer.Serialize(xmlFs, sidecar);
xmlFs.Close(); xmlFs.Close();
alcohol.Close(); alcohol.Close();

View File

@@ -49,12 +49,12 @@ using Spare = DiscImageChef.Decoders.DVD.Spare;
namespace DiscImageChef.Core.Devices.Dumping namespace DiscImageChef.Core.Devices.Dumping
{ {
/// <summary> /// <summary>
/// Implement dumping optical discs from MultiMedia devices /// Implement dumping optical discs from MultiMedia devices
/// </summary> /// </summary>
static class Mmc static class Mmc
{ {
/// <summary> /// <summary>
/// Dumps an optical disc /// Dumps an optical disc
/// </summary> /// </summary>
/// <param name="dev">Device</param> /// <param name="dev">Device</param>
/// <param name="devicePath">Path to the device</param> /// <param name="devicePath">Path to the device</param>
@@ -204,7 +204,8 @@ namespace DiscImageChef.Core.Devices.Dumping
dumpLog.WriteLine("Device reports disc has {0} blocks", blocks); dumpLog.WriteLine("Device reports disc has {0} blocks", blocks);
#region Nintendo #region Nintendo
switch(dskType) { switch(dskType)
{
case MediaType.Unknown when blocks > 0: case MediaType.Unknown when blocks > 0:
dumpLog.WriteLine("Reading Physical Format Information"); dumpLog.WriteLine("Reading Physical Format Information");
sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
@@ -333,8 +334,7 @@ namespace DiscImageChef.Core.Devices.Dumping
sense = dev.ScsiInquiry(out byte[] inqBuf, out _); sense = dev.ScsiInquiry(out byte[] inqBuf, out _);
if(sense || !Inquiry.Decode(inqBuf).HasValue || if(sense || !Inquiry.Decode(inqBuf).HasValue || Inquiry.Decode(inqBuf).HasValue &&
Inquiry.Decode(inqBuf).HasValue &&
!Inquiry.Decode(inqBuf).Value.KreonPresent) !Inquiry.Decode(inqBuf).Value.KreonPresent)
{ {
dumpLog.WriteLine("Dumping Xbox Game Discs requires a drive with Kreon firmware."); dumpLog.WriteLine("Dumping Xbox Game Discs requires a drive with Kreon firmware.");
@@ -381,8 +381,7 @@ namespace DiscImageChef.Core.Devices.Dumping
{ {
dumpLog.WriteLine("Reading Lead-in Copyright Information."); dumpLog.WriteLine("Reading Lead-in Copyright Information.");
sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.CopyrightInformation, 0, dev.Timeout, MmcDiscStructureFormat.CopyrightInformation, 0, dev.Timeout, out _);
out _);
if(!sense) if(!sense)
if(CSS_CPRM.DecodeLeadInCopyright(cmdBuf).HasValue) if(CSS_CPRM.DecodeLeadInCopyright(cmdBuf).HasValue)
{ {
@@ -396,15 +395,15 @@ namespace DiscImageChef.Core.Devices.Dumping
}; };
DataFile.WriteTo("SCSI Dump", sidecar.OpticalDisc[0].CMI.Image, tmpBuf); DataFile.WriteTo("SCSI Dump", sidecar.OpticalDisc[0].CMI.Image, tmpBuf);
CSS_CPRM.LeadInCopyright cpy = CSS_CPRM.LeadInCopyright cpy = CSS_CPRM.DecodeLeadInCopyright(cmdBuf).Value;
CSS_CPRM.DecodeLeadInCopyright(cmdBuf).Value;
if(cpy.CopyrightType != CopyrightType.NoProtection) if(cpy.CopyrightType != CopyrightType.NoProtection)
sidecar.OpticalDisc[0].CopyProtection = cpy.CopyrightType.ToString(); sidecar.OpticalDisc[0].CopyProtection = cpy.CopyrightType.ToString();
} }
} }
#endregion DVD-ROM #endregion DVD-ROM
switch(dskType) { switch(dskType)
{
#region DVD-ROM and HD DVD-ROM #region DVD-ROM and HD DVD-ROM
case MediaType.DVDDownload: case MediaType.DVDDownload:
case MediaType.DVDROM: case MediaType.DVDROM:
@@ -427,6 +426,7 @@ namespace DiscImageChef.Core.Devices.Dumping
} }
break; break;
#endregion DVD-ROM and HD DVD-ROM #endregion DVD-ROM and HD DVD-ROM
#region DVD-RAM and HD DVD-RAM #region DVD-RAM and HD DVD-RAM
case MediaType.DVDRAM: case MediaType.DVDRAM:
case MediaType.HDDVDRAM: case MediaType.HDDVDRAM:
@@ -466,6 +466,7 @@ namespace DiscImageChef.Core.Devices.Dumping
} }
break; break;
#endregion DVD-RAM and HD DVD-RAM #endregion DVD-RAM and HD DVD-RAM
#region DVD-R and DVD-RW #region DVD-R and DVD-RW
case MediaType.DVDR: case MediaType.DVDR:
case MediaType.DVDRW: case MediaType.DVDRW:
@@ -488,15 +489,15 @@ namespace DiscImageChef.Core.Devices.Dumping
#endregion DVD-R and DVD-RW #endregion DVD-R and DVD-RW
} }
switch(dskType) { switch(dskType)
{
#region DVD-R, DVD-RW and HD DVD-R #region DVD-R, DVD-RW and HD DVD-R
case MediaType.DVDR: case MediaType.DVDR:
case MediaType.DVDRW: case MediaType.DVDRW:
case MediaType.HDDVDR: case MediaType.HDDVDR:
dumpLog.WriteLine("Reading Media Identifier."); dumpLog.WriteLine("Reading Media Identifier.");
sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.DvdrMediaIdentifier, 0, dev.Timeout, MmcDiscStructureFormat.DvdrMediaIdentifier, 0, dev.Timeout, out _);
out _);
if(!sense) if(!sense)
{ {
tmpBuf = new byte[cmdBuf.Length - 4]; tmpBuf = new byte[cmdBuf.Length - 4];
@@ -528,6 +529,7 @@ namespace DiscImageChef.Core.Devices.Dumping
} }
break; break;
#endregion DVD-R, DVD-RW and HD DVD-R #endregion DVD-R, DVD-RW and HD DVD-R
#region All DVD+ #region All DVD+
case MediaType.DVDPR: case MediaType.DVDPR:
case MediaType.DVDPRDL: case MediaType.DVDPRDL:
@@ -566,6 +568,7 @@ namespace DiscImageChef.Core.Devices.Dumping
} }
break; break;
#endregion All DVD+ #endregion All DVD+
#region HD DVD-ROM #region HD DVD-ROM
case MediaType.HDDVDROM: case MediaType.HDDVDROM:
dumpLog.WriteLine("Reading Lead-in Copyright Information."); dumpLog.WriteLine("Reading Lead-in Copyright Information.");
@@ -586,6 +589,7 @@ namespace DiscImageChef.Core.Devices.Dumping
} }
break; break;
#endregion HD DVD-ROM #endregion HD DVD-ROM
#region All Blu-ray #region All Blu-ray
case MediaType.BDR: case MediaType.BDR:
case MediaType.BDRE: case MediaType.BDRE:
@@ -628,7 +632,8 @@ namespace DiscImageChef.Core.Devices.Dumping
#endregion All Blu-ray #endregion All Blu-ray
} }
switch(dskType) { switch(dskType)
{
#region BD-ROM only #region BD-ROM only
case MediaType.BDROM: case MediaType.BDROM:
dumpLog.WriteLine("Reading Burst Cutting Area."); dumpLog.WriteLine("Reading Burst Cutting Area.");
@@ -649,6 +654,7 @@ namespace DiscImageChef.Core.Devices.Dumping
} }
break; break;
#endregion BD-ROM only #endregion BD-ROM only
#region Writable Blu-ray only #region Writable Blu-ray only
case MediaType.BDR: case MediaType.BDR:
case MediaType.BDRE: case MediaType.BDRE:
@@ -672,8 +678,7 @@ namespace DiscImageChef.Core.Devices.Dumping
dumpLog.WriteLine("Reading Spare Area Information."); dumpLog.WriteLine("Reading Spare Area Information.");
sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Bd, 0, 0, sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Bd, 0, 0,
MmcDiscStructureFormat.BdSpareAreaInformation, 0, dev.Timeout, MmcDiscStructureFormat.BdSpareAreaInformation, 0, dev.Timeout, out _);
out _);
if(!sense) if(!sense)
{ {
tmpBuf = new byte[cmdBuf.Length - 4]; tmpBuf = new byte[cmdBuf.Length - 4];

View File

@@ -41,8 +41,8 @@ namespace DiscImageChef.Core.Devices.Dumping
public static class NvMe public static class NvMe
{ {
public static void Dump(Device dev, string devicePath, string outputPrefix, ushort retryPasses, bool force, public static void Dump(Device dev, string devicePath, string outputPrefix, ushort retryPasses, bool force,
bool dumpRaw, bool persistent, bool stopOnError, ref Resume resume, bool dumpRaw, bool persistent, bool stopOnError, ref Resume resume, ref DumpLog dumpLog,
ref DumpLog dumpLog, Encoding encoding) Encoding encoding)
{ {
throw new NotImplementedException("NVMe devices not yet supported."); throw new NotImplementedException("NVMe devices not yet supported.");
} }

View File

@@ -40,12 +40,12 @@ using PlatformID = DiscImageChef.Interop.PlatformID;
namespace DiscImageChef.Core.Devices.Dumping namespace DiscImageChef.Core.Devices.Dumping
{ {
/// <summary> /// <summary>
/// Implements resume support /// Implements resume support
/// </summary> /// </summary>
static class ResumeSupport static class ResumeSupport
{ {
/// <summary> /// <summary>
/// Process resume /// Process resume
/// </summary> /// </summary>
/// <param name="isLba">If drive is LBA</param> /// <param name="isLba">If drive is LBA</param>
/// <param name="removable">If media is removable from device</param> /// <param name="removable">If media is removable from device</param>
@@ -57,11 +57,14 @@ namespace DiscImageChef.Core.Devices.Dumping
/// <param name="resume">Previous resume, or null</param> /// <param name="resume">Previous resume, or null</param>
/// <param name="currentTry">Current dumping hardware</param> /// <param name="currentTry">Current dumping hardware</param>
/// <param name="extents">Dumped extents</param> /// <param name="extents">Dumped extents</param>
/// <exception cref="NotImplementedException">If device uses CHS addressing</exception> /// <exception cref="System.NotImplementedException">If device uses CHS addressing</exception>
/// <exception cref="InvalidOperationException">If the provided resume does not correspond with the current in progress dump</exception> /// <exception cref="System.InvalidOperationException">
/// If the provided resume does not correspond with the current in
/// progress dump
/// </exception>
internal static void Process(bool isLba, bool removable, ulong blocks, string manufacturer, string model, internal static void Process(bool isLba, bool removable, ulong blocks, string manufacturer, string model,
string serial, PlatformID platform, ref Resume resume, string serial, PlatformID platform, ref Resume resume,
ref DumpHardwareType currentTry, ref ExtentsULong extents) ref DumpHardwareType currentTry, ref ExtentsULong extents)
{ {
if(resume != null) if(resume != null)
{ {
@@ -92,7 +95,8 @@ namespace DiscImageChef.Core.Devices.Dumping
InvalidOperationException($"Resume file specifies a device with serial {oldtry.Serial} but you're requesting to dump one with serial {serial}, not continuing..."); InvalidOperationException($"Resume file specifies a device with serial {oldtry.Serial} but you're requesting to dump one with serial {serial}, not continuing...");
} }
if(oldtry.Software == null) throw new InvalidOperationException("Found corrupt resume file, cannot continue..."); if(oldtry.Software == null)
throw new InvalidOperationException("Found corrupt resume file, cannot continue...");
if(oldtry.Software.Name != "DiscImageChef" || if(oldtry.Software.Name != "DiscImageChef" ||
oldtry.Software.OperatingSystem != platform.ToString() || oldtry.Software.OperatingSystem != platform.ToString() ||

View File

@@ -39,7 +39,6 @@ using System.Xml.Serialization;
using DiscImageChef.CommonTypes; using DiscImageChef.CommonTypes;
using DiscImageChef.Console; using DiscImageChef.Console;
using DiscImageChef.Core.Logging; using DiscImageChef.Core.Logging;
using DiscImageChef.Decoders.ATA;
using DiscImageChef.Decoders.SCSI; using DiscImageChef.Decoders.SCSI;
using DiscImageChef.Devices; using DiscImageChef.Devices;
using DiscImageChef.DiscImages; using DiscImageChef.DiscImages;
@@ -54,12 +53,12 @@ using TrackType = DiscImageChef.DiscImages.TrackType;
namespace DiscImageChef.Core.Devices.Dumping namespace DiscImageChef.Core.Devices.Dumping
{ {
/// <summary> /// <summary>
/// Implements dumping SCSI Block Commands and Reduced Block Commands devices /// Implements dumping SCSI Block Commands and Reduced Block Commands devices
/// </summary> /// </summary>
static class Sbc static class Sbc
{ {
/// <summary> /// <summary>
/// Dumps a SCSI Block Commands device or a Reduced Block Commands devices /// Dumps a SCSI Block Commands device or a Reduced Block Commands devices
/// </summary> /// </summary>
/// <param name="dev">Device</param> /// <param name="dev">Device</param>
/// <param name="devicePath">Path to the device</param> /// <param name="devicePath">Path to the device</param>
@@ -79,8 +78,8 @@ namespace DiscImageChef.Core.Devices.Dumping
/// <exception cref="InvalidOperationException">If the resume file is invalid</exception> /// <exception cref="InvalidOperationException">If the resume file is invalid</exception>
internal static void Dump(Device dev, string devicePath, string outputPrefix, ushort retryPasses, bool force, internal static void Dump(Device dev, string devicePath, string outputPrefix, ushort retryPasses, bool force,
bool dumpRaw, bool persistent, bool stopOnError, ref CICMMetadataType sidecar, bool dumpRaw, bool persistent, bool stopOnError, ref CICMMetadataType sidecar,
ref MediaType dskType, bool opticalDisc, ref Resume resume, ref MediaType dskType, bool opticalDisc, ref Resume resume, ref DumpLog dumpLog,
ref DumpLog dumpLog, Encoding encoding, Alcohol120 alcohol = null) Encoding encoding, Alcohol120 alcohol = null)
{ {
bool sense; bool sense;
ulong blocks; ulong blocks;
@@ -230,11 +229,11 @@ namespace DiscImageChef.Core.Devices.Dumping
} }
dumpLog.WriteLine("Requesting MODE SENSE (10)."); dumpLog.WriteLine("Requesting MODE SENSE (10).");
sense = dev.ModeSense10(out cmdBuf, out _, false, true, ScsiModeSensePageControl.Current, sense = dev.ModeSense10(out cmdBuf, out _, false, true, ScsiModeSensePageControl.Current, 0x3F,
0x3F, 0xFF, 5, out _); 0xFF, 5, out _);
if(!sense || dev.Error) if(!sense || dev.Error)
sense = dev.ModeSense10(out cmdBuf, out _, false, true, sense = dev.ModeSense10(out cmdBuf, out _, false, true, ScsiModeSensePageControl.Current,
ScsiModeSensePageControl.Current, 0x3F, 0x00, 5, out _); 0x3F, 0x00, 5, out _);
Modes.DecodedMode? decMode = null; Modes.DecodedMode? decMode = null;
@@ -252,11 +251,11 @@ namespace DiscImageChef.Core.Devices.Dumping
} }
dumpLog.WriteLine("Requesting MODE SENSE (6)."); dumpLog.WriteLine("Requesting MODE SENSE (6).");
sense = dev.ModeSense6(out cmdBuf, out _, false, ScsiModeSensePageControl.Current, 0x3F, sense = dev.ModeSense6(out cmdBuf, out _, false, ScsiModeSensePageControl.Current, 0x3F, 0x00,
0x00, 5, out _); 5, out _);
if(sense || dev.Error) if(sense || dev.Error)
sense = dev.ModeSense6(out cmdBuf, out _, false, ScsiModeSensePageControl.Current, sense = dev.ModeSense6(out cmdBuf, out _, false, ScsiModeSensePageControl.Current, 0x3F,
0x3F, 0x00, 5, out _); 0x00, 5, out _);
if(sense || dev.Error) sense = dev.ModeSense(out cmdBuf, out _, 5, out _); if(sense || dev.Error) sense = dev.ModeSense(out cmdBuf, out _, 5, out _);
if(!sense && !dev.Error) if(!sense && !dev.Error)
@@ -279,7 +278,9 @@ namespace DiscImageChef.Core.Devices.Dumping
decMode.Value.Header.BlockDescriptors.Length >= 1) decMode.Value.Header.BlockDescriptors.Length >= 1)
scsiDensityCode = (byte)decMode.Value.Header.BlockDescriptors[0].Density; scsiDensityCode = (byte)decMode.Value.Header.BlockDescriptors[0].Density;
containsFloppyPage = decMode.Value.Pages.Aggregate(containsFloppyPage, (current, modePage) => current | (modePage.Page == 0x05)); containsFloppyPage =
decMode.Value.Pages.Aggregate(containsFloppyPage,
(current, modePage) => current | (modePage.Page == 0x05));
} }
} }
} }
@@ -289,7 +290,6 @@ namespace DiscImageChef.Core.Devices.Dumping
dskType = MediaTypeFromScsi.Get((byte)dev.ScsiType, dev.Manufacturer, dev.Model, scsiMediumType, dskType = MediaTypeFromScsi.Get((byte)dev.ScsiType, dev.Manufacturer, dev.Model, scsiMediumType,
scsiDensityCode, blocks, blockSize); scsiDensityCode, blocks, blockSize);
dumpLog.WriteLine("Device reports {0} blocks ({1} bytes).", blocks, blocks * blockSize); dumpLog.WriteLine("Device reports {0} blocks ({1} bytes).", blocks, blocks * blockSize);
dumpLog.WriteLine("Device can read {0} blocks at a time.", blocksToRead); dumpLog.WriteLine("Device can read {0} blocks at a time.", blocksToRead);
dumpLog.WriteLine("Device reports {0} bytes per logical block.", blockSize); dumpLog.WriteLine("Device reports {0} bytes per logical block.", blockSize);
@@ -407,7 +407,7 @@ namespace DiscImageChef.Core.Devices.Dumping
dumpLog.WriteLine("Error reading {0} blocks from block {1}.", blocksToRead, i); dumpLog.WriteLine("Error reading {0} blocks from block {1}.", blocksToRead, i);
} }
double newSpeed= (double)blockSize * blocksToRead / 1048576 / (cmdDuration / 1000); double newSpeed = (double)blockSize * blocksToRead / 1048576 / (cmdDuration / 1000);
if(!double.IsInfinity(newSpeed)) currentSpeed = newSpeed; if(!double.IsInfinity(newSpeed)) currentSpeed = newSpeed;
resume.NextBlock = i + blocksToRead; resume.NextBlock = i + blocksToRead;
} }
@@ -474,12 +474,7 @@ namespace DiscImageChef.Core.Devices.Dumping
if(dev.ScsiType == PeripheralDeviceTypes.MultiMediaDevice) if(dev.ScsiType == PeripheralDeviceTypes.MultiMediaDevice)
{ {
Modes.ModePage_01_MMC pgMmc = Modes.ModePage_01_MMC pgMmc =
new Modes.ModePage_01_MMC new Modes.ModePage_01_MMC {PS = false, ReadRetryCount = 255, Parameter = 0x20};
{
PS = false,
ReadRetryCount = 255,
Parameter = 0x20
};
Modes.DecodedMode md = new Modes.DecodedMode Modes.DecodedMode md = new Modes.DecodedMode
{ {
Header = new Modes.ModeHeader(), Header = new Modes.ModeHeader(),
@@ -651,14 +646,19 @@ namespace DiscImageChef.Core.Devices.Dumping
Statistics.AddFilesystem(plugin.XmlFSType.Type); Statistics.AddFilesystem(plugin.XmlFSType.Type);
dumpLog.WriteLine("Filesystem {0} found.", plugin.XmlFSType.Type); dumpLog.WriteLine("Filesystem {0} found.", plugin.XmlFSType.Type);
switch(plugin.XmlFSType.Type) { switch(plugin.XmlFSType.Type)
case "Opera": dskType = MediaType.ThreeDO; {
case "Opera":
dskType = MediaType.ThreeDO;
break; break;
case "PC Engine filesystem": dskType = MediaType.SuperCDROM2; case "PC Engine filesystem":
dskType = MediaType.SuperCDROM2;
break; break;
case "Nintendo Wii filesystem": dskType = MediaType.WOD; case "Nintendo Wii filesystem":
dskType = MediaType.WOD;
break; break;
case "Nintendo Gamecube filesystem": dskType = MediaType.GOD; case "Nintendo Gamecube filesystem":
dskType = MediaType.GOD;
break; break;
} }
} }
@@ -692,14 +692,19 @@ namespace DiscImageChef.Core.Devices.Dumping
Statistics.AddFilesystem(plugin.XmlFSType.Type); Statistics.AddFilesystem(plugin.XmlFSType.Type);
dumpLog.WriteLine("Filesystem {0} found.", plugin.XmlFSType.Type); dumpLog.WriteLine("Filesystem {0} found.", plugin.XmlFSType.Type);
switch(plugin.XmlFSType.Type) { switch(plugin.XmlFSType.Type)
case "Opera": dskType = MediaType.ThreeDO; {
case "Opera":
dskType = MediaType.ThreeDO;
break; break;
case "PC Engine filesystem": dskType = MediaType.SuperCDROM2; case "PC Engine filesystem":
dskType = MediaType.SuperCDROM2;
break; break;
case "Nintendo Wii filesystem": dskType = MediaType.WOD; case "Nintendo Wii filesystem":
dskType = MediaType.WOD;
break; break;
case "Nintendo Gamecube filesystem": dskType = MediaType.GOD; case "Nintendo Gamecube filesystem":
dskType = MediaType.GOD;
break; break;
} }
} }
@@ -837,8 +842,7 @@ namespace DiscImageChef.Core.Devices.Dumping
FileStream xmlFs = new FileStream(outputPrefix + ".cicm.xml", FileMode.Create); FileStream xmlFs = new FileStream(outputPrefix + ".cicm.xml", FileMode.Create);
XmlSerializer xmlSer = XmlSerializer xmlSer = new XmlSerializer(typeof(CICMMetadataType));
new XmlSerializer(typeof(CICMMetadataType));
xmlSer.Serialize(xmlFs, sidecar); xmlSer.Serialize(xmlFs, sidecar);
xmlFs.Close(); xmlFs.Close();
if(alcohol != null && !dumpRaw) alcohol.Close(); if(alcohol != null && !dumpRaw) alcohol.Close();

View File

@@ -44,13 +44,13 @@ using MediaType = DiscImageChef.CommonTypes.MediaType;
namespace DiscImageChef.Core.Devices.Dumping namespace DiscImageChef.Core.Devices.Dumping
{ {
/// <summary> /// <summary>
/// Implements dumping SCSI and ATAPI devices /// Implements dumping SCSI and ATAPI devices
/// </summary> /// </summary>
public class Scsi public class Scsi
{ {
// TODO: Get cartridge serial number from Certance vendor EVPD // TODO: Get cartridge serial number from Certance vendor EVPD
/// <summary> /// <summary>
/// Dumps a SCSI Block Commands device or a Reduced Block Commands devices /// Dumps a SCSI Block Commands device or a Reduced Block Commands devices
/// </summary> /// </summary>
/// <param name="dev">Device</param> /// <param name="dev">Device</param>
/// <param name="devicePath">Path to the device</param> /// <param name="devicePath">Path to the device</param>
@@ -193,7 +193,8 @@ namespace DiscImageChef.Core.Devices.Dumping
CICMMetadataType sidecar = new CICMMetadataType(); CICMMetadataType sidecar = new CICMMetadataType();
switch(dev.ScsiType) { switch(dev.ScsiType)
{
case PeripheralDeviceTypes.SequentialAccess: case PeripheralDeviceTypes.SequentialAccess:
if(dumpRaw) throw new ArgumentException("Tapes cannot be dumped raw."); if(dumpRaw) throw new ArgumentException("Tapes cannot be dumped raw.");
@@ -201,11 +202,12 @@ namespace DiscImageChef.Core.Devices.Dumping
return; return;
case PeripheralDeviceTypes.MultiMediaDevice: case PeripheralDeviceTypes.MultiMediaDevice:
Mmc.Dump(dev, devicePath, outputPrefix, retryPasses, force, dumpRaw, persistent, stopOnError, Mmc.Dump(dev, devicePath, outputPrefix, retryPasses, force, dumpRaw, persistent, stopOnError,
ref sidecar, ref dskType, separateSubchannel, ref resume, ref dumpLog, dumpLeadIn, encoding); ref sidecar, ref dskType, separateSubchannel, ref resume, ref dumpLog, dumpLeadIn,
encoding);
return; return;
default: default:
Sbc.Dump(dev, devicePath, outputPrefix, retryPasses, force, dumpRaw, persistent, stopOnError, ref sidecar, Sbc.Dump(dev, devicePath, outputPrefix, retryPasses, force, dumpRaw, persistent, stopOnError,
ref dskType, false, ref resume, ref dumpLog, encoding); ref sidecar, ref dskType, false, ref resume, ref dumpLog, encoding);
break; break;
} }
} }

View File

@@ -49,7 +49,7 @@ namespace DiscImageChef.Core.Devices.Dumping
static class Ssc static class Ssc
{ {
/// <summary> /// <summary>
/// Dumps the tape from a SCSI Streaming device /// Dumps the tape from a SCSI Streaming device
/// </summary> /// </summary>
/// <param name="dev">Device</param> /// <param name="dev">Device</param>
/// <param name="devicePath">Path to the device</param> /// <param name="devicePath">Path to the device</param>
@@ -110,8 +110,8 @@ namespace DiscImageChef.Core.Devices.Dumping
fxSense = Sense.DecodeFixed(senseBuf, out strSense); fxSense = Sense.DecodeFixed(senseBuf, out strSense);
// And yet, did not rewind! // And yet, did not rewind!
if(fxSense.HasValue && (fxSense.Value.ASC == 0x00 && fxSense.Value.ASCQ != 0x04 || if(fxSense.HasValue &&
fxSense.Value.ASC != 0x00)) (fxSense.Value.ASC == 0x00 && fxSense.Value.ASCQ != 0x04 || fxSense.Value.ASC != 0x00))
{ {
DicConsole.WriteLine(); DicConsole.WriteLine();
DicConsole.ErrorWriteLine("Drive could not rewind, please correct. Sense follows..."); DicConsole.ErrorWriteLine("Drive could not rewind, please correct. Sense follows...");
@@ -136,8 +136,8 @@ namespace DiscImageChef.Core.Devices.Dumping
fxSense = Sense.DecodeFixed(senseBuf, out strSense); fxSense = Sense.DecodeFixed(senseBuf, out strSense);
if(fxSense.HasValue && (fxSense.Value.ASC == 0x20 && fxSense.Value.ASCQ != 0x00 || if(fxSense.HasValue && (fxSense.Value.ASC == 0x20 && fxSense.Value.ASCQ != 0x00 ||
fxSense.Value.ASC != 0x20 && fxSense.Value.SenseKey != fxSense.Value.ASC != 0x20 && fxSense.Value.SenseKey != SenseKeys.IllegalRequest)
SenseKeys.IllegalRequest)) )
{ {
DicConsole.ErrorWriteLine("Could not get position. Sense follows..."); DicConsole.ErrorWriteLine("Could not get position. Sense follows...");
DicConsole.ErrorWriteLine("{0}", strSense); DicConsole.ErrorWriteLine("{0}", strSense);
@@ -671,8 +671,7 @@ namespace DiscImageChef.Core.Devices.Dumping
FileStream xmlFs = new FileStream(outputPrefix + ".cicm.xml", FileMode.Create); FileStream xmlFs = new FileStream(outputPrefix + ".cicm.xml", FileMode.Create);
XmlSerializer xmlSer = XmlSerializer xmlSer = new XmlSerializer(typeof(CICMMetadataType));
new XmlSerializer(typeof(CICMMetadataType));
xmlSer.Serialize(xmlFs, sidecar); xmlSer.Serialize(xmlFs, sidecar);
xmlFs.Close(); xmlFs.Close();
} }

View File

@@ -51,12 +51,12 @@ using MediaType = DiscImageChef.Metadata.MediaType;
namespace DiscImageChef.Core.Devices.Dumping namespace DiscImageChef.Core.Devices.Dumping
{ {
/// <summary> /// <summary>
/// Implements dumping a MultiMediaCard or SecureDigital flash card /// Implements dumping a MultiMediaCard or SecureDigital flash card
/// </summary> /// </summary>
public class SecureDigital public class SecureDigital
{ {
/// <summary> /// <summary>
/// Dumps a MultiMediaCard or SecureDigital flash card /// Dumps a MultiMediaCard or SecureDigital flash card
/// </summary> /// </summary>
/// <param name="dev">Device</param> /// <param name="dev">Device</param>
/// <param name="devicePath">Path to the device</param> /// <param name="devicePath">Path to the device</param>
@@ -71,8 +71,8 @@ namespace DiscImageChef.Core.Devices.Dumping
/// <param name="encoding">Encoding to use when analyzing dump</param> /// <param name="encoding">Encoding to use when analyzing dump</param>
/// <exception cref="ArgumentException">If you asked to dump long sectors from a SCSI Streaming device</exception> /// <exception cref="ArgumentException">If you asked to dump long sectors from a SCSI Streaming device</exception>
public static void Dump(Device dev, string devicePath, string outputPrefix, ushort retryPasses, bool force, public static void Dump(Device dev, string devicePath, string outputPrefix, ushort retryPasses, bool force,
bool dumpRaw, bool persistent, bool stopOnError, ref Resume resume, bool dumpRaw, bool persistent, bool stopOnError, ref Resume resume, ref DumpLog dumpLog,
ref DumpLog dumpLog, Encoding encoding) Encoding encoding)
{ {
bool aborted; bool aborted;
@@ -93,8 +93,7 @@ namespace DiscImageChef.Core.Devices.Dumping
const uint TIMEOUT = 5; const uint TIMEOUT = 5;
double duration; double duration;
CICMMetadataType sidecar = CICMMetadataType sidecar = new CICMMetadataType {BlockMedia = new[] {new BlockMediaType()}};
new CICMMetadataType {BlockMedia = new[] {new BlockMediaType()}};
uint blocksToRead = 128; uint blocksToRead = 128;
uint blockSize = 512; uint blockSize = 512;
@@ -106,7 +105,8 @@ namespace DiscImageChef.Core.Devices.Dumping
int physicalBlockSize = 0; int physicalBlockSize = 0;
bool byteAddressed = true; bool byteAddressed = true;
switch(dev.Type) { switch(dev.Type)
{
case DeviceType.MMC: case DeviceType.MMC:
{ {
dumpLog.WriteLine("Reading Extended CSD"); dumpLog.WriteLine("Reading Extended CSD");
@@ -237,8 +237,8 @@ namespace DiscImageChef.Core.Devices.Dumping
DataFile.WriteTo("MMC/SecureDigital Dump", sidecar.BlockMedia[0].SecureDigital.SCR.Image, scr); DataFile.WriteTo("MMC/SecureDigital Dump", sidecar.BlockMedia[0].SecureDigital.SCR.Image, scr);
} }
switch(dev.Type)
switch(dev.Type) { {
case DeviceType.MMC: case DeviceType.MMC:
sidecar.BlockMedia[0].MultiMediaCard.CID = cidDump; sidecar.BlockMedia[0].MultiMediaCard.CID = cidDump;
sidecar.BlockMedia[0].MultiMediaCard.CSD = csdDump; sidecar.BlockMedia[0].MultiMediaCard.CSD = csdDump;
@@ -276,8 +276,7 @@ namespace DiscImageChef.Core.Devices.Dumping
while(true) while(true)
{ {
error = dev.Read(out cmdBuf, out _, 0, blockSize, blocksToRead, byteAddressed, TIMEOUT, error = dev.Read(out cmdBuf, out _, 0, blockSize, blocksToRead, byteAddressed, TIMEOUT, out duration);
out duration);
if(error) blocksToRead /= 2; if(error) blocksToRead /= 2;
@@ -549,14 +548,16 @@ namespace DiscImageChef.Core.Devices.Dumping
sidecar.BlockMedia[0].Checksums = dataChk.End().ToArray(); sidecar.BlockMedia[0].Checksums = dataChk.End().ToArray();
string xmlDskTyp = null, xmlDskSubTyp = null; string xmlDskTyp = null, xmlDskSubTyp = null;
switch(dev.Type) { switch(dev.Type)
{
case DeviceType.MMC: case DeviceType.MMC:
MediaType.MediaTypeToString(CommonTypes.MediaType.MMC, out xmlDskTyp, out xmlDskSubTyp); MediaType.MediaTypeToString(CommonTypes.MediaType.MMC, out xmlDskTyp, out xmlDskSubTyp);
sidecar.BlockMedia[0].Dimensions = Dimensions.DimensionsFromMediaType(CommonTypes.MediaType.MMC); sidecar.BlockMedia[0].Dimensions = Dimensions.DimensionsFromMediaType(CommonTypes.MediaType.MMC);
break; break;
case DeviceType.SecureDigital: case DeviceType.SecureDigital:
MediaType.MediaTypeToString(CommonTypes.MediaType.SecureDigital, out xmlDskTyp, out xmlDskSubTyp); MediaType.MediaTypeToString(CommonTypes.MediaType.SecureDigital, out xmlDskTyp, out xmlDskSubTyp);
sidecar.BlockMedia[0].Dimensions = Dimensions.DimensionsFromMediaType(CommonTypes.MediaType.SecureDigital); sidecar.BlockMedia[0].Dimensions =
Dimensions.DimensionsFromMediaType(CommonTypes.MediaType.SecureDigital);
break; break;
} }
@@ -568,10 +569,13 @@ namespace DiscImageChef.Core.Devices.Dumping
format = "Raw disk image (sector by sector copy)", format = "Raw disk image (sector by sector copy)",
Value = outputPrefix + ".bin" Value = outputPrefix + ".bin"
}; };
switch(dev.Type) { switch(dev.Type)
case DeviceType.MMC: sidecar.BlockMedia[0].Interface = "MultiMediaCard"; {
case DeviceType.MMC:
sidecar.BlockMedia[0].Interface = "MultiMediaCard";
break; break;
case DeviceType.SecureDigital: sidecar.BlockMedia[0].Interface = "SecureDigital"; case DeviceType.SecureDigital:
sidecar.BlockMedia[0].Interface = "SecureDigital";
break; break;
} }
@@ -602,16 +606,18 @@ namespace DiscImageChef.Core.Devices.Dumping
FileStream xmlFs = new FileStream(outputPrefix + ".cicm.xml", FileMode.Create); FileStream xmlFs = new FileStream(outputPrefix + ".cicm.xml", FileMode.Create);
XmlSerializer xmlSer = XmlSerializer xmlSer = new XmlSerializer(typeof(CICMMetadataType));
new XmlSerializer(typeof(CICMMetadataType));
xmlSer.Serialize(xmlFs, sidecar); xmlSer.Serialize(xmlFs, sidecar);
xmlFs.Close(); xmlFs.Close();
} }
switch(dev.Type) { switch(dev.Type)
case DeviceType.MMC: Statistics.AddMedia(CommonTypes.MediaType.MMC, true); {
case DeviceType.MMC:
Statistics.AddMedia(CommonTypes.MediaType.MMC, true);
break; break;
case DeviceType.SecureDigital: Statistics.AddMedia(CommonTypes.MediaType.SecureDigital, true); case DeviceType.SecureDigital:
Statistics.AddMedia(CommonTypes.MediaType.SecureDigital, true);
break; break;
} }
} }

View File

@@ -54,12 +54,12 @@ using TrackType = Schemas.TrackType;
namespace DiscImageChef.Core.Devices.Dumping namespace DiscImageChef.Core.Devices.Dumping
{ {
/// <summary> /// <summary>
/// Implements dumping an Xbox Game Disc using a Kreon drive /// Implements dumping an Xbox Game Disc using a Kreon drive
/// </summary> /// </summary>
static class Xgd static class Xgd
{ {
/// <summary> /// <summary>
/// Dumps an Xbox Game Disc using a Kreon drive /// Dumps an Xbox Game Disc using a Kreon drive
/// </summary> /// </summary>
/// <param name="dev">Device</param> /// <param name="dev">Device</param>
/// <param name="devicePath">Path to the device</param> /// <param name="devicePath">Path to the device</param>
@@ -74,11 +74,13 @@ namespace DiscImageChef.Core.Devices.Dumping
/// <param name="encoding">Encoding to use when analyzing dump</param> /// <param name="encoding">Encoding to use when analyzing dump</param>
/// <param name="sidecar">Partially filled initialized sidecar</param> /// <param name="sidecar">Partially filled initialized sidecar</param>
/// <param name="dskType">Disc type as detected in MMC layer</param> /// <param name="dskType">Disc type as detected in MMC layer</param>
/// <exception cref="InvalidOperationException">If the provided resume does not correspond with the current in progress dump</exception> /// <exception cref="InvalidOperationException">
/// If the provided resume does not correspond with the current in progress
/// dump
/// </exception>
internal static void Dump(Device dev, string devicePath, string outputPrefix, ushort retryPasses, bool force, internal static void Dump(Device dev, string devicePath, string outputPrefix, ushort retryPasses, bool force,
bool dumpRaw, bool persistent, bool stopOnError, ref CICMMetadataType sidecar, bool dumpRaw, bool persistent, bool stopOnError, ref CICMMetadataType sidecar,
ref MediaType dskType, ref Resume resume, ref DumpLog dumpLog, ref MediaType dskType, ref Resume resume, ref DumpLog dumpLog, Encoding encoding)
Encoding encoding)
{ {
bool sense; bool sense;
ulong blocks; ulong blocks;
@@ -176,8 +178,7 @@ namespace DiscImageChef.Core.Devices.Dumping
}; };
DataFile.WriteTo("SCSI Dump", sidecar.OpticalDisc[0].PFI.Image, tmpBuf, "Locked PFI", true); DataFile.WriteTo("SCSI Dump", sidecar.OpticalDisc[0].PFI.Image, tmpBuf, "Locked PFI", true);
DicConsole.DebugWriteLine("Dump-media command", "Video partition total size: {0} sectors", totalSize); DicConsole.DebugWriteLine("Dump-media command", "Video partition total size: {0} sectors", totalSize);
l0Video = PFI.Decode(readBuffer).Value.Layer0EndPSN - l0Video = PFI.Decode(readBuffer).Value.Layer0EndPSN - PFI.Decode(readBuffer).Value.DataAreaStartPSN + 1;
PFI.Decode(readBuffer).Value.DataAreaStartPSN + 1;
l1Video = totalSize - l0Video + 1; l1Video = totalSize - l0Video + 1;
dumpLog.WriteLine("Reading Disc Manufacturing Information."); dumpLog.WriteLine("Reading Disc Manufacturing Information.");
sense = dev.ReadDiscStructure(out readBuffer, out senseBuf, MmcDiscStructureMediaType.Dvd, 0, 0, sense = dev.ReadDiscStructure(out readBuffer, out senseBuf, MmcDiscStructureMediaType.Dvd, 0, 0,
@@ -256,8 +257,9 @@ namespace DiscImageChef.Core.Devices.Dumping
DicConsole.DebugWriteLine("Dump-media command", "Unlocked total size: {0} sectors", totalSize); DicConsole.DebugWriteLine("Dump-media command", "Unlocked total size: {0} sectors", totalSize);
blocks = totalSize + 1; blocks = totalSize + 1;
middleZone = totalSize - (PFI.Decode(readBuffer).Value.Layer0EndPSN - middleZone =
PFI.Decode(readBuffer).Value.DataAreaStartPSN + 1) - gameSize + 1; totalSize - (PFI.Decode(readBuffer).Value.Layer0EndPSN - PFI.Decode(readBuffer).Value.DataAreaStartPSN +
1) - gameSize + 1;
tmpBuf = new byte[readBuffer.Length - 4]; tmpBuf = new byte[readBuffer.Length - 4];
Array.Copy(readBuffer, 4, tmpBuf, 0, readBuffer.Length - 4); Array.Copy(readBuffer, 4, tmpBuf, 0, readBuffer.Length - 4);
@@ -438,15 +440,15 @@ namespace DiscImageChef.Core.Devices.Dumping
for(ulong b = i; b < i + blocksToRead; b++) resume.BadBlocks.Add(b); for(ulong b = i; b < i + blocksToRead; b++) resume.BadBlocks.Add(b);
DicConsole.DebugWriteLine("Dump-Media", "READ error:\n{0}", DicConsole.DebugWriteLine("Dump-Media", "READ error:\n{0}", Sense.PrettifySense(senseBuf));
Sense.PrettifySense(senseBuf));
mhddLog.Write(i, cmdDuration < 500 ? 65535 : cmdDuration); mhddLog.Write(i, cmdDuration < 500 ? 65535 : cmdDuration);
ibgLog.Write(i, 0); ibgLog.Write(i, 0);
dumpLog.WriteLine("Error reading {0} blocks from block {1}.", blocksToRead, i); dumpLog.WriteLine("Error reading {0} blocks from block {1}.", blocksToRead, i);
string[] senseLines = Sense.PrettifySense(senseBuf).Split(new[] {Environment.NewLine}, string[] senseLines = Sense.PrettifySense(senseBuf).Split(new[] {Environment.NewLine},
StringSplitOptions.RemoveEmptyEntries); StringSplitOptions
.RemoveEmptyEntries);
foreach(string senseLine in senseLines) dumpLog.WriteLine(senseLine); foreach(string senseLine in senseLines) dumpLog.WriteLine(senseLine);
} }
@@ -567,15 +569,13 @@ namespace DiscImageChef.Core.Devices.Dumping
// TODO: Handle errors in video partition // TODO: Handle errors in video partition
//errored += blocksToRead; //errored += blocksToRead;
//resume.BadBlocks.Add(l1); //resume.BadBlocks.Add(l1);
DicConsole.DebugWriteLine("Dump-Media", "READ error:\n{0}", DicConsole.DebugWriteLine("Dump-Media", "READ error:\n{0}", Sense.PrettifySense(senseBuf));
Sense.PrettifySense(senseBuf));
mhddLog.Write(l1, cmdDuration < 500 ? 65535 : cmdDuration); mhddLog.Write(l1, cmdDuration < 500 ? 65535 : cmdDuration);
ibgLog.Write(l1, 0); ibgLog.Write(l1, 0);
dumpLog.WriteLine("Error reading {0} blocks from block {1}.", blocksToRead, l1); dumpLog.WriteLine("Error reading {0} blocks from block {1}.", blocksToRead, l1);
string[] senseLines = Sense.PrettifySense(senseBuf).Split(new[] {Environment.NewLine}, string[] senseLines = Sense.PrettifySense(senseBuf).Split(new[] {Environment.NewLine},
StringSplitOptions StringSplitOptions.RemoveEmptyEntries);
.RemoveEmptyEntries);
foreach(string senseLine in senseLines) dumpLog.WriteLine(senseLine); foreach(string senseLine in senseLines) dumpLog.WriteLine(senseLine);
} }
@@ -672,12 +672,7 @@ namespace DiscImageChef.Core.Devices.Dumping
if(dev.ScsiType == PeripheralDeviceTypes.MultiMediaDevice) if(dev.ScsiType == PeripheralDeviceTypes.MultiMediaDevice)
{ {
Modes.ModePage_01_MMC pgMmc = Modes.ModePage_01_MMC pgMmc =
new Modes.ModePage_01_MMC new Modes.ModePage_01_MMC {PS = false, ReadRetryCount = 255, Parameter = 0x20};
{
PS = false,
ReadRetryCount = 255,
Parameter = 0x20
};
Modes.DecodedMode md = new Modes.DecodedMode Modes.DecodedMode md = new Modes.DecodedMode
{ {
Header = new Modes.ModeHeader(), Header = new Modes.ModeHeader(),
@@ -851,14 +846,19 @@ namespace DiscImageChef.Core.Devices.Dumping
Statistics.AddFilesystem(plugin.XmlFSType.Type); Statistics.AddFilesystem(plugin.XmlFSType.Type);
dumpLog.WriteLine("Filesystem {0} found.", plugin.XmlFSType.Type); dumpLog.WriteLine("Filesystem {0} found.", plugin.XmlFSType.Type);
switch(plugin.XmlFSType.Type) { switch(plugin.XmlFSType.Type)
case "Opera": dskType = MediaType.ThreeDO; {
case "Opera":
dskType = MediaType.ThreeDO;
break; break;
case "PC Engine filesystem": dskType = MediaType.SuperCDROM2; case "PC Engine filesystem":
dskType = MediaType.SuperCDROM2;
break; break;
case "Nintendo Wii filesystem": dskType = MediaType.WOD; case "Nintendo Wii filesystem":
dskType = MediaType.WOD;
break; break;
case "Nintendo Gamecube filesystem": dskType = MediaType.GOD; case "Nintendo Gamecube filesystem":
dskType = MediaType.GOD;
break; break;
} }
} }
@@ -892,14 +892,19 @@ namespace DiscImageChef.Core.Devices.Dumping
Statistics.AddFilesystem(plugin.XmlFSType.Type); Statistics.AddFilesystem(plugin.XmlFSType.Type);
dumpLog.WriteLine("Filesystem {0} found.", plugin.XmlFSType.Type); dumpLog.WriteLine("Filesystem {0} found.", plugin.XmlFSType.Type);
switch(plugin.XmlFSType.Type) { switch(plugin.XmlFSType.Type)
case "Opera": dskType = MediaType.ThreeDO; {
case "Opera":
dskType = MediaType.ThreeDO;
break; break;
case "PC Engine filesystem": dskType = MediaType.SuperCDROM2; case "PC Engine filesystem":
dskType = MediaType.SuperCDROM2;
break; break;
case "Nintendo Wii filesystem": dskType = MediaType.WOD; case "Nintendo Wii filesystem":
dskType = MediaType.WOD;
break; break;
case "Nintendo Gamecube filesystem": dskType = MediaType.GOD; case "Nintendo Gamecube filesystem":
dskType = MediaType.GOD;
break; break;
} }
} }
@@ -961,8 +966,7 @@ namespace DiscImageChef.Core.Devices.Dumping
FileStream xmlFs = new FileStream(outputPrefix + ".cicm.xml", FileMode.Create); FileStream xmlFs = new FileStream(outputPrefix + ".cicm.xml", FileMode.Create);
XmlSerializer xmlSer = XmlSerializer xmlSer = new XmlSerializer(typeof(CICMMetadataType));
new XmlSerializer(typeof(CICMMetadataType));
xmlSer.Serialize(xmlFs, sidecar); xmlSer.Serialize(xmlFs, sidecar);
xmlFs.Close(); xmlFs.Close();
} }

View File

@@ -37,23 +37,13 @@ using DiscImageChef.Devices;
namespace DiscImageChef.Core.Devices namespace DiscImageChef.Core.Devices
{ {
/// <summary> /// <summary>
/// Reduces common code used for scanning and dumping /// Reduces common code used for scanning and dumping
/// </summary> /// </summary>
partial class Reader partial class Reader
{ {
Device dev; Device dev;
uint timeout; uint timeout;
internal string ErrorMessage { get; private set; }
internal ulong Blocks { get; private set; }
internal uint BlocksToRead { get; private set; }
internal uint LogicalBlockSize { get; private set; }
internal uint PhysicalBlockSize { get; private set; }
internal uint LongBlockSize { get; private set; }
internal bool CanReadRaw { get; private set; }
internal bool CanSeek => ataSeek || seek6 || seek10;
internal bool CanSeekLba => ataSeekLba || seek6 || seek10;
internal Reader(Device dev, uint timeout, byte[] identification, bool raw = false) internal Reader(Device dev, uint timeout, byte[] identification, bool raw = false)
{ {
this.dev = dev; this.dev = dev;
@@ -71,6 +61,16 @@ namespace DiscImageChef.Core.Devices
} }
} }
internal string ErrorMessage { get; private set; }
internal ulong Blocks { get; private set; }
internal uint BlocksToRead { get; private set; }
internal uint LogicalBlockSize { get; private set; }
internal uint PhysicalBlockSize { get; private set; }
internal uint LongBlockSize { get; private set; }
internal bool CanReadRaw { get; private set; }
internal bool CanSeek => ataSeek || seek6 || seek10;
internal bool CanSeekLba => ataSeekLba || seek6 || seek10;
internal ulong GetDeviceBlocks() internal ulong GetDeviceBlocks()
{ {
switch(dev.Type) switch(dev.Type)

View File

@@ -39,21 +39,20 @@ namespace DiscImageChef.Core.Devices
{ {
partial class Reader partial class Reader
{ {
bool ataReadLba; Identify.IdentifyDevice ataId;
bool ataReadRetryLba;
bool ataReadDmaLba;
bool ataReadDmaRetryLba;
bool ataReadLba48;
bool ataReadDmaLba48;
bool ataRead; bool ataRead;
bool ataReadRetry;
bool ataReadDma; bool ataReadDma;
bool ataReadDmaLba;
bool ataReadDmaLba48;
bool ataReadDmaRetry; bool ataReadDmaRetry;
bool ataReadDmaRetryLba;
bool ataReadLba;
bool ataReadLba48;
bool ataReadRetry;
bool ataReadRetryLba;
bool ataSeek; bool ataSeek;
bool ataSeekLba; bool ataSeekLba;
Identify.IdentifyDevice ataId;
internal bool IsLba { get; private set; } internal bool IsLba { get; private set; }
internal ushort Cylinders { get; private set; } internal ushort Cylinders { get; private set; }
internal byte Heads { get; private set; } internal byte Heads { get; private set; }
@@ -71,7 +70,7 @@ namespace DiscImageChef.Core.Devices
Blocks = (ulong)(Cylinders * Heads * Sectors); Blocks = (ulong)(Cylinders * Heads * Sectors);
} }
if((ataId.CurrentCylinders != 0 && ataId.CurrentHeads != 0 && ataId.CurrentSectorsPerTrack != 0) || if(ataId.CurrentCylinders != 0 && ataId.CurrentHeads != 0 && ataId.CurrentSectorsPerTrack != 0 ||
ataId.Cylinders <= 0 || ataId.Heads <= 0 || ataId.Cylinders <= 0 || ataId.Heads <= 0 ||
ataId.SectorsPerTrack <= 0) return (Cylinders, Heads, Sectors); ataId.SectorsPerTrack <= 0) return (Cylinders, Heads, Sectors);
@@ -103,7 +102,8 @@ namespace DiscImageChef.Core.Devices
bool AtaFindReadCommand() bool AtaFindReadCommand()
{ {
bool sense = dev.Read(out byte[] cmdBuf, out AtaErrorRegistersChs errorChs, false, 0, 0, 1, 1, timeout, out _); bool sense = dev.Read(out byte[] cmdBuf, out AtaErrorRegistersChs errorChs, false, 0, 0, 1, 1, timeout,
out _);
ataRead = !sense && (errorChs.Status & 0x27) == 0 && errorChs.Error == 0 && cmdBuf.Length > 0; ataRead = !sense && (errorChs.Status & 0x27) == 0 && errorChs.Error == 0 && cmdBuf.Length > 0;
sense = dev.Read(out cmdBuf, out errorChs, true, 0, 0, 1, 1, timeout, out _); sense = dev.Read(out cmdBuf, out errorChs, true, 0, 0, 1, 1, timeout, out _);
ataReadRetry = !sense && (errorChs.Status & 0x27) == 0 && errorChs.Error == 0 && cmdBuf.Length > 0; ataReadRetry = !sense && (errorChs.Status & 0x27) == 0 && errorChs.Error == 0 && cmdBuf.Length > 0;
@@ -183,9 +183,7 @@ namespace DiscImageChef.Core.Devices
else LogicalBlockSize = 512; else LogicalBlockSize = 512;
if((ataId.PhysLogSectorSize & 0x2000) == 0x2000) if((ataId.PhysLogSectorSize & 0x2000) == 0x2000)
{
PhysicalBlockSize = LogicalBlockSize * (uint)Math.Pow(2, ataId.PhysLogSectorSize & 0xF); PhysicalBlockSize = LogicalBlockSize * (uint)Math.Pow(2, ataId.PhysLogSectorSize & 0xF);
}
else PhysicalBlockSize = LogicalBlockSize; else PhysicalBlockSize = LogicalBlockSize;
} }
else else

View File

@@ -39,19 +39,19 @@ namespace DiscImageChef.Core.Devices
partial class Reader partial class Reader
{ {
// TODO: Raw reading // TODO: Raw reading
bool read6; bool hldtstReadRaw;
bool plextorReadRaw;
bool read10; bool read10;
bool read12; bool read12;
bool read16; bool read16;
bool read6;
bool readLong10; bool readLong10;
bool readLong16; bool readLong16;
bool hldtstReadRaw;
bool readLongDvd; bool readLongDvd;
bool plextorReadRaw;
bool syqReadLong6;
bool syqReadLong10;
bool seek6;
bool seek10; bool seek10;
bool seek6;
bool syqReadLong10;
bool syqReadLong6;
ulong ScsiGetBlocks() ulong ScsiGetBlocks()
{ {
@@ -62,14 +62,14 @@ namespace DiscImageChef.Core.Devices
{ {
read6 = !dev.Read6(out _, out byte[] senseBuf, 0, LogicalBlockSize, timeout, out _); read6 = !dev.Read6(out _, out byte[] senseBuf, 0, LogicalBlockSize, timeout, out _);
read10 = !dev.Read10(out _, out senseBuf, 0, false, true, false, false, 0, LogicalBlockSize, 0, 1, read10 = !dev.Read10(out _, out senseBuf, 0, false, true, false, false, 0, LogicalBlockSize, 0, 1, timeout,
timeout, out _); out _);
read12 = !dev.Read12(out _, out senseBuf, 0, false, true, false, false, 0, LogicalBlockSize, 0, 1, false, read12 = !dev.Read12(out _, out senseBuf, 0, false, true, false, false, 0, LogicalBlockSize, 0, 1, false,
timeout, out _); timeout, out _);
read16 = !dev.Read16(out _, out senseBuf, 0, false, true, false, 0, LogicalBlockSize, 0, 1, false, read16 = !dev.Read16(out _, out senseBuf, 0, false, true, false, 0, LogicalBlockSize, 0, 1, false, timeout,
timeout, out _); out _);
seek6 = !dev.Seek6(out senseBuf, 0, timeout, out _); seek6 = !dev.Seek6(out senseBuf, 0, timeout, out _);
@@ -121,15 +121,14 @@ namespace DiscImageChef.Core.Devices
} }
}*/ }*/
testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, 0xFFFF, timeout, testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, 0xFFFF, timeout, out _);
out _);
FixedSense? decSense; FixedSense? decSense;
if(testSense && !dev.Error) if(testSense && !dev.Error)
{ {
decSense = Sense.DecodeFixed(senseBuf); decSense = Sense.DecodeFixed(senseBuf);
if(decSense.HasValue) if(decSense.HasValue)
if(decSense.Value.SenseKey == SenseKeys.IllegalRequest && if(decSense.Value.SenseKey == SenseKeys.IllegalRequest && decSense.Value.ASC == 0x24 &&
decSense.Value.ASC == 0x24 && decSense.Value.ASCQ == 0x00) decSense.Value.ASCQ == 0x00)
{ {
CanReadRaw = true; CanReadRaw = true;
if(decSense.Value.InformationValid && decSense.Value.ILI) if(decSense.Value.InformationValid && decSense.Value.ILI)
@@ -153,8 +152,7 @@ namespace DiscImageChef.Core.Devices
600, 610, 630 600, 610, 630
}) })
{ {
testSense = dev.ReadLong16(out _, out senseBuf, false, 0, testSize, timeout, testSense = dev.ReadLong16(out _, out senseBuf, false, 0, testSize, timeout, out _);
out _);
if(!testSense && !dev.Error) if(!testSense && !dev.Error)
{ {
readLong16 = true; readLong16 = true;
@@ -163,8 +161,8 @@ namespace DiscImageChef.Core.Devices
break; break;
} }
testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, testSize, testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, testSize, timeout,
timeout, out _); out _);
if(testSense || dev.Error) continue; if(testSense || dev.Error) continue;
readLong10 = true; readLong10 = true;
@@ -181,8 +179,7 @@ namespace DiscImageChef.Core.Devices
1200 1200
}) })
{ {
testSense = dev.ReadLong16(out _, out senseBuf, false, 0, testSize, timeout, testSense = dev.ReadLong16(out _, out senseBuf, false, 0, testSize, timeout, out _);
out _);
if(!testSense && !dev.Error) if(!testSense && !dev.Error)
{ {
readLong16 = true; readLong16 = true;
@@ -191,8 +188,8 @@ namespace DiscImageChef.Core.Devices
break; break;
} }
testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, testSize, testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, testSize, timeout,
timeout, out _); out _);
if(testSense || dev.Error) continue; if(testSense || dev.Error) continue;
readLong10 = true; readLong10 = true;
@@ -202,8 +199,7 @@ namespace DiscImageChef.Core.Devices
} }
else if(LogicalBlockSize == 2048) else if(LogicalBlockSize == 2048)
{ {
testSense = dev.ReadLong16(out _, out senseBuf, false, 0, 2380, timeout, testSense = dev.ReadLong16(out _, out senseBuf, false, 0, 2380, timeout, out _);
out _);
if(!testSense && !dev.Error) if(!testSense && !dev.Error)
{ {
readLong16 = true; readLong16 = true;
@@ -212,8 +208,7 @@ namespace DiscImageChef.Core.Devices
} }
else else
{ {
testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, 2380, timeout, testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, 2380, timeout, out _);
out _);
if(!testSense && !dev.Error) if(!testSense && !dev.Error)
{ {
readLong10 = true; readLong10 = true;
@@ -224,8 +219,7 @@ namespace DiscImageChef.Core.Devices
} }
else if(LogicalBlockSize == 4096) else if(LogicalBlockSize == 4096)
{ {
testSense = dev.ReadLong16(out _, out senseBuf, false, 0, 4760, timeout, testSense = dev.ReadLong16(out _, out senseBuf, false, 0, 4760, timeout, out _);
out _);
if(!testSense && !dev.Error) if(!testSense && !dev.Error)
{ {
readLong16 = true; readLong16 = true;
@@ -234,8 +228,7 @@ namespace DiscImageChef.Core.Devices
} }
else else
{ {
testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, 4760, timeout, testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, 4760, timeout, out _);
out _);
if(!testSense && !dev.Error) if(!testSense && !dev.Error)
{ {
readLong10 = true; readLong10 = true;
@@ -246,8 +239,7 @@ namespace DiscImageChef.Core.Devices
} }
else if(LogicalBlockSize == 8192) else if(LogicalBlockSize == 8192)
{ {
testSense = dev.ReadLong16(out _, out senseBuf, false, 0, 9424, timeout, testSense = dev.ReadLong16(out _, out senseBuf, false, 0, 9424, timeout, out _);
out _);
if(!testSense && !dev.Error) if(!testSense && !dev.Error)
{ {
readLong16 = true; readLong16 = true;
@@ -256,8 +248,7 @@ namespace DiscImageChef.Core.Devices
} }
else else
{ {
testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, 9424, timeout, testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, 9424, timeout, out _);
out _);
if(!testSense && !dev.Error) if(!testSense && !dev.Error)
{ {
readLong10 = true; readLong10 = true;
@@ -269,28 +260,26 @@ namespace DiscImageChef.Core.Devices
if(!CanReadRaw && dev.Manufacturer == "SYQUEST") if(!CanReadRaw && dev.Manufacturer == "SYQUEST")
{ {
testSense = dev.SyQuestReadLong10(out _, out senseBuf, 0, 0xFFFF, timeout, testSense = dev.SyQuestReadLong10(out _, out senseBuf, 0, 0xFFFF, timeout, out _);
out _);
if(testSense) if(testSense)
{ {
decSense = Sense.DecodeFixed(senseBuf); decSense = Sense.DecodeFixed(senseBuf);
if(decSense.HasValue) if(decSense.HasValue)
if(decSense.Value.SenseKey == SenseKeys.IllegalRequest && if(decSense.Value.SenseKey == SenseKeys.IllegalRequest && decSense.Value.ASC == 0x24 &&
decSense.Value.ASC == 0x24 && decSense.Value.ASCQ == 0x00) decSense.Value.ASCQ == 0x00)
{ {
CanReadRaw = true; CanReadRaw = true;
if(decSense.Value.InformationValid && decSense.Value.ILI) if(decSense.Value.InformationValid && decSense.Value.ILI)
{ {
LongBlockSize = 0xFFFF - (decSense.Value.Information & 0xFFFF); LongBlockSize = 0xFFFF - (decSense.Value.Information & 0xFFFF);
syqReadLong10 = syqReadLong10 =
!dev.SyQuestReadLong10(out _, out senseBuf, 0, LongBlockSize, !dev.SyQuestReadLong10(out _, out senseBuf, 0, LongBlockSize, timeout,
timeout, out _); out _);
} }
} }
else else
{ {
testSense = dev.SyQuestReadLong6(out _, out senseBuf, 0, 0xFFFF, timeout, testSense = dev.SyQuestReadLong6(out _, out senseBuf, 0, 0xFFFF, timeout, out _);
out _);
if(testSense) if(testSense)
{ {
decSense = Sense.DecodeFixed(senseBuf); decSense = Sense.DecodeFixed(senseBuf);
@@ -303,8 +292,8 @@ namespace DiscImageChef.Core.Devices
{ {
LongBlockSize = 0xFFFF - (decSense.Value.Information & 0xFFFF); LongBlockSize = 0xFFFF - (decSense.Value.Information & 0xFFFF);
syqReadLong6 = syqReadLong6 =
!dev.SyQuestReadLong6(out _, out senseBuf, 0, !dev.SyQuestReadLong6(out _, out senseBuf, 0, LongBlockSize,
LongBlockSize, timeout, out _); timeout, out _);
} }
} }
} }
@@ -313,8 +302,7 @@ namespace DiscImageChef.Core.Devices
if(!CanReadRaw && LogicalBlockSize == 256) if(!CanReadRaw && LogicalBlockSize == 256)
{ {
testSense = dev.SyQuestReadLong6(out _, out senseBuf, 0, 262, timeout, testSense = dev.SyQuestReadLong6(out _, out senseBuf, 0, 262, timeout, out _);
out _);
if(!testSense && !dev.Error) if(!testSense && !dev.Error)
{ {
syqReadLong6 = true; syqReadLong6 = true;
@@ -326,14 +314,13 @@ namespace DiscImageChef.Core.Devices
} }
else else
{ {
switch(dev.Manufacturer) { switch(dev.Manufacturer)
{
case "HL-DT-ST": case "HL-DT-ST":
hldtstReadRaw = hldtstReadRaw = !dev.HlDtStReadRawDvd(out _, out senseBuf, 0, 1, timeout, out _);
!dev.HlDtStReadRawDvd(out _, out senseBuf, 0, 1, timeout, out _);
break; break;
case "PLEXTOR": case "PLEXTOR":
plextorReadRaw = plextorReadRaw = !dev.PlextorReadRawDvd(out _, out senseBuf, 0, 1, timeout, out _);
!dev.PlextorReadRawDvd(out _, out senseBuf, 0, 1, timeout, out _);
break; break;
} }
@@ -346,8 +333,7 @@ namespace DiscImageChef.Core.Devices
// READ LONG (10) for some DVD drives // READ LONG (10) for some DVD drives
if(!CanReadRaw && dev.Manufacturer == "MATSHITA") if(!CanReadRaw && dev.Manufacturer == "MATSHITA")
{ {
testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, 37856, timeout, testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, 37856, timeout, out _);
out _);
if(!testSense && !dev.Error) if(!testSense && !dev.Error)
{ {
readLongDvd = true; readLongDvd = true;
@@ -423,26 +409,25 @@ namespace DiscImageChef.Core.Devices
{ {
if(read16) if(read16)
{ {
dev.Read16(out _, out _, 0, false, true, false, 0, LogicalBlockSize, 0, dev.Read16(out _, out _, 0, false, true, false, 0, LogicalBlockSize, 0, BlocksToRead, false,
BlocksToRead, false, timeout, out _); timeout, out _);
if(dev.Error) BlocksToRead /= 2; if(dev.Error) BlocksToRead /= 2;
} }
else if(read12) else if(read12)
{ {
dev.Read12(out _, out _, 0, false, false, false, false, 0, LogicalBlockSize, 0, dev.Read12(out _, out _, 0, false, false, false, false, 0, LogicalBlockSize, 0, BlocksToRead, false,
BlocksToRead, false, timeout, out _); timeout, out _);
if(dev.Error) BlocksToRead /= 2; if(dev.Error) BlocksToRead /= 2;
} }
else if(read10) else if(read10)
{ {
dev.Read10(out _, out _, 0, false, true, false, false, 0, LogicalBlockSize, 0, dev.Read10(out _, out _, 0, false, true, false, false, 0, LogicalBlockSize, 0, (ushort)BlocksToRead,
(ushort)BlocksToRead, timeout, out _); timeout, out _);
if(dev.Error) BlocksToRead /= 2; if(dev.Error) BlocksToRead /= 2;
} }
else if(read6) else if(read6)
{ {
dev.Read6(out _, out _, 0, LogicalBlockSize, (byte)BlocksToRead, timeout, dev.Read6(out _, out _, 0, LogicalBlockSize, (byte)BlocksToRead, timeout, out _);
out _);
if(dev.Error) BlocksToRead /= 2; if(dev.Error) BlocksToRead /= 2;
} }
@@ -486,14 +471,14 @@ namespace DiscImageChef.Core.Devices
else else
{ {
if(read16) if(read16)
sense = dev.Read16(out buffer, out senseBuf, 0, false, true, false, block, LogicalBlockSize, 0, count, sense = dev.Read16(out buffer, out senseBuf, 0, false, true, false, block, LogicalBlockSize, 0,
false, timeout, out duration); count, false, timeout, out duration);
else if(read12) else if(read12)
sense = dev.Read12(out buffer, out senseBuf, 0, false, false, false, false, (uint)block, LogicalBlockSize, sense = dev.Read12(out buffer, out senseBuf, 0, false, false, false, false, (uint)block,
0, count, false, timeout, out duration); LogicalBlockSize, 0, count, false, timeout, out duration);
else if(read10) else if(read10)
sense = dev.Read10(out buffer, out senseBuf, 0, false, true, false, false, (uint)block, LogicalBlockSize, sense = dev.Read10(out buffer, out senseBuf, 0, false, true, false, false, (uint)block,
0, (ushort)count, timeout, out duration); LogicalBlockSize, 0, (ushort)count, timeout, out duration);
else if(read6) else if(read6)
sense = dev.Read6(out buffer, out senseBuf, (uint)block, LogicalBlockSize, (byte)count, timeout, sense = dev.Read6(out buffer, out senseBuf, (uint)block, LogicalBlockSize, (byte)count, timeout,
out duration); out duration);
@@ -502,8 +487,7 @@ namespace DiscImageChef.Core.Devices
if(!sense && !dev.Error) return false; if(!sense && !dev.Error) return false;
DicConsole.DebugWriteLine("SCSI Reader", "READ error:\n{0}", DicConsole.DebugWriteLine("SCSI Reader", "READ error:\n{0}", Sense.PrettifySense(senseBuf));
Sense.PrettifySense(senseBuf));
return sense; return sense;
} }

View File

@@ -40,12 +40,12 @@ using DiscImageChef.Metadata;
namespace DiscImageChef.Core.Devices.Report namespace DiscImageChef.Core.Devices.Report
{ {
/// <summary> /// <summary>
/// Implements creating a report for an ATA device /// Implements creating a report for an ATA device
/// </summary> /// </summary>
public static class Ata public static class Ata
{ {
/// <summary> /// <summary>
/// Creates a report of an ATA device /// Creates a report of an ATA device
/// </summary> /// </summary>
/// <param name="dev">Device</param> /// <param name="dev">Device</param>
/// <param name="report">Device report</param> /// <param name="report">Device report</param>
@@ -81,8 +81,7 @@ namespace DiscImageChef.Core.Devices.Report
report.CompactFlashSpecified = true; report.CompactFlashSpecified = true;
removable = false; removable = false;
} }
else if(!removable && else if(!removable && ataId.GeneralConfiguration.HasFlag(Identify.GeneralConfigurationBit.Removable))
ataId.GeneralConfiguration.HasFlag(Identify.GeneralConfigurationBit.Removable))
{ {
pressedKey = new ConsoleKeyInfo(); pressedKey = new ConsoleKeyInfo();
while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
@@ -558,8 +557,7 @@ namespace DiscImageChef.Core.Devices.Report
mediaTest.BlocksSpecified = true; mediaTest.BlocksSpecified = true;
} }
if(ataId.CurrentCylinders > 0 && ataId.CurrentHeads > 0 && if(ataId.CurrentCylinders > 0 && ataId.CurrentHeads > 0 && ataId.CurrentSectorsPerTrack > 0)
ataId.CurrentSectorsPerTrack > 0)
{ {
mediaTest.CurrentCHS = new chsType mediaTest.CurrentCHS = new chsType
{ {
@@ -569,8 +567,7 @@ namespace DiscImageChef.Core.Devices.Report
}; };
if(mediaTest.Blocks == 0) if(mediaTest.Blocks == 0)
mediaTest.Blocks = mediaTest.Blocks =
(ulong)(ataId.CurrentCylinders * ataId.CurrentHeads * (ulong)(ataId.CurrentCylinders * ataId.CurrentHeads * ataId.CurrentSectorsPerTrack);
ataId.CurrentSectorsPerTrack);
mediaTest.BlocksSpecified = true; mediaTest.BlocksSpecified = true;
} }
@@ -606,8 +603,7 @@ namespace DiscImageChef.Core.Devices.Report
uint logicalsectorsize; uint logicalsectorsize;
uint physicalsectorsize; uint physicalsectorsize;
if((ataId.PhysLogSectorSize & 0x8000) == 0x0000 && if((ataId.PhysLogSectorSize & 0x8000) == 0x0000 && (ataId.PhysLogSectorSize & 0x4000) == 0x4000)
(ataId.PhysLogSectorSize & 0x4000) == 0x4000)
{ {
if((ataId.PhysLogSectorSize & 0x1000) == 0x1000) if((ataId.PhysLogSectorSize & 0x1000) == 0x1000)
if(ataId.LogicalSectorWords <= 255 || ataId.LogicalAlignment == 0xFFFF) if(ataId.LogicalSectorWords <= 255 || ataId.LogicalAlignment == 0xFFFF)
@@ -616,10 +612,7 @@ namespace DiscImageChef.Core.Devices.Report
else logicalsectorsize = 512; else logicalsectorsize = 512;
if((ataId.PhysLogSectorSize & 0x2000) == 0x2000) if((ataId.PhysLogSectorSize & 0x2000) == 0x2000)
{ physicalsectorsize = (uint)(logicalsectorsize * ((1 << ataId.PhysLogSectorSize) & 0xF));
physicalsectorsize =
(uint)(logicalsectorsize * ((1 << ataId.PhysLogSectorSize) & 0xF));
}
else physicalsectorsize = logicalsectorsize; else physicalsectorsize = logicalsectorsize;
} }
else else
@@ -692,207 +685,179 @@ namespace DiscImageChef.Core.Devices.Report
bool sense; bool sense;
DicConsole.WriteLine("Trying READ SECTOR(S) in CHS mode..."); DicConsole.WriteLine("Trying READ SECTOR(S) in CHS mode...");
sense = dev.Read(out byte[] readBuf, out AtaErrorRegistersChs errorChs, false, 0, 0, 1, 1, TIMEOUT, out _); sense = dev.Read(out byte[] readBuf, out AtaErrorRegistersChs errorChs, false, 0, 0, 1, 1,
mediaTest.SupportsRead = TIMEOUT, out _);
!sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && mediaTest.SupportsRead = !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 &&
readBuf.Length > 0; readBuf.Length > 0;
DicConsole.DebugWriteLine("ATA Report", DicConsole.DebugWriteLine("ATA Report",
"Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}",
sense, errorChs.Status, errorChs.Error, readBuf.Length); sense, errorChs.Status, errorChs.Error, readBuf.Length);
if(debug) if(debug)
DataFile.WriteTo("ATA Report", "readsectorschs", DataFile.WriteTo("ATA Report", "readsectorschs",
"_debug_" + mediaTest.MediumTypeName + ".bin", "read results", "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", readBuf);
readBuf);
DicConsole.WriteLine("Trying READ SECTOR(S) RETRY in CHS mode..."); DicConsole.WriteLine("Trying READ SECTOR(S) RETRY in CHS mode...");
sense = dev.Read(out readBuf, out errorChs, true, 0, 0, 1, 1, TIMEOUT, out _); sense = dev.Read(out readBuf, out errorChs, true, 0, 0, 1, 1, TIMEOUT, out _);
mediaTest.SupportsReadRetry = mediaTest.SupportsReadRetry = !sense && (errorChs.Status & 0x01) != 0x01 &&
!sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && errorChs.Error == 0 && readBuf.Length > 0;
readBuf.Length > 0;
DicConsole.DebugWriteLine("ATA Report", DicConsole.DebugWriteLine("ATA Report",
"Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}",
sense, errorChs.Status, errorChs.Error, readBuf.Length); sense, errorChs.Status, errorChs.Error, readBuf.Length);
if(debug) if(debug)
DataFile.WriteTo("ATA Report", "readsectorsretrychs", DataFile.WriteTo("ATA Report", "readsectorsretrychs",
"_debug_" + mediaTest.MediumTypeName + ".bin", "read results", "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", readBuf);
readBuf);
DicConsole.WriteLine("Trying READ DMA in CHS mode..."); DicConsole.WriteLine("Trying READ DMA in CHS mode...");
sense = dev.ReadDma(out readBuf, out errorChs, false, 0, 0, 1, 1, TIMEOUT, sense = dev.ReadDma(out readBuf, out errorChs, false, 0, 0, 1, 1, TIMEOUT, out _);
out _); mediaTest.SupportsReadDma = !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 &&
mediaTest.SupportsReadDma = readBuf.Length > 0;
!sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 &&
readBuf.Length > 0;
DicConsole.DebugWriteLine("ATA Report", DicConsole.DebugWriteLine("ATA Report",
"Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}",
sense, errorChs.Status, errorChs.Error, readBuf.Length); sense, errorChs.Status, errorChs.Error, readBuf.Length);
if(debug) if(debug)
DataFile.WriteTo("ATA Report", "readdmachs", DataFile.WriteTo("ATA Report", "readdmachs", "_debug_" + mediaTest.MediumTypeName + ".bin",
"_debug_" + mediaTest.MediumTypeName + ".bin", "read results", "read results", readBuf);
readBuf);
DicConsole.WriteLine("Trying READ DMA RETRY in CHS mode..."); DicConsole.WriteLine("Trying READ DMA RETRY in CHS mode...");
sense = dev.ReadDma(out readBuf, out errorChs, true, 0, 0, 1, 1, TIMEOUT, out _); sense = dev.ReadDma(out readBuf, out errorChs, true, 0, 0, 1, 1, TIMEOUT, out _);
mediaTest.SupportsReadDmaRetry = mediaTest.SupportsReadDmaRetry = !sense && (errorChs.Status & 0x01) != 0x01 &&
!sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && errorChs.Error == 0 && readBuf.Length > 0;
readBuf.Length > 0;
DicConsole.DebugWriteLine("ATA Report", DicConsole.DebugWriteLine("ATA Report",
"Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}",
sense, errorChs.Status, errorChs.Error, readBuf.Length); sense, errorChs.Status, errorChs.Error, readBuf.Length);
if(debug) if(debug)
DataFile.WriteTo("ATA Report", "readdmaretrychs", DataFile.WriteTo("ATA Report", "readdmaretrychs",
"_debug_" + mediaTest.MediumTypeName + ".bin", "read results", "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", readBuf);
readBuf);
DicConsole.WriteLine("Trying SEEK in CHS mode..."); DicConsole.WriteLine("Trying SEEK in CHS mode...");
sense = dev.Seek(out errorChs, 0, 0, 1, TIMEOUT, out _); sense = dev.Seek(out errorChs, 0, 0, 1, TIMEOUT, out _);
mediaTest.SupportsSeek = mediaTest.SupportsSeek = !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0;
!sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0; DicConsole.DebugWriteLine("ATA Report", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}",
DicConsole.DebugWriteLine("ATA Report", sense, errorChs.Status, errorChs.Error);
"Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}", sense,
errorChs.Status, errorChs.Error);
DicConsole.WriteLine("Trying READ SECTOR(S) in LBA mode..."); DicConsole.WriteLine("Trying READ SECTOR(S) in LBA mode...");
sense = dev.Read(out readBuf, out AtaErrorRegistersLba28 errorLba, false, 0, 1, TIMEOUT, out _); sense = dev.Read(out readBuf, out AtaErrorRegistersLba28 errorLba, false, 0, 1, TIMEOUT, out _);
mediaTest.SupportsReadLba = mediaTest.SupportsReadLba = !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 &&
!sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && readBuf.Length > 0;
readBuf.Length > 0;
DicConsole.DebugWriteLine("ATA Report", DicConsole.DebugWriteLine("ATA Report",
"Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}",
sense, errorChs.Status, errorChs.Error, readBuf.Length); sense, errorChs.Status, errorChs.Error, readBuf.Length);
if(debug) if(debug)
DataFile.WriteTo("ATA Report", "readsectors", DataFile.WriteTo("ATA Report", "readsectors", "_debug_" + mediaTest.MediumTypeName + ".bin",
"_debug_" + mediaTest.MediumTypeName + ".bin", "read results", "read results", readBuf);
readBuf);
DicConsole.WriteLine("Trying READ SECTOR(S) RETRY in LBA mode..."); DicConsole.WriteLine("Trying READ SECTOR(S) RETRY in LBA mode...");
sense = dev.Read(out readBuf, out errorLba, true, 0, 1, TIMEOUT, out _); sense = dev.Read(out readBuf, out errorLba, true, 0, 1, TIMEOUT, out _);
mediaTest.SupportsReadRetryLba = mediaTest.SupportsReadRetryLba = !sense && (errorLba.Status & 0x01) != 0x01 &&
!sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && errorLba.Error == 0 && readBuf.Length > 0;
readBuf.Length > 0;
DicConsole.DebugWriteLine("ATA Report", DicConsole.DebugWriteLine("ATA Report",
"Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}",
sense, errorChs.Status, errorChs.Error, readBuf.Length); sense, errorChs.Status, errorChs.Error, readBuf.Length);
if(debug) if(debug)
DataFile.WriteTo("ATA Report", "readsectorsretry", DataFile.WriteTo("ATA Report", "readsectorsretry",
"_debug_" + mediaTest.MediumTypeName + ".bin", "read results", "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", readBuf);
readBuf);
DicConsole.WriteLine("Trying READ DMA in LBA mode..."); DicConsole.WriteLine("Trying READ DMA in LBA mode...");
sense = dev.ReadDma(out readBuf, out errorLba, false, 0, 1, TIMEOUT, out _); sense = dev.ReadDma(out readBuf, out errorLba, false, 0, 1, TIMEOUT, out _);
mediaTest.SupportsReadDmaLba = mediaTest.SupportsReadDmaLba = !sense && (errorLba.Status & 0x01) != 0x01 &&
!sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && errorLba.Error == 0 && readBuf.Length > 0;
readBuf.Length > 0;
DicConsole.DebugWriteLine("ATA Report", DicConsole.DebugWriteLine("ATA Report",
"Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}",
sense, errorChs.Status, errorChs.Error, readBuf.Length); sense, errorChs.Status, errorChs.Error, readBuf.Length);
if(debug) if(debug)
DataFile.WriteTo("ATA Report", "readdma", DataFile.WriteTo("ATA Report", "readdma", "_debug_" + mediaTest.MediumTypeName + ".bin",
"_debug_" + mediaTest.MediumTypeName + ".bin", "read results", "read results", readBuf);
readBuf);
DicConsole.WriteLine("Trying READ DMA RETRY in LBA mode..."); DicConsole.WriteLine("Trying READ DMA RETRY in LBA mode...");
sense = dev.ReadDma(out readBuf, out errorLba, true, 0, 1, TIMEOUT, out _); sense = dev.ReadDma(out readBuf, out errorLba, true, 0, 1, TIMEOUT, out _);
mediaTest.SupportsReadDmaRetryLba = mediaTest.SupportsReadDmaRetryLba =
!sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && readBuf.Length > 0;
readBuf.Length > 0;
DicConsole.DebugWriteLine("ATA Report", DicConsole.DebugWriteLine("ATA Report",
"Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}",
sense, errorChs.Status, errorChs.Error, readBuf.Length); sense, errorChs.Status, errorChs.Error, readBuf.Length);
if(debug) if(debug)
DataFile.WriteTo("ATA Report", "readdmaretry", DataFile.WriteTo("ATA Report", "readdmaretry",
"_debug_" + mediaTest.MediumTypeName + ".bin", "read results", "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", readBuf);
readBuf);
DicConsole.WriteLine("Trying SEEK in LBA mode..."); DicConsole.WriteLine("Trying SEEK in LBA mode...");
sense = dev.Seek(out errorLba, 0, TIMEOUT, out _); sense = dev.Seek(out errorLba, 0, TIMEOUT, out _);
mediaTest.SupportsSeekLba = mediaTest.SupportsSeekLba = !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0;
!sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0; DicConsole.DebugWriteLine("ATA Report", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}",
DicConsole.DebugWriteLine("ATA Report", sense, errorChs.Status, errorChs.Error);
"Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}", sense,
errorChs.Status, errorChs.Error);
DicConsole.WriteLine("Trying READ SECTOR(S) in LBA48 mode..."); DicConsole.WriteLine("Trying READ SECTOR(S) in LBA48 mode...");
sense = dev.Read(out readBuf, out AtaErrorRegistersLba48 errorLba48, 0, 1, TIMEOUT, out _); sense = dev.Read(out readBuf, out AtaErrorRegistersLba48 errorLba48, 0, 1, TIMEOUT, out _);
mediaTest.SupportsReadLba48 = mediaTest.SupportsReadLba48 = !sense && (errorLba48.Status & 0x01) != 0x01 &&
!sense && (errorLba48.Status & 0x01) != 0x01 && errorLba48.Error == 0 && errorLba48.Error == 0 && readBuf.Length > 0;
readBuf.Length > 0;
DicConsole.DebugWriteLine("ATA Report", DicConsole.DebugWriteLine("ATA Report",
"Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}",
sense, errorChs.Status, errorChs.Error, readBuf.Length); sense, errorChs.Status, errorChs.Error, readBuf.Length);
if(debug) if(debug)
DataFile.WriteTo("ATA Report", "readsectors48", DataFile.WriteTo("ATA Report", "readsectors48",
"_debug_" + mediaTest.MediumTypeName + ".bin", "read results", "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", readBuf);
readBuf);
DicConsole.WriteLine("Trying READ DMA in LBA48 mode..."); DicConsole.WriteLine("Trying READ DMA in LBA48 mode...");
sense = dev.ReadDma(out readBuf, out errorLba48, 0, 1, TIMEOUT, out _); sense = dev.ReadDma(out readBuf, out errorLba48, 0, 1, TIMEOUT, out _);
mediaTest.SupportsReadDmaLba48 = mediaTest.SupportsReadDmaLba48 = !sense && (errorLba48.Status & 0x01) != 0x01 &&
!sense && (errorLba48.Status & 0x01) != 0x01 && errorLba48.Error == 0 && errorLba48.Error == 0 && readBuf.Length > 0;
readBuf.Length > 0;
DicConsole.DebugWriteLine("ATA Report", DicConsole.DebugWriteLine("ATA Report",
"Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}",
sense, errorChs.Status, errorChs.Error, readBuf.Length); sense, errorChs.Status, errorChs.Error, readBuf.Length);
if(debug) if(debug)
DataFile.WriteTo("ATA Report", "readdma48", DataFile.WriteTo("ATA Report", "readdma48", "_debug_" + mediaTest.MediumTypeName + ".bin",
"_debug_" + mediaTest.MediumTypeName + ".bin", "read results", "read results", readBuf);
readBuf);
DicConsole.WriteLine("Trying READ LONG in CHS mode..."); DicConsole.WriteLine("Trying READ LONG in CHS mode...");
sense = dev.ReadLong(out readBuf, out errorChs, false, 0, 0, 1, mediaTest.LongBlockSize, sense = dev.ReadLong(out readBuf, out errorChs, false, 0, 0, 1, mediaTest.LongBlockSize,
TIMEOUT, out _); TIMEOUT, out _);
mediaTest.SupportsReadLong = mediaTest.SupportsReadLong = !sense && (errorChs.Status & 0x01) != 0x01 &&
!sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && errorChs.Error == 0 && readBuf.Length > 0 &&
readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead;
DicConsole.DebugWriteLine("ATA Report", DicConsole.DebugWriteLine("ATA Report",
"Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}",
sense, errorChs.Status, errorChs.Error, readBuf.Length); sense, errorChs.Status, errorChs.Error, readBuf.Length);
if(debug) if(debug)
DataFile.WriteTo("ATA Report", "readlongchs", DataFile.WriteTo("ATA Report", "readlongchs", "_debug_" + mediaTest.MediumTypeName + ".bin",
"_debug_" + mediaTest.MediumTypeName + ".bin", "read results", "read results", readBuf);
readBuf);
DicConsole.WriteLine("Trying READ LONG RETRY in CHS mode..."); DicConsole.WriteLine("Trying READ LONG RETRY in CHS mode...");
sense = dev.ReadLong(out readBuf, out errorChs, true, 0, 0, 1, mediaTest.LongBlockSize, sense = dev.ReadLong(out readBuf, out errorChs, true, 0, 0, 1, mediaTest.LongBlockSize, TIMEOUT,
TIMEOUT, out _); out _);
mediaTest.SupportsReadLongRetry = mediaTest.SupportsReadLongRetry =
!sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && readBuf.Length > 0 &&
readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead;
DicConsole.DebugWriteLine("ATA Report", DicConsole.DebugWriteLine("ATA Report",
"Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}",
sense, errorChs.Status, errorChs.Error, readBuf.Length); sense, errorChs.Status, errorChs.Error, readBuf.Length);
if(debug) if(debug)
DataFile.WriteTo("ATA Report", "readlongretrychs", DataFile.WriteTo("ATA Report", "readlongretrychs",
"_debug_" + mediaTest.MediumTypeName + ".bin", "read results", "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", readBuf);
readBuf);
DicConsole.WriteLine("Trying READ LONG in LBA mode..."); DicConsole.WriteLine("Trying READ LONG in LBA mode...");
sense = dev.ReadLong(out readBuf, out errorLba, false, 0, mediaTest.LongBlockSize, sense = dev.ReadLong(out readBuf, out errorLba, false, 0, mediaTest.LongBlockSize, TIMEOUT,
TIMEOUT, out _); out _);
mediaTest.SupportsReadLongLba = mediaTest.SupportsReadLongLba = !sense && (errorLba.Status & 0x01) != 0x01 &&
!sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && errorLba.Error == 0 && readBuf.Length > 0 &&
readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead;
DicConsole.DebugWriteLine("ATA Report", DicConsole.DebugWriteLine("ATA Report",
"Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}",
sense, errorChs.Status, errorChs.Error, readBuf.Length); sense, errorChs.Status, errorChs.Error, readBuf.Length);
if(debug) if(debug)
DataFile.WriteTo("ATA Report", "readlong", DataFile.WriteTo("ATA Report", "readlong", "_debug_" + mediaTest.MediumTypeName + ".bin",
"_debug_" + mediaTest.MediumTypeName + ".bin", "read results", "read results", readBuf);
readBuf);
DicConsole.WriteLine("Trying READ LONG RETRY in LBA mode..."); DicConsole.WriteLine("Trying READ LONG RETRY in LBA mode...");
sense = dev.ReadLong(out readBuf, out errorLba, true, 0, mediaTest.LongBlockSize, sense = dev.ReadLong(out readBuf, out errorLba, true, 0, mediaTest.LongBlockSize, TIMEOUT,
TIMEOUT, out _); out _);
mediaTest.SupportsReadLongRetryLba = mediaTest.SupportsReadLongRetryLba =
!sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && readBuf.Length > 0 &&
readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead;
DicConsole.DebugWriteLine("ATA Report", DicConsole.DebugWriteLine("ATA Report",
"Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}",
sense, errorChs.Status, errorChs.Error, readBuf.Length); sense, errorChs.Status, errorChs.Error, readBuf.Length);
if(debug) if(debug)
DataFile.WriteTo("ATA Report", "readlongretry", DataFile.WriteTo("ATA Report", "readlongretry",
"_debug_" + mediaTest.MediumTypeName + ".bin", "read results", "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", readBuf);
readBuf);
} }
else mediaTest.MediaIsRecognized = false; else mediaTest.MediaIsRecognized = false;
@@ -924,8 +889,7 @@ namespace DiscImageChef.Core.Devices.Report
Heads = ataId.Heads, Heads = ataId.Heads,
Sectors = ataId.SectorsPerTrack Sectors = ataId.SectorsPerTrack
}; };
report.ATA.ReadCapabilities.Blocks = report.ATA.ReadCapabilities.Blocks = (ulong)(ataId.Cylinders * ataId.Heads * ataId.SectorsPerTrack);
(ulong)(ataId.Cylinders * ataId.Heads * ataId.SectorsPerTrack);
report.ATA.ReadCapabilities.BlocksSpecified = true; report.ATA.ReadCapabilities.BlocksSpecified = true;
} }
@@ -977,16 +941,12 @@ namespace DiscImageChef.Core.Devices.Report
if((ataId.PhysLogSectorSize & 0x8000) == 0x0000 && (ataId.PhysLogSectorSize & 0x4000) == 0x4000) if((ataId.PhysLogSectorSize & 0x8000) == 0x0000 && (ataId.PhysLogSectorSize & 0x4000) == 0x4000)
{ {
if((ataId.PhysLogSectorSize & 0x1000) == 0x1000) if((ataId.PhysLogSectorSize & 0x1000) == 0x1000)
if(ataId.LogicalSectorWords <= 255 || ataId.LogicalAlignment == 0xFFFF) if(ataId.LogicalSectorWords <= 255 || ataId.LogicalAlignment == 0xFFFF) logicalsectorsize = 512;
logicalsectorsize = 512;
else logicalsectorsize = ataId.LogicalSectorWords * 2; else logicalsectorsize = ataId.LogicalSectorWords * 2;
else logicalsectorsize = 512; else logicalsectorsize = 512;
if((ataId.PhysLogSectorSize & 0x2000) == 0x2000) if((ataId.PhysLogSectorSize & 0x2000) == 0x2000)
{ physicalsectorsize = logicalsectorsize * (uint)Math.Pow(2, ataId.PhysLogSectorSize & 0xF);
physicalsectorsize = logicalsectorsize *
(uint)Math.Pow(2, ataId.PhysLogSectorSize & 0xF);
}
else physicalsectorsize = logicalsectorsize; else physicalsectorsize = logicalsectorsize;
} }
else else
@@ -1059,7 +1019,8 @@ namespace DiscImageChef.Core.Devices.Report
bool sense; bool sense;
DicConsole.WriteLine("Trying READ SECTOR(S) in CHS mode..."); DicConsole.WriteLine("Trying READ SECTOR(S) in CHS mode...");
sense = dev.Read(out byte[] readBuf, out AtaErrorRegistersChs errorChs, false, 0, 0, 1, 1, TIMEOUT, out _); sense = dev.Read(out byte[] readBuf, out AtaErrorRegistersChs errorChs, false, 0, 0, 1, 1, TIMEOUT,
out _);
report.ATA.ReadCapabilities.SupportsRead = report.ATA.ReadCapabilities.SupportsRead =
!sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && readBuf.Length > 0; !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && readBuf.Length > 0;
DicConsole.DebugWriteLine("ATA Report", DicConsole.DebugWriteLine("ATA Report",
@@ -1088,8 +1049,8 @@ namespace DiscImageChef.Core.Devices.Report
"Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense,
errorChs.Status, errorChs.Error, readBuf.Length); errorChs.Status, errorChs.Error, readBuf.Length);
if(debug) if(debug)
DataFile.WriteTo("ATA Report", "readdmachs", "_debug_" + report.ATA.Model + ".bin", DataFile.WriteTo("ATA Report", "readdmachs", "_debug_" + report.ATA.Model + ".bin", "read results",
"read results", readBuf); readBuf);
DicConsole.WriteLine("Trying READ DMA RETRY in CHS mode..."); DicConsole.WriteLine("Trying READ DMA RETRY in CHS mode...");
sense = dev.ReadDma(out readBuf, out errorChs, true, 0, 0, 1, 1, TIMEOUT, out _); sense = dev.ReadDma(out readBuf, out errorChs, true, 0, 0, 1, 1, TIMEOUT, out _);
@@ -1117,8 +1078,8 @@ namespace DiscImageChef.Core.Devices.Report
"Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense,
errorLba.Status, errorLba.Error, readBuf.Length); errorLba.Status, errorLba.Error, readBuf.Length);
if(debug) if(debug)
DataFile.WriteTo("ATA Report", "readsectors", "_debug_" + report.ATA.Model + ".bin", DataFile.WriteTo("ATA Report", "readsectors", "_debug_" + report.ATA.Model + ".bin", "read results",
"read results", readBuf); readBuf);
DicConsole.WriteLine("Trying READ SECTOR(S) RETRY in LBA mode..."); DicConsole.WriteLine("Trying READ SECTOR(S) RETRY in LBA mode...");
sense = dev.Read(out readBuf, out errorLba, true, 0, 1, TIMEOUT, out _); sense = dev.Read(out readBuf, out errorLba, true, 0, 1, TIMEOUT, out _);
@@ -1179,8 +1140,8 @@ namespace DiscImageChef.Core.Devices.Report
"Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense,
errorLba48.Status, errorLba48.Error, readBuf.Length); errorLba48.Status, errorLba48.Error, readBuf.Length);
if(debug) if(debug)
DataFile.WriteTo("ATA Report", "readdma48", "_debug_" + report.ATA.Model + ".bin", DataFile.WriteTo("ATA Report", "readdma48", "_debug_" + report.ATA.Model + ".bin", "read results",
"read results", readBuf); readBuf);
DicConsole.WriteLine("Trying READ LONG in CHS mode..."); DicConsole.WriteLine("Trying READ LONG in CHS mode...");
sense = dev.ReadLong(out readBuf, out errorChs, false, 0, 0, 1, sense = dev.ReadLong(out readBuf, out errorChs, false, 0, 0, 1,
@@ -1192,8 +1153,8 @@ namespace DiscImageChef.Core.Devices.Report
"Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense,
errorChs.Status, errorChs.Error, readBuf.Length); errorChs.Status, errorChs.Error, readBuf.Length);
if(debug) if(debug)
DataFile.WriteTo("ATA Report", "readlongchs", "_debug_" + report.ATA.Model + ".bin", DataFile.WriteTo("ATA Report", "readlongchs", "_debug_" + report.ATA.Model + ".bin", "read results",
"read results", readBuf); readBuf);
DicConsole.WriteLine("Trying READ LONG RETRY in CHS mode..."); DicConsole.WriteLine("Trying READ LONG RETRY in CHS mode...");
sense = dev.ReadLong(out readBuf, out errorChs, true, 0, 0, 1, sense = dev.ReadLong(out readBuf, out errorChs, true, 0, 0, 1,
@@ -1218,8 +1179,8 @@ namespace DiscImageChef.Core.Devices.Report
"Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense,
errorLba.Status, errorLba.Error, readBuf.Length); errorLba.Status, errorLba.Error, readBuf.Length);
if(debug) if(debug)
DataFile.WriteTo("ATA Report", "readlong", "_debug_" + report.ATA.Model + ".bin", DataFile.WriteTo("ATA Report", "readlong", "_debug_" + report.ATA.Model + ".bin", "read results",
"read results", readBuf); readBuf);
DicConsole.WriteLine("Trying READ LONG RETRY in LBA mode..."); DicConsole.WriteLine("Trying READ LONG RETRY in LBA mode...");
sense = dev.ReadLong(out readBuf, out errorLba, true, 0, report.ATA.ReadCapabilities.LongBlockSize, sense = dev.ReadLong(out readBuf, out errorLba, true, 0, report.ATA.ReadCapabilities.LongBlockSize,

View File

@@ -38,12 +38,12 @@ using DiscImageChef.Metadata;
namespace DiscImageChef.Core.Devices.Report namespace DiscImageChef.Core.Devices.Report
{ {
/// <summary> /// <summary>
/// Implements creating a report for an ATAPI device /// Implements creating a report for an ATAPI device
/// </summary> /// </summary>
static class Atapi static class Atapi
{ {
/// <summary> /// <summary>
/// Fills a SCSI device report with parameters specific to an ATAPI device /// Fills a SCSI device report with parameters specific to an ATAPI device
/// </summary> /// </summary>
/// <param name="dev">Device</param> /// <param name="dev">Device</param>
/// <param name="report">Device report</param> /// <param name="report">Device report</param>
@@ -61,7 +61,8 @@ namespace DiscImageChef.Core.Devices.Report
if(!Identify.Decode(buffer).HasValue) return; if(!Identify.Decode(buffer).HasValue) return;
Identify.IdentifyDevice? atapiIdNullable = Identify.Decode(buffer); Identify.IdentifyDevice? atapiIdNullable = Identify.Decode(buffer);
if(atapiIdNullable != null) { if(atapiIdNullable != null)
{
Identify.IdentifyDevice atapiId = atapiIdNullable.Value; Identify.IdentifyDevice atapiId = atapiIdNullable.Value;
report.ATAPI = new ataType(); report.ATAPI = new ataType();

View File

@@ -38,12 +38,12 @@ using DiscImageChef.Metadata;
namespace DiscImageChef.Core.Devices.Report namespace DiscImageChef.Core.Devices.Report
{ {
/// <summary> /// <summary>
/// Implements creating a report for a FireWire device /// Implements creating a report for a FireWire device
/// </summary> /// </summary>
static class FireWire static class FireWire
{ {
/// <summary> /// <summary>
/// Fills a device report with parameters specific to a FireWire device /// Fills a device report with parameters specific to a FireWire device
/// </summary> /// </summary>
/// <param name="dev">Device</param> /// <param name="dev">Device</param>
/// <param name="report">Device report</param> /// <param name="report">Device report</param>

View File

@@ -37,12 +37,12 @@ using DiscImageChef.Metadata;
namespace DiscImageChef.Core.Devices.Report namespace DiscImageChef.Core.Devices.Report
{ {
/// <summary> /// <summary>
/// Implements creating a report for a PCMCIA device /// Implements creating a report for a PCMCIA device
/// </summary> /// </summary>
static class Pcmcia static class Pcmcia
{ {
/// <summary> /// <summary>
/// Fills a device report with parameters specific to a PCMCIA device /// Fills a device report with parameters specific to a PCMCIA device
/// </summary> /// </summary>
/// <param name="dev">Device</param> /// <param name="dev">Device</param>
/// <param name="report">Device report</param> /// <param name="report">Device report</param>
@@ -53,7 +53,8 @@ namespace DiscImageChef.Core.Devices.Report
if(tuples == null) return; if(tuples == null) return;
foreach(Tuple tuple in tuples) foreach(Tuple tuple in tuples)
switch(tuple.Code) { switch(tuple.Code)
{
case TupleCodes.CISTPL_MANFID: case TupleCodes.CISTPL_MANFID:
ManufacturerIdentificationTuple manfid = CIS.DecodeManufacturerIdentificationTuple(tuple); ManufacturerIdentificationTuple manfid = CIS.DecodeManufacturerIdentificationTuple(tuple);

View File

@@ -43,12 +43,13 @@ using DiscImageChef.Metadata;
namespace DiscImageChef.Core.Devices.Report.SCSI namespace DiscImageChef.Core.Devices.Report.SCSI
{ {
/// <summary> /// <summary>
/// Implements creating a report of SCSI and ATAPI devices /// Implements creating a report of SCSI and ATAPI devices
/// </summary> /// </summary>
public static class General public static class General
{ {
/// <summary> /// <summary>
/// Creates a report of SCSI and ATAPI devices, and if appropiate calls the report creators for MultiMedia and Streaming devices /// Creates a report of SCSI and ATAPI devices, and if appropiate calls the report creators for MultiMedia and
/// Streaming devices
/// </summary> /// </summary>
/// <param name="dev">Device</param> /// <param name="dev">Device</param>
/// <param name="report">Device report</param> /// <param name="report">Device report</param>
@@ -150,8 +151,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
} }
report.SCSI.Inquiry.PeripheralQualifier = (PeripheralQualifiers)inq.PeripheralQualifier; report.SCSI.Inquiry.PeripheralQualifier = (PeripheralQualifiers)inq.PeripheralQualifier;
report.SCSI.Inquiry.PeripheralDeviceType = report.SCSI.Inquiry.PeripheralDeviceType = (PeripheralDeviceTypes)inq.PeripheralDeviceType;
(PeripheralDeviceTypes)inq.PeripheralDeviceType;
report.SCSI.Inquiry.AsymmetricalLUNAccess = (TGPSValues)inq.TPGS; report.SCSI.Inquiry.AsymmetricalLUNAccess = (TGPSValues)inq.TPGS;
report.SCSI.Inquiry.SPIClocking = (SPIClocking)inq.Clocking; report.SCSI.Inquiry.SPIClocking = (SPIClocking)inq.Clocking;
@@ -194,7 +194,8 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
if(evpdPages != null && evpdPages.Length > 0) if(evpdPages != null && evpdPages.Length > 0)
{ {
List<pageType> evpds = new List<pageType>(); List<pageType> evpds = new List<pageType>();
foreach(byte page in evpdPages.Where(page => page != 0x80)) { foreach(byte page in evpdPages.Where(page => page != 0x80))
{
DicConsole.WriteLine("Querying SCSI EVPD {0:X2}h...", page); DicConsole.WriteLine("Querying SCSI EVPD {0:X2}h...", page);
sense = dev.ScsiInquiry(out buffer, out senseBuffer, page); sense = dev.ScsiInquiry(out buffer, out senseBuffer, page);
if(sense) continue; if(sense) continue;
@@ -209,7 +210,8 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
if(removable) if(removable)
{ {
switch(dev.ScsiType) { switch(dev.ScsiType)
{
case PeripheralDeviceTypes.MultiMediaDevice: case PeripheralDeviceTypes.MultiMediaDevice:
dev.AllowMediumRemoval(out senseBuffer, TIMEOUT, out _); dev.AllowMediumRemoval(out senseBuffer, TIMEOUT, out _);
dev.EjectTray(out senseBuffer, TIMEOUT, out _); dev.EjectTray(out senseBuffer, TIMEOUT, out _);
@@ -266,8 +268,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
} }
else report.SCSI.SupportsModeSubpages = true; else report.SCSI.SupportsModeSubpages = true;
if(!sense && !dev.Error && !decMode.HasValue) if(!sense && !dev.Error && !decMode.HasValue) decMode = Modes.DecodeMode6(mode6Buffer, devType);
decMode = Modes.DecodeMode6(mode6Buffer, devType);
report.SCSI.SupportsModeSense6 |= !sense && !dev.Error; report.SCSI.SupportsModeSense6 |= !sense && !dev.Error;
@@ -310,17 +311,21 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
}; };
modePages.Add(modePage); modePages.Add(modePage);
if(modePage.page == 0x2A && modePage.subpage == 0x00) cdromMode = Modes.DecodeModePage_2A(page.PageResponse); if(modePage.page == 0x2A && modePage.subpage == 0x00)
cdromMode = Modes.DecodeModePage_2A(page.PageResponse);
} }
if(modePages.Count > 0) report.SCSI.ModeSense.ModePages = modePages.ToArray(); if(modePages.Count > 0) report.SCSI.ModeSense.ModePages = modePages.ToArray();
} }
} }
switch(dev.ScsiType) { switch(dev.ScsiType)
case PeripheralDeviceTypes.MultiMediaDevice: Mmc.Report(dev, ref report, debug, ref cdromMode); {
case PeripheralDeviceTypes.MultiMediaDevice:
Mmc.Report(dev, ref report, debug, ref cdromMode);
break; break;
case PeripheralDeviceTypes.SequentialAccess: Ssc.Report(dev, ref report, debug); case PeripheralDeviceTypes.SequentialAccess:
Ssc.Report(dev, ref report, debug);
break; break;
default: default:
if(removable) if(removable)
@@ -405,8 +410,8 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
{ {
mediaTest.SupportsReadCapacity = true; mediaTest.SupportsReadCapacity = true;
mediaTest.Blocks = mediaTest.Blocks =
(ulong)((buffer[0] << 24) + (buffer[1] << 16) + (buffer[2] << 8) + (ulong)((buffer[0] << 24) + (buffer[1] << 16) + (buffer[2] << 8) + buffer[3]) +
buffer[3]) + 1; 1;
mediaTest.BlockSize = mediaTest.BlockSize =
(uint)((buffer[4] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + buffer[7]); (uint)((buffer[4] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + buffer[7]);
mediaTest.BlocksSpecified = true; mediaTest.BlocksSpecified = true;
@@ -423,8 +428,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
Array.Reverse(temp); Array.Reverse(temp);
mediaTest.Blocks = BitConverter.ToUInt64(temp, 0) + 1; mediaTest.Blocks = BitConverter.ToUInt64(temp, 0) + 1;
mediaTest.BlockSize = mediaTest.BlockSize =
(uint)((buffer[8] << 24) + (buffer[9] << 16) + (buffer[10] << 8) + (uint)((buffer[8] << 24) + (buffer[9] << 16) + (buffer[10] << 8) + buffer[11]);
buffer[11]);
mediaTest.BlocksSpecified = true; mediaTest.BlocksSpecified = true;
mediaTest.BlockSizeSpecified = true; mediaTest.BlockSizeSpecified = true;
} }
@@ -433,8 +437,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
DicConsole.WriteLine("Querying SCSI MODE SENSE (10)..."); DicConsole.WriteLine("Querying SCSI MODE SENSE (10)...");
sense = dev.ModeSense10(out buffer, out senseBuffer, false, true, sense = dev.ModeSense10(out buffer, out senseBuffer, false, true,
ScsiModeSensePageControl.Current, 0x3F, 0x00, TIMEOUT, ScsiModeSensePageControl.Current, 0x3F, 0x00, TIMEOUT, out _);
out _);
if(!sense && !dev.Error) if(!sense && !dev.Error)
{ {
report.SCSI.SupportsModeSense10 = true; report.SCSI.SupportsModeSense10 = true;
@@ -447,8 +450,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
if(!sense && !dev.Error) if(!sense && !dev.Error)
{ {
report.SCSI.SupportsModeSense6 = true; report.SCSI.SupportsModeSense6 = true;
if(!decMode.HasValue) if(!decMode.HasValue) decMode = Modes.DecodeMode6(buffer, dev.ScsiType);
decMode = Modes.DecodeMode6(buffer, dev.ScsiType);
if(debug) mediaTest.ModeSense6Data = buffer; if(debug) mediaTest.ModeSense6Data = buffer;
} }
@@ -471,8 +473,8 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
mediaTest.SupportsReadLongSpecified = true; mediaTest.SupportsReadLongSpecified = true;
DicConsole.WriteLine("Trying SCSI READ (6)..."); DicConsole.WriteLine("Trying SCSI READ (6)...");
mediaTest.SupportsRead = !dev.Read6(out buffer, out senseBuffer, 0, mediaTest.BlockSize, mediaTest.SupportsRead =
TIMEOUT, out _); !dev.Read6(out buffer, out senseBuffer, 0, mediaTest.BlockSize, TIMEOUT, out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsRead); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsRead);
if(debug) if(debug)
DataFile.WriteTo("SCSI Report", "read6", DataFile.WriteTo("SCSI Report", "read6",
@@ -616,7 +618,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
if(pressedKey.Key == ConsoleKey.Y) if(pressedKey.Key == ConsoleKey.Y)
{ {
for(ushort i = (ushort)mediaTest.BlockSize; ; i++) for(ushort i = (ushort)mediaTest.BlockSize;; i++)
{ {
DicConsole.Write("\rTrying to READ LONG with a size of {0} bytes...", i); DicConsole.Write("\rTrying to READ LONG with a size of {0} bytes...", i);
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, i, sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, i,
@@ -697,8 +699,8 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
decMode = null; decMode = null;
DicConsole.WriteLine("Querying SCSI MODE SENSE (10)..."); DicConsole.WriteLine("Querying SCSI MODE SENSE (10)...");
sense = dev.ModeSense10(out buffer, out senseBuffer, false, true, ScsiModeSensePageControl.Current, sense = dev.ModeSense10(out buffer, out senseBuffer, false, true,
0x3F, 0x00, TIMEOUT, out _); ScsiModeSensePageControl.Current, 0x3F, 0x00, TIMEOUT, out _);
if(!sense && !dev.Error) if(!sense && !dev.Error)
{ {
report.SCSI.SupportsModeSense10 = true; report.SCSI.SupportsModeSense10 = true;
@@ -735,14 +737,15 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
report.SCSI.ReadCapabilities.SupportsReadLongSpecified = true; report.SCSI.ReadCapabilities.SupportsReadLongSpecified = true;
DicConsole.WriteLine("Trying SCSI READ (6)..."); DicConsole.WriteLine("Trying SCSI READ (6)...");
report.SCSI.ReadCapabilities.SupportsRead = !dev.Read6(out buffer, out senseBuffer, 0, report.SCSI.ReadCapabilities.SupportsRead =
report.SCSI.ReadCapabilities.BlockSize, !dev.Read6(out buffer, out senseBuffer, 0, report.SCSI.ReadCapabilities.BlockSize, TIMEOUT,
TIMEOUT, out _); out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !report.SCSI.ReadCapabilities.SupportsRead); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}",
!report.SCSI.ReadCapabilities.SupportsRead);
if(debug) if(debug)
DataFile.WriteTo("SCSI Report", "read6", DataFile.WriteTo("SCSI Report", "read6",
"_debug_" + report.SCSI.Inquiry.ProductIdentification + ".bin", "read results", "_debug_" + report.SCSI.Inquiry.ProductIdentification + ".bin",
buffer); "read results", buffer);
DicConsole.WriteLine("Trying SCSI READ (10)..."); DicConsole.WriteLine("Trying SCSI READ (10)...");
report.SCSI.ReadCapabilities.SupportsRead10 = report.SCSI.ReadCapabilities.SupportsRead10 =
@@ -752,8 +755,8 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
!report.SCSI.ReadCapabilities.SupportsRead10); !report.SCSI.ReadCapabilities.SupportsRead10);
if(debug) if(debug)
DataFile.WriteTo("SCSI Report", "read10", DataFile.WriteTo("SCSI Report", "read10",
"_debug_" + report.SCSI.Inquiry.ProductIdentification + ".bin", "read results", "_debug_" + report.SCSI.Inquiry.ProductIdentification + ".bin",
buffer); "read results", buffer);
DicConsole.WriteLine("Trying SCSI READ (12)..."); DicConsole.WriteLine("Trying SCSI READ (12)...");
report.SCSI.ReadCapabilities.SupportsRead12 = report.SCSI.ReadCapabilities.SupportsRead12 =
@@ -763,8 +766,8 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
!report.SCSI.ReadCapabilities.SupportsRead12); !report.SCSI.ReadCapabilities.SupportsRead12);
if(debug) if(debug)
DataFile.WriteTo("SCSI Report", "read12", DataFile.WriteTo("SCSI Report", "read12",
"_debug_" + report.SCSI.Inquiry.ProductIdentification + ".bin", "read results", "_debug_" + report.SCSI.Inquiry.ProductIdentification + ".bin",
buffer); "read results", buffer);
DicConsole.WriteLine("Trying SCSI READ (16)..."); DicConsole.WriteLine("Trying SCSI READ (16)...");
report.SCSI.ReadCapabilities.SupportsRead16 = report.SCSI.ReadCapabilities.SupportsRead16 =
@@ -774,8 +777,8 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
!report.SCSI.ReadCapabilities.SupportsRead16); !report.SCSI.ReadCapabilities.SupportsRead16);
if(debug) if(debug)
DataFile.WriteTo("SCSI Report", "read16", DataFile.WriteTo("SCSI Report", "read16",
"_debug_" + report.SCSI.Inquiry.ProductIdentification + ".bin", "read results", "_debug_" + report.SCSI.Inquiry.ProductIdentification + ".bin",
buffer); "read results", buffer);
report.SCSI.ReadCapabilities.LongBlockSize = report.SCSI.ReadCapabilities.BlockSize; report.SCSI.ReadCapabilities.LongBlockSize = report.SCSI.ReadCapabilities.BlockSize;
DicConsole.WriteLine("Trying SCSI READ LONG (10)..."); DicConsole.WriteLine("Trying SCSI READ LONG (10)...");
@@ -784,8 +787,8 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
{ {
FixedSense? decSense = Sense.DecodeFixed(senseBuffer); FixedSense? decSense = Sense.DecodeFixed(senseBuffer);
if(decSense.HasValue) if(decSense.HasValue)
if(decSense.Value.SenseKey == SenseKeys.IllegalRequest && if(decSense.Value.SenseKey == SenseKeys.IllegalRequest && decSense.Value.ASC == 0x24 &&
decSense.Value.ASC == 0x24 && decSense.Value.ASCQ == 0x00) decSense.Value.ASCQ == 0x00)
{ {
report.SCSI.ReadCapabilities.SupportsReadLong = true; report.SCSI.ReadCapabilities.SupportsReadLong = true;
if(decSense.Value.InformationValid && decSense.Value.ILI) if(decSense.Value.InformationValid && decSense.Value.ILI)
@@ -797,8 +800,8 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
} }
} }
if(report.SCSI.ReadCapabilities.SupportsReadLong && report.SCSI.ReadCapabilities.LongBlockSize == if(report.SCSI.ReadCapabilities.SupportsReadLong &&
report.SCSI.ReadCapabilities.BlockSize) report.SCSI.ReadCapabilities.LongBlockSize == report.SCSI.ReadCapabilities.BlockSize)
if(report.SCSI.ReadCapabilities.BlockSize == 512) if(report.SCSI.ReadCapabilities.BlockSize == 512)
foreach(ushort testSize in new[] foreach(ushort testSize in new[]
{ {
@@ -810,8 +813,8 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
600, 610, 630 600, 610, 630
}) })
{ {
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, testSize, TIMEOUT, sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, testSize,
out _); TIMEOUT, out _);
if(sense || dev.Error) continue; if(sense || dev.Error) continue;
report.SCSI.ReadCapabilities.SupportsReadLong = true; report.SCSI.ReadCapabilities.SupportsReadLong = true;
@@ -828,8 +831,8 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
1200 1200
}) })
{ {
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, testSize, TIMEOUT, sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, testSize,
out _); TIMEOUT, out _);
if(sense || dev.Error) continue; if(sense || dev.Error) continue;
report.SCSI.ReadCapabilities.SupportsReadLong = true; report.SCSI.ReadCapabilities.SupportsReadLong = true;
@@ -871,8 +874,8 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
} }
} }
if(report.SCSI.ReadCapabilities.SupportsReadLong && report.SCSI.ReadCapabilities.LongBlockSize == if(report.SCSI.ReadCapabilities.SupportsReadLong &&
report.SCSI.ReadCapabilities.BlockSize) report.SCSI.ReadCapabilities.LongBlockSize == report.SCSI.ReadCapabilities.BlockSize)
{ {
pressedKey = new ConsoleKeyInfo(); pressedKey = new ConsoleKeyInfo();
while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
@@ -885,7 +888,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
if(pressedKey.Key == ConsoleKey.Y) if(pressedKey.Key == ConsoleKey.Y)
{ {
for(ushort i = (ushort)report.SCSI.ReadCapabilities.BlockSize; ; i++) for(ushort i = (ushort)report.SCSI.ReadCapabilities.BlockSize;; i++)
{ {
DicConsole.Write("\rTrying to READ LONG with a size of {0} bytes...", i); DicConsole.Write("\rTrying to READ LONG with a size of {0} bytes...", i);
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, i, TIMEOUT, sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, i, TIMEOUT,
@@ -895,8 +898,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
if(debug) if(debug)
{ {
FileStream bingo = FileStream bingo =
new FileStream($"{dev.Model}_readlong.bin", new FileStream($"{dev.Model}_readlong.bin", FileMode.Create);
FileMode.Create);
bingo.Write(buffer, 0, buffer.Length); bingo.Write(buffer, 0, buffer.Length);
bingo.Close(); bingo.Close();
} }
@@ -917,8 +919,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
report.SCSI.ReadCapabilities.LongBlockSize != report.SCSI.ReadCapabilities.BlockSize) report.SCSI.ReadCapabilities.LongBlockSize != report.SCSI.ReadCapabilities.BlockSize)
{ {
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0,
(ushort)report.SCSI.ReadCapabilities.LongBlockSize, TIMEOUT, (ushort)report.SCSI.ReadCapabilities.LongBlockSize, TIMEOUT, out _);
out _);
if(!sense) if(!sense)
DataFile.WriteTo("SCSI Report", "readlong10", DataFile.WriteTo("SCSI Report", "readlong10",
"_debug_" + report.SCSI.Inquiry.ProductIdentification + ".bin", "_debug_" + report.SCSI.Inquiry.ProductIdentification + ".bin",

View File

@@ -44,12 +44,12 @@ using DiscImageChef.Metadata;
namespace DiscImageChef.Core.Devices.Report.SCSI namespace DiscImageChef.Core.Devices.Report.SCSI
{ {
/// <summary> /// <summary>
/// Implements creating a report for a SCSI MultiMedia device /// Implements creating a report for a SCSI MultiMedia device
/// </summary> /// </summary>
static class Mmc static class Mmc
{ {
/// <summary> /// <summary>
/// Fills a SCSI device report with parameters and media tests specific to a MultiMedia device /// Fills a SCSI device report with parameters and media tests specific to a MultiMedia device
/// </summary> /// </summary>
/// <param name="dev">Device</param> /// <param name="dev">Device</param>
/// <param name="report">Device report</param> /// <param name="report">Device report</param>
@@ -181,8 +181,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
{ {
case 0x0001: case 0x0001:
{ {
Feature_0001? ftr0001 = Feature_0001? ftr0001 = Features.Decode_0001(desc.Data);
Features.Decode_0001(desc.Data);
if(ftr0001.HasValue) if(ftr0001.HasValue)
{ {
report.SCSI.MultiMediaDevice.Features.PhysicalInterfaceStandard = report.SCSI.MultiMediaDevice.Features.PhysicalInterfaceStandard =
@@ -203,8 +202,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
break; break;
case 0x0003: case 0x0003:
{ {
Feature_0003? ftr0003 = Feature_0003? ftr0003 = Features.Decode_0003(desc.Data);
Features.Decode_0003(desc.Data);
if(ftr0003.HasValue) if(ftr0003.HasValue)
{ {
report.SCSI.MultiMediaDevice.Features.LoadingMechanismType = report.SCSI.MultiMediaDevice.Features.LoadingMechanismType =
@@ -220,8 +218,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
break; break;
case 0x0004: case 0x0004:
{ {
Feature_0004? ftr0004 = Feature_0004? ftr0004 = Features.Decode_0004(desc.Data);
Features.Decode_0004(desc.Data);
if(ftr0004.HasValue) if(ftr0004.HasValue)
{ {
report.SCSI.MultiMediaDevice.Features.SupportsWriteProtectPAC = ftr0004.Value.DWP; report.SCSI.MultiMediaDevice.Features.SupportsWriteProtectPAC = ftr0004.Value.DWP;
@@ -233,8 +230,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
break; break;
case 0x0010: case 0x0010:
{ {
Feature_0010? ftr0010 = Feature_0010? ftr0010 = Features.Decode_0010(desc.Data);
Features.Decode_0010(desc.Data);
if(ftr0010.HasValue) if(ftr0010.HasValue)
{ {
if(ftr0010.Value.LogicalBlockSize > 0) if(ftr0010.Value.LogicalBlockSize > 0)
@@ -259,8 +255,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
case 0x001E: case 0x001E:
{ {
report.SCSI.MultiMediaDevice.Features.CanReadCD = true; report.SCSI.MultiMediaDevice.Features.CanReadCD = true;
Feature_001E? ftr001E = Feature_001E? ftr001E = Features.Decode_001E(desc.Data);
Features.Decode_001E(desc.Data);
if(ftr001E.HasValue) if(ftr001E.HasValue)
{ {
report.SCSI.MultiMediaDevice.Features.SupportsDAP = ftr001E.Value.DAP; report.SCSI.MultiMediaDevice.Features.SupportsDAP = ftr001E.Value.DAP;
@@ -272,8 +267,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
case 0x001F: case 0x001F:
{ {
report.SCSI.MultiMediaDevice.Features.CanReadDVD = true; report.SCSI.MultiMediaDevice.Features.CanReadDVD = true;
Feature_001F? ftr001F = Feature_001F? ftr001F = Features.Decode_001F(desc.Data);
Features.Decode_001F(desc.Data);
if(ftr001F.HasValue) if(ftr001F.HasValue)
{ {
report.SCSI.MultiMediaDevice.Features.DVDMultiRead = ftr001F.Value.MULTI110; report.SCSI.MultiMediaDevice.Features.DVDMultiRead = ftr001F.Value.MULTI110;
@@ -288,8 +282,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
case 0x0023: case 0x0023:
{ {
report.SCSI.MultiMediaDevice.Features.CanFormat = true; report.SCSI.MultiMediaDevice.Features.CanFormat = true;
Feature_0023? ftr0023 = Feature_0023? ftr0023 = Features.Decode_0023(desc.Data);
Features.Decode_0023(desc.Data);
if(ftr0023.HasValue) if(ftr0023.HasValue)
{ {
report.SCSI.MultiMediaDevice.Features.CanFormatBDREWithoutSpare = report.SCSI.MultiMediaDevice.Features.CanFormatBDREWithoutSpare =
@@ -311,8 +304,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
case 0x0028: case 0x0028:
{ {
report.SCSI.MultiMediaDevice.Features.CanReadCDMRW = true; report.SCSI.MultiMediaDevice.Features.CanReadCDMRW = true;
Feature_0028? ftr0028 = Feature_0028? ftr0028 = Features.Decode_0028(desc.Data);
Features.Decode_0028(desc.Data);
if(ftr0028.HasValue) if(ftr0028.HasValue)
{ {
report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusMRW = ftr0028.Value.DVDPRead; report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusMRW = ftr0028.Value.DVDPRead;
@@ -324,24 +316,23 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
case 0x002A: case 0x002A:
{ {
report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusRW = true; report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusRW = true;
Feature_002A? ftr002A = Feature_002A? ftr002A = Features.Decode_002A(desc.Data);
Features.Decode_002A(desc.Data); if(ftr002A.HasValue)
if(ftr002A.HasValue) report.SCSI.MultiMediaDevice.Features.CanWriteDVDPlusRW = ftr002A.Value.Write; report.SCSI.MultiMediaDevice.Features.CanWriteDVDPlusRW = ftr002A.Value.Write;
} }
break; break;
case 0x002B: case 0x002B:
{ {
report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusR = true; report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusR = true;
Feature_002B? ftr002B = Feature_002B? ftr002B = Features.Decode_002B(desc.Data);
Features.Decode_002B(desc.Data); if(ftr002B.HasValue)
if(ftr002B.HasValue) report.SCSI.MultiMediaDevice.Features.CanWriteDVDPlusR = ftr002B.Value.Write; report.SCSI.MultiMediaDevice.Features.CanWriteDVDPlusR = ftr002B.Value.Write;
} }
break; break;
case 0x002D: case 0x002D:
{ {
report.SCSI.MultiMediaDevice.Features.CanWriteCDTAO = true; report.SCSI.MultiMediaDevice.Features.CanWriteCDTAO = true;
Feature_002D? ftr002D = Feature_002D? ftr002D = Features.Decode_002D(desc.Data);
Features.Decode_002D(desc.Data);
if(ftr002D.HasValue) if(ftr002D.HasValue)
{ {
report.SCSI.MultiMediaDevice.Features.BufferUnderrunFreeInTAO = ftr002D.Value.BUF; report.SCSI.MultiMediaDevice.Features.BufferUnderrunFreeInTAO = ftr002D.Value.BUF;
@@ -359,8 +350,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
case 0x002E: case 0x002E:
{ {
report.SCSI.MultiMediaDevice.Features.CanWriteCDSAO = true; report.SCSI.MultiMediaDevice.Features.CanWriteCDSAO = true;
Feature_002E? ftr002E = Feature_002E? ftr002E = Features.Decode_002E(desc.Data);
Features.Decode_002E(desc.Data);
if(ftr002E.HasValue) if(ftr002E.HasValue)
{ {
report.SCSI.MultiMediaDevice.Features.BufferUnderrunFreeInSAO = ftr002E.Value.BUF; report.SCSI.MultiMediaDevice.Features.BufferUnderrunFreeInSAO = ftr002E.Value.BUF;
@@ -375,8 +365,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
case 0x002F: case 0x002F:
{ {
report.SCSI.MultiMediaDevice.Features.CanWriteDVDR = true; report.SCSI.MultiMediaDevice.Features.CanWriteDVDR = true;
Feature_002F? ftr002F = Feature_002F? ftr002F = Features.Decode_002F(desc.Data);
Features.Decode_002F(desc.Data);
if(ftr002F.HasValue) if(ftr002F.HasValue)
{ {
report.SCSI.MultiMediaDevice.Features.BufferUnderrunFreeInDVD = ftr002F.Value.BUF; report.SCSI.MultiMediaDevice.Features.BufferUnderrunFreeInDVD = ftr002F.Value.BUF;
@@ -392,8 +381,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
case 0x0031: case 0x0031:
{ {
report.SCSI.MultiMediaDevice.Features.CanWriteDDCDR = true; report.SCSI.MultiMediaDevice.Features.CanWriteDDCDR = true;
Feature_0031? ftr0031 = Feature_0031? ftr0031 = Features.Decode_0031(desc.Data);
Features.Decode_0031(desc.Data);
if(ftr0031.HasValue) if(ftr0031.HasValue)
report.SCSI.MultiMediaDevice.Features.CanTestWriteDDCDR = ftr0031.Value.TestWrite; report.SCSI.MultiMediaDevice.Features.CanTestWriteDDCDR = ftr0031.Value.TestWrite;
} }
@@ -410,8 +398,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
case 0x003A: case 0x003A:
{ {
report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusRWDL = true; report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusRWDL = true;
Feature_003A? ftr003A = Feature_003A? ftr003A = Features.Decode_003A(desc.Data);
Features.Decode_003A(desc.Data);
if(ftr003A.HasValue) if(ftr003A.HasValue)
report.SCSI.MultiMediaDevice.Features.CanWriteDVDPlusRWDL = ftr003A.Value.Write; report.SCSI.MultiMediaDevice.Features.CanWriteDVDPlusRWDL = ftr003A.Value.Write;
} }
@@ -419,8 +406,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
case 0x003B: case 0x003B:
{ {
report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusRDL = true; report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusRDL = true;
Feature_003B? ftr003B = Feature_003B? ftr003B = Features.Decode_003B(desc.Data);
Features.Decode_003B(desc.Data);
if(ftr003B.HasValue) if(ftr003B.HasValue)
report.SCSI.MultiMediaDevice.Features.CanWriteDVDPlusRDL = ftr003B.Value.Write; report.SCSI.MultiMediaDevice.Features.CanWriteDVDPlusRDL = ftr003B.Value.Write;
} }
@@ -428,8 +414,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
case 0x0040: case 0x0040:
{ {
report.SCSI.MultiMediaDevice.Features.CanReadBD = true; report.SCSI.MultiMediaDevice.Features.CanReadBD = true;
Feature_0040? ftr0040 = Feature_0040? ftr0040 = Features.Decode_0040(desc.Data);
Features.Decode_0040(desc.Data);
if(ftr0040.HasValue) if(ftr0040.HasValue)
{ {
report.SCSI.MultiMediaDevice.Features.CanReadBluBCA = ftr0040.Value.BCA; report.SCSI.MultiMediaDevice.Features.CanReadBluBCA = ftr0040.Value.BCA;
@@ -446,8 +431,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
case 0x0041: case 0x0041:
{ {
report.SCSI.MultiMediaDevice.Features.CanWriteBD = true; report.SCSI.MultiMediaDevice.Features.CanWriteBD = true;
Feature_0041? ftr0041 = Feature_0041? ftr0041 = Features.Decode_0041(desc.Data);
Features.Decode_0041(desc.Data);
if(ftr0041.HasValue) if(ftr0041.HasValue)
{ {
report.SCSI.MultiMediaDevice.Features.CanWriteBDRE2 = ftr0041.Value.RE2; report.SCSI.MultiMediaDevice.Features.CanWriteBDRE2 = ftr0041.Value.RE2;
@@ -461,8 +445,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
case 0x0050: case 0x0050:
{ {
report.SCSI.MultiMediaDevice.Features.CanReadHDDVD = true; report.SCSI.MultiMediaDevice.Features.CanReadHDDVD = true;
Feature_0050? ftr0050 = Feature_0050? ftr0050 = Features.Decode_0050(desc.Data);
Features.Decode_0050(desc.Data);
if(ftr0050.HasValue) if(ftr0050.HasValue)
{ {
report.SCSI.MultiMediaDevice.Features.CanReadHDDVDR = ftr0050.Value.HDDVDR; report.SCSI.MultiMediaDevice.Features.CanReadHDDVDR = ftr0050.Value.HDDVDR;
@@ -473,8 +456,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
case 0x0051: case 0x0051:
{ {
// TODO: Write HD DVD-RW // TODO: Write HD DVD-RW
Feature_0051? ftr0051 = Feature_0051? ftr0051 = Features.Decode_0051(desc.Data);
Features.Decode_0051(desc.Data);
if(ftr0051.HasValue) if(ftr0051.HasValue)
{ {
report.SCSI.MultiMediaDevice.Features.CanWriteHDDVDR = ftr0051.Value.HDDVDR; report.SCSI.MultiMediaDevice.Features.CanWriteHDDVDR = ftr0051.Value.HDDVDR;
@@ -491,8 +473,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
case 0x0102: case 0x0102:
{ {
report.SCSI.MultiMediaDevice.Features.EmbeddedChanger = true; report.SCSI.MultiMediaDevice.Features.EmbeddedChanger = true;
Feature_0102? ftr0102 = Feature_0102? ftr0102 = Features.Decode_0102(desc.Data);
Features.Decode_0102(desc.Data);
if(ftr0102.HasValue) if(ftr0102.HasValue)
{ {
report.SCSI.MultiMediaDevice.Features.ChangerIsSideChangeCapable = report.SCSI.MultiMediaDevice.Features.ChangerIsSideChangeCapable =
@@ -507,8 +488,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
case 0x0103: case 0x0103:
{ {
report.SCSI.MultiMediaDevice.Features.CanPlayCDAudio = true; report.SCSI.MultiMediaDevice.Features.CanPlayCDAudio = true;
Feature_0103? ftr0103 = Feature_0103? ftr0103 = Features.Decode_0103(desc.Data);
Features.Decode_0103(desc.Data);
if(ftr0103.HasValue) if(ftr0103.HasValue)
{ {
report.SCSI.MultiMediaDevice.Features.CanAudioScan = ftr0103.Value.Scan; report.SCSI.MultiMediaDevice.Features.CanAudioScan = ftr0103.Value.Scan;
@@ -528,8 +508,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
case 0x0106: case 0x0106:
{ {
report.SCSI.MultiMediaDevice.Features.SupportsCSS = true; report.SCSI.MultiMediaDevice.Features.SupportsCSS = true;
Feature_0106? ftr0106 = Feature_0106? ftr0106 = Features.Decode_0106(desc.Data);
Features.Decode_0106(desc.Data);
if(ftr0106.HasValue) if(ftr0106.HasValue)
if(ftr0106.Value.CSSVersion > 0) if(ftr0106.Value.CSSVersion > 0)
{ {
@@ -547,8 +526,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
case 0x010B: case 0x010B:
{ {
report.SCSI.MultiMediaDevice.Features.SupportsCPRM = true; report.SCSI.MultiMediaDevice.Features.SupportsCPRM = true;
Feature_010B? ftr010B = Feature_010B? ftr010B = Features.Decode_010B(desc.Data);
Features.Decode_010B(desc.Data);
if(ftr010B.HasValue) if(ftr010B.HasValue)
if(ftr010B.Value.CPRMVersion > 0) if(ftr010B.Value.CPRMVersion > 0)
{ {
@@ -559,8 +537,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
break; break;
case 0x010C: case 0x010C:
{ {
Feature_010C? ftr010C = Feature_010C? ftr010C = Features.Decode_010C(desc.Data);
Features.Decode_010C(desc.Data);
if(ftr010C.HasValue) if(ftr010C.HasValue)
{ {
byte[] temp = new byte[4]; byte[] temp = new byte[4];
@@ -600,8 +577,10 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
report.SCSI.MultiMediaDevice.Features.FirmwareDateSpecified = true; report.SCSI.MultiMediaDevice.Features.FirmwareDateSpecified = true;
} }
#pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body #pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body
catch { // ignored catch
} {
// ignored
}
#pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body #pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body
} }
} }
@@ -609,8 +588,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
case 0x010D: case 0x010D:
{ {
report.SCSI.MultiMediaDevice.Features.SupportsAACS = true; report.SCSI.MultiMediaDevice.Features.SupportsAACS = true;
Feature_010D? ftr010D = Feature_010D? ftr010D = Features.Decode_010D(desc.Data);
Features.Decode_010D(desc.Data);
if(ftr010D.HasValue) if(ftr010D.HasValue)
{ {
report.SCSI.MultiMediaDevice.Features.CanReadDriveAACSCertificate = report.SCSI.MultiMediaDevice.Features.CanReadDriveAACSCertificate =
@@ -681,7 +659,8 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
if(!mediaTypes.Contains("CD-RW")) mediaTypes.Add("CD-RW"); if(!mediaTypes.Contains("CD-RW")) mediaTypes.Add("CD-RW");
} }
if(report.SCSI.MultiMediaDevice.Features.CanReadCDMRW) if(!mediaTypes.Contains("CD-MRW")) mediaTypes.Add("CD-MRW"); if(report.SCSI.MultiMediaDevice.Features.CanReadCDMRW)
if(!mediaTypes.Contains("CD-MRW")) mediaTypes.Add("CD-MRW");
if(report.SCSI.MultiMediaDevice.Features.CanReadDDCD) if(report.SCSI.MultiMediaDevice.Features.CanReadDDCD)
{ {
@@ -706,7 +685,8 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
if(!mediaTypes.Contains("DVD+R DL")) mediaTypes.Add("DVD+R DL"); if(!mediaTypes.Contains("DVD+R DL")) mediaTypes.Add("DVD+R DL");
} }
if(report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusMRW) if(!mediaTypes.Contains("DVD+MRW")) mediaTypes.Add("DVD+MRW"); if(report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusMRW)
if(!mediaTypes.Contains("DVD+MRW")) mediaTypes.Add("DVD+MRW");
if(report.SCSI.MultiMediaDevice.Features.CanReadHDDVD || if(report.SCSI.MultiMediaDevice.Features.CanReadHDDVD ||
report.SCSI.MultiMediaDevice.Features.CanReadHDDVDR) report.SCSI.MultiMediaDevice.Features.CanReadHDDVDR)
@@ -716,7 +696,8 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
if(!mediaTypes.Contains("HD DVD-RW")) mediaTypes.Add("HD DVD-RW"); if(!mediaTypes.Contains("HD DVD-RW")) mediaTypes.Add("HD DVD-RW");
} }
if(report.SCSI.MultiMediaDevice.Features.CanReadHDDVDRAM) if(!mediaTypes.Contains("HD DVD-RAM")) mediaTypes.Add("HD DVD-RAM"); if(report.SCSI.MultiMediaDevice.Features.CanReadHDDVDRAM)
if(!mediaTypes.Contains("HD DVD-RAM")) mediaTypes.Add("HD DVD-RAM");
} }
bool tryPlextor = false, tryHldtst = false, tryPioneer = false, tryNec = false; bool tryPlextor = false, tryHldtst = false, tryPioneer = false, tryNec = false;
@@ -893,8 +874,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
mediaType + ".bin", "read results", buffer); mediaType + ".bin", "read results", buffer);
DicConsole.WriteLine("Querying CD Full TOC..."); DicConsole.WriteLine("Querying CD Full TOC...");
mediaTest.CanReadFullTOC = mediaTest.CanReadFullTOC = !dev.ReadRawToc(out buffer, out senseBuffer, 1, TIMEOUT, out _);
!dev.ReadRawToc(out buffer, out senseBuffer, 1, TIMEOUT, out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadFullTOC); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadFullTOC);
if(debug) if(debug)
DataFile.WriteTo("SCSI Report", "readfulltoc", DataFile.WriteTo("SCSI Report", "readfulltoc",
@@ -931,8 +911,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
DicConsole.WriteLine("Querying DVD PFI..."); DicConsole.WriteLine("Querying DVD PFI...");
mediaTest.CanReadPFI = mediaTest.CanReadPFI =
!dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.Dvd, 0, 0, !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.PhysicalInformation, 0, TIMEOUT, MmcDiscStructureFormat.PhysicalInformation, 0, TIMEOUT, out _);
out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadPFI); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadPFI);
if(debug) if(debug)
DataFile.WriteTo("SCSI Report", "pfi", DataFile.WriteTo("SCSI Report", "pfi",
@@ -956,8 +935,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
DicConsole.WriteLine("Querying DVD CMI..."); DicConsole.WriteLine("Querying DVD CMI...");
mediaTest.CanReadCMI = mediaTest.CanReadCMI =
!dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.Dvd, 0, 0, !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.CopyrightInformation, 0, TIMEOUT, MmcDiscStructureFormat.CopyrightInformation, 0, TIMEOUT, out _);
out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadCMI); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadCMI);
if(debug) if(debug)
DataFile.WriteTo("SCSI Report", "cmi", DataFile.WriteTo("SCSI Report", "cmi",
@@ -965,14 +943,15 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
mediaType + ".bin", "read results", buffer); mediaType + ".bin", "read results", buffer);
} }
switch(mediaType) { switch(mediaType)
{
case "DVD-ROM": case "DVD-ROM":
case "HD DVD-ROM": case "HD DVD-ROM":
mediaTest.CanReadBCASpecified = true; mediaTest.CanReadBCASpecified = true;
DicConsole.WriteLine("Querying DVD BCA..."); DicConsole.WriteLine("Querying DVD BCA...");
mediaTest.CanReadBCA = mediaTest.CanReadBCA =
!dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.Dvd, 0, 0, !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.Dvd,
MmcDiscStructureFormat.BurstCuttingArea, 0, TIMEOUT, 0, 0, MmcDiscStructureFormat.BurstCuttingArea, 0, TIMEOUT,
out _); out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadBCA); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadBCA);
if(debug) if(debug)
@@ -982,8 +961,8 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
mediaTest.CanReadAACSSpecified = true; mediaTest.CanReadAACSSpecified = true;
DicConsole.WriteLine("Querying DVD AACS..."); DicConsole.WriteLine("Querying DVD AACS...");
mediaTest.CanReadAACS = mediaTest.CanReadAACS =
!dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.Dvd, 0, 0, !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.Dvd,
MmcDiscStructureFormat.DvdAacs, 0, TIMEOUT, out _); 0, 0, MmcDiscStructureFormat.DvdAacs, 0, TIMEOUT, out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadAACS); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadAACS);
if(debug) if(debug)
DataFile.WriteTo("SCSI Report", "aacs", DataFile.WriteTo("SCSI Report", "aacs",
@@ -994,8 +973,8 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
mediaTest.CanReadBCASpecified = true; mediaTest.CanReadBCASpecified = true;
DicConsole.WriteLine("Querying BD BCA..."); DicConsole.WriteLine("Querying BD BCA...");
mediaTest.CanReadBCA = mediaTest.CanReadBCA =
!dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.Bd, 0, 0, !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.Bd, 0,
MmcDiscStructureFormat.BdBurstCuttingArea, 0, TIMEOUT, 0, MmcDiscStructureFormat.BdBurstCuttingArea, 0, TIMEOUT,
out _); out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadBCA); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadBCA);
if(debug) if(debug)
@@ -1008,17 +987,17 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
mediaTest.CanReadDDSSpecified = true; mediaTest.CanReadDDSSpecified = true;
mediaTest.CanReadSpareAreaInformationSpecified = true; mediaTest.CanReadSpareAreaInformationSpecified = true;
mediaTest.CanReadDDS = mediaTest.CanReadDDS =
!dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.Dvd, 0, 0, !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.Dvd,
MmcDiscStructureFormat.DvdramDds, 0, TIMEOUT, out _); 0, 0, MmcDiscStructureFormat.DvdramDds, 0, TIMEOUT, out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadDDS); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadDDS);
if(debug) if(debug)
DataFile.WriteTo("SCSI Report", "dds", DataFile.WriteTo("SCSI Report", "dds",
"_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" +
mediaType + ".bin", "read results", buffer); mediaType + ".bin", "read results", buffer);
mediaTest.CanReadSpareAreaInformation = mediaTest.CanReadSpareAreaInformation =
!dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.Dvd, 0, 0, !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.Dvd,
MmcDiscStructureFormat.DvdramSpareAreaInformation, 0, TIMEOUT, 0, 0, MmcDiscStructureFormat.DvdramSpareAreaInformation, 0,
out _); TIMEOUT, out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}",
!mediaTest.CanReadSpareAreaInformation); !mediaTest.CanReadSpareAreaInformation);
if(debug) if(debug)
@@ -1060,8 +1039,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
DicConsole.WriteLine("Querying DVD PRI..."); DicConsole.WriteLine("Querying DVD PRI...");
mediaTest.CanReadPRI = mediaTest.CanReadPRI =
!dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.Dvd, 0, 0, !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.PreRecordedInfo, 0, TIMEOUT, MmcDiscStructureFormat.PreRecordedInfo, 0, TIMEOUT, out _);
out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadPRI); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadPRI);
if(debug) if(debug)
DataFile.WriteTo("SCSI Report", "pri", DataFile.WriteTo("SCSI Report", "pri",
@@ -1076,8 +1054,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
DicConsole.WriteLine("Querying DVD Media ID..."); DicConsole.WriteLine("Querying DVD Media ID...");
mediaTest.CanReadMediaID = mediaTest.CanReadMediaID =
!dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.Dvd, 0, 0, !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.DvdrMediaIdentifier, 0, TIMEOUT, MmcDiscStructureFormat.DvdrMediaIdentifier, 0, TIMEOUT, out _);
out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadMediaID); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadMediaID);
if(debug) if(debug)
DataFile.WriteTo("SCSI Report", "mediaid", DataFile.WriteTo("SCSI Report", "mediaid",
@@ -1140,8 +1117,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
DicConsole.WriteLine("Querying DVD Layer Capacity..."); DicConsole.WriteLine("Querying DVD Layer Capacity...");
mediaTest.CanReadLayerCapacity = mediaTest.CanReadLayerCapacity =
!dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.Dvd, 0, 0, !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.DvdrLayerCapacity, 0, TIMEOUT, MmcDiscStructureFormat.DvdrLayerCapacity, 0, TIMEOUT, out _);
out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadLayerCapacity); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadLayerCapacity);
if(debug) if(debug)
DataFile.WriteTo("SCSI Report", "layer", DataFile.WriteTo("SCSI Report", "layer",
@@ -1156,8 +1132,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
DicConsole.WriteLine("Querying BD Disc Information..."); DicConsole.WriteLine("Querying BD Disc Information...");
mediaTest.CanReadDiscInformation = mediaTest.CanReadDiscInformation =
!dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.Bd, 0, 0, !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.Bd, 0, 0,
MmcDiscStructureFormat.DiscInformation, 0, TIMEOUT, MmcDiscStructureFormat.DiscInformation, 0, TIMEOUT, out _);
out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadDiscInformation); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadDiscInformation);
if(debug) if(debug)
DataFile.WriteTo("SCSI Report", "di", DataFile.WriteTo("SCSI Report", "di",
@@ -1180,8 +1155,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
mediaTest.SupportsRead16Specified = true; mediaTest.SupportsRead16Specified = true;
DicConsole.WriteLine("Trying SCSI READ (6)..."); DicConsole.WriteLine("Trying SCSI READ (6)...");
mediaTest.SupportsRead = mediaTest.SupportsRead = !dev.Read6(out buffer, out senseBuffer, 0, 2048, TIMEOUT, out _);
!dev.Read6(out buffer, out senseBuffer, 0, 2048, TIMEOUT, out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsRead); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsRead);
if(debug) if(debug)
DataFile.WriteTo("SCSI Report", "read6", DataFile.WriteTo("SCSI Report", "read6",
@@ -1380,8 +1354,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
MmcSectorTypes.Cdda, false, false, false, MmcSectorTypes.Cdda, false, false, false,
MmcHeaderCodes.None, true, false, MmcHeaderCodes.None, true, false,
MmcErrorField.C2PointersAndBlock, MmcErrorField.C2PointersAndBlock,
MmcSubchannel.None, TIMEOUT, MmcSubchannel.None, TIMEOUT, out _);
out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadC2Pointers); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadC2Pointers);
if(debug) if(debug)
DataFile.WriteTo("SCSI Report", "readcdc2", DataFile.WriteTo("SCSI Report", "readcdc2",
@@ -1389,32 +1362,28 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
mediaType + ".bin", "read results", buffer); mediaType + ".bin", "read results", buffer);
DicConsole.WriteLine("Trying to read subchannels..."); DicConsole.WriteLine("Trying to read subchannels...");
mediaTest.CanReadPQSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2368, 1, mediaTest.CanReadPQSubchannel =
MmcSectorTypes.Cdda, false, false, false, !dev.ReadCd(out buffer, out senseBuffer, 0, 2368, 1, MmcSectorTypes.Cdda, false,
MmcHeaderCodes.None, true, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None,
MmcErrorField.None, MmcSubchannel.Q16, MmcSubchannel.Q16, TIMEOUT, out _);
TIMEOUT, out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadPQSubchannel); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadPQSubchannel);
if(debug) if(debug)
DataFile.WriteTo("SCSI Report", "readcdpq", DataFile.WriteTo("SCSI Report", "readcdpq",
"_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" +
mediaType + ".bin", "read results", buffer); mediaType + ".bin", "read results", buffer);
mediaTest.CanReadRWSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2448, 1, mediaTest.CanReadRWSubchannel =
MmcSectorTypes.Cdda, false, false, false, !dev.ReadCd(out buffer, out senseBuffer, 0, 2448, 1, MmcSectorTypes.Cdda, false,
MmcHeaderCodes.None, true, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None,
MmcErrorField.None, MmcSubchannel.Raw, MmcSubchannel.Raw, TIMEOUT, out _);
TIMEOUT, out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadRWSubchannel); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadRWSubchannel);
if(debug) if(debug)
DataFile.WriteTo("SCSI Report", "readcdrw", DataFile.WriteTo("SCSI Report", "readcdrw",
"_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" +
mediaType + ".bin", "read results", buffer); mediaType + ".bin", "read results", buffer);
mediaTest.CanReadCorrectedSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2448, mediaTest.CanReadCorrectedSubchannel =
1, MmcSectorTypes.Cdda, false, false, !dev.ReadCd(out buffer, out senseBuffer, 0, 2448, 1, MmcSectorTypes.Cdda, false,
false, MmcHeaderCodes.None, true, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None,
false, MmcErrorField.None, MmcSubchannel.Rw, TIMEOUT, out _);
MmcSubchannel.Rw, TIMEOUT,
out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}",
!mediaTest.CanReadCorrectedSubchannel); !mediaTest.CanReadCorrectedSubchannel);
if(debug) if(debug)
@@ -1427,8 +1396,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
1, MmcSectorTypes.Cdda, false, false, 1, MmcSectorTypes.Cdda, false, false,
false, MmcHeaderCodes.None, true, false, MmcHeaderCodes.None, true,
false, MmcErrorField.C2Pointers, false, MmcErrorField.C2Pointers,
MmcSubchannel.Q16, TIMEOUT, MmcSubchannel.Q16, TIMEOUT, out _);
out _);
if(!mediaTest.CanReadPQSubchannelWithC2) if(!mediaTest.CanReadPQSubchannelWithC2)
mediaTest.CanReadPQSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, mediaTest.CanReadPQSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0,
2664, 1, MmcSectorTypes.Cdda, 2664, 1, MmcSectorTypes.Cdda,
@@ -1448,8 +1416,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
1, MmcSectorTypes.Cdda, false, false, 1, MmcSectorTypes.Cdda, false, false,
false, MmcHeaderCodes.None, true, false, MmcHeaderCodes.None, true,
false, MmcErrorField.C2Pointers, false, MmcErrorField.C2Pointers,
MmcSubchannel.Raw, TIMEOUT, MmcSubchannel.Raw, TIMEOUT, out _);
out _);
if(!mediaTest.CanReadRWSubchannelWithC2) if(!mediaTest.CanReadRWSubchannelWithC2)
mediaTest.CanReadRWSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, mediaTest.CanReadRWSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0,
2714, 1, MmcSectorTypes.Cdda, 2714, 1, MmcSectorTypes.Cdda,
@@ -1465,20 +1432,15 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
"_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" +
mediaType + ".bin", "read results", buffer); mediaType + ".bin", "read results", buffer);
mediaTest.CanReadCorrectedSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, mediaTest.CanReadCorrectedSubchannelWithC2 =
2712, 1, MmcSectorTypes.Cdda, !dev.ReadCd(out buffer, out senseBuffer, 0, 2712, 1, MmcSectorTypes.Cdda, false,
false, false, false, false, false, MmcHeaderCodes.None, true, false,
MmcHeaderCodes.None, true, MmcErrorField.C2Pointers, MmcSubchannel.Rw, TIMEOUT, out _);
false,
MmcErrorField.C2Pointers,
MmcSubchannel.Rw, TIMEOUT,
out _);
if(!mediaTest.CanReadCorrectedSubchannelWithC2) if(!mediaTest.CanReadCorrectedSubchannelWithC2)
mediaTest.CanReadCorrectedSubchannelWithC2 = mediaTest.CanReadCorrectedSubchannelWithC2 =
!dev.ReadCd(out buffer, out senseBuffer, 0, 2714, 1, MmcSectorTypes.Cdda, false, !dev.ReadCd(out buffer, out senseBuffer, 0, 2714, 1, MmcSectorTypes.Cdda, false,
false, false, MmcHeaderCodes.None, true, false, false, false, MmcHeaderCodes.None, true, false,
MmcErrorField.C2PointersAndBlock, MmcSubchannel.Rw, TIMEOUT, MmcErrorField.C2PointersAndBlock, MmcSubchannel.Rw, TIMEOUT, out _);
out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}",
!mediaTest.CanReadCorrectedSubchannelWithC2); !mediaTest.CanReadCorrectedSubchannelWithC2);
if(debug) if(debug)
@@ -1499,8 +1461,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
MmcSectorTypes.AllTypes, false, false, MmcSectorTypes.AllTypes, false, false,
true, MmcHeaderCodes.AllHeaders, true, true, MmcHeaderCodes.AllHeaders, true,
true, MmcErrorField.C2PointersAndBlock, true, MmcErrorField.C2PointersAndBlock,
MmcSubchannel.None, TIMEOUT, MmcSubchannel.None, TIMEOUT, out _);
out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadC2Pointers); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadC2Pointers);
if(debug) if(debug)
DataFile.WriteTo("SCSI Report", "readcdc2", DataFile.WriteTo("SCSI Report", "readcdc2",
@@ -1533,8 +1494,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
false, true, false, true,
MmcHeaderCodes.AllHeaders, true, MmcHeaderCodes.AllHeaders, true,
true, MmcErrorField.None, true, MmcErrorField.None,
MmcSubchannel.Rw, TIMEOUT, MmcSubchannel.Rw, TIMEOUT, out _);
out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}",
!mediaTest.CanReadCorrectedSubchannel); !mediaTest.CanReadCorrectedSubchannel);
if(debug) if(debug)
@@ -1548,8 +1508,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
false, true, false, true,
MmcHeaderCodes.AllHeaders, true, true, MmcHeaderCodes.AllHeaders, true, true,
MmcErrorField.C2Pointers, MmcErrorField.C2Pointers,
MmcSubchannel.Q16, TIMEOUT, MmcSubchannel.Q16, TIMEOUT, out _);
out _);
if(!mediaTest.CanReadPQSubchannelWithC2) if(!mediaTest.CanReadPQSubchannelWithC2)
mediaTest.CanReadPQSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, mediaTest.CanReadPQSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0,
2664, 1, MmcSectorTypes.AllTypes, 2664, 1, MmcSectorTypes.AllTypes,
@@ -1571,8 +1530,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
false, true, false, true,
MmcHeaderCodes.AllHeaders, true, true, MmcHeaderCodes.AllHeaders, true, true,
MmcErrorField.C2Pointers, MmcErrorField.C2Pointers,
MmcSubchannel.Raw, TIMEOUT, MmcSubchannel.Raw, TIMEOUT, out _);
out _);
if(!mediaTest.CanReadRWSubchannelWithC2) if(!mediaTest.CanReadRWSubchannelWithC2)
mediaTest.CanReadRWSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, mediaTest.CanReadRWSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0,
2714, 1, MmcSectorTypes.AllTypes, 2714, 1, MmcSectorTypes.AllTypes,
@@ -1602,8 +1560,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
mediaTest.CanReadCorrectedSubchannelWithC2 = mediaTest.CanReadCorrectedSubchannelWithC2 =
!dev.ReadCd(out buffer, out senseBuffer, 0, 2714, 1, MmcSectorTypes.AllTypes, !dev.ReadCd(out buffer, out senseBuffer, 0, 2714, 1, MmcSectorTypes.AllTypes,
false, false, true, MmcHeaderCodes.AllHeaders, true, true, false, false, true, MmcHeaderCodes.AllHeaders, true, true,
MmcErrorField.C2PointersAndBlock, MmcSubchannel.Rw, TIMEOUT, MmcErrorField.C2PointersAndBlock, MmcSubchannel.Rw, TIMEOUT, out _);
out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}",
!mediaTest.CanReadCorrectedSubchannelWithC2); !mediaTest.CanReadCorrectedSubchannelWithC2);
if(debug) if(debug)
@@ -1624,8 +1581,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
MmcSectorTypes.AllTypes, false, false, MmcSectorTypes.AllTypes, false, false,
false, MmcHeaderCodes.None, true, false, false, MmcHeaderCodes.None, true, false,
MmcErrorField.C2PointersAndBlock, MmcErrorField.C2PointersAndBlock,
MmcSubchannel.None, TIMEOUT, MmcSubchannel.None, TIMEOUT, out _);
out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadC2Pointers); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadC2Pointers);
if(debug) if(debug)
DataFile.WriteTo("SCSI Report", "readcdc2", DataFile.WriteTo("SCSI Report", "readcdc2",
@@ -1657,8 +1613,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
1, MmcSectorTypes.AllTypes, false, 1, MmcSectorTypes.AllTypes, false,
false, false, MmcHeaderCodes.None, false, false, MmcHeaderCodes.None,
true, false, MmcErrorField.None, true, false, MmcErrorField.None,
MmcSubchannel.Rw, TIMEOUT, MmcSubchannel.Rw, TIMEOUT, out _);
out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}",
!mediaTest.CanReadCorrectedSubchannel); !mediaTest.CanReadCorrectedSubchannel);
if(debug) if(debug)
@@ -1671,8 +1626,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
1, MmcSectorTypes.AllTypes, false, 1, MmcSectorTypes.AllTypes, false,
false, false, MmcHeaderCodes.None, false, false, MmcHeaderCodes.None,
true, false, MmcErrorField.C2Pointers, true, false, MmcErrorField.C2Pointers,
MmcSubchannel.Q16, TIMEOUT, MmcSubchannel.Q16, TIMEOUT, out _);
out _);
if(!mediaTest.CanReadPQSubchannelWithC2) if(!mediaTest.CanReadPQSubchannelWithC2)
mediaTest.CanReadPQSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, mediaTest.CanReadPQSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0,
2360, 1, MmcSectorTypes.AllTypes, 2360, 1, MmcSectorTypes.AllTypes,
@@ -1692,8 +1646,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
1, MmcSectorTypes.AllTypes, false, 1, MmcSectorTypes.AllTypes, false,
false, false, MmcHeaderCodes.None, false, false, MmcHeaderCodes.None,
true, false, MmcErrorField.C2Pointers, true, false, MmcErrorField.C2Pointers,
MmcSubchannel.Raw, TIMEOUT, MmcSubchannel.Raw, TIMEOUT, out _);
out _);
if(!mediaTest.CanReadRWSubchannelWithC2) if(!mediaTest.CanReadRWSubchannelWithC2)
mediaTest.CanReadRWSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, mediaTest.CanReadRWSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0,
2440, 1, MmcSectorTypes.AllTypes, 2440, 1, MmcSectorTypes.AllTypes,
@@ -1709,21 +1662,15 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
"_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" +
mediaType + ".bin", "read results", buffer); mediaType + ".bin", "read results", buffer);
mediaTest.CanReadCorrectedSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, mediaTest.CanReadCorrectedSubchannelWithC2 =
2438, 1, !dev.ReadCd(out buffer, out senseBuffer, 0, 2438, 1, MmcSectorTypes.AllTypes, false,
MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false,
false, false, MmcErrorField.C2Pointers, MmcSubchannel.Rw, TIMEOUT, out _);
MmcHeaderCodes.None, true,
false,
MmcErrorField.C2Pointers,
MmcSubchannel.Rw, TIMEOUT,
out _);
if(!mediaTest.CanReadCorrectedSubchannelWithC2) if(!mediaTest.CanReadCorrectedSubchannelWithC2)
mediaTest.CanReadCorrectedSubchannelWithC2 = mediaTest.CanReadCorrectedSubchannelWithC2 =
!dev.ReadCd(out buffer, out senseBuffer, 0, 2440, 1, MmcSectorTypes.AllTypes, !dev.ReadCd(out buffer, out senseBuffer, 0, 2440, 1, MmcSectorTypes.AllTypes,
false, false, false, MmcHeaderCodes.None, true, false, false, false, false, MmcHeaderCodes.None, true, false,
MmcErrorField.C2PointersAndBlock, MmcSubchannel.Rw, TIMEOUT, MmcErrorField.C2PointersAndBlock, MmcSubchannel.Rw, TIMEOUT, out _);
out _);
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}",
!mediaTest.CanReadCorrectedSubchannelWithC2); !mediaTest.CanReadCorrectedSubchannelWithC2);
if(debug) if(debug)
@@ -1820,14 +1767,13 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
mediaTest.LongBlockSize = mediaTest.BlockSize; mediaTest.LongBlockSize = mediaTest.BlockSize;
DicConsole.WriteLine("Trying SCSI READ LONG (10)..."); DicConsole.WriteLine("Trying SCSI READ LONG (10)...");
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 0xFFFF, TIMEOUT, sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 0xFFFF, TIMEOUT, out _);
out _);
if(sense && !dev.Error) if(sense && !dev.Error)
{ {
FixedSense? decSense = Sense.DecodeFixed(senseBuffer); FixedSense? decSense = Sense.DecodeFixed(senseBuffer);
if(decSense.HasValue) if(decSense.HasValue)
if(decSense.Value.SenseKey == SenseKeys.IllegalRequest && if(decSense.Value.SenseKey == SenseKeys.IllegalRequest && decSense.Value.ASC == 0x24 &&
decSense.Value.ASC == 0x24 && decSense.Value.ASCQ == 0x00) decSense.Value.ASCQ == 0x00)
{ {
mediaTest.SupportsReadLong = true; mediaTest.SupportsReadLong = true;
if(decSense.Value.InformationValid && decSense.Value.ILI) if(decSense.Value.InformationValid && decSense.Value.ILI)
@@ -1856,8 +1802,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
if(mediaTest.SupportsReadLong && mediaTest.LongBlockSize == mediaTest.BlockSize) if(mediaTest.SupportsReadLong && mediaTest.LongBlockSize == mediaTest.BlockSize)
{ {
// DVDs // DVDs
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 37856, TIMEOUT, sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 37856, TIMEOUT, out _);
out _);
if(!sense && !dev.Error) if(!sense && !dev.Error)
{ {
mediaTest.SupportsReadLong = true; mediaTest.SupportsReadLong = true;
@@ -1909,7 +1854,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
if(pressedKey.Key == ConsoleKey.Y) if(pressedKey.Key == ConsoleKey.Y)
{ {
for(ushort i = (ushort)mediaTest.BlockSize; ; i++) for(ushort i = (ushort)mediaTest.BlockSize;; i++)
{ {
DicConsole.Write("\rTrying to READ LONG with a size of {0} bytes...", i); DicConsole.Write("\rTrying to READ LONG with a size of {0} bytes...", i);
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, i, TIMEOUT, sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, i, TIMEOUT,
@@ -1919,8 +1864,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
if(debug) if(debug)
{ {
FileStream bingo = FileStream bingo =
new FileStream($"{mediaType}_readlong.bin", new FileStream($"{mediaType}_readlong.bin", FileMode.Create);
FileMode.Create);
bingo.Write(buffer, 0, buffer.Length); bingo.Write(buffer, 0, buffer.Length);
bingo.Close(); bingo.Close();
} }

View File

@@ -42,12 +42,12 @@ using DiscImageChef.Metadata;
namespace DiscImageChef.Core.Devices.Report.SCSI namespace DiscImageChef.Core.Devices.Report.SCSI
{ {
/// <summary> /// <summary>
/// Implements creating a report for a SCSI Streaming device /// Implements creating a report for a SCSI Streaming device
/// </summary> /// </summary>
static class Ssc static class Ssc
{ {
/// <summary> /// <summary>
/// Fills a SCSI device report with parameters and media tests specific to a Streaming device /// Fills a SCSI device report with parameters and media tests specific to a Streaming device
/// </summary> /// </summary>
/// <param name="dev">Device</param> /// <param name="dev">Device</param>
/// <param name="report">Device report</param> /// <param name="report">Device report</param>
@@ -90,8 +90,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
sense = dev.ReportDensitySupport(out buffer, out senseBuffer, false, false, TIMEOUT, out _); sense = dev.ReportDensitySupport(out buffer, out senseBuffer, false, false, TIMEOUT, out _);
if(!sense) if(!sense)
{ {
DensitySupport.DensitySupportHeader? dsh = DensitySupport.DensitySupportHeader? dsh = DensitySupport.DecodeDensity(buffer);
DensitySupport.DecodeDensity(buffer);
if(dsh.HasValue) if(dsh.HasValue)
{ {
report.SCSI.SequentialDevice.SupportedDensities = report.SCSI.SequentialDevice.SupportedDensities =
@@ -124,8 +123,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
sense = dev.ReportDensitySupport(out buffer, out senseBuffer, true, false, TIMEOUT, out _); sense = dev.ReportDensitySupport(out buffer, out senseBuffer, true, false, TIMEOUT, out _);
if(!sense) if(!sense)
{ {
DensitySupport.MediaTypeSupportHeader? mtsh = DensitySupport.MediaTypeSupportHeader? mtsh = DensitySupport.DecodeMediumType(buffer);
DensitySupport.DecodeMediumType(buffer);
if(mtsh.HasValue) if(mtsh.HasValue)
{ {
report.SCSI.SequentialDevice.SupportedMediaTypes = report.SCSI.SequentialDevice.SupportedMediaTypes =
@@ -225,8 +223,8 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
Modes.DecodedMode? decMode = null; Modes.DecodedMode? decMode = null;
DicConsole.WriteLine("Querying SCSI MODE SENSE (10)..."); DicConsole.WriteLine("Querying SCSI MODE SENSE (10)...");
sense = dev.ModeSense10(out buffer, out senseBuffer, false, true, sense = dev.ModeSense10(out buffer, out senseBuffer, false, true, ScsiModeSensePageControl.Current,
ScsiModeSensePageControl.Current, 0x3F, 0x00, TIMEOUT, out _); 0x3F, 0x00, TIMEOUT, out _);
if(!sense && !dev.Error) if(!sense && !dev.Error)
{ {
report.SCSI.SupportsModeSense10 = true; report.SCSI.SupportsModeSense10 = true;
@@ -260,8 +258,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
sense = dev.ReportDensitySupport(out buffer, out senseBuffer, false, true, TIMEOUT, out _); sense = dev.ReportDensitySupport(out buffer, out senseBuffer, false, true, TIMEOUT, out _);
if(!sense) if(!sense)
{ {
DensitySupport.DensitySupportHeader? dsh = DensitySupport.DensitySupportHeader? dsh = DensitySupport.DecodeDensity(buffer);
DensitySupport.DecodeDensity(buffer);
if(dsh.HasValue) if(dsh.HasValue)
{ {
seqTest.SupportedDensities = new SupportedDensity[dsh.Value.descriptors.Length]; seqTest.SupportedDensities = new SupportedDensity[dsh.Value.descriptors.Length];
@@ -287,8 +284,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
sense = dev.ReportDensitySupport(out buffer, out senseBuffer, true, true, TIMEOUT, out _); sense = dev.ReportDensitySupport(out buffer, out senseBuffer, true, true, TIMEOUT, out _);
if(!sense) if(!sense)
{ {
DensitySupport.MediaTypeSupportHeader? mtsh = DensitySupport.MediaTypeSupportHeader? mtsh = DensitySupport.DecodeMediumType(buffer);
DensitySupport.DecodeMediumType(buffer);
if(mtsh.HasValue) if(mtsh.HasValue)
{ {
seqTest.SupportedMediaTypes = new SupportedMedia[mtsh.Value.descriptors.Length]; seqTest.SupportedMediaTypes = new SupportedMedia[mtsh.Value.descriptors.Length];
@@ -313,8 +309,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
seqTest.CanReadMediaSerialSpecified = true; seqTest.CanReadMediaSerialSpecified = true;
DicConsole.WriteLine("Trying SCSI READ MEDIA SERIAL NUMBER..."); DicConsole.WriteLine("Trying SCSI READ MEDIA SERIAL NUMBER...");
seqTest.CanReadMediaSerial = seqTest.CanReadMediaSerial = !dev.ReadMediaSerialNumber(out buffer, out senseBuffer, TIMEOUT, out _);
!dev.ReadMediaSerialNumber(out buffer, out senseBuffer, TIMEOUT, out _);
seqTests.Add(seqTest); seqTests.Add(seqTest);
} }

View File

@@ -37,12 +37,12 @@ using DiscImageChef.Metadata;
namespace DiscImageChef.Core.Devices.Report namespace DiscImageChef.Core.Devices.Report
{ {
/// <summary> /// <summary>
/// Implements creating a device report for a SecureDigital or MultiMediaCard flash card /// Implements creating a device report for a SecureDigital or MultiMediaCard flash card
/// </summary> /// </summary>
public static class SecureDigital public static class SecureDigital
{ {
/// <summary> /// <summary>
/// Creates a device report for a SecureDigital or MultiMediaCard flash card /// Creates a device report for a SecureDigital or MultiMediaCard flash card
/// </summary> /// </summary>
/// <param name="dev">Device</param> /// <param name="dev">Device</param>
/// <param name="report">Device report</param> /// <param name="report">Device report</param>
@@ -50,10 +50,13 @@ namespace DiscImageChef.Core.Devices.Report
{ {
if(report == null) return; if(report == null) return;
switch(dev.Type) { switch(dev.Type)
case DeviceType.MMC: report.MultiMediaCard = new mmcsdType(); {
case DeviceType.MMC:
report.MultiMediaCard = new mmcsdType();
break; break;
case DeviceType.SecureDigital: report.SecureDigital = new mmcsdType(); case DeviceType.SecureDigital:
report.SecureDigital = new mmcsdType();
break; break;
} }
@@ -64,7 +67,8 @@ namespace DiscImageChef.Core.Devices.Report
{ {
DicConsole.WriteLine("CID obtained correctly..."); DicConsole.WriteLine("CID obtained correctly...");
switch(dev.Type) { switch(dev.Type)
{
case DeviceType.SecureDigital: case DeviceType.SecureDigital:
// Clear serial number and manufacturing date // Clear serial number and manufacturing date
cid[9] = 0; cid[9] = 0;
@@ -95,16 +99,20 @@ namespace DiscImageChef.Core.Devices.Report
{ {
DicConsole.WriteLine("CSD obtained correctly..."); DicConsole.WriteLine("CSD obtained correctly...");
switch(dev.Type) { switch(dev.Type)
case DeviceType.MMC: report.MultiMediaCard.CSD = csd; {
case DeviceType.MMC:
report.MultiMediaCard.CSD = csd;
break; break;
case DeviceType.SecureDigital: report.SecureDigital.CSD = csd; case DeviceType.SecureDigital:
report.SecureDigital.CSD = csd;
break; break;
} }
} }
else DicConsole.WriteLine("Could not read CSD..."); else DicConsole.WriteLine("Could not read CSD...");
switch(dev.Type) { switch(dev.Type)
{
case DeviceType.MMC: case DeviceType.MMC:
{ {
DicConsole.WriteLine("Trying to get OCR..."); DicConsole.WriteLine("Trying to get OCR...");

View File

@@ -38,12 +38,12 @@ using DiscImageChef.Metadata;
namespace DiscImageChef.Core.Devices.Report namespace DiscImageChef.Core.Devices.Report
{ {
/// <summary> /// <summary>
/// Implements creating a report for a USB device /// Implements creating a report for a USB device
/// </summary> /// </summary>
static class Usb static class Usb
{ {
/// <summary> /// <summary>
/// Fills a device report with parameters specific to a USB device /// Fills a device report with parameters specific to a USB device
/// </summary> /// </summary>
/// <param name="dev">Device</param> /// <param name="dev">Device</param>
/// <param name="report">Device report</param> /// <param name="report">Device report</param>

View File

@@ -40,12 +40,12 @@ using DiscImageChef.Devices;
namespace DiscImageChef.Core.Devices.Scanning namespace DiscImageChef.Core.Devices.Scanning
{ {
/// <summary> /// <summary>
/// Implements scanning the media from an ATA device /// Implements scanning the media from an ATA device
/// </summary> /// </summary>
public static class Ata public static class Ata
{ {
/// <summary> /// <summary>
/// Scans the media from an ATA device /// Scans the media from an ATA device
/// </summary> /// </summary>
/// <param name="mhddLogPath">Path to a MHDD log file</param> /// <param name="mhddLogPath">Path to a MHDD log file</param>
/// <param name="ibgLogPath">Path to a IMGBurn log file</param> /// <param name="ibgLogPath">Path to a IMGBurn log file</param>
@@ -176,8 +176,8 @@ namespace DiscImageChef.Core.Devices.Scanning
DicConsole.WriteLine(); DicConsole.WriteLine();
mhddLog.Close(); mhddLog.Close();
ibgLog.Close(dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024, ibgLog.Close(dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
blockSize * (double)(results.Blocks + 1) / 1024 / blockSize * (double)(results.Blocks + 1) / 1024 / (results.ProcessingTime / 1000),
(results.ProcessingTime / 1000), devicePath); devicePath);
if(ataReader.CanSeekLba) if(ataReader.CanSeekLba)
for(int i = 0; i < SEEK_TIMES; i++) for(int i = 0; i < SEEK_TIMES; i++)
@@ -260,8 +260,8 @@ namespace DiscImageChef.Core.Devices.Scanning
DicConsole.WriteLine(); DicConsole.WriteLine();
mhddLog.Close(); mhddLog.Close();
ibgLog.Close(dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024, ibgLog.Close(dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
blockSize * (double)(results.Blocks + 1) / 1024 / blockSize * (double)(results.Blocks + 1) / 1024 / (results.ProcessingTime / 1000),
(results.ProcessingTime / 1000), devicePath); devicePath);
if(ataReader.CanSeek) if(ataReader.CanSeek)
for(int i = 0; i < SEEK_TIMES; i++) for(int i = 0; i < SEEK_TIMES; i++)
@@ -291,8 +291,7 @@ namespace DiscImageChef.Core.Devices.Scanning
results.ProcessingTime /= 1000; results.ProcessingTime /= 1000;
results.TotalTime = (end - start).TotalSeconds; results.TotalTime = (end - start).TotalSeconds;
results.AvgSpeed = blockSize * (double)(results.Blocks + 1) / 1048576 / results.AvgSpeed = blockSize * (double)(results.Blocks + 1) / 1048576 / results.ProcessingTime;
results.ProcessingTime;
results.SeekTimes = SEEK_TIMES; results.SeekTimes = SEEK_TIMES;
return results; return results;

View File

@@ -43,7 +43,7 @@ using DiscImageChef.Devices;
namespace DiscImageChef.Core.Devices.Scanning namespace DiscImageChef.Core.Devices.Scanning
{ {
/// <summary> /// <summary>
/// Implements scanning the media from an SCSI device /// Implements scanning the media from an SCSI device
/// </summary> /// </summary>
public static class Scsi public static class Scsi
{ {
@@ -142,7 +142,8 @@ namespace DiscImageChef.Core.Devices.Scanning
Reader scsiReader = null; Reader scsiReader = null;
switch(dev.ScsiType) { switch(dev.ScsiType)
{
case PeripheralDeviceTypes.DirectAccess: case PeripheralDeviceTypes.DirectAccess:
case PeripheralDeviceTypes.MultiMediaDevice: case PeripheralDeviceTypes.MultiMediaDevice:
case PeripheralDeviceTypes.OCRWDevice: case PeripheralDeviceTypes.OCRWDevice:
@@ -183,8 +184,8 @@ namespace DiscImageChef.Core.Devices.Scanning
if(dev.ScsiType == PeripheralDeviceTypes.MultiMediaDevice) if(dev.ScsiType == PeripheralDeviceTypes.MultiMediaDevice)
{ {
sense = dev.GetConfiguration(out byte[] cmdBuf, out senseBuf, 0, MmcGetConfigurationRt.Current, dev.Timeout, sense = dev.GetConfiguration(out byte[] cmdBuf, out senseBuf, 0, MmcGetConfigurationRt.Current,
out _); dev.Timeout, out _);
if(!sense) if(!sense)
{ {
Features.SeparatedFeatures ftr = Features.Separate(cmdBuf); Features.SeparatedFeatures ftr = Features.Separate(cmdBuf);
@@ -246,9 +247,9 @@ namespace DiscImageChef.Core.Devices.Scanning
return results; return results;
} }
bool readcd = !dev.ReadCd(out _, out senseBuf, 0, 2352, 1, MmcSectorTypes.AllTypes, false, false, bool readcd = !dev.ReadCd(out _, out senseBuf, 0, 2352, 1, MmcSectorTypes.AllTypes, false, false, true,
true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.None,
MmcSubchannel.None, dev.Timeout, out _); dev.Timeout, out _);
if(readcd) DicConsole.WriteLine("Using MMC READ CD command."); if(readcd) DicConsole.WriteLine("Using MMC READ CD command.");
@@ -258,9 +259,9 @@ namespace DiscImageChef.Core.Devices.Scanning
{ {
if(readcd) if(readcd)
{ {
sense = dev.ReadCd(out _, out senseBuf, 0, 2352, blocksToRead, MmcSectorTypes.AllTypes, sense = dev.ReadCd(out _, out senseBuf, 0, 2352, blocksToRead, MmcSectorTypes.AllTypes, false,
false, false, true, MmcHeaderCodes.AllHeaders, true, true, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None,
MmcErrorField.None, MmcSubchannel.None, dev.Timeout, out _); MmcSubchannel.None, dev.Timeout, out _);
if(dev.Error) blocksToRead /= 2; if(dev.Error) blocksToRead /= 2;
} }
@@ -295,9 +296,9 @@ namespace DiscImageChef.Core.Devices.Scanning
if(readcd) if(readcd)
{ {
sense = dev.ReadCd(out _, out senseBuf, (uint)i, 2352, blocksToRead, sense = dev.ReadCd(out _, out senseBuf, (uint)i, 2352, blocksToRead, MmcSectorTypes.AllTypes,
MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, false, false, true, MmcHeaderCodes.AllHeaders, true, true,
true, MmcErrorField.None, MmcSubchannel.None, dev.Timeout, out cmdDuration); MmcErrorField.None, MmcSubchannel.None, dev.Timeout, out cmdDuration);
results.ProcessingTime += cmdDuration; results.ProcessingTime += cmdDuration;
} }
@@ -315,8 +316,7 @@ namespace DiscImageChef.Core.Devices.Scanning
} }
else else
{ {
DicConsole.DebugWriteLine("Media-Scan", "READ CD error:\n{0}", DicConsole.DebugWriteLine("Media-Scan", "READ CD error:\n{0}", Sense.PrettifySense(senseBuf));
Sense.PrettifySense(senseBuf));
FixedSense? senseDecoded = Sense.DecodeFixed(senseBuf); FixedSense? senseDecoded = Sense.DecodeFixed(senseBuf);
if(senseDecoded.HasValue) if(senseDecoded.HasValue)
@@ -355,8 +355,8 @@ namespace DiscImageChef.Core.Devices.Scanning
DicConsole.WriteLine(); DicConsole.WriteLine();
mhddLog.Close(); mhddLog.Close();
ibgLog.Close(dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024, ibgLog.Close(dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
blockSize * (double)(results.Blocks + 1) / 1024 / blockSize * (double)(results.Blocks + 1) / 1024 / (results.ProcessingTime / 1000),
(results.ProcessingTime / 1000), devicePath); devicePath);
} }
else else
{ {
@@ -413,8 +413,8 @@ namespace DiscImageChef.Core.Devices.Scanning
DicConsole.WriteLine(); DicConsole.WriteLine();
mhddLog.Close(); mhddLog.Close();
ibgLog.Close(dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024, ibgLog.Close(dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
blockSize * (double)(results.Blocks + 1) / 1024 / blockSize * (double)(results.Blocks + 1) / 1024 / (results.ProcessingTime / 1000),
(results.ProcessingTime / 1000), devicePath); devicePath);
} }
results.SeekMax = double.MinValue; results.SeekMax = double.MinValue;

View File

@@ -35,80 +35,80 @@ using System.Collections.Generic;
namespace DiscImageChef.Core.Devices.Scanning namespace DiscImageChef.Core.Devices.Scanning
{ {
/// <summary> /// <summary>
/// Contains the results of a media scan /// Contains the results of a media scan
/// </summary> /// </summary>
public struct ScanResults public struct ScanResults
{ {
/// <summary> /// <summary>
/// Total time spent scanning /// Total time spent scanning
/// </summary> /// </summary>
public double TotalTime; public double TotalTime;
/// <summary> /// <summary>
/// Total time spent by the device processing commands /// Total time spent by the device processing commands
/// </summary> /// </summary>
public double ProcessingTime; public double ProcessingTime;
/// <summary> /// <summary>
/// Average scan speed /// Average scan speed
/// </summary> /// </summary>
public double AvgSpeed; public double AvgSpeed;
/// <summary> /// <summary>
/// Maximum scan speed burst /// Maximum scan speed burst
/// </summary> /// </summary>
public double MaxSpeed; public double MaxSpeed;
/// <summary> /// <summary>
/// Minimum scan speed /// Minimum scan speed
/// </summary> /// </summary>
public double MinSpeed; public double MinSpeed;
/// <summary> /// <summary>
/// Sectors that took less than 3 milliseconds to be processed /// Sectors that took less than 3 milliseconds to be processed
/// </summary> /// </summary>
public ulong A; public ulong A;
/// <summary> /// <summary>
/// Sectors that took less than 10 milliseconds but more than 3 milliseconds to be processed /// Sectors that took less than 10 milliseconds but more than 3 milliseconds to be processed
/// </summary> /// </summary>
public ulong B; public ulong B;
/// <summary> /// <summary>
/// Sectors that took less than 50 milliseconds but more than 10 milliseconds to be processed /// Sectors that took less than 50 milliseconds but more than 10 milliseconds to be processed
/// </summary> /// </summary>
public ulong C; public ulong C;
/// <summary> /// <summary>
/// Sectors that took less than 150 milliseconds but more than 50 milliseconds to be processed /// Sectors that took less than 150 milliseconds but more than 50 milliseconds to be processed
/// </summary> /// </summary>
public ulong D; public ulong D;
/// <summary> /// <summary>
/// Sectors that took less than 500 milliseconds but more than 150 milliseconds to be processed /// Sectors that took less than 500 milliseconds but more than 150 milliseconds to be processed
/// </summary> /// </summary>
public ulong E; public ulong E;
/// <summary> /// <summary>
/// Sectors that took more than 500 milliseconds to be processed /// Sectors that took more than 500 milliseconds to be processed
/// </summary> /// </summary>
public ulong F; public ulong F;
/// <summary> /// <summary>
/// List of sectors that could not be read /// List of sectors that could not be read
/// </summary> /// </summary>
public List<ulong> UnreadableSectors; public List<ulong> UnreadableSectors;
/// <summary> /// <summary>
/// Slowest seek /// Slowest seek
/// </summary> /// </summary>
public double SeekMax; public double SeekMax;
/// <summary> /// <summary>
/// Fastest seek /// Fastest seek
/// </summary> /// </summary>
public double SeekMin; public double SeekMin;
/// <summary> /// <summary>
/// Total time spent seeking /// Total time spent seeking
/// </summary> /// </summary>
public double SeekTotal; public double SeekTotal;
/// <summary> /// <summary>
/// How many seeks have been done /// How many seeks have been done
/// </summary> /// </summary>
public int SeekTimes; public int SeekTimes;
/// <summary> /// <summary>
/// How many blocks were scanned /// How many blocks were scanned
/// </summary> /// </summary>
public ulong Blocks; public ulong Blocks;
/// <summary> /// <summary>
/// How many blocks could not be read /// How many blocks could not be read
/// </summary> /// </summary>
public ulong Errored; public ulong Errored;
} }

View File

@@ -40,7 +40,7 @@ using DiscImageChef.Devices;
namespace DiscImageChef.Core.Devices.Scanning namespace DiscImageChef.Core.Devices.Scanning
{ {
/// <summary> /// <summary>
/// Implements scanning a SecureDigital or MultiMediaCard flash card /// Implements scanning a SecureDigital or MultiMediaCard flash card
/// </summary> /// </summary>
public static class SecureDigital public static class SecureDigital
{ {
@@ -58,7 +58,8 @@ namespace DiscImageChef.Core.Devices.Scanning
uint blockSize = 512; uint blockSize = 512;
bool byteAddressed = true; bool byteAddressed = true;
switch(dev.Type) { switch(dev.Type)
{
case DeviceType.MMC: case DeviceType.MMC:
{ {
sense = dev.ReadExtendedCsd(out cmdBuf, out _, TIMEOUT, out _); sense = dev.ReadExtendedCsd(out cmdBuf, out _, TIMEOUT, out _);
@@ -109,8 +110,7 @@ namespace DiscImageChef.Core.Devices.Scanning
while(true) while(true)
{ {
sense = dev.Read(out cmdBuf, out _, 0, blockSize, blocksToRead, byteAddressed, TIMEOUT, sense = dev.Read(out cmdBuf, out _, 0, blockSize, blocksToRead, byteAddressed, TIMEOUT, out duration);
out duration);
if(sense) blocksToRead /= 2; if(sense) blocksToRead /= 2;
@@ -166,8 +166,8 @@ namespace DiscImageChef.Core.Devices.Scanning
DicConsole.Write("\rReading sector {0} of {1} ({2:F3} MiB/sec.)", i, results.Blocks, currentSpeed); DicConsole.Write("\rReading sector {0} of {1} ({2:F3} MiB/sec.)", i, results.Blocks, currentSpeed);
bool error = dev.Read(out cmdBuf, out _, (uint)i, blockSize, blocksToRead, byteAddressed, bool error = dev.Read(out cmdBuf, out _, (uint)i, blockSize, blocksToRead, byteAddressed, TIMEOUT,
TIMEOUT, out duration); out duration);
if(!error) if(!error)
{ {
@@ -199,8 +199,7 @@ namespace DiscImageChef.Core.Devices.Scanning
DicConsole.WriteLine(); DicConsole.WriteLine();
mhddLog.Close(); mhddLog.Close();
ibgLog.Close(dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024, ibgLog.Close(dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
blockSize * (double)(results.Blocks + 1) / 1024 / (results.ProcessingTime / 1000), blockSize * (double)(results.Blocks + 1) / 1024 / (results.ProcessingTime / 1000), devicePath);
devicePath);
for(int i = 0; i < SEEK_TIMES; i++) for(int i = 0; i < SEEK_TIMES; i++)
{ {

View File

@@ -40,7 +40,8 @@ namespace DiscImageChef.Core
public static class Filesystems public static class Filesystems
{ {
/// <summary> /// <summary>
/// Traverses all known filesystems and outputs a list of all that recognized what is in the specified image and partition /// Traverses all known filesystems and outputs a list of all that recognized what is in the specified image and
/// partition
/// </summary> /// </summary>
/// <param name="imagePlugin">Media image</param> /// <param name="imagePlugin">Media image</param>
/// <param name="idPlugins">List of plugins recognizing the filesystem</param> /// <param name="idPlugins">List of plugins recognizing the filesystem</param>
@@ -50,7 +51,9 @@ namespace DiscImageChef.Core
PluginBase plugins = new PluginBase(); PluginBase plugins = new PluginBase();
plugins.RegisterAllPlugins(); plugins.RegisterAllPlugins();
idPlugins = (from plugin in plugins.PluginsList.Values where plugin.Identify(imagePlugin, partition) select plugin.Name.ToLower()).ToList(); idPlugins = (from plugin in plugins.PluginsList.Values
where plugin.Identify(imagePlugin, partition)
select plugin.Name.ToLower()).ToList();
} }
} }
} }

View File

@@ -41,7 +41,7 @@ namespace DiscImageChef.Core
public static class ImageFormat public static class ImageFormat
{ {
/// <summary> /// <summary>
/// Detects the image plugin that recognizes the data inside a filter /// Detects the image plugin that recognizes the data inside a filter
/// </summary> /// </summary>
/// <param name="imageFilter">Filter</param> /// <param name="imageFilter">Filter</param>
/// <returns>Detected image plugin</returns> /// <returns>Detected image plugin</returns>
@@ -55,7 +55,12 @@ namespace DiscImageChef.Core
ImagePlugin imageFormat = null; ImagePlugin imageFormat = null;
// Check all but RAW plugin // Check all but RAW plugin
foreach(ImagePlugin imageplugin in plugins.ImagePluginsList.Values.Where(imageplugin => imageplugin.PluginUuid != new Guid("12345678-AAAA-BBBB-CCCC-123456789000"))) try foreach(ImagePlugin imageplugin in plugins.ImagePluginsList.Values.Where(imageplugin =>
imageplugin.PluginUuid !=
new
Guid("12345678-AAAA-BBBB-CCCC-123456789000"))
)
try
{ {
DicConsole.DebugWriteLine("Format detection", "Trying plugin {0}", imageplugin.Name); DicConsole.DebugWriteLine("Format detection", "Trying plugin {0}", imageplugin.Name);
if(!imageplugin.IdentifyImage(imageFilter)) continue; if(!imageplugin.IdentifyImage(imageFilter)) continue;
@@ -64,23 +69,32 @@ namespace DiscImageChef.Core
break; break;
} }
#pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body #pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body
catch { // ignored catch
} {
// ignored
}
if(imageFormat != null) return imageFormat; if(imageFormat != null) return imageFormat;
// Check only RAW plugin // Check only RAW plugin
foreach(ImagePlugin imageplugin in plugins.ImagePluginsList.Values.Where(imageplugin => imageplugin.PluginUuid == new Guid("12345678-AAAA-BBBB-CCCC-123456789000"))) try foreach(ImagePlugin imageplugin in plugins.ImagePluginsList.Values.Where(imageplugin =>
{ imageplugin.PluginUuid ==
DicConsole.DebugWriteLine("Format detection", "Trying plugin {0}", imageplugin.Name); new
if(!imageplugin.IdentifyImage(imageFilter)) continue; Guid("12345678-AAAA-BBBB-CCCC-123456789000"))
)
try
{
DicConsole.DebugWriteLine("Format detection", "Trying plugin {0}", imageplugin.Name);
if(!imageplugin.IdentifyImage(imageFilter)) continue;
imageFormat = imageplugin; imageFormat = imageplugin;
break; break;
} }
#pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body #pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body
catch { // ignored catch
} {
// ignored
}
// Still not recognized // Still not recognized
return imageFormat; return imageFormat;

View File

@@ -40,14 +40,14 @@ using PlatformID = DiscImageChef.Interop.PlatformID;
namespace DiscImageChef.Core.Logging namespace DiscImageChef.Core.Logging
{ {
/// <summary> /// <summary>
/// Creates a dump log /// Creates a dump log
/// </summary> /// </summary>
public class DumpLog public class DumpLog
{ {
readonly StreamWriter logSw; readonly StreamWriter logSw;
/// <summary> /// <summary>
/// Initializes the dump log /// Initializes the dump log
/// </summary> /// </summary>
/// <param name="outputFile">Output log file</param> /// <param name="outputFile">Output log file</param>
/// <param name="dev">Device</param> /// <param name="dev">Device</param>
@@ -122,7 +122,7 @@ namespace DiscImageChef.Core.Logging
} }
/// <summary> /// <summary>
/// Adds a new line to the dump log /// Adds a new line to the dump log
/// </summary> /// </summary>
/// <param name="format">Format string</param> /// <param name="format">Format string</param>
/// <param name="args">Arguments</param> /// <param name="args">Arguments</param>
@@ -136,7 +136,7 @@ namespace DiscImageChef.Core.Logging
} }
/// <summary> /// <summary>
/// Finishes and closes the dump log /// Finishes and closes the dump log
/// </summary> /// </summary>
public void Close() public void Close()
{ {

View File

@@ -39,26 +39,26 @@ using DiscImageChef.Devices;
namespace DiscImageChef.Core.Logging namespace DiscImageChef.Core.Logging
{ {
/// <summary> /// <summary>
/// Implements a log in the format used by IMGBurn /// Implements a log in the format used by IMGBurn
/// </summary> /// </summary>
class IbgLog class IbgLog
{ {
StringBuilder ibgSb;
DateTime ibgDatePoint;
CultureInfo ibgCulture; CultureInfo ibgCulture;
double ibgStartSpeed; DateTime ibgDatePoint;
string ibgMediaType;
double ibgDivider; double ibgDivider;
bool ibgStartSet;
double ibgMaxSpeed;
double ibgIntSpeed;
int ibgSnaps;
ulong ibgIntSector; ulong ibgIntSector;
double ibgIntSpeed;
double ibgMaxSpeed;
string ibgMediaType;
int ibgSampleRate; int ibgSampleRate;
StringBuilder ibgSb;
int ibgSnaps;
bool ibgStartSet;
double ibgStartSpeed;
string logFile; string logFile;
/// <summary> /// <summary>
/// Initializes the IMGBurn log /// Initializes the IMGBurn log
/// </summary> /// </summary>
/// <param name="outputFile">Log file</param> /// <param name="outputFile">Log file</param>
/// <param name="currentProfile">Profile as defined by SCSI MultiMedia Commands specification</param> /// <param name="currentProfile">Profile as defined by SCSI MultiMedia Commands specification</param>
@@ -201,7 +201,7 @@ namespace DiscImageChef.Core.Logging
} }
/// <summary> /// <summary>
/// Adds a new speed snapshot to the log /// Adds a new speed snapshot to the log
/// </summary> /// </summary>
/// <param name="sector">Sector for the snapshot</param> /// <param name="sector">Sector for the snapshot</param>
/// <param name="currentSpeed">Current speed at the snapshot</param> /// <param name="currentSpeed">Current speed at the snapshot</param>
@@ -221,8 +221,8 @@ namespace DiscImageChef.Core.Logging
ibgStartSet = true; ibgStartSet = true;
} }
ibgSb.AppendFormat("{0:0.00},{1},{2:0},0", ibgIntSpeed / ibgSnaps / ibgDivider, ibgIntSector, ibgSb.AppendFormat("{0:0.00},{1},{2:0},0", ibgIntSpeed / ibgSnaps / ibgDivider, ibgIntSector, ibgSampleRate)
ibgSampleRate).AppendLine(); .AppendLine();
if(ibgIntSpeed / ibgSnaps / ibgDivider > ibgMaxSpeed) ibgMaxSpeed = ibgIntSpeed / ibgDivider; if(ibgIntSpeed / ibgSnaps / ibgDivider > ibgMaxSpeed) ibgMaxSpeed = ibgIntSpeed / ibgDivider;
ibgDatePoint = DateTime.Now; ibgDatePoint = DateTime.Now;
@@ -233,7 +233,7 @@ namespace DiscImageChef.Core.Logging
} }
/// <summary> /// <summary>
/// Closes the IMGBurn log /// Closes the IMGBurn log
/// </summary> /// </summary>
/// <param name="dev">Device</param> /// <param name="dev">Device</param>
/// <param name="blocks">Media blocks</param> /// <param name="blocks">Media blocks</param>
@@ -243,9 +243,10 @@ namespace DiscImageChef.Core.Logging
/// <param name="averageSpeed">Average speed</param> /// <param name="averageSpeed">Average speed</param>
/// <param name="devicePath">Device path</param> /// <param name="devicePath">Device path</param>
internal void Close(Device dev, ulong blocks, ulong blockSize, double totalSeconds, double currentSpeed, internal void Close(Device dev, ulong blocks, ulong blockSize, double totalSeconds, double currentSpeed,
double averageSpeed, string devicePath) double averageSpeed, string devicePath)
{ {
if(logFile == null) return; if(logFile == null) return;
FileStream ibgFs = new FileStream(logFile, FileMode.Create); FileStream ibgFs = new FileStream(logFile, FileMode.Create);
StringBuilder ibgHeader = new StringBuilder(); StringBuilder ibgHeader = new StringBuilder();
string ibgBusType; string ibgBusType;
@@ -288,8 +289,7 @@ namespace DiscImageChef.Core.Logging
ibgHeader.AppendLine(); ibgHeader.AppendLine();
ibgHeader.AppendFormat(ibgCulture, "VERIFY_SPEED_START={0:0.00}", ibgStartSpeed).AppendLine(); ibgHeader.AppendFormat(ibgCulture, "VERIFY_SPEED_START={0:0.00}", ibgStartSpeed).AppendLine();
ibgHeader.AppendFormat(ibgCulture, "VERIFY_SPEED_END={0:0.00}", currentSpeed / ibgDivider).AppendLine(); ibgHeader.AppendFormat(ibgCulture, "VERIFY_SPEED_END={0:0.00}", currentSpeed / ibgDivider).AppendLine();
ibgHeader.AppendFormat(ibgCulture, "VERIFY_SPEED_AVERAGE={0:0.00}", averageSpeed / ibgDivider) ibgHeader.AppendFormat(ibgCulture, "VERIFY_SPEED_AVERAGE={0:0.00}", averageSpeed / ibgDivider).AppendLine();
.AppendLine();
ibgHeader.AppendFormat(ibgCulture, "VERIFY_SPEED_MAX={0:0.00}", ibgMaxSpeed).AppendLine(); ibgHeader.AppendFormat(ibgCulture, "VERIFY_SPEED_MAX={0:0.00}", ibgMaxSpeed).AppendLine();
ibgHeader.AppendFormat(ibgCulture, "VERIFY_TIME_TAKEN={0:0}", Math.Floor(totalSeconds)).AppendLine(); ibgHeader.AppendFormat(ibgCulture, "VERIFY_TIME_TAKEN={0:0}", Math.Floor(totalSeconds)).AppendLine();
ibgHeader.AppendLine("[END_CONFIGURATION]"); ibgHeader.AppendLine("[END_CONFIGURATION]");

View File

@@ -39,15 +39,15 @@ using DiscImageChef.Devices;
namespace DiscImageChef.Core.Logging namespace DiscImageChef.Core.Logging
{ {
/// <summary> /// <summary>
/// Implements a log in the format used by MHDD /// Implements a log in the format used by MHDD
/// </summary> /// </summary>
class MhddLog class MhddLog
{ {
MemoryStream mhddFs;
string logFile; string logFile;
MemoryStream mhddFs;
/// <summary> /// <summary>
/// Initializes the MHDD log /// Initializes the MHDD log
/// </summary> /// </summary>
/// <param name="outputFile">Log file</param> /// <param name="outputFile">Log file</param>
/// <param name="dev">Device</param> /// <param name="dev">Device</param>
@@ -90,10 +90,9 @@ namespace DiscImageChef.Core.Logging
string fw = $"F/W: {dev.Revision}"; string fw = $"F/W: {dev.Revision}";
string sn = $"S/N: {dev.Serial}"; string sn = $"S/N: {dev.Serial}";
string sectors = string.Format(new CultureInfo("en-US"), "SECTORS: {0:n0}", blocks); string sectors = string.Format(new CultureInfo("en-US"), "SECTORS: {0:n0}", blocks);
string sectorsize = string.Format(new CultureInfo("en-US"), "SECTOR SIZE: {0:n0} bytes", string sectorsize = string.Format(new CultureInfo("en-US"), "SECTOR SIZE: {0:n0} bytes", blockSize);
blockSize); string scanblocksize =
string scanblocksize = string.Format(new CultureInfo("en-US"), string.Format(new CultureInfo("en-US"), "SCAN BLOCK SIZE: {0:n0} sectors", blocksToRead);
"SCAN BLOCK SIZE: {0:n0} sectors", blocksToRead);
const string MHDD_VER = "VER:2 "; const string MHDD_VER = "VER:2 ";
byte[] deviceBytes = Encoding.ASCII.GetBytes(device); byte[] deviceBytes = Encoding.ASCII.GetBytes(device);
@@ -135,7 +134,7 @@ namespace DiscImageChef.Core.Logging
} }
/// <summary> /// <summary>
/// Logs a new read /// Logs a new read
/// </summary> /// </summary>
/// <param name="sector">Starting sector</param> /// <param name="sector">Starting sector</param>
/// <param name="duration">Duration in milliseconds</param> /// <param name="duration">Duration in milliseconds</param>
@@ -151,7 +150,7 @@ namespace DiscImageChef.Core.Logging
} }
/// <summary> /// <summary>
/// Closes and writes to file the MHDD log /// Closes and writes to file the MHDD log
/// </summary> /// </summary>
internal void Close() internal void Close()
{ {

View File

@@ -40,12 +40,12 @@ using DiscImageChef.Partitions;
namespace DiscImageChef.Core namespace DiscImageChef.Core
{ {
/// <summary> /// <summary>
/// Implements methods for handling partitions /// Implements methods for handling partitions
/// </summary> /// </summary>
public static class Partitions public static class Partitions
{ {
/// <summary> /// <summary>
/// Gets a list of all partitions present in the specified image /// Gets a list of all partitions present in the specified image
/// </summary> /// </summary>
/// <param name="image">Image</param> /// <param name="image">Image</param>
/// <returns>List of found partitions</returns> /// <returns>List of found partitions</returns>
@@ -97,9 +97,10 @@ namespace DiscImageChef.Core
foreach(PartitionPlugin partitionPlugin in plugins.PartPluginsList.Values) foreach(PartitionPlugin partitionPlugin in plugins.PartPluginsList.Values)
{ {
DicConsole.DebugWriteLine("Partitions", "Trying {0} @ {1}", partitionPlugin.Name, foundPartitions[0].Start); DicConsole.DebugWriteLine("Partitions", "Trying {0} @ {1}", partitionPlugin.Name,
if(!partitionPlugin.GetInformation(image, out List<Partition> partitions, foundPartitions[0].Start)) foundPartitions[0].Start);
continue; if(!partitionPlugin.GetInformation(image, out List<Partition> partitions, foundPartitions[0].Start)
) continue;
DicConsole.DebugWriteLine("Partitions", "Found {0} @ {1}", partitionPlugin.Name, DicConsole.DebugWriteLine("Partitions", "Found {0} @ {1}", partitionPlugin.Name,
foundPartitions[0].Start); foundPartitions[0].Start);
@@ -131,9 +132,12 @@ namespace DiscImageChef.Core
// Be sure that device partitions are not excluded if not mapped by any scheme... // Be sure that device partitions are not excluded if not mapped by any scheme...
if(image.ImageInfo.ImageHasPartitions) if(image.ImageInfo.ImageHasPartitions)
{ {
List<ulong> startLocations = childPartitions.Select(detectedPartition => detectedPartition.Start).ToList(); List<ulong> startLocations =
childPartitions.Select(detectedPartition => detectedPartition.Start).ToList();
childPartitions.AddRange(image.GetPartitions().Where(imagePartition => !startLocations.Contains(imagePartition.Start))); childPartitions.AddRange(image.GetPartitions()
.Where(imagePartition =>
!startLocations.Contains(imagePartition.Start)));
} }
Partition[] childArray = childPartitions Partition[] childArray = childPartitions
@@ -145,7 +149,7 @@ namespace DiscImageChef.Core
} }
/// <summary> /// <summary>
/// Adds all partition schemes from the specified list of partitions to statistics /// Adds all partition schemes from the specified list of partitions to statistics
/// </summary> /// </summary>
/// <param name="partitions">List of partitions</param> /// <param name="partitions">List of partitions</param>
public static void AddSchemesToStats(List<Partition> partitions) public static void AddSchemesToStats(List<Partition> partitions)
@@ -154,7 +158,8 @@ namespace DiscImageChef.Core
List<string> schemes = new List<string>(); List<string> schemes = new List<string>();
foreach(Partition part in partitions.Where(part => !schemes.Contains(part.Scheme))) schemes.Add(part.Scheme); foreach(Partition part in partitions.Where(part => !schemes.Contains(part.Scheme)))
schemes.Add(part.Scheme);
foreach(string scheme in schemes) Statistics.AddPartition(scheme); foreach(string scheme in schemes) Statistics.AddPartition(scheme);
} }

View File

@@ -42,25 +42,25 @@ using DiscImageChef.Partitions;
namespace DiscImageChef.Core namespace DiscImageChef.Core
{ {
/// <summary> /// <summary>
/// Contain all plugins (filesystem, partition and image) /// Contain all plugins (filesystem, partition and image)
/// </summary> /// </summary>
public class PluginBase public class PluginBase
{ {
/// <summary> /// <summary>
/// List of all filesystem plugins /// List of all media image plugins
/// </summary> /// </summary>
public SortedDictionary<string, Filesystem> PluginsList; public SortedDictionary<string, ImagePlugin> ImagePluginsList;
/// <summary> /// <summary>
/// List of all partition plugins /// List of all partition plugins
/// </summary> /// </summary>
public SortedDictionary<string, PartitionPlugin> PartPluginsList; public SortedDictionary<string, PartitionPlugin> PartPluginsList;
/// <summary> /// <summary>
/// List of all media image plugins /// List of all filesystem plugins
/// </summary> /// </summary>
public SortedDictionary<string, ImagePlugin> ImagePluginsList; public SortedDictionary<string, Filesystem> PluginsList;
/// <summary> /// <summary>
/// Initializes the plugins lists /// Initializes the plugins lists
/// </summary> /// </summary>
public PluginBase() public PluginBase()
{ {
@@ -70,7 +70,7 @@ namespace DiscImageChef.Core
} }
/// <summary> /// <summary>
/// Fills the plugins lists /// Fills the plugins lists
/// </summary> /// </summary>
/// <param name="encoding">Which encoding to pass to plugins</param> /// <param name="encoding">Which encoding to pass to plugins</param>
public void RegisterAllPlugins(Encoding encoding = null) public void RegisterAllPlugins(Encoding encoding = null)
@@ -94,7 +94,8 @@ namespace DiscImageChef.Core
{ {
if(!type.IsSubclassOf(typeof(PartitionPlugin))) continue; if(!type.IsSubclassOf(typeof(PartitionPlugin))) continue;
PartitionPlugin plugin = (PartitionPlugin)type.GetConstructor(Type.EmptyTypes)?.Invoke(new object[] { }); PartitionPlugin plugin =
(PartitionPlugin)type.GetConstructor(Type.EmptyTypes)?.Invoke(new object[] { });
RegisterPartPlugin(plugin); RegisterPartPlugin(plugin);
} }
catch(Exception exception) { DicConsole.ErrorWriteLine("Exception {0}", exception); } catch(Exception exception) { DicConsole.ErrorWriteLine("Exception {0}", exception); }
@@ -108,7 +109,8 @@ namespace DiscImageChef.Core
Filesystem plugin; Filesystem plugin;
if(encoding != null) if(encoding != null)
plugin = (Filesystem)type.GetConstructor(new[] {encoding.GetType()})?.Invoke(new object[] {encoding}); plugin = (Filesystem)type.GetConstructor(new[] {encoding.GetType()})
?.Invoke(new object[] {encoding});
else plugin = (Filesystem)type.GetConstructor(Type.EmptyTypes)?.Invoke(new object[] { }); else plugin = (Filesystem)type.GetConstructor(Type.EmptyTypes)?.Invoke(new object[] { });
RegisterPlugin(plugin); RegisterPlugin(plugin);
} }
@@ -117,7 +119,8 @@ namespace DiscImageChef.Core
void RegisterImagePlugin(ImagePlugin plugin) void RegisterImagePlugin(ImagePlugin plugin)
{ {
if(!ImagePluginsList.ContainsKey(plugin.Name.ToLower())) ImagePluginsList.Add(plugin.Name.ToLower(), plugin); if(!ImagePluginsList.ContainsKey(plugin.Name.ToLower()))
ImagePluginsList.Add(plugin.Name.ToLower(), plugin);
} }
void RegisterPlugin(Filesystem plugin) void RegisterPlugin(Filesystem plugin)
@@ -127,7 +130,8 @@ namespace DiscImageChef.Core
void RegisterPartPlugin(PartitionPlugin partplugin) void RegisterPartPlugin(PartitionPlugin partplugin)
{ {
if(!PartPluginsList.ContainsKey(partplugin.Name.ToLower())) PartPluginsList.Add(partplugin.Name.ToLower(), partplugin); if(!PartPluginsList.ContainsKey(partplugin.Name.ToLower()))
PartPluginsList.Add(partplugin.Name.ToLower(), partplugin);
} }
} }
} }

View File

@@ -40,12 +40,12 @@ using DiscImageChef.Metadata;
namespace DiscImageChef.Core namespace DiscImageChef.Core
{ {
/// <summary> /// <summary>
/// Handles connections to DiscImageChef.Server /// Handles connections to DiscImageChef.Server
/// </summary> /// </summary>
public static class Remote public static class Remote
{ {
/// <summary> /// <summary>
/// Submits a device report /// Submits a device report
/// </summary> /// </summary>
/// <param name="report">Device report</param> /// <param name="report">Device report</param>
public static void SubmitReport(DeviceReport report) public static void SubmitReport(DeviceReport report)
@@ -61,8 +61,7 @@ namespace DiscImageChef.Core
#endif #endif
MemoryStream xmlStream = new MemoryStream(); MemoryStream xmlStream = new MemoryStream();
XmlSerializer xmlSer = XmlSerializer xmlSer = new XmlSerializer(typeof(DeviceReport));
new XmlSerializer(typeof(DeviceReport));
xmlSer.Serialize(xmlStream, report); xmlSer.Serialize(xmlStream, report);
xmlStream.Seek(0, SeekOrigin.Begin); xmlStream.Seek(0, SeekOrigin.Begin);
WebRequest request = WebRequest.Create("http://discimagechef.claunia.com/api/uploadreport"); WebRequest request = WebRequest.Create("http://discimagechef.claunia.com/api/uploadreport");

View File

@@ -42,7 +42,7 @@ namespace DiscImageChef.Core
{ {
// TODO: Complete it // TODO: Complete it
/// <summary> /// <summary>
/// Creates a metadata sidecar for an audio media (e.g. cassette) /// Creates a metadata sidecar for an audio media (e.g. cassette)
/// </summary> /// </summary>
/// <param name="image">Image</param> /// <param name="image">Image</param>
/// <param name="filterId">Filter uuid</param> /// <param name="filterId">Filter uuid</param>
@@ -51,8 +51,8 @@ namespace DiscImageChef.Core
/// <param name="plugins">Image plugins</param> /// <param name="plugins">Image plugins</param>
/// <param name="imgChecksums">List of image checksums</param> /// <param name="imgChecksums">List of image checksums</param>
/// <param name="sidecar">Metadata sidecar</param> /// <param name="sidecar">Metadata sidecar</param>
static void AudioMedia(ImagePlugin image, Guid filterId, string imagePath, FileInfo fi, static void AudioMedia(ImagePlugin image, Guid filterId, string imagePath, FileInfo fi, PluginBase plugins,
PluginBase plugins, List<ChecksumType> imgChecksums, ref CICMMetadataType sidecar) List<ChecksumType> imgChecksums, ref CICMMetadataType sidecar)
{ {
sidecar.AudioMedia = new[] sidecar.AudioMedia = new[]
{ {

View File

@@ -51,7 +51,7 @@ namespace DiscImageChef.Core
public static partial class Sidecar public static partial class Sidecar
{ {
/// <summary> /// <summary>
/// Creates a metadata sidecar for a block media (e.g. floppy, hard disk, flash card, usb stick) /// Creates a metadata sidecar for a block media (e.g. floppy, hard disk, flash card, usb stick)
/// </summary> /// </summary>
/// <param name="image">Image</param> /// <param name="image">Image</param>
/// <param name="filterId">Filter uuid</param> /// <param name="filterId">Filter uuid</param>
@@ -60,8 +60,8 @@ namespace DiscImageChef.Core
/// <param name="plugins">Image plugins</param> /// <param name="plugins">Image plugins</param>
/// <param name="imgChecksums">List of image checksums</param> /// <param name="imgChecksums">List of image checksums</param>
/// <param name="sidecar">Metadata sidecar</param> /// <param name="sidecar">Metadata sidecar</param>
static void BlockMedia(ImagePlugin image, Guid filterId, string imagePath, FileInfo fi, static void BlockMedia(ImagePlugin image, Guid filterId, string imagePath, FileInfo fi, PluginBase plugins,
PluginBase plugins, List<ChecksumType> imgChecksums, ref CICMMetadataType sidecar) List<ChecksumType> imgChecksums, ref CICMMetadataType sidecar)
{ {
sidecar.BlockMedia = new[] sidecar.BlockMedia = new[]
{ {
@@ -125,7 +125,8 @@ namespace DiscImageChef.Core
Tuple[] tuples = CIS.GetTuples(cis); Tuple[] tuples = CIS.GetTuples(cis);
if(tuples != null) if(tuples != null)
foreach(Tuple tuple in tuples) foreach(Tuple tuple in tuples)
switch(tuple.Code) { switch(tuple.Code)
{
case TupleCodes.CISTPL_MANFID: case TupleCodes.CISTPL_MANFID:
ManufacturerIdentificationTuple manfid = ManufacturerIdentificationTuple manfid =
CIS.DecodeManufacturerIdentificationTuple(tuple); CIS.DecodeManufacturerIdentificationTuple(tuple);
@@ -147,7 +148,8 @@ namespace DiscImageChef.Core
sidecar.BlockMedia[0].PCMCIA.ProductName = vers.Product; sidecar.BlockMedia[0].PCMCIA.ProductName = vers.Product;
sidecar.BlockMedia[0].PCMCIA.Compliance = sidecar.BlockMedia[0].PCMCIA.Compliance =
$"{vers.MajorVersion}.{vers.MinorVersion}"; $"{vers.MajorVersion}.{vers.MinorVersion}";
sidecar.BlockMedia[0].PCMCIA.AdditionalInformation = vers.AdditionalInformation; sidecar.BlockMedia[0].PCMCIA.AdditionalInformation =
vers.AdditionalInformation;
} }
break; break;
} }
@@ -241,7 +243,8 @@ namespace DiscImageChef.Core
// If there is only one track, and it's the same as the image file (e.g. ".iso" files), don't re-checksum. // If there is only one track, and it's the same as the image file (e.g. ".iso" files), don't re-checksum.
if(image.PluginUuid == new Guid("12345678-AAAA-BBBB-CCCC-123456789000") && if(image.PluginUuid == new Guid("12345678-AAAA-BBBB-CCCC-123456789000") &&
filterId == new Guid("12345678-AAAA-BBBB-CCCC-123456789000")) sidecar.BlockMedia[0].ContentChecksums = sidecar.BlockMedia[0].Checksums; filterId == new Guid("12345678-AAAA-BBBB-CCCC-123456789000"))
sidecar.BlockMedia[0].ContentChecksums = sidecar.BlockMedia[0].Checksums;
else else
{ {
Checksum contentChkWorker = new Checksum(); Checksum contentChkWorker = new Checksum();
@@ -382,8 +385,7 @@ namespace DiscImageChef.Core
if(image.ImageInfo.ReadableMediaTags.Contains(MediaTagType.ATA_IDENTIFY)) if(image.ImageInfo.ReadableMediaTags.Contains(MediaTagType.ATA_IDENTIFY))
{ {
Identify.IdentifyDevice? ataId = Identify.IdentifyDevice? ataId = Identify.Decode(image.ReadDiskTag(MediaTagType.ATA_IDENTIFY));
Identify.Decode(image.ReadDiskTag(MediaTagType.ATA_IDENTIFY));
if(ataId.HasValue) if(ataId.HasValue)
if(ataId.Value.CurrentCylinders > 0 && ataId.Value.CurrentHeads > 0 && if(ataId.Value.CurrentCylinders > 0 && ataId.Value.CurrentHeads > 0 &&
ataId.Value.CurrentSectorsPerTrack > 0) ataId.Value.CurrentSectorsPerTrack > 0)
@@ -541,8 +543,8 @@ namespace DiscImageChef.Core
try { scpImage.OpenImage(scpFilter); } try { scpImage.OpenImage(scpFilter); }
catch(NotImplementedException) { } catch(NotImplementedException) { }
if(image.ImageInfo.Heads == 2 && scpImage.Header.heads == 0 || if(image.ImageInfo.Heads == 2 && scpImage.Header.heads == 0 || image.ImageInfo.Heads == 1 &&
image.ImageInfo.Heads == 1 && (scpImage.Header.heads == 1 || scpImage.Header.heads == 2)) (scpImage.Header.heads == 1 || scpImage.Header.heads == 2))
if(scpImage.Header.end + 1 >= image.ImageInfo.Cylinders) if(scpImage.Header.end + 1 >= image.ImageInfo.Cylinders)
{ {
List<BlockTrackType> scpBlockTrackTypes = new List<BlockTrackType>(); List<BlockTrackType> scpBlockTrackTypes = new List<BlockTrackType>();
@@ -577,8 +579,7 @@ namespace DiscImageChef.Core
{ {
byte[] trackContents = byte[] trackContents =
new byte[scpTrack.Entries.Last().dataOffset + new byte[scpTrack.Entries.Last().dataOffset +
scpTrack.Entries.Last().trackLength - scpImage.Header.offsets[t] + scpTrack.Entries.Last().trackLength - scpImage.Header.offsets[t] + 1];
1];
scpStream.Position = scpImage.Header.offsets[t]; scpStream.Position = scpImage.Header.offsets[t];
scpStream.Read(trackContents, 0, trackContents.Length); scpStream.Read(trackContents, 0, trackContents.Length);
scpBlockTrackType.Size = trackContents.Length; scpBlockTrackType.Size = trackContents.Length;

View File

@@ -39,7 +39,7 @@ namespace DiscImageChef.Core
public static partial class Sidecar public static partial class Sidecar
{ {
/// <summary> /// <summary>
/// Creates a metadata sidecar for a block tape (e.g. scsi streaming) /// Creates a metadata sidecar for a block tape (e.g. scsi streaming)
/// </summary> /// </summary>
/// <param name="files">List of files</param> /// <param name="files">List of files</param>
/// <param name="folderName">Dump path</param> /// <param name="folderName">Dump path</param>

View File

@@ -35,7 +35,7 @@ namespace DiscImageChef.Core
public static partial class Sidecar public static partial class Sidecar
{ {
/// <summary> /// <summary>
/// Converts a LBA to MM:SS:FF string for CDs /// Converts a LBA to MM:SS:FF string for CDs
/// </summary> /// </summary>
/// <param name="lba">LBA</param> /// <param name="lba">LBA</param>
/// <returns>MM:SS:FF</returns> /// <returns>MM:SS:FF</returns>
@@ -63,7 +63,7 @@ namespace DiscImageChef.Core
} }
/// <summary> /// <summary>
/// Converts a LBA to MM:SS:FF string for DDCDs /// Converts a LBA to MM:SS:FF string for DDCDs
/// </summary> /// </summary>
/// <param name="lba">LBA</param> /// <param name="lba">LBA</param>
/// <returns>MM:SS:FF</returns> /// <returns>MM:SS:FF</returns>

View File

@@ -42,7 +42,7 @@ namespace DiscImageChef.Core
{ {
// TODO: Complete it // TODO: Complete it
/// <summary> /// <summary>
/// Creates a metadata sidecar for linear media (e.g. ROM chip) /// Creates a metadata sidecar for linear media (e.g. ROM chip)
/// </summary> /// </summary>
/// <param name="image">Image</param> /// <param name="image">Image</param>
/// <param name="filterId">Filter uuid</param> /// <param name="filterId">Filter uuid</param>
@@ -51,8 +51,8 @@ namespace DiscImageChef.Core
/// <param name="plugins">Image plugins</param> /// <param name="plugins">Image plugins</param>
/// <param name="imgChecksums">List of image checksums</param> /// <param name="imgChecksums">List of image checksums</param>
/// <param name="sidecar">Metadata sidecar</param> /// <param name="sidecar">Metadata sidecar</param>
static void LinearMedia(ImagePlugin image, Guid filterId, string imagePath, FileInfo fi, static void LinearMedia(ImagePlugin image, Guid filterId, string imagePath, FileInfo fi, PluginBase plugins,
PluginBase plugins, List<ChecksumType> imgChecksums, ref CICMMetadataType sidecar) List<ChecksumType> imgChecksums, ref CICMMetadataType sidecar)
{ {
sidecar.LinearMedia = new[] sidecar.LinearMedia = new[]
{ {

View File

@@ -48,7 +48,7 @@ namespace DiscImageChef.Core
public static partial class Sidecar public static partial class Sidecar
{ {
/// <summary> /// <summary>
/// Creates a metadata sidecar for an optical disc (e.g. CD, DVD, GD, BD, XGD, GOD) /// Creates a metadata sidecar for an optical disc (e.g. CD, DVD, GD, BD, XGD, GOD)
/// </summary> /// </summary>
/// <param name="image">Image</param> /// <param name="image">Image</param>
/// <param name="filterId">Filter uuid</param> /// <param name="filterId">Filter uuid</param>
@@ -57,8 +57,8 @@ namespace DiscImageChef.Core
/// <param name="plugins">Image plugins</param> /// <param name="plugins">Image plugins</param>
/// <param name="imgChecksums">List of image checksums</param> /// <param name="imgChecksums">List of image checksums</param>
/// <param name="sidecar">Metadata sidecar</param> /// <param name="sidecar">Metadata sidecar</param>
static void OpticalDisc(ImagePlugin image, Guid filterId, string imagePath, FileInfo fi, static void OpticalDisc(ImagePlugin image, Guid filterId, string imagePath, FileInfo fi, PluginBase plugins,
PluginBase plugins, List<ChecksumType> imgChecksums, ref CICMMetadataType sidecar) List<ChecksumType> imgChecksums, ref CICMMetadataType sidecar)
{ {
sidecar.OpticalDisc = new[] sidecar.OpticalDisc = new[]
{ {
@@ -99,8 +99,7 @@ namespace DiscImageChef.Core
Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.CD_ATIP)).ToArray(), Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.CD_ATIP)).ToArray(),
Size = image.ReadDiskTag(MediaTagType.CD_ATIP).Length Size = image.ReadDiskTag(MediaTagType.CD_ATIP).Length
}; };
ATIP.CDATIP? ATIP.CDATIP? atip = ATIP.Decode(image.ReadDiskTag(MediaTagType.CD_ATIP));
atip = ATIP.Decode(image.ReadDiskTag(MediaTagType.CD_ATIP));
if(atip.HasValue) if(atip.HasValue)
if(atip.Value.DDCD) dskType = atip.Value.DiscType ? MediaType.DDCDRW : MediaType.DDCDR; if(atip.Value.DDCD) dskType = atip.Value.DiscType ? MediaType.DDCDRW : MediaType.DDCDR;
else dskType = atip.Value.DiscType ? MediaType.CDRW : MediaType.CDR; else dskType = atip.Value.DiscType ? MediaType.CDRW : MediaType.CDR;
@@ -165,8 +164,7 @@ namespace DiscImageChef.Core
Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.DVD_PFI)).ToArray(), Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.DVD_PFI)).ToArray(),
Size = image.ReadDiskTag(MediaTagType.DVD_PFI).Length Size = image.ReadDiskTag(MediaTagType.DVD_PFI).Length
}; };
PFI.PhysicalFormatInformation? pfi = PFI.PhysicalFormatInformation? pfi = PFI.Decode(image.ReadDiskTag(MediaTagType.DVD_PFI));
PFI.Decode(image.ReadDiskTag(MediaTagType.DVD_PFI));
if(pfi.HasValue) if(pfi.HasValue)
if(dskType != MediaType.XGD && dskType != MediaType.XGD2 && dskType != MediaType.XGD3) if(dskType != MediaType.XGD && dskType != MediaType.XGD2 && dskType != MediaType.XGD3)
{ {
@@ -224,12 +222,16 @@ namespace DiscImageChef.Core
sidecar.OpticalDisc[0].Dimensions = new DimensionsType(); sidecar.OpticalDisc[0].Dimensions = new DimensionsType();
if(dskType == MediaType.UMD) sidecar.OpticalDisc[0].Dimensions.Diameter = 60; if(dskType == MediaType.UMD) sidecar.OpticalDisc[0].Dimensions.Diameter = 60;
else switch(pfi.Value.DiscSize) { else
case DVDSize.Eighty: sidecar.OpticalDisc[0].Dimensions.Diameter = 80; switch(pfi.Value.DiscSize)
break; {
case DVDSize.OneTwenty: sidecar.OpticalDisc[0].Dimensions.Diameter = 120; case DVDSize.Eighty:
break; sidecar.OpticalDisc[0].Dimensions.Diameter = 80;
} break;
case DVDSize.OneTwenty:
sidecar.OpticalDisc[0].Dimensions.Diameter = 120;
break;
}
} }
break; break;
@@ -307,9 +309,11 @@ namespace DiscImageChef.Core
xmlTrk.StartSector = (long)trk.TrackStartSector; xmlTrk.StartSector = (long)trk.TrackStartSector;
xmlTrk.EndSector = (long)trk.TrackEndSector; xmlTrk.EndSector = (long)trk.TrackEndSector;
if(trk.Indexes != null && trk.Indexes.ContainsKey(0)) if(trk.Indexes.TryGetValue(0, out ulong idx0)) xmlTrk.StartSector = (long)idx0; if(trk.Indexes != null && trk.Indexes.ContainsKey(0))
if(trk.Indexes.TryGetValue(0, out ulong idx0)) xmlTrk.StartSector = (long)idx0;
switch(sidecar.OpticalDisc[0].DiscType) { switch(sidecar.OpticalDisc[0].DiscType)
{
case "CD": case "CD":
case "GD": case "GD":
xmlTrk.StartMSF = LbaToMsf(xmlTrk.StartSector); xmlTrk.StartMSF = LbaToMsf(xmlTrk.StartSector);
@@ -341,7 +345,8 @@ namespace DiscImageChef.Core
// Only if filter is none... // Only if filter is none...
(filterId == new Guid("12345678-AAAA-BBBB-CCCC-123456789000") || (filterId == new Guid("12345678-AAAA-BBBB-CCCC-123456789000") ||
// ...or AppleDouble // ...or AppleDouble
filterId == new Guid("1b2165ee-c9df-4b21-bbbb-9e5892b2df4d"))) xmlTrk.Checksums = sidecar.OpticalDisc[0].Checksums; filterId == new Guid("1b2165ee-c9df-4b21-bbbb-9e5892b2df4d")))
xmlTrk.Checksums = sidecar.OpticalDisc[0].Checksums;
else else
{ {
UpdateProgress("Track {0} of {1}", trk.TrackSequence, tracks.Count); UpdateProgress("Track {0} of {1}", trk.TrackSequence, tracks.Count);
@@ -487,14 +492,19 @@ namespace DiscImageChef.Core
lstFs.Add(plugin.XmlFSType); lstFs.Add(plugin.XmlFSType);
Statistics.AddFilesystem(plugin.XmlFSType.Type); Statistics.AddFilesystem(plugin.XmlFSType.Type);
switch(plugin.XmlFSType.Type) { switch(plugin.XmlFSType.Type)
case "Opera": dskType = MediaType.ThreeDO; {
case "Opera":
dskType = MediaType.ThreeDO;
break; break;
case "PC Engine filesystem": dskType = MediaType.SuperCDROM2; case "PC Engine filesystem":
dskType = MediaType.SuperCDROM2;
break; break;
case "Nintendo Wii filesystem": dskType = MediaType.WOD; case "Nintendo Wii filesystem":
dskType = MediaType.WOD;
break; break;
case "Nintendo Gamecube filesystem": dskType = MediaType.GOD; case "Nintendo Gamecube filesystem":
dskType = MediaType.GOD;
break; break;
} }
} }
@@ -534,14 +544,19 @@ namespace DiscImageChef.Core
lstFs.Add(plugin.XmlFSType); lstFs.Add(plugin.XmlFSType);
Statistics.AddFilesystem(plugin.XmlFSType.Type); Statistics.AddFilesystem(plugin.XmlFSType.Type);
switch(plugin.XmlFSType.Type) { switch(plugin.XmlFSType.Type)
case "Opera": dskType = MediaType.ThreeDO; {
case "Opera":
dskType = MediaType.ThreeDO;
break; break;
case "PC Engine filesystem": dskType = MediaType.SuperCDROM2; case "PC Engine filesystem":
dskType = MediaType.SuperCDROM2;
break; break;
case "Nintendo Wii filesystem": dskType = MediaType.WOD; case "Nintendo Wii filesystem":
dskType = MediaType.WOD;
break; break;
case "Nintendo Gamecube filesystem": dskType = MediaType.GOD; case "Nintendo Gamecube filesystem":
dskType = MediaType.GOD;
break; break;
} }
} }

View File

@@ -42,15 +42,14 @@ namespace DiscImageChef.Core
public static partial class Sidecar public static partial class Sidecar
{ {
/// <summary> /// <summary>
/// Implements creating a metadata sidecar /// Implements creating a metadata sidecar
/// </summary> /// </summary>
/// <param name="image">Image</param> /// <param name="image">Image</param>
/// <param name="imagePath">Path to image</param> /// <param name="imagePath">Path to image</param>
/// <param name="filterId">Filter uuid</param> /// <param name="filterId">Filter uuid</param>
/// <param name="encoding">Encoding for analysis</param> /// <param name="encoding">Encoding for analysis</param>
/// <returns>The metadata sidecar</returns> /// <returns>The metadata sidecar</returns>
public static CICMMetadataType Create(ImagePlugin image, string imagePath, Guid filterId, public static CICMMetadataType Create(ImagePlugin image, string imagePath, Guid filterId, Encoding encoding)
Encoding encoding)
{ {
CICMMetadataType sidecar = new CICMMetadataType(); CICMMetadataType sidecar = new CICMMetadataType();
PluginBase plugins = new PluginBase(); PluginBase plugins = new PluginBase();

View File

@@ -45,25 +45,25 @@ using MediaType = DiscImageChef.CommonTypes.MediaType;
namespace DiscImageChef.Core namespace DiscImageChef.Core
{ {
/// <summary> /// <summary>
/// Handles anonymous usage statistics /// Handles anonymous usage statistics
/// </summary> /// </summary>
public static class Statistics public static class Statistics
{ {
/// <summary> /// <summary>
/// Contains all known statistics /// Contains all known statistics
/// </summary> /// </summary>
public static Stats AllStats; public static Stats AllStats;
/// <summary> /// <summary>
/// Contains statistics of current execution /// Contains statistics of current execution
/// </summary> /// </summary>
public static Stats CurrentStats; public static Stats CurrentStats;
/// <summary> /// <summary>
/// Statistics file semaphore /// Statistics file semaphore
/// </summary> /// </summary>
static bool submitStatsLock; static bool submitStatsLock;
/// <summary> /// <summary>
/// Loads saved statistics from disk /// Loads saved statistics from disk
/// </summary> /// </summary>
public static void LoadStats() public static void LoadStats()
{ {
@@ -115,7 +115,7 @@ namespace DiscImageChef.Core
} }
/// <summary> /// <summary>
/// Saves statistics to disk /// Saves statistics to disk
/// </summary> /// </summary>
public static void SaveStats() public static void SaveStats()
{ {
@@ -126,8 +126,10 @@ namespace DiscImageChef.Core
long count = 0; long count = 0;
OsStats old = null; OsStats old = null;
foreach(OsStats nvs in AllStats.OperatingSystems.Where(nvs => nvs.name == DetectOS.GetRealPlatformID().ToString() && foreach(OsStats nvs in
nvs.version == DetectOS.GetVersion())) { AllStats.OperatingSystems.Where(nvs => nvs.name == DetectOS.GetRealPlatformID().ToString() &&
nvs.version == DetectOS.GetVersion()))
{
count = nvs.Value + 1; count = nvs.Value + 1;
old = nvs; old = nvs;
break; break;
@@ -150,7 +152,8 @@ namespace DiscImageChef.Core
long count = 0; long count = 0;
NameValueStats old = null; NameValueStats old = null;
foreach(NameValueStats nvs in AllStats.Versions.Where(nvs => nvs.name == Version.GetVersion())) { foreach(NameValueStats nvs in AllStats.Versions.Where(nvs => nvs.name == Version.GetVersion()))
{
count = nvs.Value + 1; count = nvs.Value + 1;
old = nvs; old = nvs;
break; break;
@@ -183,7 +186,7 @@ namespace DiscImageChef.Core
} }
/// <summary> /// <summary>
/// Submits statistics to DiscImageChef.Server /// Submits statistics to DiscImageChef.Server
/// </summary> /// </summary>
public static void SubmitStats() public static void SubmitStats()
{ {
@@ -193,8 +196,9 @@ namespace DiscImageChef.Core
submitStatsLock = true; submitStatsLock = true;
IEnumerable<string> statsFiles = Directory.EnumerateFiles(Settings.Settings.StatsPath, "PartialStats_*.xml", IEnumerable<string> statsFiles =
SearchOption.TopDirectoryOnly); Directory.EnumerateFiles(Settings.Settings.StatsPath, "PartialStats_*.xml",
SearchOption.TopDirectoryOnly);
foreach(string statsFile in statsFiles) foreach(string statsFile in statsFiles)
try try
@@ -258,7 +262,7 @@ namespace DiscImageChef.Core
} }
/// <summary> /// <summary>
/// Adds the execution of a command to statistics /// Adds the execution of a command to statistics
/// </summary> /// </summary>
/// <param name="command">Command</param> /// <param name="command">Command</param>
public static void AddCommand(string command) public static void AddCommand(string command)
@@ -351,7 +355,7 @@ namespace DiscImageChef.Core
} }
/// <summary> /// <summary>
/// Adds a new filesystem to statistics /// Adds a new filesystem to statistics
/// </summary> /// </summary>
/// <param name="filesystem">Filesystem name</param> /// <param name="filesystem">Filesystem name</param>
public static void AddFilesystem(string filesystem) public static void AddFilesystem(string filesystem)
@@ -395,7 +399,7 @@ namespace DiscImageChef.Core
} }
/// <summary> /// <summary>
/// Adds a new partition scheme to statistics /// Adds a new partition scheme to statistics
/// </summary> /// </summary>
/// <param name="partition">Partition scheme name</param> /// <param name="partition">Partition scheme name</param>
internal static void AddPartition(string partition) internal static void AddPartition(string partition)
@@ -439,7 +443,7 @@ namespace DiscImageChef.Core
} }
/// <summary> /// <summary>
/// Adds a new filter to statistics /// Adds a new filter to statistics
/// </summary> /// </summary>
/// <param name="format">Filter name</param> /// <param name="format">Filter name</param>
public static void AddFilter(string format) public static void AddFilter(string format)
@@ -483,7 +487,7 @@ namespace DiscImageChef.Core
} }
/// <summary> /// <summary>
/// Ads a new media image to statistics /// Ads a new media image to statistics
/// </summary> /// </summary>
/// <param name="format">Media image name</param> /// <param name="format">Media image name</param>
public static void AddMediaFormat(string format) public static void AddMediaFormat(string format)
@@ -527,7 +531,7 @@ namespace DiscImageChef.Core
} }
/// <summary> /// <summary>
/// Adds a new device to statistics /// Adds a new device to statistics
/// </summary> /// </summary>
/// <param name="dev">Device</param> /// <param name="dev">Device</param>
public static void AddDevice(Device dev) public static void AddDevice(Device dev)
@@ -542,7 +546,9 @@ namespace DiscImageChef.Core
else if(dev.IsFireWire) deviceBus = "FireWire"; else if(dev.IsFireWire) deviceBus = "FireWire";
else deviceBus = dev.Type.ToString(); else deviceBus = dev.Type.ToString();
DeviceStats old = AllStats.Devices.FirstOrDefault(ds => ds.Manufacturer == dev.Manufacturer && ds.Model == dev.Model && ds.Revision == dev.Revision && ds.Bus == deviceBus); DeviceStats old = AllStats.Devices.FirstOrDefault(ds => ds.Manufacturer == dev.Manufacturer &&
ds.Model == dev.Model &&
ds.Revision == dev.Revision && ds.Bus == deviceBus);
if(old != null) AllStats.Devices.Remove(old); if(old != null) AllStats.Devices.Remove(old);
@@ -556,7 +562,9 @@ namespace DiscImageChef.Core
}; };
AllStats.Devices.Add(nw); AllStats.Devices.Add(nw);
old = CurrentStats.Devices.FirstOrDefault(ds => ds.Manufacturer == dev.Manufacturer && ds.Model == dev.Model && ds.Revision == dev.Revision && ds.Bus == deviceBus); old = CurrentStats.Devices.FirstOrDefault(ds => ds.Manufacturer == dev.Manufacturer &&
ds.Model == dev.Model && ds.Revision == dev.Revision &&
ds.Bus == deviceBus);
if(old != null) CurrentStats.Devices.Remove(old); if(old != null) CurrentStats.Devices.Remove(old);
@@ -572,7 +580,7 @@ namespace DiscImageChef.Core
} }
/// <summary> /// <summary>
/// Adds a new media type to statistics /// Adds a new media type to statistics
/// </summary> /// </summary>
/// <param name="type">Media type</param> /// <param name="type">Media type</param>
/// <param name="real">Set if media was found on a real device, otherwise found on a media image</param> /// <param name="real">Set if media was found on a real device, otherwise found on a media image</param>
@@ -621,7 +629,7 @@ namespace DiscImageChef.Core
} }
/// <summary> /// <summary>
/// Adds benchmark results to statistics /// Adds benchmark results to statistics
/// </summary> /// </summary>
/// <param name="checksums">Checksum times</param> /// <param name="checksums">Checksum times</param>
/// <param name="entropy">Entropy times</param> /// <param name="entropy">Entropy times</param>
@@ -637,7 +645,12 @@ namespace DiscImageChef.Core
CurrentStats.Benchmark = new BenchmarkStats {Checksum = new List<ChecksumStats>()}; CurrentStats.Benchmark = new BenchmarkStats {Checksum = new List<ChecksumStats>()};
AllStats.Benchmark = new BenchmarkStats {Checksum = new List<ChecksumStats>()}; AllStats.Benchmark = new BenchmarkStats {Checksum = new List<ChecksumStats>()};
foreach(ChecksumStats st in checksums.Select(kvp => new ChecksumStats {algorithm = kvp.Key, Value = kvp.Value})) { foreach(ChecksumStats st in checksums.Select(kvp => new ChecksumStats
{
algorithm = kvp.Key,
Value = kvp.Value
}))
{
CurrentStats.Benchmark.Checksum.Add(st); CurrentStats.Benchmark.Checksum.Add(st);
AllStats.Benchmark.Checksum.Add(st); AllStats.Benchmark.Checksum.Add(st);
} }
@@ -656,7 +669,7 @@ namespace DiscImageChef.Core
} }
/// <summary> /// <summary>
/// Adds a new media image verification to statistics /// Adds a new media image verification to statistics
/// </summary> /// </summary>
/// <param name="mediaVerified">Set if media was correctly verified</param> /// <param name="mediaVerified">Set if media was correctly verified</param>
/// <param name="correct">How many sectors where verified correctly</param> /// <param name="correct">How many sectors where verified correctly</param>
@@ -668,13 +681,11 @@ namespace DiscImageChef.Core
if(Settings.Settings.Current.Stats == null || !Settings.Settings.Current.Stats.VerifyStats) return; if(Settings.Settings.Current.Stats == null || !Settings.Settings.Current.Stats.VerifyStats) return;
if(CurrentStats.Verify == null) if(CurrentStats.Verify == null)
{
CurrentStats.Verify = CurrentStats.Verify =
new VerifyStats {MediaImages = new VerifiedItems(), Sectors = new ScannedSectors()}; new VerifyStats {MediaImages = new VerifiedItems(), Sectors = new ScannedSectors()};
}
if(AllStats.Verify == null) if(AllStats.Verify == null)
{ AllStats.Verify = new VerifyStats {MediaImages = new VerifiedItems(), Sectors = new ScannedSectors()}; } AllStats.Verify = new VerifyStats {MediaImages = new VerifiedItems(), Sectors = new ScannedSectors()};
if(mediaVerified.HasValue) if(mediaVerified.HasValue)
if(mediaVerified.Value) if(mediaVerified.Value)
@@ -700,7 +711,7 @@ namespace DiscImageChef.Core
} }
/// <summary> /// <summary>
/// Adds a new media scan to statistics /// Adds a new media scan to statistics
/// </summary> /// </summary>
/// <param name="lessThan3ms">Sectors &lt;3ms</param> /// <param name="lessThan3ms">Sectors &lt;3ms</param>
/// <param name="lessThan10ms">Sectors &gt;3ms and &lt;10ms</param> /// <param name="lessThan10ms">Sectors &gt;3ms and &lt;10ms</param>
@@ -717,10 +728,10 @@ namespace DiscImageChef.Core
if(Settings.Settings.Current.Stats == null || !Settings.Settings.Current.Stats.MediaScanStats) return; if(Settings.Settings.Current.Stats == null || !Settings.Settings.Current.Stats.MediaScanStats) return;
if(CurrentStats.MediaScan == null) if(CurrentStats.MediaScan == null)
{ CurrentStats.MediaScan = new MediaScanStats {Sectors = new ScannedSectors(), Times = new TimeStats()}; } CurrentStats.MediaScan = new MediaScanStats {Sectors = new ScannedSectors(), Times = new TimeStats()};
if(AllStats.MediaScan == null) if(AllStats.MediaScan == null)
{ AllStats.MediaScan = new MediaScanStats {Sectors = new ScannedSectors(), Times = new TimeStats()}; } AllStats.MediaScan = new MediaScanStats {Sectors = new ScannedSectors(), Times = new TimeStats()};
CurrentStats.MediaScan.Sectors.Correct += correct; CurrentStats.MediaScan.Sectors.Correct += correct;
CurrentStats.MediaScan.Sectors.Error += error; CurrentStats.MediaScan.Sectors.Error += error;

View File

@@ -38,7 +38,7 @@ namespace DiscImageChef.Core
static class Version static class Version
{ {
/// <summary> /// <summary>
/// Gets XML software type for the running version /// Gets XML software type for the running version
/// </summary> /// </summary>
/// <param name="platform">Platform we are running in</param> /// <param name="platform">Platform we are running in</param>
/// <returns>XML software type</returns> /// <returns>XML software type</returns>
@@ -54,7 +54,7 @@ namespace DiscImageChef.Core
} }
/// <summary> /// <summary>
/// Gets version string /// Gets version string
/// </summary> /// </summary>
/// <returns>Version</returns> /// <returns>Version</returns>
internal static string GetVersion() internal static string GetVersion()