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