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