* Test unit(s).
*
* The fdintNEXT_CABINET callbacks are probably not working quite as they should.
- * There are several FIXME's in the source describing some of the deficiencies in
+ * There are several FIXMEs in the source describing some of the deficiencies in
* some detail. Additionally, we do not do a very good job of returning the right
* error codes to this callback.
*
cab_UBYTE block_resv;
} MORE_ISCAB_INFO, *PMORE_ISCAB_INFO;
+typedef struct
+{
+ unsigned int magic;
+ PFNALLOC alloc;
+ PFNFREE free;
+ PFNOPEN open;
+ PFNREAD read;
+ PFNWRITE write;
+ PFNCLOSE close;
+ PFNSEEK seek;
+ PERF perf;
+} FDI_Int;
+
+#define FDI_INT_MAGIC 0xfdfdfd05
+
/*
* ugh, well, this ended up being pretty damn silly...
* now that I've conceded to build equivalent structures to struct cab.*,
*/
typedef struct fdi_cds_fwd {
- void *hfdi; /* the hfdi we are using */
+ FDI_Int *fdi; /* the hfdi we are using */
INT_PTR filehf, cabhf; /* file handle we are using */
struct fdi_folder *current; /* current folder we're extracting from */
cab_ULONG offset; /* uncompressed offset within folder */
struct fdi_cds_fwd *next;
} fdi_decomp_state;
+#define ZIPNEEDBITS(n) {while(k<(n)){cab_LONG c=*(ZIP(inpos)++);\
+ b|=((cab_ULONG)c)<<k;k+=8;}}
+#define ZIPDUMPBITS(n) {b>>=(n);k-=(n);}
+
+/* endian-neutral reading of little-endian data */
+#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)
+
+static void set_error( FDI_Int *fdi, int oper, int err )
+{
+ fdi->perf->erfOper = oper;
+ fdi->perf->erfType = err;
+ fdi->perf->fError = TRUE;
+ if (err) SetLastError( err );
+}
+
+static FDI_Int *get_fdi_ptr( HFDI hfdi )
+{
+ FDI_Int *fdi= (FDI_Int *)hfdi;
+
+ if (!fdi || fdi->magic != FDI_INT_MAGIC)
+ {
+ SetLastError( ERROR_INVALID_HANDLE );
+ return NULL;
+ }
+ return fdi;
+}
+
/****************************************************************
* QTMupdatemodel (internal)
*/
switch (bytes & 3) {
case 3: ul |= *data++ << 16;
+ /* fall through */
case 2: ul |= *data++ << 8;
+ /* fall through */
case 1: ul |= *data;
}
csum ^= ul;
int cpuType,
PERF perf)
{
- HFDI rv;
+ FDI_Int *fdi;
TRACE("(pfnalloc == ^%p, pfnfree == ^%p, pfnopen == ^%p, pfnread == ^%p, pfnwrite == ^%p, "
"pfnclose == ^%p, pfnseek == ^%p, cpuType == %d, perf == ^%p)\n",
return NULL;
}
- if (!((rv = (*pfnalloc)(sizeof(FDI_Int))))) {
+ if (!((fdi = pfnalloc(sizeof(FDI_Int))))) {
perf->erfOper = FDIERROR_ALLOC_FAIL;
- perf->erfType = ERROR_NOT_ENOUGH_MEMORY;
+ perf->erfType = 0;
perf->fError = TRUE;
-
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return NULL;
}
-
- PFDI_INT(rv)->FDI_Intmagic = FDI_INT_MAGIC;
- PFDI_INT(rv)->pfnalloc = pfnalloc;
- PFDI_INT(rv)->pfnfree = pfnfree;
- PFDI_INT(rv)->pfnopen = pfnopen;
- PFDI_INT(rv)->pfnread = pfnread;
- PFDI_INT(rv)->pfnwrite = pfnwrite;
- PFDI_INT(rv)->pfnclose = pfnclose;
- PFDI_INT(rv)->pfnseek = pfnseek;
+
+ fdi->magic = FDI_INT_MAGIC;
+ fdi->alloc = pfnalloc;
+ fdi->free = pfnfree;
+ fdi->open = pfnopen;
+ fdi->read = pfnread;
+ fdi->write = pfnwrite;
+ fdi->close = pfnclose;
+ fdi->seek = pfnseek;
/* no-brainer: we ignore the cpu type; this is only used
for the 16-bit versions in Windows anyhow... */
- PFDI_INT(rv)->perf = perf;
+ fdi->perf = perf;
- return rv;
+ return (HFDI)fdi;
}
/*******************************************************************
*
* returns the file pointer position of a file handle.
*/
-static long FDI_getoffset(HFDI hfdi, INT_PTR hf)
+static LONG FDI_getoffset(FDI_Int *fdi, INT_PTR hf)
{
- return PFDI_SEEK(hfdi, hf, 0L, SEEK_CUR);
+ return fdi->seek(hf, 0, SEEK_CUR);
}
/**********************************************************************
*
* allocate and read an arbitrarily long string from the cabinet
*/
-static char *FDI_read_string(HFDI hfdi, INT_PTR hf, long cabsize)
+static char *FDI_read_string(FDI_Int *fdi, INT_PTR hf, long cabsize)
{
size_t len=256,
- base = FDI_getoffset(hfdi, hf),
+ base = FDI_getoffset(fdi, hf),
maxlen = cabsize - base;
BOOL ok = FALSE;
unsigned int i;
cab_UBYTE *buf = NULL;
- TRACE("(hfdi == ^%p, hf == %ld, cabsize == %ld)\n", hfdi, hf, cabsize);
+ TRACE("(fdi == %p, hf == %ld, cabsize == %ld)\n", fdi, hf, cabsize);
do {
if (len > maxlen) len = maxlen;
- if (!(buf = PFDI_ALLOC(hfdi, len))) break;
- if (!PFDI_READ(hfdi, hf, buf, len)) break;
+ if (!(buf = fdi->alloc(len))) break;
+ if (!fdi->read(hf, buf, len)) break;
/* search for a null terminator in what we've just read */
for (i=0; i < len; i++) {
break;
}
/* The buffer is too small for the string. Reset the file to the point
- * were we started, free the buffer and increase the size for the next try
+ * where we started, free the buffer and increase the size for the next try
*/
- PFDI_SEEK(hfdi, hf, base, SEEK_SET);
- PFDI_FREE(hfdi, buf);
+ fdi->seek(hf, base, SEEK_SET);
+ fdi->free(buf);
buf = NULL;
len *= 2;
}
if (!ok) {
if (buf)
- PFDI_FREE(hfdi, buf);
+ fdi->free(buf);
else
ERR("out of memory!\n");
return NULL;
}
/* otherwise, set the stream to just after the string and return */
- PFDI_SEEK(hfdi, hf, base + strlen((char *)buf) + 1, SEEK_SET);
+ fdi->seek(hf, base + strlen((char *)buf) + 1, SEEK_SET);
return (char *) buf;
}
* without the sanity checks (and bug)
*/
static BOOL FDI_read_entries(
- HFDI hfdi,
+ FDI_Int *fdi,
INT_PTR hf,
PFDICABINETINFO pfdici,
PMORE_ISCAB_INFO pmii)
{
int num_folders, num_files, header_resv, folder_resv = 0;
- LONG base_offset, cabsize;
+ LONG cabsize;
USHORT setid, cabidx, flags;
cab_UBYTE buf[64], block_resv;
char *prevname = NULL, *previnfo = NULL, *nextname = NULL, *nextinfo = NULL;
- TRACE("(hfdi == ^%p, hf == %ld, pfdici == ^%p)\n", hfdi, hf, pfdici);
-
- /*
- * FIXME: I just noticed that I am memorizing the initial file pointer
- * offset and restoring it before reading in the rest of the header
- * information in the cabinet. Perhaps that's correct -- that is, perhaps
- * this API is supposed to support "streaming" cabinets which are embedded
- * in other files, or cabinets which begin at file offsets other than zero.
- * Otherwise, I should instead go to the absolute beginning of the file.
- * (Either way, the semantics of wine's FDICopy require me to leave the
- * file pointer where it is afterwards -- If Windows does not do so, we
- * ought to duplicate the native behavior in the FDIIsCabinet API, not here.
- *
- * So, the answer lies in Windows; will native cabinet.dll recognize a
- * cabinet "file" embedded in another file? Note that cabextract.c does
- * support this, which implies that Microsoft's might. I haven't tried it
- * yet so I don't know. ATM, most of wine's FDI cabinet routines (except
- * this one) would not work in this way. To fix it, we could just make the
- * various references to absolute file positions in the code relative to an
- * initial "beginning" offset. Because the FDICopy API doesn't take a
- * file-handle like this one, we would therein need to search through the
- * file for the beginning of the cabinet (as we also do in cabextract.c).
- * Note that this limits us to a maximum of one cabinet per. file: the first.
- *
- * So, in summary: either the code below is wrong, or the rest of fdi.c is
- * wrong... I cannot imagine that both are correct ;) One of these flaws
- * should be fixed after determining the behavior on Windows. We ought
- * to check both FDIIsCabinet and FDICopy for the right behavior.
- *
- * -gmt
- */
-
- /* get basic offset & size info */
- base_offset = FDI_getoffset(hfdi, hf);
-
- if (PFDI_SEEK(hfdi, hf, 0, SEEK_END) == -1) {
- if (pmii) {
- PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NOT_A_CABINET;
- PFDI_INT(hfdi)->perf->erfType = 0;
- PFDI_INT(hfdi)->perf->fError = TRUE;
- }
- return FALSE;
- }
-
- cabsize = FDI_getoffset(hfdi, hf);
-
- if ((cabsize == -1) || (base_offset == -1) ||
- ( PFDI_SEEK(hfdi, hf, base_offset, SEEK_SET) == -1 )) {
- if (pmii) {
- PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NOT_A_CABINET;
- PFDI_INT(hfdi)->perf->erfType = 0;
- PFDI_INT(hfdi)->perf->fError = TRUE;
- }
- return FALSE;
- }
+ TRACE("(fdi == ^%p, hf == %ld, pfdici == ^%p)\n", fdi, hf, pfdici);
/* read in the CFHEADER */
- if (PFDI_READ(hfdi, hf, buf, cfhead_SIZEOF) != cfhead_SIZEOF) {
- if (pmii) {
- PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NOT_A_CABINET;
- PFDI_INT(hfdi)->perf->erfType = 0;
- PFDI_INT(hfdi)->perf->fError = TRUE;
- }
+ if (fdi->read(hf, buf, cfhead_SIZEOF) != cfhead_SIZEOF) {
+ if (pmii) set_error( fdi, FDIERROR_NOT_A_CABINET, 0 );
return FALSE;
}
-
+
/* check basic MSCF signature */
if (EndGetI32(buf+cfhead_Signature) != 0x4643534d) {
- if (pmii) {
- PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NOT_A_CABINET;
- PFDI_INT(hfdi)->perf->erfType = 0;
- PFDI_INT(hfdi)->perf->fError = TRUE;
- }
+ if (pmii) set_error( fdi, FDIERROR_NOT_A_CABINET, 0 );
return FALSE;
}
+ /* get the cabinet size */
+ cabsize = EndGetI32(buf+cfhead_CabinetSize);
+
/* get the number of folders */
num_folders = EndGetI16(buf+cfhead_NumFolders);
- if (num_folders == 0) {
- /* PONDERME: is this really invalid? */
- WARN("weird cabinet detect failure: no folders in cabinet\n");
- if (pmii) {
- PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NOT_A_CABINET;
- PFDI_INT(hfdi)->perf->erfType = 0;
- PFDI_INT(hfdi)->perf->fError = TRUE;
- }
- return FALSE;
- }
/* get the number of files */
num_files = EndGetI16(buf+cfhead_NumFiles);
- if (num_files == 0) {
- /* PONDERME: is this really invalid? */
- WARN("weird cabinet detect failure: no files in cabinet\n");
- if (pmii) {
- PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NOT_A_CABINET;
- PFDI_INT(hfdi)->perf->erfType = 0;
- PFDI_INT(hfdi)->perf->fError = TRUE;
- }
- return FALSE;
- }
/* setid */
setid = EndGetI16(buf+cfhead_SetID);
(buf[cfhead_MajorVersion] == 1 && buf[cfhead_MinorVersion] > 3))
{
WARN("cabinet format version > 1.3\n");
- if (pmii) {
- PFDI_INT(hfdi)->perf->erfOper = FDIERROR_UNKNOWN_CABINET_VERSION;
- PFDI_INT(hfdi)->perf->erfType = 0; /* ? */
- PFDI_INT(hfdi)->perf->fError = TRUE;
- }
+ if (pmii) set_error( fdi, FDIERROR_UNKNOWN_CABINET_VERSION, 0 /* ? */ );
return FALSE;
}
/* read the reserved-sizes part of header, if present */
if (flags & cfheadRESERVE_PRESENT) {
- if (PFDI_READ(hfdi, hf, buf, cfheadext_SIZEOF) != cfheadext_SIZEOF) {
+ if (fdi->read(hf, buf, cfheadext_SIZEOF) != cfheadext_SIZEOF) {
ERR("bunk reserve-sizes?\n");
- if (pmii) {
- PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
- PFDI_INT(hfdi)->perf->erfType = 0; /* ? */
- PFDI_INT(hfdi)->perf->fError = TRUE;
- }
+ if (pmii) set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 /* ? */ );
return FALSE;
}
}
/* skip the reserved header */
- if ((header_resv) && (PFDI_SEEK(hfdi, hf, header_resv, SEEK_CUR) == -1)) {
+ if ((header_resv) && (fdi->seek(hf, header_resv, SEEK_CUR) == -1)) {
ERR("seek failure: header_resv\n");
- if (pmii) {
- PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
- PFDI_INT(hfdi)->perf->erfType = 0; /* ? */
- PFDI_INT(hfdi)->perf->fError = TRUE;
- }
+ if (pmii) set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 /* ? */ );
return FALSE;
}
}
if (flags & cfheadPREV_CABINET) {
- prevname = FDI_read_string(hfdi, hf, cabsize);
+ prevname = FDI_read_string(fdi, hf, cabsize);
if (!prevname) {
- if (pmii) {
- PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
- PFDI_INT(hfdi)->perf->erfType = 0; /* ? */
- PFDI_INT(hfdi)->perf->fError = TRUE;
- }
+ if (pmii) set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 /* ? */ );
return FALSE;
} else
if (pmii)
pmii->prevname = prevname;
else
- PFDI_FREE(hfdi, prevname);
- previnfo = FDI_read_string(hfdi, hf, cabsize);
+ fdi->free(prevname);
+ previnfo = FDI_read_string(fdi, hf, cabsize);
if (previnfo) {
if (pmii)
pmii->previnfo = previnfo;
else
- PFDI_FREE(hfdi, previnfo);
+ fdi->free(previnfo);
}
}
if (flags & cfheadNEXT_CABINET) {
if (pmii)
pmii->hasnext = TRUE;
- nextname = FDI_read_string(hfdi, hf, cabsize);
+ nextname = FDI_read_string(fdi, hf, cabsize);
if (!nextname) {
if ((flags & cfheadPREV_CABINET) && pmii) {
- if (pmii->prevname) PFDI_FREE(hfdi, prevname);
- if (pmii->previnfo) PFDI_FREE(hfdi, previnfo);
+ if (pmii->prevname) fdi->free(prevname);
+ if (pmii->previnfo) fdi->free(previnfo);
}
- PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
- PFDI_INT(hfdi)->perf->erfType = 0; /* ? */
- PFDI_INT(hfdi)->perf->fError = TRUE;
+ set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 /* ? */ );
return FALSE;
} else
if (pmii)
pmii->nextname = nextname;
else
- PFDI_FREE(hfdi, nextname);
- nextinfo = FDI_read_string(hfdi, hf, cabsize);
+ fdi->free(nextname);
+ nextinfo = FDI_read_string(fdi, hf, cabsize);
if (nextinfo) {
if (pmii)
pmii->nextinfo = nextinfo;
else
- PFDI_FREE(hfdi, nextinfo);
+ fdi->free(nextinfo);
}
}
pfdici->cFiles = num_files;
pfdici->setID = setid;
pfdici->iCabinet = cabidx;
- pfdici->fReserve = (flags & cfheadRESERVE_PRESENT) ? TRUE : FALSE;
- pfdici->hasprev = (flags & cfheadPREV_CABINET) ? TRUE : FALSE;
- pfdici->hasnext = (flags & cfheadNEXT_CABINET) ? TRUE : FALSE;
+ pfdici->fReserve = (flags & cfheadRESERVE_PRESENT) != 0;
+ pfdici->hasprev = (flags & cfheadPREV_CABINET) != 0;
+ pfdici->hasnext = (flags & cfheadNEXT_CABINET) != 0;
return TRUE;
}
/***********************************************************************
- * FDIIsCabinet (CABINET.21)
+ * FDIIsCabinet (CABINET.21)
*
* Informs the caller as to whether or not the provided file handle is
* really a cabinet or not, filling out the provided PFDICABINETINFO
* be filled out with information about the cabinet
* file indicated by hf if, indeed, it is determined
* to be a cabinet.
- *
+ *
* RETURNS
* TRUE if the file is a cabinet. The info pointed to by pfdici will
* be provided.
* INCLUDES
* fdi.c
*/
-BOOL __cdecl FDIIsCabinet(
- HFDI hfdi,
- INT_PTR hf,
- PFDICABINETINFO pfdici)
+BOOL __cdecl FDIIsCabinet(HFDI hfdi, INT_PTR hf, PFDICABINETINFO pfdici)
{
BOOL rv;
+ FDI_Int *fdi = get_fdi_ptr( hfdi );
TRACE("(hfdi == ^%p, hf == ^%ld, pfdici == ^%p)\n", hfdi, hf, pfdici);
- if (!REALLY_IS_FDI(hfdi)) {
- ERR("REALLY_IS_FDI failed on ^%p\n", hfdi);
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
-
- if (!hf) {
- ERR("(!hf)!\n");
- /* PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CABINET_NOT_FOUND;
- PFDI_INT(hfdi)->perf->erfType = ERROR_INVALID_HANDLE;
- PFDI_INT(hfdi)->perf->fError = TRUE; */
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
+ if (!fdi) return FALSE;
if (!pfdici) {
- ERR("(!pfdici)!\n");
- /* PFDI_INT(hfdi)->perf->erfOper = FDIERROR_NONE;
- PFDI_INT(hfdi)->perf->erfType = ERROR_BAD_ARGUMENTS;
- PFDI_INT(hfdi)->perf->fError = TRUE; */
SetLastError(ERROR_BAD_ARGUMENTS);
return FALSE;
}
- rv = FDI_read_entries(hfdi, hf, pfdici, NULL);
+ rv = FDI_read_entries(fdi, hf, pfdici, NULL);
if (rv)
pfdici->hasnext = FALSE; /* yuck. duplicate apparent cabinet.dll bug */
/* if a previously allocated window is big enough, keep it */
if (window < 10 || window > 21) return DECR_DATAFORMAT;
if (QTM(actual_size) < wndsize) {
- if (QTM(window)) PFDI_FREE(CAB(hfdi), QTM(window));
+ if (QTM(window)) CAB(fdi)->free(QTM(window));
QTM(window) = NULL;
}
if (!QTM(window)) {
- if (!(QTM(window) = PFDI_ALLOC(CAB(hfdi), wndsize))) return DECR_NOMEMORY;
+ if (!(QTM(window) = CAB(fdi)->alloc(wndsize))) return DECR_NOMEMORY;
QTM(actual_size) = wndsize;
}
QTM(window_size) = wndsize;
/* initialize arithmetic coding models */
- QTMfdi_initmodel(&QTM(model7), &QTM(m7sym)[0], 7, 0);
+ QTMfdi_initmodel(&QTM(model7), QTM(m7sym), 7, 0);
- QTMfdi_initmodel(&QTM(model00), &QTM(m00sym)[0], 0x40, 0x00);
- QTMfdi_initmodel(&QTM(model40), &QTM(m40sym)[0], 0x40, 0x40);
- QTMfdi_initmodel(&QTM(model80), &QTM(m80sym)[0], 0x40, 0x80);
- QTMfdi_initmodel(&QTM(modelC0), &QTM(mC0sym)[0], 0x40, 0xC0);
+ QTMfdi_initmodel(&QTM(model00), QTM(m00sym), 0x40, 0x00);
+ QTMfdi_initmodel(&QTM(model40), QTM(m40sym), 0x40, 0x40);
+ QTMfdi_initmodel(&QTM(model80), QTM(m80sym), 0x40, 0x80);
+ QTMfdi_initmodel(&QTM(modelC0), QTM(mC0sym), 0x40, 0xC0);
/* model 4 depends on table size, ranges from 20 to 24 */
- QTMfdi_initmodel(&QTM(model4), &QTM(m4sym)[0], (msz < 24) ? msz : 24, 0);
+ QTMfdi_initmodel(&QTM(model4), QTM(m4sym), (msz < 24) ? msz : 24, 0);
/* model 5 depends on table size, ranges from 20 to 36 */
- QTMfdi_initmodel(&QTM(model5), &QTM(m5sym)[0], (msz < 36) ? msz : 36, 0);
+ QTMfdi_initmodel(&QTM(model5), QTM(m5sym), (msz < 36) ? msz : 36, 0);
/* model 6pos depends on table size, ranges from 20 to 42 */
- QTMfdi_initmodel(&QTM(model6pos), &QTM(m6psym)[0], msz, 0);
- QTMfdi_initmodel(&QTM(model6len), &QTM(m6lsym)[0], 27, 0);
+ QTMfdi_initmodel(&QTM(model6pos), QTM(m6psym), msz, 0);
+ QTMfdi_initmodel(&QTM(model6len), QTM(m6lsym), 27, 0);
return DECR_OK;
}
/* if a previously allocated window is big enough, keep it */
if (window < 15 || window > 21) return DECR_DATAFORMAT;
if (LZX(actual_size) < wndsize) {
- if (LZX(window)) PFDI_FREE(CAB(hfdi), LZX(window));
+ if (LZX(window)) CAB(fdi)->free(LZX(window));
LZX(window) = NULL;
}
if (!LZX(window)) {
- if (!(LZX(window) = PFDI_ALLOC(CAB(hfdi), wndsize))) return DECR_NOMEMORY;
+ if (!(LZX(window) = CAB(fdi)->alloc(wndsize))) return DECR_NOMEMORY;
LZX(actual_size) = wndsize;
}
LZX(window_size) = wndsize;
/********************************************************
* Ziphuft_free (internal)
*/
-static void fdi_Ziphuft_free(HFDI hfdi, struct Ziphuft *t)
+static void fdi_Ziphuft_free(FDI_Int *fdi, struct Ziphuft *t)
{
register struct Ziphuft *p, *q;
while (p != NULL)
{
q = (--p)->v.t;
- PFDI_FREE(hfdi, p);
+ fdi->free(p);
p = q;
}
}
l[h] = j; /* set table size in stack */
/* allocate and link in new table */
- if (!(q = PFDI_ALLOC(CAB(hfdi), (z + 1)*sizeof(struct Ziphuft))))
+ if (!(q = CAB(fdi)->alloc((z + 1)*sizeof(struct Ziphuft))))
{
if(h)
- fdi_Ziphuft_free(CAB(hfdi), ZIP(u)[0]);
+ fdi_Ziphuft_free(CAB(fdi), ZIP(u)[0]);
return 3; /* not enough memory */
}
*t = q + 1; /* link to list for Ziphuft_free() */
fixed_bd = 5;
if((i = fdi_Ziphuft_build(l, 30, 0, Zipcpdist, Zipcpdext, &fixed_td, &fixed_bd, decomp_state)) > 1)
{
- fdi_Ziphuft_free(CAB(hfdi), fixed_tl);
+ fdi_Ziphuft_free(CAB(fdi), fixed_tl);
return i;
}
/* decompress until an end-of-block code */
i = fdi_Zipinflate_codes(fixed_tl, fixed_td, fixed_bl, fixed_bd, decomp_state);
- fdi_Ziphuft_free(CAB(hfdi), fixed_td);
- fdi_Ziphuft_free(CAB(hfdi), fixed_tl);
+ fdi_Ziphuft_free(CAB(fdi), fixed_td);
+ fdi_Ziphuft_free(CAB(fdi), fixed_tl);
return i;
}
if((i = fdi_Ziphuft_build(ll, 19, 19, NULL, NULL, &tl, &bl, decomp_state)) != 0)
{
if(i == 1)
- fdi_Ziphuft_free(CAB(hfdi), tl);
+ fdi_Ziphuft_free(CAB(fdi), tl);
return i; /* incomplete code set */
}
}
/* free decoding table for trees */
- fdi_Ziphuft_free(CAB(hfdi), tl);
+ fdi_Ziphuft_free(CAB(fdi), tl);
/* restore the global bit buffer */
ZIP(bb) = b;
if((i = fdi_Ziphuft_build(ll, nl, 257, Zipcplens, Zipcplext, &tl, &bl, decomp_state)) != 0)
{
if(i == 1)
- fdi_Ziphuft_free(CAB(hfdi), tl);
+ fdi_Ziphuft_free(CAB(fdi), tl);
return i; /* incomplete code set */
}
bd = ZIPDBITS;
return 1;
/* free the decoding tables, return */
- fdi_Ziphuft_free(CAB(hfdi), tl);
- fdi_Ziphuft_free(CAB(hfdi), td);
+ fdi_Ziphuft_free(CAB(fdi), tl);
+ fdi_Ziphuft_free(CAB(fdi), td);
return 0;
}
/* if cando != 0 */
if (cando && savemode)
- PFDI_WRITE(CAB(hfdi), CAB(filehf), CAB(outpos), cando);
+ CAB(fdi)->write(CAB(filehf), CAB(outpos), cando);
CAB(outpos) += cando;
CAB(outlen) -= cando;
inlen = outlen = 0;
while (outlen == 0) {
/* read the block header, skip the reserved part */
- if (PFDI_READ(CAB(hfdi), cab->cabhf, buf, cfdata_SIZEOF) != cfdata_SIZEOF)
+ if (CAB(fdi)->read(cab->cabhf, buf, cfdata_SIZEOF) != cfdata_SIZEOF)
return DECR_INPUT;
- if (PFDI_SEEK(CAB(hfdi), cab->cabhf, cab->mii.block_resv, SEEK_CUR) == -1)
+ if (CAB(fdi)->seek(cab->cabhf, cab->mii.block_resv, SEEK_CUR) == -1)
return DECR_INPUT;
/* we shouldn't get blocks over CAB_INPUTMAX in size */
len = EndGetI16(buf+cfdata_CompressedSize);
inlen += len;
if (inlen > CAB_INPUTMAX) return DECR_INPUT;
- if (PFDI_READ(CAB(hfdi), cab->cabhf, data, len) != len)
+ if (CAB(fdi)->read(cab->cabhf, data, len) != len)
return DECR_INPUT;
/* clear two bytes after read-in data */
/* outlen=0 means this block was the last contiguous part
of a split block, continued in the next cabinet */
if (outlen == 0) {
- int pathlen, filenamelen, idx, i;
+ int pathlen, filenamelen;
INT_PTR cabhf;
char fullpath[MAX_PATH], userpath[256];
FDINOTIFICATION fdin;
FDICABINETINFO fdici;
char emptystring = '\0';
cab_UBYTE buf2[64];
- int success = FALSE;
+ BOOL success = FALSE;
struct fdi_folder *fol = NULL, *linkfol = NULL;
struct fdi_file *file = NULL, *linkfile = NULL;
/* set up the next decomp_state... */
if (!(cab->next)) {
+ unsigned int i;
+
if (!cab->mii.hasnext) return DECR_INPUT;
- if (!((cab->next = PFDI_ALLOC(CAB(hfdi), sizeof(fdi_decomp_state)))))
+ if (!((cab->next = CAB(fdi)->alloc(sizeof(fdi_decomp_state)))))
return DECR_NOMEMORY;
-
+
ZeroMemory(cab->next, sizeof(fdi_decomp_state));
/* copy pszCabPath to userpath */
ZeroMemory(userpath, 256);
- pathlen = (pszCabPath) ? strlen(pszCabPath) : 0;
+ pathlen = pszCabPath ? strlen(pszCabPath) : 0;
if (pathlen) {
- if (pathlen < 256) {
- for (i = 0; i <= pathlen; i++)
- userpath[i] = pszCabPath[i];
- } /* else we are in a weird place... let's leave it blank and see if the user fixes it */
- }
+ if (pathlen < 256) /* else we are in a weird place... let's leave it blank and see if the user fixes it */
+ strcpy(userpath, pszCabPath);
+ }
/* initial fdintNEXT_CABINET notification */
ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
- fdin.psz1 = (cab->mii.nextname) ? cab->mii.nextname : &emptystring;
- fdin.psz2 = (cab->mii.nextinfo) ? cab->mii.nextinfo : &emptystring;
- fdin.psz3 = &userpath[0];
+ fdin.psz1 = cab->mii.nextname ? cab->mii.nextname : &emptystring;
+ fdin.psz2 = cab->mii.nextinfo ? cab->mii.nextinfo : &emptystring;
+ fdin.psz3 = userpath;
fdin.fdie = FDIERROR_NONE;
fdin.pv = pvUser;
do {
pathlen = strlen(userpath);
- filenamelen = (cab->mii.nextname) ? strlen(cab->mii.nextname) : 0;
+ filenamelen = cab->mii.nextname ? strlen(cab->mii.nextname) : 0;
/* slight overestimation here to save CPU cycles in the developer's brain */
if ((pathlen + filenamelen + 3) > MAX_PATH) {
}
/* paste the path and filename together */
- idx = 0;
+ fullpath[0] = '\0';
if (pathlen) {
- for (i = 0; i < pathlen; i++) fullpath[idx++] = userpath[i];
- if (fullpath[idx - 1] != '\\') fullpath[idx++] = '\\';
+ strcpy(fullpath, userpath);
+#ifdef __REACTOS__
+ if (fullpath[pathlen - 1] == '\\')
+ fullpath[pathlen - 1] = '\0';
+#else
+ if (fullpath[pathlen - 1] != '\\')
+ strcat(fullpath, "\\");
+#endif
}
- if (filenamelen) for (i = 0; i < filenamelen; i++) fullpath[idx++] = cab->mii.nextname[i];
- fullpath[idx] = '\0';
-
+#ifdef __REACTOS__
+ if (filenamelen) {
+ strcat(fullpath, "\\");
+#else
+ if (filenamelen)
+#endif
+ strcat(fullpath, cab->mii.nextname);
+#ifdef __REACTOS__
+ }
+#endif
+
TRACE("full cab path/file name: %s\n", debugstr_a(fullpath));
-
+
/* try to get a handle to the cabfile */
- cabhf = PFDI_OPEN(CAB(hfdi), fullpath, _O_RDONLY|_O_BINARY, _S_IREAD | _S_IWRITE);
+ cabhf = CAB(fdi)->open(fullpath, _O_RDONLY|_O_BINARY, _S_IREAD | _S_IWRITE);
if (cabhf == -1) {
/* no file. allow the user to try again */
fdin.fdie = FDIERROR_CABINET_NOT_FOUND;
if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
continue;
}
-
+
if (cabhf == 0) {
ERR("PFDI_OPEN returned zero for %s.\n", fullpath);
fdin.fdie = FDIERROR_CABINET_NOT_FOUND;
if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
continue;
}
-
+
/* check if it's really a cabfile. Note that this doesn't implement the bug */
- if (!FDI_read_entries(CAB(hfdi), cabhf, &fdici, &(cab->next->mii))) {
+ if (!FDI_read_entries(CAB(fdi), cabhf, &fdici, &(cab->next->mii))) {
WARN("FDIIsCabinet failed.\n");
- PFDI_CLOSE(CAB(hfdi), cabhf);
+ CAB(fdi)->close(cabhf);
fdin.fdie = FDIERROR_NOT_A_CABINET;
if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
continue;
if ((fdici.setID != cab->setID) || (fdici.iCabinet != (cab->iCabinet + 1))) {
WARN("Wrong Cabinet.\n");
- PFDI_CLOSE(CAB(hfdi), cabhf);
+ CAB(fdi)->close(cabhf);
fdin.fdie = FDIERROR_WRONG_CABINET;
if (((*pfnfdin)(fdintNEXT_CABINET, &fdin))) return DECR_USERABORT;
continue;
cab->next->setID = fdici.setID;
cab->next->iCabinet = fdici.iCabinet;
- cab->next->hfdi = CAB(hfdi);
+ cab->next->fdi = CAB(fdi);
cab->next->filehf = CAB(filehf);
cab->next->cabhf = cabhf;
cab->next->decompress = CAB(decompress); /* crude, but unused anyhow */
/* read folders */
for (i = 0; i < fdici.cFolders; i++) {
- if (PFDI_READ(CAB(hfdi), cab->cabhf, buf2, cffold_SIZEOF) != cffold_SIZEOF)
+ if (CAB(fdi)->read(cab->cabhf, buf2, cffold_SIZEOF) != cffold_SIZEOF)
return DECR_INPUT;
if (cab->mii.folder_resv > 0)
- PFDI_SEEK(CAB(hfdi), cab->cabhf, cab->mii.folder_resv, SEEK_CUR);
+ CAB(fdi)->seek(cab->cabhf, cab->mii.folder_resv, SEEK_CUR);
- fol = PFDI_ALLOC(CAB(hfdi), sizeof(struct fdi_folder));
+ fol = CAB(fdi)->alloc(sizeof(struct fdi_folder));
if (!fol) {
ERR("out of memory!\n");
return DECR_NOMEMORY;
/* read files */
for (i = 0; i < fdici.cFiles; i++) {
- if (PFDI_READ(CAB(hfdi), cab->cabhf, buf2, cffile_SIZEOF) != cffile_SIZEOF)
+ if (CAB(fdi)->read(cab->cabhf, buf2, cffile_SIZEOF) != cffile_SIZEOF)
return DECR_INPUT;
- file = PFDI_ALLOC(CAB(hfdi), sizeof(struct fdi_file));
+ file = CAB(fdi)->alloc(sizeof(struct fdi_file));
if (!file) {
ERR("out of memory!\n");
return DECR_NOMEMORY;
file->time = EndGetI16(buf2+cffile_Time);
file->date = EndGetI16(buf2+cffile_Date);
file->attribs = EndGetI16(buf2+cffile_Attribs);
- file->filename = FDI_read_string(CAB(hfdi), cab->cabhf, fdici.cbCabinet);
+ file->filename = FDI_read_string(CAB(fdi), cab->cabhf, fdici.cbCabinet);
if (!file->filename) return DECR_INPUT;
/* check to ensure a real match */
if (lstrcmpiA(fi->filename, file->filename) == 0) {
success = TRUE;
- if (PFDI_SEEK(CAB(hfdi), cab->cabhf, cab->firstfol->offset, SEEK_SET) == -1)
+ if (CAB(fdi)->seek(cab->cabhf, cab->firstfol->offset, SEEK_SET) == -1)
return DECR_INPUT;
break;
}
return DECR_OK;
}
-static void free_decompression_temps(HFDI hfdi, const struct fdi_folder *fol,
+static void free_decompression_temps(FDI_Int *fdi, const struct fdi_folder *fol,
fdi_decomp_state *decomp_state)
{
switch (fol->comp_type & cffoldCOMPTYPE_MASK) {
case cffoldCOMPTYPE_LZX:
if (LZX(window)) {
- PFDI_FREE(hfdi, LZX(window));
+ fdi->free(LZX(window));
LZX(window) = NULL;
}
break;
case cffoldCOMPTYPE_QUANTUM:
if (QTM(window)) {
- PFDI_FREE(hfdi, QTM(window));
+ fdi->free(QTM(window));
QTM(window) = NULL;
}
break;
}
}
-static void free_decompression_mem(HFDI hfdi,
- fdi_decomp_state *decomp_state, struct fdi_file *file)
+static void free_decompression_mem(FDI_Int *fdi, fdi_decomp_state *decomp_state)
{
struct fdi_folder *fol;
while (decomp_state) {
fdi_decomp_state *prev_fds;
- PFDI_CLOSE(hfdi, CAB(cabhf));
+ fdi->close(CAB(cabhf));
/* free the storage remembered by mii */
- if (CAB(mii).nextname) PFDI_FREE(hfdi, CAB(mii).nextname);
- if (CAB(mii).nextinfo) PFDI_FREE(hfdi, CAB(mii).nextinfo);
- if (CAB(mii).prevname) PFDI_FREE(hfdi, CAB(mii).prevname);
- if (CAB(mii).previnfo) PFDI_FREE(hfdi, CAB(mii).previnfo);
+ if (CAB(mii).nextname) fdi->free(CAB(mii).nextname);
+ if (CAB(mii).nextinfo) fdi->free(CAB(mii).nextinfo);
+ if (CAB(mii).prevname) fdi->free(CAB(mii).prevname);
+ if (CAB(mii).previnfo) fdi->free(CAB(mii).previnfo);
while (CAB(firstfol)) {
fol = CAB(firstfol);
CAB(firstfol) = CAB(firstfol)->next;
- PFDI_FREE(hfdi, fol);
+ fdi->free(fol);
}
while (CAB(firstfile)) {
- file = CAB(firstfile);
- if (file->filename) PFDI_FREE(hfdi, file->filename);
+ struct fdi_file *file = CAB(firstfile);
+ if (file->filename) fdi->free(file->filename);
CAB(firstfile) = CAB(firstfile)->next;
- PFDI_FREE(hfdi, file);
+ fdi->free(file);
}
prev_fds = decomp_state;
decomp_state = CAB(next);
- PFDI_FREE(hfdi, prev_fds);
+ fdi->free(prev_fds);
}
}
FDICABINETINFO fdici;
FDINOTIFICATION fdin;
INT_PTR cabhf, filehf = 0;
- int idx;
unsigned int i;
char fullpath[MAX_PATH];
size_t pathlen, filenamelen;
struct fdi_folder *fol = NULL, *linkfol = NULL;
struct fdi_file *file = NULL, *linkfile = NULL;
fdi_decomp_state *decomp_state;
+ FDI_Int *fdi = get_fdi_ptr( hfdi );
- TRACE("(hfdi == ^%p, pszCabinet == ^%p, pszCabPath == ^%p, flags == %0d, "
+ TRACE("(hfdi == ^%p, pszCabinet == %s, pszCabPath == %s, flags == %x, "
"pfnfdin == ^%p, pfnfdid == ^%p, pvUser == ^%p)\n",
- hfdi, pszCabinet, pszCabPath, flags, pfnfdin, pfnfdid, pvUser);
+ hfdi, debugstr_a(pszCabinet), debugstr_a(pszCabPath), flags, pfnfdin, pfnfdid, pvUser);
- if (!REALLY_IS_FDI(hfdi)) {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
+ if (!fdi) return FALSE;
- if (!(decomp_state = PFDI_ALLOC(hfdi, sizeof(fdi_decomp_state))))
+ if (!(decomp_state = fdi->alloc(sizeof(fdi_decomp_state))))
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
ZeroMemory(decomp_state, sizeof(fdi_decomp_state));
- pathlen = (pszCabPath) ? strlen(pszCabPath) : 0;
- filenamelen = (pszCabinet) ? strlen(pszCabinet) : 0;
+ pathlen = pszCabPath ? strlen(pszCabPath) : 0;
+ filenamelen = pszCabinet ? strlen(pszCabinet) : 0;
/* slight overestimation here to save CPU cycles in the developer's brain */
if ((pathlen + filenamelen + 3) > MAX_PATH) {
ERR("MAX_PATH exceeded.\n");
- PFDI_FREE(hfdi, decomp_state);
- PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CABINET_NOT_FOUND;
- PFDI_INT(hfdi)->perf->erfType = ERROR_FILE_NOT_FOUND;
- PFDI_INT(hfdi)->perf->fError = TRUE;
- SetLastError(ERROR_FILE_NOT_FOUND);
+ fdi->free(decomp_state);
+ set_error( fdi, FDIERROR_CABINET_NOT_FOUND, ERROR_FILE_NOT_FOUND );
return FALSE;
}
/* paste the path and filename together */
- idx = 0;
- if (pathlen) {
- for (i = 0; i < pathlen; i++) fullpath[idx++] = pszCabPath[i];
- if (fullpath[idx - 1] != '\\') fullpath[idx++] = '\\';
- }
- if (filenamelen) for (i = 0; i < filenamelen; i++) fullpath[idx++] = pszCabinet[i];
- fullpath[idx] = '\0';
+ fullpath[0] = '\0';
+ if (pathlen)
+ strcpy(fullpath, pszCabPath);
+ if (filenamelen)
+ strcat(fullpath, pszCabinet);
TRACE("full cab path/file name: %s\n", debugstr_a(fullpath));
/* get a handle to the cabfile */
- cabhf = PFDI_OPEN(hfdi, fullpath, _O_RDONLY|_O_BINARY, _S_IREAD | _S_IWRITE);
+ cabhf = fdi->open(fullpath, _O_RDONLY|_O_BINARY, _S_IREAD | _S_IWRITE);
if (cabhf == -1) {
- PFDI_FREE(hfdi, decomp_state);
- PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CABINET_NOT_FOUND;
- PFDI_INT(hfdi)->perf->fError = TRUE;
- SetLastError(ERROR_FILE_NOT_FOUND);
- return FALSE;
- }
-
- if (cabhf == 0) {
- ERR("PFDI_OPEN returned zero for %s.\n", fullpath);
- PFDI_FREE(hfdi, decomp_state);
- PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CABINET_NOT_FOUND;
- PFDI_INT(hfdi)->perf->erfType = ERROR_FILE_NOT_FOUND;
- PFDI_INT(hfdi)->perf->fError = TRUE;
+ fdi->free(decomp_state);
+ set_error( fdi, FDIERROR_CABINET_NOT_FOUND, 0 );
SetLastError(ERROR_FILE_NOT_FOUND);
return FALSE;
}
/* check if it's really a cabfile. Note that this doesn't implement the bug */
- if (!FDI_read_entries(hfdi, cabhf, &fdici, &(CAB(mii)))) {
- ERR("FDIIsCabinet failed.\n");
- PFDI_FREE(hfdi, decomp_state);
- PFDI_CLOSE(hfdi, cabhf);
+ if (!FDI_read_entries(fdi, cabhf, &fdici, &(CAB(mii)))) {
+ WARN("FDI_read_entries failed: %u\n", fdi->perf->erfOper);
+ fdi->free(decomp_state);
+ fdi->close(cabhf);
return FALSE;
}
-
+
/* cabinet notification */
ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
fdin.setID = fdici.setID;
fdin.psz2 = (CAB(mii).nextinfo) ? CAB(mii).nextinfo : &emptystring;
fdin.psz3 = pszCabPath;
- if (((*pfnfdin)(fdintCABINET_INFO, &fdin))) {
- PFDI_INT(hfdi)->perf->erfOper = FDIERROR_USER_ABORT;
- PFDI_INT(hfdi)->perf->erfType = 0;
- PFDI_INT(hfdi)->perf->fError = TRUE;
+ if (pfnfdin(fdintCABINET_INFO, &fdin) == -1) {
+ set_error( fdi, FDIERROR_USER_ABORT, 0 );
goto bail_and_fail;
}
/* read folders */
for (i = 0; i < fdici.cFolders; i++) {
- if (PFDI_READ(hfdi, cabhf, buf, cffold_SIZEOF) != cffold_SIZEOF) {
- PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
- PFDI_INT(hfdi)->perf->erfType = 0;
- PFDI_INT(hfdi)->perf->fError = TRUE;
+ if (fdi->read(cabhf, buf, cffold_SIZEOF) != cffold_SIZEOF) {
+ set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
goto bail_and_fail;
}
if (CAB(mii).folder_resv > 0)
- PFDI_SEEK(hfdi, cabhf, CAB(mii).folder_resv, SEEK_CUR);
+ fdi->seek(cabhf, CAB(mii).folder_resv, SEEK_CUR);
- fol = PFDI_ALLOC(hfdi, sizeof(struct fdi_folder));
+ fol = fdi->alloc(sizeof(struct fdi_folder));
if (!fol) {
ERR("out of memory!\n");
- PFDI_INT(hfdi)->perf->erfOper = FDIERROR_ALLOC_FAIL;
- PFDI_INT(hfdi)->perf->erfType = ERROR_NOT_ENOUGH_MEMORY;
- PFDI_INT(hfdi)->perf->fError = TRUE;
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY );
goto bail_and_fail;
}
ZeroMemory(fol, sizeof(struct fdi_folder));
/* read files */
for (i = 0; i < fdici.cFiles; i++) {
- if (PFDI_READ(hfdi, cabhf, buf, cffile_SIZEOF) != cffile_SIZEOF) {
- PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
- PFDI_INT(hfdi)->perf->erfType = 0;
- PFDI_INT(hfdi)->perf->fError = TRUE;
+ if (fdi->read(cabhf, buf, cffile_SIZEOF) != cffile_SIZEOF) {
+ set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
goto bail_and_fail;
}
- file = PFDI_ALLOC(hfdi, sizeof(struct fdi_file));
+ file = fdi->alloc(sizeof(struct fdi_file));
if (!file) {
ERR("out of memory!\n");
- PFDI_INT(hfdi)->perf->erfOper = FDIERROR_ALLOC_FAIL;
- PFDI_INT(hfdi)->perf->erfType = ERROR_NOT_ENOUGH_MEMORY;
- PFDI_INT(hfdi)->perf->fError = TRUE;
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY );
goto bail_and_fail;
}
ZeroMemory(file, sizeof(struct fdi_file));
file->time = EndGetI16(buf+cffile_Time);
file->date = EndGetI16(buf+cffile_Date);
file->attribs = EndGetI16(buf+cffile_Attribs);
- file->filename = FDI_read_string(hfdi, cabhf, fdici.cbCabinet);
+ file->filename = FDI_read_string(fdi, cabhf, fdici.cbCabinet);
if (!file->filename) {
- PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
- PFDI_INT(hfdi)->perf->erfType = 0;
- PFDI_INT(hfdi)->perf->fError = TRUE;
+ set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
goto bail_and_fail;
}
* where all the cabinet files needed for decryption are simultaneously
* available. But presumably, the API is supposed to support cabinets which
* are split across multiple CDROMS; we may need to change our implementation
- * to strictly serialize it's file usage so that it opens only one cabinet
+ * to strictly serialize its file usage so that it opens only one cabinet
* at a time. Some experimentation with Windows is needed to figure out the
* precise semantics required. The relevant code is here and in fdi_decomp().
*/
* if we imagine parallelized access to the FDICopy API.
*
* The current implementation punts -- it just returns the previous cabinet and
- * it's info from the header of this cabinet. This provides the right answer in
- * 95% of the cases; its worth checking if Microsoft cuts the same corner before
+ * its info from the header of this cabinet. This provides the right answer in
+ * 95% of the cases; it's worth checking if Microsoft cuts the same corner before
* we "fix" it.
*/
ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
fdin.psz2 = (CAB(mii).prevname) ? CAB(mii).prevname : &emptystring;
fdin.psz3 = (CAB(mii).previnfo) ? CAB(mii).previnfo : &emptystring;
- if (((*pfnfdin)(fdintPARTIAL_FILE, &fdin))) {
- PFDI_INT(hfdi)->perf->erfOper = FDIERROR_USER_ABORT;
- PFDI_INT(hfdi)->perf->erfType = 0;
- PFDI_INT(hfdi)->perf->fError = TRUE;
+ if (pfnfdin(fdintPARTIAL_FILE, &fdin) == -1) {
+ set_error( fdi, FDIERROR_USER_ABORT, 0 );
goto bail_and_fail;
}
/* I don't think we are supposed to decompress partial files. This prevents it. */
fdin.date = file->date;
fdin.time = file->time;
fdin.attribs = file->attribs;
+ fdin.iFolder = file->index;
if ((filehf = ((*pfnfdin)(fdintCOPY_FILE, &fdin))) == -1) {
- PFDI_INT(hfdi)->perf->erfOper = FDIERROR_USER_ABORT;
- PFDI_INT(hfdi)->perf->erfType = 0;
- PFDI_INT(hfdi)->perf->fError = TRUE;
+ set_error( fdi, FDIERROR_USER_ABORT, 0 );
filehf = 0;
goto bail_and_fail;
}
/* find the folder for this file if necc. */
if (filehf) {
- int i2;
-
fol = CAB(firstfol);
if ((file->index & cffileCONTINUED_TO_NEXT) == cffileCONTINUED_TO_NEXT) {
/* pick the last folder */
while (fol->next) fol = fol->next;
} else {
+ unsigned int i2;
+
for (i2 = 0; (i2 < file->index); i2++)
if (fol->next) /* bug resistance, should always be true */
fol = fol->next;
TRACE("Extracting file %s as requested by callee.\n", debugstr_a(file->filename));
/* set up decomp_state */
- CAB(hfdi) = hfdi;
+ CAB(fdi) = fdi;
CAB(filehf) = filehf;
/* Was there a change of folder? Compression type? Did we somehow go backwards? */
TRACE("Resetting folder for file %s.\n", debugstr_a(file->filename));
- /* free stuff for the old decompresser */
+ /* free stuff for the old decompressor */
switch (ct2) {
case cffoldCOMPTYPE_LZX:
if (LZX(window)) {
- PFDI_FREE(hfdi, LZX(window));
+ fdi->free(LZX(window));
LZX(window) = NULL;
}
break;
case cffoldCOMPTYPE_QUANTUM:
if (QTM(window)) {
- PFDI_FREE(hfdi, QTM(window));
+ fdi->free(QTM(window));
QTM(window) = NULL;
}
break;
}
CAB(decomp_cab) = NULL;
- PFDI_SEEK(CAB(hfdi), CAB(cabhf), fol->offset, SEEK_SET);
+ CAB(fdi)->seek(CAB(cabhf), fol->offset, SEEK_SET);
CAB(offset) = 0;
CAB(outlen) = 0;
- /* initialize the new decompresser */
+ /* initialize the new decompressor */
switch (ct1) {
case cffoldCOMPTYPE_NONE:
CAB(decompress) = NONEfdi_decomp;
case DECR_OK:
break;
case DECR_NOMEMORY:
- PFDI_INT(hfdi)->perf->erfOper = FDIERROR_ALLOC_FAIL;
- PFDI_INT(hfdi)->perf->erfType = ERROR_NOT_ENOUGH_MEMORY;
- PFDI_INT(hfdi)->perf->fError = TRUE;
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY );
goto bail_and_fail;
default:
- PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
- PFDI_INT(hfdi)->perf->erfOper = 0;
- PFDI_INT(hfdi)->perf->fError = TRUE;
+ set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
goto bail_and_fail;
}
case DECR_OK:
break;
case DECR_USERABORT:
- PFDI_INT(hfdi)->perf->erfOper = FDIERROR_USER_ABORT;
- PFDI_INT(hfdi)->perf->erfType = 0;
- PFDI_INT(hfdi)->perf->fError = TRUE;
+ set_error( fdi, FDIERROR_USER_ABORT, 0 );
goto bail_and_fail;
case DECR_NOMEMORY:
- PFDI_INT(hfdi)->perf->erfOper = FDIERROR_ALLOC_FAIL;
- PFDI_INT(hfdi)->perf->erfType = ERROR_NOT_ENOUGH_MEMORY;
- PFDI_INT(hfdi)->perf->fError = TRUE;
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY );
goto bail_and_fail;
default:
- PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
- PFDI_INT(hfdi)->perf->erfOper = 0;
- PFDI_INT(hfdi)->perf->fError = TRUE;
+ set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
goto bail_and_fail;
}
CAB(offset) = file->offset;
fdin.pv = pvUser;
fdin.psz1 = (char *)file->filename;
fdin.hf = filehf;
- fdin.cb = (file->attribs & cffile_A_EXEC) ? TRUE : FALSE; /* FIXME: is that right? */
+ fdin.cb = (file->attribs & cffile_A_EXEC) != 0; /* FIXME: is that right? */
fdin.date = file->date;
fdin.time = file->time;
fdin.attribs = file->attribs; /* FIXME: filter _A_EXEC? */
+ fdin.iFolder = file->index;
((*pfnfdin)(fdintCLOSE_FILE_INFO, &fdin));
filehf = 0;
case DECR_OK:
break;
case DECR_USERABORT:
- PFDI_INT(hfdi)->perf->erfOper = FDIERROR_USER_ABORT;
- PFDI_INT(hfdi)->perf->erfType = 0;
- PFDI_INT(hfdi)->perf->fError = TRUE;
+ set_error( fdi, FDIERROR_USER_ABORT, 0 );
goto bail_and_fail;
case DECR_NOMEMORY:
- PFDI_INT(hfdi)->perf->erfOper = FDIERROR_ALLOC_FAIL;
- PFDI_INT(hfdi)->perf->erfType = ERROR_NOT_ENOUGH_MEMORY;
- PFDI_INT(hfdi)->perf->fError = TRUE;
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ set_error( fdi, FDIERROR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY );
goto bail_and_fail;
default:
- PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CORRUPT_CABINET;
- PFDI_INT(hfdi)->perf->erfOper = 0;
- PFDI_INT(hfdi)->perf->fError = TRUE;
+ set_error( fdi, FDIERROR_CORRUPT_CABINET, 0 );
goto bail_and_fail;
}
}
}
- free_decompression_temps(hfdi, fol, decomp_state);
- free_decompression_mem(hfdi, decomp_state, file);
+ if (fol) free_decompression_temps(fdi, fol, decomp_state);
+ free_decompression_mem(fdi, decomp_state);
return TRUE;
bail_and_fail: /* here we free ram before error returns */
- if (fol) free_decompression_temps(hfdi, fol, decomp_state);
+ if (fol) free_decompression_temps(fdi, fol, decomp_state);
- if (filehf) PFDI_CLOSE(hfdi, filehf);
+ if (filehf) fdi->close(filehf);
- free_decompression_mem(hfdi, decomp_state, file);
+ free_decompression_mem(fdi, decomp_state);
return FALSE;
}
*/
BOOL __cdecl FDIDestroy(HFDI hfdi)
{
- TRACE("(hfdi == ^%p)\n", hfdi);
- if (REALLY_IS_FDI(hfdi)) {
- PFDI_INT(hfdi)->FDI_Intmagic = 0; /* paranoia */
- PFDI_FREE(hfdi, hfdi); /* confusing, but correct */
+ FDI_Int *fdi = get_fdi_ptr( hfdi );
+
+ TRACE("(hfdi == ^%p)\n", hfdi);
+ if (!fdi) return FALSE;
+ fdi->magic = 0; /* paranoia */
+ fdi->free(fdi);
return TRUE;
- } else {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
}
/***********************************************************************
char *pszCabinetName,
USHORT iFolderToDelete)
{
+ FDI_Int *fdi = get_fdi_ptr( hfdi );
+
FIXME("(hfdi == ^%p, pszCabinetName == %s, iFolderToDelete == %hu): stub\n",
hfdi, debugstr_a(pszCabinetName), iFolderToDelete);
- if (!REALLY_IS_FDI(hfdi)) {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
+ if (!fdi) return FALSE;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;