diff --git a/ATA/Identify.cs b/ATA/Identify.cs
index c37ba6f..27079cf 100644
--- a/ATA/Identify.cs
+++ b/ATA/Identify.cs
@@ -35,2209 +35,2208 @@ using System.Diagnostics.CodeAnalysis;
using System.Text;
using Aaru.CommonTypes.Structs.Devices.SCSI;
-namespace Aaru.Decoders.ATA
+namespace Aaru.Decoders.ATA;
+
+// Information from following standards:
+// T10-791D rev. 4c (ATA)
+// T10-948D rev. 4c (ATA-2)
+// T13-1153D rev. 18 (ATA/ATAPI-4)
+// T13-1321D rev. 3 (ATA/ATAPI-5)
+// T13-1410D rev. 3b (ATA/ATAPI-6)
+// T13-1532D rev. 4b (ATA/ATAPI-7)
+// T13-1699D rev. 3f (ATA8-ACS)
+// T13-1699D rev. 4a (ATA8-ACS)
+// T13-2015D rev. 2 (ACS-2)
+// T13-2161D rev. 5 (ACS-3)
+// CF+ & CF Specification rev. 1.4 (CFA)
+[SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"),
+ SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
+public static class Identify
{
- // Information from following standards:
- // T10-791D rev. 4c (ATA)
- // T10-948D rev. 4c (ATA-2)
- // T13-1153D rev. 18 (ATA/ATAPI-4)
- // T13-1321D rev. 3 (ATA/ATAPI-5)
- // T13-1410D rev. 3b (ATA/ATAPI-6)
- // T13-1532D rev. 4b (ATA/ATAPI-7)
- // T13-1699D rev. 3f (ATA8-ACS)
- // T13-1699D rev. 4a (ATA8-ACS)
- // T13-2015D rev. 2 (ACS-2)
- // T13-2161D rev. 5 (ACS-3)
- // CF+ & CF Specification rev. 1.4 (CFA)
- [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"),
- SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
- public static class Identify
+ public static string Prettify(byte[] IdentifyDeviceResponse)
{
- public static string Prettify(byte[] IdentifyDeviceResponse)
+ if(IdentifyDeviceResponse.Length != 512)
+ return null;
+
+ CommonTypes.Structs.Devices.ATA.Identify.IdentifyDevice? decoded =
+ CommonTypes.Structs.Devices.ATA.Identify.Decode(IdentifyDeviceResponse);
+
+ return Prettify(decoded);
+ }
+
+ public static string Prettify(CommonTypes.Structs.Devices.ATA.Identify.IdentifyDevice? IdentifyDeviceResponse)
+ {
+ if(IdentifyDeviceResponse == null)
+ return null;
+
+ var sb = new StringBuilder();
+
+ bool atapi = false;
+ bool cfa = false;
+
+ CommonTypes.Structs.Devices.ATA.Identify.IdentifyDevice ATAID = IdentifyDeviceResponse.Value;
+
+ if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.GeneralConfigurationBit.
+ NonMagnetic))
+ if((ushort)ATAID.GeneralConfiguration != 0x848A)
+ atapi = true;
+ else
+ cfa = true;
+
+ if(atapi)
+ sb.AppendLine("ATAPI device");
+ else if(cfa)
+ sb.AppendLine("CompactFlash device");
+ else
+ sb.AppendLine("ATA device");
+
+ if(ATAID.Model != "")
+ sb.AppendFormat("Model: {0}", ATAID.Model).AppendLine();
+
+ if(ATAID.FirmwareRevision != "")
+ sb.AppendFormat("Firmware revision: {0}", ATAID.FirmwareRevision).AppendLine();
+
+ if(ATAID.SerialNumber != "")
+ sb.AppendFormat("Serial #: {0}", ATAID.SerialNumber).AppendLine();
+
+ if(ATAID.AdditionalPID != "")
+ sb.AppendFormat("Additional product ID: {0}", ATAID.AdditionalPID).AppendLine();
+
+ if(ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.MustBeSet) &&
+ !ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.MustBeClear))
{
- if(IdentifyDeviceResponse.Length != 512)
- return null;
+ if(ATAID.EnabledCommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.
+ MediaSerial))
+ {
+ if(ATAID.MediaManufacturer != "")
+ sb.AppendFormat("Media manufacturer: {0}", ATAID.MediaManufacturer).AppendLine();
- CommonTypes.Structs.Devices.ATA.Identify.IdentifyDevice? decoded =
- CommonTypes.Structs.Devices.ATA.Identify.Decode(IdentifyDeviceResponse);
+ if(ATAID.MediaSerial != "")
+ sb.AppendFormat("Media serial #: {0}", ATAID.MediaSerial).AppendLine();
+ }
- return Prettify(decoded);
+ if(ATAID.EnabledCommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.WWN))
+ sb.AppendFormat("World Wide Name: {0:X16}", ATAID.WWN).AppendLine();
}
- public static string Prettify(CommonTypes.Structs.Devices.ATA.Identify.IdentifyDevice? IdentifyDeviceResponse)
+ bool ata1 = false, ata2 = false, ata3 = false, ata4 = false, ata5 = false, ata6 = false, ata7 = false,
+ acs = false, acs2 = false, acs3 = false, acs4 = false;
+
+ if((ushort)ATAID.MajorVersion == 0x0000 ||
+ (ushort)ATAID.MajorVersion == 0xFFFF)
{
- if(IdentifyDeviceResponse == null)
- return null;
+ // Obsolete in ATA-2, if present, device supports ATA-1
+ ata1 |=
+ ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.GeneralConfigurationBit.
+ FastIDE) ||
+ ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.GeneralConfigurationBit.
+ SlowIDE) ||
+ ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.GeneralConfigurationBit.
+ UltraFastIDE);
- var sb = new StringBuilder();
+ ata2 |= ATAID.ExtendedIdentify.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.ExtendedIdentifyBit.
+ Words64to70Valid);
- bool atapi = false;
- bool cfa = false;
+ if(!ata1 &&
+ !ata2 &&
+ !atapi &&
+ !cfa)
+ ata2 = true;
- CommonTypes.Structs.Devices.ATA.Identify.IdentifyDevice ATAID = IdentifyDeviceResponse.Value;
+ ata4 |= atapi;
+ ata3 |= cfa;
- if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.GeneralConfigurationBit.
- NonMagnetic))
- if((ushort)ATAID.GeneralConfiguration != 0x848A)
- atapi = true;
- else
- cfa = true;
+ if(cfa && ata1)
+ ata1 = false;
- if(atapi)
- sb.AppendLine("ATAPI device");
- else if(cfa)
- sb.AppendLine("CompactFlash device");
- else
- sb.AppendLine("ATA device");
+ if(cfa && ata2)
+ ata2 = false;
- if(ATAID.Model != "")
- sb.AppendFormat("Model: {0}", ATAID.Model).AppendLine();
+ ata5 |= ATAID.Signature == 0xA5;
+ }
+ else
+ {
+ ata1 |= ATAID.MajorVersion.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.MajorVersionBit.Ata1);
+ ata2 |= ATAID.MajorVersion.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.MajorVersionBit.Ata2);
+ ata3 |= ATAID.MajorVersion.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.MajorVersionBit.Ata3);
+ ata4 |= ATAID.MajorVersion.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.MajorVersionBit.AtaAtapi4);
+ ata5 |= ATAID.MajorVersion.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.MajorVersionBit.AtaAtapi5);
+ ata6 |= ATAID.MajorVersion.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.MajorVersionBit.AtaAtapi6);
+ ata7 |= ATAID.MajorVersion.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.MajorVersionBit.AtaAtapi7);
+ acs |= ATAID.MajorVersion.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.MajorVersionBit.Ata8ACS);
+ acs2 |= ATAID.MajorVersion.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.MajorVersionBit.ACS2);
+ acs3 |= ATAID.MajorVersion.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.MajorVersionBit.ACS3);
+ acs4 |= ATAID.MajorVersion.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.MajorVersionBit.ACS4);
+ }
- if(ATAID.FirmwareRevision != "")
- sb.AppendFormat("Firmware revision: {0}", ATAID.FirmwareRevision).AppendLine();
+ int maxatalevel = 0;
+ int minatalevel = 255;
+ sb.Append("Supported ATA versions: ");
- if(ATAID.SerialNumber != "")
- sb.AppendFormat("Serial #: {0}", ATAID.SerialNumber).AppendLine();
+ if(ata1)
+ {
+ sb.Append("ATA-1 ");
+ maxatalevel = 1;
+ minatalevel = 1;
+ }
- if(ATAID.AdditionalPID != "")
- sb.AppendFormat("Additional product ID: {0}", ATAID.AdditionalPID).AppendLine();
+ if(ata2)
+ {
+ sb.Append("ATA-2 ");
+ maxatalevel = 2;
- if(ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.MustBeSet) &&
- !ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.MustBeClear))
+ if(minatalevel > 2)
+ minatalevel = 2;
+ }
+
+ if(ata3)
+ {
+ sb.Append("ATA-3 ");
+ maxatalevel = 3;
+
+ if(minatalevel > 3)
+ minatalevel = 3;
+ }
+
+ if(ata4)
+ {
+ sb.Append("ATA/ATAPI-4 ");
+ maxatalevel = 4;
+
+ if(minatalevel > 4)
+ minatalevel = 4;
+ }
+
+ if(ata5)
+ {
+ sb.Append("ATA/ATAPI-5 ");
+ maxatalevel = 5;
+
+ if(minatalevel > 5)
+ minatalevel = 5;
+ }
+
+ if(ata6)
+ {
+ sb.Append("ATA/ATAPI-6 ");
+ maxatalevel = 6;
+
+ if(minatalevel > 6)
+ minatalevel = 6;
+ }
+
+ if(ata7)
+ {
+ sb.Append("ATA/ATAPI-7 ");
+ maxatalevel = 7;
+
+ if(minatalevel > 7)
+ minatalevel = 7;
+ }
+
+ if(acs)
+ {
+ sb.Append("ATA8-ACS ");
+ maxatalevel = 8;
+
+ if(minatalevel > 8)
+ minatalevel = 8;
+ }
+
+ if(acs2)
+ {
+ sb.Append("ATA8-ACS2 ");
+ maxatalevel = 9;
+
+ if(minatalevel > 9)
+ minatalevel = 9;
+ }
+
+ if(acs3)
+ {
+ sb.Append("ATA8-ACS3 ");
+ maxatalevel = 10;
+
+ if(minatalevel > 10)
+ minatalevel = 10;
+ }
+
+ if(acs4)
+ {
+ sb.Append("ATA8-ACS4 ");
+ maxatalevel = 11;
+
+ if(minatalevel > 11)
+ minatalevel = 11;
+ }
+
+ sb.AppendLine();
+
+ sb.Append("Maximum ATA revision supported: ");
+
+ if(maxatalevel >= 3)
+ switch(ATAID.MinorVersion)
{
- if(ATAID.EnabledCommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.
- MediaSerial))
- {
- if(ATAID.MediaManufacturer != "")
- sb.AppendFormat("Media manufacturer: {0}", ATAID.MediaManufacturer).AppendLine();
-
- if(ATAID.MediaSerial != "")
- sb.AppendFormat("Media serial #: {0}", ATAID.MediaSerial).AppendLine();
- }
-
- if(ATAID.EnabledCommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.WWN))
- sb.AppendFormat("World Wide Name: {0:X16}", ATAID.WWN).AppendLine();
- }
-
- bool ata1 = false, ata2 = false, ata3 = false, ata4 = false, ata5 = false, ata6 = false, ata7 = false,
- acs = false, acs2 = false, acs3 = false, acs4 = false;
-
- if((ushort)ATAID.MajorVersion == 0x0000 ||
- (ushort)ATAID.MajorVersion == 0xFFFF)
- {
- // Obsolete in ATA-2, if present, device supports ATA-1
- ata1 |=
- ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.GeneralConfigurationBit.
- FastIDE) ||
- ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.GeneralConfigurationBit.
- SlowIDE) ||
- ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.GeneralConfigurationBit.
- UltraFastIDE);
-
- ata2 |= ATAID.ExtendedIdentify.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.ExtendedIdentifyBit.
- Words64to70Valid);
-
- if(!ata1 &&
- !ata2 &&
- !atapi &&
- !cfa)
- ata2 = true;
-
- ata4 |= atapi;
- ata3 |= cfa;
-
- if(cfa && ata1)
- ata1 = false;
-
- if(cfa && ata2)
- ata2 = false;
-
- ata5 |= ATAID.Signature == 0xA5;
- }
- else
- {
- ata1 |= ATAID.MajorVersion.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.MajorVersionBit.Ata1);
- ata2 |= ATAID.MajorVersion.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.MajorVersionBit.Ata2);
- ata3 |= ATAID.MajorVersion.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.MajorVersionBit.Ata3);
- ata4 |= ATAID.MajorVersion.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.MajorVersionBit.AtaAtapi4);
- ata5 |= ATAID.MajorVersion.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.MajorVersionBit.AtaAtapi5);
- ata6 |= ATAID.MajorVersion.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.MajorVersionBit.AtaAtapi6);
- ata7 |= ATAID.MajorVersion.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.MajorVersionBit.AtaAtapi7);
- acs |= ATAID.MajorVersion.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.MajorVersionBit.Ata8ACS);
- acs2 |= ATAID.MajorVersion.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.MajorVersionBit.ACS2);
- acs3 |= ATAID.MajorVersion.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.MajorVersionBit.ACS3);
- acs4 |= ATAID.MajorVersion.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.MajorVersionBit.ACS4);
- }
-
- int maxatalevel = 0;
- int minatalevel = 255;
- sb.Append("Supported ATA versions: ");
-
- if(ata1)
- {
- sb.Append("ATA-1 ");
- maxatalevel = 1;
- minatalevel = 1;
- }
-
- if(ata2)
- {
- sb.Append("ATA-2 ");
- maxatalevel = 2;
-
- if(minatalevel > 2)
- minatalevel = 2;
- }
-
- if(ata3)
- {
- sb.Append("ATA-3 ");
- maxatalevel = 3;
-
- if(minatalevel > 3)
- minatalevel = 3;
- }
-
- if(ata4)
- {
- sb.Append("ATA/ATAPI-4 ");
- maxatalevel = 4;
-
- if(minatalevel > 4)
- minatalevel = 4;
- }
-
- if(ata5)
- {
- sb.Append("ATA/ATAPI-5 ");
- maxatalevel = 5;
-
- if(minatalevel > 5)
- minatalevel = 5;
- }
-
- if(ata6)
- {
- sb.Append("ATA/ATAPI-6 ");
- maxatalevel = 6;
-
- if(minatalevel > 6)
- minatalevel = 6;
- }
-
- if(ata7)
- {
- sb.Append("ATA/ATAPI-7 ");
- maxatalevel = 7;
-
- if(minatalevel > 7)
- minatalevel = 7;
- }
-
- if(acs)
- {
- sb.Append("ATA8-ACS ");
- maxatalevel = 8;
-
- if(minatalevel > 8)
- minatalevel = 8;
- }
-
- if(acs2)
- {
- sb.Append("ATA8-ACS2 ");
- maxatalevel = 9;
-
- if(minatalevel > 9)
- minatalevel = 9;
- }
-
- if(acs3)
- {
- sb.Append("ATA8-ACS3 ");
- maxatalevel = 10;
-
- if(minatalevel > 10)
- minatalevel = 10;
- }
-
- if(acs4)
- {
- sb.Append("ATA8-ACS4 ");
- maxatalevel = 11;
-
- if(minatalevel > 11)
- minatalevel = 11;
- }
-
- sb.AppendLine();
-
- sb.Append("Maximum ATA revision supported: ");
-
- if(maxatalevel >= 3)
- switch(ATAID.MinorVersion)
- {
- case 0x0000:
- case 0xFFFF:
- sb.AppendLine("Minor ATA version not specified");
-
- break;
- case 0x0001:
- sb.AppendLine("ATA (ATA-1) X3T9.2 781D prior to revision 4");
-
- break;
- case 0x0002:
- sb.AppendLine("ATA-1 published, ANSI X3.221-1994");
-
- break;
- case 0x0003:
- sb.AppendLine("ATA (ATA-1) X3T9.2 781D revision 4");
-
- break;
- case 0x0004:
- sb.AppendLine("ATA-2 published, ANSI X3.279-1996");
-
- break;
- case 0x0005:
- sb.AppendLine("ATA-2 X3T10 948D prior to revision 2k");
-
- break;
- case 0x0006:
- sb.AppendLine("ATA-3 X3T10 2008D revision 1");
-
- break;
- case 0x0007:
- sb.AppendLine("ATA-2 X3T10 948D revision 2k");
-
- break;
- case 0x0008:
- sb.AppendLine("ATA-3 X3T10 2008D revision 0");
-
- break;
- case 0x0009:
- sb.AppendLine("ATA-2 X3T10 948D revision 3");
-
- break;
- case 0x000A:
- sb.AppendLine("ATA-3 published, ANSI X3.298-1997");
-
- break;
- case 0x000B:
- sb.AppendLine("ATA-3 X3T10 2008D revision 6");
-
- break;
- case 0x000C:
- sb.AppendLine("ATA-3 X3T13 2008D revision 7");
-
- break;
- case 0x000D:
- sb.AppendLine("ATA/ATAPI-4 X3T13 1153D revision 6");
-
- break;
- case 0x000E:
- sb.AppendLine("ATA/ATAPI-4 T13 1153D revision 13");
-
- break;
- case 0x000F:
- sb.AppendLine("ATA/ATAPI-4 X3T13 1153D revision 7");
-
- break;
- case 0x0010:
- sb.AppendLine("ATA/ATAPI-4 T13 1153D revision 18");
-
- break;
- case 0x0011:
- sb.AppendLine("ATA/ATAPI-4 T13 1153D revision 15");
-
- break;
- case 0x0012:
- sb.AppendLine("ATA/ATAPI-4 published, ANSI INCITS 317-1998");
-
- break;
- case 0x0013:
- sb.AppendLine("ATA/ATAPI-5 T13 1321D revision 3");
-
- break;
- case 0x0014:
- sb.AppendLine("ATA/ATAPI-4 T13 1153D revision 14");
-
- break;
- case 0x0015:
- sb.AppendLine("ATA/ATAPI-5 T13 1321D revision 1");
-
- break;
- case 0x0016:
- sb.AppendLine("ATA/ATAPI-5 published, ANSI INCITS 340-2000");
-
- break;
- case 0x0017:
- sb.AppendLine("ATA/ATAPI-4 T13 1153D revision 17");
-
- break;
- case 0x0018:
- sb.AppendLine("ATA/ATAPI-6 T13 1410D revision 0");
-
- break;
- case 0x0019:
- sb.AppendLine("ATA/ATAPI-6 T13 1410D revision 3a");
-
- break;
- case 0x001A:
- sb.AppendLine("ATA/ATAPI-7 T13 1532D revision 1");
-
- break;
- case 0x001B:
- sb.AppendLine("ATA/ATAPI-6 T13 1410D revision 2");
-
- break;
- case 0x001C:
- sb.AppendLine("ATA/ATAPI-6 T13 1410D revision 1");
-
- break;
- case 0x001D:
- sb.AppendLine("ATA/ATAPI-7 published ANSI INCITS 397-2005");
-
- break;
- case 0x001E:
- sb.AppendLine("ATA/ATAPI-7 T13 1532D revision 0");
-
- break;
- case 0x001F:
- sb.AppendLine("ACS-3 Revision 3b");
-
- break;
- case 0x0021:
- sb.AppendLine("ATA/ATAPI-7 T13 1532D revision 4a");
-
- break;
- case 0x0022:
- sb.AppendLine("ATA/ATAPI-6 published, ANSI INCITS 361-2002");
-
- break;
- case 0x0027:
- sb.AppendLine("ATA8-ACS revision 3c");
-
- break;
- case 0x0028:
- sb.AppendLine("ATA8-ACS revision 6");
-
- break;
- case 0x0029:
- sb.AppendLine("ATA8-ACS revision 4");
-
- break;
- case 0x0031:
- sb.AppendLine("ACS-2 Revision 2");
-
- break;
- case 0x0033:
- sb.AppendLine("ATA8-ACS Revision 3e");
-
- break;
- case 0x0039:
- sb.AppendLine("ATA8-ACS Revision 4c");
-
- break;
- case 0x0042:
- sb.AppendLine("ATA8-ACS Revision 3f");
-
- break;
- case 0x0052:
- sb.AppendLine("ATA8-ACS revision 3b");
-
- break;
- case 0x006D:
- sb.AppendLine("ACS-3 Revision 5");
-
- break;
- case 0x0082:
- sb.AppendLine("ACS-2 published, ANSI INCITS 482-2012");
-
- break;
- case 0x0107:
- sb.AppendLine("ATA8-ACS revision 2d");
-
- break;
- case 0x0110:
- sb.AppendLine("ACS-2 Revision 3");
-
- break;
- case 0x011B:
- sb.AppendLine("ACS-3 Revision 4");
-
- break;
- default:
- sb.AppendFormat("Unknown ATA revision 0x{0:X4}", ATAID.MinorVersion).AppendLine();
-
- break;
- }
-
- switch((ATAID.TransportMajorVersion & 0xF000) >> 12)
- {
- case 0x0:
- sb.Append("Parallel ATA device: ");
-
- if((ATAID.TransportMajorVersion & 0x0002) == 0x0002)
- sb.Append("ATA/ATAPI-7 ");
-
- if((ATAID.TransportMajorVersion & 0x0001) == 0x0001)
- sb.Append("ATA8-APT ");
-
- sb.AppendLine();
+ case 0x0000:
+ case 0xFFFF:
+ sb.AppendLine("Minor ATA version not specified");
break;
- case 0x1:
- sb.Append("Serial ATA device: ");
-
- if((ATAID.TransportMajorVersion & 0x0001) == 0x0001)
- sb.Append("ATA8-AST ");
-
- if((ATAID.TransportMajorVersion & 0x0002) == 0x0002)
- sb.Append("SATA 1.0a ");
-
- if((ATAID.TransportMajorVersion & 0x0004) == 0x0004)
- sb.Append("SATA II Extensions ");
-
- if((ATAID.TransportMajorVersion & 0x0008) == 0x0008)
- sb.Append("SATA 2.5 ");
-
- if((ATAID.TransportMajorVersion & 0x0010) == 0x0010)
- sb.Append("SATA 2.6 ");
-
- if((ATAID.TransportMajorVersion & 0x0020) == 0x0020)
- sb.Append("SATA 3.0 ");
-
- if((ATAID.TransportMajorVersion & 0x0040) == 0x0040)
- sb.Append("SATA 3.1 ");
-
- sb.AppendLine();
+ case 0x0001:
+ sb.AppendLine("ATA (ATA-1) X3T9.2 781D prior to revision 4");
break;
- case 0xE:
- sb.AppendLine("SATA Express device");
+ case 0x0002:
+ sb.AppendLine("ATA-1 published, ANSI X3.221-1994");
+
+ break;
+ case 0x0003:
+ sb.AppendLine("ATA (ATA-1) X3T9.2 781D revision 4");
+
+ break;
+ case 0x0004:
+ sb.AppendLine("ATA-2 published, ANSI X3.279-1996");
+
+ break;
+ case 0x0005:
+ sb.AppendLine("ATA-2 X3T10 948D prior to revision 2k");
+
+ break;
+ case 0x0006:
+ sb.AppendLine("ATA-3 X3T10 2008D revision 1");
+
+ break;
+ case 0x0007:
+ sb.AppendLine("ATA-2 X3T10 948D revision 2k");
+
+ break;
+ case 0x0008:
+ sb.AppendLine("ATA-3 X3T10 2008D revision 0");
+
+ break;
+ case 0x0009:
+ sb.AppendLine("ATA-2 X3T10 948D revision 3");
+
+ break;
+ case 0x000A:
+ sb.AppendLine("ATA-3 published, ANSI X3.298-1997");
+
+ break;
+ case 0x000B:
+ sb.AppendLine("ATA-3 X3T10 2008D revision 6");
+
+ break;
+ case 0x000C:
+ sb.AppendLine("ATA-3 X3T13 2008D revision 7");
+
+ break;
+ case 0x000D:
+ sb.AppendLine("ATA/ATAPI-4 X3T13 1153D revision 6");
+
+ break;
+ case 0x000E:
+ sb.AppendLine("ATA/ATAPI-4 T13 1153D revision 13");
+
+ break;
+ case 0x000F:
+ sb.AppendLine("ATA/ATAPI-4 X3T13 1153D revision 7");
+
+ break;
+ case 0x0010:
+ sb.AppendLine("ATA/ATAPI-4 T13 1153D revision 18");
+
+ break;
+ case 0x0011:
+ sb.AppendLine("ATA/ATAPI-4 T13 1153D revision 15");
+
+ break;
+ case 0x0012:
+ sb.AppendLine("ATA/ATAPI-4 published, ANSI INCITS 317-1998");
+
+ break;
+ case 0x0013:
+ sb.AppendLine("ATA/ATAPI-5 T13 1321D revision 3");
+
+ break;
+ case 0x0014:
+ sb.AppendLine("ATA/ATAPI-4 T13 1153D revision 14");
+
+ break;
+ case 0x0015:
+ sb.AppendLine("ATA/ATAPI-5 T13 1321D revision 1");
+
+ break;
+ case 0x0016:
+ sb.AppendLine("ATA/ATAPI-5 published, ANSI INCITS 340-2000");
+
+ break;
+ case 0x0017:
+ sb.AppendLine("ATA/ATAPI-4 T13 1153D revision 17");
+
+ break;
+ case 0x0018:
+ sb.AppendLine("ATA/ATAPI-6 T13 1410D revision 0");
+
+ break;
+ case 0x0019:
+ sb.AppendLine("ATA/ATAPI-6 T13 1410D revision 3a");
+
+ break;
+ case 0x001A:
+ sb.AppendLine("ATA/ATAPI-7 T13 1532D revision 1");
+
+ break;
+ case 0x001B:
+ sb.AppendLine("ATA/ATAPI-6 T13 1410D revision 2");
+
+ break;
+ case 0x001C:
+ sb.AppendLine("ATA/ATAPI-6 T13 1410D revision 1");
+
+ break;
+ case 0x001D:
+ sb.AppendLine("ATA/ATAPI-7 published ANSI INCITS 397-2005");
+
+ break;
+ case 0x001E:
+ sb.AppendLine("ATA/ATAPI-7 T13 1532D revision 0");
+
+ break;
+ case 0x001F:
+ sb.AppendLine("ACS-3 Revision 3b");
+
+ break;
+ case 0x0021:
+ sb.AppendLine("ATA/ATAPI-7 T13 1532D revision 4a");
+
+ break;
+ case 0x0022:
+ sb.AppendLine("ATA/ATAPI-6 published, ANSI INCITS 361-2002");
+
+ break;
+ case 0x0027:
+ sb.AppendLine("ATA8-ACS revision 3c");
+
+ break;
+ case 0x0028:
+ sb.AppendLine("ATA8-ACS revision 6");
+
+ break;
+ case 0x0029:
+ sb.AppendLine("ATA8-ACS revision 4");
+
+ break;
+ case 0x0031:
+ sb.AppendLine("ACS-2 Revision 2");
+
+ break;
+ case 0x0033:
+ sb.AppendLine("ATA8-ACS Revision 3e");
+
+ break;
+ case 0x0039:
+ sb.AppendLine("ATA8-ACS Revision 4c");
+
+ break;
+ case 0x0042:
+ sb.AppendLine("ATA8-ACS Revision 3f");
+
+ break;
+ case 0x0052:
+ sb.AppendLine("ATA8-ACS revision 3b");
+
+ break;
+ case 0x006D:
+ sb.AppendLine("ACS-3 Revision 5");
+
+ break;
+ case 0x0082:
+ sb.AppendLine("ACS-2 published, ANSI INCITS 482-2012");
+
+ break;
+ case 0x0107:
+ sb.AppendLine("ATA8-ACS revision 2d");
+
+ break;
+ case 0x0110:
+ sb.AppendLine("ACS-2 Revision 3");
+
+ break;
+ case 0x011B:
+ sb.AppendLine("ACS-3 Revision 4");
break;
default:
- sb.AppendFormat("Unknown transport type 0x{0:X1}", (ATAID.TransportMajorVersion & 0xF000) >> 12).
- AppendLine();
+ sb.AppendFormat("Unknown ATA revision 0x{0:X4}", ATAID.MinorVersion).AppendLine();
break;
}
- if(atapi)
+ switch((ATAID.TransportMajorVersion & 0xF000) >> 12)
+ {
+ case 0x0:
+ sb.Append("Parallel ATA device: ");
+
+ if((ATAID.TransportMajorVersion & 0x0002) == 0x0002)
+ sb.Append("ATA/ATAPI-7 ");
+
+ if((ATAID.TransportMajorVersion & 0x0001) == 0x0001)
+ sb.Append("ATA8-APT ");
+
+ sb.AppendLine();
+
+ break;
+ case 0x1:
+ sb.Append("Serial ATA device: ");
+
+ if((ATAID.TransportMajorVersion & 0x0001) == 0x0001)
+ sb.Append("ATA8-AST ");
+
+ if((ATAID.TransportMajorVersion & 0x0002) == 0x0002)
+ sb.Append("SATA 1.0a ");
+
+ if((ATAID.TransportMajorVersion & 0x0004) == 0x0004)
+ sb.Append("SATA II Extensions ");
+
+ if((ATAID.TransportMajorVersion & 0x0008) == 0x0008)
+ sb.Append("SATA 2.5 ");
+
+ if((ATAID.TransportMajorVersion & 0x0010) == 0x0010)
+ sb.Append("SATA 2.6 ");
+
+ if((ATAID.TransportMajorVersion & 0x0020) == 0x0020)
+ sb.Append("SATA 3.0 ");
+
+ if((ATAID.TransportMajorVersion & 0x0040) == 0x0040)
+ sb.Append("SATA 3.1 ");
+
+ sb.AppendLine();
+
+ break;
+ case 0xE:
+ sb.AppendLine("SATA Express device");
+
+ break;
+ default:
+ sb.AppendFormat("Unknown transport type 0x{0:X1}", (ATAID.TransportMajorVersion & 0xF000) >> 12).
+ AppendLine();
+
+ break;
+ }
+
+ if(atapi)
+ {
+ // Bits 12 to 8, SCSI Peripheral Device Type
+ switch((PeripheralDeviceTypes)(((ushort)ATAID.GeneralConfiguration & 0x1F00) >> 8))
{
- // Bits 12 to 8, SCSI Peripheral Device Type
- switch((PeripheralDeviceTypes)(((ushort)ATAID.GeneralConfiguration & 0x1F00) >> 8))
- {
- case PeripheralDeviceTypes.DirectAccess: //0x00,
- sb.AppendLine("ATAPI Direct-access device");
+ case PeripheralDeviceTypes.DirectAccess: //0x00,
+ sb.AppendLine("ATAPI Direct-access device");
- break;
- case PeripheralDeviceTypes.SequentialAccess: //0x01,
- sb.AppendLine("ATAPI Sequential-access device");
+ break;
+ case PeripheralDeviceTypes.SequentialAccess: //0x01,
+ sb.AppendLine("ATAPI Sequential-access device");
- break;
- case PeripheralDeviceTypes.PrinterDevice: //0x02,
- sb.AppendLine("ATAPI Printer device");
+ break;
+ case PeripheralDeviceTypes.PrinterDevice: //0x02,
+ sb.AppendLine("ATAPI Printer device");
- break;
- case PeripheralDeviceTypes.ProcessorDevice: //0x03,
- sb.AppendLine("ATAPI Processor device");
+ break;
+ case PeripheralDeviceTypes.ProcessorDevice: //0x03,
+ sb.AppendLine("ATAPI Processor device");
- break;
- case PeripheralDeviceTypes.WriteOnceDevice: //0x04,
- sb.AppendLine("ATAPI Write-once device");
+ break;
+ case PeripheralDeviceTypes.WriteOnceDevice: //0x04,
+ sb.AppendLine("ATAPI Write-once device");
- break;
- case PeripheralDeviceTypes.MultiMediaDevice: //0x05,
- sb.AppendLine("ATAPI CD-ROM/DVD/etc device");
+ break;
+ case PeripheralDeviceTypes.MultiMediaDevice: //0x05,
+ sb.AppendLine("ATAPI CD-ROM/DVD/etc device");
- break;
- case PeripheralDeviceTypes.ScannerDevice: //0x06,
- sb.AppendLine("ATAPI Scanner device");
+ break;
+ case PeripheralDeviceTypes.ScannerDevice: //0x06,
+ sb.AppendLine("ATAPI Scanner device");
- break;
- case PeripheralDeviceTypes.OpticalDevice: //0x07,
- sb.AppendLine("ATAPI Optical memory device");
+ break;
+ case PeripheralDeviceTypes.OpticalDevice: //0x07,
+ sb.AppendLine("ATAPI Optical memory device");
- break;
- case PeripheralDeviceTypes.MediumChangerDevice: //0x08,
- sb.AppendLine("ATAPI Medium change device");
+ break;
+ case PeripheralDeviceTypes.MediumChangerDevice: //0x08,
+ sb.AppendLine("ATAPI Medium change device");
- break;
- case PeripheralDeviceTypes.CommsDevice: //0x09,
- sb.AppendLine("ATAPI Communications device");
+ break;
+ case PeripheralDeviceTypes.CommsDevice: //0x09,
+ sb.AppendLine("ATAPI Communications device");
- break;
- case PeripheralDeviceTypes.PrePressDevice1: //0x0A,
- sb.AppendLine("ATAPI Graphics arts pre-press device (defined in ASC IT8)");
+ break;
+ case PeripheralDeviceTypes.PrePressDevice1: //0x0A,
+ sb.AppendLine("ATAPI Graphics arts pre-press device (defined in ASC IT8)");
- break;
- case PeripheralDeviceTypes.PrePressDevice2: //0x0B,
- sb.AppendLine("ATAPI Graphics arts pre-press device (defined in ASC IT8)");
+ break;
+ case PeripheralDeviceTypes.PrePressDevice2: //0x0B,
+ sb.AppendLine("ATAPI Graphics arts pre-press device (defined in ASC IT8)");
- break;
- case PeripheralDeviceTypes.ArrayControllerDevice: //0x0C,
- sb.AppendLine("ATAPI Array controller device");
+ break;
+ case PeripheralDeviceTypes.ArrayControllerDevice: //0x0C,
+ sb.AppendLine("ATAPI Array controller device");
- break;
- case PeripheralDeviceTypes.EnclosureServiceDevice: //0x0D,
- sb.AppendLine("ATAPI Enclosure services device");
+ break;
+ case PeripheralDeviceTypes.EnclosureServiceDevice: //0x0D,
+ sb.AppendLine("ATAPI Enclosure services device");
- break;
- case PeripheralDeviceTypes.SimplifiedDevice: //0x0E,
- sb.AppendLine("ATAPI Simplified direct-access device");
+ break;
+ case PeripheralDeviceTypes.SimplifiedDevice: //0x0E,
+ sb.AppendLine("ATAPI Simplified direct-access device");
- break;
- case PeripheralDeviceTypes.OCRWDevice: //0x0F,
- sb.AppendLine("ATAPI Optical card reader/writer device");
+ break;
+ case PeripheralDeviceTypes.OCRWDevice: //0x0F,
+ sb.AppendLine("ATAPI Optical card reader/writer device");
- break;
- case PeripheralDeviceTypes.BridgingExpander: //0x10,
- sb.AppendLine("ATAPI Bridging Expanders");
+ break;
+ case PeripheralDeviceTypes.BridgingExpander: //0x10,
+ sb.AppendLine("ATAPI Bridging Expanders");
- break;
- case PeripheralDeviceTypes.ObjectDevice: //0x11,
- sb.AppendLine("ATAPI Object-based Storage Device");
+ break;
+ case PeripheralDeviceTypes.ObjectDevice: //0x11,
+ sb.AppendLine("ATAPI Object-based Storage Device");
- break;
- case PeripheralDeviceTypes.ADCDevice: //0x12,
- sb.AppendLine("ATAPI Automation/Drive Interface");
+ break;
+ case PeripheralDeviceTypes.ADCDevice: //0x12,
+ sb.AppendLine("ATAPI Automation/Drive Interface");
- break;
- case PeripheralDeviceTypes.WellKnownDevice: //0x1E,
- sb.AppendLine("ATAPI Well known logical unit");
+ break;
+ case PeripheralDeviceTypes.WellKnownDevice: //0x1E,
+ sb.AppendLine("ATAPI Well known logical unit");
- break;
- case PeripheralDeviceTypes.UnknownDevice: //0x1F
- sb.AppendLine("ATAPI Unknown or no device type");
+ break;
+ case PeripheralDeviceTypes.UnknownDevice: //0x1F
+ sb.AppendLine("ATAPI Unknown or no device type");
- break;
- default:
- sb.AppendFormat("ATAPI Unknown device type field value 0x{0:X2}",
- ((ushort)ATAID.GeneralConfiguration & 0x1F00) >> 8).AppendLine();
+ break;
+ default:
+ sb.AppendFormat("ATAPI Unknown device type field value 0x{0:X2}",
+ ((ushort)ATAID.GeneralConfiguration & 0x1F00) >> 8).AppendLine();
- break;
- }
-
- // ATAPI DRQ behaviour
- switch(((ushort)ATAID.GeneralConfiguration & 0x60) >> 5)
- {
- case 0:
- sb.AppendLine("Device shall set DRQ within 3 ms of receiving PACKET");
-
- break;
- case 1:
- sb.AppendLine("Device shall assert INTRQ when DRQ is set to one");
-
- break;
- case 2:
- sb.AppendLine("Device shall set DRQ within 50 µs of receiving PACKET");
-
- break;
- default:
- sb.AppendFormat("Unknown ATAPI DRQ behaviour code {0}",
- ((ushort)ATAID.GeneralConfiguration & 0x60) >> 5).AppendLine();
-
- break;
- }
-
- // ATAPI PACKET size
- switch((ushort)ATAID.GeneralConfiguration & 0x03)
- {
- case 0:
- sb.AppendLine("ATAPI device uses 12 byte command packet");
-
- break;
- case 1:
- sb.AppendLine("ATAPI device uses 16 byte command packet");
-
- break;
- default:
- sb.AppendFormat("Unknown ATAPI packet size code {0}",
- (ushort)ATAID.GeneralConfiguration & 0x03).AppendLine();
-
- break;
- }
- }
- else if(!cfa)
- {
- if(minatalevel >= 5)
- if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
- GeneralConfigurationBit.IncompleteResponse))
- sb.AppendLine("Incomplete identify response");
-
- if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.GeneralConfigurationBit.
- NonMagnetic))
- sb.AppendLine("Device uses non-magnetic media");
-
- if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.GeneralConfigurationBit.
- Removable))
- sb.AppendLine("Device is removable");
-
- if(minatalevel <= 5)
- if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
- GeneralConfigurationBit.Fixed))
- sb.AppendLine("Device is fixed");
-
- if(ata1)
- {
- if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
- GeneralConfigurationBit.SlowIDE))
- sb.AppendLine("Device transfer rate is <= 5 Mb/s");
-
- if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
- GeneralConfigurationBit.FastIDE))
- sb.AppendLine("Device transfer rate is > 5 Mb/s but <= 10 Mb/s");
-
- if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
- GeneralConfigurationBit.UltraFastIDE))
- sb.AppendLine("Device transfer rate is > 10 Mb/s");
-
- if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
- GeneralConfigurationBit.SoftSector))
- sb.AppendLine("Device is soft sectored");
-
- if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
- GeneralConfigurationBit.HardSector))
- sb.AppendLine("Device is hard sectored");
-
- if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
- GeneralConfigurationBit.NotMFM))
- sb.AppendLine("Device is not MFM encoded");
-
- if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
- GeneralConfigurationBit.FormatGapReq))
- sb.AppendLine("Format speed tolerance gap is required");
-
- if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
- GeneralConfigurationBit.TrackOffset))
- sb.AppendLine("Track offset option is available");
-
- if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
- GeneralConfigurationBit.DataStrobeOffset))
- sb.AppendLine("Data strobe offset option is available");
-
- if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
- GeneralConfigurationBit.RotationalSpeedTolerance))
- sb.AppendLine("Rotational speed tolerance is higher than 0,5%");
-
- if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
- GeneralConfigurationBit.SpindleControl))
- sb.AppendLine("Spindle motor control is implemented");
-
- if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
- GeneralConfigurationBit.HighHeadSwitch))
- sb.AppendLine("Head switch time is bigger than 15 µs.");
- }
+ break;
}
- if(ATAID.NominalRotationRate != 0x0000 &&
- ATAID.NominalRotationRate != 0xFFFF)
- if(ATAID.NominalRotationRate == 0x0001)
- sb.AppendLine("Device does not rotate.");
- else
- sb.AppendFormat("Device rotate at {0} rpm", ATAID.NominalRotationRate).AppendLine();
-
- uint logicalSectorSize = 0;
-
- if(!atapi)
+ // ATAPI DRQ behaviour
+ switch(((ushort)ATAID.GeneralConfiguration & 0x60) >> 5)
{
- uint physicalSectorSize;
+ case 0:
+ sb.AppendLine("Device shall set DRQ within 3 ms of receiving PACKET");
- 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;
+ break;
+ case 1:
+ sb.AppendLine("Device shall assert INTRQ when DRQ is set to one");
- if((ATAID.PhysLogSectorSize & 0x2000) == 0x2000)
- physicalSectorSize = logicalSectorSize * (uint)Math.Pow(2, ATAID.PhysLogSectorSize & 0xF);
- else
- physicalSectorSize = logicalSectorSize;
- }
- else
- {
- logicalSectorSize = 512;
- physicalSectorSize = 512;
- }
+ break;
+ case 2:
+ sb.AppendLine("Device shall set DRQ within 50 µs of receiving PACKET");
- sb.AppendFormat("Physical sector size: {0} bytes", physicalSectorSize).AppendLine();
- sb.AppendFormat("Logical sector size: {0} bytes", logicalSectorSize).AppendLine();
+ break;
+ default:
+ sb.AppendFormat("Unknown ATAPI DRQ behaviour code {0}",
+ ((ushort)ATAID.GeneralConfiguration & 0x60) >> 5).AppendLine();
- if(logicalSectorSize != physicalSectorSize &&
- (ATAID.LogicalAlignment & 0x8000) == 0x0000 &&
- (ATAID.LogicalAlignment & 0x4000) == 0x4000)
- sb.AppendFormat("Logical sector starts at offset {0} from physical sector",
- ATAID.LogicalAlignment & 0x3FFF).AppendLine();
-
- if(minatalevel <= 5)
- if(ATAID.CurrentCylinders > 0 &&
- ATAID.CurrentHeads > 0 &&
- ATAID.CurrentSectorsPerTrack > 0)
- {
- sb.AppendFormat("Cylinders: {0} max., {1} current", ATAID.Cylinders, ATAID.CurrentCylinders).
- AppendLine();
-
- sb.AppendFormat("Heads: {0} max., {1} current", ATAID.Heads, ATAID.CurrentHeads).AppendLine();
-
- sb.AppendFormat("Sectors per track: {0} max., {1} current", ATAID.SectorsPerTrack,
- ATAID.CurrentSectorsPerTrack).AppendLine();
-
- sb.AppendFormat("Sectors addressable in CHS mode: {0} max., {1} current",
- ATAID.Cylinders * ATAID.Heads * ATAID.SectorsPerTrack, ATAID.CurrentSectors).
- AppendLine();
- }
- else
- {
- sb.AppendFormat("Cylinders: {0}", ATAID.Cylinders).AppendLine();
- sb.AppendFormat("Heads: {0}", ATAID.Heads).AppendLine();
- sb.AppendFormat("Sectors per track: {0}", ATAID.SectorsPerTrack).AppendLine();
-
- sb.AppendFormat("Sectors addressable in CHS mode: {0}",
- ATAID.Cylinders * ATAID.Heads * ATAID.SectorsPerTrack).AppendLine();
- }
-
- if(ATAID.Capabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit.LBASupport))
- sb.AppendFormat("{0} sectors in 28-bit LBA mode", ATAID.LBASectors).AppendLine();
-
- if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.LBA48))
- sb.AppendFormat("{0} sectors in 48-bit LBA mode", ATAID.LBA48Sectors).AppendLine();
-
- if(minatalevel <= 5)
- if(ATAID.CurrentSectors > 0)
- sb.AppendFormat("Device size in CHS mode: {0} bytes, {1} Mb, {2} MiB",
- (ulong)ATAID.CurrentSectors * logicalSectorSize,
- (ulong)ATAID.CurrentSectors * logicalSectorSize / 1000 / 1000,
- (ulong)ATAID.CurrentSectors * 512 / 1024 / 1024).AppendLine();
- else
- {
- ulong currentSectors = (ulong)(ATAID.Cylinders * ATAID.Heads * ATAID.SectorsPerTrack);
-
- sb.AppendFormat("Device size in CHS mode: {0} bytes, {1} Mb, {2} MiB",
- currentSectors * logicalSectorSize,
- currentSectors * logicalSectorSize / 1000 / 1000,
- currentSectors * 512 / 1024 / 1024).AppendLine();
- }
-
- if(ATAID.Capabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit.LBASupport))
- if((ulong)ATAID.LBASectors * logicalSectorSize / 1024 / 1024 > 1000000)
- sb.AppendFormat("Device size in 28-bit LBA mode: {0} bytes, {1} Tb, {2} TiB",
- (ulong)ATAID.LBASectors * logicalSectorSize,
- (ulong)ATAID.LBASectors * logicalSectorSize / 1000 / 1000 / 1000 / 1000,
- (ulong)ATAID.LBASectors * 512 / 1024 / 1024 / 1024 / 1024).AppendLine();
- else if((ulong)ATAID.LBASectors * logicalSectorSize / 1024 / 1024 > 1000)
- sb.AppendFormat("Device size in 28-bit LBA mode: {0} bytes, {1} Gb, {2} GiB",
- (ulong)ATAID.LBASectors * logicalSectorSize,
- (ulong)ATAID.LBASectors * logicalSectorSize / 1000 / 1000 / 1000,
- (ulong)ATAID.LBASectors * 512 / 1024 / 1024 / 1024).AppendLine();
- else
- sb.AppendFormat("Device size in 28-bit LBA mode: {0} bytes, {1} Mb, {2} MiB",
- (ulong)ATAID.LBASectors * logicalSectorSize,
- (ulong)ATAID.LBASectors * logicalSectorSize / 1000 / 1000,
- (ulong)ATAID.LBASectors * 512 / 1024 / 1024).AppendLine();
-
- if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.LBA48))
- if(ATAID.CommandSet5.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit5.ExtSectors))
- if(ATAID.ExtendedUserSectors * logicalSectorSize / 1024 / 1024 > 1000000)
- sb.AppendFormat("Device size in 48-bit LBA mode: {0} bytes, {1} Tb, {2} TiB",
- ATAID.ExtendedUserSectors * logicalSectorSize,
- ATAID.ExtendedUserSectors * logicalSectorSize / 1000 / 1000 / 1000 / 1000,
- ATAID.ExtendedUserSectors * logicalSectorSize / 1024 / 1024 / 1024 / 1024).
- AppendLine();
- else if(ATAID.ExtendedUserSectors * logicalSectorSize / 1024 / 1024 > 1000)
- sb.AppendFormat("Device size in 48-bit LBA mode: {0} bytes, {1} Gb, {2} GiB",
- ATAID.ExtendedUserSectors * logicalSectorSize,
- ATAID.ExtendedUserSectors * logicalSectorSize / 1000 / 1000 / 1000,
- ATAID.ExtendedUserSectors * logicalSectorSize / 1024 / 1024 / 1024).
- AppendLine();
- else
- sb.AppendFormat("Device size in 48-bit LBA mode: {0} bytes, {1} Mb, {2} MiB",
- ATAID.ExtendedUserSectors * logicalSectorSize,
- ATAID.ExtendedUserSectors * logicalSectorSize / 1000 / 1000,
- ATAID.ExtendedUserSectors * logicalSectorSize / 1024 / 1024).AppendLine();
- else
- {
- if(ATAID.LBA48Sectors * logicalSectorSize / 1024 / 1024 > 1000000)
- sb.AppendFormat("Device size in 48-bit LBA mode: {0} bytes, {1} Tb, {2} TiB",
- ATAID.LBA48Sectors * logicalSectorSize,
- ATAID.LBA48Sectors * logicalSectorSize / 1000 / 1000 / 1000 / 1000,
- ATAID.LBA48Sectors * logicalSectorSize / 1024 / 1024 / 1024 / 1024).
- AppendLine();
- else if(ATAID.LBA48Sectors * logicalSectorSize / 1024 / 1024 > 1000)
- sb.AppendFormat("Device size in 48-bit LBA mode: {0} bytes, {1} Gb, {2} GiB",
- ATAID.LBA48Sectors * logicalSectorSize,
- ATAID.LBA48Sectors * logicalSectorSize / 1000 / 1000 / 1000,
- ATAID.LBA48Sectors * logicalSectorSize / 1024 / 1024 / 1024).AppendLine();
- else
- sb.AppendFormat("Device size in 48-bit LBA mode: {0} bytes, {1} Mb, {2} MiB",
- ATAID.LBA48Sectors * logicalSectorSize,
- ATAID.LBA48Sectors * logicalSectorSize / 1000 / 1000,
- ATAID.LBA48Sectors * logicalSectorSize / 1024 / 1024).AppendLine();
- }
-
- if(ata1 || cfa)
- {
- if(cfa)
- sb.AppendFormat("{0} sectors in card", ATAID.SectorsPerCard).AppendLine();
-
- if(ATAID.UnformattedBPT > 0)
- sb.AppendFormat("{0} bytes per unformatted track", ATAID.UnformattedBPT).AppendLine();
-
- if(ATAID.UnformattedBPS > 0)
- sb.AppendFormat("{0} bytes per unformatted sector", ATAID.UnformattedBPS).AppendLine();
- }
+ break;
}
- if((ushort)ATAID.SpecificConfiguration != 0x0000 &&
- (ushort)ATAID.SpecificConfiguration != 0xFFFF)
- switch(ATAID.SpecificConfiguration)
- {
- case CommonTypes.Structs.Devices.ATA.Identify.SpecificConfigurationEnum.
- RequiresSetIncompleteResponse:
- sb.AppendLine("Device requires SET FEATURES to spin up and IDENTIFY DEVICE response is incomplete.");
-
- break;
- case CommonTypes.Structs.Devices.ATA.Identify.SpecificConfigurationEnum.RequiresSetCompleteResponse:
- sb.AppendLine("Device requires SET FEATURES to spin up and IDENTIFY DEVICE response is complete.");
-
- break;
- case CommonTypes.Structs.Devices.ATA.Identify.SpecificConfigurationEnum.
- NotRequiresSetIncompleteResponse:
- sb.AppendLine("Device does not require SET FEATURES to spin up and IDENTIFY DEVICE response is incomplete.");
-
- break;
- case CommonTypes.Structs.Devices.ATA.Identify.SpecificConfigurationEnum.
- NotRequiresSetCompleteResponse:
- sb.AppendLine("Device does not require SET FEATURES to spin up and IDENTIFY DEVICE response is complete.");
-
- break;
- default:
- sb.AppendFormat("Unknown device specific configuration 0x{0:X4}",
- (ushort)ATAID.SpecificConfiguration).AppendLine();
-
- break;
- }
-
- // Obsolete since ATA-2, however, it is yet used in ATA-8 devices
- if(ATAID.BufferSize != 0x0000 &&
- ATAID.BufferSize != 0xFFFF &&
- ATAID.BufferType != 0x0000 &&
- ATAID.BufferType != 0xFFFF)
- switch(ATAID.BufferType)
- {
- case 1:
- sb.AppendFormat("{0} KiB of single ported single sector buffer", ATAID.BufferSize * 512 / 1024).
- AppendLine();
-
- break;
- case 2:
- sb.AppendFormat("{0} KiB of dual ported multi sector buffer", ATAID.BufferSize * 512 / 1024).
- AppendLine();
-
- break;
- case 3:
- sb.AppendFormat("{0} KiB of dual ported multi sector buffer with read caching",
- ATAID.BufferSize * 512 / 1024).AppendLine();
-
- break;
- default:
- sb.AppendFormat("{0} KiB of unknown type {1} buffer", ATAID.BufferSize * 512 / 1024,
- ATAID.BufferType).AppendLine();
-
- break;
- }
-
- if(ATAID.EccBytes != 0x0000 &&
- ATAID.EccBytes != 0xFFFF)
- sb.AppendFormat("READ/WRITE LONG has {0} extra bytes", ATAID.EccBytes).AppendLine();
-
- sb.AppendLine();
-
- sb.Append("Device capabilities:");
-
- if(ATAID.Capabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit.
- StandardStandbyTimer))
- sb.AppendLine().Append("Standby time values are standard");
-
- if(ATAID.Capabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit.IORDY))
+ // ATAPI PACKET size
+ switch((ushort)ATAID.GeneralConfiguration & 0x03)
{
- sb.AppendLine().Append("IORDY is supported");
+ case 0:
+ sb.AppendLine("ATAPI device uses 12 byte command packet");
- if(ATAID.Capabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit.CanDisableIORDY))
- sb.Append(" and can be disabled");
+ break;
+ case 1:
+ sb.AppendLine("ATAPI device uses 16 byte command packet");
+
+ break;
+ default:
+ sb.AppendFormat("Unknown ATAPI packet size code {0}",
+ (ushort)ATAID.GeneralConfiguration & 0x03).AppendLine();
+
+ break;
}
+ }
+ else if(!cfa)
+ {
+ if(minatalevel >= 5)
+ if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
+ GeneralConfigurationBit.IncompleteResponse))
+ sb.AppendLine("Incomplete identify response");
- if(ATAID.Capabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit.DMASupport))
- sb.AppendLine().Append("DMA is supported");
+ if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.GeneralConfigurationBit.
+ NonMagnetic))
+ sb.AppendLine("Device uses non-magnetic media");
- if(ATAID.Capabilities2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit2.MustBeSet) &&
- !ATAID.Capabilities2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit2.MustBeClear))
- if(ATAID.Capabilities2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit2.
- SpecificStandbyTimer))
- sb.AppendLine().Append("Device indicates a specific minimum standby timer value");
+ if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.GeneralConfigurationBit.
+ Removable))
+ sb.AppendLine("Device is removable");
- if(ATAID.Capabilities3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit3.MultipleValid))
- {
- sb.AppendLine().
- AppendFormat("A maximum of {0} sectors can be transferred per interrupt on READ/WRITE MULTIPLE",
- ATAID.MultipleSectorNumber);
-
- sb.AppendLine().AppendFormat("Device supports setting a maximum of {0} sectors",
- ATAID.MultipleMaxSectors);
- }
-
- if(ATAID.Capabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit.
- PhysicalAlignment1) ||
- ATAID.Capabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit.PhysicalAlignment0))
- sb.AppendLine().AppendFormat("Long Physical Alignment setting is {0}",
- (ushort)ATAID.Capabilities & 0x03);
+ if(minatalevel <= 5)
+ if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
+ GeneralConfigurationBit.Fixed))
+ sb.AppendLine("Device is fixed");
if(ata1)
- if(ATAID.TrustedComputing.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TrustedComputingBit.
- TrustedComputing))
- sb.AppendLine().Append("Device supports doubleword I/O");
-
- if(atapi)
{
- if(ATAID.Capabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit.InterleavedDMA))
- sb.AppendLine().Append("ATAPI device supports interleaved DMA");
+ if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
+ GeneralConfigurationBit.SlowIDE))
+ sb.AppendLine("Device transfer rate is <= 5 Mb/s");
- if(ATAID.Capabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit.CommandQueue))
- sb.AppendLine().Append("ATAPI device supports command queueing");
+ if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
+ GeneralConfigurationBit.FastIDE))
+ sb.AppendLine("Device transfer rate is > 5 Mb/s but <= 10 Mb/s");
- if(ATAID.Capabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit.
- OverlapOperation))
- sb.AppendLine().Append("ATAPI device supports overlapped operations");
+ if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
+ GeneralConfigurationBit.UltraFastIDE))
+ sb.AppendLine("Device transfer rate is > 10 Mb/s");
- if(ATAID.Capabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit.
- RequiresATASoftReset))
- sb.AppendLine().Append("ATAPI device requires ATA software reset");
+ if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
+ GeneralConfigurationBit.SoftSector))
+ sb.AppendLine("Device is soft sectored");
+
+ if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
+ GeneralConfigurationBit.HardSector))
+ sb.AppendLine("Device is hard sectored");
+
+ if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
+ GeneralConfigurationBit.NotMFM))
+ sb.AppendLine("Device is not MFM encoded");
+
+ if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
+ GeneralConfigurationBit.FormatGapReq))
+ sb.AppendLine("Format speed tolerance gap is required");
+
+ if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
+ GeneralConfigurationBit.TrackOffset))
+ sb.AppendLine("Track offset option is available");
+
+ if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
+ GeneralConfigurationBit.DataStrobeOffset))
+ sb.AppendLine("Data strobe offset option is available");
+
+ if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
+ GeneralConfigurationBit.RotationalSpeedTolerance))
+ sb.AppendLine("Rotational speed tolerance is higher than 0,5%");
+
+ if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
+ GeneralConfigurationBit.SpindleControl))
+ sb.AppendLine("Spindle motor control is implemented");
+
+ if(ATAID.GeneralConfiguration.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
+ GeneralConfigurationBit.HighHeadSwitch))
+ sb.AppendLine("Head switch time is bigger than 15 µs.");
+ }
+ }
+
+ if(ATAID.NominalRotationRate != 0x0000 &&
+ ATAID.NominalRotationRate != 0xFFFF)
+ if(ATAID.NominalRotationRate == 0x0001)
+ sb.AppendLine("Device does not rotate.");
+ else
+ sb.AppendFormat("Device rotate at {0} rpm", ATAID.NominalRotationRate).AppendLine();
+
+ uint logicalSectorSize = 0;
+
+ if(!atapi)
+ {
+ 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 = logicalSectorSize * (uint)Math.Pow(2, ATAID.PhysLogSectorSize & 0xF);
+ else
+ physicalSectorSize = logicalSectorSize;
+ }
+ else
+ {
+ logicalSectorSize = 512;
+ physicalSectorSize = 512;
}
- if(minatalevel <= 3)
- {
- sb.AppendLine().AppendFormat("PIO timing mode: {0}", ATAID.PIOTransferTimingMode);
- sb.AppendLine().AppendFormat("DMA timing mode: {0}", ATAID.DMATransferTimingMode);
- }
+ sb.AppendFormat("Physical sector size: {0} bytes", physicalSectorSize).AppendLine();
+ sb.AppendFormat("Logical sector size: {0} bytes", logicalSectorSize).AppendLine();
- sb.AppendLine().Append("Advanced PIO: ");
+ if(logicalSectorSize != physicalSectorSize &&
+ (ATAID.LogicalAlignment & 0x8000) == 0x0000 &&
+ (ATAID.LogicalAlignment & 0x4000) == 0x4000)
+ sb.AppendFormat("Logical sector starts at offset {0} from physical sector",
+ ATAID.LogicalAlignment & 0x3FFF).AppendLine();
- if(ATAID.APIOSupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode0))
- sb.Append("PIO0 ");
-
- if(ATAID.APIOSupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode1))
- sb.Append("PIO1 ");
-
- if(ATAID.APIOSupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode2))
- sb.Append("PIO2 ");
-
- if(ATAID.APIOSupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode3))
- sb.Append("PIO3 ");
-
- if(ATAID.APIOSupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode4))
- sb.Append("PIO4 ");
-
- if(ATAID.APIOSupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode5))
- sb.Append("PIO5 ");
-
- if(ATAID.APIOSupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode6))
- sb.Append("PIO6 ");
-
- if(ATAID.APIOSupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode7))
- sb.Append("PIO7 ");
-
- if(minatalevel <= 3 &&
- !atapi)
- {
- sb.AppendLine().Append("Single-word DMA: ");
-
- if(ATAID.DMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode0))
+ if(minatalevel <= 5)
+ if(ATAID.CurrentCylinders > 0 &&
+ ATAID.CurrentHeads > 0 &&
+ ATAID.CurrentSectorsPerTrack > 0)
{
- sb.Append("DMA0 ");
+ sb.AppendFormat("Cylinders: {0} max., {1} current", ATAID.Cylinders, ATAID.CurrentCylinders).
+ AppendLine();
- if(ATAID.DMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode0))
- sb.Append("(active) ");
- }
+ sb.AppendFormat("Heads: {0} max., {1} current", ATAID.Heads, ATAID.CurrentHeads).AppendLine();
- if(ATAID.DMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode1))
- {
- sb.Append("DMA1 ");
+ sb.AppendFormat("Sectors per track: {0} max., {1} current", ATAID.SectorsPerTrack,
+ ATAID.CurrentSectorsPerTrack).AppendLine();
- if(ATAID.DMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode1))
- sb.Append("(active) ");
- }
-
- if(ATAID.DMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode2))
- {
- sb.Append("DMA2 ");
-
- if(ATAID.DMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode2))
- sb.Append("(active) ");
- }
-
- if(ATAID.DMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode3))
- {
- sb.Append("DMA3 ");
-
- if(ATAID.DMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode3))
- sb.Append("(active) ");
- }
-
- if(ATAID.DMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode4))
- {
- sb.Append("DMA4 ");
-
- if(ATAID.DMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode4))
- sb.Append("(active) ");
- }
-
- if(ATAID.DMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode5))
- {
- sb.Append("DMA5 ");
-
- if(ATAID.DMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode5))
- sb.Append("(active) ");
- }
-
- if(ATAID.DMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode6))
- {
- sb.Append("DMA6 ");
-
- if(ATAID.DMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode6))
- sb.Append("(active) ");
- }
-
- if(ATAID.DMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode7))
- {
- sb.Append("DMA7 ");
-
- if(ATAID.DMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode7))
- sb.Append("(active) ");
- }
- }
-
- sb.AppendLine().Append("Multi-word DMA: ");
-
- if(ATAID.MDMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode0))
- {
- sb.Append("MDMA0 ");
-
- if(ATAID.MDMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode0))
- sb.Append("(active) ");
- }
-
- if(ATAID.MDMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode1))
- {
- sb.Append("MDMA1 ");
-
- if(ATAID.MDMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode1))
- sb.Append("(active) ");
- }
-
- if(ATAID.MDMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode2))
- {
- sb.Append("MDMA2 ");
-
- if(ATAID.MDMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode2))
- sb.Append("(active) ");
- }
-
- if(ATAID.MDMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode3))
- {
- sb.Append("MDMA3 ");
-
- if(ATAID.MDMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode3))
- sb.Append("(active) ");
- }
-
- if(ATAID.MDMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode4))
- {
- sb.Append("MDMA4 ");
-
- if(ATAID.MDMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode4))
- sb.Append("(active) ");
- }
-
- if(ATAID.MDMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode5))
- {
- sb.Append("MDMA5 ");
-
- if(ATAID.MDMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode5))
- sb.Append("(active) ");
- }
-
- if(ATAID.MDMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode6))
- {
- sb.Append("MDMA6 ");
-
- if(ATAID.MDMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode6))
- sb.Append("(active) ");
- }
-
- if(ATAID.MDMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode7))
- {
- sb.Append("MDMA7 ");
-
- if(ATAID.MDMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode7))
- sb.Append("(active) ");
- }
-
- sb.AppendLine().Append("Ultra DMA: ");
-
- if(ATAID.UDMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode0))
- {
- sb.Append("UDMA0 ");
-
- if(ATAID.UDMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode0))
- sb.Append("(active) ");
- }
-
- if(ATAID.UDMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode1))
- {
- sb.Append("UDMA1 ");
-
- if(ATAID.UDMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode1))
- sb.Append("(active) ");
- }
-
- if(ATAID.UDMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode2))
- {
- sb.Append("UDMA2 ");
-
- if(ATAID.UDMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode2))
- sb.Append("(active) ");
- }
-
- if(ATAID.UDMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode3))
- {
- sb.Append("UDMA3 ");
-
- if(ATAID.UDMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode3))
- sb.Append("(active) ");
- }
-
- if(ATAID.UDMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode4))
- {
- sb.Append("UDMA4 ");
-
- if(ATAID.UDMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode4))
- sb.Append("(active) ");
- }
-
- if(ATAID.UDMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode5))
- {
- sb.Append("UDMA5 ");
-
- if(ATAID.UDMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode5))
- sb.Append("(active) ");
- }
-
- if(ATAID.UDMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode6))
- {
- sb.Append("UDMA6 ");
-
- if(ATAID.UDMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode6))
- sb.Append("(active) ");
- }
-
- if(ATAID.UDMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode7))
- {
- sb.Append("UDMA7 ");
-
- if(ATAID.UDMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode7))
- sb.Append("(active) ");
- }
-
- if(ATAID.MinMDMACycleTime != 0 &&
- ATAID.RecMDMACycleTime != 0)
- sb.AppendLine().
- AppendFormat("At minimum {0} ns. transfer cycle time per word in MDMA, " + "{1} ns. recommended",
- ATAID.MinMDMACycleTime, ATAID.RecMDMACycleTime);
-
- if(ATAID.MinPIOCycleTimeNoFlow != 0)
- sb.AppendLine().
- AppendFormat("At minimum {0} ns. transfer cycle time per word in PIO, " + "without flow control",
- ATAID.MinPIOCycleTimeNoFlow);
-
- if(ATAID.MinPIOCycleTimeFlow != 0)
- sb.AppendLine().
- AppendFormat("At minimum {0} ns. transfer cycle time per word in PIO, " + "with IORDY flow control",
- ATAID.MinPIOCycleTimeFlow);
-
- if(ATAID.MaxQueueDepth != 0)
- sb.AppendLine().AppendFormat("{0} depth of queue maximum", ATAID.MaxQueueDepth + 1);
-
- if(atapi)
- {
- if(ATAID.PacketBusRelease != 0)
- sb.AppendLine().AppendFormat("{0} ns. typical to release bus from receipt of PACKET",
- ATAID.PacketBusRelease);
-
- if(ATAID.ServiceBusyClear != 0)
- sb.AppendLine().AppendFormat("{0} ns. typical to clear BSY bit from receipt of SERVICE",
- ATAID.ServiceBusyClear);
- }
-
- if((ATAID.TransportMajorVersion & 0xF000) >> 12 == 0x1 ||
- (ATAID.TransportMajorVersion & 0xF000) >> 12 == 0xE)
- {
- if(!ATAID.SATACapabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit.Clear))
- {
- if(ATAID.SATACapabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit.
- Gen1Speed))
- sb.AppendLine().Append("SATA 1.5Gb/s is supported");
-
- if(ATAID.SATACapabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit.
- Gen2Speed))
- sb.AppendLine().Append("SATA 3.0Gb/s is supported");
-
- if(ATAID.SATACapabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit.
- Gen3Speed))
- sb.AppendLine().Append("SATA 6.0Gb/s is supported");
-
- if(ATAID.SATACapabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit.
- PowerReceipt))
- sb.AppendLine().Append("Receipt of host initiated power management requests is supported");
-
- if(ATAID.SATACapabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit.
- PHYEventCounter))
- sb.AppendLine().Append("PHY Event counters are supported");
-
- if(ATAID.SATACapabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit.
- HostSlumbTrans))
- sb.AppendLine().Append("Supports host automatic partial to slumber transitions is supported");
-
- if(ATAID.SATACapabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit.
- DevSlumbTrans))
- sb.AppendLine().Append("Supports device automatic partial to slumber transitions is supported");
-
- if(ATAID.SATACapabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit.NCQ))
- {
- sb.AppendLine().Append("NCQ is supported");
-
- if(ATAID.SATACapabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit.
- NCQPriority))
- sb.AppendLine().Append("NCQ priority is supported");
-
- if(ATAID.SATACapabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit.
- UnloadNCQ))
- sb.AppendLine().Append("Unload is supported with outstanding NCQ commands");
- }
- }
-
- if(!ATAID.SATACapabilities2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit2.
- Clear))
- {
- if(!ATAID.SATACapabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit.
- Clear) &&
- ATAID.SATACapabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit.NCQ))
- {
- if(ATAID.SATACapabilities2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
- SATACapabilitiesBit2.NCQMgmt))
- sb.AppendLine().Append("NCQ queue management is supported");
-
- if(ATAID.SATACapabilities2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
- SATACapabilitiesBit2.NCQStream))
- sb.AppendLine().Append("NCQ streaming is supported");
- }
-
- if(atapi)
- {
- if(ATAID.SATACapabilities2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
- SATACapabilitiesBit2.HostEnvDetect))
- sb.AppendLine().Append("ATAPI device supports host environment detection");
-
- if(ATAID.SATACapabilities2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
- SATACapabilitiesBit2.DevAttSlimline))
- sb.AppendLine().Append("ATAPI device supports attention on slimline connected devices");
- }
-
- //sb.AppendFormat("Negotiated speed = {0}", ((ushort)ATAID.SATACapabilities2 & 0x000E) >> 1);
- }
- }
-
- if(ATAID.InterseekDelay != 0x0000 &&
- ATAID.InterseekDelay != 0xFFFF)
- sb.AppendLine().AppendFormat("{0} microseconds of interseek delay for ISO-7779 acoustic testing",
- ATAID.InterseekDelay);
-
- if((ushort)ATAID.DeviceFormFactor != 0x0000 &&
- (ushort)ATAID.DeviceFormFactor != 0xFFFF)
- switch(ATAID.DeviceFormFactor)
- {
- case CommonTypes.Structs.Devices.ATA.Identify.DeviceFormFactorEnum.FiveAndQuarter:
- sb.AppendLine().Append("Device nominal size is 5.25\"");
-
- break;
- case CommonTypes.Structs.Devices.ATA.Identify.DeviceFormFactorEnum.ThreeAndHalf:
- sb.AppendLine().Append("Device nominal size is 3.5\"");
-
- break;
- case CommonTypes.Structs.Devices.ATA.Identify.DeviceFormFactorEnum.TwoAndHalf:
- sb.AppendLine().Append("Device nominal size is 2.5\"");
-
- break;
- case CommonTypes.Structs.Devices.ATA.Identify.DeviceFormFactorEnum.OnePointEight:
- sb.AppendLine().Append("Device nominal size is 1.8\"");
-
- break;
- case CommonTypes.Structs.Devices.ATA.Identify.DeviceFormFactorEnum.LessThanOnePointEight:
- sb.AppendLine().Append("Device nominal size is smaller than 1.8\"");
-
- break;
- default:
- sb.AppendLine().AppendFormat("Device nominal size field value {0} is unknown",
- ATAID.DeviceFormFactor);
-
- break;
- }
-
- if(atapi)
- if(ATAID.ATAPIByteCount > 0)
- sb.AppendLine().AppendFormat("{0} bytes count limit for ATAPI", ATAID.ATAPIByteCount);
-
- if(cfa)
- if((ATAID.CFAPowerMode & 0x8000) == 0x8000)
- {
- sb.AppendLine().Append("CompactFlash device supports power mode 1");
-
- if((ATAID.CFAPowerMode & 0x2000) == 0x2000)
- sb.AppendLine().Append("CompactFlash power mode 1 required for one or more commands");
-
- if((ATAID.CFAPowerMode & 0x1000) == 0x1000)
- sb.AppendLine().Append("CompactFlash power mode 1 is disabled");
-
- sb.AppendLine().AppendFormat("CompactFlash device uses a maximum of {0} mA",
- ATAID.CFAPowerMode & 0x0FFF);
- }
-
- sb.AppendLine();
-
- sb.AppendLine().Append("Command set and features:");
-
- if(ATAID.CommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.Nop))
- {
- sb.AppendLine().Append("NOP is supported");
-
- if(ATAID.EnabledCommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.Nop))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.ReadBuffer))
- {
- sb.AppendLine().Append("READ BUFFER is supported");
-
- if(ATAID.EnabledCommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.ReadBuffer))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.WriteBuffer))
- {
- sb.AppendLine().Append("WRITE BUFFER is supported");
-
- if(ATAID.EnabledCommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.WriteBuffer))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.HPA))
- {
- sb.AppendLine().Append("Host Protected Area is supported");
-
- if(ATAID.EnabledCommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.HPA))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.DeviceReset))
- {
- sb.AppendLine().Append("DEVICE RESET is supported");
-
- if(ATAID.EnabledCommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.DeviceReset))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.Service))
- {
- sb.AppendLine().Append("SERVICE interrupt is supported");
-
- if(ATAID.EnabledCommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.Service))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.Release))
- {
- sb.AppendLine().Append("Release is supported");
-
- if(ATAID.EnabledCommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.Release))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.LookAhead))
- {
- sb.AppendLine().Append("Look-ahead read is supported");
-
- if(ATAID.EnabledCommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.LookAhead))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.WriteCache))
- {
- sb.AppendLine().Append("Write cache is supported");
-
- if(ATAID.EnabledCommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.WriteCache))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.Packet))
- {
- sb.AppendLine().Append("PACKET is supported");
-
- if(ATAID.EnabledCommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.Packet))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.PowerManagement))
- {
- sb.AppendLine().Append("Power management is supported");
-
- if(ATAID.EnabledCommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.
- PowerManagement))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.RemovableMedia))
- {
- sb.AppendLine().Append("Removable media feature set is supported");
-
- if(ATAID.EnabledCommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.
- RemovableMedia))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.SecurityMode))
- {
- sb.AppendLine().Append("Security mode is supported");
-
- if(ATAID.EnabledCommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.SecurityMode))
- sb.Append(" and enabled");
- }
-
- if(ATAID.Capabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit.LBASupport))
- sb.AppendLine().Append("28-bit LBA is supported");
-
- if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.MustBeSet) &&
- !ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.MustBeClear))
- {
- if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.LBA48))
- {
- sb.AppendLine().Append("48-bit LBA is supported");
-
- if(ATAID.EnabledCommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.LBA48))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.FlushCache))
- {
- sb.AppendLine().Append("FLUSH CACHE is supported");
-
- if(ATAID.EnabledCommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.
- FlushCache))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.FlushCacheExt))
- {
- sb.AppendLine().Append("FLUSH CACHE EXT is supported");
-
- if(ATAID.EnabledCommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.
- FlushCacheExt))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.DCO))
- {
- sb.AppendLine().Append("Device Configuration Overlay feature set is supported");
-
- if(ATAID.EnabledCommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.DCO))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.AAM))
- {
- sb.AppendLine().Append("Automatic Acoustic Management is supported");
-
- if(ATAID.EnabledCommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.AAM))
- sb.AppendFormat(" and enabled with value {0} (vendor recommends {1}", ATAID.CurrentAAM,
- ATAID.RecommendedAAM);
- }
-
- if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.SetMax))
- {
- sb.AppendLine().Append("SET MAX security extension is supported");
-
- if(ATAID.EnabledCommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.SetMax))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.
- AddressOffsetReservedAreaBoot))
- {
- sb.AppendLine().Append("Address Offset Reserved Area Boot is supported");
-
- if(ATAID.EnabledCommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.
- AddressOffsetReservedAreaBoot))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.
- SetFeaturesRequired))
- sb.AppendLine().Append("SET FEATURES is required before spin-up");
-
- if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.PowerUpInStandby))
- {
- sb.AppendLine().Append("Power-up in standby is supported");
-
- if(ATAID.EnabledCommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.
- PowerUpInStandby))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.
- RemovableNotification))
- {
- sb.AppendLine().Append("Removable Media Status Notification is supported");
-
- if(ATAID.EnabledCommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.
- RemovableNotification))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.APM))
- {
- sb.AppendLine().Append("Advanced Power Management is supported");
-
- if(ATAID.EnabledCommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.APM))
- sb.AppendFormat(" and enabled with value {0}", ATAID.CurrentAPM);
- }
-
- if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.CompactFlash))
- {
- sb.AppendLine().Append("CompactFlash feature set is supported");
-
- if(ATAID.EnabledCommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.
- CompactFlash))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.RWQueuedDMA))
- {
- sb.AppendLine().Append("READ DMA QUEUED and WRITE DMA QUEUED are supported");
-
- if(ATAID.EnabledCommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.
- RWQueuedDMA))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.DownloadMicrocode))
- {
- sb.AppendLine().Append("DOWNLOAD MICROCODE is supported");
-
- if(ATAID.EnabledCommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.
- DownloadMicrocode))
- sb.Append(" and enabled");
- }
- }
-
- if(ATAID.CommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.SMART))
- {
- sb.AppendLine().Append("S.M.A.R.T. is supported");
-
- if(ATAID.EnabledCommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.SMART))
- sb.Append(" and enabled");
- }
-
- if(ATAID.SCTCommandTransport.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SCTCommandTransportBit.
- Supported))
- sb.AppendLine().Append("S.M.A.R.T. Command Transport is supported");
-
- if(ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.MustBeSet) &&
- !ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.MustBeClear))
- {
- if(ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.SMARTSelfTest))
- {
- sb.AppendLine().Append("S.M.A.R.T. self-testing is supported");
-
- if(ATAID.EnabledCommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.
- SMARTSelfTest))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.SMARTLog))
- {
- sb.AppendLine().Append("S.M.A.R.T. error logging is supported");
-
- if(ATAID.EnabledCommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.
- SMARTLog))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.IdleImmediate))
- {
- sb.AppendLine().Append("IDLE IMMEDIATE with UNLOAD FEATURE is supported");
-
- if(ATAID.EnabledCommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.
- IdleImmediate))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.WriteURG))
- sb.AppendLine().Append("URG bit is supported in WRITE STREAM DMA EXT and WRITE STREAM EXT");
-
- if(ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.ReadURG))
- sb.AppendLine().Append("URG bit is supported in READ STREAM DMA EXT and READ STREAM EXT");
-
- if(ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.WWN))
- sb.AppendLine().Append("Device has a World Wide Name");
-
- if(ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.FUAWriteQ))
- {
- sb.AppendLine().Append("WRITE DMA QUEUED FUA EXT is supported");
-
- if(ATAID.EnabledCommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.
- FUAWriteQ))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.FUAWrite))
- {
- sb.AppendLine().Append("WRITE DMA FUA EXT and WRITE MULTIPLE FUA EXT are supported");
-
- if(ATAID.EnabledCommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.
- FUAWrite))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.GPL))
- {
- sb.AppendLine().Append("General Purpose Logging is supported");
-
- if(ATAID.EnabledCommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.GPL))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.Streaming))
- {
- sb.AppendLine().Append("Streaming feature set is supported");
-
- if(ATAID.EnabledCommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.
- Streaming))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.MCPT))
- {
- sb.AppendLine().Append("Media Card Pass Through command set is supported");
-
- if(ATAID.EnabledCommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.MCPT))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.MediaSerial))
- {
- sb.AppendLine().Append("Media Serial is supported");
-
- if(ATAID.EnabledCommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.
- MediaSerial))
- sb.Append(" and valid");
- }
- }
-
- if(ATAID.CommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.MustBeSet) &&
- !ATAID.CommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.MustBeClear))
- {
- if(ATAID.CommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.DSN))
- {
- sb.AppendLine().Append("DSN feature set is supported");
-
- if(ATAID.EnabledCommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.DSN))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.AMAC))
- {
- sb.AppendLine().Append("Accessible Max Address Configuration is supported");
-
- if(ATAID.EnabledCommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.AMAC))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.ExtPowerCond))
- {
- sb.AppendLine().Append("Extended Power Conditions are supported");
-
- if(ATAID.EnabledCommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.
- ExtPowerCond))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.ExtStatusReport))
- {
- sb.AppendLine().Append("Extended Status Reporting is supported");
-
- if(ATAID.EnabledCommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.
- ExtStatusReport))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.FreeFallControl))
- {
- sb.AppendLine().Append("Free-fall control feature set is supported");
-
- if(ATAID.EnabledCommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.
- FreeFallControl))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.
- SegmentedDownloadMicrocode))
- {
- sb.AppendLine().Append("Segmented feature in DOWNLOAD MICROCODE is supported");
-
- if(ATAID.EnabledCommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.
- SegmentedDownloadMicrocode))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.RWDMAExtGpl))
- {
- sb.AppendLine().Append("READ/WRITE DMA EXT GPL are supported");
-
- if(ATAID.EnabledCommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.
- RWDMAExtGpl))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.WriteUnc))
- {
- sb.AppendLine().Append("WRITE UNCORRECTABLE is supported");
-
- if(ATAID.EnabledCommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.
- WriteUnc))
- sb.Append(" and enabled");
- }
-
- if(ATAID.CommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.WRV))
- {
- sb.AppendLine().Append("Write/Read/Verify is supported");
-
- if(ATAID.EnabledCommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.WRV))
- sb.Append(" and enabled");
-
- sb.AppendLine().AppendFormat("{0} sectors for Write/Read/Verify mode 2", ATAID.WRVSectorCountMode2);
- sb.AppendLine().AppendFormat("{0} sectors for Write/Read/Verify mode 3", ATAID.WRVSectorCountMode3);
-
- if(ATAID.EnabledCommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.WRV))
- sb.AppendLine().AppendFormat("Current Write/Read/Verify mode: {0}", ATAID.WRVMode);
- }
-
- if(ATAID.CommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.DT1825))
- {
- sb.AppendLine().Append("DT1825 is supported");
-
- if(ATAID.EnabledCommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.DT1825))
- sb.Append(" and enabled");
- }
- }
-
- if(ATAID.Capabilities3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit3.BlockErase))
- sb.AppendLine().Append("BLOCK ERASE EXT is supported");
-
- if(ATAID.Capabilities3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit3.Overwrite))
- sb.AppendLine().Append("OVERWRITE EXT is supported");
-
- if(ATAID.Capabilities3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit3.CryptoScramble))
- sb.AppendLine().Append("CRYPTO SCRAMBLE EXT is supported");
-
- if(ATAID.CommandSet5.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit5.DeviceConfDMA))
- sb.AppendLine().
- Append("DEVICE CONFIGURATION IDENTIFY DMA and DEVICE CONFIGURATION SET DMA are supported");
-
- if(ATAID.CommandSet5.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit5.ReadBufferDMA))
- sb.AppendLine().Append("READ BUFFER DMA is supported");
-
- if(ATAID.CommandSet5.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit5.WriteBufferDMA))
- sb.AppendLine().Append("WRITE BUFFER DMA is supported");
-
- if(ATAID.CommandSet5.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit5.DownloadMicroCodeDMA))
- sb.AppendLine().Append("DOWNLOAD MICROCODE DMA is supported");
-
- if(ATAID.CommandSet5.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit5.SetMaxDMA))
- sb.AppendLine().Append("SET PASSWORD DMA and SET UNLOCK DMA are supported");
-
- if(ATAID.CommandSet5.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit5.Ata28))
- sb.AppendLine().Append("Not all 28-bit commands are supported");
-
- if(ATAID.CommandSet5.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit5.CFast))
- sb.AppendLine().Append("Device follows CFast specification");
-
- if(ATAID.CommandSet5.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit5.IEEE1667))
- sb.AppendLine().Append("Device follows IEEE-1667");
-
- if(ATAID.CommandSet5.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit5.DeterministicTrim))
- {
- sb.AppendLine().Append("Read after TRIM is deterministic");
-
- if(ATAID.CommandSet5.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit5.ReadZeroTrim))
- sb.AppendLine().Append("Read after TRIM returns empty data");
- }
-
- if(ATAID.CommandSet5.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit5.
- LongPhysSectorAligError))
- sb.AppendLine().Append("Device supports Long Physical Sector Alignment Error Reporting Control");
-
- if(ATAID.CommandSet5.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit5.Encrypted))
- sb.AppendLine().Append("Device encrypts all user data");
-
- if(ATAID.CommandSet5.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit5.AllCacheNV))
- sb.AppendLine().Append("Device's write cache is non-volatile");
-
- if(ATAID.CommandSet5.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit5.ZonedBit0) ||
- ATAID.CommandSet5.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit5.ZonedBit1))
- sb.AppendLine().Append("Device is zoned");
-
- if(ATAID.Capabilities3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit3.Sanitize))
- {
- sb.AppendLine().Append("Sanitize feature set is supported");
-
- sb.AppendLine().
- Append(ATAID.Capabilities3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit3.
- SanitizeCommands)
- ? "Sanitize commands are specified by ACS-3 or higher"
- : "Sanitize commands are specified by ACS-2");
-
- if(ATAID.Capabilities3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit3.
- SanitizeAntifreeze))
- sb.AppendLine().Append("SANITIZE ANTIFREEZE LOCK EXT is supported");
- }
-
- if(!ata1 &&
- maxatalevel >= 8)
- if(ATAID.TrustedComputing.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TrustedComputingBit.Set) &&
- !ATAID.TrustedComputing.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TrustedComputingBit.
- Clear) &&
- ATAID.TrustedComputing.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TrustedComputingBit.
- TrustedComputing))
- sb.AppendLine().Append("Trusted Computing feature set is supported");
-
- if((ATAID.TransportMajorVersion & 0xF000) >> 12 == 0x1 ||
- (ATAID.TransportMajorVersion & 0xF000) >> 12 == 0xE)
- {
- if(!ATAID.SATACapabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit.Clear))
- if(ATAID.SATACapabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit.
- ReadLogDMAExt))
- sb.AppendLine().Append("READ LOG DMA EXT is supported");
-
- if(!ATAID.SATACapabilities2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit2.
- Clear))
- if(ATAID.SATACapabilities2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit2.
- FPDMAQ))
- sb.AppendLine().Append("RECEIVE FPDMA QUEUED and SEND FPDMA QUEUED are supported");
-
- if(!ATAID.SATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATAFeaturesBit.Clear))
- {
- if(ATAID.SATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATAFeaturesBit.
- NonZeroBufferOffset))
- {
- sb.AppendLine().Append("Non-zero buffer offsets are supported");
-
- if(ATAID.EnabledSATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATAFeaturesBit.
- NonZeroBufferOffset))
- sb.Append(" and enabled");
- }
-
- if(ATAID.SATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATAFeaturesBit.DMASetup))
- {
- sb.AppendLine().Append("DMA Setup auto-activation is supported");
-
- if(ATAID.EnabledSATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATAFeaturesBit.
- DMASetup))
- sb.Append(" and enabled");
- }
-
- if(ATAID.SATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATAFeaturesBit.
- InitPowerMgmt))
- {
- sb.AppendLine().Append("Device-initiated power management is supported");
-
- if(ATAID.EnabledSATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATAFeaturesBit.
- InitPowerMgmt))
- sb.Append(" and enabled");
- }
-
- if(ATAID.SATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATAFeaturesBit.InOrderData))
- {
- sb.AppendLine().Append("In-order data delivery is supported");
-
- if(ATAID.EnabledSATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATAFeaturesBit.
- InOrderData))
- sb.Append(" and enabled");
- }
-
- if(!atapi)
- if(ATAID.SATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATAFeaturesBit.
- HardwareFeatureControl))
- {
- sb.AppendLine().Append("Hardware Feature Control is supported");
-
- if(ATAID.EnabledSATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
- SATAFeaturesBit.HardwareFeatureControl))
- sb.Append(" and enabled");
- }
-
- if(atapi)
- if(ATAID.SATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATAFeaturesBit.
- AsyncNotification))
- {
- sb.AppendLine().Append("Asynchronous notification is supported");
-
- if(ATAID.EnabledSATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
- SATAFeaturesBit.AsyncNotification))
- sb.Append(" and enabled");
- }
-
- if(ATAID.SATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATAFeaturesBit.
- SettingsPreserve))
- {
- sb.AppendLine().Append("Software Settings Preservation is supported");
-
- if(ATAID.EnabledSATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATAFeaturesBit.
- SettingsPreserve))
- sb.Append(" and enabled");
- }
-
- if(ATAID.SATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATAFeaturesBit.
- NCQAutoSense))
- sb.AppendLine().Append("NCQ Autosense is supported");
-
- if(ATAID.EnabledSATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATAFeaturesBit.
- EnabledSlumber))
- sb.AppendLine().Append("Automatic Partial to Slumber transitions are enabled");
- }
- }
-
- if((ATAID.RemovableStatusSet & 0x03) > 0)
- sb.AppendLine().Append("Removable Media Status Notification feature set is supported");
-
- if(ATAID.FreeFallSensitivity != 0x00 &&
- ATAID.FreeFallSensitivity != 0xFF)
- sb.AppendLine().AppendFormat("Free-fall sensitivity set to {0}", ATAID.FreeFallSensitivity);
-
- if(ATAID.DataSetMgmt.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.DataSetMgmtBit.Trim))
- sb.AppendLine().Append("TRIM is supported");
-
- if(ATAID.DataSetMgmtSize > 0)
- sb.AppendLine().AppendFormat("DATA SET MANAGEMENT can receive a maximum of {0} blocks of 512 bytes",
- ATAID.DataSetMgmtSize);
-
- sb.AppendLine().AppendLine();
-
- if(ATAID.SecurityStatus.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SecurityStatusBit.Supported))
- {
- sb.AppendLine("Security:");
-
- if(ATAID.SecurityStatus.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SecurityStatusBit.Enabled))
- {
- sb.AppendLine("Security is enabled");
-
- sb.AppendLine(ATAID.SecurityStatus.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
- SecurityStatusBit.Locked)
- ? "Security is locked" : "Security is not locked");
-
- sb.AppendLine(ATAID.SecurityStatus.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
- SecurityStatusBit.Frozen)
- ? "Security is frozen" : "Security is not frozen");
-
- sb.AppendLine(ATAID.SecurityStatus.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
- SecurityStatusBit.Expired)
- ? "Security count has expired" : "Security count has not expired");
-
- sb.AppendLine(ATAID.SecurityStatus.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
- SecurityStatusBit.Maximum)
- ? "Security level is maximum" : "Security level is high");
+ sb.AppendFormat("Sectors addressable in CHS mode: {0} max., {1} current",
+ ATAID.Cylinders * ATAID.Heads * ATAID.SectorsPerTrack, ATAID.CurrentSectors).
+ AppendLine();
}
else
- sb.AppendLine("Security is not enabled");
-
- if(ATAID.SecurityStatus.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SecurityStatusBit.Enhanced))
- sb.AppendLine("Supports enhanced security erase");
-
- sb.AppendFormat("{0} minutes to complete secure erase", ATAID.SecurityEraseTime * 2).AppendLine();
-
- if(ATAID.SecurityStatus.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SecurityStatusBit.Enhanced))
- sb.AppendFormat("{0} minutes to complete enhanced secure erase",
- ATAID.EnhancedSecurityEraseTime * 2).AppendLine();
-
- sb.AppendFormat("Master password revision code: {0}", ATAID.MasterPasswordRevisionCode).AppendLine();
- }
-
- if(ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.MustBeSet) &&
- !ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.MustBeClear) &&
- ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.Streaming))
- {
- sb.AppendLine().AppendLine("Streaming:");
- sb.AppendFormat("Minimum request size is {0}", ATAID.StreamMinReqSize);
- sb.AppendFormat("Streaming transfer time in PIO is {0}", ATAID.StreamTransferTimePIO);
- sb.AppendFormat("Streaming transfer time in DMA is {0}", ATAID.StreamTransferTimeDMA);
- sb.AppendFormat("Streaming access latency is {0}", ATAID.StreamAccessLatency);
- sb.AppendFormat("Streaming performance granularity is {0}", ATAID.StreamPerformanceGranularity);
- }
-
- if(ATAID.SCTCommandTransport.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SCTCommandTransportBit.
- Supported))
- {
- sb.AppendLine().AppendLine("S.M.A.R.T. Command Transport (SCT):");
-
- if(ATAID.SCTCommandTransport.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SCTCommandTransportBit.
- LongSectorAccess))
- sb.AppendLine("SCT Long Sector Address is supported");
-
- if(ATAID.SCTCommandTransport.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SCTCommandTransportBit.
- WriteSame))
- sb.AppendLine("SCT Write Same is supported");
-
- if(ATAID.SCTCommandTransport.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SCTCommandTransportBit.
- ErrorRecoveryControl))
- sb.AppendLine("SCT Error Recovery Control is supported");
-
- if(ATAID.SCTCommandTransport.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SCTCommandTransportBit.
- FeaturesControl))
- sb.AppendLine("SCT Features Control is supported");
-
- if(ATAID.SCTCommandTransport.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SCTCommandTransportBit.
- DataTables))
- sb.AppendLine("SCT Data Tables are supported");
- }
-
- if((ATAID.NVCacheCaps & 0x0010) == 0x0010)
- {
- sb.AppendLine().AppendLine("Non-Volatile Cache:");
- sb.AppendLine().AppendFormat("Version {0}", (ATAID.NVCacheCaps & 0xF000) >> 12).AppendLine();
-
- if((ATAID.NVCacheCaps & 0x0001) == 0x0001)
{
- sb.Append("Power mode feature set is supported");
+ sb.AppendFormat("Cylinders: {0}", ATAID.Cylinders).AppendLine();
+ sb.AppendFormat("Heads: {0}", ATAID.Heads).AppendLine();
+ sb.AppendFormat("Sectors per track: {0}", ATAID.SectorsPerTrack).AppendLine();
- if((ATAID.NVCacheCaps & 0x0002) == 0x0002)
- sb.Append(" and enabled");
-
- sb.AppendLine();
-
- sb.AppendLine().AppendFormat("Version {0}", (ATAID.NVCacheCaps & 0x0F00) >> 8).AppendLine();
+ sb.AppendFormat("Sectors addressable in CHS mode: {0}",
+ ATAID.Cylinders * ATAID.Heads * ATAID.SectorsPerTrack).AppendLine();
}
- sb.AppendLine().AppendFormat("Non-Volatile Cache is {0} bytes", ATAID.NVCacheSize * logicalSectorSize).
- AppendLine();
+ if(ATAID.Capabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit.LBASupport))
+ sb.AppendFormat("{0} sectors in 28-bit LBA mode", ATAID.LBASectors).AppendLine();
+
+ if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.LBA48))
+ sb.AppendFormat("{0} sectors in 48-bit LBA mode", ATAID.LBA48Sectors).AppendLine();
+
+ if(minatalevel <= 5)
+ if(ATAID.CurrentSectors > 0)
+ sb.AppendFormat("Device size in CHS mode: {0} bytes, {1} Mb, {2} MiB",
+ (ulong)ATAID.CurrentSectors * logicalSectorSize,
+ (ulong)ATAID.CurrentSectors * logicalSectorSize / 1000 / 1000,
+ (ulong)ATAID.CurrentSectors * 512 / 1024 / 1024).AppendLine();
+ else
+ {
+ ulong currentSectors = (ulong)(ATAID.Cylinders * ATAID.Heads * ATAID.SectorsPerTrack);
+
+ sb.AppendFormat("Device size in CHS mode: {0} bytes, {1} Mb, {2} MiB",
+ currentSectors * logicalSectorSize,
+ currentSectors * logicalSectorSize / 1000 / 1000,
+ currentSectors * 512 / 1024 / 1024).AppendLine();
+ }
+
+ if(ATAID.Capabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit.LBASupport))
+ if((ulong)ATAID.LBASectors * logicalSectorSize / 1024 / 1024 > 1000000)
+ sb.AppendFormat("Device size in 28-bit LBA mode: {0} bytes, {1} Tb, {2} TiB",
+ (ulong)ATAID.LBASectors * logicalSectorSize,
+ (ulong)ATAID.LBASectors * logicalSectorSize / 1000 / 1000 / 1000 / 1000,
+ (ulong)ATAID.LBASectors * 512 / 1024 / 1024 / 1024 / 1024).AppendLine();
+ else if((ulong)ATAID.LBASectors * logicalSectorSize / 1024 / 1024 > 1000)
+ sb.AppendFormat("Device size in 28-bit LBA mode: {0} bytes, {1} Gb, {2} GiB",
+ (ulong)ATAID.LBASectors * logicalSectorSize,
+ (ulong)ATAID.LBASectors * logicalSectorSize / 1000 / 1000 / 1000,
+ (ulong)ATAID.LBASectors * 512 / 1024 / 1024 / 1024).AppendLine();
+ else
+ sb.AppendFormat("Device size in 28-bit LBA mode: {0} bytes, {1} Mb, {2} MiB",
+ (ulong)ATAID.LBASectors * logicalSectorSize,
+ (ulong)ATAID.LBASectors * logicalSectorSize / 1000 / 1000,
+ (ulong)ATAID.LBASectors * 512 / 1024 / 1024).AppendLine();
+
+ if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.LBA48))
+ if(ATAID.CommandSet5.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit5.ExtSectors))
+ if(ATAID.ExtendedUserSectors * logicalSectorSize / 1024 / 1024 > 1000000)
+ sb.AppendFormat("Device size in 48-bit LBA mode: {0} bytes, {1} Tb, {2} TiB",
+ ATAID.ExtendedUserSectors * logicalSectorSize,
+ ATAID.ExtendedUserSectors * logicalSectorSize / 1000 / 1000 / 1000 / 1000,
+ ATAID.ExtendedUserSectors * logicalSectorSize / 1024 / 1024 / 1024 / 1024).
+ AppendLine();
+ else if(ATAID.ExtendedUserSectors * logicalSectorSize / 1024 / 1024 > 1000)
+ sb.AppendFormat("Device size in 48-bit LBA mode: {0} bytes, {1} Gb, {2} GiB",
+ ATAID.ExtendedUserSectors * logicalSectorSize,
+ ATAID.ExtendedUserSectors * logicalSectorSize / 1000 / 1000 / 1000,
+ ATAID.ExtendedUserSectors * logicalSectorSize / 1024 / 1024 / 1024).
+ AppendLine();
+ else
+ sb.AppendFormat("Device size in 48-bit LBA mode: {0} bytes, {1} Mb, {2} MiB",
+ ATAID.ExtendedUserSectors * logicalSectorSize,
+ ATAID.ExtendedUserSectors * logicalSectorSize / 1000 / 1000,
+ ATAID.ExtendedUserSectors * logicalSectorSize / 1024 / 1024).AppendLine();
+ else
+ {
+ if(ATAID.LBA48Sectors * logicalSectorSize / 1024 / 1024 > 1000000)
+ sb.AppendFormat("Device size in 48-bit LBA mode: {0} bytes, {1} Tb, {2} TiB",
+ ATAID.LBA48Sectors * logicalSectorSize,
+ ATAID.LBA48Sectors * logicalSectorSize / 1000 / 1000 / 1000 / 1000,
+ ATAID.LBA48Sectors * logicalSectorSize / 1024 / 1024 / 1024 / 1024).
+ AppendLine();
+ else if(ATAID.LBA48Sectors * logicalSectorSize / 1024 / 1024 > 1000)
+ sb.AppendFormat("Device size in 48-bit LBA mode: {0} bytes, {1} Gb, {2} GiB",
+ ATAID.LBA48Sectors * logicalSectorSize,
+ ATAID.LBA48Sectors * logicalSectorSize / 1000 / 1000 / 1000,
+ ATAID.LBA48Sectors * logicalSectorSize / 1024 / 1024 / 1024).AppendLine();
+ else
+ sb.AppendFormat("Device size in 48-bit LBA mode: {0} bytes, {1} Mb, {2} MiB",
+ ATAID.LBA48Sectors * logicalSectorSize,
+ ATAID.LBA48Sectors * logicalSectorSize / 1000 / 1000,
+ ATAID.LBA48Sectors * logicalSectorSize / 1024 / 1024).AppendLine();
+ }
+
+ if(ata1 || cfa)
+ {
+ if(cfa)
+ sb.AppendFormat("{0} sectors in card", ATAID.SectorsPerCard).AppendLine();
+
+ if(ATAID.UnformattedBPT > 0)
+ sb.AppendFormat("{0} bytes per unformatted track", ATAID.UnformattedBPT).AppendLine();
+
+ if(ATAID.UnformattedBPS > 0)
+ sb.AppendFormat("{0} bytes per unformatted sector", ATAID.UnformattedBPS).AppendLine();
+ }
+ }
+
+ if((ushort)ATAID.SpecificConfiguration != 0x0000 &&
+ (ushort)ATAID.SpecificConfiguration != 0xFFFF)
+ switch(ATAID.SpecificConfiguration)
+ {
+ case CommonTypes.Structs.Devices.ATA.Identify.SpecificConfigurationEnum.
+ RequiresSetIncompleteResponse:
+ sb.AppendLine("Device requires SET FEATURES to spin up and IDENTIFY DEVICE response is incomplete.");
+
+ break;
+ case CommonTypes.Structs.Devices.ATA.Identify.SpecificConfigurationEnum.RequiresSetCompleteResponse:
+ sb.AppendLine("Device requires SET FEATURES to spin up and IDENTIFY DEVICE response is complete.");
+
+ break;
+ case CommonTypes.Structs.Devices.ATA.Identify.SpecificConfigurationEnum.
+ NotRequiresSetIncompleteResponse:
+ sb.AppendLine("Device does not require SET FEATURES to spin up and IDENTIFY DEVICE response is incomplete.");
+
+ break;
+ case CommonTypes.Structs.Devices.ATA.Identify.SpecificConfigurationEnum.
+ NotRequiresSetCompleteResponse:
+ sb.AppendLine("Device does not require SET FEATURES to spin up and IDENTIFY DEVICE response is complete.");
+
+ break;
+ default:
+ sb.AppendFormat("Unknown device specific configuration 0x{0:X4}",
+ (ushort)ATAID.SpecificConfiguration).AppendLine();
+
+ break;
}
- #if DEBUG
- sb.AppendLine();
+ // Obsolete since ATA-2, however, it is yet used in ATA-8 devices
+ if(ATAID.BufferSize != 0x0000 &&
+ ATAID.BufferSize != 0xFFFF &&
+ ATAID.BufferType != 0x0000 &&
+ ATAID.BufferType != 0xFFFF)
+ switch(ATAID.BufferType)
+ {
+ case 1:
+ sb.AppendFormat("{0} KiB of single ported single sector buffer", ATAID.BufferSize * 512 / 1024).
+ AppendLine();
- if(ATAID.VendorWord9 != 0x0000 &&
- ATAID.VendorWord9 != 0xFFFF)
- sb.AppendFormat("Word 9: 0x{0:X4}", ATAID.VendorWord9).AppendLine();
+ break;
+ case 2:
+ sb.AppendFormat("{0} KiB of dual ported multi sector buffer", ATAID.BufferSize * 512 / 1024).
+ AppendLine();
- if((ATAID.VendorWord47 & 0x7F) != 0x7F &&
- (ATAID.VendorWord47 & 0x7F) != 0x00)
- sb.AppendFormat("Word 47 bits 15 to 8: 0x{0:X2}", ATAID.VendorWord47).AppendLine();
+ break;
+ case 3:
+ sb.AppendFormat("{0} KiB of dual ported multi sector buffer with read caching",
+ ATAID.BufferSize * 512 / 1024).AppendLine();
- if(ATAID.VendorWord51 != 0x00 &&
- ATAID.VendorWord51 != 0xFF)
- sb.AppendFormat("Word 51 bits 7 to 0: 0x{0:X2}", ATAID.VendorWord51).AppendLine();
+ break;
+ default:
+ sb.AppendFormat("{0} KiB of unknown type {1} buffer", ATAID.BufferSize * 512 / 1024,
+ ATAID.BufferType).AppendLine();
- if(ATAID.VendorWord52 != 0x00 &&
- ATAID.VendorWord52 != 0xFF)
- sb.AppendFormat("Word 52 bits 7 to 0: 0x{0:X2}", ATAID.VendorWord52).AppendLine();
+ break;
+ }
- if(ATAID.ReservedWord64 != 0x00 &&
- ATAID.ReservedWord64 != 0xFF)
- sb.AppendFormat("Word 64 bits 15 to 8: 0x{0:X2}", ATAID.ReservedWord64).AppendLine();
+ if(ATAID.EccBytes != 0x0000 &&
+ ATAID.EccBytes != 0xFFFF)
+ sb.AppendFormat("READ/WRITE LONG has {0} extra bytes", ATAID.EccBytes).AppendLine();
- if(ATAID.ReservedWord70 != 0x0000 &&
- ATAID.ReservedWord70 != 0xFFFF)
- sb.AppendFormat("Word 70: 0x{0:X4}", ATAID.ReservedWord70).AppendLine();
+ sb.AppendLine();
- if(ATAID.ReservedWord73 != 0x0000 &&
- ATAID.ReservedWord73 != 0xFFFF)
- sb.AppendFormat("Word 73: 0x{0:X4}", ATAID.ReservedWord73).AppendLine();
+ sb.Append("Device capabilities:");
- if(ATAID.ReservedWord74 != 0x0000 &&
- ATAID.ReservedWord74 != 0xFFFF)
- sb.AppendFormat("Word 74: 0x{0:X4}", ATAID.ReservedWord74).AppendLine();
+ if(ATAID.Capabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit.
+ StandardStandbyTimer))
+ sb.AppendLine().Append("Standby time values are standard");
- if(ATAID.ReservedWord116 != 0x0000 &&
- ATAID.ReservedWord116 != 0xFFFF)
- sb.AppendFormat("Word 116: 0x{0:X4}", ATAID.ReservedWord116).AppendLine();
+ if(ATAID.Capabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit.IORDY))
+ {
+ sb.AppendLine().Append("IORDY is supported");
- for(int i = 0; i < ATAID.ReservedWords121.Length; i++)
- if(ATAID.ReservedWords121[i] != 0x0000 &&
- ATAID.ReservedWords121[i] != 0xFFFF)
- sb.AppendFormat("Word {1}: 0x{0:X4}", ATAID.ReservedWords121[i], 121 + i).AppendLine();
-
- for(int i = 0; i < ATAID.ReservedWords129.Length; i++)
- if(ATAID.ReservedWords129[i] != 0x0000 &&
- ATAID.ReservedWords129[i] != 0xFFFF)
- sb.AppendFormat("Word {1}: 0x{0:X4}", ATAID.ReservedWords129[i], 129 + i).AppendLine();
-
- for(int i = 0; i < ATAID.ReservedCFA.Length; i++)
- if(ATAID.ReservedCFA[i] != 0x0000 &&
- ATAID.ReservedCFA[i] != 0xFFFF)
- sb.AppendFormat("Word {1} (CFA): 0x{0:X4}", ATAID.ReservedCFA[i], 161 + i).AppendLine();
-
- if(ATAID.ReservedWord174 != 0x0000 &&
- ATAID.ReservedWord174 != 0xFFFF)
- sb.AppendFormat("Word 174: 0x{0:X4}", ATAID.ReservedWord174).AppendLine();
-
- if(ATAID.ReservedWord175 != 0x0000 &&
- ATAID.ReservedWord175 != 0xFFFF)
- sb.AppendFormat("Word 175: 0x{0:X4}", ATAID.ReservedWord175).AppendLine();
-
- if(ATAID.ReservedCEATAWord207 != 0x0000 &&
- ATAID.ReservedCEATAWord207 != 0xFFFF)
- sb.AppendFormat("Word 207 (CE-ATA): 0x{0:X4}", ATAID.ReservedCEATAWord207).AppendLine();
-
- if(ATAID.ReservedCEATAWord208 != 0x0000 &&
- ATAID.ReservedCEATAWord208 != 0xFFFF)
- sb.AppendFormat("Word 208 (CE-ATA): 0x{0:X4}", ATAID.ReservedCEATAWord208).AppendLine();
-
- if(ATAID.NVReserved != 0x00 &&
- ATAID.NVReserved != 0xFF)
- sb.AppendFormat("Word 219 bits 15 to 8: 0x{0:X2}", ATAID.NVReserved).AppendLine();
-
- if(ATAID.WRVReserved != 0x00 &&
- ATAID.WRVReserved != 0xFF)
- sb.AppendFormat("Word 220 bits 15 to 8: 0x{0:X2}", ATAID.WRVReserved).AppendLine();
-
- if(ATAID.ReservedWord221 != 0x0000 &&
- ATAID.ReservedWord221 != 0xFFFF)
- sb.AppendFormat("Word 221: 0x{0:X4}", ATAID.ReservedWord221).AppendLine();
-
- for(int i = 0; i < ATAID.ReservedCEATA224.Length; i++)
- if(ATAID.ReservedCEATA224[i] != 0x0000 &&
- ATAID.ReservedCEATA224[i] != 0xFFFF)
- sb.AppendFormat("Word {1} (CE-ATA): 0x{0:X4}", ATAID.ReservedCEATA224[i], 224 + i).AppendLine();
-
- for(int i = 0; i < ATAID.ReservedWords.Length; i++)
- if(ATAID.ReservedWords[i] != 0x0000 &&
- ATAID.ReservedWords[i] != 0xFFFF)
- sb.AppendFormat("Word {1}: 0x{0:X4}", ATAID.ReservedWords[i], 236 + i).AppendLine();
- #endif
- return sb.ToString();
+ if(ATAID.Capabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit.CanDisableIORDY))
+ sb.Append(" and can be disabled");
}
+
+ if(ATAID.Capabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit.DMASupport))
+ sb.AppendLine().Append("DMA is supported");
+
+ if(ATAID.Capabilities2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit2.MustBeSet) &&
+ !ATAID.Capabilities2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit2.MustBeClear))
+ if(ATAID.Capabilities2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit2.
+ SpecificStandbyTimer))
+ sb.AppendLine().Append("Device indicates a specific minimum standby timer value");
+
+ if(ATAID.Capabilities3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit3.MultipleValid))
+ {
+ sb.AppendLine().
+ AppendFormat("A maximum of {0} sectors can be transferred per interrupt on READ/WRITE MULTIPLE",
+ ATAID.MultipleSectorNumber);
+
+ sb.AppendLine().AppendFormat("Device supports setting a maximum of {0} sectors",
+ ATAID.MultipleMaxSectors);
+ }
+
+ if(ATAID.Capabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit.
+ PhysicalAlignment1) ||
+ ATAID.Capabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit.PhysicalAlignment0))
+ sb.AppendLine().AppendFormat("Long Physical Alignment setting is {0}",
+ (ushort)ATAID.Capabilities & 0x03);
+
+ if(ata1)
+ if(ATAID.TrustedComputing.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TrustedComputingBit.
+ TrustedComputing))
+ sb.AppendLine().Append("Device supports doubleword I/O");
+
+ if(atapi)
+ {
+ if(ATAID.Capabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit.InterleavedDMA))
+ sb.AppendLine().Append("ATAPI device supports interleaved DMA");
+
+ if(ATAID.Capabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit.CommandQueue))
+ sb.AppendLine().Append("ATAPI device supports command queueing");
+
+ if(ATAID.Capabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit.
+ OverlapOperation))
+ sb.AppendLine().Append("ATAPI device supports overlapped operations");
+
+ if(ATAID.Capabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit.
+ RequiresATASoftReset))
+ sb.AppendLine().Append("ATAPI device requires ATA software reset");
+ }
+
+ if(minatalevel <= 3)
+ {
+ sb.AppendLine().AppendFormat("PIO timing mode: {0}", ATAID.PIOTransferTimingMode);
+ sb.AppendLine().AppendFormat("DMA timing mode: {0}", ATAID.DMATransferTimingMode);
+ }
+
+ sb.AppendLine().Append("Advanced PIO: ");
+
+ if(ATAID.APIOSupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode0))
+ sb.Append("PIO0 ");
+
+ if(ATAID.APIOSupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode1))
+ sb.Append("PIO1 ");
+
+ if(ATAID.APIOSupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode2))
+ sb.Append("PIO2 ");
+
+ if(ATAID.APIOSupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode3))
+ sb.Append("PIO3 ");
+
+ if(ATAID.APIOSupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode4))
+ sb.Append("PIO4 ");
+
+ if(ATAID.APIOSupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode5))
+ sb.Append("PIO5 ");
+
+ if(ATAID.APIOSupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode6))
+ sb.Append("PIO6 ");
+
+ if(ATAID.APIOSupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode7))
+ sb.Append("PIO7 ");
+
+ if(minatalevel <= 3 &&
+ !atapi)
+ {
+ sb.AppendLine().Append("Single-word DMA: ");
+
+ if(ATAID.DMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode0))
+ {
+ sb.Append("DMA0 ");
+
+ if(ATAID.DMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode0))
+ sb.Append("(active) ");
+ }
+
+ if(ATAID.DMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode1))
+ {
+ sb.Append("DMA1 ");
+
+ if(ATAID.DMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode1))
+ sb.Append("(active) ");
+ }
+
+ if(ATAID.DMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode2))
+ {
+ sb.Append("DMA2 ");
+
+ if(ATAID.DMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode2))
+ sb.Append("(active) ");
+ }
+
+ if(ATAID.DMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode3))
+ {
+ sb.Append("DMA3 ");
+
+ if(ATAID.DMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode3))
+ sb.Append("(active) ");
+ }
+
+ if(ATAID.DMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode4))
+ {
+ sb.Append("DMA4 ");
+
+ if(ATAID.DMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode4))
+ sb.Append("(active) ");
+ }
+
+ if(ATAID.DMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode5))
+ {
+ sb.Append("DMA5 ");
+
+ if(ATAID.DMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode5))
+ sb.Append("(active) ");
+ }
+
+ if(ATAID.DMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode6))
+ {
+ sb.Append("DMA6 ");
+
+ if(ATAID.DMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode6))
+ sb.Append("(active) ");
+ }
+
+ if(ATAID.DMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode7))
+ {
+ sb.Append("DMA7 ");
+
+ if(ATAID.DMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode7))
+ sb.Append("(active) ");
+ }
+ }
+
+ sb.AppendLine().Append("Multi-word DMA: ");
+
+ if(ATAID.MDMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode0))
+ {
+ sb.Append("MDMA0 ");
+
+ if(ATAID.MDMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode0))
+ sb.Append("(active) ");
+ }
+
+ if(ATAID.MDMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode1))
+ {
+ sb.Append("MDMA1 ");
+
+ if(ATAID.MDMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode1))
+ sb.Append("(active) ");
+ }
+
+ if(ATAID.MDMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode2))
+ {
+ sb.Append("MDMA2 ");
+
+ if(ATAID.MDMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode2))
+ sb.Append("(active) ");
+ }
+
+ if(ATAID.MDMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode3))
+ {
+ sb.Append("MDMA3 ");
+
+ if(ATAID.MDMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode3))
+ sb.Append("(active) ");
+ }
+
+ if(ATAID.MDMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode4))
+ {
+ sb.Append("MDMA4 ");
+
+ if(ATAID.MDMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode4))
+ sb.Append("(active) ");
+ }
+
+ if(ATAID.MDMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode5))
+ {
+ sb.Append("MDMA5 ");
+
+ if(ATAID.MDMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode5))
+ sb.Append("(active) ");
+ }
+
+ if(ATAID.MDMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode6))
+ {
+ sb.Append("MDMA6 ");
+
+ if(ATAID.MDMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode6))
+ sb.Append("(active) ");
+ }
+
+ if(ATAID.MDMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode7))
+ {
+ sb.Append("MDMA7 ");
+
+ if(ATAID.MDMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode7))
+ sb.Append("(active) ");
+ }
+
+ sb.AppendLine().Append("Ultra DMA: ");
+
+ if(ATAID.UDMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode0))
+ {
+ sb.Append("UDMA0 ");
+
+ if(ATAID.UDMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode0))
+ sb.Append("(active) ");
+ }
+
+ if(ATAID.UDMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode1))
+ {
+ sb.Append("UDMA1 ");
+
+ if(ATAID.UDMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode1))
+ sb.Append("(active) ");
+ }
+
+ if(ATAID.UDMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode2))
+ {
+ sb.Append("UDMA2 ");
+
+ if(ATAID.UDMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode2))
+ sb.Append("(active) ");
+ }
+
+ if(ATAID.UDMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode3))
+ {
+ sb.Append("UDMA3 ");
+
+ if(ATAID.UDMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode3))
+ sb.Append("(active) ");
+ }
+
+ if(ATAID.UDMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode4))
+ {
+ sb.Append("UDMA4 ");
+
+ if(ATAID.UDMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode4))
+ sb.Append("(active) ");
+ }
+
+ if(ATAID.UDMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode5))
+ {
+ sb.Append("UDMA5 ");
+
+ if(ATAID.UDMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode5))
+ sb.Append("(active) ");
+ }
+
+ if(ATAID.UDMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode6))
+ {
+ sb.Append("UDMA6 ");
+
+ if(ATAID.UDMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode6))
+ sb.Append("(active) ");
+ }
+
+ if(ATAID.UDMASupported.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode7))
+ {
+ sb.Append("UDMA7 ");
+
+ if(ATAID.UDMAActive.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode7))
+ sb.Append("(active) ");
+ }
+
+ if(ATAID.MinMDMACycleTime != 0 &&
+ ATAID.RecMDMACycleTime != 0)
+ sb.AppendLine().
+ AppendFormat("At minimum {0} ns. transfer cycle time per word in MDMA, " + "{1} ns. recommended",
+ ATAID.MinMDMACycleTime, ATAID.RecMDMACycleTime);
+
+ if(ATAID.MinPIOCycleTimeNoFlow != 0)
+ sb.AppendLine().
+ AppendFormat("At minimum {0} ns. transfer cycle time per word in PIO, " + "without flow control",
+ ATAID.MinPIOCycleTimeNoFlow);
+
+ if(ATAID.MinPIOCycleTimeFlow != 0)
+ sb.AppendLine().
+ AppendFormat("At minimum {0} ns. transfer cycle time per word in PIO, " + "with IORDY flow control",
+ ATAID.MinPIOCycleTimeFlow);
+
+ if(ATAID.MaxQueueDepth != 0)
+ sb.AppendLine().AppendFormat("{0} depth of queue maximum", ATAID.MaxQueueDepth + 1);
+
+ if(atapi)
+ {
+ if(ATAID.PacketBusRelease != 0)
+ sb.AppendLine().AppendFormat("{0} ns. typical to release bus from receipt of PACKET",
+ ATAID.PacketBusRelease);
+
+ if(ATAID.ServiceBusyClear != 0)
+ sb.AppendLine().AppendFormat("{0} ns. typical to clear BSY bit from receipt of SERVICE",
+ ATAID.ServiceBusyClear);
+ }
+
+ if((ATAID.TransportMajorVersion & 0xF000) >> 12 == 0x1 ||
+ (ATAID.TransportMajorVersion & 0xF000) >> 12 == 0xE)
+ {
+ if(!ATAID.SATACapabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit.Clear))
+ {
+ if(ATAID.SATACapabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit.
+ Gen1Speed))
+ sb.AppendLine().Append("SATA 1.5Gb/s is supported");
+
+ if(ATAID.SATACapabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit.
+ Gen2Speed))
+ sb.AppendLine().Append("SATA 3.0Gb/s is supported");
+
+ if(ATAID.SATACapabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit.
+ Gen3Speed))
+ sb.AppendLine().Append("SATA 6.0Gb/s is supported");
+
+ if(ATAID.SATACapabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit.
+ PowerReceipt))
+ sb.AppendLine().Append("Receipt of host initiated power management requests is supported");
+
+ if(ATAID.SATACapabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit.
+ PHYEventCounter))
+ sb.AppendLine().Append("PHY Event counters are supported");
+
+ if(ATAID.SATACapabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit.
+ HostSlumbTrans))
+ sb.AppendLine().Append("Supports host automatic partial to slumber transitions is supported");
+
+ if(ATAID.SATACapabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit.
+ DevSlumbTrans))
+ sb.AppendLine().Append("Supports device automatic partial to slumber transitions is supported");
+
+ if(ATAID.SATACapabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit.NCQ))
+ {
+ sb.AppendLine().Append("NCQ is supported");
+
+ if(ATAID.SATACapabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit.
+ NCQPriority))
+ sb.AppendLine().Append("NCQ priority is supported");
+
+ if(ATAID.SATACapabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit.
+ UnloadNCQ))
+ sb.AppendLine().Append("Unload is supported with outstanding NCQ commands");
+ }
+ }
+
+ if(!ATAID.SATACapabilities2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit2.
+ Clear))
+ {
+ if(!ATAID.SATACapabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit.
+ Clear) &&
+ ATAID.SATACapabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit.NCQ))
+ {
+ if(ATAID.SATACapabilities2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
+ SATACapabilitiesBit2.NCQMgmt))
+ sb.AppendLine().Append("NCQ queue management is supported");
+
+ if(ATAID.SATACapabilities2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
+ SATACapabilitiesBit2.NCQStream))
+ sb.AppendLine().Append("NCQ streaming is supported");
+ }
+
+ if(atapi)
+ {
+ if(ATAID.SATACapabilities2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
+ SATACapabilitiesBit2.HostEnvDetect))
+ sb.AppendLine().Append("ATAPI device supports host environment detection");
+
+ if(ATAID.SATACapabilities2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
+ SATACapabilitiesBit2.DevAttSlimline))
+ sb.AppendLine().Append("ATAPI device supports attention on slimline connected devices");
+ }
+
+ //sb.AppendFormat("Negotiated speed = {0}", ((ushort)ATAID.SATACapabilities2 & 0x000E) >> 1);
+ }
+ }
+
+ if(ATAID.InterseekDelay != 0x0000 &&
+ ATAID.InterseekDelay != 0xFFFF)
+ sb.AppendLine().AppendFormat("{0} microseconds of interseek delay for ISO-7779 acoustic testing",
+ ATAID.InterseekDelay);
+
+ if((ushort)ATAID.DeviceFormFactor != 0x0000 &&
+ (ushort)ATAID.DeviceFormFactor != 0xFFFF)
+ switch(ATAID.DeviceFormFactor)
+ {
+ case CommonTypes.Structs.Devices.ATA.Identify.DeviceFormFactorEnum.FiveAndQuarter:
+ sb.AppendLine().Append("Device nominal size is 5.25\"");
+
+ break;
+ case CommonTypes.Structs.Devices.ATA.Identify.DeviceFormFactorEnum.ThreeAndHalf:
+ sb.AppendLine().Append("Device nominal size is 3.5\"");
+
+ break;
+ case CommonTypes.Structs.Devices.ATA.Identify.DeviceFormFactorEnum.TwoAndHalf:
+ sb.AppendLine().Append("Device nominal size is 2.5\"");
+
+ break;
+ case CommonTypes.Structs.Devices.ATA.Identify.DeviceFormFactorEnum.OnePointEight:
+ sb.AppendLine().Append("Device nominal size is 1.8\"");
+
+ break;
+ case CommonTypes.Structs.Devices.ATA.Identify.DeviceFormFactorEnum.LessThanOnePointEight:
+ sb.AppendLine().Append("Device nominal size is smaller than 1.8\"");
+
+ break;
+ default:
+ sb.AppendLine().AppendFormat("Device nominal size field value {0} is unknown",
+ ATAID.DeviceFormFactor);
+
+ break;
+ }
+
+ if(atapi)
+ if(ATAID.ATAPIByteCount > 0)
+ sb.AppendLine().AppendFormat("{0} bytes count limit for ATAPI", ATAID.ATAPIByteCount);
+
+ if(cfa)
+ if((ATAID.CFAPowerMode & 0x8000) == 0x8000)
+ {
+ sb.AppendLine().Append("CompactFlash device supports power mode 1");
+
+ if((ATAID.CFAPowerMode & 0x2000) == 0x2000)
+ sb.AppendLine().Append("CompactFlash power mode 1 required for one or more commands");
+
+ if((ATAID.CFAPowerMode & 0x1000) == 0x1000)
+ sb.AppendLine().Append("CompactFlash power mode 1 is disabled");
+
+ sb.AppendLine().AppendFormat("CompactFlash device uses a maximum of {0} mA",
+ ATAID.CFAPowerMode & 0x0FFF);
+ }
+
+ sb.AppendLine();
+
+ sb.AppendLine().Append("Command set and features:");
+
+ if(ATAID.CommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.Nop))
+ {
+ sb.AppendLine().Append("NOP is supported");
+
+ if(ATAID.EnabledCommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.Nop))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.ReadBuffer))
+ {
+ sb.AppendLine().Append("READ BUFFER is supported");
+
+ if(ATAID.EnabledCommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.ReadBuffer))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.WriteBuffer))
+ {
+ sb.AppendLine().Append("WRITE BUFFER is supported");
+
+ if(ATAID.EnabledCommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.WriteBuffer))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.HPA))
+ {
+ sb.AppendLine().Append("Host Protected Area is supported");
+
+ if(ATAID.EnabledCommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.HPA))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.DeviceReset))
+ {
+ sb.AppendLine().Append("DEVICE RESET is supported");
+
+ if(ATAID.EnabledCommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.DeviceReset))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.Service))
+ {
+ sb.AppendLine().Append("SERVICE interrupt is supported");
+
+ if(ATAID.EnabledCommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.Service))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.Release))
+ {
+ sb.AppendLine().Append("Release is supported");
+
+ if(ATAID.EnabledCommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.Release))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.LookAhead))
+ {
+ sb.AppendLine().Append("Look-ahead read is supported");
+
+ if(ATAID.EnabledCommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.LookAhead))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.WriteCache))
+ {
+ sb.AppendLine().Append("Write cache is supported");
+
+ if(ATAID.EnabledCommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.WriteCache))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.Packet))
+ {
+ sb.AppendLine().Append("PACKET is supported");
+
+ if(ATAID.EnabledCommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.Packet))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.PowerManagement))
+ {
+ sb.AppendLine().Append("Power management is supported");
+
+ if(ATAID.EnabledCommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.
+ PowerManagement))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.RemovableMedia))
+ {
+ sb.AppendLine().Append("Removable media feature set is supported");
+
+ if(ATAID.EnabledCommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.
+ RemovableMedia))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.SecurityMode))
+ {
+ sb.AppendLine().Append("Security mode is supported");
+
+ if(ATAID.EnabledCommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.SecurityMode))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.Capabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit.LBASupport))
+ sb.AppendLine().Append("28-bit LBA is supported");
+
+ if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.MustBeSet) &&
+ !ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.MustBeClear))
+ {
+ if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.LBA48))
+ {
+ sb.AppendLine().Append("48-bit LBA is supported");
+
+ if(ATAID.EnabledCommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.LBA48))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.FlushCache))
+ {
+ sb.AppendLine().Append("FLUSH CACHE is supported");
+
+ if(ATAID.EnabledCommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.
+ FlushCache))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.FlushCacheExt))
+ {
+ sb.AppendLine().Append("FLUSH CACHE EXT is supported");
+
+ if(ATAID.EnabledCommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.
+ FlushCacheExt))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.DCO))
+ {
+ sb.AppendLine().Append("Device Configuration Overlay feature set is supported");
+
+ if(ATAID.EnabledCommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.DCO))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.AAM))
+ {
+ sb.AppendLine().Append("Automatic Acoustic Management is supported");
+
+ if(ATAID.EnabledCommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.AAM))
+ sb.AppendFormat(" and enabled with value {0} (vendor recommends {1}", ATAID.CurrentAAM,
+ ATAID.RecommendedAAM);
+ }
+
+ if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.SetMax))
+ {
+ sb.AppendLine().Append("SET MAX security extension is supported");
+
+ if(ATAID.EnabledCommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.SetMax))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.
+ AddressOffsetReservedAreaBoot))
+ {
+ sb.AppendLine().Append("Address Offset Reserved Area Boot is supported");
+
+ if(ATAID.EnabledCommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.
+ AddressOffsetReservedAreaBoot))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.
+ SetFeaturesRequired))
+ sb.AppendLine().Append("SET FEATURES is required before spin-up");
+
+ if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.PowerUpInStandby))
+ {
+ sb.AppendLine().Append("Power-up in standby is supported");
+
+ if(ATAID.EnabledCommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.
+ PowerUpInStandby))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.
+ RemovableNotification))
+ {
+ sb.AppendLine().Append("Removable Media Status Notification is supported");
+
+ if(ATAID.EnabledCommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.
+ RemovableNotification))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.APM))
+ {
+ sb.AppendLine().Append("Advanced Power Management is supported");
+
+ if(ATAID.EnabledCommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.APM))
+ sb.AppendFormat(" and enabled with value {0}", ATAID.CurrentAPM);
+ }
+
+ if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.CompactFlash))
+ {
+ sb.AppendLine().Append("CompactFlash feature set is supported");
+
+ if(ATAID.EnabledCommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.
+ CompactFlash))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.RWQueuedDMA))
+ {
+ sb.AppendLine().Append("READ DMA QUEUED and WRITE DMA QUEUED are supported");
+
+ if(ATAID.EnabledCommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.
+ RWQueuedDMA))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.DownloadMicrocode))
+ {
+ sb.AppendLine().Append("DOWNLOAD MICROCODE is supported");
+
+ if(ATAID.EnabledCommandSet2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit2.
+ DownloadMicrocode))
+ sb.Append(" and enabled");
+ }
+ }
+
+ if(ATAID.CommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.SMART))
+ {
+ sb.AppendLine().Append("S.M.A.R.T. is supported");
+
+ if(ATAID.EnabledCommandSet.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit.SMART))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.SCTCommandTransport.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SCTCommandTransportBit.
+ Supported))
+ sb.AppendLine().Append("S.M.A.R.T. Command Transport is supported");
+
+ if(ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.MustBeSet) &&
+ !ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.MustBeClear))
+ {
+ if(ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.SMARTSelfTest))
+ {
+ sb.AppendLine().Append("S.M.A.R.T. self-testing is supported");
+
+ if(ATAID.EnabledCommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.
+ SMARTSelfTest))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.SMARTLog))
+ {
+ sb.AppendLine().Append("S.M.A.R.T. error logging is supported");
+
+ if(ATAID.EnabledCommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.
+ SMARTLog))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.IdleImmediate))
+ {
+ sb.AppendLine().Append("IDLE IMMEDIATE with UNLOAD FEATURE is supported");
+
+ if(ATAID.EnabledCommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.
+ IdleImmediate))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.WriteURG))
+ sb.AppendLine().Append("URG bit is supported in WRITE STREAM DMA EXT and WRITE STREAM EXT");
+
+ if(ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.ReadURG))
+ sb.AppendLine().Append("URG bit is supported in READ STREAM DMA EXT and READ STREAM EXT");
+
+ if(ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.WWN))
+ sb.AppendLine().Append("Device has a World Wide Name");
+
+ if(ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.FUAWriteQ))
+ {
+ sb.AppendLine().Append("WRITE DMA QUEUED FUA EXT is supported");
+
+ if(ATAID.EnabledCommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.
+ FUAWriteQ))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.FUAWrite))
+ {
+ sb.AppendLine().Append("WRITE DMA FUA EXT and WRITE MULTIPLE FUA EXT are supported");
+
+ if(ATAID.EnabledCommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.
+ FUAWrite))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.GPL))
+ {
+ sb.AppendLine().Append("General Purpose Logging is supported");
+
+ if(ATAID.EnabledCommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.GPL))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.Streaming))
+ {
+ sb.AppendLine().Append("Streaming feature set is supported");
+
+ if(ATAID.EnabledCommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.
+ Streaming))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.MCPT))
+ {
+ sb.AppendLine().Append("Media Card Pass Through command set is supported");
+
+ if(ATAID.EnabledCommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.MCPT))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.MediaSerial))
+ {
+ sb.AppendLine().Append("Media Serial is supported");
+
+ if(ATAID.EnabledCommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.
+ MediaSerial))
+ sb.Append(" and valid");
+ }
+ }
+
+ if(ATAID.CommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.MustBeSet) &&
+ !ATAID.CommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.MustBeClear))
+ {
+ if(ATAID.CommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.DSN))
+ {
+ sb.AppendLine().Append("DSN feature set is supported");
+
+ if(ATAID.EnabledCommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.DSN))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.AMAC))
+ {
+ sb.AppendLine().Append("Accessible Max Address Configuration is supported");
+
+ if(ATAID.EnabledCommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.AMAC))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.ExtPowerCond))
+ {
+ sb.AppendLine().Append("Extended Power Conditions are supported");
+
+ if(ATAID.EnabledCommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.
+ ExtPowerCond))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.ExtStatusReport))
+ {
+ sb.AppendLine().Append("Extended Status Reporting is supported");
+
+ if(ATAID.EnabledCommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.
+ ExtStatusReport))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.FreeFallControl))
+ {
+ sb.AppendLine().Append("Free-fall control feature set is supported");
+
+ if(ATAID.EnabledCommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.
+ FreeFallControl))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.
+ SegmentedDownloadMicrocode))
+ {
+ sb.AppendLine().Append("Segmented feature in DOWNLOAD MICROCODE is supported");
+
+ if(ATAID.EnabledCommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.
+ SegmentedDownloadMicrocode))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.RWDMAExtGpl))
+ {
+ sb.AppendLine().Append("READ/WRITE DMA EXT GPL are supported");
+
+ if(ATAID.EnabledCommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.
+ RWDMAExtGpl))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.WriteUnc))
+ {
+ sb.AppendLine().Append("WRITE UNCORRECTABLE is supported");
+
+ if(ATAID.EnabledCommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.
+ WriteUnc))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.CommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.WRV))
+ {
+ sb.AppendLine().Append("Write/Read/Verify is supported");
+
+ if(ATAID.EnabledCommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.WRV))
+ sb.Append(" and enabled");
+
+ sb.AppendLine().AppendFormat("{0} sectors for Write/Read/Verify mode 2", ATAID.WRVSectorCountMode2);
+ sb.AppendLine().AppendFormat("{0} sectors for Write/Read/Verify mode 3", ATAID.WRVSectorCountMode3);
+
+ if(ATAID.EnabledCommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.WRV))
+ sb.AppendLine().AppendFormat("Current Write/Read/Verify mode: {0}", ATAID.WRVMode);
+ }
+
+ if(ATAID.CommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.DT1825))
+ {
+ sb.AppendLine().Append("DT1825 is supported");
+
+ if(ATAID.EnabledCommandSet4.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit4.DT1825))
+ sb.Append(" and enabled");
+ }
+ }
+
+ if(ATAID.Capabilities3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit3.BlockErase))
+ sb.AppendLine().Append("BLOCK ERASE EXT is supported");
+
+ if(ATAID.Capabilities3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit3.Overwrite))
+ sb.AppendLine().Append("OVERWRITE EXT is supported");
+
+ if(ATAID.Capabilities3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit3.CryptoScramble))
+ sb.AppendLine().Append("CRYPTO SCRAMBLE EXT is supported");
+
+ if(ATAID.CommandSet5.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit5.DeviceConfDMA))
+ sb.AppendLine().
+ Append("DEVICE CONFIGURATION IDENTIFY DMA and DEVICE CONFIGURATION SET DMA are supported");
+
+ if(ATAID.CommandSet5.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit5.ReadBufferDMA))
+ sb.AppendLine().Append("READ BUFFER DMA is supported");
+
+ if(ATAID.CommandSet5.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit5.WriteBufferDMA))
+ sb.AppendLine().Append("WRITE BUFFER DMA is supported");
+
+ if(ATAID.CommandSet5.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit5.DownloadMicroCodeDMA))
+ sb.AppendLine().Append("DOWNLOAD MICROCODE DMA is supported");
+
+ if(ATAID.CommandSet5.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit5.SetMaxDMA))
+ sb.AppendLine().Append("SET PASSWORD DMA and SET UNLOCK DMA are supported");
+
+ if(ATAID.CommandSet5.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit5.Ata28))
+ sb.AppendLine().Append("Not all 28-bit commands are supported");
+
+ if(ATAID.CommandSet5.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit5.CFast))
+ sb.AppendLine().Append("Device follows CFast specification");
+
+ if(ATAID.CommandSet5.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit5.IEEE1667))
+ sb.AppendLine().Append("Device follows IEEE-1667");
+
+ if(ATAID.CommandSet5.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit5.DeterministicTrim))
+ {
+ sb.AppendLine().Append("Read after TRIM is deterministic");
+
+ if(ATAID.CommandSet5.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit5.ReadZeroTrim))
+ sb.AppendLine().Append("Read after TRIM returns empty data");
+ }
+
+ if(ATAID.CommandSet5.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit5.
+ LongPhysSectorAligError))
+ sb.AppendLine().Append("Device supports Long Physical Sector Alignment Error Reporting Control");
+
+ if(ATAID.CommandSet5.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit5.Encrypted))
+ sb.AppendLine().Append("Device encrypts all user data");
+
+ if(ATAID.CommandSet5.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit5.AllCacheNV))
+ sb.AppendLine().Append("Device's write cache is non-volatile");
+
+ if(ATAID.CommandSet5.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit5.ZonedBit0) ||
+ ATAID.CommandSet5.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit5.ZonedBit1))
+ sb.AppendLine().Append("Device is zoned");
+
+ if(ATAID.Capabilities3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit3.Sanitize))
+ {
+ sb.AppendLine().Append("Sanitize feature set is supported");
+
+ sb.AppendLine().
+ Append(ATAID.Capabilities3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit3.
+ SanitizeCommands)
+ ? "Sanitize commands are specified by ACS-3 or higher"
+ : "Sanitize commands are specified by ACS-2");
+
+ if(ATAID.Capabilities3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit3.
+ SanitizeAntifreeze))
+ sb.AppendLine().Append("SANITIZE ANTIFREEZE LOCK EXT is supported");
+ }
+
+ if(!ata1 &&
+ maxatalevel >= 8)
+ if(ATAID.TrustedComputing.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TrustedComputingBit.Set) &&
+ !ATAID.TrustedComputing.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TrustedComputingBit.
+ Clear) &&
+ ATAID.TrustedComputing.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.TrustedComputingBit.
+ TrustedComputing))
+ sb.AppendLine().Append("Trusted Computing feature set is supported");
+
+ if((ATAID.TransportMajorVersion & 0xF000) >> 12 == 0x1 ||
+ (ATAID.TransportMajorVersion & 0xF000) >> 12 == 0xE)
+ {
+ if(!ATAID.SATACapabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit.Clear))
+ if(ATAID.SATACapabilities.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit.
+ ReadLogDMAExt))
+ sb.AppendLine().Append("READ LOG DMA EXT is supported");
+
+ if(!ATAID.SATACapabilities2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit2.
+ Clear))
+ if(ATAID.SATACapabilities2.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATACapabilitiesBit2.
+ FPDMAQ))
+ sb.AppendLine().Append("RECEIVE FPDMA QUEUED and SEND FPDMA QUEUED are supported");
+
+ if(!ATAID.SATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATAFeaturesBit.Clear))
+ {
+ if(ATAID.SATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATAFeaturesBit.
+ NonZeroBufferOffset))
+ {
+ sb.AppendLine().Append("Non-zero buffer offsets are supported");
+
+ if(ATAID.EnabledSATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATAFeaturesBit.
+ NonZeroBufferOffset))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.SATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATAFeaturesBit.DMASetup))
+ {
+ sb.AppendLine().Append("DMA Setup auto-activation is supported");
+
+ if(ATAID.EnabledSATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATAFeaturesBit.
+ DMASetup))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.SATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATAFeaturesBit.
+ InitPowerMgmt))
+ {
+ sb.AppendLine().Append("Device-initiated power management is supported");
+
+ if(ATAID.EnabledSATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATAFeaturesBit.
+ InitPowerMgmt))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.SATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATAFeaturesBit.InOrderData))
+ {
+ sb.AppendLine().Append("In-order data delivery is supported");
+
+ if(ATAID.EnabledSATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATAFeaturesBit.
+ InOrderData))
+ sb.Append(" and enabled");
+ }
+
+ if(!atapi)
+ if(ATAID.SATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATAFeaturesBit.
+ HardwareFeatureControl))
+ {
+ sb.AppendLine().Append("Hardware Feature Control is supported");
+
+ if(ATAID.EnabledSATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
+ SATAFeaturesBit.HardwareFeatureControl))
+ sb.Append(" and enabled");
+ }
+
+ if(atapi)
+ if(ATAID.SATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATAFeaturesBit.
+ AsyncNotification))
+ {
+ sb.AppendLine().Append("Asynchronous notification is supported");
+
+ if(ATAID.EnabledSATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
+ SATAFeaturesBit.AsyncNotification))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.SATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATAFeaturesBit.
+ SettingsPreserve))
+ {
+ sb.AppendLine().Append("Software Settings Preservation is supported");
+
+ if(ATAID.EnabledSATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATAFeaturesBit.
+ SettingsPreserve))
+ sb.Append(" and enabled");
+ }
+
+ if(ATAID.SATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATAFeaturesBit.
+ NCQAutoSense))
+ sb.AppendLine().Append("NCQ Autosense is supported");
+
+ if(ATAID.EnabledSATAFeatures.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SATAFeaturesBit.
+ EnabledSlumber))
+ sb.AppendLine().Append("Automatic Partial to Slumber transitions are enabled");
+ }
+ }
+
+ if((ATAID.RemovableStatusSet & 0x03) > 0)
+ sb.AppendLine().Append("Removable Media Status Notification feature set is supported");
+
+ if(ATAID.FreeFallSensitivity != 0x00 &&
+ ATAID.FreeFallSensitivity != 0xFF)
+ sb.AppendLine().AppendFormat("Free-fall sensitivity set to {0}", ATAID.FreeFallSensitivity);
+
+ if(ATAID.DataSetMgmt.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.DataSetMgmtBit.Trim))
+ sb.AppendLine().Append("TRIM is supported");
+
+ if(ATAID.DataSetMgmtSize > 0)
+ sb.AppendLine().AppendFormat("DATA SET MANAGEMENT can receive a maximum of {0} blocks of 512 bytes",
+ ATAID.DataSetMgmtSize);
+
+ sb.AppendLine().AppendLine();
+
+ if(ATAID.SecurityStatus.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SecurityStatusBit.Supported))
+ {
+ sb.AppendLine("Security:");
+
+ if(ATAID.SecurityStatus.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SecurityStatusBit.Enabled))
+ {
+ sb.AppendLine("Security is enabled");
+
+ sb.AppendLine(ATAID.SecurityStatus.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
+ SecurityStatusBit.Locked)
+ ? "Security is locked" : "Security is not locked");
+
+ sb.AppendLine(ATAID.SecurityStatus.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
+ SecurityStatusBit.Frozen)
+ ? "Security is frozen" : "Security is not frozen");
+
+ sb.AppendLine(ATAID.SecurityStatus.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
+ SecurityStatusBit.Expired)
+ ? "Security count has expired" : "Security count has not expired");
+
+ sb.AppendLine(ATAID.SecurityStatus.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.
+ SecurityStatusBit.Maximum)
+ ? "Security level is maximum" : "Security level is high");
+ }
+ else
+ sb.AppendLine("Security is not enabled");
+
+ if(ATAID.SecurityStatus.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SecurityStatusBit.Enhanced))
+ sb.AppendLine("Supports enhanced security erase");
+
+ sb.AppendFormat("{0} minutes to complete secure erase", ATAID.SecurityEraseTime * 2).AppendLine();
+
+ if(ATAID.SecurityStatus.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SecurityStatusBit.Enhanced))
+ sb.AppendFormat("{0} minutes to complete enhanced secure erase",
+ ATAID.EnhancedSecurityEraseTime * 2).AppendLine();
+
+ sb.AppendFormat("Master password revision code: {0}", ATAID.MasterPasswordRevisionCode).AppendLine();
+ }
+
+ if(ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.MustBeSet) &&
+ !ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.MustBeClear) &&
+ ATAID.CommandSet3.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.CommandSetBit3.Streaming))
+ {
+ sb.AppendLine().AppendLine("Streaming:");
+ sb.AppendFormat("Minimum request size is {0}", ATAID.StreamMinReqSize);
+ sb.AppendFormat("Streaming transfer time in PIO is {0}", ATAID.StreamTransferTimePIO);
+ sb.AppendFormat("Streaming transfer time in DMA is {0}", ATAID.StreamTransferTimeDMA);
+ sb.AppendFormat("Streaming access latency is {0}", ATAID.StreamAccessLatency);
+ sb.AppendFormat("Streaming performance granularity is {0}", ATAID.StreamPerformanceGranularity);
+ }
+
+ if(ATAID.SCTCommandTransport.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SCTCommandTransportBit.
+ Supported))
+ {
+ sb.AppendLine().AppendLine("S.M.A.R.T. Command Transport (SCT):");
+
+ if(ATAID.SCTCommandTransport.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SCTCommandTransportBit.
+ LongSectorAccess))
+ sb.AppendLine("SCT Long Sector Address is supported");
+
+ if(ATAID.SCTCommandTransport.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SCTCommandTransportBit.
+ WriteSame))
+ sb.AppendLine("SCT Write Same is supported");
+
+ if(ATAID.SCTCommandTransport.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SCTCommandTransportBit.
+ ErrorRecoveryControl))
+ sb.AppendLine("SCT Error Recovery Control is supported");
+
+ if(ATAID.SCTCommandTransport.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SCTCommandTransportBit.
+ FeaturesControl))
+ sb.AppendLine("SCT Features Control is supported");
+
+ if(ATAID.SCTCommandTransport.HasFlag(CommonTypes.Structs.Devices.ATA.Identify.SCTCommandTransportBit.
+ DataTables))
+ sb.AppendLine("SCT Data Tables are supported");
+ }
+
+ if((ATAID.NVCacheCaps & 0x0010) == 0x0010)
+ {
+ sb.AppendLine().AppendLine("Non-Volatile Cache:");
+ sb.AppendLine().AppendFormat("Version {0}", (ATAID.NVCacheCaps & 0xF000) >> 12).AppendLine();
+
+ if((ATAID.NVCacheCaps & 0x0001) == 0x0001)
+ {
+ sb.Append("Power mode feature set is supported");
+
+ if((ATAID.NVCacheCaps & 0x0002) == 0x0002)
+ sb.Append(" and enabled");
+
+ sb.AppendLine();
+
+ sb.AppendLine().AppendFormat("Version {0}", (ATAID.NVCacheCaps & 0x0F00) >> 8).AppendLine();
+ }
+
+ sb.AppendLine().AppendFormat("Non-Volatile Cache is {0} bytes", ATAID.NVCacheSize * logicalSectorSize).
+ AppendLine();
+ }
+
+ #if DEBUG
+ sb.AppendLine();
+
+ if(ATAID.VendorWord9 != 0x0000 &&
+ ATAID.VendorWord9 != 0xFFFF)
+ sb.AppendFormat("Word 9: 0x{0:X4}", ATAID.VendorWord9).AppendLine();
+
+ if((ATAID.VendorWord47 & 0x7F) != 0x7F &&
+ (ATAID.VendorWord47 & 0x7F) != 0x00)
+ sb.AppendFormat("Word 47 bits 15 to 8: 0x{0:X2}", ATAID.VendorWord47).AppendLine();
+
+ if(ATAID.VendorWord51 != 0x00 &&
+ ATAID.VendorWord51 != 0xFF)
+ sb.AppendFormat("Word 51 bits 7 to 0: 0x{0:X2}", ATAID.VendorWord51).AppendLine();
+
+ if(ATAID.VendorWord52 != 0x00 &&
+ ATAID.VendorWord52 != 0xFF)
+ sb.AppendFormat("Word 52 bits 7 to 0: 0x{0:X2}", ATAID.VendorWord52).AppendLine();
+
+ if(ATAID.ReservedWord64 != 0x00 &&
+ ATAID.ReservedWord64 != 0xFF)
+ sb.AppendFormat("Word 64 bits 15 to 8: 0x{0:X2}", ATAID.ReservedWord64).AppendLine();
+
+ if(ATAID.ReservedWord70 != 0x0000 &&
+ ATAID.ReservedWord70 != 0xFFFF)
+ sb.AppendFormat("Word 70: 0x{0:X4}", ATAID.ReservedWord70).AppendLine();
+
+ if(ATAID.ReservedWord73 != 0x0000 &&
+ ATAID.ReservedWord73 != 0xFFFF)
+ sb.AppendFormat("Word 73: 0x{0:X4}", ATAID.ReservedWord73).AppendLine();
+
+ if(ATAID.ReservedWord74 != 0x0000 &&
+ ATAID.ReservedWord74 != 0xFFFF)
+ sb.AppendFormat("Word 74: 0x{0:X4}", ATAID.ReservedWord74).AppendLine();
+
+ if(ATAID.ReservedWord116 != 0x0000 &&
+ ATAID.ReservedWord116 != 0xFFFF)
+ sb.AppendFormat("Word 116: 0x{0:X4}", ATAID.ReservedWord116).AppendLine();
+
+ for(int i = 0; i < ATAID.ReservedWords121.Length; i++)
+ if(ATAID.ReservedWords121[i] != 0x0000 &&
+ ATAID.ReservedWords121[i] != 0xFFFF)
+ sb.AppendFormat("Word {1}: 0x{0:X4}", ATAID.ReservedWords121[i], 121 + i).AppendLine();
+
+ for(int i = 0; i < ATAID.ReservedWords129.Length; i++)
+ if(ATAID.ReservedWords129[i] != 0x0000 &&
+ ATAID.ReservedWords129[i] != 0xFFFF)
+ sb.AppendFormat("Word {1}: 0x{0:X4}", ATAID.ReservedWords129[i], 129 + i).AppendLine();
+
+ for(int i = 0; i < ATAID.ReservedCFA.Length; i++)
+ if(ATAID.ReservedCFA[i] != 0x0000 &&
+ ATAID.ReservedCFA[i] != 0xFFFF)
+ sb.AppendFormat("Word {1} (CFA): 0x{0:X4}", ATAID.ReservedCFA[i], 161 + i).AppendLine();
+
+ if(ATAID.ReservedWord174 != 0x0000 &&
+ ATAID.ReservedWord174 != 0xFFFF)
+ sb.AppendFormat("Word 174: 0x{0:X4}", ATAID.ReservedWord174).AppendLine();
+
+ if(ATAID.ReservedWord175 != 0x0000 &&
+ ATAID.ReservedWord175 != 0xFFFF)
+ sb.AppendFormat("Word 175: 0x{0:X4}", ATAID.ReservedWord175).AppendLine();
+
+ if(ATAID.ReservedCEATAWord207 != 0x0000 &&
+ ATAID.ReservedCEATAWord207 != 0xFFFF)
+ sb.AppendFormat("Word 207 (CE-ATA): 0x{0:X4}", ATAID.ReservedCEATAWord207).AppendLine();
+
+ if(ATAID.ReservedCEATAWord208 != 0x0000 &&
+ ATAID.ReservedCEATAWord208 != 0xFFFF)
+ sb.AppendFormat("Word 208 (CE-ATA): 0x{0:X4}", ATAID.ReservedCEATAWord208).AppendLine();
+
+ if(ATAID.NVReserved != 0x00 &&
+ ATAID.NVReserved != 0xFF)
+ sb.AppendFormat("Word 219 bits 15 to 8: 0x{0:X2}", ATAID.NVReserved).AppendLine();
+
+ if(ATAID.WRVReserved != 0x00 &&
+ ATAID.WRVReserved != 0xFF)
+ sb.AppendFormat("Word 220 bits 15 to 8: 0x{0:X2}", ATAID.WRVReserved).AppendLine();
+
+ if(ATAID.ReservedWord221 != 0x0000 &&
+ ATAID.ReservedWord221 != 0xFFFF)
+ sb.AppendFormat("Word 221: 0x{0:X4}", ATAID.ReservedWord221).AppendLine();
+
+ for(int i = 0; i < ATAID.ReservedCEATA224.Length; i++)
+ if(ATAID.ReservedCEATA224[i] != 0x0000 &&
+ ATAID.ReservedCEATA224[i] != 0xFFFF)
+ sb.AppendFormat("Word {1} (CE-ATA): 0x{0:X4}", ATAID.ReservedCEATA224[i], 224 + i).AppendLine();
+
+ for(int i = 0; i < ATAID.ReservedWords.Length; i++)
+ if(ATAID.ReservedWords[i] != 0x0000 &&
+ ATAID.ReservedWords[i] != 0xFFFF)
+ sb.AppendFormat("Word {1}: 0x{0:X4}", ATAID.ReservedWords[i], 236 + i).AppendLine();
+ #endif
+ return sb.ToString();
}
}
\ No newline at end of file
diff --git a/ATA/Registers.cs b/ATA/Registers.cs
index 2ff0303..d35f9fc 100644
--- a/ATA/Registers.cs
+++ b/ATA/Registers.cs
@@ -32,83 +32,82 @@
using System.Runtime.InteropServices;
-namespace Aaru.Decoders.ATA
+namespace Aaru.Decoders.ATA;
+
+[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
+public struct AtaRegistersChs
{
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
- public struct AtaRegistersChs
- {
- public byte Feature;
- public byte SectorCount;
- public byte Sector;
- public byte CylinderLow;
- public byte CylinderHigh;
- public byte DeviceHead;
- public byte Command;
- }
+ public byte Feature;
+ public byte SectorCount;
+ public byte Sector;
+ public byte CylinderLow;
+ public byte CylinderHigh;
+ public byte DeviceHead;
+ public byte Command;
+}
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
- public struct AtaRegistersLba28
- {
- public byte Feature;
- public byte SectorCount;
- public byte LbaLow;
- public byte LbaMid;
- public byte LbaHigh;
- public byte DeviceHead;
- public byte Command;
- }
+[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
+public struct AtaRegistersLba28
+{
+ public byte Feature;
+ public byte SectorCount;
+ public byte LbaLow;
+ public byte LbaMid;
+ public byte LbaHigh;
+ public byte DeviceHead;
+ public byte Command;
+}
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
- public struct AtaRegistersLba48
- {
- public ushort Feature;
- public ushort SectorCount;
- public byte LbaLowPrevious;
- public byte LbaLowCurrent;
- public byte LbaMidPrevious;
- public byte LbaMidCurrent;
- public byte LbaHighPrevious;
- public byte LbaHighCurrent;
- public byte DeviceHead;
- public byte Command;
- }
+[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
+public struct AtaRegistersLba48
+{
+ public ushort Feature;
+ public ushort SectorCount;
+ public byte LbaLowPrevious;
+ public byte LbaLowCurrent;
+ public byte LbaMidPrevious;
+ public byte LbaMidCurrent;
+ public byte LbaHighPrevious;
+ public byte LbaHighCurrent;
+ public byte DeviceHead;
+ public byte Command;
+}
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
- public struct AtaErrorRegistersChs
- {
- public byte Status;
- public byte Error;
- public byte SectorCount;
- public byte Sector;
- public byte CylinderLow;
- public byte CylinderHigh;
- public byte DeviceHead;
- }
+[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
+public struct AtaErrorRegistersChs
+{
+ public byte Status;
+ public byte Error;
+ public byte SectorCount;
+ public byte Sector;
+ public byte CylinderLow;
+ public byte CylinderHigh;
+ public byte DeviceHead;
+}
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
- public struct AtaErrorRegistersLba28
- {
- public byte Status;
- public byte Error;
- public byte SectorCount;
- public byte LbaLow;
- public byte LbaMid;
- public byte LbaHigh;
- public byte DeviceHead;
- }
+[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
+public struct AtaErrorRegistersLba28
+{
+ public byte Status;
+ public byte Error;
+ public byte SectorCount;
+ public byte LbaLow;
+ public byte LbaMid;
+ public byte LbaHigh;
+ public byte DeviceHead;
+}
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
- public struct AtaErrorRegistersLba48
- {
- public byte Status;
- public byte Error;
- public ushort SectorCount;
- public byte LbaLowPrevious;
- public byte LbaLowCurrent;
- public byte LbaMidPrevious;
- public byte LbaMidCurrent;
- public byte LbaHighPrevious;
- public byte LbaHighCurrent;
- public byte DeviceHead;
- }
+[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
+public struct AtaErrorRegistersLba48
+{
+ public byte Status;
+ public byte Error;
+ public ushort SectorCount;
+ public byte LbaLowPrevious;
+ public byte LbaLowCurrent;
+ public byte LbaMidPrevious;
+ public byte LbaMidCurrent;
+ public byte LbaHighPrevious;
+ public byte LbaHighCurrent;
+ public byte DeviceHead;
}
\ No newline at end of file
diff --git a/Bluray/BCA.cs b/Bluray/BCA.cs
index eaef404..2b37d6e 100644
--- a/Bluray/BCA.cs
+++ b/Bluray/BCA.cs
@@ -36,89 +36,88 @@ using System.Text;
using Aaru.Console;
using Aaru.Helpers;
-namespace Aaru.Decoders.Bluray
+namespace Aaru.Decoders.Bluray;
+
+// Information from the following standards:
+// ANSI X3.304-1997
+// T10/1048-D revision 9.0
+// T10/1048-D revision 10a
+// T10/1228-D revision 7.0c
+// T10/1228-D revision 11a
+// T10/1363-D revision 10g
+// T10/1545-D revision 1d
+// T10/1545-D revision 5
+// T10/1545-D revision 5a
+// T10/1675-D revision 2c
+// T10/1675-D revision 4
+// T10/1836-D revision 2g
+[SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"),
+ SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), SuppressMessage("ReSharper", "NotAccessedField.Global")]
+public static class BCA
{
- // Information from the following standards:
- // ANSI X3.304-1997
- // T10/1048-D revision 9.0
- // T10/1048-D revision 10a
- // T10/1228-D revision 7.0c
- // T10/1228-D revision 11a
- // T10/1363-D revision 10g
- // T10/1545-D revision 1d
- // T10/1545-D revision 5
- // T10/1545-D revision 5a
- // T10/1675-D revision 2c
- // T10/1675-D revision 4
- // T10/1836-D revision 2g
- [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"),
- SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), SuppressMessage("ReSharper", "NotAccessedField.Global")]
- public static class BCA
+ #region Public structures
+ public struct BurstCuttingArea
{
- #region Public structures
- public struct BurstCuttingArea
- {
- /// Bytes 0 to 1 Always 66
- public ushort DataLength;
- /// Byte 2 Reserved
- public byte Reserved1;
- /// Byte 3 Reserved
- public byte Reserved2;
- /// Byte 4 to 67 BCA data
- public byte[] BCA;
- }
- #endregion Public structures
- #region Public methods
- public static BurstCuttingArea? Decode(byte[] BCAResponse)
- {
- if(BCAResponse == null)
- return null;
-
- if(BCAResponse.Length != 68)
- {
- AaruConsole.DebugWriteLine("BD BCA decoder", "Found incorrect Blu-ray BCA size ({0} bytes)",
- BCAResponse.Length);
-
- return null;
- }
-
- var decoded = new BurstCuttingArea
- {
- DataLength = BigEndianBitConverter.ToUInt16(BCAResponse, 0),
- Reserved1 = BCAResponse[2],
- Reserved2 = BCAResponse[3],
- BCA = new byte[64]
- };
-
- Array.Copy(BCAResponse, 4, decoded.BCA, 0, 64);
-
- return decoded;
- }
-
- public static string Prettify(BurstCuttingArea? BCAResponse)
- {
- if(BCAResponse == null)
- return null;
-
- BurstCuttingArea response = BCAResponse.Value;
-
- var sb = new StringBuilder();
-
- #if DEBUG
- if(response.Reserved1 != 0)
- sb.AppendFormat("Reserved1 = 0x{0:X2}", response.Reserved1).AppendLine();
-
- if(response.Reserved2 != 0)
- sb.AppendFormat("Reserved2 = 0x{0:X2}", response.Reserved2).AppendLine();
- #endif
-
- sb.AppendFormat("Blu-ray Burst Cutting Area in hex follows:");
- sb.AppendLine(PrintHex.ByteArrayToHexArrayString(response.BCA, 80));
-
- return sb.ToString();
- }
-
- public static string Prettify(byte[] BCAResponse) => Prettify(Decode(BCAResponse));
- #endregion Public methods
+ /// Bytes 0 to 1 Always 66
+ public ushort DataLength;
+ /// Byte 2 Reserved
+ public byte Reserved1;
+ /// Byte 3 Reserved
+ public byte Reserved2;
+ /// Byte 4 to 67 BCA data
+ public byte[] BCA;
}
+ #endregion Public structures
+ #region Public methods
+ public static BurstCuttingArea? Decode(byte[] BCAResponse)
+ {
+ if(BCAResponse == null)
+ return null;
+
+ if(BCAResponse.Length != 68)
+ {
+ AaruConsole.DebugWriteLine("BD BCA decoder", "Found incorrect Blu-ray BCA size ({0} bytes)",
+ BCAResponse.Length);
+
+ return null;
+ }
+
+ var decoded = new BurstCuttingArea
+ {
+ DataLength = BigEndianBitConverter.ToUInt16(BCAResponse, 0),
+ Reserved1 = BCAResponse[2],
+ Reserved2 = BCAResponse[3],
+ BCA = new byte[64]
+ };
+
+ Array.Copy(BCAResponse, 4, decoded.BCA, 0, 64);
+
+ return decoded;
+ }
+
+ public static string Prettify(BurstCuttingArea? BCAResponse)
+ {
+ if(BCAResponse == null)
+ return null;
+
+ BurstCuttingArea response = BCAResponse.Value;
+
+ var sb = new StringBuilder();
+
+ #if DEBUG
+ if(response.Reserved1 != 0)
+ sb.AppendFormat("Reserved1 = 0x{0:X2}", response.Reserved1).AppendLine();
+
+ if(response.Reserved2 != 0)
+ sb.AppendFormat("Reserved2 = 0x{0:X2}", response.Reserved2).AppendLine();
+ #endif
+
+ sb.AppendFormat("Blu-ray Burst Cutting Area in hex follows:");
+ sb.AppendLine(PrintHex.ByteArrayToHexArrayString(response.BCA, 80));
+
+ return sb.ToString();
+ }
+
+ public static string Prettify(byte[] BCAResponse) => Prettify(Decode(BCAResponse));
+ #endregion Public methods
}
\ No newline at end of file
diff --git a/Bluray/Cartridge.cs b/Bluray/Cartridge.cs
index 83581db..bd65083 100644
--- a/Bluray/Cartridge.cs
+++ b/Bluray/Cartridge.cs
@@ -36,145 +36,144 @@ using System.Text;
using Aaru.Console;
using Aaru.Helpers;
-namespace Aaru.Decoders.Bluray
+namespace Aaru.Decoders.Bluray;
+
+// Information from the following standards:
+// ANSI X3.304-1997
+// T10/1048-D revision 9.0
+// T10/1048-D revision 10a
+// T10/1228-D revision 7.0c
+// T10/1228-D revision 11a
+// T10/1363-D revision 10g
+// T10/1545-D revision 1d
+// T10/1545-D revision 5
+// T10/1545-D revision 5a
+// T10/1675-D revision 2c
+// T10/1675-D revision 4
+// T10/1836-D revision 2g
+[SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"),
+ SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), SuppressMessage("ReSharper", "NotAccessedField.Global"),
+ SuppressMessage("ReSharper", "UnassignedField.Global")]
+public static class Cartridge
{
- // Information from the following standards:
- // ANSI X3.304-1997
- // T10/1048-D revision 9.0
- // T10/1048-D revision 10a
- // T10/1228-D revision 7.0c
- // T10/1228-D revision 11a
- // T10/1363-D revision 10g
- // T10/1545-D revision 1d
- // T10/1545-D revision 5
- // T10/1545-D revision 5a
- // T10/1675-D revision 2c
- // T10/1675-D revision 4
- // T10/1836-D revision 2g
- [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"),
- SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), SuppressMessage("ReSharper", "NotAccessedField.Global"),
- SuppressMessage("ReSharper", "UnassignedField.Global")]
- public static class Cartridge
+ #region Public structures
+ public struct CartridgeStatus
{
- #region Public structures
- public struct CartridgeStatus
+ /// Bytes 0 to 1 Always 6
+ public ushort DataLength;
+ /// Byte 2 Reserved
+ public byte Reserved1;
+ /// Byte 3 Reserved
+ public byte Reserved2;
+ /// Byte 4, bit 7 Medium is inserted in a cartridge
+ public bool Cartridge;
+ /// Byte 4, bit 6 Medium taken out / put in a cartridge
+ public bool OUT;
+ /// Byte 4, bits 5 to 3 Reserved
+ public byte Reserved3;
+ /// Byte 4, bit 2 Cartridge sets write protection
+ public bool CWP;
+ /// Byte 4, bits 1 to 0 Reserved
+ public byte Reserved4;
+ /// Byte 5 Reserved
+ public byte Reserved5;
+ /// Byte 6 Reserved
+ public byte Reserved6;
+ /// Byte 7 Reserved
+ public byte Reserved7;
+ }
+ #endregion Public structures
+ #region Public methods
+ public static CartridgeStatus? Decode(byte[] CSResponse)
+ {
+ if(CSResponse == null)
+ return null;
+
+ if(CSResponse.Length != 8)
{
- /// Bytes 0 to 1 Always 6
- public ushort DataLength;
- /// Byte 2 Reserved
- public byte Reserved1;
- /// Byte 3 Reserved
- public byte Reserved2;
- /// Byte 4, bit 7 Medium is inserted in a cartridge
- public bool Cartridge;
- /// Byte 4, bit 6 Medium taken out / put in a cartridge
- public bool OUT;
- /// Byte 4, bits 5 to 3 Reserved
- public byte Reserved3;
- /// Byte 4, bit 2 Cartridge sets write protection
- public bool CWP;
- /// Byte 4, bits 1 to 0 Reserved
- public byte Reserved4;
- /// Byte 5 Reserved
- public byte Reserved5;
- /// Byte 6 Reserved
- public byte Reserved6;
- /// Byte 7 Reserved
- public byte Reserved7;
- }
- #endregion Public structures
- #region Public methods
- public static CartridgeStatus? Decode(byte[] CSResponse)
- {
- if(CSResponse == null)
- return null;
+ AaruConsole.DebugWriteLine("BD Cartridge Status decoder",
+ "Found incorrect Blu-ray Cartridge Status size ({0} bytes)",
+ CSResponse.Length);
- if(CSResponse.Length != 8)
- {
- AaruConsole.DebugWriteLine("BD Cartridge Status decoder",
- "Found incorrect Blu-ray Cartridge Status size ({0} bytes)",
- CSResponse.Length);
-
- return null;
- }
-
- var decoded = new CartridgeStatus
- {
- DataLength = BigEndianBitConverter.ToUInt16(CSResponse, 0),
- Reserved1 = CSResponse[2],
- Reserved2 = CSResponse[3],
- Cartridge = Convert.ToBoolean(CSResponse[4] & 0x80),
- OUT = Convert.ToBoolean(CSResponse[4] & 0x40),
- Reserved3 = (byte)((CSResponse[4] & 0x38) >> 3),
- CWP = Convert.ToBoolean(CSResponse[4] & 0x04),
- Reserved4 = (byte)(CSResponse[4] & 0x03),
- Reserved5 = CSResponse[5],
- Reserved6 = CSResponse[6],
- Reserved7 = CSResponse[7]
- };
-
- return decoded;
+ return null;
}
- public static string Prettify(CartridgeStatus? CSResponse)
+ var decoded = new CartridgeStatus
{
- if(CSResponse == null)
- return null;
+ DataLength = BigEndianBitConverter.ToUInt16(CSResponse, 0),
+ Reserved1 = CSResponse[2],
+ Reserved2 = CSResponse[3],
+ Cartridge = Convert.ToBoolean(CSResponse[4] & 0x80),
+ OUT = Convert.ToBoolean(CSResponse[4] & 0x40),
+ Reserved3 = (byte)((CSResponse[4] & 0x38) >> 3),
+ CWP = Convert.ToBoolean(CSResponse[4] & 0x04),
+ Reserved4 = (byte)(CSResponse[4] & 0x03),
+ Reserved5 = CSResponse[5],
+ Reserved6 = CSResponse[6],
+ Reserved7 = CSResponse[7]
+ };
- CartridgeStatus response = CSResponse.Value;
+ return decoded;
+ }
- var sb = new StringBuilder();
+ public static string Prettify(CartridgeStatus? CSResponse)
+ {
+ if(CSResponse == null)
+ return null;
+
+ CartridgeStatus response = CSResponse.Value;
+
+ var sb = new StringBuilder();
+
+ #if DEBUG
+ if(response.Reserved1 != 0)
+ sb.AppendFormat("Reserved1 = 0x{0:X2}", response.Reserved1).AppendLine();
+
+ if(response.Reserved2 != 0)
+ sb.AppendFormat("Reserved2 = 0x{0:X2}", response.Reserved2).AppendLine();
+
+ if(response.Reserved3 != 0)
+ sb.AppendFormat("Reserved3 = 0x{0:X8}", response.Reserved3).AppendLine();
+
+ if(response.Reserved4 != 0)
+ sb.AppendFormat("Reserved4 = 0x{0:X8}", response.Reserved4).AppendLine();
+
+ if(response.Reserved5 != 0)
+ sb.AppendFormat("Reserved5 = 0x{0:X8}", response.Reserved5).AppendLine();
+
+ if(response.Reserved6 != 0)
+ sb.AppendFormat("Reserved6 = 0x{0:X8}", response.Reserved6).AppendLine();
+
+ if(response.Reserved7 != 0)
+ sb.AppendFormat("Reserved7 = 0x{0:X8}", response.Reserved7).AppendLine();
+ #endif
+
+ if(response.Cartridge)
+ {
+ sb.AppendLine("Media is inserted in a cartridge");
+
+ if(response.OUT)
+ sb.AppendLine("Media has been taken out, or inserted in, the cartridge");
+
+ if(response.CWP)
+ sb.AppendLine("Media is write protected");
+ }
+ else
+ {
+ sb.AppendLine("Media is not in a cartridge");
#if DEBUG
- if(response.Reserved1 != 0)
- sb.AppendFormat("Reserved1 = 0x{0:X2}", response.Reserved1).AppendLine();
+ if(response.OUT)
+ sb.AppendLine("Media has out bit marked, shouldn't");
- if(response.Reserved2 != 0)
- sb.AppendFormat("Reserved2 = 0x{0:X2}", response.Reserved2).AppendLine();
-
- if(response.Reserved3 != 0)
- sb.AppendFormat("Reserved3 = 0x{0:X8}", response.Reserved3).AppendLine();
-
- if(response.Reserved4 != 0)
- sb.AppendFormat("Reserved4 = 0x{0:X8}", response.Reserved4).AppendLine();
-
- if(response.Reserved5 != 0)
- sb.AppendFormat("Reserved5 = 0x{0:X8}", response.Reserved5).AppendLine();
-
- if(response.Reserved6 != 0)
- sb.AppendFormat("Reserved6 = 0x{0:X8}", response.Reserved6).AppendLine();
-
- if(response.Reserved7 != 0)
- sb.AppendFormat("Reserved7 = 0x{0:X8}", response.Reserved7).AppendLine();
+ if(response.CWP)
+ sb.AppendLine("Media has write protection bit marked, shouldn't");
#endif
-
- if(response.Cartridge)
- {
- sb.AppendLine("Media is inserted in a cartridge");
-
- if(response.OUT)
- sb.AppendLine("Media has been taken out, or inserted in, the cartridge");
-
- if(response.CWP)
- sb.AppendLine("Media is write protected");
- }
- else
- {
- sb.AppendLine("Media is not in a cartridge");
-
- #if DEBUG
- if(response.OUT)
- sb.AppendLine("Media has out bit marked, shouldn't");
-
- if(response.CWP)
- sb.AppendLine("Media has write protection bit marked, shouldn't");
- #endif
- }
-
- return sb.ToString();
}
- public static string Prettify(byte[] CSResponse) => Prettify(Decode(CSResponse));
- #endregion Public methods
+ return sb.ToString();
}
+
+ public static string Prettify(byte[] CSResponse) => Prettify(Decode(CSResponse));
+ #endregion Public methods
}
\ No newline at end of file
diff --git a/Bluray/DDS.cs b/Bluray/DDS.cs
index a4edf77..e2c0cf4 100644
--- a/Bluray/DDS.cs
+++ b/Bluray/DDS.cs
@@ -36,194 +36,193 @@ using System.Text;
using Aaru.Console;
using Aaru.Helpers;
-namespace Aaru.Decoders.Bluray
+namespace Aaru.Decoders.Bluray;
+
+/// Information from the following standards:
+/// ANSI X3.304-1997
+/// T10/1048-D revision 9.0
+/// T10/1048-D revision 10a
+/// T10/1228-D revision 7.0c
+/// T10/1228-D revision 11a
+/// T10/1363-D revision 10g
+/// T10/1545-D revision 1d
+/// T10/1545-D revision 5
+/// T10/1545-D revision 5a
+/// T10/1675-D revision 2c
+/// T10/1675-D revision 4
+/// T10/1836-D revision 2g
+[SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"),
+ SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), SuppressMessage("ReSharper", "NotAccessedField.Global")]
+public static class DDS
{
- /// Information from the following standards:
- /// ANSI X3.304-1997
- /// T10/1048-D revision 9.0
- /// T10/1048-D revision 10a
- /// T10/1228-D revision 7.0c
- /// T10/1228-D revision 11a
- /// T10/1363-D revision 10g
- /// T10/1545-D revision 1d
- /// T10/1545-D revision 5
- /// T10/1545-D revision 5a
- /// T10/1675-D revision 2c
- /// T10/1675-D revision 4
- /// T10/1836-D revision 2g
- [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"),
- SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), SuppressMessage("ReSharper", "NotAccessedField.Global")]
- public static class DDS
+ #region Private constants
+ /// Disc Definition Structure Identifier "DS"
+ const ushort DDSIdentifier = 0x4453;
+ #endregion Private constants
+
+ #region Public structures
+ public struct DiscDefinitionStructure
{
- #region Private constants
- /// Disc Definition Structure Identifier "DS"
- const ushort DDSIdentifier = 0x4453;
- #endregion Private constants
-
- #region Public structures
- public struct DiscDefinitionStructure
- {
- /// Bytes 0 to 1 Data Length
- public ushort DataLength;
- /// Byte 2 Reserved
- public byte Reserved1;
- /// Byte 3 Reserved
- public byte Reserved2;
- /// Bytes 4 to 5 "DS"
- public ushort Signature;
- /// Byte 6 DDS format
- public byte Format;
- /// Byte 7 Reserved
- public byte Reserved3;
- /// Bytes 8 to 11 DDS update count
- public uint UpdateCount;
- /// Bytes 12 to 19 Reserved
- public ulong Reserved4;
- /// Bytes 20 to 23 First PSN of Drive Area
- public uint DriveAreaPSN;
- /// Bytes 24 to 27 Reserved
- public uint Reserved5;
- /// Bytes 28 to 31 First PSN of Defect List
- public uint DefectListPSN;
- /// Bytes 32 to 35 Reserved
- public uint Reserved6;
- /// Bytes 36 to 39 PSN of LSN 0 of user data area
- public uint PSNofLSNZero;
- /// Bytes 40 to 43 Last LSN of user data area
- public uint LastUserAreaLSN;
- /// Bytes 44 to 47 ISA0 size
- public uint ISA0;
- /// Bytes 48 to 51 OSA size
- public uint OSA;
- /// Bytes 52 to 55 ISA1 size
- public uint ISA1;
- /// Byte 56 Spare Area full flags
- public byte SpareAreaFullFlags;
- /// Byte 57 Reserved
- public byte Reserved7;
- /// Byte 58 Disc type specific field
- public byte DiscTypeSpecificField1;
- /// Byte 59 Reserved
- public byte Reserved8;
- /// Byte 60 to 63 Disc type specific field
- public uint DiscTypeSpecificField2;
- /// Byte 64 to 67 Reserved
- public uint Reserved9;
- /// Bytes 68 to 99 Status bits of INFO1/2 and PAC1/2 on L0 and L1
- public byte[] StatusBits;
- /// Bytes 100 to end Disc type specific data
- public byte[] DiscTypeSpecificData;
- }
- #endregion Public structures
-
- #region Public methods
- public static DiscDefinitionStructure? Decode(byte[] DDSResponse)
- {
- if(DDSResponse == null)
- return null;
-
- var decoded = new DiscDefinitionStructure
- {
- DataLength = BigEndianBitConverter.ToUInt16(DDSResponse, 0),
- Reserved1 = DDSResponse[2],
- Reserved2 = DDSResponse[3],
- Signature = BigEndianBitConverter.ToUInt16(DDSResponse, 4)
- };
-
- if(decoded.Signature != DDSIdentifier)
- {
- AaruConsole.DebugWriteLine("BD DDS decoder", "Found incorrect DDS signature (0x{0:X4})",
- decoded.Signature);
-
- return null;
- }
-
- decoded.Format = DDSResponse[6];
- decoded.Reserved3 = DDSResponse[7];
- decoded.UpdateCount = BigEndianBitConverter.ToUInt32(DDSResponse, 8);
- decoded.Reserved4 = BigEndianBitConverter.ToUInt64(DDSResponse, 12);
- decoded.DriveAreaPSN = BigEndianBitConverter.ToUInt32(DDSResponse, 20);
- decoded.Reserved5 = BigEndianBitConverter.ToUInt32(DDSResponse, 24);
- decoded.DefectListPSN = BigEndianBitConverter.ToUInt32(DDSResponse, 28);
- decoded.Reserved6 = BigEndianBitConverter.ToUInt32(DDSResponse, 32);
- decoded.PSNofLSNZero = BigEndianBitConverter.ToUInt32(DDSResponse, 36);
- decoded.LastUserAreaLSN = BigEndianBitConverter.ToUInt32(DDSResponse, 40);
- decoded.ISA0 = BigEndianBitConverter.ToUInt32(DDSResponse, 44);
- decoded.OSA = BigEndianBitConverter.ToUInt32(DDSResponse, 48);
- decoded.ISA1 = BigEndianBitConverter.ToUInt32(DDSResponse, 52);
- decoded.SpareAreaFullFlags = DDSResponse[56];
- decoded.Reserved7 = DDSResponse[57];
- decoded.DiscTypeSpecificField1 = DDSResponse[58];
- decoded.Reserved8 = DDSResponse[59];
- decoded.DiscTypeSpecificField2 = BigEndianBitConverter.ToUInt32(DDSResponse, 60);
- decoded.Reserved9 = BigEndianBitConverter.ToUInt32(DDSResponse, 64);
- decoded.StatusBits = new byte[32];
- Array.Copy(DDSResponse, 68, decoded.StatusBits, 0, 32);
- decoded.DiscTypeSpecificData = new byte[DDSResponse.Length - 100];
- Array.Copy(DDSResponse, 100, decoded.DiscTypeSpecificData, 0, DDSResponse.Length - 100);
-
- return decoded;
- }
-
- public static string Prettify(DiscDefinitionStructure? DDSResponse)
- {
- if(DDSResponse == null)
- return null;
-
- DiscDefinitionStructure response = DDSResponse.Value;
-
- var sb = new StringBuilder();
-
- sb.AppendFormat("DDS Format: 0x{0:X2}", response.Format).AppendLine();
- sb.AppendFormat("DDS has ben updated {0} times", response.UpdateCount).AppendLine();
- sb.AppendFormat("First PSN of Drive Area: 0x{0:X8}", response.DriveAreaPSN).AppendLine();
- sb.AppendFormat("First PSN of Defect List: 0x{0:X8}", response.DefectListPSN).AppendLine();
- sb.AppendFormat("PSN of User Data Area's LSN 0: 0x{0:X8}", response.PSNofLSNZero).AppendLine();
- sb.AppendFormat("Last User Data Area's LSN 0: 0x{0:X8}", response.LastUserAreaLSN).AppendLine();
- sb.AppendFormat("ISA0 size: {0}", response.ISA0).AppendLine();
- sb.AppendFormat("OSA size: {0}", response.OSA).AppendLine();
- sb.AppendFormat("ISA1 size: {0}", response.ISA1).AppendLine();
- sb.AppendFormat("Spare Area Full Flags: 0x{0:X2}", response.SpareAreaFullFlags).AppendLine();
- sb.AppendFormat("Disc Type Specific Field 1: 0x{0:X2}", response.DiscTypeSpecificField1).AppendLine();
- sb.AppendFormat("Disc Type Specific Field 2: 0x{0:X8}", response.DiscTypeSpecificField2).AppendLine();
- sb.AppendFormat("Blu-ray DDS Status Bits in hex follows:");
- sb.AppendLine(PrintHex.ByteArrayToHexArrayString(response.StatusBits, 80));
- sb.AppendFormat("Blu-ray DDS Disc Type Specific Data in hex follows:");
- sb.AppendLine(PrintHex.ByteArrayToHexArrayString(response.DiscTypeSpecificData, 80));
-
- #if DEBUG
- if(response.Reserved1 != 0)
- sb.AppendFormat("Reserved1 = 0x{0:X2}", response.Reserved1).AppendLine();
-
- if(response.Reserved2 != 0)
- sb.AppendFormat("Reserved2 = 0x{0:X2}", response.Reserved2).AppendLine();
-
- if(response.Reserved3 != 0)
- sb.AppendFormat("Reserved3 = 0x{0:X2}", response.Reserved3).AppendLine();
-
- if(response.Reserved4 != 0)
- sb.AppendFormat("Reserved4 = 0x{0:X16}", response.Reserved4).AppendLine();
-
- if(response.Reserved5 != 0)
- sb.AppendFormat("Reserved5 = 0x{0:X8}", response.Reserved5).AppendLine();
-
- if(response.Reserved6 != 0)
- sb.AppendFormat("Reserved6 = 0x{0:X8}", response.Reserved6).AppendLine();
-
- if(response.Reserved7 != 0)
- sb.AppendFormat("Reserved7 = 0x{0:X2}", response.Reserved7).AppendLine();
-
- if(response.Reserved8 != 0)
- sb.AppendFormat("Reserved8 = 0x{0:X2}", response.Reserved8).AppendLine();
-
- if(response.Reserved9 != 0)
- sb.AppendFormat("Reserved9 = 0x{0:X8}", response.Reserved9).AppendLine();
- #endif
-
- return sb.ToString();
- }
-
- public static string Prettify(byte[] DDSResponse) => Prettify(Decode(DDSResponse));
- #endregion Public methods
+ /// Bytes 0 to 1 Data Length
+ public ushort DataLength;
+ /// Byte 2 Reserved
+ public byte Reserved1;
+ /// Byte 3 Reserved
+ public byte Reserved2;
+ /// Bytes 4 to 5 "DS"
+ public ushort Signature;
+ /// Byte 6 DDS format
+ public byte Format;
+ /// Byte 7 Reserved
+ public byte Reserved3;
+ /// Bytes 8 to 11 DDS update count
+ public uint UpdateCount;
+ /// Bytes 12 to 19 Reserved
+ public ulong Reserved4;
+ /// Bytes 20 to 23 First PSN of Drive Area
+ public uint DriveAreaPSN;
+ /// Bytes 24 to 27 Reserved
+ public uint Reserved5;
+ /// Bytes 28 to 31 First PSN of Defect List
+ public uint DefectListPSN;
+ /// Bytes 32 to 35 Reserved
+ public uint Reserved6;
+ /// Bytes 36 to 39 PSN of LSN 0 of user data area
+ public uint PSNofLSNZero;
+ /// Bytes 40 to 43 Last LSN of user data area
+ public uint LastUserAreaLSN;
+ /// Bytes 44 to 47 ISA0 size
+ public uint ISA0;
+ /// Bytes 48 to 51 OSA size
+ public uint OSA;
+ /// Bytes 52 to 55 ISA1 size
+ public uint ISA1;
+ /// Byte 56 Spare Area full flags
+ public byte SpareAreaFullFlags;
+ /// Byte 57 Reserved
+ public byte Reserved7;
+ /// Byte 58 Disc type specific field
+ public byte DiscTypeSpecificField1;
+ /// Byte 59 Reserved
+ public byte Reserved8;
+ /// Byte 60 to 63 Disc type specific field
+ public uint DiscTypeSpecificField2;
+ /// Byte 64 to 67 Reserved
+ public uint Reserved9;
+ /// Bytes 68 to 99 Status bits of INFO1/2 and PAC1/2 on L0 and L1
+ public byte[] StatusBits;
+ /// Bytes 100 to end Disc type specific data
+ public byte[] DiscTypeSpecificData;
}
+ #endregion Public structures
+
+ #region Public methods
+ public static DiscDefinitionStructure? Decode(byte[] DDSResponse)
+ {
+ if(DDSResponse == null)
+ return null;
+
+ var decoded = new DiscDefinitionStructure
+ {
+ DataLength = BigEndianBitConverter.ToUInt16(DDSResponse, 0),
+ Reserved1 = DDSResponse[2],
+ Reserved2 = DDSResponse[3],
+ Signature = BigEndianBitConverter.ToUInt16(DDSResponse, 4)
+ };
+
+ if(decoded.Signature != DDSIdentifier)
+ {
+ AaruConsole.DebugWriteLine("BD DDS decoder", "Found incorrect DDS signature (0x{0:X4})",
+ decoded.Signature);
+
+ return null;
+ }
+
+ decoded.Format = DDSResponse[6];
+ decoded.Reserved3 = DDSResponse[7];
+ decoded.UpdateCount = BigEndianBitConverter.ToUInt32(DDSResponse, 8);
+ decoded.Reserved4 = BigEndianBitConverter.ToUInt64(DDSResponse, 12);
+ decoded.DriveAreaPSN = BigEndianBitConverter.ToUInt32(DDSResponse, 20);
+ decoded.Reserved5 = BigEndianBitConverter.ToUInt32(DDSResponse, 24);
+ decoded.DefectListPSN = BigEndianBitConverter.ToUInt32(DDSResponse, 28);
+ decoded.Reserved6 = BigEndianBitConverter.ToUInt32(DDSResponse, 32);
+ decoded.PSNofLSNZero = BigEndianBitConverter.ToUInt32(DDSResponse, 36);
+ decoded.LastUserAreaLSN = BigEndianBitConverter.ToUInt32(DDSResponse, 40);
+ decoded.ISA0 = BigEndianBitConverter.ToUInt32(DDSResponse, 44);
+ decoded.OSA = BigEndianBitConverter.ToUInt32(DDSResponse, 48);
+ decoded.ISA1 = BigEndianBitConverter.ToUInt32(DDSResponse, 52);
+ decoded.SpareAreaFullFlags = DDSResponse[56];
+ decoded.Reserved7 = DDSResponse[57];
+ decoded.DiscTypeSpecificField1 = DDSResponse[58];
+ decoded.Reserved8 = DDSResponse[59];
+ decoded.DiscTypeSpecificField2 = BigEndianBitConverter.ToUInt32(DDSResponse, 60);
+ decoded.Reserved9 = BigEndianBitConverter.ToUInt32(DDSResponse, 64);
+ decoded.StatusBits = new byte[32];
+ Array.Copy(DDSResponse, 68, decoded.StatusBits, 0, 32);
+ decoded.DiscTypeSpecificData = new byte[DDSResponse.Length - 100];
+ Array.Copy(DDSResponse, 100, decoded.DiscTypeSpecificData, 0, DDSResponse.Length - 100);
+
+ return decoded;
+ }
+
+ public static string Prettify(DiscDefinitionStructure? DDSResponse)
+ {
+ if(DDSResponse == null)
+ return null;
+
+ DiscDefinitionStructure response = DDSResponse.Value;
+
+ var sb = new StringBuilder();
+
+ sb.AppendFormat("DDS Format: 0x{0:X2}", response.Format).AppendLine();
+ sb.AppendFormat("DDS has ben updated {0} times", response.UpdateCount).AppendLine();
+ sb.AppendFormat("First PSN of Drive Area: 0x{0:X8}", response.DriveAreaPSN).AppendLine();
+ sb.AppendFormat("First PSN of Defect List: 0x{0:X8}", response.DefectListPSN).AppendLine();
+ sb.AppendFormat("PSN of User Data Area's LSN 0: 0x{0:X8}", response.PSNofLSNZero).AppendLine();
+ sb.AppendFormat("Last User Data Area's LSN 0: 0x{0:X8}", response.LastUserAreaLSN).AppendLine();
+ sb.AppendFormat("ISA0 size: {0}", response.ISA0).AppendLine();
+ sb.AppendFormat("OSA size: {0}", response.OSA).AppendLine();
+ sb.AppendFormat("ISA1 size: {0}", response.ISA1).AppendLine();
+ sb.AppendFormat("Spare Area Full Flags: 0x{0:X2}", response.SpareAreaFullFlags).AppendLine();
+ sb.AppendFormat("Disc Type Specific Field 1: 0x{0:X2}", response.DiscTypeSpecificField1).AppendLine();
+ sb.AppendFormat("Disc Type Specific Field 2: 0x{0:X8}", response.DiscTypeSpecificField2).AppendLine();
+ sb.AppendFormat("Blu-ray DDS Status Bits in hex follows:");
+ sb.AppendLine(PrintHex.ByteArrayToHexArrayString(response.StatusBits, 80));
+ sb.AppendFormat("Blu-ray DDS Disc Type Specific Data in hex follows:");
+ sb.AppendLine(PrintHex.ByteArrayToHexArrayString(response.DiscTypeSpecificData, 80));
+
+ #if DEBUG
+ if(response.Reserved1 != 0)
+ sb.AppendFormat("Reserved1 = 0x{0:X2}", response.Reserved1).AppendLine();
+
+ if(response.Reserved2 != 0)
+ sb.AppendFormat("Reserved2 = 0x{0:X2}", response.Reserved2).AppendLine();
+
+ if(response.Reserved3 != 0)
+ sb.AppendFormat("Reserved3 = 0x{0:X2}", response.Reserved3).AppendLine();
+
+ if(response.Reserved4 != 0)
+ sb.AppendFormat("Reserved4 = 0x{0:X16}", response.Reserved4).AppendLine();
+
+ if(response.Reserved5 != 0)
+ sb.AppendFormat("Reserved5 = 0x{0:X8}", response.Reserved5).AppendLine();
+
+ if(response.Reserved6 != 0)
+ sb.AppendFormat("Reserved6 = 0x{0:X8}", response.Reserved6).AppendLine();
+
+ if(response.Reserved7 != 0)
+ sb.AppendFormat("Reserved7 = 0x{0:X2}", response.Reserved7).AppendLine();
+
+ if(response.Reserved8 != 0)
+ sb.AppendFormat("Reserved8 = 0x{0:X2}", response.Reserved8).AppendLine();
+
+ if(response.Reserved9 != 0)
+ sb.AppendFormat("Reserved9 = 0x{0:X8}", response.Reserved9).AppendLine();
+ #endif
+
+ return sb.ToString();
+ }
+
+ public static string Prettify(byte[] DDSResponse) => Prettify(Decode(DDSResponse));
+ #endregion Public methods
}
\ No newline at end of file
diff --git a/Bluray/DI.cs b/Bluray/DI.cs
index dcfb593..7e7c909 100644
--- a/Bluray/DI.cs
+++ b/Bluray/DI.cs
@@ -37,544 +37,543 @@ using System.Text;
using Aaru.Console;
using Aaru.Helpers;
-namespace Aaru.Decoders.Bluray
+namespace Aaru.Decoders.Bluray;
+
+// Information from the following standards:
+// ANSI X3.304-1997
+// T10/1048-D revision 9.0
+// T10/1048-D revision 10a
+// T10/1228-D revision 7.0c
+// T10/1228-D revision 11a
+// T10/1363-D revision 10g
+// T10/1545-D revision 1d
+// T10/1545-D revision 5
+// T10/1545-D revision 5a
+// T10/1675-D revision 2c
+// T10/1675-D revision 4
+// T10/1836-D revision 2g
+[SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"),
+ SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), SuppressMessage("ReSharper", "NotAccessedField.Global")]
+public static class DI
{
- // Information from the following standards:
- // ANSI X3.304-1997
- // T10/1048-D revision 9.0
- // T10/1048-D revision 10a
- // T10/1228-D revision 7.0c
- // T10/1228-D revision 11a
- // T10/1363-D revision 10g
- // T10/1545-D revision 1d
- // T10/1545-D revision 5
- // T10/1545-D revision 5a
- // T10/1675-D revision 2c
- // T10/1675-D revision 4
- // T10/1836-D revision 2g
- [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"),
- SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), SuppressMessage("ReSharper", "NotAccessedField.Global")]
- public static class DI
+ public enum BluSize : byte
{
- public enum BluSize : byte
+ /// 120mm
+ OneTwenty = 0,
+ /// 80mm
+ Eighty = 1
+ }
+
+ public enum ChannelLength : byte
+ {
+ /// 74.5nm channel or 25Gb/layer
+ Seventy = 1,
+ /// 69.0nm channel or 27Gb/layer
+ Sixty = 2
+ }
+
+ public enum HybridLayer : byte
+ {
+ /// No hybrid layer
+ None = 0,
+ /// -ROM layer
+ ReadOnly = 1,
+ /// -R layer
+ Recordable = 2,
+ /// -RW layer
+ Rewritable = 3
+ }
+
+ #region Private constants
+ const string DiscTypeBDROM = "BDO";
+ const string DiscTypeBDRE = "BDW";
+ const string DiscTypeBDR = "BDR";
+
+ /// Disc Information Unit Identifier "DI"
+ const ushort DIUIdentifier = 0x4449;
+ #endregion Private constants
+
+ #region Public methods
+ public static DiscInformation? Decode(byte[] DIResponse)
+ {
+ if(DIResponse == null)
+ return null;
+
+ if(DIResponse.Length != 4100)
{
- /// 120mm
- OneTwenty = 0,
- /// 80mm
- Eighty = 1
+ AaruConsole.DebugWriteLine("BD Disc Information decoder",
+ "Found incorrect Blu-ray Disc Information size ({0} bytes)",
+ DIResponse.Length);
+
+ return null;
}
- public enum ChannelLength : byte
+ var decoded = new DiscInformation
{
- /// 74.5nm channel or 25Gb/layer
- Seventy = 1,
- /// 69.0nm channel or 27Gb/layer
- Sixty = 2
- }
+ DataLength = BigEndianBitConverter.ToUInt16(DIResponse, 0),
+ Reserved1 = DIResponse[2],
+ Reserved2 = DIResponse[3]
+ };
- public enum HybridLayer : byte
+ int offset = 4;
+ List units = new List();
+
+ while(true)
{
- /// No hybrid layer
- None = 0,
- /// -ROM layer
- ReadOnly = 1,
- /// -R layer
- Recordable = 2,
- /// -RW layer
- Rewritable = 3
- }
+ if(offset >= 4100)
+ break;
- #region Private constants
- const string DiscTypeBDROM = "BDO";
- const string DiscTypeBDRE = "BDW";
- const string DiscTypeBDR = "BDR";
-
- /// Disc Information Unit Identifier "DI"
- const ushort DIUIdentifier = 0x4449;
- #endregion Private constants
-
- #region Public methods
- public static DiscInformation? Decode(byte[] DIResponse)
- {
- if(DIResponse == null)
- return null;
-
- if(DIResponse.Length != 4100)
+ var unit = new DiscInformationUnits
{
- AaruConsole.DebugWriteLine("BD Disc Information decoder",
- "Found incorrect Blu-ray Disc Information size ({0} bytes)",
- DIResponse.Length);
-
- return null;
- }
-
- var decoded = new DiscInformation
- {
- DataLength = BigEndianBitConverter.ToUInt16(DIResponse, 0),
- Reserved1 = DIResponse[2],
- Reserved2 = DIResponse[3]
+ Signature = BigEndianBitConverter.ToUInt16(DIResponse, 0 + offset)
};
- int offset = 4;
- List units = new List();
+ if(unit.Signature != DIUIdentifier)
+ break;
- while(true)
+ unit.Format = DIResponse[2 + offset];
+ unit.UnitsPerBlock = (byte)((DIResponse[3 + offset] & 0xF8) >> 3);
+ unit.Layer = (byte)(DIResponse[3 + offset] & 0x07);
+ unit.Legacy = DIResponse[4 + offset];
+ unit.Sequence = DIResponse[5 + offset];
+ unit.Continuation = (DIResponse[6 + offset] & 0x80) == 0x80;
+ unit.Length = (byte)(DIResponse[6 + offset] & 0x7F);
+ unit.Reserved = DIResponse[7 + offset];
+ unit.DiscTypeIdentifier = new byte[3];
+ Array.Copy(DIResponse, 8 + offset, unit.DiscTypeIdentifier, 0, 3);
+ unit.DiscSize = (BluSize)((DIResponse[11 + offset] & 0xC0) >> 6);
+ unit.DiscClass = (byte)((DIResponse[11 + offset] & 0x30) >> 4);
+ unit.DiscVersion = (byte)(DIResponse[11 + offset] & 0x0F);
+ unit.Layers = (byte)((DIResponse[12 + offset] & 0xF0) >> 4);
+ unit.DvdLayer = (HybridLayer)((DIResponse[13 + offset] & 0xC0) >> 6);
+ unit.CdLayer = (HybridLayer)((DIResponse[13 + offset] & 0x30) >> 4);
+ unit.ChannelLength = (ChannelLength)(DIResponse[13 + offset] & 0x0F);
+ unit.Polarity = DIResponse[14 + offset];
+ unit.RecordedPolarity = DIResponse[14 + offset];
+ unit.Bca = (byte)(DIResponse[16 + offset] & 0x0F);
+ unit.MaxTransfer = DIResponse[17 + offset];
+
+ unit.LastPsn = (uint)((DIResponse[20 + offset] << 24) + (DIResponse[21 + offset] << 16) +
+ (DIResponse[22 + offset] << 8) + DIResponse[23 + offset]);
+
+ // TODO: In -R/-RE how does this relate to layer size???
+ unit.FirstAun = (uint)((DIResponse[24 + offset] << 24) + (DIResponse[25 + offset] << 16) +
+ (DIResponse[26 + offset] << 8) + DIResponse[27 + offset]);
+
+ unit.LastAun = (uint)((DIResponse[28 + offset] << 24) + (DIResponse[29 + offset] << 16) +
+ (DIResponse[30 + offset] << 8) + DIResponse[31 + offset]);
+
+ switch(Encoding.ASCII.GetString(unit.DiscTypeIdentifier))
{
- if(offset >= 4100)
- break;
-
- var unit = new DiscInformationUnits
+ case DiscTypeBDROM:
{
- Signature = BigEndianBitConverter.ToUInt16(DIResponse, 0 + offset)
- };
+ unit.FormatDependentContents = new byte[32];
+ Array.Copy(DIResponse, 32 + offset, unit.FormatDependentContents, 0, 32);
- if(unit.Signature != DIUIdentifier)
break;
-
- unit.Format = DIResponse[2 + offset];
- unit.UnitsPerBlock = (byte)((DIResponse[3 + offset] & 0xF8) >> 3);
- unit.Layer = (byte)(DIResponse[3 + offset] & 0x07);
- unit.Legacy = DIResponse[4 + offset];
- unit.Sequence = DIResponse[5 + offset];
- unit.Continuation = (DIResponse[6 + offset] & 0x80) == 0x80;
- unit.Length = (byte)(DIResponse[6 + offset] & 0x7F);
- unit.Reserved = DIResponse[7 + offset];
- unit.DiscTypeIdentifier = new byte[3];
- Array.Copy(DIResponse, 8 + offset, unit.DiscTypeIdentifier, 0, 3);
- unit.DiscSize = (BluSize)((DIResponse[11 + offset] & 0xC0) >> 6);
- unit.DiscClass = (byte)((DIResponse[11 + offset] & 0x30) >> 4);
- unit.DiscVersion = (byte)(DIResponse[11 + offset] & 0x0F);
- unit.Layers = (byte)((DIResponse[12 + offset] & 0xF0) >> 4);
- unit.DvdLayer = (HybridLayer)((DIResponse[13 + offset] & 0xC0) >> 6);
- unit.CdLayer = (HybridLayer)((DIResponse[13 + offset] & 0x30) >> 4);
- unit.ChannelLength = (ChannelLength)(DIResponse[13 + offset] & 0x0F);
- unit.Polarity = DIResponse[14 + offset];
- unit.RecordedPolarity = DIResponse[14 + offset];
- unit.Bca = (byte)(DIResponse[16 + offset] & 0x0F);
- unit.MaxTransfer = DIResponse[17 + offset];
-
- unit.LastPsn = (uint)((DIResponse[20 + offset] << 24) + (DIResponse[21 + offset] << 16) +
- (DIResponse[22 + offset] << 8) + DIResponse[23 + offset]);
-
- // TODO: In -R/-RE how does this relate to layer size???
- unit.FirstAun = (uint)((DIResponse[24 + offset] << 24) + (DIResponse[25 + offset] << 16) +
- (DIResponse[26 + offset] << 8) + DIResponse[27 + offset]);
-
- unit.LastAun = (uint)((DIResponse[28 + offset] << 24) + (DIResponse[29 + offset] << 16) +
- (DIResponse[30 + offset] << 8) + DIResponse[31 + offset]);
-
- switch(Encoding.ASCII.GetString(unit.DiscTypeIdentifier))
- {
- case DiscTypeBDROM:
- {
- unit.FormatDependentContents = new byte[32];
- Array.Copy(DIResponse, 32 + offset, unit.FormatDependentContents, 0, 32);
-
- break;
- }
-
- case DiscTypeBDRE:
- case DiscTypeBDR:
- {
- unit.FormatDependentContents = new byte[66];
- Array.Copy(DIResponse, 32 + offset, unit.FormatDependentContents, 0, 66);
- unit.ManufacturerID = new byte[6];
- Array.Copy(DIResponse, 100 + offset, unit.ManufacturerID, 0, 6);
- unit.MediaTypeID = new byte[3];
- Array.Copy(DIResponse, 106 + offset, unit.MediaTypeID, 0, 3);
- unit.TimeStamp = BigEndianBitConverter.ToUInt16(DIResponse, 109 + offset);
- unit.ProductRevisionNumber = DIResponse[111 + offset];
-
- offset += 14;
-
- break;
- }
-
- default:
- {
- AaruConsole.DebugWriteLine("BD Disc Information decoder",
- "Found unknown disc type identifier \"{0}\"",
- Encoding.ASCII.GetString(unit.DiscTypeIdentifier));
-
- break;
- }
}
- units.Add(unit);
+ case DiscTypeBDRE:
+ case DiscTypeBDR:
+ {
+ unit.FormatDependentContents = new byte[66];
+ Array.Copy(DIResponse, 32 + offset, unit.FormatDependentContents, 0, 66);
+ unit.ManufacturerID = new byte[6];
+ Array.Copy(DIResponse, 100 + offset, unit.ManufacturerID, 0, 6);
+ unit.MediaTypeID = new byte[3];
+ Array.Copy(DIResponse, 106 + offset, unit.MediaTypeID, 0, 3);
+ unit.TimeStamp = BigEndianBitConverter.ToUInt16(DIResponse, 109 + offset);
+ unit.ProductRevisionNumber = DIResponse[111 + offset];
- offset += unit.Length;
+ offset += 14;
+
+ break;
+ }
+
+ default:
+ {
+ AaruConsole.DebugWriteLine("BD Disc Information decoder",
+ "Found unknown disc type identifier \"{0}\"",
+ Encoding.ASCII.GetString(unit.DiscTypeIdentifier));
+
+ break;
+ }
}
- if(units.Count <= 0)
- return decoded;
+ units.Add(unit);
- decoded.Units = new DiscInformationUnits[units.Count];
-
- for(int i = 0; i < units.Count; i++)
- decoded.Units[i] = units[i];
+ offset += unit.Length;
+ }
+ if(units.Count <= 0)
return decoded;
- }
- public static string Prettify(DiscInformation? DIResponse)
- {
- if(DIResponse == null)
- return null;
+ decoded.Units = new DiscInformationUnits[units.Count];
- DiscInformation response = DIResponse.Value;
+ for(int i = 0; i < units.Count; i++)
+ decoded.Units[i] = units[i];
- var sb = new StringBuilder();
-
- foreach(DiscInformationUnits unit in response.Units)
- {
- sb.AppendFormat("DI Unit Sequence: {0}", unit.Sequence).AppendLine();
- sb.AppendFormat("DI Unit Format: 0x{0:X2}", unit.Format).AppendLine();
- sb.AppendFormat("There are {0} per block", unit.UnitsPerBlock).AppendLine();
- sb.AppendFormat("This DI refers to layer {0}", unit.Layer).AppendLine();
-
- if(Encoding.ASCII.GetString(unit.DiscTypeIdentifier) == DiscTypeBDRE)
- sb.AppendFormat("Legacy value: 0x{0:X2}", unit.Legacy).AppendLine();
-
- sb.AppendLine(unit.Continuation ? "This DI continues previous unit" : "This DI starts a new unit");
- sb.AppendFormat("DI Unit is {0} bytes", unit.Length).AppendLine();
-
- sb.AppendFormat("Disc type identifier: \"{0}\"", Encoding.ASCII.GetString(unit.DiscTypeIdentifier)).
- AppendLine();
-
- switch(unit.DiscSize)
- {
- case BluSize.OneTwenty:
- sb.AppendLine("Disc size: 120mm");
-
- break;
- case BluSize.Eighty:
- sb.AppendLine("Disc size: 80mm");
-
- break;
- default:
- sb.AppendFormat("Disc size: Unknown code {0}", (byte)unit.DiscSize).AppendLine();
-
- break;
- }
-
- sb.AppendFormat("Disc class: {0}", unit.DiscClass).AppendLine();
- sb.AppendFormat("Disc version: {0}", unit.DiscVersion).AppendLine();
- sb.AppendFormat("This disc has {0} layers", unit.Layers).AppendLine();
-
- switch(unit.DvdLayer)
- {
- case HybridLayer.None:
- sb.AppendLine("This disc does not contain a DVD layer.");
-
- break;
- case HybridLayer.ReadOnly:
- sb.AppendLine("This disc contains a DVD-ROM layer.");
-
- break;
- case HybridLayer.Recordable:
- sb.AppendLine("This disc contains a DVD-R layer.");
-
- break;
- case HybridLayer.Rewritable:
- sb.AppendLine("This disc contains a DVD-RW layer.");
-
- break;
- }
-
- switch(unit.CdLayer)
- {
- case HybridLayer.None:
- sb.AppendLine("This disc does not contain a CD layer.");
-
- break;
- case HybridLayer.ReadOnly:
- sb.AppendLine("This disc contains a CD-ROM layer.");
-
- break;
- case HybridLayer.Recordable:
- sb.AppendLine("This disc contains a CD-R layer.");
-
- break;
- case HybridLayer.Rewritable:
- sb.AppendLine("This disc contains a CD-RW layer.");
-
- break;
- }
-
- switch(unit.ChannelLength)
- {
- case ChannelLength.Seventy:
- sb.AppendLine("Disc uses a 74.5nm channel giving 25 Gb per layer.");
-
- break;
- case ChannelLength.Sixty:
- sb.AppendLine("Disc uses a 69.0nm channel giving 27 Gb per layer.");
-
- break;
- default:
- sb.AppendFormat("Disc uses unknown channel length with code {0}", (byte)unit.ChannelLength).
- AppendLine();
-
- break;
- }
-
- switch(unit.Polarity)
- {
- case 0:
- sb.AppendLine("Disc uses positive polarity.");
-
- break;
- case 1:
- sb.AppendLine("Disc uses negative polarity.");
-
- break;
- default:
- sb.AppendFormat("Disc uses unknown polarity with code {0}", unit.Polarity).AppendLine();
-
- break;
- }
-
- if(Encoding.ASCII.GetString(unit.DiscTypeIdentifier) == DiscTypeBDR)
- switch(unit.RecordedPolarity)
- {
- case 0:
- sb.AppendLine("Recorded marks have a lower reflectivity than unrecorded ones (HTL disc).");
-
- break;
- case 1:
- sb.AppendLine("Recorded marks have a higher reflectivity than unrecorded ones (LTH disc).");
-
- break;
- default:
- sb.AppendFormat("Disc uses unknown recorded reflectivity polarity with code {0}",
- unit.RecordedPolarity).AppendLine();
-
- break;
- }
-
- switch(unit.Bca)
- {
- case 0:
- sb.AppendLine("Disc doesn't have a BCA.");
-
- break;
- case 1:
- sb.AppendLine("Disc has a BCA.");
-
- break;
- default:
- sb.AppendFormat("Disc uses unknown BCA code {0}", unit.Bca).AppendLine();
-
- break;
- }
-
- if(unit.MaxTransfer > 0)
- sb.AppendFormat("Disc has a maximum transfer rate of {0} Mbit/sec.", unit.MaxTransfer).AppendLine();
- else
- sb.AppendLine("Disc does not specify a maximum transfer rate.");
-
- sb.AppendFormat("Last user data PSN for disc: {0}", unit.LastPsn).AppendLine();
-
- sb.AppendFormat("First address unit number of data zone in this layer: {0}", unit.FirstAun).
- AppendLine();
-
- sb.AppendFormat("Last address unit number of data zone in this layer: {0}", unit.LastAun).AppendLine();
-
- if(Encoding.ASCII.GetString(unit.DiscTypeIdentifier) == DiscTypeBDR ||
- Encoding.ASCII.GetString(unit.DiscTypeIdentifier) == DiscTypeBDRE)
- {
- sb.AppendFormat("Disc manufacturer ID: \"{0}\"", Encoding.ASCII.GetString(unit.ManufacturerID)).
- AppendLine();
-
- sb.AppendFormat("Disc media type ID: \"{0}\"", Encoding.ASCII.GetString(unit.MediaTypeID)).
- AppendLine();
-
- sb.AppendFormat("Disc timestamp: 0x{0:X2}", unit.TimeStamp).AppendLine();
- sb.AppendFormat("Disc product revison number: {0}", unit.ProductRevisionNumber).AppendLine();
- }
-
- sb.AppendFormat("Blu-ray DI Unit format dependent contents as hex follows:");
- sb.AppendLine(PrintHex.ByteArrayToHexArrayString(unit.FormatDependentContents, 80));
- }
-
- return sb.ToString();
- }
-
- public static string Prettify(byte[] DIResponse) => Prettify(Decode(DIResponse));
-
- public static string ManufacturerFromDI(string manufacturerId)
- {
- string manufacturer = "";
-
- switch(manufacturerId)
- {
- case "AMESOB":
- case "OTCBDR":
- manufacturer = "Amethystum Storage Technology Co., Ltd.";
-
- break;
- case "UMEBDR":
- case "ANWELL":
- manufacturer = "Avic Umedisc HK Ltd.";
-
- break;
- case "MAXELL":
- manufacturer = "Hitachi Maxell, Ltd.";
-
- break;
- case "CMCMAG":
- manufacturer = "CMC Magnetics Corporation";
-
- break;
- case "ISMMBD":
- manufacturer = "Info Source Digital Media (Zhong Shan) Co., Ltd.";
-
- break;
- case "LGEBRA":
- manufacturer = "LG Electronics Inc.";
-
- break;
- case "MILLEN":
- manufacturer = "Millenniata, Inc.";
-
- break;
- case "VERBAT":
- case "VAMKM":
- manufacturer = "Mitsubishi Chemical Media Co., Ltd.";
-
- break;
- case "PHILIP":
- case "MBI":
- manufacturer = "Moser Baer India Ltd.";
-
- break;
- case "MEI":
- case "PAN":
- manufacturer = "Matsushita Electric Industrial Co., Ltd.";
-
- break;
- case "PRODIS":
- manufacturer = "Prodisc Technology Inc.";
-
- break;
- case "RITEK":
- manufacturer = "Ritek Co.";
-
- break;
- case "SONY":
- manufacturer = "Sony Corporation";
-
- break;
- case "TYG-BD":
- manufacturer = "Taiyo Yuden Company Ltd.";
-
- break;
- case "TDKBLD":
- manufacturer = "TDK Corporation";
-
- break;
- case "JVC-AM":
- case "JVCVAM":
- manufacturer = "Victor Advanced media Co., Ltd.";
-
- break;
- case "JVCRE1":
- manufacturer = "JVC KENWOOD Corporation";
-
- break;
- case "INFOME":
- manufacturer = "InfoMedia Inc.";
-
- break;
- }
-
- return manufacturer != "" ? $"{manufacturer} (\"{manufacturerId}\")" : $"\"{manufacturerId}\"";
- }
- #endregion Public methods
-
- #region Public structures
- public struct DiscInformation
- {
- /// Bytes 0 to 1 Always 4098
- public ushort DataLength;
- /// Byte 2 Reserved
- public byte Reserved1;
- /// Byte 3 Reserved
- public byte Reserved2;
- /// Byte 4 to 4099 Disc information units
- public DiscInformationUnits[] Units;
- }
-
- public struct DiscInformationUnits
- {
- /// Byte 0 "DI"
- public ushort Signature;
- /// Byte 2 Disc information format
- public byte Format;
- /// Byte 3, bits 7 to 3 Number of DI units per block
- public byte UnitsPerBlock;
- /// Byte 3, bits 2 to 0 Layer this DI refers to
- public byte Layer;
- /// Byte 4 Reserved for BD-ROM, legacy information for BD-R/-RE
- public byte Legacy;
- /// Byte 5 Sequence number for this DI unit
- public byte Sequence;
- /// Byte 6, bit 7 If set this DI is a continuation of the previous one
- public bool Continuation;
- /// Byte 6, bits 6 to 0 Number of bytes used by this DI unit, should be 64 for BD-ROM and 112 for BD-R/-RE
- public byte Length;
- /// Byte 7 Reserved
- public byte Reserved;
- /// Bytes 8 to 10 Disc type identifier
- public byte[] DiscTypeIdentifier;
- /// Byte 11, bits 7 to 6 Disc size
- public BluSize DiscSize;
- /// Byte 11, bits 5 to 4 Disc class
- public byte DiscClass;
- /// Byte 11, bits 3 to 0 Disc version
- public byte DiscVersion;
- /// Byte 12, bits 7 to 4 Layers in this disc
- public byte Layers;
- /// Byte 12, bits 3 to 0 Reserved
- public byte Reserved2;
- /// Byte 13, bits 7 to 6 DVD layer
- public HybridLayer DvdLayer;
- /// Byte 13, bits 5 to 4 CD layer
- public HybridLayer CdLayer;
- /// Byte 13, bits 3 to 0 Channel length
- public ChannelLength ChannelLength;
- /// Byte 14 Polarity
- public byte Polarity;
- /// Byte 15 Recorded polarity
- public byte RecordedPolarity;
- /// Byte 16, bits 7 to 4 Reserved
- public byte Reserved3;
- /// Byte 16, bits 3 to 0 If 0 no BCA, if 1 BCA, rest not defined
- public byte Bca;
- /// Byte 17 Maximum transfer speed in megabits/second, 0 if no maximum
- public byte MaxTransfer;
- /// Bytes 18 to 19 Reserved
- public ushort Reserved4;
- /// Bytes 20 to 23 Last user data PSN for disc
- public uint LastPsn;
- /// Bytes 24 to 27 First address unit number of data zone in this layer
- public uint FirstAun;
- /// Bytes 28 to 31 Last address unit number of data zone in this layer
- public uint LastAun;
- ///
- /// Bytes 32 to 63 for BD-ROM, bytes 32 to 99 for BD-R/-RE Format dependent contents, disclosed in private blu-ray
- /// specifications
- ///
- public byte[] FormatDependentContents;
- /// Bytes 100 to 105, BD-R/-RE only Manufacturer ID
- public byte[] ManufacturerID;
- /// Bytes 106 to 108, BD-R/-RE only Media type ID
- public byte[] MediaTypeID;
- /// Bytes 109 to 110, BD-R/-RE only Timestamp
- public ushort TimeStamp;
- /// Byte 111 Product revision number
- public byte ProductRevisionNumber;
- }
- #endregion Public structures
+ return decoded;
}
+
+ public static string Prettify(DiscInformation? DIResponse)
+ {
+ if(DIResponse == null)
+ return null;
+
+ DiscInformation response = DIResponse.Value;
+
+ var sb = new StringBuilder();
+
+ foreach(DiscInformationUnits unit in response.Units)
+ {
+ sb.AppendFormat("DI Unit Sequence: {0}", unit.Sequence).AppendLine();
+ sb.AppendFormat("DI Unit Format: 0x{0:X2}", unit.Format).AppendLine();
+ sb.AppendFormat("There are {0} per block", unit.UnitsPerBlock).AppendLine();
+ sb.AppendFormat("This DI refers to layer {0}", unit.Layer).AppendLine();
+
+ if(Encoding.ASCII.GetString(unit.DiscTypeIdentifier) == DiscTypeBDRE)
+ sb.AppendFormat("Legacy value: 0x{0:X2}", unit.Legacy).AppendLine();
+
+ sb.AppendLine(unit.Continuation ? "This DI continues previous unit" : "This DI starts a new unit");
+ sb.AppendFormat("DI Unit is {0} bytes", unit.Length).AppendLine();
+
+ sb.AppendFormat("Disc type identifier: \"{0}\"", Encoding.ASCII.GetString(unit.DiscTypeIdentifier)).
+ AppendLine();
+
+ switch(unit.DiscSize)
+ {
+ case BluSize.OneTwenty:
+ sb.AppendLine("Disc size: 120mm");
+
+ break;
+ case BluSize.Eighty:
+ sb.AppendLine("Disc size: 80mm");
+
+ break;
+ default:
+ sb.AppendFormat("Disc size: Unknown code {0}", (byte)unit.DiscSize).AppendLine();
+
+ break;
+ }
+
+ sb.AppendFormat("Disc class: {0}", unit.DiscClass).AppendLine();
+ sb.AppendFormat("Disc version: {0}", unit.DiscVersion).AppendLine();
+ sb.AppendFormat("This disc has {0} layers", unit.Layers).AppendLine();
+
+ switch(unit.DvdLayer)
+ {
+ case HybridLayer.None:
+ sb.AppendLine("This disc does not contain a DVD layer.");
+
+ break;
+ case HybridLayer.ReadOnly:
+ sb.AppendLine("This disc contains a DVD-ROM layer.");
+
+ break;
+ case HybridLayer.Recordable:
+ sb.AppendLine("This disc contains a DVD-R layer.");
+
+ break;
+ case HybridLayer.Rewritable:
+ sb.AppendLine("This disc contains a DVD-RW layer.");
+
+ break;
+ }
+
+ switch(unit.CdLayer)
+ {
+ case HybridLayer.None:
+ sb.AppendLine("This disc does not contain a CD layer.");
+
+ break;
+ case HybridLayer.ReadOnly:
+ sb.AppendLine("This disc contains a CD-ROM layer.");
+
+ break;
+ case HybridLayer.Recordable:
+ sb.AppendLine("This disc contains a CD-R layer.");
+
+ break;
+ case HybridLayer.Rewritable:
+ sb.AppendLine("This disc contains a CD-RW layer.");
+
+ break;
+ }
+
+ switch(unit.ChannelLength)
+ {
+ case ChannelLength.Seventy:
+ sb.AppendLine("Disc uses a 74.5nm channel giving 25 Gb per layer.");
+
+ break;
+ case ChannelLength.Sixty:
+ sb.AppendLine("Disc uses a 69.0nm channel giving 27 Gb per layer.");
+
+ break;
+ default:
+ sb.AppendFormat("Disc uses unknown channel length with code {0}", (byte)unit.ChannelLength).
+ AppendLine();
+
+ break;
+ }
+
+ switch(unit.Polarity)
+ {
+ case 0:
+ sb.AppendLine("Disc uses positive polarity.");
+
+ break;
+ case 1:
+ sb.AppendLine("Disc uses negative polarity.");
+
+ break;
+ default:
+ sb.AppendFormat("Disc uses unknown polarity with code {0}", unit.Polarity).AppendLine();
+
+ break;
+ }
+
+ if(Encoding.ASCII.GetString(unit.DiscTypeIdentifier) == DiscTypeBDR)
+ switch(unit.RecordedPolarity)
+ {
+ case 0:
+ sb.AppendLine("Recorded marks have a lower reflectivity than unrecorded ones (HTL disc).");
+
+ break;
+ case 1:
+ sb.AppendLine("Recorded marks have a higher reflectivity than unrecorded ones (LTH disc).");
+
+ break;
+ default:
+ sb.AppendFormat("Disc uses unknown recorded reflectivity polarity with code {0}",
+ unit.RecordedPolarity).AppendLine();
+
+ break;
+ }
+
+ switch(unit.Bca)
+ {
+ case 0:
+ sb.AppendLine("Disc doesn't have a BCA.");
+
+ break;
+ case 1:
+ sb.AppendLine("Disc has a BCA.");
+
+ break;
+ default:
+ sb.AppendFormat("Disc uses unknown BCA code {0}", unit.Bca).AppendLine();
+
+ break;
+ }
+
+ if(unit.MaxTransfer > 0)
+ sb.AppendFormat("Disc has a maximum transfer rate of {0} Mbit/sec.", unit.MaxTransfer).AppendLine();
+ else
+ sb.AppendLine("Disc does not specify a maximum transfer rate.");
+
+ sb.AppendFormat("Last user data PSN for disc: {0}", unit.LastPsn).AppendLine();
+
+ sb.AppendFormat("First address unit number of data zone in this layer: {0}", unit.FirstAun).
+ AppendLine();
+
+ sb.AppendFormat("Last address unit number of data zone in this layer: {0}", unit.LastAun).AppendLine();
+
+ if(Encoding.ASCII.GetString(unit.DiscTypeIdentifier) == DiscTypeBDR ||
+ Encoding.ASCII.GetString(unit.DiscTypeIdentifier) == DiscTypeBDRE)
+ {
+ sb.AppendFormat("Disc manufacturer ID: \"{0}\"", Encoding.ASCII.GetString(unit.ManufacturerID)).
+ AppendLine();
+
+ sb.AppendFormat("Disc media type ID: \"{0}\"", Encoding.ASCII.GetString(unit.MediaTypeID)).
+ AppendLine();
+
+ sb.AppendFormat("Disc timestamp: 0x{0:X2}", unit.TimeStamp).AppendLine();
+ sb.AppendFormat("Disc product revison number: {0}", unit.ProductRevisionNumber).AppendLine();
+ }
+
+ sb.AppendFormat("Blu-ray DI Unit format dependent contents as hex follows:");
+ sb.AppendLine(PrintHex.ByteArrayToHexArrayString(unit.FormatDependentContents, 80));
+ }
+
+ return sb.ToString();
+ }
+
+ public static string Prettify(byte[] DIResponse) => Prettify(Decode(DIResponse));
+
+ public static string ManufacturerFromDI(string manufacturerId)
+ {
+ string manufacturer = "";
+
+ switch(manufacturerId)
+ {
+ case "AMESOB":
+ case "OTCBDR":
+ manufacturer = "Amethystum Storage Technology Co., Ltd.";
+
+ break;
+ case "UMEBDR":
+ case "ANWELL":
+ manufacturer = "Avic Umedisc HK Ltd.";
+
+ break;
+ case "MAXELL":
+ manufacturer = "Hitachi Maxell, Ltd.";
+
+ break;
+ case "CMCMAG":
+ manufacturer = "CMC Magnetics Corporation";
+
+ break;
+ case "ISMMBD":
+ manufacturer = "Info Source Digital Media (Zhong Shan) Co., Ltd.";
+
+ break;
+ case "LGEBRA":
+ manufacturer = "LG Electronics Inc.";
+
+ break;
+ case "MILLEN":
+ manufacturer = "Millenniata, Inc.";
+
+ break;
+ case "VERBAT":
+ case "VAMKM":
+ manufacturer = "Mitsubishi Chemical Media Co., Ltd.";
+
+ break;
+ case "PHILIP":
+ case "MBI":
+ manufacturer = "Moser Baer India Ltd.";
+
+ break;
+ case "MEI":
+ case "PAN":
+ manufacturer = "Matsushita Electric Industrial Co., Ltd.";
+
+ break;
+ case "PRODIS":
+ manufacturer = "Prodisc Technology Inc.";
+
+ break;
+ case "RITEK":
+ manufacturer = "Ritek Co.";
+
+ break;
+ case "SONY":
+ manufacturer = "Sony Corporation";
+
+ break;
+ case "TYG-BD":
+ manufacturer = "Taiyo Yuden Company Ltd.";
+
+ break;
+ case "TDKBLD":
+ manufacturer = "TDK Corporation";
+
+ break;
+ case "JVC-AM":
+ case "JVCVAM":
+ manufacturer = "Victor Advanced media Co., Ltd.";
+
+ break;
+ case "JVCRE1":
+ manufacturer = "JVC KENWOOD Corporation";
+
+ break;
+ case "INFOME":
+ manufacturer = "InfoMedia Inc.";
+
+ break;
+ }
+
+ return manufacturer != "" ? $"{manufacturer} (\"{manufacturerId}\")" : $"\"{manufacturerId}\"";
+ }
+ #endregion Public methods
+
+ #region Public structures
+ public struct DiscInformation
+ {
+ /// Bytes 0 to 1 Always 4098
+ public ushort DataLength;
+ /// Byte 2 Reserved
+ public byte Reserved1;
+ /// Byte 3 Reserved
+ public byte Reserved2;
+ /// Byte 4 to 4099 Disc information units
+ public DiscInformationUnits[] Units;
+ }
+
+ public struct DiscInformationUnits
+ {
+ /// Byte 0 "DI"
+ public ushort Signature;
+ /// Byte 2 Disc information format
+ public byte Format;
+ /// Byte 3, bits 7 to 3 Number of DI units per block
+ public byte UnitsPerBlock;
+ /// Byte 3, bits 2 to 0 Layer this DI refers to
+ public byte Layer;
+ /// Byte 4 Reserved for BD-ROM, legacy information for BD-R/-RE
+ public byte Legacy;
+ /// Byte 5 Sequence number for this DI unit
+ public byte Sequence;
+ /// Byte 6, bit 7 If set this DI is a continuation of the previous one
+ public bool Continuation;
+ /// Byte 6, bits 6 to 0 Number of bytes used by this DI unit, should be 64 for BD-ROM and 112 for BD-R/-RE
+ public byte Length;
+ /// Byte 7 Reserved
+ public byte Reserved;
+ /// Bytes 8 to 10 Disc type identifier
+ public byte[] DiscTypeIdentifier;
+ /// Byte 11, bits 7 to 6 Disc size
+ public BluSize DiscSize;
+ /// Byte 11, bits 5 to 4 Disc class
+ public byte DiscClass;
+ /// Byte 11, bits 3 to 0 Disc version
+ public byte DiscVersion;
+ /// Byte 12, bits 7 to 4 Layers in this disc
+ public byte Layers;
+ /// Byte 12, bits 3 to 0 Reserved
+ public byte Reserved2;
+ /// Byte 13, bits 7 to 6 DVD layer
+ public HybridLayer DvdLayer;
+ /// Byte 13, bits 5 to 4 CD layer
+ public HybridLayer CdLayer;
+ /// Byte 13, bits 3 to 0 Channel length
+ public ChannelLength ChannelLength;
+ /// Byte 14 Polarity
+ public byte Polarity;
+ /// Byte 15 Recorded polarity
+ public byte RecordedPolarity;
+ /// Byte 16, bits 7 to 4 Reserved
+ public byte Reserved3;
+ /// Byte 16, bits 3 to 0 If 0 no BCA, if 1 BCA, rest not defined
+ public byte Bca;
+ /// Byte 17 Maximum transfer speed in megabits/second, 0 if no maximum
+ public byte MaxTransfer;
+ /// Bytes 18 to 19 Reserved
+ public ushort Reserved4;
+ /// Bytes 20 to 23 Last user data PSN for disc
+ public uint LastPsn;
+ /// Bytes 24 to 27 First address unit number of data zone in this layer
+ public uint FirstAun;
+ /// Bytes 28 to 31 Last address unit number of data zone in this layer
+ public uint LastAun;
+ ///
+ /// Bytes 32 to 63 for BD-ROM, bytes 32 to 99 for BD-R/-RE Format dependent contents, disclosed in private blu-ray
+ /// specifications
+ ///
+ public byte[] FormatDependentContents;
+ /// Bytes 100 to 105, BD-R/-RE only Manufacturer ID
+ public byte[] ManufacturerID;
+ /// Bytes 106 to 108, BD-R/-RE only Media type ID
+ public byte[] MediaTypeID;
+ /// Bytes 109 to 110, BD-R/-RE only Timestamp
+ public ushort TimeStamp;
+ /// Byte 111 Product revision number
+ public byte ProductRevisionNumber;
+ }
+ #endregion Public structures
}
\ No newline at end of file
diff --git a/Bluray/Spare.cs b/Bluray/Spare.cs
index 842e2ea..39cc685 100644
--- a/Bluray/Spare.cs
+++ b/Bluray/Spare.cs
@@ -35,96 +35,95 @@ using System.Text;
using Aaru.Console;
using Aaru.Helpers;
-namespace Aaru.Decoders.Bluray
+namespace Aaru.Decoders.Bluray;
+
+// Information from the following standards:
+// ANSI X3.304-1997
+// T10/1048-D revision 9.0
+// T10/1048-D revision 10a
+// T10/1228-D revision 7.0c
+// T10/1228-D revision 11a
+// T10/1363-D revision 10g
+// T10/1545-D revision 1d
+// T10/1545-D revision 5
+// T10/1545-D revision 5a
+// T10/1675-D revision 2c
+// T10/1675-D revision 4
+// T10/1836-D revision 2g
+[SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"),
+ SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), SuppressMessage("ReSharper", "NotAccessedField.Global")]
+public static class Spare
{
- // Information from the following standards:
- // ANSI X3.304-1997
- // T10/1048-D revision 9.0
- // T10/1048-D revision 10a
- // T10/1228-D revision 7.0c
- // T10/1228-D revision 11a
- // T10/1363-D revision 10g
- // T10/1545-D revision 1d
- // T10/1545-D revision 5
- // T10/1545-D revision 5a
- // T10/1675-D revision 2c
- // T10/1675-D revision 4
- // T10/1836-D revision 2g
- [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"),
- SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), SuppressMessage("ReSharper", "NotAccessedField.Global")]
- public static class Spare
+ #region Public structures
+ public struct SpareAreaInformation
{
- #region Public structures
- public struct SpareAreaInformation
- {
- /// Bytes 0 to 1 Always 14
- public ushort DataLength;
- /// Byte 2 Reserved
- public byte Reserved1;
- /// Byte 3 Reserved
- public byte Reserved2;
- /// Bytes 4 to 7 Reserved
- public uint Reserved3;
- /// Bytes 8 to 11 Free spare blocks
- public uint FreeSpareBlocks;
- /// Bytes 12 to 15 Allocated spare blocks
- public uint AllocatedSpareBlocks;
- }
- #endregion Public structures
- #region Public methods
- public static SpareAreaInformation? Decode(byte[] SAIResponse)
- {
- if(SAIResponse == null)
- return null;
-
- if(SAIResponse.Length != 16)
- {
- AaruConsole.DebugWriteLine("BD Spare Area Information decoder",
- "Found incorrect Blu-ray Spare Area Information size ({0} bytes)",
- SAIResponse.Length);
-
- return null;
- }
-
- var decoded = new SpareAreaInformation
- {
- DataLength = BigEndianBitConverter.ToUInt16(SAIResponse, 0),
- Reserved1 = SAIResponse[2],
- Reserved2 = SAIResponse[3],
- Reserved3 = BigEndianBitConverter.ToUInt32(SAIResponse, 4),
- FreeSpareBlocks = BigEndianBitConverter.ToUInt32(SAIResponse, 8),
- AllocatedSpareBlocks = BigEndianBitConverter.ToUInt32(SAIResponse, 12)
- };
-
- return decoded;
- }
-
- public static string Prettify(SpareAreaInformation? SAIResponse)
- {
- if(SAIResponse == null)
- return null;
-
- SpareAreaInformation response = SAIResponse.Value;
-
- var sb = new StringBuilder();
-
- #if DEBUG
- if(response.Reserved1 != 0)
- sb.AppendFormat("Reserved1 = 0x{0:X2}", response.Reserved1).AppendLine();
-
- if(response.Reserved2 != 0)
- sb.AppendFormat("Reserved2 = 0x{0:X2}", response.Reserved2).AppendLine();
-
- if(response.Reserved3 != 0)
- sb.AppendFormat("Reserved3 = 0x{0:X8}", response.Reserved3).AppendLine();
- #endif
- sb.AppendFormat("{0} free spare blocks", response.FreeSpareBlocks).AppendLine();
- sb.AppendFormat("{0} allocated spare blocks", response.AllocatedSpareBlocks).AppendLine();
-
- return sb.ToString();
- }
-
- public static string Prettify(byte[] SAIResponse) => Prettify(Decode(SAIResponse));
- #endregion Public methods
+ /// Bytes 0 to 1 Always 14
+ public ushort DataLength;
+ /// Byte 2 Reserved
+ public byte Reserved1;
+ /// Byte 3 Reserved
+ public byte Reserved2;
+ /// Bytes 4 to 7 Reserved
+ public uint Reserved3;
+ /// Bytes 8 to 11 Free spare blocks
+ public uint FreeSpareBlocks;
+ /// Bytes 12 to 15 Allocated spare blocks
+ public uint AllocatedSpareBlocks;
}
+ #endregion Public structures
+ #region Public methods
+ public static SpareAreaInformation? Decode(byte[] SAIResponse)
+ {
+ if(SAIResponse == null)
+ return null;
+
+ if(SAIResponse.Length != 16)
+ {
+ AaruConsole.DebugWriteLine("BD Spare Area Information decoder",
+ "Found incorrect Blu-ray Spare Area Information size ({0} bytes)",
+ SAIResponse.Length);
+
+ return null;
+ }
+
+ var decoded = new SpareAreaInformation
+ {
+ DataLength = BigEndianBitConverter.ToUInt16(SAIResponse, 0),
+ Reserved1 = SAIResponse[2],
+ Reserved2 = SAIResponse[3],
+ Reserved3 = BigEndianBitConverter.ToUInt32(SAIResponse, 4),
+ FreeSpareBlocks = BigEndianBitConverter.ToUInt32(SAIResponse, 8),
+ AllocatedSpareBlocks = BigEndianBitConverter.ToUInt32(SAIResponse, 12)
+ };
+
+ return decoded;
+ }
+
+ public static string Prettify(SpareAreaInformation? SAIResponse)
+ {
+ if(SAIResponse == null)
+ return null;
+
+ SpareAreaInformation response = SAIResponse.Value;
+
+ var sb = new StringBuilder();
+
+ #if DEBUG
+ if(response.Reserved1 != 0)
+ sb.AppendFormat("Reserved1 = 0x{0:X2}", response.Reserved1).AppendLine();
+
+ if(response.Reserved2 != 0)
+ sb.AppendFormat("Reserved2 = 0x{0:X2}", response.Reserved2).AppendLine();
+
+ if(response.Reserved3 != 0)
+ sb.AppendFormat("Reserved3 = 0x{0:X8}", response.Reserved3).AppendLine();
+ #endif
+ sb.AppendFormat("{0} free spare blocks", response.FreeSpareBlocks).AppendLine();
+ sb.AppendFormat("{0} allocated spare blocks", response.AllocatedSpareBlocks).AppendLine();
+
+ return sb.ToString();
+ }
+
+ public static string Prettify(byte[] SAIResponse) => Prettify(Decode(SAIResponse));
+ #endregion Public methods
}
\ No newline at end of file
diff --git a/CD/ATIP.cs b/CD/ATIP.cs
index 816d7d5..23e65d8 100644
--- a/CD/ATIP.cs
+++ b/CD/ATIP.cs
@@ -36,644 +36,643 @@ using System.Text;
using Aaru.Console;
using Aaru.Helpers;
-namespace Aaru.Decoders.CD
+namespace Aaru.Decoders.CD;
+
+// Information from the following standards:
+// ANSI X3.304-1997
+// T10/1048-D revision 9.0
+// T10/1048-D revision 10a
+// T10/1228-D revision 7.0c
+// T10/1228-D revision 11a
+// T10/1363-D revision 10g
+// T10/1545-D revision 1d
+// T10/1545-D revision 5
+// T10/1545-D revision 5a
+// T10/1675-D revision 2c
+// T10/1675-D revision 4
+// T10/1836-D revision 2g
+[SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"),
+ SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), SuppressMessage("ReSharper", "NotAccessedField.Global")]
+public static class ATIP
{
- // Information from the following standards:
- // ANSI X3.304-1997
- // T10/1048-D revision 9.0
- // T10/1048-D revision 10a
- // T10/1228-D revision 7.0c
- // T10/1228-D revision 11a
- // T10/1363-D revision 10g
- // T10/1545-D revision 1d
- // T10/1545-D revision 5
- // T10/1545-D revision 5a
- // T10/1675-D revision 2c
- // T10/1675-D revision 4
- // T10/1836-D revision 2g
- [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"),
- SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), SuppressMessage("ReSharper", "NotAccessedField.Global")]
- public static class ATIP
+ public static CDATIP Decode(byte[] CDATIPResponse)
{
- public static CDATIP Decode(byte[] CDATIPResponse)
+ if(CDATIPResponse == null ||
+ CDATIPResponse.Length <= 4)
+ return null;
+
+ var decoded = new CDATIP();
+
+ if(CDATIPResponse.Length != 32 &&
+ CDATIPResponse.Length != 28)
{
- if(CDATIPResponse == null ||
- CDATIPResponse.Length <= 4)
- return null;
+ AaruConsole.DebugWriteLine("CD ATIP decoder",
+ "Expected CD ATIP size (32 bytes) is not received size ({0} bytes), not decoding",
+ CDATIPResponse.Length);
- var decoded = new CDATIP();
-
- if(CDATIPResponse.Length != 32 &&
- CDATIPResponse.Length != 28)
- {
- AaruConsole.DebugWriteLine("CD ATIP decoder",
- "Expected CD ATIP size (32 bytes) is not received size ({0} bytes), not decoding",
- CDATIPResponse.Length);
-
- return null;
- }
-
- decoded.DataLength = BigEndianBitConverter.ToUInt16(CDATIPResponse, 0);
- decoded.Reserved1 = CDATIPResponse[2];
- decoded.Reserved2 = CDATIPResponse[3];
- decoded.ITWP = (byte)((CDATIPResponse[4] & 0xF0) >> 4);
- decoded.DDCD = Convert.ToBoolean(CDATIPResponse[4] & 0x08);
- decoded.ReferenceSpeed = (byte)(CDATIPResponse[4] & 0x07);
- decoded.AlwaysZero = Convert.ToBoolean(CDATIPResponse[5] & 0x80);
- decoded.URU = Convert.ToBoolean(CDATIPResponse[5] & 0x40);
- decoded.Reserved3 = (byte)(CDATIPResponse[5] & 0x3F);
-
- decoded.AlwaysOne = Convert.ToBoolean(CDATIPResponse[6] & 0x80);
- decoded.DiscType = Convert.ToBoolean(CDATIPResponse[6] & 0x40);
- decoded.DiscSubType = (byte)((CDATIPResponse[6] & 0x38) >> 3);
- decoded.A1Valid = Convert.ToBoolean(CDATIPResponse[6] & 0x04);
- decoded.A2Valid = Convert.ToBoolean(CDATIPResponse[6] & 0x02);
- decoded.A3Valid = Convert.ToBoolean(CDATIPResponse[6] & 0x01);
-
- decoded.Reserved4 = CDATIPResponse[7];
- decoded.LeadInStartMin = CDATIPResponse[8];
- decoded.LeadInStartSec = CDATIPResponse[9];
- decoded.LeadInStartFrame = CDATIPResponse[10];
- decoded.Reserved5 = CDATIPResponse[11];
- decoded.LeadOutStartMin = CDATIPResponse[12];
- decoded.LeadOutStartSec = CDATIPResponse[13];
- decoded.LeadOutStartFrame = CDATIPResponse[14];
- decoded.Reserved6 = CDATIPResponse[15];
-
- decoded.A1Values = new byte[3];
- decoded.A2Values = new byte[3];
- decoded.A3Values = new byte[3];
-
- Array.Copy(CDATIPResponse, 16, decoded.A1Values, 0, 3);
- Array.Copy(CDATIPResponse, 20, decoded.A2Values, 0, 3);
- Array.Copy(CDATIPResponse, 24, decoded.A3Values, 0, 3);
-
- decoded.Reserved7 = CDATIPResponse[19];
- decoded.Reserved8 = CDATIPResponse[23];
- decoded.Reserved9 = CDATIPResponse[27];
-
- if(CDATIPResponse.Length < 32)
- return decoded.AlwaysOne ? decoded : null;
-
- decoded.S4Values = new byte[3];
- Array.Copy(CDATIPResponse, 28, decoded.S4Values, 0, 3);
- decoded.Reserved10 = CDATIPResponse[31];
-
- return decoded.AlwaysOne ? decoded : null;
+ return null;
}
- public static string Prettify(CDATIP response)
+ decoded.DataLength = BigEndianBitConverter.ToUInt16(CDATIPResponse, 0);
+ decoded.Reserved1 = CDATIPResponse[2];
+ decoded.Reserved2 = CDATIPResponse[3];
+ decoded.ITWP = (byte)((CDATIPResponse[4] & 0xF0) >> 4);
+ decoded.DDCD = Convert.ToBoolean(CDATIPResponse[4] & 0x08);
+ decoded.ReferenceSpeed = (byte)(CDATIPResponse[4] & 0x07);
+ decoded.AlwaysZero = Convert.ToBoolean(CDATIPResponse[5] & 0x80);
+ decoded.URU = Convert.ToBoolean(CDATIPResponse[5] & 0x40);
+ decoded.Reserved3 = (byte)(CDATIPResponse[5] & 0x3F);
+
+ decoded.AlwaysOne = Convert.ToBoolean(CDATIPResponse[6] & 0x80);
+ decoded.DiscType = Convert.ToBoolean(CDATIPResponse[6] & 0x40);
+ decoded.DiscSubType = (byte)((CDATIPResponse[6] & 0x38) >> 3);
+ decoded.A1Valid = Convert.ToBoolean(CDATIPResponse[6] & 0x04);
+ decoded.A2Valid = Convert.ToBoolean(CDATIPResponse[6] & 0x02);
+ decoded.A3Valid = Convert.ToBoolean(CDATIPResponse[6] & 0x01);
+
+ decoded.Reserved4 = CDATIPResponse[7];
+ decoded.LeadInStartMin = CDATIPResponse[8];
+ decoded.LeadInStartSec = CDATIPResponse[9];
+ decoded.LeadInStartFrame = CDATIPResponse[10];
+ decoded.Reserved5 = CDATIPResponse[11];
+ decoded.LeadOutStartMin = CDATIPResponse[12];
+ decoded.LeadOutStartSec = CDATIPResponse[13];
+ decoded.LeadOutStartFrame = CDATIPResponse[14];
+ decoded.Reserved6 = CDATIPResponse[15];
+
+ decoded.A1Values = new byte[3];
+ decoded.A2Values = new byte[3];
+ decoded.A3Values = new byte[3];
+
+ Array.Copy(CDATIPResponse, 16, decoded.A1Values, 0, 3);
+ Array.Copy(CDATIPResponse, 20, decoded.A2Values, 0, 3);
+ Array.Copy(CDATIPResponse, 24, decoded.A3Values, 0, 3);
+
+ decoded.Reserved7 = CDATIPResponse[19];
+ decoded.Reserved8 = CDATIPResponse[23];
+ decoded.Reserved9 = CDATIPResponse[27];
+
+ if(CDATIPResponse.Length < 32)
+ return decoded.AlwaysOne ? decoded : null;
+
+ decoded.S4Values = new byte[3];
+ Array.Copy(CDATIPResponse, 28, decoded.S4Values, 0, 3);
+ decoded.Reserved10 = CDATIPResponse[31];
+
+ return decoded.AlwaysOne ? decoded : null;
+ }
+
+ public static string Prettify(CDATIP response)
+ {
+ if(response == null)
+ return null;
+
+ var sb = new StringBuilder();
+
+ if(response.DDCD)
{
- if(response == null)
- return null;
+ sb.AppendFormat("Indicative Target Writing Power: 0x{0:X2}", response.ITWP).AppendLine();
+ sb.AppendLine(response.DiscType ? "Disc is DDCD-RW" : "Disc is DDCD-R");
- var sb = new StringBuilder();
-
- if(response.DDCD)
+ switch(response.ReferenceSpeed)
{
- sb.AppendFormat("Indicative Target Writing Power: 0x{0:X2}", response.ITWP).AppendLine();
- sb.AppendLine(response.DiscType ? "Disc is DDCD-RW" : "Disc is DDCD-R");
+ case 2:
+ sb.AppendLine("Reference speed is 4x");
- switch(response.ReferenceSpeed)
+ break;
+ case 3:
+ sb.AppendLine("Reference speed is 8x");
+
+ break;
+ default:
+ sb.AppendFormat("Reference speed set is unknown: {0}", response.ReferenceSpeed).AppendLine();
+
+ break;
+ }
+
+ sb.AppendFormat("ATIP Start time of Lead-in: 0x{0:X6}",
+ (response.LeadInStartMin << 16) + (response.LeadInStartSec << 8) +
+ response.LeadInStartFrame).AppendLine();
+
+ sb.AppendFormat("ATIP Last possible start time of Lead-out: 0x{0:X6}",
+ (response.LeadOutStartMin << 16) + (response.LeadOutStartSec << 8) +
+ response.LeadOutStartFrame).AppendLine();
+
+ sb.AppendFormat("S4 value: 0x{0:X6}",
+ (response.S4Values[0] << 16) + (response.S4Values[1] << 8) + response.S4Values[2]).
+ AppendLine();
+ }
+ else
+ {
+ sb.AppendFormat("Indicative Target Writing Power: 0x{0:X2}", response.ITWP & 0x07).AppendLine();
+
+ if(response.DiscType)
+ {
+ switch(response.DiscSubType)
{
+ case 0:
+ sb.AppendLine("Disc is CD-RW");
+
+ break;
+ case 1:
+ sb.AppendLine("Disc is High-Speed CD-RW");
+
+ break;
case 2:
- sb.AppendLine("Reference speed is 4x");
+ sb.AppendLine("Disc is Ultra-Speed CD-RW");
break;
case 3:
- sb.AppendLine("Reference speed is 8x");
+ sb.AppendLine("Disc is Ultra-Speed+ CD-RW");
+
+ break;
+ case 4:
+ sb.AppendLine("Disc is medium type B, low beta category (B-) CD-RW");
+
+ break;
+ case 5:
+ sb.AppendLine("Disc is medium type B, high beta category (B+) CD-RW");
+
+ break;
+ case 6:
+ sb.AppendLine("Disc is medium type C, low beta category (C-) CD-RW");
+
+ break;
+ case 7:
+ sb.AppendLine("Disc is medium type C, high beta category (C+) CD-RW");
break;
default:
- sb.AppendFormat("Reference speed set is unknown: {0}", response.ReferenceSpeed).AppendLine();
+ sb.AppendFormat("Unknown CD-RW disc subtype: {0}", response.DiscSubType).AppendLine();
break;
}
- sb.AppendFormat("ATIP Start time of Lead-in: 0x{0:X6}",
- (response.LeadInStartMin << 16) + (response.LeadInStartSec << 8) +
- response.LeadInStartFrame).AppendLine();
+ switch(response.ReferenceSpeed)
+ {
+ case 1:
+ sb.AppendLine("Reference speed is 2x");
- sb.AppendFormat("ATIP Last possible start time of Lead-out: 0x{0:X6}",
- (response.LeadOutStartMin << 16) + (response.LeadOutStartSec << 8) +
- response.LeadOutStartFrame).AppendLine();
+ break;
+ default:
+ sb.AppendFormat("Reference speed set is unknown: {0}", response.ReferenceSpeed).
+ AppendLine();
+ break;
+ }
+ }
+ else
+ {
+ sb.AppendLine("Disc is CD-R");
+
+ switch(response.DiscSubType)
+ {
+ case 0:
+ sb.AppendLine("Disc is normal speed (CLV) CD-R");
+
+ break;
+ case 1:
+ sb.AppendLine("Disc is high speed (CAV) CD-R");
+
+ break;
+ case 2:
+ sb.AppendLine("Disc is medium type A, low beta category (A-) CD-R");
+
+ break;
+ case 3:
+ sb.AppendLine("Disc is medium type A, high beta category (A+) CD-R");
+
+ break;
+ case 4:
+ sb.AppendLine("Disc is medium type B, low beta category (B-) CD-R");
+
+ break;
+ case 5:
+ sb.AppendLine("Disc is medium type B, high beta category (B+) CD-R");
+
+ break;
+ case 6:
+ sb.AppendLine("Disc is medium type C, low beta category (C-) CD-R");
+
+ break;
+ case 7:
+ sb.AppendLine("Disc is medium type C, high beta category (C+) CD-R");
+
+ break;
+ default:
+ sb.AppendFormat("Unknown CD-R disc subtype: {0}", response.DiscSubType).AppendLine();
+
+ break;
+ }
+ }
+
+ sb.AppendLine(response.URU ? "Disc use is unrestricted" : "Disc use is restricted");
+
+ sb.AppendFormat("ATIP Start time of Lead-in: {0}:{1:D2}:{2:D2}", response.LeadInStartMin,
+ response.LeadInStartSec, response.LeadInStartFrame).AppendLine();
+
+ sb.AppendFormat("ATIP Last possible start time of Lead-out: {0}:{1:D2}:{2:D2}",
+ response.LeadOutStartMin, response.LeadOutStartSec, response.LeadOutStartFrame).
+ AppendLine();
+
+ if(response.A1Valid)
+ sb.AppendFormat("A1 value: 0x{0:X6}",
+ (response.A1Values[0] << 16) + (response.A1Values[1] << 8) + response.A1Values[2]).
+ AppendLine();
+
+ if(response.A2Valid)
+ sb.AppendFormat("A2 value: 0x{0:X6}",
+ (response.A2Values[0] << 16) + (response.A2Values[1] << 8) + response.A2Values[2]).
+ AppendLine();
+
+ if(response.A3Valid)
+ sb.AppendFormat("A3 value: 0x{0:X6}",
+ (response.A3Values[0] << 16) + (response.A3Values[1] << 8) + response.A3Values[2]).
+ AppendLine();
+
+ if(response.S4Values != null)
sb.AppendFormat("S4 value: 0x{0:X6}",
(response.S4Values[0] << 16) + (response.S4Values[1] << 8) + response.S4Values[2]).
AppendLine();
- }
- else
- {
- sb.AppendFormat("Indicative Target Writing Power: 0x{0:X2}", response.ITWP & 0x07).AppendLine();
-
- if(response.DiscType)
- {
- switch(response.DiscSubType)
- {
- case 0:
- sb.AppendLine("Disc is CD-RW");
-
- break;
- case 1:
- sb.AppendLine("Disc is High-Speed CD-RW");
-
- break;
- case 2:
- sb.AppendLine("Disc is Ultra-Speed CD-RW");
-
- break;
- case 3:
- sb.AppendLine("Disc is Ultra-Speed+ CD-RW");
-
- break;
- case 4:
- sb.AppendLine("Disc is medium type B, low beta category (B-) CD-RW");
-
- break;
- case 5:
- sb.AppendLine("Disc is medium type B, high beta category (B+) CD-RW");
-
- break;
- case 6:
- sb.AppendLine("Disc is medium type C, low beta category (C-) CD-RW");
-
- break;
- case 7:
- sb.AppendLine("Disc is medium type C, high beta category (C+) CD-RW");
-
- break;
- default:
- sb.AppendFormat("Unknown CD-RW disc subtype: {0}", response.DiscSubType).AppendLine();
-
- break;
- }
-
- switch(response.ReferenceSpeed)
- {
- case 1:
- sb.AppendLine("Reference speed is 2x");
-
- break;
- default:
- sb.AppendFormat("Reference speed set is unknown: {0}", response.ReferenceSpeed).
- AppendLine();
-
- break;
- }
- }
- else
- {
- sb.AppendLine("Disc is CD-R");
-
- switch(response.DiscSubType)
- {
- case 0:
- sb.AppendLine("Disc is normal speed (CLV) CD-R");
-
- break;
- case 1:
- sb.AppendLine("Disc is high speed (CAV) CD-R");
-
- break;
- case 2:
- sb.AppendLine("Disc is medium type A, low beta category (A-) CD-R");
-
- break;
- case 3:
- sb.AppendLine("Disc is medium type A, high beta category (A+) CD-R");
-
- break;
- case 4:
- sb.AppendLine("Disc is medium type B, low beta category (B-) CD-R");
-
- break;
- case 5:
- sb.AppendLine("Disc is medium type B, high beta category (B+) CD-R");
-
- break;
- case 6:
- sb.AppendLine("Disc is medium type C, low beta category (C-) CD-R");
-
- break;
- case 7:
- sb.AppendLine("Disc is medium type C, high beta category (C+) CD-R");
-
- break;
- default:
- sb.AppendFormat("Unknown CD-R disc subtype: {0}", response.DiscSubType).AppendLine();
-
- break;
- }
- }
-
- sb.AppendLine(response.URU ? "Disc use is unrestricted" : "Disc use is restricted");
-
- sb.AppendFormat("ATIP Start time of Lead-in: {0}:{1:D2}:{2:D2}", response.LeadInStartMin,
- response.LeadInStartSec, response.LeadInStartFrame).AppendLine();
-
- sb.AppendFormat("ATIP Last possible start time of Lead-out: {0}:{1:D2}:{2:D2}",
- response.LeadOutStartMin, response.LeadOutStartSec, response.LeadOutStartFrame).
- AppendLine();
-
- if(response.A1Valid)
- sb.AppendFormat("A1 value: 0x{0:X6}",
- (response.A1Values[0] << 16) + (response.A1Values[1] << 8) + response.A1Values[2]).
- AppendLine();
-
- if(response.A2Valid)
- sb.AppendFormat("A2 value: 0x{0:X6}",
- (response.A2Values[0] << 16) + (response.A2Values[1] << 8) + response.A2Values[2]).
- AppendLine();
-
- if(response.A3Valid)
- sb.AppendFormat("A3 value: 0x{0:X6}",
- (response.A3Values[0] << 16) + (response.A3Values[1] << 8) + response.A3Values[2]).
- AppendLine();
-
- if(response.S4Values != null)
- sb.AppendFormat("S4 value: 0x{0:X6}",
- (response.S4Values[0] << 16) + (response.S4Values[1] << 8) + response.S4Values[2]).
- AppendLine();
- }
-
- if(response.LeadInStartMin != 97)
- return sb.ToString();
-
- int type = response.LeadInStartFrame % 10;
- int frm = response.LeadInStartFrame - type;
-
- if(response.DiscType)
- sb.AppendLine("Disc uses phase change");
- else
- sb.AppendLine(type < 5 ? "Disc uses long strategy type dye (Cyanine, AZO, etc...)"
- : "Disc uses short strategy type dye (Phthalocyanine, etc...)");
-
- string manufacturer = ManufacturerFromATIP(response.LeadInStartSec, frm);
-
- if(manufacturer != "")
- sb.AppendFormat("Disc manufactured by: {0}", manufacturer).AppendLine();
+ }
+ if(response.LeadInStartMin != 97)
return sb.ToString();
- }
- public static string Prettify(byte[] CDATIPResponse)
+ int type = response.LeadInStartFrame % 10;
+ int frm = response.LeadInStartFrame - type;
+
+ if(response.DiscType)
+ sb.AppendLine("Disc uses phase change");
+ else
+ sb.AppendLine(type < 5 ? "Disc uses long strategy type dye (Cyanine, AZO, etc...)"
+ : "Disc uses short strategy type dye (Phthalocyanine, etc...)");
+
+ string manufacturer = ManufacturerFromATIP(response.LeadInStartSec, frm);
+
+ if(manufacturer != "")
+ sb.AppendFormat("Disc manufactured by: {0}", manufacturer).AppendLine();
+
+ return sb.ToString();
+ }
+
+ public static string Prettify(byte[] CDATIPResponse)
+ {
+ CDATIP decoded = Decode(CDATIPResponse);
+
+ return Prettify(decoded);
+ }
+
+ public static string ManufacturerFromATIP(byte sec, int frm)
+ {
+ switch(sec)
{
- CDATIP decoded = Decode(CDATIPResponse);
+ case 10:
+ switch(frm)
+ {
+ case 00: return "Ritek Co.";
+ }
- return Prettify(decoded);
+ break;
+ case 15:
+ switch(frm)
+ {
+ case 00: return "TDK Corporation";
+ case 10: return "Ritek Co.";
+ case 20: return "Mitsubishi Chemical Corporation";
+ case 30: return "NAN-YA Plastics Corporation";
+ }
+
+ break;
+ case 16:
+ switch(frm)
+ {
+ case 20: return "Shenzen SG&Gast Digital Optical Discs";
+ case 30: return "Grand Advance Technology Ltd.";
+ }
+
+ break;
+ case 17:
+ if(frm == 00)
+ return "Moser Baer India Ltd.";
+
+ break;
+ case 18:
+ switch(frm)
+ {
+ case 10: return "Wealth Fair Investment Ltd.";
+ case 60: return "Taroko International Co. Ltd.";
+ }
+
+ break;
+ case 20:
+ if(frm == 10)
+ return "CDA Datenträger Albrechts GmbH";
+
+ break;
+ case 21:
+ switch(frm)
+ {
+ case 10: return "Grupo Condor S.L.";
+ case 20: return "E-TOP Mediatek Inc.";
+ case 30: return "Bestdisc Technology Corporation";
+ case 40: return "Optical Disc Manufacturing Equipment";
+ case 50: return "Sound Sound Multi-Media Development Ltd.";
+ }
+
+ break;
+ case 22:
+ switch(frm)
+ {
+ case 00: return "Woongjin Media Corp.";
+ case 10: return "Seantram Technology Inc.";
+ case 20: return "Advanced Digital Media";
+ case 30: return "EXIMPO";
+ case 40: return "CIS Technology Inc.";
+ case 50: return "Hong Kong Digital Technology Co., Ltd.";
+ case 60: return "Acer Media Technology, Inc.";
+ }
+
+ break;
+ case 23:
+ switch(frm)
+ {
+ case 00: return "Matsushita Electric Industrial Co., Ltd.";
+ case 10: return "Doremi Media Co., Ltd.";
+ case 20: return "Nacar Media s.r.l.";
+ case 30: return "Audio Distributors Co., Ltd.";
+ case 40: return "Victor Company of Japan, Ltd.";
+ case 50: return "Optrom Inc.";
+ case 60: return "Customer Pressing Oosterhout";
+ }
+
+ break;
+ case 24:
+ switch(frm)
+ {
+ case 00: return "Taiyo Yuden Company Ltd.";
+ case 10: return "SONY Corporation";
+ case 20: return "Computer Support Italy s.r.l.";
+ case 30: return "Unitech Japan Inc.";
+ case 40: return "kdg mediatech AG";
+ case 50: return "Guann Yinn Co., Ltd.";
+ case 60: return "Harmonic Hall Optical Disc Ltd.";
+ }
+
+ break;
+ case 25:
+ switch(frm)
+ {
+ case 00: return "MPO";
+ case 20: return "Hitachi Maxell, Ltd.";
+ case 30: return "Infodisc Technology Co. Ltd.";
+ case 40: return "Vivastar AG";
+ case 50: return "AMS Technology Inc.";
+ case 60: return "Xcitec Inc.";
+ }
+
+ break;
+ case 26:
+ switch(frm)
+ {
+ case 00: return "Fornet International Pte Ltd.";
+ case 10: return "POSTECH Corporation";
+ case 20: return "SKC Co., Ltd.";
+ case 30: return "Optical Disc Corporation";
+ case 40: return "FUJI Photo Film Co., Ltd.";
+ case 50: return "Lead Data Inc.";
+ case 60: return "CMC Magnetics Corporation";
+ }
+
+ break;
+ case 27:
+ switch(frm)
+ {
+ case 00: return "Digital Storage Technology Co., Ltd.";
+ case 10: return "Plasmon Data systems Ltd.";
+ case 20: return "Princo Corporation";
+ case 30: return "Pioneer Video Corporation";
+ case 40: return "Kodak Japan Ltd.";
+ case 50: return "Mitsui Chemicals, Inc.";
+ case 60: return "Ricoh Company Ltd.";
+ }
+
+ break;
+ case 28:
+ switch(frm)
+ {
+ case 00: return "Opti.Me.S. S.p.A.";
+ case 10: return "Gigastore Corporation";
+ case 20: return "Multi Media Masters & Machinary SA";
+ case 30: return "Auvistar Industry Co., Ltd.";
+ case 40: return "King Pro Mediatek Inc.";
+ case 50: return "Delphi Technology Inc.";
+ case 60: return "Friendly CD-Tek Co.";
+ }
+
+ break;
+ case 29:
+ switch(frm)
+ {
+ case 00: return "Taeil Media Co., Ltd.";
+ case 10: return "Vanguard Disc Inc.";
+ case 20: return "Unidisc Technology Co., Ltd.";
+ case 30: return "Hile Optical Disc Technology Corp.";
+ case 40: return "Viva Magnetics Ltd.";
+ case 50: return "General Magnetics Ltd.";
+ }
+
+ break;
+ case 30:
+ if(frm == 10)
+ return "CDA Datenträger Albrechts GmbH";
+
+ break;
+ case 31:
+ switch(frm)
+ {
+ case 00: return "Ritek Co.";
+ case 30: return "Grand Advance Technology Ltd.";
+ }
+
+ break;
+ case 32:
+ switch(frm)
+ {
+ case 00: return "TDK Corporation";
+ case 10: return "Prodisc Technology Inc.";
+ }
+
+ break;
+ case 34:
+ switch(frm)
+ {
+ case 20:
+ case 22: return "Mitsubishi Chemical Corporation";
+ }
+
+ break;
+ case 36:
+ switch(frm)
+ {
+ case 00: return "Gish International Co., Ltd.";
+ }
+
+ break;
+ case 42:
+ if(frm == 20)
+ return "Advanced Digital Media";
+
+ break;
+ case 45:
+ switch(frm)
+ {
+ case 00: return "Fornet International Pte Ltd.";
+ case 10: return "Unitech Japan Inc.";
+ case 20: return "Acer Media Technology, Inc.";
+ case 40: return "CIS Technology Inc.";
+ case 50: return "Guann Yinn Co., Ltd.";
+ case 60: return "Xcitec Inc.";
+ }
+
+ break;
+ case 46:
+ switch(frm)
+ {
+ case 00: return "Taiyo Yuden Company Ltd.";
+ case 10: return "Hong Kong Digital Technology Co., Ltd.";
+ case 20: return "Multi Media Masters & Machinary SA";
+ case 30: return "Computer Support Italy s.r.l.";
+ case 40: return "FUJI Photo Film Co., Ltd.";
+ case 50: return "Auvistar Industry Co., Ltd.";
+ case 60: return "CMC Magnetics Corporation";
+ }
+
+ break;
+ case 47:
+ switch(frm)
+ {
+ case 10: return "Hitachi Maxell, Ltd.";
+ case 20: return "Princo Corporation";
+ case 40: return "POSTECH Corporation";
+ case 50: return "Ritek Co.";
+ case 60: return "Prodisc Technology Inc.";
+ }
+
+ break;
+ case 48:
+ switch(frm)
+ {
+ case 00: return "Ricoh Company Ltd.";
+ case 10: return "Kodak Japan Ltd.";
+ case 20: return "Plasmon Data systems Ltd.";
+ case 30: return "Pioneer Video Corporation";
+ case 40: return "Digital Storage Technology Co., Ltd.";
+ case 50: return "Mitsui Chemicals, Inc.";
+ case 60: return "Lead Data Inc.";
+ }
+
+ break;
+ case 49:
+ switch(frm)
+ {
+ case 00: return "TDK Corporation";
+ case 10: return "Gigastore Corporation";
+ case 20: return "King Pro Mediatek Inc.";
+ case 30: return "Opti.Me.S. S.p.A.";
+ case 40: return "Victor Company of Japan, Ltd.";
+ case 60: return "Matsushita Electric Industrial Co., Ltd.";
+ }
+
+ break;
+ case 50:
+ switch(frm)
+ {
+ case 10: return "Vanguard Disc Inc.";
+ case 20: return "Mitsubishi Chemical Corporation";
+ case 30: return "CDA Datenträger Albrechts GmbH";
+ }
+
+ break;
+ case 51:
+ switch(frm)
+ {
+ case 10: return "Grand Advance Technology Ltd.";
+ case 20: return "Infodisc Technology Co. Ltd.";
+ case 50: return "Hile Optical Disc Technology Corp.";
+ }
+
+ break;
}
- public static string ManufacturerFromATIP(byte sec, int frm)
- {
- switch(sec)
- {
- case 10:
- switch(frm)
- {
- case 00: return "Ritek Co.";
- }
+ return "";
+ }
- break;
- case 15:
- switch(frm)
- {
- case 00: return "TDK Corporation";
- case 10: return "Ritek Co.";
- case 20: return "Mitsubishi Chemical Corporation";
- case 30: return "NAN-YA Plastics Corporation";
- }
-
- break;
- case 16:
- switch(frm)
- {
- case 20: return "Shenzen SG&Gast Digital Optical Discs";
- case 30: return "Grand Advance Technology Ltd.";
- }
-
- break;
- case 17:
- if(frm == 00)
- return "Moser Baer India Ltd.";
-
- break;
- case 18:
- switch(frm)
- {
- case 10: return "Wealth Fair Investment Ltd.";
- case 60: return "Taroko International Co. Ltd.";
- }
-
- break;
- case 20:
- if(frm == 10)
- return "CDA Datenträger Albrechts GmbH";
-
- break;
- case 21:
- switch(frm)
- {
- case 10: return "Grupo Condor S.L.";
- case 20: return "E-TOP Mediatek Inc.";
- case 30: return "Bestdisc Technology Corporation";
- case 40: return "Optical Disc Manufacturing Equipment";
- case 50: return "Sound Sound Multi-Media Development Ltd.";
- }
-
- break;
- case 22:
- switch(frm)
- {
- case 00: return "Woongjin Media Corp.";
- case 10: return "Seantram Technology Inc.";
- case 20: return "Advanced Digital Media";
- case 30: return "EXIMPO";
- case 40: return "CIS Technology Inc.";
- case 50: return "Hong Kong Digital Technology Co., Ltd.";
- case 60: return "Acer Media Technology, Inc.";
- }
-
- break;
- case 23:
- switch(frm)
- {
- case 00: return "Matsushita Electric Industrial Co., Ltd.";
- case 10: return "Doremi Media Co., Ltd.";
- case 20: return "Nacar Media s.r.l.";
- case 30: return "Audio Distributors Co., Ltd.";
- case 40: return "Victor Company of Japan, Ltd.";
- case 50: return "Optrom Inc.";
- case 60: return "Customer Pressing Oosterhout";
- }
-
- break;
- case 24:
- switch(frm)
- {
- case 00: return "Taiyo Yuden Company Ltd.";
- case 10: return "SONY Corporation";
- case 20: return "Computer Support Italy s.r.l.";
- case 30: return "Unitech Japan Inc.";
- case 40: return "kdg mediatech AG";
- case 50: return "Guann Yinn Co., Ltd.";
- case 60: return "Harmonic Hall Optical Disc Ltd.";
- }
-
- break;
- case 25:
- switch(frm)
- {
- case 00: return "MPO";
- case 20: return "Hitachi Maxell, Ltd.";
- case 30: return "Infodisc Technology Co. Ltd.";
- case 40: return "Vivastar AG";
- case 50: return "AMS Technology Inc.";
- case 60: return "Xcitec Inc.";
- }
-
- break;
- case 26:
- switch(frm)
- {
- case 00: return "Fornet International Pte Ltd.";
- case 10: return "POSTECH Corporation";
- case 20: return "SKC Co., Ltd.";
- case 30: return "Optical Disc Corporation";
- case 40: return "FUJI Photo Film Co., Ltd.";
- case 50: return "Lead Data Inc.";
- case 60: return "CMC Magnetics Corporation";
- }
-
- break;
- case 27:
- switch(frm)
- {
- case 00: return "Digital Storage Technology Co., Ltd.";
- case 10: return "Plasmon Data systems Ltd.";
- case 20: return "Princo Corporation";
- case 30: return "Pioneer Video Corporation";
- case 40: return "Kodak Japan Ltd.";
- case 50: return "Mitsui Chemicals, Inc.";
- case 60: return "Ricoh Company Ltd.";
- }
-
- break;
- case 28:
- switch(frm)
- {
- case 00: return "Opti.Me.S. S.p.A.";
- case 10: return "Gigastore Corporation";
- case 20: return "Multi Media Masters & Machinary SA";
- case 30: return "Auvistar Industry Co., Ltd.";
- case 40: return "King Pro Mediatek Inc.";
- case 50: return "Delphi Technology Inc.";
- case 60: return "Friendly CD-Tek Co.";
- }
-
- break;
- case 29:
- switch(frm)
- {
- case 00: return "Taeil Media Co., Ltd.";
- case 10: return "Vanguard Disc Inc.";
- case 20: return "Unidisc Technology Co., Ltd.";
- case 30: return "Hile Optical Disc Technology Corp.";
- case 40: return "Viva Magnetics Ltd.";
- case 50: return "General Magnetics Ltd.";
- }
-
- break;
- case 30:
- if(frm == 10)
- return "CDA Datenträger Albrechts GmbH";
-
- break;
- case 31:
- switch(frm)
- {
- case 00: return "Ritek Co.";
- case 30: return "Grand Advance Technology Ltd.";
- }
-
- break;
- case 32:
- switch(frm)
- {
- case 00: return "TDK Corporation";
- case 10: return "Prodisc Technology Inc.";
- }
-
- break;
- case 34:
- switch(frm)
- {
- case 20:
- case 22: return "Mitsubishi Chemical Corporation";
- }
-
- break;
- case 36:
- switch(frm)
- {
- case 00: return "Gish International Co., Ltd.";
- }
-
- break;
- case 42:
- if(frm == 20)
- return "Advanced Digital Media";
-
- break;
- case 45:
- switch(frm)
- {
- case 00: return "Fornet International Pte Ltd.";
- case 10: return "Unitech Japan Inc.";
- case 20: return "Acer Media Technology, Inc.";
- case 40: return "CIS Technology Inc.";
- case 50: return "Guann Yinn Co., Ltd.";
- case 60: return "Xcitec Inc.";
- }
-
- break;
- case 46:
- switch(frm)
- {
- case 00: return "Taiyo Yuden Company Ltd.";
- case 10: return "Hong Kong Digital Technology Co., Ltd.";
- case 20: return "Multi Media Masters & Machinary SA";
- case 30: return "Computer Support Italy s.r.l.";
- case 40: return "FUJI Photo Film Co., Ltd.";
- case 50: return "Auvistar Industry Co., Ltd.";
- case 60: return "CMC Magnetics Corporation";
- }
-
- break;
- case 47:
- switch(frm)
- {
- case 10: return "Hitachi Maxell, Ltd.";
- case 20: return "Princo Corporation";
- case 40: return "POSTECH Corporation";
- case 50: return "Ritek Co.";
- case 60: return "Prodisc Technology Inc.";
- }
-
- break;
- case 48:
- switch(frm)
- {
- case 00: return "Ricoh Company Ltd.";
- case 10: return "Kodak Japan Ltd.";
- case 20: return "Plasmon Data systems Ltd.";
- case 30: return "Pioneer Video Corporation";
- case 40: return "Digital Storage Technology Co., Ltd.";
- case 50: return "Mitsui Chemicals, Inc.";
- case 60: return "Lead Data Inc.";
- }
-
- break;
- case 49:
- switch(frm)
- {
- case 00: return "TDK Corporation";
- case 10: return "Gigastore Corporation";
- case 20: return "King Pro Mediatek Inc.";
- case 30: return "Opti.Me.S. S.p.A.";
- case 40: return "Victor Company of Japan, Ltd.";
- case 60: return "Matsushita Electric Industrial Co., Ltd.";
- }
-
- break;
- case 50:
- switch(frm)
- {
- case 10: return "Vanguard Disc Inc.";
- case 20: return "Mitsubishi Chemical Corporation";
- case 30: return "CDA Datenträger Albrechts GmbH";
- }
-
- break;
- case 51:
- switch(frm)
- {
- case 10: return "Grand Advance Technology Ltd.";
- case 20: return "Infodisc Technology Co. Ltd.";
- case 50: return "Hile Optical Disc Technology Corp.";
- }
-
- break;
- }
-
- return "";
- }
-
- public class CDATIP
- {
- /// Byte 6, bit 2 A1 values are valid
- public bool A1Valid;
- /// Bytes 16 to 18 A1 values
- public byte[] A1Values;
- /// Byte 6, bit 1 A2 values are valid
- public bool A2Valid;
- /// Bytes 20 to 22 A2 values
- public byte[] A2Values;
- /// Byte 6, bit 0 A3 values are valid
- public bool A3Valid;
- /// Bytes 24 to 26 A3 values
- public byte[] A3Values;
- /// Byte 6, bit 7 Always set
- public bool AlwaysOne;
- /// Byte 5, bit 7 Always unset
- public bool AlwaysZero;
- /// Bytes 1 to 0 Total size of returned session information minus this field
- public ushort DataLength;
- /// Byte 4, bit 3 Set if DDCD
- public bool DDCD;
- /// Byte 6, bits 5 to 3 Disc subtype
- public byte DiscSubType;
- /// Byte 6, bit 6 Set if rewritable (CD-RW or DDCD-RW)
- public bool DiscType;
- /// Byte 4, bits 7 to 4 Indicative target writing power
- public byte ITWP;
- /// Byte 10 ATIP Start time of Lead-In (Frame)
- public byte LeadInStartFrame;
- /// Byte 8 ATIP Start time of Lead-In (Minute)
- public byte LeadInStartMin;
- /// Byte 9 ATIP Start time of Lead-In (Second)
- public byte LeadInStartSec;
- /// Byte 14 ATIP Last possible start time of Lead-Out (Frame)
- public byte LeadOutStartFrame;
- /// Byte 12 ATIP Last possible start time of Lead-Out (Minute)
- public byte LeadOutStartMin;
- /// Byte 13 ATIP Last possible start time of Lead-Out (Second)
- public byte LeadOutStartSec;
- /// Byte 4, bits 2 to 0 Reference speed
- public byte ReferenceSpeed;
- /// Byte 2 Reserved
- public byte Reserved1;
- /// Byte 31 Reserved
- public byte Reserved10;
- /// Byte 3 Reserved
- public byte Reserved2;
- /// Byte 5, bits 5 to 0 Reserved
- public byte Reserved3;
- /// Byte 7 Reserved
- public byte Reserved4;
- /// Byte 11 Reserved
- public byte Reserved5;
- /// Byte 15 Reserved
- public byte Reserved6;
- /// Byte 19 Reserved
- public byte Reserved7;
- /// Byte 23 Reserved
- public byte Reserved8;
- /// Byte 27 Reserved
- public byte Reserved9;
- /// Bytes 28 to 30 S4 values
- public byte[] S4Values;
- /// Byte 5, bit 6 Unrestricted media
- public bool URU;
- }
+ public class CDATIP
+ {
+ /// Byte 6, bit 2 A1 values are valid
+ public bool A1Valid;
+ /// Bytes 16 to 18 A1 values
+ public byte[] A1Values;
+ /// Byte 6, bit 1 A2 values are valid
+ public bool A2Valid;
+ /// Bytes 20 to 22 A2 values
+ public byte[] A2Values;
+ /// Byte 6, bit 0 A3 values are valid
+ public bool A3Valid;
+ /// Bytes 24 to 26 A3 values
+ public byte[] A3Values;
+ /// Byte 6, bit 7 Always set
+ public bool AlwaysOne;
+ /// Byte 5, bit 7 Always unset
+ public bool AlwaysZero;
+ /// Bytes 1 to 0 Total size of returned session information minus this field
+ public ushort DataLength;
+ /// Byte 4, bit 3 Set if DDCD
+ public bool DDCD;
+ /// Byte 6, bits 5 to 3 Disc subtype
+ public byte DiscSubType;
+ /// Byte 6, bit 6 Set if rewritable (CD-RW or DDCD-RW)
+ public bool DiscType;
+ /// Byte 4, bits 7 to 4 Indicative target writing power
+ public byte ITWP;
+ /// Byte 10 ATIP Start time of Lead-In (Frame)
+ public byte LeadInStartFrame;
+ /// Byte 8 ATIP Start time of Lead-In (Minute)
+ public byte LeadInStartMin;
+ /// Byte 9 ATIP Start time of Lead-In (Second)
+ public byte LeadInStartSec;
+ /// Byte 14 ATIP Last possible start time of Lead-Out (Frame)
+ public byte LeadOutStartFrame;
+ /// Byte 12 ATIP Last possible start time of Lead-Out (Minute)
+ public byte LeadOutStartMin;
+ /// Byte 13 ATIP Last possible start time of Lead-Out (Second)
+ public byte LeadOutStartSec;
+ /// Byte 4, bits 2 to 0 Reference speed
+ public byte ReferenceSpeed;
+ /// Byte 2 Reserved
+ public byte Reserved1;
+ /// Byte 31 Reserved
+ public byte Reserved10;
+ /// Byte 3 Reserved
+ public byte Reserved2;
+ /// Byte 5, bits 5 to 0 Reserved
+ public byte Reserved3;
+ /// Byte 7 Reserved
+ public byte Reserved4;
+ /// Byte 11 Reserved
+ public byte Reserved5;
+ /// Byte 15 Reserved
+ public byte Reserved6;
+ /// Byte 19 Reserved
+ public byte Reserved7;
+ /// Byte 23 Reserved
+ public byte Reserved8;
+ /// Byte 27 Reserved
+ public byte Reserved9;
+ /// Bytes 28 to 30 S4 values
+ public byte[] S4Values;
+ /// Byte 5, bit 6 Unrestricted media
+ public bool URU;
}
}
\ No newline at end of file
diff --git a/CD/CDTextOnLeadIn.cs b/CD/CDTextOnLeadIn.cs
index 1a808d5..1448d0e 100644
--- a/CD/CDTextOnLeadIn.cs
+++ b/CD/CDTextOnLeadIn.cs
@@ -36,342 +36,341 @@ using System.Text;
using Aaru.Console;
using Aaru.Helpers;
-namespace Aaru.Decoders.CD
+namespace Aaru.Decoders.CD;
+
+// Information from the following standards:
+// ANSI X3.304-1997
+// T10/1048-D revision 9.0
+// T10/1048-D revision 10a
+// T10/1228-D revision 7.0c
+// T10/1228-D revision 11a
+// T10/1363-D revision 10g
+// T10/1545-D revision 1d
+// T10/1545-D revision 5
+// T10/1545-D revision 5a
+// T10/1675-D revision 2c
+// T10/1675-D revision 4
+// T10/1836-D revision 2g
+[SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"),
+ SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), SuppressMessage("ReSharper", "NotAccessedField.Global")]
+public static class CDTextOnLeadIn
{
- // Information from the following standards:
- // ANSI X3.304-1997
- // T10/1048-D revision 9.0
- // T10/1048-D revision 10a
- // T10/1228-D revision 7.0c
- // T10/1228-D revision 11a
- // T10/1363-D revision 10g
- // T10/1545-D revision 1d
- // T10/1545-D revision 5
- // T10/1545-D revision 5a
- // T10/1675-D revision 2c
- // T10/1675-D revision 4
- // T10/1836-D revision 2g
- [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"),
- SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), SuppressMessage("ReSharper", "NotAccessedField.Global")]
- public static class CDTextOnLeadIn
+ public enum PackTypeIndicator : byte
{
- public enum PackTypeIndicator : byte
+ /// Title of the track (or album if track == 0)
+ Title = 0x80,
+ /// Performer
+ Performer = 0x81,
+ /// Songwriter
+ Songwriter = 0x82,
+ /// Composer
+ Composer = 0x83,
+ /// Arranger
+ Arranger = 0x84,
+ /// Message from the content provider or artist
+ Message = 0x85,
+ /// Disc identification information
+ DiscIdentification = 0x86,
+ /// Genre identification
+ GenreIdentification = 0x87,
+ /// Table of content information
+ TOCInformation = 0x88,
+ /// Second table of content information
+ SecondTOCInformation = 0x89,
+ /// Reserved
+ Reserved1 = 0x8A,
+ /// Reserved
+ Reserved2 = 0x8B,
+ /// Reserved
+ Reserved3 = 0x8C,
+ /// Reserved for content provider only
+ ReservedForContentProvider = 0x8D,
+ /// UPC of album or ISRC of track
+ UPCorISRC = 0x8E,
+ /// Size information of the block
+ BlockSizeInformation = 0x8F
+ }
+
+ public static CDText? Decode(byte[] CDTextResponse)
+ {
+ if(CDTextResponse == null ||
+ CDTextResponse.Length <= 4)
+ return null;
+
+ var decoded = new CDText
{
- /// Title of the track (or album if track == 0)
- Title = 0x80,
- /// Performer
- Performer = 0x81,
- /// Songwriter
- Songwriter = 0x82,
- /// Composer
- Composer = 0x83,
- /// Arranger
- Arranger = 0x84,
- /// Message from the content provider or artist
- Message = 0x85,
- /// Disc identification information
- DiscIdentification = 0x86,
- /// Genre identification
- GenreIdentification = 0x87,
- /// Table of content information
- TOCInformation = 0x88,
- /// Second table of content information
- SecondTOCInformation = 0x89,
- /// Reserved
- Reserved1 = 0x8A,
- /// Reserved
- Reserved2 = 0x8B,
- /// Reserved
- Reserved3 = 0x8C,
- /// Reserved for content provider only
- ReservedForContentProvider = 0x8D,
- /// UPC of album or ISRC of track
- UPCorISRC = 0x8E,
- /// Size information of the block
- BlockSizeInformation = 0x8F
+ DataLength = BigEndianBitConverter.ToUInt16(CDTextResponse, 0),
+ Reserved1 = CDTextResponse[2],
+ Reserved2 = CDTextResponse[3]
+ };
+
+ decoded.DataPacks = new CDTextPack[(decoded.DataLength - 2) / 18];
+
+ if(decoded.DataLength == 2)
+ return null;
+
+ if(decoded.DataLength + 2 != CDTextResponse.Length)
+ {
+ AaruConsole.DebugWriteLine("CD-TEXT decoder",
+ "Expected CD-TEXT size ({0} bytes) is not received size ({1} bytes), not decoding",
+ decoded.DataLength + 2, CDTextResponse.Length);
+
+ return null;
}
- public static CDText? Decode(byte[] CDTextResponse)
+ for(int i = 0; i < (decoded.DataLength - 2) / 18; i++)
{
- if(CDTextResponse == null ||
- CDTextResponse.Length <= 4)
- return null;
-
- var decoded = new CDText
- {
- DataLength = BigEndianBitConverter.ToUInt16(CDTextResponse, 0),
- Reserved1 = CDTextResponse[2],
- Reserved2 = CDTextResponse[3]
- };
-
- decoded.DataPacks = new CDTextPack[(decoded.DataLength - 2) / 18];
-
- if(decoded.DataLength == 2)
- return null;
-
- if(decoded.DataLength + 2 != CDTextResponse.Length)
- {
- AaruConsole.DebugWriteLine("CD-TEXT decoder",
- "Expected CD-TEXT size ({0} bytes) is not received size ({1} bytes), not decoding",
- decoded.DataLength + 2, CDTextResponse.Length);
-
- return null;
- }
-
- for(int i = 0; i < (decoded.DataLength - 2) / 18; i++)
- {
- decoded.DataPacks[i].HeaderID1 = CDTextResponse[0 + (i * 18) + 4];
- decoded.DataPacks[i].HeaderID2 = CDTextResponse[1 + (i * 18) + 4];
- decoded.DataPacks[i].HeaderID3 = CDTextResponse[2 + (i * 18) + 4];
- decoded.DataPacks[i].DBCC = Convert.ToBoolean(CDTextResponse[3 + (i * 18) + 4] & 0x80);
- decoded.DataPacks[i].BlockNumber = (byte)((CDTextResponse[3 + (i * 18) + 4] & 0x70) >> 4);
- decoded.DataPacks[i].CharacterPosition = (byte)(CDTextResponse[3 + (i * 18) + 4] & 0x0F);
- decoded.DataPacks[i].TextDataField = new byte[12];
- Array.Copy(CDTextResponse, 4 + (i * 18) + 4, decoded.DataPacks[i].TextDataField, 0, 12);
- decoded.DataPacks[i].CRC = BigEndianBitConverter.ToUInt16(CDTextResponse, 16 + (i * 18) + 4);
- }
-
- return decoded;
+ decoded.DataPacks[i].HeaderID1 = CDTextResponse[0 + (i * 18) + 4];
+ decoded.DataPacks[i].HeaderID2 = CDTextResponse[1 + (i * 18) + 4];
+ decoded.DataPacks[i].HeaderID3 = CDTextResponse[2 + (i * 18) + 4];
+ decoded.DataPacks[i].DBCC = Convert.ToBoolean(CDTextResponse[3 + (i * 18) + 4] & 0x80);
+ decoded.DataPacks[i].BlockNumber = (byte)((CDTextResponse[3 + (i * 18) + 4] & 0x70) >> 4);
+ decoded.DataPacks[i].CharacterPosition = (byte)(CDTextResponse[3 + (i * 18) + 4] & 0x0F);
+ decoded.DataPacks[i].TextDataField = new byte[12];
+ Array.Copy(CDTextResponse, 4 + (i * 18) + 4, decoded.DataPacks[i].TextDataField, 0, 12);
+ decoded.DataPacks[i].CRC = BigEndianBitConverter.ToUInt16(CDTextResponse, 16 + (i * 18) + 4);
}
- public static string Prettify(CDText? CDTextResponse)
- {
- if(CDTextResponse == null)
- return null;
+ return decoded;
+ }
- CDText response = CDTextResponse.Value;
- var sb = new StringBuilder();
+ public static string Prettify(CDText? CDTextResponse)
+ {
+ if(CDTextResponse == null)
+ return null;
- #if DEBUG
- if(response.Reserved1 != 0)
- sb.AppendFormat("Reserved1 = 0x{0:X2}", response.Reserved1).AppendLine();
+ CDText response = CDTextResponse.Value;
+ var sb = new StringBuilder();
- if(response.Reserved2 != 0)
- sb.AppendFormat("Reserved2 = 0x{0:X2}", response.Reserved2).AppendLine();
- #endif
+ #if DEBUG
+ if(response.Reserved1 != 0)
+ sb.AppendFormat("Reserved1 = 0x{0:X2}", response.Reserved1).AppendLine();
- foreach(CDTextPack descriptor in response.DataPacks)
- if((descriptor.HeaderID1 & 0x80) != 0x80)
+ if(response.Reserved2 != 0)
+ sb.AppendFormat("Reserved2 = 0x{0:X2}", response.Reserved2).AppendLine();
+ #endif
+
+ foreach(CDTextPack descriptor in response.DataPacks)
+ if((descriptor.HeaderID1 & 0x80) != 0x80)
+ {
+ // Ignore NOPs
+ if((descriptor.HeaderID1 & 0x80) != 0)
+ sb.AppendFormat("Incorrect CD-Text pack type {0}, not decoding", descriptor.HeaderID1).
+ AppendLine();
+ }
+ else
+ {
+ switch(descriptor.HeaderID1)
{
- // Ignore NOPs
- if((descriptor.HeaderID1 & 0x80) != 0)
- sb.AppendFormat("Incorrect CD-Text pack type {0}, not decoding", descriptor.HeaderID1).
+ case 0x80:
+ {
+ sb.Append("CD-Text pack contains title for ");
+
+ if(descriptor.HeaderID2 == 0x00)
+ sb.AppendLine("album");
+ else
+ sb.AppendFormat("track {0}", descriptor.HeaderID2).AppendLine();
+
+ break;
+ }
+
+ case 0x81:
+ {
+ sb.Append("CD-Text pack contains performer for ");
+
+ if(descriptor.HeaderID2 == 0x00)
+ sb.AppendLine("album");
+ else
+ sb.AppendFormat("track {0}", descriptor.HeaderID2).AppendLine();
+
+ break;
+ }
+
+ case 0x82:
+ {
+ sb.Append("CD-Text pack contains songwriter for ");
+
+ if(descriptor.HeaderID2 == 0x00)
+ sb.AppendLine("album");
+ else
+ sb.AppendFormat("track {0}", descriptor.HeaderID2).AppendLine();
+
+ break;
+ }
+
+ case 0x83:
+ {
+ if(descriptor.HeaderID2 == 0x00)
+ sb.AppendLine("album");
+ else
+ sb.AppendFormat("track {0}", descriptor.HeaderID2).AppendLine();
+
+ break;
+ }
+
+ case 0x84:
+ {
+ sb.Append("CD-Text pack contains arranger for ");
+
+ if(descriptor.HeaderID2 == 0x00)
+ sb.AppendLine("album");
+ else
+ sb.AppendFormat("track {0}", descriptor.HeaderID2).AppendLine();
+
+ break;
+ }
+
+ case 0x85:
+ {
+ sb.Append("CD-Text pack contains content provider's message for ");
+
+ if(descriptor.HeaderID2 == 0x00)
+ sb.AppendLine("album");
+ else
+ sb.AppendFormat("track {0}", descriptor.HeaderID2).AppendLine();
+
+ break;
+ }
+
+ case 0x86:
+ {
+ sb.AppendLine("CD-Text pack contains disc identification information");
+
+ break;
+ }
+
+ case 0x87:
+ {
+ sb.AppendLine("CD-Text pack contains genre identification information");
+
+ break;
+ }
+
+ case 0x88:
+ {
+ sb.AppendLine("CD-Text pack contains table of contents information");
+
+ break;
+ }
+
+ case 0x89:
+ {
+ sb.AppendLine("CD-Text pack contains second table of contents information");
+
+ break;
+ }
+
+ case 0x8A:
+ case 0x8B:
+ case 0x8C:
+ {
+ sb.AppendLine("CD-Text pack contains reserved data");
+
+ break;
+ }
+
+ case 0x8D:
+ {
+ sb.AppendLine("CD-Text pack contains data reserved for content provider only");
+
+ break;
+ }
+
+ case 0x8E:
+ {
+ if(descriptor.HeaderID2 == 0x00)
+ sb.AppendLine("CD-Text pack contains UPC");
+ else
+ sb.AppendFormat("track {0}", descriptor.HeaderID2).AppendLine();
+
+ break;
+ }
+
+ case 0x8F:
+ {
+ sb.AppendLine("CD-Text pack contains size block information");
+
+ break;
+ }
+ }
+
+ switch(descriptor.HeaderID1)
+ {
+ case 0x80:
+ case 0x81:
+ case 0x82:
+ case 0x83:
+ case 0x84:
+ case 0x85:
+ case 0x86:
+ case 0x87:
+ case 0x8E:
+ {
+ if(descriptor.DBCC)
+ sb.AppendLine("Double Byte Character Code is used");
+
+ sb.AppendFormat("Block number {0}", descriptor.BlockNumber).AppendLine();
+ sb.AppendFormat("Character position {0}", descriptor.CharacterPosition).AppendLine();
+
+ sb.AppendFormat("Text field: \"{0}\"",
+ StringHandlers.CToString(descriptor.TextDataField,
+ Encoding.GetEncoding("iso-8859-1"))).AppendLine();
+
+ break;
+ }
+
+ default:
+ {
+ sb.AppendFormat("Binary contents: {0}",
+ PrintHex.ByteArrayToHexArrayString(descriptor.TextDataField, 28)).
AppendLine();
- }
- else
- {
- switch(descriptor.HeaderID1)
- {
- case 0x80:
- {
- sb.Append("CD-Text pack contains title for ");
- if(descriptor.HeaderID2 == 0x00)
- sb.AppendLine("album");
- else
- sb.AppendFormat("track {0}", descriptor.HeaderID2).AppendLine();
-
- break;
- }
-
- case 0x81:
- {
- sb.Append("CD-Text pack contains performer for ");
-
- if(descriptor.HeaderID2 == 0x00)
- sb.AppendLine("album");
- else
- sb.AppendFormat("track {0}", descriptor.HeaderID2).AppendLine();
-
- break;
- }
-
- case 0x82:
- {
- sb.Append("CD-Text pack contains songwriter for ");
-
- if(descriptor.HeaderID2 == 0x00)
- sb.AppendLine("album");
- else
- sb.AppendFormat("track {0}", descriptor.HeaderID2).AppendLine();
-
- break;
- }
-
- case 0x83:
- {
- if(descriptor.HeaderID2 == 0x00)
- sb.AppendLine("album");
- else
- sb.AppendFormat("track {0}", descriptor.HeaderID2).AppendLine();
-
- break;
- }
-
- case 0x84:
- {
- sb.Append("CD-Text pack contains arranger for ");
-
- if(descriptor.HeaderID2 == 0x00)
- sb.AppendLine("album");
- else
- sb.AppendFormat("track {0}", descriptor.HeaderID2).AppendLine();
-
- break;
- }
-
- case 0x85:
- {
- sb.Append("CD-Text pack contains content provider's message for ");
-
- if(descriptor.HeaderID2 == 0x00)
- sb.AppendLine("album");
- else
- sb.AppendFormat("track {0}", descriptor.HeaderID2).AppendLine();
-
- break;
- }
-
- case 0x86:
- {
- sb.AppendLine("CD-Text pack contains disc identification information");
-
- break;
- }
-
- case 0x87:
- {
- sb.AppendLine("CD-Text pack contains genre identification information");
-
- break;
- }
-
- case 0x88:
- {
- sb.AppendLine("CD-Text pack contains table of contents information");
-
- break;
- }
-
- case 0x89:
- {
- sb.AppendLine("CD-Text pack contains second table of contents information");
-
- break;
- }
-
- case 0x8A:
- case 0x8B:
- case 0x8C:
- {
- sb.AppendLine("CD-Text pack contains reserved data");
-
- break;
- }
-
- case 0x8D:
- {
- sb.AppendLine("CD-Text pack contains data reserved for content provider only");
-
- break;
- }
-
- case 0x8E:
- {
- if(descriptor.HeaderID2 == 0x00)
- sb.AppendLine("CD-Text pack contains UPC");
- else
- sb.AppendFormat("track {0}", descriptor.HeaderID2).AppendLine();
-
- break;
- }
-
- case 0x8F:
- {
- sb.AppendLine("CD-Text pack contains size block information");
-
- break;
- }
+ break;
}
-
- switch(descriptor.HeaderID1)
- {
- case 0x80:
- case 0x81:
- case 0x82:
- case 0x83:
- case 0x84:
- case 0x85:
- case 0x86:
- case 0x87:
- case 0x8E:
- {
- if(descriptor.DBCC)
- sb.AppendLine("Double Byte Character Code is used");
-
- sb.AppendFormat("Block number {0}", descriptor.BlockNumber).AppendLine();
- sb.AppendFormat("Character position {0}", descriptor.CharacterPosition).AppendLine();
-
- sb.AppendFormat("Text field: \"{0}\"",
- StringHandlers.CToString(descriptor.TextDataField,
- Encoding.GetEncoding("iso-8859-1"))).AppendLine();
-
- break;
- }
-
- default:
- {
- sb.AppendFormat("Binary contents: {0}",
- PrintHex.ByteArrayToHexArrayString(descriptor.TextDataField, 28)).
- AppendLine();
-
- break;
- }
- }
-
- sb.AppendFormat("CRC: 0x{0:X4}", descriptor.CRC).AppendLine();
}
- return sb.ToString();
- }
+ sb.AppendFormat("CRC: 0x{0:X4}", descriptor.CRC).AppendLine();
+ }
- public static string Prettify(byte[] CDTextResponse)
- {
- CDText? decoded = Decode(CDTextResponse);
+ return sb.ToString();
+ }
- return Prettify(decoded);
- }
+ public static string Prettify(byte[] CDTextResponse)
+ {
+ CDText? decoded = Decode(CDTextResponse);
- public struct CDText
- {
- /// Total size of returned CD-Text information minus this field
- public ushort DataLength;
- /// Reserved
- public byte Reserved1;
- /// Reserved
- public byte Reserved2;
- /// CD-Text data packs
- public CDTextPack[] DataPacks;
- }
+ return Prettify(decoded);
+ }
- public struct CDTextPack
- {
- /// Byte 0 Pack ID1 (Pack Type)
- public byte HeaderID1;
- /// Byte 1 Pack ID2 (Track number)
- public byte HeaderID2;
- /// Byte 2 Pack ID3
- public byte HeaderID3;
- /// Byte 3, bit 7 Double Byte Character Code
- public bool DBCC;
- /// Byte 3, bits 6 to 4 Block number
- public byte BlockNumber;
- /// Byte 3, bits 3 to 0 Character position
- public byte CharacterPosition;
- /// Bytes 4 to 15 Text data
- public byte[] TextDataField;
- /// Bytes 16 to 17 CRC16
- public ushort CRC;
- }
+ public struct CDText
+ {
+ /// Total size of returned CD-Text information minus this field
+ public ushort DataLength;
+ /// Reserved
+ public byte Reserved1;
+ /// Reserved
+ public byte Reserved2;
+ /// CD-Text data packs
+ public CDTextPack[] DataPacks;
+ }
+
+ public struct CDTextPack
+ {
+ /// Byte 0 Pack ID1 (Pack Type)
+ public byte HeaderID1;
+ /// Byte 1 Pack ID2 (Track number)
+ public byte HeaderID2;
+ /// Byte 2 Pack ID3
+ public byte HeaderID3;
+ /// Byte 3, bit 7 Double Byte Character Code
+ public bool DBCC;
+ /// Byte 3, bits 6 to 4 Block number
+ public byte BlockNumber;
+ /// Byte 3, bits 3 to 0 Character position
+ public byte CharacterPosition;
+ /// Bytes 4 to 15 Text data
+ public byte[] TextDataField;
+ /// Bytes 16 to 17 CRC16
+ public ushort CRC;
}
}
\ No newline at end of file
diff --git a/CD/Enums.cs b/CD/Enums.cs
index 63746ce..ea42e6c 100644
--- a/CD/Enums.cs
+++ b/CD/Enums.cs
@@ -32,42 +32,41 @@
using System.Diagnostics.CodeAnalysis;
-namespace Aaru.Decoders.CD
-{
- [SuppressMessage("ReSharper", "MemberCanBeInternal")]
- public enum TocAdr : byte
- {
- /// Q Sub-channel mode information not supplied
- NoInformation = 0x00,
- /// Q Sub-channel encodes current position data
- CurrentPosition = 0x01,
- /// Q Sub-channel encodes the media catalog number
- MediaCatalogNumber = 0x02,
- /// Q Sub-channel encodes the ISRC
- ISRC = 0x03,
- /// Q Sub-channel encodes the start of an audio/data track (if found in TOC)
- TrackPointer = 0x01,
- /// Q Sub-channel encodes the start of a video track (if found in TOC) for CD-V
- VideoTrackPointer = 0x04
- }
+namespace Aaru.Decoders.CD;
- public enum TocControl : byte
- {
- /// Stereo audio, no pre-emphasis
- TwoChanNoPreEmph = 0x00,
- /// Stereo audio with pre-emphasis
- TwoChanPreEmph = 0x01,
- /// If mask applied, track can be copied
- CopyPermissionMask = 0x02,
- /// Data track, recorded uninterrumpted
- DataTrack = 0x04,
- /// Data track, recorded incrementally
- DataTrackIncremental = 0x05,
- /// Quadraphonic audio, no pre-emphasis
- FourChanNoPreEmph = 0x08,
- /// Quadraphonic audio with pre-emphasis
- FourChanPreEmph = 0x09,
- /// Reserved mask
- ReservedMask = 0x0C
- }
+[SuppressMessage("ReSharper", "MemberCanBeInternal")]
+public enum TocAdr : byte
+{
+ /// Q Sub-channel mode information not supplied
+ NoInformation = 0x00,
+ /// Q Sub-channel encodes current position data
+ CurrentPosition = 0x01,
+ /// Q Sub-channel encodes the media catalog number
+ MediaCatalogNumber = 0x02,
+ /// Q Sub-channel encodes the ISRC
+ ISRC = 0x03,
+ /// Q Sub-channel encodes the start of an audio/data track (if found in TOC)
+ TrackPointer = 0x01,
+ /// Q Sub-channel encodes the start of a video track (if found in TOC) for CD-V
+ VideoTrackPointer = 0x04
+}
+
+public enum TocControl : byte
+{
+ /// Stereo audio, no pre-emphasis
+ TwoChanNoPreEmph = 0x00,
+ /// Stereo audio with pre-emphasis
+ TwoChanPreEmph = 0x01,
+ /// If mask applied, track can be copied
+ CopyPermissionMask = 0x02,
+ /// Data track, recorded uninterrumpted
+ DataTrack = 0x04,
+ /// Data track, recorded incrementally
+ DataTrackIncremental = 0x05,
+ /// Quadraphonic audio, no pre-emphasis
+ FourChanNoPreEmph = 0x08,
+ /// Quadraphonic audio with pre-emphasis
+ FourChanPreEmph = 0x09,
+ /// Reserved mask
+ ReservedMask = 0x0C
}
\ No newline at end of file
diff --git a/CD/FullTOC.cs b/CD/FullTOC.cs
index 5d1471a..6a6ba63 100644
--- a/CD/FullTOC.cs
+++ b/CD/FullTOC.cs
@@ -39,748 +39,747 @@ using Aaru.CommonTypes.Structs;
using Aaru.Console;
using Aaru.Helpers;
-namespace Aaru.Decoders.CD
+namespace Aaru.Decoders.CD;
+
+// Information from the following standards:
+// ANSI X3.304-1997
+// T10/1048-D revision 9.0
+// T10/1048-D revision 10a
+// T10/1228-D revision 7.0c
+// T10/1228-D revision 11a
+// T10/1363-D revision 10g
+// T10/1545-D revision 1d
+// T10/1545-D revision 5
+// T10/1545-D revision 5a
+// T10/1675-D revision 2c
+// T10/1675-D revision 4
+// T10/1836-D revision 2g
+// ISO/IEC 61104: Compact disc video system - 12 cm CD-V
+// ISO/IEC 60908: Audio recording - Compact disc digital audio system
+[SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"),
+ SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
+public static class FullTOC
{
- // Information from the following standards:
- // ANSI X3.304-1997
- // T10/1048-D revision 9.0
- // T10/1048-D revision 10a
- // T10/1228-D revision 7.0c
- // T10/1228-D revision 11a
- // T10/1363-D revision 10g
- // T10/1545-D revision 1d
- // T10/1545-D revision 5
- // T10/1545-D revision 5a
- // T10/1675-D revision 2c
- // T10/1675-D revision 4
- // T10/1836-D revision 2g
- // ISO/IEC 61104: Compact disc video system - 12 cm CD-V
- // ISO/IEC 60908: Audio recording - Compact disc digital audio system
- [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"),
- SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
- public static class FullTOC
+ const string StereoNoPre = "Stereo audio track with no pre-emphasis";
+ const string StereoPreEm = "Stereo audio track with 50/15 μs pre-emphasis";
+ const string QuadNoPreEm = "Quadraphonic audio track with no pre-emphasis";
+ const string QuadPreEmph = "Quadraphonic audio track with 50/15 μs pre-emphasis";
+ const string DataUnintrp = "Data track, recorded uninterrupted";
+ const string DataIncrtly = "Data track, recorded incrementally";
+
+ public static CDFullTOC? Decode(byte[] CDFullTOCResponse)
{
- const string StereoNoPre = "Stereo audio track with no pre-emphasis";
- const string StereoPreEm = "Stereo audio track with 50/15 μs pre-emphasis";
- const string QuadNoPreEm = "Quadraphonic audio track with no pre-emphasis";
- const string QuadPreEmph = "Quadraphonic audio track with 50/15 μs pre-emphasis";
- const string DataUnintrp = "Data track, recorded uninterrupted";
- const string DataIncrtly = "Data track, recorded incrementally";
+ if(CDFullTOCResponse == null ||
+ CDFullTOCResponse.Length <= 4)
+ return null;
- public static CDFullTOC? Decode(byte[] CDFullTOCResponse)
+ var decoded = new CDFullTOC
{
- if(CDFullTOCResponse == null ||
- CDFullTOCResponse.Length <= 4)
- return null;
+ DataLength = BigEndianBitConverter.ToUInt16(CDFullTOCResponse, 0),
+ FirstCompleteSession = CDFullTOCResponse[2],
+ LastCompleteSession = CDFullTOCResponse[3]
+ };
- var decoded = new CDFullTOC
- {
- DataLength = BigEndianBitConverter.ToUInt16(CDFullTOCResponse, 0),
- FirstCompleteSession = CDFullTOCResponse[2],
- LastCompleteSession = CDFullTOCResponse[3]
- };
+ decoded.TrackDescriptors = new TrackDataDescriptor[(decoded.DataLength - 2) / 11];
- decoded.TrackDescriptors = new TrackDataDescriptor[(decoded.DataLength - 2) / 11];
+ if(decoded.DataLength + 2 != CDFullTOCResponse.Length)
+ {
+ AaruConsole.DebugWriteLine("CD full TOC decoder",
+ "Expected CDFullTOC size ({0} bytes) is not received size ({1} bytes), not decoding",
+ decoded.DataLength + 2, CDFullTOCResponse.Length);
- if(decoded.DataLength + 2 != CDFullTOCResponse.Length)
- {
- AaruConsole.DebugWriteLine("CD full TOC decoder",
- "Expected CDFullTOC size ({0} bytes) is not received size ({1} bytes), not decoding",
- decoded.DataLength + 2, CDFullTOCResponse.Length);
-
- return null;
- }
-
- for(int i = 0; i < (decoded.DataLength - 2) / 11; i++)
- {
- decoded.TrackDescriptors[i].SessionNumber = CDFullTOCResponse[0 + (i * 11) + 4];
- decoded.TrackDescriptors[i].ADR = (byte)((CDFullTOCResponse[1 + (i * 11) + 4] & 0xF0) >> 4);
- decoded.TrackDescriptors[i].CONTROL = (byte)(CDFullTOCResponse[1 + (i * 11) + 4] & 0x0F);
- decoded.TrackDescriptors[i].TNO = CDFullTOCResponse[2 + (i * 11) + 4];
- decoded.TrackDescriptors[i].POINT = CDFullTOCResponse[3 + (i * 11) + 4];
- decoded.TrackDescriptors[i].Min = CDFullTOCResponse[4 + (i * 11) + 4];
- decoded.TrackDescriptors[i].Sec = CDFullTOCResponse[5 + (i * 11) + 4];
- decoded.TrackDescriptors[i].Frame = CDFullTOCResponse[6 + (i * 11) + 4];
- decoded.TrackDescriptors[i].Zero = CDFullTOCResponse[7 + (i * 11) + 4];
- decoded.TrackDescriptors[i].HOUR = (byte)((CDFullTOCResponse[7 + (i * 11) + 4] & 0xF0) >> 4);
- decoded.TrackDescriptors[i].PHOUR = (byte)(CDFullTOCResponse[7 + (i * 11) + 4] & 0x0F);
- decoded.TrackDescriptors[i].PMIN = CDFullTOCResponse[8 + (i * 11) + 4];
- decoded.TrackDescriptors[i].PSEC = CDFullTOCResponse[9 + (i * 11) + 4];
- decoded.TrackDescriptors[i].PFRAME = CDFullTOCResponse[10 + (i * 11) + 4];
- }
-
- return decoded;
+ return null;
}
- public static string Prettify(CDFullTOC? CDFullTOCResponse)
+ for(int i = 0; i < (decoded.DataLength - 2) / 11; i++)
{
- if(CDFullTOCResponse == null)
- return null;
+ decoded.TrackDescriptors[i].SessionNumber = CDFullTOCResponse[0 + (i * 11) + 4];
+ decoded.TrackDescriptors[i].ADR = (byte)((CDFullTOCResponse[1 + (i * 11) + 4] & 0xF0) >> 4);
+ decoded.TrackDescriptors[i].CONTROL = (byte)(CDFullTOCResponse[1 + (i * 11) + 4] & 0x0F);
+ decoded.TrackDescriptors[i].TNO = CDFullTOCResponse[2 + (i * 11) + 4];
+ decoded.TrackDescriptors[i].POINT = CDFullTOCResponse[3 + (i * 11) + 4];
+ decoded.TrackDescriptors[i].Min = CDFullTOCResponse[4 + (i * 11) + 4];
+ decoded.TrackDescriptors[i].Sec = CDFullTOCResponse[5 + (i * 11) + 4];
+ decoded.TrackDescriptors[i].Frame = CDFullTOCResponse[6 + (i * 11) + 4];
+ decoded.TrackDescriptors[i].Zero = CDFullTOCResponse[7 + (i * 11) + 4];
+ decoded.TrackDescriptors[i].HOUR = (byte)((CDFullTOCResponse[7 + (i * 11) + 4] & 0xF0) >> 4);
+ decoded.TrackDescriptors[i].PHOUR = (byte)(CDFullTOCResponse[7 + (i * 11) + 4] & 0x0F);
+ decoded.TrackDescriptors[i].PMIN = CDFullTOCResponse[8 + (i * 11) + 4];
+ decoded.TrackDescriptors[i].PSEC = CDFullTOCResponse[9 + (i * 11) + 4];
+ decoded.TrackDescriptors[i].PFRAME = CDFullTOCResponse[10 + (i * 11) + 4];
+ }
- CDFullTOC response = CDFullTOCResponse.Value;
+ return decoded;
+ }
- var sb = new StringBuilder();
+ public static string Prettify(CDFullTOC? CDFullTOCResponse)
+ {
+ if(CDFullTOCResponse == null)
+ return null;
- int lastSession = 0;
+ CDFullTOC response = CDFullTOCResponse.Value;
- sb.AppendFormat("First complete session number: {0}", response.FirstCompleteSession).AppendLine();
- sb.AppendFormat("Last complete session number: {0}", response.LastCompleteSession).AppendLine();
+ var sb = new StringBuilder();
- foreach(TrackDataDescriptor descriptor in response.TrackDescriptors)
- if((descriptor.CONTROL & 0x08) == 0x08 ||
- (descriptor.ADR != 1 && descriptor.ADR != 5 && descriptor.ADR != 4 && descriptor.ADR != 6) ||
- descriptor.TNO != 0)
+ int lastSession = 0;
+
+ sb.AppendFormat("First complete session number: {0}", response.FirstCompleteSession).AppendLine();
+ sb.AppendFormat("Last complete session number: {0}", response.LastCompleteSession).AppendLine();
+
+ foreach(TrackDataDescriptor descriptor in response.TrackDescriptors)
+ if((descriptor.CONTROL & 0x08) == 0x08 ||
+ (descriptor.ADR != 1 && descriptor.ADR != 5 && descriptor.ADR != 4 && descriptor.ADR != 6) ||
+ descriptor.TNO != 0)
+ {
+ sb.AppendLine("Unknown TOC entry format, printing values as-is");
+ sb.AppendFormat("SessionNumber = {0}", descriptor.SessionNumber).AppendLine();
+ sb.AppendFormat("ADR = {0}", descriptor.ADR).AppendLine();
+ sb.AppendFormat("CONTROL = {0}", descriptor.CONTROL).AppendLine();
+ sb.AppendFormat("TNO = {0}", descriptor.TNO).AppendLine();
+ sb.AppendFormat("POINT = {0}", descriptor.POINT).AppendLine();
+ sb.AppendFormat("Min = {0}", descriptor.Min).AppendLine();
+ sb.AppendFormat("Sec = {0}", descriptor.Sec).AppendLine();
+ sb.AppendFormat("Frame = {0}", descriptor.Frame).AppendLine();
+ sb.AppendFormat("HOUR = {0}", descriptor.HOUR).AppendLine();
+ sb.AppendFormat("PHOUR = {0}", descriptor.PHOUR).AppendLine();
+ sb.AppendFormat("PMIN = {0}", descriptor.PMIN).AppendLine();
+ sb.AppendFormat("PSEC = {0}", descriptor.PSEC).AppendLine();
+ sb.AppendFormat("PFRAME = {0}", descriptor.PFRAME).AppendLine();
+ }
+ else
+ {
+ if(descriptor.SessionNumber > lastSession)
{
- sb.AppendLine("Unknown TOC entry format, printing values as-is");
- sb.AppendFormat("SessionNumber = {0}", descriptor.SessionNumber).AppendLine();
- sb.AppendFormat("ADR = {0}", descriptor.ADR).AppendLine();
- sb.AppendFormat("CONTROL = {0}", descriptor.CONTROL).AppendLine();
- sb.AppendFormat("TNO = {0}", descriptor.TNO).AppendLine();
- sb.AppendFormat("POINT = {0}", descriptor.POINT).AppendLine();
- sb.AppendFormat("Min = {0}", descriptor.Min).AppendLine();
- sb.AppendFormat("Sec = {0}", descriptor.Sec).AppendLine();
- sb.AppendFormat("Frame = {0}", descriptor.Frame).AppendLine();
- sb.AppendFormat("HOUR = {0}", descriptor.HOUR).AppendLine();
- sb.AppendFormat("PHOUR = {0}", descriptor.PHOUR).AppendLine();
- sb.AppendFormat("PMIN = {0}", descriptor.PMIN).AppendLine();
- sb.AppendFormat("PSEC = {0}", descriptor.PSEC).AppendLine();
- sb.AppendFormat("PFRAME = {0}", descriptor.PFRAME).AppendLine();
+ sb.AppendFormat("Session {0}", descriptor.SessionNumber).AppendLine();
+ lastSession = descriptor.SessionNumber;
}
- else
+
+ switch(descriptor.ADR)
{
- if(descriptor.SessionNumber > lastSession)
+ case 1:
+ case 4:
{
- sb.AppendFormat("Session {0}", descriptor.SessionNumber).AppendLine();
- lastSession = descriptor.SessionNumber;
- }
-
- switch(descriptor.ADR)
- {
- case 1:
- case 4:
+ switch(descriptor.POINT)
{
- switch(descriptor.POINT)
+ case 0xA0 when descriptor.ADR == 4:
{
- case 0xA0 when descriptor.ADR == 4:
+ sb.AppendFormat("First video track number: {0}", descriptor.PMIN).AppendLine();
+
+ switch(descriptor.PSEC)
{
- sb.AppendFormat("First video track number: {0}", descriptor.PMIN).AppendLine();
+ case 0x10:
+ sb.AppendLine("CD-V single in NTSC format with digital stereo sound");
- switch(descriptor.PSEC)
- {
- case 0x10:
- sb.AppendLine("CD-V single in NTSC format with digital stereo sound");
+ break;
+ case 0x11:
+ sb.AppendLine("CD-V single in NTSC format with digital bilingual sound");
- break;
- case 0x11:
- sb.AppendLine("CD-V single in NTSC format with digital bilingual sound");
+ break;
+ case 0x12:
+ sb.AppendLine("CD-V disc in NTSC format with digital stereo sound");
- break;
- case 0x12:
- sb.AppendLine("CD-V disc in NTSC format with digital stereo sound");
+ break;
+ case 0x13:
+ sb.AppendLine("CD-V disc in NTSC format with digital bilingual sound");
- break;
- case 0x13:
- sb.AppendLine("CD-V disc in NTSC format with digital bilingual sound");
+ break;
+ case 0x20:
+ sb.AppendLine("CD-V single in PAL format with digital stereo sound");
- break;
- case 0x20:
- sb.AppendLine("CD-V single in PAL format with digital stereo sound");
+ break;
+ case 0x21:
+ sb.AppendLine("CD-V single in PAL format with digital bilingual sound");
- break;
- case 0x21:
- sb.AppendLine("CD-V single in PAL format with digital bilingual sound");
+ break;
+ case 0x22:
+ sb.AppendLine("CD-V disc in PAL format with digital stereo sound");
- break;
- case 0x22:
- sb.AppendLine("CD-V disc in PAL format with digital stereo sound");
+ break;
+ case 0x23:
+ sb.AppendLine("CD-V disc in PAL format with digital bilingual sound");
- break;
- case 0x23:
- sb.AppendLine("CD-V disc in PAL format with digital bilingual sound");
-
- break;
- }
-
- break;
+ break;
}
- case 0xA0 when descriptor.ADR == 1:
- {
- sb.AppendFormat("First track number: {0} (", descriptor.PMIN);
-
- switch((TocControl)(descriptor.CONTROL & 0x0D))
- {
- case TocControl.TwoChanNoPreEmph:
- sb.Append(StereoNoPre);
-
- break;
- case TocControl.TwoChanPreEmph:
- sb.Append(StereoPreEm);
-
- break;
- case TocControl.FourChanNoPreEmph:
- sb.Append(QuadNoPreEm);
-
- break;
- case TocControl.FourChanPreEmph:
- sb.Append(QuadPreEmph);
-
- break;
- case TocControl.DataTrack:
- sb.Append(DataUnintrp);
-
- break;
- case TocControl.DataTrackIncremental:
- sb.Append(DataIncrtly);
-
- break;
- }
-
- sb.AppendLine(")");
- sb.AppendFormat("Disc type: {0}", descriptor.PSEC).AppendLine();
-
- //sb.AppendFormat("Absolute time: {3:D2}:{0:D2}:{1:D2}:{2:D2}", descriptor.Min, descriptor.Sec, descriptor.Frame, descriptor.HOUR).AppendLine();
- break;
- }
-
- case 0xA1 when descriptor.ADR == 4:
- sb.AppendFormat("Last video track number: {0}", descriptor.PMIN).AppendLine();
-
- break;
- case 0xA1 when descriptor.ADR == 1:
- {
- sb.AppendFormat("Last track number: {0} (", descriptor.PMIN);
-
- switch((TocControl)(descriptor.CONTROL & 0x0D))
- {
- case TocControl.TwoChanNoPreEmph:
- sb.Append(StereoNoPre);
-
- break;
- case TocControl.TwoChanPreEmph:
- sb.Append(StereoPreEm);
-
- break;
- case TocControl.FourChanNoPreEmph:
- sb.Append(QuadNoPreEm);
-
- break;
- case TocControl.FourChanPreEmph:
- sb.Append(QuadPreEmph);
-
- break;
- case TocControl.DataTrack:
- sb.Append(DataUnintrp);
-
- break;
- case TocControl.DataTrackIncremental:
- sb.Append(DataIncrtly);
-
- break;
- }
-
- sb.AppendLine(")");
-
- //sb.AppendFormat("Absolute time: {3:D2}:{0:D2}:{1:D2}:{2:D2}", descriptor.Min, descriptor.Sec, descriptor.Frame, descriptor.HOUR).AppendLine();
- break;
- }
-
- case 0xA2:
- {
- if(descriptor.PHOUR > 0)
- sb.AppendFormat("Lead-out start position: {3:D2}:{0:D2}:{1:D2}:{2:D2}",
- descriptor.PMIN, descriptor.PSEC, descriptor.PFRAME,
- descriptor.PHOUR).AppendLine();
- else
- sb.AppendFormat("Lead-out start position: {0:D2}:{1:D2}:{2:D2}",
- descriptor.PMIN, descriptor.PSEC, descriptor.PFRAME).
- AppendLine();
-
- //sb.AppendFormat("Absolute time: {3:D2}:{0:D2}:{1:D2}:{2:D2}", descriptor.Min, descriptor.Sec, descriptor.Frame, descriptor.HOUR).AppendLine();
-
- switch((TocControl)(descriptor.CONTROL & 0x0D))
- {
- case TocControl.TwoChanNoPreEmph:
- case TocControl.TwoChanPreEmph:
- case TocControl.FourChanNoPreEmph:
- case TocControl.FourChanPreEmph:
- sb.AppendLine("Lead-out is audio type");
-
- break;
- case TocControl.DataTrack:
- case TocControl.DataTrackIncremental:
- sb.AppendLine("Lead-out is data type");
-
- break;
- }
-
- break;
- }
-
- case 0xF0:
- {
- sb.AppendFormat("Book type: 0x{0:X2}", descriptor.PMIN);
- sb.AppendFormat("Material type: 0x{0:X2}", descriptor.PSEC);
- sb.AppendFormat("Moment of inertia: 0x{0:X2}", descriptor.PFRAME);
-
- if(descriptor.PHOUR > 0)
- sb.AppendFormat("Absolute time: {3:D2}:{0:D2}:{1:D2}:{2:D2}", descriptor.Min,
- descriptor.Sec, descriptor.Frame, descriptor.HOUR).AppendLine();
- else
- sb.AppendFormat("Absolute time: {0:D2}:{1:D2}:{2:D2}", descriptor.Min,
- descriptor.Sec, descriptor.Frame).AppendLine();
-
- break;
- }
-
- default:
- {
- if(descriptor.POINT >= 0x01 &&
- descriptor.POINT <= 0x63)
- if(descriptor.ADR == 4)
- sb.AppendFormat("Video track {3} starts at: {0:D2}:{1:D2}:{2:D2}",
- descriptor.PMIN, descriptor.PSEC, descriptor.PFRAME,
- descriptor.POINT).AppendLine();
- else
- {
- string type = "Audio";
-
- if((TocControl)(descriptor.CONTROL & 0x0D) == TocControl.DataTrack ||
- (TocControl)(descriptor.CONTROL & 0x0D) ==
- TocControl.DataTrackIncremental)
- type = "Data";
-
- if(descriptor.PHOUR > 0)
- sb.AppendFormat("{5} track {3} starts at: {4:D2}:{0:D2}:{1:D2}:{2:D2} (",
- descriptor.PMIN, descriptor.PSEC, descriptor.PFRAME,
- descriptor.POINT, descriptor.PHOUR, type);
- else
- sb.AppendFormat("{4} track {3} starts at: {0:D2}:{1:D2}:{2:D2} (",
- descriptor.PMIN, descriptor.PSEC, descriptor.PFRAME,
- descriptor.POINT, type);
-
- switch((TocControl)(descriptor.CONTROL & 0x0D))
- {
- case TocControl.TwoChanNoPreEmph:
- sb.Append(StereoNoPre);
-
- break;
- case TocControl.TwoChanPreEmph:
- sb.Append(StereoPreEm);
-
- break;
- case TocControl.FourChanNoPreEmph:
- sb.Append(QuadNoPreEm);
-
- break;
- case TocControl.FourChanPreEmph:
- sb.Append(QuadPreEmph);
-
- break;
- case TocControl.DataTrack:
- sb.Append(DataUnintrp);
-
- break;
- case TocControl.DataTrackIncremental:
- sb.Append(DataIncrtly);
-
- break;
- }
-
- sb.AppendLine(")");
- }
- else
- {
- sb.AppendFormat("ADR = {0}", descriptor.ADR).AppendLine();
- sb.AppendFormat("CONTROL = {0}", descriptor.CONTROL).AppendLine();
- sb.AppendFormat("TNO = {0}", descriptor.TNO).AppendLine();
- sb.AppendFormat("POINT = {0}", descriptor.POINT).AppendLine();
- sb.AppendFormat("Min = {0}", descriptor.Min).AppendLine();
- sb.AppendFormat("Sec = {0}", descriptor.Sec).AppendLine();
- sb.AppendFormat("Frame = {0}", descriptor.Frame).AppendLine();
- sb.AppendFormat("HOUR = {0}", descriptor.HOUR).AppendLine();
- sb.AppendFormat("PHOUR = {0}", descriptor.PHOUR).AppendLine();
- sb.AppendFormat("PMIN = {0}", descriptor.PMIN).AppendLine();
- sb.AppendFormat("PSEC = {0}", descriptor.PSEC).AppendLine();
- sb.AppendFormat("PFRAME = {0}", descriptor.PFRAME).AppendLine();
- }
-
- break;
- }
+ break;
}
- break;
- }
-
- case 5:
- {
- switch(descriptor.POINT)
+ case 0xA0 when descriptor.ADR == 1:
{
- case 0xB0:
+ sb.AppendFormat("First track number: {0} (", descriptor.PMIN);
+
+ switch((TocControl)(descriptor.CONTROL & 0x0D))
{
- if(descriptor.PHOUR > 0)
- {
- sb.
- AppendFormat("Start of next possible program in the recordable area of the disc: {3:D2}:{0:D2}:{1:D2}:{2:D2}",
- descriptor.Min, descriptor.Sec, descriptor.Frame,
- descriptor.HOUR).AppendLine();
+ case TocControl.TwoChanNoPreEmph:
+ sb.Append(StereoNoPre);
- sb.
- AppendFormat("Maximum start of outermost Lead-out in the recordable area of the disc: {3:D2}:{0:D2}:{1:D2}:{2:D2}",
- descriptor.PMIN, descriptor.PSEC, descriptor.PFRAME,
- descriptor.PHOUR).AppendLine();
- }
- else
- {
- sb.
- AppendFormat("Start of next possible program in the recordable area of the disc: {0:D2}:{1:D2}:{2:D2}",
- descriptor.Min, descriptor.Sec, descriptor.Frame).AppendLine();
+ break;
+ case TocControl.TwoChanPreEmph:
+ sb.Append(StereoPreEm);
- sb.
- AppendFormat("Maximum start of outermost Lead-out in the recordable area of the disc: {0:D2}:{1:D2}:{2:D2}",
- descriptor.PMIN, descriptor.PSEC, descriptor.PFRAME).
- AppendLine();
- }
+ break;
+ case TocControl.FourChanNoPreEmph:
+ sb.Append(QuadNoPreEm);
- break;
+ break;
+ case TocControl.FourChanPreEmph:
+ sb.Append(QuadPreEmph);
+
+ break;
+ case TocControl.DataTrack:
+ sb.Append(DataUnintrp);
+
+ break;
+ case TocControl.DataTrackIncremental:
+ sb.Append(DataIncrtly);
+
+ break;
}
- case 0xB1:
+ sb.AppendLine(")");
+ sb.AppendFormat("Disc type: {0}", descriptor.PSEC).AppendLine();
+
+ //sb.AppendFormat("Absolute time: {3:D2}:{0:D2}:{1:D2}:{2:D2}", descriptor.Min, descriptor.Sec, descriptor.Frame, descriptor.HOUR).AppendLine();
+ break;
+ }
+
+ case 0xA1 when descriptor.ADR == 4:
+ sb.AppendFormat("Last video track number: {0}", descriptor.PMIN).AppendLine();
+
+ break;
+ case 0xA1 when descriptor.ADR == 1:
+ {
+ sb.AppendFormat("Last track number: {0} (", descriptor.PMIN);
+
+ switch((TocControl)(descriptor.CONTROL & 0x0D))
{
- sb.AppendFormat("Number of skip interval pointers: {0}", descriptor.PMIN).
+ case TocControl.TwoChanNoPreEmph:
+ sb.Append(StereoNoPre);
+
+ break;
+ case TocControl.TwoChanPreEmph:
+ sb.Append(StereoPreEm);
+
+ break;
+ case TocControl.FourChanNoPreEmph:
+ sb.Append(QuadNoPreEm);
+
+ break;
+ case TocControl.FourChanPreEmph:
+ sb.Append(QuadPreEmph);
+
+ break;
+ case TocControl.DataTrack:
+ sb.Append(DataUnintrp);
+
+ break;
+ case TocControl.DataTrackIncremental:
+ sb.Append(DataIncrtly);
+
+ break;
+ }
+
+ sb.AppendLine(")");
+
+ //sb.AppendFormat("Absolute time: {3:D2}:{0:D2}:{1:D2}:{2:D2}", descriptor.Min, descriptor.Sec, descriptor.Frame, descriptor.HOUR).AppendLine();
+ break;
+ }
+
+ case 0xA2:
+ {
+ if(descriptor.PHOUR > 0)
+ sb.AppendFormat("Lead-out start position: {3:D2}:{0:D2}:{1:D2}:{2:D2}",
+ descriptor.PMIN, descriptor.PSEC, descriptor.PFRAME,
+ descriptor.PHOUR).AppendLine();
+ else
+ sb.AppendFormat("Lead-out start position: {0:D2}:{1:D2}:{2:D2}",
+ descriptor.PMIN, descriptor.PSEC, descriptor.PFRAME).
AppendLine();
- sb.AppendFormat("Number of skip track pointers: {0}", descriptor.PSEC).AppendLine();
+ //sb.AppendFormat("Absolute time: {3:D2}:{0:D2}:{1:D2}:{2:D2}", descriptor.Min, descriptor.Sec, descriptor.Frame, descriptor.HOUR).AppendLine();
- break;
+ switch((TocControl)(descriptor.CONTROL & 0x0D))
+ {
+ case TocControl.TwoChanNoPreEmph:
+ case TocControl.TwoChanPreEmph:
+ case TocControl.FourChanNoPreEmph:
+ case TocControl.FourChanPreEmph:
+ sb.AppendLine("Lead-out is audio type");
+
+ break;
+ case TocControl.DataTrack:
+ case TocControl.DataTrackIncremental:
+ sb.AppendLine("Lead-out is data type");
+
+ break;
}
- case 0xB2:
- case 0xB3:
- case 0xB4:
- {
- sb.AppendFormat("Skip track {0}", descriptor.Min).AppendLine();
- sb.AppendFormat("Skip track {0}", descriptor.Sec).AppendLine();
- sb.AppendFormat("Skip track {0}", descriptor.Frame).AppendLine();
- sb.AppendFormat("Skip track {0}", descriptor.Zero).AppendLine();
- sb.AppendFormat("Skip track {0}", descriptor.PMIN).AppendLine();
- sb.AppendFormat("Skip track {0}", descriptor.PSEC).AppendLine();
- sb.AppendFormat("Skip track {0}", descriptor.PFRAME).AppendLine();
+ break;
+ }
- break;
- }
+ case 0xF0:
+ {
+ sb.AppendFormat("Book type: 0x{0:X2}", descriptor.PMIN);
+ sb.AppendFormat("Material type: 0x{0:X2}", descriptor.PSEC);
+ sb.AppendFormat("Moment of inertia: 0x{0:X2}", descriptor.PFRAME);
- case 0xC0:
- {
- sb.AppendFormat("Optimum recording power: 0x{0:X2}", descriptor.Min).AppendLine();
+ if(descriptor.PHOUR > 0)
+ sb.AppendFormat("Absolute time: {3:D2}:{0:D2}:{1:D2}:{2:D2}", descriptor.Min,
+ descriptor.Sec, descriptor.Frame, descriptor.HOUR).AppendLine();
+ else
+ sb.AppendFormat("Absolute time: {0:D2}:{1:D2}:{2:D2}", descriptor.Min,
+ descriptor.Sec, descriptor.Frame).AppendLine();
- if(descriptor.PHOUR > 0)
- sb.
- AppendFormat("Start time of the first Lead-in area in the disc: {3:D2}:{0:D2}:{1:D2}:{2:D2}",
- descriptor.PMIN, descriptor.PSEC, descriptor.PFRAME,
- descriptor.PHOUR).AppendLine();
+ break;
+ }
+
+ default:
+ {
+ if(descriptor.POINT >= 0x01 &&
+ descriptor.POINT <= 0x63)
+ if(descriptor.ADR == 4)
+ sb.AppendFormat("Video track {3} starts at: {0:D2}:{1:D2}:{2:D2}",
+ descriptor.PMIN, descriptor.PSEC, descriptor.PFRAME,
+ descriptor.POINT).AppendLine();
else
- sb.
- AppendFormat("Start time of the first Lead-in area in the disc: {0:D2}:{1:D2}:{2:D2}",
- descriptor.PMIN, descriptor.PSEC, descriptor.PFRAME).
- AppendLine();
+ {
+ string type = "Audio";
- break;
- }
+ if((TocControl)(descriptor.CONTROL & 0x0D) == TocControl.DataTrack ||
+ (TocControl)(descriptor.CONTROL & 0x0D) ==
+ TocControl.DataTrackIncremental)
+ type = "Data";
- case 0xC1:
+ if(descriptor.PHOUR > 0)
+ sb.AppendFormat("{5} track {3} starts at: {4:D2}:{0:D2}:{1:D2}:{2:D2} (",
+ descriptor.PMIN, descriptor.PSEC, descriptor.PFRAME,
+ descriptor.POINT, descriptor.PHOUR, type);
+ else
+ sb.AppendFormat("{4} track {3} starts at: {0:D2}:{1:D2}:{2:D2} (",
+ descriptor.PMIN, descriptor.PSEC, descriptor.PFRAME,
+ descriptor.POINT, type);
+
+ switch((TocControl)(descriptor.CONTROL & 0x0D))
+ {
+ case TocControl.TwoChanNoPreEmph:
+ sb.Append(StereoNoPre);
+
+ break;
+ case TocControl.TwoChanPreEmph:
+ sb.Append(StereoPreEm);
+
+ break;
+ case TocControl.FourChanNoPreEmph:
+ sb.Append(QuadNoPreEm);
+
+ break;
+ case TocControl.FourChanPreEmph:
+ sb.Append(QuadPreEmph);
+
+ break;
+ case TocControl.DataTrack:
+ sb.Append(DataUnintrp);
+
+ break;
+ case TocControl.DataTrackIncremental:
+ sb.Append(DataIncrtly);
+
+ break;
+ }
+
+ sb.AppendLine(")");
+ }
+ else
{
- sb.AppendFormat("Copy of information of A1 from ATIP found");
+ sb.AppendFormat("ADR = {0}", descriptor.ADR).AppendLine();
+ sb.AppendFormat("CONTROL = {0}", descriptor.CONTROL).AppendLine();
+ sb.AppendFormat("TNO = {0}", descriptor.TNO).AppendLine();
+ sb.AppendFormat("POINT = {0}", descriptor.POINT).AppendLine();
sb.AppendFormat("Min = {0}", descriptor.Min).AppendLine();
sb.AppendFormat("Sec = {0}", descriptor.Sec).AppendLine();
sb.AppendFormat("Frame = {0}", descriptor.Frame).AppendLine();
- sb.AppendFormat("Zero = {0}", descriptor.Zero).AppendLine();
+ sb.AppendFormat("HOUR = {0}", descriptor.HOUR).AppendLine();
+ sb.AppendFormat("PHOUR = {0}", descriptor.PHOUR).AppendLine();
sb.AppendFormat("PMIN = {0}", descriptor.PMIN).AppendLine();
sb.AppendFormat("PSEC = {0}", descriptor.PSEC).AppendLine();
sb.AppendFormat("PFRAME = {0}", descriptor.PFRAME).AppendLine();
-
- break;
}
- case 0xCF:
+ break;
+ }
+ }
+
+ break;
+ }
+
+ case 5:
+ {
+ switch(descriptor.POINT)
+ {
+ case 0xB0:
+ {
+ if(descriptor.PHOUR > 0)
{
- if(descriptor.PHOUR > 0)
- {
- sb.
- AppendFormat("Start position of outer part lead-in area: {3:D2}:{0:D2}:{1:D2}:{2:D2}",
- descriptor.PMIN, descriptor.PSEC, descriptor.PFRAME,
- descriptor.PHOUR).AppendLine();
+ sb.
+ AppendFormat("Start of next possible program in the recordable area of the disc: {3:D2}:{0:D2}:{1:D2}:{2:D2}",
+ descriptor.Min, descriptor.Sec, descriptor.Frame,
+ descriptor.HOUR).AppendLine();
- sb.
- AppendFormat("Stop position of inner part lead-out area: {3:D2}:{0:D2}:{1:D2}:{2:D2}",
- descriptor.Min, descriptor.Sec, descriptor.Frame,
- descriptor.HOUR).AppendLine();
- }
- else
- {
- sb.
- AppendFormat("Start position of outer part lead-in area: {0:D2}:{1:D2}:{2:D2}",
- descriptor.PMIN, descriptor.PSEC, descriptor.PFRAME).
- AppendLine();
-
- sb.
- AppendFormat("Stop position of inner part lead-out area: {0:D2}:{1:D2}:{2:D2}",
- descriptor.Min, descriptor.Sec, descriptor.Frame).AppendLine();
- }
-
- break;
+ sb.
+ AppendFormat("Maximum start of outermost Lead-out in the recordable area of the disc: {3:D2}:{0:D2}:{1:D2}:{2:D2}",
+ descriptor.PMIN, descriptor.PSEC, descriptor.PFRAME,
+ descriptor.PHOUR).AppendLine();
}
-
- default:
+ else
{
- if(descriptor.POINT >= 0x01 &&
- descriptor.POINT <= 0x40)
- {
- sb.
- AppendFormat("Start time for interval that should be skipped: {0:D2}:{1:D2}:{2:D2}",
- descriptor.PMIN, descriptor.PSEC, descriptor.PFRAME).
- AppendLine();
+ sb.
+ AppendFormat("Start of next possible program in the recordable area of the disc: {0:D2}:{1:D2}:{2:D2}",
+ descriptor.Min, descriptor.Sec, descriptor.Frame).AppendLine();
- sb.
- AppendFormat("Ending time for interval that should be skipped: {0:D2}:{1:D2}:{2:D2}",
- descriptor.Min, descriptor.Sec, descriptor.Frame).AppendLine();
- }
- else
- {
- sb.AppendFormat("ADR = {0}", descriptor.ADR).AppendLine();
- sb.AppendFormat("CONTROL = {0}", descriptor.CONTROL).AppendLine();
- sb.AppendFormat("TNO = {0}", descriptor.TNO).AppendLine();
- sb.AppendFormat("POINT = {0}", descriptor.POINT).AppendLine();
- sb.AppendFormat("Min = {0}", descriptor.Min).AppendLine();
- sb.AppendFormat("Sec = {0}", descriptor.Sec).AppendLine();
- sb.AppendFormat("Frame = {0}", descriptor.Frame).AppendLine();
- sb.AppendFormat("HOUR = {0}", descriptor.HOUR).AppendLine();
- sb.AppendFormat("PHOUR = {0}", descriptor.PHOUR).AppendLine();
- sb.AppendFormat("PMIN = {0}", descriptor.PMIN).AppendLine();
- sb.AppendFormat("PSEC = {0}", descriptor.PSEC).AppendLine();
- sb.AppendFormat("PFRAME = {0}", descriptor.PFRAME).AppendLine();
- }
-
- break;
+ sb.
+ AppendFormat("Maximum start of outermost Lead-out in the recordable area of the disc: {0:D2}:{1:D2}:{2:D2}",
+ descriptor.PMIN, descriptor.PSEC, descriptor.PFRAME).
+ AppendLine();
}
+
+ break;
}
- break;
+ case 0xB1:
+ {
+ sb.AppendFormat("Number of skip interval pointers: {0}", descriptor.PMIN).
+ AppendLine();
+
+ sb.AppendFormat("Number of skip track pointers: {0}", descriptor.PSEC).AppendLine();
+
+ break;
+ }
+
+ case 0xB2:
+ case 0xB3:
+ case 0xB4:
+ {
+ sb.AppendFormat("Skip track {0}", descriptor.Min).AppendLine();
+ sb.AppendFormat("Skip track {0}", descriptor.Sec).AppendLine();
+ sb.AppendFormat("Skip track {0}", descriptor.Frame).AppendLine();
+ sb.AppendFormat("Skip track {0}", descriptor.Zero).AppendLine();
+ sb.AppendFormat("Skip track {0}", descriptor.PMIN).AppendLine();
+ sb.AppendFormat("Skip track {0}", descriptor.PSEC).AppendLine();
+ sb.AppendFormat("Skip track {0}", descriptor.PFRAME).AppendLine();
+
+ break;
+ }
+
+ case 0xC0:
+ {
+ sb.AppendFormat("Optimum recording power: 0x{0:X2}", descriptor.Min).AppendLine();
+
+ if(descriptor.PHOUR > 0)
+ sb.
+ AppendFormat("Start time of the first Lead-in area in the disc: {3:D2}:{0:D2}:{1:D2}:{2:D2}",
+ descriptor.PMIN, descriptor.PSEC, descriptor.PFRAME,
+ descriptor.PHOUR).AppendLine();
+ else
+ sb.
+ AppendFormat("Start time of the first Lead-in area in the disc: {0:D2}:{1:D2}:{2:D2}",
+ descriptor.PMIN, descriptor.PSEC, descriptor.PFRAME).
+ AppendLine();
+
+ break;
+ }
+
+ case 0xC1:
+ {
+ sb.AppendFormat("Copy of information of A1 from ATIP found");
+ sb.AppendFormat("Min = {0}", descriptor.Min).AppendLine();
+ sb.AppendFormat("Sec = {0}", descriptor.Sec).AppendLine();
+ sb.AppendFormat("Frame = {0}", descriptor.Frame).AppendLine();
+ sb.AppendFormat("Zero = {0}", descriptor.Zero).AppendLine();
+ sb.AppendFormat("PMIN = {0}", descriptor.PMIN).AppendLine();
+ sb.AppendFormat("PSEC = {0}", descriptor.PSEC).AppendLine();
+ sb.AppendFormat("PFRAME = {0}", descriptor.PFRAME).AppendLine();
+
+ break;
+ }
+
+ case 0xCF:
+ {
+ if(descriptor.PHOUR > 0)
+ {
+ sb.
+ AppendFormat("Start position of outer part lead-in area: {3:D2}:{0:D2}:{1:D2}:{2:D2}",
+ descriptor.PMIN, descriptor.PSEC, descriptor.PFRAME,
+ descriptor.PHOUR).AppendLine();
+
+ sb.
+ AppendFormat("Stop position of inner part lead-out area: {3:D2}:{0:D2}:{1:D2}:{2:D2}",
+ descriptor.Min, descriptor.Sec, descriptor.Frame,
+ descriptor.HOUR).AppendLine();
+ }
+ else
+ {
+ sb.
+ AppendFormat("Start position of outer part lead-in area: {0:D2}:{1:D2}:{2:D2}",
+ descriptor.PMIN, descriptor.PSEC, descriptor.PFRAME).
+ AppendLine();
+
+ sb.
+ AppendFormat("Stop position of inner part lead-out area: {0:D2}:{1:D2}:{2:D2}",
+ descriptor.Min, descriptor.Sec, descriptor.Frame).AppendLine();
+ }
+
+ break;
+ }
+
+ default:
+ {
+ if(descriptor.POINT >= 0x01 &&
+ descriptor.POINT <= 0x40)
+ {
+ sb.
+ AppendFormat("Start time for interval that should be skipped: {0:D2}:{1:D2}:{2:D2}",
+ descriptor.PMIN, descriptor.PSEC, descriptor.PFRAME).
+ AppendLine();
+
+ sb.
+ AppendFormat("Ending time for interval that should be skipped: {0:D2}:{1:D2}:{2:D2}",
+ descriptor.Min, descriptor.Sec, descriptor.Frame).AppendLine();
+ }
+ else
+ {
+ sb.AppendFormat("ADR = {0}", descriptor.ADR).AppendLine();
+ sb.AppendFormat("CONTROL = {0}", descriptor.CONTROL).AppendLine();
+ sb.AppendFormat("TNO = {0}", descriptor.TNO).AppendLine();
+ sb.AppendFormat("POINT = {0}", descriptor.POINT).AppendLine();
+ sb.AppendFormat("Min = {0}", descriptor.Min).AppendLine();
+ sb.AppendFormat("Sec = {0}", descriptor.Sec).AppendLine();
+ sb.AppendFormat("Frame = {0}", descriptor.Frame).AppendLine();
+ sb.AppendFormat("HOUR = {0}", descriptor.HOUR).AppendLine();
+ sb.AppendFormat("PHOUR = {0}", descriptor.PHOUR).AppendLine();
+ sb.AppendFormat("PMIN = {0}", descriptor.PMIN).AppendLine();
+ sb.AppendFormat("PSEC = {0}", descriptor.PSEC).AppendLine();
+ sb.AppendFormat("PFRAME = {0}", descriptor.PFRAME).AppendLine();
+ }
+
+ break;
+ }
}
- case 6:
- {
- uint id = (uint)((descriptor.Min << 16) + (descriptor.Sec << 8) + descriptor.Frame);
- sb.AppendFormat("Disc ID: {0:X6}", id & 0x00FFFFFF).AppendLine();
+ break;
+ }
- break;
- }
+ case 6:
+ {
+ uint id = (uint)((descriptor.Min << 16) + (descriptor.Sec << 8) + descriptor.Frame);
+ sb.AppendFormat("Disc ID: {0:X6}", id & 0x00FFFFFF).AppendLine();
+
+ break;
}
}
-
- return sb.ToString();
- }
-
- public static string Prettify(byte[] CDFullTOCResponse)
- {
- CDFullTOC? decoded = Decode(CDFullTOCResponse);
-
- return Prettify(decoded);
- }
-
- public struct CDFullTOC
- {
- /// Total size of returned session information minus this field
- public ushort DataLength;
- /// First complete session number in hex
- public byte FirstCompleteSession;
- /// Last complete session number in hex
- public byte LastCompleteSession;
- /// Track descriptors
- public TrackDataDescriptor[] TrackDescriptors;
- }
-
- public struct TrackDataDescriptor
- {
- /// Byte 0 Session number in hex
- public byte SessionNumber;
- /// Byte 1, bits 7 to 4 Type of information in Q subchannel of block where this TOC entry was found
- public byte ADR;
- /// Byte 1, bits 3 to 0 Track attributes
- public byte CONTROL;
- /// Byte 2
- public byte TNO;
- /// Byte 3
- public byte POINT;
- /// Byte 4
- public byte Min;
- /// Byte 5
- public byte Sec;
- /// Byte 6
- public byte Frame;
- /// Byte 7, CD only
- public byte Zero;
- /// Byte 7, bits 7 to 4, DDCD only
- public byte HOUR;
- /// Byte 7, bits 3 to 0, DDCD only
- public byte PHOUR;
- /// Byte 8
- public byte PMIN;
- /// Byte 9
- public byte PSEC;
- /// Byte 10
- public byte PFRAME;
- }
-
- public static CDFullTOC Create(List