2 * File Decompression Interface
4 * Copyright 2000-2002 Stuart Caie
5 * Copyright 2002 Patrik Stridvall
6 * Copyright 2003 Greg Turner
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.
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.
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
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.
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
39 * Wine does not implement the AFAIK undocumented "enumerate" callback during
40 * FDICopy. It is implemented in Windows and therefore worth investigating...
42 * Lots of pointers flying around here... am I leaking RAM?
46 * Probably, I need to weed out some dead code-paths.
50 * The fdintNEXT_CABINET callbacks are probably not working quite as they should.
51 * There are several FIXME's in the source describing some of the deficiencies in
52 * some detail. Additionally, we do not do a very good job of returning the right
53 * error codes to this callback.
55 * FDICopy and fdi_decomp are incomprehensibly large; separating these into smaller
56 * functions would be nice.
72 #include "wine/debug.h"
74 WINE_DEFAULT_DEBUG_CHANNEL(cabinet
);
79 struct fdi_file
*next
; /* next file in sequence */
80 LPCSTR filename
; /* output name of file */
81 int fh
; /* open file handle or NULL */
82 cab_ULONG length
; /* uncompressed length of file */
83 cab_ULONG offset
; /* uncompressed offset in folder */
84 cab_UWORD index
; /* magic index number of folder */
85 cab_UWORD time
, date
, attribs
; /* MS-DOS time/date/attributes */
86 BOOL oppressed
; /* never to be processed */
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 */
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
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
;
114 * ugh, well, this ended up being pretty damn silly...
115 * now that I've conceded to build equivalent structures to struct cab.*,
116 * I should have just used those, or, better yet, unified the two... sue me.
117 * (Note to Microsoft: That's a joke. Please /don't/ actually sue me! -gmt).
118 * Nevertheless, I've come this far, it works, so I'm not gonna change it
119 * for now. This implementation has significant semantic differences anyhow.
122 typedef struct fdi_cds_fwd
{
123 void *hfdi
; /* the hfdi we are using */
124 int filehf
, cabhf
; /* file handle we are using */
125 struct fdi_folder
*current
; /* current folder we're extracting from */
126 cab_ULONG offset
; /* uncompressed offset within folder */
127 cab_UBYTE
*outpos
; /* (high level) start of data to use up */
128 cab_UWORD outlen
; /* (high level) amount of data to use up */
129 int (*decompress
)(int, int, struct fdi_cds_fwd
*); /* chosen compress fn */
130 cab_UBYTE inbuf
[CAB_INPUTMAX
+2]; /* +2 for lzx bitbuffer overflows! */
131 cab_UBYTE outbuf
[CAB_BLOCKMAX
];
137 /* some temp variables for use during decompression */
138 cab_UBYTE q_length_base
[27], q_length_extra
[27], q_extra_bits
[42];
139 cab_ULONG q_position_base
[42];
140 cab_ULONG lzx_position_base
[51];
141 cab_UBYTE extra_bits
[51];
142 USHORT setID
; /* Cabinet set ID */
143 USHORT iCabinet
; /* Cabinet number in set (0 based) */
144 struct fdi_cds_fwd
*decomp_cab
;
146 struct fdi_folder
*firstfol
;
147 struct fdi_file
*firstfile
;
148 struct fdi_cds_fwd
*next
;
151 /****************************************************************
152 * QTMupdatemodel (internal)
154 void QTMupdatemodel(struct QTMmodel
*model
, int sym
) {
155 struct QTMmodelsym temp
;
158 for (i
= 0; i
< sym
; i
++) model
->syms
[i
].cumfreq
+= 8;
160 if (model
->syms
[0].cumfreq
> 3800) {
161 if (--model
->shiftsleft
) {
162 for (i
= model
->entries
- 1; i
>= 0; i
--) {
163 /* -1, not -2; the 0 entry saves this */
164 model
->syms
[i
].cumfreq
>>= 1;
165 if (model
->syms
[i
].cumfreq
<= model
->syms
[i
+1].cumfreq
) {
166 model
->syms
[i
].cumfreq
= model
->syms
[i
+1].cumfreq
+ 1;
171 model
->shiftsleft
= 50;
172 for (i
= 0; i
< model
->entries
; i
++) {
173 /* no -1, want to include the 0 entry */
174 /* this converts cumfreqs into frequencies, then shifts right */
175 model
->syms
[i
].cumfreq
-= model
->syms
[i
+1].cumfreq
;
176 model
->syms
[i
].cumfreq
++; /* avoid losing things entirely */
177 model
->syms
[i
].cumfreq
>>= 1;
180 /* now sort by frequencies, decreasing order -- this must be an
181 * inplace selection sort, or a sort with the same (in)stability
184 for (i
= 0; i
< model
->entries
- 1; i
++) {
185 for (j
= i
+ 1; j
< model
->entries
; j
++) {
186 if (model
->syms
[i
].cumfreq
< model
->syms
[j
].cumfreq
) {
187 temp
= model
->syms
[i
];
188 model
->syms
[i
] = model
->syms
[j
];
189 model
->syms
[j
] = temp
;
194 /* then convert frequencies back to cumfreq */
195 for (i
= model
->entries
- 1; i
>= 0; i
--) {
196 model
->syms
[i
].cumfreq
+= model
->syms
[i
+1].cumfreq
;
198 /* then update the other part of the table */
199 for (i
= 0; i
< model
->entries
; i
++) {
200 model
->tabloc
[model
->syms
[i
].sym
] = i
;
206 /*************************************************************************
207 * make_decode_table (internal)
209 * This function was coded by David Tritscher. It builds a fast huffman
210 * decoding table out of just a canonical huffman code lengths table.
213 * nsyms: total number of symbols in this huffman tree.
214 * nbits: any symbols with a code length of nbits or less can be decoded
215 * in one lookup of the table.
216 * length: A table to get code lengths from [0 to syms-1]
217 * table: The table to fill up with decoded symbols and pointers.
223 int make_decode_table(cab_ULONG nsyms
, cab_ULONG nbits
, cab_UBYTE
*length
, cab_UWORD
*table
) {
224 register cab_UWORD sym
;
225 register cab_ULONG leaf
;
226 register cab_UBYTE bit_num
= 1;
228 cab_ULONG pos
= 0; /* the current position in the decode table */
229 cab_ULONG table_mask
= 1 << nbits
;
230 cab_ULONG bit_mask
= table_mask
>> 1; /* don't do 0 length codes */
231 cab_ULONG next_symbol
= bit_mask
; /* base of allocation for long codes */
233 /* fill entries for codes short enough for a direct mapping */
234 while (bit_num
<= nbits
) {
235 for (sym
= 0; sym
< nsyms
; sym
++) {
236 if (length
[sym
] == bit_num
) {
239 if((pos
+= bit_mask
) > table_mask
) return 1; /* table overrun */
241 /* fill all possible lookups of this symbol with the symbol itself */
243 while (fill
-- > 0) table
[leaf
++] = sym
;
250 /* if there are any codes longer than nbits */
251 if (pos
!= table_mask
) {
252 /* clear the remainder of the table */
253 for (sym
= pos
; sym
< table_mask
; sym
++) table
[sym
] = 0;
255 /* give ourselves room for codes to grow by up to 16 more bits */
260 while (bit_num
<= 16) {
261 for (sym
= 0; sym
< nsyms
; sym
++) {
262 if (length
[sym
] == bit_num
) {
264 for (fill
= 0; fill
< bit_num
- nbits
; fill
++) {
265 /* if this path hasn't been taken yet, 'allocate' two entries */
266 if (table
[leaf
] == 0) {
267 table
[(next_symbol
<< 1)] = 0;
268 table
[(next_symbol
<< 1) + 1] = 0;
269 table
[leaf
] = next_symbol
++;
271 /* follow the path and select either left or right for next bit */
272 leaf
= table
[leaf
] << 1;
273 if ((pos
>> (15-fill
)) & 1) leaf
++;
277 if ((pos
+= bit_mask
) > table_mask
) return 1; /* table overflow */
286 if (pos
== table_mask
) return 0;
288 /* either erroneous table, or all elements are 0 - let's find out. */
289 for (sym
= 0; sym
< nsyms
; sym
++) if (length
[sym
]) return 1;
293 /*************************************************************************
294 * checksum (internal)
296 cab_ULONG
checksum(cab_UBYTE
*data
, cab_UWORD bytes
, cab_ULONG csum
) {
300 for (len
= bytes
>> 2; len
--; data
+= 4) {
301 csum
^= ((data
[0]) | (data
[1]<<8) | (data
[2]<<16) | (data
[3]<<24));
305 case 3: ul
|= *data
++ << 16;
306 case 2: ul
|= *data
++ << 8;
314 /***********************************************************************
315 * FDICreate (CABINET.20)
317 * Provided with several callbacks (all of them are mandatory),
318 * returns a handle which can be used to perform operations
322 * pfnalloc [I] A pointer to a function which allocates ram. Uses
323 * the same interface as malloc.
324 * pfnfree [I] A pointer to a function which frees ram. Uses the
325 * same interface as free.
326 * pfnopen [I] A pointer to a function which opens a file. Uses
327 * the same interface as _open.
328 * pfnread [I] A pointer to a function which reads from a file into
329 * a caller-provided buffer. Uses the same interface
331 * pfnwrite [I] A pointer to a function which writes to a file from
332 * a caller-provided buffer. Uses the same interface
334 * pfnclose [I] A pointer to a function which closes a file handle.
335 * Uses the same interface as _close.
336 * pfnseek [I] A pointer to a function which seeks in a file.
337 * Uses the same interface as _lseek.
338 * cpuType [I] The type of CPU; ignored in wine (recommended value:
339 * cpuUNKNOWN, aka -1).
340 * perf [IO] A pointer to an ERF structure. When FDICreate
341 * returns an error condition, error information may
342 * be found here as well as from GetLastError.
345 * On success, returns an FDI handle of type HFDI.
346 * On failure, the NULL file handle is returned. Error
347 * info can be retrieved from perf.
353 HFDI __cdecl
FDICreate(
366 TRACE("(pfnalloc == ^%p, pfnfree == ^%p, pfnopen == ^%p, pfnread == ^%p, pfnwrite == ^%p, "
367 "pfnclose == ^%p, pfnseek == ^%p, cpuType == %d, perf == ^%p)\n",
368 pfnalloc
, pfnfree
, pfnopen
, pfnread
, pfnwrite
, pfnclose
, pfnseek
,
371 if ((!pfnalloc
) || (!pfnfree
)) {
372 perf
->erfOper
= FDIERROR_NONE
;
373 perf
->erfType
= ERROR_BAD_ARGUMENTS
;
376 SetLastError(ERROR_BAD_ARGUMENTS
);
380 if (!((rv
= ((HFDI
) (*pfnalloc
)(sizeof(FDI_Int
)))))) {
381 perf
->erfOper
= FDIERROR_ALLOC_FAIL
;
382 perf
->erfType
= ERROR_NOT_ENOUGH_MEMORY
;
385 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
389 PFDI_INT(rv
)->FDI_Intmagic
= FDI_INT_MAGIC
;
390 PFDI_INT(rv
)->pfnalloc
= pfnalloc
;
391 PFDI_INT(rv
)->pfnfree
= pfnfree
;
392 PFDI_INT(rv
)->pfnopen
= pfnopen
;
393 PFDI_INT(rv
)->pfnread
= pfnread
;
394 PFDI_INT(rv
)->pfnwrite
= pfnwrite
;
395 PFDI_INT(rv
)->pfnclose
= pfnclose
;
396 PFDI_INT(rv
)->pfnseek
= pfnseek
;
397 /* no-brainer: we ignore the cpu type; this is only used
398 for the 16-bit versions in Windows anyhow... */
399 PFDI_INT(rv
)->perf
= perf
;
404 /*******************************************************************
405 * FDI_getoffset (internal)
407 * returns the file pointer position of a file handle.
409 static long FDI_getoffset(HFDI hfdi
, INT_PTR hf
)
411 return PFDI_SEEK(hfdi
, hf
, 0L, SEEK_CUR
);
414 /**********************************************************************
415 * FDI_realloc (internal)
417 * we can't use _msize; the user might not be using malloc, so we require
418 * an explicit specification of the previous size. inefficient.
420 static void *FDI_realloc(HFDI hfdi
, void *mem
, size_t prevsize
, size_t newsize
)
424 size_t copysize
= (prevsize
< newsize
) ? prevsize
: newsize
;
425 if (prevsize
== newsize
) return mem
;
426 rslt
= PFDI_ALLOC(hfdi
, newsize
);
428 for (irslt
= (char *)rslt
, imem
= (char *)mem
; (copysize
); copysize
--)
430 PFDI_FREE(hfdi
, mem
);
434 /**********************************************************************
435 * FDI_read_string (internal)
437 * allocate and read an arbitrarily long string from the cabinet
439 static char *FDI_read_string(HFDI hfdi
, INT_PTR hf
, long cabsize
)
443 base
= FDI_getoffset(hfdi
, hf
),
444 maxlen
= cabsize
- base
;
447 cab_UBYTE
*buf
= NULL
;
449 TRACE("(hfdi == ^%p, hf == %d)\n", hfdi
, hf
);
452 if (len
> maxlen
) len
= maxlen
;
453 if (!(buf
= FDI_realloc(hfdi
, buf
, oldlen
, len
))) break;
455 if (!PFDI_READ(hfdi
, hf
, buf
, len
)) break;
457 /* search for a null terminator in what we've just read */
458 for (i
=0; i
< len
; i
++) {
459 if (!buf
[i
]) {ok
=TRUE
; break;}
464 ERR("cabinet is truncated\n");
468 PFDI_SEEK(hfdi
, hf
, base
, SEEK_SET
);
474 PFDI_FREE(hfdi
, buf
);
476 ERR("out of memory!\n");
480 /* otherwise, set the stream to just after the string and return */
481 PFDI_SEEK(hfdi
, hf
, base
+ ((cab_off_t
) strlen((char *) buf
)) + 1, SEEK_SET
);
486 /******************************************************************
487 * FDI_read_entries (internal)
489 * process the cabinet header in the style of FDIIsCabinet, but
490 * without the sanity checks (and bug)
492 static BOOL
FDI_read_entries(
495 PFDICABINETINFO pfdici
,
496 PMORE_ISCAB_INFO pmii
)
498 int num_folders
, num_files
, header_resv
, folder_resv
= 0;
499 LONG base_offset
, cabsize
;
500 USHORT setid
, cabidx
, flags
;
501 cab_UBYTE buf
[64], block_resv
;
502 char *prevname
= NULL
, *previnfo
= NULL
, *nextname
= NULL
, *nextinfo
= NULL
;
504 TRACE("(hfdi == ^%p, hf == %d, pfdici == ^%p)\n", hfdi
, hf
, pfdici
);
507 * FIXME: I just noticed that I am memorizing the initial file pointer
508 * offset and restoring it before reading in the rest of the header
509 * information in the cabinet. Perhaps that's correct -- that is, perhaps
510 * this API is supposed to support "streaming" cabinets which are embedded
511 * in other files, or cabinets which begin at file offsets other than zero.
512 * Otherwise, I should instead go to the absolute beginning of the file.
513 * (Either way, the semantics of wine's FDICopy require me to leave the
514 * file pointer where it is afterwards -- If Windows does not do so, we
515 * ought to duplicate the native behavior in the FDIIsCabinet API, not here.
517 * So, the answer lies in Windows; will native cabinet.dll recognize a
518 * cabinet "file" embedded in another file? Note that cabextract.c does
519 * support this, which implies that Microsoft's might. I haven't tried it
520 * yet so I don't know. ATM, most of wine's FDI cabinet routines (except
521 * this one) would not work in this way. To fix it, we could just make the
522 * various references to absolute file positions in the code relative to an
523 * initial "beginning" offset. Because the FDICopy API doesn't take a
524 * file-handle like this one, we would therein need to search through the
525 * file for the beginning of the cabinet (as we also do in cabextract.c).
526 * Note that this limits us to a maximum of one cabinet per. file: the first.
528 * So, in summary: either the code below is wrong, or the rest of fdi.c is
529 * wrong... I cannot imagine that both are correct ;) One of these flaws
530 * should be fixed after determining the behavior on Windows. We ought
531 * to check both FDIIsCabinet and FDICopy for the right behavior.
536 /* get basic offset & size info */
537 base_offset
= FDI_getoffset(hfdi
, hf
);
539 if (PFDI_SEEK(hfdi
, hf
, 0, SEEK_END
) == -1) {
541 PFDI_INT(hfdi
)->perf
->erfOper
= FDIERROR_NOT_A_CABINET
;
542 PFDI_INT(hfdi
)->perf
->erfType
= 0;
543 PFDI_INT(hfdi
)->perf
->fError
= TRUE
;
548 cabsize
= FDI_getoffset(hfdi
, hf
);
550 if ((cabsize
== -1) || (base_offset
== -1) ||
551 ( PFDI_SEEK(hfdi
, hf
, base_offset
, SEEK_SET
) == -1 )) {
553 PFDI_INT(hfdi
)->perf
->erfOper
= FDIERROR_NOT_A_CABINET
;
554 PFDI_INT(hfdi
)->perf
->erfType
= 0;
555 PFDI_INT(hfdi
)->perf
->fError
= TRUE
;
560 /* read in the CFHEADER */
561 if (PFDI_READ(hfdi
, hf
, buf
, cfhead_SIZEOF
) != cfhead_SIZEOF
) {
563 PFDI_INT(hfdi
)->perf
->erfOper
= FDIERROR_NOT_A_CABINET
;
564 PFDI_INT(hfdi
)->perf
->erfType
= 0;
565 PFDI_INT(hfdi
)->perf
->fError
= TRUE
;
570 /* check basic MSCF signature */
571 if (EndGetI32(buf
+cfhead_Signature
) != 0x4643534d) {
573 PFDI_INT(hfdi
)->perf
->erfOper
= FDIERROR_NOT_A_CABINET
;
574 PFDI_INT(hfdi
)->perf
->erfType
= 0;
575 PFDI_INT(hfdi
)->perf
->fError
= TRUE
;
580 /* get the number of folders */
581 num_folders
= EndGetI16(buf
+cfhead_NumFolders
);
582 if (num_folders
== 0) {
583 /* PONDERME: is this really invalid? */
584 WARN("weird cabinet detect failure: no folders in cabinet\n");
586 PFDI_INT(hfdi
)->perf
->erfOper
= FDIERROR_NOT_A_CABINET
;
587 PFDI_INT(hfdi
)->perf
->erfType
= 0;
588 PFDI_INT(hfdi
)->perf
->fError
= TRUE
;
593 /* get the number of files */
594 num_files
= EndGetI16(buf
+cfhead_NumFiles
);
595 if (num_files
== 0) {
596 /* PONDERME: is this really invalid? */
597 WARN("weird cabinet detect failure: no files in cabinet\n");
599 PFDI_INT(hfdi
)->perf
->erfOper
= FDIERROR_NOT_A_CABINET
;
600 PFDI_INT(hfdi
)->perf
->erfType
= 0;
601 PFDI_INT(hfdi
)->perf
->fError
= TRUE
;
607 setid
= EndGetI16(buf
+cfhead_SetID
);
609 /* cabinet (set) index */
610 cabidx
= EndGetI16(buf
+cfhead_CabinetIndex
);
612 /* check the header revision */
613 if ((buf
[cfhead_MajorVersion
] > 1) ||
614 (buf
[cfhead_MajorVersion
] == 1 && buf
[cfhead_MinorVersion
] > 3))
616 WARN("cabinet format version > 1.3\n");
618 PFDI_INT(hfdi
)->perf
->erfOper
= FDIERROR_UNKNOWN_CABINET_VERSION
;
619 PFDI_INT(hfdi
)->perf
->erfType
= 0; /* ? */
620 PFDI_INT(hfdi
)->perf
->fError
= TRUE
;
625 /* pull the flags out */
626 flags
= EndGetI16(buf
+cfhead_Flags
);
628 /* read the reserved-sizes part of header, if present */
629 if (flags
& cfheadRESERVE_PRESENT
) {
630 if (PFDI_READ(hfdi
, hf
, buf
, cfheadext_SIZEOF
) != cfheadext_SIZEOF
) {
631 ERR("bunk reserve-sizes?\n");
633 PFDI_INT(hfdi
)->perf
->erfOper
= FDIERROR_CORRUPT_CABINET
;
634 PFDI_INT(hfdi
)->perf
->erfType
= 0; /* ? */
635 PFDI_INT(hfdi
)->perf
->fError
= TRUE
;
640 header_resv
= EndGetI16(buf
+cfheadext_HeaderReserved
);
641 if (pmii
) pmii
->header_resv
= header_resv
;
642 folder_resv
= buf
[cfheadext_FolderReserved
];
643 if (pmii
) pmii
->folder_resv
= folder_resv
;
644 block_resv
= buf
[cfheadext_DataReserved
];
645 if (pmii
) pmii
->block_resv
= block_resv
;
647 if (header_resv
> 60000) {
648 WARN("WARNING; header reserved space > 60000\n");
651 /* skip the reserved header */
652 if ((header_resv
) && (PFDI_SEEK(hfdi
, hf
, header_resv
, SEEK_CUR
) == -1)) {
653 ERR("seek failure: header_resv\n");
655 PFDI_INT(hfdi
)->perf
->erfOper
= FDIERROR_CORRUPT_CABINET
;
656 PFDI_INT(hfdi
)->perf
->erfType
= 0; /* ? */
657 PFDI_INT(hfdi
)->perf
->fError
= TRUE
;
663 if (flags
& cfheadPREV_CABINET
) {
664 prevname
= FDI_read_string(hfdi
, hf
, cabsize
);
667 PFDI_INT(hfdi
)->perf
->erfOper
= FDIERROR_CORRUPT_CABINET
;
668 PFDI_INT(hfdi
)->perf
->erfType
= 0; /* ? */
669 PFDI_INT(hfdi
)->perf
->fError
= TRUE
;
674 pmii
->prevname
= prevname
;
676 PFDI_FREE(hfdi
, prevname
);
677 previnfo
= FDI_read_string(hfdi
, hf
, cabsize
);
680 pmii
->previnfo
= previnfo
;
682 PFDI_FREE(hfdi
, previnfo
);
686 if (flags
& cfheadNEXT_CABINET
) {
688 pmii
->hasnext
= TRUE
;
689 nextname
= FDI_read_string(hfdi
, hf
, cabsize
);
691 if ((flags
& cfheadPREV_CABINET
) && pmii
) {
692 if (pmii
->prevname
) PFDI_FREE(hfdi
, prevname
);
693 if (pmii
->previnfo
) PFDI_FREE(hfdi
, previnfo
);
695 PFDI_INT(hfdi
)->perf
->erfOper
= FDIERROR_CORRUPT_CABINET
;
696 PFDI_INT(hfdi
)->perf
->erfType
= 0; /* ? */
697 PFDI_INT(hfdi
)->perf
->fError
= TRUE
;
701 pmii
->nextname
= nextname
;
703 PFDI_FREE(hfdi
, nextname
);
704 nextinfo
= FDI_read_string(hfdi
, hf
, cabsize
);
707 pmii
->nextinfo
= nextinfo
;
709 PFDI_FREE(hfdi
, nextinfo
);
713 /* we could process the whole cabinet searching for problems;
714 instead lets stop here. Now let's fill out the paperwork */
715 pfdici
->cbCabinet
= cabsize
;
716 pfdici
->cFolders
= num_folders
;
717 pfdici
->cFiles
= num_files
;
718 pfdici
->setID
= setid
;
719 pfdici
->iCabinet
= cabidx
;
720 pfdici
->fReserve
= (flags
& cfheadRESERVE_PRESENT
) ? TRUE
: FALSE
;
721 pfdici
->hasprev
= (flags
& cfheadPREV_CABINET
) ? TRUE
: FALSE
;
722 pfdici
->hasnext
= (flags
& cfheadNEXT_CABINET
) ? TRUE
: FALSE
;
726 /***********************************************************************
727 * FDIIsCabinet (CABINET.21)
729 * Informs the caller as to whether or not the provided file handle is
730 * really a cabinet or not, filling out the provided PFDICABINETINFO
731 * structure with information about the cabinet. Brief explanations of
732 * the elements of this structure are available as comments accompanying
733 * its definition in wine's include/fdi.h.
736 * hfdi [I] An HFDI from FDICreate
737 * hf [I] The file handle about which the caller inquires
738 * pfdici [IO] Pointer to a PFDICABINETINFO structure which will
739 * be filled out with information about the cabinet
740 * file indicated by hf if, indeed, it is determined
744 * TRUE if the file is a cabinet. The info pointed to by pfdici will
746 * FALSE if the file is not a cabinet, or if an error was encountered
747 * while processing the cabinet. The PERF structure provided to
748 * FDICreate can be queried for more error information.
753 BOOL __cdecl
FDIIsCabinet(
756 PFDICABINETINFO pfdici
)
760 TRACE("(hfdi == ^%p, hf == ^%d, pfdici == ^%p)\n", hfdi
, hf
, pfdici
);
762 if (!REALLY_IS_FDI(hfdi
)) {
763 ERR("REALLY_IS_FDI failed on ^%p\n", hfdi
);
764 SetLastError(ERROR_INVALID_HANDLE
);
770 /* PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CABINET_NOT_FOUND;
771 PFDI_INT(hfdi)->perf->erfType = ERROR_INVALID_HANDLE;
772 PFDI_INT(hfdi)->perf->fError = TRUE; */
773 SetLastError(ERROR_INVALID_HANDLE
);
779 /* PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NONE;
780 PFDI_INT(hfdi)->perf->erfType = ERROR_BAD_ARGUMENTS;
781 PFDI_INT(hfdi)->perf->fError = TRUE; */
782 SetLastError(ERROR_BAD_ARGUMENTS
);
785 rv
= FDI_read_entries(hfdi
, hf
, pfdici
, NULL
);
788 pfdici
->hasnext
= FALSE
; /* yuck. duplicate apparent cabinet.dll bug */
793 /******************************************************************
794 * QTMfdi_initmodel (internal)
796 * Initialize a model which decodes symbols from [s] to [s]+[n]-1
798 static void QTMfdi_initmodel(struct QTMmodel
*m
, struct QTMmodelsym
*sym
, int n
, int s
) {
803 memset(m
->tabloc
, 0xFF, sizeof(m
->tabloc
)); /* clear out look-up table */
804 for (i
= 0; i
< n
; i
++) {
805 m
->tabloc
[i
+s
] = i
; /* set up a look-up entry for symbol */
806 m
->syms
[i
].sym
= i
+s
; /* actual symbol */
807 m
->syms
[i
].cumfreq
= n
-i
; /* current frequency of that symbol */
809 m
->syms
[n
].cumfreq
= 0;
812 /******************************************************************
813 * QTMfdi_init (internal)
815 static int QTMfdi_init(int window
, int level
, fdi_decomp_state
*decomp_state
) {
816 unsigned int wndsize
= 1 << window
;
817 int msz
= window
* 2, i
;
820 /* QTM supports window sizes of 2^10 (1Kb) through 2^21 (2Mb) */
821 /* if a previously allocated window is big enough, keep it */
822 if (window
< 10 || window
> 21) return DECR_DATAFORMAT
;
823 if (QTM(actual_size
) < wndsize
) {
824 if (QTM(window
)) PFDI_FREE(CAB(hfdi
), QTM(window
));
828 if (!(QTM(window
) = PFDI_ALLOC(CAB(hfdi
), wndsize
))) return DECR_NOMEMORY
;
829 QTM(actual_size
) = wndsize
;
831 QTM(window_size
) = wndsize
;
832 QTM(window_posn
) = 0;
834 /* initialize static slot/extrabits tables */
835 for (i
= 0, j
= 0; i
< 27; i
++) {
836 CAB(q_length_extra
)[i
] = (i
== 26) ? 0 : (i
< 2 ? 0 : i
- 2) >> 2;
837 CAB(q_length_base
)[i
] = j
; j
+= 1 << ((i
== 26) ? 5 : CAB(q_length_extra
)[i
]);
839 for (i
= 0, j
= 0; i
< 42; i
++) {
840 CAB(q_extra_bits
)[i
] = (i
< 2 ? 0 : i
-2) >> 1;
841 CAB(q_position_base
)[i
] = j
; j
+= 1 << CAB(q_extra_bits
)[i
];
844 /* initialize arithmetic coding models */
846 QTMfdi_initmodel(&QTM(model7
), &QTM(m7sym
)[0], 7, 0);
848 QTMfdi_initmodel(&QTM(model00
), &QTM(m00sym
)[0], 0x40, 0x00);
849 QTMfdi_initmodel(&QTM(model40
), &QTM(m40sym
)[0], 0x40, 0x40);
850 QTMfdi_initmodel(&QTM(model80
), &QTM(m80sym
)[0], 0x40, 0x80);
851 QTMfdi_initmodel(&QTM(modelC0
), &QTM(mC0sym
)[0], 0x40, 0xC0);
853 /* model 4 depends on table size, ranges from 20 to 24 */
854 QTMfdi_initmodel(&QTM(model4
), &QTM(m4sym
)[0], (msz
< 24) ? msz
: 24, 0);
855 /* model 5 depends on table size, ranges from 20 to 36 */
856 QTMfdi_initmodel(&QTM(model5
), &QTM(m5sym
)[0], (msz
< 36) ? msz
: 36, 0);
857 /* model 6pos depends on table size, ranges from 20 to 42 */
858 QTMfdi_initmodel(&QTM(model6pos
), &QTM(m6psym
)[0], msz
, 0);
859 QTMfdi_initmodel(&QTM(model6len
), &QTM(m6lsym
)[0], 27, 0);
864 /************************************************************
865 * LZXfdi_init (internal)
867 static int LZXfdi_init(int window
, fdi_decomp_state
*decomp_state
) {
868 static const cab_UBYTE bits
[] =
869 { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
870 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14,
871 15, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
873 static const cab_ULONG base
[] =
874 { 0, 1, 2, 3, 4, 6, 8, 12,
875 16, 24, 32, 48, 64, 96, 128, 192,
876 256, 384, 512, 768, 1024, 1536, 2048, 3072,
877 4096, 6144, 8192, 12288, 16384, 24576, 32768, 49152,
878 65536, 98304, 131072, 196608, 262144, 393216, 524288, 655360,
879 786432, 917504, 1048576, 1179648, 1310720, 1441792, 1572864, 1703936,
880 1835008, 1966080, 2097152};
881 cab_ULONG wndsize
= 1 << window
;
884 /* LZX supports window sizes of 2^15 (32Kb) through 2^21 (2Mb) */
885 /* if a previously allocated window is big enough, keep it */
886 if (window
< 15 || window
> 21) return DECR_DATAFORMAT
;
887 if (LZX(actual_size
) < wndsize
) {
888 if (LZX(window
)) PFDI_FREE(CAB(hfdi
), LZX(window
));
892 if (!(LZX(window
) = PFDI_ALLOC(CAB(hfdi
), wndsize
))) return DECR_NOMEMORY
;
893 LZX(actual_size
) = wndsize
;
895 LZX(window_size
) = wndsize
;
897 /* initialize static tables */
898 memcpy(CAB(extra_bits
), bits
, sizeof(bits
));
899 memcpy(CAB(lzx_position_base
), base
, sizeof(base
));
901 /* calculate required position slots */
902 if (window
== 20) posn_slots
= 42;
903 else if (window
== 21) posn_slots
= 50;
904 else posn_slots
= window
<< 1;
906 /*posn_slots=i=0; while (i < wndsize) i += 1 << CAB(extra_bits)[posn_slots++]; */
908 LZX(R0
) = LZX(R1
) = LZX(R2
) = 1;
909 LZX(main_elements
) = LZX_NUM_CHARS
+ (posn_slots
<< 3);
910 LZX(header_read
) = 0;
911 LZX(frames_read
) = 0;
912 LZX(block_remaining
) = 0;
913 LZX(block_type
) = LZX_BLOCKTYPE_INVALID
;
914 LZX(intel_curpos
) = 0;
915 LZX(intel_started
) = 0;
916 LZX(window_posn
) = 0;
918 /* initialize tables to 0 (because deltas will be applied to them) */
919 memset(LZX(MAINTREE_len
), 0, sizeof(LZX(MAINTREE_len
)));
920 memset(LZX(LENGTH_len
), 0, sizeof(LZX(LENGTH_len
)));
925 /****************************************************
926 * NONEfdi_decomp(internal)
928 static int NONEfdi_decomp(int inlen
, int outlen
, fdi_decomp_state
*decomp_state
)
930 if (inlen
!= outlen
) return DECR_ILLEGALDATA
;
931 memcpy(CAB(outbuf
), CAB(inbuf
), (size_t) inlen
);
935 /********************************************************
936 * Ziphuft_free (internal)
938 static void fdi_Ziphuft_free(HFDI hfdi
, struct Ziphuft
*t
)
940 register struct Ziphuft
*p
, *q
;
942 /* Go through linked list, freeing from the allocated (t[-1]) address. */
944 while (p
!= (struct Ziphuft
*)NULL
)
952 /*********************************************************
953 * fdi_Ziphuft_build (internal)
955 static cab_LONG
fdi_Ziphuft_build(cab_ULONG
*b
, cab_ULONG n
, cab_ULONG s
, const cab_UWORD
*d
, const cab_UWORD
*e
,
956 struct Ziphuft
**t
, cab_LONG
*m
, fdi_decomp_state
*decomp_state
)
958 cab_ULONG a
; /* counter for codes of length k */
959 cab_ULONG el
; /* length of EOB code (value 256) */
960 cab_ULONG f
; /* i repeats in table every f entries */
961 cab_LONG g
; /* maximum code length */
962 cab_LONG h
; /* table level */
963 register cab_ULONG i
; /* counter, current code */
964 register cab_ULONG j
; /* counter */
965 register cab_LONG k
; /* number of bits in current code */
966 cab_LONG
*l
; /* stack of bits per table */
967 register cab_ULONG
*p
; /* pointer into ZIP(c)[],ZIP(b)[],ZIP(v)[] */
968 register struct Ziphuft
*q
; /* points to current table */
969 struct Ziphuft r
; /* table entry for structure assignment */
970 register cab_LONG w
; /* bits before this table == (l * h) */
971 cab_ULONG
*xp
; /* pointer into x */
972 cab_LONG y
; /* number of dummy codes added */
973 cab_ULONG z
; /* number of entries in current table */
977 /* Generate counts for each bit length */
978 el
= n
> 256 ? b
[256] : ZIPBMAX
; /* set length of EOB code, if any */
980 for(i
= 0; i
< ZIPBMAX
+1; ++i
)
985 ZIP(c
)[*p
]++; p
++; /* assume all entries <= ZIPBMAX */
987 if (ZIP(c
)[0] == n
) /* null input--all zero length codes */
989 *t
= (struct Ziphuft
*)NULL
;
994 /* Find minimum and maximum length, bound *m by those */
995 for (j
= 1; j
<= ZIPBMAX
; j
++)
998 k
= j
; /* minimum code length */
999 if ((cab_ULONG
)*m
< j
)
1001 for (i
= ZIPBMAX
; i
; i
--)
1004 g
= i
; /* maximum code length */
1005 if ((cab_ULONG
)*m
> i
)
1008 /* Adjust last length count to fill out codes, if needed */
1009 for (y
= 1 << j
; j
< i
; j
++, y
<<= 1)
1010 if ((y
-= ZIP(c
)[j
]) < 0)
1011 return 2; /* bad input: more codes than bits */
1012 if ((y
-= ZIP(c
)[i
]) < 0)
1016 /* Generate starting offsets LONGo the value table for each length */
1018 p
= ZIP(c
) + 1; xp
= ZIP(x
) + 2;
1020 { /* note that i == g from above */
1021 *xp
++ = (j
+= *p
++);
1024 /* Make a table of values in order of bit lengths */
1027 if ((j
= *p
++) != 0)
1028 ZIP(v
)[ZIP(x
)[j
]++] = i
;
1032 /* Generate the Huffman codes and for each, make the table entries */
1033 ZIP(x
)[0] = i
= 0; /* first Huffman code is zero */
1034 p
= ZIP(v
); /* grab values in bit order */
1035 h
= -1; /* no tables yet--level -1 */
1036 w
= l
[-1] = 0; /* no bits decoded yet */
1037 ZIP(u
)[0] = (struct Ziphuft
*)NULL
; /* just to keep compilers happy */
1038 q
= (struct Ziphuft
*)NULL
; /* ditto */
1041 /* go through the bit lengths (k already is bits in shortest code) */
1047 /* here i is the Huffman code of length k bits for value *p */
1048 /* make tables up to required level */
1049 while (k
> w
+ l
[h
])
1051 w
+= l
[h
++]; /* add bits already decoded */
1053 /* compute minimum size table less than or equal to *m bits */
1054 z
= (z
= g
- w
) > (cab_ULONG
)*m
? *m
: z
; /* upper limit */
1055 if ((f
= 1 << (j
= k
- w
)) > a
+ 1) /* try a k-w bit table */
1056 { /* too few codes for k-w bit table */
1057 f
-= a
+ 1; /* deduct codes from patterns left */
1059 while (++j
< z
) /* try smaller tables up to z bits */
1061 if ((f
<<= 1) <= *++xp
)
1062 break; /* enough codes to use up j bits */
1063 f
-= *xp
; /* else deduct codes from patterns */
1066 if ((cab_ULONG
)w
+ j
> el
&& (cab_ULONG
)w
< el
)
1067 j
= el
- w
; /* make EOB code end at table */
1068 z
= 1 << j
; /* table entries for j-bit table */
1069 l
[h
] = j
; /* set table size in stack */
1071 /* allocate and link in new table */
1072 if (!(q
= (struct Ziphuft
*) PFDI_ALLOC(CAB(hfdi
), (z
+ 1)*sizeof(struct Ziphuft
))))
1075 fdi_Ziphuft_free(CAB(hfdi
), ZIP(u
)[0]);
1076 return 3; /* not enough memory */
1078 *t
= q
+ 1; /* link to list for Ziphuft_free() */
1079 *(t
= &(q
->v
.t
)) = (struct Ziphuft
*)NULL
;
1080 ZIP(u
)[h
] = ++q
; /* table starts after link */
1082 /* connect to last table, if there is one */
1085 ZIP(x
)[h
] = i
; /* save pattern for backing up */
1086 r
.b
= (cab_UBYTE
)l
[h
-1]; /* bits to dump before this table */
1087 r
.e
= (cab_UBYTE
)(16 + j
); /* bits in this table */
1088 r
.v
.t
= q
; /* pointer to this table */
1089 j
= (i
& ((1 << w
) - 1)) >> (w
- l
[h
-1]);
1090 ZIP(u
)[h
-1][j
] = r
; /* connect to last table */
1094 /* set up table entry in r */
1095 r
.b
= (cab_UBYTE
)(k
- w
);
1096 if (p
>= ZIP(v
) + n
)
1097 r
.e
= 99; /* out of values--invalid code */
1100 r
.e
= (cab_UBYTE
)(*p
< 256 ? 16 : 15); /* 256 is end-of-block code */
1101 r
.v
.n
= *p
++; /* simple code is just the value */
1105 r
.e
= (cab_UBYTE
)e
[*p
- s
]; /* non-simple--look up in lists */
1106 r
.v
.n
= d
[*p
++ - s
];
1109 /* fill code-like entries with r */
1111 for (j
= i
>> w
; j
< z
; j
+= f
)
1114 /* backwards increment the k-bit code i */
1115 for (j
= 1 << (k
- 1); i
& j
; j
>>= 1)
1119 /* backup over finished tables */
1120 while ((i
& ((1 << w
) - 1)) != ZIP(x
)[h
])
1121 w
-= l
[--h
]; /* don't need to update q */
1125 /* return actual size of base table */
1128 /* Return true (1) if we were given an incomplete table */
1129 return y
!= 0 && g
!= 1;
1132 /*********************************************************
1133 * fdi_Zipinflate_codes (internal)
1135 static cab_LONG
fdi_Zipinflate_codes(struct Ziphuft
*tl
, struct Ziphuft
*td
,
1136 cab_LONG bl
, cab_LONG bd
, fdi_decomp_state
*decomp_state
)
1138 register cab_ULONG e
; /* table entry flag/number of extra bits */
1139 cab_ULONG n
, d
; /* length and index for copy */
1140 cab_ULONG w
; /* current window position */
1141 struct Ziphuft
*t
; /* pointer to table entry */
1142 cab_ULONG ml
, md
; /* masks for bl and bd bits */
1143 register cab_ULONG b
; /* bit buffer */
1144 register cab_ULONG k
; /* number of bits in bit buffer */
1146 /* make local copies of globals */
1147 b
= ZIP(bb
); /* initialize bit buffer */
1149 w
= ZIP(window_posn
); /* initialize window position */
1151 /* inflate the coded data */
1152 ml
= Zipmask
[bl
]; /* precompute masks for speed */
1157 ZIPNEEDBITS((cab_ULONG
)bl
)
1158 if((e
= (t
= tl
+ ((cab_ULONG
)b
& ml
))->e
) > 16)
1166 } while ((e
= (t
= t
->v
.t
+ ((cab_ULONG
)b
& Zipmask
[e
]))->e
) > 16);
1168 if (e
== 16) /* then it's a literal */
1169 CAB(outbuf
)[w
++] = (cab_UBYTE
)t
->v
.n
;
1170 else /* it's an EOB or a length */
1172 /* exit if end of block */
1176 /* get length of block to copy */
1178 n
= t
->v
.n
+ ((cab_ULONG
)b
& Zipmask
[e
]);
1181 /* decode distance of block to copy */
1182 ZIPNEEDBITS((cab_ULONG
)bd
)
1183 if ((e
= (t
= td
+ ((cab_ULONG
)b
& md
))->e
) > 16)
1190 } while ((e
= (t
= t
->v
.t
+ ((cab_ULONG
)b
& Zipmask
[e
]))->e
) > 16);
1193 d
= w
- t
->v
.n
- ((cab_ULONG
)b
& Zipmask
[e
]);
1197 n
-= (e
= (e
= ZIPWSIZE
- ((d
&= ZIPWSIZE
-1) > w
? d
: w
)) > n
?n
:e
);
1200 CAB(outbuf
)[w
++] = CAB(outbuf
)[d
++];
1206 /* restore the globals from the locals */
1207 ZIP(window_posn
) = w
; /* restore global window pointer */
1208 ZIP(bb
) = b
; /* restore global bit buffer */
1215 /***********************************************************
1216 * Zipinflate_stored (internal)
1218 static cab_LONG
fdi_Zipinflate_stored(fdi_decomp_state
*decomp_state
)
1219 /* "decompress" an inflated type 0 (stored) block. */
1221 cab_ULONG n
; /* number of bytes in block */
1222 cab_ULONG w
; /* current window position */
1223 register cab_ULONG b
; /* bit buffer */
1224 register cab_ULONG k
; /* number of bits in bit buffer */
1226 /* make local copies of globals */
1227 b
= ZIP(bb
); /* initialize bit buffer */
1229 w
= ZIP(window_posn
); /* initialize window position */
1231 /* go to byte boundary */
1235 /* get the length and its complement */
1237 n
= ((cab_ULONG
)b
& 0xffff);
1240 if (n
!= (cab_ULONG
)((~b
) & 0xffff))
1241 return 1; /* error in compressed data */
1244 /* read and output the compressed data */
1248 CAB(outbuf
)[w
++] = (cab_UBYTE
)b
;
1252 /* restore the globals from the locals */
1253 ZIP(window_posn
) = w
; /* restore global window pointer */
1254 ZIP(bb
) = b
; /* restore global bit buffer */
1259 /******************************************************
1260 * fdi_Zipinflate_fixed (internal)
1262 static cab_LONG
fdi_Zipinflate_fixed(fdi_decomp_state
*decomp_state
)
1264 struct Ziphuft
*fixed_tl
;
1265 struct Ziphuft
*fixed_td
;
1266 cab_LONG fixed_bl
, fixed_bd
;
1267 cab_LONG i
; /* temporary variable */
1273 for(i
= 0; i
< 144; i
++)
1279 for(; i
< 288; i
++) /* make a complete, but wrong code set */
1282 if((i
= fdi_Ziphuft_build(l
, 288, 257, Zipcplens
, Zipcplext
, &fixed_tl
, &fixed_bl
, decomp_state
)))
1285 /* distance table */
1286 for(i
= 0; i
< 30; i
++) /* make an incomplete code set */
1289 if((i
= fdi_Ziphuft_build(l
, 30, 0, Zipcpdist
, Zipcpdext
, &fixed_td
, &fixed_bd
, decomp_state
)) > 1)
1291 fdi_Ziphuft_free(CAB(hfdi
), fixed_tl
);
1295 /* decompress until an end-of-block code */
1296 i
= fdi_Zipinflate_codes(fixed_tl
, fixed_td
, fixed_bl
, fixed_bd
, decomp_state
);
1298 fdi_Ziphuft_free(CAB(hfdi
), fixed_td
);
1299 fdi_Ziphuft_free(CAB(hfdi
), fixed_tl
);
1303 /**************************************************************
1304 * fdi_Zipinflate_dynamic (internal)
1306 static cab_LONG
fdi_Zipinflate_dynamic(fdi_decomp_state
*decomp_state
)
1307 /* decompress an inflated type 2 (dynamic Huffman codes) block. */
1309 cab_LONG i
; /* temporary variables */
1312 cab_ULONG l
; /* last length */
1313 cab_ULONG m
; /* mask for bit lengths table */
1314 cab_ULONG n
; /* number of lengths to get */
1315 struct Ziphuft
*tl
; /* literal/length code table */
1316 struct Ziphuft
*td
; /* distance code table */
1317 cab_LONG bl
; /* lookup bits for tl */
1318 cab_LONG bd
; /* lookup bits for td */
1319 cab_ULONG nb
; /* number of bit length codes */
1320 cab_ULONG nl
; /* number of literal/length codes */
1321 cab_ULONG nd
; /* number of distance codes */
1322 register cab_ULONG b
; /* bit buffer */
1323 register cab_ULONG k
; /* number of bits in bit buffer */
1325 /* make local bit buffer */
1330 /* read in table lengths */
1332 nl
= 257 + ((cab_ULONG
)b
& 0x1f); /* number of literal/length codes */
1335 nd
= 1 + ((cab_ULONG
)b
& 0x1f); /* number of distance codes */
1338 nb
= 4 + ((cab_ULONG
)b
& 0xf); /* number of bit length codes */
1340 if(nl
> 288 || nd
> 32)
1341 return 1; /* bad lengths */
1343 /* read in bit-length-code lengths */
1344 for(j
= 0; j
< nb
; j
++)
1347 ll
[Zipborder
[j
]] = (cab_ULONG
)b
& 7;
1351 ll
[Zipborder
[j
]] = 0;
1353 /* build decoding table for trees--single level, 7 bit lookup */
1355 if((i
= fdi_Ziphuft_build(ll
, 19, 19, NULL
, NULL
, &tl
, &bl
, decomp_state
)) != 0)
1358 fdi_Ziphuft_free(CAB(hfdi
), tl
);
1359 return i
; /* incomplete code set */
1362 /* read in literal and distance code lengths */
1366 while((cab_ULONG
)i
< n
)
1368 ZIPNEEDBITS((cab_ULONG
)bl
)
1369 j
= (td
= tl
+ ((cab_ULONG
)b
& m
))->b
;
1372 if (j
< 16) /* length of code in bits (0..15) */
1373 ll
[i
++] = l
= j
; /* save last length in l */
1374 else if (j
== 16) /* repeat last length 3 to 6 times */
1377 j
= 3 + ((cab_ULONG
)b
& 3);
1379 if((cab_ULONG
)i
+ j
> n
)
1384 else if (j
== 17) /* 3 to 10 zero length codes */
1387 j
= 3 + ((cab_ULONG
)b
& 7);
1389 if ((cab_ULONG
)i
+ j
> n
)
1395 else /* j == 18: 11 to 138 zero length codes */
1398 j
= 11 + ((cab_ULONG
)b
& 0x7f);
1400 if ((cab_ULONG
)i
+ j
> n
)
1408 /* free decoding table for trees */
1409 fdi_Ziphuft_free(CAB(hfdi
), tl
);
1411 /* restore the global bit buffer */
1415 /* build the decoding tables for literal/length and distance codes */
1417 if((i
= fdi_Ziphuft_build(ll
, nl
, 257, Zipcplens
, Zipcplext
, &tl
, &bl
, decomp_state
)) != 0)
1420 fdi_Ziphuft_free(CAB(hfdi
), tl
);
1421 return i
; /* incomplete code set */
1424 fdi_Ziphuft_build(ll
+ nl
, nd
, 0, Zipcpdist
, Zipcpdext
, &td
, &bd
, decomp_state
);
1426 /* decompress until an end-of-block code */
1427 if(fdi_Zipinflate_codes(tl
, td
, bl
, bd
, decomp_state
))
1430 /* free the decoding tables, return */
1431 fdi_Ziphuft_free(CAB(hfdi
), tl
);
1432 fdi_Ziphuft_free(CAB(hfdi
), td
);
1436 /*****************************************************
1437 * fdi_Zipinflate_block (internal)
1439 static cab_LONG
fdi_Zipinflate_block(cab_LONG
*e
, fdi_decomp_state
*decomp_state
) /* e == last block flag */
1440 { /* decompress an inflated block */
1441 cab_ULONG t
; /* block type */
1442 register cab_ULONG b
; /* bit buffer */
1443 register cab_ULONG k
; /* number of bits in bit buffer */
1445 /* make local bit buffer */
1449 /* read in last block bit */
1451 *e
= (cab_LONG
)b
& 1;
1454 /* read in block type */
1456 t
= (cab_ULONG
)b
& 3;
1459 /* restore the global bit buffer */
1463 /* inflate that block type */
1465 return fdi_Zipinflate_dynamic(decomp_state
);
1467 return fdi_Zipinflate_stored(decomp_state
);
1469 return fdi_Zipinflate_fixed(decomp_state
);
1470 /* bad block type */
1474 /****************************************************
1475 * ZIPfdi_decomp(internal)
1477 static int ZIPfdi_decomp(int inlen
, int outlen
, fdi_decomp_state
*decomp_state
)
1479 cab_LONG e
; /* last block flag */
1481 TRACE("(inlen == %d, outlen == %d)\n", inlen
, outlen
);
1483 ZIP(inpos
) = CAB(inbuf
);
1484 ZIP(bb
) = ZIP(bk
) = ZIP(window_posn
) = 0;
1485 if(outlen
> ZIPWSIZE
)
1486 return DECR_DATAFORMAT
;
1488 /* CK = Chris Kirmse, official Microsoft purloiner */
1489 if(ZIP(inpos
)[0] != 0x43 || ZIP(inpos
)[1] != 0x4B)
1490 return DECR_ILLEGALDATA
;
1494 if(fdi_Zipinflate_block(&e
, decomp_state
))
1495 return DECR_ILLEGALDATA
;
1498 /* return success */
1502 /*******************************************************************
1503 * QTMfdi_decomp(internal)
1505 static int QTMfdi_decomp(int inlen
, int outlen
, fdi_decomp_state
*decomp_state
)
1507 cab_UBYTE
*inpos
= CAB(inbuf
);
1508 cab_UBYTE
*window
= QTM(window
);
1509 cab_UBYTE
*runsrc
, *rundest
;
1511 cab_ULONG window_posn
= QTM(window_posn
);
1512 cab_ULONG window_size
= QTM(window_size
);
1514 /* used by bitstream macros */
1515 register int bitsleft
, bitrun
, bitsneed
;
1516 register cab_ULONG bitbuf
;
1518 /* used by GET_SYMBOL */
1523 int extra
, togo
= outlen
, match_length
= 0, copy_length
;
1524 cab_UBYTE selector
, sym
;
1525 cab_ULONG match_offset
= 0;
1527 cab_UWORD H
= 0xFFFF, L
= 0, C
;
1529 TRACE("(inlen == %d, outlen == %d)\n", inlen
, outlen
);
1531 /* read initial value of C */
1535 /* apply 2^x-1 mask */
1536 window_posn
&= window_size
- 1;
1537 /* runs can't straddle the window wraparound */
1538 if ((window_posn
+ togo
) > window_size
) {
1539 TRACE("straddled run\n");
1540 return DECR_DATAFORMAT
;
1544 GET_SYMBOL(model7
, selector
);
1547 GET_SYMBOL(model00
, sym
); window
[window_posn
++] = sym
; togo
--;
1550 GET_SYMBOL(model40
, sym
); window
[window_posn
++] = sym
; togo
--;
1553 GET_SYMBOL(model80
, sym
); window
[window_posn
++] = sym
; togo
--;
1556 GET_SYMBOL(modelC0
, sym
); window
[window_posn
++] = sym
; togo
--;
1560 /* selector 4 = fixed length of 3 */
1561 GET_SYMBOL(model4
, sym
);
1562 Q_READ_BITS(extra
, CAB(q_extra_bits
)[sym
]);
1563 match_offset
= CAB(q_position_base
)[sym
] + extra
+ 1;
1568 /* selector 5 = fixed length of 4 */
1569 GET_SYMBOL(model5
, sym
);
1570 Q_READ_BITS(extra
, CAB(q_extra_bits
)[sym
]);
1571 match_offset
= CAB(q_position_base
)[sym
] + extra
+ 1;
1576 /* selector 6 = variable length */
1577 GET_SYMBOL(model6len
, sym
);
1578 Q_READ_BITS(extra
, CAB(q_length_extra
)[sym
]);
1579 match_length
= CAB(q_length_base
)[sym
] + extra
+ 5;
1580 GET_SYMBOL(model6pos
, sym
);
1581 Q_READ_BITS(extra
, CAB(q_extra_bits
)[sym
]);
1582 match_offset
= CAB(q_position_base
)[sym
] + extra
+ 1;
1586 TRACE("Selector is bogus\n");
1587 return DECR_ILLEGALDATA
;
1590 /* if this is a match */
1591 if (selector
>= 4) {
1592 rundest
= window
+ window_posn
;
1593 togo
-= match_length
;
1595 /* copy any wrapped around source data */
1596 if (window_posn
>= match_offset
) {
1598 runsrc
= rundest
- match_offset
;
1600 runsrc
= rundest
+ (window_size
- match_offset
);
1601 copy_length
= match_offset
- window_posn
;
1602 if (copy_length
< match_length
) {
1603 match_length
-= copy_length
;
1604 window_posn
+= copy_length
;
1605 while (copy_length
-- > 0) *rundest
++ = *runsrc
++;
1609 window_posn
+= match_length
;
1611 /* copy match data - no worries about destination wraps */
1612 while (match_length
-- > 0) *rundest
++ = *runsrc
++;
1614 } /* while (togo > 0) */
1617 TRACE("Frame overflow, this_run = %d\n", togo
);
1618 return DECR_ILLEGALDATA
;
1621 memcpy(CAB(outbuf
), window
+ ((!window_posn
) ? window_size
: window_posn
) -
1624 QTM(window_posn
) = window_posn
;
1628 /************************************************************
1629 * fdi_lzx_read_lens (internal)
1631 static int fdi_lzx_read_lens(cab_UBYTE
*lens
, cab_ULONG first
, cab_ULONG last
, struct lzx_bits
*lb
,
1632 fdi_decomp_state
*decomp_state
) {
1636 register cab_ULONG bitbuf
= lb
->bb
;
1637 register int bitsleft
= lb
->bl
;
1638 cab_UBYTE
*inpos
= lb
->ip
;
1641 for (x
= 0; x
< 20; x
++) {
1643 LENTABLE(PRETREE
)[x
] = y
;
1645 BUILD_TABLE(PRETREE
);
1647 for (x
= first
; x
< last
; ) {
1648 READ_HUFFSYM(PRETREE
, z
);
1650 READ_BITS(y
, 4); y
+= 4;
1651 while (y
--) lens
[x
++] = 0;
1654 READ_BITS(y
, 5); y
+= 20;
1655 while (y
--) lens
[x
++] = 0;
1658 READ_BITS(y
, 1); y
+= 4;
1659 READ_HUFFSYM(PRETREE
, z
);
1660 z
= lens
[x
] - z
; if (z
< 0) z
+= 17;
1661 while (y
--) lens
[x
++] = z
;
1664 z
= lens
[x
] - z
; if (z
< 0) z
+= 17;
1675 /*******************************************************
1676 * LZXfdi_decomp(internal)
1678 static int LZXfdi_decomp(int inlen
, int outlen
, fdi_decomp_state
*decomp_state
) {
1679 cab_UBYTE
*inpos
= CAB(inbuf
);
1680 cab_UBYTE
*endinp
= inpos
+ inlen
;
1681 cab_UBYTE
*window
= LZX(window
);
1682 cab_UBYTE
*runsrc
, *rundest
;
1683 cab_UWORD
*hufftbl
; /* used in READ_HUFFSYM macro as chosen decoding table */
1685 cab_ULONG window_posn
= LZX(window_posn
);
1686 cab_ULONG window_size
= LZX(window_size
);
1687 cab_ULONG R0
= LZX(R0
);
1688 cab_ULONG R1
= LZX(R1
);
1689 cab_ULONG R2
= LZX(R2
);
1691 register cab_ULONG bitbuf
;
1692 register int bitsleft
;
1693 cab_ULONG match_offset
, i
,j
,k
; /* ijk used in READ_HUFFSYM macro */
1694 struct lzx_bits lb
; /* used in READ_LENGTHS macro */
1696 int togo
= outlen
, this_run
, main_element
, aligned_bits
;
1697 int match_length
, copy_length
, length_footer
, extra
, verbatim_bits
;
1699 TRACE("(inlen == %d, outlen == %d)\n", inlen
, outlen
);
1703 /* read header if necessary */
1704 if (!LZX(header_read
)) {
1706 READ_BITS(k
, 1); if (k
) { READ_BITS(i
,16); READ_BITS(j
,16); }
1707 LZX(intel_filesize
) = (i
<< 16) | j
; /* or 0 if not encoded */
1708 LZX(header_read
) = 1;
1711 /* main decoding loop */
1713 /* last block finished, new block expected */
1714 if (LZX(block_remaining
) == 0) {
1715 if (LZX(block_type
) == LZX_BLOCKTYPE_UNCOMPRESSED
) {
1716 if (LZX(block_length
) & 1) inpos
++; /* realign bitstream to word */
1720 READ_BITS(LZX(block_type
), 3);
1723 LZX(block_remaining
) = LZX(block_length
) = (i
<< 8) | j
;
1725 switch (LZX(block_type
)) {
1726 case LZX_BLOCKTYPE_ALIGNED
:
1727 for (i
= 0; i
< 8; i
++) { READ_BITS(j
, 3); LENTABLE(ALIGNED
)[i
] = j
; }
1728 BUILD_TABLE(ALIGNED
);
1729 /* rest of aligned header is same as verbatim */
1731 case LZX_BLOCKTYPE_VERBATIM
:
1732 READ_LENGTHS(MAINTREE
, 0, 256, fdi_lzx_read_lens
);
1733 READ_LENGTHS(MAINTREE
, 256, LZX(main_elements
), fdi_lzx_read_lens
);
1734 BUILD_TABLE(MAINTREE
);
1735 if (LENTABLE(MAINTREE
)[0xE8] != 0) LZX(intel_started
) = 1;
1737 READ_LENGTHS(LENGTH
, 0, LZX_NUM_SECONDARY_LENGTHS
, fdi_lzx_read_lens
);
1738 BUILD_TABLE(LENGTH
);
1741 case LZX_BLOCKTYPE_UNCOMPRESSED
:
1742 LZX(intel_started
) = 1; /* because we can't assume otherwise */
1743 ENSURE_BITS(16); /* get up to 16 pad bits into the buffer */
1744 if (bitsleft
> 16) inpos
-= 2; /* and align the bitstream! */
1745 R0
= inpos
[0]|(inpos
[1]<<8)|(inpos
[2]<<16)|(inpos
[3]<<24);inpos
+=4;
1746 R1
= inpos
[0]|(inpos
[1]<<8)|(inpos
[2]<<16)|(inpos
[3]<<24);inpos
+=4;
1747 R2
= inpos
[0]|(inpos
[1]<<8)|(inpos
[2]<<16)|(inpos
[3]<<24);inpos
+=4;
1751 return DECR_ILLEGALDATA
;
1755 /* buffer exhaustion check */
1756 if (inpos
> endinp
) {
1757 /* it's possible to have a file where the next run is less than
1758 * 16 bits in size. In this case, the READ_HUFFSYM() macro used
1759 * in building the tables will exhaust the buffer, so we should
1760 * allow for this, but not allow those accidentally read bits to
1761 * be used (so we check that there are at least 16 bits
1762 * remaining - in this boundary case they aren't really part of
1763 * the compressed data)
1765 if (inpos
> (endinp
+2) || bitsleft
< 16) return DECR_ILLEGALDATA
;
1768 while ((this_run
= LZX(block_remaining
)) > 0 && togo
> 0) {
1769 if (this_run
> togo
) this_run
= togo
;
1771 LZX(block_remaining
) -= this_run
;
1773 /* apply 2^x-1 mask */
1774 window_posn
&= window_size
- 1;
1775 /* runs can't straddle the window wraparound */
1776 if ((window_posn
+ this_run
) > window_size
)
1777 return DECR_DATAFORMAT
;
1779 switch (LZX(block_type
)) {
1781 case LZX_BLOCKTYPE_VERBATIM
:
1782 while (this_run
> 0) {
1783 READ_HUFFSYM(MAINTREE
, main_element
);
1785 if (main_element
< LZX_NUM_CHARS
) {
1786 /* literal: 0 to LZX_NUM_CHARS-1 */
1787 window
[window_posn
++] = main_element
;
1791 /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
1792 main_element
-= LZX_NUM_CHARS
;
1794 match_length
= main_element
& LZX_NUM_PRIMARY_LENGTHS
;
1795 if (match_length
== LZX_NUM_PRIMARY_LENGTHS
) {
1796 READ_HUFFSYM(LENGTH
, length_footer
);
1797 match_length
+= length_footer
;
1799 match_length
+= LZX_MIN_MATCH
;
1801 match_offset
= main_element
>> 3;
1803 if (match_offset
> 2) {
1804 /* not repeated offset */
1805 if (match_offset
!= 3) {
1806 extra
= CAB(extra_bits
)[match_offset
];
1807 READ_BITS(verbatim_bits
, extra
);
1808 match_offset
= CAB(lzx_position_base
)[match_offset
]
1809 - 2 + verbatim_bits
;
1815 /* update repeated offset LRU queue */
1816 R2
= R1
; R1
= R0
; R0
= match_offset
;
1818 else if (match_offset
== 0) {
1821 else if (match_offset
== 1) {
1823 R1
= R0
; R0
= match_offset
;
1825 else /* match_offset == 2 */ {
1827 R2
= R0
; R0
= match_offset
;
1830 rundest
= window
+ window_posn
;
1831 this_run
-= match_length
;
1833 /* copy any wrapped around source data */
1834 if (window_posn
>= match_offset
) {
1836 runsrc
= rundest
- match_offset
;
1838 runsrc
= rundest
+ (window_size
- match_offset
);
1839 copy_length
= match_offset
- window_posn
;
1840 if (copy_length
< match_length
) {
1841 match_length
-= copy_length
;
1842 window_posn
+= copy_length
;
1843 while (copy_length
-- > 0) *rundest
++ = *runsrc
++;
1847 window_posn
+= match_length
;
1849 /* copy match data - no worries about destination wraps */
1850 while (match_length
-- > 0) *rundest
++ = *runsrc
++;
1855 case LZX_BLOCKTYPE_ALIGNED
:
1856 while (this_run
> 0) {
1857 READ_HUFFSYM(MAINTREE
, main_element
);
1859 if (main_element
< LZX_NUM_CHARS
) {
1860 /* literal: 0 to LZX_NUM_CHARS-1 */
1861 window
[window_posn
++] = main_element
;
1865 /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
1866 main_element
-= LZX_NUM_CHARS
;
1868 match_length
= main_element
& LZX_NUM_PRIMARY_LENGTHS
;
1869 if (match_length
== LZX_NUM_PRIMARY_LENGTHS
) {
1870 READ_HUFFSYM(LENGTH
, length_footer
);
1871 match_length
+= length_footer
;
1873 match_length
+= LZX_MIN_MATCH
;
1875 match_offset
= main_element
>> 3;
1877 if (match_offset
> 2) {
1878 /* not repeated offset */
1879 extra
= CAB(extra_bits
)[match_offset
];
1880 match_offset
= CAB(lzx_position_base
)[match_offset
] - 2;
1882 /* verbatim and aligned bits */
1884 READ_BITS(verbatim_bits
, extra
);
1885 match_offset
+= (verbatim_bits
<< 3);
1886 READ_HUFFSYM(ALIGNED
, aligned_bits
);
1887 match_offset
+= aligned_bits
;
1889 else if (extra
== 3) {
1890 /* aligned bits only */
1891 READ_HUFFSYM(ALIGNED
, aligned_bits
);
1892 match_offset
+= aligned_bits
;
1894 else if (extra
> 0) { /* extra==1, extra==2 */
1895 /* verbatim bits only */
1896 READ_BITS(verbatim_bits
, extra
);
1897 match_offset
+= verbatim_bits
;
1899 else /* extra == 0 */ {
1904 /* update repeated offset LRU queue */
1905 R2
= R1
; R1
= R0
; R0
= match_offset
;
1907 else if (match_offset
== 0) {
1910 else if (match_offset
== 1) {
1912 R1
= R0
; R0
= match_offset
;
1914 else /* match_offset == 2 */ {
1916 R2
= R0
; R0
= match_offset
;
1919 rundest
= window
+ window_posn
;
1920 this_run
-= match_length
;
1922 /* copy any wrapped around source data */
1923 if (window_posn
>= match_offset
) {
1925 runsrc
= rundest
- match_offset
;
1927 runsrc
= rundest
+ (window_size
- match_offset
);
1928 copy_length
= match_offset
- window_posn
;
1929 if (copy_length
< match_length
) {
1930 match_length
-= copy_length
;
1931 window_posn
+= copy_length
;
1932 while (copy_length
-- > 0) *rundest
++ = *runsrc
++;
1936 window_posn
+= match_length
;
1938 /* copy match data - no worries about destination wraps */
1939 while (match_length
-- > 0) *rundest
++ = *runsrc
++;
1944 case LZX_BLOCKTYPE_UNCOMPRESSED
:
1945 if ((inpos
+ this_run
) > endinp
) return DECR_ILLEGALDATA
;
1946 memcpy(window
+ window_posn
, inpos
, (size_t) this_run
);
1947 inpos
+= this_run
; window_posn
+= this_run
;
1951 return DECR_ILLEGALDATA
; /* might as well */
1957 if (togo
!= 0) return DECR_ILLEGALDATA
;
1958 memcpy(CAB(outbuf
), window
+ ((!window_posn
) ? window_size
: window_posn
) -
1959 outlen
, (size_t) outlen
);
1961 LZX(window_posn
) = window_posn
;
1966 /* intel E8 decoding */
1967 if ((LZX(frames_read
)++ < 32768) && LZX(intel_filesize
) != 0) {
1968 if (outlen
<= 6 || !LZX(intel_started
)) {
1969 LZX(intel_curpos
) += outlen
;
1972 cab_UBYTE
*data
= CAB(outbuf
);
1973 cab_UBYTE
*dataend
= data
+ outlen
- 10;
1974 cab_LONG curpos
= LZX(intel_curpos
);
1975 cab_LONG filesize
= LZX(intel_filesize
);
1976 cab_LONG abs_off
, rel_off
;
1978 LZX(intel_curpos
) = curpos
+ outlen
;
1980 while (data
< dataend
) {
1981 if (*data
++ != 0xE8) { curpos
++; continue; }
1982 abs_off
= data
[0] | (data
[1]<<8) | (data
[2]<<16) | (data
[3]<<24);
1983 if ((abs_off
>= -curpos
) && (abs_off
< filesize
)) {
1984 rel_off
= (abs_off
>= 0) ? abs_off
- curpos
: abs_off
+ filesize
;
1985 data
[0] = (cab_UBYTE
) rel_off
;
1986 data
[1] = (cab_UBYTE
) (rel_off
>> 8);
1987 data
[2] = (cab_UBYTE
) (rel_off
>> 16);
1988 data
[3] = (cab_UBYTE
) (rel_off
>> 24);
1998 /**********************************************************
1999 * fdi_decomp (internal)
2001 * Decompress the requested number of bytes. If savemode is zero,
2002 * do not save the output anywhere, just plow through blocks until we
2003 * reach the specified (uncompressed) distance from the starting point,
2004 * and remember the position of the cabfile pointer (and which cabfile)
2005 * after we are done; otherwise, save the data out to CAB(filehf),
2006 * decompressing the requested number of bytes and writing them out. This
2007 * is also where we jump to additional cabinets in the case of split
2008 * cab's, and provide (some of) the NEXT_CABINET notification semantics.
2010 static int fdi_decomp(struct fdi_file
*fi
, int savemode
, fdi_decomp_state
*decomp_state
,
2011 char *pszCabPath
, PFNFDINOTIFY pfnfdin
, void *pvUser
)
2013 cab_ULONG bytes
= savemode
? fi
->length
: fi
->offset
- CAB(offset
);
2014 cab_UBYTE buf
[cfdata_SIZEOF
], *data
;
2015 cab_UWORD inlen
, len
, outlen
, cando
;
2018 fdi_decomp_state
*cab
= (savemode
&& CAB(decomp_cab
)) ? CAB(decomp_cab
) : decomp_state
;
2020 TRACE("(fi == ^%p, savemode == %d, bytes == %d)\n", fi
, savemode
, bytes
);
2023 /* cando = the max number of bytes we can do */
2024 cando
= CAB(outlen
);
2025 if (cando
> bytes
) cando
= bytes
;
2028 if (cando
&& savemode
)
2029 PFDI_WRITE(CAB(hfdi
), CAB(filehf
), CAB(outpos
), cando
);
2031 CAB(outpos
) += cando
;
2032 CAB(outlen
) -= cando
;
2033 bytes
-= cando
; if (!bytes
) break;
2035 /* we only get here if we emptied the output buffer */
2037 /* read data header + data */
2039 while (outlen
== 0) {
2040 /* read the block header, skip the reserved part */
2041 if (PFDI_READ(CAB(hfdi
), cab
->cabhf
, buf
, cfdata_SIZEOF
) != cfdata_SIZEOF
)
2044 if (PFDI_SEEK(CAB(hfdi
), cab
->cabhf
, cab
->mii
.block_resv
, SEEK_CUR
) == -1)
2047 /* we shouldn't get blocks over CAB_INPUTMAX in size */
2048 data
= CAB(inbuf
) + inlen
;
2049 len
= EndGetI16(buf
+cfdata_CompressedSize
);
2051 if (inlen
> CAB_INPUTMAX
) return DECR_INPUT
;
2052 if (PFDI_READ(CAB(hfdi
), cab
->cabhf
, data
, len
) != len
)
2055 /* clear two bytes after read-in data */
2056 data
[len
+1] = data
[len
+2] = 0;
2058 /* perform checksum test on the block (if one is stored) */
2059 cksum
= EndGetI32(buf
+cfdata_CheckSum
);
2060 if (cksum
&& cksum
!= checksum(buf
+4, 4, checksum(data
, len
, 0)))
2061 return DECR_CHECKSUM
; /* checksum is wrong */
2063 outlen
= EndGetI16(buf
+cfdata_UncompressedSize
);
2065 /* outlen=0 means this block was the last contiguous part
2066 of a split block, continued in the next cabinet */
2068 int pathlen
, filenamelen
, idx
, i
, cabhf
;
2069 char fullpath
[MAX_PATH
], userpath
[256];
2070 FDINOTIFICATION fdin
;
2071 FDICABINETINFO fdici
;
2072 char emptystring
= '\0';
2074 int success
= FALSE
;
2075 struct fdi_folder
*fol
= NULL
, *linkfol
= NULL
;
2076 struct fdi_file
*file
= NULL
, *linkfile
= NULL
;
2080 /* set up the next decomp_state... */
2082 if (!cab
->mii
.hasnext
) return DECR_INPUT
;
2084 if (!((cab
->next
= PFDI_ALLOC(CAB(hfdi
), sizeof(fdi_decomp_state
)))))
2085 return DECR_NOMEMORY
;
2087 ZeroMemory(cab
->next
, sizeof(fdi_decomp_state
));
2089 /* copy pszCabPath to userpath */
2090 ZeroMemory(userpath
, 256);
2091 pathlen
= (pszCabPath
) ? strlen(pszCabPath
) : 0;
2093 if (pathlen
< 256) {
2094 for (i
= 0; i
<= pathlen
; i
++)
2095 userpath
[i
] = pszCabPath
[i
];
2096 } /* else we are in a weird place... let's leave it blank and see if the user fixes it */
2099 /* initial fdintNEXT_CABINET notification */
2100 ZeroMemory(&fdin
, sizeof(FDINOTIFICATION
));
2101 fdin
.psz1
= (cab
->mii
.nextname
) ? cab
->mii
.nextname
: &emptystring
;
2102 fdin
.psz2
= (cab
->mii
.nextinfo
) ? cab
->mii
.nextinfo
: &emptystring
;
2103 fdin
.psz3
= &userpath
[0];
2104 fdin
.fdie
= FDIERROR_NONE
;
2107 if (((*pfnfdin
)(fdintNEXT_CABINET
, &fdin
))) return DECR_USERABORT
;
2111 pathlen
= (userpath
) ? strlen(userpath
) : 0;
2112 filenamelen
= (cab
->mii
.nextname
) ? strlen(cab
->mii
.nextname
) : 0;
2114 /* slight overestimation here to save CPU cycles in the developer's brain */
2115 if ((pathlen
+ filenamelen
+ 3) > MAX_PATH
) {
2116 ERR("MAX_PATH exceeded.\n");
2117 return DECR_ILLEGALDATA
;
2120 /* paste the path and filename together */
2123 for (i
= 0; i
< pathlen
; i
++) fullpath
[idx
++] = userpath
[i
];
2124 if (fullpath
[idx
- 1] != '\\') fullpath
[idx
++] = '\\';
2126 if (filenamelen
) for (i
= 0; i
< filenamelen
; i
++) fullpath
[idx
++] = cab
->mii
.nextname
[i
];
2127 fullpath
[idx
] = '\0';
2129 TRACE("full cab path/file name: %s\n", debugstr_a(fullpath
));
2131 /* try to get a handle to the cabfile */
2132 cabhf
= PFDI_OPEN(CAB(hfdi
), fullpath
, 32768, _S_IREAD
| _S_IWRITE
);
2134 /* no file. allow the user to try again */
2135 fdin
.fdie
= FDIERROR_CABINET_NOT_FOUND
;
2136 if (((*pfnfdin
)(fdintNEXT_CABINET
, &fdin
))) return DECR_USERABORT
;
2141 ERR("PFDI_OPEN returned zero for %s.\n", fullpath
);
2142 fdin
.fdie
= FDIERROR_CABINET_NOT_FOUND
;
2143 if (((*pfnfdin
)(fdintNEXT_CABINET
, &fdin
))) return DECR_USERABORT
;
2147 /* check if it's really a cabfile. Note that this doesn't implement the bug */
2148 if (!FDI_read_entries(CAB(hfdi
), cabhf
, &fdici
, &(cab
->next
->mii
))) {
2149 WARN("FDIIsCabinet failed.\n");
2150 PFDI_CLOSE(CAB(hfdi
), cabhf
);
2151 fdin
.fdie
= FDIERROR_NOT_A_CABINET
;
2152 if (((*pfnfdin
)(fdintNEXT_CABINET
, &fdin
))) return DECR_USERABORT
;
2156 if ((fdici
.setID
!= cab
->setID
) || (fdici
.iCabinet
!= (cab
->iCabinet
+ 1))) {
2157 WARN("Wrong Cabinet.\n");
2158 PFDI_CLOSE(CAB(hfdi
), cabhf
);
2159 fdin
.fdie
= FDIERROR_WRONG_CABINET
;
2160 if (((*pfnfdin
)(fdintNEXT_CABINET
, &fdin
))) return DECR_USERABORT
;
2168 /* cabinet notification */
2169 ZeroMemory(&fdin
, sizeof(FDINOTIFICATION
));
2170 fdin
.setID
= fdici
.setID
;
2171 fdin
.iCabinet
= fdici
.iCabinet
;
2173 fdin
.psz1
= (cab
->next
->mii
.nextname
) ? cab
->next
->mii
.nextname
: &emptystring
;
2174 fdin
.psz2
= (cab
->next
->mii
.nextinfo
) ? cab
->next
->mii
.nextinfo
: &emptystring
;
2175 fdin
.psz3
= pszCabPath
;
2177 if (((*pfnfdin
)(fdintCABINET_INFO
, &fdin
))) return DECR_USERABORT
;
2179 cab
->next
->setID
= fdici
.setID
;
2180 cab
->next
->iCabinet
= fdici
.iCabinet
;
2181 cab
->next
->hfdi
= CAB(hfdi
);
2182 cab
->next
->filehf
= CAB(filehf
);
2183 cab
->next
->cabhf
= cabhf
;
2184 cab
->next
->decompress
= CAB(decompress
); /* crude, but unused anyhow */
2186 cab
= cab
->next
; /* advance to the next cabinet */
2189 for (i
= 0; i
< fdici
.cFolders
; i
++) {
2190 if (PFDI_READ(CAB(hfdi
), cab
->cabhf
, buf2
, cffold_SIZEOF
) != cffold_SIZEOF
)
2193 if (cab
->mii
.folder_resv
> 0)
2194 PFDI_SEEK(CAB(hfdi
), cab
->cabhf
, cab
->mii
.folder_resv
, SEEK_CUR
);
2196 fol
= (struct fdi_folder
*) PFDI_ALLOC(CAB(hfdi
), sizeof(struct fdi_folder
));
2198 ERR("out of memory!\n");
2199 return DECR_NOMEMORY
;
2201 ZeroMemory(fol
, sizeof(struct fdi_folder
));
2202 if (!(cab
->firstfol
)) cab
->firstfol
= fol
;
2204 fol
->offset
= (cab_off_t
) EndGetI32(buf2
+cffold_DataOffset
);
2205 fol
->num_blocks
= EndGetI16(buf2
+cffold_NumBlocks
);
2206 fol
->comp_type
= EndGetI16(buf2
+cffold_CompType
);
2209 linkfol
->next
= fol
;
2214 for (i
= 0; i
< fdici
.cFiles
; i
++) {
2215 if (PFDI_READ(CAB(hfdi
), cab
->cabhf
, buf2
, cffile_SIZEOF
) != cffile_SIZEOF
)
2218 file
= (struct fdi_file
*) PFDI_ALLOC(CAB(hfdi
), sizeof(struct fdi_file
));
2220 ERR("out of memory!\n");
2221 return DECR_NOMEMORY
;
2223 ZeroMemory(file
, sizeof(struct fdi_file
));
2224 if (!(cab
->firstfile
)) cab
->firstfile
= file
;
2226 file
->length
= EndGetI32(buf2
+cffile_UncompressedSize
);
2227 file
->offset
= EndGetI32(buf2
+cffile_FolderOffset
);
2228 file
->index
= EndGetI16(buf2
+cffile_FolderIndex
);
2229 file
->time
= EndGetI16(buf2
+cffile_Time
);
2230 file
->date
= EndGetI16(buf2
+cffile_Date
);
2231 file
->attribs
= EndGetI16(buf2
+cffile_Attribs
);
2232 file
->filename
= FDI_read_string(CAB(hfdi
), cab
->cabhf
, fdici
.cbCabinet
);
2234 if (!file
->filename
) return DECR_INPUT
;
2237 linkfile
->next
= file
;
2242 cab
= cab
->next
; /* advance to the next cabinet */
2244 /* iterate files -- if we encounter the continued file, process it --
2245 otherwise, jump to the label above and keep looking */
2247 for (file
= cab
->firstfile
; (file
); file
= file
->next
) {
2248 if ((file
->index
& cffileCONTINUED_FROM_PREV
) == cffileCONTINUED_FROM_PREV
) {
2249 /* check to ensure a real match */
2250 if (strcasecmp(fi
->filename
, file
->filename
) == 0) {
2252 if (PFDI_SEEK(CAB(hfdi
), cab
->cabhf
, cab
->firstfol
->offset
, SEEK_SET
) == -1)
2258 if (!success
) goto tryanothercab
; /* FIXME: shouldn't this trigger
2259 "Wrong Cabinet" notification? */
2263 /* decompress block */
2264 if ((err
= CAB(decompress
)(inlen
, outlen
, decomp_state
)))
2266 CAB(outlen
) = outlen
;
2267 CAB(outpos
) = CAB(outbuf
);
2270 CAB(decomp_cab
) = cab
;
2274 /***********************************************************************
2275 * FDICopy (CABINET.22)
2277 * Iterates through the files in the Cabinet file indicated by name and
2278 * file-location. May chain forward to additional cabinets (typically
2279 * only one) if files which begin in this Cabinet are continued in another
2280 * cabinet. For each file which is partially contained in this cabinet,
2281 * and partially contained in a prior cabinet, provides fdintPARTIAL_FILE
2282 * notification to the pfnfdin callback. For each file which begins in
2283 * this cabinet, fdintCOPY_FILE notification is provided to the pfnfdin
2284 * callback, and the file is optionally decompressed and saved to disk.
2285 * Notification is not provided for files which are not at least partially
2286 * contained in the specified cabinet file.
2288 * See below for a thorough explanation of the various notification
2292 * hfdi [I] An HFDI from FDICreate
2293 * pszCabinet [I] C-style string containing the filename of the cabinet
2294 * pszCabPath [I] C-style string containing the file path of the cabinet
2295 * flags [I] "Decoder parameters". Ignored. Suggested value: 0.
2296 * pfnfdin [I] Pointer to a notification function. See CALLBACKS below.
2297 * pfnfdid [I] Pointer to a decryption function. Ignored. Suggested
2299 * pvUser [I] arbitrary void * value which is passed to callbacks.
2302 * TRUE if successful.
2303 * FALSE if unsuccessful (error information is provided in the ERF structure
2304 * associated with the provided decompression handle by FDICreate).
2308 * Two pointers to callback functions are provided as parameters to FDICopy:
2309 * pfnfdin(of type PFNFDINOTIFY), and pfnfdid (of type PFNFDIDECRYPT). These
2310 * types are as follows:
2312 * typedef INT_PTR (__cdecl *PFNFDINOTIFY) ( FDINOTIFICATIONTYPE fdint,
2313 * PFDINOTIFICATION pfdin );
2315 * typedef int (__cdecl *PFNFDIDECRYPT) ( PFDIDECRYPT pfdid );
2317 * You can create functions of this type using the FNFDINOTIFY() and
2318 * FNFDIDECRYPT() macros, respectively. For example:
2320 * FNFDINOTIFY(mycallback) {
2321 * / * use variables fdint and pfdin to process notification * /
2324 * The second callback, which could be used for decrypting encrypted data,
2325 * is not used at all.
2327 * Each notification informs the user of some event which has occurred during
2328 * decompression of the cabinet file; each notification is also an opportunity
2329 * for the callee to abort decompression. The information provided to the
2330 * callback and the meaning of the callback's return value vary drastically
2331 * across the various types of notification. The type of notification is the
2332 * fdint parameter; all other information is provided to the callback in
2333 * notification-specific parts of the FDINOTIFICATION structure pointed to by
2334 * pfdin. The only part of that structure which is assigned for every callback
2335 * is the pv element, which contains the arbitrary value which was passed to
2336 * FDICopy in the pvUser argument (psz1 is also used each time, but its meaning
2337 * is highly dependent on fdint).
2339 * If you encounter unknown notifications, you should return zero if you want
2340 * decompression to continue (or -1 to abort). All strings used in the
2341 * callbacks are regular C-style strings. Detailed descriptions of each
2342 * notification type follow:
2344 * fdintCABINET_INFO:
2346 * This is the first notification provided after calling FDICopy, and provides
2347 * the user with various information about the cabinet. Note that this is
2348 * called for each cabinet FDICopy opens, not just the first one. In the
2349 * structure pointed to by pfdin, psz1 contains a pointer to the name of the
2350 * next cabinet file in the set after the one just loaded (if any), psz2
2351 * contains a pointer to the name or "info" of the next disk, psz3
2352 * contains a pointer to the file-path of the current cabinet, setID
2353 * contains an arbitrary constant associated with this set of cabinet files,
2354 * and iCabinet contains the numerical index of the current cabinet within
2355 * that set. Return zero, or -1 to abort.
2357 * fdintPARTIAL_FILE:
2359 * This notification is provided when FDICopy encounters a part of a file
2360 * contained in this cabinet which is missing its beginning. Files can be
2361 * split across cabinets, so this is not necessarily an abnormality; it just
2362 * means that the file in question begins in another cabinet. No file
2363 * corresponding to this notification is extracted from the cabinet. In the
2364 * structure pointed to by pfdin, psz1 contains a pointer to the name of the
2365 * partial file, psz2 contains a pointer to the file name of the cabinet in
2366 * which this file begins, and psz3 contains a pointer to the disk name or
2367 * "info" of the cabinet where the file begins. Return zero, or -1 to abort.
2371 * This notification is provided when FDICopy encounters a file which starts
2372 * in the cabinet file, provided to FDICopy in pszCabinet. (FDICopy will not
2373 * look for files in cabinets after the first one). One notification will be
2374 * sent for each such file, before the file is decompressed. By returning
2375 * zero, the callback can instruct FDICopy to skip the file. In the structure
2376 * pointed to by pfdin, psz1 contains a pointer to the file's name, cb contains
2377 * the size of the file (uncompressed), attribs contains the file attributes,
2378 * and date and time contain the date and time of the file. attributes, date,
2379 * and time are of the 16-bit ms-dos variety. Return -1 to abort decompression
2380 * for the entire cabinet, 0 to skip just this file but continue scanning the
2381 * cabinet for more files, or an FDIClose()-compatible file-handle.
2383 * fdintCLOSE_FILE_INFO:
2385 * This notification is important, don't forget to implement it. This
2386 * notification indicates that a file has been successfully uncompressed and
2387 * written to disk. Upon receipt of this notification, the callee is expected
2388 * to close the file handle, to set the attributes and date/time of the
2389 * closed file, and possibly to execute the file. In the structure pointed to
2390 * by pfdin, psz1 contains a pointer to the name of the file, hf will be the
2391 * open file handle (close it), cb contains 1 or zero, indicating respectively
2392 * that the callee should or should not execute the file, and date, time
2393 * and attributes will be set as in fdintCOPY_FILE. Bizarrely, the Cabinet SDK
2394 * specifies that _A_EXEC will be xor'ed out of attributes! wine does not do
2395 * do so. Return TRUE, or FALSE to abort decompression.
2397 * fdintNEXT_CABINET:
2399 * This notification is called when FDICopy must load in another cabinet. This
2400 * can occur when a file's data is "split" across multiple cabinets. The
2401 * callee has the opportunity to request that FDICopy look in a different file
2402 * path for the specified cabinet file, by writing that data into a provided
2403 * buffer (see below for more information). This notification will be received
2404 * more than once per-cabinet in the instance that FDICopy failed to find a
2405 * valid cabinet at the location specified by the first per-cabinet
2406 * fdintNEXT_CABINET notification. In such instances, the fdie element of the
2407 * structure pointed to by pfdin indicates the error which prevented FDICopy
2408 * from proceeding successfully. Return zero to indicate success, or -1 to
2409 * indicate failure and abort FDICopy.
2411 * Upon receipt of this notification, the structure pointed to by pfdin will
2412 * contain the following values: psz1 pointing to the name of the cabinet
2413 * which FDICopy is attempting to open, psz2 pointing to the name ("info") of
2414 * the next disk, psz3 pointing to the presumed file-location of the cabinet,
2415 * and fdie containing either FDIERROR_NONE, or one of the following:
2417 * FDIERROR_CABINET_NOT_FOUND, FDIERROR_NOT_A_CABINET,
2418 * FDIERROR_UNKNOWN_CABINET_VERSION, FDIERROR_CORRUPT_CABINET,
2419 * FDIERROR_BAD_COMPR_TYPE, FDIERROR_RESERVE_MISMATCH, and
2420 * FDIERROR_WRONG_CABINET.
2422 * The callee may choose to change the path where FDICopy will look for the
2423 * cabinet after this notification. To do so, the caller may write the new
2424 * pathname to the buffer pointed to by psz3, which is 256 characters in
2425 * length, including the terminating null character, before returning zero.
2429 * Undocumented and unimplemented in wine, this seems to be sent each time
2430 * a cabinet is opened, along with the fdintCABINET_INFO notification. It
2431 * probably has an interface similar to that of fdintCABINET_INFO; maybe this
2432 * provides information about the current cabinet instead of the next one....
2433 * this is just a guess, it has not been looked at closely.
2438 BOOL __cdecl
FDICopy(
2443 PFNFDINOTIFY pfnfdin
,
2444 PFNFDIDECRYPT pfnfdid
,
2447 FDICABINETINFO fdici
;
2448 FDINOTIFICATION fdin
;
2449 int cabhf
, filehf
= 0, idx
;
2451 char fullpath
[MAX_PATH
];
2452 size_t pathlen
, filenamelen
;
2453 char emptystring
= '\0';
2455 struct fdi_folder
*fol
= NULL
, *linkfol
= NULL
;
2456 struct fdi_file
*file
= NULL
, *linkfile
= NULL
;
2457 fdi_decomp_state _decomp_state
;
2458 fdi_decomp_state
*decomp_state
= &_decomp_state
;
2460 TRACE("(hfdi == ^%p, pszCabinet == ^%p, pszCabPath == ^%p, flags == %0d, "
2461 "pfnfdin == ^%p, pfnfdid == ^%p, pvUser == ^%p)\n",
2462 hfdi
, pszCabinet
, pszCabPath
, flags
, pfnfdin
, pfnfdid
, pvUser
);
2464 if (!REALLY_IS_FDI(hfdi
)) {
2465 SetLastError(ERROR_INVALID_HANDLE
);
2469 ZeroMemory(decomp_state
, sizeof(fdi_decomp_state
));
2471 pathlen
= (pszCabPath
) ? strlen(pszCabPath
) : 0;
2472 filenamelen
= (pszCabinet
) ? strlen(pszCabinet
) : 0;
2474 /* slight overestimation here to save CPU cycles in the developer's brain */
2475 if ((pathlen
+ filenamelen
+ 3) > MAX_PATH
) {
2476 ERR("MAX_PATH exceeded.\n");
2477 PFDI_INT(hfdi
)->perf
->erfOper
= FDIERROR_CABINET_NOT_FOUND
;
2478 PFDI_INT(hfdi
)->perf
->erfType
= ERROR_FILE_NOT_FOUND
;
2479 PFDI_INT(hfdi
)->perf
->fError
= TRUE
;
2480 SetLastError(ERROR_FILE_NOT_FOUND
);
2484 /* paste the path and filename together */
2487 for (i
= 0; i
< pathlen
; i
++) fullpath
[idx
++] = pszCabPath
[i
];
2488 if (fullpath
[idx
- 1] != '\\') fullpath
[idx
++] = '\\';
2490 if (filenamelen
) for (i
= 0; i
< filenamelen
; i
++) fullpath
[idx
++] = pszCabinet
[i
];
2491 fullpath
[idx
] = '\0';
2493 TRACE("full cab path/file name: %s\n", debugstr_a(fullpath
));
2495 /* get a handle to the cabfile */
2496 cabhf
= PFDI_OPEN(hfdi
, fullpath
, 32768, _S_IREAD
| _S_IWRITE
);
2498 PFDI_INT(hfdi
)->perf
->erfOper
= FDIERROR_CABINET_NOT_FOUND
;
2499 PFDI_INT(hfdi
)->perf
->erfType
= ERROR_FILE_NOT_FOUND
;
2500 PFDI_INT(hfdi
)->perf
->fError
= TRUE
;
2501 SetLastError(ERROR_FILE_NOT_FOUND
);
2506 ERR("PFDI_OPEN returned zero for %s.\n", fullpath
);
2507 PFDI_INT(hfdi
)->perf
->erfOper
= FDIERROR_CABINET_NOT_FOUND
;
2508 PFDI_INT(hfdi
)->perf
->erfType
= ERROR_FILE_NOT_FOUND
;
2509 PFDI_INT(hfdi
)->perf
->fError
= TRUE
;
2510 SetLastError(ERROR_FILE_NOT_FOUND
);
2514 /* check if it's really a cabfile. Note that this doesn't implement the bug */
2515 if (!FDI_read_entries(hfdi
, cabhf
, &fdici
, &(CAB(mii
)))) {
2516 ERR("FDIIsCabinet failed.\n");
2517 PFDI_CLOSE(hfdi
, cabhf
);
2521 /* cabinet notification */
2522 ZeroMemory(&fdin
, sizeof(FDINOTIFICATION
));
2523 fdin
.setID
= fdici
.setID
;
2524 fdin
.iCabinet
= fdici
.iCabinet
;
2526 fdin
.psz1
= (CAB(mii
).nextname
) ? CAB(mii
).nextname
: &emptystring
;
2527 fdin
.psz2
= (CAB(mii
).nextinfo
) ? CAB(mii
).nextinfo
: &emptystring
;
2528 fdin
.psz3
= pszCabPath
;
2530 if (((*pfnfdin
)(fdintCABINET_INFO
, &fdin
))) {
2531 PFDI_INT(hfdi
)->perf
->erfOper
= FDIERROR_USER_ABORT
;
2532 PFDI_INT(hfdi
)->perf
->erfType
= 0;
2533 PFDI_INT(hfdi
)->perf
->fError
= TRUE
;
2537 CAB(setID
) = fdici
.setID
;
2538 CAB(iCabinet
) = fdici
.iCabinet
;
2542 for (i
= 0; i
< fdici
.cFolders
; i
++) {
2543 if (PFDI_READ(hfdi
, cabhf
, buf
, cffold_SIZEOF
) != cffold_SIZEOF
) {
2544 PFDI_INT(hfdi
)->perf
->erfOper
= FDIERROR_CORRUPT_CABINET
;
2545 PFDI_INT(hfdi
)->perf
->erfType
= 0;
2546 PFDI_INT(hfdi
)->perf
->fError
= TRUE
;
2550 if (CAB(mii
).folder_resv
> 0)
2551 PFDI_SEEK(hfdi
, cabhf
, CAB(mii
).folder_resv
, SEEK_CUR
);
2553 fol
= (struct fdi_folder
*) PFDI_ALLOC(hfdi
, sizeof(struct fdi_folder
));
2555 ERR("out of memory!\n");
2556 PFDI_INT(hfdi
)->perf
->erfOper
= FDIERROR_ALLOC_FAIL
;
2557 PFDI_INT(hfdi
)->perf
->erfType
= ERROR_NOT_ENOUGH_MEMORY
;
2558 PFDI_INT(hfdi
)->perf
->fError
= TRUE
;
2559 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2562 ZeroMemory(fol
, sizeof(struct fdi_folder
));
2563 if (!CAB(firstfol
)) CAB(firstfol
) = fol
;
2565 fol
->offset
= (cab_off_t
) EndGetI32(buf
+cffold_DataOffset
);
2566 fol
->num_blocks
= EndGetI16(buf
+cffold_NumBlocks
);
2567 fol
->comp_type
= EndGetI16(buf
+cffold_CompType
);
2570 linkfol
->next
= fol
;
2575 for (i
= 0; i
< fdici
.cFiles
; i
++) {
2576 if (PFDI_READ(hfdi
, cabhf
, buf
, cffile_SIZEOF
) != cffile_SIZEOF
) {
2577 PFDI_INT(hfdi
)->perf
->erfOper
= FDIERROR_CORRUPT_CABINET
;
2578 PFDI_INT(hfdi
)->perf
->erfType
= 0;
2579 PFDI_INT(hfdi
)->perf
->fError
= TRUE
;
2583 file
= (struct fdi_file
*) PFDI_ALLOC(hfdi
, sizeof(struct fdi_file
));
2585 ERR("out of memory!\n");
2586 PFDI_INT(hfdi
)->perf
->erfOper
= FDIERROR_ALLOC_FAIL
;
2587 PFDI_INT(hfdi
)->perf
->erfType
= ERROR_NOT_ENOUGH_MEMORY
;
2588 PFDI_INT(hfdi
)->perf
->fError
= TRUE
;
2589 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2592 ZeroMemory(file
, sizeof(struct fdi_file
));
2593 if (!CAB(firstfile
)) CAB(firstfile
) = file
;
2595 file
->length
= EndGetI32(buf
+cffile_UncompressedSize
);
2596 file
->offset
= EndGetI32(buf
+cffile_FolderOffset
);
2597 file
->index
= EndGetI16(buf
+cffile_FolderIndex
);
2598 file
->time
= EndGetI16(buf
+cffile_Time
);
2599 file
->date
= EndGetI16(buf
+cffile_Date
);
2600 file
->attribs
= EndGetI16(buf
+cffile_Attribs
);
2601 file
->filename
= FDI_read_string(hfdi
, cabhf
, fdici
.cbCabinet
);
2603 if (!file
->filename
) {
2604 PFDI_INT(hfdi
)->perf
->erfOper
= FDIERROR_CORRUPT_CABINET
;
2605 PFDI_INT(hfdi
)->perf
->erfType
= 0;
2606 PFDI_INT(hfdi
)->perf
->fError
= TRUE
;
2611 linkfile
->next
= file
;
2615 for (file
= CAB(firstfile
); (file
); file
= file
->next
) {
2618 * FIXME: This implementation keeps multiple cabinet files open at once
2619 * when encountering a split cabinet. It is a quirk of this implementation
2620 * that sometimes we decrypt the same block of data more than once, to find
2621 * the right starting point for a file, moving the file-pointer backwards.
2622 * If we kept a cache of certain file-pointer information, we could eliminate
2623 * that behavior... in fact I am not sure that the caching we already have
2624 * is not sufficient.
2626 * The current implementation seems to work fine in straightforward situations
2627 * where all the cabinet files needed for decryption are simultaneously
2628 * available. But presumably, the API is supposed to support cabinets which
2629 * are split across multiple CDROMS; we may need to change our implementation
2630 * to strictly serialize it's file usage so that it opens only one cabinet
2631 * at a time. Some experimentation with Windows is needed to figure out the
2632 * precise semantics required. The relevant code is here and in fdi_decomp().
2635 /* partial-file notification */
2636 if ((file
->index
& cffileCONTINUED_FROM_PREV
) == cffileCONTINUED_FROM_PREV
) {
2638 * FIXME: Need to create a Cabinet with a single file spanning multiple files
2639 * and perform some tests to figure out the right behavior. The SDK says
2640 * FDICopy will notify the user of the filename and "disk name" (info) of
2641 * the cabinet where the spanning file /started/.
2643 * That would certainly be convenient for the API-user, who could abort,
2644 * everything (or parallelize, if that's allowed (it is in wine)), and call
2645 * FDICopy again with the provided filename, so as to avoid partial file
2646 * notification and successfully unpack. This task could be quite unpleasant
2647 * from wine's perspective: the information specifying the "start cabinet" for
2648 * a file is associated nowhere with the file header and is not to be found in
2649 * the cabinet header. We have only the index of the cabinet wherein the folder
2650 * begins, which contains the file. To find that cabinet, we must consider the
2651 * index of the current cabinet, and chain backwards, cabinet-by-cabinet (for
2652 * each cabinet refers to its "next" and "previous" cabinet only, like a linked
2655 * Bear in mind that, in the spirit of CABINET.DLL, we must assume that any
2656 * cabinet other than the active one might be at another filepath than the
2657 * current one, or on another CDROM. This could get rather dicey, especially
2658 * if we imagine parallelized access to the FDICopy API.
2660 * The current implementation punts -- it just returns the previous cabinet and
2661 * it's info from the header of this cabinet. This provides the right answer in
2662 * 95% of the cases; its worth checking if Microsoft cuts the same corner before
2665 ZeroMemory(&fdin
, sizeof(FDINOTIFICATION
));
2667 fdin
.psz1
= (char *)file
->filename
;
2668 fdin
.psz2
= (CAB(mii
).prevname
) ? CAB(mii
).prevname
: &emptystring
;
2669 fdin
.psz3
= (CAB(mii
).previnfo
) ? CAB(mii
).previnfo
: &emptystring
;
2671 if (((*pfnfdin
)(fdintPARTIAL_FILE
, &fdin
))) {
2672 PFDI_INT(hfdi
)->perf
->erfOper
= FDIERROR_USER_ABORT
;
2673 PFDI_INT(hfdi
)->perf
->erfType
= 0;
2674 PFDI_INT(hfdi
)->perf
->fError
= TRUE
;
2677 /* I don't think we are supposed to decompress partial files. This prevents it. */
2678 file
->oppressed
= TRUE
;
2680 if (file
->oppressed
) {
2683 ZeroMemory(&fdin
, sizeof(FDINOTIFICATION
));
2685 fdin
.psz1
= (char *)file
->filename
;
2686 fdin
.cb
= file
->length
;
2687 fdin
.date
= file
->date
;
2688 fdin
.time
= file
->time
;
2689 fdin
.attribs
= file
->attribs
;
2690 if ((filehf
= ((*pfnfdin
)(fdintCOPY_FILE
, &fdin
))) == -1) {
2691 PFDI_INT(hfdi
)->perf
->erfOper
= FDIERROR_USER_ABORT
;
2692 PFDI_INT(hfdi
)->perf
->erfType
= 0;
2693 PFDI_INT(hfdi
)->perf
->fError
= TRUE
;
2698 /* find the folder for this file if necc. */
2702 fol
= CAB(firstfol
);
2703 if ((file
->index
& cffileCONTINUED_TO_NEXT
) == cffileCONTINUED_TO_NEXT
) {
2704 /* pick the last folder */
2705 while (fol
->next
) fol
= fol
->next
;
2707 for (i2
= 0; (i2
< file
->index
); i2
++)
2708 if (fol
->next
) /* bug resistance, should always be true */
2714 cab_UWORD comptype
= fol
->comp_type
;
2715 int ct1
= comptype
& cffoldCOMPTYPE_MASK
;
2716 int ct2
= CAB(current
) ? (CAB(current
)->comp_type
& cffoldCOMPTYPE_MASK
) : 0;
2719 TRACE("Extracting file %s as requested by callee.\n", debugstr_a(file
->filename
));
2721 /* set up decomp_state */
2723 CAB(filehf
) = filehf
;
2725 /* Was there a change of folder? Compression type? Did we somehow go backwards? */
2726 if ((ct1
!= ct2
) || (CAB(current
) != fol
) || (file
->offset
< CAB(offset
))) {
2728 TRACE("Resetting folder for file %s.\n", debugstr_a(file
->filename
));
2730 /* free stuff for the old decompresser */
2732 case cffoldCOMPTYPE_LZX
:
2734 PFDI_FREE(hfdi
, LZX(window
));
2738 case cffoldCOMPTYPE_QUANTUM
:
2740 PFDI_FREE(hfdi
, QTM(window
));
2746 CAB(decomp_cab
) = NULL
;
2747 PFDI_SEEK(CAB(hfdi
), CAB(cabhf
), fol
->offset
, SEEK_SET
);
2751 /* initialize the new decompresser */
2753 case cffoldCOMPTYPE_NONE
:
2754 CAB(decompress
) = NONEfdi_decomp
;
2756 case cffoldCOMPTYPE_MSZIP
:
2757 CAB(decompress
) = ZIPfdi_decomp
;
2759 case cffoldCOMPTYPE_QUANTUM
:
2760 CAB(decompress
) = QTMfdi_decomp
;
2761 err
= QTMfdi_init((comptype
>> 8) & 0x1f, (comptype
>> 4) & 0xF, decomp_state
);
2763 case cffoldCOMPTYPE_LZX
:
2764 CAB(decompress
) = LZXfdi_decomp
;
2765 err
= LZXfdi_init((comptype
>> 8) & 0x1f, decomp_state
);
2768 err
= DECR_DATAFORMAT
;
2778 PFDI_INT(hfdi
)->perf
->erfOper
= FDIERROR_ALLOC_FAIL
;
2779 PFDI_INT(hfdi
)->perf
->erfType
= ERROR_NOT_ENOUGH_MEMORY
;
2780 PFDI_INT(hfdi
)->perf
->fError
= TRUE
;
2781 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2784 PFDI_INT(hfdi
)->perf
->erfOper
= FDIERROR_CORRUPT_CABINET
;
2785 PFDI_INT(hfdi
)->perf
->erfOper
= 0;
2786 PFDI_INT(hfdi
)->perf
->fError
= TRUE
;
2790 if (file
->offset
> CAB(offset
)) {
2791 /* decode bytes and send them to /dev/null */
2792 switch ((err
= fdi_decomp(file
, 0, decomp_state
, pszCabPath
, pfnfdin
, pvUser
))) {
2795 case DECR_USERABORT
:
2796 PFDI_INT(hfdi
)->perf
->erfOper
= FDIERROR_USER_ABORT
;
2797 PFDI_INT(hfdi
)->perf
->erfType
= 0;
2798 PFDI_INT(hfdi
)->perf
->fError
= TRUE
;
2801 PFDI_INT(hfdi
)->perf
->erfOper
= FDIERROR_ALLOC_FAIL
;
2802 PFDI_INT(hfdi
)->perf
->erfType
= ERROR_NOT_ENOUGH_MEMORY
;
2803 PFDI_INT(hfdi
)->perf
->fError
= TRUE
;
2804 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2807 PFDI_INT(hfdi
)->perf
->erfOper
= FDIERROR_CORRUPT_CABINET
;
2808 PFDI_INT(hfdi
)->perf
->erfOper
= 0;
2809 PFDI_INT(hfdi
)->perf
->fError
= TRUE
;
2812 CAB(offset
) = file
->offset
;
2815 /* now do the actual decompression */
2816 err
= fdi_decomp(file
, 1, decomp_state
, pszCabPath
, pfnfdin
, pvUser
);
2817 if (err
) CAB(current
) = NULL
; else CAB(offset
) += file
->length
;
2819 /* fdintCLOSE_FILE_INFO notification */
2820 ZeroMemory(&fdin
, sizeof(FDINOTIFICATION
));
2822 fdin
.psz1
= (char *)file
->filename
;
2824 fdin
.cb
= (file
->attribs
& cffile_A_EXEC
) ? TRUE
: FALSE
; /* FIXME: is that right? */
2825 fdin
.date
= file
->date
;
2826 fdin
.time
= file
->time
;
2827 fdin
.attribs
= file
->attribs
; /* FIXME: filter _A_EXEC? */
2828 ((*pfnfdin
)(fdintCLOSE_FILE_INFO
, &fdin
));
2834 case DECR_USERABORT
:
2835 PFDI_INT(hfdi
)->perf
->erfOper
= FDIERROR_USER_ABORT
;
2836 PFDI_INT(hfdi
)->perf
->erfType
= 0;
2837 PFDI_INT(hfdi
)->perf
->fError
= TRUE
;
2840 PFDI_INT(hfdi
)->perf
->erfOper
= FDIERROR_ALLOC_FAIL
;
2841 PFDI_INT(hfdi
)->perf
->erfType
= ERROR_NOT_ENOUGH_MEMORY
;
2842 PFDI_INT(hfdi
)->perf
->fError
= TRUE
;
2843 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2846 PFDI_INT(hfdi
)->perf
->erfOper
= FDIERROR_CORRUPT_CABINET
;
2847 PFDI_INT(hfdi
)->perf
->erfOper
= 0;
2848 PFDI_INT(hfdi
)->perf
->fError
= TRUE
;
2854 /* free decompression temps */
2855 switch (fol
->comp_type
& cffoldCOMPTYPE_MASK
) {
2856 case cffoldCOMPTYPE_LZX
:
2858 PFDI_FREE(hfdi
, LZX(window
));
2862 case cffoldCOMPTYPE_QUANTUM
:
2864 PFDI_FREE(hfdi
, QTM(window
));
2870 while (decomp_state
) {
2871 fdi_decomp_state
*prev_fds
;
2873 PFDI_CLOSE(hfdi
, CAB(cabhf
));
2875 /* free the storage remembered by mii */
2876 if (CAB(mii
).nextname
) PFDI_FREE(hfdi
, CAB(mii
).nextname
);
2877 if (CAB(mii
).nextinfo
) PFDI_FREE(hfdi
, CAB(mii
).nextinfo
);
2878 if (CAB(mii
).prevname
) PFDI_FREE(hfdi
, CAB(mii
).prevname
);
2879 if (CAB(mii
).previnfo
) PFDI_FREE(hfdi
, CAB(mii
).previnfo
);
2881 while (CAB(firstfol
)) {
2882 fol
= CAB(firstfol
);
2883 CAB(firstfol
) = CAB(firstfol
)->next
;
2884 PFDI_FREE(hfdi
, fol
);
2886 while (CAB(firstfile
)) {
2887 file
= CAB(firstfile
);
2888 if (file
->filename
) PFDI_FREE(hfdi
, (void *)file
->filename
);
2889 CAB(firstfile
) = CAB(firstfile
)->next
;
2890 PFDI_FREE(hfdi
, file
);
2892 prev_fds
= decomp_state
;
2893 decomp_state
= CAB(next
);
2894 if (prev_fds
!= &_decomp_state
)
2895 PFDI_FREE(hfdi
, prev_fds
);
2900 bail_and_fail
: /* here we free ram before error returns */
2902 /* free decompression temps */
2903 switch (fol
->comp_type
& cffoldCOMPTYPE_MASK
) {
2904 case cffoldCOMPTYPE_LZX
:
2906 PFDI_FREE(hfdi
, LZX(window
));
2910 case cffoldCOMPTYPE_QUANTUM
:
2912 PFDI_FREE(hfdi
, QTM(window
));
2918 if (filehf
) PFDI_CLOSE(hfdi
, filehf
);
2920 while (decomp_state
) {
2921 fdi_decomp_state
*prev_fds
;
2923 PFDI_CLOSE(hfdi
, CAB(cabhf
));
2925 /* free the storage remembered by mii */
2926 if (CAB(mii
).nextname
) PFDI_FREE(hfdi
, CAB(mii
).nextname
);
2927 if (CAB(mii
).nextinfo
) PFDI_FREE(hfdi
, CAB(mii
).nextinfo
);
2928 if (CAB(mii
).prevname
) PFDI_FREE(hfdi
, CAB(mii
).prevname
);
2929 if (CAB(mii
).previnfo
) PFDI_FREE(hfdi
, CAB(mii
).previnfo
);
2931 while (CAB(firstfol
)) {
2932 fol
= CAB(firstfol
);
2933 CAB(firstfol
) = CAB(firstfol
)->next
;
2934 PFDI_FREE(hfdi
, fol
);
2936 while (CAB(firstfile
)) {
2937 file
= CAB(firstfile
);
2938 if (file
->filename
) PFDI_FREE(hfdi
, (void *)file
->filename
);
2939 CAB(firstfile
) = CAB(firstfile
)->next
;
2940 PFDI_FREE(hfdi
, file
);
2942 prev_fds
= decomp_state
;
2943 decomp_state
= CAB(next
);
2944 if (prev_fds
!= &_decomp_state
)
2945 PFDI_FREE(hfdi
, prev_fds
);
2951 /***********************************************************************
2952 * FDIDestroy (CABINET.23)
2954 * Frees a handle created by FDICreate. Do /not/ call this in the middle
2955 * of FDICopy. Only reason for failure would be an invalid handle.
2958 * hfdi [I] The HFDI to free
2964 BOOL __cdecl
FDIDestroy(HFDI hfdi
)
2966 TRACE("(hfdi == ^%p)\n", hfdi
);
2967 if (REALLY_IS_FDI(hfdi
)) {
2968 PFDI_INT(hfdi
)->FDI_Intmagic
= 0; /* paranoia */
2969 PFDI_FREE(hfdi
, hfdi
); /* confusing, but correct */
2972 SetLastError(ERROR_INVALID_HANDLE
);
2977 /***********************************************************************
2978 * FDITruncateCabinet (CABINET.24)
2980 * Removes all folders of a cabinet file after and including the
2981 * specified folder number.
2984 * hfdi [I] Handle to the FDI context.
2985 * pszCabinetName [I] Filename of the cabinet.
2986 * iFolderToDelete [I] Index of the first folder to delete.
2993 * The PFNWRITE function supplied to FDICreate must truncate the
2994 * file at the current position if the number of bytes to write is 0.
2996 BOOL __cdecl
FDITruncateCabinet(
2998 char *pszCabinetName
,
2999 USHORT iFolderToDelete
)
3001 FIXME("(hfdi == ^%p, pszCabinetName == %s, iFolderToDelete == %hu): stub\n",
3002 hfdi
, debugstr_a(pszCabinetName
), iFolderToDelete
);
3004 if (!REALLY_IS_FDI(hfdi
)) {
3005 SetLastError(ERROR_INVALID_HANDLE
);
3009 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);