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