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