- Move NCI generated files to arch-specific directories
[reactos.git] / reactos / dll / win32 / cabinet / fdi.c
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 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, 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(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 = ((HFDI) (*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_realloc (internal)
416 *
417 * we can't use _msize; the user might not be using malloc, so we require
418 * an explicit specification of the previous size. inefficient.
419 */
420 static void *FDI_realloc(HFDI hfdi, void *mem, size_t prevsize, size_t newsize)
421 {
422 void *rslt = NULL;
423 char *irslt, *imem;
424 size_t copysize = (prevsize < newsize) ? prevsize : newsize;
425 if (prevsize == newsize) return mem;
426 rslt = PFDI_ALLOC(hfdi, newsize);
427 if (rslt)
428 for (irslt = (char *)rslt, imem = (char *)mem; (copysize); copysize--)
429 *irslt++ = *imem++;
430 PFDI_FREE(hfdi, mem);
431 return rslt;
432 }
433
434 /**********************************************************************
435 * FDI_read_string (internal)
436 *
437 * allocate and read an arbitrarily long string from the cabinet
438 */
439 static char *FDI_read_string(HFDI hfdi, INT_PTR hf, long cabsize)
440 {
441 size_t len=256,
442 oldlen = 0,
443 base = FDI_getoffset(hfdi, hf),
444 maxlen = cabsize - base;
445 BOOL ok = FALSE;
446 unsigned int i;
447 cab_UBYTE *buf = NULL;
448
449 TRACE("(hfdi == ^%p, hf == %d)\n", hfdi, hf);
450
451 do {
452 if (len > maxlen) len = maxlen;
453 if (!(buf = FDI_realloc(hfdi, buf, oldlen, len))) break;
454 oldlen = len;
455 if (!PFDI_READ(hfdi, hf, buf, len)) break;
456
457 /* search for a null terminator in what we've just read */
458 for (i=0; i < len; i++) {
459 if (!buf[i]) {ok=TRUE; break;}
460 }
461
462 if (!ok) {
463 if (len == maxlen) {
464 ERR("cabinet is truncated\n");
465 break;
466 }
467 len += 256;
468 PFDI_SEEK(hfdi, hf, base, SEEK_SET);
469 }
470 } while (!ok);
471
472 if (!ok) {
473 if (buf)
474 PFDI_FREE(hfdi, buf);
475 else
476 ERR("out of memory!\n");
477 return NULL;
478 }
479
480 /* otherwise, set the stream to just after the string and return */
481 PFDI_SEEK(hfdi, hf, base + ((cab_off_t) strlen((char *) buf)) + 1, SEEK_SET);
482
483 return (char *) buf;
484 }
485
486 /******************************************************************
487 * FDI_read_entries (internal)
488 *
489 * process the cabinet header in the style of FDIIsCabinet, but
490 * without the sanity checks (and bug)
491 */
492 static BOOL FDI_read_entries(
493 HFDI hfdi,
494 INT_PTR hf,
495 PFDICABINETINFO pfdici,
496 PMORE_ISCAB_INFO pmii)
497 {
498 int num_folders, num_files, header_resv, folder_resv = 0;
499 LONG base_offset, cabsize;
500 USHORT setid, cabidx, flags;
501 cab_UBYTE buf[64], block_resv;
502 char *prevname = NULL, *previnfo = NULL, *nextname = NULL, *nextinfo = NULL;
503
504 TRACE("(hfdi == ^%p, hf == %d, pfdici == ^%p)\n", hfdi, hf, pfdici);
505
506 /*
507 * FIXME: I just noticed that I am memorizing the initial file pointer
508 * offset and restoring it before reading in the rest of the header
509 * information in the cabinet. Perhaps that's correct -- that is, perhaps
510 * this API is supposed to support "streaming" cabinets which are embedded
511 * in other files, or cabinets which begin at file offsets other than zero.
512 * Otherwise, I should instead go to the absolute beginning of the file.
513 * (Either way, the semantics of wine's FDICopy require me to leave the
514 * file pointer where it is afterwards -- If Windows does not do so, we
515 * ought to duplicate the native behavior in the FDIIsCabinet API, not here.
516 *
517 * So, the answer lies in Windows; will native cabinet.dll recognize a
518 * cabinet "file" embedded in another file? Note that cabextract.c does
519 * support this, which implies that Microsoft's might. I haven't tried it
520 * yet so I don't know. ATM, most of wine's FDI cabinet routines (except
521 * this one) would not work in this way. To fix it, we could just make the
522 * various references to absolute file positions in the code relative to an
523 * initial "beginning" offset. Because the FDICopy API doesn't take a
524 * file-handle like this one, we would therein need to search through the
525 * file for the beginning of the cabinet (as we also do in cabextract.c).
526 * Note that this limits us to a maximum of one cabinet per. file: the first.
527 *
528 * So, in summary: either the code below is wrong, or the rest of fdi.c is
529 * wrong... I cannot imagine that both are correct ;) One of these flaws
530 * should be fixed after determining the behavior on Windows. We ought
531 * to check both FDIIsCabinet and FDICopy for the right behavior.
532 *
533 * -gmt
534 */
535
536 /* get basic offset & size info */
537 base_offset = FDI_getoffset(hfdi, hf);
538
539 if (PFDI_SEEK(hfdi, hf, 0, SEEK_END) == -1) {
540 if (pmii) {
541 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NOT_A_CABINET;
542 PFDI_INT(hfdi)->perf->erfType = 0;
543 PFDI_INT(hfdi)->perf->fError = TRUE;
544 }
545 return FALSE;
546 }
547
548 cabsize = FDI_getoffset(hfdi, hf);
549
550 if ((cabsize == -1) || (base_offset == -1) ||
551 ( PFDI_SEEK(hfdi, hf, base_offset, SEEK_SET) == -1 )) {
552 if (pmii) {
553 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NOT_A_CABINET;
554 PFDI_INT(hfdi)->perf->erfType = 0;
555 PFDI_INT(hfdi)->perf->fError = TRUE;
556 }
557 return FALSE;
558 }
559
560 /* read in the CFHEADER */
561 if (PFDI_READ(hfdi, hf, buf, cfhead_SIZEOF) != cfhead_SIZEOF) {
562 if (pmii) {
563 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NOT_A_CABINET;
564 PFDI_INT(hfdi)->perf->erfType = 0;
565 PFDI_INT(hfdi)->perf->fError = TRUE;
566 }
567 return FALSE;
568 }
569
570 /* check basic MSCF signature */
571 if (EndGetI32(buf+cfhead_Signature) != 0x4643534d) {
572 if (pmii) {
573 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NOT_A_CABINET;
574 PFDI_INT(hfdi)->perf->erfType = 0;
575 PFDI_INT(hfdi)->perf->fError = TRUE;
576 }
577 return FALSE;
578 }
579
580 /* get the number of folders */
581 num_folders = EndGetI16(buf+cfhead_NumFolders);
582 if (num_folders == 0) {
583 /* PONDERME: is this really invalid? */
584 WARN("weird cabinet detect failure: no folders in cabinet\n");
585 if (pmii) {
586 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NOT_A_CABINET;
587 PFDI_INT(hfdi)->perf->erfType = 0;
588 PFDI_INT(hfdi)->perf->fError = TRUE;
589 }
590 return FALSE;
591 }
592
593 /* get the number of files */
594 num_files = EndGetI16(buf+cfhead_NumFiles);
595 if (num_files == 0) {
596 /* PONDERME: is this really invalid? */
597 WARN("weird cabinet detect failure: no files in cabinet\n");
598 if (pmii) {
599 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NOT_A_CABINET;
600 PFDI_INT(hfdi)->perf->erfType = 0;
601 PFDI_INT(hfdi)->perf->fError = TRUE;
602 }
603 return FALSE;
604 }
605
606 /* setid */
607 setid = EndGetI16(buf+cfhead_SetID);
608
609 /* cabinet (set) index */
610 cabidx = EndGetI16(buf+cfhead_CabinetIndex);
611
612 /* check the header revision */
613 if ((buf[cfhead_MajorVersion] > 1) ||
614 (buf[cfhead_MajorVersion] == 1 && buf[cfhead_MinorVersion] > 3))
615 {
616 WARN("cabinet format version > 1.3\n");
617 if (pmii) {
618 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_UNKNOWN_CABINET_VERSION;
619 PFDI_INT(hfdi)->perf->erfType = 0; /* ? */
620 PFDI_INT(hfdi)->perf->fError = TRUE;
621 }
622 return FALSE;
623 }
624
625 /* pull the flags out */
626 flags = EndGetI16(buf+cfhead_Flags);
627
628 /* read the reserved-sizes part of header, if present */
629 if (flags & cfheadRESERVE_PRESENT) {
630 if (PFDI_READ(hfdi, hf, buf, cfheadext_SIZEOF) != cfheadext_SIZEOF) {
631 ERR("bunk reserve-sizes?\n");
632 if (pmii) {
633 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
634 PFDI_INT(hfdi)->perf->erfType = 0; /* ? */
635 PFDI_INT(hfdi)->perf->fError = TRUE;
636 }
637 return FALSE;
638 }
639
640 header_resv = EndGetI16(buf+cfheadext_HeaderReserved);
641 if (pmii) pmii->header_resv = header_resv;
642 folder_resv = buf[cfheadext_FolderReserved];
643 if (pmii) pmii->folder_resv = folder_resv;
644 block_resv = buf[cfheadext_DataReserved];
645 if (pmii) pmii->block_resv = block_resv;
646
647 if (header_resv > 60000) {
648 WARN("WARNING; header reserved space > 60000\n");
649 }
650
651 /* skip the reserved header */
652 if ((header_resv) && (PFDI_SEEK(hfdi, hf, header_resv, SEEK_CUR) == -1)) {
653 ERR("seek failure: header_resv\n");
654 if (pmii) {
655 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
656 PFDI_INT(hfdi)->perf->erfType = 0; /* ? */
657 PFDI_INT(hfdi)->perf->fError = TRUE;
658 }
659 return FALSE;
660 }
661 }
662
663 if (flags & cfheadPREV_CABINET) {
664 prevname = FDI_read_string(hfdi, hf, cabsize);
665 if (!prevname) {
666 if (pmii) {
667 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
668 PFDI_INT(hfdi)->perf->erfType = 0; /* ? */
669 PFDI_INT(hfdi)->perf->fError = TRUE;
670 }
671 return FALSE;
672 } else
673 if (pmii)
674 pmii->prevname = prevname;
675 else
676 PFDI_FREE(hfdi, prevname);
677 previnfo = FDI_read_string(hfdi, hf, cabsize);
678 if (previnfo) {
679 if (pmii)
680 pmii->previnfo = previnfo;
681 else
682 PFDI_FREE(hfdi, previnfo);
683 }
684 }
685
686 if (flags & cfheadNEXT_CABINET) {
687 if (pmii)
688 pmii->hasnext = TRUE;
689 nextname = FDI_read_string(hfdi, hf, cabsize);
690 if (!nextname) {
691 if ((flags & cfheadPREV_CABINET) && pmii) {
692 if (pmii->prevname) PFDI_FREE(hfdi, prevname);
693 if (pmii->previnfo) PFDI_FREE(hfdi, previnfo);
694 }
695 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
696 PFDI_INT(hfdi)->perf->erfType = 0; /* ? */
697 PFDI_INT(hfdi)->perf->fError = TRUE;
698 return FALSE;
699 } else
700 if (pmii)
701 pmii->nextname = nextname;
702 else
703 PFDI_FREE(hfdi, nextname);
704 nextinfo = FDI_read_string(hfdi, hf, cabsize);
705 if (nextinfo) {
706 if (pmii)
707 pmii->nextinfo = nextinfo;
708 else
709 PFDI_FREE(hfdi, nextinfo);
710 }
711 }
712
713 /* we could process the whole cabinet searching for problems;
714 instead lets stop here. Now let's fill out the paperwork */
715 pfdici->cbCabinet = cabsize;
716 pfdici->cFolders = num_folders;
717 pfdici->cFiles = num_files;
718 pfdici->setID = setid;
719 pfdici->iCabinet = cabidx;
720 pfdici->fReserve = (flags & cfheadRESERVE_PRESENT) ? TRUE : FALSE;
721 pfdici->hasprev = (flags & cfheadPREV_CABINET) ? TRUE : FALSE;
722 pfdici->hasnext = (flags & cfheadNEXT_CABINET) ? TRUE : FALSE;
723 return TRUE;
724 }
725
726 /***********************************************************************
727 * FDIIsCabinet (CABINET.21)
728 *
729 * Informs the caller as to whether or not the provided file handle is
730 * really a cabinet or not, filling out the provided PFDICABINETINFO
731 * structure with information about the cabinet. Brief explanations of
732 * the elements of this structure are available as comments accompanying
733 * its definition in wine's include/fdi.h.
734 *
735 * PARAMS
736 * hfdi [I] An HFDI from FDICreate
737 * hf [I] The file handle about which the caller inquires
738 * pfdici [IO] Pointer to a PFDICABINETINFO structure which will
739 * be filled out with information about the cabinet
740 * file indicated by hf if, indeed, it is determined
741 * to be a cabinet.
742 *
743 * RETURNS
744 * TRUE if the file is a cabinet. The info pointed to by pfdici will
745 * be provided.
746 * FALSE if the file is not a cabinet, or if an error was encountered
747 * while processing the cabinet. The PERF structure provided to
748 * FDICreate can be queried for more error information.
749 *
750 * INCLUDES
751 * fdi.c
752 */
753 BOOL __cdecl FDIIsCabinet(
754 HFDI hfdi,
755 INT_PTR hf,
756 PFDICABINETINFO pfdici)
757 {
758 BOOL rv;
759
760 TRACE("(hfdi == ^%p, hf == ^%d, pfdici == ^%p)\n", hfdi, hf, pfdici);
761
762 if (!REALLY_IS_FDI(hfdi)) {
763 ERR("REALLY_IS_FDI failed on ^%p\n", hfdi);
764 SetLastError(ERROR_INVALID_HANDLE);
765 return FALSE;
766 }
767
768 if (!hf) {
769 ERR("(!hf)!\n");
770 /* PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CABINET_NOT_FOUND;
771 PFDI_INT(hfdi)->perf->erfType = ERROR_INVALID_HANDLE;
772 PFDI_INT(hfdi)->perf->fError = TRUE; */
773 SetLastError(ERROR_INVALID_HANDLE);
774 return FALSE;
775 }
776
777 if (!pfdici) {
778 ERR("(!pfdici)!\n");
779 /* PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NONE;
780 PFDI_INT(hfdi)->perf->erfType = ERROR_BAD_ARGUMENTS;
781 PFDI_INT(hfdi)->perf->fError = TRUE; */
782 SetLastError(ERROR_BAD_ARGUMENTS);
783 return FALSE;
784 }
785 rv = FDI_read_entries(hfdi, hf, pfdici, NULL);
786
787 if (rv)
788 pfdici->hasnext = FALSE; /* yuck. duplicate apparent cabinet.dll bug */
789
790 return rv;
791 }
792
793 /******************************************************************
794 * QTMfdi_initmodel (internal)
795 *
796 * Initialize a model which decodes symbols from [s] to [s]+[n]-1
797 */
798 static void QTMfdi_initmodel(struct QTMmodel *m, struct QTMmodelsym *sym, int n, int s) {
799 int i;
800 m->shiftsleft = 4;
801 m->entries = n;
802 m->syms = sym;
803 memset(m->tabloc, 0xFF, sizeof(m->tabloc)); /* clear out look-up table */
804 for (i = 0; i < n; i++) {
805 m->tabloc[i+s] = i; /* set up a look-up entry for symbol */
806 m->syms[i].sym = i+s; /* actual symbol */
807 m->syms[i].cumfreq = n-i; /* current frequency of that symbol */
808 }
809 m->syms[n].cumfreq = 0;
810 }
811
812 /******************************************************************
813 * QTMfdi_init (internal)
814 */
815 static int QTMfdi_init(int window, int level, fdi_decomp_state *decomp_state) {
816 unsigned int wndsize = 1 << window;
817 int msz = window * 2, i;
818 cab_ULONG j;
819
820 /* QTM supports window sizes of 2^10 (1Kb) through 2^21 (2Mb) */
821 /* if a previously allocated window is big enough, keep it */
822 if (window < 10 || window > 21) return DECR_DATAFORMAT;
823 if (QTM(actual_size) < wndsize) {
824 if (QTM(window)) PFDI_FREE(CAB(hfdi), QTM(window));
825 QTM(window) = NULL;
826 }
827 if (!QTM(window)) {
828 if (!(QTM(window) = PFDI_ALLOC(CAB(hfdi), wndsize))) return DECR_NOMEMORY;
829 QTM(actual_size) = wndsize;
830 }
831 QTM(window_size) = wndsize;
832 QTM(window_posn) = 0;
833
834 /* initialize static slot/extrabits tables */
835 for (i = 0, j = 0; i < 27; i++) {
836 CAB(q_length_extra)[i] = (i == 26) ? 0 : (i < 2 ? 0 : i - 2) >> 2;
837 CAB(q_length_base)[i] = j; j += 1 << ((i == 26) ? 5 : CAB(q_length_extra)[i]);
838 }
839 for (i = 0, j = 0; i < 42; i++) {
840 CAB(q_extra_bits)[i] = (i < 2 ? 0 : i-2) >> 1;
841 CAB(q_position_base)[i] = j; j += 1 << CAB(q_extra_bits)[i];
842 }
843
844 /* initialize arithmetic coding models */
845
846 QTMfdi_initmodel(&QTM(model7), &QTM(m7sym)[0], 7, 0);
847
848 QTMfdi_initmodel(&QTM(model00), &QTM(m00sym)[0], 0x40, 0x00);
849 QTMfdi_initmodel(&QTM(model40), &QTM(m40sym)[0], 0x40, 0x40);
850 QTMfdi_initmodel(&QTM(model80), &QTM(m80sym)[0], 0x40, 0x80);
851 QTMfdi_initmodel(&QTM(modelC0), &QTM(mC0sym)[0], 0x40, 0xC0);
852
853 /* model 4 depends on table size, ranges from 20 to 24 */
854 QTMfdi_initmodel(&QTM(model4), &QTM(m4sym)[0], (msz < 24) ? msz : 24, 0);
855 /* model 5 depends on table size, ranges from 20 to 36 */
856 QTMfdi_initmodel(&QTM(model5), &QTM(m5sym)[0], (msz < 36) ? msz : 36, 0);
857 /* model 6pos depends on table size, ranges from 20 to 42 */
858 QTMfdi_initmodel(&QTM(model6pos), &QTM(m6psym)[0], msz, 0);
859 QTMfdi_initmodel(&QTM(model6len), &QTM(m6lsym)[0], 27, 0);
860
861 return DECR_OK;
862 }
863
864 /************************************************************
865 * LZXfdi_init (internal)
866 */
867 static int LZXfdi_init(int window, fdi_decomp_state *decomp_state) {
868 static const cab_UBYTE bits[] =
869 { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
870 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14,
871 15, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
872 17, 17, 17};
873 static const cab_ULONG base[] =
874 { 0, 1, 2, 3, 4, 6, 8, 12,
875 16, 24, 32, 48, 64, 96, 128, 192,
876 256, 384, 512, 768, 1024, 1536, 2048, 3072,
877 4096, 6144, 8192, 12288, 16384, 24576, 32768, 49152,
878 65536, 98304, 131072, 196608, 262144, 393216, 524288, 655360,
879 786432, 917504, 1048576, 1179648, 1310720, 1441792, 1572864, 1703936,
880 1835008, 1966080, 2097152};
881 cab_ULONG wndsize = 1 << window;
882 int posn_slots;
883
884 /* LZX supports window sizes of 2^15 (32Kb) through 2^21 (2Mb) */
885 /* if a previously allocated window is big enough, keep it */
886 if (window < 15 || window > 21) return DECR_DATAFORMAT;
887 if (LZX(actual_size) < wndsize) {
888 if (LZX(window)) PFDI_FREE(CAB(hfdi), LZX(window));
889 LZX(window) = NULL;
890 }
891 if (!LZX(window)) {
892 if (!(LZX(window) = PFDI_ALLOC(CAB(hfdi), wndsize))) return DECR_NOMEMORY;
893 LZX(actual_size) = wndsize;
894 }
895 LZX(window_size) = wndsize;
896
897 /* initialize static tables */
898 memcpy(CAB(extra_bits), bits, sizeof(bits));
899 memcpy(CAB(lzx_position_base), base, sizeof(base));
900
901 /* calculate required position slots */
902 if (window == 20) posn_slots = 42;
903 else if (window == 21) posn_slots = 50;
904 else posn_slots = window << 1;
905
906 /*posn_slots=i=0; while (i < wndsize) i += 1 << CAB(extra_bits)[posn_slots++]; */
907
908 LZX(R0) = LZX(R1) = LZX(R2) = 1;
909 LZX(main_elements) = LZX_NUM_CHARS + (posn_slots << 3);
910 LZX(header_read) = 0;
911 LZX(frames_read) = 0;
912 LZX(block_remaining) = 0;
913 LZX(block_type) = LZX_BLOCKTYPE_INVALID;
914 LZX(intel_curpos) = 0;
915 LZX(intel_started) = 0;
916 LZX(window_posn) = 0;
917
918 /* initialize tables to 0 (because deltas will be applied to them) */
919 memset(LZX(MAINTREE_len), 0, sizeof(LZX(MAINTREE_len)));
920 memset(LZX(LENGTH_len), 0, sizeof(LZX(LENGTH_len)));
921
922 return DECR_OK;
923 }
924
925 /****************************************************
926 * NONEfdi_decomp(internal)
927 */
928 static int NONEfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state)
929 {
930 if (inlen != outlen) return DECR_ILLEGALDATA;
931 memcpy(CAB(outbuf), CAB(inbuf), (size_t) inlen);
932 return DECR_OK;
933 }
934
935 /********************************************************
936 * Ziphuft_free (internal)
937 */
938 static void fdi_Ziphuft_free(HFDI hfdi, struct Ziphuft *t)
939 {
940 register struct Ziphuft *p, *q;
941
942 /* Go through linked list, freeing from the allocated (t[-1]) address. */
943 p = t;
944 while (p != (struct Ziphuft *)NULL)
945 {
946 q = (--p)->v.t;
947 PFDI_FREE(hfdi, p);
948 p = q;
949 }
950 }
951
952 /*********************************************************
953 * fdi_Ziphuft_build (internal)
954 */
955 static cab_LONG fdi_Ziphuft_build(cab_ULONG *b, cab_ULONG n, cab_ULONG s, const cab_UWORD *d, const cab_UWORD *e,
956 struct Ziphuft **t, cab_LONG *m, fdi_decomp_state *decomp_state)
957 {
958 cab_ULONG a; /* counter for codes of length k */
959 cab_ULONG el; /* length of EOB code (value 256) */
960 cab_ULONG f; /* i repeats in table every f entries */
961 cab_LONG g; /* maximum code length */
962 cab_LONG h; /* table level */
963 register cab_ULONG i; /* counter, current code */
964 register cab_ULONG j; /* counter */
965 register cab_LONG k; /* number of bits in current code */
966 cab_LONG *l; /* stack of bits per table */
967 register cab_ULONG *p; /* pointer into ZIP(c)[],ZIP(b)[],ZIP(v)[] */
968 register struct Ziphuft *q; /* points to current table */
969 struct Ziphuft r; /* table entry for structure assignment */
970 register cab_LONG w; /* bits before this table == (l * h) */
971 cab_ULONG *xp; /* pointer into x */
972 cab_LONG y; /* number of dummy codes added */
973 cab_ULONG z; /* number of entries in current table */
974
975 l = ZIP(lx)+1;
976
977 /* Generate counts for each bit length */
978 el = n > 256 ? b[256] : ZIPBMAX; /* set length of EOB code, if any */
979
980 for(i = 0; i < ZIPBMAX+1; ++i)
981 ZIP(c)[i] = 0;
982 p = b; i = n;
983 do
984 {
985 ZIP(c)[*p]++; p++; /* assume all entries <= ZIPBMAX */
986 } while (--i);
987 if (ZIP(c)[0] == n) /* null input--all zero length codes */
988 {
989 *t = (struct Ziphuft *)NULL;
990 *m = 0;
991 return 0;
992 }
993
994 /* Find minimum and maximum length, bound *m by those */
995 for (j = 1; j <= ZIPBMAX; j++)
996 if (ZIP(c)[j])
997 break;
998 k = j; /* minimum code length */
999 if ((cab_ULONG)*m < j)
1000 *m = j;
1001 for (i = ZIPBMAX; i; i--)
1002 if (ZIP(c)[i])
1003 break;
1004 g = i; /* maximum code length */
1005 if ((cab_ULONG)*m > i)
1006 *m = i;
1007
1008 /* Adjust last length count to fill out codes, if needed */
1009 for (y = 1 << j; j < i; j++, y <<= 1)
1010 if ((y -= ZIP(c)[j]) < 0)
1011 return 2; /* bad input: more codes than bits */
1012 if ((y -= ZIP(c)[i]) < 0)
1013 return 2;
1014 ZIP(c)[i] += y;
1015
1016 /* Generate starting offsets LONGo the value table for each length */
1017 ZIP(x)[1] = j = 0;
1018 p = ZIP(c) + 1; xp = ZIP(x) + 2;
1019 while (--i)
1020 { /* note that i == g from above */
1021 *xp++ = (j += *p++);
1022 }
1023
1024 /* Make a table of values in order of bit lengths */
1025 p = b; i = 0;
1026 do{
1027 if ((j = *p++) != 0)
1028 ZIP(v)[ZIP(x)[j]++] = i;
1029 } while (++i < n);
1030
1031
1032 /* Generate the Huffman codes and for each, make the table entries */
1033 ZIP(x)[0] = i = 0; /* first Huffman code is zero */
1034 p = ZIP(v); /* grab values in bit order */
1035 h = -1; /* no tables yet--level -1 */
1036 w = l[-1] = 0; /* no bits decoded yet */
1037 ZIP(u)[0] = (struct Ziphuft *)NULL; /* just to keep compilers happy */
1038 q = (struct Ziphuft *)NULL; /* ditto */
1039 z = 0; /* ditto */
1040
1041 /* go through the bit lengths (k already is bits in shortest code) */
1042 for (; k <= g; k++)
1043 {
1044 a = ZIP(c)[k];
1045 while (a--)
1046 {
1047 /* here i is the Huffman code of length k bits for value *p */
1048 /* make tables up to required level */
1049 while (k > w + l[h])
1050 {
1051 w += l[h++]; /* add bits already decoded */
1052
1053 /* compute minimum size table less than or equal to *m bits */
1054 z = (z = g - w) > (cab_ULONG)*m ? *m : z; /* upper limit */
1055 if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
1056 { /* too few codes for k-w bit table */
1057 f -= a + 1; /* deduct codes from patterns left */
1058 xp = ZIP(c) + k;
1059 while (++j < z) /* try smaller tables up to z bits */
1060 {
1061 if ((f <<= 1) <= *++xp)
1062 break; /* enough codes to use up j bits */
1063 f -= *xp; /* else deduct codes from patterns */
1064 }
1065 }
1066 if ((cab_ULONG)w + j > el && (cab_ULONG)w < el)
1067 j = el - w; /* make EOB code end at table */
1068 z = 1 << j; /* table entries for j-bit table */
1069 l[h] = j; /* set table size in stack */
1070
1071 /* allocate and link in new table */
1072 if (!(q = (struct Ziphuft *) PFDI_ALLOC(CAB(hfdi), (z + 1)*sizeof(struct Ziphuft))))
1073 {
1074 if(h)
1075 fdi_Ziphuft_free(CAB(hfdi), ZIP(u)[0]);
1076 return 3; /* not enough memory */
1077 }
1078 *t = q + 1; /* link to list for Ziphuft_free() */
1079 *(t = &(q->v.t)) = (struct Ziphuft *)NULL;
1080 ZIP(u)[h] = ++q; /* table starts after link */
1081
1082 /* connect to last table, if there is one */
1083 if (h)
1084 {
1085 ZIP(x)[h] = i; /* save pattern for backing up */
1086 r.b = (cab_UBYTE)l[h-1]; /* bits to dump before this table */
1087 r.e = (cab_UBYTE)(16 + j); /* bits in this table */
1088 r.v.t = q; /* pointer to this table */
1089 j = (i & ((1 << w) - 1)) >> (w - l[h-1]);
1090 ZIP(u)[h-1][j] = r; /* connect to last table */
1091 }
1092 }
1093
1094 /* set up table entry in r */
1095 r.b = (cab_UBYTE)(k - w);
1096 if (p >= ZIP(v) + n)
1097 r.e = 99; /* out of values--invalid code */
1098 else if (*p < s)
1099 {
1100 r.e = (cab_UBYTE)(*p < 256 ? 16 : 15); /* 256 is end-of-block code */
1101 r.v.n = *p++; /* simple code is just the value */
1102 }
1103 else
1104 {
1105 r.e = (cab_UBYTE)e[*p - s]; /* non-simple--look up in lists */
1106 r.v.n = d[*p++ - s];
1107 }
1108
1109 /* fill code-like entries with r */
1110 f = 1 << (k - w);
1111 for (j = i >> w; j < z; j += f)
1112 q[j] = r;
1113
1114 /* backwards increment the k-bit code i */
1115 for (j = 1 << (k - 1); i & j; j >>= 1)
1116 i ^= j;
1117 i ^= j;
1118
1119 /* backup over finished tables */
1120 while ((i & ((1 << w) - 1)) != ZIP(x)[h])
1121 w -= l[--h]; /* don't need to update q */
1122 }
1123 }
1124
1125 /* return actual size of base table */
1126 *m = l[0];
1127
1128 /* Return true (1) if we were given an incomplete table */
1129 return y != 0 && g != 1;
1130 }
1131
1132 /*********************************************************
1133 * fdi_Zipinflate_codes (internal)
1134 */
1135 static cab_LONG fdi_Zipinflate_codes(struct Ziphuft *tl, struct Ziphuft *td,
1136 cab_LONG bl, cab_LONG bd, fdi_decomp_state *decomp_state)
1137 {
1138 register cab_ULONG e; /* table entry flag/number of extra bits */
1139 cab_ULONG n, d; /* length and index for copy */
1140 cab_ULONG w; /* current window position */
1141 struct Ziphuft *t; /* pointer to table entry */
1142 cab_ULONG ml, md; /* masks for bl and bd bits */
1143 register cab_ULONG b; /* bit buffer */
1144 register cab_ULONG k; /* number of bits in bit buffer */
1145
1146 /* make local copies of globals */
1147 b = ZIP(bb); /* initialize bit buffer */
1148 k = ZIP(bk);
1149 w = ZIP(window_posn); /* initialize window position */
1150
1151 /* inflate the coded data */
1152 ml = Zipmask[bl]; /* precompute masks for speed */
1153 md = Zipmask[bd];
1154
1155 for(;;)
1156 {
1157 ZIPNEEDBITS((cab_ULONG)bl)
1158 if((e = (t = tl + ((cab_ULONG)b & ml))->e) > 16)
1159 do
1160 {
1161 if (e == 99)
1162 return 1;
1163 ZIPDUMPBITS(t->b)
1164 e -= 16;
1165 ZIPNEEDBITS(e)
1166 } while ((e = (t = t->v.t + ((cab_ULONG)b & Zipmask[e]))->e) > 16);
1167 ZIPDUMPBITS(t->b)
1168 if (e == 16) /* then it's a literal */
1169 CAB(outbuf)[w++] = (cab_UBYTE)t->v.n;
1170 else /* it's an EOB or a length */
1171 {
1172 /* exit if end of block */
1173 if(e == 15)
1174 break;
1175
1176 /* get length of block to copy */
1177 ZIPNEEDBITS(e)
1178 n = t->v.n + ((cab_ULONG)b & Zipmask[e]);
1179 ZIPDUMPBITS(e);
1180
1181 /* decode distance of block to copy */
1182 ZIPNEEDBITS((cab_ULONG)bd)
1183 if ((e = (t = td + ((cab_ULONG)b & md))->e) > 16)
1184 do {
1185 if (e == 99)
1186 return 1;
1187 ZIPDUMPBITS(t->b)
1188 e -= 16;
1189 ZIPNEEDBITS(e)
1190 } while ((e = (t = t->v.t + ((cab_ULONG)b & Zipmask[e]))->e) > 16);
1191 ZIPDUMPBITS(t->b)
1192 ZIPNEEDBITS(e)
1193 d = w - t->v.n - ((cab_ULONG)b & Zipmask[e]);
1194 ZIPDUMPBITS(e)
1195 do
1196 {
1197 n -= (e = (e = ZIPWSIZE - ((d &= ZIPWSIZE-1) > w ? d : w)) > n ?n:e);
1198 do
1199 {
1200 CAB(outbuf)[w++] = CAB(outbuf)[d++];
1201 } while (--e);
1202 } while (n);
1203 }
1204 }
1205
1206 /* restore the globals from the locals */
1207 ZIP(window_posn) = w; /* restore global window pointer */
1208 ZIP(bb) = b; /* restore global bit buffer */
1209 ZIP(bk) = k;
1210
1211 /* done */
1212 return 0;
1213 }
1214
1215 /***********************************************************
1216 * Zipinflate_stored (internal)
1217 */
1218 static cab_LONG fdi_Zipinflate_stored(fdi_decomp_state *decomp_state)
1219 /* "decompress" an inflated type 0 (stored) block. */
1220 {
1221 cab_ULONG n; /* number of bytes in block */
1222 cab_ULONG w; /* current window position */
1223 register cab_ULONG b; /* bit buffer */
1224 register cab_ULONG k; /* number of bits in bit buffer */
1225
1226 /* make local copies of globals */
1227 b = ZIP(bb); /* initialize bit buffer */
1228 k = ZIP(bk);
1229 w = ZIP(window_posn); /* initialize window position */
1230
1231 /* go to byte boundary */
1232 n = k & 7;
1233 ZIPDUMPBITS(n);
1234
1235 /* get the length and its complement */
1236 ZIPNEEDBITS(16)
1237 n = ((cab_ULONG)b & 0xffff);
1238 ZIPDUMPBITS(16)
1239 ZIPNEEDBITS(16)
1240 if (n != (cab_ULONG)((~b) & 0xffff))
1241 return 1; /* error in compressed data */
1242 ZIPDUMPBITS(16)
1243
1244 /* read and output the compressed data */
1245 while(n--)
1246 {
1247 ZIPNEEDBITS(8)
1248 CAB(outbuf)[w++] = (cab_UBYTE)b;
1249 ZIPDUMPBITS(8)
1250 }
1251
1252 /* restore the globals from the locals */
1253 ZIP(window_posn) = w; /* restore global window pointer */
1254 ZIP(bb) = b; /* restore global bit buffer */
1255 ZIP(bk) = k;
1256 return 0;
1257 }
1258
1259 /******************************************************
1260 * fdi_Zipinflate_fixed (internal)
1261 */
1262 static cab_LONG fdi_Zipinflate_fixed(fdi_decomp_state *decomp_state)
1263 {
1264 struct Ziphuft *fixed_tl;
1265 struct Ziphuft *fixed_td;
1266 cab_LONG fixed_bl, fixed_bd;
1267 cab_LONG i; /* temporary variable */
1268 cab_ULONG *l;
1269
1270 l = ZIP(ll);
1271
1272 /* literal table */
1273 for(i = 0; i < 144; i++)
1274 l[i] = 8;
1275 for(; i < 256; i++)
1276 l[i] = 9;
1277 for(; i < 280; i++)
1278 l[i] = 7;
1279 for(; i < 288; i++) /* make a complete, but wrong code set */
1280 l[i] = 8;
1281 fixed_bl = 7;
1282 if((i = fdi_Ziphuft_build(l, 288, 257, Zipcplens, Zipcplext, &fixed_tl, &fixed_bl, decomp_state)))
1283 return i;
1284
1285 /* distance table */
1286 for(i = 0; i < 30; i++) /* make an incomplete code set */
1287 l[i] = 5;
1288 fixed_bd = 5;
1289 if((i = fdi_Ziphuft_build(l, 30, 0, Zipcpdist, Zipcpdext, &fixed_td, &fixed_bd, decomp_state)) > 1)
1290 {
1291 fdi_Ziphuft_free(CAB(hfdi), fixed_tl);
1292 return i;
1293 }
1294
1295 /* decompress until an end-of-block code */
1296 i = fdi_Zipinflate_codes(fixed_tl, fixed_td, fixed_bl, fixed_bd, decomp_state);
1297
1298 fdi_Ziphuft_free(CAB(hfdi), fixed_td);
1299 fdi_Ziphuft_free(CAB(hfdi), fixed_tl);
1300 return i;
1301 }
1302
1303 /**************************************************************
1304 * fdi_Zipinflate_dynamic (internal)
1305 */
1306 static cab_LONG fdi_Zipinflate_dynamic(fdi_decomp_state *decomp_state)
1307 /* decompress an inflated type 2 (dynamic Huffman codes) block. */
1308 {
1309 cab_LONG i; /* temporary variables */
1310 cab_ULONG j;
1311 cab_ULONG *ll;
1312 cab_ULONG l; /* last length */
1313 cab_ULONG m; /* mask for bit lengths table */
1314 cab_ULONG n; /* number of lengths to get */
1315 struct Ziphuft *tl; /* literal/length code table */
1316 struct Ziphuft *td; /* distance code table */
1317 cab_LONG bl; /* lookup bits for tl */
1318 cab_LONG bd; /* lookup bits for td */
1319 cab_ULONG nb; /* number of bit length codes */
1320 cab_ULONG nl; /* number of literal/length codes */
1321 cab_ULONG nd; /* number of distance codes */
1322 register cab_ULONG b; /* bit buffer */
1323 register cab_ULONG k; /* number of bits in bit buffer */
1324
1325 /* make local bit buffer */
1326 b = ZIP(bb);
1327 k = ZIP(bk);
1328 ll = ZIP(ll);
1329
1330 /* read in table lengths */
1331 ZIPNEEDBITS(5)
1332 nl = 257 + ((cab_ULONG)b & 0x1f); /* number of literal/length codes */
1333 ZIPDUMPBITS(5)
1334 ZIPNEEDBITS(5)
1335 nd = 1 + ((cab_ULONG)b & 0x1f); /* number of distance codes */
1336 ZIPDUMPBITS(5)
1337 ZIPNEEDBITS(4)
1338 nb = 4 + ((cab_ULONG)b & 0xf); /* number of bit length codes */
1339 ZIPDUMPBITS(4)
1340 if(nl > 288 || nd > 32)
1341 return 1; /* bad lengths */
1342
1343 /* read in bit-length-code lengths */
1344 for(j = 0; j < nb; j++)
1345 {
1346 ZIPNEEDBITS(3)
1347 ll[Zipborder[j]] = (cab_ULONG)b & 7;
1348 ZIPDUMPBITS(3)
1349 }
1350 for(; j < 19; j++)
1351 ll[Zipborder[j]] = 0;
1352
1353 /* build decoding table for trees--single level, 7 bit lookup */
1354 bl = 7;
1355 if((i = fdi_Ziphuft_build(ll, 19, 19, NULL, NULL, &tl, &bl, decomp_state)) != 0)
1356 {
1357 if(i == 1)
1358 fdi_Ziphuft_free(CAB(hfdi), tl);
1359 return i; /* incomplete code set */
1360 }
1361
1362 /* read in literal and distance code lengths */
1363 n = nl + nd;
1364 m = Zipmask[bl];
1365 i = l = 0;
1366 while((cab_ULONG)i < n)
1367 {
1368 ZIPNEEDBITS((cab_ULONG)bl)
1369 j = (td = tl + ((cab_ULONG)b & m))->b;
1370 ZIPDUMPBITS(j)
1371 j = td->v.n;
1372 if (j < 16) /* length of code in bits (0..15) */
1373 ll[i++] = l = j; /* save last length in l */
1374 else if (j == 16) /* repeat last length 3 to 6 times */
1375 {
1376 ZIPNEEDBITS(2)
1377 j = 3 + ((cab_ULONG)b & 3);
1378 ZIPDUMPBITS(2)
1379 if((cab_ULONG)i + j > n)
1380 return 1;
1381 while (j--)
1382 ll[i++] = l;
1383 }
1384 else if (j == 17) /* 3 to 10 zero length codes */
1385 {
1386 ZIPNEEDBITS(3)
1387 j = 3 + ((cab_ULONG)b & 7);
1388 ZIPDUMPBITS(3)
1389 if ((cab_ULONG)i + j > n)
1390 return 1;
1391 while (j--)
1392 ll[i++] = 0;
1393 l = 0;
1394 }
1395 else /* j == 18: 11 to 138 zero length codes */
1396 {
1397 ZIPNEEDBITS(7)
1398 j = 11 + ((cab_ULONG)b & 0x7f);
1399 ZIPDUMPBITS(7)
1400 if ((cab_ULONG)i + j > n)
1401 return 1;
1402 while (j--)
1403 ll[i++] = 0;
1404 l = 0;
1405 }
1406 }
1407
1408 /* free decoding table for trees */
1409 fdi_Ziphuft_free(CAB(hfdi), tl);
1410
1411 /* restore the global bit buffer */
1412 ZIP(bb) = b;
1413 ZIP(bk) = k;
1414
1415 /* build the decoding tables for literal/length and distance codes */
1416 bl = ZIPLBITS;
1417 if((i = fdi_Ziphuft_build(ll, nl, 257, Zipcplens, Zipcplext, &tl, &bl, decomp_state)) != 0)
1418 {
1419 if(i == 1)
1420 fdi_Ziphuft_free(CAB(hfdi), tl);
1421 return i; /* incomplete code set */
1422 }
1423 bd = ZIPDBITS;
1424 fdi_Ziphuft_build(ll + nl, nd, 0, Zipcpdist, Zipcpdext, &td, &bd, decomp_state);
1425
1426 /* decompress until an end-of-block code */
1427 if(fdi_Zipinflate_codes(tl, td, bl, bd, decomp_state))
1428 return 1;
1429
1430 /* free the decoding tables, return */
1431 fdi_Ziphuft_free(CAB(hfdi), tl);
1432 fdi_Ziphuft_free(CAB(hfdi), td);
1433 return 0;
1434 }
1435
1436 /*****************************************************
1437 * fdi_Zipinflate_block (internal)
1438 */
1439 static cab_LONG fdi_Zipinflate_block(cab_LONG *e, fdi_decomp_state *decomp_state) /* e == last block flag */
1440 { /* decompress an inflated block */
1441 cab_ULONG t; /* block type */
1442 register cab_ULONG b; /* bit buffer */
1443 register cab_ULONG k; /* number of bits in bit buffer */
1444
1445 /* make local bit buffer */
1446 b = ZIP(bb);
1447 k = ZIP(bk);
1448
1449 /* read in last block bit */
1450 ZIPNEEDBITS(1)
1451 *e = (cab_LONG)b & 1;
1452 ZIPDUMPBITS(1)
1453
1454 /* read in block type */
1455 ZIPNEEDBITS(2)
1456 t = (cab_ULONG)b & 3;
1457 ZIPDUMPBITS(2)
1458
1459 /* restore the global bit buffer */
1460 ZIP(bb) = b;
1461 ZIP(bk) = k;
1462
1463 /* inflate that block type */
1464 if(t == 2)
1465 return fdi_Zipinflate_dynamic(decomp_state);
1466 if(t == 0)
1467 return fdi_Zipinflate_stored(decomp_state);
1468 if(t == 1)
1469 return fdi_Zipinflate_fixed(decomp_state);
1470 /* bad block type */
1471 return 2;
1472 }
1473
1474 /****************************************************
1475 * ZIPfdi_decomp(internal)
1476 */
1477 static int ZIPfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state)
1478 {
1479 cab_LONG e; /* last block flag */
1480
1481 TRACE("(inlen == %d, outlen == %d)\n", inlen, outlen);
1482
1483 ZIP(inpos) = CAB(inbuf);
1484 ZIP(bb) = ZIP(bk) = ZIP(window_posn) = 0;
1485 if(outlen > ZIPWSIZE)
1486 return DECR_DATAFORMAT;
1487
1488 /* CK = Chris Kirmse, official Microsoft purloiner */
1489 if(ZIP(inpos)[0] != 0x43 || ZIP(inpos)[1] != 0x4B)
1490 return DECR_ILLEGALDATA;
1491 ZIP(inpos) += 2;
1492
1493 do {
1494 if(fdi_Zipinflate_block(&e, decomp_state))
1495 return DECR_ILLEGALDATA;
1496 } while(!e);
1497
1498 /* return success */
1499 return DECR_OK;
1500 }
1501
1502 /*******************************************************************
1503 * QTMfdi_decomp(internal)
1504 */
1505 static int QTMfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state)
1506 {
1507 cab_UBYTE *inpos = CAB(inbuf);
1508 cab_UBYTE *window = QTM(window);
1509 cab_UBYTE *runsrc, *rundest;
1510
1511 cab_ULONG window_posn = QTM(window_posn);
1512 cab_ULONG window_size = QTM(window_size);
1513
1514 /* used by bitstream macros */
1515 register int bitsleft, bitrun, bitsneed;
1516 register cab_ULONG bitbuf;
1517
1518 /* used by GET_SYMBOL */
1519 cab_ULONG range;
1520 cab_UWORD symf;
1521 int i;
1522
1523 int extra, togo = outlen, match_length = 0, copy_length;
1524 cab_UBYTE selector, sym;
1525 cab_ULONG match_offset = 0;
1526
1527 cab_UWORD H = 0xFFFF, L = 0, C;
1528
1529 TRACE("(inlen == %d, outlen == %d)\n", inlen, outlen);
1530
1531 /* read initial value of C */
1532 Q_INIT_BITSTREAM;
1533 Q_READ_BITS(C, 16);
1534
1535 /* apply 2^x-1 mask */
1536 window_posn &= window_size - 1;
1537 /* runs can't straddle the window wraparound */
1538 if ((window_posn + togo) > window_size) {
1539 TRACE("straddled run\n");
1540 return DECR_DATAFORMAT;
1541 }
1542
1543 while (togo > 0) {
1544 GET_SYMBOL(model7, selector);
1545 switch (selector) {
1546 case 0:
1547 GET_SYMBOL(model00, sym); window[window_posn++] = sym; togo--;
1548 break;
1549 case 1:
1550 GET_SYMBOL(model40, sym); window[window_posn++] = sym; togo--;
1551 break;
1552 case 2:
1553 GET_SYMBOL(model80, sym); window[window_posn++] = sym; togo--;
1554 break;
1555 case 3:
1556 GET_SYMBOL(modelC0, sym); window[window_posn++] = sym; togo--;
1557 break;
1558
1559 case 4:
1560 /* selector 4 = fixed length of 3 */
1561 GET_SYMBOL(model4, sym);
1562 Q_READ_BITS(extra, CAB(q_extra_bits)[sym]);
1563 match_offset = CAB(q_position_base)[sym] + extra + 1;
1564 match_length = 3;
1565 break;
1566
1567 case 5:
1568 /* selector 5 = fixed length of 4 */
1569 GET_SYMBOL(model5, sym);
1570 Q_READ_BITS(extra, CAB(q_extra_bits)[sym]);
1571 match_offset = CAB(q_position_base)[sym] + extra + 1;
1572 match_length = 4;
1573 break;
1574
1575 case 6:
1576 /* selector 6 = variable length */
1577 GET_SYMBOL(model6len, sym);
1578 Q_READ_BITS(extra, CAB(q_length_extra)[sym]);
1579 match_length = CAB(q_length_base)[sym] + extra + 5;
1580 GET_SYMBOL(model6pos, sym);
1581 Q_READ_BITS(extra, CAB(q_extra_bits)[sym]);
1582 match_offset = CAB(q_position_base)[sym] + extra + 1;
1583 break;
1584
1585 default:
1586 TRACE("Selector is bogus\n");
1587 return DECR_ILLEGALDATA;
1588 }
1589
1590 /* if this is a match */
1591 if (selector >= 4) {
1592 rundest = window + window_posn;
1593 togo -= match_length;
1594
1595 /* copy any wrapped around source data */
1596 if (window_posn >= match_offset) {
1597 /* no wrap */
1598 runsrc = rundest - match_offset;
1599 } else {
1600 runsrc = rundest + (window_size - match_offset);
1601 copy_length = match_offset - window_posn;
1602 if (copy_length < match_length) {
1603 match_length -= copy_length;
1604 window_posn += copy_length;
1605 while (copy_length-- > 0) *rundest++ = *runsrc++;
1606 runsrc = window;
1607 }
1608 }
1609 window_posn += match_length;
1610
1611 /* copy match data - no worries about destination wraps */
1612 while (match_length-- > 0) *rundest++ = *runsrc++;
1613 }
1614 } /* while (togo > 0) */
1615
1616 if (togo != 0) {
1617 TRACE("Frame overflow, this_run = %d\n", togo);
1618 return DECR_ILLEGALDATA;
1619 }
1620
1621 memcpy(CAB(outbuf), window + ((!window_posn) ? window_size : window_posn) -
1622 outlen, outlen);
1623
1624 QTM(window_posn) = window_posn;
1625 return DECR_OK;
1626 }
1627
1628 /************************************************************
1629 * fdi_lzx_read_lens (internal)
1630 */
1631 static int fdi_lzx_read_lens(cab_UBYTE *lens, cab_ULONG first, cab_ULONG last, struct lzx_bits *lb,
1632 fdi_decomp_state *decomp_state) {
1633 cab_ULONG i,j, x,y;
1634 int z;
1635
1636 register cab_ULONG bitbuf = lb->bb;
1637 register int bitsleft = lb->bl;
1638 cab_UBYTE *inpos = lb->ip;
1639 cab_UWORD *hufftbl;
1640
1641 for (x = 0; x < 20; x++) {
1642 READ_BITS(y, 4);
1643 LENTABLE(PRETREE)[x] = y;
1644 }
1645 BUILD_TABLE(PRETREE);
1646
1647 for (x = first; x < last; ) {
1648 READ_HUFFSYM(PRETREE, z);
1649 if (z == 17) {
1650 READ_BITS(y, 4); y += 4;
1651 while (y--) lens[x++] = 0;
1652 }
1653 else if (z == 18) {
1654 READ_BITS(y, 5); y += 20;
1655 while (y--) lens[x++] = 0;
1656 }
1657 else if (z == 19) {
1658 READ_BITS(y, 1); y += 4;
1659 READ_HUFFSYM(PRETREE, z);
1660 z = lens[x] - z; if (z < 0) z += 17;
1661 while (y--) lens[x++] = z;
1662 }
1663 else {
1664 z = lens[x] - z; if (z < 0) z += 17;
1665 lens[x++] = z;
1666 }
1667 }
1668
1669 lb->bb = bitbuf;
1670 lb->bl = bitsleft;
1671 lb->ip = inpos;
1672 return 0;
1673 }
1674
1675 /*******************************************************
1676 * LZXfdi_decomp(internal)
1677 */
1678 static int LZXfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state) {
1679 cab_UBYTE *inpos = CAB(inbuf);
1680 cab_UBYTE *endinp = inpos + inlen;
1681 cab_UBYTE *window = LZX(window);
1682 cab_UBYTE *runsrc, *rundest;
1683 cab_UWORD *hufftbl; /* used in READ_HUFFSYM macro as chosen decoding table */
1684
1685 cab_ULONG window_posn = LZX(window_posn);
1686 cab_ULONG window_size = LZX(window_size);
1687 cab_ULONG R0 = LZX(R0);
1688 cab_ULONG R1 = LZX(R1);
1689 cab_ULONG R2 = LZX(R2);
1690
1691 register cab_ULONG bitbuf;
1692 register int bitsleft;
1693 cab_ULONG match_offset, i,j,k; /* ijk used in READ_HUFFSYM macro */
1694 struct lzx_bits lb; /* used in READ_LENGTHS macro */
1695
1696 int togo = outlen, this_run, main_element, aligned_bits;
1697 int match_length, copy_length, length_footer, extra, verbatim_bits;
1698
1699 TRACE("(inlen == %d, outlen == %d)\n", inlen, outlen);
1700
1701 INIT_BITSTREAM;
1702
1703 /* read header if necessary */
1704 if (!LZX(header_read)) {
1705 i = j = 0;
1706 READ_BITS(k, 1); if (k) { READ_BITS(i,16); READ_BITS(j,16); }
1707 LZX(intel_filesize) = (i << 16) | j; /* or 0 if not encoded */
1708 LZX(header_read) = 1;
1709 }
1710
1711 /* main decoding loop */
1712 while (togo > 0) {
1713 /* last block finished, new block expected */
1714 if (LZX(block_remaining) == 0) {
1715 if (LZX(block_type) == LZX_BLOCKTYPE_UNCOMPRESSED) {
1716 if (LZX(block_length) & 1) inpos++; /* realign bitstream to word */
1717 INIT_BITSTREAM;
1718 }
1719
1720 READ_BITS(LZX(block_type), 3);
1721 READ_BITS(i, 16);
1722 READ_BITS(j, 8);
1723 LZX(block_remaining) = LZX(block_length) = (i << 8) | j;
1724
1725 switch (LZX(block_type)) {
1726 case LZX_BLOCKTYPE_ALIGNED:
1727 for (i = 0; i < 8; i++) { READ_BITS(j, 3); LENTABLE(ALIGNED)[i] = j; }
1728 BUILD_TABLE(ALIGNED);
1729 /* rest of aligned header is same as verbatim */
1730
1731 case LZX_BLOCKTYPE_VERBATIM:
1732 READ_LENGTHS(MAINTREE, 0, 256, fdi_lzx_read_lens);
1733 READ_LENGTHS(MAINTREE, 256, LZX(main_elements), fdi_lzx_read_lens);
1734 BUILD_TABLE(MAINTREE);
1735 if (LENTABLE(MAINTREE)[0xE8] != 0) LZX(intel_started) = 1;
1736
1737 READ_LENGTHS(LENGTH, 0, LZX_NUM_SECONDARY_LENGTHS, fdi_lzx_read_lens);
1738 BUILD_TABLE(LENGTH);
1739 break;
1740
1741 case LZX_BLOCKTYPE_UNCOMPRESSED:
1742 LZX(intel_started) = 1; /* because we can't assume otherwise */
1743 ENSURE_BITS(16); /* get up to 16 pad bits into the buffer */
1744 if (bitsleft > 16) inpos -= 2; /* and align the bitstream! */
1745 R0 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
1746 R1 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
1747 R2 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
1748 break;
1749
1750 default:
1751 return DECR_ILLEGALDATA;
1752 }
1753 }
1754
1755 /* buffer exhaustion check */
1756 if (inpos > endinp) {
1757 /* it's possible to have a file where the next run is less than
1758 * 16 bits in size. In this case, the READ_HUFFSYM() macro used
1759 * in building the tables will exhaust the buffer, so we should
1760 * allow for this, but not allow those accidentally read bits to
1761 * be used (so we check that there are at least 16 bits
1762 * remaining - in this boundary case they aren't really part of
1763 * the compressed data)
1764 */
1765 if (inpos > (endinp+2) || bitsleft < 16) return DECR_ILLEGALDATA;
1766 }
1767
1768 while ((this_run = LZX(block_remaining)) > 0 && togo > 0) {
1769 if (this_run > togo) this_run = togo;
1770 togo -= this_run;
1771 LZX(block_remaining) -= this_run;
1772
1773 /* apply 2^x-1 mask */
1774 window_posn &= window_size - 1;
1775 /* runs can't straddle the window wraparound */
1776 if ((window_posn + this_run) > window_size)
1777 return DECR_DATAFORMAT;
1778
1779 switch (LZX(block_type)) {
1780
1781 case LZX_BLOCKTYPE_VERBATIM:
1782 while (this_run > 0) {
1783 READ_HUFFSYM(MAINTREE, main_element);
1784
1785 if (main_element < LZX_NUM_CHARS) {
1786 /* literal: 0 to LZX_NUM_CHARS-1 */
1787 window[window_posn++] = main_element;
1788 this_run--;
1789 }
1790 else {
1791 /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
1792 main_element -= LZX_NUM_CHARS;
1793
1794 match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
1795 if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
1796 READ_HUFFSYM(LENGTH, length_footer);
1797 match_length += length_footer;
1798 }
1799 match_length += LZX_MIN_MATCH;
1800
1801 match_offset = main_element >> 3;
1802
1803 if (match_offset > 2) {
1804 /* not repeated offset */
1805 if (match_offset != 3) {
1806 extra = CAB(extra_bits)[match_offset];
1807 READ_BITS(verbatim_bits, extra);
1808 match_offset = CAB(lzx_position_base)[match_offset]
1809 - 2 + verbatim_bits;
1810 }
1811 else {
1812 match_offset = 1;
1813 }
1814
1815 /* update repeated offset LRU queue */
1816 R2 = R1; R1 = R0; R0 = match_offset;
1817 }
1818 else if (match_offset == 0) {
1819 match_offset = R0;
1820 }
1821 else if (match_offset == 1) {
1822 match_offset = R1;
1823 R1 = R0; R0 = match_offset;
1824 }
1825 else /* match_offset == 2 */ {
1826 match_offset = R2;
1827 R2 = R0; R0 = match_offset;
1828 }
1829
1830 rundest = window + window_posn;
1831 this_run -= match_length;
1832
1833 /* copy any wrapped around source data */
1834 if (window_posn >= match_offset) {
1835 /* no wrap */
1836 runsrc = rundest - match_offset;
1837 } else {
1838 runsrc = rundest + (window_size - match_offset);
1839 copy_length = match_offset - window_posn;
1840 if (copy_length < match_length) {
1841 match_length -= copy_length;
1842 window_posn += copy_length;
1843 while (copy_length-- > 0) *rundest++ = *runsrc++;
1844 runsrc = window;
1845 }
1846 }
1847 window_posn += match_length;
1848
1849 /* copy match data - no worries about destination wraps */
1850 while (match_length-- > 0) *rundest++ = *runsrc++;
1851 }
1852 }
1853 break;
1854
1855 case LZX_BLOCKTYPE_ALIGNED:
1856 while (this_run > 0) {
1857 READ_HUFFSYM(MAINTREE, main_element);
1858
1859 if (main_element < LZX_NUM_CHARS) {
1860 /* literal: 0 to LZX_NUM_CHARS-1 */
1861 window[window_posn++] = main_element;
1862 this_run--;
1863 }
1864 else {
1865 /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
1866 main_element -= LZX_NUM_CHARS;
1867
1868 match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
1869 if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
1870 READ_HUFFSYM(LENGTH, length_footer);
1871 match_length += length_footer;
1872 }
1873 match_length += LZX_MIN_MATCH;
1874
1875 match_offset = main_element >> 3;
1876
1877 if (match_offset > 2) {
1878 /* not repeated offset */
1879 extra = CAB(extra_bits)[match_offset];
1880 match_offset = CAB(lzx_position_base)[match_offset] - 2;
1881 if (extra > 3) {
1882 /* verbatim and aligned bits */
1883 extra -= 3;
1884 READ_BITS(verbatim_bits, extra);
1885 match_offset += (verbatim_bits << 3);
1886 READ_HUFFSYM(ALIGNED, aligned_bits);
1887 match_offset += aligned_bits;
1888 }
1889 else if (extra == 3) {
1890 /* aligned bits only */
1891 READ_HUFFSYM(ALIGNED, aligned_bits);
1892 match_offset += aligned_bits;
1893 }
1894 else if (extra > 0) { /* extra==1, extra==2 */
1895 /* verbatim bits only */
1896 READ_BITS(verbatim_bits, extra);
1897 match_offset += verbatim_bits;
1898 }
1899 else /* extra == 0 */ {
1900 /* ??? */
1901 match_offset = 1;
1902 }
1903
1904 /* update repeated offset LRU queue */
1905 R2 = R1; R1 = R0; R0 = match_offset;
1906 }
1907 else if (match_offset == 0) {
1908 match_offset = R0;
1909 }
1910 else if (match_offset == 1) {
1911 match_offset = R1;
1912 R1 = R0; R0 = match_offset;
1913 }
1914 else /* match_offset == 2 */ {
1915 match_offset = R2;
1916 R2 = R0; R0 = match_offset;
1917 }
1918
1919 rundest = window + window_posn;
1920 this_run -= match_length;
1921
1922 /* copy any wrapped around source data */
1923 if (window_posn >= match_offset) {
1924 /* no wrap */
1925 runsrc = rundest - match_offset;
1926 } else {
1927 runsrc = rundest + (window_size - match_offset);
1928 copy_length = match_offset - window_posn;
1929 if (copy_length < match_length) {
1930 match_length -= copy_length;
1931 window_posn += copy_length;
1932 while (copy_length-- > 0) *rundest++ = *runsrc++;
1933 runsrc = window;
1934 }
1935 }
1936 window_posn += match_length;
1937
1938 /* copy match data - no worries about destination wraps */
1939 while (match_length-- > 0) *rundest++ = *runsrc++;
1940 }
1941 }
1942 break;
1943
1944 case LZX_BLOCKTYPE_UNCOMPRESSED:
1945 if ((inpos + this_run) > endinp) return DECR_ILLEGALDATA;
1946 memcpy(window + window_posn, inpos, (size_t) this_run);
1947 inpos += this_run; window_posn += this_run;
1948 break;
1949
1950 default:
1951 return DECR_ILLEGALDATA; /* might as well */
1952 }
1953
1954 }
1955 }
1956
1957 if (togo != 0) return DECR_ILLEGALDATA;
1958 memcpy(CAB(outbuf), window + ((!window_posn) ? window_size : window_posn) -
1959 outlen, (size_t) outlen);
1960
1961 LZX(window_posn) = window_posn;
1962 LZX(R0) = R0;
1963 LZX(R1) = R1;
1964 LZX(R2) = R2;
1965
1966 /* intel E8 decoding */
1967 if ((LZX(frames_read)++ < 32768) && LZX(intel_filesize) != 0) {
1968 if (outlen <= 6 || !LZX(intel_started)) {
1969 LZX(intel_curpos) += outlen;
1970 }
1971 else {
1972 cab_UBYTE *data = CAB(outbuf);
1973 cab_UBYTE *dataend = data + outlen - 10;
1974 cab_LONG curpos = LZX(intel_curpos);
1975 cab_LONG filesize = LZX(intel_filesize);
1976 cab_LONG abs_off, rel_off;
1977
1978 LZX(intel_curpos) = curpos + outlen;
1979
1980 while (data < dataend) {
1981 if (*data++ != 0xE8) { curpos++; continue; }
1982 abs_off = data[0] | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);
1983 if ((abs_off >= -curpos) && (abs_off < filesize)) {
1984 rel_off = (abs_off >= 0) ? abs_off - curpos : abs_off + filesize;
1985 data[0] = (cab_UBYTE) rel_off;
1986 data[1] = (cab_UBYTE) (rel_off >> 8);
1987 data[2] = (cab_UBYTE) (rel_off >> 16);
1988 data[3] = (cab_UBYTE) (rel_off >> 24);
1989 }
1990 data += 4;
1991 curpos += 5;
1992 }
1993 }
1994 }
1995 return DECR_OK;
1996 }
1997
1998 /**********************************************************
1999 * fdi_decomp (internal)
2000 *
2001 * Decompress the requested number of bytes. If savemode is zero,
2002 * do not save the output anywhere, just plow through blocks until we
2003 * reach the specified (uncompressed) distance from the starting point,
2004 * and remember the position of the cabfile pointer (and which cabfile)
2005 * after we are done; otherwise, save the data out to CAB(filehf),
2006 * decompressing the requested number of bytes and writing them out. This
2007 * is also where we jump to additional cabinets in the case of split
2008 * cab's, and provide (some of) the NEXT_CABINET notification semantics.
2009 */
2010 static int fdi_decomp(struct fdi_file *fi, int savemode, fdi_decomp_state *decomp_state,
2011 char *pszCabPath, PFNFDINOTIFY pfnfdin, void *pvUser)
2012 {
2013 cab_ULONG bytes = savemode ? fi->length : fi->offset - CAB(offset);
2014 cab_UBYTE buf[cfdata_SIZEOF], *data;
2015 cab_UWORD inlen, len, outlen, cando;
2016 cab_ULONG cksum;
2017 cab_LONG err;
2018 fdi_decomp_state *cab = (savemode && CAB(decomp_cab)) ? CAB(decomp_cab) : decomp_state;
2019
2020 TRACE("(fi == ^%p, savemode == %d, bytes == %d)\n", fi, savemode, bytes);
2021
2022 while (bytes > 0) {
2023 /* cando = the max number of bytes we can do */
2024 cando = CAB(outlen);
2025 if (cando > bytes) cando = bytes;
2026
2027 /* if cando != 0 */
2028 if (cando && savemode)
2029 PFDI_WRITE(CAB(hfdi), CAB(filehf), CAB(outpos), cando);
2030
2031 CAB(outpos) += cando;
2032 CAB(outlen) -= cando;
2033 bytes -= cando; if (!bytes) break;
2034
2035 /* we only get here if we emptied the output buffer */
2036
2037 /* read data header + data */
2038 inlen = outlen = 0;
2039 while (outlen == 0) {
2040 /* read the block header, skip the reserved part */
2041 if (PFDI_READ(CAB(hfdi), cab->cabhf, buf, cfdata_SIZEOF) != cfdata_SIZEOF)
2042 return DECR_INPUT;
2043
2044 if (PFDI_SEEK(CAB(hfdi), cab->cabhf, cab->mii.block_resv, SEEK_CUR) == -1)
2045 return DECR_INPUT;
2046
2047 /* we shouldn't get blocks over CAB_INPUTMAX in size */
2048 data = CAB(inbuf) + inlen;
2049 len = EndGetI16(buf+cfdata_CompressedSize);
2050 inlen += len;
2051 if (inlen > CAB_INPUTMAX) return DECR_INPUT;
2052 if (PFDI_READ(CAB(hfdi), cab->cabhf, data, len) != len)
2053 return DECR_INPUT;
2054
2055 /* clear two bytes after read-in data */
2056 data[len+1] = data[len+2] = 0;
2057
2058 /* perform checksum test on the block (if one is stored) */
2059 cksum = EndGetI32(buf+cfdata_CheckSum);
2060 if (cksum && cksum != checksum(buf+4, 4, checksum(data, len, 0)))
2061 return DECR_CHECKSUM; /* checksum is wrong */
2062
2063 outlen = EndGetI16(buf+cfdata_UncompressedSize);
2064
2065 /* outlen=0 means this block was the last contiguous part
2066 of a split block, continued in the next cabinet */
2067 if (outlen == 0) {
2068 int pathlen, filenamelen, idx, i, cabhf;
2069 char fullpath[MAX_PATH], userpath[256];
2070 FDINOTIFICATION fdin;
2071 FDICABINETINFO fdici;
2072 char emptystring = '\0';
2073 cab_UBYTE buf2[64];
2074 int success = FALSE;
2075 struct fdi_folder *fol = NULL, *linkfol = NULL;
2076 struct fdi_file *file = NULL, *linkfile = NULL;
2077
2078 tryanothercab:
2079
2080 /* set up the next decomp_state... */
2081 if (!(cab->next)) {
2082 if (!cab->mii.hasnext) return DECR_INPUT;
2083
2084 if (!((cab->next = PFDI_ALLOC(CAB(hfdi), sizeof(fdi_decomp_state)))))
2085 return DECR_NOMEMORY;
2086
2087 ZeroMemory(cab->next, sizeof(fdi_decomp_state));
2088
2089 /* copy pszCabPath to userpath */
2090 ZeroMemory(userpath, 256);
2091 pathlen = (pszCabPath) ? strlen(pszCabPath) : 0;
2092 if (pathlen) {
2093 if (pathlen < 256) {
2094 for (i = 0; i <= pathlen; i++)
2095 userpath[i] = pszCabPath[i];
2096 } /* else we are in a weird place... let's leave it blank and see if the user fixes it */
2097 }
2098
2099 /* initial fdintNEXT_CABINET notification */
2100 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2101 fdin.psz1 = (cab->mii.nextname) ? cab->mii.nextname : &emptystring;
2102 fdin.psz2 = (cab->mii.nextinfo) ? cab->mii.nextinfo : &emptystring;
2103 fdin.psz3 = &userpath[0];
2104 fdin.fdie = FDIERROR_NONE;
2105 fdin.pv = pvUser;
2106
2107 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2108
2109 do {
2110
2111 pathlen = (userpath) ? strlen(userpath) : 0;
2112 filenamelen = (cab->mii.nextname) ? strlen(cab->mii.nextname) : 0;
2113
2114 /* slight overestimation here to save CPU cycles in the developer's brain */
2115 if ((pathlen + filenamelen + 3) > MAX_PATH) {
2116 ERR("MAX_PATH exceeded.\n");
2117 return DECR_ILLEGALDATA;
2118 }
2119
2120 /* paste the path and filename together */
2121 idx = 0;
2122 if (pathlen) {
2123 for (i = 0; i < pathlen; i++) fullpath[idx++] = userpath[i];
2124 if (fullpath[idx - 1] != '\\') fullpath[idx++] = '\\';
2125 }
2126 if (filenamelen) for (i = 0; i < filenamelen; i++) fullpath[idx++] = cab->mii.nextname[i];
2127 fullpath[idx] = '\0';
2128
2129 TRACE("full cab path/file name: %s\n", debugstr_a(fullpath));
2130
2131 /* try to get a handle to the cabfile */
2132 cabhf = PFDI_OPEN(CAB(hfdi), fullpath, 32768, _S_IREAD | _S_IWRITE);
2133 if (cabhf == -1) {
2134 /* no file. allow the user to try again */
2135 fdin.fdie = FDIERROR_CABINET_NOT_FOUND;
2136 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2137 continue;
2138 }
2139
2140 if (cabhf == 0) {
2141 ERR("PFDI_OPEN returned zero for %s.\n", fullpath);
2142 fdin.fdie = FDIERROR_CABINET_NOT_FOUND;
2143 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2144 continue;
2145 }
2146
2147 /* check if it's really a cabfile. Note that this doesn't implement the bug */
2148 if (!FDI_read_entries(CAB(hfdi), cabhf, &fdici, &(cab->next->mii))) {
2149 WARN("FDIIsCabinet failed.\n");
2150 PFDI_CLOSE(CAB(hfdi), cabhf);
2151 fdin.fdie = FDIERROR_NOT_A_CABINET;
2152 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2153 continue;
2154 }
2155
2156 if ((fdici.setID != cab->setID) || (fdici.iCabinet != (cab->iCabinet + 1))) {
2157 WARN("Wrong Cabinet.\n");
2158 PFDI_CLOSE(CAB(hfdi), cabhf);
2159 fdin.fdie = FDIERROR_WRONG_CABINET;
2160 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2161 continue;
2162 }
2163
2164 break;
2165
2166 } while (1);
2167
2168 /* cabinet notification */
2169 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2170 fdin.setID = fdici.setID;
2171 fdin.iCabinet = fdici.iCabinet;
2172 fdin.pv = pvUser;
2173 fdin.psz1 = (cab->next->mii.nextname) ? cab->next->mii.nextname : &emptystring;
2174 fdin.psz2 = (cab->next->mii.nextinfo) ? cab->next->mii.nextinfo : &emptystring;
2175 fdin.psz3 = pszCabPath;
2176
2177 if (((*pfnfdin)(fdintCABINET_INFO, &fdin))) return DECR_USERABORT;
2178
2179 cab->next->setID = fdici.setID;
2180 cab->next->iCabinet = fdici.iCabinet;
2181 cab->next->hfdi = CAB(hfdi);
2182 cab->next->filehf = CAB(filehf);
2183 cab->next->cabhf = cabhf;
2184 cab->next->decompress = CAB(decompress); /* crude, but unused anyhow */
2185
2186 cab = cab->next; /* advance to the next cabinet */
2187
2188 /* read folders */
2189 for (i = 0; i < fdici.cFolders; i++) {
2190 if (PFDI_READ(CAB(hfdi), cab->cabhf, buf2, cffold_SIZEOF) != cffold_SIZEOF)
2191 return DECR_INPUT;
2192
2193 if (cab->mii.folder_resv > 0)
2194 PFDI_SEEK(CAB(hfdi), cab->cabhf, cab->mii.folder_resv, SEEK_CUR);
2195
2196 fol = (struct fdi_folder *) PFDI_ALLOC(CAB(hfdi), sizeof(struct fdi_folder));
2197 if (!fol) {
2198 ERR("out of memory!\n");
2199 return DECR_NOMEMORY;
2200 }
2201 ZeroMemory(fol, sizeof(struct fdi_folder));
2202 if (!(cab->firstfol)) cab->firstfol = fol;
2203
2204 fol->offset = (cab_off_t) EndGetI32(buf2+cffold_DataOffset);
2205 fol->num_blocks = EndGetI16(buf2+cffold_NumBlocks);
2206 fol->comp_type = EndGetI16(buf2+cffold_CompType);
2207
2208 if (linkfol)
2209 linkfol->next = fol;
2210 linkfol = fol;
2211 }
2212
2213 /* read files */
2214 for (i = 0; i < fdici.cFiles; i++) {
2215 if (PFDI_READ(CAB(hfdi), cab->cabhf, buf2, cffile_SIZEOF) != cffile_SIZEOF)
2216 return DECR_INPUT;
2217
2218 file = (struct fdi_file *) PFDI_ALLOC(CAB(hfdi), sizeof(struct fdi_file));
2219 if (!file) {
2220 ERR("out of memory!\n");
2221 return DECR_NOMEMORY;
2222 }
2223 ZeroMemory(file, sizeof(struct fdi_file));
2224 if (!(cab->firstfile)) cab->firstfile = file;
2225
2226 file->length = EndGetI32(buf2+cffile_UncompressedSize);
2227 file->offset = EndGetI32(buf2+cffile_FolderOffset);
2228 file->index = EndGetI16(buf2+cffile_FolderIndex);
2229 file->time = EndGetI16(buf2+cffile_Time);
2230 file->date = EndGetI16(buf2+cffile_Date);
2231 file->attribs = EndGetI16(buf2+cffile_Attribs);
2232 file->filename = FDI_read_string(CAB(hfdi), cab->cabhf, fdici.cbCabinet);
2233
2234 if (!file->filename) return DECR_INPUT;
2235
2236 if (linkfile)
2237 linkfile->next = file;
2238 linkfile = file;
2239 }
2240
2241 } else
2242 cab = cab->next; /* advance to the next cabinet */
2243
2244 /* iterate files -- if we encounter the continued file, process it --
2245 otherwise, jump to the label above and keep looking */
2246
2247 for (file = cab->firstfile; (file); file = file->next) {
2248 if ((file->index & cffileCONTINUED_FROM_PREV) == cffileCONTINUED_FROM_PREV) {
2249 /* check to ensure a real match */
2250 if (strcasecmp(fi->filename, file->filename) == 0) {
2251 success = TRUE;
2252 if (PFDI_SEEK(CAB(hfdi), cab->cabhf, cab->firstfol->offset, SEEK_SET) == -1)
2253 return DECR_INPUT;
2254 break;
2255 }
2256 }
2257 }
2258 if (!success) goto tryanothercab; /* FIXME: shouldn't this trigger
2259 "Wrong Cabinet" notification? */
2260 }
2261 }
2262
2263 /* decompress block */
2264 if ((err = CAB(decompress)(inlen, outlen, decomp_state)))
2265 return err;
2266 CAB(outlen) = outlen;
2267 CAB(outpos) = CAB(outbuf);
2268 }
2269
2270 CAB(decomp_cab) = cab;
2271 return DECR_OK;
2272 }
2273
2274 /***********************************************************************
2275 * FDICopy (CABINET.22)
2276 *
2277 * Iterates through the files in the Cabinet file indicated by name and
2278 * file-location. May chain forward to additional cabinets (typically
2279 * only one) if files which begin in this Cabinet are continued in another
2280 * cabinet. For each file which is partially contained in this cabinet,
2281 * and partially contained in a prior cabinet, provides fdintPARTIAL_FILE
2282 * notification to the pfnfdin callback. For each file which begins in
2283 * this cabinet, fdintCOPY_FILE notification is provided to the pfnfdin
2284 * callback, and the file is optionally decompressed and saved to disk.
2285 * Notification is not provided for files which are not at least partially
2286 * contained in the specified cabinet file.
2287 *
2288 * See below for a thorough explanation of the various notification
2289 * callbacks.
2290 *
2291 * PARAMS
2292 * hfdi [I] An HFDI from FDICreate
2293 * pszCabinet [I] C-style string containing the filename of the cabinet
2294 * pszCabPath [I] C-style string containing the file path of the cabinet
2295 * flags [I] "Decoder parameters". Ignored. Suggested value: 0.
2296 * pfnfdin [I] Pointer to a notification function. See CALLBACKS below.
2297 * pfnfdid [I] Pointer to a decryption function. Ignored. Suggested
2298 * value: NULL.
2299 * pvUser [I] arbitrary void * value which is passed to callbacks.
2300 *
2301 * RETURNS
2302 * TRUE if successful.
2303 * FALSE if unsuccessful (error information is provided in the ERF structure
2304 * associated with the provided decompression handle by FDICreate).
2305 *
2306 * CALLBACKS
2307 *
2308 * Two pointers to callback functions are provided as parameters to FDICopy:
2309 * pfnfdin(of type PFNFDINOTIFY), and pfnfdid (of type PFNFDIDECRYPT). These
2310 * types are as follows:
2311 *
2312 * typedef INT_PTR (__cdecl *PFNFDINOTIFY) ( FDINOTIFICATIONTYPE fdint,
2313 * PFDINOTIFICATION pfdin );
2314 *
2315 * typedef int (__cdecl *PFNFDIDECRYPT) ( PFDIDECRYPT pfdid );
2316 *
2317 * You can create functions of this type using the FNFDINOTIFY() and
2318 * FNFDIDECRYPT() macros, respectively. For example:
2319 *
2320 * FNFDINOTIFY(mycallback) {
2321 * / * use variables fdint and pfdin to process notification * /
2322 * }
2323 *
2324 * The second callback, which could be used for decrypting encrypted data,
2325 * is not used at all.
2326 *
2327 * Each notification informs the user of some event which has occurred during
2328 * decompression of the cabinet file; each notification is also an opportunity
2329 * for the callee to abort decompression. The information provided to the
2330 * callback and the meaning of the callback's return value vary drastically
2331 * across the various types of notification. The type of notification is the
2332 * fdint parameter; all other information is provided to the callback in
2333 * notification-specific parts of the FDINOTIFICATION structure pointed to by
2334 * pfdin. The only part of that structure which is assigned for every callback
2335 * is the pv element, which contains the arbitrary value which was passed to
2336 * FDICopy in the pvUser argument (psz1 is also used each time, but its meaning
2337 * is highly dependent on fdint).
2338 *
2339 * If you encounter unknown notifications, you should return zero if you want
2340 * decompression to continue (or -1 to abort). All strings used in the
2341 * callbacks are regular C-style strings. Detailed descriptions of each
2342 * notification type follow:
2343 *
2344 * fdintCABINET_INFO:
2345 *
2346 * This is the first notification provided after calling FDICopy, and provides
2347 * the user with various information about the cabinet. Note that this is
2348 * called for each cabinet FDICopy opens, not just the first one. In the
2349 * structure pointed to by pfdin, psz1 contains a pointer to the name of the
2350 * next cabinet file in the set after the one just loaded (if any), psz2
2351 * contains a pointer to the name or "info" of the next disk, psz3
2352 * contains a pointer to the file-path of the current cabinet, setID
2353 * contains an arbitrary constant associated with this set of cabinet files,
2354 * and iCabinet contains the numerical index of the current cabinet within
2355 * that set. Return zero, or -1 to abort.
2356 *
2357 * fdintPARTIAL_FILE:
2358 *
2359 * This notification is provided when FDICopy encounters a part of a file
2360 * contained in this cabinet which is missing its beginning. Files can be
2361 * split across cabinets, so this is not necessarily an abnormality; it just
2362 * means that the file in question begins in another cabinet. No file
2363 * corresponding to this notification is extracted from the cabinet. In the
2364 * structure pointed to by pfdin, psz1 contains a pointer to the name of the
2365 * partial file, psz2 contains a pointer to the file name of the cabinet in
2366 * which this file begins, and psz3 contains a pointer to the disk name or
2367 * "info" of the cabinet where the file begins. Return zero, or -1 to abort.
2368 *
2369 * fdintCOPY_FILE:
2370 *
2371 * This notification is provided when FDICopy encounters a file which starts
2372 * in the cabinet file, provided to FDICopy in pszCabinet. (FDICopy will not
2373 * look for files in cabinets after the first one). One notification will be
2374 * sent for each such file, before the file is decompressed. By returning
2375 * zero, the callback can instruct FDICopy to skip the file. In the structure
2376 * pointed to by pfdin, psz1 contains a pointer to the file's name, cb contains
2377 * the size of the file (uncompressed), attribs contains the file attributes,
2378 * and date and time contain the date and time of the file. attributes, date,
2379 * and time are of the 16-bit ms-dos variety. Return -1 to abort decompression
2380 * for the entire cabinet, 0 to skip just this file but continue scanning the
2381 * cabinet for more files, or an FDIClose()-compatible file-handle.
2382 *
2383 * fdintCLOSE_FILE_INFO:
2384 *
2385 * This notification is important, don't forget to implement it. This
2386 * notification indicates that a file has been successfully uncompressed and
2387 * written to disk. Upon receipt of this notification, the callee is expected
2388 * to close the file handle, to set the attributes and date/time of the
2389 * closed file, and possibly to execute the file. In the structure pointed to
2390 * by pfdin, psz1 contains a pointer to the name of the file, hf will be the
2391 * open file handle (close it), cb contains 1 or zero, indicating respectively
2392 * that the callee should or should not execute the file, and date, time
2393 * and attributes will be set as in fdintCOPY_FILE. Bizarrely, the Cabinet SDK
2394 * specifies that _A_EXEC will be xor'ed out of attributes! wine does not do
2395 * do so. Return TRUE, or FALSE to abort decompression.
2396 *
2397 * fdintNEXT_CABINET:
2398 *
2399 * This notification is called when FDICopy must load in another cabinet. This
2400 * can occur when a file's data is "split" across multiple cabinets. The
2401 * callee has the opportunity to request that FDICopy look in a different file
2402 * path for the specified cabinet file, by writing that data into a provided
2403 * buffer (see below for more information). This notification will be received
2404 * more than once per-cabinet in the instance that FDICopy failed to find a
2405 * valid cabinet at the location specified by the first per-cabinet
2406 * fdintNEXT_CABINET notification. In such instances, the fdie element of the
2407 * structure pointed to by pfdin indicates the error which prevented FDICopy
2408 * from proceeding successfully. Return zero to indicate success, or -1 to
2409 * indicate failure and abort FDICopy.
2410 *
2411 * Upon receipt of this notification, the structure pointed to by pfdin will
2412 * contain the following values: psz1 pointing to the name of the cabinet
2413 * which FDICopy is attempting to open, psz2 pointing to the name ("info") of
2414 * the next disk, psz3 pointing to the presumed file-location of the cabinet,
2415 * and fdie containing either FDIERROR_NONE, or one of the following:
2416 *
2417 * FDIERROR_CABINET_NOT_FOUND, FDIERROR_NOT_A_CABINET,
2418 * FDIERROR_UNKNOWN_CABINET_VERSION, FDIERROR_CORRUPT_CABINET,
2419 * FDIERROR_BAD_COMPR_TYPE, FDIERROR_RESERVE_MISMATCH, and
2420 * FDIERROR_WRONG_CABINET.
2421 *
2422 * The callee may choose to change the path where FDICopy will look for the
2423 * cabinet after this notification. To do so, the caller may write the new
2424 * pathname to the buffer pointed to by psz3, which is 256 characters in
2425 * length, including the terminating null character, before returning zero.
2426 *
2427 * fdintENUMERATE:
2428 *
2429 * Undocumented and unimplemented in wine, this seems to be sent each time
2430 * a cabinet is opened, along with the fdintCABINET_INFO notification. It
2431 * probably has an interface similar to that of fdintCABINET_INFO; maybe this
2432 * provides information about the current cabinet instead of the next one....
2433 * this is just a guess, it has not been looked at closely.
2434 *
2435 * INCLUDES
2436 * fdi.c
2437 */
2438 BOOL __cdecl FDICopy(
2439 HFDI hfdi,
2440 char *pszCabinet,
2441 char *pszCabPath,
2442 int flags,
2443 PFNFDINOTIFY pfnfdin,
2444 PFNFDIDECRYPT pfnfdid,
2445 void *pvUser)
2446 {
2447 FDICABINETINFO fdici;
2448 FDINOTIFICATION fdin;
2449 int cabhf, filehf = 0, idx;
2450 unsigned int i;
2451 char fullpath[MAX_PATH];
2452 size_t pathlen, filenamelen;
2453 char emptystring = '\0';
2454 cab_UBYTE buf[64];
2455 struct fdi_folder *fol = NULL, *linkfol = NULL;
2456 struct fdi_file *file = NULL, *linkfile = NULL;
2457 fdi_decomp_state _decomp_state;
2458 fdi_decomp_state *decomp_state = &_decomp_state;
2459
2460 TRACE("(hfdi == ^%p, pszCabinet == ^%p, pszCabPath == ^%p, flags == %0d, "
2461 "pfnfdin == ^%p, pfnfdid == ^%p, pvUser == ^%p)\n",
2462 hfdi, pszCabinet, pszCabPath, flags, pfnfdin, pfnfdid, pvUser);
2463
2464 if (!REALLY_IS_FDI(hfdi)) {
2465 SetLastError(ERROR_INVALID_HANDLE);
2466 return FALSE;
2467 }
2468
2469 ZeroMemory(decomp_state, sizeof(fdi_decomp_state));
2470
2471 pathlen = (pszCabPath) ? strlen(pszCabPath) : 0;
2472 filenamelen = (pszCabinet) ? strlen(pszCabinet) : 0;
2473
2474 /* slight overestimation here to save CPU cycles in the developer's brain */
2475 if ((pathlen + filenamelen + 3) > MAX_PATH) {
2476 ERR("MAX_PATH exceeded.\n");
2477 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CABINET_NOT_FOUND;
2478 PFDI_INT(hfdi)->perf->erfType = ERROR_FILE_NOT_FOUND;
2479 PFDI_INT(hfdi)->perf->fError = TRUE;
2480 SetLastError(ERROR_FILE_NOT_FOUND);
2481 return FALSE;
2482 }
2483
2484 /* paste the path and filename together */
2485 idx = 0;
2486 if (pathlen) {
2487 for (i = 0; i < pathlen; i++) fullpath[idx++] = pszCabPath[i];
2488 if (fullpath[idx - 1] != '\\') fullpath[idx++] = '\\';
2489 }
2490 if (filenamelen) for (i = 0; i < filenamelen; i++) fullpath[idx++] = pszCabinet[i];
2491 fullpath[idx] = '\0';
2492
2493 TRACE("full cab path/file name: %s\n", debugstr_a(fullpath));
2494
2495 /* get a handle to the cabfile */
2496 cabhf = PFDI_OPEN(hfdi, fullpath, 32768, _S_IREAD | _S_IWRITE);
2497 if (cabhf == -1) {
2498 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CABINET_NOT_FOUND;
2499 PFDI_INT(hfdi)->perf->erfType = ERROR_FILE_NOT_FOUND;
2500 PFDI_INT(hfdi)->perf->fError = TRUE;
2501 SetLastError(ERROR_FILE_NOT_FOUND);
2502 return FALSE;
2503 }
2504
2505 if (cabhf == 0) {
2506 ERR("PFDI_OPEN returned zero for %s.\n", fullpath);
2507 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CABINET_NOT_FOUND;
2508 PFDI_INT(hfdi)->perf->erfType = ERROR_FILE_NOT_FOUND;
2509 PFDI_INT(hfdi)->perf->fError = TRUE;
2510 SetLastError(ERROR_FILE_NOT_FOUND);
2511 return FALSE;
2512 }
2513
2514 /* check if it's really a cabfile. Note that this doesn't implement the bug */
2515 if (!FDI_read_entries(hfdi, cabhf, &fdici, &(CAB(mii)))) {
2516 ERR("FDIIsCabinet failed.\n");
2517 PFDI_CLOSE(hfdi, cabhf);
2518 return FALSE;
2519 }
2520
2521 /* cabinet notification */
2522 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2523 fdin.setID = fdici.setID;
2524 fdin.iCabinet = fdici.iCabinet;
2525 fdin.pv = pvUser;
2526 fdin.psz1 = (CAB(mii).nextname) ? CAB(mii).nextname : &emptystring;
2527 fdin.psz2 = (CAB(mii).nextinfo) ? CAB(mii).nextinfo : &emptystring;
2528 fdin.psz3 = pszCabPath;
2529
2530 if (((*pfnfdin)(fdintCABINET_INFO, &fdin))) {
2531 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_USER_ABORT;
2532 PFDI_INT(hfdi)->perf->erfType = 0;
2533 PFDI_INT(hfdi)->perf->fError = TRUE;
2534 goto bail_and_fail;
2535 }
2536
2537 CAB(setID) = fdici.setID;
2538 CAB(iCabinet) = fdici.iCabinet;
2539 CAB(cabhf) = cabhf;
2540
2541 /* read folders */
2542 for (i = 0; i < fdici.cFolders; i++) {
2543 if (PFDI_READ(hfdi, cabhf, buf, cffold_SIZEOF) != cffold_SIZEOF) {
2544 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
2545 PFDI_INT(hfdi)->perf->erfType = 0;
2546 PFDI_INT(hfdi)->perf->fError = TRUE;
2547 goto bail_and_fail;
2548 }
2549
2550 if (CAB(mii).folder_resv > 0)
2551 PFDI_SEEK(hfdi, cabhf, CAB(mii).folder_resv, SEEK_CUR);
2552
2553 fol = (struct fdi_folder *) PFDI_ALLOC(hfdi, sizeof(struct fdi_folder));
2554 if (!fol) {
2555 ERR("out of memory!\n");
2556 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_ALLOC_FAIL;
2557 PFDI_INT(hfdi)->perf->erfType = ERROR_NOT_ENOUGH_MEMORY;
2558 PFDI_INT(hfdi)->perf->fError = TRUE;
2559 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2560 goto bail_and_fail;
2561 }
2562 ZeroMemory(fol, sizeof(struct fdi_folder));
2563 if (!CAB(firstfol)) CAB(firstfol) = fol;
2564
2565 fol->offset = (cab_off_t) EndGetI32(buf+cffold_DataOffset);
2566 fol->num_blocks = EndGetI16(buf+cffold_NumBlocks);
2567 fol->comp_type = EndGetI16(buf+cffold_CompType);
2568
2569 if (linkfol)
2570 linkfol->next = fol;
2571 linkfol = fol;
2572 }
2573
2574 /* read files */
2575 for (i = 0; i < fdici.cFiles; i++) {
2576 if (PFDI_READ(hfdi, cabhf, buf, cffile_SIZEOF) != cffile_SIZEOF) {
2577 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
2578 PFDI_INT(hfdi)->perf->erfType = 0;
2579 PFDI_INT(hfdi)->perf->fError = TRUE;
2580 goto bail_and_fail;
2581 }
2582
2583 file = (struct fdi_file *) PFDI_ALLOC(hfdi, sizeof(struct fdi_file));
2584 if (!file) {
2585 ERR("out of memory!\n");
2586 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_ALLOC_FAIL;
2587 PFDI_INT(hfdi)->perf->erfType = ERROR_NOT_ENOUGH_MEMORY;
2588 PFDI_INT(hfdi)->perf->fError = TRUE;
2589 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2590 goto bail_and_fail;
2591 }
2592 ZeroMemory(file, sizeof(struct fdi_file));
2593 if (!CAB(firstfile)) CAB(firstfile) = file;
2594
2595 file->length = EndGetI32(buf+cffile_UncompressedSize);
2596 file->offset = EndGetI32(buf+cffile_FolderOffset);
2597 file->index = EndGetI16(buf+cffile_FolderIndex);
2598 file->time = EndGetI16(buf+cffile_Time);
2599 file->date = EndGetI16(buf+cffile_Date);
2600 file->attribs = EndGetI16(buf+cffile_Attribs);
2601 file->filename = FDI_read_string(hfdi, cabhf, fdici.cbCabinet);
2602
2603 if (!file->filename) {
2604 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
2605 PFDI_INT(hfdi)->perf->erfType = 0;
2606 PFDI_INT(hfdi)->perf->fError = TRUE;
2607 goto bail_and_fail;
2608 }
2609
2610 if (linkfile)
2611 linkfile->next = file;
2612 linkfile = file;
2613 }
2614
2615 for (file = CAB(firstfile); (file); file = file->next) {
2616
2617 /*
2618 * FIXME: This implementation keeps multiple cabinet files open at once
2619 * when encountering a split cabinet. It is a quirk of this implementation
2620 * that sometimes we decrypt the same block of data more than once, to find
2621 * the right starting point for a file, moving the file-pointer backwards.
2622 * If we kept a cache of certain file-pointer information, we could eliminate
2623 * that behavior... in fact I am not sure that the caching we already have
2624 * is not sufficient.
2625 *
2626 * The current implementation seems to work fine in straightforward situations
2627 * where all the cabinet files needed for decryption are simultaneously
2628 * available. But presumably, the API is supposed to support cabinets which
2629 * are split across multiple CDROMS; we may need to change our implementation
2630 * to strictly serialize it's file usage so that it opens only one cabinet
2631 * at a time. Some experimentation with Windows is needed to figure out the
2632 * precise semantics required. The relevant code is here and in fdi_decomp().
2633 */
2634
2635 /* partial-file notification */
2636 if ((file->index & cffileCONTINUED_FROM_PREV) == cffileCONTINUED_FROM_PREV) {
2637 /*
2638 * FIXME: Need to create a Cabinet with a single file spanning multiple files
2639 * and perform some tests to figure out the right behavior. The SDK says
2640 * FDICopy will notify the user of the filename and "disk name" (info) of
2641 * the cabinet where the spanning file /started/.
2642 *
2643 * That would certainly be convenient for the API-user, who could abort,
2644 * everything (or parallelize, if that's allowed (it is in wine)), and call
2645 * FDICopy again with the provided filename, so as to avoid partial file
2646 * notification and successfully unpack. This task could be quite unpleasant
2647 * from wine's perspective: the information specifying the "start cabinet" for
2648 * a file is associated nowhere with the file header and is not to be found in
2649 * the cabinet header. We have only the index of the cabinet wherein the folder
2650 * begins, which contains the file. To find that cabinet, we must consider the
2651 * index of the current cabinet, and chain backwards, cabinet-by-cabinet (for
2652 * each cabinet refers to its "next" and "previous" cabinet only, like a linked
2653 * list).
2654 *
2655 * Bear in mind that, in the spirit of CABINET.DLL, we must assume that any
2656 * cabinet other than the active one might be at another filepath than the
2657 * current one, or on another CDROM. This could get rather dicey, especially
2658 * if we imagine parallelized access to the FDICopy API.
2659 *
2660 * The current implementation punts -- it just returns the previous cabinet and
2661 * it's info from the header of this cabinet. This provides the right answer in
2662 * 95% of the cases; its worth checking if Microsoft cuts the same corner before
2663 * we "fix" it.
2664 */
2665 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2666 fdin.pv = pvUser;
2667 fdin.psz1 = (char *)file->filename;
2668 fdin.psz2 = (CAB(mii).prevname) ? CAB(mii).prevname : &emptystring;
2669 fdin.psz3 = (CAB(mii).previnfo) ? CAB(mii).previnfo : &emptystring;
2670
2671 if (((*pfnfdin)(fdintPARTIAL_FILE, &fdin))) {
2672 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_USER_ABORT;
2673 PFDI_INT(hfdi)->perf->erfType = 0;
2674 PFDI_INT(hfdi)->perf->fError = TRUE;
2675 goto bail_and_fail;
2676 }
2677 /* I don't think we are supposed to decompress partial files. This prevents it. */
2678 file->oppressed = TRUE;
2679 }
2680 if (file->oppressed) {
2681 filehf = 0;
2682 } else {
2683 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2684 fdin.pv = pvUser;
2685 fdin.psz1 = (char *)file->filename;
2686 fdin.cb = file->length;
2687 fdin.date = file->date;
2688 fdin.time = file->time;
2689 fdin.attribs = file->attribs;
2690 if ((filehf = ((*pfnfdin)(fdintCOPY_FILE, &fdin))) == -1) {
2691 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_USER_ABORT;
2692 PFDI_INT(hfdi)->perf->erfType = 0;
2693 PFDI_INT(hfdi)->perf->fError = TRUE;
2694 goto bail_and_fail;
2695 }
2696 }
2697
2698 /* find the folder for this file if necc. */
2699 if (filehf) {
2700 int i2;
2701
2702 fol = CAB(firstfol);
2703 if ((file->index & cffileCONTINUED_TO_NEXT) == cffileCONTINUED_TO_NEXT) {
2704 /* pick the last folder */
2705 while (fol->next) fol = fol->next;
2706 } else {
2707 for (i2 = 0; (i2 < file->index); i2++)
2708 if (fol->next) /* bug resistance, should always be true */
2709 fol = fol->next;
2710 }
2711 }
2712
2713 if (filehf) {
2714 cab_UWORD comptype = fol->comp_type;
2715 int ct1 = comptype & cffoldCOMPTYPE_MASK;
2716 int ct2 = CAB(current) ? (CAB(current)->comp_type & cffoldCOMPTYPE_MASK) : 0;
2717 int err = 0;
2718
2719 TRACE("Extracting file %s as requested by callee.\n", debugstr_a(file->filename));
2720
2721 /* set up decomp_state */
2722 CAB(hfdi) = hfdi;
2723 CAB(filehf) = filehf;
2724
2725 /* Was there a change of folder? Compression type? Did we somehow go backwards? */
2726 if ((ct1 != ct2) || (CAB(current) != fol) || (file->offset < CAB(offset))) {
2727
2728 TRACE("Resetting folder for file %s.\n", debugstr_a(file->filename));
2729
2730 /* free stuff for the old decompresser */
2731 switch (ct2) {
2732 case cffoldCOMPTYPE_LZX:
2733 if (LZX(window)) {
2734 PFDI_FREE(hfdi, LZX(window));
2735 LZX(window) = NULL;
2736 }
2737 break;
2738 case cffoldCOMPTYPE_QUANTUM:
2739 if (QTM(window)) {
2740 PFDI_FREE(hfdi, QTM(window));
2741 QTM(window) = NULL;
2742 }
2743 break;
2744 }
2745
2746 CAB(decomp_cab) = NULL;
2747 PFDI_SEEK(CAB(hfdi), CAB(cabhf), fol->offset, SEEK_SET);
2748 CAB(offset) = 0;
2749 CAB(outlen) = 0;
2750
2751 /* initialize the new decompresser */
2752 switch (ct1) {
2753 case cffoldCOMPTYPE_NONE:
2754 CAB(decompress) = NONEfdi_decomp;
2755 break;
2756 case cffoldCOMPTYPE_MSZIP:
2757 CAB(decompress) = ZIPfdi_decomp;
2758 break;
2759 case cffoldCOMPTYPE_QUANTUM:
2760 CAB(decompress) = QTMfdi_decomp;
2761 err = QTMfdi_init((comptype >> 8) & 0x1f, (comptype >> 4) & 0xF, decomp_state);
2762 break;
2763 case cffoldCOMPTYPE_LZX:
2764 CAB(decompress) = LZXfdi_decomp;
2765 err = LZXfdi_init((comptype >> 8) & 0x1f, decomp_state);
2766 break;
2767 default:
2768 err = DECR_DATAFORMAT;
2769 }
2770 }
2771
2772 CAB(current) = fol;
2773
2774 switch (err) {
2775 case DECR_OK:
2776 break;
2777 case DECR_NOMEMORY:
2778 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_ALLOC_FAIL;
2779 PFDI_INT(hfdi)->perf->erfType = ERROR_NOT_ENOUGH_MEMORY;
2780 PFDI_INT(hfdi)->perf->fError = TRUE;
2781 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2782 goto bail_and_fail;
2783 default:
2784 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
2785 PFDI_INT(hfdi)->perf->erfOper = 0;
2786 PFDI_INT(hfdi)->perf->fError = TRUE;
2787 goto bail_and_fail;
2788 }
2789
2790 if (file->offset > CAB(offset)) {
2791 /* decode bytes and send them to /dev/null */
2792 switch ((err = fdi_decomp(file, 0, decomp_state, pszCabPath, pfnfdin, pvUser))) {
2793 case DECR_OK:
2794 break;
2795 case DECR_USERABORT:
2796 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_USER_ABORT;
2797 PFDI_INT(hfdi)->perf->erfType = 0;
2798 PFDI_INT(hfdi)->perf->fError = TRUE;
2799 goto bail_and_fail;
2800 case DECR_NOMEMORY:
2801 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_ALLOC_FAIL;
2802 PFDI_INT(hfdi)->perf->erfType = ERROR_NOT_ENOUGH_MEMORY;
2803 PFDI_INT(hfdi)->perf->fError = TRUE;
2804 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2805 goto bail_and_fail;
2806 default:
2807 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
2808 PFDI_INT(hfdi)->perf->erfOper = 0;
2809 PFDI_INT(hfdi)->perf->fError = TRUE;
2810 goto bail_and_fail;
2811 }
2812 CAB(offset) = file->offset;
2813 }
2814
2815 /* now do the actual decompression */
2816 err = fdi_decomp(file, 1, decomp_state, pszCabPath, pfnfdin, pvUser);
2817 if (err) CAB(current) = NULL; else CAB(offset) += file->length;
2818
2819 /* fdintCLOSE_FILE_INFO notification */
2820 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2821 fdin.pv = pvUser;
2822 fdin.psz1 = (char *)file->filename;
2823 fdin.hf = filehf;
2824 fdin.cb = (file->attribs & cffile_A_EXEC) ? TRUE : FALSE; /* FIXME: is that right? */
2825 fdin.date = file->date;
2826 fdin.time = file->time;
2827 fdin.attribs = file->attribs; /* FIXME: filter _A_EXEC? */
2828 ((*pfnfdin)(fdintCLOSE_FILE_INFO, &fdin));
2829 filehf = 0;
2830
2831 switch (err) {
2832 case DECR_OK:
2833 break;
2834 case DECR_USERABORT:
2835 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_USER_ABORT;
2836 PFDI_INT(hfdi)->perf->erfType = 0;
2837 PFDI_INT(hfdi)->perf->fError = TRUE;
2838 goto bail_and_fail;
2839 case DECR_NOMEMORY:
2840 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_ALLOC_FAIL;
2841 PFDI_INT(hfdi)->perf->erfType = ERROR_NOT_ENOUGH_MEMORY;
2842 PFDI_INT(hfdi)->perf->fError = TRUE;
2843 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2844 goto bail_and_fail;
2845 default:
2846 PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
2847 PFDI_INT(hfdi)->perf->erfOper = 0;
2848 PFDI_INT(hfdi)->perf->fError = TRUE;
2849 goto bail_and_fail;
2850 }
2851 }
2852 }
2853
2854 /* free decompression temps */
2855 switch (fol->comp_type & cffoldCOMPTYPE_MASK) {
2856 case cffoldCOMPTYPE_LZX:
2857 if (LZX(window)) {
2858 PFDI_FREE(hfdi, LZX(window));
2859 LZX(window) = NULL;
2860 }
2861 break;
2862 case cffoldCOMPTYPE_QUANTUM:
2863 if (QTM(window)) {
2864 PFDI_FREE(hfdi, QTM(window));
2865 QTM(window) = NULL;
2866 }
2867 break;
2868 }
2869
2870 while (decomp_state) {
2871 fdi_decomp_state *prev_fds;
2872
2873 PFDI_CLOSE(hfdi, CAB(cabhf));
2874
2875 /* free the storage remembered by mii */
2876 if (CAB(mii).nextname) PFDI_FREE(hfdi, CAB(mii).nextname);
2877 if (CAB(mii).nextinfo) PFDI_FREE(hfdi, CAB(mii).nextinfo);
2878 if (CAB(mii).prevname) PFDI_FREE(hfdi, CAB(mii).prevname);
2879 if (CAB(mii).previnfo) PFDI_FREE(hfdi, CAB(mii).previnfo);
2880
2881 while (CAB(firstfol)) {
2882 fol = CAB(firstfol);
2883 CAB(firstfol) = CAB(firstfol)->next;
2884 PFDI_FREE(hfdi, fol);
2885 }
2886 while (CAB(firstfile)) {
2887 file = CAB(firstfile);
2888 if (file->filename) PFDI_FREE(hfdi, (void *)file->filename);
2889 CAB(firstfile) = CAB(firstfile)->next;
2890 PFDI_FREE(hfdi, file);
2891 }
2892 prev_fds = decomp_state;
2893 decomp_state = CAB(next);
2894 if (prev_fds != &_decomp_state)
2895 PFDI_FREE(hfdi, prev_fds);
2896 }
2897
2898 return TRUE;
2899
2900 bail_and_fail: /* here we free ram before error returns */
2901
2902 /* free decompression temps */
2903 switch (fol->comp_type & cffoldCOMPTYPE_MASK) {
2904 case cffoldCOMPTYPE_LZX:
2905 if (LZX(window)) {
2906 PFDI_FREE(hfdi, LZX(window));
2907 LZX(window) = NULL;
2908 }
2909 break;
2910 case cffoldCOMPTYPE_QUANTUM:
2911 if (QTM(window)) {
2912 PFDI_FREE(hfdi, QTM(window));
2913 QTM(window) = NULL;
2914 }
2915 break;
2916 }
2917
2918 if (filehf) PFDI_CLOSE(hfdi, filehf);
2919
2920 while (decomp_state) {
2921 fdi_decomp_state *prev_fds;
2922
2923 PFDI_CLOSE(hfdi, CAB(cabhf));
2924
2925 /* free the storage remembered by mii */
2926 if (CAB(mii).nextname) PFDI_FREE(hfdi, CAB(mii).nextname);
2927 if (CAB(mii).nextinfo) PFDI_FREE(hfdi, CAB(mii).nextinfo);
2928 if (CAB(mii).prevname) PFDI_FREE(hfdi, CAB(mii).prevname);
2929 if (CAB(mii).previnfo) PFDI_FREE(hfdi, CAB(mii).previnfo);
2930
2931 while (CAB(firstfol)) {
2932 fol = CAB(firstfol);
2933 CAB(firstfol) = CAB(firstfol)->next;
2934 PFDI_FREE(hfdi, fol);
2935 }
2936 while (CAB(firstfile)) {
2937 file = CAB(firstfile);
2938 if (file->filename) PFDI_FREE(hfdi, (void *)file->filename);
2939 CAB(firstfile) = CAB(firstfile)->next;
2940 PFDI_FREE(hfdi, file);
2941 }
2942 prev_fds = decomp_state;
2943 decomp_state = CAB(next);
2944 if (prev_fds != &_decomp_state)
2945 PFDI_FREE(hfdi, prev_fds);
2946 }
2947
2948 return FALSE;
2949 }
2950
2951 /***********************************************************************
2952 * FDIDestroy (CABINET.23)
2953 *
2954 * Frees a handle created by FDICreate. Do /not/ call this in the middle
2955 * of FDICopy. Only reason for failure would be an invalid handle.
2956 *
2957 * PARAMS
2958 * hfdi [I] The HFDI to free
2959 *
2960 * RETURNS
2961 * TRUE for success
2962 * FALSE for failure
2963 */
2964 BOOL __cdecl FDIDestroy(HFDI hfdi)
2965 {
2966 TRACE("(hfdi == ^%p)\n", hfdi);
2967 if (REALLY_IS_FDI(hfdi)) {
2968 PFDI_INT(hfdi)->FDI_Intmagic = 0; /* paranoia */
2969 PFDI_FREE(hfdi, hfdi); /* confusing, but correct */
2970 return TRUE;
2971 } else {
2972 SetLastError(ERROR_INVALID_HANDLE);
2973 return FALSE;
2974 }
2975 }
2976
2977 /***********************************************************************
2978 * FDITruncateCabinet (CABINET.24)
2979 *
2980 * Removes all folders of a cabinet file after and including the
2981 * specified folder number.
2982 *
2983 * PARAMS
2984 * hfdi [I] Handle to the FDI context.
2985 * pszCabinetName [I] Filename of the cabinet.
2986 * iFolderToDelete [I] Index of the first folder to delete.
2987 *
2988 * RETURNS
2989 * Success: TRUE.
2990 * Failure: FALSE.
2991 *
2992 * NOTES
2993 * The PFNWRITE function supplied to FDICreate must truncate the
2994 * file at the current position if the number of bytes to write is 0.
2995 */
2996 BOOL __cdecl FDITruncateCabinet(
2997 HFDI hfdi,
2998 char *pszCabinetName,
2999 USHORT iFolderToDelete)
3000 {
3001 FIXME("(hfdi == ^%p, pszCabinetName == %s, iFolderToDelete == %hu): stub\n",
3002 hfdi, debugstr_a(pszCabinetName), iFolderToDelete);
3003
3004 if (!REALLY_IS_FDI(hfdi)) {
3005 SetLastError(ERROR_INVALID_HANDLE);
3006 return FALSE;
3007 }
3008
3009 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3010 return FALSE;
3011 }