📄 fci.c
字号:
/* set seek of p_fci_internal->handleCFDATA1 to 0 */
if( PFCI_SEEK(hfci,p_fci_internal->handleCFDATA1,0,SEEK_SET,&err,
p_fci_internal->pv) !=0 ) {
/* wrong return value */
fci_set_error( FCIERR_NONE, ERROR_SEEK, TRUE );
PFCI_CLOSE(hfci,handleCFDATA1new,&err,p_fci_internal->pv);
/* TODO error handling of err */
PFCI_CLOSE(hfci,handleCFFILE1new,&err,p_fci_internal->pv);
/* TODO error handling of err */
return FALSE;
}
/* TODO error handling of err */
/* save size of file CFDATA2 - required for the folder's offset to data */
sizeFileCFDATA2old = p_fci_internal->sizeFileCFDATA2;
if(!(reserved = (char*)PFCI_ALLOC(hfci, cbReserveCFData+sizeof(CFDATA)))) {
fci_set_error( FCIERR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY, TRUE );
PFCI_CLOSE(hfci,handleCFDATA1new,&err,p_fci_internal->pv);
/* TODO error handling of err */
PFCI_CLOSE(hfci,handleCFFILE1new,&err,p_fci_internal->pv);
/* TODO error handling of err */
return FALSE;
}
if(!fci_flushfolder_copy_cfdata(hfci, reserved, cbReserveCFData, pfnfcis, &err,
handleCFDATA1new, &sizeFileCFDATA1new, &payload
)) {
PFCI_CLOSE(hfci,handleCFDATA1new,&err,p_fci_internal->pv);
/* TODO error handling of err */
PFCI_DELETE(hfci,szFileNameCFDATA1new,&err,p_fci_internal->pv);
/* TODO error handling of err */
PFCI_CLOSE(hfci,handleCFFILE1new,&err,p_fci_internal->pv);
/* TODO error handling of err */
PFCI_FREE(hfci,reserved);
return FALSE;
}
PFCI_FREE(hfci,reserved);
if(!fci_flushfolder_copy_cffolder(hfci, &err, cbReserveCFFolder,
sizeFileCFDATA2old )) {
PFCI_CLOSE(hfci,handleCFDATA1new,&err,p_fci_internal->pv);
/* TODO error handling of err */
PFCI_DELETE(hfci,szFileNameCFDATA1new,&err,p_fci_internal->pv);
/* TODO error handling of err */
PFCI_CLOSE(hfci,handleCFFILE1new,&err,p_fci_internal->pv);
/* TODO error handling of err */
return FALSE;
}
if(!fci_flushfolder_copy_cffile(hfci, &err, handleCFFILE1new,
&sizeFileCFFILE1new, payload)) {
PFCI_CLOSE(hfci,handleCFDATA1new,&err,p_fci_internal->pv);
/* TODO error handling of err */
PFCI_DELETE(hfci,szFileNameCFDATA1new,&err,p_fci_internal->pv);
/* TODO error handling of err */
PFCI_CLOSE(hfci,handleCFFILE1new,&err,p_fci_internal->pv);
/* TODO error handling of err */
PFCI_DELETE(hfci,szFileNameCFFILE1new,&err,p_fci_internal->pv);
/* TODO error handling of err */
return FALSE;
}
/* close and delete p_fci_internal->handleCFDATA1 */
PFCI_CLOSE(hfci,p_fci_internal->handleCFDATA1,&err,p_fci_internal->pv);
/* TODO error handling of err */
PFCI_DELETE(hfci,p_fci_internal->szFileNameCFDATA1,&err,p_fci_internal->pv);
/* TODO error handling of err */
/* put new CFDATA1 into hfci */
memcpy(p_fci_internal->szFileNameCFDATA1,szFileNameCFDATA1new,
CB_MAX_FILENAME);
/* put CFDATA1 file handle */
PFCI_INT(hfci)->handleCFDATA1 = handleCFDATA1new;
/* set file size */
PFCI_INT(hfci)->sizeFileCFDATA1 = sizeFileCFDATA1new;
/* close and delete PFCI_INT(hfci)->handleCFFILE1 */
PFCI_CLOSE(hfci,p_fci_internal->handleCFFILE1,&err,PFCI_INT(hfci)->pv);
/* TODO error handling of err */
PFCI_DELETE(hfci,p_fci_internal->szFileNameCFFILE1,&err,p_fci_internal->pv);
/* TODO error handling of err */
/* put new CFFILE1 into hfci */
memcpy(p_fci_internal->szFileNameCFFILE1,szFileNameCFFILE1new,
CB_MAX_FILENAME);
/* put CFFILE1 file handle */
p_fci_internal->handleCFFILE1 = handleCFFILE1new;
/* set file size */
p_fci_internal->sizeFileCFFILE1 = sizeFileCFFILE1new;
++(p_fci_internal->cFolders);
/* reset CFFolder specific information */
p_fci_internal->cDataBlocks=0;
p_fci_internal->cCompressedBytesInFolder=0;
return TRUE;
} /* end of fci_flush_folder */
static BOOL fci_flush_cabinet(
HFCI hfci,
BOOL fGetNextCab,
PFNFCIGETNEXTCABINET pfnfcignc,
PFNFCISTATUS pfnfcis)
{
int err;
CFHEADER cfheader;
struct {
cab_UWORD cbCFHeader;
cab_UBYTE cbCFFolder;
cab_UBYTE cbCFData;
} cfreserved;
CFFOLDER cffolder;
cab_ULONG read_result=0;
int handleCABINET; /* file handle for cabinet */
char szFileNameCABINET[CB_MAX_CAB_PATH+CB_MAX_CABINET_NAME];/* name buffer */
UINT cbReserveCFHeader, cbReserveCFFolder, i;
char* reserved;
BOOL returntrue=FALSE;
PFCI_Int p_fci_internal=((PFCI_Int)(hfci));
/* TODO test if fci_flush_cabinet really aborts if there was no FCIAddFile */
/* when FCIFlushCabinet was or FCIAddFile hasn't been called */
if( p_fci_internal->sizeFileCFFILE1==0 && fGetNextCab ) {
returntrue=TRUE;
}
if (!fci_flush_folder(hfci,fGetNextCab,pfnfcignc,pfnfcis)){
/* TODO set error */
return FALSE;
}
if(returntrue) return TRUE;
if ( (p_fci_internal->fSplitFolder && p_fci_internal->fNextCab==FALSE)||
(p_fci_internal->sizeFileCFFOLDER==0 &&
(p_fci_internal->sizeFileCFFILE1!=0 ||
p_fci_internal->sizeFileCFFILE2!=0 )
) )
{
/* error */
fci_set_error( FCIERR_NONE, ERROR_GEN_FAILURE, TRUE );
return FALSE;
}
if( p_fci_internal->fNextCab ||
p_fci_internal->fGetNextCabInVain ) {
cbReserveCFFolder=p_fci_internal->oldCCAB.cbReserveCFFolder;
cbReserveCFHeader=p_fci_internal->oldCCAB.cbReserveCFHeader;
/* safety */
if (strlen(p_fci_internal->oldCCAB.szCabPath)>=CB_MAX_CAB_PATH ||
strlen(p_fci_internal->oldCCAB.szCab)>=CB_MAX_CABINET_NAME) {
/* set error */
fci_set_error( FCIERR_NONE, ERROR_INVALID_DATA, TRUE );
return FALSE;
}
/* get the full name of the cabinet */
memcpy(szFileNameCABINET,p_fci_internal->oldCCAB.szCabPath,
CB_MAX_CAB_PATH);
memcpy(szFileNameCABINET+strlen(szFileNameCABINET),
p_fci_internal->oldCCAB.szCab, CB_MAX_CABINET_NAME);
} else {
cbReserveCFFolder=p_fci_internal->pccab->cbReserveCFFolder;
cbReserveCFHeader=p_fci_internal->pccab->cbReserveCFHeader;
/* safety */
if (strlen(p_fci_internal->pccab->szCabPath)>=CB_MAX_CAB_PATH ||
strlen(p_fci_internal->pccab->szCab)>=CB_MAX_CABINET_NAME) {
/* set error */
fci_set_error( FCIERR_NONE, ERROR_INVALID_DATA, TRUE );
return FALSE;
}
/* get the full name of the cabinet */
memcpy(szFileNameCABINET,p_fci_internal->pccab->szCabPath,
CB_MAX_CAB_PATH);
memcpy(szFileNameCABINET+strlen(szFileNameCABINET),
p_fci_internal->pccab->szCab, CB_MAX_CABINET_NAME);
}
memcpy(cfheader.signature,"!CAB",4);
cfheader.reserved1=0;
cfheader.cbCabinet= /* size of the cabinet file in bytes */
sizeof(CFHEADER) +
p_fci_internal->sizeFileCFFOLDER +
p_fci_internal->sizeFileCFFILE2 +
p_fci_internal->sizeFileCFDATA2;
if (p_fci_internal->fPrevCab) {
cfheader.cbCabinet+=strlen(p_fci_internal->szPrevCab)+1 +
strlen(p_fci_internal->szPrevDisk)+1;
}
if (p_fci_internal->fNextCab) {
cfheader.cbCabinet+=strlen(p_fci_internal->pccab->szCab)+1 +
strlen(p_fci_internal->pccab->szDisk)+1;
}
if( p_fci_internal->fNextCab ||
p_fci_internal->fGetNextCabInVain ) {
cfheader.cbCabinet+=p_fci_internal->oldCCAB.cbReserveCFHeader;
if ( p_fci_internal->oldCCAB.cbReserveCFHeader != 0 ||
p_fci_internal->oldCCAB.cbReserveCFFolder != 0 ||
p_fci_internal->oldCCAB.cbReserveCFData != 0 ) {
cfheader.cbCabinet+=4;
}
} else {
cfheader.cbCabinet+=p_fci_internal->pccab->cbReserveCFHeader;
if ( p_fci_internal->pccab->cbReserveCFHeader != 0 ||
p_fci_internal->pccab->cbReserveCFFolder != 0 ||
p_fci_internal->pccab->cbReserveCFData != 0 ) {
cfheader.cbCabinet+=4;
}
}
if( ( ( p_fci_internal->fNextCab ||
p_fci_internal->fGetNextCabInVain ) &&
cfheader.cbCabinet > p_fci_internal->oldCCAB.cb
) ||
( ( p_fci_internal->fNextCab==FALSE &&
p_fci_internal->fGetNextCabInVain==FALSE ) &&
cfheader.cbCabinet > p_fci_internal->pccab->cb
)
)
{
fci_set_error( FCIERR_NONE, ERROR_MORE_DATA, TRUE );
return FALSE;
}
cfheader.reserved2=0;
cfheader.coffFiles= /* offset to first CFFILE section */
cfheader.cbCabinet - p_fci_internal->sizeFileCFFILE2 -
p_fci_internal->sizeFileCFDATA2;
cfheader.reserved3=0;
cfheader.versionMinor=3;
cfheader.versionMajor=1;
/* number of CFFOLDER entries in the cabinet */
cfheader.cFolders=p_fci_internal->cFolders;
/* number of CFFILE entries in the cabinet */
cfheader.cFiles=p_fci_internal->cFiles;
cfheader.flags=0; /* 1=prev cab, 2=next cabinet, 4=reserved setions */
if( p_fci_internal->fPrevCab ) {
cfheader.flags = cfheadPREV_CABINET;
}
if( p_fci_internal->fNextCab ) {
cfheader.flags |= cfheadNEXT_CABINET;
}
if( p_fci_internal->fNextCab ||
p_fci_internal->fGetNextCabInVain ) {
if( p_fci_internal->oldCCAB.cbReserveCFHeader != 0 ||
p_fci_internal->oldCCAB.cbReserveCFFolder != 0 ||
p_fci_internal->oldCCAB.cbReserveCFData != 0 ) {
cfheader.flags |= cfheadRESERVE_PRESENT;
}
cfheader.setID = p_fci_internal->oldCCAB.setID;
cfheader.iCabinet = p_fci_internal->oldCCAB.iCab-1;
} else {
if( p_fci_internal->pccab->cbReserveCFHeader != 0 ||
p_fci_internal->pccab->cbReserveCFFolder != 0 ||
p_fci_internal->pccab->cbReserveCFData != 0 ) {
cfheader.flags |= cfheadRESERVE_PRESENT;
}
cfheader.setID = p_fci_internal->pccab->setID;
cfheader.iCabinet = p_fci_internal->pccab->iCab-1;
}
/* create the cabinet */
handleCABINET = PFCI_OPEN(hfci, szFileNameCABINET,
33538, 384, &err, p_fci_internal->pv );
if(handleCABINET==0){
fci_set_error( FCIERR_CAB_FILE, ERROR_OPEN_FAILED, TRUE );
return FALSE;
}
/* TODO error checking of err */
/* set little endian */
cfheader.reserved1=fci_endian_ulong(cfheader.reserved1);
cfheader.cbCabinet=fci_endian_ulong(cfheader.cbCabinet);
cfheader.reserved2=fci_endian_ulong(cfheader.reserved2);
cfheader.coffFiles=fci_endian_ulong(cfheader.coffFiles);
cfheader.reserved3=fci_endian_ulong(cfheader.reserved3);
cfheader.cFolders=fci_endian_uword(cfheader.cFolders);
cfheader.cFiles=fci_endian_uword(cfheader.cFiles);
cfheader.flags=fci_endian_uword(cfheader.flags);
cfheader.setID=fci_endian_uword(cfheader.setID);
cfheader.iCabinet=fci_endian_uword(cfheader.iCabinet);
/* write CFHEADER into cabinet file */
if( PFCI_WRITE(hfci, handleCABINET, /* file handle */
&cfheader, /* memory buffer */
sizeof(cfheader), /* number of bytes to copy */
&err, p_fci_internal->pv) != sizeof(cfheader) ) {
/* write error */
fci_set_error( FCIERR_CAB_FILE, ERROR_WRITE_FAULT, TRUE );
return FALSE;
}
/* TODO error handling of err */
/* reset little endian */
cfheader.reserved1=fci_endian_ulong(cfheader.reserved1);
cfheader.cbCabinet=fci_endian_ulong(cfheader.cbCabinet);
cfheader.reserved2=fci_endian_ulong(cfheader.reserved2);
cfheader.coffFiles=fci_endian_ulong(cfheader.coffFiles);
cfheader.reserved3=fci_endian_ulong(cfheader.reserved3);
cfheader.cFolders=fci_endian_uword(cfheader.cFolders);
cfheader.cFiles=fci_endian_uword(cfheader.cFiles);
cfheader.flags=fci_endian_uword(cfheader.flags);
cfheader.setID=fci_endian_uword(cfheader.setID);
cfheader.iCabinet=fci_endian_uword(cfheader.iCabinet);
if( cfheader.flags & cfheadRESERVE_PRESENT ) {
/* NOTE: No checks for maximum value overflows as designed by MS!!! */
cfreserved.cbCFHeader = cbReserveCFHeader;
cfreserved.cbCFFolder = cbReserveCFFolder;
if( p_fci_internal->fNextCab ||
p_fci_internal->fGetNextCabInVain ) {
cfreserved.cbCFData = p_fci_internal->oldCCAB.cbReserveCFData;
} else {
cfreserved.cbCFData = p_fci_internal->pccab->cbReserveCFData;
}
/* set little endian */
cfreserved.cbCFHeader=fci_endian_uword(cfreserved.cbCFHeader);
/* write reserved info into cabinet file */
if( PFCI_WRITE(hfci, handleCABINET, /* file handle */
&cfreserved, /* memory buffer */
sizeof(cfreserved), /* number of bytes to copy */
&err, p_fci_internal->pv) != sizeof(cfreserved) ) {
/* write error */
fci_set_error( FCIERR_CAB_FILE, ERROR_WRITE_FAULT, TRUE );
return FALSE;
}
/* TODO error handling of err */
/* reset little endian */
cfreserved.cbCFHeader=fci_endian_u
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -