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 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 */
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
;
126 #define FDI_INT_MAGIC 0xfdfdfd05
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.
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
];
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
;
161 struct fdi_folder
*firstfol
;
162 struct fdi_file
*firstfile
;
163 struct fdi_cds_fwd
*next
;
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);}
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]))
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)
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)
187 static void set_error( FDI_Int
*fdi
, int oper
, int err
)
189 fdi
->perf
->erfOper
= oper
;
190 fdi
->perf
->erfType
= err
;
191 fdi
->perf
->fError
= TRUE
;
192 if (err
) SetLastError( err
);
195 static FDI_Int
*get_fdi_ptr( HFDI hfdi
)
197 FDI_Int
*fdi
= (FDI_Int
*)hfdi
;
199 if (!fdi
|| !fdi
->magic
== FDI_INT_MAGIC
)
201 SetLastError( ERROR_INVALID_HANDLE
);
207 /****************************************************************
208 * QTMupdatemodel (internal)
210 static void QTMupdatemodel(struct QTMmodel
*model
, int sym
) {
211 struct QTMmodelsym temp
;
214 for (i
= 0; i
< sym
; i
++) model
->syms
[i
].cumfreq
+= 8;
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;
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;
236 /* now sort by frequencies, decreasing order -- this must be an
237 * inplace selection sort, or a sort with the same (in)stability
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
;
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
;
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
;
262 /*************************************************************************
263 * make_decode_table (internal)
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.
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.
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;
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 */
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
) {
296 if((pos
+= bit_mask
) > table_mask
) return 1; /* table overrun */
298 /* fill all possible lookups of this symbol with the symbol itself */
300 while (fill
-- > 0) table
[leaf
++] = sym
;
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;
312 /* give ourselves room for codes to grow by up to 16 more bits */
317 while (bit_num
<= 16) {
318 for (sym
= 0; sym
< nsyms
; sym
++) {
319 if (length
[sym
] == bit_num
) {
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
++;
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
++;
334 if ((pos
+= bit_mask
) > table_mask
) return 1; /* table overflow */
343 if (pos
== table_mask
) return 0;
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;
350 /*************************************************************************
351 * checksum (internal)
353 static cab_ULONG
checksum(const cab_UBYTE
*data
, cab_UWORD bytes
, cab_ULONG csum
) {
357 for (len
= bytes
>> 2; len
--; data
+= 4) {
358 csum
^= ((data
[0]) | (data
[1]<<8) | (data
[2]<<16) | (data
[3]<<24));
362 case 3: ul
|= *data
++ << 16;
363 case 2: ul
|= *data
++ << 8;
371 /***********************************************************************
372 * FDICreate (CABINET.20)
374 * Provided with several callbacks (all of them are mandatory),
375 * returns a handle which can be used to perform operations
379 * pfnalloc [I] A pointer to a function which allocates ram. Uses
380 * the same interface as malloc.
381 * pfnfree [I] A pointer to a function which frees ram. Uses the
382 * same interface as free.
383 * pfnopen [I] A pointer to a function which opens a file. Uses
384 * the same interface as _open.
385 * pfnread [I] A pointer to a function which reads from a file into
386 * a caller-provided buffer. Uses the same interface
388 * pfnwrite [I] A pointer to a function which writes to a file from
389 * a caller-provided buffer. Uses the same interface
391 * pfnclose [I] A pointer to a function which closes a file handle.
392 * Uses the same interface as _close.
393 * pfnseek [I] A pointer to a function which seeks in a file.
394 * Uses the same interface as _lseek.
395 * cpuType [I] The type of CPU; ignored in wine (recommended value:
396 * cpuUNKNOWN, aka -1).
397 * perf [IO] A pointer to an ERF structure. When FDICreate
398 * returns an error condition, error information may
399 * be found here as well as from GetLastError.
402 * On success, returns an FDI handle of type HFDI.
403 * On failure, the NULL file handle is returned. Error
404 * info can be retrieved from perf.
410 HFDI __cdecl
FDICreate(
423 TRACE("(pfnalloc == ^%p, pfnfree == ^%p, pfnopen == ^%p, pfnread == ^%p, pfnwrite == ^%p, "
424 "pfnclose == ^%p, pfnseek == ^%p, cpuType == %d, perf == ^%p)\n",
425 pfnalloc
, pfnfree
, pfnopen
, pfnread
, pfnwrite
, pfnclose
, pfnseek
,
428 if ((!pfnalloc
) || (!pfnfree
)) {
429 perf
->erfOper
= FDIERROR_NONE
;
430 perf
->erfType
= ERROR_BAD_ARGUMENTS
;
433 SetLastError(ERROR_BAD_ARGUMENTS
);
437 if (!((fdi
= pfnalloc(sizeof(FDI_Int
))))) {
438 perf
->erfOper
= FDIERROR_ALLOC_FAIL
;
439 perf
->erfType
= ERROR_NOT_ENOUGH_MEMORY
;
442 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
446 fdi
->magic
= FDI_INT_MAGIC
;
447 fdi
->alloc
= pfnalloc
;
451 fdi
->write
= pfnwrite
;
452 fdi
->close
= pfnclose
;
454 /* no-brainer: we ignore the cpu type; this is only used
455 for the 16-bit versions in Windows anyhow... */
461 /*******************************************************************
462 * FDI_getoffset (internal)
464 * returns the file pointer position of a file handle.
466 static LONG
FDI_getoffset(FDI_Int
*fdi
, INT_PTR hf
)
468 return fdi
->seek(hf
, 0, SEEK_CUR
);
471 /**********************************************************************
472 * FDI_read_string (internal)
474 * allocate and read an arbitrarily long string from the cabinet
476 static char *FDI_read_string(FDI_Int
*fdi
, INT_PTR hf
, long cabsize
)
479 base
= FDI_getoffset(fdi
, hf
),
480 maxlen
= cabsize
- base
;
483 cab_UBYTE
*buf
= NULL
;
485 TRACE("(fdi == %p, hf == %ld, cabsize == %ld)\n", fdi
, hf
, cabsize
);
488 if (len
> maxlen
) len
= maxlen
;
489 if (!(buf
= fdi
->alloc(len
))) break;
490 if (!fdi
->read(hf
, buf
, len
)) break;
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;}
499 ERR("cabinet is truncated\n");
502 /* The buffer is too small for the string. Reset the file to the point
503 * were we started, free the buffer and increase the size for the next try
505 fdi
->seek(hf
, base
, SEEK_SET
);
516 ERR("out of memory!\n");
520 /* otherwise, set the stream to just after the string and return */
521 fdi
->seek(hf
, base
+ strlen((char *)buf
) + 1, SEEK_SET
);
526 /******************************************************************
527 * FDI_read_entries (internal)
529 * process the cabinet header in the style of FDIIsCabinet, but
530 * without the sanity checks (and bug)
532 static BOOL
FDI_read_entries(
535 PFDICABINETINFO pfdici
,
536 PMORE_ISCAB_INFO pmii
)
538 int num_folders
, num_files
, header_resv
, folder_resv
= 0;
539 LONG base_offset
, cabsize
;
540 USHORT setid
, cabidx
, flags
;
541 cab_UBYTE buf
[64], block_resv
;
542 char *prevname
= NULL
, *previnfo
= NULL
, *nextname
= NULL
, *nextinfo
= NULL
;
544 TRACE("(fdi == ^%p, hf == %ld, pfdici == ^%p)\n", fdi
, hf
, pfdici
);
547 * FIXME: I just noticed that I am memorizing the initial file pointer
548 * offset and restoring it before reading in the rest of the header
549 * information in the cabinet. Perhaps that's correct -- that is, perhaps
550 * this API is supposed to support "streaming" cabinets which are embedded
551 * in other files, or cabinets which begin at file offsets other than zero.
552 * Otherwise, I should instead go to the absolute beginning of the file.
553 * (Either way, the semantics of wine's FDICopy require me to leave the
554 * file pointer where it is afterwards -- If Windows does not do so, we
555 * ought to duplicate the native behavior in the FDIIsCabinet API, not here.
557 * So, the answer lies in Windows; will native cabinet.dll recognize a
558 * cabinet "file" embedded in another file? Note that cabextract.c does
559 * support this, which implies that Microsoft's might. I haven't tried it
560 * yet so I don't know. ATM, most of wine's FDI cabinet routines (except
561 * this one) would not work in this way. To fix it, we could just make the
562 * various references to absolute file positions in the code relative to an
563 * initial "beginning" offset. Because the FDICopy API doesn't take a
564 * file-handle like this one, we would therein need to search through the
565 * file for the beginning of the cabinet (as we also do in cabextract.c).
566 * Note that this limits us to a maximum of one cabinet per. file: the first.
568 * So, in summary: either the code below is wrong, or the rest of fdi.c is
569 * wrong... I cannot imagine that both are correct ;) One of these flaws
570 * should be fixed after determining the behavior on Windows. We ought
571 * to check both FDIIsCabinet and FDICopy for the right behavior.
576 /* get basic offset & size info */
577 base_offset
= FDI_getoffset(fdi
, hf
);
579 if (fdi
->seek(hf
, 0, SEEK_END
) == -1) {
580 if (pmii
) set_error( fdi
, FDIERROR_NOT_A_CABINET
, 0 );
584 cabsize
= FDI_getoffset(fdi
, hf
);
586 if ((cabsize
== -1) || (base_offset
== -1) ||
587 ( fdi
->seek(hf
, base_offset
, SEEK_SET
) == -1 )) {
588 if (pmii
) set_error( fdi
, FDIERROR_NOT_A_CABINET
, 0 );
592 /* read in the CFHEADER */
593 if (fdi
->read(hf
, buf
, cfhead_SIZEOF
) != cfhead_SIZEOF
) {
594 if (pmii
) set_error( fdi
, FDIERROR_NOT_A_CABINET
, 0 );
598 /* check basic MSCF signature */
599 if (EndGetI32(buf
+cfhead_Signature
) != 0x4643534d) {
600 if (pmii
) set_error( fdi
, FDIERROR_NOT_A_CABINET
, 0 );
604 /* get the number of folders */
605 num_folders
= EndGetI16(buf
+cfhead_NumFolders
);
606 if (num_folders
== 0) {
607 /* PONDERME: is this really invalid? */
608 WARN("weird cabinet detect failure: no folders in cabinet\n");
609 if (pmii
) set_error( fdi
, FDIERROR_NOT_A_CABINET
, 0 );
613 /* get the number of files */
614 num_files
= EndGetI16(buf
+cfhead_NumFiles
);
615 if (num_files
== 0) {
616 /* PONDERME: is this really invalid? */
617 WARN("weird cabinet detect failure: no files in cabinet\n");
618 if (pmii
) set_error( fdi
, FDIERROR_NOT_A_CABINET
, 0 );
623 setid
= EndGetI16(buf
+cfhead_SetID
);
625 /* cabinet (set) index */
626 cabidx
= EndGetI16(buf
+cfhead_CabinetIndex
);
628 /* check the header revision */
629 if ((buf
[cfhead_MajorVersion
] > 1) ||
630 (buf
[cfhead_MajorVersion
] == 1 && buf
[cfhead_MinorVersion
] > 3))
632 WARN("cabinet format version > 1.3\n");
633 if (pmii
) set_error( fdi
, FDIERROR_UNKNOWN_CABINET_VERSION
, 0 /* ? */ );
637 /* pull the flags out */
638 flags
= EndGetI16(buf
+cfhead_Flags
);
640 /* read the reserved-sizes part of header, if present */
641 if (flags
& cfheadRESERVE_PRESENT
) {
642 if (fdi
->read(hf
, buf
, cfheadext_SIZEOF
) != cfheadext_SIZEOF
) {
643 ERR("bunk reserve-sizes?\n");
644 if (pmii
) set_error( fdi
, FDIERROR_CORRUPT_CABINET
, 0 /* ? */ );
648 header_resv
= EndGetI16(buf
+cfheadext_HeaderReserved
);
649 if (pmii
) pmii
->header_resv
= header_resv
;
650 folder_resv
= buf
[cfheadext_FolderReserved
];
651 if (pmii
) pmii
->folder_resv
= folder_resv
;
652 block_resv
= buf
[cfheadext_DataReserved
];
653 if (pmii
) pmii
->block_resv
= block_resv
;
655 if (header_resv
> 60000) {
656 WARN("WARNING; header reserved space > 60000\n");
659 /* skip the reserved header */
660 if ((header_resv
) && (fdi
->seek(hf
, header_resv
, SEEK_CUR
) == -1)) {
661 ERR("seek failure: header_resv\n");
662 if (pmii
) set_error( fdi
, FDIERROR_CORRUPT_CABINET
, 0 /* ? */ );
667 if (flags
& cfheadPREV_CABINET
) {
668 prevname
= FDI_read_string(fdi
, hf
, cabsize
);
670 if (pmii
) set_error( fdi
, FDIERROR_CORRUPT_CABINET
, 0 /* ? */ );
674 pmii
->prevname
= prevname
;
677 previnfo
= FDI_read_string(fdi
, hf
, cabsize
);
680 pmii
->previnfo
= previnfo
;
686 if (flags
& cfheadNEXT_CABINET
) {
688 pmii
->hasnext
= TRUE
;
689 nextname
= FDI_read_string(fdi
, hf
, cabsize
);
691 if ((flags
& cfheadPREV_CABINET
) && pmii
) {
692 if (pmii
->prevname
) fdi
->free(prevname
);
693 if (pmii
->previnfo
) fdi
->free(previnfo
);
695 set_error( fdi
, FDIERROR_CORRUPT_CABINET
, 0 /* ? */ );
699 pmii
->nextname
= nextname
;
702 nextinfo
= FDI_read_string(fdi
, hf
, cabsize
);
705 pmii
->nextinfo
= nextinfo
;
711 /* we could process the whole cabinet searching for problems;
712 instead lets stop here. Now let's fill out the paperwork */
713 pfdici
->cbCabinet
= cabsize
;
714 pfdici
->cFolders
= num_folders
;
715 pfdici
->cFiles
= num_files
;
716 pfdici
->setID
= setid
;
717 pfdici
->iCabinet
= cabidx
;
718 pfdici
->fReserve
= (flags
& cfheadRESERVE_PRESENT
) ? TRUE
: FALSE
;
719 pfdici
->hasprev
= (flags
& cfheadPREV_CABINET
) ? TRUE
: FALSE
;
720 pfdici
->hasnext
= (flags
& cfheadNEXT_CABINET
) ? TRUE
: FALSE
;
724 /***********************************************************************
725 * FDIIsCabinet (CABINET.21)
727 * Informs the caller as to whether or not the provided file handle is
728 * really a cabinet or not, filling out the provided PFDICABINETINFO
729 * structure with information about the cabinet. Brief explanations of
730 * the elements of this structure are available as comments accompanying
731 * its definition in wine's include/fdi.h.
734 * hfdi [I] An HFDI from FDICreate
735 * hf [I] The file handle about which the caller inquires
736 * pfdici [IO] Pointer to a PFDICABINETINFO structure which will
737 * be filled out with information about the cabinet
738 * file indicated by hf if, indeed, it is determined
742 * TRUE if the file is a cabinet. The info pointed to by pfdici will
744 * FALSE if the file is not a cabinet, or if an error was encountered
745 * while processing the cabinet. The PERF structure provided to
746 * FDICreate can be queried for more error information.
751 BOOL __cdecl
FDIIsCabinet(
754 PFDICABINETINFO pfdici
)
757 FDI_Int
*fdi
= get_fdi_ptr( hfdi
);
759 TRACE("(hfdi == ^%p, hf == ^%ld, pfdici == ^%p)\n", hfdi
, hf
, pfdici
);
761 if (!fdi
) return FALSE
;
765 SetLastError(ERROR_INVALID_HANDLE
);
771 SetLastError(ERROR_BAD_ARGUMENTS
);
774 rv
= FDI_read_entries(fdi
, hf
, pfdici
, NULL
);
777 pfdici
->hasnext
= FALSE
; /* yuck. duplicate apparent cabinet.dll bug */
782 /******************************************************************
783 * QTMfdi_initmodel (internal)
785 * Initialize a model which decodes symbols from [s] to [s]+[n]-1
787 static void QTMfdi_initmodel(struct QTMmodel
*m
, struct QTMmodelsym
*sym
, int n
, int s
) {
792 memset(m
->tabloc
, 0xFF, sizeof(m
->tabloc
)); /* clear out look-up table */
793 for (i
= 0; i
< n
; i
++) {
794 m
->tabloc
[i
+s
] = i
; /* set up a look-up entry for symbol */
795 m
->syms
[i
].sym
= i
+s
; /* actual symbol */
796 m
->syms
[i
].cumfreq
= n
-i
; /* current frequency of that symbol */
798 m
->syms
[n
].cumfreq
= 0;
801 /******************************************************************
802 * QTMfdi_init (internal)
804 static int QTMfdi_init(int window
, int level
, fdi_decomp_state
*decomp_state
) {
805 unsigned int wndsize
= 1 << window
;
806 int msz
= window
* 2, i
;
809 /* QTM supports window sizes of 2^10 (1Kb) through 2^21 (2Mb) */
810 /* if a previously allocated window is big enough, keep it */
811 if (window
< 10 || window
> 21) return DECR_DATAFORMAT
;
812 if (QTM(actual_size
) < wndsize
) {
813 if (QTM(window
)) CAB(fdi
)->free(QTM(window
));
817 if (!(QTM(window
) = CAB(fdi
)->alloc(wndsize
))) return DECR_NOMEMORY
;
818 QTM(actual_size
) = wndsize
;
820 QTM(window_size
) = wndsize
;
821 QTM(window_posn
) = 0;
823 /* initialize static slot/extrabits tables */
824 for (i
= 0, j
= 0; i
< 27; i
++) {
825 CAB(q_length_extra
)[i
] = (i
== 26) ? 0 : (i
< 2 ? 0 : i
- 2) >> 2;
826 CAB(q_length_base
)[i
] = j
; j
+= 1 << ((i
== 26) ? 5 : CAB(q_length_extra
)[i
]);
828 for (i
= 0, j
= 0; i
< 42; i
++) {
829 CAB(q_extra_bits
)[i
] = (i
< 2 ? 0 : i
-2) >> 1;
830 CAB(q_position_base
)[i
] = j
; j
+= 1 << CAB(q_extra_bits
)[i
];
833 /* initialize arithmetic coding models */
835 QTMfdi_initmodel(&QTM(model7
), &QTM(m7sym
)[0], 7, 0);
837 QTMfdi_initmodel(&QTM(model00
), &QTM(m00sym
)[0], 0x40, 0x00);
838 QTMfdi_initmodel(&QTM(model40
), &QTM(m40sym
)[0], 0x40, 0x40);
839 QTMfdi_initmodel(&QTM(model80
), &QTM(m80sym
)[0], 0x40, 0x80);
840 QTMfdi_initmodel(&QTM(modelC0
), &QTM(mC0sym
)[0], 0x40, 0xC0);
842 /* model 4 depends on table size, ranges from 20 to 24 */
843 QTMfdi_initmodel(&QTM(model4
), &QTM(m4sym
)[0], (msz
< 24) ? msz
: 24, 0);
844 /* model 5 depends on table size, ranges from 20 to 36 */
845 QTMfdi_initmodel(&QTM(model5
), &QTM(m5sym
)[0], (msz
< 36) ? msz
: 36, 0);
846 /* model 6pos depends on table size, ranges from 20 to 42 */
847 QTMfdi_initmodel(&QTM(model6pos
), &QTM(m6psym
)[0], msz
, 0);
848 QTMfdi_initmodel(&QTM(model6len
), &QTM(m6lsym
)[0], 27, 0);
853 /************************************************************
854 * LZXfdi_init (internal)
856 static int LZXfdi_init(int window
, fdi_decomp_state
*decomp_state
) {
857 static const cab_UBYTE bits
[] =
858 { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
859 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14,
860 15, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
862 static const cab_ULONG base
[] =
863 { 0, 1, 2, 3, 4, 6, 8, 12,
864 16, 24, 32, 48, 64, 96, 128, 192,
865 256, 384, 512, 768, 1024, 1536, 2048, 3072,
866 4096, 6144, 8192, 12288, 16384, 24576, 32768, 49152,
867 65536, 98304, 131072, 196608, 262144, 393216, 524288, 655360,
868 786432, 917504, 1048576, 1179648, 1310720, 1441792, 1572864, 1703936,
869 1835008, 1966080, 2097152};
870 cab_ULONG wndsize
= 1 << window
;
873 /* LZX supports window sizes of 2^15 (32Kb) through 2^21 (2Mb) */
874 /* if a previously allocated window is big enough, keep it */
875 if (window
< 15 || window
> 21) return DECR_DATAFORMAT
;
876 if (LZX(actual_size
) < wndsize
) {
877 if (LZX(window
)) CAB(fdi
)->free(LZX(window
));
881 if (!(LZX(window
) = CAB(fdi
)->alloc(wndsize
))) return DECR_NOMEMORY
;
882 LZX(actual_size
) = wndsize
;
884 LZX(window_size
) = wndsize
;
886 /* initialize static tables */
887 memcpy(CAB(extra_bits
), bits
, sizeof(bits
));
888 memcpy(CAB(lzx_position_base
), base
, sizeof(base
));
890 /* calculate required position slots */
891 if (window
== 20) posn_slots
= 42;
892 else if (window
== 21) posn_slots
= 50;
893 else posn_slots
= window
<< 1;
895 /*posn_slots=i=0; while (i < wndsize) i += 1 << CAB(extra_bits)[posn_slots++]; */
897 LZX(R0
) = LZX(R1
) = LZX(R2
) = 1;
898 LZX(main_elements
) = LZX_NUM_CHARS
+ (posn_slots
<< 3);
899 LZX(header_read
) = 0;
900 LZX(frames_read
) = 0;
901 LZX(block_remaining
) = 0;
902 LZX(block_type
) = LZX_BLOCKTYPE_INVALID
;
903 LZX(intel_curpos
) = 0;
904 LZX(intel_started
) = 0;
905 LZX(window_posn
) = 0;
907 /* initialize tables to 0 (because deltas will be applied to them) */
908 memset(LZX(MAINTREE_len
), 0, sizeof(LZX(MAINTREE_len
)));
909 memset(LZX(LENGTH_len
), 0, sizeof(LZX(LENGTH_len
)));
914 /****************************************************
915 * NONEfdi_decomp(internal)
917 static int NONEfdi_decomp(int inlen
, int outlen
, fdi_decomp_state
*decomp_state
)
919 if (inlen
!= outlen
) return DECR_ILLEGALDATA
;
920 if (outlen
> CAB_BLOCKMAX
) return DECR_DATAFORMAT
;
921 memcpy(CAB(outbuf
), CAB(inbuf
), (size_t) inlen
);
925 /********************************************************
926 * Ziphuft_free (internal)
928 static void fdi_Ziphuft_free(FDI_Int
*fdi
, struct Ziphuft
*t
)
930 register struct Ziphuft
*p
, *q
;
932 /* Go through linked list, freeing from the allocated (t[-1]) address. */
942 /*********************************************************
943 * fdi_Ziphuft_build (internal)
945 static cab_LONG
fdi_Ziphuft_build(cab_ULONG
*b
, cab_ULONG n
, cab_ULONG s
, const cab_UWORD
*d
, const cab_UWORD
*e
,
946 struct Ziphuft
**t
, cab_LONG
*m
, fdi_decomp_state
*decomp_state
)
948 cab_ULONG a
; /* counter for codes of length k */
949 cab_ULONG el
; /* length of EOB code (value 256) */
950 cab_ULONG f
; /* i repeats in table every f entries */
951 cab_LONG g
; /* maximum code length */
952 cab_LONG h
; /* table level */
953 register cab_ULONG i
; /* counter, current code */
954 register cab_ULONG j
; /* counter */
955 register cab_LONG k
; /* number of bits in current code */
956 cab_LONG
*l
; /* stack of bits per table */
957 register cab_ULONG
*p
; /* pointer into ZIP(c)[],ZIP(b)[],ZIP(v)[] */
958 register struct Ziphuft
*q
; /* points to current table */
959 struct Ziphuft r
; /* table entry for structure assignment */
960 register cab_LONG w
; /* bits before this table == (l * h) */
961 cab_ULONG
*xp
; /* pointer into x */
962 cab_LONG y
; /* number of dummy codes added */
963 cab_ULONG z
; /* number of entries in current table */
967 /* Generate counts for each bit length */
968 el
= n
> 256 ? b
[256] : ZIPBMAX
; /* set length of EOB code, if any */
970 for(i
= 0; i
< ZIPBMAX
+1; ++i
)
975 ZIP(c
)[*p
]++; p
++; /* assume all entries <= ZIPBMAX */
977 if (ZIP(c
)[0] == n
) /* null input--all zero length codes */
984 /* Find minimum and maximum length, bound *m by those */
985 for (j
= 1; j
<= ZIPBMAX
; j
++)
988 k
= j
; /* minimum code length */
989 if ((cab_ULONG
)*m
< j
)
991 for (i
= ZIPBMAX
; i
; i
--)
994 g
= i
; /* maximum code length */
995 if ((cab_ULONG
)*m
> i
)
998 /* Adjust last length count to fill out codes, if needed */
999 for (y
= 1 << j
; j
< i
; j
++, y
<<= 1)
1000 if ((y
-= ZIP(c
)[j
]) < 0)
1001 return 2; /* bad input: more codes than bits */
1002 if ((y
-= ZIP(c
)[i
]) < 0)
1006 /* Generate starting offsets LONGo the value table for each length */
1008 p
= ZIP(c
) + 1; xp
= ZIP(x
) + 2;
1010 { /* note that i == g from above */
1011 *xp
++ = (j
+= *p
++);
1014 /* Make a table of values in order of bit lengths */
1017 if ((j
= *p
++) != 0)
1018 ZIP(v
)[ZIP(x
)[j
]++] = i
;
1022 /* Generate the Huffman codes and for each, make the table entries */
1023 ZIP(x
)[0] = i
= 0; /* first Huffman code is zero */
1024 p
= ZIP(v
); /* grab values in bit order */
1025 h
= -1; /* no tables yet--level -1 */
1026 w
= l
[-1] = 0; /* no bits decoded yet */
1027 ZIP(u
)[0] = NULL
; /* just to keep compilers happy */
1028 q
= NULL
; /* ditto */
1031 /* go through the bit lengths (k already is bits in shortest code) */
1037 /* here i is the Huffman code of length k bits for value *p */
1038 /* make tables up to required level */
1039 while (k
> w
+ l
[h
])
1041 w
+= l
[h
++]; /* add bits already decoded */
1043 /* compute minimum size table less than or equal to *m bits */
1044 if ((z
= g
- w
) > (cab_ULONG
)*m
) /* upper limit */
1046 if ((f
= 1 << (j
= k
- w
)) > a
+ 1) /* try a k-w bit table */
1047 { /* too few codes for k-w bit table */
1048 f
-= a
+ 1; /* deduct codes from patterns left */
1050 while (++j
< z
) /* try smaller tables up to z bits */
1052 if ((f
<<= 1) <= *++xp
)
1053 break; /* enough codes to use up j bits */
1054 f
-= *xp
; /* else deduct codes from patterns */
1057 if ((cab_ULONG
)w
+ j
> el
&& (cab_ULONG
)w
< el
)
1058 j
= el
- w
; /* make EOB code end at table */
1059 z
= 1 << j
; /* table entries for j-bit table */
1060 l
[h
] = j
; /* set table size in stack */
1062 /* allocate and link in new table */
1063 if (!(q
= CAB(fdi
)->alloc((z
+ 1)*sizeof(struct Ziphuft
))))
1066 fdi_Ziphuft_free(CAB(fdi
), ZIP(u
)[0]);
1067 return 3; /* not enough memory */
1069 *t
= q
+ 1; /* link to list for Ziphuft_free() */
1070 *(t
= &(q
->v
.t
)) = NULL
;
1071 ZIP(u
)[h
] = ++q
; /* table starts after link */
1073 /* connect to last table, if there is one */
1076 ZIP(x
)[h
] = i
; /* save pattern for backing up */
1077 r
.b
= (cab_UBYTE
)l
[h
-1]; /* bits to dump before this table */
1078 r
.e
= (cab_UBYTE
)(16 + j
); /* bits in this table */
1079 r
.v
.t
= q
; /* pointer to this table */
1080 j
= (i
& ((1 << w
) - 1)) >> (w
- l
[h
-1]);
1081 ZIP(u
)[h
-1][j
] = r
; /* connect to last table */
1085 /* set up table entry in r */
1086 r
.b
= (cab_UBYTE
)(k
- w
);
1087 if (p
>= ZIP(v
) + n
)
1088 r
.e
= 99; /* out of values--invalid code */
1091 r
.e
= (cab_UBYTE
)(*p
< 256 ? 16 : 15); /* 256 is end-of-block code */
1092 r
.v
.n
= *p
++; /* simple code is just the value */
1096 r
.e
= (cab_UBYTE
)e
[*p
- s
]; /* non-simple--look up in lists */
1097 r
.v
.n
= d
[*p
++ - s
];
1100 /* fill code-like entries with r */
1102 for (j
= i
>> w
; j
< z
; j
+= f
)
1105 /* backwards increment the k-bit code i */
1106 for (j
= 1 << (k
- 1); i
& j
; j
>>= 1)
1110 /* backup over finished tables */
1111 while ((i
& ((1 << w
) - 1)) != ZIP(x
)[h
])
1112 w
-= l
[--h
]; /* don't need to update q */
1116 /* return actual size of base table */
1119 /* Return true (1) if we were given an incomplete table */
1120 return y
!= 0 && g
!= 1;
1123 /*********************************************************
1124 * fdi_Zipinflate_codes (internal)
1126 static cab_LONG
fdi_Zipinflate_codes(const struct Ziphuft
*tl
, const struct Ziphuft
*td
,
1127 cab_LONG bl
, cab_LONG bd
, fdi_decomp_state
*decomp_state
)
1129 register cab_ULONG e
; /* table entry flag/number of extra bits */
1130 cab_ULONG n
, d
; /* length and index for copy */
1131 cab_ULONG w
; /* current window position */
1132 const struct Ziphuft
*t
; /* pointer to table entry */
1133 cab_ULONG ml
, md
; /* masks for bl and bd bits */
1134 register cab_ULONG b
; /* bit buffer */
1135 register cab_ULONG k
; /* number of bits in bit buffer */
1137 /* make local copies of globals */
1138 b
= ZIP(bb
); /* initialize bit buffer */
1140 w
= ZIP(window_posn
); /* initialize window position */
1142 /* inflate the coded data */
1143 ml
= Zipmask
[bl
]; /* precompute masks for speed */
1148 ZIPNEEDBITS((cab_ULONG
)bl
)
1149 if((e
= (t
= tl
+ (b
& ml
))->e
) > 16)
1157 } while ((e
= (t
= t
->v
.t
+ (b
& Zipmask
[e
]))->e
) > 16);
1159 if (e
== 16) /* then it's a literal */
1160 CAB(outbuf
)[w
++] = (cab_UBYTE
)t
->v
.n
;
1161 else /* it's an EOB or a length */
1163 /* exit if end of block */
1167 /* get length of block to copy */
1169 n
= t
->v
.n
+ (b
& Zipmask
[e
]);
1172 /* decode distance of block to copy */
1173 ZIPNEEDBITS((cab_ULONG
)bd
)
1174 if ((e
= (t
= td
+ (b
& md
))->e
) > 16)
1181 } while ((e
= (t
= t
->v
.t
+ (b
& Zipmask
[e
]))->e
) > 16);
1184 d
= w
- t
->v
.n
- (b
& Zipmask
[e
]);
1189 e
= ZIPWSIZE
- max(d
, w
);
1194 CAB(outbuf
)[w
++] = CAB(outbuf
)[d
++];
1200 /* restore the globals from the locals */
1201 ZIP(window_posn
) = w
; /* restore global window pointer */
1202 ZIP(bb
) = b
; /* restore global bit buffer */
1209 /***********************************************************
1210 * Zipinflate_stored (internal)
1212 static cab_LONG
fdi_Zipinflate_stored(fdi_decomp_state
*decomp_state
)
1213 /* "decompress" an inflated type 0 (stored) block. */
1215 cab_ULONG n
; /* number of bytes in block */
1216 cab_ULONG w
; /* current window position */
1217 register cab_ULONG b
; /* bit buffer */
1218 register cab_ULONG k
; /* number of bits in bit buffer */
1220 /* make local copies of globals */
1221 b
= ZIP(bb
); /* initialize bit buffer */
1223 w
= ZIP(window_posn
); /* initialize window position */
1225 /* go to byte boundary */
1229 /* get the length and its complement */
1234 if (n
!= ((~b
) & 0xffff))
1235 return 1; /* error in compressed data */
1238 /* read and output the compressed data */
1242 CAB(outbuf
)[w
++] = (cab_UBYTE
)b
;
1246 /* restore the globals from the locals */
1247 ZIP(window_posn
) = w
; /* restore global window pointer */
1248 ZIP(bb
) = b
; /* restore global bit buffer */
1253 /******************************************************
1254 * fdi_Zipinflate_fixed (internal)
1256 static cab_LONG
fdi_Zipinflate_fixed(fdi_decomp_state
*decomp_state
)
1258 struct Ziphuft
*fixed_tl
;
1259 struct Ziphuft
*fixed_td
;
1260 cab_LONG fixed_bl
, fixed_bd
;
1261 cab_LONG i
; /* temporary variable */
1267 for(i
= 0; i
< 144; i
++)
1273 for(; i
< 288; i
++) /* make a complete, but wrong code set */
1276 if((i
= fdi_Ziphuft_build(l
, 288, 257, Zipcplens
, Zipcplext
, &fixed_tl
, &fixed_bl
, decomp_state
)))
1279 /* distance table */
1280 for(i
= 0; i
< 30; i
++) /* make an incomplete code set */
1283 if((i
= fdi_Ziphuft_build(l
, 30, 0, Zipcpdist
, Zipcpdext
, &fixed_td
, &fixed_bd
, decomp_state
)) > 1)
1285 fdi_Ziphuft_free(CAB(fdi
), fixed_tl
);
1289 /* decompress until an end-of-block code */
1290 i
= fdi_Zipinflate_codes(fixed_tl
, fixed_td
, fixed_bl
, fixed_bd
, decomp_state
);
1292 fdi_Ziphuft_free(CAB(fdi
), fixed_td
);
1293 fdi_Ziphuft_free(CAB(fdi
), fixed_tl
);
1297 /**************************************************************
1298 * fdi_Zipinflate_dynamic (internal)
1300 static cab_LONG
fdi_Zipinflate_dynamic(fdi_decomp_state
*decomp_state
)
1301 /* decompress an inflated type 2 (dynamic Huffman codes) block. */
1303 cab_LONG i
; /* temporary variables */
1306 cab_ULONG l
; /* last length */
1307 cab_ULONG m
; /* mask for bit lengths table */
1308 cab_ULONG n
; /* number of lengths to get */
1309 struct Ziphuft
*tl
; /* literal/length code table */
1310 struct Ziphuft
*td
; /* distance code table */
1311 cab_LONG bl
; /* lookup bits for tl */
1312 cab_LONG bd
; /* lookup bits for td */
1313 cab_ULONG nb
; /* number of bit length codes */
1314 cab_ULONG nl
; /* number of literal/length codes */
1315 cab_ULONG nd
; /* number of distance codes */
1316 register cab_ULONG b
; /* bit buffer */
1317 register cab_ULONG k
; /* number of bits in bit buffer */
1319 /* make local bit buffer */
1324 /* read in table lengths */
1326 nl
= 257 + (b
& 0x1f); /* number of literal/length codes */
1329 nd
= 1 + (b
& 0x1f); /* number of distance codes */
1332 nb
= 4 + (b
& 0xf); /* number of bit length codes */
1334 if(nl
> 288 || nd
> 32)
1335 return 1; /* bad lengths */
1337 /* read in bit-length-code lengths */
1338 for(j
= 0; j
< nb
; j
++)
1341 ll
[Zipborder
[j
]] = b
& 7;
1345 ll
[Zipborder
[j
]] = 0;
1347 /* build decoding table for trees--single level, 7 bit lookup */
1349 if((i
= fdi_Ziphuft_build(ll
, 19, 19, NULL
, NULL
, &tl
, &bl
, decomp_state
)) != 0)
1352 fdi_Ziphuft_free(CAB(fdi
), tl
);
1353 return i
; /* incomplete code set */
1356 /* read in literal and distance code lengths */
1360 while((cab_ULONG
)i
< n
)
1362 ZIPNEEDBITS((cab_ULONG
)bl
)
1363 j
= (td
= tl
+ (b
& m
))->b
;
1366 if (j
< 16) /* length of code in bits (0..15) */
1367 ll
[i
++] = l
= j
; /* save last length in l */
1368 else if (j
== 16) /* repeat last length 3 to 6 times */
1373 if((cab_ULONG
)i
+ j
> n
)
1378 else if (j
== 17) /* 3 to 10 zero length codes */
1383 if ((cab_ULONG
)i
+ j
> n
)
1389 else /* j == 18: 11 to 138 zero length codes */
1392 j
= 11 + (b
& 0x7f);
1394 if ((cab_ULONG
)i
+ j
> n
)
1402 /* free decoding table for trees */
1403 fdi_Ziphuft_free(CAB(fdi
), tl
);
1405 /* restore the global bit buffer */
1409 /* build the decoding tables for literal/length and distance codes */
1411 if((i
= fdi_Ziphuft_build(ll
, nl
, 257, Zipcplens
, Zipcplext
, &tl
, &bl
, decomp_state
)) != 0)
1414 fdi_Ziphuft_free(CAB(fdi
), tl
);
1415 return i
; /* incomplete code set */
1418 fdi_Ziphuft_build(ll
+ nl
, nd
, 0, Zipcpdist
, Zipcpdext
, &td
, &bd
, decomp_state
);
1420 /* decompress until an end-of-block code */
1421 if(fdi_Zipinflate_codes(tl
, td
, bl
, bd
, decomp_state
))
1424 /* free the decoding tables, return */
1425 fdi_Ziphuft_free(CAB(fdi
), tl
);
1426 fdi_Ziphuft_free(CAB(fdi
), td
);
1430 /*****************************************************
1431 * fdi_Zipinflate_block (internal)
1433 static cab_LONG
fdi_Zipinflate_block(cab_LONG
*e
, fdi_decomp_state
*decomp_state
) /* e == last block flag */
1434 { /* decompress an inflated block */
1435 cab_ULONG t
; /* block type */
1436 register cab_ULONG b
; /* bit buffer */
1437 register cab_ULONG k
; /* number of bits in bit buffer */
1439 /* make local bit buffer */
1443 /* read in last block bit */
1445 *e
= (cab_LONG
)b
& 1;
1448 /* read in block type */
1453 /* restore the global bit buffer */
1457 /* inflate that block type */
1459 return fdi_Zipinflate_dynamic(decomp_state
);
1461 return fdi_Zipinflate_stored(decomp_state
);
1463 return fdi_Zipinflate_fixed(decomp_state
);
1464 /* bad block type */
1468 /****************************************************
1469 * ZIPfdi_decomp(internal)
1471 static int ZIPfdi_decomp(int inlen
, int outlen
, fdi_decomp_state
*decomp_state
)
1473 cab_LONG e
; /* last block flag */
1475 TRACE("(inlen == %d, outlen == %d)\n", inlen
, outlen
);
1477 ZIP(inpos
) = CAB(inbuf
);
1478 ZIP(bb
) = ZIP(bk
) = ZIP(window_posn
) = 0;
1479 if(outlen
> ZIPWSIZE
)
1480 return DECR_DATAFORMAT
;
1482 /* CK = Chris Kirmse, official Microsoft purloiner */
1483 if(ZIP(inpos
)[0] != 0x43 || ZIP(inpos
)[1] != 0x4B)
1484 return DECR_ILLEGALDATA
;
1488 if(fdi_Zipinflate_block(&e
, decomp_state
))
1489 return DECR_ILLEGALDATA
;
1492 /* return success */
1496 /*******************************************************************
1497 * QTMfdi_decomp(internal)
1499 static int QTMfdi_decomp(int inlen
, int outlen
, fdi_decomp_state
*decomp_state
)
1501 cab_UBYTE
*inpos
= CAB(inbuf
);
1502 cab_UBYTE
*window
= QTM(window
);
1503 cab_UBYTE
*runsrc
, *rundest
;
1504 cab_ULONG window_posn
= QTM(window_posn
);
1505 cab_ULONG window_size
= QTM(window_size
);
1507 /* used by bitstream macros */
1508 register int bitsleft
, bitrun
, bitsneed
;
1509 register cab_ULONG bitbuf
;
1511 /* used by GET_SYMBOL */
1516 int extra
, togo
= outlen
, match_length
= 0, copy_length
;
1517 cab_UBYTE selector
, sym
;
1518 cab_ULONG match_offset
= 0;
1520 cab_UWORD H
= 0xFFFF, L
= 0, C
;
1522 TRACE("(inlen == %d, outlen == %d)\n", inlen
, outlen
);
1524 /* read initial value of C */
1528 /* apply 2^x-1 mask */
1529 window_posn
&= window_size
- 1;
1530 /* runs can't straddle the window wraparound */
1531 if ((window_posn
+ togo
) > window_size
) {
1532 TRACE("straddled run\n");
1533 return DECR_DATAFORMAT
;
1537 GET_SYMBOL(model7
, selector
);
1540 GET_SYMBOL(model00
, sym
); window
[window_posn
++] = sym
; togo
--;
1543 GET_SYMBOL(model40
, sym
); window
[window_posn
++] = sym
; togo
--;
1546 GET_SYMBOL(model80
, sym
); window
[window_posn
++] = sym
; togo
--;
1549 GET_SYMBOL(modelC0
, sym
); window
[window_posn
++] = sym
; togo
--;
1553 /* selector 4 = fixed length of 3 */
1554 GET_SYMBOL(model4
, sym
);
1555 Q_READ_BITS(extra
, CAB(q_extra_bits
)[sym
]);
1556 match_offset
= CAB(q_position_base
)[sym
] + extra
+ 1;
1561 /* selector 5 = fixed length of 4 */
1562 GET_SYMBOL(model5
, sym
);
1563 Q_READ_BITS(extra
, CAB(q_extra_bits
)[sym
]);
1564 match_offset
= CAB(q_position_base
)[sym
] + extra
+ 1;
1569 /* selector 6 = variable length */
1570 GET_SYMBOL(model6len
, sym
);
1571 Q_READ_BITS(extra
, CAB(q_length_extra
)[sym
]);
1572 match_length
= CAB(q_length_base
)[sym
] + extra
+ 5;
1573 GET_SYMBOL(model6pos
, sym
);
1574 Q_READ_BITS(extra
, CAB(q_extra_bits
)[sym
]);
1575 match_offset
= CAB(q_position_base
)[sym
] + extra
+ 1;
1579 TRACE("Selector is bogus\n");
1580 return DECR_ILLEGALDATA
;
1583 /* if this is a match */
1584 if (selector
>= 4) {
1585 rundest
= window
+ window_posn
;
1586 togo
-= match_length
;
1588 /* copy any wrapped around source data */
1589 if (window_posn
>= match_offset
) {
1591 runsrc
= rundest
- match_offset
;
1593 runsrc
= rundest
+ (window_size
- match_offset
);
1594 copy_length
= match_offset
- window_posn
;
1595 if (copy_length
< match_length
) {
1596 match_length
-= copy_length
;
1597 window_posn
+= copy_length
;
1598 while (copy_length
-- > 0) *rundest
++ = *runsrc
++;
1602 window_posn
+= match_length
;
1604 /* copy match data - no worries about destination wraps */
1605 while (match_length
-- > 0) *rundest
++ = *runsrc
++;
1607 } /* while (togo > 0) */
1610 TRACE("Frame overflow, this_run = %d\n", togo
);
1611 return DECR_ILLEGALDATA
;
1614 memcpy(CAB(outbuf
), window
+ ((!window_posn
) ? window_size
: window_posn
) -
1617 QTM(window_posn
) = window_posn
;
1621 /************************************************************
1622 * fdi_lzx_read_lens (internal)
1624 static int fdi_lzx_read_lens(cab_UBYTE
*lens
, cab_ULONG first
, cab_ULONG last
, struct lzx_bits
*lb
,
1625 fdi_decomp_state
*decomp_state
) {
1629 register cab_ULONG bitbuf
= lb
->bb
;
1630 register int bitsleft
= lb
->bl
;
1631 cab_UBYTE
*inpos
= lb
->ip
;
1634 for (x
= 0; x
< 20; x
++) {
1636 LENTABLE(PRETREE
)[x
] = y
;
1638 BUILD_TABLE(PRETREE
);
1640 for (x
= first
; x
< last
; ) {
1641 READ_HUFFSYM(PRETREE
, z
);
1643 READ_BITS(y
, 4); y
+= 4;
1644 while (y
--) lens
[x
++] = 0;
1647 READ_BITS(y
, 5); y
+= 20;
1648 while (y
--) lens
[x
++] = 0;
1651 READ_BITS(y
, 1); y
+= 4;
1652 READ_HUFFSYM(PRETREE
, z
);
1653 z
= lens
[x
] - z
; if (z
< 0) z
+= 17;
1654 while (y
--) lens
[x
++] = z
;
1657 z
= lens
[x
] - z
; if (z
< 0) z
+= 17;
1668 /*******************************************************
1669 * LZXfdi_decomp(internal)
1671 static int LZXfdi_decomp(int inlen
, int outlen
, fdi_decomp_state
*decomp_state
) {
1672 cab_UBYTE
*inpos
= CAB(inbuf
);
1673 const cab_UBYTE
*endinp
= inpos
+ inlen
;
1674 cab_UBYTE
*window
= LZX(window
);
1675 cab_UBYTE
*runsrc
, *rundest
;
1676 cab_UWORD
*hufftbl
; /* used in READ_HUFFSYM macro as chosen decoding table */
1678 cab_ULONG window_posn
= LZX(window_posn
);
1679 cab_ULONG window_size
= LZX(window_size
);
1680 cab_ULONG R0
= LZX(R0
);
1681 cab_ULONG R1
= LZX(R1
);
1682 cab_ULONG R2
= LZX(R2
);
1684 register cab_ULONG bitbuf
;
1685 register int bitsleft
;
1686 cab_ULONG match_offset
, i
,j
,k
; /* ijk used in READ_HUFFSYM macro */
1687 struct lzx_bits lb
; /* used in READ_LENGTHS macro */
1689 int togo
= outlen
, this_run
, main_element
, aligned_bits
;
1690 int match_length
, copy_length
, length_footer
, extra
, verbatim_bits
;
1692 TRACE("(inlen == %d, outlen == %d)\n", inlen
, outlen
);
1696 /* read header if necessary */
1697 if (!LZX(header_read
)) {
1699 READ_BITS(k
, 1); if (k
) { READ_BITS(i
,16); READ_BITS(j
,16); }
1700 LZX(intel_filesize
) = (i
<< 16) | j
; /* or 0 if not encoded */
1701 LZX(header_read
) = 1;
1704 /* main decoding loop */
1706 /* last block finished, new block expected */
1707 if (LZX(block_remaining
) == 0) {
1708 if (LZX(block_type
) == LZX_BLOCKTYPE_UNCOMPRESSED
) {
1709 if (LZX(block_length
) & 1) inpos
++; /* realign bitstream to word */
1713 READ_BITS(LZX(block_type
), 3);
1716 LZX(block_remaining
) = LZX(block_length
) = (i
<< 8) | j
;
1718 switch (LZX(block_type
)) {
1719 case LZX_BLOCKTYPE_ALIGNED
:
1720 for (i
= 0; i
< 8; i
++) { READ_BITS(j
, 3); LENTABLE(ALIGNED
)[i
] = j
; }
1721 BUILD_TABLE(ALIGNED
);
1722 /* rest of aligned header is same as verbatim */
1724 case LZX_BLOCKTYPE_VERBATIM
:
1725 READ_LENGTHS(MAINTREE
, 0, 256, fdi_lzx_read_lens
);
1726 READ_LENGTHS(MAINTREE
, 256, LZX(main_elements
), fdi_lzx_read_lens
);
1727 BUILD_TABLE(MAINTREE
);
1728 if (LENTABLE(MAINTREE
)[0xE8] != 0) LZX(intel_started
) = 1;
1730 READ_LENGTHS(LENGTH
, 0, LZX_NUM_SECONDARY_LENGTHS
, fdi_lzx_read_lens
);
1731 BUILD_TABLE(LENGTH
);
1734 case LZX_BLOCKTYPE_UNCOMPRESSED
:
1735 LZX(intel_started
) = 1; /* because we can't assume otherwise */
1736 ENSURE_BITS(16); /* get up to 16 pad bits into the buffer */
1737 if (bitsleft
> 16) inpos
-= 2; /* and align the bitstream! */
1738 R0
= inpos
[0]|(inpos
[1]<<8)|(inpos
[2]<<16)|(inpos
[3]<<24);inpos
+=4;
1739 R1
= inpos
[0]|(inpos
[1]<<8)|(inpos
[2]<<16)|(inpos
[3]<<24);inpos
+=4;
1740 R2
= inpos
[0]|(inpos
[1]<<8)|(inpos
[2]<<16)|(inpos
[3]<<24);inpos
+=4;
1744 return DECR_ILLEGALDATA
;
1748 /* buffer exhaustion check */
1749 if (inpos
> endinp
) {
1750 /* it's possible to have a file where the next run is less than
1751 * 16 bits in size. In this case, the READ_HUFFSYM() macro used
1752 * in building the tables will exhaust the buffer, so we should
1753 * allow for this, but not allow those accidentally read bits to
1754 * be used (so we check that there are at least 16 bits
1755 * remaining - in this boundary case they aren't really part of
1756 * the compressed data)
1758 if (inpos
> (endinp
+2) || bitsleft
< 16) return DECR_ILLEGALDATA
;
1761 while ((this_run
= LZX(block_remaining
)) > 0 && togo
> 0) {
1762 if (this_run
> togo
) this_run
= togo
;
1764 LZX(block_remaining
) -= this_run
;
1766 /* apply 2^x-1 mask */
1767 window_posn
&= window_size
- 1;
1768 /* runs can't straddle the window wraparound */
1769 if ((window_posn
+ this_run
) > window_size
)
1770 return DECR_DATAFORMAT
;
1772 switch (LZX(block_type
)) {
1774 case LZX_BLOCKTYPE_VERBATIM
:
1775 while (this_run
> 0) {
1776 READ_HUFFSYM(MAINTREE
, main_element
);
1778 if (main_element
< LZX_NUM_CHARS
) {
1779 /* literal: 0 to LZX_NUM_CHARS-1 */
1780 window
[window_posn
++] = main_element
;
1784 /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
1785 main_element
-= LZX_NUM_CHARS
;
1787 match_length
= main_element
& LZX_NUM_PRIMARY_LENGTHS
;
1788 if (match_length
== LZX_NUM_PRIMARY_LENGTHS
) {
1789 READ_HUFFSYM(LENGTH
, length_footer
);
1790 match_length
+= length_footer
;
1792 match_length
+= LZX_MIN_MATCH
;
1794 match_offset
= main_element
>> 3;
1796 if (match_offset
> 2) {
1797 /* not repeated offset */
1798 if (match_offset
!= 3) {
1799 extra
= CAB(extra_bits
)[match_offset
];
1800 READ_BITS(verbatim_bits
, extra
);
1801 match_offset
= CAB(lzx_position_base
)[match_offset
]
1802 - 2 + verbatim_bits
;
1808 /* update repeated offset LRU queue */
1809 R2
= R1
; R1
= R0
; R0
= match_offset
;
1811 else if (match_offset
== 0) {
1814 else if (match_offset
== 1) {
1816 R1
= R0
; R0
= match_offset
;
1818 else /* match_offset == 2 */ {
1820 R2
= R0
; R0
= match_offset
;
1823 rundest
= window
+ window_posn
;
1824 this_run
-= match_length
;
1826 /* copy any wrapped around source data */
1827 if (window_posn
>= match_offset
) {
1829 runsrc
= rundest
- match_offset
;
1831 runsrc
= rundest
+ (window_size
- match_offset
);
1832 copy_length
= match_offset
- window_posn
;
1833 if (copy_length
< match_length
) {
1834 match_length
-= copy_length
;
1835 window_posn
+= copy_length
;
1836 while (copy_length
-- > 0) *rundest
++ = *runsrc
++;
1840 window_posn
+= match_length
;
1842 /* copy match data - no worries about destination wraps */
1843 while (match_length
-- > 0) *rundest
++ = *runsrc
++;
1848 case LZX_BLOCKTYPE_ALIGNED
:
1849 while (this_run
> 0) {
1850 READ_HUFFSYM(MAINTREE
, main_element
);
1852 if (main_element
< LZX_NUM_CHARS
) {
1853 /* literal: 0 to LZX_NUM_CHARS-1 */
1854 window
[window_posn
++] = main_element
;
1858 /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
1859 main_element
-= LZX_NUM_CHARS
;
1861 match_length
= main_element
& LZX_NUM_PRIMARY_LENGTHS
;
1862 if (match_length
== LZX_NUM_PRIMARY_LENGTHS
) {
1863 READ_HUFFSYM(LENGTH
, length_footer
);
1864 match_length
+= length_footer
;
1866 match_length
+= LZX_MIN_MATCH
;
1868 match_offset
= main_element
>> 3;
1870 if (match_offset
> 2) {
1871 /* not repeated offset */
1872 extra
= CAB(extra_bits
)[match_offset
];
1873 match_offset
= CAB(lzx_position_base
)[match_offset
] - 2;
1875 /* verbatim and aligned bits */
1877 READ_BITS(verbatim_bits
, extra
);
1878 match_offset
+= (verbatim_bits
<< 3);
1879 READ_HUFFSYM(ALIGNED
, aligned_bits
);
1880 match_offset
+= aligned_bits
;
1882 else if (extra
== 3) {
1883 /* aligned bits only */
1884 READ_HUFFSYM(ALIGNED
, aligned_bits
);
1885 match_offset
+= aligned_bits
;
1887 else if (extra
> 0) { /* extra==1, extra==2 */
1888 /* verbatim bits only */
1889 READ_BITS(verbatim_bits
, extra
);
1890 match_offset
+= verbatim_bits
;
1892 else /* extra == 0 */ {
1897 /* update repeated offset LRU queue */
1898 R2
= R1
; R1
= R0
; R0
= match_offset
;
1900 else if (match_offset
== 0) {
1903 else if (match_offset
== 1) {
1905 R1
= R0
; R0
= match_offset
;
1907 else /* match_offset == 2 */ {
1909 R2
= R0
; R0
= match_offset
;
1912 rundest
= window
+ window_posn
;
1913 this_run
-= match_length
;
1915 /* copy any wrapped around source data */
1916 if (window_posn
>= match_offset
) {
1918 runsrc
= rundest
- match_offset
;
1920 runsrc
= rundest
+ (window_size
- match_offset
);
1921 copy_length
= match_offset
- window_posn
;
1922 if (copy_length
< match_length
) {
1923 match_length
-= copy_length
;
1924 window_posn
+= copy_length
;
1925 while (copy_length
-- > 0) *rundest
++ = *runsrc
++;
1929 window_posn
+= match_length
;
1931 /* copy match data - no worries about destination wraps */
1932 while (match_length
-- > 0) *rundest
++ = *runsrc
++;
1937 case LZX_BLOCKTYPE_UNCOMPRESSED
:
1938 if ((inpos
+ this_run
) > endinp
) return DECR_ILLEGALDATA
;
1939 memcpy(window
+ window_posn
, inpos
, (size_t) this_run
);
1940 inpos
+= this_run
; window_posn
+= this_run
;
1944 return DECR_ILLEGALDATA
; /* might as well */
1950 if (togo
!= 0) return DECR_ILLEGALDATA
;
1951 memcpy(CAB(outbuf
), window
+ ((!window_posn
) ? window_size
: window_posn
) -
1952 outlen
, (size_t) outlen
);
1954 LZX(window_posn
) = window_posn
;
1959 /* intel E8 decoding */
1960 if ((LZX(frames_read
)++ < 32768) && LZX(intel_filesize
) != 0) {
1961 if (outlen
<= 6 || !LZX(intel_started
)) {
1962 LZX(intel_curpos
) += outlen
;
1965 cab_UBYTE
*data
= CAB(outbuf
);
1966 cab_UBYTE
*dataend
= data
+ outlen
- 10;
1967 cab_LONG curpos
= LZX(intel_curpos
);
1968 cab_LONG filesize
= LZX(intel_filesize
);
1969 cab_LONG abs_off
, rel_off
;
1971 LZX(intel_curpos
) = curpos
+ outlen
;
1973 while (data
< dataend
) {
1974 if (*data
++ != 0xE8) { curpos
++; continue; }
1975 abs_off
= data
[0] | (data
[1]<<8) | (data
[2]<<16) | (data
[3]<<24);
1976 if ((abs_off
>= -curpos
) && (abs_off
< filesize
)) {
1977 rel_off
= (abs_off
>= 0) ? abs_off
- curpos
: abs_off
+ filesize
;
1978 data
[0] = (cab_UBYTE
) rel_off
;
1979 data
[1] = (cab_UBYTE
) (rel_off
>> 8);
1980 data
[2] = (cab_UBYTE
) (rel_off
>> 16);
1981 data
[3] = (cab_UBYTE
) (rel_off
>> 24);
1991 /**********************************************************
1992 * fdi_decomp (internal)
1994 * Decompress the requested number of bytes. If savemode is zero,
1995 * do not save the output anywhere, just plow through blocks until we
1996 * reach the specified (uncompressed) distance from the starting point,
1997 * and remember the position of the cabfile pointer (and which cabfile)
1998 * after we are done; otherwise, save the data out to CAB(filehf),
1999 * decompressing the requested number of bytes and writing them out. This
2000 * is also where we jump to additional cabinets in the case of split
2001 * cab's, and provide (some of) the NEXT_CABINET notification semantics.
2003 static int fdi_decomp(const struct fdi_file
*fi
, int savemode
, fdi_decomp_state
*decomp_state
,
2004 char *pszCabPath
, PFNFDINOTIFY pfnfdin
, void *pvUser
)
2006 cab_ULONG bytes
= savemode
? fi
->length
: fi
->offset
- CAB(offset
);
2007 cab_UBYTE buf
[cfdata_SIZEOF
], *data
;
2008 cab_UWORD inlen
, len
, outlen
, cando
;
2011 fdi_decomp_state
*cab
= (savemode
&& CAB(decomp_cab
)) ? CAB(decomp_cab
) : decomp_state
;
2013 TRACE("(fi == ^%p, savemode == %d, bytes == %d)\n", fi
, savemode
, bytes
);
2016 /* cando = the max number of bytes we can do */
2017 cando
= CAB(outlen
);
2018 if (cando
> bytes
) cando
= bytes
;
2021 if (cando
&& savemode
)
2022 CAB(fdi
)->write(CAB(filehf
), CAB(outpos
), cando
);
2024 CAB(outpos
) += cando
;
2025 CAB(outlen
) -= cando
;
2026 bytes
-= cando
; if (!bytes
) break;
2028 /* we only get here if we emptied the output buffer */
2030 /* read data header + data */
2032 while (outlen
== 0) {
2033 /* read the block header, skip the reserved part */
2034 if (CAB(fdi
)->read(cab
->cabhf
, buf
, cfdata_SIZEOF
) != cfdata_SIZEOF
)
2037 if (CAB(fdi
)->seek(cab
->cabhf
, cab
->mii
.block_resv
, SEEK_CUR
) == -1)
2040 /* we shouldn't get blocks over CAB_INPUTMAX in size */
2041 data
= CAB(inbuf
) + inlen
;
2042 len
= EndGetI16(buf
+cfdata_CompressedSize
);
2044 if (inlen
> CAB_INPUTMAX
) return DECR_INPUT
;
2045 if (CAB(fdi
)->read(cab
->cabhf
, data
, len
) != len
)
2048 /* clear two bytes after read-in data */
2049 data
[len
+1] = data
[len
+2] = 0;
2051 /* perform checksum test on the block (if one is stored) */
2052 cksum
= EndGetI32(buf
+cfdata_CheckSum
);
2053 if (cksum
&& cksum
!= checksum(buf
+4, 4, checksum(data
, len
, 0)))
2054 return DECR_CHECKSUM
; /* checksum is wrong */
2056 outlen
= EndGetI16(buf
+cfdata_UncompressedSize
);
2058 /* outlen=0 means this block was the last contiguous part
2059 of a split block, continued in the next cabinet */
2061 int pathlen
, filenamelen
, idx
, i
;
2063 char fullpath
[MAX_PATH
], userpath
[256];
2064 FDINOTIFICATION fdin
;
2065 FDICABINETINFO fdici
;
2066 char emptystring
= '\0';
2068 int success
= FALSE
;
2069 struct fdi_folder
*fol
= NULL
, *linkfol
= NULL
;
2070 struct fdi_file
*file
= NULL
, *linkfile
= NULL
;
2074 /* set up the next decomp_state... */
2076 if (!cab
->mii
.hasnext
) return DECR_INPUT
;
2078 if (!((cab
->next
= CAB(fdi
)->alloc(sizeof(fdi_decomp_state
)))))
2079 return DECR_NOMEMORY
;
2081 ZeroMemory(cab
->next
, sizeof(fdi_decomp_state
));
2083 /* copy pszCabPath to userpath */
2084 ZeroMemory(userpath
, 256);
2085 pathlen
= (pszCabPath
) ? strlen(pszCabPath
) : 0;
2087 if (pathlen
< 256) {
2088 for (i
= 0; i
<= pathlen
; i
++)
2089 userpath
[i
] = pszCabPath
[i
];
2090 } /* else we are in a weird place... let's leave it blank and see if the user fixes it */
2093 /* initial fdintNEXT_CABINET notification */
2094 ZeroMemory(&fdin
, sizeof(FDINOTIFICATION
));
2095 fdin
.psz1
= (cab
->mii
.nextname
) ? cab
->mii
.nextname
: &emptystring
;
2096 fdin
.psz2
= (cab
->mii
.nextinfo
) ? cab
->mii
.nextinfo
: &emptystring
;
2097 fdin
.psz3
= &userpath
[0];
2098 fdin
.fdie
= FDIERROR_NONE
;
2101 if (((*pfnfdin
)(fdintNEXT_CABINET
, &fdin
))) return DECR_USERABORT
;
2105 pathlen
= strlen(userpath
);
2106 filenamelen
= (cab
->mii
.nextname
) ? strlen(cab
->mii
.nextname
) : 0;
2108 /* slight overestimation here to save CPU cycles in the developer's brain */
2109 if ((pathlen
+ filenamelen
+ 3) > MAX_PATH
) {
2110 ERR("MAX_PATH exceeded.\n");
2111 return DECR_ILLEGALDATA
;
2114 /* paste the path and filename together */
2117 for (i
= 0; i
< pathlen
; i
++) fullpath
[idx
++] = userpath
[i
];
2118 if (fullpath
[idx
- 1] != '\\') fullpath
[idx
++] = '\\';
2120 if (filenamelen
) for (i
= 0; i
< filenamelen
; i
++) fullpath
[idx
++] = cab
->mii
.nextname
[i
];
2121 fullpath
[idx
] = '\0';
2123 TRACE("full cab path/file name: %s\n", debugstr_a(fullpath
));
2125 /* try to get a handle to the cabfile */
2126 cabhf
= CAB(fdi
)->open(fullpath
, _O_RDONLY
|_O_BINARY
, _S_IREAD
| _S_IWRITE
);
2128 /* no file. allow the user to try again */
2129 fdin
.fdie
= FDIERROR_CABINET_NOT_FOUND
;
2130 if (((*pfnfdin
)(fdintNEXT_CABINET
, &fdin
))) return DECR_USERABORT
;
2135 ERR("PFDI_OPEN returned zero for %s.\n", fullpath
);
2136 fdin
.fdie
= FDIERROR_CABINET_NOT_FOUND
;
2137 if (((*pfnfdin
)(fdintNEXT_CABINET
, &fdin
))) return DECR_USERABORT
;
2141 /* check if it's really a cabfile. Note that this doesn't implement the bug */
2142 if (!FDI_read_entries(CAB(fdi
), cabhf
, &fdici
, &(cab
->next
->mii
))) {
2143 WARN("FDIIsCabinet failed.\n");
2144 CAB(fdi
)->close(cabhf
);
2145 fdin
.fdie
= FDIERROR_NOT_A_CABINET
;
2146 if (((*pfnfdin
)(fdintNEXT_CABINET
, &fdin
))) return DECR_USERABORT
;
2150 if ((fdici
.setID
!= cab
->setID
) || (fdici
.iCabinet
!= (cab
->iCabinet
+ 1))) {
2151 WARN("Wrong Cabinet.\n");
2152 CAB(fdi
)->close(cabhf
);
2153 fdin
.fdie
= FDIERROR_WRONG_CABINET
;
2154 if (((*pfnfdin
)(fdintNEXT_CABINET
, &fdin
))) return DECR_USERABORT
;
2162 /* cabinet notification */
2163 ZeroMemory(&fdin
, sizeof(FDINOTIFICATION
));
2164 fdin
.setID
= fdici
.setID
;
2165 fdin
.iCabinet
= fdici
.iCabinet
;
2167 fdin
.psz1
= (cab
->next
->mii
.nextname
) ? cab
->next
->mii
.nextname
: &emptystring
;
2168 fdin
.psz2
= (cab
->next
->mii
.nextinfo
) ? cab
->next
->mii
.nextinfo
: &emptystring
;
2169 fdin
.psz3
= pszCabPath
;
2171 if (((*pfnfdin
)(fdintCABINET_INFO
, &fdin
))) return DECR_USERABORT
;
2173 cab
->next
->setID
= fdici
.setID
;
2174 cab
->next
->iCabinet
= fdici
.iCabinet
;
2175 cab
->next
->fdi
= CAB(fdi
);
2176 cab
->next
->filehf
= CAB(filehf
);
2177 cab
->next
->cabhf
= cabhf
;
2178 cab
->next
->decompress
= CAB(decompress
); /* crude, but unused anyhow */
2180 cab
= cab
->next
; /* advance to the next cabinet */
2183 for (i
= 0; i
< fdici
.cFolders
; i
++) {
2184 if (CAB(fdi
)->read(cab
->cabhf
, buf2
, cffold_SIZEOF
) != cffold_SIZEOF
)
2187 if (cab
->mii
.folder_resv
> 0)
2188 CAB(fdi
)->seek(cab
->cabhf
, cab
->mii
.folder_resv
, SEEK_CUR
);
2190 fol
= CAB(fdi
)->alloc(sizeof(struct fdi_folder
));
2192 ERR("out of memory!\n");
2193 return DECR_NOMEMORY
;
2195 ZeroMemory(fol
, sizeof(struct fdi_folder
));
2196 if (!(cab
->firstfol
)) cab
->firstfol
= fol
;
2198 fol
->offset
= (cab_off_t
) EndGetI32(buf2
+cffold_DataOffset
);
2199 fol
->num_blocks
= EndGetI16(buf2
+cffold_NumBlocks
);
2200 fol
->comp_type
= EndGetI16(buf2
+cffold_CompType
);
2203 linkfol
->next
= fol
;
2208 for (i
= 0; i
< fdici
.cFiles
; i
++) {
2209 if (CAB(fdi
)->read(cab
->cabhf
, buf2
, cffile_SIZEOF
) != cffile_SIZEOF
)
2212 file
= CAB(fdi
)->alloc(sizeof(struct fdi_file
));
2214 ERR("out of memory!\n");
2215 return DECR_NOMEMORY
;
2217 ZeroMemory(file
, sizeof(struct fdi_file
));
2218 if (!(cab
->firstfile
)) cab
->firstfile
= file
;
2220 file
->length
= EndGetI32(buf2
+cffile_UncompressedSize
);
2221 file
->offset
= EndGetI32(buf2
+cffile_FolderOffset
);
2222 file
->index
= EndGetI16(buf2
+cffile_FolderIndex
);
2223 file
->time
= EndGetI16(buf2
+cffile_Time
);
2224 file
->date
= EndGetI16(buf2
+cffile_Date
);
2225 file
->attribs
= EndGetI16(buf2
+cffile_Attribs
);
2226 file
->filename
= FDI_read_string(CAB(fdi
), cab
->cabhf
, fdici
.cbCabinet
);
2228 if (!file
->filename
) return DECR_INPUT
;
2231 linkfile
->next
= file
;
2236 cab
= cab
->next
; /* advance to the next cabinet */
2238 /* iterate files -- if we encounter the continued file, process it --
2239 otherwise, jump to the label above and keep looking */
2241 for (file
= cab
->firstfile
; (file
); file
= file
->next
) {
2242 if ((file
->index
& cffileCONTINUED_FROM_PREV
) == cffileCONTINUED_FROM_PREV
) {
2243 /* check to ensure a real match */
2244 if (lstrcmpiA(fi
->filename
, file
->filename
) == 0) {
2246 if (CAB(fdi
)->seek(cab
->cabhf
, cab
->firstfol
->offset
, SEEK_SET
) == -1)
2252 if (!success
) goto tryanothercab
; /* FIXME: shouldn't this trigger
2253 "Wrong Cabinet" notification? */
2257 /* decompress block */
2258 if ((err
= CAB(decompress
)(inlen
, outlen
, decomp_state
)))
2260 CAB(outlen
) = outlen
;
2261 CAB(outpos
) = CAB(outbuf
);
2264 CAB(decomp_cab
) = cab
;
2268 static void free_decompression_temps(FDI_Int
*fdi
, const struct fdi_folder
*fol
,
2269 fdi_decomp_state
*decomp_state
)
2271 switch (fol
->comp_type
& cffoldCOMPTYPE_MASK
) {
2272 case cffoldCOMPTYPE_LZX
:
2274 fdi
->free(LZX(window
));
2278 case cffoldCOMPTYPE_QUANTUM
:
2280 fdi
->free(QTM(window
));
2287 static void free_decompression_mem(FDI_Int
*fdi
,
2288 fdi_decomp_state
*decomp_state
, struct fdi_file
*file
)
2290 struct fdi_folder
*fol
;
2291 while (decomp_state
) {
2292 fdi_decomp_state
*prev_fds
;
2294 fdi
->close(CAB(cabhf
));
2296 /* free the storage remembered by mii */
2297 if (CAB(mii
).nextname
) fdi
->free(CAB(mii
).nextname
);
2298 if (CAB(mii
).nextinfo
) fdi
->free(CAB(mii
).nextinfo
);
2299 if (CAB(mii
).prevname
) fdi
->free(CAB(mii
).prevname
);
2300 if (CAB(mii
).previnfo
) fdi
->free(CAB(mii
).previnfo
);
2302 while (CAB(firstfol
)) {
2303 fol
= CAB(firstfol
);
2304 CAB(firstfol
) = CAB(firstfol
)->next
;
2307 while (CAB(firstfile
)) {
2308 file
= CAB(firstfile
);
2309 if (file
->filename
) fdi
->free(file
->filename
);
2310 CAB(firstfile
) = CAB(firstfile
)->next
;
2313 prev_fds
= decomp_state
;
2314 decomp_state
= CAB(next
);
2315 fdi
->free(prev_fds
);
2319 /***********************************************************************
2320 * FDICopy (CABINET.22)
2322 * Iterates through the files in the Cabinet file indicated by name and
2323 * file-location. May chain forward to additional cabinets (typically
2324 * only one) if files which begin in this Cabinet are continued in another
2325 * cabinet. For each file which is partially contained in this cabinet,
2326 * and partially contained in a prior cabinet, provides fdintPARTIAL_FILE
2327 * notification to the pfnfdin callback. For each file which begins in
2328 * this cabinet, fdintCOPY_FILE notification is provided to the pfnfdin
2329 * callback, and the file is optionally decompressed and saved to disk.
2330 * Notification is not provided for files which are not at least partially
2331 * contained in the specified cabinet file.
2333 * See below for a thorough explanation of the various notification
2337 * hfdi [I] An HFDI from FDICreate
2338 * pszCabinet [I] C-style string containing the filename of the cabinet
2339 * pszCabPath [I] C-style string containing the file path of the cabinet
2340 * flags [I] "Decoder parameters". Ignored. Suggested value: 0.
2341 * pfnfdin [I] Pointer to a notification function. See CALLBACKS below.
2342 * pfnfdid [I] Pointer to a decryption function. Ignored. Suggested
2344 * pvUser [I] arbitrary void * value which is passed to callbacks.
2347 * TRUE if successful.
2348 * FALSE if unsuccessful (error information is provided in the ERF structure
2349 * associated with the provided decompression handle by FDICreate).
2353 * Two pointers to callback functions are provided as parameters to FDICopy:
2354 * pfnfdin(of type PFNFDINOTIFY), and pfnfdid (of type PFNFDIDECRYPT). These
2355 * types are as follows:
2357 * typedef INT_PTR (__cdecl *PFNFDINOTIFY) ( FDINOTIFICATIONTYPE fdint,
2358 * PFDINOTIFICATION pfdin );
2360 * typedef int (__cdecl *PFNFDIDECRYPT) ( PFDIDECRYPT pfdid );
2362 * You can create functions of this type using the FNFDINOTIFY() and
2363 * FNFDIDECRYPT() macros, respectively. For example:
2365 * FNFDINOTIFY(mycallback) {
2366 * / * use variables fdint and pfdin to process notification * /
2369 * The second callback, which could be used for decrypting encrypted data,
2370 * is not used at all.
2372 * Each notification informs the user of some event which has occurred during
2373 * decompression of the cabinet file; each notification is also an opportunity
2374 * for the callee to abort decompression. The information provided to the
2375 * callback and the meaning of the callback's return value vary drastically
2376 * across the various types of notification. The type of notification is the
2377 * fdint parameter; all other information is provided to the callback in
2378 * notification-specific parts of the FDINOTIFICATION structure pointed to by
2379 * pfdin. The only part of that structure which is assigned for every callback
2380 * is the pv element, which contains the arbitrary value which was passed to
2381 * FDICopy in the pvUser argument (psz1 is also used each time, but its meaning
2382 * is highly dependent on fdint).
2384 * If you encounter unknown notifications, you should return zero if you want
2385 * decompression to continue (or -1 to abort). All strings used in the
2386 * callbacks are regular C-style strings. Detailed descriptions of each
2387 * notification type follow:
2389 * fdintCABINET_INFO:
2391 * This is the first notification provided after calling FDICopy, and provides
2392 * the user with various information about the cabinet. Note that this is
2393 * called for each cabinet FDICopy opens, not just the first one. In the
2394 * structure pointed to by pfdin, psz1 contains a pointer to the name of the
2395 * next cabinet file in the set after the one just loaded (if any), psz2
2396 * contains a pointer to the name or "info" of the next disk, psz3
2397 * contains a pointer to the file-path of the current cabinet, setID
2398 * contains an arbitrary constant associated with this set of cabinet files,
2399 * and iCabinet contains the numerical index of the current cabinet within
2400 * that set. Return zero, or -1 to abort.
2402 * fdintPARTIAL_FILE:
2404 * This notification is provided when FDICopy encounters a part of a file
2405 * contained in this cabinet which is missing its beginning. Files can be
2406 * split across cabinets, so this is not necessarily an abnormality; it just
2407 * means that the file in question begins in another cabinet. No file
2408 * corresponding to this notification is extracted from the cabinet. In the
2409 * structure pointed to by pfdin, psz1 contains a pointer to the name of the
2410 * partial file, psz2 contains a pointer to the file name of the cabinet in
2411 * which this file begins, and psz3 contains a pointer to the disk name or
2412 * "info" of the cabinet where the file begins. Return zero, or -1 to abort.
2416 * This notification is provided when FDICopy encounters a file which starts
2417 * in the cabinet file, provided to FDICopy in pszCabinet. (FDICopy will not
2418 * look for files in cabinets after the first one). One notification will be
2419 * sent for each such file, before the file is decompressed. By returning
2420 * zero, the callback can instruct FDICopy to skip the file. In the structure
2421 * pointed to by pfdin, psz1 contains a pointer to the file's name, cb contains
2422 * the size of the file (uncompressed), attribs contains the file attributes,
2423 * and date and time contain the date and time of the file. attributes, date,
2424 * and time are of the 16-bit ms-dos variety. Return -1 to abort decompression
2425 * for the entire cabinet, 0 to skip just this file but continue scanning the
2426 * cabinet for more files, or an FDIClose()-compatible file-handle.
2428 * fdintCLOSE_FILE_INFO:
2430 * This notification is important, don't forget to implement it. This
2431 * notification indicates that a file has been successfully uncompressed and
2432 * written to disk. Upon receipt of this notification, the callee is expected
2433 * to close the file handle, to set the attributes and date/time of the
2434 * closed file, and possibly to execute the file. In the structure pointed to
2435 * by pfdin, psz1 contains a pointer to the name of the file, hf will be the
2436 * open file handle (close it), cb contains 1 or zero, indicating respectively
2437 * that the callee should or should not execute the file, and date, time
2438 * and attributes will be set as in fdintCOPY_FILE. Bizarrely, the Cabinet SDK
2439 * specifies that _A_EXEC will be xor'ed out of attributes! wine does not do
2440 * do so. Return TRUE, or FALSE to abort decompression.
2442 * fdintNEXT_CABINET:
2444 * This notification is called when FDICopy must load in another cabinet. This
2445 * can occur when a file's data is "split" across multiple cabinets. The
2446 * callee has the opportunity to request that FDICopy look in a different file
2447 * path for the specified cabinet file, by writing that data into a provided
2448 * buffer (see below for more information). This notification will be received
2449 * more than once per-cabinet in the instance that FDICopy failed to find a
2450 * valid cabinet at the location specified by the first per-cabinet
2451 * fdintNEXT_CABINET notification. In such instances, the fdie element of the
2452 * structure pointed to by pfdin indicates the error which prevented FDICopy
2453 * from proceeding successfully. Return zero to indicate success, or -1 to
2454 * indicate failure and abort FDICopy.
2456 * Upon receipt of this notification, the structure pointed to by pfdin will
2457 * contain the following values: psz1 pointing to the name of the cabinet
2458 * which FDICopy is attempting to open, psz2 pointing to the name ("info") of
2459 * the next disk, psz3 pointing to the presumed file-location of the cabinet,
2460 * and fdie containing either FDIERROR_NONE, or one of the following:
2462 * FDIERROR_CABINET_NOT_FOUND, FDIERROR_NOT_A_CABINET,
2463 * FDIERROR_UNKNOWN_CABINET_VERSION, FDIERROR_CORRUPT_CABINET,
2464 * FDIERROR_BAD_COMPR_TYPE, FDIERROR_RESERVE_MISMATCH, and
2465 * FDIERROR_WRONG_CABINET.
2467 * The callee may choose to change the path where FDICopy will look for the
2468 * cabinet after this notification. To do so, the caller may write the new
2469 * pathname to the buffer pointed to by psz3, which is 256 characters in
2470 * length, including the terminating null character, before returning zero.
2474 * Undocumented and unimplemented in wine, this seems to be sent each time
2475 * a cabinet is opened, along with the fdintCABINET_INFO notification. It
2476 * probably has an interface similar to that of fdintCABINET_INFO; maybe this
2477 * provides information about the current cabinet instead of the next one....
2478 * this is just a guess, it has not been looked at closely.
2483 BOOL __cdecl
FDICopy(
2488 PFNFDINOTIFY pfnfdin
,
2489 PFNFDIDECRYPT pfnfdid
,
2492 FDICABINETINFO fdici
;
2493 FDINOTIFICATION fdin
;
2494 INT_PTR cabhf
, filehf
= 0;
2497 char fullpath
[MAX_PATH
];
2498 size_t pathlen
, filenamelen
;
2499 char emptystring
= '\0';
2501 struct fdi_folder
*fol
= NULL
, *linkfol
= NULL
;
2502 struct fdi_file
*file
= NULL
, *linkfile
= NULL
;
2503 fdi_decomp_state
*decomp_state
;
2504 FDI_Int
*fdi
= get_fdi_ptr( hfdi
);
2506 TRACE("(hfdi == ^%p, pszCabinet == ^%p, pszCabPath == ^%p, flags == %0d, "
2507 "pfnfdin == ^%p, pfnfdid == ^%p, pvUser == ^%p)\n",
2508 hfdi
, pszCabinet
, pszCabPath
, flags
, pfnfdin
, pfnfdid
, pvUser
);
2510 if (!fdi
) return FALSE
;
2512 if (!(decomp_state
= fdi
->alloc(sizeof(fdi_decomp_state
))))
2514 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2517 ZeroMemory(decomp_state
, sizeof(fdi_decomp_state
));
2519 pathlen
= (pszCabPath
) ? strlen(pszCabPath
) : 0;
2520 filenamelen
= (pszCabinet
) ? strlen(pszCabinet
) : 0;
2522 /* slight overestimation here to save CPU cycles in the developer's brain */
2523 if ((pathlen
+ filenamelen
+ 3) > MAX_PATH
) {
2524 ERR("MAX_PATH exceeded.\n");
2525 fdi
->free(decomp_state
);
2526 set_error( fdi
, FDIERROR_CABINET_NOT_FOUND
, ERROR_FILE_NOT_FOUND
);
2530 /* paste the path and filename together */
2533 for (i
= 0; i
< pathlen
; i
++) fullpath
[idx
++] = pszCabPath
[i
];
2534 if (fullpath
[idx
- 1] != '\\') fullpath
[idx
++] = '\\';
2536 if (filenamelen
) for (i
= 0; i
< filenamelen
; i
++) fullpath
[idx
++] = pszCabinet
[i
];
2537 fullpath
[idx
] = '\0';
2539 TRACE("full cab path/file name: %s\n", debugstr_a(fullpath
));
2541 /* get a handle to the cabfile */
2542 cabhf
= fdi
->open(fullpath
, _O_RDONLY
|_O_BINARY
, _S_IREAD
| _S_IWRITE
);
2544 fdi
->free(decomp_state
);
2545 set_error( fdi
, FDIERROR_CABINET_NOT_FOUND
, 0 );
2546 SetLastError(ERROR_FILE_NOT_FOUND
);
2551 ERR("PFDI_OPEN returned zero for %s.\n", fullpath
);
2552 fdi
->free(decomp_state
);
2553 set_error( fdi
, FDIERROR_CABINET_NOT_FOUND
, ERROR_FILE_NOT_FOUND
);
2557 /* check if it's really a cabfile. Note that this doesn't implement the bug */
2558 if (!FDI_read_entries(fdi
, cabhf
, &fdici
, &(CAB(mii
)))) {
2559 ERR("FDIIsCabinet failed.\n");
2560 fdi
->free(decomp_state
);
2565 /* cabinet notification */
2566 ZeroMemory(&fdin
, sizeof(FDINOTIFICATION
));
2567 fdin
.setID
= fdici
.setID
;
2568 fdin
.iCabinet
= fdici
.iCabinet
;
2570 fdin
.psz1
= (CAB(mii
).nextname
) ? CAB(mii
).nextname
: &emptystring
;
2571 fdin
.psz2
= (CAB(mii
).nextinfo
) ? CAB(mii
).nextinfo
: &emptystring
;
2572 fdin
.psz3
= pszCabPath
;
2574 if (((*pfnfdin
)(fdintCABINET_INFO
, &fdin
))) {
2575 set_error( fdi
, FDIERROR_USER_ABORT
, 0 );
2579 CAB(setID
) = fdici
.setID
;
2580 CAB(iCabinet
) = fdici
.iCabinet
;
2584 for (i
= 0; i
< fdici
.cFolders
; i
++) {
2585 if (fdi
->read(cabhf
, buf
, cffold_SIZEOF
) != cffold_SIZEOF
) {
2586 set_error( fdi
, FDIERROR_CORRUPT_CABINET
, 0 );
2590 if (CAB(mii
).folder_resv
> 0)
2591 fdi
->seek(cabhf
, CAB(mii
).folder_resv
, SEEK_CUR
);
2593 fol
= fdi
->alloc(sizeof(struct fdi_folder
));
2595 ERR("out of memory!\n");
2596 set_error( fdi
, FDIERROR_ALLOC_FAIL
, ERROR_NOT_ENOUGH_MEMORY
);
2599 ZeroMemory(fol
, sizeof(struct fdi_folder
));
2600 if (!CAB(firstfol
)) CAB(firstfol
) = fol
;
2602 fol
->offset
= (cab_off_t
) EndGetI32(buf
+cffold_DataOffset
);
2603 fol
->num_blocks
= EndGetI16(buf
+cffold_NumBlocks
);
2604 fol
->comp_type
= EndGetI16(buf
+cffold_CompType
);
2607 linkfol
->next
= fol
;
2612 for (i
= 0; i
< fdici
.cFiles
; i
++) {
2613 if (fdi
->read(cabhf
, buf
, cffile_SIZEOF
) != cffile_SIZEOF
) {
2614 set_error( fdi
, FDIERROR_CORRUPT_CABINET
, 0 );
2618 file
= fdi
->alloc(sizeof(struct fdi_file
));
2620 ERR("out of memory!\n");
2621 set_error( fdi
, FDIERROR_ALLOC_FAIL
, ERROR_NOT_ENOUGH_MEMORY
);
2624 ZeroMemory(file
, sizeof(struct fdi_file
));
2625 if (!CAB(firstfile
)) CAB(firstfile
) = file
;
2627 file
->length
= EndGetI32(buf
+cffile_UncompressedSize
);
2628 file
->offset
= EndGetI32(buf
+cffile_FolderOffset
);
2629 file
->index
= EndGetI16(buf
+cffile_FolderIndex
);
2630 file
->time
= EndGetI16(buf
+cffile_Time
);
2631 file
->date
= EndGetI16(buf
+cffile_Date
);
2632 file
->attribs
= EndGetI16(buf
+cffile_Attribs
);
2633 file
->filename
= FDI_read_string(fdi
, cabhf
, fdici
.cbCabinet
);
2635 if (!file
->filename
) {
2636 set_error( fdi
, FDIERROR_CORRUPT_CABINET
, 0 );
2641 linkfile
->next
= file
;
2645 for (file
= CAB(firstfile
); (file
); file
= file
->next
) {
2648 * FIXME: This implementation keeps multiple cabinet files open at once
2649 * when encountering a split cabinet. It is a quirk of this implementation
2650 * that sometimes we decrypt the same block of data more than once, to find
2651 * the right starting point for a file, moving the file-pointer backwards.
2652 * If we kept a cache of certain file-pointer information, we could eliminate
2653 * that behavior... in fact I am not sure that the caching we already have
2654 * is not sufficient.
2656 * The current implementation seems to work fine in straightforward situations
2657 * where all the cabinet files needed for decryption are simultaneously
2658 * available. But presumably, the API is supposed to support cabinets which
2659 * are split across multiple CDROMS; we may need to change our implementation
2660 * to strictly serialize it's file usage so that it opens only one cabinet
2661 * at a time. Some experimentation with Windows is needed to figure out the
2662 * precise semantics required. The relevant code is here and in fdi_decomp().
2665 /* partial-file notification */
2666 if ((file
->index
& cffileCONTINUED_FROM_PREV
) == cffileCONTINUED_FROM_PREV
) {
2668 * FIXME: Need to create a Cabinet with a single file spanning multiple files
2669 * and perform some tests to figure out the right behavior. The SDK says
2670 * FDICopy will notify the user of the filename and "disk name" (info) of
2671 * the cabinet where the spanning file /started/.
2673 * That would certainly be convenient for the API-user, who could abort,
2674 * everything (or parallelize, if that's allowed (it is in wine)), and call
2675 * FDICopy again with the provided filename, so as to avoid partial file
2676 * notification and successfully unpack. This task could be quite unpleasant
2677 * from wine's perspective: the information specifying the "start cabinet" for
2678 * a file is associated nowhere with the file header and is not to be found in
2679 * the cabinet header. We have only the index of the cabinet wherein the folder
2680 * begins, which contains the file. To find that cabinet, we must consider the
2681 * index of the current cabinet, and chain backwards, cabinet-by-cabinet (for
2682 * each cabinet refers to its "next" and "previous" cabinet only, like a linked
2685 * Bear in mind that, in the spirit of CABINET.DLL, we must assume that any
2686 * cabinet other than the active one might be at another filepath than the
2687 * current one, or on another CDROM. This could get rather dicey, especially
2688 * if we imagine parallelized access to the FDICopy API.
2690 * The current implementation punts -- it just returns the previous cabinet and
2691 * it's info from the header of this cabinet. This provides the right answer in
2692 * 95% of the cases; its worth checking if Microsoft cuts the same corner before
2695 ZeroMemory(&fdin
, sizeof(FDINOTIFICATION
));
2697 fdin
.psz1
= (char *)file
->filename
;
2698 fdin
.psz2
= (CAB(mii
).prevname
) ? CAB(mii
).prevname
: &emptystring
;
2699 fdin
.psz3
= (CAB(mii
).previnfo
) ? CAB(mii
).previnfo
: &emptystring
;
2701 if (((*pfnfdin
)(fdintPARTIAL_FILE
, &fdin
))) {
2702 set_error( fdi
, FDIERROR_USER_ABORT
, 0 );
2705 /* I don't think we are supposed to decompress partial files. This prevents it. */
2706 file
->oppressed
= TRUE
;
2708 if (file
->oppressed
) {
2711 ZeroMemory(&fdin
, sizeof(FDINOTIFICATION
));
2713 fdin
.psz1
= (char *)file
->filename
;
2714 fdin
.cb
= file
->length
;
2715 fdin
.date
= file
->date
;
2716 fdin
.time
= file
->time
;
2717 fdin
.attribs
= file
->attribs
;
2718 if ((filehf
= ((*pfnfdin
)(fdintCOPY_FILE
, &fdin
))) == -1) {
2719 set_error( fdi
, FDIERROR_USER_ABORT
, 0 );
2725 /* find the folder for this file if necc. */
2729 fol
= CAB(firstfol
);
2730 if ((file
->index
& cffileCONTINUED_TO_NEXT
) == cffileCONTINUED_TO_NEXT
) {
2731 /* pick the last folder */
2732 while (fol
->next
) fol
= fol
->next
;
2734 for (i2
= 0; (i2
< file
->index
); i2
++)
2735 if (fol
->next
) /* bug resistance, should always be true */
2741 cab_UWORD comptype
= fol
->comp_type
;
2742 int ct1
= comptype
& cffoldCOMPTYPE_MASK
;
2743 int ct2
= CAB(current
) ? (CAB(current
)->comp_type
& cffoldCOMPTYPE_MASK
) : 0;
2746 TRACE("Extracting file %s as requested by callee.\n", debugstr_a(file
->filename
));
2748 /* set up decomp_state */
2750 CAB(filehf
) = filehf
;
2752 /* Was there a change of folder? Compression type? Did we somehow go backwards? */
2753 if ((ct1
!= ct2
) || (CAB(current
) != fol
) || (file
->offset
< CAB(offset
))) {
2755 TRACE("Resetting folder for file %s.\n", debugstr_a(file
->filename
));
2757 /* free stuff for the old decompresser */
2759 case cffoldCOMPTYPE_LZX
:
2761 fdi
->free(LZX(window
));
2765 case cffoldCOMPTYPE_QUANTUM
:
2767 fdi
->free(QTM(window
));
2773 CAB(decomp_cab
) = NULL
;
2774 CAB(fdi
)->seek(CAB(cabhf
), fol
->offset
, SEEK_SET
);
2778 /* initialize the new decompresser */
2780 case cffoldCOMPTYPE_NONE
:
2781 CAB(decompress
) = NONEfdi_decomp
;
2783 case cffoldCOMPTYPE_MSZIP
:
2784 CAB(decompress
) = ZIPfdi_decomp
;
2786 case cffoldCOMPTYPE_QUANTUM
:
2787 CAB(decompress
) = QTMfdi_decomp
;
2788 err
= QTMfdi_init((comptype
>> 8) & 0x1f, (comptype
>> 4) & 0xF, decomp_state
);
2790 case cffoldCOMPTYPE_LZX
:
2791 CAB(decompress
) = LZXfdi_decomp
;
2792 err
= LZXfdi_init((comptype
>> 8) & 0x1f, decomp_state
);
2795 err
= DECR_DATAFORMAT
;
2805 set_error( fdi
, FDIERROR_ALLOC_FAIL
, ERROR_NOT_ENOUGH_MEMORY
);
2808 set_error( fdi
, FDIERROR_CORRUPT_CABINET
, 0 );
2812 if (file
->offset
> CAB(offset
)) {
2813 /* decode bytes and send them to /dev/null */
2814 switch (fdi_decomp(file
, 0, decomp_state
, pszCabPath
, pfnfdin
, pvUser
)) {
2817 case DECR_USERABORT
:
2818 set_error( fdi
, FDIERROR_USER_ABORT
, 0 );
2821 set_error( fdi
, FDIERROR_ALLOC_FAIL
, ERROR_NOT_ENOUGH_MEMORY
);
2824 set_error( fdi
, FDIERROR_CORRUPT_CABINET
, 0 );
2827 CAB(offset
) = file
->offset
;
2830 /* now do the actual decompression */
2831 err
= fdi_decomp(file
, 1, decomp_state
, pszCabPath
, pfnfdin
, pvUser
);
2832 if (err
) CAB(current
) = NULL
; else CAB(offset
) += file
->length
;
2834 /* fdintCLOSE_FILE_INFO notification */
2835 ZeroMemory(&fdin
, sizeof(FDINOTIFICATION
));
2837 fdin
.psz1
= (char *)file
->filename
;
2839 fdin
.cb
= (file
->attribs
& cffile_A_EXEC
) ? TRUE
: FALSE
; /* FIXME: is that right? */
2840 fdin
.date
= file
->date
;
2841 fdin
.time
= file
->time
;
2842 fdin
.attribs
= file
->attribs
; /* FIXME: filter _A_EXEC? */
2843 ((*pfnfdin
)(fdintCLOSE_FILE_INFO
, &fdin
));
2849 case DECR_USERABORT
:
2850 set_error( fdi
, FDIERROR_USER_ABORT
, 0 );
2853 set_error( fdi
, FDIERROR_ALLOC_FAIL
, ERROR_NOT_ENOUGH_MEMORY
);
2856 set_error( fdi
, FDIERROR_CORRUPT_CABINET
, 0 );
2862 free_decompression_temps(fdi
, fol
, decomp_state
);
2863 free_decompression_mem(fdi
, decomp_state
, file
);
2867 bail_and_fail
: /* here we free ram before error returns */
2869 if (fol
) free_decompression_temps(fdi
, fol
, decomp_state
);
2871 if (filehf
) fdi
->close(filehf
);
2873 free_decompression_mem(fdi
, decomp_state
, file
);
2878 /***********************************************************************
2879 * FDIDestroy (CABINET.23)
2881 * Frees a handle created by FDICreate. Do /not/ call this in the middle
2882 * of FDICopy. Only reason for failure would be an invalid handle.
2885 * hfdi [I] The HFDI to free
2891 BOOL __cdecl
FDIDestroy(HFDI hfdi
)
2893 FDI_Int
*fdi
= get_fdi_ptr( hfdi
);
2895 TRACE("(hfdi == ^%p)\n", hfdi
);
2896 if (!fdi
) return FALSE
;
2897 fdi
->magic
= 0; /* paranoia */
2902 /***********************************************************************
2903 * FDITruncateCabinet (CABINET.24)
2905 * Removes all folders of a cabinet file after and including the
2906 * specified folder number.
2909 * hfdi [I] Handle to the FDI context.
2910 * pszCabinetName [I] Filename of the cabinet.
2911 * iFolderToDelete [I] Index of the first folder to delete.
2918 * The PFNWRITE function supplied to FDICreate must truncate the
2919 * file at the current position if the number of bytes to write is 0.
2921 BOOL __cdecl
FDITruncateCabinet(
2923 char *pszCabinetName
,
2924 USHORT iFolderToDelete
)
2926 FDI_Int
*fdi
= get_fdi_ptr( hfdi
);
2928 FIXME("(hfdi == ^%p, pszCabinetName == %s, iFolderToDelete == %hu): stub\n",
2929 hfdi
, debugstr_a(pszCabinetName
), iFolderToDelete
);
2931 if (!fdi
) return FALSE
;
2933 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);