cabinet: Add support for MSZIP compression.

oldstable
Alexandre Julliard 2011-02-18 00:15:44 +01:00
parent 527c8263a1
commit e1a0ef7ef8
3 changed files with 53 additions and 7 deletions

View File

@ -1,5 +1,6 @@
MODULE = cabinet.dll
IMPORTLIB = cabinet
EXTRALIBS = @ZLIB@
C_SRCS = \
cabinet_main.c \

View File

@ -24,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
*/
@ -40,6 +38,9 @@ There is still some work to be done:
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#ifdef HAVE_ZLIB
# include <zlib.h>
#endif
#include "windef.h"
#include "winbase.h"
@ -166,9 +167,9 @@ typedef struct FCI_Int
void *pv;
char szPrevCab[CB_MAX_CABINET_NAME]; /* previous cabinet name */
char szPrevDisk[CB_MAX_DISK_NAME]; /* disk name of previous cabinet */
char* data_in; /* uncompressed data blocks */
unsigned char *data_in; /* uncompressed data blocks */
cab_UWORD cdata_in;
char* data_out; /* compressed data blocks */
unsigned char *data_out; /* compressed data blocks */
ULONG cCompressedBytesInFolder;
cab_UWORD cFolders;
cab_UWORD cFiles;
@ -945,6 +946,46 @@ static cab_UWORD compress_NONE( FCI_Int *fci )
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;
return 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 = 2 * CB_MAX_CHUNK - 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)
@ -1441,6 +1482,12 @@ BOOL __cdecl FCIAddFile(
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 */

View File

@ -581,11 +581,9 @@ static void test_FDIIsCabinet(void)
ok(cabinfo.cFiles == 4, "Expected 4, got %d\n", cabinfo.cFiles);
ok(cabinfo.cFolders == 1, "Expected 1, got %d\n", cabinfo.cFolders);
ok(cabinfo.setID == 0xbeef, "Expected 0xbeef, got %d\n", cabinfo.setID);
ok(cabinfo.cbCabinet == 182, "Expected 182, got %d\n", cabinfo.cbCabinet);
todo_wine
{
ok(cabinfo.cbCabinet == 182, "Expected 182, got %d\n", cabinfo.cbCabinet);
ok(cabinfo.iCabinet == 0, "Expected 0, got %d\n", cabinfo.iCabinet);
}
fdi_close(fd);
FDIDestroy(hfdi);