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