From 73a8d91a83d04d5762dfc84aa818bc39501469bb Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Tue, 23 Apr 2024 20:55:10 -0400 Subject: [PATCH] Add layouts for some CFB models --- CFB/Binary.cs | 8 ++++---- CFB/DirectoryEntry.cs | 35 ++++++++++++++++++++------------ CFB/FileHeader.cs | 42 ++++++++++++++++++++++----------------- CFB/SummaryInformation.cs | 2 +- 4 files changed, 51 insertions(+), 36 deletions(-) diff --git a/CFB/Binary.cs b/CFB/Binary.cs index 1aad482..8bddf02 100644 --- a/CFB/Binary.cs +++ b/CFB/Binary.cs @@ -25,7 +25,7 @@ namespace SabreTools.Models.CFB /// /// If Header Major Version is 4, there MUST be 1,024 fields specified to fill a 4,096-byte sector /// - public SectorNumber?[]? FATSectorNumbers { get; set; } + public SectorNumber[]? FATSectorNumbers { get; set; } /// /// The mini FAT is used to allocate space in the mini stream. @@ -38,7 +38,7 @@ namespace SabreTools.Models.CFB /// /// If Header Major Version is 4, there MUST be 1,024 fields specified to fill a 4,096-byte sector /// - public SectorNumber?[]? MiniFATSectorNumbers { get; set; } + public SectorNumber[]? MiniFATSectorNumbers { get; set; } /// /// The DIFAT array is used to represent storage of the FAT sectors. @@ -55,7 +55,7 @@ namespace SabreTools.Models.CFB /// If Header Major Version is 4, there MUST be 1,023 fields specified /// to fill a 4,096-byte sector minus the "Next DIFAT Sector Location" field. /// - public SectorNumber?[]? DIFATSectorNumbers { get; set; } + public SectorNumber[]? DIFATSectorNumbers { get; set; } /// /// The directory entry array is an array of directory entries that @@ -87,6 +87,6 @@ namespace SabreTools.Models.CFB /// all zeroes. The Modified Time field in the root storage directory /// entry MAY be all zeroes. /// - public DirectoryEntry?[]? DirectoryEntries { get; set; } + public DirectoryEntry[]? DirectoryEntries { get; set; } } } \ No newline at end of file diff --git a/CFB/DirectoryEntry.cs b/CFB/DirectoryEntry.cs index 9082465..19635e5 100644 --- a/CFB/DirectoryEntry.cs +++ b/CFB/DirectoryEntry.cs @@ -1,8 +1,10 @@ using System; +using System.Runtime.InteropServices; namespace SabreTools.Models.CFB { /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public sealed class DirectoryEntry { /// @@ -16,13 +18,15 @@ namespace SabreTools.Models.CFB /// The following characters are illegal and MUST NOT be part of the /// name: '/', '\', ':', '!'. /// - public string? Name { get; set; } + /// 64 bytes + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] + public string? Name; /// /// This field MUST be 0x00, 0x01, 0x02, or 0x05, depending on the /// actual type of object. All other values are not valid. /// - public ushort NameLength { get; set; } + public ushort NameLength; /// /// This field MUST match the length of the Directory Entry Name Unicode @@ -30,31 +34,36 @@ namespace SabreTools.Models.CFB /// terminating null character in the count. This length MUST NOT exceed 64, /// the maximum size of the Directory Entry Name field. /// - public ObjectType ObjectType { get; set; } + [MarshalAs(UnmanagedType.U1)] + public ObjectType ObjectType; /// /// This field MUST be 0x00 (red) or 0x01 (black). All other values are not valid. /// - public ColorFlag ColorFlag { get; set; } + [MarshalAs(UnmanagedType.U1)] + public ColorFlag ColorFlag; /// /// This field contains the stream ID of the left sibling. If there /// is no left sibling, the field MUST be set to NOSTREAM (0xFFFFFFFF). /// - public StreamID LeftSiblingID { get; set; } + [MarshalAs(UnmanagedType.U4)] + public StreamID LeftSiblingID; /// /// This field contains the stream ID of the right sibling. If there /// is no right sibling, the field MUST be set to NOSTREAM (0xFFFFFFFF). /// - public StreamID RightSiblingID { get; set; } + [MarshalAs(UnmanagedType.U4)] + public StreamID RightSiblingID; /// /// 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). /// - public StreamID ChildID { get; set; } + [MarshalAs(UnmanagedType.U4)] + public StreamID ChildID; /// /// This field contains an object class GUID, if this entry is for a @@ -67,7 +76,7 @@ namespace SabreTools.Models.CFB /// this value is not all zeroes, the object class GUID can be used as a /// parameter to start applications. /// - public Guid CLSID { get; set; } + public Guid CLSID; /// /// This field contains the user-defined flags if this entry is for a storage @@ -78,7 +87,7 @@ namespace SabreTools.Models.CFB /// objects without explicitly setting state bits, it MUST write all zeroes /// by default. /// - public uint StateBits { get; set; } + public uint StateBits; /// /// This field contains the creation time for a storage object, or all zeroes @@ -88,7 +97,7 @@ namespace SabreTools.Models.CFB /// object, this field MUST be all zeroes, and the creation time is retrieved /// or set on the compound file itself. /// - public ulong CreationTime { get; set; } + public ulong CreationTime; /// /// This field contains the modification time for a storage object, or all @@ -98,7 +107,7 @@ namespace SabreTools.Models.CFB /// storage object, this field MAY<2> be set to all zeroes, and the modified /// time is retrieved or set on the compound file itself. /// - public ulong ModifiedTime { get; set; } + public ulong ModifiedTime; /// /// This field contains the first sector location if this is a stream object. @@ -106,7 +115,7 @@ namespace SabreTools.Models.CFB /// mini stream, if the mini stream exists. For a storage object, this field MUST /// be set to all zeroes. /// - public uint StartingSectorLocation { get; set; } + public uint StartingSectorLocation; /// /// This 64-bit integer field contains the size of the user-defined data if this @@ -128,6 +137,6 @@ namespace SabreTools.Models.CFB /// unless there is a specific reason to do otherwise (for example, a parser whose /// purpose is to verify the correctness of a compound file). /// - public ulong StreamSize { get; set; } + public ulong StreamSize; } } \ No newline at end of file diff --git a/CFB/FileHeader.cs b/CFB/FileHeader.cs index 632039e..5714fe8 100644 --- a/CFB/FileHeader.cs +++ b/CFB/FileHeader.cs @@ -1,38 +1,40 @@ using System; +using System.Runtime.InteropServices; namespace SabreTools.Models.CFB { /// + [StructLayout(LayoutKind.Sequential)] public sealed class FileHeader { /// /// Iddentification signature for the compound file structure, and MUST be /// set to the value 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1. /// - public ulong Signature { get; set; } + public ulong Signature; /// /// Reserved and unused class ID that MUST be set to all zeroes (CLSID_NULL) /// - public Guid CLSID { get; set; } + public Guid CLSID; /// /// Version number for nonbreaking changes. This field SHOULD be set to /// 0x003E if the major version field is either 0x0003 or 0x0004. /// - public ushort MinorVersion { get; set; } + public ushort MinorVersion; /// /// Version number for breaking changes. This field MUST be set to either /// 0x0003 (version 3) or 0x0004 (version 4). /// - public ushort MajorVersion { get; set; } + public ushort MajorVersion; /// /// This field MUST be set to 0xFFFE. This field is a byte order mark for /// all integer fields, specifying little-endian byte order. /// - public ushort ByteOrder { get; set; } + public ushort ByteOrder; /// /// This field MUST be set to 0x0009, or 0x000c, depending on the Major @@ -45,19 +47,21 @@ namespace SabreTools.Models.CFB /// If Major Version is 4, the Sector Shift MUST be 0x000C, specifying a /// sector size of 4096 bytes. /// - public ushort SectorShift { get; set; } + public ushort SectorShift; /// /// 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. /// - public ushort MiniSectorShift { get; set; } + public ushort MiniSectorShift; /// /// This field MUST be set to all zeroes. /// - public byte[]? Reserved { get; set; } + /// 6 bytes + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public byte[]? Reserved; /// /// This integer field contains the count of the number of directory sectors @@ -66,18 +70,18 @@ namespace SabreTools.Models.CFB /// If Major Version is 3, the Number of Directory Sectors MUST be zero. This /// field is not supported for version 3 compound files. /// - public uint NumberOfDirectorySectors { get; set; } + public uint NumberOfDirectorySectors; /// /// This integer field contains the count of the number of FAT sectors in the /// compound file. /// - public uint NumberOfFATSectors { get; set; } + public uint NumberOfFATSectors; /// /// This integer field contains the starting sector number for the directory stream. /// - public uint FirstDirectorySectorLocation { get; set; } + public uint FirstDirectorySectorLocation; /// /// This integer field MAY contain a sequence number that is incremented every time @@ -85,7 +89,7 @@ namespace SabreTools.Models.CFB /// This is the field that MUST be set to all zeroes if file transactions are not /// implemented. /// - public uint TransactionSignatureNumber { get; set; } + public uint TransactionSignatureNumber; /// /// This integer field MUST be set to 0x00001000. This field specifies the maximum @@ -94,34 +98,36 @@ namespace SabreTools.Models.CFB /// greater than or equal to this cutoff size must be allocated as normal sectors from /// the FAT. /// - public uint MiniStreamCutoffSize { get; set; } + public uint MiniStreamCutoffSize; /// /// This integer field contains the starting sector number for the mini FAT. /// - public uint FirstMiniFATSectorLocation { get; set; } + public uint FirstMiniFATSectorLocation; /// /// This integer field contains the count of the number of mini FAT sectors in the /// compound file. /// - public uint NumberOfMiniFATSectors { get; set; } + public uint NumberOfMiniFATSectors; /// /// This integer field contains the starting sector number for the DIFAT. /// - public uint FirstDIFATSectorLocation { get; set; } + public uint FirstDIFATSectorLocation; /// /// This integer field contains the count of the number of DIFAT sectors in the /// compound file. /// - public uint NumberOfDIFATSectors { get; set; } + public uint NumberOfDIFATSectors; /// /// This array of 32-bit integer fields contains the first 109 FAT sector /// locations of the compound file /// - public SectorNumber?[]? DIFAT { get; set; } + /// 109 entries + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 109)] + public SectorNumber[]? DIFAT; } } \ No newline at end of file diff --git a/CFB/SummaryInformation.cs b/CFB/SummaryInformation.cs index 78ff3f5..6a9f864 100644 --- a/CFB/SummaryInformation.cs +++ b/CFB/SummaryInformation.cs @@ -75,7 +75,7 @@ namespace SabreTools.Models.CFB /// Properties /// /// Each Variant might be followed by an index and offset value - public Variant?[]? Properties { get; set; } + public Variant[]? Properties { get; set; } #endregion }