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