Commit e1a0ef7e authored by Alexandre Julliard's avatar Alexandre Julliard

cabinet: Add support for MSZIP compression.

parent 527c8263
MODULE = cabinet.dll MODULE = cabinet.dll
IMPORTLIB = cabinet IMPORTLIB = cabinet
EXTRALIBS = @ZLIB@
C_SRCS = \ C_SRCS = \
cabinet_main.c \ cabinet_main.c \
......
...@@ -24,11 +24,9 @@ ...@@ -24,11 +24,9 @@
There is still some work to be done: There is still some work to be done:
- no real compression yet
- unknown behaviour if files>=2GB or cabinet >=4GB - unknown behaviour if files>=2GB or cabinet >=4GB
- check if the maximum size for a cabinet is too small to store any data - 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 - 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: ...@@ -40,6 +38,9 @@ There is still some work to be done:
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#ifdef HAVE_ZLIB
# include <zlib.h>
#endif
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
...@@ -166,9 +167,9 @@ typedef struct FCI_Int ...@@ -166,9 +167,9 @@ typedef struct FCI_Int
void *pv; void *pv;
char szPrevCab[CB_MAX_CABINET_NAME]; /* previous cabinet name */ char szPrevCab[CB_MAX_CABINET_NAME]; /* previous cabinet name */
char szPrevDisk[CB_MAX_DISK_NAME]; /* disk name of previous cabinet */ char szPrevDisk[CB_MAX_DISK_NAME]; /* disk name of previous cabinet */
char* data_in; /* uncompressed data blocks */ unsigned char *data_in; /* uncompressed data blocks */
cab_UWORD cdata_in; cab_UWORD cdata_in;
char* data_out; /* compressed data blocks */ unsigned char *data_out; /* compressed data blocks */
ULONG cCompressedBytesInFolder; ULONG cCompressedBytesInFolder;
cab_UWORD cFolders; cab_UWORD cFolders;
cab_UWORD cFiles; cab_UWORD cFiles;
...@@ -945,6 +946,46 @@ static cab_UWORD compress_NONE( FCI_Int *fci ) ...@@ -945,6 +946,46 @@ static cab_UWORD compress_NONE( FCI_Int *fci )
return 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;
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) * FCICreate (CABINET.10)
...@@ -1441,6 +1482,12 @@ BOOL __cdecl FCIAddFile( ...@@ -1441,6 +1482,12 @@ BOOL __cdecl FCIAddFile(
if (!FCIFlushFolder( hfci, pfnfcignc, pfnfcis )) return FALSE; if (!FCIFlushFolder( hfci, pfnfcignc, pfnfcis )) return FALSE;
switch (typeCompress) switch (typeCompress)
{ {
case tcompTYPE_MSZIP:
#ifdef HAVE_ZLIB
p_fci_internal->compression = tcompTYPE_MSZIP;
p_fci_internal->compress = compress_MSZIP;
break;
#endif
default: default:
FIXME( "compression %x not supported, defaulting to none\n", typeCompress ); FIXME( "compression %x not supported, defaulting to none\n", typeCompress );
/* fall through */ /* fall through */
......
...@@ -581,11 +581,9 @@ static void test_FDIIsCabinet(void) ...@@ -581,11 +581,9 @@ static void test_FDIIsCabinet(void)
ok(cabinfo.cFiles == 4, "Expected 4, got %d\n", cabinfo.cFiles); ok(cabinfo.cFiles == 4, "Expected 4, got %d\n", cabinfo.cFiles);
ok(cabinfo.cFolders == 1, "Expected 1, got %d\n", cabinfo.cFolders); ok(cabinfo.cFolders == 1, "Expected 1, got %d\n", cabinfo.cFolders);
ok(cabinfo.setID == 0xbeef, "Expected 0xbeef, got %d\n", cabinfo.setID); ok(cabinfo.setID == 0xbeef, "Expected 0xbeef, got %d\n", cabinfo.setID);
ok(cabinfo.cbCabinet == 182, "Expected 182, got %d\n", cabinfo.cbCabinet);
todo_wine todo_wine
{
ok(cabinfo.cbCabinet == 182, "Expected 182, got %d\n", cabinfo.cbCabinet);
ok(cabinfo.iCabinet == 0, "Expected 0, got %d\n", cabinfo.iCabinet); ok(cabinfo.iCabinet == 0, "Expected 0, got %d\n", cabinfo.iCabinet);
}
fdi_close(fd); fdi_close(fd);
FDIDestroy(hfdi); FDIDestroy(hfdi);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment