diff --git a/Nitro/CommonHeader.cs b/Nitro/CommonHeader.cs
index 9796c7f..5fad6b3 100644
--- a/Nitro/CommonHeader.cs
+++ b/Nitro/CommonHeader.cs
@@ -1,214 +1,232 @@
+using System.Runtime.InteropServices;
+
namespace SabreTools.Models.Nitro
{
///
/// Nintendo DS / DSi cartridge header
///
///
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public sealed class CommonHeader
{
///
/// Game Title
///
- public string? GameTitle { get; set; }
+ /// 12 bytes
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 12)]
+ public string? GameTitle;
///
/// Gamecode
///
- public uint GameCode { get; set; }
+ public uint GameCode;
///
/// Makercode
///
- public string? MakerCode { get; set; }
+ /// 2 bytes
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 2)]
+ public string? MakerCode;
///
/// Unitcode
///
- public Unitcode UnitCode { get; set; }
+ [MarshalAs(UnmanagedType.U1)]
+ public Unitcode UnitCode;
///
/// Encryption seed select (device code. 0 = normal)
///
- public byte EncryptionSeedSelect { get; set; }
+ public byte EncryptionSeedSelect;
///
/// Devicecapacity
///
- public byte DeviceCapacity { get; set; }
+ public byte DeviceCapacity;
///
/// Reserved
///
- public byte[]? Reserved1 { get; set; }
+ /// 7 bytes
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)]
+ public byte[]? Reserved1;
///
/// Game Revision (used by DSi titles)
///
- public ushort GameRevision { get; set; }
+ public ushort GameRevision;
///
/// ROM Version
///
- public byte RomVersion { get; set; }
+ public byte RomVersion;
///
/// Internal flags, (Bit2: Autostart)
///
- public byte InternalFlags { get; set; }
+ public byte InternalFlags;
///
/// ARM9 rom offset
///
- public uint ARM9RomOffset { get; set; }
+ public uint ARM9RomOffset;
///
/// ARM9 entry address
///
- public uint ARM9EntryAddress { get; set; }
+ public uint ARM9EntryAddress;
///
/// ARM9 load address
///
- public uint ARM9LoadAddress { get; set; }
+ public uint ARM9LoadAddress;
///
/// ARM9 size
///
- public uint ARM9Size { get; set; }
+ public uint ARM9Size;
///
/// ARM7 rom offset
///
- public uint ARM7RomOffset { get; set; }
+ public uint ARM7RomOffset;
///
/// ARM7 entry address
///
- public uint ARM7EntryAddress { get; set; }
+ public uint ARM7EntryAddress;
///
/// ARM7 load address
///
- public uint ARM7LoadAddress { get; set; }
+ public uint ARM7LoadAddress;
///
/// ARM7 size
///
- public uint ARM7Size { get; set; }
+ public uint ARM7Size;
///
/// File Name Table (FNT) offset
///
- public uint FileNameTableOffset { get; set; }
+ public uint FileNameTableOffset;
///
/// File Name Table (FNT) length
///
- public uint FileNameTableLength { get; set; }
+ public uint FileNameTableLength;
///
/// File Allocation Table (FNT) offset
///
- public uint FileAllocationTableOffset { get; set; }
+ public uint FileAllocationTableOffset;
///
/// File Allocation Table (FNT) length
///
- public uint FileAllocationTableLength { get; set; }
+ public uint FileAllocationTableLength;
///
/// File Name Table (FNT) offset
///
- public uint ARM9OverlayOffset { get; set; }
+ public uint ARM9OverlayOffset;
///
/// File Name Table (FNT) length
///
- public uint ARM9OverlayLength { get; set; }
+ public uint ARM9OverlayLength;
///
/// File Name Table (FNT) offset
///
- public uint ARM7OverlayOffset { get; set; }
+ public uint ARM7OverlayOffset;
///
/// File Name Table (FNT) length
///
- public uint ARM7OverlayLength { get; set; }
+ public uint ARM7OverlayLength;
///
/// Normal card control register settings (0x00416657 for OneTimePROM)
///
- public uint NormalCardControlRegisterSettings { get; set; }
+ public uint NormalCardControlRegisterSettings;
///
/// Secure card control register settings (0x081808F8 for OneTimePROM)
///
- public uint SecureCardControlRegisterSettings { get; set; }
+ public uint SecureCardControlRegisterSettings;
///
/// Icon Banner offset (NDSi same as NDS, but with new extra entries)
///
- public uint IconBannerOffset { get; set; }
+ public uint IconBannerOffset;
///
/// Secure area (2K) CRC
///
- public ushort SecureAreaCRC { get; set; }
+ public ushort SecureAreaCRC;
///
/// Secure transfer timeout (0x0D7E for OneTimePROM)
///
- public ushort SecureTransferTimeout { get; set; }
+ public ushort SecureTransferTimeout;
///
/// ARM9 autoload
///
- public uint ARM9Autoload { get; set; }
+ public uint ARM9Autoload;
///
/// ARM7 autoload
///
- public uint ARM7Autoload { get; set; }
+ public uint ARM7Autoload;
///
/// Secure disable
///
- public byte[]? SecureDisable { get; set; }
+ /// 8 bytes
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
+ public byte[]? SecureDisable;
///
/// NTR region ROM size (excluding DSi area)
///
- public uint NTRRegionRomSize { get; set; }
+ public uint NTRRegionRomSize;
///
/// Header size
///
- public uint HeaderSize { get; set; }
+ public uint HeaderSize;
///
- ///Reserved (0x88, 0x8C, 0x90 = Unknown, used by DSi)
+ /// Reserved (0x88, 0x8C, 0x90 = Unknown, used by DSi)
///
- public byte[]? Reserved2 { get; set; }
+ /// 56 bytes
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 56)]
+ public byte[]? Reserved2;
///
/// Nintendo Logo
///
- public byte[]? NintendoLogo { get; set; }
+ /// 156 bytes
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 156)]
+ public byte[]? NintendoLogo;
///
/// Nintendo Logo CRC
///
- public ushort NintendoLogoCRC { get; set; }
+ public ushort NintendoLogoCRC;
///
/// Header CRC
///
- public ushort HeaderCRC { get; set; }
+ public ushort HeaderCRC;
///
/// Debugger reserved
///
- public byte[]? DebuggerReserved { get; set; }
+ /// 0x20 bytes
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)]
+ public byte[]? DebuggerReserved;
}
}
\ No newline at end of file
diff --git a/Nitro/ExtendedDSiHeader.cs b/Nitro/ExtendedDSiHeader.cs
index 943fe82..cf4a766 100644
--- a/Nitro/ExtendedDSiHeader.cs
+++ b/Nitro/ExtendedDSiHeader.cs
@@ -1,259 +1,298 @@
+using System.Runtime.InteropServices;
+
namespace SabreTools.Models.Nitro
{
///
/// Nintendo DSi extended cart header
///
///
+ [StructLayout(LayoutKind.Sequential)]
public sealed class ExtendedDSiHeader
{
///
/// Global MBK1..MBK5 Settings
///
- public uint[]? GlobalMBK15Settings { get; set; }
+ /// 5 entries
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
+ public uint[]? GlobalMBK15Settings;
///
/// Local MBK6..MBK8 Settings for ARM9
///
- public uint[]? LocalMBK68SettingsARM9 { get; set; }
+ /// 3 entries
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
+ public uint[]? LocalMBK68SettingsARM9;
///
/// Local MBK6..MBK8 Settings for ARM7
///
- public uint[]? LocalMBK68SettingsARM7 { get; set; }
+ /// 3 entries
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
+ public uint[]? LocalMBK68SettingsARM7;
///
/// Global MBK9 Setting
///
- public uint GlobalMBK9Setting { get; set; }
+ public uint GlobalMBK9Setting;
///
/// Region Flags
///
- public uint RegionFlags { get; set; }
+ public uint RegionFlags;
///
/// Access control
///
- public uint AccessControl { get; set; }
+ public uint AccessControl;
///
/// ARM7 SCFG EXT mask (controls which devices to enable)
///
- public uint ARM7SCFGEXTMask { get; set; }
+ public uint ARM7SCFGEXTMask;
///
/// Reserved/flags? When bit2 of byte 0x1bf is set, usage of banner.sav from the title data dir is enabled.(additional banner data)
///
- public uint ReservedFlags { get; set; }
+ public uint ReservedFlags;
///
/// ARM9i rom offset
///
- public uint ARM9iRomOffset { get; set; }
+ public uint ARM9iRomOffset;
///
/// Reserved
///
- public uint Reserved3 { get; set; }
+ public uint Reserved3;
///
/// ARM9i load address
///
- public uint ARM9iLoadAddress { get; set; }
+ public uint ARM9iLoadAddress;
///
- /// ARM9i size { get; set; }
+ /// ARM9i size;
///
- public uint ARM9iSize { get; set; }
+ public uint ARM9iSize;
///
/// ARM7i rom offset
///
- public uint ARM7iRomOffset { get; set; }
+ public uint ARM7iRomOffset;
///
/// Pointer to base address where various structures and parameters are passed to the title - what is that???
///
- public uint Reserved4 { get; set; }
+ public uint Reserved4;
///
/// ARM7i load address
///
- public uint ARM7iLoadAddress { get; set; }
+ public uint ARM7iLoadAddress;
///
- /// ARM7i size { get; set; }
+ /// ARM7i size;
///
- public uint ARM7iSize { get; set; }
+ public uint ARM7iSize;
///
/// Digest NTR region offset
///
- public uint DigestNTRRegionOffset { get; set; }
+ public uint DigestNTRRegionOffset;
///
/// Digest NTR region length
///
- public uint DigestNTRRegionLength { get; set; }
+ public uint DigestNTRRegionLength;
//
/// Digest TWL region offset
///
- public uint DigestTWLRegionOffset { get; set; }
+ public uint DigestTWLRegionOffset;
///
/// Digest TWL region length
///
- public uint DigestTWLRegionLength { get; set; }
+ public uint DigestTWLRegionLength;
//
/// Digest Sector Hashtable region offset
///
- public uint DigestSectorHashtableRegionOffset { get; set; }
+ public uint DigestSectorHashtableRegionOffset;
///
/// Digest Sector Hashtable region length
///
- public uint DigestSectorHashtableRegionLength { get; set; }
+ public uint DigestSectorHashtableRegionLength;
//
/// Digest Block Hashtable region offset
///
- public uint DigestBlockHashtableRegionOffset { get; set; }
+ public uint DigestBlockHashtableRegionOffset;
///
/// Digest Block Hashtable region length
///
- public uint DigestBlockHashtableRegionLength { get; set; }
+ public uint DigestBlockHashtableRegionLength;
///
/// Digest Sector size
///
- public uint DigestSectorSize { get; set; }
+ public uint DigestSectorSize;
///
/// Digeset Block Sectorount
///
- public uint DigestBlockSectorCount { get; set; }
+ public uint DigestBlockSectorCount;
///
/// Icon Banner Size (usually 0x23C0)
///
- public uint IconBannerSize { get; set; }
+ public uint IconBannerSize;
///
/// Unknown (used by DSi)
///
- public uint Unknown1 { get; set; }
+ public uint Unknown1;
///
/// NTR+TWL region ROM size (total size including DSi area)
///
- public uint NTRTWLRegionRomSize { get; set; }
+ public uint NTRTWLRegionRomSize;
///
/// Unknown (used by DSi)
///
- public byte[]? Unknown2 { get; set; }
+ /// 12 bytes
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
+ public byte[]? Unknown2;
///
/// Modcrypt area 1 offset
///
- public uint ModcryptArea1Offset { get; set; }
+ public uint ModcryptArea1Offset;
///
/// Modcrypt area 1 size
///
- public uint ModcryptArea1Size { get; set; }
+ public uint ModcryptArea1Size;
///
/// Modcrypt area 2 offset
///
- public uint ModcryptArea2Offset { get; set; }
+ public uint ModcryptArea2Offset;
///
/// Modcrypt area 2 size
///
- public uint ModcryptArea2Size { get; set; }
+ public uint ModcryptArea2Size;
///
/// Title ID
///
- public byte[]? TitleID { get; set; }
+ /// 8 bytes
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
+ public byte[]? TitleID;
///
/// DSiWare: "public.sav" size
///
- public uint DSiWarePublicSavSize { get; set; }
+ public uint DSiWarePublicSavSize;
///
/// DSiWare: "private.sav" size
///
- public uint DSiWarePrivateSavSize { get; set; }
+ public uint DSiWarePrivateSavSize;
///
/// Reserved (zero)
///
- public byte[]? ReservedZero { get; set; }
+ /// 176 bytes
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 176)]
+ public byte[]? ReservedZero;
///
/// Unknown (used by DSi)
///
- public byte[]? Unknown3 { get; set; }
+ /// 16 bytes
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
+ public byte[]? Unknown3;
///
/// ARM9 (with encrypted secure area) SHA1 HMAC hash
///
- public byte[]? ARM9WithSecureAreaSHA1HMACHash { get; set; }
+ /// 20 bytes
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
+ public byte[]? ARM9WithSecureAreaSHA1HMACHash;
///
/// ARM7 SHA1 HMAC hash
///
- public byte[]? ARM7SHA1HMACHash { get; set; }
+ /// 20 bytes
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
+ public byte[]? ARM7SHA1HMACHash;
///
/// Digest master SHA1 HMAC hash
///
- public byte[]? DigestMasterSHA1HMACHash { get; set; }
+ /// 20 bytes
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
+ public byte[]? DigestMasterSHA1HMACHash;
///
/// Banner SHA1 HMAC hash
///
- public byte[]? BannerSHA1HMACHash { get; set; }
+ /// 20 bytes
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
+ public byte[]? BannerSHA1HMACHash;
///
/// ARM9i (decrypted) SHA1 HMAC hash
///
- public byte[]? ARM9iDecryptedSHA1HMACHash { get; set; }
+ /// 20 bytes
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
+ public byte[]? ARM9iDecryptedSHA1HMACHash;
///
/// ARM7i (decrypted) SHA1 HMAC hash
///
- public byte[]? ARM7iDecryptedSHA1HMACHash { get; set; }
+ /// 20 bytes
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
+ public byte[]? ARM7iDecryptedSHA1HMACHash;
///
/// Reserved
///
- public byte[]? Reserved5 { get; set; }
+ /// 40 bytes
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
+ public byte[]? Reserved5;
///
/// ARM9 (without secure area) SHA1 HMAC hash
///
- public byte[]? ARM9NoSecureAreaSHA1HMACHash { get; set; }
+ /// 20 bytes
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
+ public byte[]? ARM9NoSecureAreaSHA1HMACHash;
///
/// Reserved
///
- public byte[]? Reserved6 { get; set; }
+ /// 2636 bytes
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2636)]
+ public byte[]? Reserved6;
///
/// Reserved and unchecked region, always zero. Used for passing arguments in debug environment.
///
- public byte[]? ReservedAndUnchecked { get; set; }
+ /// 0x180 bytes
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x180)]
+ public byte[]? ReservedAndUnchecked;
///
/// RSA signature (the first 0xE00 bytes of the header are signed with an 1024-bit RSA signature).
///
- public byte[]? RSASignature { get; set; }
+ /// 0x80 bytes
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x80)]
+ public byte[]? RSASignature;
}
}
\ No newline at end of file
diff --git a/Nitro/FileAllocationTableEntry.cs b/Nitro/FileAllocationTableEntry.cs
index 47817e1..43c4819 100644
--- a/Nitro/FileAllocationTableEntry.cs
+++ b/Nitro/FileAllocationTableEntry.cs
@@ -1,3 +1,5 @@
+using System.Runtime.InteropServices;
+
namespace SabreTools.Models.Nitro
{
///
@@ -5,16 +7,17 @@ namespace SabreTools.Models.Nitro
/// it's just a table of 8 byte entries
///
///
+ [StructLayout(LayoutKind.Sequential)]
public sealed class FileAllocationTableEntry
{
///
/// Start offset of file
///
- public uint StartOffset { get; set; }
+ public uint StartOffset;
///
/// End offset of file (after this is padding)
///
- public uint EndOffset { get; set; }
+ public uint EndOffset;
}
}
\ No newline at end of file
diff --git a/Nitro/FolderAllocationTableEntry.cs b/Nitro/FolderAllocationTableEntry.cs
index e177991..7a8e5a3 100644
--- a/Nitro/FolderAllocationTableEntry.cs
+++ b/Nitro/FolderAllocationTableEntry.cs
@@ -1,3 +1,5 @@
+using System.Runtime.InteropServices;
+
namespace SabreTools.Models.Nitro
{
///
@@ -6,28 +8,29 @@ namespace SabreTools.Models.Nitro
/// point to the file system.
///
///
+ [StructLayout(LayoutKind.Sequential)]
public sealed class FolderAllocationTableEntry
{
///
/// Start offset of folder contents within Name List
/// relative to start of NameTable
///
- public uint StartOffset { get; set; }
+ public uint StartOffset;
///
/// Index of first file within folder in File Allocation Table
///
- public ushort FirstFileIndex { get; set; }
+ public ushort FirstFileIndex;
///
/// Index of parent folder in current table; for root folder
/// this holds the number of entries in the table
///
- public byte ParentFolderIndex { get; set; }
+ public byte ParentFolderIndex;
///
/// Unknown, always 0xF0 except for root folder
///
- public byte Unknown { get; set; }
+ public byte Unknown;
}
}
\ No newline at end of file