using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
namespace Vanara.PInvoke
{
/// Items from the cabinet.dll
public static partial class Cabinet
{
///
public const int CB_MAX_CAB_PATH = 256;
///
public const int CB_MAX_CABINET_NAME = 256;
///
public const int CB_MAX_CHUNK = 32768;
///
public const int CB_MAX_DISK = 0x7fffffff;
///
public const int CB_MAX_DISK_NAME = 256;
///
public const int CB_MAX_FILENAME = 256;
///
[PInvokeData("fci.h")]
public const int tcompSHIFT_LZX_WINDOW = 8;
///
[PInvokeData("fci.h")]
public const int tcompSHIFT_QUANTUM_LEVEL = 4;
///
[PInvokeData("fci.h")]
public const int tcompSHIFT_QUANTUM_MEM = 8;
///
/// The FNFCIALLOC provides the declaration for the application-defined callback function to allocate memory within an FCI context.
///
/// Bytes to be allocated from the stack.
/// pointer to the allocated space
///
/// The function accepts parameters similar to malloc.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/fci/nf-fci-fnfcialloc
[PInvokeData("fci.h", MSDNShortId = "339ac9d2-60bc-4a90-8a46-6fbb073be9d1")]
[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public delegate IntPtr PFNALLOC(uint cb);
///
/// The FNFCICLOSE macro provides the declaration for the application-defined callback function to close a file in an FCI context.
///
/// The file handle.
/// The error.
/// An application-defined value.
/// Returns 0 if the file was successfully closed. A return value of –1 indicates an error.
/// The function accepts parameters similar to _close, with the addition of err and pv.
// https://docs.microsoft.com/en-us/windows/desktop/api/fci/nf-fci-fnfciclose
[PInvokeData("fci.h", MSDNShortId = "c4edf6ca-0b16-4e30-933b-934f8930c6d6")]
[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public delegate int PFNFCICLOSE(IntPtr hf, out int err, IntPtr pv);
///
/// The FNFCIDELETE macro provides the declaration for the application-defined callback function to delete a file in the FCI context.
///
/// The name of the file to be deleted.
/// The error.
/// An application-defined value.
/// Returns 0 if the file was successfully deleted. A return value of –1 indicates an error.
/// The function accepts parameters similar to remove, with the addition of err and pv.
// https://docs.microsoft.com/en-us/windows/desktop/api/fci/nf-fci-fnfcidelete
[PInvokeData("fci.h", MSDNShortId = "5c85ad86-2794-4f7c-8c10-18fea3519b11")]
[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public delegate int PFNFCIDELETE(string pszFile, out int err, IntPtr pv);
///
/// The FNFCIFILEPLACED macro provides the declaration for the application-defined callback function to notify when a file is
/// placed in the cabinet.
///
/// Pointer to the CCAB structure containing the parameters of the cabinet on which the file has been stored.
/// The name of the file to be replaced.
/// The length of the file.
/// true if this is a later segment of a continued file
/// An application-defined value.
/// Returns 0 if the file was successfully replaced. A return value of –1 indicates an error.
// https://docs.microsoft.com/en-us/windows/desktop/api/fci/nf-fci-fnfcifileplaced
[PInvokeData("fci.h", MSDNShortId = "f8a1bcfc-8a13-49cf-a3e7-caec6c6421b0")]
[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public delegate int PFNFCIFILEPLACED(ref CCAB pccab, string pszFile, int cbFile, [MarshalAs(UnmanagedType.Bool)] bool fContinuation, IntPtr pv);
///
/// The FNFCIGETNEXTCABINET macro provides the declaration for the application-defined callback function to request
/// information for the next cabinet.
///
/// Points to copy of old ccab structure to modify.
/// Estimate of size of previous cabinet.
/// An application-defined value.
/// on success.
///
///
/// The CCAB structure referenced by this function is relevant to the most recently completed cabinet. However, with each successful
/// operation the iCab field contained within this structure will have incremented by 1. Additionally, the next cabinet will be
/// created using the fields in this structure. The szCab, in particular, should be modified as necessary. In particular, the szCab
/// field, which specifies the cabinet name, should be changed for each cabinet.
///
/// When creating multiple cabinets, typically the iCab field is used to create the name.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/fci/nf-fci-fnfcigetnextcabinet
[PInvokeData("fci.h", MSDNShortId = "d56fb63e-91bf-4991-a954-176211697a2e")]
[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
[return: MarshalAs(UnmanagedType.Bool)]
public delegate bool PFNFCIGETNEXTCABINET(ref CCAB pccab, uint cbPrevCab, IntPtr pv);
///
/// The FNFCIGETOPENINFO macro provides the declaration for the application-defined callback function to open a file and
/// retrieve file date, time, and attribute.
///
/// complete path to filename.
/// location to return FAT-style date code.
/// location to return FAT-style time code.
/// location to return FAT-style attributes.
/// The error.
/// An application-defined value.
/// Return value is file handle of open file to read, or INVALID_FILE_HANDLE on failure.
/// The function should open the file using the file open function compatible with those passed into FCICreate.
// https://docs.microsoft.com/en-us/windows/desktop/api/fci/nf-fci-fnfcigetopeninfo
[PInvokeData("fci.h", MSDNShortId = "5baccb69-7872-4d67-ad74-70cdd7459f8d")]
[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public delegate IntPtr PFNFCIGETOPENINFO(string pszName, ref ushort pdate, ref ushort ptime, ref ushort pattribs, out int err, IntPtr pv);
///
/// The FNFCIGETTEMPFILE macro provides the declaration for the application-defined callback function to obtain a temporary
/// file name.
///
/// Buffer to receive complete tempfile name.
/// Size of pszTempName buffer.
/// An application-defined value.
/// on success.
///
/// The function can return a filename that already exists by the time it is opened. For this reason, the caller should be prepared
/// to make several attempts to create temporary files.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/fci/nf-fci-fnfcigettempfile
[PInvokeData("fci.h", MSDNShortId = "8978f688-d8f1-437a-b298-eed1e7dac012")]
[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
[return: MarshalAs(UnmanagedType.Bool)]
public delegate bool PFNFCIGETTEMPFILE(IntPtr pszTempName, int cbTempName, IntPtr pv);
///
/// The FNFCIOPEN macro provides the declaration for the application-defined callback function to open a file in an FCI context.
///
/// File name.
/// The kind of operations allowed.
/// Permission mode.
/// The error.
/// An application-defined value.
/// Return value is file handle of open file to read, or INVALID_FILE_HANDLE on failure.
/// The function accepts parameters similar to _open.
// https://docs.microsoft.com/en-us/windows/desktop/api/fci/nf-fci-fnfciopen
[PInvokeData("fci.h", MSDNShortId = "72cf50cb-c895-4953-9c4d-f8ddaa294f2a")]
[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public delegate IntPtr PFNFCIOPEN(string pszFile, RunTimeLib.FileOpConstant oflag, RunTimeLib.FilePermissionConstant pmode, out int err, IntPtr pv);
///
/// The FNFCIREAD macro provides the declaration for the application-defined callback function to read data from a file in an
/// FCI context.
///
/// File descriptor referring to the open file.
/// Storage location for data.
/// Maximum number of bytes to read.
/// The error.
/// An application-defined value.
/// returns the number of bytes read
///
/// The function accepts parameters similar to _read with the addition to err and pv.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/fci/nf-fci-fnfciread
[PInvokeData("fci.h", MSDNShortId = "dd4e97ff-efbc-462b-b954-bc3260fa1513")]
[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public delegate uint PFNFCIREAD(IntPtr hf, [Out] IntPtr memory, uint cb, out int err, IntPtr pv);
///
/// The FNFCISEEK macro provides the declaration for the application-defined callback function to move a file pointer to the
/// specified location in an FCI context.
///
/// File descriptor referring to an open file.
/// Number of bytes from origin.
/// Initial position..
/// The error.
/// An application-defined value.
/// returns the offset, in bytes, of the new position from the beginning of the file.
///
/// The function accepts parameters similar to _lseek with the addition to err and pv.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/fci/nf-fci-fnfciseek
[PInvokeData("fci.h", MSDNShortId = "e5a14c98-4de6-452e-8993-afb7964aeee7")]
[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public delegate int PFNFCISEEK(IntPtr hf, int dist, System.IO.SeekOrigin seektype, out int err, IntPtr pv);
///
/// The FNFCISTATUS macro provides the declaration for the application-defined callback function to update the user.
///
/// The type status.
///
/// File: Size of compressed block. Folder: Amount of folder copied to cabinet so far. Cabinet: Estimated cabinet size that was
/// previously passed to fnfciGetNextCabinet().
///
/// File: Size of uncompressed block. Folder: Total size of folder. Cabinet: Actual cabinet size.
/// An application-defined value.
/// Returns -1 to signal that FCI should abort; Returns anything other than -1 on success.
///
/// If typeStatus equals statusCabinet the returned value indicates the desired size for the cabinet file. FCI updates the
/// maximum cabinet size remaining using this returned value. This allows a client to generate multiple cabinets per disk, and have
/// FCI limit the size accordingly.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/fci/nf-fci-fnfcistatus
[PInvokeData("fci.h", MSDNShortId = "529fd3c8-9783-4dbe-9268-a9137935cf9b")]
[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public delegate int PFNFCISTATUS(CabinetFileStatus typeStatus, uint cb1, uint cb2, IntPtr pv);
///
/// The FNFCIWRITE macro provides the declaration for the application-defined callback function to write data to a file in an
/// FCI context.
///
/// File descriptor of file into which data is written.
/// Data to be written.
/// Number of bytes.
/// The error.
/// An application-defined value.
/// returns the number of bytes actually written.
/// The function accepts parameters similar to _write.
// https://docs.microsoft.com/en-us/windows/desktop/api/fci/nf-fci-fnfciwrite
[PInvokeData("fci.h", MSDNShortId = "ca4c3b5b-1ed5-4f12-8317-c1e1dac5f816")]
[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public delegate uint PFNFCIWRITE(IntPtr hf, [In] IntPtr memory, uint cb, out int err, IntPtr pv);
///
/// The FNFCIFREE macro provides the declaration for the application-defined callback function to free previously allocated
/// memory in an FCI context.
///
/// The pointer to the memory to be freed.
///
/// The function accepts parameters similar to free.
/// Examples
///
// https://docs.microsoft.com/en-us/windows/desktop/api/fci/nf-fci-fnfcifree
[PInvokeData("fci.h", MSDNShortId = "48f052e2-7786-430a-b3dc-afcfdffae387")]
[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public delegate void PFNFREE(IntPtr memory);
/// Used by .
[PInvokeData("fci.h")]
public enum CabinetFileStatus
{
/// compressing a block into a folder
File,
/// adding a folder to a cabinet
Folder,
/// writing out a complete cabinet
Cabinet
}
/// An FCI/FDI error code.
[PInvokeData("fci.h")]
public enum FCIERROR
{
/// No Error.
FCIERR_NONE = 0x00,
/// Failure opening the file to be stored in the cabinet.
FCIERR_OPEN_SRC = 0x01,
/// Failure reading the file to be stored in the cabinet.
FCIERR_READ_SRC = 0x02,
/// Out of memory in FCI.
FCIERR_ALLOC_FAIL = 0x03,
/// Could not create a temporary file.
FCIERR_TEMP_FILE = 0x04,
/// Unknown compression type.
FCIERR_BAD_COMPR_TYPE = 0x05,
/// Could not create the cabinet file.
FCIERR_CAB_FILE = 0x06,
/// FCI aborted.
FCIERR_USER_ABORT = 0x07,
/// Failure compressing data.
FCIERR_MCI_FAIL = 0x08,
/// Data-size or file-count exceeded CAB format limits.
FCIERR_CAB_FORMAT_LIMIT = 0x09,
}
/// The compression type to use.
[PInvokeData("fci.h")]
[Flags]
public enum TCOMP
{
///
tcompMASK_TYPE = 0x000F,
/// No compression.
tcompTYPE_NONE = 0x0000,
/// Microsoft ZIP compression.
tcompTYPE_MSZIP = 0x0001,
///
tcompTYPE_QUANTUM = 0x0002,
///
tcompTYPE_LZX = 0x0003,
///
tcompBAD = 0x000F,
///
tcompMASK_LZX_WINDOW = 0x1F00,
///
tcompLZX_WINDOW_LO = 0x0F00,
///
tcompLZX_WINDOW_HI = 0x1500,
///
tcompMASK_QUANTUM_LEVEL = 0x00F0,
///
tcompQUANTUM_LEVEL_LO = 0x0010,
///
tcompQUANTUM_LEVEL_HI = 0x0070,
///
tcompMASK_QUANTUM_MEM = 0x1F00,
///
tcompQUANTUM_MEM_LO = 0x0A00,
///
tcompQUANTUM_MEM_HI = 0x1500,
///
tcompMASK_RESERVED = 0xE000,
}
/// The FCIAddFile adds a file to the cabinet under construction.
/// A valid FCI context handle returned by the FCICreate function.
/// The name of the file to add; this value should include path information.
/// The name under which to store the file in the cabinet.
/// If set TRUE, the file will be executed when extracted.
///
/// Pointer to an application-defined callback function to obtain specifications on the next cabinet to create. The function should
/// be declared using the FNFCIGETNEXTCABINET macro.
///
///
/// Pointer to an application-defined callback function to update the progress information available to the user. The function
/// should be declared using the FNFCISTATUS macro.
///
///
/// Pointer to an application-defined callback function to open a file and retrieve the file date, time, and attributes. The
/// function should be declared using the FNFCIGETOPENINFO macro.
///
///
/// The compression type to use.
/// Note To indicate LZX compression, use the TCOMPfromLZXWindow macro.
///
///
/// Value
/// Meaning
///
/// -
/// tcompTYPE_NONE 0x0000
/// No compression.
///
/// -
/// tcompTYPE_MSZIP 0x0001
/// Microsoft ZIP compression.
///
///
///
///
/// If the function succeeds, it returns TRUE; otherwise, FALSE.
/// Extended error information is provided in the ERF structure used to create the FCI context.
///
///
/// When set, the _A_EXEC attribute is added to the file entry in the CAB. This mechanism is used in some Microsoft self-extracting
/// executables, and could be used for this purpose in any custom extraction application.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/fci/nf-fci-fciaddfile BOOL DIAMONDAPI FCIAddFile( HFCI hfci, LPSTR
// pszSourceFile, LPSTR pszFileName, BOOL fExecute, PFNFCIGETNEXTCABINET pfnfcignc, PFNFCISTATUS pfnfcis, PFNFCIGETOPENINFO
// pfnfcigoi, TCOMP typeCompress );
[DllImport(Lib.Cabinet, SetLastError = false, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
[PInvokeData("fci.h", MSDNShortId = "f99e8718-853b-4d35-98ae-61a8333dbaba")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool FCIAddFile([In] HFCI hfci, string pszSourceFile, string pszFileName, [MarshalAs(UnmanagedType.Bool)] bool fExecute,
[In] PFNFCIGETNEXTCABINET pfnfcignc, [In] PFNFCISTATUS pfnfcis, [In] PFNFCIGETOPENINFO pfnfcigoi, TCOMP typeCompress);
/// The FCICreate function creates an FCI context.
/// Pointer to an ERF structure that receives the error information.
///
/// Pointer to an application-defined callback function to notify when a file is placed in the cabinet. The function should be
/// declared using the FNFCIFILEPLACED macro.
///
///
/// Pointer to an application-defined callback function to allocate memory. The function should be declared using the FNFCIALLOC macro.
///
///
/// Pointer to an application-defined callback function to free previously allocated memory. The function should be delcared using
/// the FNFCIFREE macro.
///
///
/// Pointer to an application-defined callback function to open a file. The function should be declared using the FNFCIOPEN macro.
///
///
/// Pointer to an application-defined callback function to read data from a file. The function should be declared using the
/// FNFCIREAD macro.
///
///
/// Pointer to an application-defined callback function to write data to a file. The function should be declared using the
/// FNFCIWRITE macro.
///
///
/// Pointer to an application-defined callback function to close a file. The function should be declared using the FNFCICLOSE macro.
///
///
/// Pointer to an application-defined callback function to move a file pointer to the specific location. The function should be
/// declared using the FNFCISEEK macro.
///
///
/// Pointer to an application-defined callback function to delete a file. The function should be declared using the FNFCIDELETE macro.
///
///
/// Pointer to an application-defined callback function to retrieve a temporary file name. The function should be declared using the
/// FNFCIGETTEMPFILE macro.
///
/// Pointer to a CCAB structure that contains the parameters for creating a cabinet.
/// Pointer to an application-defined value that is passed to callback functions.
///
/// If the function succeeds, it returns a non- NULL HFCI context pointer; otherwise, NULL.
/// Extended error information is provided in the ERF structure.
///
///
/// FCI supports multiple simultaneous contexts. As a result it is possible to create or extract multiple cabinets at the same time
/// within the same application. If the application is multithreaded, it is also possible to run a different context in each thread;
/// however, an application cannot use the same context simultaneously in multiple threads. For example, FCIAddFile cannot be called
/// from two different threads, using the same FCI context.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/fci/nf-fci-fcicreate HFCI DIAMONDAPI FCICreate( PERF perf, PFNFCIFILEPLACED
// pfnfcifp, PFNFCIALLOC pfna, PFNFCIFREE pfnf, PFNFCIOPEN pfnopen, PFNFCIREAD pfnread, PFNFCIWRITE pfnwrite, PFNFCICLOSE pfnclose,
// PFNFCISEEK pfnseek, PFNFCIDELETE pfndelete, PFNFCIGETTEMPFILE pfnfcigtf, PCCAB pccab, void *pv );
[DllImport(Lib.Cabinet, SetLastError = false, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
[PInvokeData("fci.h", MSDNShortId = "bfcea06d-2f09-405c-955c-0f56149148f2")]
public static extern SafeHFCI FCICreate(ref ERF perf, [In] PFNFCIFILEPLACED pfnfcifp, [In] PFNALLOC pfna, [In] PFNFREE pfnf,
[In] PFNFCIOPEN pfnopen, [In] PFNFCIREAD pfnread, [In] PFNFCIWRITE pfnwrite, [In] PFNFCICLOSE pfnclose, [In] PFNFCISEEK pfnseek,
[In] PFNFCIDELETE pfndelete, [In] PFNFCIGETTEMPFILE pfnfcigtf, in CCAB pccab, [In, Optional] IntPtr pv);
///
/// The FCIDestroy function deletes an open FCI context, freeing any memory and temporary files associated with the context.
///
/// A valid FCI context handle returned by the FCICreate function.
///
/// If the function succeeds, it returns TRUE; otherwise, FALSE.
/// Extended error information is provided in the ERF structure used to create the FCI context.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/fci/nf-fci-fcidestroy BOOL DIAMONDAPI FCIDestroy( HFCI hfci );
[DllImport(Lib.Cabinet, SetLastError = false, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
[PInvokeData("fci.h", MSDNShortId = "bb1a6294-664f-450f-b8ec-d6f8957d920e")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool FCIDestroy([In] HFCI hfci);
/// The FCIFlushCabinet function completes the current cabinet.
/// A valid FCI context handle returned by theFCICreate function.
/// Specifies whether the function pointed to by the supplied GetNextCab parameter will be called.
///
/// Pointer to an application-defined callback function to obtain specifications on the next cabinet to create. The function should
/// be declared using the FNFCIGETNEXTCABINET macro.
///
///
/// Pointer to an application-defined callback function to update the user. The function should be declared using the FNFCISTATUS macro.
///
///
/// If the function succeeds, it returns TRUE; otherwise, FALSE.
/// Extended error information is provided in the ERF structure used to create the FCI context.
///
///
///
/// The FCIFlushCabinet API forces the current cabinet under construction to be completed immediately and then written to
/// disk. Further calls to FCIAddFile will result in files being added to another cabinet.
///
///
/// In the event the current cabinet has reached the application-specified media size limit, the pending data within an FCI's
/// internal buffers will be placed into another cabinet.
///
///
/// The fGetNextCab flag determines whether the function pointed to by the GetNextCab parameter will be called. If fGetNextCab is
/// set TRUE, GetNextCab is called to obtain continuation information. If FALSE, then GetNextCab is called only in the
/// event the cabinet overflows.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/fci/nf-fci-fciflushcabinet BOOL DIAMONDAPI FCIFlushCabinet( HFCI hfci, BOOL
// fGetNextCab, PFNFCIGETNEXTCABINET pfnfcignc, PFNFCISTATUS pfnfcis );
[DllImport(Lib.Cabinet, SetLastError = false, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
[PInvokeData("fci.h", MSDNShortId = "dc586260-180e-4a6b-accf-2ddd62ac1335")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool FCIFlushCabinet([In] HFCI hfci, [MarshalAs(UnmanagedType.Bool)] bool fGetNextCab, [In] PFNFCIGETNEXTCABINET pfnfcignc, [In] PFNFCISTATUS pfnfcis);
/// The FCIFlushFolder function forces the current folder under construction to be completed immediately.
/// A valid FCI context handle returned by the FCICreate function.
///
/// Pointer to an application-defined callback function to obtain specifications on the next cabinet to create. The function should
/// be declared using the FNFCIGETNEXTCABINET macro.
///
///
/// Pointer to an application-defined callback function to update the user. The function should be declared using the FNFCISTATUS macro.
///
///
/// If the function succeeds, it returns TRUE; otherwise, FASLE.
/// Extended error information is provided in the ERF structure used to create the FCI context.
///
///
///
/// The FCIFlushFolder API forces the folder currently under construction to be completed immediately; effectively resetting
/// the compression history if a compression method is in use.
///
///
/// The callback function indicated by GetNextCab will be called if the cabinet overflows, which occurs if the pending data buffered
/// inside an FCI causes the application-specified cabinet media size to be exceeded.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/fci/nf-fci-fciflushfolder BOOL DIAMONDAPI FCIFlushFolder( HFCI hfci,
// PFNFCIGETNEXTCABINET pfnfcignc, PFNFCISTATUS pfnfcis );
[DllImport(Lib.Cabinet, SetLastError = false, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
[PInvokeData("fci.h", MSDNShortId = "dc9c226e-e309-48c3-9edb-3f0a040c0c18")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool FCIFlushFolder([In] HFCI hfci, [In] PFNFCIGETNEXTCABINET pfnfcignc, [In] PFNFCISTATUS pfnfcis);
/// The CCAB structure contains cabinet information.
// https://docs.microsoft.com/en-us/windows/desktop/api/fci/ns-fci-ccab typedef struct { ULONG cb; ULONG cbFolderThresh; UINT
// cbReserveCFHeader; UINT cbReserveCFFolder; UINT cbReserveCFData; int iCab; int iDisk; int fFailOnIncompressible; USHORT setID;
// char szDisk[CB_MAX_DISK_NAME]; char szCab[CB_MAX_CABINET_NAME]; char szCabPath[CB_MAX_CAB_PATH]; } CCAB;
[PInvokeData("fci.h", MSDNShortId = "e25cb72b-4c96-40e9-9fd5-2920e4a01d3a")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct CCAB
{
/// The maximum size, in bytes, of a cabinet created by FCI.
public uint cb;
/// The maximum size, in bytes, that a folder will contain before a new folder is created.
public uint cbFolderThresh;
/// The size, in bytes, of the CFHeader reserve area. Possible value range is 0-255.
public uint cbReserveCFHeader;
/// The size, in bytes, of the CFFolder reserve area. Possible value range is 0-255.
public uint cbReserveCFFolder;
/// The size, in bytes, of the CFData reserve area. Possible value range is 0-255.
public uint cbReserveCFData;
/// The number of created cabinets.
public int iCab;
/// The number of disks.
public int iDisk;
/// TRUE if fail if a block is incompressible.
[MarshalAs(UnmanagedType.Bool)]
public bool fFailOnIncompressible;
/// A value that represents the association between a collection of linked cabinet files.
public ushort setID;
/// The name of the disk on which the cabinet is placed.
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CB_MAX_DISK_NAME)]
public string szDisk;
///
/// The name of the cabinet.
///
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CB_MAX_CABINET_NAME)]
public string szCab;
///
/// The full path that indicates where to create the cabinet.
///
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CB_MAX_CAB_PATH)]
public string szCabPath;
/// Initializes a new instance of the struct.
/// The full path to the cabinet to create.
/// A value that represents the association between a collection of linked cabinet files.
/// The number of disks.
/// The maximum size, in bytes, of a cabinet created by FCI.
public CCAB(string cabFullPath, ushort setId = 1, int disk = 1, uint maxSize = CB_MAX_DISK)
{
cb = cbFolderThresh = maxSize;
setID = setId;
iDisk = disk;
cbReserveCFData = cbReserveCFFolder = cbReserveCFHeader = 0;
iCab = 0;
fFailOnIncompressible = false;
szDisk = string.Empty;
szCab = Path.GetFileName(cabFullPath);
szCabPath = Path.GetDirectoryName(cabFullPath);
if (szCabPath[szCabPath.Length - 1] != Path.DirectorySeparatorChar)
szCabPath += Path.DirectorySeparatorChar;
}
}
/// Provides a handle to a file compression interface.
[StructLayout(LayoutKind.Sequential)]
public struct HFCI : IHandle
{
private readonly IntPtr handle;
/// Initializes a new instance of the struct.
/// An object that represents the pre-existing handle to use.
public HFCI(IntPtr preexistingHandle) => handle = preexistingHandle;
/// Returns an invalid handle by instantiating a object with .
public static HFCI NULL => new(IntPtr.Zero);
/// Gets a value indicating whether this instance is a null handle.
public bool IsNull => handle == IntPtr.Zero;
/// Performs an explicit conversion from to .
/// The handle.
/// The result of the conversion.
public static explicit operator IntPtr(HFCI h) => h.handle;
/// Performs an implicit conversion from to .
/// The pointer to a handle.
/// The result of the conversion.
public static implicit operator HFCI(IntPtr h) => new(h);
/// Implements the operator !=.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator !=(HFCI h1, HFCI h2) => !(h1 == h2);
/// Implements the operator ==.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator ==(HFCI h1, HFCI h2) => h1.Equals(h2);
///
public override bool Equals(object obj) => obj is HFCI h && handle == h.handle;
///
public override int GetHashCode() => handle.GetHashCode();
///
public IntPtr DangerousGetHandle() => handle;
}
/// Provides a for that is disposed using .
public class SafeHFCI : SafeHANDLE
{
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
///
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
///
public SafeHFCI(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// Initializes a new instance of the class.
private SafeHFCI() : base() { }
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator HFCI(SafeHFCI h) => h.handle;
///
protected override bool InternalReleaseHandle() => FCIDestroy(handle);
}
}
}