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