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