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