cabinet: Move internal FDI definitions to fdi.c.
[wine.git] / dlls / cabinet / fdi.c
blobb5dc29d1ef86d05a885fc4813c297b37a0bbabd5
1 /*
2 * File Decompression Interface
4 * Copyright 2000-2002 Stuart Caie
5 * Copyright 2002 Patrik Stridvall
6 * Copyright 2003 Greg Turner
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * This is a largely redundant reimplementation of the stuff in cabextract.c. It
24 * would be theoretically preferable to have only one, shared implementation, however
25 * there are semantic differences which may discourage efforts to unify the two. It
26 * should be possible, if awkward, to go back and reimplement cabextract.c using FDI.
27 * But this approach would be quite a bit less performant. Probably a better way
28 * would be to create a "library" of routines in cabextract.c which do the actual
29 * decompression, and have both fdi.c and cabextract share those routines. The rest
30 * of the code is not sufficiently similar to merit a shared implementation.
32 * The worst thing about this API is the bug. "The bug" is this: when you extract a
33 * cabinet, it /always/ informs you (via the hasnext field of PFDICABINETINFO), that
34 * there is no subsequent cabinet, even if there is one. wine faithfully reproduces
35 * this behavior.
37 * TODO:
39 * Wine does not implement the AFAIK undocumented "enumerate" callback during
40 * FDICopy. It is implemented in Windows and therefore worth investigating...
42 * Lots of pointers flying around here... am I leaking RAM?
44 * WTF is FDITruncate?
46 * Probably, I need to weed out some dead code-paths.
48 * Test unit(s).
50 * The fdintNEXT_CABINET callbacks are probably not working quite as they should.
51 * There are several FIXME's in the source describing some of the deficiencies in
52 * some detail. Additionally, we do not do a very good job of returning the right
53 * error codes to this callback.
55 * FDICopy and fdi_decomp are incomprehensibly large; separating these into smaller
56 * functions would be nice.
58 * -gmt
61 #include "config.h"
63 #include <stdarg.h>
64 #include <stdio.h>
66 #include "windef.h"
67 #include "winbase.h"
68 #include "winerror.h"
69 #include "fdi.h"
70 #include "cabinet.h"
72 #include "wine/debug.h"
74 WINE_DEFAULT_DEBUG_CHANNEL(cabinet);
76 THOSE_ZIP_CONSTS;
78 struct fdi_file {
79 struct fdi_file *next; /* next file in sequence */
80 LPSTR filename; /* output name of file */
81 int fh; /* open file handle or NULL */
82 cab_ULONG length; /* uncompressed length of file */
83 cab_ULONG offset; /* uncompressed offset in folder */
84 cab_UWORD index; /* magic index number of folder */
85 cab_UWORD time, date, attribs; /* MS-DOS time/date/attributes */
86 BOOL oppressed; /* never to be processed */
89 struct fdi_folder {
90 struct fdi_folder *next;
91 cab_off_t offset; /* offset to data blocks (32 bit) */
92 cab_UWORD comp_type; /* compression format/window size */
93 cab_ULONG comp_size; /* compressed size of folder */
94 cab_UBYTE num_splits; /* number of split blocks + 1 */
95 cab_UWORD num_blocks; /* total number of blocks */
99 * this structure fills the gaps between what is available in a PFDICABINETINFO
100 * vs what is needed by FDICopy. Memory allocated for these becomes the responsibility
101 * of the caller to free. Yes, I am aware that this is totally, utterly inelegant.
102 * To make things even more unnecessarily confusing, we now attach these to the
103 * fdi_decomp_state.
105 typedef struct {
106 char *prevname, *previnfo;
107 char *nextname, *nextinfo;
108 BOOL hasnext; /* bug free indicator */
109 int folder_resv, header_resv;
110 cab_UBYTE block_resv;
111 } MORE_ISCAB_INFO, *PMORE_ISCAB_INFO;
113 typedef struct
115 unsigned int magic;
116 PFNALLOC alloc;
117 PFNFREE free;
118 PFNOPEN open;
119 PFNREAD read;
120 PFNWRITE write;
121 PFNCLOSE close;
122 PFNSEEK seek;
123 PERF perf;
124 } FDI_Int;
126 #define FDI_INT_MAGIC 0xfdfdfd05
129 * ugh, well, this ended up being pretty damn silly...
130 * now that I've conceded to build equivalent structures to struct cab.*,
131 * I should have just used those, or, better yet, unified the two... sue me.
132 * (Note to Microsoft: That's a joke. Please /don't/ actually sue me! -gmt).
133 * Nevertheless, I've come this far, it works, so I'm not gonna change it
134 * for now. This implementation has significant semantic differences anyhow.
137 typedef struct fdi_cds_fwd {
138 FDI_Int *fdi; /* the hfdi we are using */
139 INT_PTR filehf, cabhf; /* file handle we are using */
140 struct fdi_folder *current; /* current folder we're extracting from */
141 cab_ULONG offset; /* uncompressed offset within folder */
142 cab_UBYTE *outpos; /* (high level) start of data to use up */
143 cab_UWORD outlen; /* (high level) amount of data to use up */
144 int (*decompress)(int, int, struct fdi_cds_fwd *); /* chosen compress fn */
145 cab_UBYTE inbuf[CAB_INPUTMAX+2]; /* +2 for lzx bitbuffer overflows! */
146 cab_UBYTE outbuf[CAB_BLOCKMAX];
147 union {
148 struct ZIPstate zip;
149 struct QTMstate qtm;
150 struct LZXstate lzx;
151 } methods;
152 /* some temp variables for use during decompression */
153 cab_UBYTE q_length_base[27], q_length_extra[27], q_extra_bits[42];
154 cab_ULONG q_position_base[42];
155 cab_ULONG lzx_position_base[51];
156 cab_UBYTE extra_bits[51];
157 USHORT setID; /* Cabinet set ID */
158 USHORT iCabinet; /* Cabinet number in set (0 based) */
159 struct fdi_cds_fwd *decomp_cab;
160 MORE_ISCAB_INFO mii;
161 struct fdi_folder *firstfol;
162 struct fdi_file *firstfile;
163 struct fdi_cds_fwd *next;
164 } fdi_decomp_state;
166 #define ZIPNEEDBITS(n) {while(k<(n)){cab_LONG c=*(ZIP(inpos)++);\
167 b|=((cab_ULONG)c)<<k;k+=8;}}
168 #define ZIPDUMPBITS(n) {b>>=(n);k-=(n);}
170 /* endian-neutral reading of little-endian data */
171 #define EndGetI32(a) ((((a)[3])<<24)|(((a)[2])<<16)|(((a)[1])<<8)|((a)[0]))
172 #define EndGetI16(a) ((((a)[1])<<8)|((a)[0]))
174 #define CAB(x) (decomp_state->x)
175 #define ZIP(x) (decomp_state->methods.zip.x)
176 #define QTM(x) (decomp_state->methods.qtm.x)
177 #define LZX(x) (decomp_state->methods.lzx.x)
178 #define DECR_OK (0)
179 #define DECR_DATAFORMAT (1)
180 #define DECR_ILLEGALDATA (2)
181 #define DECR_NOMEMORY (3)
182 #define DECR_CHECKSUM (4)
183 #define DECR_INPUT (5)
184 #define DECR_OUTPUT (6)
185 #define DECR_USERABORT (7)
187 static void set_error( FDI_Int *fdi, int oper, int err )
189 fdi->perf->erfOper = oper;
190 fdi->perf->erfType = err;
191 fdi->perf->fError = TRUE;
192 if (err) SetLastError( err );
195 static FDI_Int *get_fdi_ptr( HFDI hfdi )
197 FDI_Int *fdi= (FDI_Int *)hfdi;
199 if (!fdi || !fdi->magic == FDI_INT_MAGIC)
201 SetLastError( ERROR_INVALID_HANDLE );
202 return NULL;
204 return fdi;
207 /****************************************************************
208 * QTMupdatemodel (internal)
210 static void QTMupdatemodel(struct QTMmodel *model, int sym) {
211 struct QTMmodelsym temp;
212 int i, j;
214 for (i = 0; i < sym; i++) model->syms[i].cumfreq += 8;
216 if (model->syms[0].cumfreq > 3800) {
217 if (--model->shiftsleft) {
218 for (i = model->entries - 1; i >= 0; i--) {
219 /* -1, not -2; the 0 entry saves this */
220 model->syms[i].cumfreq >>= 1;
221 if (model->syms[i].cumfreq <= model->syms[i+1].cumfreq) {
222 model->syms[i].cumfreq = model->syms[i+1].cumfreq + 1;
226 else {
227 model->shiftsleft = 50;
228 for (i = 0; i < model->entries ; i++) {
229 /* no -1, want to include the 0 entry */
230 /* this converts cumfreqs into frequencies, then shifts right */
231 model->syms[i].cumfreq -= model->syms[i+1].cumfreq;
232 model->syms[i].cumfreq++; /* avoid losing things entirely */
233 model->syms[i].cumfreq >>= 1;
236 /* now sort by frequencies, decreasing order -- this must be an
237 * inplace selection sort, or a sort with the same (in)stability
238 * characteristics
240 for (i = 0; i < model->entries - 1; i++) {
241 for (j = i + 1; j < model->entries; j++) {
242 if (model->syms[i].cumfreq < model->syms[j].cumfreq) {
243 temp = model->syms[i];
244 model->syms[i] = model->syms[j];
245 model->syms[j] = temp;
250 /* then convert frequencies back to cumfreq */
251 for (i = model->entries - 1; i >= 0; i--) {
252 model->syms[i].cumfreq += model->syms[i+1].cumfreq;
254 /* then update the other part of the table */
255 for (i = 0; i < model->entries; i++) {
256 model->tabloc[model->syms[i].sym] = i;
262 /*************************************************************************
263 * make_decode_table (internal)
265 * This function was coded by David Tritscher. It builds a fast huffman
266 * decoding table out of just a canonical huffman code lengths table.
268 * PARAMS
269 * nsyms: total number of symbols in this huffman tree.
270 * nbits: any symbols with a code length of nbits or less can be decoded
271 * in one lookup of the table.
272 * length: A table to get code lengths from [0 to syms-1]
273 * table: The table to fill up with decoded symbols and pointers.
275 * RETURNS
276 * OK: 0
277 * error: 1
279 static int make_decode_table(cab_ULONG nsyms, cab_ULONG nbits,
280 const cab_UBYTE *length, cab_UWORD *table) {
281 register cab_UWORD sym;
282 register cab_ULONG leaf;
283 register cab_UBYTE bit_num = 1;
284 cab_ULONG fill;
285 cab_ULONG pos = 0; /* the current position in the decode table */
286 cab_ULONG table_mask = 1 << nbits;
287 cab_ULONG bit_mask = table_mask >> 1; /* don't do 0 length codes */
288 cab_ULONG next_symbol = bit_mask; /* base of allocation for long codes */
290 /* fill entries for codes short enough for a direct mapping */
291 while (bit_num <= nbits) {
292 for (sym = 0; sym < nsyms; sym++) {
293 if (length[sym] == bit_num) {
294 leaf = pos;
296 if((pos += bit_mask) > table_mask) return 1; /* table overrun */
298 /* fill all possible lookups of this symbol with the symbol itself */
299 fill = bit_mask;
300 while (fill-- > 0) table[leaf++] = sym;
303 bit_mask >>= 1;
304 bit_num++;
307 /* if there are any codes longer than nbits */
308 if (pos != table_mask) {
309 /* clear the remainder of the table */
310 for (sym = pos; sym < table_mask; sym++) table[sym] = 0;
312 /* give ourselves room for codes to grow by up to 16 more bits */
313 pos <<= 16;
314 table_mask <<= 16;
315 bit_mask = 1 << 15;
317 while (bit_num <= 16) {
318 for (sym = 0; sym < nsyms; sym++) {
319 if (length[sym] == bit_num) {
320 leaf = pos >> 16;
321 for (fill = 0; fill < bit_num - nbits; fill++) {
322 /* if this path hasn't been taken yet, 'allocate' two entries */
323 if (table[leaf] == 0) {
324 table[(next_symbol << 1)] = 0;
325 table[(next_symbol << 1) + 1] = 0;
326 table[leaf] = next_symbol++;
328 /* follow the path and select either left or right for next bit */
329 leaf = table[leaf] << 1;
330 if ((pos >> (15-fill)) & 1) leaf++;
332 table[leaf] = sym;
334 if ((pos += bit_mask) > table_mask) return 1; /* table overflow */
337 bit_mask >>= 1;
338 bit_num++;
342 /* full table? */
343 if (pos == table_mask) return 0;
345 /* either erroneous table, or all elements are 0 - let's find out. */
346 for (sym = 0; sym < nsyms; sym++) if (length[sym]) return 1;
347 return 0;
350 /*************************************************************************
351 * checksum (internal)
353 static cab_ULONG checksum(const cab_UBYTE *data, cab_UWORD bytes, cab_ULONG csum) {
354 int len;
355 cab_ULONG ul = 0;
357 for (len = bytes >> 2; len--; data += 4) {
358 csum ^= ((data[0]) | (data[1]<<8) | (data[2]<<16) | (data[3]<<24));
361 switch (bytes & 3) {
362 case 3: ul |= *data++ << 16;
363 case 2: ul |= *data++ << 8;
364 case 1: ul |= *data;
366 csum ^= ul;
368 return csum;
371 /***********************************************************************
372 * FDICreate (CABINET.20)
374 * Provided with several callbacks (all of them are mandatory),
375 * returns a handle which can be used to perform operations
376 * on cabinet files.
378 * PARAMS
379 * pfnalloc [I] A pointer to a function which allocates ram. Uses
380 * the same interface as malloc.
381 * pfnfree [I] A pointer to a function which frees ram. Uses the
382 * same interface as free.
383 * pfnopen [I] A pointer to a function which opens a file. Uses
384 * the same interface as _open.
385 * pfnread [I] A pointer to a function which reads from a file into
386 * a caller-provided buffer. Uses the same interface
387 * as _read
388 * pfnwrite [I] A pointer to a function which writes to a file from
389 * a caller-provided buffer. Uses the same interface
390 * as _write.
391 * pfnclose [I] A pointer to a function which closes a file handle.
392 * Uses the same interface as _close.
393 * pfnseek [I] A pointer to a function which seeks in a file.
394 * Uses the same interface as _lseek.
395 * cpuType [I] The type of CPU; ignored in wine (recommended value:
396 * cpuUNKNOWN, aka -1).
397 * perf [IO] A pointer to an ERF structure. When FDICreate
398 * returns an error condition, error information may
399 * be found here as well as from GetLastError.
401 * RETURNS
402 * On success, returns an FDI handle of type HFDI.
403 * On failure, the NULL file handle is returned. Error
404 * info can be retrieved from perf.
406 * INCLUDES
407 * fdi.h
410 HFDI __cdecl FDICreate(
411 PFNALLOC pfnalloc,
412 PFNFREE pfnfree,
413 PFNOPEN pfnopen,
414 PFNREAD pfnread,
415 PFNWRITE pfnwrite,
416 PFNCLOSE pfnclose,
417 PFNSEEK pfnseek,
418 int cpuType,
419 PERF perf)
421 FDI_Int *fdi;
423 TRACE("(pfnalloc == ^%p, pfnfree == ^%p, pfnopen == ^%p, pfnread == ^%p, pfnwrite == ^%p, "
424 "pfnclose == ^%p, pfnseek == ^%p, cpuType == %d, perf == ^%p)\n",
425 pfnalloc, pfnfree, pfnopen, pfnread, pfnwrite, pfnclose, pfnseek,
426 cpuType, perf);
428 if ((!pfnalloc) || (!pfnfree)) {
429 perf->erfOper = FDIERROR_NONE;
430 perf->erfType = ERROR_BAD_ARGUMENTS;
431 perf->fError = TRUE;
433 SetLastError(ERROR_BAD_ARGUMENTS);
434 return NULL;
437 if (!((fdi = pfnalloc(sizeof(FDI_Int))))) {
438 perf->erfOper = FDIERROR_ALLOC_FAIL;
439 perf->erfType = ERROR_NOT_ENOUGH_MEMORY;
440 perf->fError = TRUE;
442 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
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);
606 if (num_folders == 0) {
607 /* PONDERME: is this really invalid? */
608 WARN("weird cabinet detect failure: no folders in cabinet\n");
609 if (pmii) set_error( fdi, FDIERROR_NOT_A_CABINET, 0 );
610 return FALSE;
613 /* get the number of files */
614 num_files = EndGetI16(buf+cfhead_NumFiles);
615 if (num_files == 0) {
616 /* PONDERME: is this really invalid? */
617 WARN("weird cabinet detect failure: no files in cabinet\n");
618 if (pmii) set_error( fdi, FDIERROR_NOT_A_CABINET, 0 );
619 return FALSE;
622 /* setid */
623 setid = EndGetI16(buf+cfhead_SetID);
625 /* cabinet (set) index */
626 cabidx = EndGetI16(buf+cfhead_CabinetIndex);
628 /* check the header revision */
629 if ((buf[cfhead_MajorVersion] > 1) ||
630 (buf[cfhead_MajorVersion] == 1 && buf[cfhead_MinorVersion] > 3))
632 WARN("cabinet format version > 1.3\n");
633 if (pmii) set_error( fdi, FDIERROR_UNKNOWN_CABINET_VERSION, 0 /* ? */ );
634 return FALSE;
637 /* pull the flags out */
638 flags = EndGetI16(buf+cfhead_Flags);
640 /* read the reserved-sizes part of header, if present */
641 if (flags & cfheadRESERVE_PRESENT) {
642 if (fdi->read(hf, buf, cfheadext_SIZEOF) != cfheadext_SIZEOF) {
643 ERR("bunk reserve-sizes?\n");
644 if (pmii) set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 /* ? */ );
645 return FALSE;
648 header_resv = EndGetI16(buf+cfheadext_HeaderReserved);
649 if (pmii) pmii->header_resv = header_resv;
650 folder_resv = buf[cfheadext_FolderReserved];
651 if (pmii) pmii->folder_resv = folder_resv;
652 block_resv = buf[cfheadext_DataReserved];
653 if (pmii) pmii->block_resv = block_resv;
655 if (header_resv > 60000) {
656 WARN("WARNING; header reserved space > 60000\n");
659 /* skip the reserved header */
660 if ((header_resv) && (fdi->seek(hf, header_resv, SEEK_CUR) == -1)) {
661 ERR("seek failure: header_resv\n");
662 if (pmii) set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 /* ? */ );
663 return FALSE;
667 if (flags & cfheadPREV_CABINET) {
668 prevname = FDI_read_string(fdi, hf, cabsize);
669 if (!prevname) {
670 if (pmii) set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 /* ? */ );
671 return FALSE;
672 } else
673 if (pmii)
674 pmii->prevname = prevname;
675 else
676 fdi->free(prevname);
677 previnfo = FDI_read_string(fdi, hf, cabsize);
678 if (previnfo) {
679 if (pmii)
680 pmii->previnfo = previnfo;
681 else
682 fdi->free(previnfo);
686 if (flags & cfheadNEXT_CABINET) {
687 if (pmii)
688 pmii->hasnext = TRUE;
689 nextname = FDI_read_string(fdi, hf, cabsize);
690 if (!nextname) {
691 if ((flags & cfheadPREV_CABINET) && pmii) {
692 if (pmii->prevname) fdi->free(prevname);
693 if (pmii->previnfo) fdi->free(previnfo);
695 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 /* ? */ );
696 return FALSE;
697 } else
698 if (pmii)
699 pmii->nextname = nextname;
700 else
701 fdi->free(nextname);
702 nextinfo = FDI_read_string(fdi, hf, cabsize);
703 if (nextinfo) {
704 if (pmii)
705 pmii->nextinfo = nextinfo;
706 else
707 fdi->free(nextinfo);
711 /* we could process the whole cabinet searching for problems;
712 instead lets stop here. Now let's fill out the paperwork */
713 pfdici->cbCabinet = cabsize;
714 pfdici->cFolders = num_folders;
715 pfdici->cFiles = num_files;
716 pfdici->setID = setid;
717 pfdici->iCabinet = cabidx;
718 pfdici->fReserve = (flags & cfheadRESERVE_PRESENT) ? TRUE : FALSE;
719 pfdici->hasprev = (flags & cfheadPREV_CABINET) ? TRUE : FALSE;
720 pfdici->hasnext = (flags & cfheadNEXT_CABINET) ? TRUE : FALSE;
721 return TRUE;
724 /***********************************************************************
725 * FDIIsCabinet (CABINET.21)
727 * Informs the caller as to whether or not the provided file handle is
728 * really a cabinet or not, filling out the provided PFDICABINETINFO
729 * structure with information about the cabinet. Brief explanations of
730 * the elements of this structure are available as comments accompanying
731 * its definition in wine's include/fdi.h.
733 * PARAMS
734 * hfdi [I] An HFDI from FDICreate
735 * hf [I] The file handle about which the caller inquires
736 * pfdici [IO] Pointer to a PFDICABINETINFO structure which will
737 * be filled out with information about the cabinet
738 * file indicated by hf if, indeed, it is determined
739 * to be a cabinet.
741 * RETURNS
742 * TRUE if the file is a cabinet. The info pointed to by pfdici will
743 * be provided.
744 * FALSE if the file is not a cabinet, or if an error was encountered
745 * while processing the cabinet. The PERF structure provided to
746 * FDICreate can be queried for more error information.
748 * INCLUDES
749 * fdi.c
751 BOOL __cdecl FDIIsCabinet(
752 HFDI hfdi,
753 INT_PTR hf,
754 PFDICABINETINFO pfdici)
756 BOOL rv;
757 FDI_Int *fdi = get_fdi_ptr( hfdi );
759 TRACE("(hfdi == ^%p, hf == ^%ld, pfdici == ^%p)\n", hfdi, hf, pfdici);
761 if (!fdi) return FALSE;
763 if (!hf) {
764 ERR("(!hf)!\n");
765 SetLastError(ERROR_INVALID_HANDLE);
766 return FALSE;
769 if (!pfdici) {
770 ERR("(!pfdici)!\n");
771 SetLastError(ERROR_BAD_ARGUMENTS);
772 return FALSE;
774 rv = FDI_read_entries(fdi, hf, pfdici, NULL);
776 if (rv)
777 pfdici->hasnext = FALSE; /* yuck. duplicate apparent cabinet.dll bug */
779 return rv;
782 /******************************************************************
783 * QTMfdi_initmodel (internal)
785 * Initialize a model which decodes symbols from [s] to [s]+[n]-1
787 static void QTMfdi_initmodel(struct QTMmodel *m, struct QTMmodelsym *sym, int n, int s) {
788 int i;
789 m->shiftsleft = 4;
790 m->entries = n;
791 m->syms = sym;
792 memset(m->tabloc, 0xFF, sizeof(m->tabloc)); /* clear out look-up table */
793 for (i = 0; i < n; i++) {
794 m->tabloc[i+s] = i; /* set up a look-up entry for symbol */
795 m->syms[i].sym = i+s; /* actual symbol */
796 m->syms[i].cumfreq = n-i; /* current frequency of that symbol */
798 m->syms[n].cumfreq = 0;
801 /******************************************************************
802 * QTMfdi_init (internal)
804 static int QTMfdi_init(int window, int level, fdi_decomp_state *decomp_state) {
805 unsigned int wndsize = 1 << window;
806 int msz = window * 2, i;
807 cab_ULONG j;
809 /* QTM supports window sizes of 2^10 (1Kb) through 2^21 (2Mb) */
810 /* if a previously allocated window is big enough, keep it */
811 if (window < 10 || window > 21) return DECR_DATAFORMAT;
812 if (QTM(actual_size) < wndsize) {
813 if (QTM(window)) CAB(fdi)->free(QTM(window));
814 QTM(window) = NULL;
816 if (!QTM(window)) {
817 if (!(QTM(window) = CAB(fdi)->alloc(wndsize))) return DECR_NOMEMORY;
818 QTM(actual_size) = wndsize;
820 QTM(window_size) = wndsize;
821 QTM(window_posn) = 0;
823 /* initialize static slot/extrabits tables */
824 for (i = 0, j = 0; i < 27; i++) {
825 CAB(q_length_extra)[i] = (i == 26) ? 0 : (i < 2 ? 0 : i - 2) >> 2;
826 CAB(q_length_base)[i] = j; j += 1 << ((i == 26) ? 5 : CAB(q_length_extra)[i]);
828 for (i = 0, j = 0; i < 42; i++) {
829 CAB(q_extra_bits)[i] = (i < 2 ? 0 : i-2) >> 1;
830 CAB(q_position_base)[i] = j; j += 1 << CAB(q_extra_bits)[i];
833 /* initialize arithmetic coding models */
835 QTMfdi_initmodel(&QTM(model7), &QTM(m7sym)[0], 7, 0);
837 QTMfdi_initmodel(&QTM(model00), &QTM(m00sym)[0], 0x40, 0x00);
838 QTMfdi_initmodel(&QTM(model40), &QTM(m40sym)[0], 0x40, 0x40);
839 QTMfdi_initmodel(&QTM(model80), &QTM(m80sym)[0], 0x40, 0x80);
840 QTMfdi_initmodel(&QTM(modelC0), &QTM(mC0sym)[0], 0x40, 0xC0);
842 /* model 4 depends on table size, ranges from 20 to 24 */
843 QTMfdi_initmodel(&QTM(model4), &QTM(m4sym)[0], (msz < 24) ? msz : 24, 0);
844 /* model 5 depends on table size, ranges from 20 to 36 */
845 QTMfdi_initmodel(&QTM(model5), &QTM(m5sym)[0], (msz < 36) ? msz : 36, 0);
846 /* model 6pos depends on table size, ranges from 20 to 42 */
847 QTMfdi_initmodel(&QTM(model6pos), &QTM(m6psym)[0], msz, 0);
848 QTMfdi_initmodel(&QTM(model6len), &QTM(m6lsym)[0], 27, 0);
850 return DECR_OK;
853 /************************************************************
854 * LZXfdi_init (internal)
856 static int LZXfdi_init(int window, fdi_decomp_state *decomp_state) {
857 static const cab_UBYTE bits[] =
858 { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
859 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14,
860 15, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
861 17, 17, 17};
862 static const cab_ULONG base[] =
863 { 0, 1, 2, 3, 4, 6, 8, 12,
864 16, 24, 32, 48, 64, 96, 128, 192,
865 256, 384, 512, 768, 1024, 1536, 2048, 3072,
866 4096, 6144, 8192, 12288, 16384, 24576, 32768, 49152,
867 65536, 98304, 131072, 196608, 262144, 393216, 524288, 655360,
868 786432, 917504, 1048576, 1179648, 1310720, 1441792, 1572864, 1703936,
869 1835008, 1966080, 2097152};
870 cab_ULONG wndsize = 1 << window;
871 int posn_slots;
873 /* LZX supports window sizes of 2^15 (32Kb) through 2^21 (2Mb) */
874 /* if a previously allocated window is big enough, keep it */
875 if (window < 15 || window > 21) return DECR_DATAFORMAT;
876 if (LZX(actual_size) < wndsize) {
877 if (LZX(window)) CAB(fdi)->free(LZX(window));
878 LZX(window) = NULL;
880 if (!LZX(window)) {
881 if (!(LZX(window) = CAB(fdi)->alloc(wndsize))) return DECR_NOMEMORY;
882 LZX(actual_size) = wndsize;
884 LZX(window_size) = wndsize;
886 /* initialize static tables */
887 memcpy(CAB(extra_bits), bits, sizeof(bits));
888 memcpy(CAB(lzx_position_base), base, sizeof(base));
890 /* calculate required position slots */
891 if (window == 20) posn_slots = 42;
892 else if (window == 21) posn_slots = 50;
893 else posn_slots = window << 1;
895 /*posn_slots=i=0; while (i < wndsize) i += 1 << CAB(extra_bits)[posn_slots++]; */
897 LZX(R0) = LZX(R1) = LZX(R2) = 1;
898 LZX(main_elements) = LZX_NUM_CHARS + (posn_slots << 3);
899 LZX(header_read) = 0;
900 LZX(frames_read) = 0;
901 LZX(block_remaining) = 0;
902 LZX(block_type) = LZX_BLOCKTYPE_INVALID;
903 LZX(intel_curpos) = 0;
904 LZX(intel_started) = 0;
905 LZX(window_posn) = 0;
907 /* initialize tables to 0 (because deltas will be applied to them) */
908 memset(LZX(MAINTREE_len), 0, sizeof(LZX(MAINTREE_len)));
909 memset(LZX(LENGTH_len), 0, sizeof(LZX(LENGTH_len)));
911 return DECR_OK;
914 /****************************************************
915 * NONEfdi_decomp(internal)
917 static int NONEfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state)
919 if (inlen != outlen) return DECR_ILLEGALDATA;
920 if (outlen > CAB_BLOCKMAX) return DECR_DATAFORMAT;
921 memcpy(CAB(outbuf), CAB(inbuf), (size_t) inlen);
922 return DECR_OK;
925 /********************************************************
926 * Ziphuft_free (internal)
928 static void fdi_Ziphuft_free(FDI_Int *fdi, struct Ziphuft *t)
930 register struct Ziphuft *p, *q;
932 /* Go through linked list, freeing from the allocated (t[-1]) address. */
933 p = t;
934 while (p != NULL)
936 q = (--p)->v.t;
937 fdi->free(p);
938 p = q;
942 /*********************************************************
943 * fdi_Ziphuft_build (internal)
945 static cab_LONG fdi_Ziphuft_build(cab_ULONG *b, cab_ULONG n, cab_ULONG s, const cab_UWORD *d, const cab_UWORD *e,
946 struct Ziphuft **t, cab_LONG *m, fdi_decomp_state *decomp_state)
948 cab_ULONG a; /* counter for codes of length k */
949 cab_ULONG el; /* length of EOB code (value 256) */
950 cab_ULONG f; /* i repeats in table every f entries */
951 cab_LONG g; /* maximum code length */
952 cab_LONG h; /* table level */
953 register cab_ULONG i; /* counter, current code */
954 register cab_ULONG j; /* counter */
955 register cab_LONG k; /* number of bits in current code */
956 cab_LONG *l; /* stack of bits per table */
957 register cab_ULONG *p; /* pointer into ZIP(c)[],ZIP(b)[],ZIP(v)[] */
958 register struct Ziphuft *q; /* points to current table */
959 struct Ziphuft r; /* table entry for structure assignment */
960 register cab_LONG w; /* bits before this table == (l * h) */
961 cab_ULONG *xp; /* pointer into x */
962 cab_LONG y; /* number of dummy codes added */
963 cab_ULONG z; /* number of entries in current table */
965 l = ZIP(lx)+1;
967 /* Generate counts for each bit length */
968 el = n > 256 ? b[256] : ZIPBMAX; /* set length of EOB code, if any */
970 for(i = 0; i < ZIPBMAX+1; ++i)
971 ZIP(c)[i] = 0;
972 p = b; i = n;
975 ZIP(c)[*p]++; p++; /* assume all entries <= ZIPBMAX */
976 } while (--i);
977 if (ZIP(c)[0] == n) /* null input--all zero length codes */
979 *t = NULL;
980 *m = 0;
981 return 0;
984 /* Find minimum and maximum length, bound *m by those */
985 for (j = 1; j <= ZIPBMAX; j++)
986 if (ZIP(c)[j])
987 break;
988 k = j; /* minimum code length */
989 if ((cab_ULONG)*m < j)
990 *m = j;
991 for (i = ZIPBMAX; i; i--)
992 if (ZIP(c)[i])
993 break;
994 g = i; /* maximum code length */
995 if ((cab_ULONG)*m > i)
996 *m = i;
998 /* Adjust last length count to fill out codes, if needed */
999 for (y = 1 << j; j < i; j++, y <<= 1)
1000 if ((y -= ZIP(c)[j]) < 0)
1001 return 2; /* bad input: more codes than bits */
1002 if ((y -= ZIP(c)[i]) < 0)
1003 return 2;
1004 ZIP(c)[i] += y;
1006 /* Generate starting offsets LONGo the value table for each length */
1007 ZIP(x)[1] = j = 0;
1008 p = ZIP(c) + 1; xp = ZIP(x) + 2;
1009 while (--i)
1010 { /* note that i == g from above */
1011 *xp++ = (j += *p++);
1014 /* Make a table of values in order of bit lengths */
1015 p = b; i = 0;
1017 if ((j = *p++) != 0)
1018 ZIP(v)[ZIP(x)[j]++] = i;
1019 } while (++i < n);
1022 /* Generate the Huffman codes and for each, make the table entries */
1023 ZIP(x)[0] = i = 0; /* first Huffman code is zero */
1024 p = ZIP(v); /* grab values in bit order */
1025 h = -1; /* no tables yet--level -1 */
1026 w = l[-1] = 0; /* no bits decoded yet */
1027 ZIP(u)[0] = NULL; /* just to keep compilers happy */
1028 q = NULL; /* ditto */
1029 z = 0; /* ditto */
1031 /* go through the bit lengths (k already is bits in shortest code) */
1032 for (; k <= g; k++)
1034 a = ZIP(c)[k];
1035 while (a--)
1037 /* here i is the Huffman code of length k bits for value *p */
1038 /* make tables up to required level */
1039 while (k > w + l[h])
1041 w += l[h++]; /* add bits already decoded */
1043 /* compute minimum size table less than or equal to *m bits */
1044 if ((z = g - w) > (cab_ULONG)*m) /* upper limit */
1045 z = *m;
1046 if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
1047 { /* too few codes for k-w bit table */
1048 f -= a + 1; /* deduct codes from patterns left */
1049 xp = ZIP(c) + k;
1050 while (++j < z) /* try smaller tables up to z bits */
1052 if ((f <<= 1) <= *++xp)
1053 break; /* enough codes to use up j bits */
1054 f -= *xp; /* else deduct codes from patterns */
1057 if ((cab_ULONG)w + j > el && (cab_ULONG)w < el)
1058 j = el - w; /* make EOB code end at table */
1059 z = 1 << j; /* table entries for j-bit table */
1060 l[h] = j; /* set table size in stack */
1062 /* allocate and link in new table */
1063 if (!(q = CAB(fdi)->alloc((z + 1)*sizeof(struct Ziphuft))))
1065 if(h)
1066 fdi_Ziphuft_free(CAB(fdi), ZIP(u)[0]);
1067 return 3; /* not enough memory */
1069 *t = q + 1; /* link to list for Ziphuft_free() */
1070 *(t = &(q->v.t)) = NULL;
1071 ZIP(u)[h] = ++q; /* table starts after link */
1073 /* connect to last table, if there is one */
1074 if (h)
1076 ZIP(x)[h] = i; /* save pattern for backing up */
1077 r.b = (cab_UBYTE)l[h-1]; /* bits to dump before this table */
1078 r.e = (cab_UBYTE)(16 + j); /* bits in this table */
1079 r.v.t = q; /* pointer to this table */
1080 j = (i & ((1 << w) - 1)) >> (w - l[h-1]);
1081 ZIP(u)[h-1][j] = r; /* connect to last table */
1085 /* set up table entry in r */
1086 r.b = (cab_UBYTE)(k - w);
1087 if (p >= ZIP(v) + n)
1088 r.e = 99; /* out of values--invalid code */
1089 else if (*p < s)
1091 r.e = (cab_UBYTE)(*p < 256 ? 16 : 15); /* 256 is end-of-block code */
1092 r.v.n = *p++; /* simple code is just the value */
1094 else
1096 r.e = (cab_UBYTE)e[*p - s]; /* non-simple--look up in lists */
1097 r.v.n = d[*p++ - s];
1100 /* fill code-like entries with r */
1101 f = 1 << (k - w);
1102 for (j = i >> w; j < z; j += f)
1103 q[j] = r;
1105 /* backwards increment the k-bit code i */
1106 for (j = 1 << (k - 1); i & j; j >>= 1)
1107 i ^= j;
1108 i ^= j;
1110 /* backup over finished tables */
1111 while ((i & ((1 << w) - 1)) != ZIP(x)[h])
1112 w -= l[--h]; /* don't need to update q */
1116 /* return actual size of base table */
1117 *m = l[0];
1119 /* Return true (1) if we were given an incomplete table */
1120 return y != 0 && g != 1;
1123 /*********************************************************
1124 * fdi_Zipinflate_codes (internal)
1126 static cab_LONG fdi_Zipinflate_codes(const struct Ziphuft *tl, const struct Ziphuft *td,
1127 cab_LONG bl, cab_LONG bd, fdi_decomp_state *decomp_state)
1129 register cab_ULONG e; /* table entry flag/number of extra bits */
1130 cab_ULONG n, d; /* length and index for copy */
1131 cab_ULONG w; /* current window position */
1132 const struct Ziphuft *t; /* pointer to table entry */
1133 cab_ULONG ml, md; /* masks for bl and bd bits */
1134 register cab_ULONG b; /* bit buffer */
1135 register cab_ULONG k; /* number of bits in bit buffer */
1137 /* make local copies of globals */
1138 b = ZIP(bb); /* initialize bit buffer */
1139 k = ZIP(bk);
1140 w = ZIP(window_posn); /* initialize window position */
1142 /* inflate the coded data */
1143 ml = Zipmask[bl]; /* precompute masks for speed */
1144 md = Zipmask[bd];
1146 for(;;)
1148 ZIPNEEDBITS((cab_ULONG)bl)
1149 if((e = (t = tl + (b & ml))->e) > 16)
1152 if (e == 99)
1153 return 1;
1154 ZIPDUMPBITS(t->b)
1155 e -= 16;
1156 ZIPNEEDBITS(e)
1157 } while ((e = (t = t->v.t + (b & Zipmask[e]))->e) > 16);
1158 ZIPDUMPBITS(t->b)
1159 if (e == 16) /* then it's a literal */
1160 CAB(outbuf)[w++] = (cab_UBYTE)t->v.n;
1161 else /* it's an EOB or a length */
1163 /* exit if end of block */
1164 if(e == 15)
1165 break;
1167 /* get length of block to copy */
1168 ZIPNEEDBITS(e)
1169 n = t->v.n + (b & Zipmask[e]);
1170 ZIPDUMPBITS(e);
1172 /* decode distance of block to copy */
1173 ZIPNEEDBITS((cab_ULONG)bd)
1174 if ((e = (t = td + (b & md))->e) > 16)
1175 do {
1176 if (e == 99)
1177 return 1;
1178 ZIPDUMPBITS(t->b)
1179 e -= 16;
1180 ZIPNEEDBITS(e)
1181 } while ((e = (t = t->v.t + (b & Zipmask[e]))->e) > 16);
1182 ZIPDUMPBITS(t->b)
1183 ZIPNEEDBITS(e)
1184 d = w - t->v.n - (b & Zipmask[e]);
1185 ZIPDUMPBITS(e)
1188 d &= ZIPWSIZE - 1;
1189 e = ZIPWSIZE - max(d, w);
1190 e = min(e, n);
1191 n -= e;
1194 CAB(outbuf)[w++] = CAB(outbuf)[d++];
1195 } while (--e);
1196 } while (n);
1200 /* restore the globals from the locals */
1201 ZIP(window_posn) = w; /* restore global window pointer */
1202 ZIP(bb) = b; /* restore global bit buffer */
1203 ZIP(bk) = k;
1205 /* done */
1206 return 0;
1209 /***********************************************************
1210 * Zipinflate_stored (internal)
1212 static cab_LONG fdi_Zipinflate_stored(fdi_decomp_state *decomp_state)
1213 /* "decompress" an inflated type 0 (stored) block. */
1215 cab_ULONG n; /* number of bytes in block */
1216 cab_ULONG w; /* current window position */
1217 register cab_ULONG b; /* bit buffer */
1218 register cab_ULONG k; /* number of bits in bit buffer */
1220 /* make local copies of globals */
1221 b = ZIP(bb); /* initialize bit buffer */
1222 k = ZIP(bk);
1223 w = ZIP(window_posn); /* initialize window position */
1225 /* go to byte boundary */
1226 n = k & 7;
1227 ZIPDUMPBITS(n);
1229 /* get the length and its complement */
1230 ZIPNEEDBITS(16)
1231 n = (b & 0xffff);
1232 ZIPDUMPBITS(16)
1233 ZIPNEEDBITS(16)
1234 if (n != ((~b) & 0xffff))
1235 return 1; /* error in compressed data */
1236 ZIPDUMPBITS(16)
1238 /* read and output the compressed data */
1239 while(n--)
1241 ZIPNEEDBITS(8)
1242 CAB(outbuf)[w++] = (cab_UBYTE)b;
1243 ZIPDUMPBITS(8)
1246 /* restore the globals from the locals */
1247 ZIP(window_posn) = w; /* restore global window pointer */
1248 ZIP(bb) = b; /* restore global bit buffer */
1249 ZIP(bk) = k;
1250 return 0;
1253 /******************************************************
1254 * fdi_Zipinflate_fixed (internal)
1256 static cab_LONG fdi_Zipinflate_fixed(fdi_decomp_state *decomp_state)
1258 struct Ziphuft *fixed_tl;
1259 struct Ziphuft *fixed_td;
1260 cab_LONG fixed_bl, fixed_bd;
1261 cab_LONG i; /* temporary variable */
1262 cab_ULONG *l;
1264 l = ZIP(ll);
1266 /* literal table */
1267 for(i = 0; i < 144; i++)
1268 l[i] = 8;
1269 for(; i < 256; i++)
1270 l[i] = 9;
1271 for(; i < 280; i++)
1272 l[i] = 7;
1273 for(; i < 288; i++) /* make a complete, but wrong code set */
1274 l[i] = 8;
1275 fixed_bl = 7;
1276 if((i = fdi_Ziphuft_build(l, 288, 257, Zipcplens, Zipcplext, &fixed_tl, &fixed_bl, decomp_state)))
1277 return i;
1279 /* distance table */
1280 for(i = 0; i < 30; i++) /* make an incomplete code set */
1281 l[i] = 5;
1282 fixed_bd = 5;
1283 if((i = fdi_Ziphuft_build(l, 30, 0, Zipcpdist, Zipcpdext, &fixed_td, &fixed_bd, decomp_state)) > 1)
1285 fdi_Ziphuft_free(CAB(fdi), fixed_tl);
1286 return i;
1289 /* decompress until an end-of-block code */
1290 i = fdi_Zipinflate_codes(fixed_tl, fixed_td, fixed_bl, fixed_bd, decomp_state);
1292 fdi_Ziphuft_free(CAB(fdi), fixed_td);
1293 fdi_Ziphuft_free(CAB(fdi), fixed_tl);
1294 return i;
1297 /**************************************************************
1298 * fdi_Zipinflate_dynamic (internal)
1300 static cab_LONG fdi_Zipinflate_dynamic(fdi_decomp_state *decomp_state)
1301 /* decompress an inflated type 2 (dynamic Huffman codes) block. */
1303 cab_LONG i; /* temporary variables */
1304 cab_ULONG j;
1305 cab_ULONG *ll;
1306 cab_ULONG l; /* last length */
1307 cab_ULONG m; /* mask for bit lengths table */
1308 cab_ULONG n; /* number of lengths to get */
1309 struct Ziphuft *tl; /* literal/length code table */
1310 struct Ziphuft *td; /* distance code table */
1311 cab_LONG bl; /* lookup bits for tl */
1312 cab_LONG bd; /* lookup bits for td */
1313 cab_ULONG nb; /* number of bit length codes */
1314 cab_ULONG nl; /* number of literal/length codes */
1315 cab_ULONG nd; /* number of distance codes */
1316 register cab_ULONG b; /* bit buffer */
1317 register cab_ULONG k; /* number of bits in bit buffer */
1319 /* make local bit buffer */
1320 b = ZIP(bb);
1321 k = ZIP(bk);
1322 ll = ZIP(ll);
1324 /* read in table lengths */
1325 ZIPNEEDBITS(5)
1326 nl = 257 + (b & 0x1f); /* number of literal/length codes */
1327 ZIPDUMPBITS(5)
1328 ZIPNEEDBITS(5)
1329 nd = 1 + (b & 0x1f); /* number of distance codes */
1330 ZIPDUMPBITS(5)
1331 ZIPNEEDBITS(4)
1332 nb = 4 + (b & 0xf); /* number of bit length codes */
1333 ZIPDUMPBITS(4)
1334 if(nl > 288 || nd > 32)
1335 return 1; /* bad lengths */
1337 /* read in bit-length-code lengths */
1338 for(j = 0; j < nb; j++)
1340 ZIPNEEDBITS(3)
1341 ll[Zipborder[j]] = b & 7;
1342 ZIPDUMPBITS(3)
1344 for(; j < 19; j++)
1345 ll[Zipborder[j]] = 0;
1347 /* build decoding table for trees--single level, 7 bit lookup */
1348 bl = 7;
1349 if((i = fdi_Ziphuft_build(ll, 19, 19, NULL, NULL, &tl, &bl, decomp_state)) != 0)
1351 if(i == 1)
1352 fdi_Ziphuft_free(CAB(fdi), tl);
1353 return i; /* incomplete code set */
1356 /* read in literal and distance code lengths */
1357 n = nl + nd;
1358 m = Zipmask[bl];
1359 i = l = 0;
1360 while((cab_ULONG)i < n)
1362 ZIPNEEDBITS((cab_ULONG)bl)
1363 j = (td = tl + (b & m))->b;
1364 ZIPDUMPBITS(j)
1365 j = td->v.n;
1366 if (j < 16) /* length of code in bits (0..15) */
1367 ll[i++] = l = j; /* save last length in l */
1368 else if (j == 16) /* repeat last length 3 to 6 times */
1370 ZIPNEEDBITS(2)
1371 j = 3 + (b & 3);
1372 ZIPDUMPBITS(2)
1373 if((cab_ULONG)i + j > n)
1374 return 1;
1375 while (j--)
1376 ll[i++] = l;
1378 else if (j == 17) /* 3 to 10 zero length codes */
1380 ZIPNEEDBITS(3)
1381 j = 3 + (b & 7);
1382 ZIPDUMPBITS(3)
1383 if ((cab_ULONG)i + j > n)
1384 return 1;
1385 while (j--)
1386 ll[i++] = 0;
1387 l = 0;
1389 else /* j == 18: 11 to 138 zero length codes */
1391 ZIPNEEDBITS(7)
1392 j = 11 + (b & 0x7f);
1393 ZIPDUMPBITS(7)
1394 if ((cab_ULONG)i + j > n)
1395 return 1;
1396 while (j--)
1397 ll[i++] = 0;
1398 l = 0;
1402 /* free decoding table for trees */
1403 fdi_Ziphuft_free(CAB(fdi), tl);
1405 /* restore the global bit buffer */
1406 ZIP(bb) = b;
1407 ZIP(bk) = k;
1409 /* build the decoding tables for literal/length and distance codes */
1410 bl = ZIPLBITS;
1411 if((i = fdi_Ziphuft_build(ll, nl, 257, Zipcplens, Zipcplext, &tl, &bl, decomp_state)) != 0)
1413 if(i == 1)
1414 fdi_Ziphuft_free(CAB(fdi), tl);
1415 return i; /* incomplete code set */
1417 bd = ZIPDBITS;
1418 fdi_Ziphuft_build(ll + nl, nd, 0, Zipcpdist, Zipcpdext, &td, &bd, decomp_state);
1420 /* decompress until an end-of-block code */
1421 if(fdi_Zipinflate_codes(tl, td, bl, bd, decomp_state))
1422 return 1;
1424 /* free the decoding tables, return */
1425 fdi_Ziphuft_free(CAB(fdi), tl);
1426 fdi_Ziphuft_free(CAB(fdi), td);
1427 return 0;
1430 /*****************************************************
1431 * fdi_Zipinflate_block (internal)
1433 static cab_LONG fdi_Zipinflate_block(cab_LONG *e, fdi_decomp_state *decomp_state) /* e == last block flag */
1434 { /* decompress an inflated block */
1435 cab_ULONG t; /* block type */
1436 register cab_ULONG b; /* bit buffer */
1437 register cab_ULONG k; /* number of bits in bit buffer */
1439 /* make local bit buffer */
1440 b = ZIP(bb);
1441 k = ZIP(bk);
1443 /* read in last block bit */
1444 ZIPNEEDBITS(1)
1445 *e = (cab_LONG)b & 1;
1446 ZIPDUMPBITS(1)
1448 /* read in block type */
1449 ZIPNEEDBITS(2)
1450 t = b & 3;
1451 ZIPDUMPBITS(2)
1453 /* restore the global bit buffer */
1454 ZIP(bb) = b;
1455 ZIP(bk) = k;
1457 /* inflate that block type */
1458 if(t == 2)
1459 return fdi_Zipinflate_dynamic(decomp_state);
1460 if(t == 0)
1461 return fdi_Zipinflate_stored(decomp_state);
1462 if(t == 1)
1463 return fdi_Zipinflate_fixed(decomp_state);
1464 /* bad block type */
1465 return 2;
1468 /****************************************************
1469 * ZIPfdi_decomp(internal)
1471 static int ZIPfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state)
1473 cab_LONG e; /* last block flag */
1475 TRACE("(inlen == %d, outlen == %d)\n", inlen, outlen);
1477 ZIP(inpos) = CAB(inbuf);
1478 ZIP(bb) = ZIP(bk) = ZIP(window_posn) = 0;
1479 if(outlen > ZIPWSIZE)
1480 return DECR_DATAFORMAT;
1482 /* CK = Chris Kirmse, official Microsoft purloiner */
1483 if(ZIP(inpos)[0] != 0x43 || ZIP(inpos)[1] != 0x4B)
1484 return DECR_ILLEGALDATA;
1485 ZIP(inpos) += 2;
1487 do {
1488 if(fdi_Zipinflate_block(&e, decomp_state))
1489 return DECR_ILLEGALDATA;
1490 } while(!e);
1492 /* return success */
1493 return DECR_OK;
1496 /*******************************************************************
1497 * QTMfdi_decomp(internal)
1499 static int QTMfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state)
1501 cab_UBYTE *inpos = CAB(inbuf);
1502 cab_UBYTE *window = QTM(window);
1503 cab_UBYTE *runsrc, *rundest;
1504 cab_ULONG window_posn = QTM(window_posn);
1505 cab_ULONG window_size = QTM(window_size);
1507 /* used by bitstream macros */
1508 register int bitsleft, bitrun, bitsneed;
1509 register cab_ULONG bitbuf;
1511 /* used by GET_SYMBOL */
1512 cab_ULONG range;
1513 cab_UWORD symf;
1514 int i;
1516 int extra, togo = outlen, match_length = 0, copy_length;
1517 cab_UBYTE selector, sym;
1518 cab_ULONG match_offset = 0;
1520 cab_UWORD H = 0xFFFF, L = 0, C;
1522 TRACE("(inlen == %d, outlen == %d)\n", inlen, outlen);
1524 /* read initial value of C */
1525 Q_INIT_BITSTREAM;
1526 Q_READ_BITS(C, 16);
1528 /* apply 2^x-1 mask */
1529 window_posn &= window_size - 1;
1530 /* runs can't straddle the window wraparound */
1531 if ((window_posn + togo) > window_size) {
1532 TRACE("straddled run\n");
1533 return DECR_DATAFORMAT;
1536 while (togo > 0) {
1537 GET_SYMBOL(model7, selector);
1538 switch (selector) {
1539 case 0:
1540 GET_SYMBOL(model00, sym); window[window_posn++] = sym; togo--;
1541 break;
1542 case 1:
1543 GET_SYMBOL(model40, sym); window[window_posn++] = sym; togo--;
1544 break;
1545 case 2:
1546 GET_SYMBOL(model80, sym); window[window_posn++] = sym; togo--;
1547 break;
1548 case 3:
1549 GET_SYMBOL(modelC0, sym); window[window_posn++] = sym; togo--;
1550 break;
1552 case 4:
1553 /* selector 4 = fixed length of 3 */
1554 GET_SYMBOL(model4, sym);
1555 Q_READ_BITS(extra, CAB(q_extra_bits)[sym]);
1556 match_offset = CAB(q_position_base)[sym] + extra + 1;
1557 match_length = 3;
1558 break;
1560 case 5:
1561 /* selector 5 = fixed length of 4 */
1562 GET_SYMBOL(model5, sym);
1563 Q_READ_BITS(extra, CAB(q_extra_bits)[sym]);
1564 match_offset = CAB(q_position_base)[sym] + extra + 1;
1565 match_length = 4;
1566 break;
1568 case 6:
1569 /* selector 6 = variable length */
1570 GET_SYMBOL(model6len, sym);
1571 Q_READ_BITS(extra, CAB(q_length_extra)[sym]);
1572 match_length = CAB(q_length_base)[sym] + extra + 5;
1573 GET_SYMBOL(model6pos, sym);
1574 Q_READ_BITS(extra, CAB(q_extra_bits)[sym]);
1575 match_offset = CAB(q_position_base)[sym] + extra + 1;
1576 break;
1578 default:
1579 TRACE("Selector is bogus\n");
1580 return DECR_ILLEGALDATA;
1583 /* if this is a match */
1584 if (selector >= 4) {
1585 rundest = window + window_posn;
1586 togo -= match_length;
1588 /* copy any wrapped around source data */
1589 if (window_posn >= match_offset) {
1590 /* no wrap */
1591 runsrc = rundest - match_offset;
1592 } else {
1593 runsrc = rundest + (window_size - match_offset);
1594 copy_length = match_offset - window_posn;
1595 if (copy_length < match_length) {
1596 match_length -= copy_length;
1597 window_posn += copy_length;
1598 while (copy_length-- > 0) *rundest++ = *runsrc++;
1599 runsrc = window;
1602 window_posn += match_length;
1604 /* copy match data - no worries about destination wraps */
1605 while (match_length-- > 0) *rundest++ = *runsrc++;
1607 } /* while (togo > 0) */
1609 if (togo != 0) {
1610 TRACE("Frame overflow, this_run = %d\n", togo);
1611 return DECR_ILLEGALDATA;
1614 memcpy(CAB(outbuf), window + ((!window_posn) ? window_size : window_posn) -
1615 outlen, outlen);
1617 QTM(window_posn) = window_posn;
1618 return DECR_OK;
1621 /************************************************************
1622 * fdi_lzx_read_lens (internal)
1624 static int fdi_lzx_read_lens(cab_UBYTE *lens, cab_ULONG first, cab_ULONG last, struct lzx_bits *lb,
1625 fdi_decomp_state *decomp_state) {
1626 cab_ULONG i,j, x,y;
1627 int z;
1629 register cab_ULONG bitbuf = lb->bb;
1630 register int bitsleft = lb->bl;
1631 cab_UBYTE *inpos = lb->ip;
1632 cab_UWORD *hufftbl;
1634 for (x = 0; x < 20; x++) {
1635 READ_BITS(y, 4);
1636 LENTABLE(PRETREE)[x] = y;
1638 BUILD_TABLE(PRETREE);
1640 for (x = first; x < last; ) {
1641 READ_HUFFSYM(PRETREE, z);
1642 if (z == 17) {
1643 READ_BITS(y, 4); y += 4;
1644 while (y--) lens[x++] = 0;
1646 else if (z == 18) {
1647 READ_BITS(y, 5); y += 20;
1648 while (y--) lens[x++] = 0;
1650 else if (z == 19) {
1651 READ_BITS(y, 1); y += 4;
1652 READ_HUFFSYM(PRETREE, z);
1653 z = lens[x] - z; if (z < 0) z += 17;
1654 while (y--) lens[x++] = z;
1656 else {
1657 z = lens[x] - z; if (z < 0) z += 17;
1658 lens[x++] = z;
1662 lb->bb = bitbuf;
1663 lb->bl = bitsleft;
1664 lb->ip = inpos;
1665 return 0;
1668 /*******************************************************
1669 * LZXfdi_decomp(internal)
1671 static int LZXfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state) {
1672 cab_UBYTE *inpos = CAB(inbuf);
1673 const cab_UBYTE *endinp = inpos + inlen;
1674 cab_UBYTE *window = LZX(window);
1675 cab_UBYTE *runsrc, *rundest;
1676 cab_UWORD *hufftbl; /* used in READ_HUFFSYM macro as chosen decoding table */
1678 cab_ULONG window_posn = LZX(window_posn);
1679 cab_ULONG window_size = LZX(window_size);
1680 cab_ULONG R0 = LZX(R0);
1681 cab_ULONG R1 = LZX(R1);
1682 cab_ULONG R2 = LZX(R2);
1684 register cab_ULONG bitbuf;
1685 register int bitsleft;
1686 cab_ULONG match_offset, i,j,k; /* ijk used in READ_HUFFSYM macro */
1687 struct lzx_bits lb; /* used in READ_LENGTHS macro */
1689 int togo = outlen, this_run, main_element, aligned_bits;
1690 int match_length, copy_length, length_footer, extra, verbatim_bits;
1692 TRACE("(inlen == %d, outlen == %d)\n", inlen, outlen);
1694 INIT_BITSTREAM;
1696 /* read header if necessary */
1697 if (!LZX(header_read)) {
1698 i = j = 0;
1699 READ_BITS(k, 1); if (k) { READ_BITS(i,16); READ_BITS(j,16); }
1700 LZX(intel_filesize) = (i << 16) | j; /* or 0 if not encoded */
1701 LZX(header_read) = 1;
1704 /* main decoding loop */
1705 while (togo > 0) {
1706 /* last block finished, new block expected */
1707 if (LZX(block_remaining) == 0) {
1708 if (LZX(block_type) == LZX_BLOCKTYPE_UNCOMPRESSED) {
1709 if (LZX(block_length) & 1) inpos++; /* realign bitstream to word */
1710 INIT_BITSTREAM;
1713 READ_BITS(LZX(block_type), 3);
1714 READ_BITS(i, 16);
1715 READ_BITS(j, 8);
1716 LZX(block_remaining) = LZX(block_length) = (i << 8) | j;
1718 switch (LZX(block_type)) {
1719 case LZX_BLOCKTYPE_ALIGNED:
1720 for (i = 0; i < 8; i++) { READ_BITS(j, 3); LENTABLE(ALIGNED)[i] = j; }
1721 BUILD_TABLE(ALIGNED);
1722 /* rest of aligned header is same as verbatim */
1724 case LZX_BLOCKTYPE_VERBATIM:
1725 READ_LENGTHS(MAINTREE, 0, 256, fdi_lzx_read_lens);
1726 READ_LENGTHS(MAINTREE, 256, LZX(main_elements), fdi_lzx_read_lens);
1727 BUILD_TABLE(MAINTREE);
1728 if (LENTABLE(MAINTREE)[0xE8] != 0) LZX(intel_started) = 1;
1730 READ_LENGTHS(LENGTH, 0, LZX_NUM_SECONDARY_LENGTHS, fdi_lzx_read_lens);
1731 BUILD_TABLE(LENGTH);
1732 break;
1734 case LZX_BLOCKTYPE_UNCOMPRESSED:
1735 LZX(intel_started) = 1; /* because we can't assume otherwise */
1736 ENSURE_BITS(16); /* get up to 16 pad bits into the buffer */
1737 if (bitsleft > 16) inpos -= 2; /* and align the bitstream! */
1738 R0 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
1739 R1 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
1740 R2 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
1741 break;
1743 default:
1744 return DECR_ILLEGALDATA;
1748 /* buffer exhaustion check */
1749 if (inpos > endinp) {
1750 /* it's possible to have a file where the next run is less than
1751 * 16 bits in size. In this case, the READ_HUFFSYM() macro used
1752 * in building the tables will exhaust the buffer, so we should
1753 * allow for this, but not allow those accidentally read bits to
1754 * be used (so we check that there are at least 16 bits
1755 * remaining - in this boundary case they aren't really part of
1756 * the compressed data)
1758 if (inpos > (endinp+2) || bitsleft < 16) return DECR_ILLEGALDATA;
1761 while ((this_run = LZX(block_remaining)) > 0 && togo > 0) {
1762 if (this_run > togo) this_run = togo;
1763 togo -= this_run;
1764 LZX(block_remaining) -= this_run;
1766 /* apply 2^x-1 mask */
1767 window_posn &= window_size - 1;
1768 /* runs can't straddle the window wraparound */
1769 if ((window_posn + this_run) > window_size)
1770 return DECR_DATAFORMAT;
1772 switch (LZX(block_type)) {
1774 case LZX_BLOCKTYPE_VERBATIM:
1775 while (this_run > 0) {
1776 READ_HUFFSYM(MAINTREE, main_element);
1778 if (main_element < LZX_NUM_CHARS) {
1779 /* literal: 0 to LZX_NUM_CHARS-1 */
1780 window[window_posn++] = main_element;
1781 this_run--;
1783 else {
1784 /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
1785 main_element -= LZX_NUM_CHARS;
1787 match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
1788 if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
1789 READ_HUFFSYM(LENGTH, length_footer);
1790 match_length += length_footer;
1792 match_length += LZX_MIN_MATCH;
1794 match_offset = main_element >> 3;
1796 if (match_offset > 2) {
1797 /* not repeated offset */
1798 if (match_offset != 3) {
1799 extra = CAB(extra_bits)[match_offset];
1800 READ_BITS(verbatim_bits, extra);
1801 match_offset = CAB(lzx_position_base)[match_offset]
1802 - 2 + verbatim_bits;
1804 else {
1805 match_offset = 1;
1808 /* update repeated offset LRU queue */
1809 R2 = R1; R1 = R0; R0 = match_offset;
1811 else if (match_offset == 0) {
1812 match_offset = R0;
1814 else if (match_offset == 1) {
1815 match_offset = R1;
1816 R1 = R0; R0 = match_offset;
1818 else /* match_offset == 2 */ {
1819 match_offset = R2;
1820 R2 = R0; R0 = match_offset;
1823 rundest = window + window_posn;
1824 this_run -= match_length;
1826 /* copy any wrapped around source data */
1827 if (window_posn >= match_offset) {
1828 /* no wrap */
1829 runsrc = rundest - match_offset;
1830 } else {
1831 runsrc = rundest + (window_size - match_offset);
1832 copy_length = match_offset - window_posn;
1833 if (copy_length < match_length) {
1834 match_length -= copy_length;
1835 window_posn += copy_length;
1836 while (copy_length-- > 0) *rundest++ = *runsrc++;
1837 runsrc = window;
1840 window_posn += match_length;
1842 /* copy match data - no worries about destination wraps */
1843 while (match_length-- > 0) *rundest++ = *runsrc++;
1846 break;
1848 case LZX_BLOCKTYPE_ALIGNED:
1849 while (this_run > 0) {
1850 READ_HUFFSYM(MAINTREE, main_element);
1852 if (main_element < LZX_NUM_CHARS) {
1853 /* literal: 0 to LZX_NUM_CHARS-1 */
1854 window[window_posn++] = main_element;
1855 this_run--;
1857 else {
1858 /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
1859 main_element -= LZX_NUM_CHARS;
1861 match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
1862 if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
1863 READ_HUFFSYM(LENGTH, length_footer);
1864 match_length += length_footer;
1866 match_length += LZX_MIN_MATCH;
1868 match_offset = main_element >> 3;
1870 if (match_offset > 2) {
1871 /* not repeated offset */
1872 extra = CAB(extra_bits)[match_offset];
1873 match_offset = CAB(lzx_position_base)[match_offset] - 2;
1874 if (extra > 3) {
1875 /* verbatim and aligned bits */
1876 extra -= 3;
1877 READ_BITS(verbatim_bits, extra);
1878 match_offset += (verbatim_bits << 3);
1879 READ_HUFFSYM(ALIGNED, aligned_bits);
1880 match_offset += aligned_bits;
1882 else if (extra == 3) {
1883 /* aligned bits only */
1884 READ_HUFFSYM(ALIGNED, aligned_bits);
1885 match_offset += aligned_bits;
1887 else if (extra > 0) { /* extra==1, extra==2 */
1888 /* verbatim bits only */
1889 READ_BITS(verbatim_bits, extra);
1890 match_offset += verbatim_bits;
1892 else /* extra == 0 */ {
1893 /* ??? */
1894 match_offset = 1;
1897 /* update repeated offset LRU queue */
1898 R2 = R1; R1 = R0; R0 = match_offset;
1900 else if (match_offset == 0) {
1901 match_offset = R0;
1903 else if (match_offset == 1) {
1904 match_offset = R1;
1905 R1 = R0; R0 = match_offset;
1907 else /* match_offset == 2 */ {
1908 match_offset = R2;
1909 R2 = R0; R0 = match_offset;
1912 rundest = window + window_posn;
1913 this_run -= match_length;
1915 /* copy any wrapped around source data */
1916 if (window_posn >= match_offset) {
1917 /* no wrap */
1918 runsrc = rundest - match_offset;
1919 } else {
1920 runsrc = rundest + (window_size - match_offset);
1921 copy_length = match_offset - window_posn;
1922 if (copy_length < match_length) {
1923 match_length -= copy_length;
1924 window_posn += copy_length;
1925 while (copy_length-- > 0) *rundest++ = *runsrc++;
1926 runsrc = window;
1929 window_posn += match_length;
1931 /* copy match data - no worries about destination wraps */
1932 while (match_length-- > 0) *rundest++ = *runsrc++;
1935 break;
1937 case LZX_BLOCKTYPE_UNCOMPRESSED:
1938 if ((inpos + this_run) > endinp) return DECR_ILLEGALDATA;
1939 memcpy(window + window_posn, inpos, (size_t) this_run);
1940 inpos += this_run; window_posn += this_run;
1941 break;
1943 default:
1944 return DECR_ILLEGALDATA; /* might as well */
1950 if (togo != 0) return DECR_ILLEGALDATA;
1951 memcpy(CAB(outbuf), window + ((!window_posn) ? window_size : window_posn) -
1952 outlen, (size_t) outlen);
1954 LZX(window_posn) = window_posn;
1955 LZX(R0) = R0;
1956 LZX(R1) = R1;
1957 LZX(R2) = R2;
1959 /* intel E8 decoding */
1960 if ((LZX(frames_read)++ < 32768) && LZX(intel_filesize) != 0) {
1961 if (outlen <= 6 || !LZX(intel_started)) {
1962 LZX(intel_curpos) += outlen;
1964 else {
1965 cab_UBYTE *data = CAB(outbuf);
1966 cab_UBYTE *dataend = data + outlen - 10;
1967 cab_LONG curpos = LZX(intel_curpos);
1968 cab_LONG filesize = LZX(intel_filesize);
1969 cab_LONG abs_off, rel_off;
1971 LZX(intel_curpos) = curpos + outlen;
1973 while (data < dataend) {
1974 if (*data++ != 0xE8) { curpos++; continue; }
1975 abs_off = data[0] | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);
1976 if ((abs_off >= -curpos) && (abs_off < filesize)) {
1977 rel_off = (abs_off >= 0) ? abs_off - curpos : abs_off + filesize;
1978 data[0] = (cab_UBYTE) rel_off;
1979 data[1] = (cab_UBYTE) (rel_off >> 8);
1980 data[2] = (cab_UBYTE) (rel_off >> 16);
1981 data[3] = (cab_UBYTE) (rel_off >> 24);
1983 data += 4;
1984 curpos += 5;
1988 return DECR_OK;
1991 /**********************************************************
1992 * fdi_decomp (internal)
1994 * Decompress the requested number of bytes. If savemode is zero,
1995 * do not save the output anywhere, just plow through blocks until we
1996 * reach the specified (uncompressed) distance from the starting point,
1997 * and remember the position of the cabfile pointer (and which cabfile)
1998 * after we are done; otherwise, save the data out to CAB(filehf),
1999 * decompressing the requested number of bytes and writing them out. This
2000 * is also where we jump to additional cabinets in the case of split
2001 * cab's, and provide (some of) the NEXT_CABINET notification semantics.
2003 static int fdi_decomp(const struct fdi_file *fi, int savemode, fdi_decomp_state *decomp_state,
2004 char *pszCabPath, PFNFDINOTIFY pfnfdin, void *pvUser)
2006 cab_ULONG bytes = savemode ? fi->length : fi->offset - CAB(offset);
2007 cab_UBYTE buf[cfdata_SIZEOF], *data;
2008 cab_UWORD inlen, len, outlen, cando;
2009 cab_ULONG cksum;
2010 cab_LONG err;
2011 fdi_decomp_state *cab = (savemode && CAB(decomp_cab)) ? CAB(decomp_cab) : decomp_state;
2013 TRACE("(fi == ^%p, savemode == %d, bytes == %d)\n", fi, savemode, bytes);
2015 while (bytes > 0) {
2016 /* cando = the max number of bytes we can do */
2017 cando = CAB(outlen);
2018 if (cando > bytes) cando = bytes;
2020 /* if cando != 0 */
2021 if (cando && savemode)
2022 CAB(fdi)->write(CAB(filehf), CAB(outpos), cando);
2024 CAB(outpos) += cando;
2025 CAB(outlen) -= cando;
2026 bytes -= cando; if (!bytes) break;
2028 /* we only get here if we emptied the output buffer */
2030 /* read data header + data */
2031 inlen = outlen = 0;
2032 while (outlen == 0) {
2033 /* read the block header, skip the reserved part */
2034 if (CAB(fdi)->read(cab->cabhf, buf, cfdata_SIZEOF) != cfdata_SIZEOF)
2035 return DECR_INPUT;
2037 if (CAB(fdi)->seek(cab->cabhf, cab->mii.block_resv, SEEK_CUR) == -1)
2038 return DECR_INPUT;
2040 /* we shouldn't get blocks over CAB_INPUTMAX in size */
2041 data = CAB(inbuf) + inlen;
2042 len = EndGetI16(buf+cfdata_CompressedSize);
2043 inlen += len;
2044 if (inlen > CAB_INPUTMAX) return DECR_INPUT;
2045 if (CAB(fdi)->read(cab->cabhf, data, len) != len)
2046 return DECR_INPUT;
2048 /* clear two bytes after read-in data */
2049 data[len+1] = data[len+2] = 0;
2051 /* perform checksum test on the block (if one is stored) */
2052 cksum = EndGetI32(buf+cfdata_CheckSum);
2053 if (cksum && cksum != checksum(buf+4, 4, checksum(data, len, 0)))
2054 return DECR_CHECKSUM; /* checksum is wrong */
2056 outlen = EndGetI16(buf+cfdata_UncompressedSize);
2058 /* outlen=0 means this block was the last contiguous part
2059 of a split block, continued in the next cabinet */
2060 if (outlen == 0) {
2061 int pathlen, filenamelen, idx, i;
2062 INT_PTR cabhf;
2063 char fullpath[MAX_PATH], userpath[256];
2064 FDINOTIFICATION fdin;
2065 FDICABINETINFO fdici;
2066 char emptystring = '\0';
2067 cab_UBYTE buf2[64];
2068 int success = FALSE;
2069 struct fdi_folder *fol = NULL, *linkfol = NULL;
2070 struct fdi_file *file = NULL, *linkfile = NULL;
2072 tryanothercab:
2074 /* set up the next decomp_state... */
2075 if (!(cab->next)) {
2076 if (!cab->mii.hasnext) return DECR_INPUT;
2078 if (!((cab->next = CAB(fdi)->alloc(sizeof(fdi_decomp_state)))))
2079 return DECR_NOMEMORY;
2081 ZeroMemory(cab->next, sizeof(fdi_decomp_state));
2083 /* copy pszCabPath to userpath */
2084 ZeroMemory(userpath, 256);
2085 pathlen = (pszCabPath) ? strlen(pszCabPath) : 0;
2086 if (pathlen) {
2087 if (pathlen < 256) {
2088 for (i = 0; i <= pathlen; i++)
2089 userpath[i] = pszCabPath[i];
2090 } /* else we are in a weird place... let's leave it blank and see if the user fixes it */
2093 /* initial fdintNEXT_CABINET notification */
2094 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2095 fdin.psz1 = (cab->mii.nextname) ? cab->mii.nextname : &emptystring;
2096 fdin.psz2 = (cab->mii.nextinfo) ? cab->mii.nextinfo : &emptystring;
2097 fdin.psz3 = &userpath[0];
2098 fdin.fdie = FDIERROR_NONE;
2099 fdin.pv = pvUser;
2101 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2103 do {
2105 pathlen = strlen(userpath);
2106 filenamelen = (cab->mii.nextname) ? strlen(cab->mii.nextname) : 0;
2108 /* slight overestimation here to save CPU cycles in the developer's brain */
2109 if ((pathlen + filenamelen + 3) > MAX_PATH) {
2110 ERR("MAX_PATH exceeded.\n");
2111 return DECR_ILLEGALDATA;
2114 /* paste the path and filename together */
2115 idx = 0;
2116 if (pathlen) {
2117 for (i = 0; i < pathlen; i++) fullpath[idx++] = userpath[i];
2118 if (fullpath[idx - 1] != '\\') fullpath[idx++] = '\\';
2120 if (filenamelen) for (i = 0; i < filenamelen; i++) fullpath[idx++] = cab->mii.nextname[i];
2121 fullpath[idx] = '\0';
2123 TRACE("full cab path/file name: %s\n", debugstr_a(fullpath));
2125 /* try to get a handle to the cabfile */
2126 cabhf = CAB(fdi)->open(fullpath, _O_RDONLY|_O_BINARY, _S_IREAD | _S_IWRITE);
2127 if (cabhf == -1) {
2128 /* no file. allow the user to try again */
2129 fdin.fdie = FDIERROR_CABINET_NOT_FOUND;
2130 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2131 continue;
2134 if (cabhf == 0) {
2135 ERR("PFDI_OPEN returned zero for %s.\n", fullpath);
2136 fdin.fdie = FDIERROR_CABINET_NOT_FOUND;
2137 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2138 continue;
2141 /* check if it's really a cabfile. Note that this doesn't implement the bug */
2142 if (!FDI_read_entries(CAB(fdi), cabhf, &fdici, &(cab->next->mii))) {
2143 WARN("FDIIsCabinet failed.\n");
2144 CAB(fdi)->close(cabhf);
2145 fdin.fdie = FDIERROR_NOT_A_CABINET;
2146 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2147 continue;
2150 if ((fdici.setID != cab->setID) || (fdici.iCabinet != (cab->iCabinet + 1))) {
2151 WARN("Wrong Cabinet.\n");
2152 CAB(fdi)->close(cabhf);
2153 fdin.fdie = FDIERROR_WRONG_CABINET;
2154 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2155 continue;
2158 break;
2160 } while (1);
2162 /* cabinet notification */
2163 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2164 fdin.setID = fdici.setID;
2165 fdin.iCabinet = fdici.iCabinet;
2166 fdin.pv = pvUser;
2167 fdin.psz1 = (cab->next->mii.nextname) ? cab->next->mii.nextname : &emptystring;
2168 fdin.psz2 = (cab->next->mii.nextinfo) ? cab->next->mii.nextinfo : &emptystring;
2169 fdin.psz3 = pszCabPath;
2171 if (((*pfnfdin)(fdintCABINET_INFO, &fdin))) return DECR_USERABORT;
2173 cab->next->setID = fdici.setID;
2174 cab->next->iCabinet = fdici.iCabinet;
2175 cab->next->fdi = CAB(fdi);
2176 cab->next->filehf = CAB(filehf);
2177 cab->next->cabhf = cabhf;
2178 cab->next->decompress = CAB(decompress); /* crude, but unused anyhow */
2180 cab = cab->next; /* advance to the next cabinet */
2182 /* read folders */
2183 for (i = 0; i < fdici.cFolders; i++) {
2184 if (CAB(fdi)->read(cab->cabhf, buf2, cffold_SIZEOF) != cffold_SIZEOF)
2185 return DECR_INPUT;
2187 if (cab->mii.folder_resv > 0)
2188 CAB(fdi)->seek(cab->cabhf, cab->mii.folder_resv, SEEK_CUR);
2190 fol = CAB(fdi)->alloc(sizeof(struct fdi_folder));
2191 if (!fol) {
2192 ERR("out of memory!\n");
2193 return DECR_NOMEMORY;
2195 ZeroMemory(fol, sizeof(struct fdi_folder));
2196 if (!(cab->firstfol)) cab->firstfol = fol;
2198 fol->offset = (cab_off_t) EndGetI32(buf2+cffold_DataOffset);
2199 fol->num_blocks = EndGetI16(buf2+cffold_NumBlocks);
2200 fol->comp_type = EndGetI16(buf2+cffold_CompType);
2202 if (linkfol)
2203 linkfol->next = fol;
2204 linkfol = fol;
2207 /* read files */
2208 for (i = 0; i < fdici.cFiles; i++) {
2209 if (CAB(fdi)->read(cab->cabhf, buf2, cffile_SIZEOF) != cffile_SIZEOF)
2210 return DECR_INPUT;
2212 file = CAB(fdi)->alloc(sizeof(struct fdi_file));
2213 if (!file) {
2214 ERR("out of memory!\n");
2215 return DECR_NOMEMORY;
2217 ZeroMemory(file, sizeof(struct fdi_file));
2218 if (!(cab->firstfile)) cab->firstfile = file;
2220 file->length = EndGetI32(buf2+cffile_UncompressedSize);
2221 file->offset = EndGetI32(buf2+cffile_FolderOffset);
2222 file->index = EndGetI16(buf2+cffile_FolderIndex);
2223 file->time = EndGetI16(buf2+cffile_Time);
2224 file->date = EndGetI16(buf2+cffile_Date);
2225 file->attribs = EndGetI16(buf2+cffile_Attribs);
2226 file->filename = FDI_read_string(CAB(fdi), cab->cabhf, fdici.cbCabinet);
2228 if (!file->filename) return DECR_INPUT;
2230 if (linkfile)
2231 linkfile->next = file;
2232 linkfile = file;
2235 } else
2236 cab = cab->next; /* advance to the next cabinet */
2238 /* iterate files -- if we encounter the continued file, process it --
2239 otherwise, jump to the label above and keep looking */
2241 for (file = cab->firstfile; (file); file = file->next) {
2242 if ((file->index & cffileCONTINUED_FROM_PREV) == cffileCONTINUED_FROM_PREV) {
2243 /* check to ensure a real match */
2244 if (lstrcmpiA(fi->filename, file->filename) == 0) {
2245 success = TRUE;
2246 if (CAB(fdi)->seek(cab->cabhf, cab->firstfol->offset, SEEK_SET) == -1)
2247 return DECR_INPUT;
2248 break;
2252 if (!success) goto tryanothercab; /* FIXME: shouldn't this trigger
2253 "Wrong Cabinet" notification? */
2257 /* decompress block */
2258 if ((err = CAB(decompress)(inlen, outlen, decomp_state)))
2259 return err;
2260 CAB(outlen) = outlen;
2261 CAB(outpos) = CAB(outbuf);
2264 CAB(decomp_cab) = cab;
2265 return DECR_OK;
2268 static void free_decompression_temps(FDI_Int *fdi, const struct fdi_folder *fol,
2269 fdi_decomp_state *decomp_state)
2271 switch (fol->comp_type & cffoldCOMPTYPE_MASK) {
2272 case cffoldCOMPTYPE_LZX:
2273 if (LZX(window)) {
2274 fdi->free(LZX(window));
2275 LZX(window) = NULL;
2277 break;
2278 case cffoldCOMPTYPE_QUANTUM:
2279 if (QTM(window)) {
2280 fdi->free(QTM(window));
2281 QTM(window) = NULL;
2283 break;
2287 static void free_decompression_mem(FDI_Int *fdi,
2288 fdi_decomp_state *decomp_state, struct fdi_file *file)
2290 struct fdi_folder *fol;
2291 while (decomp_state) {
2292 fdi_decomp_state *prev_fds;
2294 fdi->close(CAB(cabhf));
2296 /* free the storage remembered by mii */
2297 if (CAB(mii).nextname) fdi->free(CAB(mii).nextname);
2298 if (CAB(mii).nextinfo) fdi->free(CAB(mii).nextinfo);
2299 if (CAB(mii).prevname) fdi->free(CAB(mii).prevname);
2300 if (CAB(mii).previnfo) fdi->free(CAB(mii).previnfo);
2302 while (CAB(firstfol)) {
2303 fol = CAB(firstfol);
2304 CAB(firstfol) = CAB(firstfol)->next;
2305 fdi->free(fol);
2307 while (CAB(firstfile)) {
2308 file = CAB(firstfile);
2309 if (file->filename) fdi->free(file->filename);
2310 CAB(firstfile) = CAB(firstfile)->next;
2311 fdi->free(file);
2313 prev_fds = decomp_state;
2314 decomp_state = CAB(next);
2315 fdi->free(prev_fds);
2319 /***********************************************************************
2320 * FDICopy (CABINET.22)
2322 * Iterates through the files in the Cabinet file indicated by name and
2323 * file-location. May chain forward to additional cabinets (typically
2324 * only one) if files which begin in this Cabinet are continued in another
2325 * cabinet. For each file which is partially contained in this cabinet,
2326 * and partially contained in a prior cabinet, provides fdintPARTIAL_FILE
2327 * notification to the pfnfdin callback. For each file which begins in
2328 * this cabinet, fdintCOPY_FILE notification is provided to the pfnfdin
2329 * callback, and the file is optionally decompressed and saved to disk.
2330 * Notification is not provided for files which are not at least partially
2331 * contained in the specified cabinet file.
2333 * See below for a thorough explanation of the various notification
2334 * callbacks.
2336 * PARAMS
2337 * hfdi [I] An HFDI from FDICreate
2338 * pszCabinet [I] C-style string containing the filename of the cabinet
2339 * pszCabPath [I] C-style string containing the file path of the cabinet
2340 * flags [I] "Decoder parameters". Ignored. Suggested value: 0.
2341 * pfnfdin [I] Pointer to a notification function. See CALLBACKS below.
2342 * pfnfdid [I] Pointer to a decryption function. Ignored. Suggested
2343 * value: NULL.
2344 * pvUser [I] arbitrary void * value which is passed to callbacks.
2346 * RETURNS
2347 * TRUE if successful.
2348 * FALSE if unsuccessful (error information is provided in the ERF structure
2349 * associated with the provided decompression handle by FDICreate).
2351 * CALLBACKS
2353 * Two pointers to callback functions are provided as parameters to FDICopy:
2354 * pfnfdin(of type PFNFDINOTIFY), and pfnfdid (of type PFNFDIDECRYPT). These
2355 * types are as follows:
2357 * typedef INT_PTR (__cdecl *PFNFDINOTIFY) ( FDINOTIFICATIONTYPE fdint,
2358 * PFDINOTIFICATION pfdin );
2360 * typedef int (__cdecl *PFNFDIDECRYPT) ( PFDIDECRYPT pfdid );
2362 * You can create functions of this type using the FNFDINOTIFY() and
2363 * FNFDIDECRYPT() macros, respectively. For example:
2365 * FNFDINOTIFY(mycallback) {
2366 * / * use variables fdint and pfdin to process notification * /
2369 * The second callback, which could be used for decrypting encrypted data,
2370 * is not used at all.
2372 * Each notification informs the user of some event which has occurred during
2373 * decompression of the cabinet file; each notification is also an opportunity
2374 * for the callee to abort decompression. The information provided to the
2375 * callback and the meaning of the callback's return value vary drastically
2376 * across the various types of notification. The type of notification is the
2377 * fdint parameter; all other information is provided to the callback in
2378 * notification-specific parts of the FDINOTIFICATION structure pointed to by
2379 * pfdin. The only part of that structure which is assigned for every callback
2380 * is the pv element, which contains the arbitrary value which was passed to
2381 * FDICopy in the pvUser argument (psz1 is also used each time, but its meaning
2382 * is highly dependent on fdint).
2384 * If you encounter unknown notifications, you should return zero if you want
2385 * decompression to continue (or -1 to abort). All strings used in the
2386 * callbacks are regular C-style strings. Detailed descriptions of each
2387 * notification type follow:
2389 * fdintCABINET_INFO:
2391 * This is the first notification provided after calling FDICopy, and provides
2392 * the user with various information about the cabinet. Note that this is
2393 * called for each cabinet FDICopy opens, not just the first one. In the
2394 * structure pointed to by pfdin, psz1 contains a pointer to the name of the
2395 * next cabinet file in the set after the one just loaded (if any), psz2
2396 * contains a pointer to the name or "info" of the next disk, psz3
2397 * contains a pointer to the file-path of the current cabinet, setID
2398 * contains an arbitrary constant associated with this set of cabinet files,
2399 * and iCabinet contains the numerical index of the current cabinet within
2400 * that set. Return zero, or -1 to abort.
2402 * fdintPARTIAL_FILE:
2404 * This notification is provided when FDICopy encounters a part of a file
2405 * contained in this cabinet which is missing its beginning. Files can be
2406 * split across cabinets, so this is not necessarily an abnormality; it just
2407 * means that the file in question begins in another cabinet. No file
2408 * corresponding to this notification is extracted from the cabinet. In the
2409 * structure pointed to by pfdin, psz1 contains a pointer to the name of the
2410 * partial file, psz2 contains a pointer to the file name of the cabinet in
2411 * which this file begins, and psz3 contains a pointer to the disk name or
2412 * "info" of the cabinet where the file begins. Return zero, or -1 to abort.
2414 * fdintCOPY_FILE:
2416 * This notification is provided when FDICopy encounters a file which starts
2417 * in the cabinet file, provided to FDICopy in pszCabinet. (FDICopy will not
2418 * look for files in cabinets after the first one). One notification will be
2419 * sent for each such file, before the file is decompressed. By returning
2420 * zero, the callback can instruct FDICopy to skip the file. In the structure
2421 * pointed to by pfdin, psz1 contains a pointer to the file's name, cb contains
2422 * the size of the file (uncompressed), attribs contains the file attributes,
2423 * and date and time contain the date and time of the file. attributes, date,
2424 * and time are of the 16-bit ms-dos variety. Return -1 to abort decompression
2425 * for the entire cabinet, 0 to skip just this file but continue scanning the
2426 * cabinet for more files, or an FDIClose()-compatible file-handle.
2428 * fdintCLOSE_FILE_INFO:
2430 * This notification is important, don't forget to implement it. This
2431 * notification indicates that a file has been successfully uncompressed and
2432 * written to disk. Upon receipt of this notification, the callee is expected
2433 * to close the file handle, to set the attributes and date/time of the
2434 * closed file, and possibly to execute the file. In the structure pointed to
2435 * by pfdin, psz1 contains a pointer to the name of the file, hf will be the
2436 * open file handle (close it), cb contains 1 or zero, indicating respectively
2437 * that the callee should or should not execute the file, and date, time
2438 * and attributes will be set as in fdintCOPY_FILE. Bizarrely, the Cabinet SDK
2439 * specifies that _A_EXEC will be xor'ed out of attributes! wine does not do
2440 * do so. Return TRUE, or FALSE to abort decompression.
2442 * fdintNEXT_CABINET:
2444 * This notification is called when FDICopy must load in another cabinet. This
2445 * can occur when a file's data is "split" across multiple cabinets. The
2446 * callee has the opportunity to request that FDICopy look in a different file
2447 * path for the specified cabinet file, by writing that data into a provided
2448 * buffer (see below for more information). This notification will be received
2449 * more than once per-cabinet in the instance that FDICopy failed to find a
2450 * valid cabinet at the location specified by the first per-cabinet
2451 * fdintNEXT_CABINET notification. In such instances, the fdie element of the
2452 * structure pointed to by pfdin indicates the error which prevented FDICopy
2453 * from proceeding successfully. Return zero to indicate success, or -1 to
2454 * indicate failure and abort FDICopy.
2456 * Upon receipt of this notification, the structure pointed to by pfdin will
2457 * contain the following values: psz1 pointing to the name of the cabinet
2458 * which FDICopy is attempting to open, psz2 pointing to the name ("info") of
2459 * the next disk, psz3 pointing to the presumed file-location of the cabinet,
2460 * and fdie containing either FDIERROR_NONE, or one of the following:
2462 * FDIERROR_CABINET_NOT_FOUND, FDIERROR_NOT_A_CABINET,
2463 * FDIERROR_UNKNOWN_CABINET_VERSION, FDIERROR_CORRUPT_CABINET,
2464 * FDIERROR_BAD_COMPR_TYPE, FDIERROR_RESERVE_MISMATCH, and
2465 * FDIERROR_WRONG_CABINET.
2467 * The callee may choose to change the path where FDICopy will look for the
2468 * cabinet after this notification. To do so, the caller may write the new
2469 * pathname to the buffer pointed to by psz3, which is 256 characters in
2470 * length, including the terminating null character, before returning zero.
2472 * fdintENUMERATE:
2474 * Undocumented and unimplemented in wine, this seems to be sent each time
2475 * a cabinet is opened, along with the fdintCABINET_INFO notification. It
2476 * probably has an interface similar to that of fdintCABINET_INFO; maybe this
2477 * provides information about the current cabinet instead of the next one....
2478 * this is just a guess, it has not been looked at closely.
2480 * INCLUDES
2481 * fdi.c
2483 BOOL __cdecl FDICopy(
2484 HFDI hfdi,
2485 char *pszCabinet,
2486 char *pszCabPath,
2487 int flags,
2488 PFNFDINOTIFY pfnfdin,
2489 PFNFDIDECRYPT pfnfdid,
2490 void *pvUser)
2492 FDICABINETINFO fdici;
2493 FDINOTIFICATION fdin;
2494 INT_PTR cabhf, filehf = 0;
2495 int idx;
2496 unsigned int i;
2497 char fullpath[MAX_PATH];
2498 size_t pathlen, filenamelen;
2499 char emptystring = '\0';
2500 cab_UBYTE buf[64];
2501 struct fdi_folder *fol = NULL, *linkfol = NULL;
2502 struct fdi_file *file = NULL, *linkfile = NULL;
2503 fdi_decomp_state *decomp_state;
2504 FDI_Int *fdi = get_fdi_ptr( hfdi );
2506 TRACE("(hfdi == ^%p, pszCabinet == ^%p, pszCabPath == ^%p, flags == %0d, "
2507 "pfnfdin == ^%p, pfnfdid == ^%p, pvUser == ^%p)\n",
2508 hfdi, pszCabinet, pszCabPath, flags, pfnfdin, pfnfdid, pvUser);
2510 if (!fdi) return FALSE;
2512 if (!(decomp_state = fdi->alloc(sizeof(fdi_decomp_state))))
2514 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2515 return FALSE;
2517 ZeroMemory(decomp_state, sizeof(fdi_decomp_state));
2519 pathlen = (pszCabPath) ? strlen(pszCabPath) : 0;
2520 filenamelen = (pszCabinet) ? strlen(pszCabinet) : 0;
2522 /* slight overestimation here to save CPU cycles in the developer's brain */
2523 if ((pathlen + filenamelen + 3) > MAX_PATH) {
2524 ERR("MAX_PATH exceeded.\n");
2525 fdi->free(decomp_state);
2526 set_error( fdi, FDIERROR_CABINET_NOT_FOUND, ERROR_FILE_NOT_FOUND );
2527 return FALSE;
2530 /* paste the path and filename together */
2531 idx = 0;
2532 if (pathlen) {
2533 for (i = 0; i < pathlen; i++) fullpath[idx++] = pszCabPath[i];
2534 if (fullpath[idx - 1] != '\\') fullpath[idx++] = '\\';
2536 if (filenamelen) for (i = 0; i < filenamelen; i++) fullpath[idx++] = pszCabinet[i];
2537 fullpath[idx] = '\0';
2539 TRACE("full cab path/file name: %s\n", debugstr_a(fullpath));
2541 /* get a handle to the cabfile */
2542 cabhf = fdi->open(fullpath, _O_RDONLY|_O_BINARY, _S_IREAD | _S_IWRITE);
2543 if (cabhf == -1) {
2544 fdi->free(decomp_state);
2545 set_error( fdi, FDIERROR_CABINET_NOT_FOUND, 0 );
2546 SetLastError(ERROR_FILE_NOT_FOUND);
2547 return FALSE;
2550 if (cabhf == 0) {
2551 ERR("PFDI_OPEN returned zero for %s.\n", fullpath);
2552 fdi->free(decomp_state);
2553 set_error( fdi, FDIERROR_CABINET_NOT_FOUND, ERROR_FILE_NOT_FOUND );
2554 return FALSE;
2557 /* check if it's really a cabfile. Note that this doesn't implement the bug */
2558 if (!FDI_read_entries(fdi, cabhf, &fdici, &(CAB(mii)))) {
2559 ERR("FDIIsCabinet failed.\n");
2560 fdi->free(decomp_state);
2561 fdi->close(cabhf);
2562 return FALSE;
2565 /* cabinet notification */
2566 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2567 fdin.setID = fdici.setID;
2568 fdin.iCabinet = fdici.iCabinet;
2569 fdin.pv = pvUser;
2570 fdin.psz1 = (CAB(mii).nextname) ? CAB(mii).nextname : &emptystring;
2571 fdin.psz2 = (CAB(mii).nextinfo) ? CAB(mii).nextinfo : &emptystring;
2572 fdin.psz3 = pszCabPath;
2574 if (((*pfnfdin)(fdintCABINET_INFO, &fdin))) {
2575 set_error( fdi, FDIERROR_USER_ABORT, 0 );
2576 goto bail_and_fail;
2579 CAB(setID) = fdici.setID;
2580 CAB(iCabinet) = fdici.iCabinet;
2581 CAB(cabhf) = cabhf;
2583 /* read folders */
2584 for (i = 0; i < fdici.cFolders; i++) {
2585 if (fdi->read(cabhf, buf, cffold_SIZEOF) != cffold_SIZEOF) {
2586 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
2587 goto bail_and_fail;
2590 if (CAB(mii).folder_resv > 0)
2591 fdi->seek(cabhf, CAB(mii).folder_resv, SEEK_CUR);
2593 fol = fdi->alloc(sizeof(struct fdi_folder));
2594 if (!fol) {
2595 ERR("out of memory!\n");
2596 set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY );
2597 goto bail_and_fail;
2599 ZeroMemory(fol, sizeof(struct fdi_folder));
2600 if (!CAB(firstfol)) CAB(firstfol) = fol;
2602 fol->offset = (cab_off_t) EndGetI32(buf+cffold_DataOffset);
2603 fol->num_blocks = EndGetI16(buf+cffold_NumBlocks);
2604 fol->comp_type = EndGetI16(buf+cffold_CompType);
2606 if (linkfol)
2607 linkfol->next = fol;
2608 linkfol = fol;
2611 /* read files */
2612 for (i = 0; i < fdici.cFiles; i++) {
2613 if (fdi->read(cabhf, buf, cffile_SIZEOF) != cffile_SIZEOF) {
2614 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
2615 goto bail_and_fail;
2618 file = fdi->alloc(sizeof(struct fdi_file));
2619 if (!file) {
2620 ERR("out of memory!\n");
2621 set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY );
2622 goto bail_and_fail;
2624 ZeroMemory(file, sizeof(struct fdi_file));
2625 if (!CAB(firstfile)) CAB(firstfile) = file;
2627 file->length = EndGetI32(buf+cffile_UncompressedSize);
2628 file->offset = EndGetI32(buf+cffile_FolderOffset);
2629 file->index = EndGetI16(buf+cffile_FolderIndex);
2630 file->time = EndGetI16(buf+cffile_Time);
2631 file->date = EndGetI16(buf+cffile_Date);
2632 file->attribs = EndGetI16(buf+cffile_Attribs);
2633 file->filename = FDI_read_string(fdi, cabhf, fdici.cbCabinet);
2635 if (!file->filename) {
2636 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
2637 goto bail_and_fail;
2640 if (linkfile)
2641 linkfile->next = file;
2642 linkfile = file;
2645 for (file = CAB(firstfile); (file); file = file->next) {
2648 * FIXME: This implementation keeps multiple cabinet files open at once
2649 * when encountering a split cabinet. It is a quirk of this implementation
2650 * that sometimes we decrypt the same block of data more than once, to find
2651 * the right starting point for a file, moving the file-pointer backwards.
2652 * If we kept a cache of certain file-pointer information, we could eliminate
2653 * that behavior... in fact I am not sure that the caching we already have
2654 * is not sufficient.
2656 * The current implementation seems to work fine in straightforward situations
2657 * where all the cabinet files needed for decryption are simultaneously
2658 * available. But presumably, the API is supposed to support cabinets which
2659 * are split across multiple CDROMS; we may need to change our implementation
2660 * to strictly serialize it's file usage so that it opens only one cabinet
2661 * at a time. Some experimentation with Windows is needed to figure out the
2662 * precise semantics required. The relevant code is here and in fdi_decomp().
2665 /* partial-file notification */
2666 if ((file->index & cffileCONTINUED_FROM_PREV) == cffileCONTINUED_FROM_PREV) {
2668 * FIXME: Need to create a Cabinet with a single file spanning multiple files
2669 * and perform some tests to figure out the right behavior. The SDK says
2670 * FDICopy will notify the user of the filename and "disk name" (info) of
2671 * the cabinet where the spanning file /started/.
2673 * That would certainly be convenient for the API-user, who could abort,
2674 * everything (or parallelize, if that's allowed (it is in wine)), and call
2675 * FDICopy again with the provided filename, so as to avoid partial file
2676 * notification and successfully unpack. This task could be quite unpleasant
2677 * from wine's perspective: the information specifying the "start cabinet" for
2678 * a file is associated nowhere with the file header and is not to be found in
2679 * the cabinet header. We have only the index of the cabinet wherein the folder
2680 * begins, which contains the file. To find that cabinet, we must consider the
2681 * index of the current cabinet, and chain backwards, cabinet-by-cabinet (for
2682 * each cabinet refers to its "next" and "previous" cabinet only, like a linked
2683 * list).
2685 * Bear in mind that, in the spirit of CABINET.DLL, we must assume that any
2686 * cabinet other than the active one might be at another filepath than the
2687 * current one, or on another CDROM. This could get rather dicey, especially
2688 * if we imagine parallelized access to the FDICopy API.
2690 * The current implementation punts -- it just returns the previous cabinet and
2691 * it's info from the header of this cabinet. This provides the right answer in
2692 * 95% of the cases; its worth checking if Microsoft cuts the same corner before
2693 * we "fix" it.
2695 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2696 fdin.pv = pvUser;
2697 fdin.psz1 = (char *)file->filename;
2698 fdin.psz2 = (CAB(mii).prevname) ? CAB(mii).prevname : &emptystring;
2699 fdin.psz3 = (CAB(mii).previnfo) ? CAB(mii).previnfo : &emptystring;
2701 if (((*pfnfdin)(fdintPARTIAL_FILE, &fdin))) {
2702 set_error( fdi, FDIERROR_USER_ABORT, 0 );
2703 goto bail_and_fail;
2705 /* I don't think we are supposed to decompress partial files. This prevents it. */
2706 file->oppressed = TRUE;
2708 if (file->oppressed) {
2709 filehf = 0;
2710 } else {
2711 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2712 fdin.pv = pvUser;
2713 fdin.psz1 = (char *)file->filename;
2714 fdin.cb = file->length;
2715 fdin.date = file->date;
2716 fdin.time = file->time;
2717 fdin.attribs = file->attribs;
2718 if ((filehf = ((*pfnfdin)(fdintCOPY_FILE, &fdin))) == -1) {
2719 set_error( fdi, FDIERROR_USER_ABORT, 0 );
2720 filehf = 0;
2721 goto bail_and_fail;
2725 /* find the folder for this file if necc. */
2726 if (filehf) {
2727 int i2;
2729 fol = CAB(firstfol);
2730 if ((file->index & cffileCONTINUED_TO_NEXT) == cffileCONTINUED_TO_NEXT) {
2731 /* pick the last folder */
2732 while (fol->next) fol = fol->next;
2733 } else {
2734 for (i2 = 0; (i2 < file->index); i2++)
2735 if (fol->next) /* bug resistance, should always be true */
2736 fol = fol->next;
2740 if (filehf) {
2741 cab_UWORD comptype = fol->comp_type;
2742 int ct1 = comptype & cffoldCOMPTYPE_MASK;
2743 int ct2 = CAB(current) ? (CAB(current)->comp_type & cffoldCOMPTYPE_MASK) : 0;
2744 int err = 0;
2746 TRACE("Extracting file %s as requested by callee.\n", debugstr_a(file->filename));
2748 /* set up decomp_state */
2749 CAB(fdi) = fdi;
2750 CAB(filehf) = filehf;
2752 /* Was there a change of folder? Compression type? Did we somehow go backwards? */
2753 if ((ct1 != ct2) || (CAB(current) != fol) || (file->offset < CAB(offset))) {
2755 TRACE("Resetting folder for file %s.\n", debugstr_a(file->filename));
2757 /* free stuff for the old decompresser */
2758 switch (ct2) {
2759 case cffoldCOMPTYPE_LZX:
2760 if (LZX(window)) {
2761 fdi->free(LZX(window));
2762 LZX(window) = NULL;
2764 break;
2765 case cffoldCOMPTYPE_QUANTUM:
2766 if (QTM(window)) {
2767 fdi->free(QTM(window));
2768 QTM(window) = NULL;
2770 break;
2773 CAB(decomp_cab) = NULL;
2774 CAB(fdi)->seek(CAB(cabhf), fol->offset, SEEK_SET);
2775 CAB(offset) = 0;
2776 CAB(outlen) = 0;
2778 /* initialize the new decompresser */
2779 switch (ct1) {
2780 case cffoldCOMPTYPE_NONE:
2781 CAB(decompress) = NONEfdi_decomp;
2782 break;
2783 case cffoldCOMPTYPE_MSZIP:
2784 CAB(decompress) = ZIPfdi_decomp;
2785 break;
2786 case cffoldCOMPTYPE_QUANTUM:
2787 CAB(decompress) = QTMfdi_decomp;
2788 err = QTMfdi_init((comptype >> 8) & 0x1f, (comptype >> 4) & 0xF, decomp_state);
2789 break;
2790 case cffoldCOMPTYPE_LZX:
2791 CAB(decompress) = LZXfdi_decomp;
2792 err = LZXfdi_init((comptype >> 8) & 0x1f, decomp_state);
2793 break;
2794 default:
2795 err = DECR_DATAFORMAT;
2799 CAB(current) = fol;
2801 switch (err) {
2802 case DECR_OK:
2803 break;
2804 case DECR_NOMEMORY:
2805 set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY );
2806 goto bail_and_fail;
2807 default:
2808 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
2809 goto bail_and_fail;
2812 if (file->offset > CAB(offset)) {
2813 /* decode bytes and send them to /dev/null */
2814 switch (fdi_decomp(file, 0, decomp_state, pszCabPath, pfnfdin, pvUser)) {
2815 case DECR_OK:
2816 break;
2817 case DECR_USERABORT:
2818 set_error( fdi, FDIERROR_USER_ABORT, 0 );
2819 goto bail_and_fail;
2820 case DECR_NOMEMORY:
2821 set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY );
2822 goto bail_and_fail;
2823 default:
2824 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
2825 goto bail_and_fail;
2827 CAB(offset) = file->offset;
2830 /* now do the actual decompression */
2831 err = fdi_decomp(file, 1, decomp_state, pszCabPath, pfnfdin, pvUser);
2832 if (err) CAB(current) = NULL; else CAB(offset) += file->length;
2834 /* fdintCLOSE_FILE_INFO notification */
2835 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2836 fdin.pv = pvUser;
2837 fdin.psz1 = (char *)file->filename;
2838 fdin.hf = filehf;
2839 fdin.cb = (file->attribs & cffile_A_EXEC) ? TRUE : FALSE; /* FIXME: is that right? */
2840 fdin.date = file->date;
2841 fdin.time = file->time;
2842 fdin.attribs = file->attribs; /* FIXME: filter _A_EXEC? */
2843 ((*pfnfdin)(fdintCLOSE_FILE_INFO, &fdin));
2844 filehf = 0;
2846 switch (err) {
2847 case DECR_OK:
2848 break;
2849 case DECR_USERABORT:
2850 set_error( fdi, FDIERROR_USER_ABORT, 0 );
2851 goto bail_and_fail;
2852 case DECR_NOMEMORY:
2853 set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY );
2854 goto bail_and_fail;
2855 default:
2856 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
2857 goto bail_and_fail;
2862 free_decompression_temps(fdi, fol, decomp_state);
2863 free_decompression_mem(fdi, decomp_state, file);
2865 return TRUE;
2867 bail_and_fail: /* here we free ram before error returns */
2869 if (fol) free_decompression_temps(fdi, fol, decomp_state);
2871 if (filehf) fdi->close(filehf);
2873 free_decompression_mem(fdi, decomp_state, file);
2875 return FALSE;
2878 /***********************************************************************
2879 * FDIDestroy (CABINET.23)
2881 * Frees a handle created by FDICreate. Do /not/ call this in the middle
2882 * of FDICopy. Only reason for failure would be an invalid handle.
2884 * PARAMS
2885 * hfdi [I] The HFDI to free
2887 * RETURNS
2888 * TRUE for success
2889 * FALSE for failure
2891 BOOL __cdecl FDIDestroy(HFDI hfdi)
2893 FDI_Int *fdi = get_fdi_ptr( hfdi );
2895 TRACE("(hfdi == ^%p)\n", hfdi);
2896 if (!fdi) return FALSE;
2897 fdi->magic = 0; /* paranoia */
2898 fdi->free(fdi);
2899 return TRUE;
2902 /***********************************************************************
2903 * FDITruncateCabinet (CABINET.24)
2905 * Removes all folders of a cabinet file after and including the
2906 * specified folder number.
2908 * PARAMS
2909 * hfdi [I] Handle to the FDI context.
2910 * pszCabinetName [I] Filename of the cabinet.
2911 * iFolderToDelete [I] Index of the first folder to delete.
2913 * RETURNS
2914 * Success: TRUE.
2915 * Failure: FALSE.
2917 * NOTES
2918 * The PFNWRITE function supplied to FDICreate must truncate the
2919 * file at the current position if the number of bytes to write is 0.
2921 BOOL __cdecl FDITruncateCabinet(
2922 HFDI hfdi,
2923 char *pszCabinetName,
2924 USHORT iFolderToDelete)
2926 FDI_Int *fdi = get_fdi_ptr( hfdi );
2928 FIXME("(hfdi == ^%p, pszCabinetName == %s, iFolderToDelete == %hu): stub\n",
2929 hfdi, debugstr_a(pszCabinetName), iFolderToDelete);
2931 if (!fdi) return FALSE;
2933 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2934 return FALSE;