Alexandre Julliard : cabinet: Add support for MSZIP compression.

Alexandre Julliard julliard at winehq.org
Fri Feb 18 10:50:16 CST 2011


Module: wine
Branch: master
Commit: e1a0ef7ef8922a029a0d26c5bb9b37fe131c8f60
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=e1a0ef7ef8922a029a0d26c5bb9b37fe131c8f60

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri Feb 18 00:15:44 2011 +0100

cabinet: Add support for MSZIP compression.

---

 dlls/cabinet/Makefile.in |    1 +
 dlls/cabinet/fci.c       |   55 ++++++++++++++++++++++++++++++++++++++++++---
 dlls/cabinet/tests/fdi.c |    4 +--
 3 files changed, 53 insertions(+), 7 deletions(-)

diff --git a/dlls/cabinet/Makefile.in b/dlls/cabinet/Makefile.in
index 7a1ad9d..2876936 100644
--- a/dlls/cabinet/Makefile.in
+++ b/dlls/cabinet/Makefile.in
@@ -1,5 +1,6 @@
 MODULE    = cabinet.dll
 IMPORTLIB = cabinet
+EXTRALIBS = @ZLIB@
 
 C_SRCS = \
 	cabinet_main.c \
diff --git a/dlls/cabinet/fci.c b/dlls/cabinet/fci.c
index f1d6a80..55a024a 100644
--- a/dlls/cabinet/fci.c
+++ b/dlls/cabinet/fci.c
@@ -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 */
diff --git a/dlls/cabinet/tests/fdi.c b/dlls/cabinet/tests/fdi.c
index 19f9e29..b3f70bf 100644
--- a/dlls/cabinet/tests/fdi.c
+++ b/dlls/cabinet/tests/fdi.c
@@ -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);




More information about the wine-cvs mailing list