From 5cf9ee2b66f3eaa436df3cbf704ae922fdb56db3 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Mon, 23 Jan 2012 15:12:50 +0000 Subject: [PATCH] [CABINET] * Sync to Wine 1.3.37. svn path=/trunk/; revision=55103 --- reactos/dll/win32/cabinet/CMakeLists.txt | 12 +- reactos/dll/win32/cabinet/cabinet.h | 125 - reactos/dll/win32/cabinet/cabinet.rbuild | 3 + reactos/dll/win32/cabinet/cabinet_main.c | 26 +- reactos/dll/win32/cabinet/fci.c | 3171 +++++++--------------- reactos/dll/win32/cabinet/fdi.c | 499 ++-- reactos/media/doc/README.WINE | 2 +- 7 files changed, 1278 insertions(+), 2560 deletions(-) diff --git a/reactos/dll/win32/cabinet/CMakeLists.txt b/reactos/dll/win32/cabinet/CMakeLists.txt index e90ef01ac4c..a79b033fb63 100644 --- a/reactos/dll/win32/cabinet/CMakeLists.txt +++ b/reactos/dll/win32/cabinet/CMakeLists.txt @@ -1,7 +1,11 @@ -add_definitions(-D__WINESRC__) +add_definitions( + -D__WINESRC__ + -DHAVE_ZLIB) -include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine) +include_directories( + ${REACTOS_SOURCE_DIR}/include/reactos/wine + ${REACTOS_SOURCE_DIR}/include/reactos/libs/zlib) spec2def(cabinet.dll cabinet.spec) @@ -16,8 +20,8 @@ list(APPEND SOURCE add_library(cabinet SHARED ${SOURCE}) set_module_type(cabinet win32dll ENTRYPOINT 0) -target_link_libraries(cabinet wine) -add_importlibs(cabinet kernel32 ntdll) +target_link_libraries(cabinet wine zlib) +add_importlibs(cabinet msvcrt kernel32 ntdll) add_importlib_target(cabinet.spec) add_pch(cabinet cabinet.h) add_dependencies(cabinet psdk) diff --git a/reactos/dll/win32/cabinet/cabinet.h b/reactos/dll/win32/cabinet/cabinet.h index cd82d14da45..b84c3a7c5d7 100644 --- a/reactos/dll/win32/cabinet/cabinet.h +++ b/reactos/dll/win32/cabinet/cabinet.h @@ -306,136 +306,11 @@ typedef struct cds_forward { } methods; } cab_decomp_state; -/* _Int as in "Internal" fyi */ - -typedef struct { - unsigned int FCI_Intmagic; - PERF perf; - PFNFCIFILEPLACED pfnfiledest; - PFNFCIALLOC pfnalloc; - PFNFCIFREE pfnfree; - PFNFCIOPEN pfnopen; - PFNFCIREAD pfnread; - PFNFCIWRITE pfnwrite; - PFNFCICLOSE pfnclose; - PFNFCISEEK pfnseek; - PFNFCIDELETE pfndelete; - PFNFCIGETTEMPFILE pfnfcigtf; - PCCAB pccab; - BOOL fPrevCab; - BOOL fNextCab; - BOOL fSplitFolder; - cab_ULONG statusFolderCopied; - cab_ULONG statusFolderTotal; - BOOL fGetNextCabInVain; - void *pv; - char szPrevCab[CB_MAX_CABINET_NAME]; /* previous cabinet name */ - char szPrevDisk[CB_MAX_DISK_NAME]; /* disk name of previous cabinet */ - CCAB oldCCAB; - char* data_in; /* uncompressed data blocks */ - cab_UWORD cdata_in; - char* data_out; /* compressed data blocks */ - ULONG cCompressedBytesInFolder; - cab_UWORD cFolders; - cab_UWORD cFiles; - cab_ULONG cDataBlocks; - cab_ULONG cbFileRemainer; /* uncompressed, yet to be written data */ - /* of spanned file of a spanning folder of a spanning cabinet */ - char szFileNameCFDATA1[CB_MAX_FILENAME]; - int handleCFDATA1; - char szFileNameCFFILE1[CB_MAX_FILENAME]; - int handleCFFILE1; - char szFileNameCFDATA2[CB_MAX_FILENAME]; - int handleCFDATA2; - char szFileNameCFFILE2[CB_MAX_FILENAME]; - int handleCFFILE2; - char szFileNameCFFOLDER[CB_MAX_FILENAME]; - int handleCFFOLDER; - cab_ULONG sizeFileCFDATA1; - cab_ULONG sizeFileCFFILE1; - cab_ULONG sizeFileCFDATA2; - cab_ULONG sizeFileCFFILE2; - cab_ULONG sizeFileCFFOLDER; - BOOL fNewPrevious; - cab_ULONG estimatedCabinetSize; -} FCI_Int, *PFCI_Int; - -typedef struct { - unsigned int FDI_Intmagic; - PFNALLOC pfnalloc; - PFNFREE pfnfree; - PFNOPEN pfnopen; - PFNREAD pfnread; - PFNWRITE pfnwrite; - PFNCLOSE pfnclose; - PFNSEEK pfnseek; - PERF perf; -} FDI_Int, *PFDI_Int; - -/* cast an HFCI into a PFCI_Int */ -#define PFCI_INT(hfci) ((PFCI_Int)(hfci)) - -/* cast an HFDI into a PFDI_Int */ -#define PFDI_INT(hfdi) ((PFDI_Int)(hfdi)) - -/* quick pfci method invokers */ -#define PFCI_ALLOC(hfdi, size) ((*PFCI_INT(hfdi)->pfnalloc) (size)) -#define PFCI_FREE(hfdi, ptr) ((*PFCI_INT(hfdi)->pfnfree) (ptr)) -#define PFCI_GETTEMPFILE(hfci,name,length) ((*PFCI_INT(hfci)->pfnfcigtf)(name,length,PFCI_INT(hfci)->pv)) -#define PFCI_DELETE(hfci,name,err,pv) ((*PFCI_INT(hfci)->pfndelete)(name,err,pv)) -#define PFCI_OPEN(hfci,name,oflag,pmode,err,pv) ((*PFCI_INT(hfci)->pfnopen)(name,oflag,pmode,err,pv)) -#define PFCI_READ(hfci,hf,memory,cb,err,pv)((*PFCI_INT(hfci)->pfnread)(hf,memory,cb,err,pv)) -#define PFCI_WRITE(hfci,hf,memory,cb,err,pv) ((*PFCI_INT(hfci)->pfnwrite)(hf,memory,cb,err,pv)) -#define PFCI_CLOSE(hfci,hf,err,pv) ((*PFCI_INT(hfci)->pfnclose)(hf,err,pv)) -#define PFCI_SEEK(hfci,hf,dist,seektype,err,pv)((*PFCI_INT(hfci)->pfnseek)(hf,dist,seektype,err,pv)) -#define PFCI_FILEPLACED(hfci,pccab,name,cb,cont,pv)((*PFCI_INT(hfci)->pfnfiledest)(pccab,name,cb,cont,pv)) - -/* quickie pfdi method invokers */ -#define PFDI_ALLOC(hfdi, size) ((*PFDI_INT(hfdi)->pfnalloc) (size)) -#define PFDI_FREE(hfdi, ptr) ((*PFDI_INT(hfdi)->pfnfree) (ptr)) -#define PFDI_OPEN(hfdi, file, flag, mode) ((*PFDI_INT(hfdi)->pfnopen) (file, flag, mode)) -#define PFDI_READ(hfdi, hf, pv, cb) ((*PFDI_INT(hfdi)->pfnread) (hf, pv, cb)) -#define PFDI_WRITE(hfdi, hf, pv, cb) ((*PFDI_INT(hfdi)->pfnwrite) (hf, pv, cb)) -#define PFDI_CLOSE(hfdi, hf) ((*PFDI_INT(hfdi)->pfnclose) (hf)) -#define PFDI_SEEK(hfdi, hf, dist, type) ((*PFDI_INT(hfdi)->pfnseek) (hf, dist, type)) - -#define FCI_INT_MAGIC 0xfcfcfc05 -#define FDI_INT_MAGIC 0xfdfdfd05 - -#define REALLY_IS_FCI(hfci) ( \ - ((hfci) != NULL) && \ - (PFCI_INT(hfci)->FCI_Intmagic == FCI_INT_MAGIC) ) - -#define REALLY_IS_FDI(hfdi) ( \ - ((hfdi) != NULL) && \ - (PFDI_INT(hfdi)->FDI_Intmagic == FDI_INT_MAGIC) ) - /* * the rest of these are somewhat kludgy macros which are shared between fdi.c * and cabextract.c. */ -#define ZIPNEEDBITS(n) {while(k<(n)){cab_LONG c=*(ZIP(inpos)++);\ - b|=((cab_ULONG)c)<>=(n);k-=(n);} - -/* endian-neutral reading of little-endian data */ -#define EndGetI32(a) ((((a)[3])<<24)|(((a)[2])<<16)|(((a)[1])<<8)|((a)[0])) -#define EndGetI16(a) ((((a)[1])<<8)|((a)[0])) - -#define CAB(x) (decomp_state->x) -#define ZIP(x) (decomp_state->methods.zip.x) -#define QTM(x) (decomp_state->methods.qtm.x) -#define LZX(x) (decomp_state->methods.lzx.x) -#define DECR_OK (0) -#define DECR_DATAFORMAT (1) -#define DECR_ILLEGALDATA (2) -#define DECR_NOMEMORY (3) -#define DECR_CHECKSUM (4) -#define DECR_INPUT (5) -#define DECR_OUTPUT (6) -#define DECR_USERABORT (7) - /* Bitstream reading macros (Quantum / normal byte order) * * Q_INIT_BITSTREAM should be used first to set up the system diff --git a/reactos/dll/win32/cabinet/cabinet.rbuild b/reactos/dll/win32/cabinet/cabinet.rbuild index 22b32681fab..5314c1b3c05 100644 --- a/reactos/dll/win32/cabinet/cabinet.rbuild +++ b/reactos/dll/win32/cabinet/cabinet.rbuild @@ -5,7 +5,9 @@ . include/reactos/wine + include/reactos/libs/zlib + cabinet_main.c fci.c fdi.c @@ -13,6 +15,7 @@ cabinet.rc cabinet.h wine + zlib ntdll diff --git a/reactos/dll/win32/cabinet/cabinet_main.c b/reactos/dll/win32/cabinet/cabinet_main.c index 45454f403e6..1f0daf8b46f 100644 --- a/reactos/dll/win32/cabinet/cabinet_main.c +++ b/reactos/dll/win32/cabinet/cabinet_main.c @@ -331,7 +331,7 @@ HRESULT WINAPI Extract(SESSION *dest, LPCSTR szCabName) { HRESULT res = S_OK; HFDI hfdi; - char *str, *path, *name; + char *str, *end, *path = NULL, *name = NULL; TRACE("(%p, %s)\n", dest, szCabName); @@ -363,13 +363,22 @@ HRESULT WINAPI Extract(SESSION *dest, LPCSTR szCabName) } lstrcpyA(str, szCabName); - path = str; - name = strrchr(path, '\\'); - if (name) - *name++ = 0; + if ((end = strrchr(str, '\\'))) + { + end++; + name = HeapAlloc( GetProcessHeap(), 0, strlen(end) + 1 ); + if (!name) + { + res = E_OUTOFMEMORY; + goto end; + } + strcpy( name, end ); + *end = 0; + path = str; + } else { - name = path; + name = str; path = NULL; } @@ -379,10 +388,9 @@ HRESULT WINAPI Extract(SESSION *dest, LPCSTR szCabName) fdi_notify_extract, NULL, dest)) res = HRESULT_FROM_WIN32(GetLastError()); - HeapFree(GetProcessHeap(), 0, str); end: - + HeapFree(GetProcessHeap(), 0, path); + HeapFree(GetProcessHeap(), 0, name); FDIDestroy(hfdi); - return res; } diff --git a/reactos/dll/win32/cabinet/fci.c b/reactos/dll/win32/cabinet/fci.c index 4166598ee97..70d4f3f170f 100644 --- a/reactos/dll/win32/cabinet/fci.c +++ b/reactos/dll/win32/cabinet/fci.c @@ -3,6 +3,7 @@ * * Copyright 2002 Patrik Stridvall * Copyright 2005 Gerold Jens Wucherpfennig + * Copyright 2011 Alexandre Julliard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,11 +24,9 @@ There is still some work to be done: -- no real compression yet - unknown behaviour if files>=2GB or cabinet >=4GB - check if the maximum size for a cabinet is too small to store any data - call pfnfcignc on exactly the same position as MS FCIAddFile in every case -- probably check err */ @@ -35,9 +34,13 @@ There is still some work to be done: #include "config.h" +#include #include #include #include +#ifdef HAVE_ZLIB +# include +#endif #include "windef.h" #include "winbase.h" @@ -45,8 +48,10 @@ There is still some work to be done: #include "winternl.h" #include "fci.h" #include "cabinet.h" +#include "wine/list.h" #include "wine/debug.h" +WINE_DEFAULT_DEBUG_CHANNEL(cabinet); #ifdef WORDS_BIGENDIAN #define fci_endian_ulong(x) RtlUlongByteSwap(x) @@ -57,13 +62,6 @@ There is still some work to be done: #endif -#define fci_set_error(A,B,C) do { \ - p_fci_internal->perf->erfOper = A; \ - p_fci_internal->perf->erfType = B; \ - p_fci_internal->perf->fError = C; \ - if (B) SetLastError(B); } while(0) - - typedef struct { cab_UBYTE signature[4]; /* !CAB for unfinished cabinets else MSCF */ cab_ULONG reserved1; @@ -108,6 +106,849 @@ typedef struct { /* compressed data */ } CFDATA; +struct temp_file +{ + INT_PTR handle; + char name[CB_MAX_FILENAME]; +}; + +struct folder +{ + struct list entry; + struct list files_list; + struct list blocks_list; + struct temp_file data; + cab_ULONG data_start; + cab_UWORD data_count; + TCOMP compression; +}; + +struct file +{ + struct list entry; + cab_ULONG size; /* uncompressed size */ + cab_ULONG offset; /* offset in folder */ + cab_UWORD folder; /* index of folder */ + cab_UWORD date; + cab_UWORD time; + cab_UWORD attribs; + char name[1]; +}; + +struct data_block +{ + struct list entry; + cab_UWORD compressed; + cab_UWORD uncompressed; +}; + +typedef struct FCI_Int +{ + unsigned int magic; + PERF perf; + PFNFCIFILEPLACED fileplaced; + PFNFCIALLOC alloc; + PFNFCIFREE free; + PFNFCIOPEN open; + PFNFCIREAD read; + PFNFCIWRITE write; + PFNFCICLOSE close; + PFNFCISEEK seek; + PFNFCIDELETE delete; + PFNFCIGETTEMPFILE gettemp; + CCAB ccab; + PCCAB pccab; + BOOL fPrevCab; + BOOL fNextCab; + BOOL fSplitFolder; + cab_ULONG statusFolderCopied; + cab_ULONG statusFolderTotal; + BOOL fGetNextCabInVain; + void *pv; + char szPrevCab[CB_MAX_CABINET_NAME]; /* previous cabinet name */ + char szPrevDisk[CB_MAX_DISK_NAME]; /* disk name of previous cabinet */ + unsigned char data_in[CAB_BLOCKMAX]; /* uncompressed data blocks */ + unsigned char data_out[2 * CAB_BLOCKMAX]; /* compressed data blocks */ + cab_UWORD cdata_in; + ULONG cCompressedBytesInFolder; + cab_UWORD cFolders; + cab_UWORD cFiles; + cab_ULONG cDataBlocks; + cab_ULONG cbFileRemainer; /* uncompressed, yet to be written data */ + /* of spanned file of a spanning folder of a spanning cabinet */ + struct temp_file data; + BOOL fNewPrevious; + cab_ULONG estimatedCabinetSize; + struct list folders_list; + struct list files_list; + struct list blocks_list; + cab_ULONG folders_size; + cab_ULONG files_size; /* size of files not yet assigned to a folder */ + cab_ULONG placed_files_size; /* size of files already placed into a folder */ + cab_ULONG pending_data_size; /* size of data not yet assigned to a folder */ + cab_ULONG folders_data_size; /* total size of data contained in the current folders */ + TCOMP compression; + cab_UWORD (*compress)(struct FCI_Int *); +} FCI_Int; + +#define FCI_INT_MAGIC 0xfcfcfc05 + +static void set_error( FCI_Int *fci, int oper, int err ) +{ + fci->perf->erfOper = oper; + fci->perf->erfType = err; + fci->perf->fError = TRUE; + if (err) SetLastError( err ); +} + +static FCI_Int *get_fci_ptr( HFCI hfci ) +{ + FCI_Int *fci= (FCI_Int *)hfci; + + if (!fci || fci->magic != FCI_INT_MAGIC) + { + SetLastError( ERROR_INVALID_HANDLE ); + return NULL; + } + 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 ) +{ + int err; + + if (!fci->gettemp( file->name, CB_MAX_FILENAME, fci->pv )) + { + set_error( fci, FCIERR_TEMP_FILE, ERROR_FUNCTION_FAILED ); + return FALSE; + } + if ((file->handle = fci->open( file->name, _O_RDWR | _O_CREAT | _O_EXCL | _O_BINARY, + _S_IREAD | _S_IWRITE, &err, fci->pv )) == -1) + { + set_error( fci, FCIERR_TEMP_FILE, err ); + return FALSE; + } + return TRUE; +} + +static BOOL close_temp_file( FCI_Int *fci, struct temp_file *file ) +{ + int err; + + if (file->handle == -1) return TRUE; + if (fci->close( file->handle, &err, fci->pv ) == -1) + { + set_error( fci, FCIERR_TEMP_FILE, err ); + return FALSE; + } + file->handle = -1; + if (fci->delete( file->name, &err, fci->pv ) == -1) + { + set_error( fci, FCIERR_TEMP_FILE, err ); + return FALSE; + } + return TRUE; +} + +static struct file *add_file( FCI_Int *fci, const char *filename ) +{ + unsigned int size = FIELD_OFFSET( struct file, name[strlen(filename) + 1] ); + struct file *file = fci->alloc( size ); + + if (!file) + { + set_error( fci, FCIERR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY ); + return NULL; + } + file->size = 0; + file->offset = fci->cDataBlocks * CAB_BLOCKMAX + fci->cdata_in; + file->folder = fci->cFolders; + file->date = 0; + file->time = 0; + file->attribs = 0; + strcpy( file->name, filename ); + list_add_tail( &fci->files_list, &file->entry ); + fci->files_size += sizeof(CFFILE) + strlen(filename) + 1; + return file; +} + +static struct file *copy_file( FCI_Int *fci, const struct file *orig ) +{ + unsigned int size = FIELD_OFFSET( struct file, name[strlen(orig->name) + 1] ); + struct file *file = fci->alloc( size ); + + if (!file) + { + set_error( fci, FCIERR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY ); + return NULL; + } + memcpy( file, orig, size ); + return file; +} + +static void free_file( FCI_Int *fci, struct file *file ) +{ + list_remove( &file->entry ); + fci->free( file ); +} + +/* create a new data block for the data in fci->data_in */ +static BOOL add_data_block( FCI_Int *fci, PFNFCISTATUS status_callback ) +{ + int err; + struct data_block *block; + + if (!fci->cdata_in) return TRUE; + + if (fci->data.handle == -1 && !create_temp_file( fci, &fci->data )) return FALSE; + + if (!(block = fci->alloc( sizeof(*block) ))) + { + set_error( fci, FCIERR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY ); + return FALSE; + } + block->uncompressed = fci->cdata_in; + block->compressed = fci->compress( fci ); + + if (fci->write( fci->data.handle, fci->data_out, + block->compressed, &err, fci->pv ) != block->compressed) + { + set_error( fci, FCIERR_TEMP_FILE, err ); + fci->free( block ); + return FALSE; + } + + fci->cdata_in = 0; + fci->pending_data_size += sizeof(CFDATA) + fci->ccab.cbReserveCFData + block->compressed; + fci->cCompressedBytesInFolder += block->compressed; + fci->cDataBlocks++; + list_add_tail( &fci->blocks_list, &block->entry ); + + if (status_callback( statusFile, block->compressed, block->uncompressed, fci->pv ) == -1) + { + set_error( fci, FCIERR_USER_ABORT, 0 ); + return FALSE; + } + return TRUE; +} + +/* add compressed blocks for all the data that can be read from the file */ +static BOOL add_file_data( FCI_Int *fci, char *sourcefile, char *filename, BOOL execute, + PFNFCIGETOPENINFO get_open_info, PFNFCISTATUS status_callback ) +{ + int err, len; + INT_PTR handle; + struct file *file; + + if (!(file = add_file( fci, filename ))) return FALSE; + + handle = get_open_info( sourcefile, &file->date, &file->time, &file->attribs, &err, fci->pv ); + if (handle == -1) + { + free_file( fci, file ); + set_error( fci, FCIERR_OPEN_SRC, err ); + return FALSE; + } + if (execute) file->attribs |= _A_EXEC; + + for (;;) + { + len = fci->read( handle, fci->data_in + fci->cdata_in, + CAB_BLOCKMAX - fci->cdata_in, &err, fci->pv ); + if (!len) break; + + if (len == -1) + { + set_error( fci, FCIERR_READ_SRC, err ); + return FALSE; + } + file->size += len; + fci->cdata_in += len; + if (fci->cdata_in == CAB_BLOCKMAX && !add_data_block( fci, status_callback )) return FALSE; + } + fci->close( handle, &err, fci->pv ); + return TRUE; +} + +static void free_data_block( FCI_Int *fci, struct data_block *block ) +{ + list_remove( &block->entry ); + fci->free( block ); +} + +static struct folder *add_folder( FCI_Int *fci ) +{ + struct folder *folder = fci->alloc( sizeof(*folder) ); + + if (!folder) + { + set_error( fci, FCIERR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY ); + return NULL; + } + folder->data.handle = -1; + folder->data_start = fci->folders_data_size; + folder->data_count = 0; + folder->compression = fci->compression; + list_init( &folder->files_list ); + list_init( &folder->blocks_list ); + list_add_tail( &fci->folders_list, &folder->entry ); + fci->folders_size += sizeof(CFFOLDER) + fci->ccab.cbReserveCFFolder; + fci->cFolders++; + return folder; +} + +static void free_folder( FCI_Int *fci, struct folder *folder ) +{ + struct file *file, *file_next; + struct data_block *block, *block_next; + + LIST_FOR_EACH_ENTRY_SAFE( file, file_next, &folder->files_list, struct file, entry ) + free_file( fci, file ); + LIST_FOR_EACH_ENTRY_SAFE( block, block_next, &folder->blocks_list, struct data_block, entry ) + free_data_block( fci, block ); + close_temp_file( fci, &folder->data ); + list_remove( &folder->entry ); + fci->free( folder ); +} + +/* reset state for the next cabinet file once the current one has been flushed */ +static void reset_cabinet( FCI_Int *fci ) +{ + struct folder *folder, *folder_next; + + LIST_FOR_EACH_ENTRY_SAFE( folder, folder_next, &fci->folders_list, struct folder, entry ) + free_folder( fci, folder ); + + fci->cFolders = 0; + fci->cFiles = 0; + fci->folders_size = 0; + fci->placed_files_size = 0; + fci->folders_data_size = 0; +} + +static cab_ULONG fci_get_checksum( const void *pv, UINT cb, cab_ULONG seed ) +{ + cab_ULONG csum; + cab_ULONG ul; + int cUlong; + const BYTE *pb; + + csum = seed; + cUlong = cb / 4; + pb = pv; + + while (cUlong-- > 0) { + ul = *pb++; + ul |= (((cab_ULONG)(*pb++)) << 8); + ul |= (((cab_ULONG)(*pb++)) << 16); + ul |= (((cab_ULONG)(*pb++)) << 24); + csum ^= ul; + } + + ul = 0; + switch (cb % 4) { + case 3: + ul |= (((ULONG)(*pb++)) << 16); + /* fall through */ + case 2: + ul |= (((ULONG)(*pb++)) << 8); + /* fall through */ + case 1: + ul |= *pb; + /* fall through */ + default: + break; + } + csum ^= ul; + + return csum; +} + +/* copy all remaining data block to a new temp file */ +static BOOL copy_data_blocks( FCI_Int *fci, INT_PTR handle, cab_ULONG start_pos, + struct temp_file *temp, PFNFCISTATUS status_callback ) +{ + struct data_block *block; + int err; + + if (fci->seek( handle, start_pos, SEEK_SET, &err, fci->pv ) != start_pos) + { + set_error( fci, FCIERR_TEMP_FILE, err ); + return FALSE; + } + if (!create_temp_file( fci, temp )) return FALSE; + + LIST_FOR_EACH_ENTRY( block, &fci->blocks_list, struct data_block, entry ) + { + if (fci->read( handle, fci->data_out, block->compressed, + &err, fci->pv ) != block->compressed) + { + close_temp_file( fci, temp ); + set_error( fci, FCIERR_TEMP_FILE, err ); + return FALSE; + } + if (fci->write( temp->handle, fci->data_out, block->compressed, + &err, fci->pv ) != block->compressed) + { + close_temp_file( fci, temp ); + set_error( fci, FCIERR_TEMP_FILE, err ); + return FALSE; + } + fci->pending_data_size += sizeof(CFDATA) + fci->ccab.cbReserveCFData + block->compressed; + fci->statusFolderCopied += block->compressed; + + if (status_callback( statusFolder, fci->statusFolderCopied, + fci->statusFolderTotal, fci->pv) == -1) + { + close_temp_file( fci, temp ); + set_error( fci, FCIERR_USER_ABORT, 0 ); + return FALSE; + } + } + return TRUE; +} + +/* write all folders to disk and remove them from the list */ +static BOOL write_folders( FCI_Int *fci, INT_PTR handle, cab_ULONG header_size, PFNFCISTATUS status_callback ) +{ + struct folder *folder; + int err; + CFFOLDER *cffolder = (CFFOLDER *)fci->data_out; + cab_ULONG folder_size = sizeof(CFFOLDER) + fci->ccab.cbReserveCFFolder; + + memset( cffolder, 0, folder_size ); + + /* write the folders */ + LIST_FOR_EACH_ENTRY( folder, &fci->folders_list, struct folder, entry ) + { + cffolder->coffCabStart = fci_endian_ulong( folder->data_start + header_size ); + cffolder->cCFData = fci_endian_uword( folder->data_count ); + cffolder->typeCompress = fci_endian_uword( folder->compression ); + if (fci->write( handle, cffolder, folder_size, &err, fci->pv ) != folder_size) + { + set_error( fci, FCIERR_CAB_FILE, err ); + return FALSE; + } + } + return TRUE; +} + +/* write all the files to the cabinet file */ +static BOOL write_files( FCI_Int *fci, INT_PTR handle, PFNFCISTATUS status_callback ) +{ + cab_ULONG file_size; + struct folder *folder; + struct file *file; + int err; + CFFILE *cffile = (CFFILE *)fci->data_out; + + LIST_FOR_EACH_ENTRY( folder, &fci->folders_list, struct folder, entry ) + { + LIST_FOR_EACH_ENTRY( file, &folder->files_list, struct file, entry ) + { + cffile->cbFile = fci_endian_ulong( file->size ); + cffile->uoffFolderStart = fci_endian_ulong( file->offset ); + cffile->iFolder = fci_endian_uword( file->folder ); + cffile->date = fci_endian_uword( file->date ); + cffile->time = fci_endian_uword( file->time ); + cffile->attribs = fci_endian_uword( file->attribs ); + lstrcpynA( (char *)(cffile + 1), file->name, CB_MAX_FILENAME ); + file_size = sizeof(CFFILE) + strlen( (char *)(cffile + 1) ) + 1; + if (fci->write( handle, cffile, file_size, &err, fci->pv ) != file_size) + { + set_error( fci, FCIERR_CAB_FILE, err ); + return FALSE; + } + if (!fci->fSplitFolder) + { + fci->statusFolderCopied = 0; + /* TODO TEST THIS further */ + fci->statusFolderTotal = fci->folders_data_size + fci->placed_files_size; + } + fci->statusFolderCopied += file_size; + /* report status about copied size of folder */ + if (status_callback( statusFolder, fci->statusFolderCopied, + fci->statusFolderTotal, fci->pv ) == -1) + { + set_error( fci, FCIERR_USER_ABORT, 0 ); + return FALSE; + } + } + } + return TRUE; +} + +/* write all data blocks to the cabinet file */ +static BOOL write_data_blocks( FCI_Int *fci, INT_PTR handle, PFNFCISTATUS status_callback ) +{ + struct folder *folder; + struct data_block *block; + int err, len; + CFDATA *cfdata; + void *data; + cab_UWORD header_size; + + header_size = sizeof(CFDATA) + fci->ccab.cbReserveCFData; + cfdata = (CFDATA *)fci->data_out; + memset( cfdata, 0, header_size ); + data = (char *)cfdata + header_size; + + LIST_FOR_EACH_ENTRY( folder, &fci->folders_list, struct folder, entry ) + { + if (fci->seek( folder->data.handle, 0, SEEK_SET, &err, fci->pv ) != 0) + { + set_error( fci, FCIERR_CAB_FILE, err ); + return FALSE; + } + LIST_FOR_EACH_ENTRY( block, &folder->blocks_list, struct data_block, entry ) + { + len = fci->read( folder->data.handle, data, block->compressed, &err, fci->pv ); + if (len != block->compressed) return FALSE; + + cfdata->cbData = fci_endian_uword( block->compressed ); + cfdata->cbUncomp = fci_endian_uword( block->uncompressed ); + cfdata->csum = fci_endian_ulong( fci_get_checksum( &cfdata->cbData, + header_size - FIELD_OFFSET(CFDATA, cbData), + fci_get_checksum( data, len, 0 ))); + + fci->statusFolderCopied += len; + len += header_size; + if (fci->write( handle, fci->data_out, len, &err, fci->pv ) != len) + { + set_error( fci, FCIERR_CAB_FILE, err ); + return FALSE; + } + if (status_callback( statusFolder, fci->statusFolderCopied, fci->statusFolderTotal, fci->pv) == -1) + { + set_error( fci, FCIERR_USER_ABORT, 0 ); + return FALSE; + } + } + } + return TRUE; +} + +/* write the cabinet file to disk */ +static BOOL write_cabinet( FCI_Int *fci, PFNFCISTATUS status_callback ) +{ + char filename[CB_MAX_CAB_PATH + CB_MAX_CABINET_NAME]; + int err; + char *ptr; + INT_PTR handle; + CFHEADER *cfheader = (CFHEADER *)fci->data_out; + cab_UWORD flags = 0; + cab_ULONG header_size = get_header_size( fci ); + cab_ULONG total_size = header_size + fci->folders_size + + fci->placed_files_size + fci->folders_data_size; + + assert( header_size <= sizeof(fci->data_out) ); + memset( cfheader, 0, header_size ); + + if (fci->fPrevCab) flags |= cfheadPREV_CABINET; + if (fci->fNextCab) flags |= cfheadNEXT_CABINET; + if (fci->ccab.cbReserveCFHeader || fci->ccab.cbReserveCFFolder || fci->ccab.cbReserveCFData) + flags |= cfheadRESERVE_PRESENT; + + memcpy( cfheader->signature, "!CAB", 4 ); + cfheader->cbCabinet = fci_endian_ulong( total_size ); + cfheader->coffFiles = fci_endian_ulong( header_size + fci->folders_size ); + cfheader->versionMinor = 3; + cfheader->versionMajor = 1; + cfheader->cFolders = fci_endian_uword( fci->cFolders ); + cfheader->cFiles = fci_endian_uword( fci->cFiles ); + cfheader->flags = fci_endian_uword( flags ); + cfheader->setID = fci_endian_uword( fci->ccab.setID ); + cfheader->iCabinet = fci_endian_uword( fci->ccab.iCab ); + ptr = (char *)(cfheader + 1); + + if (flags & cfheadRESERVE_PRESENT) + { + struct + { + cab_UWORD cbCFHeader; + cab_UBYTE cbCFFolder; + cab_UBYTE cbCFData; + } *reserve = (void *)ptr; + + reserve->cbCFHeader = fci_endian_uword( fci->ccab.cbReserveCFHeader ); + reserve->cbCFFolder = fci->ccab.cbReserveCFFolder; + reserve->cbCFData = fci->ccab.cbReserveCFData; + ptr = (char *)(reserve + 1); + } + ptr += fci->ccab.cbReserveCFHeader; + + if (flags & cfheadPREV_CABINET) + { + strcpy( ptr, fci->szPrevCab ); + ptr += strlen( ptr ) + 1; + strcpy( ptr, fci->szPrevDisk ); + ptr += strlen( ptr ) + 1; + } + + if (flags & cfheadNEXT_CABINET) + { + strcpy( ptr, fci->pccab->szCab ); + ptr += strlen( ptr ) + 1; + strcpy( ptr, fci->pccab->szDisk ); + ptr += strlen( ptr ) + 1; + } + + assert( ptr - (char *)cfheader == header_size ); + + strcpy( filename, fci->ccab.szCabPath ); + strcat( filename, fci->ccab.szCab ); + + if ((handle = fci->open( filename, _O_RDWR | _O_CREAT | _O_TRUNC | _O_BINARY, + _S_IREAD | _S_IWRITE, &err, fci->pv )) == -1) + { + set_error( fci, FCIERR_CAB_FILE, err ); + return FALSE; + } + + if (fci->write( handle, cfheader, header_size, &err, fci->pv ) != header_size) + { + set_error( fci, FCIERR_CAB_FILE, err ); + goto failed; + } + + /* add size of header size of all CFFOLDERs and size of all CFFILEs */ + header_size += fci->placed_files_size + fci->folders_size; + if (!write_folders( fci, handle, header_size, status_callback )) goto failed; + if (!write_files( fci, handle, status_callback )) goto failed; + if (!write_data_blocks( fci, handle, status_callback )) goto failed; + + /* update the signature */ + if (fci->seek( handle, 0, SEEK_SET, &err, fci->pv ) != 0 ) + { + set_error( fci, FCIERR_CAB_FILE, err ); + goto failed; + } + memcpy( cfheader->signature, "MSCF", 4 ); + if (fci->write( handle, cfheader->signature, 4, &err, fci->pv ) != 4) + { + set_error( fci, FCIERR_CAB_FILE, err ); + goto failed; + } + fci->close( handle, &err, fci->pv ); + + reset_cabinet( fci ); + status_callback( statusCabinet, fci->estimatedCabinetSize, total_size, fci->pv ); + return TRUE; + +failed: + fci->close( handle, &err, fci->pv ); + fci->delete( filename, &err, fci->pv ); + return FALSE; +} + +/* add all pending data blocks folder */ +static BOOL add_data_to_folder( FCI_Int *fci, struct folder *folder, cab_ULONG *payload, + PFNFCISTATUS status_callback ) +{ + struct data_block *block, *new, *next; + BOOL split_block = FALSE; + cab_ULONG current_size, start_pos = 0; + + *payload = 0; + current_size = get_header_size( fci ) + fci->folders_size + + fci->files_size + fci->placed_files_size + fci->folders_data_size; + + /* move the temp file into the folder structure */ + folder->data = fci->data; + fci->data.handle = -1; + fci->pending_data_size = 0; + + LIST_FOR_EACH_ENTRY_SAFE( block, next, &fci->blocks_list, struct data_block, entry ) + { + /* No more CFDATA fits into the cabinet under construction */ + /* So don't try to store more data into it */ + if (fci->fNextCab && (fci->ccab.cb <= sizeof(CFDATA) + fci->ccab.cbReserveCFData + + current_size + sizeof(CFFOLDER) + fci->ccab.cbReserveCFFolder)) + break; + + if (!(new = fci->alloc( sizeof(*new) ))) + { + set_error( fci, FCIERR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY ); + return FALSE; + } + /* Is cabinet with new CFDATA too large? Then data block has to be split */ + if( fci->fNextCab && + (fci->ccab.cb < sizeof(CFDATA) + fci->ccab.cbReserveCFData + + block->compressed + current_size + sizeof(CFFOLDER) + fci->ccab.cbReserveCFFolder)) + { + /* Modify the size of the compressed data to store only a part of the */ + /* data block into the current cabinet. This is done to prevent */ + /* that the maximum cabinet size will be exceeded. The remainder */ + /* will be stored into the next following cabinet. */ + + new->compressed = fci->ccab.cb - (sizeof(CFDATA) + fci->ccab.cbReserveCFData + current_size + + sizeof(CFFOLDER) + fci->ccab.cbReserveCFFolder ); + new->uncompressed = 0; /* on split blocks of data this is zero */ + block->compressed -= new->compressed; + split_block = TRUE; + } + else + { + new->compressed = block->compressed; + new->uncompressed = block->uncompressed; + } + + start_pos += new->compressed; + current_size += sizeof(CFDATA) + fci->ccab.cbReserveCFData + new->compressed; + fci->folders_data_size += sizeof(CFDATA) + fci->ccab.cbReserveCFData + new->compressed; + fci->statusFolderCopied += new->compressed; + (*payload) += new->uncompressed; + + list_add_tail( &folder->blocks_list, &new->entry ); + folder->data_count++; + + /* report status with pfnfcis about copied size of folder */ + if (status_callback( statusFolder, fci->statusFolderCopied, + fci->statusFolderTotal, fci->pv ) == -1) + { + set_error( fci, FCIERR_USER_ABORT, 0 ); + return FALSE; + } + if (split_block) break; + free_data_block( fci, block ); + fci->cDataBlocks--; + } + + if (list_empty( &fci->blocks_list )) return TRUE; + return copy_data_blocks( fci, folder->data.handle, start_pos, &fci->data, status_callback ); +} + +/* add all pending files to folder */ +static BOOL add_files_to_folder( FCI_Int *fci, struct folder *folder, cab_ULONG payload ) +{ + cab_ULONG sizeOfFiles = 0, sizeOfFilesPrev; + cab_ULONG cbFileRemainer = 0; + struct file *file, *next; + + LIST_FOR_EACH_ENTRY_SAFE( file, next, &fci->files_list, struct file, entry ) + { + cab_ULONG size = sizeof(CFFILE) + strlen(file->name) + 1; + + /* fnfilfnfildest: placed file on cabinet */ + fci->fileplaced( &fci->ccab, file->name, file->size, + (file->folder == cffileCONTINUED_FROM_PREV), fci->pv ); + + sizeOfFilesPrev = sizeOfFiles; + /* set complete size of all processed files */ + if (file->folder == cffileCONTINUED_FROM_PREV && fci->cbFileRemainer != 0) + { + sizeOfFiles += fci->cbFileRemainer; + fci->cbFileRemainer = 0; + } + else sizeOfFiles += file->size; + + /* check if spanned file fits into this cabinet folder */ + if (sizeOfFiles > payload) + { + if (file->folder == cffileCONTINUED_FROM_PREV) + file->folder = cffileCONTINUED_PREV_AND_NEXT; + else + file->folder = cffileCONTINUED_TO_NEXT; + } + + list_remove( &file->entry ); + list_add_tail( &folder->files_list, &file->entry ); + fci->placed_files_size += size; + fci->cFiles++; + + /* This is only true for files which will be written into the */ + /* next cabinet of the spanning folder */ + if (sizeOfFiles > payload) + { + /* add a copy back onto the list */ + if (!(file = copy_file( fci, file ))) return FALSE; + list_add_before( &next->entry, &file->entry ); + + /* Files which data will be partially written into the current cabinet */ + if (file->folder == cffileCONTINUED_PREV_AND_NEXT || file->folder == cffileCONTINUED_TO_NEXT) + { + if (sizeOfFilesPrev <= payload) + { + /* The size of the uncompressed, data of a spanning file in a */ + /* spanning data */ + cbFileRemainer = sizeOfFiles - payload; + } + file->folder = cffileCONTINUED_FROM_PREV; + } + else file->folder = 0; + } + else + { + fci->files_size -= size; + } + } + fci->cbFileRemainer = cbFileRemainer; + return TRUE; +} + +static cab_UWORD compress_NONE( FCI_Int *fci ) +{ + memcpy( fci->data_out, fci->data_in, fci->cdata_in ); + return fci->cdata_in; +} + +#ifdef HAVE_ZLIB + +static void *zalloc( void *opaque, unsigned int items, unsigned int size ) +{ + FCI_Int *fci = opaque; + return fci->alloc( items * size ); +} + +static void zfree( void *opaque, void *ptr ) +{ + FCI_Int *fci = opaque; + fci->free( ptr ); +} + +static cab_UWORD compress_MSZIP( FCI_Int *fci ) +{ + z_stream stream; + + stream.zalloc = zalloc; + stream.zfree = zfree; + stream.opaque = fci; + if (deflateInit2( &stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY ) != Z_OK) + { + set_error( fci, FCIERR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY ); + return 0; + } + stream.next_in = fci->data_in; + stream.avail_in = fci->cdata_in; + stream.next_out = fci->data_out + 2; + stream.avail_out = sizeof(fci->data_out) - 2; + /* insert the signature */ + fci->data_out[0] = 'C'; + fci->data_out[1] = 'K'; + deflate( &stream, Z_FINISH ); + deflateEnd( &stream ); + return stream.total_out + 2; +} + +#endif /* HAVE_ZLIB */ + /*********************************************************************** * FCICreate (CABINET.10) @@ -169,9 +1010,7 @@ HFCI __cdecl FCICreate( PCCAB pccab, void *pv) { - HFCI hfci; - int err; - PFCI_Int p_fci_internal; + FCI_Int *p_fci_internal; if (!perf) { SetLastError(ERROR_BAD_ARGUMENTS); @@ -188,7 +1027,7 @@ HFCI __cdecl FCICreate( return NULL; } - if (!((hfci = (*pfnalloc)(sizeof(FCI_Int))))) { + if (!((p_fci_internal = pfnalloc(sizeof(FCI_Int))))) { perf->erfOper = FCIERR_ALLOC_FAIL; perf->erfType = ERROR_NOT_ENOUGH_MEMORY; perf->fError = TRUE; @@ -197,980 +1036,89 @@ HFCI __cdecl FCICreate( return NULL; } - p_fci_internal=((PFCI_Int)(hfci)); - p_fci_internal->FCI_Intmagic = FCI_INT_MAGIC; + p_fci_internal->magic = FCI_INT_MAGIC; p_fci_internal->perf = perf; - p_fci_internal->pfnfiledest = pfnfiledest; - p_fci_internal->pfnalloc = pfnalloc; - p_fci_internal->pfnfree = pfnfree; - p_fci_internal->pfnopen = pfnopen; - p_fci_internal->pfnread = pfnread; - p_fci_internal->pfnwrite = pfnwrite; - p_fci_internal->pfnclose = pfnclose; - p_fci_internal->pfnseek = pfnseek; - p_fci_internal->pfndelete = pfndelete; - p_fci_internal->pfnfcigtf = pfnfcigtf; + p_fci_internal->fileplaced = pfnfiledest; + p_fci_internal->alloc = pfnalloc; + p_fci_internal->free = pfnfree; + p_fci_internal->open = pfnopen; + p_fci_internal->read = pfnread; + p_fci_internal->write = pfnwrite; + p_fci_internal->close = pfnclose; + p_fci_internal->seek = pfnseek; + p_fci_internal->delete = pfndelete; + p_fci_internal->gettemp = pfnfcigtf; + p_fci_internal->ccab = *pccab; p_fci_internal->pccab = pccab; p_fci_internal->fPrevCab = FALSE; p_fci_internal->fNextCab = FALSE; p_fci_internal->fSplitFolder = FALSE; p_fci_internal->fGetNextCabInVain = FALSE; p_fci_internal->pv = pv; - p_fci_internal->data_in = NULL; p_fci_internal->cdata_in = 0; - p_fci_internal->data_out = NULL; p_fci_internal->cCompressedBytesInFolder = 0; p_fci_internal->cFolders = 0; p_fci_internal->cFiles = 0; p_fci_internal->cDataBlocks = 0; - p_fci_internal->sizeFileCFDATA1 = 0; - p_fci_internal->sizeFileCFFILE1 = 0; - p_fci_internal->sizeFileCFDATA2 = 0; - p_fci_internal->sizeFileCFFILE2 = 0; - p_fci_internal->sizeFileCFFOLDER = 0; - p_fci_internal->sizeFileCFFOLDER = 0; + p_fci_internal->data.handle = -1; p_fci_internal->fNewPrevious = FALSE; p_fci_internal->estimatedCabinetSize = 0; p_fci_internal->statusFolderTotal = 0; + p_fci_internal->folders_size = 0; + p_fci_internal->files_size = 0; + p_fci_internal->placed_files_size = 0; + p_fci_internal->pending_data_size = 0; + p_fci_internal->folders_data_size = 0; + p_fci_internal->compression = tcompTYPE_NONE; + p_fci_internal->compress = compress_NONE; + + list_init( &p_fci_internal->folders_list ); + list_init( &p_fci_internal->files_list ); + list_init( &p_fci_internal->blocks_list ); - memset(&p_fci_internal->oldCCAB, 0, sizeof(CCAB)); memcpy(p_fci_internal->szPrevCab, pccab->szCab, CB_MAX_CABINET_NAME); memcpy(p_fci_internal->szPrevDisk, pccab->szDisk, CB_MAX_DISK_NAME); - /* CFDATA */ - if( !PFCI_GETTEMPFILE(hfci,p_fci_internal->szFileNameCFDATA1, - CB_MAX_FILENAME)) { - fci_set_error( FCIERR_NONE, ERROR_FUNCTION_FAILED, TRUE ); - return FALSE; - } - /* safety */ - if ( strlen(p_fci_internal->szFileNameCFDATA1) >= CB_MAX_FILENAME ) { - fci_set_error( FCIERR_NONE, ERROR_INVALID_DATA, TRUE ); - return FALSE; - } + return (HFCI)p_fci_internal; +} - p_fci_internal->handleCFDATA1 = PFCI_OPEN(hfci, - p_fci_internal->szFileNameCFDATA1, 34050, 384, &err, pv); - if(p_fci_internal->handleCFDATA1==0){ - fci_set_error( FCIERR_TEMP_FILE, ERROR_OPEN_FAILED, TRUE ); - return FALSE; - } - /* TODO error checking of err */ - /* array of all CFFILE in a folder */ - if( !PFCI_GETTEMPFILE(hfci,p_fci_internal->szFileNameCFFILE1, - CB_MAX_FILENAME)) { - fci_set_error( FCIERR_NONE, ERROR_FUNCTION_FAILED, TRUE ); - return FALSE; - } - /* safety */ - if ( strlen(p_fci_internal->szFileNameCFFILE1) >= CB_MAX_FILENAME ) { - fci_set_error( FCIERR_NONE, ERROR_INVALID_DATA, TRUE ); - return FALSE; - } - p_fci_internal->handleCFFILE1 = PFCI_OPEN(hfci, - p_fci_internal->szFileNameCFFILE1, 34050, 384, &err, pv); - if(p_fci_internal->handleCFFILE1==0){ - fci_set_error( FCIERR_TEMP_FILE, ERROR_OPEN_FAILED, TRUE ); - return FALSE; - } - /* TODO error checking of err */ - /* CFDATA with checksum and ready to be copied into cabinet */ - if( !PFCI_GETTEMPFILE(hfci,p_fci_internal->szFileNameCFDATA2, - CB_MAX_FILENAME)) { - fci_set_error( FCIERR_NONE, ERROR_FUNCTION_FAILED, TRUE); - return FALSE; - } - /* safety */ - if ( strlen(p_fci_internal->szFileNameCFDATA2) >= CB_MAX_FILENAME ) { - fci_set_error( FCIERR_NONE, ERROR_INVALID_DATA, TRUE ); - return FALSE; - } - p_fci_internal->handleCFDATA2 = PFCI_OPEN(hfci, - p_fci_internal->szFileNameCFDATA2, 34050, 384, &err, pv); - if(p_fci_internal->handleCFDATA2==0){ - fci_set_error( FCIERR_TEMP_FILE, ERROR_OPEN_FAILED, TRUE ); - return FALSE; - } - /* TODO error checking of err */ - /* array of all CFFILE in a folder, ready to be copied into cabinet */ - if( !PFCI_GETTEMPFILE(hfci,p_fci_internal->szFileNameCFFILE2, - CB_MAX_FILENAME)) { - fci_set_error( FCIERR_NONE, ERROR_FUNCTION_FAILED, TRUE ); - return FALSE; - } - /* safety */ - if ( strlen(p_fci_internal->szFileNameCFFILE2) >= CB_MAX_FILENAME ) { - fci_set_error( FCIERR_NONE, ERROR_INVALID_DATA, TRUE ); - return FALSE; - } - p_fci_internal->handleCFFILE2 = PFCI_OPEN(hfci, - p_fci_internal->szFileNameCFFILE2, 34050, 384, &err, pv); - if(p_fci_internal->handleCFFILE2==0){ - fci_set_error( FCIERR_TEMP_FILE, ERROR_OPEN_FAILED, TRUE ); - return FALSE; - } - /* TODO error checking of err */ - - /* array of all CFFILE in a folder, ready to be copied into cabinet */ - if( !PFCI_GETTEMPFILE(hfci,p_fci_internal->szFileNameCFFOLDER, - CB_MAX_FILENAME)) { - fci_set_error( FCIERR_NONE, ERROR_FUNCTION_FAILED, TRUE ); - return FALSE; - } - /* safety */ - if ( strlen(p_fci_internal->szFileNameCFFOLDER) >= CB_MAX_FILENAME ) { - fci_set_error( FCIERR_NONE, ERROR_INVALID_DATA, TRUE ); - return FALSE; - } - p_fci_internal->handleCFFOLDER = PFCI_OPEN(hfci, - p_fci_internal->szFileNameCFFOLDER, 34050, 384, &err, pv); - if(p_fci_internal->handleCFFOLDER==0) { - fci_set_error( FCIERR_TEMP_FILE, ERROR_OPEN_FAILED, TRUE); - return FALSE; - } - - /* TODO close and delete new files when return FALSE */ - /* TODO error checking of err */ - - return hfci; -} /* end of FCICreate */ - - - - - - -static BOOL fci_flush_data_block (HFCI hfci, int* err, - PFNFCISTATUS pfnfcis) { - - /* attention no hfci checks!!! */ - /* attention no checks if there is data available!!! */ - CFDATA data; - CFDATA* cfdata=&data; - char* reserved; - PFCI_Int p_fci_internal=((PFCI_Int)(hfci)); - UINT cbReserveCFData=p_fci_internal->pccab->cbReserveCFData; - UINT i; - - /* TODO compress the data of p_fci_internal->data_in */ - /* and write it to p_fci_internal->data_out */ - memcpy(p_fci_internal->data_out, p_fci_internal->data_in, - p_fci_internal->cdata_in /* number of bytes to copy */); - - cfdata->csum=0; /* checksum has to be set later */ - /* TODO set realsize of compressed data */ - cfdata->cbData = p_fci_internal->cdata_in; - cfdata->cbUncomp = p_fci_internal->cdata_in; - - /* write cfdata to p_fci_internal->handleCFDATA1 */ - if( PFCI_WRITE(hfci, p_fci_internal->handleCFDATA1, /* file handle */ - cfdata, sizeof(*cfdata), err, p_fci_internal->pv) - != sizeof(*cfdata) ) { - fci_set_error( FCIERR_TEMP_FILE, ERROR_WRITE_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - p_fci_internal->sizeFileCFDATA1 += sizeof(*cfdata); - - /* add optional reserved area */ - - /* This allocation and freeing at each CFData block is a bit */ - /* inefficient, but it's harder to forget about freeing the buffer :-). */ - /* Reserved areas are used seldom besides that... */ - if (cbReserveCFData!=0) { - if(!(reserved = PFCI_ALLOC(hfci, cbReserveCFData))) { - fci_set_error( FCIERR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY, TRUE ); - return FALSE; - } - for(i=0;ihandleCFDATA1, /* file handle */ - reserved, /* memory buffer */ - cbReserveCFData, /* number of bytes to copy */ - err, p_fci_internal->pv) != cbReserveCFData ) { - PFCI_FREE(hfci, reserved); - fci_set_error( FCIERR_TEMP_FILE, ERROR_WRITE_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err PFCI_FREE(hfci, reserved)*/ - - p_fci_internal->sizeFileCFDATA1 += cbReserveCFData; - PFCI_FREE(hfci, reserved); - } - - /* write p_fci_internal->data_out to p_fci_internal->handleCFDATA1 */ - if( PFCI_WRITE(hfci, p_fci_internal->handleCFDATA1, /* file handle */ - p_fci_internal->data_out, /* memory buffer */ - cfdata->cbData, /* number of bytes to copy */ - err, p_fci_internal->pv) != cfdata->cbData) { - fci_set_error( FCIERR_TEMP_FILE, ERROR_WRITE_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - p_fci_internal->sizeFileCFDATA1 += cfdata->cbData; - - /* reset the offset */ - p_fci_internal->cdata_in = 0; - p_fci_internal->cCompressedBytesInFolder += cfdata->cbData; - - /* report status with pfnfcis about uncompressed and compressed file data */ - if( (*pfnfcis)(statusFile, cfdata->cbData, cfdata->cbUncomp, - p_fci_internal->pv) == -1) { - fci_set_error( FCIERR_USER_ABORT, 0, TRUE ); - return FALSE; - } - - ++(p_fci_internal->cDataBlocks); - - return TRUE; -} /* end of fci_flush_data_block */ - - - - - -static cab_ULONG fci_get_checksum(const void *pv, UINT cb, CHECKSUM seed) -{ - cab_ULONG csum; - cab_ULONG ul; - int cUlong; - const BYTE *pb; - - csum = seed; - cUlong = cb / 4; - pb = pv; - - while (cUlong-- > 0) { - ul = *pb++; - ul |= (((cab_ULONG)(*pb++)) << 8); - ul |= (((cab_ULONG)(*pb++)) << 16); - ul |= (((cab_ULONG)(*pb++)) << 24); - - csum ^= ul; - } - - ul = 0; - switch (cb % 4) { - case 3: - ul |= (((ULONG)(*pb++)) << 16); - case 2: - ul |= (((ULONG)(*pb++)) << 8); - case 1: - ul |= *pb; - default: - break; - } - csum ^= ul; - - return csum; -} /* end of fci_get_checksum */ - - - -static BOOL fci_flushfolder_copy_cfdata(HFCI hfci, char* buffer, UINT cbReserveCFData, - PFNFCISTATUS pfnfcis, int* err, int handleCFDATA1new, - cab_ULONG* psizeFileCFDATA1new, cab_ULONG* payload) -{ - cab_ULONG read_result; - CFDATA* pcfdata=(CFDATA*)buffer; - BOOL split_block=FALSE; - cab_UWORD savedUncomp=0; - PFCI_Int p_fci_internal=((PFCI_Int)(hfci)); - - *payload=0; - - /* while not all CFDATAs have been copied do */ - while(!FALSE) { - if( p_fci_internal->fNextCab ) { - if( split_block ) { - /* internal error should never happen */ - fci_set_error( FCIERR_NONE, ERROR_GEN_FAILURE, TRUE ); - 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 */ - /* So don't try to store more data into it */ - if( p_fci_internal->fNextCab && - (p_fci_internal->oldCCAB.cb <= sizeof(CFDATA) + cbReserveCFData + - p_fci_internal->sizeFileCFFILE1 + p_fci_internal->sizeFileCFDATA2 + - p_fci_internal->sizeFileCFFILE2 + p_fci_internal->sizeFileCFFOLDER + - sizeof(CFHEADER) + - read_result + - 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. - Pray that the code that calls fci_flushfolder_copy_cfdata handles this.*/ - split_block=TRUE; /* In this case split_block is abused to store */ - /* the complete data block into the next cabinet and not into the */ - /* current one. Originally split_block is the indicator that a */ - /* data block has been split across different cabinets. */ - } else { - - /* read CFDATA from p_fci_internal->handleCFDATA1 to cfdata*/ - read_result= PFCI_READ(hfci, p_fci_internal->handleCFDATA1,/*file handle*/ - buffer, /* memory buffer */ - sizeof(CFDATA)+cbReserveCFData, /* number of bytes to copy */ - err, p_fci_internal->pv); - if (read_result!=sizeof(CFDATA)+cbReserveCFData) { - if (read_result==0) break; /* ALL DATA has been copied */ - /* read error */ - fci_set_error( FCIERR_NONE, ERROR_READ_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - /* REUSE buffer p_fci_internal->data_out !!! */ - /* read data from p_fci_internal->handleCFDATA1 to */ - /* p_fci_internal->data_out */ - if( PFCI_READ(hfci, p_fci_internal->handleCFDATA1 /* file handle */, - p_fci_internal->data_out /* memory buffer */, - pcfdata->cbData /* number of bytes to copy */, - err, p_fci_internal->pv) != pcfdata->cbData ) { - /* read error */ - fci_set_error( FCIERR_NONE, ERROR_READ_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - /* 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 */ - if( p_fci_internal->fNextCab && - (p_fci_internal->oldCCAB.cb < sizeof(CFDATA) + cbReserveCFData + - pcfdata->cbData + - p_fci_internal->sizeFileCFFILE1 + p_fci_internal->sizeFileCFDATA2 + - p_fci_internal->sizeFileCFFILE2 + p_fci_internal->sizeFileCFFOLDER + - sizeof(CFHEADER) + - read_result + - 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 */ - read_result=pcfdata->cbData; - /* Modify the size of the compressed data to store only a part of the */ - /* data block into the current cabinet. This is done to prevent */ - /* that the maximum cabinet size will be exceeded. The remainder */ - /* will be stored into the next following cabinet. */ - - /* The cabinet will be of size "p_fci_internal->oldCCAB.cb". */ - /* Substract everything except the size of the block of data */ - /* to get it's actual size */ - pcfdata->cbData = p_fci_internal->oldCCAB.cb - ( - sizeof(CFDATA) + cbReserveCFData + - p_fci_internal->sizeFileCFFILE1 + p_fci_internal->sizeFileCFDATA2 + - p_fci_internal->sizeFileCFFILE2 + p_fci_internal->sizeFileCFFOLDER + - sizeof(CFHEADER) + - p_fci_internal->oldCCAB.cbReserveCFHeader + - 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; - pcfdata->cbUncomp = 0; /* on split blocks of data this is zero */ - - /* if split_block==TRUE then the above while loop won't */ - /* be executed again */ - split_block=TRUE; /* split_block is the indicator that */ - /* a data block has been split across */ - /* different cabinets.*/ - } - - /* This should never happen !!! */ - if (pcfdata->cbData==0) { - /* set error */ - fci_set_error( FCIERR_NONE, ERROR_GEN_FAILURE, TRUE ); - return FALSE; - } - - /* set little endian */ - pcfdata->cbData=fci_endian_uword(pcfdata->cbData); - pcfdata->cbUncomp=fci_endian_uword(pcfdata->cbUncomp); - - /* get checksum and write to cfdata.csum */ - pcfdata->csum = fci_get_checksum( &(pcfdata->cbData), - sizeof(CFDATA)+cbReserveCFData - - sizeof(pcfdata->csum), fci_get_checksum( p_fci_internal->data_out, /*buffer*/ - pcfdata->cbData, 0 ) ); - - /* set little endian */ - pcfdata->csum=fci_endian_ulong(pcfdata->csum); - - /* write cfdata with checksum to p_fci_internal->handleCFDATA2 */ - if( PFCI_WRITE(hfci, p_fci_internal->handleCFDATA2, /* file handle */ - buffer, /* memory buffer */ - sizeof(CFDATA)+cbReserveCFData, /* number of bytes to copy */ - err, p_fci_internal->pv) != sizeof(CFDATA)+cbReserveCFData ) { - fci_set_error( FCIERR_TEMP_FILE, ERROR_WRITE_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - p_fci_internal->sizeFileCFDATA2 += sizeof(CFDATA)+cbReserveCFData; - - /* reset little endian */ - pcfdata->cbData=fci_endian_uword(pcfdata->cbData); - pcfdata->cbUncomp=fci_endian_uword(pcfdata->cbUncomp); - pcfdata->csum=fci_endian_ulong(pcfdata->csum); - - /* write compressed data into p_fci_internal->handleCFDATA2 */ - if( PFCI_WRITE(hfci, p_fci_internal->handleCFDATA2, /* file handle */ - p_fci_internal->data_out, /* memory buffer */ - pcfdata->cbData, /* number of bytes to copy */ - err, p_fci_internal->pv) != pcfdata->cbData) { - fci_set_error( FCIERR_TEMP_FILE, ERROR_WRITE_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - p_fci_internal->sizeFileCFDATA2 += pcfdata->cbData; - ++(p_fci_internal->cDataBlocks); - p_fci_internal->statusFolderCopied += pcfdata->cbData; - (*payload)+=pcfdata->cbUncomp; - /* if cabinet size too large and data has been split */ - /* write the remainder of the data block to the new CFDATA1 file */ - if( split_block ) { /* This does not include the */ - /* abused one (just search for "abused" )*/ - /* copy all CFDATA structures from handleCFDATA1 to handleCFDATA1new */ - if (p_fci_internal->fNextCab==FALSE ) { - /* internal error */ - fci_set_error( FCIERR_NONE, ERROR_GEN_FAILURE, TRUE ); - return FALSE; - } - - /* set cbData to the size of the remainder of the data block */ - pcfdata->cbData = read_result - pcfdata->cbData; - /*recover former value of cfdata.cbData; read_result will be the offset*/ - read_result -= pcfdata->cbData; - pcfdata->cbUncomp = savedUncomp; - - /* reset checksum, it will be computed later */ - pcfdata->csum=0; - - /* write cfdata WITHOUT checksum to handleCFDATA1new */ - if( PFCI_WRITE(hfci, handleCFDATA1new, /* file handle */ - buffer, /* memory buffer */ - sizeof(CFDATA)+cbReserveCFData, /* number of bytes to copy */ - err, p_fci_internal->pv) != sizeof(CFDATA)+cbReserveCFData ) { - fci_set_error( FCIERR_TEMP_FILE, ERROR_WRITE_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err don't forget PFCI_FREE(hfci, reserved) */ - - *psizeFileCFDATA1new += sizeof(CFDATA)+cbReserveCFData; - - /* write compressed data into handleCFDATA1new */ - if( PFCI_WRITE(hfci, handleCFDATA1new, /* file handle */ - p_fci_internal->data_out + read_result, /* memory buffer + offset */ - /* to last part of split data */ - pcfdata->cbData, /* number of bytes to copy */ - err, p_fci_internal->pv) != pcfdata->cbData) { - fci_set_error( FCIERR_TEMP_FILE, ERROR_WRITE_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - p_fci_internal->statusFolderCopied += pcfdata->cbData; - - *psizeFileCFDATA1new += pcfdata->cbData; - /* the two blocks of the split data block have been written */ - /* don't reset split_data yet, because it is still needed see below */ - } - - /* report status with pfnfcis about copied size of folder */ - if( (*pfnfcis)(statusFolder, - p_fci_internal->statusFolderCopied, /*cfdata.cbData(+previous ones)*/ - p_fci_internal->statusFolderTotal, /* total folder size */ - p_fci_internal->pv) == -1) { - fci_set_error( FCIERR_USER_ABORT, 0, TRUE ); - return FALSE; - } - } - - /* if cabinet size too large */ - /* write the remaining data blocks to the new CFDATA1 file */ - if ( split_block ) { /* This does include the */ - /* abused one (just search for "abused" )*/ - if (p_fci_internal->fNextCab==FALSE ) { - /* internal error */ - fci_set_error( FCIERR_NONE, ERROR_GEN_FAILURE, TRUE ); - return FALSE; - } - /* copy all CFDATA structures from handleCFDATA1 to handleCFDATA1new */ - while(!FALSE) { - /* read CFDATA from p_fci_internal->handleCFDATA1 to cfdata*/ - read_result= PFCI_READ(hfci, p_fci_internal->handleCFDATA1,/* handle */ - buffer, /* memory buffer */ - sizeof(CFDATA)+cbReserveCFData, /* number of bytes to copy */ - err, p_fci_internal->pv); - if (read_result!=sizeof(CFDATA)+cbReserveCFData) { - if (read_result==0) break; /* ALL DATA has been copied */ - /* read error */ - fci_set_error(FCIERR_NONE, ERROR_READ_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - /* REUSE buffer p_fci_internal->data_out !!! */ - /* read data from p_fci_internal->handleCFDATA1 to */ - /* p_fci_internal->data_out */ - if( PFCI_READ(hfci, p_fci_internal->handleCFDATA1 /* file handle */, - p_fci_internal->data_out /* memory buffer */, - pcfdata->cbData /* number of bytes to copy */, - err, p_fci_internal->pv) != pcfdata->cbData ) { - /* read error */ - fci_set_error( FCIERR_NONE, ERROR_READ_FAULT, TRUE); - return FALSE; - } - /* TODO error handling of err don't forget PFCI_FREE(hfci, reserved) */ - - /* write cfdata with checksum to handleCFDATA1new */ - if( PFCI_WRITE(hfci, handleCFDATA1new, /* file handle */ - buffer, /* memory buffer */ - sizeof(CFDATA)+cbReserveCFData, /* number of bytes to copy */ - err, p_fci_internal->pv) != sizeof(CFDATA)+cbReserveCFData ) { - fci_set_error( FCIERR_TEMP_FILE, ERROR_WRITE_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err don't forget PFCI_FREE(hfci, reserved) */ - - *psizeFileCFDATA1new += sizeof(CFDATA)+cbReserveCFData; - - /* write compressed data into handleCFDATA1new */ - if( PFCI_WRITE(hfci, handleCFDATA1new, /* file handle */ - p_fci_internal->data_out, /* memory buffer */ - pcfdata->cbData, /* number of bytes to copy */ - err, p_fci_internal->pv) != pcfdata->cbData) { - fci_set_error( FCIERR_TEMP_FILE, ERROR_WRITE_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - *psizeFileCFDATA1new += pcfdata->cbData; - p_fci_internal->statusFolderCopied += pcfdata->cbData; - - /* report status with pfnfcis about copied size of folder */ - if( (*pfnfcis)(statusFolder, - p_fci_internal->statusFolderCopied,/*cfdata.cbData(+previous ones)*/ - p_fci_internal->statusFolderTotal, /* total folder size */ - p_fci_internal->pv) == -1) { - fci_set_error( FCIERR_USER_ABORT, 0, TRUE ); - return FALSE; - } - - } /* end of WHILE */ - break; /* jump out of the next while loop */ - } /* end of if( split_data ) */ - } /* end of WHILE */ - return TRUE; -} /* end of fci_flushfolder_copy_cfdata */ - - - - - -static BOOL fci_flushfolder_copy_cffolder(HFCI hfci, int* err, UINT cbReserveCFFolder, - cab_ULONG sizeFileCFDATA2old) -{ - CFFOLDER cffolder; - UINT i; - char* reserved; - PFCI_Int p_fci_internal=((PFCI_Int)(hfci)); - - /* absolute offset cannot be set yet, because the size of cabinet header, */ - /* the number of CFFOLDERs and the number of CFFILEs may change. */ - /* Instead the size of all previous data blocks will be stored and */ - /* the remainder of the offset will be added when the cabinet will be */ - /* flushed to disk. */ - /* This is exactly the way the original CABINET.DLL works!!! */ - cffolder.coffCabStart=sizeFileCFDATA2old; - - /* set the number of this folder's CFDATA sections */ - cffolder.cCFData=p_fci_internal->cDataBlocks; - /* TODO set compression type */ - cffolder.typeCompress = tcompTYPE_NONE; - - /* write cffolder to p_fci_internal->handleCFFOLDER */ - if( PFCI_WRITE(hfci, p_fci_internal->handleCFFOLDER, /* file handle */ - &cffolder, /* memory buffer */ - sizeof(cffolder), /* number of bytes to copy */ - err, p_fci_internal->pv) != sizeof(cffolder) ) { - fci_set_error( FCIERR_TEMP_FILE, ERROR_WRITE_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - p_fci_internal->sizeFileCFFOLDER += sizeof(cffolder); - - /* add optional reserved area */ - if (cbReserveCFFolder!=0) { - if(!(reserved = PFCI_ALLOC(hfci, cbReserveCFFolder))) { - fci_set_error( FCIERR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY, TRUE ); - return FALSE; - } - for(i=0;ihandleCFFOLDER, /* file handle */ - reserved, /* memory buffer */ - cbReserveCFFolder, /* number of bytes to copy */ - err, p_fci_internal->pv) != cbReserveCFFolder ) { - PFCI_FREE(hfci, reserved); - fci_set_error( FCIERR_TEMP_FILE, ERROR_WRITE_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - p_fci_internal->sizeFileCFFOLDER += cbReserveCFFolder; - - PFCI_FREE(hfci, reserved); - } - return TRUE; -} /* end of fci_flushfolder_copy_cffolder */ - - - - - -static BOOL fci_flushfolder_copy_cffile(HFCI hfci, int* err, int handleCFFILE1new, - cab_ULONG *psizeFileCFFILE1new, cab_ULONG payload) -{ - CFFILE cffile; - cab_ULONG read_result; - cab_ULONG seek=0; - cab_ULONG sizeOfFiles=0, sizeOfFilesPrev; - BOOL may_be_prev=TRUE; - cab_ULONG cbFileRemainer=0; - PFCI_Int p_fci_internal=((PFCI_Int)(hfci)); - /* set seek of p_fci_internal->handleCFFILE1 to 0 */ - if( PFCI_SEEK(hfci,p_fci_internal->handleCFFILE1,0,SEEK_SET,err, - p_fci_internal->pv) !=0 ) { - /* wrong return value */ - fci_set_error( FCIERR_NONE, ERROR_SEEK, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - /* while not all CFFILE structures have been copied do */ - while(!FALSE) { - /* REUSE the variable read_result */ - /* read data from p_fci_internal->handleCFFILE1 to cffile */ - read_result = PFCI_READ(hfci,p_fci_internal->handleCFFILE1/* file handle */, - &cffile, /* memory buffer */ - sizeof(cffile), /* number of bytes to copy */ - err, p_fci_internal->pv); - if( read_result != sizeof(cffile) ) { - if( read_result == 0 ) break; /* ALL CFFILE structures have been copied */ - /* read error */ - fci_set_error( FCIERR_NONE, ERROR_READ_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - /* Microsoft's(R) CABINET.DLL would do a seek to the current! */ - /* position. I don't know why so I'll just omit it */ - - /* read the filename from p_fci_internal->handleCFFILE1 */ - /* REUSE the variable read_result AGAIN */ - /* REUSE the memory buffer PFCI(hfci)->data_out */ - if( PFCI_READ(hfci, p_fci_internal->handleCFFILE1 /*file handle*/, - p_fci_internal->data_out, /* memory buffer */ - CB_MAX_FILENAME, /* number of bytes to copy */ - err, p_fci_internal->pv) <2) { - /* read error */ - fci_set_error( FCIERR_NONE, ERROR_READ_FAULT, TRUE ); - return FALSE; - } - /* TODO maybe other checks of read_result */ - /* TODO error handling of err */ - - /* safety */ - if( strlen(p_fci_internal->data_out)>=CB_MAX_FILENAME ) { - /* set error code internal error */ - fci_set_error( FCIERR_NONE, ERROR_INVALID_DATA, TRUE ); - return FALSE; - } - - seek+=sizeof(cffile) + strlen(p_fci_internal->data_out)+1; - - /* set seek of p_fci_internal->handleCFFILE1 to end of file name */ - /* i.e. seek to the next CFFILE area */ - if( PFCI_SEEK(hfci,p_fci_internal->handleCFFILE1, - seek, /* seek position*/ - SEEK_SET ,err, - p_fci_internal->pv) - != seek) { - /* wrong return value */ - fci_set_error( FCIERR_NONE, ERROR_SEEK, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - /* fnfilfnfildest: placed file on cabinet */ - if (p_fci_internal->fNextCab || - p_fci_internal->fGetNextCabInVain) { - PFCI_FILEPLACED( hfci, &(p_fci_internal->oldCCAB), - p_fci_internal->data_out, /* the file name*/ - cffile.cbFile, /* file size */ - (cffile.iFolder==cffileCONTINUED_FROM_PREV), - p_fci_internal->pv - ); - } else { - PFCI_FILEPLACED( hfci, p_fci_internal->pccab, - p_fci_internal->data_out, /* the file name*/ - cffile.cbFile, /* file size */ - (cffile.iFolder==cffileCONTINUED_FROM_PREV), - p_fci_internal->pv - ); - } - - /* Check special iFolder values */ - if( cffile.iFolder==cffileCONTINUED_FROM_PREV && - p_fci_internal->fPrevCab==FALSE ) { - /* THIS MAY NEVER HAPPEN */ - /* set error code */ - fci_set_error( FCIERR_NONE, ERROR_GEN_FAILURE, TRUE ); - return FALSE; - } - if( cffile.iFolder==cffileCONTINUED_PREV_AND_NEXT || - cffile.iFolder==cffileCONTINUED_TO_NEXT ) { - /* THIS MAY NEVER HAPPEN */ - /* set error code */ - fci_set_error( FCIERR_NONE, ERROR_GEN_FAILURE, TRUE ); - return FALSE; - } - if( may_be_prev && cffile.iFolder!=cffileCONTINUED_FROM_PREV ) { - may_be_prev=FALSE; - } - if( cffile.iFolder==cffileCONTINUED_FROM_PREV && may_be_prev==FALSE ) { - /* THIS MAY NEVER HAPPEN */ - /* set error code */ - fci_set_error( FCIERR_NONE, ERROR_GEN_FAILURE, TRUE ); - return FALSE; - } - if( cffile.iFolder!=cffileCONTINUED_FROM_PREV ) { - may_be_prev=FALSE; - } - - sizeOfFilesPrev=sizeOfFiles; - /* Set complete size of all processed files */ - if( cffile.iFolder==cffileCONTINUED_FROM_PREV && - p_fci_internal->cbFileRemainer!=0 - ) { - sizeOfFiles+=p_fci_internal->cbFileRemainer; - p_fci_internal->cbFileRemainer=0; - } else { - sizeOfFiles+=cffile.cbFile; - } - - /* Check if spanned file fits into this cabinet folder */ - if( cffile.iFolder==cffileCONTINUED_FROM_PREV && sizeOfFiles>payload ) { - cffile.iFolder=cffileCONTINUED_PREV_AND_NEXT; - } else - - /* Check if file doesn't fit into this cabinet folder */ - if( sizeOfFiles>payload ) { - cffile.iFolder=cffileCONTINUED_TO_NEXT; - } - - /* set little endian */ - cffile.cbFile=fci_endian_ulong(cffile.cbFile); - cffile.uoffFolderStart=fci_endian_ulong(cffile.uoffFolderStart); - cffile.iFolder=fci_endian_uword(cffile.iFolder); - cffile.date=fci_endian_uword(cffile.date); - cffile.time=fci_endian_uword(cffile.time); - cffile.attribs=fci_endian_uword(cffile.attribs); - - /* write cffile to p_fci_internal->handleCFFILE2 */ - if( PFCI_WRITE(hfci, p_fci_internal->handleCFFILE2, /* file handle */ - &cffile, /* memory buffer */ - sizeof(cffile), /* number of bytes to copy */ - err, p_fci_internal->pv) != sizeof(cffile) ) { - fci_set_error( FCIERR_TEMP_FILE, ERROR_WRITE_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - p_fci_internal->sizeFileCFFILE2 += sizeof(cffile); - - /* reset little endian */ - cffile.cbFile=fci_endian_ulong(cffile.cbFile); - cffile.uoffFolderStart=fci_endian_ulong(cffile.uoffFolderStart); - cffile.iFolder=fci_endian_uword(cffile.iFolder); - cffile.date=fci_endian_uword(cffile.date); - cffile.time=fci_endian_uword(cffile.time); - cffile.attribs=fci_endian_uword(cffile.attribs); - - /* write file name to p_fci_internal->handleCFFILE2 */ - if( PFCI_WRITE(hfci, p_fci_internal->handleCFFILE2, /* file handle */ - p_fci_internal->data_out, /* memory buffer */ - strlen(p_fci_internal->data_out)+1, /* number of bytes to copy */ - err, p_fci_internal->pv) != strlen(p_fci_internal->data_out)+1 ) { - fci_set_error( FCIERR_TEMP_FILE, ERROR_WRITE_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - p_fci_internal->sizeFileCFFILE2 += strlen(p_fci_internal->data_out)+1; - - /* cFiles is used to count all files of a cabinet */ - ++(p_fci_internal->cFiles); - - /* This is only true for files which will be written into the */ - /* next cabinet of the spanning folder */ - if( sizeOfFiles>payload ) { - - /* Files which data will be partially written into the current cabinet */ - if( cffile.iFolder==cffileCONTINUED_PREV_AND_NEXT || - cffile.iFolder==cffileCONTINUED_TO_NEXT - ) { - if( sizeOfFilesPrev<=payload ) { - /* The size of the uncompressed, data of a spanning file in a */ - /* spanning data */ - cbFileRemainer=sizeOfFiles-payload; - } - cffile.iFolder=cffileCONTINUED_FROM_PREV; - } else { - cffile.iFolder=0; - } - - /* write cffile into handleCFFILE1new */ - if( PFCI_WRITE(hfci, handleCFFILE1new, /* file handle */ - &cffile, /* memory buffer */ - sizeof(cffile), /* number of bytes to copy */ - err, p_fci_internal->pv) != sizeof(cffile) ) { - fci_set_error( FCIERR_TEMP_FILE, ERROR_WRITE_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - *psizeFileCFFILE1new += sizeof(cffile); - /* write name of file into handleCFFILE1new */ - if( PFCI_WRITE(hfci, handleCFFILE1new, /* file handle */ - p_fci_internal->data_out, /* memory buffer */ - strlen(p_fci_internal->data_out)+1, /* number of bytes to copy */ - err, p_fci_internal->pv) != strlen(p_fci_internal->data_out)+1 ) { - fci_set_error( FCIERR_TEMP_FILE, ERROR_WRITE_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - *psizeFileCFFILE1new += strlen(p_fci_internal->data_out)+1; - } - - } /* END OF while */ - p_fci_internal->cbFileRemainer=cbFileRemainer; - return TRUE; -} /* end of fci_flushfolder_copy_cffile */ - - - - -static BOOL fci_flush_folder( - HFCI hfci, +static BOOL fci_flush_folder( FCI_Int *p_fci_internal, BOOL fGetNextCab, PFNFCIGETNEXTCABINET pfnfcignc, PFNFCISTATUS pfnfcis) { - int err; - int handleCFDATA1new; /* handle for new temp file */ - char szFileNameCFDATA1new[CB_MAX_FILENAME]; /* name buffer for temp file */ - int handleCFFILE1new; /* handle for new temp file */ - char szFileNameCFFILE1new[CB_MAX_FILENAME]; /* name buffer for temp file */ - UINT cbReserveCFData, cbReserveCFFolder; - char* reserved; - cab_ULONG sizeFileCFDATA1new=0; - cab_ULONG sizeFileCFFILE1new=0; - cab_ULONG sizeFileCFDATA2old; cab_ULONG payload; cab_ULONG read_result; - PFCI_Int p_fci_internal=((PFCI_Int)(hfci)); - - /* test hfci */ - if (!REALLY_IS_FCI(hfci)) { - SetLastError(ERROR_INVALID_HANDLE); - return FALSE; - } + struct folder *folder; if ((!pfnfcignc) || (!pfnfcis)) { - fci_set_error( FCIERR_NONE, ERROR_BAD_ARGUMENTS, TRUE ); + set_error( p_fci_internal, FCIERR_NONE, ERROR_BAD_ARGUMENTS ); return FALSE; } if( p_fci_internal->fGetNextCabInVain && p_fci_internal->fNextCab ){ /* internal error */ - fci_set_error( FCIERR_NONE, ERROR_GEN_FAILURE, TRUE ); + set_error( p_fci_internal, FCIERR_NONE, ERROR_GEN_FAILURE ); return FALSE; } /* If there was no FCIAddFile or FCIFlushFolder has already been called */ /* this function will return TRUE */ - if( p_fci_internal->sizeFileCFFILE1 == 0 ) { - if ( p_fci_internal->sizeFileCFDATA1 != 0 ) { + if( p_fci_internal->files_size == 0 ) { + if ( p_fci_internal->pending_data_size != 0 ) { /* error handling */ - fci_set_error( FCIERR_NONE, ERROR_GEN_FAILURE, TRUE ); + set_error( p_fci_internal, FCIERR_NONE, ERROR_GEN_FAILURE ); return FALSE; } return TRUE; } - if (p_fci_internal->data_in==NULL || p_fci_internal->data_out==NULL ) { - /* error handling */ - fci_set_error( FCIERR_NONE, ERROR_GEN_FAILURE, TRUE ); - return FALSE; - } - /* FCIFlushFolder has already been called... */ - if (p_fci_internal->fSplitFolder && p_fci_internal->sizeFileCFFILE2!=0) { + if (p_fci_internal->fSplitFolder && p_fci_internal->placed_files_size!=0) { return TRUE; } @@ -1178,136 +1126,34 @@ static BOOL fci_flush_folder( /* when the current function exits with return FALSE */ p_fci_internal->fSplitFolder=FALSE; - - if( p_fci_internal->fGetNextCabInVain || - 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 */ - /* if there is data in p_fci_internal->data_in */ - if (p_fci_internal->cdata_in!=0) { + if (!add_data_block( p_fci_internal, pfnfcis )) return FALSE; - if( !fci_flush_data_block(hfci, &err, pfnfcis) ) return FALSE; - - } /* reset to get the number of data blocks of this folder which are */ /* actually in this cabinet ( at least partially ) */ p_fci_internal->cDataBlocks=0; - if ( p_fci_internal->fNextCab || - p_fci_internal->fGetNextCabInVain ) { - 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) { - 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->sizeFileCFFILE2+ - p_fci_internal->sizeFileCFDATA2 + p_fci_internal->sizeFileCFFILE1+ - p_fci_internal->sizeFileCFDATA1 + p_fci_internal->sizeFileCFFOLDER; + p_fci_internal->statusFolderTotal = get_header_size( p_fci_internal ) + + sizeof(CFFOLDER) + p_fci_internal->ccab.cbReserveCFFolder + + p_fci_internal->placed_files_size+ + p_fci_internal->folders_data_size + p_fci_internal->files_size+ + p_fci_internal->pending_data_size + p_fci_internal->folders_size; p_fci_internal->statusFolderCopied = 0; /* report status with pfnfcis about copied size of folder */ if( (*pfnfcis)(statusFolder, p_fci_internal->statusFolderCopied, p_fci_internal->statusFolderTotal, /* TODO total folder size */ p_fci_internal->pv) == -1) { - fci_set_error( FCIERR_USER_ABORT, 0, TRUE ); + set_error( p_fci_internal, FCIERR_USER_ABORT, 0 ); return FALSE; } - /* get a new temp file */ - if(!PFCI_GETTEMPFILE(hfci,szFileNameCFDATA1new,CB_MAX_FILENAME)) { - fci_set_error( FCIERR_NONE, ERROR_FUNCTION_FAILED, TRUE ); - return FALSE; - } - /* safety */ - if ( strlen(szFileNameCFDATA1new) >= CB_MAX_FILENAME ) { - fci_set_error( FCIERR_NONE, ERROR_INVALID_DATA, TRUE ); - return FALSE; - } - handleCFDATA1new = PFCI_OPEN(hfci,szFileNameCFDATA1new,34050,384,&err, - p_fci_internal->pv); - if(handleCFDATA1new==0){ - fci_set_error( FCIERR_TEMP_FILE, ERROR_OPEN_FAILED, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - - - /* get a new temp file */ - if(!PFCI_GETTEMPFILE(hfci,szFileNameCFFILE1new,CB_MAX_FILENAME)) { - fci_set_error( FCIERR_NONE, ERROR_FUNCTION_FAILED, TRUE ); - PFCI_CLOSE(hfci,handleCFDATA1new,&err,p_fci_internal->pv); - /* TODO error handling of err */ - return FALSE; - } - /* safety */ - if ( strlen(szFileNameCFFILE1new) >= CB_MAX_FILENAME ) { - fci_set_error( FCIERR_NONE, ERROR_INVALID_DATA, TRUE ); - PFCI_CLOSE(hfci,handleCFDATA1new,&err,p_fci_internal->pv); - /* TODO error handling of err */ - return FALSE; - } - handleCFFILE1new = PFCI_OPEN(hfci,szFileNameCFFILE1new,34050,384,&err, - p_fci_internal->pv); - if(handleCFFILE1new==0){ - fci_set_error( FCIERR_TEMP_FILE, ERROR_OPEN_FAILED, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - /* USE the variable read_result */ - if ( p_fci_internal->fNextCab || - p_fci_internal->fGetNextCabInVain ) { - 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->sizeFileCFDATA2 + - p_fci_internal->sizeFileCFFILE2 + p_fci_internal->sizeFileCFFOLDER; + read_result = get_header_size( p_fci_internal ) + p_fci_internal->folders_data_size + + p_fci_internal->placed_files_size + p_fci_internal->folders_size; - if(p_fci_internal->sizeFileCFFILE1!=0) { - read_result+= sizeof(CFFOLDER)+p_fci_internal->pccab->cbReserveCFFolder; + if(p_fci_internal->files_size!=0) { + read_result+= sizeof(CFFOLDER)+p_fci_internal->ccab.cbReserveCFFolder; } /* Check if multiple cabinets have to be created. */ @@ -1322,16 +1168,14 @@ static BOOL fci_flush_folder( p_fci_internal->fNextCab==FALSE && ( ( - p_fci_internal->pccab->cb < read_result + - p_fci_internal->sizeFileCFDATA1 + - p_fci_internal->sizeFileCFFILE1 + + p_fci_internal->ccab.cb < read_result + + p_fci_internal->pending_data_size + + p_fci_internal->files_size + CB_MAX_CABINET_NAME + /* next cabinet name */ CB_MAX_DISK_NAME /* next disk name */ ) || fGetNextCab ) ) { - /* save CCAB */ - p_fci_internal->oldCCAB = *p_fci_internal->pccab; /* increment cabinet index */ ++(p_fci_internal->pccab->iCab); /* get name of next cabinet */ @@ -1339,12 +1183,7 @@ static BOOL fci_flush_folder( if (!(*pfnfcignc)(p_fci_internal->pccab, p_fci_internal->estimatedCabinetSize, /* estimated size of cab */ p_fci_internal->pv)) { - /* error handling */ - fci_set_error( FCIERR_NONE, ERROR_FUNCTION_FAILED, TRUE ); - PFCI_CLOSE(hfci,handleCFDATA1new,&err,p_fci_internal->pv); - /* TODO error handling of err */ - PFCI_CLOSE(hfci,handleCFFILE1new,&err,p_fci_internal->pv); - /* TODO error handling of err */ + set_error( p_fci_internal, FCIERR_NONE, ERROR_FUNCTION_FAILED ); return FALSE; } @@ -1357,9 +1196,9 @@ static BOOL fci_flush_folder( p_fci_internal->fNextCab ) && ( ( - p_fci_internal->oldCCAB.cb < read_result + - p_fci_internal->sizeFileCFDATA1 + - p_fci_internal->sizeFileCFFILE1 + + p_fci_internal->ccab.cb < read_result + + p_fci_internal->pending_data_size + + p_fci_internal->files_size + strlen(p_fci_internal->pccab->szCab)+1 + /* next cabinet name */ strlen(p_fci_internal->pccab->szDisk)+1 /* next disk name */ ) || fGetNextCab @@ -1370,24 +1209,13 @@ static BOOL fci_flush_folder( /* return FALSE if there is not enough space left*/ /* this should never happen */ - if (p_fci_internal->oldCCAB.cb <= - p_fci_internal->sizeFileCFFILE1 + + if (p_fci_internal->ccab.cb <= + p_fci_internal->files_size + read_result + strlen(p_fci_internal->pccab->szCab)+1 + /* next cabinet name */ strlen(p_fci_internal->pccab->szDisk)+1 /* next disk name */ ) { - PFCI_CLOSE(hfci,handleCFDATA1new,&err,p_fci_internal->pv); - /* TODO error handling of err */ - PFCI_DELETE(hfci,szFileNameCFDATA1new,&err,p_fci_internal->pv); - /* TODO error handling of err */ - - /* close and delete p_fci_internal->handleCFFILE1 */ - PFCI_CLOSE(hfci,handleCFFILE1new,&err,p_fci_internal->pv); - /* TODO error handling of err */ - PFCI_DELETE(hfci,szFileNameCFFILE1new,&err,p_fci_internal->pv); - /* TODO error handling of err */ - return FALSE; } @@ -1398,147 +1226,41 @@ static BOOL fci_flush_folder( /* this should never happen */ if (p_fci_internal->fNextCab) { /* internal error */ - fci_set_error( FCIERR_NONE, ERROR_GEN_FAILURE, TRUE ); + set_error( p_fci_internal, FCIERR_NONE, ERROR_GEN_FAILURE ); return FALSE; } } - /* set seek of p_fci_internal->handleCFDATA1 to 0 */ - if( PFCI_SEEK(hfci,p_fci_internal->handleCFDATA1,0,SEEK_SET,&err, - p_fci_internal->pv) !=0 ) { - /* wrong return value */ - fci_set_error( FCIERR_NONE, ERROR_SEEK, TRUE ); - PFCI_CLOSE(hfci,handleCFDATA1new,&err,p_fci_internal->pv); - /* TODO error handling of err */ - PFCI_CLOSE(hfci,handleCFFILE1new,&err,p_fci_internal->pv); - /* TODO error handling of err */ - return FALSE; - } - /* TODO error handling of err */ - - /* save size of file CFDATA2 - required for the folder's offset to data */ - sizeFileCFDATA2old = p_fci_internal->sizeFileCFDATA2; - - if(!(reserved = PFCI_ALLOC(hfci, cbReserveCFData+sizeof(CFDATA)))) { - fci_set_error( FCIERR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY, TRUE ); - PFCI_CLOSE(hfci,handleCFDATA1new,&err,p_fci_internal->pv); - /* TODO error handling of err */ - PFCI_CLOSE(hfci,handleCFFILE1new,&err,p_fci_internal->pv); - /* TODO error handling of err */ - return FALSE; - } - - if(!fci_flushfolder_copy_cfdata(hfci, reserved, cbReserveCFData, pfnfcis, &err, - handleCFDATA1new, &sizeFileCFDATA1new, &payload - )) { - PFCI_CLOSE(hfci,handleCFDATA1new,&err,p_fci_internal->pv); - /* TODO error handling of err */ - PFCI_DELETE(hfci,szFileNameCFDATA1new,&err,p_fci_internal->pv); - /* TODO error handling of err */ - PFCI_CLOSE(hfci,handleCFFILE1new,&err,p_fci_internal->pv); - /* TODO error handling of err */ - PFCI_FREE(hfci,reserved); - return FALSE; - } - - PFCI_FREE(hfci,reserved); - - if(!fci_flushfolder_copy_cffolder(hfci, &err, cbReserveCFFolder, - sizeFileCFDATA2old )) { - PFCI_CLOSE(hfci,handleCFDATA1new,&err,p_fci_internal->pv); - /* TODO error handling of err */ - PFCI_DELETE(hfci,szFileNameCFDATA1new,&err,p_fci_internal->pv); - /* TODO error handling of err */ - PFCI_CLOSE(hfci,handleCFFILE1new,&err,p_fci_internal->pv); - /* TODO error handling of err */ - return FALSE; - } - - if(!fci_flushfolder_copy_cffile(hfci, &err, handleCFFILE1new, - &sizeFileCFFILE1new, payload)) { - PFCI_CLOSE(hfci,handleCFDATA1new,&err,p_fci_internal->pv); - /* TODO error handling of err */ - PFCI_DELETE(hfci,szFileNameCFDATA1new,&err,p_fci_internal->pv); - /* TODO error handling of err */ - PFCI_CLOSE(hfci,handleCFFILE1new,&err,p_fci_internal->pv); - /* TODO error handling of err */ - PFCI_DELETE(hfci,szFileNameCFFILE1new,&err,p_fci_internal->pv); - /* TODO error handling of err */ - return FALSE; - } - - /* close and delete p_fci_internal->handleCFDATA1 */ - PFCI_CLOSE(hfci,p_fci_internal->handleCFDATA1,&err,p_fci_internal->pv); - /* TODO error handling of err */ - PFCI_DELETE(hfci,p_fci_internal->szFileNameCFDATA1,&err,p_fci_internal->pv); - /* TODO error handling of err */ - - /* put new CFDATA1 into hfci */ - memcpy(p_fci_internal->szFileNameCFDATA1,szFileNameCFDATA1new, - CB_MAX_FILENAME); - - /* put CFDATA1 file handle */ - PFCI_INT(hfci)->handleCFDATA1 = handleCFDATA1new; - /* set file size */ - PFCI_INT(hfci)->sizeFileCFDATA1 = sizeFileCFDATA1new; - - /* close and delete PFCI_INT(hfci)->handleCFFILE1 */ - PFCI_CLOSE(hfci,p_fci_internal->handleCFFILE1,&err,PFCI_INT(hfci)->pv); - /* TODO error handling of err */ - PFCI_DELETE(hfci,p_fci_internal->szFileNameCFFILE1,&err,p_fci_internal->pv); - /* TODO error handling of err */ - - /* put new CFFILE1 into hfci */ - memcpy(p_fci_internal->szFileNameCFFILE1,szFileNameCFFILE1new, - CB_MAX_FILENAME); - - /* put CFFILE1 file handle */ - p_fci_internal->handleCFFILE1 = handleCFFILE1new; - /* set file size */ - p_fci_internal->sizeFileCFFILE1 = sizeFileCFFILE1new; - - ++(p_fci_internal->cFolders); + if (!(folder = add_folder( p_fci_internal ))) return FALSE; + if (!add_data_to_folder( p_fci_internal, folder, &payload, pfnfcis )) return FALSE; + if (!add_files_to_folder( p_fci_internal, folder, payload )) return FALSE; /* reset CFFolder specific information */ p_fci_internal->cDataBlocks=0; p_fci_internal->cCompressedBytesInFolder=0; return TRUE; -} /* end of fci_flush_folder */ +} -static BOOL fci_flush_cabinet( - HFCI hfci, +static BOOL fci_flush_cabinet( FCI_Int *p_fci_internal, BOOL fGetNextCab, PFNFCIGETNEXTCABINET pfnfcignc, PFNFCISTATUS pfnfcis) { - int err; - CFHEADER cfheader; - struct { - cab_UWORD cbCFHeader; - cab_UBYTE cbCFFolder; - cab_UBYTE cbCFData; - } cfreserved; - CFFOLDER cffolder; cab_ULONG read_result=0; - int handleCABINET; /* file handle for cabinet */ - char szFileNameCABINET[CB_MAX_CAB_PATH+CB_MAX_CABINET_NAME];/* name buffer */ - UINT cbReserveCFHeader, cbReserveCFFolder, i; - char* reserved; BOOL returntrue=FALSE; - PFCI_Int p_fci_internal=((PFCI_Int)(hfci)); /* TODO test if fci_flush_cabinet really aborts if there was no FCIAddFile */ /* when FCIFlushCabinet was or FCIAddFile hasn't been called */ - if( p_fci_internal->sizeFileCFFILE1==0 && fGetNextCab ) { + if( p_fci_internal->files_size==0 && fGetNextCab ) { returntrue=TRUE; } - if (!fci_flush_folder(hfci,fGetNextCab,pfnfcignc,pfnfcis)){ + if (!fci_flush_folder(p_fci_internal,fGetNextCab,pfnfcignc,pfnfcis)){ /* TODO set error */ return FALSE; } @@ -1546,630 +1268,18 @@ static BOOL fci_flush_cabinet( if(returntrue) return TRUE; if ( (p_fci_internal->fSplitFolder && p_fci_internal->fNextCab==FALSE)|| - (p_fci_internal->sizeFileCFFOLDER==0 && - (p_fci_internal->sizeFileCFFILE1!=0 || - p_fci_internal->sizeFileCFFILE2!=0 ) + (p_fci_internal->folders_size==0 && + (p_fci_internal->files_size!=0 || + p_fci_internal->placed_files_size!=0 ) ) ) { /* error */ - fci_set_error( FCIERR_NONE, ERROR_GEN_FAILURE, TRUE ); + set_error( p_fci_internal, FCIERR_NONE, ERROR_GEN_FAILURE ); return FALSE; } - if( p_fci_internal->fNextCab || - p_fci_internal->fGetNextCabInVain ) { - cbReserveCFFolder=p_fci_internal->oldCCAB.cbReserveCFFolder; - cbReserveCFHeader=p_fci_internal->oldCCAB.cbReserveCFHeader; - /* safety */ - if (strlen(p_fci_internal->oldCCAB.szCabPath)>=CB_MAX_CAB_PATH || - strlen(p_fci_internal->oldCCAB.szCab)>=CB_MAX_CABINET_NAME) { - /* set error */ - fci_set_error( FCIERR_NONE, ERROR_INVALID_DATA, TRUE ); - return FALSE; - } - /* get the full name of the cabinet */ - memcpy(szFileNameCABINET,p_fci_internal->oldCCAB.szCabPath, - CB_MAX_CAB_PATH); - memcpy(szFileNameCABINET+strlen(szFileNameCABINET), - p_fci_internal->oldCCAB.szCab, CB_MAX_CABINET_NAME); - } else { - cbReserveCFFolder=p_fci_internal->pccab->cbReserveCFFolder; - cbReserveCFHeader=p_fci_internal->pccab->cbReserveCFHeader; - /* safety */ - if (strlen(p_fci_internal->pccab->szCabPath)>=CB_MAX_CAB_PATH || - strlen(p_fci_internal->pccab->szCab)>=CB_MAX_CABINET_NAME) { - /* set error */ - fci_set_error( FCIERR_NONE, ERROR_INVALID_DATA, TRUE ); - return FALSE; - } - /* get the full name of the cabinet */ - memcpy(szFileNameCABINET,p_fci_internal->pccab->szCabPath, - CB_MAX_CAB_PATH); - memcpy(szFileNameCABINET+strlen(szFileNameCABINET), - p_fci_internal->pccab->szCab, CB_MAX_CABINET_NAME); - } - - memcpy(cfheader.signature,"!CAB",4); - cfheader.reserved1=0; - cfheader.cbCabinet= /* size of the cabinet file in bytes */ - sizeof(CFHEADER) + - p_fci_internal->sizeFileCFFOLDER + - p_fci_internal->sizeFileCFFILE2 + - p_fci_internal->sizeFileCFDATA2; - - if (p_fci_internal->fPrevCab) { - cfheader.cbCabinet+=strlen(p_fci_internal->szPrevCab)+1 + - strlen(p_fci_internal->szPrevDisk)+1; - } - if (p_fci_internal->fNextCab) { - cfheader.cbCabinet+=strlen(p_fci_internal->pccab->szCab)+1 + - strlen(p_fci_internal->pccab->szDisk)+1; - } - if( p_fci_internal->fNextCab || - p_fci_internal->fGetNextCabInVain ) { - cfheader.cbCabinet+=p_fci_internal->oldCCAB.cbReserveCFHeader; - if ( p_fci_internal->oldCCAB.cbReserveCFHeader != 0 || - p_fci_internal->oldCCAB.cbReserveCFFolder != 0 || - p_fci_internal->oldCCAB.cbReserveCFData != 0 ) { - cfheader.cbCabinet+=4; - } - } else { - cfheader.cbCabinet+=p_fci_internal->pccab->cbReserveCFHeader; - if ( p_fci_internal->pccab->cbReserveCFHeader != 0 || - p_fci_internal->pccab->cbReserveCFFolder != 0 || - p_fci_internal->pccab->cbReserveCFData != 0 ) { - cfheader.cbCabinet+=4; - } - } - - if( ( ( p_fci_internal->fNextCab || - p_fci_internal->fGetNextCabInVain ) && - cfheader.cbCabinet > p_fci_internal->oldCCAB.cb - ) || - ( ( p_fci_internal->fNextCab==FALSE && - p_fci_internal->fGetNextCabInVain==FALSE ) && - cfheader.cbCabinet > p_fci_internal->pccab->cb - ) - ) - { - fci_set_error( FCIERR_NONE, ERROR_MORE_DATA, TRUE ); - return FALSE; - } - - - cfheader.reserved2=0; - cfheader.coffFiles= /* offset to first CFFILE section */ - cfheader.cbCabinet - p_fci_internal->sizeFileCFFILE2 - - p_fci_internal->sizeFileCFDATA2; - - cfheader.reserved3=0; - cfheader.versionMinor=3; - cfheader.versionMajor=1; - /* number of CFFOLDER entries in the cabinet */ - cfheader.cFolders=p_fci_internal->cFolders; - /* number of CFFILE entries in the cabinet */ - cfheader.cFiles=p_fci_internal->cFiles; - cfheader.flags=0; /* 1=prev cab, 2=next cabinet, 4=reserved sections */ - - if( p_fci_internal->fPrevCab ) { - cfheader.flags = cfheadPREV_CABINET; - } - - if( p_fci_internal->fNextCab ) { - cfheader.flags |= cfheadNEXT_CABINET; - } - - if( p_fci_internal->fNextCab || - p_fci_internal->fGetNextCabInVain ) { - if( p_fci_internal->oldCCAB.cbReserveCFHeader != 0 || - p_fci_internal->oldCCAB.cbReserveCFFolder != 0 || - p_fci_internal->oldCCAB.cbReserveCFData != 0 ) { - cfheader.flags |= cfheadRESERVE_PRESENT; - } - cfheader.setID = p_fci_internal->oldCCAB.setID; - cfheader.iCabinet = p_fci_internal->oldCCAB.iCab-1; - } else { - if( p_fci_internal->pccab->cbReserveCFHeader != 0 || - p_fci_internal->pccab->cbReserveCFFolder != 0 || - p_fci_internal->pccab->cbReserveCFData != 0 ) { - cfheader.flags |= cfheadRESERVE_PRESENT; - } - cfheader.setID = p_fci_internal->pccab->setID; - cfheader.iCabinet = p_fci_internal->pccab->iCab-1; - } - /* create the cabinet */ - handleCABINET = PFCI_OPEN(hfci, szFileNameCABINET, - 33538, 384, &err, p_fci_internal->pv ); - if(handleCABINET==0){ - fci_set_error( FCIERR_CAB_FILE, ERROR_OPEN_FAILED, TRUE ); - return FALSE; - } - /* TODO error checking of err */ - - /* set little endian */ - cfheader.reserved1=fci_endian_ulong(cfheader.reserved1); - cfheader.cbCabinet=fci_endian_ulong(cfheader.cbCabinet); - cfheader.reserved2=fci_endian_ulong(cfheader.reserved2); - cfheader.coffFiles=fci_endian_ulong(cfheader.coffFiles); - cfheader.reserved3=fci_endian_ulong(cfheader.reserved3); - cfheader.cFolders=fci_endian_uword(cfheader.cFolders); - cfheader.cFiles=fci_endian_uword(cfheader.cFiles); - cfheader.flags=fci_endian_uword(cfheader.flags); - cfheader.setID=fci_endian_uword(cfheader.setID); - cfheader.iCabinet=fci_endian_uword(cfheader.iCabinet); - - /* write CFHEADER into cabinet file */ - if( PFCI_WRITE(hfci, handleCABINET, /* file handle */ - &cfheader, /* memory buffer */ - sizeof(cfheader), /* number of bytes to copy */ - &err, p_fci_internal->pv) != sizeof(cfheader) ) { - /* write error */ - fci_set_error( FCIERR_CAB_FILE, ERROR_WRITE_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - /* reset little endian */ - cfheader.reserved1=fci_endian_ulong(cfheader.reserved1); - cfheader.cbCabinet=fci_endian_ulong(cfheader.cbCabinet); - cfheader.reserved2=fci_endian_ulong(cfheader.reserved2); - cfheader.coffFiles=fci_endian_ulong(cfheader.coffFiles); - cfheader.reserved3=fci_endian_ulong(cfheader.reserved3); - cfheader.cFolders=fci_endian_uword(cfheader.cFolders); - cfheader.cFiles=fci_endian_uword(cfheader.cFiles); - cfheader.flags=fci_endian_uword(cfheader.flags); - cfheader.setID=fci_endian_uword(cfheader.setID); - cfheader.iCabinet=fci_endian_uword(cfheader.iCabinet); - - if( cfheader.flags & cfheadRESERVE_PRESENT ) { - /* NOTE: No checks for maximum value overflows as designed by MS!!! */ - cfreserved.cbCFHeader = cbReserveCFHeader; - cfreserved.cbCFFolder = cbReserveCFFolder; - if( p_fci_internal->fNextCab || - p_fci_internal->fGetNextCabInVain ) { - cfreserved.cbCFData = p_fci_internal->oldCCAB.cbReserveCFData; - } else { - cfreserved.cbCFData = p_fci_internal->pccab->cbReserveCFData; - } - - /* set little endian */ - cfreserved.cbCFHeader=fci_endian_uword(cfreserved.cbCFHeader); - - /* write reserved info into cabinet file */ - if( PFCI_WRITE(hfci, handleCABINET, /* file handle */ - &cfreserved, /* memory buffer */ - sizeof(cfreserved), /* number of bytes to copy */ - &err, p_fci_internal->pv) != sizeof(cfreserved) ) { - /* write error */ - fci_set_error( FCIERR_CAB_FILE, ERROR_WRITE_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - /* reset little endian */ - cfreserved.cbCFHeader=fci_endian_uword(cfreserved.cbCFHeader); - } - - /* add optional reserved area */ - if (cbReserveCFHeader!=0) { - if(!(reserved = PFCI_ALLOC(hfci, cbReserveCFHeader))) { - fci_set_error( FCIERR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY, TRUE ); - return FALSE; - } - for(i=0;ipv) != cbReserveCFHeader ) { - PFCI_FREE(hfci, reserved); - /* write error */ - fci_set_error( FCIERR_CAB_FILE, ERROR_WRITE_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - PFCI_FREE(hfci, reserved); - } - - if( cfheader.flags & cfheadPREV_CABINET ) { - if( PFCI_WRITE(hfci, handleCABINET, /* file handle */ - p_fci_internal->szPrevCab, /* memory buffer */ - strlen(p_fci_internal->szPrevCab)+1, /* number of bytes to copy */ - &err, p_fci_internal->pv) != strlen(p_fci_internal->szPrevCab)+1 ) { - /* write error */ - fci_set_error( FCIERR_CAB_FILE, ERROR_WRITE_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - if( PFCI_WRITE(hfci, handleCABINET, /* file handle */ - p_fci_internal->szPrevDisk, /* memory buffer */ - strlen(p_fci_internal->szPrevDisk)+1, /* number of bytes to copy */ - &err, p_fci_internal->pv) != strlen(p_fci_internal->szPrevDisk)+1 ) { - /* write error */ - fci_set_error( FCIERR_CAB_FILE, ERROR_WRITE_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - } - - if( cfheader.flags & cfheadNEXT_CABINET ) { - if( PFCI_WRITE(hfci, handleCABINET, /* file handle */ - p_fci_internal->pccab->szCab, /* memory buffer */ - strlen(p_fci_internal->pccab->szCab)+1, /* number of bytes to copy */ - &err, p_fci_internal->pv) != strlen(p_fci_internal->pccab->szCab)+1 ) { - /* write error */ - fci_set_error( FCIERR_CAB_FILE, ERROR_WRITE_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - if( PFCI_WRITE(hfci, handleCABINET, /* file handle */ - p_fci_internal->pccab->szDisk, /* memory buffer */ - strlen(p_fci_internal->pccab->szDisk)+1, /* number of bytes to copy */ - &err, p_fci_internal->pv) != strlen(p_fci_internal->pccab->szDisk)+1 ) { - /* write error */ - fci_set_error( FCIERR_CAB_FILE, ERROR_WRITE_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - } - - /* set seek of p_fci_internal->handleCFFOLDER to 0 */ - if( PFCI_SEEK(hfci,p_fci_internal->handleCFFOLDER, - 0, SEEK_SET, &err, p_fci_internal->pv) != 0 ) { - /* wrong return value */ - fci_set_error( FCIERR_NONE, ERROR_SEEK, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - /* while not all CFFOLDER structures have been copied into the cabinet do */ - while(!FALSE) { - /* use the variable read_result */ - /* read cffolder of p_fci_internal->handleCFFOLDER */ - read_result = PFCI_READ(hfci, p_fci_internal->handleCFFOLDER, /* handle */ - &cffolder, /* memory buffer */ - sizeof(cffolder), /* number of bytes to copy */ - &err, p_fci_internal->pv); - if( read_result != sizeof(cffolder) ) { - if( read_result == 0 ) break;/*ALL CFFOLDER structures have been copied*/ - /* read error */ - fci_set_error( FCIERR_NONE, ERROR_READ_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - /* add size of header size of all CFFOLDERs and size of all CFFILEs */ - cffolder.coffCabStart += - p_fci_internal->sizeFileCFFILE2 + p_fci_internal->sizeFileCFFOLDER + - sizeof(CFHEADER); - if( p_fci_internal->fNextCab || - p_fci_internal->fGetNextCabInVain ) { - cffolder.coffCabStart+=p_fci_internal->oldCCAB.cbReserveCFHeader; - } else { - cffolder.coffCabStart+=p_fci_internal->pccab->cbReserveCFHeader; - } - - if (p_fci_internal->fPrevCab) { - cffolder.coffCabStart += strlen(p_fci_internal->szPrevCab)+1 + - strlen(p_fci_internal->szPrevDisk)+1; - } - - if (p_fci_internal->fNextCab) { - cffolder.coffCabStart += strlen(p_fci_internal->oldCCAB.szCab)+1 + - strlen(p_fci_internal->oldCCAB.szDisk)+1; - } - - if( p_fci_internal->fNextCab || - p_fci_internal->fGetNextCabInVain ) { - cffolder.coffCabStart += p_fci_internal->oldCCAB.cbReserveCFHeader; - if( p_fci_internal->oldCCAB.cbReserveCFHeader != 0 || - p_fci_internal->oldCCAB.cbReserveCFFolder != 0 || - p_fci_internal->oldCCAB.cbReserveCFData != 0 ) { - cffolder.coffCabStart += 4; - } - } else { - cffolder.coffCabStart += p_fci_internal->pccab->cbReserveCFHeader; - if( p_fci_internal->pccab->cbReserveCFHeader != 0 || - p_fci_internal->pccab->cbReserveCFFolder != 0 || - p_fci_internal->pccab->cbReserveCFData != 0 ) { - cffolder.coffCabStart += 4; - } - } - - /* set little endian */ - cffolder.coffCabStart=fci_endian_ulong(cffolder.coffCabStart); - cffolder.cCFData=fci_endian_uword(cffolder.cCFData); - cffolder.typeCompress=fci_endian_uword(cffolder.typeCompress); - - /* write cffolder to cabinet file */ - if( PFCI_WRITE(hfci, handleCABINET, /* file handle */ - &cffolder, /* memory buffer */ - sizeof(cffolder), /* number of bytes to copy */ - &err, p_fci_internal->pv) != sizeof(cffolder) ) { - /* write error */ - fci_set_error( FCIERR_CAB_FILE, ERROR_WRITE_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - /* reset little endian */ - cffolder.coffCabStart=fci_endian_ulong(cffolder.coffCabStart); - cffolder.cCFData=fci_endian_uword(cffolder.cCFData); - cffolder.typeCompress=fci_endian_uword(cffolder.typeCompress); - - /* add optional reserved area */ - - /* This allocation and freeing at each CFFolder block is a bit */ - /* inefficient, but it's harder to forget about freeing the buffer :-). */ - /* Reserved areas are used seldom besides that... */ - if (cbReserveCFFolder!=0) { - if(!(reserved = PFCI_ALLOC(hfci, cbReserveCFFolder))) { - fci_set_error( FCIERR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY, TRUE ); - return FALSE; - } - - if( PFCI_READ(hfci, p_fci_internal->handleCFFOLDER, /* file handle */ - reserved, /* memory buffer */ - cbReserveCFFolder, /* number of bytes to copy */ - &err, p_fci_internal->pv) != cbReserveCFFolder ) { - PFCI_FREE(hfci, reserved); - /* read error */ - fci_set_error( FCIERR_NONE, ERROR_READ_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - if( PFCI_WRITE(hfci, handleCABINET, /* file handle */ - reserved, /* memory buffer */ - cbReserveCFFolder, /* number of bytes to copy */ - &err, p_fci_internal->pv) != cbReserveCFFolder ) { - PFCI_FREE(hfci, reserved); - /* write error */ - fci_set_error( FCIERR_CAB_FILE, ERROR_WRITE_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - PFCI_FREE(hfci, reserved); - } - - } /* END OF while */ - - /* set seek of p_fci_internal->handleCFFILE2 to 0 */ - if( PFCI_SEEK(hfci,p_fci_internal->handleCFFILE2, - 0, SEEK_SET, &err, p_fci_internal->pv) != 0 ) { - /* wrong return value */ - fci_set_error( FCIERR_NONE, ERROR_SEEK, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - /* while not all CFFILE structures have been copied to the cabinet do */ - if (p_fci_internal->data_out) while(!FALSE) { - /* REUSE the variable read_result */ - /* REUSE the buffer p_fci_internal->data_out AGAIN */ - /* read a block from p_fci_internal->handleCFFILE2 */ - read_result = PFCI_READ(hfci, p_fci_internal->handleCFFILE2 /* handle */, - p_fci_internal->data_out, /* memory buffer */ - CB_MAX_CHUNK, /* number of bytes to copy */ - &err, p_fci_internal->pv); - if( read_result == 0 ) break; /* ALL CFFILE structures have been copied */ - /* TODO error handling of err */ - - /* write the block to the cabinet file */ - if( PFCI_WRITE(hfci, handleCABINET, /* file handle */ - p_fci_internal->data_out, /* memory buffer */ - read_result, /* number of bytes to copy */ - &err, p_fci_internal->pv) != read_result ) { - /* write error */ - fci_set_error( FCIERR_CAB_FILE, ERROR_WRITE_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - if (p_fci_internal->fSplitFolder==FALSE) { - p_fci_internal->statusFolderCopied = 0; - /* TODO TEST THIS further */ - p_fci_internal->statusFolderTotal = p_fci_internal->sizeFileCFDATA2+ - p_fci_internal->sizeFileCFFILE2; - } - p_fci_internal->statusFolderCopied += read_result; - - /* report status with pfnfcis about copied size of folder */ - if( (*pfnfcis)(statusFolder, - p_fci_internal->statusFolderCopied, /* length of copied blocks */ - p_fci_internal->statusFolderTotal, /* total size of folder */ - p_fci_internal->pv) == -1) { - fci_set_error( FCIERR_USER_ABORT, 0, TRUE ); - return FALSE; - } - - } /* END OF while */ - - /* set seek of p_fci_internal->handleCFDATA2 to 0 */ - if( PFCI_SEEK(hfci,p_fci_internal->handleCFDATA2, - 0, SEEK_SET, &err, p_fci_internal->pv) != 0 ) { - /* wrong return value */ - fci_set_error( FCIERR_NONE, ERROR_SEEK, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - /* reset the number of folders for the next cabinet */ - p_fci_internal->cFolders=0; - /* reset the number of files for the next cabinet */ - p_fci_internal->cFiles=0; - - /* while not all CFDATA structures have been copied to the cabinet do */ - if (p_fci_internal->data_out) while(!FALSE) { - /* REUSE the variable read_result AGAIN */ - /* REUSE the buffer p_fci_internal->data_out AGAIN */ - /* read a block from p_fci_internal->handleCFDATA2 */ - read_result = PFCI_READ(hfci, p_fci_internal->handleCFDATA2 /* handle */, - p_fci_internal->data_out, /* memory buffer */ - CB_MAX_CHUNK, /* number of bytes to copy */ - &err, p_fci_internal->pv); - if( read_result == 0 ) break; /* ALL CFDATA structures have been copied */ - /* TODO error handling of err */ - - /* write the block to the cabinet file */ - if( PFCI_WRITE(hfci, handleCABINET, /* file handle */ - p_fci_internal->data_out, /* memory buffer */ - read_result, /* number of bytes to copy */ - &err, p_fci_internal->pv) != read_result ) { - /* write error */ - fci_set_error( FCIERR_CAB_FILE, ERROR_WRITE_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - p_fci_internal->statusFolderCopied += read_result; - /* report status with pfnfcis about copied size of folder */ - if( (*pfnfcis)(statusFolder, - p_fci_internal->statusFolderCopied, /* length of copied blocks */ - p_fci_internal->statusFolderTotal, /* total size of folder */ - p_fci_internal->pv) == -1) { - /* set error code and abort */ - fci_set_error( FCIERR_USER_ABORT, 0, TRUE ); - return FALSE; - } - } /* END OF while */ - - /* set seek of the cabinet file to 0 */ - if( PFCI_SEEK(hfci, handleCABINET, - 0, SEEK_SET, &err, p_fci_internal->pv) != 0 ) { - /* wrong return value */ - fci_set_error( FCIERR_NONE, ERROR_SEEK, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - /* write the signature "MSCF" into the cabinet file */ - memcpy( cfheader.signature, "MSCF", 4 ); - if( PFCI_WRITE(hfci, handleCABINET, /* file handle */ - &cfheader, /* memory buffer */ - 4, /* number of bytes to copy */ - &err, p_fci_internal->pv) != 4 ) { - /* wrtie error */ - fci_set_error( FCIERR_CAB_FILE, ERROR_WRITE_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - /* close the cabinet file */ - PFCI_CLOSE(hfci,handleCABINET,&err,p_fci_internal->pv); - /* TODO error handling of err */ - - -/* COPIED FROM FCIDestroy */ - - PFCI_CLOSE (hfci, p_fci_internal->handleCFDATA2,&err,p_fci_internal->pv); - /* TODO error handling of err */ - PFCI_DELETE(hfci, p_fci_internal->szFileNameCFDATA2, &err, - p_fci_internal->pv); - /* TODO error handling of err */ - PFCI_CLOSE (hfci, p_fci_internal->handleCFFILE2,&err,p_fci_internal->pv); - /* TODO error handling of err */ - PFCI_DELETE(hfci, p_fci_internal->szFileNameCFFILE2, &err, - p_fci_internal->pv); - /* TODO error handling of err */ - PFCI_CLOSE (hfci, p_fci_internal->handleCFFOLDER,&err,p_fci_internal->pv); - /* TODO error handling of err */ - PFCI_DELETE(hfci, p_fci_internal->szFileNameCFFOLDER, &err, - p_fci_internal->pv); - /* TODO error handling of err */ - -/* END OF copied from FCIDestroy */ - - /* get 3 temporary files and open them */ - /* write names and handles to hfci */ - - - p_fci_internal->sizeFileCFDATA2 = 0; - p_fci_internal->sizeFileCFFILE2 = 0; - p_fci_internal->sizeFileCFFOLDER = 0; - -/* COPIED FROM FCICreate */ - - /* CFDATA with checksum and ready to be copied into cabinet */ - if( !PFCI_GETTEMPFILE(hfci, p_fci_internal->szFileNameCFDATA2, - CB_MAX_FILENAME)) { - /* error handling */ - fci_set_error( FCIERR_NONE, ERROR_FUNCTION_FAILED, TRUE ); - return FALSE; - } - /* safety */ - if ( strlen(p_fci_internal->szFileNameCFDATA2) >= CB_MAX_FILENAME ) { - /* set error code and abort */ - fci_set_error( FCIERR_NONE, ERROR_INVALID_DATA, TRUE ); - return FALSE; - } - p_fci_internal->handleCFDATA2 = PFCI_OPEN(hfci, - p_fci_internal->szFileNameCFDATA2, 34050, 384, &err, p_fci_internal->pv); - /* check handle */ - if(p_fci_internal->handleCFDATA2==0){ - fci_set_error( FCIERR_TEMP_FILE, ERROR_OPEN_FAILED, TRUE ); - return FALSE; - } - /* TODO error checking of err */ - - /* array of all CFFILE in a folder, ready to be copied into cabinet */ - if( !PFCI_GETTEMPFILE(hfci,p_fci_internal->szFileNameCFFILE2, - CB_MAX_FILENAME)) { - /* error handling */ - fci_set_error( FCIERR_NONE, ERROR_FUNCTION_FAILED, TRUE ); - return FALSE; - } - /* safety */ - if ( strlen(p_fci_internal->szFileNameCFFILE2) >= CB_MAX_FILENAME ) { - /* set error code and abort */ - fci_set_error( FCIERR_NONE, ERROR_INVALID_DATA, TRUE ); - return FALSE; - } - p_fci_internal->handleCFFILE2 = PFCI_OPEN(hfci, - p_fci_internal->szFileNameCFFILE2, 34050, 384, &err, p_fci_internal->pv); - /* check handle */ - if(p_fci_internal->handleCFFILE2==0){ - fci_set_error( FCIERR_TEMP_FILE, ERROR_OPEN_FAILED, TRUE); - return FALSE; - } - /* TODO error checking of err */ - - /* array of all CFFILE in a folder, ready to be copied into cabinet */ - if (!PFCI_GETTEMPFILE(hfci,p_fci_internal->szFileNameCFFOLDER,CB_MAX_FILENAME)) { - /* error handling */ - fci_set_error( FCIERR_NONE, ERROR_FUNCTION_FAILED, TRUE ); - return FALSE; - } - /* safety */ - if ( strlen(p_fci_internal->szFileNameCFFOLDER) >= CB_MAX_FILENAME ) { - /* set error code and abort */ - fci_set_error( FCIERR_NONE, ERROR_INVALID_DATA, TRUE ); - return FALSE; - } - p_fci_internal->handleCFFOLDER = PFCI_OPEN(hfci, - p_fci_internal->szFileNameCFFOLDER, 34050, 384, &err, p_fci_internal->pv); - /* check handle */ - if(p_fci_internal->handleCFFOLDER==0){ - fci_set_error( FCIERR_TEMP_FILE, ERROR_OPEN_FAILED, TRUE ); - return FALSE; - } - /* TODO error checking of err */ - -/* END OF copied from FCICreate */ - - - /* TODO close and delete new files when return FALSE */ - - - /* report status with pfnfcis about copied size of folder */ - (*pfnfcis)(statusCabinet, - p_fci_internal->estimatedCabinetSize, /* estimated cabinet file size */ - cfheader.cbCabinet /* real cabinet file size */, p_fci_internal->pv); + if (!write_cabinet( p_fci_internal, pfnfcis )) return FALSE; p_fci_internal->fPrevCab=TRUE; /* The sections szPrevCab and szPrevDisk are not being updated, because */ @@ -2178,59 +1288,36 @@ static BOOL fci_flush_cabinet( if (p_fci_internal->fNextCab) { p_fci_internal->fNextCab=FALSE; - if (p_fci_internal->sizeFileCFFILE1==0 && p_fci_internal->sizeFileCFDATA1!=0) { + if (p_fci_internal->files_size==0 && p_fci_internal->pending_data_size!=0) { /* THIS CAN NEVER HAPPEN */ /* set error code */ - fci_set_error( FCIERR_NONE, ERROR_GEN_FAILURE, TRUE ); + set_error( p_fci_internal, FCIERR_NONE, ERROR_GEN_FAILURE ); return FALSE; } -/* COPIED FROM FCIAddFile and modified */ - - /* REUSE the variable read_result */ - if (p_fci_internal->fGetNextCabInVain) { - read_result=p_fci_internal->oldCCAB.cbReserveCFHeader; - if(p_fci_internal->sizeFileCFFILE1!=0) { - 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->sizeFileCFFILE1!=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->sizeFileCFDATA1 + - p_fci_internal->sizeFileCFFILE1 + p_fci_internal->sizeFileCFDATA2 + - p_fci_internal->sizeFileCFFILE2 + p_fci_internal->sizeFileCFFOLDER + - sizeof(CFHEADER) + - sizeof(CFFOLDER); /* set size of new CFFolder entry */ - if( p_fci_internal->fNewPrevious ) { - memcpy(p_fci_internal->szPrevCab, p_fci_internal->oldCCAB.szCab, + memcpy(p_fci_internal->szPrevCab, p_fci_internal->ccab.szCab, CB_MAX_CABINET_NAME); - memcpy(p_fci_internal->szPrevDisk, p_fci_internal->oldCCAB.szDisk, + 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 */ + read_result=get_header_size( p_fci_internal ); + if(p_fci_internal->files_size!=0) { + read_result+=p_fci_internal->ccab.cbReserveCFFolder; + } + read_result+= p_fci_internal->pending_data_size + + p_fci_internal->files_size + p_fci_internal->folders_data_size + + p_fci_internal->placed_files_size + p_fci_internal->folders_size + + sizeof(CFFOLDER); /* set size of new CFFolder entry */ /* too much data for the maximum size of a cabinet */ if( p_fci_internal->fGetNextCabInVain==FALSE && - p_fci_internal->pccab->cb < read_result ) { - return fci_flush_cabinet( hfci, FALSE, pfnfcignc, pfnfcis); + p_fci_internal->ccab.cb < read_result ) { + return fci_flush_cabinet( p_fci_internal, FALSE, pfnfcignc, pfnfcis); } /* Might be too much data for the maximum size of a cabinet.*/ @@ -2240,11 +1327,9 @@ static BOOL fci_flush_cabinet( /* cabinet and name of the corresponding disk. */ /* So take care of this and get the name of the next cabinet */ 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 )) { - /* save CCAB */ - p_fci_internal->oldCCAB = *p_fci_internal->pccab; /* increment cabinet index */ ++(p_fci_internal->pccab->iCab); /* get name of next cabinet */ @@ -2253,7 +1338,7 @@ static BOOL fci_flush_cabinet( p_fci_internal->estimatedCabinetSize, /* estimated size of cab */ p_fci_internal->pv)) { /* error handling */ - fci_set_error( FCIERR_NONE, ERROR_FUNCTION_FAILED, TRUE ); + set_error( p_fci_internal, FCIERR_NONE, ERROR_FUNCTION_FAILED ); return FALSE; } /* Skip a few lines of code. This is caught by the next if. */ @@ -2262,40 +1347,29 @@ static BOOL fci_flush_cabinet( /* too much data for cabinet */ if (p_fci_internal->fGetNextCabInVain && ( - p_fci_internal->oldCCAB.cb < read_result + - strlen(p_fci_internal->oldCCAB.szCab)+1+ - strlen(p_fci_internal->oldCCAB.szDisk)+1 + p_fci_internal->ccab.cb < read_result + + strlen(p_fci_internal->ccab.szCab)+1+ + strlen(p_fci_internal->ccab.szDisk)+1 )) { p_fci_internal->fGetNextCabInVain=FALSE; p_fci_internal->fNextCab=TRUE; - return fci_flush_cabinet( hfci, FALSE, pfnfcignc, pfnfcis); + return fci_flush_cabinet( p_fci_internal, FALSE, pfnfcignc, pfnfcis); } /* if the FolderThreshold has been reached flush the folder automatically */ - if( p_fci_internal->fGetNextCabInVain ) { - if( p_fci_internal->cCompressedBytesInFolder >= - p_fci_internal->oldCCAB.cbFolderThresh) { - return FCIFlushFolder(hfci, pfnfcignc, pfnfcis); - } - } else { - if( p_fci_internal->cCompressedBytesInFolder >= - p_fci_internal->pccab->cbFolderThresh) { - return FCIFlushFolder(hfci, pfnfcignc, pfnfcis); - } - } + if (p_fci_internal->cCompressedBytesInFolder >= p_fci_internal->ccab.cbFolderThresh) + return fci_flush_folder(p_fci_internal, FALSE, pfnfcignc, pfnfcis); -/* END OF COPIED FROM FCIAddFile and modified */ - - if( p_fci_internal->sizeFileCFFILE1>0 ) { - if( !FCIFlushFolder(hfci, pfnfcignc, pfnfcis) ) return FALSE; + if( p_fci_internal->files_size>0 ) { + if( !fci_flush_folder(p_fci_internal, FALSE, pfnfcignc, pfnfcis) ) return FALSE; p_fci_internal->fNewPrevious=TRUE; } } else { p_fci_internal->fNewPrevious=FALSE; - if( p_fci_internal->sizeFileCFFILE1>0 || p_fci_internal->sizeFileCFDATA1) { + if( p_fci_internal->files_size>0 || p_fci_internal->pending_data_size) { /* THIS MAY NEVER HAPPEN */ /* set error structures */ - fci_set_error( FCIERR_NONE, ERROR_GEN_FAILURE, TRUE ); + set_error( p_fci_internal, FCIERR_NONE, ERROR_GEN_FAILURE ); return FALSE; } } @@ -2347,121 +1421,58 @@ BOOL __cdecl FCIAddFile( PFNFCIGETOPENINFO pfnfcigoi, TCOMP typeCompress) { - int err; - CFFILE cffile; cab_ULONG read_result; - int file_handle; - PFCI_Int p_fci_internal=((PFCI_Int)(hfci)); + FCI_Int *p_fci_internal = get_fci_ptr( hfci ); - /* test hfci */ - if (!REALLY_IS_FCI(hfci)) { - SetLastError(ERROR_INVALID_HANDLE); - return FALSE; - } + if (!p_fci_internal) return FALSE; if ((!pszSourceFile) || (!pszFileName) || (!pfnfcignc) || (!pfnfcis) || (!pfnfcigoi) || strlen(pszFileName)>=CB_MAX_FILENAME) { - fci_set_error( FCIERR_NONE, ERROR_BAD_ARGUMENTS, TRUE ); + set_error( p_fci_internal, FCIERR_NONE, ERROR_BAD_ARGUMENTS ); return FALSE; } + if (typeCompress != p_fci_internal->compression) + { + if (!FCIFlushFolder( hfci, pfnfcignc, pfnfcis )) return FALSE; + switch (typeCompress) + { + case tcompTYPE_MSZIP: +#ifdef HAVE_ZLIB + p_fci_internal->compression = tcompTYPE_MSZIP; + p_fci_internal->compress = compress_MSZIP; + break; +#endif + default: + FIXME( "compression %x not supported, defaulting to none\n", typeCompress ); + /* fall through */ + case tcompTYPE_NONE: + p_fci_internal->compression = tcompTYPE_NONE; + p_fci_internal->compress = compress_NONE; + break; + } + } + /* TODO check if pszSourceFile??? */ if(p_fci_internal->fGetNextCabInVain && p_fci_internal->fNextCab) { /* internal error */ - fci_set_error( FCIERR_NONE, ERROR_GEN_FAILURE, TRUE ); + set_error( p_fci_internal, FCIERR_NONE, ERROR_GEN_FAILURE ); return FALSE; } if(p_fci_internal->fNextCab) { /* internal error */ - fci_set_error( FCIERR_NONE, ERROR_GEN_FAILURE, TRUE ); + set_error( p_fci_internal, FCIERR_NONE, ERROR_GEN_FAILURE ); return FALSE; } - cffile.cbFile=0; /* size of the to be added file*/ - /* offset of the uncompressed file in the folder */ - cffile.uoffFolderStart=p_fci_internal->cDataBlocks*CAB_BLOCKMAX + p_fci_internal->cdata_in; - /* number of folder in the cabinet or special 0=first */ - cffile.iFolder = p_fci_internal->cFolders; - - /* allocation of memory */ - if (p_fci_internal->data_in==NULL) { - if (p_fci_internal->cdata_in!=0) { - /* error handling */ - fci_set_error( FCIERR_NONE, ERROR_GEN_FAILURE, TRUE ); - return FALSE; - } - if (p_fci_internal->data_out!=NULL) { - /* error handling */ - fci_set_error( FCIERR_NONE, ERROR_GEN_FAILURE, TRUE ); - return FALSE; - } - if(!(p_fci_internal->data_in = PFCI_ALLOC(hfci,CB_MAX_CHUNK))) { - fci_set_error( FCIERR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY, TRUE ); - return FALSE; - } - if (p_fci_internal->data_out==NULL) { - if(!(p_fci_internal->data_out = PFCI_ALLOC(hfci, 2 * CB_MAX_CHUNK))){ - fci_set_error( FCIERR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY, TRUE ); - return FALSE; - } - } - } - - if (p_fci_internal->data_out==NULL) { - PFCI_FREE(hfci,p_fci_internal->data_in); - /* error handling */ - fci_set_error( FCIERR_NONE, ERROR_GEN_FAILURE, TRUE ); - return FALSE; - } - - /* get information about the file */ - /* set defaults in case callback doesn't set one or more fields */ - cffile.attribs=0; - cffile.date=0; - cffile.time=0; - file_handle=(*pfnfcigoi)(pszSourceFile, &(cffile.date), &(cffile.time), - &(cffile.attribs), &err, p_fci_internal->pv); - /* check file_handle */ - if(file_handle==0){ - fci_set_error( FCIERR_OPEN_SRC, ERROR_OPEN_FAILED, TRUE ); - } - /* TODO error handling of err */ - - if (fExecute) { cffile.attribs |= _A_EXEC; } - /* REUSE the variable read_result */ - if (p_fci_internal->fGetNextCabInVain) { - 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=get_header_size( p_fci_internal ) + p_fci_internal->ccab.cbReserveCFFolder; read_result+= sizeof(CFFILE) + strlen(pszFileName)+1 + - p_fci_internal->sizeFileCFFILE1 + p_fci_internal->sizeFileCFDATA2 + - p_fci_internal->sizeFileCFFILE2 + p_fci_internal->sizeFileCFFOLDER + - sizeof(CFHEADER) + + p_fci_internal->files_size + p_fci_internal->folders_data_size + + p_fci_internal->placed_files_size + p_fci_internal->folders_size + sizeof(CFFOLDER); /* size of new CFFolder entry */ /* Might be too much data for the maximum size of a cabinet.*/ @@ -2472,12 +1483,10 @@ BOOL __cdecl FCIAddFile( /* So take care of this and get the name of the next cabinet */ if( p_fci_internal->fGetNextCabInVain==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 ) ) { - /* save CCAB */ - p_fci_internal->oldCCAB = *p_fci_internal->pccab; /* increment cabinet index */ ++(p_fci_internal->pccab->iCab); /* get name of next cabinet */ @@ -2486,7 +1495,7 @@ BOOL __cdecl FCIAddFile( p_fci_internal->estimatedCabinetSize, /* estimated size of cab */ p_fci_internal->pv)) { /* error handling */ - fci_set_error( FCIERR_NONE, ERROR_FUNCTION_FAILED, TRUE ); + set_error( p_fci_internal, FCIERR_NONE, ERROR_FUNCTION_FAILED ); return FALSE; } /* Skip a few lines of code. This is caught by the next if. */ @@ -2498,136 +1507,45 @@ BOOL __cdecl FCIAddFile( ) { /* THIS CAN NEVER HAPPEN */ /* set error code */ - fci_set_error( FCIERR_NONE, ERROR_GEN_FAILURE, TRUE ); + set_error( p_fci_internal, FCIERR_NONE, ERROR_GEN_FAILURE ); return FALSE; } /* too much data for cabinet */ 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->szDisk)+1 )) { p_fci_internal->fGetNextCabInVain=FALSE; p_fci_internal->fNextCab=TRUE; - if(!fci_flush_cabinet( hfci, FALSE, pfnfcignc, pfnfcis)) return FALSE; + if(!fci_flush_cabinet( p_fci_internal, FALSE, pfnfcignc, pfnfcis)) return FALSE; } if( p_fci_internal->fNextCab ) { /* THIS MAY NEVER HAPPEN */ /* set error code */ - fci_set_error( FCIERR_NONE, ERROR_GEN_FAILURE, TRUE ); + set_error( p_fci_internal, FCIERR_NONE, ERROR_GEN_FAILURE ); return FALSE; } - /* read the contents of the file blockwise */ - while (!FALSE) { - if (p_fci_internal->cdata_in > CAB_BLOCKMAX) { - /* internal error */ - fci_set_error( FCIERR_NONE, ERROR_GEN_FAILURE, TRUE ); + if (!add_file_data( p_fci_internal, pszSourceFile, pszFileName, fExecute, pfnfcigoi, pfnfcis )) return FALSE; - } - - read_result = PFCI_READ(hfci, file_handle /* file handle */, - (p_fci_internal->data_in + p_fci_internal->cdata_in) /* memory buffer */, - (CAB_BLOCKMAX - p_fci_internal->cdata_in) /* number of bytes to copy */, - &err, p_fci_internal->pv); - /* TODO error handling of err */ - - if( read_result==0 ) break; - - /* increment the block size */ - p_fci_internal->cdata_in += read_result; - - /* increment the file size */ - cffile.cbFile += read_result; - - if ( p_fci_internal->cdata_in > CAB_BLOCKMAX ) { - /* report internal error */ - fci_set_error( FCIERR_NONE, ERROR_GEN_FAILURE, TRUE ); - return FALSE; - } - /* write a whole block */ - if ( p_fci_internal->cdata_in == CAB_BLOCKMAX ) { - - if( !fci_flush_data_block(hfci, &err, pfnfcis) ) return FALSE; - } - } - - /* close the file from FCIAddFile */ - PFCI_CLOSE(hfci,file_handle,&err,p_fci_internal->pv); - /* TODO error handling of err */ - - /* write cffile to p_fci_internal->handleCFFILE1 */ - if( PFCI_WRITE(hfci, p_fci_internal->handleCFFILE1, /* file handle */ - &cffile, sizeof(cffile),&err, p_fci_internal->pv) != sizeof(cffile) ) { - /* write error */ - fci_set_error( FCIERR_TEMP_FILE, ERROR_WRITE_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - p_fci_internal->sizeFileCFFILE1 += sizeof(cffile); - - /* append the name of file */ - if (strlen(pszFileName)>=CB_MAX_FILENAME) { - /* IMPOSSIBLE */ - /* set error code */ - fci_set_error( FCIERR_NONE, ERROR_INVALID_DATA, TRUE ); - return FALSE; - } - if( PFCI_WRITE(hfci, p_fci_internal->handleCFFILE1, /* file handle */ - pszFileName, strlen(pszFileName)+1, &err, p_fci_internal->pv) - != strlen(pszFileName)+1 ) { - /* write error */ - fci_set_error( FCIERR_TEMP_FILE, ERROR_WRITE_FAULT, TRUE ); - return FALSE; - } - /* TODO error handling of err */ - - p_fci_internal->sizeFileCFFILE1 += strlen(pszFileName)+1; /* REUSE the variable read_result */ - if (p_fci_internal->fGetNextCabInVain || - 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->sizeFileCFDATA1 + - p_fci_internal->sizeFileCFFILE1 + p_fci_internal->sizeFileCFDATA2 + - p_fci_internal->sizeFileCFFILE2 + p_fci_internal->sizeFileCFFOLDER + - sizeof(CFHEADER) + + read_result = get_header_size( p_fci_internal ) + p_fci_internal->ccab.cbReserveCFFolder; + read_result+= p_fci_internal->pending_data_size + + p_fci_internal->files_size + p_fci_internal->folders_data_size + + p_fci_internal->placed_files_size + p_fci_internal->folders_size + sizeof(CFFOLDER); /* set size of new CFFolder entry */ /* too much data for the maximum size of a cabinet */ /* (ignoring the unflushed data block) */ if( p_fci_internal->fGetNextCabInVain==FALSE && p_fci_internal->fNextCab==FALSE && /* this is always the case */ - p_fci_internal->pccab->cb < read_result ) { - return fci_flush_cabinet( hfci, FALSE, pfnfcignc, pfnfcis); + p_fci_internal->ccab.cb < read_result ) { + return fci_flush_cabinet( p_fci_internal, FALSE, pfnfcignc, pfnfcis); } /* Might be too much data for the maximum size of a cabinet.*/ @@ -2639,12 +1557,10 @@ BOOL __cdecl FCIAddFile( /* (ignoring the unflushed data block) */ if( p_fci_internal->fGetNextCabInVain==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 ) ) { - /* save CCAB */ - p_fci_internal->oldCCAB = *p_fci_internal->pccab; /* increment cabinet index */ ++(p_fci_internal->pccab->iCab); /* get name of next cabinet */ @@ -2653,7 +1569,7 @@ BOOL __cdecl FCIAddFile( p_fci_internal->estimatedCabinetSize,/* estimated size of cab */ p_fci_internal->pv)) { /* error handling */ - fci_set_error( FCIERR_NONE, ERROR_FUNCTION_FAILED, TRUE ); + set_error( p_fci_internal, FCIERR_NONE, ERROR_FUNCTION_FAILED ); return FALSE; } /* Skip a few lines of code. This is caught by the next if. */ @@ -2664,42 +1580,33 @@ BOOL __cdecl FCIAddFile( p_fci_internal->fNextCab ) { /* THIS CAN NEVER HAPPEN */ - fci_set_error( FCIERR_NONE, ERROR_GEN_FAILURE, TRUE ); + set_error( p_fci_internal, FCIERR_NONE, ERROR_GEN_FAILURE ); return FALSE; } /* too much data for cabinet */ if( (p_fci_internal->fGetNextCabInVain || 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->szDisk)+1 )) { p_fci_internal->fGetNextCabInVain=FALSE; p_fci_internal->fNextCab=TRUE; - return fci_flush_cabinet( hfci, FALSE, pfnfcignc, pfnfcis); + return fci_flush_cabinet( p_fci_internal, FALSE, pfnfcignc, pfnfcis); } if( p_fci_internal->fNextCab ) { /* THIS MAY NEVER HAPPEN */ /* set error code */ - fci_set_error( FCIERR_NONE, ERROR_GEN_FAILURE, TRUE ); + set_error( p_fci_internal, FCIERR_NONE, ERROR_GEN_FAILURE ); return FALSE; } /* if the FolderThreshold has been reached flush the folder automatically */ - if( p_fci_internal->fGetNextCabInVain ) { - if( p_fci_internal->cCompressedBytesInFolder >= - p_fci_internal->oldCCAB.cbFolderThresh) { + if (p_fci_internal->cCompressedBytesInFolder >= p_fci_internal->ccab.cbFolderThresh) return FCIFlushFolder(hfci, pfnfcignc, pfnfcis); - } - } else { - if( p_fci_internal->cCompressedBytesInFolder >= - p_fci_internal->pccab->cbFolderThresh) { - return FCIFlushFolder(hfci, pfnfcignc, pfnfcis); - } - } return TRUE; } /* end of FCIAddFile */ @@ -2743,8 +1650,11 @@ BOOL __cdecl FCIFlushFolder( PFNFCIGETNEXTCABINET pfnfcignc, PFNFCISTATUS pfnfcis) { - return fci_flush_folder(hfci,FALSE,pfnfcignc,pfnfcis); -} /* end of FCIFlushFolder */ + FCI_Int *p_fci_internal = get_fci_ptr( hfci ); + + if (!p_fci_internal) return FALSE; + return fci_flush_folder(p_fci_internal,FALSE,pfnfcignc,pfnfcis); +} @@ -2785,17 +1695,19 @@ BOOL __cdecl FCIFlushCabinet( PFNFCIGETNEXTCABINET pfnfcignc, PFNFCISTATUS pfnfcis) { - PFCI_Int p_fci_internal=((PFCI_Int)(hfci)); + FCI_Int *p_fci_internal = get_fci_ptr( hfci ); - if(!fci_flush_cabinet(hfci,fGetNextCab,pfnfcignc,pfnfcis)) return FALSE; + if (!p_fci_internal) return FALSE; - while( p_fci_internal->sizeFileCFFILE1>0 || - p_fci_internal->sizeFileCFFILE2>0 ) { - if(!fci_flush_cabinet(hfci,fGetNextCab,pfnfcignc,pfnfcis)) return FALSE; + if(!fci_flush_cabinet(p_fci_internal,fGetNextCab,pfnfcignc,pfnfcis)) return FALSE; + + while( p_fci_internal->files_size>0 || + p_fci_internal->placed_files_size>0 ) { + if(!fci_flush_cabinet(p_fci_internal,fGetNextCab,pfnfcignc,pfnfcis)) return FALSE; } return TRUE; -} /* end of FCIFlushCabinet */ +} /*********************************************************************** @@ -2813,52 +1725,33 @@ BOOL __cdecl FCIFlushCabinet( */ BOOL __cdecl FCIDestroy(HFCI hfci) { - int err; - PFCI_Int p_fci_internal=((PFCI_Int)(hfci)); - if (REALLY_IS_FCI(hfci)) { + struct folder *folder, *folder_next; + struct file *file, *file_next; + struct data_block *block, *block_next; + FCI_Int *p_fci_internal = get_fci_ptr( hfci ); + + if (!p_fci_internal) return FALSE; /* before hfci can be removed all temporary files must be closed */ /* and deleted */ - p_fci_internal->FCI_Intmagic = 0; + p_fci_internal->magic = 0; - PFCI_CLOSE (hfci, p_fci_internal->handleCFDATA1,&err,p_fci_internal->pv); - /* TODO error handling of err */ - PFCI_DELETE(hfci, p_fci_internal->szFileNameCFDATA1, &err, - p_fci_internal->pv); - /* TODO error handling of err */ - PFCI_CLOSE (hfci, p_fci_internal->handleCFFILE1,&err,p_fci_internal->pv); - /* TODO error handling of err */ - PFCI_DELETE(hfci, p_fci_internal->szFileNameCFFILE1, &err, - p_fci_internal->pv); - /* TODO error handling of err */ - PFCI_CLOSE (hfci, p_fci_internal->handleCFDATA2,&err,p_fci_internal->pv); - /* TODO error handling of err */ - PFCI_DELETE(hfci, p_fci_internal->szFileNameCFDATA2, &err, - p_fci_internal->pv); - /* TODO error handling of err */ - PFCI_CLOSE (hfci, p_fci_internal->handleCFFILE2,&err,p_fci_internal->pv); - /* TODO error handling of err */ - PFCI_DELETE(hfci, p_fci_internal->szFileNameCFFILE2, &err, - p_fci_internal->pv); - /* TODO error handling of err */ - PFCI_CLOSE (hfci, p_fci_internal->handleCFFOLDER,&err,p_fci_internal->pv); - /* TODO error handling of err */ - PFCI_DELETE(hfci, p_fci_internal->szFileNameCFFOLDER, &err, - p_fci_internal->pv); - /* TODO error handling of err */ + LIST_FOR_EACH_ENTRY_SAFE( folder, folder_next, &p_fci_internal->folders_list, struct folder, entry ) + { + free_folder( p_fci_internal, folder ); + } + LIST_FOR_EACH_ENTRY_SAFE( file, file_next, &p_fci_internal->files_list, struct file, entry ) + { + free_file( p_fci_internal, file ); + } + LIST_FOR_EACH_ENTRY_SAFE( block, block_next, &p_fci_internal->blocks_list, struct data_block, entry ) + { + free_data_block( p_fci_internal, block ); + } - /* data in and out buffers have to be removed */ - if (p_fci_internal->data_in!=NULL) - PFCI_FREE(hfci, p_fci_internal->data_in); - if (p_fci_internal->data_out!=NULL) - PFCI_FREE(hfci, p_fci_internal->data_out); + close_temp_file( p_fci_internal, &p_fci_internal->data ); /* hfci can now be removed */ - PFCI_FREE(hfci, hfci); + p_fci_internal->free(hfci); return TRUE; - } else { - SetLastError(ERROR_INVALID_HANDLE); - return FALSE; - } - -} /* end of FCIDestroy */ +} diff --git a/reactos/dll/win32/cabinet/fdi.c b/reactos/dll/win32/cabinet/fdi.c index b68ab15acd8..d091dbb2128 100644 --- a/reactos/dll/win32/cabinet/fdi.c +++ b/reactos/dll/win32/cabinet/fdi.c @@ -48,7 +48,7 @@ * Test unit(s). * * The fdintNEXT_CABINET callbacks are probably not working quite as they should. - * There are several FIXME's in the source describing some of the deficiencies in + * There are several FIXMEs in the source describing some of the deficiencies in * some detail. Additionally, we do not do a very good job of returning the right * error codes to this callback. * @@ -110,6 +110,21 @@ typedef struct { cab_UBYTE block_resv; } MORE_ISCAB_INFO, *PMORE_ISCAB_INFO; +typedef struct +{ + unsigned int magic; + PFNALLOC alloc; + PFNFREE free; + PFNOPEN open; + PFNREAD read; + PFNWRITE write; + PFNCLOSE close; + PFNSEEK seek; + PERF perf; +} FDI_Int; + +#define FDI_INT_MAGIC 0xfdfdfd05 + /* * ugh, well, this ended up being pretty damn silly... * now that I've conceded to build equivalent structures to struct cab.*, @@ -120,7 +135,7 @@ typedef struct { */ typedef struct fdi_cds_fwd { - void *hfdi; /* the hfdi we are using */ + FDI_Int *fdi; /* the hfdi we are using */ INT_PTR filehf, cabhf; /* file handle we are using */ struct fdi_folder *current; /* current folder we're extracting from */ cab_ULONG offset; /* uncompressed offset within folder */ @@ -148,6 +163,47 @@ typedef struct fdi_cds_fwd { struct fdi_cds_fwd *next; } fdi_decomp_state; +#define ZIPNEEDBITS(n) {while(k<(n)){cab_LONG c=*(ZIP(inpos)++);\ + b|=((cab_ULONG)c)<>=(n);k-=(n);} + +/* endian-neutral reading of little-endian data */ +#define EndGetI32(a) ((((a)[3])<<24)|(((a)[2])<<16)|(((a)[1])<<8)|((a)[0])) +#define EndGetI16(a) ((((a)[1])<<8)|((a)[0])) + +#define CAB(x) (decomp_state->x) +#define ZIP(x) (decomp_state->methods.zip.x) +#define QTM(x) (decomp_state->methods.qtm.x) +#define LZX(x) (decomp_state->methods.lzx.x) +#define DECR_OK (0) +#define DECR_DATAFORMAT (1) +#define DECR_ILLEGALDATA (2) +#define DECR_NOMEMORY (3) +#define DECR_CHECKSUM (4) +#define DECR_INPUT (5) +#define DECR_OUTPUT (6) +#define DECR_USERABORT (7) + +static void set_error( FDI_Int *fdi, int oper, int err ) +{ + fdi->perf->erfOper = oper; + fdi->perf->erfType = err; + fdi->perf->fError = TRUE; + if (err) SetLastError( err ); +} + +static FDI_Int *get_fdi_ptr( HFDI hfdi ) +{ + FDI_Int *fdi= (FDI_Int *)hfdi; + + if (!fdi || fdi->magic != FDI_INT_MAGIC) + { + SetLastError( ERROR_INVALID_HANDLE ); + return NULL; + } + return fdi; +} + /**************************************************************** * QTMupdatemodel (internal) */ @@ -304,7 +360,9 @@ static cab_ULONG checksum(const cab_UBYTE *data, cab_UWORD bytes, cab_ULONG csum switch (bytes & 3) { case 3: ul |= *data++ << 16; + /* fall through */ case 2: ul |= *data++ << 8; + /* fall through */ case 1: ul |= *data; } csum ^= ul; @@ -362,7 +420,7 @@ HFDI __cdecl FDICreate( int cpuType, PERF perf) { - HFDI rv; + FDI_Int *fdi; TRACE("(pfnalloc == ^%p, pfnfree == ^%p, pfnopen == ^%p, pfnread == ^%p, pfnwrite == ^%p, " "pfnclose == ^%p, pfnseek == ^%p, cpuType == %d, perf == ^%p)\n", @@ -378,28 +436,26 @@ HFDI __cdecl FDICreate( return NULL; } - if (!((rv = (*pfnalloc)(sizeof(FDI_Int))))) { + if (!((fdi = pfnalloc(sizeof(FDI_Int))))) { perf->erfOper = FDIERROR_ALLOC_FAIL; - perf->erfType = ERROR_NOT_ENOUGH_MEMORY; + perf->erfType = 0; perf->fError = TRUE; - - SetLastError(ERROR_NOT_ENOUGH_MEMORY); return NULL; } - - PFDI_INT(rv)->FDI_Intmagic = FDI_INT_MAGIC; - PFDI_INT(rv)->pfnalloc = pfnalloc; - PFDI_INT(rv)->pfnfree = pfnfree; - PFDI_INT(rv)->pfnopen = pfnopen; - PFDI_INT(rv)->pfnread = pfnread; - PFDI_INT(rv)->pfnwrite = pfnwrite; - PFDI_INT(rv)->pfnclose = pfnclose; - PFDI_INT(rv)->pfnseek = pfnseek; + + fdi->magic = FDI_INT_MAGIC; + fdi->alloc = pfnalloc; + fdi->free = pfnfree; + fdi->open = pfnopen; + fdi->read = pfnread; + fdi->write = pfnwrite; + fdi->close = pfnclose; + fdi->seek = pfnseek; /* no-brainer: we ignore the cpu type; this is only used for the 16-bit versions in Windows anyhow... */ - PFDI_INT(rv)->perf = perf; + fdi->perf = perf; - return rv; + return (HFDI)fdi; } /******************************************************************* @@ -407,9 +463,9 @@ HFDI __cdecl FDICreate( * * returns the file pointer position of a file handle. */ -static long FDI_getoffset(HFDI hfdi, INT_PTR hf) +static LONG FDI_getoffset(FDI_Int *fdi, INT_PTR hf) { - return PFDI_SEEK(hfdi, hf, 0L, SEEK_CUR); + return fdi->seek(hf, 0, SEEK_CUR); } /********************************************************************** @@ -417,21 +473,21 @@ static long FDI_getoffset(HFDI hfdi, INT_PTR hf) * * allocate and read an arbitrarily long string from the cabinet */ -static char *FDI_read_string(HFDI hfdi, INT_PTR hf, long cabsize) +static char *FDI_read_string(FDI_Int *fdi, INT_PTR hf, long cabsize) { size_t len=256, - base = FDI_getoffset(hfdi, hf), + base = FDI_getoffset(fdi, hf), maxlen = cabsize - base; BOOL ok = FALSE; unsigned int i; cab_UBYTE *buf = NULL; - TRACE("(hfdi == ^%p, hf == %ld, cabsize == %ld)\n", hfdi, hf, cabsize); + TRACE("(fdi == %p, hf == %ld, cabsize == %ld)\n", fdi, hf, cabsize); do { if (len > maxlen) len = maxlen; - if (!(buf = PFDI_ALLOC(hfdi, len))) break; - if (!PFDI_READ(hfdi, hf, buf, len)) break; + if (!(buf = fdi->alloc(len))) break; + if (!fdi->read(hf, buf, len)) break; /* search for a null terminator in what we've just read */ for (i=0; i < len; i++) { @@ -446,8 +502,8 @@ static char *FDI_read_string(HFDI hfdi, INT_PTR hf, long cabsize) /* The buffer is too small for the string. Reset the file to the point * were we started, free the buffer and increase the size for the next try */ - PFDI_SEEK(hfdi, hf, base, SEEK_SET); - PFDI_FREE(hfdi, buf); + fdi->seek(hf, base, SEEK_SET); + fdi->free(buf); buf = NULL; len *= 2; } @@ -455,14 +511,14 @@ static char *FDI_read_string(HFDI hfdi, INT_PTR hf, long cabsize) if (!ok) { if (buf) - PFDI_FREE(hfdi, buf); + fdi->free(buf); else ERR("out of memory!\n"); return NULL; } /* otherwise, set the stream to just after the string and return */ - PFDI_SEEK(hfdi, hf, base + strlen((char *)buf) + 1, SEEK_SET); + fdi->seek(hf, base + strlen((char *)buf) + 1, SEEK_SET); return (char *) buf; } @@ -474,7 +530,7 @@ static char *FDI_read_string(HFDI hfdi, INT_PTR hf, long cabsize) * without the sanity checks (and bug) */ static BOOL FDI_read_entries( - HFDI hfdi, + FDI_Int *fdi, INT_PTR hf, PFDICABINETINFO pfdici, PMORE_ISCAB_INFO pmii) @@ -485,7 +541,7 @@ static BOOL FDI_read_entries( cab_UBYTE buf[64], block_resv; char *prevname = NULL, *previnfo = NULL, *nextname = NULL, *nextinfo = NULL; - TRACE("(hfdi == ^%p, hf == %ld, pfdici == ^%p)\n", hfdi, hf, pfdici); + TRACE("(fdi == ^%p, hf == %ld, pfdici == ^%p)\n", fdi, hf, pfdici); /* * FIXME: I just noticed that I am memorizing the initial file pointer @@ -518,74 +574,38 @@ static BOOL FDI_read_entries( */ /* get basic offset & size info */ - base_offset = FDI_getoffset(hfdi, hf); + base_offset = FDI_getoffset(fdi, hf); - if (PFDI_SEEK(hfdi, hf, 0, SEEK_END) == -1) { - if (pmii) { - PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NOT_A_CABINET; - PFDI_INT(hfdi)->perf->erfType = 0; - PFDI_INT(hfdi)->perf->fError = TRUE; - } + if (fdi->seek(hf, 0, SEEK_END) == -1) { + if (pmii) set_error( fdi, FDIERROR_NOT_A_CABINET, 0 ); return FALSE; } - cabsize = FDI_getoffset(hfdi, hf); + cabsize = FDI_getoffset(fdi, hf); if ((cabsize == -1) || (base_offset == -1) || - ( PFDI_SEEK(hfdi, hf, base_offset, SEEK_SET) == -1 )) { - if (pmii) { - PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NOT_A_CABINET; - PFDI_INT(hfdi)->perf->erfType = 0; - PFDI_INT(hfdi)->perf->fError = TRUE; - } + ( fdi->seek(hf, base_offset, SEEK_SET) == -1 )) { + if (pmii) set_error( fdi, FDIERROR_NOT_A_CABINET, 0 ); return FALSE; } /* read in the CFHEADER */ - if (PFDI_READ(hfdi, hf, buf, cfhead_SIZEOF) != cfhead_SIZEOF) { - if (pmii) { - PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NOT_A_CABINET; - PFDI_INT(hfdi)->perf->erfType = 0; - PFDI_INT(hfdi)->perf->fError = TRUE; - } + if (fdi->read(hf, buf, cfhead_SIZEOF) != cfhead_SIZEOF) { + if (pmii) set_error( fdi, FDIERROR_NOT_A_CABINET, 0 ); return FALSE; } /* check basic MSCF signature */ if (EndGetI32(buf+cfhead_Signature) != 0x4643534d) { - if (pmii) { - PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NOT_A_CABINET; - PFDI_INT(hfdi)->perf->erfType = 0; - PFDI_INT(hfdi)->perf->fError = TRUE; - } + if (pmii) set_error( fdi, FDIERROR_NOT_A_CABINET, 0 ); return FALSE; } /* get the number of folders */ num_folders = EndGetI16(buf+cfhead_NumFolders); - if (num_folders == 0) { - /* PONDERME: is this really invalid? */ - WARN("weird cabinet detect failure: no folders in cabinet\n"); - if (pmii) { - PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NOT_A_CABINET; - PFDI_INT(hfdi)->perf->erfType = 0; - PFDI_INT(hfdi)->perf->fError = TRUE; - } - return FALSE; - } /* get the number of files */ num_files = EndGetI16(buf+cfhead_NumFiles); - if (num_files == 0) { - /* PONDERME: is this really invalid? */ - WARN("weird cabinet detect failure: no files in cabinet\n"); - if (pmii) { - PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NOT_A_CABINET; - PFDI_INT(hfdi)->perf->erfType = 0; - PFDI_INT(hfdi)->perf->fError = TRUE; - } - return FALSE; - } /* setid */ setid = EndGetI16(buf+cfhead_SetID); @@ -598,11 +618,7 @@ static BOOL FDI_read_entries( (buf[cfhead_MajorVersion] == 1 && buf[cfhead_MinorVersion] > 3)) { WARN("cabinet format version > 1.3\n"); - if (pmii) { - PFDI_INT(hfdi)->perf->erfOper = FDIERROR_UNKNOWN_CABINET_VERSION; - PFDI_INT(hfdi)->perf->erfType = 0; /* ? */ - PFDI_INT(hfdi)->perf->fError = TRUE; - } + if (pmii) set_error( fdi, FDIERROR_UNKNOWN_CABINET_VERSION, 0 /* ? */ ); return FALSE; } @@ -611,13 +627,9 @@ static BOOL FDI_read_entries( /* read the reserved-sizes part of header, if present */ if (flags & cfheadRESERVE_PRESENT) { - if (PFDI_READ(hfdi, hf, buf, cfheadext_SIZEOF) != cfheadext_SIZEOF) { + if (fdi->read(hf, buf, cfheadext_SIZEOF) != cfheadext_SIZEOF) { ERR("bunk reserve-sizes?\n"); - if (pmii) { - PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET; - PFDI_INT(hfdi)->perf->erfType = 0; /* ? */ - PFDI_INT(hfdi)->perf->fError = TRUE; - } + if (pmii) set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 /* ? */ ); return FALSE; } @@ -633,64 +645,54 @@ static BOOL FDI_read_entries( } /* skip the reserved header */ - if ((header_resv) && (PFDI_SEEK(hfdi, hf, header_resv, SEEK_CUR) == -1)) { + if ((header_resv) && (fdi->seek(hf, header_resv, SEEK_CUR) == -1)) { ERR("seek failure: header_resv\n"); - if (pmii) { - PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET; - PFDI_INT(hfdi)->perf->erfType = 0; /* ? */ - PFDI_INT(hfdi)->perf->fError = TRUE; - } + if (pmii) set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 /* ? */ ); return FALSE; } } if (flags & cfheadPREV_CABINET) { - prevname = FDI_read_string(hfdi, hf, cabsize); + prevname = FDI_read_string(fdi, hf, cabsize); if (!prevname) { - if (pmii) { - PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET; - PFDI_INT(hfdi)->perf->erfType = 0; /* ? */ - PFDI_INT(hfdi)->perf->fError = TRUE; - } + if (pmii) set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 /* ? */ ); return FALSE; } else if (pmii) pmii->prevname = prevname; else - PFDI_FREE(hfdi, prevname); - previnfo = FDI_read_string(hfdi, hf, cabsize); + fdi->free(prevname); + previnfo = FDI_read_string(fdi, hf, cabsize); if (previnfo) { if (pmii) pmii->previnfo = previnfo; else - PFDI_FREE(hfdi, previnfo); + fdi->free(previnfo); } } if (flags & cfheadNEXT_CABINET) { if (pmii) pmii->hasnext = TRUE; - nextname = FDI_read_string(hfdi, hf, cabsize); + nextname = FDI_read_string(fdi, hf, cabsize); if (!nextname) { if ((flags & cfheadPREV_CABINET) && pmii) { - if (pmii->prevname) PFDI_FREE(hfdi, prevname); - if (pmii->previnfo) PFDI_FREE(hfdi, previnfo); + if (pmii->prevname) fdi->free(prevname); + if (pmii->previnfo) fdi->free(previnfo); } - PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET; - PFDI_INT(hfdi)->perf->erfType = 0; /* ? */ - PFDI_INT(hfdi)->perf->fError = TRUE; + set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 /* ? */ ); return FALSE; } else if (pmii) pmii->nextname = nextname; else - PFDI_FREE(hfdi, nextname); - nextinfo = FDI_read_string(hfdi, hf, cabsize); + fdi->free(nextname); + nextinfo = FDI_read_string(fdi, hf, cabsize); if (nextinfo) { if (pmii) pmii->nextinfo = nextinfo; else - PFDI_FREE(hfdi, nextinfo); + fdi->free(nextinfo); } } @@ -740,33 +742,24 @@ BOOL __cdecl FDIIsCabinet( PFDICABINETINFO pfdici) { BOOL rv; + FDI_Int *fdi = get_fdi_ptr( hfdi ); TRACE("(hfdi == ^%p, hf == ^%ld, pfdici == ^%p)\n", hfdi, hf, pfdici); - if (!REALLY_IS_FDI(hfdi)) { - ERR("REALLY_IS_FDI failed on ^%p\n", hfdi); - SetLastError(ERROR_INVALID_HANDLE); - return FALSE; - } + if (!fdi) return FALSE; if (!hf) { ERR("(!hf)!\n"); - /* PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CABINET_NOT_FOUND; - PFDI_INT(hfdi)->perf->erfType = ERROR_INVALID_HANDLE; - PFDI_INT(hfdi)->perf->fError = TRUE; */ SetLastError(ERROR_INVALID_HANDLE); return FALSE; } if (!pfdici) { ERR("(!pfdici)!\n"); - /* PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NONE; - PFDI_INT(hfdi)->perf->erfType = ERROR_BAD_ARGUMENTS; - PFDI_INT(hfdi)->perf->fError = TRUE; */ SetLastError(ERROR_BAD_ARGUMENTS); return FALSE; } - rv = FDI_read_entries(hfdi, hf, pfdici, NULL); + rv = FDI_read_entries(fdi, hf, pfdici, NULL); if (rv) pfdici->hasnext = FALSE; /* yuck. duplicate apparent cabinet.dll bug */ @@ -805,11 +798,11 @@ static int QTMfdi_init(int window, int level, fdi_decomp_state *decomp_state) { /* if a previously allocated window is big enough, keep it */ if (window < 10 || window > 21) return DECR_DATAFORMAT; if (QTM(actual_size) < wndsize) { - if (QTM(window)) PFDI_FREE(CAB(hfdi), QTM(window)); + if (QTM(window)) CAB(fdi)->free(QTM(window)); QTM(window) = NULL; } if (!QTM(window)) { - if (!(QTM(window) = PFDI_ALLOC(CAB(hfdi), wndsize))) return DECR_NOMEMORY; + if (!(QTM(window) = CAB(fdi)->alloc(wndsize))) return DECR_NOMEMORY; QTM(actual_size) = wndsize; } QTM(window_size) = wndsize; @@ -869,11 +862,11 @@ static int LZXfdi_init(int window, fdi_decomp_state *decomp_state) { /* if a previously allocated window is big enough, keep it */ if (window < 15 || window > 21) return DECR_DATAFORMAT; if (LZX(actual_size) < wndsize) { - if (LZX(window)) PFDI_FREE(CAB(hfdi), LZX(window)); + if (LZX(window)) CAB(fdi)->free(LZX(window)); LZX(window) = NULL; } if (!LZX(window)) { - if (!(LZX(window) = PFDI_ALLOC(CAB(hfdi), wndsize))) return DECR_NOMEMORY; + if (!(LZX(window) = CAB(fdi)->alloc(wndsize))) return DECR_NOMEMORY; LZX(actual_size) = wndsize; } LZX(window_size) = wndsize; @@ -920,7 +913,7 @@ static int NONEfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state) /******************************************************** * Ziphuft_free (internal) */ -static void fdi_Ziphuft_free(HFDI hfdi, struct Ziphuft *t) +static void fdi_Ziphuft_free(FDI_Int *fdi, struct Ziphuft *t) { register struct Ziphuft *p, *q; @@ -929,7 +922,7 @@ static void fdi_Ziphuft_free(HFDI hfdi, struct Ziphuft *t) while (p != NULL) { q = (--p)->v.t; - PFDI_FREE(hfdi, p); + fdi->free(p); p = q; } } @@ -1055,10 +1048,10 @@ struct Ziphuft **t, cab_LONG *m, fdi_decomp_state *decomp_state) l[h] = j; /* set table size in stack */ /* allocate and link in new table */ - if (!(q = PFDI_ALLOC(CAB(hfdi), (z + 1)*sizeof(struct Ziphuft)))) + if (!(q = CAB(fdi)->alloc((z + 1)*sizeof(struct Ziphuft)))) { if(h) - fdi_Ziphuft_free(CAB(hfdi), ZIP(u)[0]); + fdi_Ziphuft_free(CAB(fdi), ZIP(u)[0]); return 3; /* not enough memory */ } *t = q + 1; /* link to list for Ziphuft_free() */ @@ -1277,15 +1270,15 @@ static cab_LONG fdi_Zipinflate_fixed(fdi_decomp_state *decomp_state) fixed_bd = 5; if((i = fdi_Ziphuft_build(l, 30, 0, Zipcpdist, Zipcpdext, &fixed_td, &fixed_bd, decomp_state)) > 1) { - fdi_Ziphuft_free(CAB(hfdi), fixed_tl); + fdi_Ziphuft_free(CAB(fdi), fixed_tl); return i; } /* decompress until an end-of-block code */ i = fdi_Zipinflate_codes(fixed_tl, fixed_td, fixed_bl, fixed_bd, decomp_state); - fdi_Ziphuft_free(CAB(hfdi), fixed_td); - fdi_Ziphuft_free(CAB(hfdi), fixed_tl); + fdi_Ziphuft_free(CAB(fdi), fixed_td); + fdi_Ziphuft_free(CAB(fdi), fixed_tl); return i; } @@ -1344,7 +1337,7 @@ static cab_LONG fdi_Zipinflate_dynamic(fdi_decomp_state *decomp_state) if((i = fdi_Ziphuft_build(ll, 19, 19, NULL, NULL, &tl, &bl, decomp_state)) != 0) { if(i == 1) - fdi_Ziphuft_free(CAB(hfdi), tl); + fdi_Ziphuft_free(CAB(fdi), tl); return i; /* incomplete code set */ } @@ -1395,7 +1388,7 @@ static cab_LONG fdi_Zipinflate_dynamic(fdi_decomp_state *decomp_state) } /* free decoding table for trees */ - fdi_Ziphuft_free(CAB(hfdi), tl); + fdi_Ziphuft_free(CAB(fdi), tl); /* restore the global bit buffer */ ZIP(bb) = b; @@ -1406,7 +1399,7 @@ static cab_LONG fdi_Zipinflate_dynamic(fdi_decomp_state *decomp_state) if((i = fdi_Ziphuft_build(ll, nl, 257, Zipcplens, Zipcplext, &tl, &bl, decomp_state)) != 0) { if(i == 1) - fdi_Ziphuft_free(CAB(hfdi), tl); + fdi_Ziphuft_free(CAB(fdi), tl); return i; /* incomplete code set */ } bd = ZIPDBITS; @@ -1417,8 +1410,8 @@ static cab_LONG fdi_Zipinflate_dynamic(fdi_decomp_state *decomp_state) return 1; /* free the decoding tables, return */ - fdi_Ziphuft_free(CAB(hfdi), tl); - fdi_Ziphuft_free(CAB(hfdi), td); + fdi_Ziphuft_free(CAB(fdi), tl); + fdi_Ziphuft_free(CAB(fdi), td); return 0; } @@ -2014,7 +2007,7 @@ static int fdi_decomp(const struct fdi_file *fi, int savemode, fdi_decomp_state /* if cando != 0 */ if (cando && savemode) - PFDI_WRITE(CAB(hfdi), CAB(filehf), CAB(outpos), cando); + CAB(fdi)->write(CAB(filehf), CAB(outpos), cando); CAB(outpos) += cando; CAB(outlen) -= cando; @@ -2026,10 +2019,10 @@ static int fdi_decomp(const struct fdi_file *fi, int savemode, fdi_decomp_state inlen = outlen = 0; while (outlen == 0) { /* read the block header, skip the reserved part */ - if (PFDI_READ(CAB(hfdi), cab->cabhf, buf, cfdata_SIZEOF) != cfdata_SIZEOF) + if (CAB(fdi)->read(cab->cabhf, buf, cfdata_SIZEOF) != cfdata_SIZEOF) return DECR_INPUT; - if (PFDI_SEEK(CAB(hfdi), cab->cabhf, cab->mii.block_resv, SEEK_CUR) == -1) + if (CAB(fdi)->seek(cab->cabhf, cab->mii.block_resv, SEEK_CUR) == -1) return DECR_INPUT; /* we shouldn't get blocks over CAB_INPUTMAX in size */ @@ -2037,7 +2030,7 @@ static int fdi_decomp(const struct fdi_file *fi, int savemode, fdi_decomp_state len = EndGetI16(buf+cfdata_CompressedSize); inlen += len; if (inlen > CAB_INPUTMAX) return DECR_INPUT; - if (PFDI_READ(CAB(hfdi), cab->cabhf, data, len) != len) + if (CAB(fdi)->read(cab->cabhf, data, len) != len) return DECR_INPUT; /* clear two bytes after read-in data */ @@ -2070,7 +2063,7 @@ static int fdi_decomp(const struct fdi_file *fi, int savemode, fdi_decomp_state if (!(cab->next)) { if (!cab->mii.hasnext) return DECR_INPUT; - if (!((cab->next = PFDI_ALLOC(CAB(hfdi), sizeof(fdi_decomp_state))))) + if (!((cab->next = CAB(fdi)->alloc(sizeof(fdi_decomp_state))))) return DECR_NOMEMORY; ZeroMemory(cab->next, sizeof(fdi_decomp_state)); @@ -2118,7 +2111,7 @@ static int fdi_decomp(const struct fdi_file *fi, int savemode, fdi_decomp_state TRACE("full cab path/file name: %s\n", debugstr_a(fullpath)); /* try to get a handle to the cabfile */ - cabhf = PFDI_OPEN(CAB(hfdi), fullpath, _O_RDONLY|_O_BINARY, _S_IREAD | _S_IWRITE); + cabhf = CAB(fdi)->open(fullpath, _O_RDONLY|_O_BINARY, _S_IREAD | _S_IWRITE); if (cabhf == -1) { /* no file. allow the user to try again */ fdin.fdie = FDIERROR_CABINET_NOT_FOUND; @@ -2134,9 +2127,9 @@ static int fdi_decomp(const struct fdi_file *fi, int savemode, fdi_decomp_state } /* check if it's really a cabfile. Note that this doesn't implement the bug */ - if (!FDI_read_entries(CAB(hfdi), cabhf, &fdici, &(cab->next->mii))) { + if (!FDI_read_entries(CAB(fdi), cabhf, &fdici, &(cab->next->mii))) { WARN("FDIIsCabinet failed.\n"); - PFDI_CLOSE(CAB(hfdi), cabhf); + CAB(fdi)->close(cabhf); fdin.fdie = FDIERROR_NOT_A_CABINET; if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT; continue; @@ -2144,7 +2137,7 @@ static int fdi_decomp(const struct fdi_file *fi, int savemode, fdi_decomp_state if ((fdici.setID != cab->setID) || (fdici.iCabinet != (cab->iCabinet + 1))) { WARN("Wrong Cabinet.\n"); - PFDI_CLOSE(CAB(hfdi), cabhf); + CAB(fdi)->close(cabhf); fdin.fdie = FDIERROR_WRONG_CABINET; if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT; continue; @@ -2167,7 +2160,7 @@ static int fdi_decomp(const struct fdi_file *fi, int savemode, fdi_decomp_state cab->next->setID = fdici.setID; cab->next->iCabinet = fdici.iCabinet; - cab->next->hfdi = CAB(hfdi); + cab->next->fdi = CAB(fdi); cab->next->filehf = CAB(filehf); cab->next->cabhf = cabhf; cab->next->decompress = CAB(decompress); /* crude, but unused anyhow */ @@ -2176,13 +2169,13 @@ static int fdi_decomp(const struct fdi_file *fi, int savemode, fdi_decomp_state /* read folders */ for (i = 0; i < fdici.cFolders; i++) { - if (PFDI_READ(CAB(hfdi), cab->cabhf, buf2, cffold_SIZEOF) != cffold_SIZEOF) + if (CAB(fdi)->read(cab->cabhf, buf2, cffold_SIZEOF) != cffold_SIZEOF) return DECR_INPUT; if (cab->mii.folder_resv > 0) - PFDI_SEEK(CAB(hfdi), cab->cabhf, cab->mii.folder_resv, SEEK_CUR); + CAB(fdi)->seek(cab->cabhf, cab->mii.folder_resv, SEEK_CUR); - fol = PFDI_ALLOC(CAB(hfdi), sizeof(struct fdi_folder)); + fol = CAB(fdi)->alloc(sizeof(struct fdi_folder)); if (!fol) { ERR("out of memory!\n"); return DECR_NOMEMORY; @@ -2201,10 +2194,10 @@ static int fdi_decomp(const struct fdi_file *fi, int savemode, fdi_decomp_state /* read files */ for (i = 0; i < fdici.cFiles; i++) { - if (PFDI_READ(CAB(hfdi), cab->cabhf, buf2, cffile_SIZEOF) != cffile_SIZEOF) + if (CAB(fdi)->read(cab->cabhf, buf2, cffile_SIZEOF) != cffile_SIZEOF) return DECR_INPUT; - file = PFDI_ALLOC(CAB(hfdi), sizeof(struct fdi_file)); + file = CAB(fdi)->alloc(sizeof(struct fdi_file)); if (!file) { ERR("out of memory!\n"); return DECR_NOMEMORY; @@ -2218,7 +2211,7 @@ static int fdi_decomp(const struct fdi_file *fi, int savemode, fdi_decomp_state file->time = EndGetI16(buf2+cffile_Time); file->date = EndGetI16(buf2+cffile_Date); file->attribs = EndGetI16(buf2+cffile_Attribs); - file->filename = FDI_read_string(CAB(hfdi), cab->cabhf, fdici.cbCabinet); + file->filename = FDI_read_string(CAB(fdi), cab->cabhf, fdici.cbCabinet); if (!file->filename) return DECR_INPUT; @@ -2238,7 +2231,7 @@ static int fdi_decomp(const struct fdi_file *fi, int savemode, fdi_decomp_state /* check to ensure a real match */ if (lstrcmpiA(fi->filename, file->filename) == 0) { success = TRUE; - if (PFDI_SEEK(CAB(hfdi), cab->cabhf, cab->firstfol->offset, SEEK_SET) == -1) + if (CAB(fdi)->seek(cab->cabhf, cab->firstfol->offset, SEEK_SET) == -1) return DECR_INPUT; break; } @@ -2260,54 +2253,53 @@ static int fdi_decomp(const struct fdi_file *fi, int savemode, fdi_decomp_state return DECR_OK; } -static void free_decompression_temps(HFDI hfdi, const struct fdi_folder *fol, +static void free_decompression_temps(FDI_Int *fdi, const struct fdi_folder *fol, fdi_decomp_state *decomp_state) { switch (fol->comp_type & cffoldCOMPTYPE_MASK) { case cffoldCOMPTYPE_LZX: if (LZX(window)) { - PFDI_FREE(hfdi, LZX(window)); + fdi->free(LZX(window)); LZX(window) = NULL; } break; case cffoldCOMPTYPE_QUANTUM: if (QTM(window)) { - PFDI_FREE(hfdi, QTM(window)); + fdi->free(QTM(window)); QTM(window) = NULL; } break; } } -static void free_decompression_mem(HFDI hfdi, - fdi_decomp_state *decomp_state, struct fdi_file *file) +static void free_decompression_mem(FDI_Int *fdi, fdi_decomp_state *decomp_state) { struct fdi_folder *fol; while (decomp_state) { fdi_decomp_state *prev_fds; - PFDI_CLOSE(hfdi, CAB(cabhf)); + fdi->close(CAB(cabhf)); /* free the storage remembered by mii */ - if (CAB(mii).nextname) PFDI_FREE(hfdi, CAB(mii).nextname); - if (CAB(mii).nextinfo) PFDI_FREE(hfdi, CAB(mii).nextinfo); - if (CAB(mii).prevname) PFDI_FREE(hfdi, CAB(mii).prevname); - if (CAB(mii).previnfo) PFDI_FREE(hfdi, CAB(mii).previnfo); + if (CAB(mii).nextname) fdi->free(CAB(mii).nextname); + if (CAB(mii).nextinfo) fdi->free(CAB(mii).nextinfo); + if (CAB(mii).prevname) fdi->free(CAB(mii).prevname); + if (CAB(mii).previnfo) fdi->free(CAB(mii).previnfo); while (CAB(firstfol)) { fol = CAB(firstfol); CAB(firstfol) = CAB(firstfol)->next; - PFDI_FREE(hfdi, fol); + fdi->free(fol); } while (CAB(firstfile)) { - file = CAB(firstfile); - if (file->filename) PFDI_FREE(hfdi, file->filename); + struct fdi_file *file = CAB(firstfile); + if (file->filename) fdi->free(file->filename); CAB(firstfile) = CAB(firstfile)->next; - PFDI_FREE(hfdi, file); + fdi->free(file); } prev_fds = decomp_state; decomp_state = CAB(next); - PFDI_FREE(hfdi, prev_fds); + fdi->free(prev_fds); } } @@ -2496,17 +2488,15 @@ BOOL __cdecl FDICopy( struct fdi_folder *fol = NULL, *linkfol = NULL; struct fdi_file *file = NULL, *linkfile = NULL; fdi_decomp_state *decomp_state; + FDI_Int *fdi = get_fdi_ptr( hfdi ); TRACE("(hfdi == ^%p, pszCabinet == ^%p, pszCabPath == ^%p, flags == %0d, " "pfnfdin == ^%p, pfnfdid == ^%p, pvUser == ^%p)\n", hfdi, pszCabinet, pszCabPath, flags, pfnfdin, pfnfdid, pvUser); - if (!REALLY_IS_FDI(hfdi)) { - SetLastError(ERROR_INVALID_HANDLE); - return FALSE; - } + if (!fdi) return FALSE; - if (!(decomp_state = PFDI_ALLOC(hfdi, sizeof(fdi_decomp_state)))) + if (!(decomp_state = fdi->alloc(sizeof(fdi_decomp_state)))) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; @@ -2519,11 +2509,8 @@ BOOL __cdecl FDICopy( /* slight overestimation here to save CPU cycles in the developer's brain */ if ((pathlen + filenamelen + 3) > MAX_PATH) { ERR("MAX_PATH exceeded.\n"); - PFDI_FREE(hfdi, decomp_state); - PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CABINET_NOT_FOUND; - PFDI_INT(hfdi)->perf->erfType = ERROR_FILE_NOT_FOUND; - PFDI_INT(hfdi)->perf->fError = TRUE; - SetLastError(ERROR_FILE_NOT_FOUND); + fdi->free(decomp_state); + set_error( fdi, FDIERROR_CABINET_NOT_FOUND, ERROR_FILE_NOT_FOUND ); return FALSE; } @@ -2531,7 +2518,6 @@ BOOL __cdecl FDICopy( idx = 0; if (pathlen) { for (i = 0; i < pathlen; i++) fullpath[idx++] = pszCabPath[i]; - if (fullpath[idx - 1] != '\\') fullpath[idx++] = '\\'; } if (filenamelen) for (i = 0; i < filenamelen; i++) fullpath[idx++] = pszCabinet[i]; fullpath[idx] = '\0'; @@ -2539,30 +2525,19 @@ BOOL __cdecl FDICopy( TRACE("full cab path/file name: %s\n", debugstr_a(fullpath)); /* get a handle to the cabfile */ - cabhf = PFDI_OPEN(hfdi, fullpath, _O_RDONLY|_O_BINARY, _S_IREAD | _S_IWRITE); + cabhf = fdi->open(fullpath, _O_RDONLY|_O_BINARY, _S_IREAD | _S_IWRITE); if (cabhf == -1) { - PFDI_FREE(hfdi, decomp_state); - PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CABINET_NOT_FOUND; - PFDI_INT(hfdi)->perf->fError = TRUE; - SetLastError(ERROR_FILE_NOT_FOUND); - return FALSE; - } - - if (cabhf == 0) { - ERR("PFDI_OPEN returned zero for %s.\n", fullpath); - PFDI_FREE(hfdi, decomp_state); - PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CABINET_NOT_FOUND; - PFDI_INT(hfdi)->perf->erfType = ERROR_FILE_NOT_FOUND; - PFDI_INT(hfdi)->perf->fError = TRUE; + fdi->free(decomp_state); + set_error( fdi, FDIERROR_CABINET_NOT_FOUND, 0 ); SetLastError(ERROR_FILE_NOT_FOUND); return FALSE; } /* check if it's really a cabfile. Note that this doesn't implement the bug */ - if (!FDI_read_entries(hfdi, cabhf, &fdici, &(CAB(mii)))) { - ERR("FDIIsCabinet failed.\n"); - PFDI_FREE(hfdi, decomp_state); - PFDI_CLOSE(hfdi, cabhf); + if (!FDI_read_entries(fdi, cabhf, &fdici, &(CAB(mii)))) { + ERR("FDIIsCabinet failed: %u.\n", fdi->perf->erfOper); + fdi->free(decomp_state); + fdi->close(cabhf); return FALSE; } @@ -2576,9 +2551,7 @@ BOOL __cdecl FDICopy( fdin.psz3 = pszCabPath; if (((*pfnfdin)(fdintCABINET_INFO, &fdin))) { - PFDI_INT(hfdi)->perf->erfOper = FDIERROR_USER_ABORT; - PFDI_INT(hfdi)->perf->erfType = 0; - PFDI_INT(hfdi)->perf->fError = TRUE; + set_error( fdi, FDIERROR_USER_ABORT, 0 ); goto bail_and_fail; } @@ -2588,23 +2561,18 @@ BOOL __cdecl FDICopy( /* read folders */ for (i = 0; i < fdici.cFolders; i++) { - if (PFDI_READ(hfdi, cabhf, buf, cffold_SIZEOF) != cffold_SIZEOF) { - PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET; - PFDI_INT(hfdi)->perf->erfType = 0; - PFDI_INT(hfdi)->perf->fError = TRUE; + if (fdi->read(cabhf, buf, cffold_SIZEOF) != cffold_SIZEOF) { + set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 ); goto bail_and_fail; } if (CAB(mii).folder_resv > 0) - PFDI_SEEK(hfdi, cabhf, CAB(mii).folder_resv, SEEK_CUR); + fdi->seek(cabhf, CAB(mii).folder_resv, SEEK_CUR); - fol = PFDI_ALLOC(hfdi, sizeof(struct fdi_folder)); + fol = fdi->alloc(sizeof(struct fdi_folder)); if (!fol) { ERR("out of memory!\n"); - PFDI_INT(hfdi)->perf->erfOper = FDIERROR_ALLOC_FAIL; - PFDI_INT(hfdi)->perf->erfType = ERROR_NOT_ENOUGH_MEMORY; - PFDI_INT(hfdi)->perf->fError = TRUE; - SetLastError(ERROR_NOT_ENOUGH_MEMORY); + set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY ); goto bail_and_fail; } ZeroMemory(fol, sizeof(struct fdi_folder)); @@ -2621,20 +2589,15 @@ BOOL __cdecl FDICopy( /* read files */ for (i = 0; i < fdici.cFiles; i++) { - if (PFDI_READ(hfdi, cabhf, buf, cffile_SIZEOF) != cffile_SIZEOF) { - PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET; - PFDI_INT(hfdi)->perf->erfType = 0; - PFDI_INT(hfdi)->perf->fError = TRUE; + if (fdi->read(cabhf, buf, cffile_SIZEOF) != cffile_SIZEOF) { + set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 ); goto bail_and_fail; } - file = PFDI_ALLOC(hfdi, sizeof(struct fdi_file)); + file = fdi->alloc(sizeof(struct fdi_file)); if (!file) { ERR("out of memory!\n"); - PFDI_INT(hfdi)->perf->erfOper = FDIERROR_ALLOC_FAIL; - PFDI_INT(hfdi)->perf->erfType = ERROR_NOT_ENOUGH_MEMORY; - PFDI_INT(hfdi)->perf->fError = TRUE; - SetLastError(ERROR_NOT_ENOUGH_MEMORY); + set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY ); goto bail_and_fail; } ZeroMemory(file, sizeof(struct fdi_file)); @@ -2646,12 +2609,10 @@ BOOL __cdecl FDICopy( file->time = EndGetI16(buf+cffile_Time); file->date = EndGetI16(buf+cffile_Date); file->attribs = EndGetI16(buf+cffile_Attribs); - file->filename = FDI_read_string(hfdi, cabhf, fdici.cbCabinet); + file->filename = FDI_read_string(fdi, cabhf, fdici.cbCabinet); if (!file->filename) { - PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET; - PFDI_INT(hfdi)->perf->erfType = 0; - PFDI_INT(hfdi)->perf->fError = TRUE; + set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 ); goto bail_and_fail; } @@ -2717,9 +2678,7 @@ BOOL __cdecl FDICopy( fdin.psz3 = (CAB(mii).previnfo) ? CAB(mii).previnfo : &emptystring; if (((*pfnfdin)(fdintPARTIAL_FILE, &fdin))) { - PFDI_INT(hfdi)->perf->erfOper = FDIERROR_USER_ABORT; - PFDI_INT(hfdi)->perf->erfType = 0; - PFDI_INT(hfdi)->perf->fError = TRUE; + set_error( fdi, FDIERROR_USER_ABORT, 0 ); goto bail_and_fail; } /* I don't think we are supposed to decompress partial files. This prevents it. */ @@ -2736,9 +2695,7 @@ BOOL __cdecl FDICopy( fdin.time = file->time; fdin.attribs = file->attribs; if ((filehf = ((*pfnfdin)(fdintCOPY_FILE, &fdin))) == -1) { - PFDI_INT(hfdi)->perf->erfOper = FDIERROR_USER_ABORT; - PFDI_INT(hfdi)->perf->erfType = 0; - PFDI_INT(hfdi)->perf->fError = TRUE; + set_error( fdi, FDIERROR_USER_ABORT, 0 ); filehf = 0; goto bail_and_fail; } @@ -2768,7 +2725,7 @@ BOOL __cdecl FDICopy( TRACE("Extracting file %s as requested by callee.\n", debugstr_a(file->filename)); /* set up decomp_state */ - CAB(hfdi) = hfdi; + CAB(fdi) = fdi; CAB(filehf) = filehf; /* Was there a change of folder? Compression type? Did we somehow go backwards? */ @@ -2776,28 +2733,28 @@ BOOL __cdecl FDICopy( TRACE("Resetting folder for file %s.\n", debugstr_a(file->filename)); - /* free stuff for the old decompresser */ + /* free stuff for the old decompressor */ switch (ct2) { case cffoldCOMPTYPE_LZX: if (LZX(window)) { - PFDI_FREE(hfdi, LZX(window)); + fdi->free(LZX(window)); LZX(window) = NULL; } break; case cffoldCOMPTYPE_QUANTUM: if (QTM(window)) { - PFDI_FREE(hfdi, QTM(window)); + fdi->free(QTM(window)); QTM(window) = NULL; } break; } CAB(decomp_cab) = NULL; - PFDI_SEEK(CAB(hfdi), CAB(cabhf), fol->offset, SEEK_SET); + CAB(fdi)->seek(CAB(cabhf), fol->offset, SEEK_SET); CAB(offset) = 0; CAB(outlen) = 0; - /* initialize the new decompresser */ + /* initialize the new decompressor */ switch (ct1) { case cffoldCOMPTYPE_NONE: CAB(decompress) = NONEfdi_decomp; @@ -2824,15 +2781,10 @@ BOOL __cdecl FDICopy( case DECR_OK: break; case DECR_NOMEMORY: - PFDI_INT(hfdi)->perf->erfOper = FDIERROR_ALLOC_FAIL; - PFDI_INT(hfdi)->perf->erfType = ERROR_NOT_ENOUGH_MEMORY; - PFDI_INT(hfdi)->perf->fError = TRUE; - SetLastError(ERROR_NOT_ENOUGH_MEMORY); + set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY ); goto bail_and_fail; default: - PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET; - PFDI_INT(hfdi)->perf->erfOper = 0; - PFDI_INT(hfdi)->perf->fError = TRUE; + set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 ); goto bail_and_fail; } @@ -2842,20 +2794,13 @@ BOOL __cdecl FDICopy( case DECR_OK: break; case DECR_USERABORT: - PFDI_INT(hfdi)->perf->erfOper = FDIERROR_USER_ABORT; - PFDI_INT(hfdi)->perf->erfType = 0; - PFDI_INT(hfdi)->perf->fError = TRUE; + set_error( fdi, FDIERROR_USER_ABORT, 0 ); goto bail_and_fail; case DECR_NOMEMORY: - PFDI_INT(hfdi)->perf->erfOper = FDIERROR_ALLOC_FAIL; - PFDI_INT(hfdi)->perf->erfType = ERROR_NOT_ENOUGH_MEMORY; - PFDI_INT(hfdi)->perf->fError = TRUE; - SetLastError(ERROR_NOT_ENOUGH_MEMORY); + set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY ); goto bail_and_fail; default: - PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET; - PFDI_INT(hfdi)->perf->erfOper = 0; - PFDI_INT(hfdi)->perf->fError = TRUE; + set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 ); goto bail_and_fail; } CAB(offset) = file->offset; @@ -2881,37 +2826,30 @@ BOOL __cdecl FDICopy( case DECR_OK: break; case DECR_USERABORT: - PFDI_INT(hfdi)->perf->erfOper = FDIERROR_USER_ABORT; - PFDI_INT(hfdi)->perf->erfType = 0; - PFDI_INT(hfdi)->perf->fError = TRUE; + set_error( fdi, FDIERROR_USER_ABORT, 0 ); goto bail_and_fail; case DECR_NOMEMORY: - PFDI_INT(hfdi)->perf->erfOper = FDIERROR_ALLOC_FAIL; - PFDI_INT(hfdi)->perf->erfType = ERROR_NOT_ENOUGH_MEMORY; - PFDI_INT(hfdi)->perf->fError = TRUE; - SetLastError(ERROR_NOT_ENOUGH_MEMORY); + set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY ); goto bail_and_fail; default: - PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET; - PFDI_INT(hfdi)->perf->erfOper = 0; - PFDI_INT(hfdi)->perf->fError = TRUE; + set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 ); goto bail_and_fail; } } } - free_decompression_temps(hfdi, fol, decomp_state); - free_decompression_mem(hfdi, decomp_state, file); + if (fol) free_decompression_temps(fdi, fol, decomp_state); + free_decompression_mem(fdi, decomp_state); return TRUE; bail_and_fail: /* here we free ram before error returns */ - if (fol) free_decompression_temps(hfdi, fol, decomp_state); + if (fol) free_decompression_temps(fdi, fol, decomp_state); - if (filehf) PFDI_CLOSE(hfdi, filehf); + if (filehf) fdi->close(filehf); - free_decompression_mem(hfdi, decomp_state, file); + free_decompression_mem(fdi, decomp_state); return FALSE; } @@ -2931,15 +2869,13 @@ BOOL __cdecl FDICopy( */ BOOL __cdecl FDIDestroy(HFDI hfdi) { - TRACE("(hfdi == ^%p)\n", hfdi); - if (REALLY_IS_FDI(hfdi)) { - PFDI_INT(hfdi)->FDI_Intmagic = 0; /* paranoia */ - PFDI_FREE(hfdi, hfdi); /* confusing, but correct */ + FDI_Int *fdi = get_fdi_ptr( hfdi ); + + TRACE("(hfdi == ^%p)\n", hfdi); + if (!fdi) return FALSE; + fdi->magic = 0; /* paranoia */ + fdi->free(fdi); return TRUE; - } else { - SetLastError(ERROR_INVALID_HANDLE); - return FALSE; - } } /*********************************************************************** @@ -2966,13 +2902,12 @@ BOOL __cdecl FDITruncateCabinet( char *pszCabinetName, USHORT iFolderToDelete) { + FDI_Int *fdi = get_fdi_ptr( hfdi ); + FIXME("(hfdi == ^%p, pszCabinetName == %s, iFolderToDelete == %hu): stub\n", hfdi, debugstr_a(pszCabinetName), iFolderToDelete); - if (!REALLY_IS_FDI(hfdi)) { - SetLastError(ERROR_INVALID_HANDLE); - return FALSE; - } + if (!fdi) return FALSE; SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return FALSE; diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index d1bd7c6a2a2..cfc1109f016 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -45,7 +45,7 @@ reactos/dll/win32/atl # Autosync reactos/dll/win32/avifil32 # Autosync reactos/dll/win32/bcrypt # Synced to Wine-1.3.37 reactos/dll/win32/browseui # Out of sync -reactos/dll/win32/cabinet # Autosync +reactos/dll/win32/cabinet # Synced to Wine-1.3.37 reactos/dll/win32/clusapi # Autosync reactos/dll/win32/comcat # Autosync reactos/dll/win32/comctl32 # Synced to Wine 1.3.14