Move to file scoped namespaces.

This commit is contained in:
2022-03-06 13:29:37 +00:00
parent c7178d94c6
commit 3b6091c02c
119 changed files with 38048 additions and 38172 deletions

View File

@@ -35,249 +35,248 @@ using System.Diagnostics.CodeAnalysis;
using System.Text;
using Aaru.Helpers;
namespace Aaru.Decoders.Xbox
namespace Aaru.Decoders.Xbox;
[SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"),
SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), SuppressMessage("ReSharper", "NotAccessedField.Global")]
public static class DMI
{
[SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"),
SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), SuppressMessage("ReSharper", "NotAccessedField.Global")]
public static class DMI
public static bool IsXbox(byte[] dmi)
{
public static bool IsXbox(byte[] dmi)
{
if(dmi?.Length != 2052)
if(dmi?.Length != 2052)
return false;
// Version is 1
if(BitConverter.ToUInt32(dmi, 4) != 1)
return false;
// Catalogue number is two letters, five numbers, one letter
for(int i = 12; i < 14; i++)
if(dmi[i] < 0x41 ||
dmi[i] > 0x5A)
return false;
// Version is 1
if(BitConverter.ToUInt32(dmi, 4) != 1)
for(int i = 14; i < 19; i++)
if(dmi[i] < 0x30 ||
dmi[i] > 0x39)
return false;
// Catalogue number is two letters, five numbers, one letter
for(int i = 12; i < 14; i++)
if(dmi[i] < 0x41 ||
dmi[i] > 0x5A)
return false;
if(dmi[19] < 0x41 ||
dmi[19] > 0x5A)
return false;
for(int i = 14; i < 19; i++)
if(dmi[i] < 0x30 ||
dmi[i] > 0x39)
return false;
long timestamp = BitConverter.ToInt64(dmi, 20);
if(dmi[19] < 0x41 ||
dmi[19] > 0x5A)
return false;
// Game cannot exist before the Xbox
return timestamp >= 0x1BD164833DFC000;
}
long timestamp = BitConverter.ToInt64(dmi, 20);
public static bool IsXbox360(byte[] dmi)
{
if(dmi?.Length != 2052)
return false;
// Game cannot exist before the Xbox
return timestamp >= 0x1BD164833DFC000;
}
uint signature = BitConverter.ToUInt32(dmi, 0x7EC);
public static bool IsXbox360(byte[] dmi)
// "XBOX" swapped as .NET is little endian
return signature == 0x584F4258;
}
public static XboxDMI? DecodeXbox(byte[] response)
{
bool isXbox = IsXbox(response);
if(!isXbox)
return null;
var dmi = new XboxDMI
{
if(dmi?.Length != 2052)
return false;
DataLength = (ushort)((response[0] << 8) + response[1]),
Reserved1 = response[2],
Reserved2 = response[3],
Version = BitConverter.ToUInt32(response, 4),
Timestamp = BitConverter.ToInt64(response, 20)
};
uint signature = BitConverter.ToUInt32(dmi, 0x7EC);
byte[] tmp = new byte[8];
Array.Copy(response, 12, tmp, 0, 8);
dmi.CatalogNumber = StringHandlers.CToString(tmp);
// "XBOX" swapped as .NET is little endian
return signature == 0x584F4258;
}
return dmi;
}
public static XboxDMI? DecodeXbox(byte[] response)
public static Xbox360DMI? DecodeXbox360(byte[] response)
{
bool isX360 = IsXbox360(response);
if(!isX360)
return null;
var dmi = new Xbox360DMI
{
bool isXbox = IsXbox(response);
DataLength = (ushort)((response[0] << 8) + response[1]),
Reserved1 = response[2],
Reserved2 = response[3],
Version = BitConverter.ToUInt32(response, 4),
Timestamp = BitConverter.ToInt64(response, 20),
MediaID = new byte[16]
};
if(!isXbox)
return null;
Array.Copy(response, 36, dmi.MediaID, 0, 16);
byte[] tmp = new byte[16];
Array.Copy(response, 68, tmp, 0, 16);
dmi.CatalogNumber = StringHandlers.CToString(tmp);
var dmi = new XboxDMI
{
DataLength = (ushort)((response[0] << 8) + response[1]),
Reserved1 = response[2],
Reserved2 = response[3],
Version = BitConverter.ToUInt32(response, 4),
Timestamp = BitConverter.ToInt64(response, 20)
};
return dmi.CatalogNumber == null || dmi.CatalogNumber.Length < 13 ? (Xbox360DMI?)null : dmi;
}
byte[] tmp = new byte[8];
Array.Copy(response, 12, tmp, 0, 8);
dmi.CatalogNumber = StringHandlers.CToString(tmp);
public static string PrettifyXbox(XboxDMI? dmi)
{
if(dmi == null)
return null;
return dmi;
}
XboxDMI decoded = dmi.Value;
var sb = new StringBuilder();
public static Xbox360DMI? DecodeXbox360(byte[] response)
sb.Append("Catalogue number: ");
for(int i = 0; i < 2; i++)
sb.AppendFormat("{0}", decoded.CatalogNumber[i]);
sb.Append("-");
for(int i = 2; i < 7; i++)
sb.AppendFormat("{0}", decoded.CatalogNumber[i]);
sb.Append("-");
sb.AppendFormat("{0}", decoded.CatalogNumber[7]);
sb.AppendLine();
sb.AppendFormat("Timestamp: {0}", DateTime.FromFileTimeUtc(decoded.Timestamp)).AppendLine();
return sb.ToString();
}
public static string PrettifyXbox360(Xbox360DMI? dmi)
{
if(dmi == null)
return null;
Xbox360DMI decoded = dmi.Value;
var sb = new StringBuilder();
sb.Append("Catalogue number: ");
for(int i = 0; i < 2; i++)
sb.AppendFormat("{0}", decoded.CatalogNumber[i]);
sb.Append("-");
for(int i = 2; i < 6; i++)
sb.AppendFormat("{0}", decoded.CatalogNumber[i]);
sb.Append("-");
for(int i = 6; i < 8; i++)
sb.AppendFormat("{0}", decoded.CatalogNumber[i]);
sb.Append("-");
switch(decoded.CatalogNumber.Length)
{
bool isX360 = IsXbox360(response);
case 13:
for(int i = 8; i < 10; i++)
sb.AppendFormat("{0}", decoded.CatalogNumber[i]);
if(!isX360)
return null;
sb.Append("-");
var dmi = new Xbox360DMI
{
DataLength = (ushort)((response[0] << 8) + response[1]),
Reserved1 = response[2],
Reserved2 = response[3],
Version = BitConverter.ToUInt32(response, 4),
Timestamp = BitConverter.ToInt64(response, 20),
MediaID = new byte[16]
};
for(int i = 10; i < 13; i++)
sb.AppendFormat("{0}", decoded.CatalogNumber[i]);
Array.Copy(response, 36, dmi.MediaID, 0, 16);
byte[] tmp = new byte[16];
Array.Copy(response, 68, tmp, 0, 16);
dmi.CatalogNumber = StringHandlers.CToString(tmp);
break;
case 14:
for(int i = 8; i < 11; i++)
sb.AppendFormat("{0}", decoded.CatalogNumber[i]);
return dmi.CatalogNumber == null || dmi.CatalogNumber.Length < 13 ? (Xbox360DMI?)null : dmi;
sb.Append("-");
for(int i = 11; i < 14; i++)
sb.AppendFormat("{0}", decoded.CatalogNumber[i]);
break;
default:
for(int i = 8; i < decoded.CatalogNumber.Length - 3; i++)
sb.AppendFormat("{0}", decoded.CatalogNumber[i]);
sb.Append("-");
for(int i = decoded.CatalogNumber.Length - 3; i < decoded.CatalogNumber.Length; i++)
sb.AppendFormat("{0}", decoded.CatalogNumber[i]);
break;
}
public static string PrettifyXbox(XboxDMI? dmi)
{
if(dmi == null)
return null;
sb.AppendLine();
XboxDMI decoded = dmi.Value;
var sb = new StringBuilder();
sb.Append("Media ID: ");
sb.Append("Catalogue number: ");
for(int i = 0; i < 12; i++)
sb.AppendFormat("{0:X2}", decoded.MediaID[i]);
for(int i = 0; i < 2; i++)
sb.AppendFormat("{0}", decoded.CatalogNumber[i]);
sb.Append("-");
sb.Append("-");
for(int i = 12; i < 16; i++)
sb.AppendFormat("{0:X2}", decoded.MediaID[i]);
for(int i = 2; i < 7; i++)
sb.AppendFormat("{0}", decoded.CatalogNumber[i]);
sb.AppendLine();
sb.Append("-");
sb.AppendFormat("{0}", decoded.CatalogNumber[7]);
sb.AppendLine();
sb.AppendFormat("Timestamp: {0}", DateTime.FromFileTimeUtc(decoded.Timestamp)).AppendLine();
sb.AppendFormat("Timestamp: {0}", DateTime.FromFileTimeUtc(decoded.Timestamp)).AppendLine();
return sb.ToString();
}
return sb.ToString();
}
public static string PrettifyXbox(byte[] response) => PrettifyXbox(DecodeXbox(response));
public static string PrettifyXbox360(Xbox360DMI? dmi)
{
if(dmi == null)
return null;
public static string PrettifyXbox360(byte[] response) => PrettifyXbox360(DecodeXbox360(response));
Xbox360DMI decoded = dmi.Value;
var sb = new StringBuilder();
public struct XboxDMI
{
/// <summary>Bytes 0 to 1 Data length</summary>
public ushort DataLength;
/// <summary>Byte 2 Reserved</summary>
public byte Reserved1;
/// <summary>Byte 3 Reserved</summary>
public byte Reserved2;
sb.Append("Catalogue number: ");
/// <summary>Bytes 4 to 7 0x01 in XGD</summary>
public uint Version;
for(int i = 0; i < 2; i++)
sb.AppendFormat("{0}", decoded.CatalogNumber[i]);
/// <summary>Bytes 12 to 16 Catalogue number in XX-XXXXX-X</summary>
public string CatalogNumber;
sb.Append("-");
/// <summary>Bytes 20 to 27 DMI timestamp</summary>
public long Timestamp;
}
for(int i = 2; i < 6; i++)
sb.AppendFormat("{0}", decoded.CatalogNumber[i]);
public struct Xbox360DMI
{
/// <summary>Bytes 0 to 1 Data length</summary>
public ushort DataLength;
/// <summary>Byte 2 Reserved</summary>
public byte Reserved1;
/// <summary>Byte 3 Reserved</summary>
public byte Reserved2;
sb.Append("-");
/// <summary>Bytes 4 to 7 0x02 in XGD2 and XGD3</summary>
public uint Version;
for(int i = 6; i < 8; i++)
sb.AppendFormat("{0}", decoded.CatalogNumber[i]);
/// <summary>Bytes 20 to 27 DMI timestamp</summary>
public long Timestamp;
sb.Append("-");
/// <summary>Bytes 36 to 51 Media ID in hex XXXXXXXXXXXX-XXXXXXXX</summary>
public byte[] MediaID;
switch(decoded.CatalogNumber.Length)
{
case 13:
for(int i = 8; i < 10; i++)
sb.AppendFormat("{0}", decoded.CatalogNumber[i]);
sb.Append("-");
for(int i = 10; i < 13; i++)
sb.AppendFormat("{0}", decoded.CatalogNumber[i]);
break;
case 14:
for(int i = 8; i < 11; i++)
sb.AppendFormat("{0}", decoded.CatalogNumber[i]);
sb.Append("-");
for(int i = 11; i < 14; i++)
sb.AppendFormat("{0}", decoded.CatalogNumber[i]);
break;
default:
for(int i = 8; i < decoded.CatalogNumber.Length - 3; i++)
sb.AppendFormat("{0}", decoded.CatalogNumber[i]);
sb.Append("-");
for(int i = decoded.CatalogNumber.Length - 3; i < decoded.CatalogNumber.Length; i++)
sb.AppendFormat("{0}", decoded.CatalogNumber[i]);
break;
}
sb.AppendLine();
sb.Append("Media ID: ");
for(int i = 0; i < 12; i++)
sb.AppendFormat("{0:X2}", decoded.MediaID[i]);
sb.Append("-");
for(int i = 12; i < 16; i++)
sb.AppendFormat("{0:X2}", decoded.MediaID[i]);
sb.AppendLine();
sb.AppendFormat("Timestamp: {0}", DateTime.FromFileTimeUtc(decoded.Timestamp)).AppendLine();
return sb.ToString();
}
public static string PrettifyXbox(byte[] response) => PrettifyXbox(DecodeXbox(response));
public static string PrettifyXbox360(byte[] response) => PrettifyXbox360(DecodeXbox360(response));
public struct XboxDMI
{
/// <summary>Bytes 0 to 1 Data length</summary>
public ushort DataLength;
/// <summary>Byte 2 Reserved</summary>
public byte Reserved1;
/// <summary>Byte 3 Reserved</summary>
public byte Reserved2;
/// <summary>Bytes 4 to 7 0x01 in XGD</summary>
public uint Version;
/// <summary>Bytes 12 to 16 Catalogue number in XX-XXXXX-X</summary>
public string CatalogNumber;
/// <summary>Bytes 20 to 27 DMI timestamp</summary>
public long Timestamp;
}
public struct Xbox360DMI
{
/// <summary>Bytes 0 to 1 Data length</summary>
public ushort DataLength;
/// <summary>Byte 2 Reserved</summary>
public byte Reserved1;
/// <summary>Byte 3 Reserved</summary>
public byte Reserved2;
/// <summary>Bytes 4 to 7 0x02 in XGD2 and XGD3</summary>
public uint Version;
/// <summary>Bytes 20 to 27 DMI timestamp</summary>
public long Timestamp;
/// <summary>Bytes 36 to 51 Media ID in hex XXXXXXXXXXXX-XXXXXXXX</summary>
public byte[] MediaID;
/// <summary>Bytes 68 to 83 Catalogue number in XX-XXXX-XX-XXY-XXX, Y not always exists</summary>
public string CatalogNumber;
}
/// <summary>Bytes 68 to 83 Catalogue number in XX-XXXX-XX-XXY-XXX, Y not always exists</summary>
public string CatalogNumber;
}
}

View File

@@ -35,369 +35,368 @@ using System.Diagnostics.CodeAnalysis;
using System.Text;
using Aaru.Decoders.DVD;
namespace Aaru.Decoders.Xbox
namespace Aaru.Decoders.Xbox;
[SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"),
SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), SuppressMessage("ReSharper", "NotAccessedField.Global")]
public static class SS
{
[SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"),
SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), SuppressMessage("ReSharper", "NotAccessedField.Global")]
public static class SS
public static SecuritySector? Decode(byte[] response)
{
public static SecuritySector? Decode(byte[] response)
if(response == null)
return null;
if(response.Length < 2048)
return null;
var ss = new SecuritySector
{
if(response == null)
return null;
DiskCategory = (DiskCategory)((response[0] & 0xF0) >> 4),
PartVersion = (byte)(response[0] & 0x0F),
DiscSize = (DVDSize)((response[1] & 0xF0) >> 4),
MaximumRate = (MaximumRateField)(response[1] & 0x0F),
Reserved3 = (response[2] & 0x80) == 0x80,
Layers = (byte)((response[2] & 0x60) >> 5),
TrackPath = (response[2] & 0x08) == 0x08,
LayerType = (LayerTypeFieldMask)(response[2] & 0x07),
LinearDensity = (LinearDensityField)((response[3] & 0xF0) >> 4),
TrackDensity = (TrackDensityField)(response[3] & 0x0F),
DataAreaStartPSN = (uint)((response[4] << 24) + (response[5] << 16) + (response[6] << 8) + response[7]),
DataAreaEndPSN = (uint)((response[8] << 24) + (response[9] << 16) + (response[10] << 8) + response[11]),
Layer0EndPSN = (uint)((response[12] << 24) + (response[13] << 16) + (response[14] << 8) + response[15]),
Unknown1 = response[27],
Unknown2 = new byte[28],
Unknown3 = new byte[436],
Unknown4 = new byte[4],
Unknown5 = new byte[43],
ChallengeTableVersion = response[768],
NoChallengeEntries = response[769],
ChallengeEntries = new ChallengeEntry[23],
Unknown6 = response[1023],
Unknown7 = new byte[48],
Unknown8 = new byte[16],
Unknown9 = new byte[16],
Unknown10 = new byte[303],
Unknown11 = new byte[104],
Extents = new SecuritySectorExtent[23],
ExtentsCopy = new SecuritySectorExtent[23]
};
if(response.Length < 2048)
return null;
Array.Copy(response, 256, ss.Unknown2, 0, 28);
Array.Copy(response, 284, ss.Unknown3, 0, 436);
Array.Copy(response, 720, ss.Unknown4, 0, 4);
Array.Copy(response, 724, ss.Unknown5, 0, 43);
var ss = new SecuritySector
for(int i = 0; i < 23; i++)
ss.ChallengeEntries[i] = new ChallengeEntry
{
DiskCategory = (DiskCategory)((response[0] & 0xF0) >> 4),
PartVersion = (byte)(response[0] & 0x0F),
DiscSize = (DVDSize)((response[1] & 0xF0) >> 4),
MaximumRate = (MaximumRateField)(response[1] & 0x0F),
Reserved3 = (response[2] & 0x80) == 0x80,
Layers = (byte)((response[2] & 0x60) >> 5),
TrackPath = (response[2] & 0x08) == 0x08,
LayerType = (LayerTypeFieldMask)(response[2] & 0x07),
LinearDensity = (LinearDensityField)((response[3] & 0xF0) >> 4),
TrackDensity = (TrackDensityField)(response[3] & 0x0F),
DataAreaStartPSN = (uint)((response[4] << 24) + (response[5] << 16) + (response[6] << 8) + response[7]),
DataAreaEndPSN = (uint)((response[8] << 24) + (response[9] << 16) + (response[10] << 8) + response[11]),
Layer0EndPSN = (uint)((response[12] << 24) + (response[13] << 16) + (response[14] << 8) + response[15]),
Unknown1 = response[27],
Unknown2 = new byte[28],
Unknown3 = new byte[436],
Unknown4 = new byte[4],
Unknown5 = new byte[43],
ChallengeTableVersion = response[768],
NoChallengeEntries = response[769],
ChallengeEntries = new ChallengeEntry[23],
Unknown6 = response[1023],
Unknown7 = new byte[48],
Unknown8 = new byte[16],
Unknown9 = new byte[16],
Unknown10 = new byte[303],
Unknown11 = new byte[104],
Extents = new SecuritySectorExtent[23],
ExtentsCopy = new SecuritySectorExtent[23]
Level = response[770 + (i * 11) + 0],
ChallengeId = response[770 + (i * 11) + 1],
ChallengeValue = (uint)((response[770 + (i * 11) + 2] << 24) +
(response[770 + (i * 11) + 3] << 16) + (response[770 + (i * 11) + 4] << 8) +
response[770 + (i * 11) + 5]),
ResponseModifier = response[770 + (i * 11) + 6],
ResponseValue = (uint)((response[770 + (i * 11) + 7] << 24) + (response[770 + (i * 11) + 8] << 16) +
(response[770 + (i * 11) + 9] << 8) + response[770 + (i * 11) + 10])
};
Array.Copy(response, 256, ss.Unknown2, 0, 28);
Array.Copy(response, 284, ss.Unknown3, 0, 436);
Array.Copy(response, 720, ss.Unknown4, 0, 4);
Array.Copy(response, 724, ss.Unknown5, 0, 43);
Array.Copy(response, 1052, ss.Unknown7, 0, 48);
Array.Copy(response, 1120, ss.Unknown8, 0, 16);
Array.Copy(response, 1180, ss.Unknown9, 0, 16);
Array.Copy(response, 1208, ss.Unknown10, 0, 303);
Array.Copy(response, 1528, ss.Unknown11, 0, 104);
for(int i = 0; i < 23; i++)
ss.ChallengeEntries[i] = new ChallengeEntry
{
Level = response[770 + (i * 11) + 0],
ChallengeId = response[770 + (i * 11) + 1],
ChallengeValue = (uint)((response[770 + (i * 11) + 2] << 24) +
(response[770 + (i * 11) + 3] << 16) + (response[770 + (i * 11) + 4] << 8) +
response[770 + (i * 11) + 5]),
ResponseModifier = response[770 + (i * 11) + 6],
ResponseValue = (uint)((response[770 + (i * 11) + 7] << 24) + (response[770 + (i * 11) + 8] << 16) +
(response[770 + (i * 11) + 9] << 8) + response[770 + (i * 11) + 10])
};
for(int i = 0; i < 23; i++)
ss.Extents[i] = new SecuritySectorExtent
{
Unknown = (uint)((response[1633 + (i * 9) + 0] << 16) + (response[1633 + (i * 9) + 1] << 8) +
response[1633 + (i * 9) + 2]),
StartPSN = (uint)((response[1633 + (i * 9) + 3] << 16) + (response[1633 + (i * 9) + 4] << 8) +
response[1633 + (i * 9) + 5]),
EndPSN = (uint)((response[1633 + (i * 9) + 6] << 16) + (response[1633 + (i * 9) + 7] << 8) +
response[1633 + (i * 9) + 8])
};
Array.Copy(response, 1052, ss.Unknown7, 0, 48);
Array.Copy(response, 1120, ss.Unknown8, 0, 16);
Array.Copy(response, 1180, ss.Unknown9, 0, 16);
Array.Copy(response, 1208, ss.Unknown10, 0, 303);
Array.Copy(response, 1528, ss.Unknown11, 0, 104);
for(int i = 0; i < 23; i++)
ss.ExtentsCopy[i] = new SecuritySectorExtent
{
Unknown = (uint)((response[1840 + (i * 9) + 0] << 16) + (response[1840 + (i * 9) + 1] << 8) +
response[1840 + (i * 9) + 2]),
StartPSN = (uint)((response[1840 + (i * 9) + 3] << 16) + (response[1840 + (i * 9) + 4] << 8) +
response[1840 + (i * 9) + 5]),
EndPSN = (uint)((response[1840 + (i * 9) + 6] << 16) + (response[1840 + (i * 9) + 7] << 8) +
response[1840 + (i * 9) + 8])
};
for(int i = 0; i < 23; i++)
ss.Extents[i] = new SecuritySectorExtent
{
Unknown = (uint)((response[1633 + (i * 9) + 0] << 16) + (response[1633 + (i * 9) + 1] << 8) +
response[1633 + (i * 9) + 2]),
StartPSN = (uint)((response[1633 + (i * 9) + 3] << 16) + (response[1633 + (i * 9) + 4] << 8) +
response[1633 + (i * 9) + 5]),
EndPSN = (uint)((response[1633 + (i * 9) + 6] << 16) + (response[1633 + (i * 9) + 7] << 8) +
response[1633 + (i * 9) + 8])
};
return ss;
}
for(int i = 0; i < 23; i++)
ss.ExtentsCopy[i] = new SecuritySectorExtent
{
Unknown = (uint)((response[1840 + (i * 9) + 0] << 16) + (response[1840 + (i * 9) + 1] << 8) +
response[1840 + (i * 9) + 2]),
StartPSN = (uint)((response[1840 + (i * 9) + 3] << 16) + (response[1840 + (i * 9) + 4] << 8) +
response[1840 + (i * 9) + 5]),
EndPSN = (uint)((response[1840 + (i * 9) + 6] << 16) + (response[1840 + (i * 9) + 7] << 8) +
response[1840 + (i * 9) + 8])
};
public static string Prettify(SecuritySector? ss)
{
if(ss == null)
return null;
return ss;
SecuritySector decoded = ss.Value;
var sb = new StringBuilder();
string sizeString;
switch(decoded.DiscSize)
{
case DVDSize.Eighty:
sizeString = "80mm";
break;
case DVDSize.OneTwenty:
sizeString = "120mm";
break;
default:
sizeString = $"unknown size identifier {decoded.DiscSize}";
break;
}
public static string Prettify(SecuritySector? ss)
const string categorySentence = "Disc is a {0} {1} version {2}";
switch(decoded.DiskCategory)
{
if(ss == null)
return null;
case DiskCategory.DVDPRWDL:
sb.AppendFormat(categorySentence, sizeString, "Xbox Game Disc", decoded.PartVersion).AppendLine();
SecuritySector decoded = ss.Value;
var sb = new StringBuilder();
break;
case DiskCategory.DVDPRDL:
sb.AppendFormat(categorySentence, sizeString, "Xbox 360 Game Disc", decoded.PartVersion).
AppendLine();
string sizeString;
break;
default:
sb.AppendFormat(categorySentence, sizeString, "unknown disc type", decoded.PartVersion).
AppendLine();
switch(decoded.DiscSize)
break;
}
switch(decoded.MaximumRate)
{
case MaximumRateField.TwoMbps:
sb.AppendLine("Disc maximum transfer rate is 2,52 Mbit/sec.");
break;
case MaximumRateField.FiveMbps:
sb.AppendLine("Disc maximum transfer rate is 5,04 Mbit/sec.");
break;
case MaximumRateField.TenMbps:
sb.AppendLine("Disc maximum transfer rate is 10,08 Mbit/sec.");
break;
case MaximumRateField.TwentyMbps:
sb.AppendLine("Disc maximum transfer rate is 20,16 Mbit/sec.");
break;
case MaximumRateField.ThirtyMbps:
sb.AppendLine("Disc maximum transfer rate is 30,24 Mbit/sec.");
break;
case MaximumRateField.Unspecified:
sb.AppendLine("Disc maximum transfer rate is unspecified.");
break;
default:
sb.AppendFormat("Disc maximum transfer rate is specified by unknown key {0}", decoded.MaximumRate).
AppendLine();
break;
}
sb.AppendFormat("Disc has {0} layers", decoded.Layers + 1).AppendLine();
if(decoded.TrackPath &&
decoded.Layers == 1)
sb.AppendLine("Layers are in parallel track path");
else if(!decoded.TrackPath &&
decoded.Layers == 1)
sb.AppendLine("Layers are in opposite track path");
switch(decoded.LinearDensity)
{
case LinearDensityField.TwoSix:
sb.AppendLine("Pitch size is 0,267 μm/bit");
break;
case LinearDensityField.TwoNine:
sb.AppendLine("Pitch size is 0,147 μm/bit");
break;
case LinearDensityField.FourZero:
sb.AppendLine("Pitch size is between 0,409 μm/bit and 0,435 μm/bit");
break;
case LinearDensityField.TwoEight:
sb.AppendLine("Pitch size is between 0,140 μm/bit and 0,148 μm/bit");
break;
case LinearDensityField.OneFive:
sb.AppendLine("Pitch size is 0,153 μm/bit");
break;
case LinearDensityField.OneThree:
sb.AppendLine("Pitch size is between 0,130 μm/bit and 0,140 μm/bit");
break;
case LinearDensityField.ThreeFive:
sb.AppendLine("Pitch size is 0,353 μm/bit");
break;
default:
sb.AppendFormat("Unknown pitch size key {0}", decoded.LinearDensity).AppendLine();
break;
}
switch(decoded.TrackDensity)
{
case TrackDensityField.Seven:
sb.AppendLine("Track size is 0,74 μm");
break;
case TrackDensityField.Eight:
sb.AppendLine("Track size is 0,80 μm");
break;
case TrackDensityField.Six:
sb.AppendLine("Track size is 0,615 μm");
break;
case TrackDensityField.Four:
sb.AppendLine("Track size is 0,40 μm");
break;
case TrackDensityField.Three:
sb.AppendLine("Track size is 0,34 μm");
break;
default:
sb.AppendFormat("Unknown track size key {0}", decoded.LinearDensity).AppendLine();
break;
}
if(decoded.DataAreaStartPSN > 0)
if(decoded.DataAreaEndPSN > 0)
{
case DVDSize.Eighty:
sizeString = "80mm";
sb.AppendFormat("Data area starts at PSN {0:X}h", decoded.DataAreaStartPSN).AppendLine();
sb.AppendFormat("Data area ends at PSN {0:X}h", decoded.DataAreaEndPSN).AppendLine();
break;
case DVDSize.OneTwenty:
sizeString = "120mm";
break;
default:
sizeString = $"unknown size identifier {decoded.DiscSize}";
break;
if(decoded.Layers == 1 &&
!decoded.TrackPath)
sb.AppendFormat("Layer 0 ends at PSN {0:X}h", decoded.Layer0EndPSN).AppendLine();
}
const string categorySentence = "Disc is a {0} {1} version {2}";
switch(decoded.DiskCategory)
{
case DiskCategory.DVDPRWDL:
sb.AppendFormat(categorySentence, sizeString, "Xbox Game Disc", decoded.PartVersion).AppendLine();
break;
case DiskCategory.DVDPRDL:
sb.AppendFormat(categorySentence, sizeString, "Xbox 360 Game Disc", decoded.PartVersion).
AppendLine();
break;
default:
sb.AppendFormat(categorySentence, sizeString, "unknown disc type", decoded.PartVersion).
AppendLine();
break;
}
switch(decoded.MaximumRate)
{
case MaximumRateField.TwoMbps:
sb.AppendLine("Disc maximum transfer rate is 2,52 Mbit/sec.");
break;
case MaximumRateField.FiveMbps:
sb.AppendLine("Disc maximum transfer rate is 5,04 Mbit/sec.");
break;
case MaximumRateField.TenMbps:
sb.AppendLine("Disc maximum transfer rate is 10,08 Mbit/sec.");
break;
case MaximumRateField.TwentyMbps:
sb.AppendLine("Disc maximum transfer rate is 20,16 Mbit/sec.");
break;
case MaximumRateField.ThirtyMbps:
sb.AppendLine("Disc maximum transfer rate is 30,24 Mbit/sec.");
break;
case MaximumRateField.Unspecified:
sb.AppendLine("Disc maximum transfer rate is unspecified.");
break;
default:
sb.AppendFormat("Disc maximum transfer rate is specified by unknown key {0}", decoded.MaximumRate).
AppendLine();
break;
}
sb.AppendFormat("Disc has {0} layers", decoded.Layers + 1).AppendLine();
if(decoded.TrackPath &&
decoded.Layers == 1)
sb.AppendLine("Layers are in parallel track path");
else if(!decoded.TrackPath &&
decoded.Layers == 1)
sb.AppendLine("Layers are in opposite track path");
switch(decoded.LinearDensity)
{
case LinearDensityField.TwoSix:
sb.AppendLine("Pitch size is 0,267 μm/bit");
break;
case LinearDensityField.TwoNine:
sb.AppendLine("Pitch size is 0,147 μm/bit");
break;
case LinearDensityField.FourZero:
sb.AppendLine("Pitch size is between 0,409 μm/bit and 0,435 μm/bit");
break;
case LinearDensityField.TwoEight:
sb.AppendLine("Pitch size is between 0,140 μm/bit and 0,148 μm/bit");
break;
case LinearDensityField.OneFive:
sb.AppendLine("Pitch size is 0,153 μm/bit");
break;
case LinearDensityField.OneThree:
sb.AppendLine("Pitch size is between 0,130 μm/bit and 0,140 μm/bit");
break;
case LinearDensityField.ThreeFive:
sb.AppendLine("Pitch size is 0,353 μm/bit");
break;
default:
sb.AppendFormat("Unknown pitch size key {0}", decoded.LinearDensity).AppendLine();
break;
}
switch(decoded.TrackDensity)
{
case TrackDensityField.Seven:
sb.AppendLine("Track size is 0,74 μm");
break;
case TrackDensityField.Eight:
sb.AppendLine("Track size is 0,80 μm");
break;
case TrackDensityField.Six:
sb.AppendLine("Track size is 0,615 μm");
break;
case TrackDensityField.Four:
sb.AppendLine("Track size is 0,40 μm");
break;
case TrackDensityField.Three:
sb.AppendLine("Track size is 0,34 μm");
break;
default:
sb.AppendFormat("Unknown track size key {0}", decoded.LinearDensity).AppendLine();
break;
}
if(decoded.DataAreaStartPSN > 0)
if(decoded.DataAreaEndPSN > 0)
{
sb.AppendFormat("Data area starts at PSN {0:X}h", decoded.DataAreaStartPSN).AppendLine();
sb.AppendFormat("Data area ends at PSN {0:X}h", decoded.DataAreaEndPSN).AppendLine();
if(decoded.Layers == 1 &&
!decoded.TrackPath)
sb.AppendFormat("Layer 0 ends at PSN {0:X}h", decoded.Layer0EndPSN).AppendLine();
}
else
sb.AppendLine("Disc is empty");
else
sb.AppendLine("Disc is empty");
else
sb.AppendLine("Disc is empty");
sb.AppendLine("Challenges:");
sb.AppendLine("Challenges:");
foreach(ChallengeEntry entry in decoded.ChallengeEntries)
{
sb.AppendFormat("\tChallenge ID: {0}", entry.ChallengeId).AppendLine();
sb.AppendFormat("\tChallenge level: {0}", entry.Level).AppendLine();
sb.AppendFormat("\tChallenge value: 0x{0:X8}", entry.ChallengeValue).AppendLine();
sb.AppendFormat("\tResponse modifier: {0}", entry.ResponseModifier).AppendLine();
sb.AppendFormat("\tResponse value: 0x{0:X8}", entry.ResponseValue).AppendLine();
}
for(int i = 0; i < 16; i++)
sb.AppendFormat("Extent starts at PSN {0:X6}h and ends at PSN {1:X6}h", decoded.Extents[i].StartPSN,
decoded.Extents[i].EndPSN).AppendLine();
return sb.ToString();
}
public static string Prettify(byte[] response) => Prettify(Decode(response));
public struct SecuritySector
foreach(ChallengeEntry entry in decoded.ChallengeEntries)
{
/// <summary>Byte 0, bits 7 to 4 Disk category field</summary>
public DiskCategory DiskCategory;
/// <summary>Byte 0, bits 3 to 0 Media version</summary>
public byte PartVersion;
/// <summary>Byte 1, bits 7 to 4 120mm if 0, 80mm if 1. If UMD (60mm) 0 also. Reserved rest of values</summary>
public DVDSize DiscSize;
/// <summary>Byte 1, bits 3 to 0 Maximum data rate</summary>
public MaximumRateField MaximumRate;
/// <summary>Byte 2, bit 7 Reserved</summary>
public bool Reserved3;
/// <summary>Byte 2, bits 6 to 5 Number of layers</summary>
public byte Layers;
/// <summary>Byte 2, bit 4 Track path</summary>
public bool TrackPath;
/// <summary>Byte 2, bits 3 to 0 Layer type</summary>
public LayerTypeFieldMask LayerType;
/// <summary>Byte 3, bits 7 to 4 Linear density field</summary>
public LinearDensityField LinearDensity;
/// <summary>Byte 3, bits 3 to 0 Track density field</summary>
public TrackDensityField TrackDensity;
/// <summary>Bytes 4 to 7 PSN where Data Area starts</summary>
public uint DataAreaStartPSN;
/// <summary>Bytes 8 to 11 PSN where Data Area ends</summary>
public uint DataAreaEndPSN;
/// <summary>Bytes 12 to 15 PSN where Data Area ends in Layer 0</summary>
public uint Layer0EndPSN;
/// <summary>Byte 27 Always 0x06 on XGD3</summary>
public byte Unknown1;
/// <summary>Bytes 256 to 283 Unknown, XGD2 and XGD3</summary>
public byte[] Unknown2;
/// <summary>Bytes 284 to 719 Unknown, XGD3</summary>
public byte[] Unknown3;
/// <summary>Bytes 720 to 723 Unknown</summary>
public byte[] Unknown4;
/// <summary>Bytes 724 to 767 Unknown, XGD3</summary>
public byte[] Unknown5;
/// <summary>Byte 768 Version of challenge table</summary>
public byte ChallengeTableVersion;
/// <summary>Byte 769 Number of challenge entries</summary>
public byte NoChallengeEntries;
/// <summary>Bytes 770 to 1022 Unknown</summary>
public ChallengeEntry[] ChallengeEntries;
/// <summary>Byte 1023 Unknown</summary>
public byte Unknown6;
/// <summary>Bytes 1052 to 1099 Unknown, XGD1 only</summary>
public byte[] Unknown7;
/// <summary>Bytes 1120 to 1135 Unknown, XGD2 and XGD3</summary>
public byte[] Unknown8;
/// <summary>Bytes 1180 to 1195 Unknown</summary>
public byte[] Unknown9;
/// <summary>Bytes 1208 to 1511 Unknown</summary>
public byte[] Unknown10;
/// <summary>Bytes 1528 to 1632</summary>
public byte[] Unknown11;
/// <summary>Bytes 1633 to 1839 Security extents, 23 entries of 9 bytes</summary>
public SecuritySectorExtent[] Extents;
/// <summary>Bytes 1840 to 2047 Copy of the security extents, 23 entries of 9 bytes</summary>
public SecuritySectorExtent[] ExtentsCopy;
sb.AppendFormat("\tChallenge ID: {0}", entry.ChallengeId).AppendLine();
sb.AppendFormat("\tChallenge level: {0}", entry.Level).AppendLine();
sb.AppendFormat("\tChallenge value: 0x{0:X8}", entry.ChallengeValue).AppendLine();
sb.AppendFormat("\tResponse modifier: {0}", entry.ResponseModifier).AppendLine();
sb.AppendFormat("\tResponse value: 0x{0:X8}", entry.ResponseValue).AppendLine();
}
public struct SecuritySectorExtent
{
/// <summary>Bytes 0 to 2 Unknown</summary>
public uint Unknown;
/// <summary>Bytes 3 to 5 Start PSN of this security extent</summary>
public uint StartPSN;
/// <summary>Bytes 6 to 8 End PSN of this security extent</summary>
public uint EndPSN;
}
for(int i = 0; i < 16; i++)
sb.AppendFormat("Extent starts at PSN {0:X6}h and ends at PSN {1:X6}h", decoded.Extents[i].StartPSN,
decoded.Extents[i].EndPSN).AppendLine();
public struct ChallengeEntry
{
public byte Level;
public byte ChallengeId;
public uint ChallengeValue;
public byte ResponseModifier;
public uint ResponseValue;
}
return sb.ToString();
}
public static string Prettify(byte[] response) => Prettify(Decode(response));
public struct SecuritySector
{
/// <summary>Byte 0, bits 7 to 4 Disk category field</summary>
public DiskCategory DiskCategory;
/// <summary>Byte 0, bits 3 to 0 Media version</summary>
public byte PartVersion;
/// <summary>Byte 1, bits 7 to 4 120mm if 0, 80mm if 1. If UMD (60mm) 0 also. Reserved rest of values</summary>
public DVDSize DiscSize;
/// <summary>Byte 1, bits 3 to 0 Maximum data rate</summary>
public MaximumRateField MaximumRate;
/// <summary>Byte 2, bit 7 Reserved</summary>
public bool Reserved3;
/// <summary>Byte 2, bits 6 to 5 Number of layers</summary>
public byte Layers;
/// <summary>Byte 2, bit 4 Track path</summary>
public bool TrackPath;
/// <summary>Byte 2, bits 3 to 0 Layer type</summary>
public LayerTypeFieldMask LayerType;
/// <summary>Byte 3, bits 7 to 4 Linear density field</summary>
public LinearDensityField LinearDensity;
/// <summary>Byte 3, bits 3 to 0 Track density field</summary>
public TrackDensityField TrackDensity;
/// <summary>Bytes 4 to 7 PSN where Data Area starts</summary>
public uint DataAreaStartPSN;
/// <summary>Bytes 8 to 11 PSN where Data Area ends</summary>
public uint DataAreaEndPSN;
/// <summary>Bytes 12 to 15 PSN where Data Area ends in Layer 0</summary>
public uint Layer0EndPSN;
/// <summary>Byte 27 Always 0x06 on XGD3</summary>
public byte Unknown1;
/// <summary>Bytes 256 to 283 Unknown, XGD2 and XGD3</summary>
public byte[] Unknown2;
/// <summary>Bytes 284 to 719 Unknown, XGD3</summary>
public byte[] Unknown3;
/// <summary>Bytes 720 to 723 Unknown</summary>
public byte[] Unknown4;
/// <summary>Bytes 724 to 767 Unknown, XGD3</summary>
public byte[] Unknown5;
/// <summary>Byte 768 Version of challenge table</summary>
public byte ChallengeTableVersion;
/// <summary>Byte 769 Number of challenge entries</summary>
public byte NoChallengeEntries;
/// <summary>Bytes 770 to 1022 Unknown</summary>
public ChallengeEntry[] ChallengeEntries;
/// <summary>Byte 1023 Unknown</summary>
public byte Unknown6;
/// <summary>Bytes 1052 to 1099 Unknown, XGD1 only</summary>
public byte[] Unknown7;
/// <summary>Bytes 1120 to 1135 Unknown, XGD2 and XGD3</summary>
public byte[] Unknown8;
/// <summary>Bytes 1180 to 1195 Unknown</summary>
public byte[] Unknown9;
/// <summary>Bytes 1208 to 1511 Unknown</summary>
public byte[] Unknown10;
/// <summary>Bytes 1528 to 1632</summary>
public byte[] Unknown11;
/// <summary>Bytes 1633 to 1839 Security extents, 23 entries of 9 bytes</summary>
public SecuritySectorExtent[] Extents;
/// <summary>Bytes 1840 to 2047 Copy of the security extents, 23 entries of 9 bytes</summary>
public SecuritySectorExtent[] ExtentsCopy;
}
public struct SecuritySectorExtent
{
/// <summary>Bytes 0 to 2 Unknown</summary>
public uint Unknown;
/// <summary>Bytes 3 to 5 Start PSN of this security extent</summary>
public uint StartPSN;
/// <summary>Bytes 6 to 8 End PSN of this security extent</summary>
public uint EndPSN;
}
public struct ChallengeEntry
{
public byte Level;
public byte ChallengeId;
public uint ChallengeValue;
public byte ResponseModifier;
public uint ResponseValue;
}
}