Add everything from cab.h

This commit is contained in:
Matt Nadareski
2023-09-19 01:33:34 -04:00
parent 04af8d3f79
commit f47434bc3b
7 changed files with 223 additions and 0 deletions

75
libmspack/cab.cs Normal file
View File

@@ -0,0 +1,75 @@
namespace SabreTools.Compression.libmspack
{
public static class cab
{
/* structure offsets */
public const byte cfhead_Signature = 0x00;
public const byte cfhead_CabinetSize = 0x08;
public const byte cfhead_FileOffset = 0x10;
public const byte cfhead_MinorVersion = 0x18;
public const byte cfhead_MajorVersion = 0x19;
public const byte cfhead_NumFolders = 0x1A;
public const byte cfhead_NumFiles = 0x1C;
public const byte cfhead_Flags = 0x1E;
public const byte cfhead_SetID = 0x20;
public const byte cfhead_CabinetIndex = 0x22;
public const byte cfhead_SIZEOF = 0x24;
public const byte cfheadext_HeaderReserved = 0x00;
public const byte cfheadext_FolderReserved = 0x02;
public const byte cfheadext_DataReserved = 0x03;
public const byte cfheadext_SIZEOF = 0x04;
public const byte cffold_DataOffset = 0x00;
public const byte cffold_NumBlocks = 0x04;
public const byte cffold_CompType = 0x06;
public const byte cffold_SIZEOF = 0x08;
public const byte cffile_UncompressedSize = 0x00;
public const byte cffile_FolderOffset = 0x04;
public const byte cffile_FolderIndex = 0x08;
public const byte cffile_Date = 0x0A;
public const byte cffile_Time = 0x0C;
public const byte cffile_Attribs = 0x0E;
public const byte cffile_SIZEOF = 0x10;
public const byte cfdata_CheckSum = 0x00;
public const byte cfdata_CompressedSize = 0x04;
public const byte cfdata_UncompressedSize = 0x06;
public const byte cfdata_SIZEOF = 0x08;
/* flags */
public const ushort cffoldCOMPTYPE_MASK = 0x000f;
public const ushort cffoldCOMPTYPE_NONE = 0x0000;
public const ushort cffoldCOMPTYPE_MSZIP = 0x0001;
public const ushort cffoldCOMPTYPE_QUANTUM = 0x0002;
public const ushort cffoldCOMPTYPE_LZX = 0x0003;
public const ushort cfheadPREV_CABINET = 0x0001;
public const ushort cfheadNEXT_CABINET = 0x0002;
public const ushort cfheadRESERVE_PRESENT = 0x0004;
public const ushort cffileCONTINUED_FROM_PREV = 0xFFFD;
public const ushort cffileCONTINUED_TO_NEXT = 0xFFFE;
public const ushort cffileCONTINUED_PREV_AND_NEXT = 0xFFFF;
/* CAB data blocks are <= 32768 bytes in uncompressed form. Uncompressed
* blocks have zero growth. MSZIP guarantees that it won't grow above
* uncompressed size by more than 12 bytes. LZX guarantees it won't grow
* more than 6144 bytes. Quantum has no documentation, but the largest
* block seen in the wild is 337 bytes above uncompressed size.
*/
public const int CAB_BLOCKMAX = 32768;
public const int CAB_INPUTMAX = CAB_BLOCKMAX + 6144;
/* input buffer needs to be CAB_INPUTMAX + 1 byte to allow for max-sized block
* plus 1 trailer byte added by cabd_sys_read_block() for Quantum alignment.
*
* When MSCABD_PARAM_SALVAGE is set, block size is not checked so can be
* up to 65535 bytes, so max input buffer size needed is 65535 + 1
*/
public const int CAB_INPUTMAX_SALVAGE = 65535;
public const int CAB_INPUTBUF = CAB_INPUTMAX_SALVAGE + 1;
/* There are no more than 65535 data blocks per folder, so a folder cannot
* be more than 32768*65535 bytes in length. As files cannot span more than
* one folder, this is also their max offset, length and offset+length limit.
*/
public const int CAB_FOLDERMAX = 65535;
public const int CAB_LENGTHMAX = CAB_BLOCKMAX * CAB_FOLDERMAX;
}
}

View File

@@ -6,5 +6,7 @@ namespace SabreTools.Compression.libmspack
public class mscab_compressor
{
public int dummy { get; set; }
public mspack_system system { get; set; }
}
}

View File

@@ -9,6 +9,22 @@ namespace SabreTools.Compression.libmspack
/// <see cref="mspack_destroy_cab_decompressor()"/>
public abstract class mscab_decompressor
{
public mscabd_decompress_state d { get; set; }
public mspack_system system { get; set; }
public int buf_size { get; set; }
public int searchbuf_size { get; set; }
public int fix_mszip { get; set; }
public int salvage { get; set; }
public MSPACK_ERR error { get; set; }
public MSPACK_ERR read_error { get; set; }
/// <summary>
/// Opens a cabinet file and reads its contents.
///

View File

@@ -111,5 +111,15 @@ namespace SabreTools.Compression.libmspack
/// <see cref="nextinfo"/>
/// <see cref="header_resv"/>
public MSCAB_HDR flags { get; set; }
/// <summary>
/// Offset to data blocks
/// </summary>
public long blocks_off { get; set; }
/// <summary>
/// Reserved space in data blocks
/// </summary>
public int block_resv { get; set; }
}
}

View File

@@ -0,0 +1,85 @@
using static SabreTools.Compression.libmspack.cab;
namespace SabreTools.Compression.libmspack
{
public abstract unsafe class mscabd_decompress_state
{
/// <summary>
/// Current folder we're extracting from
/// </summary>
public mscabd_folder folder { get; set; }
/// <summary>
/// Current folder split we're in
/// </summary>
public mscabd_folder_data data { get; set; }
/// <summary>
/// Uncompressed offset within folder
/// </summary>
public uint offset { get; set; }
/// <summary>
/// Which block are we decompressing?
/// </summary>
public uint block { get; set; }
/// <summary>
/// Cumulative sum of block output sizes
/// </summary>
public long outlen { get; set; }
/// <summary>
/// Special I/O code for decompressor
/// </summary>
public mspack_system sys { get; set; }
/// <summary>
/// Type of compression used by folder
/// </summary>
public MSCAB_COMP comp_type { get; set; }
/// <summary>
/// Decompressor code
/// </summary>
/// <param name="data"></param>
/// <param name="offset"></param>
/// <returns></returns>
public abstract int decompress(void* data, long offset);
/// <summary>
/// Decompressor state
/// </summary>
public void* state { get; set; }
/// <summary>
/// Cabinet where input data comes from
/// </summary>
public mscabd_cabinet incab { get; set; }
/// <summary>
/// Input file handle
/// </summary>
public mspack_file infh { get; set; }
/// <summary>
/// Output file handle
/// </summary>
public mspack_file outfh { get; set; }
/// <summary>
/// Input data consumed
/// </summary>
public byte* i_ptr { get; set; }
/// <summary>
/// Input data end
/// </summary>
public byte* i_end { get; set; }
/// <summary>
/// One input block of data
/// </summary>
public byte[] input { get; set; } = new byte[CAB_INPUTBUF];
}
}

View File

@@ -34,5 +34,20 @@ namespace SabreTools.Compression.libmspack
/// one cabinet.
/// </summary>
public uint num_blocks { get; set; }
/// <summary>
/// Where are the data blocks?
/// </summary>
public mscabd_folder_data data { get; set; }
/// <summary>
/// First file needing backwards merge
/// </summary>
public mscabd_file merge_prev { get; set; }
/// <summary>
/// First file needing forwards merge
/// </summary>
public mscabd_file merge_next { get; set; }
}
}

View File

@@ -0,0 +1,20 @@
namespace SabreTools.Compression.libmspack
{
/// <summary>
/// There is one of these for every cabinet a folder spans
/// </summary>
public class mscabd_folder_data
{
public mscabd_folder_data next { get; set; }
/// <summary>
/// Cabinet file of this folder span
/// </summary>
public mscabd_cabinet cab { get; set; }
/// <summary>
/// Cabinet offset of first datablock
/// </summary>
public long offset { get; set; }
}
}