diff --git a/DiscImageChef.Checksums/Adler32Context.cs b/DiscImageChef.Checksums/Adler32Context.cs index 418db2d2..a0c4c236 100644 --- a/DiscImageChef.Checksums/Adler32Context.cs +++ b/DiscImageChef.Checksums/Adler32Context.cs @@ -36,6 +36,9 @@ using System.Text; namespace DiscImageChef.Checksums { + /// + /// Implements the Adler-32 algorithm + /// public class Adler32Context { ushort sum1, sum2; diff --git a/DiscImageChef.Checksums/CDChecksums.cs b/DiscImageChef.Checksums/CDChecksums.cs index 7b963dc0..45478af2 100644 --- a/DiscImageChef.Checksums/CDChecksums.cs +++ b/DiscImageChef.Checksums/CDChecksums.cs @@ -37,6 +37,9 @@ using DiscImageChef.Console; namespace DiscImageChef.Checksums { + /// + /// Implements ReedSolomon and CRC32 algorithms as used by CD-ROM + /// public static class CdChecksums { static byte[] eccFTable; diff --git a/DiscImageChef.Checksums/CRC16Context.cs b/DiscImageChef.Checksums/CRC16Context.cs index ecd9bd4d..389ef624 100644 --- a/DiscImageChef.Checksums/CRC16Context.cs +++ b/DiscImageChef.Checksums/CRC16Context.cs @@ -37,7 +37,7 @@ using System.Text; namespace DiscImageChef.Checksums { /// - /// Provides a UNIX similar API to calculate CRC16. + /// Implements a CRC16-CCITT algorithm /// public class Crc16Context { diff --git a/DiscImageChef.Checksums/CRC32Context.cs b/DiscImageChef.Checksums/CRC32Context.cs index 7ad121d7..26b54396 100644 --- a/DiscImageChef.Checksums/CRC32Context.cs +++ b/DiscImageChef.Checksums/CRC32Context.cs @@ -37,7 +37,7 @@ using System.Text; namespace DiscImageChef.Checksums { /// - /// Provides a UNIX similar API to calculate CRC32. + /// Implements a CRC32 algorithm /// public class Crc32Context { diff --git a/DiscImageChef.Checksums/CRC64Context.cs b/DiscImageChef.Checksums/CRC64Context.cs index 7a26a651..2294e5ca 100644 --- a/DiscImageChef.Checksums/CRC64Context.cs +++ b/DiscImageChef.Checksums/CRC64Context.cs @@ -36,7 +36,7 @@ using System.Text; namespace DiscImageChef.Checksums { /// - /// Provides a UNIX similar API to calculate CRC64 (ECMA). + /// Implements a CRC64 (ECMA) algorithm /// public class Crc64Context { diff --git a/DiscImageChef.Checksums/FletcherContext.cs b/DiscImageChef.Checksums/FletcherContext.cs index 13982c8a..da63771f 100644 --- a/DiscImageChef.Checksums/FletcherContext.cs +++ b/DiscImageChef.Checksums/FletcherContext.cs @@ -40,12 +40,12 @@ namespace DiscImageChef.Checksums { public class Fletcher32Context { - UInt16 sum1, sum2; - byte oddValue; bool inodd; + byte oddValue; + ushort sum1, sum2; /// - /// Initializes the Fletcher32 sums + /// Initializes the Fletcher32 sums /// public void Init() { @@ -56,16 +56,14 @@ namespace DiscImageChef.Checksums } /// - /// Updates the hash with data. + /// Updates the hash with data. /// /// Data buffer. /// Length of buffer to hash. 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,11 +82,10 @@ 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 else { @@ -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,15 +116,15 @@ 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); } } } } /// - /// Updates the hash with data. + /// Updates the hash with data. /// /// Data buffer. public void Update(byte[] data) @@ -136,68 +133,62 @@ namespace DiscImageChef.Checksums } /// - /// Returns a byte array of the hash value. + /// Returns a byte array of the hash value. /// public byte[] Final() { - UInt32 finalSum = (UInt32)(sum1 + (sum2 << 16)); + uint finalSum = (uint)(sum1 + (sum2 << 16)); return BigEndianBitConverter.GetBytes(finalSum); } /// - /// Returns a hexadecimal representation of the hash value. + /// Returns a hexadecimal representation of the hash value. /// 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(); } /// - /// Gets the hash of a file + /// Gets the hash of a file /// /// File path. public static byte[] File(string filename) { - byte[] hash; - File(filename, out hash); + File(filename, out byte[] hash); return hash; } /// - /// Gets the hash of a file in hexadecimal and as a byte array. + /// Gets the hash of a file in hexadecimal and as a byte array. /// /// File path. /// Byte array of the hash value. 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 { for(int i = 0; i < fileStream.Length - 1; i += 2) @@ -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,55 +205,49 @@ 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(); } /// - /// Gets the hash of the specified data buffer. + /// Gets the hash of the specified data buffer. /// /// Data buffer. /// Length of the data buffer to hash. /// Byte array of the hash value. 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,26 +255,23 @@ 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(); } /// - /// Gets the hash of the specified data buffer. + /// Gets the hash of the specified data buffer. /// /// Data buffer. /// Byte array of the hash value. @@ -304,7 +286,7 @@ namespace DiscImageChef.Checksums byte sum1, sum2; /// - /// Initializes the Fletcher16 sums + /// Initializes the Fletcher16 sums /// public void Init() { @@ -313,7 +295,7 @@ namespace DiscImageChef.Checksums } /// - /// Updates the hash with data. + /// Updates the hash with data. /// /// Data buffer. /// Length of buffer to hash. @@ -327,7 +309,7 @@ namespace DiscImageChef.Checksums } /// - /// Updates the hash with data. + /// Updates the hash with data. /// /// Data buffer. public void Update(byte[] data) @@ -336,43 +318,40 @@ namespace DiscImageChef.Checksums } /// - /// Returns a byte array of the hash value. + /// Returns a byte array of the hash value. /// public byte[] Final() { - UInt16 finalSum = (UInt16)(sum1 + (sum2 << 8)); + ushort finalSum = (ushort)(sum1 + (sum2 << 8)); return BigEndianBitConverter.GetBytes(finalSum); } /// - /// Returns a hexadecimal representation of the hash value. + /// Returns a hexadecimal representation of the hash value. /// 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(); } /// - /// Gets the hash of a file + /// Gets the hash of a file /// /// File path. public static byte[] File(string filename) { - byte[] hash; - File(filename, out hash); + File(filename, out byte[] hash); return hash; } /// - /// Gets the hash of a file in hexadecimal and as a byte array. + /// Gets the hash of a file in hexadecimal and as a byte array. /// /// File path. /// Byte array of the hash value. @@ -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,22 +371,19 @@ 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(); } /// - /// Gets the hash of the specified data buffer. + /// Gets the hash of the specified data buffer. /// /// Data buffer. /// Length of the data buffer to hash. @@ -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,22 +402,19 @@ 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(); } /// - /// Gets the hash of the specified data buffer. + /// Gets the hash of the specified data buffer. /// /// Data buffer. /// Byte array of the hash value. @@ -451,6 +423,4 @@ namespace DiscImageChef.Checksums return Data(data, (uint)data.Length, out hash); } } -} -*/ - +}*/ \ No newline at end of file diff --git a/DiscImageChef.Checksums/MD5Context.cs b/DiscImageChef.Checksums/MD5Context.cs index 81e08930..c43aece5 100644 --- a/DiscImageChef.Checksums/MD5Context.cs +++ b/DiscImageChef.Checksums/MD5Context.cs @@ -37,7 +37,7 @@ using System.Text; namespace DiscImageChef.Checksums { /// - /// Provides a UNIX similar API to .NET MD5. + /// Wraps up .NET MD5 implementation to a Init(), Update(), Final() context. /// public class Md5Context { diff --git a/DiscImageChef.Checksums/RIPEMD160Context.cs b/DiscImageChef.Checksums/RIPEMD160Context.cs index 6fe08083..ec246e9e 100644 --- a/DiscImageChef.Checksums/RIPEMD160Context.cs +++ b/DiscImageChef.Checksums/RIPEMD160Context.cs @@ -37,7 +37,7 @@ using System.Text; namespace DiscImageChef.Checksums { /// - /// Provides a UNIX similar API to .NET RIPEMD160. + /// Wraps up .NET RIPEMD160 implementation to a Init(), Update(), Final() context. /// public class Ripemd160Context { diff --git a/DiscImageChef.Checksums/ReedSolomon.cs b/DiscImageChef.Checksums/ReedSolomon.cs index 89b4b6e6..c93d0d98 100644 --- a/DiscImageChef.Checksums/ReedSolomon.cs +++ b/DiscImageChef.Checksums/ReedSolomon.cs @@ -62,6 +62,9 @@ using DiscImageChef.Console; namespace DiscImageChef.Checksums { + /// + /// Implements the Reed-Solomon algorithm + /// public class ReedSolomon { /* Primitive polynomials - see Lin & Costello, Error Control Coding Appendix A, diff --git a/DiscImageChef.Checksums/SHA1Context.cs b/DiscImageChef.Checksums/SHA1Context.cs index 6f6544c6..f8dcea1c 100644 --- a/DiscImageChef.Checksums/SHA1Context.cs +++ b/DiscImageChef.Checksums/SHA1Context.cs @@ -37,7 +37,7 @@ using System.Text; namespace DiscImageChef.Checksums { /// - /// Provides a UNIX similar API to .NET SHA1. + /// Wraps up .NET SHA1 implementation to a Init(), Update(), Final() context. /// public class Sha1Context { diff --git a/DiscImageChef.Checksums/SHA256Context.cs b/DiscImageChef.Checksums/SHA256Context.cs index a2453105..146c3801 100644 --- a/DiscImageChef.Checksums/SHA256Context.cs +++ b/DiscImageChef.Checksums/SHA256Context.cs @@ -37,7 +37,7 @@ using System.Text; namespace DiscImageChef.Checksums { /// - /// Provides a UNIX similar API to .NET SHA256. + /// Wraps up .NET SHA256 implementation to a Init(), Update(), Final() context. /// public class Sha256Context { diff --git a/DiscImageChef.Checksums/SHA384Context.cs b/DiscImageChef.Checksums/SHA384Context.cs index ee0cd3eb..e2a21cf3 100644 --- a/DiscImageChef.Checksums/SHA384Context.cs +++ b/DiscImageChef.Checksums/SHA384Context.cs @@ -37,7 +37,7 @@ using System.Text; namespace DiscImageChef.Checksums { /// - /// Provides a UNIX similar API to .NET SHA384. + /// Wraps up .NET SHA384 implementation to a Init(), Update(), Final() context. /// public class Sha384Context { diff --git a/DiscImageChef.Checksums/SHA512Context.cs b/DiscImageChef.Checksums/SHA512Context.cs index 2ad824ef..dbaa42c7 100644 --- a/DiscImageChef.Checksums/SHA512Context.cs +++ b/DiscImageChef.Checksums/SHA512Context.cs @@ -37,7 +37,7 @@ using System.Text; namespace DiscImageChef.Checksums { /// - /// Provides a UNIX similar API to .NET SHA512. + /// Wraps up .NET SHA512 implementation to a Init(), Update(), Final() context. /// public class Sha512Context { diff --git a/DiscImageChef.Checksums/SpamSumContext.cs b/DiscImageChef.Checksums/SpamSumContext.cs index 72e5b490..52030a62 100644 --- a/DiscImageChef.Checksums/SpamSumContext.cs +++ b/DiscImageChef.Checksums/SpamSumContext.cs @@ -45,7 +45,7 @@ using System.Text; namespace DiscImageChef.Checksums { /// - /// Provides a UNIX similar API to calculate Fuzzy Hash (SpamSum). + /// Implements the SpamSum fuzzy hashing algorithm. /// public class SpamSumContext { diff --git a/DiscImageChef.CommonTypes/MediaType.cs b/DiscImageChef.CommonTypes/MediaType.cs index 635df2c9..ccd57e47 100644 --- a/DiscImageChef.CommonTypes/MediaType.cs +++ b/DiscImageChef.CommonTypes/MediaType.cs @@ -34,7 +34,9 @@ // TODO: Rename contents namespace DiscImageChef.CommonTypes { - // Media (disk, cartridge, tape, cassette, etc) types + /// + /// Contains an enumeration of all known types of media. + /// public enum MediaType { /// Unknown disk type diff --git a/DiscImageChef.CommonTypes/MediaTypeFromSCSI.cs b/DiscImageChef.CommonTypes/MediaTypeFromSCSI.cs index 23e638e6..3f9d011f 100644 --- a/DiscImageChef.CommonTypes/MediaTypeFromSCSI.cs +++ b/DiscImageChef.CommonTypes/MediaTypeFromSCSI.cs @@ -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 { + /// + /// Tries to guess, from SCSI information, the media type of a device and/or its inserted media + /// + /// The SCSI Peripheral Type as indicated in the INQUIRY response + /// The vendor string of the device + /// The model string of the device + /// The medium type byte from MODE SENSE + /// The density type byte from MODE SENSE + /// How many blocks are on the media + /// Size in bytes of each block + /// public static MediaType Get(byte scsiPeripheralType, string vendor, string model, byte mediumType, byte densityCode, ulong blocks, uint blockSize) { diff --git a/DiscImageChef.CommonTypes/Partition.cs b/DiscImageChef.CommonTypes/Partition.cs index e931bc71..2494d47a 100644 --- a/DiscImageChef.CommonTypes/Partition.cs +++ b/DiscImageChef.CommonTypes/Partition.cs @@ -56,13 +56,15 @@ namespace DiscImageChef.CommonTypes /// Information that does not find space in this struct public string Description; /// LBA of last partition sector - public ulong End - { - get => Start + Length - 1; - } + public ulong End => Start + Length - 1; /// Name of partition scheme that contains this partition public string Scheme; + /// + /// Compares two partitions + /// + /// Partition to compare with + /// 0 if both partitions start and end at the same sector public bool Equals(Partition other) { return Start == other.Start && Length == other.Length; @@ -80,6 +82,11 @@ namespace DiscImageChef.CommonTypes return Start.GetHashCode() + End.GetHashCode(); } + /// + /// 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. + /// + /// Partition to compare with + /// A value that indicates the relative equality of the partitions being compared. public int CompareTo(Partition other) { if(Start == other.Start && End == other.End) return 0; diff --git a/DiscImageChef.Console/DicConsole.cs b/DiscImageChef.Console/DicConsole.cs index 4e0823f5..336ce373 100644 --- a/DiscImageChef.Console/DicConsole.cs +++ b/DiscImageChef.Console/DicConsole.cs @@ -48,6 +48,9 @@ namespace DiscImageChef.Console public delegate void DebugWriteHandler(string format, params object[] arg); + /// + /// Implements a console abstraction that defines four level of messages that can be routed to different consoles: standard, error, verbose and debug. + /// public static class DicConsole { public static event WriteLineHandler WriteLineEvent; diff --git a/DiscImageChef.Core/Benchmark.cs b/DiscImageChef.Core/Benchmark.cs index 8bb31aca..2c2bfee1 100644 --- a/DiscImageChef.Core/Benchmark.cs +++ b/DiscImageChef.Core/Benchmark.cs @@ -61,6 +61,9 @@ namespace DiscImageChef.Core public double Speed; } + /// + /// Benchmarks the speed at which we can do checksums + /// public static class Benchmark { public static event InitProgressHandler InitProgressEvent; diff --git a/DiscImageChef.Core/Checksum.cs b/DiscImageChef.Core/Checksum.cs index e0086b2d..22403412 100644 --- a/DiscImageChef.Core/Checksum.cs +++ b/DiscImageChef.Core/Checksum.cs @@ -55,6 +55,9 @@ namespace DiscImageChef.Core All = Adler32 | Crc16 | Crc32 | Crc64 | Md5 | Ripemd160 | Sha1 | Sha256 | Sha384 | Sha512 | SpamSum } + /// + /// Checksums and hashes data, with different algorithms multithreaded + /// public class Checksum { Adler32Context adler32Ctx; diff --git a/DiscImageChef.Core/DataFile.cs b/DiscImageChef.Core/DataFile.cs index e7a7976c..534ae761 100644 --- a/DiscImageChef.Core/DataFile.cs +++ b/DiscImageChef.Core/DataFile.cs @@ -30,77 +30,154 @@ // Copyright © 2011-2018 Natalia Portillo // ****************************************************************************/ +using System.Diagnostics.CodeAnalysis; using System.IO; using DiscImageChef.Console; namespace DiscImageChef.Core { + /// + /// Abstracts a datafile with a block based interface + /// + [SuppressMessage("ReSharper", "UnusedMethodReturnValue.Global")] public class DataFile { FileStream dataFs; + /// + /// Opens, or create, a new file + /// + /// File public DataFile(string outputFile) { dataFs = new FileStream(outputFile, FileMode.OpenOrCreate, FileAccess.ReadWrite); } + /// + /// Closes the file + /// public void Close() { dataFs?.Close(); } + /// + /// Reads bytes at current position + /// + /// Array to place read data within + /// Offset of where data will be read + /// How many bytes to read + /// How many bytes were read public int Read(byte[] array, int offset, int count) { return dataFs.Read(array, offset, count); } + /// + /// Seeks to the specified block + /// + /// Block to seek to + /// Block size in bytes + /// Position public long Seek(ulong block, ulong blockSize) { return dataFs.Seek((long)(block * blockSize), SeekOrigin.Begin); } + /// + /// Seeks to specified byte position + /// + /// Byte position + /// Where to count for position + /// Position public long Seek(ulong offset, SeekOrigin origin) { return dataFs.Seek((long)offset, origin); } + /// + /// Seeks to specified byte position + /// + /// Byte position + /// Where to count for position + /// Position public long Seek(long offset, SeekOrigin origin) { return dataFs.Seek(offset, origin); } + /// + /// Writes data at current position + /// + /// Data public void Write(byte[] data) { Write(data, 0, data.Length); } + /// + /// Writes data at current position + /// + /// Data + /// Offset of data from where to start taking data to write + /// How many bytes to write public void Write(byte[] data, int offset, int count) { dataFs.Write(data, offset, count); } + /// + /// Writes data at specified block + /// + /// Data + /// Block + /// Bytes per block public void WriteAt(byte[] data, ulong block, uint blockSize) { WriteAt(data, block, blockSize, 0, data.Length); } + /// + /// Writes data at specified block + /// + /// Data + /// Block + /// Bytes per block + /// Offset of data from where to start taking data to write + /// How many bytes to write 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; - } + /// + /// Current file position + /// + public long Position => dataFs.Position; - public static void WriteTo(string who, string outputPrefix, string outputSuffix, string what, byte[] data) + /// + /// Writes data to a newly created file + /// + /// Who asked the file to be written (class, plugin, etc.) + /// Data to write + /// First part of the file name + /// Last part of the file name + /// What is the data about? + 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); } + /// + /// Writes data to a newly created file + /// + /// Who asked the file to be written (class, plugin, etc.) + /// Filename to create + /// Data to write + /// What is the data about? + /// If set to true overwrites the file, does nothing otherwise public static void WriteTo(string who, string filename, byte[] data, string whatWriting = null, bool overwrite = false) { diff --git a/DiscImageChef.Core/Devices/Dumping/ATA.cs b/DiscImageChef.Core/Devices/Dumping/ATA.cs index 42b1a7c6..38f45151 100644 --- a/DiscImageChef.Core/Devices/Dumping/ATA.cs +++ b/DiscImageChef.Core/Devices/Dumping/ATA.cs @@ -52,8 +52,26 @@ using Tuple = DiscImageChef.Decoders.PCMCIA.Tuple; namespace DiscImageChef.Core.Devices.Dumping { + /// + /// Implements dumping ATA devices + /// public class Ata { + /// + /// Dumps an ATA device + /// + /// Device + /// Path to the device + /// Prefix for output data files + /// How many times to retry + /// Force to continue dump whenever possible + /// Dump long sectors + /// Store whatever data the drive returned on error + /// Stop dump on first error + /// Information for dump resuming + /// Dump logger + /// Encoding to use when analyzing dump + /// If the resume file is invalid 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; diff --git a/DiscImageChef.Core/Devices/Dumping/CompactDisc.cs b/DiscImageChef.Core/Devices/Dumping/CompactDisc.cs index 029def28..88582a3e 100644 --- a/DiscImageChef.Core/Devices/Dumping/CompactDisc.cs +++ b/DiscImageChef.Core/Devices/Dumping/CompactDisc.cs @@ -52,8 +52,32 @@ using TrackType = Schemas.TrackType; namespace DiscImageChef.Core.Devices.Dumping { + /// + /// Implement dumping Compact Discs + /// class CompactDisc { + /// + /// Dumps a compact disc + /// + /// Device + /// Path to the device + /// Prefix for output data files + /// How many times to retry + /// Force to continue dump whenever possible + /// Dump scrambled sectors + /// Store whatever data the drive returned on error + /// Stop dump on first error + /// Information for dump resuming + /// Dump logger + /// Partially filled initialized sidecar + /// Disc type as detected in MMC layer + /// Write subchannel separate from main channel + /// Alcohol disc image already initialized + /// Try to read and dump as much Lead-in as possible + /// If trying to dump scrambled sectors + /// If the resume file is invalid + /// If the track type is unknown (never) 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) { diff --git a/DiscImageChef.Core/Devices/Dumping/MMC.cs b/DiscImageChef.Core/Devices/Dumping/MMC.cs index 678aa6a1..887fbbfd 100644 --- a/DiscImageChef.Core/Devices/Dumping/MMC.cs +++ b/DiscImageChef.Core/Devices/Dumping/MMC.cs @@ -48,8 +48,30 @@ using Spare = DiscImageChef.Decoders.DVD.Spare; namespace DiscImageChef.Core.Devices.Dumping { + /// + /// Implement dumping optical discs from MultiMedia devices + /// static class Mmc { + /// + /// Dumps an optical disc + /// + /// Device + /// Path to the device + /// Prefix for output data files + /// How many times to retry + /// Force to continue dump whenever possible + /// Dump raw/long sectors + /// Store whatever data the drive returned on error + /// Stop dump on first error + /// Information for dump resuming + /// Dump logger + /// Encoding to use when analyzing dump + /// Partially filled initialized sidecar + /// Disc type as detected in MMC layer + /// Write subchannel separate from main channel + /// Try to read and dump as much Lead-in as possible + /// If trying to dump GOD or WOD, or XGDs without a Kreon drive 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, diff --git a/DiscImageChef.Core/Devices/Dumping/ResumeSupport.cs b/DiscImageChef.Core/Devices/Dumping/ResumeSupport.cs index 62b904e4..6b5ef757 100644 --- a/DiscImageChef.Core/Devices/Dumping/ResumeSupport.cs +++ b/DiscImageChef.Core/Devices/Dumping/ResumeSupport.cs @@ -39,8 +39,26 @@ using PlatformID = DiscImageChef.Interop.PlatformID; namespace DiscImageChef.Core.Devices.Dumping { + /// + /// Implements resume support + /// static class ResumeSupport { + /// + /// Process resume + /// + /// If drive is LBA + /// If media is removable from device + /// Media blocks + /// Device manufacturer + /// Device model + /// Device serial + /// Platform where the dump is made + /// Previous resume, or null + /// Current dumping hardware + /// Dumped extents + /// If device uses CHS addressing + /// If the provided resume does not correspond with the current in progress dump 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) - throw new - Exception($"Resume file specifies a device manufactured by {oldtry.Manufacturer} but you're requesting to dump one by {manufacturer}, not continuing..."); + if(!removable) + { + if(oldtry.Manufacturer != manufacturer) + throw new + 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) - throw new - Exception($"Resume file specifies a device model {oldtry.Model} but you're requesting to dump model {model}, not continuing..."); + if(oldtry.Model != model) + throw new + InvalidOperationException($"Resume file specifies a device model {oldtry.Model} but you're requesting to dump model {model}, not continuing..."); - if(oldtry.Serial != serial && !removable) - throw new - Exception($"Resume file specifies a device with serial {oldtry.Serial} but you're requesting to dump one with serial {serial}, not continuing..."); + if(oldtry.Serial != serial) + throw new + 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() || diff --git a/DiscImageChef.Core/Devices/Dumping/SBC.cs b/DiscImageChef.Core/Devices/Dumping/SBC.cs index 702afb4c..e1716692 100644 --- a/DiscImageChef.Core/Devices/Dumping/SBC.cs +++ b/DiscImageChef.Core/Devices/Dumping/SBC.cs @@ -53,8 +53,30 @@ using TrackType = DiscImageChef.DiscImages.TrackType; namespace DiscImageChef.Core.Devices.Dumping { + /// + /// Implements dumping SCSI Block Commands and Reduced Block Commands devices + /// static class Sbc { + /// + /// Dumps a SCSI Block Commands device or a Reduced Block Commands devices + /// + /// Device + /// Path to the device + /// Prefix for output data files + /// How many times to retry + /// Force to continue dump whenever possible + /// Dump long or scrambled sectors + /// Store whatever data the drive returned on error + /// Stop dump on first error + /// Information for dump resuming + /// Dump logger + /// Encoding to use when analyzing dump + /// If device contains an optical disc (e.g. DVD or BD) + /// Partially filled initialized sidecar + /// Disc type as detected in SCSI or MMC layer + /// Alcohol disc image already initialized for optical discs, null otherwise + /// If the resume file is invalid 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); diff --git a/DiscImageChef.Core/Devices/Dumping/SCSI.cs b/DiscImageChef.Core/Devices/Dumping/SCSI.cs index 5adec3ff..9d70dcf4 100644 --- a/DiscImageChef.Core/Devices/Dumping/SCSI.cs +++ b/DiscImageChef.Core/Devices/Dumping/SCSI.cs @@ -43,9 +43,29 @@ using MediaType = DiscImageChef.CommonTypes.MediaType; namespace DiscImageChef.Core.Devices.Dumping { + /// + /// Implements dumping SCSI and ATAPI devices + /// public class Scsi { // TODO: Get cartridge serial number from Certance vendor EVPD + /// + /// Dumps a SCSI Block Commands device or a Reduced Block Commands devices + /// + /// Device + /// Path to the device + /// Prefix for output data files + /// How many times to retry + /// Force to continue dump whenever possible + /// Dump long or scrambled sectors + /// Store whatever data the drive returned on error + /// Stop dump on first error + /// Information for dump resuming + /// Dump logger + /// Encoding to use when analyzing dump + /// Write subchannel separate from main channel + /// Try to read and dump as much Lead-in as possible + /// If you asked to dump long sectors from a SCSI Streaming device 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) diff --git a/DiscImageChef.Core/Devices/Dumping/SSC.cs b/DiscImageChef.Core/Devices/Dumping/SSC.cs index baad6ed7..05e0218d 100644 --- a/DiscImageChef.Core/Devices/Dumping/SSC.cs +++ b/DiscImageChef.Core/Devices/Dumping/SSC.cs @@ -48,6 +48,15 @@ namespace DiscImageChef.Core.Devices.Dumping { static class Ssc { + /// + /// Dumps the tape from a SCSI Streaming device + /// + /// Device + /// Path to the device + /// Prefix for output data files + /// Information for dump resuming + /// Dump logger + /// Partially filled initialized sidecar internal static void Dump(Device dev, string outputPrefix, string devicePath, ref CICMMetadataType sidecar, ref Resume resume, ref DumpLog dumpLog) { diff --git a/DiscImageChef.Core/Devices/Dumping/SecureDigital.cs b/DiscImageChef.Core/Devices/Dumping/SecureDigital.cs index 417496da..3f0e2732 100644 --- a/DiscImageChef.Core/Devices/Dumping/SecureDigital.cs +++ b/DiscImageChef.Core/Devices/Dumping/SecureDigital.cs @@ -50,8 +50,26 @@ using MediaType = DiscImageChef.Metadata.MediaType; namespace DiscImageChef.Core.Devices.Dumping { + /// + /// Implements dumping a MultiMediaCard or SecureDigital flash card + /// public class SecureDigital { + /// + /// Dumps a MultiMediaCard or SecureDigital flash card + /// + /// Device + /// Path to the device + /// Prefix for output data files + /// How many times to retry + /// Force to continue dump whenever possible + /// Dump long or scrambled sectors + /// Store whatever data the drive returned on error + /// Stop dump on first error + /// Information for dump resuming + /// Dump logger + /// Encoding to use when analyzing dump + /// If you asked to dump long sectors from a SCSI Streaming device 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); diff --git a/DiscImageChef.Core/Devices/Dumping/XGD.cs b/DiscImageChef.Core/Devices/Dumping/XGD.cs index 8b169a08..2ce85932 100644 --- a/DiscImageChef.Core/Devices/Dumping/XGD.cs +++ b/DiscImageChef.Core/Devices/Dumping/XGD.cs @@ -53,8 +53,28 @@ using TrackType = Schemas.TrackType; namespace DiscImageChef.Core.Devices.Dumping { + /// + /// Implements dumping an Xbox Game Disc using a Kreon drive + /// static class Xgd { + /// + /// Dumps an Xbox Game Disc using a Kreon drive + /// + /// Device + /// Path to the device + /// Prefix for output data files + /// How many times to retry + /// Force to continue dump whenever possible + /// Dump raw/long sectors + /// Store whatever data the drive returned on error + /// Stop dump on first error + /// Information for dump resuming + /// Dump logger + /// Encoding to use when analyzing dump + /// Partially filled initialized sidecar + /// Disc type as detected in MMC layer + /// If the provided resume does not correspond with the current in progress dump 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); diff --git a/DiscImageChef.Core/Devices/Reader.cs b/DiscImageChef.Core/Devices/Reader.cs index d7633715..59a25ad3 100644 --- a/DiscImageChef.Core/Devices/Reader.cs +++ b/DiscImageChef.Core/Devices/Reader.cs @@ -36,6 +36,9 @@ using DiscImageChef.Devices; namespace DiscImageChef.Core.Devices { + /// + /// Reduces common code used for scanning and dumping + /// 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) { diff --git a/DiscImageChef.Core/Devices/Report/ATA.cs b/DiscImageChef.Core/Devices/Report/ATA.cs index 372c3658..98be03e0 100644 --- a/DiscImageChef.Core/Devices/Report/ATA.cs +++ b/DiscImageChef.Core/Devices/Report/ATA.cs @@ -39,8 +39,18 @@ using DiscImageChef.Metadata; namespace DiscImageChef.Core.Devices.Report { + /// + /// Implements creating a report for an ATA device + /// public static class Ata { + /// + /// Creates a report of an ATA device + /// + /// Device + /// Device report + /// If debug is enabled + /// If device is removable public static void Report(Device dev, ref DeviceReport report, bool debug, ref bool removable) { if(report == null) return; @@ -60,1169 +70,1169 @@ namespace DiscImageChef.Core.Devices.Report if(!Identify.Decode(buffer).HasValue) return; Identify.IdentifyDevice? ataIdNullable = Identify.Decode(buffer); - if(ataIdNullable != null) { - Identify.IdentifyDevice ataId = ataIdNullable.Value; + if(ataIdNullable == null) return; - ConsoleKeyInfo pressedKey; - if((ushort)ataId.GeneralConfiguration == 0x848A) + Identify.IdentifyDevice ataId = ataIdNullable.Value; + + ConsoleKeyInfo pressedKey; + if((ushort)ataId.GeneralConfiguration == 0x848A) + { + report.CompactFlash = true; + report.CompactFlashSpecified = true; + removable = false; + } + else if(!removable && + ataId.GeneralConfiguration.HasFlag(Identify.GeneralConfigurationBit.Removable)) + { + pressedKey = new ConsoleKeyInfo(); + while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) { - report.CompactFlash = true; - report.CompactFlashSpecified = true; - removable = false; + DicConsole.Write("Is the media removable from the reading/writing elements? (Y/N): "); + pressedKey = System.Console.ReadKey(); + DicConsole.WriteLine(); } - else if(!removable && - ataId.GeneralConfiguration.HasFlag(Identify.GeneralConfigurationBit.Removable)) + + removable = pressedKey.Key == ConsoleKey.Y; + } + + if(removable) + { + DicConsole.WriteLine("Please remove any media from the device and press any key when it is out."); + System.Console.ReadKey(true); + DicConsole.WriteLine("Querying ATA IDENTIFY..."); + dev.AtaIdentify(out buffer, out _, TIMEOUT, out _); + ataId = Identify.Decode(buffer).Value; + } + + report.ATA = new ataType(); + + if(!string.IsNullOrWhiteSpace(ataId.AdditionalPID)) + { + report.ATA.AdditionalPID = ataId.AdditionalPID; + report.ATA.AdditionalPIDSpecified = true; + } + if(ataId.APIOSupported != 0) + { + report.ATA.APIOSupported = ataId.APIOSupported; + report.ATA.APIOSupportedSpecified = true; + } + if(ataId.BufferType != 0) + { + report.ATA.BufferType = ataId.BufferType; + report.ATA.BufferTypeSpecified = true; + } + if(ataId.BufferSize != 0) + { + report.ATA.BufferSize = ataId.BufferSize; + report.ATA.BufferSizeSpecified = true; + } + if(ataId.Capabilities != 0) + { + report.ATA.Capabilities = ataId.Capabilities; + report.ATA.CapabilitiesSpecified = true; + } + if(ataId.Capabilities2 != 0) + { + report.ATA.Capabilities2 = ataId.Capabilities2; + report.ATA.Capabilities2Specified = true; + } + if(ataId.Capabilities3 != 0) + { + report.ATA.Capabilities3 = ataId.Capabilities3; + report.ATA.Capabilities3Specified = true; + } + if(ataId.CFAPowerMode != 0) + { + report.ATA.CFAPowerMode = ataId.CFAPowerMode; + report.ATA.CFAPowerModeSpecified = true; + } + if(ataId.CommandSet != 0) + { + report.ATA.CommandSet = ataId.CommandSet; + report.ATA.CommandSetSpecified = true; + } + if(ataId.CommandSet2 != 0) + { + report.ATA.CommandSet2 = ataId.CommandSet2; + report.ATA.CommandSet2Specified = true; + } + if(ataId.CommandSet3 != 0) + { + report.ATA.CommandSet3 = ataId.CommandSet3; + report.ATA.CommandSet3Specified = true; + } + if(ataId.CommandSet4 != 0) + { + report.ATA.CommandSet4 = ataId.CommandSet4; + report.ATA.CommandSet4Specified = true; + } + if(ataId.CommandSet5 != 0) + { + report.ATA.CommandSet5 = ataId.CommandSet5; + report.ATA.CommandSet5Specified = true; + } + if(ataId.CurrentAAM != 0) + { + report.ATA.CurrentAAM = ataId.CurrentAAM; + report.ATA.CurrentAAMSpecified = true; + } + if(ataId.CurrentAPM != 0) + { + report.ATA.CurrentAPM = ataId.CurrentAPM; + report.ATA.CurrentAPMSpecified = true; + } + if(ataId.DataSetMgmt != 0) + { + report.ATA.DataSetMgmt = ataId.DataSetMgmt; + report.ATA.DataSetMgmtSpecified = true; + } + if(ataId.DataSetMgmtSize != 0) + { + report.ATA.DataSetMgmtSize = ataId.DataSetMgmtSize; + report.ATA.DataSetMgmtSizeSpecified = true; + } + if(ataId.DeviceFormFactor != 0) + { + report.ATA.DeviceFormFactor = ataId.DeviceFormFactor; + report.ATA.DeviceFormFactorSpecified = true; + } + if(ataId.DMAActive != 0) + { + report.ATA.DMAActive = ataId.DMAActive; + report.ATA.DMAActiveSpecified = true; + } + if(ataId.DMASupported != 0) + { + report.ATA.DMASupported = ataId.DMASupported; + report.ATA.DMASupportedSpecified = true; + } + if(ataId.DMATransferTimingMode != 0) + { + report.ATA.DMATransferTimingMode = ataId.DMATransferTimingMode; + report.ATA.DMATransferTimingModeSpecified = true; + } + if(ataId.EnhancedSecurityEraseTime != 0) + { + report.ATA.EnhancedSecurityEraseTime = ataId.EnhancedSecurityEraseTime; + report.ATA.EnhancedSecurityEraseTimeSpecified = true; + } + if(ataId.EnabledCommandSet != 0) + { + report.ATA.EnabledCommandSet = ataId.EnabledCommandSet; + report.ATA.EnabledCommandSetSpecified = true; + } + if(ataId.EnabledCommandSet2 != 0) + { + report.ATA.EnabledCommandSet2 = ataId.EnabledCommandSet2; + report.ATA.EnabledCommandSet2Specified = true; + } + if(ataId.EnabledCommandSet3 != 0) + { + report.ATA.EnabledCommandSet3 = ataId.EnabledCommandSet3; + report.ATA.EnabledCommandSet3Specified = true; + } + if(ataId.EnabledCommandSet4 != 0) + { + report.ATA.EnabledCommandSet4 = ataId.EnabledCommandSet4; + report.ATA.EnabledCommandSet4Specified = true; + } + if(ataId.EnabledSATAFeatures != 0) + { + report.ATA.EnabledSATAFeatures = ataId.EnabledSATAFeatures; + report.ATA.EnabledSATAFeaturesSpecified = true; + } + if(ataId.ExtendedUserSectors != 0) + { + report.ATA.ExtendedUserSectors = ataId.ExtendedUserSectors; + report.ATA.ExtendedUserSectorsSpecified = true; + } + if(ataId.FreeFallSensitivity != 0) + { + report.ATA.FreeFallSensitivity = ataId.FreeFallSensitivity; + report.ATA.FreeFallSensitivitySpecified = true; + } + if(!string.IsNullOrWhiteSpace(ataId.FirmwareRevision)) + { + report.ATA.FirmwareRevision = ataId.FirmwareRevision; + report.ATA.FirmwareRevisionSpecified = true; + } + if(ataId.GeneralConfiguration != 0) + { + report.ATA.GeneralConfiguration = ataId.GeneralConfiguration; + report.ATA.GeneralConfigurationSpecified = true; + } + if(ataId.HardwareResetResult != 0) + { + report.ATA.HardwareResetResult = ataId.HardwareResetResult; + report.ATA.HardwareResetResultSpecified = true; + } + if(ataId.InterseekDelay != 0) + { + report.ATA.InterseekDelay = ataId.InterseekDelay; + report.ATA.InterseekDelaySpecified = true; + } + if(ataId.MajorVersion != 0) + { + report.ATA.MajorVersion = ataId.MajorVersion; + report.ATA.MajorVersionSpecified = true; + } + if(ataId.MasterPasswordRevisionCode != 0) + { + report.ATA.MasterPasswordRevisionCode = ataId.MasterPasswordRevisionCode; + report.ATA.MasterPasswordRevisionCodeSpecified = true; + } + if(ataId.MaxDownloadMicroMode3 != 0) + { + report.ATA.MaxDownloadMicroMode3 = ataId.MaxDownloadMicroMode3; + report.ATA.MaxDownloadMicroMode3Specified = true; + } + if(ataId.MaxQueueDepth != 0) + { + report.ATA.MaxQueueDepth = ataId.MaxQueueDepth; + report.ATA.MaxQueueDepthSpecified = true; + } + if(ataId.MDMAActive != 0) + { + report.ATA.MDMAActive = ataId.MDMAActive; + report.ATA.MDMAActiveSpecified = true; + } + if(ataId.MDMASupported != 0) + { + report.ATA.MDMASupported = ataId.MDMASupported; + report.ATA.MDMASupportedSpecified = true; + } + if(ataId.MinDownloadMicroMode3 != 0) + { + report.ATA.MinDownloadMicroMode3 = ataId.MinDownloadMicroMode3; + report.ATA.MinDownloadMicroMode3Specified = true; + } + if(ataId.MinMDMACycleTime != 0) + { + report.ATA.MinMDMACycleTime = ataId.MinMDMACycleTime; + report.ATA.MinMDMACycleTimeSpecified = true; + } + if(ataId.MinorVersion != 0) + { + report.ATA.MinorVersion = ataId.MinorVersion; + report.ATA.MinorVersionSpecified = true; + } + if(ataId.MinPIOCycleTimeNoFlow != 0) + { + report.ATA.MinPIOCycleTimeNoFlow = ataId.MinPIOCycleTimeNoFlow; + report.ATA.MinPIOCycleTimeNoFlowSpecified = true; + } + if(ataId.MinPIOCycleTimeFlow != 0) + { + report.ATA.MinPIOCycleTimeFlow = ataId.MinPIOCycleTimeFlow; + report.ATA.MinPIOCycleTimeFlowSpecified = true; + } + if(!string.IsNullOrWhiteSpace(ataId.Model)) + { + report.ATA.Model = ataId.Model; + report.ATA.ModelSpecified = true; + } + if(ataId.MultipleMaxSectors != 0) + { + report.ATA.MultipleMaxSectors = ataId.MultipleMaxSectors; + report.ATA.MultipleMaxSectorsSpecified = true; + } + if(ataId.MultipleSectorNumber != 0) + { + report.ATA.MultipleSectorNumber = ataId.MultipleSectorNumber; + report.ATA.MultipleSectorNumberSpecified = true; + } + if(ataId.NVCacheCaps != 0) + { + report.ATA.NVCacheCaps = ataId.NVCacheCaps; + report.ATA.NVCacheCapsSpecified = true; + } + if(ataId.NVCacheSize != 0) + { + report.ATA.NVCacheSize = ataId.NVCacheSize; + report.ATA.NVCacheSizeSpecified = true; + } + if(ataId.NVCacheWriteSpeed != 0) + { + report.ATA.NVCacheWriteSpeed = ataId.NVCacheWriteSpeed; + report.ATA.NVCacheWriteSpeedSpecified = true; + } + if(ataId.NVEstimatedSpinUp != 0) + { + report.ATA.NVEstimatedSpinUp = ataId.NVEstimatedSpinUp; + report.ATA.NVEstimatedSpinUpSpecified = true; + } + if(ataId.PacketBusRelease != 0) + { + report.ATA.PacketBusRelease = ataId.PacketBusRelease; + report.ATA.PacketBusReleaseSpecified = true; + } + if(ataId.PIOTransferTimingMode != 0) + { + report.ATA.PIOTransferTimingMode = ataId.PIOTransferTimingMode; + report.ATA.PIOTransferTimingModeSpecified = true; + } + if(ataId.RecommendedAAM != 0) + { + report.ATA.RecommendedAAM = ataId.RecommendedAAM; + report.ATA.RecommendedAAMSpecified = true; + } + if(ataId.RecMDMACycleTime != 0) + { + report.ATA.RecommendedMDMACycleTime = ataId.RecMDMACycleTime; + report.ATA.RecommendedMDMACycleTimeSpecified = true; + } + if(ataId.RemovableStatusSet != 0) + { + report.ATA.RemovableStatusSet = ataId.RemovableStatusSet; + report.ATA.RemovableStatusSetSpecified = true; + } + if(ataId.SATACapabilities != 0) + { + report.ATA.SATACapabilities = ataId.SATACapabilities; + report.ATA.SATACapabilitiesSpecified = true; + } + if(ataId.SATACapabilities2 != 0) + { + report.ATA.SATACapabilities2 = ataId.SATACapabilities2; + report.ATA.SATACapabilities2Specified = true; + } + if(ataId.SATAFeatures != 0) + { + report.ATA.SATAFeatures = ataId.SATAFeatures; + report.ATA.SATAFeaturesSpecified = true; + } + if(ataId.SCTCommandTransport != 0) + { + report.ATA.SCTCommandTransport = ataId.SCTCommandTransport; + report.ATA.SCTCommandTransportSpecified = true; + } + if(ataId.SectorsPerCard != 0) + { + report.ATA.SectorsPerCard = ataId.SectorsPerCard; + report.ATA.SectorsPerCardSpecified = true; + } + if(ataId.SecurityEraseTime != 0) + { + report.ATA.SecurityEraseTime = ataId.SecurityEraseTime; + report.ATA.SecurityEraseTimeSpecified = true; + } + if(ataId.SecurityStatus != 0) + { + report.ATA.SecurityStatus = ataId.SecurityStatus; + report.ATA.SecurityStatusSpecified = true; + } + if(ataId.ServiceBusyClear != 0) + { + report.ATA.ServiceBusyClear = ataId.ServiceBusyClear; + report.ATA.ServiceBusyClearSpecified = true; + } + if(ataId.SpecificConfiguration != 0) + { + report.ATA.SpecificConfiguration = ataId.SpecificConfiguration; + report.ATA.SpecificConfigurationSpecified = true; + } + if(ataId.StreamAccessLatency != 0) + { + report.ATA.StreamAccessLatency = ataId.StreamAccessLatency; + report.ATA.StreamAccessLatencySpecified = true; + } + if(ataId.StreamMinReqSize != 0) + { + report.ATA.StreamMinReqSize = ataId.StreamMinReqSize; + report.ATA.StreamMinReqSizeSpecified = true; + } + if(ataId.StreamPerformanceGranularity != 0) + { + report.ATA.StreamPerformanceGranularity = ataId.StreamPerformanceGranularity; + report.ATA.StreamPerformanceGranularitySpecified = true; + } + if(ataId.StreamTransferTimeDMA != 0) + { + report.ATA.StreamTransferTimeDMA = ataId.StreamTransferTimeDMA; + report.ATA.StreamTransferTimeDMASpecified = true; + } + if(ataId.StreamTransferTimePIO != 0) + { + report.ATA.StreamTransferTimePIO = ataId.StreamTransferTimePIO; + report.ATA.StreamTransferTimePIOSpecified = true; + } + if(ataId.TransportMajorVersion != 0) + { + report.ATA.TransportMajorVersion = ataId.TransportMajorVersion; + report.ATA.TransportMajorVersionSpecified = true; + } + if(ataId.TransportMinorVersion != 0) + { + report.ATA.TransportMinorVersion = ataId.TransportMinorVersion; + report.ATA.TransportMinorVersionSpecified = true; + } + if(ataId.TrustedComputing != 0) + { + report.ATA.TrustedComputing = ataId.TrustedComputing; + report.ATA.TrustedComputingSpecified = true; + } + if(ataId.UDMAActive != 0) + { + report.ATA.UDMAActive = ataId.UDMAActive; + report.ATA.UDMAActiveSpecified = true; + } + if(ataId.UDMASupported != 0) + { + report.ATA.UDMASupported = ataId.UDMASupported; + report.ATA.UDMASupportedSpecified = true; + } + if(ataId.WRVMode != 0) + { + report.ATA.WRVMode = ataId.WRVMode; + report.ATA.WRVModeSpecified = true; + } + if(ataId.WRVSectorCountMode3 != 0) + { + report.ATA.WRVSectorCountMode3 = ataId.WRVSectorCountMode3; + report.ATA.WRVSectorCountMode3Specified = true; + } + if(ataId.WRVSectorCountMode2 != 0) + { + report.ATA.WRVSectorCountMode2 = ataId.WRVSectorCountMode2; + report.ATA.WRVSectorCountMode2Specified = true; + } + if(debug) report.ATA.Identify = buffer; + + if(removable) + { + List mediaTests = new List(); + + pressedKey = new ConsoleKeyInfo(); + while(pressedKey.Key != ConsoleKey.N) { pressedKey = new ConsoleKeyInfo(); while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) { - DicConsole.Write("Is the media removable from the reading/writing elements? (Y/N): "); + DicConsole.Write("Do you have media that you can insert in the drive? (Y/N): "); pressedKey = System.Console.ReadKey(); DicConsole.WriteLine(); } - removable = pressedKey.Key == ConsoleKey.Y; - } + if(pressedKey.Key != ConsoleKey.Y) continue; - if(removable) - { - DicConsole.WriteLine("Please remove any media from the device and press any key when it is out."); + DicConsole.WriteLine("Please insert it in the drive and press any key when it is ready."); System.Console.ReadKey(true); + + testedMediaType mediaTest = new testedMediaType(); + DicConsole.Write("Please write a description of the media type and press enter: "); + mediaTest.MediumTypeName = System.Console.ReadLine(); + DicConsole.Write("Please write the media model and press enter: "); + mediaTest.Model = System.Console.ReadLine(); + + mediaTest.ManufacturerSpecified = true; + mediaTest.ModelSpecified = true; + mediaTest.MediaIsRecognized = true; + DicConsole.WriteLine("Querying ATA IDENTIFY..."); dev.AtaIdentify(out buffer, out _, TIMEOUT, out _); - ataId = Identify.Decode(buffer).Value; - } - report.ATA = new ataType(); - - if(!string.IsNullOrWhiteSpace(ataId.AdditionalPID)) - { - report.ATA.AdditionalPID = ataId.AdditionalPID; - report.ATA.AdditionalPIDSpecified = true; - } - if(ataId.APIOSupported != 0) - { - report.ATA.APIOSupported = ataId.APIOSupported; - report.ATA.APIOSupportedSpecified = true; - } - if(ataId.BufferType != 0) - { - report.ATA.BufferType = ataId.BufferType; - report.ATA.BufferTypeSpecified = true; - } - if(ataId.BufferSize != 0) - { - report.ATA.BufferSize = ataId.BufferSize; - report.ATA.BufferSizeSpecified = true; - } - if(ataId.Capabilities != 0) - { - report.ATA.Capabilities = ataId.Capabilities; - report.ATA.CapabilitiesSpecified = true; - } - if(ataId.Capabilities2 != 0) - { - report.ATA.Capabilities2 = ataId.Capabilities2; - report.ATA.Capabilities2Specified = true; - } - if(ataId.Capabilities3 != 0) - { - report.ATA.Capabilities3 = ataId.Capabilities3; - report.ATA.Capabilities3Specified = true; - } - if(ataId.CFAPowerMode != 0) - { - report.ATA.CFAPowerMode = ataId.CFAPowerMode; - report.ATA.CFAPowerModeSpecified = true; - } - if(ataId.CommandSet != 0) - { - report.ATA.CommandSet = ataId.CommandSet; - report.ATA.CommandSetSpecified = true; - } - if(ataId.CommandSet2 != 0) - { - report.ATA.CommandSet2 = ataId.CommandSet2; - report.ATA.CommandSet2Specified = true; - } - if(ataId.CommandSet3 != 0) - { - report.ATA.CommandSet3 = ataId.CommandSet3; - report.ATA.CommandSet3Specified = true; - } - if(ataId.CommandSet4 != 0) - { - report.ATA.CommandSet4 = ataId.CommandSet4; - report.ATA.CommandSet4Specified = true; - } - if(ataId.CommandSet5 != 0) - { - report.ATA.CommandSet5 = ataId.CommandSet5; - report.ATA.CommandSet5Specified = true; - } - if(ataId.CurrentAAM != 0) - { - report.ATA.CurrentAAM = ataId.CurrentAAM; - report.ATA.CurrentAAMSpecified = true; - } - if(ataId.CurrentAPM != 0) - { - report.ATA.CurrentAPM = ataId.CurrentAPM; - report.ATA.CurrentAPMSpecified = true; - } - if(ataId.DataSetMgmt != 0) - { - report.ATA.DataSetMgmt = ataId.DataSetMgmt; - report.ATA.DataSetMgmtSpecified = true; - } - if(ataId.DataSetMgmtSize != 0) - { - report.ATA.DataSetMgmtSize = ataId.DataSetMgmtSize; - report.ATA.DataSetMgmtSizeSpecified = true; - } - if(ataId.DeviceFormFactor != 0) - { - report.ATA.DeviceFormFactor = ataId.DeviceFormFactor; - report.ATA.DeviceFormFactorSpecified = true; - } - if(ataId.DMAActive != 0) - { - report.ATA.DMAActive = ataId.DMAActive; - report.ATA.DMAActiveSpecified = true; - } - if(ataId.DMASupported != 0) - { - report.ATA.DMASupported = ataId.DMASupported; - report.ATA.DMASupportedSpecified = true; - } - if(ataId.DMATransferTimingMode != 0) - { - report.ATA.DMATransferTimingMode = ataId.DMATransferTimingMode; - report.ATA.DMATransferTimingModeSpecified = true; - } - if(ataId.EnhancedSecurityEraseTime != 0) - { - report.ATA.EnhancedSecurityEraseTime = ataId.EnhancedSecurityEraseTime; - report.ATA.EnhancedSecurityEraseTimeSpecified = true; - } - if(ataId.EnabledCommandSet != 0) - { - report.ATA.EnabledCommandSet = ataId.EnabledCommandSet; - report.ATA.EnabledCommandSetSpecified = true; - } - if(ataId.EnabledCommandSet2 != 0) - { - report.ATA.EnabledCommandSet2 = ataId.EnabledCommandSet2; - report.ATA.EnabledCommandSet2Specified = true; - } - if(ataId.EnabledCommandSet3 != 0) - { - report.ATA.EnabledCommandSet3 = ataId.EnabledCommandSet3; - report.ATA.EnabledCommandSet3Specified = true; - } - if(ataId.EnabledCommandSet4 != 0) - { - report.ATA.EnabledCommandSet4 = ataId.EnabledCommandSet4; - report.ATA.EnabledCommandSet4Specified = true; - } - if(ataId.EnabledSATAFeatures != 0) - { - report.ATA.EnabledSATAFeatures = ataId.EnabledSATAFeatures; - report.ATA.EnabledSATAFeaturesSpecified = true; - } - if(ataId.ExtendedUserSectors != 0) - { - report.ATA.ExtendedUserSectors = ataId.ExtendedUserSectors; - report.ATA.ExtendedUserSectorsSpecified = true; - } - if(ataId.FreeFallSensitivity != 0) - { - report.ATA.FreeFallSensitivity = ataId.FreeFallSensitivity; - report.ATA.FreeFallSensitivitySpecified = true; - } - if(!string.IsNullOrWhiteSpace(ataId.FirmwareRevision)) - { - report.ATA.FirmwareRevision = ataId.FirmwareRevision; - report.ATA.FirmwareRevisionSpecified = true; - } - if(ataId.GeneralConfiguration != 0) - { - report.ATA.GeneralConfiguration = ataId.GeneralConfiguration; - report.ATA.GeneralConfigurationSpecified = true; - } - if(ataId.HardwareResetResult != 0) - { - report.ATA.HardwareResetResult = ataId.HardwareResetResult; - report.ATA.HardwareResetResultSpecified = true; - } - if(ataId.InterseekDelay != 0) - { - report.ATA.InterseekDelay = ataId.InterseekDelay; - report.ATA.InterseekDelaySpecified = true; - } - if(ataId.MajorVersion != 0) - { - report.ATA.MajorVersion = ataId.MajorVersion; - report.ATA.MajorVersionSpecified = true; - } - if(ataId.MasterPasswordRevisionCode != 0) - { - report.ATA.MasterPasswordRevisionCode = ataId.MasterPasswordRevisionCode; - report.ATA.MasterPasswordRevisionCodeSpecified = true; - } - if(ataId.MaxDownloadMicroMode3 != 0) - { - report.ATA.MaxDownloadMicroMode3 = ataId.MaxDownloadMicroMode3; - report.ATA.MaxDownloadMicroMode3Specified = true; - } - if(ataId.MaxQueueDepth != 0) - { - report.ATA.MaxQueueDepth = ataId.MaxQueueDepth; - report.ATA.MaxQueueDepthSpecified = true; - } - if(ataId.MDMAActive != 0) - { - report.ATA.MDMAActive = ataId.MDMAActive; - report.ATA.MDMAActiveSpecified = true; - } - if(ataId.MDMASupported != 0) - { - report.ATA.MDMASupported = ataId.MDMASupported; - report.ATA.MDMASupportedSpecified = true; - } - if(ataId.MinDownloadMicroMode3 != 0) - { - report.ATA.MinDownloadMicroMode3 = ataId.MinDownloadMicroMode3; - report.ATA.MinDownloadMicroMode3Specified = true; - } - if(ataId.MinMDMACycleTime != 0) - { - report.ATA.MinMDMACycleTime = ataId.MinMDMACycleTime; - report.ATA.MinMDMACycleTimeSpecified = true; - } - if(ataId.MinorVersion != 0) - { - report.ATA.MinorVersion = ataId.MinorVersion; - report.ATA.MinorVersionSpecified = true; - } - if(ataId.MinPIOCycleTimeNoFlow != 0) - { - report.ATA.MinPIOCycleTimeNoFlow = ataId.MinPIOCycleTimeNoFlow; - report.ATA.MinPIOCycleTimeNoFlowSpecified = true; - } - if(ataId.MinPIOCycleTimeFlow != 0) - { - report.ATA.MinPIOCycleTimeFlow = ataId.MinPIOCycleTimeFlow; - report.ATA.MinPIOCycleTimeFlowSpecified = true; - } - if(!string.IsNullOrWhiteSpace(ataId.Model)) - { - report.ATA.Model = ataId.Model; - report.ATA.ModelSpecified = true; - } - if(ataId.MultipleMaxSectors != 0) - { - report.ATA.MultipleMaxSectors = ataId.MultipleMaxSectors; - report.ATA.MultipleMaxSectorsSpecified = true; - } - if(ataId.MultipleSectorNumber != 0) - { - report.ATA.MultipleSectorNumber = ataId.MultipleSectorNumber; - report.ATA.MultipleSectorNumberSpecified = true; - } - if(ataId.NVCacheCaps != 0) - { - report.ATA.NVCacheCaps = ataId.NVCacheCaps; - report.ATA.NVCacheCapsSpecified = true; - } - if(ataId.NVCacheSize != 0) - { - report.ATA.NVCacheSize = ataId.NVCacheSize; - report.ATA.NVCacheSizeSpecified = true; - } - if(ataId.NVCacheWriteSpeed != 0) - { - report.ATA.NVCacheWriteSpeed = ataId.NVCacheWriteSpeed; - report.ATA.NVCacheWriteSpeedSpecified = true; - } - if(ataId.NVEstimatedSpinUp != 0) - { - report.ATA.NVEstimatedSpinUp = ataId.NVEstimatedSpinUp; - report.ATA.NVEstimatedSpinUpSpecified = true; - } - if(ataId.PacketBusRelease != 0) - { - report.ATA.PacketBusRelease = ataId.PacketBusRelease; - report.ATA.PacketBusReleaseSpecified = true; - } - if(ataId.PIOTransferTimingMode != 0) - { - report.ATA.PIOTransferTimingMode = ataId.PIOTransferTimingMode; - report.ATA.PIOTransferTimingModeSpecified = true; - } - if(ataId.RecommendedAAM != 0) - { - report.ATA.RecommendedAAM = ataId.RecommendedAAM; - report.ATA.RecommendedAAMSpecified = true; - } - if(ataId.RecMDMACycleTime != 0) - { - report.ATA.RecommendedMDMACycleTime = ataId.RecMDMACycleTime; - report.ATA.RecommendedMDMACycleTimeSpecified = true; - } - if(ataId.RemovableStatusSet != 0) - { - report.ATA.RemovableStatusSet = ataId.RemovableStatusSet; - report.ATA.RemovableStatusSetSpecified = true; - } - if(ataId.SATACapabilities != 0) - { - report.ATA.SATACapabilities = ataId.SATACapabilities; - report.ATA.SATACapabilitiesSpecified = true; - } - if(ataId.SATACapabilities2 != 0) - { - report.ATA.SATACapabilities2 = ataId.SATACapabilities2; - report.ATA.SATACapabilities2Specified = true; - } - if(ataId.SATAFeatures != 0) - { - report.ATA.SATAFeatures = ataId.SATAFeatures; - report.ATA.SATAFeaturesSpecified = true; - } - if(ataId.SCTCommandTransport != 0) - { - report.ATA.SCTCommandTransport = ataId.SCTCommandTransport; - report.ATA.SCTCommandTransportSpecified = true; - } - if(ataId.SectorsPerCard != 0) - { - report.ATA.SectorsPerCard = ataId.SectorsPerCard; - report.ATA.SectorsPerCardSpecified = true; - } - if(ataId.SecurityEraseTime != 0) - { - report.ATA.SecurityEraseTime = ataId.SecurityEraseTime; - report.ATA.SecurityEraseTimeSpecified = true; - } - if(ataId.SecurityStatus != 0) - { - report.ATA.SecurityStatus = ataId.SecurityStatus; - report.ATA.SecurityStatusSpecified = true; - } - if(ataId.ServiceBusyClear != 0) - { - report.ATA.ServiceBusyClear = ataId.ServiceBusyClear; - report.ATA.ServiceBusyClearSpecified = true; - } - if(ataId.SpecificConfiguration != 0) - { - report.ATA.SpecificConfiguration = ataId.SpecificConfiguration; - report.ATA.SpecificConfigurationSpecified = true; - } - if(ataId.StreamAccessLatency != 0) - { - report.ATA.StreamAccessLatency = ataId.StreamAccessLatency; - report.ATA.StreamAccessLatencySpecified = true; - } - if(ataId.StreamMinReqSize != 0) - { - report.ATA.StreamMinReqSize = ataId.StreamMinReqSize; - report.ATA.StreamMinReqSizeSpecified = true; - } - if(ataId.StreamPerformanceGranularity != 0) - { - report.ATA.StreamPerformanceGranularity = ataId.StreamPerformanceGranularity; - report.ATA.StreamPerformanceGranularitySpecified = true; - } - if(ataId.StreamTransferTimeDMA != 0) - { - report.ATA.StreamTransferTimeDMA = ataId.StreamTransferTimeDMA; - report.ATA.StreamTransferTimeDMASpecified = true; - } - if(ataId.StreamTransferTimePIO != 0) - { - report.ATA.StreamTransferTimePIO = ataId.StreamTransferTimePIO; - report.ATA.StreamTransferTimePIOSpecified = true; - } - if(ataId.TransportMajorVersion != 0) - { - report.ATA.TransportMajorVersion = ataId.TransportMajorVersion; - report.ATA.TransportMajorVersionSpecified = true; - } - if(ataId.TransportMinorVersion != 0) - { - report.ATA.TransportMinorVersion = ataId.TransportMinorVersion; - report.ATA.TransportMinorVersionSpecified = true; - } - if(ataId.TrustedComputing != 0) - { - report.ATA.TrustedComputing = ataId.TrustedComputing; - report.ATA.TrustedComputingSpecified = true; - } - if(ataId.UDMAActive != 0) - { - report.ATA.UDMAActive = ataId.UDMAActive; - report.ATA.UDMAActiveSpecified = true; - } - if(ataId.UDMASupported != 0) - { - report.ATA.UDMASupported = ataId.UDMASupported; - report.ATA.UDMASupportedSpecified = true; - } - if(ataId.WRVMode != 0) - { - report.ATA.WRVMode = ataId.WRVMode; - report.ATA.WRVModeSpecified = true; - } - if(ataId.WRVSectorCountMode3 != 0) - { - report.ATA.WRVSectorCountMode3 = ataId.WRVSectorCountMode3; - report.ATA.WRVSectorCountMode3Specified = true; - } - if(ataId.WRVSectorCountMode2 != 0) - { - report.ATA.WRVSectorCountMode2 = ataId.WRVSectorCountMode2; - report.ATA.WRVSectorCountMode2Specified = true; - } - if(debug) report.ATA.Identify = buffer; - - if(removable) - { - List mediaTests = new List(); - - pressedKey = new ConsoleKeyInfo(); - while(pressedKey.Key != ConsoleKey.N) + if(Identify.Decode(buffer).HasValue) { - pressedKey = new ConsoleKeyInfo(); - while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) + ataId = Identify.Decode(buffer).Value; + + if(ataId.UnformattedBPT != 0) { - DicConsole.Write("Do you have media that you can insert in the drive? (Y/N): "); - pressedKey = System.Console.ReadKey(); - DicConsole.WriteLine(); + mediaTest.UnformattedBPT = ataId.UnformattedBPT; + mediaTest.UnformattedBPTSpecified = true; + } + if(ataId.UnformattedBPS != 0) + { + mediaTest.UnformattedBPS = ataId.UnformattedBPS; + mediaTest.UnformattedBPSSpecified = true; } - if(pressedKey.Key != ConsoleKey.Y) continue; - - DicConsole.WriteLine("Please insert it in the drive and press any key when it is ready."); - System.Console.ReadKey(true); - - testedMediaType mediaTest = new testedMediaType(); - DicConsole.Write("Please write a description of the media type and press enter: "); - mediaTest.MediumTypeName = System.Console.ReadLine(); - DicConsole.Write("Please write the media model and press enter: "); - mediaTest.Model = System.Console.ReadLine(); - - mediaTest.ManufacturerSpecified = true; - mediaTest.ModelSpecified = true; - mediaTest.MediaIsRecognized = true; - - DicConsole.WriteLine("Querying ATA IDENTIFY..."); - dev.AtaIdentify(out buffer, out _, TIMEOUT, out _); - - if(Identify.Decode(buffer).HasValue) + if(ataId.Cylinders > 0 && ataId.Heads > 0 && ataId.SectorsPerTrack > 0) { - ataId = Identify.Decode(buffer).Value; - - if(ataId.UnformattedBPT != 0) + mediaTest.CHS = new chsType { - mediaTest.UnformattedBPT = ataId.UnformattedBPT; - mediaTest.UnformattedBPTSpecified = true; - } - if(ataId.UnformattedBPS != 0) + Cylinders = ataId.Cylinders, + Heads = ataId.Heads, + Sectors = ataId.SectorsPerTrack + }; + mediaTest.Blocks = (ulong)(ataId.Cylinders * ataId.Heads * ataId.SectorsPerTrack); + mediaTest.BlocksSpecified = true; + } + + if(ataId.CurrentCylinders > 0 && ataId.CurrentHeads > 0 && + ataId.CurrentSectorsPerTrack > 0) + { + mediaTest.CurrentCHS = new chsType { - mediaTest.UnformattedBPS = ataId.UnformattedBPS; - mediaTest.UnformattedBPSSpecified = true; - } + Cylinders = ataId.CurrentCylinders, + Heads = ataId.CurrentHeads, + Sectors = ataId.CurrentSectorsPerTrack + }; + if(mediaTest.Blocks == 0) + mediaTest.Blocks = + (ulong)(ataId.CurrentCylinders * ataId.CurrentHeads * + ataId.CurrentSectorsPerTrack); + mediaTest.BlocksSpecified = true; + } - if(ataId.Cylinders > 0 && ataId.Heads > 0 && ataId.SectorsPerTrack > 0) + if(ataId.Capabilities.HasFlag(Identify.CapabilitiesBit.LBASupport)) + { + mediaTest.LBASectors = ataId.LBASectors; + mediaTest.LBASectorsSpecified = true; + mediaTest.Blocks = ataId.LBASectors; + mediaTest.BlocksSpecified = true; + } + + if(ataId.CommandSet2.HasFlag(Identify.CommandSetBit2.LBA48)) + { + mediaTest.LBA48Sectors = ataId.LBA48Sectors; + mediaTest.LBA48SectorsSpecified = true; + mediaTest.Blocks = ataId.LBA48Sectors; + mediaTest.BlocksSpecified = true; + } + + if(ataId.NominalRotationRate != 0x0000 && ataId.NominalRotationRate != 0xFFFF) + if(ataId.NominalRotationRate == 0x0001) { - mediaTest.CHS = new chsType - { - Cylinders = ataId.Cylinders, - Heads = ataId.Heads, - Sectors = ataId.SectorsPerTrack - }; - mediaTest.Blocks = (ulong)(ataId.Cylinders * ataId.Heads * ataId.SectorsPerTrack); - mediaTest.BlocksSpecified = true; - } - - if(ataId.CurrentCylinders > 0 && ataId.CurrentHeads > 0 && - ataId.CurrentSectorsPerTrack > 0) - { - mediaTest.CurrentCHS = new chsType - { - Cylinders = ataId.CurrentCylinders, - Heads = ataId.CurrentHeads, - Sectors = ataId.CurrentSectorsPerTrack - }; - if(mediaTest.Blocks == 0) - mediaTest.Blocks = - (ulong)(ataId.CurrentCylinders * ataId.CurrentHeads * - ataId.CurrentSectorsPerTrack); - mediaTest.BlocksSpecified = true; - } - - if(ataId.Capabilities.HasFlag(Identify.CapabilitiesBit.LBASupport)) - { - mediaTest.LBASectors = ataId.LBASectors; - mediaTest.LBASectorsSpecified = true; - mediaTest.Blocks = ataId.LBASectors; - mediaTest.BlocksSpecified = true; - } - - if(ataId.CommandSet2.HasFlag(Identify.CommandSetBit2.LBA48)) - { - mediaTest.LBA48Sectors = ataId.LBA48Sectors; - mediaTest.LBA48SectorsSpecified = true; - mediaTest.Blocks = ataId.LBA48Sectors; - mediaTest.BlocksSpecified = true; - } - - if(ataId.NominalRotationRate != 0x0000 && ataId.NominalRotationRate != 0xFFFF) - if(ataId.NominalRotationRate == 0x0001) - { - mediaTest.SolidStateDevice = true; - mediaTest.SolidStateDeviceSpecified = true; - } - else - { - mediaTest.SolidStateDevice = false; - mediaTest.SolidStateDeviceSpecified = true; - mediaTest.NominalRotationRate = ataId.NominalRotationRate; - mediaTest.NominalRotationRateSpecified = true; - } - - uint logicalsectorsize; - uint physicalsectorsize; - if((ataId.PhysLogSectorSize & 0x8000) == 0x0000 && - (ataId.PhysLogSectorSize & 0x4000) == 0x4000) - { - if((ataId.PhysLogSectorSize & 0x1000) == 0x1000) - if(ataId.LogicalSectorWords <= 255 || ataId.LogicalAlignment == 0xFFFF) - logicalsectorsize = 512; - else logicalsectorsize = ataId.LogicalSectorWords * 2; - else logicalsectorsize = 512; - - if((ataId.PhysLogSectorSize & 0x2000) == 0x2000) - { - physicalsectorsize = - (uint)(logicalsectorsize * ((1 << ataId.PhysLogSectorSize) & 0xF)); - } - else physicalsectorsize = logicalsectorsize; + mediaTest.SolidStateDevice = true; + mediaTest.SolidStateDeviceSpecified = true; } else { - logicalsectorsize = 512; - physicalsectorsize = 512; + mediaTest.SolidStateDevice = false; + mediaTest.SolidStateDeviceSpecified = true; + mediaTest.NominalRotationRate = ataId.NominalRotationRate; + mediaTest.NominalRotationRateSpecified = true; } - mediaTest.BlockSize = logicalsectorsize; - mediaTest.BlockSizeSpecified = true; - if(physicalsectorsize != logicalsectorsize) - { - mediaTest.PhysicalBlockSize = physicalsectorsize; - mediaTest.PhysicalBlockSizeSpecified = true; - - if((ataId.LogicalAlignment & 0x8000) == 0x0000 && - (ataId.LogicalAlignment & 0x4000) == 0x4000) - { - mediaTest.LogicalAlignment = (ushort)(ataId.LogicalAlignment & 0x3FFF); - mediaTest.LogicalAlignmentSpecified = true; - } - } - - if(ataId.EccBytes != 0x0000 && ataId.EccBytes != 0xFFFF) - { - mediaTest.LongBlockSize = logicalsectorsize + ataId.EccBytes; - mediaTest.LongBlockSizeSpecified = true; - } - - if(ataId.UnformattedBPS > logicalsectorsize && - (!mediaTest.LongBlockSizeSpecified || mediaTest.LongBlockSize == 516)) - { - mediaTest.LongBlockSize = ataId.UnformattedBPS; - mediaTest.LongBlockSizeSpecified = true; - } - - if(ataId.CommandSet3.HasFlag(Identify.CommandSetBit3.MustBeSet) && - !ataId.CommandSet3.HasFlag(Identify.CommandSetBit3.MustBeClear) && - ataId.EnabledCommandSet3.HasFlag(Identify.CommandSetBit3.MediaSerial)) - { - mediaTest.CanReadMediaSerial = true; - mediaTest.CanReadMediaSerialSpecified = true; - if(!string.IsNullOrWhiteSpace(ataId.MediaManufacturer)) - { - mediaTest.Manufacturer = ataId.MediaManufacturer; - mediaTest.ManufacturerSpecified = true; - } - } - - mediaTest.SupportsReadLbaSpecified = true; - mediaTest.SupportsReadRetryLbaSpecified = true; - mediaTest.SupportsReadDmaLbaSpecified = true; - mediaTest.SupportsReadDmaRetryLbaSpecified = true; - mediaTest.SupportsReadLongLbaSpecified = true; - mediaTest.SupportsReadLongRetryLbaSpecified = true; - mediaTest.SupportsSeekLbaSpecified = true; - - mediaTest.SupportsReadLba48Specified = true; - mediaTest.SupportsReadDmaLba48Specified = true; - - mediaTest.SupportsReadSpecified = true; - mediaTest.SupportsReadRetrySpecified = true; - mediaTest.SupportsReadDmaSpecified = true; - mediaTest.SupportsReadDmaRetrySpecified = true; - mediaTest.SupportsReadLongSpecified = true; - mediaTest.SupportsReadLongRetrySpecified = true; - mediaTest.SupportsSeekSpecified = true; - - ulong checkCorrectRead = BitConverter.ToUInt64(buffer, 0); - bool sense; - - 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 _); - mediaTest.SupportsRead = - !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && - readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", - sense, errorChs.Status, errorChs.Error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readsectorschs", - "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", - readBuf); - - DicConsole.WriteLine("Trying READ SECTOR(S) RETRY in CHS mode..."); - sense = dev.Read(out readBuf, out errorChs, true, 0, 0, 1, 1, TIMEOUT, out _); - mediaTest.SupportsReadRetry = - !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && - readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", - sense, errorChs.Status, errorChs.Error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readsectorsretrychs", - "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", - readBuf); - - DicConsole.WriteLine("Trying READ DMA in CHS mode..."); - sense = dev.ReadDma(out readBuf, out errorChs, false, 0, 0, 1, 1, TIMEOUT, - out _); - mediaTest.SupportsReadDma = - !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && - readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", - sense, errorChs.Status, errorChs.Error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readdmachs", - "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", - readBuf); - - DicConsole.WriteLine("Trying READ DMA RETRY in CHS mode..."); - sense = dev.ReadDma(out readBuf, out errorChs, true, 0, 0, 1, 1, TIMEOUT, out _); - mediaTest.SupportsReadDmaRetry = - !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && - readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", - sense, errorChs.Status, errorChs.Error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readdmaretrychs", - "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", - readBuf); - - DicConsole.WriteLine("Trying SEEK in CHS mode..."); - sense = dev.Seek(out errorChs, 0, 0, 1, TIMEOUT, out _); - mediaTest.SupportsSeek = - !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}", sense, - errorChs.Status, errorChs.Error); - - DicConsole.WriteLine("Trying READ SECTOR(S) in LBA mode..."); - sense = dev.Read(out readBuf, out AtaErrorRegistersLba28 errorLba, false, 0, 1, TIMEOUT, out _); - mediaTest.SupportsReadLba = - !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && - readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", - sense, errorChs.Status, errorChs.Error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readsectors", - "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", - readBuf); - - DicConsole.WriteLine("Trying READ SECTOR(S) RETRY in LBA mode..."); - sense = dev.Read(out readBuf, out errorLba, true, 0, 1, TIMEOUT, out _); - mediaTest.SupportsReadRetryLba = - !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && - readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", - sense, errorChs.Status, errorChs.Error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readsectorsretry", - "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", - readBuf); - - DicConsole.WriteLine("Trying READ DMA in LBA mode..."); - sense = dev.ReadDma(out readBuf, out errorLba, false, 0, 1, TIMEOUT, out _); - mediaTest.SupportsReadDmaLba = - !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && - readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", - sense, errorChs.Status, errorChs.Error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readdma", - "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", - readBuf); - - DicConsole.WriteLine("Trying READ DMA RETRY in LBA mode..."); - sense = dev.ReadDma(out readBuf, out errorLba, true, 0, 1, TIMEOUT, out _); - mediaTest.SupportsReadDmaRetryLba = - !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && - readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", - sense, errorChs.Status, errorChs.Error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readdmaretry", - "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", - readBuf); - - DicConsole.WriteLine("Trying SEEK in LBA mode..."); - sense = dev.Seek(out errorLba, 0, TIMEOUT, out _); - mediaTest.SupportsSeekLba = - !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}", sense, - errorChs.Status, errorChs.Error); - - DicConsole.WriteLine("Trying READ SECTOR(S) in LBA48 mode..."); - sense = dev.Read(out readBuf, out AtaErrorRegistersLba48 errorLba48, 0, 1, TIMEOUT, out _); - mediaTest.SupportsReadLba48 = - !sense && (errorLba48.Status & 0x01) != 0x01 && errorLba48.Error == 0 && - readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", - sense, errorChs.Status, errorChs.Error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readsectors48", - "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", - readBuf); - - DicConsole.WriteLine("Trying READ DMA in LBA48 mode..."); - sense = dev.ReadDma(out readBuf, out errorLba48, 0, 1, TIMEOUT, out _); - mediaTest.SupportsReadDmaLba48 = - !sense && (errorLba48.Status & 0x01) != 0x01 && errorLba48.Error == 0 && - readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", - sense, errorChs.Status, errorChs.Error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readdma48", - "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", - readBuf); - - DicConsole.WriteLine("Trying READ LONG in CHS mode..."); - sense = dev.ReadLong(out readBuf, out errorChs, false, 0, 0, 1, mediaTest.LongBlockSize, - TIMEOUT, out _); - mediaTest.SupportsReadLong = - !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && - readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", - sense, errorChs.Status, errorChs.Error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readlongchs", - "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", - readBuf); - - DicConsole.WriteLine("Trying READ LONG RETRY in CHS mode..."); - sense = dev.ReadLong(out readBuf, out errorChs, true, 0, 0, 1, mediaTest.LongBlockSize, - TIMEOUT, out _); - mediaTest.SupportsReadLongRetry = - !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && - readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", - sense, errorChs.Status, errorChs.Error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readlongretrychs", - "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", - readBuf); - - DicConsole.WriteLine("Trying READ LONG in LBA mode..."); - sense = dev.ReadLong(out readBuf, out errorLba, false, 0, mediaTest.LongBlockSize, - TIMEOUT, out _); - mediaTest.SupportsReadLongLba = - !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && - readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", - sense, errorChs.Status, errorChs.Error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readlong", - "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", - readBuf); - - DicConsole.WriteLine("Trying READ LONG RETRY in LBA mode..."); - sense = dev.ReadLong(out readBuf, out errorLba, true, 0, mediaTest.LongBlockSize, - TIMEOUT, out _); - mediaTest.SupportsReadLongRetryLba = - !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && - readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", - sense, errorChs.Status, errorChs.Error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readlongretry", - "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", - readBuf); - } - else mediaTest.MediaIsRecognized = false; - - mediaTests.Add(mediaTest); - } - - report.ATA.RemovableMedias = mediaTests.ToArray(); - } - else - { - report.ATA.ReadCapabilities = new testedMediaType(); - - if(ataId.UnformattedBPT != 0) - { - report.ATA.ReadCapabilities.UnformattedBPT = ataId.UnformattedBPT; - report.ATA.ReadCapabilities.UnformattedBPTSpecified = true; - } - if(ataId.UnformattedBPS != 0) - { - report.ATA.ReadCapabilities.UnformattedBPS = ataId.UnformattedBPS; - report.ATA.ReadCapabilities.UnformattedBPSSpecified = true; - } - - if(ataId.Cylinders > 0 && ataId.Heads > 0 && ataId.SectorsPerTrack > 0) - { - report.ATA.ReadCapabilities.CHS = new chsType + uint logicalsectorsize; + uint physicalsectorsize; + if((ataId.PhysLogSectorSize & 0x8000) == 0x0000 && + (ataId.PhysLogSectorSize & 0x4000) == 0x4000) { - Cylinders = ataId.Cylinders, - Heads = ataId.Heads, - Sectors = ataId.SectorsPerTrack - }; - report.ATA.ReadCapabilities.Blocks = - (ulong)(ataId.Cylinders * ataId.Heads * ataId.SectorsPerTrack); - report.ATA.ReadCapabilities.BlocksSpecified = true; - } + if((ataId.PhysLogSectorSize & 0x1000) == 0x1000) + if(ataId.LogicalSectorWords <= 255 || ataId.LogicalAlignment == 0xFFFF) + logicalsectorsize = 512; + else logicalsectorsize = ataId.LogicalSectorWords * 2; + else logicalsectorsize = 512; - if(ataId.CurrentCylinders > 0 && ataId.CurrentHeads > 0 && ataId.CurrentSectorsPerTrack > 0) - { - report.ATA.ReadCapabilities.CurrentCHS = new chsType - { - Cylinders = ataId.CurrentCylinders, - Heads = ataId.CurrentHeads, - Sectors = ataId.CurrentSectorsPerTrack - }; - report.ATA.ReadCapabilities.Blocks = - (ulong)(ataId.CurrentCylinders * ataId.CurrentHeads * ataId.CurrentSectorsPerTrack); - report.ATA.ReadCapabilities.BlocksSpecified = true; - } - - if(ataId.Capabilities.HasFlag(Identify.CapabilitiesBit.LBASupport)) - { - report.ATA.ReadCapabilities.LBASectors = ataId.LBASectors; - report.ATA.ReadCapabilities.LBASectorsSpecified = true; - report.ATA.ReadCapabilities.Blocks = ataId.LBASectors; - report.ATA.ReadCapabilities.BlocksSpecified = true; - } - - if(ataId.CommandSet2.HasFlag(Identify.CommandSetBit2.LBA48)) - { - report.ATA.ReadCapabilities.LBA48Sectors = ataId.LBA48Sectors; - report.ATA.ReadCapabilities.LBA48SectorsSpecified = true; - report.ATA.ReadCapabilities.Blocks = ataId.LBA48Sectors; - report.ATA.ReadCapabilities.BlocksSpecified = true; - } - - if(ataId.NominalRotationRate != 0x0000 && ataId.NominalRotationRate != 0xFFFF) - if(ataId.NominalRotationRate == 0x0001) - { - report.ATA.ReadCapabilities.SolidStateDevice = true; - report.ATA.ReadCapabilities.SolidStateDeviceSpecified = true; + if((ataId.PhysLogSectorSize & 0x2000) == 0x2000) + { + physicalsectorsize = + (uint)(logicalsectorsize * ((1 << ataId.PhysLogSectorSize) & 0xF)); + } + else physicalsectorsize = logicalsectorsize; } else { - report.ATA.ReadCapabilities.SolidStateDevice = false; - report.ATA.ReadCapabilities.SolidStateDeviceSpecified = true; - report.ATA.ReadCapabilities.NominalRotationRate = ataId.NominalRotationRate; - report.ATA.ReadCapabilities.NominalRotationRateSpecified = true; + logicalsectorsize = 512; + physicalsectorsize = 512; } - uint logicalsectorsize; - uint physicalsectorsize; - if((ataId.PhysLogSectorSize & 0x8000) == 0x0000 && (ataId.PhysLogSectorSize & 0x4000) == 0x4000) - { - if((ataId.PhysLogSectorSize & 0x1000) == 0x1000) - if(ataId.LogicalSectorWords <= 255 || ataId.LogicalAlignment == 0xFFFF) - logicalsectorsize = 512; - else logicalsectorsize = ataId.LogicalSectorWords * 2; - else logicalsectorsize = 512; - - if((ataId.PhysLogSectorSize & 0x2000) == 0x2000) + mediaTest.BlockSize = logicalsectorsize; + mediaTest.BlockSizeSpecified = true; + if(physicalsectorsize != logicalsectorsize) { - physicalsectorsize = logicalsectorsize * - (uint)Math.Pow(2, ataId.PhysLogSectorSize & 0xF); + mediaTest.PhysicalBlockSize = physicalsectorsize; + mediaTest.PhysicalBlockSizeSpecified = true; + + if((ataId.LogicalAlignment & 0x8000) == 0x0000 && + (ataId.LogicalAlignment & 0x4000) == 0x4000) + { + mediaTest.LogicalAlignment = (ushort)(ataId.LogicalAlignment & 0x3FFF); + mediaTest.LogicalAlignmentSpecified = true; + } } - else physicalsectorsize = logicalsectorsize; + + if(ataId.EccBytes != 0x0000 && ataId.EccBytes != 0xFFFF) + { + mediaTest.LongBlockSize = logicalsectorsize + ataId.EccBytes; + mediaTest.LongBlockSizeSpecified = true; + } + + if(ataId.UnformattedBPS > logicalsectorsize && + (!mediaTest.LongBlockSizeSpecified || mediaTest.LongBlockSize == 516)) + { + mediaTest.LongBlockSize = ataId.UnformattedBPS; + mediaTest.LongBlockSizeSpecified = true; + } + + if(ataId.CommandSet3.HasFlag(Identify.CommandSetBit3.MustBeSet) && + !ataId.CommandSet3.HasFlag(Identify.CommandSetBit3.MustBeClear) && + ataId.EnabledCommandSet3.HasFlag(Identify.CommandSetBit3.MediaSerial)) + { + mediaTest.CanReadMediaSerial = true; + mediaTest.CanReadMediaSerialSpecified = true; + if(!string.IsNullOrWhiteSpace(ataId.MediaManufacturer)) + { + mediaTest.Manufacturer = ataId.MediaManufacturer; + mediaTest.ManufacturerSpecified = true; + } + } + + mediaTest.SupportsReadLbaSpecified = true; + mediaTest.SupportsReadRetryLbaSpecified = true; + mediaTest.SupportsReadDmaLbaSpecified = true; + mediaTest.SupportsReadDmaRetryLbaSpecified = true; + mediaTest.SupportsReadLongLbaSpecified = true; + mediaTest.SupportsReadLongRetryLbaSpecified = true; + mediaTest.SupportsSeekLbaSpecified = true; + + mediaTest.SupportsReadLba48Specified = true; + mediaTest.SupportsReadDmaLba48Specified = true; + + mediaTest.SupportsReadSpecified = true; + mediaTest.SupportsReadRetrySpecified = true; + mediaTest.SupportsReadDmaSpecified = true; + mediaTest.SupportsReadDmaRetrySpecified = true; + mediaTest.SupportsReadLongSpecified = true; + mediaTest.SupportsReadLongRetrySpecified = true; + mediaTest.SupportsSeekSpecified = true; + + ulong checkCorrectRead = BitConverter.ToUInt64(buffer, 0); + bool sense; + + 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 _); + mediaTest.SupportsRead = + !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && + readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", + sense, errorChs.Status, errorChs.Error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readsectorschs", + "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", + readBuf); + + DicConsole.WriteLine("Trying READ SECTOR(S) RETRY in CHS mode..."); + sense = dev.Read(out readBuf, out errorChs, true, 0, 0, 1, 1, TIMEOUT, out _); + mediaTest.SupportsReadRetry = + !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && + readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", + sense, errorChs.Status, errorChs.Error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readsectorsretrychs", + "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", + readBuf); + + DicConsole.WriteLine("Trying READ DMA in CHS mode..."); + sense = dev.ReadDma(out readBuf, out errorChs, false, 0, 0, 1, 1, TIMEOUT, + out _); + mediaTest.SupportsReadDma = + !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && + readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", + sense, errorChs.Status, errorChs.Error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readdmachs", + "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", + readBuf); + + DicConsole.WriteLine("Trying READ DMA RETRY in CHS mode..."); + sense = dev.ReadDma(out readBuf, out errorChs, true, 0, 0, 1, 1, TIMEOUT, out _); + mediaTest.SupportsReadDmaRetry = + !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && + readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", + sense, errorChs.Status, errorChs.Error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readdmaretrychs", + "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", + readBuf); + + DicConsole.WriteLine("Trying SEEK in CHS mode..."); + sense = dev.Seek(out errorChs, 0, 0, 1, TIMEOUT, out _); + mediaTest.SupportsSeek = + !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}", sense, + errorChs.Status, errorChs.Error); + + DicConsole.WriteLine("Trying READ SECTOR(S) in LBA mode..."); + sense = dev.Read(out readBuf, out AtaErrorRegistersLba28 errorLba, false, 0, 1, TIMEOUT, out _); + mediaTest.SupportsReadLba = + !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && + readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", + sense, errorChs.Status, errorChs.Error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readsectors", + "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", + readBuf); + + DicConsole.WriteLine("Trying READ SECTOR(S) RETRY in LBA mode..."); + sense = dev.Read(out readBuf, out errorLba, true, 0, 1, TIMEOUT, out _); + mediaTest.SupportsReadRetryLba = + !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && + readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", + sense, errorChs.Status, errorChs.Error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readsectorsretry", + "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", + readBuf); + + DicConsole.WriteLine("Trying READ DMA in LBA mode..."); + sense = dev.ReadDma(out readBuf, out errorLba, false, 0, 1, TIMEOUT, out _); + mediaTest.SupportsReadDmaLba = + !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && + readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", + sense, errorChs.Status, errorChs.Error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readdma", + "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", + readBuf); + + DicConsole.WriteLine("Trying READ DMA RETRY in LBA mode..."); + sense = dev.ReadDma(out readBuf, out errorLba, true, 0, 1, TIMEOUT, out _); + mediaTest.SupportsReadDmaRetryLba = + !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && + readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", + sense, errorChs.Status, errorChs.Error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readdmaretry", + "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", + readBuf); + + DicConsole.WriteLine("Trying SEEK in LBA mode..."); + sense = dev.Seek(out errorLba, 0, TIMEOUT, out _); + mediaTest.SupportsSeekLba = + !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}", sense, + errorChs.Status, errorChs.Error); + + DicConsole.WriteLine("Trying READ SECTOR(S) in LBA48 mode..."); + sense = dev.Read(out readBuf, out AtaErrorRegistersLba48 errorLba48, 0, 1, TIMEOUT, out _); + mediaTest.SupportsReadLba48 = + !sense && (errorLba48.Status & 0x01) != 0x01 && errorLba48.Error == 0 && + readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", + sense, errorChs.Status, errorChs.Error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readsectors48", + "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", + readBuf); + + DicConsole.WriteLine("Trying READ DMA in LBA48 mode..."); + sense = dev.ReadDma(out readBuf, out errorLba48, 0, 1, TIMEOUT, out _); + mediaTest.SupportsReadDmaLba48 = + !sense && (errorLba48.Status & 0x01) != 0x01 && errorLba48.Error == 0 && + readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", + sense, errorChs.Status, errorChs.Error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readdma48", + "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", + readBuf); + + DicConsole.WriteLine("Trying READ LONG in CHS mode..."); + sense = dev.ReadLong(out readBuf, out errorChs, false, 0, 0, 1, mediaTest.LongBlockSize, + TIMEOUT, out _); + mediaTest.SupportsReadLong = + !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && + readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", + sense, errorChs.Status, errorChs.Error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readlongchs", + "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", + readBuf); + + DicConsole.WriteLine("Trying READ LONG RETRY in CHS mode..."); + sense = dev.ReadLong(out readBuf, out errorChs, true, 0, 0, 1, mediaTest.LongBlockSize, + TIMEOUT, out _); + mediaTest.SupportsReadLongRetry = + !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && + readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", + sense, errorChs.Status, errorChs.Error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readlongretrychs", + "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", + readBuf); + + DicConsole.WriteLine("Trying READ LONG in LBA mode..."); + sense = dev.ReadLong(out readBuf, out errorLba, false, 0, mediaTest.LongBlockSize, + TIMEOUT, out _); + mediaTest.SupportsReadLongLba = + !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && + readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", + sense, errorChs.Status, errorChs.Error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readlong", + "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", + readBuf); + + DicConsole.WriteLine("Trying READ LONG RETRY in LBA mode..."); + sense = dev.ReadLong(out readBuf, out errorLba, true, 0, mediaTest.LongBlockSize, + TIMEOUT, out _); + mediaTest.SupportsReadLongRetryLba = + !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && + readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", + sense, errorChs.Status, errorChs.Error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readlongretry", + "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", + readBuf); + } + else mediaTest.MediaIsRecognized = false; + + mediaTests.Add(mediaTest); + } + + report.ATA.RemovableMedias = mediaTests.ToArray(); + } + else + { + report.ATA.ReadCapabilities = new testedMediaType(); + + if(ataId.UnformattedBPT != 0) + { + report.ATA.ReadCapabilities.UnformattedBPT = ataId.UnformattedBPT; + report.ATA.ReadCapabilities.UnformattedBPTSpecified = true; + } + if(ataId.UnformattedBPS != 0) + { + report.ATA.ReadCapabilities.UnformattedBPS = ataId.UnformattedBPS; + report.ATA.ReadCapabilities.UnformattedBPSSpecified = true; + } + + if(ataId.Cylinders > 0 && ataId.Heads > 0 && ataId.SectorsPerTrack > 0) + { + report.ATA.ReadCapabilities.CHS = new chsType + { + Cylinders = ataId.Cylinders, + Heads = ataId.Heads, + Sectors = ataId.SectorsPerTrack + }; + report.ATA.ReadCapabilities.Blocks = + (ulong)(ataId.Cylinders * ataId.Heads * ataId.SectorsPerTrack); + report.ATA.ReadCapabilities.BlocksSpecified = true; + } + + if(ataId.CurrentCylinders > 0 && ataId.CurrentHeads > 0 && ataId.CurrentSectorsPerTrack > 0) + { + report.ATA.ReadCapabilities.CurrentCHS = new chsType + { + Cylinders = ataId.CurrentCylinders, + Heads = ataId.CurrentHeads, + Sectors = ataId.CurrentSectorsPerTrack + }; + report.ATA.ReadCapabilities.Blocks = + (ulong)(ataId.CurrentCylinders * ataId.CurrentHeads * ataId.CurrentSectorsPerTrack); + report.ATA.ReadCapabilities.BlocksSpecified = true; + } + + if(ataId.Capabilities.HasFlag(Identify.CapabilitiesBit.LBASupport)) + { + report.ATA.ReadCapabilities.LBASectors = ataId.LBASectors; + report.ATA.ReadCapabilities.LBASectorsSpecified = true; + report.ATA.ReadCapabilities.Blocks = ataId.LBASectors; + report.ATA.ReadCapabilities.BlocksSpecified = true; + } + + if(ataId.CommandSet2.HasFlag(Identify.CommandSetBit2.LBA48)) + { + report.ATA.ReadCapabilities.LBA48Sectors = ataId.LBA48Sectors; + report.ATA.ReadCapabilities.LBA48SectorsSpecified = true; + report.ATA.ReadCapabilities.Blocks = ataId.LBA48Sectors; + report.ATA.ReadCapabilities.BlocksSpecified = true; + } + + if(ataId.NominalRotationRate != 0x0000 && ataId.NominalRotationRate != 0xFFFF) + if(ataId.NominalRotationRate == 0x0001) + { + report.ATA.ReadCapabilities.SolidStateDevice = true; + report.ATA.ReadCapabilities.SolidStateDeviceSpecified = true; } else { - logicalsectorsize = 512; - physicalsectorsize = 512; + report.ATA.ReadCapabilities.SolidStateDevice = false; + report.ATA.ReadCapabilities.SolidStateDeviceSpecified = true; + report.ATA.ReadCapabilities.NominalRotationRate = ataId.NominalRotationRate; + report.ATA.ReadCapabilities.NominalRotationRateSpecified = true; } - report.ATA.ReadCapabilities.BlockSize = logicalsectorsize; - report.ATA.ReadCapabilities.BlockSizeSpecified = true; - if(physicalsectorsize != logicalsectorsize) + uint logicalsectorsize; + uint physicalsectorsize; + if((ataId.PhysLogSectorSize & 0x8000) == 0x0000 && (ataId.PhysLogSectorSize & 0x4000) == 0x4000) + { + if((ataId.PhysLogSectorSize & 0x1000) == 0x1000) + if(ataId.LogicalSectorWords <= 255 || ataId.LogicalAlignment == 0xFFFF) + logicalsectorsize = 512; + else logicalsectorsize = ataId.LogicalSectorWords * 2; + else logicalsectorsize = 512; + + if((ataId.PhysLogSectorSize & 0x2000) == 0x2000) { - report.ATA.ReadCapabilities.PhysicalBlockSize = physicalsectorsize; - report.ATA.ReadCapabilities.PhysicalBlockSizeSpecified = true; - - if((ataId.LogicalAlignment & 0x8000) == 0x0000 && (ataId.LogicalAlignment & 0x4000) == 0x4000) - { - report.ATA.ReadCapabilities.LogicalAlignment = (ushort)(ataId.LogicalAlignment & 0x3FFF); - report.ATA.ReadCapabilities.LogicalAlignmentSpecified = true; - } + physicalsectorsize = logicalsectorsize * + (uint)Math.Pow(2, ataId.PhysLogSectorSize & 0xF); } - - if(ataId.EccBytes != 0x0000 && ataId.EccBytes != 0xFFFF) - { - report.ATA.ReadCapabilities.LongBlockSize = logicalsectorsize + ataId.EccBytes; - report.ATA.ReadCapabilities.LongBlockSizeSpecified = true; - } - - if(ataId.UnformattedBPS > logicalsectorsize && - (!report.ATA.ReadCapabilities.LongBlockSizeSpecified || - report.ATA.ReadCapabilities.LongBlockSize == 516)) - { - report.ATA.ReadCapabilities.LongBlockSize = ataId.UnformattedBPS; - report.ATA.ReadCapabilities.LongBlockSizeSpecified = true; - } - - if(ataId.CommandSet3.HasFlag(Identify.CommandSetBit3.MustBeSet) && - !ataId.CommandSet3.HasFlag(Identify.CommandSetBit3.MustBeClear) && - ataId.EnabledCommandSet3.HasFlag(Identify.CommandSetBit3.MediaSerial)) - { - report.ATA.ReadCapabilities.CanReadMediaSerial = true; - report.ATA.ReadCapabilities.CanReadMediaSerialSpecified = true; - if(!string.IsNullOrWhiteSpace(ataId.MediaManufacturer)) - { - report.ATA.ReadCapabilities.Manufacturer = ataId.MediaManufacturer; - report.ATA.ReadCapabilities.ManufacturerSpecified = true; - } - } - - report.ATA.ReadCapabilities.SupportsReadLbaSpecified = true; - report.ATA.ReadCapabilities.SupportsReadRetryLbaSpecified = true; - report.ATA.ReadCapabilities.SupportsReadDmaLbaSpecified = true; - report.ATA.ReadCapabilities.SupportsReadDmaRetryLbaSpecified = true; - report.ATA.ReadCapabilities.SupportsReadLongLbaSpecified = true; - report.ATA.ReadCapabilities.SupportsReadLongRetryLbaSpecified = true; - report.ATA.ReadCapabilities.SupportsSeekLbaSpecified = true; - - report.ATA.ReadCapabilities.SupportsReadLba48Specified = true; - report.ATA.ReadCapabilities.SupportsReadDmaLba48Specified = true; - - report.ATA.ReadCapabilities.SupportsReadSpecified = true; - report.ATA.ReadCapabilities.SupportsReadRetrySpecified = true; - report.ATA.ReadCapabilities.SupportsReadDmaSpecified = true; - report.ATA.ReadCapabilities.SupportsReadDmaRetrySpecified = true; - report.ATA.ReadCapabilities.SupportsReadLongSpecified = true; - report.ATA.ReadCapabilities.SupportsReadLongRetrySpecified = true; - report.ATA.ReadCapabilities.SupportsSeekSpecified = true; - - ulong checkCorrectRead = BitConverter.ToUInt64(buffer, 0); - bool sense; - - 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 _); - report.ATA.ReadCapabilities.SupportsRead = - !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, - errorChs.Status, errorChs.Error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readsectorschs", "_debug_" + report.ATA.Model + ".bin", - "read results", readBuf); - - DicConsole.WriteLine("Trying READ SECTOR(S) RETRY in CHS mode..."); - sense = dev.Read(out readBuf, out errorChs, true, 0, 0, 1, 1, TIMEOUT, out _); - report.ATA.ReadCapabilities.SupportsReadRetry = - !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, - errorChs.Status, errorChs.Error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readsectorsretrychs", "_debug_" + report.ATA.Model + ".bin", - "read results", readBuf); - - DicConsole.WriteLine("Trying READ DMA in CHS mode..."); - sense = dev.ReadDma(out readBuf, out errorChs, false, 0, 0, 1, 1, TIMEOUT, out _); - report.ATA.ReadCapabilities.SupportsReadDma = - !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, - errorChs.Status, errorChs.Error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readdmachs", "_debug_" + report.ATA.Model + ".bin", - "read results", readBuf); - - DicConsole.WriteLine("Trying READ DMA RETRY in CHS mode..."); - sense = dev.ReadDma(out readBuf, out errorChs, true, 0, 0, 1, 1, TIMEOUT, out _); - report.ATA.ReadCapabilities.SupportsReadDmaRetry = - !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, - errorChs.Status, errorChs.Error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readdmaretrychs", "_debug_" + report.ATA.Model + ".bin", - "read results", readBuf); - - DicConsole.WriteLine("Trying SEEK in CHS mode..."); - sense = dev.Seek(out errorChs, 0, 0, 1, TIMEOUT, out _); - report.ATA.ReadCapabilities.SupportsSeek = - !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0; - DicConsole.DebugWriteLine("ATA Report", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}", sense, - errorChs.Status, errorChs.Error); - - DicConsole.WriteLine("Trying READ SECTOR(S) in LBA mode..."); - sense = dev.Read(out readBuf, out AtaErrorRegistersLba28 errorLba, false, 0, 1, TIMEOUT, out _); - report.ATA.ReadCapabilities.SupportsReadLba = - !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, - errorLba.Status, errorLba.Error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readsectors", "_debug_" + report.ATA.Model + ".bin", - "read results", readBuf); - - DicConsole.WriteLine("Trying READ SECTOR(S) RETRY in LBA mode..."); - sense = dev.Read(out readBuf, out errorLba, true, 0, 1, TIMEOUT, out _); - report.ATA.ReadCapabilities.SupportsReadRetryLba = - !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, - errorLba.Status, errorLba.Error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readsectorsretry", "_debug_" + report.ATA.Model + ".bin", - "read results", readBuf); - - DicConsole.WriteLine("Trying READ DMA in LBA mode..."); - sense = dev.ReadDma(out readBuf, out errorLba, false, 0, 1, TIMEOUT, out _); - report.ATA.ReadCapabilities.SupportsReadDmaLba = - !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, - errorLba.Status, errorLba.Error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readdma", "_debug_" + report.ATA.Model + ".bin", "read results", - readBuf); - - DicConsole.WriteLine("Trying READ DMA RETRY in LBA mode..."); - sense = dev.ReadDma(out readBuf, out errorLba, true, 0, 1, TIMEOUT, out _); - report.ATA.ReadCapabilities.SupportsReadDmaRetryLba = - !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, - errorLba.Status, errorLba.Error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readdmaretry", "_debug_" + report.ATA.Model + ".bin", - "read results", readBuf); - - DicConsole.WriteLine("Trying SEEK in LBA mode..."); - sense = dev.Seek(out errorLba, 0, TIMEOUT, out _); - report.ATA.ReadCapabilities.SupportsSeekLba = - !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0; - DicConsole.DebugWriteLine("ATA Report", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}", sense, - errorLba.Status, errorLba.Error); - - DicConsole.WriteLine("Trying READ SECTOR(S) in LBA48 mode..."); - sense = dev.Read(out readBuf, out AtaErrorRegistersLba48 errorLba48, 0, 1, TIMEOUT, out _); - report.ATA.ReadCapabilities.SupportsReadLba48 = - !sense && (errorLba48.Status & 0x01) != 0x01 && errorLba48.Error == 0 && readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, - errorLba48.Status, errorLba48.Error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readsectors48", "_debug_" + report.ATA.Model + ".bin", - "read results", readBuf); - - DicConsole.WriteLine("Trying READ DMA in LBA48 mode..."); - sense = dev.ReadDma(out readBuf, out errorLba48, 0, 1, TIMEOUT, out _); - report.ATA.ReadCapabilities.SupportsReadDmaLba48 = - !sense && (errorLba48.Status & 0x01) != 0x01 && errorLba48.Error == 0 && readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, - errorLba48.Status, errorLba48.Error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readdma48", "_debug_" + report.ATA.Model + ".bin", - "read results", readBuf); - - DicConsole.WriteLine("Trying READ LONG in CHS mode..."); - sense = dev.ReadLong(out readBuf, out errorChs, false, 0, 0, 1, - report.ATA.ReadCapabilities.LongBlockSize, TIMEOUT, out _); - report.ATA.ReadCapabilities.SupportsReadLong = - !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && readBuf.Length > 0 && - BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, - errorChs.Status, errorChs.Error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readlongchs", "_debug_" + report.ATA.Model + ".bin", - "read results", readBuf); - - DicConsole.WriteLine("Trying READ LONG RETRY in CHS mode..."); - sense = dev.ReadLong(out readBuf, out errorChs, true, 0, 0, 1, - report.ATA.ReadCapabilities.LongBlockSize, TIMEOUT, out _); - report.ATA.ReadCapabilities.SupportsReadLongRetry = - !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && readBuf.Length > 0 && - BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, - errorChs.Status, errorChs.Error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readlongretrychs", "_debug_" + report.ATA.Model + ".bin", - "read results", readBuf); - - DicConsole.WriteLine("Trying READ LONG in LBA mode..."); - sense = dev.ReadLong(out readBuf, out errorLba, false, 0, report.ATA.ReadCapabilities.LongBlockSize, - TIMEOUT, out _); - report.ATA.ReadCapabilities.SupportsReadLongLba = - !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && readBuf.Length > 0 && - BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, - errorLba.Status, errorLba.Error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readlong", "_debug_" + report.ATA.Model + ".bin", - "read results", readBuf); - - DicConsole.WriteLine("Trying READ LONG RETRY in LBA mode..."); - sense = dev.ReadLong(out readBuf, out errorLba, true, 0, report.ATA.ReadCapabilities.LongBlockSize, - TIMEOUT, out _); - report.ATA.ReadCapabilities.SupportsReadLongRetryLba = - !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && readBuf.Length > 0 && - BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, - errorLba.Status, errorLba.Error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readlongretry", "_debug_" + report.ATA.Model + ".bin", - "read results", readBuf); + else physicalsectorsize = logicalsectorsize; } + else + { + logicalsectorsize = 512; + physicalsectorsize = 512; + } + + report.ATA.ReadCapabilities.BlockSize = logicalsectorsize; + report.ATA.ReadCapabilities.BlockSizeSpecified = true; + if(physicalsectorsize != logicalsectorsize) + { + report.ATA.ReadCapabilities.PhysicalBlockSize = physicalsectorsize; + report.ATA.ReadCapabilities.PhysicalBlockSizeSpecified = true; + + if((ataId.LogicalAlignment & 0x8000) == 0x0000 && (ataId.LogicalAlignment & 0x4000) == 0x4000) + { + report.ATA.ReadCapabilities.LogicalAlignment = (ushort)(ataId.LogicalAlignment & 0x3FFF); + report.ATA.ReadCapabilities.LogicalAlignmentSpecified = true; + } + } + + if(ataId.EccBytes != 0x0000 && ataId.EccBytes != 0xFFFF) + { + report.ATA.ReadCapabilities.LongBlockSize = logicalsectorsize + ataId.EccBytes; + report.ATA.ReadCapabilities.LongBlockSizeSpecified = true; + } + + if(ataId.UnformattedBPS > logicalsectorsize && + (!report.ATA.ReadCapabilities.LongBlockSizeSpecified || + report.ATA.ReadCapabilities.LongBlockSize == 516)) + { + report.ATA.ReadCapabilities.LongBlockSize = ataId.UnformattedBPS; + report.ATA.ReadCapabilities.LongBlockSizeSpecified = true; + } + + if(ataId.CommandSet3.HasFlag(Identify.CommandSetBit3.MustBeSet) && + !ataId.CommandSet3.HasFlag(Identify.CommandSetBit3.MustBeClear) && + ataId.EnabledCommandSet3.HasFlag(Identify.CommandSetBit3.MediaSerial)) + { + report.ATA.ReadCapabilities.CanReadMediaSerial = true; + report.ATA.ReadCapabilities.CanReadMediaSerialSpecified = true; + if(!string.IsNullOrWhiteSpace(ataId.MediaManufacturer)) + { + report.ATA.ReadCapabilities.Manufacturer = ataId.MediaManufacturer; + report.ATA.ReadCapabilities.ManufacturerSpecified = true; + } + } + + report.ATA.ReadCapabilities.SupportsReadLbaSpecified = true; + report.ATA.ReadCapabilities.SupportsReadRetryLbaSpecified = true; + report.ATA.ReadCapabilities.SupportsReadDmaLbaSpecified = true; + report.ATA.ReadCapabilities.SupportsReadDmaRetryLbaSpecified = true; + report.ATA.ReadCapabilities.SupportsReadLongLbaSpecified = true; + report.ATA.ReadCapabilities.SupportsReadLongRetryLbaSpecified = true; + report.ATA.ReadCapabilities.SupportsSeekLbaSpecified = true; + + report.ATA.ReadCapabilities.SupportsReadLba48Specified = true; + report.ATA.ReadCapabilities.SupportsReadDmaLba48Specified = true; + + report.ATA.ReadCapabilities.SupportsReadSpecified = true; + report.ATA.ReadCapabilities.SupportsReadRetrySpecified = true; + report.ATA.ReadCapabilities.SupportsReadDmaSpecified = true; + report.ATA.ReadCapabilities.SupportsReadDmaRetrySpecified = true; + report.ATA.ReadCapabilities.SupportsReadLongSpecified = true; + report.ATA.ReadCapabilities.SupportsReadLongRetrySpecified = true; + report.ATA.ReadCapabilities.SupportsSeekSpecified = true; + + ulong checkCorrectRead = BitConverter.ToUInt64(buffer, 0); + bool sense; + + 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 _); + report.ATA.ReadCapabilities.SupportsRead = + !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, + errorChs.Status, errorChs.Error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readsectorschs", "_debug_" + report.ATA.Model + ".bin", + "read results", readBuf); + + DicConsole.WriteLine("Trying READ SECTOR(S) RETRY in CHS mode..."); + sense = dev.Read(out readBuf, out errorChs, true, 0, 0, 1, 1, TIMEOUT, out _); + report.ATA.ReadCapabilities.SupportsReadRetry = + !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, + errorChs.Status, errorChs.Error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readsectorsretrychs", "_debug_" + report.ATA.Model + ".bin", + "read results", readBuf); + + DicConsole.WriteLine("Trying READ DMA in CHS mode..."); + sense = dev.ReadDma(out readBuf, out errorChs, false, 0, 0, 1, 1, TIMEOUT, out _); + report.ATA.ReadCapabilities.SupportsReadDma = + !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, + errorChs.Status, errorChs.Error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readdmachs", "_debug_" + report.ATA.Model + ".bin", + "read results", readBuf); + + DicConsole.WriteLine("Trying READ DMA RETRY in CHS mode..."); + sense = dev.ReadDma(out readBuf, out errorChs, true, 0, 0, 1, 1, TIMEOUT, out _); + report.ATA.ReadCapabilities.SupportsReadDmaRetry = + !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, + errorChs.Status, errorChs.Error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readdmaretrychs", "_debug_" + report.ATA.Model + ".bin", + "read results", readBuf); + + DicConsole.WriteLine("Trying SEEK in CHS mode..."); + sense = dev.Seek(out errorChs, 0, 0, 1, TIMEOUT, out _); + report.ATA.ReadCapabilities.SupportsSeek = + !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0; + DicConsole.DebugWriteLine("ATA Report", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}", sense, + errorChs.Status, errorChs.Error); + + DicConsole.WriteLine("Trying READ SECTOR(S) in LBA mode..."); + sense = dev.Read(out readBuf, out AtaErrorRegistersLba28 errorLba, false, 0, 1, TIMEOUT, out _); + report.ATA.ReadCapabilities.SupportsReadLba = + !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, + errorLba.Status, errorLba.Error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readsectors", "_debug_" + report.ATA.Model + ".bin", + "read results", readBuf); + + DicConsole.WriteLine("Trying READ SECTOR(S) RETRY in LBA mode..."); + sense = dev.Read(out readBuf, out errorLba, true, 0, 1, TIMEOUT, out _); + report.ATA.ReadCapabilities.SupportsReadRetryLba = + !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, + errorLba.Status, errorLba.Error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readsectorsretry", "_debug_" + report.ATA.Model + ".bin", + "read results", readBuf); + + DicConsole.WriteLine("Trying READ DMA in LBA mode..."); + sense = dev.ReadDma(out readBuf, out errorLba, false, 0, 1, TIMEOUT, out _); + report.ATA.ReadCapabilities.SupportsReadDmaLba = + !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, + errorLba.Status, errorLba.Error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readdma", "_debug_" + report.ATA.Model + ".bin", "read results", + readBuf); + + DicConsole.WriteLine("Trying READ DMA RETRY in LBA mode..."); + sense = dev.ReadDma(out readBuf, out errorLba, true, 0, 1, TIMEOUT, out _); + report.ATA.ReadCapabilities.SupportsReadDmaRetryLba = + !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, + errorLba.Status, errorLba.Error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readdmaretry", "_debug_" + report.ATA.Model + ".bin", + "read results", readBuf); + + DicConsole.WriteLine("Trying SEEK in LBA mode..."); + sense = dev.Seek(out errorLba, 0, TIMEOUT, out _); + report.ATA.ReadCapabilities.SupportsSeekLba = + !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0; + DicConsole.DebugWriteLine("ATA Report", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}", sense, + errorLba.Status, errorLba.Error); + + DicConsole.WriteLine("Trying READ SECTOR(S) in LBA48 mode..."); + sense = dev.Read(out readBuf, out AtaErrorRegistersLba48 errorLba48, 0, 1, TIMEOUT, out _); + report.ATA.ReadCapabilities.SupportsReadLba48 = + !sense && (errorLba48.Status & 0x01) != 0x01 && errorLba48.Error == 0 && readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, + errorLba48.Status, errorLba48.Error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readsectors48", "_debug_" + report.ATA.Model + ".bin", + "read results", readBuf); + + DicConsole.WriteLine("Trying READ DMA in LBA48 mode..."); + sense = dev.ReadDma(out readBuf, out errorLba48, 0, 1, TIMEOUT, out _); + report.ATA.ReadCapabilities.SupportsReadDmaLba48 = + !sense && (errorLba48.Status & 0x01) != 0x01 && errorLba48.Error == 0 && readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, + errorLba48.Status, errorLba48.Error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readdma48", "_debug_" + report.ATA.Model + ".bin", + "read results", readBuf); + + DicConsole.WriteLine("Trying READ LONG in CHS mode..."); + sense = dev.ReadLong(out readBuf, out errorChs, false, 0, 0, 1, + report.ATA.ReadCapabilities.LongBlockSize, TIMEOUT, out _); + report.ATA.ReadCapabilities.SupportsReadLong = + !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && readBuf.Length > 0 && + BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, + errorChs.Status, errorChs.Error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readlongchs", "_debug_" + report.ATA.Model + ".bin", + "read results", readBuf); + + DicConsole.WriteLine("Trying READ LONG RETRY in CHS mode..."); + sense = dev.ReadLong(out readBuf, out errorChs, true, 0, 0, 1, + report.ATA.ReadCapabilities.LongBlockSize, TIMEOUT, out _); + report.ATA.ReadCapabilities.SupportsReadLongRetry = + !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && readBuf.Length > 0 && + BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, + errorChs.Status, errorChs.Error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readlongretrychs", "_debug_" + report.ATA.Model + ".bin", + "read results", readBuf); + + DicConsole.WriteLine("Trying READ LONG in LBA mode..."); + sense = dev.ReadLong(out readBuf, out errorLba, false, 0, report.ATA.ReadCapabilities.LongBlockSize, + TIMEOUT, out _); + report.ATA.ReadCapabilities.SupportsReadLongLba = + !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && readBuf.Length > 0 && + BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, + errorLba.Status, errorLba.Error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readlong", "_debug_" + report.ATA.Model + ".bin", + "read results", readBuf); + + DicConsole.WriteLine("Trying READ LONG RETRY in LBA mode..."); + sense = dev.ReadLong(out readBuf, out errorLba, true, 0, report.ATA.ReadCapabilities.LongBlockSize, + TIMEOUT, out _); + report.ATA.ReadCapabilities.SupportsReadLongRetryLba = + !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && readBuf.Length > 0 && + BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, + errorLba.Status, errorLba.Error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readlongretry", "_debug_" + report.ATA.Model + ".bin", + "read results", readBuf); } } } diff --git a/DiscImageChef.Core/Devices/Report/ATAPI.cs b/DiscImageChef.Core/Devices/Report/ATAPI.cs index 37991771..1fa62a72 100644 --- a/DiscImageChef.Core/Devices/Report/ATAPI.cs +++ b/DiscImageChef.Core/Devices/Report/ATAPI.cs @@ -37,9 +37,18 @@ using DiscImageChef.Metadata; namespace DiscImageChef.Core.Devices.Report { + /// + /// Implements creating a report for an ATAPI device + /// static class Atapi { - internal static void Report(Device dev, ref DeviceReport report, bool debug, ref bool removable) + /// + /// Fills a SCSI device report with parameters specific to an ATAPI device + /// + /// Device + /// Device report + /// If debug is enabled + internal static void Report(Device dev, ref DeviceReport report, bool debug) { if(report == null) return; diff --git a/DiscImageChef.Core/Devices/Report/FireWire.cs b/DiscImageChef.Core/Devices/Report/FireWire.cs index bf765885..72aa406d 100644 --- a/DiscImageChef.Core/Devices/Report/FireWire.cs +++ b/DiscImageChef.Core/Devices/Report/FireWire.cs @@ -37,8 +37,17 @@ using DiscImageChef.Metadata; namespace DiscImageChef.Core.Devices.Report { + /// + /// Implements creating a report for a FireWire device + /// static class FireWire - { + { + /// + /// Fills a device report with parameters specific to a FireWire device + /// + /// Device + /// Device report + /// If device is removable internal static void Report(Device dev, ref DeviceReport report, ref bool removable) { if(report == null) return; diff --git a/DiscImageChef.Core/Devices/Report/PCMCIA.cs b/DiscImageChef.Core/Devices/Report/PCMCIA.cs index 791ef8b0..72f71483 100644 --- a/DiscImageChef.Core/Devices/Report/PCMCIA.cs +++ b/DiscImageChef.Core/Devices/Report/PCMCIA.cs @@ -36,8 +36,16 @@ using DiscImageChef.Metadata; namespace DiscImageChef.Core.Devices.Report { + /// + /// Implements creating a report for a PCMCIA device + /// static class Pcmcia { + /// + /// Fills a device report with parameters specific to a PCMCIA device + /// + /// Device + /// Device report internal static void Report(Device dev, ref DeviceReport report) { report.PCMCIA = new pcmciaType {CIS = dev.Cis}; diff --git a/DiscImageChef.Core/Devices/Report/SCSI/General.cs b/DiscImageChef.Core/Devices/Report/SCSI/General.cs index b81a739a..3ba7baf3 100644 --- a/DiscImageChef.Core/Devices/Report/SCSI/General.cs +++ b/DiscImageChef.Core/Devices/Report/SCSI/General.cs @@ -42,8 +42,18 @@ using DiscImageChef.Metadata; namespace DiscImageChef.Core.Devices.Report.SCSI { + /// + /// Implements creating a report of SCSI and ATAPI devices + /// public static class General { + /// + /// Creates a report of SCSI and ATAPI devices, and if appropiate calls the report creators for MultiMedia and Streaming devices + /// + /// Device + /// Device report + /// If debug is enabled + /// If device is removable 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 mediaTypes = new List(); - 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; diff --git a/DiscImageChef.Core/Devices/Report/SCSI/MMC.cs b/DiscImageChef.Core/Devices/Report/SCSI/MMC.cs index c59e62fe..193591c9 100644 --- a/DiscImageChef.Core/Devices/Report/SCSI/MMC.cs +++ b/DiscImageChef.Core/Devices/Report/SCSI/MMC.cs @@ -43,16 +43,26 @@ using DiscImageChef.Metadata; namespace DiscImageChef.Core.Devices.Report.SCSI { + /// + /// Implements creating a report for a SCSI MultiMedia device + /// static class Mmc { - internal static void Report(Device dev, ref DeviceReport report, bool debug, - ref Modes.ModePage_2A? cdromMode, ref List mediaTypes) + /// + /// Fills a SCSI device report with parameters and media tests specific to a MultiMedia device + /// + /// Device + /// Device report + /// If debug is enabled + /// Decoded MODE PAGE 2Ah + 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 mediaTypes = new List(); report.SCSI.MultiMediaDevice = new mmcType(); if(cdromMode.HasValue) diff --git a/DiscImageChef.Core/Devices/Report/SCSI/SSC.cs b/DiscImageChef.Core/Devices/Report/SCSI/SSC.cs index 06be78da..6fb44b89 100644 --- a/DiscImageChef.Core/Devices/Report/SCSI/SSC.cs +++ b/DiscImageChef.Core/Devices/Report/SCSI/SSC.cs @@ -41,8 +41,17 @@ using DiscImageChef.Metadata; namespace DiscImageChef.Core.Devices.Report.SCSI { + /// + /// Implements creating a report for a SCSI Streaming device + /// static class Ssc { + /// + /// Fills a SCSI device report with parameters and media tests specific to a Streaming device + /// + /// Device + /// Device report + /// If debug is enabled internal static void Report(Device dev, ref DeviceReport report, bool debug) { if(report == null) return; diff --git a/DiscImageChef.Core/Devices/Report/SecureDigital.cs b/DiscImageChef.Core/Devices/Report/SecureDigital.cs index 7b6e3c3f..bc76f92c 100644 --- a/DiscImageChef.Core/Devices/Report/SecureDigital.cs +++ b/DiscImageChef.Core/Devices/Report/SecureDigital.cs @@ -36,8 +36,16 @@ using DiscImageChef.Metadata; namespace DiscImageChef.Core.Devices.Report { + /// + /// Implements creating a device report for a SecureDigital or MultiMediaCard flash card + /// public static class SecureDigital { + /// + /// Creates a device report for a SecureDigital or MultiMediaCard flash card + /// + /// Device + /// Device report public static void Report(Device dev, ref DeviceReport report) { if(report == null) return; diff --git a/DiscImageChef.Core/Devices/Report/USB.cs b/DiscImageChef.Core/Devices/Report/USB.cs index 0a8da7ff..4d49222a 100644 --- a/DiscImageChef.Core/Devices/Report/USB.cs +++ b/DiscImageChef.Core/Devices/Report/USB.cs @@ -37,8 +37,18 @@ using DiscImageChef.Metadata; namespace DiscImageChef.Core.Devices.Report { + /// + /// Implements creating a report for a USB device + /// static class Usb { + /// + /// Fills a device report with parameters specific to a USB device + /// + /// Device + /// Device report + /// If device is removable + /// If debug is enabled internal static void Report(Device dev, ref DeviceReport report, bool debug, ref bool removable) { if(report == null) return; diff --git a/DiscImageChef.Core/Devices/Scanning/ATA.cs b/DiscImageChef.Core/Devices/Scanning/ATA.cs index 7972765f..1a7a16b2 100644 --- a/DiscImageChef.Core/Devices/Scanning/ATA.cs +++ b/DiscImageChef.Core/Devices/Scanning/ATA.cs @@ -39,8 +39,19 @@ using DiscImageChef.Devices; namespace DiscImageChef.Core.Devices.Scanning { + /// + /// Implements scanning the media from an ATA device + /// public static class Ata { + /// + /// Scans the media from an ATA device + /// + /// Path to a MHDD log file + /// Path to a IMGBurn log file + /// Device path + /// Device + /// Scanning results public static ScanResults Scan(string mhddLogPath, string ibgLogPath, string devicePath, Device dev) { ScanResults results = new ScanResults(); diff --git a/DiscImageChef.Core/Devices/Scanning/SCSI.cs b/DiscImageChef.Core/Devices/Scanning/SCSI.cs index 4b9af827..958f167e 100644 --- a/DiscImageChef.Core/Devices/Scanning/SCSI.cs +++ b/DiscImageChef.Core/Devices/Scanning/SCSI.cs @@ -42,6 +42,9 @@ using DiscImageChef.Devices; namespace DiscImageChef.Core.Devices.Scanning { + /// + /// Implements scanning the media from an SCSI device + /// public static class Scsi { public static ScanResults Scan(string mhddLogPath, string ibgLogPath, string devicePath, Device dev) diff --git a/DiscImageChef.Core/Devices/Scanning/ScanResults.cs b/DiscImageChef.Core/Devices/Scanning/ScanResults.cs index fa8a76f8..6525553c 100644 --- a/DiscImageChef.Core/Devices/Scanning/ScanResults.cs +++ b/DiscImageChef.Core/Devices/Scanning/ScanResults.cs @@ -34,25 +34,82 @@ using System.Collections.Generic; namespace DiscImageChef.Core.Devices.Scanning { + /// + /// Contains the results of a media scan + /// public struct ScanResults { + /// + /// Total time spent scanning + /// public double TotalTime; + /// + /// Total time spent by the device processing commands + /// public double ProcessingTime; + /// + /// Average scan speed + /// public double AvgSpeed; + /// + /// Maximum scan speed burst + /// public double MaxSpeed; + /// + /// Minimum scan speed + /// public double MinSpeed; + /// + /// Sectors that took less than 3 milliseconds to be processed + /// public ulong A; + /// + /// Sectors that took less than 10 milliseconds but more than 3 milliseconds to be processed + /// public ulong B; + /// + /// Sectors that took less than 50 milliseconds but more than 10 milliseconds to be processed + /// public ulong C; + /// + /// Sectors that took less than 150 milliseconds but more than 50 milliseconds to be processed + /// public ulong D; + /// + /// Sectors that took less than 500 milliseconds but more than 150 milliseconds to be processed + /// public ulong E; + /// + /// Sectors that took more than 500 milliseconds to be processed + /// public ulong F; + /// + /// List of sectors that could not be read + /// public List UnreadableSectors; + /// + /// Slowest seek + /// public double SeekMax; + /// + /// Fastest seek + /// public double SeekMin; + /// + /// Total time spent seeking + /// public double SeekTotal; + /// + /// How many seeks have been done + /// public int SeekTimes; + /// + /// How many blocks were scanned + /// public ulong Blocks; + /// + /// How many blocks could not be read + /// public ulong Errored; } } \ No newline at end of file diff --git a/DiscImageChef.Core/Devices/Scanning/SecureDigital.cs b/DiscImageChef.Core/Devices/Scanning/SecureDigital.cs index 2bad12e5..6879a2f8 100644 --- a/DiscImageChef.Core/Devices/Scanning/SecureDigital.cs +++ b/DiscImageChef.Core/Devices/Scanning/SecureDigital.cs @@ -39,6 +39,9 @@ using DiscImageChef.Devices; namespace DiscImageChef.Core.Devices.Scanning { + /// + /// Implements scanning a SecureDigital or MultiMediaCard flash card + /// public static class SecureDigital { public static ScanResults Scan(string mhddLogPath, string ibgLogPath, string devicePath, Device dev) diff --git a/DiscImageChef.Core/Filesystems.cs b/DiscImageChef.Core/Filesystems.cs index 1b756c87..fe848ca6 100644 --- a/DiscImageChef.Core/Filesystems.cs +++ b/DiscImageChef.Core/Filesystems.cs @@ -39,6 +39,12 @@ namespace DiscImageChef.Core { public static class Filesystems { + /// + /// Traverses all known filesystems and outputs a list of all that recognized what is in the specified image and partition + /// + /// Media image + /// List of plugins recognizing the filesystem + /// Partition public static void Identify(ImagePlugin imagePlugin, out List idPlugins, Partition partition) { PluginBase plugins = new PluginBase(); diff --git a/DiscImageChef.Core/ImageFormat.cs b/DiscImageChef.Core/ImageFormat.cs index 79f5a41d..e8546b7f 100644 --- a/DiscImageChef.Core/ImageFormat.cs +++ b/DiscImageChef.Core/ImageFormat.cs @@ -40,6 +40,11 @@ namespace DiscImageChef.Core { public static class ImageFormat { + /// + /// Detects the image plugin that recognizes the data inside a filter + /// + /// Filter + /// Detected image plugin public static ImagePlugin Detect(Filter imageFilter) { try diff --git a/DiscImageChef.Core/Logging/DumpLog.cs b/DiscImageChef.Core/Logging/DumpLog.cs index b6590149..a9e61f36 100644 --- a/DiscImageChef.Core/Logging/DumpLog.cs +++ b/DiscImageChef.Core/Logging/DumpLog.cs @@ -39,10 +39,18 @@ using PlatformID = DiscImageChef.Interop.PlatformID; namespace DiscImageChef.Core.Logging { + /// + /// Creates a dump log + /// public class DumpLog { readonly StreamWriter logSw; + /// + /// Initializes the dump log + /// + /// Output log file + /// Device public DumpLog(string outputFile, Device dev) { if(string.IsNullOrEmpty(outputFile)) return; @@ -113,6 +121,11 @@ namespace DiscImageChef.Core.Logging logSw.Flush(); } + /// + /// Adds a new line to the dump log + /// + /// Format string + /// Arguments public void WriteLine(string format, params object[] args) { if(logSw == null) return; @@ -122,6 +135,9 @@ namespace DiscImageChef.Core.Logging logSw.Flush(); } + /// + /// Finishes and closes the dump log + /// public void Close() { logSw?.WriteLine("######################################################"); diff --git a/DiscImageChef.Core/Logging/IBGLog.cs b/DiscImageChef.Core/Logging/IBGLog.cs index 7cc8ab02..1be97b4c 100644 --- a/DiscImageChef.Core/Logging/IBGLog.cs +++ b/DiscImageChef.Core/Logging/IBGLog.cs @@ -38,6 +38,9 @@ using DiscImageChef.Devices; namespace DiscImageChef.Core.Logging { + /// + /// Implements a log in the format used by IMGBurn + /// class IbgLog { StringBuilder ibgSb; @@ -54,6 +57,11 @@ namespace DiscImageChef.Core.Logging int ibgSampleRate; string logFile; + /// + /// Initializes the IMGBurn log + /// + /// Log file + /// Profile as defined by SCSI MultiMedia Commands specification internal IbgLog(string outputFile, ushort currentProfile) { if(string.IsNullOrEmpty(outputFile)) return; @@ -192,6 +200,11 @@ namespace DiscImageChef.Core.Logging } } + /// + /// Adds a new speed snapshot to the log + /// + /// Sector for the snapshot + /// Current speed at the snapshot internal void Write(ulong sector, double currentSpeed) { if(logFile == null) return; @@ -219,6 +232,16 @@ namespace DiscImageChef.Core.Logging ibgIntSector = sector; } + /// + /// Closes the IMGBurn log + /// + /// Device + /// Media blocks + /// Bytes per block + /// Total seconds spent dumping + /// Speed at the end + /// Average speed + /// Device path internal void Close(Device dev, ulong blocks, ulong blockSize, double totalSeconds, double currentSpeed, double averageSpeed, string devicePath) { diff --git a/DiscImageChef.Core/Logging/MHDDLog.cs b/DiscImageChef.Core/Logging/MHDDLog.cs index cda3635a..3bdd87e3 100644 --- a/DiscImageChef.Core/Logging/MHDDLog.cs +++ b/DiscImageChef.Core/Logging/MHDDLog.cs @@ -38,11 +38,22 @@ using DiscImageChef.Devices; namespace DiscImageChef.Core.Logging { + /// + /// Implements a log in the format used by MHDD + /// class MhddLog { MemoryStream mhddFs; string logFile; + /// + /// Initializes the MHDD log + /// + /// Log file + /// Device + /// Blocks in media + /// Bytes per block + /// How many blocks read at once 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); } + /// + /// Logs a new read + /// + /// Starting sector + /// Duration in milliseconds internal void Write(ulong sector, double duration) { if(logFile == null) return; @@ -134,6 +150,9 @@ namespace DiscImageChef.Core.Logging mhddFs.Write(durationBytes, 0, 8); } + /// + /// Closes and writes to file the MHDD log + /// internal void Close() { if(logFile == null) return; diff --git a/DiscImageChef.Core/Partitions.cs b/DiscImageChef.Core/Partitions.cs index 9dcad703..a76d8d08 100644 --- a/DiscImageChef.Core/Partitions.cs +++ b/DiscImageChef.Core/Partitions.cs @@ -39,8 +39,16 @@ using DiscImageChef.Partitions; namespace DiscImageChef.Core { + /// + /// Implements methods for handling partitions + /// public static class Partitions { + /// + /// Gets a list of all partitions present in the specified image + /// + /// Image + /// List of found partitions public static List GetAll(ImagePlugin image) { PluginBase plugins = new PluginBase(); @@ -136,6 +144,10 @@ namespace DiscImageChef.Core return childArray.ToList(); } + /// + /// Adds all partition schemes from the specified list of partitions to statistics + /// + /// List of partitions public static void AddSchemesToStats(List partitions) { if(partitions == null || partitions.Count == 0) return; diff --git a/DiscImageChef.Core/PluginBase.cs b/DiscImageChef.Core/PluginBase.cs index e3a8ec75..437e0948 100644 --- a/DiscImageChef.Core/PluginBase.cs +++ b/DiscImageChef.Core/PluginBase.cs @@ -41,12 +41,27 @@ using DiscImageChef.Partitions; namespace DiscImageChef.Core { + /// + /// Contain all plugins (filesystem, partition and image) + /// public class PluginBase { + /// + /// List of all filesystem plugins + /// public SortedDictionary PluginsList; + /// + /// List of all partition plugins + /// public SortedDictionary PartPluginsList; + /// + /// List of all media image plugins + /// public SortedDictionary ImagePluginsList; + /// + /// Initializes the plugins lists + /// public PluginBase() { PluginsList = new SortedDictionary(); @@ -54,6 +69,10 @@ namespace DiscImageChef.Core ImagePluginsList = new SortedDictionary(); } + /// + /// Fills the plugins lists + /// + /// Which encoding to pass to plugins public void RegisterAllPlugins(Encoding encoding = null) { Assembly assembly = Assembly.GetAssembly(typeof(ImagePlugin)); diff --git a/DiscImageChef.Core/Remote.cs b/DiscImageChef.Core/Remote.cs index 3d69cf50..30d862ef 100644 --- a/DiscImageChef.Core/Remote.cs +++ b/DiscImageChef.Core/Remote.cs @@ -39,8 +39,15 @@ using DiscImageChef.Metadata; namespace DiscImageChef.Core { + /// + /// Handles connections to DiscImageChef.Server + /// public static class Remote { + /// + /// Submits a device report + /// + /// Device report 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(); diff --git a/DiscImageChef.Core/Sidecar/AudioMedia.cs b/DiscImageChef.Core/Sidecar/AudioMedia.cs index 6923e571..3b271d2a 100644 --- a/DiscImageChef.Core/Sidecar/AudioMedia.cs +++ b/DiscImageChef.Core/Sidecar/AudioMedia.cs @@ -41,6 +41,16 @@ namespace DiscImageChef.Core public static partial class Sidecar { // TODO: Complete it + /// + /// Creates a metadata sidecar for an audio media (e.g. cassette) + /// + /// Image + /// Filter uuid + /// Image path + /// Image file information + /// Image plugins + /// List of image checksums + /// Metadata sidecar static void AudioMedia(ImagePlugin image, Guid filterId, string imagePath, FileInfo fi, PluginBase plugins, List imgChecksums, ref CICMMetadataType sidecar) { diff --git a/DiscImageChef.Core/Sidecar/BlockMedia.cs b/DiscImageChef.Core/Sidecar/BlockMedia.cs index 7a0a19bf..726ff1e6 100644 --- a/DiscImageChef.Core/Sidecar/BlockMedia.cs +++ b/DiscImageChef.Core/Sidecar/BlockMedia.cs @@ -50,6 +50,16 @@ namespace DiscImageChef.Core { public static partial class Sidecar { + /// + /// Creates a metadata sidecar for a block media (e.g. floppy, hard disk, flash card, usb stick) + /// + /// Image + /// Filter uuid + /// Image path + /// Image file information + /// Image plugins + /// List of image checksums + /// Metadata sidecar static void BlockMedia(ImagePlugin image, Guid filterId, string imagePath, FileInfo fi, PluginBase plugins, List imgChecksums, ref CICMMetadataType sidecar) { diff --git a/DiscImageChef.Core/Sidecar/BlockTape.cs b/DiscImageChef.Core/Sidecar/BlockTape.cs index a1b43e4e..2b3e20f7 100644 --- a/DiscImageChef.Core/Sidecar/BlockTape.cs +++ b/DiscImageChef.Core/Sidecar/BlockTape.cs @@ -38,6 +38,12 @@ namespace DiscImageChef.Core { public static partial class Sidecar { + /// + /// Creates a metadata sidecar for a block tape (e.g. scsi streaming) + /// + /// List of files + /// Dump path + /// Expected block size in bytes public static CICMMetadataType Create(string folderName, List files, int blockSize) { CICMMetadataType sidecar = new CICMMetadataType diff --git a/DiscImageChef.Core/Sidecar/Helpers.cs b/DiscImageChef.Core/Sidecar/Helpers.cs index bf221117..d517cf8d 100644 --- a/DiscImageChef.Core/Sidecar/Helpers.cs +++ b/DiscImageChef.Core/Sidecar/Helpers.cs @@ -34,6 +34,11 @@ namespace DiscImageChef.Core { public static partial class Sidecar { + /// + /// Converts a LBA to MM:SS:FF string for CDs + /// + /// LBA + /// MM:SS:FF static string LbaToMsf(long lba) { long m, s, f; @@ -57,6 +62,11 @@ namespace DiscImageChef.Core return $"{m}:{s:D2}:{f:D2}"; } + /// + /// Converts a LBA to MM:SS:FF string for DDCDs + /// + /// LBA + /// MM:SS:FF static string DdcdLbaToMsf(long lba) { long h, m, s, f; diff --git a/DiscImageChef.Core/Sidecar/LinearMedia.cs b/DiscImageChef.Core/Sidecar/LinearMedia.cs index de228860..62e6475c 100644 --- a/DiscImageChef.Core/Sidecar/LinearMedia.cs +++ b/DiscImageChef.Core/Sidecar/LinearMedia.cs @@ -41,6 +41,16 @@ namespace DiscImageChef.Core public static partial class Sidecar { // TODO: Complete it + /// + /// Creates a metadata sidecar for linear media (e.g. ROM chip) + /// + /// Image + /// Filter uuid + /// Image path + /// Image file information + /// Image plugins + /// List of image checksums + /// Metadata sidecar static void LinearMedia(ImagePlugin image, Guid filterId, string imagePath, FileInfo fi, PluginBase plugins, List imgChecksums, ref CICMMetadataType sidecar) { diff --git a/DiscImageChef.Core/Sidecar/OpticalDisc.cs b/DiscImageChef.Core/Sidecar/OpticalDisc.cs index 329b35c6..c3784dcb 100644 --- a/DiscImageChef.Core/Sidecar/OpticalDisc.cs +++ b/DiscImageChef.Core/Sidecar/OpticalDisc.cs @@ -47,6 +47,16 @@ namespace DiscImageChef.Core { public static partial class Sidecar { + /// + /// Creates a metadata sidecar for an optical disc (e.g. CD, DVD, GD, BD, XGD, GOD) + /// + /// Image + /// Filter uuid + /// Image path + /// Image file information + /// Image plugins + /// List of image checksums + /// Metadata sidecar static void OpticalDisc(ImagePlugin image, Guid filterId, string imagePath, FileInfo fi, PluginBase plugins, List imgChecksums, ref CICMMetadataType sidecar) { diff --git a/DiscImageChef.Core/Sidecar/Sidecar.cs b/DiscImageChef.Core/Sidecar/Sidecar.cs index 4e856016..7100e973 100644 --- a/DiscImageChef.Core/Sidecar/Sidecar.cs +++ b/DiscImageChef.Core/Sidecar/Sidecar.cs @@ -41,6 +41,14 @@ namespace DiscImageChef.Core { public static partial class Sidecar { + /// + /// Implements creating a metadata sidecar + /// + /// Image + /// Path to image + /// Filter uuid + /// Encoding for analysis + /// The metadata sidecar public static CICMMetadataType Create(ImagePlugin image, string imagePath, Guid filterId, Encoding encoding) { diff --git a/DiscImageChef.Core/Statistics.cs b/DiscImageChef.Core/Statistics.cs index 420460f2..01311031 100644 --- a/DiscImageChef.Core/Statistics.cs +++ b/DiscImageChef.Core/Statistics.cs @@ -44,13 +44,27 @@ using MediaType = DiscImageChef.CommonTypes.MediaType; namespace DiscImageChef.Core { + /// + /// Handles anonymous usage statistics + /// public static class Statistics { + /// + /// Contains all known statistics + /// public static Stats AllStats; + /// + /// Contains statistics of current execution + /// public static Stats CurrentStats; - + /// + /// Statistics file semaphore + /// static bool submitStatsLock; + /// + /// Loads saved statistics from disk + /// public static void LoadStats() { if(File.Exists(Path.Combine(Settings.Settings.StatsPath, "Statistics.xml"))) @@ -100,6 +114,9 @@ namespace DiscImageChef.Core } } + /// + /// Saves statistics to disk + /// public static void SaveStats() { if(AllStats == null) return; @@ -165,6 +182,9 @@ namespace DiscImageChef.Core if(Settings.Settings.Current.Stats.ShareStats) SubmitStats(); } + /// + /// Submits statistics to DiscImageChef.Server + /// 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(); } + /// + /// Adds the execution of a command to statistics + /// + /// Command 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 } } + /// + /// Adds a new filesystem to statistics + /// + /// Filesystem name 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); } + /// + /// Adds a new partition scheme to statistics + /// + /// Partition scheme name 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); } + /// + /// Adds a new filter to statistics + /// + /// Filter name 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); } + /// + /// Ads a new media image to statistics + /// + /// Media image name 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); } + /// + /// Adds a new device to statistics + /// + /// Device 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); } + /// + /// Adds a new media type to statistics + /// + /// Media type + /// Set if media was found on a real device, otherwise found on a media image 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); } + /// + /// Adds benchmark results to statistics + /// + /// Checksum times + /// Entropy times + /// Time for all running togheter + /// Time for sequential running + /// Maximum used memory + /// Minimum used memory public static void AddBenchmark(Dictionary checksums, double entropy, double all, double sequential, long maxMemory, long minMemory) { @@ -597,6 +655,14 @@ namespace DiscImageChef.Core AllStats.Benchmark.Sequential = sequential; } + /// + /// Adds a new media image verification to statistics + /// + /// Set if media was correctly verified + /// How many sectors where verified correctly + /// How many sectors failed verification + /// How many sectors could not be verified + /// Total sectors verified 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; } + /// + /// Adds a new media scan to statistics + /// + /// Sectors <3ms + /// Sectors >3ms and <10ms + /// Sectors >10ms and <50ms + /// Sectors >50ms and <150ms + /// Sectors >150ms and <500ms + /// Sectors >500ms + /// Total sectors + /// Errored sectors + /// Correct sectors public static void AddMediaScan(long lessThan3ms, long lessThan10ms, long lessThan50ms, long lessThan150ms, long lessThan500ms, long moreThan500ms, long total, long error, long correct) { diff --git a/DiscImageChef.Core/Version.cs b/DiscImageChef.Core/Version.cs index a4fcba49..8c3de517 100644 --- a/DiscImageChef.Core/Version.cs +++ b/DiscImageChef.Core/Version.cs @@ -37,8 +37,14 @@ namespace DiscImageChef.Core { static class Version { + /// + /// Gets XML software type for the running version + /// + /// Platform we are running in + /// XML software type internal static SoftwareType GetSoftwareType(PlatformID platform) { + // TODO: Platform should be get automatically return new SoftwareType { Name = "DiscImageChef", @@ -47,6 +53,10 @@ namespace DiscImageChef.Core }; } + /// + /// Gets version string + /// + /// Version internal static string GetVersion() { return typeof(Version).Assembly.GetName().Version.ToString();