mirror of
https://github.com/SabreTools/SabreTools.Models.git
synced 2026-09-23 15:16:14 +00:00
Add layouts for some N3DS models
This commit is contained in:
@@ -1,9 +1,12 @@
|
||||
namespace SabreTools.Models.N3DS
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SabreTools.Models.N3DS
|
||||
{
|
||||
/// <summary>
|
||||
/// The kernel capability descriptors are passed to svcCreateProcess.
|
||||
/// </summary>
|
||||
/// <see href="https://www.3dbrew.org/wiki/NCCH/Extended_Header#ARM11_Kernel_Capabilities"/>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public sealed class ARM11KernelCapabilities
|
||||
{
|
||||
/// <summary>
|
||||
@@ -34,11 +37,15 @@
|
||||
/// 13 Process has access to CPU core 2 (New3DS only)
|
||||
/// </summary>
|
||||
/// TODO: Make enum for flag values
|
||||
public uint[]? Descriptors { get; set; }
|
||||
/// <remarks>28 entries</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 28)]
|
||||
public uint[]? Descriptors;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
public byte[]? Reserved { get; set; }
|
||||
/// <remarks>0x10 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x10)]
|
||||
public byte[]? Reserved;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,66 +1,81 @@
|
||||
namespace SabreTools.Models.N3DS
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SabreTools.Models.N3DS
|
||||
{
|
||||
/// <see href="https://www.3dbrew.org/wiki/NCCH/Extended_Header#ARM11_Local_System_Capabilities"/>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public sealed class ARM11LocalSystemCapabilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Program ID
|
||||
/// </summary>
|
||||
public ulong ProgramID { get; set; }
|
||||
public ulong ProgramID;
|
||||
|
||||
/// <summary>
|
||||
/// Core version (The Title ID low of the required FIRM)
|
||||
/// </summary>
|
||||
public uint CoreVersion { get; set; }
|
||||
public uint CoreVersion;
|
||||
|
||||
/// <summary>
|
||||
/// Flag1 (implemented starting from 8.0.0-18).
|
||||
/// </summary>
|
||||
public ARM11LSCFlag1 Flag1 { get; set; }
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public ARM11LSCFlag1 Flag1;
|
||||
|
||||
/// <summary>
|
||||
/// Flag2 (implemented starting from 8.0.0-18).
|
||||
/// </summary>
|
||||
public ARM11LSCFlag2 Flag2 { get; set; }
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public ARM11LSCFlag2 Flag2;
|
||||
|
||||
/// <summary>
|
||||
/// Flag0
|
||||
/// </summary>
|
||||
public ARM11LSCFlag0 Flag0 { get; set; }
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public ARM11LSCFlag0 Flag0;
|
||||
|
||||
/// <summary>
|
||||
/// Priority
|
||||
/// </summary>
|
||||
public byte Priority { get; set; }
|
||||
public byte Priority;
|
||||
|
||||
/// <summary>
|
||||
/// Resource limit descriptors. The first byte here controls the maximum allowed CpuTime.
|
||||
/// </summary>
|
||||
public ushort[]? ResourceLimitDescriptors { get; set; }
|
||||
/// <remarks>16 entries</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
|
||||
public ushort[]? ResourceLimitDescriptors;
|
||||
|
||||
/// <summary>
|
||||
/// Storage info
|
||||
/// </summary>
|
||||
public StorageInfo? StorageInfo { get; set; }
|
||||
public StorageInfo? StorageInfo;
|
||||
|
||||
/// <summary>
|
||||
/// Service access control
|
||||
/// </summary>
|
||||
public ulong[]? ServiceAccessControl { get; set; }
|
||||
/// <remarks>32 entries</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
|
||||
public ulong[]? ServiceAccessControl;
|
||||
|
||||
/// <summary>
|
||||
/// Extended service access control, support for this was implemented with 9.3.0-X.
|
||||
/// </summary>
|
||||
public ulong[]? ExtendedServiceAccessControl { get; set; }
|
||||
/// <remarks>2 entries</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
|
||||
public ulong[]? ExtendedServiceAccessControl;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
public byte[]? Reserved { get; set; }
|
||||
/// <remarks>0x0F bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x0F)]
|
||||
public byte[]? Reserved;
|
||||
|
||||
/// <summary>
|
||||
/// Resource limit category. (0 = APPLICATION, 1 = SYS_APPLET, 2 = LIB_APPLET, 3 = OTHER (sysmodules running under the BASE memregion))
|
||||
/// </summary>
|
||||
public ResourceLimitCategory ResourceLimitCategory { get; set; }
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public ResourceLimitCategory ResourceLimitCategory;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,22 @@
|
||||
namespace SabreTools.Models.N3DS
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SabreTools.Models.N3DS
|
||||
{
|
||||
/// <see href="https://www.3dbrew.org/wiki/NCCH/Extended_Header#ARM9_Access_Control"/>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public sealed class ARM9AccessControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Descriptors
|
||||
/// </summary>
|
||||
public byte[]? Descriptors { get; set; }
|
||||
/// <remarks>15 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 15)]
|
||||
public byte[]? Descriptors;
|
||||
|
||||
/// <summary>
|
||||
/// ARM9 Descriptor Version. Originally this value had to be ≥ 2.
|
||||
/// Starting with 9.3.0-X this value has to be either value 2 or value 3.
|
||||
/// </summary>
|
||||
public byte DescriptorVersion { get; set; }
|
||||
public byte DescriptorVersion;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,24 @@
|
||||
namespace SabreTools.Models.N3DS
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SabreTools.Models.N3DS
|
||||
{
|
||||
/// <see href="https://www.3dbrew.org/wiki/NCCH/Extended_Header#Access_Control_Info"/>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public sealed class AccessControlInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// ARM11 local system capabilities
|
||||
/// </summary>
|
||||
public ARM11LocalSystemCapabilities? ARM11LocalSystemCapabilities { get; set; }
|
||||
public ARM11LocalSystemCapabilities? ARM11LocalSystemCapabilities;
|
||||
|
||||
/// <summary>
|
||||
/// ARM11 kernel capabilities
|
||||
/// </summary>
|
||||
public ARM11KernelCapabilities? ARM11KernelCapabilities { get; set; }
|
||||
public ARM11KernelCapabilities? ARM11KernelCapabilities;
|
||||
|
||||
/// <summary>
|
||||
/// ARM9 access control
|
||||
/// </summary>
|
||||
public ARM9AccessControl? ARM9AccessControl { get; set; }
|
||||
public ARM9AccessControl? ARM9AccessControl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,51 +1,56 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SabreTools.Models.N3DS
|
||||
{
|
||||
/// <see href="https://www.3dbrew.org/wiki/CIA#CIA_Header"/>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public sealed class CIAHeader
|
||||
{
|
||||
/// <summary>
|
||||
/// Archive header size, usually 0x2020 bytes
|
||||
/// </summary>
|
||||
public uint HeaderSize { get; set; }
|
||||
public uint HeaderSize;
|
||||
|
||||
/// <summary>
|
||||
/// Type
|
||||
/// </summary>
|
||||
public ushort Type { get; set; }
|
||||
public ushort Type;
|
||||
|
||||
/// <summary>
|
||||
/// Version
|
||||
/// </summary>
|
||||
public ushort Version { get; set; }
|
||||
public ushort Version;
|
||||
|
||||
/// <summary>
|
||||
/// Certificate chain size
|
||||
/// </summary>
|
||||
public uint CertificateChainSize { get; set; }
|
||||
public uint CertificateChainSize;
|
||||
|
||||
/// <summary>
|
||||
/// Ticket size
|
||||
/// </summary>
|
||||
public uint TicketSize { get; set; }
|
||||
public uint TicketSize;
|
||||
|
||||
/// <summary>
|
||||
/// TMD file size
|
||||
/// </summary>
|
||||
public uint TMDFileSize { get; set; }
|
||||
public uint TMDFileSize;
|
||||
|
||||
/// <summary>
|
||||
/// Meta size (0 if no Meta data is present)
|
||||
/// </summary>
|
||||
public uint MetaSize { get; set; }
|
||||
public uint MetaSize;
|
||||
|
||||
/// <summary>
|
||||
/// Content size
|
||||
/// </summary>
|
||||
public ulong ContentSize { get; set; }
|
||||
public ulong ContentSize;
|
||||
|
||||
/// <summary>
|
||||
/// Content Index
|
||||
/// </summary>
|
||||
public byte[]? ContentIndex { get; set; }
|
||||
/// <remarks>0x2000 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x2000)]
|
||||
public byte[]? ContentIndex;
|
||||
}
|
||||
}
|
||||
@@ -1,61 +1,74 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SabreTools.Models.N3DS
|
||||
{
|
||||
/// <see href="https://www.3dbrew.org/wiki/NCSD#Card_Info_Header"/>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public sealed class CardInfoHeader
|
||||
{
|
||||
/// <summary>
|
||||
/// CARD2: Writable Address In Media Units (For 'On-Chip' Savedata). CARD1: Always 0xFFFFFFFF.
|
||||
/// </summary>
|
||||
public uint WritableAddressMediaUnits { get; set; }
|
||||
public uint WritableAddressMediaUnits;
|
||||
|
||||
/// <summary>
|
||||
/// Card Info Bitmask
|
||||
/// </summary>
|
||||
public uint CardInfoBitmask { get; set; }
|
||||
public uint CardInfoBitmask;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
public byte[]? Reserved1 { get; set; }
|
||||
/// <remarks>0xF8 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0xF8)]
|
||||
public byte[]? Reserved1;
|
||||
|
||||
/// <summary>
|
||||
/// Filled size of cartridge
|
||||
/// </summary>
|
||||
public uint FilledSize { get; set; }
|
||||
public uint FilledSize;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
public byte[]? Reserved2 { get; set; }
|
||||
/// <remarks>0x0C bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x0C)]
|
||||
public byte[]? Reserved2;
|
||||
|
||||
/// <summary>
|
||||
/// Title version
|
||||
/// </summary>
|
||||
public ushort TitleVersion { get; set; }
|
||||
public ushort TitleVersion;
|
||||
|
||||
/// <summary>
|
||||
/// Card revision
|
||||
/// </summary>
|
||||
public ushort CardRevision { get; set; }
|
||||
public ushort CardRevision;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
public byte[]? Reserved3 { get; set; }
|
||||
/// <remarks>0x0C bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x0C)]
|
||||
public byte[]? Reserved3;
|
||||
|
||||
/// <summary>
|
||||
/// Title ID of CVer in included update partition
|
||||
/// </summary>
|
||||
public byte[]? CVerTitleID { get; set; }
|
||||
/// <remarks>8 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public byte[]? CVerTitleID;
|
||||
|
||||
/// <summary>
|
||||
/// Version number of CVer in included update partition
|
||||
/// </summary>
|
||||
public ushort CVerVersionNumber { get; set; }
|
||||
public ushort CVerVersionNumber;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
public byte[]? Reserved4 { get; set; }
|
||||
/// <remarks>0xCD6 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0xCD6)]
|
||||
public byte[]? Reserved4;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,24 @@
|
||||
namespace SabreTools.Models.N3DS
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SabreTools.Models.N3DS
|
||||
{
|
||||
/// <see href="https://www.3dbrew.org/wiki/NCCH/Extended_Header#Code_Set_Info"/>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public sealed class CodeSetInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Address
|
||||
/// </summary>
|
||||
public uint Address { get; set; }
|
||||
public uint Address;
|
||||
|
||||
/// <summary>
|
||||
/// Physical region size (in page-multiples)
|
||||
/// </summary>
|
||||
public uint PhysicalRegionSizeInPages { get; set; }
|
||||
public uint PhysicalRegionSizeInPages;
|
||||
|
||||
/// <summary>
|
||||
/// Size (in bytes)
|
||||
/// </summary>
|
||||
public uint SizeInBytes { get; set; }
|
||||
public uint SizeInBytes;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SabreTools.Models.N3DS
|
||||
{
|
||||
/// <summary>
|
||||
@@ -5,12 +7,13 @@ namespace SabreTools.Models.N3DS
|
||||
/// (Determined by "Content Count" in the TMD Header).
|
||||
/// </summary>
|
||||
/// <see href="https://www.3dbrew.org/wiki/Title_metadata#Content_chunk_records"/>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public sealed class ContentChunkRecord
|
||||
{
|
||||
/// <summary>
|
||||
/// Content id
|
||||
/// </summary>
|
||||
public uint ContentId { get; set; }
|
||||
public uint ContentId;
|
||||
|
||||
/// <summary>
|
||||
/// Content index
|
||||
@@ -18,21 +21,23 @@ namespace SabreTools.Models.N3DS
|
||||
/// <remarks>
|
||||
/// This does not apply to DLC.
|
||||
/// </remarks>
|
||||
public ContentIndex ContentIndex { get; set; }
|
||||
public ContentIndex ContentIndex;
|
||||
|
||||
/// <summary>
|
||||
/// Content type
|
||||
/// </summary>
|
||||
public TMDContentType ContentType { get; set; }
|
||||
public TMDContentType ContentType;
|
||||
|
||||
/// <summary>
|
||||
/// Content size
|
||||
/// </summary>
|
||||
public ulong ContentSize { get; set; }
|
||||
public ulong ContentSize;
|
||||
|
||||
/// <summary>
|
||||
/// SHA-256 hash
|
||||
/// </summary>
|
||||
public byte[]? SHA256Hash { get; set; }
|
||||
/// <remarks>0x20 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)]
|
||||
public byte[]? SHA256Hash;
|
||||
}
|
||||
}
|
||||
@@ -1,24 +1,29 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SabreTools.Models.N3DS
|
||||
{
|
||||
/// <summary>
|
||||
/// There are 64 of these records, usually only the first is used.
|
||||
/// </summary>
|
||||
/// <see href="https://www.3dbrew.org/wiki/Title_metadata#Content_Info_Records"/>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public sealed class ContentInfoRecord
|
||||
{
|
||||
/// <summary>
|
||||
/// Content index offset
|
||||
/// </summary>
|
||||
public ushort ContentIndexOffset { get; set; }
|
||||
public ushort ContentIndexOffset;
|
||||
|
||||
/// <summary>
|
||||
/// Content command count [k]
|
||||
/// </summary>
|
||||
public ushort ContentCommandCount { get; set; }
|
||||
public ushort ContentCommandCount;
|
||||
|
||||
/// <summary>
|
||||
/// SHA-256 hash of the next k content records that have not been hashed yet
|
||||
/// </summary>
|
||||
public byte[]? UnhashedContentRecordsSHA256Hash { get; set; }
|
||||
/// <remarks>0x20 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)]
|
||||
public byte[]? UnhashedContentRecordsSHA256Hash;
|
||||
}
|
||||
}
|
||||
@@ -1,31 +1,40 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SabreTools.Models.N3DS
|
||||
{
|
||||
/// <see href="https://www.3dbrew.org/wiki/NCSD#Development_Card_Info_Header_Extension"/>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public sealed class DevelopmentCardInfoHeader
|
||||
{
|
||||
/// <summary>
|
||||
/// InitialData
|
||||
/// </summary>
|
||||
public InitialData? InitialData { get; set; }
|
||||
public InitialData? InitialData;
|
||||
|
||||
/// <summary>
|
||||
/// CardDeviceReserved1
|
||||
/// </summary>
|
||||
public byte[]? CardDeviceReserved1 { get; set; }
|
||||
/// <remarks>0x200 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x200)]
|
||||
public byte[]? CardDeviceReserved1;
|
||||
|
||||
/// <summary>
|
||||
/// TitleKey
|
||||
/// </summary>
|
||||
public byte[]? TitleKey { get; set; }
|
||||
/// <remarks>0x10 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x10)]
|
||||
public byte[]? TitleKey;
|
||||
|
||||
/// <summary>
|
||||
/// CardDeviceReserved2
|
||||
/// </summary>
|
||||
public byte[]? CardDeviceReserved2 { get; set; }
|
||||
/// <remarks>0x1BF0 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x1BF0)]
|
||||
public byte[]? CardDeviceReserved2;
|
||||
|
||||
/// <summary>
|
||||
/// TestData
|
||||
/// </summary>
|
||||
public TestData? TestData { get; set; }
|
||||
public TestData? TestData;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
namespace SabreTools.Models.N3DS
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SabreTools.Models.N3DS
|
||||
{
|
||||
/// <summary>
|
||||
/// There are a maximum of 10 file headers in the ExeFS format. (This maximum
|
||||
@@ -8,26 +10,24 @@
|
||||
/// the currently define size of 0x200 bytes.)
|
||||
/// </summary>
|
||||
/// <see href="https://www.3dbrew.org/wiki/ExeFS#File_headers"/>
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
||||
public sealed class ExeFSFileHeader
|
||||
{
|
||||
/// <summary>
|
||||
/// File name
|
||||
/// </summary>
|
||||
public string? FileName { get; set; }
|
||||
/// <remarks>8 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
|
||||
public string? FileName;
|
||||
|
||||
/// <summary>
|
||||
/// File offset
|
||||
/// </summary>
|
||||
public uint FileOffset { get; set; }
|
||||
public uint FileOffset;
|
||||
|
||||
/// <summary>
|
||||
/// File size
|
||||
/// </summary>
|
||||
public uint FileSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// SHA256 hash calculated over the entire file contents
|
||||
/// </summary>
|
||||
public byte[]? FileHash { get; set; }
|
||||
public uint FileSize;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
/// <remarks>0x20 bytes</remarks>
|
||||
public byte[]? Reserved { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,36 +1,49 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SabreTools.Models.N3DS
|
||||
{
|
||||
/// <see href="https://www.3dbrew.org/wiki/NCSD#InitialData"/>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public sealed class InitialData
|
||||
{
|
||||
/// <summary>
|
||||
/// Card seed keyY (first u64 is Media ID (same as first NCCH partitionId))
|
||||
/// </summary>
|
||||
public byte[]? CardSeedKeyY { get; set; }
|
||||
/// <remarks>0x10 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x10)]
|
||||
public byte[]? CardSeedKeyY;
|
||||
|
||||
/// <summary>
|
||||
/// Encrypted card seed (AES-CCM, keyslot 0x3B for retail cards, see CTRCARD_SECSEED)
|
||||
/// </summary>
|
||||
public byte[]? EncryptedCardSeed { get; set; }
|
||||
/// <remarks>0x10 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x10)]
|
||||
public byte[]? EncryptedCardSeed;
|
||||
|
||||
/// <summary>
|
||||
/// Card seed AES-MAC
|
||||
/// </summary>
|
||||
public byte[]? CardSeedAESMAC { get; set; }
|
||||
/// <remarks>0x10 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x10)]
|
||||
public byte[]? CardSeedAESMAC;
|
||||
|
||||
/// <summary>
|
||||
/// Card seed nonce
|
||||
/// </summary>
|
||||
public byte[]? CardSeedNonce { get; set; }
|
||||
/// <remarks>0x0C bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x0C)]
|
||||
public byte[]? CardSeedNonce;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved3
|
||||
/// </summary>
|
||||
public byte[]? Reserved { get; set; }
|
||||
/// <remarks>0xC4 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0xC4)]
|
||||
public byte[]? Reserved;
|
||||
|
||||
/// <summary>
|
||||
/// Copy of first NCCH header (excluding RSA signature)
|
||||
/// </summary>
|
||||
public NCCHHeader? BackupHeader { get; set; }
|
||||
public NCCHHeader? BackupHeader;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,32 +1,43 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SabreTools.Models.N3DS
|
||||
{
|
||||
/// <see href="https://www.3dbrew.org/wiki/CIA#Meta"/>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public sealed class MetaData
|
||||
{
|
||||
/// <summary>
|
||||
/// Title ID dependency list - Taken from the application's ExHeader
|
||||
/// </summary>
|
||||
/// TODO: Determine numeric format of each entry
|
||||
public byte[]? TitleIDDependencyList { get; set; }
|
||||
/// <remarks>0x180 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x180)]
|
||||
public byte[]? TitleIDDependencyList;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
public byte[]? Reserved1 { get; set; }
|
||||
/// <remarks>0x180 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x180)]
|
||||
public byte[]? Reserved1;
|
||||
|
||||
/// <summary>
|
||||
/// Core Version
|
||||
/// </summary>
|
||||
public uint CoreVersion { get; set; }
|
||||
public uint CoreVersion;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
public byte[]? Reserved2 { get; set; }
|
||||
/// <remarks>0xFC bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0xFC)]
|
||||
public byte[]? Reserved2;
|
||||
|
||||
/// <summary>
|
||||
/// Icon Data(.ICN) - Taken from the application's ExeFS
|
||||
/// </summary>
|
||||
public byte[]? IconData { get; set; }
|
||||
/// <remarks>0x36C0 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x36C0)]
|
||||
public byte[]? IconData;
|
||||
}
|
||||
}
|
||||
@@ -1,36 +1,43 @@
|
||||
namespace SabreTools.Models.N3DS
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SabreTools.Models.N3DS
|
||||
{
|
||||
/// <summary>
|
||||
/// The exheader has two sections:
|
||||
/// - The actual exheader data, containing System Control Info (SCI) and Access Control Info (ACI) { get; set; }
|
||||
/// - The actual exheader data, containing System Control Info (SCI) and Access Control Info (ACI);
|
||||
/// - A signed copy of NCCH HDR public key, and exheader ACI. This version of the ACI is used as limitation to the actual ACI.
|
||||
/// </summary>
|
||||
/// <see href="https://www.3dbrew.org/wiki/NCCH/Extended_Header"/>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public sealed class NCCHExtendedHeader
|
||||
{
|
||||
/// <summary>
|
||||
/// SCI
|
||||
/// </summary>
|
||||
public SystemControlInfo? SCI { get; set; }
|
||||
public SystemControlInfo? SCI;
|
||||
|
||||
/// <summary>
|
||||
/// ACI
|
||||
/// </summary>
|
||||
public AccessControlInfo? ACI { get; set; }
|
||||
public AccessControlInfo? ACI;
|
||||
|
||||
/// <summary>
|
||||
/// AccessDesc signature (RSA-2048-SHA256)
|
||||
/// </summary>
|
||||
public byte[]? AccessDescSignature { get; set; }
|
||||
/// <remarks>0x100 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x100)]
|
||||
public byte[]? AccessDescSignature;
|
||||
|
||||
/// <summary>
|
||||
/// NCCH HDR RSA-2048 public key
|
||||
/// </summary>
|
||||
public byte[]? NCCHHDRPublicKey { get; set; }
|
||||
/// <remarks>0x100 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x100)]
|
||||
public byte[]? NCCHHDRPublicKey;
|
||||
|
||||
/// <summary>
|
||||
/// ACI (for limitation of first ACI)
|
||||
/// </summary>
|
||||
public AccessControlInfo? ACIForLimitations { get; set; }
|
||||
public AccessControlInfo? ACIForLimitations;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +1,44 @@
|
||||
namespace SabreTools.Models.N3DS
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SabreTools.Models.N3DS
|
||||
{
|
||||
/// <see href="https://www.3dbrew.org/wiki/NCCH#NCCH_Header"/>
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
||||
public sealed class NCCHHeader
|
||||
{
|
||||
/// <summary>
|
||||
/// RSA-2048 signature of the NCCH header, using SHA-256.
|
||||
/// </summary>
|
||||
public byte[]? RSA2048Signature { get; set; }
|
||||
/// <remarks>0x100 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x100)]
|
||||
public byte[]? RSA2048Signature;
|
||||
|
||||
/// <summary>
|
||||
/// Magic ID, always 'NCCH'
|
||||
/// </summary>
|
||||
public string? MagicID { get; set; }
|
||||
/// <remarks>4 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]
|
||||
public string? MagicID;
|
||||
|
||||
/// <summary>
|
||||
/// Content size, in media units (1 media unit = 0x200 bytes)
|
||||
/// </summary>
|
||||
public uint ContentSizeInMediaUnits { get; set; }
|
||||
public uint ContentSizeInMediaUnits;
|
||||
|
||||
/// <summary>
|
||||
/// Partition ID
|
||||
/// </summary>
|
||||
public ulong PartitionId { get; set; }
|
||||
public ulong PartitionId;
|
||||
|
||||
/// <summary>
|
||||
/// Maker code
|
||||
/// </summary>
|
||||
public ushort MakerCode { get; set; }
|
||||
public ushort MakerCode;
|
||||
|
||||
/// <summary>
|
||||
/// Version
|
||||
/// </summary>
|
||||
public ushort Version { get; set; }
|
||||
public ushort Version;
|
||||
|
||||
/// <summary>
|
||||
/// When ncchflag[7] = 0x20 starting with FIRM 9.6.0-X, this is compared with the first output u32 from a
|
||||
@@ -39,118 +46,132 @@
|
||||
/// [programID from NCCH + 0x118]. This hash is only used for verification of the content lock seed, and
|
||||
/// is not the actual keyY.
|
||||
/// </summary>
|
||||
public uint VerificationHash { get; set; }
|
||||
public uint VerificationHash;
|
||||
|
||||
/// <summary>
|
||||
/// Program ID
|
||||
/// </summary>
|
||||
public byte[]? ProgramId { get; set; }
|
||||
/// <remarks>8 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public byte[]? ProgramId;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
public byte[]? Reserved1 { get; set; }
|
||||
/// <remarks>0x10 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x10)]
|
||||
public byte[]? Reserved1;
|
||||
|
||||
/// <summary>
|
||||
/// Logo Region SHA-256 hash. (For applications built with SDK 5+) (Supported from firmware: 5.0.0-11)
|
||||
/// </summary>
|
||||
public byte[]? LogoRegionHash { get; set; }
|
||||
/// <remarks>0x20 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)]
|
||||
public byte[]? LogoRegionHash;
|
||||
|
||||
/// <summary>
|
||||
/// Product code
|
||||
/// </summary>
|
||||
public string? ProductCode { get; set; }
|
||||
/// <remarks>0x10 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x10)]
|
||||
public string? ProductCode;
|
||||
|
||||
/// <summary>
|
||||
/// Extended header SHA-256 hash (SHA256 of 2x Alignment Size, beginning at 0x0 of ExHeader)
|
||||
/// </summary>
|
||||
public byte[]? ExtendedHeaderHash { get; set; }
|
||||
/// <remarks>0x20 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)]
|
||||
public byte[]? ExtendedHeaderHash;
|
||||
|
||||
/// <summary>
|
||||
/// Extended header size, in bytes
|
||||
/// </summary>
|
||||
public uint ExtendedHeaderSizeInBytes { get; set; }
|
||||
public uint ExtendedHeaderSizeInBytes;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
public byte[]? Reserved2 { get; set; }
|
||||
public uint Reserved2;
|
||||
|
||||
/// <summary>
|
||||
/// Flags
|
||||
/// </summary>
|
||||
public NCCHHeaderFlags? Flags { get; set; }
|
||||
public NCCHHeaderFlags? Flags;
|
||||
|
||||
/// <summary>
|
||||
/// Plain region offset, in media units
|
||||
/// </summary>
|
||||
public uint PlainRegionOffsetInMediaUnits { get; set; }
|
||||
public uint PlainRegionOffsetInMediaUnits;
|
||||
|
||||
/// <summary>
|
||||
/// Plain region size, in media units
|
||||
/// </summary>
|
||||
public uint PlainRegionSizeInMediaUnits { get; set; }
|
||||
public uint PlainRegionSizeInMediaUnits;
|
||||
|
||||
/// <summary>
|
||||
/// Logo Region offset, in media units (For applications built with SDK 5+) (Supported from firmware: 5.0.0-11)
|
||||
/// </summary>
|
||||
public uint LogoRegionOffsetInMediaUnits { get; set; }
|
||||
public uint LogoRegionOffsetInMediaUnits;
|
||||
|
||||
/// <summary>
|
||||
/// Logo Region size, in media units (For applications built with SDK 5+) (Supported from firmware: 5.0.0-11)
|
||||
/// </summary>
|
||||
public uint LogoRegionSizeInMediaUnits { get; set; }
|
||||
public uint LogoRegionSizeInMediaUnits;
|
||||
|
||||
/// <summary>
|
||||
/// ExeFS offset, in media units
|
||||
/// </summary>
|
||||
public uint ExeFSOffsetInMediaUnits { get; set; }
|
||||
public uint ExeFSOffsetInMediaUnits;
|
||||
|
||||
/// <summary>
|
||||
/// ExeFS size, in media units
|
||||
/// </summary>
|
||||
public uint ExeFSSizeInMediaUnits { get; set; }
|
||||
public uint ExeFSSizeInMediaUnits;
|
||||
|
||||
/// <summary>
|
||||
/// ExeFS hash region size, in media units
|
||||
/// </summary>
|
||||
public uint ExeFSHashRegionSizeInMediaUnits { get; set; }
|
||||
public uint ExeFSHashRegionSizeInMediaUnits;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
public byte[]? Reserved3 { get; set; }
|
||||
public uint Reserved3;
|
||||
|
||||
/// <summary>
|
||||
/// RomFS offset, in media units
|
||||
/// </summary>
|
||||
public uint RomFSOffsetInMediaUnits { get; set; }
|
||||
public uint RomFSOffsetInMediaUnits;
|
||||
|
||||
/// <summary>
|
||||
/// RomFS size, in media units
|
||||
/// </summary>
|
||||
public uint RomFSSizeInMediaUnits { get; set; }
|
||||
public uint RomFSSizeInMediaUnits;
|
||||
|
||||
/// <summary>
|
||||
/// RomFS hash region size, in media units
|
||||
/// </summary>
|
||||
public uint RomFSHashRegionSizeInMediaUnits { get; set; }
|
||||
public uint RomFSHashRegionSizeInMediaUnits;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
public byte[]? Reserved4 { get; set; }
|
||||
public uint Reserved4;
|
||||
|
||||
/// <summary>
|
||||
/// ExeFS superblock SHA-256 hash - (SHA-256 hash, starting at 0x0 of the ExeFS over the number of
|
||||
/// media units specified in the ExeFS hash region size)
|
||||
/// </summary>
|
||||
public byte[]? ExeFSSuperblockHash { get; set; }
|
||||
/// <remarks>0x20 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)]
|
||||
public byte[]? ExeFSSuperblockHash;
|
||||
|
||||
/// <summary>
|
||||
/// RomFS superblock SHA-256 hash - (SHA-256 hash, starting at 0x0 of the RomFS over the number
|
||||
/// of media units specified in the RomFS hash region size)
|
||||
/// </summary>
|
||||
public byte[]? RomFSSuperblockHash { get; set; }
|
||||
/// <remarks>0x20 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)]
|
||||
public byte[]? RomFSSuperblockHash;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,49 +1,56 @@
|
||||
namespace SabreTools.Models.N3DS
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SabreTools.Models.N3DS
|
||||
{
|
||||
/// <see href="https://www.3dbrew.org/wiki/NCCH#NCCH_Flags"/>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public sealed class NCCHHeaderFlags
|
||||
{
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
public byte Reserved0 { get; set; }
|
||||
public byte Reserved0;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
public byte Reserved1 { get; set; }
|
||||
public byte Reserved1;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
public byte Reserved2 { get; set; }
|
||||
public byte Reserved2;
|
||||
|
||||
/// <summary>
|
||||
/// Crypto Method: When this is non-zero, a NCCH crypto method using two keyslots is used.
|
||||
/// </summary>
|
||||
public CryptoMethod CryptoMethod { get; set; }
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public CryptoMethod CryptoMethod;
|
||||
|
||||
/// <summary>
|
||||
/// Content Platform: 1 = CTR, 2 = snake (New 3DS).
|
||||
/// </summary>
|
||||
public ContentPlatform ContentPlatform { get; set; }
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public ContentPlatform ContentPlatform;
|
||||
|
||||
/// <summary>
|
||||
/// Content Type Bit-masks: Data = 0x1, Executable = 0x2, SystemUpdate = 0x4, Manual = 0x8,
|
||||
/// Child = (0x4|0x8), Trial = 0x10. When 'Data' is set, but not 'Executable', NCCH is a CFA.
|
||||
/// Otherwise when 'Executable' is set, NCCH is a CXI.
|
||||
/// </summary>
|
||||
public ContentType MediaPlatformIndex { get; set; }
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public ContentType MediaPlatformIndex;
|
||||
|
||||
/// <summary>
|
||||
/// Content Unit Size i.e. u32 ContentUnitSize = 0x200*2^flags[6] { get; set; }
|
||||
/// Content Unit Size i.e. u32 ContentUnitSize = 0x200*2^flags[6];
|
||||
/// </summary>
|
||||
public byte ContentUnitSize { get; set; }
|
||||
public byte ContentUnitSize;
|
||||
|
||||
/// <summary>
|
||||
/// Bit-masks: FixedCryptoKey = 0x1, NoMountRomFs = 0x2, NoCrypto = 0x4, using a new keyY
|
||||
/// generator = 0x20(starting with FIRM 9.6.0-X).
|
||||
/// </summary>
|
||||
public BitMasks BitMasks { get; set; }
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public BitMasks BitMasks;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
namespace SabreTools.Models.N3DS
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SabreTools.Models.N3DS
|
||||
{
|
||||
/// <summary>
|
||||
/// Offset and Length partition table, in media units
|
||||
/// </summary>
|
||||
/// <see href="https://www.3dbrew.org/wiki/NCSD#NCSD_header"/>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public sealed class PartitionTableEntry
|
||||
{
|
||||
/// <summary>
|
||||
/// Offset
|
||||
/// </summary>
|
||||
public uint Offset { get; set; }
|
||||
public uint Offset;
|
||||
|
||||
/// <summary>
|
||||
/// Length
|
||||
/// </summary>
|
||||
public uint Length { get; set; }
|
||||
public uint Length;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
namespace SabreTools.Models.N3DS
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SabreTools.Models.N3DS
|
||||
{
|
||||
/// <summary>
|
||||
/// RomFS (or Read-Only Filesystem) is part of the NCCH format, and is
|
||||
@@ -6,91 +8,94 @@
|
||||
/// </summary>
|
||||
/// <see href="https://www.3dbrew.org/wiki/RomFS"/>
|
||||
/// TODO: Implement the other parts of the RomFS tree structure
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
||||
public sealed class RomFSHeader
|
||||
{
|
||||
/// <summary>
|
||||
/// Magic "IVFC"
|
||||
/// </summary>
|
||||
public string? MagicString { get; set; }
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]
|
||||
public string? MagicString;
|
||||
|
||||
/// <summary>
|
||||
/// Magic number 0x10000
|
||||
/// </summary>
|
||||
public uint MagicNumber { get; set; }
|
||||
public uint MagicNumber;
|
||||
|
||||
/// <summary>
|
||||
/// Master hash size
|
||||
/// </summary>
|
||||
public uint MasterHashSize { get; set; }
|
||||
public uint MasterHashSize;
|
||||
|
||||
/// <summary>
|
||||
/// Level 1 logical offset
|
||||
/// </summary>
|
||||
public ulong Level1LogicalOffset { get; set; }
|
||||
public ulong Level1LogicalOffset;
|
||||
|
||||
/// <summary>
|
||||
/// Level 1 hashdata size
|
||||
/// </summary>
|
||||
public ulong Level1HashdataSize { get; set; }
|
||||
public ulong Level1HashdataSize;
|
||||
|
||||
/// <summary>
|
||||
/// Level 1 block size, in log2
|
||||
/// </summary>
|
||||
public uint Level1BlockSizeLog2 { get; set; }
|
||||
public uint Level1BlockSizeLog2;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
public byte[]? Reserved1 { get; set; }
|
||||
public uint Reserved1;
|
||||
|
||||
/// <summary>
|
||||
/// Level 2 logical offset
|
||||
/// </summary>
|
||||
public ulong Level2LogicalOffset { get; set; }
|
||||
public ulong Level2LogicalOffset;
|
||||
|
||||
/// <summary>
|
||||
/// Level 2 hashdata size
|
||||
/// </summary>
|
||||
public ulong Level2HashdataSize { get; set; }
|
||||
public ulong Level2HashdataSize;
|
||||
|
||||
/// <summary>
|
||||
/// Level 2 block size, in log2
|
||||
/// </summary>
|
||||
public uint Level2BlockSizeLog2 { get; set; }
|
||||
public uint Level2BlockSizeLog2;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
public byte[]? Reserved2 { get; set; }
|
||||
public uint Reserved2;
|
||||
|
||||
/// <summary>
|
||||
/// Level 3 logical offset
|
||||
/// </summary>
|
||||
public ulong Level3LogicalOffset { get; set; }
|
||||
public ulong Level3LogicalOffset;
|
||||
|
||||
/// <summary>
|
||||
/// Level 3 hashdata size
|
||||
/// </summary>
|
||||
public ulong Level3HashdataSize { get; set; }
|
||||
public ulong Level3HashdataSize;
|
||||
|
||||
/// <summary>
|
||||
/// Level 3 block size, in log2
|
||||
/// </summary>
|
||||
public uint Level3BlockSizeLog2 { get; set; }
|
||||
public uint Level3BlockSizeLog2;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
public byte[]? Reserved3 { get; set; }
|
||||
public uint Reserved3;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
public byte[]? Reserved4 { get; set; }
|
||||
public uint Reserved4;
|
||||
|
||||
/// <summary>
|
||||
/// Optional info size.
|
||||
/// </summary>
|
||||
public uint OptionalInfoSize { get; set; }
|
||||
public uint OptionalInfoSize;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +1,46 @@
|
||||
namespace SabreTools.Models.N3DS
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SabreTools.Models.N3DS
|
||||
{
|
||||
/// <summary>
|
||||
/// Used in FSReg:Register.
|
||||
/// </summary>
|
||||
/// <see href="https://www.3dbrew.org/wiki/NCCH/Extended_Header#Storage_Info"/>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public sealed class StorageInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Extdata ID
|
||||
/// </summary>
|
||||
public ulong ExtdataID { get; set; }
|
||||
public ulong ExtdataID;
|
||||
|
||||
/// <summary>
|
||||
/// System savedata IDs
|
||||
/// </summary>
|
||||
public byte[]? SystemSavedataIDs { get; set; }
|
||||
/// <remarks>8 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public byte[]? SystemSavedataIDs;
|
||||
|
||||
/// <summary>
|
||||
/// Storage accessible unique IDs
|
||||
/// </summary>
|
||||
public byte[]? StorageAccessibleUniqueIDs { get; set; }
|
||||
/// <remarks>8 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public byte[]? StorageAccessibleUniqueIDs;
|
||||
|
||||
/// <summary>
|
||||
/// Filesystem access info
|
||||
/// </summary>
|
||||
/// TODO: Create enum for the flag values
|
||||
/// TODO: Combine with "other attributes"
|
||||
public byte[]? FileSystemAccessInfo { get; set; }
|
||||
/// <remarks>7 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)]
|
||||
public byte[]? FileSystemAccessInfo;
|
||||
|
||||
/// <summary>
|
||||
/// Other attributes
|
||||
/// </summary>
|
||||
public StorageInfoOtherAttributes OtherAttributes { get; set; }
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public StorageInfoOtherAttributes OtherAttributes;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,66 +1,75 @@
|
||||
namespace SabreTools.Models.N3DS
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SabreTools.Models.N3DS
|
||||
{
|
||||
/// <see href="https://www.3dbrew.org/wiki/NCCH/Extended_Header#System_Control_Info"/>
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
||||
public sealed class SystemControlInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Application title (default is "CtrApp")
|
||||
/// </summary>
|
||||
public string? ApplicationTitle { get; set; }
|
||||
/// <remarks>8 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
|
||||
public string? ApplicationTitle;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
public byte[]? Reserved1 { get; set; }
|
||||
/// <remarks>5 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
|
||||
public byte[]? Reserved1;
|
||||
|
||||
/// <summary>
|
||||
/// Flag (bit 0: CompressExefsCode, bit 1: SDApplication)
|
||||
/// </summary>
|
||||
public byte Flag { get; set; }
|
||||
public byte Flag;
|
||||
|
||||
/// <summary>
|
||||
/// Remaster version
|
||||
/// </summary>
|
||||
public ushort RemasterVersion { get; set; }
|
||||
public ushort RemasterVersion;
|
||||
|
||||
/// <summary>
|
||||
/// Text code set info
|
||||
/// </summary>
|
||||
public CodeSetInfo? TextCodeSetInfo { get; set; }
|
||||
public CodeSetInfo? TextCodeSetInfo;
|
||||
|
||||
/// <summary>
|
||||
/// Stack size
|
||||
/// </summary>
|
||||
public uint StackSize { get; set; }
|
||||
public uint StackSize;
|
||||
|
||||
/// <summary>
|
||||
/// Read-only code set info
|
||||
/// </summary>
|
||||
public CodeSetInfo? ReadOnlyCodeSetInfo { get; set; }
|
||||
public CodeSetInfo? ReadOnlyCodeSetInfo;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
public byte[]? Reserved2 { get; set; }
|
||||
public uint Reserved2;
|
||||
|
||||
/// <summary>
|
||||
/// Data code set info
|
||||
/// </summary>
|
||||
public CodeSetInfo? DataCodeSetInfo { get; set; }
|
||||
public CodeSetInfo? DataCodeSetInfo;
|
||||
|
||||
/// <summary>
|
||||
/// BSS size
|
||||
/// </summary>
|
||||
public uint BSSSize { get; set; }
|
||||
public uint BSSSize;
|
||||
|
||||
/// <summary>
|
||||
/// Dependency module (program ID) list
|
||||
/// </summary>
|
||||
public ulong[]? DependencyModuleList { get; set; }
|
||||
/// <remarks>48 entries</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 48)]
|
||||
public ulong[]? DependencyModuleList;
|
||||
|
||||
/// <summary>
|
||||
/// SystemInfo
|
||||
/// </summary>
|
||||
public SystemInfo? SystemInfo { get; set; }
|
||||
public SystemInfo? SystemInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,26 @@
|
||||
namespace SabreTools.Models.N3DS
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SabreTools.Models.N3DS
|
||||
{
|
||||
/// <see href="https://www.3dbrew.org/wiki/NCCH/Extended_Header#System_Info"/>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public sealed class SystemInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// SaveData Size
|
||||
/// </summary>
|
||||
public ulong SaveDataSize { get; set; }
|
||||
public ulong SaveDataSize;
|
||||
|
||||
/// <summary>
|
||||
/// Jump ID
|
||||
/// </summary>
|
||||
public ulong JumpID { get; set; }
|
||||
public ulong JumpID;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
public byte[]? Reserved { get; set; }
|
||||
/// <remarks>0x30 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x30)]
|
||||
public byte[]? Reserved;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,59 +1,80 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SabreTools.Models.N3DS
|
||||
{
|
||||
/// <summary>
|
||||
/// The test data is the same one encountered in development DS/DSi cartridges.
|
||||
/// </summary>
|
||||
/// <see href="https://www.3dbrew.org/wiki/NCSD#TestData"/>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public sealed class TestData
|
||||
{
|
||||
/// <summary>
|
||||
/// The bytes FF 00 FF 00 AA 55 AA 55.
|
||||
/// </summary>
|
||||
public byte[]? Signature { get; set; }
|
||||
/// <remarks>8 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public byte[]? Signature;
|
||||
|
||||
/// <summary>
|
||||
/// An ascending byte sequence equal to the offset mod 256 (08 09 0A ... FE FF 00 01 ... FF).
|
||||
/// </summary>
|
||||
public byte[]? AscendingByteSequence { get; set; }
|
||||
/// <remarks>0x1F8 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x1F8)]
|
||||
public byte[]? AscendingByteSequence;
|
||||
|
||||
/// <summary>
|
||||
/// A descending byte sequence equal to 255 minus the offset mod 256 (FF FE FD ... 00 FF DE ... 00).
|
||||
/// </summary>
|
||||
public byte[]? DescendingByteSequence { get; set; }
|
||||
/// <remarks>0x200 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x200)]
|
||||
public byte[]? DescendingByteSequence;
|
||||
|
||||
/// <summary>
|
||||
/// Filled with 00 (0b00000000) bytes.
|
||||
/// </summary>
|
||||
public byte[]? Filled00 { get; set; }
|
||||
/// <remarks>0x200 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x200)]
|
||||
public byte[]? Filled00;
|
||||
|
||||
/// <summary>
|
||||
/// Filled with FF (0b11111111) bytes.
|
||||
/// </summary>
|
||||
public byte[]? FilledFF { get; set; }
|
||||
/// <remarks>0x200 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x200)]
|
||||
public byte[]? FilledFF;
|
||||
|
||||
/// <summary>
|
||||
/// Filled with 0F (0b00001111) bytes.
|
||||
/// </summary>
|
||||
public byte[]? Filled0F { get; set; }
|
||||
/// <remarks>0x200 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x200)]
|
||||
public byte[]? Filled0F;
|
||||
|
||||
/// <summary>
|
||||
/// Filled with F0 (0b11110000) bytes.
|
||||
/// </summary>
|
||||
public byte[]? FilledF0 { get; set; }
|
||||
/// <remarks>0x200 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x200)]
|
||||
public byte[]? FilledF0;
|
||||
|
||||
/// <summary>
|
||||
/// Filled with 55 (0b01010101) bytes.
|
||||
/// </summary>
|
||||
public byte[]? Filled55 { get; set; }
|
||||
/// <remarks>0x200 bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x200)]
|
||||
public byte[]? Filled55;
|
||||
|
||||
/// <summary>
|
||||
/// Filled with AA (0b10101010) bytes.
|
||||
/// </summary>
|
||||
public byte[]? FilledAA { get; set; }
|
||||
/// <remarks>0x1FF bytes</remarks>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x1FF)]
|
||||
public byte[]? FilledAA;
|
||||
|
||||
/// <summary>
|
||||
/// The final byte is 00 (0b00000000).
|
||||
/// </summary>
|
||||
public byte FinalByte { get; set; }
|
||||
public byte FinalByte;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user