Assorted spelling fixes.
[wine.git] / dlls / cabinet / fdi.c
blobae0576b2365c6164514411e9347db83b88430918
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 "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 /* 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 * were 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 (!hf) {
706 SetLastError(ERROR_INVALID_HANDLE);
707 return FALSE;
710 if (!pfdici) {
711 SetLastError(ERROR_BAD_ARGUMENTS);
712 return FALSE;
714 rv = FDI_read_entries(fdi, hf, pfdici, NULL);
716 if (rv)
717 pfdici->hasnext = FALSE; /* yuck. duplicate apparent cabinet.dll bug */
719 return rv;
722 /******************************************************************
723 * QTMfdi_initmodel (internal)
725 * Initialize a model which decodes symbols from [s] to [s]+[n]-1
727 static void QTMfdi_initmodel(struct QTMmodel *m, struct QTMmodelsym *sym, int n, int s) {
728 int i;
729 m->shiftsleft = 4;
730 m->entries = n;
731 m->syms = sym;
732 memset(m->tabloc, 0xFF, sizeof(m->tabloc)); /* clear out look-up table */
733 for (i = 0; i < n; i++) {
734 m->tabloc[i+s] = i; /* set up a look-up entry for symbol */
735 m->syms[i].sym = i+s; /* actual symbol */
736 m->syms[i].cumfreq = n-i; /* current frequency of that symbol */
738 m->syms[n].cumfreq = 0;
741 /******************************************************************
742 * QTMfdi_init (internal)
744 static int QTMfdi_init(int window, int level, fdi_decomp_state *decomp_state) {
745 unsigned int wndsize = 1 << window;
746 int msz = window * 2, i;
747 cab_ULONG j;
749 /* QTM supports window sizes of 2^10 (1Kb) through 2^21 (2Mb) */
750 /* if a previously allocated window is big enough, keep it */
751 if (window < 10 || window > 21) return DECR_DATAFORMAT;
752 if (QTM(actual_size) < wndsize) {
753 if (QTM(window)) CAB(fdi)->free(QTM(window));
754 QTM(window) = NULL;
756 if (!QTM(window)) {
757 if (!(QTM(window) = CAB(fdi)->alloc(wndsize))) return DECR_NOMEMORY;
758 QTM(actual_size) = wndsize;
760 QTM(window_size) = wndsize;
761 QTM(window_posn) = 0;
763 /* initialize static slot/extrabits tables */
764 for (i = 0, j = 0; i < 27; i++) {
765 CAB(q_length_extra)[i] = (i == 26) ? 0 : (i < 2 ? 0 : i - 2) >> 2;
766 CAB(q_length_base)[i] = j; j += 1 << ((i == 26) ? 5 : CAB(q_length_extra)[i]);
768 for (i = 0, j = 0; i < 42; i++) {
769 CAB(q_extra_bits)[i] = (i < 2 ? 0 : i-2) >> 1;
770 CAB(q_position_base)[i] = j; j += 1 << CAB(q_extra_bits)[i];
773 /* initialize arithmetic coding models */
775 QTMfdi_initmodel(&QTM(model7), QTM(m7sym), 7, 0);
777 QTMfdi_initmodel(&QTM(model00), QTM(m00sym), 0x40, 0x00);
778 QTMfdi_initmodel(&QTM(model40), QTM(m40sym), 0x40, 0x40);
779 QTMfdi_initmodel(&QTM(model80), QTM(m80sym), 0x40, 0x80);
780 QTMfdi_initmodel(&QTM(modelC0), QTM(mC0sym), 0x40, 0xC0);
782 /* model 4 depends on table size, ranges from 20 to 24 */
783 QTMfdi_initmodel(&QTM(model4), QTM(m4sym), (msz < 24) ? msz : 24, 0);
784 /* model 5 depends on table size, ranges from 20 to 36 */
785 QTMfdi_initmodel(&QTM(model5), QTM(m5sym), (msz < 36) ? msz : 36, 0);
786 /* model 6pos depends on table size, ranges from 20 to 42 */
787 QTMfdi_initmodel(&QTM(model6pos), QTM(m6psym), msz, 0);
788 QTMfdi_initmodel(&QTM(model6len), QTM(m6lsym), 27, 0);
790 return DECR_OK;
793 /************************************************************
794 * LZXfdi_init (internal)
796 static int LZXfdi_init(int window, fdi_decomp_state *decomp_state) {
797 static const cab_UBYTE bits[] =
798 { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
799 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14,
800 15, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
801 17, 17, 17};
802 static const cab_ULONG base[] =
803 { 0, 1, 2, 3, 4, 6, 8, 12,
804 16, 24, 32, 48, 64, 96, 128, 192,
805 256, 384, 512, 768, 1024, 1536, 2048, 3072,
806 4096, 6144, 8192, 12288, 16384, 24576, 32768, 49152,
807 65536, 98304, 131072, 196608, 262144, 393216, 524288, 655360,
808 786432, 917504, 1048576, 1179648, 1310720, 1441792, 1572864, 1703936,
809 1835008, 1966080, 2097152};
810 cab_ULONG wndsize = 1 << window;
811 int posn_slots;
813 /* LZX supports window sizes of 2^15 (32Kb) through 2^21 (2Mb) */
814 /* if a previously allocated window is big enough, keep it */
815 if (window < 15 || window > 21) return DECR_DATAFORMAT;
816 if (LZX(actual_size) < wndsize) {
817 if (LZX(window)) CAB(fdi)->free(LZX(window));
818 LZX(window) = NULL;
820 if (!LZX(window)) {
821 if (!(LZX(window) = CAB(fdi)->alloc(wndsize))) return DECR_NOMEMORY;
822 LZX(actual_size) = wndsize;
824 LZX(window_size) = wndsize;
826 /* initialize static tables */
827 memcpy(CAB(extra_bits), bits, sizeof(bits));
828 memcpy(CAB(lzx_position_base), base, sizeof(base));
830 /* calculate required position slots */
831 if (window == 20) posn_slots = 42;
832 else if (window == 21) posn_slots = 50;
833 else posn_slots = window << 1;
835 /*posn_slots=i=0; while (i < wndsize) i += 1 << CAB(extra_bits)[posn_slots++]; */
837 LZX(R0) = LZX(R1) = LZX(R2) = 1;
838 LZX(main_elements) = LZX_NUM_CHARS + (posn_slots << 3);
839 LZX(header_read) = 0;
840 LZX(frames_read) = 0;
841 LZX(block_remaining) = 0;
842 LZX(block_type) = LZX_BLOCKTYPE_INVALID;
843 LZX(intel_curpos) = 0;
844 LZX(intel_started) = 0;
845 LZX(window_posn) = 0;
847 /* initialize tables to 0 (because deltas will be applied to them) */
848 memset(LZX(MAINTREE_len), 0, sizeof(LZX(MAINTREE_len)));
849 memset(LZX(LENGTH_len), 0, sizeof(LZX(LENGTH_len)));
851 return DECR_OK;
854 /****************************************************
855 * NONEfdi_decomp(internal)
857 static int NONEfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state)
859 if (inlen != outlen) return DECR_ILLEGALDATA;
860 if (outlen > CAB_BLOCKMAX) return DECR_DATAFORMAT;
861 memcpy(CAB(outbuf), CAB(inbuf), (size_t) inlen);
862 return DECR_OK;
865 /********************************************************
866 * Ziphuft_free (internal)
868 static void fdi_Ziphuft_free(FDI_Int *fdi, struct Ziphuft *t)
870 register struct Ziphuft *p, *q;
872 /* Go through linked list, freeing from the allocated (t[-1]) address. */
873 p = t;
874 while (p != NULL)
876 q = (--p)->v.t;
877 fdi->free(p);
878 p = q;
882 /*********************************************************
883 * fdi_Ziphuft_build (internal)
885 static cab_LONG fdi_Ziphuft_build(cab_ULONG *b, cab_ULONG n, cab_ULONG s, const cab_UWORD *d, const cab_UWORD *e,
886 struct Ziphuft **t, cab_LONG *m, fdi_decomp_state *decomp_state)
888 cab_ULONG a; /* counter for codes of length k */
889 cab_ULONG el; /* length of EOB code (value 256) */
890 cab_ULONG f; /* i repeats in table every f entries */
891 cab_LONG g; /* maximum code length */
892 cab_LONG h; /* table level */
893 register cab_ULONG i; /* counter, current code */
894 register cab_ULONG j; /* counter */
895 register cab_LONG k; /* number of bits in current code */
896 cab_LONG *l; /* stack of bits per table */
897 register cab_ULONG *p; /* pointer into ZIP(c)[],ZIP(b)[],ZIP(v)[] */
898 register struct Ziphuft *q; /* points to current table */
899 struct Ziphuft r; /* table entry for structure assignment */
900 register cab_LONG w; /* bits before this table == (l * h) */
901 cab_ULONG *xp; /* pointer into x */
902 cab_LONG y; /* number of dummy codes added */
903 cab_ULONG z; /* number of entries in current table */
905 l = ZIP(lx)+1;
907 /* Generate counts for each bit length */
908 el = n > 256 ? b[256] : ZIPBMAX; /* set length of EOB code, if any */
910 for(i = 0; i < ZIPBMAX+1; ++i)
911 ZIP(c)[i] = 0;
912 p = b; i = n;
915 ZIP(c)[*p]++; p++; /* assume all entries <= ZIPBMAX */
916 } while (--i);
917 if (ZIP(c)[0] == n) /* null input--all zero length codes */
919 *t = NULL;
920 *m = 0;
921 return 0;
924 /* Find minimum and maximum length, bound *m by those */
925 for (j = 1; j <= ZIPBMAX; j++)
926 if (ZIP(c)[j])
927 break;
928 k = j; /* minimum code length */
929 if ((cab_ULONG)*m < j)
930 *m = j;
931 for (i = ZIPBMAX; i; i--)
932 if (ZIP(c)[i])
933 break;
934 g = i; /* maximum code length */
935 if ((cab_ULONG)*m > i)
936 *m = i;
938 /* Adjust last length count to fill out codes, if needed */
939 for (y = 1 << j; j < i; j++, y <<= 1)
940 if ((y -= ZIP(c)[j]) < 0)
941 return 2; /* bad input: more codes than bits */
942 if ((y -= ZIP(c)[i]) < 0)
943 return 2;
944 ZIP(c)[i] += y;
946 /* Generate starting offsets LONGo the value table for each length */
947 ZIP(x)[1] = j = 0;
948 p = ZIP(c) + 1; xp = ZIP(x) + 2;
949 while (--i)
950 { /* note that i == g from above */
951 *xp++ = (j += *p++);
954 /* Make a table of values in order of bit lengths */
955 p = b; i = 0;
957 if ((j = *p++) != 0)
958 ZIP(v)[ZIP(x)[j]++] = i;
959 } while (++i < n);
962 /* Generate the Huffman codes and for each, make the table entries */
963 ZIP(x)[0] = i = 0; /* first Huffman code is zero */
964 p = ZIP(v); /* grab values in bit order */
965 h = -1; /* no tables yet--level -1 */
966 w = l[-1] = 0; /* no bits decoded yet */
967 ZIP(u)[0] = NULL; /* just to keep compilers happy */
968 q = NULL; /* ditto */
969 z = 0; /* ditto */
971 /* go through the bit lengths (k already is bits in shortest code) */
972 for (; k <= g; k++)
974 a = ZIP(c)[k];
975 while (a--)
977 /* here i is the Huffman code of length k bits for value *p */
978 /* make tables up to required level */
979 while (k > w + l[h])
981 w += l[h++]; /* add bits already decoded */
983 /* compute minimum size table less than or equal to *m bits */
984 if ((z = g - w) > (cab_ULONG)*m) /* upper limit */
985 z = *m;
986 if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
987 { /* too few codes for k-w bit table */
988 f -= a + 1; /* deduct codes from patterns left */
989 xp = ZIP(c) + k;
990 while (++j < z) /* try smaller tables up to z bits */
992 if ((f <<= 1) <= *++xp)
993 break; /* enough codes to use up j bits */
994 f -= *xp; /* else deduct codes from patterns */
997 if ((cab_ULONG)w + j > el && (cab_ULONG)w < el)
998 j = el - w; /* make EOB code end at table */
999 z = 1 << j; /* table entries for j-bit table */
1000 l[h] = j; /* set table size in stack */
1002 /* allocate and link in new table */
1003 if (!(q = CAB(fdi)->alloc((z + 1)*sizeof(struct Ziphuft))))
1005 if(h)
1006 fdi_Ziphuft_free(CAB(fdi), ZIP(u)[0]);
1007 return 3; /* not enough memory */
1009 *t = q + 1; /* link to list for Ziphuft_free() */
1010 *(t = &(q->v.t)) = NULL;
1011 ZIP(u)[h] = ++q; /* table starts after link */
1013 /* connect to last table, if there is one */
1014 if (h)
1016 ZIP(x)[h] = i; /* save pattern for backing up */
1017 r.b = (cab_UBYTE)l[h-1]; /* bits to dump before this table */
1018 r.e = (cab_UBYTE)(16 + j); /* bits in this table */
1019 r.v.t = q; /* pointer to this table */
1020 j = (i & ((1 << w) - 1)) >> (w - l[h-1]);
1021 ZIP(u)[h-1][j] = r; /* connect to last table */
1025 /* set up table entry in r */
1026 r.b = (cab_UBYTE)(k - w);
1027 if (p >= ZIP(v) + n)
1028 r.e = 99; /* out of values--invalid code */
1029 else if (*p < s)
1031 r.e = (cab_UBYTE)(*p < 256 ? 16 : 15); /* 256 is end-of-block code */
1032 r.v.n = *p++; /* simple code is just the value */
1034 else
1036 r.e = (cab_UBYTE)e[*p - s]; /* non-simple--look up in lists */
1037 r.v.n = d[*p++ - s];
1040 /* fill code-like entries with r */
1041 f = 1 << (k - w);
1042 for (j = i >> w; j < z; j += f)
1043 q[j] = r;
1045 /* backwards increment the k-bit code i */
1046 for (j = 1 << (k - 1); i & j; j >>= 1)
1047 i ^= j;
1048 i ^= j;
1050 /* backup over finished tables */
1051 while ((i & ((1 << w) - 1)) != ZIP(x)[h])
1052 w -= l[--h]; /* don't need to update q */
1056 /* return actual size of base table */
1057 *m = l[0];
1059 /* Return true (1) if we were given an incomplete table */
1060 return y != 0 && g != 1;
1063 /*********************************************************
1064 * fdi_Zipinflate_codes (internal)
1066 static cab_LONG fdi_Zipinflate_codes(const struct Ziphuft *tl, const struct Ziphuft *td,
1067 cab_LONG bl, cab_LONG bd, fdi_decomp_state *decomp_state)
1069 register cab_ULONG e; /* table entry flag/number of extra bits */
1070 cab_ULONG n, d; /* length and index for copy */
1071 cab_ULONG w; /* current window position */
1072 const struct Ziphuft *t; /* pointer to table entry */
1073 cab_ULONG ml, md; /* masks for bl and bd bits */
1074 register cab_ULONG b; /* bit buffer */
1075 register cab_ULONG k; /* number of bits in bit buffer */
1077 /* make local copies of globals */
1078 b = ZIP(bb); /* initialize bit buffer */
1079 k = ZIP(bk);
1080 w = ZIP(window_posn); /* initialize window position */
1082 /* inflate the coded data */
1083 ml = Zipmask[bl]; /* precompute masks for speed */
1084 md = Zipmask[bd];
1086 for(;;)
1088 ZIPNEEDBITS((cab_ULONG)bl)
1089 if((e = (t = tl + (b & ml))->e) > 16)
1092 if (e == 99)
1093 return 1;
1094 ZIPDUMPBITS(t->b)
1095 e -= 16;
1096 ZIPNEEDBITS(e)
1097 } while ((e = (t = t->v.t + (b & Zipmask[e]))->e) > 16);
1098 ZIPDUMPBITS(t->b)
1099 if (e == 16) /* then it's a literal */
1100 CAB(outbuf)[w++] = (cab_UBYTE)t->v.n;
1101 else /* it's an EOB or a length */
1103 /* exit if end of block */
1104 if(e == 15)
1105 break;
1107 /* get length of block to copy */
1108 ZIPNEEDBITS(e)
1109 n = t->v.n + (b & Zipmask[e]);
1110 ZIPDUMPBITS(e);
1112 /* decode distance of block to copy */
1113 ZIPNEEDBITS((cab_ULONG)bd)
1114 if ((e = (t = td + (b & md))->e) > 16)
1115 do {
1116 if (e == 99)
1117 return 1;
1118 ZIPDUMPBITS(t->b)
1119 e -= 16;
1120 ZIPNEEDBITS(e)
1121 } while ((e = (t = t->v.t + (b & Zipmask[e]))->e) > 16);
1122 ZIPDUMPBITS(t->b)
1123 ZIPNEEDBITS(e)
1124 d = w - t->v.n - (b & Zipmask[e]);
1125 ZIPDUMPBITS(e)
1128 d &= ZIPWSIZE - 1;
1129 e = ZIPWSIZE - max(d, w);
1130 e = min(e, n);
1131 n -= e;
1134 CAB(outbuf)[w++] = CAB(outbuf)[d++];
1135 } while (--e);
1136 } while (n);
1140 /* restore the globals from the locals */
1141 ZIP(window_posn) = w; /* restore global window pointer */
1142 ZIP(bb) = b; /* restore global bit buffer */
1143 ZIP(bk) = k;
1145 /* done */
1146 return 0;
1149 /***********************************************************
1150 * Zipinflate_stored (internal)
1152 static cab_LONG fdi_Zipinflate_stored(fdi_decomp_state *decomp_state)
1153 /* "decompress" an inflated type 0 (stored) block. */
1155 cab_ULONG n; /* number of bytes in block */
1156 cab_ULONG w; /* current window position */
1157 register cab_ULONG b; /* bit buffer */
1158 register cab_ULONG k; /* number of bits in bit buffer */
1160 /* make local copies of globals */
1161 b = ZIP(bb); /* initialize bit buffer */
1162 k = ZIP(bk);
1163 w = ZIP(window_posn); /* initialize window position */
1165 /* go to byte boundary */
1166 n = k & 7;
1167 ZIPDUMPBITS(n);
1169 /* get the length and its complement */
1170 ZIPNEEDBITS(16)
1171 n = (b & 0xffff);
1172 ZIPDUMPBITS(16)
1173 ZIPNEEDBITS(16)
1174 if (n != ((~b) & 0xffff))
1175 return 1; /* error in compressed data */
1176 ZIPDUMPBITS(16)
1178 /* read and output the compressed data */
1179 while(n--)
1181 ZIPNEEDBITS(8)
1182 CAB(outbuf)[w++] = (cab_UBYTE)b;
1183 ZIPDUMPBITS(8)
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;
1190 return 0;
1193 /******************************************************
1194 * fdi_Zipinflate_fixed (internal)
1196 static cab_LONG fdi_Zipinflate_fixed(fdi_decomp_state *decomp_state)
1198 struct Ziphuft *fixed_tl;
1199 struct Ziphuft *fixed_td;
1200 cab_LONG fixed_bl, fixed_bd;
1201 cab_LONG i; /* temporary variable */
1202 cab_ULONG *l;
1204 l = ZIP(ll);
1206 /* literal table */
1207 for(i = 0; i < 144; i++)
1208 l[i] = 8;
1209 for(; i < 256; i++)
1210 l[i] = 9;
1211 for(; i < 280; i++)
1212 l[i] = 7;
1213 for(; i < 288; i++) /* make a complete, but wrong code set */
1214 l[i] = 8;
1215 fixed_bl = 7;
1216 if((i = fdi_Ziphuft_build(l, 288, 257, Zipcplens, Zipcplext, &fixed_tl, &fixed_bl, decomp_state)))
1217 return i;
1219 /* distance table */
1220 for(i = 0; i < 30; i++) /* make an incomplete code set */
1221 l[i] = 5;
1222 fixed_bd = 5;
1223 if((i = fdi_Ziphuft_build(l, 30, 0, Zipcpdist, Zipcpdext, &fixed_td, &fixed_bd, decomp_state)) > 1)
1225 fdi_Ziphuft_free(CAB(fdi), fixed_tl);
1226 return i;
1229 /* decompress until an end-of-block code */
1230 i = fdi_Zipinflate_codes(fixed_tl, fixed_td, fixed_bl, fixed_bd, decomp_state);
1232 fdi_Ziphuft_free(CAB(fdi), fixed_td);
1233 fdi_Ziphuft_free(CAB(fdi), fixed_tl);
1234 return i;
1237 /**************************************************************
1238 * fdi_Zipinflate_dynamic (internal)
1240 static cab_LONG fdi_Zipinflate_dynamic(fdi_decomp_state *decomp_state)
1241 /* decompress an inflated type 2 (dynamic Huffman codes) block. */
1243 cab_LONG i; /* temporary variables */
1244 cab_ULONG j;
1245 cab_ULONG *ll;
1246 cab_ULONG l; /* last length */
1247 cab_ULONG m; /* mask for bit lengths table */
1248 cab_ULONG n; /* number of lengths to get */
1249 struct Ziphuft *tl; /* literal/length code table */
1250 struct Ziphuft *td; /* distance code table */
1251 cab_LONG bl; /* lookup bits for tl */
1252 cab_LONG bd; /* lookup bits for td */
1253 cab_ULONG nb; /* number of bit length codes */
1254 cab_ULONG nl; /* number of literal/length codes */
1255 cab_ULONG nd; /* number of distance codes */
1256 register cab_ULONG b; /* bit buffer */
1257 register cab_ULONG k; /* number of bits in bit buffer */
1259 /* make local bit buffer */
1260 b = ZIP(bb);
1261 k = ZIP(bk);
1262 ll = ZIP(ll);
1264 /* read in table lengths */
1265 ZIPNEEDBITS(5)
1266 nl = 257 + (b & 0x1f); /* number of literal/length codes */
1267 ZIPDUMPBITS(5)
1268 ZIPNEEDBITS(5)
1269 nd = 1 + (b & 0x1f); /* number of distance codes */
1270 ZIPDUMPBITS(5)
1271 ZIPNEEDBITS(4)
1272 nb = 4 + (b & 0xf); /* number of bit length codes */
1273 ZIPDUMPBITS(4)
1274 if(nl > 288 || nd > 32)
1275 return 1; /* bad lengths */
1277 /* read in bit-length-code lengths */
1278 for(j = 0; j < nb; j++)
1280 ZIPNEEDBITS(3)
1281 ll[Zipborder[j]] = b & 7;
1282 ZIPDUMPBITS(3)
1284 for(; j < 19; j++)
1285 ll[Zipborder[j]] = 0;
1287 /* build decoding table for trees--single level, 7 bit lookup */
1288 bl = 7;
1289 if((i = fdi_Ziphuft_build(ll, 19, 19, NULL, NULL, &tl, &bl, decomp_state)) != 0)
1291 if(i == 1)
1292 fdi_Ziphuft_free(CAB(fdi), tl);
1293 return i; /* incomplete code set */
1296 /* read in literal and distance code lengths */
1297 n = nl + nd;
1298 m = Zipmask[bl];
1299 i = l = 0;
1300 while((cab_ULONG)i < n)
1302 ZIPNEEDBITS((cab_ULONG)bl)
1303 j = (td = tl + (b & m))->b;
1304 ZIPDUMPBITS(j)
1305 j = td->v.n;
1306 if (j < 16) /* length of code in bits (0..15) */
1307 ll[i++] = l = j; /* save last length in l */
1308 else if (j == 16) /* repeat last length 3 to 6 times */
1310 ZIPNEEDBITS(2)
1311 j = 3 + (b & 3);
1312 ZIPDUMPBITS(2)
1313 if((cab_ULONG)i + j > n)
1314 return 1;
1315 while (j--)
1316 ll[i++] = l;
1318 else if (j == 17) /* 3 to 10 zero length codes */
1320 ZIPNEEDBITS(3)
1321 j = 3 + (b & 7);
1322 ZIPDUMPBITS(3)
1323 if ((cab_ULONG)i + j > n)
1324 return 1;
1325 while (j--)
1326 ll[i++] = 0;
1327 l = 0;
1329 else /* j == 18: 11 to 138 zero length codes */
1331 ZIPNEEDBITS(7)
1332 j = 11 + (b & 0x7f);
1333 ZIPDUMPBITS(7)
1334 if ((cab_ULONG)i + j > n)
1335 return 1;
1336 while (j--)
1337 ll[i++] = 0;
1338 l = 0;
1342 /* free decoding table for trees */
1343 fdi_Ziphuft_free(CAB(fdi), tl);
1345 /* restore the global bit buffer */
1346 ZIP(bb) = b;
1347 ZIP(bk) = k;
1349 /* build the decoding tables for literal/length and distance codes */
1350 bl = ZIPLBITS;
1351 if((i = fdi_Ziphuft_build(ll, nl, 257, Zipcplens, Zipcplext, &tl, &bl, decomp_state)) != 0)
1353 if(i == 1)
1354 fdi_Ziphuft_free(CAB(fdi), tl);
1355 return i; /* incomplete code set */
1357 bd = ZIPDBITS;
1358 fdi_Ziphuft_build(ll + nl, nd, 0, Zipcpdist, Zipcpdext, &td, &bd, decomp_state);
1360 /* decompress until an end-of-block code */
1361 if(fdi_Zipinflate_codes(tl, td, bl, bd, decomp_state))
1362 return 1;
1364 /* free the decoding tables, return */
1365 fdi_Ziphuft_free(CAB(fdi), tl);
1366 fdi_Ziphuft_free(CAB(fdi), td);
1367 return 0;
1370 /*****************************************************
1371 * fdi_Zipinflate_block (internal)
1373 static cab_LONG fdi_Zipinflate_block(cab_LONG *e, fdi_decomp_state *decomp_state) /* e == last block flag */
1374 { /* decompress an inflated block */
1375 cab_ULONG t; /* block type */
1376 register cab_ULONG b; /* bit buffer */
1377 register cab_ULONG k; /* number of bits in bit buffer */
1379 /* make local bit buffer */
1380 b = ZIP(bb);
1381 k = ZIP(bk);
1383 /* read in last block bit */
1384 ZIPNEEDBITS(1)
1385 *e = (cab_LONG)b & 1;
1386 ZIPDUMPBITS(1)
1388 /* read in block type */
1389 ZIPNEEDBITS(2)
1390 t = b & 3;
1391 ZIPDUMPBITS(2)
1393 /* restore the global bit buffer */
1394 ZIP(bb) = b;
1395 ZIP(bk) = k;
1397 /* inflate that block type */
1398 if(t == 2)
1399 return fdi_Zipinflate_dynamic(decomp_state);
1400 if(t == 0)
1401 return fdi_Zipinflate_stored(decomp_state);
1402 if(t == 1)
1403 return fdi_Zipinflate_fixed(decomp_state);
1404 /* bad block type */
1405 return 2;
1408 /****************************************************
1409 * ZIPfdi_decomp(internal)
1411 static int ZIPfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state)
1413 cab_LONG e; /* last block flag */
1415 TRACE("(inlen == %d, outlen == %d)\n", inlen, outlen);
1417 ZIP(inpos) = CAB(inbuf);
1418 ZIP(bb) = ZIP(bk) = ZIP(window_posn) = 0;
1419 if(outlen > ZIPWSIZE)
1420 return DECR_DATAFORMAT;
1422 /* CK = Chris Kirmse, official Microsoft purloiner */
1423 if(ZIP(inpos)[0] != 0x43 || ZIP(inpos)[1] != 0x4B)
1424 return DECR_ILLEGALDATA;
1425 ZIP(inpos) += 2;
1427 do {
1428 if(fdi_Zipinflate_block(&e, decomp_state))
1429 return DECR_ILLEGALDATA;
1430 } while(!e);
1432 /* return success */
1433 return DECR_OK;
1436 /*******************************************************************
1437 * QTMfdi_decomp(internal)
1439 static int QTMfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state)
1441 cab_UBYTE *inpos = CAB(inbuf);
1442 cab_UBYTE *window = QTM(window);
1443 cab_UBYTE *runsrc, *rundest;
1444 cab_ULONG window_posn = QTM(window_posn);
1445 cab_ULONG window_size = QTM(window_size);
1447 /* used by bitstream macros */
1448 register int bitsleft, bitrun, bitsneed;
1449 register cab_ULONG bitbuf;
1451 /* used by GET_SYMBOL */
1452 cab_ULONG range;
1453 cab_UWORD symf;
1454 int i;
1456 int extra, togo = outlen, match_length = 0, copy_length;
1457 cab_UBYTE selector, sym;
1458 cab_ULONG match_offset = 0;
1460 cab_UWORD H = 0xFFFF, L = 0, C;
1462 TRACE("(inlen == %d, outlen == %d)\n", inlen, outlen);
1464 /* read initial value of C */
1465 Q_INIT_BITSTREAM;
1466 Q_READ_BITS(C, 16);
1468 /* apply 2^x-1 mask */
1469 window_posn &= window_size - 1;
1470 /* runs can't straddle the window wraparound */
1471 if ((window_posn + togo) > window_size) {
1472 TRACE("straddled run\n");
1473 return DECR_DATAFORMAT;
1476 while (togo > 0) {
1477 GET_SYMBOL(model7, selector);
1478 switch (selector) {
1479 case 0:
1480 GET_SYMBOL(model00, sym); window[window_posn++] = sym; togo--;
1481 break;
1482 case 1:
1483 GET_SYMBOL(model40, sym); window[window_posn++] = sym; togo--;
1484 break;
1485 case 2:
1486 GET_SYMBOL(model80, sym); window[window_posn++] = sym; togo--;
1487 break;
1488 case 3:
1489 GET_SYMBOL(modelC0, sym); window[window_posn++] = sym; togo--;
1490 break;
1492 case 4:
1493 /* selector 4 = fixed length of 3 */
1494 GET_SYMBOL(model4, sym);
1495 Q_READ_BITS(extra, CAB(q_extra_bits)[sym]);
1496 match_offset = CAB(q_position_base)[sym] + extra + 1;
1497 match_length = 3;
1498 break;
1500 case 5:
1501 /* selector 5 = fixed length of 4 */
1502 GET_SYMBOL(model5, sym);
1503 Q_READ_BITS(extra, CAB(q_extra_bits)[sym]);
1504 match_offset = CAB(q_position_base)[sym] + extra + 1;
1505 match_length = 4;
1506 break;
1508 case 6:
1509 /* selector 6 = variable length */
1510 GET_SYMBOL(model6len, sym);
1511 Q_READ_BITS(extra, CAB(q_length_extra)[sym]);
1512 match_length = CAB(q_length_base)[sym] + extra + 5;
1513 GET_SYMBOL(model6pos, sym);
1514 Q_READ_BITS(extra, CAB(q_extra_bits)[sym]);
1515 match_offset = CAB(q_position_base)[sym] + extra + 1;
1516 break;
1518 default:
1519 TRACE("Selector is bogus\n");
1520 return DECR_ILLEGALDATA;
1523 /* if this is a match */
1524 if (selector >= 4) {
1525 rundest = window + window_posn;
1526 togo -= match_length;
1528 /* copy any wrapped around source data */
1529 if (window_posn >= match_offset) {
1530 /* no wrap */
1531 runsrc = rundest - match_offset;
1532 } else {
1533 runsrc = rundest + (window_size - match_offset);
1534 copy_length = match_offset - window_posn;
1535 if (copy_length < match_length) {
1536 match_length -= copy_length;
1537 window_posn += copy_length;
1538 while (copy_length-- > 0) *rundest++ = *runsrc++;
1539 runsrc = window;
1542 window_posn += match_length;
1544 /* copy match data - no worries about destination wraps */
1545 while (match_length-- > 0) *rundest++ = *runsrc++;
1547 } /* while (togo > 0) */
1549 if (togo != 0) {
1550 TRACE("Frame overflow, this_run = %d\n", togo);
1551 return DECR_ILLEGALDATA;
1554 memcpy(CAB(outbuf), window + ((!window_posn) ? window_size : window_posn) -
1555 outlen, outlen);
1557 QTM(window_posn) = window_posn;
1558 return DECR_OK;
1561 /************************************************************
1562 * fdi_lzx_read_lens (internal)
1564 static int fdi_lzx_read_lens(cab_UBYTE *lens, cab_ULONG first, cab_ULONG last, struct lzx_bits *lb,
1565 fdi_decomp_state *decomp_state) {
1566 cab_ULONG i,j, x,y;
1567 int z;
1569 register cab_ULONG bitbuf = lb->bb;
1570 register int bitsleft = lb->bl;
1571 cab_UBYTE *inpos = lb->ip;
1572 cab_UWORD *hufftbl;
1574 for (x = 0; x < 20; x++) {
1575 READ_BITS(y, 4);
1576 LENTABLE(PRETREE)[x] = y;
1578 BUILD_TABLE(PRETREE);
1580 for (x = first; x < last; ) {
1581 READ_HUFFSYM(PRETREE, z);
1582 if (z == 17) {
1583 READ_BITS(y, 4); y += 4;
1584 while (y--) lens[x++] = 0;
1586 else if (z == 18) {
1587 READ_BITS(y, 5); y += 20;
1588 while (y--) lens[x++] = 0;
1590 else if (z == 19) {
1591 READ_BITS(y, 1); y += 4;
1592 READ_HUFFSYM(PRETREE, z);
1593 z = lens[x] - z; if (z < 0) z += 17;
1594 while (y--) lens[x++] = z;
1596 else {
1597 z = lens[x] - z; if (z < 0) z += 17;
1598 lens[x++] = z;
1602 lb->bb = bitbuf;
1603 lb->bl = bitsleft;
1604 lb->ip = inpos;
1605 return 0;
1608 /*******************************************************
1609 * LZXfdi_decomp(internal)
1611 static int LZXfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state) {
1612 cab_UBYTE *inpos = CAB(inbuf);
1613 const cab_UBYTE *endinp = inpos + inlen;
1614 cab_UBYTE *window = LZX(window);
1615 cab_UBYTE *runsrc, *rundest;
1616 cab_UWORD *hufftbl; /* used in READ_HUFFSYM macro as chosen decoding table */
1618 cab_ULONG window_posn = LZX(window_posn);
1619 cab_ULONG window_size = LZX(window_size);
1620 cab_ULONG R0 = LZX(R0);
1621 cab_ULONG R1 = LZX(R1);
1622 cab_ULONG R2 = LZX(R2);
1624 register cab_ULONG bitbuf;
1625 register int bitsleft;
1626 cab_ULONG match_offset, i,j,k; /* ijk used in READ_HUFFSYM macro */
1627 struct lzx_bits lb; /* used in READ_LENGTHS macro */
1629 int togo = outlen, this_run, main_element, aligned_bits;
1630 int match_length, copy_length, length_footer, extra, verbatim_bits;
1632 TRACE("(inlen == %d, outlen == %d)\n", inlen, outlen);
1634 INIT_BITSTREAM;
1636 /* read header if necessary */
1637 if (!LZX(header_read)) {
1638 i = j = 0;
1639 READ_BITS(k, 1); if (k) { READ_BITS(i,16); READ_BITS(j,16); }
1640 LZX(intel_filesize) = (i << 16) | j; /* or 0 if not encoded */
1641 LZX(header_read) = 1;
1644 /* main decoding loop */
1645 while (togo > 0) {
1646 /* last block finished, new block expected */
1647 if (LZX(block_remaining) == 0) {
1648 if (LZX(block_type) == LZX_BLOCKTYPE_UNCOMPRESSED) {
1649 if (LZX(block_length) & 1) inpos++; /* realign bitstream to word */
1650 INIT_BITSTREAM;
1653 READ_BITS(LZX(block_type), 3);
1654 READ_BITS(i, 16);
1655 READ_BITS(j, 8);
1656 LZX(block_remaining) = LZX(block_length) = (i << 8) | j;
1658 switch (LZX(block_type)) {
1659 case LZX_BLOCKTYPE_ALIGNED:
1660 for (i = 0; i < 8; i++) { READ_BITS(j, 3); LENTABLE(ALIGNED)[i] = j; }
1661 BUILD_TABLE(ALIGNED);
1662 /* rest of aligned header is same as verbatim */
1664 case LZX_BLOCKTYPE_VERBATIM:
1665 READ_LENGTHS(MAINTREE, 0, 256, fdi_lzx_read_lens);
1666 READ_LENGTHS(MAINTREE, 256, LZX(main_elements), fdi_lzx_read_lens);
1667 BUILD_TABLE(MAINTREE);
1668 if (LENTABLE(MAINTREE)[0xE8] != 0) LZX(intel_started) = 1;
1670 READ_LENGTHS(LENGTH, 0, LZX_NUM_SECONDARY_LENGTHS, fdi_lzx_read_lens);
1671 BUILD_TABLE(LENGTH);
1672 break;
1674 case LZX_BLOCKTYPE_UNCOMPRESSED:
1675 LZX(intel_started) = 1; /* because we can't assume otherwise */
1676 ENSURE_BITS(16); /* get up to 16 pad bits into the buffer */
1677 if (bitsleft > 16) inpos -= 2; /* and align the bitstream! */
1678 R0 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
1679 R1 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
1680 R2 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
1681 break;
1683 default:
1684 return DECR_ILLEGALDATA;
1688 /* buffer exhaustion check */
1689 if (inpos > endinp) {
1690 /* it's possible to have a file where the next run is less than
1691 * 16 bits in size. In this case, the READ_HUFFSYM() macro used
1692 * in building the tables will exhaust the buffer, so we should
1693 * allow for this, but not allow those accidentally read bits to
1694 * be used (so we check that there are at least 16 bits
1695 * remaining - in this boundary case they aren't really part of
1696 * the compressed data)
1698 if (inpos > (endinp+2) || bitsleft < 16) return DECR_ILLEGALDATA;
1701 while ((this_run = LZX(block_remaining)) > 0 && togo > 0) {
1702 if (this_run > togo) this_run = togo;
1703 togo -= this_run;
1704 LZX(block_remaining) -= this_run;
1706 /* apply 2^x-1 mask */
1707 window_posn &= window_size - 1;
1708 /* runs can't straddle the window wraparound */
1709 if ((window_posn + this_run) > window_size)
1710 return DECR_DATAFORMAT;
1712 switch (LZX(block_type)) {
1714 case LZX_BLOCKTYPE_VERBATIM:
1715 while (this_run > 0) {
1716 READ_HUFFSYM(MAINTREE, main_element);
1718 if (main_element < LZX_NUM_CHARS) {
1719 /* literal: 0 to LZX_NUM_CHARS-1 */
1720 window[window_posn++] = main_element;
1721 this_run--;
1723 else {
1724 /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
1725 main_element -= LZX_NUM_CHARS;
1727 match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
1728 if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
1729 READ_HUFFSYM(LENGTH, length_footer);
1730 match_length += length_footer;
1732 match_length += LZX_MIN_MATCH;
1734 match_offset = main_element >> 3;
1736 if (match_offset > 2) {
1737 /* not repeated offset */
1738 if (match_offset != 3) {
1739 extra = CAB(extra_bits)[match_offset];
1740 READ_BITS(verbatim_bits, extra);
1741 match_offset = CAB(lzx_position_base)[match_offset]
1742 - 2 + verbatim_bits;
1744 else {
1745 match_offset = 1;
1748 /* update repeated offset LRU queue */
1749 R2 = R1; R1 = R0; R0 = match_offset;
1751 else if (match_offset == 0) {
1752 match_offset = R0;
1754 else if (match_offset == 1) {
1755 match_offset = R1;
1756 R1 = R0; R0 = match_offset;
1758 else /* match_offset == 2 */ {
1759 match_offset = R2;
1760 R2 = R0; R0 = match_offset;
1763 rundest = window + window_posn;
1764 this_run -= match_length;
1766 /* copy any wrapped around source data */
1767 if (window_posn >= match_offset) {
1768 /* no wrap */
1769 runsrc = rundest - match_offset;
1770 } else {
1771 runsrc = rundest + (window_size - match_offset);
1772 copy_length = match_offset - window_posn;
1773 if (copy_length < match_length) {
1774 match_length -= copy_length;
1775 window_posn += copy_length;
1776 while (copy_length-- > 0) *rundest++ = *runsrc++;
1777 runsrc = window;
1780 window_posn += match_length;
1782 /* copy match data - no worries about destination wraps */
1783 while (match_length-- > 0) *rundest++ = *runsrc++;
1786 break;
1788 case LZX_BLOCKTYPE_ALIGNED:
1789 while (this_run > 0) {
1790 READ_HUFFSYM(MAINTREE, main_element);
1792 if (main_element < LZX_NUM_CHARS) {
1793 /* literal: 0 to LZX_NUM_CHARS-1 */
1794 window[window_posn++] = main_element;
1795 this_run--;
1797 else {
1798 /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
1799 main_element -= LZX_NUM_CHARS;
1801 match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
1802 if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
1803 READ_HUFFSYM(LENGTH, length_footer);
1804 match_length += length_footer;
1806 match_length += LZX_MIN_MATCH;
1808 match_offset = main_element >> 3;
1810 if (match_offset > 2) {
1811 /* not repeated offset */
1812 extra = CAB(extra_bits)[match_offset];
1813 match_offset = CAB(lzx_position_base)[match_offset] - 2;
1814 if (extra > 3) {
1815 /* verbatim and aligned bits */
1816 extra -= 3;
1817 READ_BITS(verbatim_bits, extra);
1818 match_offset += (verbatim_bits << 3);
1819 READ_HUFFSYM(ALIGNED, aligned_bits);
1820 match_offset += aligned_bits;
1822 else if (extra == 3) {
1823 /* aligned bits only */
1824 READ_HUFFSYM(ALIGNED, aligned_bits);
1825 match_offset += aligned_bits;
1827 else if (extra > 0) { /* extra==1, extra==2 */
1828 /* verbatim bits only */
1829 READ_BITS(verbatim_bits, extra);
1830 match_offset += verbatim_bits;
1832 else /* extra == 0 */ {
1833 /* ??? */
1834 match_offset = 1;
1837 /* update repeated offset LRU queue */
1838 R2 = R1; R1 = R0; R0 = match_offset;
1840 else if (match_offset == 0) {
1841 match_offset = R0;
1843 else if (match_offset == 1) {
1844 match_offset = R1;
1845 R1 = R0; R0 = match_offset;
1847 else /* match_offset == 2 */ {
1848 match_offset = R2;
1849 R2 = R0; R0 = match_offset;
1852 rundest = window + window_posn;
1853 this_run -= match_length;
1855 /* copy any wrapped around source data */
1856 if (window_posn >= match_offset) {
1857 /* no wrap */
1858 runsrc = rundest - match_offset;
1859 } else {
1860 runsrc = rundest + (window_size - match_offset);
1861 copy_length = match_offset - window_posn;
1862 if (copy_length < match_length) {
1863 match_length -= copy_length;
1864 window_posn += copy_length;
1865 while (copy_length-- > 0) *rundest++ = *runsrc++;
1866 runsrc = window;
1869 window_posn += match_length;
1871 /* copy match data - no worries about destination wraps */
1872 while (match_length-- > 0) *rundest++ = *runsrc++;
1875 break;
1877 case LZX_BLOCKTYPE_UNCOMPRESSED:
1878 if ((inpos + this_run) > endinp) return DECR_ILLEGALDATA;
1879 memcpy(window + window_posn, inpos, (size_t) this_run);
1880 inpos += this_run; window_posn += this_run;
1881 break;
1883 default:
1884 return DECR_ILLEGALDATA; /* might as well */
1890 if (togo != 0) return DECR_ILLEGALDATA;
1891 memcpy(CAB(outbuf), window + ((!window_posn) ? window_size : window_posn) -
1892 outlen, (size_t) outlen);
1894 LZX(window_posn) = window_posn;
1895 LZX(R0) = R0;
1896 LZX(R1) = R1;
1897 LZX(R2) = R2;
1899 /* intel E8 decoding */
1900 if ((LZX(frames_read)++ < 32768) && LZX(intel_filesize) != 0) {
1901 if (outlen <= 6 || !LZX(intel_started)) {
1902 LZX(intel_curpos) += outlen;
1904 else {
1905 cab_UBYTE *data = CAB(outbuf);
1906 cab_UBYTE *dataend = data + outlen - 10;
1907 cab_LONG curpos = LZX(intel_curpos);
1908 cab_LONG filesize = LZX(intel_filesize);
1909 cab_LONG abs_off, rel_off;
1911 LZX(intel_curpos) = curpos + outlen;
1913 while (data < dataend) {
1914 if (*data++ != 0xE8) { curpos++; continue; }
1915 abs_off = data[0] | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);
1916 if ((abs_off >= -curpos) && (abs_off < filesize)) {
1917 rel_off = (abs_off >= 0) ? abs_off - curpos : abs_off + filesize;
1918 data[0] = (cab_UBYTE) rel_off;
1919 data[1] = (cab_UBYTE) (rel_off >> 8);
1920 data[2] = (cab_UBYTE) (rel_off >> 16);
1921 data[3] = (cab_UBYTE) (rel_off >> 24);
1923 data += 4;
1924 curpos += 5;
1928 return DECR_OK;
1931 /**********************************************************
1932 * fdi_decomp (internal)
1934 * Decompress the requested number of bytes. If savemode is zero,
1935 * do not save the output anywhere, just plow through blocks until we
1936 * reach the specified (uncompressed) distance from the starting point,
1937 * and remember the position of the cabfile pointer (and which cabfile)
1938 * after we are done; otherwise, save the data out to CAB(filehf),
1939 * decompressing the requested number of bytes and writing them out. This
1940 * is also where we jump to additional cabinets in the case of split
1941 * cab's, and provide (some of) the NEXT_CABINET notification semantics.
1943 static int fdi_decomp(const struct fdi_file *fi, int savemode, fdi_decomp_state *decomp_state,
1944 char *pszCabPath, PFNFDINOTIFY pfnfdin, void *pvUser)
1946 cab_ULONG bytes = savemode ? fi->length : fi->offset - CAB(offset);
1947 cab_UBYTE buf[cfdata_SIZEOF], *data;
1948 cab_UWORD inlen, len, outlen, cando;
1949 cab_ULONG cksum;
1950 cab_LONG err;
1951 fdi_decomp_state *cab = (savemode && CAB(decomp_cab)) ? CAB(decomp_cab) : decomp_state;
1953 TRACE("(fi == ^%p, savemode == %d, bytes == %d)\n", fi, savemode, bytes);
1955 while (bytes > 0) {
1956 /* cando = the max number of bytes we can do */
1957 cando = CAB(outlen);
1958 if (cando > bytes) cando = bytes;
1960 /* if cando != 0 */
1961 if (cando && savemode)
1962 CAB(fdi)->write(CAB(filehf), CAB(outpos), cando);
1964 CAB(outpos) += cando;
1965 CAB(outlen) -= cando;
1966 bytes -= cando; if (!bytes) break;
1968 /* we only get here if we emptied the output buffer */
1970 /* read data header + data */
1971 inlen = outlen = 0;
1972 while (outlen == 0) {
1973 /* read the block header, skip the reserved part */
1974 if (CAB(fdi)->read(cab->cabhf, buf, cfdata_SIZEOF) != cfdata_SIZEOF)
1975 return DECR_INPUT;
1977 if (CAB(fdi)->seek(cab->cabhf, cab->mii.block_resv, SEEK_CUR) == -1)
1978 return DECR_INPUT;
1980 /* we shouldn't get blocks over CAB_INPUTMAX in size */
1981 data = CAB(inbuf) + inlen;
1982 len = EndGetI16(buf+cfdata_CompressedSize);
1983 inlen += len;
1984 if (inlen > CAB_INPUTMAX) return DECR_INPUT;
1985 if (CAB(fdi)->read(cab->cabhf, data, len) != len)
1986 return DECR_INPUT;
1988 /* clear two bytes after read-in data */
1989 data[len+1] = data[len+2] = 0;
1991 /* perform checksum test on the block (if one is stored) */
1992 cksum = EndGetI32(buf+cfdata_CheckSum);
1993 if (cksum && cksum != checksum(buf+4, 4, checksum(data, len, 0)))
1994 return DECR_CHECKSUM; /* checksum is wrong */
1996 outlen = EndGetI16(buf+cfdata_UncompressedSize);
1998 /* outlen=0 means this block was the last contiguous part
1999 of a split block, continued in the next cabinet */
2000 if (outlen == 0) {
2001 int pathlen, filenamelen;
2002 INT_PTR cabhf;
2003 char fullpath[MAX_PATH], userpath[256];
2004 FDINOTIFICATION fdin;
2005 FDICABINETINFO fdici;
2006 char emptystring = '\0';
2007 cab_UBYTE buf2[64];
2008 BOOL success = FALSE;
2009 struct fdi_folder *fol = NULL, *linkfol = NULL;
2010 struct fdi_file *file = NULL, *linkfile = NULL;
2012 tryanothercab:
2014 /* set up the next decomp_state... */
2015 if (!(cab->next)) {
2016 unsigned int i;
2018 if (!cab->mii.hasnext) return DECR_INPUT;
2020 if (!((cab->next = CAB(fdi)->alloc(sizeof(fdi_decomp_state)))))
2021 return DECR_NOMEMORY;
2023 ZeroMemory(cab->next, sizeof(fdi_decomp_state));
2025 /* copy pszCabPath to userpath */
2026 ZeroMemory(userpath, 256);
2027 pathlen = pszCabPath ? strlen(pszCabPath) : 0;
2028 if (pathlen) {
2029 if (pathlen < 256) /* else we are in a weird place... let's leave it blank and see if the user fixes it */
2030 strcpy(userpath, pszCabPath);
2033 /* initial fdintNEXT_CABINET notification */
2034 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2035 fdin.psz1 = cab->mii.nextname ? cab->mii.nextname : &emptystring;
2036 fdin.psz2 = cab->mii.nextinfo ? cab->mii.nextinfo : &emptystring;
2037 fdin.psz3 = userpath;
2038 fdin.fdie = FDIERROR_NONE;
2039 fdin.pv = pvUser;
2041 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2043 do {
2045 pathlen = strlen(userpath);
2046 filenamelen = cab->mii.nextname ? strlen(cab->mii.nextname) : 0;
2048 /* slight overestimation here to save CPU cycles in the developer's brain */
2049 if ((pathlen + filenamelen + 3) > MAX_PATH) {
2050 ERR("MAX_PATH exceeded.\n");
2051 return DECR_ILLEGALDATA;
2054 /* paste the path and filename together */
2055 fullpath[0] = '\0';
2056 if (pathlen) {
2057 strcpy(fullpath, userpath);
2058 if (fullpath[pathlen - 1] != '\\')
2059 strcat(fullpath, "\\");
2061 if (filenamelen)
2062 strcat(fullpath, cab->mii.nextname);
2064 TRACE("full cab path/file name: %s\n", debugstr_a(fullpath));
2066 /* try to get a handle to the cabfile */
2067 cabhf = CAB(fdi)->open(fullpath, _O_RDONLY|_O_BINARY, _S_IREAD | _S_IWRITE);
2068 if (cabhf == -1) {
2069 /* no file. allow the user to try again */
2070 fdin.fdie = FDIERROR_CABINET_NOT_FOUND;
2071 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2072 continue;
2075 if (cabhf == 0) {
2076 ERR("PFDI_OPEN returned zero for %s.\n", fullpath);
2077 fdin.fdie = FDIERROR_CABINET_NOT_FOUND;
2078 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2079 continue;
2082 /* check if it's really a cabfile. Note that this doesn't implement the bug */
2083 if (!FDI_read_entries(CAB(fdi), cabhf, &fdici, &(cab->next->mii))) {
2084 WARN("FDIIsCabinet failed.\n");
2085 CAB(fdi)->close(cabhf);
2086 fdin.fdie = FDIERROR_NOT_A_CABINET;
2087 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2088 continue;
2091 if ((fdici.setID != cab->setID) || (fdici.iCabinet != (cab->iCabinet + 1))) {
2092 WARN("Wrong Cabinet.\n");
2093 CAB(fdi)->close(cabhf);
2094 fdin.fdie = FDIERROR_WRONG_CABINET;
2095 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2096 continue;
2099 break;
2101 } while (1);
2103 /* cabinet notification */
2104 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2105 fdin.setID = fdici.setID;
2106 fdin.iCabinet = fdici.iCabinet;
2107 fdin.pv = pvUser;
2108 fdin.psz1 = (cab->next->mii.nextname) ? cab->next->mii.nextname : &emptystring;
2109 fdin.psz2 = (cab->next->mii.nextinfo) ? cab->next->mii.nextinfo : &emptystring;
2110 fdin.psz3 = pszCabPath;
2112 if (((*pfnfdin)(fdintCABINET_INFO, &fdin))) return DECR_USERABORT;
2114 cab->next->setID = fdici.setID;
2115 cab->next->iCabinet = fdici.iCabinet;
2116 cab->next->fdi = CAB(fdi);
2117 cab->next->filehf = CAB(filehf);
2118 cab->next->cabhf = cabhf;
2119 cab->next->decompress = CAB(decompress); /* crude, but unused anyhow */
2121 cab = cab->next; /* advance to the next cabinet */
2123 /* read folders */
2124 for (i = 0; i < fdici.cFolders; i++) {
2125 if (CAB(fdi)->read(cab->cabhf, buf2, cffold_SIZEOF) != cffold_SIZEOF)
2126 return DECR_INPUT;
2128 if (cab->mii.folder_resv > 0)
2129 CAB(fdi)->seek(cab->cabhf, cab->mii.folder_resv, SEEK_CUR);
2131 fol = CAB(fdi)->alloc(sizeof(struct fdi_folder));
2132 if (!fol) {
2133 ERR("out of memory!\n");
2134 return DECR_NOMEMORY;
2136 ZeroMemory(fol, sizeof(struct fdi_folder));
2137 if (!(cab->firstfol)) cab->firstfol = fol;
2139 fol->offset = (cab_off_t) EndGetI32(buf2+cffold_DataOffset);
2140 fol->num_blocks = EndGetI16(buf2+cffold_NumBlocks);
2141 fol->comp_type = EndGetI16(buf2+cffold_CompType);
2143 if (linkfol)
2144 linkfol->next = fol;
2145 linkfol = fol;
2148 /* read files */
2149 for (i = 0; i < fdici.cFiles; i++) {
2150 if (CAB(fdi)->read(cab->cabhf, buf2, cffile_SIZEOF) != cffile_SIZEOF)
2151 return DECR_INPUT;
2153 file = CAB(fdi)->alloc(sizeof(struct fdi_file));
2154 if (!file) {
2155 ERR("out of memory!\n");
2156 return DECR_NOMEMORY;
2158 ZeroMemory(file, sizeof(struct fdi_file));
2159 if (!(cab->firstfile)) cab->firstfile = file;
2161 file->length = EndGetI32(buf2+cffile_UncompressedSize);
2162 file->offset = EndGetI32(buf2+cffile_FolderOffset);
2163 file->index = EndGetI16(buf2+cffile_FolderIndex);
2164 file->time = EndGetI16(buf2+cffile_Time);
2165 file->date = EndGetI16(buf2+cffile_Date);
2166 file->attribs = EndGetI16(buf2+cffile_Attribs);
2167 file->filename = FDI_read_string(CAB(fdi), cab->cabhf, fdici.cbCabinet);
2169 if (!file->filename) return DECR_INPUT;
2171 if (linkfile)
2172 linkfile->next = file;
2173 linkfile = file;
2176 } else
2177 cab = cab->next; /* advance to the next cabinet */
2179 /* iterate files -- if we encounter the continued file, process it --
2180 otherwise, jump to the label above and keep looking */
2182 for (file = cab->firstfile; (file); file = file->next) {
2183 if ((file->index & cffileCONTINUED_FROM_PREV) == cffileCONTINUED_FROM_PREV) {
2184 /* check to ensure a real match */
2185 if (lstrcmpiA(fi->filename, file->filename) == 0) {
2186 success = TRUE;
2187 if (CAB(fdi)->seek(cab->cabhf, cab->firstfol->offset, SEEK_SET) == -1)
2188 return DECR_INPUT;
2189 break;
2193 if (!success) goto tryanothercab; /* FIXME: shouldn't this trigger
2194 "Wrong Cabinet" notification? */
2198 /* decompress block */
2199 if ((err = CAB(decompress)(inlen, outlen, decomp_state)))
2200 return err;
2201 CAB(outlen) = outlen;
2202 CAB(outpos) = CAB(outbuf);
2205 CAB(decomp_cab) = cab;
2206 return DECR_OK;
2209 static void free_decompression_temps(FDI_Int *fdi, const struct fdi_folder *fol,
2210 fdi_decomp_state *decomp_state)
2212 switch (fol->comp_type & cffoldCOMPTYPE_MASK) {
2213 case cffoldCOMPTYPE_LZX:
2214 if (LZX(window)) {
2215 fdi->free(LZX(window));
2216 LZX(window) = NULL;
2218 break;
2219 case cffoldCOMPTYPE_QUANTUM:
2220 if (QTM(window)) {
2221 fdi->free(QTM(window));
2222 QTM(window) = NULL;
2224 break;
2228 static void free_decompression_mem(FDI_Int *fdi, fdi_decomp_state *decomp_state)
2230 struct fdi_folder *fol;
2231 while (decomp_state) {
2232 fdi_decomp_state *prev_fds;
2234 fdi->close(CAB(cabhf));
2236 /* free the storage remembered by mii */
2237 if (CAB(mii).nextname) fdi->free(CAB(mii).nextname);
2238 if (CAB(mii).nextinfo) fdi->free(CAB(mii).nextinfo);
2239 if (CAB(mii).prevname) fdi->free(CAB(mii).prevname);
2240 if (CAB(mii).previnfo) fdi->free(CAB(mii).previnfo);
2242 while (CAB(firstfol)) {
2243 fol = CAB(firstfol);
2244 CAB(firstfol) = CAB(firstfol)->next;
2245 fdi->free(fol);
2247 while (CAB(firstfile)) {
2248 struct fdi_file *file = CAB(firstfile);
2249 if (file->filename) fdi->free(file->filename);
2250 CAB(firstfile) = CAB(firstfile)->next;
2251 fdi->free(file);
2253 prev_fds = decomp_state;
2254 decomp_state = CAB(next);
2255 fdi->free(prev_fds);
2259 /***********************************************************************
2260 * FDICopy (CABINET.22)
2262 * Iterates through the files in the Cabinet file indicated by name and
2263 * file-location. May chain forward to additional cabinets (typically
2264 * only one) if files which begin in this Cabinet are continued in another
2265 * cabinet. For each file which is partially contained in this cabinet,
2266 * and partially contained in a prior cabinet, provides fdintPARTIAL_FILE
2267 * notification to the pfnfdin callback. For each file which begins in
2268 * this cabinet, fdintCOPY_FILE notification is provided to the pfnfdin
2269 * callback, and the file is optionally decompressed and saved to disk.
2270 * Notification is not provided for files which are not at least partially
2271 * contained in the specified cabinet file.
2273 * See below for a thorough explanation of the various notification
2274 * callbacks.
2276 * PARAMS
2277 * hfdi [I] An HFDI from FDICreate
2278 * pszCabinet [I] C-style string containing the filename of the cabinet
2279 * pszCabPath [I] C-style string containing the file path of the cabinet
2280 * flags [I] "Decoder parameters". Ignored. Suggested value: 0.
2281 * pfnfdin [I] Pointer to a notification function. See CALLBACKS below.
2282 * pfnfdid [I] Pointer to a decryption function. Ignored. Suggested
2283 * value: NULL.
2284 * pvUser [I] arbitrary void * value which is passed to callbacks.
2286 * RETURNS
2287 * TRUE if successful.
2288 * FALSE if unsuccessful (error information is provided in the ERF structure
2289 * associated with the provided decompression handle by FDICreate).
2291 * CALLBACKS
2293 * Two pointers to callback functions are provided as parameters to FDICopy:
2294 * pfnfdin(of type PFNFDINOTIFY), and pfnfdid (of type PFNFDIDECRYPT). These
2295 * types are as follows:
2297 * typedef INT_PTR (__cdecl *PFNFDINOTIFY) ( FDINOTIFICATIONTYPE fdint,
2298 * PFDINOTIFICATION pfdin );
2300 * typedef int (__cdecl *PFNFDIDECRYPT) ( PFDIDECRYPT pfdid );
2302 * You can create functions of this type using the FNFDINOTIFY() and
2303 * FNFDIDECRYPT() macros, respectively. For example:
2305 * FNFDINOTIFY(mycallback) {
2306 * / * use variables fdint and pfdin to process notification * /
2309 * The second callback, which could be used for decrypting encrypted data,
2310 * is not used at all.
2312 * Each notification informs the user of some event which has occurred during
2313 * decompression of the cabinet file; each notification is also an opportunity
2314 * for the callee to abort decompression. The information provided to the
2315 * callback and the meaning of the callback's return value vary drastically
2316 * across the various types of notification. The type of notification is the
2317 * fdint parameter; all other information is provided to the callback in
2318 * notification-specific parts of the FDINOTIFICATION structure pointed to by
2319 * pfdin. The only part of that structure which is assigned for every callback
2320 * is the pv element, which contains the arbitrary value which was passed to
2321 * FDICopy in the pvUser argument (psz1 is also used each time, but its meaning
2322 * is highly dependent on fdint).
2324 * If you encounter unknown notifications, you should return zero if you want
2325 * decompression to continue (or -1 to abort). All strings used in the
2326 * callbacks are regular C-style strings. Detailed descriptions of each
2327 * notification type follow:
2329 * fdintCABINET_INFO:
2331 * This is the first notification provided after calling FDICopy, and provides
2332 * the user with various information about the cabinet. Note that this is
2333 * called for each cabinet FDICopy opens, not just the first one. In the
2334 * structure pointed to by pfdin, psz1 contains a pointer to the name of the
2335 * next cabinet file in the set after the one just loaded (if any), psz2
2336 * contains a pointer to the name or "info" of the next disk, psz3
2337 * contains a pointer to the file-path of the current cabinet, setID
2338 * contains an arbitrary constant associated with this set of cabinet files,
2339 * and iCabinet contains the numerical index of the current cabinet within
2340 * that set. Return zero, or -1 to abort.
2342 * fdintPARTIAL_FILE:
2344 * This notification is provided when FDICopy encounters a part of a file
2345 * contained in this cabinet which is missing its beginning. Files can be
2346 * split across cabinets, so this is not necessarily an abnormality; it just
2347 * means that the file in question begins in another cabinet. No file
2348 * corresponding to this notification is extracted from the cabinet. In the
2349 * structure pointed to by pfdin, psz1 contains a pointer to the name of the
2350 * partial file, psz2 contains a pointer to the file name of the cabinet in
2351 * which this file begins, and psz3 contains a pointer to the disk name or
2352 * "info" of the cabinet where the file begins. Return zero, or -1 to abort.
2354 * fdintCOPY_FILE:
2356 * This notification is provided when FDICopy encounters a file which starts
2357 * in the cabinet file, provided to FDICopy in pszCabinet. (FDICopy will not
2358 * look for files in cabinets after the first one). One notification will be
2359 * sent for each such file, before the file is decompressed. By returning
2360 * zero, the callback can instruct FDICopy to skip the file. In the structure
2361 * pointed to by pfdin, psz1 contains a pointer to the file's name, cb contains
2362 * the size of the file (uncompressed), attribs contains the file attributes,
2363 * and date and time contain the date and time of the file. attributes, date,
2364 * and time are of the 16-bit ms-dos variety. Return -1 to abort decompression
2365 * for the entire cabinet, 0 to skip just this file but continue scanning the
2366 * cabinet for more files, or an FDIClose()-compatible file-handle.
2368 * fdintCLOSE_FILE_INFO:
2370 * This notification is important, don't forget to implement it. This
2371 * notification indicates that a file has been successfully uncompressed and
2372 * written to disk. Upon receipt of this notification, the callee is expected
2373 * to close the file handle, to set the attributes and date/time of the
2374 * closed file, and possibly to execute the file. In the structure pointed to
2375 * by pfdin, psz1 contains a pointer to the name of the file, hf will be the
2376 * open file handle (close it), cb contains 1 or zero, indicating respectively
2377 * that the callee should or should not execute the file, and date, time
2378 * and attributes will be set as in fdintCOPY_FILE. Bizarrely, the Cabinet SDK
2379 * specifies that _A_EXEC will be xor'ed out of attributes! wine does not do
2380 * do so. Return TRUE, or FALSE to abort decompression.
2382 * fdintNEXT_CABINET:
2384 * This notification is called when FDICopy must load in another cabinet. This
2385 * can occur when a file's data is "split" across multiple cabinets. The
2386 * callee has the opportunity to request that FDICopy look in a different file
2387 * path for the specified cabinet file, by writing that data into a provided
2388 * buffer (see below for more information). This notification will be received
2389 * more than once per-cabinet in the instance that FDICopy failed to find a
2390 * valid cabinet at the location specified by the first per-cabinet
2391 * fdintNEXT_CABINET notification. In such instances, the fdie element of the
2392 * structure pointed to by pfdin indicates the error which prevented FDICopy
2393 * from proceeding successfully. Return zero to indicate success, or -1 to
2394 * indicate failure and abort FDICopy.
2396 * Upon receipt of this notification, the structure pointed to by pfdin will
2397 * contain the following values: psz1 pointing to the name of the cabinet
2398 * which FDICopy is attempting to open, psz2 pointing to the name ("info") of
2399 * the next disk, psz3 pointing to the presumed file-location of the cabinet,
2400 * and fdie containing either FDIERROR_NONE, or one of the following:
2402 * FDIERROR_CABINET_NOT_FOUND, FDIERROR_NOT_A_CABINET,
2403 * FDIERROR_UNKNOWN_CABINET_VERSION, FDIERROR_CORRUPT_CABINET,
2404 * FDIERROR_BAD_COMPR_TYPE, FDIERROR_RESERVE_MISMATCH, and
2405 * FDIERROR_WRONG_CABINET.
2407 * The callee may choose to change the path where FDICopy will look for the
2408 * cabinet after this notification. To do so, the caller may write the new
2409 * pathname to the buffer pointed to by psz3, which is 256 characters in
2410 * length, including the terminating null character, before returning zero.
2412 * fdintENUMERATE:
2414 * Undocumented and unimplemented in wine, this seems to be sent each time
2415 * a cabinet is opened, along with the fdintCABINET_INFO notification. It
2416 * probably has an interface similar to that of fdintCABINET_INFO; maybe this
2417 * provides information about the current cabinet instead of the next one....
2418 * this is just a guess, it has not been looked at closely.
2420 * INCLUDES
2421 * fdi.c
2423 BOOL __cdecl FDICopy(
2424 HFDI hfdi,
2425 char *pszCabinet,
2426 char *pszCabPath,
2427 int flags,
2428 PFNFDINOTIFY pfnfdin,
2429 PFNFDIDECRYPT pfnfdid,
2430 void *pvUser)
2432 FDICABINETINFO fdici;
2433 FDINOTIFICATION fdin;
2434 INT_PTR cabhf, filehf = 0;
2435 unsigned int i;
2436 char fullpath[MAX_PATH];
2437 size_t pathlen, filenamelen;
2438 char emptystring = '\0';
2439 cab_UBYTE buf[64];
2440 struct fdi_folder *fol = NULL, *linkfol = NULL;
2441 struct fdi_file *file = NULL, *linkfile = NULL;
2442 fdi_decomp_state *decomp_state;
2443 FDI_Int *fdi = get_fdi_ptr( hfdi );
2445 TRACE("(hfdi == ^%p, pszCabinet == %s, pszCabPath == %s, flags == %x, "
2446 "pfnfdin == ^%p, pfnfdid == ^%p, pvUser == ^%p)\n",
2447 hfdi, debugstr_a(pszCabinet), debugstr_a(pszCabPath), flags, pfnfdin, pfnfdid, pvUser);
2449 if (!fdi) return FALSE;
2451 if (!(decomp_state = fdi->alloc(sizeof(fdi_decomp_state))))
2453 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2454 return FALSE;
2456 ZeroMemory(decomp_state, sizeof(fdi_decomp_state));
2458 pathlen = pszCabPath ? strlen(pszCabPath) : 0;
2459 filenamelen = pszCabinet ? strlen(pszCabinet) : 0;
2461 /* slight overestimation here to save CPU cycles in the developer's brain */
2462 if ((pathlen + filenamelen + 3) > MAX_PATH) {
2463 ERR("MAX_PATH exceeded.\n");
2464 fdi->free(decomp_state);
2465 set_error( fdi, FDIERROR_CABINET_NOT_FOUND, ERROR_FILE_NOT_FOUND );
2466 return FALSE;
2469 /* paste the path and filename together */
2470 fullpath[0] = '\0';
2471 if (pathlen)
2472 strcpy(fullpath, pszCabPath);
2473 if (filenamelen)
2474 strcat(fullpath, pszCabinet);
2476 TRACE("full cab path/file name: %s\n", debugstr_a(fullpath));
2478 /* get a handle to the cabfile */
2479 cabhf = fdi->open(fullpath, _O_RDONLY|_O_BINARY, _S_IREAD | _S_IWRITE);
2480 if (cabhf == -1) {
2481 fdi->free(decomp_state);
2482 set_error( fdi, FDIERROR_CABINET_NOT_FOUND, 0 );
2483 SetLastError(ERROR_FILE_NOT_FOUND);
2484 return FALSE;
2487 /* check if it's really a cabfile. Note that this doesn't implement the bug */
2488 if (!FDI_read_entries(fdi, cabhf, &fdici, &(CAB(mii)))) {
2489 WARN("FDI_read_entries failed: %u\n", fdi->perf->erfOper);
2490 fdi->free(decomp_state);
2491 fdi->close(cabhf);
2492 return FALSE;
2495 /* cabinet notification */
2496 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2497 fdin.setID = fdici.setID;
2498 fdin.iCabinet = fdici.iCabinet;
2499 fdin.pv = pvUser;
2500 fdin.psz1 = (CAB(mii).nextname) ? CAB(mii).nextname : &emptystring;
2501 fdin.psz2 = (CAB(mii).nextinfo) ? CAB(mii).nextinfo : &emptystring;
2502 fdin.psz3 = pszCabPath;
2504 if (((*pfnfdin)(fdintCABINET_INFO, &fdin))) {
2505 set_error( fdi, FDIERROR_USER_ABORT, 0 );
2506 goto bail_and_fail;
2509 CAB(setID) = fdici.setID;
2510 CAB(iCabinet) = fdici.iCabinet;
2511 CAB(cabhf) = cabhf;
2513 /* read folders */
2514 for (i = 0; i < fdici.cFolders; i++) {
2515 if (fdi->read(cabhf, buf, cffold_SIZEOF) != cffold_SIZEOF) {
2516 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
2517 goto bail_and_fail;
2520 if (CAB(mii).folder_resv > 0)
2521 fdi->seek(cabhf, CAB(mii).folder_resv, SEEK_CUR);
2523 fol = fdi->alloc(sizeof(struct fdi_folder));
2524 if (!fol) {
2525 ERR("out of memory!\n");
2526 set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY );
2527 goto bail_and_fail;
2529 ZeroMemory(fol, sizeof(struct fdi_folder));
2530 if (!CAB(firstfol)) CAB(firstfol) = fol;
2532 fol->offset = (cab_off_t) EndGetI32(buf+cffold_DataOffset);
2533 fol->num_blocks = EndGetI16(buf+cffold_NumBlocks);
2534 fol->comp_type = EndGetI16(buf+cffold_CompType);
2536 if (linkfol)
2537 linkfol->next = fol;
2538 linkfol = fol;
2541 /* read files */
2542 for (i = 0; i < fdici.cFiles; i++) {
2543 if (fdi->read(cabhf, buf, cffile_SIZEOF) != cffile_SIZEOF) {
2544 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
2545 goto bail_and_fail;
2548 file = fdi->alloc(sizeof(struct fdi_file));
2549 if (!file) {
2550 ERR("out of memory!\n");
2551 set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY );
2552 goto bail_and_fail;
2554 ZeroMemory(file, sizeof(struct fdi_file));
2555 if (!CAB(firstfile)) CAB(firstfile) = file;
2557 file->length = EndGetI32(buf+cffile_UncompressedSize);
2558 file->offset = EndGetI32(buf+cffile_FolderOffset);
2559 file->index = EndGetI16(buf+cffile_FolderIndex);
2560 file->time = EndGetI16(buf+cffile_Time);
2561 file->date = EndGetI16(buf+cffile_Date);
2562 file->attribs = EndGetI16(buf+cffile_Attribs);
2563 file->filename = FDI_read_string(fdi, cabhf, fdici.cbCabinet);
2565 if (!file->filename) {
2566 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
2567 goto bail_and_fail;
2570 if (linkfile)
2571 linkfile->next = file;
2572 linkfile = file;
2575 for (file = CAB(firstfile); (file); file = file->next) {
2578 * FIXME: This implementation keeps multiple cabinet files open at once
2579 * when encountering a split cabinet. It is a quirk of this implementation
2580 * that sometimes we decrypt the same block of data more than once, to find
2581 * the right starting point for a file, moving the file-pointer backwards.
2582 * If we kept a cache of certain file-pointer information, we could eliminate
2583 * that behavior... in fact I am not sure that the caching we already have
2584 * is not sufficient.
2586 * The current implementation seems to work fine in straightforward situations
2587 * where all the cabinet files needed for decryption are simultaneously
2588 * available. But presumably, the API is supposed to support cabinets which
2589 * are split across multiple CDROMS; we may need to change our implementation
2590 * to strictly serialize it's file usage so that it opens only one cabinet
2591 * at a time. Some experimentation with Windows is needed to figure out the
2592 * precise semantics required. The relevant code is here and in fdi_decomp().
2595 /* partial-file notification */
2596 if ((file->index & cffileCONTINUED_FROM_PREV) == cffileCONTINUED_FROM_PREV) {
2598 * FIXME: Need to create a Cabinet with a single file spanning multiple files
2599 * and perform some tests to figure out the right behavior. The SDK says
2600 * FDICopy will notify the user of the filename and "disk name" (info) of
2601 * the cabinet where the spanning file /started/.
2603 * That would certainly be convenient for the API-user, who could abort,
2604 * everything (or parallelize, if that's allowed (it is in wine)), and call
2605 * FDICopy again with the provided filename, so as to avoid partial file
2606 * notification and successfully unpack. This task could be quite unpleasant
2607 * from wine's perspective: the information specifying the "start cabinet" for
2608 * a file is associated nowhere with the file header and is not to be found in
2609 * the cabinet header. We have only the index of the cabinet wherein the folder
2610 * begins, which contains the file. To find that cabinet, we must consider the
2611 * index of the current cabinet, and chain backwards, cabinet-by-cabinet (for
2612 * each cabinet refers to its "next" and "previous" cabinet only, like a linked
2613 * list).
2615 * Bear in mind that, in the spirit of CABINET.DLL, we must assume that any
2616 * cabinet other than the active one might be at another filepath than the
2617 * current one, or on another CDROM. This could get rather dicey, especially
2618 * if we imagine parallelized access to the FDICopy API.
2620 * The current implementation punts -- it just returns the previous cabinet and
2621 * it's info from the header of this cabinet. This provides the right answer in
2622 * 95% of the cases; its worth checking if Microsoft cuts the same corner before
2623 * we "fix" it.
2625 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2626 fdin.pv = pvUser;
2627 fdin.psz1 = (char *)file->filename;
2628 fdin.psz2 = (CAB(mii).prevname) ? CAB(mii).prevname : &emptystring;
2629 fdin.psz3 = (CAB(mii).previnfo) ? CAB(mii).previnfo : &emptystring;
2631 if (((*pfnfdin)(fdintPARTIAL_FILE, &fdin))) {
2632 set_error( fdi, FDIERROR_USER_ABORT, 0 );
2633 goto bail_and_fail;
2635 /* I don't think we are supposed to decompress partial files. This prevents it. */
2636 file->oppressed = TRUE;
2638 if (file->oppressed) {
2639 filehf = 0;
2640 } else {
2641 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2642 fdin.pv = pvUser;
2643 fdin.psz1 = (char *)file->filename;
2644 fdin.cb = file->length;
2645 fdin.date = file->date;
2646 fdin.time = file->time;
2647 fdin.attribs = file->attribs;
2648 if ((filehf = ((*pfnfdin)(fdintCOPY_FILE, &fdin))) == -1) {
2649 set_error( fdi, FDIERROR_USER_ABORT, 0 );
2650 filehf = 0;
2651 goto bail_and_fail;
2655 /* find the folder for this file if necc. */
2656 if (filehf) {
2657 fol = CAB(firstfol);
2658 if ((file->index & cffileCONTINUED_TO_NEXT) == cffileCONTINUED_TO_NEXT) {
2659 /* pick the last folder */
2660 while (fol->next) fol = fol->next;
2661 } else {
2662 unsigned int i2;
2664 for (i2 = 0; (i2 < file->index); i2++)
2665 if (fol->next) /* bug resistance, should always be true */
2666 fol = fol->next;
2670 if (filehf) {
2671 cab_UWORD comptype = fol->comp_type;
2672 int ct1 = comptype & cffoldCOMPTYPE_MASK;
2673 int ct2 = CAB(current) ? (CAB(current)->comp_type & cffoldCOMPTYPE_MASK) : 0;
2674 int err = 0;
2676 TRACE("Extracting file %s as requested by callee.\n", debugstr_a(file->filename));
2678 /* set up decomp_state */
2679 CAB(fdi) = fdi;
2680 CAB(filehf) = filehf;
2682 /* Was there a change of folder? Compression type? Did we somehow go backwards? */
2683 if ((ct1 != ct2) || (CAB(current) != fol) || (file->offset < CAB(offset))) {
2685 TRACE("Resetting folder for file %s.\n", debugstr_a(file->filename));
2687 /* free stuff for the old decompressor */
2688 switch (ct2) {
2689 case cffoldCOMPTYPE_LZX:
2690 if (LZX(window)) {
2691 fdi->free(LZX(window));
2692 LZX(window) = NULL;
2694 break;
2695 case cffoldCOMPTYPE_QUANTUM:
2696 if (QTM(window)) {
2697 fdi->free(QTM(window));
2698 QTM(window) = NULL;
2700 break;
2703 CAB(decomp_cab) = NULL;
2704 CAB(fdi)->seek(CAB(cabhf), fol->offset, SEEK_SET);
2705 CAB(offset) = 0;
2706 CAB(outlen) = 0;
2708 /* initialize the new decompressor */
2709 switch (ct1) {
2710 case cffoldCOMPTYPE_NONE:
2711 CAB(decompress) = NONEfdi_decomp;
2712 break;
2713 case cffoldCOMPTYPE_MSZIP:
2714 CAB(decompress) = ZIPfdi_decomp;
2715 break;
2716 case cffoldCOMPTYPE_QUANTUM:
2717 CAB(decompress) = QTMfdi_decomp;
2718 err = QTMfdi_init((comptype >> 8) & 0x1f, (comptype >> 4) & 0xF, decomp_state);
2719 break;
2720 case cffoldCOMPTYPE_LZX:
2721 CAB(decompress) = LZXfdi_decomp;
2722 err = LZXfdi_init((comptype >> 8) & 0x1f, decomp_state);
2723 break;
2724 default:
2725 err = DECR_DATAFORMAT;
2729 CAB(current) = fol;
2731 switch (err) {
2732 case DECR_OK:
2733 break;
2734 case DECR_NOMEMORY:
2735 set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY );
2736 goto bail_and_fail;
2737 default:
2738 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
2739 goto bail_and_fail;
2742 if (file->offset > CAB(offset)) {
2743 /* decode bytes and send them to /dev/null */
2744 switch (fdi_decomp(file, 0, decomp_state, pszCabPath, pfnfdin, pvUser)) {
2745 case DECR_OK:
2746 break;
2747 case DECR_USERABORT:
2748 set_error( fdi, FDIERROR_USER_ABORT, 0 );
2749 goto bail_and_fail;
2750 case DECR_NOMEMORY:
2751 set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY );
2752 goto bail_and_fail;
2753 default:
2754 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
2755 goto bail_and_fail;
2757 CAB(offset) = file->offset;
2760 /* now do the actual decompression */
2761 err = fdi_decomp(file, 1, decomp_state, pszCabPath, pfnfdin, pvUser);
2762 if (err) CAB(current) = NULL; else CAB(offset) += file->length;
2764 /* fdintCLOSE_FILE_INFO notification */
2765 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2766 fdin.pv = pvUser;
2767 fdin.psz1 = (char *)file->filename;
2768 fdin.hf = filehf;
2769 fdin.cb = (file->attribs & cffile_A_EXEC) != 0; /* FIXME: is that right? */
2770 fdin.date = file->date;
2771 fdin.time = file->time;
2772 fdin.attribs = file->attribs; /* FIXME: filter _A_EXEC? */
2773 ((*pfnfdin)(fdintCLOSE_FILE_INFO, &fdin));
2774 filehf = 0;
2776 switch (err) {
2777 case DECR_OK:
2778 break;
2779 case DECR_USERABORT:
2780 set_error( fdi, FDIERROR_USER_ABORT, 0 );
2781 goto bail_and_fail;
2782 case DECR_NOMEMORY:
2783 set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY );
2784 goto bail_and_fail;
2785 default:
2786 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
2787 goto bail_and_fail;
2792 if (fol) free_decompression_temps(fdi, fol, decomp_state);
2793 free_decompression_mem(fdi, decomp_state);
2795 return TRUE;
2797 bail_and_fail: /* here we free ram before error returns */
2799 if (fol) free_decompression_temps(fdi, fol, decomp_state);
2801 if (filehf) fdi->close(filehf);
2803 free_decompression_mem(fdi, decomp_state);
2805 return FALSE;
2808 /***********************************************************************
2809 * FDIDestroy (CABINET.23)
2811 * Frees a handle created by FDICreate. Do /not/ call this in the middle
2812 * of FDICopy. Only reason for failure would be an invalid handle.
2814 * PARAMS
2815 * hfdi [I] The HFDI to free
2817 * RETURNS
2818 * TRUE for success
2819 * FALSE for failure
2821 BOOL __cdecl FDIDestroy(HFDI hfdi)
2823 FDI_Int *fdi = get_fdi_ptr( hfdi );
2825 TRACE("(hfdi == ^%p)\n", hfdi);
2826 if (!fdi) return FALSE;
2827 fdi->magic = 0; /* paranoia */
2828 fdi->free(fdi);
2829 return TRUE;
2832 /***********************************************************************
2833 * FDITruncateCabinet (CABINET.24)
2835 * Removes all folders of a cabinet file after and including the
2836 * specified folder number.
2838 * PARAMS
2839 * hfdi [I] Handle to the FDI context.
2840 * pszCabinetName [I] Filename of the cabinet.
2841 * iFolderToDelete [I] Index of the first folder to delete.
2843 * RETURNS
2844 * Success: TRUE.
2845 * Failure: FALSE.
2847 * NOTES
2848 * The PFNWRITE function supplied to FDICreate must truncate the
2849 * file at the current position if the number of bytes to write is 0.
2851 BOOL __cdecl FDITruncateCabinet(
2852 HFDI hfdi,
2853 char *pszCabinetName,
2854 USHORT iFolderToDelete)
2856 FDI_Int *fdi = get_fdi_ptr( hfdi );
2858 FIXME("(hfdi == ^%p, pszCabinetName == %s, iFolderToDelete == %hu): stub\n",
2859 hfdi, debugstr_a(pszCabinetName), iFolderToDelete);
2861 if (!fdi) return FALSE;
2863 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2864 return FALSE;