cabinet: Store the CCAB data as soon as it is available.

Also add a helper function for the cabinet header size.
This commit is contained in:
Alexandre Julliard 2011-02-15 14:11:22 +01:00
parent 5dc4986dab
commit 28fce46de7

View File

@ -134,7 +134,7 @@ struct file
typedef struct typedef struct
{ {
unsigned int magic; unsigned int magic;
PERF perf; PERF perf;
PFNFCIFILEPLACED fileplaced; PFNFCIFILEPLACED fileplaced;
PFNFCIALLOC alloc; PFNFCIALLOC alloc;
PFNFCIFREE free; PFNFCIFREE free;
@ -145,6 +145,7 @@ typedef struct
PFNFCISEEK seek; PFNFCISEEK seek;
PFNFCIDELETE delete; PFNFCIDELETE delete;
PFNFCIGETTEMPFILE gettemp; PFNFCIGETTEMPFILE gettemp;
CCAB ccab;
PCCAB pccab; PCCAB pccab;
BOOL fPrevCab; BOOL fPrevCab;
BOOL fNextCab; BOOL fNextCab;
@ -155,7 +156,6 @@ typedef struct
void *pv; void *pv;
char szPrevCab[CB_MAX_CABINET_NAME]; /* previous cabinet name */ char szPrevCab[CB_MAX_CABINET_NAME]; /* previous cabinet name */
char szPrevDisk[CB_MAX_DISK_NAME]; /* disk name of previous cabinet */ char szPrevDisk[CB_MAX_DISK_NAME]; /* disk name of previous cabinet */
CCAB oldCCAB;
char* data_in; /* uncompressed data blocks */ char* data_in; /* uncompressed data blocks */
cab_UWORD cdata_in; cab_UWORD cdata_in;
char* data_out; /* compressed data blocks */ char* data_out; /* compressed data blocks */
@ -198,6 +198,23 @@ static FCI_Int *get_fci_ptr( HFCI hfci )
return fci; return fci;
} }
/* compute the cabinet header size */
static cab_ULONG get_header_size( FCI_Int *fci )
{
cab_ULONG ret = sizeof(CFHEADER) + fci->ccab.cbReserveCFHeader;
if (fci->ccab.cbReserveCFHeader || fci->ccab.cbReserveCFFolder || fci->ccab.cbReserveCFData)
ret += 4;
if (fci->fPrevCab)
ret += strlen( fci->szPrevCab ) + 1 + strlen( fci->szPrevDisk ) + 1;
if (fci->fNextCab)
ret += strlen( fci->pccab->szCab ) + 1 + strlen( fci->pccab->szDisk ) + 1;
return ret;
}
static BOOL create_temp_file( FCI_Int *fci, struct temp_file *file ) static BOOL create_temp_file( FCI_Int *fci, struct temp_file *file )
{ {
int err; int err;
@ -236,14 +253,6 @@ static BOOL close_temp_file( FCI_Int *fci, struct temp_file *file )
return TRUE; return TRUE;
} }
static cab_ULONG get_folder_size( FCI_Int *fci )
{
if (fci->fNextCab || fci->fGetNextCabInVain)
return sizeof(CFFOLDER) + fci->oldCCAB.cbReserveCFFolder;
else
return sizeof(CFFOLDER) + fci->pccab->cbReserveCFFolder;
}
static struct file *add_file( FCI_Int *fci, const char *filename ) static struct file *add_file( FCI_Int *fci, const char *filename )
{ {
unsigned int size = FIELD_OFFSET( struct file, name[strlen(filename) + 1] ); unsigned int size = FIELD_OFFSET( struct file, name[strlen(filename) + 1] );
@ -298,7 +307,7 @@ static struct folder *add_folder( FCI_Int *fci )
folder->compression = tcompTYPE_NONE; /* FIXME */ folder->compression = tcompTYPE_NONE; /* FIXME */
list_init( &folder->files_list ); list_init( &folder->files_list );
list_add_tail( &fci->folders_list, &folder->entry ); list_add_tail( &fci->folders_list, &folder->entry );
fci->folders_size += get_folder_size( fci ); fci->folders_size += sizeof(CFFOLDER) + fci->ccab.cbReserveCFFolder;
fci->cFolders++; fci->cFolders++;
return folder; return folder;
} }
@ -321,7 +330,7 @@ static BOOL write_folders( FCI_Int *fci, INT_PTR handle, cab_ULONG header_size,
BOOL ret = TRUE; BOOL ret = TRUE;
CFFILE *cffile; CFFILE *cffile;
CFFOLDER *cffolder; CFFOLDER *cffolder;
cab_ULONG file_size, folder_size = get_folder_size( fci ); cab_ULONG file_size, folder_size = sizeof(CFFOLDER) + fci->ccab.cbReserveCFFolder;
if (!(cffolder = fci->alloc( folder_size ))) if (!(cffolder = fci->alloc( folder_size )))
{ {
@ -410,12 +419,8 @@ static BOOL add_files_to_folder( FCI_Int *fci, struct folder *folder, cab_ULONG
cab_ULONG size = sizeof(CFFILE) + strlen(file->name) + 1; cab_ULONG size = sizeof(CFFILE) + strlen(file->name) + 1;
/* fnfilfnfildest: placed file on cabinet */ /* fnfilfnfildest: placed file on cabinet */
if (fci->fNextCab || fci->fGetNextCabInVain) fci->fileplaced( &fci->ccab, file->name, file->size,
fci->fileplaced( &fci->oldCCAB, file->name, file->size, (file->folder == cffileCONTINUED_FROM_PREV), fci->pv );
(file->folder == cffileCONTINUED_FROM_PREV), fci->pv );
else
fci->fileplaced( fci->pccab, file->name, file->size,
(file->folder == cffileCONTINUED_FROM_PREV), fci->pv );
sizeOfFilesPrev = sizeOfFiles; sizeOfFilesPrev = sizeOfFiles;
/* set complete size of all processed files */ /* set complete size of all processed files */
@ -568,6 +573,7 @@ HFCI __cdecl FCICreate(
p_fci_internal->seek = pfnseek; p_fci_internal->seek = pfnseek;
p_fci_internal->delete = pfndelete; p_fci_internal->delete = pfndelete;
p_fci_internal->gettemp = pfnfcigtf; p_fci_internal->gettemp = pfnfcigtf;
p_fci_internal->ccab = *pccab;
p_fci_internal->pccab = pccab; p_fci_internal->pccab = pccab;
p_fci_internal->fPrevCab = FALSE; p_fci_internal->fPrevCab = FALSE;
p_fci_internal->fNextCab = FALSE; p_fci_internal->fNextCab = FALSE;
@ -593,7 +599,6 @@ HFCI __cdecl FCICreate(
list_init( &p_fci_internal->folders_list ); list_init( &p_fci_internal->folders_list );
list_init( &p_fci_internal->files_list ); list_init( &p_fci_internal->files_list );
memset(&p_fci_internal->oldCCAB, 0, sizeof(CCAB));
memcpy(p_fci_internal->szPrevCab, pccab->szCab, CB_MAX_CABINET_NAME); memcpy(p_fci_internal->szPrevCab, pccab->szCab, CB_MAX_CABINET_NAME);
memcpy(p_fci_internal->szPrevDisk, pccab->szDisk, CB_MAX_DISK_NAME); memcpy(p_fci_internal->szPrevDisk, pccab->szDisk, CB_MAX_DISK_NAME);
@ -760,31 +765,15 @@ static BOOL fci_flushfolder_copy_cfdata(FCI_Int *p_fci_internal, char* buffer, U
return FALSE; return FALSE;
} }
} }
/* REUSE the variable read_result */
if ( p_fci_internal->oldCCAB.cbReserveCFHeader != 0 ||
p_fci_internal->oldCCAB.cbReserveCFFolder != 0 ||
p_fci_internal->oldCCAB.cbReserveCFData != 0 ) {
read_result=4;
} else {
read_result=0;
}
if (p_fci_internal->fPrevCab) {
read_result+=strlen(p_fci_internal->szPrevCab)+1 +
strlen(p_fci_internal->szPrevDisk)+1;
}
/* No more CFDATA fits into the cabinet under construction */ /* No more CFDATA fits into the cabinet under construction */
/* So don't try to store more data into it */ /* So don't try to store more data into it */
if( p_fci_internal->fNextCab && if( p_fci_internal->fNextCab &&
(p_fci_internal->oldCCAB.cb <= sizeof(CFDATA) + cbReserveCFData + (p_fci_internal->ccab.cb <= sizeof(CFDATA) + cbReserveCFData +
p_fci_internal->files_size + p_fci_internal->data2.size + p_fci_internal->files_size + p_fci_internal->data2.size +
p_fci_internal->placed_files_size + p_fci_internal->folders_size + p_fci_internal->placed_files_size + p_fci_internal->folders_size +
sizeof(CFHEADER) + get_header_size( p_fci_internal ) +
read_result + sizeof(CFFOLDER) + p_fci_internal->ccab.cbReserveCFFolder
p_fci_internal->oldCCAB.cbReserveCFHeader +
sizeof(CFFOLDER) +
p_fci_internal->oldCCAB.cbReserveCFFolder +
strlen(p_fci_internal->pccab->szCab)+1 +
strlen(p_fci_internal->pccab->szDisk)+1
)) { )) {
/* This may never be run for the first time the while loop is entered. /* This may never be run for the first time the while loop is entered.
Pray that the code that calls fci_flushfolder_copy_cfdata handles this.*/ Pray that the code that calls fci_flushfolder_copy_cfdata handles this.*/
@ -822,32 +811,14 @@ static BOOL fci_flushfolder_copy_cfdata(FCI_Int *p_fci_internal, char* buffer, U
/* if cabinet size is too large */ /* if cabinet size is too large */
/* REUSE the variable read_result */
if ( p_fci_internal->oldCCAB.cbReserveCFHeader != 0 ||
p_fci_internal->oldCCAB.cbReserveCFFolder != 0 ||
p_fci_internal->oldCCAB.cbReserveCFData != 0 ) {
read_result=4;
} else {
read_result=0;
}
if (p_fci_internal->fPrevCab) {
read_result+=strlen(p_fci_internal->szPrevCab)+1 +
strlen(p_fci_internal->szPrevDisk)+1;
}
/* Is cabinet with new CFDATA too large? Then data block has to be split */ /* Is cabinet with new CFDATA too large? Then data block has to be split */
if( p_fci_internal->fNextCab && if( p_fci_internal->fNextCab &&
(p_fci_internal->oldCCAB.cb < sizeof(CFDATA) + cbReserveCFData + (p_fci_internal->ccab.cb < sizeof(CFDATA) + cbReserveCFData +
pcfdata->cbData + pcfdata->cbData +
p_fci_internal->files_size + p_fci_internal->data2.size + p_fci_internal->files_size + p_fci_internal->data2.size +
p_fci_internal->placed_files_size + p_fci_internal->folders_size + p_fci_internal->placed_files_size + p_fci_internal->folders_size +
sizeof(CFHEADER) + get_header_size( p_fci_internal ) +
read_result + sizeof(CFFOLDER) + p_fci_internal->ccab.cbReserveCFFolder
p_fci_internal->oldCCAB.cbReserveCFHeader +
sizeof(CFFOLDER) + /* size of new CFFolder entry */
p_fci_internal->oldCCAB.cbReserveCFFolder +
strlen(p_fci_internal->pccab->szCab)+1 + /* name of next cabinet */
strlen(p_fci_internal->pccab->szDisk)+1 /* name of next disk */
)) { )) {
/* REUSE read_result to save the size of the compressed data */ /* REUSE read_result to save the size of the compressed data */
read_result=pcfdata->cbData; read_result=pcfdata->cbData;
@ -856,29 +827,15 @@ static BOOL fci_flushfolder_copy_cfdata(FCI_Int *p_fci_internal, char* buffer, U
/* that the maximum cabinet size will be exceeded. The remainder */ /* that the maximum cabinet size will be exceeded. The remainder */
/* will be stored into the next following cabinet. */ /* will be stored into the next following cabinet. */
/* The cabinet will be of size "p_fci_internal->oldCCAB.cb". */ /* The cabinet will be of size "p_fci_internal->ccab.cb". */
/* Substract everything except the size of the block of data */ /* Substract everything except the size of the block of data */
/* to get it's actual size */ /* to get it's actual size */
pcfdata->cbData = p_fci_internal->oldCCAB.cb - ( pcfdata->cbData = p_fci_internal->ccab.cb - (
sizeof(CFDATA) + cbReserveCFData + sizeof(CFDATA) + cbReserveCFData +
p_fci_internal->files_size + p_fci_internal->data2.size + p_fci_internal->files_size + p_fci_internal->data2.size +
p_fci_internal->placed_files_size + p_fci_internal->folders_size + p_fci_internal->placed_files_size + p_fci_internal->folders_size +
sizeof(CFHEADER) + get_header_size( p_fci_internal ) +
p_fci_internal->oldCCAB.cbReserveCFHeader + sizeof(CFFOLDER) + p_fci_internal->ccab.cbReserveCFFolder );
sizeof(CFFOLDER) + /* set size of new CFFolder entry */
p_fci_internal->oldCCAB.cbReserveCFFolder );
/* substract the size of special header fields */
if ( p_fci_internal->oldCCAB.cbReserveCFHeader != 0 ||
p_fci_internal->oldCCAB.cbReserveCFFolder != 0 ||
p_fci_internal->oldCCAB.cbReserveCFData != 0 ) {
pcfdata->cbData-=4;
}
if (p_fci_internal->fPrevCab) {
pcfdata->cbData-=strlen(p_fci_internal->szPrevCab)+1 +
strlen(p_fci_internal->szPrevDisk)+1;
}
pcfdata->cbData-=strlen(p_fci_internal->pccab->szCab)+1 +
strlen(p_fci_internal->pccab->szDisk)+1;
savedUncomp = pcfdata->cbUncomp; savedUncomp = pcfdata->cbUncomp;
pcfdata->cbUncomp = 0; /* on split blocks of data this is zero */ pcfdata->cbUncomp = 0; /* on split blocks of data this is zero */
@ -1134,15 +1091,8 @@ static BOOL fci_flush_folder( FCI_Int *p_fci_internal,
/* when the current function exits with return FALSE */ /* when the current function exits with return FALSE */
p_fci_internal->fSplitFolder=FALSE; p_fci_internal->fSplitFolder=FALSE;
cbReserveCFData = p_fci_internal->ccab.cbReserveCFData;
if( p_fci_internal->fGetNextCabInVain || cbReserveCFFolder = p_fci_internal->ccab.cbReserveCFFolder;
p_fci_internal->fNextCab ){
cbReserveCFData = p_fci_internal->oldCCAB.cbReserveCFData;
cbReserveCFFolder = p_fci_internal->oldCCAB.cbReserveCFFolder;
} else {
cbReserveCFData = p_fci_internal->pccab->cbReserveCFData;
cbReserveCFFolder = p_fci_internal->pccab->cbReserveCFFolder;
}
/* START of COPY */ /* START of COPY */
/* if there is data in p_fci_internal->data_in */ /* if there is data in p_fci_internal->data_in */
@ -1155,35 +1105,9 @@ static BOOL fci_flush_folder( FCI_Int *p_fci_internal,
/* actually in this cabinet ( at least partially ) */ /* actually in this cabinet ( at least partially ) */
p_fci_internal->cDataBlocks=0; p_fci_internal->cDataBlocks=0;
if ( p_fci_internal->fNextCab || p_fci_internal->statusFolderTotal = get_header_size( p_fci_internal ) +
p_fci_internal->fGetNextCabInVain ) { sizeof(CFFOLDER) + p_fci_internal->ccab.cbReserveCFFolder +
read_result= p_fci_internal->oldCCAB.cbReserveCFHeader+ p_fci_internal->placed_files_size+
p_fci_internal->oldCCAB.cbReserveCFFolder;
if ( p_fci_internal->oldCCAB.cbReserveCFHeader != 0 ||
p_fci_internal->oldCCAB.cbReserveCFFolder != 0 ||
p_fci_internal->oldCCAB.cbReserveCFData != 0 ) {
read_result+=4;
}
} else {
read_result= p_fci_internal->pccab->cbReserveCFHeader+
p_fci_internal->pccab->cbReserveCFFolder;
if ( p_fci_internal->pccab->cbReserveCFHeader != 0 ||
p_fci_internal->pccab->cbReserveCFFolder != 0 ||
p_fci_internal->pccab->cbReserveCFData != 0 ) {
read_result+=4;
}
}
if (p_fci_internal->fPrevCab) {
read_result+=strlen(p_fci_internal->szPrevCab)+1 +
strlen(p_fci_internal->szPrevDisk)+1;
}
if (p_fci_internal->fNextCab) {
read_result+=strlen(p_fci_internal->pccab->szCab)+1 +
strlen(p_fci_internal->pccab->szDisk)+1;
}
p_fci_internal->statusFolderTotal = sizeof(CFHEADER)+read_result+
sizeof(CFFOLDER) + p_fci_internal->placed_files_size+
p_fci_internal->data2.size + p_fci_internal->files_size+ p_fci_internal->data2.size + p_fci_internal->files_size+
p_fci_internal->data1.size + p_fci_internal->folders_size; p_fci_internal->data1.size + p_fci_internal->folders_size;
p_fci_internal->statusFolderCopied = 0; p_fci_internal->statusFolderCopied = 0;
@ -1200,31 +1124,11 @@ static BOOL fci_flush_folder( FCI_Int *p_fci_internal,
if (!create_temp_file( p_fci_internal, &data1new )) return FALSE; if (!create_temp_file( p_fci_internal, &data1new )) return FALSE;
/* USE the variable read_result */ /* USE the variable read_result */
if ( p_fci_internal->fNextCab || read_result = get_header_size( p_fci_internal ) + p_fci_internal->data2.size +
p_fci_internal->fGetNextCabInVain ) { p_fci_internal->placed_files_size + p_fci_internal->folders_size;
read_result= p_fci_internal->oldCCAB.cbReserveCFHeader;
if ( p_fci_internal->oldCCAB.cbReserveCFHeader != 0 ||
p_fci_internal->oldCCAB.cbReserveCFFolder != 0 ||
p_fci_internal->oldCCAB.cbReserveCFData != 0 ) {
read_result+=4;
}
} else {
read_result= p_fci_internal->pccab->cbReserveCFHeader;
if ( p_fci_internal->pccab->cbReserveCFHeader != 0 ||
p_fci_internal->pccab->cbReserveCFFolder != 0 ||
p_fci_internal->pccab->cbReserveCFData != 0 ) {
read_result+=4;
}
}
if (p_fci_internal->fPrevCab) {
read_result+=strlen(p_fci_internal->szPrevCab)+1 +
strlen(p_fci_internal->szPrevDisk)+1;
}
read_result+= sizeof(CFHEADER) + p_fci_internal->data2.size +
p_fci_internal->placed_files_size + p_fci_internal->folders_size;
if(p_fci_internal->files_size!=0) { if(p_fci_internal->files_size!=0) {
read_result+= sizeof(CFFOLDER)+p_fci_internal->pccab->cbReserveCFFolder; read_result+= sizeof(CFFOLDER)+p_fci_internal->ccab.cbReserveCFFolder;
} }
/* Check if multiple cabinets have to be created. */ /* Check if multiple cabinets have to be created. */
@ -1239,7 +1143,7 @@ static BOOL fci_flush_folder( FCI_Int *p_fci_internal,
p_fci_internal->fNextCab==FALSE && p_fci_internal->fNextCab==FALSE &&
( (
( (
p_fci_internal->pccab->cb < read_result + p_fci_internal->ccab.cb < read_result +
p_fci_internal->data1.size + p_fci_internal->data1.size +
p_fci_internal->files_size + p_fci_internal->files_size +
CB_MAX_CABINET_NAME + /* next cabinet name */ CB_MAX_CABINET_NAME + /* next cabinet name */
@ -1247,8 +1151,6 @@ static BOOL fci_flush_folder( FCI_Int *p_fci_internal,
) || fGetNextCab ) || fGetNextCab
) )
) { ) {
/* save CCAB */
p_fci_internal->oldCCAB = *p_fci_internal->pccab;
/* increment cabinet index */ /* increment cabinet index */
++(p_fci_internal->pccab->iCab); ++(p_fci_internal->pccab->iCab);
/* get name of next cabinet */ /* get name of next cabinet */
@ -1270,7 +1172,7 @@ static BOOL fci_flush_folder( FCI_Int *p_fci_internal,
p_fci_internal->fNextCab ) && p_fci_internal->fNextCab ) &&
( (
( (
p_fci_internal->oldCCAB.cb < read_result + p_fci_internal->ccab.cb < read_result +
p_fci_internal->data1.size + p_fci_internal->data1.size +
p_fci_internal->files_size + p_fci_internal->files_size +
strlen(p_fci_internal->pccab->szCab)+1 + /* next cabinet name */ strlen(p_fci_internal->pccab->szCab)+1 + /* next cabinet name */
@ -1283,7 +1185,7 @@ static BOOL fci_flush_folder( FCI_Int *p_fci_internal,
/* return FALSE if there is not enough space left*/ /* return FALSE if there is not enough space left*/
/* this should never happen */ /* this should never happen */
if (p_fci_internal->oldCCAB.cb <= if (p_fci_internal->ccab.cb <=
p_fci_internal->files_size + p_fci_internal->files_size +
read_result + read_result +
strlen(p_fci_internal->pccab->szCab)+1 + /* next cabinet name */ strlen(p_fci_internal->pccab->szCab)+1 + /* next cabinet name */
@ -1400,81 +1302,21 @@ static BOOL fci_flush_cabinet( FCI_Int *p_fci_internal,
return FALSE; return FALSE;
} }
if( p_fci_internal->fNextCab || cbReserveCFFolder=p_fci_internal->ccab.cbReserveCFFolder;
p_fci_internal->fGetNextCabInVain ) { cbReserveCFHeader=p_fci_internal->ccab.cbReserveCFHeader;
cbReserveCFFolder=p_fci_internal->oldCCAB.cbReserveCFFolder; /* get the full name of the cabinet */
cbReserveCFHeader=p_fci_internal->oldCCAB.cbReserveCFHeader; memcpy(szFileNameCABINET,p_fci_internal->ccab.szCabPath, CB_MAX_CAB_PATH);
/* safety */ memcpy(szFileNameCABINET+strlen(szFileNameCABINET), p_fci_internal->ccab.szCab, CB_MAX_CABINET_NAME);
if (strlen(p_fci_internal->oldCCAB.szCabPath)>=CB_MAX_CAB_PATH ||
strlen(p_fci_internal->oldCCAB.szCab)>=CB_MAX_CABINET_NAME) {
/* set error */
set_error( p_fci_internal, FCIERR_NONE, ERROR_INVALID_DATA );
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 */
set_error( p_fci_internal, FCIERR_NONE, ERROR_INVALID_DATA );
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); memcpy(cfheader.signature,"!CAB",4);
cfheader.reserved1=0; cfheader.reserved1=0;
cfheader.cbCabinet= /* size of the cabinet file in bytes */ cfheader.cbCabinet= /* size of the cabinet file in bytes */
sizeof(CFHEADER) + get_header_size( p_fci_internal ) +
p_fci_internal->folders_size + p_fci_internal->folders_size +
p_fci_internal->placed_files_size + p_fci_internal->placed_files_size +
p_fci_internal->data2.size; p_fci_internal->data2.size;
if (p_fci_internal->fPrevCab) { if (cfheader.cbCabinet > p_fci_internal->ccab.cb)
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
)
)
{ {
set_error( p_fci_internal, FCIERR_NONE, ERROR_MORE_DATA ); set_error( p_fci_internal, FCIERR_NONE, ERROR_MORE_DATA );
return FALSE; return FALSE;
@ -1503,24 +1345,12 @@ static BOOL fci_flush_cabinet( FCI_Int *p_fci_internal,
cfheader.flags |= cfheadNEXT_CABINET; cfheader.flags |= cfheadNEXT_CABINET;
} }
if( p_fci_internal->fNextCab || if( p_fci_internal->ccab.cbReserveCFHeader != 0 ||
p_fci_internal->fGetNextCabInVain ) { p_fci_internal->ccab.cbReserveCFFolder != 0 ||
if( p_fci_internal->oldCCAB.cbReserveCFHeader != 0 || p_fci_internal->ccab.cbReserveCFData != 0 )
p_fci_internal->oldCCAB.cbReserveCFFolder != 0 ||
p_fci_internal->oldCCAB.cbReserveCFData != 0 ) {
cfheader.flags |= cfheadRESERVE_PRESENT; cfheader.flags |= cfheadRESERVE_PRESENT;
} cfheader.setID = p_fci_internal->ccab.setID;
cfheader.setID = p_fci_internal->oldCCAB.setID; cfheader.iCabinet = p_fci_internal->ccab.iCab-1;
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 */ /* create the cabinet */
handleCABINET = p_fci_internal->open( szFileNameCABINET, _O_RDWR | _O_CREAT | _O_TRUNC | _O_BINARY, handleCABINET = p_fci_internal->open( szFileNameCABINET, _O_RDWR | _O_CREAT | _O_TRUNC | _O_BINARY,
@ -1571,12 +1401,7 @@ static BOOL fci_flush_cabinet( FCI_Int *p_fci_internal,
/* NOTE: No checks for maximum value overflows as designed by MS!!! */ /* NOTE: No checks for maximum value overflows as designed by MS!!! */
cfreserved.cbCFHeader = cbReserveCFHeader; cfreserved.cbCFHeader = cbReserveCFHeader;
cfreserved.cbCFFolder = cbReserveCFFolder; cfreserved.cbCFFolder = cbReserveCFFolder;
if( p_fci_internal->fNextCab || cfreserved.cbCFData = p_fci_internal->ccab.cbReserveCFData;
p_fci_internal->fGetNextCabInVain ) {
cfreserved.cbCFData = p_fci_internal->oldCCAB.cbReserveCFData;
} else {
cfreserved.cbCFData = p_fci_internal->pccab->cbReserveCFData;
}
/* set little endian */ /* set little endian */
cfreserved.cbCFHeader=fci_endian_uword(cfreserved.cbCFHeader); cfreserved.cbCFHeader=fci_endian_uword(cfreserved.cbCFHeader);
@ -1663,38 +1488,8 @@ static BOOL fci_flush_cabinet( FCI_Int *p_fci_internal,
} }
/* add size of header size of all CFFOLDERs and size of all CFFILEs */ /* add size of header size of all CFFOLDERs and size of all CFFILEs */
header_size = p_fci_internal->placed_files_size + p_fci_internal->folders_size + sizeof(CFHEADER); header_size = get_header_size( p_fci_internal ) +
if( p_fci_internal->fNextCab || p_fci_internal->fGetNextCabInVain ) { p_fci_internal->placed_files_size + p_fci_internal->folders_size;
header_size+=p_fci_internal->oldCCAB.cbReserveCFHeader;
} else {
header_size+=p_fci_internal->pccab->cbReserveCFHeader;
}
if (p_fci_internal->fPrevCab) {
header_size += strlen(p_fci_internal->szPrevCab)+1 +
strlen(p_fci_internal->szPrevDisk)+1;
}
if (p_fci_internal->fNextCab) {
header_size += strlen(p_fci_internal->oldCCAB.szCab)+1 +
strlen(p_fci_internal->oldCCAB.szDisk)+1;
}
if( p_fci_internal->fNextCab || p_fci_internal->fGetNextCabInVain ) {
header_size += p_fci_internal->oldCCAB.cbReserveCFHeader;
if( p_fci_internal->oldCCAB.cbReserveCFHeader != 0 ||
p_fci_internal->oldCCAB.cbReserveCFFolder != 0 ||
p_fci_internal->oldCCAB.cbReserveCFData != 0 ) {
header_size += 4;
}
} else {
header_size += p_fci_internal->pccab->cbReserveCFHeader;
if( p_fci_internal->pccab->cbReserveCFHeader != 0 ||
p_fci_internal->pccab->cbReserveCFFolder != 0 ||
p_fci_internal->pccab->cbReserveCFData != 0 ) {
header_size += 4;
}
}
if (!write_folders( p_fci_internal, handleCABINET, header_size, pfnfcis )) return FALSE; if (!write_folders( p_fci_internal, handleCABINET, header_size, pfnfcis )) return FALSE;
@ -1799,51 +1594,28 @@ static BOOL fci_flush_cabinet( FCI_Int *p_fci_internal,
return FALSE; return FALSE;
} }
/* COPIED FROM FCIAddFile and modified */ if( p_fci_internal->fNewPrevious ) {
memcpy(p_fci_internal->szPrevCab, p_fci_internal->ccab.szCab,
CB_MAX_CABINET_NAME);
memcpy(p_fci_internal->szPrevDisk, p_fci_internal->ccab.szDisk,
CB_MAX_DISK_NAME);
p_fci_internal->fNewPrevious=FALSE;
}
p_fci_internal->ccab = *p_fci_internal->pccab;
/* REUSE the variable read_result */ /* REUSE the variable read_result */
if (p_fci_internal->fGetNextCabInVain) { read_result=get_header_size( p_fci_internal );
read_result=p_fci_internal->oldCCAB.cbReserveCFHeader; if(p_fci_internal->files_size!=0) {
if(p_fci_internal->files_size!=0) { read_result+=p_fci_internal->ccab.cbReserveCFFolder;
read_result+=p_fci_internal->oldCCAB.cbReserveCFFolder;
}
if ( p_fci_internal->oldCCAB.cbReserveCFHeader != 0 ||
p_fci_internal->oldCCAB.cbReserveCFFolder != 0 ||
p_fci_internal->oldCCAB.cbReserveCFData != 0 ) {
read_result+=4;
}
} else {
read_result=p_fci_internal->pccab->cbReserveCFHeader;
if(p_fci_internal->files_size!=0) {
read_result+=p_fci_internal->pccab->cbReserveCFFolder;
}
if ( p_fci_internal->pccab->cbReserveCFHeader != 0 ||
p_fci_internal->pccab->cbReserveCFFolder != 0 ||
p_fci_internal->pccab->cbReserveCFData != 0 ) {
read_result+=4;
}
}
if ( p_fci_internal->fPrevCab ) {
read_result+= strlen(p_fci_internal->szPrevCab)+1+
strlen(p_fci_internal->szPrevDisk)+1;
} }
read_result+= p_fci_internal->data1.size + read_result+= p_fci_internal->data1.size +
p_fci_internal->files_size + p_fci_internal->data2.size + p_fci_internal->files_size + p_fci_internal->data2.size +
p_fci_internal->placed_files_size + p_fci_internal->folders_size + p_fci_internal->placed_files_size + p_fci_internal->folders_size +
sizeof(CFHEADER) +
sizeof(CFFOLDER); /* set size of new CFFolder entry */ sizeof(CFFOLDER); /* set size of new CFFolder entry */
if( p_fci_internal->fNewPrevious ) {
memcpy(p_fci_internal->szPrevCab, p_fci_internal->oldCCAB.szCab,
CB_MAX_CABINET_NAME);
memcpy(p_fci_internal->szPrevDisk, p_fci_internal->oldCCAB.szDisk,
CB_MAX_DISK_NAME);
p_fci_internal->fNewPrevious=FALSE;
}
/* too much data for the maximum size of a cabinet */ /* too much data for the maximum size of a cabinet */
if( p_fci_internal->fGetNextCabInVain==FALSE && if( p_fci_internal->fGetNextCabInVain==FALSE &&
p_fci_internal->pccab->cb < read_result ) { p_fci_internal->ccab.cb < read_result ) {
return fci_flush_cabinet( p_fci_internal, FALSE, pfnfcignc, pfnfcis); return fci_flush_cabinet( p_fci_internal, FALSE, pfnfcignc, pfnfcis);
} }
@ -1854,11 +1626,9 @@ static BOOL fci_flush_cabinet( FCI_Int *p_fci_internal,
/* cabinet and name of the corresponding disk. */ /* cabinet and name of the corresponding disk. */
/* So take care of this and get the name of the next cabinet */ /* So take care of this and get the name of the next cabinet */
if (p_fci_internal->fGetNextCabInVain==FALSE && ( if (p_fci_internal->fGetNextCabInVain==FALSE && (
p_fci_internal->pccab->cb < read_result + p_fci_internal->ccab.cb < read_result +
CB_MAX_CABINET_NAME + CB_MAX_DISK_NAME CB_MAX_CABINET_NAME + CB_MAX_DISK_NAME
)) { )) {
/* save CCAB */
p_fci_internal->oldCCAB = *p_fci_internal->pccab;
/* increment cabinet index */ /* increment cabinet index */
++(p_fci_internal->pccab->iCab); ++(p_fci_internal->pccab->iCab);
/* get name of next cabinet */ /* get name of next cabinet */
@ -1876,9 +1646,9 @@ static BOOL fci_flush_cabinet( FCI_Int *p_fci_internal,
/* too much data for cabinet */ /* too much data for cabinet */
if (p_fci_internal->fGetNextCabInVain && ( if (p_fci_internal->fGetNextCabInVain && (
p_fci_internal->oldCCAB.cb < read_result + p_fci_internal->ccab.cb < read_result +
strlen(p_fci_internal->oldCCAB.szCab)+1+ strlen(p_fci_internal->ccab.szCab)+1+
strlen(p_fci_internal->oldCCAB.szDisk)+1 strlen(p_fci_internal->ccab.szDisk)+1
)) { )) {
p_fci_internal->fGetNextCabInVain=FALSE; p_fci_internal->fGetNextCabInVain=FALSE;
p_fci_internal->fNextCab=TRUE; p_fci_internal->fNextCab=TRUE;
@ -1886,19 +1656,8 @@ static BOOL fci_flush_cabinet( FCI_Int *p_fci_internal,
} }
/* if the FolderThreshold has been reached flush the folder automatically */ /* if the FolderThreshold has been reached flush the folder automatically */
if( p_fci_internal->fGetNextCabInVain ) { if (p_fci_internal->cCompressedBytesInFolder >= p_fci_internal->ccab.cbFolderThresh)
if( p_fci_internal->cCompressedBytesInFolder >=
p_fci_internal->oldCCAB.cbFolderThresh) {
return fci_flush_folder(p_fci_internal, FALSE, pfnfcignc, pfnfcis); return fci_flush_folder(p_fci_internal, FALSE, pfnfcignc, pfnfcis);
}
} else {
if( p_fci_internal->cCompressedBytesInFolder >=
p_fci_internal->pccab->cbFolderThresh) {
return fci_flush_folder(p_fci_internal, FALSE, pfnfcignc, pfnfcis);
}
}
/* END OF COPIED FROM FCIAddFile and modified */
if( p_fci_internal->files_size>0 ) { if( p_fci_internal->files_size>0 ) {
if( !fci_flush_folder(p_fci_internal, FALSE, pfnfcignc, pfnfcis) ) return FALSE; if( !fci_flush_folder(p_fci_internal, FALSE, pfnfcignc, pfnfcis) ) return FALSE;
@ -2035,36 +1794,11 @@ BOOL __cdecl FCIAddFile(
if (fExecute) { file->attribs |= _A_EXEC; } if (fExecute) { file->attribs |= _A_EXEC; }
/* REUSE the variable read_result */ /* REUSE the variable read_result */
if (p_fci_internal->fGetNextCabInVain) { read_result=get_header_size( p_fci_internal ) + p_fci_internal->ccab.cbReserveCFFolder;
read_result=p_fci_internal->oldCCAB.cbReserveCFHeader +
p_fci_internal->oldCCAB.cbReserveCFFolder;
if ( p_fci_internal->oldCCAB.cbReserveCFHeader != 0 ||
p_fci_internal->oldCCAB.cbReserveCFFolder != 0 ||
p_fci_internal->oldCCAB.cbReserveCFData != 0 ) {
read_result+=4;
}
} else {
read_result=p_fci_internal->pccab->cbReserveCFHeader +
p_fci_internal->pccab->cbReserveCFFolder;
if ( p_fci_internal->pccab->cbReserveCFHeader != 0 ||
p_fci_internal->pccab->cbReserveCFFolder != 0 ||
p_fci_internal->pccab->cbReserveCFData != 0 ) {
read_result+=4;
}
}
if ( p_fci_internal->fPrevCab ) {
read_result+= strlen(p_fci_internal->szPrevCab)+1+
strlen(p_fci_internal->szPrevDisk)+1;
}
if ( p_fci_internal->fNextCab ) { /* this is never the case */
read_result+= strlen(p_fci_internal->pccab->szCab)+1+
strlen(p_fci_internal->pccab->szDisk)+1;
}
read_result+= sizeof(CFFILE) + strlen(pszFileName)+1 + read_result+= sizeof(CFFILE) + strlen(pszFileName)+1 +
p_fci_internal->files_size + p_fci_internal->data2.size + p_fci_internal->files_size + p_fci_internal->data2.size +
p_fci_internal->placed_files_size + p_fci_internal->folders_size + p_fci_internal->placed_files_size + p_fci_internal->folders_size +
sizeof(CFHEADER) +
sizeof(CFFOLDER); /* size of new CFFolder entry */ sizeof(CFFOLDER); /* size of new CFFolder entry */
/* Might be too much data for the maximum size of a cabinet.*/ /* Might be too much data for the maximum size of a cabinet.*/
@ -2075,12 +1809,10 @@ BOOL __cdecl FCIAddFile(
/* So take care of this and get the name of the next cabinet */ /* So take care of this and get the name of the next cabinet */
if( p_fci_internal->fGetNextCabInVain==FALSE && if( p_fci_internal->fGetNextCabInVain==FALSE &&
p_fci_internal->fNextCab==FALSE && p_fci_internal->fNextCab==FALSE &&
( p_fci_internal->pccab->cb < read_result + ( p_fci_internal->ccab.cb < read_result +
CB_MAX_CABINET_NAME + CB_MAX_DISK_NAME CB_MAX_CABINET_NAME + CB_MAX_DISK_NAME
) )
) { ) {
/* save CCAB */
p_fci_internal->oldCCAB = *p_fci_internal->pccab;
/* increment cabinet index */ /* increment cabinet index */
++(p_fci_internal->pccab->iCab); ++(p_fci_internal->pccab->iCab);
/* get name of next cabinet */ /* get name of next cabinet */
@ -2108,7 +1840,7 @@ BOOL __cdecl FCIAddFile(
/* too much data for cabinet */ /* too much data for cabinet */
if( p_fci_internal->fGetNextCabInVain && if( p_fci_internal->fGetNextCabInVain &&
( (
p_fci_internal->oldCCAB.cb < read_result + p_fci_internal->ccab.cb < read_result +
strlen(p_fci_internal->pccab->szCab)+1+ strlen(p_fci_internal->pccab->szCab)+1+
strlen(p_fci_internal->pccab->szDisk)+1 strlen(p_fci_internal->pccab->szDisk)+1
)) { )) {
@ -2165,44 +1897,17 @@ BOOL __cdecl FCIAddFile(
p_fci_internal->files_size += sizeof(CFFILE) + strlen(pszFileName)+1; p_fci_internal->files_size += sizeof(CFFILE) + strlen(pszFileName)+1;
/* REUSE the variable read_result */ /* REUSE the variable read_result */
if (p_fci_internal->fGetNextCabInVain || read_result = get_header_size( p_fci_internal ) + p_fci_internal->ccab.cbReserveCFFolder;
p_fci_internal->fNextCab
) {
read_result=p_fci_internal->oldCCAB.cbReserveCFHeader +
p_fci_internal->oldCCAB.cbReserveCFFolder;
if ( p_fci_internal->oldCCAB.cbReserveCFHeader != 0 ||
p_fci_internal->oldCCAB.cbReserveCFFolder != 0 ||
p_fci_internal->oldCCAB.cbReserveCFData != 0 ) {
read_result+=4;
}
} else {
read_result=p_fci_internal->pccab->cbReserveCFHeader +
p_fci_internal->pccab->cbReserveCFFolder;
if ( p_fci_internal->pccab->cbReserveCFHeader != 0 ||
p_fci_internal->pccab->cbReserveCFFolder != 0 ||
p_fci_internal->pccab->cbReserveCFData != 0 ) {
read_result+=4;
}
}
if ( p_fci_internal->fPrevCab ) {
read_result+= strlen(p_fci_internal->szPrevCab)+1+
strlen(p_fci_internal->szPrevDisk)+1;
}
if ( p_fci_internal->fNextCab ) { /* this is never the case */
read_result+= strlen(p_fci_internal->pccab->szCab)+1+
strlen(p_fci_internal->pccab->szDisk)+1;
}
read_result+= p_fci_internal->data1.size + read_result+= p_fci_internal->data1.size +
p_fci_internal->files_size + p_fci_internal->data2.size + p_fci_internal->files_size + p_fci_internal->data2.size +
p_fci_internal->placed_files_size + p_fci_internal->folders_size + p_fci_internal->placed_files_size + p_fci_internal->folders_size +
sizeof(CFHEADER) +
sizeof(CFFOLDER); /* set size of new CFFolder entry */ sizeof(CFFOLDER); /* set size of new CFFolder entry */
/* too much data for the maximum size of a cabinet */ /* too much data for the maximum size of a cabinet */
/* (ignoring the unflushed data block) */ /* (ignoring the unflushed data block) */
if( p_fci_internal->fGetNextCabInVain==FALSE && if( p_fci_internal->fGetNextCabInVain==FALSE &&
p_fci_internal->fNextCab==FALSE && /* this is always the case */ p_fci_internal->fNextCab==FALSE && /* this is always the case */
p_fci_internal->pccab->cb < read_result ) { p_fci_internal->ccab.cb < read_result ) {
return fci_flush_cabinet( p_fci_internal, FALSE, pfnfcignc, pfnfcis); return fci_flush_cabinet( p_fci_internal, FALSE, pfnfcignc, pfnfcis);
} }
@ -2215,12 +1920,10 @@ BOOL __cdecl FCIAddFile(
/* (ignoring the unflushed data block) */ /* (ignoring the unflushed data block) */
if( p_fci_internal->fGetNextCabInVain==FALSE && if( p_fci_internal->fGetNextCabInVain==FALSE &&
p_fci_internal->fNextCab==FALSE && p_fci_internal->fNextCab==FALSE &&
( p_fci_internal->pccab->cb < read_result + ( p_fci_internal->ccab.cb < read_result +
CB_MAX_CABINET_NAME + CB_MAX_DISK_NAME CB_MAX_CABINET_NAME + CB_MAX_DISK_NAME
) )
) { ) {
/* save CCAB */
p_fci_internal->oldCCAB = *p_fci_internal->pccab;
/* increment cabinet index */ /* increment cabinet index */
++(p_fci_internal->pccab->iCab); ++(p_fci_internal->pccab->iCab);
/* get name of next cabinet */ /* get name of next cabinet */
@ -2247,7 +1950,7 @@ BOOL __cdecl FCIAddFile(
/* too much data for cabinet */ /* too much data for cabinet */
if( (p_fci_internal->fGetNextCabInVain || if( (p_fci_internal->fGetNextCabInVain ||
p_fci_internal->fNextCab) && ( p_fci_internal->fNextCab) && (
p_fci_internal->oldCCAB.cb < read_result + p_fci_internal->ccab.cb < read_result +
strlen(p_fci_internal->pccab->szCab)+1+ strlen(p_fci_internal->pccab->szCab)+1+
strlen(p_fci_internal->pccab->szDisk)+1 strlen(p_fci_internal->pccab->szDisk)+1
)) { )) {
@ -2265,17 +1968,8 @@ BOOL __cdecl FCIAddFile(
} }
/* if the FolderThreshold has been reached flush the folder automatically */ /* if the FolderThreshold has been reached flush the folder automatically */
if( p_fci_internal->fGetNextCabInVain ) { if (p_fci_internal->cCompressedBytesInFolder >= p_fci_internal->ccab.cbFolderThresh)
if( p_fci_internal->cCompressedBytesInFolder >=
p_fci_internal->oldCCAB.cbFolderThresh) {
return FCIFlushFolder(hfci, pfnfcignc, pfnfcis); return FCIFlushFolder(hfci, pfnfcignc, pfnfcis);
}
} else {
if( p_fci_internal->cCompressedBytesInFolder >=
p_fci_internal->pccab->cbFolderThresh) {
return FCIFlushFolder(hfci, pfnfcignc, pfnfcis);
}
}
return TRUE; return TRUE;
} /* end of FCIAddFile */ } /* end of FCIAddFile */