Stubs for BuildTrusteeWithSid(A/W).
[wine] / dlls / cabinet / cabextract.c
1 /*
2  * cabextract.c
3  *
4  * Copyright 2000-2002 Stuart Caie
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * Principal author: Stuart Caie <kyzer@4u.net>
21  *
22  * Based on specification documents from Microsoft Corporation
23  * Quantum decompression researched and implemented by Matthew Russoto
24  * Huffman code adapted from unlzx by Dave Tritscher.
25  * InfoZip team's INFLATE implementation adapted to MSZIP by Dirk Stoecker.
26  * Major LZX fixes by Jae Jung.
27  */
28  
29 #include "config.h"
30
31 #include <stdlib.h>
32
33 #include "windef.h"
34 #include "winbase.h"
35 #include "winerror.h"
36
37 #include "cabinet.h"
38
39 #include "wine/debug.h"
40
41 WINE_DEFAULT_DEBUG_CHANNEL(cabinet);
42
43 THOSE_ZIP_CONSTS;
44
45 /* all the file IO is abstracted into these routines:
46  * cabinet_(open|close|read|seek|skip|getoffset)
47  * file_(open|close|write)
48  */
49
50 /* try to open a cabinet file, returns success */
51 BOOL cabinet_open(struct cabinet *cab)
52 {
53   char *name = (char *)cab->filename;
54   HANDLE fh;
55
56   TRACE("(cab == ^%p)\n", cab);
57
58   if ((fh = CreateFileA( name, GENERIC_READ, FILE_SHARE_READ,
59               NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL )) == INVALID_HANDLE_VALUE) {
60     ERR("Couldn't open %s\n", debugstr_a(name));
61     return FALSE;
62   }
63
64   /* seek to end of file and get the length */
65   if ((cab->filelen = SetFilePointer(fh, 0, NULL, FILE_END)) == INVALID_SET_FILE_POINTER) {
66     if (GetLastError() != NO_ERROR) {
67       ERR("Seek END failed: %s", debugstr_a(name));
68       CloseHandle(fh);
69       return FALSE;
70     }
71   }
72
73   /* return to the start of the file */
74   if (SetFilePointer(fh, 0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
75     ERR("Seek BEGIN failed: %s", debugstr_a(name));
76     CloseHandle(fh);
77     return FALSE;
78   }
79
80   cab->fh = fh;
81   return TRUE;
82 }
83
84 /*******************************************************************
85  * cabinet_close (internal)
86  *
87  * close the file handle in a struct cabinet.
88  */
89 void cabinet_close(struct cabinet *cab) {
90   TRACE("(cab == ^%p)\n", cab);
91   if (cab->fh) CloseHandle(cab->fh);
92   cab->fh = 0;
93 }
94
95 /*******************************************************
96  * ensure_filepath2 (internal)
97  */
98 BOOL ensure_filepath2(char *path) {
99   BOOL ret = TRUE;
100   int len;
101   char *new_path;
102
103   new_path = HeapAlloc(GetProcessHeap(), 0, (strlen(path) + 1));
104   strcpy(new_path, path);
105
106   while((len = strlen(new_path)) && new_path[len - 1] == '\\')
107     new_path[len - 1] = 0;
108
109   TRACE("About to try to create directory %s\n", debugstr_a(new_path));
110   while(!CreateDirectoryA(new_path, NULL)) {
111     char *slash;
112     DWORD last_error = GetLastError();
113
114     if(last_error == ERROR_ALREADY_EXISTS)
115       break;
116
117     if(last_error != ERROR_PATH_NOT_FOUND) {
118       ret = FALSE;
119       break;
120     }
121
122     if(!(slash = strrchr(new_path, '\\'))) {
123       ret = FALSE;
124       break;
125     }
126
127     len = slash - new_path;
128     new_path[len] = 0;
129     if(! ensure_filepath2(new_path)) {
130       ret = FALSE;
131       break;
132     }
133     new_path[len] = '\\';
134     TRACE("New path in next iteration: %s\n", debugstr_a(new_path));
135   }
136
137   HeapFree(GetProcessHeap(), 0, new_path);
138   return ret;
139 }
140
141
142 /**********************************************************************
143  * ensure_filepath (internal)
144  *
145  * ensure_filepath("a\b\c\d.txt") ensures a, a\b and a\b\c exist as dirs
146  */
147 BOOL ensure_filepath(char *path) {
148   char new_path[MAX_PATH];
149   int len, i, lastslashpos = -1;
150
151   TRACE("(path == %s)\n", debugstr_a(path));
152
153   strcpy(new_path, path); 
154   /* remove trailing slashes (shouldn't need to but wth...) */
155   while ((len = strlen(new_path)) && new_path[len - 1] == '\\')
156     new_path[len - 1] = 0;
157   /* find the position of the last '\\' */
158   for (i=0; i<MAX_PATH; i++) {
159     if (new_path[i] == 0) break; 
160     if (new_path[i] == '\\')
161       lastslashpos = i;
162   }
163   if (lastslashpos > 0) {
164     new_path[lastslashpos] = 0;
165     /* may be trailing slashes but ensure_filepath2 will chop them */
166     return ensure_filepath2(new_path);
167   } else
168     return TRUE; /* ? */
169 }
170
171 /*******************************************************************
172  * file_open (internal)
173  *
174  * opens a file for output, returns success
175  */
176 BOOL file_open(struct cab_file *fi, BOOL lower, LPCSTR dir)
177 {
178   char c, *s, *d, *name;
179   BOOL ok = FALSE;
180
181   TRACE("(fi == ^%p, lower == %s, dir == %s)\n", fi, lower ? "TRUE" : "FALSE", debugstr_a(dir));
182
183   if (!(name = malloc(strlen(fi->filename) + (dir ? strlen(dir) : 0) + 2))) {
184     ERR("out of memory!\n");
185     return FALSE;
186   }
187   
188   /* start with blank name */
189   *name = 0;
190
191   /* add output directory if needed */
192   if (dir) {
193     strcpy(name, dir);
194     strcat(name, "\\");
195   }
196
197   /* remove leading slashes */
198   s = (char *) fi->filename;
199   while (*s == '\\') s++;
200
201   /* copy from fi->filename to new name.
202    * lowercases characters if needed.
203    */
204   d = &name[strlen(name)];
205   do {
206     c = *s++;
207     *d++ = (lower ? tolower((unsigned char) c) : c);
208   } while (c);
209
210   /* create directories if needed, attempt to write file */
211   if (ensure_filepath(name)) {
212     fi->fh = CreateFileA(name, GENERIC_WRITE, 0, NULL,
213                          CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
214     if (fi->fh != INVALID_HANDLE_VALUE)
215       ok = TRUE;
216     else {
217       ERR("CreateFileA returned INVALID_HANDLE_VALUE\n");
218       fi->fh = 0;
219     }
220   } else 
221     ERR("Couldn't ensure filepath for %s", debugstr_a(name));
222
223   if (!ok) {
224     ERR("Couldn't open file %s for writing\n", debugstr_a(name));
225   }
226
227   /* as full filename is no longer needed, free it */
228   free(name);
229
230   return ok;
231 }
232
233 /********************************************************
234  * close_file (internal)
235  *
236  * closes a completed file
237  */
238 void file_close(struct cab_file *fi)
239 {
240   TRACE("(fi == ^%p)\n", fi);
241
242   if (fi->fh) {
243     CloseHandle(fi->fh);
244   }
245   fi->fh = 0;
246 }
247
248 /******************************************************************
249  * file_write (internal)
250  *
251  * writes from buf to a file specified as a cab_file struct.
252  * returns success/failure
253  */
254 BOOL file_write(struct cab_file *fi, cab_UBYTE *buf, cab_off_t length)
255 {
256   DWORD bytes_written;
257
258   TRACE("(fi == ^%p, buf == ^%p, length == %u)\n", fi, buf, length);
259
260   if ((!WriteFile( fi->fh, (LPCVOID) buf, length, &bytes_written, FALSE) ||
261       (bytes_written != length))) {
262     ERR("Error writing file: %s\n", debugstr_a(fi->filename));
263     return FALSE;
264   }
265   return TRUE;
266 }
267
268
269 /*******************************************************************
270  * cabinet_skip (internal)
271  *
272  * advance the file pointer associated with the cab structure
273  * by distance bytes
274  */
275 void cabinet_skip(struct cabinet *cab, cab_off_t distance)
276 {
277   TRACE("(cab == ^%p, distance == %u)\n", cab, distance);
278   if (SetFilePointer(cab->fh, distance, NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER) {
279     if (distance != INVALID_SET_FILE_POINTER)
280       ERR("%s", debugstr_a((char *) cab->filename));
281   }
282 }
283
284 /*******************************************************************
285  * cabinet_seek (internal)
286  *
287  * seek to the specified absolute offset in a cab
288  */
289 void cabinet_seek(struct cabinet *cab, cab_off_t offset) {
290   TRACE("(cab == ^%p, offset == %u)\n", cab, offset);
291   if (SetFilePointer(cab->fh, offset, NULL, FILE_BEGIN) != offset)
292     ERR("%s seek failure\n", debugstr_a((char *)cab->filename));
293 }
294
295 /*******************************************************************
296  * cabinet_getoffset (internal)
297  *
298  * returns the file pointer position of a cab
299  */
300 cab_off_t cabinet_getoffset(struct cabinet *cab) 
301 {
302   return SetFilePointer(cab->fh, 0, NULL, FILE_CURRENT);
303 }
304
305 /*******************************************************************
306  * cabinet_read (internal)
307  *
308  * read data from a cabinet, returns success
309  */
310 BOOL cabinet_read(struct cabinet *cab, cab_UBYTE *buf, cab_off_t length)
311 {
312   DWORD bytes_read;
313   cab_off_t avail = cab->filelen - cabinet_getoffset(cab);
314
315   TRACE("(cab == ^%p, buf == ^%p, length == %u)\n", cab, buf, length);
316
317   if (length > avail) {
318     WARN("%s: WARNING; cabinet is truncated\n", debugstr_a((char *)cab->filename));
319     length = avail;
320   }
321
322   if (! ReadFile( cab->fh, (LPVOID) buf, length, &bytes_read, NULL )) {
323     ERR("%s read error\n", debugstr_a((char *) cab->filename));
324     return FALSE;
325   } else if (bytes_read != length) {
326     ERR("%s read size mismatch\n", debugstr_a((char *) cab->filename));
327     return FALSE;
328   }
329
330   return TRUE;
331 }
332
333 /**********************************************************************
334  * cabinet_read_string (internal)
335  *
336  * allocate and read an aribitrarily long string from the cabinet
337  */
338 char *cabinet_read_string(struct cabinet *cab)
339 {
340   cab_off_t len=256, base = cabinet_getoffset(cab), maxlen = cab->filelen - base;
341   BOOL ok = FALSE;
342   int i;
343   cab_UBYTE *buf = NULL;
344
345   TRACE("(cab == ^%p)\n", cab);
346
347   do {
348     if (len > maxlen) len = maxlen;
349     if (!(buf = realloc(buf, (size_t) len))) break;
350     if (!cabinet_read(cab, buf, (size_t) len)) break;
351
352     /* search for a null terminator in what we've just read */
353     for (i=0; i < len; i++) {
354       if (!buf[i]) {ok=TRUE; break;}
355     }
356
357     if (!ok) {
358       if (len == maxlen) {
359         ERR("%s: WARNING; cabinet is truncated\n", debugstr_a((char *) cab->filename));
360         break;
361       }
362       len += 256;
363       cabinet_seek(cab, base);
364     }
365   } while (!ok);
366
367   if (!ok) {
368     if (buf)
369       free(buf);
370     else
371       ERR("out of memory!\n");
372     return NULL;
373   }
374
375   /* otherwise, set the stream to just after the string and return */
376   cabinet_seek(cab, base + ((cab_off_t) strlen((char *) buf)) + 1);
377
378   return (char *) buf;
379 }
380
381 /******************************************************************
382  * cabinet_read_entries (internal)
383  *
384  * reads the header and all folder and file entries in this cabinet
385  */
386 BOOL cabinet_read_entries(struct cabinet *cab)
387 {
388   int num_folders, num_files, header_resv, folder_resv = 0, i;
389   struct cab_folder *fol, *linkfol = NULL;
390   struct cab_file *file, *linkfile = NULL;
391   cab_off_t base_offset;
392   cab_UBYTE buf[64];
393
394   TRACE("(cab == ^%p)\n", cab);
395
396   /* read in the CFHEADER */
397   base_offset = cabinet_getoffset(cab);
398   if (!cabinet_read(cab, buf, cfhead_SIZEOF)) {
399     return FALSE;
400   }
401   
402   /* check basic MSCF signature */
403   if (EndGetI32(buf+cfhead_Signature) != 0x4643534d) {
404     ERR("%s: not a Microsoft cabinet file\n", debugstr_a((char *) cab->filename));
405     return FALSE;
406   }
407
408   /* get the number of folders */
409   num_folders = EndGetI16(buf+cfhead_NumFolders);
410   if (num_folders == 0) {
411     ERR("%s: no folders in cabinet\n", debugstr_a((char *) cab->filename));
412     return FALSE;
413   }
414
415   /* get the number of files */
416   num_files = EndGetI16(buf+cfhead_NumFiles);
417   if (num_files == 0) {
418     ERR("%s: no files in cabinet\n", debugstr_a((char *) cab->filename));
419     return FALSE;
420   }
421
422   /* just check the header revision */
423   if ((buf[cfhead_MajorVersion] > 1) ||
424       (buf[cfhead_MajorVersion] == 1 && buf[cfhead_MinorVersion] > 3))
425   {
426     WARN("%s: WARNING; cabinet format version > 1.3\n", debugstr_a((char *) cab->filename));
427   }
428
429   /* read the reserved-sizes part of header, if present */
430   cab->flags = EndGetI16(buf+cfhead_Flags);
431   if (cab->flags & cfheadRESERVE_PRESENT) {
432     if (!cabinet_read(cab, buf, cfheadext_SIZEOF)) return FALSE;
433     header_resv     = EndGetI16(buf+cfheadext_HeaderReserved);
434     folder_resv     = buf[cfheadext_FolderReserved];
435     cab->block_resv = buf[cfheadext_DataReserved];
436
437     if (header_resv > 60000) {
438       WARN("%s: WARNING; header reserved space > 60000\n", debugstr_a((char *) cab->filename));
439     }
440
441     /* skip the reserved header */
442     if (header_resv) 
443       if (SetFilePointer(cab->fh, (cab_off_t) header_resv, NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER)
444         ERR("seek failure: %s\n", debugstr_a((char *) cab->filename));
445   }
446
447   if (cab->flags & cfheadPREV_CABINET) {
448     cab->prevname = cabinet_read_string(cab);
449     if (!cab->prevname) return FALSE;
450     cab->previnfo = cabinet_read_string(cab);
451   }
452
453   if (cab->flags & cfheadNEXT_CABINET) {
454     cab->nextname = cabinet_read_string(cab);
455     if (!cab->nextname) return FALSE;
456     cab->nextinfo = cabinet_read_string(cab);
457   }
458
459   /* read folders */
460   for (i = 0; i < num_folders; i++) {
461     if (!cabinet_read(cab, buf, cffold_SIZEOF)) return FALSE;
462     if (folder_resv) cabinet_skip(cab, folder_resv);
463
464     fol = (struct cab_folder *) calloc(1, sizeof(struct cab_folder));
465     if (!fol) {
466       ERR("out of memory!\n");
467       return FALSE;
468     }
469
470     fol->cab[0]     = cab;
471     fol->offset[0]  = base_offset + (cab_off_t) EndGetI32(buf+cffold_DataOffset);
472     fol->num_blocks = EndGetI16(buf+cffold_NumBlocks);
473     fol->comp_type  = EndGetI16(buf+cffold_CompType);
474
475     if (!linkfol) 
476       cab->folders = fol; 
477     else 
478       linkfol->next = fol;
479
480     linkfol = fol;
481   }
482
483   /* read files */
484   for (i = 0; i < num_files; i++) {
485     if (!cabinet_read(cab, buf, cffile_SIZEOF))
486       return FALSE;
487
488     file = (struct cab_file *) calloc(1, sizeof(struct cab_file));
489     if (!file) { 
490       ERR("out of memory!\n"); 
491       return FALSE;
492     }
493       
494     file->length   = EndGetI32(buf+cffile_UncompressedSize);
495     file->offset   = EndGetI32(buf+cffile_FolderOffset);
496     file->index    = EndGetI16(buf+cffile_FolderIndex);
497     file->time     = EndGetI16(buf+cffile_Time);
498     file->date     = EndGetI16(buf+cffile_Date);
499     file->attribs  = EndGetI16(buf+cffile_Attribs);
500     file->filename = cabinet_read_string(cab);
501
502     if (!file->filename) {
503       free(file);
504       return FALSE;
505     }
506
507     if (!linkfile) 
508       cab->files = file;
509     else 
510       linkfile->next = file;
511
512     linkfile = file;
513   }
514   return TRUE;
515 }
516
517 /***********************************************************
518  * load_cab_offset (internal)
519  *
520  * validates and reads file entries from a cabinet at offset [offset] in
521  * file [name]. Returns a cabinet structure if successful, or NULL
522  * otherwise.
523  */
524 struct cabinet *load_cab_offset(LPCSTR name, cab_off_t offset)
525 {
526   struct cabinet *cab = (struct cabinet *) calloc(1, sizeof(struct cabinet));
527   int ok;
528
529   TRACE("(name == %s, offset == %u)\n", debugstr_a((char *) name), offset);
530
531   if (!cab) return NULL;
532
533   cab->filename = name;
534   if ((ok = cabinet_open(cab))) {
535     cabinet_seek(cab, offset);
536     ok = cabinet_read_entries(cab);
537     cabinet_close(cab);
538   }
539
540   if (ok) return cab;
541   free(cab);
542   return NULL;
543 }
544
545 /* MSZIP decruncher */
546
547 /* Dirk Stoecker wrote the ZIP decoder, based on the InfoZip deflate code */
548
549 /********************************************************
550  * Ziphuft_free (internal)
551  */
552 void Ziphuft_free(struct Ziphuft *t)
553 {
554   register struct Ziphuft *p, *q;
555
556   /* Go through linked list, freeing from the allocated (t[-1]) address. */
557   p = t;
558   while (p != (struct Ziphuft *)NULL)
559   {
560     q = (--p)->v.t;
561     free(p);
562     p = q;
563   } 
564 }
565
566 /*********************************************************
567  * Ziphuft_build (internal)
568  */
569 cab_LONG Ziphuft_build(cab_ULONG *b, cab_ULONG n, cab_ULONG s, cab_UWORD *d, cab_UWORD *e,
570 struct Ziphuft **t, cab_LONG *m, cab_decomp_state *decomp_state)
571 {
572   cab_ULONG a;                          /* counter for codes of length k */
573   cab_ULONG el;                         /* length of EOB code (value 256) */
574   cab_ULONG f;                          /* i repeats in table every f entries */
575   cab_LONG g;                           /* maximum code length */
576   cab_LONG h;                           /* table level */
577   register cab_ULONG i;                 /* counter, current code */
578   register cab_ULONG j;                 /* counter */
579   register cab_LONG k;                  /* number of bits in current code */
580   cab_LONG *l;                          /* stack of bits per table */
581   register cab_ULONG *p;                /* pointer into ZIP(c)[],ZIP(b)[],ZIP(v)[] */
582   register struct Ziphuft *q;           /* points to current table */
583   struct Ziphuft r;                     /* table entry for structure assignment */
584   register cab_LONG w;                  /* bits before this table == (l * h) */
585   cab_ULONG *xp;                        /* pointer into x */
586   cab_LONG y;                           /* number of dummy codes added */
587   cab_ULONG z;                          /* number of entries in current table */
588
589   l = ZIP(lx)+1;
590
591   /* Generate counts for each bit length */
592   el = n > 256 ? b[256] : ZIPBMAX; /* set length of EOB code, if any */
593
594   for(i = 0; i < ZIPBMAX+1; ++i)
595     ZIP(c)[i] = 0;
596   p = b;  i = n;
597   do
598   {
599     ZIP(c)[*p]++; p++;               /* assume all entries <= ZIPBMAX */
600   } while (--i);
601   if (ZIP(c)[0] == n)                /* null input--all zero length codes */
602   {
603     *t = (struct Ziphuft *)NULL;
604     *m = 0;
605     return 0;
606   }
607
608   /* Find minimum and maximum length, bound *m by those */
609   for (j = 1; j <= ZIPBMAX; j++)
610     if (ZIP(c)[j])
611       break;
612   k = j;                        /* minimum code length */
613   if ((cab_ULONG)*m < j)
614     *m = j;
615   for (i = ZIPBMAX; i; i--)
616     if (ZIP(c)[i])
617       break;
618   g = i;                        /* maximum code length */
619   if ((cab_ULONG)*m > i)
620     *m = i;
621
622   /* Adjust last length count to fill out codes, if needed */
623   for (y = 1 << j; j < i; j++, y <<= 1)
624     if ((y -= ZIP(c)[j]) < 0)
625       return 2;                 /* bad input: more codes than bits */
626   if ((y -= ZIP(c)[i]) < 0)
627     return 2;
628   ZIP(c)[i] += y;
629
630   /* Generate starting offsets LONGo the value table for each length */
631   ZIP(x)[1] = j = 0;
632   p = ZIP(c) + 1;  xp = ZIP(x) + 2;
633   while (--i)
634   {                 /* note that i == g from above */
635     *xp++ = (j += *p++);
636   }
637
638   /* Make a table of values in order of bit lengths */
639   p = b;  i = 0;
640   do{
641     if ((j = *p++) != 0)
642       ZIP(v)[ZIP(x)[j]++] = i;
643   } while (++i < n);
644
645
646   /* Generate the Huffman codes and for each, make the table entries */
647   ZIP(x)[0] = i = 0;                 /* first Huffman code is zero */
648   p = ZIP(v);                        /* grab values in bit order */
649   h = -1;                       /* no tables yet--level -1 */
650   w = l[-1] = 0;                /* no bits decoded yet */
651   ZIP(u)[0] = (struct Ziphuft *)NULL;   /* just to keep compilers happy */
652   q = (struct Ziphuft *)NULL;      /* ditto */
653   z = 0;                        /* ditto */
654
655   /* go through the bit lengths (k already is bits in shortest code) */
656   for (; k <= g; k++)
657   {
658     a = ZIP(c)[k];
659     while (a--)
660     {
661       /* here i is the Huffman code of length k bits for value *p */
662       /* make tables up to required level */
663       while (k > w + l[h])
664       {
665         w += l[h++];            /* add bits already decoded */
666
667         /* compute minimum size table less than or equal to *m bits */
668         z = (z = g - w) > (cab_ULONG)*m ? *m : z;        /* upper limit */
669         if ((f = 1 << (j = k - w)) > a + 1)     /* try a k-w bit table */
670         {                       /* too few codes for k-w bit table */
671           f -= a + 1;           /* deduct codes from patterns left */
672           xp = ZIP(c) + k;
673           while (++j < z)       /* try smaller tables up to z bits */
674           {
675             if ((f <<= 1) <= *++xp)
676               break;            /* enough codes to use up j bits */
677             f -= *xp;           /* else deduct codes from patterns */
678           }
679         }
680         if ((cab_ULONG)w + j > el && (cab_ULONG)w < el)
681           j = el - w;           /* make EOB code end at table */
682         z = 1 << j;             /* table entries for j-bit table */
683         l[h] = j;               /* set table size in stack */
684
685         /* allocate and link in new table */
686         if (!(q = (struct Ziphuft *) malloc((z + 1)*sizeof(struct Ziphuft))))
687         {
688           if(h)
689             Ziphuft_free(ZIP(u)[0]);
690           return 3;             /* not enough memory */
691         }
692         *t = q + 1;             /* link to list for Ziphuft_free() */
693         *(t = &(q->v.t)) = (struct Ziphuft *)NULL;
694         ZIP(u)[h] = ++q;             /* table starts after link */
695
696         /* connect to last table, if there is one */
697         if (h)
698         {
699           ZIP(x)[h] = i;              /* save pattern for backing up */
700           r.b = (cab_UBYTE)l[h-1];    /* bits to dump before this table */
701           r.e = (cab_UBYTE)(16 + j);  /* bits in this table */
702           r.v.t = q;                  /* pointer to this table */
703           j = (i & ((1 << w) - 1)) >> (w - l[h-1]);
704           ZIP(u)[h-1][j] = r;        /* connect to last table */
705         }
706       }
707
708       /* set up table entry in r */
709       r.b = (cab_UBYTE)(k - w);
710       if (p >= ZIP(v) + n)
711         r.e = 99;               /* out of values--invalid code */
712       else if (*p < s)
713       {
714         r.e = (cab_UBYTE)(*p < 256 ? 16 : 15);    /* 256 is end-of-block code */
715         r.v.n = *p++;           /* simple code is just the value */
716       }
717       else
718       {
719         r.e = (cab_UBYTE)e[*p - s];   /* non-simple--look up in lists */
720         r.v.n = d[*p++ - s];
721       }
722
723       /* fill code-like entries with r */
724       f = 1 << (k - w);
725       for (j = i >> w; j < z; j += f)
726         q[j] = r;
727
728       /* backwards increment the k-bit code i */
729       for (j = 1 << (k - 1); i & j; j >>= 1)
730         i ^= j;
731       i ^= j;
732
733       /* backup over finished tables */
734       while ((i & ((1 << w) - 1)) != ZIP(x)[h])
735         w -= l[--h];            /* don't need to update q */
736     }
737   }
738
739   /* return actual size of base table */
740   *m = l[0];
741
742   /* Return true (1) if we were given an incomplete table */
743   return y != 0 && g != 1;
744 }
745
746 /*********************************************************
747  * Zipinflate_codes (internal)
748  */
749 cab_LONG Zipinflate_codes(struct Ziphuft *tl, struct Ziphuft *td,
750   cab_LONG bl, cab_LONG bd, cab_decomp_state *decomp_state)
751 {
752   register cab_ULONG e;  /* table entry flag/number of extra bits */
753   cab_ULONG n, d;        /* length and index for copy */
754   cab_ULONG w;           /* current window position */
755   struct Ziphuft *t;     /* pointer to table entry */
756   cab_ULONG ml, md;      /* masks for bl and bd bits */
757   register cab_ULONG b;  /* bit buffer */
758   register cab_ULONG k;  /* number of bits in bit buffer */
759
760   /* make local copies of globals */
761   b = ZIP(bb);                       /* initialize bit buffer */
762   k = ZIP(bk);
763   w = ZIP(window_posn);                       /* initialize window position */
764
765   /* inflate the coded data */
766   ml = Zipmask[bl];             /* precompute masks for speed */
767   md = Zipmask[bd];
768
769   for(;;)
770   {
771     ZIPNEEDBITS((cab_ULONG)bl)
772     if((e = (t = tl + ((cab_ULONG)b & ml))->e) > 16)
773       do
774       {
775         if (e == 99)
776           return 1;
777         ZIPDUMPBITS(t->b)
778         e -= 16;
779         ZIPNEEDBITS(e)
780       } while ((e = (t = t->v.t + ((cab_ULONG)b & Zipmask[e]))->e) > 16);
781     ZIPDUMPBITS(t->b)
782     if (e == 16)                /* then it's a literal */
783       CAB(outbuf)[w++] = (cab_UBYTE)t->v.n;
784     else                        /* it's an EOB or a length */
785     {
786       /* exit if end of block */
787       if(e == 15)
788         break;
789
790       /* get length of block to copy */
791       ZIPNEEDBITS(e)
792       n = t->v.n + ((cab_ULONG)b & Zipmask[e]);
793       ZIPDUMPBITS(e);
794
795       /* decode distance of block to copy */
796       ZIPNEEDBITS((cab_ULONG)bd)
797       if ((e = (t = td + ((cab_ULONG)b & md))->e) > 16)
798         do {
799           if (e == 99)
800             return 1;
801           ZIPDUMPBITS(t->b)
802           e -= 16;
803           ZIPNEEDBITS(e)
804         } while ((e = (t = t->v.t + ((cab_ULONG)b & Zipmask[e]))->e) > 16);
805       ZIPDUMPBITS(t->b)
806       ZIPNEEDBITS(e)
807       d = w - t->v.n - ((cab_ULONG)b & Zipmask[e]);
808       ZIPDUMPBITS(e)
809       do
810       {
811         n -= (e = (e = ZIPWSIZE - ((d &= ZIPWSIZE-1) > w ? d : w)) > n ?n:e);
812         do
813         {
814           CAB(outbuf)[w++] = CAB(outbuf)[d++];
815         } while (--e);
816       } while (n);
817     }
818   }
819
820   /* restore the globals from the locals */
821   ZIP(window_posn) = w;              /* restore global window pointer */
822   ZIP(bb) = b;                       /* restore global bit buffer */
823   ZIP(bk) = k;
824
825   /* done */
826   return 0;
827 }
828
829 /***********************************************************
830  * Zipinflate_stored (internal)
831  */
832 cab_LONG Zipinflate_stored(cab_decomp_state *decomp_state)
833 /* "decompress" an inflated type 0 (stored) block. */
834 {
835   cab_ULONG n;           /* number of bytes in block */
836   cab_ULONG w;           /* current window position */
837   register cab_ULONG b;  /* bit buffer */
838   register cab_ULONG k;  /* number of bits in bit buffer */
839
840   /* make local copies of globals */
841   b = ZIP(bb);                       /* initialize bit buffer */
842   k = ZIP(bk);
843   w = ZIP(window_posn);              /* initialize window position */
844
845   /* go to byte boundary */
846   n = k & 7;
847   ZIPDUMPBITS(n);
848
849   /* get the length and its complement */
850   ZIPNEEDBITS(16)
851   n = ((cab_ULONG)b & 0xffff);
852   ZIPDUMPBITS(16)
853   ZIPNEEDBITS(16)
854   if (n != (cab_ULONG)((~b) & 0xffff))
855     return 1;                   /* error in compressed data */
856   ZIPDUMPBITS(16)
857
858   /* read and output the compressed data */
859   while(n--)
860   {
861     ZIPNEEDBITS(8)
862     CAB(outbuf)[w++] = (cab_UBYTE)b;
863     ZIPDUMPBITS(8)
864   }
865
866   /* restore the globals from the locals */
867   ZIP(window_posn) = w;              /* restore global window pointer */
868   ZIP(bb) = b;                       /* restore global bit buffer */
869   ZIP(bk) = k;
870   return 0;
871 }
872
873 /******************************************************
874  * Zipinflate_fixed (internal)
875  */
876 cab_LONG Zipinflate_fixed(cab_decomp_state *decomp_state)
877 {
878   struct Ziphuft *fixed_tl;
879   struct Ziphuft *fixed_td;
880   cab_LONG fixed_bl, fixed_bd;
881   cab_LONG i;                /* temporary variable */
882   cab_ULONG *l;
883
884   l = ZIP(ll);
885
886   /* literal table */
887   for(i = 0; i < 144; i++)
888     l[i] = 8;
889   for(; i < 256; i++)
890     l[i] = 9;
891   for(; i < 280; i++)
892     l[i] = 7;
893   for(; i < 288; i++)          /* make a complete, but wrong code set */
894     l[i] = 8;
895   fixed_bl = 7;
896   if((i = Ziphuft_build(l, 288, 257, (cab_UWORD *) Zipcplens,
897   (cab_UWORD *) Zipcplext, &fixed_tl, &fixed_bl, decomp_state)))
898     return i;
899
900   /* distance table */
901   for(i = 0; i < 30; i++)      /* make an incomplete code set */
902     l[i] = 5;
903   fixed_bd = 5;
904   if((i = Ziphuft_build(l, 30, 0, (cab_UWORD *) Zipcpdist, (cab_UWORD *) Zipcpdext,
905   &fixed_td, &fixed_bd, decomp_state)) > 1)
906   {
907     Ziphuft_free(fixed_tl);
908     return i;
909   }
910
911   /* decompress until an end-of-block code */
912   i = Zipinflate_codes(fixed_tl, fixed_td, fixed_bl, fixed_bd, decomp_state);
913
914   Ziphuft_free(fixed_td);
915   Ziphuft_free(fixed_tl);
916   return i;
917 }
918
919 /**************************************************************
920  * Zipinflate_dynamic (internal)
921  */
922 cab_LONG Zipinflate_dynamic(cab_decomp_state *decomp_state)
923  /* decompress an inflated type 2 (dynamic Huffman codes) block. */
924 {
925   cab_LONG i;           /* temporary variables */
926   cab_ULONG j;
927   cab_ULONG *ll;
928   cab_ULONG l;                  /* last length */
929   cab_ULONG m;                  /* mask for bit lengths table */
930   cab_ULONG n;                  /* number of lengths to get */
931   struct Ziphuft *tl;           /* literal/length code table */
932   struct Ziphuft *td;           /* distance code table */
933   cab_LONG bl;                  /* lookup bits for tl */
934   cab_LONG bd;                  /* lookup bits for td */
935   cab_ULONG nb;                 /* number of bit length codes */
936   cab_ULONG nl;                 /* number of literal/length codes */
937   cab_ULONG nd;                 /* number of distance codes */
938   register cab_ULONG b;         /* bit buffer */
939   register cab_ULONG k;         /* number of bits in bit buffer */
940
941   /* make local bit buffer */
942   b = ZIP(bb);
943   k = ZIP(bk);
944   ll = ZIP(ll);
945
946   /* read in table lengths */
947   ZIPNEEDBITS(5)
948   nl = 257 + ((cab_ULONG)b & 0x1f);      /* number of literal/length codes */
949   ZIPDUMPBITS(5)
950   ZIPNEEDBITS(5)
951   nd = 1 + ((cab_ULONG)b & 0x1f);        /* number of distance codes */
952   ZIPDUMPBITS(5)
953   ZIPNEEDBITS(4)
954   nb = 4 + ((cab_ULONG)b & 0xf);         /* number of bit length codes */
955   ZIPDUMPBITS(4)
956   if(nl > 288 || nd > 32)
957     return 1;                   /* bad lengths */
958
959   /* read in bit-length-code lengths */
960   for(j = 0; j < nb; j++)
961   {
962     ZIPNEEDBITS(3)
963     ll[Zipborder[j]] = (cab_ULONG)b & 7;
964     ZIPDUMPBITS(3)
965   }
966   for(; j < 19; j++)
967     ll[Zipborder[j]] = 0;
968
969   /* build decoding table for trees--single level, 7 bit lookup */
970   bl = 7;
971   if((i = Ziphuft_build(ll, 19, 19, NULL, NULL, &tl, &bl, decomp_state)) != 0)
972   {
973     if(i == 1)
974       Ziphuft_free(tl);
975     return i;                   /* incomplete code set */
976   }
977
978   /* read in literal and distance code lengths */
979   n = nl + nd;
980   m = Zipmask[bl];
981   i = l = 0;
982   while((cab_ULONG)i < n)
983   {
984     ZIPNEEDBITS((cab_ULONG)bl)
985     j = (td = tl + ((cab_ULONG)b & m))->b;
986     ZIPDUMPBITS(j)
987     j = td->v.n;
988     if (j < 16)                 /* length of code in bits (0..15) */
989       ll[i++] = l = j;          /* save last length in l */
990     else if (j == 16)           /* repeat last length 3 to 6 times */
991     {
992       ZIPNEEDBITS(2)
993       j = 3 + ((cab_ULONG)b & 3);
994       ZIPDUMPBITS(2)
995       if((cab_ULONG)i + j > n)
996         return 1;
997       while (j--)
998         ll[i++] = l;
999     }
1000     else if (j == 17)           /* 3 to 10 zero length codes */
1001     {
1002       ZIPNEEDBITS(3)
1003       j = 3 + ((cab_ULONG)b & 7);
1004       ZIPDUMPBITS(3)
1005       if ((cab_ULONG)i + j > n)
1006         return 1;
1007       while (j--)
1008         ll[i++] = 0;
1009       l = 0;
1010     }
1011     else                        /* j == 18: 11 to 138 zero length codes */
1012     {
1013       ZIPNEEDBITS(7)
1014       j = 11 + ((cab_ULONG)b & 0x7f);
1015       ZIPDUMPBITS(7)
1016       if ((cab_ULONG)i + j > n)
1017         return 1;
1018       while (j--)
1019         ll[i++] = 0;
1020       l = 0;
1021     }
1022   }
1023
1024   /* free decoding table for trees */
1025   Ziphuft_free(tl);
1026
1027   /* restore the global bit buffer */
1028   ZIP(bb) = b;
1029   ZIP(bk) = k;
1030
1031   /* build the decoding tables for literal/length and distance codes */
1032   bl = ZIPLBITS;
1033   if((i = Ziphuft_build(ll, nl, 257, (cab_UWORD *) Zipcplens, (cab_UWORD *) Zipcplext,
1034                         &tl, &bl, decomp_state)) != 0)
1035   {
1036     if(i == 1)
1037       Ziphuft_free(tl);
1038     return i;                   /* incomplete code set */
1039   }
1040   bd = ZIPDBITS;
1041   Ziphuft_build(ll + nl, nd, 0, (cab_UWORD *) Zipcpdist, (cab_UWORD *) Zipcpdext,
1042                 &td, &bd, decomp_state);
1043
1044   /* decompress until an end-of-block code */
1045   if(Zipinflate_codes(tl, td, bl, bd, decomp_state))
1046     return 1;
1047
1048   /* free the decoding tables, return */
1049   Ziphuft_free(tl);
1050   Ziphuft_free(td);
1051   return 0;
1052 }
1053
1054 /*****************************************************
1055  * Zipinflate_block (internal)
1056  */
1057 cab_LONG Zipinflate_block(cab_LONG *e, cab_decomp_state *decomp_state) /* e == last block flag */
1058 { /* decompress an inflated block */
1059   cab_ULONG t;                  /* block type */
1060   register cab_ULONG b;     /* bit buffer */
1061   register cab_ULONG k;     /* number of bits in bit buffer */
1062
1063   /* make local bit buffer */
1064   b = ZIP(bb);
1065   k = ZIP(bk);
1066
1067   /* read in last block bit */
1068   ZIPNEEDBITS(1)
1069   *e = (cab_LONG)b & 1;
1070   ZIPDUMPBITS(1)
1071
1072   /* read in block type */
1073   ZIPNEEDBITS(2)
1074   t = (cab_ULONG)b & 3;
1075   ZIPDUMPBITS(2)
1076
1077   /* restore the global bit buffer */
1078   ZIP(bb) = b;
1079   ZIP(bk) = k;
1080
1081   /* inflate that block type */
1082   if(t == 2)
1083     return Zipinflate_dynamic(decomp_state);
1084   if(t == 0)
1085     return Zipinflate_stored(decomp_state);
1086   if(t == 1)
1087     return Zipinflate_fixed(decomp_state);
1088   /* bad block type */
1089   return 2;
1090 }
1091
1092 /****************************************************
1093  * ZIPdecompress (internal)
1094  */
1095 int ZIPdecompress(int inlen, int outlen, cab_decomp_state *decomp_state)
1096 {
1097   cab_LONG e;               /* last block flag */
1098
1099   TRACE("(inlen == %d, outlen == %d)\n", inlen, outlen);
1100
1101   ZIP(inpos) = CAB(inbuf);
1102   ZIP(bb) = ZIP(bk) = ZIP(window_posn) = 0;
1103   if(outlen > ZIPWSIZE)
1104     return DECR_DATAFORMAT;
1105
1106   /* CK = Chris Kirmse, official Microsoft purloiner */
1107   if(ZIP(inpos)[0] != 0x43 || ZIP(inpos)[1] != 0x4B)
1108     return DECR_ILLEGALDATA;
1109   ZIP(inpos) += 2;
1110
1111   do
1112   {
1113     if(Zipinflate_block(&e, decomp_state))
1114       return DECR_ILLEGALDATA;
1115   } while(!e);
1116
1117   /* return success */
1118   return DECR_OK;
1119 }
1120
1121 /* Quantum decruncher */
1122
1123 /* This decruncher was researched and implemented by Matthew Russoto. */
1124 /* It has since been tidied up by Stuart Caie */
1125
1126 /******************************************************************
1127  * QTMinitmodel (internal)
1128  *
1129  * Initialise a model which decodes symbols from [s] to [s]+[n]-1
1130  */
1131 void QTMinitmodel(struct QTMmodel *m, struct QTMmodelsym *sym, int n, int s) {
1132   int i;
1133   m->shiftsleft = 4;
1134   m->entries    = n;
1135   m->syms       = sym;
1136   memset(m->tabloc, 0xFF, sizeof(m->tabloc)); /* clear out look-up table */
1137   for (i = 0; i < n; i++) {
1138     m->tabloc[i+s]     = i;   /* set up a look-up entry for symbol */
1139     m->syms[i].sym     = i+s; /* actual symbol */
1140     m->syms[i].cumfreq = n-i; /* current frequency of that symbol */
1141   }
1142   m->syms[n].cumfreq = 0;
1143 }
1144
1145 /******************************************************************
1146  * QTMinit (internal)
1147  */
1148 int QTMinit(int window, int level, cab_decomp_state *decomp_state) {
1149   int wndsize = 1 << window, msz = window * 2, i;
1150   cab_ULONG j;
1151
1152   /* QTM supports window sizes of 2^10 (1Kb) through 2^21 (2Mb) */
1153   /* if a previously allocated window is big enough, keep it    */
1154   if (window < 10 || window > 21) return DECR_DATAFORMAT;
1155   if (QTM(actual_size) < wndsize) {
1156     if (QTM(window)) free(QTM(window));
1157     QTM(window) = NULL;
1158   }
1159   if (!QTM(window)) {
1160     if (!(QTM(window) = malloc(wndsize))) return DECR_NOMEMORY;
1161     QTM(actual_size) = wndsize;
1162   }
1163   QTM(window_size) = wndsize;
1164   QTM(window_posn) = 0;
1165
1166   /* initialise static slot/extrabits tables */
1167   for (i = 0, j = 0; i < 27; i++) {
1168     CAB(q_length_extra)[i] = (i == 26) ? 0 : (i < 2 ? 0 : i - 2) >> 2;
1169     CAB(q_length_base)[i] = j; j += 1 << ((i == 26) ? 5 : CAB(q_length_extra)[i]);
1170   }
1171   for (i = 0, j = 0; i < 42; i++) {
1172     CAB(q_extra_bits)[i] = (i < 2 ? 0 : i-2) >> 1;
1173     CAB(q_position_base)[i] = j; j += 1 << CAB(q_extra_bits)[i];
1174   }
1175
1176   /* initialise arithmetic coding models */
1177
1178   QTMinitmodel(&QTM(model7), &QTM(m7sym)[0], 7, 0);
1179
1180   QTMinitmodel(&QTM(model00), &QTM(m00sym)[0], 0x40, 0x00);
1181   QTMinitmodel(&QTM(model40), &QTM(m40sym)[0], 0x40, 0x40);
1182   QTMinitmodel(&QTM(model80), &QTM(m80sym)[0], 0x40, 0x80);
1183   QTMinitmodel(&QTM(modelC0), &QTM(mC0sym)[0], 0x40, 0xC0);
1184
1185   /* model 4 depends on table size, ranges from 20 to 24  */
1186   QTMinitmodel(&QTM(model4), &QTM(m4sym)[0], (msz < 24) ? msz : 24, 0);
1187   /* model 5 depends on table size, ranges from 20 to 36  */
1188   QTMinitmodel(&QTM(model5), &QTM(m5sym)[0], (msz < 36) ? msz : 36, 0);
1189   /* model 6pos depends on table size, ranges from 20 to 42 */
1190   QTMinitmodel(&QTM(model6pos), &QTM(m6psym)[0], msz, 0);
1191   QTMinitmodel(&QTM(model6len), &QTM(m6lsym)[0], 27, 0);
1192
1193   return DECR_OK;
1194 }
1195
1196 /****************************************************************
1197  * QTMupdatemodel (internal)
1198  */
1199 void QTMupdatemodel(struct QTMmodel *model, int sym) {
1200   struct QTMmodelsym temp;
1201   int i, j;
1202
1203   for (i = 0; i < sym; i++) model->syms[i].cumfreq += 8;
1204
1205   if (model->syms[0].cumfreq > 3800) {
1206     if (--model->shiftsleft) {
1207       for (i = model->entries - 1; i >= 0; i--) {
1208         /* -1, not -2; the 0 entry saves this */
1209         model->syms[i].cumfreq >>= 1;
1210         if (model->syms[i].cumfreq <= model->syms[i+1].cumfreq) {
1211           model->syms[i].cumfreq = model->syms[i+1].cumfreq + 1;
1212         }
1213       }
1214     }
1215     else {
1216       model->shiftsleft = 50;
1217       for (i = 0; i < model->entries ; i++) {
1218         /* no -1, want to include the 0 entry */
1219         /* this converts cumfreqs into frequencies, then shifts right */
1220         model->syms[i].cumfreq -= model->syms[i+1].cumfreq;
1221         model->syms[i].cumfreq++; /* avoid losing things entirely */
1222         model->syms[i].cumfreq >>= 1;
1223       }
1224
1225       /* now sort by frequencies, decreasing order -- this must be an
1226        * inplace selection sort, or a sort with the same (in)stability
1227        * characteristics
1228        */
1229       for (i = 0; i < model->entries - 1; i++) {
1230         for (j = i + 1; j < model->entries; j++) {
1231           if (model->syms[i].cumfreq < model->syms[j].cumfreq) {
1232             temp = model->syms[i];
1233             model->syms[i] = model->syms[j];
1234             model->syms[j] = temp;
1235           }
1236         }
1237       }
1238     
1239       /* then convert frequencies back to cumfreq */
1240       for (i = model->entries - 1; i >= 0; i--) {
1241         model->syms[i].cumfreq += model->syms[i+1].cumfreq;
1242       }
1243       /* then update the other part of the table */
1244       for (i = 0; i < model->entries; i++) {
1245         model->tabloc[model->syms[i].sym] = i;
1246       }
1247     }
1248   }
1249 }
1250
1251 /*******************************************************************
1252  * QTMdecompress (internal)
1253  */
1254 int QTMdecompress(int inlen, int outlen, cab_decomp_state *decomp_state)
1255 {
1256   cab_UBYTE *inpos  = CAB(inbuf);
1257   cab_UBYTE *window = QTM(window);
1258   cab_UBYTE *runsrc, *rundest;
1259
1260   cab_ULONG window_posn = QTM(window_posn);
1261   cab_ULONG window_size = QTM(window_size);
1262
1263   /* used by bitstream macros */
1264   register int bitsleft, bitrun, bitsneed;
1265   register cab_ULONG bitbuf;
1266
1267   /* used by GET_SYMBOL */
1268   cab_ULONG range;
1269   cab_UWORD symf;
1270   int i;
1271
1272   int extra, togo = outlen, match_length = 0, copy_length;
1273   cab_UBYTE selector, sym;
1274   cab_ULONG match_offset = 0;
1275
1276   cab_UWORD H = 0xFFFF, L = 0, C;
1277
1278   TRACE("(inlen == %d, outlen == %d)\n", inlen, outlen);
1279
1280   /* read initial value of C */
1281   Q_INIT_BITSTREAM;
1282   Q_READ_BITS(C, 16);
1283
1284   /* apply 2^x-1 mask */
1285   window_posn &= window_size - 1;
1286   /* runs can't straddle the window wraparound */
1287   if ((window_posn + togo) > window_size) {
1288     TRACE("straddled run\n");
1289     return DECR_DATAFORMAT;
1290   }
1291
1292   while (togo > 0) {
1293     GET_SYMBOL(model7, selector);
1294     switch (selector) {
1295     case 0:
1296       GET_SYMBOL(model00, sym); window[window_posn++] = sym; togo--;
1297       break;
1298     case 1:
1299       GET_SYMBOL(model40, sym); window[window_posn++] = sym; togo--;
1300       break;
1301     case 2:
1302       GET_SYMBOL(model80, sym); window[window_posn++] = sym; togo--;
1303       break;
1304     case 3:
1305       GET_SYMBOL(modelC0, sym); window[window_posn++] = sym; togo--;
1306       break;
1307
1308     case 4:
1309       /* selector 4 = fixed length of 3 */
1310       GET_SYMBOL(model4, sym);
1311       Q_READ_BITS(extra, CAB(q_extra_bits)[sym]);
1312       match_offset = CAB(q_position_base)[sym] + extra + 1;
1313       match_length = 3;
1314       break;
1315
1316     case 5:
1317       /* selector 5 = fixed length of 4 */
1318       GET_SYMBOL(model5, sym);
1319       Q_READ_BITS(extra, CAB(q_extra_bits)[sym]);
1320       match_offset = CAB(q_position_base)[sym] + extra + 1;
1321       match_length = 4;
1322       break;
1323
1324     case 6:
1325       /* selector 6 = variable length */
1326       GET_SYMBOL(model6len, sym);
1327       Q_READ_BITS(extra, CAB(q_length_extra)[sym]);
1328       match_length = CAB(q_length_base)[sym] + extra + 5;
1329       GET_SYMBOL(model6pos, sym);
1330       Q_READ_BITS(extra, CAB(q_extra_bits)[sym]);
1331       match_offset = CAB(q_position_base)[sym] + extra + 1;
1332       break;
1333
1334     default:
1335       TRACE("Selector is bogus\n");
1336       return DECR_ILLEGALDATA;
1337     }
1338
1339     /* if this is a match */
1340     if (selector >= 4) {
1341       rundest = window + window_posn;
1342       togo -= match_length;
1343
1344       /* copy any wrapped around source data */
1345       if (window_posn >= match_offset) {
1346         /* no wrap */
1347         runsrc = rundest - match_offset;
1348       } else {
1349         runsrc = rundest + (window_size - match_offset);
1350         copy_length = match_offset - window_posn;
1351         if (copy_length < match_length) {
1352           match_length -= copy_length;
1353           window_posn += copy_length;
1354           while (copy_length-- > 0) *rundest++ = *runsrc++;
1355           runsrc = window;
1356         }
1357       }
1358       window_posn += match_length;
1359
1360       /* copy match data - no worries about destination wraps */
1361       while (match_length-- > 0) *rundest++ = *runsrc++;
1362     }
1363   } /* while (togo > 0) */
1364
1365   if (togo != 0) {
1366     TRACE("Frame overflow, this_run = %d\n", togo);
1367     return DECR_ILLEGALDATA;
1368   }
1369
1370   memcpy(CAB(outbuf), window + ((!window_posn) ? window_size : window_posn) -
1371     outlen, outlen);
1372
1373   QTM(window_posn) = window_posn;
1374   return DECR_OK;
1375 }
1376
1377 /* LZX decruncher */
1378
1379 /* Microsoft's LZX document and their implementation of the
1380  * com.ms.util.cab Java package do not concur.
1381  *
1382  * In the LZX document, there is a table showing the correlation between
1383  * window size and the number of position slots. It states that the 1MB
1384  * window = 40 slots and the 2MB window = 42 slots. In the implementation,
1385  * 1MB = 42 slots, 2MB = 50 slots. The actual calculation is 'find the
1386  * first slot whose position base is equal to or more than the required
1387  * window size'. This would explain why other tables in the document refer
1388  * to 50 slots rather than 42.
1389  *
1390  * The constant NUM_PRIMARY_LENGTHS used in the decompression pseudocode
1391  * is not defined in the specification.
1392  *
1393  * The LZX document does not state the uncompressed block has an
1394  * uncompressed length field. Where does this length field come from, so
1395  * we can know how large the block is? The implementation has it as the 24
1396  * bits following after the 3 blocktype bits, before the alignment
1397  * padding.
1398  *
1399  * The LZX document states that aligned offset blocks have their aligned
1400  * offset huffman tree AFTER the main and length trees. The implementation
1401  * suggests that the aligned offset tree is BEFORE the main and length
1402  * trees.
1403  *
1404  * The LZX document decoding algorithm states that, in an aligned offset
1405  * block, if an extra_bits value is 1, 2 or 3, then that number of bits
1406  * should be read and the result added to the match offset. This is
1407  * correct for 1 and 2, but not 3, where just a huffman symbol (using the
1408  * aligned tree) should be read.
1409  *
1410  * Regarding the E8 preprocessing, the LZX document states 'No translation
1411  * may be performed on the last 6 bytes of the input block'. This is
1412  * correct.  However, the pseudocode provided checks for the *E8 leader*
1413  * up to the last 6 bytes. If the leader appears between -10 and -7 bytes
1414  * from the end, this would cause the next four bytes to be modified, at
1415  * least one of which would be in the last 6 bytes, which is not allowed
1416  * according to the spec.
1417  *
1418  * The specification states that the huffman trees must always contain at
1419  * least one element. However, many CAB files contain blocks where the
1420  * length tree is completely empty (because there are no matches), and
1421  * this is expected to succeed.
1422  */
1423
1424
1425 /* LZX uses what it calls 'position slots' to represent match offsets.
1426  * What this means is that a small 'position slot' number and a small
1427  * offset from that slot are encoded instead of one large offset for
1428  * every match.
1429  * - lzx_position_base is an index to the position slot bases
1430  * - lzx_extra_bits states how many bits of offset-from-base data is needed.
1431  */
1432
1433 /************************************************************
1434  * LZXinit (internal)
1435  */
1436 int LZXinit(int window, cab_decomp_state *decomp_state) {
1437   cab_ULONG wndsize = 1 << window;
1438   int i, j, posn_slots;
1439
1440   /* LZX supports window sizes of 2^15 (32Kb) through 2^21 (2Mb) */
1441   /* if a previously allocated window is big enough, keep it     */
1442   if (window < 15 || window > 21) return DECR_DATAFORMAT;
1443   if (LZX(actual_size) < wndsize) {
1444     if (LZX(window)) free(LZX(window));
1445     LZX(window) = NULL;
1446   }
1447   if (!LZX(window)) {
1448     if (!(LZX(window) = malloc(wndsize))) return DECR_NOMEMORY;
1449     LZX(actual_size) = wndsize;
1450   }
1451   LZX(window_size) = wndsize;
1452
1453   /* initialise static tables */
1454   for (i=0, j=0; i <= 50; i += 2) {
1455     CAB(extra_bits)[i] = CAB(extra_bits)[i+1] = j; /* 0,0,0,0,1,1,2,2,3,3... */
1456     if ((i != 0) && (j < 17)) j++; /* 0,0,1,2,3,4...15,16,17,17,17,17... */
1457   }
1458   for (i=0, j=0; i <= 50; i++) {
1459     CAB(lzx_position_base)[i] = j; /* 0,1,2,3,4,6,8,12,16,24,32,... */
1460     j += 1 << CAB(extra_bits)[i]; /* 1,1,1,1,2,2,4,4,8,8,16,16,32,32,... */
1461   }
1462
1463   /* calculate required position slots */
1464        if (window == 20) posn_slots = 42;
1465   else if (window == 21) posn_slots = 50;
1466   else posn_slots = window << 1;
1467
1468   /*posn_slots=i=0; while (i < wndsize) i += 1 << CAB(extra_bits)[posn_slots++]; */
1469
1470   LZX(R0)  =  LZX(R1)  = LZX(R2) = 1;
1471   LZX(main_elements)   = LZX_NUM_CHARS + (posn_slots << 3);
1472   LZX(header_read)     = 0;
1473   LZX(frames_read)     = 0;
1474   LZX(block_remaining) = 0;
1475   LZX(block_type)      = LZX_BLOCKTYPE_INVALID;
1476   LZX(intel_curpos)    = 0;
1477   LZX(intel_started)   = 0;
1478   LZX(window_posn)     = 0;
1479
1480   /* initialise tables to 0 (because deltas will be applied to them) */
1481   for (i = 0; i < LZX_MAINTREE_MAXSYMBOLS; i++) LZX(MAINTREE_len)[i] = 0;
1482   for (i = 0; i < LZX_LENGTH_MAXSYMBOLS; i++)   LZX(LENGTH_len)[i]   = 0;
1483
1484   return DECR_OK;
1485 }
1486
1487 /*************************************************************************
1488  * make_decode_table (internal)
1489  *
1490  * This function was coded by David Tritscher. It builds a fast huffman
1491  * decoding table out of just a canonical huffman code lengths table.
1492  *
1493  * PARAMS
1494  *   nsyms:  total number of symbols in this huffman tree.
1495  *   nbits:  any symbols with a code length of nbits or less can be decoded
1496  *           in one lookup of the table.
1497  *   length: A table to get code lengths from [0 to syms-1]
1498  *   table:  The table to fill up with decoded symbols and pointers.
1499  *
1500  * RETURNS
1501  *   OK:    0
1502  *   error: 1
1503  */
1504 int make_decode_table(cab_ULONG nsyms, cab_ULONG nbits, cab_UBYTE *length, cab_UWORD *table) {
1505   register cab_UWORD sym;
1506   register cab_ULONG leaf;
1507   register cab_UBYTE bit_num = 1;
1508   cab_ULONG fill;
1509   cab_ULONG pos         = 0; /* the current position in the decode table */
1510   cab_ULONG table_mask  = 1 << nbits;
1511   cab_ULONG bit_mask    = table_mask >> 1; /* don't do 0 length codes */
1512   cab_ULONG next_symbol = bit_mask; /* base of allocation for long codes */
1513
1514   /* fill entries for codes short enough for a direct mapping */
1515   while (bit_num <= nbits) {
1516     for (sym = 0; sym < nsyms; sym++) {
1517       if (length[sym] == bit_num) {
1518         leaf = pos;
1519
1520         if((pos += bit_mask) > table_mask) return 1; /* table overrun */
1521
1522         /* fill all possible lookups of this symbol with the symbol itself */
1523         fill = bit_mask;
1524         while (fill-- > 0) table[leaf++] = sym;
1525       }
1526     }
1527     bit_mask >>= 1;
1528     bit_num++;
1529   }
1530
1531   /* if there are any codes longer than nbits */
1532   if (pos != table_mask) {
1533     /* clear the remainder of the table */
1534     for (sym = pos; sym < table_mask; sym++) table[sym] = 0;
1535
1536     /* give ourselves room for codes to grow by up to 16 more bits */
1537     pos <<= 16;
1538     table_mask <<= 16;
1539     bit_mask = 1 << 15;
1540
1541     while (bit_num <= 16) {
1542       for (sym = 0; sym < nsyms; sym++) {
1543         if (length[sym] == bit_num) {
1544           leaf = pos >> 16;
1545           for (fill = 0; fill < bit_num - nbits; fill++) {
1546             /* if this path hasn't been taken yet, 'allocate' two entries */
1547             if (table[leaf] == 0) {
1548               table[(next_symbol << 1)] = 0;
1549               table[(next_symbol << 1) + 1] = 0;
1550               table[leaf] = next_symbol++;
1551             }
1552             /* follow the path and select either left or right for next bit */
1553             leaf = table[leaf] << 1;
1554             if ((pos >> (15-fill)) & 1) leaf++;
1555           }
1556           table[leaf] = sym;
1557
1558           if ((pos += bit_mask) > table_mask) return 1; /* table overflow */
1559         }
1560       }
1561       bit_mask >>= 1;
1562       bit_num++;
1563     }
1564   }
1565
1566   /* full table? */
1567   if (pos == table_mask) return 0;
1568
1569   /* either erroneous table, or all elements are 0 - let's find out. */
1570   for (sym = 0; sym < nsyms; sym++) if (length[sym]) return 1;
1571   return 0;
1572 }
1573
1574 /************************************************************
1575  * lzx_read_lens (internal)
1576  */
1577 int lzx_read_lens(cab_UBYTE *lens, cab_ULONG first, cab_ULONG last, struct lzx_bits *lb,
1578                   cab_decomp_state *decomp_state) {
1579   cab_ULONG i,j, x,y;
1580   int z;
1581
1582   register cab_ULONG bitbuf = lb->bb;
1583   register int bitsleft = lb->bl;
1584   cab_UBYTE *inpos = lb->ip;
1585   cab_UWORD *hufftbl;
1586   
1587   for (x = 0; x < 20; x++) {
1588     READ_BITS(y, 4);
1589     LENTABLE(PRETREE)[x] = y;
1590   }
1591   BUILD_TABLE(PRETREE);
1592
1593   for (x = first; x < last; ) {
1594     READ_HUFFSYM(PRETREE, z);
1595     if (z == 17) {
1596       READ_BITS(y, 4); y += 4;
1597       while (y--) lens[x++] = 0;
1598     }
1599     else if (z == 18) {
1600       READ_BITS(y, 5); y += 20;
1601       while (y--) lens[x++] = 0;
1602     }
1603     else if (z == 19) {
1604       READ_BITS(y, 1); y += 4;
1605       READ_HUFFSYM(PRETREE, z);
1606       z = lens[x] - z; if (z < 0) z += 17;
1607       while (y--) lens[x++] = z;
1608     }
1609     else {
1610       z = lens[x] - z; if (z < 0) z += 17;
1611       lens[x++] = z;
1612     }
1613   }
1614
1615   lb->bb = bitbuf;
1616   lb->bl = bitsleft;
1617   lb->ip = inpos;
1618   return 0;
1619 }
1620
1621 /*******************************************************
1622  * LZXdecompress (internal)
1623  */
1624 int LZXdecompress(int inlen, int outlen, cab_decomp_state *decomp_state) {
1625   cab_UBYTE *inpos  = CAB(inbuf);
1626   cab_UBYTE *endinp = inpos + inlen;
1627   cab_UBYTE *window = LZX(window);
1628   cab_UBYTE *runsrc, *rundest;
1629   cab_UWORD *hufftbl; /* used in READ_HUFFSYM macro as chosen decoding table */
1630
1631   cab_ULONG window_posn = LZX(window_posn);
1632   cab_ULONG window_size = LZX(window_size);
1633   cab_ULONG R0 = LZX(R0);
1634   cab_ULONG R1 = LZX(R1);
1635   cab_ULONG R2 = LZX(R2);
1636
1637   register cab_ULONG bitbuf;
1638   register int bitsleft;
1639   cab_ULONG match_offset, i,j,k; /* ijk used in READ_HUFFSYM macro */
1640   struct lzx_bits lb; /* used in READ_LENGTHS macro */
1641
1642   int togo = outlen, this_run, main_element, aligned_bits;
1643   int match_length, copy_length, length_footer, extra, verbatim_bits;
1644
1645   TRACE("(inlen == %d, outlen == %d)\n", inlen, outlen);
1646
1647   INIT_BITSTREAM;
1648
1649   /* read header if necessary */
1650   if (!LZX(header_read)) {
1651     i = j = 0;
1652     READ_BITS(k, 1); if (k) { READ_BITS(i,16); READ_BITS(j,16); }
1653     LZX(intel_filesize) = (i << 16) | j; /* or 0 if not encoded */
1654     LZX(header_read) = 1;
1655   }
1656
1657   /* main decoding loop */
1658   while (togo > 0) {
1659     /* last block finished, new block expected */
1660     if (LZX(block_remaining) == 0) {
1661       if (LZX(block_type) == LZX_BLOCKTYPE_UNCOMPRESSED) {
1662         if (LZX(block_length) & 1) inpos++; /* realign bitstream to word */
1663         INIT_BITSTREAM;
1664       }
1665
1666       READ_BITS(LZX(block_type), 3);
1667       READ_BITS(i, 16);
1668       READ_BITS(j, 8);
1669       LZX(block_remaining) = LZX(block_length) = (i << 8) | j;
1670
1671       switch (LZX(block_type)) {
1672       case LZX_BLOCKTYPE_ALIGNED:
1673         for (i = 0; i < 8; i++) { READ_BITS(j, 3); LENTABLE(ALIGNED)[i] = j; }
1674         BUILD_TABLE(ALIGNED);
1675         /* rest of aligned header is same as verbatim */
1676
1677       case LZX_BLOCKTYPE_VERBATIM:
1678         READ_LENGTHS(MAINTREE, 0, 256, lzx_read_lens);
1679         READ_LENGTHS(MAINTREE, 256, LZX(main_elements), lzx_read_lens);
1680         BUILD_TABLE(MAINTREE);
1681         if (LENTABLE(MAINTREE)[0xE8] != 0) LZX(intel_started) = 1;
1682
1683         READ_LENGTHS(LENGTH, 0, LZX_NUM_SECONDARY_LENGTHS, lzx_read_lens);
1684         BUILD_TABLE(LENGTH);
1685         break;
1686
1687       case LZX_BLOCKTYPE_UNCOMPRESSED:
1688         LZX(intel_started) = 1; /* because we can't assume otherwise */
1689         ENSURE_BITS(16); /* get up to 16 pad bits into the buffer */
1690         if (bitsleft > 16) inpos -= 2; /* and align the bitstream! */
1691         R0 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
1692         R1 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
1693         R2 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
1694         break;
1695
1696       default:
1697         return DECR_ILLEGALDATA;
1698       }
1699     }
1700
1701     /* buffer exhaustion check */
1702     if (inpos > endinp) {
1703       /* it's possible to have a file where the next run is less than
1704        * 16 bits in size. In this case, the READ_HUFFSYM() macro used
1705        * in building the tables will exhaust the buffer, so we should
1706        * allow for this, but not allow those accidentally read bits to
1707        * be used (so we check that there are at least 16 bits
1708        * remaining - in this boundary case they aren't really part of
1709        * the compressed data)
1710        */
1711       if (inpos > (endinp+2) || bitsleft < 16) return DECR_ILLEGALDATA;
1712     }
1713
1714     while ((this_run = LZX(block_remaining)) > 0 && togo > 0) {
1715       if (this_run > togo) this_run = togo;
1716       togo -= this_run;
1717       LZX(block_remaining) -= this_run;
1718
1719       /* apply 2^x-1 mask */
1720       window_posn &= window_size - 1;
1721       /* runs can't straddle the window wraparound */
1722       if ((window_posn + this_run) > window_size)
1723         return DECR_DATAFORMAT;
1724
1725       switch (LZX(block_type)) {
1726
1727       case LZX_BLOCKTYPE_VERBATIM:
1728         while (this_run > 0) {
1729           READ_HUFFSYM(MAINTREE, main_element);
1730
1731           if (main_element < LZX_NUM_CHARS) {
1732             /* literal: 0 to LZX_NUM_CHARS-1 */
1733             window[window_posn++] = main_element;
1734             this_run--;
1735           }
1736           else {
1737             /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
1738             main_element -= LZX_NUM_CHARS;
1739   
1740             match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
1741             if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
1742               READ_HUFFSYM(LENGTH, length_footer);
1743               match_length += length_footer;
1744             }
1745             match_length += LZX_MIN_MATCH;
1746   
1747             match_offset = main_element >> 3;
1748   
1749             if (match_offset > 2) {
1750               /* not repeated offset */
1751               if (match_offset != 3) {
1752                 extra = CAB(extra_bits)[match_offset];
1753                 READ_BITS(verbatim_bits, extra);
1754                 match_offset = CAB(lzx_position_base)[match_offset] 
1755                                - 2 + verbatim_bits;
1756               }
1757               else {
1758                 match_offset = 1;
1759               }
1760   
1761               /* update repeated offset LRU queue */
1762               R2 = R1; R1 = R0; R0 = match_offset;
1763             }
1764             else if (match_offset == 0) {
1765               match_offset = R0;
1766             }
1767             else if (match_offset == 1) {
1768               match_offset = R1;
1769               R1 = R0; R0 = match_offset;
1770             }
1771             else /* match_offset == 2 */ {
1772               match_offset = R2;
1773               R2 = R0; R0 = match_offset;
1774             }
1775
1776             rundest = window + window_posn;
1777             this_run -= match_length;
1778
1779             /* copy any wrapped around source data */
1780             if (window_posn >= match_offset) {
1781               /* no wrap */
1782               runsrc = rundest - match_offset;
1783             } else {
1784               runsrc = rundest + (window_size - match_offset);
1785               copy_length = match_offset - window_posn;
1786               if (copy_length < match_length) {
1787                 match_length -= copy_length;
1788                 window_posn += copy_length;
1789                 while (copy_length-- > 0) *rundest++ = *runsrc++;
1790                 runsrc = window;
1791               }
1792             }
1793             window_posn += match_length;
1794
1795             /* copy match data - no worries about destination wraps */
1796             while (match_length-- > 0) *rundest++ = *runsrc++;
1797           }
1798         }
1799         break;
1800
1801       case LZX_BLOCKTYPE_ALIGNED:
1802         while (this_run > 0) {
1803           READ_HUFFSYM(MAINTREE, main_element);
1804   
1805           if (main_element < LZX_NUM_CHARS) {
1806             /* literal: 0 to LZX_NUM_CHARS-1 */
1807             window[window_posn++] = main_element;
1808             this_run--;
1809           }
1810           else {
1811             /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
1812             main_element -= LZX_NUM_CHARS;
1813   
1814             match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
1815             if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
1816               READ_HUFFSYM(LENGTH, length_footer);
1817               match_length += length_footer;
1818             }
1819             match_length += LZX_MIN_MATCH;
1820   
1821             match_offset = main_element >> 3;
1822   
1823             if (match_offset > 2) {
1824               /* not repeated offset */
1825               extra = CAB(extra_bits)[match_offset];
1826               match_offset = CAB(lzx_position_base)[match_offset] - 2;
1827               if (extra > 3) {
1828                 /* verbatim and aligned bits */
1829                 extra -= 3;
1830                 READ_BITS(verbatim_bits, extra);
1831                 match_offset += (verbatim_bits << 3);
1832                 READ_HUFFSYM(ALIGNED, aligned_bits);
1833                 match_offset += aligned_bits;
1834               }
1835               else if (extra == 3) {
1836                 /* aligned bits only */
1837                 READ_HUFFSYM(ALIGNED, aligned_bits);
1838                 match_offset += aligned_bits;
1839               }
1840               else if (extra > 0) { /* extra==1, extra==2 */
1841                 /* verbatim bits only */
1842                 READ_BITS(verbatim_bits, extra);
1843                 match_offset += verbatim_bits;
1844               }
1845               else /* extra == 0 */ {
1846                 /* ??? */
1847                 match_offset = 1;
1848               }
1849   
1850               /* update repeated offset LRU queue */
1851               R2 = R1; R1 = R0; R0 = match_offset;
1852             }
1853             else if (match_offset == 0) {
1854               match_offset = R0;
1855             }
1856             else if (match_offset == 1) {
1857               match_offset = R1;
1858               R1 = R0; R0 = match_offset;
1859             }
1860             else /* match_offset == 2 */ {
1861               match_offset = R2;
1862               R2 = R0; R0 = match_offset;
1863             }
1864
1865             rundest = window + window_posn;
1866             this_run -= match_length;
1867
1868             /* copy any wrapped around source data */
1869             if (window_posn >= match_offset) {
1870               /* no wrap */
1871               runsrc = rundest - match_offset;
1872             } else {
1873               runsrc = rundest + (window_size - match_offset);
1874               copy_length = match_offset - window_posn;
1875               if (copy_length < match_length) {
1876                 match_length -= copy_length;
1877                 window_posn += copy_length;
1878                 while (copy_length-- > 0) *rundest++ = *runsrc++;
1879                 runsrc = window;
1880               }
1881             }
1882             window_posn += match_length;
1883
1884             /* copy match data - no worries about destination wraps */
1885             while (match_length-- > 0) *rundest++ = *runsrc++;
1886           }
1887         }
1888         break;
1889
1890       case LZX_BLOCKTYPE_UNCOMPRESSED:
1891         if ((inpos + this_run) > endinp) return DECR_ILLEGALDATA;
1892         memcpy(window + window_posn, inpos, (size_t) this_run);
1893         inpos += this_run; window_posn += this_run;
1894         break;
1895
1896       default:
1897         return DECR_ILLEGALDATA; /* might as well */
1898       }
1899
1900     }
1901   }
1902
1903   if (togo != 0) return DECR_ILLEGALDATA;
1904   memcpy(CAB(outbuf), window + ((!window_posn) ? window_size : window_posn) -
1905     outlen, (size_t) outlen);
1906
1907   LZX(window_posn) = window_posn;
1908   LZX(R0) = R0;
1909   LZX(R1) = R1;
1910   LZX(R2) = R2;
1911
1912   /* intel E8 decoding */
1913   if ((LZX(frames_read)++ < 32768) && LZX(intel_filesize) != 0) {
1914     if (outlen <= 6 || !LZX(intel_started)) {
1915       LZX(intel_curpos) += outlen;
1916     }
1917     else {
1918       cab_UBYTE *data    = CAB(outbuf);
1919       cab_UBYTE *dataend = data + outlen - 10;
1920       cab_LONG curpos    = LZX(intel_curpos);
1921       cab_LONG filesize  = LZX(intel_filesize);
1922       cab_LONG abs_off, rel_off;
1923
1924       LZX(intel_curpos) = curpos + outlen;
1925
1926       while (data < dataend) {
1927         if (*data++ != 0xE8) { curpos++; continue; }
1928         abs_off = data[0] | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);
1929         if ((abs_off >= -curpos) && (abs_off < filesize)) {
1930           rel_off = (abs_off >= 0) ? abs_off - curpos : abs_off + filesize;
1931           data[0] = (cab_UBYTE) rel_off;
1932           data[1] = (cab_UBYTE) (rel_off >> 8);
1933           data[2] = (cab_UBYTE) (rel_off >> 16);
1934           data[3] = (cab_UBYTE) (rel_off >> 24);
1935         }
1936         data += 4;
1937         curpos += 5;
1938       }
1939     }
1940   }
1941   return DECR_OK;
1942 }
1943
1944 /*********************************************************
1945  * find_cabs_in_file (internal)
1946  */
1947 struct cabinet *find_cabs_in_file(LPCSTR name, cab_UBYTE search_buf[])
1948 {
1949   struct cabinet *cab, *cab2, *firstcab = NULL, *linkcab = NULL;
1950   cab_UBYTE *pstart = &search_buf[0], *pend, *p;
1951   cab_off_t offset, caboff, cablen = 0, foffset = 0, filelen, length;
1952   int state = 0, found = 0, ok = 0;
1953
1954   TRACE("(name == %s)\n", debugstr_a((char *) name));
1955
1956   /* open the file and search for cabinet headers */
1957   if ((cab = (struct cabinet *) calloc(1, sizeof(struct cabinet)))) {
1958     cab->filename = name;
1959     if (cabinet_open(cab)) {
1960       filelen = cab->filelen;
1961       for (offset = 0; (offset < filelen); offset += length) {
1962         /* search length is either the full length of the search buffer,
1963          * or the amount of data remaining to the end of the file,
1964          * whichever is less.
1965          */
1966         length = filelen - offset;
1967         if (length > CAB_SEARCH_SIZE) length = CAB_SEARCH_SIZE;
1968
1969         /* fill the search buffer with data from disk */
1970         if (!cabinet_read(cab, search_buf, length)) break;
1971
1972         /* read through the entire buffer. */
1973         p = pstart;
1974         pend = &search_buf[length];
1975         while (p < pend) {
1976           switch (state) {
1977           /* starting state */
1978           case 0:
1979             /* we spend most of our time in this while loop, looking for
1980              * a leading 'M' of the 'MSCF' signature
1981              */
1982             while (*p++ != 0x4D && p < pend);
1983             if (p < pend) state = 1; /* if we found tht 'M', advance state */
1984             break;
1985
1986           /* verify that the next 3 bytes are 'S', 'C' and 'F' */
1987           case 1: state = (*p++ == 0x53) ? 2 : 0; break;
1988           case 2: state = (*p++ == 0x43) ? 3 : 0; break;
1989           case 3: state = (*p++ == 0x46) ? 4 : 0; break;
1990
1991           /* we don't care about bytes 4-7 */
1992           /* bytes 8-11 are the overall length of the cabinet */
1993           case 8:  cablen  = *p++;       state++; break;
1994           case 9:  cablen |= *p++ << 8;  state++; break;
1995           case 10: cablen |= *p++ << 16; state++; break;
1996           case 11: cablen |= *p++ << 24; state++; break;
1997
1998           /* we don't care about bytes 12-15 */
1999           /* bytes 16-19 are the offset within the cabinet of the filedata */
2000           case 16: foffset  = *p++;       state++; break;
2001           case 17: foffset |= *p++ << 8;  state++; break;
2002           case 18: foffset |= *p++ << 16; state++; break;
2003           case 19: foffset |= *p++ << 24;
2004             /* now we have received 20 bytes of potential cab header. */
2005             /* work out the offset in the file of this potential cabinet */
2006             caboff = offset + (p-pstart) - 20;
2007
2008             /* check that the files offset is less than the alleged length
2009              * of the cabinet, and that the offset + the alleged length are
2010              * 'roughly' within the end of overall file length
2011              */
2012             if ((foffset < cablen) &&
2013                 ((caboff + foffset) < (filelen + 32)) &&
2014                 ((caboff + cablen) < (filelen + 32)) )
2015             {
2016               /* found a potential result - try loading it */
2017               found++;
2018               cab2 =  load_cab_offset(name, caboff);
2019               if (cab2) {
2020                 /* success */
2021                 ok++;
2022
2023                 /* cause the search to restart after this cab's data. */
2024                 offset = caboff + cablen;
2025                 if (offset < cab->filelen) cabinet_seek(cab, offset);
2026                 length = 0;
2027                 p = pend;
2028
2029                 /* link the cab into the list */
2030                 if (linkcab == NULL) firstcab = cab2;
2031                 else linkcab->next = cab2;
2032                 linkcab = cab2;
2033               }
2034             }
2035             state = 0;
2036             break;
2037           default:
2038             p++, state++; break;
2039           }
2040         }
2041       }
2042       cabinet_close(cab);
2043     }
2044     free(cab);
2045   }
2046
2047   /* if there were cabinets that were found but are not ok, point this out */
2048   if (found > ok) {
2049     WARN("%s: found %d bad cabinets\n", debugstr_a(name), found-ok);
2050   }
2051
2052   /* if no cabinets were found, let the user know */
2053   if (!firstcab) {
2054     WARN("%s: not a Microsoft cabinet file.\n", debugstr_a(name));
2055   }
2056   return firstcab;
2057 }
2058
2059 /***********************************************************************
2060  * find_cabinet_file (internal)
2061  *
2062  * tries to find *cabname, from the directory path of origcab, correcting the
2063  * case of *cabname if necessary, If found, writes back to *cabname.
2064  */
2065 void find_cabinet_file(char **cabname, LPCSTR origcab) {
2066
2067   char *tail, *cab, *name, *nextpart, nametmp[MAX_PATH], *filepart;
2068   int found = 0;
2069
2070   TRACE("(*cabname == ^%p, origcab == %s)\n", cabname ? *cabname : NULL, debugstr_a(origcab));
2071
2072   /* ensure we have a cabinet name at all */
2073   if (!(name = *cabname)) {
2074     WARN("no cabinet name at all\n");
2075   }
2076
2077   /* find if there's a directory path in the origcab */
2078   tail = origcab ? max(strrchr(origcab, '/'), strrchr(origcab, '\\')) : NULL;
2079
2080   if ((cab = (char *) malloc(MAX_PATH))) {
2081     /* add the directory path from the original cabinet name */
2082     if (tail) {
2083       memcpy(cab, origcab, tail - origcab);
2084       cab[tail - origcab] = '\0';
2085     } else {
2086       /* default directory path of '.' */
2087       cab[0] = '.';
2088       cab[1] = '\0';
2089     }
2090
2091     do {
2092       TRACE("trying cab == %s", debugstr_a(cab));
2093
2094       /* we don't want null cabinet filenames */
2095       if (name[0] == '\0') {
2096         WARN("null cab name\n");
2097         break;
2098       }
2099
2100       /* if there is a directory component in the cabinet name,
2101        * look for that alone first
2102        */
2103       nextpart = strchr(name, '\\');
2104       if (nextpart) *nextpart = '\0';
2105
2106       found = SearchPathA(cab, name, NULL, MAX_PATH, nametmp, &filepart);
2107
2108       /* if the component was not found, look for it in the current dir */
2109       if (!found) {
2110         found = SearchPathA(".", name, NULL, MAX_PATH, nametmp, &filepart);
2111       }
2112       
2113       if (found) 
2114         TRACE("found: %s\n", debugstr_a(nametmp));
2115       else
2116         TRACE("not found.\n");
2117
2118       /* restore the real name and skip to the next directory component
2119        * or actual cabinet name
2120        */
2121       if (nextpart) *nextpart = '\\', name = &nextpart[1];
2122
2123       /* while there is another directory component, and while we
2124        * successfully found the current component
2125        */
2126     } while (nextpart && found);
2127
2128     /* if we found the cabinet, change the next cabinet's name.
2129      * otherwise, pretend nothing happened
2130      */
2131     if (found) {
2132       free((void *) *cabname);
2133       *cabname = cab;
2134       strncpy(cab, nametmp, found+1);
2135       TRACE("result: %s\n", debugstr_a(cab));
2136     } else {
2137       free((void *) cab);
2138       TRACE("result: nothing\n");
2139     }
2140   }
2141 }
2142
2143 /************************************************************************
2144  * process_files (internal)
2145  *
2146  * this does the tricky job of running through every file in the cabinet,
2147  * including spanning cabinets, and working out which file is in which
2148  * folder in which cabinet. It also throws out the duplicate file entries
2149  * that appear in spanning cabinets. There is memory leakage here because
2150  * those entries are not freed. See the XAD CAB client (function CAB_GetInfo
2151  * in CAB.c) for an implementation of this that correctly frees the discarded
2152  * file entries.
2153  */
2154 struct cab_file *process_files(struct cabinet *basecab) {
2155   struct cabinet *cab;
2156   struct cab_file *outfi = NULL, *linkfi = NULL, *nextfi, *fi, *cfi;
2157   struct cab_folder *fol, *firstfol, *lastfol = NULL, *predfol;
2158   int i, mergeok;
2159
2160   FIXME("(basecab == ^%p): Memory leak.\n", basecab);
2161
2162   for (cab = basecab; cab; cab = cab->nextcab) {
2163     /* firstfol = first folder in this cabinet */
2164     /* lastfol  = last folder in this cabinet */
2165     /* predfol  = last folder in previous cabinet (or NULL if first cabinet) */
2166     predfol = lastfol;
2167     firstfol = cab->folders;
2168     for (lastfol = firstfol; lastfol->next;) lastfol = lastfol->next;
2169     mergeok = 1;
2170
2171     for (fi = cab->files; fi; fi = nextfi) {
2172       i = fi->index;
2173       nextfi = fi->next;
2174
2175       if (i < cffileCONTINUED_FROM_PREV) {
2176         for (fol = firstfol; fol && i--; ) fol = fol->next;
2177         fi->folder = fol; /* NULL if an invalid folder index */
2178       }
2179       else {
2180         /* folder merging */
2181         if (i == cffileCONTINUED_TO_NEXT
2182         ||  i == cffileCONTINUED_PREV_AND_NEXT) {
2183           if (cab->nextcab && !lastfol->contfile) lastfol->contfile = fi;
2184         }
2185
2186         if (i == cffileCONTINUED_FROM_PREV
2187         ||  i == cffileCONTINUED_PREV_AND_NEXT) {
2188           /* these files are to be continued in yet another
2189            * cabinet, don't merge them in just yet */
2190           if (i == cffileCONTINUED_PREV_AND_NEXT) mergeok = 0;
2191
2192           /* only merge once per cabinet */
2193           if (predfol) {
2194             if ((cfi = predfol->contfile)
2195             && (cfi->offset == fi->offset)
2196             && (cfi->length == fi->length)
2197             && (strcmp(cfi->filename, fi->filename) == 0)
2198             && (predfol->comp_type == firstfol->comp_type)) {
2199               /* increase the number of splits */
2200               if ((i = ++(predfol->num_splits)) > CAB_SPLITMAX) {
2201                 mergeok = 0;
2202                 ERR("%s: internal error: CAB_SPLITMAX exceeded. please report this to wine-devel@winehq.org)\n",
2203                     debugstr_a(basecab->filename));
2204               }
2205               else {
2206                 /* copy information across from the merged folder */
2207                 predfol->offset[i] = firstfol->offset[0];
2208                 predfol->cab[i]    = firstfol->cab[0];
2209                 predfol->next      = firstfol->next;
2210                 predfol->contfile  = firstfol->contfile;
2211
2212                 if (firstfol == lastfol) lastfol = predfol;
2213                 firstfol = predfol;
2214                 predfol = NULL; /* don't merge again within this cabinet */
2215               }
2216             }
2217             else {
2218               /* if the folders won't merge, don't add their files */
2219               mergeok = 0;
2220             }
2221           }
2222
2223           if (mergeok) fi->folder = firstfol;
2224         }
2225       }
2226
2227       if (fi->folder) {
2228         if (linkfi) linkfi->next = fi; else outfi = fi;
2229         linkfi = fi;
2230       }
2231     } /* for (fi= .. */
2232   } /* for (cab= ...*/
2233
2234   return outfi;
2235 }
2236
2237 /****************************************************************
2238  * convertUTF (internal)
2239  *
2240  * translate UTF -> ASCII
2241  *
2242  * UTF translates two-byte unicode characters into 1, 2 or 3 bytes.
2243  * %000000000xxxxxxx -> %0xxxxxxx
2244  * %00000xxxxxyyyyyy -> %110xxxxx %10yyyyyy
2245  * %xxxxyyyyyyzzzzzz -> %1110xxxx %10yyyyyy %10zzzzzz
2246  *
2247  * Therefore, the inverse is as follows:
2248  * First char:
2249  *  0x00 - 0x7F = one byte char
2250  *  0x80 - 0xBF = invalid
2251  *  0xC0 - 0xDF = 2 byte char (next char only 0x80-0xBF is valid)
2252  *  0xE0 - 0xEF = 3 byte char (next 2 chars only 0x80-0xBF is valid)
2253  *  0xF0 - 0xFF = invalid
2254  * 
2255  * FIXME: use a winapi to do this
2256  */
2257 int convertUTF(cab_UBYTE *in) {
2258   cab_UBYTE c, *out = in, *end = in + strlen((char *) in) + 1;
2259   cab_ULONG x;
2260
2261   do {
2262     /* read unicode character */
2263     if ((c = *in++) < 0x80) x = c;
2264     else {
2265       if (c < 0xC0) return 0;
2266       else if (c < 0xE0) {
2267         x = (c & 0x1F) << 6;
2268         if ((c = *in++) < 0x80 || c > 0xBF) return 0; else x |= (c & 0x3F);
2269       }
2270       else if (c < 0xF0) {
2271         x = (c & 0xF) << 12;
2272         if ((c = *in++) < 0x80 || c > 0xBF) return 0; else x |= (c & 0x3F)<<6;
2273         if ((c = *in++) < 0x80 || c > 0xBF) return 0; else x |= (c & 0x3F);
2274       }
2275       else return 0;
2276     }
2277
2278     /* terrible unicode -> ASCII conversion */
2279     if (x > 127) x = '_';
2280
2281     if (in > end) return 0; /* just in case */
2282   } while ((*out++ = (cab_UBYTE) x));
2283   return 1;
2284 }
2285
2286 /****************************************************
2287  * NONEdecompress (internal)
2288  */
2289 int NONEdecompress(int inlen, int outlen, cab_decomp_state *decomp_state)
2290 {
2291   if (inlen != outlen) return DECR_ILLEGALDATA;
2292   memcpy(CAB(outbuf), CAB(inbuf), (size_t) inlen);
2293   return DECR_OK;
2294 }
2295
2296 /**************************************************
2297  * checksum (internal)
2298  */
2299 cab_ULONG checksum(cab_UBYTE *data, cab_UWORD bytes, cab_ULONG csum) {
2300   int len;
2301   cab_ULONG ul = 0;
2302
2303   for (len = bytes >> 2; len--; data += 4) {
2304     csum ^= ((data[0]) | (data[1]<<8) | (data[2]<<16) | (data[3]<<24));
2305   }
2306
2307   switch (bytes & 3) {
2308   case 3: ul |= *data++ << 16;
2309   case 2: ul |= *data++ <<  8;
2310   case 1: ul |= *data;
2311   }
2312   csum ^= ul;
2313
2314   return csum;
2315 }
2316
2317 /**********************************************************
2318  * decompress (internal)
2319  */
2320 int decompress(struct cab_file *fi, int savemode, int fix, cab_decomp_state *decomp_state)
2321 {
2322   cab_ULONG bytes = savemode ? fi->length : fi->offset - CAB(offset);
2323   struct cabinet *cab = CAB(current)->cab[CAB(split)];
2324   cab_UBYTE buf[cfdata_SIZEOF], *data;
2325   cab_UWORD inlen, len, outlen, cando;
2326   cab_ULONG cksum;
2327   cab_LONG err;
2328
2329   TRACE("(fi == ^%p, savemode == %d, fix == %d)\n", fi, savemode, fix);
2330
2331   while (bytes > 0) {
2332     /* cando = the max number of bytes we can do */
2333     cando = CAB(outlen);
2334     if (cando > bytes) cando = bytes;
2335
2336     /* if cando != 0 */
2337     if (cando && savemode)
2338       file_write(fi, CAB(outpos), cando);
2339
2340     CAB(outpos) += cando;
2341     CAB(outlen) -= cando;
2342     bytes -= cando; if (!bytes) break;
2343
2344     /* we only get here if we emptied the output buffer */
2345
2346     /* read data header + data */
2347     inlen = outlen = 0;
2348     while (outlen == 0) {
2349       /* read the block header, skip the reserved part */
2350       if (!cabinet_read(cab, buf, cfdata_SIZEOF)) return DECR_INPUT;
2351       cabinet_skip(cab, cab->block_resv);
2352
2353       /* we shouldn't get blocks over CAB_INPUTMAX in size */
2354       data = CAB(inbuf) + inlen;
2355       len = EndGetI16(buf+cfdata_CompressedSize);
2356       inlen += len;
2357       if (inlen > CAB_INPUTMAX) return DECR_INPUT;
2358       if (!cabinet_read(cab, data, len)) return DECR_INPUT;
2359
2360       /* clear two bytes after read-in data */
2361       data[len+1] = data[len+2] = 0;
2362
2363       /* perform checksum test on the block (if one is stored) */
2364       cksum = EndGetI32(buf+cfdata_CheckSum);
2365       if (cksum && cksum != checksum(buf+4, 4, checksum(data, len, 0))) {
2366         /* checksum is wrong */
2367         if (fix && ((fi->folder->comp_type & cffoldCOMPTYPE_MASK)
2368                     == cffoldCOMPTYPE_MSZIP))
2369         {
2370           WARN("%s: checksum failed\n", debugstr_a(fi->filename)); 
2371         }
2372         else {
2373           return DECR_CHECKSUM;
2374         }
2375       }
2376
2377       /* outlen=0 means this block was part of a split block */
2378       outlen = EndGetI16(buf+cfdata_UncompressedSize);
2379       if (outlen == 0) {
2380         cabinet_close(cab);
2381         cab = CAB(current)->cab[++CAB(split)];
2382         if (!cabinet_open(cab)) return DECR_INPUT;
2383         cabinet_seek(cab, CAB(current)->offset[CAB(split)]);
2384       }
2385     }
2386
2387     /* decompress block */
2388     if ((err = CAB(decompress)(inlen, outlen, decomp_state))) {
2389       if (fix && ((fi->folder->comp_type & cffoldCOMPTYPE_MASK)
2390                   == cffoldCOMPTYPE_MSZIP))
2391       {
2392         ERR("%s: failed decrunching block\n", debugstr_a(fi->filename)); 
2393       }
2394       else {
2395         return err;
2396       }
2397     }
2398     CAB(outlen) = outlen;
2399     CAB(outpos) = CAB(outbuf);
2400   }
2401
2402   return DECR_OK;
2403 }
2404
2405 /****************************************************************
2406  * extract_file (internal)
2407  *
2408  * workhorse to extract a particular file from a cab
2409  */
2410 void extract_file(struct cab_file *fi, int lower, int fix, LPCSTR dir, cab_decomp_state *decomp_state)
2411 {
2412   struct cab_folder *fol = fi->folder, *oldfol = CAB(current);
2413   cab_LONG err = DECR_OK;
2414
2415   TRACE("(fi == ^%p, lower == %d, fix == %d, dir == %s)\n", fi, lower, fix, debugstr_a(dir));
2416
2417   /* is a change of folder needed? do we need to reset the current folder? */
2418   if (fol != oldfol || fi->offset < CAB(offset)) {
2419     cab_UWORD comptype = fol->comp_type;
2420     int ct1 = comptype & cffoldCOMPTYPE_MASK;
2421     int ct2 = oldfol ? (oldfol->comp_type & cffoldCOMPTYPE_MASK) : 0;
2422
2423     /* if the archiver has changed, call the old archiver's free() function */
2424     if (ct1 != ct2) {
2425       switch (ct2) {
2426       case cffoldCOMPTYPE_LZX:
2427         if (LZX(window)) {
2428           free(LZX(window));
2429           LZX(window) = NULL;
2430         }
2431         break;
2432       case cffoldCOMPTYPE_QUANTUM:
2433         if (QTM(window)) {
2434           free(QTM(window));
2435           QTM(window) = NULL;
2436         }
2437         break;
2438       }
2439     }
2440
2441     switch (ct1) {
2442     case cffoldCOMPTYPE_NONE:
2443       CAB(decompress) = NONEdecompress;
2444       break;
2445
2446     case cffoldCOMPTYPE_MSZIP:
2447       CAB(decompress) = ZIPdecompress;
2448       break;
2449
2450     case cffoldCOMPTYPE_QUANTUM:
2451       CAB(decompress) = QTMdecompress;
2452       err = QTMinit((comptype >> 8) & 0x1f, (comptype >> 4) & 0xF, decomp_state);
2453       break;
2454
2455     case cffoldCOMPTYPE_LZX:
2456       CAB(decompress) = LZXdecompress;
2457       err = LZXinit((comptype >> 8) & 0x1f, decomp_state);
2458       break;
2459
2460     default:
2461       err = DECR_DATAFORMAT;
2462     }
2463     if (err) goto exit_handler;
2464
2465     /* initialisation OK, set current folder and reset offset */
2466     if (oldfol) cabinet_close(oldfol->cab[CAB(split)]);
2467     if (!cabinet_open(fol->cab[0])) goto exit_handler;
2468     cabinet_seek(fol->cab[0], fol->offset[0]);
2469     CAB(current) = fol;
2470     CAB(offset) = 0;
2471     CAB(outlen) = 0; /* discard existing block */
2472     CAB(split)  = 0;
2473   }
2474
2475   if (fi->offset > CAB(offset)) {
2476     /* decode bytes and send them to /dev/null */
2477     if ((err = decompress(fi, 0, fix, decomp_state))) goto exit_handler;
2478     CAB(offset) = fi->offset;
2479   }
2480   
2481   if (!file_open(fi, lower, dir)) return;
2482   err = decompress(fi, 1, fix, decomp_state);
2483   if (err) CAB(current) = NULL; else CAB(offset) += fi->length;
2484   file_close(fi);
2485
2486 exit_handler:
2487   if (err) {
2488     char *errmsg, *cabname;
2489     switch (err) {
2490     case DECR_NOMEMORY:
2491       errmsg = "out of memory!\n"; break;
2492     case DECR_ILLEGALDATA:
2493       errmsg = "%s: illegal or corrupt data\n"; break;
2494     case DECR_DATAFORMAT:
2495       errmsg = "%s: unsupported data format\n"; break;
2496     case DECR_CHECKSUM:
2497       errmsg = "%s: checksum error\n"; break;
2498     case DECR_INPUT:
2499       errmsg = "%s: input error\n"; break;
2500     case DECR_OUTPUT:
2501       errmsg = "%s: output error\n"; break;
2502     default:
2503       errmsg = "%s: unknown error (BUG)\n";
2504     }
2505
2506     if (CAB(current)) {
2507       cabname = (char *) (CAB(current)->cab[CAB(split)]->filename);
2508     }
2509     else {
2510       cabname = (char *) (fi->folder->cab[0]->filename);
2511     }
2512
2513     ERR(errmsg, cabname);
2514   }
2515 }
2516
2517 /*********************************************************
2518  * print_fileinfo (internal)
2519  */
2520 void print_fileinfo(struct cab_file *fi) {
2521   int d = fi->date, t = fi->time;
2522   char *fname = NULL;
2523
2524   if (fi->attribs & cffile_A_NAME_IS_UTF) {
2525     fname = malloc(strlen(fi->filename) + 1);
2526     if (fname) {
2527       strcpy(fname, fi->filename);
2528       convertUTF((cab_UBYTE *) fname);
2529     }
2530   }
2531
2532   TRACE("%9u | %02d.%02d.%04d %02d:%02d:%02d | %s\n",
2533     fi->length, 
2534     d & 0x1f, (d>>5) & 0xf, (d>>9) + 1980,
2535     t >> 11, (t>>5) & 0x3f, (t << 1) & 0x3e,
2536     fname ? fname : fi->filename
2537   );
2538
2539   if (fname) free(fname);
2540 }
2541
2542 /****************************************************************************
2543  * process_cabinet (internal) 
2544  *
2545  * called to simply "extract" a cabinet file.  Will find every cabinet file
2546  * in that file, search for every chained cabinet attached to those cabinets,
2547  * and will either extract the cabinets, or ? (call a callback?)
2548  *
2549  * PARAMS
2550  *   cabname [I] name of the cabinet file to extract
2551  *   dir     [I] directory to extract to
2552  *   fix     [I] attempt to process broken cabinets
2553  *   lower   [I] ? (lower case something or other?)
2554  *
2555  * RETURNS
2556  *   Success: TRUE
2557  *   Failure: FALSE
2558  */
2559 BOOL process_cabinet(LPCSTR cabname, LPCSTR dir, BOOL fix, BOOL lower)
2560 {
2561   struct cabinet *basecab, *cab, *cab1, *cab2;
2562   struct cab_file *filelist, *fi;
2563
2564   /* The first result of a search will be returned, and
2565    * the remaining results will be chained to it via the cab->next structure
2566    * member.
2567    */
2568   cab_UBYTE search_buf[CAB_SEARCH_SIZE];
2569
2570   cab_decomp_state decomp_state_local;
2571   cab_decomp_state *decomp_state = &decomp_state_local;
2572
2573   /* has the list-mode header been seen before? */
2574   int viewhdr = 0;
2575
2576   ZeroMemory(decomp_state, sizeof(cab_decomp_state));
2577
2578   TRACE("Extract %s\n", debugstr_a(cabname));
2579
2580   /* load the file requested */
2581   basecab = find_cabs_in_file(cabname, search_buf);
2582   if (!basecab) return FALSE;
2583
2584   /* iterate over all cabinets found in that file */
2585   for (cab = basecab; cab; cab=cab->next) {
2586
2587     /* bi-directionally load any spanning cabinets -- backwards */
2588     for (cab1 = cab; cab1->flags & cfheadPREV_CABINET; cab1 = cab1->prevcab) {
2589       TRACE("%s: extends backwards to %s (%s)\n", debugstr_a(cabname),
2590             debugstr_a(cab1->prevname), debugstr_a(cab1->previnfo));
2591       find_cabinet_file(&(cab1->prevname), cabname);
2592       if (!(cab1->prevcab = load_cab_offset(cab1->prevname, 0))) {
2593         ERR("%s: can't read previous cabinet %s\n", debugstr_a(cabname), debugstr_a(cab1->prevname));
2594         break;
2595       }
2596       cab1->prevcab->nextcab = cab1;
2597     }
2598
2599     /* bi-directionally load any spanning cabinets -- forwards */
2600     for (cab2 = cab; cab2->flags & cfheadNEXT_CABINET; cab2 = cab2->nextcab) {
2601       TRACE("%s: extends to %s (%s)\n", debugstr_a(cabname),
2602             debugstr_a(cab2->nextname), debugstr_a(cab2->nextinfo));
2603       find_cabinet_file(&(cab2->nextname), cabname);
2604       if (!(cab2->nextcab = load_cab_offset(cab2->nextname, 0))) {
2605         ERR("%s: can't read next cabinet %s\n", debugstr_a(cabname), debugstr_a(cab2->nextname));
2606         break;
2607       }
2608       cab2->nextcab->prevcab = cab2;
2609     }
2610
2611     filelist = process_files(cab1);
2612     CAB(current) = NULL;
2613
2614     if (!viewhdr) {
2615       TRACE("File size | Date       Time     | Name\n");
2616       TRACE("----------+---------------------+-------------\n");
2617       viewhdr = 1;
2618     }
2619     for (fi = filelist; fi; fi = fi->next)
2620         print_fileinfo(fi);
2621     TRACE("Beginning Extraction...\n");
2622     for (fi = filelist; fi; fi = fi->next) {
2623         TRACE("  extracting: %s\n", debugstr_a(fi->filename));
2624         extract_file(fi, lower, fix, dir, decomp_state);
2625     }
2626   }
2627
2628   TRACE("Finished processing cabinet.\n");
2629
2630   return TRUE;
2631 }