diff --git a/Blu-ray/BCA.cs b/Blu-ray/BCA.cs new file mode 100644 index 000000000..90a332f3f --- /dev/null +++ b/Blu-ray/BCA.cs @@ -0,0 +1,141 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : BCA.cs +// Version : 1.0 +// Author(s) : Natalia Portillo +// +// Component : Component +// +// Revision : $Revision$ +// Last change by : $Author$ +// Date : $Date$ +// +// --[ Description ] ---------------------------------------------------------- +// +// Description +// +// --[ License ] -------------------------------------------------------------- +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// ---------------------------------------------------------------------------- +// Copyright (C) 2011-2015 Claunia.com +// ****************************************************************************/ +// //$Id$ +using System; +using DiscImageChef.Console; +using System.Text; + +namespace DiscImageChef.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 + /// + public static class BCA + { + #region Public methods + public static BurstCuttingArea? Decode(byte[] BCAResponse) + { + if (BCAResponse == null) + return null; + + if (BCAResponse.Length != 68) + { + DicConsole.DebugWriteLine("BD BCA decoder", "Found incorrect Blu-ray BCA size ({0} bytes)", BCAResponse.Length); + return null; + } + + BurstCuttingArea decoded = new BurstCuttingArea(); + + BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian; + + decoded.DataLength = BigEndianBitConverter.ToUInt16(BCAResponse, 0); + decoded.Reserved1 = BCAResponse[2]; + decoded.Reserved2 = BCAResponse[3]; + decoded.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; + + StringBuilder 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) + { + return Prettify(Decode(BCAResponse)); + } + #endregion Public methods + + #region Public structures + public struct BurstCuttingArea + { + /// + /// Bytes 0 to 1 + /// Always 66 + /// + public UInt16 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 + } +} + diff --git a/Blu-ray/BD.cs b/Blu-ray/BD.cs deleted file mode 100644 index 4e89cca4a..000000000 --- a/Blu-ray/BD.cs +++ /dev/null @@ -1,849 +0,0 @@ -/*************************************************************************** -The Disc Image Chef ----------------------------------------------------------------------------- - -Filename : BD.cs -Version : 1.0 -Author(s) : Natalia Portillo - -Component : Decoders. - -Revision : $Revision$ -Last change by : $Author$ -Date : $Date$ - ---[ Description ] ---------------------------------------------------------- - -Decodes Blu-ray structures. - ---[ License ] -------------------------------------------------------------- - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - ----------------------------------------------------------------------------- -Copyright (C) 2011-2014 Claunia.com -****************************************************************************/ -//$Id$ -using System; -using System.Text; -using System.Collections.Generic; -using DiscImageChef.Console; - -namespace DiscImageChef.Decoders -{ - /// - /// 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 - /// - public static class BD - { - #region Private constants - const string DiscTypeBDROM = "BDO"; - const string DiscTypeBDRE = "BDW"; - const string DiscTypeBDR = "BDR"; - - /// - /// Disc Definition Structure Identifier "DS" - /// - const UInt16 DDSIdentifier = 0x4453; - /// - /// Disc Information Unit Identifier "DI" - /// - const UInt16 DIUIdentifier = 0x4449; - #endregion Private constants - - #region Public methods - public static DiscInformation? DecodeDiscInformation(byte[] DIResponse) - { - if (DIResponse == null) - return null; - - if (DIResponse.Length != 4100) - { - DicConsole.DebugWriteLine("BD Disc Information decoder", "Found incorrect Blu-ray Disc Information size ({0} bytes)", DIResponse.Length); - - return null; - } - - DiscInformation decoded = new DiscInformation(); - - BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian; - - decoded.DataLength = BigEndianBitConverter.ToUInt16(DIResponse, 0); - decoded.Reserved1 = DIResponse[2]; - decoded.Reserved2 = DIResponse[3]; - - int offset = 4; - List units = new List(); - - while (true) - { - if (offset >= 100) - break; - - DiscInformationUnits unit = new DiscInformationUnits(); - unit.Signature = BigEndianBitConverter.ToUInt16(DIResponse, 0 + offset); - - if (unit.Signature != DIUIdentifier) - break; - - unit.Format = DIResponse[2 + offset]; - unit.UnitsPerBlock = DIResponse[3 + offset]; - unit.Legacy = DIResponse[4 + offset]; - unit.Sequence = DIResponse[5 + offset]; - unit.Length = DIResponse[6 + offset]; - unit.Reserved = DIResponse[7 + offset]; - unit.DiscTypeIdentifier = new byte[3]; - Array.Copy(DIResponse, 8 + offset, unit.DiscTypeIdentifier, 0, 3); - unit.DiscSizeClassVersion = DIResponse[11 + offset]; - switch (Encoding.ASCII.GetString(unit.DiscTypeIdentifier)) - { - case DiscTypeBDROM: - { - unit.FormatDependentContents = new byte[52]; - Array.Copy(DIResponse, 12 + offset, unit.DiscTypeIdentifier, 0, 52); - break; - } - case DiscTypeBDRE: - case DiscTypeBDR: - { - unit.FormatDependentContents = new byte[88]; - Array.Copy(DIResponse, 12 + offset, unit.DiscTypeIdentifier, 0, 88); - 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]; - break; - } - default: - { - DicConsole.DebugWriteLine("BD Disc Information decoder", "Found unknown disc type identifier \"{0}\"", Encoding.ASCII.GetString(unit.DiscTypeIdentifier)); - break; - } - } - - units.Add(unit); - - offset += unit.Length; - } - - if (units.Count > 0) - { - decoded.Units = new DiscInformationUnits[units.Count]; - for (int i = 0; i < units.Count; i++) - decoded.Units[i] = units[i]; - } - - return decoded; - } - - public static string PrettifyDiscInformation(DiscInformation? DIResponse) - { - if (DIResponse == null) - return null; - - DiscInformation response = DIResponse.Value; - - StringBuilder 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(); - if (Encoding.ASCII.GetString(unit.DiscTypeIdentifier) != DiscTypeBDROM) - sb.AppendFormat("Legacy value: 0x{0:X2}", unit.Legacy).AppendLine(); - sb.AppendFormat("DI Unit is {0} bytes", unit.Length).AppendLine(); - sb.AppendFormat("Disc type identifier: \"{0}\"", Encoding.ASCII.GetString(unit.DiscTypeIdentifier)).AppendLine(); - sb.AppendFormat("Disc size/class/version: {0}", unit.DiscSizeClassVersion).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 PrettifyDiscInformation(byte[] DIResponse) - { - DiscInformation? decoded = DecodeDiscInformation(DIResponse); - return PrettifyDiscInformation(decoded); - } - - public static BurstCuttingArea? DecodeBurstCuttingArea(byte[] BCAResponse) - { - if (BCAResponse == null) - return null; - - if (BCAResponse.Length != 68) - { - DicConsole.DebugWriteLine("BD BCA decoder", "Found incorrect Blu-ray BCA size ({0} bytes)", BCAResponse.Length); - - return null; - } - - BurstCuttingArea decoded = new BurstCuttingArea(); - - BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian; - - decoded.DataLength = BigEndianBitConverter.ToUInt16(BCAResponse, 0); - decoded.Reserved1 = BCAResponse[2]; - decoded.Reserved2 = BCAResponse[3]; - decoded.BCA = new byte[64]; - Array.Copy(BCAResponse, 4, decoded.BCA, 0, 64); - - return decoded; - } - - public static string PrettifyBurstCuttingArea(BurstCuttingArea? BCAResponse) - { - if (BCAResponse == null) - return null; - - BurstCuttingArea response = BCAResponse.Value; - - StringBuilder 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 PrettifyBurstCuttingArea(byte[] BCAResponse) - { - BurstCuttingArea? decoded = DecodeBurstCuttingArea(BCAResponse); - return PrettifyBurstCuttingArea(decoded); - } - - public static DiscDefinitionStructure? DecodeDDS(byte[] DDSResponse) - { - if (DDSResponse == null) - return null; - - DiscDefinitionStructure decoded = new DiscDefinitionStructure(); - - BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian; - - decoded.DataLength = BigEndianBitConverter.ToUInt16(DDSResponse, 0); - decoded.Reserved1 = DDSResponse[2]; - decoded.Reserved2 = DDSResponse[3]; - decoded.Signature = BigEndianBitConverter.ToUInt16(DDSResponse, 4); - if (decoded.Signature != DDSIdentifier) - { - DicConsole.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 PrettifyDDS(DiscDefinitionStructure? DDSResponse) - { - if (DDSResponse == null) - return null; - - DiscDefinitionStructure response = DDSResponse.Value; - - StringBuilder 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 PrettifyDDS(byte[] DDSResponse) - { - DiscDefinitionStructure? decoded = DecodeDDS(DDSResponse); - return PrettifyDDS(decoded); - } - - public static CartridgeStatus? DecodeCartridgeStatus(byte[] CSResponse) - { - if (CSResponse == null) - return null; - - if (CSResponse.Length != 8) - { - DicConsole.DebugWriteLine("BD Cartridge Status decoder", "Found incorrect Blu-ray Cartridge Status size ({0} bytes)", CSResponse.Length); - - return null; - } - - CartridgeStatus decoded = new CartridgeStatus(); - - BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian; - - decoded.DataLength = BigEndianBitConverter.ToUInt16(CSResponse, 0); - decoded.Reserved1 = CSResponse[2]; - decoded.Reserved2 = CSResponse[3]; - decoded.Cartridge = Convert.ToBoolean(CSResponse[4] & 0x80); - decoded.OUT = Convert.ToBoolean(CSResponse[4]&0x40); - decoded.Reserved3 = (byte)((CSResponse[4] & 0x38) >> 3); - decoded.OUT = Convert.ToBoolean(CSResponse[4]&0x04); - decoded.Reserved4 = (byte)(CSResponse[4] & 0x03); - decoded.Reserved5 = CSResponse[5]; - decoded.Reserved6 = CSResponse[6]; - decoded.Reserved7 = CSResponse[7]; - - return decoded; - } - - public static string PrettifyCartridgeStatus(CartridgeStatus? CSResponse) - { - if (CSResponse == null) - return null; - - CartridgeStatus response = CSResponse.Value; - - StringBuilder 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.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 PrettifyCartridgeStatus(byte[] CSResponse) - { - CartridgeStatus? decoded = DecodeCartridgeStatus(CSResponse); - return PrettifyCartridgeStatus(decoded); - } - - public static SpareAreaInformation? DecodeCDTOC(byte[] SAIResponse) - { - if (SAIResponse == null) - return null; - - if (SAIResponse.Length != 16) - { - DicConsole.DebugWriteLine("BD Spare Area Information decoder", "Found incorrect Blu-ray Spare Area Information size ({0} bytes)", SAIResponse.Length); - - return null; - } - - SpareAreaInformation decoded = new SpareAreaInformation(); - - BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian; - - decoded.DataLength = BigEndianBitConverter.ToUInt16(SAIResponse, 0); - decoded.Reserved1 = SAIResponse[2]; - decoded.Reserved2 = SAIResponse[3]; - decoded.Reserved3 = BigEndianBitConverter.ToUInt32(SAIResponse, 4); - decoded.FreeSpareBlocks = BigEndianBitConverter.ToUInt32(SAIResponse, 8); - decoded.AllocatedSpareBlocks = BigEndianBitConverter.ToUInt32(SAIResponse, 12); - - return decoded; - } - - public static string PrettifySpareAreaInformation(SpareAreaInformation? SAIResponse) - { - if (SAIResponse == null) - return null; - - SpareAreaInformation response = SAIResponse.Value; - - StringBuilder 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 PrettifySpareAreaInformation(byte[] SAIResponse) - { - SpareAreaInformation? decoded = DecodeCDTOC(SAIResponse); - return PrettifySpareAreaInformation(decoded); - } - #endregion Public methods - - #region Public structures - public struct DiscInformation - { - /// - /// Bytes 0 to 1 - /// Always 4098 - /// - public UInt16 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 UInt16 Signature; - /// - /// Byte 2 - /// Disc information format - /// - public byte Format; - /// - /// Byte 3 - /// Number of DI units per block - /// - public byte UnitsPerBlock; - /// - /// 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 - /// 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 - /// Disc size/class/version - /// - public byte DiscSizeClassVersion; - /// - /// Bytes 12 to 63 for BD-ROM, bytes 12 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 UInt16 TimeStamp; - /// - /// Byte 111 - /// Product revision number - /// - public byte ProductRevisionNumber; - } - - public struct BurstCuttingArea - { - /// - /// Bytes 0 to 1 - /// Always 66 - /// - public UInt16 DataLength; - /// - /// Byte 2 - /// Reserved - /// - public byte Reserved1; - /// - /// Byte 3 - /// Reserved - /// - public byte Reserved2; - /// - /// Byte 4 to 67 - /// BCA data - /// - public byte[] BCA; - } - - public struct DiscDefinitionStructure - { - /// - /// Bytes 0 to 1 - /// Data Length - /// - public UInt16 DataLength; - /// - /// Byte 2 - /// Reserved - /// - public byte Reserved1; - /// - /// Byte 3 - /// Reserved - /// - public byte Reserved2; - /// - /// Bytes 4 to 5 - /// "DS" - /// - public UInt16 Signature; - /// - /// Byte 6 - /// DDS format - /// - public byte Format; - /// - /// Byte 7 - /// Reserved - /// - public byte Reserved3; - /// - /// Bytes 8 to 11 - /// DDS update count - /// - public UInt32 UpdateCount; - /// - /// Bytes 12 to 19 - /// Reserved - /// - public UInt64 Reserved4; - /// - /// Bytes 20 to 23 - /// First PSN of Drive Area - /// - public UInt32 DriveAreaPSN; - /// - /// Bytes 24 to 27 - /// Reserved - /// - public UInt32 Reserved5; - /// - /// Bytes 28 to 31 - /// First PSN of Defect List - /// - public UInt32 DefectListPSN; - /// - /// Bytes 32 to 35 - /// Reserved - /// - public UInt32 Reserved6; - /// - /// Bytes 36 to 39 - /// PSN of LSN 0 of user data area - /// - public UInt32 PSNofLSNZero; - /// - /// Bytes 40 to 43 - /// Last LSN of user data area - /// - public UInt32 LastUserAreaLSN; - /// - /// Bytes 44 to 47 - /// ISA0 size - /// - public UInt32 ISA0; - /// - /// Bytes 48 to 51 - /// OSA size - /// - public UInt32 OSA; - /// - /// Bytes 52 to 55 - /// ISA1 size - /// - public UInt32 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 UInt32 DiscTypeSpecificField2; - /// - /// Byte 64 to 67 - /// Reserved - /// - public UInt32 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; - } - - public struct CartridgeStatus - { - /// - /// Bytes 0 to 1 - /// Always 6 - /// - public UInt16 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; - } - - public struct SpareAreaInformation - { - /// - /// Bytes 0 to 1 - /// Always 14 - /// - public UInt16 DataLength; - /// - /// Byte 2 - /// Reserved - /// - public byte Reserved1; - /// - /// Byte 3 - /// Reserved - /// - public byte Reserved2; - /// - /// Bytes 4 to 7 - /// Reserved - /// - public UInt32 Reserved3; - /// - /// Bytes 8 to 11 - /// Free spare blocks - /// - public UInt32 FreeSpareBlocks; - /// - /// Bytes 12 to 15 - /// Allocated spare blocks - /// - public UInt32 AllocatedSpareBlocks; - } - #endregion Public structures - } -} - diff --git a/Blu-ray/Cartridge.cs b/Blu-ray/Cartridge.cs new file mode 100644 index 000000000..d3843e6aa --- /dev/null +++ b/Blu-ray/Cartridge.cs @@ -0,0 +1,208 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : Cartridge.cs +// Version : 1.0 +// Author(s) : Natalia Portillo +// +// Component : Component +// +// Revision : $Revision$ +// Last change by : $Author$ +// Date : $Date$ +// +// --[ Description ] ---------------------------------------------------------- +// +// Description +// +// --[ License ] -------------------------------------------------------------- +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// ---------------------------------------------------------------------------- +// Copyright (C) 2011-2015 Claunia.com +// ****************************************************************************/ +// //$Id$ +using System; +using DiscImageChef.Console; +using System.Text; + +namespace DiscImageChef.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 + /// + public static class Cartridge + { + #region Public methods + public static CartridgeStatus? Decode(byte[] CSResponse) + { + if (CSResponse == null) + return null; + + if (CSResponse.Length != 8) + { + DicConsole.DebugWriteLine("BD Cartridge Status decoder", "Found incorrect Blu-ray Cartridge Status size ({0} bytes)", CSResponse.Length); + return null; + } + + CartridgeStatus decoded = new CartridgeStatus(); + + BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian; + + decoded.DataLength = BigEndianBitConverter.ToUInt16(CSResponse, 0); + decoded.Reserved1 = CSResponse[2]; + decoded.Reserved2 = CSResponse[3]; + decoded.Cartridge = Convert.ToBoolean(CSResponse[4] & 0x80); + decoded.OUT = Convert.ToBoolean(CSResponse[4]&0x40); + decoded.Reserved3 = (byte)((CSResponse[4] & 0x38) >> 3); + decoded.OUT = Convert.ToBoolean(CSResponse[4]&0x04); + decoded.Reserved4 = (byte)(CSResponse[4] & 0x03); + decoded.Reserved5 = CSResponse[5]; + decoded.Reserved6 = CSResponse[6]; + decoded.Reserved7 = CSResponse[7]; + + return decoded; + } + + public static string Prettify(CartridgeStatus? CSResponse) + { + if (CSResponse == null) + return null; + + CartridgeStatus response = CSResponse.Value; + + StringBuilder 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.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) + { + return Prettify(Decode(CSResponse)); + } + #endregion Public methods + + #region Public structures + public struct CartridgeStatus + { + /// + /// Bytes 0 to 1 + /// Always 6 + /// + public UInt16 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 + } +} + diff --git a/Blu-ray/DDS.cs b/Blu-ray/DDS.cs new file mode 100644 index 000000000..b320b9688 --- /dev/null +++ b/Blu-ray/DDS.cs @@ -0,0 +1,303 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : DDS.cs +// Version : 1.0 +// Author(s) : Natalia Portillo +// +// Component : Component +// +// Revision : $Revision$ +// Last change by : $Author$ +// Date : $Date$ +// +// --[ Description ] ---------------------------------------------------------- +// +// Description +// +// --[ License ] -------------------------------------------------------------- +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// ---------------------------------------------------------------------------- +// Copyright (C) 2011-2015 Claunia.com +// ****************************************************************************/ +// //$Id$ +using System; +using DiscImageChef.Console; +using System.Text; + +namespace DiscImageChef.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 + /// + public static class DDS + { + #region Private constants + /// + /// Disc Definition Structure Identifier "DS" + /// + const UInt16 DDSIdentifier = 0x4453; + #endregion Private constants + + #region Public methods + public static DiscDefinitionStructure? Decode(byte[] DDSResponse) + { + if (DDSResponse == null) + return null; + + DiscDefinitionStructure decoded = new DiscDefinitionStructure(); + + BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian; + + decoded.DataLength = BigEndianBitConverter.ToUInt16(DDSResponse, 0); + decoded.Reserved1 = DDSResponse[2]; + decoded.Reserved2 = DDSResponse[3]; + decoded.Signature = BigEndianBitConverter.ToUInt16(DDSResponse, 4); + if (decoded.Signature != DDSIdentifier) + { + DicConsole.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; + + StringBuilder 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) + { + return Prettify(Decode(DDSResponse)); + } + #endregion Public methods + + #region Public structures + public struct DiscDefinitionStructure + { + /// + /// Bytes 0 to 1 + /// Data Length + /// + public UInt16 DataLength; + /// + /// Byte 2 + /// Reserved + /// + public byte Reserved1; + /// + /// Byte 3 + /// Reserved + /// + public byte Reserved2; + /// + /// Bytes 4 to 5 + /// "DS" + /// + public UInt16 Signature; + /// + /// Byte 6 + /// DDS format + /// + public byte Format; + /// + /// Byte 7 + /// Reserved + /// + public byte Reserved3; + /// + /// Bytes 8 to 11 + /// DDS update count + /// + public UInt32 UpdateCount; + /// + /// Bytes 12 to 19 + /// Reserved + /// + public UInt64 Reserved4; + /// + /// Bytes 20 to 23 + /// First PSN of Drive Area + /// + public UInt32 DriveAreaPSN; + /// + /// Bytes 24 to 27 + /// Reserved + /// + public UInt32 Reserved5; + /// + /// Bytes 28 to 31 + /// First PSN of Defect List + /// + public UInt32 DefectListPSN; + /// + /// Bytes 32 to 35 + /// Reserved + /// + public UInt32 Reserved6; + /// + /// Bytes 36 to 39 + /// PSN of LSN 0 of user data area + /// + public UInt32 PSNofLSNZero; + /// + /// Bytes 40 to 43 + /// Last LSN of user data area + /// + public UInt32 LastUserAreaLSN; + /// + /// Bytes 44 to 47 + /// ISA0 size + /// + public UInt32 ISA0; + /// + /// Bytes 48 to 51 + /// OSA size + /// + public UInt32 OSA; + /// + /// Bytes 52 to 55 + /// ISA1 size + /// + public UInt32 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 UInt32 DiscTypeSpecificField2; + /// + /// Byte 64 to 67 + /// Reserved + /// + public UInt32 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 + } +} + diff --git a/Blu-ray/DI.cs b/Blu-ray/DI.cs new file mode 100644 index 000000000..680901fe3 --- /dev/null +++ b/Blu-ray/DI.cs @@ -0,0 +1,301 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : DI.cs +// Version : 1.0 +// Author(s) : Natalia Portillo +// +// Component : Component +// +// Revision : $Revision$ +// Last change by : $Author$ +// Date : $Date$ +// +// --[ Description ] ---------------------------------------------------------- +// +// Description +// +// --[ License ] -------------------------------------------------------------- +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// ---------------------------------------------------------------------------- +// Copyright (C) 2011-2015 Claunia.com +// ****************************************************************************/ +// //$Id$ +using System; +using DiscImageChef.Console; +using System.Collections.Generic; +using System.Text; + +namespace DiscImageChef.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 + /// + public static class DI + { + #region Private constants + const string DiscTypeBDROM = "BDO"; + const string DiscTypeBDRE = "BDW"; + const string DiscTypeBDR = "BDR"; + + /// + /// Disc Information Unit Identifier "DI" + /// + const UInt16 DIUIdentifier = 0x4449; + #endregion Private constants + + #region Public methods + public static DiscInformation? Decode(byte[] DIResponse) + { + if (DIResponse == null) + return null; + + if (DIResponse.Length != 4100) + { + DicConsole.DebugWriteLine("BD Disc Information decoder", "Found incorrect Blu-ray Disc Information size ({0} bytes)", DIResponse.Length); + return null; + } + + DiscInformation decoded = new DiscInformation(); + + BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian; + + decoded.DataLength = BigEndianBitConverter.ToUInt16(DIResponse, 0); + decoded.Reserved1 = DIResponse[2]; + decoded.Reserved2 = DIResponse[3]; + + int offset = 4; + List units = new List(); + + while (true) + { + if (offset >= 100) + break; + + DiscInformationUnits unit = new DiscInformationUnits(); + unit.Signature = BigEndianBitConverter.ToUInt16(DIResponse, 0 + offset); + + if (unit.Signature != DIUIdentifier) + break; + + unit.Format = DIResponse[2 + offset]; + unit.UnitsPerBlock = DIResponse[3 + offset]; + unit.Legacy = DIResponse[4 + offset]; + unit.Sequence = DIResponse[5 + offset]; + unit.Length = DIResponse[6 + offset]; + unit.Reserved = DIResponse[7 + offset]; + unit.DiscTypeIdentifier = new byte[3]; + Array.Copy(DIResponse, 8 + offset, unit.DiscTypeIdentifier, 0, 3); + unit.DiscSizeClassVersion = DIResponse[11 + offset]; + switch (Encoding.ASCII.GetString(unit.DiscTypeIdentifier)) + { + case DiscTypeBDROM: + { + unit.FormatDependentContents = new byte[52]; + Array.Copy(DIResponse, 12 + offset, unit.DiscTypeIdentifier, 0, 52); + break; + } + case DiscTypeBDRE: + case DiscTypeBDR: + { + unit.FormatDependentContents = new byte[88]; + Array.Copy(DIResponse, 12 + offset, unit.DiscTypeIdentifier, 0, 88); + 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]; + break; + } + default: + { + DicConsole.DebugWriteLine("BD Disc Information decoder", "Found unknown disc type identifier \"{0}\"", Encoding.ASCII.GetString(unit.DiscTypeIdentifier)); + break; + } + } + + units.Add(unit); + + offset += unit.Length; + } + + if (units.Count > 0) + { + decoded.Units = new DiscInformationUnits[units.Count]; + for (int i = 0; i < units.Count; i++) + decoded.Units[i] = units[i]; + } + + return decoded; + } + + public static string Prettify(DiscInformation? DIResponse) + { + if (DIResponse == null) + return null; + + DiscInformation response = DIResponse.Value; + + StringBuilder 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(); + if (Encoding.ASCII.GetString(unit.DiscTypeIdentifier) != DiscTypeBDROM) + sb.AppendFormat("Legacy value: 0x{0:X2}", unit.Legacy).AppendLine(); + sb.AppendFormat("DI Unit is {0} bytes", unit.Length).AppendLine(); + sb.AppendFormat("Disc type identifier: \"{0}\"", Encoding.ASCII.GetString(unit.DiscTypeIdentifier)).AppendLine(); + sb.AppendFormat("Disc size/class/version: {0}", unit.DiscSizeClassVersion).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) + { + return Prettify(Decode(DIResponse)); + } + #endregion Public methods + + #region Public structures + public struct DiscInformation + { + /// + /// Bytes 0 to 1 + /// Always 4098 + /// + public UInt16 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 UInt16 Signature; + /// + /// Byte 2 + /// Disc information format + /// + public byte Format; + /// + /// Byte 3 + /// Number of DI units per block + /// + public byte UnitsPerBlock; + /// + /// 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 + /// 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 + /// Disc size/class/version + /// + public byte DiscSizeClassVersion; + /// + /// Bytes 12 to 63 for BD-ROM, bytes 12 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 UInt16 TimeStamp; + /// + /// Byte 111 + /// Product revision number + /// + public byte ProductRevisionNumber; + } + #endregion Public structures + } +} + diff --git a/Blu-ray/Spare.cs b/Blu-ray/Spare.cs new file mode 100644 index 000000000..e1e1092f0 --- /dev/null +++ b/Blu-ray/Spare.cs @@ -0,0 +1,153 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : Spare.cs +// Version : 1.0 +// Author(s) : Natalia Portillo +// +// Component : Component +// +// Revision : $Revision$ +// Last change by : $Author$ +// Date : $Date$ +// +// --[ Description ] ---------------------------------------------------------- +// +// Description +// +// --[ License ] -------------------------------------------------------------- +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// ---------------------------------------------------------------------------- +// Copyright (C) 2011-2015 Claunia.com +// ****************************************************************************/ +// //$Id$ +using System; +using DiscImageChef.Console; +using System.Text; + +namespace DiscImageChef.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 + /// + public static class Spare + { + #region Public methods + public static SpareAreaInformation? Decode(byte[] SAIResponse) + { + if (SAIResponse == null) + return null; + + if (SAIResponse.Length != 16) + { + DicConsole.DebugWriteLine("BD Spare Area Information decoder", "Found incorrect Blu-ray Spare Area Information size ({0} bytes)", SAIResponse.Length); + return null; + } + + SpareAreaInformation decoded = new SpareAreaInformation(); + + BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian; + + decoded.DataLength = BigEndianBitConverter.ToUInt16(SAIResponse, 0); + decoded.Reserved1 = SAIResponse[2]; + decoded.Reserved2 = SAIResponse[3]; + decoded.Reserved3 = BigEndianBitConverter.ToUInt32(SAIResponse, 4); + decoded.FreeSpareBlocks = BigEndianBitConverter.ToUInt32(SAIResponse, 8); + decoded.AllocatedSpareBlocks = BigEndianBitConverter.ToUInt32(SAIResponse, 12); + + return decoded; + } + + public static string Prettify(SpareAreaInformation? SAIResponse) + { + if (SAIResponse == null) + return null; + + SpareAreaInformation response = SAIResponse.Value; + + StringBuilder 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) + { + return Prettify(Decode(SAIResponse)); + } + #endregion Public methods + + #region Public structures + public struct SpareAreaInformation + { + /// + /// Bytes 0 to 1 + /// Always 14 + /// + public UInt16 DataLength; + /// + /// Byte 2 + /// Reserved + /// + public byte Reserved1; + /// + /// Byte 3 + /// Reserved + /// + public byte Reserved2; + /// + /// Bytes 4 to 7 + /// Reserved + /// + public UInt32 Reserved3; + /// + /// Bytes 8 to 11 + /// Free spare blocks + /// + public UInt32 FreeSpareBlocks; + /// + /// Bytes 12 to 15 + /// Allocated spare blocks + /// + public UInt32 AllocatedSpareBlocks; + } + #endregion Public structures + } +} + diff --git a/ChangeLog b/ChangeLog index 43dfa468e..5b067524c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2015-12-01 Natalia Portillo + + * Blu-ray/DI.cs: + * Blu-ray/BD.cs: + * Blu-ray/BCA.cs: + * Blu-ray/DDS.cs: + * Blu-ray/Spare.cs: + * Blu-ray/Cartridge.cs: + * DiscImageChef.Decoders.csproj: + Separated blu-ray structure decoders. + 2015-12-01 Natalia Portillo * DVD/PFI.cs: diff --git a/DiscImageChef.Decoders.csproj b/DiscImageChef.Decoders.csproj index 0061c8911..69b447bf6 100644 --- a/DiscImageChef.Decoders.csproj +++ b/DiscImageChef.Decoders.csproj @@ -35,7 +35,6 @@ - @@ -82,6 +81,11 @@ + + + + +