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