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