27 Commits
1.4.3 ... 1.4.5

Author SHA1 Message Date
Matt Nadareski
adaac68898 Bump version 2024-04-24 10:04:06 -04:00
Matt Nadareski
a9bc4a2bfe Fix getopts 2024-04-24 01:35:59 -04:00
Matt Nadareski
262b91de65 32 unicode characters, 64 bytes 2024-04-24 01:25:30 -04:00
Matt Nadareski
62bd6a4bde Add a couple of constants from UnshieldSharp 2024-04-24 00:36:41 -04:00
Matt Nadareski
7f14f0c5b0 Fix encoding for DirectoryEntry 2024-04-23 21:43:17 -04:00
Matt Nadareski
33d63fddae Bump version 2024-04-23 21:01:52 -04:00
Matt Nadareski
209be57bf4 Add layouts for some BD+ models 2024-04-23 20:59:47 -04:00
Matt Nadareski
a1581e9d9b Add layouts for some BFPK models 2024-04-23 20:58:51 -04:00
Matt Nadareski
521664d5a8 Add layouts for some BSP models 2024-04-23 20:57:24 -04:00
Matt Nadareski
73a8d91a83 Add layouts for some CFB models 2024-04-23 20:55:10 -04:00
Matt Nadareski
438e87f833 Add layouts for some CHD models 2024-04-23 20:50:09 -04:00
Matt Nadareski
2cdedbb456 Add layouts for some DVD models 2024-04-23 20:47:33 -04:00
Matt Nadareski
b57a545598 Add layouts for some GCF models 2024-04-23 20:38:11 -04:00
Matt Nadareski
8dc6eb2eee Add layouts for some IS-CAB models 2024-04-23 20:26:18 -04:00
Matt Nadareski
b58436d71a Add layouts for some MoPaQ models 2024-04-23 20:18:26 -04:00
Matt Nadareski
925c20021f Add layouts for some MSDOS models 2024-04-23 20:13:07 -04:00
Matt Nadareski
9bebf95599 Add layouts for some N3DS models 2024-04-23 20:09:39 -04:00
Matt Nadareski
089e13ca03 Add layouts for some NCF models 2024-04-23 19:34:56 -04:00
Matt Nadareski
de07b3b0dd Make some types non-nullable 2024-04-23 19:13:47 -04:00
Matt Nadareski
22cb5360e6 Add notes about prefixed strings 2024-04-23 17:20:05 -04:00
Matt Nadareski
a422ec7e6d Add layouts for some Nitro models 2024-04-23 17:15:15 -04:00
Matt Nadareski
f60afd6368 Add layouts for some PE models 2024-04-23 16:42:29 -04:00
Matt Nadareski
b8f67a8ab0 Add layouts for some VBSP models 2024-04-23 16:06:09 -04:00
Matt Nadareski
d844a8b582 Add layouts for some VPK models 2024-04-23 16:03:20 -04:00
Matt Nadareski
8583baa862 Add layouts for some WAD models 2024-04-23 15:56:43 -04:00
Matt Nadareski
8f3be17850 Add layouts for some XZP models 2024-04-23 15:49:41 -04:00
Matt Nadareski
5856967794 Fill and fix some ISAv3 information 2024-04-23 15:43:33 -04:00
87 changed files with 957 additions and 541 deletions

View File

@@ -6,11 +6,13 @@ namespace SabreTools.Models.BDPlus
/// <summary>
/// "BDSVM_CC"
/// </summary>
/// <remarks>8 bytes</remarks>
public string? Signature { get; set; }
/// <summary>
/// 5 bytes of unknown data
/// Unknown data
/// </summary>
/// <remarks>5 bytes</remarks>
public byte[]? Unknown1 { get; set; }
/// <summary>
@@ -29,8 +31,9 @@ namespace SabreTools.Models.BDPlus
public byte Day { get; set; }
/// <summary>
/// 4 bytes of unknown data
/// Unknown data
/// </summary>
/// <remarks>4 bytes</remarks>
public byte[]? Unknown2 { get; set; }
/// <summary>

View File

@@ -14,6 +14,6 @@
/// <summary>
/// Files
/// </summary>
public FileEntry?[]? Files { get; set; }
public FileEntry[]? Files { get; set; }
}
}

View File

@@ -11,6 +11,7 @@ namespace SabreTools.Models.BSP
/// <summary>
/// Offsets
/// </summary>
/// <remarks>TextureCount entries</remarks>
public uint[]? Offsets { get; set; }
}
}

View File

@@ -25,7 +25,7 @@ namespace SabreTools.Models.CFB
///
/// If Header Major Version is 4, there MUST be 1,024 fields specified to fill a 4,096-byte sector
/// </remarks>
public SectorNumber?[]? FATSectorNumbers { get; set; }
public SectorNumber[]? FATSectorNumbers { get; set; }
/// <summary>
/// The mini FAT is used to allocate space in the mini stream.
@@ -38,7 +38,7 @@ namespace SabreTools.Models.CFB
///
/// If Header Major Version is 4, there MUST be 1,024 fields specified to fill a 4,096-byte sector
/// </remarks>
public SectorNumber?[]? MiniFATSectorNumbers { get; set; }
public SectorNumber[]? MiniFATSectorNumbers { get; set; }
/// <summary>
/// The DIFAT array is used to represent storage of the FAT sectors.
@@ -55,7 +55,7 @@ namespace SabreTools.Models.CFB
/// If Header Major Version is 4, there MUST be 1,023 fields specified
/// to fill a 4,096-byte sector minus the "Next DIFAT Sector Location" field.
/// </remarks>
public SectorNumber?[]? DIFATSectorNumbers { get; set; }
public SectorNumber[]? DIFATSectorNumbers { get; set; }
/// <summary>
/// The directory entry array is an array of directory entries that
@@ -87,6 +87,6 @@ namespace SabreTools.Models.CFB
/// all zeroes. The Modified Time field in the root storage directory
/// entry MAY be all zeroes.
/// <remarks>
public DirectoryEntry?[]? DirectoryEntries { get; set; }
public DirectoryEntry[]? DirectoryEntries { get; set; }
}
}

View File

@@ -1,8 +1,10 @@
using System;
using System.Runtime.InteropServices;
namespace SabreTools.Models.CFB
{
/// <see href="https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-CFB/%5bMS-CFB%5d.pdf"/>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public sealed class DirectoryEntry
{
/// <summary>
@@ -16,13 +18,15 @@ namespace SabreTools.Models.CFB
/// The following characters are illegal and MUST NOT be part of the
/// name: '/', '\', ':', '!'.
/// </summary>
public string? Name { get; set; }
/// <remarks>64 bytes</remarks>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string? Name;
/// <summary>
/// This field MUST be 0x00, 0x01, 0x02, or 0x05, depending on the
/// actual type of object. All other values are not valid.
/// </summary>
public ushort NameLength { get; set; }
public ushort NameLength;
/// <summary>
/// This field MUST match the length of the Directory Entry Name Unicode
@@ -30,31 +34,36 @@ namespace SabreTools.Models.CFB
/// terminating null character in the count. This length MUST NOT exceed 64,
/// the maximum size of the Directory Entry Name field.
/// </summary>
public ObjectType ObjectType { get; set; }
[MarshalAs(UnmanagedType.U1)]
public ObjectType ObjectType;
/// <summary>
/// This field MUST be 0x00 (red) or 0x01 (black). All other values are not valid.
/// </summary>
public ColorFlag ColorFlag { get; set; }
[MarshalAs(UnmanagedType.U1)]
public ColorFlag ColorFlag;
/// <summary>
/// This field contains the stream ID of the left sibling. If there
/// is no left sibling, the field MUST be set to NOSTREAM (0xFFFFFFFF).
/// </summary>
public StreamID LeftSiblingID { get; set; }
[MarshalAs(UnmanagedType.U4)]
public StreamID LeftSiblingID;
/// <summary>
/// This field contains the stream ID of the right sibling. If there
/// is no right sibling, the field MUST be set to NOSTREAM (0xFFFFFFFF).
/// </summary>
public StreamID RightSiblingID { get; set; }
[MarshalAs(UnmanagedType.U4)]
public StreamID RightSiblingID;
/// <summary>
/// This field contains the stream ID of a child object. If there is no
/// child object, including all entries for stream objects, the field
/// MUST be set to NOSTREAM (0xFFFFFFFF).
/// </summary>
public StreamID ChildID { get; set; }
[MarshalAs(UnmanagedType.U4)]
public StreamID ChildID;
/// <summary>
/// This field contains an object class GUID, if this entry is for a
@@ -67,7 +76,7 @@ namespace SabreTools.Models.CFB
/// this value is not all zeroes, the object class GUID can be used as a
/// parameter to start applications.
/// </summary>
public Guid CLSID { get; set; }
public Guid CLSID;
/// <summary>
/// This field contains the user-defined flags if this entry is for a storage
@@ -78,7 +87,7 @@ namespace SabreTools.Models.CFB
/// objects without explicitly setting state bits, it MUST write all zeroes
/// by default.
/// </summary>
public uint StateBits { get; set; }
public uint StateBits;
/// <summary>
/// This field contains the creation time for a storage object, or all zeroes
@@ -88,7 +97,7 @@ namespace SabreTools.Models.CFB
/// object, this field MUST be all zeroes, and the creation time is retrieved
/// or set on the compound file itself.
/// </summary>
public ulong CreationTime { get; set; }
public ulong CreationTime;
/// <summary>
/// This field contains the modification time for a storage object, or all
@@ -98,7 +107,7 @@ namespace SabreTools.Models.CFB
/// storage object, this field MAY<2> be set to all zeroes, and the modified
/// time is retrieved or set on the compound file itself.
/// </summary>
public ulong ModifiedTime { get; set; }
public ulong ModifiedTime;
/// <summary>
/// This field contains the first sector location if this is a stream object.
@@ -106,7 +115,7 @@ namespace SabreTools.Models.CFB
/// mini stream, if the mini stream exists. For a storage object, this field MUST
/// be set to all zeroes.
/// </summary>
public uint StartingSectorLocation { get; set; }
public uint StartingSectorLocation;
/// <summary>
/// This 64-bit integer field contains the size of the user-defined data if this
@@ -128,6 +137,6 @@ namespace SabreTools.Models.CFB
/// unless there is a specific reason to do otherwise (for example, a parser whose
/// purpose is to verify the correctness of a compound file).
/// </remarks>
public ulong StreamSize { get; set; }
public ulong StreamSize;
}
}

View File

@@ -1,38 +1,40 @@
using System;
using System.Runtime.InteropServices;
namespace SabreTools.Models.CFB
{
/// <see href="https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-CFB/%5bMS-CFB%5d.pdf"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class FileHeader
{
/// <summary>
/// Iddentification signature for the compound file structure, and MUST be
/// set to the value 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1.
/// </summary>
public ulong Signature { get; set; }
public ulong Signature;
/// <summary>
/// Reserved and unused class ID that MUST be set to all zeroes (CLSID_NULL)
/// </summary>
public Guid CLSID { get; set; }
public Guid CLSID;
/// <summary>
/// Version number for nonbreaking changes. This field SHOULD be set to
/// 0x003E if the major version field is either 0x0003 or 0x0004.
/// </summary>
public ushort MinorVersion { get; set; }
public ushort MinorVersion;
/// <summary>
/// Version number for breaking changes. This field MUST be set to either
/// 0x0003 (version 3) or 0x0004 (version 4).
/// </summary>
public ushort MajorVersion { get; set; }
public ushort MajorVersion;
/// <summary>
/// This field MUST be set to 0xFFFE. This field is a byte order mark for
/// all integer fields, specifying little-endian byte order.
/// </summary>
public ushort ByteOrder { get; set; }
public ushort ByteOrder;
/// <summary>
/// This field MUST be set to 0x0009, or 0x000c, depending on the Major
@@ -45,19 +47,21 @@ namespace SabreTools.Models.CFB
/// If Major Version is 4, the Sector Shift MUST be 0x000C, specifying a
/// sector size of 4096 bytes.
/// </summary>
public ushort SectorShift { get; set; }
public ushort SectorShift;
/// <summary>
/// This field MUST be set to 0x0006. This field specifies the sector size
/// of the Mini Stream as a power of 2. The sector size of the Mini Stream
/// MUST be 64 bytes.
/// </summary>
public ushort MiniSectorShift { get; set; }
public ushort MiniSectorShift;
/// <summary>
/// This field MUST be set to all zeroes.
/// </summary>
public byte[]? Reserved { get; set; }
/// <remarks>6 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public byte[]? Reserved;
/// <summary>
/// This integer field contains the count of the number of directory sectors
@@ -66,18 +70,18 @@ namespace SabreTools.Models.CFB
/// If Major Version is 3, the Number of Directory Sectors MUST be zero. This
/// field is not supported for version 3 compound files.
/// </summary>
public uint NumberOfDirectorySectors { get; set; }
public uint NumberOfDirectorySectors;
/// <summary>
/// This integer field contains the count of the number of FAT sectors in the
/// compound file.
/// </summary>
public uint NumberOfFATSectors { get; set; }
public uint NumberOfFATSectors;
/// <summary>
/// This integer field contains the starting sector number for the directory stream.
/// </summary>
public uint FirstDirectorySectorLocation { get; set; }
public uint FirstDirectorySectorLocation;
/// <summary>
/// This integer field MAY contain a sequence number that is incremented every time
@@ -85,7 +89,7 @@ namespace SabreTools.Models.CFB
/// This is the field that MUST be set to all zeroes if file transactions are not
/// implemented.
/// </summary>
public uint TransactionSignatureNumber { get; set; }
public uint TransactionSignatureNumber;
/// <summary>
/// This integer field MUST be set to 0x00001000. This field specifies the maximum
@@ -94,34 +98,36 @@ namespace SabreTools.Models.CFB
/// greater than or equal to this cutoff size must be allocated as normal sectors from
/// the FAT.
/// </summary>
public uint MiniStreamCutoffSize { get; set; }
public uint MiniStreamCutoffSize;
/// <summary>
/// This integer field contains the starting sector number for the mini FAT.
/// </summary>
public uint FirstMiniFATSectorLocation { get; set; }
public uint FirstMiniFATSectorLocation;
/// <summary>
/// This integer field contains the count of the number of mini FAT sectors in the
/// compound file.
/// </summary>
public uint NumberOfMiniFATSectors { get; set; }
public uint NumberOfMiniFATSectors;
/// <summary>
/// This integer field contains the starting sector number for the DIFAT.
/// </summary>
public uint FirstDIFATSectorLocation { get; set; }
public uint FirstDIFATSectorLocation;
/// <summary>
/// This integer field contains the count of the number of DIFAT sectors in the
/// compound file.
/// </summary>
public uint NumberOfDIFATSectors { get; set; }
public uint NumberOfDIFATSectors;
/// <summary>
/// This array of 32-bit integer fields contains the first 109 FAT sector
/// locations of the compound file
/// </summary>
public SectorNumber?[]? DIFAT { get; set; }
/// <remarks>109 entries</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 109)]
public SectorNumber[]? DIFAT;
}
}

View File

@@ -75,7 +75,7 @@ namespace SabreTools.Models.CFB
/// Properties
/// </summary>
/// <remarks>Each Variant might be followed by an index and offset value</remarks>
public Variant?[]? Properties { get; set; }
public Variant[]? Properties { get; set; }
#endregion
}

View File

@@ -1,28 +1,31 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.CHD
{
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.h"/>
public class CompressedMapEntryV5
[StructLayout(LayoutKind.Sequential)]
public sealed class CompressedMapEntryV5
{
/// <summary>
/// Compression type
/// </summary>
public byte Compression { get; set; }
public byte Compression;
/// <summary>
/// Compressed length
/// </summary>
/// <remarks>Actually UInt24</remarks>
public uint CompLength { get; set; }
public uint CompLength;
/// <summary>
/// Offset
/// </summary>
/// <remarks>Actually UInt48</remarks>
public ulong Offset { get; set; }
public ulong Offset;
/// <summary>
/// CRC-16 of the data
/// </summary>
public ushort CRC { get; set; }
public ushort CRC;
}
}

View File

@@ -1,42 +1,45 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.CHD
{
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.h"/>
public class CompressedMapHeaderV5
[StructLayout(LayoutKind.Sequential)]
public sealed class CompressedMapHeaderV5
{
/// <summary>
/// Length of compressed map
/// </summary>
public uint Length { get; set; }
public uint Length;
/// <summary>
/// Offset of first block
/// </summary>
/// <remarks>Actually UInt48</remarks>
public ulong DataStart { get; set; }
public ulong DataStart;
/// <summary>
/// CRC-16 of the map
/// </summary>
public ushort CRC { get; set; }
public ushort CRC;
/// <summary>
/// Bits used to encode complength
/// </summary>
public byte LengthBits { get; set; }
public byte LengthBits;
/// <summary>
/// Bits used to encode self-refs
/// </summary>
public byte HunkBits { get; set; }
public byte HunkBits;
/// <summary>
/// Bits used to encode parent unit refs
/// </summary>
public byte ParentUnitBits { get; set; }
public byte ParentUnitBits;
/// <summary>
/// Future use
/// </summary>
public byte Reserved { get; set; }
public byte Reserved;
}
}

View File

@@ -1,16 +1,19 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.CHD
{
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.h"/>
public class MapV1
[StructLayout(LayoutKind.Sequential)]
public sealed class MapV1
{
/// <summary>
/// Starting offset within the file
/// </summary>
public ulong StartingOffset { get; set; }
public ulong StartingOffset;
/// <summary>
/// Length of data; If == hunksize, data is uncompressed
/// </summary>
public ulong Length { get; set; }
public ulong Length;
}
}

View File

@@ -1,31 +1,34 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.CHD
{
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.h"/>
public class MapV3
[StructLayout(LayoutKind.Sequential)]
public sealed class MapV3
{
/// <summary>
/// Starting offset within the file
/// </summary>
public ulong StartingOffset { get; set; }
public ulong StartingOffset;
/// <summary>
/// 32-bit CRC of the uncompressed data
/// </summary>
public uint CRC32 { get; set; }
public uint CRC32;
/// <summary>
/// Lower 16 bits of length
/// </summary>
public ushort LengthLo { get; set; }
public ushort LengthLo;
/// <summary>
/// Upper 8 bits of length
/// </summary>
public byte LengthHi { get; set; }
public byte LengthHi;
/// <summary>
/// Flags, indicating compression info
/// </summary>
public byte Flags { get; set; }
public byte Flags;
}
}

View File

@@ -1,11 +1,14 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.CHD
{
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.h"/>
[StructLayout(LayoutKind.Sequential)]
public class UncompressedMapV5
{
/// <summary>
/// Starting offset / hunk size
/// </summary>
public uint StartingOffset { get; set; }
public uint StartingOffset;
}
}

View File

@@ -1,6 +1,6 @@
namespace SabreTools.Models.DVD
{
/// <see href="https://dvd.sourceforge.net/dvdinfo/ifo.html"/>
/// <see href="https://dvd.sourceforge.net/dvdinfo/ifo_vmg.html"/>
public sealed class AudioSubPictureAttributesTable
{
/// <summary>
@@ -11,7 +11,7 @@ namespace SabreTools.Models.DVD
/// <summary>
/// Reserved
/// </summary>
public byte[]? Reserved { get; set; }
public ushort Reserved { get; set; }
/// <summary>
/// End address (last byte of last VTS_ATRT)
@@ -21,11 +21,12 @@ namespace SabreTools.Models.DVD
/// <summary>
/// Offset to VTS_ATRT n
/// </summary>
/// <remarks>NumberOfTitleSets entries</remarks>
public uint[]? Offsets { get; set; }
/// <summary>
/// Entries
/// </summary>
public AudioSubPictureAttributesTableEntry?[]? Entries { get; set; }
public AudioSubPictureAttributesTableEntry[]? Entries { get; set; }
}
}

View File

@@ -1,6 +1,6 @@
namespace SabreTools.Models.DVD
{
/// <see href="https://dvd.sourceforge.net/dvdinfo/ifo.html"/>
/// <see href="https://dvd.sourceforge.net/dvdinfo/ifo_vmg.html"/>
public sealed class AudioSubPictureAttributesTableEntry
{
/// <summary>

View File

@@ -11,7 +11,7 @@ namespace SabreTools.Models.DVD
/// <summary>
/// Reserved
/// </summary>
public byte[]? Reserved { get; set; }
public ushort Reserved { get; set; }
/// <summary>
/// End address (last byte of last entry)
@@ -21,6 +21,7 @@ namespace SabreTools.Models.DVD
/// <summary>
/// 12-byte entries
/// </summary>
public CellAddressTableEntry?[]? Entries { get; set; }
/// <remarks>NumberOfVOBIDs entries</remarks>
public CellAddressTableEntry[]? Entries { get; set; }
}
}

View File

@@ -11,7 +11,7 @@ namespace SabreTools.Models.DVD
/// <summary>
/// Reserved
/// </summary>
public byte[]? Reserved { get; set; }
public ushort Reserved { get; set; }
/// <summary>
/// End address (last byte of last PGC in last LU)
@@ -22,11 +22,13 @@ namespace SabreTools.Models.DVD
/// <summary>
/// Language Units
/// </summary>
public LanguageUnitTableEntry?[]? Entries { get; set; }
/// <remarks>NumberOfVOBIDs entries</remarks>
public LanguageUnitTableEntry[]? Entries { get; set; }
/// <summary>
/// Program Chains
/// </summary>
public ProgramChainTable?[]? ProgramChains { get; set; }
/// <remarks>NumberOfVOBIDs entries</remarks>
public ProgramChainTable[]? ProgramChains { get; set; }
}
}

View File

@@ -7,7 +7,7 @@ namespace SabreTools.Models.DVD
public sealed class LanguageUnitTableEntry
{
/// <summary>
/// ISO639 language code
/// ISO639 language code
/// </summary>
public ushort ISO639LanguageCode;

View File

@@ -25,7 +25,7 @@ namespace SabreTools.Models.DVD
/// <summary>
/// Entries
/// </summary>
public ParentalManagementMasksTableEntry?[]? Entries { get; set; }
public ParentalManagementMasksTableEntry[]? Entries { get; set; }
/// <summary>
/// The PTL_MAIT contains the 16-bit masks for the VMG and

View File

@@ -22,6 +22,7 @@ namespace SabreTools.Models.DVD
/// <summary>
/// Program Chains
/// </summary>
public ProgramChainTableEntry?[]? Entries { get; set; }
/// <remarks>NumberOfProgramChains entries</remarks>
public ProgramChainTableEntry[]? Entries { get; set; }
}
}

View File

@@ -21,6 +21,7 @@ namespace SabreTools.Models.DVD
/// <summary>
/// 12-byte entries
/// </summary>
public TitlesTableEntry?[]? Entries { get; set; }
/// <remarks>NumberOfTitles entries</remarks>
public TitlesTableEntry[]? Entries { get; set; }
}
}

View File

@@ -1,4 +1,3 @@
using System.Drawing;
using System.Runtime.InteropServices;
namespace SabreTools.Models.DVD

View File

@@ -1,46 +1,45 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.GCF
{
/// <see href="https://github.com/RavuAlHemio/hllib/blob/master/HLLib/GCFFile.h"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class DirectoryEntry
{
/// <summary>
/// Offset to the directory item name from the end of the directory items.
/// </summary>
public uint NameOffset { get; set; }
/// <summary>
/// Directory item name from the end of the directory items.
/// </summary>
public string? Name { get; set; }
public uint NameOffset;
/// <summary>
/// Size of the item. (If file, file size. If folder, num items.)
/// </summary>
public uint ItemSize { get; set; }
public uint ItemSize;
/// <summary>
/// Checksome index. (0xFFFFFFFF == None).
/// </summary>
public uint ChecksumIndex { get; set; }
public uint ChecksumIndex;
/// <summary>
/// Flags for the directory item. (0x00000000 == Folder).
/// </summary>
public HL_GCF_FLAG DirectoryFlags { get; set; }
[MarshalAs(UnmanagedType.U4)]
public HL_GCF_FLAG DirectoryFlags;
/// <summary>
/// Index of the parent directory item. (0xFFFFFFFF == None).
/// </summary>
public uint ParentIndex { get; set; }
public uint ParentIndex;
/// <summary>
/// Index of the next directory item. (0x00000000 == None).
/// </summary>
public uint NextIndex { get; set; }
public uint NextIndex;
/// <summary>
/// Index of the first directory item. (0x00000000 == None).
/// </summary>
public uint FirstIndex { get; set; }
public uint FirstIndex;
}
}

View File

@@ -0,0 +1,7 @@
namespace SabreTools.Models.InstallShieldArchiveV3
{
public static class Constants
{
public const uint HeaderSignature = 0x8C655D13;
}
}

View File

@@ -6,9 +6,20 @@ namespace SabreTools.Models.InstallShieldArchiveV3
[StructLayout(LayoutKind.Sequential)]
public class Directory
{
/// <summary>
/// Number of files in the directory
/// </summary>
public ushort FileCount;
/// <summary>
/// Size of the chunk
/// </summary>
public ushort ChunkSize;
/// <summary>
/// Byte-length-prefixed ASCII string
/// </summary>
[MarshalAs(UnmanagedType.BStr)]
public string? Name;
public ushort FileCount;
}
}

View File

@@ -8,10 +8,14 @@ namespace SabreTools.Models.InstallShieldCabinet
public const uint SignatureUInt32 = 0x28635349;
public const string HEADER_SUFFIX = "hdr";
public const string CABINET_SUFFIX = "cab";
public const int COMMON_HEADER_SIZE = 20;
public const int VOLUME_HEADER_SIZE_V5 = 40;
public const int VOLUME_HEADER_SIZE_V6 = 64;
// TODO: Determine how the value "71" was chosen here

View File

@@ -3,6 +3,7 @@ using System.Runtime.InteropServices;
namespace SabreTools.Models.InstallShieldCabinet
{
/// <see href="https://github.com/twogood/unshield/blob/main/lib/cabfile.h"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class Descriptor
{
/// <summary>

View File

@@ -24,7 +24,7 @@
/// This defines the length of the string in bytes. The length of each
/// ascii name string is limited to 127 characters.
/// </remarks>
public byte Length { get; set; }
public byte Length { get; set; } // TODO: Remove in lieu of AnsiBStr
/// <summary>
/// ASCII String.

View File

@@ -32,7 +32,7 @@
/// linear EXE module and will be used in the future for parameter type
/// checking.
/// </remarks>
public byte Length { get; set; }
public byte Length { get; set; } // TODO: Remove in lieu of AnsiBStr
/// <summary>
/// ASCII String.

View File

@@ -39,7 +39,7 @@
/// signifies that additional information is contained in the linear EXE module and
/// will be used in the future for parameter type checking.
/// </remarks>
public byte Length { get; set; }
public byte Length { get; set; } // TODO: Remove in lieu of AnsiBStr
/// <summary>
/// ASCII String.

View File

@@ -39,7 +39,7 @@
/// signifies that additional information is contained in the linear EXE module and
/// will be used in the future for parameter type checking.
/// </remarks>
public byte Length { get; set; }
public byte Length { get; set; } // TODO: Remove in lieu of AnsiBStr
/// <summary>
/// ASCII String.

View File

@@ -1,3 +1,5 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.MSDOS
{
/// <summary>
@@ -6,6 +8,7 @@ namespace SabreTools.Models.MSDOS
/// </summary>
/// <see href="https://wiki.osdev.org/MZ"/>
/// <see href="http://www.pinvoke.net/default.aspx/Structures.IMAGE_DOS_HEADER"/>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public sealed class ExecutableHeader
{
#region Standard Fields
@@ -13,23 +16,25 @@ namespace SabreTools.Models.MSDOS
/// <summary>
/// 0x5A4D (ASCII for 'M' and 'Z')
/// </summary>
public string? Magic { get; set; }
/// <remarks>15 bytes</remarks>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 2)]
public string? Magic;
/// <summary>
/// Number of bytes in the last page.
/// </summary>
public ushort LastPageBytes { get; set; }
public ushort LastPageBytes;
/// <summary>
/// Number of whole/partial pages.
/// </summary>
/// <remarks>A page (or block) is 512 bytes long.</remarks>
public ushort Pages { get; set; }
public ushort Pages;
/// <summary>
/// Number of entries in the relocation table.
/// </summary>
public ushort RelocationItems { get; set; }
public ushort RelocationItems;
/// <summary>
/// The number of paragraphs taken up by the header. It can be any value, as the loader
@@ -38,57 +43,57 @@ namespace SabreTools.Models.MSDOS
/// own header metadata, or put the relocation table there, or use it for any other purpose. [08]
/// </summary>
/// <remarks>A paragraph is 16 bytes in size</remarks>
public ushort HeaderParagraphSize { get; set; }
public ushort HeaderParagraphSize;
/// <summary>
/// The number of paragraphs required by the program, excluding the PSP and program image.
/// If no free block is big enough, the loading stops.
/// </summary>
/// <remarks>A paragraph is 16 bytes in size</remarks>
public ushort MinimumExtraParagraphs { get; set; }
public ushort MinimumExtraParagraphs;
/// <summary>
/// The number of paragraphs requested by the program.
/// If no free block is big enough, the biggest one possible is allocated.
/// </summary>
/// <remarks>A paragraph is 16 bytes in size</remarks>
public ushort MaximumExtraParagraphs { get; set; }
public ushort MaximumExtraParagraphs;
/// <summary>
/// Relocatable segment address for SS.
/// </summary>
public ushort InitialSSValue { get; set; }
public ushort InitialSSValue;
/// <summary>
/// Initial value for SP.
/// </summary>
public ushort InitialSPValue { get; set; }
public ushort InitialSPValue;
/// <summary>
/// When added to the sum of all other words in the file, the result should be zero.
/// </summary>
public ushort Checksum { get; set; }
public ushort Checksum;
/// <summary>
/// Initial value for IP. [14]
/// </summary>
public ushort InitialIPValue { get; set; }
public ushort InitialIPValue;
/// <summary>
/// Relocatable segment address for CS.
/// </summary>
public ushort InitialCSValue { get; set; }
public ushort InitialCSValue;
/// <summary>
/// The (absolute) offset to the relocation table.
/// </summary>
public ushort RelocationTableAddr { get; set; }
public ushort RelocationTableAddr;
/// <summary>
/// Value used for overlay management.
/// If zero, this is the main executable.
/// </summary>
public ushort OverlayNumber { get; set; }
public ushort OverlayNumber;
#endregion
@@ -97,27 +102,31 @@ namespace SabreTools.Models.MSDOS
/// <summary>
/// Reserved words
/// </summary>
public ushort[]? Reserved1 { get; set; } = new ushort[4];
/// <remarks>4 entries/remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public ushort[]? Reserved1;
/// <summary>
/// Defined by name but no other information is given; typically zeroes
/// </summary>
public ushort OEMIdentifier { get; set; }
public ushort OEMIdentifier;
/// <summary>
/// Defined by name but no other information is given; typically zeroes
/// </summary>
public ushort OEMInformation { get; set; }
public ushort OEMInformation;
/// <summary>
/// Reserved words
/// </summary>
public ushort[]? Reserved2 { get; set; } = new ushort[10];
/// <remarks>10 entries/remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public ushort[]? Reserved2;
/// <summary>
/// Starting address of the PE header
/// </summary>
public uint NewExeHeaderAddr { get; set; }
public uint NewExeHeaderAddr;
#endregion
}

View File

@@ -1,4 +1,6 @@
namespace SabreTools.Models.MoPaQ
using System.Runtime.InteropServices;
namespace SabreTools.Models.MoPaQ
{
/// <summary>
/// The BET table is present if the BetTablePos64 member of MPQ header is set
@@ -14,7 +16,8 @@
/// <summary>
/// 'BET\x1A'
/// </summary>
public string? Signature { get; set; }
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]
public string? Signature;
/// <summary>
/// Version. Seems to be always 1

View File

@@ -1,4 +1,6 @@
namespace SabreTools.Models.MoPaQ
using System.Runtime.InteropServices;
namespace SabreTools.Models.MoPaQ
{
/// <summary>
/// The HET table is present if the HetTablePos64 member of MPQ header is
@@ -15,7 +17,8 @@
/// <summary>
/// 'HET\x1A'
/// </summary>
public string? Signature { get; set; }
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]
public string? Signature;
/// <summary>
/// Version. Seems to be always 1

View File

@@ -1,35 +1,42 @@
namespace SabreTools.Models.MoPaQ
using System.Runtime.InteropServices;
namespace SabreTools.Models.MoPaQ
{
/// <summary>
/// This structure contains size of the patch, flags and also MD5 of the patch.
/// </summary>
/// <see href="http://zezula.net/en/mpq/mpqformat.html"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class PatchInfo
{
/// <summary>
/// Length of patch info header, in bytes
/// </summary>
public uint Length { get; set; }
public uint Length;
/// <summary>
/// Flags. 0x80000000 = MD5 (?)
/// </summary>
public uint Flags { get; set; }
public uint Flags;
/// <summary>
/// Uncompressed size of the patch file
/// </summary>
public uint DataSize { get; set; }
public uint DataSize;
/// <summary>
/// MD5 of the entire patch file after decompression
/// </summary>
/// <remarks>0x10 bytes</remarks>
public byte[]? MD5 { get; set; }
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x10)]
public byte[]? MD5;
/// <summary>
/// The sector offset table (variable length)
/// </summary>
public uint[]? SectorOffsetTable { get; set; }
/// <remarks>0 entries</remarks>
/// TODO: Determine the number of entries
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0)]
public uint[]? SectorOffsetTable;
}
}

View File

@@ -1,4 +1,6 @@
namespace SabreTools.Models.MoPaQ
using System.Runtime.InteropServices;
namespace SabreTools.Models.MoPaQ
{
/// <summary>
/// MPQ User Data are optional, and is commonly used in custom maps for
@@ -6,28 +8,31 @@
/// from where the MPQ header should be searched.
/// </summary>
/// <see href="http://zezula.net/en/mpq/mpqformat.html"/>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public sealed class UserData
{
/// <summary>
/// The user data signature
/// </summary>
/// <see cref="SignatureValue"/>
public string? Signature { get; set; }
/// <remarks>4 bytes</remarks>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]
public string? Signature;
/// <summary>
/// Maximum size of the user data
/// </summary>
public uint UserDataSize { get; set; }
public uint UserDataSize;
/// <summary>
/// Offset of the MPQ header, relative to the beginning of this header
/// </summary>
public uint HeaderOffset { get; set; }
public uint HeaderOffset;
/// <summary>
/// Appears to be size of user data header (Starcraft II maps)
/// </summary>
public uint UserDataHeaderSize { get; set; }
public uint UserDataHeaderSize;
// TODO: Does this area contain extra data that should be read in?
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -21,6 +21,7 @@
/// <summary>
/// Reserved
/// </summary>
/// <remarks>0x20 bytes</remarks>
public byte[]? Reserved { get; set; }
/// <summary>

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -1,46 +1,45 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.NCF
{
/// <see href="https://github.com/RavuAlHemio/hllib/blob/master/HLLib/NCFFile.h"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class DirectoryEntry
{
/// <summary>
/// Offset to the directory item name from the end of the directory items.
/// </summary>
public uint NameOffset { get; set; }
/// <summary>
/// Directory item name from the end of the directory items.
/// </summary>
public string? Name { get; set; }
public uint NameOffset;
/// <summary>
/// Size of the item. (If file, file size. If folder, num items.)
/// </summary>
public uint ItemSize { get; set; }
public uint ItemSize;
/// <summary>
/// Checksome index. (0xFFFFFFFF == None).
/// </summary>
public uint ChecksumIndex { get; set; }
public uint ChecksumIndex;
/// <summary>
/// Flags for the directory item. (0x00000000 == Folder).
/// </summary>
public HL_NCF_FLAG DirectoryFlags { get; set; }
[MarshalAs(UnmanagedType.U4)]
public HL_NCF_FLAG DirectoryFlags;
/// <summary>
/// Index of the parent directory item. (0xFFFFFFFF == None).
/// </summary>
public uint ParentIndex { get; set; }
public uint ParentIndex;
/// <summary>
/// Index of the next directory item. (0x00000000 == None).
/// </summary>
public uint NextIndex { get; set; }
public uint NextIndex;
/// <summary>
/// Index of the first directory item. (0x00000000 == None).
/// </summary>
public uint FirstIndex { get; set; }
public uint FirstIndex;
}
}

View File

@@ -26,7 +26,7 @@ namespace SabreTools.Models.NewExecutable
/// <summary>
/// Segment table
/// </summary>
public SegmentTableEntry?[]? SegmentTable { get; set; }
public SegmentTableEntry[]? SegmentTable { get; set; }
/// <summary>
/// Resource table
@@ -36,26 +36,26 @@ namespace SabreTools.Models.NewExecutable
/// <summary>
/// Resident-Name table
/// </summary>
public ResidentNameTableEntry?[]? ResidentNameTable { get; set; }
public ResidentNameTableEntry[]? ResidentNameTable { get; set; }
/// <summary>
/// Module-Reference table
/// </summary>
public ModuleReferenceTableEntry?[]? ModuleReferenceTable { get; set; }
public ModuleReferenceTableEntry[]? ModuleReferenceTable { get; set; }
/// <summary>
/// Imported-Name table
/// </summary>
public Dictionary<ushort, ImportedNameTableEntry?>? ImportedNameTable { get; set; }
public Dictionary<ushort, ImportedNameTableEntry>? ImportedNameTable { get; set; }
/// <summary>
/// Entry table
/// </summary>
public EntryTableBundle?[]? EntryTable { get; set; }
public EntryTableBundle[]? EntryTable { get; set; }
/// <summary>
/// Nonresident-Name table
/// </summary>
public NonResidentNameTableEntry?[]? NonResidentNameTable { get; set; }
public NonResidentNameTableEntry[]? NonResidentNameTable { get; set; }
}
}

View File

@@ -15,7 +15,7 @@
/// Length of the name string that follows. A zero value indicates
/// the end of the name table.
/// </summary>
public byte Length { get; set; }
public byte Length { get; set; } // TODO: Remove in lieu of AnsiBStr
/// <summary>
/// ASCII text of the name string.

View File

@@ -15,7 +15,7 @@
/// Length of the name string that follows. A zero value indicates
/// the end of the name table.
/// </summary>
public byte Length { get; set; }
public byte Length { get; set; } // TODO: Remove in lieu of AnsiBStr
/// <summary>
/// ASCII text of the name string.

View File

@@ -14,7 +14,7 @@
/// Length of the name string that follows. A zero value indicates
/// the end of the name table.
/// </summary>
public byte Length { get; set; }
public byte Length { get; set; } // TODO: Remove in lieu of AnsiBStr
/// <summary>
/// ASCII text of the name string.

View File

@@ -13,7 +13,7 @@
/// indicates the end of the resource type and name string, also
/// the end of the resource table.
/// </summary>
public byte Length { get; set; }
public byte Length { get; set; } // TODO: Remove in lieu of AnsiBStr
/// <summary>
/// ASCII text of the type or name string.

View File

@@ -1,214 +1,232 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.Nitro
{
/// <summary>
/// Nintendo DS / DSi cartridge header
/// </summary>
/// <see href="https://dsibrew.org/wiki/DSi_cartridge_header"/>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public sealed class CommonHeader
{
/// <summary>
/// Game Title
/// </summary>
public string? GameTitle { get; set; }
/// <remarks>12 bytes</remarks>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 12)]
public string? GameTitle;
/// <summary>
/// Gamecode
/// </summary>
public uint GameCode { get; set; }
public uint GameCode;
/// <summary>
/// Makercode
/// </summary>
public string? MakerCode { get; set; }
/// <remarks>2 bytes</remarks>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 2)]
public string? MakerCode;
/// <summary>
/// Unitcode
/// </summary>
public Unitcode UnitCode { get; set; }
[MarshalAs(UnmanagedType.U1)]
public Unitcode UnitCode;
/// <summary>
/// Encryption seed select (device code. 0 = normal)
/// </summary>
public byte EncryptionSeedSelect { get; set; }
public byte EncryptionSeedSelect;
/// <summary>
/// Devicecapacity
/// </summary>
public byte DeviceCapacity { get; set; }
public byte DeviceCapacity;
/// <summary>
/// Reserved
/// </summary>
public byte[]? Reserved1 { get; set; }
/// <remarks>7 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)]
public byte[]? Reserved1;
/// <summary>
/// Game Revision (used by DSi titles)
/// </summary>
public ushort GameRevision { get; set; }
public ushort GameRevision;
/// <summary>
/// ROM Version
/// </summary>
public byte RomVersion { get; set; }
public byte RomVersion;
/// <summary>
/// Internal flags, (Bit2: Autostart)
/// </summary>
public byte InternalFlags { get; set; }
public byte InternalFlags;
/// <summary>
/// ARM9 rom offset
/// </summary>
public uint ARM9RomOffset { get; set; }
public uint ARM9RomOffset;
/// <summary>
/// ARM9 entry address
/// </summary>
public uint ARM9EntryAddress { get; set; }
public uint ARM9EntryAddress;
/// <summary>
/// ARM9 load address
/// </summary>
public uint ARM9LoadAddress { get; set; }
public uint ARM9LoadAddress;
/// <summary>
/// ARM9 size
/// </summary>
public uint ARM9Size { get; set; }
public uint ARM9Size;
/// <summary>
/// ARM7 rom offset
/// </summary>
public uint ARM7RomOffset { get; set; }
public uint ARM7RomOffset;
/// <summary>
/// ARM7 entry address
/// </summary>
public uint ARM7EntryAddress { get; set; }
public uint ARM7EntryAddress;
/// <summary>
/// ARM7 load address
/// </summary>
public uint ARM7LoadAddress { get; set; }
public uint ARM7LoadAddress;
/// <summary>
/// ARM7 size
/// </summary>
public uint ARM7Size { get; set; }
public uint ARM7Size;
/// <summary>
/// File Name Table (FNT) offset
/// </summary>
public uint FileNameTableOffset { get; set; }
public uint FileNameTableOffset;
/// <summary>
/// File Name Table (FNT) length
/// </summary>
public uint FileNameTableLength { get; set; }
public uint FileNameTableLength;
/// <summary>
/// File Allocation Table (FNT) offset
/// </summary>
public uint FileAllocationTableOffset { get; set; }
public uint FileAllocationTableOffset;
/// <summary>
/// File Allocation Table (FNT) length
/// </summary>
public uint FileAllocationTableLength { get; set; }
public uint FileAllocationTableLength;
/// <summary>
/// File Name Table (FNT) offset
/// </summary>
public uint ARM9OverlayOffset { get; set; }
public uint ARM9OverlayOffset;
/// <summary>
/// File Name Table (FNT) length
/// </summary>
public uint ARM9OverlayLength { get; set; }
public uint ARM9OverlayLength;
/// <summary>
/// File Name Table (FNT) offset
/// </summary>
public uint ARM7OverlayOffset { get; set; }
public uint ARM7OverlayOffset;
/// <summary>
/// File Name Table (FNT) length
/// </summary>
public uint ARM7OverlayLength { get; set; }
public uint ARM7OverlayLength;
/// <summary>
/// Normal card control register settings (0x00416657 for OneTimePROM)
/// </summary>
public uint NormalCardControlRegisterSettings { get; set; }
public uint NormalCardControlRegisterSettings;
/// <summary>
/// Secure card control register settings (0x081808F8 for OneTimePROM)
/// </summary>
public uint SecureCardControlRegisterSettings { get; set; }
public uint SecureCardControlRegisterSettings;
/// <summary>
/// Icon Banner offset (NDSi same as NDS, but with new extra entries)
/// </summary>
public uint IconBannerOffset { get; set; }
public uint IconBannerOffset;
/// <summary>
/// Secure area (2K) CRC
/// </summary>
public ushort SecureAreaCRC { get; set; }
public ushort SecureAreaCRC;
/// <summary>
/// Secure transfer timeout (0x0D7E for OneTimePROM)
/// </summary>
public ushort SecureTransferTimeout { get; set; }
public ushort SecureTransferTimeout;
/// <summary>
/// ARM9 autoload
/// </summary>
public uint ARM9Autoload { get; set; }
public uint ARM9Autoload;
/// <summary>
/// ARM7 autoload
/// </summary>
public uint ARM7Autoload { get; set; }
public uint ARM7Autoload;
/// <summary>
/// Secure disable
/// </summary>
public byte[]? SecureDisable { get; set; }
/// <remarks>8 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[]? SecureDisable;
/// <summary>
/// NTR region ROM size (excluding DSi area)
/// </summary>
public uint NTRRegionRomSize { get; set; }
public uint NTRRegionRomSize;
/// <summary>
/// Header size
/// </summary>
public uint HeaderSize { get; set; }
public uint HeaderSize;
/// <summary>
///Reserved (0x88, 0x8C, 0x90 = Unknown, used by DSi)
/// Reserved (0x88, 0x8C, 0x90 = Unknown, used by DSi)
/// </summary>
public byte[]? Reserved2 { get; set; }
/// <remarks>56 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 56)]
public byte[]? Reserved2;
/// <summary>
/// Nintendo Logo
/// </summary>
public byte[]? NintendoLogo { get; set; }
/// <remarks>156 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 156)]
public byte[]? NintendoLogo;
/// <summary>
/// Nintendo Logo CRC
/// </summary>
public ushort NintendoLogoCRC { get; set; }
public ushort NintendoLogoCRC;
/// <summary>
/// Header CRC
/// </summary>
public ushort HeaderCRC { get; set; }
public ushort HeaderCRC;
/// <summary>
/// Debugger reserved
/// </summary>
public byte[]? DebuggerReserved { get; set; }
/// <remarks>0x20 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)]
public byte[]? DebuggerReserved;
}
}

View File

@@ -1,259 +1,298 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.Nitro
{
/// <summary>
/// Nintendo DSi extended cart header
/// </summary>
/// <see href="https://dsibrew.org/wiki/DSi_cartridge_header"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class ExtendedDSiHeader
{
/// <summary>
/// Global MBK1..MBK5 Settings
/// </summary>
public uint[]? GlobalMBK15Settings { get; set; }
/// <remarks>5 entries</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public uint[]? GlobalMBK15Settings;
/// <summary>
/// Local MBK6..MBK8 Settings for ARM9
/// </summary>
public uint[]? LocalMBK68SettingsARM9 { get; set; }
/// <remarks>3 entries</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public uint[]? LocalMBK68SettingsARM9;
/// <summary>
/// Local MBK6..MBK8 Settings for ARM7
/// </summary>
public uint[]? LocalMBK68SettingsARM7 { get; set; }
/// <remarks>3 entries</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public uint[]? LocalMBK68SettingsARM7;
/// <summary>
/// Global MBK9 Setting
/// </summary>
public uint GlobalMBK9Setting { get; set; }
public uint GlobalMBK9Setting;
/// <summary>
/// Region Flags
/// </summary>
public uint RegionFlags { get; set; }
public uint RegionFlags;
/// <summary>
/// Access control
/// </summary>
public uint AccessControl { get; set; }
public uint AccessControl;
/// <summary>
/// ARM7 SCFG EXT mask (controls which devices to enable)
/// </summary>
public uint ARM7SCFGEXTMask { get; set; }
public uint ARM7SCFGEXTMask;
/// <summary>
/// Reserved/flags? When bit2 of byte 0x1bf is set, usage of banner.sav from the title data dir is enabled.(additional banner data)
/// </summary>
public uint ReservedFlags { get; set; }
public uint ReservedFlags;
/// <summary>
/// ARM9i rom offset
/// </summary>
public uint ARM9iRomOffset { get; set; }
public uint ARM9iRomOffset;
/// <summary>
/// Reserved
/// </summary>
public uint Reserved3 { get; set; }
public uint Reserved3;
/// <summary>
/// ARM9i load address
/// </summary>
public uint ARM9iLoadAddress { get; set; }
public uint ARM9iLoadAddress;
/// <summary>
/// ARM9i size { get; set; }
/// ARM9i size;
/// </summary>
public uint ARM9iSize { get; set; }
public uint ARM9iSize;
/// <summary>
/// ARM7i rom offset
/// </summary>
public uint ARM7iRomOffset { get; set; }
public uint ARM7iRomOffset;
/// <summary>
/// Pointer to base address where various structures and parameters are passed to the title - what is that???
/// </summary>
public uint Reserved4 { get; set; }
public uint Reserved4;
/// <summary>
/// ARM7i load address
/// </summary>
public uint ARM7iLoadAddress { get; set; }
public uint ARM7iLoadAddress;
/// <summary>
/// ARM7i size { get; set; }
/// ARM7i size;
/// </summary>
public uint ARM7iSize { get; set; }
public uint ARM7iSize;
/// <summary>
/// Digest NTR region offset
/// </summary>
public uint DigestNTRRegionOffset { get; set; }
public uint DigestNTRRegionOffset;
/// <summary>
/// Digest NTR region length
/// </summary>
public uint DigestNTRRegionLength { get; set; }
public uint DigestNTRRegionLength;
// <summary>
/// Digest TWL region offset
/// </summary>
public uint DigestTWLRegionOffset { get; set; }
public uint DigestTWLRegionOffset;
/// <summary>
/// Digest TWL region length
/// </summary>
public uint DigestTWLRegionLength { get; set; }
public uint DigestTWLRegionLength;
// <summary>
/// Digest Sector Hashtable region offset
/// </summary>
public uint DigestSectorHashtableRegionOffset { get; set; }
public uint DigestSectorHashtableRegionOffset;
/// <summary>
/// Digest Sector Hashtable region length
/// </summary>
public uint DigestSectorHashtableRegionLength { get; set; }
public uint DigestSectorHashtableRegionLength;
// <summary>
/// Digest Block Hashtable region offset
/// </summary>
public uint DigestBlockHashtableRegionOffset { get; set; }
public uint DigestBlockHashtableRegionOffset;
/// <summary>
/// Digest Block Hashtable region length
/// </summary>
public uint DigestBlockHashtableRegionLength { get; set; }
public uint DigestBlockHashtableRegionLength;
/// <summary>
/// Digest Sector size
/// </summary>
public uint DigestSectorSize { get; set; }
public uint DigestSectorSize;
/// <summary>
/// Digeset Block Sectorount
/// </summary>
public uint DigestBlockSectorCount { get; set; }
public uint DigestBlockSectorCount;
/// <summary>
/// Icon Banner Size (usually 0x23C0)
/// </summary>
public uint IconBannerSize { get; set; }
public uint IconBannerSize;
/// <summary>
/// Unknown (used by DSi)
/// </summary>
public uint Unknown1 { get; set; }
public uint Unknown1;
/// <summary>
/// NTR+TWL region ROM size (total size including DSi area)
/// </summary>
public uint NTRTWLRegionRomSize { get; set; }
public uint NTRTWLRegionRomSize;
/// <summary>
/// Unknown (used by DSi)
/// </summary>
public byte[]? Unknown2 { get; set; }
/// <remarks>12 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public byte[]? Unknown2;
/// <summary>
/// Modcrypt area 1 offset
/// </summary>
public uint ModcryptArea1Offset { get; set; }
public uint ModcryptArea1Offset;
/// <summary>
/// Modcrypt area 1 size
/// </summary>
public uint ModcryptArea1Size { get; set; }
public uint ModcryptArea1Size;
/// <summary>
/// Modcrypt area 2 offset
/// </summary>
public uint ModcryptArea2Offset { get; set; }
public uint ModcryptArea2Offset;
/// <summary>
/// Modcrypt area 2 size
/// </summary>
public uint ModcryptArea2Size { get; set; }
public uint ModcryptArea2Size;
/// <summary>
/// Title ID
/// </summary>
public byte[]? TitleID { get; set; }
/// <remarks>8 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[]? TitleID;
/// <summary>
/// DSiWare: "public.sav" size
/// </summary>
public uint DSiWarePublicSavSize { get; set; }
public uint DSiWarePublicSavSize;
/// <summary>
/// DSiWare: "private.sav" size
/// </summary>
public uint DSiWarePrivateSavSize { get; set; }
public uint DSiWarePrivateSavSize;
/// <summary>
/// Reserved (zero)
/// </summary>
public byte[]? ReservedZero { get; set; }
/// <remarks>176 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 176)]
public byte[]? ReservedZero;
/// <summary>
/// Unknown (used by DSi)
/// </summary>
public byte[]? Unknown3 { get; set; }
/// <remarks>16 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[]? Unknown3;
/// <summary>
/// ARM9 (with encrypted secure area) SHA1 HMAC hash
/// </summary>
public byte[]? ARM9WithSecureAreaSHA1HMACHash { get; set; }
/// <remarks>20 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[]? ARM9WithSecureAreaSHA1HMACHash;
/// <summary>
/// ARM7 SHA1 HMAC hash
/// </summary>
public byte[]? ARM7SHA1HMACHash { get; set; }
/// <remarks>20 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[]? ARM7SHA1HMACHash;
/// <summary>
/// Digest master SHA1 HMAC hash
/// </summary>
public byte[]? DigestMasterSHA1HMACHash { get; set; }
/// <remarks>20 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[]? DigestMasterSHA1HMACHash;
/// <summary>
/// Banner SHA1 HMAC hash
/// </summary>
public byte[]? BannerSHA1HMACHash { get; set; }
/// <remarks>20 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[]? BannerSHA1HMACHash;
/// <summary>
/// ARM9i (decrypted) SHA1 HMAC hash
/// </summary>
public byte[]? ARM9iDecryptedSHA1HMACHash { get; set; }
/// <remarks>20 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[]? ARM9iDecryptedSHA1HMACHash;
/// <summary>
/// ARM7i (decrypted) SHA1 HMAC hash
/// </summary>
public byte[]? ARM7iDecryptedSHA1HMACHash { get; set; }
/// <remarks>20 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[]? ARM7iDecryptedSHA1HMACHash;
/// <summary>
/// Reserved
/// </summary>
public byte[]? Reserved5 { get; set; }
/// <remarks>40 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
public byte[]? Reserved5;
/// <summary>
/// ARM9 (without secure area) SHA1 HMAC hash
/// </summary>
public byte[]? ARM9NoSecureAreaSHA1HMACHash { get; set; }
/// <remarks>20 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[]? ARM9NoSecureAreaSHA1HMACHash;
/// <summary>
/// Reserved
/// </summary>
public byte[]? Reserved6 { get; set; }
/// <remarks>2636 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2636)]
public byte[]? Reserved6;
/// <summary>
/// Reserved and unchecked region, always zero. Used for passing arguments in debug environment.
/// </summary>
public byte[]? ReservedAndUnchecked { get; set; }
/// <remarks>0x180 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x180)]
public byte[]? ReservedAndUnchecked;
/// <summary>
/// RSA signature (the first 0xE00 bytes of the header are signed with an 1024-bit RSA signature).
/// </summary>
public byte[]? RSASignature { get; set; }
/// <remarks>0x80 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x80)]
public byte[]? RSASignature;
}
}

View File

@@ -1,3 +1,5 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.Nitro
{
/// <summary>
@@ -5,16 +7,17 @@ namespace SabreTools.Models.Nitro
/// it's just a table of 8 byte entries
/// </summary>
/// <see href="https://github.com/Deijin27/RanseiLink/wiki/NDS-File-System"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class FileAllocationTableEntry
{
/// <summary>
/// Start offset of file
/// </summary>
public uint StartOffset { get; set; }
public uint StartOffset;
/// <summary>
/// End offset of file (after this is padding)
/// </summary>
public uint EndOffset { get; set; }
public uint EndOffset;
}
}

View File

@@ -1,3 +1,5 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.Nitro
{
/// <summary>
@@ -6,28 +8,29 @@ namespace SabreTools.Models.Nitro
/// point to the file system.
/// </summary>
/// <see href="https://github.com/Deijin27/RanseiLink/wiki/NDS-File-System"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class FolderAllocationTableEntry
{
/// <summary>
/// Start offset of folder contents within Name List
/// relative to start of NameTable
/// </summary>
public uint StartOffset { get; set; }
public uint StartOffset;
/// <summary>
/// Index of first file within folder in File Allocation Table
/// </summary>
public ushort FirstFileIndex { get; set; }
public ushort FirstFileIndex;
/// <summary>
/// Index of parent folder in current table; for root folder
/// this holds the number of entries in the table
/// </summary>
public byte ParentFolderIndex { get; set; }
public byte ParentFolderIndex;
/// <summary>
/// Unknown, always 0xF0 except for root folder
/// </summary>
public byte Unknown { get; set; }
public byte Unknown;
}
}

View File

@@ -1,12 +1,9 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.PortableExecutable
namespace SabreTools.Models.PortableExecutable
{
/// <summary>
/// Type or Offset field entry is a WORD (2 bytes).
/// </summary>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/debug/pe-format"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class BaseRelocationTypeOffsetFieldEntry
{
/// <summary>

View File

@@ -1,9 +1,12 @@
namespace SabreTools.Models.PortableExecutable
using System.Runtime.InteropServices;
namespace SabreTools.Models.PortableExecutable
{
/// <summary>
/// One hint/name table suffices for the entire import section.
/// </summary>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/debug/pe-format"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class HintNameTableEntry
{
/// <summary>
@@ -11,13 +14,14 @@
/// with this value. If it fails, a binary search is performed on the DLL's
/// export name pointer table.
/// </summary>
public ushort Hint { get; set; }
public ushort Hint;
/// <summary>
/// An ASCII string that contains the name to import. This is the string that
/// must be matched to the public name in the DLL. This string is case sensitive
/// and terminated by a null byte.
/// </summary>
public string? Name { get; set; }
[MarshalAs(UnmanagedType.LPStr)]
public string? Name;
}
}

View File

@@ -1,62 +1,9 @@
namespace SabreTools.Models.PortableExecutable
{
/// <summary>
/// Contains information about each item in a menu resource that does not open a menu
/// or a submenu. The structure definition provided here is for explanation only; it
/// is not present in any standard header file.
///
/// Contains information about the menu items in a menu resource that open a menu
/// or a submenu. The structure definition provided here is for explanation only;
/// it is not present in any standard header file.
/// Common base class for menu item types
/// </summary>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/menurc/normalmenuitem"/>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/menurc/popupmenuitem"/>
public sealed class MenuItem
{
#region NORMALMENUITEM
/// <summary>
/// The type of menu item.
/// </summary>
public MenuFlags NormalResInfo { get; set; }
/// <summary>
/// A null-terminated Unicode string that contains the text for this menu item.
/// There is no fixed limit on the size of this string.
/// </summary>
public string? NormalMenuText { get; set; }
#endregion
#region POPUPMENUITEM
/// <summary>
/// Describes the menu item.
/// </summary>
public MenuFlags PopupItemType { get; set; }
/// <summary>
/// Describes the menu item.
/// </summary>
public MenuFlags PopupState { get; set; }
/// <summary>
/// A numeric expression that identifies the menu item that is passed in the
/// WM_COMMAND message.
/// </summary>
public uint PopupID { get; set; }
/// <summary>
/// A set of bit flags that specify the type of menu item.
/// </summary>
public MenuFlags PopupResInfo { get; set; }
/// <summary>
/// A null-terminated Unicode string that contains the text for this menu item.
/// There is no fixed limit on the size of this string.
/// </summary>
public string? PopupMenuText { get; set; }
#endregion
}
public abstract class MenuItem { }
}

View File

@@ -35,8 +35,9 @@ namespace SabreTools.Models.PortableExecutable
/// <summary>
/// Null-terminated name of the PDB file. It can also contain full
/// or partial path to the file.
/// or partial path to the file.
/// </summary>
/// <remarks>Is this Unicode?</remarks>
[MarshalAs(UnmanagedType.LPStr)]
public string? PdbFileName;
}

View File

@@ -0,0 +1,27 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.PortableExecutable
{
/// <summary>
/// Contains information about each item in a menu resource that does not open a menu
/// or a submenu. The structure definition provided here is for explanation only; it
/// is not present in any standard header file.
/// </summary>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/menurc/normalmenuitem"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class NormalMenuItem : MenuItem
{
/// <summary>
/// The type of menu item.
/// </summary>
[MarshalAs(UnmanagedType.U2)]
public MenuFlags NormalResInfo;
/// <summary>
/// A null-terminated Unicode string that contains the text for this menu item.
/// There is no fixed limit on the size of this string.
/// </summary>
[MarshalAs(UnmanagedType.LPWStr)]
public string? NormalMenuText;
}
}

View File

@@ -0,0 +1,45 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.PortableExecutable
{
/// <summary>
/// Contains information about the menu items in a menu resource that open a menu
/// or a submenu. The structure definition provided here is for explanation only;
/// it is not present in any standard header file.
/// </summary>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/menurc/popupmenuitem"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class PopupMenuItem : MenuItem
{
/// <summary>
/// Describes the menu item.
/// </summary>
[MarshalAs(UnmanagedType.U4)]
public MenuFlags PopupItemType;
/// <summary>
/// Describes the menu item.
/// </summary>
[MarshalAs(UnmanagedType.U4)]
public MenuFlags PopupState;
/// <summary>
/// A numeric expression that identifies the menu item that is passed in the
/// WM_COMMAND message.
/// </summary>
public uint PopupID;
/// <summary>
/// A set of bit flags that specify the type of menu item.
/// </summary>
[MarshalAs(UnmanagedType.U4)]
public MenuFlags PopupResInfo;
/// <summary>
/// A null-terminated Unicode string that contains the text for this menu item.
/// There is no fixed limit on the size of this string.
/// </summary>
[MarshalAs(UnmanagedType.LPWStr)]
public string? PopupMenuText;
}
}

View File

@@ -1,4 +1,5 @@
using System;
using System.Runtime.InteropServices;
namespace SabreTools.Models.PortableExecutable
{
@@ -7,28 +8,30 @@ namespace SabreTools.Models.PortableExecutable
/// or "DS" type which are emitted by Miscrosoft's link.exe from version 7 and above.
/// </summary>
/// <see href="http://www.godevtool.com/Other/pdb.htm"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class RSDSProgramDatabase
{
/// <summary>
/// "RSDS" signature
/// </summary>
public uint Signature { get; set; }
public uint Signature;
/// <summary>
/// 16-byte Globally Unique Identifier
/// </summary>
public Guid GUID { get; set; }
public Guid GUID;
/// <summary>
/// Ever-incrementing value, which is initially set to 1 and
/// incremented every time when a part of the PDB file is updated
/// without rewriting the whole file.
/// </summary>
public uint Age { get; set; }
public uint Age;
/// <summary>
/// zero terminated UTF8 path and file name
/// </summary>
public string? PathAndFileName { get; set; }
[MarshalAs(UnmanagedType.LPWStr)]
public string? PathAndFileName;
}
}

View File

@@ -13,7 +13,7 @@
/// <summary>
/// The size of the string, not including length field itself.
/// </summary>
public ushort Length { get; set; }
public ushort Length { get; set; } // TODO: Remove in lieu of BStr
/// <summary>
/// The variable-length Unicode string data, word-aligned.

View File

@@ -1,4 +1,6 @@
namespace SabreTools.Models.PortableExecutable
using System.Runtime.InteropServices;
namespace SabreTools.Models.PortableExecutable
{
/// <summary>
/// Overlay data associated with SecuROM executables
@@ -15,7 +17,7 @@
/// </summary>
public uint Signature { get; set; }
/// <summary>
/// <summary>s
/// Unknown (Entry count?)
/// </summary>
/// <remarks>
@@ -27,12 +29,14 @@
/// <summary>
/// Version, always 8 bytes?
/// </summary>
public string? Version { get; set; }
[MarshalAs(UnmanagedType.LPStr)]
public string? Version;
/// <summary>
/// Unknown (Build? Formatted as a string)
/// </summary>
public char[]? Build { get; set; }
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public char[]? Build;
/// <summary>
/// Unknown (0x14h), Variable number of bytes before entry table

View File

@@ -64,7 +64,7 @@ namespace SabreTools.Models.PortableExecutable
/// Entry file name (null-terminated)
/// </summary>
/// <remarks>12 bytes long in the sample (all 3 entries) in 4.47.00.0039</remarks>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 12)]
[MarshalAs(UnmanagedType.LPStr)]
public string? FileName;
/// <summary>

View File

@@ -7,7 +7,7 @@
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>1.4.3</Version>
<Version>1.4.5</Version>
<WarningsNotAsErrors>CS0618</WarningsNotAsErrors>
<!-- Package Properties -->

View File

@@ -3,7 +3,7 @@ using System.Runtime.InteropServices;
namespace SabreTools.Models.VBSP
{
/// <see href="https://github.com/RavuAlHemio/hllib/blob/master/HLLib/VBSPFile.h"/>
[StructLayout(LayoutKind.Sequential)]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public sealed class Lump
{
public uint Offset;

View File

@@ -1,17 +1,21 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.VPK
{
/// <see href="https://github.com/RavuAlHemio/hllib/blob/master/HLLib/VPKFile.h"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class ArchiveHash
{
public uint ArchiveIndex { get; set; }
public uint ArchiveIndex;
public uint ArchiveOffset { get; set; }
public uint ArchiveOffset;
public uint Length { get; set; }
public uint Length;
/// <summary>
/// MD5
/// </summary>
public byte[]? Hash { get; set; }
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x10)]
public byte[]? Hash;
}
}

View File

@@ -1,12 +1,26 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.WAD
{
/// <see href="https://github.com/RavuAlHemio/hllib/blob/master/HLLib/WADFile.h"/>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public sealed class Header
{
public string? Signature { get; set; }
public uint LumpCount { get; set; }
public uint LumpOffset { get; set; }
/// <summary>
/// "WAD3"
/// </summary>
/// <remarks>4 bytes</remarks>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]
public string? Signature;
/// <summary>
/// Number of lumps in the file
/// </summary>
public uint LumpCount;
/// <summary>
/// Offset where lumps are stored
/// </summary>
public uint LumpOffset;
}
}

View File

@@ -1,22 +1,27 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.WAD
{
/// <see href="https://github.com/RavuAlHemio/hllib/blob/master/HLLib/WADFile.h"/>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public sealed class Lump
{
public uint Offset { get; set; }
public uint Offset;
public uint DiskLength { get; set; }
public uint DiskLength;
public uint Length { get; set; }
public uint Length;
public byte Type { get; set; }
public byte Type;
public byte Compression { get; set; }
public byte Compression;
public byte Padding0 { get; set; }
public byte Padding0;
public byte Padding1 { get; set; }
public byte Padding1;
public string? Name { get; set; }
/// <remarks>16 bytes</remarks>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string? Name;
}
}

View File

@@ -1,22 +1,38 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.WAD
{
/// <see href="https://github.com/RavuAlHemio/hllib/blob/master/HLLib/WADFile.h"/>
public sealed class LumpInfo
{
public string? Name { get; set; }
/// <summary>
/// Type 0x42 has no name, type 0x43 does
/// </summary>
/// <remarks>16 bytes</remarks>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string? Name;
public uint Width { get; set; }
public uint Width;
public uint Height { get; set; }
public uint Height;
public uint PixelOffset { get; set; }
public uint PixelOffset;
// 12 bytes of unknown data
/// <summary>
/// Unknown data
/// </summary>
/// <remarks>12 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public byte[]? UnknownData;
/// <remarks>Width * Height bytes located at PixelOffset</remarks>
public byte[]? PixelData { get; set; }
// TODO: Determine what mipmap data looks like
public uint PaletteSize { get; set; }
/// <remarks>PaletteSize * 3 bytes</remarks>
public byte[]? PaletteData { get; set; }
}
}

View File

@@ -1,10 +1,18 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.XZP
{
/// <see href="https://github.com/RavuAlHemio/hllib/blob/master/HLLib/XZPFile.h"/>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public sealed class Footer
{
public uint FileLength { get; set; }
public uint FileLength;
public string? Signature { get; set; }
/// <summary>
/// "tFzX"
/// </summary>
/// <remarks>4 bytes</remarks>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]
public string? Signature;
}
}

View File

@@ -1,24 +1,32 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.XZP
{
/// <see href="https://github.com/RavuAlHemio/hllib/blob/master/HLLib/XZPFile.h"/>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public sealed class Header
{
public string? Signature { get; set; }
/// <summary>
/// "piZx"
/// </summary>
/// <remarks>4 bytes</remarks>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]
public string? Signature;
public uint Version { get; set; }
public uint Version;
public uint PreloadDirectoryEntryCount { get; set; }
public uint PreloadDirectoryEntryCount;
public uint DirectoryEntryCount { get; set; }
public uint DirectoryEntryCount;
public uint PreloadBytes { get; set; }
public uint PreloadBytes;
public uint HeaderLength { get; set; }
public uint HeaderLength;
public uint DirectoryItemCount { get; set; }
public uint DirectoryItemCount;
public uint DirectoryItemOffset { get; set; }
public uint DirectoryItemOffset;
public uint DirectoryItemLength { get; set; }
public uint DirectoryItemLength;
}
}

View File

@@ -8,7 +8,7 @@
# Optional parameters
NO_BUILD=false
while getopts "uba" OPTION
while getopts "b" OPTION
do
case $OPTION in
b)