using System.IO; using System.Text; namespace BinaryObjectScanner.Wrappers { public class CIA : WrapperBase { #region Descriptive Properties /// public override string DescriptionString => "CTR Importable Archive (CIA)"; #endregion #region Pass-Through Properties #region Header /// #if NET48 public uint HeaderSize => _model.Header.HeaderSize; #else public uint? HeaderSize => _model.Header?.HeaderSize; #endif /// #if NET48 public ushort Type => _model.Header.Type; #else public ushort? Type => _model.Header?.Type; #endif /// #if NET48 public ushort Version => _model.Header.Version; #else public ushort? Version => _model.Header?.Version; #endif /// #if NET48 public uint CertificateChainSize => _model.Header.CertificateChainSize; #else public uint? CertificateChainSize => _model.Header?.CertificateChainSize; #endif /// #if NET48 public uint TicketSize => _model.Header.TicketSize; #else public uint? TicketSize => _model.Header?.TicketSize; #endif /// #if NET48 public uint TMDFileSize => _model.Header.TMDFileSize; #else public uint? TMDFileSize => _model.Header?.TMDFileSize; #endif /// #if NET48 public uint MetaSize => _model.Header.MetaSize; #else public uint? MetaSize => _model.Header?.MetaSize; #endif /// #if NET48 public ulong ContentSize => _model.Header.ContentSize; #else public ulong? ContentSize => _model.Header?.ContentSize; #endif /// #if NET48 public byte[] ContentIndex => _model.Header.ContentIndex; #else public byte[]? ContentIndex => _model.Header?.ContentIndex; #endif #endregion #region Certificate Chain /// #if NET48 public SabreTools.Models.N3DS.Certificate[] CertificateChain => _model.CertificateChain; #else public SabreTools.Models.N3DS.Certificate?[]? CertificateChain => _model.CertificateChain; #endif #endregion #region Ticket /// #if NET48 public SabreTools.Models.N3DS.SignatureType T_SignatureType => _model.Ticket.SignatureType; #else public SabreTools.Models.N3DS.SignatureType? T_SignatureType => _model.Ticket?.SignatureType; #endif /// #if NET48 public ushort T_SignatureSize => _model.Ticket.SignatureSize; #else public ushort? T_SignatureSize => _model.Ticket?.SignatureSize; #endif /// #if NET48 public byte T_PaddingSize => _model.Ticket.PaddingSize; #else public byte? T_PaddingSize => _model.Ticket?.PaddingSize; #endif /// #if NET48 public byte[] T_Signature => _model.Ticket.Signature; #else public byte[]? T_Signature => _model.Ticket?.Signature; #endif /// #if NET48 public byte[] T_Padding => _model.Ticket.Padding; #else public byte[]? T_Padding => _model.Ticket?.Padding; #endif /// #if NET48 public string T_Issuer => _model.Ticket.Issuer; #else public string? T_Issuer => _model.Ticket?.Issuer; #endif /// #if NET48 public byte[] T_ECCPublicKey => _model.Ticket.ECCPublicKey; #else public byte[]? T_ECCPublicKey => _model.Ticket?.ECCPublicKey; #endif /// #if NET48 public byte T_Version => _model.Ticket.Version; #else public byte? T_Version => _model.Ticket?.Version; #endif /// #if NET48 public byte T_CaCrlVersion => _model.Ticket.CaCrlVersion; #else public byte? T_CaCrlVersion => _model.Ticket?.CaCrlVersion; #endif /// #if NET48 public byte T_SignerCrlVersion => _model.Ticket.SignerCrlVersion; #else public byte? T_SignerCrlVersion => _model.Ticket?.SignerCrlVersion; #endif /// #if NET48 public byte[] T_TitleKey => _model.Ticket.TitleKey; #else public byte[]? T_TitleKey => _model.Ticket?.TitleKey; #endif /// #if NET48 public byte T_Reserved1 => _model.Ticket.Reserved1; #else public byte? T_Reserved1 => _model.Ticket?.Reserved1; #endif /// #if NET48 public ulong T_TicketID => _model.Ticket.TicketID; #else public ulong? T_TicketID => _model.Ticket?.TicketID; #endif /// #if NET48 public uint T_ConsoleID => _model.Ticket.ConsoleID; #else public uint? T_ConsoleID => _model.Ticket?.ConsoleID; #endif /// #if NET48 public ulong T_TitleID => _model.Ticket.TitleID; #else public ulong? T_TitleID => _model.Ticket?.TitleID; #endif /// #if NET48 public byte[] T_Reserved2 => _model.Ticket.Reserved2; #else public byte[]? T_Reserved2 => _model.Ticket?.Reserved2; #endif /// #if NET48 public ushort T_TicketTitleVersion => _model.Ticket.TicketTitleVersion; #else public ushort? T_TicketTitleVersion => _model.Ticket?.TicketTitleVersion; #endif /// #if NET48 public byte[] T_Reserved3 => _model.Ticket.Reserved3; #else public byte[]? T_Reserved3 => _model.Ticket?.Reserved3; #endif /// #if NET48 public byte T_LicenseType => _model.Ticket.LicenseType; #else public byte? T_LicenseType => _model.Ticket?.LicenseType; #endif /// #if NET48 public byte T_CommonKeyYIndex => _model.Ticket.CommonKeyYIndex; #else public byte? T_CommonKeyYIndex => _model.Ticket?.CommonKeyYIndex; #endif /// #if NET48 public byte[] T_Reserved4 => _model.Ticket.Reserved4; #else public byte[]? T_Reserved4 => _model.Ticket?.Reserved4; #endif /// #if NET48 public uint T_eShopAccountID => _model.Ticket.eShopAccountID; #else public uint? T_eShopAccountID => _model.Ticket?.eShopAccountID; #endif /// #if NET48 public byte T_Reserved5 => _model.Ticket.Reserved5; #else public byte? T_Reserved5 => _model.Ticket?.Reserved5; #endif /// #if NET48 public byte T_Audit => _model.Ticket.Audit; #else public byte? T_Audit => _model.Ticket?.Audit; #endif /// #if NET48 public byte[] T_Reserved6 => _model.Ticket.Reserved6; #else public byte[]? T_Reserved6 => _model.Ticket?.Reserved6; #endif /// #if NET48 public uint[] T_Limits => _model.Ticket.Limits; #else public uint[]? T_Limits => _model.Ticket?.Limits; #endif /// #if NET48 public uint T_ContentIndexSize => _model.Ticket.ContentIndexSize; #else public uint? T_ContentIndexSize => _model.Ticket?.ContentIndexSize; #endif /// #if NET48 public byte[] T_ContentIndex => _model.Ticket.ContentIndex; #else public byte[]? T_ContentIndex => _model.Ticket?.ContentIndex; #endif /// #if NET48 public SabreTools.Models.N3DS.Certificate[] T_CertificateChain => _model.Ticket.CertificateChain; #else public SabreTools.Models.N3DS.Certificate?[]? T_CertificateChain => _model.Ticket?.CertificateChain; #endif #endregion #region Title Metadata /// #if NET48 public SabreTools.Models.N3DS.SignatureType TMD_SignatureType => _model.TMDFileData.SignatureType; #else public SabreTools.Models.N3DS.SignatureType? TMD_SignatureType => _model.TMDFileData?.SignatureType; #endif /// #if NET48 public ushort TMD_SignatureSize => _model.TMDFileData.SignatureSize; #else public ushort? TMD_SignatureSize => _model.TMDFileData?.SignatureSize; #endif /// #if NET48 public byte TMD_PaddingSize => _model.TMDFileData.PaddingSize; #else public byte? TMD_PaddingSize => _model.TMDFileData?.PaddingSize; #endif /// #if NET48 public byte[] TMD_Signature => _model.TMDFileData.Signature; #else public byte[]? TMD_Signature => _model.TMDFileData?.Signature; #endif /// #if NET48 public byte[] TMD_Padding1 => _model.TMDFileData.Padding1; #else public byte[]? TMD_Padding1 => _model.TMDFileData?.Padding1; #endif /// #if NET48 public string TMD_Issuer => _model.TMDFileData.Issuer; #else public string? TMD_Issuer => _model.TMDFileData?.Issuer; #endif /// #if NET48 public byte TMD_Version => _model.TMDFileData.Version; #else public byte? TMD_Version => _model.TMDFileData?.Version; #endif /// #if NET48 public byte TMD_CaCrlVersion => _model.TMDFileData.CaCrlVersion; #else public byte? TMD_CaCrlVersion => _model.TMDFileData?.CaCrlVersion; #endif /// #if NET48 public byte TMD_SignerCrlVersion => _model.TMDFileData.SignerCrlVersion; #else public byte? TMD_SignerCrlVersion => _model.TMDFileData?.SignerCrlVersion; #endif /// #if NET48 public byte TMD_Reserved1 => _model.TMDFileData.Reserved1; #else public byte? TMD_Reserved1 => _model.TMDFileData?.Reserved1; #endif /// #if NET48 public ulong TMD_SystemVersion => _model.TMDFileData.SystemVersion; #else public ulong? TMD_SystemVersion => _model.TMDFileData?.SystemVersion; #endif /// #if NET48 public ulong TMD_TitleID => _model.TMDFileData.TitleID; #else public ulong? TMD_TitleID => _model.TMDFileData?.TitleID; #endif /// #if NET48 public uint TMD_TitleType => _model.TMDFileData.TitleType; #else public uint? TMD_TitleType => _model.TMDFileData?.TitleType; #endif /// #if NET48 public ushort TMD_GroupID => _model.TMDFileData.GroupID; #else public ushort? TMD_GroupID => _model.TMDFileData?.GroupID; #endif /// #if NET48 public uint TMD_SaveDataSize => _model.TMDFileData.SaveDataSize; #else public uint? TMD_SaveDataSize => _model.TMDFileData?.SaveDataSize; #endif /// #if NET48 public uint TMD_SRLPrivateSaveDataSize => _model.TMDFileData.SRLPrivateSaveDataSize; #else public uint? TMD_SRLPrivateSaveDataSize => _model.TMDFileData?.SRLPrivateSaveDataSize; #endif /// #if NET48 public byte[] TMD_Reserved2 => _model.TMDFileData.Reserved2; #else public byte[]? TMD_Reserved2 => _model.TMDFileData?.Reserved2; #endif /// #if NET48 public byte TMD_SRLFlag => _model.TMDFileData.SRLFlag; #else public byte? TMD_SRLFlag => _model.TMDFileData?.SRLFlag; #endif /// #if NET48 public byte[] TMD_Reserved3 => _model.TMDFileData.Reserved3; #else public byte[]? TMD_Reserved3 => _model.TMDFileData?.Reserved3; #endif /// #if NET48 public uint TMD_AccessRights => _model.TMDFileData.AccessRights; #else public uint? TMD_AccessRights => _model.TMDFileData?.AccessRights; #endif /// #if NET48 public ushort TMD_TitleVersion => _model.TMDFileData.TitleVersion; #else public ushort? TMD_TitleVersion => _model.TMDFileData?.TitleVersion; #endif /// #if NET48 public ushort TMD_ContentCount => _model.TMDFileData.ContentCount; #else public ushort? TMD_ContentCount => _model.TMDFileData?.ContentCount; #endif /// #if NET48 public ushort TMD_BootContent => _model.TMDFileData.BootContent; #else public ushort? TMD_BootContent => _model.TMDFileData?.BootContent; #endif /// #if NET48 public byte[] TMD_Padding2 => _model.TMDFileData.Padding2; #else public byte[]? TMD_Padding2 => _model.TMDFileData?.Padding2; #endif /// #if NET48 public byte[] TMD_SHA256HashContentInfoRecords => _model.TMDFileData.SHA256HashContentInfoRecords; #else public byte[]? TMD_SHA256HashContentInfoRecords => _model.TMDFileData?.SHA256HashContentInfoRecords; #endif /// #if NET48 public SabreTools.Models.N3DS.ContentInfoRecord[] TMD_ContentInfoRecords => _model.TMDFileData.ContentInfoRecords; #else public SabreTools.Models.N3DS.ContentInfoRecord?[]? TMD_ContentInfoRecords => _model.TMDFileData?.ContentInfoRecords; #endif /// #if NET48 public SabreTools.Models.N3DS.ContentChunkRecord[] TMD_ContentChunkRecords => _model.TMDFileData.ContentChunkRecords; #else public SabreTools.Models.N3DS.ContentChunkRecord?[]? TMD_ContentChunkRecords => _model.TMDFileData?.ContentChunkRecords; #endif /// #if NET48 public SabreTools.Models.N3DS.Certificate[] TMD_CertificateChain => _model.TMDFileData.CertificateChain; #else public SabreTools.Models.N3DS.Certificate?[]? TMD_CertificateChain => _model.TMDFileData?.CertificateChain; #endif #endregion #region Partitions /// #if NET48 public SabreTools.Models.N3DS.NCCHHeader[] Partitions => _model.Partitions; #else public SabreTools.Models.N3DS.NCCHHeader?[]? Partitions => _model.Partitions; #endif #endregion #region Meta Data /// #if NET48 public byte[] MD_TitleIDDependencyList => _model.MetaData?.TitleIDDependencyList; #else public byte[]? MD_TitleIDDependencyList => _model.MetaData?.TitleIDDependencyList; #endif /// #if NET48 public byte[] MD_Reserved1 => _model.MetaData?.Reserved1; #else public byte[]? MD_Reserved1 => _model.MetaData?.Reserved1; #endif /// public uint? MD_CoreVersion => _model.MetaData?.CoreVersion; /// #if NET48 public byte[] MD_Reserved2 => _model.MetaData?.Reserved2; #else public byte[]? MD_Reserved2 => _model.MetaData?.Reserved2; #endif /// #if NET48 public byte[] MD_IconData => _model.MetaData?.IconData; #else public byte[]? MD_IconData => _model.MetaData?.IconData; #endif #endregion #endregion #region Constructors /// #if NET48 public CIA(SabreTools.Models.N3DS.CIA model, byte[] data, int offset) #else public CIA(SabreTools.Models.N3DS.CIA? model, byte[]? data, int offset) #endif : base(model, data, offset) { // All logic is handled by the base class } /// #if NET48 public CIA(SabreTools.Models.N3DS.CIA model, Stream data) #else public CIA(SabreTools.Models.N3DS.CIA? model, Stream? data) #endif : base(model, data) { // All logic is handled by the base class } /// /// Create a CIA archive from a byte array and offset /// /// Byte array representing the archive /// Offset within the array to parse /// A CIA archive wrapper on success, null on failure #if NET48 public static CIA Create(byte[] data, int offset) #else public static CIA? Create(byte[]? data, int offset) #endif { // If the data is invalid if (data == null) return null; // If the offset is out of bounds if (offset < 0 || offset >= data.Length) return null; // Create a memory stream and use that MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset); return Create(dataStream); } /// /// Create a CIA archive from a Stream /// /// Stream representing the archive /// A CIA archive wrapper on success, null on failure #if NET48 public static CIA Create(Stream data) #else public static CIA? Create(Stream? data) #endif { // If the data is invalid if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead) return null; var archive = new SabreTools.Serialization.Streams.CIA().Deserialize(data); if (archive == null) return null; try { return new CIA(archive, data); } catch { return null; } } #endregion #region Printing /// public override StringBuilder PrettyPrint() { StringBuilder builder = new StringBuilder(); Printing.CIA.Print(builder, _model); return builder; } #if NET6_0_OR_GREATER /// public override string ExportJSON() => System.Text.Json.JsonSerializer.Serialize(_model, _jsonSerializerOptions); #endif #endregion } }