winex11: Consider zero-size windows mapped even when they are positioned at 0,0.
[wine/multimedia.git] / dlls / cabinet / fdi.c
blobd091dbb2128af491f80b8dcd3921c723af573cce
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 base_offset, 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);
547 * FIXME: I just noticed that I am memorizing the initial file pointer
548 * offset and restoring it before reading in the rest of the header
549 * information in the cabinet. Perhaps that's correct -- that is, perhaps
550 * this API is supposed to support "streaming" cabinets which are embedded
551 * in other files, or cabinets which begin at file offsets other than zero.
552 * Otherwise, I should instead go to the absolute beginning of the file.
553 * (Either way, the semantics of wine's FDICopy require me to leave the
554 * file pointer where it is afterwards -- If Windows does not do so, we
555 * ought to duplicate the native behavior in the FDIIsCabinet API, not here.
557 * So, the answer lies in Windows; will native cabinet.dll recognize a
558 * cabinet "file" embedded in another file? Note that cabextract.c does
559 * support this, which implies that Microsoft's might. I haven't tried it
560 * yet so I don't know. ATM, most of wine's FDI cabinet routines (except
561 * this one) would not work in this way. To fix it, we could just make the
562 * various references to absolute file positions in the code relative to an
563 * initial "beginning" offset. Because the FDICopy API doesn't take a
564 * file-handle like this one, we would therein need to search through the
565 * file for the beginning of the cabinet (as we also do in cabextract.c).
566 * Note that this limits us to a maximum of one cabinet per. file: the first.
568 * So, in summary: either the code below is wrong, or the rest of fdi.c is
569 * wrong... I cannot imagine that both are correct ;) One of these flaws
570 * should be fixed after determining the behavior on Windows. We ought
571 * to check both FDIIsCabinet and FDICopy for the right behavior.
573 * -gmt
576 /* get basic offset & size info */
577 base_offset = FDI_getoffset(fdi, hf);
579 if (fdi->seek(hf, 0, SEEK_END) == -1) {
580 if (pmii) set_error( fdi, FDIERROR_NOT_A_CABINET, 0 );
581 return FALSE;
584 cabsize = FDI_getoffset(fdi, hf);
586 if ((cabsize == -1) || (base_offset == -1) ||
587 ( fdi->seek(hf, base_offset, SEEK_SET) == -1 )) {
588 if (pmii) set_error( fdi, FDIERROR_NOT_A_CABINET, 0 );
589 return FALSE;
592 /* read in the CFHEADER */
593 if (fdi->read(hf, buf, cfhead_SIZEOF) != cfhead_SIZEOF) {
594 if (pmii) set_error( fdi, FDIERROR_NOT_A_CABINET, 0 );
595 return FALSE;
598 /* check basic MSCF signature */
599 if (EndGetI32(buf+cfhead_Signature) != 0x4643534d) {
600 if (pmii) set_error( fdi, FDIERROR_NOT_A_CABINET, 0 );
601 return FALSE;
604 /* get the number of folders */
605 num_folders = EndGetI16(buf+cfhead_NumFolders);
607 /* get the number of files */
608 num_files = EndGetI16(buf+cfhead_NumFiles);
610 /* setid */
611 setid = EndGetI16(buf+cfhead_SetID);
613 /* cabinet (set) index */
614 cabidx = EndGetI16(buf+cfhead_CabinetIndex);
616 /* check the header revision */
617 if ((buf[cfhead_MajorVersion] > 1) ||
618 (buf[cfhead_MajorVersion] == 1 && buf[cfhead_MinorVersion] > 3))
620 WARN("cabinet format version > 1.3\n");
621 if (pmii) set_error( fdi, FDIERROR_UNKNOWN_CABINET_VERSION, 0 /* ? */ );
622 return FALSE;
625 /* pull the flags out */
626 flags = EndGetI16(buf+cfhead_Flags);
628 /* read the reserved-sizes part of header, if present */
629 if (flags & cfheadRESERVE_PRESENT) {
630 if (fdi->read(hf, buf, cfheadext_SIZEOF) != cfheadext_SIZEOF) {
631 ERR("bunk reserve-sizes?\n");
632 if (pmii) set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 /* ? */ );
633 return FALSE;
636 header_resv = EndGetI16(buf+cfheadext_HeaderReserved);
637 if (pmii) pmii->header_resv = header_resv;
638 folder_resv = buf[cfheadext_FolderReserved];
639 if (pmii) pmii->folder_resv = folder_resv;
640 block_resv = buf[cfheadext_DataReserved];
641 if (pmii) pmii->block_resv = block_resv;
643 if (header_resv > 60000) {
644 WARN("WARNING; header reserved space > 60000\n");
647 /* skip the reserved header */
648 if ((header_resv) && (fdi->seek(hf, header_resv, SEEK_CUR) == -1)) {
649 ERR("seek failure: header_resv\n");
650 if (pmii) set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 /* ? */ );
651 return FALSE;
655 if (flags & cfheadPREV_CABINET) {
656 prevname = FDI_read_string(fdi, hf, cabsize);
657 if (!prevname) {
658 if (pmii) set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 /* ? */ );
659 return FALSE;
660 } else
661 if (pmii)
662 pmii->prevname = prevname;
663 else
664 fdi->free(prevname);
665 previnfo = FDI_read_string(fdi, hf, cabsize);
666 if (previnfo) {
667 if (pmii)
668 pmii->previnfo = previnfo;
669 else
670 fdi->free(previnfo);
674 if (flags & cfheadNEXT_CABINET) {
675 if (pmii)
676 pmii->hasnext = TRUE;
677 nextname = FDI_read_string(fdi, hf, cabsize);
678 if (!nextname) {
679 if ((flags & cfheadPREV_CABINET) && pmii) {
680 if (pmii->prevname) fdi->free(prevname);
681 if (pmii->previnfo) fdi->free(previnfo);
683 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 /* ? */ );
684 return FALSE;
685 } else
686 if (pmii)
687 pmii->nextname = nextname;
688 else
689 fdi->free(nextname);
690 nextinfo = FDI_read_string(fdi, hf, cabsize);
691 if (nextinfo) {
692 if (pmii)
693 pmii->nextinfo = nextinfo;
694 else
695 fdi->free(nextinfo);
699 /* we could process the whole cabinet searching for problems;
700 instead lets stop here. Now let's fill out the paperwork */
701 pfdici->cbCabinet = cabsize;
702 pfdici->cFolders = num_folders;
703 pfdici->cFiles = num_files;
704 pfdici->setID = setid;
705 pfdici->iCabinet = cabidx;
706 pfdici->fReserve = (flags & cfheadRESERVE_PRESENT) ? TRUE : FALSE;
707 pfdici->hasprev = (flags & cfheadPREV_CABINET) ? TRUE : FALSE;
708 pfdici->hasnext = (flags & cfheadNEXT_CABINET) ? TRUE : FALSE;
709 return TRUE;
712 /***********************************************************************
713 * FDIIsCabinet (CABINET.21)
715 * Informs the caller as to whether or not the provided file handle is
716 * really a cabinet or not, filling out the provided PFDICABINETINFO
717 * structure with information about the cabinet. Brief explanations of
718 * the elements of this structure are available as comments accompanying
719 * its definition in wine's include/fdi.h.
721 * PARAMS
722 * hfdi [I] An HFDI from FDICreate
723 * hf [I] The file handle about which the caller inquires
724 * pfdici [IO] Pointer to a PFDICABINETINFO structure which will
725 * be filled out with information about the cabinet
726 * file indicated by hf if, indeed, it is determined
727 * to be a cabinet.
729 * RETURNS
730 * TRUE if the file is a cabinet. The info pointed to by pfdici will
731 * be provided.
732 * FALSE if the file is not a cabinet, or if an error was encountered
733 * while processing the cabinet. The PERF structure provided to
734 * FDICreate can be queried for more error information.
736 * INCLUDES
737 * fdi.c
739 BOOL __cdecl FDIIsCabinet(
740 HFDI hfdi,
741 INT_PTR hf,
742 PFDICABINETINFO pfdici)
744 BOOL rv;
745 FDI_Int *fdi = get_fdi_ptr( hfdi );
747 TRACE("(hfdi == ^%p, hf == ^%ld, pfdici == ^%p)\n", hfdi, hf, pfdici);
749 if (!fdi) return FALSE;
751 if (!hf) {
752 ERR("(!hf)!\n");
753 SetLastError(ERROR_INVALID_HANDLE);
754 return FALSE;
757 if (!pfdici) {
758 ERR("(!pfdici)!\n");
759 SetLastError(ERROR_BAD_ARGUMENTS);
760 return FALSE;
762 rv = FDI_read_entries(fdi, hf, pfdici, NULL);
764 if (rv)
765 pfdici->hasnext = FALSE; /* yuck. duplicate apparent cabinet.dll bug */
767 return rv;
770 /******************************************************************
771 * QTMfdi_initmodel (internal)
773 * Initialize a model which decodes symbols from [s] to [s]+[n]-1
775 static void QTMfdi_initmodel(struct QTMmodel *m, struct QTMmodelsym *sym, int n, int s) {
776 int i;
777 m->shiftsleft = 4;
778 m->entries = n;
779 m->syms = sym;
780 memset(m->tabloc, 0xFF, sizeof(m->tabloc)); /* clear out look-up table */
781 for (i = 0; i < n; i++) {
782 m->tabloc[i+s] = i; /* set up a look-up entry for symbol */
783 m->syms[i].sym = i+s; /* actual symbol */
784 m->syms[i].cumfreq = n-i; /* current frequency of that symbol */
786 m->syms[n].cumfreq = 0;
789 /******************************************************************
790 * QTMfdi_init (internal)
792 static int QTMfdi_init(int window, int level, fdi_decomp_state *decomp_state) {
793 unsigned int wndsize = 1 << window;
794 int msz = window * 2, i;
795 cab_ULONG j;
797 /* QTM supports window sizes of 2^10 (1Kb) through 2^21 (2Mb) */
798 /* if a previously allocated window is big enough, keep it */
799 if (window < 10 || window > 21) return DECR_DATAFORMAT;
800 if (QTM(actual_size) < wndsize) {
801 if (QTM(window)) CAB(fdi)->free(QTM(window));
802 QTM(window) = NULL;
804 if (!QTM(window)) {
805 if (!(QTM(window) = CAB(fdi)->alloc(wndsize))) return DECR_NOMEMORY;
806 QTM(actual_size) = wndsize;
808 QTM(window_size) = wndsize;
809 QTM(window_posn) = 0;
811 /* initialize static slot/extrabits tables */
812 for (i = 0, j = 0; i < 27; i++) {
813 CAB(q_length_extra)[i] = (i == 26) ? 0 : (i < 2 ? 0 : i - 2) >> 2;
814 CAB(q_length_base)[i] = j; j += 1 << ((i == 26) ? 5 : CAB(q_length_extra)[i]);
816 for (i = 0, j = 0; i < 42; i++) {
817 CAB(q_extra_bits)[i] = (i < 2 ? 0 : i-2) >> 1;
818 CAB(q_position_base)[i] = j; j += 1 << CAB(q_extra_bits)[i];
821 /* initialize arithmetic coding models */
823 QTMfdi_initmodel(&QTM(model7), &QTM(m7sym)[0], 7, 0);
825 QTMfdi_initmodel(&QTM(model00), &QTM(m00sym)[0], 0x40, 0x00);
826 QTMfdi_initmodel(&QTM(model40), &QTM(m40sym)[0], 0x40, 0x40);
827 QTMfdi_initmodel(&QTM(model80), &QTM(m80sym)[0], 0x40, 0x80);
828 QTMfdi_initmodel(&QTM(modelC0), &QTM(mC0sym)[0], 0x40, 0xC0);
830 /* model 4 depends on table size, ranges from 20 to 24 */
831 QTMfdi_initmodel(&QTM(model4), &QTM(m4sym)[0], (msz < 24) ? msz : 24, 0);
832 /* model 5 depends on table size, ranges from 20 to 36 */
833 QTMfdi_initmodel(&QTM(model5), &QTM(m5sym)[0], (msz < 36) ? msz : 36, 0);
834 /* model 6pos depends on table size, ranges from 20 to 42 */
835 QTMfdi_initmodel(&QTM(model6pos), &QTM(m6psym)[0], msz, 0);
836 QTMfdi_initmodel(&QTM(model6len), &QTM(m6lsym)[0], 27, 0);
838 return DECR_OK;
841 /************************************************************
842 * LZXfdi_init (internal)
844 static int LZXfdi_init(int window, fdi_decomp_state *decomp_state) {
845 static const cab_UBYTE bits[] =
846 { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
847 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14,
848 15, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
849 17, 17, 17};
850 static const cab_ULONG base[] =
851 { 0, 1, 2, 3, 4, 6, 8, 12,
852 16, 24, 32, 48, 64, 96, 128, 192,
853 256, 384, 512, 768, 1024, 1536, 2048, 3072,
854 4096, 6144, 8192, 12288, 16384, 24576, 32768, 49152,
855 65536, 98304, 131072, 196608, 262144, 393216, 524288, 655360,
856 786432, 917504, 1048576, 1179648, 1310720, 1441792, 1572864, 1703936,
857 1835008, 1966080, 2097152};
858 cab_ULONG wndsize = 1 << window;
859 int posn_slots;
861 /* LZX supports window sizes of 2^15 (32Kb) through 2^21 (2Mb) */
862 /* if a previously allocated window is big enough, keep it */
863 if (window < 15 || window > 21) return DECR_DATAFORMAT;
864 if (LZX(actual_size) < wndsize) {
865 if (LZX(window)) CAB(fdi)->free(LZX(window));
866 LZX(window) = NULL;
868 if (!LZX(window)) {
869 if (!(LZX(window) = CAB(fdi)->alloc(wndsize))) return DECR_NOMEMORY;
870 LZX(actual_size) = wndsize;
872 LZX(window_size) = wndsize;
874 /* initialize static tables */
875 memcpy(CAB(extra_bits), bits, sizeof(bits));
876 memcpy(CAB(lzx_position_base), base, sizeof(base));
878 /* calculate required position slots */
879 if (window == 20) posn_slots = 42;
880 else if (window == 21) posn_slots = 50;
881 else posn_slots = window << 1;
883 /*posn_slots=i=0; while (i < wndsize) i += 1 << CAB(extra_bits)[posn_slots++]; */
885 LZX(R0) = LZX(R1) = LZX(R2) = 1;
886 LZX(main_elements) = LZX_NUM_CHARS + (posn_slots << 3);
887 LZX(header_read) = 0;
888 LZX(frames_read) = 0;
889 LZX(block_remaining) = 0;
890 LZX(block_type) = LZX_BLOCKTYPE_INVALID;
891 LZX(intel_curpos) = 0;
892 LZX(intel_started) = 0;
893 LZX(window_posn) = 0;
895 /* initialize tables to 0 (because deltas will be applied to them) */
896 memset(LZX(MAINTREE_len), 0, sizeof(LZX(MAINTREE_len)));
897 memset(LZX(LENGTH_len), 0, sizeof(LZX(LENGTH_len)));
899 return DECR_OK;
902 /****************************************************
903 * NONEfdi_decomp(internal)
905 static int NONEfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state)
907 if (inlen != outlen) return DECR_ILLEGALDATA;
908 if (outlen > CAB_BLOCKMAX) return DECR_DATAFORMAT;
909 memcpy(CAB(outbuf), CAB(inbuf), (size_t) inlen);
910 return DECR_OK;
913 /********************************************************
914 * Ziphuft_free (internal)
916 static void fdi_Ziphuft_free(FDI_Int *fdi, struct Ziphuft *t)
918 register struct Ziphuft *p, *q;
920 /* Go through linked list, freeing from the allocated (t[-1]) address. */
921 p = t;
922 while (p != NULL)
924 q = (--p)->v.t;
925 fdi->free(p);
926 p = q;
930 /*********************************************************
931 * fdi_Ziphuft_build (internal)
933 static cab_LONG fdi_Ziphuft_build(cab_ULONG *b, cab_ULONG n, cab_ULONG s, const cab_UWORD *d, const cab_UWORD *e,
934 struct Ziphuft **t, cab_LONG *m, fdi_decomp_state *decomp_state)
936 cab_ULONG a; /* counter for codes of length k */
937 cab_ULONG el; /* length of EOB code (value 256) */
938 cab_ULONG f; /* i repeats in table every f entries */
939 cab_LONG g; /* maximum code length */
940 cab_LONG h; /* table level */
941 register cab_ULONG i; /* counter, current code */
942 register cab_ULONG j; /* counter */
943 register cab_LONG k; /* number of bits in current code */
944 cab_LONG *l; /* stack of bits per table */
945 register cab_ULONG *p; /* pointer into ZIP(c)[],ZIP(b)[],ZIP(v)[] */
946 register struct Ziphuft *q; /* points to current table */
947 struct Ziphuft r; /* table entry for structure assignment */
948 register cab_LONG w; /* bits before this table == (l * h) */
949 cab_ULONG *xp; /* pointer into x */
950 cab_LONG y; /* number of dummy codes added */
951 cab_ULONG z; /* number of entries in current table */
953 l = ZIP(lx)+1;
955 /* Generate counts for each bit length */
956 el = n > 256 ? b[256] : ZIPBMAX; /* set length of EOB code, if any */
958 for(i = 0; i < ZIPBMAX+1; ++i)
959 ZIP(c)[i] = 0;
960 p = b; i = n;
963 ZIP(c)[*p]++; p++; /* assume all entries <= ZIPBMAX */
964 } while (--i);
965 if (ZIP(c)[0] == n) /* null input--all zero length codes */
967 *t = NULL;
968 *m = 0;
969 return 0;
972 /* Find minimum and maximum length, bound *m by those */
973 for (j = 1; j <= ZIPBMAX; j++)
974 if (ZIP(c)[j])
975 break;
976 k = j; /* minimum code length */
977 if ((cab_ULONG)*m < j)
978 *m = j;
979 for (i = ZIPBMAX; i; i--)
980 if (ZIP(c)[i])
981 break;
982 g = i; /* maximum code length */
983 if ((cab_ULONG)*m > i)
984 *m = i;
986 /* Adjust last length count to fill out codes, if needed */
987 for (y = 1 << j; j < i; j++, y <<= 1)
988 if ((y -= ZIP(c)[j]) < 0)
989 return 2; /* bad input: more codes than bits */
990 if ((y -= ZIP(c)[i]) < 0)
991 return 2;
992 ZIP(c)[i] += y;
994 /* Generate starting offsets LONGo the value table for each length */
995 ZIP(x)[1] = j = 0;
996 p = ZIP(c) + 1; xp = ZIP(x) + 2;
997 while (--i)
998 { /* note that i == g from above */
999 *xp++ = (j += *p++);
1002 /* Make a table of values in order of bit lengths */
1003 p = b; i = 0;
1005 if ((j = *p++) != 0)
1006 ZIP(v)[ZIP(x)[j]++] = i;
1007 } while (++i < n);
1010 /* Generate the Huffman codes and for each, make the table entries */
1011 ZIP(x)[0] = i = 0; /* first Huffman code is zero */
1012 p = ZIP(v); /* grab values in bit order */
1013 h = -1; /* no tables yet--level -1 */
1014 w = l[-1] = 0; /* no bits decoded yet */
1015 ZIP(u)[0] = NULL; /* just to keep compilers happy */
1016 q = NULL; /* ditto */
1017 z = 0; /* ditto */
1019 /* go through the bit lengths (k already is bits in shortest code) */
1020 for (; k <= g; k++)
1022 a = ZIP(c)[k];
1023 while (a--)
1025 /* here i is the Huffman code of length k bits for value *p */
1026 /* make tables up to required level */
1027 while (k > w + l[h])
1029 w += l[h++]; /* add bits already decoded */
1031 /* compute minimum size table less than or equal to *m bits */
1032 if ((z = g - w) > (cab_ULONG)*m) /* upper limit */
1033 z = *m;
1034 if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
1035 { /* too few codes for k-w bit table */
1036 f -= a + 1; /* deduct codes from patterns left */
1037 xp = ZIP(c) + k;
1038 while (++j < z) /* try smaller tables up to z bits */
1040 if ((f <<= 1) <= *++xp)
1041 break; /* enough codes to use up j bits */
1042 f -= *xp; /* else deduct codes from patterns */
1045 if ((cab_ULONG)w + j > el && (cab_ULONG)w < el)
1046 j = el - w; /* make EOB code end at table */
1047 z = 1 << j; /* table entries for j-bit table */
1048 l[h] = j; /* set table size in stack */
1050 /* allocate and link in new table */
1051 if (!(q = CAB(fdi)->alloc((z + 1)*sizeof(struct Ziphuft))))
1053 if(h)
1054 fdi_Ziphuft_free(CAB(fdi), ZIP(u)[0]);
1055 return 3; /* not enough memory */
1057 *t = q + 1; /* link to list for Ziphuft_free() */
1058 *(t = &(q->v.t)) = NULL;
1059 ZIP(u)[h] = ++q; /* table starts after link */
1061 /* connect to last table, if there is one */
1062 if (h)
1064 ZIP(x)[h] = i; /* save pattern for backing up */
1065 r.b = (cab_UBYTE)l[h-1]; /* bits to dump before this table */
1066 r.e = (cab_UBYTE)(16 + j); /* bits in this table */
1067 r.v.t = q; /* pointer to this table */
1068 j = (i & ((1 << w) - 1)) >> (w - l[h-1]);
1069 ZIP(u)[h-1][j] = r; /* connect to last table */
1073 /* set up table entry in r */
1074 r.b = (cab_UBYTE)(k - w);
1075 if (p >= ZIP(v) + n)
1076 r.e = 99; /* out of values--invalid code */
1077 else if (*p < s)
1079 r.e = (cab_UBYTE)(*p < 256 ? 16 : 15); /* 256 is end-of-block code */
1080 r.v.n = *p++; /* simple code is just the value */
1082 else
1084 r.e = (cab_UBYTE)e[*p - s]; /* non-simple--look up in lists */
1085 r.v.n = d[*p++ - s];
1088 /* fill code-like entries with r */
1089 f = 1 << (k - w);
1090 for (j = i >> w; j < z; j += f)
1091 q[j] = r;
1093 /* backwards increment the k-bit code i */
1094 for (j = 1 << (k - 1); i & j; j >>= 1)
1095 i ^= j;
1096 i ^= j;
1098 /* backup over finished tables */
1099 while ((i & ((1 << w) - 1)) != ZIP(x)[h])
1100 w -= l[--h]; /* don't need to update q */
1104 /* return actual size of base table */
1105 *m = l[0];
1107 /* Return true (1) if we were given an incomplete table */
1108 return y != 0 && g != 1;
1111 /*********************************************************
1112 * fdi_Zipinflate_codes (internal)
1114 static cab_LONG fdi_Zipinflate_codes(const struct Ziphuft *tl, const struct Ziphuft *td,
1115 cab_LONG bl, cab_LONG bd, fdi_decomp_state *decomp_state)
1117 register cab_ULONG e; /* table entry flag/number of extra bits */
1118 cab_ULONG n, d; /* length and index for copy */
1119 cab_ULONG w; /* current window position */
1120 const struct Ziphuft *t; /* pointer to table entry */
1121 cab_ULONG ml, md; /* masks for bl and bd bits */
1122 register cab_ULONG b; /* bit buffer */
1123 register cab_ULONG k; /* number of bits in bit buffer */
1125 /* make local copies of globals */
1126 b = ZIP(bb); /* initialize bit buffer */
1127 k = ZIP(bk);
1128 w = ZIP(window_posn); /* initialize window position */
1130 /* inflate the coded data */
1131 ml = Zipmask[bl]; /* precompute masks for speed */
1132 md = Zipmask[bd];
1134 for(;;)
1136 ZIPNEEDBITS((cab_ULONG)bl)
1137 if((e = (t = tl + (b & ml))->e) > 16)
1140 if (e == 99)
1141 return 1;
1142 ZIPDUMPBITS(t->b)
1143 e -= 16;
1144 ZIPNEEDBITS(e)
1145 } while ((e = (t = t->v.t + (b & Zipmask[e]))->e) > 16);
1146 ZIPDUMPBITS(t->b)
1147 if (e == 16) /* then it's a literal */
1148 CAB(outbuf)[w++] = (cab_UBYTE)t->v.n;
1149 else /* it's an EOB or a length */
1151 /* exit if end of block */
1152 if(e == 15)
1153 break;
1155 /* get length of block to copy */
1156 ZIPNEEDBITS(e)
1157 n = t->v.n + (b & Zipmask[e]);
1158 ZIPDUMPBITS(e);
1160 /* decode distance of block to copy */
1161 ZIPNEEDBITS((cab_ULONG)bd)
1162 if ((e = (t = td + (b & md))->e) > 16)
1163 do {
1164 if (e == 99)
1165 return 1;
1166 ZIPDUMPBITS(t->b)
1167 e -= 16;
1168 ZIPNEEDBITS(e)
1169 } while ((e = (t = t->v.t + (b & Zipmask[e]))->e) > 16);
1170 ZIPDUMPBITS(t->b)
1171 ZIPNEEDBITS(e)
1172 d = w - t->v.n - (b & Zipmask[e]);
1173 ZIPDUMPBITS(e)
1176 d &= ZIPWSIZE - 1;
1177 e = ZIPWSIZE - max(d, w);
1178 e = min(e, n);
1179 n -= e;
1182 CAB(outbuf)[w++] = CAB(outbuf)[d++];
1183 } while (--e);
1184 } while (n);
1188 /* restore the globals from the locals */
1189 ZIP(window_posn) = w; /* restore global window pointer */
1190 ZIP(bb) = b; /* restore global bit buffer */
1191 ZIP(bk) = k;
1193 /* done */
1194 return 0;
1197 /***********************************************************
1198 * Zipinflate_stored (internal)
1200 static cab_LONG fdi_Zipinflate_stored(fdi_decomp_state *decomp_state)
1201 /* "decompress" an inflated type 0 (stored) block. */
1203 cab_ULONG n; /* number of bytes in block */
1204 cab_ULONG w; /* current window position */
1205 register cab_ULONG b; /* bit buffer */
1206 register cab_ULONG k; /* number of bits in bit buffer */
1208 /* make local copies of globals */
1209 b = ZIP(bb); /* initialize bit buffer */
1210 k = ZIP(bk);
1211 w = ZIP(window_posn); /* initialize window position */
1213 /* go to byte boundary */
1214 n = k & 7;
1215 ZIPDUMPBITS(n);
1217 /* get the length and its complement */
1218 ZIPNEEDBITS(16)
1219 n = (b & 0xffff);
1220 ZIPDUMPBITS(16)
1221 ZIPNEEDBITS(16)
1222 if (n != ((~b) & 0xffff))
1223 return 1; /* error in compressed data */
1224 ZIPDUMPBITS(16)
1226 /* read and output the compressed data */
1227 while(n--)
1229 ZIPNEEDBITS(8)
1230 CAB(outbuf)[w++] = (cab_UBYTE)b;
1231 ZIPDUMPBITS(8)
1234 /* restore the globals from the locals */
1235 ZIP(window_posn) = w; /* restore global window pointer */
1236 ZIP(bb) = b; /* restore global bit buffer */
1237 ZIP(bk) = k;
1238 return 0;
1241 /******************************************************
1242 * fdi_Zipinflate_fixed (internal)
1244 static cab_LONG fdi_Zipinflate_fixed(fdi_decomp_state *decomp_state)
1246 struct Ziphuft *fixed_tl;
1247 struct Ziphuft *fixed_td;
1248 cab_LONG fixed_bl, fixed_bd;
1249 cab_LONG i; /* temporary variable */
1250 cab_ULONG *l;
1252 l = ZIP(ll);
1254 /* literal table */
1255 for(i = 0; i < 144; i++)
1256 l[i] = 8;
1257 for(; i < 256; i++)
1258 l[i] = 9;
1259 for(; i < 280; i++)
1260 l[i] = 7;
1261 for(; i < 288; i++) /* make a complete, but wrong code set */
1262 l[i] = 8;
1263 fixed_bl = 7;
1264 if((i = fdi_Ziphuft_build(l, 288, 257, Zipcplens, Zipcplext, &fixed_tl, &fixed_bl, decomp_state)))
1265 return i;
1267 /* distance table */
1268 for(i = 0; i < 30; i++) /* make an incomplete code set */
1269 l[i] = 5;
1270 fixed_bd = 5;
1271 if((i = fdi_Ziphuft_build(l, 30, 0, Zipcpdist, Zipcpdext, &fixed_td, &fixed_bd, decomp_state)) > 1)
1273 fdi_Ziphuft_free(CAB(fdi), fixed_tl);
1274 return i;
1277 /* decompress until an end-of-block code */
1278 i = fdi_Zipinflate_codes(fixed_tl, fixed_td, fixed_bl, fixed_bd, decomp_state);
1280 fdi_Ziphuft_free(CAB(fdi), fixed_td);
1281 fdi_Ziphuft_free(CAB(fdi), fixed_tl);
1282 return i;
1285 /**************************************************************
1286 * fdi_Zipinflate_dynamic (internal)
1288 static cab_LONG fdi_Zipinflate_dynamic(fdi_decomp_state *decomp_state)
1289 /* decompress an inflated type 2 (dynamic Huffman codes) block. */
1291 cab_LONG i; /* temporary variables */
1292 cab_ULONG j;
1293 cab_ULONG *ll;
1294 cab_ULONG l; /* last length */
1295 cab_ULONG m; /* mask for bit lengths table */
1296 cab_ULONG n; /* number of lengths to get */
1297 struct Ziphuft *tl; /* literal/length code table */
1298 struct Ziphuft *td; /* distance code table */
1299 cab_LONG bl; /* lookup bits for tl */
1300 cab_LONG bd; /* lookup bits for td */
1301 cab_ULONG nb; /* number of bit length codes */
1302 cab_ULONG nl; /* number of literal/length codes */
1303 cab_ULONG nd; /* number of distance codes */
1304 register cab_ULONG b; /* bit buffer */
1305 register cab_ULONG k; /* number of bits in bit buffer */
1307 /* make local bit buffer */
1308 b = ZIP(bb);
1309 k = ZIP(bk);
1310 ll = ZIP(ll);
1312 /* read in table lengths */
1313 ZIPNEEDBITS(5)
1314 nl = 257 + (b & 0x1f); /* number of literal/length codes */
1315 ZIPDUMPBITS(5)
1316 ZIPNEEDBITS(5)
1317 nd = 1 + (b & 0x1f); /* number of distance codes */
1318 ZIPDUMPBITS(5)
1319 ZIPNEEDBITS(4)
1320 nb = 4 + (b & 0xf); /* number of bit length codes */
1321 ZIPDUMPBITS(4)
1322 if(nl > 288 || nd > 32)
1323 return 1; /* bad lengths */
1325 /* read in bit-length-code lengths */
1326 for(j = 0; j < nb; j++)
1328 ZIPNEEDBITS(3)
1329 ll[Zipborder[j]] = b & 7;
1330 ZIPDUMPBITS(3)
1332 for(; j < 19; j++)
1333 ll[Zipborder[j]] = 0;
1335 /* build decoding table for trees--single level, 7 bit lookup */
1336 bl = 7;
1337 if((i = fdi_Ziphuft_build(ll, 19, 19, NULL, NULL, &tl, &bl, decomp_state)) != 0)
1339 if(i == 1)
1340 fdi_Ziphuft_free(CAB(fdi), tl);
1341 return i; /* incomplete code set */
1344 /* read in literal and distance code lengths */
1345 n = nl + nd;
1346 m = Zipmask[bl];
1347 i = l = 0;
1348 while((cab_ULONG)i < n)
1350 ZIPNEEDBITS((cab_ULONG)bl)
1351 j = (td = tl + (b & m))->b;
1352 ZIPDUMPBITS(j)
1353 j = td->v.n;
1354 if (j < 16) /* length of code in bits (0..15) */
1355 ll[i++] = l = j; /* save last length in l */
1356 else if (j == 16) /* repeat last length 3 to 6 times */
1358 ZIPNEEDBITS(2)
1359 j = 3 + (b & 3);
1360 ZIPDUMPBITS(2)
1361 if((cab_ULONG)i + j > n)
1362 return 1;
1363 while (j--)
1364 ll[i++] = l;
1366 else if (j == 17) /* 3 to 10 zero length codes */
1368 ZIPNEEDBITS(3)
1369 j = 3 + (b & 7);
1370 ZIPDUMPBITS(3)
1371 if ((cab_ULONG)i + j > n)
1372 return 1;
1373 while (j--)
1374 ll[i++] = 0;
1375 l = 0;
1377 else /* j == 18: 11 to 138 zero length codes */
1379 ZIPNEEDBITS(7)
1380 j = 11 + (b & 0x7f);
1381 ZIPDUMPBITS(7)
1382 if ((cab_ULONG)i + j > n)
1383 return 1;
1384 while (j--)
1385 ll[i++] = 0;
1386 l = 0;
1390 /* free decoding table for trees */
1391 fdi_Ziphuft_free(CAB(fdi), tl);
1393 /* restore the global bit buffer */
1394 ZIP(bb) = b;
1395 ZIP(bk) = k;
1397 /* build the decoding tables for literal/length and distance codes */
1398 bl = ZIPLBITS;
1399 if((i = fdi_Ziphuft_build(ll, nl, 257, Zipcplens, Zipcplext, &tl, &bl, decomp_state)) != 0)
1401 if(i == 1)
1402 fdi_Ziphuft_free(CAB(fdi), tl);
1403 return i; /* incomplete code set */
1405 bd = ZIPDBITS;
1406 fdi_Ziphuft_build(ll + nl, nd, 0, Zipcpdist, Zipcpdext, &td, &bd, decomp_state);
1408 /* decompress until an end-of-block code */
1409 if(fdi_Zipinflate_codes(tl, td, bl, bd, decomp_state))
1410 return 1;
1412 /* free the decoding tables, return */
1413 fdi_Ziphuft_free(CAB(fdi), tl);
1414 fdi_Ziphuft_free(CAB(fdi), td);
1415 return 0;
1418 /*****************************************************
1419 * fdi_Zipinflate_block (internal)
1421 static cab_LONG fdi_Zipinflate_block(cab_LONG *e, fdi_decomp_state *decomp_state) /* e == last block flag */
1422 { /* decompress an inflated block */
1423 cab_ULONG t; /* block type */
1424 register cab_ULONG b; /* bit buffer */
1425 register cab_ULONG k; /* number of bits in bit buffer */
1427 /* make local bit buffer */
1428 b = ZIP(bb);
1429 k = ZIP(bk);
1431 /* read in last block bit */
1432 ZIPNEEDBITS(1)
1433 *e = (cab_LONG)b & 1;
1434 ZIPDUMPBITS(1)
1436 /* read in block type */
1437 ZIPNEEDBITS(2)
1438 t = b & 3;
1439 ZIPDUMPBITS(2)
1441 /* restore the global bit buffer */
1442 ZIP(bb) = b;
1443 ZIP(bk) = k;
1445 /* inflate that block type */
1446 if(t == 2)
1447 return fdi_Zipinflate_dynamic(decomp_state);
1448 if(t == 0)
1449 return fdi_Zipinflate_stored(decomp_state);
1450 if(t == 1)
1451 return fdi_Zipinflate_fixed(decomp_state);
1452 /* bad block type */
1453 return 2;
1456 /****************************************************
1457 * ZIPfdi_decomp(internal)
1459 static int ZIPfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state)
1461 cab_LONG e; /* last block flag */
1463 TRACE("(inlen == %d, outlen == %d)\n", inlen, outlen);
1465 ZIP(inpos) = CAB(inbuf);
1466 ZIP(bb) = ZIP(bk) = ZIP(window_posn) = 0;
1467 if(outlen > ZIPWSIZE)
1468 return DECR_DATAFORMAT;
1470 /* CK = Chris Kirmse, official Microsoft purloiner */
1471 if(ZIP(inpos)[0] != 0x43 || ZIP(inpos)[1] != 0x4B)
1472 return DECR_ILLEGALDATA;
1473 ZIP(inpos) += 2;
1475 do {
1476 if(fdi_Zipinflate_block(&e, decomp_state))
1477 return DECR_ILLEGALDATA;
1478 } while(!e);
1480 /* return success */
1481 return DECR_OK;
1484 /*******************************************************************
1485 * QTMfdi_decomp(internal)
1487 static int QTMfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state)
1489 cab_UBYTE *inpos = CAB(inbuf);
1490 cab_UBYTE *window = QTM(window);
1491 cab_UBYTE *runsrc, *rundest;
1492 cab_ULONG window_posn = QTM(window_posn);
1493 cab_ULONG window_size = QTM(window_size);
1495 /* used by bitstream macros */
1496 register int bitsleft, bitrun, bitsneed;
1497 register cab_ULONG bitbuf;
1499 /* used by GET_SYMBOL */
1500 cab_ULONG range;
1501 cab_UWORD symf;
1502 int i;
1504 int extra, togo = outlen, match_length = 0, copy_length;
1505 cab_UBYTE selector, sym;
1506 cab_ULONG match_offset = 0;
1508 cab_UWORD H = 0xFFFF, L = 0, C;
1510 TRACE("(inlen == %d, outlen == %d)\n", inlen, outlen);
1512 /* read initial value of C */
1513 Q_INIT_BITSTREAM;
1514 Q_READ_BITS(C, 16);
1516 /* apply 2^x-1 mask */
1517 window_posn &= window_size - 1;
1518 /* runs can't straddle the window wraparound */
1519 if ((window_posn + togo) > window_size) {
1520 TRACE("straddled run\n");
1521 return DECR_DATAFORMAT;
1524 while (togo > 0) {
1525 GET_SYMBOL(model7, selector);
1526 switch (selector) {
1527 case 0:
1528 GET_SYMBOL(model00, sym); window[window_posn++] = sym; togo--;
1529 break;
1530 case 1:
1531 GET_SYMBOL(model40, sym); window[window_posn++] = sym; togo--;
1532 break;
1533 case 2:
1534 GET_SYMBOL(model80, sym); window[window_posn++] = sym; togo--;
1535 break;
1536 case 3:
1537 GET_SYMBOL(modelC0, sym); window[window_posn++] = sym; togo--;
1538 break;
1540 case 4:
1541 /* selector 4 = fixed length of 3 */
1542 GET_SYMBOL(model4, sym);
1543 Q_READ_BITS(extra, CAB(q_extra_bits)[sym]);
1544 match_offset = CAB(q_position_base)[sym] + extra + 1;
1545 match_length = 3;
1546 break;
1548 case 5:
1549 /* selector 5 = fixed length of 4 */
1550 GET_SYMBOL(model5, sym);
1551 Q_READ_BITS(extra, CAB(q_extra_bits)[sym]);
1552 match_offset = CAB(q_position_base)[sym] + extra + 1;
1553 match_length = 4;
1554 break;
1556 case 6:
1557 /* selector 6 = variable length */
1558 GET_SYMBOL(model6len, sym);
1559 Q_READ_BITS(extra, CAB(q_length_extra)[sym]);
1560 match_length = CAB(q_length_base)[sym] + extra + 5;
1561 GET_SYMBOL(model6pos, sym);
1562 Q_READ_BITS(extra, CAB(q_extra_bits)[sym]);
1563 match_offset = CAB(q_position_base)[sym] + extra + 1;
1564 break;
1566 default:
1567 TRACE("Selector is bogus\n");
1568 return DECR_ILLEGALDATA;
1571 /* if this is a match */
1572 if (selector >= 4) {
1573 rundest = window + window_posn;
1574 togo -= match_length;
1576 /* copy any wrapped around source data */
1577 if (window_posn >= match_offset) {
1578 /* no wrap */
1579 runsrc = rundest - match_offset;
1580 } else {
1581 runsrc = rundest + (window_size - match_offset);
1582 copy_length = match_offset - window_posn;
1583 if (copy_length < match_length) {
1584 match_length -= copy_length;
1585 window_posn += copy_length;
1586 while (copy_length-- > 0) *rundest++ = *runsrc++;
1587 runsrc = window;
1590 window_posn += match_length;
1592 /* copy match data - no worries about destination wraps */
1593 while (match_length-- > 0) *rundest++ = *runsrc++;
1595 } /* while (togo > 0) */
1597 if (togo != 0) {
1598 TRACE("Frame overflow, this_run = %d\n", togo);
1599 return DECR_ILLEGALDATA;
1602 memcpy(CAB(outbuf), window + ((!window_posn) ? window_size : window_posn) -
1603 outlen, outlen);
1605 QTM(window_posn) = window_posn;
1606 return DECR_OK;
1609 /************************************************************
1610 * fdi_lzx_read_lens (internal)
1612 static int fdi_lzx_read_lens(cab_UBYTE *lens, cab_ULONG first, cab_ULONG last, struct lzx_bits *lb,
1613 fdi_decomp_state *decomp_state) {
1614 cab_ULONG i,j, x,y;
1615 int z;
1617 register cab_ULONG bitbuf = lb->bb;
1618 register int bitsleft = lb->bl;
1619 cab_UBYTE *inpos = lb->ip;
1620 cab_UWORD *hufftbl;
1622 for (x = 0; x < 20; x++) {
1623 READ_BITS(y, 4);
1624 LENTABLE(PRETREE)[x] = y;
1626 BUILD_TABLE(PRETREE);
1628 for (x = first; x < last; ) {
1629 READ_HUFFSYM(PRETREE, z);
1630 if (z == 17) {
1631 READ_BITS(y, 4); y += 4;
1632 while (y--) lens[x++] = 0;
1634 else if (z == 18) {
1635 READ_BITS(y, 5); y += 20;
1636 while (y--) lens[x++] = 0;
1638 else if (z == 19) {
1639 READ_BITS(y, 1); y += 4;
1640 READ_HUFFSYM(PRETREE, z);
1641 z = lens[x] - z; if (z < 0) z += 17;
1642 while (y--) lens[x++] = z;
1644 else {
1645 z = lens[x] - z; if (z < 0) z += 17;
1646 lens[x++] = z;
1650 lb->bb = bitbuf;
1651 lb->bl = bitsleft;
1652 lb->ip = inpos;
1653 return 0;
1656 /*******************************************************
1657 * LZXfdi_decomp(internal)
1659 static int LZXfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state) {
1660 cab_UBYTE *inpos = CAB(inbuf);
1661 const cab_UBYTE *endinp = inpos + inlen;
1662 cab_UBYTE *window = LZX(window);
1663 cab_UBYTE *runsrc, *rundest;
1664 cab_UWORD *hufftbl; /* used in READ_HUFFSYM macro as chosen decoding table */
1666 cab_ULONG window_posn = LZX(window_posn);
1667 cab_ULONG window_size = LZX(window_size);
1668 cab_ULONG R0 = LZX(R0);
1669 cab_ULONG R1 = LZX(R1);
1670 cab_ULONG R2 = LZX(R2);
1672 register cab_ULONG bitbuf;
1673 register int bitsleft;
1674 cab_ULONG match_offset, i,j,k; /* ijk used in READ_HUFFSYM macro */
1675 struct lzx_bits lb; /* used in READ_LENGTHS macro */
1677 int togo = outlen, this_run, main_element, aligned_bits;
1678 int match_length, copy_length, length_footer, extra, verbatim_bits;
1680 TRACE("(inlen == %d, outlen == %d)\n", inlen, outlen);
1682 INIT_BITSTREAM;
1684 /* read header if necessary */
1685 if (!LZX(header_read)) {
1686 i = j = 0;
1687 READ_BITS(k, 1); if (k) { READ_BITS(i,16); READ_BITS(j,16); }
1688 LZX(intel_filesize) = (i << 16) | j; /* or 0 if not encoded */
1689 LZX(header_read) = 1;
1692 /* main decoding loop */
1693 while (togo > 0) {
1694 /* last block finished, new block expected */
1695 if (LZX(block_remaining) == 0) {
1696 if (LZX(block_type) == LZX_BLOCKTYPE_UNCOMPRESSED) {
1697 if (LZX(block_length) & 1) inpos++; /* realign bitstream to word */
1698 INIT_BITSTREAM;
1701 READ_BITS(LZX(block_type), 3);
1702 READ_BITS(i, 16);
1703 READ_BITS(j, 8);
1704 LZX(block_remaining) = LZX(block_length) = (i << 8) | j;
1706 switch (LZX(block_type)) {
1707 case LZX_BLOCKTYPE_ALIGNED:
1708 for (i = 0; i < 8; i++) { READ_BITS(j, 3); LENTABLE(ALIGNED)[i] = j; }
1709 BUILD_TABLE(ALIGNED);
1710 /* rest of aligned header is same as verbatim */
1712 case LZX_BLOCKTYPE_VERBATIM:
1713 READ_LENGTHS(MAINTREE, 0, 256, fdi_lzx_read_lens);
1714 READ_LENGTHS(MAINTREE, 256, LZX(main_elements), fdi_lzx_read_lens);
1715 BUILD_TABLE(MAINTREE);
1716 if (LENTABLE(MAINTREE)[0xE8] != 0) LZX(intel_started) = 1;
1718 READ_LENGTHS(LENGTH, 0, LZX_NUM_SECONDARY_LENGTHS, fdi_lzx_read_lens);
1719 BUILD_TABLE(LENGTH);
1720 break;
1722 case LZX_BLOCKTYPE_UNCOMPRESSED:
1723 LZX(intel_started) = 1; /* because we can't assume otherwise */
1724 ENSURE_BITS(16); /* get up to 16 pad bits into the buffer */
1725 if (bitsleft > 16) inpos -= 2; /* and align the bitstream! */
1726 R0 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
1727 R1 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
1728 R2 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
1729 break;
1731 default:
1732 return DECR_ILLEGALDATA;
1736 /* buffer exhaustion check */
1737 if (inpos > endinp) {
1738 /* it's possible to have a file where the next run is less than
1739 * 16 bits in size. In this case, the READ_HUFFSYM() macro used
1740 * in building the tables will exhaust the buffer, so we should
1741 * allow for this, but not allow those accidentally read bits to
1742 * be used (so we check that there are at least 16 bits
1743 * remaining - in this boundary case they aren't really part of
1744 * the compressed data)
1746 if (inpos > (endinp+2) || bitsleft < 16) return DECR_ILLEGALDATA;
1749 while ((this_run = LZX(block_remaining)) > 0 && togo > 0) {
1750 if (this_run > togo) this_run = togo;
1751 togo -= this_run;
1752 LZX(block_remaining) -= this_run;
1754 /* apply 2^x-1 mask */
1755 window_posn &= window_size - 1;
1756 /* runs can't straddle the window wraparound */
1757 if ((window_posn + this_run) > window_size)
1758 return DECR_DATAFORMAT;
1760 switch (LZX(block_type)) {
1762 case LZX_BLOCKTYPE_VERBATIM:
1763 while (this_run > 0) {
1764 READ_HUFFSYM(MAINTREE, main_element);
1766 if (main_element < LZX_NUM_CHARS) {
1767 /* literal: 0 to LZX_NUM_CHARS-1 */
1768 window[window_posn++] = main_element;
1769 this_run--;
1771 else {
1772 /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
1773 main_element -= LZX_NUM_CHARS;
1775 match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
1776 if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
1777 READ_HUFFSYM(LENGTH, length_footer);
1778 match_length += length_footer;
1780 match_length += LZX_MIN_MATCH;
1782 match_offset = main_element >> 3;
1784 if (match_offset > 2) {
1785 /* not repeated offset */
1786 if (match_offset != 3) {
1787 extra = CAB(extra_bits)[match_offset];
1788 READ_BITS(verbatim_bits, extra);
1789 match_offset = CAB(lzx_position_base)[match_offset]
1790 - 2 + verbatim_bits;
1792 else {
1793 match_offset = 1;
1796 /* update repeated offset LRU queue */
1797 R2 = R1; R1 = R0; R0 = match_offset;
1799 else if (match_offset == 0) {
1800 match_offset = R0;
1802 else if (match_offset == 1) {
1803 match_offset = R1;
1804 R1 = R0; R0 = match_offset;
1806 else /* match_offset == 2 */ {
1807 match_offset = R2;
1808 R2 = R0; R0 = match_offset;
1811 rundest = window + window_posn;
1812 this_run -= match_length;
1814 /* copy any wrapped around source data */
1815 if (window_posn >= match_offset) {
1816 /* no wrap */
1817 runsrc = rundest - match_offset;
1818 } else {
1819 runsrc = rundest + (window_size - match_offset);
1820 copy_length = match_offset - window_posn;
1821 if (copy_length < match_length) {
1822 match_length -= copy_length;
1823 window_posn += copy_length;
1824 while (copy_length-- > 0) *rundest++ = *runsrc++;
1825 runsrc = window;
1828 window_posn += match_length;
1830 /* copy match data - no worries about destination wraps */
1831 while (match_length-- > 0) *rundest++ = *runsrc++;
1834 break;
1836 case LZX_BLOCKTYPE_ALIGNED:
1837 while (this_run > 0) {
1838 READ_HUFFSYM(MAINTREE, main_element);
1840 if (main_element < LZX_NUM_CHARS) {
1841 /* literal: 0 to LZX_NUM_CHARS-1 */
1842 window[window_posn++] = main_element;
1843 this_run--;
1845 else {
1846 /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
1847 main_element -= LZX_NUM_CHARS;
1849 match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
1850 if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
1851 READ_HUFFSYM(LENGTH, length_footer);
1852 match_length += length_footer;
1854 match_length += LZX_MIN_MATCH;
1856 match_offset = main_element >> 3;
1858 if (match_offset > 2) {
1859 /* not repeated offset */
1860 extra = CAB(extra_bits)[match_offset];
1861 match_offset = CAB(lzx_position_base)[match_offset] - 2;
1862 if (extra > 3) {
1863 /* verbatim and aligned bits */
1864 extra -= 3;
1865 READ_BITS(verbatim_bits, extra);
1866 match_offset += (verbatim_bits << 3);
1867 READ_HUFFSYM(ALIGNED, aligned_bits);
1868 match_offset += aligned_bits;
1870 else if (extra == 3) {
1871 /* aligned bits only */
1872 READ_HUFFSYM(ALIGNED, aligned_bits);
1873 match_offset += aligned_bits;
1875 else if (extra > 0) { /* extra==1, extra==2 */
1876 /* verbatim bits only */
1877 READ_BITS(verbatim_bits, extra);
1878 match_offset += verbatim_bits;
1880 else /* extra == 0 */ {
1881 /* ??? */
1882 match_offset = 1;
1885 /* update repeated offset LRU queue */
1886 R2 = R1; R1 = R0; R0 = match_offset;
1888 else if (match_offset == 0) {
1889 match_offset = R0;
1891 else if (match_offset == 1) {
1892 match_offset = R1;
1893 R1 = R0; R0 = match_offset;
1895 else /* match_offset == 2 */ {
1896 match_offset = R2;
1897 R2 = R0; R0 = match_offset;
1900 rundest = window + window_posn;
1901 this_run -= match_length;
1903 /* copy any wrapped around source data */
1904 if (window_posn >= match_offset) {
1905 /* no wrap */
1906 runsrc = rundest - match_offset;
1907 } else {
1908 runsrc = rundest + (window_size - match_offset);
1909 copy_length = match_offset - window_posn;
1910 if (copy_length < match_length) {
1911 match_length -= copy_length;
1912 window_posn += copy_length;
1913 while (copy_length-- > 0) *rundest++ = *runsrc++;
1914 runsrc = window;
1917 window_posn += match_length;
1919 /* copy match data - no worries about destination wraps */
1920 while (match_length-- > 0) *rundest++ = *runsrc++;
1923 break;
1925 case LZX_BLOCKTYPE_UNCOMPRESSED:
1926 if ((inpos + this_run) > endinp) return DECR_ILLEGALDATA;
1927 memcpy(window + window_posn, inpos, (size_t) this_run);
1928 inpos += this_run; window_posn += this_run;
1929 break;
1931 default:
1932 return DECR_ILLEGALDATA; /* might as well */
1938 if (togo != 0) return DECR_ILLEGALDATA;
1939 memcpy(CAB(outbuf), window + ((!window_posn) ? window_size : window_posn) -
1940 outlen, (size_t) outlen);
1942 LZX(window_posn) = window_posn;
1943 LZX(R0) = R0;
1944 LZX(R1) = R1;
1945 LZX(R2) = R2;
1947 /* intel E8 decoding */
1948 if ((LZX(frames_read)++ < 32768) && LZX(intel_filesize) != 0) {
1949 if (outlen <= 6 || !LZX(intel_started)) {
1950 LZX(intel_curpos) += outlen;
1952 else {
1953 cab_UBYTE *data = CAB(outbuf);
1954 cab_UBYTE *dataend = data + outlen - 10;
1955 cab_LONG curpos = LZX(intel_curpos);
1956 cab_LONG filesize = LZX(intel_filesize);
1957 cab_LONG abs_off, rel_off;
1959 LZX(intel_curpos) = curpos + outlen;
1961 while (data < dataend) {
1962 if (*data++ != 0xE8) { curpos++; continue; }
1963 abs_off = data[0] | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);
1964 if ((abs_off >= -curpos) && (abs_off < filesize)) {
1965 rel_off = (abs_off >= 0) ? abs_off - curpos : abs_off + filesize;
1966 data[0] = (cab_UBYTE) rel_off;
1967 data[1] = (cab_UBYTE) (rel_off >> 8);
1968 data[2] = (cab_UBYTE) (rel_off >> 16);
1969 data[3] = (cab_UBYTE) (rel_off >> 24);
1971 data += 4;
1972 curpos += 5;
1976 return DECR_OK;
1979 /**********************************************************
1980 * fdi_decomp (internal)
1982 * Decompress the requested number of bytes. If savemode is zero,
1983 * do not save the output anywhere, just plow through blocks until we
1984 * reach the specified (uncompressed) distance from the starting point,
1985 * and remember the position of the cabfile pointer (and which cabfile)
1986 * after we are done; otherwise, save the data out to CAB(filehf),
1987 * decompressing the requested number of bytes and writing them out. This
1988 * is also where we jump to additional cabinets in the case of split
1989 * cab's, and provide (some of) the NEXT_CABINET notification semantics.
1991 static int fdi_decomp(const struct fdi_file *fi, int savemode, fdi_decomp_state *decomp_state,
1992 char *pszCabPath, PFNFDINOTIFY pfnfdin, void *pvUser)
1994 cab_ULONG bytes = savemode ? fi->length : fi->offset - CAB(offset);
1995 cab_UBYTE buf[cfdata_SIZEOF], *data;
1996 cab_UWORD inlen, len, outlen, cando;
1997 cab_ULONG cksum;
1998 cab_LONG err;
1999 fdi_decomp_state *cab = (savemode && CAB(decomp_cab)) ? CAB(decomp_cab) : decomp_state;
2001 TRACE("(fi == ^%p, savemode == %d, bytes == %d)\n", fi, savemode, bytes);
2003 while (bytes > 0) {
2004 /* cando = the max number of bytes we can do */
2005 cando = CAB(outlen);
2006 if (cando > bytes) cando = bytes;
2008 /* if cando != 0 */
2009 if (cando && savemode)
2010 CAB(fdi)->write(CAB(filehf), CAB(outpos), cando);
2012 CAB(outpos) += cando;
2013 CAB(outlen) -= cando;
2014 bytes -= cando; if (!bytes) break;
2016 /* we only get here if we emptied the output buffer */
2018 /* read data header + data */
2019 inlen = outlen = 0;
2020 while (outlen == 0) {
2021 /* read the block header, skip the reserved part */
2022 if (CAB(fdi)->read(cab->cabhf, buf, cfdata_SIZEOF) != cfdata_SIZEOF)
2023 return DECR_INPUT;
2025 if (CAB(fdi)->seek(cab->cabhf, cab->mii.block_resv, SEEK_CUR) == -1)
2026 return DECR_INPUT;
2028 /* we shouldn't get blocks over CAB_INPUTMAX in size */
2029 data = CAB(inbuf) + inlen;
2030 len = EndGetI16(buf+cfdata_CompressedSize);
2031 inlen += len;
2032 if (inlen > CAB_INPUTMAX) return DECR_INPUT;
2033 if (CAB(fdi)->read(cab->cabhf, data, len) != len)
2034 return DECR_INPUT;
2036 /* clear two bytes after read-in data */
2037 data[len+1] = data[len+2] = 0;
2039 /* perform checksum test on the block (if one is stored) */
2040 cksum = EndGetI32(buf+cfdata_CheckSum);
2041 if (cksum && cksum != checksum(buf+4, 4, checksum(data, len, 0)))
2042 return DECR_CHECKSUM; /* checksum is wrong */
2044 outlen = EndGetI16(buf+cfdata_UncompressedSize);
2046 /* outlen=0 means this block was the last contiguous part
2047 of a split block, continued in the next cabinet */
2048 if (outlen == 0) {
2049 int pathlen, filenamelen, idx, i;
2050 INT_PTR cabhf;
2051 char fullpath[MAX_PATH], userpath[256];
2052 FDINOTIFICATION fdin;
2053 FDICABINETINFO fdici;
2054 char emptystring = '\0';
2055 cab_UBYTE buf2[64];
2056 int success = FALSE;
2057 struct fdi_folder *fol = NULL, *linkfol = NULL;
2058 struct fdi_file *file = NULL, *linkfile = NULL;
2060 tryanothercab:
2062 /* set up the next decomp_state... */
2063 if (!(cab->next)) {
2064 if (!cab->mii.hasnext) return DECR_INPUT;
2066 if (!((cab->next = CAB(fdi)->alloc(sizeof(fdi_decomp_state)))))
2067 return DECR_NOMEMORY;
2069 ZeroMemory(cab->next, sizeof(fdi_decomp_state));
2071 /* copy pszCabPath to userpath */
2072 ZeroMemory(userpath, 256);
2073 pathlen = (pszCabPath) ? strlen(pszCabPath) : 0;
2074 if (pathlen) {
2075 if (pathlen < 256) {
2076 for (i = 0; i <= pathlen; i++)
2077 userpath[i] = pszCabPath[i];
2078 } /* else we are in a weird place... let's leave it blank and see if the user fixes it */
2081 /* initial fdintNEXT_CABINET notification */
2082 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2083 fdin.psz1 = (cab->mii.nextname) ? cab->mii.nextname : &emptystring;
2084 fdin.psz2 = (cab->mii.nextinfo) ? cab->mii.nextinfo : &emptystring;
2085 fdin.psz3 = &userpath[0];
2086 fdin.fdie = FDIERROR_NONE;
2087 fdin.pv = pvUser;
2089 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2091 do {
2093 pathlen = strlen(userpath);
2094 filenamelen = (cab->mii.nextname) ? strlen(cab->mii.nextname) : 0;
2096 /* slight overestimation here to save CPU cycles in the developer's brain */
2097 if ((pathlen + filenamelen + 3) > MAX_PATH) {
2098 ERR("MAX_PATH exceeded.\n");
2099 return DECR_ILLEGALDATA;
2102 /* paste the path and filename together */
2103 idx = 0;
2104 if (pathlen) {
2105 for (i = 0; i < pathlen; i++) fullpath[idx++] = userpath[i];
2106 if (fullpath[idx - 1] != '\\') fullpath[idx++] = '\\';
2108 if (filenamelen) for (i = 0; i < filenamelen; i++) fullpath[idx++] = cab->mii.nextname[i];
2109 fullpath[idx] = '\0';
2111 TRACE("full cab path/file name: %s\n", debugstr_a(fullpath));
2113 /* try to get a handle to the cabfile */
2114 cabhf = CAB(fdi)->open(fullpath, _O_RDONLY|_O_BINARY, _S_IREAD | _S_IWRITE);
2115 if (cabhf == -1) {
2116 /* no file. allow the user to try again */
2117 fdin.fdie = FDIERROR_CABINET_NOT_FOUND;
2118 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2119 continue;
2122 if (cabhf == 0) {
2123 ERR("PFDI_OPEN returned zero for %s.\n", fullpath);
2124 fdin.fdie = FDIERROR_CABINET_NOT_FOUND;
2125 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2126 continue;
2129 /* check if it's really a cabfile. Note that this doesn't implement the bug */
2130 if (!FDI_read_entries(CAB(fdi), cabhf, &fdici, &(cab->next->mii))) {
2131 WARN("FDIIsCabinet failed.\n");
2132 CAB(fdi)->close(cabhf);
2133 fdin.fdie = FDIERROR_NOT_A_CABINET;
2134 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2135 continue;
2138 if ((fdici.setID != cab->setID) || (fdici.iCabinet != (cab->iCabinet + 1))) {
2139 WARN("Wrong Cabinet.\n");
2140 CAB(fdi)->close(cabhf);
2141 fdin.fdie = FDIERROR_WRONG_CABINET;
2142 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2143 continue;
2146 break;
2148 } while (1);
2150 /* cabinet notification */
2151 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2152 fdin.setID = fdici.setID;
2153 fdin.iCabinet = fdici.iCabinet;
2154 fdin.pv = pvUser;
2155 fdin.psz1 = (cab->next->mii.nextname) ? cab->next->mii.nextname : &emptystring;
2156 fdin.psz2 = (cab->next->mii.nextinfo) ? cab->next->mii.nextinfo : &emptystring;
2157 fdin.psz3 = pszCabPath;
2159 if (((*pfnfdin)(fdintCABINET_INFO, &fdin))) return DECR_USERABORT;
2161 cab->next->setID = fdici.setID;
2162 cab->next->iCabinet = fdici.iCabinet;
2163 cab->next->fdi = CAB(fdi);
2164 cab->next->filehf = CAB(filehf);
2165 cab->next->cabhf = cabhf;
2166 cab->next->decompress = CAB(decompress); /* crude, but unused anyhow */
2168 cab = cab->next; /* advance to the next cabinet */
2170 /* read folders */
2171 for (i = 0; i < fdici.cFolders; i++) {
2172 if (CAB(fdi)->read(cab->cabhf, buf2, cffold_SIZEOF) != cffold_SIZEOF)
2173 return DECR_INPUT;
2175 if (cab->mii.folder_resv > 0)
2176 CAB(fdi)->seek(cab->cabhf, cab->mii.folder_resv, SEEK_CUR);
2178 fol = CAB(fdi)->alloc(sizeof(struct fdi_folder));
2179 if (!fol) {
2180 ERR("out of memory!\n");
2181 return DECR_NOMEMORY;
2183 ZeroMemory(fol, sizeof(struct fdi_folder));
2184 if (!(cab->firstfol)) cab->firstfol = fol;
2186 fol->offset = (cab_off_t) EndGetI32(buf2+cffold_DataOffset);
2187 fol->num_blocks = EndGetI16(buf2+cffold_NumBlocks);
2188 fol->comp_type = EndGetI16(buf2+cffold_CompType);
2190 if (linkfol)
2191 linkfol->next = fol;
2192 linkfol = fol;
2195 /* read files */
2196 for (i = 0; i < fdici.cFiles; i++) {
2197 if (CAB(fdi)->read(cab->cabhf, buf2, cffile_SIZEOF) != cffile_SIZEOF)
2198 return DECR_INPUT;
2200 file = CAB(fdi)->alloc(sizeof(struct fdi_file));
2201 if (!file) {
2202 ERR("out of memory!\n");
2203 return DECR_NOMEMORY;
2205 ZeroMemory(file, sizeof(struct fdi_file));
2206 if (!(cab->firstfile)) cab->firstfile = file;
2208 file->length = EndGetI32(buf2+cffile_UncompressedSize);
2209 file->offset = EndGetI32(buf2+cffile_FolderOffset);
2210 file->index = EndGetI16(buf2+cffile_FolderIndex);
2211 file->time = EndGetI16(buf2+cffile_Time);
2212 file->date = EndGetI16(buf2+cffile_Date);
2213 file->attribs = EndGetI16(buf2+cffile_Attribs);
2214 file->filename = FDI_read_string(CAB(fdi), cab->cabhf, fdici.cbCabinet);
2216 if (!file->filename) return DECR_INPUT;
2218 if (linkfile)
2219 linkfile->next = file;
2220 linkfile = file;
2223 } else
2224 cab = cab->next; /* advance to the next cabinet */
2226 /* iterate files -- if we encounter the continued file, process it --
2227 otherwise, jump to the label above and keep looking */
2229 for (file = cab->firstfile; (file); file = file->next) {
2230 if ((file->index & cffileCONTINUED_FROM_PREV) == cffileCONTINUED_FROM_PREV) {
2231 /* check to ensure a real match */
2232 if (lstrcmpiA(fi->filename, file->filename) == 0) {
2233 success = TRUE;
2234 if (CAB(fdi)->seek(cab->cabhf, cab->firstfol->offset, SEEK_SET) == -1)
2235 return DECR_INPUT;
2236 break;
2240 if (!success) goto tryanothercab; /* FIXME: shouldn't this trigger
2241 "Wrong Cabinet" notification? */
2245 /* decompress block */
2246 if ((err = CAB(decompress)(inlen, outlen, decomp_state)))
2247 return err;
2248 CAB(outlen) = outlen;
2249 CAB(outpos) = CAB(outbuf);
2252 CAB(decomp_cab) = cab;
2253 return DECR_OK;
2256 static void free_decompression_temps(FDI_Int *fdi, const struct fdi_folder *fol,
2257 fdi_decomp_state *decomp_state)
2259 switch (fol->comp_type & cffoldCOMPTYPE_MASK) {
2260 case cffoldCOMPTYPE_LZX:
2261 if (LZX(window)) {
2262 fdi->free(LZX(window));
2263 LZX(window) = NULL;
2265 break;
2266 case cffoldCOMPTYPE_QUANTUM:
2267 if (QTM(window)) {
2268 fdi->free(QTM(window));
2269 QTM(window) = NULL;
2271 break;
2275 static void free_decompression_mem(FDI_Int *fdi, fdi_decomp_state *decomp_state)
2277 struct fdi_folder *fol;
2278 while (decomp_state) {
2279 fdi_decomp_state *prev_fds;
2281 fdi->close(CAB(cabhf));
2283 /* free the storage remembered by mii */
2284 if (CAB(mii).nextname) fdi->free(CAB(mii).nextname);
2285 if (CAB(mii).nextinfo) fdi->free(CAB(mii).nextinfo);
2286 if (CAB(mii).prevname) fdi->free(CAB(mii).prevname);
2287 if (CAB(mii).previnfo) fdi->free(CAB(mii).previnfo);
2289 while (CAB(firstfol)) {
2290 fol = CAB(firstfol);
2291 CAB(firstfol) = CAB(firstfol)->next;
2292 fdi->free(fol);
2294 while (CAB(firstfile)) {
2295 struct fdi_file *file = CAB(firstfile);
2296 if (file->filename) fdi->free(file->filename);
2297 CAB(firstfile) = CAB(firstfile)->next;
2298 fdi->free(file);
2300 prev_fds = decomp_state;
2301 decomp_state = CAB(next);
2302 fdi->free(prev_fds);
2306 /***********************************************************************
2307 * FDICopy (CABINET.22)
2309 * Iterates through the files in the Cabinet file indicated by name and
2310 * file-location. May chain forward to additional cabinets (typically
2311 * only one) if files which begin in this Cabinet are continued in another
2312 * cabinet. For each file which is partially contained in this cabinet,
2313 * and partially contained in a prior cabinet, provides fdintPARTIAL_FILE
2314 * notification to the pfnfdin callback. For each file which begins in
2315 * this cabinet, fdintCOPY_FILE notification is provided to the pfnfdin
2316 * callback, and the file is optionally decompressed and saved to disk.
2317 * Notification is not provided for files which are not at least partially
2318 * contained in the specified cabinet file.
2320 * See below for a thorough explanation of the various notification
2321 * callbacks.
2323 * PARAMS
2324 * hfdi [I] An HFDI from FDICreate
2325 * pszCabinet [I] C-style string containing the filename of the cabinet
2326 * pszCabPath [I] C-style string containing the file path of the cabinet
2327 * flags [I] "Decoder parameters". Ignored. Suggested value: 0.
2328 * pfnfdin [I] Pointer to a notification function. See CALLBACKS below.
2329 * pfnfdid [I] Pointer to a decryption function. Ignored. Suggested
2330 * value: NULL.
2331 * pvUser [I] arbitrary void * value which is passed to callbacks.
2333 * RETURNS
2334 * TRUE if successful.
2335 * FALSE if unsuccessful (error information is provided in the ERF structure
2336 * associated with the provided decompression handle by FDICreate).
2338 * CALLBACKS
2340 * Two pointers to callback functions are provided as parameters to FDICopy:
2341 * pfnfdin(of type PFNFDINOTIFY), and pfnfdid (of type PFNFDIDECRYPT). These
2342 * types are as follows:
2344 * typedef INT_PTR (__cdecl *PFNFDINOTIFY) ( FDINOTIFICATIONTYPE fdint,
2345 * PFDINOTIFICATION pfdin );
2347 * typedef int (__cdecl *PFNFDIDECRYPT) ( PFDIDECRYPT pfdid );
2349 * You can create functions of this type using the FNFDINOTIFY() and
2350 * FNFDIDECRYPT() macros, respectively. For example:
2352 * FNFDINOTIFY(mycallback) {
2353 * / * use variables fdint and pfdin to process notification * /
2356 * The second callback, which could be used for decrypting encrypted data,
2357 * is not used at all.
2359 * Each notification informs the user of some event which has occurred during
2360 * decompression of the cabinet file; each notification is also an opportunity
2361 * for the callee to abort decompression. The information provided to the
2362 * callback and the meaning of the callback's return value vary drastically
2363 * across the various types of notification. The type of notification is the
2364 * fdint parameter; all other information is provided to the callback in
2365 * notification-specific parts of the FDINOTIFICATION structure pointed to by
2366 * pfdin. The only part of that structure which is assigned for every callback
2367 * is the pv element, which contains the arbitrary value which was passed to
2368 * FDICopy in the pvUser argument (psz1 is also used each time, but its meaning
2369 * is highly dependent on fdint).
2371 * If you encounter unknown notifications, you should return zero if you want
2372 * decompression to continue (or -1 to abort). All strings used in the
2373 * callbacks are regular C-style strings. Detailed descriptions of each
2374 * notification type follow:
2376 * fdintCABINET_INFO:
2378 * This is the first notification provided after calling FDICopy, and provides
2379 * the user with various information about the cabinet. Note that this is
2380 * called for each cabinet FDICopy opens, not just the first one. In the
2381 * structure pointed to by pfdin, psz1 contains a pointer to the name of the
2382 * next cabinet file in the set after the one just loaded (if any), psz2
2383 * contains a pointer to the name or "info" of the next disk, psz3
2384 * contains a pointer to the file-path of the current cabinet, setID
2385 * contains an arbitrary constant associated with this set of cabinet files,
2386 * and iCabinet contains the numerical index of the current cabinet within
2387 * that set. Return zero, or -1 to abort.
2389 * fdintPARTIAL_FILE:
2391 * This notification is provided when FDICopy encounters a part of a file
2392 * contained in this cabinet which is missing its beginning. Files can be
2393 * split across cabinets, so this is not necessarily an abnormality; it just
2394 * means that the file in question begins in another cabinet. No file
2395 * corresponding to this notification is extracted from the cabinet. In the
2396 * structure pointed to by pfdin, psz1 contains a pointer to the name of the
2397 * partial file, psz2 contains a pointer to the file name of the cabinet in
2398 * which this file begins, and psz3 contains a pointer to the disk name or
2399 * "info" of the cabinet where the file begins. Return zero, or -1 to abort.
2401 * fdintCOPY_FILE:
2403 * This notification is provided when FDICopy encounters a file which starts
2404 * in the cabinet file, provided to FDICopy in pszCabinet. (FDICopy will not
2405 * look for files in cabinets after the first one). One notification will be
2406 * sent for each such file, before the file is decompressed. By returning
2407 * zero, the callback can instruct FDICopy to skip the file. In the structure
2408 * pointed to by pfdin, psz1 contains a pointer to the file's name, cb contains
2409 * the size of the file (uncompressed), attribs contains the file attributes,
2410 * and date and time contain the date and time of the file. attributes, date,
2411 * and time are of the 16-bit ms-dos variety. Return -1 to abort decompression
2412 * for the entire cabinet, 0 to skip just this file but continue scanning the
2413 * cabinet for more files, or an FDIClose()-compatible file-handle.
2415 * fdintCLOSE_FILE_INFO:
2417 * This notification is important, don't forget to implement it. This
2418 * notification indicates that a file has been successfully uncompressed and
2419 * written to disk. Upon receipt of this notification, the callee is expected
2420 * to close the file handle, to set the attributes and date/time of the
2421 * closed file, and possibly to execute the file. In the structure pointed to
2422 * by pfdin, psz1 contains a pointer to the name of the file, hf will be the
2423 * open file handle (close it), cb contains 1 or zero, indicating respectively
2424 * that the callee should or should not execute the file, and date, time
2425 * and attributes will be set as in fdintCOPY_FILE. Bizarrely, the Cabinet SDK
2426 * specifies that _A_EXEC will be xor'ed out of attributes! wine does not do
2427 * do so. Return TRUE, or FALSE to abort decompression.
2429 * fdintNEXT_CABINET:
2431 * This notification is called when FDICopy must load in another cabinet. This
2432 * can occur when a file's data is "split" across multiple cabinets. The
2433 * callee has the opportunity to request that FDICopy look in a different file
2434 * path for the specified cabinet file, by writing that data into a provided
2435 * buffer (see below for more information). This notification will be received
2436 * more than once per-cabinet in the instance that FDICopy failed to find a
2437 * valid cabinet at the location specified by the first per-cabinet
2438 * fdintNEXT_CABINET notification. In such instances, the fdie element of the
2439 * structure pointed to by pfdin indicates the error which prevented FDICopy
2440 * from proceeding successfully. Return zero to indicate success, or -1 to
2441 * indicate failure and abort FDICopy.
2443 * Upon receipt of this notification, the structure pointed to by pfdin will
2444 * contain the following values: psz1 pointing to the name of the cabinet
2445 * which FDICopy is attempting to open, psz2 pointing to the name ("info") of
2446 * the next disk, psz3 pointing to the presumed file-location of the cabinet,
2447 * and fdie containing either FDIERROR_NONE, or one of the following:
2449 * FDIERROR_CABINET_NOT_FOUND, FDIERROR_NOT_A_CABINET,
2450 * FDIERROR_UNKNOWN_CABINET_VERSION, FDIERROR_CORRUPT_CABINET,
2451 * FDIERROR_BAD_COMPR_TYPE, FDIERROR_RESERVE_MISMATCH, and
2452 * FDIERROR_WRONG_CABINET.
2454 * The callee may choose to change the path where FDICopy will look for the
2455 * cabinet after this notification. To do so, the caller may write the new
2456 * pathname to the buffer pointed to by psz3, which is 256 characters in
2457 * length, including the terminating null character, before returning zero.
2459 * fdintENUMERATE:
2461 * Undocumented and unimplemented in wine, this seems to be sent each time
2462 * a cabinet is opened, along with the fdintCABINET_INFO notification. It
2463 * probably has an interface similar to that of fdintCABINET_INFO; maybe this
2464 * provides information about the current cabinet instead of the next one....
2465 * this is just a guess, it has not been looked at closely.
2467 * INCLUDES
2468 * fdi.c
2470 BOOL __cdecl FDICopy(
2471 HFDI hfdi,
2472 char *pszCabinet,
2473 char *pszCabPath,
2474 int flags,
2475 PFNFDINOTIFY pfnfdin,
2476 PFNFDIDECRYPT pfnfdid,
2477 void *pvUser)
2479 FDICABINETINFO fdici;
2480 FDINOTIFICATION fdin;
2481 INT_PTR cabhf, filehf = 0;
2482 int idx;
2483 unsigned int i;
2484 char fullpath[MAX_PATH];
2485 size_t pathlen, filenamelen;
2486 char emptystring = '\0';
2487 cab_UBYTE buf[64];
2488 struct fdi_folder *fol = NULL, *linkfol = NULL;
2489 struct fdi_file *file = NULL, *linkfile = NULL;
2490 fdi_decomp_state *decomp_state;
2491 FDI_Int *fdi = get_fdi_ptr( hfdi );
2493 TRACE("(hfdi == ^%p, pszCabinet == ^%p, pszCabPath == ^%p, flags == %0d, "
2494 "pfnfdin == ^%p, pfnfdid == ^%p, pvUser == ^%p)\n",
2495 hfdi, pszCabinet, pszCabPath, flags, pfnfdin, pfnfdid, pvUser);
2497 if (!fdi) return FALSE;
2499 if (!(decomp_state = fdi->alloc(sizeof(fdi_decomp_state))))
2501 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2502 return FALSE;
2504 ZeroMemory(decomp_state, sizeof(fdi_decomp_state));
2506 pathlen = (pszCabPath) ? strlen(pszCabPath) : 0;
2507 filenamelen = (pszCabinet) ? strlen(pszCabinet) : 0;
2509 /* slight overestimation here to save CPU cycles in the developer's brain */
2510 if ((pathlen + filenamelen + 3) > MAX_PATH) {
2511 ERR("MAX_PATH exceeded.\n");
2512 fdi->free(decomp_state);
2513 set_error( fdi, FDIERROR_CABINET_NOT_FOUND, ERROR_FILE_NOT_FOUND );
2514 return FALSE;
2517 /* paste the path and filename together */
2518 idx = 0;
2519 if (pathlen) {
2520 for (i = 0; i < pathlen; i++) fullpath[idx++] = pszCabPath[i];
2522 if (filenamelen) for (i = 0; i < filenamelen; i++) fullpath[idx++] = pszCabinet[i];
2523 fullpath[idx] = '\0';
2525 TRACE("full cab path/file name: %s\n", debugstr_a(fullpath));
2527 /* get a handle to the cabfile */
2528 cabhf = fdi->open(fullpath, _O_RDONLY|_O_BINARY, _S_IREAD | _S_IWRITE);
2529 if (cabhf == -1) {
2530 fdi->free(decomp_state);
2531 set_error( fdi, FDIERROR_CABINET_NOT_FOUND, 0 );
2532 SetLastError(ERROR_FILE_NOT_FOUND);
2533 return FALSE;
2536 /* check if it's really a cabfile. Note that this doesn't implement the bug */
2537 if (!FDI_read_entries(fdi, cabhf, &fdici, &(CAB(mii)))) {
2538 ERR("FDIIsCabinet failed: %u.\n", fdi->perf->erfOper);
2539 fdi->free(decomp_state);
2540 fdi->close(cabhf);
2541 return FALSE;
2544 /* cabinet notification */
2545 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2546 fdin.setID = fdici.setID;
2547 fdin.iCabinet = fdici.iCabinet;
2548 fdin.pv = pvUser;
2549 fdin.psz1 = (CAB(mii).nextname) ? CAB(mii).nextname : &emptystring;
2550 fdin.psz2 = (CAB(mii).nextinfo) ? CAB(mii).nextinfo : &emptystring;
2551 fdin.psz3 = pszCabPath;
2553 if (((*pfnfdin)(fdintCABINET_INFO, &fdin))) {
2554 set_error( fdi, FDIERROR_USER_ABORT, 0 );
2555 goto bail_and_fail;
2558 CAB(setID) = fdici.setID;
2559 CAB(iCabinet) = fdici.iCabinet;
2560 CAB(cabhf) = cabhf;
2562 /* read folders */
2563 for (i = 0; i < fdici.cFolders; i++) {
2564 if (fdi->read(cabhf, buf, cffold_SIZEOF) != cffold_SIZEOF) {
2565 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
2566 goto bail_and_fail;
2569 if (CAB(mii).folder_resv > 0)
2570 fdi->seek(cabhf, CAB(mii).folder_resv, SEEK_CUR);
2572 fol = fdi->alloc(sizeof(struct fdi_folder));
2573 if (!fol) {
2574 ERR("out of memory!\n");
2575 set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY );
2576 goto bail_and_fail;
2578 ZeroMemory(fol, sizeof(struct fdi_folder));
2579 if (!CAB(firstfol)) CAB(firstfol) = fol;
2581 fol->offset = (cab_off_t) EndGetI32(buf+cffold_DataOffset);
2582 fol->num_blocks = EndGetI16(buf+cffold_NumBlocks);
2583 fol->comp_type = EndGetI16(buf+cffold_CompType);
2585 if (linkfol)
2586 linkfol->next = fol;
2587 linkfol = fol;
2590 /* read files */
2591 for (i = 0; i < fdici.cFiles; i++) {
2592 if (fdi->read(cabhf, buf, cffile_SIZEOF) != cffile_SIZEOF) {
2593 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
2594 goto bail_and_fail;
2597 file = fdi->alloc(sizeof(struct fdi_file));
2598 if (!file) {
2599 ERR("out of memory!\n");
2600 set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY );
2601 goto bail_and_fail;
2603 ZeroMemory(file, sizeof(struct fdi_file));
2604 if (!CAB(firstfile)) CAB(firstfile) = file;
2606 file->length = EndGetI32(buf+cffile_UncompressedSize);
2607 file->offset = EndGetI32(buf+cffile_FolderOffset);
2608 file->index = EndGetI16(buf+cffile_FolderIndex);
2609 file->time = EndGetI16(buf+cffile_Time);
2610 file->date = EndGetI16(buf+cffile_Date);
2611 file->attribs = EndGetI16(buf+cffile_Attribs);
2612 file->filename = FDI_read_string(fdi, cabhf, fdici.cbCabinet);
2614 if (!file->filename) {
2615 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
2616 goto bail_and_fail;
2619 if (linkfile)
2620 linkfile->next = file;
2621 linkfile = file;
2624 for (file = CAB(firstfile); (file); file = file->next) {
2627 * FIXME: This implementation keeps multiple cabinet files open at once
2628 * when encountering a split cabinet. It is a quirk of this implementation
2629 * that sometimes we decrypt the same block of data more than once, to find
2630 * the right starting point for a file, moving the file-pointer backwards.
2631 * If we kept a cache of certain file-pointer information, we could eliminate
2632 * that behavior... in fact I am not sure that the caching we already have
2633 * is not sufficient.
2635 * The current implementation seems to work fine in straightforward situations
2636 * where all the cabinet files needed for decryption are simultaneously
2637 * available. But presumably, the API is supposed to support cabinets which
2638 * are split across multiple CDROMS; we may need to change our implementation
2639 * to strictly serialize it's file usage so that it opens only one cabinet
2640 * at a time. Some experimentation with Windows is needed to figure out the
2641 * precise semantics required. The relevant code is here and in fdi_decomp().
2644 /* partial-file notification */
2645 if ((file->index & cffileCONTINUED_FROM_PREV) == cffileCONTINUED_FROM_PREV) {
2647 * FIXME: Need to create a Cabinet with a single file spanning multiple files
2648 * and perform some tests to figure out the right behavior. The SDK says
2649 * FDICopy will notify the user of the filename and "disk name" (info) of
2650 * the cabinet where the spanning file /started/.
2652 * That would certainly be convenient for the API-user, who could abort,
2653 * everything (or parallelize, if that's allowed (it is in wine)), and call
2654 * FDICopy again with the provided filename, so as to avoid partial file
2655 * notification and successfully unpack. This task could be quite unpleasant
2656 * from wine's perspective: the information specifying the "start cabinet" for
2657 * a file is associated nowhere with the file header and is not to be found in
2658 * the cabinet header. We have only the index of the cabinet wherein the folder
2659 * begins, which contains the file. To find that cabinet, we must consider the
2660 * index of the current cabinet, and chain backwards, cabinet-by-cabinet (for
2661 * each cabinet refers to its "next" and "previous" cabinet only, like a linked
2662 * list).
2664 * Bear in mind that, in the spirit of CABINET.DLL, we must assume that any
2665 * cabinet other than the active one might be at another filepath than the
2666 * current one, or on another CDROM. This could get rather dicey, especially
2667 * if we imagine parallelized access to the FDICopy API.
2669 * The current implementation punts -- it just returns the previous cabinet and
2670 * it's info from the header of this cabinet. This provides the right answer in
2671 * 95% of the cases; its worth checking if Microsoft cuts the same corner before
2672 * we "fix" it.
2674 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2675 fdin.pv = pvUser;
2676 fdin.psz1 = (char *)file->filename;
2677 fdin.psz2 = (CAB(mii).prevname) ? CAB(mii).prevname : &emptystring;
2678 fdin.psz3 = (CAB(mii).previnfo) ? CAB(mii).previnfo : &emptystring;
2680 if (((*pfnfdin)(fdintPARTIAL_FILE, &fdin))) {
2681 set_error( fdi, FDIERROR_USER_ABORT, 0 );
2682 goto bail_and_fail;
2684 /* I don't think we are supposed to decompress partial files. This prevents it. */
2685 file->oppressed = TRUE;
2687 if (file->oppressed) {
2688 filehf = 0;
2689 } else {
2690 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2691 fdin.pv = pvUser;
2692 fdin.psz1 = (char *)file->filename;
2693 fdin.cb = file->length;
2694 fdin.date = file->date;
2695 fdin.time = file->time;
2696 fdin.attribs = file->attribs;
2697 if ((filehf = ((*pfnfdin)(fdintCOPY_FILE, &fdin))) == -1) {
2698 set_error( fdi, FDIERROR_USER_ABORT, 0 );
2699 filehf = 0;
2700 goto bail_and_fail;
2704 /* find the folder for this file if necc. */
2705 if (filehf) {
2706 int i2;
2708 fol = CAB(firstfol);
2709 if ((file->index & cffileCONTINUED_TO_NEXT) == cffileCONTINUED_TO_NEXT) {
2710 /* pick the last folder */
2711 while (fol->next) fol = fol->next;
2712 } else {
2713 for (i2 = 0; (i2 < file->index); i2++)
2714 if (fol->next) /* bug resistance, should always be true */
2715 fol = fol->next;
2719 if (filehf) {
2720 cab_UWORD comptype = fol->comp_type;
2721 int ct1 = comptype & cffoldCOMPTYPE_MASK;
2722 int ct2 = CAB(current) ? (CAB(current)->comp_type & cffoldCOMPTYPE_MASK) : 0;
2723 int err = 0;
2725 TRACE("Extracting file %s as requested by callee.\n", debugstr_a(file->filename));
2727 /* set up decomp_state */
2728 CAB(fdi) = fdi;
2729 CAB(filehf) = filehf;
2731 /* Was there a change of folder? Compression type? Did we somehow go backwards? */
2732 if ((ct1 != ct2) || (CAB(current) != fol) || (file->offset < CAB(offset))) {
2734 TRACE("Resetting folder for file %s.\n", debugstr_a(file->filename));
2736 /* free stuff for the old decompressor */
2737 switch (ct2) {
2738 case cffoldCOMPTYPE_LZX:
2739 if (LZX(window)) {
2740 fdi->free(LZX(window));
2741 LZX(window) = NULL;
2743 break;
2744 case cffoldCOMPTYPE_QUANTUM:
2745 if (QTM(window)) {
2746 fdi->free(QTM(window));
2747 QTM(window) = NULL;
2749 break;
2752 CAB(decomp_cab) = NULL;
2753 CAB(fdi)->seek(CAB(cabhf), fol->offset, SEEK_SET);
2754 CAB(offset) = 0;
2755 CAB(outlen) = 0;
2757 /* initialize the new decompressor */
2758 switch (ct1) {
2759 case cffoldCOMPTYPE_NONE:
2760 CAB(decompress) = NONEfdi_decomp;
2761 break;
2762 case cffoldCOMPTYPE_MSZIP:
2763 CAB(decompress) = ZIPfdi_decomp;
2764 break;
2765 case cffoldCOMPTYPE_QUANTUM:
2766 CAB(decompress) = QTMfdi_decomp;
2767 err = QTMfdi_init((comptype >> 8) & 0x1f, (comptype >> 4) & 0xF, decomp_state);
2768 break;
2769 case cffoldCOMPTYPE_LZX:
2770 CAB(decompress) = LZXfdi_decomp;
2771 err = LZXfdi_init((comptype >> 8) & 0x1f, decomp_state);
2772 break;
2773 default:
2774 err = DECR_DATAFORMAT;
2778 CAB(current) = fol;
2780 switch (err) {
2781 case DECR_OK:
2782 break;
2783 case DECR_NOMEMORY:
2784 set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY );
2785 goto bail_and_fail;
2786 default:
2787 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
2788 goto bail_and_fail;
2791 if (file->offset > CAB(offset)) {
2792 /* decode bytes and send them to /dev/null */
2793 switch (fdi_decomp(file, 0, decomp_state, pszCabPath, pfnfdin, pvUser)) {
2794 case DECR_OK:
2795 break;
2796 case DECR_USERABORT:
2797 set_error( fdi, FDIERROR_USER_ABORT, 0 );
2798 goto bail_and_fail;
2799 case DECR_NOMEMORY:
2800 set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY );
2801 goto bail_and_fail;
2802 default:
2803 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
2804 goto bail_and_fail;
2806 CAB(offset) = file->offset;
2809 /* now do the actual decompression */
2810 err = fdi_decomp(file, 1, decomp_state, pszCabPath, pfnfdin, pvUser);
2811 if (err) CAB(current) = NULL; else CAB(offset) += file->length;
2813 /* fdintCLOSE_FILE_INFO notification */
2814 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2815 fdin.pv = pvUser;
2816 fdin.psz1 = (char *)file->filename;
2817 fdin.hf = filehf;
2818 fdin.cb = (file->attribs & cffile_A_EXEC) ? TRUE : FALSE; /* FIXME: is that right? */
2819 fdin.date = file->date;
2820 fdin.time = file->time;
2821 fdin.attribs = file->attribs; /* FIXME: filter _A_EXEC? */
2822 ((*pfnfdin)(fdintCLOSE_FILE_INFO, &fdin));
2823 filehf = 0;
2825 switch (err) {
2826 case DECR_OK:
2827 break;
2828 case DECR_USERABORT:
2829 set_error( fdi, FDIERROR_USER_ABORT, 0 );
2830 goto bail_and_fail;
2831 case DECR_NOMEMORY:
2832 set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY );
2833 goto bail_and_fail;
2834 default:
2835 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
2836 goto bail_and_fail;
2841 if (fol) free_decompression_temps(fdi, fol, decomp_state);
2842 free_decompression_mem(fdi, decomp_state);
2844 return TRUE;
2846 bail_and_fail: /* here we free ram before error returns */
2848 if (fol) free_decompression_temps(fdi, fol, decomp_state);
2850 if (filehf) fdi->close(filehf);
2852 free_decompression_mem(fdi, decomp_state);
2854 return FALSE;
2857 /***********************************************************************
2858 * FDIDestroy (CABINET.23)
2860 * Frees a handle created by FDICreate. Do /not/ call this in the middle
2861 * of FDICopy. Only reason for failure would be an invalid handle.
2863 * PARAMS
2864 * hfdi [I] The HFDI to free
2866 * RETURNS
2867 * TRUE for success
2868 * FALSE for failure
2870 BOOL __cdecl FDIDestroy(HFDI hfdi)
2872 FDI_Int *fdi = get_fdi_ptr( hfdi );
2874 TRACE("(hfdi == ^%p)\n", hfdi);
2875 if (!fdi) return FALSE;
2876 fdi->magic = 0; /* paranoia */
2877 fdi->free(fdi);
2878 return TRUE;
2881 /***********************************************************************
2882 * FDITruncateCabinet (CABINET.24)
2884 * Removes all folders of a cabinet file after and including the
2885 * specified folder number.
2887 * PARAMS
2888 * hfdi [I] Handle to the FDI context.
2889 * pszCabinetName [I] Filename of the cabinet.
2890 * iFolderToDelete [I] Index of the first folder to delete.
2892 * RETURNS
2893 * Success: TRUE.
2894 * Failure: FALSE.
2896 * NOTES
2897 * The PFNWRITE function supplied to FDICreate must truncate the
2898 * file at the current position if the number of bytes to write is 0.
2900 BOOL __cdecl FDITruncateCabinet(
2901 HFDI hfdi,
2902 char *pszCabinetName,
2903 USHORT iFolderToDelete)
2905 FDI_Int *fdi = get_fdi_ptr( hfdi );
2907 FIXME("(hfdi == ^%p, pszCabinetName == %s, iFolderToDelete == %hu): stub\n",
2908 hfdi, debugstr_a(pszCabinetName), iFolderToDelete);
2910 if (!fdi) return FALSE;
2912 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2913 return FALSE;