📄 fdi.pas
字号:
*
* fdintPARTIAL_FILE:
* Called for files at the front of the cabinet that are CONTINUED
* from a previous cabinet. This callback occurs only when FDICopy is
* started on second or subsequent cabinet in a series that has files
* continued from a previous cabinet.
* Entry:
* pfdin->psz1 = file name of file CONTINUED from a PREVIOUS cabinet
* pfdin->psz2 = name of cabinet where file starts
* pfdin->psz3 = name of disk where file starts
* Exit-Success:
* Return anything other than -1; enumeration continues
* Exit-Failure:
* Returns -1 => Abort FDICopy() call
*
* fdintENUMERATE:
* Called once after a call to FDICopy() starts scanning a CAB's
* CFFILE entries, and again when there are no more CFFILE entries.
* If CAB spanning occurs, an additional call will occur after the
* first spanned file is completed. If the pfdin->iFolder value is
* changed from zero, additional calls will occur next time it reaches
* zero. If iFolder is changed to zero, FDICopy will terminate, as if
* there were no more CFFILE entries. Primarily intended to allow an
* application with it's own file list to help FDI advance quickly to
* a CFFILE entry of interest. Can also be used to allow an
* application to determine the cb values for each file in the CAB.
* Entry:
* pfdin->cb = current CFFILE position
* pfdin->iFolder = number of files remaining
* pfdin->setID = current CAB's setID value
* Exit-Don't Care:
* Don't change anything.
* Return anything but -1.
* Exit-Forcing a skip:
* pfdin->cb = desired CFFILE position
* pfdin->iFolder = desired # of files remaining
* Return anything but -1.
* Exit-Stop:
* pfdin->iFolder = set to 0
* Return anything but -1.
* Exit-Failure:
* Return -1 => Abort FDICopy call ("user aborted".)
* Notes:
* This call can be ignored by applications which want normal file
* searching. The application can adjust the supplied values to
* force FDICopy() to continue it's search at another location, or
* to force FDICopy() to terminate the search, by setting iFolder to 0.
* (FDICopy() will report no error when terminated this way.)
* FDI has no means to verify the supplied cb or iFolder values.
* Arbitrary values are likely to cause undesirable results. An
* application should cross-check pfdin->setID to be certain the
* external database is in sync with the CAB. Reverse-skips are OK
* (but may be inefficient) unless fdintNEXT_CABINET has been called.
*
* fdintNEXT_CABINET:
* This function is *only* called when fdintCOPY_FILE was told to copy
* a file in the current cabinet that is continued to a subsequent
* cabinet file. It is important that the cabinet path name (psz3)
* be validated before returning! This function should ensure that
* the cabinet exists and is readable before returning. So, this
* is the function that should, for example, issue a disk change
* prompt and make sure the cabinet file exists.
*
* When this function returns to FDI, FDI will check that the setID
* and iCabinet match the expected values for the next cabinet.
* If not, FDI will continue to call this function until the correct
* cabinet file is specified, or until this function returns -1 to
* abort the FDICopy() function. pfdin->fdie is set to
* FDIERROR_WRONG_CABINET to indicate this case.
*
* If you *haven't* ensured that the cabinet file is present and
* readable, or the cabinet file has been damaged, pfdin->fdie will
* receive other appropriate error codes:
*
* FDIERROR_CABINET_NOT_FOUND
* FDIERROR_NOT_A_CABINET
* FDIERROR_UNKNOWN_CABINET_VERSION
* FDIERROR_CORRUPT_CABINET
* FDIERROR_BAD_COMPR_TYPE
* FDIERROR_RESERVE_MISMATCH
* FDIERROR_WRONG_CABINET
*
* Entry:
* pfdin->psz1 = name of next cabinet where current file is continued
* pfdin->psz2 = name of next disk where current file is continued
* pfdin->psz3 = cabinet path name; FDI concatenates psz3 with psz1
* to produce the fully-qualified path for the cabinet
* file. The 256-byte buffer pointed at by psz3 may
* be modified, but psz1 may not!
* pfdin->fdie = FDIERROR_WRONG_CABINET if the previous call to
* fdintNEXT_CABINET specified a cabinet file that
* did not match the setID/iCabinet that was expected.
* Exit-Success:
* Return anything but -1
* Exit-Failure:
* Returns -1 => Abort FDICopy() call
* Notes:
* This call is almost always made when a target file is open and
* being written to, and the next cabinet is needed to get more
* data for the file.
}
type
TFDINOTIFICATIONTYPE =
(
fdintCABINET_INFO // General information about cabinet
,
fdintPARTIAL_FILE // First file in cabinet is continuation
,
fdintCOPY_FILE // File to be copied
,
fdintCLOSE_FILE_INFO // close the file, set relevant info
,
fdintNEXT_CABINET // File continued to next cabinet
,
fdintENUMERATE // Enumeration status
);
{ fdint }
TFNFDINOTIFY_dummy = function (fdint : TFDINOTIFICATIONTYPE;
pfdin : PFDINOTIFICATION) : Integer; cdecl;
PFNFDINOTIFY = TFNFDINOTIFY_dummy;
{ pfnfdin }
{** cpuType values for FDICreate()
*
* (Ignored by 32-bit FDI.)
}
const
cpuUNKNOWN = (-1);
cpu80286 = (0);
cpu80386 = (1);
{** FDICreate - Create an FDI context
*
* Entry:
* pfnalloc
* pfnfree
* pfnopen
* pfnread
* pfnwrite
* pfnclose
* pfnlseek
* cpuType - Select CPU type (auto-detect, 286, or 386+)
* NOTE: For the 32-bit FDI.LIB, this parameter is ignored!
* perf
*
* Exit-Success:
* Returns non-NULL FDI context handle.
*
* Exit-Failure:
* Returns NULL; perf filled in with error code
*
}
function FDICreate (pfnalloc : PFNALLOC; pfnfree : PFNFREE; pfnopen : PFNOPEN;
pfnread : PFNREAD; pfnwrite : PFNWRITE; pfnclose : PFNCLOSE;
pfnseek : PFNSEEK; cpuType : Integer; perf : PERF) : HFDI; cdecl;
{** FDIIsCabinet - Determines if file is a cabinet, returns info if it is
*
* Entry:
* hfdi - Handle to FDI context (created by FDICreate())
* hf - File handle suitable for PFNREAD/PFNSEEK, positioned
* at offset 0 in the file to test.
* pfdici - Buffer to receive info about cabinet if it is one.
*
* Exit-Success:
* Returns TRUE; file is a cabinet, pfdici filled in.
*
* Exit-Failure:
* Returns FALSE, file is not a cabinet; If an error occurred,
* perf (passed on FDICreate call!) filled in with error.
}
function FDIIsCabinet (hfdi : HFDI; hf : Integer; pfdici : TPFDICABINETINFO) : BOOL; cdecl;
{** FDICopy - extracts files from a cabinet
*
* Entry:
* hfdi - handle to FDI context (created by FDICreate())
* pszCabinet - main name of cabinet file
* pszCabPath - Path to cabinet file(s)
* flags - Flags to modify behavior
* pfnfdin - Notification function
* pfnfdid - Decryption function (pass NULL if not used)
* pvUser - User specified value to pass to notification function
*
* Exit-Success:
* Returns TRUE;
*
* Exit-Failure:
* Returns FALSE, perf (passed on FDICreate call!) filled in with
* error.
*
* Notes:
* (1) If FDICopy() fails while a target file is being written out, then
* FDI will use the PFNCLOSE function to close the file handle for that
* target file that was returned from the fdintCOPY_FILE notification.
* The client application is then free to delete the target file, since
* it will not be in a valid state (since there was an error while
* writing it out).
}
function FDICopy (hfdi : HFDI; pszCabinet : PChar; pszCabPath : PChar;
flags : Integer; pfnfdin : PFNFDINOTIFY; pfnfdid : PFNFDIDECRYPT;
pvUser : PVoid) : BOOL; cdecl;
{** FDIDestroy - Destroy an FDI context
*
* Entry:
* hfdi - handle to FDI context (created by FDICreate())
*
* Exit-Success:
* Returns TRUE;
*
* Exit-Failure:
* Returns FALSE;
}
function FDIDestroy (hfdi : HFDI) : BOOL; cdecl;
function CompressionTypeFromTCOMP (tc : TCOMP) : Integer;
function CompressionLevelFromTCOMP (tc : TCOMP) : Integer;
function CompressionMemoryFromTCOMP (tc : TCOMP) : Integer;
function TCOMPfromTypeLevelMemory (t : Integer; l : Integer; m : Integer) : Integer;
function LZXCompressionWindowFromTCOMP (tc : TCOMP) : Integer;
function TCOMPfromLZXWindow (w : Integer) : Integer;
implementation
const
CabinetDll = 'cabinet.dll';
function FDICreate; external CabinetDll name 'FDICreate';
function FDIIsCabinet; external CabinetDll name 'FDIIsCabinet';
function FDICopy; external CabinetDll name 'FDICopy';
function FDIDestroy; external CabinetDll name 'FDIDestroy';
function CompressionTypeFromTCOMP (tc : TCOMP) : Integer;
begin
Result:=((tc) and $000F);
end;
function CompressionLevelFromTCOMP (tc : TCOMP) : Integer;
begin
Result:=(((tc) and $00F0) shr 4);
end;
function CompressionMemoryFromTCOMP (tc : TCOMP) : Integer;
begin
Result:=(((tc) and $1F00) shr 8);
end;
function TCOMPfromTypeLevelMemory (t : Integer; l : Integer;
m : Integer) : Integer;
begin
Result:=(((m) shl 8) or ((l) shl 4) or (t));
end;
function LZXCompressionWindowFromTCOMP (tc : TCOMP) : Integer;
begin
Result:=(((tc) and $1F00) shr 8);
end;
function TCOMPfromLZXWindow (w : Integer) : Integer;
begin
Result:=(((w) shl 8) or ($0003));
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -