2017-05-23 22:58:02 +01:00
|
|
|
|
// /***************************************************************************
|
|
|
|
|
|
// The Disc Image Chef
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
//
|
|
|
|
|
|
// Filename : SS.cs
|
|
|
|
|
|
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
|
|
|
|
|
//
|
2017-12-19 03:50:57 +00:00
|
|
|
|
// Component : Device structures decoders.
|
2017-05-23 22:58:02 +01:00
|
|
|
|
//
|
|
|
|
|
|
// --[ Description ] ----------------------------------------------------------
|
|
|
|
|
|
//
|
2017-12-19 03:50:57 +00:00
|
|
|
|
// Decodes Xbox security sectors
|
2017-05-23 22:58:02 +01:00
|
|
|
|
//
|
|
|
|
|
|
// --[ License ] --------------------------------------------------------------
|
|
|
|
|
|
//
|
|
|
|
|
|
// This library is free software; you can redistribute it and/or modify
|
|
|
|
|
|
// it under the terms of the GNU Lesser General Public License as
|
|
|
|
|
|
// published by the Free Software Foundation; either version 2.1 of the
|
|
|
|
|
|
// License, or (at your option) any later version.
|
|
|
|
|
|
//
|
|
|
|
|
|
// This library is distributed in the hope that it will be useful, but
|
|
|
|
|
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
|
// Lesser General Public License for more details.
|
|
|
|
|
|
//
|
|
|
|
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
|
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
//
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
2018-12-29 17:34:38 +00:00
|
|
|
|
// Copyright © 2011-2019 Natalia Portillo
|
2017-05-23 22:58:02 +01:00
|
|
|
|
// ****************************************************************************/
|
2017-12-19 19:33:46 +00:00
|
|
|
|
|
2017-05-23 22:58:02 +01:00
|
|
|
|
using System;
|
2017-12-22 02:04:18 +00:00
|
|
|
|
using System.Diagnostics.CodeAnalysis;
|
2017-05-23 22:58:02 +01:00
|
|
|
|
using System.Text;
|
|
|
|
|
|
using DiscImageChef.Decoders.DVD;
|
|
|
|
|
|
|
|
|
|
|
|
namespace DiscImageChef.Decoders.Xbox
|
|
|
|
|
|
{
|
2017-12-22 02:04:18 +00:00
|
|
|
|
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
|
|
|
|
|
[SuppressMessage("ReSharper", "MemberCanBeInternal")]
|
|
|
|
|
|
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
|
|
|
|
|
|
[SuppressMessage("ReSharper", "NotAccessedField.Global")]
|
2017-05-23 22:58:02 +01:00
|
|
|
|
public static class SS
|
|
|
|
|
|
{
|
|
|
|
|
|
public struct SecuritySector
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
2017-12-23 18:31:38 +00:00
|
|
|
|
/// Byte 0, bits 7 to 4
|
|
|
|
|
|
/// Disk category field
|
2017-05-23 22:58:02 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public DiskCategory DiskCategory;
|
|
|
|
|
|
/// <summary>
|
2017-12-23 18:31:38 +00:00
|
|
|
|
/// Byte 0, bits 3 to 0
|
|
|
|
|
|
/// Media version
|
2017-05-23 22:58:02 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public byte PartVersion;
|
|
|
|
|
|
/// <summary>
|
2017-12-23 18:31:38 +00:00
|
|
|
|
/// Byte 1, bits 7 to 4
|
|
|
|
|
|
/// 120mm if 0, 80mm if 1. If UMD (60mm) 0 also. Reserved rest of values
|
2017-05-23 22:58:02 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public DVDSize DiscSize;
|
|
|
|
|
|
/// <summary>
|
2017-12-23 18:31:38 +00:00
|
|
|
|
/// Byte 1, bits 3 to 0
|
|
|
|
|
|
/// Maximum data rate
|
2017-05-23 22:58:02 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public MaximumRateField MaximumRate;
|
|
|
|
|
|
/// <summary>
|
2017-12-23 18:31:38 +00:00
|
|
|
|
/// Byte 2, bit 7
|
|
|
|
|
|
/// Reserved
|
2017-05-23 22:58:02 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public bool Reserved3;
|
|
|
|
|
|
/// <summary>
|
2017-12-23 18:31:38 +00:00
|
|
|
|
/// Byte 2, bits 6 to 5
|
|
|
|
|
|
/// Number of layers
|
2017-05-23 22:58:02 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public byte Layers;
|
|
|
|
|
|
/// <summary>
|
2017-12-23 18:31:38 +00:00
|
|
|
|
/// Byte 2, bit 4
|
|
|
|
|
|
/// Track path
|
2017-05-23 22:58:02 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public bool TrackPath;
|
|
|
|
|
|
/// <summary>
|
2017-12-23 18:31:38 +00:00
|
|
|
|
/// Byte 2, bits 3 to 0
|
|
|
|
|
|
/// Layer type
|
2017-05-23 22:58:02 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public LayerTypeFieldMask LayerType;
|
|
|
|
|
|
/// <summary>
|
2017-12-23 18:31:38 +00:00
|
|
|
|
/// Byte 3, bits 7 to 4
|
|
|
|
|
|
/// Linear density field
|
2017-05-23 22:58:02 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public LinearDensityField LinearDensity;
|
|
|
|
|
|
/// <summary>
|
2017-12-23 18:31:38 +00:00
|
|
|
|
/// Byte 3, bits 3 to 0
|
|
|
|
|
|
/// Track density field
|
2017-05-23 22:58:02 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public TrackDensityField TrackDensity;
|
|
|
|
|
|
/// <summary>
|
2017-12-23 18:31:38 +00:00
|
|
|
|
/// Bytes 4 to 7
|
|
|
|
|
|
/// PSN where Data Area starts
|
2017-05-23 22:58:02 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public uint DataAreaStartPSN;
|
|
|
|
|
|
/// <summary>
|
2017-12-23 18:31:38 +00:00
|
|
|
|
/// Bytes 8 to 11
|
|
|
|
|
|
/// PSN where Data Area ends
|
2017-05-23 22:58:02 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public uint DataAreaEndPSN;
|
|
|
|
|
|
/// <summary>
|
2017-12-23 18:31:38 +00:00
|
|
|
|
/// Bytes 12 to 15
|
|
|
|
|
|
/// PSN where Data Area ends in Layer 0
|
2017-05-23 22:58:02 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public uint Layer0EndPSN;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2017-12-23 18:31:38 +00:00
|
|
|
|
/// Byte 27
|
|
|
|
|
|
/// Always 0x06 on XGD3
|
2017-05-23 22:58:02 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public byte Unknown1;
|
|
|
|
|
|
/// <summary>
|
2017-12-23 18:31:38 +00:00
|
|
|
|
/// Bytes 256 to 283
|
|
|
|
|
|
/// Unknown, XGD2 and XGD3
|
2017-05-23 22:58:02 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public byte[] Unknown2;
|
|
|
|
|
|
/// <summary>
|
2017-12-23 18:31:38 +00:00
|
|
|
|
/// Bytes 284 to 719
|
|
|
|
|
|
/// Unknown, XGD3
|
2017-05-23 22:58:02 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public byte[] Unknown3;
|
|
|
|
|
|
/// <summary>
|
2017-12-23 18:31:38 +00:00
|
|
|
|
/// Bytes 720 to 723
|
|
|
|
|
|
/// Unknown
|
2017-05-23 22:58:02 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public byte[] Unknown4;
|
|
|
|
|
|
/// <summary>
|
2017-12-23 18:31:38 +00:00
|
|
|
|
/// Bytes 724 to 767
|
|
|
|
|
|
/// Unknown, XGD3
|
2017-05-23 22:58:02 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public byte[] Unknown5;
|
|
|
|
|
|
/// <summary>
|
2017-12-23 18:31:38 +00:00
|
|
|
|
/// Byte 768
|
|
|
|
|
|
/// Version of challenge table
|
2017-05-23 22:58:02 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public byte ChallengeTableVersion;
|
|
|
|
|
|
/// <summary>
|
2017-12-23 18:31:38 +00:00
|
|
|
|
/// Byte 769
|
|
|
|
|
|
/// Number of challenge entries
|
2017-05-23 22:58:02 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public byte NoChallengeEntries;
|
|
|
|
|
|
/// <summary>
|
2017-12-23 18:31:38 +00:00
|
|
|
|
/// Bytes 770 to 1022
|
|
|
|
|
|
/// Unknown
|
2017-05-23 22:58:02 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public ChallengeEntry[] ChallengeEntries;
|
|
|
|
|
|
/// <summary>
|
2017-12-23 18:31:38 +00:00
|
|
|
|
/// Byte 1023
|
|
|
|
|
|
/// Unknown
|
2017-05-23 22:58:02 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public byte Unknown6;
|
|
|
|
|
|
/// <summary>
|
2017-12-23 18:31:38 +00:00
|
|
|
|
/// Bytes 1052 to 1099
|
|
|
|
|
|
/// Unknown, XGD1 only
|
2017-05-23 22:58:02 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public byte[] Unknown7;
|
|
|
|
|
|
/// <summary>
|
2017-12-23 18:31:38 +00:00
|
|
|
|
/// Bytes 1120 to 1135
|
|
|
|
|
|
/// Unknown, XGD2 and XGD3
|
2017-05-23 22:58:02 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public byte[] Unknown8;
|
|
|
|
|
|
/// <summary>
|
2017-12-23 18:31:38 +00:00
|
|
|
|
/// Bytes 1180 to 1195
|
|
|
|
|
|
/// Unknown
|
2017-05-23 22:58:02 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public byte[] Unknown9;
|
|
|
|
|
|
/// <summary>
|
2017-12-23 18:31:38 +00:00
|
|
|
|
/// Bytes 1208 to 1511
|
|
|
|
|
|
/// Unknown
|
2017-05-23 22:58:02 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public byte[] Unknown10;
|
|
|
|
|
|
/// <summary>
|
2017-12-23 18:31:38 +00:00
|
|
|
|
/// Bytes 1528 to 1632
|
2017-05-23 22:58:02 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public byte[] Unknown11;
|
|
|
|
|
|
/// <summary>
|
2017-12-23 18:31:38 +00:00
|
|
|
|
/// Bytes 1633 to 1839
|
|
|
|
|
|
/// Security extents, 23 entries of 9 bytes
|
2017-05-23 22:58:02 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public SecuritySectorExtent[] Extents;
|
|
|
|
|
|
/// <summary>
|
2017-12-23 18:31:38 +00:00
|
|
|
|
/// Bytes 1840 to 2047
|
|
|
|
|
|
/// Copy of the security extents, 23 entries of 9 bytes
|
2017-05-23 22:58:02 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public SecuritySectorExtent[] ExtentsCopy;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public struct SecuritySectorExtent
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
2017-12-23 18:31:38 +00:00
|
|
|
|
/// Bytes 0 to 2
|
|
|
|
|
|
/// Unknown
|
2017-05-23 22:58:02 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public uint Unknown;
|
|
|
|
|
|
/// <summary>
|
2017-12-23 18:31:38 +00:00
|
|
|
|
/// Bytes 3 to 5
|
|
|
|
|
|
/// Start PSN of this security extent
|
2017-05-23 22:58:02 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public uint StartPSN;
|
|
|
|
|
|
/// <summary>
|
2017-12-23 18:31:38 +00:00
|
|
|
|
/// Bytes 6 to 8
|
|
|
|
|
|
/// End PSN of this security extent
|
2017-05-23 22:58:02 +01:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public uint EndPSN;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public struct ChallengeEntry
|
|
|
|
|
|
{
|
|
|
|
|
|
public byte Level;
|
|
|
|
|
|
public byte ChallengeId;
|
|
|
|
|
|
public uint ChallengeValue;
|
|
|
|
|
|
public byte ResponseModifier;
|
|
|
|
|
|
public uint ResponseValue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static SecuritySector? Decode(byte[] response)
|
|
|
|
|
|
{
|
2017-12-19 20:33:03 +00:00
|
|
|
|
if(response == null) return null;
|
2017-05-23 22:58:02 +01:00
|
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
|
if(response.Length < 2048) return null;
|
2017-05-23 22:58:02 +01:00
|
|
|
|
|
2017-12-22 02:04:18 +00:00
|
|
|
|
SecuritySector ss = new SecuritySector
|
|
|
|
|
|
{
|
2018-06-22 08:08:38 +01:00
|
|
|
|
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),
|
2017-12-22 02:04:18 +00:00
|
|
|
|
LinearDensity = (LinearDensityField)((response[3] & 0xF0) >> 4),
|
2018-06-22 08:08:38 +01:00
|
|
|
|
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],
|
2017-12-22 02:04:18 +00:00
|
|
|
|
ChallengeTableVersion = response[768],
|
2018-06-22 08:08:38 +01:00
|
|
|
|
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]
|
2017-12-22 02:04:18 +00:00
|
|
|
|
};
|
2017-05-23 22:58:02 +01:00
|
|
|
|
|
|
|
|
|
|
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);
|
2017-12-22 02:04:18 +00:00
|
|
|
|
|
2017-05-23 22:58:02 +01:00
|
|
|
|
for(int i = 0; i < 23; i++)
|
2017-12-22 02:04:18 +00:00
|
|
|
|
ss.ChallengeEntries[i] = new ChallengeEntry
|
2017-12-23 18:31:38 +00:00
|
|
|
|
{
|
2018-06-22 08:08:38 +01:00
|
|
|
|
Level = response[770 + i * 11 + 0],
|
2017-12-22 02:04:18 +00:00
|
|
|
|
ChallengeId = response[770 + i * 11 + 1],
|
|
|
|
|
|
ChallengeValue =
|
|
|
|
|
|
(uint)((response[770 + i * 11 + 2] << 24) + (response[770 + i * 11 + 3] << 16) +
|
2018-06-22 08:08:38 +01:00
|
|
|
|
(response[770 + i * 11 + 4] << 8) + response[770 + i * 11 + 5]),
|
2017-12-22 02:04:18 +00:00
|
|
|
|
ResponseModifier = response[770 + i * 11 + 6],
|
|
|
|
|
|
ResponseValue = (uint)((response[770 + i * 11 + 7] << 24) + (response[770 + i * 11 + 8] << 16) +
|
2018-06-22 08:08:38 +01:00
|
|
|
|
(response[770 + i * 11 + 9] << 8) + response[770 + i * 11 + 10])
|
2017-12-22 02:04:18 +00:00
|
|
|
|
};
|
2017-12-19 20:33:03 +00:00
|
|
|
|
|
2018-06-22 08:08:38 +01:00
|
|
|
|
Array.Copy(response, 1052, ss.Unknown7, 0, 48);
|
|
|
|
|
|
Array.Copy(response, 1120, ss.Unknown8, 0, 16);
|
|
|
|
|
|
Array.Copy(response, 1180, ss.Unknown9, 0, 16);
|
2017-05-23 22:58:02 +01:00
|
|
|
|
Array.Copy(response, 1208, ss.Unknown10, 0, 303);
|
|
|
|
|
|
Array.Copy(response, 1528, ss.Unknown11, 0, 104);
|
|
|
|
|
|
for(int i = 0; i < 23; i++)
|
2017-12-22 02:04:18 +00:00
|
|
|
|
ss.Extents[i] = new SecuritySectorExtent
|
2017-12-23 18:31:38 +00:00
|
|
|
|
{
|
2017-12-22 02:04:18 +00:00
|
|
|
|
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])
|
|
|
|
|
|
};
|
2017-12-19 20:33:03 +00:00
|
|
|
|
|
2017-05-23 22:58:02 +01:00
|
|
|
|
for(int i = 0; i < 23; i++)
|
2017-12-22 02:04:18 +00:00
|
|
|
|
ss.ExtentsCopy[i] = new SecuritySectorExtent
|
2017-12-23 18:31:38 +00:00
|
|
|
|
{
|
2017-12-22 02:04:18 +00:00
|
|
|
|
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])
|
|
|
|
|
|
};
|
2017-12-19 20:33:03 +00:00
|
|
|
|
|
2017-05-23 22:58:02 +01:00
|
|
|
|
return ss;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static string Prettify(SecuritySector? ss)
|
|
|
|
|
|
{
|
2017-12-19 20:33:03 +00:00
|
|
|
|
if(ss == null) return null;
|
2017-05-23 22:58:02 +01:00
|
|
|
|
|
|
|
|
|
|
SecuritySector decoded = ss.Value;
|
2018-06-22 08:08:38 +01:00
|
|
|
|
StringBuilder sb = new StringBuilder();
|
2017-05-23 22:58:02 +01:00
|
|
|
|
|
|
|
|
|
|
string sizeString;
|
|
|
|
|
|
switch(decoded.DiscSize)
|
|
|
|
|
|
{
|
|
|
|
|
|
case DVDSize.Eighty:
|
|
|
|
|
|
sizeString = "80mm";
|
|
|
|
|
|
break;
|
|
|
|
|
|
case DVDSize.OneTwenty:
|
|
|
|
|
|
sizeString = "120mm";
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
2017-12-21 17:58:51 +00:00
|
|
|
|
sizeString = $"unknown size identifier {decoded.DiscSize}";
|
2017-05-23 22:58:02 +01:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-12-22 02:04:18 +00:00
|
|
|
|
const string categorySentence = "Disc is a {0} {1} version {2}";
|
2017-05-23 22:58:02 +01:00
|
|
|
|
|
|
|
|
|
|
switch(decoded.DiskCategory)
|
|
|
|
|
|
{
|
|
|
|
|
|
case DiskCategory.DVDPRWDL:
|
|
|
|
|
|
sb.AppendFormat(categorySentence, sizeString, "Xbox Game Disc", decoded.PartVersion).AppendLine();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case DiskCategory.DVDPRDL:
|
2017-12-19 20:33:03 +00:00
|
|
|
|
sb.AppendFormat(categorySentence, sizeString, "Xbox 360 Game Disc", decoded.PartVersion)
|
|
|
|
|
|
.AppendLine();
|
2017-05-23 22:58:02 +01:00
|
|
|
|
break;
|
|
|
|
|
|
default:
|
2017-12-19 20:33:03 +00:00
|
|
|
|
sb.AppendFormat(categorySentence, sizeString, "unknown disc type", decoded.PartVersion)
|
|
|
|
|
|
.AppendLine();
|
2017-05-23 22:58:02 +01:00
|
|
|
|
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:
|
2017-12-19 20:33:03 +00:00
|
|
|
|
sb.AppendFormat("Disc maximum transfer rate is specified by unknown key {0}", decoded.MaximumRate)
|
|
|
|
|
|
.AppendLine();
|
2017-05-23 22:58:02 +01:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
sb.AppendFormat("Disc has {0} layers", decoded.Layers + 1).AppendLine();
|
2018-06-22 08:08:38 +01:00
|
|
|
|
if(decoded.TrackPath && decoded.Layers == 1) sb.AppendLine("Layers are in parallel track path");
|
2017-12-19 20:33:03 +00:00
|
|
|
|
else if(!decoded.TrackPath && decoded.Layers == 1) sb.AppendLine("Layers are in opposite track path");
|
2017-05-23 22:58:02 +01:00
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
|
}
|
2018-06-22 08:08:38 +01:00
|
|
|
|
else
|
|
|
|
|
|
sb.AppendLine("Disc is empty");
|
2017-12-19 20:33:03 +00:00
|
|
|
|
else sb.AppendLine("Disc is empty");
|
2017-05-23 22:58:02 +01:00
|
|
|
|
|
|
|
|
|
|
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++)
|
2017-12-19 20:33:03 +00:00
|
|
|
|
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();
|
2017-05-23 22:58:02 +01:00
|
|
|
|
|
|
|
|
|
|
return sb.ToString();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-12-31 13:17:27 +00:00
|
|
|
|
public static string Prettify(byte[] response) => Prettify(Decode(response));
|
2017-05-23 22:58:02 +01:00
|
|
|
|
}
|
2017-12-19 20:33:03 +00:00
|
|
|
|
}
|