📄 fdi.pas
字号:
* 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.
}
type
TFDIERROR =
(
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.
);
(*
* FAT file attribute flag used by FCI/FDI to indicate that
* the filename in the CAB is a UTF string
*)
const
_A_NAME_IS_UTF = $80;
(*
* FAT file attribute flag used by FCI/FDI to indicate that
* the file should be executed after extraction
*)
const
_A_EXEC = $40;
{** HFDI - Handle to an FDI context
*
* FDICreate() creates this, and it must be passed to all other FDI
* functions.
}
type
HFDI = PVoid;
{ hfdi }
{** FDICABINETINFO - Information about a cabinet
*
}
type
TFDICABINETINFO =
record
cbCabinet : Longint; // Total length of cabinet file
cFolders : TUSHORT; // Count of folders in cabinet
cFiles : TUSHORT; // Count of files in cabinet
setID : TUSHORT; // Cabinet set ID
iCabinet : TUSHORT; // Cabinet number in set (0 based)
fReserve : BOOL; // TRUE => RESERVE present in cabinet
hasprev : BOOL; // TRUE => Cabinet is chained prev
hasnext : BOOL; // TRUE => Cabinet is chained next
end;
{ fdici }
TPFDICABINETINFO = ^TFDICABINETINFO;
{ pfdici }
{** FDIDECRYPTTYPE - PFNFDIDECRYPT command types
*
}
type
TFDIDECRYPTTYPE =
(
fdidtNEW_CABINET // New cabinet
,
fdidtNEW_FOLDER // New folder
,
fdidtDECRYPT // Decrypt a data block
);
{ fdidt }
{** FDIDECRYPT - Data for PFNFDIDECRYPT function
*
}
type
TFDIDECRYPT =
record
fdidt : TFDIDECRYPTTYPE; // Command type (selects union below)
pvUser : PVoid; // Decryption context
_noname1 :
record
case Integer of
1 :
(
cabinet :
record
// fdidtNEW_CABINET
pHeaderReserve : PVoid; // RESERVE section from CFHEADER
cbHeaderReserve : TUSHORT; // Size of pHeaderReserve
setID : TUSHORT; // Cabinet set ID
iCabinet : Integer; // Cabinet number in set (0 based)
end;
);
2 :
(
folder :
record
// fdidtNEW_FOLDER
pFolderReserve : PVoid; // RESERVE section from CFFOLDER
cbFolderReserve : TUSHORT; // Size of pFolderReserve
iFolder : TUSHORT; // Folder number in cabinet (0 based)
end;
);
3 :
(
decrypt :
record
// fdidtDECRYPT
pDataReserve : PVoid; // RESERVE section from CFDATA
cbDataReserve : TUSHORT; // Size of pDataReserve
pbData : PVoid; // Data buffer
cbData : TUSHORT; // Size of data buffer
fSplit : BOOL; // TRUE if this is a split data block
cbPartial : TUSHORT; // 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.
end;
);
end;
end;
{ fdid }
PFDIDECRYPT = ^TFDIDECRYPT;
{ pfdid }
{** FNALLOC - Memory Allocation
* FNFREE - Memory Free
*
* These are modeled after the C run-time routines malloc() and free()
* FDI expects error handling to be identical to these C run-time routines.
*
* As long as you faithfully copy the semantics of malloc() and free(),
* you can supply any functions you like!
*
* WARNING: You should never assume anything about the sequence of
* PFNALLOC and PFNFREE calls -- incremental releases of
* FDI may have radically different numbers of
* PFNALLOC calls and allocation sizes!
}
//** Memory functions for FDI
type
TFNALLOC_dummy = function (cb : TULONG) : PVoid; cdecl;
PFNALLOC = TFNALLOC_dummy;
{ pfna }
TFNFREE_dummy = function (pv : PVoid) : Pointer; cdecl;
PFNFREE = TFNFREE_dummy;
{ pfnf }
{** PFNOPEN - File I/O callbacks for FDI
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -