mfplat: Read queue subscriber within the critical section.
[wine/zf.git] / dlls / cabinet / fdi.c
blob1f442917d561a0cc47496dc76eebd36be5731e1a
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 FIXMEs 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 <stdarg.h>
62 #include <stdio.h>
63 #include <sys/stat.h>
64 #include <fcntl.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 /* fall through */
364 case 2: ul |= *data++ << 8;
365 /* fall through */
366 case 1: ul |= *data;
368 csum ^= ul;
370 return csum;
373 /***********************************************************************
374 * FDICreate (CABINET.20)
376 * Provided with several callbacks (all of them are mandatory),
377 * returns a handle which can be used to perform operations
378 * on cabinet files.
380 * PARAMS
381 * pfnalloc [I] A pointer to a function which allocates ram. Uses
382 * the same interface as malloc.
383 * pfnfree [I] A pointer to a function which frees ram. Uses the
384 * same interface as free.
385 * pfnopen [I] A pointer to a function which opens a file. Uses
386 * the same interface as _open.
387 * pfnread [I] A pointer to a function which reads from a file into
388 * a caller-provided buffer. Uses the same interface
389 * as _read
390 * pfnwrite [I] A pointer to a function which writes to a file from
391 * a caller-provided buffer. Uses the same interface
392 * as _write.
393 * pfnclose [I] A pointer to a function which closes a file handle.
394 * Uses the same interface as _close.
395 * pfnseek [I] A pointer to a function which seeks in a file.
396 * Uses the same interface as _lseek.
397 * cpuType [I] The type of CPU; ignored in wine (recommended value:
398 * cpuUNKNOWN, aka -1).
399 * perf [IO] A pointer to an ERF structure. When FDICreate
400 * returns an error condition, error information may
401 * be found here as well as from GetLastError.
403 * RETURNS
404 * On success, returns an FDI handle of type HFDI.
405 * On failure, the NULL file handle is returned. Error
406 * info can be retrieved from perf.
408 * INCLUDES
409 * fdi.h
412 HFDI __cdecl FDICreate(
413 PFNALLOC pfnalloc,
414 PFNFREE pfnfree,
415 PFNOPEN pfnopen,
416 PFNREAD pfnread,
417 PFNWRITE pfnwrite,
418 PFNCLOSE pfnclose,
419 PFNSEEK pfnseek,
420 int cpuType,
421 PERF perf)
423 FDI_Int *fdi;
425 TRACE("(pfnalloc == ^%p, pfnfree == ^%p, pfnopen == ^%p, pfnread == ^%p, pfnwrite == ^%p, "
426 "pfnclose == ^%p, pfnseek == ^%p, cpuType == %d, perf == ^%p)\n",
427 pfnalloc, pfnfree, pfnopen, pfnread, pfnwrite, pfnclose, pfnseek,
428 cpuType, perf);
430 if ((!pfnalloc) || (!pfnfree)) {
431 perf->erfOper = FDIERROR_NONE;
432 perf->erfType = ERROR_BAD_ARGUMENTS;
433 perf->fError = TRUE;
435 SetLastError(ERROR_BAD_ARGUMENTS);
436 return NULL;
439 if (!((fdi = pfnalloc(sizeof(FDI_Int))))) {
440 perf->erfOper = FDIERROR_ALLOC_FAIL;
441 perf->erfType = 0;
442 perf->fError = TRUE;
443 return NULL;
446 fdi->magic = FDI_INT_MAGIC;
447 fdi->alloc = pfnalloc;
448 fdi->free = pfnfree;
449 fdi->open = pfnopen;
450 fdi->read = pfnread;
451 fdi->write = pfnwrite;
452 fdi->close = pfnclose;
453 fdi->seek = pfnseek;
454 /* no-brainer: we ignore the cpu type; this is only used
455 for the 16-bit versions in Windows anyhow... */
456 fdi->perf = perf;
458 return (HFDI)fdi;
461 /*******************************************************************
462 * FDI_getoffset (internal)
464 * returns the file pointer position of a file handle.
466 static LONG FDI_getoffset(FDI_Int *fdi, INT_PTR hf)
468 return fdi->seek(hf, 0, SEEK_CUR);
471 /**********************************************************************
472 * FDI_read_string (internal)
474 * allocate and read an arbitrarily long string from the cabinet
476 static char *FDI_read_string(FDI_Int *fdi, INT_PTR hf, long cabsize)
478 size_t len=256,
479 base = FDI_getoffset(fdi, hf),
480 maxlen = cabsize - base;
481 BOOL ok = FALSE;
482 unsigned int i;
483 cab_UBYTE *buf = NULL;
485 TRACE("(fdi == %p, hf == %ld, cabsize == %ld)\n", fdi, hf, cabsize);
487 do {
488 if (len > maxlen) len = maxlen;
489 if (!(buf = fdi->alloc(len))) break;
490 if (!fdi->read(hf, buf, len)) break;
492 /* search for a null terminator in what we've just read */
493 for (i=0; i < len; i++) {
494 if (!buf[i]) {ok=TRUE; break;}
497 if (!ok) {
498 if (len == maxlen) {
499 ERR("cabinet is truncated\n");
500 break;
502 /* The buffer is too small for the string. Reset the file to the point
503 * where we started, free the buffer and increase the size for the next try
505 fdi->seek(hf, base, SEEK_SET);
506 fdi->free(buf);
507 buf = NULL;
508 len *= 2;
510 } while (!ok);
512 if (!ok) {
513 if (buf)
514 fdi->free(buf);
515 else
516 ERR("out of memory!\n");
517 return NULL;
520 /* otherwise, set the stream to just after the string and return */
521 fdi->seek(hf, base + strlen((char *)buf) + 1, SEEK_SET);
523 return (char *) buf;
526 /******************************************************************
527 * FDI_read_entries (internal)
529 * process the cabinet header in the style of FDIIsCabinet, but
530 * without the sanity checks (and bug)
532 static BOOL FDI_read_entries(
533 FDI_Int *fdi,
534 INT_PTR hf,
535 PFDICABINETINFO pfdici,
536 PMORE_ISCAB_INFO pmii)
538 int num_folders, num_files, header_resv, folder_resv = 0;
539 LONG cabsize;
540 USHORT setid, cabidx, flags;
541 cab_UBYTE buf[64], block_resv;
542 char *prevname = NULL, *previnfo = NULL, *nextname = NULL, *nextinfo = NULL;
544 TRACE("(fdi == ^%p, hf == %ld, pfdici == ^%p)\n", fdi, hf, pfdici);
546 /* read in the CFHEADER */
547 if (fdi->read(hf, buf, cfhead_SIZEOF) != cfhead_SIZEOF) {
548 if (pmii) set_error( fdi, FDIERROR_NOT_A_CABINET, 0 );
549 return FALSE;
552 /* check basic MSCF signature */
553 if (EndGetI32(buf+cfhead_Signature) != 0x4643534d) {
554 if (pmii) set_error( fdi, FDIERROR_NOT_A_CABINET, 0 );
555 return FALSE;
558 /* get the cabinet size */
559 cabsize = EndGetI32(buf+cfhead_CabinetSize);
561 /* get the number of folders */
562 num_folders = EndGetI16(buf+cfhead_NumFolders);
564 /* get the number of files */
565 num_files = EndGetI16(buf+cfhead_NumFiles);
567 /* setid */
568 setid = EndGetI16(buf+cfhead_SetID);
570 /* cabinet (set) index */
571 cabidx = EndGetI16(buf+cfhead_CabinetIndex);
573 /* check the header revision */
574 if ((buf[cfhead_MajorVersion] > 1) ||
575 (buf[cfhead_MajorVersion] == 1 && buf[cfhead_MinorVersion] > 3))
577 WARN("cabinet format version > 1.3\n");
578 if (pmii) set_error( fdi, FDIERROR_UNKNOWN_CABINET_VERSION, 0 /* ? */ );
579 return FALSE;
582 /* pull the flags out */
583 flags = EndGetI16(buf+cfhead_Flags);
585 /* read the reserved-sizes part of header, if present */
586 if (flags & cfheadRESERVE_PRESENT) {
587 if (fdi->read(hf, buf, cfheadext_SIZEOF) != cfheadext_SIZEOF) {
588 ERR("bunk reserve-sizes?\n");
589 if (pmii) set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 /* ? */ );
590 return FALSE;
593 header_resv = EndGetI16(buf+cfheadext_HeaderReserved);
594 if (pmii) pmii->header_resv = header_resv;
595 folder_resv = buf[cfheadext_FolderReserved];
596 if (pmii) pmii->folder_resv = folder_resv;
597 block_resv = buf[cfheadext_DataReserved];
598 if (pmii) pmii->block_resv = block_resv;
600 if (header_resv > 60000) {
601 WARN("WARNING; header reserved space > 60000\n");
604 /* skip the reserved header */
605 if ((header_resv) && (fdi->seek(hf, header_resv, SEEK_CUR) == -1)) {
606 ERR("seek failure: header_resv\n");
607 if (pmii) set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 /* ? */ );
608 return FALSE;
612 if (flags & cfheadPREV_CABINET) {
613 prevname = FDI_read_string(fdi, hf, cabsize);
614 if (!prevname) {
615 if (pmii) set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 /* ? */ );
616 return FALSE;
617 } else
618 if (pmii)
619 pmii->prevname = prevname;
620 else
621 fdi->free(prevname);
622 previnfo = FDI_read_string(fdi, hf, cabsize);
623 if (previnfo) {
624 if (pmii)
625 pmii->previnfo = previnfo;
626 else
627 fdi->free(previnfo);
631 if (flags & cfheadNEXT_CABINET) {
632 if (pmii)
633 pmii->hasnext = TRUE;
634 nextname = FDI_read_string(fdi, hf, cabsize);
635 if (!nextname) {
636 if ((flags & cfheadPREV_CABINET) && pmii) {
637 if (pmii->prevname) fdi->free(prevname);
638 if (pmii->previnfo) fdi->free(previnfo);
640 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 /* ? */ );
641 return FALSE;
642 } else
643 if (pmii)
644 pmii->nextname = nextname;
645 else
646 fdi->free(nextname);
647 nextinfo = FDI_read_string(fdi, hf, cabsize);
648 if (nextinfo) {
649 if (pmii)
650 pmii->nextinfo = nextinfo;
651 else
652 fdi->free(nextinfo);
656 /* we could process the whole cabinet searching for problems;
657 instead lets stop here. Now let's fill out the paperwork */
658 pfdici->cbCabinet = cabsize;
659 pfdici->cFolders = num_folders;
660 pfdici->cFiles = num_files;
661 pfdici->setID = setid;
662 pfdici->iCabinet = cabidx;
663 pfdici->fReserve = (flags & cfheadRESERVE_PRESENT) != 0;
664 pfdici->hasprev = (flags & cfheadPREV_CABINET) != 0;
665 pfdici->hasnext = (flags & cfheadNEXT_CABINET) != 0;
666 return TRUE;
669 /***********************************************************************
670 * FDIIsCabinet (CABINET.21)
672 * Informs the caller as to whether or not the provided file handle is
673 * really a cabinet or not, filling out the provided PFDICABINETINFO
674 * structure with information about the cabinet. Brief explanations of
675 * the elements of this structure are available as comments accompanying
676 * its definition in wine's include/fdi.h.
678 * PARAMS
679 * hfdi [I] An HFDI from FDICreate
680 * hf [I] The file handle about which the caller inquires
681 * pfdici [IO] Pointer to a PFDICABINETINFO structure which will
682 * be filled out with information about the cabinet
683 * file indicated by hf if, indeed, it is determined
684 * to be a cabinet.
686 * RETURNS
687 * TRUE if the file is a cabinet. The info pointed to by pfdici will
688 * be provided.
689 * FALSE if the file is not a cabinet, or if an error was encountered
690 * while processing the cabinet. The PERF structure provided to
691 * FDICreate can be queried for more error information.
693 * INCLUDES
694 * fdi.c
696 BOOL __cdecl FDIIsCabinet(HFDI hfdi, INT_PTR hf, PFDICABINETINFO pfdici)
698 BOOL rv;
699 FDI_Int *fdi = get_fdi_ptr( hfdi );
701 TRACE("(hfdi == ^%p, hf == ^%ld, pfdici == ^%p)\n", hfdi, hf, pfdici);
703 if (!fdi) return FALSE;
705 if (!pfdici) {
706 SetLastError(ERROR_BAD_ARGUMENTS);
707 return FALSE;
709 rv = FDI_read_entries(fdi, hf, pfdici, NULL);
711 if (rv)
712 pfdici->hasnext = FALSE; /* yuck. duplicate apparent cabinet.dll bug */
714 return rv;
717 /******************************************************************
718 * QTMfdi_initmodel (internal)
720 * Initialize a model which decodes symbols from [s] to [s]+[n]-1
722 static void QTMfdi_initmodel(struct QTMmodel *m, struct QTMmodelsym *sym, int n, int s) {
723 int i;
724 m->shiftsleft = 4;
725 m->entries = n;
726 m->syms = sym;
727 memset(m->tabloc, 0xFF, sizeof(m->tabloc)); /* clear out look-up table */
728 for (i = 0; i < n; i++) {
729 m->tabloc[i+s] = i; /* set up a look-up entry for symbol */
730 m->syms[i].sym = i+s; /* actual symbol */
731 m->syms[i].cumfreq = n-i; /* current frequency of that symbol */
733 m->syms[n].cumfreq = 0;
736 /******************************************************************
737 * QTMfdi_init (internal)
739 static int QTMfdi_init(int window, int level, fdi_decomp_state *decomp_state) {
740 unsigned int wndsize = 1 << window;
741 int msz = window * 2, i;
742 cab_ULONG j;
744 /* QTM supports window sizes of 2^10 (1Kb) through 2^21 (2Mb) */
745 /* if a previously allocated window is big enough, keep it */
746 if (window < 10 || window > 21) return DECR_DATAFORMAT;
747 if (QTM(actual_size) < wndsize) {
748 if (QTM(window)) CAB(fdi)->free(QTM(window));
749 QTM(window) = NULL;
751 if (!QTM(window)) {
752 if (!(QTM(window) = CAB(fdi)->alloc(wndsize))) return DECR_NOMEMORY;
753 QTM(actual_size) = wndsize;
755 QTM(window_size) = wndsize;
756 QTM(window_posn) = 0;
758 /* initialize static slot/extrabits tables */
759 for (i = 0, j = 0; i < 27; i++) {
760 CAB(q_length_extra)[i] = (i == 26) ? 0 : (i < 2 ? 0 : i - 2) >> 2;
761 CAB(q_length_base)[i] = j; j += 1 << ((i == 26) ? 5 : CAB(q_length_extra)[i]);
763 for (i = 0, j = 0; i < 42; i++) {
764 CAB(q_extra_bits)[i] = (i < 2 ? 0 : i-2) >> 1;
765 CAB(q_position_base)[i] = j; j += 1 << CAB(q_extra_bits)[i];
768 /* initialize arithmetic coding models */
770 QTMfdi_initmodel(&QTM(model7), QTM(m7sym), 7, 0);
772 QTMfdi_initmodel(&QTM(model00), QTM(m00sym), 0x40, 0x00);
773 QTMfdi_initmodel(&QTM(model40), QTM(m40sym), 0x40, 0x40);
774 QTMfdi_initmodel(&QTM(model80), QTM(m80sym), 0x40, 0x80);
775 QTMfdi_initmodel(&QTM(modelC0), QTM(mC0sym), 0x40, 0xC0);
777 /* model 4 depends on table size, ranges from 20 to 24 */
778 QTMfdi_initmodel(&QTM(model4), QTM(m4sym), (msz < 24) ? msz : 24, 0);
779 /* model 5 depends on table size, ranges from 20 to 36 */
780 QTMfdi_initmodel(&QTM(model5), QTM(m5sym), (msz < 36) ? msz : 36, 0);
781 /* model 6pos depends on table size, ranges from 20 to 42 */
782 QTMfdi_initmodel(&QTM(model6pos), QTM(m6psym), msz, 0);
783 QTMfdi_initmodel(&QTM(model6len), QTM(m6lsym), 27, 0);
785 return DECR_OK;
788 /************************************************************
789 * LZXfdi_init (internal)
791 static int LZXfdi_init(int window, fdi_decomp_state *decomp_state) {
792 static const cab_UBYTE bits[] =
793 { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
794 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14,
795 15, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
796 17, 17, 17};
797 static const cab_ULONG base[] =
798 { 0, 1, 2, 3, 4, 6, 8, 12,
799 16, 24, 32, 48, 64, 96, 128, 192,
800 256, 384, 512, 768, 1024, 1536, 2048, 3072,
801 4096, 6144, 8192, 12288, 16384, 24576, 32768, 49152,
802 65536, 98304, 131072, 196608, 262144, 393216, 524288, 655360,
803 786432, 917504, 1048576, 1179648, 1310720, 1441792, 1572864, 1703936,
804 1835008, 1966080, 2097152};
805 cab_ULONG wndsize = 1 << window;
806 int posn_slots;
808 /* LZX supports window sizes of 2^15 (32Kb) through 2^21 (2Mb) */
809 /* if a previously allocated window is big enough, keep it */
810 if (window < 15 || window > 21) return DECR_DATAFORMAT;
811 if (LZX(actual_size) < wndsize) {
812 if (LZX(window)) CAB(fdi)->free(LZX(window));
813 LZX(window) = NULL;
815 if (!LZX(window)) {
816 if (!(LZX(window) = CAB(fdi)->alloc(wndsize))) return DECR_NOMEMORY;
817 LZX(actual_size) = wndsize;
819 LZX(window_size) = wndsize;
821 /* initialize static tables */
822 memcpy(CAB(extra_bits), bits, sizeof(bits));
823 memcpy(CAB(lzx_position_base), base, sizeof(base));
825 /* calculate required position slots */
826 if (window == 20) posn_slots = 42;
827 else if (window == 21) posn_slots = 50;
828 else posn_slots = window << 1;
830 /*posn_slots=i=0; while (i < wndsize) i += 1 << CAB(extra_bits)[posn_slots++]; */
832 LZX(R0) = LZX(R1) = LZX(R2) = 1;
833 LZX(main_elements) = LZX_NUM_CHARS + (posn_slots << 3);
834 LZX(header_read) = 0;
835 LZX(frames_read) = 0;
836 LZX(block_remaining) = 0;
837 LZX(block_type) = LZX_BLOCKTYPE_INVALID;
838 LZX(intel_curpos) = 0;
839 LZX(intel_started) = 0;
840 LZX(window_posn) = 0;
842 /* initialize tables to 0 (because deltas will be applied to them) */
843 memset(LZX(MAINTREE_len), 0, sizeof(LZX(MAINTREE_len)));
844 memset(LZX(LENGTH_len), 0, sizeof(LZX(LENGTH_len)));
846 return DECR_OK;
849 /****************************************************
850 * NONEfdi_decomp(internal)
852 static int NONEfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state)
854 if (inlen != outlen) return DECR_ILLEGALDATA;
855 if (outlen > CAB_BLOCKMAX) return DECR_DATAFORMAT;
856 memcpy(CAB(outbuf), CAB(inbuf), (size_t) inlen);
857 return DECR_OK;
860 /********************************************************
861 * Ziphuft_free (internal)
863 static void fdi_Ziphuft_free(FDI_Int *fdi, struct Ziphuft *t)
865 register struct Ziphuft *p, *q;
867 /* Go through linked list, freeing from the allocated (t[-1]) address. */
868 p = t;
869 while (p != NULL)
871 q = (--p)->v.t;
872 fdi->free(p);
873 p = q;
877 /*********************************************************
878 * fdi_Ziphuft_build (internal)
880 static cab_LONG fdi_Ziphuft_build(cab_ULONG *b, cab_ULONG n, cab_ULONG s, const cab_UWORD *d, const cab_UWORD *e,
881 struct Ziphuft **t, cab_LONG *m, fdi_decomp_state *decomp_state)
883 cab_ULONG a; /* counter for codes of length k */
884 cab_ULONG el; /* length of EOB code (value 256) */
885 cab_ULONG f; /* i repeats in table every f entries */
886 cab_LONG g; /* maximum code length */
887 cab_LONG h; /* table level */
888 register cab_ULONG i; /* counter, current code */
889 register cab_ULONG j; /* counter */
890 register cab_LONG k; /* number of bits in current code */
891 cab_LONG *l; /* stack of bits per table */
892 register cab_ULONG *p; /* pointer into ZIP(c)[],ZIP(b)[],ZIP(v)[] */
893 register struct Ziphuft *q; /* points to current table */
894 struct Ziphuft r; /* table entry for structure assignment */
895 register cab_LONG w; /* bits before this table == (l * h) */
896 cab_ULONG *xp; /* pointer into x */
897 cab_LONG y; /* number of dummy codes added */
898 cab_ULONG z; /* number of entries in current table */
900 l = ZIP(lx)+1;
902 /* Generate counts for each bit length */
903 el = n > 256 ? b[256] : ZIPBMAX; /* set length of EOB code, if any */
905 for(i = 0; i < ZIPBMAX+1; ++i)
906 ZIP(c)[i] = 0;
907 p = b; i = n;
910 ZIP(c)[*p]++; p++; /* assume all entries <= ZIPBMAX */
911 } while (--i);
912 if (ZIP(c)[0] == n) /* null input--all zero length codes */
914 *t = NULL;
915 *m = 0;
916 return 0;
919 /* Find minimum and maximum length, bound *m by those */
920 for (j = 1; j <= ZIPBMAX; j++)
921 if (ZIP(c)[j])
922 break;
923 k = j; /* minimum code length */
924 if ((cab_ULONG)*m < j)
925 *m = j;
926 for (i = ZIPBMAX; i; i--)
927 if (ZIP(c)[i])
928 break;
929 g = i; /* maximum code length */
930 if ((cab_ULONG)*m > i)
931 *m = i;
933 /* Adjust last length count to fill out codes, if needed */
934 for (y = 1 << j; j < i; j++, y <<= 1)
935 if ((y -= ZIP(c)[j]) < 0)
936 return 2; /* bad input: more codes than bits */
937 if ((y -= ZIP(c)[i]) < 0)
938 return 2;
939 ZIP(c)[i] += y;
941 /* Generate starting offsets LONGo the value table for each length */
942 ZIP(x)[1] = j = 0;
943 p = ZIP(c) + 1; xp = ZIP(x) + 2;
944 while (--i)
945 { /* note that i == g from above */
946 *xp++ = (j += *p++);
949 /* Make a table of values in order of bit lengths */
950 p = b; i = 0;
952 if ((j = *p++) != 0)
953 ZIP(v)[ZIP(x)[j]++] = i;
954 } while (++i < n);
957 /* Generate the Huffman codes and for each, make the table entries */
958 ZIP(x)[0] = i = 0; /* first Huffman code is zero */
959 p = ZIP(v); /* grab values in bit order */
960 h = -1; /* no tables yet--level -1 */
961 w = l[-1] = 0; /* no bits decoded yet */
962 ZIP(u)[0] = NULL; /* just to keep compilers happy */
963 q = NULL; /* ditto */
964 z = 0; /* ditto */
966 /* go through the bit lengths (k already is bits in shortest code) */
967 for (; k <= g; k++)
969 a = ZIP(c)[k];
970 while (a--)
972 /* here i is the Huffman code of length k bits for value *p */
973 /* make tables up to required level */
974 while (k > w + l[h])
976 w += l[h++]; /* add bits already decoded */
978 /* compute minimum size table less than or equal to *m bits */
979 if ((z = g - w) > (cab_ULONG)*m) /* upper limit */
980 z = *m;
981 if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
982 { /* too few codes for k-w bit table */
983 f -= a + 1; /* deduct codes from patterns left */
984 xp = ZIP(c) + k;
985 while (++j < z) /* try smaller tables up to z bits */
987 if ((f <<= 1) <= *++xp)
988 break; /* enough codes to use up j bits */
989 f -= *xp; /* else deduct codes from patterns */
992 if ((cab_ULONG)w + j > el && (cab_ULONG)w < el)
993 j = el - w; /* make EOB code end at table */
994 z = 1 << j; /* table entries for j-bit table */
995 l[h] = j; /* set table size in stack */
997 /* allocate and link in new table */
998 if (!(q = CAB(fdi)->alloc((z + 1)*sizeof(struct Ziphuft))))
1000 if(h)
1001 fdi_Ziphuft_free(CAB(fdi), ZIP(u)[0]);
1002 return 3; /* not enough memory */
1004 *t = q + 1; /* link to list for Ziphuft_free() */
1005 *(t = &(q->v.t)) = NULL;
1006 ZIP(u)[h] = ++q; /* table starts after link */
1008 /* connect to last table, if there is one */
1009 if (h)
1011 ZIP(x)[h] = i; /* save pattern for backing up */
1012 r.b = (cab_UBYTE)l[h-1]; /* bits to dump before this table */
1013 r.e = (cab_UBYTE)(16 + j); /* bits in this table */
1014 r.v.t = q; /* pointer to this table */
1015 j = (i & ((1 << w) - 1)) >> (w - l[h-1]);
1016 ZIP(u)[h-1][j] = r; /* connect to last table */
1020 /* set up table entry in r */
1021 r.b = (cab_UBYTE)(k - w);
1022 if (p >= ZIP(v) + n)
1023 r.e = 99; /* out of values--invalid code */
1024 else if (*p < s)
1026 r.e = (cab_UBYTE)(*p < 256 ? 16 : 15); /* 256 is end-of-block code */
1027 r.v.n = *p++; /* simple code is just the value */
1029 else
1031 r.e = (cab_UBYTE)e[*p - s]; /* non-simple--look up in lists */
1032 r.v.n = d[*p++ - s];
1035 /* fill code-like entries with r */
1036 f = 1 << (k - w);
1037 for (j = i >> w; j < z; j += f)
1038 q[j] = r;
1040 /* backwards increment the k-bit code i */
1041 for (j = 1 << (k - 1); i & j; j >>= 1)
1042 i ^= j;
1043 i ^= j;
1045 /* backup over finished tables */
1046 while ((i & ((1 << w) - 1)) != ZIP(x)[h])
1047 w -= l[--h]; /* don't need to update q */
1051 /* return actual size of base table */
1052 *m = l[0];
1054 /* Return true (1) if we were given an incomplete table */
1055 return y != 0 && g != 1;
1058 /*********************************************************
1059 * fdi_Zipinflate_codes (internal)
1061 static cab_LONG fdi_Zipinflate_codes(const struct Ziphuft *tl, const struct Ziphuft *td,
1062 cab_LONG bl, cab_LONG bd, fdi_decomp_state *decomp_state)
1064 register cab_ULONG e; /* table entry flag/number of extra bits */
1065 cab_ULONG n, d; /* length and index for copy */
1066 cab_ULONG w; /* current window position */
1067 const struct Ziphuft *t; /* pointer to table entry */
1068 cab_ULONG ml, md; /* masks for bl and bd bits */
1069 register cab_ULONG b; /* bit buffer */
1070 register cab_ULONG k; /* number of bits in bit buffer */
1072 /* make local copies of globals */
1073 b = ZIP(bb); /* initialize bit buffer */
1074 k = ZIP(bk);
1075 w = ZIP(window_posn); /* initialize window position */
1077 /* inflate the coded data */
1078 ml = Zipmask[bl]; /* precompute masks for speed */
1079 md = Zipmask[bd];
1081 for(;;)
1083 ZIPNEEDBITS((cab_ULONG)bl)
1084 if((e = (t = tl + (b & ml))->e) > 16)
1087 if (e == 99)
1088 return 1;
1089 ZIPDUMPBITS(t->b)
1090 e -= 16;
1091 ZIPNEEDBITS(e)
1092 } while ((e = (t = t->v.t + (b & Zipmask[e]))->e) > 16);
1093 ZIPDUMPBITS(t->b)
1094 if (e == 16) /* then it's a literal */
1095 CAB(outbuf)[w++] = (cab_UBYTE)t->v.n;
1096 else /* it's an EOB or a length */
1098 /* exit if end of block */
1099 if(e == 15)
1100 break;
1102 /* get length of block to copy */
1103 ZIPNEEDBITS(e)
1104 n = t->v.n + (b & Zipmask[e]);
1105 ZIPDUMPBITS(e);
1107 /* decode distance of block to copy */
1108 ZIPNEEDBITS((cab_ULONG)bd)
1109 if ((e = (t = td + (b & md))->e) > 16)
1110 do {
1111 if (e == 99)
1112 return 1;
1113 ZIPDUMPBITS(t->b)
1114 e -= 16;
1115 ZIPNEEDBITS(e)
1116 } while ((e = (t = t->v.t + (b & Zipmask[e]))->e) > 16);
1117 ZIPDUMPBITS(t->b)
1118 ZIPNEEDBITS(e)
1119 d = w - t->v.n - (b & Zipmask[e]);
1120 ZIPDUMPBITS(e)
1123 d &= ZIPWSIZE - 1;
1124 e = ZIPWSIZE - max(d, w);
1125 e = min(e, n);
1126 n -= e;
1129 CAB(outbuf)[w++] = CAB(outbuf)[d++];
1130 } while (--e);
1131 } while (n);
1135 /* restore the globals from the locals */
1136 ZIP(window_posn) = w; /* restore global window pointer */
1137 ZIP(bb) = b; /* restore global bit buffer */
1138 ZIP(bk) = k;
1140 /* done */
1141 return 0;
1144 /***********************************************************
1145 * Zipinflate_stored (internal)
1147 static cab_LONG fdi_Zipinflate_stored(fdi_decomp_state *decomp_state)
1148 /* "decompress" an inflated type 0 (stored) block. */
1150 cab_ULONG n; /* number of bytes in block */
1151 cab_ULONG w; /* current window position */
1152 register cab_ULONG b; /* bit buffer */
1153 register cab_ULONG k; /* number of bits in bit buffer */
1155 /* make local copies of globals */
1156 b = ZIP(bb); /* initialize bit buffer */
1157 k = ZIP(bk);
1158 w = ZIP(window_posn); /* initialize window position */
1160 /* go to byte boundary */
1161 n = k & 7;
1162 ZIPDUMPBITS(n);
1164 /* get the length and its complement */
1165 ZIPNEEDBITS(16)
1166 n = (b & 0xffff);
1167 ZIPDUMPBITS(16)
1168 ZIPNEEDBITS(16)
1169 if (n != ((~b) & 0xffff))
1170 return 1; /* error in compressed data */
1171 ZIPDUMPBITS(16)
1173 /* read and output the compressed data */
1174 while(n--)
1176 ZIPNEEDBITS(8)
1177 CAB(outbuf)[w++] = (cab_UBYTE)b;
1178 ZIPDUMPBITS(8)
1181 /* restore the globals from the locals */
1182 ZIP(window_posn) = w; /* restore global window pointer */
1183 ZIP(bb) = b; /* restore global bit buffer */
1184 ZIP(bk) = k;
1185 return 0;
1188 /******************************************************
1189 * fdi_Zipinflate_fixed (internal)
1191 static cab_LONG fdi_Zipinflate_fixed(fdi_decomp_state *decomp_state)
1193 struct Ziphuft *fixed_tl;
1194 struct Ziphuft *fixed_td;
1195 cab_LONG fixed_bl, fixed_bd;
1196 cab_LONG i; /* temporary variable */
1197 cab_ULONG *l;
1199 l = ZIP(ll);
1201 /* literal table */
1202 for(i = 0; i < 144; i++)
1203 l[i] = 8;
1204 for(; i < 256; i++)
1205 l[i] = 9;
1206 for(; i < 280; i++)
1207 l[i] = 7;
1208 for(; i < 288; i++) /* make a complete, but wrong code set */
1209 l[i] = 8;
1210 fixed_bl = 7;
1211 if((i = fdi_Ziphuft_build(l, 288, 257, Zipcplens, Zipcplext, &fixed_tl, &fixed_bl, decomp_state)))
1212 return i;
1214 /* distance table */
1215 for(i = 0; i < 30; i++) /* make an incomplete code set */
1216 l[i] = 5;
1217 fixed_bd = 5;
1218 if((i = fdi_Ziphuft_build(l, 30, 0, Zipcpdist, Zipcpdext, &fixed_td, &fixed_bd, decomp_state)) > 1)
1220 fdi_Ziphuft_free(CAB(fdi), fixed_tl);
1221 return i;
1224 /* decompress until an end-of-block code */
1225 i = fdi_Zipinflate_codes(fixed_tl, fixed_td, fixed_bl, fixed_bd, decomp_state);
1227 fdi_Ziphuft_free(CAB(fdi), fixed_td);
1228 fdi_Ziphuft_free(CAB(fdi), fixed_tl);
1229 return i;
1232 /**************************************************************
1233 * fdi_Zipinflate_dynamic (internal)
1235 static cab_LONG fdi_Zipinflate_dynamic(fdi_decomp_state *decomp_state)
1236 /* decompress an inflated type 2 (dynamic Huffman codes) block. */
1238 cab_LONG i; /* temporary variables */
1239 cab_ULONG j;
1240 cab_ULONG *ll;
1241 cab_ULONG l; /* last length */
1242 cab_ULONG m; /* mask for bit lengths table */
1243 cab_ULONG n; /* number of lengths to get */
1244 struct Ziphuft *tl; /* literal/length code table */
1245 struct Ziphuft *td; /* distance code table */
1246 cab_LONG bl; /* lookup bits for tl */
1247 cab_LONG bd; /* lookup bits for td */
1248 cab_ULONG nb; /* number of bit length codes */
1249 cab_ULONG nl; /* number of literal/length codes */
1250 cab_ULONG nd; /* number of distance codes */
1251 register cab_ULONG b; /* bit buffer */
1252 register cab_ULONG k; /* number of bits in bit buffer */
1254 /* make local bit buffer */
1255 b = ZIP(bb);
1256 k = ZIP(bk);
1257 ll = ZIP(ll);
1259 /* read in table lengths */
1260 ZIPNEEDBITS(5)
1261 nl = 257 + (b & 0x1f); /* number of literal/length codes */
1262 ZIPDUMPBITS(5)
1263 ZIPNEEDBITS(5)
1264 nd = 1 + (b & 0x1f); /* number of distance codes */
1265 ZIPDUMPBITS(5)
1266 ZIPNEEDBITS(4)
1267 nb = 4 + (b & 0xf); /* number of bit length codes */
1268 ZIPDUMPBITS(4)
1269 if(nl > 288 || nd > 32)
1270 return 1; /* bad lengths */
1272 /* read in bit-length-code lengths */
1273 for(j = 0; j < nb; j++)
1275 ZIPNEEDBITS(3)
1276 ll[Zipborder[j]] = b & 7;
1277 ZIPDUMPBITS(3)
1279 for(; j < 19; j++)
1280 ll[Zipborder[j]] = 0;
1282 /* build decoding table for trees--single level, 7 bit lookup */
1283 bl = 7;
1284 if((i = fdi_Ziphuft_build(ll, 19, 19, NULL, NULL, &tl, &bl, decomp_state)) != 0)
1286 if(i == 1)
1287 fdi_Ziphuft_free(CAB(fdi), tl);
1288 return i; /* incomplete code set */
1291 /* read in literal and distance code lengths */
1292 n = nl + nd;
1293 m = Zipmask[bl];
1294 i = l = 0;
1295 while((cab_ULONG)i < n)
1297 ZIPNEEDBITS((cab_ULONG)bl)
1298 j = (td = tl + (b & m))->b;
1299 ZIPDUMPBITS(j)
1300 j = td->v.n;
1301 if (j < 16) /* length of code in bits (0..15) */
1302 ll[i++] = l = j; /* save last length in l */
1303 else if (j == 16) /* repeat last length 3 to 6 times */
1305 ZIPNEEDBITS(2)
1306 j = 3 + (b & 3);
1307 ZIPDUMPBITS(2)
1308 if((cab_ULONG)i + j > n)
1309 return 1;
1310 while (j--)
1311 ll[i++] = l;
1313 else if (j == 17) /* 3 to 10 zero length codes */
1315 ZIPNEEDBITS(3)
1316 j = 3 + (b & 7);
1317 ZIPDUMPBITS(3)
1318 if ((cab_ULONG)i + j > n)
1319 return 1;
1320 while (j--)
1321 ll[i++] = 0;
1322 l = 0;
1324 else /* j == 18: 11 to 138 zero length codes */
1326 ZIPNEEDBITS(7)
1327 j = 11 + (b & 0x7f);
1328 ZIPDUMPBITS(7)
1329 if ((cab_ULONG)i + j > n)
1330 return 1;
1331 while (j--)
1332 ll[i++] = 0;
1333 l = 0;
1337 /* free decoding table for trees */
1338 fdi_Ziphuft_free(CAB(fdi), tl);
1340 /* restore the global bit buffer */
1341 ZIP(bb) = b;
1342 ZIP(bk) = k;
1344 /* build the decoding tables for literal/length and distance codes */
1345 bl = ZIPLBITS;
1346 if((i = fdi_Ziphuft_build(ll, nl, 257, Zipcplens, Zipcplext, &tl, &bl, decomp_state)) != 0)
1348 if(i == 1)
1349 fdi_Ziphuft_free(CAB(fdi), tl);
1350 return i; /* incomplete code set */
1352 bd = ZIPDBITS;
1353 fdi_Ziphuft_build(ll + nl, nd, 0, Zipcpdist, Zipcpdext, &td, &bd, decomp_state);
1355 /* decompress until an end-of-block code */
1356 if(fdi_Zipinflate_codes(tl, td, bl, bd, decomp_state))
1357 return 1;
1359 /* free the decoding tables, return */
1360 fdi_Ziphuft_free(CAB(fdi), tl);
1361 fdi_Ziphuft_free(CAB(fdi), td);
1362 return 0;
1365 /*****************************************************
1366 * fdi_Zipinflate_block (internal)
1368 static cab_LONG fdi_Zipinflate_block(cab_LONG *e, fdi_decomp_state *decomp_state) /* e == last block flag */
1369 { /* decompress an inflated block */
1370 cab_ULONG t; /* block type */
1371 register cab_ULONG b; /* bit buffer */
1372 register cab_ULONG k; /* number of bits in bit buffer */
1374 /* make local bit buffer */
1375 b = ZIP(bb);
1376 k = ZIP(bk);
1378 /* read in last block bit */
1379 ZIPNEEDBITS(1)
1380 *e = (cab_LONG)b & 1;
1381 ZIPDUMPBITS(1)
1383 /* read in block type */
1384 ZIPNEEDBITS(2)
1385 t = b & 3;
1386 ZIPDUMPBITS(2)
1388 /* restore the global bit buffer */
1389 ZIP(bb) = b;
1390 ZIP(bk) = k;
1392 /* inflate that block type */
1393 if(t == 2)
1394 return fdi_Zipinflate_dynamic(decomp_state);
1395 if(t == 0)
1396 return fdi_Zipinflate_stored(decomp_state);
1397 if(t == 1)
1398 return fdi_Zipinflate_fixed(decomp_state);
1399 /* bad block type */
1400 return 2;
1403 /****************************************************
1404 * ZIPfdi_decomp(internal)
1406 static int ZIPfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state)
1408 cab_LONG e; /* last block flag */
1410 TRACE("(inlen == %d, outlen == %d)\n", inlen, outlen);
1412 ZIP(inpos) = CAB(inbuf);
1413 ZIP(bb) = ZIP(bk) = ZIP(window_posn) = 0;
1414 if(outlen > ZIPWSIZE)
1415 return DECR_DATAFORMAT;
1417 /* CK = Chris Kirmse, official Microsoft purloiner */
1418 if(ZIP(inpos)[0] != 0x43 || ZIP(inpos)[1] != 0x4B)
1419 return DECR_ILLEGALDATA;
1420 ZIP(inpos) += 2;
1422 do {
1423 if(fdi_Zipinflate_block(&e, decomp_state))
1424 return DECR_ILLEGALDATA;
1425 } while(!e);
1427 /* return success */
1428 return DECR_OK;
1431 /*******************************************************************
1432 * QTMfdi_decomp(internal)
1434 static int QTMfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state)
1436 cab_UBYTE *inpos = CAB(inbuf);
1437 cab_UBYTE *window = QTM(window);
1438 cab_UBYTE *runsrc, *rundest;
1439 cab_ULONG window_posn = QTM(window_posn);
1440 cab_ULONG window_size = QTM(window_size);
1442 /* used by bitstream macros */
1443 register int bitsleft, bitrun, bitsneed;
1444 register cab_ULONG bitbuf;
1446 /* used by GET_SYMBOL */
1447 cab_ULONG range;
1448 cab_UWORD symf;
1449 int i;
1451 int extra, togo = outlen, match_length = 0, copy_length;
1452 cab_UBYTE selector, sym;
1453 cab_ULONG match_offset = 0;
1455 cab_UWORD H = 0xFFFF, L = 0, C;
1457 TRACE("(inlen == %d, outlen == %d)\n", inlen, outlen);
1459 /* read initial value of C */
1460 Q_INIT_BITSTREAM;
1461 Q_READ_BITS(C, 16);
1463 /* apply 2^x-1 mask */
1464 window_posn &= window_size - 1;
1465 /* runs can't straddle the window wraparound */
1466 if ((window_posn + togo) > window_size) {
1467 TRACE("straddled run\n");
1468 return DECR_DATAFORMAT;
1471 while (togo > 0) {
1472 GET_SYMBOL(model7, selector);
1473 switch (selector) {
1474 case 0:
1475 GET_SYMBOL(model00, sym); window[window_posn++] = sym; togo--;
1476 break;
1477 case 1:
1478 GET_SYMBOL(model40, sym); window[window_posn++] = sym; togo--;
1479 break;
1480 case 2:
1481 GET_SYMBOL(model80, sym); window[window_posn++] = sym; togo--;
1482 break;
1483 case 3:
1484 GET_SYMBOL(modelC0, sym); window[window_posn++] = sym; togo--;
1485 break;
1487 case 4:
1488 /* selector 4 = fixed length of 3 */
1489 GET_SYMBOL(model4, sym);
1490 Q_READ_BITS(extra, CAB(q_extra_bits)[sym]);
1491 match_offset = CAB(q_position_base)[sym] + extra + 1;
1492 match_length = 3;
1493 break;
1495 case 5:
1496 /* selector 5 = fixed length of 4 */
1497 GET_SYMBOL(model5, sym);
1498 Q_READ_BITS(extra, CAB(q_extra_bits)[sym]);
1499 match_offset = CAB(q_position_base)[sym] + extra + 1;
1500 match_length = 4;
1501 break;
1503 case 6:
1504 /* selector 6 = variable length */
1505 GET_SYMBOL(model6len, sym);
1506 Q_READ_BITS(extra, CAB(q_length_extra)[sym]);
1507 match_length = CAB(q_length_base)[sym] + extra + 5;
1508 GET_SYMBOL(model6pos, sym);
1509 Q_READ_BITS(extra, CAB(q_extra_bits)[sym]);
1510 match_offset = CAB(q_position_base)[sym] + extra + 1;
1511 break;
1513 default:
1514 TRACE("Selector is bogus\n");
1515 return DECR_ILLEGALDATA;
1518 /* if this is a match */
1519 if (selector >= 4) {
1520 rundest = window + window_posn;
1521 togo -= match_length;
1523 /* copy any wrapped around source data */
1524 if (window_posn >= match_offset) {
1525 /* no wrap */
1526 runsrc = rundest - match_offset;
1527 } else {
1528 runsrc = rundest + (window_size - match_offset);
1529 copy_length = match_offset - window_posn;
1530 if (copy_length < match_length) {
1531 match_length -= copy_length;
1532 window_posn += copy_length;
1533 while (copy_length-- > 0) *rundest++ = *runsrc++;
1534 runsrc = window;
1537 window_posn += match_length;
1539 /* copy match data - no worries about destination wraps */
1540 while (match_length-- > 0) *rundest++ = *runsrc++;
1542 } /* while (togo > 0) */
1544 if (togo != 0) {
1545 TRACE("Frame overflow, this_run = %d\n", togo);
1546 return DECR_ILLEGALDATA;
1549 memcpy(CAB(outbuf), window + ((!window_posn) ? window_size : window_posn) -
1550 outlen, outlen);
1552 QTM(window_posn) = window_posn;
1553 return DECR_OK;
1556 /************************************************************
1557 * fdi_lzx_read_lens (internal)
1559 static int fdi_lzx_read_lens(cab_UBYTE *lens, cab_ULONG first, cab_ULONG last, struct lzx_bits *lb,
1560 fdi_decomp_state *decomp_state) {
1561 cab_ULONG i,j, x,y;
1562 int z;
1564 register cab_ULONG bitbuf = lb->bb;
1565 register int bitsleft = lb->bl;
1566 cab_UBYTE *inpos = lb->ip;
1567 cab_UWORD *hufftbl;
1569 for (x = 0; x < 20; x++) {
1570 READ_BITS(y, 4);
1571 LENTABLE(PRETREE)[x] = y;
1573 BUILD_TABLE(PRETREE);
1575 for (x = first; x < last; ) {
1576 READ_HUFFSYM(PRETREE, z);
1577 if (z == 17) {
1578 READ_BITS(y, 4); y += 4;
1579 while (y--) lens[x++] = 0;
1581 else if (z == 18) {
1582 READ_BITS(y, 5); y += 20;
1583 while (y--) lens[x++] = 0;
1585 else if (z == 19) {
1586 READ_BITS(y, 1); y += 4;
1587 READ_HUFFSYM(PRETREE, z);
1588 z = lens[x] - z; if (z < 0) z += 17;
1589 while (y--) lens[x++] = z;
1591 else {
1592 z = lens[x] - z; if (z < 0) z += 17;
1593 lens[x++] = z;
1597 lb->bb = bitbuf;
1598 lb->bl = bitsleft;
1599 lb->ip = inpos;
1600 return 0;
1603 /*******************************************************
1604 * LZXfdi_decomp(internal)
1606 static int LZXfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state) {
1607 cab_UBYTE *inpos = CAB(inbuf);
1608 const cab_UBYTE *endinp = inpos + inlen;
1609 cab_UBYTE *window = LZX(window);
1610 cab_UBYTE *runsrc, *rundest;
1611 cab_UWORD *hufftbl; /* used in READ_HUFFSYM macro as chosen decoding table */
1613 cab_ULONG window_posn = LZX(window_posn);
1614 cab_ULONG window_size = LZX(window_size);
1615 cab_ULONG R0 = LZX(R0);
1616 cab_ULONG R1 = LZX(R1);
1617 cab_ULONG R2 = LZX(R2);
1619 register cab_ULONG bitbuf;
1620 register int bitsleft;
1621 cab_ULONG match_offset, i,j,k; /* ijk used in READ_HUFFSYM macro */
1622 struct lzx_bits lb; /* used in READ_LENGTHS macro */
1624 int togo = outlen, this_run, main_element, aligned_bits;
1625 int match_length, copy_length, length_footer, extra, verbatim_bits;
1627 TRACE("(inlen == %d, outlen == %d)\n", inlen, outlen);
1629 INIT_BITSTREAM;
1631 /* read header if necessary */
1632 if (!LZX(header_read)) {
1633 i = j = 0;
1634 READ_BITS(k, 1); if (k) { READ_BITS(i,16); READ_BITS(j,16); }
1635 LZX(intel_filesize) = (i << 16) | j; /* or 0 if not encoded */
1636 LZX(header_read) = 1;
1639 /* main decoding loop */
1640 while (togo > 0) {
1641 /* last block finished, new block expected */
1642 if (LZX(block_remaining) == 0) {
1643 if (LZX(block_type) == LZX_BLOCKTYPE_UNCOMPRESSED) {
1644 if (LZX(block_length) & 1) inpos++; /* realign bitstream to word */
1645 INIT_BITSTREAM;
1648 READ_BITS(LZX(block_type), 3);
1649 READ_BITS(i, 16);
1650 READ_BITS(j, 8);
1651 LZX(block_remaining) = LZX(block_length) = (i << 8) | j;
1653 switch (LZX(block_type)) {
1654 case LZX_BLOCKTYPE_ALIGNED:
1655 for (i = 0; i < 8; i++) { READ_BITS(j, 3); LENTABLE(ALIGNED)[i] = j; }
1656 BUILD_TABLE(ALIGNED);
1657 /* rest of aligned header is same as verbatim */
1659 case LZX_BLOCKTYPE_VERBATIM:
1660 READ_LENGTHS(MAINTREE, 0, 256, fdi_lzx_read_lens);
1661 READ_LENGTHS(MAINTREE, 256, LZX(main_elements), fdi_lzx_read_lens);
1662 BUILD_TABLE(MAINTREE);
1663 if (LENTABLE(MAINTREE)[0xE8] != 0) LZX(intel_started) = 1;
1665 READ_LENGTHS(LENGTH, 0, LZX_NUM_SECONDARY_LENGTHS, fdi_lzx_read_lens);
1666 BUILD_TABLE(LENGTH);
1667 break;
1669 case LZX_BLOCKTYPE_UNCOMPRESSED:
1670 LZX(intel_started) = 1; /* because we can't assume otherwise */
1671 ENSURE_BITS(16); /* get up to 16 pad bits into the buffer */
1672 if (bitsleft > 16) inpos -= 2; /* and align the bitstream! */
1673 R0 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
1674 R1 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
1675 R2 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
1676 break;
1678 default:
1679 return DECR_ILLEGALDATA;
1683 /* buffer exhaustion check */
1684 if (inpos > endinp) {
1685 /* it's possible to have a file where the next run is less than
1686 * 16 bits in size. In this case, the READ_HUFFSYM() macro used
1687 * in building the tables will exhaust the buffer, so we should
1688 * allow for this, but not allow those accidentally read bits to
1689 * be used (so we check that there are at least 16 bits
1690 * remaining - in this boundary case they aren't really part of
1691 * the compressed data)
1693 if (inpos > (endinp+2) || bitsleft < 16) return DECR_ILLEGALDATA;
1696 while ((this_run = LZX(block_remaining)) > 0 && togo > 0) {
1697 if (this_run > togo) this_run = togo;
1698 togo -= this_run;
1699 LZX(block_remaining) -= this_run;
1701 /* apply 2^x-1 mask */
1702 window_posn &= window_size - 1;
1703 /* runs can't straddle the window wraparound */
1704 if ((window_posn + this_run) > window_size)
1705 return DECR_DATAFORMAT;
1707 switch (LZX(block_type)) {
1709 case LZX_BLOCKTYPE_VERBATIM:
1710 while (this_run > 0) {
1711 READ_HUFFSYM(MAINTREE, main_element);
1713 if (main_element < LZX_NUM_CHARS) {
1714 /* literal: 0 to LZX_NUM_CHARS-1 */
1715 window[window_posn++] = main_element;
1716 this_run--;
1718 else {
1719 /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
1720 main_element -= LZX_NUM_CHARS;
1722 match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
1723 if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
1724 READ_HUFFSYM(LENGTH, length_footer);
1725 match_length += length_footer;
1727 match_length += LZX_MIN_MATCH;
1729 match_offset = main_element >> 3;
1731 if (match_offset > 2) {
1732 /* not repeated offset */
1733 if (match_offset != 3) {
1734 extra = CAB(extra_bits)[match_offset];
1735 READ_BITS(verbatim_bits, extra);
1736 match_offset = CAB(lzx_position_base)[match_offset]
1737 - 2 + verbatim_bits;
1739 else {
1740 match_offset = 1;
1743 /* update repeated offset LRU queue */
1744 R2 = R1; R1 = R0; R0 = match_offset;
1746 else if (match_offset == 0) {
1747 match_offset = R0;
1749 else if (match_offset == 1) {
1750 match_offset = R1;
1751 R1 = R0; R0 = match_offset;
1753 else /* match_offset == 2 */ {
1754 match_offset = R2;
1755 R2 = R0; R0 = match_offset;
1758 rundest = window + window_posn;
1759 this_run -= match_length;
1761 /* copy any wrapped around source data */
1762 if (window_posn >= match_offset) {
1763 /* no wrap */
1764 runsrc = rundest - match_offset;
1765 } else {
1766 runsrc = rundest + (window_size - match_offset);
1767 copy_length = match_offset - window_posn;
1768 if (copy_length < match_length) {
1769 match_length -= copy_length;
1770 window_posn += copy_length;
1771 while (copy_length-- > 0) *rundest++ = *runsrc++;
1772 runsrc = window;
1775 window_posn += match_length;
1777 /* copy match data - no worries about destination wraps */
1778 while (match_length-- > 0) *rundest++ = *runsrc++;
1781 break;
1783 case LZX_BLOCKTYPE_ALIGNED:
1784 while (this_run > 0) {
1785 READ_HUFFSYM(MAINTREE, main_element);
1787 if (main_element < LZX_NUM_CHARS) {
1788 /* literal: 0 to LZX_NUM_CHARS-1 */
1789 window[window_posn++] = main_element;
1790 this_run--;
1792 else {
1793 /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
1794 main_element -= LZX_NUM_CHARS;
1796 match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
1797 if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
1798 READ_HUFFSYM(LENGTH, length_footer);
1799 match_length += length_footer;
1801 match_length += LZX_MIN_MATCH;
1803 match_offset = main_element >> 3;
1805 if (match_offset > 2) {
1806 /* not repeated offset */
1807 extra = CAB(extra_bits)[match_offset];
1808 match_offset = CAB(lzx_position_base)[match_offset] - 2;
1809 if (extra > 3) {
1810 /* verbatim and aligned bits */
1811 extra -= 3;
1812 READ_BITS(verbatim_bits, extra);
1813 match_offset += (verbatim_bits << 3);
1814 READ_HUFFSYM(ALIGNED, aligned_bits);
1815 match_offset += aligned_bits;
1817 else if (extra == 3) {
1818 /* aligned bits only */
1819 READ_HUFFSYM(ALIGNED, aligned_bits);
1820 match_offset += aligned_bits;
1822 else if (extra > 0) { /* extra==1, extra==2 */
1823 /* verbatim bits only */
1824 READ_BITS(verbatim_bits, extra);
1825 match_offset += verbatim_bits;
1827 else /* extra == 0 */ {
1828 /* ??? */
1829 match_offset = 1;
1832 /* update repeated offset LRU queue */
1833 R2 = R1; R1 = R0; R0 = match_offset;
1835 else if (match_offset == 0) {
1836 match_offset = R0;
1838 else if (match_offset == 1) {
1839 match_offset = R1;
1840 R1 = R0; R0 = match_offset;
1842 else /* match_offset == 2 */ {
1843 match_offset = R2;
1844 R2 = R0; R0 = match_offset;
1847 rundest = window + window_posn;
1848 this_run -= match_length;
1850 /* copy any wrapped around source data */
1851 if (window_posn >= match_offset) {
1852 /* no wrap */
1853 runsrc = rundest - match_offset;
1854 } else {
1855 runsrc = rundest + (window_size - match_offset);
1856 copy_length = match_offset - window_posn;
1857 if (copy_length < match_length) {
1858 match_length -= copy_length;
1859 window_posn += copy_length;
1860 while (copy_length-- > 0) *rundest++ = *runsrc++;
1861 runsrc = window;
1864 window_posn += match_length;
1866 /* copy match data - no worries about destination wraps */
1867 while (match_length-- > 0) *rundest++ = *runsrc++;
1870 break;
1872 case LZX_BLOCKTYPE_UNCOMPRESSED:
1873 if ((inpos + this_run) > endinp) return DECR_ILLEGALDATA;
1874 memcpy(window + window_posn, inpos, (size_t) this_run);
1875 inpos += this_run; window_posn += this_run;
1876 break;
1878 default:
1879 return DECR_ILLEGALDATA; /* might as well */
1885 if (togo != 0) return DECR_ILLEGALDATA;
1886 memcpy(CAB(outbuf), window + ((!window_posn) ? window_size : window_posn) -
1887 outlen, (size_t) outlen);
1889 LZX(window_posn) = window_posn;
1890 LZX(R0) = R0;
1891 LZX(R1) = R1;
1892 LZX(R2) = R2;
1894 /* intel E8 decoding */
1895 if ((LZX(frames_read)++ < 32768) && LZX(intel_filesize) != 0) {
1896 if (outlen <= 6 || !LZX(intel_started)) {
1897 LZX(intel_curpos) += outlen;
1899 else {
1900 cab_UBYTE *data = CAB(outbuf);
1901 cab_UBYTE *dataend = data + outlen - 10;
1902 cab_LONG curpos = LZX(intel_curpos);
1903 cab_LONG filesize = LZX(intel_filesize);
1904 cab_LONG abs_off, rel_off;
1906 LZX(intel_curpos) = curpos + outlen;
1908 while (data < dataend) {
1909 if (*data++ != 0xE8) { curpos++; continue; }
1910 abs_off = data[0] | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);
1911 if ((abs_off >= -curpos) && (abs_off < filesize)) {
1912 rel_off = (abs_off >= 0) ? abs_off - curpos : abs_off + filesize;
1913 data[0] = (cab_UBYTE) rel_off;
1914 data[1] = (cab_UBYTE) (rel_off >> 8);
1915 data[2] = (cab_UBYTE) (rel_off >> 16);
1916 data[3] = (cab_UBYTE) (rel_off >> 24);
1918 data += 4;
1919 curpos += 5;
1923 return DECR_OK;
1926 /**********************************************************
1927 * fdi_decomp (internal)
1929 * Decompress the requested number of bytes. If savemode is zero,
1930 * do not save the output anywhere, just plow through blocks until we
1931 * reach the specified (uncompressed) distance from the starting point,
1932 * and remember the position of the cabfile pointer (and which cabfile)
1933 * after we are done; otherwise, save the data out to CAB(filehf),
1934 * decompressing the requested number of bytes and writing them out. This
1935 * is also where we jump to additional cabinets in the case of split
1936 * cab's, and provide (some of) the NEXT_CABINET notification semantics.
1938 static int fdi_decomp(const struct fdi_file *fi, int savemode, fdi_decomp_state *decomp_state,
1939 char *pszCabPath, PFNFDINOTIFY pfnfdin, void *pvUser)
1941 cab_ULONG bytes = savemode ? fi->length : fi->offset - CAB(offset);
1942 cab_UBYTE buf[cfdata_SIZEOF], *data;
1943 cab_UWORD inlen, len, outlen, cando;
1944 cab_ULONG cksum;
1945 cab_LONG err;
1946 fdi_decomp_state *cab = (savemode && CAB(decomp_cab)) ? CAB(decomp_cab) : decomp_state;
1948 TRACE("(fi == ^%p, savemode == %d, bytes == %d)\n", fi, savemode, bytes);
1950 while (bytes > 0) {
1951 /* cando = the max number of bytes we can do */
1952 cando = CAB(outlen);
1953 if (cando > bytes) cando = bytes;
1955 /* if cando != 0 */
1956 if (cando && savemode)
1957 CAB(fdi)->write(CAB(filehf), CAB(outpos), cando);
1959 CAB(outpos) += cando;
1960 CAB(outlen) -= cando;
1961 bytes -= cando; if (!bytes) break;
1963 /* we only get here if we emptied the output buffer */
1965 /* read data header + data */
1966 inlen = outlen = 0;
1967 while (outlen == 0) {
1968 /* read the block header, skip the reserved part */
1969 if (CAB(fdi)->read(cab->cabhf, buf, cfdata_SIZEOF) != cfdata_SIZEOF)
1970 return DECR_INPUT;
1972 if (CAB(fdi)->seek(cab->cabhf, cab->mii.block_resv, SEEK_CUR) == -1)
1973 return DECR_INPUT;
1975 /* we shouldn't get blocks over CAB_INPUTMAX in size */
1976 data = CAB(inbuf) + inlen;
1977 len = EndGetI16(buf+cfdata_CompressedSize);
1978 inlen += len;
1979 if (inlen > CAB_INPUTMAX) return DECR_INPUT;
1980 if (CAB(fdi)->read(cab->cabhf, data, len) != len)
1981 return DECR_INPUT;
1983 /* clear two bytes after read-in data */
1984 data[len+1] = data[len+2] = 0;
1986 /* perform checksum test on the block (if one is stored) */
1987 cksum = EndGetI32(buf+cfdata_CheckSum);
1988 if (cksum && cksum != checksum(buf+4, 4, checksum(data, len, 0)))
1989 return DECR_CHECKSUM; /* checksum is wrong */
1991 outlen = EndGetI16(buf+cfdata_UncompressedSize);
1993 /* outlen=0 means this block was the last contiguous part
1994 of a split block, continued in the next cabinet */
1995 if (outlen == 0) {
1996 int pathlen, filenamelen;
1997 INT_PTR cabhf;
1998 char fullpath[MAX_PATH], userpath[256];
1999 FDINOTIFICATION fdin;
2000 FDICABINETINFO fdici;
2001 char emptystring = '\0';
2002 cab_UBYTE buf2[64];
2003 BOOL success = FALSE;
2004 struct fdi_folder *fol = NULL, *linkfol = NULL;
2005 struct fdi_file *file = NULL, *linkfile = NULL;
2007 tryanothercab:
2009 /* set up the next decomp_state... */
2010 if (!(cab->next)) {
2011 unsigned int i;
2013 if (!cab->mii.hasnext) return DECR_INPUT;
2015 if (!((cab->next = CAB(fdi)->alloc(sizeof(fdi_decomp_state)))))
2016 return DECR_NOMEMORY;
2018 ZeroMemory(cab->next, sizeof(fdi_decomp_state));
2020 /* copy pszCabPath to userpath */
2021 ZeroMemory(userpath, 256);
2022 pathlen = pszCabPath ? strlen(pszCabPath) : 0;
2023 if (pathlen) {
2024 if (pathlen < 256) /* else we are in a weird place... let's leave it blank and see if the user fixes it */
2025 strcpy(userpath, pszCabPath);
2028 /* initial fdintNEXT_CABINET notification */
2029 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2030 fdin.psz1 = cab->mii.nextname ? cab->mii.nextname : &emptystring;
2031 fdin.psz2 = cab->mii.nextinfo ? cab->mii.nextinfo : &emptystring;
2032 fdin.psz3 = userpath;
2033 fdin.fdie = FDIERROR_NONE;
2034 fdin.pv = pvUser;
2036 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2038 do {
2040 pathlen = strlen(userpath);
2041 filenamelen = cab->mii.nextname ? strlen(cab->mii.nextname) : 0;
2043 /* slight overestimation here to save CPU cycles in the developer's brain */
2044 if ((pathlen + filenamelen + 3) > MAX_PATH) {
2045 ERR("MAX_PATH exceeded.\n");
2046 return DECR_ILLEGALDATA;
2049 /* paste the path and filename together */
2050 fullpath[0] = '\0';
2051 if (pathlen) {
2052 strcpy(fullpath, userpath);
2053 if (fullpath[pathlen - 1] != '\\')
2054 strcat(fullpath, "\\");
2056 if (filenamelen)
2057 strcat(fullpath, cab->mii.nextname);
2059 TRACE("full cab path/file name: %s\n", debugstr_a(fullpath));
2061 /* try to get a handle to the cabfile */
2062 cabhf = CAB(fdi)->open(fullpath, _O_RDONLY|_O_BINARY, _S_IREAD | _S_IWRITE);
2063 if (cabhf == -1) {
2064 /* no file. allow the user to try again */
2065 fdin.fdie = FDIERROR_CABINET_NOT_FOUND;
2066 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2067 continue;
2070 if (cabhf == 0) {
2071 ERR("PFDI_OPEN returned zero for %s.\n", fullpath);
2072 fdin.fdie = FDIERROR_CABINET_NOT_FOUND;
2073 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2074 continue;
2077 /* check if it's really a cabfile. Note that this doesn't implement the bug */
2078 if (!FDI_read_entries(CAB(fdi), cabhf, &fdici, &(cab->next->mii))) {
2079 WARN("FDIIsCabinet failed.\n");
2080 CAB(fdi)->close(cabhf);
2081 fdin.fdie = FDIERROR_NOT_A_CABINET;
2082 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2083 continue;
2086 if ((fdici.setID != cab->setID) || (fdici.iCabinet != (cab->iCabinet + 1))) {
2087 WARN("Wrong Cabinet.\n");
2088 CAB(fdi)->close(cabhf);
2089 fdin.fdie = FDIERROR_WRONG_CABINET;
2090 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2091 continue;
2094 break;
2096 } while (1);
2098 /* cabinet notification */
2099 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2100 fdin.setID = fdici.setID;
2101 fdin.iCabinet = fdici.iCabinet;
2102 fdin.pv = pvUser;
2103 fdin.psz1 = (cab->next->mii.nextname) ? cab->next->mii.nextname : &emptystring;
2104 fdin.psz2 = (cab->next->mii.nextinfo) ? cab->next->mii.nextinfo : &emptystring;
2105 fdin.psz3 = pszCabPath;
2107 if (((*pfnfdin)(fdintCABINET_INFO, &fdin))) return DECR_USERABORT;
2109 cab->next->setID = fdici.setID;
2110 cab->next->iCabinet = fdici.iCabinet;
2111 cab->next->fdi = CAB(fdi);
2112 cab->next->filehf = CAB(filehf);
2113 cab->next->cabhf = cabhf;
2114 cab->next->decompress = CAB(decompress); /* crude, but unused anyhow */
2116 cab = cab->next; /* advance to the next cabinet */
2118 /* read folders */
2119 for (i = 0; i < fdici.cFolders; i++) {
2120 if (CAB(fdi)->read(cab->cabhf, buf2, cffold_SIZEOF) != cffold_SIZEOF)
2121 return DECR_INPUT;
2123 if (cab->mii.folder_resv > 0)
2124 CAB(fdi)->seek(cab->cabhf, cab->mii.folder_resv, SEEK_CUR);
2126 fol = CAB(fdi)->alloc(sizeof(struct fdi_folder));
2127 if (!fol) {
2128 ERR("out of memory!\n");
2129 return DECR_NOMEMORY;
2131 ZeroMemory(fol, sizeof(struct fdi_folder));
2132 if (!(cab->firstfol)) cab->firstfol = fol;
2134 fol->offset = (cab_off_t) EndGetI32(buf2+cffold_DataOffset);
2135 fol->num_blocks = EndGetI16(buf2+cffold_NumBlocks);
2136 fol->comp_type = EndGetI16(buf2+cffold_CompType);
2138 if (linkfol)
2139 linkfol->next = fol;
2140 linkfol = fol;
2143 /* read files */
2144 for (i = 0; i < fdici.cFiles; i++) {
2145 if (CAB(fdi)->read(cab->cabhf, buf2, cffile_SIZEOF) != cffile_SIZEOF)
2146 return DECR_INPUT;
2148 file = CAB(fdi)->alloc(sizeof(struct fdi_file));
2149 if (!file) {
2150 ERR("out of memory!\n");
2151 return DECR_NOMEMORY;
2153 ZeroMemory(file, sizeof(struct fdi_file));
2154 if (!(cab->firstfile)) cab->firstfile = file;
2156 file->length = EndGetI32(buf2+cffile_UncompressedSize);
2157 file->offset = EndGetI32(buf2+cffile_FolderOffset);
2158 file->index = EndGetI16(buf2+cffile_FolderIndex);
2159 file->time = EndGetI16(buf2+cffile_Time);
2160 file->date = EndGetI16(buf2+cffile_Date);
2161 file->attribs = EndGetI16(buf2+cffile_Attribs);
2162 file->filename = FDI_read_string(CAB(fdi), cab->cabhf, fdici.cbCabinet);
2164 if (!file->filename) return DECR_INPUT;
2166 if (linkfile)
2167 linkfile->next = file;
2168 linkfile = file;
2171 } else
2172 cab = cab->next; /* advance to the next cabinet */
2174 /* iterate files -- if we encounter the continued file, process it --
2175 otherwise, jump to the label above and keep looking */
2177 for (file = cab->firstfile; (file); file = file->next) {
2178 if ((file->index & cffileCONTINUED_FROM_PREV) == cffileCONTINUED_FROM_PREV) {
2179 /* check to ensure a real match */
2180 if (lstrcmpiA(fi->filename, file->filename) == 0) {
2181 success = TRUE;
2182 if (CAB(fdi)->seek(cab->cabhf, cab->firstfol->offset, SEEK_SET) == -1)
2183 return DECR_INPUT;
2184 break;
2188 if (!success) goto tryanothercab; /* FIXME: shouldn't this trigger
2189 "Wrong Cabinet" notification? */
2193 /* decompress block */
2194 if ((err = CAB(decompress)(inlen, outlen, decomp_state)))
2195 return err;
2196 CAB(outlen) = outlen;
2197 CAB(outpos) = CAB(outbuf);
2200 CAB(decomp_cab) = cab;
2201 return DECR_OK;
2204 static void free_decompression_temps(FDI_Int *fdi, const struct fdi_folder *fol,
2205 fdi_decomp_state *decomp_state)
2207 switch (fol->comp_type & cffoldCOMPTYPE_MASK) {
2208 case cffoldCOMPTYPE_LZX:
2209 if (LZX(window)) {
2210 fdi->free(LZX(window));
2211 LZX(window) = NULL;
2213 break;
2214 case cffoldCOMPTYPE_QUANTUM:
2215 if (QTM(window)) {
2216 fdi->free(QTM(window));
2217 QTM(window) = NULL;
2219 break;
2223 static void free_decompression_mem(FDI_Int *fdi, fdi_decomp_state *decomp_state)
2225 struct fdi_folder *fol;
2226 while (decomp_state) {
2227 fdi_decomp_state *prev_fds;
2229 fdi->close(CAB(cabhf));
2231 /* free the storage remembered by mii */
2232 if (CAB(mii).nextname) fdi->free(CAB(mii).nextname);
2233 if (CAB(mii).nextinfo) fdi->free(CAB(mii).nextinfo);
2234 if (CAB(mii).prevname) fdi->free(CAB(mii).prevname);
2235 if (CAB(mii).previnfo) fdi->free(CAB(mii).previnfo);
2237 while (CAB(firstfol)) {
2238 fol = CAB(firstfol);
2239 CAB(firstfol) = CAB(firstfol)->next;
2240 fdi->free(fol);
2242 while (CAB(firstfile)) {
2243 struct fdi_file *file = CAB(firstfile);
2244 if (file->filename) fdi->free(file->filename);
2245 CAB(firstfile) = CAB(firstfile)->next;
2246 fdi->free(file);
2248 prev_fds = decomp_state;
2249 decomp_state = CAB(next);
2250 fdi->free(prev_fds);
2254 /***********************************************************************
2255 * FDICopy (CABINET.22)
2257 * Iterates through the files in the Cabinet file indicated by name and
2258 * file-location. May chain forward to additional cabinets (typically
2259 * only one) if files which begin in this Cabinet are continued in another
2260 * cabinet. For each file which is partially contained in this cabinet,
2261 * and partially contained in a prior cabinet, provides fdintPARTIAL_FILE
2262 * notification to the pfnfdin callback. For each file which begins in
2263 * this cabinet, fdintCOPY_FILE notification is provided to the pfnfdin
2264 * callback, and the file is optionally decompressed and saved to disk.
2265 * Notification is not provided for files which are not at least partially
2266 * contained in the specified cabinet file.
2268 * See below for a thorough explanation of the various notification
2269 * callbacks.
2271 * PARAMS
2272 * hfdi [I] An HFDI from FDICreate
2273 * pszCabinet [I] C-style string containing the filename of the cabinet
2274 * pszCabPath [I] C-style string containing the file path of the cabinet
2275 * flags [I] "Decoder parameters". Ignored. Suggested value: 0.
2276 * pfnfdin [I] Pointer to a notification function. See CALLBACKS below.
2277 * pfnfdid [I] Pointer to a decryption function. Ignored. Suggested
2278 * value: NULL.
2279 * pvUser [I] arbitrary void * value which is passed to callbacks.
2281 * RETURNS
2282 * TRUE if successful.
2283 * FALSE if unsuccessful (error information is provided in the ERF structure
2284 * associated with the provided decompression handle by FDICreate).
2286 * CALLBACKS
2288 * Two pointers to callback functions are provided as parameters to FDICopy:
2289 * pfnfdin(of type PFNFDINOTIFY), and pfnfdid (of type PFNFDIDECRYPT). These
2290 * types are as follows:
2292 * typedef INT_PTR (__cdecl *PFNFDINOTIFY) ( FDINOTIFICATIONTYPE fdint,
2293 * PFDINOTIFICATION pfdin );
2295 * typedef int (__cdecl *PFNFDIDECRYPT) ( PFDIDECRYPT pfdid );
2297 * You can create functions of this type using the FNFDINOTIFY() and
2298 * FNFDIDECRYPT() macros, respectively. For example:
2300 * FNFDINOTIFY(mycallback) {
2301 * / * use variables fdint and pfdin to process notification * /
2304 * The second callback, which could be used for decrypting encrypted data,
2305 * is not used at all.
2307 * Each notification informs the user of some event which has occurred during
2308 * decompression of the cabinet file; each notification is also an opportunity
2309 * for the callee to abort decompression. The information provided to the
2310 * callback and the meaning of the callback's return value vary drastically
2311 * across the various types of notification. The type of notification is the
2312 * fdint parameter; all other information is provided to the callback in
2313 * notification-specific parts of the FDINOTIFICATION structure pointed to by
2314 * pfdin. The only part of that structure which is assigned for every callback
2315 * is the pv element, which contains the arbitrary value which was passed to
2316 * FDICopy in the pvUser argument (psz1 is also used each time, but its meaning
2317 * is highly dependent on fdint).
2319 * If you encounter unknown notifications, you should return zero if you want
2320 * decompression to continue (or -1 to abort). All strings used in the
2321 * callbacks are regular C-style strings. Detailed descriptions of each
2322 * notification type follow:
2324 * fdintCABINET_INFO:
2326 * This is the first notification provided after calling FDICopy, and provides
2327 * the user with various information about the cabinet. Note that this is
2328 * called for each cabinet FDICopy opens, not just the first one. In the
2329 * structure pointed to by pfdin, psz1 contains a pointer to the name of the
2330 * next cabinet file in the set after the one just loaded (if any), psz2
2331 * contains a pointer to the name or "info" of the next disk, psz3
2332 * contains a pointer to the file-path of the current cabinet, setID
2333 * contains an arbitrary constant associated with this set of cabinet files,
2334 * and iCabinet contains the numerical index of the current cabinet within
2335 * that set. Return zero, or -1 to abort.
2337 * fdintPARTIAL_FILE:
2339 * This notification is provided when FDICopy encounters a part of a file
2340 * contained in this cabinet which is missing its beginning. Files can be
2341 * split across cabinets, so this is not necessarily an abnormality; it just
2342 * means that the file in question begins in another cabinet. No file
2343 * corresponding to this notification is extracted from the cabinet. In the
2344 * structure pointed to by pfdin, psz1 contains a pointer to the name of the
2345 * partial file, psz2 contains a pointer to the file name of the cabinet in
2346 * which this file begins, and psz3 contains a pointer to the disk name or
2347 * "info" of the cabinet where the file begins. Return zero, or -1 to abort.
2349 * fdintCOPY_FILE:
2351 * This notification is provided when FDICopy encounters a file which starts
2352 * in the cabinet file, provided to FDICopy in pszCabinet. (FDICopy will not
2353 * look for files in cabinets after the first one). One notification will be
2354 * sent for each such file, before the file is decompressed. By returning
2355 * zero, the callback can instruct FDICopy to skip the file. In the structure
2356 * pointed to by pfdin, psz1 contains a pointer to the file's name, cb contains
2357 * the size of the file (uncompressed), attribs contains the file attributes,
2358 * and date and time contain the date and time of the file. attributes, date,
2359 * and time are of the 16-bit ms-dos variety. Return -1 to abort decompression
2360 * for the entire cabinet, 0 to skip just this file but continue scanning the
2361 * cabinet for more files, or an FDIClose()-compatible file-handle.
2363 * fdintCLOSE_FILE_INFO:
2365 * This notification is important, don't forget to implement it. This
2366 * notification indicates that a file has been successfully uncompressed and
2367 * written to disk. Upon receipt of this notification, the callee is expected
2368 * to close the file handle, to set the attributes and date/time of the
2369 * closed file, and possibly to execute the file. In the structure pointed to
2370 * by pfdin, psz1 contains a pointer to the name of the file, hf will be the
2371 * open file handle (close it), cb contains 1 or zero, indicating respectively
2372 * that the callee should or should not execute the file, and date, time
2373 * and attributes will be set as in fdintCOPY_FILE. Bizarrely, the Cabinet SDK
2374 * specifies that _A_EXEC will be xor'ed out of attributes! wine does not do
2375 * do so. Return TRUE, or FALSE to abort decompression.
2377 * fdintNEXT_CABINET:
2379 * This notification is called when FDICopy must load in another cabinet. This
2380 * can occur when a file's data is "split" across multiple cabinets. The
2381 * callee has the opportunity to request that FDICopy look in a different file
2382 * path for the specified cabinet file, by writing that data into a provided
2383 * buffer (see below for more information). This notification will be received
2384 * more than once per-cabinet in the instance that FDICopy failed to find a
2385 * valid cabinet at the location specified by the first per-cabinet
2386 * fdintNEXT_CABINET notification. In such instances, the fdie element of the
2387 * structure pointed to by pfdin indicates the error which prevented FDICopy
2388 * from proceeding successfully. Return zero to indicate success, or -1 to
2389 * indicate failure and abort FDICopy.
2391 * Upon receipt of this notification, the structure pointed to by pfdin will
2392 * contain the following values: psz1 pointing to the name of the cabinet
2393 * which FDICopy is attempting to open, psz2 pointing to the name ("info") of
2394 * the next disk, psz3 pointing to the presumed file-location of the cabinet,
2395 * and fdie containing either FDIERROR_NONE, or one of the following:
2397 * FDIERROR_CABINET_NOT_FOUND, FDIERROR_NOT_A_CABINET,
2398 * FDIERROR_UNKNOWN_CABINET_VERSION, FDIERROR_CORRUPT_CABINET,
2399 * FDIERROR_BAD_COMPR_TYPE, FDIERROR_RESERVE_MISMATCH, and
2400 * FDIERROR_WRONG_CABINET.
2402 * The callee may choose to change the path where FDICopy will look for the
2403 * cabinet after this notification. To do so, the caller may write the new
2404 * pathname to the buffer pointed to by psz3, which is 256 characters in
2405 * length, including the terminating null character, before returning zero.
2407 * fdintENUMERATE:
2409 * Undocumented and unimplemented in wine, this seems to be sent each time
2410 * a cabinet is opened, along with the fdintCABINET_INFO notification. It
2411 * probably has an interface similar to that of fdintCABINET_INFO; maybe this
2412 * provides information about the current cabinet instead of the next one....
2413 * this is just a guess, it has not been looked at closely.
2415 * INCLUDES
2416 * fdi.c
2418 BOOL __cdecl FDICopy(
2419 HFDI hfdi,
2420 char *pszCabinet,
2421 char *pszCabPath,
2422 int flags,
2423 PFNFDINOTIFY pfnfdin,
2424 PFNFDIDECRYPT pfnfdid,
2425 void *pvUser)
2427 FDICABINETINFO fdici;
2428 FDINOTIFICATION fdin;
2429 INT_PTR cabhf, filehf = 0;
2430 unsigned int i;
2431 char fullpath[MAX_PATH];
2432 size_t pathlen, filenamelen;
2433 char emptystring = '\0';
2434 cab_UBYTE buf[64];
2435 struct fdi_folder *fol = NULL, *linkfol = NULL;
2436 struct fdi_file *file = NULL, *linkfile = NULL;
2437 fdi_decomp_state *decomp_state;
2438 FDI_Int *fdi = get_fdi_ptr( hfdi );
2440 TRACE("(hfdi == ^%p, pszCabinet == %s, pszCabPath == %s, flags == %x, "
2441 "pfnfdin == ^%p, pfnfdid == ^%p, pvUser == ^%p)\n",
2442 hfdi, debugstr_a(pszCabinet), debugstr_a(pszCabPath), flags, pfnfdin, pfnfdid, pvUser);
2444 if (!fdi) return FALSE;
2446 if (!(decomp_state = fdi->alloc(sizeof(fdi_decomp_state))))
2448 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2449 return FALSE;
2451 ZeroMemory(decomp_state, sizeof(fdi_decomp_state));
2453 pathlen = pszCabPath ? strlen(pszCabPath) : 0;
2454 filenamelen = pszCabinet ? strlen(pszCabinet) : 0;
2456 /* slight overestimation here to save CPU cycles in the developer's brain */
2457 if ((pathlen + filenamelen + 3) > MAX_PATH) {
2458 ERR("MAX_PATH exceeded.\n");
2459 fdi->free(decomp_state);
2460 set_error( fdi, FDIERROR_CABINET_NOT_FOUND, ERROR_FILE_NOT_FOUND );
2461 return FALSE;
2464 /* paste the path and filename together */
2465 fullpath[0] = '\0';
2466 if (pathlen)
2467 strcpy(fullpath, pszCabPath);
2468 if (filenamelen)
2469 strcat(fullpath, pszCabinet);
2471 TRACE("full cab path/file name: %s\n", debugstr_a(fullpath));
2473 /* get a handle to the cabfile */
2474 cabhf = fdi->open(fullpath, _O_RDONLY|_O_BINARY, _S_IREAD | _S_IWRITE);
2475 if (cabhf == -1) {
2476 fdi->free(decomp_state);
2477 set_error( fdi, FDIERROR_CABINET_NOT_FOUND, 0 );
2478 SetLastError(ERROR_FILE_NOT_FOUND);
2479 return FALSE;
2482 /* check if it's really a cabfile. Note that this doesn't implement the bug */
2483 if (!FDI_read_entries(fdi, cabhf, &fdici, &(CAB(mii)))) {
2484 WARN("FDI_read_entries failed: %u\n", fdi->perf->erfOper);
2485 fdi->free(decomp_state);
2486 fdi->close(cabhf);
2487 return FALSE;
2490 /* cabinet notification */
2491 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2492 fdin.setID = fdici.setID;
2493 fdin.iCabinet = fdici.iCabinet;
2494 fdin.pv = pvUser;
2495 fdin.psz1 = (CAB(mii).nextname) ? CAB(mii).nextname : &emptystring;
2496 fdin.psz2 = (CAB(mii).nextinfo) ? CAB(mii).nextinfo : &emptystring;
2497 fdin.psz3 = pszCabPath;
2499 if (pfnfdin(fdintCABINET_INFO, &fdin) == -1) {
2500 set_error( fdi, FDIERROR_USER_ABORT, 0 );
2501 goto bail_and_fail;
2504 CAB(setID) = fdici.setID;
2505 CAB(iCabinet) = fdici.iCabinet;
2506 CAB(cabhf) = cabhf;
2508 /* read folders */
2509 for (i = 0; i < fdici.cFolders; i++) {
2510 if (fdi->read(cabhf, buf, cffold_SIZEOF) != cffold_SIZEOF) {
2511 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
2512 goto bail_and_fail;
2515 if (CAB(mii).folder_resv > 0)
2516 fdi->seek(cabhf, CAB(mii).folder_resv, SEEK_CUR);
2518 fol = fdi->alloc(sizeof(struct fdi_folder));
2519 if (!fol) {
2520 ERR("out of memory!\n");
2521 set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY );
2522 goto bail_and_fail;
2524 ZeroMemory(fol, sizeof(struct fdi_folder));
2525 if (!CAB(firstfol)) CAB(firstfol) = fol;
2527 fol->offset = (cab_off_t) EndGetI32(buf+cffold_DataOffset);
2528 fol->num_blocks = EndGetI16(buf+cffold_NumBlocks);
2529 fol->comp_type = EndGetI16(buf+cffold_CompType);
2531 if (linkfol)
2532 linkfol->next = fol;
2533 linkfol = fol;
2536 /* read files */
2537 for (i = 0; i < fdici.cFiles; i++) {
2538 if (fdi->read(cabhf, buf, cffile_SIZEOF) != cffile_SIZEOF) {
2539 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
2540 goto bail_and_fail;
2543 file = fdi->alloc(sizeof(struct fdi_file));
2544 if (!file) {
2545 ERR("out of memory!\n");
2546 set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY );
2547 goto bail_and_fail;
2549 ZeroMemory(file, sizeof(struct fdi_file));
2550 if (!CAB(firstfile)) CAB(firstfile) = file;
2552 file->length = EndGetI32(buf+cffile_UncompressedSize);
2553 file->offset = EndGetI32(buf+cffile_FolderOffset);
2554 file->index = EndGetI16(buf+cffile_FolderIndex);
2555 file->time = EndGetI16(buf+cffile_Time);
2556 file->date = EndGetI16(buf+cffile_Date);
2557 file->attribs = EndGetI16(buf+cffile_Attribs);
2558 file->filename = FDI_read_string(fdi, cabhf, fdici.cbCabinet);
2560 if (!file->filename) {
2561 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
2562 goto bail_and_fail;
2565 if (linkfile)
2566 linkfile->next = file;
2567 linkfile = file;
2570 for (file = CAB(firstfile); (file); file = file->next) {
2573 * FIXME: This implementation keeps multiple cabinet files open at once
2574 * when encountering a split cabinet. It is a quirk of this implementation
2575 * that sometimes we decrypt the same block of data more than once, to find
2576 * the right starting point for a file, moving the file-pointer backwards.
2577 * If we kept a cache of certain file-pointer information, we could eliminate
2578 * that behavior... in fact I am not sure that the caching we already have
2579 * is not sufficient.
2581 * The current implementation seems to work fine in straightforward situations
2582 * where all the cabinet files needed for decryption are simultaneously
2583 * available. But presumably, the API is supposed to support cabinets which
2584 * are split across multiple CDROMS; we may need to change our implementation
2585 * to strictly serialize its file usage so that it opens only one cabinet
2586 * at a time. Some experimentation with Windows is needed to figure out the
2587 * precise semantics required. The relevant code is here and in fdi_decomp().
2590 /* partial-file notification */
2591 if ((file->index & cffileCONTINUED_FROM_PREV) == cffileCONTINUED_FROM_PREV) {
2593 * FIXME: Need to create a Cabinet with a single file spanning multiple files
2594 * and perform some tests to figure out the right behavior. The SDK says
2595 * FDICopy will notify the user of the filename and "disk name" (info) of
2596 * the cabinet where the spanning file /started/.
2598 * That would certainly be convenient for the API-user, who could abort,
2599 * everything (or parallelize, if that's allowed (it is in wine)), and call
2600 * FDICopy again with the provided filename, so as to avoid partial file
2601 * notification and successfully unpack. This task could be quite unpleasant
2602 * from wine's perspective: the information specifying the "start cabinet" for
2603 * a file is associated nowhere with the file header and is not to be found in
2604 * the cabinet header. We have only the index of the cabinet wherein the folder
2605 * begins, which contains the file. To find that cabinet, we must consider the
2606 * index of the current cabinet, and chain backwards, cabinet-by-cabinet (for
2607 * each cabinet refers to its "next" and "previous" cabinet only, like a linked
2608 * list).
2610 * Bear in mind that, in the spirit of CABINET.DLL, we must assume that any
2611 * cabinet other than the active one might be at another filepath than the
2612 * current one, or on another CDROM. This could get rather dicey, especially
2613 * if we imagine parallelized access to the FDICopy API.
2615 * The current implementation punts -- it just returns the previous cabinet and
2616 * its info from the header of this cabinet. This provides the right answer in
2617 * 95% of the cases; it's worth checking if Microsoft cuts the same corner before
2618 * we "fix" it.
2620 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2621 fdin.pv = pvUser;
2622 fdin.psz1 = (char *)file->filename;
2623 fdin.psz2 = (CAB(mii).prevname) ? CAB(mii).prevname : &emptystring;
2624 fdin.psz3 = (CAB(mii).previnfo) ? CAB(mii).previnfo : &emptystring;
2626 if (pfnfdin(fdintPARTIAL_FILE, &fdin) == -1) {
2627 set_error( fdi, FDIERROR_USER_ABORT, 0 );
2628 goto bail_and_fail;
2630 /* I don't think we are supposed to decompress partial files. This prevents it. */
2631 file->oppressed = TRUE;
2633 if (file->oppressed) {
2634 filehf = 0;
2635 } else {
2636 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2637 fdin.pv = pvUser;
2638 fdin.psz1 = (char *)file->filename;
2639 fdin.cb = file->length;
2640 fdin.date = file->date;
2641 fdin.time = file->time;
2642 fdin.attribs = file->attribs;
2643 fdin.iFolder = file->index;
2644 if ((filehf = ((*pfnfdin)(fdintCOPY_FILE, &fdin))) == -1) {
2645 set_error( fdi, FDIERROR_USER_ABORT, 0 );
2646 filehf = 0;
2647 goto bail_and_fail;
2651 /* find the folder for this file if necc. */
2652 if (filehf) {
2653 fol = CAB(firstfol);
2654 if ((file->index & cffileCONTINUED_TO_NEXT) == cffileCONTINUED_TO_NEXT) {
2655 /* pick the last folder */
2656 while (fol->next) fol = fol->next;
2657 } else {
2658 unsigned int i2;
2660 for (i2 = 0; (i2 < file->index); i2++)
2661 if (fol->next) /* bug resistance, should always be true */
2662 fol = fol->next;
2666 if (filehf) {
2667 cab_UWORD comptype = fol->comp_type;
2668 int ct1 = comptype & cffoldCOMPTYPE_MASK;
2669 int ct2 = CAB(current) ? (CAB(current)->comp_type & cffoldCOMPTYPE_MASK) : 0;
2670 int err = 0;
2672 TRACE("Extracting file %s as requested by callee.\n", debugstr_a(file->filename));
2674 /* set up decomp_state */
2675 CAB(fdi) = fdi;
2676 CAB(filehf) = filehf;
2678 /* Was there a change of folder? Compression type? Did we somehow go backwards? */
2679 if ((ct1 != ct2) || (CAB(current) != fol) || (file->offset < CAB(offset))) {
2681 TRACE("Resetting folder for file %s.\n", debugstr_a(file->filename));
2683 /* free stuff for the old decompressor */
2684 switch (ct2) {
2685 case cffoldCOMPTYPE_LZX:
2686 if (LZX(window)) {
2687 fdi->free(LZX(window));
2688 LZX(window) = NULL;
2690 break;
2691 case cffoldCOMPTYPE_QUANTUM:
2692 if (QTM(window)) {
2693 fdi->free(QTM(window));
2694 QTM(window) = NULL;
2696 break;
2699 CAB(decomp_cab) = NULL;
2700 CAB(fdi)->seek(CAB(cabhf), fol->offset, SEEK_SET);
2701 CAB(offset) = 0;
2702 CAB(outlen) = 0;
2704 /* initialize the new decompressor */
2705 switch (ct1) {
2706 case cffoldCOMPTYPE_NONE:
2707 CAB(decompress) = NONEfdi_decomp;
2708 break;
2709 case cffoldCOMPTYPE_MSZIP:
2710 CAB(decompress) = ZIPfdi_decomp;
2711 break;
2712 case cffoldCOMPTYPE_QUANTUM:
2713 CAB(decompress) = QTMfdi_decomp;
2714 err = QTMfdi_init((comptype >> 8) & 0x1f, (comptype >> 4) & 0xF, decomp_state);
2715 break;
2716 case cffoldCOMPTYPE_LZX:
2717 CAB(decompress) = LZXfdi_decomp;
2718 err = LZXfdi_init((comptype >> 8) & 0x1f, decomp_state);
2719 break;
2720 default:
2721 err = DECR_DATAFORMAT;
2725 CAB(current) = fol;
2727 switch (err) {
2728 case DECR_OK:
2729 break;
2730 case DECR_NOMEMORY:
2731 set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY );
2732 goto bail_and_fail;
2733 default:
2734 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
2735 goto bail_and_fail;
2738 if (file->offset > CAB(offset)) {
2739 /* decode bytes and send them to /dev/null */
2740 switch (fdi_decomp(file, 0, decomp_state, pszCabPath, pfnfdin, pvUser)) {
2741 case DECR_OK:
2742 break;
2743 case DECR_USERABORT:
2744 set_error( fdi, FDIERROR_USER_ABORT, 0 );
2745 goto bail_and_fail;
2746 case DECR_NOMEMORY:
2747 set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY );
2748 goto bail_and_fail;
2749 default:
2750 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
2751 goto bail_and_fail;
2753 CAB(offset) = file->offset;
2756 /* now do the actual decompression */
2757 err = fdi_decomp(file, 1, decomp_state, pszCabPath, pfnfdin, pvUser);
2758 if (err) CAB(current) = NULL; else CAB(offset) += file->length;
2760 /* fdintCLOSE_FILE_INFO notification */
2761 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2762 fdin.pv = pvUser;
2763 fdin.psz1 = (char *)file->filename;
2764 fdin.hf = filehf;
2765 fdin.cb = (file->attribs & cffile_A_EXEC) != 0; /* FIXME: is that right? */
2766 fdin.date = file->date;
2767 fdin.time = file->time;
2768 fdin.attribs = file->attribs; /* FIXME: filter _A_EXEC? */
2769 fdin.iFolder = file->index;
2770 ((*pfnfdin)(fdintCLOSE_FILE_INFO, &fdin));
2771 filehf = 0;
2773 switch (err) {
2774 case DECR_OK:
2775 break;
2776 case DECR_USERABORT:
2777 set_error( fdi, FDIERROR_USER_ABORT, 0 );
2778 goto bail_and_fail;
2779 case DECR_NOMEMORY:
2780 set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY );
2781 goto bail_and_fail;
2782 default:
2783 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
2784 goto bail_and_fail;
2789 if (fol) free_decompression_temps(fdi, fol, decomp_state);
2790 free_decompression_mem(fdi, decomp_state);
2792 return TRUE;
2794 bail_and_fail: /* here we free ram before error returns */
2796 if (fol) free_decompression_temps(fdi, fol, decomp_state);
2798 if (filehf) fdi->close(filehf);
2800 free_decompression_mem(fdi, decomp_state);
2802 return FALSE;
2805 /***********************************************************************
2806 * FDIDestroy (CABINET.23)
2808 * Frees a handle created by FDICreate. Do /not/ call this in the middle
2809 * of FDICopy. Only reason for failure would be an invalid handle.
2811 * PARAMS
2812 * hfdi [I] The HFDI to free
2814 * RETURNS
2815 * TRUE for success
2816 * FALSE for failure
2818 BOOL __cdecl FDIDestroy(HFDI hfdi)
2820 FDI_Int *fdi = get_fdi_ptr( hfdi );
2822 TRACE("(hfdi == ^%p)\n", hfdi);
2823 if (!fdi) return FALSE;
2824 fdi->magic = 0; /* paranoia */
2825 fdi->free(fdi);
2826 return TRUE;
2829 /***********************************************************************
2830 * FDITruncateCabinet (CABINET.24)
2832 * Removes all folders of a cabinet file after and including the
2833 * specified folder number.
2835 * PARAMS
2836 * hfdi [I] Handle to the FDI context.
2837 * pszCabinetName [I] Filename of the cabinet.
2838 * iFolderToDelete [I] Index of the first folder to delete.
2840 * RETURNS
2841 * Success: TRUE.
2842 * Failure: FALSE.
2844 * NOTES
2845 * The PFNWRITE function supplied to FDICreate must truncate the
2846 * file at the current position if the number of bytes to write is 0.
2848 BOOL __cdecl FDITruncateCabinet(
2849 HFDI hfdi,
2850 char *pszCabinetName,
2851 USHORT iFolderToDelete)
2853 FDI_Int *fdi = get_fdi_ptr( hfdi );
2855 FIXME("(hfdi == ^%p, pszCabinetName == %s, iFolderToDelete == %hu): stub\n",
2856 hfdi, debugstr_a(pszCabinetName), iFolderToDelete);
2858 if (!fdi) return FALSE;
2860 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2861 return FALSE;