1 /*
2 * File Decompression Interface
3 *
4 * Copyright 2000-2002 Stuart Caie
5 * Copyright 2002 Patrik Stridvall
6 * Copyright 2003 Greg Turner
7 *
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.
12 *
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.
17 *
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
21 *
22 *
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.
31 *
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.
36 *
37 * TODO:
38 *
39 * Wine does not implement the AFAIK undocumented "enumerate" callback during
40 * FDICopy. It is implemented in Windows and therefore worth investigating...
41 *
42 * Lots of pointers flying around here... am I leaking RAM?
43 *
44 * WTF is FDITruncate?
45 *
46 * Probably, I need to weed out some dead code-paths.
47 *
48 * Test unit(s).
49 *
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.
54 *
55 * FDICopy and fdi_decomp are incomprehensibly large; separating these into smaller
56 * functions would be nice.
57 *
58 * -gmt
59 */
60
61 #include "config.h"
62
63 #include <stdarg.h>
64 #include <stdio.h>
65
66 #include "windef.h"
67 #include "winbase.h"
68 #include "winerror.h"
69 #include "fdi.h"
70 #include "cabinet.h"
71
72 #include "wine/debug.h"
73
74 WINE_DEFAULT_DEBUG_CHANNEL(cabinet);
75
76 THOSE_ZIP_CONSTS;
77
78 struct fdi_file {
79 struct fdi_file *next; /* next file in sequence */
80 LPCSTR 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 */
87 };
88
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 */
96 };
97
98 /*
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.
104 */
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;
112
113 /*
114 * ugh, well, this ended up being pretty damn silly...
115 * now that I've conceded to build equivalent structures to struct cab.*,
116 * I should have just used those, or, better yet, unified the two... sue me.
117 * (Note to Microsoft: That's a joke. Please /don't/ actually sue me! -gmt).
118 * Nevertheless, I've come this far, it works, so I'm not gonna change it
119 * for now. This implementation has significant semantic differences anyhow.
120 */
121
122 typedef struct fdi_cds_fwd {
123 void *hfdi; /* the hfdi we are using */
124 INT_PTR filehf, cabhf; /* file handle we are using */
125 struct fdi_folder *current; /* current folder we're extracting from */
126 cab_ULONG offset; /* uncompressed offset within folder */
127 cab_UBYTE *outpos; /* (high level) start of data to use up */
128 cab_UWORD outlen; /* (high level) amount of data to use up */
129 int (*decompress)(int, int, struct fdi_cds_fwd *); /* chosen compress fn */
130 cab_UBYTE inbuf[CAB_INPUTMAX+2]; /* +2 for lzx bitbuffer overflows! */
131 cab_UBYTE outbuf[CAB_BLOCKMAX];
132 union {
133 struct ZIPstate zip;
134 struct QTMstate qtm;
135 struct LZXstate lzx;
136 } methods;
137 /* some temp variables for use during decompression */
138 cab_UBYTE q_length_base[27], q_length_extra[27], q_extra_bits[42];
139 cab_ULONG q_position_base[42];
140 cab_ULONG lzx_position_base[51];
141 cab_UBYTE extra_bits[51];
142 USHORT setID; /* Cabinet set ID */
143 USHORT iCabinet; /* Cabinet number in set (0 based) */
144 struct fdi_cds_fwd *decomp_cab;
145 MORE_ISCAB_INFO mii;
146 struct fdi_folder *firstfol;
147 struct fdi_file *firstfile;
148 struct fdi_cds_fwd *next;
149 } fdi_decomp_state;
150
151 /****************************************************************
152 * QTMupdatemodel (internal)
153 */
154 void QTMupdatemodel(struct QTMmodel *model, int sym) {
155 struct QTMmodelsym temp;
156 int i, j;
157
158 for (i = 0; i < sym; i++) model->syms[i].cumfreq += 8;
159
160 if (model->syms[0].cumfreq > 3800) {
161 if (--model->shiftsleft) {
162 for (i = model->entries - 1; i >= 0; i--) {
163 /* -1, not -2; the 0 entry saves this */
164 model->syms[i].cumfreq >>= 1;
165 if (model->syms[i].cumfreq <= model->syms[i+1].cumfreq) {
166 model->syms[i].cumfreq = model->syms[i+1].cumfreq + 1;
167 }
168 }
169 }
170 else {
171 model->shiftsleft = 50;
172 for (i = 0; i < model->entries ; i++) {
173 /* no -1, want to include the 0 entry */
174 /* this converts cumfreqs into frequencies, then shifts right */
175 model->syms[i].cumfreq -= model->syms[i+1].cumfreq;
176 model->syms[i].cumfreq++; /* avoid losing things entirely */
177 model->syms[i].cumfreq >>= 1;
178 }
179
180 /* now sort by frequencies, decreasing order -- this must be an
181 * inplace selection sort, or a sort with the same (in)stability
182 * characteristics
183 */
184 for (i = 0; i < model->entries - 1; i++) {
185 for (j = i + 1; j < model->entries; j++) {
186 if (model->syms[i].cumfreq < model->syms[j].cumfreq) {
187 temp = model->syms[i];
188 model->syms[i] = model->syms[j];
189 model->syms[j] = temp;
190 }
191 }
192 }
193
194 /* then convert frequencies back to cumfreq */
195 for (i = model->entries - 1; i >= 0; i--) {
196 model->syms[i].cumfreq += model->syms[i+1].cumfreq;
197 }
198 /* then update the other part of the table */
199 for (i = 0; i < model->entries; i++) {
200 model->tabloc[model->syms[i].sym] = i;
201 }
202 }
203 }
204 }
205
206 /*************************************************************************
207 * make_decode_table (internal)
208 *
209 * This function was coded by David Tritscher. It builds a fast huffman
210 * decoding table out of just a canonical huffman code lengths table.
211 *
212 * PARAMS
213 * nsyms: total number of symbols in this huffman tree.
214 * nbits: any symbols with a code length of nbits or less can be decoded
215 * in one lookup of the table.
216 * length: A table to get code lengths from [0 to syms-1]
217 * table: The table to fill up with decoded symbols and pointers.
218 *
219 * RETURNS
220 * OK: 0
221 * error: 1
222 */
223 int make_decode_table(cab_ULONG nsyms, cab_ULONG nbits, const cab_UBYTE *length, cab_UWORD *table) {
224 register cab_UWORD sym;
225 register cab_ULONG leaf;
226 register cab_UBYTE bit_num = 1;
227 cab_ULONG fill;
228 cab_ULONG pos = 0; /* the current position in the decode table */
229 cab_ULONG table_mask = 1 << nbits;
230 cab_ULONG bit_mask = table_mask >> 1; /* don't do 0 length codes */
231 cab_ULONG next_symbol = bit_mask; /* base of allocation for long codes */
232
233 /* fill entries for codes short enough for a direct mapping */
234 while (bit_num <= nbits) {
235 for (sym = 0; sym < nsyms; sym++) {
236 if (length[sym] == bit_num) {
237 leaf = pos;
238
239 if((pos += bit_mask) > table_mask) return 1; /* table overrun */
240
241 /* fill all possible lookups of this symbol with the symbol itself */
242 fill = bit_mask;
243 while (fill-- > 0) table[leaf++] = sym;
244 }
245 }
246 bit_mask >>= 1;
247 bit_num++;
248 }
249
250 /* if there are any codes longer than nbits */
251 if (pos != table_mask) {
252 /* clear the remainder of the table */
253 for (sym = pos; sym < table_mask; sym++) table[sym] = 0;
254
255 /* give ourselves room for codes to grow by up to 16 more bits */
256 pos <<= 16;
257 table_mask <<= 16;
258 bit_mask = 1 << 15;
259
260 while (bit_num <= 16) {
261 for (sym = 0; sym < nsyms; sym++) {
262 if (length[sym] == bit_num) {
263 leaf = pos >> 16;
264 for (fill = 0; fill < bit_num - nbits; fill++) {
265 /* if this path hasn't been taken yet, 'allocate' two entries */
266 if (table[leaf] == 0) {
267 table[(next_symbol << 1)] = 0;
268 table[(next_symbol << 1) + 1] = 0;
269 table[leaf] = next_symbol++;
270 }
271 /* follow the path and select either left or right for next bit */
272 leaf = table[leaf] << 1;
273 if ((pos >> (15-fill)) & 1) leaf++;
274 }
275 table[leaf] = sym;
276
277 if ((pos += bit_mask) > table_mask) return 1; /* table overflow */
278 }
279 }
280 bit_mask >>= 1;
281 bit_num++;
282 }
283 }
284
285 /* full table? */
286 if (pos == table_mask) return 0;
287
288 /* either erroneous table, or all elements are 0 - let's find out. */
289 for (sym = 0; sym < nsyms; sym++) if (length[sym]) return 1;
290 return 0;
291 }
292
293 /*************************************************************************
294 * checksum (internal)
295 */
296 cab_ULONG checksum(const cab_UBYTE *data, cab_UWORD bytes, cab_ULONG csum) {
297 int len;
298 cab_ULONG ul = 0;
299
300 for (len = bytes >> 2; len--; data += 4) {
301 csum ^= ((data[0]) | (data[1]<<8) | (data[2]<<16) | (data[3]<<24));
302 }
303
304 switch (bytes & 3) {
305 case 3: ul |= *data++ << 16;
306 case 2: ul |= *data++ << 8;
307 case 1: ul |= *data;
308 }
309 csum ^= ul;
310
311 return csum;
312 }
313
314 /***********************************************************************
315 * FDICreate (CABINET.20)
316 *
317 * Provided with several callbacks (all of them are mandatory),
318 * returns a handle which can be used to perform operations
319 * on cabinet files.
320 *
321 * PARAMS
322 * pfnalloc [I] A pointer to a function which allocates ram. Uses
323 * the same interface as malloc.
324 * pfnfree [I] A pointer to a function which frees ram. Uses the
325 * same interface as free.
326 * pfnopen [I] A pointer to a function which opens a file. Uses
327 * the same interface as _open.
328 * pfnread [I] A pointer to a function which reads from a file into
329 * a caller-provided buffer. Uses the same interface
330 * as _read
331 * pfnwrite [I] A pointer to a function which writes to a file from
332 * a caller-provided buffer. Uses the same interface
333 * as _write.
334 * pfnclose [I] A pointer to a function which closes a file handle.
335 * Uses the same interface as _close.
336 * pfnseek [I] A pointer to a function which seeks in a file.
337 * Uses the same interface as _lseek.
338 * cpuType [I] The type of CPU; ignored in wine (recommended value:
339 * cpuUNKNOWN, aka -1).
340 * perf [IO] A pointer to an ERF structure. When FDICreate
341 * returns an error condition, error information may
342 * be found here as well as from GetLastError.
343 *
344 * RETURNS
345 * On success, returns an FDI handle of type HFDI.
346 * On failure, the NULL file handle is returned. Error
347 * info can be retrieved from perf.
348 *
349 * INCLUDES
350 * fdi.h
351 *
352 */
353 HFDI __cdecl FDICreate(
354 PFNALLOC pfnalloc,
355 PFNFREE pfnfree,
356 PFNOPEN pfnopen,
357 PFNREAD pfnread,
358 PFNWRITE pfnwrite,
359 PFNCLOSE pfnclose,
360 PFNSEEK pfnseek,
361 int cpuType,
362 PERF perf)
363 {
364 HFDI rv;
365
366 TRACE("(pfnalloc == ^%p, pfnfree == ^%p, pfnopen == ^%p, pfnread == ^%p, pfnwrite == ^%p, "
367 "pfnclose == ^%p, pfnseek == ^%p, cpuType == %d, perf == ^%p)\n",
368 pfnalloc, pfnfree, pfnopen, pfnread, pfnwrite, pfnclose, pfnseek,
369 cpuType, perf);
370
371 if ((!pfnalloc) || (!pfnfree)) {
372 perf->erfOper = FDIERROR_NONE;
373 perf->erfType = ERROR_BAD_ARGUMENTS;
374 perf->fError = TRUE;
375
376 SetLastError(ERROR_BAD_ARGUMENTS);
377 return NULL;
378 }
379
380 if (!((rv = (*pfnalloc)(sizeof(FDI_Int))))) {
381 perf->erfOper = FDIERROR_ALLOC_FAIL;
382 perf->erfType = ERROR_NOT_ENOUGH_MEMORY;
383 perf->fError = TRUE;
384
385 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
386 return NULL;
387 }
388
389 PFDI_INT(rv)->FDI_Intmagic = FDI_INT_MAGIC;
390 PFDI_INT(rv)->pfnalloc = pfnalloc;
391 PFDI_INT(rv)->pfnfree = pfnfree;
392 PFDI_INT(rv)->pfnopen = pfnopen;
393 PFDI_INT(rv)->pfnread = pfnread;
394 PFDI_INT(rv)->pfnwrite = pfnwrite;
395 PFDI_INT(rv)->pfnclose = pfnclose;
396 PFDI_INT(rv)->pfnseek = pfnseek;
397 /* no-brainer: we ignore the cpu type; this is only used
398 for the 16-bit versions in Windows anyhow... */
399 PFDI_INT(rv)->perf = perf;
400
401 return rv;
402 }
403
404 /*******************************************************************
405 * FDI_getoffset (internal)
406 *
407 * returns the file pointer position of a file handle.
408 */
409 static long FDI_getoffset(HFDI hfdi, INT_PTR hf)
410 {
411 return PFDI_SEEK(hfdi, hf, 0L, SEEK_CUR);
412 }
413
414 /**********************************************************************
415 * FDI_read_string (internal)
416 *
417 * allocate and read an arbitrarily long string from the cabinet
418 */
419 static char *FDI_read_string(HFDI hfdi, INT_PTR hf, long cabsize)
420 {
421 size_t len=256,
422 base = FDI_getoffset(hfdi, hf),
423 maxlen = cabsize - base;
424 BOOL ok = FALSE;
425 unsigned int i;
426 cab_UBYTE *buf = NULL;
427
428 TRACE("(hfdi == ^%p, hf == %ld, cabsize == %ld)\n", hfdi, hf, cabsize);
429
430 do {
431 if (len > maxlen) len = maxlen;
432 if (!(buf = PFDI_ALLOC(hfdi, len))) break;
433 if (!PFDI_READ(hfdi, hf, buf, len)) break;
434
435 /* search for a null terminator in what we've just read */
436 for (i=0; i < len; i++) {
437 if (!buf[i]) {ok=TRUE; break;}
438 }
439
440 if (!ok) {
441 if (len == maxlen) {
442 ERR("cabinet is truncated\n");
443 break;
444 }
445 /* The buffer is too small for the string. Reset the file to the point
446 * were we started, free the buffer and increase the size for the next try
447 */
448 PFDI_SEEK(hfdi, hf, base, SEEK_SET);
449 PFDI_FREE(hfdi, buf);
450 buf = NULL;
451 len *= 2;
452 }
453 } while (!ok);
454
455 if (!ok) {
456 if (buf)
457 PFDI_FREE(hfdi, buf);
458 else
459 ERR("out of memory!\n");
460 return NULL;
461 }
462
463 /* otherwise, set the stream to just after the string and return */
464 PFDI_SEEK(hfdi, hf, base + strlen((char *)buf) + 1, SEEK_SET);
465
466 return (char *) buf;
467 }
468
469 /******************************************************************
470 * FDI_read_entries (internal)
471 *
472 * process the cabinet header in the style of FDIIsCabinet, but
473 * without the sanity checks (and bug)
474 */
475 static BOOL FDI_read_entries(
476 HFDI hfdi,
477 INT_PTR hf,
478 PFDICABINETINFO pfdici,
479 PMORE_ISCAB_INFO pmii)
480 {
481 int num_folders, num_files, header_resv, folder_resv = 0;
482 LONG base_offset, cabsize;
483 USHORT setid, cabidx, flags;
484 cab_UBYTE buf[64], block_resv;
485 char *prevname = NULL, *previnfo = NULL, *nextname = NULL, *nextinfo = NULL;
486
487 TRACE("(hfdi == ^%p, hf == %ld, pfdici == ^%p)\n", hfdi, hf, pfdici);
488
489 /*
490 * FIXME: I just noticed that I am memorizing the initial file pointer
491 * offset and restoring it before reading in the rest of the header
492 * information in the cabinet. Perhaps that's correct -- that is, perhaps
493 * this API is supposed to support "streaming" cabinets which are embedded
494 * in other files, or cabinets which begin at file offsets other than zero.
495 * Otherwise, I should instead go to the absolute beginning of the file.
496 * (Either way, the semantics of wine's FDICopy require me to leave the
497 * file pointer where it is afterwards -- If Windows does not do so, we
498 * ought to duplicate the native behavior in the FDIIsCabinet API, not here.
499 *
500 * So, the answer lies in Windows; will native cabinet.dll recognize a
501 * cabinet "file" embedded in another file? Note that cabextract.c does
502 * support this, which implies that Microsoft's might. I haven't tried it
503 * yet so I don't know. ATM, most of wine's FDI cabinet routines (except
504 * this one) would not work in this way. To fix it, we could just make the
505 * various references to absolute file positions in the code relative to an
506 * initial "beginning" offset. Because the FDICopy API doesn't take a
507 * file-handle like this one, we would therein need to search through the
508 * file for the beginning of the cabinet (as we also do in cabextract.c).
509 * Note that this limits us to a maximum of one cabinet per. file: the first.
510 *
511 * So, in summary: either the code below is wrong, or the rest of fdi.c is
512 * wrong... I cannot imagine that both are correct ;) One of these flaws
513 * should be fixed after determining the behavior on Windows. We ought
514 * to check both FDIIsCabinet and FDICopy for the right behavior.
515 *
516 * -gmt
517 */
518
519 /* get basic offset & size info */
520 base_offset = FDI_getoffset(hfdi, hf);
521
522 if (PFDI_SEEK(hfdi, hf, 0, SEEK_END) == -1) {
523 if (pmii) {
524 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NOT_A_CABINET;
525 PFDI_INT(hfdi)->perf->erfType = 0;
526 PFDI_INT(hfdi)->perf->fError = TRUE;
527 }
528 return FALSE;
529 }
530
531 cabsize = FDI_getoffset(hfdi, hf);
532
533 if ((cabsize == -1) || (base_offset == -1) ||
534 ( PFDI_SEEK(hfdi, hf, base_offset, SEEK_SET) == -1 )) {
535 if (pmii) {
536 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NOT_A_CABINET;
537 PFDI_INT(hfdi)->perf->erfType = 0;
538 PFDI_INT(hfdi)->perf->fError = TRUE;
539 }
540 return FALSE;
541 }
542
543 /* read in the CFHEADER */
544 if (PFDI_READ(hfdi, hf, buf, cfhead_SIZEOF) != cfhead_SIZEOF) {
545 if (pmii) {
546 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NOT_A_CABINET;
547 PFDI_INT(hfdi)->perf->erfType = 0;
548 PFDI_INT(hfdi)->perf->fError = TRUE;
549 }
550 return FALSE;
551 }
552
553 /* check basic MSCF signature */
554 if (EndGetI32(buf+cfhead_Signature) != 0x4643534d) {
555 if (pmii) {
556 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NOT_A_CABINET;
557 PFDI_INT(hfdi)->perf->erfType = 0;
558 PFDI_INT(hfdi)->perf->fError = TRUE;
559 }
560 return FALSE;
561 }
562
563 /* get the number of folders */
564 num_folders = EndGetI16(buf+cfhead_NumFolders);
565 if (num_folders == 0) {
566 /* PONDERME: is this really invalid? */
567 WARN("weird cabinet detect failure: no folders in cabinet\n");
568 if (pmii) {
569 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NOT_A_CABINET;
570 PFDI_INT(hfdi)->perf->erfType = 0;
571 PFDI_INT(hfdi)->perf->fError = TRUE;
572 }
573 return FALSE;
574 }
575
576 /* get the number of files */
577 num_files = EndGetI16(buf+cfhead_NumFiles);
578 if (num_files == 0) {
579 /* PONDERME: is this really invalid? */
580 WARN("weird cabinet detect failure: no files in cabinet\n");
581 if (pmii) {
582 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NOT_A_CABINET;
583 PFDI_INT(hfdi)->perf->erfType = 0;
584 PFDI_INT(hfdi)->perf->fError = TRUE;
585 }
586 return FALSE;
587 }
588
589 /* setid */
590 setid = EndGetI16(buf+cfhead_SetID);
591
592 /* cabinet (set) index */
593 cabidx = EndGetI16(buf+cfhead_CabinetIndex);
594
595 /* check the header revision */
596 if ((buf[cfhead_MajorVersion] > 1) ||
597 (buf[cfhead_MajorVersion] == 1 && buf[cfhead_MinorVersion] > 3))
598 {
599 WARN("cabinet format version > 1.3\n");
600 if (pmii) {
601 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_UNKNOWN_CABINET_VERSION;
602 PFDI_INT(hfdi)->perf->erfType = 0; /* ? */
603 PFDI_INT(hfdi)->perf->fError = TRUE;
604 }
605 return FALSE;
606 }
607
608 /* pull the flags out */
609 flags = EndGetI16(buf+cfhead_Flags);
610
611 /* read the reserved-sizes part of header, if present */
612 if (flags & cfheadRESERVE_PRESENT) {
613 if (PFDI_READ(hfdi, hf, buf, cfheadext_SIZEOF) != cfheadext_SIZEOF) {
614 ERR("bunk reserve-sizes?\n");
615 if (pmii) {
616 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
617 PFDI_INT(hfdi)->perf->erfType = 0; /* ? */
618 PFDI_INT(hfdi)->perf->fError = TRUE;
619 }
620 return FALSE;
621 }
622
623 header_resv = EndGetI16(buf+cfheadext_HeaderReserved);
624 if (pmii) pmii->header_resv = header_resv;
625 folder_resv = buf[cfheadext_FolderReserved];
626 if (pmii) pmii->folder_resv = folder_resv;
627 block_resv = buf[cfheadext_DataReserved];
628 if (pmii) pmii->block_resv = block_resv;
629
630 if (header_resv > 60000) {
631 WARN("WARNING; header reserved space > 60000\n");
632 }
633
634 /* skip the reserved header */
635 if ((header_resv) && (PFDI_SEEK(hfdi, hf, header_resv, SEEK_CUR) == -1)) {
636 ERR("seek failure: header_resv\n");
637 if (pmii) {
638 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
639 PFDI_INT(hfdi)->perf->erfType = 0; /* ? */
640 PFDI_INT(hfdi)->perf->fError = TRUE;
641 }
642 return FALSE;
643 }
644 }
645
646 if (flags & cfheadPREV_CABINET) {
647 prevname = FDI_read_string(hfdi, hf, cabsize);
648 if (!prevname) {
649 if (pmii) {
650 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
651 PFDI_INT(hfdi)->perf->erfType = 0; /* ? */
652 PFDI_INT(hfdi)->perf->fError = TRUE;
653 }
654 return FALSE;
655 } else
656 if (pmii)
657 pmii->prevname = prevname;
658 else
659 PFDI_FREE(hfdi, prevname);
660 previnfo = FDI_read_string(hfdi, hf, cabsize);
661 if (previnfo) {
662 if (pmii)
663 pmii->previnfo = previnfo;
664 else
665 PFDI_FREE(hfdi, previnfo);
666 }
667 }
668
669 if (flags & cfheadNEXT_CABINET) {
670 if (pmii)
671 pmii->hasnext = TRUE;
672 nextname = FDI_read_string(hfdi, hf, cabsize);
673 if (!nextname) {
674 if ((flags & cfheadPREV_CABINET) && pmii) {
675 if (pmii->prevname) PFDI_FREE(hfdi, prevname);
676 if (pmii->previnfo) PFDI_FREE(hfdi, previnfo);
677 }
678 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
679 PFDI_INT(hfdi)->perf->erfType = 0; /* ? */
680 PFDI_INT(hfdi)->perf->fError = TRUE;
681 return FALSE;
682 } else
683 if (pmii)
684 pmii->nextname = nextname;
685 else
686 PFDI_FREE(hfdi, nextname);
687 nextinfo = FDI_read_string(hfdi, hf, cabsize);
688 if (nextinfo) {
689 if (pmii)
690 pmii->nextinfo = nextinfo;
691 else
692 PFDI_FREE(hfdi, nextinfo);
693 }
694 }
695
696 /* we could process the whole cabinet searching for problems;
697 instead lets stop here. Now let's fill out the paperwork */
698 pfdici->cbCabinet = cabsize;
699 pfdici->cFolders = num_folders;
700 pfdici->cFiles = num_files;
701 pfdici->setID = setid;
702 pfdici->iCabinet = cabidx;
703 pfdici->fReserve = (flags & cfheadRESERVE_PRESENT) ? TRUE : FALSE;
704 pfdici->hasprev = (flags & cfheadPREV_CABINET) ? TRUE : FALSE;
705 pfdici->hasnext = (flags & cfheadNEXT_CABINET) ? TRUE : FALSE;
706 return TRUE;
707 }
708
709 /***********************************************************************
710 * FDIIsCabinet (CABINET.21)
711 *
712 * Informs the caller as to whether or not the provided file handle is
713 * really a cabinet or not, filling out the provided PFDICABINETINFO
714 * structure with information about the cabinet. Brief explanations of
715 * the elements of this structure are available as comments accompanying
716 * its definition in wine's include/fdi.h.
717 *
718 * PARAMS
719 * hfdi [I] An HFDI from FDICreate
720 * hf [I] The file handle about which the caller inquires
721 * pfdici [IO] Pointer to a PFDICABINETINFO structure which will
722 * be filled out with information about the cabinet
723 * file indicated by hf if, indeed, it is determined
724 * to be a cabinet.
725 *
726 * RETURNS
727 * TRUE if the file is a cabinet. The info pointed to by pfdici will
728 * be provided.
729 * FALSE if the file is not a cabinet, or if an error was encountered
730 * while processing the cabinet. The PERF structure provided to
731 * FDICreate can be queried for more error information.
732 *
733 * INCLUDES
734 * fdi.c
735 */
736 BOOL __cdecl FDIIsCabinet(
737 HFDI hfdi,
738 INT_PTR hf,
739 PFDICABINETINFO pfdici)
740 {
741 BOOL rv;
742
743 TRACE("(hfdi == ^%p, hf == ^%ld, pfdici == ^%p)\n", hfdi, hf, pfdici);
744
745 if (!REALLY_IS_FDI(hfdi)) {
746 ERR("REALLY_IS_FDI failed on ^%p\n", hfdi);
747 SetLastError(ERROR_INVALID_HANDLE);
748 return FALSE;
749 }
750
751 if (!hf) {
752 ERR("(!hf)!\n");
753 /* PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CABINET_NOT_FOUND;
754 PFDI_INT(hfdi)->perf->erfType = ERROR_INVALID_HANDLE;
755 PFDI_INT(hfdi)->perf->fError = TRUE; */
756 SetLastError(ERROR_INVALID_HANDLE);
757 return FALSE;
758 }
759
760 if (!pfdici) {
761 ERR("(!pfdici)!\n");
762 /* PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NONE;
763 PFDI_INT(hfdi)->perf->erfType = ERROR_BAD_ARGUMENTS;
764 PFDI_INT(hfdi)->perf->fError = TRUE; */
765 SetLastError(ERROR_BAD_ARGUMENTS);
766 return FALSE;
767 }
768 rv = FDI_read_entries(hfdi, hf, pfdici, NULL);
769
770 if (rv)
771 pfdici->hasnext = FALSE; /* yuck. duplicate apparent cabinet.dll bug */
772
773 return rv;
774 }
775
776 /******************************************************************
777 * QTMfdi_initmodel (internal)
778 *
779 * Initialize a model which decodes symbols from [s] to [s]+[n]-1
780 */
781 static void QTMfdi_initmodel(struct QTMmodel *m, struct QTMmodelsym *sym, int n, int s) {
782 int i;
783 m->shiftsleft = 4;
784 m->entries = n;
785 m->syms = sym;
786 memset(m->tabloc, 0xFF, sizeof(m->tabloc)); /* clear out look-up table */
787 for (i = 0; i < n; i++) {
788 m->tabloc[i+s] = i; /* set up a look-up entry for symbol */
789 m->syms[i].sym = i+s; /* actual symbol */
790 m->syms[i].cumfreq = n-i; /* current frequency of that symbol */
791 }
792 m->syms[n].cumfreq = 0;
793 }
794
795 /******************************************************************
796 * QTMfdi_init (internal)
797 */
798 static int QTMfdi_init(int window, int level, fdi_decomp_state *decomp_state) {
799 unsigned int wndsize = 1 << window;
800 int msz = window * 2, i;
801 cab_ULONG j;
802
803 /* QTM supports window sizes of 2^10 (1Kb) through 2^21 (2Mb) */
804 /* if a previously allocated window is big enough, keep it */
805 if (window < 10 || window > 21) return DECR_DATAFORMAT;
806 if (QTM(actual_size) < wndsize) {
807 if (QTM(window)) PFDI_FREE(CAB(hfdi), QTM(window));
808 QTM(window) = NULL;
809 }
810 if (!QTM(window)) {
811 if (!(QTM(window) = PFDI_ALLOC(CAB(hfdi), wndsize))) return DECR_NOMEMORY;
812 QTM(actual_size) = wndsize;
813 }
814 QTM(window_size) = wndsize;
815 QTM(window_posn) = 0;
816
817 /* initialize static slot/extrabits tables */
818 for (i = 0, j = 0; i < 27; i++) {
819 CAB(q_length_extra)[i] = (i == 26) ? 0 : (i < 2 ? 0 : i - 2) >> 2;
820 CAB(q_length_base)[i] = j; j += 1 << ((i == 26) ? 5 : CAB(q_length_extra)[i]);
821 }
822 for (i = 0, j = 0; i < 42; i++) {
823 CAB(q_extra_bits)[i] = (i < 2 ? 0 : i-2) >> 1;
824 CAB(q_position_base)[i] = j; j += 1 << CAB(q_extra_bits)[i];
825 }
826
827 /* initialize arithmetic coding models */
828
829 QTMfdi_initmodel(&QTM(model7), &QTM(m7sym)[0], 7, 0);
830
831 QTMfdi_initmodel(&QTM(model00), &QTM(m00sym)[0], 0x40, 0x00);
832 QTMfdi_initmodel(&QTM(model40), &QTM(m40sym)[0], 0x40, 0x40);
833 QTMfdi_initmodel(&QTM(model80), &QTM(m80sym)[0], 0x40, 0x80);
834 QTMfdi_initmodel(&QTM(modelC0), &QTM(mC0sym)[0], 0x40, 0xC0);
835
836 /* model 4 depends on table size, ranges from 20 to 24 */
837 QTMfdi_initmodel(&QTM(model4), &QTM(m4sym)[0], (msz < 24) ? msz : 24, 0);
838 /* model 5 depends on table size, ranges from 20 to 36 */
839 QTMfdi_initmodel(&QTM(model5), &QTM(m5sym)[0], (msz < 36) ? msz : 36, 0);
840 /* model 6pos depends on table size, ranges from 20 to 42 */
841 QTMfdi_initmodel(&QTM(model6pos), &QTM(m6psym)[0], msz, 0);
842 QTMfdi_initmodel(&QTM(model6len), &QTM(m6lsym)[0], 27, 0);
843
844 return DECR_OK;
845 }
846
847 /************************************************************
848 * LZXfdi_init (internal)
849 */
850 static int LZXfdi_init(int window, fdi_decomp_state *decomp_state) {
851 static const cab_UBYTE bits[] =
852 { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
853 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14,
854 15, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
855 17, 17, 17};
856 static const cab_ULONG base[] =
857 { 0, 1, 2, 3, 4, 6, 8, 12,
858 16, 24, 32, 48, 64, 96, 128, 192,
859 256, 384, 512, 768, 1024, 1536, 2048, 3072,
860 4096, 6144, 8192, 12288, 16384, 24576, 32768, 49152,
861 65536, 98304, 131072, 196608, 262144, 393216, 524288, 655360,
862 786432, 917504, 1048576, 1179648, 1310720, 1441792, 1572864, 1703936,
863 1835008, 1966080, 2097152};
864 cab_ULONG wndsize = 1 << window;
865 int posn_slots;
866
867 /* LZX supports window sizes of 2^15 (32Kb) through 2^21 (2Mb) */
868 /* if a previously allocated window is big enough, keep it */
869 if (window < 15 || window > 21) return DECR_DATAFORMAT;
870 if (LZX(actual_size) < wndsize) {
871 if (LZX(window)) PFDI_FREE(CAB(hfdi), LZX(window));
872 LZX(window) = NULL;
873 }
874 if (!LZX(window)) {
875 if (!(LZX(window) = PFDI_ALLOC(CAB(hfdi), wndsize))) return DECR_NOMEMORY;
876 LZX(actual_size) = wndsize;
877 }
878 LZX(window_size) = wndsize;
879
880 /* initialize static tables */
881 memcpy(CAB(extra_bits), bits, sizeof(bits));
882 memcpy(CAB(lzx_position_base), base, sizeof(base));
883
884 /* calculate required position slots */
885 if (window == 20) posn_slots = 42;
886 else if (window == 21) posn_slots = 50;
887 else posn_slots = window << 1;
888
889 /*posn_slots=i=0; while (i < wndsize) i += 1 << CAB(extra_bits)[posn_slots++]; */
890
891 LZX(R0) = LZX(R1) = LZX(R2) = 1;
892 LZX(main_elements) = LZX_NUM_CHARS + (posn_slots << 3);
893 LZX(header_read) = 0;
894 LZX(frames_read) = 0;
895 LZX(block_remaining) = 0;
896 LZX(block_type) = LZX_BLOCKTYPE_INVALID;
897 LZX(intel_curpos) = 0;
898 LZX(intel_started) = 0;
899 LZX(window_posn) = 0;
900
901 /* initialize tables to 0 (because deltas will be applied to them) */
902 memset(LZX(MAINTREE_len), 0, sizeof(LZX(MAINTREE_len)));
903 memset(LZX(LENGTH_len), 0, sizeof(LZX(LENGTH_len)));
904
905 return DECR_OK;
906 }
907
908 /****************************************************
909 * NONEfdi_decomp(internal)
910 */
911 static int NONEfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state)
912 {
913 if (inlen != outlen) return DECR_ILLEGALDATA;
914 memcpy(CAB(outbuf), CAB(inbuf), (size_t) inlen);
915 return DECR_OK;
916 }
917
918 /********************************************************
919 * Ziphuft_free (internal)
920 */
921 static void fdi_Ziphuft_free(HFDI hfdi, struct Ziphuft *t)
922 {
923 register struct Ziphuft *p, *q;
924
925 /* Go through linked list, freeing from the allocated (t[-1]) address. */
926 p = t;
927 while (p != (struct Ziphuft *)NULL)
928 {
929 q = (--p)->v.t;
930 PFDI_FREE(hfdi, p);
931 p = q;
932 }
933 }
934
935 /*********************************************************
936 * fdi_Ziphuft_build (internal)
937 */
938 static cab_LONG fdi_Ziphuft_build(cab_ULONG *b, cab_ULONG n, cab_ULONG s, const cab_UWORD *d, const cab_UWORD *e,
939 struct Ziphuft **t, cab_LONG *m, fdi_decomp_state *decomp_state)
940 {
941 cab_ULONG a; /* counter for codes of length k */
942 cab_ULONG el; /* length of EOB code (value 256) */
943 cab_ULONG f; /* i repeats in table every f entries */
944 cab_LONG g; /* maximum code length */
945 cab_LONG h; /* table level */
946 register cab_ULONG i; /* counter, current code */
947 register cab_ULONG j; /* counter */
948 register cab_LONG k; /* number of bits in current code */
949 cab_LONG *l; /* stack of bits per table */
950 register cab_ULONG *p; /* pointer into ZIP(c)[],ZIP(b)[],ZIP(v)[] */
951 register struct Ziphuft *q; /* points to current table */
952 struct Ziphuft r; /* table entry for structure assignment */
953 register cab_LONG w; /* bits before this table == (l * h) */
954 cab_ULONG *xp; /* pointer into x */
955 cab_LONG y; /* number of dummy codes added */
956 cab_ULONG z; /* number of entries in current table */
957
958 l = ZIP(lx)+1;
959
960 /* Generate counts for each bit length */
961 el = n > 256 ? b[256] : ZIPBMAX; /* set length of EOB code, if any */
962
963 for(i = 0; i < ZIPBMAX+1; ++i)
964 ZIP(c)[i] = 0;
965 p = b; i = n;
966 do
967 {
968 ZIP(c)[*p]++; p++; /* assume all entries <= ZIPBMAX */
969 } while (--i);
970 if (ZIP(c)[0] == n) /* null input--all zero length codes */
971 {
972 *t = (struct Ziphuft *)NULL;
973 *m = 0;
974 return 0;