📄 fdi.h
字号:
* FDIIsCabinet(), and make sure the setID matches the one for
* the current cabinet specified in the fdintCABINET_INFO, and
* that the disk number is one greater.
*
* NOTE: FDI will continue to call fdintNEXT_CABINET until it
* gets the cabinet it wants, or until you return -1
* to abort the FDICopy() call.
*
* The documentation below on the FDI error codes provides explicit
* guidance on how to avoid each error.
*
* If you find you must return a failure to FDI from one of your
* callback functions, then FDICopy() frees all resources it allocated
* and closes all files. If you can figure out how to overcome the
* problem, you can call FDICopy() again on the last cabinet, and
* skip any files that you already copied. But, note that FDI does
* *not* maintain any state between FDICopy() calls, other than possibly
* memory allocated for the decompressor.
*
* See FDIERROR for details on FDI error codes and recommended actions.
*
*
* Progress Indicator Suggestions:
* As above, all of the file I/O functions are supplied by you. So,
* updating a progress indicator is very simple. You keep track of
* the target files handles you have opened, along with the uncompressed
* size of the target file. When you see writes to the handle of a
* target file, you use the write count to update your status!
* Since this method is available, there is no separate callback from
* FDI just for progess indication.
*/
#ifndef INCLUDED_FDI
#define INCLUDED_FDI 1
//** Specify structure packing explicitly for clients of FDI
#pragma pack(4)
/*** FDIERROR - Error codes returned in erf.erfOper field
*
* In general, FDI will only fail if one of the passed in memory or
* file I/O functions fails. Other errors are pretty unlikely, and are
* caused by corrupted cabinet files, passing in a file which is not a
* cabinet file, or cabinet files out of order.
*
* Description: Summary of error.
* Cause: List of possible causes of this error.
* Response: How client might respond to this error, or avoid it in
* the first place.
*/
typedef enum {
FDIERROR_NONE,
// Description: No error
// Cause: Function was successfull.
// Response: Keep going!
FDIERROR_CABINET_NOT_FOUND,
// Description: Cabinet not found
// Cause: Bad file name or path passed to FDICopy(), or returned
// to fdintNEXT_CABINET.
// Response: To prevent this error, validate the existence of the
// the cabinet *before* passing the path to FDI.
FDIERROR_NOT_A_CABINET,
// Description: Cabinet file does not have the correct format
// Cause: File passed to to FDICopy(), or returned to
// fdintNEXT_CABINET, is too small to be a cabinet file,
// or does not have the cabinet signature in its first
// four bytes.
// Response: To prevent this error, call FDIIsCabinet() to check a
// cabinet before calling FDICopy() or returning the
// cabinet path to fdintNEXT_CABINET.
FDIERROR_UNKNOWN_CABINET_VERSION,
// Description: Cabinet file has an unknown version number.
// Cause: File passed to to FDICopy(), or returned to
// fdintNEXT_CABINET, has what looks like a cabinet file
// header, but the version of the cabinet file format
// is not one understood by this version of FDI. The
// erf.erfType field is filled in with the version number
// found in the cabinet file.
// Response: To prevent this error, call FDIIsCabinet() to check a
// cabinet before calling FDICopy() or returning the
// cabinet path to fdintNEXT_CABINET.
FDIERROR_CORRUPT_CABINET,
// Description: Cabinet file is corrupt
// Cause: FDI returns this error any time it finds a problem
// with the logical format of a cabinet file, and any
// time one of the passed-in file I/O calls fails when
// operating on a cabinet (PFNOPEN, PFNSEEK, PFNREAD,
// or PFNCLOSE). The client can distinguish these two
// cases based upon whether the last file I/O call
// failed or not.
// Response: Assuming this is not a real corruption problem in
// a cabinet file, the file I/O functions could attempt
// to do retries on failure (for example, if there is a
// temporary network connection problem). If this does
// not work, and the file I/O call has to fail, then the
// FDI client will have to clean up and call the
// FDICopy() function again.
FDIERROR_ALLOC_FAIL,
// Description: Could not allocate enough memory
// Cause: FDI tried to allocate memory with the PFNALLOC
// function, but it failed.
// Response: If possible, PFNALLOC should take whatever steps
// are possible to allocate the memory requested. If
// memory is not immediately available, it might post a
// dialog asking the user to free memory, for example.
// Note that the bulk of FDI's memory allocations are
// made at FDICreate() time and when the first cabinet
// file is opened during FDICopy().
FDIERROR_BAD_COMPR_TYPE,
// Description: Unknown compression type in a cabinet folder
// Cause: [Should never happen.] A folder in a cabinet has an
// unknown compression type. This is probably caused by
// a mismatch between the version of FCI.LIB used to
// create the cabinet and the FDI.LIB used to read the
// cabinet.
// Response: Abort.
FDIERROR_MDI_FAIL,
// Description: Failure decompressing data from a cabinet file
// Cause: The decompressor found an error in the data coming
// from the file cabinet. The cabinet file was corrupted.
// [11-Apr-1994 bens When checksuming is turned on, this
// error should never occur.]
// Response: Probably should abort; only other choice is to cleanup
// and call FDICopy() again, and hope there was some
// intermittent data error that will not reoccur.
FDIERROR_TARGET_FILE,
// Description: Failure writing to target file
// Cause: FDI returns this error any time it gets an error back
// from one of the passed-in file I/O calls fails when
// writing to a file being extracted from a cabinet.
// Response: To avoid or minimize this error, the file I/O functions
// could attempt to avoid failing. A common cause might
// be disk full -- in this case, the PFNWRITE function
// could have a check for free space, and put up a dialog
// asking the user to free some disk space.
FDIERROR_RESERVE_MISMATCH,
// Description: Cabinets in a set do not have the same RESERVE sizes
// Cause: [Should never happen]. FDI requires that the sizes of
// the per-cabinet, per-folder, and per-data block
// RESERVE sections be consistent across all the cabinets
// in a set.
// Response: Abort.
FDIERROR_WRONG_CABINET,
// Description: Cabinet returned on fdintNEXT_CABINET is incorrect
// Cause: NOTE: THIS ERROR IS NEVER RETURNED BY FDICopy()!
// Rather, FDICopy() keeps calling the fdintNEXT_CABINET
// callback until either the correct cabinet is specified,
// or you return ABORT.
// When FDICopy() is extracting a file that crosses a
// cabinet boundary, it calls fdintNEXT_CABINET to ask
// for the path to the next cabinet. Not being very
// trusting, FDI then checks to make sure that the
// correct continuation cabinet was supplied! It does
// this by checking the "setID" and "iCabinet" fields
// in the cabinet. When MAKECAB.EXE creates a set of
// cabinets, it constructs the "setID" using the sum
// of the bytes of all the destination file names in
// the cabinet set. FDI makes sure that the 16-bit
// setID of the continuation cabinet matches the
// cabinet file just processed. FDI then checks that
// the cabinet number (iCabinet) is one more than the
// cabinet number for the cabinet just processed.
// Response: You need code in your fdintNEXT_CABINET (see below)
// handler to do retries if you get recalled with this
// error. See the sample code (EXTRACT.C) to see how
// this should be handled.
FDIERROR_USER_ABORT,
// Description: FDI aborted.
// Cause: An FDI callback returnd -1 (usually).
// Response: Up to client.
} FDIERROR;
/*
* FAT file attribute flag used by FCI/FDI to indicate that
* the filename in the CAB is a UTF string
*/
#ifndef _A_NAME_IS_UTF
#define _A_NAME_IS_UTF 0x80
#endif
/*
* FAT file attribute flag used by FCI/FDI to indicate that
* the file should be executed after extraction
*/
#ifndef _A_EXEC
#define _A_EXEC 0x40
#endif
/*** HFDI - Handle to an FDI context
*
* FDICreate() creates this, and it must be passed to all other FDI
* functions.
*/
typedef void FAR *HFDI; /* hfdi */
/*** FDICABINETINFO - Information about a cabinet
*
*/
typedef struct {
long cbCabinet; // Total length of cabinet file
USHORT cFolders; // Count of folders in cabinet
USHORT cFiles; // Count of files in cabinet
USHORT setID; // Cabinet set ID
USHORT iCabinet; // Cabinet number in set (0 based)
BOOL fReserve; // TRUE => RESERVE present in cabinet
BOOL hasprev; // TRUE => Cabinet is chained prev
BOOL hasnext; // TRUE => Cabinet is chained next
} FDICABINETINFO; /* fdici */
typedef FDICABINETINFO FAR *PFDICABINETINFO; /* pfdici */
/*** FDIDECRYPTTYPE - PFNFDIDECRYPT command types
*
*/
typedef enum {
fdidtNEW_CABINET, // New cabinet
fdidtNEW_FOLDER, // New folder
fdidtDECRYPT, // Decrypt a data block
} FDIDECRYPTTYPE; /* fdidt */
/*** FDIDECRYPT - Data for PFNFDIDECRYPT function
*
*/
typedef struct {
FDIDECRYPTTYPE fdidt; // Command type (selects union below)
void FAR *pvUser; // Decryption context
union {
struct { // fdidtNEW_CABINET
void FAR *pHeaderReserve; // RESERVE section from CFHEADER
USHORT cbHeaderReserve; // Size of pHeaderReserve
USHORT setID; // Cabinet set ID
int iCabinet; // Cabinet number in set (0 based)
} cabinet;
struct { // fdidtNEW_FOLDER
void FAR *pFolderReserve; // RESERVE section from CFFOLDER
USHORT cbFolderReserve; // Size of pFolderReserve
USHORT iFolder; // Folder number in cabinet (0 based)
} folder;
struct { // fdidtDECRYPT
void FAR *pDataReserve; // RESERVE section from CFDATA
USHORT cbDataReserve; // Size of pDataReserve
void FAR *pbData; // Data buffer
USHORT cbData; // Size of data buffer
BOOL fSplit; // TRUE if this is a split data block
USHORT cbPartial; // 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.
} decrypt;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -