DOCUMENTATION: Added XML documentation to DiscImageChef.Core.

This commit is contained in:
2017-12-23 01:46:08 +00:00
parent e7932c12c2
commit 9249a221fc
61 changed files with 1937 additions and 1267 deletions

View File

@@ -36,6 +36,9 @@ using System.Text;
namespace DiscImageChef.Checksums
{
/// <summary>
/// Implements the Adler-32 algorithm
/// </summary>
public class Adler32Context
{
ushort sum1, sum2;

View File

@@ -37,6 +37,9 @@ using DiscImageChef.Console;
namespace DiscImageChef.Checksums
{
/// <summary>
/// Implements ReedSolomon and CRC32 algorithms as used by CD-ROM
/// </summary>
public static class CdChecksums
{
static byte[] eccFTable;

View File

@@ -37,7 +37,7 @@ using System.Text;
namespace DiscImageChef.Checksums
{
/// <summary>
/// Provides a UNIX similar API to calculate CRC16.
/// Implements a CRC16-CCITT algorithm
/// </summary>
public class Crc16Context
{

View File

@@ -37,7 +37,7 @@ using System.Text;
namespace DiscImageChef.Checksums
{
/// <summary>
/// Provides a UNIX similar API to calculate CRC32.
/// Implements a CRC32 algorithm
/// </summary>
public class Crc32Context
{

View File

@@ -36,7 +36,7 @@ using System.Text;
namespace DiscImageChef.Checksums
{
/// <summary>
/// Provides a UNIX similar API to calculate CRC64 (ECMA).
/// Implements a CRC64 (ECMA) algorithm
/// </summary>
public class Crc64Context
{

View File

@@ -40,9 +40,9 @@ namespace DiscImageChef.Checksums
{
public class Fletcher32Context
{
UInt16 sum1, sum2;
byte oddValue;
bool inodd;
byte oddValue;
ushort sum1, sum2;
/// <summary>
/// Initializes the Fletcher32 sums
@@ -62,10 +62,8 @@ namespace DiscImageChef.Checksums
/// <param name="len">Length of buffer to hash.</param>
public void Update(byte[] data, uint len)
{
UInt16 block;
ushort block;
if(!inodd)
{
// Odd size
if(len % 2 != 0)
{
oddValue = data[len - 1];
@@ -74,8 +72,8 @@ namespace DiscImageChef.Checksums
for(int i = 0; i < len - 1; i += 2)
{
block = BigEndianBitConverter.ToUInt16(data, i);
sum1 = (UInt16)((sum1 + block) % 0xFFFF);
sum2 = (UInt16)((sum2 + sum1) % 0xFFFF);
sum1 = (ushort)((sum1 + block) % 0xFFFF);
sum2 = (ushort)((sum2 + sum1) % 0xFFFF);
}
}
else
@@ -84,9 +82,8 @@ namespace DiscImageChef.Checksums
for(int i = 0; i < len; i += 2)
{
block = BigEndianBitConverter.ToUInt16(data, i);
sum1 = (UInt16)((sum1 + block) % 0xFFFF);
sum2 = (UInt16)((sum2 + sum1) % 0xFFFF);
}
sum1 = (ushort)((sum1 + block) % 0xFFFF);
sum2 = (ushort)((sum2 + sum1) % 0xFFFF);
}
}
// Carrying odd
@@ -97,8 +94,8 @@ namespace DiscImageChef.Checksums
oddData[1] = data[0];
block = BigEndianBitConverter.ToUInt16(oddData, 0);
sum1 = (UInt16)((sum1 + block) % 0xFFFF);
sum2 = (UInt16)((sum2 + sum1) % 0xFFFF);
sum1 = (ushort)((sum1 + block) % 0xFFFF);
sum2 = (ushort)((sum2 + sum1) % 0xFFFF);
// Even size, carrying odd
if(len % 2 == 0)
@@ -109,8 +106,8 @@ namespace DiscImageChef.Checksums
for(int i = 1; i < len - 1; i += 2)
{
block = BigEndianBitConverter.ToUInt16(data, i);
sum1 = (UInt16)((sum1 + block) % 0xFFFF);
sum2 = (UInt16)((sum2 + sum1) % 0xFFFF);
sum1 = (ushort)((sum1 + block) % 0xFFFF);
sum2 = (ushort)((sum2 + sum1) % 0xFFFF);
}
}
else
@@ -119,8 +116,8 @@ namespace DiscImageChef.Checksums
for(int i = 1; i < len; i += 2)
{
block = BigEndianBitConverter.ToUInt16(data, i);
sum1 = (UInt16)((sum1 + block) % 0xFFFF);
sum2 = (UInt16)((sum2 + sum1) % 0xFFFF);
sum1 = (ushort)((sum1 + block) % 0xFFFF);
sum2 = (ushort)((sum2 + sum1) % 0xFFFF);
}
}
}
@@ -140,7 +137,7 @@ namespace DiscImageChef.Checksums
/// </summary>
public byte[] Final()
{
UInt32 finalSum = (UInt32)(sum1 + (sum2 << 16));
uint finalSum = (uint)(sum1 + (sum2 << 16));
return BigEndianBitConverter.GetBytes(finalSum);
}
@@ -149,13 +146,11 @@ namespace DiscImageChef.Checksums
/// </summary>
public string End()
{
UInt32 finalSum = (UInt32)(sum1 + (sum2 << 16));
uint finalSum = (uint)(sum1 + (sum2 << 16));
StringBuilder fletcherOutput = new StringBuilder();
for(int i = 0; i < BigEndianBitConverter.GetBytes(finalSum).Length; i++)
{
fletcherOutput.Append(BigEndianBitConverter.GetBytes(finalSum)[i].ToString("x2"));
}
return fletcherOutput.ToString();
}
@@ -166,8 +161,7 @@ namespace DiscImageChef.Checksums
/// <param name="filename">File path.</param>
public static byte[] File(string filename)
{
byte[] hash;
File(filename, out hash);
File(filename, out byte[] hash);
return hash;
}
@@ -179,24 +173,21 @@ namespace DiscImageChef.Checksums
public static string File(string filename, out byte[] hash)
{
FileStream fileStream = new FileStream(filename, FileMode.Open);
UInt16 localSum1, localSum2, block;
UInt32 finalSum;
ushort localSum1, localSum2, block;
uint finalSum;
byte[] blockBytes;
localSum1 = 0xFFFF;
localSum2 = 0xFFFF;
block = 0;
if(fileStream.Length % 2 == 0)
{
for(int i = 0; i < fileStream.Length; i += 2)
{
blockBytes = new byte[2];
fileStream.Read(blockBytes, 0, 2);
block = BigEndianBitConverter.ToUInt16(blockBytes, 0);
localSum1 = (UInt16)((localSum1 + block) % 0xFFFF);
localSum2 = (UInt16)((localSum2 + localSum1) % 0xFFFF);
}
localSum1 = (ushort)((localSum1 + block) % 0xFFFF);
localSum2 = (ushort)((localSum2 + localSum1) % 0xFFFF);
}
else
{
@@ -205,8 +196,8 @@ namespace DiscImageChef.Checksums
blockBytes = new byte[2];
fileStream.Read(blockBytes, 0, 2);
block = BigEndianBitConverter.ToUInt16(blockBytes, 0);
localSum1 = (UInt16)((localSum1 + block) % 0xFFFF);
localSum2 = (UInt16)((localSum2 + localSum1) % 0xFFFF);
localSum1 = (ushort)((localSum1 + block) % 0xFFFF);
localSum2 = (ushort)((localSum2 + localSum1) % 0xFFFF);
}
byte[] oddData = new byte[2];
@@ -214,20 +205,17 @@ namespace DiscImageChef.Checksums
oddData[1] = 0;
block = BigEndianBitConverter.ToUInt16(oddData, 0);
localSum1 = (UInt16)((localSum1 + block) % 0xFFFF);
localSum2 = (UInt16)((localSum2 + localSum1) % 0xFFFF);
localSum1 = (ushort)((localSum1 + block) % 0xFFFF);
localSum2 = (ushort)((localSum2 + localSum1) % 0xFFFF);
}
finalSum = (UInt32)(localSum1 + (localSum2 << 16));
finalSum = (uint)(localSum1 + (localSum2 << 16));
hash = BitConverter.GetBytes(finalSum);
StringBuilder fletcherOutput = new StringBuilder();
for(int i = 0; i < hash.Length; i++)
{
fletcherOutput.Append(hash[i].ToString("x2"));
}
foreach(byte h in hash) fletcherOutput.Append(h.ToString("x2"));
return fletcherOutput.ToString();
}
@@ -240,29 +228,26 @@ namespace DiscImageChef.Checksums
/// <param name="hash">Byte array of the hash value.</param>
public static string Data(byte[] data, uint len, out byte[] hash)
{
UInt16 localSum1, localSum2, block;
UInt32 finalSum;
ushort localSum1, localSum2, block;
uint finalSum;
localSum1 = 0xFFFF;
localSum2 = 0xFFFF;
block = 0;
if(len % 2 == 0)
{
for(int i = 0; i < len; i += 2)
{
block = BigEndianBitConverter.ToUInt16(data, i);
localSum1 = (UInt16)((localSum1 + block) % 0xFFFF);
localSum2 = (UInt16)((localSum2 + localSum1) % 0xFFFF);
}
localSum1 = (ushort)((localSum1 + block) % 0xFFFF);
localSum2 = (ushort)((localSum2 + localSum1) % 0xFFFF);
}
else
{
for(int i = 0; i < len - 1; i += 2)
{
block = BigEndianBitConverter.ToUInt16(data, i);
localSum1 = (UInt16)((localSum1 + block) % 0xFFFF);
localSum2 = (UInt16)((localSum2 + localSum1) % 0xFFFF);
localSum1 = (ushort)((localSum1 + block) % 0xFFFF);
localSum2 = (ushort)((localSum2 + localSum1) % 0xFFFF);
}
byte[] oddData = new byte[2];
@@ -270,20 +255,17 @@ namespace DiscImageChef.Checksums
oddData[1] = 0;
block = BigEndianBitConverter.ToUInt16(oddData, 0);
localSum1 = (UInt16)((localSum1 + block) % 0xFFFF);
localSum2 = (UInt16)((localSum2 + localSum1) % 0xFFFF);
localSum1 = (ushort)((localSum1 + block) % 0xFFFF);
localSum2 = (ushort)((localSum2 + localSum1) % 0xFFFF);
}
finalSum = (UInt32)(localSum1 + (localSum2 << 16));
finalSum = (uint)(localSum1 + (localSum2 << 16));
hash = BitConverter.GetBytes(finalSum);
StringBuilder fletcherOutput = new StringBuilder();
for(int i = 0; i < hash.Length; i++)
{
fletcherOutput.Append(hash[i].ToString("x2"));
}
foreach(byte h in hash) fletcherOutput.Append(h.ToString("x2"));
return fletcherOutput.ToString();
}
@@ -340,7 +322,7 @@ namespace DiscImageChef.Checksums
/// </summary>
public byte[] Final()
{
UInt16 finalSum = (UInt16)(sum1 + (sum2 << 8));
ushort finalSum = (ushort)(sum1 + (sum2 << 8));
return BigEndianBitConverter.GetBytes(finalSum);
}
@@ -349,13 +331,11 @@ namespace DiscImageChef.Checksums
/// </summary>
public string End()
{
UInt16 finalSum = (UInt16)(sum1 + (sum2 << 8));
ushort finalSum = (ushort)(sum1 + (sum2 << 8));
StringBuilder fletcherOutput = new StringBuilder();
for(int i = 0; i < BigEndianBitConverter.GetBytes(finalSum).Length; i++)
{
fletcherOutput.Append(BigEndianBitConverter.GetBytes(finalSum)[i].ToString("x2"));
}
return fletcherOutput.ToString();
}
@@ -366,8 +346,7 @@ namespace DiscImageChef.Checksums
/// <param name="filename">File path.</param>
public static byte[] File(string filename)
{
byte[] hash;
File(filename, out hash);
File(filename, out byte[] hash);
return hash;
}
@@ -380,11 +359,10 @@ namespace DiscImageChef.Checksums
{
FileStream fileStream = new FileStream(filename, FileMode.Open);
byte localSum1, localSum2, block;
UInt16 finalSum;
ushort finalSum;
localSum1 = 0xFF;
localSum2 = 0xFF;
block = 0;
for(int i = 0; i < fileStream.Length; i += 2)
{
@@ -393,16 +371,13 @@ namespace DiscImageChef.Checksums
localSum2 = (byte)((localSum2 + localSum1) % 0xFF);
}
finalSum = (UInt16)(localSum1 + (localSum2 << 8));
finalSum = (ushort)(localSum1 + (localSum2 << 8));
hash = BitConverter.GetBytes(finalSum);
StringBuilder fletcherOutput = new StringBuilder();
for(int i = 0; i < hash.Length; i++)
{
fletcherOutput.Append(hash[i].ToString("x2"));
}
foreach(byte h in hash) fletcherOutput.Append(h.ToString("x2"));
return fletcherOutput.ToString();
}
@@ -416,7 +391,7 @@ namespace DiscImageChef.Checksums
public static string Data(byte[] data, uint len, out byte[] hash)
{
byte localSum1, localSum2;
UInt16 finalSum;
ushort finalSum;
localSum1 = 0xFF;
localSum2 = 0xFF;
@@ -427,16 +402,13 @@ namespace DiscImageChef.Checksums
localSum2 = (byte)((localSum2 + localSum1) % 0xFF);
}
finalSum = (UInt16)(localSum1 + (localSum2 << 8));
finalSum = (ushort)(localSum1 + (localSum2 << 8));
hash = BitConverter.GetBytes(finalSum);
StringBuilder fletcherOutput = new StringBuilder();
for(int i = 0; i < hash.Length; i++)
{
fletcherOutput.Append(hash[i].ToString("x2"));
}
foreach(byte h in hash) fletcherOutput.Append(h.ToString("x2"));
return fletcherOutput.ToString();
}
@@ -451,6 +423,4 @@ namespace DiscImageChef.Checksums
return Data(data, (uint)data.Length, out hash);
}
}
}
*/
}*/

View File

@@ -37,7 +37,7 @@ using System.Text;
namespace DiscImageChef.Checksums
{
/// <summary>
/// Provides a UNIX similar API to .NET MD5.
/// Wraps up .NET MD5 implementation to a Init(), Update(), Final() context.
/// </summary>
public class Md5Context
{

View File

@@ -37,7 +37,7 @@ using System.Text;
namespace DiscImageChef.Checksums
{
/// <summary>
/// Provides a UNIX similar API to .NET RIPEMD160.
/// Wraps up .NET RIPEMD160 implementation to a Init(), Update(), Final() context.
/// </summary>
public class Ripemd160Context
{

View File

@@ -62,6 +62,9 @@ using DiscImageChef.Console;
namespace DiscImageChef.Checksums
{
/// <summary>
/// Implements the Reed-Solomon algorithm
/// </summary>
public class ReedSolomon
{
/* Primitive polynomials - see Lin & Costello, Error Control Coding Appendix A,

View File

@@ -37,7 +37,7 @@ using System.Text;
namespace DiscImageChef.Checksums
{
/// <summary>
/// Provides a UNIX similar API to .NET SHA1.
/// Wraps up .NET SHA1 implementation to a Init(), Update(), Final() context.
/// </summary>
public class Sha1Context
{

View File

@@ -37,7 +37,7 @@ using System.Text;
namespace DiscImageChef.Checksums
{
/// <summary>
/// Provides a UNIX similar API to .NET SHA256.
/// Wraps up .NET SHA256 implementation to a Init(), Update(), Final() context.
/// </summary>
public class Sha256Context
{

View File

@@ -37,7 +37,7 @@ using System.Text;
namespace DiscImageChef.Checksums
{
/// <summary>
/// Provides a UNIX similar API to .NET SHA384.
/// Wraps up .NET SHA384 implementation to a Init(), Update(), Final() context.
/// </summary>
public class Sha384Context
{

View File

@@ -37,7 +37,7 @@ using System.Text;
namespace DiscImageChef.Checksums
{
/// <summary>
/// Provides a UNIX similar API to .NET SHA512.
/// Wraps up .NET SHA512 implementation to a Init(), Update(), Final() context.
/// </summary>
public class Sha512Context
{

View File

@@ -45,7 +45,7 @@ using System.Text;
namespace DiscImageChef.Checksums
{
/// <summary>
/// Provides a UNIX similar API to calculate Fuzzy Hash (SpamSum).
/// Implements the SpamSum fuzzy hashing algorithm.
/// </summary>
public class SpamSumContext
{

View File

@@ -34,7 +34,9 @@
// TODO: Rename contents
namespace DiscImageChef.CommonTypes
{
// Media (disk, cartridge, tape, cassette, etc) types
/// <summary>
/// Contains an enumeration of all known types of media.
/// </summary>
public enum MediaType
{
/// <summary>Unknown disk type</summary>

View File

@@ -37,6 +37,17 @@ namespace DiscImageChef.CommonTypes
#pragma warning disable RECS0063 // Warns when a culture-aware 'StartsWith' call is used by default.
public static class MediaTypeFromScsi
{
/// <summary>
/// Tries to guess, from SCSI information, the media type of a device and/or its inserted media
/// </summary>
/// <param name="scsiPeripheralType">The SCSI Peripheral Type as indicated in the INQUIRY response</param>
/// <param name="vendor">The vendor string of the device</param>
/// <param name="model">The model string of the device</param>
/// <param name="mediumType">The medium type byte from MODE SENSE</param>
/// <param name="densityCode">The density type byte from MODE SENSE</param>
/// <param name="blocks">How many blocks are on the media</param>
/// <param name="blockSize">Size in bytes of each block</param>
/// <returns></returns>
public static MediaType Get(byte scsiPeripheralType, string vendor, string model, byte mediumType,
byte densityCode, ulong blocks, uint blockSize)
{

View File

@@ -56,13 +56,15 @@ namespace DiscImageChef.CommonTypes
/// <summary>Information that does not find space in this struct</summary>
public string Description;
/// <summary>LBA of last partition sector</summary>
public ulong End
{
get => Start + Length - 1;
}
public ulong End => Start + Length - 1;
/// <summary>Name of partition scheme that contains this partition</summary>
public string Scheme;
/// <summary>
/// Compares two partitions
/// </summary>
/// <param name="other">Partition to compare with</param>
/// <returns>0 if both partitions start and end at the same sector</returns>
public bool Equals(Partition other)
{
return Start == other.Start && Length == other.Length;
@@ -80,6 +82,11 @@ namespace DiscImageChef.CommonTypes
return Start.GetHashCode() + End.GetHashCode();
}
/// <summary>
/// Compares this partition with another and returns an integer that indicates whether the current partition precedes, follows, or is in the same place as the other partition.
/// </summary>
/// <param name="other">Partition to compare with</param>
/// <returns>A value that indicates the relative equality of the partitions being compared.</returns>
public int CompareTo(Partition other)
{
if(Start == other.Start && End == other.End) return 0;

View File

@@ -48,6 +48,9 @@ namespace DiscImageChef.Console
public delegate void DebugWriteHandler(string format, params object[] arg);
/// <summary>
/// Implements a console abstraction that defines four level of messages that can be routed to different consoles: standard, error, verbose and debug.
/// </summary>
public static class DicConsole
{
public static event WriteLineHandler WriteLineEvent;

View File

@@ -61,6 +61,9 @@ namespace DiscImageChef.Core
public double Speed;
}
/// <summary>
/// Benchmarks the speed at which we can do checksums
/// </summary>
public static class Benchmark
{
public static event InitProgressHandler InitProgressEvent;

View File

@@ -55,6 +55,9 @@ namespace DiscImageChef.Core
All = Adler32 | Crc16 | Crc32 | Crc64 | Md5 | Ripemd160 | Sha1 | Sha256 | Sha384 | Sha512 | SpamSum
}
/// <summary>
/// Checksums and hashes data, with different algorithms multithreaded
/// </summary>
public class Checksum
{
Adler32Context adler32Ctx;

View File

@@ -30,77 +30,154 @@
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
using System.Diagnostics.CodeAnalysis;
using System.IO;
using DiscImageChef.Console;
namespace DiscImageChef.Core
{
/// <summary>
/// Abstracts a datafile with a block based interface
/// </summary>
[SuppressMessage("ReSharper", "UnusedMethodReturnValue.Global")]
public class DataFile
{
FileStream dataFs;
/// <summary>
/// Opens, or create, a new file
/// </summary>
/// <param name="outputFile">File</param>
public DataFile(string outputFile)
{
dataFs = new FileStream(outputFile, FileMode.OpenOrCreate, FileAccess.ReadWrite);
}
/// <summary>
/// Closes the file
/// </summary>
public void Close()
{
dataFs?.Close();
}
/// <summary>
/// Reads bytes at current position
/// </summary>
/// <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="count">How many bytes to read</param>
/// <returns>How many bytes were read</returns>
public int Read(byte[] array, int offset, int count)
{
return dataFs.Read(array, offset, count);
}
/// <summary>
/// Seeks to the specified block
/// </summary>
/// <param name="block">Block to seek to</param>
/// <param name="blockSize">Block size in bytes</param>
/// <returns>Position</returns>
public long Seek(ulong block, ulong blockSize)
{
return dataFs.Seek((long)(block * blockSize), SeekOrigin.Begin);
}
/// <summary>
/// Seeks to specified byte position
/// </summary>
/// <param name="offset">Byte position</param>
/// <param name="origin">Where to count for position</param>
/// <returns>Position</returns>
public long Seek(ulong offset, SeekOrigin origin)
{
return dataFs.Seek((long)offset, origin);
}
/// <summary>
/// Seeks to specified byte position
/// </summary>
/// <param name="offset">Byte position</param>
/// <param name="origin">Where to count for position</param>
/// <returns>Position</returns>
public long Seek(long offset, SeekOrigin origin)
{
return dataFs.Seek(offset, origin);
}
/// <summary>
/// Writes data at current position
/// </summary>
/// <param name="data">Data</param>
public void Write(byte[] data)
{
Write(data, 0, data.Length);
}
/// <summary>
/// Writes data at current position
/// </summary>
/// <param name="data">Data</param>
/// <param name="offset">Offset of data from where to start taking data to write</param>
/// <param name="count">How many bytes to write</param>
public void Write(byte[] data, int offset, int count)
{
dataFs.Write(data, offset, count);
}
/// <summary>
/// Writes data at specified block
/// </summary>
/// <param name="data">Data</param>
/// <param name="block">Block</param>
/// <param name="blockSize">Bytes per block</param>
public void WriteAt(byte[] data, ulong block, uint blockSize)
{
WriteAt(data, block, blockSize, 0, data.Length);
}
/// <summary>
/// Writes data at specified block
/// </summary>
/// <param name="data">Data</param>
/// <param name="block">Block</param>
/// <param name="blockSize">Bytes per block</param>
/// <param name="offset">Offset of data from where to start taking data to write</param>
/// <param name="count">How many bytes to write</param>
public void WriteAt(byte[] data, ulong block, uint blockSize, int offset, int count)
{
dataFs.Seek((long)(block * blockSize), SeekOrigin.Begin);
dataFs.Write(data, offset, count);
}
public long Position
{
get => dataFs.Position;
}
/// <summary>
/// Current file position
/// </summary>
public long Position => dataFs.Position;
public static void WriteTo(string who, string outputPrefix, string outputSuffix, string what, byte[] data)
/// <summary>
/// Writes data to a newly created file
/// </summary>
/// <param name="who">Who asked the file to be written (class, plugin, etc.)</param>
/// <param name="data">Data to write</param>
/// <param name="outputPrefix">First 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>
public static void WriteTo(string who, string outputPrefix, string outputSuffix, string whatWriting, byte[] data)
{
if(!string.IsNullOrEmpty(outputPrefix) && !string.IsNullOrEmpty(outputSuffix))
WriteTo(who, outputPrefix + outputSuffix, data, what);
WriteTo(who, outputPrefix + outputSuffix, data, whatWriting);
}
/// <summary>
/// Writes data to a newly created file
/// </summary>
/// <param name="who">Who asked the file to be written (class, plugin, etc.)</param>
/// <param name="filename">Filename to create</param>
/// <param name="data">Data to write</param>
/// <param name="whatWriting">What is the data about?</param>
/// <param name="overwrite">If set to <c>true</c> overwrites the file, does nothing otherwise</param>
public static void WriteTo(string who, string filename, byte[] data, string whatWriting = null,
bool overwrite = false)
{

View File

@@ -52,8 +52,26 @@ using Tuple = DiscImageChef.Decoders.PCMCIA.Tuple;
namespace DiscImageChef.Core.Devices.Dumping
{
/// <summary>
/// Implements dumping ATA devices
/// </summary>
public class Ata
{
/// <summary>
/// Dumps an ATA device
/// </summary>
/// <param name="dev">Device</param>
/// <param name="devicePath">Path to the device</param>
/// <param name="outputPrefix">Prefix for output data files</param>
/// <param name="retryPasses">How many times to retry</param>
/// <param name="force">Force to continue dump whenever possible</param>
/// <param name="dumpRaw">Dump long sectors</param>
/// <param name="persistent">Store whatever data the drive returned on error</param>
/// <param name="stopOnError">Stop dump on first error</param>
/// <param name="resume">Information for dump resuming</param>
/// <param name="dumpLog">Dump logger</param>
/// <param name="encoding">Encoding to use when analyzing dump</param>
/// <exception cref="InvalidOperationException">If the resume file is invalid</exception>
public static void Dump(Device dev, string devicePath, string outputPrefix, ushort retryPasses, bool force,
bool dumpRaw, bool persistent, bool stopOnError, ref Resume resume,
ref DumpLog dumpLog, Encoding encoding)
@@ -222,7 +240,7 @@ namespace DiscImageChef.Core.Devices.Dumping
ResumeSupport.Process(ataReader.IsLba, removable, blocks, dev.Manufacturer, dev.Model, dev.Serial,
dev.PlatformId, ref resume, ref currentTry, ref extents);
if(currentTry == null || extents == null)
throw new Exception("Could not process resume file, not continuing...");
throw new InvalidOperationException("Could not process resume file, not continuing...");
MhddLog mhddLog;
IbgLog ibgLog;

View File

@@ -52,8 +52,32 @@ using TrackType = Schemas.TrackType;
namespace DiscImageChef.Core.Devices.Dumping
{
/// <summary>
/// Implement dumping Compact Discs
/// </summary>
class CompactDisc
{
/// <summary>
/// Dumps a compact disc
/// </summary>
/// <param name="dev">Device</param>
/// <param name="devicePath">Path to the device</param>
/// <param name="outputPrefix">Prefix for output data files</param>
/// <param name="retryPasses">How many times to retry</param>
/// <param name="force">Force to continue dump whenever possible</param>
/// <param name="dumpRaw">Dump scrambled sectors</param>
/// <param name="persistent">Store whatever data the drive returned on error</param>
/// <param name="stopOnError">Stop dump on first error</param>
/// <param name="resume">Information for dump resuming</param>
/// <param name="dumpLog">Dump logger</param>
/// <param name="sidecar">Partially filled initialized sidecar</param>
/// <param name="dskType">Disc type as detected in MMC layer</param>
/// <param name="separateSubchannel">Write subchannel separate from main channel</param>
/// <param name="alcohol">Alcohol disc image already initialized</param>
/// <param name="dumpLeadIn">Try to read and dump as much Lead-in as possible</param>
/// <exception cref="NotImplementedException">If trying to dump scrambled sectors</exception>
/// <exception cref="InvalidOperationException">If the resume file is invalid</exception>
/// <exception cref="ArgumentOutOfRangeException">If the track type is unknown (never)</exception>
internal static void Dump(Device dev, string devicePath, string outputPrefix, ushort retryPasses, bool force,
bool dumpRaw, bool persistent, bool stopOnError, ref CICMMetadataType sidecar,
ref MediaType dskType, bool separateSubchannel, ref Resume resume,
@@ -367,7 +391,7 @@ namespace DiscImageChef.Core.Devices.Dumping
ResumeSupport.Process(true, true, blocks, dev.Manufacturer, dev.Model, dev.Serial, dev.PlatformId,
ref resume, ref currentTry, ref extents);
if(currentTry == null || extents == null)
throw new Exception("Could not process resume file, not continuing...");
throw new InvalidOperationException("Could not process resume file, not continuing...");
if(dumpLeadIn)
{

View File

@@ -48,8 +48,30 @@ using Spare = DiscImageChef.Decoders.DVD.Spare;
namespace DiscImageChef.Core.Devices.Dumping
{
/// <summary>
/// Implement dumping optical discs from MultiMedia devices
/// </summary>
static class Mmc
{
/// <summary>
/// Dumps an optical disc
/// </summary>
/// <param name="dev">Device</param>
/// <param name="devicePath">Path to the device</param>
/// <param name="outputPrefix">Prefix for output data files</param>
/// <param name="retryPasses">How many times to retry</param>
/// <param name="force">Force to continue dump whenever possible</param>
/// <param name="dumpRaw">Dump raw/long sectors</param>
/// <param name="persistent">Store whatever data the drive returned on error</param>
/// <param name="stopOnError">Stop dump on first error</param>
/// <param name="resume">Information for dump resuming</param>
/// <param name="dumpLog">Dump logger</param>
/// <param name="encoding">Encoding to use when analyzing dump</param>
/// <param name="sidecar">Partially filled initialized sidecar</param>
/// <param name="dskType">Disc type as detected in MMC layer</param>
/// <param name="separateSubchannel">Write subchannel separate from main channel</param>
/// <param name="dumpLeadIn">Try to read and dump as much Lead-in as possible</param>
/// <exception cref="NotImplementedException">If trying to dump GOD or WOD, or XGDs without a Kreon drive</exception>
internal static void Dump(Device dev, string devicePath, string outputPrefix, ushort retryPasses, bool force,
bool dumpRaw, bool persistent, bool stopOnError, ref CICMMetadataType sidecar,
ref MediaType dskType, bool separateSubchannel, ref Resume resume,

View File

@@ -39,8 +39,26 @@ using PlatformID = DiscImageChef.Interop.PlatformID;
namespace DiscImageChef.Core.Devices.Dumping
{
/// <summary>
/// Implements resume support
/// </summary>
static class ResumeSupport
{
/// <summary>
/// Process resume
/// </summary>
/// <param name="isLba">If drive is LBA</param>
/// <param name="removable">If media is removable from device</param>
/// <param name="blocks">Media blocks</param>
/// <param name="manufacturer">Device manufacturer</param>
/// <param name="model">Device model</param>
/// <param name="serial">Device serial</param>
/// <param name="platform">Platform where the dump is made</param>
/// <param name="resume">Previous resume, or null</param>
/// <param name="currentTry">Current dumping hardware</param>
/// <param name="extents">Dumped extents</param>
/// <exception cref="NotImplementedException">If device uses CHS addressing</exception>
/// <exception cref="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,
string serial, PlatformID platform, ref Resume resume,
ref DumpHardwareType currentTry, ref ExtentsULong extents)
@@ -51,27 +69,30 @@ namespace DiscImageChef.Core.Devices.Dumping
if(resume.Removable != removable)
throw new
Exception($"Resume file specifies a {(resume.Removable ? "removable" : "non removable")} device but you're requesting to dump a {(removable ? "removable" : "non removable")} device, not continuing...");
InvalidOperationException($"Resume file specifies a {(resume.Removable ? "removable" : "non removable")} device but you're requesting to dump a {(removable ? "removable" : "non removable")} device, not continuing...");
if(resume.LastBlock != blocks - 1)
throw new
Exception($"Resume file specifies a device with {resume.LastBlock + 1} blocks but you're requesting to dump one with {blocks} blocks, not continuing...");
InvalidOperationException($"Resume file specifies a device with {resume.LastBlock + 1} blocks but you're requesting to dump one with {blocks} blocks, not continuing...");
foreach(DumpHardwareType oldtry in resume.Tries)
{
if(oldtry.Manufacturer != manufacturer && !removable)
if(!removable)
{
if(oldtry.Manufacturer != manufacturer)
throw new
Exception($"Resume file specifies a device manufactured by {oldtry.Manufacturer} but you're requesting to dump one by {manufacturer}, not continuing...");
InvalidOperationException($"Resume file specifies a device manufactured by {oldtry.Manufacturer} but you're requesting to dump one by {manufacturer}, not continuing...");
if(oldtry.Model != model && !removable)
if(oldtry.Model != model)
throw new
Exception($"Resume file specifies a device model {oldtry.Model} but you're requesting to dump model {model}, not continuing...");
InvalidOperationException($"Resume file specifies a device model {oldtry.Model} but you're requesting to dump model {model}, not continuing...");
if(oldtry.Serial != serial && !removable)
if(oldtry.Serial != serial)
throw new
Exception($"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 Exception("Found corrupt resume file, cannot continue...");
if(oldtry.Software == null) throw new InvalidOperationException("Found corrupt resume file, cannot continue...");
if(oldtry.Software.Name != "DiscImageChef" ||
oldtry.Software.OperatingSystem != platform.ToString() ||

View File

@@ -53,8 +53,30 @@ using TrackType = DiscImageChef.DiscImages.TrackType;
namespace DiscImageChef.Core.Devices.Dumping
{
/// <summary>
/// Implements dumping SCSI Block Commands and Reduced Block Commands devices
/// </summary>
static class Sbc
{
/// <summary>
/// Dumps a SCSI Block Commands device or a Reduced Block Commands devices
/// </summary>
/// <param name="dev">Device</param>
/// <param name="devicePath">Path to the device</param>
/// <param name="outputPrefix">Prefix for output data files</param>
/// <param name="retryPasses">How many times to retry</param>
/// <param name="force">Force to continue dump whenever possible</param>
/// <param name="dumpRaw">Dump long or scrambled sectors</param>
/// <param name="persistent">Store whatever data the drive returned on error</param>
/// <param name="stopOnError">Stop dump on first error</param>
/// <param name="resume">Information for dump resuming</param>
/// <param name="dumpLog">Dump logger</param>
/// <param name="encoding">Encoding to use when analyzing dump</param>
/// <param name="opticalDisc">If device contains an optical disc (e.g. DVD or BD)</param>
/// <param name="sidecar">Partially filled initialized sidecar</param>
/// <param name="dskType">Disc type as detected in SCSI or MMC layer</param>
/// <param name="alcohol">Alcohol disc image already initialized for optical discs, null otherwise</param>
/// <exception cref="InvalidOperationException">If the resume file is invalid</exception>
internal static void Dump(Device dev, string devicePath, string outputPrefix, ushort retryPasses, bool force,
bool dumpRaw, bool persistent, bool stopOnError, ref CICMMetadataType sidecar,
ref MediaType dskType, bool opticalDisc, ref Resume resume,
@@ -336,7 +358,7 @@ namespace DiscImageChef.Core.Devices.Dumping
ResumeSupport.Process(true, dev.IsRemovable, blocks, dev.Manufacturer, dev.Model, dev.Serial,
dev.PlatformId, ref resume, ref currentTry, ref extents);
if(currentTry == null || extents == null)
throw new Exception("Could not process resume file, not continuing...");
throw new InvalidOperationException("Could not process resume file, not continuing...");
dumpFile.Seek(resume.NextBlock, blockSize);
if(resume.NextBlock > 0) dumpLog.WriteLine("Resuming from block {0}.", resume.NextBlock);

View File

@@ -43,9 +43,29 @@ using MediaType = DiscImageChef.CommonTypes.MediaType;
namespace DiscImageChef.Core.Devices.Dumping
{
/// <summary>
/// Implements dumping SCSI and ATAPI devices
/// </summary>
public class Scsi
{
// TODO: Get cartridge serial number from Certance vendor EVPD
/// <summary>
/// Dumps a SCSI Block Commands device or a Reduced Block Commands devices
/// </summary>
/// <param name="dev">Device</param>
/// <param name="devicePath">Path to the device</param>
/// <param name="outputPrefix">Prefix for output data files</param>
/// <param name="retryPasses">How many times to retry</param>
/// <param name="force">Force to continue dump whenever possible</param>
/// <param name="dumpRaw">Dump long or scrambled sectors</param>
/// <param name="persistent">Store whatever data the drive returned on error</param>
/// <param name="stopOnError">Stop dump on first error</param>
/// <param name="resume">Information for dump resuming</param>
/// <param name="dumpLog">Dump logger</param>
/// <param name="encoding">Encoding to use when analyzing dump</param>
/// <param name="separateSubchannel">Write subchannel separate from main channel</param>
/// <param name="dumpLeadIn">Try to read and dump as much Lead-in as possible</param>
/// <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,
bool dumpRaw, bool persistent, bool stopOnError, bool separateSubchannel,
ref Resume resume, ref DumpLog dumpLog, bool dumpLeadIn, Encoding encoding)

View File

@@ -48,6 +48,15 @@ namespace DiscImageChef.Core.Devices.Dumping
{
static class Ssc
{
/// <summary>
/// Dumps the tape from a SCSI Streaming device
/// </summary>
/// <param name="dev">Device</param>
/// <param name="devicePath">Path to the device</param>
/// <param name="outputPrefix">Prefix for output data files</param>
/// <param name="resume">Information for dump resuming</param>
/// <param name="dumpLog">Dump logger</param>
/// <param name="sidecar">Partially filled initialized sidecar</param>
internal static void Dump(Device dev, string outputPrefix, string devicePath, ref CICMMetadataType sidecar,
ref Resume resume, ref DumpLog dumpLog)
{

View File

@@ -50,8 +50,26 @@ using MediaType = DiscImageChef.Metadata.MediaType;
namespace DiscImageChef.Core.Devices.Dumping
{
/// <summary>
/// Implements dumping a MultiMediaCard or SecureDigital flash card
/// </summary>
public class SecureDigital
{
/// <summary>
/// Dumps a MultiMediaCard or SecureDigital flash card
/// </summary>
/// <param name="dev">Device</param>
/// <param name="devicePath">Path to the device</param>
/// <param name="outputPrefix">Prefix for output data files</param>
/// <param name="retryPasses">How many times to retry</param>
/// <param name="force">Force to continue dump whenever possible</param>
/// <param name="dumpRaw">Dump long or scrambled sectors</param>
/// <param name="persistent">Store whatever data the drive returned on error</param>
/// <param name="stopOnError">Stop dump on first error</param>
/// <param name="resume">Information for dump resuming</param>
/// <param name="dumpLog">Dump logger</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>
public static void Dump(Device dev, string devicePath, string outputPrefix, ushort retryPasses, bool force,
bool dumpRaw, bool persistent, bool stopOnError, ref Resume resume,
ref DumpLog dumpLog, Encoding encoding)
@@ -280,7 +298,7 @@ namespace DiscImageChef.Core.Devices.Dumping
ResumeSupport.Process(true, false, blocks, dev.Manufacturer, dev.Model, dev.Serial, dev.PlatformId,
ref resume, ref currentTry, ref extents);
if(currentTry == null || extents == null)
throw new Exception("Could not process resume file, not continuing...");
throw new InvalidOperationException("Could not process resume file, not continuing...");
DicConsole.WriteLine("Reading {0} sectors at a time.", blocksToRead);

View File

@@ -53,8 +53,28 @@ using TrackType = Schemas.TrackType;
namespace DiscImageChef.Core.Devices.Dumping
{
/// <summary>
/// Implements dumping an Xbox Game Disc using a Kreon drive
/// </summary>
static class Xgd
{
/// <summary>
/// Dumps an Xbox Game Disc using a Kreon drive
/// </summary>
/// <param name="dev">Device</param>
/// <param name="devicePath">Path to the device</param>
/// <param name="outputPrefix">Prefix for output data files</param>
/// <param name="retryPasses">How many times to retry</param>
/// <param name="force">Force to continue dump whenever possible</param>
/// <param name="dumpRaw">Dump raw/long sectors</param>
/// <param name="persistent">Store whatever data the drive returned on error</param>
/// <param name="stopOnError">Stop dump on first error</param>
/// <param name="resume">Information for dump resuming</param>
/// <param name="dumpLog">Dump logger</param>
/// <param name="encoding">Encoding to use when analyzing dump</param>
/// <param name="sidecar">Partially filled initialized sidecar</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>
internal static void Dump(Device dev, string devicePath, string outputPrefix, ushort retryPasses, bool force,
bool dumpRaw, bool persistent, bool stopOnError, ref CICMMetadataType sidecar,
ref MediaType dskType, ref Resume resume, ref DumpLog dumpLog,
@@ -334,7 +354,7 @@ namespace DiscImageChef.Core.Devices.Dumping
ResumeSupport.Process(true, true, totalSize, dev.Manufacturer, dev.Model, dev.Serial, dev.PlatformId,
ref resume, ref currentTry, ref extents);
if(currentTry == null || extents == null)
throw new Exception("Could not process resume file, not continuing...");
throw new NotImplementedException("Could not process resume file, not continuing...");
ulong currentSector = resume.NextBlock;
dumpFile.Seek(resume.NextBlock, BLOCK_SIZE);

View File

@@ -36,6 +36,9 @@ using DiscImageChef.Devices;
namespace DiscImageChef.Core.Devices
{
/// <summary>
/// Reduces common code used for scanning and dumping
/// </summary>
partial class Reader
{
Device dev;
@@ -48,14 +51,8 @@ namespace DiscImageChef.Core.Devices
internal uint PhysicalBlockSize { get; private set; }
internal uint LongBlockSize { get; private set; }
internal bool CanReadRaw { get; private set; }
internal bool CanSeek
{
get => ataSeek || seek6 || seek10;
}
internal bool CanSeekLba
{
get => ataSeekLba || seek6 || seek10;
}
internal bool CanSeek => ataSeek || seek6 || seek10;
internal bool CanSeekLba => ataSeekLba || seek6 || seek10;
internal Reader(Device dev, uint timeout, byte[] identification, bool raw = false)
{

View File

@@ -39,8 +39,18 @@ using DiscImageChef.Metadata;
namespace DiscImageChef.Core.Devices.Report
{
/// <summary>
/// Implements creating a report for an ATA device
/// </summary>
public static class Ata
{
/// <summary>
/// Creates a report of an ATA device
/// </summary>
/// <param name="dev">Device</param>
/// <param name="report">Device report</param>
/// <param name="debug">If debug is enabled</param>
/// <param name="removable">If device is removable</param>
public static void Report(Device dev, ref DeviceReport report, bool debug, ref bool removable)
{
if(report == null) return;
@@ -60,7 +70,8 @@ namespace DiscImageChef.Core.Devices.Report
if(!Identify.Decode(buffer).HasValue) return;
Identify.IdentifyDevice? ataIdNullable = Identify.Decode(buffer);
if(ataIdNullable != null) {
if(ataIdNullable == null) return;
Identify.IdentifyDevice ataId = ataIdNullable.Value;
ConsoleKeyInfo pressedKey;
@@ -1225,5 +1236,4 @@ namespace DiscImageChef.Core.Devices.Report
}
}
}
}
}

View File

@@ -37,9 +37,18 @@ using DiscImageChef.Metadata;
namespace DiscImageChef.Core.Devices.Report
{
/// <summary>
/// Implements creating a report for an ATAPI device
/// </summary>
static class Atapi
{
internal static void Report(Device dev, ref DeviceReport report, bool debug, ref bool removable)
/// <summary>
/// Fills a SCSI device report with parameters specific to an ATAPI device
/// </summary>
/// <param name="dev">Device</param>
/// <param name="report">Device report</param>
/// <param name="debug">If debug is enabled</param>
internal static void Report(Device dev, ref DeviceReport report, bool debug)
{
if(report == null) return;

View File

@@ -37,8 +37,17 @@ using DiscImageChef.Metadata;
namespace DiscImageChef.Core.Devices.Report
{
/// <summary>
/// Implements creating a report for a FireWire device
/// </summary>
static class FireWire
{
/// <summary>
/// Fills a device report with parameters specific to a FireWire device
/// </summary>
/// <param name="dev">Device</param>
/// <param name="report">Device report</param>
/// <param name="removable">If device is removable</param>
internal static void Report(Device dev, ref DeviceReport report, ref bool removable)
{
if(report == null) return;

View File

@@ -36,8 +36,16 @@ using DiscImageChef.Metadata;
namespace DiscImageChef.Core.Devices.Report
{
/// <summary>
/// Implements creating a report for a PCMCIA device
/// </summary>
static class Pcmcia
{
/// <summary>
/// Fills a device report with parameters specific to a PCMCIA device
/// </summary>
/// <param name="dev">Device</param>
/// <param name="report">Device report</param>
internal static void Report(Device dev, ref DeviceReport report)
{
report.PCMCIA = new pcmciaType {CIS = dev.Cis};

View File

@@ -42,8 +42,18 @@ using DiscImageChef.Metadata;
namespace DiscImageChef.Core.Devices.Report.SCSI
{
/// <summary>
/// Implements creating a report of SCSI and ATAPI devices
/// </summary>
public static class General
{
/// <summary>
/// Creates a report of SCSI and ATAPI devices, and if appropiate calls the report creators for MultiMedia and Streaming devices
/// </summary>
/// <param name="dev">Device</param>
/// <param name="report">Device report</param>
/// <param name="debug">If debug is enabled</param>
/// <param name="removable">If device is removable</param>
public static void Report(Device dev, ref DeviceReport report, bool debug, ref bool removable)
{
if(report == null) return;
@@ -71,7 +81,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
removable = pressedKey.Key == ConsoleKey.Y;
}
if(dev.Type == DeviceType.ATAPI) Atapi.Report(dev, ref report, debug, ref removable);
if(dev.Type == DeviceType.ATAPI) Atapi.Report(dev, ref report, debug);
DicConsole.WriteLine("Querying SCSI INQUIRY...");
sense = dev.ScsiInquiry(out byte[] buffer, out byte[] senseBuffer);
@@ -307,10 +317,8 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
}
}
List<string> mediaTypes = new List<string>();
switch(dev.ScsiType) {
case PeripheralDeviceTypes.MultiMediaDevice: Mmc.Report(dev, ref report, debug, ref cdromMode, ref mediaTypes);
case PeripheralDeviceTypes.MultiMediaDevice: Mmc.Report(dev, ref report, debug, ref cdromMode);
break;
case PeripheralDeviceTypes.SequentialAccess: Ssc.Report(dev, ref report, debug);
break;

View File

@@ -43,16 +43,26 @@ using DiscImageChef.Metadata;
namespace DiscImageChef.Core.Devices.Report.SCSI
{
/// <summary>
/// Implements creating a report for a SCSI MultiMedia device
/// </summary>
static class Mmc
{
internal static void Report(Device dev, ref DeviceReport report, bool debug,
ref Modes.ModePage_2A? cdromMode, ref List<string> mediaTypes)
/// <summary>
/// Fills a SCSI device report with parameters and media tests specific to a MultiMedia device
/// </summary>
/// <param name="dev">Device</param>
/// <param name="report">Device report</param>
/// <param name="debug">If debug is enabled</param>
/// <param name="cdromMode">Decoded MODE PAGE 2Ah</param>
internal static void Report(Device dev, ref DeviceReport report, bool debug, ref Modes.ModePage_2A? cdromMode)
{
if(report == null) return;
bool sense;
const uint TIMEOUT = 5;
List<string> mediaTypes = new List<string>();
report.SCSI.MultiMediaDevice = new mmcType();
if(cdromMode.HasValue)

View File

@@ -41,8 +41,17 @@ using DiscImageChef.Metadata;
namespace DiscImageChef.Core.Devices.Report.SCSI
{
/// <summary>
/// Implements creating a report for a SCSI Streaming device
/// </summary>
static class Ssc
{
/// <summary>
/// Fills a SCSI device report with parameters and media tests specific to a Streaming device
/// </summary>
/// <param name="dev">Device</param>
/// <param name="report">Device report</param>
/// <param name="debug">If debug is enabled</param>
internal static void Report(Device dev, ref DeviceReport report, bool debug)
{
if(report == null) return;

View File

@@ -36,8 +36,16 @@ using DiscImageChef.Metadata;
namespace DiscImageChef.Core.Devices.Report
{
/// <summary>
/// Implements creating a device report for a SecureDigital or MultiMediaCard flash card
/// </summary>
public static class SecureDigital
{
/// <summary>
/// Creates a device report for a SecureDigital or MultiMediaCard flash card
/// </summary>
/// <param name="dev">Device</param>
/// <param name="report">Device report</param>
public static void Report(Device dev, ref DeviceReport report)
{
if(report == null) return;

View File

@@ -37,8 +37,18 @@ using DiscImageChef.Metadata;
namespace DiscImageChef.Core.Devices.Report
{
/// <summary>
/// Implements creating a report for a USB device
/// </summary>
static class Usb
{
/// <summary>
/// Fills a device report with parameters specific to a USB device
/// </summary>
/// <param name="dev">Device</param>
/// <param name="report">Device report</param>
/// <param name="removable">If device is removable</param>
/// <param name="debug">If debug is enabled</param>
internal static void Report(Device dev, ref DeviceReport report, bool debug, ref bool removable)
{
if(report == null) return;

View File

@@ -39,8 +39,19 @@ using DiscImageChef.Devices;
namespace DiscImageChef.Core.Devices.Scanning
{
/// <summary>
/// Implements scanning the media from an ATA device
/// </summary>
public static class Ata
{
/// <summary>
/// Scans the media from an ATA device
/// </summary>
/// <param name="mhddLogPath">Path to a MHDD log file</param>
/// <param name="ibgLogPath">Path to a IMGBurn log file</param>
/// <param name="devicePath">Device path</param>
/// <param name="dev">Device</param>
/// <returns>Scanning results</returns>
public static ScanResults Scan(string mhddLogPath, string ibgLogPath, string devicePath, Device dev)
{
ScanResults results = new ScanResults();

View File

@@ -42,6 +42,9 @@ using DiscImageChef.Devices;
namespace DiscImageChef.Core.Devices.Scanning
{
/// <summary>
/// Implements scanning the media from an SCSI device
/// </summary>
public static class Scsi
{
public static ScanResults Scan(string mhddLogPath, string ibgLogPath, string devicePath, Device dev)

View File

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

View File

@@ -39,6 +39,9 @@ using DiscImageChef.Devices;
namespace DiscImageChef.Core.Devices.Scanning
{
/// <summary>
/// Implements scanning a SecureDigital or MultiMediaCard flash card
/// </summary>
public static class SecureDigital
{
public static ScanResults Scan(string mhddLogPath, string ibgLogPath, string devicePath, Device dev)

View File

@@ -39,6 +39,12 @@ namespace DiscImageChef.Core
{
public static class Filesystems
{
/// <summary>
/// Traverses all known filesystems and outputs a list of all that recognized what is in the specified image and partition
/// </summary>
/// <param name="imagePlugin">Media image</param>
/// <param name="idPlugins">List of plugins recognizing the filesystem</param>
/// <param name="partition">Partition</param>
public static void Identify(ImagePlugin imagePlugin, out List<string> idPlugins, Partition partition)
{
PluginBase plugins = new PluginBase();

View File

@@ -40,6 +40,11 @@ namespace DiscImageChef.Core
{
public static class ImageFormat
{
/// <summary>
/// Detects the image plugin that recognizes the data inside a filter
/// </summary>
/// <param name="imageFilter">Filter</param>
/// <returns>Detected image plugin</returns>
public static ImagePlugin Detect(Filter imageFilter)
{
try

View File

@@ -39,10 +39,18 @@ using PlatformID = DiscImageChef.Interop.PlatformID;
namespace DiscImageChef.Core.Logging
{
/// <summary>
/// Creates a dump log
/// </summary>
public class DumpLog
{
readonly StreamWriter logSw;
/// <summary>
/// Initializes the dump log
/// </summary>
/// <param name="outputFile">Output log file</param>
/// <param name="dev">Device</param>
public DumpLog(string outputFile, Device dev)
{
if(string.IsNullOrEmpty(outputFile)) return;
@@ -113,6 +121,11 @@ namespace DiscImageChef.Core.Logging
logSw.Flush();
}
/// <summary>
/// Adds a new line to the dump log
/// </summary>
/// <param name="format">Format string</param>
/// <param name="args">Arguments</param>
public void WriteLine(string format, params object[] args)
{
if(logSw == null) return;
@@ -122,6 +135,9 @@ namespace DiscImageChef.Core.Logging
logSw.Flush();
}
/// <summary>
/// Finishes and closes the dump log
/// </summary>
public void Close()
{
logSw?.WriteLine("######################################################");

View File

@@ -38,6 +38,9 @@ using DiscImageChef.Devices;
namespace DiscImageChef.Core.Logging
{
/// <summary>
/// Implements a log in the format used by IMGBurn
/// </summary>
class IbgLog
{
StringBuilder ibgSb;
@@ -54,6 +57,11 @@ namespace DiscImageChef.Core.Logging
int ibgSampleRate;
string logFile;
/// <summary>
/// Initializes the IMGBurn log
/// </summary>
/// <param name="outputFile">Log file</param>
/// <param name="currentProfile">Profile as defined by SCSI MultiMedia Commands specification</param>
internal IbgLog(string outputFile, ushort currentProfile)
{
if(string.IsNullOrEmpty(outputFile)) return;
@@ -192,6 +200,11 @@ namespace DiscImageChef.Core.Logging
}
}
/// <summary>
/// Adds a new speed snapshot to the log
/// </summary>
/// <param name="sector">Sector for the snapshot</param>
/// <param name="currentSpeed">Current speed at the snapshot</param>
internal void Write(ulong sector, double currentSpeed)
{
if(logFile == null) return;
@@ -219,6 +232,16 @@ namespace DiscImageChef.Core.Logging
ibgIntSector = sector;
}
/// <summary>
/// Closes the IMGBurn log
/// </summary>
/// <param name="dev">Device</param>
/// <param name="blocks">Media blocks</param>
/// <param name="blockSize">Bytes per block</param>
/// <param name="totalSeconds">Total seconds spent dumping</param>
/// <param name="currentSpeed">Speed at the end</param>
/// <param name="averageSpeed">Average speed</param>
/// <param name="devicePath">Device path</param>
internal void Close(Device dev, ulong blocks, ulong blockSize, double totalSeconds, double currentSpeed,
double averageSpeed, string devicePath)
{

View File

@@ -38,11 +38,22 @@ using DiscImageChef.Devices;
namespace DiscImageChef.Core.Logging
{
/// <summary>
/// Implements a log in the format used by MHDD
/// </summary>
class MhddLog
{
MemoryStream mhddFs;
string logFile;
/// <summary>
/// Initializes the MHDD log
/// </summary>
/// <param name="outputFile">Log file</param>
/// <param name="dev">Device</param>
/// <param name="blocks">Blocks in media</param>
/// <param name="blockSize">Bytes per block</param>
/// <param name="blocksToRead">How many blocks read at once</param>
internal MhddLog(string outputFile, Device dev, ulong blocks, ulong blockSize, ulong blocksToRead)
{
if(dev == null || string.IsNullOrEmpty(outputFile)) return;
@@ -123,6 +134,11 @@ namespace DiscImageChef.Core.Logging
mhddFs.Write(newLine, 0, 2);
}
/// <summary>
/// Logs a new read
/// </summary>
/// <param name="sector">Starting sector</param>
/// <param name="duration">Duration in milliseconds</param>
internal void Write(ulong sector, double duration)
{
if(logFile == null) return;
@@ -134,6 +150,9 @@ namespace DiscImageChef.Core.Logging
mhddFs.Write(durationBytes, 0, 8);
}
/// <summary>
/// Closes and writes to file the MHDD log
/// </summary>
internal void Close()
{
if(logFile == null) return;

View File

@@ -39,8 +39,16 @@ using DiscImageChef.Partitions;
namespace DiscImageChef.Core
{
/// <summary>
/// Implements methods for handling partitions
/// </summary>
public static class Partitions
{
/// <summary>
/// Gets a list of all partitions present in the specified image
/// </summary>
/// <param name="image">Image</param>
/// <returns>List of found partitions</returns>
public static List<Partition> GetAll(ImagePlugin image)
{
PluginBase plugins = new PluginBase();
@@ -136,6 +144,10 @@ namespace DiscImageChef.Core
return childArray.ToList();
}
/// <summary>
/// Adds all partition schemes from the specified list of partitions to statistics
/// </summary>
/// <param name="partitions">List of partitions</param>
public static void AddSchemesToStats(List<Partition> partitions)
{
if(partitions == null || partitions.Count == 0) return;

View File

@@ -41,12 +41,27 @@ using DiscImageChef.Partitions;
namespace DiscImageChef.Core
{
/// <summary>
/// Contain all plugins (filesystem, partition and image)
/// </summary>
public class PluginBase
{
/// <summary>
/// List of all filesystem plugins
/// </summary>
public SortedDictionary<string, Filesystem> PluginsList;
/// <summary>
/// List of all partition plugins
/// </summary>
public SortedDictionary<string, PartitionPlugin> PartPluginsList;
/// <summary>
/// List of all media image plugins
/// </summary>
public SortedDictionary<string, ImagePlugin> ImagePluginsList;
/// <summary>
/// Initializes the plugins lists
/// </summary>
public PluginBase()
{
PluginsList = new SortedDictionary<string, Filesystem>();
@@ -54,6 +69,10 @@ namespace DiscImageChef.Core
ImagePluginsList = new SortedDictionary<string, ImagePlugin>();
}
/// <summary>
/// Fills the plugins lists
/// </summary>
/// <param name="encoding">Which encoding to pass to plugins</param>
public void RegisterAllPlugins(Encoding encoding = null)
{
Assembly assembly = Assembly.GetAssembly(typeof(ImagePlugin));

View File

@@ -39,8 +39,15 @@ using DiscImageChef.Metadata;
namespace DiscImageChef.Core
{
/// <summary>
/// Handles connections to DiscImageChef.Server
/// </summary>
public static class Remote
{
/// <summary>
/// Submits a device report
/// </summary>
/// <param name="report">Device report</param>
public static void SubmitReport(DeviceReport report)
{
Thread submitThread = new Thread(() =>
@@ -50,7 +57,7 @@ namespace DiscImageChef.Core
#if DEBUG
System.Console.WriteLine("Uploading device report");
#else
DicConsole.DebugWriteLine("Submit stats", "Uploading device report");
DiscImageChef.Console.DicConsole.DebugWriteLine("Submit stats", "Uploading device report");
#endif
MemoryStream xmlStream = new MemoryStream();

View File

@@ -41,6 +41,16 @@ namespace DiscImageChef.Core
public static partial class Sidecar
{
// TODO: Complete it
/// <summary>
/// Creates a metadata sidecar for an audio media (e.g. cassette)
/// </summary>
/// <param name="image">Image</param>
/// <param name="filterId">Filter uuid</param>
/// <param name="imagePath">Image path</param>
/// <param name="fi">Image file information</param>
/// <param name="plugins">Image plugins</param>
/// <param name="imgChecksums">List of image checksums</param>
/// <param name="sidecar">Metadata sidecar</param>
static void AudioMedia(ImagePlugin image, Guid filterId, string imagePath, FileInfo fi,
PluginBase plugins, List<ChecksumType> imgChecksums, ref CICMMetadataType sidecar)
{

View File

@@ -50,6 +50,16 @@ namespace DiscImageChef.Core
{
public static partial class Sidecar
{
/// <summary>
/// Creates a metadata sidecar for a block media (e.g. floppy, hard disk, flash card, usb stick)
/// </summary>
/// <param name="image">Image</param>
/// <param name="filterId">Filter uuid</param>
/// <param name="imagePath">Image path</param>
/// <param name="fi">Image file information</param>
/// <param name="plugins">Image plugins</param>
/// <param name="imgChecksums">List of image checksums</param>
/// <param name="sidecar">Metadata sidecar</param>
static void BlockMedia(ImagePlugin image, Guid filterId, string imagePath, FileInfo fi,
PluginBase plugins, List<ChecksumType> imgChecksums, ref CICMMetadataType sidecar)
{

View File

@@ -38,6 +38,12 @@ namespace DiscImageChef.Core
{
public static partial class Sidecar
{
/// <summary>
/// Creates a metadata sidecar for a block tape (e.g. scsi streaming)
/// </summary>
/// <param name="files">List of files</param>
/// <param name="folderName">Dump path</param>
/// <param name="blockSize">Expected block size in bytes</param>
public static CICMMetadataType Create(string folderName, List<string> files, int blockSize)
{
CICMMetadataType sidecar = new CICMMetadataType

View File

@@ -34,6 +34,11 @@ namespace DiscImageChef.Core
{
public static partial class Sidecar
{
/// <summary>
/// Converts a LBA to MM:SS:FF string for CDs
/// </summary>
/// <param name="lba">LBA</param>
/// <returns>MM:SS:FF</returns>
static string LbaToMsf(long lba)
{
long m, s, f;
@@ -57,6 +62,11 @@ namespace DiscImageChef.Core
return $"{m}:{s:D2}:{f:D2}";
}
/// <summary>
/// Converts a LBA to MM:SS:FF string for DDCDs
/// </summary>
/// <param name="lba">LBA</param>
/// <returns>MM:SS:FF</returns>
static string DdcdLbaToMsf(long lba)
{
long h, m, s, f;

View File

@@ -41,6 +41,16 @@ namespace DiscImageChef.Core
public static partial class Sidecar
{
// TODO: Complete it
/// <summary>
/// Creates a metadata sidecar for linear media (e.g. ROM chip)
/// </summary>
/// <param name="image">Image</param>
/// <param name="filterId">Filter uuid</param>
/// <param name="imagePath">Image path</param>
/// <param name="fi">Image file information</param>
/// <param name="plugins">Image plugins</param>
/// <param name="imgChecksums">List of image checksums</param>
/// <param name="sidecar">Metadata sidecar</param>
static void LinearMedia(ImagePlugin image, Guid filterId, string imagePath, FileInfo fi,
PluginBase plugins, List<ChecksumType> imgChecksums, ref CICMMetadataType sidecar)
{

View File

@@ -47,6 +47,16 @@ namespace DiscImageChef.Core
{
public static partial class Sidecar
{
/// <summary>
/// Creates a metadata sidecar for an optical disc (e.g. CD, DVD, GD, BD, XGD, GOD)
/// </summary>
/// <param name="image">Image</param>
/// <param name="filterId">Filter uuid</param>
/// <param name="imagePath">Image path</param>
/// <param name="fi">Image file information</param>
/// <param name="plugins">Image plugins</param>
/// <param name="imgChecksums">List of image checksums</param>
/// <param name="sidecar">Metadata sidecar</param>
static void OpticalDisc(ImagePlugin image, Guid filterId, string imagePath, FileInfo fi,
PluginBase plugins, List<ChecksumType> imgChecksums, ref CICMMetadataType sidecar)
{

View File

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

View File

@@ -44,13 +44,27 @@ using MediaType = DiscImageChef.CommonTypes.MediaType;
namespace DiscImageChef.Core
{
/// <summary>
/// Handles anonymous usage statistics
/// </summary>
public static class Statistics
{
/// <summary>
/// Contains all known statistics
/// </summary>
public static Stats AllStats;
/// <summary>
/// Contains statistics of current execution
/// </summary>
public static Stats CurrentStats;
/// <summary>
/// Statistics file semaphore
/// </summary>
static bool submitStatsLock;
/// <summary>
/// Loads saved statistics from disk
/// </summary>
public static void LoadStats()
{
if(File.Exists(Path.Combine(Settings.Settings.StatsPath, "Statistics.xml")))
@@ -100,6 +114,9 @@ namespace DiscImageChef.Core
}
}
/// <summary>
/// Saves statistics to disk
/// </summary>
public static void SaveStats()
{
if(AllStats == null) return;
@@ -165,6 +182,9 @@ namespace DiscImageChef.Core
if(Settings.Settings.Current.Stats.ShareStats) SubmitStats();
}
/// <summary>
/// Submits statistics to DiscImageChef.Server
/// </summary>
public static void SubmitStats()
{
Thread submitThread = new Thread(() =>
@@ -187,7 +207,7 @@ namespace DiscImageChef.Core
#if DEBUG
System.Console.WriteLine("Uploading partial statistics file {0}", statsFile);
#else
DicConsole.DebugWriteLine("Submit stats", "Uploading partial statistics file {0}", statsFile);
DiscImageChef.Console.DicConsole.DebugWriteLine("Submit stats", "Uploading partial statistics file {0}", statsFile);
#endif
FileStream fs = new FileStream(statsFile, FileMode.Open, FileAccess.Read);
@@ -237,6 +257,10 @@ namespace DiscImageChef.Core
submitThread.Start();
}
/// <summary>
/// Adds the execution of a command to statistics
/// </summary>
/// <param name="command">Command</param>
public static void AddCommand(string command)
{
if(Settings.Settings.Current.Stats == null || !Settings.Settings.Current.Stats.DeviceStats) return;
@@ -326,6 +350,10 @@ namespace DiscImageChef.Core
}
}
/// <summary>
/// Adds a new filesystem to statistics
/// </summary>
/// <param name="filesystem">Filesystem name</param>
public static void AddFilesystem(string filesystem)
{
if(Settings.Settings.Current.Stats == null || !Settings.Settings.Current.Stats.FilesystemStats) return;
@@ -366,6 +394,10 @@ namespace DiscImageChef.Core
CurrentStats.Filesystems.Add(nw);
}
/// <summary>
/// Adds a new partition scheme to statistics
/// </summary>
/// <param name="partition">Partition scheme name</param>
internal static void AddPartition(string partition)
{
if(Settings.Settings.Current.Stats == null || !Settings.Settings.Current.Stats.PartitionStats) return;
@@ -406,6 +438,10 @@ namespace DiscImageChef.Core
CurrentStats.Partitions.Add(nw);
}
/// <summary>
/// Adds a new filter to statistics
/// </summary>
/// <param name="format">Filter name</param>
public static void AddFilter(string format)
{
if(Settings.Settings.Current.Stats == null || !Settings.Settings.Current.Stats.FilterStats) return;
@@ -446,6 +482,10 @@ namespace DiscImageChef.Core
CurrentStats.Filters.Add(nw);
}
/// <summary>
/// Ads a new media image to statistics
/// </summary>
/// <param name="format">Media image name</param>
public static void AddMediaFormat(string format)
{
if(Settings.Settings.Current.Stats == null || !Settings.Settings.Current.Stats.MediaImageStats) return;
@@ -486,6 +526,10 @@ namespace DiscImageChef.Core
CurrentStats.MediaImages.Add(nw);
}
/// <summary>
/// Adds a new device to statistics
/// </summary>
/// <param name="dev">Device</param>
public static void AddDevice(Device dev)
{
if(Settings.Settings.Current.Stats == null || !Settings.Settings.Current.Stats.DeviceStats) return;
@@ -527,6 +571,11 @@ namespace DiscImageChef.Core
CurrentStats.Devices.Add(nw);
}
/// <summary>
/// Adds a new media type to statistics
/// </summary>
/// <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>
public static void AddMedia(MediaType type, bool real)
{
if(Settings.Settings.Current.Stats == null || !Settings.Settings.Current.Stats.MediaStats) return;
@@ -571,6 +620,15 @@ namespace DiscImageChef.Core
CurrentStats.Medias.Add(nw);
}
/// <summary>
/// Adds benchmark results to statistics
/// </summary>
/// <param name="checksums">Checksum times</param>
/// <param name="entropy">Entropy times</param>
/// <param name="all">Time for all running togheter</param>
/// <param name="sequential">Time for sequential running</param>
/// <param name="maxMemory">Maximum used memory</param>
/// <param name="minMemory">Minimum used memory</param>
public static void AddBenchmark(Dictionary<string, double> checksums, double entropy, double all,
double sequential, long maxMemory, long minMemory)
{
@@ -597,6 +655,14 @@ namespace DiscImageChef.Core
AllStats.Benchmark.Sequential = sequential;
}
/// <summary>
/// Adds a new media image verification to statistics
/// </summary>
/// <param name="mediaVerified">Set if media was correctly verified</param>
/// <param name="correct">How many sectors where verified correctly</param>
/// <param name="failed">How many sectors failed verification</param>
/// <param name="unknown">How many sectors could not be verified</param>
/// <param name="total">Total sectors verified</param>
public static void AddVerify(bool? mediaVerified, long correct, long failed, long unknown, long total)
{
if(Settings.Settings.Current.Stats == null || !Settings.Settings.Current.Stats.VerifyStats) return;
@@ -633,6 +699,18 @@ namespace DiscImageChef.Core
AllStats.Verify.Sectors.Total += total;
}
/// <summary>
/// Adds a new media scan to statistics
/// </summary>
/// <param name="lessThan3ms">Sectors &lt;3ms</param>
/// <param name="lessThan10ms">Sectors &gt;3ms and &lt;10ms</param>
/// <param name="lessThan50ms">Sectors &gt;10ms and &lt;50ms</param>
/// <param name="lessThan150ms">Sectors &gt;50ms and &lt;150ms</param>
/// <param name="lessThan500ms">Sectors &gt;150ms and &lt;500ms</param>
/// <param name="moreThan500ms">Sectors &gt;500ms</param>
/// <param name="total">Total sectors</param>
/// <param name="error">Errored sectors</param>
/// <param name="correct">Correct sectors</param>
public static void AddMediaScan(long lessThan3ms, long lessThan10ms, long lessThan50ms, long lessThan150ms,
long lessThan500ms, long moreThan500ms, long total, long error, long correct)
{

View File

@@ -37,8 +37,14 @@ namespace DiscImageChef.Core
{
static class Version
{
/// <summary>
/// Gets XML software type for the running version
/// </summary>
/// <param name="platform">Platform we are running in</param>
/// <returns>XML software type</returns>
internal static SoftwareType GetSoftwareType(PlatformID platform)
{
// TODO: Platform should be get automatically
return new SoftwareType
{
Name = "DiscImageChef",
@@ -47,6 +53,10 @@ namespace DiscImageChef.Core
};
}
/// <summary>
/// Gets version string
/// </summary>
/// <returns>Version</returns>
internal static string GetVersion()
{
return typeof(Version).Assembly.GetName().Version.ToString();