OK, I couldn't resist. Performance enhancement patch. This one allows cabinet to remember its place, avoiding (sometimes) lots and lots of unnecessary processing. License: LGPL ChangeLog: * dlls/cabinet: fdi.c: Greg Turner <gmturner007@ameritech.net> - remember decompression state during extraction, so as to avoid unnecessary work. -- diff -ur --minimal --exclude-from=/home/greg/bin/winetreediff_excl ../wine.test/dlls/cabinet/fdi.c ./dlls/cabinet/fdi.c --- ../wine.test/dlls/cabinet/fdi.c 2003-07-29 17:14:35.000000000 -0500 +++ ./dlls/cabinet/fdi.c 2003-07-29 17:31:48.000000000 -0500 @@ -2216,6 +2216,7 @@ if (filehf) { cab_UWORD comptype = fol->comp_type; int ct1 = comptype & cffoldCOMPTYPE_MASK; + int ct2 = CAB(current) ? (CAB(current)->comp_type & cffoldCOMPTYPE_MASK) : 0; int err = 0; TRACE("Extracting file %s as requested by callee.\n", debugstr_a(file->filename)); @@ -2224,11 +2225,35 @@ CAB(hfdi) = hfdi; CAB(filehf) = filehf; CAB(cabhf) = cabhf; - CAB(current) = fol; - CAB(decomp_cab) = NULL; - /* set up the appropriate decompressor */ - switch (ct1) { + /* Was there a change of folder? Compression type? Did we somehow go backwards? */ + if ((ct1 != ct2) || (CAB(current) != fol) || (file->offset < CAB(offset))) { + + TRACE("Resetting folder for file %s.\n", debugstr_a(file->filename)); + + /* free stuff for the old decompressor */ + switch (ct2) { + case cffoldCOMPTYPE_LZX: + if (LZX(window)) { + PFDI_FREE(hfdi, LZX(window)); + LZX(window) = NULL; + } + break; + case cffoldCOMPTYPE_QUANTUM: + if (QTM(window)) { + PFDI_FREE(hfdi, QTM(window)); + QTM(window) = NULL; + } + break; + } + + CAB(decomp_cab) = NULL; + PFDI_SEEK(CAB(hfdi), CAB(cabhf), fol->offset, SEEK_SET); + CAB(offset) = 0; + CAB(outlen) = 0; + + /* initialize the new decompressor */ + switch (ct1) { case cffoldCOMPTYPE_NONE: CAB(decompress) = NONEfdi_decomp; break; @@ -2245,8 +2270,11 @@ break; default: err = DECR_DATAFORMAT; + } } + CAB(current) = fol; + switch (err) { case DECR_OK: break; @@ -2263,10 +2291,6 @@ goto bail_and_fail; } - PFDI_SEEK(CAB(hfdi), CAB(cabhf), fol->offset, SEEK_SET); - CAB(offset) = 0; - CAB(outlen) = 0; - if (file->offset > CAB(offset)) { /* decode bytes and send them to /dev/null */ switch ((err = fdi_decomp(file, 0, decomp_state, pszCabPath, pfnfdin, pvUser))) { @@ -2317,24 +2341,6 @@ goto bail_and_fail; } - /* free decompression temps */ - switch (ct1) { - case cffoldCOMPTYPE_LZX: - if (LZX(window)) { - PFDI_FREE(hfdi, LZX(window)); - LZX(window) = NULL; - } - break; - case cffoldCOMPTYPE_QUANTUM: - if (QTM(window)) { - PFDI_FREE(hfdi, QTM(window)); - QTM(window) = NULL; - } - break; - default: - break; - } - /* fdintCLOSE_FILE_INFO notification */ ZeroMemory(&fdin, sizeof(FDINOTIFICATION)); fdin.pv = pvUser; @@ -2359,6 +2365,16 @@ } } + /* free decompression temps */ + if (LZX(window)) { + PFDI_FREE(hfdi, LZX(window)); + LZX(window) = NULL; + } + if (QTM(window)) { + PFDI_FREE(hfdi, QTM(window)); + QTM(window) = NULL; + } + while (decomp_state) { fdi_decomp_state *prev_fds; @@ -2391,6 +2407,16 @@ bail_and_fail: /* here we free ram before error returns */ + /* free decompression temps */ + if (LZX(window)) { + PFDI_FREE(hfdi, LZX(window)); + LZX(window) = NULL; + } + if (QTM(window)) { + PFDI_FREE(hfdi, QTM(window)); + QTM(window) = NULL; + } + while (decomp_state) { fdi_decomp_state *prev_fds; -- gmt "Deorum injuriae Diis curae" (trans: "Leave offenses against the gods to the care of the gods") - Tacitus