comctl32: Set label width after editting.
[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, const 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(const 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(const struct Ziphuft *tl, const 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   const 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   cab_ULONG window_posn = QTM(window_posn);
1511   cab_ULONG window_size = QTM(window_size);
1512
1513   /* used by bitstream macros */
1514   register int bitsleft, bitrun, bitsneed;
1515   register cab_ULONG bitbuf;
1516
1517   /* used by GET_SYMBOL */
1518   cab_ULONG range;
1519   cab_UWORD symf;
1520   int i;
1521
1522   int extra, togo = outlen, match_length = 0, copy_length;
1523   cab_UBYTE selector, sym;
1524   cab_ULONG match_offset = 0;
1525
1526   cab_UWORD H = 0xFFFF, L = 0, C;
1527
1528   TRACE("(inlen == %d, outlen == %d)\n", inlen, outlen);
1529
1530   /* read initial value of C */
1531   Q_INIT_BITSTREAM;
1532   Q_READ_BITS(C, 16);
1533
1534   /* apply 2^x-1 mask */
1535   window_posn &= window_size - 1;
1536   /* runs can't straddle the window wraparound */
1537   if ((window_posn + togo) > window_size) {
1538     TRACE("straddled run\n");
1539     return DECR_DATAFORMAT;
1540   }
1541
1542   while (togo > 0) {
1543     GET_SYMBOL(model7, selector);
1544     switch (selector) {
1545     case 0:
1546       GET_SYMBOL(model00, sym); window[window_posn++] = sym; togo--;
1547       break;
1548     case 1:
1549       GET_SYMBOL(model40, sym); window[window_posn++] = sym; togo--;
1550       break;
1551     case 2:
1552       GET_SYMBOL(model80, sym); window[window_posn++] = sym; togo--;
1553       break;
1554     case 3:
1555       GET_SYMBOL(modelC0, sym); window[window_posn++] = sym; togo--;
1556       break;
1557
1558     case 4:
1559       /* selector 4 = fixed length of 3 */
1560       GET_SYMBOL(model4, sym);
1561       Q_READ_BITS(extra, CAB(q_extra_bits)[sym]);
1562       match_offset = CAB(q_position_base)[sym] + extra + 1;
1563       match_length = 3;
1564       break;
1565
1566     case 5:
1567       /* selector 5 = fixed length of 4 */
1568       GET_SYMBOL(model5, sym);
1569       Q_READ_BITS(extra, CAB(q_extra_bits)[sym]);
1570       match_offset = CAB(q_position_base)[sym] + extra + 1;
1571       match_length = 4;
1572       break;
1573
1574     case 6:
1575       /* selector 6 = variable length */
1576       GET_SYMBOL(model6len, sym);
1577       Q_READ_BITS(extra, CAB(q_length_extra)[sym]);
1578       match_length = CAB(q_length_base)[sym] + extra + 5;
1579       GET_SYMBOL(model6pos, sym);
1580       Q_READ_BITS(extra, CAB(q_extra_bits)[sym]);
1581       match_offset = CAB(q_position_base)[sym] + extra + 1;
1582       break;
1583
1584     default:
1585       TRACE("Selector is bogus\n");
1586       return DECR_ILLEGALDATA;
1587     }
1588
1589     /* if this is a match */
1590     if (selector >= 4) {
1591       rundest = window + window_posn;
1592       togo -= match_length;
1593
1594       /* copy any wrapped around source data */
1595       if (window_posn >= match_offset) {
1596         /* no wrap */
1597         runsrc = rundest - match_offset;
1598       } else {
1599         runsrc = rundest + (window_size - match_offset);
1600         copy_length = match_offset - window_posn;
1601         if (copy_length < match_length) {
1602           match_length -= copy_length;
1603           window_posn += copy_length;
1604           while (copy_length-- > 0) *rundest++ = *runsrc++;
1605           runsrc = window;
1606         }
1607       }
1608       window_posn += match_length;
1609
1610       /* copy match data - no worries about destination wraps */
1611       while (match_length-- > 0) *rundest++ = *runsrc++;
1612     }
1613   } /* while (togo > 0) */
1614
1615   if (togo != 0) {
1616     TRACE("Frame overflow, this_run = %d\n", togo);
1617     return DECR_ILLEGALDATA;
1618   }
1619
1620   memcpy(CAB(outbuf), window + ((!window_posn) ? window_size : window_posn) -
1621     outlen, outlen);
1622
1623   QTM(window_posn) = window_posn;
1624   return DECR_OK;
1625 }
1626
1627 /************************************************************
1628  * fdi_lzx_read_lens (internal)
1629  */
1630 static int fdi_lzx_read_lens(cab_UBYTE *lens, cab_ULONG first, cab_ULONG last, struct lzx_bits *lb,
1631                   fdi_decomp_state *decomp_state) {
1632   cab_ULONG i,j, x,y;
1633   int z;
1634
1635   register cab_ULONG bitbuf = lb->bb;
1636   register int bitsleft = lb->bl;
1637   cab_UBYTE *inpos = lb->ip;
1638   cab_UWORD *hufftbl;
1639   
1640   for (x = 0; x < 20; x++) {
1641     READ_BITS(y, 4);
1642     LENTABLE(PRETREE)[x] = y;
1643   }
1644   BUILD_TABLE(PRETREE);
1645
1646   for (x = first; x < last; ) {
1647     READ_HUFFSYM(PRETREE, z);
1648     if (z == 17) {
1649       READ_BITS(y, 4); y += 4;
1650       while (y--) lens[x++] = 0;
1651     }
1652     else if (z == 18) {
1653       READ_BITS(y, 5); y += 20;
1654       while (y--) lens[x++] = 0;
1655     }
1656     else if (z == 19) {
1657       READ_BITS(y, 1); y += 4;
1658       READ_HUFFSYM(PRETREE, z);
1659       z = lens[x] - z; if (z < 0) z += 17;
1660       while (y--) lens[x++] = z;
1661     }
1662     else {
1663       z = lens[x] - z; if (z < 0) z += 17;
1664       lens[x++] = z;
1665     }
1666   }
1667
1668   lb->bb = bitbuf;
1669   lb->bl = bitsleft;
1670   lb->ip = inpos;
1671   return 0;
1672 }
1673
1674 /*******************************************************
1675  * LZXfdi_decomp(internal)
1676  */
1677 static int LZXfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state) {
1678   cab_UBYTE *inpos  = CAB(inbuf);
1679   const cab_UBYTE *endinp = inpos + inlen;
1680   cab_UBYTE *window = LZX(window);
1681   cab_UBYTE *runsrc, *rundest;
1682   cab_UWORD *hufftbl; /* used in READ_HUFFSYM macro as chosen decoding table */
1683
1684   cab_ULONG window_posn = LZX(window_posn);
1685   cab_ULONG window_size = LZX(window_size);
1686   cab_ULONG R0 = LZX(R0);
1687   cab_ULONG R1 = LZX(R1);
1688   cab_ULONG R2 = LZX(R2);
1689
1690   register cab_ULONG bitbuf;
1691   register int bitsleft;
1692   cab_ULONG match_offset, i,j,k; /* ijk used in READ_HUFFSYM macro */
1693   struct lzx_bits lb; /* used in READ_LENGTHS macro */
1694
1695   int togo = outlen, this_run, main_element, aligned_bits;
1696   int match_length, copy_length, length_footer, extra, verbatim_bits;
1697
1698   TRACE("(inlen == %d, outlen == %d)\n", inlen, outlen);
1699
1700   INIT_BITSTREAM;
1701
1702   /* read header if necessary */
1703   if (!LZX(header_read)) {
1704     i = j = 0;
1705     READ_BITS(k, 1); if (k) { READ_BITS(i,16); READ_BITS(j,16); }
1706     LZX(intel_filesize) = (i << 16) | j; /* or 0 if not encoded */
1707     LZX(header_read) = 1;
1708   }
1709
1710   /* main decoding loop */
1711   while (togo > 0) {
1712     /* last block finished, new block expected */
1713     if (LZX(block_remaining) == 0) {
1714       if (LZX(block_type) == LZX_BLOCKTYPE_UNCOMPRESSED) {
1715         if (LZX(block_length) & 1) inpos++; /* realign bitstream to word */
1716         INIT_BITSTREAM;
1717       }
1718
1719       READ_BITS(LZX(block_type), 3);
1720       READ_BITS(i, 16);
1721       READ_BITS(j, 8);
1722       LZX(block_remaining) = LZX(block_length) = (i << 8) | j;
1723
1724       switch (LZX(block_type)) {
1725       case LZX_BLOCKTYPE_ALIGNED:
1726         for (i = 0; i < 8; i++) { READ_BITS(j, 3); LENTABLE(ALIGNED)[i] = j; }
1727         BUILD_TABLE(ALIGNED);
1728         /* rest of aligned header is same as verbatim */
1729
1730       case LZX_BLOCKTYPE_VERBATIM:
1731         READ_LENGTHS(MAINTREE, 0, 256, fdi_lzx_read_lens);
1732         READ_LENGTHS(MAINTREE, 256, LZX(main_elements), fdi_lzx_read_lens);
1733         BUILD_TABLE(MAINTREE);
1734         if (LENTABLE(MAINTREE)[0xE8] != 0) LZX(intel_started) = 1;
1735
1736         READ_LENGTHS(LENGTH, 0, LZX_NUM_SECONDARY_LENGTHS, fdi_lzx_read_lens);
1737         BUILD_TABLE(LENGTH);
1738         break;
1739
1740       case LZX_BLOCKTYPE_UNCOMPRESSED:
1741         LZX(intel_started) = 1; /* because we can't assume otherwise */
1742         ENSURE_BITS(16); /* get up to 16 pad bits into the buffer */
1743         if (bitsleft > 16) inpos -= 2; /* and align the bitstream! */
1744         R0 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
1745         R1 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
1746         R2 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
1747         break;
1748
1749       default:
1750         return DECR_ILLEGALDATA;
1751       }
1752     }
1753
1754     /* buffer exhaustion check */
1755     if (inpos > endinp) {
1756       /* it's possible to have a file where the next run is less than
1757        * 16 bits in size. In this case, the READ_HUFFSYM() macro used
1758        * in building the tables will exhaust the buffer, so we should
1759        * allow for this, but not allow those accidentally read bits to
1760        * be used (so we check that there are at least 16 bits
1761        * remaining - in this boundary case they aren't really part of
1762        * the compressed data)
1763        */
1764       if (inpos > (endinp+2) || bitsleft < 16) return DECR_ILLEGALDATA;
1765     }
1766
1767     while ((this_run = LZX(block_remaining)) > 0 && togo > 0) {
1768       if (this_run > togo) this_run = togo;
1769       togo -= this_run;
1770       LZX(block_remaining) -= this_run;
1771
1772       /* apply 2^x-1 mask */
1773       window_posn &= window_size - 1;
1774       /* runs can't straddle the window wraparound */
1775       if ((window_posn + this_run) > window_size)
1776         return DECR_DATAFORMAT;
1777
1778       switch (LZX(block_type)) {
1779
1780       case LZX_BLOCKTYPE_VERBATIM:
1781         while (this_run > 0) {
1782           READ_HUFFSYM(MAINTREE, main_element);
1783
1784           if (main_element < LZX_NUM_CHARS) {
1785             /* literal: 0 to LZX_NUM_CHARS-1 */
1786             window[window_posn++] = main_element;
1787             this_run--;
1788           }
1789           else {
1790             /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
1791             main_element -= LZX_NUM_CHARS;
1792   
1793             match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
1794             if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
1795               READ_HUFFSYM(LENGTH, length_footer);
1796               match_length += length_footer;
1797             }
1798             match_length += LZX_MIN_MATCH;
1799   
1800             match_offset = main_element >> 3;
1801   
1802             if (match_offset > 2) {
1803               /* not repeated offset */
1804               if (match_offset != 3) {
1805                 extra = CAB(extra_bits)[match_offset];
1806                 READ_BITS(verbatim_bits, extra);
1807                 match_offset = CAB(lzx_position_base)[match_offset] 
1808                                - 2 + verbatim_bits;
1809               }
1810               else {
1811                 match_offset = 1;
1812               }
1813   
1814               /* update repeated offset LRU queue */
1815               R2 = R1; R1 = R0; R0 = match_offset;
1816             }
1817             else if (match_offset == 0) {
1818               match_offset = R0;
1819             }
1820             else if (match_offset == 1) {
1821               match_offset = R1;
1822               R1 = R0; R0 = match_offset;
1823             }
1824             else /* match_offset == 2 */ {
1825               match_offset = R2;
1826               R2 = R0; R0 = match_offset;
1827             }
1828
1829             rundest = window + window_posn;
1830             this_run -= match_length;
1831
1832             /* copy any wrapped around source data */
1833             if (window_posn >= match_offset) {
1834               /* no wrap */
1835               runsrc = rundest - match_offset;
1836             } else {
1837               runsrc = rundest + (window_size - match_offset);
1838               copy_length = match_offset - window_posn;
1839               if (copy_length < match_length) {
1840                 match_length -= copy_length;
1841                 window_posn += copy_length;
1842                 while (copy_length-- > 0) *rundest++ = *runsrc++;
1843                 runsrc = window;
1844               }
1845             }
1846             window_posn += match_length;
1847
1848             /* copy match data - no worries about destination wraps */
1849             while (match_length-- > 0) *rundest++ = *runsrc++;
1850           }
1851         }
1852         break;
1853
1854       case LZX_BLOCKTYPE_ALIGNED:
1855         while (this_run > 0) {
1856           READ_HUFFSYM(MAINTREE, main_element);
1857   
1858           if (main_element < LZX_NUM_CHARS) {
1859             /* literal: 0 to LZX_NUM_CHARS-1 */
1860             window[window_posn++] = main_element;
1861             this_run--;
1862           }
1863           else {
1864             /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
1865             main_element -= LZX_NUM_CHARS;
1866   
1867             match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
1868             if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
1869               READ_HUFFSYM(LENGTH, length_footer);
1870               match_length += length_footer;
1871             }
1872             match_length += LZX_MIN_MATCH;
1873   
1874             match_offset = main_element >> 3;
1875   
1876             if (match_offset > 2) {
1877               /* not repeated offset */
1878               extra = CAB(extra_bits)[match_offset];
1879               match_offset = CAB(lzx_position_base)[match_offset] - 2;
1880               if (extra > 3) {
1881                 /* verbatim and aligned bits */
1882                 extra -= 3;
1883                 READ_BITS(verbatim_bits, extra);
1884                 match_offset += (verbatim_bits << 3);
1885                 READ_HUFFSYM(ALIGNED, aligned_bits);
1886                 match_offset += aligned_bits;
1887               }
1888               else if (extra == 3) {
1889                 /* aligned bits only */
1890                 READ_HUFFSYM(ALIGNED, aligned_bits);
1891                 match_offset += aligned_bits;
1892               }
1893               else if (extra > 0) { /* extra==1, extra==2 */
1894                 /* verbatim bits only */
1895                 READ_BITS(verbatim_bits, extra);
1896                 match_offset += verbatim_bits;
1897               }
1898               else /* extra == 0 */ {
1899                 /* ??? */
1900                 match_offset = 1;
1901               }
1902   
1903               /* update repeated offset LRU queue */
1904               R2 = R1; R1 = R0; R0 = match_offset;
1905             }
1906             else if (match_offset == 0) {
1907               match_offset = R0;
1908             }
1909             else if (match_offset == 1) {
1910               match_offset = R1;
1911               R1 = R0; R0 = match_offset;
1912             }
1913             else /* match_offset == 2 */ {
1914               match_offset = R2;
1915               R2 = R0; R0 = match_offset;
1916             }
1917
1918             rundest = window + window_posn;
1919             this_run -= match_length;
1920
1921             /* copy any wrapped around source data */
1922             if (window_posn >= match_offset) {
1923               /* no wrap */
1924               runsrc = rundest - match_offset;
1925             } else {
1926               runsrc = rundest + (window_size - match_offset);
1927               copy_length = match_offset - window_posn;
1928               if (copy_length < match_length) {
1929                 match_length -= copy_length;
1930                 window_posn += copy_length;
1931                 while (copy_length-- > 0) *rundest++ = *runsrc++;
1932                 runsrc = window;
1933               }
1934             }
1935             window_posn += match_length;
1936
1937             /* copy match data - no worries about destination wraps */
1938             while (match_length-- > 0) *rundest++ = *runsrc++;
1939           }
1940         }
1941         break;
1942
1943       case LZX_BLOCKTYPE_UNCOMPRESSED:
1944         if ((inpos + this_run) > endinp) return DECR_ILLEGALDATA;
1945         memcpy(window + window_posn, inpos, (size_t) this_run);
1946         inpos += this_run; window_posn += this_run;
1947         break;
1948
1949       default:
1950         return DECR_ILLEGALDATA; /* might as well */
1951       }
1952
1953     }
1954   }
1955
1956   if (togo != 0) return DECR_ILLEGALDATA;
1957   memcpy(CAB(outbuf), window + ((!window_posn) ? window_size : window_posn) -
1958     outlen, (size_t) outlen);
1959
1960   LZX(window_posn) = window_posn;
1961   LZX(R0) = R0;
1962   LZX(R1) = R1;
1963   LZX(R2) = R2;
1964
1965   /* intel E8 decoding */
1966   if ((LZX(frames_read)++ < 32768) && LZX(intel_filesize) != 0) {
1967     if (outlen <= 6 || !LZX(intel_started)) {
1968       LZX(intel_curpos) += outlen;
1969     }
1970     else {
1971       cab_UBYTE *data    = CAB(outbuf);
1972       cab_UBYTE *dataend = data + outlen - 10;
1973       cab_LONG curpos    = LZX(intel_curpos);
1974       cab_LONG filesize  = LZX(intel_filesize);
1975       cab_LONG abs_off, rel_off;
1976
1977       LZX(intel_curpos) = curpos + outlen;
1978
1979       while (data < dataend) {
1980         if (*data++ != 0xE8) { curpos++; continue; }
1981         abs_off = data[0] | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);
1982         if ((abs_off >= -curpos) && (abs_off < filesize)) {
1983           rel_off = (abs_off >= 0) ? abs_off - curpos : abs_off + filesize;
1984           data[0] = (cab_UBYTE) rel_off;
1985           data[1] = (cab_UBYTE) (rel_off >> 8);
1986           data[2] = (cab_UBYTE) (rel_off >> 16);
1987           data[3] = (cab_UBYTE) (rel_off >> 24);
1988         }
1989         data += 4;
1990         curpos += 5;
1991       }
1992     }
1993   }
1994   return DECR_OK;
1995 }
1996
1997 /**********************************************************
1998  * fdi_decomp (internal)
1999  *
2000  * Decompress the requested number of bytes.  If savemode is zero,
2001  * do not save the output anywhere, just plow through blocks until we
2002  * reach the specified (uncompressed) distance from the starting point,
2003  * and remember the position of the cabfile pointer (and which cabfile)
2004  * after we are done; otherwise, save the data out to CAB(filehf),
2005  * decompressing the requested number of bytes and writing them out.  This
2006  * is also where we jump to additional cabinets in the case of split
2007  * cab's, and provide (some of) the NEXT_CABINET notification semantics.
2008  */
2009 static int fdi_decomp(const struct fdi_file *fi, int savemode, fdi_decomp_state *decomp_state,
2010   char *pszCabPath, PFNFDINOTIFY pfnfdin, void *pvUser)
2011 {
2012   cab_ULONG bytes = savemode ? fi->length : fi->offset - CAB(offset);
2013   cab_UBYTE buf[cfdata_SIZEOF], *data;
2014   cab_UWORD inlen, len, outlen, cando;
2015   cab_ULONG cksum;
2016   cab_LONG err;
2017   fdi_decomp_state *cab = (savemode && CAB(decomp_cab)) ? CAB(decomp_cab) : decomp_state;
2018
2019   TRACE("(fi == ^%p, savemode == %d, bytes == %d)\n", fi, savemode, bytes);
2020
2021   while (bytes > 0) {
2022     /* cando = the max number of bytes we can do */
2023     cando = CAB(outlen);
2024     if (cando > bytes) cando = bytes;
2025
2026     /* if cando != 0 */
2027     if (cando && savemode)
2028       PFDI_WRITE(CAB(hfdi), CAB(filehf), CAB(outpos), cando);
2029
2030     CAB(outpos) += cando;
2031     CAB(outlen) -= cando;
2032     bytes -= cando; if (!bytes) break;
2033
2034     /* we only get here if we emptied the output buffer */
2035
2036     /* read data header + data */
2037     inlen = outlen = 0;
2038     while (outlen == 0) {
2039       /* read the block header, skip the reserved part */
2040       if (PFDI_READ(CAB(hfdi), cab->cabhf, buf, cfdata_SIZEOF) != cfdata_SIZEOF)
2041         return DECR_INPUT;
2042
2043       if (PFDI_SEEK(CAB(hfdi), cab->cabhf, cab->mii.block_resv, SEEK_CUR) == -1)
2044         return DECR_INPUT;
2045
2046       /* we shouldn't get blocks over CAB_INPUTMAX in size */
2047       data = CAB(inbuf) + inlen;
2048       len = EndGetI16(buf+cfdata_CompressedSize);
2049       inlen += len;
2050       if (inlen > CAB_INPUTMAX) return DECR_INPUT;
2051       if (PFDI_READ(CAB(hfdi), cab->cabhf, data, len) != len)
2052         return DECR_INPUT;
2053
2054       /* clear two bytes after read-in data */
2055       data[len+1] = data[len+2] = 0;
2056
2057       /* perform checksum test on the block (if one is stored) */
2058       cksum = EndGetI32(buf+cfdata_CheckSum);
2059       if (cksum && cksum != checksum(buf+4, 4, checksum(data, len, 0)))
2060         return DECR_CHECKSUM; /* checksum is wrong */
2061
2062       outlen = EndGetI16(buf+cfdata_UncompressedSize);
2063
2064       /* outlen=0 means this block was the last contiguous part
2065          of a split block, continued in the next cabinet */
2066       if (outlen == 0) {
2067         int pathlen, filenamelen, idx, i, cabhf;
2068         char fullpath[MAX_PATH], userpath[256];
2069         FDINOTIFICATION fdin;
2070         FDICABINETINFO fdici;
2071         char emptystring = '\0';
2072         cab_UBYTE buf2[64];
2073         int success = FALSE;
2074         struct fdi_folder *fol = NULL, *linkfol = NULL; 
2075         struct fdi_file   *file = NULL, *linkfile = NULL;
2076
2077         tryanothercab:
2078
2079         /* set up the next decomp_state... */
2080         if (!(cab->next)) {
2081           if (!cab->mii.hasnext) return DECR_INPUT;
2082
2083           if (!((cab->next = PFDI_ALLOC(CAB(hfdi), sizeof(fdi_decomp_state)))))
2084             return DECR_NOMEMORY;
2085         
2086           ZeroMemory(cab->next, sizeof(fdi_decomp_state));
2087
2088           /* copy pszCabPath to userpath */
2089           ZeroMemory(userpath, 256);
2090           pathlen = (pszCabPath) ? strlen(pszCabPath) : 0;
2091           if (pathlen) {
2092             if (pathlen < 256) {
2093               for (i = 0; i <= pathlen; i++)
2094                 userpath[i] = pszCabPath[i];
2095             } /* else we are in a weird place... let's leave it blank and see if the user fixes it */
2096           } 
2097
2098           /* initial fdintNEXT_CABINET notification */
2099           ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2100           fdin.psz1 = (cab->mii.nextname) ? cab->mii.nextname : &emptystring;
2101           fdin.psz2 = (cab->mii.nextinfo) ? cab->mii.nextinfo : &emptystring;
2102           fdin.psz3 = &userpath[0];
2103           fdin.fdie = FDIERROR_NONE;
2104           fdin.pv = pvUser;
2105
2106           if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2107
2108           do {
2109
2110             pathlen = strlen(userpath);
2111             filenamelen = (cab->mii.nextname) ? strlen(cab->mii.nextname) : 0;
2112
2113             /* slight overestimation here to save CPU cycles in the developer's brain */
2114             if ((pathlen + filenamelen + 3) > MAX_PATH) {
2115               ERR("MAX_PATH exceeded.\n");
2116               return DECR_ILLEGALDATA;
2117             }
2118
2119             /* paste the path and filename together */
2120             idx = 0;
2121             if (pathlen) {
2122               for (i = 0; i < pathlen; i++) fullpath[idx++] = userpath[i];
2123               if (fullpath[idx - 1] != '\\') fullpath[idx++] = '\\';
2124             }
2125             if (filenamelen) for (i = 0; i < filenamelen; i++) fullpath[idx++] = cab->mii.nextname[i];
2126             fullpath[idx] = '\0';
2127         
2128             TRACE("full cab path/file name: %s\n", debugstr_a(fullpath));
2129         
2130             /* try to get a handle to the cabfile */
2131             cabhf = PFDI_OPEN(CAB(hfdi), fullpath, 32768, _S_IREAD | _S_IWRITE);
2132             if (cabhf == -1) {
2133               /* no file.  allow the user to try again */
2134               fdin.fdie = FDIERROR_CABINET_NOT_FOUND;
2135               if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2136               continue;
2137             }
2138         
2139             if (cabhf == 0) {
2140               ERR("PFDI_OPEN returned zero for %s.\n", fullpath);
2141               fdin.fdie = FDIERROR_CABINET_NOT_FOUND;
2142               if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2143               continue;
2144             }
2145  
2146             /* check if it's really a cabfile. Note that this doesn't implement the bug */
2147             if (!FDI_read_entries(CAB(hfdi), cabhf, &fdici, &(cab->next->mii))) {
2148               WARN("FDIIsCabinet failed.\n");
2149               PFDI_CLOSE(CAB(hfdi), cabhf);
2150               fdin.fdie = FDIERROR_NOT_A_CABINET;
2151               if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2152               continue;
2153             }
2154
2155             if ((fdici.setID != cab->setID) || (fdici.iCabinet != (cab->iCabinet + 1))) {
2156               WARN("Wrong Cabinet.\n");
2157               PFDI_CLOSE(CAB(hfdi), cabhf);
2158               fdin.fdie = FDIERROR_WRONG_CABINET;
2159               if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2160               continue;
2161             }
2162            
2163             break;
2164
2165           } while (1);
2166           
2167           /* cabinet notification */
2168           ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2169           fdin.setID = fdici.setID;
2170           fdin.iCabinet = fdici.iCabinet;
2171           fdin.pv = pvUser;
2172           fdin.psz1 = (cab->next->mii.nextname) ? cab->next->mii.nextname : &emptystring;
2173           fdin.psz2 = (cab->next->mii.nextinfo) ? cab->next->mii.nextinfo : &emptystring;
2174           fdin.psz3 = pszCabPath;
2175         
2176           if (((*pfnfdin)(fdintCABINET_INFO, &fdin))) return DECR_USERABORT;
2177           
2178           cab->next->setID = fdici.setID;
2179           cab->next->iCabinet = fdici.iCabinet;
2180           cab->next->hfdi = CAB(hfdi);
2181           cab->next->filehf = CAB(filehf);
2182           cab->next->cabhf = cabhf;
2183           cab->next->decompress = CAB(decompress); /* crude, but unused anyhow */
2184
2185           cab = cab->next; /* advance to the next cabinet */
2186
2187           /* read folders */
2188           for (i = 0; i < fdici.cFolders; i++) {
2189             if (PFDI_READ(CAB(hfdi), cab->cabhf, buf2, cffold_SIZEOF) != cffold_SIZEOF) 
2190               return DECR_INPUT;
2191
2192             if (cab->mii.folder_resv > 0)
2193               PFDI_SEEK(CAB(hfdi), cab->cabhf, cab->mii.folder_resv, SEEK_CUR);
2194         
2195             fol = (struct fdi_folder *) PFDI_ALLOC(CAB(hfdi), sizeof(struct fdi_folder));
2196             if (!fol) {
2197               ERR("out of memory!\n");
2198               return DECR_NOMEMORY;
2199             }
2200             ZeroMemory(fol, sizeof(struct fdi_folder));
2201             if (!(cab->firstfol)) cab->firstfol = fol;
2202         
2203             fol->offset = (cab_off_t) EndGetI32(buf2+cffold_DataOffset);
2204             fol->num_blocks = EndGetI16(buf2+cffold_NumBlocks);
2205             fol->comp_type  = EndGetI16(buf2+cffold_CompType);
2206         
2207             if (linkfol)
2208               linkfol->next = fol; 
2209             linkfol = fol;
2210           }
2211         
2212           /* read files */
2213           for (i = 0; i < fdici.cFiles; i++) {
2214             if (PFDI_READ(CAB(hfdi), cab->cabhf, buf2, cffile_SIZEOF) != cffile_SIZEOF)
2215               return DECR_INPUT;
2216               
2217             file = (struct fdi_file *) PFDI_ALLOC(CAB(hfdi), sizeof(struct fdi_file));
2218             if (!file) {
2219               ERR("out of memory!\n"); 
2220               return DECR_NOMEMORY;
2221             }
2222             ZeroMemory(file, sizeof(struct fdi_file));
2223             if (!(cab->firstfile)) cab->firstfile = file;
2224               
2225             file->length   = EndGetI32(buf2+cffile_UncompressedSize);
2226             file->offset   = EndGetI32(buf2+cffile_FolderOffset);
2227             file->index    = EndGetI16(buf2+cffile_FolderIndex);
2228             file->time     = EndGetI16(buf2+cffile_Time);
2229             file->date     = EndGetI16(buf2+cffile_Date);
2230             file->attribs  = EndGetI16(buf2+cffile_Attribs);
2231             file->filename = FDI_read_string(CAB(hfdi), cab->cabhf, fdici.cbCabinet);
2232         
2233             if (!file->filename) return DECR_INPUT;
2234         
2235             if (linkfile)
2236               linkfile->next = file;
2237             linkfile = file;
2238           }
2239         
2240         } else 
2241             cab = cab->next; /* advance to the next cabinet */
2242
2243         /* iterate files -- if we encounter the continued file, process it --
2244            otherwise, jump to the label above and keep looking */
2245
2246         for (file = cab->firstfile; (file); file = file->next) {
2247           if ((file->index & cffileCONTINUED_FROM_PREV) == cffileCONTINUED_FROM_PREV) {
2248             /* check to ensure a real match */
2249             if (strcasecmp(fi->filename, file->filename) == 0) {
2250               success = TRUE;
2251               if (PFDI_SEEK(CAB(hfdi), cab->cabhf, cab->firstfol->offset, SEEK_SET) == -1)
2252                 return DECR_INPUT;
2253               break;
2254             }
2255           }
2256         }
2257         if (!success) goto tryanothercab; /* FIXME: shouldn't this trigger
2258                                              "Wrong Cabinet" notification? */
2259       }
2260     }
2261
2262     /* decompress block */
2263     if ((err = CAB(decompress)(inlen, outlen, decomp_state)))
2264       return err;
2265     CAB(outlen) = outlen;
2266     CAB(outpos) = CAB(outbuf);
2267   }
2268   
2269   CAB(decomp_cab) = cab;
2270   return DECR_OK;
2271 }
2272
2273 /***********************************************************************
2274  *              FDICopy (CABINET.22)
2275  *
2276  * Iterates through the files in the Cabinet file indicated by name and
2277  * file-location.  May chain forward to additional cabinets (typically
2278  * only one) if files which begin in this Cabinet are continued in another
2279  * cabinet.  For each file which is partially contained in this cabinet,
2280  * and partially contained in a prior cabinet, provides fdintPARTIAL_FILE
2281  * notification to the pfnfdin callback.  For each file which begins in
2282  * this cabinet, fdintCOPY_FILE notification is provided to the pfnfdin
2283  * callback, and the file is optionally decompressed and saved to disk.
2284  * Notification is not provided for files which are not at least partially
2285  * contained in the specified cabinet file.
2286  *
2287  * See below for a thorough explanation of the various notification
2288  * callbacks.
2289  *
2290  * PARAMS
2291  *   hfdi       [I] An HFDI from FDICreate
2292  *   pszCabinet [I] C-style string containing the filename of the cabinet
2293  *   pszCabPath [I] C-style string containing the file path of the cabinet
2294  *   flags      [I] "Decoder parameters".  Ignored.  Suggested value: 0.
2295  *   pfnfdin    [I] Pointer to a notification function.  See CALLBACKS below.
2296  *   pfnfdid    [I] Pointer to a decryption function.  Ignored.  Suggested
2297  *                  value: NULL.
2298  *   pvUser     [I] arbitrary void * value which is passed to callbacks.
2299  *
2300  * RETURNS
2301  *   TRUE if successful.
2302  *   FALSE if unsuccessful (error information is provided in the ERF structure
2303  *     associated with the provided decompression handle by FDICreate).
2304  *
2305  * CALLBACKS
2306  *
2307  *   Two pointers to callback functions are provided as parameters to FDICopy:
2308  *   pfnfdin(of type PFNFDINOTIFY), and pfnfdid (of type PFNFDIDECRYPT).  These
2309  *   types are as follows:
2310  *
2311  *     typedef INT_PTR (__cdecl *PFNFDINOTIFY)  ( FDINOTIFICATIONTYPE fdint,
2312  *                                               PFDINOTIFICATION  pfdin );
2313  *
2314  *     typedef int     (__cdecl *PFNFDIDECRYPT) ( PFDIDECRYPT pfdid );
2315  *
2316  *   You can create functions of this type using the FNFDINOTIFY() and
2317  *   FNFDIDECRYPT() macros, respectively.  For example:
2318  *
2319  *     FNFDINOTIFY(mycallback) {
2320  *       / * use variables fdint and pfdin to process notification * /
2321  *     }
2322  *
2323  *   The second callback, which could be used for decrypting encrypted data,
2324  *   is not used at all.
2325  *
2326  *   Each notification informs the user of some event which has occurred during
2327  *   decompression of the cabinet file; each notification is also an opportunity
2328  *   for the callee to abort decompression.  The information provided to the
2329  *   callback and the meaning of the callback's return value vary drastically
2330  *   across the various types of notification.  The type of notification is the
2331  *   fdint parameter; all other information is provided to the callback in
2332  *   notification-specific parts of the FDINOTIFICATION structure pointed to by
2333  *   pfdin.  The only part of that structure which is assigned for every callback
2334  *   is the pv element, which contains the arbitrary value which was passed to
2335  *   FDICopy in the pvUser argument (psz1 is also used each time, but its meaning
2336  *   is highly dependent on fdint).
2337  *   
2338  *   If you encounter unknown notifications, you should return zero if you want
2339  *   decompression to continue (or -1 to abort).  All strings used in the
2340  *   callbacks are regular C-style strings.  Detailed descriptions of each
2341  *   notification type follow:
2342  *
2343  *   fdintCABINET_INFO:
2344  * 
2345  *     This is the first notification provided after calling FDICopy, and provides
2346  *     the user with various information about the cabinet.  Note that this is
2347  *     called for each cabinet FDICopy opens, not just the first one.  In the
2348  *     structure pointed to by pfdin, psz1 contains a pointer to the name of the
2349  *     next cabinet file in the set after the one just loaded (if any), psz2
2350  *     contains a pointer to the name or "info" of the next disk, psz3
2351  *     contains a pointer to the file-path of the current cabinet, setID
2352  *     contains an arbitrary constant associated with this set of cabinet files,
2353  *     and iCabinet contains the numerical index of the current cabinet within
2354  *     that set.  Return zero, or -1 to abort.
2355  *
2356  *   fdintPARTIAL_FILE:
2357  *
2358  *     This notification is provided when FDICopy encounters a part of a file
2359  *     contained in this cabinet which is missing its beginning.  Files can be
2360  *     split across cabinets, so this is not necessarily an abnormality; it just
2361  *     means that the file in question begins in another cabinet.  No file
2362  *     corresponding to this notification is extracted from the cabinet.  In the
2363  *     structure pointed to by pfdin, psz1 contains a pointer to the name of the
2364  *     partial file, psz2 contains a pointer to the file name of the cabinet in
2365  *     which this file begins, and psz3 contains a pointer to the disk name or
2366  *     "info" of the cabinet where the file begins. Return zero, or -1 to abort.
2367  *
2368  *   fdintCOPY_FILE:
2369  *
2370  *     This notification is provided when FDICopy encounters a file which starts
2371  *     in the cabinet file, provided to FDICopy in pszCabinet.  (FDICopy will not
2372  *     look for files in cabinets after the first one).  One notification will be
2373  *     sent for each such file, before the file is decompressed.  By returning
2374  *     zero, the callback can instruct FDICopy to skip the file.  In the structure
2375  *     pointed to by pfdin, psz1 contains a pointer to the file's name, cb contains
2376  *     the size of the file (uncompressed), attribs contains the file attributes,
2377  *     and date and time contain the date and time of the file.  attributes, date,
2378  *     and time are of the 16-bit ms-dos variety.  Return -1 to abort decompression
2379  *     for the entire cabinet, 0 to skip just this file but continue scanning the
2380  *     cabinet for more files, or an FDIClose()-compatible file-handle.
2381  *
2382  *   fdintCLOSE_FILE_INFO:
2383  *
2384  *     This notification is important, don't forget to implement it.  This
2385  *     notification indicates that a file has been successfully uncompressed and
2386  *     written to disk.  Upon receipt of this notification, the callee is expected
2387  *     to close the file handle, to set the attributes and date/time of the
2388  *     closed file, and possibly to execute the file.  In the structure pointed to
2389  *     by pfdin, psz1 contains a pointer to the name of the file, hf will be the
2390  *     open file handle (close it), cb contains 1 or zero, indicating respectively
2391  *     that the callee should or should not execute the file, and date, time
2392  *     and attributes will be set as in fdintCOPY_FILE.  Bizarrely, the Cabinet SDK
2393  *     specifies that _A_EXEC will be xor'ed out of attributes!  wine does not do
2394  *     do so.  Return TRUE, or FALSE to abort decompression.
2395  *
2396  *   fdintNEXT_CABINET:
2397  *
2398  *     This notification is called when FDICopy must load in another cabinet.  This
2399  *     can occur when a file's data is "split" across multiple cabinets.  The
2400  *     callee has the opportunity to request that FDICopy look in a different file
2401  *     path for the specified cabinet file, by writing that data into a provided
2402  *     buffer (see below for more information).  This notification will be received
2403  *     more than once per-cabinet in the instance that FDICopy failed to find a
2404  *     valid cabinet at the location specified by the first per-cabinet
2405  *     fdintNEXT_CABINET notification.  In such instances, the fdie element of the
2406  *     structure pointed to by pfdin indicates the error which prevented FDICopy
2407  *     from proceeding successfully.  Return zero to indicate success, or -1 to
2408  *     indicate failure and abort FDICopy.
2409  *
2410  *     Upon receipt of this notification, the structure pointed to by pfdin will
2411  *     contain the following values: psz1 pointing to the name of the cabinet
2412  *     which FDICopy is attempting to open, psz2 pointing to the name ("info") of
2413  *     the next disk, psz3 pointing to the presumed file-location of the cabinet,
2414  *     and fdie containing either FDIERROR_NONE, or one of the following: 
2415  *
2416  *       FDIERROR_CABINET_NOT_FOUND, FDIERROR_NOT_A_CABINET,
2417  *       FDIERROR_UNKNOWN_CABINET_VERSION, FDIERROR_CORRUPT_CABINET,
2418  *       FDIERROR_BAD_COMPR_TYPE, FDIERROR_RESERVE_MISMATCH, and 
2419  *       FDIERROR_WRONG_CABINET.
2420  *
2421  *     The callee may choose to change the path where FDICopy will look for the
2422  *     cabinet after this notification.  To do so, the caller may write the new
2423  *     pathname to the buffer pointed to by psz3, which is 256 characters in
2424  *     length, including the terminating null character, before returning zero.
2425  *
2426  *   fdintENUMERATE:
2427  *
2428  *     Undocumented and unimplemented in wine, this seems to be sent each time
2429  *     a cabinet is opened, along with the fdintCABINET_INFO notification.  It
2430  *     probably has an interface similar to that of fdintCABINET_INFO; maybe this
2431  *     provides information about the current cabinet instead of the next one....
2432  *     this is just a guess, it has not been looked at closely.
2433  *
2434  * INCLUDES
2435  *   fdi.c
2436  */
2437 BOOL __cdecl FDICopy(
2438         HFDI           hfdi,
2439         char          *pszCabinet,
2440         char          *pszCabPath,
2441         int            flags,
2442         PFNFDINOTIFY   pfnfdin,
2443         PFNFDIDECRYPT  pfnfdid,
2444         void          *pvUser)
2445
2446   FDICABINETINFO    fdici;
2447   FDINOTIFICATION   fdin;
2448   int               cabhf, filehf = 0, idx;
2449   unsigned int      i;
2450   char              fullpath[MAX_PATH];
2451   size_t            pathlen, filenamelen;
2452   char              emptystring = '\0';
2453   cab_UBYTE         buf[64];
2454   struct fdi_folder *fol = NULL, *linkfol = NULL; 
2455   struct fdi_file   *file = NULL, *linkfile = NULL;
2456   fdi_decomp_state _decomp_state;
2457   fdi_decomp_state *decomp_state = &_decomp_state;
2458
2459   TRACE("(hfdi == ^%p, pszCabinet == ^%p, pszCabPath == ^%p, flags == %0d, "
2460         "pfnfdin == ^%p, pfnfdid == ^%p, pvUser == ^%p)\n",
2461         hfdi, pszCabinet, pszCabPath, flags, pfnfdin, pfnfdid, pvUser);
2462
2463   if (!REALLY_IS_FDI(hfdi)) {
2464     SetLastError(ERROR_INVALID_HANDLE);
2465     return FALSE;
2466   }
2467
2468   ZeroMemory(decomp_state, sizeof(fdi_decomp_state));
2469
2470   pathlen = (pszCabPath) ? strlen(pszCabPath) : 0;
2471   filenamelen = (pszCabinet) ? strlen(pszCabinet) : 0;
2472
2473   /* slight overestimation here to save CPU cycles in the developer's brain */
2474   if ((pathlen + filenamelen + 3) > MAX_PATH) {
2475     ERR("MAX_PATH exceeded.\n");
2476     PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CABINET_NOT_FOUND;
2477     PFDI_INT(hfdi)->perf->erfType = ERROR_FILE_NOT_FOUND;
2478     PFDI_INT(hfdi)->perf->fError = TRUE;
2479     SetLastError(ERROR_FILE_NOT_FOUND);
2480     return FALSE;
2481   }
2482
2483   /* paste the path and filename together */
2484   idx = 0;
2485   if (pathlen) {
2486     for (i = 0; i < pathlen; i++) fullpath[idx++] = pszCabPath[i];
2487     if (fullpath[idx - 1] != '\\') fullpath[idx++] = '\\';
2488   }
2489   if (filenamelen) for (i = 0; i < filenamelen; i++) fullpath[idx++] = pszCabinet[i];
2490   fullpath[idx] = '\0';
2491
2492   TRACE("full cab path/file name: %s\n", debugstr_a(fullpath));
2493
2494   /* get a handle to the cabfile */
2495   cabhf = PFDI_OPEN(hfdi, fullpath, 32768, _S_IREAD | _S_IWRITE);
2496   if (cabhf == -1) {
2497     PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CABINET_NOT_FOUND;
2498     PFDI_INT(hfdi)->perf->erfType = ERROR_FILE_NOT_FOUND;
2499     PFDI_INT(hfdi)->perf->fError = TRUE;
2500     SetLastError(ERROR_FILE_NOT_FOUND);
2501     return FALSE;
2502   }
2503
2504   if (cabhf == 0) {
2505     ERR("PFDI_OPEN returned zero for %s.\n", fullpath);
2506     PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CABINET_NOT_FOUND;
2507     PFDI_INT(hfdi)->perf->erfType = ERROR_FILE_NOT_FOUND;
2508     PFDI_INT(hfdi)->perf->fError = TRUE;
2509     SetLastError(ERROR_FILE_NOT_FOUND);
2510     return FALSE;
2511   }
2512
2513   /* check if it's really a cabfile. Note that this doesn't implement the bug */
2514   if (!FDI_read_entries(hfdi, cabhf, &fdici, &(CAB(mii)))) {
2515     ERR("FDIIsCabinet failed.\n");
2516     PFDI_CLOSE(hfdi, cabhf);
2517     return FALSE;
2518   }
2519    
2520   /* cabinet notification */
2521   ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2522   fdin.setID = fdici.setID;
2523   fdin.iCabinet = fdici.iCabinet;
2524   fdin.pv = pvUser;
2525   fdin.psz1 = (CAB(mii).nextname) ? CAB(mii).nextname : &emptystring;
2526   fdin.psz2 = (CAB(mii).nextinfo) ? CAB(mii).nextinfo : &emptystring;
2527   fdin.psz3 = pszCabPath;
2528
2529   if (((*pfnfdin)(fdintCABINET_INFO, &fdin))) {
2530     PFDI_INT(hfdi)->perf->erfOper = FDIERROR_USER_ABORT;
2531     PFDI_INT(hfdi)->perf->erfType = 0;
2532     PFDI_INT(hfdi)->perf->fError = TRUE;
2533     goto bail_and_fail;
2534   }
2535
2536   CAB(setID) = fdici.setID;
2537   CAB(iCabinet) = fdici.iCabinet;
2538   CAB(cabhf) = cabhf;
2539
2540   /* read folders */
2541   for (i = 0; i < fdici.cFolders; i++) {
2542     if (PFDI_READ(hfdi, cabhf, buf, cffold_SIZEOF) != cffold_SIZEOF) {
2543       PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
2544       PFDI_INT(hfdi)->perf->erfType = 0;
2545       PFDI_INT(hfdi)->perf->fError = TRUE;
2546       goto bail_and_fail;
2547     }
2548
2549     if (CAB(mii).folder_resv > 0)
2550       PFDI_SEEK(hfdi, cabhf, CAB(mii).folder_resv, SEEK_CUR);
2551
2552     fol = (struct fdi_folder *) PFDI_ALLOC(hfdi, sizeof(struct fdi_folder));
2553     if (!fol) {
2554       ERR("out of memory!\n");
2555       PFDI_INT(hfdi)->perf->erfOper = FDIERROR_ALLOC_FAIL;
2556       PFDI_INT(hfdi)->perf->erfType = ERROR_NOT_ENOUGH_MEMORY;
2557       PFDI_INT(hfdi)->perf->fError = TRUE;
2558       SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2559       goto bail_and_fail;
2560     }
2561     ZeroMemory(fol, sizeof(struct fdi_folder));
2562     if (!CAB(firstfol)) CAB(firstfol) = fol;
2563
2564     fol->offset = (cab_off_t) EndGetI32(buf+cffold_DataOffset);
2565     fol->num_blocks = EndGetI16(buf+cffold_NumBlocks);
2566     fol->comp_type  = EndGetI16(buf+cffold_CompType);
2567
2568     if (linkfol)
2569       linkfol->next = fol; 
2570     linkfol = fol;
2571   }
2572
2573   /* read files */
2574   for (i = 0; i < fdici.cFiles; i++) {
2575     if (PFDI_READ(hfdi, cabhf, buf, cffile_SIZEOF) != cffile_SIZEOF) {
2576       PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
2577       PFDI_INT(hfdi)->perf->erfType = 0;
2578       PFDI_INT(hfdi)->perf->fError = TRUE;
2579       goto bail_and_fail;
2580     }
2581
2582     file = (struct fdi_file *) PFDI_ALLOC(hfdi, sizeof(struct fdi_file));
2583     if (!file) { 
2584       ERR("out of memory!\n"); 
2585       PFDI_INT(hfdi)->perf->erfOper = FDIERROR_ALLOC_FAIL;
2586       PFDI_INT(hfdi)->perf->erfType = ERROR_NOT_ENOUGH_MEMORY;
2587       PFDI_INT(hfdi)->perf->fError = TRUE;
2588       SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2589       goto bail_and_fail;
2590     }
2591     ZeroMemory(file, sizeof(struct fdi_file));
2592     if (!CAB(firstfile)) CAB(firstfile) = file;
2593       
2594     file->length   = EndGetI32(buf+cffile_UncompressedSize);
2595     file->offset   = EndGetI32(buf+cffile_FolderOffset);
2596     file->index    = EndGetI16(buf+cffile_FolderIndex);
2597     file->time     = EndGetI16(buf+cffile_Time);
2598     file->date     = EndGetI16(buf+cffile_Date);
2599     file->attribs  = EndGetI16(buf+cffile_Attribs);
2600     file->filename = FDI_read_string(hfdi, cabhf, fdici.cbCabinet);
2601
2602     if (!file->filename) {
2603       PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
2604       PFDI_INT(hfdi)->perf->erfType = 0;
2605       PFDI_INT(hfdi)->perf->fError = TRUE;
2606       goto bail_and_fail;
2607     }
2608
2609     if (linkfile)
2610       linkfile->next = file;
2611     linkfile = file;
2612   }
2613
2614   for (file = CAB(firstfile); (file); file = file->next) {
2615
2616     /*
2617      * FIXME: This implementation keeps multiple cabinet files open at once
2618      * when encountering a split cabinet.  It is a quirk of this implementation
2619      * that sometimes we decrypt the same block of data more than once, to find
2620      * the right starting point for a file, moving the file-pointer backwards.
2621      * If we kept a cache of certain file-pointer information, we could eliminate
2622      * that behavior... in fact I am not sure that the caching we already have
2623      * is not sufficient.
2624      * 
2625      * The current implementation seems to work fine in straightforward situations
2626      * where all the cabinet files needed for decryption are simultaneously
2627      * available.  But presumably, the API is supposed to support cabinets which
2628      * are split across multiple CDROMS; we may need to change our implementation
2629      * to strictly serialize it's file usage so that it opens only one cabinet
2630      * at a time.  Some experimentation with Windows is needed to figure out the
2631      * precise semantics required.  The relevant code is here and in fdi_decomp().
2632      */
2633
2634     /* partial-file notification */
2635     if ((file->index & cffileCONTINUED_FROM_PREV) == cffileCONTINUED_FROM_PREV) {
2636       /*
2637        * FIXME: Need to create a Cabinet with a single file spanning multiple files
2638        * and perform some tests to figure out the right behavior.  The SDK says
2639        * FDICopy will notify the user of the filename and "disk name" (info) of
2640        * the cabinet where the spanning file /started/.
2641        *
2642        * That would certainly be convenient for the API-user, who could abort,
2643        * everything (or parallelize, if that's allowed (it is in wine)), and call
2644        * FDICopy again with the provided filename, so as to avoid partial file
2645        * notification and successfully unpack.  This task could be quite unpleasant
2646        * from wine's perspective: the information specifying the "start cabinet" for
2647        * a file is associated nowhere with the file header and is not to be found in
2648        * the cabinet header.  We have only the index of the cabinet wherein the folder
2649        * begins, which contains the file.  To find that cabinet, we must consider the
2650        * index of the current cabinet, and chain backwards, cabinet-by-cabinet (for
2651        * each cabinet refers to its "next" and "previous" cabinet only, like a linked
2652        * list).
2653        *
2654        * Bear in mind that, in the spirit of CABINET.DLL, we must assume that any
2655        * cabinet other than the active one might be at another filepath than the
2656        * current one, or on another CDROM. This could get rather dicey, especially
2657        * if we imagine parallelized access to the FDICopy API.
2658        *
2659        * The current implementation punts -- it just returns the previous cabinet and
2660        * it's info from the header of this cabinet.  This provides the right answer in
2661        * 95% of the cases; its worth checking if Microsoft cuts the same corner before
2662        * we "fix" it.
2663        */
2664       ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2665       fdin.pv = pvUser;
2666       fdin.psz1 = (char *)file->filename;
2667       fdin.psz2 = (CAB(mii).prevname) ? CAB(mii).prevname : &emptystring;
2668       fdin.psz3 = (CAB(mii).previnfo) ? CAB(mii).previnfo : &emptystring;
2669
2670       if (((*pfnfdin)(fdintPARTIAL_FILE, &fdin))) {
2671         PFDI_INT(hfdi)->perf->erfOper = FDIERROR_USER_ABORT;
2672         PFDI_INT(hfdi)->perf->erfType = 0;
2673         PFDI_INT(hfdi)->perf->fError = TRUE;
2674         goto bail_and_fail;
2675       }
2676       /* I don't think we are supposed to decompress partial files.  This prevents it. */
2677       file->oppressed = TRUE;
2678     }
2679     if (file->oppressed) {
2680       filehf = 0;
2681     } else {
2682       ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2683       fdin.pv = pvUser;
2684       fdin.psz1 = (char *)file->filename;
2685       fdin.cb = file->length;
2686       fdin.date = file->date;
2687       fdin.time = file->time;
2688       fdin.attribs = file->attribs;
2689       if ((filehf = ((*pfnfdin)(fdintCOPY_FILE, &fdin))) == -1) {
2690         PFDI_INT(hfdi)->perf->erfOper = FDIERROR_USER_ABORT;
2691         PFDI_INT(hfdi)->perf->erfType = 0;
2692         PFDI_INT(hfdi)->perf->fError = TRUE;
2693         goto bail_and_fail;
2694       }
2695     }
2696
2697     /* find the folder for this file if necc. */
2698     if (filehf) {
2699       int i2;
2700
2701       fol = CAB(firstfol);
2702       if ((file->index & cffileCONTINUED_TO_NEXT) == cffileCONTINUED_TO_NEXT) {
2703         /* pick the last folder */
2704         while (fol->next) fol = fol->next;
2705       } else {
2706         for (i2 = 0; (i2 < file->index); i2++)
2707           if (fol->next) /* bug resistance, should always be true */
2708             fol = fol->next;
2709       }
2710     }
2711
2712     if (filehf) {
2713       cab_UWORD comptype = fol->comp_type;
2714       int ct1 = comptype & cffoldCOMPTYPE_MASK;
2715       int ct2 = CAB(current) ? (CAB(current)->comp_type & cffoldCOMPTYPE_MASK) : 0;
2716       int err = 0;
2717
2718       TRACE("Extracting file %s as requested by callee.\n", debugstr_a(file->filename));
2719
2720       /* set up decomp_state */
2721       CAB(hfdi) = hfdi;
2722       CAB(filehf) = filehf;
2723
2724       /* Was there a change of folder?  Compression type?  Did we somehow go backwards? */
2725       if ((ct1 != ct2) || (CAB(current) != fol) || (file->offset < CAB(offset))) {
2726
2727         TRACE("Resetting folder for file %s.\n", debugstr_a(file->filename));
2728
2729         /* free stuff for the old decompresser */
2730         switch (ct2) {
2731         case cffoldCOMPTYPE_LZX:
2732           if (LZX(window)) {
2733             PFDI_FREE(hfdi, LZX(window));
2734             LZX(window) = NULL;
2735           }
2736           break;
2737         case cffoldCOMPTYPE_QUANTUM:
2738           if (QTM(window)) {
2739             PFDI_FREE(hfdi, QTM(window));
2740             QTM(window) = NULL;
2741           }
2742           break;
2743         }
2744
2745         CAB(decomp_cab) = NULL;
2746         PFDI_SEEK(CAB(hfdi), CAB(cabhf), fol->offset, SEEK_SET);
2747         CAB(offset) = 0;
2748         CAB(outlen) = 0;
2749
2750         /* initialize the new decompresser */
2751         switch (ct1) {
2752         case cffoldCOMPTYPE_NONE:
2753           CAB(decompress) = NONEfdi_decomp;
2754           break;
2755         case cffoldCOMPTYPE_MSZIP:
2756           CAB(decompress) = ZIPfdi_decomp;
2757           break;
2758         case cffoldCOMPTYPE_QUANTUM:
2759           CAB(decompress) = QTMfdi_decomp;
2760           err = QTMfdi_init((comptype >> 8) & 0x1f, (comptype >> 4) & 0xF, decomp_state);
2761           break;
2762         case cffoldCOMPTYPE_LZX:
2763           CAB(decompress) = LZXfdi_decomp;
2764           err = LZXfdi_init((comptype >> 8) & 0x1f, decomp_state);
2765           break;
2766         default:
2767           err = DECR_DATAFORMAT;
2768         }
2769       }
2770
2771       CAB(current) = fol;
2772
2773       switch (err) {
2774         case DECR_OK:
2775           break;
2776         case DECR_NOMEMORY:
2777           PFDI_INT(hfdi)->perf->erfOper = FDIERROR_ALLOC_FAIL;
2778           PFDI_INT(hfdi)->perf->erfType = ERROR_NOT_ENOUGH_MEMORY;
2779           PFDI_INT(hfdi)->perf->fError = TRUE;
2780           SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2781           goto bail_and_fail;
2782         default:
2783           PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
2784           PFDI_INT(hfdi)->perf->erfOper = 0;
2785           PFDI_INT(hfdi)->perf->fError = TRUE;
2786           goto bail_and_fail;
2787       }
2788
2789       if (file->offset > CAB(offset)) {
2790         /* decode bytes and send them to /dev/null */
2791         switch ((err = fdi_decomp(file, 0, decomp_state, pszCabPath, pfnfdin, pvUser))) {
2792           case DECR_OK:
2793             break;
2794           case DECR_USERABORT:
2795             PFDI_INT(hfdi)->perf->erfOper = FDIERROR_USER_ABORT;
2796             PFDI_INT(hfdi)->perf->erfType = 0;
2797             PFDI_INT(hfdi)->perf->fError = TRUE;
2798             goto bail_and_fail;
2799           case DECR_NOMEMORY:
2800             PFDI_INT(hfdi)->perf->erfOper = FDIERROR_ALLOC_FAIL;
2801             PFDI_INT(hfdi)->perf->erfType = ERROR_NOT_ENOUGH_MEMORY;
2802             PFDI_INT(hfdi)->perf->fError = TRUE;
2803             SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2804             goto bail_and_fail;
2805           default:
2806             PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
2807             PFDI_INT(hfdi)->perf->erfOper = 0;
2808             PFDI_INT(hfdi)->perf->fError = TRUE;
2809             goto bail_and_fail;
2810         }
2811         CAB(offset) = file->offset;
2812       }
2813
2814       /* now do the actual decompression */
2815       err = fdi_decomp(file, 1, decomp_state, pszCabPath, pfnfdin, pvUser);
2816       if (err) CAB(current) = NULL; else CAB(offset) += file->length;
2817
2818       /* fdintCLOSE_FILE_INFO notification */
2819       ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2820       fdin.pv = pvUser;
2821       fdin.psz1 = (char *)file->filename;
2822       fdin.hf = filehf;
2823       fdin.cb = (file->attribs & cffile_A_EXEC) ? TRUE : FALSE; /* FIXME: is that right? */
2824       fdin.date = file->date;
2825       fdin.time = file->time;
2826       fdin.attribs = file->attribs; /* FIXME: filter _A_EXEC? */
2827       ((*pfnfdin)(fdintCLOSE_FILE_INFO, &fdin));
2828       filehf = 0;
2829
2830       switch (err) {
2831         case DECR_OK:
2832           break;
2833         case DECR_USERABORT:
2834           PFDI_INT(hfdi)->perf->erfOper = FDIERROR_USER_ABORT;
2835           PFDI_INT(hfdi)->perf->erfType = 0;
2836           PFDI_INT(hfdi)->perf->fError = TRUE;
2837           goto bail_and_fail;
2838         case DECR_NOMEMORY:
2839           PFDI_INT(hfdi)->perf->erfOper = FDIERROR_ALLOC_FAIL;
2840           PFDI_INT(hfdi)->perf->erfType = ERROR_NOT_ENOUGH_MEMORY;
2841           PFDI_INT(hfdi)->perf->fError = TRUE;
2842           SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2843           goto bail_and_fail;
2844         default:
2845           PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
2846           PFDI_INT(hfdi)->perf->erfOper = 0;
2847           PFDI_INT(hfdi)->perf->fError = TRUE;
2848           goto bail_and_fail;
2849       }
2850     }
2851   }
2852
2853   /* free decompression temps */
2854   switch (fol->comp_type & cffoldCOMPTYPE_MASK) {
2855   case cffoldCOMPTYPE_LZX:
2856     if (LZX(window)) {
2857       PFDI_FREE(hfdi, LZX(window));
2858       LZX(window) = NULL;
2859     }
2860     break;
2861   case cffoldCOMPTYPE_QUANTUM:
2862     if (QTM(window)) {
2863       PFDI_FREE(hfdi, QTM(window));
2864       QTM(window) = NULL;
2865     }
2866     break;
2867   }
2868
2869   while (decomp_state) {
2870     fdi_decomp_state *prev_fds;
2871
2872     PFDI_CLOSE(hfdi, CAB(cabhf));
2873
2874     /* free the storage remembered by mii */
2875     if (CAB(mii).nextname) PFDI_FREE(hfdi, CAB(mii).nextname);
2876     if (CAB(mii).nextinfo) PFDI_FREE(hfdi, CAB(mii).nextinfo);
2877     if (CAB(mii).prevname) PFDI_FREE(hfdi, CAB(mii).prevname);
2878     if (CAB(mii).previnfo) PFDI_FREE(hfdi, CAB(mii).previnfo);
2879
2880     while (CAB(firstfol)) {
2881       fol = CAB(firstfol);
2882       CAB(firstfol) = CAB(firstfol)->next;
2883       PFDI_FREE(hfdi, fol);
2884     }
2885     while (CAB(firstfile)) {
2886       file = CAB(firstfile);
2887       if (file->filename) PFDI_FREE(hfdi, (void *)file->filename);
2888       CAB(firstfile) = CAB(firstfile)->next;
2889       PFDI_FREE(hfdi, file);
2890     }
2891     prev_fds = decomp_state;
2892     decomp_state = CAB(next);
2893     if (prev_fds != &_decomp_state)
2894       PFDI_FREE(hfdi, prev_fds);
2895   }
2896  
2897   return TRUE;
2898
2899   bail_and_fail: /* here we free ram before error returns */
2900
2901   /* free decompression temps */
2902   switch (fol->comp_type & cffoldCOMPTYPE_MASK) {
2903   case cffoldCOMPTYPE_LZX:
2904     if (LZX(window)) {
2905       PFDI_FREE(hfdi, LZX(window));
2906       LZX(window) = NULL;
2907     }
2908     break;
2909   case cffoldCOMPTYPE_QUANTUM:
2910     if (QTM(window)) {
2911       PFDI_FREE(hfdi, QTM(window));
2912       QTM(window) = NULL;
2913     }
2914     break;
2915   }
2916
2917   if (filehf) PFDI_CLOSE(hfdi, filehf);
2918
2919   while (decomp_state) {
2920     fdi_decomp_state *prev_fds;
2921
2922     PFDI_CLOSE(hfdi, CAB(cabhf));
2923
2924     /* free the storage remembered by mii */
2925     if (CAB(mii).nextname) PFDI_FREE(hfdi, CAB(mii).nextname);
2926     if (CAB(mii).nextinfo) PFDI_FREE(hfdi, CAB(mii).nextinfo);
2927     if (CAB(mii).prevname) PFDI_FREE(hfdi, CAB(mii).prevname);
2928     if (CAB(mii).previnfo) PFDI_FREE(hfdi, CAB(mii).previnfo);
2929
2930     while (CAB(firstfol)) {
2931       fol = CAB(firstfol);
2932       CAB(firstfol) = CAB(firstfol)->next;
2933       PFDI_FREE(hfdi, fol);
2934     }
2935     while (CAB(firstfile)) {
2936       file = CAB(firstfile);
2937       if (file->filename) PFDI_FREE(hfdi, (void *)file->filename);
2938       CAB(firstfile) = CAB(firstfile)->next;
2939       PFDI_FREE(hfdi, file);
2940     }
2941     prev_fds = decomp_state;
2942     decomp_state = CAB(next);
2943     if (prev_fds != &_decomp_state)
2944       PFDI_FREE(hfdi, prev_fds);
2945   }
2946
2947   return FALSE;
2948 }
2949
2950 /***********************************************************************
2951  *              FDIDestroy (CABINET.23)
2952  *
2953  * Frees a handle created by FDICreate.  Do /not/ call this in the middle
2954  * of FDICopy.  Only reason for failure would be an invalid handle.
2955  * 
2956  * PARAMS
2957  *   hfdi [I] The HFDI to free
2958  *
2959  * RETURNS
2960  *   TRUE for success
2961  *   FALSE for failure
2962  */
2963 BOOL __cdecl FDIDestroy(HFDI hfdi)
2964 {
2965   TRACE("(hfdi == ^%p)\n", hfdi);
2966   if (REALLY_IS_FDI(hfdi)) {
2967     PFDI_INT(hfdi)->FDI_Intmagic = 0; /* paranoia */
2968     PFDI_FREE(hfdi, hfdi); /* confusing, but correct */
2969     return TRUE;
2970   } else {
2971     SetLastError(ERROR_INVALID_HANDLE);
2972     return FALSE;
2973   }
2974 }
2975
2976 /***********************************************************************
2977  *              FDITruncateCabinet (CABINET.24)
2978  *
2979  * Removes all folders of a cabinet file after and including the
2980  * specified folder number.
2981  * 
2982  * PARAMS
2983  *   hfdi            [I] Handle to the FDI context.
2984  *   pszCabinetName  [I] Filename of the cabinet.
2985  *   iFolderToDelete [I] Index of the first folder to delete.
2986  * 
2987  * RETURNS
2988  *   Success: TRUE.
2989  *   Failure: FALSE.
2990  * 
2991  * NOTES
2992  *   The PFNWRITE function supplied to FDICreate must truncate the
2993  *   file at the current position if the number of bytes to write is 0.
2994  */
2995 BOOL __cdecl FDITruncateCabinet(
2996         HFDI    hfdi,
2997         char   *pszCabinetName,
2998         USHORT  iFolderToDelete)
2999 {
3000   FIXME("(hfdi == ^%p, pszCabinetName == %s, iFolderToDelete == %hu): stub\n",
3001     hfdi, debugstr_a(pszCabinetName), iFolderToDelete);
3002
3003   if (!REALLY_IS_FDI(hfdi)) {
3004     SetLastError(ERROR_INVALID_HANDLE);
3005     return FALSE;
3006   }
3007
3008   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3009   return FALSE;
3010 }