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