2023-01-07 12:33:15 -08:00
using System ;
using System.IO ;
2023-01-13 14:04:21 -08:00
using System.Text ;
2023-01-07 12:33:15 -08:00
2023-03-07 16:59:14 -05:00
namespace BinaryObjectScanner.Wrappers
2023-01-07 12:33:15 -08:00
{
2023-09-11 23:25:09 -04:00
public class N3DS : WrapperBase < SabreTools . Models . N3DS . Cart >
2023-01-07 12:33:15 -08:00
{
2023-01-18 11:18:53 -08:00
#region Descriptive Properties
/// <inheritdoc/>
2023-09-11 23:25:09 -04:00
public override string DescriptionString = > "Nintendo 3DS Cart Image" ;
2023-01-18 11:18:53 -08:00
#endregion
2023-01-07 12:33:15 -08:00
#region Pass - Through Properties
#region Header
#region Common to all NCSD files
/// <inheritdoc cref="Models.N3DS.NCSDHeader.RSA2048Signature"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte [ ] RSA2048Signature = > _model . Header . RSA2048Signature ;
2023-09-12 17:12:23 -04:00
#else
2023-09-13 00:08:11 -04:00
public byte [ ] ? RSA2048Signature = > _model . Header ? . RSA2048Signature ;
2023-09-12 17:12:23 -04:00
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.NCSDHeader.MagicNumber"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public string MagicNumber = > _model . Header . MagicNumber ;
2023-09-12 17:12:23 -04:00
#else
2023-09-13 00:08:11 -04:00
public string? MagicNumber = > _model . Header ? . MagicNumber ;
2023-09-12 17:12:23 -04:00
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.NCSDHeader.ImageSizeInMediaUnits"/>
2023-09-13 00:08:11 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public uint ImageSizeInMediaUnits = > _model . Header . ImageSizeInMediaUnits ;
2023-09-13 00:08:11 -04:00
#else
public uint? ImageSizeInMediaUnits = > _model . Header ? . ImageSizeInMediaUnits ;
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.NCSDHeader.MediaId"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte [ ] MediaId = > _model . Header . MediaId ;
2023-09-12 17:12:23 -04:00
#else
2023-09-13 00:08:11 -04:00
public byte [ ] ? MediaId = > _model . Header ? . MediaId ;
2023-09-12 17:12:23 -04:00
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.NCSDHeader.PartitionsFSType"/>
2023-09-13 00:08:11 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public SabreTools . Models . N3DS . FilesystemType PartitionsFSType = > _model . Header . PartitionsFSType ;
2023-09-13 00:08:11 -04:00
#else
public SabreTools . Models . N3DS . FilesystemType ? PartitionsFSType = > _model . Header ? . PartitionsFSType ;
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.NCSDHeader.PartitionsCryptType"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte [ ] PartitionsCryptType = > _model . Header . PartitionsCryptType ;
2023-09-12 17:12:23 -04:00
#else
2023-09-13 00:08:11 -04:00
public byte [ ] ? PartitionsCryptType = > _model . Header ? . PartitionsCryptType ;
2023-09-12 17:12:23 -04:00
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.NCSDHeader.PartitionsTable"/>
2023-09-12 12:35:19 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public SabreTools . Models . N3DS . PartitionTableEntry [ ] PartitionsTable = > _model . Header . PartitionsTable ;
2023-09-12 12:35:19 -04:00
#else
2023-09-13 00:08:11 -04:00
public SabreTools . Models . N3DS . PartitionTableEntry ? [ ] ? PartitionsTable = > _model . Header ? . PartitionsTable ;
2023-09-12 12:35:19 -04:00
#endif
2023-01-07 12:33:15 -08:00
#endregion
#region CTR Cart Image ( CCI ) Specific
/// <inheritdoc cref="Models.N3DS.NCSDHeader.ExheaderHash"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte [ ] ExheaderHash = > _model . Header . ExheaderHash ;
2023-09-12 17:12:23 -04:00
#else
2023-09-13 00:08:11 -04:00
public byte [ ] ? ExheaderHash = > _model . Header ? . ExheaderHash ;
2023-09-12 17:12:23 -04:00
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.NCSDHeader.AdditionalHeaderSize"/>
2023-09-13 00:08:11 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public uint AdditionalHeaderSize = > _model . Header . AdditionalHeaderSize ;
2023-09-13 00:08:11 -04:00
#else
public uint? AdditionalHeaderSize = > _model . Header ? . AdditionalHeaderSize ;
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.NCSDHeader.SectorZeroOffset"/>
2023-09-13 00:08:11 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public uint SectorZeroOffset = > _model . Header . SectorZeroOffset ;
2023-09-13 00:08:11 -04:00
#else
public uint? SectorZeroOffset = > _model . Header ? . SectorZeroOffset ;
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.NCSDHeader.PartitionFlags"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte [ ] PartitionFlags = > _model . Header . PartitionFlags ;
2023-09-12 17:12:23 -04:00
#else
2023-09-13 00:08:11 -04:00
public byte [ ] ? PartitionFlags = > _model . Header ? . PartitionFlags ;
2023-09-12 17:12:23 -04:00
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.NCSDHeader.PartitionIdTable"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public ulong [ ] PartitionIdTable = > _model . Header . PartitionIdTable ;
2023-09-12 17:12:23 -04:00
#else
2023-09-13 00:08:11 -04:00
public ulong [ ] ? PartitionIdTable = > _model . Header ? . PartitionIdTable ;
2023-09-12 17:12:23 -04:00
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.NCSDHeader.Reserved1"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte [ ] Reserved1 = > _model . Header . Reserved1 ;
2023-09-12 17:12:23 -04:00
#else
2023-09-13 00:08:11 -04:00
public byte [ ] ? Reserved1 = > _model . Header ? . Reserved1 ;
2023-09-12 17:12:23 -04:00
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.NCSDHeader.Reserved2"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte [ ] Reserved2 = > _model . Header . Reserved2 ;
2023-09-12 17:12:23 -04:00
#else
2023-09-13 00:08:11 -04:00
public byte [ ] ? Reserved2 = > _model . Header ? . Reserved2 ;
2023-09-12 17:12:23 -04:00
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.NCSDHeader.FirmUpdateByte1"/>
2023-09-13 00:08:11 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte FirmUpdateByte1 = > _model . Header . FirmUpdateByte1 ;
2023-09-13 00:08:11 -04:00
#else
public byte? FirmUpdateByte1 = > _model . Header ? . FirmUpdateByte1 ;
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.NCSDHeader.FirmUpdateByte2"/>
2023-09-13 00:08:11 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte FirmUpdateByte2 = > _model . Header . FirmUpdateByte2 ;
2023-09-13 00:08:11 -04:00
#else
public byte? FirmUpdateByte2 = > _model . Header ? . FirmUpdateByte2 ;
#endif
2023-01-07 12:33:15 -08:00
#endregion
#region Raw NAND Format Specific
/// <inheritdoc cref="Models.N3DS.NCSDHeader.Unknown"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte [ ] Unknown = > _model . Header . Unknown ;
2023-09-12 17:12:23 -04:00
#else
2023-09-13 00:08:11 -04:00
public byte [ ] ? Unknown = > _model . Header ? . Unknown ;
2023-09-12 17:12:23 -04:00
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.NCSDHeader.EncryptedMBR"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte [ ] EncryptedMBR = > _model . Header . EncryptedMBR ;
2023-09-12 17:12:23 -04:00
#else
2023-09-13 00:08:11 -04:00
public byte [ ] ? EncryptedMBR = > _model . Header ? . EncryptedMBR ;
2023-09-12 17:12:23 -04:00
#endif
2023-01-07 12:33:15 -08:00
#endregion
#endregion
#region Card Info Header
/// <inheritdoc cref="Models.N3DS.CardInfoHeader.WritableAddressMediaUnits"/>
2023-09-13 00:08:11 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public uint CIH_WritableAddressMediaUnits = > _model . CardInfoHeader . WritableAddressMediaUnits ;
2023-09-13 00:08:11 -04:00
#else
public uint? CIH_WritableAddressMediaUnits = > _model . CardInfoHeader ? . WritableAddressMediaUnits ;
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.CardInfoHeader.CardInfoBitmask"/>
2023-09-13 00:08:11 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public uint CIH_CardInfoBitmask = > _model . CardInfoHeader . CardInfoBitmask ;
2023-09-13 00:08:11 -04:00
#else
public uint? CIH_CardInfoBitmask = > _model . CardInfoHeader ? . CardInfoBitmask ;
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.CardInfoHeader.Reserved1"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte [ ] CIH_Reserved1 = > _model . CardInfoHeader . Reserved1 ;
2023-09-12 17:12:23 -04:00
#else
2023-09-13 00:08:11 -04:00
public byte [ ] ? CIH_Reserved1 = > _model . CardInfoHeader ? . Reserved1 ;
2023-09-12 17:12:23 -04:00
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.CardInfoHeader.FilledSize"/>
2023-09-13 00:08:11 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public uint CIH_FilledSize = > _model . CardInfoHeader . FilledSize ;
2023-09-13 00:08:11 -04:00
#else
public uint? CIH_FilledSize = > _model . CardInfoHeader ? . FilledSize ;
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.CardInfoHeader.Reserved2"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte [ ] CIH_Reserved2 = > _model . CardInfoHeader . Reserved2 ;
2023-09-12 17:12:23 -04:00
#else
2023-09-13 00:08:11 -04:00
public byte [ ] ? CIH_Reserved2 = > _model . CardInfoHeader ? . Reserved2 ;
2023-09-12 17:12:23 -04:00
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.CardInfoHeader.TitleVersion"/>
2023-09-13 00:08:11 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public ushort CIH_TitleVersion = > _model . CardInfoHeader . TitleVersion ;
2023-09-13 00:08:11 -04:00
#else
public ushort? CIH_TitleVersion = > _model . CardInfoHeader ? . TitleVersion ;
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.CardInfoHeader.CardRevision"/>
2023-09-13 00:08:11 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public ushort CIH_CardRevision = > _model . CardInfoHeader . CardRevision ;
2023-09-13 00:08:11 -04:00
#else
public ushort? CIH_CardRevision = > _model . CardInfoHeader ? . CardRevision ;
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.CardInfoHeader.Reserved3"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte [ ] CIH_Reserved3 = > _model . CardInfoHeader . Reserved3 ;
2023-09-12 17:12:23 -04:00
#else
2023-09-13 00:08:11 -04:00
public byte [ ] ? CIH_Reserved3 = > _model . CardInfoHeader ? . Reserved3 ;
2023-09-12 17:12:23 -04:00
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.CardInfoHeader.CVerTitleID"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte [ ] CIH_CVerTitleID = > _model . CardInfoHeader . CVerTitleID ;
2023-09-12 17:12:23 -04:00
#else
2023-09-13 00:08:11 -04:00
public byte [ ] ? CIH_CVerTitleID = > _model . CardInfoHeader ? . CVerTitleID ;
2023-09-12 17:12:23 -04:00
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.CardInfoHeader.CVerVersionNumber"/>
2023-09-13 00:08:11 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public ushort CIH_CVerVersionNumber = > _model . CardInfoHeader . CVerVersionNumber ;
2023-09-13 00:08:11 -04:00
#else
public ushort? CIH_CVerVersionNumber = > _model . CardInfoHeader ? . CVerVersionNumber ;
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.CardInfoHeader.Reserved4"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte [ ] CIH_Reserved4 = > _model . CardInfoHeader . Reserved4 ;
2023-09-12 17:12:23 -04:00
#else
2023-09-13 00:08:11 -04:00
public byte [ ] ? CIH_Reserved4 = > _model . CardInfoHeader ? . Reserved4 ;
2023-09-12 17:12:23 -04:00
#endif
2023-01-07 12:33:15 -08:00
#endregion
#region Development Card Info Header
#region Initial Data
/// <inheritdoc cref="Models.N3DS.InitialData.CardSeedKeyY"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte [ ] DCIH_ID_CardSeedKeyY = > _model . DevelopmentCardInfoHeader ? . InitialData ? . CardSeedKeyY ;
2023-09-12 17:12:23 -04:00
#else
public byte [ ] ? DCIH_ID_CardSeedKeyY = > _model . DevelopmentCardInfoHeader ? . InitialData ? . CardSeedKeyY ;
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.InitialData.EncryptedCardSeed"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte [ ] DCIH_ID_EncryptedCardSeed = > _model . DevelopmentCardInfoHeader ? . InitialData ? . EncryptedCardSeed ;
2023-09-12 17:12:23 -04:00
#else
public byte [ ] ? DCIH_ID_EncryptedCardSeed = > _model . DevelopmentCardInfoHeader ? . InitialData ? . EncryptedCardSeed ;
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.InitialData.CardSeedAESMAC"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte [ ] DCIH_ID_CardSeedAESMAC = > _model . DevelopmentCardInfoHeader ? . InitialData ? . CardSeedAESMAC ;
2023-09-12 17:12:23 -04:00
#else
public byte [ ] ? DCIH_ID_CardSeedAESMAC = > _model . DevelopmentCardInfoHeader ? . InitialData ? . CardSeedAESMAC ;
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.InitialData.CardSeedNonce"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte [ ] DCIH_ID_CardSeedNonce = > _model . DevelopmentCardInfoHeader ? . InitialData ? . CardSeedNonce ;
2023-09-12 17:12:23 -04:00
#else
public byte [ ] ? DCIH_ID_CardSeedNonce = > _model . DevelopmentCardInfoHeader ? . InitialData ? . CardSeedNonce ;
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.InitialData.Reserved3"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte [ ] DCIH_ID_Reserved = > _model . DevelopmentCardInfoHeader ? . InitialData ? . Reserved ;
2023-09-12 17:12:23 -04:00
#else
public byte [ ] ? DCIH_ID_Reserved = > _model . DevelopmentCardInfoHeader ? . InitialData ? . Reserved ;
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.InitialData.BackupHeader"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public SabreTools . Models . N3DS . NCCHHeader DCIH_ID_BackupHeader = > _model . DevelopmentCardInfoHeader ? . InitialData ? . BackupHeader ;
2023-09-12 17:12:23 -04:00
#else
public SabreTools . Models . N3DS . NCCHHeader ? DCIH_ID_BackupHeader = > _model . DevelopmentCardInfoHeader ? . InitialData ? . BackupHeader ;
#endif
2023-01-07 12:33:15 -08:00
#endregion
/// <inheritdoc cref="Models.N3DS.DevelopmentCardInfoHeader.CardDeviceReserved1"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte [ ] DCIH_CardDeviceReserved1 = > _model . DevelopmentCardInfoHeader ? . CardDeviceReserved1 ;
2023-09-12 17:12:23 -04:00
#else
public byte [ ] ? DCIH_CardDeviceReserved1 = > _model . DevelopmentCardInfoHeader ? . CardDeviceReserved1 ;
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.DevelopmentCardInfoHeader.TitleKey"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte [ ] DCIH_TitleKey = > _model . DevelopmentCardInfoHeader ? . TitleKey ;
2023-09-12 17:12:23 -04:00
#else
public byte [ ] ? DCIH_TitleKey = > _model . DevelopmentCardInfoHeader ? . TitleKey ;
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.DevelopmentCardInfoHeader.CardDeviceReserved2"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte [ ] DCIH_CardDeviceReserved2 = > _model . DevelopmentCardInfoHeader ? . CardDeviceReserved2 ;
2023-09-12 17:12:23 -04:00
#else
public byte [ ] ? DCIH_CardDeviceReserved2 = > _model . DevelopmentCardInfoHeader ? . CardDeviceReserved2 ;
#endif
2023-01-07 12:33:15 -08:00
#region Test Data
/// <inheritdoc cref="Models.N3DS.TestData.Signature"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte [ ] DCIH_TD_Signature = > _model . DevelopmentCardInfoHeader ? . TestData ? . Signature ;
2023-09-12 17:12:23 -04:00
#else
public byte [ ] ? DCIH_TD_Signature = > _model . DevelopmentCardInfoHeader ? . TestData ? . Signature ;
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.TestData.AscendingByteSequence"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte [ ] DCIH_TD_AscendingByteSequence = > _model . DevelopmentCardInfoHeader ? . TestData ? . AscendingByteSequence ;
2023-09-12 17:12:23 -04:00
#else
public byte [ ] ? DCIH_TD_AscendingByteSequence = > _model . DevelopmentCardInfoHeader ? . TestData ? . AscendingByteSequence ;
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.TestData.DescendingByteSequence"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte [ ] DCIH_TD_DescendingByteSequence = > _model . DevelopmentCardInfoHeader ? . TestData ? . DescendingByteSequence ;
2023-09-12 17:12:23 -04:00
#else
public byte [ ] ? DCIH_TD_DescendingByteSequence = > _model . DevelopmentCardInfoHeader ? . TestData ? . DescendingByteSequence ;
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.TestData.Filled00"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte [ ] DCIH_TD_Filled00 = > _model . DevelopmentCardInfoHeader ? . TestData ? . Filled00 ;
2023-09-12 17:12:23 -04:00
#else
public byte [ ] ? DCIH_TD_Filled00 = > _model . DevelopmentCardInfoHeader ? . TestData ? . Filled00 ;
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.TestData.FilledFF"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte [ ] DCIH_TD_FilledFF = > _model . DevelopmentCardInfoHeader ? . TestData ? . FilledFF ;
2023-09-12 17:12:23 -04:00
#else
public byte [ ] ? DCIH_TD_FilledFF = > _model . DevelopmentCardInfoHeader ? . TestData ? . FilledFF ;
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.TestData.Filled0F"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte [ ] DCIH_TD_Filled0F = > _model . DevelopmentCardInfoHeader ? . TestData ? . Filled0F ;
2023-09-12 17:12:23 -04:00
#else
public byte [ ] ? DCIH_TD_Filled0F = > _model . DevelopmentCardInfoHeader ? . TestData ? . Filled0F ;
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.TestData.FilledF0"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte [ ] DCIH_TD_FilledF0 = > _model . DevelopmentCardInfoHeader ? . TestData ? . FilledF0 ;
2023-09-12 17:12:23 -04:00
#else
public byte [ ] ? DCIH_TD_FilledF0 = > _model . DevelopmentCardInfoHeader ? . TestData ? . FilledF0 ;
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.TestData.Filled55"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte [ ] DCIH_TD_Filled55 = > _model . DevelopmentCardInfoHeader ? . TestData ? . Filled55 ;
2023-09-12 17:12:23 -04:00
#else
public byte [ ] ? DCIH_TD_Filled55 = > _model . DevelopmentCardInfoHeader ? . TestData ? . Filled55 ;
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.TestData.FilledAA"/>
2023-09-12 17:12:23 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public byte [ ] DCIH_TD_FilledAA = > _model . DevelopmentCardInfoHeader ? . TestData ? . FilledAA ;
2023-09-12 17:12:23 -04:00
#else
public byte [ ] ? DCIH_TD_FilledAA = > _model . DevelopmentCardInfoHeader ? . TestData ? . FilledAA ;
#endif
2023-01-07 12:33:15 -08:00
/// <inheritdoc cref="Models.N3DS.TestData.FinalByte"/>
2023-09-11 23:25:09 -04:00
public byte? DCIH_TD_FinalByte = > _model . DevelopmentCardInfoHeader ? . TestData ? . FinalByte ;
2023-01-07 12:33:15 -08:00
#endregion
#endregion
#region Partitions
/// <inheritdoc cref="Models.N3DS.Cart.Partitions"/>
2023-09-12 12:35:19 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public SabreTools . Models . N3DS . NCCHHeader [ ] Partitions = > _model . Partitions ;
2023-09-12 12:35:19 -04:00
#else
public SabreTools . Models . N3DS . NCCHHeader ? [ ] ? Partitions = > _model . Partitions ;
#endif
2023-01-07 12:33:15 -08:00
#endregion
2023-01-07 22:33:55 -08:00
#region Extended Headers
/// <inheritdoc cref="Models.N3DS.Cart.ExtendedHeaders"/>
2023-09-12 12:35:19 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public SabreTools . Models . N3DS . NCCHExtendedHeader [ ] ExtendedHeaders = > _model . ExtendedHeaders ;
2023-09-12 12:35:19 -04:00
#else
public SabreTools . Models . N3DS . NCCHExtendedHeader ? [ ] ? ExtendedHeaders = > _model . ExtendedHeaders ;
#endif
2023-01-07 22:33:55 -08:00
#endregion
2023-01-07 22:50:31 -08:00
#region ExeFS Headers
/// <inheritdoc cref="Models.N3DS.Cart.ExeFSHeaders"/>
2023-09-12 12:35:19 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public SabreTools . Models . N3DS . ExeFSHeader [ ] ExeFSHeaders = > _model . ExeFSHeaders ;
2023-09-12 12:35:19 -04:00
#else
public SabreTools . Models . N3DS . ExeFSHeader ? [ ] ? ExeFSHeaders = > _model . ExeFSHeaders ;
#endif
2023-01-07 22:50:31 -08:00
#endregion
2023-01-07 23:09:26 -08:00
#region RomFS Headers
/// <inheritdoc cref="Models.N3DS.Cart.RomFSHeaders"/>
2023-09-12 12:35:19 -04:00
#if NET48
2023-09-11 23:25:09 -04:00
public SabreTools . Models . N3DS . RomFSHeader [ ] RomFSHeaders = > _model . RomFSHeaders ;
2023-09-12 12:35:19 -04:00
#else
public SabreTools . Models . N3DS . RomFSHeader ? [ ] ? RomFSHeaders = > _model . RomFSHeaders ;
#endif
2023-01-07 23:09:26 -08:00
#endregion
2023-01-07 12:33:15 -08:00
#endregion
#region Constructors
2023-09-11 23:25:09 -04:00
/// <inheritdoc/>
#if NET48
public N3DS ( SabreTools . Models . N3DS . Cart model , byte [ ] data , int offset )
#else
public N3DS ( SabreTools . Models . N3DS . Cart ? model , byte [ ] ? data , int offset )
#endif
: base ( model , data , offset )
{
// All logic is handled by the base class
}
/// <inheritdoc/>
#if NET48
public N3DS ( SabreTools . Models . N3DS . Cart model , Stream data )
#else
public N3DS ( SabreTools . Models . N3DS . Cart ? model , Stream ? data )
#endif
: base ( model , data )
{
// All logic is handled by the base class
}
2023-01-07 12:33:15 -08:00
/// <summary>
/// Create a 3DS cart image from a byte array and offset
/// </summary>
/// <param name="data">Byte array representing the archive</param>
/// <param name="offset">Offset within the array to parse</param>
/// <returns>A 3DS cart image wrapper on success, null on failure</returns>
2023-09-12 17:12:23 -04:00
#if NET48
2023-01-07 12:33:15 -08:00
public static N3DS Create ( byte [ ] data , int offset )
2023-09-12 17:12:23 -04:00
#else
public static N3DS ? Create ( byte [ ] ? data , int offset )
#endif
2023-01-07 12:33:15 -08:00
{
// 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 ) ;
}
/// <summary>
/// Create a 3DS cart image from a Stream
/// </summary>
/// <param name="data">Stream representing the archive</param>
/// <returns>A 3DS cart image wrapper on success, null on failure</returns>
2023-09-12 17:12:23 -04:00
#if NET48
2023-01-07 12:33:15 -08:00
public static N3DS Create ( Stream data )
2023-09-12 17:12:23 -04:00
#else
public static N3DS ? Create ( Stream ? data )
#endif
2023-01-07 12:33:15 -08:00
{
// If the data is invalid
if ( data = = null | | data . Length = = 0 | | ! data . CanSeek | | ! data . CanRead )
return null ;
2023-09-10 23:51:38 -04:00
var archive = new SabreTools . Serialization . Streams . N3DS ( ) . Deserialize ( data ) ;
2023-01-07 12:33:15 -08:00
if ( archive = = null )
return null ;
2023-09-11 23:25:09 -04:00
try
{
return new N3DS ( archive , data ) ;
}
catch
2023-01-07 12:33:15 -08:00
{
2023-09-11 23:25:09 -04:00
return null ;
}
2023-01-07 12:33:15 -08:00
}
#endregion
#region Printing
/// <inheritdoc/>
2023-01-13 14:04:21 -08:00
public override StringBuilder PrettyPrint ( )
2023-01-07 12:33:15 -08:00
{
2023-01-13 14:04:21 -08:00
StringBuilder builder = new StringBuilder ( ) ;
builder . AppendLine ( "3DS Cart Information:" ) ;
builder . AppendLine ( "-------------------------" ) ;
builder . AppendLine ( ) ;
PrintNCSDHeader ( builder ) ;
PrintCardInfoHeader ( builder ) ;
PrintDevelopmentCardInfoHeader ( builder ) ;
PrintPartitions ( builder ) ;
PrintExtendedHeaders ( builder ) ;
PrintExeFSHeaders ( builder ) ;
PrintRomFSHeaders ( builder ) ;
return builder ;
2023-01-07 12:33:15 -08:00
}
/// <summary>
/// Print NCSD header information
/// </summary>
2023-01-13 14:04:21 -08:00
/// <param name="builder">StringBuilder to append information to</param>
private void PrintNCSDHeader ( StringBuilder builder )
2023-01-07 12:33:15 -08:00
{
2023-01-13 14:04:21 -08:00
builder . AppendLine ( " NCSD Header Information:" ) ;
builder . AppendLine ( " -------------------------" ) ;
2023-09-12 17:12:23 -04:00
builder . AppendLine ( $" RSA-2048 SHA-256 signature: {(RSA2048Signature == null ? " [ NULL ] " : BitConverter.ToString(RSA2048Signature).Replace('-', ' '))}" ) ;
2023-01-13 14:04:21 -08:00
builder . AppendLine ( $" Magic number: {MagicNumber} (0x{MagicNumber:X})" ) ;
builder . AppendLine ( $" Image size in media units: {ImageSizeInMediaUnits} (0x{ImageSizeInMediaUnits:X})" ) ;
2023-09-12 17:12:23 -04:00
builder . AppendLine ( $" Media ID: {(MediaId == null ? " [ NULL ] " : BitConverter.ToString(MediaId).Replace('-', ' '))}" ) ;
2023-01-13 14:04:21 -08:00
builder . AppendLine ( $" Partitions filesystem type: {PartitionsFSType} (0x{PartitionsFSType:X})" ) ;
2023-09-12 17:12:23 -04:00
builder . AppendLine ( $" Partitions crypt type: {(PartitionsCryptType == null ? " [ NULL ] " : BitConverter.ToString(PartitionsCryptType).Replace('-', ' '))}" ) ;
2023-01-13 14:04:21 -08:00
builder . AppendLine ( ) ;
builder . AppendLine ( $" Partition table:" ) ;
builder . AppendLine ( " -------------------------" ) ;
2023-09-13 00:08:11 -04:00
if ( PartitionsTable = = null | | PartitionsTable . Length = = 0 )
{
builder . AppendLine ( " No partition table entries" ) ;
}
else
2023-01-07 12:33:15 -08:00
{
2023-09-13 00:08:11 -04:00
for ( int i = 0 ; i < PartitionsTable . Length ; i + + )
{
var partitionTableEntry = PartitionsTable [ i ] ;
builder . AppendLine ( $" Partition table entry {i}" ) ;
if ( partitionTableEntry = = null )
{
builder . AppendLine ( " [NULL]" ) ;
continue ;
}
builder . AppendLine ( $" Offset: {partitionTableEntry.Offset} (0x{partitionTableEntry.Offset:X})" ) ;
builder . AppendLine ( $" Length: {partitionTableEntry.Length} (0x{partitionTableEntry.Length:X})" ) ;
}
2023-01-07 12:33:15 -08:00
}
2023-01-13 14:04:21 -08:00
builder . AppendLine ( ) ;
2023-01-07 12:33:15 -08:00
// If we have a cart image
2023-09-04 23:44:45 -04:00
if ( PartitionsFSType = = SabreTools . Models . N3DS . FilesystemType . Normal | | PartitionsFSType = = SabreTools . Models . N3DS . FilesystemType . None )
2023-01-07 12:33:15 -08:00
{
2023-09-12 17:12:23 -04:00
builder . AppendLine ( $" Exheader SHA-256 hash: {(ExheaderHash == null ? " [ NULL ] " : BitConverter.ToString(ExheaderHash).Replace('-', ' '))}" ) ;
2023-01-13 14:04:21 -08:00
builder . AppendLine ( $" Additional header size: {AdditionalHeaderSize} (0x{AdditionalHeaderSize:X})" ) ;
builder . AppendLine ( $" Sector zero offset: {SectorZeroOffset} (0x{SectorZeroOffset:X})" ) ;
2023-09-12 17:12:23 -04:00
builder . AppendLine ( $" Partition flags: {(PartitionFlags == null ? " [ NULL ] " : BitConverter.ToString(PartitionFlags).Replace('-', ' '))}" ) ;
2023-01-13 14:04:21 -08:00
builder . AppendLine ( ) ;
builder . AppendLine ( $" Partition ID table:" ) ;
builder . AppendLine ( " -------------------------" ) ;
2023-09-13 00:08:11 -04:00
if ( PartitionIdTable = = null | | PartitionIdTable . Length = = 0 )
{
builder . AppendLine ( " No partition ID table entries" ) ;
}
else
2023-01-07 12:33:15 -08:00
{
2023-09-13 00:08:11 -04:00
for ( int i = 0 ; i < PartitionIdTable . Length ; i + + )
{
builder . AppendLine ( $" Partition {i} ID: {PartitionIdTable[i]} (0x{PartitionIdTable[i]:X})" ) ;
}
2023-01-07 12:33:15 -08:00
}
2023-01-13 14:04:21 -08:00
builder . AppendLine ( ) ;
2023-01-07 12:33:15 -08:00
2023-09-12 17:12:23 -04:00
builder . AppendLine ( $" Reserved 1: {(Reserved1 == null ? " [ NULL ] " : BitConverter.ToString(Reserved1).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Reserved 2: {(Reserved2 == null ? " [ NULL ] " : BitConverter.ToString(Reserved2).Replace('-', ' '))}" ) ;
2023-01-13 14:04:21 -08:00
builder . AppendLine ( $" Firmware update byte 1: {FirmUpdateByte1} (0x{FirmUpdateByte1:X})" ) ;
builder . AppendLine ( $" Firmware update byte 2: {FirmUpdateByte2} (0x{FirmUpdateByte2:X})" ) ;
2023-01-07 12:33:15 -08:00
}
// If we have a firmware image
2023-09-04 23:44:45 -04:00
else if ( PartitionsFSType = = SabreTools . Models . N3DS . FilesystemType . FIRM )
2023-01-07 12:33:15 -08:00
{
2023-09-12 17:12:23 -04:00
builder . AppendLine ( $" Unknown: {(Unknown == null ? " [ NULL ] " : BitConverter.ToString(Unknown).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Encrypted MBR: {(EncryptedMBR == null ? " [ NULL ] " : BitConverter.ToString(EncryptedMBR).Replace('-', ' '))}" ) ;
2023-01-07 12:33:15 -08:00
}
2023-01-13 14:04:21 -08:00
builder . AppendLine ( ) ;
2023-01-07 12:33:15 -08:00
}
/// <summary>
/// Print card info header information
/// </summary>
2023-01-13 14:04:21 -08:00
/// <param name="builder">StringBuilder to append information to</param>
private void PrintCardInfoHeader ( StringBuilder builder )
2023-01-07 12:33:15 -08:00
{
2023-01-13 14:04:21 -08:00
builder . AppendLine ( " Card Info Header Information:" ) ;
builder . AppendLine ( " -------------------------" ) ;
builder . AppendLine ( $" Writable address in media units: {CIH_WritableAddressMediaUnits} (0x{CIH_WritableAddressMediaUnits:X})" ) ;
builder . AppendLine ( $" Card info bitmask: {CIH_CardInfoBitmask} (0x{CIH_CardInfoBitmask:X})" ) ;
2023-09-12 17:12:23 -04:00
builder . AppendLine ( $" Reserved 1: {(CIH_Reserved1 == null ? " [ NULL ] " : BitConverter.ToString(CIH_Reserved1).Replace('-', ' '))}" ) ;
2023-01-13 14:04:21 -08:00
builder . AppendLine ( $" Filled size of cartridge: {CIH_FilledSize} (0x{CIH_FilledSize:X})" ) ;
2023-09-12 17:12:23 -04:00
builder . AppendLine ( $" Reserved 2: {(CIH_Reserved2 == null ? " [ NULL ] " : BitConverter.ToString(CIH_Reserved2).Replace('-', ' '))}" ) ;
2023-01-13 14:04:21 -08:00
builder . AppendLine ( $" Title version: {CIH_TitleVersion} (0x{CIH_TitleVersion:X})" ) ;
builder . AppendLine ( $" Card revision: {CIH_CardRevision} (0x{CIH_CardRevision:X})" ) ;
2023-09-12 17:12:23 -04:00
builder . AppendLine ( $" Reserved 3: {(CIH_Reserved3 == null ? " [ NULL ] " : BitConverter.ToString(CIH_Reserved3).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Title ID of CVer in included update partition: {(CIH_CVerTitleID == null ? " [ NULL ] " : BitConverter.ToString(CIH_CVerTitleID).Replace('-', ' '))}" ) ;
2023-01-13 14:04:21 -08:00
builder . AppendLine ( $" Version number of CVer in included update partition: {CIH_CVerVersionNumber} (0x{CIH_CVerVersionNumber:X})" ) ;
2023-09-12 17:12:23 -04:00
builder . AppendLine ( $" Reserved 4: {(CIH_Reserved4 == null ? " [ NULL ] " : BitConverter.ToString(CIH_Reserved4).Replace('-', ' '))}" ) ;
2023-01-13 14:04:21 -08:00
builder . AppendLine ( ) ;
2023-01-07 12:33:15 -08:00
}
/// <summary>
/// Print development card info header information
/// </summary>
2023-01-13 14:04:21 -08:00
/// <param name="builder">StringBuilder to append information to</param>
private void PrintDevelopmentCardInfoHeader ( StringBuilder builder )
2023-01-07 12:33:15 -08:00
{
2023-01-13 14:04:21 -08:00
builder . AppendLine ( " Development Card Info Header Information:" ) ;
builder . AppendLine ( " -------------------------" ) ;
2023-09-11 23:25:09 -04:00
if ( _model . DevelopmentCardInfoHeader = = null )
2023-01-07 12:33:15 -08:00
{
2023-01-13 14:04:21 -08:00
builder . AppendLine ( " No development card info header" ) ;
2023-01-07 12:33:15 -08:00
}
else
{
2023-01-13 14:04:21 -08:00
builder . AppendLine ( ) ;
builder . AppendLine ( " Initial Data:" ) ;
builder . AppendLine ( " -------------------------" ) ;
2023-09-12 17:12:23 -04:00
builder . AppendLine ( $" Card seed keyY: {(DCIH_ID_CardSeedKeyY == null ? " [ NULL ] " : BitConverter.ToString(DCIH_ID_CardSeedKeyY).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Encrypted card seed: {(DCIH_ID_EncryptedCardSeed == null ? " [ NULL ] " : BitConverter.ToString(DCIH_ID_EncryptedCardSeed).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Card seed AES-MAC: {(DCIH_ID_CardSeedAESMAC == null ? " [ NULL ] " : BitConverter.ToString(DCIH_ID_CardSeedAESMAC).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Card seed nonce: {(DCIH_ID_CardSeedNonce == null ? " [ NULL ] " : BitConverter.ToString(DCIH_ID_CardSeedNonce).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Reserved: {(DCIH_ID_Reserved == null ? " [ NULL ] " : BitConverter.ToString(DCIH_ID_Reserved).Replace('-', ' '))}" ) ;
2023-01-13 14:04:21 -08:00
builder . AppendLine ( ) ;
builder . AppendLine ( " Backup Header:" ) ;
builder . AppendLine ( " -------------------------" ) ;
2023-09-13 00:08:11 -04:00
if ( DCIH_ID_BackupHeader = = null )
{
builder . AppendLine ( " No backup header" ) ;
}
else
{
builder . AppendLine ( $" Magic ID: {DCIH_ID_BackupHeader.MagicID} (0x{DCIH_ID_BackupHeader.MagicID:X})" ) ;
builder . AppendLine ( $" Content size in media units: {DCIH_ID_BackupHeader.ContentSizeInMediaUnits} (0x{DCIH_ID_BackupHeader.ContentSizeInMediaUnits:X})" ) ;
builder . AppendLine ( $" Partition ID: {DCIH_ID_BackupHeader.PartitionId} (0x{DCIH_ID_BackupHeader.PartitionId:X})" ) ;
builder . AppendLine ( $" Maker code: {DCIH_ID_BackupHeader.MakerCode} (0x{DCIH_ID_BackupHeader.MakerCode:X})" ) ;
builder . AppendLine ( $" Version: {DCIH_ID_BackupHeader.Version} (0x{DCIH_ID_BackupHeader.Version:X})" ) ;
builder . AppendLine ( $" Verification hash: {DCIH_ID_BackupHeader.VerificationHash} (0x{DCIH_ID_BackupHeader.VerificationHash:X})" ) ;
builder . AppendLine ( $" Program ID: {(DCIH_ID_BackupHeader.ProgramId == null ? " [ NULL ] " : BitConverter.ToString(DCIH_ID_BackupHeader.ProgramId).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Reserved 1: {(DCIH_ID_BackupHeader.Reserved1 == null ? " [ NULL ] " : BitConverter.ToString(DCIH_ID_BackupHeader.Reserved1).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Logo region SHA-256 hash: {(DCIH_ID_BackupHeader.LogoRegionHash == null ? " [ NULL ] " : BitConverter.ToString(DCIH_ID_BackupHeader.LogoRegionHash).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Product code: {DCIH_ID_BackupHeader.ProductCode} (0x{DCIH_ID_BackupHeader.ProductCode:X})" ) ;
builder . AppendLine ( $" Extended header SHA-256 hash: {(DCIH_ID_BackupHeader.ExtendedHeaderHash == null ? " [ NULL ] " : BitConverter.ToString(DCIH_ID_BackupHeader.ExtendedHeaderHash).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Extended header size in bytes: {DCIH_ID_BackupHeader.ExtendedHeaderSizeInBytes} (0x{DCIH_ID_BackupHeader.ExtendedHeaderSizeInBytes:X})" ) ;
builder . AppendLine ( $" Reserved 2: {(DCIH_ID_BackupHeader.Reserved2 == null ? " [ NULL ] " : BitConverter.ToString(DCIH_ID_BackupHeader.Reserved2).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Flags: {DCIH_ID_BackupHeader.Flags} (0x{DCIH_ID_BackupHeader.Flags:X})" ) ;
builder . AppendLine ( $" Plain region offset, in media units: {DCIH_ID_BackupHeader.PlainRegionOffsetInMediaUnits} (0x{DCIH_ID_BackupHeader.PlainRegionOffsetInMediaUnits:X})" ) ;
builder . AppendLine ( $" Plain region size, in media units: {DCIH_ID_BackupHeader.PlainRegionSizeInMediaUnits} (0x{DCIH_ID_BackupHeader.PlainRegionSizeInMediaUnits:X})" ) ;
builder . AppendLine ( $" Logo region offset, in media units: {DCIH_ID_BackupHeader.LogoRegionOffsetInMediaUnits} (0x{DCIH_ID_BackupHeader.LogoRegionOffsetInMediaUnits:X})" ) ;
builder . AppendLine ( $" Logo region size, in media units: {DCIH_ID_BackupHeader.LogoRegionSizeInMediaUnits} (0x{DCIH_ID_BackupHeader.LogoRegionSizeInMediaUnits:X})" ) ;
builder . AppendLine ( $" ExeFS offset, in media units: {DCIH_ID_BackupHeader.ExeFSOffsetInMediaUnits} (0x{DCIH_ID_BackupHeader.ExeFSOffsetInMediaUnits:X})" ) ;
builder . AppendLine ( $" ExeFS size, in media units: {DCIH_ID_BackupHeader.ExeFSSizeInMediaUnits} (0x{DCIH_ID_BackupHeader.ExeFSSizeInMediaUnits:X})" ) ;
builder . AppendLine ( $" ExeFS hash region size, in media units: {DCIH_ID_BackupHeader.ExeFSHashRegionSizeInMediaUnits} (0x{DCIH_ID_BackupHeader.ExeFSHashRegionSizeInMediaUnits:X})" ) ;
builder . AppendLine ( $" Reserved 3: {(DCIH_ID_BackupHeader.Reserved3 == null ? " [ NULL ] " : BitConverter.ToString(DCIH_ID_BackupHeader.Reserved3).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" RomFS offset, in media units: {DCIH_ID_BackupHeader.RomFSOffsetInMediaUnits} (0x{DCIH_ID_BackupHeader.RomFSOffsetInMediaUnits:X})" ) ;
builder . AppendLine ( $" RomFS size, in media units: {DCIH_ID_BackupHeader.RomFSSizeInMediaUnits} (0x{DCIH_ID_BackupHeader.RomFSSizeInMediaUnits:X})" ) ;
builder . AppendLine ( $" RomFS hash region size, in media units: {DCIH_ID_BackupHeader.RomFSHashRegionSizeInMediaUnits} (0x{DCIH_ID_BackupHeader.RomFSHashRegionSizeInMediaUnits:X})" ) ;
builder . AppendLine ( $" Reserved 4: {(DCIH_ID_BackupHeader.Reserved4 == null ? " [ NULL ] " : BitConverter.ToString(DCIH_ID_BackupHeader.Reserved4).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" ExeFS superblock SHA-256 hash: {(DCIH_ID_BackupHeader.ExeFSSuperblockHash == null ? " [ NULL ] " : BitConverter.ToString(DCIH_ID_BackupHeader.ExeFSSuperblockHash).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" RomFS superblock SHA-256 hash: {(DCIH_ID_BackupHeader.RomFSSuperblockHash == null ? " [ NULL ] " : BitConverter.ToString(DCIH_ID_BackupHeader.RomFSSuperblockHash).Replace('-', ' '))}" ) ;
}
2023-01-13 14:04:21 -08:00
builder . AppendLine ( ) ;
2023-09-12 17:12:23 -04:00
builder . AppendLine ( $" Card device reserved 1: {(DCIH_CardDeviceReserved1 == null ? " [ NULL ] " : BitConverter.ToString(DCIH_CardDeviceReserved1).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Title key: {(DCIH_TitleKey == null ? " [ NULL ] " : BitConverter.ToString(DCIH_TitleKey).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Card device reserved 2: {(DCIH_CardDeviceReserved2 == null ? " [ NULL ] " : BitConverter.ToString(DCIH_CardDeviceReserved2).Replace('-', ' '))}" ) ;
2023-01-13 14:04:21 -08:00
builder . AppendLine ( ) ;
builder . AppendLine ( " Test Data:" ) ;
builder . AppendLine ( " -------------------------" ) ;
2023-09-12 17:12:23 -04:00
builder . AppendLine ( $" Signature: {(DCIH_TD_Signature == null ? " [ NULL ] " : BitConverter.ToString(DCIH_TD_Signature).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Ascending byte sequence: {(DCIH_TD_AscendingByteSequence == null ? " [ NULL ] " : BitConverter.ToString(DCIH_TD_AscendingByteSequence).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Descending byte sequence: {(DCIH_TD_DescendingByteSequence == null ? " [ NULL ] " : BitConverter.ToString(DCIH_TD_DescendingByteSequence).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Filled with 00: {(DCIH_TD_Filled00 == null ? " [ NULL ] " : BitConverter.ToString(DCIH_TD_Filled00).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Filled with FF: {(DCIH_TD_FilledFF == null ? " [ NULL ] " : BitConverter.ToString(DCIH_TD_FilledFF).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Filled with 0F: {(DCIH_TD_Filled0F == null ? " [ NULL ] " : BitConverter.ToString(DCIH_TD_Filled0F).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Filled with F0: {(DCIH_TD_FilledF0 == null ? " [ NULL ] " : BitConverter.ToString(DCIH_TD_FilledF0).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Filled with 55: {(DCIH_TD_Filled55 == null ? " [ NULL ] " : BitConverter.ToString(DCIH_TD_Filled55).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Filled with AA: {(DCIH_TD_FilledAA == null ? " [ NULL ] " : BitConverter.ToString(DCIH_TD_FilledAA).Replace('-', ' '))}" ) ;
2023-01-13 14:04:21 -08:00
builder . AppendLine ( $" Final byte: {DCIH_TD_FinalByte}" ) ;
2023-01-07 12:33:15 -08:00
}
2023-01-13 14:04:21 -08:00
builder . AppendLine ( ) ;
2023-01-07 12:33:15 -08:00
}
/// <summary>
/// Print NCCH partition header information
/// </summary>
2023-01-13 14:04:21 -08:00
/// <param name="builder">StringBuilder to append information to</param>
private void PrintPartitions ( StringBuilder builder )
2023-01-07 12:33:15 -08:00
{
2023-01-13 14:04:21 -08:00
builder . AppendLine ( " NCCH Partition Header Information:" ) ;
builder . AppendLine ( " -------------------------" ) ;
2023-01-07 12:33:15 -08:00
if ( Partitions = = null | | Partitions . Length = = 0 )
{
2023-01-13 14:04:21 -08:00
builder . AppendLine ( " No NCCH partition headers" ) ;
2023-01-07 12:33:15 -08:00
}
else
{
for ( int i = 0 ; i < Partitions . Length ; i + + )
{
var partitionHeader = Partitions [ i ] ;
2023-01-13 14:04:21 -08:00
builder . AppendLine ( $" NCCH Partition Header {i}" ) ;
2023-09-13 00:08:11 -04:00
if ( partitionHeader = = null )
{
builder . AppendLine ( $" [NULL]" ) ;
continue ;
}
2023-01-07 21:42:13 -08:00
if ( partitionHeader . MagicID = = string . Empty )
{
2023-01-13 14:04:21 -08:00
builder . AppendLine ( $" Empty partition, no data can be parsed" ) ;
2023-01-07 21:42:13 -08:00
}
2023-09-04 23:44:45 -04:00
else if ( partitionHeader . MagicID ! = SabreTools . Models . N3DS . Constants . NCCHMagicNumber )
2023-01-07 21:42:13 -08:00
{
2023-01-13 14:04:21 -08:00
builder . AppendLine ( $" Unrecognized partition data, no data can be parsed" ) ;
2023-01-07 21:42:13 -08:00
}
else
{
2023-09-12 17:12:23 -04:00
builder . AppendLine ( $" RSA-2048 SHA-256 signature: {(partitionHeader.RSA2048Signature == null ? " [ NULL ] " : BitConverter.ToString(partitionHeader.RSA2048Signature).Replace('-', ' '))}" ) ;
2023-01-13 14:04:21 -08:00
builder . AppendLine ( $" Magic ID: {partitionHeader.MagicID} (0x{partitionHeader.MagicID:X})" ) ;
builder . AppendLine ( $" Content size in media units: {partitionHeader.ContentSizeInMediaUnits} (0x{partitionHeader.ContentSizeInMediaUnits:X})" ) ;
builder . AppendLine ( $" Partition ID: {partitionHeader.PartitionId} (0x{partitionHeader.PartitionId:X})" ) ;
builder . AppendLine ( $" Maker code: {partitionHeader.MakerCode} (0x{partitionHeader.MakerCode:X})" ) ;
builder . AppendLine ( $" Version: {partitionHeader.Version} (0x{partitionHeader.Version:X})" ) ;
builder . AppendLine ( $" Verification hash: {partitionHeader.VerificationHash} (0x{partitionHeader.VerificationHash:X})" ) ;
2023-09-12 17:12:23 -04:00
builder . AppendLine ( $" Program ID: {(partitionHeader.ProgramId == null ? " [ NULL ] " : BitConverter.ToString(partitionHeader.ProgramId).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Reserved 1: {(partitionHeader.Reserved1 == null ? " [ NULL ] " : BitConverter.ToString(partitionHeader.Reserved1).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Logo region SHA-256 hash: {(partitionHeader.LogoRegionHash == null ? " [ NULL ] " : BitConverter.ToString(partitionHeader.LogoRegionHash).Replace('-', ' '))}" ) ;
2023-01-13 14:04:21 -08:00
builder . AppendLine ( $" Product code: {partitionHeader.ProductCode} (0x{partitionHeader.ProductCode:X})" ) ;
2023-09-12 17:12:23 -04:00
builder . AppendLine ( $" Extended header SHA-256 hash: {(partitionHeader.ExtendedHeaderHash == null ? " [ NULL ] " : BitConverter.ToString(partitionHeader.ExtendedHeaderHash).Replace('-', ' '))}" ) ;
2023-01-13 14:04:21 -08:00
builder . AppendLine ( $" Extended header size in bytes: {partitionHeader.ExtendedHeaderSizeInBytes} (0x{partitionHeader.ExtendedHeaderSizeInBytes:X})" ) ;
2023-09-12 17:12:23 -04:00
builder . AppendLine ( $" Reserved 2: {(partitionHeader.Reserved2 == null ? " [ NULL ] " : BitConverter.ToString(partitionHeader.Reserved2).Replace('-', ' '))}" ) ;
2023-01-13 14:04:21 -08:00
builder . AppendLine ( " Flags:" ) ;
2023-09-13 00:08:11 -04:00
if ( partitionHeader . Flags = = null )
{
builder . AppendLine ( " [NULL]" ) ;
}
else
{
builder . AppendLine ( $" Reserved 0: {partitionHeader.Flags.Reserved0} (0x{partitionHeader.Flags.Reserved0:X})" ) ;
builder . AppendLine ( $" Reserved 1: {partitionHeader.Flags.Reserved1} (0x{partitionHeader.Flags.Reserved1:X})" ) ;
builder . AppendLine ( $" Reserved 2: {partitionHeader.Flags.Reserved2} (0x{partitionHeader.Flags.Reserved2:X})" ) ;
builder . AppendLine ( $" Crypto method: {partitionHeader.Flags.CryptoMethod} (0x{partitionHeader.Flags.CryptoMethod:X})" ) ;
builder . AppendLine ( $" Content platform: {partitionHeader.Flags.ContentPlatform} (0x{partitionHeader.Flags.ContentPlatform:X})" ) ;
builder . AppendLine ( $" Content type: {partitionHeader.Flags.MediaPlatformIndex} (0x{partitionHeader.Flags.MediaPlatformIndex:X})" ) ;
builder . AppendLine ( $" Content unit size: {partitionHeader.Flags.ContentUnitSize} (0x{partitionHeader.Flags.ContentUnitSize:X})" ) ;
builder . AppendLine ( $" Bitmasks: {partitionHeader.Flags.BitMasks} (0x{partitionHeader.Flags.BitMasks:X})" ) ;
}
2023-01-13 14:04:21 -08:00
builder . AppendLine ( $" Plain region offset, in media units: {partitionHeader.PlainRegionOffsetInMediaUnits} (0x{partitionHeader.PlainRegionOffsetInMediaUnits:X})" ) ;
builder . AppendLine ( $" Plain region size, in media units: {partitionHeader.PlainRegionSizeInMediaUnits} (0x{partitionHeader.PlainRegionSizeInMediaUnits:X})" ) ;
builder . AppendLine ( $" Logo region offset, in media units: {partitionHeader.LogoRegionOffsetInMediaUnits} (0x{partitionHeader.LogoRegionOffsetInMediaUnits:X})" ) ;
builder . AppendLine ( $" Logo region size, in media units: {partitionHeader.LogoRegionSizeInMediaUnits} (0x{partitionHeader.LogoRegionSizeInMediaUnits:X})" ) ;
builder . AppendLine ( $" ExeFS offset, in media units: {partitionHeader.ExeFSOffsetInMediaUnits} (0x{partitionHeader.ExeFSOffsetInMediaUnits:X})" ) ;
builder . AppendLine ( $" ExeFS size, in media units: {partitionHeader.ExeFSSizeInMediaUnits} (0x{partitionHeader.ExeFSSizeInMediaUnits:X})" ) ;
builder . AppendLine ( $" ExeFS hash region size, in media units: {partitionHeader.ExeFSHashRegionSizeInMediaUnits} (0x{partitionHeader.ExeFSHashRegionSizeInMediaUnits:X})" ) ;
2023-09-12 17:12:23 -04:00
builder . AppendLine ( $" Reserved 3: {(partitionHeader.Reserved3 == null ? " [ NULL ] " : BitConverter.ToString(partitionHeader.Reserved3).Replace('-', ' '))}" ) ;
2023-01-13 14:04:21 -08:00
builder . AppendLine ( $" RomFS offset, in media units: {partitionHeader.RomFSOffsetInMediaUnits} (0x{partitionHeader.RomFSOffsetInMediaUnits:X})" ) ;
builder . AppendLine ( $" RomFS size, in media units: {partitionHeader.RomFSSizeInMediaUnits} (0x{partitionHeader.RomFSSizeInMediaUnits:X})" ) ;
builder . AppendLine ( $" RomFS hash region size, in media units: {partitionHeader.RomFSHashRegionSizeInMediaUnits} (0x{partitionHeader.RomFSHashRegionSizeInMediaUnits:X})" ) ;
2023-09-12 17:12:23 -04:00
builder . AppendLine ( $" Reserved 4: {(partitionHeader.Reserved4 == null ? " [ NULL ] " : BitConverter.ToString(partitionHeader.Reserved4).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" ExeFS superblock SHA-256 hash: {(partitionHeader.ExeFSSuperblockHash == null ? " [ NULL ] " : BitConverter.ToString(partitionHeader.ExeFSSuperblockHash).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" RomFS superblock SHA-256 hash: {(partitionHeader.RomFSSuperblockHash == null ? " [ NULL ] " : BitConverter.ToString(partitionHeader.RomFSSuperblockHash).Replace('-', ' '))}" ) ;
2023-01-07 21:42:13 -08:00
}
2023-01-07 12:33:15 -08:00
}
}
2023-01-13 14:04:21 -08:00
builder . AppendLine ( ) ;
2023-01-07 12:33:15 -08:00
}
2023-01-07 22:33:55 -08:00
/// <summary>
/// Print NCCH extended header information
/// </summary>
2023-01-13 14:04:21 -08:00
/// <param name="builder">StringBuilder to append information to</param>
private void PrintExtendedHeaders ( StringBuilder builder )
2023-01-07 22:33:55 -08:00
{
2023-01-13 14:04:21 -08:00
builder . AppendLine ( " NCCH Extended Header Information:" ) ;
builder . AppendLine ( " -------------------------" ) ;
2023-01-07 22:33:55 -08:00
if ( ExtendedHeaders = = null | | ExtendedHeaders . Length = = 0 )
{
2023-01-13 14:04:21 -08:00
builder . AppendLine ( " No NCCH extended headers" ) ;
2023-01-07 22:33:55 -08:00
}
else
{
for ( int i = 0 ; i < ExtendedHeaders . Length ; i + + )
{
var extendedHeader = ExtendedHeaders [ i ] ;
2023-01-13 14:04:21 -08:00
builder . AppendLine ( $" NCCH Extended Header {i}" ) ;
2023-01-07 22:33:55 -08:00
if ( extendedHeader = = null )
{
2023-01-13 14:04:21 -08:00
builder . AppendLine ( $" Unrecognized partition data, no data can be parsed" ) ;
2023-01-07 22:33:55 -08:00
}
else
{
2023-01-13 14:04:21 -08:00
builder . AppendLine ( $" System control info:" ) ;
2023-09-13 00:08:11 -04:00
if ( extendedHeader . SCI = = null )
{
builder . AppendLine ( " [NULL]" ) ;
}
else
{
builder . AppendLine ( $" Application title: {extendedHeader.SCI.ApplicationTitle}" ) ;
builder . AppendLine ( $" Reserved 1: {(extendedHeader.SCI.Reserved1 == null ? " [ NULL ] " : BitConverter.ToString(extendedHeader.SCI.Reserved1).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Flag: {extendedHeader.SCI.Flag} (0x{extendedHeader.SCI.Flag:X})" ) ;
builder . AppendLine ( $" Remaster version: {extendedHeader.SCI.RemasterVersion} (0x{extendedHeader.SCI.RemasterVersion:X})" ) ;
builder . AppendLine ( $" Text code set info:" ) ;
if ( extendedHeader . SCI . TextCodeSetInfo = = null )
{
builder . AppendLine ( " [NULL]" ) ;
}
else
{
builder . AppendLine ( $" Address: {extendedHeader.SCI.TextCodeSetInfo.Address} (0x{extendedHeader.SCI.TextCodeSetInfo.Address:X})" ) ;
builder . AppendLine ( $" Physical region size (in page-multiples): {extendedHeader.SCI.TextCodeSetInfo.PhysicalRegionSizeInPages} (0x{extendedHeader.SCI.TextCodeSetInfo.PhysicalRegionSizeInPages:X})" ) ;
builder . AppendLine ( $" Size (in bytes): {extendedHeader.SCI.TextCodeSetInfo.SizeInBytes} (0x{extendedHeader.SCI.TextCodeSetInfo.SizeInBytes:X})" ) ;
}
builder . AppendLine ( $" Stack size: {extendedHeader.SCI.StackSize} (0x{extendedHeader.SCI.StackSize:X})" ) ;
builder . AppendLine ( $" Read-only code set info:" ) ;
if ( extendedHeader . SCI . ReadOnlyCodeSetInfo = = null )
{
builder . AppendLine ( " [NULL]" ) ;
}
else
{
builder . AppendLine ( $" Address: {extendedHeader.SCI.ReadOnlyCodeSetInfo.Address} (0x{extendedHeader.SCI.ReadOnlyCodeSetInfo.Address:X})" ) ;
builder . AppendLine ( $" Physical region size (in page-multiples): {extendedHeader.SCI.ReadOnlyCodeSetInfo.PhysicalRegionSizeInPages} (0x{extendedHeader.SCI.ReadOnlyCodeSetInfo.PhysicalRegionSizeInPages:X})" ) ;
builder . AppendLine ( $" Size (in bytes): {extendedHeader.SCI.ReadOnlyCodeSetInfo.SizeInBytes} (0x{extendedHeader.SCI.ReadOnlyCodeSetInfo.SizeInBytes:X})" ) ;
}
builder . AppendLine ( $" Reserved 2: {(extendedHeader.SCI.Reserved2 == null ? " [ NULL ] " : BitConverter.ToString(extendedHeader.SCI.Reserved2).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Data code set info:" ) ;
if ( extendedHeader . SCI . DataCodeSetInfo = = null )
{
builder . AppendLine ( " [NULL]" ) ;
}
else
{
builder . AppendLine ( $" Address: {extendedHeader.SCI.DataCodeSetInfo.Address} (0x{extendedHeader.SCI.DataCodeSetInfo.Address:X})" ) ;
builder . AppendLine ( $" Physical region size (in page-multiples): {extendedHeader.SCI.DataCodeSetInfo.PhysicalRegionSizeInPages} (0x{extendedHeader.SCI.DataCodeSetInfo.PhysicalRegionSizeInPages:X})" ) ;
builder . AppendLine ( $" Size (in bytes): {extendedHeader.SCI.DataCodeSetInfo.SizeInBytes} (0x{extendedHeader.SCI.DataCodeSetInfo.SizeInBytes:X})" ) ;
}
builder . AppendLine ( $" BSS size: {extendedHeader.SCI.BSSSize} (0x{extendedHeader.SCI.BSSSize:X})" ) ;
builder . AppendLine ( $" Dependency module list: {(extendedHeader.SCI.DependencyModuleList == null ? " [ NULL ] " : string.Join(" , ", extendedHeader.SCI.DependencyModuleList))}" ) ;
builder . AppendLine ( $" System info:" ) ;
if ( extendedHeader . SCI . SystemInfo = = null )
{
builder . AppendLine ( " [NULL]" ) ;
}
else
{
builder . AppendLine ( $" SaveData size: {extendedHeader.SCI.SystemInfo.SaveDataSize} (0x{extendedHeader.SCI.SystemInfo.SaveDataSize:X})" ) ;
builder . AppendLine ( $" Jump ID: {extendedHeader.SCI.SystemInfo.JumpID} (0x{extendedHeader.SCI.SystemInfo.JumpID:X})" ) ;
builder . AppendLine ( $" Reserved: {(extendedHeader.SCI.SystemInfo.Reserved == null ? " [ NULL ] " : BitConverter.ToString(extendedHeader.SCI.SystemInfo.Reserved).Replace('-', ' '))}" ) ;
}
}
2023-01-13 14:04:21 -08:00
builder . AppendLine ( $" Access control info:" ) ;
2023-09-13 00:08:11 -04:00
if ( extendedHeader . ACI = = null )
{
builder . AppendLine ( " [NULL]" ) ;
}
else
{
builder . AppendLine ( $" ARM11 local system capabilities:" ) ;
if ( extendedHeader . ACI . ARM11LocalSystemCapabilities = = null )
{
builder . AppendLine ( " [NULL]" ) ;
}
else
{
builder . AppendLine ( $" Program ID: {extendedHeader.ACI.ARM11LocalSystemCapabilities.ProgramID} (0x{extendedHeader.ACI.ARM11LocalSystemCapabilities.ProgramID:X})" ) ;
builder . AppendLine ( $" Core version: {extendedHeader.ACI.ARM11LocalSystemCapabilities.CoreVersion} (0x{extendedHeader.ACI.ARM11LocalSystemCapabilities.CoreVersion:X})" ) ;
builder . AppendLine ( $" Flag 1: {extendedHeader.ACI.ARM11LocalSystemCapabilities.Flag1} (0x{extendedHeader.ACI.ARM11LocalSystemCapabilities.Flag1:X})" ) ;
builder . AppendLine ( $" Flag 2: {extendedHeader.ACI.ARM11LocalSystemCapabilities.Flag2} (0x{extendedHeader.ACI.ARM11LocalSystemCapabilities.Flag2:X})" ) ;
builder . AppendLine ( $" Flag 0: {extendedHeader.ACI.ARM11LocalSystemCapabilities.Flag0} (0x{extendedHeader.ACI.ARM11LocalSystemCapabilities.Flag0:X})" ) ;
builder . AppendLine ( $" Priority: {extendedHeader.ACI.ARM11LocalSystemCapabilities.Priority} (0x{extendedHeader.ACI.ARM11LocalSystemCapabilities.Priority:X})" ) ;
builder . AppendLine ( $" Resource limit descriptors: {(extendedHeader.ACI.ARM11LocalSystemCapabilities.ResourceLimitDescriptors == null ? " [ NULL ] " : string.Join(" , ", extendedHeader.ACI.ARM11LocalSystemCapabilities.ResourceLimitDescriptors))}" ) ;
builder . AppendLine ( $" Storage info:" ) ;
if ( extendedHeader . ACI . ARM11LocalSystemCapabilities . StorageInfo = = null )
{
builder . AppendLine ( " [NULL]" ) ;
}
else
{
builder . AppendLine ( $" Extdata ID: {extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.ExtdataID} (0x{extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.ExtdataID:X})" ) ;
builder . AppendLine ( $" System savedata IDs: {(extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.SystemSavedataIDs == null ? " [ NULL ] " : BitConverter.ToString(extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.SystemSavedataIDs).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Storage accessible unique IDs: {(extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.StorageAccessibleUniqueIDs == null ? " [ NULL ] " : BitConverter.ToString(extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.StorageAccessibleUniqueIDs).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" File system access info: {(extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.FileSystemAccessInfo == null ? " [ NULL ] " : BitConverter.ToString(extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.FileSystemAccessInfo).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Other attributes: {extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.OtherAttributes} (0x{extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.OtherAttributes:X})" ) ;
}
builder . AppendLine ( $" Service access control: {(extendedHeader.ACI.ARM11LocalSystemCapabilities.ServiceAccessControl == null ? " [ NULL ] " : string.Join(" , ", extendedHeader.ACI.ARM11LocalSystemCapabilities.ServiceAccessControl))}" ) ;
builder . AppendLine ( $" Extended service access control: {(extendedHeader.ACI.ARM11LocalSystemCapabilities.ExtendedServiceAccessControl == null ? " [ NULL ] " : string.Join(" , ", extendedHeader.ACI.ARM11LocalSystemCapabilities.ExtendedServiceAccessControl))}" ) ;
builder . AppendLine ( $" Reserved: {(extendedHeader.ACI.ARM11LocalSystemCapabilities.Reserved == null ? " [ NULL ] " : BitConverter.ToString(extendedHeader.ACI.ARM11LocalSystemCapabilities.Reserved).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Resource limit cateogry: {extendedHeader.ACI.ARM11LocalSystemCapabilities.ResourceLimitCategory} (0x{extendedHeader.ACI.ARM11LocalSystemCapabilities.ResourceLimitCategory:X})" ) ;
}
builder . AppendLine ( $" ARM11 kernel capabilities:" ) ;
if ( extendedHeader . ACI . ARM11KernelCapabilities = = null )
{
builder . AppendLine ( " [NULL]" ) ;
}
else
{
builder . AppendLine ( $" Descriptors: {(extendedHeader.ACI.ARM11KernelCapabilities.Descriptors == null ? " [ NULL ] " : string.Join(" , ", extendedHeader.ACI.ARM11KernelCapabilities.Descriptors))}" ) ;
builder . AppendLine ( $" Reserved: {(extendedHeader.ACI.ARM11KernelCapabilities.Reserved == null ? " [ NULL ] " : BitConverter.ToString(extendedHeader.ACI.ARM11KernelCapabilities.Reserved).Replace('-', ' '))}" ) ;
}
builder . AppendLine ( $" ARM9 access control:" ) ;
if ( extendedHeader . ACI . ARM9AccessControl = = null )
{
builder . AppendLine ( " [NULL]" ) ;
}
else
{
builder . AppendLine ( $" Descriptors: {(extendedHeader.ACI.ARM9AccessControl.Descriptors == null ? " [ NULL ] " : BitConverter.ToString(extendedHeader.ACI.ARM9AccessControl.Descriptors).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Descriptor version: {extendedHeader.ACI.ARM9AccessControl.DescriptorVersion} (0x{extendedHeader.ACI.ARM9AccessControl.DescriptorVersion:X})" ) ;
}
builder . AppendLine ( $" AccessDec signature (RSA-2048-SHA256): {(extendedHeader.AccessDescSignature == null ? " [ NULL ] " : BitConverter.ToString(extendedHeader.AccessDescSignature).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" NCCH HDR RSA-2048 public key: {(extendedHeader.NCCHHDRPublicKey == null ? " [ NULL ] " : BitConverter.ToString(extendedHeader.NCCHHDRPublicKey).Replace('-', ' '))}" ) ;
}
2023-01-13 14:04:21 -08:00
builder . AppendLine ( $" Access control info (for limitations of first ACI):" ) ;
2023-09-13 00:08:11 -04:00
if ( extendedHeader . ACIForLimitations = = null )
{
builder . AppendLine ( " [NULL]" ) ;
}
else
{
builder . AppendLine ( $" ARM11 local system capabilities:" ) ;
if ( extendedHeader . ACIForLimitations . ARM11LocalSystemCapabilities = = null )
{
builder . AppendLine ( " [NULL]" ) ;
}
else
{
builder . AppendLine ( $" Program ID: {extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ProgramID} (0x{extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ProgramID:X})" ) ;
builder . AppendLine ( $" Core version: {extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.CoreVersion} (0x{extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.CoreVersion:X})" ) ;
builder . AppendLine ( $" Flag 1: {extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.Flag1} (0x{extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.Flag1:X})" ) ;
builder . AppendLine ( $" Flag 2: {extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.Flag2} (0x{extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.Flag2:X})" ) ;
builder . AppendLine ( $" Flag 0: {extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.Flag0} (0x{extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.Flag0:X})" ) ;
builder . AppendLine ( $" Priority: {extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.Priority} (0x{extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.Priority:X})" ) ;
builder . AppendLine ( $" Resource limit descriptors: {(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ResourceLimitDescriptors == null ? " [ NULL ] " : string.Join(" , ", extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ResourceLimitDescriptors))}" ) ;
builder . AppendLine ( $" Storage info:" ) ;
if ( extendedHeader . ACIForLimitations . ARM11LocalSystemCapabilities . StorageInfo = = null )
{
builder . AppendLine ( " [NULL]" ) ;
}
else
{
builder . AppendLine ( $" Extdata ID: {extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.ExtdataID} (0x{extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.ExtdataID:X})" ) ;
builder . AppendLine ( $" System savedata IDs: {(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.SystemSavedataIDs == null ? " [ NULL ] " : BitConverter.ToString(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.SystemSavedataIDs).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Storage accessible unique IDs: {(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.StorageAccessibleUniqueIDs == null ? " [ NULL ] " : BitConverter.ToString(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.StorageAccessibleUniqueIDs).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" File system access info: {(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.FileSystemAccessInfo == null ? " [ NULL ] " : BitConverter.ToString(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.FileSystemAccessInfo).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Other attributes: {extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.OtherAttributes} (0x{extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.OtherAttributes:X})" ) ;
}
builder . AppendLine ( $" Service access control: {(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ServiceAccessControl == null ? " [ NULL ] " : string.Join(" , ", extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ServiceAccessControl))}" ) ;
builder . AppendLine ( $" Extended service access control: {(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ExtendedServiceAccessControl == null ? " [ NULL ] " : string.Join(" , ", extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ExtendedServiceAccessControl))}" ) ;
builder . AppendLine ( $" Reserved: {(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.Reserved == null ? " [ NULL ] " : BitConverter.ToString(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.Reserved).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Resource limit cateogry: {extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ResourceLimitCategory} (0x{extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ResourceLimitCategory:X})" ) ;
}
builder . AppendLine ( $" ARM11 kernel capabilities:" ) ;
if ( extendedHeader . ACIForLimitations . ARM11KernelCapabilities = = null )
{
builder . AppendLine ( " [NULL]" ) ;
}
else
{
builder . AppendLine ( $" Descriptors: {(extendedHeader.ACIForLimitations.ARM11KernelCapabilities.Descriptors == null ? " [ NULL ] " : string.Join(" , ", extendedHeader.ACIForLimitations.ARM11KernelCapabilities.Descriptors))}" ) ;
builder . AppendLine ( $" Reserved: {(extendedHeader.ACIForLimitations.ARM11KernelCapabilities.Reserved == null ? " [ NULL ] " : BitConverter.ToString(extendedHeader.ACIForLimitations.ARM11KernelCapabilities.Reserved).Replace('-', ' '))}" ) ;
}
builder . AppendLine ( $" ARM9 access control:" ) ;
if ( extendedHeader . ACIForLimitations . ARM9AccessControl = = null )
{
builder . AppendLine ( " [NULL]" ) ;
}
else
{
builder . AppendLine ( $" Descriptors: {(extendedHeader.ACIForLimitations.ARM9AccessControl.Descriptors == null ? " [ NULL ] " : BitConverter.ToString(extendedHeader.ACIForLimitations.ARM9AccessControl.Descriptors).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Descriptor version: {extendedHeader.ACIForLimitations.ARM9AccessControl.DescriptorVersion} (0x{extendedHeader.ACIForLimitations.ARM9AccessControl.DescriptorVersion:X})" ) ;
}
}
2023-01-07 22:33:55 -08:00
}
}
}
2023-01-13 14:04:21 -08:00
builder . AppendLine ( ) ;
2023-01-07 22:33:55 -08:00
}
2023-01-07 22:50:31 -08:00
/// <summary>
2023-01-07 23:09:26 -08:00
/// Print ExeFS header information
2023-01-07 22:50:31 -08:00
/// </summary>
2023-01-13 14:04:21 -08:00
/// <param name="builder">StringBuilder to append information to</param>
private void PrintExeFSHeaders ( StringBuilder builder )
2023-01-07 22:50:31 -08:00
{
2023-01-13 14:04:21 -08:00
builder . AppendLine ( " ExeFS Header Information:" ) ;
builder . AppendLine ( " -------------------------" ) ;
2023-01-07 22:50:31 -08:00
if ( ExeFSHeaders = = null | | ExeFSHeaders . Length = = 0 )
{
2023-01-13 14:04:21 -08:00
builder . AppendLine ( " No ExeFS headers" ) ;
2023-01-07 22:50:31 -08:00
}
else
{
for ( int i = 0 ; i < ExeFSHeaders . Length ; i + + )
{
var exeFSHeader = ExeFSHeaders [ i ] ;
2023-01-13 14:04:21 -08:00
builder . AppendLine ( $" ExeFS Header {i}" ) ;
2023-01-07 22:50:31 -08:00
if ( exeFSHeader = = null )
{
2023-01-13 14:04:21 -08:00
builder . AppendLine ( $" Unrecognized partition data, no data can be parsed" ) ;
2023-01-07 22:50:31 -08:00
}
else
{
2023-01-13 14:04:21 -08:00
builder . AppendLine ( $" File headers:" ) ;
2023-09-13 00:08:11 -04:00
if ( exeFSHeader . FileHeaders = = null | | exeFSHeader . FileHeaders . Length = = 0 )
2023-01-07 22:50:31 -08:00
{
2023-09-13 00:08:11 -04:00
builder . AppendLine ( " No file headers" ) ;
2023-01-07 22:50:31 -08:00
}
2023-09-13 00:08:11 -04:00
else
{
for ( int j = 0 ; j < exeFSHeader . FileHeaders . Length ; j + + )
{
var fileHeader = exeFSHeader . FileHeaders [ j ] ;
builder . AppendLine ( $" File Header {j}" ) ;
if ( fileHeader = = null )
{
builder . AppendLine ( " [NULL]" ) ;
continue ;
}
builder . AppendLine ( $" File name: {fileHeader.FileName}" ) ;
builder . AppendLine ( $" File offset: {fileHeader.FileOffset} (0x{fileHeader.FileOffset:X})" ) ;
builder . AppendLine ( $" File size: {fileHeader.FileSize} (0x{fileHeader.FileSize:X})" ) ;
}
}
builder . AppendLine ( $" Reserved: {(exeFSHeader.Reserved == null ? " [ NULL ] " : BitConverter.ToString(exeFSHeader.Reserved).Replace('-', ' '))}" ) ;
2023-01-07 22:50:31 -08:00
2023-01-13 14:04:21 -08:00
builder . AppendLine ( $" File hashes:" ) ;
2023-09-13 00:08:11 -04:00
if ( exeFSHeader . FileHashes = = null | | exeFSHeader . FileHashes . Length = = 0 )
{
builder . AppendLine ( " No file hashes" ) ;
}
else
2023-01-07 22:50:31 -08:00
{
2023-09-13 00:08:11 -04:00
for ( int j = 0 ; j < exeFSHeader . FileHashes . Length ; j + + )
{
var fileHash = exeFSHeader . FileHashes [ j ] ;
builder . AppendLine ( $" File Hash {j}" ) ;
if ( fileHash = = null )
{
builder . AppendLine ( " [NULL]" ) ;
continue ;
}
builder . AppendLine ( $" SHA-256: {(fileHash == null ? " [ NULL ] " : BitConverter.ToString(fileHash).Replace('-', ' '))}" ) ;
}
2023-01-07 22:50:31 -08:00
}
}
}
}
2023-01-13 14:04:21 -08:00
builder . AppendLine ( ) ;
2023-01-07 22:50:31 -08:00
}
2023-01-07 23:09:26 -08:00
/// <summary>
/// Print RomFS header information
/// </summary>
2023-01-13 14:04:21 -08:00
/// <param name="builder">StringBuilder to append information to</param>
private void PrintRomFSHeaders ( StringBuilder builder )
2023-01-07 23:09:26 -08:00
{
2023-01-13 14:04:21 -08:00
builder . AppendLine ( " RomFS Header Information:" ) ;
builder . AppendLine ( " -------------------------" ) ;
2023-01-07 23:09:26 -08:00
if ( RomFSHeaders = = null | | RomFSHeaders . Length = = 0 )
{
2023-01-13 14:04:21 -08:00
builder . AppendLine ( " No RomFS headers" ) ;
2023-01-07 23:09:26 -08:00
}
else
{
for ( int i = 0 ; i < RomFSHeaders . Length ; i + + )
{
var romFSHeader = RomFSHeaders [ i ] ;
2023-01-13 14:04:21 -08:00
builder . AppendLine ( $" RomFS Header {i}" ) ;
2023-01-07 23:09:26 -08:00
if ( romFSHeader = = null )
{
2023-01-13 14:04:21 -08:00
builder . AppendLine ( $" Unrecognized RomFS data, no data can be parsed" ) ;
2023-01-07 23:09:26 -08:00
}
else
{
2023-09-13 00:08:11 -04:00
builder . AppendLine ( $" Magic string: {romFSHeader.MagicString}" ) ;
builder . AppendLine ( $" Magic number: {romFSHeader.MagicNumber} (0x{romFSHeader.MagicNumber:X})" ) ;
builder . AppendLine ( $" Master hash size: {romFSHeader.MasterHashSize} (0x{romFSHeader.MasterHashSize:X})" ) ;
builder . AppendLine ( $" Level 1 logical offset: {romFSHeader.Level1LogicalOffset} (0x{romFSHeader.Level1LogicalOffset:X})" ) ;
builder . AppendLine ( $" Level 1 hashdata size: {romFSHeader.Level1HashdataSize} (0x{romFSHeader.Level1HashdataSize:X})" ) ;
builder . AppendLine ( $" Level 1 block size: {romFSHeader.Level1BlockSizeLog2} (0x{romFSHeader.Level1BlockSizeLog2:X})" ) ;
builder . AppendLine ( $" Reserved 1: {(romFSHeader.Reserved1 == null ? " [ NULL ] " : BitConverter.ToString(romFSHeader.Reserved1).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Level 2 logical offset: {romFSHeader.Level2LogicalOffset} (0x{romFSHeader.Level2LogicalOffset:X})" ) ;
builder . AppendLine ( $" Level 2 hashdata size: {romFSHeader.Level2HashdataSize} (0x{romFSHeader.Level2HashdataSize:X})" ) ;
builder . AppendLine ( $" Level 2 block size: {romFSHeader.Level2BlockSizeLog2} (0x{romFSHeader.Level2BlockSizeLog2:X})" ) ;
builder . AppendLine ( $" Reserved 2: {(romFSHeader.Reserved2 == null ? " [ NULL ] " : BitConverter.ToString(romFSHeader.Reserved2).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Level 3 logical offset: {romFSHeader.Level3LogicalOffset} (0x{romFSHeader.Level3LogicalOffset:X})" ) ;
builder . AppendLine ( $" Level 3 hashdata size: {romFSHeader.Level3HashdataSize} (0x{romFSHeader.Level3HashdataSize:X})" ) ;
builder . AppendLine ( $" Level 3 block size: {romFSHeader.Level3BlockSizeLog2} (0x{romFSHeader.Level3BlockSizeLog2:X})" ) ;
builder . AppendLine ( $" Reserved 3: {(romFSHeader.Reserved3 == null ? " [ NULL ] " : BitConverter.ToString(romFSHeader.Reserved3).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Reserved 4: {(romFSHeader.Reserved4 == null ? " [ NULL ] " : BitConverter.ToString(romFSHeader.Reserved4).Replace('-', ' '))}" ) ;
builder . AppendLine ( $" Optional info size: {romFSHeader.OptionalInfoSize} (0x{romFSHeader.OptionalInfoSize:X})" ) ;
2023-01-07 23:09:26 -08:00
}
}
}
2023-01-13 14:04:21 -08:00
builder . AppendLine ( ) ;
2023-01-07 23:09:26 -08:00
}
2023-01-13 10:41:50 -08:00
#if NET6_0_OR_GREATER
/// <inheritdoc/>
2023-09-11 23:25:09 -04:00
public override string ExportJSON ( ) = > System . Text . Json . JsonSerializer . Serialize ( _model , _jsonSerializerOptions ) ;
2023-01-13 10:41:50 -08:00
#endif
2023-01-07 12:33:15 -08:00
#endregion
}
}