(* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is TurboPower Abbrevia * * The Initial Developer of the Original Code is * TurboPower Software * * Portions created by the Initial Developer are Copyright (C) 1997-2002 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * ***** END LICENSE BLOCK ***** *) {*********************************************************} {* ABBREVIA: AbFciFdi.pas *} {*********************************************************} {* ABBREVIA: Cabinet DLL wrapper *} {* Based on info from the FCI/FDI Library Description, *} {* included in the Microsoft Cabinet SDK *} {*********************************************************} unit AbFciFdi; {$I AbDefine.inc} interface uses Windows, AbUtils; const CabinetDLL = 'cabinet.dll'; cpuUnknown = -1; cpu80286 = 0; cpu80386 = 1; cpuDefault = cpuUnknown; type {FDI errors} 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); {FCI errors} FCIError = (FCIError_NONE, FCIError_Open_SRC, FCIError_Read_SRC, FCIError_Alloc_Fail, FCIError_Temp_File, FCIError_Bad_Compr_Type, FCIError_Cab_File, FCIError_User_Abort, FCIERRor_MCI_Fail); {FDI notifications} FDINotificationType = (FDINT_Cabinet_Info, FDINT_Partial_File, FDINT_Copy_File, FDINT_Close_File_Info, FDINT_Next_Cabinet, FDINT_Enumerate); {FDI/FCI error structure} PCabErrorRecord = ^CabErrorRecord; CabErrorRecord = record ErrorCode : Integer; ErrorType : Integer; ErrorPresent : BOOL; end; {FDI cabinet information structure} PFDICabInfo = ^FDICabInfo; FDICabInfo = record cbCabinet : Longint; cFolders : Word; cFiles : Word; setID : Word; iCabinet : Word; fReserve : BOOL; hasprev : BOOL; hasnext : BOOL; end; {FCI cabinet information structure} PFCICabInfo = ^FCICabInfo; FCICabInfo = record cb : Longint; cbFolderThresh : Longint; cbReserveCFHeader : Integer; cbReserveCFFolder : Integer; cbReserveCFData : Integer; iCab : Integer; iDisk : Integer; fFailOnIncompressible : Integer; setID : Word; szDisk : array[0..255] of AnsiChar; szCab : array[0..255] of AnsiChar; szCabPath : array[0..255] of AnsiChar; end; {FDI notification structure} PFDINotification = ^FDINotification; FDINotification = record cb : Longint; psz1 : PAnsiChar; psz2 : PAnsiChar; psz3 : PAnsiChar; pv : Pointer; hf : PtrInt; date : Word; time : Word; attribs : Word; setID : Word; iCabinet : Word; iFolder : Word; fdie : FDIERROR; end; {misc defines} HFDI = Pointer; HFCI = Pointer; FARPROC = Pointer; {== Cabinet DLL routine prototypes ==========================================} type TFDICreate = function (pfnalloc, pfnfree, pfnopen, pfnread, pfnwrite, pfnclose, pfnseek : FARPROC; cpuType : Integer; pError : PCabErrorRecord) : HFDI; cdecl; {----------------------------------------------------------------------------} TFDIIsCabinet = function(hfdi : HFDI; hf : PtrInt; pfdici : PFDICabInfo) : BOOL; cdecl; {----------------------------------------------------------------------------} TFDICopy = function(hfdi : HFDI; pszCabinet, pszCabPath : PAnsiChar; flags : Integer; pfnfdin, pfnfdid : FARPROC; Archive : Pointer) : BOOL; cdecl; {----------------------------------------------------------------------------} TFDIDestroy = function(hfdi : HFDI) : BOOL; cdecl; {----------------------------------------------------------------------------} TFCICreate = function(pError : PCabErrorRecord; pfnfcifp, pfnalloc, pfnfree, pfnopen, pfnread, pfnwrite, pfnclose, pfnseek, pfndelete, pfnfcigtf : FARPROC; pccab : PFCICabInfo; Archive : Pointer) : HFCI; cdecl; {----------------------------------------------------------------------------} TFCIAddFile = function(hfci : HFCI; pszFilePath, pszFileName : PAnsiChar; fExecute : BOOL; pfnfcignc, pfnfcis, pfnfcigoi : FARPROC; typeCompress : Word) : BOOL; cdecl; {----------------------------------------------------------------------------} TFCIFlushCabinet = function(hfci : HFCI; fGetNextCab : BOOL; pfnfcignc, pfnfcis : FARPROC) : BOOL; cdecl; {----------------------------------------------------------------------------} TFCIFlushFolder = function(hfci : HFCI; pfnfcignc, pfnfcis : FARPROC) : BOOL; cdecl; {----------------------------------------------------------------------------} TFCIDestroy = function(hfci : HFCI) : BOOL; cdecl; {== DLL routine wrappers ====================================================} function FDICreate(pfnalloc, pfnfree, pfnopen, pfnread, pfnwrite, pfnclose, pfnseek : FARPROC; cpuType : Integer; pError : PCabErrorRecord) : HFDI; {returns an FDI context for opening an existing cabinet} { pfnalloc - heap allocation callback function } { pfnfree - heap deallocation callback function } { pfnopen - open file callback function } { pfnwrite - write file callback function } { pfnclose - close file callback function } { pfnseek - reposition file pointer callback function } { cpuType - -1: unknown, 0: 80286, 1: 80386 } { pError - pointer to error record } {----------------------------------------------------------------------------} function FDIIsCabinet(hfdi : HFDI; hf : PtrInt; pfdici : PFDICabInfo) : BOOL; {checks cabinet file for validity} { hfdi - FDI context } { hf - cabinet file handle } { pfdici - pointer to FDI cabinet info structure } {----------------------------------------------------------------------------} function FDICopy(hfdi : HFDI; pszCabinet, pszCabPath : PAnsiChar; flags : Integer; pfnfdin, pfnfdid : FARPROC; Archive : Pointer) : BOOL; {enumerates every file in the cabinet. The callback function } {should indicate whether or not to extract a given file} { hfdi - FDI context } { pszCabinet - cabinet file name } { pszCabPath - cabinet file path } { flags - currently not used } { pfnfdin - FDI notifaction callback function } { pfnfdid - decryption callback (currently not used)} { Archive - the calling TAbCabArchive instance } {----------------------------------------------------------------------------} function FDIDestroy(hfdi : HFDI) : BOOL; {releases FDI context and frees resources} { hfdi - FDI context } {----------------------------------------------------------------------------} function FCICreate(pError : PCabErrorRecord; pfnfcifp, pfnalloc, pfnfree, pfnopen, pfnread, pfnwrite, pfnclose, pfnseek, pfndelete, pfnfcigtf : FARPROC; pccab : PFCICabInfo; Archive : Pointer) : HFCI; {creates a new cabinet file and returns the FCI context} { pError - pointer to error record } { pfnfcifp - callback notification when file has been placed in cabinet } { pfnalloc - callback function to allocate memory } { pfnfree - callback function to free memory } { pfnopen - callback function to open a file } { pfnwrite - callback function to write to a file } { pfnclose - callback function to close a file } { pfnseek - callback function to reposition file pointer } { pfndelete - callback function to delete a file } { pfnfcigtf - callback function to obtain temp filename } { pccab - pointer to FCI cabinet infor structure } { Archive - the calling TAbCabArchive instance } {----------------------------------------------------------------------------} function FCIAddFile(hfci : HFCI; pszFilePath, pszFileName : PAnsiChar; fExecute : BOOL; pfnfcignc, pfnfcis, pfnfcigoi : FARPROC; typeCompress : Word) : BOOL; {adds a file to the cabinet} { hfci - FCI context } { pszFilePath - full pathname of file being added } { pszFileName - just the file name } { fExecute - flag to indicate if file is executable } { pfnfcignc - callback function to obtain next cabinet info } { pfnfcis - callback function to relay progress } { pfnfcigoi - callback function to open file and get attributes } { typeCompress - compression type to use } {----------------------------------------------------------------------------} function FCIFlushCabinet(hfci : HFCI; fGetNextCab : BOOL; pfnfcignc, pfnfcis : FARPROC) : BOOL; {writes current cabinet file out to disk and optionally starts a new one} { hfci - FCI context } { fGetNextCab - flag indicating whether to start a new cabinet } { pfnfcignc - callback function to obtain next cabinet info } { pfnfcis - callback function to relay progress } {----------------------------------------------------------------------------} function FCIFlushFolder(hfci : HFCI; pfnfcignc, pfnfcis : FARPROC) : BOOL; {close current compression block and start a new one} { hfci - FCI context } { pfnfcignc - callback function to obtain next cabinet info } { pfnfcis - callback function to relay progress } {----------------------------------------------------------------------------} function FCIDestroy(hfci : HFCI) : BOOL; {releases FCI context and frees resources} { hfdi - FDI context } {----------------------------------------------------------------------------} implementation uses AbExcept; var CabDLLLoaded : Boolean; CabDLLHandle : THandle; FDICreateProc : TFDICreate; FDIIsCabinetProc : TFDIIsCabinet; FDICopyProc : TFDICopy; FDIDestroyProc : TFDIDestroy; FCICreateProc : TFCICreate; FCIAddFileProc : TFCIAddFile; FCIFlushCabinetProc : TFCIFlushCabinet; FCIFlushFolderProc : TFCIFlushFolder; FCIDestroyProc : TFCIDestroy; {============================================================================} procedure LoadCabinetDLL; begin if CabDllLoaded then Exit; CabDllHandle := LoadLibrary(CabinetDLL); if (CabDllHandle = 0) then raise EAbNoCabinetDLL.Create; @FDICreateProc := GetProcAddress(CabDllHandle, 'FDICreate'); @FDIIsCabinetProc := GetProcAddress(CabDllHandle, 'FDIIsCabinet'); @FDICopyProc := GetProcAddress(CabDllHandle, 'FDICopy'); @FDIDestroyProc := GetProcAddress(CabDllHandle, 'FDIDestroy'); @FCICreateProc := GetProcAddress(CabDllHandle, 'FCICreate'); @FCIAddFileProc := GetProcAddress(CabDllHandle, 'FCIAddFile'); @FCIFlushCabinetProc := GetProcAddress(CabDllHandle, 'FCIFlushCabinet'); @FCIFlushFolderProc := GetProcAddress(CabDllHandle, 'FCIFlushFolder'); @FCIDestroyProc := GetProcAddress(CabDllHandle, 'FCIDestroy'); CabDllLoaded := True; end; {----------------------------------------------------------------------------} function FDICreate(pfnalloc, pfnfree, pfnopen, pfnread, pfnwrite, pfnclose, pfnseek : FARPROC; cpuType : Integer; pError : PCabErrorRecord) : HFDI; begin LoadCabinetDLL; if Assigned(FDICreateProc) then Result := FDICreateProc(pfnalloc, pfnfree, pfnopen, pfnread, pfnwrite, pfnclose, pfnseek, cpuType, pError) else Result := nil; end; {----------------------------------------------------------------------------} function FDIIsCabinet(hfdi : HFDI; hf : PtrInt; pfdici : PFDICabInfo) : BOOL; begin LoadCabinetDLL; if Assigned(FDIIsCabinetProc) then Result := FDIIsCabinetProc(hfdi, hf, pfdici) else Result := False; end; {----------------------------------------------------------------------------} function FDICopy(hfdi : HFDI; pszCabinet, pszCabPath : PAnsiChar; flags : Integer; pfnfdin, pfnfdid : FARPROC; Archive : Pointer) : BOOL; begin LoadCabinetDLL; if Assigned(FDICopyProc) then Result := FDICopyProc(hfdi, pszCabinet, pszCabPath, flags, pfnfdin, pfnfdid, Archive) else Result := False; end; {----------------------------------------------------------------------------} function FDIDestroy(hfdi : HFDI) : BOOL; begin LoadCabinetDLL; if Assigned(FDIDestroyProc) then Result := FDIDestroyProc(hfdi) else Result := False; end; {----------------------------------------------------------------------------} function FCICreate(pError : PCabErrorRecord; pfnfcifp, pfnalloc, pfnfree, pfnopen, pfnread, pfnwrite, pfnclose, pfnseek, pfndelete, pfnfcigtf : FARPROC; pccab : PFCICabInfo; Archive : Pointer) : HFCI; begin LoadCabinetDLL; if Assigned(FCICreateProc) then Result := FCICreateProc(pError, pfnfcifp, pfnalloc, pfnfree, pfnopen, pfnread, pfnwrite, pfnclose, pfnseek, pfndelete, pfnfcigtf, pccab, Archive) else Result := nil; end; {----------------------------------------------------------------------------} function FCIAddFile(hfci : HFCI; pszFilePath, pszFileName : PAnsiChar; fExecute : BOOL; pfnfcignc, pfnfcis, pfnfcigoi : FARPROC; typeCompress : Word) : BOOL; begin LoadCabinetDLL; if Assigned(FCIAddFileProc) then Result := FCIAddFileProc(hfci, pszFilePath, pszFileName, fExecute, pfnfcignc, pfnfcis, pfnfcigoi, typeCompress) else Result := False; end; {----------------------------------------------------------------------------} function FCIFlushCabinet(hfci : HFCI; fGetNextCab : BOOL; pfnfcignc, pfnfcis : FARPROC) : BOOL; begin LoadCabinetDLL; if Assigned(FCIFlushCabinetProc) then Result := FCIFlushCabinetProc(hfci, fGetNextCab, pfnfcignc, pfnfcis) else Result := False; end; {----------------------------------------------------------------------------} function FCIFlushFolder(hfci : HFCI; pfnfcignc, pfnfcis : FARPROC) : BOOL; begin LoadCabinetDLL; if Assigned(FCIFlushFolderProc) then Result := FCIFlushFolderProc(hfci, pfnfcignc, pfnfcis) else Result := False; end; {----------------------------------------------------------------------------} function FCIDestroy(hfci : HFCI) : BOOL; begin LoadCabinetDLL; if Assigned(FCIDestroyProc) then Result := FCIDestroyProc(hfci) else Result := False; end; {----------------------------------------------------------------------------} initialization CabDllLoaded := False; end.