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