diff --git a/BurnOutSharp.Wrappers/MicrosoftCabinet.fdi.cs b/BurnOutSharp.Wrappers/MicrosoftCabinet.fdi.cs
index 9fce303a..9bdbb6ba 100644
--- a/BurnOutSharp.Wrappers/MicrosoftCabinet.fdi.cs
+++ b/BurnOutSharp.Wrappers/MicrosoftCabinet.fdi.cs
@@ -1,1319 +1,2325 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using static BurnOutSharp.Wrappers.CabinetConstants;
-using static BurnOutSharp.Wrappers.FDIConstants;
-
-namespace BurnOutSharp.Wrappers
-{
- public partial class MicrosoftCabinet
- {
-
- }
-
- ///
- #region fdi.h
-
- ///
- internal class ERF
- {
- ///
- /// FCI/FDI error code - see {FCI,FDI}ERROR_XXX for details.
- ///
- public int erfOper;
-
- ///
- /// Optional error value filled in by FCI/FDI.
- ///
- public int erfType;
-
- ///
- /// TRUE => error present
- ///
- public bool fError;
- }
-
- /**********************************************************************/
-
- ///
- internal static class FDIConstants
- {
- public const ushort CB_MAX_CHUNK = 32768;
- public const uint CB_MAX_DISK = 0x7fffffff;
- public const int CB_MAX_FILENAME = 256;
- public const int CB_MAX_CABINET_NAME = 256;
- public const int CB_MAX_CAB_PATH = 256;
- public const int CB_MAX_DISK_NAME = 256;
-
- /**********************************************************************/
-
- ///
- /// Mask for compression type
- ///
- public const ushort tcompMASK_TYPE = 0x000F;
-
- ///
- /// No compression
- ///
- public const ushort tcompTYPE_NONE = 0x0000;
-
- ///
- /// MSZIP
- ///
- public const ushort tcompTYPE_MSZIP = 0x0001;
-
- ///
- /// Quantum
- ///
- public const ushort tcompTYPE_QUANTUM = 0x0002;
-
- ///
- /// LZX
- ///
- public const ushort tcompTYPE_LZX = 0x0003;
-
- ///
- /// Unspecified compression type
- ///
- public const ushort tcompBAD = 0x000F;
-
- ///
- /// Mask for LZX Compression Memory
- ///
- public const ushort tcompMASK_LZX_WINDOW = 0x1F00;
-
- ///
- /// Lowest LZX Memory (15)
- ///
- public const ushort tcompLZX_WINDOW_LO = 0x0F00;
-
- ///
- /// Highest LZX Memory (21)
- ///
- public const ushort tcompLZX_WINDOW_HI = 0x1500;
-
- ///
- /// Amount to shift over to get int
- ///
- public const ushort tcompSHIFT_LZX_WINDOW = 8;
-
- ///
- /// Mask for Quantum Compression Level
- ///
- public const ushort tcompMASK_QUANTUM_LEVEL = 0x00F0;
-
- ///
- /// Lowest Quantum Level (1)
- ///
- public const ushort tcompQUANTUM_LEVEL_LO = 0x0010;
-
- ///
- /// Highest Quantum Level (7)
- ///
- public const ushort tcompQUANTUM_LEVEL_HI = 0x0070;
-
- ///
- /// Amount to shift over to get int
- ///
- public const ushort tcompSHIFT_QUANTUM_LEVEL = 4;
-
- ///
- /// Mask for Quantum Compression Memory
- ///
- public const ushort tcompMASK_QUANTUM_MEM = 0x1F00;
-
- ///
- /// Lowest Quantum Memory (10)
- ///
- public const ushort tcompQUANTUM_MEM_LO = 0x0A00;
-
- ///
- /// Highest Quantum Memory (21)
- ///
- public const ushort tcompQUANTUM_MEM_HI = 0x1500;
-
- ///
- /// Amount to shift over to get int
- ///
- public const ushort tcompSHIFT_QUANTUM_MEM = 8;
-
- ///
- /// Reserved bits (high 3 bits)
- ///
- public const ushort tcompMASK_RESERVED = 0xE000;
-
- /**********************************************************************/
-
- public const byte _A_NAME_IS_UTF = 0x80;
-
- public const byte _A_EXEC = 0x40;
-
- /**********************************************************************/
-
- ///
- /// FDI does detection
- ///
- public const int cpuUNKNOWN = -1;
-
- ///
- /// '286 opcodes only
- ///
- public const int cpu80286 = 0;
-
- ///
- /// '386 opcodes used
- ///
- public const int cpu80386 = 1;
-
- /**********************************************************************/
- }
-
- /**********************************************************************/
-
- ///
- internal enum FDIERROR
- {
- FDIERROR_NONE,
- FDIERROR_CABINET_NOT_FOUND,
- FDIERROR_NOT_A_CABINET,
- FDIERROR_UNKNOWN_CABINET_VERSION,
- FDIERROR_CORRUPT_CABINET,
- FDIERROR_ALLOC_FAIL,
- FDIERROR_BAD_COMPR_TYPE,
- FDIERROR_MDI_FAIL,
- FDIERROR_TARGET_FILE,
- FDIERROR_RESERVE_MISMATCH,
- FDIERROR_WRONG_CABINET,
- FDIERROR_USER_ABORT,
- }
-
- /**********************************************************************/
-
- ///
- internal class FDICABINETINFO
- {
- ///
- /// Total length of cabinet file
- ///
- public long cbCabinet;
-
- ///
- /// Count of folders in cabinet
- ///
- public ushort cFolders;
-
- ///
- /// Count of files in cabinet
- ///
- public ushort cFiles;
-
- ///
- /// Cabinet set ID
- ///
- public ushort setID;
-
- ///
- /// Cabinet number in set (0 based)
- ///
- public ushort iCabinet;
-
- ///
- /// TRUE => RESERVE present in cabinet
- ///
- public bool fReserve;
-
- ///
- /// TRUE => Cabinet is chained prev
- ///
- public bool hasprev;
-
- ///
- /// TRUE => Cabinet is chained next
- ///
- public bool hasnext;
- }
-
- /**********************************************************************/
-
- ///
- internal enum FDIDECRYPTTYPE
- {
- ///
- /// New cabinet
- ///
- fdidtNEW_CABINET,
-
- ///
- /// New folder
- ///
- fdidtNEW_FOLDER,
-
- ///
- /// Decrypt a data block
- ///
- fdidtDECRYPT,
- }
-
- /**********************************************************************/
-
- ///
- internal class FDIDECRYPT
- {
- ///
- /// Command type (selects union below)
- ///
- public FDIDECRYPTTYPE fdidt;
-
- ///
- /// Decryption context
- ///
- public object pvUser;
-
- #region DUMMYUNIONNAME
-
- ///
- /// fdidtNEW_CABINET
- ///
- public DUMMYUNIONNAMEcabinet cabinet;
-
- ///
- /// fdidtNEW_FOLDER
- ///
- public DUMMYUNIONNAMEfolder folder;
-
- ///
- /// fdidtDECRYPT
- ///
- public DUMMYUNIONNAMEdecrypt decrypt;
-
- ///
- /// fdidtNEW_CABINET
- ///
- public class DUMMYUNIONNAMEcabinet
- {
- ///
- /// RESERVE section from CFHEADER
- ///
- public object pHeaderReserve;
-
- ///
- /// Size of pHeaderReserve
- ///
- public ushort cbHeaderReserve;
-
- ///
- /// Cabinet set ID
- ///
- public ushort setID;
-
- ///
- /// Cabinet number in set (0 based)
- ///
- public int iCabinet;
- }
-
- ///
- /// fdidtNEW_FOLDER
- ///
- public class DUMMYUNIONNAMEfolder
- {
- ///
- /// RESERVE section from CFFOLDER
- ///
- public object pFolderReserve;
-
- ///
- /// Size of pFolderReserve
- ///
- public ushort cbFolderReserve;
-
- ///
- /// Folder number in cabinet (0 based)
- ///
- public ushort iFolder;
- }
-
- ///
- /// fdidtDECRYPT
- ///
- public class DUMMYUNIONNAMEdecrypt
- {
- ///
- /// RESERVE section from CFDATA
- ///
- public object pDataReserve;
-
- ///
- /// Size of pDataReserve
- ///
- public ushort cbDataReserve;
-
- ///
- /// Data buffer
- ///
- public object pbData;
-
- ///
- /// Size of data buffer
- ///
- public ushort cbData;
-
- ///
- /// TRUE if this is a split data block
- ///
- public bool fSplit;
-
- ///
- /// 0 if this is not a split block, or the first piece of a split block;
- /// Greater than 0 if this is the second piece of a split block.
- ///
- public ushort cbPartial;
- }
-
- #endregion
- }
-
- /**********************************************************************/
-
- ///
- internal class FDINOTIFICATION
- {
- public long cb;
- public char[] psz1;
- public char[] psz2;
-
- ///
- /// Points to a 256 character buffer
- ///
- public char[] psz3;
-
- ///
- /// Value for client
- ///
- public object pv;
-
- public IntPtr hf;
-
- public ushort date;
- public ushort time;
- public ushort attribs;
-
- ///
- /// Cabinet set ID
- ///
- public ushort setID;
-
- ///
- /// Cabinet number (0-based)
- ///
- public ushort iCabinet;
-
- ///
- /// Folder number (0-based)
- ///
- public ushort iFolder;
-
- public FDIERROR fdie;
- }
-
- ///
- internal enum FDINOTIFICATIONTYPE
- {
- ///
- /// General information about cabinet
- ///
- fdintCABINET_INFO,
-
- ///
- /// First file in cabinet is continuation
- ///
- fdintPARTIAL_FILE,
-
- ///
- /// File to be copied
- ///
- fdintCOPY_FILE,
-
- ///
- /// Close the file, set relevant info
- ///
- fdintCLOSE_FILE_INFO,
-
- ///
- /// File continued to next cabinet
- ///
- fdintNEXT_CABINET,
-
- ///
- /// Enumeration status
- ///
- fdintENUMERATE,
- }
-
- ///
- internal class FDINOTIFY
- {
- public FDINOTIFICATIONTYPE fdint;
-
- public FDINOTIFICATION pfdin;
- }
-
- ///
- internal class FDISPILLFILE
- {
- ///
- /// Set to { '*', '\0' }
- ///
- public char[] ach = new char[2];
-
- ///
- /// Required spill file size
- ///
- public long cbFile;
- }
-
- #endregion
-
- ///
- #region cabinet.h
-
- ///
- internal static class CabinetConstants
- {
- public const int CAB_SPLITMAX = (10);
-
- public const int CAB_SEARCH_SIZE = (32 * 1024);
-
- /* 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);
- public const byte cffile_A_RDONLY = (0x01);
- public const byte cffile_A_HIDDEN = (0x02);
- public const byte cffile_A_SYSTEM = (0x04);
- public const byte cffile_A_ARCH = (0x20);
- public const byte cffile_A_EXEC = (0x40);
- public const byte cffile_A_NAME_IS_UTF = (0x80);
-
- /****************************************************************************/
- /* our archiver information / state */
-
- /* MSZIP stuff */
-
- ///
- /// window size
- ///
- public const ushort ZIPWSIZE = 0x8000;
-
- ///
- /// bits in base literal/length lookup table
- ///
- public const int ZIPLBITS = 9;
-
- ///
- /// bits in base distance lookup table
- ///
- public const int ZIPDBITS = 6;
-
- ///
- /// maximum bit length of any code
- ///
- public const int ZIPBMAX = 16;
-
- ///
- /// maximum number of codes in any set
- ///
- public const int ZIPN_MAX = 288;
-
- /* LZX stuff */
-
- /* some constants defined by the LZX specification */
- public const int LZX_MIN_MATCH = (2);
- public const int LZX_MAX_MATCH = (257);
- public const int LZX_NUM_CHARS = (256);
-
- ///
- /// also blocktypes 4-7 invalid
- ///
- public const int LZX_BLOCKTYPE_INVALID = (0);
- public const int LZX_BLOCKTYPE_VERBATIM = (1);
- public const int LZX_BLOCKTYPE_ALIGNED = (2);
- public const int LZX_BLOCKTYPE_UNCOMPRESSED = (3);
- public const int LZX_PRETREE_NUM_ELEMENTS = (20);
-
- ///
- /// aligned offset tree #elements
- ///
- public const int LZX_ALIGNED_NUM_ELEMENTS = (8);
-
- ///
- /// this one missing from spec!
- ///
- public const int LZX_NUM_PRIMARY_LENGTHS = (7);
-
- ///
- /// length tree #elements
- ///
- public const int LZX_NUM_SECONDARY_LENGTHS = (249);
-
- /* LZX huffman defines: tweak tablebits as desired */
- public const int LZX_PRETREE_MAXSYMBOLS = (LZX_PRETREE_NUM_ELEMENTS);
- public const int LZX_PRETREE_TABLEBITS = (6);
- public const int LZX_MAINTREE_MAXSYMBOLS = (LZX_NUM_CHARS + 50 * 8);
- public const int LZX_MAINTREE_TABLEBITS = (12);
- public const int LZX_LENGTH_MAXSYMBOLS = (LZX_NUM_SECONDARY_LENGTHS + 1);
- public const int LZX_LENGTH_TABLEBITS = (12);
- public const int LZX_ALIGNED_MAXSYMBOLS = (LZX_ALIGNED_NUM_ELEMENTS);
- public const int LZX_ALIGNED_TABLEBITS = (7);
-
- public const int LZX_LENTABLE_SAFETY = (64); /* we allow length table decoding overruns */
-
- /* 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.
- */
- public const int CAB_BLOCKMAX = (32768);
- public const int CAB_INPUTMAX = (CAB_BLOCKMAX + 6144);
-
- /****************************************************************************/
- /* Tables for deflate from PKZIP's appnote.txt. */
-
- //#define THOSE_ZIP_CONSTS
-
- /* Order of the bit length code lengths */
- public static readonly byte[] Zipborder =
- { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-
- /* Copy lengths for literal codes 257..285 */
- public static readonly ushort[] Zipcplens =
- { 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51,
- 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
-
- /* Extra bits for literal codes 257..285 */
- public static readonly ushort[] Zipcplext =
- { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,
- 4, 5, 5, 5, 5, 0, 99, 99}; /* 99==invalid */
-
- /* Copy offsets for distance codes 0..29 */
- public static readonly ushort[] Zipcpdist =
- { 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385,
- 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577};
-
- /* Extra bits for distance codes */
- public static readonly ushort[] Zipcpdext =
- { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10,
- 10, 11, 11, 12, 12, 13, 13};
-
- /* And'ing with Zipmask[n] masks the lower n bits */
- public static readonly ushort[] Zipmask = new ushort[17]
- { 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
- 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff };
-
- /* SESSION Operation */
- public const uint EXTRACT_FILLFILELIST = 0x00000001;
- public const uint EXTRACT_EXTRACTFILES = 0x00000002;
- }
-
- /* MSZIP stuff */
-
- ///
- internal class Ziphuft
- {
- ///
- /// number of extra bits or operation
- ///
- public byte e;
-
- ///
- /// number of bits in this code or subcode
- ///
- public byte b;
-
- #region v
-
- ///
- /// literal, length base, or distance base
- ///
- public ushort n;
-
- ///
- /// pointer to next level of table
- ///
- public Ziphuft t;
-
- #endregion
- }
-
- ///
- internal class ZIPstate
- {
- ///
- /// current offset within the window
- ///
- public uint window_posn;
-
- ///
- /// bit buffer
- ///
- public uint bb;
-
- ///
- /// bits in bit buffer
- ///
- public uint bk;
-
- ///
- /// literal/length and distance code lengths
- ///
- public uint[] ll = new uint[288 + 32];
-
- ///
- /// bit length count table
- ///
- public uint[] c = new uint[ZIPBMAX + 1];
-
- ///
- /// memory for l[-1..ZIPBMAX-1]
- ///
- public uint[] lx = new uint[ZIPBMAX + 1];
-
- ///
- /// table stack
- ///
- public Ziphuft[] u = new Ziphuft[ZIPBMAX];
-
- ///
- /// values in order of bit length
- ///
- public uint[] v = new uint[ZIPN_MAX];
-
- ///
- /// bit offsets, then code stack
- ///
- public uint[] x = new uint[ZIPBMAX + 1];
-
- public int inpos; // byte*
- }
-
- /* Quantum stuff */
-
- ///
- internal class QTMmodelsym
- {
- public ushort sym;
-
- public ushort cumfreq;
- }
-
- ///
- internal class QTMmodel
- {
- public int shiftsleft;
-
- public int entries;
-
- public QTMmodelsym[] syms;
-
- public ushort[] tabloc = new ushort[256];
- }
-
- ///
- internal class QTMstate
- {
- ///
- /// the actual decoding window
- ///
- public byte[] window;
-
- ///
- /// window size (1Kb through 2Mb)
- ///
- public uint window_size;
-
- ///
- /// window size when it was first allocated
- ///
- public uint actual_size;
-
- ///
- /// current offset within the window
- ///
- public uint window_posn;
-
- public QTMmodel model7;
- public QTMmodelsym[] m7sym = new QTMmodelsym[7 + 1];
-
- public QTMmodel model4;
- public QTMmodel model5;
- public QTMmodel model6pos;
- public QTMmodel model6len;
- public QTMmodelsym[] m4sym = new QTMmodelsym[0x18 + 1];
- public QTMmodelsym[] m5sym = new QTMmodelsym[0x24 + 1];
- public QTMmodelsym[] m6psym = new QTMmodelsym[0x2a + 1];
- public QTMmodelsym[] m6lsym = new QTMmodelsym[0x1b + 1];
-
- public QTMmodel model00;
- public QTMmodel model40;
- public QTMmodel model80;
- public QTMmodel modelC0;
- public QTMmodelsym[] m00sym = new QTMmodelsym[0x40 + 1];
- public QTMmodelsym[] m40sym = new QTMmodelsym[0x40 + 1];
- public QTMmodelsym[] m80sym = new QTMmodelsym[0x40 + 1];
- public QTMmodelsym[] mC0sym = new QTMmodelsym[0x40 + 1];
- }
-
- /* LZX stuff */
-
- ///
- internal class LZXstate
- {
- ///
- /// the actual decoding window
- ///
- public byte[] window;
-
- ///
- /// window size (32Kb through 2Mb)
- ///
- public uint window_size;
-
- ///
- /// window size when it was first allocated
- ///
- public uint actual_size;
-
- ///
- /// current offset within the window
- ///
- public uint window_posn;
-
- ///
- /// for the LRU offset system
- ///
- public uint R0, R1, R2;
-
- ///
- /// number of main tree elements
- ///
- public ushort main_elements;
-
- ///
- /// have we started decoding at all yet?
- ///
- public int header_read;
-
- ///
- /// type of this block
- ///
- public ushort block_type;
-
- ///
- /// uncompressed length of this block
- ///
- public uint block_length;
-
- ///
- /// uncompressed bytes still left to decode
- ///
- public uint block_remaining;
-
- ///
- /// the number of CFDATA blocks processed
- ///
- public uint frames_read;
-
- ///
- /// magic header value used for transform
- ///
- public int intel_filesize;
-
- ///
- /// current offset in transform space
- ///
- public int intel_curpos;
-
- ///
- /// have we seen any translatable data yet?
- ///
- public int intel_started;
-
- public ushort[] tblPRETREE_table = new ushort[(1 << LZX_PRETREE_TABLEBITS) + (LZX_PRETREE_MAXSYMBOLS << 1)];
- public ushort[] tblMAINTREE_table = new ushort[(1 << LZX_MAINTREE_TABLEBITS) + (LZX_MAINTREE_MAXSYMBOLS << 1)];
- public ushort[] tblLENGTH_table = new ushort[(1 << LZX_LENGTH_TABLEBITS) + (LZX_LENGTH_MAXSYMBOLS << 1)];
- public ushort[] tblALIGNED_table = new ushort[(1 << LZX_ALIGNED_TABLEBITS) + (LZX_ALIGNED_MAXSYMBOLS << 1)];
- }
-
- ///
- internal class lzx_bits
- {
- public uint bb;
-
- public int bl;
-
- public byte[] ip; // byte*
- }
-
- /****************************************************************************/
-
- ///
- internal class cab_file
- {
- ///
- /// next file in sequence
- ///
- public cab_file next;
-
- ///
- /// folder that contains this file
- ///
- public cab_folder folder;
-
- ///
- /// output name of file
- ///
- public string filename;
-
- ///
- /// open file handle or NULL
- ///
- public Stream fh;
-
- ///
- /// uncompressed length of file
- ///
- public uint length;
-
- ///
- /// uncompressed offset in folder
- ///
- public uint offset;
-
- ///
- /// magic index number of folder
- ///
- public ushort index;
-
- ///
- /// MS-DOS time/date/attributes
- ///
- public ushort time, date, attribs;
- }
-
- ///
- internal class cab_folder
- {
- ///
- /// next folder in sequence
- ///
- public cab_folder next;
-
- ///
- /// cabinet(s) this folder spans
- ///
- public cabinet[] cab = new cabinet[CAB_SPLITMAX];
-
- ///
- /// offset to data blocks
- ///
- public uint[] offset = new uint[CAB_SPLITMAX];
-
- ///
- /// compression format/window size
- ///
- public ushort comp_type;
-
- ///
- /// compressed size of folder
- ///
- public uint comp_size;
-
- ///
- /// number of split blocks + 1
- ///
- public byte num_splits;
-
- ///
- /// total number of blocks
- ///
- public ushort num_blocks;
-
- ///
- /// the first split file
- ///
- public cab_file contfile;
- }
-
- ///
- internal class cabinet
- {
- ///
- /// next cabinet in sequence
- ///
- public cabinet next;
-
- ///
- /// input name of cabinet
- ///
- public string filename;
-
- ///
- /// open file handle or NULL
- ///
- public Stream fh;
-
- ///
- /// length of cabinet file
- ///
- public uint filelen;
-
- ///
- /// offset to data blocks in file
- ///
- public uint blocks_off;
-
- ///
- /// multipart cabinet chains
- ///
- public cabinet prevcab, nextcab;
-
- ///
- /// and their filenames
- ///
- public string prevname, nextname;
-
- ///
- /// and their visible names
- ///
- public string previnfo, nextinfo;
-
- ///
- /// first folder in this cabinet
- ///
- public cab_folder folders;
-
- ///
- /// first file in this cabinet
- ///
- public cab_file files;
-
- ///
- /// reserved space in datablocks
- ///
- public byte block_resv;
-
- ///
- /// header flags
- ///
- public byte flags;
- }
-
- ///
- internal class cds_forward
- {
- ///
- /// current folder we're extracting from
- ///
- public cab_folder current;
-
- ///
- /// uncompressed offset within folder
- ///
- public uint offset;
-
- ///
- /// (high level) start of data to use up
- ///
- public byte outpos; // byte*
-
- ///
- /// (high level) amount of data to use up
- ///
- public ushort outlen;
-
- ///
- /// at which split in current folder?
- ///
- public ushort split;
-
- ///
- /// chosen compress fn
- ///
- public Func decompress;
-
- ///
- /// +2 for lzx bitbuffer overflows!
- ///
- public byte[] inbuf = new byte[CAB_INPUTMAX + 2];
-
- public byte[] outbuf = new byte[CAB_INPUTMAX];
-
- public byte[] q_length_base = new byte[27], q_length_extra = new byte[27], q_extra_bits = new byte[42];
-
- public uint[] q_position_base = new uint[42];
-
- public uint[] lzx_position_base = new uint[51];
-
- public uint[] extra_bits = new uint[51];
-
- #region methods
-
- public ZIPstate zip;
- public QTMstate qtm;
- public LZXstate lzx;
-
- #endregion
- }
-
- /*
- * the rest of these are somewhat kludgy macros which are shared between fdi.c
- * and cabextract.c.
- */
-
- /* Bitstream reading macros (Quantum / normal byte order)
- *
- * Q_INIT_BITSTREAM should be used first to set up the system
- * Q_READ_BITS(var,n) takes N bits from the buffer and puts them in var.
- * unlike LZX, this can loop several times to get the
- * requisite number of bits.
- * Q_FILL_BUFFER adds more data to the bit buffer, if there is room
- * for another 16 bits.
- * Q_PEEK_BITS(n) extracts (without removing) N bits from the bit
- * buffer
- * Q_REMOVE_BITS(n) removes N bits from the bit buffer
- *
- * These bit access routines work by using the area beyond the MSB and the
- * LSB as a free source of zeroes. This avoids having to mask any bits.
- * So we have to know the bit width of the bitbuffer variable. This is
- * defined as ULONG_BITS.
- *
- * ULONG_BITS should be at least 16 bits. Unlike LZX's Huffman decoding,
- * Quantum's arithmetic decoding only needs 1 bit at a time, it doesn't
- * need an assured number. Retrieving larger bitstrings can be done with
- * multiple reads and fills of the bitbuffer. The code should work fine
- * for machines where ULONG >= 32 bits.
- *
- * Also note that Quantum reads bytes in normal order; LZX is in
- * little-endian order.
- */
-
- // #define Q_INIT_BITSTREAM do { bitsleft = 0; bitbuf = 0; } while (0)
-
- // #define Q_FILL_BUFFER do { \
- // if (bitsleft <= (CAB_ULONG_BITS - 16)) { \
- // bitbuf |= ((inpos[0]<<8)|inpos[1]) << (CAB_ULONG_BITS-16 - bitsleft); \
- // bitsleft += 16; inpos += 2; \
- // } \
- // } while (0)
-
- // #define Q_PEEK_BITS(n) (bitbuf >> (CAB_ULONG_BITS - (n)))
- // #define Q_REMOVE_BITS(n) ((bitbuf <<= (n)), (bitsleft -= (n)))
-
- // #define Q_READ_BITS(v,n) do { \
- // (v) = 0; \
- // for (bitsneed = (n); bitsneed; bitsneed -= bitrun) { \
- // Q_FILL_BUFFER; \
- // bitrun = (bitsneed > bitsleft) ? bitsleft : bitsneed; \
- // (v) = ((v) << bitrun) | Q_PEEK_BITS(bitrun); \
- // Q_REMOVE_BITS(bitrun); \
- // } \
- // } while (0)
-
- // #define Q_MENTRIES(model) (QTM(model).entries)
- // #define Q_MSYM(model,symidx) (QTM(model).syms[(symidx)].sym)
- // #define Q_MSYMFREQ(model,symidx) (QTM(model).syms[(symidx)].cumfreq)
-
- /* GET_SYMBOL(model, var) fetches the next symbol from the stated model
- * and puts it in var. it may need to read the bitstream to do this.
- */
- // #define GET_SYMBOL(m, var) do { \
- // range = ((H - L) & 0xFFFF) + 1; \
- // symf = ((((C - L + 1) * Q_MSYMFREQ(m,0)) - 1) / range) & 0xFFFF; \
- // \
- // for (i=1; i < Q_MENTRIES(m); i++) { \
- // if (Q_MSYMFREQ(m,i) <= symf) break; \
- // } \
- // (var) = Q_MSYM(m,i-1); \
- // \
- // range = (H - L) + 1; \
- // H = L + ((Q_MSYMFREQ(m,i-1) * range) / Q_MSYMFREQ(m,0)) - 1; \
- // L = L + ((Q_MSYMFREQ(m,i) * range) / Q_MSYMFREQ(m,0)); \
- // while (1) { \
- // if ((L & 0x8000) != (H & 0x8000)) { \
- // if ((L & 0x4000) && !(H & 0x4000)) { \
- // /* underflow case */ \
- // C ^= 0x4000; L &= 0x3FFF; H |= 0x4000; \
- // } \
- // else break; \
- // } \
- // L <<= 1; H = (H << 1) | 1; \
- // Q_FILL_BUFFER; \
- // C = (C << 1) | Q_PEEK_BITS(1); \
- // Q_REMOVE_BITS(1); \
- // } \
- // \
- // QTMupdatemodel(&(QTM(m)), i); \
- // } while (0)
-
- /* Bitstream reading macros (LZX / intel little-endian byte order)
- *
- * INIT_BITSTREAM should be used first to set up the system
- * READ_BITS(var,n) takes N bits from the buffer and puts them in var
- *
- * ENSURE_BITS(n) ensures there are at least N bits in the bit buffer.
- * it can guarantee up to 17 bits (i.e. it can read in
- * 16 new bits when there is down to 1 bit in the buffer,
- * and it can read 32 bits when there are 0 bits in the
- * buffer).
- * PEEK_BITS(n) extracts (without removing) N bits from the bit buffer
- * REMOVE_BITS(n) removes N bits from the bit buffer
- *
- * These bit access routines work by using the area beyond the MSB and the
- * LSB as a free source of zeroes. This avoids having to mask any bits.
- * So we have to know the bit width of the bitbuffer variable.
- */
-
- // #define INIT_BITSTREAM do { bitsleft = 0; bitbuf = 0; } while (0)
-
- /* Quantum reads bytes in normal order; LZX is little-endian order */
- // #define ENSURE_BITS(n) \
- // while (bitsleft < (n)) { \
- // bitbuf |= ((inpos[1]<<8)|inpos[0]) << (CAB_ULONG_BITS-16 - bitsleft); \
- // bitsleft += 16; inpos+=2; \
- // }
-
- // #define PEEK_BITS(n) (bitbuf >> (CAB_ULONG_BITS - (n)))
- // #define REMOVE_BITS(n) ((bitbuf <<= (n)), (bitsleft -= (n)))
-
- // #define READ_BITS(v,n) do { \
- // if (n) { \
- // ENSURE_BITS(n); \
- // (v) = PEEK_BITS(n); \
- // REMOVE_BITS(n); \
- // } \
- // else { \
- // (v) = 0; \
- // } \
- // } while (0)
-
- /* Huffman macros */
-
- // #define TABLEBITS(tbl) (LZX_##tbl##_TABLEBITS)
- // #define MAXSYMBOLS(tbl) (LZX_##tbl##_MAXSYMBOLS)
- // #define SYMTABLE(tbl) (LZX(tbl##_table))
- // #define LENTABLE(tbl) (LZX(tbl##_len))
-
- /* BUILD_TABLE(tablename) builds a huffman lookup table from code lengths.
- * In reality, it just calls make_decode_table() with the appropriate
- * values - they're all fixed by some #defines anyway, so there's no point
- * writing each call out in full by hand.
- */
- // #define BUILD_TABLE(tbl) \
- // if (make_decode_table( \
- // MAXSYMBOLS(tbl), TABLEBITS(tbl), LENTABLE(tbl), SYMTABLE(tbl) \
- // )) { return DECR_ILLEGALDATA; }
-
- /* READ_HUFFSYM(tablename, var) decodes one huffman symbol from the
- * bitstream using the stated table and puts it in var.
- */
- // #define READ_HUFFSYM(tbl,var) do { \
- // ENSURE_BITS(16); \
- // hufftbl = SYMTABLE(tbl); \
- // if ((i = hufftbl[PEEK_BITS(TABLEBITS(tbl))]) >= MAXSYMBOLS(tbl)) { \
- // j = 1 << (CAB_ULONG_BITS - TABLEBITS(tbl)); \
- // do { \
- // j >>= 1; i <<= 1; i |= (bitbuf & j) ? 1 : 0; \
- // if (!j) { return DECR_ILLEGALDATA; } \
- // } while ((i = hufftbl[i]) >= MAXSYMBOLS(tbl)); \
- // } \
- // j = LENTABLE(tbl)[(var) = i]; \
- // REMOVE_BITS(j); \
- // } while (0)
-
- /* READ_LENGTHS(tablename, first, last) reads in code lengths for symbols
- * first to last in the given table. The code lengths are stored in their
- * own special LZX way.
- */
- // #define READ_LENGTHS(tbl,first,last,fn) do { \
- // lb.bb = bitbuf; lb.bl = bitsleft; lb.ip = inpos; \
- // if (fn(LENTABLE(tbl),(first),(last),&lb,decomp_state)) { \
- // return DECR_ILLEGALDATA; \
- // } \
- // bitbuf = lb.bb; bitsleft = lb.bl; inpos = lb.ip; \
- // } while (0)
-
- ///
- internal class FILELIST
- {
- public string FileName;
-
- public FILELIST next;
-
- public bool DoExtract;
- }
-
- ///
- internal class SESSION
- {
- public int FileSize;
-
- public ERF Error;
-
- public FILELIST FileList;
-
- public int FileCount;
-
- public int Operation;
-
- public char[] Destination = new char[CB_MAX_CAB_PATH];
-
- public char[] CurrentFile = new char[CB_MAX_CAB_PATH];
-
- public char[] Reserved = new char[CB_MAX_CAB_PATH];
-
- public FILELIST FilterList;
- }
-
- #endregion
-}
\ No newline at end of file
+// using System;
+// using System.Collections.Generic;
+// using System.IO;
+// using System.Linq;
+// using static BurnOutSharp.Wrappers.CabinetConstants;
+// using static BurnOutSharp.Wrappers.FDIcConstants;
+// using static BurnOutSharp.Wrappers.FDIConstants;
+
+// namespace BurnOutSharp.Wrappers
+// {
+// public partial class MicrosoftCabinet
+// {
+// // TEMP AREA TO MAKE BUILDS WORK
+
+// private static void SetLastError(int error) { }
+// private class HFDI : FDI_Int { }
+// private const int ERROR_INVALID_HANDLE = 0;
+// private const int FDIERROR_NONE = 0;
+// private const int ERROR_BAD_ARGUMENTS = 0;
+// private const int FDIERROR_ALLOC_FAIL = 0;
+// private static void TRACE(object o) { }
+// private static void ERR(object o) { }
+
+// // END TEMP AREA
+
+// static void set_error(FDI_Int fdi, int oper, int err)
+// {
+// fdi.perf.erfOper = oper;
+// fdi.perf.erfType = err;
+// fdi.perf.fError = true;
+// if (err != 0) SetLastError(err);
+// }
+
+// static FDI_Int get_fdi_ptr(HFDI hfdi)
+// {
+// FDI_Int fdi = hfdi as FDI_Int;
+
+// if (fdi == null || fdi.magic != FDI_INT_MAGIC)
+// {
+// SetLastError(ERROR_INVALID_HANDLE);
+// return null;
+// }
+// return fdi;
+// }
+
+// /****************************************************************
+// * QTMupdatemodel (internal)
+// */
+// static void QTMupdatemodel(QTMmodel model, int sym)
+// {
+// QTMmodelsym temp;
+// int i, j;
+
+// for (i = 0; i < sym; i++) model.syms[i].cumfreq += 8;
+
+// if (model.syms[0].cumfreq > 3800)
+// {
+// if (--model.shiftsleft != 0)
+// {
+// for (i = model.entries - 1; i >= 0; i--)
+// {
+// /* -1, not -2; the 0 entry saves this */
+// model.syms[i].cumfreq >>= 1;
+// if (model.syms[i].cumfreq <= model.syms[i + 1].cumfreq)
+// {
+// model.syms[i].cumfreq = (ushort)(model.syms[i + 1].cumfreq + 1);
+// }
+// }
+// }
+// else
+// {
+// model.shiftsleft = 50;
+// for (i = 0; i < model.entries; i++)
+// {
+// /* no -1, want to include the 0 entry */
+// /* this converts cumfreqs into frequencies, then shifts right */
+// model.syms[i].cumfreq -= model.syms[i + 1].cumfreq;
+// model.syms[i].cumfreq++; /* avoid losing things entirely */
+// model.syms[i].cumfreq >>= 1;
+// }
+
+// /* now sort by frequencies, decreasing order -- this must be an
+// * inplace selection sort, or a sort with the same (in)stability
+// * characteristics
+// */
+// for (i = 0; i < model.entries - 1; i++)
+// {
+// for (j = i + 1; j < model.entries; j++)
+// {
+// if (model.syms[i].cumfreq < model.syms[j].cumfreq)
+// {
+// temp = model.syms[i];
+// model.syms[i] = model.syms[j];
+// model.syms[j] = temp;
+// }
+// }
+// }
+
+// /* then convert frequencies back to cumfreq */
+// for (i = model.entries - 1; i >= 0; i--)
+// {
+// model.syms[i].cumfreq += model.syms[i + 1].cumfreq;
+// }
+// /* then update the other part of the table */
+// for (i = 0; i < model.entries; i++)
+// {
+// model.tabloc[model.syms[i].sym] = (ushort)i;
+// }
+// }
+// }
+// }
+
+// /*************************************************************************
+// * make_decode_table (internal)
+// *
+// * This function was coded by David Tritscher. It builds a fast huffman
+// * decoding table out of just a canonical huffman code lengths table.
+// *
+// * PARAMS
+// * nsyms: total number of symbols in this huffman tree.
+// * nbits: any symbols with a code length of nbits or less can be decoded
+// * in one lookup of the table.
+// * length: A table to get code lengths from [0 to syms-1]
+// * table: The table to fill up with decoded symbols and pointers.
+// *
+// * RETURNS
+// * OK: 0
+// * error: 1
+// */
+// static int make_decode_table(uint nsyms, uint nbits, byte[] length, ushort[] table)
+// {
+// ushort sym;
+// uint leaf;
+// byte bit_num = 1;
+// uint fill;
+// uint pos = 0; /* the current position in the decode table */
+// uint table_mask = (uint)(1 << (int)nbits);
+// uint bit_mask = table_mask >> 1; /* don't do 0 length codes */
+// uint next_symbol = bit_mask; /* base of allocation for long codes */
+
+// /* fill entries for codes short enough for a direct mapping */
+// while (bit_num <= nbits)
+// {
+// for (sym = 0; sym < nsyms; sym++)
+// {
+// if (length[sym] == bit_num)
+// {
+// leaf = pos;
+
+// if ((pos += bit_mask) > table_mask) return 1; /* table overrun */
+
+// /* fill all possible lookups of this symbol with the symbol itself */
+// fill = bit_mask;
+// while (fill-- > 0) table[leaf++] = sym;
+// }
+// }
+// bit_mask >>= 1;
+// bit_num++;
+// }
+
+// /* if there are any codes longer than nbits */
+// if (pos != table_mask)
+// {
+// /* clear the remainder of the table */
+// for (sym = (ushort)pos; sym < table_mask; sym++) table[sym] = 0;
+
+// /* give ourselves room for codes to grow by up to 16 more bits */
+// pos <<= 16;
+// table_mask <<= 16;
+// bit_mask = 1 << 15;
+
+// while (bit_num <= 16)
+// {
+// for (sym = 0; sym < nsyms; sym++)
+// {
+// if (length[sym] == bit_num)
+// {
+// leaf = pos >> 16;
+// for (fill = 0; fill < bit_num - nbits; fill++)
+// {
+// /* if this path hasn't been taken yet, 'allocate' two entries */
+// if (table[leaf] == 0)
+// {
+// table[(next_symbol << 1)] = 0;
+// table[(next_symbol << 1) + 1] = 0;
+// table[leaf] = (ushort)next_symbol++;
+// }
+// /* follow the path and select either left or right for next bit */
+// leaf = (uint)(table[leaf] << 1);
+// if (((pos >> (int)(15 - fill)) & 1) != 0) leaf++;
+// }
+// table[leaf] = sym;
+
+// if ((pos += bit_mask) > table_mask) return 1; /* table overflow */
+// }
+// }
+// bit_mask >>= 1;
+// bit_num++;
+// }
+// }
+
+// /* full table? */
+// if (pos == table_mask) return 0;
+
+// /* either erroneous table, or all elements are 0 - let's find out. */
+// for (sym = 0; sym < nsyms; sym++) if (length[sym] != 0) return 1;
+// return 0;
+// }
+
+// /*************************************************************************
+// * checksum (internal)
+// */
+// static uint checksum(byte[] data, ushort bytes, uint csum)
+// {
+// int dataPtr = 0; // TODO: Confirm that it's always starting at the beginning of data
+
+// int len;
+// uint ul = 0;
+
+// for (len = bytes >> 2; len-- > 0; dataPtr += 4)
+// {
+// csum ^= (uint)((data[dataPtr + 0]) | (data[dataPtr + 1] << 8) | (data[dataPtr + 2] << 16) | (data[dataPtr + 3] << 24));
+// }
+
+// switch (bytes & 3)
+// {
+// case 3: ul |= (uint)(data[dataPtr++] << 16); goto case 2;
+// /* fall through */
+// case 2: ul |= (uint)(data[dataPtr++] << 8); goto case 1;
+// /* fall through */
+// case 1: ul |= data[dataPtr]; break;
+// }
+// csum ^= ul;
+
+// return csum;
+// }
+
+// /***********************************************************************
+// * FDICreate (CABINET.20)
+// *
+// * Provided with several callbacks (all of them are mandatory),
+// * returns a handle which can be used to perform operations
+// * on cabinet files.
+// *
+// * PARAMS
+// * pfnalloc [I] A pointer to a function which allocates ram. Uses
+// * the same interface as malloc.
+// * pfnfree [I] A pointer to a function which frees ram. Uses the
+// * same interface as free.
+// * pfnopen [I] A pointer to a function which opens a file. Uses
+// * the same interface as _open.
+// * pfnread [I] A pointer to a function which reads from a file into
+// * a caller-provided buffer. Uses the same interface
+// * as _read
+// * pfnwrite [I] A pointer to a function which writes to a file from
+// * a caller-provided buffer. Uses the same interface
+// * as _write.
+// * pfnclose [I] A pointer to a function which closes a file handle.
+// * Uses the same interface as _close.
+// * pfnseek [I] A pointer to a function which seeks in a file.
+// * Uses the same interface as _lseek.
+// * cpuType [I] The type of CPU; ignored in wine (recommended value:
+// * cpuUNKNOWN, aka -1).
+// * perf [IO] A pointer to an ERF structure. When FDICreate
+// * returns an error condition, error information may
+// * be found here as well as from GetLastError.
+// *
+// * RETURNS
+// * On success, returns an FDI handle of type HFDI.
+// * On failure, the null file handle is returned. Error
+// * info can be retrieved from perf.
+// *
+// * INCLUDES
+// * fdi.h
+// *
+// */
+// HFDI FDICreate(
+// Action pfnalloc,
+// Action