2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS cabinet manager
4 * FILE: apps/cabman/mszip.cpp
5 * PURPOSE: CAB codec for MSZIP compressed data
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * NOTES: The ZLIB does the real work. Get the full version
8 * from http://www.cdrom.com/pub/infozip/zlib/
10 * CSH 21/03-2001 Created
17 /* Memory functions */
19 voidpf
MSZipAlloc(voidpf opaque
, uInt items
, uInt size
)
21 DPRINT(DEBUG_MEMORY
, ("items = (%d) size = (%d)\n", items
, size
));
22 return HeapAlloc(GetProcessHeap(), 0, items
* size
);
25 void MSZipFree (voidpf opaque
, voidpf address
)
27 DPRINT(DEBUG_MEMORY
, ("\n"));
28 HeapFree(GetProcessHeap(), 0, address
);
34 CMSZipCodec::CMSZipCodec()
36 * FUNCTION: Default constructor
39 ZStream
.zalloc
= MSZipAlloc
;
40 ZStream
.zfree
= MSZipFree
;
41 ZStream
.opaque
= (voidpf
)0;
45 CMSZipCodec::~CMSZipCodec()
47 * FUNCTION: Default destructor
53 ULONG
CMSZipCodec::Compress(PVOID OutputBuffer
,
58 * FUNCTION: Compresses data in a buffer
60 * OutputBuffer = Pointer to buffer to place compressed data
61 * InputBuffer = Pointer to buffer with data to be compressed
62 * InputLength = Length of input buffer
63 * OutputLength = Address of buffer to place size of compressed data
68 DPRINT(MAX_TRACE
, ("InputLength (%d).\n", InputLength
));
70 Magic
= (PUSHORT
)OutputBuffer
;
73 ZStream
.next_in
= (PUCHAR
)InputBuffer
;
74 ZStream
.avail_in
= InputLength
;
75 ZStream
.next_out
= (PUCHAR
)((ULONG
)OutputBuffer
+ 2);
76 ZStream
.avail_out
= CAB_BLOCKSIZE
+ 12;
78 /* WindowBits is passed < 0 to tell that there is no zlib header */
79 Status
= deflateInit2(&ZStream
,
86 DPRINT(MIN_TRACE
, ("deflateInit() returned (%d).\n", Status
));
90 Status
= deflate(&ZStream
, Z_FINISH
);
91 if ((Status
!= Z_OK
) && (Status
!= Z_STREAM_END
)) {
92 DPRINT(MIN_TRACE
, ("deflate() returned (%d) (%s).\n", Status
, ZStream
.msg
));
93 if (Status
== Z_MEM_ERROR
)
98 *OutputLength
= ZStream
.total_out
+ 2;
100 Status
= deflateEnd(&ZStream
);
101 if (Status
!= Z_OK
) {
102 DPRINT(MIN_TRACE
, ("deflateEnd() returned (%d).\n", Status
));
110 ULONG
CMSZipCodec::Uncompress(PVOID OutputBuffer
,
115 * FUNCTION: Uncompresses data in a buffer
117 * OutputBuffer = Pointer to buffer to place uncompressed data
118 * InputBuffer = Pointer to buffer with data to be uncompressed
119 * InputLength = Length of input buffer
120 * OutputLength = Address of buffer to place size of uncompressed data
125 DPRINT(MAX_TRACE
, ("InputLength (%d).\n", InputLength
));
127 Magic
= *((PUSHORT
)InputBuffer
);
129 if (Magic
!= MSZIP_MAGIC
) {
130 DPRINT(MID_TRACE
, ("Bad MSZIP block header magic (0x%X)\n", Magic
));
134 ZStream
.next_in
= (PUCHAR
)((ULONG
)InputBuffer
+ 2);
135 ZStream
.avail_in
= InputLength
- 2;
136 ZStream
.next_out
= (PUCHAR
)OutputBuffer
;
137 ZStream
.avail_out
= CAB_BLOCKSIZE
+ 12;
139 /* WindowBits is passed < 0 to tell that there is no zlib header.
140 * Note that in this case inflate *requires* an extra "dummy" byte
141 * after the compressed stream in order to complete decompression and
142 * return Z_STREAM_END.
144 Status
= inflateInit2(&ZStream
, -MAX_WBITS
);
145 if (Status
!= Z_OK
) {
146 DPRINT(MIN_TRACE
, ("inflateInit2() returned (%d).\n", Status
));
150 while ((ZStream
.total_out
< CAB_BLOCKSIZE
+ 12) &&
151 (ZStream
.total_in
< InputLength
- 2)) {
152 Status
= inflate(&ZStream
, Z_NO_FLUSH
);
153 if (Status
== Z_STREAM_END
) break;
154 if (Status
!= Z_OK
) {
155 DPRINT(MIN_TRACE
, ("inflate() returned (%d) (%s).\n", Status
, ZStream
.msg
));
156 if (Status
== Z_MEM_ERROR
)
162 *OutputLength
= ZStream
.total_out
;
164 Status
= inflateEnd(&ZStream
);
165 if (Status
!= Z_OK
) {
166 DPRINT(MIN_TRACE
, ("inflateEnd() returned (%d).\n", Status
));