~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/cabinet/fdi.c

Version: ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  2  * File Decompression Interface
  3  *
  4  * Copyright 2000-2002 Stuart Caie
  5  * Copyright 2002 Patrik Stridvall
  6  * Copyright 2003 Greg Turner
  7  *
  8  * This library is free software; you can redistribute it and/or
  9  * modify it under the terms of the GNU Lesser General Public
 10  * License as published by the Free Software Foundation; either
 11  * version 2.1 of the License, or (at your option) any later version.
 12  *
 13  * This library is distributed in the hope that it will be useful,
 14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 16  * Lesser General Public License for more details.
 17  *
 18  * You should have received a copy of the GNU Lesser General Public
 19  * License along with this library; if not, write to the Free Software
 20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 21  *
 22  *
 23  * This is a largely redundant reimplementation of the stuff in cabextract.c.  It
 24  * would be theoretically preferable to have only one, shared implementation, however
 25  * there are semantic differences which may discourage efforts to unify the two.  It
 26  * should be possible, if awkward, to go back and reimplement cabextract.c using FDI.
 27  * But this approach would be quite a bit less performant.  Probably a better way
 28  * would be to create a "library" of routines in cabextract.c which do the actual
 29  * decompression, and have both fdi.c and cabextract share those routines.  The rest
 30  * of the code is not sufficiently similar to merit a shared implementation.
 31  *
 32  * The worst thing about this API is the bug.  "The bug" is this: when you extract a
 33  * cabinet, it /always/ informs you (via the hasnext field of PFDICABINETINFO), that
 34  * there is no subsequent cabinet, even if there is one.  wine faithfully reproduces
 35  * this behavior.
 36  *
 37  * TODO:
 38  *
 39  * Wine does not implement the AFAIK undocumented "enumerate" callback during
 40  * FDICopy.  It is implemented in Windows and therefore worth investigating...
 41  *
 42  * Lots of pointers flying around here... am I leaking RAM?
 43  *
 44  * WTF is FDITruncate?
 45  *
 46  * Probably, I need to weed out some dead code-paths.
 47  *
 48  * Test unit(s).
 49  *
 50  * The fdintNEXT_CABINET callbacks are probably not working quite as they should.
 51  * There are several FIXME's in the source describing some of the deficiencies in
 52  * some detail.  Additionally, we do not do a very good job of returning the right
 53  * error codes to this callback.
 54  *
 55  * FDICopy and fdi_decomp are incomprehensibly large; separating these into smaller
 56  * functions would be nice.
 57  *
 58  *   -gmt
 59  */
 60 
 61 #include "config.h"
 62 
 63 #include <stdarg.h>
 64 #include <stdio.h>
 65 
 66 #include "windef.h"
 67 #include "winbase.h"
 68 #include "winerror.h"
 69 #include "fdi.h"
 70 #include "cabinet.h"
 71 
 72 #include "wine/debug.h"
 73 
 74 WINE_DEFAULT_DEBUG_CHANNEL(cabinet);
 75 
 76 THOSE_ZIP_CONSTS;
 77 
 78 struct fdi_file {
 79   struct fdi_file *next;               /* next file in sequence          */
 80   LPCSTR filename;                     /* output name of file            */
 81   int    fh;                           /* open file handle or NULL       */
 82   cab_ULONG length;                    /* uncompressed length of file    */
 83   cab_ULONG offset;                    /* uncompressed offset in folder  */
 84   cab_UWORD index;                     /* magic index number of folder   */
 85   cab_UWORD time, date, attribs;       /* MS-DOS time/date/attributes    */
 86   BOOL oppressed;                      /* never to be processed          */
 87 };
 88 
 89 struct fdi_folder {
 90   struct fdi_folder *next;
 91   cab_off_t offset;                    /* offset to data blocks (32 bit) */
 92   cab_UWORD comp_type;                 /* compression format/window size */
 93   cab_ULONG comp_size;                 /* compressed size of folder      */
 94   cab_UBYTE num_splits;                /* number of split blocks + 1     */
 95   cab_UWORD num_blocks;                /* total number of blocks         */
 96 };
 97 
 98 /*
 99  * this structure fills the gaps between what is available in a PFDICABINETINFO
100  * vs what is needed by FDICopy.  Memory allocated for these becomes the responsibility
101  * of the caller to free.  Yes, I am aware that this is totally, utterly inelegant.
102  * To make things even more unnecessarily confusing, we now attach these to the
103  * fdi_decomp_state.
104  */
105 typedef struct {
106    char *prevname, *previnfo;
107    char *nextname, *nextinfo;
108    BOOL hasnext;  /* bug free indicator */
109    int folder_resv, header_resv;
110    cab_UBYTE block_resv;
111 } MORE_ISCAB_INFO, *PMORE_ISCAB_INFO;
112 
113 /*
114  * ugh, well, this ended up being pretty damn silly...
115  * now that I've conceded to build equivalent structures to struct cab.*,
116  * I should have just used those, or, better yet, unified the two... sue me.
117  * (Note to Microsoft: That's a joke.  Please /don't/ actually sue me! -gmt).
118  * Nevertheless, I've come this far, it works, so I'm not gonna change it
119  * for now.  This implementation has significant semantic differences anyhow.
120  */
121 
122 typedef struct fdi_cds_fwd {
123   void *hfdi;                      /* the hfdi we are using                 */
124   int filehf, cabhf;               /* file handle we are using              */
125   struct fdi_folder *current;      /* current folder we're extracting from  */
126   cab_ULONG offset;                /* uncompressed offset within folder     */
127   cab_UBYTE *outpos;               /* (high level) start of data to use up  */
128   cab_UWORD outlen;                /* (high level) amount of data to use up */
129   int (*decompress)(int, int, struct fdi_cds_fwd *); /* chosen compress fn  */
130   cab_UBYTE inbuf[CAB_INPUTMAX+2]; /* +2 for lzx bitbuffer overflows!       */
131   cab_UBYTE outbuf[CAB_BLOCKMAX];
132   union {
133     struct ZIPstate zip;
134     struct QTMstate qtm;
135     struct LZXstate lzx;
136   } methods;
137   /* some temp variables for use during decompression */
138   cab_UBYTE q_length_base[27], q_length_extra[27], q_extra_bits[42];
139   cab_ULONG q_position_base[42];
140   cab_ULONG lzx_position_base[51];
141   cab_UBYTE extra_bits[51];
142   USHORT  setID;                   /* Cabinet set ID */
143   USHORT  iCabinet;                /* Cabinet number in set (0 based) */
144   struct fdi_cds_fwd *decomp_cab;
145   MORE_ISCAB_INFO mii;
146   struct fdi_folder *firstfol; 
147   struct fdi_file   *firstfile;
148   struct fdi_cds_fwd *next;
149 } fdi_decomp_state;
150 
151 /****************************************************************
152  * QTMupdatemodel (internal)
153  */
154 void QTMupdatemodel(struct QTMmodel *model, int sym) {
155   struct QTMmodelsym temp;
156   int i, j;
157 
158   for (i = 0; i < sym; i++) model->syms[i].cumfreq += 8;
159 
160   if (model->syms[0].cumfreq > 3800) {
161     if (--model->shiftsleft) {
162       for (i = model->entries - 1; i >= 0; i--) {
163         /* -1, not -2; the 0 entry saves this */
164         model->syms[i].cumfreq >>= 1;
165         if (model->syms[i].cumfreq <= model->syms[i+1].cumfreq) {
166           model->syms[i].cumfreq = model->syms[i+1].cumfreq + 1;
167         }
168       }
169     }
170     else {
171       model->shiftsleft = 50;
172       for (i = 0; i < model->entries ; i++) {
173         /* no -1, want to include the 0 entry */
174         /* this converts cumfreqs into frequencies, then shifts right */
175         model->syms[i].cumfreq -= model->syms[i+1].cumfreq;
176         model->syms[i].cumfreq++; /* avoid losing things entirely */
177         model->syms[i].cumfreq >>= 1;
178       }
179 
180       /* now sort by frequencies, decreasing order -- this must be an
181        * inplace selection sort, or a sort with the same (in)stability
182        * characteristics
183        */
184       for (i = 0; i < model->entries - 1; i++) {
185         for (j = i + 1; j < model->entries; j++) {
186           if (model->syms[i].cumfreq < model->syms[j].cumfreq) {
187             temp = model->syms[i];
188             model->syms[i] = model->syms[j];
189             model->syms[j] = temp;
190           }
191         }
192       }
193 
194       /* then convert frequencies back to cumfreq */
195       for (i = model->entries - 1; i >= 0; i--) {
196         model->syms[i].cumfreq += model->syms[i+1].cumfreq;
197       }
198       /* then update the other part of the table */
199       for (i = 0; i < model->entries; i++) {
200         model->tabloc[model->syms[i].sym] = i;
201       }
202     }
203   }
204 }
205 
206 /*************************************************************************
207  * make_decode_table (internal)
208  *
209  * This function was coded by David Tritscher. It builds a fast huffman
210  * decoding table out of just a canonical huffman code lengths table.
211  *
212  * PARAMS
213  *   nsyms:  total number of symbols in this huffman tree.
214  *   nbits:  any symbols with a code length of nbits or less can be decoded
215  *           in one lookup of the table.
216  *   length: A table to get code lengths from [0 to syms-1]
217  *   table:  The table to fill up with decoded symbols and pointers.
218  *
219  * RETURNS
220  *   OK:    0
221  *   error: 1
222  */
223 int make_decode_table(cab_ULONG nsyms, cab_ULONG nbits, const cab_UBYTE *length, cab_UWORD *table) {
224   register cab_UWORD sym;
225   register cab_ULONG leaf;
226   register cab_UBYTE bit_num = 1;
227   cab_ULONG fill;
228   cab_ULONG pos         = 0; /* the current position in the decode table */
229   cab_ULONG table_mask  = 1 << nbits;
230   cab_ULONG bit_mask    = table_mask >> 1; /* don't do 0 length codes */
231   cab_ULONG next_symbol = bit_mask; /* base of allocation for long codes */
232 
233   /* fill entries for codes short enough for a direct mapping */
234   while (bit_num <= nbits) {
235     for (sym = 0; sym < nsyms; sym++) {
236       if (length[sym] == bit_num) {
237         leaf = pos;
238 
239         if((pos += bit_mask) > table_mask) return 1; /* table overrun */
240 
241         /* fill all possible lookups of this symbol with the symbol itself */
242         fill = bit_mask;
243         while (fill-- > 0) table[leaf++] = sym;
244       }
245     }
246     bit_mask >>= 1;
247     bit_num++;
248   }
249 
250   /* if there are any codes longer than nbits */
251   if (pos != table_mask) {
252     /* clear the remainder of the table */
253     for (sym = pos; sym < table_mask; sym++) table[sym] = 0;
254 
255     /* give ourselves room for codes to grow by up to 16 more bits */
256     pos <<= 16;
257     table_mask <<= 16;
258     bit_mask = 1 << 15;
259 
260     while (bit_num <= 16) {
261       for (sym = 0; sym < nsyms; sym++) {
262         if (length[sym] == bit_num) {
263           leaf = pos >> 16;
264           for (fill = 0; fill < bit_num - nbits; fill++) {
265             /* if this path hasn't been taken yet, 'allocate' two entries */
266             if (table[leaf] == 0) {
267               table[(next_symbol << 1)] = 0;
268               table[(next_symbol << 1) + 1] = 0;
269               table[leaf] = next_symbol++;
270             }
271             /* follow the path and select either left or right for next bit */
272             leaf = table[leaf] << 1;
273             if ((pos >> (15-fill)) & 1) leaf++;
274           }
275           table[leaf] = sym;
276 
277           if ((pos += bit_mask) > table_mask) return 1; /* table overflow */
278         }
279       }
280       bit_mask >>= 1;
281       bit_num++;
282     }
283   }
284 
285   /* full table? */
286   if (pos == table_mask) return 0;
287 
288   /* either erroneous table, or all elements are 0 - let's find out. */
289   for (sym = 0; sym < nsyms; sym++) if (length[sym]) return 1;
290   return 0;
291 }
292 
293 /*************************************************************************
294  * checksum (internal)
295  */
296 cab_ULONG checksum(const cab_UBYTE *data, cab_UWORD bytes, cab_ULONG csum) {
297   int len;
298   cab_ULONG ul = 0;
299 
300   for (len = bytes >> 2; len--; data += 4) {
301     csum ^= ((data[0]) | (data[1]<<8) | (data[2]<<16) | (data[3]<<24));
302   }
303 
304   switch (bytes & 3) {
305   case 3: ul |= *data++ << 16;
306   case 2: ul |= *data++ <<  8;
307   case 1: ul |= *data;
308   }
309   csum ^= ul;
310 
311   return csum;
312 }
313 
314 /***********************************************************************
315  *              FDICreate (CABINET.20)
316  *
317  * Provided with several callbacks (all of them are mandatory),
318  * returns a handle which can be used to perform operations
319  * on cabinet files.
320  *
321  * PARAMS
322  *   pfnalloc [I]  A pointer to a function which allocates ram.  Uses
323  *                 the same interface as malloc.
324  *   pfnfree  [I]  A pointer to a function which frees ram.  Uses the
325  *                 same interface as free.
326  *   pfnopen  [I]  A pointer to a function which opens a file.  Uses
327  *                 the same interface as _open.
328  *   pfnread  [I]  A pointer to a function which reads from a file into
329  *                 a caller-provided buffer.  Uses the same interface
330  *                 as _read
331  *   pfnwrite [I]  A pointer to a function which writes to a file from
332  *                 a caller-provided buffer.  Uses the same interface
333  *                 as _write.
334  *   pfnclose [I]  A pointer to a function which closes a file handle.
335  *                 Uses the same interface as _close.
336  *   pfnseek  [I]  A pointer to a function which seeks in a file.
337  *                 Uses the same interface as _lseek.
338  *   cpuType  [I]  The type of CPU; ignored in wine (recommended value:
339  *                 cpuUNKNOWN, aka -1).
340  *   perf     [IO] A pointer to an ERF structure.  When FDICreate
341  *                 returns an error condition, error information may
342  *                 be found here as well as from GetLastError.
343  *
344  * RETURNS
345  *   On success, returns an FDI handle of type HFDI.
346  *   On failure, the NULL file handle is returned. Error
347  *   info can be retrieved from perf.
348  *
349  * INCLUDES
350  *   fdi.h
351  * 
352  */
353 HFDI __cdecl FDICreate(
354         PFNALLOC pfnalloc,
355         PFNFREE  pfnfree,
356         PFNOPEN  pfnopen,
357         PFNREAD  pfnread,
358         PFNWRITE pfnwrite,
359         PFNCLOSE pfnclose,
360         PFNSEEK  pfnseek,
361         int      cpuType,
362         PERF     perf)
363 {
364   HFDI rv;
365 
366   TRACE("(pfnalloc == ^%p, pfnfree == ^%p, pfnopen == ^%p, pfnread == ^%p, pfnwrite == ^%p, "
367         "pfnclose == ^%p, pfnseek == ^%p, cpuType == %d, perf == ^%p)\n",
368         pfnalloc, pfnfree, pfnopen, pfnread, pfnwrite, pfnclose, pfnseek,
369         cpuType, perf);
370 
371   if ((!pfnalloc) || (!pfnfree)) {
372     perf->erfOper = FDIERROR_NONE;
373     perf->erfType = ERROR_BAD_ARGUMENTS;
374     perf->fError = TRUE;
375 
376     SetLastError(ERROR_BAD_ARGUMENTS);
377     return NULL;
378   }
379 
380   if (!((rv = (*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, cabhf;
2055         char fullpath[MAX_PATH], userpath[256];
2056         FDINOTIFICATION fdin;
2057         FDICABINETINFO fdici;
2058         char emptystring = '\0';
2059         cab_UBYTE buf2[64];
2060         int success = FALSE;
2061         struct fdi_folder *fol = NULL, *linkfol = NULL; 
2062         struct fdi_file   *file = NULL, *linkfile = NULL;
2063 
2064         tryanothercab:
2065 
2066         /* set up the next decomp_state... */
2067         if (!(cab->next)) {
2068           if (!cab->mii.hasnext) return DECR_INPUT;
2069 
2070           if (!((cab->next = PFDI_ALLOC(CAB(hfdi), sizeof(fdi_decomp_state)))))
2071             return DECR_NOMEMORY;
2072         
2073           ZeroMemory(cab->next, sizeof(fdi_decomp_state));
2074 
2075           /* copy pszCabPath to userpath */
2076           ZeroMemory(userpath, 256);
2077           pathlen = (pszCabPath) ? strlen(pszCabPath) : 0;
2078           if (pathlen) {
2079             if (pathlen < 256) {
2080               for (i = 0; i <= pathlen; i++)
2081                 userpath[i] = pszCabPath[i];
2082             } /* else we are in a weird place... let's leave it blank and see if the user fixes it */
2083           } 
2084 
2085           /* initial fdintNEXT_CABINET notification */
2086           ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2087           fdin.psz1 = (cab->mii.nextname) ? cab->mii.nextname : &emptystring;
2088           fdin.psz2 = (cab->mii.nextinfo) ? cab->mii.nextinfo : &emptystring;
2089           fdin.psz3 = &userpath[0];
2090           fdin.fdie = FDIERROR_NONE;
2091           fdin.pv = pvUser;
2092 
2093           if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2094 
2095           do {
2096 
2097             pathlen = strlen(userpath);
2098             filenamelen = (cab->mii.nextname) ? strlen(cab->mii.nextname) : 0;
2099 
2100             /* slight overestimation here to save CPU cycles in the developer's brain */
2101             if ((pathlen + filenamelen + 3) > MAX_PATH) {
2102               ERR("MAX_PATH exceeded.\n");
2103               return DECR_ILLEGALDATA;
2104             }
2105 
2106             /* paste the path and filename together */
2107             idx = 0;
2108             if (pathlen) {
2109               for (i = 0; i < pathlen; i++) fullpath[idx++] = userpath[i];
2110               if (fullpath[idx - 1] != '\\') fullpath[idx++] = '\\';
2111             }
2112             if (filenamelen) for (i = 0; i < filenamelen; i++) fullpath[idx++] = cab->mii.nextname[i];
2113             fullpath[idx] = '\0';
2114         
2115             TRACE("full cab path/file name: %s\n", debugstr_a(fullpath));
2116         
2117             /* try to get a handle to the cabfile */
2118             cabhf = PFDI_OPEN(CAB(hfdi), fullpath, _O_RDONLY|_O_BINARY, _S_IREAD | _S_IWRITE);
2119             if (cabhf == -1) {
2120               /* no file.  allow the user to try again */
2121               fdin.fdie = FDIERROR_CABINET_NOT_FOUND;
2122               if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2123               continue;
2124             }
2125         
2126             if (cabhf == 0) {
2127               ERR("PFDI_OPEN returned zero for %s.\n", fullpath);
2128               fdin.fdie = FDIERROR_CABINET_NOT_FOUND;
2129               if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2130               continue;
2131             }
2132  
2133             /* check if it's really a cabfile. Note that this doesn't implement the bug */
2134             if (!FDI_read_entries(CAB(hfdi), cabhf, &fdici, &(cab->next->mii))) {
2135               WARN("FDIIsCabinet failed.\n");
2136               PFDI_CLOSE(CAB(hfdi), cabhf);
2137               fdin.fdie = FDIERROR_NOT_A_CABINET;
2138               if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2139               continue;
2140             }
2141 
2142             if ((fdici.setID != cab->setID) || (fdici.iCabinet != (cab->iCabinet + 1))) {
2143               WARN("Wrong Cabinet.\n");
2144               PFDI_CLOSE(CAB(hfdi), cabhf);
2145               fdin.fdie = FDIERROR_WRONG_CABINET;
2146               if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2147               continue;
2148             }
2149            
2150             break;
2151 
2152           } while (1);
2153           
2154           /* cabinet notification */
2155           ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2156           fdin.setID = fdici.setID;
2157           fdin.iCabinet = fdici.iCabinet;
2158           fdin.pv = pvUser;
2159           fdin.psz1 = (cab->next->mii.nextname) ? cab->next->mii.nextname : &emptystring;
2160           fdin.psz2 = (cab->next->mii.nextinfo) ? cab->next->mii.nextinfo : &emptystring;
2161           fdin.psz3 = pszCabPath;
2162         
2163           if (((*pfnfdin)(fdintCABINET_INFO, &fdin))) return DECR_USERABORT;
2164           
2165           cab->next->setID = fdici.setID;
2166           cab->next->iCabinet = fdici.iCabinet;
2167           cab->next->hfdi = CAB(hfdi);
2168           cab->next->filehf = CAB(filehf);
2169           cab->next->cabhf = cabhf;
2170           cab->next->decompress = CAB(decompress); /* crude, but unused anyhow */
2171 
2172           cab = cab->next; /* advance to the next cabinet */
2173 
2174           /* read folders */
2175           for (i = 0; i < fdici.cFolders; i++) {
2176             if (PFDI_READ(CAB(hfdi), cab->cabhf, buf2, cffold_SIZEOF) != cffold_SIZEOF) 
2177               return DECR_INPUT;
2178 
2179             if (cab->mii.folder_resv > 0)
2180               PFDI_SEEK(CAB(hfdi), cab->cabhf, cab->mii.folder_resv, SEEK_CUR);
2181         
2182             fol = (struct fdi_folder *) PFDI_ALLOC(CAB(hfdi), sizeof(struct fdi_folder));
2183             if (!fol) {
2184               ERR("out of memory!\n");
2185               return DECR_NOMEMORY;
2186             }
2187             ZeroMemory(fol, sizeof(struct fdi_folder));
2188             if (!(cab->firstfol)) cab->firstfol = fol;
2189         
2190             fol->offset = (cab_off_t) EndGetI32(buf2+cffold_DataOffset);
2191             fol->num_blocks = EndGetI16(buf2+cffold_NumBlocks);
2192             fol->comp_type  = EndGetI16(buf2+cffold_CompType);
2193         
2194             if (linkfol)
2195               linkfol->next = fol; 
2196             linkfol = fol;
2197           }
2198         
2199           /* read files */
2200           for (i = 0; i < fdici.cFiles; i++) {
2201             if (PFDI_READ(CAB(hfdi), cab->cabhf, buf2, cffile_SIZEOF) != cffile_SIZEOF)
2202               return DECR_INPUT;
2203               
2204             file = (struct fdi_file *) PFDI_ALLOC(CAB(hfdi), sizeof(struct fdi_file));
2205             if (!file) {
2206               ERR("out of memory!\n"); 
2207               return DECR_NOMEMORY;
2208             }
2209             ZeroMemory(file, sizeof(struct fdi_file));
2210             if (!(cab->firstfile)) cab->firstfile = file;
2211               
2212             file->length   = EndGetI32(buf2+cffile_UncompressedSize);
2213             file->offset   = EndGetI32(buf2+cffile_FolderOffset);
2214             file->index    = EndGetI16(buf2+cffile_FolderIndex);
2215             file->time     = EndGetI16(buf2+cffile_Time);
2216             file->date     = EndGetI16(buf2+cffile_Date);
2217             file->attribs  = EndGetI16(buf2+cffile_Attribs);
2218             file->filename = FDI_read_string(CAB(hfdi), cab->cabhf, fdici.cbCabinet);
2219         
2220             if (!file->filename) return DECR_INPUT;
2221         
2222             if (linkfile)
2223               linkfile->next = file;
2224             linkfile = file;
2225           }
2226         
2227         } else 
2228             cab = cab->next; /* advance to the next cabinet */
2229 
2230         /* iterate files -- if we encounter the continued file, process it --
2231            otherwise, jump to the label above and keep looking */
2232 
2233         for (file = cab->firstfile; (file); file = file->next) {
2234           if ((file->index & cffileCONTINUED_FROM_PREV) == cffileCONTINUED_FROM_PREV) {
2235             /* check to ensure a real match */
2236             if (lstrcmpiA(fi->filename, file->filename) == 0) {
2237               success = TRUE;
2238               if (PFDI_SEEK(CAB(hfdi), cab->cabhf, cab->firstfol->offset, SEEK_SET) == -1)
2239                 return DECR_INPUT;
2240               break;
2241             }
2242           }
2243         }
2244         if (!success) goto tryanothercab; /* FIXME: shouldn't this trigger
2245                                              "Wrong Cabinet" notification? */
2246       }
2247     }
2248 
2249     /* decompress block */
2250     if ((err = CAB(decompress)(inlen, outlen, decomp_state)))
2251       return err;
2252     CAB(outlen) = outlen;
2253     CAB(outpos) = CAB(outbuf);
2254   }
2255   
2256   CAB(decomp_cab) = cab;
2257   return DECR_OK;
2258 }
2259 
2260 /***********************************************************************
2261  *              FDICopy (CABINET.22)
2262  *
2263  * Iterates through the files in the Cabinet file indicated by name and
2264  * file-location.  May chain forward to additional cabinets (typically
2265  * only one) if files which begin in this Cabinet are continued in another
2266  * cabinet.  For each file which is partially contained in this cabinet,
2267  * and partially contained in a prior cabinet, provides fdintPARTIAL_FILE
2268  * notification to the pfnfdin callback.  For each file which begins in
2269  * this cabinet, fdintCOPY_FILE notification is provided to the pfnfdin
2270  * callback, and the file is optionally decompressed and saved to disk.
2271  * Notification is not provided for files which are not at least partially
2272  * contained in the specified cabinet file.
2273  *
2274  * See below for a thorough explanation of the various notification
2275  * callbacks.
2276  *
2277  * PARAMS
2278  *   hfdi       [I] An HFDI from FDICreate
2279  *   pszCabinet [I] C-style string containing the filename of the cabinet
2280  *   pszCabPath [I] C-style string containing the file path of the cabinet
2281  *   flags      [I] "Decoder parameters".  Ignored.  Suggested value: 0.
2282  *   pfnfdin    [I] Pointer to a notification function.  See CALLBACKS below.
2283  *   pfnfdid    [I] Pointer to a decryption function.  Ignored.  Suggested
2284  *                  value: NULL.
2285  *   pvUser     [I] arbitrary void * value which is passed to callbacks.
2286  *
2287  * RETURNS
2288  *   TRUE if successful.
2289  *   FALSE if unsuccessful (error information is provided in the ERF structure
2290  *     associated with the provided decompression handle by FDICreate).
2291  *
2292  * CALLBACKS
2293  *
2294  *   Two pointers to callback functions are provided as parameters to FDICopy:
2295  *   pfnfdin(of type PFNFDINOTIFY), and pfnfdid (of type PFNFDIDECRYPT).  These
2296  *   types are as follows:
2297  *
2298  *     typedef INT_PTR (__cdecl *PFNFDINOTIFY)  ( FDINOTIFICATIONTYPE fdint,
2299  *                                               PFDINOTIFICATION  pfdin );
2300  *
2301  *     typedef int     (__cdecl *PFNFDIDECRYPT) ( PFDIDECRYPT pfdid );
2302  *
2303  *   You can create functions of this type using the FNFDINOTIFY() and
2304  *   FNFDIDECRYPT() macros, respectively.  For example:
2305  *
2306  *     FNFDINOTIFY(mycallback) {
2307  *       / * use variables fdint and pfdin to process notification * /
2308  *     }
2309  *
2310  *   The second callback, which could be used for decrypting encrypted data,
2311  *   is not used at all.
2312  *
2313  *   Each notification informs the user of some event which has occurred during
2314  *   decompression of the cabinet file; each notification is also an opportunity
2315  *   for the callee to abort decompression.  The information provided to the
2316  *   callback and the meaning of the callback's return value vary drastically
2317  *   across the various types of notification.  The type of notification is the
2318  *   fdint parameter; all other information is provided to the callback in
2319  *   notification-specific parts of the FDINOTIFICATION structure pointed to by
2320  *   pfdin.  The only part of that structure which is assigned for every callback
2321  *   is the pv element, which contains the arbitrary value which was passed to
2322  *   FDICopy in the pvUser argument (psz1 is also used each time, but its meaning
2323  *   is highly dependent on fdint).
2324  *   
2325  *   If you encounter unknown notifications, you should return zero if you want
2326  *   decompression to continue (or -1 to abort).  All strings used in the
2327  *   callbacks are regular C-style strings.  Detailed descriptions of each
2328  *   notification type follow:
2329  *
2330  *   fdintCABINET_INFO:
2331  * 
2332  *     This is the first notification provided after calling FDICopy, and provides
2333  *     the user with various information about the cabinet.  Note that this is
2334  *     called for each cabinet FDICopy opens, not just the first one.  In the
2335  *     structure pointed to by pfdin, psz1 contains a pointer to the name of the
2336  *     next cabinet file in the set after the one just loaded (if any), psz2
2337  *     contains a pointer to the name or "info" of the next disk, psz3
2338  *     contains a pointer to the file-path of the current cabinet, setID
2339  *     contains an arbitrary constant associated with this set of cabinet files,
2340  *     and iCabinet contains the numerical index of the current cabinet within
2341  *     that set.  Return zero, or -1 to abort.
2342  *
2343  *   fdintPARTIAL_FILE:
2344  *
2345  *     This notification is provided when FDICopy encounters a part of a file
2346  *     contained in this cabinet which is missing its beginning.  Files can be
2347  *     split across cabinets, so this is not necessarily an abnormality; it just
2348  *     means that the file in question begins in another cabinet.  No file
2349  *     corresponding to this notification is extracted from the cabinet.  In the
2350  *     structure pointed to by pfdin, psz1 contains a pointer to the name of the
2351  *     partial file, psz2 contains a pointer to the file name of the cabinet in
2352  *     which this file begins, and psz3 contains a pointer to the disk name or
2353  *     "info" of the cabinet where the file begins. Return zero, or -1 to abort.
2354  *
2355  *   fdintCOPY_FILE:
2356  *
2357  *     This notification is provided when FDICopy encounters a file which starts
2358  *     in the cabinet file, provided to FDICopy in pszCabinet.  (FDICopy will not
2359  *     look for files in cabinets after the first one).  One notification will be
2360  *     sent for each such file, before the file is decompressed.  By returning
2361  *     zero, the callback can instruct FDICopy to skip the file.  In the structure
2362  *     pointed to by pfdin, psz1 contains a pointer to the file's name, cb contains
2363  *     the size of the file (uncompressed), attribs contains the file attributes,
2364  *     and date and time contain the date and time of the file.  attributes, date,
2365  *     and time are of the 16-bit ms-dos variety.  Return -1 to abort decompression
2366  *     for the entire cabinet, 0 to skip just this file but continue scanning the
2367  *     cabinet for more files, or an FDIClose()-compatible file-handle.
2368  *
2369  *   fdintCLOSE_FILE_INFO:
2370  *
2371  *     This notification is important, don't forget to implement it.  This
2372  *     notification indicates that a file has been successfully uncompressed and
2373  *     written to disk.  Upon receipt of this notification, the callee is expected
2374  *     to close the file handle, to set the attributes and date/time of the
2375  *     closed file, and possibly to execute the file.  In the structure pointed to
2376  *     by pfdin, psz1 contains a pointer to the name of the file, hf will be the
2377  *     open file handle (close it), cb contains 1 or zero, indicating respectively
2378  *     that the callee should or should not execute the file, and date, time
2379  *     and attributes will be set as in fdintCOPY_FILE.  Bizarrely, the Cabinet SDK
2380  *     specifies that _A_EXEC will be xor'ed out of attributes!  wine does not do
2381  *     do so.  Return TRUE, or FALSE to abort decompression.
2382  *
2383  *   fdintNEXT_CABINET:
2384  *
2385  *     This notification is called when FDICopy must load in another cabinet.  This
2386  *     can occur when a file's data is "split" across multiple cabinets.  The
2387  *     callee has the opportunity to request that FDICopy look in a different file
2388  *     path for the specified cabinet file, by writing that data into a provided
2389  *     buffer (see below for more information).  This notification will be received
2390  *     more than once per-cabinet in the instance that FDICopy failed to find a
2391  *     valid cabinet at the location specified by the first per-cabinet
2392  *     fdintNEXT_CABINET notification.  In such instances, the fdie element of the
2393  *     structure pointed to by pfdin indicates the error which prevented FDICopy
2394  *     from proceeding successfully.  Return zero to indicate success, or -1 to
2395  *     indicate failure and abort FDICopy.
2396  *
2397  *     Upon receipt of this notification, the structure pointed to by pfdin will
2398  *     contain the following values: psz1 pointing to the name of the cabinet
2399  *     which FDICopy is attempting to open, psz2 pointing to the name ("info") of
2400  *     the next disk, psz3 pointing to the presumed file-location of the cabinet,
2401  *     and fdie containing either FDIERROR_NONE, or one of the following: 
2402  *
2403  *       FDIERROR_CABINET_NOT_FOUND, FDIERROR_NOT_A_CABINET,
2404  *       FDIERROR_UNKNOWN_CABINET_VERSION, FDIERROR_CORRUPT_CABINET,
2405  *       FDIERROR_BAD_COMPR_TYPE, FDIERROR_RESERVE_MISMATCH, and 
2406  *       FDIERROR_WRONG_CABINET.
2407  *
2408  *     The callee may choose to change the path where FDICopy will look for the
2409  *     cabinet after this notification.  To do so, the caller may write the new
2410  *     pathname to the buffer pointed to by psz3, which is 256 characters in
2411  *     length, including the terminating null character, before returning zero.
2412  *
2413  *   fdintENUMERATE:
2414  *
2415  *     Undocumented and unimplemented in wine, this seems to be sent each time
2416  *     a cabinet is opened, along with the fdintCABINET_INFO notification.  It
2417  *     probably has an interface similar to that of fdintCABINET_INFO; maybe this
2418  *     provides information about the current cabinet instead of the next one....
2419  *     this is just a guess, it has not been looked at closely.
2420  *
2421  * INCLUDES
2422  *   fdi.c
2423  */
2424 BOOL __cdecl FDICopy(
2425         HFDI           hfdi,
2426         char          *pszCabinet,
2427         char          *pszCabPath,
2428         int            flags,
2429         PFNFDINOTIFY   pfnfdin,
2430         PFNFDIDECRYPT  pfnfdid,
2431         void          *pvUser)
2432 { 
2433   FDICABINETINFO    fdici;
2434   FDINOTIFICATION   fdin;
2435   int               cabhf, filehf = 0, idx;
2436   unsigned int      i;
2437   char              fullpath[MAX_PATH];
2438   size_t            pathlen, filenamelen;
2439   char              emptystring = '\0';
2440   cab_UBYTE         buf[64];
2441   struct fdi_folder *fol = NULL, *linkfol = NULL; 
2442   struct fdi_file   *file = NULL, *linkfile = NULL;
2443   fdi_decomp_state _decomp_state;
2444   fdi_decomp_state *decomp_state = &_decomp_state;
2445 
2446   TRACE("(hfdi == ^%p, pszCabinet == ^%p, pszCabPath == ^%p, flags == %0d, "
2447         "pfnfdin == ^%p, pfnfdid == ^%p, pvUser == ^%p)\n",
2448         hfdi, pszCabinet, pszCabPath, flags, pfnfdin, pfnfdid, pvUser);
2449 
2450   if (!REALLY_IS_FDI(hfdi)) {
2451     SetLastError(ERROR_INVALID_HANDLE);
2452     return FALSE;
2453   }
2454 
2455   ZeroMemory(decomp_state, sizeof(fdi_decomp_state));
2456 
2457   pathlen = (pszCabPath) ? strlen(pszCabPath) : 0;
2458   filenamelen = (pszCabinet) ? strlen(pszCabinet) : 0;
2459 
2460   /* slight overestimation here to save CPU cycles in the developer's brain */
2461   if ((pathlen + filenamelen + 3) > MAX_PATH) {
2462     ERR("MAX_PATH exceeded.\n");
2463     PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CABINET_NOT_FOUND;
2464     PFDI_INT(hfdi)->perf->erfType = ERROR_FILE_NOT_FOUND;
2465     PFDI_INT(hfdi)->perf->fError = TRUE;
2466     SetLastError(ERROR_FILE_NOT_FOUND);
2467     return FALSE;
2468   }
2469 
2470   /* paste the path and filename together */
2471   idx = 0;
2472   if (pathlen) {
2473     for (i = 0; i < pathlen; i++) fullpath[idx++] = pszCabPath[i];
2474     if (fullpath[idx - 1] != '\\') fullpath[idx++] = '\\';
2475   }
2476   if (filenamelen) for (i = 0; i < filenamelen; i++) fullpath[idx++] = pszCabinet[i];
2477   fullpath[idx] = '\0';
2478 
2479   TRACE("full cab path/file name: %s\n", debugstr_a(fullpath));
2480 
2481   /* get a handle to the cabfile */
2482   cabhf = PFDI_OPEN(hfdi, fullpath, _O_RDONLY|_O_BINARY, _S_IREAD | _S_IWRITE);
2483   if (cabhf == -1) {
2484     PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CABINET_NOT_FOUND;
2485     PFDI_INT(hfdi)->perf->fError = TRUE;
2486     SetLastError(ERROR_FILE_NOT_FOUND);
2487     return FALSE;
2488   }
2489 
2490   if (cabhf == 0) {
2491     ERR("PFDI_OPEN returned zero for %s.\n", fullpath);
2492     PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CABINET_NOT_FOUND;
2493     PFDI_INT(hfdi)->perf->erfType = ERROR_FILE_NOT_FOUND;
2494     PFDI_INT(hfdi)->perf->fError = TRUE;
2495     SetLastError(ERROR_FILE_NOT_FOUND);
2496     return FALSE;
2497   }
2498 
2499   /* check if it's really a cabfile. Note that this doesn't implement the bug */
2500   if (!FDI_read_entries(hfdi, cabhf, &fdici, &(CAB(mii)))) {
2501     ERR("FDIIsCabinet failed.\n");
2502     PFDI_CLOSE(hfdi, cabhf);
2503     return FALSE;
2504   }
2505    
2506   /* cabinet notification */
2507   ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2508   fdin.setID = fdici.setID;
2509   fdin.iCabinet = fdici.iCabinet;
2510   fdin.pv = pvUser;
2511   fdin.psz1 = (CAB(mii).nextname) ? CAB(mii).nextname : &emptystring;
2512   fdin.psz2 = (CAB(mii).nextinfo) ? CAB(mii).nextinfo : &emptystring;
2513   fdin.psz3 = pszCabPath;
2514 
2515   if (((*pfnfdin)(fdintCABINET_INFO, &fdin))) {
2516     PFDI_INT(hfdi)->perf->erfOper = FDIERROR_USER_ABORT;
2517     PFDI_INT(hfdi)->perf->erfType = 0;
2518     PFDI_INT(hfdi)->perf->fError = TRUE;
2519     goto bail_and_fail;
2520   }
2521 
2522   CAB(setID) = fdici.setID;
2523   CAB(iCabinet) = fdici.iCabinet;
2524   CAB(cabhf) = cabhf;
2525 
2526   /* read folders */
2527   for (i = 0; i < fdici.cFolders; i++) {
2528     if (PFDI_READ(hfdi, cabhf, buf, cffold_SIZEOF) != cffold_SIZEOF) {
2529       PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
2530       PFDI_INT(hfdi)->perf->erfType = 0;
2531       PFDI_INT(hfdi)->perf->fError = TRUE;
2532       goto bail_and_fail;
2533     }
2534 
2535     if (CAB(mii).folder_resv > 0)
2536       PFDI_SEEK(hfdi, cabhf, CAB(mii).folder_resv, SEEK_CUR);
2537 
2538     fol = (struct fdi_folder *) PFDI_ALLOC(hfdi, sizeof(struct fdi_folder));
2539     if (!fol) {
2540       ERR("out of memory!\n");
2541       PFDI_INT(hfdi)->perf->erfOper = FDIERROR_ALLOC_FAIL;
2542       PFDI_INT(hfdi)->perf->erfType = ERROR_NOT_ENOUGH_MEMORY;
2543       PFDI_INT(hfdi)->perf->fError = TRUE;
2544       SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2545       goto bail_and_fail;
2546     }
2547     ZeroMemory(fol, sizeof(struct fdi_folder));
2548     if (!CAB(firstfol)) CAB(firstfol) = fol;
2549 
2550     fol->offset = (cab_off_t) EndGetI32(buf+cffold_DataOffset);
2551     fol->num_blocks = EndGetI16(buf+cffold_NumBlocks);
2552     fol->comp_type  = EndGetI16(buf+cffold_CompType);
2553 
2554     if (linkfol)
2555       linkfol->next = fol; 
2556     linkfol = fol;
2557   }
2558 
2559   /* read files */
2560   for (i = 0; i < fdici.cFiles; i++) {
2561     if (PFDI_READ(hfdi, cabhf, buf, cffile_SIZEOF) != cffile_SIZEOF) {
2562       PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
2563       PFDI_INT(hfdi)->perf->erfType = 0;
2564       PFDI_INT(hfdi)->perf->fError = TRUE;
2565       goto bail_and_fail;
2566     }
2567 
2568     file = (struct fdi_file *) PFDI_ALLOC(hfdi, sizeof(struct fdi_file));
2569     if (!file) { 
2570       ERR("out of memory!\n"); 
2571       PFDI_INT(hfdi)->perf->erfOper = FDIERROR_ALLOC_FAIL;
2572       PFDI_INT(hfdi)->perf->erfType = ERROR_NOT_ENOUGH_MEMORY;
2573       PFDI_INT(hfdi)->perf->fError = TRUE;
2574       SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2575       goto bail_and_fail;
2576     }
2577     ZeroMemory(file, sizeof(struct fdi_file));
2578     if (!CAB(firstfile)) CAB(firstfile) = file;
2579       
2580     file->length   = EndGetI32(buf+cffile_UncompressedSize);
2581     file->offset   = EndGetI32(buf+cffile_FolderOffset);
2582     file->index    = EndGetI16(buf+cffile_FolderIndex);
2583     file->time     = EndGetI16(buf+cffile_Time);
2584     file->date     = EndGetI16(buf+cffile_Date);
2585     file->attribs  = EndGetI16(buf+cffile_Attribs);
2586     file->filename = FDI_read_string(hfdi, cabhf, fdici.cbCabinet);
2587 
2588     if (!file->filename) {
2589       PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
2590       PFDI_INT(hfdi)->perf->erfType = 0;
2591       PFDI_INT(hfdi)->perf->fError = TRUE;
2592       goto bail_and_fail;
2593     }
2594 
2595     if (linkfile)
2596       linkfile->next = file;
2597     linkfile = file;
2598   }
2599 
2600   for (file = CAB(firstfile); (file); file = file->next) {
2601 
2602     /*
2603      * FIXME: This implementation keeps multiple cabinet files open at once
2604      * when encountering a split cabinet.  It is a quirk of this implementation
2605      * that sometimes we decrypt the same block of data more than once, to find
2606      * the right starting point for a file, moving the file-pointer backwards.
2607      * If we kept a cache of certain file-pointer information, we could eliminate
2608      * that behavior... in fact I am not sure that the caching we already have
2609      * is not sufficient.
2610      * 
2611      * The current implementation seems to work fine in straightforward situations
2612      * where all the cabinet files needed for decryption are simultaneously
2613      * available.  But presumably, the API is supposed to support cabinets which
2614      * are split across multiple CDROMS; we may need to change our implementation
2615      * to strictly serialize it's file usage so that it opens only one cabinet
2616      * at a time.  Some experimentation with Windows is needed to figure out the
2617      * precise semantics required.  The relevant code is here and in fdi_decomp().
2618      */
2619 
2620     /* partial-file notification */
2621     if ((file->index & cffileCONTINUED_FROM_PREV) == cffileCONTINUED_FROM_PREV) {
2622       /*
2623        * FIXME: Need to create a Cabinet with a single file spanning multiple files
2624        * and perform some tests to figure out the right behavior.  The SDK says
2625        * FDICopy will notify the user of the filename and "disk name" (info) of
2626        * the cabinet where the spanning file /started/.
2627        *
2628        * That would certainly be convenient for the API-user, who could abort,
2629        * everything (or parallelize, if that's allowed (it is in wine)), and call
2630        * FDICopy again with the provided filename, so as to avoid partial file
2631        * notification and successfully unpack.  This task could be quite unpleasant
2632        * from wine's perspective: the information specifying the "start cabinet" for
2633        * a file is associated nowhere with the file header and is not to be found in
2634        * the cabinet header.  We have only the index of the cabinet wherein the folder
2635        * begins, which contains the file.  To find that cabinet, we must consider the
2636        * index of the current cabinet, and chain backwards, cabinet-by-cabinet (for
2637        * each cabinet refers to its "next" and "previous" cabinet only, like a linked
2638        * list).
2639        *
2640        * Bear in mind that, in the spirit of CABINET.DLL, we must assume that any
2641        * cabinet other than the active one might be at another filepath than the
2642        * current one, or on another CDROM. This could get rather dicey, especially
2643        * if we imagine parallelized access to the FDICopy API.
2644        *
2645        * The current implementation punts -- it just returns the previous cabinet and
2646        * it's info from the header of this cabinet.  This provides the right answer in
2647        * 95% of the cases; its worth checking if Microsoft cuts the same corner before
2648        * we "fix" it.
2649        */
2650       ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2651       fdin.pv = pvUser;
2652       fdin.psz1 = (char *)file->filename;
2653       fdin.psz2 = (CAB(mii).prevname) ? CAB(mii).prevname : &emptystring;
2654       fdin.psz3 = (CAB(mii).previnfo) ? CAB(mii).previnfo : &emptystring;
2655 
2656       if (((*pfnfdin)(fdintPARTIAL_FILE, &fdin))) {
2657         PFDI_INT(hfdi)->perf->erfOper = FDIERROR_USER_ABORT;
2658         PFDI_INT(hfdi)->perf->erfType = 0;
2659         PFDI_INT(hfdi)->perf->fError = TRUE;
2660         goto bail_and_fail;
2661       }
2662       /* I don't think we are supposed to decompress partial files.  This prevents it. */
2663       file->oppressed = TRUE;
2664     }
2665     if (file->oppressed) {
2666       filehf = 0;
2667     } else {
2668       ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2669       fdin.pv = pvUser;
2670       fdin.psz1 = (char *)file->filename;
2671       fdin.cb = file->length;
2672       fdin.date = file->date;
2673       fdin.time = file->time;
2674       fdin.attribs = file->attribs;
2675       if ((filehf = ((*pfnfdin)(fdintCOPY_FILE, &fdin))) == -1) {
2676         PFDI_INT(hfdi)->perf->erfOper = FDIERROR_USER_ABORT;
2677         PFDI_INT(hfdi)->perf->erfType = 0;
2678         PFDI_INT(hfdi)->perf->fError = TRUE;
2679         filehf = 0;
2680         goto bail_and_fail;
2681       }
2682     }
2683 
2684     /* find the folder for this file if necc. */
2685     if (filehf) {
2686       int i2;
2687 
2688       fol = CAB(firstfol);
2689       if ((file->index & cffileCONTINUED_TO_NEXT) == cffileCONTINUED_TO_NEXT) {
2690         /* pick the last folder */
2691         while (fol->next) fol = fol->next;
2692       } else {
2693         for (i2 = 0; (i2 < file->index); i2++)
2694           if (fol->next) /* bug resistance, should always be true */
2695             fol = fol->next;
2696       }
2697     }
2698 
2699     if (filehf) {
2700       cab_UWORD comptype = fol->comp_type;
2701       int ct1 = comptype & cffoldCOMPTYPE_MASK;
2702       int ct2 = CAB(current) ? (CAB(current)->comp_type & cffoldCOMPTYPE_MASK) : 0;
2703       int err = 0;
2704 
2705       TRACE("Extracting file %s as requested by callee.\n", debugstr_a(file->filename));
2706 
2707       /* set up decomp_state */
2708       CAB(hfdi) = hfdi;
2709       CAB(filehf) = filehf;
2710 
2711       /* Was there a change of folder?  Compression type?  Did we somehow go backwards? */
2712       if ((ct1 != ct2) || (CAB(current) != fol) || (file->offset < CAB(offset))) {
2713 
2714         TRACE("Resetting folder for file %s.\n", debugstr_a(file->filename));
2715 
2716         /* free stuff for the old decompresser */
2717         switch (ct2) {
2718         case cffoldCOMPTYPE_LZX:
2719           if (LZX(window)) {
2720             PFDI_FREE(hfdi, LZX(window));
2721             LZX(window) = NULL;
2722           }
2723           break;
2724         case cffoldCOMPTYPE_QUANTUM:
2725           if (QTM(window)) {
2726             PFDI_FREE(hfdi, QTM(window));
2727             QTM(window) = NULL;
2728           }
2729           break;
2730         }
2731 
2732         CAB(decomp_cab) = NULL;
2733         PFDI_SEEK(CAB(hfdi), CAB(cabhf), fol->offset, SEEK_SET);
2734         CAB(offset) = 0;
2735         CAB(outlen) = 0;
2736 
2737         /* initialize the new decompresser */
2738         switch (ct1) {
2739         case cffoldCOMPTYPE_NONE:
2740           CAB(decompress) = NONEfdi_decomp;
2741           break;
2742         case cffoldCOMPTYPE_MSZIP:
2743           CAB(decompress) = ZIPfdi_decomp;
2744           break;
2745         case cffoldCOMPTYPE_QUANTUM:
2746           CAB(decompress) = QTMfdi_decomp;
2747           err = QTMfdi_init((comptype >> 8) & 0x1f, (comptype >> 4) & 0xF, decomp_state);
2748           break;
2749         case cffoldCOMPTYPE_LZX:
2750           CAB(decompress) = LZXfdi_decomp;
2751           err = LZXfdi_init((comptype >> 8) & 0x1f, decomp_state);
2752           break;
2753         default:
2754           err = DECR_DATAFORMAT;
2755         }
2756       }
2757 
2758       CAB(current) = fol;
2759 
2760       switch (err) {
2761         case DECR_OK:
2762           break;
2763         case DECR_NOMEMORY:
2764           PFDI_INT(hfdi)->perf->erfOper = FDIERROR_ALLOC_FAIL;
2765           PFDI_INT(hfdi)->perf->erfType = ERROR_NOT_ENOUGH_MEMORY;
2766           PFDI_INT(hfdi)->perf->fError = TRUE;
2767           SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2768           goto bail_and_fail;
2769         default:
2770           PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
2771           PFDI_INT(hfdi)->perf->erfOper = 0;
2772           PFDI_INT(hfdi)->perf->fError = TRUE;
2773           goto bail_and_fail;
2774       }
2775 
2776       if (file->offset > CAB(offset)) {
2777         /* decode bytes and send them to /dev/null */
2778         switch ((err = fdi_decomp(file, 0, decomp_state, pszCabPath, pfnfdin, pvUser))) {
2779           case DECR_OK:
2780             break;
2781           case DECR_USERABORT:
2782             PFDI_INT(hfdi)->perf->erfOper = FDIERROR_USER_ABORT;
2783             PFDI_INT(hfdi)->perf->erfType = 0;
2784             PFDI_INT(hfdi)->perf->fError = TRUE;
2785             goto bail_and_fail;
2786           case DECR_NOMEMORY:
2787             PFDI_INT(hfdi)->perf->erfOper = FDIERROR_ALLOC_FAIL;
2788             PFDI_INT(hfdi)->perf->erfType = ERROR_NOT_ENOUGH_MEMORY;
2789             PFDI_INT(hfdi)->perf->fError = TRUE;
2790             SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2791             goto bail_and_fail;
2792           default:
2793             PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
2794             PFDI_INT(hfdi)->perf->erfOper = 0;
2795             PFDI_INT(hfdi)->perf->fError = TRUE;
2796             goto bail_and_fail;
2797         }
2798         CAB(offset) = file->offset;
2799       }
2800 
2801       /* now do the actual decompression */
2802       err = fdi_decomp(file, 1, decomp_state, pszCabPath, pfnfdin, pvUser);
2803       if (err) CAB(current) = NULL; else CAB(offset) += file->length;
2804 
2805       /* fdintCLOSE_FILE_INFO notification */
2806       ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2807       fdin.pv = pvUser;
2808       fdin.psz1 = (char *)file->filename;
2809       fdin.hf = filehf;
2810       fdin.cb = (file->attribs & cffile_A_EXEC) ? TRUE : FALSE; /* FIXME: is that right? */
2811       fdin.date = file->date;
2812       fdin.time = file->time;
2813       fdin.attribs = file->attribs; /* FIXME: filter _A_EXEC? */
2814       ((*pfnfdin)(fdintCLOSE_FILE_INFO, &fdin));
2815       filehf = 0;
2816 
2817       switch (err) {
2818         case DECR_OK:
2819           break;
2820         case DECR_USERABORT:
2821           PFDI_INT(hfdi)->perf->erfOper = FDIERROR_USER_ABORT;
2822           PFDI_INT(hfdi)->perf->erfType = 0;
2823           PFDI_INT(hfdi)->perf->fError = TRUE;
2824           goto bail_and_fail;
2825         case DECR_NOMEMORY:
2826           PFDI_INT(hfdi)->perf->erfOper = FDIERROR_ALLOC_FAIL;
2827           PFDI_INT(hfdi)->perf->erfType = ERROR_NOT_ENOUGH_MEMORY;
2828           PFDI_INT(hfdi)->perf->fError = TRUE;
2829           SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2830           goto bail_and_fail;
2831         default:
2832           PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
2833           PFDI_INT(hfdi)->perf->erfOper = 0;
2834           PFDI_INT(hfdi)->perf->fError = TRUE;
2835           goto bail_and_fail;
2836       }
2837     }
2838   }
2839 
2840   /* free decompression temps */
2841   switch (fol->comp_type & cffoldCOMPTYPE_MASK) {
2842   case cffoldCOMPTYPE_LZX:
2843     if (LZX(window)) {
2844       PFDI_FREE(hfdi, LZX(window));
2845       LZX(window) = NULL;
2846     }
2847     break;
2848   case cffoldCOMPTYPE_QUANTUM:
2849     if (QTM(window)) {
2850       PFDI_FREE(hfdi, QTM(window));
2851       QTM(window) = NULL;
2852     }
2853     break;
2854   }
2855 
2856   while (decomp_state) {
2857     fdi_decomp_state *prev_fds;
2858 
2859     PFDI_CLOSE(hfdi, CAB(cabhf));
2860 
2861     /* free the storage remembered by mii */
2862     if (CAB(mii).nextname) PFDI_FREE(hfdi, CAB(mii).nextname);
2863     if (CAB(mii).nextinfo) PFDI_FREE(hfdi, CAB(mii).nextinfo);
2864     if (CAB(mii).prevname) PFDI_FREE(hfdi, CAB(mii).prevname);
2865     if (CAB(mii).previnfo) PFDI_FREE(hfdi, CAB(mii).previnfo);
2866 
2867     while (CAB(firstfol)) {
2868       fol = CAB(firstfol);
2869       CAB(firstfol) = CAB(firstfol)->next;
2870       PFDI_FREE(hfdi, fol);
2871     }
2872     while (CAB(firstfile)) {
2873       file = CAB(firstfile);
2874       if (file->filename) PFDI_FREE(hfdi, (void *)file->filename);
2875       CAB(firstfile) = CAB(firstfile)->next;
2876       PFDI_FREE(hfdi, file);
2877     }
2878     prev_fds = decomp_state;
2879     decomp_state = CAB(next);
2880     if (prev_fds != &_decomp_state)
2881       PFDI_FREE(hfdi, prev_fds);
2882   }
2883  
2884   return TRUE;
2885 
2886   bail_and_fail: /* here we free ram before error returns */
2887 
2888   /* free decompression temps */
2889   switch (fol->comp_type & cffoldCOMPTYPE_MASK) {
2890   case cffoldCOMPTYPE_LZX:
2891     if (LZX(window)) {
2892       PFDI_FREE(hfdi, LZX(window));
2893       LZX(window) = NULL;
2894     }
2895     break;
2896   case cffoldCOMPTYPE_QUANTUM:
2897     if (QTM(window)) {
2898       PFDI_FREE(hfdi, QTM(window));
2899       QTM(window) = NULL;
2900     }
2901     break;
2902   }
2903 
2904   if (filehf) PFDI_CLOSE(hfdi, filehf);
2905 
2906   while (decomp_state) {
2907     fdi_decomp_state *prev_fds;
2908 
2909     PFDI_CLOSE(hfdi, CAB(cabhf));
2910 
2911     /* free the storage remembered by mii */
2912     if (CAB(mii).nextname) PFDI_FREE(hfdi, CAB(mii).nextname);
2913     if (CAB(mii).nextinfo) PFDI_FREE(hfdi, CAB(mii).nextinfo);
2914     if (CAB(mii).prevname) PFDI_FREE(hfdi, CAB(mii).prevname);
2915     if (CAB(mii).previnfo) PFDI_FREE(hfdi, CAB(mii).previnfo);
2916 
2917     while (CAB(firstfol)) {
2918       fol = CAB(firstfol);
2919       CAB(firstfol) = CAB(firstfol)->next;
2920       PFDI_FREE(hfdi, fol);
2921     }
2922     while (CAB(firstfile)) {
2923       file = CAB(firstfile);
2924       if (file->filename) PFDI_FREE(hfdi, (void *)file->filename);
2925       CAB(firstfile) = CAB(firstfile)->next;
2926       PFDI_FREE(hfdi, file);
2927     }
2928     prev_fds = decomp_state;
2929     decomp_state = CAB(next);
2930     if (prev_fds != &_decomp_state)
2931       PFDI_FREE(hfdi, prev_fds);
2932   }
2933 
2934   return FALSE;
2935 }
2936 
2937 /***********************************************************************
2938  *              FDIDestroy (CABINET.23)
2939  *
2940  * Frees a handle created by FDICreate.  Do /not/ call this in the middle
2941  * of FDICopy.  Only reason for failure would be an invalid handle.
2942  * 
2943  * PARAMS
2944  *   hfdi [I] The HFDI to free
2945  *
2946  * RETURNS
2947  *   TRUE for success
2948  *   FALSE for failure
2949  */
2950 BOOL __cdecl FDIDestroy(HFDI hfdi)
2951 {
2952   TRACE("(hfdi == ^%p)\n", hfdi);
2953   if (REALLY_IS_FDI(hfdi)) {
2954     PFDI_INT(hfdi)->FDI_Intmagic = 0; /* paranoia */
2955     PFDI_FREE(hfdi, hfdi); /* confusing, but correct */
2956     return TRUE;
2957   } else {
2958     SetLastError(ERROR_INVALID_HANDLE);
2959     return FALSE;
2960   }
2961 }
2962 
2963 /***********************************************************************
2964  *              FDITruncateCabinet (CABINET.24)
2965  *
2966  * Removes all folders of a cabinet file after and including the
2967  * specified folder number.
2968  * 
2969  * PARAMS
2970  *   hfdi            [I] Handle to the FDI context.
2971  *   pszCabinetName  [I] Filename of the cabinet.
2972  *   iFolderToDelete [I] Index of the first folder to delete.
2973  * 
2974  * RETURNS
2975  *   Success: TRUE.
2976  *   Failure: FALSE.
2977  * 
2978  * NOTES
2979  *   The PFNWRITE function supplied to FDICreate must truncate the
2980  *   file at the current position if the number of bytes to write is 0.
2981  */
2982 BOOL __cdecl FDITruncateCabinet(
2983         HFDI    hfdi,
2984         char   *pszCabinetName,
2985         USHORT  iFolderToDelete)
2986 {
2987   FIXME("(hfdi == ^%p, pszCabinetName == %s, iFolderToDelete == %hu): stub\n",
2988     hfdi, debugstr_a(pszCabinetName), iFolderToDelete);
2989 
2990   if (!REALLY_IS_FDI(hfdi)) {
2991     SetLastError(ERROR_INVALID_HANDLE);
2992     return FALSE;
2993   }
2994 
2995   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2996   return FALSE;
2997 }
2998 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.