/***************************************************************************
The Disc Image Chef
----------------------------------------------------------------------------
Filename : Nero.cs
Version : 2.0
Author(s) : Natalia Portillo
Component : Disc image plugins
Revision : $Revision$
Last change by : $Author$
Date : $Date$
--[ Description ] ----------------------------------------------------------
Manages Nero Burning ROM images.
--[ 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.IO;
using System.Collections.Generic;
using DiscImageChef;
namespace DiscImageChef.ImagePlugins
{
class Nero : ImagePlugin
{
#region Internal structures
struct NeroV1Footer
{
///
/// "NERO"
///
public UInt32 ChunkID;
///
/// Offset of first chunk in file
///
public UInt32 FirstChunkOffset;
}
struct NeroV2Footer
{
///
/// "NER5"
///
public UInt32 ChunkID;
///
/// Offset of first chunk in file
///
public UInt64 FirstChunkOffset;
}
struct NeroV2CueEntry
{
///
/// Track mode. 0x01 for audio, 0x21 for copy-protected audio, 0x41 for data
///
public byte Mode;
///
/// Track number in BCD
///
public byte TrackNumber;
///
/// Index number in BCD
///
public byte IndexNumber;
///
/// Always zero
///
public byte Dummy;
///
/// LBA sector start for this entry
///
public Int32 LBAStart;
}
struct NeroV2Cuesheet
{
///
/// "CUEX"
///
public UInt32 ChunkID;
///
/// Chunk size
///
public UInt32 ChunkSize;
///
/// Cuesheet entries
///
public List Entries;
}
struct NeroV1CueEntry
{
///
/// Track mode. 0x01 for audio, 0x21 for copy-protected audio, 0x41 for data
///
public byte Mode;
///
/// Track number in BCD
///
public byte TrackNumber;
///
/// Index number in BCD
///
public byte IndexNumber;
///
/// Always zero
///
public UInt16 Dummy;
///
/// MSF start sector's minute for this entry
///
public byte Minute;
///
/// MSF start sector's second for this entry
///
public byte Second;
///
/// MSF start sector's frame for this entry
///
public byte Frame;
}
struct NeroV1Cuesheet
{
///
/// "CUES"
///
public UInt32 ChunkID;
///
/// Chunk size
///
public UInt32 ChunkSize;
///
/// Cuesheet entries
///
public List Entries;
}
struct NeroV1DAOEntry
{
///
/// ISRC (12 bytes)
///
public byte[] ISRC;
///
/// Size of sector inside image (in bytes)
///
public UInt16 SectorSize;
///
/// Sector mode in image
///
public UInt16 Mode;
///
/// Unknown
///
public UInt16 Unknown;
///
/// Index 0 start
///
public UInt32 Index0;
///
/// Index 1 start
///
public UInt32 Index1;
///
/// End of track + 1
///
public UInt32 EndOfTrack;
}
struct NeroV1DAO
{
///
/// "DAOI"
///
public UInt32 ChunkID;
///
/// Chunk size (big endian)
///
public UInt32 ChunkSizeBe;
///
/// Chunk size (little endian)
///
public UInt32 ChunkSizeLe;
///
/// UPC (14 bytes, null-padded)
///
public byte[] UPC;
///
/// TOC type
///
public UInt16 TocType;
///
/// First track
///
public byte FirstTrack;
///
/// Last track
///
public byte LastTrack;
///
/// Tracks
///
public List Tracks;
}
struct NeroV2DAOEntry
{
///
/// ISRC (12 bytes)
///
public byte[] ISRC;
///
/// Size of sector inside image (in bytes)
///
public UInt16 SectorSize;
///
/// Sector mode in image
///
public UInt16 Mode;
///
/// Seems to be always 0.
///
public UInt16 Unknown;
///
/// Index 0 start
///
public UInt64 Index0;
///
/// Index 1 start
///
public UInt64 Index1;
///
/// End of track + 1
///
public UInt64 EndOfTrack;
}
struct NeroV2DAO
{
///
/// "DAOX"
///
public UInt32 ChunkID;
///
/// Chunk size (big endian)
///
public UInt32 ChunkSizeBe;
///
/// Chunk size (little endian)
///
public UInt32 ChunkSizeLe;
///
/// UPC (14 bytes, null-padded)
///
public byte[] UPC;
///
/// TOC type
///
public UInt16 TocType;
///
/// First track
///
public byte FirstTrack;
///
/// Last track
///
public byte LastTrack;
///
/// Tracks
///
public List Tracks;
}
struct NeroCDTextPack
{
///
/// Pack type
///
public byte PackType;
///
/// Track number
///
public byte TrackNumber;
///
/// Pack number in block
///
public byte PackNumber;
///
/// Block number
///
public byte BlockNumber;
///
/// 12 bytes of data
///
public byte[] Text;
///
/// CRC
///
public UInt16 CRC;
}
struct NeroCDText
{
///
/// "CDTX"
///
public UInt32 ChunkID;
///
/// Chunk size
///
public UInt32 ChunkSize;
///
/// CD-TEXT packs
///
public List Packs;
}
struct NeroV1TAOEntry
{
///
/// Offset of track on image
///
public UInt32 Offset;
///
/// Length of track in bytes
///
public UInt32 Length;
///
/// Track mode
///
public UInt32 Mode;
///
/// LBA track start (plus 150 lead in sectors)
///
public UInt32 StartLBA;
///
/// Unknown
///
public UInt32 Unknown;
}
struct NeroV1TAO
{
///
/// "ETNF"
///
public UInt32 ChunkID;
///
/// Chunk size
///
public UInt32 ChunkSize;
///
/// CD-TEXT packs
///
public List Tracks;
}
struct NeroV2TAOEntry
{
///
/// Offset of track on image
///
public UInt64 Offset;
///
/// Length of track in bytes
///
public UInt64 Length;
///
/// Track mode
///
public UInt32 Mode;
///
/// LBA track start (plus 150 lead in sectors)
///
public UInt32 StartLBA;
///
/// Unknown
///
public UInt32 Unknown;
///
/// Track length in sectors
///
public UInt32 Sectors;
}
struct NeroV2TAO
{
///
/// "ETN2"
///
public UInt32 ChunkID;
///
/// Chunk size
///
public UInt32 ChunkSize;
///
/// CD-TEXT packs
///
public List Tracks;
}
struct NeroSession
{
///
/// "SINF"
///
public UInt32 ChunkID;
///
/// Chunk size
///
public UInt32 ChunkSize;
///
/// Tracks in session
///
public UInt32 Tracks;
}
struct NeroMediaType
{
///
/// "MTYP"
///
public UInt32 ChunkID;
///
/// Chunk size
///
public UInt32 ChunkSize;
///
/// Media type
///
public UInt32 Type;
}
struct NeroDiscInformation
{
///
/// "DINF"
///
public UInt32 ChunkID;
///
/// Chunk size
///
public UInt32 ChunkSize;
///
/// Unknown
///
public UInt32 Unknown;
}
struct NeroTOCChunk
{
///
/// "TOCT"
///
public UInt32 ChunkID;
///
/// Chunk size
///
public UInt32 ChunkSize;
///
/// Unknown
///
public UInt16 Unknown;
}
struct NeroRELOChunk
{
///
/// "RELO"
///
public UInt32 ChunkID;
///
/// Chunk size
///
public UInt32 ChunkSize;
///
/// Unknown
///
public UInt32 Unknown;
}
struct NeroEndOfChunkChain
{
///
/// "END!"
///
public UInt32 ChunkID;
///
/// Chunk size
///
public UInt32 ChunkSize;
}
// Internal use only
struct NeroTrack
{
public byte[] ISRC;
public UInt16 SectorSize;
public UInt64 Offset;
public UInt64 Length;
public UInt64 EndOfTrack;
public UInt32 Mode;
public UInt64 StartLBA;
public UInt64 Sectors;
public UInt64 Index0;
public UInt64 Index1;
public UInt32 Sequence;
}
#endregion
#region Internal consts
// "NERO"
public const UInt32 NeroV1FooterID = 0x4E45524F;
// "NER5"
public const UInt32 NeroV2FooterID = 0x4E455235;
// "CUES"
public const UInt32 NeroV1CUEID = 0x43554553;
// "CUEX"
public const UInt32 NeroV2CUEID = 0x43554558;
// "ETNF"
public const UInt32 NeroV1TAOID = 0x45544E46;
// "ETN2"
public const UInt32 NeroV2TAOID = 0x45544E32;
// "DAOI"
public const UInt32 NeroV1DAOID = 0x44414F49;
// "DAOX"
public const UInt32 NeroV2DAOID = 0x44414F58;
// "CDTX"
public const UInt32 NeroCDTextID = 0x43445458;
// "SINF"
public const UInt32 NeroSessionID = 0x53494E46;
// "MTYP"
public const UInt32 NeroDiskTypeID = 0x4D545950;
// "DINF"
public const UInt32 NeroDiscInfoID = 0x44494E46;
// "TOCT"
public const UInt32 NeroTOCID = 0x544F4354;
// "RELO"
public const UInt32 NeroReloID = 0x52454C4F;
// "END!"
public const UInt32 NeroEndID = 0x454E4421;
public enum DAOMode : ushort
{
Data = 0x0000,
DataM2F1 = 0x0002,
DataM2F2 = 0x0003,
DataRaw = 0x0005,
DataM2Raw = 0x0006,
Audio = 0x0007,
DataRawSub = 0x000F,
AudioSub = 0x0010,
DataM2RawSub = 0x0011
}
public enum NeroMediaTypes : uint
{
///
/// No media
///
NERO_MTYP_NONE = 0x00000,
///
/// CD-R/RW
///
NERO_MTYP_CD = 0x00001,
///
/// DDCD-R/RW
///
NERO_MTYP_DDCD = 0x00002,
///
/// DVD-R/RW
///
NERO_MTYP_DVD_M = 0x00004,
///
/// DVD+RW
///
NERO_MTYP_DVD_P = 0x00008,
///
/// DVD-RAM
///
NERO_MTYP_DVD_RAM = 0x00010,
///
/// Multi-level disc
///
NERO_MTYP_ML = 0x00020,
///
/// Mount Rainier
///
NERO_MTYP_MRW = 0x00040,
///
/// Exclude CD-R
///
NERO_MTYP_NO_CDR = 0x00080,
///
/// Exclude CD-RW
///
NERO_MTYP_NO_CDRW = 0x00100,
///
/// CD-RW
///
NERO_MTYP_CDRW = NERO_MTYP_CD | NERO_MTYP_NO_CDR,
///
/// CD-R
///
NERO_MTYP_CDR = NERO_MTYP_CD | NERO_MTYP_NO_CDRW,
///
/// DVD-ROM
///
NERO_MTYP_DVD_ROM = 0x00200,
///
/// CD-ROM
///
NERO_MTYP_CDROM = 0x00400,
///
/// Exclude DVD-RW
///
NERO_MTYP_NO_DVD_M_RW = 0x00800,
///
/// Exclude DVD-R
///
NERO_MTYP_NO_DVD_M_R = 0x01000,
///
/// Exclude DVD+RW
///
NERO_MTYP_NO_DVD_P_RW = 0x02000,
///
/// Exclude DVD+R
///
NERO_MTYP_NO_DVD_P_R = 0x04000,
///
/// DVD-R
///
NERO_MTYP_DVD_M_R = NERO_MTYP_DVD_M | NERO_MTYP_NO_DVD_M_RW,
///
/// DVD-RW
///
NERO_MTYP_DVD_M_RW = NERO_MTYP_DVD_M | NERO_MTYP_NO_DVD_M_R,
///
/// DVD+R
///
NERO_MTYP_DVD_P_R = NERO_MTYP_DVD_P | NERO_MTYP_NO_DVD_P_RW,
///
/// DVD+RW
///
NERO_MTYP_DVD_P_RW = NERO_MTYP_DVD_P | NERO_MTYP_NO_DVD_P_R,
///
/// Packet-writing (fixed)
///
NERO_MTYP_FPACKET = 0x08000,
///
/// Packet-writing (variable)
///
NERO_MTYP_VPACKET = 0x10000,
///
/// Packet-writing (any)
///
NERO_MTYP_PACKETW = NERO_MTYP_MRW | NERO_MTYP_FPACKET | NERO_MTYP_VPACKET,
///
/// HD-Burn
///
NERO_MTYP_HDB = 0x20000,
///
/// DVD+R DL
///
NERO_MTYP_DVD_P_R9 = 0x40000,
///
/// DVD-R DL
///
NERO_MTYP_DVD_M_R9 = 0x80000,
///
/// Any DVD double-layer
///
NERO_MTYP_DVD_ANY_R9 = NERO_MTYP_DVD_P_R9 | NERO_MTYP_DVD_M_R9,
///
/// Any DVD
///
NERO_MTYP_DVD_ANY = NERO_MTYP_DVD_M | NERO_MTYP_DVD_P | NERO_MTYP_DVD_RAM | NERO_MTYP_DVD_ANY_R9,
///
/// BD-ROM
///
NERO_MTYP_BD_ROM = 0x100000,
///
/// BD-R
///
NERO_MTYP_BD_R = 0x200000,
///
/// BD-RE
///
NERO_MTYP_BD_RE = 0x400000,
///
/// BD-R/RE
///
NERO_MTYP_BD = NERO_MTYP_BD_R | NERO_MTYP_BD_RE,
///
/// Any BD
///
NERO_MTYP_BD_ANY = NERO_MTYP_BD | NERO_MTYP_BD_ROM,
///
/// HD DVD-ROM
///
NERO_MTYP_HD_DVD_ROM = 0x0800000,
///
/// HD DVD-R
///
NERO_MTYP_HD_DVD_R = 0x1000000,
///
/// HD DVD-RW
///
NERO_MTYP_HD_DVD_RW = 0x2000000,
///
/// HD DVD-R/RW
///
NERO_MTYP_HD_DVD = NERO_MTYP_HD_DVD_R | NERO_MTYP_HD_DVD_RW,
///
/// Any HD DVD
///
NERO_MTYP_HD_DVD_ANY = NERO_MTYP_HD_DVD | NERO_MTYP_HD_DVD_ROM,
}
#endregion
#region Internal variables
string _imagePath;
FileStream imageStream;
FileInfo imageInfo;
bool imageNewFormat;
Dictionary neroSessions;
NeroV1Cuesheet neroCuesheetV1;
NeroV2Cuesheet neroCuesheetV2;
NeroV1DAO neroDAOV1;
NeroV2DAO neroDAOV2;
NeroCDText neroCDTXT;
NeroV1TAO neroTAOV1;
NeroV2TAO neroTAOV2;
NeroMediaType neroMediaTyp;
NeroDiscInformation neroDiscInfo;
NeroTOCChunk neroTOC;
NeroRELOChunk neroRELO;
List