ReactOS 0.4.15-dev-7788-g1ad9096
fdi.c File Reference
#include "config.h"
#include <stdarg.h>
#include <stdio.h>
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "fdi.h"
#include "cabinet.h"
#include "wine/debug.h"
Include dependency graph for fdi.c:

Go to the source code of this file.

Classes

struct  fdi_file
 
struct  fdi_folder
 
struct  MORE_ISCAB_INFO
 
struct  FDI_Int
 
struct  fdi_cds_fwd
 

Macros

#define FDI_INT_MAGIC   0xfdfdfd05
 
#define ZIPNEEDBITS(n)
 
#define ZIPDUMPBITS(n)   {b>>=(n);k-=(n);}
 
#define EndGetI32(a)   ((((a)[3])<<24)|(((a)[2])<<16)|(((a)[1])<<8)|((a)[0]))
 
#define EndGetI16(a)   ((((a)[1])<<8)|((a)[0]))
 
#define CAB(x)   (decomp_state->x)
 
#define ZIP(x)   (decomp_state->methods.zip.x)
 
#define QTM(x)   (decomp_state->methods.qtm.x)
 
#define LZX(x)   (decomp_state->methods.lzx.x)
 
#define DECR_OK   (0)
 
#define DECR_DATAFORMAT   (1)
 
#define DECR_ILLEGALDATA   (2)
 
#define DECR_NOMEMORY   (3)
 
#define DECR_CHECKSUM   (4)
 
#define DECR_INPUT   (5)
 
#define DECR_OUTPUT   (6)
 
#define DECR_USERABORT   (7)
 

Typedefs

typedef struct MORE_ISCAB_INFOPMORE_ISCAB_INFO
 
typedef struct fdi_cds_fwd fdi_decomp_state
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (cabinet)
 
static void set_error (FDI_Int *fdi, int oper, int err)
 
static FDI_Intget_fdi_ptr (HFDI hfdi)
 
static void QTMupdatemodel (struct QTMmodel *model, int sym)
 
static int make_decode_table (cab_ULONG nsyms, cab_ULONG nbits, const cab_UBYTE *length, cab_UWORD *table)
 
static cab_ULONG checksum (const cab_UBYTE *data, cab_UWORD bytes, cab_ULONG csum)
 
HFDI __cdecl FDICreate (PFNALLOC pfnalloc, PFNFREE pfnfree, PFNOPEN pfnopen, PFNREAD pfnread, PFNWRITE pfnwrite, PFNCLOSE pfnclose, PFNSEEK pfnseek, int cpuType, PERF perf)
 
static LONG FDI_getoffset (FDI_Int *fdi, INT_PTR hf)
 
static charFDI_read_string (FDI_Int *fdi, INT_PTR hf, long cabsize)
 
static BOOL FDI_read_entries (FDI_Int *fdi, INT_PTR hf, PFDICABINETINFO pfdici, PMORE_ISCAB_INFO pmii)
 
BOOL __cdecl FDIIsCabinet (HFDI hfdi, INT_PTR hf, PFDICABINETINFO pfdici)
 
static void QTMfdi_initmodel (struct QTMmodel *m, struct QTMmodelsym *sym, int n, int s)
 
static int QTMfdi_init (int window, int level, fdi_decomp_state *decomp_state)
 
static int LZXfdi_init (int window, fdi_decomp_state *decomp_state)
 
static int NONEfdi_decomp (int inlen, int outlen, fdi_decomp_state *decomp_state)
 
static void fdi_Ziphuft_free (FDI_Int *fdi, struct Ziphuft *t)
 
static cab_LONG fdi_Ziphuft_build (cab_ULONG *b, cab_ULONG n, cab_ULONG s, const cab_UWORD *d, const cab_UWORD *e, struct Ziphuft **t, cab_LONG *m, fdi_decomp_state *decomp_state)
 
static cab_LONG fdi_Zipinflate_codes (const struct Ziphuft *tl, const struct Ziphuft *td, cab_LONG bl, cab_LONG bd, fdi_decomp_state *decomp_state)
 
static cab_LONG fdi_Zipinflate_stored (fdi_decomp_state *decomp_state)
 
static cab_LONG fdi_Zipinflate_fixed (fdi_decomp_state *decomp_state)
 
static cab_LONG fdi_Zipinflate_dynamic (fdi_decomp_state *decomp_state)
 
static cab_LONG fdi_Zipinflate_block (cab_LONG *e, fdi_decomp_state *decomp_state)
 
static int ZIPfdi_decomp (int inlen, int outlen, fdi_decomp_state *decomp_state)
 
static int QTMfdi_decomp (int inlen, int outlen, fdi_decomp_state *decomp_state)
 
static int fdi_lzx_read_lens (cab_UBYTE *lens, cab_ULONG first, cab_ULONG last, struct lzx_bits *lb, fdi_decomp_state *decomp_state)
 
static int LZXfdi_decomp (int inlen, int outlen, fdi_decomp_state *decomp_state)
 
static int fdi_decomp (const struct fdi_file *fi, int savemode, fdi_decomp_state *decomp_state, char *pszCabPath, PFNFDINOTIFY pfnfdin, void *pvUser)
 
static void free_decompression_temps (FDI_Int *fdi, const struct fdi_folder *fol, fdi_decomp_state *decomp_state)
 
static void free_decompression_mem (FDI_Int *fdi, fdi_decomp_state *decomp_state)
 
BOOL __cdecl FDICopy (HFDI hfdi, char *pszCabinet, char *pszCabPath, int flags, PFNFDINOTIFY pfnfdin, PFNFDIDECRYPT pfnfdid, void *pvUser)
 
BOOL __cdecl FDIDestroy (HFDI hfdi)
 
BOOL __cdecl FDITruncateCabinet (HFDI hfdi, char *pszCabinetName, USHORT iFolderToDelete)
 

Variables

 THOSE_ZIP_CONSTS
 

Macro Definition Documentation

◆ CAB

#define CAB (   x)    (decomp_state->x)

Definition at line 174 of file fdi.c.

◆ DECR_CHECKSUM

#define DECR_CHECKSUM   (4)

Definition at line 182 of file fdi.c.

◆ DECR_DATAFORMAT

#define DECR_DATAFORMAT   (1)

Definition at line 179 of file fdi.c.

◆ DECR_ILLEGALDATA

#define DECR_ILLEGALDATA   (2)

Definition at line 180 of file fdi.c.

◆ DECR_INPUT

#define DECR_INPUT   (5)

Definition at line 183 of file fdi.c.

◆ DECR_NOMEMORY

#define DECR_NOMEMORY   (3)

Definition at line 181 of file fdi.c.

◆ DECR_OK

#define DECR_OK   (0)

Definition at line 178 of file fdi.c.

◆ DECR_OUTPUT

#define DECR_OUTPUT   (6)

Definition at line 184 of file fdi.c.

◆ DECR_USERABORT

#define DECR_USERABORT   (7)

Definition at line 185 of file fdi.c.

◆ EndGetI16

#define EndGetI16 (   a)    ((((a)[1])<<8)|((a)[0]))

Definition at line 172 of file fdi.c.

◆ EndGetI32

#define EndGetI32 (   a)    ((((a)[3])<<24)|(((a)[2])<<16)|(((a)[1])<<8)|((a)[0]))

Definition at line 171 of file fdi.c.

◆ FDI_INT_MAGIC

#define FDI_INT_MAGIC   0xfdfdfd05

Definition at line 126 of file fdi.c.

◆ LZX

#define LZX (   x)    (decomp_state->methods.lzx.x)

Definition at line 177 of file fdi.c.

◆ QTM

#define QTM (   x)    (decomp_state->methods.qtm.x)

Definition at line 176 of file fdi.c.

◆ ZIP

#define ZIP (   x)    (decomp_state->methods.zip.x)

Definition at line 175 of file fdi.c.

◆ ZIPDUMPBITS

#define ZIPDUMPBITS (   n)    {b>>=(n);k-=(n);}

Definition at line 168 of file fdi.c.

◆ ZIPNEEDBITS

#define ZIPNEEDBITS (   n)
Value:
{while(k<(n)){cab_LONG c=*(ZIP(inpos)++);\
b|=((cab_ULONG)c)<<k;k+=8;}}
INT32 cab_LONG
Definition: mszip.h:28
UINT32 cab_ULONG
Definition: mszip.h:27
#define ZIP(x)
Definition: fdi.c:175
GLdouble n
Definition: glext.h:7729
const GLubyte * c
Definition: glext.h:8905
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
int k
Definition: mpi.c:3369

Definition at line 166 of file fdi.c.

Typedef Documentation

◆ fdi_decomp_state

◆ PMORE_ISCAB_INFO

Function Documentation

◆ checksum()

static cab_ULONG checksum ( const cab_UBYTE data,
cab_UWORD  bytes,
cab_ULONG  csum 
)
static

Definition at line 353 of file fdi.c.

353 {
354 int len;
355 cab_ULONG ul = 0;
356
357 for (len = bytes >> 2; len--; data += 4) {
358 csum ^= ((data[0]) | (data[1]<<8) | (data[2]<<16) | (data[3]<<24));
359 }
360
361 switch (bytes & 3) {
362 case 3: ul |= *data++ << 16;
363 /* fall through */
364 case 2: ul |= *data++ << 8;
365 /* fall through */
366 case 1: ul |= *data;
367 }
368 csum ^= ul;
369
370 return csum;
371}
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLenum GLsizei len
Definition: glext.h:6722
Definition: ffs.h:52

Referenced by add_module(), authgss_marshal(), authgss_validate(), authsspi_marshal(), authsspi_validate(), CalculateChecksum(), CalculateIpv4PseudoHeaderChecksum(), CalculateIpv6PseudoHeaderChecksum(), DECLARE_INTERFACE_(), elf_fetch_file_info(), extract_emf_from_comment(), fdi_decomp(), fetch_host_module_info_cb(), fix_checksum(), get_torito_desc(), getpacket(), GetWinMetaFileBits(), macho_fetch_file_info(), module_new(), putpacket(), SOFTPUB_HashPEFile(), svcauth_gss_accept_sec_context(), svcauth_gss_nextverf(), svcauth_gss_validate(), test__hwrite(), test__lwrite(), test_clip_xform(), tt_check_trickyness_sfnt_ids(), tt_synth_sfnt_checksum(), UDFReadTagged(), ZSTD_ldm_generateSequences_internal(), ZSTD_ldm_makeEntryAndInsertByTag(), and ZSTD_writeEpilogue().

◆ fdi_decomp()

static int fdi_decomp ( const struct fdi_file fi,
int  savemode,
fdi_decomp_state decomp_state,
char pszCabPath,
PFNFDINOTIFY  pfnfdin,
void pvUser 
)
static

Definition at line 1938 of file fdi.c.

1940{
1941 cab_ULONG bytes = savemode ? fi->length : fi->offset - CAB(offset);
1943 cab_UWORD inlen, len, outlen, cando;
1944 cab_ULONG cksum;
1945 cab_LONG err;
1946 fdi_decomp_state *cab = (savemode && CAB(decomp_cab)) ? CAB(decomp_cab) : decomp_state;
1947
1948 TRACE("(fi == ^%p, savemode == %d, bytes == %d)\n", fi, savemode, bytes);
1949
1950 while (bytes > 0) {
1951 /* cando = the max number of bytes we can do */
1952 cando = CAB(outlen);
1953 if (cando > bytes) cando = bytes;
1954
1955 /* if cando != 0 */
1956 if (cando && savemode)
1957 CAB(fdi)->write(CAB(filehf), CAB(outpos), cando);
1958
1959 CAB(outpos) += cando;
1960 CAB(outlen) -= cando;
1961 bytes -= cando; if (!bytes) break;
1962
1963 /* we only get here if we emptied the output buffer */
1964
1965 /* read data header + data */
1966 inlen = outlen = 0;
1967 while (outlen == 0) {
1968 /* read the block header, skip the reserved part */
1969 if (CAB(fdi)->read(cab->cabhf, buf, cfdata_SIZEOF) != cfdata_SIZEOF)
1970 return DECR_INPUT;
1971
1972 if (CAB(fdi)->seek(cab->cabhf, cab->mii.block_resv, SEEK_CUR) == -1)
1973 return DECR_INPUT;
1974
1975 /* we shouldn't get blocks over CAB_INPUTMAX in size */
1976 data = CAB(inbuf) + inlen;
1978 inlen += len;
1979 if (inlen > CAB_INPUTMAX) return DECR_INPUT;
1980 if (CAB(fdi)->read(cab->cabhf, data, len) != len)
1981 return DECR_INPUT;
1982
1983 /* clear two bytes after read-in data */
1984 data[len+1] = data[len+2] = 0;
1985
1986 /* perform checksum test on the block (if one is stored) */
1987 cksum = EndGetI32(buf+cfdata_CheckSum);
1988 if (cksum && cksum != checksum(buf+4, 4, checksum(data, len, 0)))
1989 return DECR_CHECKSUM; /* checksum is wrong */
1990
1992
1993 /* outlen=0 means this block was the last contiguous part
1994 of a split block, continued in the next cabinet */
1995 if (outlen == 0) {
1996 int pathlen, filenamelen;
1997 INT_PTR cabhf;
1998 char fullpath[MAX_PATH], userpath[256];
1999 FDINOTIFICATION fdin;
2000 FDICABINETINFO fdici;
2001 char emptystring = '\0';
2002 cab_UBYTE buf2[64];
2003 BOOL success = FALSE;
2004 struct fdi_folder *fol = NULL, *linkfol = NULL;
2005 struct fdi_file *file = NULL, *linkfile = NULL;
2006
2007 tryanothercab:
2008
2009 /* set up the next decomp_state... */
2010 if (!(cab->next)) {
2011 unsigned int i;
2012
2013 if (!cab->mii.hasnext) return DECR_INPUT;
2014
2015 if (!((cab->next = CAB(fdi)->alloc(sizeof(fdi_decomp_state)))))
2016 return DECR_NOMEMORY;
2017
2018 ZeroMemory(cab->next, sizeof(fdi_decomp_state));
2019
2020 /* copy pszCabPath to userpath */
2021 ZeroMemory(userpath, 256);
2022 pathlen = pszCabPath ? strlen(pszCabPath) : 0;
2023 if (pathlen) {
2024 if (pathlen < 256) /* else we are in a weird place... let's leave it blank and see if the user fixes it */
2025 strcpy(userpath, pszCabPath);
2026 }
2027
2028 /* initial fdintNEXT_CABINET notification */
2029 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2030 fdin.psz1 = cab->mii.nextname ? cab->mii.nextname : &emptystring;
2031 fdin.psz2 = cab->mii.nextinfo ? cab->mii.nextinfo : &emptystring;
2032 fdin.psz3 = userpath;
2033 fdin.fdie = FDIERROR_NONE;
2034 fdin.pv = pvUser;
2035
2036 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2037
2038 do {
2039
2040 pathlen = strlen(userpath);
2041 filenamelen = cab->mii.nextname ? strlen(cab->mii.nextname) : 0;
2042
2043 /* slight overestimation here to save CPU cycles in the developer's brain */
2044 if ((pathlen + filenamelen + 3) > MAX_PATH) {
2045 ERR("MAX_PATH exceeded.\n");
2046 return DECR_ILLEGALDATA;
2047 }
2048
2049 /* paste the path and filename together */
2050 fullpath[0] = '\0';
2051 if (pathlen) {
2052 strcpy(fullpath, userpath);
2053#ifdef __REACTOS__
2054 if (fullpath[pathlen - 1] == '\\')
2055 fullpath[pathlen - 1] = '\0';
2056#else
2057 if (fullpath[pathlen - 1] != '\\')
2058 strcat(fullpath, "\\");
2059#endif
2060 }
2061#ifdef __REACTOS__
2062 if (filenamelen) {
2063 strcat(fullpath, "\\");
2064#else
2065 if (filenamelen)
2066#endif
2067 strcat(fullpath, cab->mii.nextname);
2068#ifdef __REACTOS__
2069 }
2070#endif
2071
2072 TRACE("full cab path/file name: %s\n", debugstr_a(fullpath));
2073
2074 /* try to get a handle to the cabfile */
2075 cabhf = CAB(fdi)->open(fullpath, _O_RDONLY|_O_BINARY, _S_IREAD | _S_IWRITE);
2076 if (cabhf == -1) {
2077 /* no file. allow the user to try again */
2079 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2080 continue;
2081 }
2082
2083 if (cabhf == 0) {
2084 ERR("PFDI_OPEN returned zero for %s.\n", fullpath);
2086 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2087 continue;
2088 }
2089
2090 /* check if it's really a cabfile. Note that this doesn't implement the bug */
2091 if (!FDI_read_entries(CAB(fdi), cabhf, &fdici, &(cab->next->mii))) {
2092 WARN("FDIIsCabinet failed.\n");
2093 CAB(fdi)->close(cabhf);
2095 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2096 continue;
2097 }
2098
2099 if ((fdici.setID != cab->setID) || (fdici.iCabinet != (cab->iCabinet + 1))) {
2100 WARN("Wrong Cabinet.\n");
2101 CAB(fdi)->close(cabhf);
2103 if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
2104 continue;
2105 }
2106
2107 break;
2108
2109 } while (1);
2110
2111 /* cabinet notification */
2112 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2113 fdin.setID = fdici.setID;
2114 fdin.iCabinet = fdici.iCabinet;
2115 fdin.pv = pvUser;
2116 fdin.psz1 = (cab->next->mii.nextname) ? cab->next->mii.nextname : &emptystring;
2117 fdin.psz2 = (cab->next->mii.nextinfo) ? cab->next->mii.nextinfo : &emptystring;
2118 fdin.psz3 = pszCabPath;
2119
2120 if (((*pfnfdin)(fdintCABINET_INFO, &fdin))) return DECR_USERABORT;
2121
2122 cab->next->setID = fdici.setID;
2123 cab->next->iCabinet = fdici.iCabinet;
2124 cab->next->fdi = CAB(fdi);
2125 cab->next->filehf = CAB(filehf);
2126 cab->next->cabhf = cabhf;
2127 cab->next->decompress = CAB(decompress); /* crude, but unused anyhow */
2128
2129 cab = cab->next; /* advance to the next cabinet */
2130
2131 /* read folders */
2132 for (i = 0; i < fdici.cFolders; i++) {
2133 if (CAB(fdi)->read(cab->cabhf, buf2, cffold_SIZEOF) != cffold_SIZEOF)
2134 return DECR_INPUT;
2135
2136 if (cab->mii.folder_resv > 0)
2137 CAB(fdi)->seek(cab->cabhf, cab->mii.folder_resv, SEEK_CUR);
2138
2139 fol = CAB(fdi)->alloc(sizeof(struct fdi_folder));
2140 if (!fol) {
2141 ERR("out of memory!\n");
2142 return DECR_NOMEMORY;
2143 }
2144 ZeroMemory(fol, sizeof(struct fdi_folder));
2145 if (!(cab->firstfol)) cab->firstfol = fol;
2146
2149 fol->comp_type = EndGetI16(buf2+cffold_CompType);
2150
2151 if (linkfol)
2152 linkfol->next = fol;
2153 linkfol = fol;
2154 }
2155
2156 /* read files */
2157 for (i = 0; i < fdici.cFiles; i++) {
2158 if (CAB(fdi)->read(cab->cabhf, buf2, cffile_SIZEOF) != cffile_SIZEOF)
2159 return DECR_INPUT;
2160
2161 file = CAB(fdi)->alloc(sizeof(struct fdi_file));
2162 if (!file) {
2163 ERR("out of memory!\n");
2164 return DECR_NOMEMORY;
2165 }
2166 ZeroMemory(file, sizeof(struct fdi_file));
2167 if (!(cab->firstfile)) cab->firstfile = file;
2168
2169 file->length = EndGetI32(buf2+cffile_UncompressedSize);
2171 file->index = EndGetI16(buf2+cffile_FolderIndex);
2172 file->time = EndGetI16(buf2+cffile_Time);
2173 file->date = EndGetI16(buf2+cffile_Date);
2175 file->filename = FDI_read_string(CAB(fdi), cab->cabhf, fdici.cbCabinet);
2176
2177 if (!file->filename) return DECR_INPUT;
2178
2179 if (linkfile)
2180 linkfile->next = file;
2181 linkfile = file;
2182 }
2183
2184 } else
2185 cab = cab->next; /* advance to the next cabinet */
2186
2187 /* iterate files -- if we encounter the continued file, process it --
2188 otherwise, jump to the label above and keep looking */
2189
2190 for (file = cab->firstfile; (file); file = file->next) {
2192 /* check to ensure a real match */
2193 if (lstrcmpiA(fi->filename, file->filename) == 0) {
2194 success = TRUE;
2195 if (CAB(fdi)->seek(cab->cabhf, cab->firstfol->offset, SEEK_SET) == -1)
2196 return DECR_INPUT;
2197 break;
2198 }
2199 }
2200 }
2201 if (!success) goto tryanothercab; /* FIXME: shouldn't this trigger
2202 "Wrong Cabinet" notification? */
2203 }
2204 }
2205
2206 /* decompress block */
2207 if ((err = CAB(decompress)(inlen, outlen, decomp_state)))
2208 return err;
2209 CAB(outlen) = outlen;
2210 CAB(outpos) = CAB(outbuf);
2211 }
2212
2213 CAB(decomp_cab) = cab;
2214 return DECR_OK;
2215}
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define read
Definition: acwin.h:96
static int inbuf
Definition: adnsresfilter.c:73
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CAB_INPUTMAX
Definition: mszip.h:98
UINT16 cab_UWORD
Definition: mszip.h:26
unsigned char cab_UBYTE
Definition: mszip.h:25
#define cffile_Attribs
Definition: cabinet.h:92
#define _O_BINARY
Definition: cabinet.h:51
#define cffold_NumBlocks
Definition: cabinet.h:84
#define cffile_Time
Definition: cabinet.h:91
#define cffold_SIZEOF
Definition: cabinet.h:86
#define cffile_SIZEOF
Definition: cabinet.h:93
#define cffileCONTINUED_FROM_PREV
Definition: cabinet.h:108
#define cffile_FolderOffset
Definition: cabinet.h:88
#define cffile_FolderIndex
Definition: cabinet.h:89
#define _O_RDONLY
Definition: cabinet.h:37
#define cfdata_UncompressedSize
Definition: cabinet.h:96
#define cffile_Date
Definition: cabinet.h:90
#define cffile_UncompressedSize
Definition: cabinet.h:87
#define cfdata_CheckSum
Definition: cabinet.h:94
UINT32 cab_off_t
Definition: cabinet.h:62
#define cffold_DataOffset
Definition: cabinet.h:83
#define cffold_CompType
Definition: cabinet.h:85
#define cfdata_SIZEOF
Definition: cabinet.h:97
#define _S_IWRITE
Definition: cabinet.h:33
#define cfdata_CompressedSize
Definition: cabinet.h:95
#define _S_IREAD
Definition: cabinet.h:34
static cab_ULONG checksum(const cab_UBYTE *data, cab_UWORD bytes, cab_ULONG csum)
Definition: fdi.c:353
static char * FDI_read_string(FDI_Int *fdi, INT_PTR hf, long cabsize)
Definition: fdi.c:476
#define DECR_CHECKSUM
Definition: fdi.c:182
#define DECR_USERABORT
Definition: fdi.c:185
static BOOL FDI_read_entries(FDI_Int *fdi, INT_PTR hf, PFDICABINETINFO pfdici, PMORE_ISCAB_INFO pmii)
Definition: fdi.c:532
#define EndGetI16(a)
Definition: fdi.c:172
#define CAB(x)
Definition: fdi.c:174
#define EndGetI32(a)
Definition: fdi.c:171
#define DECR_OK
Definition: fdi.c:178
#define DECR_ILLEGALDATA
Definition: fdi.c:180
#define DECR_INPUT
Definition: fdi.c:183
#define DECR_NOMEMORY
Definition: fdi.c:181
#define MAX_PATH
Definition: compat.h:34
@ FDIERROR_WRONG_CABINET
Definition: fdi.h:125
@ FDIERROR_NONE
Definition: fdi.h:115
@ FDIERROR_NOT_A_CABINET
Definition: fdi.h:117
@ FDIERROR_CABINET_NOT_FOUND
Definition: fdi.h:116
@ fdintCABINET_INFO
Definition: fdi.h:247
@ fdintNEXT_CABINET
Definition: fdi.h:251
unsigned int BOOL
Definition: ntddk_ex.h:94
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLintptr offset
Definition: glext.h:5920
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define SEEK_SET
Definition: jmemansi.c:26
#define debugstr_a
Definition: kernel32.h:31
int WINAPI lstrcmpiA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:42
#define SEEK_CUR
Definition: util.h:63
#define err(...)
#define alloc
Definition: rosglue.h:13
int seek(void *fd, ulong off, int mode)
Definition: pe.c:51
#define TRACE(s)
Definition: solgame.cpp:4
USHORT setID
Definition: fdi.h:149
USHORT iCabinet
Definition: fdi.h:150
USHORT cFiles
Definition: fdi.h:148
USHORT cFolders
Definition: fdi.h:147
LONG cbCabinet
Definition: fdi.h:146
USHORT setID
Definition: fdi.h:239
USHORT iCabinet
Definition: fdi.h:240
char * psz3
Definition: fdi.h:230
char * psz2
Definition: fdi.h:229
void * pv
Definition: fdi.h:231
FDIERROR fdie
Definition: fdi.h:243
char * psz1
Definition: fdi.h:228
cab_UBYTE block_resv
Definition: fdi.c:110
BOOL hasnext
Definition: fdi.c:108
char * nextinfo
Definition: fdi.c:107
int folder_resv
Definition: fdi.c:109
char * nextname
Definition: fdi.c:107
struct define * next
Definition: compiler.c:65
MORE_ISCAB_INFO mii
Definition: fdi.c:160
USHORT iCabinet
Definition: fdi.c:158
struct fdi_cds_fwd * next
Definition: fdi.c:163
USHORT setID
Definition: fdi.c:157
struct fdi_folder * firstfol
Definition: fdi.c:161
INT_PTR cabhf
Definition: fdi.c:139
struct fdi_file * firstfile
Definition: fdi.c:162
Definition: fdi.c:78
cab_ULONG length
Definition: fdi.c:82
LPSTR filename
Definition: fdi.c:80
cab_ULONG offset
Definition: fdi.c:83
Definition: fdi.c:89
cab_UWORD comp_type
Definition: fdi.c:92
cab_UWORD num_blocks
Definition: fdi.c:95
cab_off_t offset
Definition: fdi.c:91
Definition: fci.c:127
cab_ULONG offset
Definition: fci.c:130
cab_UWORD date
Definition: fci.c:132
cab_UWORD attribs
Definition: fci.c:134
cab_UWORD time
Definition: fci.c:133
int32_t INT_PTR
Definition: typedefs.h:64
#define success(from, fromstr, to, tostr)
#define ZeroMemory
Definition: winbase.h:1712

Referenced by FDICopy().

◆ FDI_getoffset()

static LONG FDI_getoffset ( FDI_Int fdi,
INT_PTR  hf 
)
static

Definition at line 466 of file fdi.c.

467{
468 return fdi->seek(hf, 0, SEEK_CUR);
469}
PFNSEEK seek
Definition: fdi.c:122

Referenced by FDI_read_string().

◆ fdi_lzx_read_lens()

static int fdi_lzx_read_lens ( cab_UBYTE lens,
cab_ULONG  first,
cab_ULONG  last,
struct lzx_bits lb,
fdi_decomp_state decomp_state 
)
static

Definition at line 1559 of file fdi.c.

1560 {
1561 cab_ULONG i,j, x,y;
1562 int z;
1563
1564 register cab_ULONG bitbuf = lb->bb;
1565 register int bitsleft = lb->bl;
1566 cab_UBYTE *inpos = lb->ip;
1567 cab_UWORD *hufftbl;
1568
1569 for (x = 0; x < 20; x++) {
1570 READ_BITS(y, 4);
1571 LENTABLE(PRETREE)[x] = y;
1572 }
1573 BUILD_TABLE(PRETREE);
1574
1575 for (x = first; x < last; ) {
1576 READ_HUFFSYM(PRETREE, z);
1577 if (z == 17) {
1578 READ_BITS(y, 4); y += 4;
1579 while (y--) lens[x++] = 0;
1580 }
1581 else if (z == 18) {
1582 READ_BITS(y, 5); y += 20;
1583 while (y--) lens[x++] = 0;
1584 }
1585 else if (z == 19) {
1586 READ_BITS(y, 1); y += 4;
1587 READ_HUFFSYM(PRETREE, z);
1588 z = lens[x] - z; if (z < 0) z += 17;
1589 while (y--) lens[x++] = z;
1590 }
1591 else {
1592 z = lens[x] - z; if (z < 0) z += 17;
1593 lens[x++] = z;
1594 }
1595 }
1596
1597 lb->bb = bitbuf;
1598 lb->bl = bitsleft;
1599 lb->ip = inpos;
1600 return 0;
1601}
#define READ_BITS(v, n)
Definition: cabinet.h:426
#define LENTABLE(tbl)
Definition: cabinet.h:442
#define READ_HUFFSYM(tbl, var)
Definition: cabinet.h:457
#define BUILD_TABLE(tbl)
Definition: cabinet.h:449
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
const GLint * first
Definition: glext.h:5794
GLdouble GLdouble z
Definition: glext.h:5874
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
static UINT UINT last
Definition: font.c:45
cab_ULONG bb
Definition: cabinet.h:235
cab_UBYTE * ip
Definition: cabinet.h:237
int bl
Definition: cabinet.h:236

Referenced by LZXfdi_decomp().

◆ FDI_read_entries()

static BOOL FDI_read_entries ( FDI_Int fdi,
INT_PTR  hf,
PFDICABINETINFO  pfdici,
PMORE_ISCAB_INFO  pmii 
)
static

Definition at line 532 of file fdi.c.

537{
538 int num_folders, num_files, header_resv, folder_resv = 0;
539 LONG cabsize;
540 USHORT setid, cabidx, flags;
541 cab_UBYTE buf[64], block_resv;
542 char *prevname = NULL, *previnfo = NULL, *nextname = NULL, *nextinfo = NULL;
543
544 TRACE("(fdi == ^%p, hf == %ld, pfdici == ^%p)\n", fdi, hf, pfdici);
545
546 /* read in the CFHEADER */
547 if (fdi->read(hf, buf, cfhead_SIZEOF) != cfhead_SIZEOF) {
548 if (pmii) set_error( fdi, FDIERROR_NOT_A_CABINET, 0 );
549 return FALSE;
550 }
551
552 /* check basic MSCF signature */
553 if (EndGetI32(buf+cfhead_Signature) != 0x4643534d) {
554 if (pmii) set_error( fdi, FDIERROR_NOT_A_CABINET, 0 );
555 return FALSE;
556 }
557
558 /* get the cabinet size */
560
561 /* get the number of folders */
562 num_folders = EndGetI16(buf+cfhead_NumFolders);
563
564 /* get the number of files */
565 num_files = EndGetI16(buf+cfhead_NumFiles);
566
567 /* setid */
568 setid = EndGetI16(buf+cfhead_SetID);
569
570 /* cabinet (set) index */
572
573 /* check the header revision */
574 if ((buf[cfhead_MajorVersion] > 1) ||
576 {
577 WARN("cabinet format version > 1.3\n");
578 if (pmii) set_error( fdi, FDIERROR_UNKNOWN_CABINET_VERSION, 0 /* ? */ );
579 return FALSE;
580 }
581
582 /* pull the flags out */
584
585 /* read the reserved-sizes part of header, if present */
587 if (fdi->read(hf, buf, cfheadext_SIZEOF) != cfheadext_SIZEOF) {
588 ERR("bunk reserve-sizes?\n");
589 if (pmii) set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 /* ? */ );
590 return FALSE;
591 }
592
594 if (pmii) pmii->header_resv = header_resv;
595 folder_resv = buf[cfheadext_FolderReserved];
596 if (pmii) pmii->folder_resv = folder_resv;
597 block_resv = buf[cfheadext_DataReserved];
598 if (pmii) pmii->block_resv = block_resv;
599
600 if (header_resv > 60000) {
601 WARN("WARNING; header reserved space > 60000\n");
602 }
603
604 /* skip the reserved header */
605 if ((header_resv) && (fdi->seek(hf, header_resv, SEEK_CUR) == -1)) {
606 ERR("seek failure: header_resv\n");
607 if (pmii) set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 /* ? */ );
608 return FALSE;
609 }
610 }
611
613 prevname = FDI_read_string(fdi, hf, cabsize);
614 if (!prevname) {
615 if (pmii) set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 /* ? */ );
616 return FALSE;
617 } else
618 if (pmii)
619 pmii->prevname = prevname;
620 else
621 fdi->free(prevname);
622 previnfo = FDI_read_string(fdi, hf, cabsize);
623 if (previnfo) {
624 if (pmii)
625 pmii->previnfo = previnfo;
626 else
627 fdi->free(previnfo);
628 }
629 }
630
632 if (pmii)
633 pmii->hasnext = TRUE;
634 nextname = FDI_read_string(fdi, hf, cabsize);
635 if (!nextname) {
636 if ((flags & cfheadPREV_CABINET) && pmii) {
637 if (pmii->prevname) fdi->free(prevname);
638 if (pmii->previnfo) fdi->free(previnfo);
639 }
640 set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 /* ? */ );
641 return FALSE;
642 } else
643 if (pmii)
644 pmii->nextname = nextname;
645 else
646 fdi->free(nextname);
647 nextinfo = FDI_read_string(fdi, hf, cabsize);
648 if (nextinfo) {
649 if (pmii)
650 pmii->nextinfo = nextinfo;
651 else
652 fdi->free(nextinfo);
653 }
654 }
655
656 /* we could process the whole cabinet searching for problems;
657 instead lets stop here. Now let's fill out the paperwork */
658 pfdici->cbCabinet = cabsize;
659 pfdici->cFolders = num_folders;
660 pfdici->cFiles = num_files;
661 pfdici->setID = setid;
662 pfdici->iCabinet = cabidx;
663 pfdici->fReserve = (flags & cfheadRESERVE_PRESENT) != 0;
664 pfdici->hasprev = (flags & cfheadPREV_CABINET) != 0;
665 pfdici->hasnext = (flags & cfheadNEXT_CABINET) != 0;
666 return TRUE;
667}
#define cfheadext_HeaderReserved
Definition: cabinet.h:79
#define cfheadRESERVE_PRESENT
Definition: cabinet.h:107
#define cfhead_Signature
Definition: cabinet.h:68
#define cfheadext_DataReserved
Definition: cabinet.h:81
#define cfhead_MajorVersion
Definition: cabinet.h:72
#define cfheadNEXT_CABINET
Definition: cabinet.h:106
#define cfhead_CabinetIndex
Definition: cabinet.h:77
#define cfhead_SetID
Definition: cabinet.h:76
#define cfhead_NumFiles
Definition: cabinet.h:74
#define cfhead_SIZEOF
Definition: cabinet.h:78
#define cfhead_MinorVersion
Definition: cabinet.h:71
#define cfhead_NumFolders
Definition: cabinet.h:73
#define cfhead_CabinetSize
Definition: cabinet.h:69
#define cfheadext_FolderReserved
Definition: cabinet.h:80
#define cfheadext_SIZEOF
Definition: cabinet.h:82
#define cfhead_Flags
Definition: cabinet.h:75
#define cfheadPREV_CABINET
Definition: cabinet.h:105
static void set_error(FDI_Int *fdi, int oper, int err)
Definition: fdi.c:187
@ FDIERROR_CORRUPT_CABINET
Definition: fdi.h:119
@ FDIERROR_UNKNOWN_CABINET_VERSION
Definition: fdi.h:118
GLbitfield flags
Definition: glext.h:7161
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
BOOL hasprev
Definition: fdi.h:152
BOOL hasnext
Definition: fdi.h:153
BOOL fReserve
Definition: fdi.h:151
PFNFREE free
Definition: fdi.c:117
PFNREAD read
Definition: fdi.c:119
char * prevname
Definition: fdi.c:106
int header_resv
Definition: fdi.c:109
char * previnfo
Definition: fdi.c:106

Referenced by fdi_decomp(), FDICopy(), and FDIIsCabinet().

◆ FDI_read_string()

static char * FDI_read_string ( FDI_Int fdi,
INT_PTR  hf,
long  cabsize 
)
static

Definition at line 476 of file fdi.c.

477{
478 size_t len=256,
479 base = FDI_getoffset(fdi, hf),
480 maxlen = cabsize - base;
481 BOOL ok = FALSE;
482 unsigned int i;
483 cab_UBYTE *buf = NULL;
484
485 TRACE("(fdi == %p, hf == %ld, cabsize == %ld)\n", fdi, hf, cabsize);
486
487 do {
488 if (len > maxlen) len = maxlen;
489 if (!(buf = fdi->alloc(len))) break;
490 if (!fdi->read(hf, buf, len)) break;
491
492 /* search for a null terminator in what we've just read */
493 for (i=0; i < len; i++) {
494 if (!buf[i]) {ok=TRUE; break;}
495 }
496
497 if (!ok) {
498 if (len == maxlen) {
499 ERR("cabinet is truncated\n");
500 break;
501 }
502 /* The buffer is too small for the string. Reset the file to the point
503 * where we started, free the buffer and increase the size for the next try
504 */
505 fdi->seek(hf, base, SEEK_SET);
506 fdi->free(buf);
507 buf = NULL;
508 len *= 2;
509 }
510 } while (!ok);
511
512 if (!ok) {
513 if (buf)
514 fdi->free(buf);
515 else
516 ERR("out of memory!\n");
517 return NULL;
518 }
519
520 /* otherwise, set the stream to just after the string and return */
521 fdi->seek(hf, base + strlen((char *)buf) + 1, SEEK_SET);
522
523 return (char *) buf;
524}
#define ok(value,...)
Definition: atltest.h:57
static LONG FDI_getoffset(FDI_Int *fdi, INT_PTR hf)
Definition: fdi.c:466
PFNALLOC alloc
Definition: fdi.c:116

Referenced by fdi_decomp(), FDI_read_entries(), and FDICopy().

◆ fdi_Ziphuft_build()

static cab_LONG fdi_Ziphuft_build ( cab_ULONG b,
cab_ULONG  n,
cab_ULONG  s,
const cab_UWORD d,
const cab_UWORD e,
struct Ziphuft **  t,
cab_LONG m,
fdi_decomp_state decomp_state 
)
static

Definition at line 880 of file fdi.c.

882{
883 cab_ULONG a; /* counter for codes of length k */
884 cab_ULONG el; /* length of EOB code (value 256) */
885 cab_ULONG f; /* i repeats in table every f entries */
886 cab_LONG g; /* maximum code length */
887 cab_LONG h; /* table level */
888 register cab_ULONG i; /* counter, current code */
889 register cab_ULONG j; /* counter */
890 register cab_LONG k; /* number of bits in current code */
891 cab_LONG *l; /* stack of bits per table */
892 register cab_ULONG *p; /* pointer into ZIP(c)[],ZIP(b)[],ZIP(v)[] */
893 register struct Ziphuft *q; /* points to current table */
894 struct Ziphuft r; /* table entry for structure assignment */
895 register cab_LONG w; /* bits before this table == (l * h) */
896 cab_ULONG *xp; /* pointer into x */
897 cab_LONG y; /* number of dummy codes added */
898 cab_ULONG z; /* number of entries in current table */
899
900 l = ZIP(lx)+1;
901
902 /* Generate counts for each bit length */
903 el = n > 256 ? b[256] : ZIPBMAX; /* set length of EOB code, if any */
904
905 for(i = 0; i < ZIPBMAX+1; ++i)
906 ZIP(c)[i] = 0;
907 p = b; i = n;
908 do
909 {
910 ZIP(c)[*p]++; p++; /* assume all entries <= ZIPBMAX */
911 } while (--i);
912 if (ZIP(c)[0] == n) /* null input--all zero length codes */
913 {
914 *t = NULL;
915 *m = 0;
916 return 0;
917 }
918
919 /* Find minimum and maximum length, bound *m by those */
920 for (j = 1; j <= ZIPBMAX; j++)
921 if (ZIP(c)[j])
922 break;
923 k = j; /* minimum code length */
924 if ((cab_ULONG)*m < j)
925 *m = j;
926 for (i = ZIPBMAX; i; i--)
927 if (ZIP(c)[i])
928 break;
929 g = i; /* maximum code length */
930 if ((cab_ULONG)*m > i)
931 *m = i;
932
933 /* Adjust last length count to fill out codes, if needed */
934 for (y = 1 << j; j < i; j++, y <<= 1)
935 if ((y -= ZIP(c)[j]) < 0)
936 return 2; /* bad input: more codes than bits */
937 if ((y -= ZIP(c)[i]) < 0)
938 return 2;
939 ZIP(c)[i] += y;
940
941 /* Generate starting offsets LONGo the value table for each length */
942 ZIP(x)[1] = j = 0;
943 p = ZIP(c) + 1; xp = ZIP(x) + 2;
944 while (--i)
945 { /* note that i == g from above */
946 *xp++ = (j += *p++);
947 }
948
949 /* Make a table of values in order of bit lengths */
950 p = b; i = 0;
951 do{
952 if ((j = *p++) != 0)
953 ZIP(v)[ZIP(x)[j]++] = i;
954 } while (++i < n);
955
956
957 /* Generate the Huffman codes and for each, make the table entries */
958 ZIP(x)[0] = i = 0; /* first Huffman code is zero */
959 p = ZIP(v); /* grab values in bit order */
960 h = -1; /* no tables yet--level -1 */
961 w = l[-1] = 0; /* no bits decoded yet */
962 ZIP(u)[0] = NULL; /* just to keep compilers happy */
963 q = NULL; /* ditto */
964 z = 0; /* ditto */
965
966 /* go through the bit lengths (k already is bits in shortest code) */
967 for (; k <= g; k++)
968 {
969 a = ZIP(c)[k];
970 while (a--)
971 {
972 /* here i is the Huffman code of length k bits for value *p */
973 /* make tables up to required level */
974 while (k > w + l[h])
975 {
976 w += l[h++]; /* add bits already decoded */
977
978 /* compute minimum size table less than or equal to *m bits */
979 if ((z = g - w) > (cab_ULONG)*m) /* upper limit */
980 z = *m;
981 if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
982 { /* too few codes for k-w bit table */
983 f -= a + 1; /* deduct codes from patterns left */
984 xp = ZIP(c) + k;
985 while (++j < z) /* try smaller tables up to z bits */
986 {
987 if ((f <<= 1) <= *++xp)
988 break; /* enough codes to use up j bits */
989 f -= *xp; /* else deduct codes from patterns */
990 }
991 }
992 if ((cab_ULONG)w + j > el && (cab_ULONG)w < el)
993 j = el - w; /* make EOB code end at table */
994 z = 1 << j; /* table entries for j-bit table */
995 l[h] = j; /* set table size in stack */
996
997 /* allocate and link in new table */
998 if (!(q = CAB(fdi)->alloc((z + 1)*sizeof(struct Ziphuft))))
999 {
1000 if(h)
1001 fdi_Ziphuft_free(CAB(fdi), ZIP(u)[0]);
1002 return 3; /* not enough memory */
1003 }
1004 *t = q + 1; /* link to list for Ziphuft_free() */
1005 *(t = &(q->v.t)) = NULL;
1006 ZIP(u)[h] = ++q; /* table starts after link */
1007
1008 /* connect to last table, if there is one */
1009 if (h)
1010 {
1011 ZIP(x)[h] = i; /* save pattern for backing up */
1012 r.b = (cab_UBYTE)l[h-1]; /* bits to dump before this table */
1013 r.e = (cab_UBYTE)(16 + j); /* bits in this table */
1014 r.v.t = q; /* pointer to this table */
1015 j = (i & ((1 << w) - 1)) >> (w - l[h-1]);
1016 ZIP(u)[h-1][j] = r; /* connect to last table */
1017 }
1018 }
1019
1020 /* set up table entry in r */
1021 r.b = (cab_UBYTE)(k - w);
1022 if (p >= ZIP(v) + n)
1023 r.e = 99; /* out of values--invalid code */
1024 else if (*p < s)
1025 {
1026 r.e = (cab_UBYTE)(*p < 256 ? 16 : 15); /* 256 is end-of-block code */
1027 r.v.n = *p++; /* simple code is just the value */
1028 }
1029 else
1030 {
1031 r.e = (cab_UBYTE)e[*p - s]; /* non-simple--look up in lists */
1032 r.v.n = d[*p++ - s];
1033 }
1034
1035 /* fill code-like entries with r */
1036 f = 1 << (k - w);
1037 for (j = i >> w; j < z; j += f)
1038 q[j] = r;
1039
1040 /* backwards increment the k-bit code i */
1041 for (j = 1 << (k - 1); i & j; j >>= 1)
1042 i ^= j;
1043 i ^= j;
1044
1045 /* backup over finished tables */
1046 while ((i & ((1 << w) - 1)) != ZIP(x)[h])
1047 w -= l[--h]; /* don't need to update q */
1048 }
1049 }
1050
1051 /* return actual size of base table */
1052 *m = l[0];
1053
1054 /* Return true (1) if we were given an incomplete table */
1055 return y != 0 && g != 1;
1056}
r l[0]
Definition: byte_order.h:168
#define ZIPBMAX
Definition: mszip.h:52
static void fdi_Ziphuft_free(FDI_Int *fdi, struct Ziphuft *t)
Definition: fdi.c:863
const GLdouble * v
Definition: gl.h:2040
GLdouble s
Definition: gl.h:2039
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble GLdouble t
Definition: gl.h:2047
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLfloat f
Definition: glext.h:7540
GLboolean GLboolean g
Definition: glext.h:6204
GLfloat GLfloat p
Definition: glext.h:8902
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
const GLfloat * m
Definition: glext.h:10848
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
#define d
Definition: ke_i.h:81
#define e
Definition: ke_i.h:82
#define f
Definition: ke_i.h:83
#define a
Definition: ke_i.h:78
#define b
Definition: ke_i.h:79
if(dx< 0)
Definition: linetemp.h:194
Definition: mszip.h:55

Referenced by fdi_Zipinflate_dynamic(), and fdi_Zipinflate_fixed().

◆ fdi_Ziphuft_free()

static void fdi_Ziphuft_free ( FDI_Int fdi,
struct Ziphuft t 
)
static

Definition at line 863 of file fdi.c.

864{
865 register struct Ziphuft *p, *q;
866
867 /* Go through linked list, freeing from the allocated (t[-1]) address. */
868 p = t;
869 while (p != NULL)
870 {
871 q = (--p)->v.t;
872 fdi->free(p);
873 p = q;
874 }
875}

Referenced by fdi_Ziphuft_build(), fdi_Zipinflate_dynamic(), and fdi_Zipinflate_fixed().

◆ fdi_Zipinflate_block()

static cab_LONG fdi_Zipinflate_block ( cab_LONG e,
fdi_decomp_state decomp_state 
)
static

Definition at line 1368 of file fdi.c.

1369{ /* decompress an inflated block */
1370 cab_ULONG t; /* block type */
1371 register cab_ULONG b; /* bit buffer */
1372 register cab_ULONG k; /* number of bits in bit buffer */
1373
1374 /* make local bit buffer */
1375 b = ZIP(bb);
1376 k = ZIP(bk);
1377
1378 /* read in last block bit */
1379 ZIPNEEDBITS(1)
1380 *e = (cab_LONG)b & 1;
1381 ZIPDUMPBITS(1)
1382
1383 /* read in block type */
1384 ZIPNEEDBITS(2)
1385 t = b & 3;
1386 ZIPDUMPBITS(2)
1387
1388 /* restore the global bit buffer */
1389 ZIP(bb) = b;
1390 ZIP(bk) = k;
1391
1392 /* inflate that block type */
1393 if(t == 2)
1394 return fdi_Zipinflate_dynamic(decomp_state);
1395 if(t == 0)
1396 return fdi_Zipinflate_stored(decomp_state);
1397 if(t == 1)
1398 return fdi_Zipinflate_fixed(decomp_state);
1399 /* bad block type */
1400 return 2;
1401}
return
Definition: dirsup.c:529
static cab_LONG fdi_Zipinflate_fixed(fdi_decomp_state *decomp_state)
Definition: fdi.c:1191
#define ZIPNEEDBITS(n)
Definition: fdi.c:166
#define ZIPDUMPBITS(n)
Definition: fdi.c:168
static cab_LONG fdi_Zipinflate_stored(fdi_decomp_state *decomp_state)
Definition: fdi.c:1147
static cab_LONG fdi_Zipinflate_dynamic(fdi_decomp_state *decomp_state)
Definition: fdi.c:1235

Referenced by ZIPfdi_decomp().

◆ fdi_Zipinflate_codes()

static cab_LONG fdi_Zipinflate_codes ( const struct Ziphuft tl,
const struct Ziphuft td,
cab_LONG  bl,
cab_LONG  bd,
fdi_decomp_state decomp_state 
)
static

Definition at line 1061 of file fdi.c.

1063{
1064 register cab_ULONG e; /* table entry flag/number of extra bits */
1065 cab_ULONG n, d; /* length and index for copy */
1066 cab_ULONG w; /* current window position */
1067 const struct Ziphuft *t; /* pointer to table entry */
1068 cab_ULONG ml, md; /* masks for bl and bd bits */
1069 register cab_ULONG b; /* bit buffer */
1070 register cab_ULONG k; /* number of bits in bit buffer */
1071
1072 /* make local copies of globals */
1073 b = ZIP(bb); /* initialize bit buffer */
1074 k = ZIP(bk);
1075 w = ZIP(window_posn); /* initialize window position */
1076
1077 /* inflate the coded data */
1078 ml = Zipmask[bl]; /* precompute masks for speed */
1079 md = Zipmask[bd];
1080
1081 for(;;)
1082 {
1084 if((e = (t = tl + (b & ml))->e) > 16)
1085 do
1086 {
1087 if (e == 99)
1088 return 1;
1089 ZIPDUMPBITS(t->b)
1090 e -= 16;
1091 ZIPNEEDBITS(e)
1092 } while ((e = (t = t->v.t + (b & Zipmask[e]))->e) > 16);
1093 ZIPDUMPBITS(t->b)
1094 if (e == 16) /* then it's a literal */
1095 CAB(outbuf)[w++] = (cab_UBYTE)t->v.n;
1096 else /* it's an EOB or a length */
1097 {
1098 /* exit if end of block */
1099 if(e == 15)
1100 break;
1101
1102 /* get length of block to copy */
1103 ZIPNEEDBITS(e)
1104 n = t->v.n + (b & Zipmask[e]);
1105 ZIPDUMPBITS(e);
1106
1107 /* decode distance of block to copy */
1109 if ((e = (t = td + (b & md))->e) > 16)
1110 do {
1111 if (e == 99)
1112 return 1;
1113 ZIPDUMPBITS(t->b)
1114 e -= 16;
1115 ZIPNEEDBITS(e)
1116 } while ((e = (t = t->v.t + (b & Zipmask[e]))->e) > 16);
1117 ZIPDUMPBITS(t->b)
1118 ZIPNEEDBITS(e)
1119 d = w - t->v.n - (b & Zipmask[e]);
1120 ZIPDUMPBITS(e)
1121 do
1122 {
1123 d &= ZIPWSIZE - 1;
1124 e = ZIPWSIZE - max(d, w);
1125 e = min(e, n);
1126 n -= e;
1127 do
1128 {
1129 CAB(outbuf)[w++] = CAB(outbuf)[d++];
1130 } while (--e);
1131 } while (n);
1132 }
1133 }
1134
1135 /* restore the globals from the locals */
1136 ZIP(window_posn) = w; /* restore global window pointer */
1137 ZIP(bb) = b; /* restore global bit buffer */
1138 ZIP(bk) = k;
1139
1140 /* done */
1141 return 0;
1142}
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
do
Definition: dirsup.c:1173
#define md
Definition: compat-1.3.h:2013
#define ZIPWSIZE
Definition: mszip.h:49
#define min(a, b)
Definition: monoChain.cc:55
#define max(a, b)
Definition: svc.c:63
else
Definition: tritemp.h:161

Referenced by fdi_Zipinflate_dynamic(), and fdi_Zipinflate_fixed().

◆ fdi_Zipinflate_dynamic()

static cab_LONG fdi_Zipinflate_dynamic ( fdi_decomp_state decomp_state)
static

Definition at line 1235 of file fdi.c.

1237{
1238 cab_LONG i; /* temporary variables */
1239 cab_ULONG j;
1240 cab_ULONG *ll;
1241 cab_ULONG l; /* last length */
1242 cab_ULONG m; /* mask for bit lengths table */
1243 cab_ULONG n; /* number of lengths to get */
1244 struct Ziphuft *tl; /* literal/length code table */
1245 struct Ziphuft *td; /* distance code table */
1246 cab_LONG bl; /* lookup bits for tl */
1247 cab_LONG bd; /* lookup bits for td */
1248 cab_ULONG nb; /* number of bit length codes */
1249 cab_ULONG nl; /* number of literal/length codes */
1250 cab_ULONG nd; /* number of distance codes */
1251 register cab_ULONG b; /* bit buffer */
1252 register cab_ULONG k; /* number of bits in bit buffer */
1253
1254 /* make local bit buffer */
1255 b = ZIP(bb);
1256 k = ZIP(bk);
1257 ll = ZIP(ll);
1258
1259 /* read in table lengths */
1260 ZIPNEEDBITS(5)
1261 nl = 257 + (b & 0x1f); /* number of literal/length codes */
1262 ZIPDUMPBITS(5)
1263 ZIPNEEDBITS(5)
1264 nd = 1 + (b & 0x1f); /* number of distance codes */
1265 ZIPDUMPBITS(5)
1266 ZIPNEEDBITS(4)
1267 nb = 4 + (b & 0xf); /* number of bit length codes */
1268 ZIPDUMPBITS(4)
1269 if(nl > 288 || nd > 32)
1270 return 1; /* bad lengths */
1271
1272 /* read in bit-length-code lengths */
1273 for(j = 0; j < nb; j++)
1274 {
1275 ZIPNEEDBITS(3)
1276 ll[Zipborder[j]] = b & 7;
1277 ZIPDUMPBITS(3)
1278 }
1279 for(; j < 19; j++)
1280 ll[Zipborder[j]] = 0;
1281
1282 /* build decoding table for trees--single level, 7 bit lookup */
1283 bl = 7;
1284 if((i = fdi_Ziphuft_build(ll, 19, 19, NULL, NULL, &tl, &bl, decomp_state)) != 0)
1285 {
1286 if(i == 1)
1287 fdi_Ziphuft_free(CAB(fdi), tl);
1288 return i; /* incomplete code set */
1289 }
1290
1291 /* read in literal and distance code lengths */
1292 n = nl + nd;
1293 m = Zipmask[bl];
1294 i = l = 0;
1295 while((cab_ULONG)i < n)
1296 {
1298 j = (td = tl + (b & m))->b;
1299 ZIPDUMPBITS(j)
1300 j = td->v.n;
1301 if (j < 16) /* length of code in bits (0..15) */
1302 ll[i++] = l = j; /* save last length in l */
1303 else if (j == 16) /* repeat last length 3 to 6 times */
1304 {
1305 ZIPNEEDBITS(2)
1306 j = 3 + (b & 3);
1307 ZIPDUMPBITS(2)
1308 if((cab_ULONG)i + j > n)
1309 return 1;
1310 while (j--)
1311 ll[i++] = l;
1312 }
1313 else if (j == 17) /* 3 to 10 zero length codes */
1314 {
1315 ZIPNEEDBITS(3)
1316 j = 3 + (b & 7);
1317 ZIPDUMPBITS(3)
1318 if ((cab_ULONG)i + j > n)
1319 return 1;
1320 while (j--)
1321 ll[i++] = 0;
1322 l = 0;
1323 }
1324 else /* j == 18: 11 to 138 zero length codes */
1325 {
1326 ZIPNEEDBITS(7)
1327 j = 11 + (b & 0x7f);
1328 ZIPDUMPBITS(7)
1329 if ((cab_ULONG)i + j > n)
1330 return 1;
1331 while (j--)
1332 ll[i++] = 0;
1333 l = 0;
1334 }
1335 }
1336
1337 /* free decoding table for trees */
1338 fdi_Ziphuft_free(CAB(fdi), tl);
1339
1340 /* restore the global bit buffer */
1341 ZIP(bb) = b;
1342 ZIP(bk) = k;
1343
1344 /* build the decoding tables for literal/length and distance codes */
1345 bl = ZIPLBITS;
1346 if((i = fdi_Ziphuft_build(ll, nl, 257, Zipcplens, Zipcplext, &tl, &bl, decomp_state)) != 0)
1347 {
1348 if(i == 1)
1349 fdi_Ziphuft_free(CAB(fdi), tl);
1350 return i; /* incomplete code set */
1351 }
1352 bd = ZIPDBITS;
1353 fdi_Ziphuft_build(ll + nl, nd, 0, Zipcpdist, Zipcpdext, &td, &bd, decomp_state);
1354
1355 /* decompress until an end-of-block code */
1356 if(fdi_Zipinflate_codes(tl, td, bl, bd, decomp_state))
1357 return 1;
1358
1359 /* free the decoding tables, return */
1360 fdi_Ziphuft_free(CAB(fdi), tl);
1361 fdi_Ziphuft_free(CAB(fdi), td);
1362 return 0;
1363}
w ll
Definition: byte_order.h:167
#define ZIPDBITS
Definition: mszip.h:51
#define ZIPLBITS
Definition: mszip.h:50
static cab_LONG fdi_Ziphuft_build(cab_ULONG *b, cab_ULONG n, cab_ULONG s, const cab_UWORD *d, const cab_UWORD *e, struct Ziphuft **t, cab_LONG *m, fdi_decomp_state *decomp_state)
Definition: fdi.c:880
static cab_LONG fdi_Zipinflate_codes(const struct Ziphuft *tl, const struct Ziphuft *td, cab_LONG bl, cab_LONG bd, fdi_decomp_state *decomp_state)
Definition: fdi.c:1061
#define for
Definition: utility.h:88
cab_UWORD n
Definition: mszip.h:59
union Ziphuft::@253 v

Referenced by fdi_Zipinflate_block().

◆ fdi_Zipinflate_fixed()

static cab_LONG fdi_Zipinflate_fixed ( fdi_decomp_state decomp_state)
static

Definition at line 1191 of file fdi.c.

1192{
1193 struct Ziphuft *fixed_tl;
1194 struct Ziphuft *fixed_td;
1196 cab_LONG i; /* temporary variable */
1197 cab_ULONG *l;
1198
1199 l = ZIP(ll);
1200
1201 /* literal table */
1202 for(i = 0; i < 144; i++)
1203 l[i] = 8;
1204 for(; i < 256; i++)
1205 l[i] = 9;
1206 for(; i < 280; i++)
1207 l[i] = 7;
1208 for(; i < 288; i++) /* make a complete, but wrong code set */
1209 l[i] = 8;
1210 fixed_bl = 7;
1211 if((i = fdi_Ziphuft_build(l, 288, 257, Zipcplens, Zipcplext, &fixed_tl, &fixed_bl, decomp_state)))
1212 return i;
1213
1214 /* distance table */
1215 for(i = 0; i < 30; i++) /* make an incomplete code set */
1216 l[i] = 5;
1217 fixed_bd = 5;
1218 if((i = fdi_Ziphuft_build(l, 30, 0, Zipcpdist, Zipcpdext, &fixed_td, &fixed_bd, decomp_state)) > 1)
1219 {
1221 return i;
1222 }
1223
1224 /* decompress until an end-of-block code */
1226
1229 return i;
1230}
const inflate_huft fixed_tl[]
Definition: inffixed.h:12
const uInt fixed_bd
Definition: inffixed.h:11
const uInt fixed_bl
Definition: inffixed.h:10
const inflate_huft fixed_td[]
Definition: inffixed.h:142

Referenced by fdi_Zipinflate_block().

◆ fdi_Zipinflate_stored()

static cab_LONG fdi_Zipinflate_stored ( fdi_decomp_state decomp_state)
static

Definition at line 1147 of file fdi.c.

1149{
1150 cab_ULONG n; /* number of bytes in block */
1151 cab_ULONG w; /* current window position */
1152 register cab_ULONG b; /* bit buffer */
1153 register cab_ULONG k; /* number of bits in bit buffer */
1154
1155 /* make local copies of globals */
1156 b = ZIP(bb); /* initialize bit buffer */
1157 k = ZIP(bk);
1158 w = ZIP(window_posn); /* initialize window position */
1159
1160 /* go to byte boundary */
1161 n = k & 7;
1162 ZIPDUMPBITS(n);
1163
1164 /* get the length and its complement */
1165 ZIPNEEDBITS(16)
1166 n = (b & 0xffff);
1167 ZIPDUMPBITS(16)
1168 ZIPNEEDBITS(16)
1169 if (n != ((~b) & 0xffff))
1170 return 1; /* error in compressed data */
1171 ZIPDUMPBITS(16)
1172
1173 /* read and output the compressed data */
1174 while(n--)
1175 {
1176 ZIPNEEDBITS(8)
1177 CAB(outbuf)[w++] = (cab_UBYTE)b;
1178 ZIPDUMPBITS(8)
1179 }
1180
1181 /* restore the globals from the locals */
1182 ZIP(window_posn) = w; /* restore global window pointer */
1183 ZIP(bb) = b; /* restore global bit buffer */
1184 ZIP(bk) = k;
1185 return 0;
1186}

Referenced by fdi_Zipinflate_block().

◆ FDICopy()

BOOL __cdecl FDICopy ( HFDI  hfdi,
char pszCabinet,
char pszCabPath,
int  flags,
PFNFDINOTIFY  pfnfdin,
PFNFDIDECRYPT  pfnfdid,
void pvUser 
)

Definition at line 2431 of file fdi.c.

2439{
2440 FDICABINETINFO fdici;
2441 FDINOTIFICATION fdin;
2442 INT_PTR cabhf, filehf = 0;
2443 unsigned int i;
2444 char fullpath[MAX_PATH];
2445 size_t pathlen, filenamelen;
2446 char emptystring = '\0';
2447 cab_UBYTE buf[64];
2448 struct fdi_folder *fol = NULL, *linkfol = NULL;
2449 struct fdi_file *file = NULL, *linkfile = NULL;
2450 fdi_decomp_state *decomp_state;
2451 FDI_Int *fdi = get_fdi_ptr( hfdi );
2452
2453 TRACE("(hfdi == ^%p, pszCabinet == %s, pszCabPath == %s, flags == %x, "
2454 "pfnfdin == ^%p, pfnfdid == ^%p, pvUser == ^%p)\n",
2455 hfdi, debugstr_a(pszCabinet), debugstr_a(pszCabPath), flags, pfnfdin, pfnfdid, pvUser);
2456
2457 if (!fdi) return FALSE;
2458
2459 if (!(decomp_state = fdi->alloc(sizeof(fdi_decomp_state))))
2460 {
2462 return FALSE;
2463 }
2464 ZeroMemory(decomp_state, sizeof(fdi_decomp_state));
2465
2466 pathlen = pszCabPath ? strlen(pszCabPath) : 0;
2467 filenamelen = pszCabinet ? strlen(pszCabinet) : 0;
2468
2469 /* slight overestimation here to save CPU cycles in the developer's brain */
2470 if ((pathlen + filenamelen + 3) > MAX_PATH) {
2471 ERR("MAX_PATH exceeded.\n");
2472 fdi->free(decomp_state);
2474 return FALSE;
2475 }
2476
2477 /* paste the path and filename together */
2478 fullpath[0] = '\0';
2479 if (pathlen)
2480 strcpy(fullpath, pszCabPath);
2481 if (filenamelen)
2482 strcat(fullpath, pszCabinet);
2483
2484 TRACE("full cab path/file name: %s\n", debugstr_a(fullpath));
2485
2486 /* get a handle to the cabfile */
2487 cabhf = fdi->open(fullpath, _O_RDONLY|_O_BINARY, _S_IREAD | _S_IWRITE);
2488 if (cabhf == -1) {
2489 fdi->free(decomp_state);
2492 return FALSE;
2493 }
2494
2495 /* check if it's really a cabfile. Note that this doesn't implement the bug */
2496 if (!FDI_read_entries(fdi, cabhf, &fdici, &(CAB(mii)))) {
2497 WARN("FDI_read_entries failed: %u\n", fdi->perf->erfOper);
2498 fdi->free(decomp_state);
2499 fdi->close(cabhf);
2500 return FALSE;
2501 }
2502
2503 /* cabinet notification */
2504 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2505 fdin.setID = fdici.setID;
2506 fdin.iCabinet = fdici.iCabinet;
2507 fdin.pv = pvUser;
2508 fdin.psz1 = (CAB(mii).nextname) ? CAB(mii).nextname : &emptystring;
2509 fdin.psz2 = (CAB(mii).nextinfo) ? CAB(mii).nextinfo : &emptystring;
2510 fdin.psz3 = pszCabPath;
2511
2512 if (pfnfdin(fdintCABINET_INFO, &fdin) == -1) {
2513 set_error( fdi, FDIERROR_USER_ABORT, 0 );
2514 goto bail_and_fail;
2515 }
2516
2517 CAB(setID) = fdici.setID;
2518 CAB(iCabinet) = fdici.iCabinet;
2519 CAB(cabhf) = cabhf;
2520
2521 /* read folders */
2522 for (i = 0; i < fdici.cFolders; i++) {
2523 if (fdi->read(cabhf, buf, cffold_SIZEOF) != cffold_SIZEOF) {
2525 goto bail_and_fail;
2526 }
2527
2528 if (CAB(mii).folder_resv > 0)
2529 fdi->seek(cabhf, CAB(mii).folder_resv, SEEK_CUR);
2530
2531 fol = fdi->alloc(sizeof(struct fdi_folder));
2532 if (!fol) {
2533 ERR("out of memory!\n");
2535 goto bail_and_fail;
2536 }
2537 ZeroMemory(fol, sizeof(struct fdi_folder));
2538 if (!CAB(firstfol)) CAB(firstfol) = fol;
2539
2543
2544 if (linkfol)
2545 linkfol->next = fol;
2546 linkfol = fol;
2547 }
2548
2549 /* read files */
2550 for (i = 0; i < fdici.cFiles; i++) {
2551 if (fdi->read(cabhf, buf, cffile_SIZEOF) != cffile_SIZEOF) {
2553 goto bail_and_fail;
2554 }
2555
2556 file = fdi->alloc(sizeof(struct fdi_file));
2557 if (!file) {
2558 ERR("out of memory!\n");
2560 goto bail_and_fail;
2561 }
2562 ZeroMemory(file, sizeof(struct fdi_file));
2563 if (!CAB(firstfile)) CAB(firstfile) = file;
2564
2571 file->filename = FDI_read_string(fdi, cabhf, fdici.cbCabinet);
2572
2573 if (!file->filename) {
2575 goto bail_and_fail;
2576 }
2577
2578 if (linkfile)
2579 linkfile->next = file;
2580 linkfile = file;
2581 }
2582
2583 for (file = CAB(firstfile); (file); file = file->next) {
2584
2585 /*
2586 * FIXME: This implementation keeps multiple cabinet files open at once
2587 * when encountering a split cabinet. It is a quirk of this implementation
2588 * that sometimes we decrypt the same block of data more than once, to find
2589 * the right starting point for a file, moving the file-pointer backwards.
2590 * If we kept a cache of certain file-pointer information, we could eliminate
2591 * that behavior... in fact I am not sure that the caching we already have
2592 * is not sufficient.
2593 *
2594 * The current implementation seems to work fine in straightforward situations
2595 * where all the cabinet files needed for decryption are simultaneously
2596 * available. But presumably, the API is supposed to support cabinets which
2597 * are split across multiple CDROMS; we may need to change our implementation
2598 * to strictly serialize its file usage so that it opens only one cabinet
2599 * at a time. Some experimentation with Windows is needed to figure out the
2600 * precise semantics required. The relevant code is here and in fdi_decomp().
2601 */
2602
2603 /* partial-file notification */
2605 /*
2606 * FIXME: Need to create a Cabinet with a single file spanning multiple files
2607 * and perform some tests to figure out the right behavior. The SDK says
2608 * FDICopy will notify the user of the filename and "disk name" (info) of
2609 * the cabinet where the spanning file /started/.
2610 *
2611 * That would certainly be convenient for the API-user, who could abort,
2612 * everything (or parallelize, if that's allowed (it is in wine)), and call
2613 * FDICopy again with the provided filename, so as to avoid partial file
2614 * notification and successfully unpack. This task could be quite unpleasant
2615 * from wine's perspective: the information specifying the "start cabinet" for
2616 * a file is associated nowhere with the file header and is not to be found in
2617 * the cabinet header. We have only the index of the cabinet wherein the folder
2618 * begins, which contains the file. To find that cabinet, we must consider the
2619 * index of the current cabinet, and chain backwards, cabinet-by-cabinet (for
2620 * each cabinet refers to its "next" and "previous" cabinet only, like a linked
2621 * list).
2622 *
2623 * Bear in mind that, in the spirit of CABINET.DLL, we must assume that any
2624 * cabinet other than the active one might be at another filepath than the
2625 * current one, or on another CDROM. This could get rather dicey, especially
2626 * if we imagine parallelized access to the FDICopy API.
2627 *
2628 * The current implementation punts -- it just returns the previous cabinet and
2629 * its info from the header of this cabinet. This provides the right answer in
2630 * 95% of the cases; it's worth checking if Microsoft cuts the same corner before
2631 * we "fix" it.
2632 */
2633 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2634 fdin.pv = pvUser;
2635 fdin.psz1 = (char *)file->filename;
2636 fdin.psz2 = (CAB(mii).prevname) ? CAB(mii).prevname : &emptystring;
2637 fdin.psz3 = (CAB(mii).previnfo) ? CAB(mii).previnfo : &emptystring;
2638
2639 if (pfnfdin(fdintPARTIAL_FILE, &fdin) == -1) {
2640 set_error( fdi, FDIERROR_USER_ABORT, 0 );
2641 goto bail_and_fail;
2642 }
2643 /* I don't think we are supposed to decompress partial files. This prevents it. */
2644 file->oppressed = TRUE;
2645 }
2646 if (file->oppressed) {
2647 filehf = 0;
2648 } else {
2649 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2650 fdin.pv = pvUser;
2651 fdin.psz1 = (char *)file->filename;
2652 fdin.cb = file->length;
2653 fdin.date = file->date;
2654 fdin.time = file->time;
2655 fdin.attribs = file->attribs;
2656 fdin.iFolder = file->index;
2657 if ((filehf = ((*pfnfdin)(fdintCOPY_FILE, &fdin))) == -1) {
2658 set_error( fdi, FDIERROR_USER_ABORT, 0 );
2659 filehf = 0;
2660 goto bail_and_fail;
2661 }
2662 }
2663
2664 /* find the folder for this file if necc. */
2665 if (filehf) {
2666 fol = CAB(firstfol);
2668 /* pick the last folder */
2669 while (fol->next) fol = fol->next;
2670 } else {
2671 unsigned int i2;
2672
2673 for (i2 = 0; (i2 < file->index); i2++)
2674 if (fol->next) /* bug resistance, should always be true */
2675 fol = fol->next;
2676 }
2677 }
2678
2679 if (filehf) {
2680 cab_UWORD comptype = fol->comp_type;
2681 int ct1 = comptype & cffoldCOMPTYPE_MASK;
2682 int ct2 = CAB(current) ? (CAB(current)->comp_type & cffoldCOMPTYPE_MASK) : 0;
2683 int err = 0;
2684
2685 TRACE("Extracting file %s as requested by callee.\n", debugstr_a(file->filename));
2686
2687 /* set up decomp_state */
2688 CAB(fdi) = fdi;
2689 CAB(filehf) = filehf;
2690
2691 /* Was there a change of folder? Compression type? Did we somehow go backwards? */
2692 if ((ct1 != ct2) || (CAB(current) != fol) || (file->offset < CAB(offset))) {
2693
2694 TRACE("Resetting folder for file %s.\n", debugstr_a(file->filename));
2695
2696 /* free stuff for the old decompressor */
2697 switch (ct2) {
2698 case cffoldCOMPTYPE_LZX:
2699 if (LZX(window)) {
2700 fdi->free(LZX(window));
2701 LZX(window) = NULL;
2702 }
2703 break;
2705 if (QTM(window)) {
2706 fdi->free(QTM(window));
2707 QTM(window) = NULL;
2708 }
2709 break;
2710 }
2711
2712 CAB(decomp_cab) = NULL;
2713 CAB(fdi)->seek(CAB(cabhf), fol->offset, SEEK_SET);
2714 CAB(offset) = 0;
2715 CAB(outlen) = 0;
2716
2717 /* initialize the new decompressor */
2718 switch (ct1) {
2720 CAB(decompress) = NONEfdi_decomp;
2721 break;
2723 CAB(decompress) = ZIPfdi_decomp;
2724 break;
2726 CAB(decompress) = QTMfdi_decomp;
2727 err = QTMfdi_init((comptype >> 8) & 0x1f, (comptype >> 4) & 0xF, decomp_state);
2728 break;
2729 case cffoldCOMPTYPE_LZX:
2730 CAB(decompress) = LZXfdi_decomp;
2731 err = LZXfdi_init((comptype >> 8) & 0x1f, decomp_state);
2732 break;
2733 default:
2735 }
2736 }
2737
2738 CAB(current) = fol;
2739
2740 switch (err) {
2741 case DECR_OK:
2742 break;
2743 case DECR_NOMEMORY:
2745 goto bail_and_fail;
2746 default:
2748 goto bail_and_fail;
2749 }
2750
2751 if (file->offset > CAB(offset)) {
2752 /* decode bytes and send them to /dev/null */
2753 switch (fdi_decomp(file, 0, decomp_state, pszCabPath, pfnfdin, pvUser)) {
2754 case DECR_OK:
2755 break;
2756 case DECR_USERABORT:
2757 set_error( fdi, FDIERROR_USER_ABORT, 0 );
2758 goto bail_and_fail;
2759 case DECR_NOMEMORY:
2761 goto bail_and_fail;
2762 default:
2764 goto bail_and_fail;
2765 }
2766 CAB(offset) = file->offset;
2767 }
2768
2769 /* now do the actual decompression */
2770 err = fdi_decomp(file, 1, decomp_state, pszCabPath, pfnfdin, pvUser);
2771 if (err) CAB(current) = NULL; else CAB(offset) += file->length;
2772
2773 /* fdintCLOSE_FILE_INFO notification */
2774 ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
2775 fdin.pv = pvUser;
2776 fdin.psz1 = (char *)file->filename;
2777 fdin.hf = filehf;
2778 fdin.cb = (file->attribs & cffile_A_EXEC) != 0; /* FIXME: is that right? */
2779 fdin.date = file->date;
2780 fdin.time = file->time;
2781 fdin.attribs = file->attribs; /* FIXME: filter _A_EXEC? */
2782 fdin.iFolder = file->index;
2783 ((*pfnfdin)(fdintCLOSE_FILE_INFO, &fdin));
2784 filehf = 0;
2785
2786 switch (err) {
2787 case DECR_OK:
2788 break;
2789 case DECR_USERABORT:
2790 set_error( fdi, FDIERROR_USER_ABORT, 0 );
2791 goto bail_and_fail;
2792 case DECR_NOMEMORY:
2794 goto bail_and_fail;
2795 default:
2797 goto bail_and_fail;
2798 }
2799 }
2800 }
2801
2802 if (fol) free_decompression_temps(fdi, fol, decomp_state);
2803 free_decompression_mem(fdi, decomp_state);
2804
2805 return TRUE;
2806
2807 bail_and_fail: /* here we free ram before error returns */
2808
2809 if (fol) free_decompression_temps(fdi, fol, decomp_state);
2810
2811 if (filehf) fdi->close(filehf);
2812
2813 free_decompression_mem(fdi, decomp_state);
2814
2815 return FALSE;
2816}
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define cffoldCOMPTYPE_MSZIP
Definition: cabinet.h:102
#define cffile_A_EXEC
Definition: cabinet.h:115
#define cffoldCOMPTYPE_LZX
Definition: cabinet.h:104
#define cffoldCOMPTYPE_MASK
Definition: cabinet.h:100
#define cffoldCOMPTYPE_QUANTUM
Definition: cabinet.h:103
#define cffileCONTINUED_TO_NEXT
Definition: cabinet.h:109
#define cffoldCOMPTYPE_NONE
Definition: cabinet.h:101
static int LZXfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state)
Definition: fdi.c:1606
static FDI_Int * get_fdi_ptr(HFDI hfdi)
Definition: fdi.c:195
static int NONEfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state)
Definition: fdi.c:852
static int QTMfdi_init(int window, int level, fdi_decomp_state *decomp_state)
Definition: fdi.c:739
static void free_decompression_temps(FDI_Int *fdi, const struct fdi_folder *fol, fdi_decomp_state *decomp_state)
Definition: fdi.c:2217
static int LZXfdi_init(int window, fdi_decomp_state *decomp_state)
Definition: fdi.c:791
#define LZX(x)
Definition: fdi.c:177
static int ZIPfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state)
Definition: fdi.c:1406
static int QTMfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state)
Definition: fdi.c:1434
#define DECR_DATAFORMAT
Definition: fdi.c:179
static void free_decompression_mem(FDI_Int *fdi, fdi_decomp_state *decomp_state)
Definition: fdi.c:2236
static int fdi_decomp(const struct fdi_file *fi, int savemode, fdi_decomp_state *decomp_state, char *pszCabPath, PFNFDINOTIFY pfnfdin, void *pvUser)
Definition: fdi.c:1938
#define QTM(x)
Definition: fdi.c:176
#define SetLastError(x)
Definition: compat.h:752
@ FDIERROR_USER_ABORT
Definition: fdi.h:126
@ FDIERROR_ALLOC_FAIL
Definition: fdi.h:120
@ fdintCOPY_FILE
Definition: fdi.h:249
@ fdintPARTIAL_FILE
Definition: fdi.h:248
@ fdintCLOSE_FILE_INFO
Definition: fdi.h:250
struct task_struct * current
Definition: linux.c:32
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static IHTMLWindow2 * window
Definition: events.c:77
int erfOper
Definition: fci.h:45
USHORT time
Definition: fdi.h:236
USHORT iFolder
Definition: fdi.h:241
INT_PTR hf
Definition: fdi.h:233
USHORT date
Definition: fdi.h:235
USHORT attribs
Definition: fdi.h:237
LONG cb
Definition: fdi.h:227
Definition: mszip.h:30
PFNOPEN open
Definition: fdi.c:118
PFNCLOSE close
Definition: fdi.c:121
PERF perf
Definition: mszip.h:39
struct fdi_folder * next
Definition: fdi.c:90

Referenced by Extract(), extract_cabinet(), extract_cabinet_stream(), and test_FDICopy().

◆ FDICreate()

HFDI __cdecl FDICreate ( PFNALLOC  pfnalloc,
PFNFREE  pfnfree,
PFNOPEN  pfnopen,
PFNREAD  pfnread,
PFNWRITE  pfnwrite,
PFNCLOSE  pfnclose,
PFNSEEK  pfnseek,
int  cpuType,
PERF  perf 
)

Definition at line 412 of file fdi.c.

422{
423 FDI_Int *fdi;
424
425 TRACE("(pfnalloc == ^%p, pfnfree == ^%p, pfnopen == ^%p, pfnread == ^%p, pfnwrite == ^%p, "
426 "pfnclose == ^%p, pfnseek == ^%p, cpuType == %d, perf == ^%p)\n",
427 pfnalloc, pfnfree, pfnopen, pfnread, pfnwrite, pfnclose, pfnseek,
428 cpuType, perf);
429
430 if ((!pfnalloc) || (!pfnfree)) {
431 perf->erfOper = FDIERROR_NONE;
433 perf->fError = TRUE;
434
436 return NULL;
437 }
438
439 if (!((fdi = pfnalloc(sizeof(FDI_Int))))) {
441 perf->erfType = 0;
442 perf->fError = TRUE;
443 return NULL;
444 }
445
446 fdi->magic = FDI_INT_MAGIC;
447 fdi->alloc = pfnalloc;
448 fdi->free = pfnfree;
449 fdi->open = pfnopen;
450 fdi->read = pfnread;
451 fdi->write = pfnwrite;
452 fdi->close = pfnclose;
453 fdi->seek = pfnseek;
454 /* no-brainer: we ignore the cpu type; this is only used
455 for the 16-bit versions in Windows anyhow... */
456 fdi->perf = perf;
457
458 return (HFDI)fdi;
459}
#define FDI_INT_MAGIC
Definition: fdi.c:126
int erfType
Definition: fci.h:46
BOOL fError
Definition: fci.h:47
PFNWRITE write
Definition: fdi.c:120
unsigned int magic
Definition: fdi.c:115
#define ERROR_BAD_ARGUMENTS
Definition: winerror.h:232

Referenced by Extract(), extract_cabinet(), extract_cabinet_stream(), test_FDICopy(), test_FDICreate(), test_FDIDestroy(), and test_FDIIsCabinet().

◆ FDIDestroy()

BOOL __cdecl FDIDestroy ( HFDI  hfdi)

Definition at line 2831 of file fdi.c.

2832{
2833 FDI_Int *fdi = get_fdi_ptr( hfdi );
2834
2835 TRACE("(hfdi == ^%p)\n", hfdi);
2836 if (!fdi) return FALSE;
2837 fdi->magic = 0; /* paranoia */
2838 fdi->free(fdi);
2839 return TRUE;
2840}

Referenced by Extract(), extract_cabinet(), extract_cabinet_stream(), test_FDICopy(), test_FDICreate(), test_FDIDestroy(), and test_FDIIsCabinet().

◆ FDIIsCabinet()

BOOL __cdecl FDIIsCabinet ( HFDI  hfdi,
INT_PTR  hf,
PFDICABINETINFO  pfdici 
)

Definition at line 696 of file fdi.c.

697{
698 BOOL rv;
699 FDI_Int *fdi = get_fdi_ptr( hfdi );
700
701 TRACE("(hfdi == ^%p, hf == ^%ld, pfdici == ^%p)\n", hfdi, hf, pfdici);
702
703 if (!fdi) return FALSE;
704
705 if (!pfdici) {
707 return FALSE;
708 }
709 rv = FDI_read_entries(fdi, hf, pfdici, NULL);
710
711 if (rv)
712 pfdici->hasnext = FALSE; /* yuck. duplicate apparent cabinet.dll bug */
713
714 return rv;
715}

Referenced by test_FDICopy(), and test_FDIIsCabinet().

◆ FDITruncateCabinet()

BOOL __cdecl FDITruncateCabinet ( HFDI  hfdi,
char pszCabinetName,
USHORT  iFolderToDelete 
)

Definition at line 2861 of file fdi.c.

2865{
2866 FDI_Int *fdi = get_fdi_ptr( hfdi );
2867
2868 FIXME("(hfdi == ^%p, pszCabinetName == %s, iFolderToDelete == %hu): stub\n",
2869 hfdi, debugstr_a(pszCabinetName), iFolderToDelete);
2870
2871 if (!fdi) return FALSE;
2872
2874 return FALSE;
2875}
#define FIXME(fmt,...)
Definition: debug.h:111
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102

◆ free_decompression_mem()

static void free_decompression_mem ( FDI_Int fdi,
fdi_decomp_state decomp_state 
)
static

Definition at line 2236 of file fdi.c.

2237{
2238 struct fdi_folder *fol;
2239 while (decomp_state) {
2240 fdi_decomp_state *prev_fds;
2241
2242 fdi->close(CAB(cabhf));
2243
2244 /* free the storage remembered by mii */
2245 if (CAB(mii).nextname) fdi->free(CAB(mii).nextname);
2246 if (CAB(mii).nextinfo) fdi->free(CAB(mii).nextinfo);
2247 if (CAB(mii).prevname) fdi->free(CAB(mii).prevname);
2248 if (CAB(mii).previnfo) fdi->free(CAB(mii).previnfo);
2249
2250 while (CAB(firstfol)) {
2251 fol = CAB(firstfol);
2252 CAB(firstfol) = CAB(firstfol)->next;
2253 fdi->free(fol);
2254 }
2255 while (CAB(firstfile)) {
2256 struct fdi_file *file = CAB(firstfile);
2257 if (file->filename) fdi->free(file->filename);
2258 CAB(firstfile) = CAB(firstfile)->next;
2259 fdi->free(file);
2260 }
2261 prev_fds = decomp_state;
2262 decomp_state = CAB(next);
2263 fdi->free(prev_fds);
2264 }
2265}
static unsigned __int64 next
Definition: rand_nt.c:6

Referenced by FDICopy().

◆ free_decompression_temps()

static void free_decompression_temps ( FDI_Int fdi,
const struct fdi_folder fol,
fdi_decomp_state decomp_state 
)
static

Definition at line 2217 of file fdi.c.

2219{
2220 switch (fol->comp_type & cffoldCOMPTYPE_MASK) {
2221 case cffoldCOMPTYPE_LZX:
2222 if (LZX(window)) {
2223 fdi->free(LZX(window));
2224 LZX(window) = NULL;
2225 }
2226 break;
2228 if (QTM(window)) {
2229 fdi->free(QTM(window));
2230 QTM(window) = NULL;
2231 }
2232 break;
2233 }
2234}

Referenced by FDICopy().

◆ get_fdi_ptr()

static FDI_Int * get_fdi_ptr ( HFDI  hfdi)
static

Definition at line 195 of file fdi.c.

196{
197 FDI_Int *fdi= (FDI_Int *)hfdi;
198
199 if (!fdi || fdi->magic != FDI_INT_MAGIC)
200 {
202 return NULL;
203 }
204 return fdi;
205}
#define ERROR_INVALID_HANDLE
Definition: compat.h:98

Referenced by FDICopy(), FDIDestroy(), FDIIsCabinet(), and FDITruncateCabinet().

◆ LZXfdi_decomp()

static int LZXfdi_decomp ( int  inlen,
int  outlen,
fdi_decomp_state decomp_state 
)
static

Definition at line 1606 of file fdi.c.

1606 {
1607 cab_UBYTE *inpos = CAB(inbuf);
1608 const cab_UBYTE *endinp = inpos + inlen;
1610 cab_UBYTE *runsrc, *rundest;
1611 cab_UWORD *hufftbl; /* used in READ_HUFFSYM macro as chosen decoding table */
1612
1613 cab_ULONG window_posn = LZX(window_posn);
1614 cab_ULONG window_size = LZX(window_size);
1615 cab_ULONG R0 = LZX(R0);
1616 cab_ULONG R1 = LZX(R1);
1617 cab_ULONG R2 = LZX(R2);
1618
1619 register cab_ULONG bitbuf;
1620 register int bitsleft;
1621 cab_ULONG match_offset, i,j,k; /* ijk used in READ_HUFFSYM macro */
1622 struct lzx_bits lb; /* used in READ_LENGTHS macro */
1623
1624 int togo = outlen, this_run, main_element, aligned_bits;
1625 int match_length, copy_length, length_footer, extra, verbatim_bits;
1626
1627 TRACE("(inlen == %d, outlen == %d)\n", inlen, outlen);
1628
1630
1631 /* read header if necessary */
1632 if (!LZX(header_read)) {
1633 i = j = 0;
1634 READ_BITS(k, 1); if (k) { READ_BITS(i,16); READ_BITS(j,16); }
1635 LZX(intel_filesize) = (i << 16) | j; /* or 0 if not encoded */
1636 LZX(header_read) = 1;
1637 }
1638
1639 /* main decoding loop */
1640 while (togo > 0) {
1641 /* last block finished, new block expected */
1642 if (LZX(block_remaining) == 0) {
1643 if (LZX(block_type) == LZX_BLOCKTYPE_UNCOMPRESSED) {
1644 if (LZX(block_length) & 1) inpos++; /* realign bitstream to word */
1646 }
1647
1648 READ_BITS(LZX(block_type), 3);
1649 READ_BITS(i, 16);
1650 READ_BITS(j, 8);
1651 LZX(block_remaining) = LZX(block_length) = (i << 8) | j;
1652
1653 switch (LZX(block_type)) {
1655 for (i = 0; i < 8; i++) { READ_BITS(j, 3); LENTABLE(ALIGNED)[i] = j; }
1657 /* rest of aligned header is same as verbatim */
1658
1660 READ_LENGTHS(MAINTREE, 0, 256, fdi_lzx_read_lens);
1661 READ_LENGTHS(MAINTREE, 256, LZX(main_elements), fdi_lzx_read_lens);
1662 BUILD_TABLE(MAINTREE);
1663 if (LENTABLE(MAINTREE)[0xE8] != 0) LZX(intel_started) = 1;
1664
1667 break;
1668
1670 LZX(intel_started) = 1; /* because we can't assume otherwise */
1671 ENSURE_BITS(16); /* get up to 16 pad bits into the buffer */
1672 if (bitsleft > 16) inpos -= 2; /* and align the bitstream! */
1673 R0 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
1674 R1 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
1675 R2 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
1676 break;
1677
1678 default:
1679 return DECR_ILLEGALDATA;
1680 }
1681 }
1682
1683 /* buffer exhaustion check */
1684 if (inpos > endinp) {
1685 /* it's possible to have a file where the next run is less than
1686 * 16 bits in size. In this case, the READ_HUFFSYM() macro used
1687 * in building the tables will exhaust the buffer, so we should
1688 * allow for this, but not allow those accidentally read bits to
1689 * be used (so we check that there are at least 16 bits
1690 * remaining - in this boundary case they aren't really part of
1691 * the compressed data)
1692 */
1693 if (inpos > (endinp+2) || bitsleft < 16) return DECR_ILLEGALDATA;
1694 }
1695
1696 while ((this_run = LZX(block_remaining)) > 0 && togo > 0) {
1697 if (this_run > togo) this_run = togo;
1698 togo -= this_run;
1699 LZX(block_remaining) -= this_run;
1700
1701 /* apply 2^x-1 mask */
1702 window_posn &= window_size - 1;
1703 /* runs can't straddle the window wraparound */
1704 if ((window_posn + this_run) > window_size)
1705 return DECR_DATAFORMAT;
1706
1707 switch (LZX(block_type)) {
1708
1710 while (this_run > 0) {
1711 READ_HUFFSYM(MAINTREE, main_element);
1712
1713 if (main_element < LZX_NUM_CHARS) {
1714 /* literal: 0 to LZX_NUM_CHARS-1 */
1715 window[window_posn++] = main_element;
1716 this_run--;
1717 }
1718 else {
1719 /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
1720 main_element -= LZX_NUM_CHARS;
1721
1722 match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
1723 if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
1724 READ_HUFFSYM(LENGTH, length_footer);
1725 match_length += length_footer;
1726 }
1727 match_length += LZX_MIN_MATCH;
1728
1729 match_offset = main_element >> 3;
1730
1731 if (match_offset > 2) {
1732 /* not repeated offset */
1733 if (match_offset != 3) {
1734 extra = CAB(extra_bits)[match_offset];
1735 READ_BITS(verbatim_bits, extra);
1736 match_offset = CAB(lzx_position_base)[match_offset]
1737 - 2 + verbatim_bits;
1738 }
1739 else {
1740 match_offset = 1;
1741 }
1742
1743 /* update repeated offset LRU queue */
1744 R2 = R1; R1 = R0; R0 = match_offset;
1745 }
1746 else if (match_offset == 0) {
1747 match_offset = R0;
1748 }
1749 else if (match_offset == 1) {
1750 match_offset = R1;
1751 R1 = R0; R0 = match_offset;
1752 }
1753 else /* match_offset == 2 */ {
1754 match_offset = R2;
1755 R2 = R0; R0 = match_offset;
1756 }
1757
1758 rundest = window + window_posn;
1759 this_run -= match_length;
1760
1761 /* copy any wrapped around source data */
1762 if (window_posn >= match_offset) {
1763 /* no wrap */
1764 runsrc = rundest - match_offset;
1765 } else {
1766 runsrc = rundest + (window_size - match_offset);
1767 copy_length = match_offset - window_posn;
1768 if (copy_length < match_length) {
1769 match_length -= copy_length;
1770 window_posn += copy_length;
1771 while (copy_length-- > 0) *rundest++ = *runsrc++;
1772 runsrc = window;
1773 }
1774 }
1775 window_posn += match_length;
1776
1777 /* copy match data - no worries about destination wraps */
1778 while (match_length-- > 0) *rundest++ = *runsrc++;
1779 }
1780 }
1781 break;
1782
1784 while (this_run > 0) {
1785 READ_HUFFSYM(MAINTREE, main_element);
1786
1787 if (main_element < LZX_NUM_CHARS) {
1788 /* literal: 0 to LZX_NUM_CHARS-1 */
1789 window[window_posn++] = main_element;
1790 this_run--;
1791 }
1792 else {
1793 /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
1794 main_element -= LZX_NUM_CHARS;
1795
1796 match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
1797 if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
1798 READ_HUFFSYM(LENGTH, length_footer);
1799 match_length += length_footer;
1800 }
1801 match_length += LZX_MIN_MATCH;
1802
1803 match_offset = main_element >> 3;
1804
1805 if (match_offset > 2) {
1806 /* not repeated offset */
1807 extra = CAB(extra_bits)[match_offset];
1808 match_offset = CAB(lzx_position_base)[match_offset] - 2;
1809 if (extra > 3) {
1810 /* verbatim and aligned bits */
1811 extra -= 3;
1812 READ_BITS(verbatim_bits, extra);
1813 match_offset += (verbatim_bits << 3);
1814 READ_HUFFSYM(ALIGNED, aligned_bits);
1815 match_offset += aligned_bits;
1816 }
1817 else if (extra == 3) {
1818 /* aligned bits only */
1819 READ_HUFFSYM(ALIGNED, aligned_bits);
1820 match_offset += aligned_bits;
1821 }
1822 else if (extra > 0) { /* extra==1, extra==2 */
1823 /* verbatim bits only */
1824 READ_BITS(verbatim_bits, extra);
1825 match_offset += verbatim_bits;
1826 }
1827 else /* extra == 0 */ {
1828 /* ??? */
1829 match_offset = 1;
1830 }
1831
1832 /* update repeated offset LRU queue */
1833 R2 = R1; R1 = R0; R0 = match_offset;
1834 }
1835 else if (match_offset == 0) {
1836 match_offset = R0;
1837 }
1838 else if (match_offset == 1) {
1839 match_offset = R1;
1840 R1 = R0; R0 = match_offset;
1841 }
1842 else /* match_offset == 2 */ {
1843 match_offset = R2;
1844 R2 = R0; R0 = match_offset;
1845 }
1846
1847 rundest = window + window_posn;
1848 this_run -= match_length;
1849
1850 /* copy any wrapped around source data */
1851 if (window_posn >= match_offset) {
1852 /* no wrap */
1853 runsrc = rundest - match_offset;
1854 } else {
1855 runsrc = rundest + (window_size - match_offset);
1856 copy_length = match_offset - window_posn;
1857 if (copy_length < match_length) {
1858 match_length -= copy_length;
1859 window_posn += copy_length;
1860 while (copy_length-- > 0) *rundest++ = *runsrc++;
1861 runsrc = window;
1862 }
1863 }
1864 window_posn += match_length;
1865
1866 /* copy match data - no worries about destination wraps */
1867 while (match_length-- > 0) *rundest++ = *runsrc++;
1868 }
1869 }
1870 break;
1871
1873 if ((inpos + this_run) > endinp) return DECR_ILLEGALDATA;
1874 memcpy(window + window_posn, inpos, (size_t) this_run);
1875 inpos += this_run; window_posn += this_run;
1876 break;
1877
1878 default:
1879 return DECR_ILLEGALDATA; /* might as well */
1880 }
1881
1882 }
1883 }
1884
1885 if (togo != 0) return DECR_ILLEGALDATA;
1886 memcpy(CAB(outbuf), window + ((!window_posn) ? window_size : window_posn) -
1887 outlen, (size_t) outlen);
1888
1889 LZX(window_posn) = window_posn;
1890 LZX(R0) = R0;
1891 LZX(R1) = R1;
1892 LZX(R2) = R2;
1893
1894 /* intel E8 decoding */
1895 if ((LZX(frames_read)++ < 32768) && LZX(intel_filesize) != 0) {
1896 if (outlen <= 6 || !LZX(intel_started)) {
1897 LZX(intel_curpos) += outlen;
1898 }
1899 else {
1900 cab_UBYTE *data = CAB(outbuf);
1901 cab_UBYTE *dataend = data + outlen - 10;
1902 cab_LONG curpos = LZX(intel_curpos);
1903 cab_LONG filesize = LZX(intel_filesize);
1904 cab_LONG abs_off, rel_off;
1905
1906 LZX(intel_curpos) = curpos + outlen;
1907
1908 while (data < dataend) {
1909 if (*data++ != 0xE8) { curpos++; continue; }
1910 abs_off = data[0] | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);
1911 if ((abs_off >= -curpos) && (abs_off < filesize)) {
1912 rel_off = (abs_off >= 0) ? abs_off - curpos : abs_off + filesize;
1913 data[0] = (cab_UBYTE) rel_off;
1914 data[1] = (cab_UBYTE) (rel_off >> 8);
1915 data[2] = (cab_UBYTE) (rel_off >> 16);
1916 data[3] = (cab_UBYTE) (rel_off >> 24);
1917 }
1918 data += 4;
1919 curpos += 5;
1920 }
1921 }
1922 }
1923 return DECR_OK;
1924}
#define LZX_NUM_CHARS
Definition: cabinet.h:186
#define READ_LENGTHS(tbl, first, last, fn)
Definition: cabinet.h:475
#define LZX_BLOCKTYPE_ALIGNED
Definition: cabinet.h:189
#define LZX_NUM_SECONDARY_LENGTHS
Definition: cabinet.h:194
#define LZX_BLOCKTYPE_VERBATIM
Definition: cabinet.h:188
#define LZX_NUM_PRIMARY_LENGTHS
Definition: cabinet.h:193
#define LZX_BLOCKTYPE_UNCOMPRESSED
Definition: cabinet.h:190
#define INIT_BITSTREAM
Definition: cabinet.h:414
#define LZX_MIN_MATCH
Definition: cabinet.h:184
#define ENSURE_BITS(n)
Definition: cabinet.h:417
static int fdi_lzx_read_lens(cab_UBYTE *lens, cab_ULONG first, cab_ULONG last, struct lzx_bits *lb, fdi_decomp_state *decomp_state)
Definition: fdi.c:1559
@ LENGTH
Definition: inflate.c:185
@ extra
Definition: id3.c:95
static const UBYTE extra_bits[51]
Definition: lzx.c:158
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ALIGNED(a)
Definition: optimize.h:190
#define R1(v, w, x, y, z, i)
Definition: sha1.c:36
#define R2(v, w, x, y, z, i)
Definition: sha1.c:37
#define R0(v, w, x, y, z, i)
Definition: sha1.c:35

Referenced by FDICopy().

◆ LZXfdi_init()

static int LZXfdi_init ( int  window,
fdi_decomp_state decomp_state 
)
static

Definition at line 791 of file fdi.c.

791 {
792 static const cab_UBYTE bits[] =
793 { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
794 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14,
795 15, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
796 17, 17, 17};
797 static const cab_ULONG base[] =
798 { 0, 1, 2, 3, 4, 6, 8, 12,
799 16, 24, 32, 48, 64, 96, 128, 192,
800 256, 384, 512, 768, 1024, 1536, 2048, 3072,
801 4096, 6144, 8192, 12288, 16384, 24576, 32768, 49152,
802 65536, 98304, 131072, 196608, 262144, 393216, 524288, 655360,
803 786432, 917504, 1048576, 1179648, 1310720, 1441792, 1572864, 1703936,
804 1835008, 1966080, 2097152};
805 cab_ULONG wndsize = 1 << window;
806 int posn_slots;
807
808 /* LZX supports window sizes of 2^15 (32Kb) through 2^21 (2Mb) */
809 /* if a previously allocated window is big enough, keep it */
810 if (window < 15 || window > 21) return DECR_DATAFORMAT;
811 if (LZX(actual_size) < wndsize) {
812 if (LZX(window)) CAB(fdi)->free(LZX(window));
813 LZX(window) = NULL;
814 }
815 if (!LZX(window)) {
816 if (!(LZX(window) = CAB(fdi)->alloc(wndsize))) return DECR_NOMEMORY;
817 LZX(actual_size) = wndsize;
818 }
819 LZX(window_size) = wndsize;
820
821 /* initialize static tables */
822 memcpy(CAB(extra_bits), bits, sizeof(bits));
823 memcpy(CAB(lzx_position_base), base, sizeof(base));
824
825 /* calculate required position slots */
826 if (window == 20) posn_slots = 42;
827 else if (window == 21) posn_slots = 50;
828 else posn_slots = window << 1;
829
830 /*posn_slots=i=0; while (i < wndsize) i += 1 << CAB(extra_bits)[posn_slots++]; */
831
832 LZX(R0) = LZX(R1) = LZX(R2) = 1;
833 LZX(main_elements) = LZX_NUM_CHARS + (posn_slots << 3);
834 LZX(header_read) = 0;
835 LZX(frames_read) = 0;
836 LZX(block_remaining) = 0;
837 LZX(block_type) = LZX_BLOCKTYPE_INVALID;
838 LZX(intel_curpos) = 0;
839 LZX(intel_started) = 0;
840 LZX(window_posn) = 0;
841
842 /* initialize tables to 0 (because deltas will be applied to them) */
843 memset(LZX(MAINTREE_len), 0, sizeof(LZX(MAINTREE_len)));
844 memset(LZX(LENGTH_len), 0, sizeof(LZX(LENGTH_len)));
845
846 return DECR_OK;
847}
#define LZX_BLOCKTYPE_INVALID
Definition: cabinet.h:187
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:10929
#define memset(x, y, z)
Definition: compat.h:39

Referenced by FDICopy().

◆ make_decode_table()

static int make_decode_table ( cab_ULONG  nsyms,
cab_ULONG  nbits,
const cab_UBYTE length,
cab_UWORD table 
)
static

Definition at line 279 of file fdi.c.

280 {
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 */
289
290 /* fill entries for codes short enough for a direct mapping */
291 while (bit_num <= nbits) {
292 for (sym = 0; sym < nsyms; sym++) {
293 if (length[sym] == bit_num) {
294 leaf = pos;
295
296 if((pos += bit_mask) > table_mask) return 1; /* table overrun */
297
298 /* fill all possible lookups of this symbol with the symbol itself */
299 fill = bit_mask;
300 while (fill-- > 0) table[leaf++] = sym;
301 }
302 }
303 bit_mask >>= 1;
304 bit_num++;
305 }
306
307 /* if there are any codes longer than nbits */
308 if (pos != table_mask) {
309 /* clear the remainder of the table */
310 for (sym = pos; sym < table_mask; sym++) table[sym] = 0;
311
312 /* give ourselves room for codes to grow by up to 16 more bits */
313 pos <<= 16;
314 table_mask <<= 16;
315 bit_mask = 1 << 15;
316
317 while (bit_num <= 16) {
318 for (sym = 0; sym < nsyms; sym++) {
319 if (length[sym] == bit_num) {
320 leaf = pos >> 16;
321 for (fill = 0; fill < bit_num - nbits; fill++) {
322 /* if this path hasn't been taken yet, 'allocate' two entries */
323 if (table[leaf] == 0) {
324 table[(next_symbol << 1)] = 0;
325 table[(next_symbol << 1) + 1] = 0;
326 table[leaf] = next_symbol++;
327 }
328 /* follow the path and select either left or right for next bit */
329 leaf = table[leaf] << 1;
330 if ((pos >> (15-fill)) & 1) leaf++;
331 }
332 table[leaf] = sym;
333
334 if ((pos += bit_mask) > table_mask) return 1; /* table overflow */
335 }
336 }
337 bit_mask >>= 1;
338 bit_num++;
339 }
340 }
341
342 /* full table? */
343 if (pos == table_mask) return 0;
344
345 /* either erroneous table, or all elements are 0 - let's find out. */
346 for (sym = 0; sym < nsyms; sym++) if (length[sym]) return 1;
347 return 0;
348}
_STLP_MOVE_TO_STD_NAMESPACE void fill(_ForwardIter __first, _ForwardIter __last, const _Tp &__val)
Definition: _algobase.h:449
GLuint GLsizei GLsizei * length
Definition: glext.h:6040

◆ NONEfdi_decomp()

static int NONEfdi_decomp ( int  inlen,
int  outlen,
fdi_decomp_state decomp_state 
)
static

Definition at line 852 of file fdi.c.

853{
854 if (inlen != outlen) return DECR_ILLEGALDATA;
855 if (outlen > CAB_BLOCKMAX) return DECR_DATAFORMAT;
856 memcpy(CAB(outbuf), CAB(inbuf), (size_t) inlen);
857 return DECR_OK;
858}
#define CAB_BLOCKMAX
Definition: mszip.h:97

Referenced by FDICopy().

◆ QTMfdi_decomp()

static int QTMfdi_decomp ( int  inlen,
int  outlen,
fdi_decomp_state decomp_state 
)
static

Definition at line 1434 of file fdi.c.

1435{
1436 cab_UBYTE *inpos = CAB(inbuf);
1438 cab_UBYTE *runsrc, *rundest;
1439 cab_ULONG window_posn = QTM(window_posn);
1440 cab_ULONG window_size = QTM(window_size);
1441
1442 /* used by bitstream macros */
1443 register int bitsleft, bitrun, bitsneed;
1444 register cab_ULONG bitbuf;
1445
1446 /* used by GET_SYMBOL */
1448 cab_UWORD symf;
1449 int i;
1450
1451 int extra, togo = outlen, match_length = 0, copy_length;
1452 cab_UBYTE selector, sym;
1453 cab_ULONG match_offset = 0;
1454
1455 cab_UWORD H = 0xFFFF, L = 0, C;
1456
1457 TRACE("(inlen == %d, outlen == %d)\n", inlen, outlen);
1458
1459 /* read initial value of C */
1461 Q_READ_BITS(C, 16);
1462
1463 /* apply 2^x-1 mask */
1464 window_posn &= window_size - 1;
1465 /* runs can't straddle the window wraparound */
1466 if ((window_posn + togo) > window_size) {
1467 TRACE("straddled run\n");
1468 return DECR_DATAFORMAT;
1469 }
1470
1471 while (togo > 0) {
1472 GET_SYMBOL(model7, selector);
1473 switch (selector) {
1474 case 0:
1475 GET_SYMBOL(model00, sym); window[window_posn++] = sym; togo--;
1476 break;
1477 case 1:
1478 GET_SYMBOL(model40, sym); window[window_posn++] = sym; togo--;
1479 break;
1480 case 2:
1481 GET_SYMBOL(model80, sym); window[window_posn++] = sym; togo--;
1482 break;
1483 case 3:
1484 GET_SYMBOL(modelC0, sym); window[window_posn++] = sym; togo--;
1485 break;
1486
1487 case 4:
1488 /* selector 4 = fixed length of 3 */
1489 GET_SYMBOL(model4, sym);
1490 Q_READ_BITS(extra, CAB(q_extra_bits)[sym]);
1491 match_offset = CAB(q_position_base)[sym] + extra + 1;
1492 match_length = 3;
1493 break;
1494
1495 case 5:
1496 /* selector 5 = fixed length of 4 */
1497 GET_SYMBOL(model5, sym);
1498 Q_READ_BITS(extra, CAB(q_extra_bits)[sym]);
1499 match_offset = CAB(q_position_base)[sym] + extra + 1;
1500 match_length = 4;
1501 break;
1502
1503 case 6:
1504 /* selector 6 = variable length */
1505 GET_SYMBOL(model6len, sym);
1506 Q_READ_BITS(extra, CAB(q_length_extra)[sym]);
1507 match_length = CAB(q_length_base)[sym] + extra + 5;
1508 GET_SYMBOL(model6pos, sym);
1509 Q_READ_BITS(extra, CAB(q_extra_bits)[sym]);
1510 match_offset = CAB(q_position_base)[sym] + extra + 1;
1511 break;
1512
1513 default:
1514 TRACE("Selector is bogus\n");
1515 return DECR_ILLEGALDATA;
1516 }
1517
1518 /* if this is a match */
1519 if (selector >= 4) {
1520 rundest = window + window_posn;
1521 togo -= match_length;
1522
1523 /* copy any wrapped around source data */
1524 if (window_posn >= match_offset) {
1525 /* no wrap */
1526 runsrc = rundest - match_offset;
1527 } else {
1528 runsrc = rundest + (window_size - match_offset);
1529 copy_length = match_offset - window_posn;
1530 if (copy_length < match_length) {
1531 match_length -= copy_length;
1532 window_posn += copy_length;
1533 while (copy_length-- > 0) *rundest++ = *runsrc++;
1534 runsrc = window;
1535 }
1536 }
1537 window_posn += match_length;
1538
1539 /* copy match data - no worries about destination wraps */
1540 while (match_length-- > 0) *rundest++ = *runsrc++;
1541 }
1542 } /* while (togo > 0) */
1543
1544 if (togo != 0) {
1545 TRACE("Frame overflow, this_run = %d\n", togo);
1546 return DECR_ILLEGALDATA;
1547 }
1548
1549 memcpy(CAB(outbuf), window + ((!window_posn) ? window_size : window_posn) -
1550 outlen, outlen);
1551
1552 QTM(window_posn) = window_posn;
1553 return DECR_OK;
1554}
#define C(c)
Definition: builtin.c:4556
Definition: terminate.cpp:24
#define GET_SYMBOL(m, var)
Definition: cabinet.h:367
#define Q_READ_BITS(v, n)
Definition: cabinet.h:350
#define Q_INIT_BITSTREAM
Definition: cabinet.h:338
GLenum GLint * range
Definition: glext.h:7539
#define H
#define L(x)
Definition: ntvdm.h:50

Referenced by FDICopy().

◆ QTMfdi_init()

static int QTMfdi_init ( int  window,
int  level,
fdi_decomp_state decomp_state 
)
static

Definition at line 739 of file fdi.c.

739 {
740 unsigned int wndsize = 1 << window;
741 int msz = window * 2, i;
742 cab_ULONG j;
743
744 /* QTM supports window sizes of 2^10 (1Kb) through 2^21 (2Mb) */
745 /* if a previously allocated window is big enough, keep it */
746 if (window < 10 || window > 21) return DECR_DATAFORMAT;
747 if (QTM(actual_size) < wndsize) {
748 if (QTM(window)) CAB(fdi)->free(QTM(window));
749 QTM(window) = NULL;
750 }
751 if (!QTM(window)) {
752 if (!(QTM(window) = CAB(fdi)->alloc(wndsize))) return DECR_NOMEMORY;
753 QTM(actual_size) = wndsize;
754 }
755 QTM(window_size) = wndsize;
756 QTM(window_posn) = 0;
757
758 /* initialize static slot/extrabits tables */
759 for (i = 0, j = 0; i < 27; i++) {
760 CAB(q_length_extra)[i] = (i == 26) ? 0 : (i < 2 ? 0 : i - 2) >> 2;
761 CAB(q_length_base)[i] = j; j += 1 << ((i == 26) ? 5 : CAB(q_length_extra)[i]);
762 }
763 for (i = 0, j = 0; i < 42; i++) {
764 CAB(q_extra_bits)[i] = (i < 2 ? 0 : i-2) >> 1;
765 CAB(q_position_base)[i] = j; j += 1 << CAB(q_extra_bits)[i];
766 }
767
768 /* initialize arithmetic coding models */
769
770 QTMfdi_initmodel(&QTM(model7), QTM(m7sym), 7, 0);
771
772 QTMfdi_initmodel(&QTM(model00), QTM(m00sym), 0x40, 0x00);
773 QTMfdi_initmodel(&QTM(model40), QTM(m40sym), 0x40, 0x40);
774 QTMfdi_initmodel(&QTM(model80), QTM(m80sym), 0x40, 0x80);
775 QTMfdi_initmodel(&QTM(modelC0), QTM(mC0sym), 0x40, 0xC0);
776
777 /* model 4 depends on table size, ranges from 20 to 24 */
778 QTMfdi_initmodel(&QTM(model4), QTM(m4sym), (msz < 24) ? msz : 24, 0);
779 /* model 5 depends on table size, ranges from 20 to 36 */
780 QTMfdi_initmodel(&QTM(model5), QTM(m5sym), (msz < 36) ? msz : 36, 0);
781 /* model 6pos depends on table size, ranges from 20 to 42 */
782 QTMfdi_initmodel(&QTM(model6pos), QTM(m6psym), msz, 0);
783 QTMfdi_initmodel(&QTM(model6len), QTM(m6lsym), 27, 0);
784
785 return DECR_OK;
786}
static void QTMfdi_initmodel(struct QTMmodel *m, struct QTMmodelsym *sym, int n, int s)
Definition: fdi.c:722

Referenced by FDICopy().

◆ QTMfdi_initmodel()

static void QTMfdi_initmodel ( struct QTMmodel m,
struct QTMmodelsym sym,
int  n,
int  s 
)
static

Definition at line 722 of file fdi.c.

722 {
723 int i;
724 m->shiftsleft = 4;
725 m->entries = n;
726 m->syms = sym;
727 memset(m->tabloc, 0xFF, sizeof(m->tabloc)); /* clear out look-up table */
728 for (i = 0; i < n; i++) {
729 m->tabloc[i+s] = i; /* set up a look-up entry for symbol */
730 m->syms[i].sym = i+s; /* actual symbol */
731 m->syms[i].cumfreq = n-i; /* current frequency of that symbol */
732 }
733 m->syms[n].cumfreq = 0;
734}

Referenced by QTMfdi_init().

◆ QTMupdatemodel()

static void QTMupdatemodel ( struct QTMmodel model,
int  sym 
)
static

Definition at line 210 of file fdi.c.

210 {
211 struct QTMmodelsym temp;
212 int i, j;
213
214 for (i = 0; i < sym; i++) model->syms[i].cumfreq += 8;
215
216 if (model->syms[0].cumfreq > 3800) {
217 if (--model->shiftsleft) {
218 for (i = model->entries - 1; i >= 0; i--) {
219 /* -1, not -2; the 0 entry saves this */
220 model->syms[i].cumfreq >>= 1;
221 if (model->syms[i].cumfreq <= model->syms[i+1].cumfreq) {
222 model->syms[i].cumfreq = model->syms[i+1].cumfreq + 1;
223 }
224 }
225 }
226 else {
227 model->shiftsleft = 50;
228 for (i = 0; i < model->entries ; i++) {
229 /* no -1, want to include the 0 entry */
230 /* this converts cumfreqs into frequencies, then shifts right */
231 model->syms[i].cumfreq -= model->syms[i+1].cumfreq;
232 model->syms[i].cumfreq++; /* avoid losing things entirely */
233 model->syms[i].cumfreq >>= 1;
234 }
235
236 /* now sort by frequencies, decreasing order -- this must be an
237 * inplace selection sort, or a sort with the same (in)stability
238 * characteristics
239 */
240 for (i = 0; i < model->entries - 1; i++) {
241 for (j = i + 1; j < model->entries; j++) {
242 if (model->syms[i].cumfreq < model->syms[j].cumfreq) {
243 temp = model->syms[i];
244 model->syms[i] = model->syms[j];
245 model->syms[j] = temp;
246 }
247 }
248 }
249
250 /* then convert frequencies back to cumfreq */
251 for (i = model->entries - 1; i >= 0; i--) {
252 model->syms[i].cumfreq += model->syms[i+1].cumfreq;
253 }
254 /* then update the other part of the table */
255 for (i = 0; i < model->entries; i++) {
256 model->tabloc[model->syms[i].sym] = i;
257 }
258 }
259 }
260}
static calc_node_t temp
Definition: rpn_ieee.c:38
int shiftsleft
Definition: cabinet.h:157
int entries
Definition: cabinet.h:157
struct QTMmodelsym * syms
Definition: cabinet.h:158
cab_UWORD tabloc[256]
Definition: cabinet.h:159
cab_UWORD sym
Definition: cabinet.h:153

◆ set_error()

static void set_error ( FDI_Int fdi,
int  oper,
int  err 
)
static

Definition at line 187 of file fdi.c.

188{
189 fdi->perf->erfOper = oper;
190 fdi->perf->erfType = err;
191 fdi->perf->fError = TRUE;
192 if (err) SetLastError( err );
193}

Referenced by FDI_read_entries(), and FDICopy().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( cabinet  )

◆ ZIPfdi_decomp()

static int ZIPfdi_decomp ( int  inlen,
int  outlen,
fdi_decomp_state decomp_state 
)
static

Definition at line 1406 of file fdi.c.

1407{
1408 cab_LONG e; /* last block flag */
1409
1410 TRACE("(inlen == %d, outlen == %d)\n", inlen, outlen);
1411
1412 ZIP(inpos) = CAB(inbuf);
1413 ZIP(bb) = ZIP(bk) = ZIP(window_posn) = 0;
1414 if(outlen > ZIPWSIZE)
1415 return DECR_DATAFORMAT;
1416
1417 /* CK = Chris Kirmse, official Microsoft purloiner */
1418 if(ZIP(inpos)[0] != 0x43 || ZIP(inpos)[1] != 0x4B)
1419 return DECR_ILLEGALDATA;
1420 ZIP(inpos) += 2;
1421
1422 do {
1423 if(fdi_Zipinflate_block(&e, decomp_state))
1424 return DECR_ILLEGALDATA;
1425 } while(!e);
1426
1427 /* return success */
1428 return DECR_OK;
1429}
static cab_LONG fdi_Zipinflate_block(cab_LONG *e, fdi_decomp_state *decomp_state)
Definition: fdi.c:1368

Referenced by FDICopy().

Variable Documentation

◆ THOSE_ZIP_CONSTS

THOSE_ZIP_CONSTS

Definition at line 76 of file fdi.c.