ReactOS 0.4.17-dev-804-g023d8af
fci.c File Reference
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <zlib.h>
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "winternl.h"
#include "fci.h"
#include "cabinet.h"
#include "wine/list.h"
#include "wine/debug.h"
Include dependency graph for fci.c:

Go to the source code of this file.

Classes

struct  CFHEADER
 
struct  CFFOLDER
 
struct  CFFILE
 
struct  CFDATA
 
struct  temp_file
 
struct  folder
 
struct  file
 
struct  data_block
 
struct  FCI_Int
 

Macros

#define fci_endian_ulong(x)   (x)
 
#define fci_endian_uword(x)   (x)
 
#define FCI_INT_MAGIC   0xfcfcfc05
 

Typedefs

typedef struct FCI_Int FCI_Int
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (cabinet)
 
static void set_error (FCI_Int *fci, int oper, int err)
 
static FCI_Intget_fci_ptr (HFCI hfci)
 
static cab_ULONG get_header_size (FCI_Int *fci)
 
static BOOL create_temp_file (FCI_Int *fci, struct temp_file *file)
 
static BOOL close_temp_file (FCI_Int *fci, struct temp_file *file)
 
static struct fileadd_file (FCI_Int *fci, const char *filename)
 
static struct filecopy_file (FCI_Int *fci, const struct file *orig)
 
static void free_file (FCI_Int *fci, struct file *file)
 
static BOOL add_data_block (FCI_Int *fci, PFNFCISTATUS status_callback)
 
static BOOL add_file_data (FCI_Int *fci, char *sourcefile, char *filename, BOOL execute, PFNFCIGETOPENINFO get_open_info, PFNFCISTATUS status_callback)
 
static void free_data_block (FCI_Int *fci, struct data_block *block)
 
static struct folderadd_folder (FCI_Int *fci)
 
static void free_folder (FCI_Int *fci, struct folder *folder)
 
static void reset_cabinet (FCI_Int *fci)
 
static cab_ULONG fci_get_checksum (const void *pv, UINT cb, cab_ULONG seed)
 
static BOOL copy_data_blocks (FCI_Int *fci, INT_PTR handle, cab_ULONG start_pos, struct temp_file *temp, PFNFCISTATUS status_callback)
 
static BOOL write_folders (FCI_Int *fci, INT_PTR handle, cab_ULONG header_size, PFNFCISTATUS status_callback)
 
static BOOL write_files (FCI_Int *fci, INT_PTR handle, PFNFCISTATUS status_callback)
 
static BOOL write_data_blocks (FCI_Int *fci, INT_PTR handle, PFNFCISTATUS status_callback)
 
static BOOL write_cabinet (FCI_Int *fci, PFNFCISTATUS status_callback)
 
static BOOL add_data_to_folder (FCI_Int *fci, struct folder *folder, cab_ULONG *payload, PFNFCISTATUS status_callback)
 
static BOOL add_files_to_folder (FCI_Int *fci, struct folder *folder, cab_ULONG payload)
 
static cab_UWORD compress_NONE (FCI_Int *fci)
 
static voidzalloc (void *opaque, unsigned int items, unsigned int size)
 
static void zfree (void *opaque, void *ptr)
 
static cab_UWORD compress_MSZIP (FCI_Int *fci)
 
HFCI __cdecl FCICreate (PERF perf, PFNFCIFILEPLACED pfnfiledest, PFNFCIALLOC pfnalloc, PFNFCIFREE pfnfree, PFNFCIOPEN pfnopen, PFNFCIREAD pfnread, PFNFCIWRITE pfnwrite, PFNFCICLOSE pfnclose, PFNFCISEEK pfnseek, PFNFCIDELETE pfndelete, PFNFCIGETTEMPFILE pfnfcigtf, PCCAB pccab, void *pv)
 
static BOOL fci_flush_folder (FCI_Int *p_fci_internal, BOOL fGetNextCab, PFNFCIGETNEXTCABINET pfnfcignc, PFNFCISTATUS pfnfcis)
 
static BOOL fci_flush_cabinet (FCI_Int *p_fci_internal, BOOL fGetNextCab, PFNFCIGETNEXTCABINET pfnfcignc, PFNFCISTATUS pfnfcis)
 
BOOL __cdecl FCIAddFile (HFCI hfci, char *pszSourceFile, char *pszFileName, BOOL fExecute, PFNFCIGETNEXTCABINET pfnfcignc, PFNFCISTATUS pfnfcis, PFNFCIGETOPENINFO pfnfcigoi, TCOMP typeCompress)
 
BOOL __cdecl FCIFlushFolder (HFCI hfci, PFNFCIGETNEXTCABINET pfnfcignc, PFNFCISTATUS pfnfcis)
 
BOOL __cdecl FCIFlushCabinet (HFCI hfci, BOOL fGetNextCab, PFNFCIGETNEXTCABINET pfnfcignc, PFNFCISTATUS pfnfcis)
 
BOOL __cdecl FCIDestroy (HFCI hfci)
 

Macro Definition Documentation

◆ fci_endian_ulong

#define fci_endian_ulong (   x)    (x)

Definition at line 56 of file fci.c.

◆ fci_endian_uword

#define fci_endian_uword (   x)    (x)

Definition at line 57 of file fci.c.

◆ FCI_INT_MAGIC

#define FCI_INT_MAGIC   0xfcfcfc05

Definition at line 190 of file fci.c.

Typedef Documentation

◆ FCI_Int

Function Documentation

◆ add_data_block()

static BOOL add_data_block ( FCI_Int fci,
PFNFCISTATUS  status_callback 
)
static

Definition at line 309 of file fci.c.

310{
311 int err;
312 struct data_block *block;
313
314 if (!fci->cdata_in) return TRUE;
315
316 if (fci->data.handle == -1 && !create_temp_file( fci, &fci->data )) return FALSE;
317
318 if (!(block = fci->alloc( sizeof(*block) )))
319 {
321 return FALSE;
322 }
323 block->uncompressed = fci->cdata_in;
324 block->compressed = fci->compress( fci );
325
326 if (fci->write( fci->data.handle, fci->data_out,
327 block->compressed, &err, fci->pv ) != block->compressed)
328 {
330 fci->free( block );
331 return FALSE;
332 }
333
334 fci->cdata_in = 0;
335 fci->pending_data_size += sizeof(CFDATA) + fci->ccab.cbReserveCFData + block->compressed;
336 fci->cCompressedBytesInFolder += block->compressed;
337 fci->cDataBlocks++;
338 list_add_tail( &fci->blocks_list, &block->entry );
339
340 if (status_callback( statusFile, block->compressed, block->uncompressed, fci->pv ) == -1)
341 {
342 set_error( fci, FCIERR_USER_ABORT, 0 );
343 return FALSE;
344 }
345 return TRUE;
346}
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static void set_error(FCI_Int *fci, int oper, int err)
Definition: fci.c:192
static BOOL create_temp_file(FCI_Int *fci, struct temp_file *file)
Definition: fci.c:229
#define statusFile
Definition: fci.h:219
@ FCIERR_TEMP_FILE
Definition: fci.h:121
@ FCIERR_USER_ABORT
Definition: fci.h:124
@ FCIERR_ALLOC_FAIL
Definition: fci.h:120
static void WINAPI status_callback(HINTERNET handle, DWORD_PTR ctx, DWORD status, LPVOID info, DWORD info_len)
Definition: ftp.c:948
#define err(...)
UINT cbReserveCFData
Definition: fci.h:150
Definition: fci.c:97
PFNFCIFREE free
Definition: fci.c:147
void * pv
Definition: fci.c:163
PFNFCIWRITE write
Definition: fci.c:150
unsigned char data_out[2 *CAB_BLOCKMAX]
Definition: fci.c:167
struct temp_file data
Definition: fci.c:175
cab_ULONG pending_data_size
Definition: fci.c:184
cab_UWORD cdata_in
Definition: fci.c:168
PFNFCIALLOC alloc
Definition: fci.c:146
CCAB ccab
Definition: fci.c:155
ULONG cCompressedBytesInFolder
Definition: fci.c:169
struct list blocks_list
Definition: fci.c:180
cab_UWORD(* compress)(struct FCI_Int *)
Definition: fci.c:187
cab_ULONG cDataBlocks
Definition: fci.c:172
static unsigned int block
Definition: xmlmemory.c:101

Referenced by add_file_data(), and fci_flush_folder().

◆ add_data_to_folder()

static BOOL add_data_to_folder ( FCI_Int fci,
struct folder folder,
cab_ULONG payload,
PFNFCISTATUS  status_callback 
)
static

Definition at line 758 of file fci.c.

760{
761 struct data_block *block, *new, *next;
762 BOOL split_block = FALSE;
763 cab_ULONG current_size, start_pos = 0;
764
765 *payload = 0;
766 current_size = get_header_size( fci ) + fci->folders_size +
768
769 /* move the temp file into the folder structure */
770 folder->data = fci->data;
771 fci->data.handle = -1;
772 fci->pending_data_size = 0;
773
775 {
776 /* No more CFDATA fits into the cabinet under construction */
777 /* So don't try to store more data into it */
778 if (fci->fNextCab && (fci->ccab.cb <= sizeof(CFDATA) + fci->ccab.cbReserveCFData +
779 current_size + sizeof(CFFOLDER) + fci->ccab.cbReserveCFFolder))
780 break;
781
782 if (!(new = fci->alloc( sizeof(*new) )))
783 {
785 return FALSE;
786 }
787 /* Is cabinet with new CFDATA too large? Then data block has to be split */
788 if( fci->fNextCab &&
789 (fci->ccab.cb < sizeof(CFDATA) + fci->ccab.cbReserveCFData +
790 block->compressed + current_size + sizeof(CFFOLDER) + fci->ccab.cbReserveCFFolder))
791 {
792 /* Modify the size of the compressed data to store only a part of the */
793 /* data block into the current cabinet. This is done to prevent */
794 /* that the maximum cabinet size will be exceeded. The remainder */
795 /* will be stored into the next following cabinet. */
796
797 new->compressed = fci->ccab.cb - (sizeof(CFDATA) + fci->ccab.cbReserveCFData + current_size +
798 sizeof(CFFOLDER) + fci->ccab.cbReserveCFFolder );
799 new->uncompressed = 0; /* on split blocks of data this is zero */
800 block->compressed -= new->compressed;
801 split_block = TRUE;
802 }
803 else
804 {
805 new->compressed = block->compressed;
806 new->uncompressed = block->uncompressed;
807 }
808
809 start_pos += new->compressed;
810 current_size += sizeof(CFDATA) + fci->ccab.cbReserveCFData + new->compressed;
811 fci->folders_data_size += sizeof(CFDATA) + fci->ccab.cbReserveCFData + new->compressed;
812 fci->statusFolderCopied += new->compressed;
813 (*payload) += new->uncompressed;
814
817
818 /* report status with pfnfcis about copied size of folder */
820 fci->statusFolderTotal, fci->pv ) == -1)
821 {
822 set_error( fci, FCIERR_USER_ABORT, 0 );
823 return FALSE;
824 }
825 if (split_block) break;
826 free_data_block( fci, block );
827 fci->cDataBlocks--;
828 }
829
830 if (list_empty( &fci->blocks_list )) return TRUE;
831 return copy_data_blocks( fci, folder->data.handle, start_pos, &fci->data, status_callback );
832}
static int list_empty(struct list_entry *head)
Definition: list.h:58
UINT32 cab_ULONG
Definition: mszip.h:27
static void free_data_block(FCI_Int *fci, struct data_block *block)
Definition: fci.c:386
static cab_ULONG get_header_size(FCI_Int *fci)
Definition: fci.c:213
static BOOL copy_data_blocks(FCI_Int *fci, INT_PTR handle, cab_ULONG start_pos, struct temp_file *temp, PFNFCISTATUS status_callback)
Definition: fci.c:481
#define statusFolder
Definition: fci.h:220
unsigned int BOOL
Definition: ntddk_ex.h:94
uint32_t entry
Definition: isohybrid.c:63
static unsigned __int64 next
Definition: rand_nt.c:6
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:204
UINT cbReserveCFFolder
Definition: fci.h:149
ULONG cb
Definition: fci.h:145
Definition: fci.c:78
cab_ULONG folders_size
Definition: fci.c:181
cab_ULONG files_size
Definition: fci.c:182
cab_ULONG statusFolderCopied
Definition: fci.c:160
cab_ULONG statusFolderTotal
Definition: fci.c:161
BOOL fNextCab
Definition: fci.c:158
cab_ULONG folders_data_size
Definition: fci.c:185
cab_ULONG placed_files_size
Definition: fci.c:183
struct list entry
Definition: wpp.c:51
Definition: fci.c:112
struct temp_file data
Definition: fci.c:116
struct list blocks_list
Definition: fci.c:115
cab_UWORD data_count
Definition: fci.c:118
#define new(TYPE, numElems)
Definition: treelist.c:54

Referenced by fci_flush_folder().

◆ add_file()

static struct file * add_file ( FCI_Int fci,
const char filename 
)
static

Definition at line 266 of file fci.c.

267{
268 unsigned int size = FIELD_OFFSET( struct file, name[strlen(filename) + 1] );
269 struct file *file = fci->alloc( size );
270
271 if (!file)
272 {
274 return NULL;
275 }
276 file->size = 0;
278 file->folder = fci->cFolders;
279 file->date = 0;
280 file->time = 0;
281 file->attribs = 0;
284 fci->files_size += sizeof(CFFILE) + strlen(filename) + 1;
285 return file;
286}
#define NULL
Definition: types.h:112
#define CAB_BLOCKMAX
Definition: mszip.h:97
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1597
GLsizeiptr size
Definition: glext.h:5919
const char * filename
Definition: ioapi.h:137
strcpy
Definition: string.h:131
Definition: fci.c:85
struct list files_list
Definition: fci.c:179
cab_UWORD cFolders
Definition: fci.c:170
Definition: fci.c:123
cab_ULONG offset
Definition: fci.c:126
cab_UWORD folder
Definition: fci.c:127
cab_UWORD date
Definition: fci.c:128
struct list entry
Definition: fci.c:124
cab_UWORD attribs
Definition: fci.c:130
cab_ULONG size
Definition: fci.c:125
cab_UWORD time
Definition: fci.c:129
char name[1]
Definition: fci.c:131
Definition: name.c:39
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255

Referenced by add_file_data().

◆ add_file_data()

static BOOL add_file_data ( FCI_Int fci,
char sourcefile,
char filename,
BOOL  execute,
PFNFCIGETOPENINFO  get_open_info,
PFNFCISTATUS  status_callback 
)
static

Definition at line 349 of file fci.c.

351{
352 int err, len;
354 struct file *file;
355
356 if (!(file = add_file( fci, filename ))) return FALSE;
357
358 handle = get_open_info( sourcefile, &file->date, &file->time, &file->attribs, &err, fci->pv );
359 if (handle == -1)
360 {
361 free_file( fci, file );
363 return FALSE;
364 }
365 if (execute) file->attribs |= _A_EXEC;
366
367 for (;;)
368 {
369 len = fci->read( handle, fci->data_in + fci->cdata_in,
370 CAB_BLOCKMAX - fci->cdata_in, &err, fci->pv );
371 if (!len) break;
372
373 if (len == -1)
374 {
376 return FALSE;
377 }
378 file->size += len;
379 fci->cdata_in += len;
380 if (fci->cdata_in == CAB_BLOCKMAX && !add_data_block( fci, status_callback )) return FALSE;
381 }
382 fci->close( handle, &err, fci->pv );
383 return TRUE;
384}
static BOOL add_data_block(FCI_Int *fci, PFNFCISTATUS status_callback)
Definition: fci.c:309
static struct file * add_file(FCI_Int *fci, const char *filename)
Definition: fci.c:266
static void free_file(FCI_Int *fci, struct file *file)
Definition: fci.c:302
#define _A_EXEC
Definition: fci.h:135
@ FCIERR_OPEN_SRC
Definition: fci.h:118
@ FCIERR_READ_SRC
Definition: fci.h:119
GLenum GLsizei len
Definition: glext.h:6722
static INT_PTR CDECL get_open_info(char *pszName, USHORT *pdate, USHORT *ptime, USHORT *pattribs, int *err, void *pv)
Definition: files.c:304
void execute(char *message, int(*func)(int))
Definition: noexecute.c:13
PFNFCIREAD read
Definition: fci.c:149
PFNFCICLOSE close
Definition: fci.c:151
unsigned char data_in[CAB_BLOCKMAX]
Definition: fci.c:166
int32_t INT_PTR
Definition: typedefs.h:64

Referenced by FCIAddFile().

◆ add_files_to_folder()

static BOOL add_files_to_folder ( FCI_Int fci,
struct folder folder,
cab_ULONG  payload 
)
static

Definition at line 835 of file fci.c.

836{
837 cab_ULONG sizeOfFiles = 0, sizeOfFilesPrev;
838 cab_ULONG cbFileRemainder = 0;
839 struct file *file, *next;
840
842 {
843 cab_ULONG size = sizeof(CFFILE) + strlen(file->name) + 1;
844
845 /* fnfilfnfildest: placed file on cabinet */
846 fci->fileplaced( &fci->ccab, file->name, file->size,
848
849 sizeOfFilesPrev = sizeOfFiles;
850 /* set complete size of all processed files */
852 {
853 sizeOfFiles += fci->cbFileRemainder;
854 fci->cbFileRemainder = 0;
855 }
856 else sizeOfFiles += file->size;
857
858 /* check if spanned file fits into this cabinet folder */
859 if (sizeOfFiles > payload)
860 {
863 else
865 }
866
869 fci->placed_files_size += size;
870 fci->cFiles++;
871
872 /* This is only true for files which will be written into the */
873 /* next cabinet of the spanning folder */
874 if (sizeOfFiles > payload)
875 {
876 /* add a copy back onto the list */
877 if (!(file = copy_file( fci, file ))) return FALSE;
878 list_add_before( &next->entry, &file->entry );
879
880 /* Files which data will be partially written into the current cabinet */
882 {
883 if (sizeOfFilesPrev <= payload)
884 {
885 /* The size of the uncompressed, data of a spanning file in a */
886 /* spanning data */
887 cbFileRemainder = sizeOfFiles - payload;
888 }
890 }
891 else file->folder = 0;
892 }
893 else
894 {
895 fci->files_size -= size;
896 }
897 }
898 fci->cbFileRemainder = cbFileRemainder;
899 return TRUE;
900}
static void list_remove(struct list_entry *entry)
Definition: list.h:90
#define cffileCONTINUED_FROM_PREV
Definition: cabinet.h:90
#define cffileCONTINUED_PREV_AND_NEXT
Definition: cabinet.h:92
#define cffileCONTINUED_TO_NEXT
Definition: cabinet.h:91
static struct file * copy_file(FCI_Int *fci, const struct file *orig)
Definition: fci.c:288
__WINE_SERVER_LIST_INLINE void list_add_before(struct list *elem, struct list *to_add)
Definition: list.h:87
cab_UWORD cFiles
Definition: fci.c:171
cab_ULONG cbFileRemainder
Definition: fci.c:173
PFNFCIFILEPLACED fileplaced
Definition: fci.c:145
struct list files_list
Definition: fci.c:114

Referenced by fci_flush_folder().

◆ add_folder()

static struct folder * add_folder ( FCI_Int fci)
static

Definition at line 392 of file fci.c.

393{
394 struct folder *folder = fci->alloc( sizeof(*folder) );
395
396 if (!folder)
397 {
399 return NULL;
400 }
401 folder->data.handle = -1;
403 folder->data_count = 0;
408 fci->folders_size += sizeof(CFFOLDER) + fci->ccab.cbReserveCFFolder;
409 fci->cFolders++;
410 return folder;
411}
static void list_init(struct list_entry *head)
Definition: list.h:51
TCOMP compression
Definition: fci.c:186
struct list folders_list
Definition: fci.c:178
TCOMP compression
Definition: fci.c:119
struct list entry
Definition: fci.c:113
cab_ULONG data_start
Definition: fci.c:117

Referenced by fci_flush_folder().

◆ close_temp_file()

static BOOL close_temp_file ( FCI_Int fci,
struct temp_file file 
)
static

Definition at line 247 of file fci.c.

248{
249 int err;
250
251 if (file->handle == -1) return TRUE;
252 if (fci->close( file->handle, &err, fci->pv ) == -1)
253 {
255 return FALSE;
256 }
257 file->handle = -1;
258 if (fci->delete( file->name, &err, fci->pv ) == -1)
259 {
261 return FALSE;
262 }
263 return TRUE;
264}
PFNFCIDELETE delete
Definition: fci.c:153

Referenced by copy_data_blocks(), FCIDestroy(), and free_folder().

◆ compress_MSZIP()

static cab_UWORD compress_MSZIP ( FCI_Int fci)
static

Definition at line 920 of file fci.c.

921{
923
924 stream.zalloc = zalloc;
925 stream.zfree = zfree;
926 stream.opaque = fci;
928 {
930 return 0;
931 }
932 stream.next_in = fci->data_in;
933 stream.avail_in = fci->cdata_in;
934 stream.next_out = fci->data_out + 2;
935 stream.avail_out = sizeof(fci->data_out) - 2;
936 /* insert the signature */
937 fci->data_out[0] = 'C';
938 fci->data_out[1] = 'K';
940 deflateEnd( &stream );
941 return stream.total_out + 2;
942}
#define Z_DEFLATED
Definition: zlib.h:146
#define Z_DEFAULT_STRATEGY
Definition: zlib.h:137
#define Z_FINISH
Definition: zlib.h:109
#define Z_OK
Definition: zlib.h:114
int deflate(z_streamp strm, int flush) DECLSPEC_HIDDEN
Definition: deflate.c:815
int deflateEnd(z_streamp strm) DECLSPEC_HIDDEN
Definition: deflate.c:1130
#define Z_DEFAULT_COMPRESSION
Definition: zlib.h:130
static void * zalloc(void *opaque, unsigned int items, unsigned int size)
Definition: fci.c:908
static void zfree(void *opaque, void *ptr)
Definition: fci.c:914
#define deflateInit2(strm, level, method, windowBits, memLevel, strategy)
Definition: zlib.h:1814
Definition: parse.h:23

Referenced by FCIAddFile().

◆ compress_NONE()

static cab_UWORD compress_NONE ( FCI_Int fci)
static

Definition at line 902 of file fci.c.

903{
904 memcpy( fci->data_out, fci->data_in, fci->cdata_in );
905 return fci->cdata_in;
906}
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878

Referenced by FCIAddFile(), and FCICreate().

◆ copy_data_blocks()

static BOOL copy_data_blocks ( FCI_Int fci,
INT_PTR  handle,
cab_ULONG  start_pos,
struct temp_file temp,
PFNFCISTATUS  status_callback 
)
static

Definition at line 481 of file fci.c.

483{
484 struct data_block *block;
485 int err;
486
487 if (fci->seek( handle, start_pos, SEEK_SET, &err, fci->pv ) != start_pos)
488 {
490 return FALSE;
491 }
492 if (!create_temp_file( fci, temp )) return FALSE;
493
495 {
496 if (fci->read( handle, fci->data_out, block->compressed,
497 &err, fci->pv ) != block->compressed)
498 {
499 close_temp_file( fci, temp );
501 return FALSE;
502 }
503 if (fci->write( temp->handle, fci->data_out, block->compressed,
504 &err, fci->pv ) != block->compressed)
505 {
506 close_temp_file( fci, temp );
508 return FALSE;
509 }
510 fci->pending_data_size += sizeof(CFDATA) + fci->ccab.cbReserveCFData + block->compressed;
511 fci->statusFolderCopied += block->compressed;
512
514 fci->statusFolderTotal, fci->pv) == -1)
515 {
516 close_temp_file( fci, temp );
517 set_error( fci, FCIERR_USER_ABORT, 0 );
518 return FALSE;
519 }
520 }
521 return TRUE;
522}
static BOOL close_temp_file(FCI_Int *fci, struct temp_file *file)
Definition: fci.c:247
#define SEEK_SET
Definition: jmemansi.c:26
if(dx< 0)
Definition: linetemp.h:194
static calc_node_t temp
Definition: rpn_ieee.c:38
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
PFNFCISEEK seek
Definition: fci.c:152

Referenced by add_data_to_folder().

◆ copy_file()

static struct file * copy_file ( FCI_Int fci,
const struct file orig 
)
static

Definition at line 288 of file fci.c.

289{
290 unsigned int size = FIELD_OFFSET( struct file, name[strlen(orig->name) + 1] );
291 struct file *file = fci->alloc( size );
292
293 if (!file)
294 {
296 return NULL;
297 }
298 memcpy( file, orig, size );
299 return file;
300}

Referenced by add_files_to_folder().

◆ create_temp_file()

static BOOL create_temp_file ( FCI_Int fci,
struct temp_file file 
)
static

Definition at line 229 of file fci.c.

230{
231 int err;
232
233 if (!fci->gettemp( file->name, CB_MAX_FILENAME, fci->pv ))
234 {
236 return FALSE;
237 }
238 if ((file->handle = fci->open( file->name, _O_RDWR | _O_CREAT | _O_EXCL | _O_BINARY,
239 _S_IREAD | _S_IWRITE, &err, fci->pv )) == -1)
240 {
242 return FALSE;
243 }
244 return TRUE;
245}
#define _S_IWRITE
Definition: stat.h:85
#define _S_IREAD
Definition: stat.h:84
#define _O_RDWR
Definition: fcntl.h:15
#define _O_BINARY
Definition: fcntl.h:27
#define _O_CREAT
Definition: fcntl.h:22
#define _O_EXCL
Definition: fcntl.h:24
#define CB_MAX_FILENAME
Definition: fci.h:54
PFNFCIOPEN open
Definition: fci.c:148
PFNFCIGETTEMPFILE gettemp
Definition: fci.c:154
#define ERROR_FUNCTION_FAILED
Definition: winerror.h:1333

Referenced by add_data_block(), and copy_data_blocks().

◆ fci_flush_cabinet()

static BOOL fci_flush_cabinet ( FCI_Int p_fci_internal,
BOOL  fGetNextCab,
PFNFCIGETNEXTCABINET  pfnfcignc,
PFNFCISTATUS  pfnfcis 
)
static

Definition at line 1223 of file fci.c.

1227{
1228 cab_ULONG read_result=0;
1229 BOOL returntrue=FALSE;
1230
1231 /* TODO test if fci_flush_cabinet really aborts if there was no FCIAddFile */
1232
1233 /* when FCIFlushCabinet was or FCIAddFile hasn't been called */
1234 if( p_fci_internal->files_size==0 && fGetNextCab ) {
1235 returntrue=TRUE;
1236 }
1237
1238 if (!fci_flush_folder(p_fci_internal,fGetNextCab,pfnfcignc,pfnfcis)){
1239 /* TODO set error */
1240 return FALSE;
1241 }
1242
1243 if(returntrue) return TRUE;
1244
1245 if ( (p_fci_internal->fSplitFolder && p_fci_internal->fNextCab==FALSE)||
1246 (p_fci_internal->folders_size==0 &&
1247 (p_fci_internal->files_size!=0 ||
1248 p_fci_internal->placed_files_size!=0 )
1249 ) )
1250 {
1251 /* error */
1252 set_error( p_fci_internal, FCIERR_NONE, ERROR_GEN_FAILURE );
1253 return FALSE;
1254 }
1255
1256 /* create the cabinet */
1257 if (!write_cabinet( p_fci_internal, pfnfcis )) return FALSE;
1258
1259 p_fci_internal->fPrevCab=TRUE;
1260 /* The sections szPrevCab and szPrevDisk are not being updated, because */
1261 /* MS CABINET.DLL always puts the first cabinet name and disk into them */
1262
1263 if (p_fci_internal->fNextCab) {
1264 p_fci_internal->fNextCab=FALSE;
1265
1266 if (p_fci_internal->files_size==0 && p_fci_internal->pending_data_size!=0) {
1267 /* THIS CAN NEVER HAPPEN */
1268 /* set error code */
1269 set_error( p_fci_internal, FCIERR_NONE, ERROR_GEN_FAILURE );
1270 return FALSE;
1271 }
1272
1273 if( p_fci_internal->fNewPrevious ) {
1274 memcpy(p_fci_internal->szPrevCab, p_fci_internal->ccab.szCab,
1276 memcpy(p_fci_internal->szPrevDisk, p_fci_internal->ccab.szDisk,
1278 p_fci_internal->fNewPrevious=FALSE;
1279 }
1280 p_fci_internal->ccab = *p_fci_internal->pccab;
1281
1282 /* REUSE the variable read_result */
1283 read_result=get_header_size( p_fci_internal );
1284 if(p_fci_internal->files_size!=0) {
1285 read_result+=p_fci_internal->ccab.cbReserveCFFolder;
1286 }
1287 read_result+= p_fci_internal->pending_data_size +
1288 p_fci_internal->files_size + p_fci_internal->folders_data_size +
1289 p_fci_internal->placed_files_size + p_fci_internal->folders_size +
1290 sizeof(CFFOLDER); /* set size of new CFFolder entry */
1291
1292 /* too much data for the maximum size of a cabinet */
1293 if( p_fci_internal->fGetNextCabInVain==FALSE &&
1294 p_fci_internal->ccab.cb < read_result ) {
1295 return fci_flush_cabinet( p_fci_internal, FALSE, pfnfcignc, pfnfcis);
1296 }
1297
1298 /* Might be too much data for the maximum size of a cabinet.*/
1299 /* When any further data will be added later, it might not */
1300 /* be possible to flush the cabinet, because there might */
1301 /* not be enough space to store the name of the following */
1302 /* cabinet and name of the corresponding disk. */
1303 /* So take care of this and get the name of the next cabinet */
1304 if (p_fci_internal->fGetNextCabInVain==FALSE && (
1305 p_fci_internal->ccab.cb < read_result +
1307 )) {
1308 /* increment cabinet index */
1309 ++(p_fci_internal->pccab->iCab);
1310 /* get name of next cabinet */
1311 p_fci_internal->estimatedCabinetSize=p_fci_internal->statusFolderTotal;
1312 if (!(*pfnfcignc)(p_fci_internal->pccab,
1313 p_fci_internal->estimatedCabinetSize, /* estimated size of cab */
1314 p_fci_internal->pv)) {
1315 /* error handling */
1316 set_error( p_fci_internal, FCIERR_NONE, ERROR_FUNCTION_FAILED );
1317 return FALSE;
1318 }
1319 /* Skip a few lines of code. This is caught by the next if. */
1320 p_fci_internal->fGetNextCabInVain=TRUE;
1321 }
1322
1323 /* too much data for cabinet */
1324 if (p_fci_internal->fGetNextCabInVain && (
1325 p_fci_internal->ccab.cb < read_result +
1326 strlen(p_fci_internal->ccab.szCab)+1+
1327 strlen(p_fci_internal->ccab.szDisk)+1
1328 )) {
1329 p_fci_internal->fGetNextCabInVain=FALSE;
1330 p_fci_internal->fNextCab=TRUE;
1331 return fci_flush_cabinet( p_fci_internal, FALSE, pfnfcignc, pfnfcis);
1332 }
1333
1334 /* if the FolderThreshold has been reached flush the folder automatically */
1335 if (p_fci_internal->cCompressedBytesInFolder >= p_fci_internal->ccab.cbFolderThresh)
1336 return fci_flush_folder(p_fci_internal, FALSE, pfnfcignc, pfnfcis);
1337
1338 if( p_fci_internal->files_size>0 ) {
1339 if( !fci_flush_folder(p_fci_internal, FALSE, pfnfcignc, pfnfcis) ) return FALSE;
1340 p_fci_internal->fNewPrevious=TRUE;
1341 }
1342 } else {
1343 p_fci_internal->fNewPrevious=FALSE;
1344 if( p_fci_internal->files_size>0 || p_fci_internal->pending_data_size) {
1345 /* THIS MAY NEVER HAPPEN */
1346 /* set error structures */
1347 set_error( p_fci_internal, FCIERR_NONE, ERROR_GEN_FAILURE );
1348 return FALSE;
1349 }
1350 }
1351
1352 return TRUE;
1353} /* end of fci_flush_cabinet */
static BOOL fci_flush_folder(FCI_Int *p_fci_internal, BOOL fGetNextCab, PFNFCIGETNEXTCABINET pfnfcignc, PFNFCISTATUS pfnfcis)
Definition: fci.c:1063
static BOOL fci_flush_cabinet(FCI_Int *p_fci_internal, BOOL fGetNextCab, PFNFCIGETNEXTCABINET pfnfcignc, PFNFCISTATUS pfnfcis)
Definition: fci.c:1223
static BOOL write_cabinet(FCI_Int *fci, PFNFCISTATUS status_callback)
Definition: fci.c:645
#define CB_MAX_DISK_NAME
Definition: fci.h:57
#define CB_MAX_CABINET_NAME
Definition: fci.h:55
@ FCIERR_NONE
Definition: fci.h:117
ULONG cbFolderThresh
Definition: fci.h:146
int iCab
Definition: fci.h:151
char szDisk[CB_MAX_DISK_NAME]
Definition: fci.h:159
char szCab[CB_MAX_CABINET_NAME]
Definition: fci.h:160
char szPrevDisk[CB_MAX_DISK_NAME]
Definition: fci.c:165
BOOL fGetNextCabInVain
Definition: fci.c:162
cab_ULONG estimatedCabinetSize
Definition: fci.c:177
BOOL fPrevCab
Definition: fci.c:157
BOOL fSplitFolder
Definition: fci.c:159
BOOL fNewPrevious
Definition: fci.c:176
PCCAB pccab
Definition: fci.c:156
char szPrevCab[CB_MAX_CABINET_NAME]
Definition: fci.c:164
#define ERROR_GEN_FAILURE
Definition: winerror.h:256

Referenced by fci_flush_cabinet(), FCIAddFile(), and FCIFlushCabinet().

◆ fci_flush_folder()

static BOOL fci_flush_folder ( FCI_Int p_fci_internal,
BOOL  fGetNextCab,
PFNFCIGETNEXTCABINET  pfnfcignc,
PFNFCISTATUS  pfnfcis 
)
static

Definition at line 1063 of file fci.c.

1067{
1068 cab_ULONG payload;
1069 cab_ULONG read_result;
1070 struct folder *folder;
1071
1072 if ((!pfnfcignc) || (!pfnfcis)) {
1073 set_error( p_fci_internal, FCIERR_NONE, ERROR_BAD_ARGUMENTS );
1074 return FALSE;
1075 }
1076
1077 if( p_fci_internal->fGetNextCabInVain &&
1078 p_fci_internal->fNextCab ){
1079 /* internal error */
1080 set_error( p_fci_internal, FCIERR_NONE, ERROR_GEN_FAILURE );
1081 return FALSE;
1082 }
1083
1084 /* If there was no FCIAddFile or FCIFlushFolder has already been called */
1085 /* this function will return TRUE */
1086 if( p_fci_internal->files_size == 0 ) {
1087 if ( p_fci_internal->pending_data_size != 0 ) {
1088 /* error handling */
1089 set_error( p_fci_internal, FCIERR_NONE, ERROR_GEN_FAILURE );
1090 return FALSE;
1091 }
1092 return TRUE;
1093 }
1094
1095 /* FCIFlushFolder has already been called... */
1096 if (p_fci_internal->fSplitFolder && p_fci_internal->placed_files_size!=0) {
1097 return TRUE;
1098 }
1099
1100 /* This can be set already, because it makes only a difference */
1101 /* when the current function exits with return FALSE */
1102 p_fci_internal->fSplitFolder=FALSE;
1103
1104 /* START of COPY */
1105 if (!add_data_block( p_fci_internal, pfnfcis )) return FALSE;
1106
1107 /* reset to get the number of data blocks of this folder which are */
1108 /* actually in this cabinet ( at least partially ) */
1109 p_fci_internal->cDataBlocks=0;
1110
1111 p_fci_internal->statusFolderTotal = get_header_size( p_fci_internal ) +
1112 sizeof(CFFOLDER) + p_fci_internal->ccab.cbReserveCFFolder +
1113 p_fci_internal->placed_files_size+
1114 p_fci_internal->folders_data_size + p_fci_internal->files_size+
1115 p_fci_internal->pending_data_size + p_fci_internal->folders_size;
1116 p_fci_internal->statusFolderCopied = 0;
1117
1118 /* report status with pfnfcis about copied size of folder */
1119 if( (*pfnfcis)(statusFolder, p_fci_internal->statusFolderCopied,
1120 p_fci_internal->statusFolderTotal, /* TODO total folder size */
1121 p_fci_internal->pv) == -1) {
1122 set_error( p_fci_internal, FCIERR_USER_ABORT, 0 );
1123 return FALSE;
1124 }
1125
1126 /* USE the variable read_result */
1127 read_result = get_header_size( p_fci_internal ) + p_fci_internal->folders_data_size +
1128 p_fci_internal->placed_files_size + p_fci_internal->folders_size;
1129
1130 if(p_fci_internal->files_size!=0) {
1131 read_result+= sizeof(CFFOLDER)+p_fci_internal->ccab.cbReserveCFFolder;
1132 }
1133
1134 /* Check if multiple cabinets have to be created. */
1135
1136 /* Might be too much data for the maximum allowed cabinet size.*/
1137 /* When any further data will be added later, it might not */
1138 /* be possible to flush the cabinet, because there might */
1139 /* not be enough space to store the name of the following */
1140 /* cabinet and name of the corresponding disk. */
1141 /* So take care of this and get the name of the next cabinet */
1142 if( p_fci_internal->fGetNextCabInVain==FALSE &&
1143 p_fci_internal->fNextCab==FALSE &&
1144 (
1145 (
1146 p_fci_internal->ccab.cb < read_result +
1147 p_fci_internal->pending_data_size +
1148 p_fci_internal->files_size +
1149 CB_MAX_CABINET_NAME + /* next cabinet name */
1150 CB_MAX_DISK_NAME /* next disk name */
1151 ) || fGetNextCab
1152 )
1153 ) {
1154 /* increment cabinet index */
1155 ++(p_fci_internal->pccab->iCab);
1156 /* get name of next cabinet */
1157 p_fci_internal->estimatedCabinetSize=p_fci_internal->statusFolderTotal;
1158 if (!(*pfnfcignc)(p_fci_internal->pccab,
1159 p_fci_internal->estimatedCabinetSize, /* estimated size of cab */
1160 p_fci_internal->pv)) {
1161 set_error( p_fci_internal, FCIERR_NONE, ERROR_FUNCTION_FAILED );
1162 return FALSE;
1163 }
1164
1165 /* Skip a few lines of code. This is caught by the next if. */
1166 p_fci_internal->fGetNextCabInVain=TRUE;
1167 }
1168
1169 /* too much data for cabinet */
1170 if( (p_fci_internal->fGetNextCabInVain ||
1171 p_fci_internal->fNextCab ) &&
1172 (
1173 (
1174 p_fci_internal->ccab.cb < read_result +
1175 p_fci_internal->pending_data_size +
1176 p_fci_internal->files_size +
1177 strlen(p_fci_internal->pccab->szCab)+1 + /* next cabinet name */
1178 strlen(p_fci_internal->pccab->szDisk)+1 /* next disk name */
1179 ) || fGetNextCab
1180 )
1181 ) {
1182 p_fci_internal->fGetNextCabInVain=FALSE;
1183 p_fci_internal->fNextCab=TRUE;
1184
1185 /* return FALSE if there is not enough space left*/
1186 /* this should never happen */
1187 if (p_fci_internal->ccab.cb <=
1188 p_fci_internal->files_size +
1189 read_result +
1190 strlen(p_fci_internal->pccab->szCab)+1 + /* next cabinet name */
1191 strlen(p_fci_internal->pccab->szDisk)+1 /* next disk name */
1192 ) {
1193
1194 return FALSE;
1195 }
1196
1197 /* the folder will be split across cabinets */
1198 p_fci_internal->fSplitFolder=TRUE;
1199
1200 } else {
1201 /* this should never happen */
1202 if (p_fci_internal->fNextCab) {
1203 /* internal error */
1204 set_error( p_fci_internal, FCIERR_NONE, ERROR_GEN_FAILURE );
1205 return FALSE;
1206 }
1207 }
1208
1209 if (!(folder = add_folder( p_fci_internal ))) return FALSE;
1210 if (!add_data_to_folder( p_fci_internal, folder, &payload, pfnfcis )) return FALSE;
1211 if (!add_files_to_folder( p_fci_internal, folder, payload )) return FALSE;
1212
1213 /* reset CFFolder specific information */
1214 p_fci_internal->cDataBlocks=0;
1215 p_fci_internal->cCompressedBytesInFolder=0;
1216
1217 return TRUE;
1218}
static struct folder * add_folder(FCI_Int *fci)
Definition: fci.c:392
static BOOL add_files_to_folder(FCI_Int *fci, struct folder *folder, cab_ULONG payload)
Definition: fci.c:835
static BOOL add_data_to_folder(FCI_Int *fci, struct folder *folder, cab_ULONG *payload, PFNFCISTATUS status_callback)
Definition: fci.c:758
#define ERROR_BAD_ARGUMENTS
Definition: winerror.h:354

Referenced by fci_flush_cabinet(), and FCIFlushFolder().

◆ fci_get_checksum()

static cab_ULONG fci_get_checksum ( const void pv,
UINT  cb,
cab_ULONG  seed 
)
static

Definition at line 442 of file fci.c.

443{
445 cab_ULONG ul;
446 int cUlong;
447 const BYTE *pb;
448
449 csum = seed;
450 cUlong = cb / 4;
451 pb = pv;
452
453 while (cUlong-- > 0) {
454 ul = *pb++;
455 ul |= (((cab_ULONG)(*pb++)) << 8);
456 ul |= (((cab_ULONG)(*pb++)) << 16);
457 ul |= (((cab_ULONG)(*pb++)) << 24);
458 csum ^= ul;
459 }
460
461 ul = 0;
462 switch (cb % 4) {
463 case 3:
464 ul |= (((ULONG)(*pb++)) << 16);
465 /* fall through */
466 case 2:
467 ul |= (((ULONG)(*pb++)) << 8);
468 /* fall through */
469 case 1:
470 ul |= *pb;
471 /* fall through */
472 default:
473 break;
474 }
475 csum ^= ul;
476
477 return csum;
478}
static MonoProfilerRuntimeShutdownBeginCallback cb
Definition: metahost.c:118
Definition: ffs.h:52
uint32_t ULONG
Definition: typedefs.h:59
unsigned char BYTE
Definition: xxhash.c:193

Referenced by write_data_blocks().

◆ FCIAddFile()

BOOL __cdecl FCIAddFile ( HFCI  hfci,
char pszSourceFile,
char pszFileName,
BOOL  fExecute,
PFNFCIGETNEXTCABINET  pfnfcignc,
PFNFCISTATUS  pfnfcis,
PFNFCIGETOPENINFO  pfnfcigoi,
TCOMP  typeCompress 
)

Definition at line 1389 of file fci.c.

1398{
1399 cab_ULONG read_result;
1400 FCI_Int *p_fci_internal = get_fci_ptr( hfci );
1401
1402 if (!p_fci_internal) return FALSE;
1403
1404 if ((!pszSourceFile) || (!pszFileName) || (!pfnfcignc) || (!pfnfcis) ||
1405 (!pfnfcigoi) || strlen(pszFileName)>=CB_MAX_FILENAME) {
1406 set_error( p_fci_internal, FCIERR_NONE, ERROR_BAD_ARGUMENTS );
1407 return FALSE;
1408 }
1409
1410 if (typeCompress != p_fci_internal->compression)
1411 {
1412 if (!FCIFlushFolder( hfci, pfnfcignc, pfnfcis )) return FALSE;
1413 switch (typeCompress)
1414 {
1415 case tcompTYPE_MSZIP:
1416 p_fci_internal->compression = tcompTYPE_MSZIP;
1417 p_fci_internal->compress = compress_MSZIP;
1418 break;
1419 default:
1420 FIXME( "compression %x not supported, defaulting to none\n", typeCompress );
1421 /* fall through */
1422 case tcompTYPE_NONE:
1423 p_fci_internal->compression = tcompTYPE_NONE;
1424 p_fci_internal->compress = compress_NONE;
1425 break;
1426 }
1427 }
1428
1429 /* TODO check if pszSourceFile??? */
1430
1431 if(p_fci_internal->fGetNextCabInVain && p_fci_internal->fNextCab) {
1432 /* internal error */
1433 set_error( p_fci_internal, FCIERR_NONE, ERROR_GEN_FAILURE );
1434 return FALSE;
1435 }
1436
1437 if(p_fci_internal->fNextCab) {
1438 /* internal error */
1439 set_error( p_fci_internal, FCIERR_NONE, ERROR_GEN_FAILURE );
1440 return FALSE;
1441 }
1442
1443 /* REUSE the variable read_result */
1444 read_result=get_header_size( p_fci_internal ) + p_fci_internal->ccab.cbReserveCFFolder;
1445
1446 read_result+= sizeof(CFFILE) + strlen(pszFileName)+1 +
1447 p_fci_internal->files_size + p_fci_internal->folders_data_size +
1448 p_fci_internal->placed_files_size + p_fci_internal->folders_size +
1449 sizeof(CFFOLDER); /* size of new CFFolder entry */
1450
1451 /* Might be too much data for the maximum size of a cabinet.*/
1452 /* When any further data will be added later, it might not */
1453 /* be possible to flush the cabinet, because there might */
1454 /* not be enough space to store the name of the following */
1455 /* cabinet and name of the corresponding disk. */
1456 /* So take care of this and get the name of the next cabinet */
1457 if( p_fci_internal->fGetNextCabInVain==FALSE &&
1458 p_fci_internal->fNextCab==FALSE &&
1459 ( p_fci_internal->ccab.cb < read_result +
1461 )
1462 ) {
1463 /* increment cabinet index */
1464 ++(p_fci_internal->pccab->iCab);
1465 /* get name of next cabinet */
1466 p_fci_internal->estimatedCabinetSize=p_fci_internal->statusFolderTotal;
1467 if (!(*pfnfcignc)(p_fci_internal->pccab,
1468 p_fci_internal->estimatedCabinetSize, /* estimated size of cab */
1469 p_fci_internal->pv)) {
1470 /* error handling */
1471 set_error( p_fci_internal, FCIERR_NONE, ERROR_FUNCTION_FAILED );
1472 return FALSE;
1473 }
1474 /* Skip a few lines of code. This is caught by the next if. */
1475 p_fci_internal->fGetNextCabInVain=TRUE;
1476 }
1477
1478 if( p_fci_internal->fGetNextCabInVain &&
1479 p_fci_internal->fNextCab
1480 ) {
1481 /* THIS CAN NEVER HAPPEN */
1482 /* set error code */
1483 set_error( p_fci_internal, FCIERR_NONE, ERROR_GEN_FAILURE );
1484 return FALSE;
1485 }
1486
1487 /* too much data for cabinet */
1488 if( p_fci_internal->fGetNextCabInVain &&
1489 (
1490 p_fci_internal->ccab.cb < read_result +
1491 strlen(p_fci_internal->pccab->szCab)+1+
1492 strlen(p_fci_internal->pccab->szDisk)+1
1493 )) {
1494 p_fci_internal->fGetNextCabInVain=FALSE;
1495 p_fci_internal->fNextCab=TRUE;
1496 if(!fci_flush_cabinet( p_fci_internal, FALSE, pfnfcignc, pfnfcis)) return FALSE;
1497 }
1498
1499 if( p_fci_internal->fNextCab ) {
1500 /* THIS MAY NEVER HAPPEN */
1501 /* set error code */
1502 set_error( p_fci_internal, FCIERR_NONE, ERROR_GEN_FAILURE );
1503 return FALSE;
1504 }
1505
1506 if (!add_file_data( p_fci_internal, pszSourceFile, pszFileName, fExecute, pfnfcigoi, pfnfcis ))
1507 return FALSE;
1508
1509 /* REUSE the variable read_result */
1510 read_result = get_header_size( p_fci_internal ) + p_fci_internal->ccab.cbReserveCFFolder;
1511 read_result+= p_fci_internal->pending_data_size +
1512 p_fci_internal->files_size + p_fci_internal->folders_data_size +
1513 p_fci_internal->placed_files_size + p_fci_internal->folders_size +
1514 sizeof(CFFOLDER); /* set size of new CFFolder entry */
1515
1516 /* too much data for the maximum size of a cabinet */
1517 /* (ignoring the unflushed data block) */
1518 if( p_fci_internal->fGetNextCabInVain==FALSE &&
1519 p_fci_internal->fNextCab==FALSE && /* this is always the case */
1520 p_fci_internal->ccab.cb < read_result ) {
1521 return fci_flush_cabinet( p_fci_internal, FALSE, pfnfcignc, pfnfcis);
1522 }
1523
1524 /* Might be too much data for the maximum size of a cabinet.*/
1525 /* When any further data will be added later, it might not */
1526 /* be possible to flush the cabinet, because there might */
1527 /* not be enough space to store the name of the following */
1528 /* cabinet and name of the corresponding disk. */
1529 /* So take care of this and get the name of the next cabinet */
1530 /* (ignoring the unflushed data block) */
1531 if( p_fci_internal->fGetNextCabInVain==FALSE &&
1532 p_fci_internal->fNextCab==FALSE &&
1533 ( p_fci_internal->ccab.cb < read_result +
1535 )
1536 ) {
1537 /* increment cabinet index */
1538 ++(p_fci_internal->pccab->iCab);
1539 /* get name of next cabinet */
1540 p_fci_internal->estimatedCabinetSize=p_fci_internal->statusFolderTotal;
1541 if (!(*pfnfcignc)(p_fci_internal->pccab,
1542 p_fci_internal->estimatedCabinetSize,/* estimated size of cab */
1543 p_fci_internal->pv)) {
1544 /* error handling */
1545 set_error( p_fci_internal, FCIERR_NONE, ERROR_FUNCTION_FAILED );
1546 return FALSE;
1547 }
1548 /* Skip a few lines of code. This is caught by the next if. */
1549 p_fci_internal->fGetNextCabInVain=TRUE;
1550 }
1551
1552 if( p_fci_internal->fGetNextCabInVain &&
1553 p_fci_internal->fNextCab
1554 ) {
1555 /* THIS CAN NEVER HAPPEN */
1556 set_error( p_fci_internal, FCIERR_NONE, ERROR_GEN_FAILURE );
1557 return FALSE;
1558 }
1559
1560 /* too much data for cabinet */
1561 if( (p_fci_internal->fGetNextCabInVain ||
1562 p_fci_internal->fNextCab) && (
1563 p_fci_internal->ccab.cb < read_result +
1564 strlen(p_fci_internal->pccab->szCab)+1+
1565 strlen(p_fci_internal->pccab->szDisk)+1
1566 )) {
1567
1568 p_fci_internal->fGetNextCabInVain=FALSE;
1569 p_fci_internal->fNextCab=TRUE;
1570 return fci_flush_cabinet( p_fci_internal, FALSE, pfnfcignc, pfnfcis);
1571 }
1572
1573 if( p_fci_internal->fNextCab ) {
1574 /* THIS MAY NEVER HAPPEN */
1575 /* set error code */
1576 set_error( p_fci_internal, FCIERR_NONE, ERROR_GEN_FAILURE );
1577 return FALSE;
1578 }
1579
1580 /* if the FolderThreshold has been reached flush the folder automatically */
1581 if (p_fci_internal->cCompressedBytesInFolder >= p_fci_internal->ccab.cbFolderThresh)
1582 return FCIFlushFolder(hfci, pfnfcignc, pfnfcis);
1583
1584 return TRUE;
1585} /* end of FCIAddFile */
#define FIXME(fmt,...)
Definition: precomp.h:53
static BOOL add_file_data(FCI_Int *fci, char *sourcefile, char *filename, BOOL execute, PFNFCIGETOPENINFO get_open_info, PFNFCISTATUS status_callback)
Definition: fci.c:349
static cab_UWORD compress_NONE(FCI_Int *fci)
Definition: fci.c:902
static FCI_Int * get_fci_ptr(HFCI hfci)
Definition: fci.c:200
static cab_UWORD compress_MSZIP(FCI_Int *fci)
Definition: fci.c:920
BOOL __cdecl FCIFlushFolder(HFCI hfci, PFNFCIGETNEXTCABINET pfnfcignc, PFNFCISTATUS pfnfcis)
Definition: fci.c:1621
#define tcompTYPE_NONE
Definition: fci.h:64
#define tcompTYPE_MSZIP
Definition: fci.h:65
Definition: fci.c:142
WORD WORD PSZ PSZ pszFileName
Definition: vdmdbg.h:44

Referenced by add_file().

◆ FCICreate()

HFCI __cdecl FCICreate ( PERF  perf,
PFNFCIFILEPLACED  pfnfiledest,
PFNFCIALLOC  pfnalloc,
PFNFCIFREE  pfnfree,
PFNFCIOPEN  pfnopen,
PFNFCIREAD  pfnread,
PFNFCIWRITE  pfnwrite,
PFNFCICLOSE  pfnclose,
PFNFCISEEK  pfnseek,
PFNFCIDELETE  pfndelete,
PFNFCIGETTEMPFILE  pfnfcigtf,
PCCAB  pccab,
void pv 
)

Definition at line 990 of file fci.c.

1004{
1005 FCI_Int *p_fci_internal;
1006
1007 if (!perf) {
1009 return NULL;
1010 }
1011 if ((!pfnalloc) || (!pfnfree) || (!pfnopen) || (!pfnread) ||
1012 (!pfnwrite) || (!pfnclose) || (!pfnseek) || (!pfndelete) ||
1013 (!pfnfcigtf) || (!pccab)) {
1014 perf->erfOper = FCIERR_NONE;
1016 perf->fError = TRUE;
1017
1019 return NULL;
1020 }
1021
1022 if (!((p_fci_internal = pfnalloc(sizeof(FCI_Int))))) {
1023 perf->erfOper = FCIERR_ALLOC_FAIL;
1025 perf->fError = TRUE;
1026
1028 return NULL;
1029 }
1030
1031 memset(p_fci_internal, 0, sizeof(FCI_Int));
1032 p_fci_internal->magic = FCI_INT_MAGIC;
1033 p_fci_internal->perf = perf;
1034 p_fci_internal->fileplaced = pfnfiledest;
1035 p_fci_internal->alloc = pfnalloc;
1036 p_fci_internal->free = pfnfree;
1037 p_fci_internal->open = pfnopen;
1038 p_fci_internal->read = pfnread;
1039 p_fci_internal->write = pfnwrite;
1040 p_fci_internal->close = pfnclose;
1041 p_fci_internal->seek = pfnseek;
1042 p_fci_internal->delete = pfndelete;
1043 p_fci_internal->gettemp = pfnfcigtf;
1044 p_fci_internal->ccab = *pccab;
1045 p_fci_internal->pccab = pccab;
1046 p_fci_internal->pv = pv;
1047 p_fci_internal->data.handle = -1;
1048 p_fci_internal->compress = compress_NONE;
1049
1050 list_init( &p_fci_internal->folders_list );
1051 list_init( &p_fci_internal->files_list );
1052 list_init( &p_fci_internal->blocks_list );
1053
1054 memcpy(p_fci_internal->szPrevCab, pccab->szCab, CB_MAX_CABINET_NAME);
1055 memcpy(p_fci_internal->szPrevDisk, pccab->szDisk, CB_MAX_DISK_NAME);
1056
1057 return (HFCI)p_fci_internal;
1058}
#define SetLastError(x)
Definition: compat.h:752
#define FCI_INT_MAGIC
Definition: fci.c:190
#define memset(x, y, z)
Definition: compat.h:39
int erfType
Definition: fci.h:46
BOOL fError
Definition: fci.h:47
int erfOper
Definition: fci.h:45
PERF perf
Definition: fci.c:144
unsigned int magic
Definition: fci.c:143

Referenced by create_cab_file(), create_cc_test_files(), and test_FDICopy().

◆ FCIDestroy()

BOOL __cdecl FCIDestroy ( HFCI  hfci)

Definition at line 1699 of file fci.c.

1700{
1701 struct folder *folder, *folder_next;
1702 struct file *file, *file_next;
1703 struct data_block *block, *block_next;
1704 FCI_Int *p_fci_internal = get_fci_ptr( hfci );
1705
1706 if (!p_fci_internal) return FALSE;
1707
1708 /* before hfci can be removed all temporary files must be closed */
1709 /* and deleted */
1710 p_fci_internal->magic = 0;
1711
1712 LIST_FOR_EACH_ENTRY_SAFE( folder, folder_next, &p_fci_internal->folders_list, struct folder, entry )
1713 {
1714 free_folder( p_fci_internal, folder );
1715 }
1716 LIST_FOR_EACH_ENTRY_SAFE( file, file_next, &p_fci_internal->files_list, struct file, entry )
1717 {
1718 free_file( p_fci_internal, file );
1719 }
1720 LIST_FOR_EACH_ENTRY_SAFE( block, block_next, &p_fci_internal->blocks_list, struct data_block, entry )
1721 {
1722 free_data_block( p_fci_internal, block );
1723 }
1724
1725 close_temp_file( p_fci_internal, &p_fci_internal->data );
1726
1727 /* hfci can now be removed */
1728 p_fci_internal->free(hfci);
1729 return TRUE;
1730}
static void free_folder(FCI_Int *fci, struct folder *folder)
Definition: fci.c:413

Referenced by create_cab_file(), create_cc_test_files(), and test_FDICopy().

◆ FCIFlushCabinet()

BOOL __cdecl FCIFlushCabinet ( HFCI  hfci,
BOOL  fGetNextCab,
PFNFCIGETNEXTCABINET  pfnfcignc,
PFNFCISTATUS  pfnfcis 
)

Definition at line 1665 of file fci.c.

1670{
1671 FCI_Int *p_fci_internal = get_fci_ptr( hfci );
1672
1673 if (!p_fci_internal) return FALSE;
1674
1675 if(!fci_flush_cabinet(p_fci_internal,fGetNextCab,pfnfcignc,pfnfcis)) return FALSE;
1676
1677 while( p_fci_internal->files_size>0 ||
1678 p_fci_internal->placed_files_size>0 ) {
1679 if(!fci_flush_cabinet(p_fci_internal,fGetNextCab,pfnfcignc,pfnfcis)) return FALSE;
1680 }
1681
1682 return TRUE;
1683}

Referenced by create_cab_file(), create_cc_test_files(), and test_FDICopy().

◆ FCIFlushFolder()

BOOL __cdecl FCIFlushFolder ( HFCI  hfci,
PFNFCIGETNEXTCABINET  pfnfcignc,
PFNFCISTATUS  pfnfcis 
)

Definition at line 1621 of file fci.c.

1625{
1626 FCI_Int *p_fci_internal = get_fci_ptr( hfci );
1627
1628 if (!p_fci_internal) return FALSE;
1629 return fci_flush_folder(p_fci_internal,FALSE,pfnfcignc,pfnfcis);
1630}

Referenced by FCIAddFile().

◆ free_data_block()

static void free_data_block ( FCI_Int fci,
struct data_block block 
)
static

Definition at line 386 of file fci.c.

387{
388 list_remove( &block->entry );
389 fci->free( block );
390}

Referenced by add_data_to_folder(), FCIDestroy(), and free_folder().

◆ free_file()

static void free_file ( FCI_Int fci,
struct file file 
)
static

Definition at line 302 of file fci.c.

303{
305 fci->free( file );
306}

Referenced by add_file_data(), FCIDestroy(), and free_folder().

◆ free_folder()

static void free_folder ( FCI_Int fci,
struct folder folder 
)
static

Definition at line 413 of file fci.c.

414{
415 struct file *file, *file_next;
416 struct data_block *block, *block_next;
417
418 LIST_FOR_EACH_ENTRY_SAFE( file, file_next, &folder->files_list, struct file, entry )
419 free_file( fci, file );
421 free_data_block( fci, block );
422 close_temp_file( fci, &folder->data );
424 fci->free( folder );
425}

Referenced by FCIDestroy(), and reset_cabinet().

◆ get_fci_ptr()

static FCI_Int * get_fci_ptr ( HFCI  hfci)
static

Definition at line 200 of file fci.c.

201{
202 FCI_Int *fci= (FCI_Int *)hfci;
203
204 if (!fci || fci->magic != FCI_INT_MAGIC)
205 {
207 return NULL;
208 }
209 return fci;
210}
#define ERROR_INVALID_HANDLE
Definition: compat.h:98

Referenced by FCIAddFile(), FCIDestroy(), FCIFlushCabinet(), and FCIFlushFolder().

◆ get_header_size()

static cab_ULONG get_header_size ( FCI_Int fci)
static

Definition at line 213 of file fci.c.

214{
216
218 ret += 4;
219
220 if (fci->fPrevCab)
221 ret += strlen( fci->szPrevCab ) + 1 + strlen( fci->szPrevDisk ) + 1;
222
223 if (fci->fNextCab)
224 ret += strlen( fci->pccab->szCab ) + 1 + strlen( fci->pccab->szDisk ) + 1;
225
226 return ret;
227}
return ret
Definition: mutex.c:147
UINT cbReserveCFHeader
Definition: fci.h:148
Definition: fci.c:61

Referenced by add_data_to_folder(), fci_flush_cabinet(), fci_flush_folder(), FCIAddFile(), and write_cabinet().

◆ reset_cabinet()

static void reset_cabinet ( FCI_Int fci)
static

Definition at line 428 of file fci.c.

429{
430 struct folder *folder, *folder_next;
431
432 LIST_FOR_EACH_ENTRY_SAFE( folder, folder_next, &fci->folders_list, struct folder, entry )
433 free_folder( fci, folder );
434
435 fci->cFolders = 0;
436 fci->cFiles = 0;
437 fci->folders_size = 0;
438 fci->placed_files_size = 0;
439 fci->folders_data_size = 0;
440}

Referenced by write_cabinet().

◆ set_error()

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( cabinet  )

◆ write_cabinet()

static BOOL write_cabinet ( FCI_Int fci,
PFNFCISTATUS  status_callback 
)
static

Definition at line 645 of file fci.c.

646{
648 int err;
649 char *ptr;
651 CFHEADER *cfheader = (CFHEADER *)fci->data_out;
652 cab_UWORD flags = 0;
653 cab_ULONG header_size = get_header_size( fci );
654 cab_ULONG total_size = header_size + fci->folders_size +
656
657 assert( header_size <= sizeof(fci->data_out) );
658 memset( cfheader, 0, header_size );
659
660 if (fci->fPrevCab) flags |= cfheadPREV_CABINET;
661 if (fci->fNextCab) flags |= cfheadNEXT_CABINET;
664
665 memcpy( cfheader->signature, "!CAB", 4 );
666 cfheader->cbCabinet = fci_endian_ulong( total_size );
667 cfheader->coffFiles = fci_endian_ulong( header_size + fci->folders_size );
668 cfheader->versionMinor = 3;
669 cfheader->versionMajor = 1;
670 cfheader->cFolders = fci_endian_uword( fci->cFolders );
671 cfheader->cFiles = fci_endian_uword( fci->cFiles );
672 cfheader->flags = fci_endian_uword( flags );
673 cfheader->setID = fci_endian_uword( fci->ccab.setID );
674 cfheader->iCabinet = fci_endian_uword( fci->ccab.iCab );
675 ptr = (char *)(cfheader + 1);
676
678 {
679 struct
680 {
681 cab_UWORD cbCFHeader;
682 cab_UBYTE cbCFFolder;
683 cab_UBYTE cbCFData;
684 } *reserve = (void *)ptr;
685
686 reserve->cbCFHeader = fci_endian_uword( fci->ccab.cbReserveCFHeader );
687 reserve->cbCFFolder = fci->ccab.cbReserveCFFolder;
688 reserve->cbCFData = fci->ccab.cbReserveCFData;
689 ptr = (char *)(reserve + 1);
690 }
691 ptr += fci->ccab.cbReserveCFHeader;
692
694 {
695 strcpy( ptr, fci->szPrevCab );
696 ptr += strlen( ptr ) + 1;
697 strcpy( ptr, fci->szPrevDisk );
698 ptr += strlen( ptr ) + 1;
699 }
700
702 {
703 strcpy( ptr, fci->pccab->szCab );
704 ptr += strlen( ptr ) + 1;
705 strcpy( ptr, fci->pccab->szDisk );
706 ptr += strlen( ptr ) + 1;
707 }
708
709 assert( ptr - (char *)cfheader == header_size );
710
711 strcpy( filename, fci->ccab.szCabPath );
712 strcat( filename, fci->ccab.szCab );
713
715 _S_IREAD | _S_IWRITE, &err, fci->pv )) == -1)
716 {
718 return FALSE;
719 }
720
721 if (fci->write( handle, cfheader, header_size, &err, fci->pv ) != header_size)
722 {
724 goto failed;
725 }
726
727 /* add size of header size of all CFFOLDERs and size of all CFFILEs */
728 header_size += fci->placed_files_size + fci->folders_size;
729 if (!write_folders( fci, handle, header_size, status_callback )) goto failed;
730 if (!write_files( fci, handle, status_callback )) goto failed;
731 if (!write_data_blocks( fci, handle, status_callback )) goto failed;
732
733 /* update the signature */
734 if (fci->seek( handle, 0, SEEK_SET, &err, fci->pv ) != 0 )
735 {
737 goto failed;
738 }
739 memcpy( cfheader->signature, "MSCF", 4 );
740 if (fci->write( handle, cfheader->signature, 4, &err, fci->pv ) != 4)
741 {
743 goto failed;
744 }
745 fci->close( handle, &err, fci->pv );
746
747 reset_cabinet( fci );
748 status_callback( statusCabinet, fci->estimatedCabinetSize, total_size, fci->pv );
749 return TRUE;
750
751failed:
752 fci->close( handle, &err, fci->pv );
753 fci->delete( filename, &err, fci->pv );
754 return FALSE;
755}
static BOOL reserve(struct dynamic_array *array, int count, int itemsize)
Definition: mesh.c:5392
UINT16 cab_UWORD
Definition: mszip.h:26
unsigned char cab_UBYTE
Definition: mszip.h:25
#define cfheadRESERVE_PRESENT
Definition: cabinet.h:89
#define cfheadNEXT_CABINET
Definition: cabinet.h:88
#define cfheadPREV_CABINET
Definition: cabinet.h:87
#define assert(_expr)
Definition: assert.h:32
#define _O_TRUNC
Definition: fcntl.h:23
static BOOL write_files(FCI_Int *fci, INT_PTR handle, PFNFCISTATUS status_callback)
Definition: fci.c:550
static void reset_cabinet(FCI_Int *fci)
Definition: fci.c:428
static BOOL write_folders(FCI_Int *fci, INT_PTR handle, cab_ULONG header_size, PFNFCISTATUS status_callback)
Definition: fci.c:525
static BOOL write_data_blocks(FCI_Int *fci, INT_PTR handle, PFNFCISTATUS status_callback)
Definition: fci.c:595
#define fci_endian_uword(x)
Definition: fci.c:57
#define fci_endian_ulong(x)
Definition: fci.c:56
#define CB_MAX_CAB_PATH
Definition: fci.h:56
#define statusCabinet
Definition: fci.h:221
@ FCIERR_CAB_FILE
Definition: fci.h:123
GLbitfield flags
Definition: glext.h:7161
static PVOID ptr
Definition: dispmode.c:27
strcat
Definition: string.h:92
USHORT setID
Definition: fci.h:157
char szCabPath[CB_MAX_CAB_PATH]
Definition: fci.h:161
cab_UBYTE versionMajor
Definition: fci.c:69
cab_UBYTE versionMinor
Definition: fci.c:68
cab_UWORD flags
Definition: fci.c:72
cab_ULONG coffFiles
Definition: fci.c:66
cab_UWORD cFolders
Definition: fci.c:70
cab_ULONG cbCabinet
Definition: fci.c:64
cab_UWORD cFiles
Definition: fci.c:71
cab_UWORD setID
Definition: fci.c:73
cab_UWORD iCabinet
Definition: fci.c:74
cab_UBYTE signature[4]
Definition: fci.c:62

Referenced by fci_flush_cabinet().

◆ write_data_blocks()

static BOOL write_data_blocks ( FCI_Int fci,
INT_PTR  handle,
PFNFCISTATUS  status_callback 
)
static

Definition at line 595 of file fci.c.

596{
597 struct folder *folder;
598 struct data_block *block;
599 int err, len;
600 CFDATA *cfdata;
601 void *data;
602 cab_UWORD header_size;
603
604 header_size = sizeof(CFDATA) + fci->ccab.cbReserveCFData;
605 cfdata = (CFDATA *)fci->data_out;
606 memset( cfdata, 0, header_size );
607 data = (char *)cfdata + header_size;
608
610 {
611 if (fci->seek( folder->data.handle, 0, SEEK_SET, &err, fci->pv ) != 0)
612 {
614 return FALSE;
615 }
617 {
618 len = fci->read( folder->data.handle, data, block->compressed, &err, fci->pv );
619 if (len != block->compressed) return FALSE;
620
621 cfdata->cbData = fci_endian_uword( block->compressed );
622 cfdata->cbUncomp = fci_endian_uword( block->uncompressed );
623 cfdata->csum = fci_endian_ulong( fci_get_checksum( &cfdata->cbData,
624 header_size - FIELD_OFFSET(CFDATA, cbData),
625 fci_get_checksum( data, len, 0 )));
626
627 fci->statusFolderCopied += len;
628 len += header_size;
629 if (fci->write( handle, fci->data_out, len, &err, fci->pv ) != len)
630 {
632 return FALSE;
633 }
635 {
636 set_error( fci, FCIERR_USER_ABORT, 0 );
637 return FALSE;
638 }
639 }
640 }
641 return TRUE;
642}
static cab_ULONG fci_get_checksum(const void *pv, UINT cb, cab_ULONG seed)
Definition: fci.c:442
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
_In_opt_ _In_opt_ _In_ _In_ DWORD cbData
Definition: shlwapi.h:761
cab_ULONG csum
Definition: fci.c:98
cab_UWORD cbUncomp
Definition: fci.c:100
cab_UWORD cbData
Definition: fci.c:99

Referenced by write_cabinet().

◆ write_files()

static BOOL write_files ( FCI_Int fci,
INT_PTR  handle,
PFNFCISTATUS  status_callback 
)
static

Definition at line 550 of file fci.c.

551{
553 struct folder *folder;
554 struct file *file;
555 int err;
556 CFFILE *cffile = (CFFILE *)fci->data_out;
557
559 {
561 {
562 cffile->cbFile = fci_endian_ulong( file->size );
564 cffile->iFolder = fci_endian_uword( file->folder );
565 cffile->date = fci_endian_uword( file->date );
566 cffile->time = fci_endian_uword( file->time );
567 cffile->attribs = fci_endian_uword( file->attribs );
568 lstrcpynA( (char *)(cffile + 1), file->name, CB_MAX_FILENAME );
569 file_size = sizeof(CFFILE) + strlen( (char *)(cffile + 1) ) + 1;
570 if (fci->write( handle, cffile, file_size, &err, fci->pv ) != file_size)
571 {
573 return FALSE;
574 }
575 if (!fci->fSplitFolder)
576 {
577 fci->statusFolderCopied = 0;
578 /* TODO TEST THIS further */
580 }
582 /* report status about copied size of folder */
584 fci->statusFolderTotal, fci->pv ) == -1)
585 {
586 set_error( fci, FCIERR_USER_ABORT, 0 );
587 return FALSE;
588 }
589 }
590 }
591 return TRUE;
592}
#define lstrcpynA
Definition: compat.h:751
static unsigned int file_size
Definition: regtests2xml.c:47
cab_UWORD time
Definition: fci.c:91
cab_ULONG uoffFolderStart
Definition: fci.c:87
cab_ULONG cbFile
Definition: fci.c:86
cab_UWORD date
Definition: fci.c:90
cab_UWORD iFolder
Definition: fci.c:88
cab_UWORD attribs
Definition: fci.c:92

Referenced by write_cabinet().

◆ write_folders()

static BOOL write_folders ( FCI_Int fci,
INT_PTR  handle,
cab_ULONG  header_size,
PFNFCISTATUS  status_callback 
)
static

Definition at line 525 of file fci.c.

526{
527 struct folder *folder;
528 int err;
529 CFFOLDER *cffolder = (CFFOLDER *)fci->data_out;
530 cab_ULONG folder_size = sizeof(CFFOLDER) + fci->ccab.cbReserveCFFolder;
531
532 memset( cffolder, 0, folder_size );
533
534 /* write the folders */
536 {
537 cffolder->coffCabStart = fci_endian_ulong( folder->data_start + header_size );
540 if (fci->write( handle, cffolder, folder_size, &err, fci->pv ) != folder_size)
541 {
543 return FALSE;
544 }
545 }
546 return TRUE;
547}
cab_UWORD cCFData
Definition: fci.c:80
cab_ULONG coffCabStart
Definition: fci.c:79
cab_UWORD typeCompress
Definition: fci.c:81

Referenced by write_cabinet().

◆ zalloc()

static void * zalloc ( void opaque,
unsigned int  items,
unsigned int  size 
)
static

Definition at line 908 of file fci.c.

909{
910 FCI_Int *fci = opaque;
911 return fci->alloc( items * size );
912}
static TCHAR * items[]
Definition: page1.c:45

Referenced by compress_MSZIP().

◆ zfree()

static void zfree ( void opaque,
void ptr 
)
static

Definition at line 914 of file fci.c.

915{
916 FCI_Int *fci = opaque;
917 fci->free( ptr );
918}

Referenced by compress_MSZIP().