ddraw: Don't interpret end padding as dwCaps2 for x64.
[wine.git] / dlls / cabinet / fdi.c
bloba004c1da2fde567431ee447baf5e86911533f4ec
1 /*
2 * File Decompression Interface
4 * Copyright 2000-2002 Stuart Caie
5 * Copyright 2002 Patrik Stridvall
6 * Copyright 2003 Greg Turner
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * This is a largely redundant reimplementation of the stuff in cabextract.c. It
24 * would be theoretically preferable to have only one, shared implementation, however
25 * there are semantic differences which may discourage efforts to unify the two. It
26 * should be possible, if awkward, to go back and reimplement cabextract.c using FDI.
27 * But this approach would be quite a bit less performant. Probably a better way
28 * would be to create a "library" of routines in cabextract.c which do the actual
29 * decompression, and have both fdi.c and cabextract share those routines. The rest
30 * of the code is not sufficiently similar to merit a shared implementation.
32 * The worst thing about this API is the bug. "The bug" is this: when you extract a
33 * cabinet, it /always/ informs you (via the hasnext field of PFDICABINETINFO), that
34 * there is no subsequent cabinet, even if there is one. wine faithfully reproduces
35 * this behavior.
37 * TODO:
39 * Wine does not implement the AFAIK undocumented "enumerate" callback during
40 * FDICopy. It is implemented in Windows and therefore worth investigating...
42 * Lots of pointers flying around here... am I leaking RAM?
44 * WTF is FDITruncate?
46 * Probably, I need to weed out some dead code-paths.
48 * Test unit(s).
50 * The fdintNEXT_CABINET callbacks are probably not working quite as they should.
51 * There are several FIXME's in the source describing some of the deficiencies in
52 * some detail. Additionally, we do not do a very good job of returning the right
53 * error codes to this callback.
55 * FDICopy and fdi_decomp are incomprehensibly large; separating these into smaller
56 * functions would be nice.
58 * -gmt
61 #include "config.h"
63 #include <stdarg.h>
64 #include <stdio.h>
66 #include "windef.h"
67 #include "winbase.h"
68 #include "winerror.h"
69 #include "fdi.h"
70 #include "cabinet.h"
72 #include "wine/debug.h"
74 WINE_DEFAULT_DEBUG_CHANNEL(cabinet);
76 THOSE_ZIP_CONSTS;
78 struct fdi_file {
79 struct fdi_file *next; /* next file in sequence */
80 LPSTR filename; /* output name of file */
81 int fh; /* open file handle or NULL */
82 cab_ULONG length; /* uncompressed length of file */
83 cab_ULONG offset; /* uncompressed offset in folder */
84 cab_UWORD index; /* magic index number of folder */
85 cab_UWORD time, date, attribs; /* MS-DOS time/date/attributes */
86 BOOL oppressed; /* never to be processed */
89 struct fdi_folder {
90 struct fdi_folder *next;
91 cab_off_t offset; /* offset to data blocks (32 bit) */
92 cab_UWORD comp_type; /* compression format/window size */
93 cab_ULONG comp_size; /* compressed size of folder */
94 cab_UBYTE num_splits; /* number of split blocks + 1 */
95 cab_UWORD num_blocks; /* total number of blocks */
99 * this structure fills the gaps between what is available in a PFDICABINETINFO
100 * vs what is needed by FDICopy. Memory allocated for these becomes the responsibility
101 * of the caller to free. Yes, I am aware that this is totally, utterly inelegant.
102 * To make things even more unnecessarily confusing, we now attach these to the
103 * fdi_decomp_state.
105 typedef struct {
106 char *prevname, *previnfo;
107 char *nextname, *nextinfo;
108 BOOL hasnext; /* bug free indicator */
109 int folder_resv, header_resv;
110 cab_UBYTE block_resv;
111 } MORE_ISCAB_INFO, *PMORE_ISCAB_INFO;
113 typedef struct
115 unsigned int magic;
116 PFNALLOC alloc;
117 PFNFREE free;
118 PFNOPEN open;
119 PFNREAD read;
120 PFNWRITE write;
121 PFNCLOSE close;
122 PFNSEEK seek;
123 PERF perf;
124 } FDI_Int;
126 #define FDI_INT_MAGIC 0xfdfdfd05
129 * ugh, well, this ended up being pretty damn silly...
130 * now that I've conceded to build equivalent structures to struct cab.*,
131 * I should have just used those, or, better yet, unified the two... sue me.
132 * (Note to Microsoft: That's a joke. Please /don't/ actually sue me! -gmt).
133 * Nevertheless, I've come this far, it works, so I'm not gonna change it
134 * for now. This implementation has significant semantic differences anyhow.
137 typedef struct fdi_cds_fwd {
138 FDI_Int *fdi; /* the hfdi we are using */
139 INT_PTR filehf, cabhf; /* file handle we are using */
140 struct fdi_folder *current; /* current folder we're extracting from */
141 cab_ULONG offset; /* uncompressed offset within folder */
142 cab_UBYTE *outpos; /* (high level) start of data to use up */
143 cab_UWORD outlen; /* (high level) amount of data to use up */
144 int (*decompress)(int, int, struct fdi_cds_fwd *); /* chosen compress fn */
145 cab_UBYTE inbuf[CAB_INPUTMAX+2]; /* +2 for lzx bitbuffer overflows! */
146 cab_UBYTE outbuf[CAB_BLOCKMAX];
147 union {
148 struct ZIPstate zip;
149 struct QTMstate qtm;
150 struct LZXstate lzx;
151 } methods;
152 /* some temp variables for use during decompression */
153 cab_UBYTE q_length_base[27], q_length_extra[27], q_extra_bits[42];
154 cab_ULONG q_position_base[42];
155 cab_ULONG lzx_position_base[51];
156 cab_UBYTE extra_bits[51];
157 USHORT setID; /* Cabinet set ID */
158 USHORT iCabinet; /* Cabinet number in set (0 based) */
159 struct fdi_cds_fwd *decomp_cab;
160 MORE_ISCAB_INFO mii;
161 struct fdi_folder *firstfol;
162 struct fdi_file *firstfile;
163 struct fdi_cds_fwd *next;
164 } fdi_decomp_state;
166 #define ZIPNEEDBITS(n) {while(k<(n)){cab_LONG c=*(ZIP(inpos)++);\
167 b|=((cab_ULONG)c)<<k;k+=8;}}
168 #define ZIPDUMPBITS(n) {b>>=(n);k-=(n);}
170 /* endian-neutral reading of little-endian data */
171 #define EndGetI32(a) ((((a)[3])<<24)|(((a)[2])<<16)|(((a)[1])<<8)|((a)[0]))
172 #define EndGetI16(a) ((((a)[1])<<8)|((a)[0]))
174 #define CAB(x) (decomp_state->x)
175 #define ZIP(x) (decomp_state->methods.zip.x)
176 #define QTM(x) (decomp_state->methods.qtm.x)
177 #define LZX(x) (decomp_state->methods.lzx.x)
178 #define DECR_OK (0)
179 #define DECR_DATAFORMAT (1)
180 #define DECR_ILLEGALDATA (2)
181 #define DECR_NOMEMORY (3)
182 #define DECR_CHECKSUM (4)
183 #define DECR_INPUT (5)
184 #define DECR_OUTPUT (6)
185 #define DECR_USERABORT (7)
187 static void set_error( FDI_Int *fdi, int oper, int err )
189 fdi->perf->erfOper = oper;
190 fdi->perf->erfType = err;
191 fdi->perf->fError = TRUE;
192 if (err) SetLastError( err );
195 static FDI_Int *get_fdi_ptr( HFDI hfdi )
197 FDI_Int *fdi= (FDI_Int *)hfdi;
199 if (!fdi || fdi->magic != FDI_INT_MAGIC)
201 SetLastError( ERROR_INVALID_HANDLE );
202 return NULL;
204 return fdi;
207 /****************************************************************
208 * QTMupdatemodel (internal)
210 static void QTMupdatemodel(struct QTMmodel *model, int sym) {
211 struct QTMmodelsym temp;
212 int i, j;
214 for (i = 0; i < sym; i++) model->syms[i].cumfreq += 8;
216 if (model->syms[0].cumfreq > 3800) {
217 if (--model->shiftsleft) {
218 for (i = model->entries - 1; i >= 0; i--) {
219 /* -1, not -2; the 0 entry saves this */
220 model->syms[i].cumfreq >>= 1;
221 if (model->syms[i].cumfreq <= model->syms[i+1].cumfreq) {
222 model->syms[i].cumfreq = model->syms[i+1].cumfreq + 1;
226 else {
227 model->shiftsleft = 50;
228 for (i = 0; i < model->entries ; i++) {
229 /* no -1, want to include the 0 entry */
230 /* this converts cumfreqs into frequencies, then shifts right */
231 model->syms[i].cumfreq -= model->syms[i+1].cumfreq;
232 model->syms[i].cumfreq++; /* avoid losing things entirely */
233 model->syms[i].cumfreq >>= 1;
236 /* now sort by frequencies, decreasing order -- this must be an
237 * inplace selection sort, or a sort with the same (in)stability
238 * characteristics
240 for (i = 0; i < model->entries - 1; i++) {
241 for (j = i + 1; j < model->entries; j++) {
242 if (model->syms[i].cumfreq < model->syms[j].cumfreq) {
243 temp = model->syms[i];
244 model->syms[i] = model->syms[j];
245 model->syms[j] = temp;
250 /* then convert frequencies back to cumfreq */
251 for (i = model->entries - 1; i >= 0; i--) {
252 model->syms[i].cumfreq += model->syms[i+1].cumfreq;
254 /* then update the other part of the table */
255 for (i = 0; i < model->entries; i++) {
256 model->tabloc[model->syms[i].sym] = i;
262 /*************************************************************************
263 * make_decode_table (internal)
265 * This function was coded by David Tritscher. It builds a fast huffman
266 * decoding table out of just a canonical huffman code lengths table.
268 * PARAMS
269 * nsyms: total number of symbols in this huffman tree.
270 * nbits: any symbols with a code length of nbits or less can be decoded
271 * in one lookup of the table.
272 * length: A table to get code lengths from [0 to syms-1]
273 * table: The table to fill up with decoded symbols and pointers.
275 * RETURNS
276 * OK: 0
277 * error: 1
279 static int make_decode_table(cab_ULONG nsyms, cab_ULONG nbits,
280 const cab_UBYTE *length, cab_UWORD *table) {
281 register cab_UWORD sym;
282 register cab_ULONG leaf;
283 register cab_UBYTE bit_num = 1;
284 cab_ULONG fill;
285 cab_ULONG pos = 0; /* the current position in the decode table */
286 cab_ULONG table_mask = 1 << nbits;
287 cab_ULONG bit_mask = table_mask >> 1; /* don't do 0 length codes */
288 cab_ULONG next_symbol = bit_mask; /* base of allocation for long codes */
290 /* fill entries for codes short enough for a direct mapping */
291 while (bit_num <= nbits) {
292 for (sym = 0; sym < nsyms; sym++) {
293 if (length[sym] == bit_num) {
294 leaf = pos;
296 if((pos += bit_mask) > table_mask) return 1; /* table overrun */
298 /* fill all possible lookups of this symbol with the symbol itself */
299 fill = bit_mask;
300 while (fill-- > 0) table[leaf++] = sym;
303 bit_mask >>= 1;
304 bit_num++;
307 /* if there are any codes longer than nbits */
308 if (pos != table_mask) {
309 /* clear the remainder of the table */
310 for (sym = pos; sym < table_mask; sym++) table[sym] = 0;
312 /* give ourselves room for codes to grow by up to 16 more bits */
313 pos <<= 16;
314 table_mask <<= 16;
315 bit_mask = 1 << 15;
317 while (bit_num <= 16) {
318 for (sym = 0; sym < nsyms; sym++) {
319 if (length[sym] == bit_num) {
320 leaf = pos >> 16;
321 for (fill = 0; fill < bit_num - nbits; fill++) {
322 /* if this path hasn't been taken yet, 'allocate' two entries */
323 if (table[leaf] == 0) {
324 table[(next_symbol << 1)] = 0;
325 table[(next_symbol << 1) + 1] = 0;
326 table[leaf] = next_symbol++;
328 /* follow the path and select either left or right for next bit */
329 leaf = table[leaf] << 1;
330 if ((pos >> (15-fill)) & 1) leaf++;
332 table[leaf] = sym;
334 if ((pos += bit_mask) > table_mask) return 1; /* table overflow */
337 bit_mask >>= 1;
338 bit_num++;
342 /* full table? */
343 if (pos == table_mask) return 0;
345 /* either erroneous table, or all elements are 0 - let's find out. */
346 for (sym = 0; sym < nsyms; sym++) if (length[sym]) return 1;
347 return 0;
350 /*************************************************************************
351 * checksum (internal)
353 static cab_ULONG checksum(const cab_UBYTE *data, cab_UWORD bytes, cab_ULONG csum) {
354 int len;
355 cab_ULONG ul = 0;
357 for (len = bytes >> 2; len--; data += 4) {
358 csum ^= ((data[0]) | (data[1]<<8) | (data[2]<<16) | (data[3]<<24));
361 switch (bytes & 3) {
362 case 3: ul |= *data++ << 16;
363 case 2: ul |= *data++ << 8;
364 case 1: ul |= *data;
366 csum ^= ul;
368 return csum;
371 /***********************************************************************
372 * FDICreate (CABINET.20)
374 * Provided with several callbacks (all of them are mandatory),
375 * returns a handle which can be used to perform operations
376 * on cabinet files.
378 * PARAMS
379 * pfnalloc [I] A pointer to a function which allocates ram. Uses
380 * the same interface as malloc.
381 * pfnfree [I] A pointer to a function which frees ram. Uses the
382 * same interface as free.
383 * pfnopen [I] A pointer to a function which opens a file. Uses
384 * the same interface as _open.
385 * pfnread [I] A pointer to a function which reads from a file into
386 * a caller-provided buffer. Uses the same interface
387 * as _read
388 * pfnwrite [I] A pointer to a function which writes to a file from
389 * a caller-provided buffer. Uses the same interface
390 * as _write.
391 * pfnclose [I] A pointer to a function which closes a file handle.
392 * Uses the same interface as _close.
393 * pfnseek [I] A pointer to a function which seeks in a file.
394 * Uses the same interface as _lseek.
395 * cpuType [I] The type of CPU; ignored in wine (recommended value:
396 * cpuUNKNOWN, aka -1).
397 * perf [IO] A pointer to an ERF structure. When FDICreate
398 * returns an error condition, error information may
399 * be found here as well as from GetLastError.
401 * RETURNS
402 * On success, returns an FDI handle of type HFDI.
403 * On failure, the NULL file handle is returned. Error
404 * info can be retrieved from perf.
406 * INCLUDES
407 * fdi.h
410 HFDI __cdecl FDICreate(
411 PFNALLOC pfnalloc,
412 PFNFREE pfnfree,
413 PFNOPEN pfnopen,
414 PFNREAD pfnread,
415 PFNWRITE pfnwrite,
416 PFNCLOSE pfnclose,
417 PFNSEEK pfnseek,
418 int cpuType,
419 PERF perf)
421 FDI_Int *fdi;
423 TRACE("(pfnalloc == ^%p, pfnfree == ^%p, pfnopen == ^%p, pfnread == ^%p, pfnwrite == ^%p, "
424 "pfnclose == ^%p, pfnseek == ^%p, cpuType == %d, perf == ^%p)\n",
425 pfnalloc, pfnfree, pfnopen, pfnread, pfnwrite, pfnclose, pfnseek,
426 cpuType, perf);
428 if ((!pfnalloc) || (!pfnfree)) {
429 perf->erfOper = FDIERROR_NONE;
430 perf->erfType = ERROR_BAD_ARGUMENTS;
431 perf->fError = TRUE;
433 SetLastError(ERROR_BAD_ARGUMENTS);
434 return NULL;
437 if (!((fdi = pfnalloc(sizeof(FDI_Int))))) {
438 perf->erfOper = FDIERROR_ALLOC_FAIL;
439 perf->erfType = 0;
440 perf->fError = TRUE;
441 return NULL;
444 fdi->magic = FDI_INT_MAGIC;
445 fdi->alloc = pfnalloc;
446 fdi->free = pfnfree;
447 fdi->open = pfnopen;
448 fdi->read = pfnread;
449 fdi->write = pfnwrite;
450 fdi->close = pfnclose;
451 fdi->seek = pfnseek;
452 /* no-brainer: we ignore the cpu type; this is only used
453 for the 16-bit versions in Windows anyhow... */
454 fdi->perf = perf;
456 return (HFDI)fdi;
459 /*******************************************************************
460 * FDI_getoffset (internal)
462 * returns the file pointer position of a file handle.
464 static LONG FDI_getoffset(FDI_Int *fdi, INT_PTR hf)
466 return fdi->seek(hf, 0, SEEK_CUR);
469 /**********************************************************************
470 * FDI_read_string (internal)
472 * allocate and read an arbitrarily long string from the cabinet
474 static char *FDI_read_string(FDI_Int *fdi, INT_PTR hf, long cabsize)
476 size_t len=256,
477 base = FDI_getoffset(fdi, hf),
478 maxlen = cabsize - base;
479 BOOL ok = FALSE;
480 unsigned int i;
481 cab_UBYTE *buf = NULL;
483 TRACE("(fdi == %p, hf == %ld, cabsize == %ld)\n", fdi, hf, cabsize);
485 do {
486 if (len > maxlen) len = maxlen;
487 if (!(buf = fdi->alloc(len))) break;
488 if (!fdi->read(hf, buf, len)) break;
490 /* search for a null terminator in what we've just read */
491 for (i=0; i < len; i++) {
492 if (!buf[i]) {ok=TRUE; break;}
495 if (!ok) {
496 if (len == maxlen) {
497 ERR("cabinet is truncated\n");
498 break;
500 /* The buffer is too small for the string. Reset the file to the point
501 * were we started, free the buffer and increase the size for the next try
503 fdi->seek(hf, base, SEEK_SET);
504 fdi->free(buf);
505 buf = NULL;
506 len *= 2;
508 } while (!ok);
510 if (!ok) {
511 if (buf)
512 fdi->free(buf);
513 else
514 ERR("out of memory!\n");
515 return NULL;
518 /* otherwise, set the stream to just after the string and return */
519 fdi->seek(hf, base + strlen((char *)buf) + 1, SEEK_SET);
521 return (char *) buf;
524 /******************************************************************
525 * FDI_read_entries (internal)
527 * process the cabinet header in the style of FDIIsCabinet, but
528 * without the sanity checks (and bug)
530 static BOOL FDI_read_entries(
531 FDI_Int *fdi,
532 INT_PTR hf,
533 PFDICABINETINFO pfdici,
534 PMORE_ISCAB_INFO pmii)
536 int num_folders, num_files, header_resv, folder_resv = 0;
537 LONG base_offset, cabsize;
538 USHORT setid, cabidx, flags;
539 cab_UBYTE buf[64], block_resv;
540 char *prevname = NULL, *previnfo = NULL, *nextname = NULL, *nextinfo = NULL;
542 TRACE("(fdi == ^%p, hf == %ld, pfdici == ^%p)\n", fdi, hf, pfdici);
545 * FIXME: I just noticed that I am memorizing the initial file pointer
546 * offset and restoring it before reading in the rest of the header
547 * information in the cabinet. Perhaps that's correct -- that is, perhaps
548 * this API is supposed to support "streaming" cabinets which are embedded
549 * in other files, or cabinets which begin at file offsets other than zero.
550 * Otherwise, I should instead go to the absolute beginning of the file.
551 * (Either way, the semantics of wine's FDICopy require me to leave the
552 * file pointer where it is afterwards -- If Windows does not do so, we
553 * ought to duplicate the native behavior in the FDIIsCabinet API, not here.
555 * So, the answer lies in Windows; will native cabinet.dll recognize a
556 * cabinet "file" embedded in another file? Note that cabextract.c does
557 * support this, which implies that Microsoft's might. I haven't tried it
558 * yet so I don't know. ATM, most of wine's FDI cabinet routines (except
559 * this one) would not work in this way. To fix it, we could just make the
560 * various references to absolute file positions in the code relative to an
561 * initial "beginning" offset. Because the FDICopy API doesn't take a
562 * file-handle like this one, we would therein need to search through the
563 * file for the beginning of the cabinet (as we also do in cabextract.c).
564 * Note that this limits us to a maximum of one cabinet per. file: the first.
566 * So, in summary: either the code below is wrong, or the rest of fdi.c is
567 * wrong... I cannot imagine that both are correct ;) One of these flaws
568 * should be fixed after determining the behavior on Windows. We ought
569 * to check both FDIIsCabinet and FDICopy for the right behavior.
571 * -gmt
574 /* get basic offset & size info */
575 base_offset = FDI_getoffset(fdi, hf);
577 if (fdi->seek(hf, 0, SEEK_END) == -1) {
578 if (pmii) set_error( fdi, FDIERROR_NOT_A_CABINET, 0 );
579 return FALSE;
582 cabsize = FDI_getoffset(fdi, hf);
584 if ((cabsize == -1) || (base_offset == -1) ||
585 ( fdi->seek(hf, base_offset, SEEK_SET) == -1 )) {
586 if (pmii) set_error( fdi, FDIERROR_NOT_A_CABINET, 0 );
587 return FALSE;
590 /* read in the CFHEADER */
591 if (fdi->read(hf, buf, cfhead_SIZEOF) != cfhead_SIZEOF) {
592 if (pmii) set_error( fdi, FDIERROR_NOT_A_CABINET, 0 );
593 return FALSE;
596 /* check basic MSCF signature */
597 if (EndGetI32(buf+cfhead_Signature) != 0x4643534d) {
598 if (pmii) set_error( fdi, FDIERROR_NOT_A_CABINET, 0 );
599 return FALSE;
602 /* get the number of folders */
603 num_folders = EndGetI16(buf+cfhead_NumFolders);
605 /* get the number of files */
606 num_files = EndGetI16(buf+cfhead_NumFiles);
608 /* setid */
609 setid = EndGetI16(buf+cfhead_SetID);
611 /* cabinet (set) index */
612 cabidx = EndGetI16(buf+cfhead_CabinetIndex);
614 /* check the header revision */
615 if ((buf[cfhead_MajorVersion] > 1) ||
616 (buf[cfhead_MajorVersion] == 1 && buf[cfhead_MinorVersion] > 3))
618 WARN("cabinet format version > 1.3\n");
619 if (pmii) set_error( fdi, FDIERROR_UNKNOWN_CABINET_VERSION, 0 /* ? */ );
620 return FALSE;
623 /* pull the flags out */
624 flags = EndGetI16(buf+cfhead_Flags);
626 /* read the reserved-sizes part of header, if present */
627 if (flags & cfheadRESERVE_PRESENT) {
628 if (fdi->read(hf, buf, cfheadext_SIZEOF) != cfheadext_SIZEOF) {
629 ERR("bunk reserve-sizes?\n");
630 if (pmii) set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 /* ? */ );
631 return FALSE;
634 header_resv = EndGetI16(buf+cfheadext_HeaderReserved);
635 if (pmii) pmii->header_resv = header_resv;
636 folder_resv = buf[cfheadext_FolderReserved];
637 if (pmii) pmii->folder_resv = folder_resv;
638 block_resv = buf[cfheadext_DataReserved];
639 if (pmii) pmii->block_resv = block_resv;
641 if (header_resv > 60000) {
642 WARN("WARNING; header reserved space > 60000\n");
645 /* skip the reserved header */
646 if ((header_resv) && (fdi->seek(hf, header_resv, SEEK_CUR) == -1)) {
647 ERR("seek failure: header_resv\n");
648 if (pmii) set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 /* ? */ );
649 return FALSE;
653 if (flags & cfheadPREV_CABINET) {
654 prevname = FDI_read_string(fdi, hf, cabsize);
655 if (!prevname) {
656 if (pmii) set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 /* ? */ );
657 return FALSE;
658 } else
659 if (pmii)
660 pmii->prevname = prevname;
661 else
662 fdi->free(prevname);
663 previnfo = FDI_read_string(fdi, hf, cabsize);
664 if (previnfo) {
665 if (pmii)
666 pmii->previnfo = previnfo;
667 else
668 fdi->free(previnfo);
672 if (flags & cfheadNEXT_CABINET) {
673 if (pmii)
674 pmii->hasnext = TRUE;
675 nextname = FDI_read_string(fdi, hf, cabsize);
676 if (!nextname) {
677 if ((flags & cfheadPREV_CABINET) && pmii) {
678 if (pmii->prevname) fdi->free(prevname);
679 if (pmii->previnfo) fdi->free(previnfo);
681 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 /* ? */ );
682 return FALSE;
683 } else
684 if (pmii)
685 pmii->nextname = nextname;
686 else
687 fdi->free(nextname);
688 nextinfo = FDI_read_string(fdi, hf, cabsize);
689 if (nextinfo) {
690 if (pmii)
691 pmii->nextinfo = nextinfo;
692 else
693 fdi->free(nextinfo);
697 /* we could process the whole cabinet searching for problems;
698 instead lets stop here. Now let's fill out the paperwork */
699 pfdici->cbCabinet = cabsize;
700 pfdici->cFolders = num_folders;
701 pfdici->cFiles = num_files;
702 pfdici->setID = setid;
703 pfdici->iCabinet = cabidx;
704 pfdici->fReserve = (flags & cfheadRESERVE_PRESENT) ? TRUE : FALSE;
705 pfdici->hasprev = (flags & cfheadPREV_CABINET) ? TRUE : FALSE;
706 pfdici->hasnext = (flags & cfheadNEXT_CABINET) ? TRUE : FALSE;
707 return TRUE;
710 /***********************************************************************
711 * FDIIsCabinet (CABINET.21)
713 * Informs the caller as to whether or not the provided file handle is
714 * really a cabinet or not, filling out the provided PFDICABINETINFO
715 * structure with information about the cabinet. Brief explanations of
716 * the elements of this structure are available as comments accompanying
717 * its definition in wine's include/fdi.h.
719 * PARAMS
720 * hfdi [I] An HFDI from FDICreate
721 * hf [I] The file handle about which the caller inquires
722 * pfdici [IO] Pointer to a PFDICABINETINFO structure which will
723 * be filled out with information about the cabinet
724 * file indicated by hf if, indeed, it is determined
725 * to be a cabinet.
727 * RETURNS
728 * TRUE if the file is a cabinet. The info pointed to by pfdici will
729 * be provided.
730 * FALSE if the file is not a cabinet, or if an error was encountered
731 * while processing the cabinet. The PERF structure provided to
732 * FDICreate can be queried for more error information.
734 * INCLUDES
735 * fdi.c
737 BOOL __cdecl FDIIsCabinet(
738 HFDI hfdi,
739 INT_PTR hf,
740 PFDICABINETINFO pfdici)
742 BOOL rv;
743 FDI_Int *fdi = get_fdi_ptr( hfdi );
745 TRACE("(hfdi == ^%p, hf == ^%ld, pfdici == ^%p)\n", hfdi, hf, pfdici);
747 if (!fdi) return FALSE;
749 if (!hf) {
750 ERR("(!hf)!\n");
751 SetLastError(ERROR_INVALID_HANDLE);
752 return FALSE;
755 if (!pfdici) {
756 ERR("(!pfdici)!\n");
757 SetLastError(ERROR_BAD_ARGUMENTS);
758 return FALSE;
760 rv = FDI_read_entries(fdi, hf, pfdici, NULL);
762 if (rv)
763 pfdici->hasnext = FALSE; /* yuck. duplicate apparent cabinet.dll bug */
765 return rv;
768 /******************************************************************
769 * QTMfdi_initmodel (internal)
771 * Initialize a model which decodes symbols from [s] to [s]+[n]-1
773 static void QTMfdi_initmodel(struct QTMmodel *m, struct QTMmodelsym *sym, int n, int s) {
774 int i;
775 m->shiftsleft = 4;
776 m->entries = n;
777 m->syms = sym;
778 memset(m->tabloc, 0xFF, sizeof(m->tabloc)); /* clear out look-up table */
779 for (i = 0; i < n; i++) {
780 m->tabloc[i+s] = i; /* set up a look-up entry for symbol */
781 m->syms[i].sym = i+s; /* actual symbol */
782 m->syms[i].cumfreq = n-i; /* current frequency of that symbol */
784 m->syms[n].cumfreq = 0;
787 /******************************************************************
788 * QTMfdi_init (internal)
790 static int QTMfdi_init(int window, int level, fdi_decomp_state *decomp_state) {
791 unsigned int wndsize = 1 << window;
792 int msz = window * 2, i;
793 cab_ULONG j;
795 /* QTM supports window sizes of 2^10 (1Kb) through 2^21 (2Mb) */
796 /* if a previously allocated window is big enough, keep it */
797 if (window < 10 || window > 21) return DECR_DATAFORMAT;
798 if (QTM(actual_size) < wndsize) {
799 if (QTM(window)) CAB(fdi)->free(QTM(window));
800 QTM(window) = NULL;
802 if (!QTM(window)) {
803 if (!(QTM(window) = CAB(fdi)->alloc(wndsize))) return DECR_NOMEMORY;
804 QTM(actual_size) = wndsize;
806 QTM(window_size) = wndsize;
807 QTM(window_posn) = 0;
809 /* initialize static slot/extrabits tables */
810 for (i = 0, j = 0; i < 27; i++) {
811 CAB(q_length_extra)[i] = (i == 26) ? 0 : (i < 2 ? 0 : i - 2) >> 2;
812 CAB(q_length_base)[i] = j; j += 1 << ((i == 26) ? 5 : CAB(q_length_extra)[i]);
814 for (i = 0, j = 0; i < 42; i++) {
815 CAB(q_extra_bits)[i] = (i < 2 ? 0 : i-2) >> 1;
816 CAB(q_position_base)[i] = j; j += 1 << CAB(q_extra_bits)[i];
819 /* initialize arithmetic coding models */
821 QTMfdi_initmodel(&QTM(model7), &QTM(m7sym)[0], 7, 0);
823 QTMfdi_initmodel(&QTM(model00), &QTM(m00sym)[0], 0x40, 0x00);
824 QTMfdi_initmodel(&QTM(model40), &QTM(m40sym)[0], 0x40, 0x40);
825 QTMfdi_initmodel(&QTM(model80), &QTM(m80sym)[0], 0x40, 0x80);
826 QTMfdi_initmodel(&QTM(modelC0), &QTM(mC0sym)[0], 0x40, 0xC0);
828 /* model 4 depends on table size, ranges from 20 to 24 */
829 QTMfdi_initmodel(&QTM(model4), &QTM(m4sym)[0], (msz < 24) ? msz : 24, 0);
830 /* model 5 depends on table size, ranges from 20 to 36 */
831 QTMfdi_initmodel(&QTM(model5), &QTM(m5sym)[0], (msz < 36) ? msz : 36, 0);
832 /* model 6pos depends on table size, ranges from 20 to 42 */
833 QTMfdi_initmodel(&QTM(model6pos), &QTM(m6psym)[0], msz, 0);
834 QTMfdi_initmodel(&QTM(model6len), &QTM(m6lsym)[0], 27, 0);
836 return DECR_OK;
839 /************************************************************
840 * LZXfdi_init (internal)
842 static int LZXfdi_init(int window, fdi_decomp_state *decomp_state) {
843 static const cab_UBYTE bits[] =
844 { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
845 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14,
846 15, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
847 17, 17, 17};
848 static const cab_ULONG base[] =
849 { 0, 1, 2, 3, 4, 6, 8, 12,
850 16, 24, 32, 48, 64, 96, 128, 192,
851 256, 384, 512, 768, 1024, 1536, 2048, 3072,
852 4096, 6144, 8192, 12288, 16384, 24576, 32768, 49152,
853 65536, 98304, 131072, 196608, 262144, 393216, 524288, 655360,
854 786432, 917504, 1048576, 1179648, 1310720, 1441792, 1572864, 1703936,
855 1835008, 1966080, 2097152};
856 cab_ULONG wndsize = 1 << window;
857 int posn_slots;
859 /* LZX supports window sizes of 2^15 (32Kb) through 2^21 (2Mb) */
860 /* if a previously allocated window is big enough, keep it */
861 if (window < 15 || window > 21) return DECR_DATAFORMAT;
862 if (LZX(actual_size) < wndsize) {
863 if (LZX(window)) CAB(fdi)->free(LZX(window));
864 LZX(window) = NULL;
866 if (!LZX(window)) {
867 if (!(LZX(window) = CAB(fdi)->alloc(wndsize))) return DECR_NOMEMORY;
868 LZX(actual_size) = wndsize;
870 LZX(window_size) = wndsize;
872 /* initialize static tables */
873 memcpy(CAB(extra_bits), bits, sizeof(bits));
874 memcpy(CAB(lzx_position_base), base, sizeof(base));
876 /* calculate required position slots */
877 if (window == 20) posn_slots = 42;
878 else if (window == 21) posn_slots = 50;
879 else posn_slots = window << 1;
881 /*posn_slots=i=0; while (i < wndsize) i += 1 << CAB(extra_bits)[posn_slots++]; */
883 LZX(R0) = LZX(R1) = LZX(R2) = 1;
884 LZX(main_elements) = LZX_NUM_CHARS + (posn_slots << 3);
885 LZX(header_read) = 0;
886 LZX(frames_read) = 0;
887 LZX(block_remaining) = 0;
888 LZX(block_type) = LZX_BLOCKTYPE_INVALID;
889 LZX(intel_curpos) = 0;
890 LZX(intel_started) = 0;
891 LZX(window_posn) = 0;
893 /* initialize tables to 0 (because deltas will be applied to them) */
894 memset(LZX(MAINTREE_len), 0, sizeof(LZX(MAINTREE_len)));
895 memset(LZX(LENGTH_len), 0, sizeof(LZX(LENGTH_len)));
897 return DECR_OK;
900 /****************************************************
901 * NONEfdi_decomp(internal)
903 static int NONEfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state)
905 if (inlen != outlen) return DECR_ILLEGALDATA;
906 if (outlen > CAB_BLOCKMAX) return DECR_DATAFORMAT;
907 memcpy(CAB(outbuf), CAB(inbuf), (size_t) inlen);
908 return DECR_OK;
911 /********************************************************
912 * Ziphuft_free (internal)
914 static void fdi_Ziphuft_free(FDI_Int *fdi, struct Ziphuft *t)
916 register struct Ziphuft *p, *q;
918 /* Go through linked list, freeing from the allocated (t[-1]) address. */
919 p = t;
920 while (p != NULL)
922 q = (--p)->v.t;
923 fdi->free(p);
924 p = q;
928 /*********************************************************
929 * fdi_Ziphuft_build (internal)
931 static cab_LONG fdi_Ziphuft_build(cab_ULONG *b, cab_ULONG n, cab_ULONG s, const cab_UWORD *d, const cab_UWORD *e,
932 struct Ziphuft **t, cab_LONG *m, fdi_decomp_state *decomp_state)
934 cab_ULONG a; /* counter for codes of length k */
935 cab_ULONG el; /* length of EOB code (value 256) */
936 cab_ULONG f; /* i repeats in table every f entries */
937 cab_LONG g; /* maximum code length */
938 cab_LONG h; /* table level */
939 register cab_ULONG i; /* counter, current code */
940 register cab_ULONG j; /* counter */
941 register cab_LONG k; /* number of bits in current code */
942 cab_LONG *l; /* stack of bits per table */
943 register cab_ULONG *p; /* pointer into ZIP(c)[],ZIP(b)[],ZIP(v)[] */
944 register struct Ziphuft *q; /* points to current table */
945 struct Ziphuft r; /* table entry for structure assignment */
946 register cab_LONG w; /* bits before this table == (l * h) */
947 cab_ULONG *xp; /* pointer into x */
948 cab_LONG y; /* number of dummy codes added */
949 cab_ULONG z; /* number of entries in current table */
951 l = ZIP(lx)+1;
953 /* Generate counts for each bit length */
954 el = n > 256 ? b[256] : ZIPBMAX; /* set length of EOB code, if any */
956 for(i = 0; i < ZIPBMAX+1; ++i)
957 ZIP(c)[i] = 0;
958 p = b; i = n;
961 ZIP(c)[*p]++; p++; /* assume all entries <= ZIPBMAX */
962 } while (--i);
963 if (ZIP(c)[0] == n) /* null input--all zero length codes */
965 *t = NULL;
966 *m = 0;
967 return 0;
970 /* Find minimum and maximum length, bound *m by those */
971 for (j = 1; j <= ZIPBMAX; j++)
972 if (ZIP(c)[j])
973 break;
974 k = j; /* minimum code length */
975 if ((cab_ULONG)*m < j)
976 *m = j;
977 for (i = ZIPBMAX; i; i--)
978 if (ZIP(c)[i])
979 break;
980 g = i; /* maximum code length */
981 if ((cab_ULONG)*m > i)
982 *m = i;
984 /* Adjust last length count to fill out codes, if needed */
985 for (y = 1 << j; j < i; j++, y <<= 1)
986 if ((y -= ZIP(c)[j]) < 0)
987 return 2; /* bad input: more codes than bits */
988 if ((y -= ZIP(c)[i]) < 0)
989 return 2;
990 ZIP(c)[i] += y;
992 /* Generate starting offsets LONGo the value table for each length */
993 ZIP(x)[1] = j = 0;
994 p = ZIP(c) + 1; xp = ZIP(x) + 2;
995 while (--i)
996 { /* note that i == g from above */
997 *xp++ = (j += *p++);
1000 /* Make a table of values in order of bit lengths */
1001 p = b; i = 0;
1003 if ((j = *p++) != 0)
1004 ZIP(v)[ZIP(x)[j]++] = i;
1005 } while (++i < n);
1008 /* Generate the Huffman codes and for each, make the table entries */
1009 ZIP(x)[0] = i = 0; /* first Huffman code is zero */
1010 p = ZIP(v); /* grab values in bit order */
1011 h = -1; /* no tables yet--level -1 */
1012 w = l[-1] = 0; /* no bits decoded yet */
1013 ZIP(u)[0] = NULL; /* just to keep compilers happy */
1014 q = NULL; /* ditto */
1015 z = 0; /* ditto */
1017 /* go through the bit lengths (k already is bits in shortest code) */
1018 for (; k <= g; k++)
1020 a = ZIP(c)[k];
1021 while (a--)
1023 /* here i is the Huffman code of length k bits for value *p */
1024 /* make tables up to required level */
1025 while (k > w + l[h])
1027 w += l[h++]; /* add bits already decoded */
1029 /* compute minimum size table less than or equal to *m bits */
1030 if ((z = g - w) > (cab_ULONG)*m) /* upper limit */
1031 z = *m;
1032 if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
1033 { /* too few codes for k-w bit table */
1034 f -= a + 1; /* deduct codes from patterns left */
1035 xp = ZIP(c) + k;
1036 while (++j < z) /* try smaller tables up to z bits */
1038 if ((f <<= 1) <= *++xp)
1039 break; /* enough codes to use up j bits */
1040 f -= *xp; /* else deduct codes from patterns */
1043 if ((cab_ULONG)w + j > el && (cab_ULONG)w < el)
1044 j = el - w; /* make EOB code end at table */
1045 z = 1 << j; /* table entries for j-bit table */
1046 l[h] = j; /* set table size in stack */
1048 /* allocate and link in new table */
1049 if (!(q = CAB(fdi)->alloc((z + 1)*sizeof(struct Ziphuft))))
1051 if(h)
1052 fdi_Ziphuft_free(CAB(fdi), ZIP(u)[0]);
1053 return 3; /* not enough memory */
1055 *t = q + 1; /* link to list for Ziphuft_free() */
1056 *(t = &(q->v.t)) = NULL;
1057 ZIP(u)[h] = ++q; /* table starts after link */
1059 /* connect to last table, if there is one */
1060 if (h)
1062 ZIP(x)[h] = i; /* save pattern for backing up */
1063 r.b = (cab_UBYTE)l[h-1]; /* bits to dump before this table */
1064 r.e = (cab_UBYTE)(16 + j); /* bits in this table */
1065 r.v.t = q; /* pointer to this table */
1066 j = (i & ((1 << w) - 1)) >> (w - l[h-1]);
1067 ZIP(u)[h-1][j] = r; /* connect to last table */
1071 /* set up table entry in r */
1072 r.b = (cab_UBYTE)(k - w);
1073 if (p >= ZIP(v) + n)
1074 r.e = 99; /* out of values--invalid code */
1075 else if (*p < s)
1077 r.e = (cab_UBYTE)(*p < 256 ? 16 : 15); /* 256 is end-of-block code */
1078 r.v.n = *p++; /* simple code is just the value */
1080 else
1082 r.e = (cab_UBYTE)e[*p - s]; /* non-simple--look up in lists */
1083 r.v.n = d[*p++ - s];
1086 /* fill code-like entries with r */
1087 f = 1 << (k - w);
1088 for (j = i >> w; j < z; j += f)
1089 q[j] = r;
1091 /* backwards increment the k-bit code i */
1092 for (j = 1 << (k - 1); i & j; j >>= 1)
1093 i ^= j;
1094 i ^= j;
1096 /* backup over finished tables */
1097 while ((i & ((1 << w) - 1)) != ZIP(x)[h])
1098 w -= l[--h]; /* don't need to update q */
1102 /* return actual size of base table */
1103 *m = l[0];
1105 /* Return true (1) if we were given an incomplete table */
1106 return y != 0 && g != 1;
1109 /*********************************************************
1110 * fdi_Zipinflate_codes (internal)
1112 static cab_LONG fdi_Zipinflate_codes(const struct Ziphuft *tl, const struct Ziphuft *td,
1113 cab_LONG bl, cab_LONG bd, fdi_decomp_state *decomp_state)
1115 register cab_ULONG e; /* table entry flag/number of extra bits */
1116 cab_ULONG n, d; /* length and index for copy */
1117 cab_ULONG w; /* current window position */
1118 const struct Ziphuft *t; /* pointer to table entry */
1119 cab_ULONG ml, md; /* masks for bl and bd bits */
1120 register cab_ULONG b; /* bit buffer */
1121 register cab_ULONG k; /* number of bits in bit buffer */
1123 /* make local copies of globals */
1124 b = ZIP(bb); /* initialize bit buffer */
1125 k = ZIP(bk);
1126 w = ZIP(window_posn); /* initialize window position */
1128 /* inflate the coded data */
1129 ml = Zipmask[bl]; /* precompute masks for speed */
1130 md = Zipmask[bd];
1132 for(;;)
1134 ZIPNEEDBITS((cab_ULONG)bl)
1135 if((e = (t = tl + (b & ml))->e) > 16)
1138 if (e == 99)
1139 return 1;
1140 ZIPDUMPBITS(t->b)
1141 e -= 16;
1142 ZIPNEEDBITS(e)
1143 } while ((e = (t = t->v.t + (b & Zipmask[e]))->e) > 16);
1144 ZIPDUMPBITS(t->b)
1145 if (e == 16) /* then it's a literal */
1146 CAB(outbuf)[w++] = (cab_UBYTE)t->v.n;
1147 else /* it's an EOB or a length */
1149 /* exit if end of block */
1150 if(e == 15)
1151 break;
1153 /* get length of block to copy */
1154 ZIPNEEDBITS(e)
1155 n = t->v.n + (b & Zipmask[e]);
1156 ZIPDUMPBITS(e);
1158 /* decode distance of block to copy */
1159 ZIPNEEDBITS((cab_ULONG)bd)
1160 if ((e = (t = td + (b & md))->e) > 16)
1161 do {
1162 if (e == 99)
1163 return 1;
1164 ZIPDUMPBITS(t->b)
1165 e -= 16;
1166 ZIPNEEDBITS(e)
1167 } while ((e = (t = t->v.t + (b & Zipmask[e]))->e) > 16);
1168 ZIPDUMPBITS(t->b)
1169 ZIPNEEDBITS(e)
1170 d = w - t->v.n - (b & Zipmask[e]);
1171 ZIPDUMPBITS(e)
1174 d &= ZIPWSIZE - 1;
1175 e = ZIPWSIZE - max(d, w);
1176 e = min(e, n);
1177 n -= e;
1180 CAB(outbuf)[w++] = CAB(outbuf)[d++];
1181 } while (--e);
1182 } while (n);
1186 /* restore the globals from the locals */
1187 ZIP(window_posn) = w; /* restore global window pointer */
1188 ZIP(bb) = b; /* restore global bit buffer */
1189 ZIP(bk) = k;
1191 /* done */
1192 return 0;
1195 /***********************************************************
1196 * Zipinflate_stored (internal)
1198 static cab_LONG fdi_Zipinflate_stored(fdi_decomp_state *decomp_state)
1199 /* "decompress" an inflated type 0 (stored) block. */
1201 cab_ULONG n; /* number of bytes in block */
1202 cab_ULONG w; /* current window position */
1203 register cab_ULONG b; /* bit buffer */
1204 register cab_ULONG k; /* number of bits in bit buffer */
1206 /* make local copies of globals */
1207 b = ZIP(bb); /* initialize bit buffer */
1208 k = ZIP(bk);
1209 w = ZIP(window_posn); /* initialize window position */
1211 /* go to byte boundary */
1212 n = k & 7;
1213 ZIPDUMPBITS(n);
1215 /* get the length and its complement */
1216 ZIPNEEDBITS(16)
1217 n = (b & 0xffff);
1218 ZIPDUMPBITS(16)
1219 ZIPNEEDBITS(16)
1220 if (n != ((~b) & 0xffff))
1221 return 1; /* error in compressed data */
1222 ZIPDUMPBITS(16)
1224 /* read and output the compressed data */
1225 while(n--)
1227 ZIPNEEDBITS(8)
1228 CAB(outbuf)[w++] = (cab_UBYTE)b;
1229 ZIPDUMPBITS(8)
1232 /* restore the globals from the locals */
1233 ZIP(window_posn) = w; /* restore global window pointer */
1234 ZIP(bb) = b; /* restore global bit buffer */
1235 ZIP(bk) = k;
1236 return 0;
1239 /******************************************************
1240 * fdi_Zipinflate_fixed (internal)
1242 static cab_LONG fdi_Zipinflate_fixed(fdi_decomp_state *decomp_state)
1244 struct Ziphuft *fixed_tl;
1245 struct Ziphuft *fixed_td;
1246 cab_LONG fixed_bl, fixed_bd;
1247 cab_LONG i; /* temporary variable */
1248 cab_ULONG *l;
1250 l = ZIP(ll);
1252 /* literal table */
1253 for(i = 0; i < 144; i++)
1254 l[i] = 8;
1255 for(; i < 256; i++)
1256 l[i] = 9;
1257 for(; i < 280; i++)
1258 l[i] = 7;
1259 for(; i < 288; i++) /* make a complete, but wrong code set */
1260 l[i] = 8;
1261 fixed_bl = 7;
1262 if((i = fdi_Ziphuft_build(l, 288, 257, Zipcplens, Zipcplext, &fixed_tl, &fixed_bl, decomp_state)))
1263 return i;
1265 /* distance table */
1266 for(i = 0; i < 30; i++) /* make an incomplete code set */
1267 l[i] = 5;
1268 fixed_bd = 5;
1269 if((i = fdi_Ziphuft_build(l, 30, 0, Zipcpdist, Zipcpdext, &fixed_td, &fixed_bd, decomp_state)) > 1)
1271 fdi_Ziphuft_free(CAB(fdi), fixed_tl);
1272 return i;
1275 /* decompress until an end-of-block code */
1276 i = fdi_Zipinflate_codes(fixed_tl, fixed_td, fixed_bl, fixed_bd, decomp_state);
1278 fdi_Ziphuft_free(CAB(fdi), fixed_td);
1279 fdi_Ziphuft_free(CAB(fdi), fixed_tl);
1280 return i;
1283 /**************************************************************
1284 * fdi_Zipinflate_dynamic (internal)
1286 static cab_LONG fdi_Zipinflate_dynamic(fdi_decomp_state *decomp_state)
1287 /* decompress an inflated type 2 (dynamic Huffman codes) block. */
1289 cab_LONG i; /* temporary variables */
1290 cab_ULONG j;
1291 cab_ULONG *ll;
1292 cab_ULONG l; /* last length */
1293 cab_ULONG m; /* mask for bit lengths table */
1294 cab_ULONG n; /* number of lengths to get */
1295 struct Ziphuft *tl; /* literal/length code table */
1296 struct Ziphuft *td; /* distance code table */
1297 cab_LONG bl; /* lookup bits for tl */
1298 cab_LONG bd; /* lookup bits for td */
1299 cab_ULONG nb; /* number of bit length codes */
1300 cab_ULONG nl; /* number of literal/length codes */
1301 cab_ULONG nd; /* number of distance codes */
1302 register cab_ULONG b; /* bit buffer */
1303 register cab_ULONG k; /* number of bits in bit buffer */
1305 /* make local bit buffer */
1306 b = ZIP(bb);
1307 k = ZIP(bk);
1308 ll = ZIP(ll);
1310 /* read in table lengths */
1311 ZIPNEEDBITS(5)
1312 nl = 257 + (b & 0x1f); /* number of literal/length codes */
1313 ZIPDUMPBITS(5)
1314 ZIPNEEDBITS(5)
1315 nd = 1 + (b & 0x1f); /* number of distance codes */
1316 ZIPDUMPBITS(5)
1317 ZIPNEEDBITS(4)
1318 nb = 4 + (b & 0xf); /* number of bit length codes */
1319 ZIPDUMPBITS(4)
1320 if(nl > 288 || nd > 32)
1321 return 1; /* bad lengths */
1323 /* read in bit-length-code lengths */
1324 for(j = 0; j < nb; j++)
1326 ZIPNEEDBITS(3)
1327 ll[Zipborder[j]] = b & 7;
1328 ZIPDUMPBITS(3)
1330 for(; j < 19; j++)
1331 ll[Zipborder[j]] = 0;
1333 /* build decoding table for trees--single level, 7 bit lookup */
1334 bl = 7;
1335 if((i = fdi_Ziphuft_build(ll, 19, 19, NULL, NULL, &tl, &bl, decomp_state)) != 0)
1337 if(i == 1)
1338 fdi_Ziphuft_free(CAB(fdi), tl);
1339 return i; /* incomplete code set */
1342 /* read in literal and distance code lengths */
1343 n = nl + nd;
1344 m = Zipmask[bl];
1345 i = l = 0;
1346 while((cab_ULONG)i < n)
1348 ZIPNEEDBITS((cab_ULONG)bl)
1349 j = (td = tl + (b & m))->b;
1350 ZIPDUMPBITS(j)
1351 j = td->v.n;
1352 if (j < 16) /* length of code in bits (0..15) */
1353 ll[i++] = l = j; /* save last length in l */
1354 else if (j == 16) /* repeat last length 3 to 6 times */
1356 ZIPNEEDBITS(2)
1357 j = 3 + (b & 3);
1358 ZIPDUMPBITS(2)
1359 if((cab_ULONG)i + j > n)
1360 return 1;
1361 while (j--)
1362 ll[i++] = l;
1364 else if (j == 17) /* 3 to 10 zero length codes */
1366 ZIPNEEDBITS(3)
1367 j = 3 + (b & 7);
1368 ZIPDUMPBITS(3)
1369 if ((cab_ULONG)i + j > n)
1370 return 1;
1371 while (j--)
1372 ll[i++] = 0;
1373 l = 0;
1375 else /* j == 18: 11 to 138 zero length codes */
1377 ZIPNEEDBITS(7)
1378 j = 11 + (b & 0x7f);
1379 ZIPDUMPBITS(7)
1380 if ((cab_ULONG)i + j > n)
1381 return 1;
1382 while (j--)
1383 ll[i++] = 0;
1384 l = 0;
1388 /* free decoding table for trees */
1389 fdi_Ziphuft_free(CAB(fdi), tl);
1391 /* restore the global bit buffer */
1392 ZIP(bb) = b;
1393 ZIP(bk) = k;
1395 /* build the decoding tables for literal/length and distance codes */
1396 bl = ZIPLBITS;
1397 if((i = fdi_Ziphuft_build(ll, nl, 257, Zipcplens, Zipcplext, &tl, &bl, decomp_state)) != 0)
1399 if(i == 1)
1400 fdi_Ziphuft_free(CAB(fdi), tl);
1401 return i; /* incomplete code set */
1403 bd = ZIPDBITS;
1404 fdi_Ziphuft_build(ll + nl, nd, 0, Zipcpdist, Zipcpdext, &td, &bd, decomp_state);
1406 /* decompress until an end-of-block code */
1407 if(fdi_Zipinflate_codes(tl, td, bl, bd, decomp_state))
1408 return 1;
1410 /* free the decoding tables, return */
1411 fdi_Ziphuft_free(CAB(fdi), tl);
1412 fdi_Ziphuft_free(CAB(fdi), td);
1413 return 0;
1416 /*****************************************************
1417 * fdi_Zipinflate_block (internal)
1419 static cab_LONG fdi_Zipinflate_block(cab_LONG *e, fdi_decomp_state *decomp_state) /* e == last block flag */
1420 { /* decompress an inflated block */
1421 cab_ULONG t; /* block type */
1422 register cab_ULONG b; /* bit buffer */
1423 register cab_ULONG k; /* number of bits in bit buffer */
1425 /* make local bit buffer */
1426 b = ZIP(bb);
1427 k = ZIP(bk);
1429 /* read in last block bit */
1430 ZIPNEEDBITS(1)
1431 *e = (cab_LONG)b & 1;
1432 ZIPDUMPBITS(1)
1434 /* read in block type */
1435 ZIPNEEDBITS(2)
1436 t = b & 3;
1437 ZIPDUMPBITS(2)
1439 /* restore the global bit buffer */
1440 ZIP(bb) = b;
1441 ZIP(bk) = k;
1443 /* inflate that block type */
1444 if(t == 2)
1445 return fdi_Zipinflate_dynamic(decomp_state);
1446 if(t == 0)
1447 return fdi_Zipinflate_stored(decomp_state);
1448 if(t == 1)
1449 return fdi_Zipinflate_fixed(decomp_state);
1450 /* bad block type */
1451 return 2;
1454 /****************************************************
1455 * ZIPfdi_decomp(internal)
1457 static int ZIPfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state)
1459 cab_LONG e; /* last block flag */
1461 TRACE("(inlen == %d, outlen == %d)\n", inlen, outlen);
1463 ZIP(inpos) = CAB(inbuf);
1464 ZIP(bb) = ZIP(bk) = ZIP(window_posn) = 0;
1465 if(outlen > ZIPWSIZE)
1466 return DECR_DATAFORMAT;
1468 /* CK = Chris Kirmse, official Microsoft purloiner */
1469 if(ZIP(inpos)[0] != 0x43 || ZIP(inpos)[1] != 0x4B)
1470 return DECR_ILLEGALDATA;
1471 ZIP(inpos) += 2;
1473 do {
1474 if(fdi_Zipinflate_block(&e, decomp_state))
1475 return DECR_ILLEGALDATA;
1476 } while(!e);
1478 /* return success */
1479 return DECR_OK;
1482 /*******************************************************************
1483 * QTMfdi_decomp(internal)
1485 static int QTMfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state)
1487 cab_UBYTE *inpos = CAB(inbuf);
1488 cab_UBYTE *window = QTM(window);
1489 cab_UBYTE *runsrc, *rundest;
1490 cab_ULONG window_posn = QTM(window_posn);
1491 cab_ULONG window_size = QTM(window_size);
1493 /* used by bitstream macros */
1494 register int bitsleft, bitrun, bitsneed;
1495 register cab_ULONG bitbuf;
1497 /* used by GET_SYMBOL */
1498 cab_ULONG range;
1499 cab_UWORD symf;
1500 int i;
1502 int extra, togo = outlen, match_length = 0, copy_length;
1503 cab_UBYTE selector, sym;
1504 cab_ULONG match_offset = 0;
1506 cab_UWORD H = 0xFFFF, L = 0, C;
1508 TRACE("(inlen == %d, outlen == %d)\n", inlen, outlen);
1510 /* read initial value of C */
1511 Q_INIT_BITSTREAM;
1512 Q_READ_BITS(C, 16);
1514 /* apply 2^x-1 mask */
1515 window_posn &= window_size - 1;
1516 /* runs can't straddle the window wraparound */
1517 if ((window_posn + togo) > window_size) {
1518 TRACE("straddled run\n");
1519 return DECR_DATAFORMAT;
1522 while (togo > 0) {
1523 GET_SYMBOL(model7, selector);
1524 switch (selector) {
1525 case 0:
1526 GET_SYMBOL(model00, sym); window[window_posn++] = sym; togo--;
1527 break;
1528 case 1:
1529 GET_SYMBOL(model40, sym); window[window_posn++] = sym; togo--;
1530 break;
1531 case 2:
1532 GET_SYMBOL(model80, sym); window[window_posn++] = sym; togo--;
1533 break;
1534 case 3:
1535 GET_SYMBOL(modelC0, sym); window[window_posn++] = sym; togo--;
1536 break;
1538 case 4:
1539 /* selector 4 = fixed length of 3 */
1540 GET_SYMBOL(model4, sym);
1541 Q_READ_BITS(extra, CAB(q_extra_bits)[sym]);
1542 match_offset = CAB(q_position_base)[sym] + extra + 1;
1543 match_length = 3;
1544 break;
1546 case 5:
1547 /* selector 5 = fixed length of 4 */
1548 GET_SYMBOL(model5, sym);
1549 Q_READ_BITS(extra, CAB(q_extra_bits)[sym]);
1550 match_offset = CAB(q_position_base)[sym] + extra + 1;
1551 match_length = 4;
1552 break;
1554 case 6:
1555 /* selector 6 = variable length */
1556 GET_SYMBOL(model6len, sym);
1557 Q_READ_BITS(extra, CAB(q_length_extra)[sym]);
1558 match_length = CAB(q_length_base)[sym] + extra + 5;
1559 GET_SYMBOL(model6pos, sym);
1560 Q_READ_BITS(extra, CAB(q_extra_bits)[sym]);
1561 match_offset = CAB(q_position_base)[sym] + extra + 1;
1562 break;
1564 default:
1565 TRACE("Selector is bogus\n");
1566 return DECR_ILLEGALDATA;
1569 /* if this is a match */
1570 if (selector >= 4) {
1571 rundest = window + window_posn;
1572 togo -= match_length;
1574 /* copy any wrapped around source data */
1575 if (window_posn >= match_offset) {
1576 /* no wrap */
1577 runsrc = rundest - match_offset;
1578 } else {
1579 runsrc = rundest + (window_size - match_offset);
1580 copy_length = match_offset - window_posn;
1581 if (copy_length < match_length) {
1582 match_length -= copy_length;
1583 window_posn += copy_length;
1584 while (copy_length-- > 0) *rundest++ = *runsrc++;
1585 runsrc = window;
1588 window_posn += match_length;
1590 /* copy match data - no worries about destination wraps */
1591 while (match_length-- > 0) *rundest++ = *runsrc++;
1593 } /* while (togo > 0) */
1595 if (togo != 0) {
1596 TRACE("Frame overflow, this_run = %d\n", togo);
1597 return DECR_ILLEGALDATA;
1600 memcpy(CAB(outbuf), window + ((!window_posn) ? window_size : window_posn) -
1601 outlen, outlen);
1603 QTM(window_posn) = window_posn;
1604 return DECR_OK;
1607 /************************************************************
1608 * fdi_lzx_read_lens (internal)
1610 static int fdi_lzx_read_lens(cab_UBYTE *lens, cab_ULONG first, cab_ULONG last, struct lzx_bits *lb,
1611 fdi_decomp_state *decomp_state) {
1612 cab_ULONG i,j, x,y;
1613 int z;
1615 register cab_ULONG bitbuf = lb->bb;
1616 register int bitsleft = lb->bl;
1617 cab_UBYTE *inpos = lb->ip;
1618 cab_UWORD *hufftbl;
1620 for (x = 0; x < 20; x++) {
1621 READ_BITS(y, 4);
1622 LENTABLE(PRETREE)[x] = y;
1624 BUILD_TABLE(PRETREE);
1626 for (x = first; x < last; ) {
1627 READ_HUFFSYM(PRETREE, z);
1628 if (z == 17) {
1629 READ_BITS(y, 4); y += 4;
1630 while (y--) lens[x++] = 0;
1632 else if (z == 18) {
1633 READ_BITS(y, 5); y += 20;
1634 while (y--) lens[x++] = 0;
1636 else if (z == 19) {
1637 READ_BITS(y, 1); y += 4;
1638 READ_HUFFSYM(PRETREE, z);
1639 z = lens[x] - z; if (z < 0) z += 17;
1640 while (y--) lens[x++] = z;
1642 else {
1643 z = lens[x] - z; if (z < 0) z += 17;
1644 lens[x++] = z;
1648 lb->bb = bitbuf;
1649 lb->bl = bitsleft;
1650 lb->ip = inpos;
1651 return 0;
1654 /*******************************************************
1655 * LZXfdi_decomp(internal)
1657 static int LZXfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state) {
1658 cab_UBYTE *inpos = CAB(inbuf);
1659 const cab_UBYTE *endinp = inpos + inlen;
1660 cab_UBYTE *window = LZX(window);
1661 cab_UBYTE *runsrc, *rundest;
1662 cab_UWORD *hufftbl; /* used in READ_HUFFSYM macro as chosen decoding table */
1664 cab_ULONG window_posn = LZX(window_posn);
1665 cab_ULONG window_size = LZX(window_size);
1666 cab_ULONG R0 = LZX(R0);
1667 cab_ULONG R1 = LZX(R1);
1668 cab_ULONG R2 = LZX(R2);
1670 register cab_ULONG bitbuf;
1671 register int bitsleft;
1672 cab_ULONG match_offset, i,j,k; /* ijk used in READ_HUFFSYM macro */
1673 struct lzx_bits lb; /* used in READ_LENGTHS macro */
1675 int togo = outlen, this_run, main_element, aligned_bits;
1676 int match_length, copy_length, length_footer, extra, verbatim_bits;
1678 TRACE("(inlen == %d, outlen == %d)\n", inlen, outlen);
1680 INIT_BITSTREAM;
1682 /* read header if necessary */
1683 if (!LZX(header_read)) {
1684 i = j = 0;
1685 READ_BITS(k, 1); if (k) { READ_BITS(i,16); READ_BITS(j,16); }
1686 LZX(intel_filesize) = (i << 16) | j; /* or 0 if not encoded */
1687 LZX(header_read) = 1;
1690 /* main decoding loop */
1691 while (togo > 0) {
1692 /* last block finished, new block expected */
1693 if (LZX(block_remaining) == 0) {
1694 if (LZX(block_type) == LZX_BLOCKTYPE_UNCOMPRESSED) {
1695 if (LZX(block_length) & 1) inpos++; /* realign bitstream to word */
1696 INIT_BITSTREAM;
1699 READ_BITS(LZX(block_type), 3);
1700 READ_BITS(i, 16);
1701 READ_BITS(j, 8);
1702 LZX(block_remaining) = LZX(block_length) = (i << 8) | j;
1704 switch (LZX(block_type)) {
1705 case LZX_BLOCKTYPE_ALIGNED:
1706 for (i = 0; i < 8; i++) { READ_BITS(j, 3); LENTABLE(ALIGNED)[i] = j; }
1707 BUILD_TABLE(ALIGNED);
1708 /* rest of aligned header is same as verbatim */
1710 case LZX_BLOCKTYPE_VERBATIM:
1711 READ_LENGTHS(MAINTREE, 0, 256, fdi_lzx_read_lens);
1712 READ_LENGTHS(MAINTREE, 256, LZX(main_elements), fdi_lzx_read_lens);
1713 BUILD_TABLE(MAINTREE);
1714 if (LENTABLE(MAINTREE)[0xE8] != 0) LZX(intel_started) = 1;
1716 READ_LENGTHS(LENGTH, 0, LZX_NUM_SECONDARY_LENGTHS, fdi_lzx_read_lens);
1717 BUILD_TABLE(LENGTH);
1718 break;
1720 case LZX_BLOCKTYPE_UNCOMPRESSED:
1721 LZX(intel_started) = 1; /* because we can't assume otherwise */
1722 ENSURE_BITS(16); /* get up to 16 pad bits into the buffer */
1723 if (bitsleft > 16) inpos -= 2; /* and align the bitstream! */
1724 R0 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
1725 R1 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
1726 R2 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
1727 break;
1729 default:
1730 return DECR_ILLEGALDATA;
1734 /* buffer exhaustion check */
1735 if (inpos > endinp) {
1736 /* it's possible to have a file where the next run is less than
1737 * 16 bits in size. In this case, the READ_HUFFSYM() macro used
1738 * in building the tables will exhaust the buffer, so we should
1739 * allow for this, but not allow those accidentally read bits to
1740 * be used (so we check that there are at least 16 bits
1741 * remaining - in this boundary case they aren't really part of
1742 * the compressed data)
1744 if (inpos > (endinp+2) || bitsleft < 16) return DECR_ILLEGALDATA;
1747 while ((this_run = LZX(block_remaining)) > 0 && togo > 0) {
1748 if (this_run > togo) this_run = togo;
1749 togo -= this_run;
1750 LZX(block_remaining) -= this_run;
1752 /* apply 2^x-1 mask */
1753 window_posn &= window_size - 1;
1754 /* runs can't straddle the window wraparound */
1755 if ((window_posn + this_run) > window_size)
1756 return DECR_DATAFORMAT;
1758 switch (LZX(block_type)) {
1760 case LZX_BLOCKTYPE_VERBATIM:
1761 while (this_run > 0) {
1762 READ_HUFFSYM(MAINTREE, main_element);
1764 if (main_element < LZX_NUM_CHARS) {
1765 /* literal: 0 to LZX_NUM_CHARS-1 */
1766 window[window_posn++] = main_element;
1767 this_run--;
1769 else {
1770 /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
1771 main_element -= LZX_NUM_CHARS;
1773 match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
1774 if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
1775 READ_HUFFSYM(LENGTH, length_footer);
1776 match_length += length_footer;
1778 match_length += LZX_MIN_MATCH;
1780 match_offset = main_element >> 3;
1782 if (match_offset > 2) {
1783 /* not repeated offset */
1784 if (match_offset != 3) {
1785 extra = CAB(extra_bits)[match_offset];
1786 READ_BITS(verbatim_bits, extra);
1787 match_offset = CAB(lzx_position_base)[match_offset]
1788 - 2 + verbatim_bits;
1790 else {
1791 match_offset = 1;
1794 /* update repeated offset LRU queue */
1795 R2 = R1; R1 = R0; R0 = match_offset;
1797 else if (match_offset == 0) {
1798 match_offset = R0;
1800 else if (match_offset == 1) {
1801 match_offset = R1;
1802 R1 = R0; R0 = match_offset;
1804 else /* match_offset == 2 */ {
1805 match_offset = R2;
1806 R2 = R0; R0 = match_offset;
1809 rundest = window + window_posn;
1810 this_run -= match_length;
1812 /* copy any wrapped around source data */
1813 if (window_posn >= match_offset) {
1814 /* no wrap */
1815 runsrc = rundest - match_offset;
1816 } else {
1817 runsrc = rundest + (window_size - match_offset);
1818 copy_length = match_offset - window_posn;
1819 if (copy_length < match_length) {
1820 match_length -= copy_length;
1821 window_posn += copy_length;
1822 while (copy_length-- > 0) *rundest++ = *runsrc++;
1823 runsrc = window;
1826 window_posn += match_length;
1828 /* copy match data - no worries about destination wraps */
1829 while (match_length-- > 0) *rundest++ = *runsrc++;
1832 break;
1834 case LZX_BLOCKTYPE_ALIGNED:
1835 while (this_run > 0) {
1836 READ_HUFFSYM(MAINTREE, main_element);
1838 if (main_element < LZX_NUM_CHARS) {
1839 /* literal: 0 to LZX_NUM_CHARS-1 */
1840 window[window_posn++] = main_element;
1841 this_run--;
1843 else {
1844 /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
1845 main_element -= LZX_NUM_CHARS;
1847 match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
1848 if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
1849 READ_HUFFSYM(LENGTH, length_footer);
1850 match_length += length_footer;
1852 match_length += LZX_MIN_MATCH;
1854 match_offset = main_element >> 3;
1856 if (match_offset > 2) {
1857 /* not repeated offset */
1858 extra = CAB(extra_bits)[match_offset];
1859 match_offset = CAB(lzx_position_base)[match_offset] - 2;
1860 if (extra > 3) {
1861 /* verbatim and aligned bits */
1862 extra -= 3;
1863 READ_BITS(verbatim_bits, extra);
1864 match_offset += (verbatim_bits << 3);
1865 READ_HUFFSYM(ALIGNED, aligned_bits);
1866 match_offset += aligned_bits;
1868 else if (extra == 3) {
1869 /* aligned bits only */
1870 READ_HUFFSYM(ALIGNED, aligned_bits);
1871 match_offset += aligned_bits;
1873 else if (extra > 0) { /* extra==1, extra==2 */
1874 /* verbatim bits only */
1875 READ_BITS(verbatim_bits, extra);
1876 match_offset += verbatim_bits;
1878 else /* extra == 0 */ {
1879 /* ??? */
1880 match_offset = 1;
1883 /* update repeated offset LRU queue */
1884 R2 = R1; R1 = R0; R0 = match_offset;
1886 else if (match_offset == 0) {
1887 match_offset = R0;
1889 else if (match_offset == 1) {
1890 match_offset = R1;
1891 R1 = R0; R0 = match_offset;
1893 else /* match_offset == 2 */ {
1894 match_offset = R2;
1895 R2 = R0; R0 = match_offset;
1898 rundest = window + window_posn;
1899 this_run -= match_length;
1901 /* copy any wrapped around source data */
1902 if (window_posn >= match_offset) {
1903 /* no wrap */
1904 runsrc = rundest - match_offset;
1905 } else {
1906 runsrc = rundest + (window_size - match_offset);
1907 copy_length = match_offset - window_posn;
1908 if (copy_length < match_length) {
1909 match_length -= copy_length;
1910 window_posn += copy_length;
1911 while (copy_length-- > 0) *rundest++ = *runsrc++;
1912 runsrc = window;
1915 window_posn += match_length;
1917 /* copy match data - no worries about destination wraps */
1918 while (match_length-- > 0) *rundest++ = *runsrc++;
1921 break;
1923 case LZX_BLOCKTYPE_UNCOMPRESSED:
1924 if ((inpos + this_run) > endinp) return DECR_ILLEGALDATA;
1925 memcpy(window + window_posn, inpos, (size_t) this_run);
1926 inpos += this_run; window_posn += this_run;
1927 break;
1929 default:
1930 return DECR_ILLEGALDATA; /* might as well */
1936 if (togo != 0) return DECR_ILLEGALDATA;
1937 memcpy(CAB(outbuf), window + ((!window_posn) ? window_size : window_posn) -
1938 outlen, (size_t) outlen);
1940 LZX(window_posn) = window_posn;
1941 LZX(R0) = R0;
1942 LZX(R1) = R1;
1943 LZX(R2) = R2;
1945 /* intel E8 decoding */
1946 if ((LZX(frames_read)++ < 32768) && LZX(intel_filesize) != 0) {
1947 if (outlen <= 6 || !LZX(intel_started)) {
1948 LZX(intel_curpos) += outlen;
1950 else {
1951 cab_UBYTE *data = CAB(outbuf);
1952 cab_UBYTE *dataend = data + outlen - 10;
1953 cab_LONG curpos = LZX(intel_curpos);
1954 cab_LONG filesize = LZX(intel_filesize);
1955 cab_LONG abs_off, rel_off;
1957 LZX(intel_curpos) = curpos + outlen;
1959 while (data < dataend) {
1960 if (*data++ != 0xE8) { curpos++; continue; }
1961 abs_off = data[0] | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);
1962 if ((abs_off >= -curpos) && (abs_off < filesize)) {
1963 rel_off = (abs_off >= 0) ? abs_off - curpos : abs_off + filesize;
1964 data[0] = (cab_UBYTE) rel_off;
1965 data[1] = (cab_UBYTE) (rel_off >> 8);
1966 data[2] = (cab_UBYTE) (rel_off >> 16);
1967 data[3] = (cab_UBYTE) (rel_off >> 24);
1969 data += 4;
1970 curpos += 5;
1974 return DECR_OK;
1977 /**********************************************************
1978 * fdi_decomp (internal)
1980 * Decompress the requested number of bytes. If savemode is zero,
1981 * do not save the output anywhere, just plow through blocks until we
1982 * reach the specified (uncompressed) distance from the starting point,
1983 * and remember the position of the cabfile pointer (and which cabfile)
1984 * after we are done; otherwise, save the data out to CAB(filehf),
1985 * decompressing the requested number of bytes and writing them out. This
1986 * is also where we jump to additional cabinets in the case of split
1987 * cab's, and provide (some of) the NEXT_CABINET notification semantics.
1989 static int fdi_decomp(const struct fdi_file *fi, int savemode, fdi_decomp_state *decomp_state,
1990 char *pszCabPath, PFNFDINOTIFY pfnfdin, void *pvUser)
1992 cab_ULONG bytes = savemode ? fi->length : fi->offset - CAB(offset);
1993 cab_UBYTE buf[cfdata_SIZEOF], *data;
1994 cab_UWORD inlen, len, outlen, cando;
1995 cab_ULONG cksum;
1996 cab_LONG err;
1997 fdi_decomp_state *cab = (savemode && CAB(decomp_cab)) ? CAB(decomp_cab) : decomp_state;
1999 TRACE("(fi == ^%p, savemode == %d, bytes == %d)\n", fi, savemode, bytes);
2001 while (bytes > 0) {
2002 /* cando = the max number of bytes we can do */
2003 cando = CAB(outlen);
2004 if (cando > bytes) cando = bytes;
2006 /* if cando != 0 */
2007 if (cando && savemode)
2008 CAB(fdi)->write(CAB(filehf), CAB(outpos), cando);
2010 CAB(outpos) += cando;
2011 CAB(outlen) -= cando;
2012 bytes -= cando; if (!bytes) break;
2014 /* we only get here if we emptied the output buffer */
2016 /* read data header + data */
2017 inlen = outlen = 0;
2018 while (outlen == 0) {
2019 /* read the block header, skip the reserved part */
2020 if (CAB(fdi)->read(cab->cabhf, buf, cfdata_SIZEOF) != cfdata_SIZEOF)
2021 return DECR_INPUT;
2023 if (CAB(fdi)->seek(cab->cabhf, cab->mii.block_resv, SEEK_CUR) == -1)
2024 return DECR_INPUT;
2026 /* we shouldn't get blocks over CAB_INPUTMAX in size */
2027 data = CAB(inbuf) + inlen;
2028 len = EndGetI16(buf+cfdata_CompressedSize);
2029 inlen += len;
2030 if (inlen > CAB_INPUTMAX) return DECR_INPUT;
2031 if (CAB(fdi)->read(cab->cabhf, data, len) != len)
2032 return DECR_INPUT;
2034 /* clear two bytes after read-in data */
2035 data[len+1] = data[len+2] = 0;
2037 /* perform checksum test on the block (if one is stored) */
2038 cksum = EndGetI32(buf+cfdata_CheckSum);
2039 if (cksum && cksum != checksum(buf+4, 4, checksum(data, len, 0)))
2040 return DECR_CHECKSUM; /* checksum is wrong */
2042 outlen = EndGetI16(buf+cfdata_UncompressedSize);
2044 /* outlen=0 means this block was the last contiguous part
2045 of a split block, continued in the next cabinet */
2046 if (outlen == 0) {
2047 int pathlen, filenamelen, idx, i;
2048 INT_PTR cabhf;
2049 char fullpath[MAX_PATH], userpath[256];
2050 FDINOTIFICATION fdin;
2051 FDICABINETINFO fdici;
2052 char emptystring = '\0';
2053 cab_UBYTE buf2[64];
2054 int success = FALSE;
2055 struct fdi_folder *fol = NULL, *linkfol = NULL;
2056 struct fdi_file *file = NULL, *linkfile = NULL;
2058 tryanothercab:
2060 /* set up the next decomp_state... */
2061 if (!(cab->next)) {
2062 if (!cab->mii.hasnext) return DECR_INPUT;
2064 if (!((cab->next = CAB(fdi)->alloc(sizeof(fdi_decomp_state)))))
2065 return DECR_NOMEMORY;
2067 ZeroMemory(cab->next, sizeof(fdi_decomp_state));
2069 /* copy pszCabPath to userpath */
2070 ZeroMemory(userpath, 256);
2071 pathlen = (pszCabPath) ? strlen(pszCabPath) : 0;
2072 if (pathlen) {
2073 if (pathlen < 256) {
2074 for (i = 0; i <= pathlen; i++)
2075 userpath[i] = pszCabPath[i];
2076 } /* else we are in a weird place... let's leave it blank and see if the user fixes it */
2079 /* initial fdintNEXT_CABINET notification */
2080 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2081 fdin.psz1 = (cab->mii.nextname) ? cab->mii.nextname : &emptystring;
2082 fdin.psz2 = (cab->mii.nextinfo) ? cab->mii.nextinfo : &emptystring;
2083 fdin.psz3 = &userpath[0];
2084 fdin.fdie = FDIERROR_NONE;
2085 fdin.pv = pvUser;
2087 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2089 do {
2091 pathlen = strlen(userpath);
2092 filenamelen = (cab->mii.nextname) ? strlen(cab->mii.nextname) : 0;
2094 /* slight overestimation here to save CPU cycles in the developer's brain */
2095 if ((pathlen + filenamelen + 3) > MAX_PATH) {
2096 ERR("MAX_PATH exceeded.\n");
2097 return DECR_ILLEGALDATA;
2100 /* paste the path and filename together */
2101 idx = 0;
2102 if (pathlen) {
2103 for (i = 0; i < pathlen; i++) fullpath[idx++] = userpath[i];
2104 if (fullpath[idx - 1] != '\\') fullpath[idx++] = '\\';
2106 if (filenamelen) for (i = 0; i < filenamelen; i++) fullpath[idx++] = cab->mii.nextname[i];
2107 fullpath[idx] = '\0';
2109 TRACE("full cab path/file name: %s\n", debugstr_a(fullpath));
2111 /* try to get a handle to the cabfile */
2112 cabhf = CAB(fdi)->open(fullpath, _O_RDONLY|_O_BINARY, _S_IREAD | _S_IWRITE);
2113 if (cabhf == -1) {
2114 /* no file. allow the user to try again */
2115 fdin.fdie = FDIERROR_CABINET_NOT_FOUND;
2116 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2117 continue;
2120 if (cabhf == 0) {
2121 ERR("PFDI_OPEN returned zero for %s.\n", fullpath);
2122 fdin.fdie = FDIERROR_CABINET_NOT_FOUND;
2123 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2124 continue;
2127 /* check if it's really a cabfile. Note that this doesn't implement the bug */
2128 if (!FDI_read_entries(CAB(fdi), cabhf, &fdici, &(cab->next->mii))) {
2129 WARN("FDIIsCabinet failed.\n");
2130 CAB(fdi)->close(cabhf);
2131 fdin.fdie = FDIERROR_NOT_A_CABINET;
2132 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2133 continue;
2136 if ((fdici.setID != cab->setID) || (fdici.iCabinet != (cab->iCabinet + 1))) {
2137 WARN("Wrong Cabinet.\n");
2138 CAB(fdi)->close(cabhf);
2139 fdin.fdie = FDIERROR_WRONG_CABINET;
2140 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2141 continue;
2144 break;
2146 } while (1);
2148 /* cabinet notification */
2149 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2150 fdin.setID = fdici.setID;
2151 fdin.iCabinet = fdici.iCabinet;
2152 fdin.pv = pvUser;
2153 fdin.psz1 = (cab->next->mii.nextname) ? cab->next->mii.nextname : &emptystring;
2154 fdin.psz2 = (cab->next->mii.nextinfo) ? cab->next->mii.nextinfo : &emptystring;
2155 fdin.psz3 = pszCabPath;
2157 if (((*pfnfdin)(fdintCABINET_INFO, &fdin))) return DECR_USERABORT;
2159 cab->next->setID = fdici.setID;
2160 cab->next->iCabinet = fdici.iCabinet;
2161 cab->next->fdi = CAB(fdi);
2162 cab->next->filehf = CAB(filehf);
2163 cab->next->cabhf = cabhf;
2164 cab->next->decompress = CAB(decompress); /* crude, but unused anyhow */
2166 cab = cab->next; /* advance to the next cabinet */
2168 /* read folders */
2169 for (i = 0; i < fdici.cFolders; i++) {
2170 if (CAB(fdi)->read(cab->cabhf, buf2, cffold_SIZEOF) != cffold_SIZEOF)
2171 return DECR_INPUT;
2173 if (cab->mii.folder_resv > 0)
2174 CAB(fdi)->seek(cab->cabhf, cab->mii.folder_resv, SEEK_CUR);
2176 fol = CAB(fdi)->alloc(sizeof(struct fdi_folder));
2177 if (!fol) {
2178 ERR("out of memory!\n");
2179 return DECR_NOMEMORY;
2181 ZeroMemory(fol, sizeof(struct fdi_folder));
2182 if (!(cab->firstfol)) cab->firstfol = fol;
2184 fol->offset = (cab_off_t) EndGetI32(buf2+cffold_DataOffset);
2185 fol->num_blocks = EndGetI16(buf2+cffold_NumBlocks);
2186 fol->comp_type = EndGetI16(buf2+cffold_CompType);
2188 if (linkfol)
2189 linkfol->next = fol;
2190 linkfol = fol;
2193 /* read files */
2194 for (i = 0; i < fdici.cFiles; i++) {
2195 if (CAB(fdi)->read(cab->cabhf, buf2, cffile_SIZEOF) != cffile_SIZEOF)
2196 return DECR_INPUT;
2198 file = CAB(fdi)->alloc(sizeof(struct fdi_file));
2199 if (!file) {
2200 ERR("out of memory!\n");
2201 return DECR_NOMEMORY;
2203 ZeroMemory(file, sizeof(struct fdi_file));
2204 if (!(cab->firstfile)) cab->firstfile = file;
2206 file->length = EndGetI32(buf2+cffile_UncompressedSize);
2207 file->offset = EndGetI32(buf2+cffile_FolderOffset);
2208 file->index = EndGetI16(buf2+cffile_FolderIndex);
2209 file->time = EndGetI16(buf2+cffile_Time);
2210 file->date = EndGetI16(buf2+cffile_Date);
2211 file->attribs = EndGetI16(buf2+cffile_Attribs);
2212 file->filename = FDI_read_string(CAB(fdi), cab->cabhf, fdici.cbCabinet);
2214 if (!file->filename) return DECR_INPUT;
2216 if (linkfile)
2217 linkfile->next = file;
2218 linkfile = file;
2221 } else
2222 cab = cab->next; /* advance to the next cabinet */
2224 /* iterate files -- if we encounter the continued file, process it --
2225 otherwise, jump to the label above and keep looking */
2227 for (file = cab->firstfile; (file); file = file->next) {
2228 if ((file->index & cffileCONTINUED_FROM_PREV) == cffileCONTINUED_FROM_PREV) {
2229 /* check to ensure a real match */
2230 if (lstrcmpiA(fi->filename, file->filename) == 0) {
2231 success = TRUE;
2232 if (CAB(fdi)->seek(cab->cabhf, cab->firstfol->offset, SEEK_SET) == -1)
2233 return DECR_INPUT;
2234 break;
2238 if (!success) goto tryanothercab; /* FIXME: shouldn't this trigger
2239 "Wrong Cabinet" notification? */
2243 /* decompress block */
2244 if ((err = CAB(decompress)(inlen, outlen, decomp_state)))
2245 return err;
2246 CAB(outlen) = outlen;
2247 CAB(outpos) = CAB(outbuf);
2250 CAB(decomp_cab) = cab;
2251 return DECR_OK;
2254 static void free_decompression_temps(FDI_Int *fdi, const struct fdi_folder *fol,
2255 fdi_decomp_state *decomp_state)
2257 switch (fol->comp_type & cffoldCOMPTYPE_MASK) {
2258 case cffoldCOMPTYPE_LZX:
2259 if (LZX(window)) {
2260 fdi->free(LZX(window));
2261 LZX(window) = NULL;
2263 break;
2264 case cffoldCOMPTYPE_QUANTUM:
2265 if (QTM(window)) {
2266 fdi->free(QTM(window));
2267 QTM(window) = NULL;
2269 break;
2273 static void free_decompression_mem(FDI_Int *fdi, fdi_decomp_state *decomp_state)
2275 struct fdi_folder *fol;
2276 while (decomp_state) {
2277 fdi_decomp_state *prev_fds;
2279 fdi->close(CAB(cabhf));
2281 /* free the storage remembered by mii */
2282 if (CAB(mii).nextname) fdi->free(CAB(mii).nextname);
2283 if (CAB(mii).nextinfo) fdi->free(CAB(mii).nextinfo);
2284 if (CAB(mii).prevname) fdi->free(CAB(mii).prevname);
2285 if (CAB(mii).previnfo) fdi->free(CAB(mii).previnfo);
2287 while (CAB(firstfol)) {
2288 fol = CAB(firstfol);
2289 CAB(firstfol) = CAB(firstfol)->next;
2290 fdi->free(fol);
2292 while (CAB(firstfile)) {
2293 struct fdi_file *file = CAB(firstfile);
2294 if (file->filename) fdi->free(file->filename);
2295 CAB(firstfile) = CAB(firstfile)->next;
2296 fdi->free(file);
2298 prev_fds = decomp_state;
2299 decomp_state = CAB(next);
2300 fdi->free(prev_fds);
2304 /***********************************************************************
2305 * FDICopy (CABINET.22)
2307 * Iterates through the files in the Cabinet file indicated by name and
2308 * file-location. May chain forward to additional cabinets (typically
2309 * only one) if files which begin in this Cabinet are continued in another
2310 * cabinet. For each file which is partially contained in this cabinet,
2311 * and partially contained in a prior cabinet, provides fdintPARTIAL_FILE
2312 * notification to the pfnfdin callback. For each file which begins in
2313 * this cabinet, fdintCOPY_FILE notification is provided to the pfnfdin
2314 * callback, and the file is optionally decompressed and saved to disk.
2315 * Notification is not provided for files which are not at least partially
2316 * contained in the specified cabinet file.
2318 * See below for a thorough explanation of the various notification
2319 * callbacks.
2321 * PARAMS
2322 * hfdi [I] An HFDI from FDICreate
2323 * pszCabinet [I] C-style string containing the filename of the cabinet
2324 * pszCabPath [I] C-style string containing the file path of the cabinet
2325 * flags [I] "Decoder parameters". Ignored. Suggested value: 0.
2326 * pfnfdin [I] Pointer to a notification function. See CALLBACKS below.
2327 * pfnfdid [I] Pointer to a decryption function. Ignored. Suggested
2328 * value: NULL.
2329 * pvUser [I] arbitrary void * value which is passed to callbacks.
2331 * RETURNS
2332 * TRUE if successful.
2333 * FALSE if unsuccessful (error information is provided in the ERF structure
2334 * associated with the provided decompression handle by FDICreate).
2336 * CALLBACKS
2338 * Two pointers to callback functions are provided as parameters to FDICopy:
2339 * pfnfdin(of type PFNFDINOTIFY), and pfnfdid (of type PFNFDIDECRYPT). These
2340 * types are as follows:
2342 * typedef INT_PTR (__cdecl *PFNFDINOTIFY) ( FDINOTIFICATIONTYPE fdint,
2343 * PFDINOTIFICATION pfdin );
2345 * typedef int (__cdecl *PFNFDIDECRYPT) ( PFDIDECRYPT pfdid );
2347 * You can create functions of this type using the FNFDINOTIFY() and
2348 * FNFDIDECRYPT() macros, respectively. For example:
2350 * FNFDINOTIFY(mycallback) {
2351 * / * use variables fdint and pfdin to process notification * /
2354 * The second callback, which could be used for decrypting encrypted data,
2355 * is not used at all.
2357 * Each notification informs the user of some event which has occurred during
2358 * decompression of the cabinet file; each notification is also an opportunity
2359 * for the callee to abort decompression. The information provided to the
2360 * callback and the meaning of the callback's return value vary drastically
2361 * across the various types of notification. The type of notification is the
2362 * fdint parameter; all other information is provided to the callback in
2363 * notification-specific parts of the FDINOTIFICATION structure pointed to by
2364 * pfdin. The only part of that structure which is assigned for every callback
2365 * is the pv element, which contains the arbitrary value which was passed to
2366 * FDICopy in the pvUser argument (psz1 is also used each time, but its meaning
2367 * is highly dependent on fdint).
2369 * If you encounter unknown notifications, you should return zero if you want
2370 * decompression to continue (or -1 to abort). All strings used in the
2371 * callbacks are regular C-style strings. Detailed descriptions of each
2372 * notification type follow:
2374 * fdintCABINET_INFO:
2376 * This is the first notification provided after calling FDICopy, and provides
2377 * the user with various information about the cabinet. Note that this is
2378 * called for each cabinet FDICopy opens, not just the first one. In the
2379 * structure pointed to by pfdin, psz1 contains a pointer to the name of the
2380 * next cabinet file in the set after the one just loaded (if any), psz2
2381 * contains a pointer to the name or "info" of the next disk, psz3
2382 * contains a pointer to the file-path of the current cabinet, setID
2383 * contains an arbitrary constant associated with this set of cabinet files,
2384 * and iCabinet contains the numerical index of the current cabinet within
2385 * that set. Return zero, or -1 to abort.
2387 * fdintPARTIAL_FILE:
2389 * This notification is provided when FDICopy encounters a part of a file
2390 * contained in this cabinet which is missing its beginning. Files can be
2391 * split across cabinets, so this is not necessarily an abnormality; it just
2392 * means that the file in question begins in another cabinet. No file
2393 * corresponding to this notification is extracted from the cabinet. In the
2394 * structure pointed to by pfdin, psz1 contains a pointer to the name of the
2395 * partial file, psz2 contains a pointer to the file name of the cabinet in
2396 * which this file begins, and psz3 contains a pointer to the disk name or
2397 * "info" of the cabinet where the file begins. Return zero, or -1 to abort.
2399 * fdintCOPY_FILE:
2401 * This notification is provided when FDICopy encounters a file which starts
2402 * in the cabinet file, provided to FDICopy in pszCabinet. (FDICopy will not
2403 * look for files in cabinets after the first one). One notification will be
2404 * sent for each such file, before the file is decompressed. By returning
2405 * zero, the callback can instruct FDICopy to skip the file. In the structure
2406 * pointed to by pfdin, psz1 contains a pointer to the file's name, cb contains
2407 * the size of the file (uncompressed), attribs contains the file attributes,
2408 * and date and time contain the date and time of the file. attributes, date,
2409 * and time are of the 16-bit ms-dos variety. Return -1 to abort decompression
2410 * for the entire cabinet, 0 to skip just this file but continue scanning the
2411 * cabinet for more files, or an FDIClose()-compatible file-handle.
2413 * fdintCLOSE_FILE_INFO:
2415 * This notification is important, don't forget to implement it. This
2416 * notification indicates that a file has been successfully uncompressed and
2417 * written to disk. Upon receipt of this notification, the callee is expected
2418 * to close the file handle, to set the attributes and date/time of the
2419 * closed file, and possibly to execute the file. In the structure pointed to
2420 * by pfdin, psz1 contains a pointer to the name of the file, hf will be the
2421 * open file handle (close it), cb contains 1 or zero, indicating respectively
2422 * that the callee should or should not execute the file, and date, time
2423 * and attributes will be set as in fdintCOPY_FILE. Bizarrely, the Cabinet SDK
2424 * specifies that _A_EXEC will be xor'ed out of attributes! wine does not do
2425 * do so. Return TRUE, or FALSE to abort decompression.
2427 * fdintNEXT_CABINET:
2429 * This notification is called when FDICopy must load in another cabinet. This
2430 * can occur when a file's data is "split" across multiple cabinets. The
2431 * callee has the opportunity to request that FDICopy look in a different file
2432 * path for the specified cabinet file, by writing that data into a provided
2433 * buffer (see below for more information). This notification will be received
2434 * more than once per-cabinet in the instance that FDICopy failed to find a
2435 * valid cabinet at the location specified by the first per-cabinet
2436 * fdintNEXT_CABINET notification. In such instances, the fdie element of the
2437 * structure pointed to by pfdin indicates the error which prevented FDICopy
2438 * from proceeding successfully. Return zero to indicate success, or -1 to
2439 * indicate failure and abort FDICopy.
2441 * Upon receipt of this notification, the structure pointed to by pfdin will
2442 * contain the following values: psz1 pointing to the name of the cabinet
2443 * which FDICopy is attempting to open, psz2 pointing to the name ("info") of
2444 * the next disk, psz3 pointing to the presumed file-location of the cabinet,
2445 * and fdie containing either FDIERROR_NONE, or one of the following:
2447 * FDIERROR_CABINET_NOT_FOUND, FDIERROR_NOT_A_CABINET,
2448 * FDIERROR_UNKNOWN_CABINET_VERSION, FDIERROR_CORRUPT_CABINET,
2449 * FDIERROR_BAD_COMPR_TYPE, FDIERROR_RESERVE_MISMATCH, and
2450 * FDIERROR_WRONG_CABINET.
2452 * The callee may choose to change the path where FDICopy will look for the
2453 * cabinet after this notification. To do so, the caller may write the new
2454 * pathname to the buffer pointed to by psz3, which is 256 characters in
2455 * length, including the terminating null character, before returning zero.
2457 * fdintENUMERATE:
2459 * Undocumented and unimplemented in wine, this seems to be sent each time
2460 * a cabinet is opened, along with the fdintCABINET_INFO notification. It
2461 * probably has an interface similar to that of fdintCABINET_INFO; maybe this
2462 * provides information about the current cabinet instead of the next one....
2463 * this is just a guess, it has not been looked at closely.
2465 * INCLUDES
2466 * fdi.c
2468 BOOL __cdecl FDICopy(
2469 HFDI hfdi,
2470 char *pszCabinet,
2471 char *pszCabPath,
2472 int flags,
2473 PFNFDINOTIFY pfnfdin,
2474 PFNFDIDECRYPT pfnfdid,
2475 void *pvUser)
2477 FDICABINETINFO fdici;
2478 FDINOTIFICATION fdin;
2479 INT_PTR cabhf, filehf = 0;
2480 int idx;
2481 unsigned int i;
2482 char fullpath[MAX_PATH];
2483 size_t pathlen, filenamelen;
2484 char emptystring = '\0';
2485 cab_UBYTE buf[64];
2486 struct fdi_folder *fol = NULL, *linkfol = NULL;
2487 struct fdi_file *file = NULL, *linkfile = NULL;
2488 fdi_decomp_state *decomp_state;
2489 FDI_Int *fdi = get_fdi_ptr( hfdi );
2491 TRACE("(hfdi == ^%p, pszCabinet == ^%p, pszCabPath == ^%p, flags == %0d, "
2492 "pfnfdin == ^%p, pfnfdid == ^%p, pvUser == ^%p)\n",
2493 hfdi, pszCabinet, pszCabPath, flags, pfnfdin, pfnfdid, pvUser);
2495 if (!fdi) return FALSE;
2497 if (!(decomp_state = fdi->alloc(sizeof(fdi_decomp_state))))
2499 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2500 return FALSE;
2502 ZeroMemory(decomp_state, sizeof(fdi_decomp_state));
2504 pathlen = (pszCabPath) ? strlen(pszCabPath) : 0;
2505 filenamelen = (pszCabinet) ? strlen(pszCabinet) : 0;
2507 /* slight overestimation here to save CPU cycles in the developer's brain */
2508 if ((pathlen + filenamelen + 3) > MAX_PATH) {
2509 ERR("MAX_PATH exceeded.\n");
2510 fdi->free(decomp_state);
2511 set_error( fdi, FDIERROR_CABINET_NOT_FOUND, ERROR_FILE_NOT_FOUND );
2512 return FALSE;
2515 /* paste the path and filename together */
2516 idx = 0;
2517 if (pathlen) {
2518 for (i = 0; i < pathlen; i++) fullpath[idx++] = pszCabPath[i];
2520 if (filenamelen) for (i = 0; i < filenamelen; i++) fullpath[idx++] = pszCabinet[i];
2521 fullpath[idx] = '\0';
2523 TRACE("full cab path/file name: %s\n", debugstr_a(fullpath));
2525 /* get a handle to the cabfile */
2526 cabhf = fdi->open(fullpath, _O_RDONLY|_O_BINARY, _S_IREAD | _S_IWRITE);
2527 if (cabhf == -1) {
2528 fdi->free(decomp_state);
2529 set_error( fdi, FDIERROR_CABINET_NOT_FOUND, 0 );
2530 SetLastError(ERROR_FILE_NOT_FOUND);
2531 return FALSE;
2534 /* check if it's really a cabfile. Note that this doesn't implement the bug */
2535 if (!FDI_read_entries(fdi, cabhf, &fdici, &(CAB(mii)))) {
2536 ERR("FDIIsCabinet failed: %u.\n", fdi->perf->erfOper);
2537 fdi->free(decomp_state);
2538 fdi->close(cabhf);
2539 return FALSE;
2542 /* cabinet notification */
2543 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2544 fdin.setID = fdici.setID;
2545 fdin.iCabinet = fdici.iCabinet;
2546 fdin.pv = pvUser;
2547 fdin.psz1 = (CAB(mii).nextname) ? CAB(mii).nextname : &emptystring;
2548 fdin.psz2 = (CAB(mii).nextinfo) ? CAB(mii).nextinfo : &emptystring;
2549 fdin.psz3 = pszCabPath;
2551 if (((*pfnfdin)(fdintCABINET_INFO, &fdin))) {
2552 set_error( fdi, FDIERROR_USER_ABORT, 0 );
2553 goto bail_and_fail;
2556 CAB(setID) = fdici.setID;
2557 CAB(iCabinet) = fdici.iCabinet;
2558 CAB(cabhf) = cabhf;
2560 /* read folders */
2561 for (i = 0; i < fdici.cFolders; i++) {
2562 if (fdi->read(cabhf, buf, cffold_SIZEOF) != cffold_SIZEOF) {
2563 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
2564 goto bail_and_fail;
2567 if (CAB(mii).folder_resv > 0)
2568 fdi->seek(cabhf, CAB(mii).folder_resv, SEEK_CUR);
2570 fol = fdi->alloc(sizeof(struct fdi_folder));
2571 if (!fol) {
2572 ERR("out of memory!\n");
2573 set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY );
2574 goto bail_and_fail;
2576 ZeroMemory(fol, sizeof(struct fdi_folder));
2577 if (!CAB(firstfol)) CAB(firstfol) = fol;
2579 fol->offset = (cab_off_t) EndGetI32(buf+cffold_DataOffset);
2580 fol->num_blocks = EndGetI16(buf+cffold_NumBlocks);
2581 fol->comp_type = EndGetI16(buf+cffold_CompType);
2583 if (linkfol)
2584 linkfol->next = fol;
2585 linkfol = fol;
2588 /* read files */
2589 for (i = 0; i < fdici.cFiles; i++) {
2590 if (fdi->read(cabhf, buf, cffile_SIZEOF) != cffile_SIZEOF) {
2591 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
2592 goto bail_and_fail;
2595 file = fdi->alloc(sizeof(struct fdi_file));
2596 if (!file) {
2597 ERR("out of memory!\n");
2598 set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY );
2599 goto bail_and_fail;
2601 ZeroMemory(file, sizeof(struct fdi_file));
2602 if (!CAB(firstfile)) CAB(firstfile) = file;
2604 file->length = EndGetI32(buf+cffile_UncompressedSize);
2605 file->offset = EndGetI32(buf+cffile_FolderOffset);
2606 file->index = EndGetI16(buf+cffile_FolderIndex);
2607 file->time = EndGetI16(buf+cffile_Time);
2608 file->date = EndGetI16(buf+cffile_Date);
2609 file->attribs = EndGetI16(buf+cffile_Attribs);
2610 file->filename = FDI_read_string(fdi, cabhf, fdici.cbCabinet);
2612 if (!file->filename) {
2613 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
2614 goto bail_and_fail;
2617 if (linkfile)
2618 linkfile->next = file;
2619 linkfile = file;
2622 for (file = CAB(firstfile); (file); file = file->next) {
2625 * FIXME: This implementation keeps multiple cabinet files open at once
2626 * when encountering a split cabinet. It is a quirk of this implementation
2627 * that sometimes we decrypt the same block of data more than once, to find
2628 * the right starting point for a file, moving the file-pointer backwards.
2629 * If we kept a cache of certain file-pointer information, we could eliminate
2630 * that behavior... in fact I am not sure that the caching we already have
2631 * is not sufficient.
2633 * The current implementation seems to work fine in straightforward situations
2634 * where all the cabinet files needed for decryption are simultaneously
2635 * available. But presumably, the API is supposed to support cabinets which
2636 * are split across multiple CDROMS; we may need to change our implementation
2637 * to strictly serialize it's file usage so that it opens only one cabinet
2638 * at a time. Some experimentation with Windows is needed to figure out the
2639 * precise semantics required. The relevant code is here and in fdi_decomp().
2642 /* partial-file notification */
2643 if ((file->index & cffileCONTINUED_FROM_PREV) == cffileCONTINUED_FROM_PREV) {
2645 * FIXME: Need to create a Cabinet with a single file spanning multiple files
2646 * and perform some tests to figure out the right behavior. The SDK says
2647 * FDICopy will notify the user of the filename and "disk name" (info) of
2648 * the cabinet where the spanning file /started/.
2650 * That would certainly be convenient for the API-user, who could abort,
2651 * everything (or parallelize, if that's allowed (it is in wine)), and call
2652 * FDICopy again with the provided filename, so as to avoid partial file
2653 * notification and successfully unpack. This task could be quite unpleasant
2654 * from wine's perspective: the information specifying the "start cabinet" for
2655 * a file is associated nowhere with the file header and is not to be found in
2656 * the cabinet header. We have only the index of the cabinet wherein the folder
2657 * begins, which contains the file. To find that cabinet, we must consider the
2658 * index of the current cabinet, and chain backwards, cabinet-by-cabinet (for
2659 * each cabinet refers to its "next" and "previous" cabinet only, like a linked
2660 * list).
2662 * Bear in mind that, in the spirit of CABINET.DLL, we must assume that any
2663 * cabinet other than the active one might be at another filepath than the
2664 * current one, or on another CDROM. This could get rather dicey, especially
2665 * if we imagine parallelized access to the FDICopy API.
2667 * The current implementation punts -- it just returns the previous cabinet and
2668 * it's info from the header of this cabinet. This provides the right answer in
2669 * 95% of the cases; its worth checking if Microsoft cuts the same corner before
2670 * we "fix" it.
2672 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2673 fdin.pv = pvUser;
2674 fdin.psz1 = (char *)file->filename;
2675 fdin.psz2 = (CAB(mii).prevname) ? CAB(mii).prevname : &emptystring;
2676 fdin.psz3 = (CAB(mii).previnfo) ? CAB(mii).previnfo : &emptystring;
2678 if (((*pfnfdin)(fdintPARTIAL_FILE, &fdin))) {
2679 set_error( fdi, FDIERROR_USER_ABORT, 0 );
2680 goto bail_and_fail;
2682 /* I don't think we are supposed to decompress partial files. This prevents it. */
2683 file->oppressed = TRUE;
2685 if (file->oppressed) {
2686 filehf = 0;
2687 } else {
2688 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2689 fdin.pv = pvUser;
2690 fdin.psz1 = (char *)file->filename;
2691 fdin.cb = file->length;
2692 fdin.date = file->date;
2693 fdin.time = file->time;
2694 fdin.attribs = file->attribs;
2695 if ((filehf = ((*pfnfdin)(fdintCOPY_FILE, &fdin))) == -1) {
2696 set_error( fdi, FDIERROR_USER_ABORT, 0 );
2697 filehf = 0;
2698 goto bail_and_fail;
2702 /* find the folder for this file if necc. */
2703 if (filehf) {
2704 int i2;
2706 fol = CAB(firstfol);
2707 if ((file->index & cffileCONTINUED_TO_NEXT) == cffileCONTINUED_TO_NEXT) {
2708 /* pick the last folder */
2709 while (fol->next) fol = fol->next;
2710 } else {
2711 for (i2 = 0; (i2 < file->index); i2++)
2712 if (fol->next) /* bug resistance, should always be true */
2713 fol = fol->next;
2717 if (filehf) {
2718 cab_UWORD comptype = fol->comp_type;
2719 int ct1 = comptype & cffoldCOMPTYPE_MASK;
2720 int ct2 = CAB(current) ? (CAB(current)->comp_type & cffoldCOMPTYPE_MASK) : 0;
2721 int err = 0;
2723 TRACE("Extracting file %s as requested by callee.\n", debugstr_a(file->filename));
2725 /* set up decomp_state */
2726 CAB(fdi) = fdi;
2727 CAB(filehf) = filehf;
2729 /* Was there a change of folder? Compression type? Did we somehow go backwards? */
2730 if ((ct1 != ct2) || (CAB(current) != fol) || (file->offset < CAB(offset))) {
2732 TRACE("Resetting folder for file %s.\n", debugstr_a(file->filename));
2734 /* free stuff for the old decompresser */
2735 switch (ct2) {
2736 case cffoldCOMPTYPE_LZX:
2737 if (LZX(window)) {
2738 fdi->free(LZX(window));
2739 LZX(window) = NULL;
2741 break;
2742 case cffoldCOMPTYPE_QUANTUM:
2743 if (QTM(window)) {
2744 fdi->free(QTM(window));
2745 QTM(window) = NULL;
2747 break;
2750 CAB(decomp_cab) = NULL;
2751 CAB(fdi)->seek(CAB(cabhf), fol->offset, SEEK_SET);
2752 CAB(offset) = 0;
2753 CAB(outlen) = 0;
2755 /* initialize the new decompresser */
2756 switch (ct1) {
2757 case cffoldCOMPTYPE_NONE:
2758 CAB(decompress) = NONEfdi_decomp;
2759 break;
2760 case cffoldCOMPTYPE_MSZIP:
2761 CAB(decompress) = ZIPfdi_decomp;
2762 break;
2763 case cffoldCOMPTYPE_QUANTUM:
2764 CAB(decompress) = QTMfdi_decomp;
2765 err = QTMfdi_init((comptype >> 8) & 0x1f, (comptype >> 4) & 0xF, decomp_state);
2766 break;
2767 case cffoldCOMPTYPE_LZX:
2768 CAB(decompress) = LZXfdi_decomp;
2769 err = LZXfdi_init((comptype >> 8) & 0x1f, decomp_state);
2770 break;
2771 default:
2772 err = DECR_DATAFORMAT;
2776 CAB(current) = fol;
2778 switch (err) {
2779 case DECR_OK:
2780 break;
2781 case DECR_NOMEMORY:
2782 set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY );
2783 goto bail_and_fail;
2784 default:
2785 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
2786 goto bail_and_fail;
2789 if (file->offset > CAB(offset)) {
2790 /* decode bytes and send them to /dev/null */
2791 switch (fdi_decomp(file, 0, decomp_state, pszCabPath, pfnfdin, pvUser)) {
2792 case DECR_OK:
2793 break;
2794 case DECR_USERABORT:
2795 set_error( fdi, FDIERROR_USER_ABORT, 0 );
2796 goto bail_and_fail;
2797 case DECR_NOMEMORY:
2798 set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY );
2799 goto bail_and_fail;
2800 default:
2801 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
2802 goto bail_and_fail;
2804 CAB(offset) = file->offset;
2807 /* now do the actual decompression */
2808 err = fdi_decomp(file, 1, decomp_state, pszCabPath, pfnfdin, pvUser);
2809 if (err) CAB(current) = NULL; else CAB(offset) += file->length;
2811 /* fdintCLOSE_FILE_INFO notification */
2812 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2813 fdin.pv = pvUser;
2814 fdin.psz1 = (char *)file->filename;
2815 fdin.hf = filehf;
2816 fdin.cb = (file->attribs & cffile_A_EXEC) ? TRUE : FALSE; /* FIXME: is that right? */
2817 fdin.date = file->date;
2818 fdin.time = file->time;
2819 fdin.attribs = file->attribs; /* FIXME: filter _A_EXEC? */
2820 ((*pfnfdin)(fdintCLOSE_FILE_INFO, &fdin));
2821 filehf = 0;
2823 switch (err) {
2824 case DECR_OK:
2825 break;
2826 case DECR_USERABORT:
2827 set_error( fdi, FDIERROR_USER_ABORT, 0 );
2828 goto bail_and_fail;
2829 case DECR_NOMEMORY:
2830 set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY );
2831 goto bail_and_fail;
2832 default:
2833 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
2834 goto bail_and_fail;
2839 if (fol) free_decompression_temps(fdi, fol, decomp_state);
2840 free_decompression_mem(fdi, decomp_state);
2842 return TRUE;
2844 bail_and_fail: /* here we free ram before error returns */
2846 if (fol) free_decompression_temps(fdi, fol, decomp_state);
2848 if (filehf) fdi->close(filehf);
2850 free_decompression_mem(fdi, decomp_state);
2852 return FALSE;
2855 /***********************************************************************
2856 * FDIDestroy (CABINET.23)
2858 * Frees a handle created by FDICreate. Do /not/ call this in the middle
2859 * of FDICopy. Only reason for failure would be an invalid handle.
2861 * PARAMS
2862 * hfdi [I] The HFDI to free
2864 * RETURNS
2865 * TRUE for success
2866 * FALSE for failure
2868 BOOL __cdecl FDIDestroy(HFDI hfdi)
2870 FDI_Int *fdi = get_fdi_ptr( hfdi );
2872 TRACE("(hfdi == ^%p)\n", hfdi);
2873 if (!fdi) return FALSE;
2874 fdi->magic = 0; /* paranoia */
2875 fdi->free(fdi);
2876 return TRUE;
2879 /***********************************************************************
2880 * FDITruncateCabinet (CABINET.24)
2882 * Removes all folders of a cabinet file after and including the
2883 * specified folder number.
2885 * PARAMS
2886 * hfdi [I] Handle to the FDI context.
2887 * pszCabinetName [I] Filename of the cabinet.
2888 * iFolderToDelete [I] Index of the first folder to delete.
2890 * RETURNS
2891 * Success: TRUE.
2892 * Failure: FALSE.
2894 * NOTES
2895 * The PFNWRITE function supplied to FDICreate must truncate the
2896 * file at the current position if the number of bytes to write is 0.
2898 BOOL __cdecl FDITruncateCabinet(
2899 HFDI hfdi,
2900 char *pszCabinetName,
2901 USHORT iFolderToDelete)
2903 FDI_Int *fdi = get_fdi_ptr( hfdi );
2905 FIXME("(hfdi == ^%p, pszCabinetName == %s, iFolderToDelete == %hu): stub\n",
2906 hfdi, debugstr_a(pszCabinetName), iFolderToDelete);
2908 if (!fdi) return FALSE;
2910 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2911 return FALSE;