Migrate non-executable models to Serialization

This commit is contained in:
Matt Nadareski
2025-09-26 11:57:24 -04:00
parent f101df48ae
commit 19e9734a6f
108 changed files with 0 additions and 7181 deletions

View File

@@ -1,38 +0,0 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BMP
{
/// <summary>
/// The BITMAPFILEHEADER structure contains information about the type, size,
/// and layout of a file that contains a DIB.
/// </summary>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapfileheader"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class BITMAPFILEHEADER
{
/// <summary>
/// The file type; must be BM.
/// </summary>
public ushort Type;
/// <summary>
/// The size, in bytes, of the bitmap file.
/// </summary>
public uint Size;
/// <summary>
/// Reserved; must be zero.
/// </summary>
public ushort Reserved1;
/// <summary>
/// Reserved; must be zero.
/// </summary>
public ushort Reserved2;
/// <summary>
/// The offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits.
/// </summary>
public uint OffBits;
}
}

View File

@@ -1,97 +0,0 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BMP
{
/// <summary>
/// The BITMAPINFOHEADER structure contains information about the dimensions and
/// color format of a device-independent bitmap (DIB).
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public sealed class BITMAPINFOHEADER
{
/// <summary>
/// Specifies the number of bytes required by the structure. This value does
/// not include the size of the color table or the size of the color masks,
/// if they are appended to the end of structure.
/// </summary>
public uint Size;
/// <summary>
/// Specifies the width of the bitmap, in pixels.
/// </summary>
public int Width;
/// <summary>
/// Specifies the height of the bitmap, in pixels.
/// - For uncompressed RGB bitmaps, if biHeight is positive, the bitmap is a
/// bottom-up DIB with the origin at the lower left corner. If biHeight is
/// negative, the bitmap is a top-down DIB with the origin at the upper left
/// corner.
/// - For YUV bitmaps, the bitmap is always top-down, regardless of the sign of
/// biHeight. Decoders should offer YUV formats with positive biHeight, but for
/// backward compatibility they should accept YUV formats with either positive
/// or negative biHeight.
/// - For compressed formats, biHeight must be positive, regardless of image orientation.
/// </summary>
public int Height;
/// <summary>
/// Specifies the number of planes for the target device. This value must be set to 1.
/// </summary>
public ushort Planes;
/// <summary>
/// Specifies the number of bits per pixel (bpp). For uncompressed formats, this value
/// is the average number of bits per pixel. For compressed formats, this value is the
/// implied bit depth of the uncompressed image, after the image has been decoded.
/// </summary>
public ushort BitCount;
/// <summary>
/// For compressed video and YUV formats, this member is a FOURCC code, specified as a
/// DWORD in little-endian order. For example, YUYV video has the FOURCC 'VYUY' or
/// 0x56595559. For more information, see FOURCC Codes.
///
/// For uncompressed RGB formats, the following values are possible:
/// - BI_RGB: Uncompressed RGB.
/// - BI_BITFIELDS: Uncompressed RGB with color masks. Valid for 16-bpp and 32-bpp bitmaps.
///
/// Note that BI_JPG and BI_PNG are not valid video formats.
///
/// For 16-bpp bitmaps, if biCompression equals BI_RGB, the format is always RGB 555.
/// If biCompression equals BI_BITFIELDS, the format is either RGB 555 or RGB 565. Use
/// the subtype GUID in the AM_MEDIA_TYPE structure to determine the specific RGB type.
/// </summary>
public uint Compression;
/// <summary>
/// Specifies the size, in bytes, of the image. This can be set to 0 for uncompressed
/// RGB bitmaps.
/// </summary>
public uint SizeImage;
/// <summary>
/// Specifies the horizontal resolution, in pixels per meter, of the target device for
/// the bitmap.
/// </summary>
public int XPelsPerMeter;
/// <summary>
/// Specifies the vertical resolution, in pixels per meter, of the target device for
/// the bitmap.
/// </summary>
public int YPelsPerMeter;
/// <summary>
/// Specifies the number of color indices in the color table that are actually used by
/// the bitmap.
/// </summary>
public uint ClrUsed;
/// <summary>
/// Specifies the number of color indices that are considered important for displaying
/// the bitmap. If this value is zero, all colors are important.
/// </summary>
public uint ClrImportant;
}
}

View File

@@ -1,92 +0,0 @@
namespace SabreTools.Models.CFB
{
/// <summary>
/// Microsoft Compound File Binary (CFB) file format, also known as the
/// Object Linking and Embedding (OLE) or Component Object Model (COM)
/// structured storage compound file implementation binary file format.
/// This structure name can be shortened to compound file.
/// </summary>
/// <see href="https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-CFB/%5bMS-CFB%5d.pdf"/>
public sealed class Binary
{
/// <summary>
/// Compound file header
/// </summary>
public FileHeader? Header { get; set; }
/// <summary>
/// The FAT is the main allocator for space within a compound file.
/// Every sector in the file is represented within the FAT in some
/// fashion, including those sectors that are unallocated (free).
/// The FAT is a sector chain that is made up of one or more FAT sectors.
/// </summary>
/// <remarks>
/// If Header Major Version is 3, there MUST be 128 fields specified to fill a 512-byte sector.
///
/// 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; }
/// <summary>
/// The mini FAT is used to allocate space in the mini stream.
/// The mini stream is divided intosmaller, equal-length sectors,
/// and the sector size that is used for the mini stream is specified
/// from the Compound File Header (64 bytes).
/// </summary>
/// <remarks>
/// If Header Major Version is 3, there MUST be 128 fields specified to fill a 512-byte sector.
///
/// 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; }
/// <summary>
/// The DIFAT array is used to represent storage of the FAT sectors.
/// The DIFAT is represented by an array of 32-bit sector numbers.
/// The DIFAT array is stored both in the header and in DIFAT sectors.
/// In the header, the DIFAT array occupies 109 entries, and in each
/// DIFAT sector, the DIFAT array occupies the entire sector minus
/// 4 bytes. (The last field is for chaining the DIFAT sector chain.)
/// </summary>
/// <remarks>
/// If Header Major Version is 3, there MUST be 127 fields specified to
/// fill a 512-byte sector minus the "Next DIFAT Sector Location" field.
///
/// 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; }
/// <summary>
/// The directory entry array is an array of directory entries that
/// are grouped into a directory sector. Each storage object or stream
/// object within a compound file is represented by a single directory
/// entry. The space for the directory sectors that are holding the
/// array is allocated from the FAT.
/// </summary>
/// <remarks>
/// The first entry in the first sector of the directory chain (also
/// referred to as the first element of the directory array, or stream
/// ID #0) is known as the root directory entry, and it is reserved for
/// two purposes. First, it provides a root parent for all objects that
/// are stationed at the root of the compound file. Second, its function
/// is overloaded to store the size and starting sector for the mini stream.
///
/// The root directory entry behaves as both a stream and a storage object.
/// The root directory entry's Name field MUST contain the null-terminated
/// string "Root Entry" in Unicode UTF-16.
///
/// The object class GUID (CLSID) that is stored in the root directory
/// entry can be used for COM activation of the document's application.
///
/// The time stamps for the root storage are not maintained in the root
/// directory entry. Rather, the root storage's creation and modification
/// time stamps are normally stored on the file itself in the file system.
///
/// The Creation Time field in the root storage directory entry MUST be
/// all zeroes. The Modified Time field in the root storage directory
/// entry MAY be all zeroes.
/// <remarks>
public DirectoryEntry[]? DirectoryEntries { get; set; }
}
}

View File

@@ -1,52 +0,0 @@
using System;
namespace SabreTools.Models.CFB
{
public static class Constants
{
public static readonly byte[] SignatureBytes = [0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1];
public const ulong SignatureUInt64 = 0xE11AB1A1E011CFD0;
/// <see href="https://devblogs.microsoft.com/setup/identifying-windows-installer-file-types/"/>
#region Class IDs
/// <summary>
/// Installer Package (msi), Merge Module (msm), Patch Creation Properties (pcp)
/// </summary>
public static readonly Guid InstallerPackage = new("000c1084-0000-0000-c000-000000000046");
/// <summary>
/// Patch Package (msp)
/// </summary>
public static readonly Guid PatchPackage = new("000C1086-0000-0000-C000-000000000046");
/// <summary>
/// Transform (mst)
/// </summary>
public static readonly Guid Transform = new("000C1082-0000-0000-C000-000000000046");
#endregion
/// <see href="https://learn.microsoft.com/en-us/windows/win32/stg/predefined-property-set-format-identifiers"/>
#region Property Set Format IDs
/// <summary>
/// The Summary Information Property Set
/// </summary>
public static readonly Guid FMTID_SummaryInformation = new("F29F85E0-4FF9-1068-AB91-08002B27B3D9");
/// <summary>
/// The DocumentSummaryInformation and UserDefined Property Sets
/// </summary>
public static readonly Guid FMTID_DocSummaryInformation = new("D5CDD502-2E9C-101B-9397-08002B2CF9AE");
/// <summary>
/// The DocumentSummaryInformation and UserDefined Property Sets
/// </summary>
public static readonly Guid FMTID_UserDefinedProperties = new("D5CDD505-2E9C-101B-9397-08002B2CF9AE");
#endregion
}
}

View File

@@ -1,142 +0,0 @@
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>
/// This field MUST contain a Unicode string for the storage or stream
/// name encoded in UTF-16. The name MUST be terminated with a UTF-16
/// terminating null character. Thus, storage and stream names are limited
/// to 32 UTF-16 code points, including the terminating null character.
/// When locating an object in the compound file except for the root
/// storage, the directory entry name is compared by using a special
/// case-insensitive uppercase mapping, described in Red-Black Tree.
/// The following characters are illegal and MUST NOT be part of the
/// name: '/', '\', ':', '!'.
/// </summary>
/// <remarks>64 bytes</remarks>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string? Name;
/// <summary>
/// This field MUST match the length of the Directory Entry Name Unicode
/// string in bytes. The length MUST be a multiple of 2 and include the
/// terminating null character in the count. This length MUST NOT exceed 64,
/// the maximum size of the Directory Entry Name field.
/// </summary>
public ushort NameLength;
/// <summary>
/// This field MUST be 0x00, 0x01, 0x02, or 0x05, depending on the
/// actual type of object. All other values are not valid.
/// </summary>
[MarshalAs(UnmanagedType.U1)]
public ObjectType ObjectType;
/// <summary>
/// This field MUST be 0x00 (red) or 0x01 (black). All other values are not valid.
/// </summary>
[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>
[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>
[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>
[MarshalAs(UnmanagedType.U4)]
public StreamID ChildID;
/// <summary>
/// This field contains an object class GUID, if this entry is for a
/// storage object or root storage object. For a stream object, this field
/// MUST be set to all zeroes. A value containing all zeroes in a storage
/// or root storage directory entry is valid, and indicates that no object
/// class is associated with the storage. If an implementation of the file
/// format enables applications to create storage objects without explicitly
/// setting an object class GUID, it MUST write all zeroes by default. If
/// this value is not all zeroes, the object class GUID can be used as a
/// parameter to start applications.
/// </summary>
public Guid CLSID;
/// <summary>
/// This field contains the user-defined flags if this entry is for a storage
/// object or root storage object. For a stream object, this field SHOULD be
/// set to all zeroes because many implementations provide no way for
/// applications to retrieve state bits from a stream object. If an
/// implementation of the file format enables applications to create storage
/// objects without explicitly setting state bits, it MUST write all zeroes
/// by default.
/// </summary>
public uint StateBits;
/// <summary>
/// This field contains the creation time for a storage object, or all zeroes
/// to indicate that the creation time of the storage object was not recorded.
/// The Windows FILETIME structure is used to represent this field in UTC.
/// For a stream object, this field MUST be all zeroes. For a root storage
/// object, this field MUST be all zeroes, and the creation time is retrieved
/// or set on the compound file itself.
/// </summary>
public ulong CreationTime;
/// <summary>
/// This field contains the modification time for a storage object, or all
/// zeroes to indicate that the modified time of the storage object was not
/// recorded. The Windows FILETIME structure is used to represent this field
/// in UTC. For a stream object, this field MUST be all zeroes. For a root
/// 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;
/// <summary>
/// This field contains the first sector location if this is a stream object.
/// For a root storage object, this field MUST contain the first sector of the
/// mini stream, if the mini stream exists. For a storage object, this field MUST
/// be set to all zeroes.
/// </summary>
public uint StartingSectorLocation;
/// <summary>
/// This 64-bit integer field contains the size of the user-defined data if this
/// is a stream object. For a root storage object, this field contains the size
/// of the mini stream. For a storage object, this field MUST be set to all zeroes.
/// </summary>
/// <remarks>
/// For a version 3 compound file 512-byte sector size, the value of this field MUST
/// be less than or equal to 0x80000000. (Equivalently, this requirement can be stated:
/// the size of a stream or of the mini stream in a version 3 compound file MUST be
/// less than or equal to 2 gigabytes (GB).) Note that as a consequence of this
/// requirement, the most significant 32 bits of this field MUST be zero in a version
/// 3 compound file. However, implementers should be aware that some older
/// implementations did not initialize the most significant 32 bits of this field,
/// and these bits might therefore be nonzero in files that are otherwise valid
/// version 3 compound files. Although this document does not normatively specify
/// parser behavior, it is recommended that parsers ignore the most significant 32 bits
/// of this field in version 3 compound files, treating it as if its value were zero,
/// 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;
}
}

View File

@@ -1,474 +0,0 @@
namespace SabreTools.Models.CFB
{
public enum ColorFlag : byte
{
Red = 0x00,
Black = 0x01,
}
public enum ObjectType : byte
{
Unknown = 0x00,
StorageObject = 0x01,
StreamObject = 0x02,
RootStorageObject = 0x05,
}
public enum SectorNumber : uint
{
/// <summary>
/// Regular sector number.
/// </summary>
REGSECT = 0x00000000, // 0x00000000 - 0xFFFFFFF9
/// <summary>
/// Maximum regular sector number.
/// </summary>
MAXREGSECT = 0xFFFFFFFA,
/// <summary>
/// Reserved for future use.
/// </summary>
NotApplicable = 0xFFFFFFFB,
/// <summary>
/// Specifies a DIFAT sector in the FAT.
/// </summary>
DIFSECT = 0xFFFFFFFC,
/// <summary>
/// Specifies a FAT sector in the FAT.
/// </summary>
FATSECT = 0xFFFFFFFD,
/// <summary>
/// End of a linked chain of sectors.
/// </summary>
ENDOFCHAIN = 0xFFFFFFFE,
/// <summary>
/// Specifies an unallocated sector in the FAT, Mini FAT, or DIFAT.
/// </summary>
FREESECT = 0xFFFFFFFF,
}
public enum StreamID : uint
{
/// <summary>
/// Regular stream ID to identify the directory entry.
/// </summary>
REGSID = 0x00000000, // 0x00000000 - 0xFFFFFFF9
/// <summary>
/// Maximum regular stream ID.
/// </summary>
MAXREGSID = 0xFFFFFFFA,
/// <summary>
/// Terminator or empty pointer.
/// </summary>
NOSTREAM = 0xFFFFFFFF,
}
/// <see href="https://learn.microsoft.com/en-us/windows/win32/stg/the-summary-information-property-set"/>
public enum SummaryInformationProperty : uint
{
/// <summary>
/// Title
/// </summary>
PIDSI_TITLE = 0x00000002,
/// <summary>
/// Subject
/// </summary>
PIDSI_SUBJECT = 0x00000003,
/// <summary>
/// Author
/// </summary>
PIDSI_AUTHOR = 0x00000004,
/// <summary>
/// Keywords
/// </summary>
PIDSI_KEYWORDS = 0x00000005,
/// <summary>
/// Comments
/// </summary>
PIDSI_COMMENTS = 0x00000006,
/// <summary>
/// Template
/// </summary>
PIDSI_TEMPLATE = 0x00000007,
/// <summary>
/// Last Saved By
/// </summary>
PIDSI_LASTAUTHOR = 0x00000008,
/// <summary>
/// Revision Number
/// </summary>
PIDSI_REVNUMBER = 0x00000009,
/// <summary>
/// Total Editing Time
/// </summary>
PIDSI_EDITTIME = 0x0000000A,
/// <summary>
/// Last Printed
/// </summary>
PIDSI_LASTPRINTED = 0x0000000B,
/// <summary>
/// Create Time/Date
/// </summary>
PIDSI_CREATE_DTM = 0x0000000C,
/// <summary>
/// Last saved Time/Date
/// </summary>
PIDSI_LASTSAVE_DTM = 0x0000000D,
/// <summary>
/// Number of Pages
/// </summary>
PIDSI_PAGECOUNT = 0x0000000E,
/// <summary>
/// Number of Words
/// </summary>
PIDSI_WORDCOUNT = 0x0000000F,
/// <summary>
/// Number of Characters
/// </summary>
PIDSI_CHARCOUNT = 0x00000010,
/// <summary>
/// Thumbnail
/// </summary>
PIDSI_THUMBNAIL = 0x00000011,
/// <summary>
/// Name of Creating Application
/// </summary>
PIDSI_APPNAME = 0x00000012,
/// <summary>
/// Security
/// </summary>
PIDSI_SECURITY = 0x00000013,
}
/// <remarks>Also includes the DocumentSummaryInformation set</remarks>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/stg/the-documentsummaryinformation-and-userdefined-property-sets"/>
public enum UserDefinedProperty : uint
{
/// <summary>
/// Category - A text string typed by the user that indicates what
/// category the file belongs to (memo, proposal, and so on). It
/// is useful for finding files of same type.
/// </summary>
PIDDSI_CATEGORY = 0x00000002,
/// <summary>
/// PresentationTarget - Target format for presentation (35mm,
/// printer, video, and so on).
/// </summary>
PIDDSI_PRESFORMAT = 0x00000003,
/// <summary>
/// Bytes - Number of bytes.
/// </summary>
PIDDSI_BYTECOUNT = 0x00000004,
/// <summary>
/// Lines - Number of lines.
/// </summary>
PIDDSI_LINECOUNT = 0x00000005,
/// <summary>
/// Paragraphs - Number of paragraphs.
/// </summary>
PIDDSI_PARCOUNT = 0x00000006,
/// <summary>
/// Slides - Number of slides.
/// </summary>
PIDDSI_SLIDECOUNT = 0x00000007,
/// <summary>
/// Notes - Number of pages that contain notes.
/// </summary>
PIDDSI_NOTECOUNT = 0x00000008,
/// <summary>
/// HiddenSlides - Number of slides that are hidden.
/// </summary>
PIDDSI_HIDDENCOUNT = 0x00000009,
/// <summary>
/// MMClips - Number of sound or video clips.
/// </summary>
PIDDSI_MMCLIPCOUNT = 0x0000000A,
/// <summary>
/// ScaleCrop - Set to True (-1) when scaling of the thumbnail
/// is desired. If not set, cropping is desired.
/// </summary>
PIDDSI_SCALE = 0x0000000B,
/// <summary>
/// HeadingPairs - Internally used property indicating the
/// grouping of different document parts and the number of
/// items in each group. The titles of the document parts are
/// stored in the TitlesofParts property. The HeadingPairs
/// property is stored as a vector of variants, in repeating
/// pairs of VT_LPSTR (or VT_LPWSTR) and VT_I4 values. The
/// VT_LPSTR value represents a heading name, and the VT_I4
/// value indicates the count of document parts under that heading.
/// </summary>
PIDDSI_HEADINGPAIR = 0x0000000C,
/// <summary>
/// TitlesofParts - Names of document parts.
/// </summary>
PIDDSI_DOCPARTS = 0x0000000D,
/// <summary>
/// Manager - Manager of the project.
/// </summary>
PIDDSI_MANAGER = 0x0000000E,
/// <summary>
/// Company - Company name.
/// </summary>
PIDDSI_COMPANY = 0x0000000F,
/// <summary>
/// LinksUpToDate - Boolean value to indicate whether the custom
/// links are hampered by excessive noise, for all applications.
/// </summary>
PIDDSI_LINKSDIRTY = 0x00000010,
}
/// <see href="https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-oaut/3fe7db9f-5803-4dc4-9d14-5425d3f5461f"/>
public enum VariantType : ushort
{
/// <summary>
/// The type of the contained field is undefined. When this flag is
/// specified, the VARIANT MUST NOT contain a data field.
/// </summary>
VT_EMPTY = 0x0000,
/// <summary>
/// The type of the contained field is NULL. When this flag is
/// specified, the VARIANT MUST NOT contain a data field.
/// </summary>
VT_NULL = 0x0001,
/// <summary>
/// Either the specified type, or the type of the element or contained
/// field MUST be a 2-byte signed integer.
/// </summary>
VT_I2 = 0x0002,
/// <summary>
/// Either the specified type, or the type of the element or contained
/// field MUST be a 4-byte signed integer.
/// </summary>
VT_I4 = 0x0003,
/// <summary>
/// Either the specified type, or the type of the element or contained
/// field MUST be a 4-byte IEEE floating-point number.
/// </summary>
VT_R4 = 0x0004,
/// <summary>
/// Either the specified type, or the type of the element or contained
/// field MUST be an 8-byte IEEE floating-point number.
/// </summary>
VT_R8 = 0x0005,
/// <summary>
/// Either the specified type, or the type of the element or contained
/// field MUST be CURRENCY.
/// </summary>
VT_CY = 0x0006,
/// <summary>
/// Either the specified type, or the type of the element or contained
/// field MUST be DATE.
/// </summary>
VT_DATE = 0x0007,
/// <summary>
/// Either the specified type, or the type of the element or contained
/// field MUST be BSTR.
/// </summary>
VT_BSTR = 0x0008,
/// <summary>
/// Either the specified type, or the type of the element or contained
/// field MUST be a pointer to IDispatch.
/// </summary>
VT_DISPATCH = 0x0009,
/// <summary>
/// Either the specified type, or the type of the element or contained
/// field MUST be HRESULT.
/// </summary>
VT_ERROR = 0x000A,
/// <summary>
/// Either the specified type, or the type of the element or contained
/// field MUST be VARIANT_BOOL.
/// </summary>
VT_BOOL = 0x000B,
/// <summary>
/// Either the specified type, or the type of the element or contained
/// field MUST be VARIANT. It MUST appear with the bit flag VT_BYREF.
/// </summary>
VT_VARIANT = 0x000C,
/// <summary>
/// Either the specified type, or the type of the element or contained
/// field MUST be a pointer to IUnknown.
/// </summary>
VT_UNKNOWN = 0x000D,
/// <summary>
/// Either the specified type, or the type of the element or contained
/// field MUST be DECIMAL.
/// </summary>
VT_DECIMAL = 0x000E,
/// <summary>
/// Either the specified type, or the type of the element or contained
/// field MUST be a 1-byte integer.
/// </summary>
VT_I1 = 0x0010,
/// <summary>
/// Either the specified type, or the type of the element or contained
/// field MUST be a 1-byte unsigned integer.
/// </summary>
VT_UI1 = 0x0011,
/// <summary>
/// Either the specified type, or the type of the element or contained
/// field MUST be a 2-byte unsigned integer.
/// </summary>
VT_UI2 = 0x0012,
/// <summary>
/// Either the specified type, or the type of the element or contained
/// field MUST be a 4-byte unsigned integer.
/// </summary>
VT_UI4 = 0x0013,
/// <summary>
/// Either the specified type, or the type of the element or contained
/// field MUST be an 8-byte signed integer.
/// </summary>
VT_I8 = 0x0014,
/// <summary>
/// Either the specified type, or the type of the element or contained
/// field MUST be an 8-byte unsigned integer.
/// </summary>
VT_UI8 = 0x0015,
/// <summary>
/// Either the specified type, or the type of the element or contained
/// field MUST be a 4-byte signed integer.
/// </summary>
VT_INT = 0x0016,
/// <summary>
/// Either the specified type, or the type of the element or contained
/// field MUST be a 4-byte unsigned integer.
/// </summary>
VT_UINT = 0x0017,
/// <summary>
/// The specified type MUST be void.
/// </summary>
VT_VOID = 0x0018,
/// <summary>
/// The specified type MUST be HRESULT.
/// </summary>
VT_HRESULT = 0x0019,
/// <summary>
/// The specified type MUST be a unique pointer.
/// </summary>
VT_PTR = 0x001A,
/// <summary>
/// The specified type MUST be SAFEARRAY.
/// </summary>
VT_SAFEARRAY = 0x001B,
/// <summary>
/// The specified type MUST be a fixed-size array.
/// </summary>
VT_CARRAY = 0x001C,
/// <summary>
/// The specified type MUST be user defined.
/// </summary>
VT_USERDEFINED = 0x001D,
/// <summary>
/// The specified type MUST be a NULL-terminated string.
/// </summary>
VT_LPSTR = 0x001E,
/// <summary>
/// The specified type MUST be a zero-terminated string of
/// UNICODE characters.
/// </summary>
VT_LPWSTR = 0x001F,
/// <summary>
/// The type of the element or contained field MUST be a BRECORD.
/// </summary>
VT_RECORD = 0x0024,
/// <summary>
/// The specified type MUST be either a 4-byte or an 8-byte signed
/// integer. The size of the integer is platform specific and
/// determines the system pointer size value.
/// </summary>
VT_INT_PTR = 0x0025,
/// <summary>
/// The specified type MUST be either a 4 byte or an 8 byte unsigned
/// integer. The size of the integer is platform specific and
/// determines the system pointer size value
/// </summary>
VT_UINT_PTR = 0x0026,
/// <summary>
/// The type of the element or contained field MUST be a SAFEARRAY.
/// </summary>
VT_ARRAY = 0x2000,
/// <summary>
/// The type of the element or contained field MUST be a pointer to
/// one of the types listed in the previous rows of this table. If
/// present, this bit flag MUST appear in a VARIANT discriminant
/// with one of the previous flags.
/// </summary>
VT_BYREF = 0x4000
}
}

View File

@@ -1,133 +0,0 @@
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;
/// <summary>
/// Reserved and unused class ID that MUST be set to all zeroes (CLSID_NULL)
/// </summary>
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;
/// <summary>
/// Version number for breaking changes. This field MUST be set to either
/// 0x0003 (version 3) or 0x0004 (version 4).
/// </summary>
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;
/// <summary>
/// This field MUST be set to 0x0009, or 0x000c, depending on the Major
/// Version field. This field specifies the sector size of the compound file
/// as a power of 2.
///
/// If Major Version is 3, the Sector Shift MUST be 0x0009, specifying a
/// sector size of 512 bytes.
///
/// If Major Version is 4, the Sector Shift MUST be 0x000C, specifying a
/// sector size of 4096 bytes.
/// </summary>
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;
/// <summary>
/// This field MUST be set to all zeroes.
/// </summary>
/// <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
/// in the compound file.
///
/// 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;
/// <summary>
/// This integer field contains the count of the number of FAT sectors in the
/// compound file.
/// </summary>
public uint NumberOfFATSectors;
/// <summary>
/// This integer field contains the starting sector number for the directory stream.
/// </summary>
public uint FirstDirectorySectorLocation;
/// <summary>
/// This integer field MAY contain a sequence number that is incremented every time
/// the compound file is saved by an implementation that supports file transactions.
/// This is the field that MUST be set to all zeroes if file transactions are not
/// implemented.
/// </summary>
public uint TransactionSignatureNumber;
/// <summary>
/// This integer field MUST be set to 0x00001000. This field specifies the maximum
/// size of a user-defined data stream that is allocated from the mini FAT and mini
/// stream, and that cutoff is 4,096 bytes. Any user-defined data stream that is
/// greater than or equal to this cutoff size must be allocated as normal sectors from
/// the FAT.
/// </summary>
public uint MiniStreamCutoffSize;
/// <summary>
/// This integer field contains the starting sector number for the mini FAT.
/// </summary>
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;
/// <summary>
/// This integer field contains the starting sector number for the DIFAT.
/// </summary>
public uint FirstDIFATSectorLocation;
/// <summary>
/// This integer field contains the count of the number of DIFAT sectors in the
/// compound file.
/// </summary>
public uint NumberOfDIFATSectors;
/// <summary>
/// This array of 32-bit integer fields contains the first 109 FAT sector
/// locations of the compound file
/// </summary>
/// <remarks>109 entries</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 109)]
public SectorNumber[]? DIFAT;
}
}

View File

@@ -1,82 +0,0 @@
using System;
namespace SabreTools.Models.CFB
{
/// <see href="https://github.com/GNOME/msitools/blob/master/libmsi/libmsi-summary-info.c"/>
public sealed class SummaryInformation
{
#region Set Header
/// <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; }
/// <summary>
/// Format
/// </summary>
public ushort Format { get; set; }
/// <summary>
/// Build
/// </summary>
public ushort Build { get; set; }
/// <summary>
/// Platform ID
/// </summary>
public ushort PlatformID { get; set; }
/// <summary>
/// CLSID
/// </summary>
public Guid CLSID { get; set; }
/// <summary>
/// 4 bytes of reserved data
/// </summary>
public byte[]? Reserved { get; set; }
#endregion
#region Format Header
/// <summary>
/// Format ID, should be <see cref="Constants.FMTID_SummaryInformation"/>
/// </summary>
public Guid FormatID { get; set; }
/// <summary>
/// 16 bytes of unknown data
/// </summary>
public byte[]? Unknown { get; set; }
#endregion
#region Section Header
/// <summary>
/// Location of the section
/// </summary>
public uint Offset { get; set; }
/// <summary>
/// Section count(?)
/// </summary>
public uint SectionCount { get; set; }
/// <summary>
/// Property count
/// </summary>
public uint PropertyCount { get; set; }
/// <summary>
/// Properties
/// </summary>
/// <remarks>Each Variant might be followed by an index and offset value</remarks>
public Variant[]? Properties { get; set; }
#endregion
}
}

View File

@@ -1,45 +0,0 @@
namespace SabreTools.Models.CFB
{
/// <summary>
/// VARIANT is a container for a union that can hold many types of data.
/// </summary>
/// <see href="https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-oaut/b2ee2b50-665e-43e6-a92c-8f2a29fd7add"/>
public sealed class Variant
{
/// <summary>
/// MUST be set to the size, in quad words (64 bits), of the structure.
/// </summary>
public uint Size { get; set; }
/// <summary>
/// MUST be set to 0 and MUST be ignored by the recipient.
/// </summary>
public uint RpcReserved { get; set; }
/// <summary>
/// MUST be set to one of the values specified with a "V".
/// </summary>
public VariantType VariantType { get; set; }
/// <summary>
/// MAY be set to 0 and MUST be ignored by the recipient.
/// </summary>
public ushort Reserved1 { get; set; }
/// <summary>
/// MAY be set to 0 and MUST be ignored by the recipient.
/// </summary>
public ushort Reserved2 { get; set; }
/// <summary>
/// MAY be set to 0 and MUST be ignored by the recipient.
/// </summary>
public ushort Reserved3 { get; set; }
/// <summary>
/// MUST contain an instance of the type, according to the value
/// in the <see cref="VariantType"/> field.
/// </summary>
public object? Union { get; set; }
}
}

View File

@@ -1,31 +0,0 @@
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 sealed class CompressedMapEntryV5
{
/// <summary>
/// Compression type
/// </summary>
public byte Compression;
/// <summary>
/// Compressed length
/// </summary>
/// <remarks>Actually UInt24</remarks>
public uint CompLength;
/// <summary>
/// Offset
/// </summary>
/// <remarks>Actually UInt48</remarks>
public ulong Offset;
/// <summary>
/// CRC-16 of the data
/// </summary>
public ushort CRC;
}
}

View File

@@ -1,45 +0,0 @@
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 sealed class CompressedMapHeaderV5
{
/// <summary>
/// Length of compressed map
/// </summary>
public uint Length;
/// <summary>
/// Offset of first block
/// </summary>
/// <remarks>Actually UInt48</remarks>
public ulong DataStart;
/// <summary>
/// CRC-16 of the map
/// </summary>
public ushort CRC;
/// <summary>
/// Bits used to encode complength
/// </summary>
public byte LengthBits;
/// <summary>
/// Bits used to encode self-refs
/// </summary>
public byte HunkBits;
/// <summary>
/// Bits used to encode parent unit refs
/// </summary>
public byte ParentUnitBits;
/// <summary>
/// Future use
/// </summary>
public byte Reserved;
}
}

View File

@@ -1,25 +0,0 @@
namespace SabreTools.Models.CHD
{
public static class Constants
{
public static readonly byte[] SignatureBytes = [0x4D, 0x43, 0x6F, 0x6D, 0x70, 0x72, 0x48, 0x44];
public const string SignatureString = "MComprHD";
#region Header Sizes
public const int HeaderV1Size = 76;
public const int HeaderV2Size = 80;
public const int HeaderV3Size = 120;
public const int HeaderV4Size = 108;
public const int HeaderV5Size = 124;
#endregion
#region Metadata Parameters
public const uint CHDMETAINDEX_APPEND = uint.MaxValue;
#endregion
}
}

View File

@@ -1,358 +0,0 @@
using System;
namespace SabreTools.Models.CHD
{
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chdcodec.h"/>
public enum AVHuffCodec
{
DECOMPRESS_CONFIG = 1,
}
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chdcodec.h"/>
public enum CodecType : uint
{
CHD_CODEC_NONE = 0,
#region General Codecs
/// <remarks>"zlib"</remarks>
ZLIB = 0x7a6c6962,
/// <remarks>"zstd"</remarks>
ZSTD = 0x7a737464,
/// <remarks>"lzma"</remarks>
LZMA = 0x6c7a6d61,
/// <remarks>"huff"</remarks>
HUFFMAN = 0x68756666,
/// <remarks>"flac"</remarks>
FLAC = 0x666c6163,
#endregion
#region General Codecs with CD Frontend
/// <remarks>"cdzl"</remarks>
CD_ZLIB = 0x63647a6c,
/// <remarks>"cdzs"</remarks>
CD_ZSTD = 0x63647a73,
/// <remarks>"cdlz"</remarks>
CD_LZMA = 0x63646c7a,
/// <remarks>"cdfl"</remarks>
CD_FLAC = 0x6364666c,
#endregion
#region A/V Codecs
/// <remarks>"avhu"</remarks>
AVHUFF = 0x61766875,
#endregion
#region Pseudo-Codecs Returned by hunk_info
/// <summary>
/// Copy of another hunk
/// </summary>
CHD_CODEC_SELF = 1,
/// <summary>
/// Copy of a parent's hunk
/// </summary>
CHD_CODEC_PARENT = 2,
/// <summary>
/// Legacy "mini" 8-byte repeat
/// </summary>
CHD_CODEC_MINI = 3,
#endregion
}
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.h"/>
public enum CompressionType : uint
{
#region V1
CHDCOMPRESSION_NONE = 0,
CHDCOMPRESSION_ZLIB = 1,
#endregion
#region V3
CHDCOMPRESSION_ZLIB_PLUS = 2,
#endregion
#region V4
CHDCOMPRESSION_AV = 3,
#endregion
}
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.h"/>
public enum Error : uint
{
NO_INTERFACE = 1,
NOT_OPEN,
ALREADY_OPEN,
INVALID_FILE,
INVALID_DATA,
REQUIRES_PARENT,
FILE_NOT_WRITEABLE,
CODEC_ERROR,
INVALID_PARENT,
HUNK_OUT_OF_RANGE,
DECOMPRESSION_ERROR,
COMPRESSION_ERROR,
CANT_VERIFY,
METADATA_NOT_FOUND,
INVALID_METADATA_SIZE,
UNSUPPORTED_VERSION,
VERIFY_INCOMPLETE,
INVALID_METADATA,
INVALID_STATE,
OPERATION_PENDING,
UNSUPPORTED_FORMAT,
UNKNOWN_COMPRESSION,
WALKING_PARENT,
COMPRESSING
}
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.h"/>
[Flags]
public enum Flags : uint
{
/// <summary>
/// Set if this drive has a parent
/// </summary>
DriveHasParent = 0x00000001,
/// <summary>
/// Set if this drive allows writes
/// </summary>
DriveAllowsWrites = 0x00000002,
}
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.h"/>
[Flags]
public enum MetadataFlags : byte
{
/// <summary>
/// Indicates data is checksummed
/// </summary>
CHD_MDFLAGS_CHECKSUM = 0x01,
}
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.h"/>
public enum MetadataTag : uint
{
CHDMETATAG_WILDCARD = 0,
#region Hard Disk
/// <summary>
/// Standard hard disk metadata
/// </summary>
/// <remarks>"GDDD"</remarks>
HARD_DISK_METADATA_TAG = 0x47444444,
/// <summary>
/// Hard disk identify information
/// </summary>
/// <remarks>"IDNT"</remarks>
HARD_DISK_IDENT_METADATA_TAG = 0x49444e54,
/// <summary>
/// Hard disk key information
/// </summary>
/// <remarks>"KEY "</remarks>
HARD_DISK_KEY_METADATA_TAG = 0x4b455920,
#endregion
#region PCMCIA
/// <summary>
/// PCMCIA CIS information
/// </summary>
/// <remarks>"CIS "</remarks>
PCMCIA_CIS_METADATA_TAG = 0x43495320,
#endregion
#region CD-ROM
/// <remarks>"CHCD"</remarks>
CDROM_OLD_METADATA_TAG = 0x43484344,
/// <remarks>"CHTR"</remarks>
CDROM_TRACK_METADATA_TAG = 0x43485452,
/// <remarks>"CHT2"</remarks>
CDROM_TRACK_METADATA2_TAG = 0x43485432,
#endregion
#region GD-ROM
/// <remarks>"CHGT"</remarks>
GDROM_OLD_METADATA_TAG = 0x43484754,
/// <remarks>"CHGD"</remarks>
GDROM_TRACK_METADATA_TAG = 0x43484744,
#endregion
#region DVD
/// <summary>
/// Standard DVD metadata
/// </summary>
/// <remarks>"DVD "</remarks>
DVD_METADATA_TAG = 0x44564420,
#endregion
#region A/V
/// <summary>
/// Standard A/V metadata
/// </summary>
/// <remarks>"AVAV"</remarks>
AV_METADATA_TAG = 0x41564156,
/// <summary>
/// A/V laserdisc frame metadata
/// </summary>
/// <remarks>"AVLD"</remarks>
AV_LD_METADATA_TAG = 0x41564c44,
#endregion
}
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.cpp"/>
public enum V34EntryType : uint
{
/// <summary>
/// Invalid type
/// </summary>
V34_MAP_ENTRY_TYPE_INVALID = 0,
/// <summary>
/// Standard compression
/// </summary>
V34_MAP_ENTRY_TYPE_COMPRESSED = 1,
/// <summary>
/// Uncompressed data
/// </summary>
V34_MAP_ENTRY_TYPE_UNCOMPRESSED = 2,
/// <summary>
/// Mini: use offset as raw data
/// </summary>
V34_MAP_ENTRY_TYPE_MINI = 3,
/// <summary>
/// Same as another hunk in this file
/// </summary>
V34_MAP_ENTRY_TYPE_SELF_HUNK = 4,
/// <summary>
/// Same as a hunk in the parent file
/// </summary>
V34_MAP_ENTRY_TYPE_PARENT_HUNK = 5,
/// <summary>
/// Compressed with secondary algorithm (usually FLAC CDDA)
/// </summary>
V34_MAP_ENTRY_TYPE_2ND_COMPRESSED = 6,
}
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.cpp"/>
public enum V5CompressionType : uint
{
// These types are live when running
/// <summary>
/// Codec #0
/// </summary>
COMPRESSION_TYPE_0 = 0,
/// <summary>
/// Codec #1
/// </summary>
COMPRESSION_TYPE_1 = 1,
/// <summary>
/// Codec #2
/// </summary>
COMPRESSION_TYPE_2 = 2,
/// <summary>
/// Codec #3
/// </summary>
COMPRESSION_TYPE_3 = 3,
/// <summary>
/// No compression; implicit length = hunkbytes
/// </summary>
COMPRESSION_NONE = 4,
/// <summary>
/// Same as another block in this CHD
/// </summary>
COMPRESSION_SELF = 5,
/// <summary>
/// Same as a hunk's worth of units in the parent CHD
/// </summary>
COMPRESSION_PARENT = 6,
// These additional pseudo-types are used for compressed encodings
/// <summary>
/// Start of small RLE run (4-bit length)
/// </summary>
COMPRESSION_RLE_SMALL,
/// <summary>
/// Start of large RLE run (8-bit length)
/// </summary>
COMPRESSION_RLE_LARGE,
/// <summary>
/// Same as the last COMPRESSION_SELF block
/// </summary>
COMPRESSION_SELF_0,
/// <summary>
/// Same as the last COMPRESSION_SELF block + 1
/// </summary>
COMPRESSION_SELF_1,
/// <summary>
/// Same block in the parent
/// </summary>
COMPRESSION_PARENT_SELF,
/// <summary>
/// Same as the last COMPRESSION_PARENT block
/// </summary>
COMPRESSION_PARENT_0,
/// <summary>
/// Same as the last COMPRESSION_PARENT block + 1
/// </summary>
COMPRESSION_PARENT_1
}
}

View File

@@ -1,25 +0,0 @@
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, CharSet = CharSet.Unicode)]
public abstract class Header
{
/// <summary>
/// 'MComprHD'
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
public string? Tag;
/// <summary>
/// Length of header (including tag and length fields)
/// </summary>
public uint Length;
/// <summary>
/// Drive format version
/// </summary>
public uint Version;
}
}

View File

@@ -1,58 +0,0 @@
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, CharSet = CharSet.Unicode)]
public class HeaderV1 : Header
{
/// <summary>
/// Flags
/// </summary>
[MarshalAs(UnmanagedType.U4)]
public Flags Flags;
/// <summary>
/// Compression type
/// </summary>
[MarshalAs(UnmanagedType.U4)]
public CompressionType Compression;
/// <summary>
/// 512-byte sectors per hunk
/// </summary>
public uint HunkSize;
/// <summary>
/// Total # of hunks represented
/// </summary>
public uint TotalHunks;
/// <summary>
/// Number of cylinders on hard disk
/// </summary>
public uint Cylinders;
/// <summary>
/// Number of heads on hard disk
/// </summary>
public uint Heads;
/// <summary>
/// Number of sectors on hard disk
/// </summary>
public uint Sectors;
/// <summary>
/// MD5 checksum of raw data
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] MD5 = new byte[16];
/// <summary>
/// MD5 checksum of parent file
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] ParentMD5 = new byte[16];
}
}

View File

@@ -1,63 +0,0 @@
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, CharSet = CharSet.Unicode)]
public class HeaderV2 : Header
{
/// <summary>
/// Flags
/// </summary>
[MarshalAs(UnmanagedType.U4)]
public Flags Flags;
/// <summary>
/// Compression type
/// </summary>
[MarshalAs(UnmanagedType.U4)]
public CompressionType Compression;
/// <summary>
/// Seclen-byte sectors per hunk
/// </summary>
public uint HunkSize;
/// <summary>
/// Total # of hunks represented
/// </summary>
public uint TotalHunks;
/// <summary>
/// Number of cylinders on hard disk
/// </summary>
public uint Cylinders;
/// <summary>
/// Number of heads on hard disk
/// </summary>
public uint Heads;
/// <summary>
/// Number of sectors on hard disk
/// </summary>
public uint Sectors;
/// <summary>
/// MD5 checksum of raw data
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[]? MD5 = new byte[16];
/// <summary>
/// MD5 checksum of parent file
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[]? ParentMD5 = new byte[16];
/// <summary>
/// Number of bytes per sector
/// </summary>
public uint BytesPerSector;
}
}

View File

@@ -1,65 +0,0 @@
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, CharSet = CharSet.Unicode)]
public class HeaderV3 : Header
{
/// <summary>
/// Flags
/// </summary>
[MarshalAs(UnmanagedType.U4)]
public Flags Flags;
/// <summary>
/// Compression type
/// </summary>
[MarshalAs(UnmanagedType.U4)]
public CompressionType Compression;
/// <summary>
/// Total # of hunks represented
/// </summary>
public uint TotalHunks;
/// <summary>
/// Logical size of the data (in bytes)
/// </summary>
public ulong LogicalBytes;
/// <summary>
/// Offset to the first blob of metadata
/// </summary>
public ulong MetaOffset;
/// <summary>
/// MD5 checksum of raw data
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[]? MD5 = new byte[16];
/// <summary>
/// MD5 checksum of parent file
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[]? ParentMD5 = new byte[16];
/// <summary>
/// Number of bytes per hunk
/// </summary>
public uint HunkBytes;
/// <summary>
/// SHA1 checksum of raw data
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[]? SHA1 = new byte[20];
/// <summary>
/// SHA1 checksum of parent file
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[]? ParentSHA1 = new byte[20];
}
}

View File

@@ -1,59 +0,0 @@
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, CharSet = CharSet.Unicode)]
public class HeaderV4 : Header
{
/// <summary>
/// Flags
/// </summary>
[MarshalAs(UnmanagedType.U4)]
public Flags Flags;
/// <summary>
/// Compression type
/// </summary>
[MarshalAs(UnmanagedType.U4)]
public CompressionType Compression;
/// <summary>
/// Total # of hunks represented
/// </summary>
public uint TotalHunks;
/// <summary>
/// Logical size of the data (in bytes)
/// </summary>
public ulong LogicalBytes;
/// <summary>
/// Offset to the first blob of metadata
/// </summary>
public ulong MetaOffset;
/// <summary>
/// Number of bytes per hunk
/// </summary>
public uint HunkBytes;
/// <summary>
/// Combined raw+meta SHA1
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[]? SHA1 = new byte[20];
/// <summary>
/// Combined raw+meta SHA1 of parent
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[]? ParentSHA1 = new byte[20];
/// <summary>
/// Raw data SHA1
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[]? RawSHA1 = new byte[20];
}
}

View File

@@ -1,54 +0,0 @@
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, CharSet = CharSet.Unicode)]
public class HeaderV5 : Header
{
/// <summary>
/// Which custom compressors are used?
/// </summary>
public CodecType[] Compressors { get; set; } = new CodecType[4];
/// <summary>
/// Logical size of the data (in bytes)
/// </summary>
public ulong LogicalBytes { get; set; }
/// <summary>
/// Offset to the map
/// </summary>
public ulong MapOffset { get; set; }
/// <summary>
/// Offset to the first blob of metadata
/// </summary>
public ulong MetaOffset { get; set; }
/// <summary>
/// Number of bytes per hunk (512k maximum)
/// </summary>
public uint HunkBytes { get; set; }
/// <summary>
/// Number of bytes per unit within each hunk
/// </summary>
public uint UnitBytes { get; set; }
/// <summary>
/// Raw data SHA1
/// </summary>
public byte[]? RawSHA1 { get; set; }
/// <summary>
/// Combined raw+meta SHA1
/// </summary>
public byte[]? SHA1 { get; set; }
/// <summary>
/// Combined raw+meta SHA1 of parent
/// </summary>
public byte[]? ParentSHA1 { get; set; }
}
}

View File

@@ -1,19 +0,0 @@
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 sealed class MapV1
{
/// <summary>
/// Starting offset within the file
/// </summary>
public ulong StartingOffset;
/// <summary>
/// Length of data; If == hunksize, data is uncompressed
/// </summary>
public ulong Length;
}
}

View File

@@ -1,34 +0,0 @@
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 sealed class MapV3
{
/// <summary>
/// Starting offset within the file
/// </summary>
public ulong StartingOffset;
/// <summary>
/// 32-bit CRC of the uncompressed data
/// </summary>
public uint CRC32;
/// <summary>
/// Lower 16 bits of length
/// </summary>
public ushort LengthLo;
/// <summary>
/// Upper 8 bits of length
/// </summary>
public byte LengthHi;
/// <summary>
/// Flags, indicating compression info
/// </summary>
public byte Flags;
}
}

View File

@@ -1,39 +0,0 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.CHD
{
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.cpp"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class MetadataEntry
{
/// <summary>
/// Offset within the file of the header
/// </summary>
public ulong Offset;
/// <summary>
/// Offset within the file of the next header
/// </summary>
public ulong Next;
/// <summary>
/// Offset within the file of the previous header
/// </summary>
public ulong Prev;
/// <summary>
/// Length of the metadata
/// </summary>
public uint Length;
/// <summary>
/// Metadata tag
/// </summary>
public MetadataTag Metatag;
/// <summary>
/// Flag bits
/// </summary>
public MetadataFlags Flags;
}
}

View File

@@ -1,20 +0,0 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.CHD
{
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.cpp"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class MetadataHash
{
/// <summary>
/// Tag of the metadata in big-endian
/// </summary>
public MetadataTag Tag;
/// <summary>
/// Hash data
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[]? SHA1;
}
}

View File

@@ -1,14 +0,0 @@
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;
}
}

View File

@@ -1,9 +0,0 @@
namespace SabreTools.Models.LDSCRYPT
{
public static class Constants
{
public static readonly byte[] SignatureBytes = [0x4C, 0x44, 0x53, 0x43, 0x52, 0x59, 0x50, 0x54];
public const string SignatureString = "LDSCRYPT";
}
}

View File

@@ -1,10 +0,0 @@
namespace SabreTools.Models.LDSCRYPT
{
/// <summary>
/// This is a placeholder model for future work
/// </summary>
public class EncryptedFile
{
}
}

View File

@@ -1,51 +0,0 @@
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>
/// Descriptors
/// -------------------
/// Pattern of bits 20-31 Type Fields
/// 0b1110xxxxxxxx Interrupt info
/// 0b11110xxxxxxx System call mask Bits 24-26: System call mask table index; Bits 0-23: mask
/// 0b1111110xxxxx Kernel release version Bits 8-15: Major version; Bits 0-7: Minor version
/// 0b11111110xxxx Handle table size Bits 0-18: size
/// 0b111111110xxx Kernel flags
/// 0b11111111100x Map address range Describes a memory mapping like the 0b111111111110 descriptor, but an entire range rather than a single page is mapped.Another 0b11111111100x descriptor must follow this one to denote the(exclusive) end of the address range to map.
/// 0b111111111110 Map memory page Bits 0-19: page index to map(virtual address >> 12; the physical address is determined per-page according to Memory layout); Bit 20: Map read-only(otherwise read-write)
///
/// ARM11 Kernel Flags
/// -------------------
/// Bit Description
/// 0 Allow debug
/// 1 Force debug
/// 2 Allow non-alphanum
/// 3 Shared page writing
/// 4 Privilege priority
/// 5 Allow main() args
/// 6 Shared device memory
/// 7 Runnable on sleep
/// 8-11 Memory type(1: application, 2: system, 3: base)
/// 12 Special memory
/// 13 Process has access to CPU core 2 (New3DS only)
/// </summary>
/// TODO: Make enum for flag values
/// <remarks>28 entries</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 28)]
public uint[]? Descriptors;
/// <summary>
/// Reserved
/// </summary>
/// <remarks>0x10 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x10)]
public byte[]? Reserved;
}
}

View File

@@ -1,81 +0,0 @@
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;
/// <summary>
/// Core version (The Title ID low of the required FIRM)
/// </summary>
public uint CoreVersion;
/// <summary>
/// Flag1 (implemented starting from 8.0.0-18).
/// </summary>
[MarshalAs(UnmanagedType.U1)]
public ARM11LSCFlag1 Flag1;
/// <summary>
/// Flag2 (implemented starting from 8.0.0-18).
/// </summary>
[MarshalAs(UnmanagedType.U1)]
public ARM11LSCFlag2 Flag2;
/// <summary>
/// Flag0
/// </summary>
[MarshalAs(UnmanagedType.U1)]
public ARM11LSCFlag0 Flag0;
/// <summary>
/// Priority
/// </summary>
public byte Priority;
/// <summary>
/// Resource limit descriptors. The first byte here controls the maximum allowed CpuTime.
/// </summary>
/// <remarks>16 entries</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public ushort[]? ResourceLimitDescriptors;
/// <summary>
/// Storage info
/// </summary>
public StorageInfo? StorageInfo;
/// <summary>
/// Service access control
/// </summary>
/// <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>
/// <remarks>2 entries</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public ulong[]? ExtendedServiceAccessControl;
/// <summary>
/// Reserved
/// </summary>
/// <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>
[MarshalAs(UnmanagedType.U1)]
public ResourceLimitCategory ResourceLimitCategory;
}
}

View File

@@ -1,22 +0,0 @@
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>
/// <remarks>15 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 15)]
public ARM9AccessControlDescriptors[]? 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;
}
}

View File

@@ -1,25 +0,0 @@
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;
/// <summary>
/// ARM11 kernel capabilities
/// </summary>
public ARM11KernelCapabilities? ARM11KernelCapabilities;
/// <summary>
/// ARM9 access control
/// </summary>
/// TODO: Fix serialization issue with this type
public ARM9AccessControl? ARM9AccessControl;
}
}

View File

@@ -1,56 +0,0 @@
namespace SabreTools.Models.N3DS
{
/// <summary>
/// CIA stands for CTR Importable Archive. This format allows the installation of
/// titles to the 3DS. CIA files and titles on Nintendo's CDN contain identical data.
/// As a consequence, valid CIA files can be generated from CDN content. This also
/// means CIA files can contain anything that titles on Nintendo's CDN can contain.
///
/// Under normal circumstances CIA files are used where downloading a title is
/// impractical or not possible. Such as distributing a Download Play child, or
/// installing forced Gamecard updates. Those CIA(s) are stored by the titles in
/// question, in an auxiliary CFA file.
/// </summary>
/// <see href="https://www.3dbrew.org/wiki/CIA"/>
public class CIA
{
/// <summary>
/// CIA header
/// </summary>
public CIAHeader? Header { get; set; }
/// <summary>
/// Certificate chain
/// </summary>
/// <remarks>
/// https://www.3dbrew.org/wiki/CIA#Certificate_Chain
/// </remarks>
public Certificate[]? CertificateChain { get; set; }
/// <summary>
/// Ticket
/// </summary>
public Ticket? Ticket { get; set; }
/// <summary>
/// TMD file data
/// </summary>
public TitleMetadata? TMDFileData { get; set; }
/// <summary>
/// Content file data
/// </summary>
public NCCHHeader[]? Partitions { get; set; }
/// <summary>
/// Content file data
/// </summary>
/// TODO: Parse the content file data
public byte[]? ContentFileData { get; set; }
/// <summary>
/// Meta file data (Not a necessary component)
/// </summary>
public MetaData? MetaData { get; set; }
}
}

View File

@@ -1,56 +0,0 @@
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;
/// <summary>
/// Type
/// </summary>
public ushort Type;
/// <summary>
/// Version
/// </summary>
public ushort Version;
/// <summary>
/// Certificate chain size
/// </summary>
public uint CertificateChainSize;
/// <summary>
/// Ticket size
/// </summary>
public uint TicketSize;
/// <summary>
/// TMD file size
/// </summary>
public uint TMDFileSize;
/// <summary>
/// Meta size (0 if no Meta data is present)
/// </summary>
public uint MetaSize;
/// <summary>
/// Content size
/// </summary>
public ulong ContentSize;
/// <summary>
/// Content Index
/// </summary>
/// <remarks>0x2000 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x2000)]
public byte[]? ContentIndex;
}
}

View File

@@ -1,79 +0,0 @@
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;
/// <summary>
/// Card Info Bitmask
/// </summary>
public uint CardInfoBitmask;
/// <summary>
/// Reserved
/// </summary>
/// <remarks>0xF8 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0xF8)]
public byte[]? Reserved1;
/// <summary>
/// Filled size of cartridge
/// </summary>
public uint FilledSize;
/// <summary>
/// Reserved
/// </summary>
/// <remarks>0x0C bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x0C)]
public byte[]? Reserved2;
/// <summary>
/// Title version
/// </summary>
public ushort TitleVersion;
/// <summary>
/// Card revision
/// </summary>
public ushort CardRevision;
/// <summary>
/// Reserved
/// </summary>
/// <remarks>0x0C bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x0C)]
public byte[]? Reserved3;
/// <summary>
/// Title ID of CVer in included update partition
/// </summary>
/// <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;
/// <summary>
/// Reserved
/// </summary>
/// <remarks>0xCD6 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0xCD6)]
public byte[]? Reserved4;
/// <summary>
/// This data is returned by 16-byte cartridge command 0x82.
/// </summary>
public InitialData? InitialData;
}
}

View File

@@ -1,43 +0,0 @@
namespace SabreTools.Models.N3DS
{
/// <summary>
/// Represents a 3DS cart image
/// </summary>
public class Cart
{
/// <summary>
/// 3DS cart header
/// </summary>
public NCSDHeader? Header { get; set; }
/// <summary>
/// 3DS card info header
/// </summary>
public CardInfoHeader? CardInfoHeader { get; set; }
/// <summary>
/// 3DS development card info header
/// </summary>
public DevelopmentCardInfoHeader? DevelopmentCardInfoHeader { get; set; }
/// <summary>
/// NCCH partitions
/// </summary>
public NCCHHeader[]? Partitions { get; set; }
/// <summary>
/// NCCH extended headers
/// </summary>
public NCCHExtendedHeader[]? ExtendedHeaders { get; set; }
/// <summary>
/// ExeFS headers associated with each partition
/// </summary>
public ExeFSHeader[]? ExeFSHeaders { get; set; }
/// <summary>
/// RomFS headers associated with each partition
/// </summary>
public RomFSHeader[]? RomFSHeaders { get; set; }
}
}

View File

@@ -1,92 +0,0 @@
namespace SabreTools.Models.N3DS
{
/// <summary>
/// Certificates contain cryptography information for verifying Signatures.
/// These certificates are also signed. The parent/child relationship between
/// certificates, makes all the certificates effectively signed by 'Root',
/// the public key for which is stored in NATIVE_FIRM.
/// </summary>
/// <see href="https://www.3dbrew.org/wiki/Certificates"/>
public sealed class Certificate
{
/// <summary>
/// Signature Type
/// </summary>
public SignatureType SignatureType { get; set; }
/// <summary>
/// Signature size
/// </summary>
public ushort SignatureSize { get; set; }
/// <summary>
/// Padding size
/// </summary>
public byte PaddingSize { get; set; }
/// <summary>
/// Signature
/// </summary>
public byte[]? Signature { get; set; }
/// <summary>
/// Padding to align next data to 0x40 bytes
/// </summary>
public byte[]? Padding { get; set; }
/// <summary>
/// Issuer
/// </summary>
public string? Issuer { get; set; }
/// <summary>
/// Key Type
/// </summary>
public PublicKeyType KeyType { get; set; }
/// <summary>
/// Name
/// </summary>
public string? Name { get; set; }
/// <summary>
/// Expiration time as UNIX Timestamp, used at least for CTCert
/// </summary>
public uint ExpirationTime { get; set; }
// This contains the Public Key (i.e. Modulus & Public Exponent)
#region RSA-4096 and RSA-2048
/// <summary>
/// Modulus
/// </summary>
public byte[]? RSAModulus { get; set; }
/// <summary>
/// Public Exponent
/// </summary>
public uint RSAPublicExponent { get; set; }
/// <summary>
/// Padding
/// </summary>
public byte[]? RSAPadding { get; set; }
#endregion
// This contains the ECC public key, and is as follows:
#region ECC
/// <summary>
/// Public Key
/// </summary>
public byte[]? ECCPublicKey { get; set; }
/// <summary>
/// Padding
/// </summary>
public byte[]? ECCPadding { get; set; }
#endregion
}
}

View File

@@ -1,24 +0,0 @@
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;
/// <summary>
/// Physical region size (in page-multiples)
/// </summary>
public uint PhysicalRegionSizeInPages;
/// <summary>
/// Size (in bytes)
/// </summary>
public uint SizeInBytes;
}
}

View File

@@ -1,25 +0,0 @@
namespace SabreTools.Models.N3DS
{
public static class Constants
{
// ExeFS
public static readonly byte[] CodeSegmentName = [0x2e, 0x63, 0x6f, 0x64, 0x65, 0x00, 0x00, 0x00]; // .code\0\0\0
// NCCH
public const string NCCHMagicNumber = "NCCH";
// NCSD
public const string NCSDMagicNumber = "NCSD";
// RomFS
public const string RomFSMagicNumber = "IVFC";
public const uint RomFSSecondMagicNumber = 0x10000;
// Setup Keys and IVs
public static byte[] PlainCounter = [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
public static byte[] ExefsCounter = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
public static byte[] RomfsCounter = [0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
public const int CXTExtendedDataHeaderLength = 0x800;
}
}

View File

@@ -1,43 +0,0 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.N3DS
{
/// <summary>
/// There is one of these for each content contained in this title.
/// (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;
/// <summary>
/// Content index
/// </summary>
/// <remarks>
/// This does not apply to DLC.
/// </remarks>
public ContentIndex ContentIndex;
/// <summary>
/// Content type
/// </summary>
public TMDContentType ContentType;
/// <summary>
/// Content size
/// </summary>
public ulong ContentSize;
/// <summary>
/// SHA-256 hash
/// </summary>
/// <remarks>0x20 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)]
public byte[]? SHA256Hash;
}
}

View File

@@ -1,29 +0,0 @@
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;
/// <summary>
/// Content command count [k]
/// </summary>
public ushort ContentCommandCount;
/// <summary>
/// SHA-256 hash of the next k content records that have not been hashed yet
/// </summary>
/// <remarks>0x20 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)]
public byte[]? UnhashedContentRecordsSHA256Hash;
}
}

View File

@@ -1,35 +0,0 @@
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>
/// CardDeviceReserved1
/// </summary>
/// <remarks>0x200 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x200)]
public byte[]? CardDeviceReserved1;
/// <summary>
/// TitleKey
/// </summary>
/// <remarks>0x10 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x10)]
public byte[]? TitleKey;
/// <summary>
/// CardDeviceReserved2
/// </summary>
/// <remarks>0x1BF0 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x1BF0)]
public byte[]? CardDeviceReserved2;
/// <summary>
/// TestData
/// </summary>
public TestData? TestData;
}
}

View File

@@ -1,229 +0,0 @@
using System;
namespace SabreTools.Models.N3DS
{
[Flags]
public enum ARM9AccessControlDescriptors : byte
{
MountNandRoot = 0x01,
MountNandroWriteAccess = 0x02,
MountTwlnRoot = 0x04,
MountWnandRoot = 0x08,
MountCardSPI = 0x0F,
UseSDIF3 = 0x10,
CreateSeed = 0x20,
UseCardSPI = 0x40,
SDApplication = 0x80,
MountSdmcWriteAccess = 0xF0,
}
[Flags]
public enum ARM11LSCFlag0 : byte
{
IdealProcessor = 0x01 | 0x02,
AffinityMask = 0x04 | 0x08,
/// <summary>
/// Value Description
/// 0 Prod (64MB of usable application memory)
/// 1 Undefined (unusable)
/// 2 Dev1 (96MB of usable application memory)
/// 3 Dev2 (80MB of usable application memory)
/// 4 Dev3 (72MB of usable application memory)
/// 5 Dev4 (32MB of usable application memory)
/// 6-7 Undefined Same as Prod?
/// </summary>
Old3DSSystemMode = 0x0F | 0x10 | 0x20 | 0x40,
}
[Flags]
public enum ARM11LSCFlag1 : byte
{
EnableL2Cache = 0x01,
Cpuspeed_804MHz = 0x02,
}
[Flags]
public enum ARM11LSCFlag2 : byte
{
/// <summary>
/// Value Description
/// 0 Legacy (use Old3DS system mode)
/// 1 Prod (124MB of usable application memory)
/// 2 Dev1 (178MB of usable application memory)
/// 3 Dev2 (124MB of usable application memory)
/// 4-7 Undefined Same as Prod?
/// </summary>
New3DSSystemMode = 0x01 | 0x02 | 0x04 | 0x08,
}
[Flags]
public enum BitMasks : byte
{
FixedCryptoKey = 0x01,
NoMountRomFs = 0x02,
NoCrypto = 0x04,
NewKeyYGenerator = 0x20,
}
public enum ContentIndex : ushort
{
/// <summary>
/// Main Content (.CXI for 3DS executable content/.CFA for 3DS Data Archives/.SRL for TWL content)
/// </summary>
MainContent = 0x0000,
/// <summary>
/// Home Menu Manual (.CFA)
/// </summary>
HomeMenuManual = 0x0001,
/// <summary>
/// DLP Child Container (.CFA)
/// </summary>
DLPChildContainer = 0x0002,
}
public enum ContentPlatform : byte
{
CTR = 0x01,
Snake = 0x02, // New3DS
}
[Flags]
public enum ContentType : byte
{
Data = 0x01,
Executable = 0x02,
SystemUpdate = 0x04,
Manual = 0x08,
Child = 0x04 | 0x08,
Trial = 0x10,
}
public enum CryptoMethod : byte
{
Original = 0x00,
Seven = 0x01,
NineThree = 0x0A,
NineSix = 0x0B,
}
[Flags]
public enum FilesystemAccessInfo : ulong
{
CategorySystemApplication = 0x1,
CategoryHardwareCheck = 0x2,
CategoryFilesystemTool = 0x4,
Debug = 0x8,
TWLCardBackup = 0x10,
TWLNANDData = 0x20,
BOSS = 0x40,
sdmcRoot = 0x80,
Core = 0x100,
nandRootroReadOnly = 0x200,
nandRootrw = 0x400,
nandrootroWriteAccess = 0x800,
CategorySystemSettings = 0x1000,
Cardboard = 0x2000,
ExportImportIVS = 0x4000,
sdmcRootWriteOnly = 0x8000,
SwitchCleanup = 0x10000, // Introduced in 3.0.0?
SavedataMove = 0x20000, // Introduced in 5.0.0
Shop = 0x40000, // Introduced in 5.0.0
Shell = 0x80000, // Introduced in 5.0.0
CategoryHomeMenu = 0x100000, // Introduced in 6.0.0
SeedDB = 0x200000, // Introduced in 9.6.0-X FIRM. Home Menu has this bit set starting with 9.6.0-X.
}
public enum FilesystemType : ulong
{
None = 0,
Normal = 1,
FIRM = 3,
AGB_FIRMSave = 4,
}
public enum MediaCardDeviceType : byte
{
NORFlash = 0x01,
None = 0x02,
BT = 0x03,
}
public enum MediaPlatformIndex : byte
{
CTR = 0x01,
}
public enum MediaTypeIndex : byte
{
InnerDevice = 0x00,
Card1 = 0x01,
Card2 = 0x02,
ExtendedDevice = 0x03,
}
public enum NCCHFlags
{
CryptoMethod = 0x03,
ContentPlatform = 0x04,
ContentTypeBitMask = 0x05,
ContentUnitSize = 0x06,
BitMasks = 0x07,
}
public enum NCSDFlags
{
BackupWriteWaitTime = 0x00,
MediaCardDevice3X = 0x03,
MediaPlatformIndex = 0x04,
MediaTypeIndex = 0x05,
MediaUnitSize = 0x06,
MediaCardDevice2X = 0x07,
}
public enum PublicKeyType : uint
{
RSA_4096 = 0x00000000,
RSA_2048 = 0x01000000,
EllipticCurve = 0x02000000,
}
public enum ResourceLimitCategory : byte
{
APPLICATION = 0,
SYS_APPLET = 1,
LIB_APPLET = 2,
OTHER = 3,
}
// Note: These are reversed because of how C# reads values
public enum SignatureType : uint
{
RSA_4096_SHA1 = 0x00000100,
RSA_2048_SHA1 = 0x01000100,
ECDSA_SHA1 = 0x02000100,
RSA_4096_SHA256 = 0x03000100,
RSA_2048_SHA256 = 0x04000100,
ECDSA_SHA256 = 0x05000100,
}
[Flags]
public enum StorageInfoOtherAttributes : byte
{
NotUseROMFS = 0x01,
UseExtendedSavedataAccess = 0x02,
}
[Flags]
public enum TMDContentType : ushort
{
Encrypted = 0x0001,
Disc = 0x0002,
CFM = 0x0004,
Optional = 0x4000,
Shared = 0x8000,
}
}

View File

@@ -1,33 +0,0 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.N3DS
{
/// <summary>
/// There are a maximum of 10 file headers in the ExeFS format. (This maximum
/// number of file headers is disputable, with makerom indicating a maximum of
/// 8 sections and makecia indicating a maximum of 10. From a non-SDK point of
/// view, the ExeFS header format can hold no more than 10 file headers within
/// 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>
/// <remarks>8 bytes</remarks>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
public string? FileName;
/// <summary>
/// File offset
/// </summary>
public uint FileOffset;
/// <summary>
/// File size
/// </summary>
public uint FileSize;
}
}

View File

@@ -1,33 +0,0 @@
namespace SabreTools.Models.N3DS
{
/// <summary>
/// ExeFS or Executable Filesystem contains information related to the
/// executable program, and is the part of the CXI format.
///
/// The ExeFS usually contains one or more of the following files:
/// - .code Contains the code binary, which can be optionally reverse-LZSS compressed via an exheader flag.
/// - logo Contains distribution licensing Binary data.
/// - banner Contains the banner which homemenu uses for this CXI.
/// - icon Contains the icon which homemenu displays for this CXI.
/// </summary>
/// <see href="https://www.3dbrew.org/wiki/ExeFS"/>
public sealed class ExeFSHeader
{
/// <summary>
/// File headers (10 headers maximum, 16 bytes each)
/// </summary>
public ExeFSFileHeader[]? FileHeaders { get; set; }
/// <summary>
/// Reserved
/// </summary>
/// <remarks>0x20 bytes</remarks>
public byte[]? Reserved { get; set; }
/// <summary>
/// File hashes (10 hashes maximum, 32 bytes each, one for each header)
/// </summary>
/// <remarks>SHA-256 hashes</remarks>
public byte[][]? FileHashes { get; set; }
}
}

View File

@@ -1,49 +0,0 @@
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>
/// <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>
/// <remarks>0x10 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x10)]
public byte[]? EncryptedCardSeed;
/// <summary>
/// Card seed AES-MAC
/// </summary>
/// <remarks>0x10 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x10)]
public byte[]? CardSeedAESMAC;
/// <summary>
/// Card seed nonce
/// </summary>
/// <remarks>0x0C bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x0C)]
public byte[]? CardSeedNonce;
/// <summary>
/// Reserved3
/// </summary>
/// <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;
}
}

View File

@@ -1,43 +0,0 @@
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
/// <remarks>0x180 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x180)]
public byte[]? TitleIDDependencyList;
/// <summary>
/// Reserved
/// </summary>
/// <remarks>0x180 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x180)]
public byte[]? Reserved1;
/// <summary>
/// Core Version
/// </summary>
public uint CoreVersion;
/// <summary>
/// Reserved
/// </summary>
/// <remarks>0xFC bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0xFC)]
public byte[]? Reserved2;
/// <summary>
/// Icon Data(.ICN) - Taken from the application's ExeFS
/// </summary>
/// <remarks>0x36C0 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x36C0)]
public byte[]? IconData;
}
}

View File

@@ -1,43 +0,0 @@
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);
/// - 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;
/// <summary>
/// ACI
/// </summary>
public AccessControlInfo? ACI;
/// <summary>
/// AccessDesc signature (RSA-2048-SHA256)
/// </summary>
/// <remarks>0x100 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x100)]
public byte[]? AccessDescSignature;
/// <summary>
/// NCCH HDR RSA-2048 public key
/// </summary>
/// <remarks>0x100 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x100)]
public byte[]? NCCHHDRPublicKey;
/// <summary>
/// ACI (for limitation of first ACI)
/// </summary>
public AccessControlInfo? ACIForLimitations;
}
}

View File

@@ -1,177 +0,0 @@
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>
/// <remarks>0x100 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x100)]
public byte[]? RSA2048Signature;
/// <summary>
/// Magic ID, always 'NCCH'
/// </summary>
/// <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;
/// <summary>
/// Partition ID
/// </summary>
public ulong PartitionId;
/// <summary>
/// Maker code
/// </summary>
public ushort MakerCode;
/// <summary>
/// Version
/// </summary>
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
/// SHA256 hash. The data used for that hash is 0x18-bytes: [0x10-long title-unique content lock seed]
/// [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;
/// <summary>
/// Program ID
/// </summary>
/// <remarks>8 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[]? ProgramId;
/// <summary>
/// Reserved
/// </summary>
/// <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>
/// <remarks>0x20 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)]
public byte[]? LogoRegionHash;
/// <summary>
/// Product code
/// </summary>
/// <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>
/// <remarks>0x20 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)]
public byte[]? ExtendedHeaderHash;
/// <summary>
/// Extended header size, in bytes
/// </summary>
public uint ExtendedHeaderSizeInBytes;
/// <summary>
/// Reserved
/// </summary>
public uint Reserved2;
/// <summary>
/// Flags
/// </summary>
public NCCHHeaderFlags? Flags;
/// <summary>
/// Plain region offset, in media units
/// </summary>
public uint PlainRegionOffsetInMediaUnits;
/// <summary>
/// Plain region size, in media units
/// </summary>
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;
/// <summary>
/// Logo Region size, in media units (For applications built with SDK 5+) (Supported from firmware: 5.0.0-11)
/// </summary>
public uint LogoRegionSizeInMediaUnits;
/// <summary>
/// ExeFS offset, in media units
/// </summary>
public uint ExeFSOffsetInMediaUnits;
/// <summary>
/// ExeFS size, in media units
/// </summary>
public uint ExeFSSizeInMediaUnits;
/// <summary>
/// ExeFS hash region size, in media units
/// </summary>
public uint ExeFSHashRegionSizeInMediaUnits;
/// <summary>
/// Reserved
/// </summary>
public uint Reserved3;
/// <summary>
/// RomFS offset, in media units
/// </summary>
public uint RomFSOffsetInMediaUnits;
/// <summary>
/// RomFS size, in media units
/// </summary>
public uint RomFSSizeInMediaUnits;
/// <summary>
/// RomFS hash region size, in media units
/// </summary>
public uint RomFSHashRegionSizeInMediaUnits;
/// <summary>
/// Reserved
/// </summary>
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>
/// <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>
/// <remarks>0x20 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)]
public byte[]? RomFSSuperblockHash;
}
}

View File

@@ -1,56 +0,0 @@
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;
/// <summary>
/// Reserved
/// </summary>
public byte Reserved1;
/// <summary>
/// Reserved
/// </summary>
public byte Reserved2;
/// <summary>
/// Crypto Method: When this is non-zero, a NCCH crypto method using two keyslots is used.
/// </summary>
[MarshalAs(UnmanagedType.U1)]
public CryptoMethod CryptoMethod;
/// <summary>
/// Content Platform: 1 = CTR, 2 = snake (New 3DS).
/// </summary>
[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>
[MarshalAs(UnmanagedType.U1)]
public ContentType MediaPlatformIndex;
/// <summary>
/// Content Unit Size i.e. u32 ContentUnitSize = 0x200*2^flags[6];
/// </summary>
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>
[MarshalAs(UnmanagedType.U1)]
public BitMasks BitMasks;
}
}

View File

@@ -1,119 +0,0 @@
namespace SabreTools.Models.N3DS
{
/// <summary>
/// There are two known specialisations of the NCSD container format:
/// - The CTR Cart Image (CCI) format, the 3DS' raw NAND format
/// - CCI is the format of game ROM images.
///
/// CTR System Update (CSU) is a variant of CCI, where the only difference
/// is in the file extension.
/// </summary>
/// <see href="https://www.3dbrew.org/wiki/NCSD"/>
public sealed class NCSDHeader
{
#region Common to all NCSD files
/// <summary>
/// RSA-2048 SHA-256 signature of the NCSD header
/// </summary>
public byte[]? RSA2048Signature { get; set; }
/// <summary>
/// Magic Number 'NCSD'
/// </summary>
public string? MagicNumber { get; set; }
/// <summary>
/// Size of the NCSD image, in media units (1 media unit = 0x200 bytes)
/// </summary>
public uint ImageSizeInMediaUnits { get; set; }
/// <summary>
/// Media ID
/// </summary>
public byte[]? MediaId { get; set; }
/// <summary>
/// Partitions FS type (0=None, 1=Normal, 3=FIRM, 4=AGB_FIRM save)
/// </summary>
public FilesystemType PartitionsFSType { get; set; }
/// <summary>
/// Partitions crypt type (each byte corresponds to a partition in the partition table)
/// </summary>
public byte[]? PartitionsCryptType { get; set; }
/// <summary>
/// Offset & Length partition table, in media units
/// </summary>
public PartitionTableEntry[]? PartitionsTable { get; set; }
#endregion
#region CTR Cart Image (CCI) Specific
/// <summary>
/// Exheader SHA-256 hash
/// </summary>
public byte[]? ExheaderHash { get; set; }
/// <summary>
/// Additional header size
/// </summary>
public uint AdditionalHeaderSize { get; set; }
/// <summary>
/// Sector zero offset
/// </summary>
public uint SectorZeroOffset { get; set; }
/// <summary>
/// Partition Flags
/// </summary>
public byte[]? PartitionFlags { get; set; }
/// <summary>
/// Partition ID table
/// </summary>
public ulong[]? PartitionIdTable { get; set; }
/// <summary>
/// Reserved
/// </summary>
public byte[]? Reserved1 { get; set; }
/// <summary>
/// Reserved?
/// </summary>
public byte[]? Reserved2 { get; set; }
/// <summary>
/// Support for this was implemented with 9.6.0-X FIRM. Bit0=1 enables using bits 1-2, it's unknown
/// what these two bits are actually used for(the value of these two bits get compared with some other
/// value during NCSD verification/loading). This appears to enable a new, likely hardware-based,
/// antipiracy check on cartridges.
/// </summary>
public byte FirmUpdateByte1 { get; set; }
/// <summary>
/// Support for this was implemented with 9.6.0-X FIRM, see below regarding save crypto.
/// </summary>
public byte FirmUpdateByte2 { get; set; }
#endregion
#region Raw NAND Format Specific
/// <summary>
/// Unknown
/// </summary>
public byte[]? Unknown { get; set; }
/// <summary>
/// Encrypted MBR partition-table, for the TWL partitions(key-data used for this keyslot is console-unique).
/// </summary>
public byte[]? EncryptedMBR { get; set; }
#endregion
}
}

View File

@@ -1,22 +0,0 @@
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;
/// <summary>
/// Length
/// </summary>
public uint Length;
}
}

View File

@@ -1,101 +0,0 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.N3DS
{
/// <summary>
/// RomFS (or Read-Only Filesystem) is part of the NCCH format, and is
/// used as external file storage.
/// </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>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]
public string? MagicString;
/// <summary>
/// Magic number 0x10000
/// </summary>
public uint MagicNumber;
/// <summary>
/// Master hash size
/// </summary>
public uint MasterHashSize;
/// <summary>
/// Level 1 logical offset
/// </summary>
public ulong Level1LogicalOffset;
/// <summary>
/// Level 1 hashdata size
/// </summary>
public ulong Level1HashdataSize;
/// <summary>
/// Level 1 block size, in log2
/// </summary>
public uint Level1BlockSizeLog2;
/// <summary>
/// Reserved
/// </summary>
public uint Reserved1;
/// <summary>
/// Level 2 logical offset
/// </summary>
public ulong Level2LogicalOffset;
/// <summary>
/// Level 2 hashdata size
/// </summary>
public ulong Level2HashdataSize;
/// <summary>
/// Level 2 block size, in log2
/// </summary>
public uint Level2BlockSizeLog2;
/// <summary>
/// Reserved
/// </summary>
public uint Reserved2;
/// <summary>
/// Level 3 logical offset
/// </summary>
public ulong Level3LogicalOffset;
/// <summary>
/// Level 3 hashdata size
/// </summary>
public ulong Level3HashdataSize;
/// <summary>
/// Level 3 block size, in log2
/// </summary>
public uint Level3BlockSizeLog2;
/// <summary>
/// Reserved
/// </summary>
public uint Reserved3;
/// <summary>
/// Reserved
/// </summary>
public uint Reserved4;
/// <summary>
/// Optional info size.
/// </summary>
public uint OptionalInfoSize;
}
}

View File

@@ -1,46 +0,0 @@
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;
/// <summary>
/// System savedata IDs
/// </summary>
/// <remarks>8 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[]? SystemSavedataIDs;
/// <summary>
/// Storage accessible unique IDs
/// </summary>
/// <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"
/// <remarks>7 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)]
public byte[]? FileSystemAccessInfo;
/// <summary>
/// Other attributes
/// </summary>
[MarshalAs(UnmanagedType.U1)]
public StorageInfoOtherAttributes OtherAttributes;
}
}

View File

@@ -1,75 +0,0 @@
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>
/// <remarks>8 bytes</remarks>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
public string? ApplicationTitle;
/// <summary>
/// Reserved
/// </summary>
/// <remarks>5 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public byte[]? Reserved1;
/// <summary>
/// Flag (bit 0: CompressExefsCode, bit 1: SDApplication)
/// </summary>
public byte Flag;
/// <summary>
/// Remaster version
/// </summary>
public ushort RemasterVersion;
/// <summary>
/// Text code set info
/// </summary>
public CodeSetInfo? TextCodeSetInfo;
/// <summary>
/// Stack size
/// </summary>
public uint StackSize;
/// <summary>
/// Read-only code set info
/// </summary>
public CodeSetInfo? ReadOnlyCodeSetInfo;
/// <summary>
/// Reserved
/// </summary>
public uint Reserved2;
/// <summary>
/// Data code set info
/// </summary>
public CodeSetInfo? DataCodeSetInfo;
/// <summary>
/// BSS size
/// </summary>
public uint BSSSize;
/// <summary>
/// Dependency module (program ID) list
/// </summary>
/// <remarks>48 entries</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 48)]
public ulong[]? DependencyModuleList;
/// <summary>
/// SystemInfo
/// </summary>
public SystemInfo? SystemInfo;
}
}

View File

@@ -1,26 +0,0 @@
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;
/// <summary>
/// Jump ID
/// </summary>
public ulong JumpID;
/// <summary>
/// Reserved
/// </summary>
/// <remarks>0x30 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x30)]
public byte[]? Reserved;
}
}

View File

@@ -1,80 +0,0 @@
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>
/// <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>
/// <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>
/// <remarks>0x200 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x200)]
public byte[]? DescendingByteSequence;
/// <summary>
/// Filled with 00 (0b00000000) bytes.
/// </summary>
/// <remarks>0x200 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x200)]
public byte[]? Filled00;
/// <summary>
/// Filled with FF (0b11111111) bytes.
/// </summary>
/// <remarks>0x200 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x200)]
public byte[]? FilledFF;
/// <summary>
/// Filled with 0F (0b00001111) bytes.
/// </summary>
/// <remarks>0x200 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x200)]
public byte[]? Filled0F;
/// <summary>
/// Filled with F0 (0b11110000) bytes.
/// </summary>
/// <remarks>0x200 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x200)]
public byte[]? FilledF0;
/// <summary>
/// Filled with 55 (0b01010101) bytes.
/// </summary>
/// <remarks>0x200 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x200)]
public byte[]? Filled55;
/// <summary>
/// Filled with AA (0b10101010) bytes.
/// </summary>
/// <remarks>0x1FF bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x1FF)]
public byte[]? FilledAA;
/// <summary>
/// The final byte is 00 (0b00000000).
/// </summary>
public byte FinalByte;
}
}

View File

@@ -1,178 +0,0 @@
namespace SabreTools.Models.N3DS
{
/// <summary>
/// A format used to store an encrypted titlekey (using 128-Bit AES-CBC).
/// With 3DS, the Ticket format was updated (now v1) from Wii/DSi format (v0).
/// </summary>
/// <see href="https://www.3dbrew.org/wiki/Ticket"/>
public sealed class Ticket
{
/// <summary>
/// Signature Type
/// </summary>
public SignatureType SignatureType { get; set; }
/// <summary>
/// Signature size
/// </summary>
public ushort SignatureSize { get; set; }
/// <summary>
/// Padding size
/// </summary>
public byte PaddingSize { get; set; }
/// <summary>
/// Signature
/// </summary>
public byte[]? Signature { get; set; }
/// <summary>
/// Padding
/// </summary>
public byte[]? Padding { get; set; }
/// <summary>
/// Issuer
/// </summary>
public string? Issuer { get; set; }
/// <summary>
/// ECC PublicKey
/// </summary>
public byte[]? ECCPublicKey { get; set; }
/// <summary>
/// Version (For 3DS this is always 1)
/// </summary>
public byte Version { get; set; }
/// <summary>
/// CaCrlVersion
/// </summary>
public byte CaCrlVersion { get; set; }
/// <summary>
/// SignerCrlVersion
/// </summary>
public byte SignerCrlVersion { get; set; }
/// <summary>
/// TitleKey (normal-key encrypted using one of the common keyYs; see below)
/// </summary>
/// <remarks>
/// The titlekey is decrypted by using the AES engine with the ticket common-key keyslot.
/// The keyY is selected through an index (ticket offset 0xB1) into a plaintext array
/// of 6 keys ("common keyYs") stored in the data section of Process9. AES-CBC mode is used
/// where the IV is the big-endian titleID. Note that on a retail unit index0 is a retail keyY,
/// while on a dev-unit index0 is the dev common-key which is a normal-key.
/// (On retail for these keyYs, the hardware key-scrambler is used)
///
/// The titlekey is used to decrypt content downloaded from the CDN using 128-bit AES-CBC with
/// the content index (as big endian u16, padded with trailing zeroes) as the IV.
/// </remarks>
public byte[]? TitleKey { get; set; }
/// <summary>
/// Reserved
/// </summary>
public byte Reserved1 { get; set; }
/// <summary>
/// TicketID
/// </summary>
public ulong TicketID { get; set; }
/// <summary>
/// ConsoleID
/// </summary>
public uint ConsoleID { get; set; }
/// <summary>
/// TitleID
/// </summary>
public ulong TitleID { get; set; }
/// <summary>
/// Reserved
/// </summary>
public byte[]? Reserved2 { get; set; }
/// <summary>
/// Ticket title version
/// </summary>
/// <remarks>
/// The Ticket Title Version is generally the same as the title version stored in the
/// Title Metadata. Although it doesn't have to match the TMD version to be valid.
/// </remarks>
public ushort TicketTitleVersion { get; set; }
/// <summary>
/// Reserved
/// </summary>
public byte[]? Reserved3 { get; set; }
/// <summary>
/// License Type
/// </summary>
public byte LicenseType { get; set; }
/// <summary>
/// Index to the common keyY used for this ticket, usually 0x1 for retail system titles
/// </summary>
public byte CommonKeyYIndex { get; set; }
/// <summary>
/// Reserved
/// </summary>
public byte[]? Reserved4 { get; set; }
/// <summary>
/// eShop Account ID?
/// </summary>
public uint eShopAccountID { get; set; }
/// <summary>
/// Reserved
/// </summary>
public byte Reserved5 { get; set; }
/// <summary>
/// Audit
/// </summary>
public byte Audit { get; set; }
/// <summary>
/// Reserved
/// </summary>
public byte[]? Reserved6 { get; set; }
/// <summary>
/// Limits
/// </summary>
/// <remarks>
/// In demos, the first u32 in the "Limits" section is 0x4, then the second u32 is the max-playcount.
/// </remarks>
public uint[]? Limits { get; set; }
/// <summary>
/// The Content Index of a ticket has its own size defined within itself,
/// with seemingly a minimal of 20 bytes, the second u32 in big endian defines
/// the full value of X.
/// </summary>
public uint ContentIndexSize { get; set; }
/// <summary>
/// Content Index
/// </summary>
public byte[]? ContentIndex { get; set; }
/// <summary>
/// Certificate chain
/// </summary>
/// <remarks>
/// https://www.3dbrew.org/wiki/Ticket#Certificate_Chain
/// </remarks>
public Certificate[]? CertificateChain { get; set; }
}
}

View File

@@ -1,155 +0,0 @@
namespace SabreTools.Models.N3DS
{
/// <summary>
/// A format used to store information about a title (installed title, DLC, etc.)
/// and all its installed contents, including which contents they consist of and
/// their SHA256 hashes.
/// </summary>
/// <see href="https://www.3dbrew.org/wiki/Title_metadata"/>
public sealed class TitleMetadata
{
/// <summary>
/// Signature Type
/// </summary>
public SignatureType SignatureType { get; set; }
/// <summary>
/// Signature size
/// </summary>
public ushort SignatureSize { get; set; }
/// <summary>
/// Padding size
/// </summary>
public byte PaddingSize { get; set; }
/// <summary>
/// Signature
/// </summary>
public byte[]? Signature { get; set; }
/// <summary>
/// Padding
/// </summary>
public byte[]? Padding1 { get; set; }
/// <summary>
/// Signature Issuer
/// </summary>
public string? Issuer { get; set; }
/// <summary>
/// Version
/// </summary>
public byte Version { get; set; }
/// <summary>
/// CaCrlVersion
/// </summary>
public byte CaCrlVersion { get; set; }
/// <summary>
/// SignerCrlVersion
/// </summary>
public byte SignerCrlVersion { get; set; }
/// <summary>
/// Reserved
/// </summary>
public byte Reserved1 { get; set; }
/// <summary>
/// System Version
/// </summary>
public ulong SystemVersion { get; set; }
/// <summary>
/// TitleID
/// </summary>
public ulong TitleID { get; set; }
/// <summary>
/// Title Type
/// </summary>
public uint TitleType { get; set; }
/// <summary>
/// Group ID
/// </summary>
public ushort GroupID { get; set; }
/// <summary>
/// Save Data Size in Little Endian (Bytes) (Also SRL Public Save Data Size)
/// </summary>
public uint SaveDataSize { get; set; }
/// <summary>
/// SRL Private Save Data Size in Little Endian (Bytes)
/// </summary>
public uint SRLPrivateSaveDataSize { get; set; }
/// <summary>
/// Reserved
/// </summary>
public byte[]? Reserved2 { get; set; }
/// <summary>
/// SRL Flag
/// </summary>
public byte SRLFlag { get; set; }
/// <summary>
/// Reserved
/// </summary>
public byte[]? Reserved3 { get; set; }
/// <summary>
/// Access Rights
/// </summary>
public uint AccessRights { get; set; }
/// <summary>
/// Title Version
/// </summary>
public ushort TitleVersion { get; set; }
/// <summary>
/// Content Count (big-endian)
/// </summary>
public ushort ContentCount { get; set; }
/// <summary>
/// Boot Content
/// </summary>
public ushort BootContent { get; set; }
/// <summary>
/// Padding
/// </summary>
public byte[]? Padding2 { get; set; }
/// <summary>
/// SHA-256 Hash of the Content Info Records
/// </summary>
public byte[]? SHA256HashContentInfoRecords { get; set; }
/// <summary>
/// There are 64 of these records, usually only the first is used.
/// </summary>
public ContentInfoRecord[]? ContentInfoRecords { get; set; }
/// <summary>
/// There is one of these for each content contained in this title.
/// (Determined by "Content Count" in the TMD Header).
/// </summary>
public ContentChunkRecord[]? ContentChunkRecords { get; set; }
/// <summary>
/// Certificate chain
/// </summary>
/// <remarks>
/// https://www.3dbrew.org/wiki/Title_metadata#Certificate_Chain
/// </remarks>
public Certificate[]? CertificateChain { get; set; }
}
}

View File

@@ -1,33 +0,0 @@
namespace SabreTools.Models.Nitro
{
/// <summary>
/// Represents a DS/DSi cart image
/// </summary>
public class Cart
{
/// <summary>
/// DS/DSi cart header
/// </summary>
public CommonHeader? CommonHeader { get; set; }
/// <summary>
/// DSi extended cart header
/// </summary>
public ExtendedDSiHeader? ExtendedDSiHeader { get; set; }
/// <summary>
/// Secure area, may be encrypted or decrypted
/// </summary>
public byte[]? SecureArea { get; set; }
/// <summary>
/// Name table (folder allocation table, name list)
/// </summary>
public NameTable? NameTable { get; set; }
/// <summary>
/// File allocation table
/// </summary>
public FileAllocationTableEntry[]? FileAllocationTable { get; set; }
}
}

View File

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

View File

@@ -1,368 +0,0 @@
namespace SabreTools.Models.Nitro
{
public static class Constants
{
public const uint MAGIC30 = 0x72636E65;
public const uint MAGIC34 = 0x6A624F79;
#region Empty Secure Area
public const uint EmptySecureAreaValue1 = 0x00000000;
public const uint EmptySecureAreaValue2 = 0x00000000;
#endregion
#region Improperly Decrypted Secure Area
public const uint ImproperlyDecrypted1Value1 = 0xE386C397;
public const uint ImproperlyDecrypted1Value2 = 0x82775B7E;
public const uint ImproperlyDecrypted2Value1 = 0xF98415B8;
public const uint ImproperlyDecrypted2Value2 = 0x698068FC;
public const uint ImproperlyDecrypted3Value1 = 0xA71329EE;
public const uint ImproperlyDecrypted3Value2 = 0x2A1D4C38;
public const uint ImproperlyDecrypted4Value1 = 0xC44DCC48;
public const uint ImproperlyDecrypted4Value2 = 0x38B6F8CB;
public const uint ImproperlyDecrypted5Value1 = 0x3A9323B5;
public const uint ImproperlyDecrypted5Value2 = 0xC0387241;
#endregion
#region Improperly Encrypted Secure Area
public const uint ImproperlyEncrypted1Value1 = 0x4BCE88BE;
public const uint ImproperlyEncrypted1Value2 = 0xD3662DD1;
public const uint ImproperlyEncrypted2Value1 = 0x2543C534;
public const uint ImproperlyEncrypted2Value2 = 0xCC4BE38E;
#endregion
#region Properly Decrypted Non-Standard Secure Area (Mastering Issue)
/// <remarks>Dragon Quest 5 (EU)</remarks>
public const uint NonStandardDecrypted1Value1 = 0xD0D48B67;
/// <remarks>Dragon Quest 5 (EU)</remarks>
public const uint NonStandardDecrypted1Value2 = 0x39392F23;
/// <remarks>Dragon Quest 5 (USA)</remarks>
public const uint NonStandardDecrypted2Value1 = 0x014A191A;
/// <remarks>Dragon Quest 5 (USA)</remarks>
public const uint NonStandardDecrypted2Value2 = 0xA5C470B9;
/// <remarks>Dragon Quest 5 (JP)</remarks>
public const uint NonStandardDecrypted3Value1 = 0x7829BC8D;
/// <remarks>Dragon Quest 5 (JP)</remarks>
public const uint NonStandardDecrypted3Value2 = 0x9968EF44;
/// <remarks>Prince of Persia (EU)</remarks>
public const uint NonStandardDecrypted4Value1 = 0xC4A15AB8;
/// <remarks>Prince of Persia (EU)</remarks>
public const uint NonStandardDecrypted4Value2 = 0xD2E667C8;
/// <remarks>Prince of Persia (USA)</remarks>
public const uint NonStandardDecrypted5Value1 = 0xD5E97D20;
/// <remarks>Prince of Persia (USA)</remarks>
public const uint NonStandardDecrypted5Value2 = 0x21B2A159;
#endregion
#region Properly Decrypted Prototype Secure Area
public const uint PrototypeDecryptedValue1 = 0xBA35F813;
public const uint PrototypeDecryptedValue2 = 0xB691AAE8;
#endregion
#region Properly Decrypted Secure Area
public const uint DecryptedValue1 = 0xE7FFDEFF;
public const uint DecryptedValue2 = 0xE7FFDEFF;
#endregion
public static byte[] EncryptionData =
[
0x99,0xD5,0x20,0x5F,0x57,0x44,0xF5,0xB9,0x6E,0x19,0xA4,0xD9,0x9E,0x6A,0x5A,0x94,
0xD8,0xAE,0xF1,0xEB,0x41,0x75,0xE2,0x3A,0x93,0x82,0xD0,0x32,0x33,0xEE,0x31,0xD5,
0xCC,0x57,0x61,0x9A,0x37,0x06,0xA2,0x1B,0x79,0x39,0x72,0xF5,0x55,0xAE,0xF6,0xBE,
0x5F,0x1B,0x69,0xFB,0xE5,0x9D,0xF1,0xE9,0xCE,0x2C,0xD9,0xA1,0x5E,0x32,0x05,0xE6,
0xFE,0xD3,0xFE,0xCF,0xD4,0x62,0x04,0x0D,0x8B,0xF5,0xEC,0xB7,0x2B,0x60,0x79,0xBB,
0x12,0x95,0x31,0x0D,0x6E,0x3F,0xDA,0x2B,0x88,0x84,0xF0,0xF1,0x3D,0x12,0x7E,0x25,
0x45,0x22,0xF1,0xBB,0x24,0x06,0x1A,0x06,0x11,0xAD,0xDF,0x28,0x8B,0x64,0x81,0x34,
0x2B,0xEB,0x33,0x29,0x99,0xAA,0xF2,0xBD,0x9C,0x14,0x95,0x9D,0x9F,0xF7,0xF5,0x8C,
0x72,0x97,0xA1,0x29,0x9D,0xD1,0x5F,0xCF,0x66,0x4D,0x07,0x1A,0xDE,0xD3,0x4A,0x4B,
0x85,0xC9,0xA7,0xA3,0x17,0x95,0x05,0x3A,0x3D,0x49,0x0A,0xBF,0x0A,0x89,0x8B,0xA2,
0x4A,0x82,0x49,0xDD,0x27,0x90,0xF1,0x0B,0xE9,0xEB,0x1C,0x6A,0x83,0x76,0x45,0x05,
0xBA,0x81,0x70,0x61,0x17,0x3F,0x4B,0xDE,0xAE,0xCF,0xAB,0x39,0x57,0xF2,0x3A,0x56,
0x48,0x11,0xAD,0x8A,0x40,0xE1,0x45,0x3F,0xFA,0x9B,0x02,0x54,0xCA,0xA6,0x93,0xFB,
0xEF,0x4D,0xFE,0x6F,0xA3,0xD8,0x87,0x9C,0x08,0xBA,0xD5,0x48,0x6A,0x8D,0x2D,0xFD,
0x6E,0x15,0xF8,0x74,0xBD,0xBE,0x52,0x8B,0x18,0x22,0x8A,0x9E,0xFB,0x74,0x37,0x07,
0x1B,0x36,0x6C,0x4A,0x19,0xBA,0x42,0x62,0xB9,0x79,0x91,0x10,0x7B,0x67,0x65,0x96,
0xFE,0x02,0x23,0xE8,0xEE,0x99,0x8C,0x77,0x3E,0x5C,0x86,0x64,0x4D,0x6D,0x78,0x86,
0xA5,0x4F,0x65,0xE2,0x1E,0xB2,0xDF,0x5A,0x0A,0xD0,0x7E,0x08,0x14,0xB0,0x71,0xAC,
0xBD,0xDB,0x83,0x1C,0xB9,0xD7,0xA1,0x62,0xCD,0xC6,0x63,0x7C,0x52,0x69,0xC3,0xE6,
0xBF,0x75,0xCE,0x12,0x44,0x5D,0x21,0x04,0xFA,0xFB,0xD3,0x3C,0x38,0x11,0x63,0xD4,
0x95,0x85,0x41,0x49,0x46,0x09,0xF2,0x08,0x43,0x11,0xDC,0x1F,0x76,0xC0,0x15,0x6D,
0x1F,0x3C,0x63,0x70,0xEA,0x87,0x80,0x6C,0xC3,0xBD,0x63,0x8B,0xC2,0x37,0x21,0x37,
0xDC,0xEE,0x09,0x23,0x2E,0x37,0x6A,0x4D,0x73,0x90,0xF7,0x50,0x30,0xAC,0x1C,0x92,
0x04,0x10,0x23,0x91,0x4F,0xD2,0x07,0xAA,0x68,0x3E,0x4F,0x9A,0xC9,0x64,0x60,0x6A,
0xC8,0x14,0x21,0xF3,0xD6,0x22,0x41,0x12,0x44,0x24,0xCF,0xE6,0x8A,0x56,0xDD,0x0D,
0x53,0x4D,0xE1,0x85,0x1E,0x8C,0x52,0x5A,0x9C,0x19,0x84,0xC2,0x03,0x57,0xF1,0x6F,
0xE3,0x00,0xBE,0x58,0xF6,0x4C,0xED,0xD5,0x21,0x64,0x9C,0x1F,0xBE,0x55,0x03,0x3C,
0x4A,0xDC,0xFF,0xAA,0xC9,0xDA,0xE0,0x5D,0x5E,0xBF,0xE6,0xDE,0xF5,0xD8,0xB1,0xF8,
0xFF,0x36,0xB3,0xB9,0x62,0x67,0x95,0xDB,0x31,0x5F,0x37,0xED,0x4C,0x70,0x67,0x99,
0x90,0xB5,0x18,0x31,0x6C,0x3D,0x99,0x99,0xE4,0x42,0xDA,0xD3,0x25,0x42,0x13,0xA0,
0xAE,0xD7,0x70,0x6C,0xB1,0x55,0xCF,0xC7,0xD7,0x46,0xD5,0x43,0x61,0x17,0x3D,0x44,
0x28,0xE9,0x33,0x85,0xD5,0xD0,0xA2,0x93,0xAA,0x25,0x12,0x1F,0xFB,0xC5,0x0B,0x46,
0xF5,0x97,0x76,0x56,0x45,0xA6,0xBE,0x87,0xB1,0x94,0x6B,0xE8,0xB1,0xFE,0x33,0x99,
0xAE,0x1F,0x3E,0x6C,0x39,0x71,0x1D,0x09,0x00,0x90,0x37,0xE4,0x10,0x3E,0x75,0x74,
0xFF,0x8C,0x83,0x3B,0xB0,0xF1,0xB0,0xF9,0x01,0x05,0x47,0x42,0x95,0xF1,0xD6,0xAC,
0x7E,0x38,0xE6,0x9E,0x95,0x74,0x26,0x3F,0xB4,0x68,0x50,0x18,0xD0,0x43,0x30,0xB4,
0x4C,0x4B,0xE3,0x68,0xBF,0xE5,0x4D,0xB6,0x95,0x8B,0x0A,0xA0,0x74,0x25,0x32,0x77,
0xCF,0xA1,0xF7,0x2C,0xD8,0x71,0x13,0x5A,0xAB,0xEA,0xC9,0x51,0xE8,0x0D,0xEE,0xEF,
0xE9,0x93,0x7E,0x19,0xA7,0x1E,0x43,0x38,0x81,0x16,0x2C,0xA1,0x48,0xE3,0x73,0xCC,
0x29,0x21,0x6C,0xD3,0x5D,0xCE,0xA0,0xD9,0x61,0x71,0x43,0xA0,0x15,0x13,0xB5,0x64,
0x92,0xCF,0x2A,0x19,0xDC,0xAD,0xB7,0xA5,0x9F,0x86,0x65,0xF8,0x1A,0x9F,0xE7,0xFB,
0xF7,0xFD,0xB8,0x13,0x6C,0x27,0xDB,0x6F,0xDF,0x35,0x1C,0xF7,0x8D,0x2C,0x5B,0x9B,
0x12,0xAB,0x38,0x64,0x06,0xCC,0xDE,0x31,0xE8,0x4E,0x75,0x11,0x64,0xE3,0xFA,0xEA,
0xEB,0x34,0x54,0xC2,0xAD,0x3F,0x34,0xEB,0x93,0x2C,0x7D,0x26,0x36,0x9D,0x56,0xF3,
0x5A,0xE1,0xF6,0xB3,0x98,0x63,0x4A,0x9E,0x32,0x83,0xE4,0x9A,0x84,0x60,0x7D,0x90,
0x2E,0x13,0x0E,0xEE,0x93,0x4B,0x36,0xA2,0x85,0xEC,0x16,0x38,0xE8,0x88,0x06,0x02,
0xBF,0xF0,0xA0,0x3A,0xED,0xD7,0x6A,0x9A,0x73,0xE1,0x57,0xCF,0xF8,0x44,0xB8,0xDC,
0x2E,0x23,0x59,0xD1,0xDF,0x95,0x52,0x71,0x99,0x61,0xA0,0x4B,0xD5,0x7F,0x6E,0x78,
0xBA,0xA9,0xC5,0x30,0xD3,0x40,0x86,0x32,0x9D,0x32,0x0C,0x9C,0x37,0xB7,0x02,0x2F,
0xBA,0x54,0x98,0xA9,0xC4,0x13,0x04,0xC9,0x8D,0xBE,0xC8,0xE7,0x5D,0x97,0x50,0x2E,
0x93,0xD6,0x22,0x59,0x0C,0x27,0xBC,0x22,0x92,0xE0,0xA7,0x20,0x0F,0x93,0x6F,0x7F,
0x4C,0x9F,0xD3,0xB5,0xA6,0x2A,0x0B,0x74,0x67,0x49,0x7D,0x10,0x26,0xCB,0xD1,0xC5,
0x86,0x71,0xE7,0x8C,0xA0,0x9C,0xE9,0x5B,0xB2,0x1A,0xF6,0x01,0xEE,0x8C,0x9E,0x5E,
0x83,0xF2,0x1A,0xDB,0xE6,0xE5,0xEA,0x84,0x59,0x76,0xD2,0x7C,0xF6,0x8D,0xA5,0x49,
0x36,0x48,0xC2,0x16,0x52,0xBB,0x83,0xA3,0x74,0xB9,0x07,0x0C,0x3B,0xFF,0x61,0x28,
0xE1,0x61,0xE9,0xE4,0xEF,0x6E,0x15,0xAA,0x4E,0xBA,0xE8,0x5D,0x05,0x96,0xBB,0x32,
0x56,0xB0,0xFB,0x72,0x52,0x0F,0x0E,0xC8,0x42,0x25,0x65,0x76,0x89,0xAF,0xF2,0xDE,
0x10,0x27,0xF0,0x01,0x4B,0x74,0xA7,0x97,0x07,0xD5,0x26,0x54,0x54,0x09,0x1F,0x82,
0x0A,0x86,0x7D,0x30,0x39,0x0E,0xB3,0x26,0x9B,0x0B,0x57,0xBB,0x36,0x06,0x31,0xAF,
0xFD,0x79,0xFC,0xD9,0x30,0x10,0x2B,0x0C,0xB3,0xE1,0x9B,0xD7,0x7B,0xDC,0x5F,0xEF,
0xD2,0xF8,0x13,0x45,0x4D,0x47,0x75,0xBD,0x46,0x96,0x3C,0x7E,0x75,0xF3,0x3E,0xB5,
0x67,0xC5,0x9A,0x3B,0xB0,0x5B,0x29,0x6B,0xDE,0x80,0x5B,0xC8,0x15,0x05,0xB1,0x31,
0xB6,0xCE,0x49,0xDD,0xAD,0x84,0xB5,0xAE,0x60,0xDC,0x67,0x31,0x34,0x30,0xFE,0x4E,
0xBD,0x80,0x2F,0xA6,0xBF,0x63,0x39,0x21,0x86,0xD9,0x35,0x7F,0x16,0x68,0x22,0x05,
0x54,0xE9,0x90,0x26,0x8C,0x07,0x6C,0x51,0xA4,0x31,0x55,0xD7,0x09,0x07,0xA8,0x3E,
0x2E,0x53,0x66,0xC1,0xF8,0xF2,0x7B,0xC4,0xF2,0x58,0xCF,0xF1,0x87,0xC5,0xA2,0xE7,
0x27,0x8F,0x30,0x87,0x58,0xA0,0x64,0x62,0x23,0x18,0xB9,0x88,0x7C,0xFA,0xCE,0xC4,
0x98,0xAE,0xAD,0x17,0xCC,0x4A,0x5B,0xF3,0xE9,0x48,0xD5,0x56,0xD3,0x0D,0xF2,0xC8,
0x92,0x73,0x8C,0xDB,0xD7,0x2F,0x56,0xAC,0x81,0xF9,0x92,0x69,0x4D,0xC6,0x32,0xF6,
0xE6,0xC0,0x8D,0x21,0xE2,0x76,0x80,0x61,0x11,0xBC,0xDC,0x6C,0x93,0xAF,0x19,0x69,
0x9B,0xD0,0xBF,0xB9,0x31,0x9F,0x02,0x67,0xA3,0x51,0xEE,0x83,0x06,0x22,0x7B,0x0C,
0xAB,0x49,0x42,0x40,0xB8,0xD5,0x01,0x7D,0xCE,0x5E,0xF7,0x55,0x53,0x39,0xC5,0x99,
0x46,0xD8,0x87,0x9F,0xBA,0xF7,0x64,0xB4,0xE3,0x9A,0xFA,0xA1,0x6D,0x90,0x68,0x10,
0x30,0xCA,0x8A,0x54,0xA7,0x9F,0x60,0xC3,0x19,0xF5,0x6B,0x0D,0x7A,0x51,0x98,0xE6,
0x98,0x43,0x51,0xB4,0xD6,0x35,0xE9,0x4F,0xC3,0xDF,0x0F,0x7B,0xD6,0x2F,0x5C,0xBD,
0x3A,0x15,0x61,0x19,0xF1,0x4B,0xCB,0xAA,0xDC,0x6D,0x64,0xC9,0xD3,0xC6,0x1E,0x56,
0xEF,0x38,0x4C,0x50,0x71,0x86,0x75,0xCC,0x0D,0x0D,0x4E,0xE9,0x28,0xF6,0x06,0x5D,
0x70,0x1B,0xAA,0xD3,0x45,0xCF,0xA8,0x39,0xAC,0x95,0xA6,0x2E,0xB4,0xE4,0x22,0xD4,
0x74,0xA8,0x37,0x5F,0x48,0x7A,0x04,0xCC,0xA5,0x4C,0x40,0xD8,0x28,0xB4,0x28,0x08,
0x0D,0x1C,0x72,0x52,0x41,0xF0,0x7D,0x47,0x19,0x3A,0x53,0x4E,0x58,0x84,0x62,0x6B,
0x93,0xB5,0x8A,0x81,0x21,0x4E,0x0D,0xDC,0xB4,0x3F,0xA2,0xC6,0xFC,0xC9,0x2B,0x40,
0xDA,0x38,0x04,0xE9,0x5E,0x5A,0x86,0x6B,0x0C,0x22,0x25,0x85,0x68,0x11,0x8D,0x7C,
0x92,0x1D,0x95,0x55,0x4D,0xAB,0x8E,0xBB,0xDA,0xA6,0xE6,0xB7,0x51,0xB6,0x32,0x5A,
0x05,0x41,0xDD,0x05,0x2A,0x0A,0x56,0x50,0x91,0x17,0x47,0xCC,0xC9,0xE6,0x7E,0xB5,
0x61,0x4A,0xDB,0x73,0x67,0x51,0xC8,0x33,0xF5,0xDA,0x6E,0x74,0x2E,0x54,0xC3,0x37,
0x0D,0x6D,0xAF,0x08,0xE8,0x15,0x8A,0x5F,0xE2,0x59,0x21,0xCD,0xA8,0xDE,0x0C,0x06,
0x5A,0x77,0x6B,0x5F,0xDB,0x18,0x65,0x3E,0xC8,0x50,0xDE,0x78,0xE0,0xB8,0x82,0xB3,
0x5D,0x4E,0x72,0x32,0x07,0x4F,0xC1,0x34,0x23,0xBA,0x96,0xB7,0x67,0x4E,0xA4,0x28,
0x1E,0x34,0x62,0xEB,0x2D,0x6A,0x70,0xE9,0x2F,0x42,0xC4,0x70,0x4E,0x5A,0x31,0x9C,
0xF9,0x5B,0x47,0x28,0xAA,0xDA,0x71,0x6F,0x38,0x1F,0xB3,0x78,0xC4,0x92,0x6B,0x1C,
0x9E,0xF6,0x35,0x9A,0xB7,0x4D,0x0E,0xBF,0xCC,0x18,0x29,0x41,0x03,0x48,0x35,0x5D,
0x55,0xD0,0x2B,0xC6,0x29,0xAF,0x5C,0x60,0x74,0x69,0x8E,0x5E,0x9B,0x7C,0xD4,0xBD,
0x7B,0x44,0x64,0x7D,0x3F,0x92,0x5D,0x69,0xB6,0x1F,0x00,0x4B,0xD4,0x83,0x35,0xCF,
0x7E,0x64,0x4E,0x17,0xAE,0x8D,0xD5,0x2E,0x9A,0x28,0x12,0x4E,0x2E,0x2B,0x49,0x08,
0x5C,0xAE,0xC6,0x46,0x85,0xAE,0x41,0x61,0x1E,0x6F,0x82,0xD2,0x51,0x37,0x16,0x1F,
0x0B,0xF6,0x59,0xA4,0x9A,0xCA,0x5A,0xAF,0x0D,0xD4,0x33,0x8B,0x20,0x63,0xF1,0x84,
0x80,0x5C,0xCB,0xCF,0x08,0xB4,0xB9,0xD3,0x16,0x05,0xBD,0x62,0x83,0x31,0x9B,0x56,
0x51,0x98,0x9F,0xBA,0xB2,0x5B,0xAA,0xB2,0x22,0x6B,0x2C,0xB5,0xD4,0x48,0xFA,0x63,
0x2B,0x5F,0x58,0xFA,0x61,0xFA,0x64,0x09,0xBB,0x38,0xE0,0xB8,0x9D,0x92,0x60,0xA8,
0x0D,0x67,0x6F,0x0E,0x37,0xF5,0x0D,0x01,0x9F,0xC2,0x77,0xD4,0xFE,0xEC,0xF1,0x73,
0x30,0x39,0xE0,0x7D,0xF5,0x61,0x98,0xE4,0x2C,0x28,0x55,0x04,0x56,0x55,0xDB,0x2F,
0x6B,0xEC,0xE5,0x58,0x06,0xB6,0x64,0x80,0x6A,0x2A,0x1A,0x4E,0x5B,0x0F,0xD8,0xC4,
0x0A,0x2E,0x52,0x19,0xD9,0x62,0xF5,0x30,0x48,0xBE,0x8C,0x7B,0x4F,0x38,0x9B,0xA2,
0xC3,0xAF,0xC9,0xD3,0xC7,0xC1,0x62,0x41,0x86,0xB9,0x61,0x21,0x57,0x6F,0x99,0x4F,
0xC1,0xBA,0xCE,0x7B,0xB5,0x3B,0x4D,0x5E,0x8A,0x8B,0x44,0x57,0x5F,0x13,0x5F,0x70,
0x6D,0x5B,0x29,0x47,0xDC,0x38,0xE2,0xEC,0x04,0x55,0x65,0x12,0x2A,0xE8,0x17,0x43,
0xE1,0x8E,0xDD,0x2A,0xB3,0xE2,0x94,0xF7,0x09,0x6E,0x5C,0xE6,0xEB,0x8A,0xF8,0x6D,
0x89,0x49,0x54,0x48,0xF5,0x2F,0xAD,0xBF,0xEA,0x94,0x4B,0xCA,0xFC,0x39,0x87,0x82,
0x5F,0x8A,0x01,0xF2,0x75,0xF2,0xE6,0x71,0xD6,0xD8,0x42,0xDE,0xF1,0x2D,0x1D,0x28,
0xA6,0x88,0x7E,0xA3,0xA0,0x47,0x1D,0x30,0xD9,0xA3,0x71,0xDF,0x49,0x1C,0xCB,0x01,
0xF8,0x36,0xB1,0xF2,0xF0,0x22,0x58,0x5D,0x45,0x6B,0xBD,0xA0,0xBB,0xB2,0x88,0x42,
0xC7,0x8C,0x28,0xCE,0x93,0xE8,0x90,0x63,0x08,0x90,0x7C,0x89,0x3C,0xF5,0x7D,0xB7,
0x04,0x2D,0x4F,0x55,0x51,0x16,0xFD,0x7E,0x79,0xE8,0xBE,0xC1,0xF2,0x12,0xD4,0xF8,
0xB4,0x84,0x05,0x23,0xA0,0xCC,0xD2,0x2B,0xFD,0xE1,0xAB,0xAD,0x0D,0xD1,0x55,0x6C,
0x23,0x41,0x94,0x4D,0x77,0x37,0x4F,0x05,0x28,0x0C,0xBF,0x17,0xB3,0x12,0x67,0x6C,
0x8C,0xC3,0x5A,0xF7,0x41,0x84,0x2A,0x6D,0xD0,0x94,0x12,0x27,0x2C,0xB4,0xED,0x9C,
0x4D,0xEC,0x47,0x82,0x97,0xD5,0x67,0xB9,0x1B,0x9D,0xC0,0x55,0x07,0x7E,0xE5,0x8E,
0xE2,0xA8,0xE7,0x3E,0x12,0xE4,0x0E,0x3A,0x2A,0x45,0x55,0x34,0xA2,0xF9,0x2D,0x5A,
0x1B,0xAB,0x52,0x7C,0x83,0x10,0x5F,0x55,0xD2,0xF1,0x5A,0x43,0x2B,0xC6,0xA7,0xA4,
0x89,0x15,0x95,0xE8,0xB4,0x4B,0x9D,0xF8,0x75,0xE3,0x9F,0x60,0x78,0x5B,0xD6,0xE6,
0x0D,0x44,0xE6,0x21,0x06,0xBD,0x47,0x22,0x53,0xA4,0x00,0xAD,0x8D,0x43,0x13,0x85,
0x39,0xF7,0xAA,0xFC,0x38,0xAF,0x7B,0xED,0xFC,0xE4,0x2B,0x54,0x50,0x98,0x4C,0xFC,
0x85,0x80,0xF7,0xDF,0x3C,0x80,0x22,0xE1,0x94,0xDA,0xDE,0x24,0xC6,0xB0,0x7A,0x39,
0x38,0xDC,0x0F,0xA1,0xA7,0xF4,0xF9,0x6F,0x63,0x18,0x57,0x8B,0x84,0x41,0x2A,0x2E,
0xD4,0x53,0xF2,0xD9,0x00,0x0F,0xD0,0xDD,0x99,0x6E,0x19,0xA6,0x0A,0xD0,0xEC,0x5B,
0x58,0x24,0xAB,0xC0,0xCB,0x06,0x65,0xEC,0x1A,0x13,0x38,0x94,0x0A,0x67,0x03,0x2F,
0x3F,0xF7,0xE3,0x77,0x44,0x77,0x33,0xC6,0x14,0x39,0xD0,0xE3,0xC0,0xA2,0x08,0x79,
0xBB,0x40,0x99,0x57,0x41,0x0B,0x01,0x90,0xCD,0xE1,0xCC,0x48,0x67,0xDB,0xB3,0xAF,
0x88,0x74,0xF3,0x4C,0x82,0x8F,0x72,0xB1,0xB5,0x23,0x29,0xC4,0x12,0x6C,0x19,0xFC,
0x8E,0x46,0xA4,0x9C,0xC4,0x25,0x65,0x87,0xD3,0x6D,0xBE,0x8A,0x93,0x11,0x03,0x38,
0xED,0x83,0x2B,0xF3,0x46,0xA4,0x93,0xEA,0x3B,0x53,0x85,0x1D,0xCE,0xD4,0xF1,0x08,
0x83,0x27,0xED,0xFC,0x9B,0x1A,0x18,0xBC,0xF9,0x8B,0xAE,0xDC,0x24,0xAB,0x50,0x38,
0xE9,0x72,0x4B,0x10,0x22,0x17,0x7B,0x46,0x5D,0xAB,0x59,0x64,0xF3,0x40,0xAE,0xF8,
0xBB,0xE5,0xC8,0xF9,0x26,0x03,0x4E,0x55,0x7D,0xEB,0xEB,0xFE,0xF7,0x39,0xE6,0xE0,
0x0A,0x11,0xBE,0x2E,0x28,0xFF,0x98,0xED,0xC0,0xC9,0x42,0x56,0x42,0xC3,0xFD,0x00,
0xF6,0xAF,0x87,0xA2,0x5B,0x01,0x3F,0x32,0x92,0x47,0x95,0x9A,0x72,0xA5,0x32,0x3D,
0xAE,0x6B,0xD0,0x9B,0x07,0xD2,0x49,0x92,0xE3,0x78,0x4A,0xFA,0xA1,0x06,0x7D,0xF2,
0x41,0xCF,0x77,0x74,0x04,0x14,0xB2,0x0C,0x86,0x84,0x64,0x16,0xD5,0xBB,0x51,0xA1,
0xE5,0x6F,0xF1,0xD1,0xF2,0xE2,0xF7,0x5F,0x58,0x20,0x4D,0xB8,0x57,0xC7,0xCF,0xDD,
0xC5,0xD8,0xBE,0x76,0x3D,0xF6,0x5F,0x7E,0xE7,0x2A,0x8B,0x88,0x24,0x1B,0x38,0x3F,
0x0E,0x41,0x23,0x77,0xF5,0xF0,0x4B,0xD4,0x0C,0x1F,0xFA,0xA4,0x0B,0x80,0x5F,0xCF,
0x45,0xF6,0xE0,0xDA,0x2F,0x34,0x59,0x53,0xFB,0x20,0x3C,0x52,0x62,0x5E,0x35,0xB5,
0x62,0xFE,0x8B,0x60,0x63,0xE3,0x86,0x5A,0x15,0x1A,0x6E,0xD1,0x47,0x45,0xBC,0x32,
0xB4,0xEB,0x67,0x38,0xAB,0xE4,0x6E,0x33,0x3A,0xB5,0xED,0xA3,0xAD,0x67,0xE0,0x4E,
0x41,0x95,0xEE,0x62,0x62,0x71,0x26,0x1D,0x31,0xEF,0x62,0x30,0xAF,0xD7,0x82,0xAC,
0xC2,0xDC,0x05,0x04,0xF5,0x97,0x07,0xBF,0x11,0x59,0x23,0x07,0xC0,0x64,0x02,0xE8,
0x97,0xE5,0x3E,0xAF,0x18,0xAC,0x59,0xA6,0x8B,0x4A,0x33,0x90,0x1C,0x6E,0x7C,0x9C,
0x20,0x7E,0x4C,0x3C,0x3E,0x61,0x64,0xBB,0xC5,0x6B,0x7C,0x7E,0x3E,0x9F,0xC5,0x4C,
0x9F,0xEA,0x73,0xF5,0xD7,0x89,0xC0,0x4C,0xF4,0xFB,0xF4,0x2D,0xEC,0x14,0x1B,0x51,
0xD5,0xC1,0x12,0xC8,0x10,0xDF,0x0B,0x4A,0x8B,0x9C,0xBC,0x93,0x45,0x6A,0x3E,0x3E,
0x7D,0xC1,0xA9,0xBA,0xCD,0xC1,0xB4,0x07,0xE4,0xE1,0x68,0x86,0x43,0xB2,0x6D,0x38,
0xF3,0xFB,0x0C,0x5C,0x66,0x37,0x71,0xDE,0x56,0xEF,0x6E,0xA0,0x10,0x40,0x65,0xA7,
0x98,0xF7,0xD0,0xBE,0x0E,0xC8,0x37,0x36,0xEC,0x10,0xCA,0x7C,0x9C,0xAB,0x84,0x1E,
0x05,0x17,0x76,0x02,0x1C,0x4F,0x52,0xAA,0x5F,0xC1,0xC6,0xA0,0x56,0xB9,0xD8,0x04,
0x84,0x44,0x4D,0xA7,0x59,0xD8,0xDE,0x60,0xE6,0x38,0x0E,0x05,0x8F,0x03,0xE1,0x3B,
0x6D,0x81,0x04,0x33,0x6F,0x30,0x0B,0xCE,0x69,0x05,0x21,0x33,0xFB,0x26,0xBB,0x89,
0x7D,0xB6,0xAE,0x87,0x7E,0x51,0x07,0xE0,0xAC,0xF7,0x96,0x0A,0x6B,0xF9,0xC4,0x5C,
0x1D,0xE4,0x44,0x47,0xB8,0x5E,0xFA,0xE3,0x78,0x84,0x55,0x42,0x4B,0x48,0x5E,0xF7,
0x7D,0x47,0x35,0x86,0x1D,0x2B,0x43,0x05,0x03,0xEC,0x8A,0xB8,0x1E,0x06,0x3C,0x76,
0x0C,0x48,0x1A,0x43,0xA7,0xB7,0x8A,0xED,0x1E,0x13,0xC6,0x43,0xEE,0x10,0xEF,0xDB,
0xEC,0xFB,0x3C,0x83,0xB2,0x95,0x44,0xEF,0xD8,0x54,0x51,0x4E,0x2D,0x11,0x44,0x1D,
0xFB,0x36,0x59,0x1E,0x7A,0x34,0xC1,0xC3,0xCA,0x57,0x00,0x61,0xEA,0x67,0xA5,0x16,
0x9B,0x55,0xD0,0x55,0xE1,0x7F,0xD9,0x36,0xD2,0x40,0x76,0xAE,0xDC,0x01,0xCE,0xB0,
0x7A,0x83,0xD5,0xCB,0x20,0x98,0xEC,0x6B,0xC1,0x72,0x92,0x34,0xF3,0x82,0x57,0x37,
0x62,0x8A,0x32,0x36,0x0C,0x90,0x43,0xAE,0xAE,0x5C,0x9B,0x78,0x8E,0x13,0x65,0x02,
0xFD,0x68,0x71,0xC1,0xFE,0xB0,0x31,0xA0,0x24,0x82,0xB0,0xC3,0xB1,0x79,0x69,0xA7,
0xF5,0xD2,0xEB,0xD0,0x82,0xC0,0x32,0xDC,0x9E,0xC7,0x26,0x3C,0x6D,0x8D,0x98,0xC1,
0xBB,0x22,0xD4,0xD0,0x0F,0x33,0xEC,0x3E,0xB9,0xCC,0xE1,0xDC,0x6A,0x4C,0x77,0x36,
0x14,0x1C,0xF9,0xBF,0x81,0x9F,0x28,0x5F,0x71,0x85,0x32,0x29,0x90,0x75,0x48,0xC4,
0xB3,0x4A,0xCE,0xD8,0x44,0x8F,0x14,0x2F,0xFD,0x40,0x57,0xEF,0xAA,0x08,0x75,0xD9,
0x46,0xD1,0xD6,0x6E,0x32,0x55,0x1F,0xC3,0x18,0xFE,0x84,0x1F,0xFC,0x84,0xD5,0xFF,
0x71,0x5E,0x1B,0x48,0xC3,0x86,0x95,0x0E,0x28,0x08,0x27,0xD3,0x38,0x83,0x71,0x7B,
0x4C,0x80,0x63,0x54,0x9A,0x56,0xB0,0xAC,0xCF,0x80,0xCA,0x31,0x09,0xEF,0xFE,0xF3,
0xBE,0xAF,0x24,0x7E,0xA6,0xFE,0x53,0x3F,0xC2,0x8D,0x4A,0x33,0x68,0xD1,0x22,0xA6,
0x66,0xAD,0x7B,0xEA,0xDE,0xB6,0x43,0xB0,0xA1,0x25,0x95,0x00,0xA3,0x3F,0x75,0x46,
0x14,0x11,0x44,0xEC,0xD7,0x95,0xBC,0x92,0xF0,0x4F,0xA9,0x16,0x53,0x62,0x97,0x60,
0x2A,0x0F,0x41,0xF1,0x71,0x24,0xBE,0xEE,0x94,0x7F,0x08,0xCD,0x60,0x93,0xB3,0x85,
0x5B,0x07,0x00,0x3F,0xD8,0x0F,0x28,0x83,0x9A,0xD1,0x69,0x9F,0xD1,0xDA,0x2E,0xC3,
0x90,0x01,0xA2,0xB9,0x6B,0x4E,0x2A,0x66,0x9D,0xDA,0xAE,0xA6,0xEA,0x2A,0xD3,0x68,
0x2F,0x0C,0x0C,0x9C,0xD2,0x8C,0x4A,0xED,0xE2,0x9E,0x57,0x65,0x9D,0x09,0x87,0xA3,
0xB4,0xC4,0x32,0x5D,0xC9,0xD4,0x32,0x2B,0xB1,0xE0,0x71,0x1E,0x64,0x4D,0xE6,0x90,
0x71,0xE3,0x1E,0x40,0xED,0x7D,0xF3,0x84,0x0E,0xED,0xC8,0x78,0x76,0xAE,0xC0,0x71,
0x27,0x72,0xBB,0x05,0xEA,0x02,0x64,0xFB,0xF3,0x48,0x6B,0xB5,0x42,0x93,0x3F,0xED,
0x9F,0x13,0x53,0xD2,0xF7,0xFE,0x2A,0xEC,0x1D,0x47,0x25,0xDB,0x3C,0x91,0x86,0xC6,
0x8E,0xF0,0x11,0xFD,0x23,0x74,0x36,0xF7,0xA4,0xF5,0x9E,0x7A,0x7E,0x53,0x50,0x44,
0xD4,0x47,0xCA,0xD3,0xEB,0x38,0x6D,0xE6,0xD9,0x71,0x94,0x7F,0x4A,0xC6,0x69,0x4B,
0x11,0xF4,0x52,0xEA,0x22,0xFE,0x8A,0xB0,0x36,0x67,0x8B,0x59,0xE8,0xE6,0x80,0x2A,
0xEB,0x65,0x04,0x13,0xEE,0xEC,0xDC,0x9E,0x5F,0xB1,0xEC,0x05,0x6A,0x59,0xE6,0x9F,
0x5E,0x59,0x6B,0x89,0xBF,0xF7,0x1A,0xCA,0x44,0xF9,0x5B,0x6A,0x71,0x85,0x03,0xE4,
0x29,0x62,0xE0,0x70,0x6F,0x41,0xC4,0xCF,0xB2,0xB1,0xCC,0xE3,0x7E,0xA6,0x07,0xA8,
0x87,0xE7,0x7F,0x84,0x93,0xDB,0x52,0x4B,0x6C,0xEC,0x7E,0xDD,0xD4,0x24,0x48,0x10,
0x69,0x9F,0x04,0x60,0x74,0xE6,0x48,0x18,0xF3,0xE4,0x2C,0xB9,0x4F,0x2E,0x50,0x7A,
0xDF,0xD4,0x54,0x69,0x2B,0x8B,0xA7,0xF3,0xCE,0xFF,0x1F,0xF3,0x3E,0x26,0x01,0x39,
0x17,0x95,0x84,0x89,0xB0,0xF0,0x4C,0x4B,0x82,0x91,0x9F,0xC4,0x4B,0xAC,0x9D,0xA5,
0x74,0xAF,0x17,0x25,0xC9,0xCA,0x32,0xD3,0xBC,0x89,0x8A,0x84,0x89,0xCC,0x0D,0xAE,
0x7C,0xA2,0xDB,0x9C,0x6A,0x78,0x91,0xEE,0xEA,0x76,0x5D,0x4E,0x87,0x60,0xF5,0x69,
0x15,0x67,0xD4,0x02,0xCF,0xAF,0x48,0x36,0x07,0xEA,0xBF,0x6F,0x66,0x2D,0x06,0x8F,
0xC4,0x9A,0xFE,0xF9,0xF6,0x90,0x87,0x75,0xB8,0xF7,0xAD,0x0F,0x76,0x10,0x5A,0x3D,
0x59,0xB0,0x2E,0xB3,0xC7,0x35,0x2C,0xCC,0x70,0x56,0x2B,0xCB,0xE3,0x37,0x96,0xC5,
0x2F,0x46,0x1B,0x8A,0x22,0x46,0xC7,0x88,0xA7,0x26,0x32,0x98,0x61,0xDF,0x86,0x22,
0x8A,0xF4,0x1C,0x2F,0x87,0xA1,0x09,0xAA,0xCC,0xA9,0xAE,0xD3,0xBD,0x00,0x45,0x1C,
0x9A,0x54,0x87,0x86,0x52,0x87,0xEF,0xFF,0x1E,0x8F,0xA1,0x8F,0xC1,0x89,0x5C,0x35,
0x1B,0xDA,0x2D,0x3A,0x2C,0x16,0xB2,0xC2,0xF1,0x56,0xE2,0x78,0xC1,0x6B,0x63,0x97,
0xC5,0x56,0x8F,0xC9,0x32,0x7F,0x2C,0xAA,0xAF,0xA6,0xA8,0xAC,0x20,0x91,0x22,0x88,
0xDE,0xE4,0x60,0x8B,0xF9,0x4B,0x42,0x25,0x1A,0xE3,0x7F,0x9C,0x2C,0x19,0x89,0x3A,
0x7E,0x05,0xD4,0x36,0xCC,0x69,0x58,0xC2,0xC1,0x32,0x8B,0x2F,0x90,0x85,0xEB,0x7A,
0x39,0x50,0xA5,0xA1,0x27,0x92,0xC5,0x66,0xB0,0x20,0x4F,0x58,0x7E,0x55,0x83,0x43,
0x2B,0x45,0xE2,0x9C,0xE4,0xD8,0x12,0x90,0x2C,0x16,0x83,0x56,0x16,0x79,0x03,0xB3,
0xAD,0x2D,0x61,0x18,0x1A,0x13,0x1F,0x37,0xE2,0xE1,0x9C,0x73,0x7B,0x80,0xD5,0xFD,
0x2D,0x51,0x87,0xFC,0x7B,0xAA,0xD7,0x1F,0x2C,0x7A,0x8E,0xAF,0xF4,0x8D,0xBB,0xCD,
0x95,0x11,0x7C,0x72,0x0B,0xEE,0x6F,0xE2,0xB9,0xAF,0xDE,0x37,0x83,0xDE,0x8C,0x8D,
0x62,0x05,0x67,0xB7,0x96,0xC6,0x8D,0x56,0xB6,0x0D,0xD7,0x62,0xBA,0xD6,0x46,0x36,
0xBD,0x8E,0xC8,0xE6,0xEA,0x2A,0x6C,0x10,0x14,0xFF,0x6B,0x5B,0xFA,0x82,0x3C,0x46,
0xB1,0x30,0x43,0x46,0x51,0x8A,0x7D,0x9B,0x92,0x3E,0x83,0x79,0x5B,0x55,0x5D,0xB2,
0x6C,0x5E,0xCE,0x90,0x62,0x8E,0x53,0x98,0xC9,0x0D,0x6D,0xE5,0x2D,0x57,0xCD,0xC5,
0x81,0x57,0xBA,0xE1,0xE8,0xB8,0x8F,0x72,0xE5,0x4F,0x13,0xDC,0xEA,0x9D,0x71,0x15,
0x10,0xB2,0x11,0x88,0xD5,0x09,0xD4,0x7F,0x5B,0x65,0x7F,0x2C,0x3B,0x38,0x4C,0x11,
0x68,0x50,0x8D,0xFB,0x9E,0xB0,0x59,0xBF,0x94,0x80,0x89,0x4A,0xC5,0x1A,0x18,0x12,
0x89,0x53,0xD1,0x4A,0x10,0x29,0xE8,0x8C,0x1C,0xEC,0xB6,0xEA,0x46,0xC7,0x17,0x8B,
0x25,0x15,0x31,0xA8,0xA2,0x6B,0x43,0xB1,0x9D,0xE2,0xDB,0x0B,0x87,0x9B,0xB0,0x11,
0x04,0x0E,0x71,0xD2,0x29,0x77,0x89,0x82,0x0A,0x66,0x41,0x7F,0x1D,0x0B,0x48,0xFF,
0x72,0xBB,0x24,0xFD,0xC2,0x48,0xA1,0x9B,0xFE,0x7B,0x7F,0xCE,0x88,0xDB,0x86,0xD9,
0x85,0x3B,0x1C,0xB0,0xDC,0xA8,0x33,0x07,0xBF,0x51,0x2E,0xE3,0x0E,0x9A,0x00,0x97,
0x1E,0x06,0xC0,0x97,0x43,0x9D,0xD8,0xB6,0x45,0xC4,0x86,0x67,0x5F,0x00,0xF8,0x88,
0x9A,0xA4,0x52,0x9E,0xC7,0xAA,0x8A,0x83,0x75,0xEC,0xC5,0x18,0xAE,0xCE,0xC3,0x2F,
0x1A,0x2B,0xF9,0x18,0xFF,0xAE,0x1A,0xF5,0x53,0x0B,0xB5,0x33,0x51,0xA7,0xFD,0xE8,
0xA8,0xE1,0xA2,0x64,0xB6,0x22,0x17,0x43,0x80,0xCC,0x0A,0xD8,0xAE,0x3B,0xBA,0x40,
0xD7,0xD9,0x92,0x4A,0x89,0xDF,0x04,0x10,0xEE,0x9B,0x18,0x2B,0x6A,0x77,0x69,0x8A,
0x68,0xF4,0xF9,0xB9,0xA2,0x21,0x15,0x6E,0xE6,0x1E,0x3B,0x03,0x62,0x30,0x9B,0x60,
0x41,0x7E,0x25,0x9B,0x9E,0x8F,0xC5,0x52,0x10,0x08,0xF8,0xC2,0x69,0xA1,0x21,0x11,
0x88,0x37,0x5E,0x79,0x35,0x66,0xFF,0x10,0x42,0x18,0x6E,0xED,0x97,0xB6,0x6B,0x1C,
0x4E,0x36,0xE5,0x6D,0x7D,0xB4,0xE4,0xBF,0x20,0xB9,0xE0,0x05,0x3A,0x69,0xD5,0xB8,
0xE3,0xD5,0xDC,0xE0,0xB9,0xAC,0x53,0x3E,0x07,0xA4,0x57,0xAD,0x77,0xFF,0x48,0x18,
0x76,0x2A,0xAC,0x49,0x2A,0x8E,0x47,0x75,0x6D,0x9F,0x67,0x63,0x30,0x35,0x8C,0x39,
0x05,0x39,0xD5,0x6F,0x64,0x3A,0x5B,0xAD,0xCA,0x0B,0xBB,0x82,0x52,0x99,0x45,0xB1,
0x93,0x36,0x36,0x99,0xAF,0x13,0x20,0x44,0x36,0xD8,0x02,0x44,0x09,0x39,0x92,0x85,
0xFF,0x4A,0x4A,0x97,0x87,0xA6,0x63,0xD7,0xC7,0xB5,0xB5,0x24,0xED,0x0F,0xB4,0x6F,
0x0C,0x58,0x52,0x14,0xD9,0xA6,0x7B,0xD3,0x79,0xBC,0x38,0x58,0xA1,0xBD,0x3B,0x84,
0x06,0xD8,0x1A,0x06,0xFD,0x6B,0xA8,0xEA,0x4B,0x69,0x28,0x04,0x37,0xAD,0x82,0x99,
0xFB,0x0E,0x1B,0x85,0xBD,0xA8,0x5D,0x73,0xCD,0xDC,0x58,0x75,0x0A,0xBE,0x63,0x6C,
0x48,0xE7,0x4C,0xE4,0x30,0x2B,0x04,0x60,0xB9,0x15,0xD8,0xDA,0x86,0x81,0x75,0x8F,
0x96,0xD4,0x8D,0x1C,0x5D,0x70,0x85,0x7C,0x1C,0x67,0x7B,0xD5,0x08,0x67,0xA6,0xCE,
0x4B,0x0A,0x66,0x70,0xB7,0xE5,0x63,0xD4,0x5B,0x8A,0x82,0xEA,0x10,0x67,0xCA,0xE2,
0xF4,0xEF,0x17,0x85,0x2F,0x2A,0x5F,0x8A,0x97,0x82,0xF8,0x6A,0xD6,0x34,0x10,0xEA,
0xEB,0xC9,0x5C,0x3C,0xE1,0x49,0xF8,0x46,0xEB,0xDE,0xBD,0xF6,0xA9,0x92,0xF1,0xAA,
0xA6,0xA0,0x18,0xB0,0x3A,0xD3,0x0F,0x1F,0xF3,0x6F,0xFF,0x31,0x45,0x43,0x44,0xD3,
0x50,0x9A,0xF7,0x88,0x09,0x96,0xC1,0xCE,0x76,0xCC,0xF2,0x2C,0x2C,0xBA,0xAD,0x82,
0x77,0x8F,0x18,0x84,0xC0,0xD2,0x07,0x9C,0x36,0x90,0x83,0x4E,0x0B,0xA5,0x4F,0x43,
0x3E,0x04,0xAB,0x78,0x4F,0xD6,0xFB,0x09,0x01,0x24,0x90,0xDA,0x6F,0x3C,0x3A,0x61,
0x0D,0x7F,0x69,0x4A,0xEB,0x2B,0x30,0x02,0xB4,0xDB,0xE0,0x84,0xA9,0xEC,0xD7,0x35,
0xBF,0x37,0x7D,0x85,0x58,0xCE,0xA9,0x4E,0xE4,0x80,0xC7,0xA8,0xD3,0x30,0x67,0x48,
0xEB,0x29,0xAF,0x2F,0x74,0x6A,0xB4,0xA7,0x3F,0x0F,0x3F,0x92,0xAF,0xF3,0xCA,0xAC,
0xAF,0x4B,0xD9,0x94,0xC0,0x43,0xCA,0x81,0x0D,0x2F,0x48,0xA1,0xB0,0x27,0xD5,0xD2,
0xEF,0x4B,0x05,0x85,0xA3,0xDE,0x4D,0x93,0x30,0x3C,0xF0,0xBB,0x4A,0x8F,0x30,0x27,
0x4C,0xEB,0xE3,0x3E,0x64,0xED,0x9A,0x2F,0x3B,0xF1,0x82,0xF0,0xBA,0xF4,0xCF,0x7F,
0x40,0xCB,0xB0,0xE1,0x7F,0xBC,0xAA,0x57,0xD3,0xC9,0x74,0xF2,0xFA,0x43,0x0D,0x22,
0xD0,0xF4,0x77,0x4E,0x93,0xD7,0x85,0x70,0x1F,0x99,0xBF,0xB6,0xDE,0x35,0xF1,0x30,
0xA7,0x5E,0x71,0xF0,0x6B,0x01,0x2D,0x7B,0x64,0xF0,0x33,0x53,0x0A,0x39,0x88,0xF3,
0x6B,0x3A,0xA6,0x6B,0x35,0xD2,0x2F,0x43,0xCD,0x02,0xFD,0xB5,0xE9,0xBC,0x5B,0xAA,
0xD8,0xA4,0x19,0x7E,0x0E,0x5D,0x94,0x81,0x9E,0x6F,0x77,0xAD,0xD6,0x0E,0x74,0x93,
0x96,0xE7,0xC4,0x18,0x5F,0xAD,0xF5,0x19,
];
}
}

View File

@@ -1,11 +0,0 @@
namespace SabreTools.Models.Nitro
{
public enum Unitcode : byte
{
NDS = 0x00,
NDSPlusDSi = 0x02,
DSi = 0x03,
}
}

View File

@@ -1,298 +0,0 @@
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>
/// <remarks>5 entries</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public uint[]? GlobalMBK15Settings;
/// <summary>
/// Local MBK6..MBK8 Settings for ARM9
/// </summary>
/// <remarks>3 entries</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public uint[]? LocalMBK68SettingsARM9;
/// <summary>
/// Local MBK6..MBK8 Settings for ARM7
/// </summary>
/// <remarks>3 entries</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public uint[]? LocalMBK68SettingsARM7;
/// <summary>
/// Global MBK9 Setting
/// </summary>
public uint GlobalMBK9Setting;
/// <summary>
/// Region Flags
/// </summary>
public uint RegionFlags;
/// <summary>
/// Access control
/// </summary>
public uint AccessControl;
/// <summary>
/// ARM7 SCFG EXT mask (controls which devices to enable)
/// </summary>
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;
/// <summary>
/// ARM9i rom offset
/// </summary>
public uint ARM9iRomOffset;
/// <summary>
/// Reserved
/// </summary>
public uint Reserved3;
/// <summary>
/// ARM9i load address
/// </summary>
public uint ARM9iLoadAddress;
/// <summary>
/// ARM9i size;
/// </summary>
public uint ARM9iSize;
/// <summary>
/// ARM7i rom offset
/// </summary>
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;
/// <summary>
/// ARM7i load address
/// </summary>
public uint ARM7iLoadAddress;
/// <summary>
/// ARM7i size;
/// </summary>
public uint ARM7iSize;
/// <summary>
/// Digest NTR region offset
/// </summary>
public uint DigestNTRRegionOffset;
/// <summary>
/// Digest NTR region length
/// </summary>
public uint DigestNTRRegionLength;
// <summary>
/// Digest TWL region offset
/// </summary>
public uint DigestTWLRegionOffset;
/// <summary>
/// Digest TWL region length
/// </summary>
public uint DigestTWLRegionLength;
// <summary>
/// Digest Sector Hashtable region offset
/// </summary>
public uint DigestSectorHashtableRegionOffset;
/// <summary>
/// Digest Sector Hashtable region length
/// </summary>
public uint DigestSectorHashtableRegionLength;
// <summary>
/// Digest Block Hashtable region offset
/// </summary>
public uint DigestBlockHashtableRegionOffset;
/// <summary>
/// Digest Block Hashtable region length
/// </summary>
public uint DigestBlockHashtableRegionLength;
/// <summary>
/// Digest Sector size
/// </summary>
public uint DigestSectorSize;
/// <summary>
/// Digeset Block Sectorount
/// </summary>
public uint DigestBlockSectorCount;
/// <summary>
/// Icon Banner Size (usually 0x23C0)
/// </summary>
public uint IconBannerSize;
/// <summary>
/// Unknown (used by DSi)
/// </summary>
public uint Unknown1;
/// <summary>
/// NTR+TWL region ROM size (total size including DSi area)
/// </summary>
public uint NTRTWLRegionRomSize;
/// <summary>
/// Unknown (used by DSi)
/// </summary>
/// <remarks>12 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public byte[]? Unknown2;
/// <summary>
/// Modcrypt area 1 offset
/// </summary>
public uint ModcryptArea1Offset;
/// <summary>
/// Modcrypt area 1 size
/// </summary>
public uint ModcryptArea1Size;
/// <summary>
/// Modcrypt area 2 offset
/// </summary>
public uint ModcryptArea2Offset;
/// <summary>
/// Modcrypt area 2 size
/// </summary>
public uint ModcryptArea2Size;
/// <summary>
/// Title ID
/// </summary>
/// <remarks>8 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[]? TitleID;
/// <summary>
/// DSiWare: "public.sav" size
/// </summary>
public uint DSiWarePublicSavSize;
/// <summary>
/// DSiWare: "private.sav" size
/// </summary>
public uint DSiWarePrivateSavSize;
/// <summary>
/// Reserved (zero)
/// </summary>
/// <remarks>176 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 176)]
public byte[]? ReservedZero;
/// <summary>
/// Unknown (used by DSi)
/// </summary>
/// <remarks>16 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[]? Unknown3;
/// <summary>
/// ARM9 (with encrypted secure area) SHA1 HMAC hash
/// </summary>
/// <remarks>20 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[]? ARM9WithSecureAreaSHA1HMACHash;
/// <summary>
/// ARM7 SHA1 HMAC hash
/// </summary>
/// <remarks>20 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[]? ARM7SHA1HMACHash;
/// <summary>
/// Digest master SHA1 HMAC hash
/// </summary>
/// <remarks>20 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[]? DigestMasterSHA1HMACHash;
/// <summary>
/// Banner SHA1 HMAC hash
/// </summary>
/// <remarks>20 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[]? BannerSHA1HMACHash;
/// <summary>
/// ARM9i (decrypted) SHA1 HMAC hash
/// </summary>
/// <remarks>20 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[]? ARM9iDecryptedSHA1HMACHash;
/// <summary>
/// ARM7i (decrypted) SHA1 HMAC hash
/// </summary>
/// <remarks>20 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[]? ARM7iDecryptedSHA1HMACHash;
/// <summary>
/// Reserved
/// </summary>
/// <remarks>40 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
public byte[]? Reserved5;
/// <summary>
/// ARM9 (without secure area) SHA1 HMAC hash
/// </summary>
/// <remarks>20 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[]? ARM9NoSecureAreaSHA1HMACHash;
/// <summary>
/// Reserved
/// </summary>
/// <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>
/// <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>
/// <remarks>0x80 bytes</remarks>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x80)]
public byte[]? RSASignature;
}
}

View File

@@ -1,23 +0,0 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.Nitro
{
/// <summary>
/// The structure of the file allocation table is very simple,
/// 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;
/// <summary>
/// End offset of file (after this is padding)
/// </summary>
public uint EndOffset;
}
}

View File

@@ -1,36 +0,0 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.Nitro
{
/// <summary>
/// Each folder in the file system has a 8 byte long entry.
/// The first one is for the root folder, and acts as an entry
/// 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;
/// <summary>
/// Index of first file within folder in File Allocation Table
/// </summary>
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;
/// <summary>
/// Unknown, always 0xF0 except for root folder
/// </summary>
public byte Unknown;
}
}

View File

@@ -1,29 +0,0 @@
namespace SabreTools.Models.Nitro
{
/// <summary>
/// The name list holds the names of the folders, and their contents
/// in order, with references back to the Folder Allocation Table.
/// </summary>
/// <see href="https://github.com/Deijin27/RanseiLink/wiki/NDS-File-System"/>
public sealed class NameListEntry
{
/// <summary>
/// The least significant 7 bits store the length of the name,
/// and the most significant bit indicates whether it is a
/// folder (1 = folder, 0 = file).
/// </summary>
public bool Folder { get; set; }
/// <summary>
/// The variable length name (UTF-8)
/// </summary>
public string? Name { get; set; }
/// <summary>
/// Only there if it is a folder. Refers to the the index of it
/// within the Folder allocation table, allowing its contents to
/// be found.
/// </summary>
public ushort Index { get; set; }
}
}

View File

@@ -1,25 +0,0 @@
namespace SabreTools.Models.Nitro
{
/// <summary>
/// The name table stores the names of the files and the structure
/// of the file system. From the information stored, the index of the
/// file's entry in the File Allocation Table can be found.
///
/// It is split into two parts:
/// - Folder Allocation Table
/// - Name List
/// </summary>
/// <see href="https://github.com/Deijin27/RanseiLink/wiki/NDS-File-System"/>
public sealed class NameTable
{
/// <summary>
/// Folder allocation table
/// </summary>
public FolderAllocationTableEntry[]? FolderAllocationTable { get; set; }
/// <summary>
/// Name list
/// </summary>
public NameListEntry[]? NameList { get; set; }
}
}

View File

@@ -1,23 +0,0 @@
namespace SabreTools.Models.OLE
{
/// <summary>
/// The ArrayDimension packet represents the size and index offset of a dimension of an array
/// property type.
/// </summary>
/// <see href="https://winprotocoldoc.z19.web.core.windows.net/MS-OLEPS/%5bMS-OLEPS%5d.pdf"/>
public class ArrayDimension
{
/// <summary>
/// An unsigned integer representing the size of the dimension.
/// </summary>
public uint Size { get; set; }
/// <summary>
/// A signed integer representing the index offset of the dimension. For
/// example, an array dimension that is to be accessed with a 0-based index would have the value
/// zero, whereas an array dimension that is to be accessed with a 1-based index would have the
/// value 0x00000001.
/// </summary>
public int Value { get; set; }
}
}

View File

@@ -1,29 +0,0 @@
namespace SabreTools.Models.OLE
{
/// <summary>
/// The ArrayHeader packet represents the type and dimensions of an array property type.
/// </summary>
/// <see href="https://winprotocoldoc.z19.web.core.windows.net/MS-OLEPS/%5bMS-OLEPS%5d.pdf"/>
public class ArrayHeader
{
/// <summary>
/// MUST be set to the value obtained by clearing the VT_ARRAY (0x2000) bit of
/// this array property's PropertyType value.
/// </summary>
public PropertyType Type { get; set; }
/// <summary>
/// An unsigned integer representing the number of dimensions in the array
/// property. MUST be at least 1 and at most 31.
/// </summary>
public uint NumDimensions { get; set; }
/// <summary>
/// MUST be a sequence of ArrayDimension packets
///
/// The number of scalar values in an array property can be calculated from the ArrayHeader packet
/// as the product of the Size fields of each of the ArrayDimension packets.
/// </summary>
public ArrayDimension[]? Dimensions { get; set; }
}
}

View File

@@ -1,19 +0,0 @@
namespace SabreTools.Models.OLE
{
/// <summary>
/// The BLOB packet represents binary data
/// </summary>
/// <see href="https://winprotocoldoc.z19.web.core.windows.net/MS-OLEPS/%5bMS-OLEPS%5d.pdf"/>
public class BLOB
{
/// <summary>
/// The size in bytes of the <see cref="Bytes"> field, not including padding (if any)
/// </summary>
public uint Size { get; set; }
/// <summary>
/// MUST be an array of bytes, followed by zero padding to a multiple of 4 bytes.
/// </summary>
public byte[]? Bytes { get; set; }
}
}

View File

@@ -1,15 +0,0 @@
namespace SabreTools.Models.OLE
{
/// <summary>
/// The CURRENCY (Packet Version) packet represents a CURRENCY as specified in [MS-OAUT]
/// section 2.2.24.
/// </summary>
/// <see href="https://winprotocoldoc.z19.web.core.windows.net/MS-OLEPS/%5bMS-OLEPS%5d.pdf"/>
public class CURRENCY
{
/// <summary>
/// The value of the int64 field specified in [MS-OAUT] section 2.2.24.
/// </summary>
public ulong Value { get; set; }
}
}

View File

@@ -1,26 +0,0 @@
namespace SabreTools.Models.OLE
{
/// <summary>
/// The ClipboardData packet represents clipboard data
/// </summary>
/// <see href="https://winprotocoldoc.z19.web.core.windows.net/MS-OLEPS/%5bMS-OLEPS%5d.pdf"/>
public class ClipboardData
{
/// <summary>
/// The total size in bytes of the <see cref="Format"> and <see cref="Data"> fields,
/// not including padding (if any).
/// </summary>
public uint Size { get; set; }
/// <summary>
/// An application-specific identifier for the format of the data in the
/// <see cref="Data"> field.
/// </summary>
public uint Format { get; set; }
/// <summary>
/// MUST be an array of bytes, followed by zero padding to a multiple of 4 bytes
/// </summary>
public byte[]? Data { get; set; }
}
}

View File

@@ -1,33 +0,0 @@
namespace SabreTools.Models.OLE
{
/// <summary>
/// The CodePageString packet represents a string whose encoding depends on the
/// value of the property set's CodePage property.
/// </summary>
/// <see href="https://winprotocoldoc.z19.web.core.windows.net/MS-OLEPS/%5bMS-OLEPS%5d.pdf"/>
public class CodePageString
{
/// <summary>
/// The size in bytes of the <see cref="Characters"/> field, including the null terminator,
/// but not including padding (if any). If the property set's CodePage property
/// has the value CP_WINUNICODE (0x04B0), then the value MUST be a multiple of 2
/// </summary>
public uint Size { get; set; }
/// <summary>
/// If <see cref="Size"/> is zero, this field MUST be zero bytes in length. If <see cref="Size"/>
/// is nonzero and the CodePage property set's CodePage property has the value CP_WINUNICODE (0x04B0),
/// then the value MUST be a null-terminated array of 16-bit Unicode characters, followed by zero
/// padding to a multiple of 4 bytes. If <see cref="Size"/> is nonzero and the property set's CodePage
/// property has any other value, it MUST be a null-terminated array of 8-bit characters from the code
/// page identified by the CodePage property, followed by zero padding to a multiple of 4 bytes. The
/// string represented by this field MAY contain embedded or additional trailing null characters and
/// an OLEPS implementation MUST be able to handle such strings. However, the manner in which
/// strings with embedded or additional trailing null characters are presented by the implementation
/// to an application is implementation-specific. For maximum interoperability, an OLEPS
/// implementation SHOULD NOT write strings with embedded or trailing null characters unless
/// specifically requested to do so by an application.
/// </summary>
public string? Characters { get; set; }
}
}

View File

@@ -1,90 +0,0 @@
namespace SabreTools.Models.OLE
{
public static class Constants
{
#region Format IDs
public const string SummaryInformationFMTIDString = "F29F85E0-4FF9-1068-AB91-08002B27B3D9";
public static readonly GUID SummaryInformationFMTIDGUID = new()
{
Data1 = 0xF29F85E0,
Data2 = 0x4FF9,
Data3 = 0x1068,
Data4 = [0xAB, 0x91, 0x08, 0x00, 0x2B, 0x27, 0xB3, 0xD9],
};
public const string DocSummaryInformationFMTIDString = "D5CDD502-2E9C-101B-9397-08002B2CF9AE";
public static readonly GUID DocSummaryInformationFMTIDGUID = new()
{
Data1 = 0xD5CDD502,
Data2 = 0x2E9C,
Data3 = 0x101B,
Data4 = [0x93, 0x97, 0x08, 0x00, 0x2B, 0x2C, 0xF9, 0xAE],
};
public const string UserDefinedPropertiesFMTIDString = "D5CDD502-2E9C-101B-9397-08002B2CF9AE";
public static readonly GUID UserDefinedPropertiesFMTIDGUID = new()
{
Data1 = 0xD5CDD502,
Data2 = 0x2E9C,
Data3 = 0x101B,
Data4 = [0x93, 0x97, 0x08, 0x00, 0x2B, 0x2C, 0xF9, 0xAE],
};
public const string GlobalInfoFMTIDString = "56616F00-C154-11CE-8553-00AA00A1F95B";
public static readonly GUID GlobalInfoFMTIDGUID = new()
{
Data1 = 0x56616F00,
Data2 = 0xC154,
Data3 = 0x11CE,
Data4 = [0x85, 0x53, 0x00, 0xAA, 0x00, 0xA1, 0xF9, 0x5B],
};
public const string ImageContentsFMTIDString = "556616400-C154-11CE-8553-00AA00A1F95B";
public static readonly GUID ImageContentsFMTIDGUID = new()
{
Data1 = 0x56616F00,
Data2 = 0xC154,
Data3 = 0x11CE,
Data4 = [0x85, 0x53, 0x00, 0xAA, 0x00, 0xA1, 0xF9, 0x5B],
};
public const string ImageInfoFMTIDString = "556616400-C154-11CE-8553-00AA00A1F95B";
public static readonly GUID ImageInfoFMTIDGUID = new()
{
Data1 = 0x56616F00,
Data2 = 0xC154,
Data3 = 0x11CE,
Data4 = [0x85, 0x53, 0x00, 0xAA, 0x00, 0xA1, 0xF9, 0x5B],
};
public const string PropertyBagFMTIDString = "20001801-5DE6-11D1-8E38-00C04FB9386D";
public static readonly GUID PropertyBagFMTIDGUID = new()
{
Data1 = 0x20001801,
Data2 = 0x5DE6,
Data3 = 0x11D1,
Data4 = [0x8E, 0x38, 0x00, 0xC0, 0x4F, 0xB9, 0x38, 0x6D],
};
#endregion
#region Stream or Storage Names
public static readonly string SummaryInformationName = (byte)0x05 + "SummaryInformation";
public static readonly string DocSummaryInformationName = (byte)0x05 + "DocumentSummaryInformation";
public static readonly string UserDefinedPropertiesName = (byte)0x05 + "DocumentSummaryInformation";
public static readonly string GlobalInfoName = (byte)0x05 + "GlobalInfo";
public static readonly string ImageContentsName = (byte)0x05 + "ImageContents";
public static readonly string ImageInfoName = (byte)0x05 + "ImageInfo";
public const string ControlStreamName = "{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}";
#endregion
}
}

View File

@@ -1,35 +0,0 @@
namespace SabreTools.Models.OLE
{
/// <summary>
/// A file that has one or more property sets associated with it through the alternate
/// stream binding MUST have a control stream, which is an alternate stream with the name
/// "{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}". This stream MUST contain the following packet.
/// </summary>
/// <see href="https://winprotocoldoc.z19.web.core.windows.net/MS-OLEPS/%5bMS-OLEPS%5d.pdf"/>
public class ControlStream
{
/// <summary>
/// MUST be set to zero, and nonzero values MUST be rejected.
/// </summary>
public ushort Reserved1 { get; set; }
/// <summary>
/// MUST be set to zero, and MUST be ignored.
/// </summary>
public ushort Reserved2 { get; set; }
/// <summary>
/// An application-provided value that MUST NOT be interpreted by the
/// OLEPS implementation. If the application did not provide a value,
/// it SHOULD be set to zero.
/// </summary>
public uint ApplicationState { get; set; }
/// <summary>
/// An application-provided value that MUST NOT be interpreted by the
/// OLEPS implementation. If the application did not provide a value,
/// it SHOULD be absent.
/// </summary>
public GUID? CLSID { get; set; }
}
}

View File

@@ -1,16 +0,0 @@
namespace SabreTools.Models.OLE
{
/// <summary>
/// The DATE (Packet Version) packet represents a DATE as specified in [MS-OAUT]
/// section 2.2.25
/// </summary>
/// <see href="https://winprotocoldoc.z19.web.core.windows.net/MS-OLEPS/%5bMS-OLEPS%5d.pdf"/>
public class DATE
{
/// <summary>
/// The value of the DATE is an 8-byte IEEE floating-point number, as specified in
/// [MS-OAUT] section 2.2.25.
/// </summary>
public ulong Value { get; set; }
}
}

View File

@@ -1,35 +0,0 @@
namespace SabreTools.Models.OLE
{
/// <summary>
/// The DECIMAL (Packet Version) packet represents a DECIMAL as specified in [MS-OAUT] section
/// 2.2.26
/// </summary>
/// <see href="https://winprotocoldoc.z19.web.core.windows.net/MS-OLEPS/%5bMS-OLEPS%5d.pdf"/>
public class DECIMAL
{
/// <summary>
/// MUST be set to zero and MUST be ignored
/// </summary>
public ushort Reserved { get; set; }
/// <summary>
/// The value of the scale field specified in [MS-OAUT] section 2.2.26
/// </summary>
public byte Scale { get; set; }
/// <summary>
/// The value of the sign field specified in [MS-OAUT] section 2.2.26
/// </summary>
public byte Sign { get; set; }
/// <summary>
/// The value of the Hi32 field specified in [MS-OAUT] section 2.2.26
/// </summary>
public uint Hi32 { get; set; }
/// <summary>
/// The value of the Lo64 field specified in [MS-OAUT] section 2.2.26
/// </summary>
public ulong Lo64 { get; set; }
}
}

View File

@@ -1,24 +0,0 @@
namespace SabreTools.Models.OLE
{
/// <summary>
/// The Dictionary packet represents all mappings between property identifiers and
/// property names in a property set
/// </summary>
/// <see href="https://winprotocoldoc.z19.web.core.windows.net/MS-OLEPS/%5bMS-OLEPS%5d.pdf"/>
public class Dictionary
{
/// <summary>
/// n unsigned integer representing the number of entries in the Dictionary
/// </summary>
public uint NumEntries { get; set; }
/// <summary>
/// All Entry fields MUST be a sequence of DictionaryEntry packets. Entries are
/// not required to appear in any particular order.
/// </summary>
public DictionaryEntry[]? Entries { get; set; }
// Padding (variable): Padding, if necessary, to a total length that is a multiple of 4 bytes.
// Padding would be after each dictionary entry
}
}

View File

@@ -1,35 +0,0 @@
namespace SabreTools.Models.OLE
{
/// <summary>
/// The DictionaryEntry packet represents a mapping between a property identifier and a
/// property name
/// </summary>
/// <see href="https://winprotocoldoc.z19.web.core.windows.net/MS-OLEPS/%5bMS-OLEPS%5d.pdf"/>
public class DictionaryEntry
{
/// <summary>
/// An unsigned integer representing a property identifier. MUST be a valid
/// PropertyIdentifier value in the range 0x00000002 to 0x7FFFFFFF, inclusive
/// (this specifically excludes the property identifiers for any of the special
/// properties specified in section 2.18).
/// </summary>
public PropertyIdentifier PropertyIdentifier { get; set; }
/// <summary>
/// If the property set's CodePage property has the value CP_WINUNICODE (0x04B0),
/// MUST be the length of the Name field in 16-bit Unicode characters, including
/// the null terminator but not including padding (if any). Otherwise, MUST be the
/// length of the Name field in 8-bit characters, including the null terminator.
/// </summary>
public uint Length { get; set; }
/// <summary>
/// If the property set's CodePage property has the value CP_WINUNICODE (0x04B0),
/// MUST be a null-terminated array of 16-bit Unicode characters, followed by zero
/// padding to a multiple of 4 bytes. Otherwise, MUST be a null-terminated array of
/// 8-bit characters from the code page identified by the CodePage property and MUST
/// NOT be padded.
/// </summary>
public string? Name { get; set; }
}
}

View File

@@ -1,503 +0,0 @@
namespace SabreTools.Models.OLE
{
/// <summary>
/// The PropertyIdentifier data type represents the property identifier of a property in a property set
/// </summary>
/// <remarks>
/// The SummaryInformation property set format, identified by FMTID_SummaryInformation
/// ({F29F85E0-4FF9-1068-AB91-08002B27B3D9}), represents generic properties of a document. The properties
/// specific to the SummaryInformation property set are specified in the following table. Except where
/// otherwise stated, a SummaryInformation property set SHOULD have all of these properties, and SHOULD
/// NOT have any other properties, except for the special properties specified in section 2.18.
/// </remarks>
/// <see href="https://winprotocoldoc.z19.web.core.windows.net/MS-OLEPS/%5bMS-OLEPS%5d.pdf"/>
public enum PropertyIdentifier : uint
{
/// <summary>
/// Property identifier for the Dictionary property
/// </summary>
DICTIONARY_PROPERTY_IDENTIFIER = 0x00000000,
/// <summary>
/// Property identifier for the CodePage property
/// </summary>
CODEPAGE_PROPERTY_IDENTIFIER = 0x00000001,
/// <summary>
/// Property identifier for the Locale property
/// </summary>
LOCALE_PROPERTY_IDENTIFIER = 0x80000000,
/// <summary>
/// Property identifier for the Behavior property
/// </summary>
BEHAVIOR_PROPERTY_IDENTIFIER = 0x80000003,
#region SummaryInformation
/// <summary>
/// The title of the document.
/// </summary>
/// <remarks>VT_LPSTR</remarks>
PIDSI_TITLE = 0x00000002,
/// <summary>
/// The subject of the document.
/// </summary>
/// <remarks>VT_LPSTR</remarks>
PIDSI_SUBJECT = 0x00000003,
/// <summary>
/// The author of the document.
/// </summary>
/// <remarks>VT_LPSTR</remarks>
PIDSI_AUTHOR = 0x00000004,
/// <summary>
/// Keywords related to the document.
/// </summary>
/// <remarks>VT_LPSTR</remarks>
PIDSI_KEYWORDS = 0x00000005,
/// <summary>
/// Comments related the document.
/// </summary>
/// <remarks>VT_LPSTR</remarks>
PIDSI_COMMENTS = 0x00000006,
/// <summary>
/// The application-specific template from which the document was created.
/// </summary>
/// <remarks>VT_LPSTR</remarks>
PIDSI_TEMPLATE = 0x00000007,
/// <summary>
/// The last author of the document.
/// </summary>
/// <remarks>VT_LPSTR</remarks>
PIDSI_LASTAUTHOR = 0x00000008,
/// <summary>
/// An application-specific revision number for this version of the document.
/// </summary>
/// <remarks>VT_LPSTR</remarks>
PIDSI_REVNUMBER = 0x00000009,
/// <summary>
/// A 64-bit unsigned integer indicating the total amount of time that
/// has been spent editing the document in 100-nanosecond
/// increments. MUST be encoded as a FILETIME by setting the
/// dwLowDataTime field to the low 32-bits and the dwHighDateTime
/// field to the high 32-bits.
/// </summary>
/// <remarks>VT_FILETIME</remarks>
PIDSI_EDITTIME = 0x0000000A,
/// <summary>
/// The most recent time that the document was printed.
/// </summary>
/// <remarks>VT_FILETIME</remarks>
PIDSI_LASTPRINTED = 0x0000000B,
/// <summary>
/// The time that the document was created.
/// </summary>
/// <remarks>VT_FILETIME</remarks>
PIDSI_CREATE_DTM = 0x0000000C,
/// <summary>
/// The most recent time that the document was saved.
/// </summary>
/// <remarks>VT_FILETIME</remarks>
PIDSI_LASTSAVE_DTM = 0x0000000D,
/// <summary>
/// The total number of pages in the document.
/// </summary>
/// <remarks>VT_I4</remarks>
PIDSI_PAGECOUNT = 0x0000000E,
/// <summary>
/// The total number of words in the document.
/// </summary>
/// <remarks>VT_I4</remarks>
PIDSI_WORDCOUNT = 0x0000000F,
/// <summary>
/// The total number of characters in the document.
/// </summary>
/// <remarks>VT_I4</remarks>
PIDSI_CHARCOUNT = 0x00000010,
/// <summary>
/// Application-specific clipboard data containing a thumbnail
/// representing the document's contents. MAY be absent.
/// </summary>
/// <remarks>VT_CF</remarks>
PIDSI_THUMBNAIL = 0x00000011,
/// <summary>
/// The name of the application that was used to create the document.
/// </summary>
/// <remarks>VT_LPSTR</remarks>
PIDSI_APPNAME = 0x00000012,
/// <summary>
/// A 32-bit signed integer representing a set of application-suggested
/// access control flags with the following values:
/// - 0x00000001: Password protected
/// - 0x00000002: Read-only recommended
/// - 0x00000004: Read-only enforced
/// - 0x00000008: Locked for annotations
/// </summary>
/// <remarks>VT_I4</remarks>
PIDSI_DOC_SECURITY = 0x00000013,
#endregion
}
/// <summary>
/// The PropertyType enumeration represents the type of a property in a property set. The set of types
/// supported depends on the version of the property set, which is indicated by the Version field of the
/// PropertySetStream packet. In addition, the property types not supported in simple property sets
/// are specified as such. PropertyType is an enumeration, which MUST be one of the following values
/// </summary>
/// <see href="https://winprotocoldoc.z19.web.core.windows.net/MS-OLEPS/%5bMS-OLEPS%5d.pdf"/>
public enum PropertyType : ushort
{
/// <summary>
/// Type is undefined, and the minimum property set version is 0
/// </summary>
VT_EMPTY = 0x0000,
/// <summary>
/// Type is null, and the minimum property set version is 0
/// </summary>
VT_NULL = 0x0001,
/// <summary>
/// Type is 16-bit signed integer, and the minimum property set version is 0
/// </summary>
VT_I2 = 0x0002,
/// <summary>
/// Type is 32-bit signed integer, and the minimum property set version is 0.
/// </summary>
VT_I4 = 0x0003,
/// <summary>
/// Type is 4-byte (single-precision) IEEE floating-point number, and the
/// minimum property set version is 0.
/// </summary>
VT_R4 = 0x0004,
/// <summary>
/// Type is 8-byte (double-precision) IEEE floating-point number, and the
/// minimum property set version is 0.
/// </summary>
VT_R8 = 0x0005,
/// <summary>
/// Type is CURRENCY, and the minimum property set version is 0.
/// </summary>
VT_CY = 0x0006,
/// <summary>
/// Type is DATE, and the minimum property set version is 0.
/// </summary>
VT_DATE = 0x0007,
/// <summary>
/// Type is CodePageString, and the minimum property set version is 0.
/// </summary>
VT_BSTR = 0x0008,
/// <summary>
/// Type is HRESULT, and the minimum property set version is 0.
/// </summary>
VT_ERROR = 0x000A,
/// <summary>
/// Type is VARIANT_BOOL, and the minimum property set version is 0.
/// </summary>
VT_BOOL = 0x000B,
/// <summary>
/// Type is DECIMAL, and the minimum property set version is 0.
/// </summary>
VT_DECIMAL = 0x000E,
/// <summary>
/// Type is 1-byte signed integer, and the minimum property set version
/// is 1.
/// </summary>
VT_I1 = 0x0010,
/// <summary>
/// Type is 1-byte unsigned integer, and the minimum property set version
/// is 0.
/// </summary>
VT_UI1 = 0x0011,
/// <summary>
/// Type is 2-byte unsigned integer, and the minimum property set version
/// is 0.
/// </summary>
VT_UI2 = 0x0012,
/// <summary>
/// Type is 4-byte unsigned integer, and the minimum property set version
/// is 0.
/// </summary>
VT_UI4 = 0x0013,
/// <summary>
/// Type is 8-byte signed integer, and the minimum property set version
/// is 0.
/// </summary>
VT_I8 = 0x0014,
/// <summary>
/// Type is 8-byte unsigned integer, and the minimum property set version
/// is 0.
/// </summary>
VT_UI8 = 0x0015,
/// <summary>
/// Type is 4-byte signed integer, and the minimum property set version
/// is 1.
/// </summary>
VT_INT = 0x0016,
/// <summary>
/// Type is 4-byte unsigned integer, and the minimum property set version
/// is 1.
/// </summary>
VT_UINT = 0x0017,
/// <summary>
/// Type is CodePageString, and the minimum property set version is 0.
/// </summary>
VT_LPSTR = 0x001E,
/// <summary>
/// Type is UnicodeString, and the minimum property set version is 0.
/// </summary>
VT_LPWSTR = 0x001F,
/// <summary>
/// Type is FILETIME, and the minimum property set version is 0.
/// </summary>
VT_FILETIME = 0x0040,
/// <summary>
/// Type is binary large object (BLOB), and the minimum property set
/// version is 0.
/// </summary>
VT_BLOB = 0x0041,
/// <summary>
/// Type is Stream, and the minimum property set version is 0. VT_STREAM
/// is not allowed in a simple property set.
/// </summary>
VT_STREAM = 0x0042,
/// <summary>
/// Type is Storage, and the minimum property set version is 0. VT_STORAGE
/// is not allowed in a simple property set.
/// </summary>
VT_STORAGE = 0x0043,
/// <summary>
/// Type is Stream representing an Object in an application-specific manner,
/// and the minimum property set version is 0. VT_STREAMED_Object is not
/// allowed in a simple property set.
/// </summary>
VT_STREAMED_Object = 0x0044,
/// <summary>
/// Type is Storage representing an Object in an application-specific manner,
/// and the minimum property set version is 0. VT_STORED_Object is not
/// allowed in a simple property set.
/// </summary>
VT_STORED_Object = 0x0045,
/// <summary>
/// Type is BLOB representing an object in an application-specific manner.
/// The minimum property set version is 0.
/// </summary>
VT_BLOB_Object = 0x0046,
/// <summary>
/// Type is PropertyIdentifier, and the minimum property set version is 0.
/// </summary>
VT_CF = 0x0047,
/// <summary>
/// Type is CLSID, and the minimum property set version is 0.
/// </summary>
VT_CLSID = 0x0048,
/// <summary>
/// Type is Stream with application-specific version GUID (VersionedStream).
/// The minimum property set version is 0. VT_VERSIONED_STREAM is not allowed
/// in a simple property set.
/// </summary>
VT_VERSIONED_STREAM = 0x0049,
/// <summary>
/// Type is Vector, and the minimum property set version is 0
/// </summary>
VT_VECTOR = 0x1000,
/// <summary>
/// Type is Vector of 1-byte unsigned integers, and the minimum property set version
/// is 0.
/// </summary>
VT_VECTOR_UI1 = 0x1011,
/// <summary>
/// Type is Vector of 2-byte unsigned integers, and the minimum property set version
/// is 0.
/// </summary>
VT_VECTOR_UI2 = 0x1012,
/// <summary>
/// Type is Vector of 4-byte unsigned integers, and the minimum property set version
/// is 0.
/// </summary>
VT_VECTOR_UI4 = 0x1013,
/// <summary>
/// Type is Vector of 8-byte signed integers, and the minimum property set version
/// is 0.
/// </summary>
VT_VECTOR_I8 = 0x1014,
/// <summary>
/// Type is Vector of 8-byte unsigned integers and the minimum property set version
/// is 0.
/// </summary>
VT_VECTOR_UI8 = 0x1015,
/// <summary>
/// Type is Vector of CodePageString, and the minimum property set version is 0.
/// </summary>
VT_VECTOR_LPSTR = 0x101E,
/// <summary>
/// Type is Vector of UnicodeString, and the minimum property set version is 0.
/// </summary>
VT_VECTOR_LPWSTR = 0x101F,
/// <summary>
/// Type is Vector of FILETIME, and the minimum property set version is 0.
/// </summary>
VT_VECTOR_FILETIME = 0x1040,
/// <summary>
/// Type is Vector of PropertyIdentifier, and the minimum property set version is 0.
/// </summary>
VT_VECTOR_CF = 0x1047,
/// <summary>
/// Type is Vector of CLSID, and the minimum property set version is 0.
/// </summary>
VT_VECTOR_CLSID = 0x1048,
/// <summary>
/// Type is Array of 16-bit signed integers, and the minimum property set version
/// is 1.
/// </summary>
VT_ARRAY_I2 = 0x2002,
/// <summary>
/// Type is Array of 32-bit signed integers, and the minimum property set version
/// is 1.
/// </summary>
VT_ARRAY_I4 = 0x2003,
/// <summary>
/// Type is Array of 4-byte (single-precision) IEEE floating-point numbers, and the
/// minimum property set version is 1.
/// </summary>
VT_ARRAY_R4 = 0x2004,
/// <summary>
/// Type is IEEE floating-point numbers, and the minimum property set version is 1.
/// </summary>
VT_ARRAY_R8 = 0x2005,
/// <summary>
/// Type is Array of CURRENCY, and the minimum property set version is 1.
/// </summary>
VT_ARRAY_CY = 0x2006,
/// <summary>
/// Type is Array of DATE, and the minimum property set version is 1.
/// </summary>
VT_ARRAY_DATE = 0x2007,
/// <summary>
/// Type is Array of CodePageString, and the minimum property set version is 1.
/// </summary>
VT_ARRAY_BSTR = 0x2008,
/// <summary>
/// Type is Array of HRESULT, and the minimum property set version is 1.
/// </summary>
VT_ARRAY_ERROR = 0x200A,
/// <summary>
/// Type is Array of VARIANT_BOOL, and the minimum property set version is 1.
/// </summary>
VT_ARRAY_BOOL = 0x200B,
/// <summary>
/// Type is Array of variable-typed properties, and the minimum property set
/// version is 1
/// </summary>
VT_ARRAY_VARIANT = 0x200C,
/// <summary>
/// Type is Array of DECIMAL, and the minimum property set version is 1
/// </summary>
VT_ARRAY_DECIMAL = 0x200E,
/// <summary>
/// Type is Array of 1-byte signed integers, and the minimum property set
/// version is 1
/// </summary>
VT_ARRAY_I1 = 0x2010,
/// <summary>
/// Type is Array of 1-byte unsigned integers, and the minimum property set
/// version is 1
/// </summary>
VT_ARRAY_UI1 = 0x2011,
/// <summary>
/// Type is Array of 2-byte unsigned integers, and the minimum property set
/// version is 1.
/// </summary>
VT_ARRAY_UI2 = 0x2012,
/// <summary>
/// Type is Array of 4-byte unsigned integers, and the minimum property set
/// version is 1.
/// </summary>
VT_ARRAY_UI4 = 0x2013,
/// <summary>
/// Type is Array of 4-byte signed integers, and the minimum property set version
/// is 1.
/// </summary>
VT_ARRAY_INT = 0x2016,
/// <summary>
/// Type is Array of 4-byte unsigned integers, and the minimum property set version
/// is 1.
/// </summary>
VT_ARRAY_UINT = 0x2017,
}
}

View File

@@ -1,19 +0,0 @@
namespace SabreTools.Models.OLE
{
/// <summary>
/// The FILETIME (Packet Version) packet represents a FILETIME structure ([MS-DTYP] section 2.3.3
/// </summary>
/// <see href="https://winprotocoldoc.z19.web.core.windows.net/MS-OLEPS/%5bMS-OLEPS%5d.pdf"/>
public class FILETIME
{
/// <summary>
/// The value of the dwLowDateTime field specified in [MS-DTYP] section 2.3.3.
/// </summary>
public uint LowDateTime { get; set; }
/// <summary>
/// The value of the dwHighDateTime field specified in [MS-DTYP] section 2.3.3.
/// </summary>
public uint HighDateTime { get; set; }
}
}

View File

@@ -1,29 +0,0 @@
namespace SabreTools.Models.OLE
{
/// <summary>
/// The GUID (Packet Version) packet represents a GUID
/// </summary>
/// <see href="https://winprotocoldoc.z19.web.core.windows.net/MS-OLEPS/%5bMS-OLEPS%5d.pdf"/>
public class GUID
{
/// <summary>
/// The value of the Data1 field specified in [MS-DTYP] section 2.3.4
/// </summary>
public uint Data1 { get; set; }
/// <summary>
/// The value of the Data2 field specified in [MS-DTYP] section 2.3.4
/// </summary>
public ushort Data2 { get; set; }
/// <summary>
/// The value of the Data3 field specified in [MS-DTYP] section 2.3.4
/// </summary>
public ushort Data3 { get; set; }
/// <summary>
/// The value of the Data4 field specified in [MS-DTYP] section 2.3.4
/// </summary>
public byte[]? Data4 { get; set; }
}
}

View File

@@ -1,19 +0,0 @@
namespace SabreTools.Models.OLE
{
/// <summary>
/// The IndirectPropertyName packet represents the name of a stream or storage as used in the
/// representation of the following property types in a non-simple property set: VT_STREAM (0x0042),
/// VT_STORAGE (0x0043), VT_STREAMED_OBJECT (0x0044), VT_STORED_OBJECT (0x0044), and
/// VT_VERSIONED_STREAM (0x0049). It MUST be represented as a CodePageString, and its value MUST
/// be derived from the property identifier of the property represented according to the following
/// Augmented BackusNaur Form (ABNF) [RFC4234] syntax.
///
/// Indirectproperty = "prop" propertyIdentifier
///
/// Where PropertyIdentifier is the decimal string representation of the property identifier. This property
/// identifier MUST be a valid PropertyIdentifier value and MUST NOT be the property identifier for any of
/// the special properties specified in section 2.18.
/// </summary>
/// <see href="https://winprotocoldoc.z19.web.core.windows.net/MS-OLEPS/%5bMS-OLEPS%5d.pdf"/>
public class IndirectPropertyName : CodePageString { }
}

View File

@@ -1,23 +0,0 @@
namespace SabreTools.Models.OLE
{
/// <summary>
/// The PropertyIdentifierAndOffset packet is used in the PropertySet packet to represent a
/// property identifier and the byte offset of the property in the PropertySet packet
/// </summary>
/// <see href="https://winprotocoldoc.z19.web.core.windows.net/MS-OLEPS/%5bMS-OLEPS%5d.pdf"/>
public class PropertyIdentifierAndOffset
{
/// <summary>
/// An unsigned integer representing the property identifier of a property
/// in the property set. MUST be a valid PropertyIdentifier value.
/// </summary>
public PropertyIdentifier PropertyIdentifier { get; set; }
/// <summary>
/// An unsigned integer representing the offset in bytes from the beginning
/// of the PropertySet packet to the beginning of the Property field for the
/// property represented. MUST be a multiple of 4 bytes.
/// </summary>
public uint Offset { get; set; }
}
}

View File

@@ -1,36 +0,0 @@
namespace SabreTools.Models.OLE
{
/// <summary>
/// The PropertySet packet represents a property set.
/// </summary>
/// <see href="https://winprotocoldoc.z19.web.core.windows.net/MS-OLEPS/%5bMS-OLEPS%5d.pdf"/>
public class PropertySet
{
/// <summary>
/// MUST be the total size in bytes of the PropertySet packet
/// </summary>
public uint Size { get; set; }
/// <summary>
/// An unsigned integer representing the number of properties in the
/// property set.
/// </summary>
public uint NumProperties { get; set; }
/// <summary>
/// All PropertyIdentifierAndOffset fields MUST be a sequence of
/// PropertyIdentifierAndOffset packets. The sequence MUST be in order of
/// increasing value of the Offset field. Packets are not required to be
/// in any particular order with regard to the value of the PropertyIdentifier
/// field.
/// </summary>
public PropertyIdentifierAndOffset[]? PropertyIdentifierAndOffsets { get; set; }
/// <summary>
/// Each Property field is a sequence of property values, each of which MUST
/// be represented by a TypedPropertyValue packet or a Dictionary packet in
/// the special case of the Dictionary property.
/// </summary>
public object[]? Properties { get; set; }
}
}

View File

@@ -1,106 +0,0 @@
namespace SabreTools.Models.OLE
{
/// <summary>
/// The PropertySetStream packet specifies the stream format for simple property
/// sets and the stream format for the CONTENTS stream in the Non-Simple Property
/// Set Storage Format. A simple property set MUST be represented by a stream
/// containing a PropertySetStream packet.
///
/// The PropertySetStream packet usually represents exactly one property set, but
/// for historical reasons, the DocumentSummaryInfo and UserDefinedProperties
/// property sets are represented in the same stream.In this special case, a
/// PropertySetStream might represent two property sets.
///
/// An implementation SHOULD enforce a limit on the total size of a PropertySetStream
/// packet. This limit MUST be at least 262,144 bytes, and for maximum interoperability
/// SHOULD be 2,097,152 bytes.
/// </summary>
/// <see href="https://winprotocoldoc.z19.web.core.windows.net/MS-OLEPS/%5bMS-OLEPS%5d.pdf"/>
public class PropertySetStream
{
/// <summary>
/// MUST be set to 0xFFFE
/// </summary>
public ushort ByteOrder { get; set; }
/// <summary>
/// An unsigned integer indicating the version number of the property set (or
/// property sets). MUST be 0x0000 or 0x0001. An OLEPS implementation MUST
/// accept version 0 property sets and SHOULD<5> also accept version 1 property
/// sets. This field MUST be set to 0x0001 if the property set or property sets
/// use any of the following features not supported by version 0 property sets:
/// - Property types not supported for version 0 property sets, as specified in
/// the PropertyType enumeration.
/// - The Behavior property.
///
/// If the property set does not use any of these features, this field SHOULD be
/// set to 0x0000 for maximum interoperability.
/// </summary>
public ushort Version { get; set; }
/// <summary>
/// An implementation-specific value that SHOULD be ignored, except possibly to
/// report this value to applications. It SHOULD NOT be interpreted by the
/// OLEPS implementation.
/// </summary>
public uint SystemIdentifier { get; set; }
/// <summary>
/// MUST be a GUID (Packet Version) packet representing the associated CLSID of
/// the property set (or property sets). If no CLSID is provided by the
/// application, it SHOULD be set to GUID_NULL by default.
/// </summary>
public GUID? CLSID { get; set; }
/// <summary>
/// An unsigned integer indicating the number of property sets represented by
/// this PropertySetStream structure. MUST be either 0x00000001 or 0x00000002.
///
/// - 0x00000001: This structure contains one property set
/// - 0x00000002: This structure contains two property sets.
/// The optional fields for PropertySet 1 are present.
/// </summary>
public uint NumPropertySets { get; set; }
/// <summary>
/// A GUID that MUST be set to the FMTID of the property set represented by the
/// field PropertySet 0. If NumPropertySets has the value 0x00000002, then this
/// GUID MUST be set to FMTID_DocSummaryInformation
/// ({D5CDD502-2E9C-101B-9397-08002B2CF9AE}).
/// </summary>
public GUID? FMTID0 { get; set; }
/// <summary>
/// An unsigned integer that MUST be set to the offset in bytes from the beginning
/// of this PropertySetStream structure to the beginning of the field PropertySet 0.
/// </summary>
public uint Offset0 { get; set; }
/// <summary>
/// If NumPropertySets has the value 0x00000002, it MUST be set to FMTID_UserDefinedProperties
/// ({D5CDD505-2E9C-101B-9397-08002B2CF9AE}). Otherwise, it MUST be absent.
/// </summary>
public GUID? FMTID1 { get; set; }
/// <summary>
/// If NumPropertySets has the value 0x00000002, it MUST be set to the offset in bytes
/// from the beginning of this PropertySetStream structure to the beginning of the
/// field PropertySet 1. Otherwise, it MUST be absent.
/// </summary>
public uint? Offset1 { get; set; }
/// <summary>
/// MUST be a PropertySet packet
/// </summary>
public PropertySet? PropertySet0 { get; set; }
/// <summary>
/// If NumPropertySets has the value 0x00000002, it MUST be a PropertySet packet.
/// Otherwise, it MUST be absent.
/// </summary>
public PropertySet? PropertySet1 { get; set; }
// Padding (variable): Contains additional padding added by the implementation.
// If present, padding MUST be zeroes and MUST be ignored.
}
}

View File

@@ -1,27 +0,0 @@
namespace SabreTools.Models.OLE
{
/// <summary>
/// The TypedPropertyValue structure represents the typed value of a property in a property set
/// </summary>
/// <see href="https://winprotocoldoc.z19.web.core.windows.net/MS-OLEPS/%5bMS-OLEPS%5d.pdf"/>
public class TypedPropertyValue
{
/// <summary>
/// MUST be a value from the PropertyType enumeration, indicating the type of
/// property represented.
/// </summary>
public PropertyType Type { get; set; }
/// <summary>
/// MUST be set to zero, and any nonzero value SHOULD be rejected
/// </summary>
public ushort Padding { get; set; }
/// <summary>
/// MUST be the value of the property represented and serialized according to
/// the value of Type as follows.
/// </summary>
/// <remarks>See documentation for required lengths</remarks>
public byte[]? Value { get; set; }
}
}

View File

@@ -1,23 +0,0 @@
namespace SabreTools.Models.OLE
{
/// <summary>
/// The UnicodeString packet represents a Unicode string.
/// </summary>
/// <see href="https://winprotocoldoc.z19.web.core.windows.net/MS-OLEPS/%5bMS-OLEPS%5d.pdf"/>
public class UnicodeString
{
/// <summary>
/// The length in 16-bit Unicode characters of the <see cref="Characters"/> field, including the null
/// terminator, but not including padding (if any).
/// </summary>
public uint Length { get; set; }
/// <summary>
/// If <see cref="Length"/> is zero, this field MUST be zero bytes in length. If <see cref="Length"/> is
/// nonzero, this field MUST be a null-terminated array of 16-bit Unicode characters, followed by zero
/// padding to a multiple of 4 bytes. The string represented by this field SHOULD NOT contain
/// embedded or additional trailing null characters.
/// </summary>
public string? Characters { get; set; }
}
}

View File

@@ -1,14 +0,0 @@
namespace SabreTools.Models.OLE
{
/// <summary>
/// The VectorHeader packet represents the number of scalar values in a vector property type.
/// </summary>
/// <see href="https://winprotocoldoc.z19.web.core.windows.net/MS-OLEPS/%5bMS-OLEPS%5d.pdf"/>
public class VectorHeader
{
/// <summary>
/// An unsigned integer indicating the number of scalar values following the header.
/// </summary>
public uint Length { get; set; }
}
}

View File

@@ -1,19 +0,0 @@
namespace SabreTools.Models.OLE
{
/// <summary>
/// The VersionedStream packet represents a stream with an application-specific version GUID.
/// </summary>
/// <see href="https://winprotocoldoc.z19.web.core.windows.net/MS-OLEPS/%5bMS-OLEPS%5d.pdf"/>
public class VersionedStream
{
/// <summary>
/// MUST be a GUID (Packet Version).
/// </summary>
public GUID? VersionGuid { get; set; }
/// <summary>
/// MUST be an IndirectPropertyName.
/// </summary>
public IndirectPropertyName? StreamName { get; set; }
}
}

View File

@@ -1,50 +0,0 @@
namespace SabreTools.Models.PlayJ
{
/// <summary>
/// PlayJ audio file / CDS entry
/// <summary>
public sealed class AudioFile
{
/// <summary>
/// Header
/// </summary>
public AudioHeader? Header { get; set; }
/// <summary>
/// Unknown block 1
/// </summary>
public UnknownBlock1? UnknownBlock1 { get; set; }
#region V1 Only
/// <summary>
/// Value referred to by <see cref="AudioHeaderV1.UnknownOffset2"/>
/// </summary>
/// <remarks>Typically 0x00000000</remarks>
public uint UnknownValue2 { get; set; }
/// <summary>
/// Unknown block 3 (V1 only)
/// </summary>
public UnknownBlock3? UnknownBlock3 { get; set; }
#endregion
#region V2 Only
/// <summary>
/// Number of data files embedded
/// </summary>
public uint DataFilesCount { get; set; }
/// <summary>
/// Data files (V2 only)
/// </summary>
public DataFile[]? DataFiles { get; set; }
// After the data files is a block starting with 0x00000001
// This block then contains highly repeating data, possible audio samples?
#endregion
}
}

View File

@@ -1,93 +0,0 @@
namespace SabreTools.Models.PlayJ
{
/// <summary>
/// PlayJ audio header / CDS entry header
/// </summary>
/// <remarks>V1 and V2 variants exist</remarks>
public abstract class AudioHeader
{
/// <summary>
/// Signature (0x4B539DFF)
/// </summary>
public uint Signature { get; set; }
/// <summary>
/// Version
/// </summary>
public uint Version { get; set; }
// Header-specific data goes here
/// <summary>
/// Length of the track name
/// </summary>
public ushort TrackLength { get; set; }
/// <summary>
/// Track name (not null-terminated)
/// </summary>
public string? Track { get; set; }
/// <summary>
/// Length of the artist name
/// </summary>
public ushort ArtistLength { get; set; }
/// <summary>
/// Artist name (not null-terminated)
/// </summary>
public string? Artist { get; set; }
/// <summary>
/// Length of the album name
/// </summary>
public ushort AlbumLength { get; set; }
/// <summary>
/// Album name (not null-terminated)
/// </summary>
public string? Album { get; set; }
/// <summary>
/// Length of the writer name
/// </summary>
public ushort WriterLength { get; set; }
/// <summary>
/// Writer name (not null-terminated)
/// </summary>
public string? Writer { get; set; }
/// <summary>
/// Length of the publisher name
/// </summary>
public ushort PublisherLength { get; set; }
/// <summary>
/// Publisher name (not null-terminated)
/// </summary>
public string? Publisher { get; set; }
/// <summary>
/// Length of the label name
/// </summary>
public ushort LabelLength { get; set; }
/// <summary>
/// Label name (not null-terminated)
/// </summary>
public string? Label { get; set; }
/// <summary>
/// Length of the comments
/// </summary>
/// <remarks>Optional field only in some samples</remarks>
public ushort CommentsLength { get; set; }
/// <summary>
/// Comments (not null-terminated)
/// </summary>
/// <remarks>Optional field only in some samples</remarks>
public string? Comments { get; set; }
}
}

View File

@@ -1,62 +0,0 @@
namespace SabreTools.Models.PlayJ
{
/// <summary>
/// PlayJ audio header / CDS entry header (V1)
/// </summary>
public sealed class AudioHeaderV1 : AudioHeader
{
/// <summary>
/// Download track ID
/// </summary>
/// <remarks>0xFFFFFFFF if unset</remarks>
public uint TrackID { get; set; }
/// <summary>
/// Offset to unknown data block 1
/// </summary>
public uint UnknownOffset1 { get; set; }
/// <summary>
/// Offset to unknown data block 2
/// </summary>
public uint UnknownOffset2 { get; set; }
/// <summary>
/// Offset to unknown data block 3
/// </summary>
public uint UnknownOffset3 { get; set; }
/// <summary>
/// Unknown
/// </summary>
/// <remarks>Always 0x00000001</remarks>
public uint Unknown1 { get; set; }
/// <summary>
/// Unknown
/// </summary>
/// <remarks>Typically 0x00000001 in download titles</remarks>
public uint Unknown2 { get; set; }
/// <summary>
/// Track year
/// </summary>
/// <remarks>0xFFFFFFFF if unset</remarks>
public uint Year { get; set; }
/// <summary>
/// Track number
/// </summary>
public byte TrackNumber { get; set; }
/// <summary>
/// Subgenre
/// </summary>
public Subgenre Subgenre { get; set; }
/// <summary>
/// Track duration in seconds
/// </summary>
public uint Duration { get; set; }
}
}

View File

@@ -1,126 +0,0 @@
namespace SabreTools.Models.PlayJ
{
/// <summary>
/// PlayJ audio header / CDS entry header (V2)
/// </summary>
public sealed class AudioHeaderV2 : AudioHeader
{
/// <summary>
/// Unknown (Always 0x00000001)
/// </summary>
public uint Unknown1 { get; set; }
/// <summary>
/// Unknown (Always 0x00000001)
/// </summary>
public uint Unknown2 { get; set; }
/// <summary>
/// Unknown (Always 0x00000000)
/// </summary>
public uint Unknown3 { get; set; }
/// <summary>
/// Unknown (Always 0x00000003)
/// </summary>
public uint Unknown4 { get; set; }
/// <summary>
/// Unknown (Always 0x00000001)
/// </summary>
public uint Unknown5 { get; set; }
/// <summary>
/// Unknown (Always 0x00000000)
/// </summary>
public uint Unknown6 { get; set; }
/// <summary>
/// Offset to unknown block 1, relative to the track ID
/// </summary>
public uint UnknownOffset1 { get; set; }
/// <summary>
/// Unknown
/// </summary>
public uint Unknown7 { get; set; }
/// <summary>
/// Unknown (Always 0x00000004)
/// </summary>
public uint Unknown8 { get; set; }
/// <summary>
/// Unknown (Always 0x00000002)
/// </summary>
public uint Unknown9 { get; set; }
/// <summary>
/// Offset to unknown block 1, relative to the track ID
/// </summary>
/// <remarks>Always identical to <see cref="UnknownOffset1"/>?</remarks>
public uint UnknownOffset2 { get; set; }
/// <summary>
/// Unknown
/// </summary>
public uint Unknown10 { get; set; }
/// <summary>
/// Unknown
/// </summary>
public uint Unknown11 { get; set; }
/// <summary>
/// Unknown (Always 0x0000005)
/// </summary>
public uint Unknown12 { get; set; }
/// <summary>
/// Unknown (Always 0x0000009)
/// </summary>
public uint Unknown13 { get; set; }
/// <summary>
/// Unknown
/// </summary>
public uint Unknown14 { get; set; }
/// <summary>
/// Unknown
/// </summary>
public uint Unknown15 { get; set; }
/// <summary>
/// Unknown (Always 0x0000000)
/// </summary>
public uint Unknown16 { get; set; }
/// <summary>
/// Unknown (Always 0x00000007)
/// </summary>
public uint Unknown17 { get; set; }
/// <summary>
/// Download track ID
/// </summary>
/// <remarks>0xFFFFFFFF if unset</remarks>
public uint TrackID { get; set; }
/// <summary>
/// Track year -- UNCONFIRMED
/// </summary>
/// <remarks>0xFFFFFFFF if unset</remarks>
public uint Year { get; set; }
/// <summary>
/// Track number
/// </summary>
public uint TrackNumber { get; set; }
/// <summary>
/// Unknown
/// </summary>
public uint Unknown18 { get; set; }
}
}

View File

@@ -1,9 +0,0 @@
namespace SabreTools.Models.PlayJ
{
public static class Constants
{
public static readonly byte[] SignatureBytes = [0xFF, 0x9D, 0x53, 0x4B];
public const uint SignatureUInt32 = 0x4B539DFF;
}
}

View File

@@ -1,35 +0,0 @@
namespace SabreTools.Models.PlayJ
{
/// <summary>
/// Embedded data file (V2 only?)
/// </summary>
public sealed class DataFile
{
/// <summary>
/// Length of the data file name
/// </summary>
public ushort FileNameLength { get; set; }
/// <summary>
/// Data file name
/// </summary>
public string? FileName { get; set; }
/// <summary>
/// Length of the data
/// </summary>
public uint DataLength { get; set; }
/// <summary>
/// Data
/// </summary>
public byte[]? Data { get; set; }
// Notes about Data:
// - Each data block in the samples contains a GIF header
// - Each GIF header contains an application extension: http://www.vurdalakov.net/misc/gif/application-extension
// - Each GIF doesn't always stretch to the end of the data
// - Remaining data seems to be padded as 0x00 (typically 8 bytes)
// - GIF data is fully formed and may be copied to a standalone file
}
}

View File

@@ -1,122 +0,0 @@
namespace SabreTools.Models.PlayJ
{
/// <see href="http://www.playj.com/static/genreindex_XX.html"/>
public enum Genre
{
/// <summary>
/// Blues/Folk/Country
/// </summary>
BluesFolkCountry = 1,
/// <summary>
/// Jazz
/// </summary>
Jazz = 5,
/// <summary>
/// Reggae
/// </summary>
Reggae = 10,
/// <summary>
/// Classical
/// </summary>
Classical = 12,
/// <summary>
/// Electronic
/// </summary>
Electronic = 13,
/// <summary>
/// Pop/Rock
/// </summary>
PopRock = 15,
/// <summary>
/// World
/// </summary>
World = 16,
/// <summary>
/// Urban
/// </summary>
Urban = 17,
/// <summary>
/// Latin
/// </summary>
Latin = 18,
/// <summary>
/// Soundtrack/Other
/// </summary>
SoundtrackOther = 20,
/// <summary>
/// New Age
/// </summary>
NewAge = 21,
/// <summary>
/// Spiritual
/// </summary>
Spiritual = 22,
/// <summary>
/// Sway & Tech
/// </summary>
SwayAndTech = 23,
/// <summary>
/// Jam Bands
/// </summary>
JamBands = 24,
/// <summary>
/// Comedy
/// </summary>
Comedy = 25,
/// <summary>
/// Brazilian
/// </summary>
Brazilian = 26,
}
// TODO: Fill out the remaining subgenres from the wayback machine
/// <see href="http://playj.com/static/subgenre_XX.html"/>
/// <remarks>Every subgenre is uniquely associated with a genre</remarks>
public enum Subgenre : byte
{
/// <summary>
/// Blues/Folk/Country > Blues (Modern/Electric)
/// </summary>
BluesModernElectric = 2,
/// <summary>
/// Blues/Folk/Country > Blues (Modern/Acoustic)
/// </summary>
BluesModernAcoustic = 3,
/// <summary>
/// Blues/Folk/Country > Blues (Traditional)
/// </summary>
BluesTraditional = 4,
/// <summary>
/// Blues/Folk/Country > Folk (Traditional)
/// </summary>
FolkTraditional = 5,
/// <summary>
/// Blues/Folk/Country > Folk (Contemporary)
/// </summary>
FolkContemporary = 6,
/// <summary>
/// Blues/Folk/Country > Folk (Jazz)
/// </summary>
FolkJazz = 7,
}
}

View File

@@ -1,18 +0,0 @@
namespace SabreTools.Models.PlayJ
{
/// <summary>
/// PlayJ playlist file
/// </summary>
public sealed class Playlist
{
/// <summary>
/// Playlist header
/// </summary>
public PlaylistHeader? Header { get; set; }
/// <summary>
/// Embedded audio files / headers
/// </summary>
public AudioFile[]? AudioFiles { get; set; }
}
}

View File

@@ -1,18 +0,0 @@
namespace SabreTools.Models.PlayJ
{
/// <summary>
/// PlayJ playlist header
/// </summary>
public sealed class PlaylistHeader
{
/// <summary>
/// Number of tracks contained within the playlist
/// </summary>
public uint TrackCount { get; set; }
/// <summary>
/// 52 bytes of unknown data
/// </summary>
public byte[]? Data { get; set; }
}
}

View File

@@ -1,24 +0,0 @@
namespace SabreTools.Models.PlayJ
{
/// <summary>
/// Data referred to by <see cref="AudioHeaderV1.UnknownOffset1"/> or <see cref="AudioHeaderV2.UnknownOffset1"/>
/// </summary>
public sealed class UnknownBlock1
{
/// <summary>
/// Length of the following data block
/// </summary>
public uint Length { get; set; }
/// <summary>
/// Unknown data
/// </summary>
public byte[]? Data { get; set; }
// Notes about Data:
// - Might be UInt16 offset and UInt16 length pairs
// - Might be relevant to ad data
// - Might be relevant to encryption
// - Highly repeating patterns in the values with only a few differences
}
}

View File

@@ -1,18 +0,0 @@
namespace SabreTools.Models.PlayJ
{
/// <summary>
/// Data referred to by <see cref="AudioHeaderV1.UnknownOffset3"/>
/// </summary>
public sealed class UnknownBlock3
{
/// <summary>
/// Unknown data
/// </summary>
public byte[]? Data { get; set; }
// Notes about Data:
// - This may be where the encrypted audio samples live
// - It is also possible that it's where the ad data lives and samples follow
// + See V2 for example of why this would be the case
}
}

Some files were not shown because too many files have changed in this diff Show More