summaryrefslogtreecommitdiffstats
path: root/private/windows/diamond/chuck/buildfol.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/windows/diamond/chuck/buildfol.c')
-rw-r--r--private/windows/diamond/chuck/buildfol.c764
1 files changed, 764 insertions, 0 deletions
diff --git a/private/windows/diamond/chuck/buildfol.c b/private/windows/diamond/chuck/buildfol.c
new file mode 100644
index 000000000..93378aa42
--- /dev/null
+++ b/private/windows/diamond/chuck/buildfol.c
@@ -0,0 +1,764 @@
+/*** buildfol.c - Diamond Folder Builder
+ *
+ * Author:
+ * Chuck Strouss
+ *
+ * History:
+ * 01-Dec-1993 chuckst Initial version
+ * 01-Dec-1993 chuckst Now requires only two output files
+ * 03-Dec-1993 chuckst Implemented FCC blocks
+ * 09-Jan-1994 chuckst Renamed from FCI.C, FCI.C will be the
+ * higher level calls.
+ * 15-Mar-1994 bens Add tempfile index enumeration; RESERVE work
+ * 01-Jun-1994 bens Add Quantum support
+ */
+
+#include <memory.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys\types.h>
+#include <sys\stat.h>
+#include <io.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include "types.h"
+#include "asrt.h"
+#include "fci_int.h"
+#include "cabinet.h"
+#include "erf.h"
+#include "..\mszip\mci.h"
+#include "..\quantum\qci.h"
+
+#include "buildcab.h"
+#include "checksum.h"
+
+
+//*** Internal function prototypes
+
+BOOL WriteCFDATABlock (PFOL pfol,
+ PFNFCISTATUS pfnProgress,
+ void *pv);
+
+BOOL MCIResetCompressionGlobal(PFOL pfol);
+BOOL MCICreateCompressionGlobal(PFOL pfol);
+BOOL MCIDestroyCompressionGlobal(PFOL pfol);
+BOOL MCICompressGlobal(PFOL pfol, USHORT *pcbData);
+
+
+/*** FolderInit - Initialize for folder creation
+ *
+ */
+HFOL FolderInit(PERF perf, // error type return structure
+ PFNALLOC pfnalloc, // memory allocation function
+ PFNFREE pfnfree, // memory free function
+ PFNFCIGETTEMPFILE pfntemp, // generate temp file name
+ UINT cbCFDataPlusReserve
+ )
+{
+ PFOL pfol;
+
+ pfol = (PFOL)pfnalloc(sizeof (FOL));
+ if (pfol == NULL) {
+ ErfSetCodes(perf,FCIERR_ALLOC_FAIL,0);
+ return NULL;
+ }
+
+ SetAssertSignature(pfol,sigFOL);
+ AssertFOL(pfol); // Make sure we've really set sig
+
+ pfol->perf = perf; // Save away error pointer
+ pfol->pfnfree = pfnfree; // Save free function in our context
+ pfol->pfnalloc = pfnalloc; // Save alloc function in our context
+ pfol->pchCompr = NULL; // Simplify error cleanup
+ pfol->pchUncompr = NULL; // Simplify error cleanup
+ pfol->typeCompress = tcompBAD; // No compressor initialized yet
+
+ pfol->cbCFDataPlusReserve = cbCFDataPlusReserve;
+
+ if (!CrTempFiles(pfol->tf,NUM_FOLDER_TF,pfntemp,pfol->perf)) {
+ FolderDestroy(pfol); // clean up
+ return NULL;
+ }
+
+ pfol->uoffNext = 0; // keep track of uncompressed size.
+ pfol->cbBuffered = 0; // Nothing currently in our buffer
+
+ return HFOLfromPFOL(pfol);
+} /* FolderInit() */
+
+
+/*** AddFileToFolder -- add a source file into the current folder
+ *
+ * Entry:
+ * parameters noted below
+ *
+ * Exit success:
+ * Returns TRUE
+ *
+ * Exit failure:
+ * Returns FALSE
+ * error structure indicates error type
+ * files closed, context deleted
+ */
+int AddFileToFolder(
+ HFOL hfol, // compression context
+ char *pszSourceFile, // filename to get new data from
+ char *pszFileName, // name to store into CAB file
+ BOOL fExecute, // Set Execute on extract
+ PFNFCISTATUS pfnProgress, // Progress callback
+ PFNFCIGETOPENINFO pfnOpenInfo, // Open file, get info callback
+ TCOMP typeCompress, // compression setting
+ void *pv) // context pointer for callbacks
+{
+ PFOL pfol;
+ int hfInput;
+ int cbRead;
+ CFFILE cff;
+
+ pfol = PFOLfromHFOL(hfol);
+ AssertFOL (pfol); // verify structure signature
+ cff.uoffFolderStart = pfol->uoffNext; // save file start
+ cff.iFolder = 0; // folder numbers filled in at
+
+ if (-1 == (hfInput = pfnOpenInfo(pszSourceFile,
+ &cff.date,
+ &cff.time,
+ &cff.attribs,
+ pv))) {
+ ErfSetCodes(pfol->perf,FCIERR_OPEN_SRC,errno); // set error
+ return FALSE; // fatal error
+ }
+
+ // Overloading this flag -- if it's actually used we're in trouble
+ Assert( !(cff.attribs & RUNATTRIB) );
+ if (fExecute) {
+ cff.attribs |= RUNATTRIB;
+ }
+
+ while ((cbRead = _read(hfInput,
+ &(pfol->pchUncompr[pfol->cbBuffered]),
+ pfol->cbSrcBuffer-pfol->cbBuffered)) !=0 ) {
+ if (cbRead == -1) { // Read error
+ ErfSetCodes(pfol->perf,FCIERR_READ_SRC,errno);
+ goto error;
+ }
+ pfol->uoffNext += (unsigned)cbRead;
+ pfol->cbBuffered += (unsigned)cbRead;
+ //** If we filled up the buffer, compress it and write it
+ if (pfol->cbBuffered == pfol->cbSrcBuffer) {
+ // Compress, write, give progress reports
+ if (!WriteCFDATABlock(pfol,pfnProgress,pv)) {
+ goto error; // error already filled in
+ }
+ }
+ }
+ //** Done reading this file
+ _close(hfInput);
+
+ //** Write out the CFFILE structure to the temp file
+ cff.cbFile = pfol->uoffNext - cff.uoffFolderStart;
+ if (!WriteCount(&pfol->tf[iftfCFFOLDER],
+ &cff,
+ sizeof(cff),
+ pfol->perf)
+ || !WritePszTmp(&pfol->tf[iftfCFFOLDER],
+ pszFileName,
+ pfol->perf)) {
+ goto error;
+ }
+
+ //** Success
+ return TRUE;
+
+error:
+ if (hfInput != -1) {
+ _close(hfInput);
+ }
+ return FALSE;
+}
+
+
+/*** FolderFlush - Flush buffers, reset MCI compressor
+ *
+ * Entry:
+ * hfol -- handle to folder context
+ * pfnProgress -- Progress callbacks go here
+ * pv -- original caller's callback context
+ *
+ * Exit-success:
+ * returns TRUE
+ *
+ * Exit-failure:
+ * returns FALSE
+ * error structure in pfol filled in
+ */
+BOOL FolderFlush (HFOL hfol,PFNFCISTATUS pfnProgress,void *pv)
+{
+ PFOL pfol;
+ BOOL rc;
+
+ pfol = PFOLfromHFOL (hfol);
+ AssertFOL (pfol);
+
+ //** flush the last buffer, if any
+ rc = WriteCFDATABlock(pfol,pfnProgress,pv);
+ if (!MCIResetCompressionGlobal(pfol)) { // reset the compressor
+ return FALSE; // error already filled in
+ }
+
+ pfol->uoffNext = 0; // keep track of uncompressed size.
+ return rc; // error already filled in
+}
+
+
+/*** FolderDestroy - Deletes temp files and destroy a folder context
+ *
+ * Entry:
+ * hfol -- folder context
+ *
+ * Exit-Success:
+ * returns TRUE
+ *
+ * Exit-Failure:
+ * returns FALSE, error struct filled in
+ */
+BOOL FolderDestroy (HFOL hfol)
+{
+
+ PFOL pfol;
+ BOOL fOK;
+
+ pfol = PFOLfromHFOL (hfol);
+ AssertFOL (pfol);
+
+ SetCompressionType(tcompBAD,pfol); // clear out compressor
+
+ fOK = NukeTempFiles(pfol->tf,NUM_FOLDER_TF,pfol->perf);
+
+ ClearAssertSignature(pfol);
+ (*pfol->pfnfree)(pfol);
+ return fOK;
+}
+
+
+/*** SetCompressionType -- initializes a new compressor
+ *
+ * Entry:
+ * typeCompress - New compression type (tcompBAD to term w/ no new)
+ * pfol - Folder context structure
+ *
+ * Exit-Success:
+ * returns TRUE;
+ *
+ * Exit-Failure:
+ * returns FALSE, error structure filled in
+ */
+BOOL SetCompressionType(TCOMP typeCompress,PFOL pfol)
+{
+//BUGBUG 15-Mar-1994 bens What if new type is same as old type?
+ if (!MCIDestroyCompressionGlobal(pfol)) {
+ return FALSE; // error already filled in
+ }
+
+ pfol->typeCompress = typeCompress; // update current compression type
+
+ if (!MCICreateCompressionGlobal(pfol)) {
+ return FALSE; // error already filled in
+ }
+
+ return TRUE;
+}
+
+
+/*** WriteCFDATABlock - write out a CFDATA block to current .CFD file
+ *
+ * Entry:
+ * pfol - pointer to folder structure
+ * pfnProgress - issue Progress callbacks to this function
+ * pv - context to pass to Progress callbacks
+ *
+ * Exit-Success:
+ * Returns TRUE
+ *
+ * Exit-Failure:
+ * Returns FALSE; error structure filled in
+ */
+BOOL WriteCFDATABlock (PFOL pfol, PFNFCISTATUS pfnProgress, void *pv)
+{
+ CFDATA *pcfdata=NULL;
+
+ AssertFOL (pfol);
+
+ if (pfol->cbBuffered == 0) {
+ return TRUE; // done if nothing to write
+ }
+
+ if (!(pcfdata = (*pfol->pfnalloc)(pfol->cbCFDataPlusReserve))) {
+ ErfSetCodes(pfol->perf,FCIERR_ALLOC_FAIL,0);
+ return FALSE;
+ }
+ //** Zero reserved area (and rest of CFDATA structure, too)
+ memset(pcfdata,0,pfol->cbCFDataPlusReserve);
+
+ if (!MCICompressGlobal(pfol,&(pcfdata->cbData))) {
+ goto error; // error struct already filled in
+ }
+
+// Generate the CFDATA structure that will be prepended to the actual
+// data on the disk. Notice that we will not fill in the checksum until
+// later, when this record is copied to the cabinet. This works better
+// because there are times when a CFDATA block ends up being split
+// between two cabinets.
+
+ pcfdata->cbUncomp = pfol->cbBuffered;
+
+ if (!WriteCount(&pfol->tf[iftfCFDATA],
+ pcfdata,
+ pfol->cbCFDataPlusReserve,
+ pfol->perf)
+ || !WriteCount(&pfol->tf[iftfCFDATA],
+ pfol->pchCompr,
+ pcfdata->cbData,
+ pfol->perf)) {
+ goto error; // Error already filled in
+ }
+
+ if (-1 == pfnProgress(statusFile, // type of Progress callback
+ pcfdata->cbData, // Compressed size
+ pfol->cbBuffered, // Uncompressed size
+ pv)) { // context pointer
+ ErfSetCodes(pfol->perf,FCIERR_USER_ABORT,0);
+ goto error;
+ }
+
+ pfol->cbBuffered = 0; // Folder is empty
+ (*pfol->pfnfree)(pcfdata); // Free resources
+ return TRUE;
+
+error:
+ //** Clean up and exit
+ if (pcfdata) {
+ (*pfol->pfnfree)(pcfdata);
+ }
+ return FALSE;
+}
+
+
+// The following routines are use for manipulating temporary files
+
+/*** CrTempFiles -- creates temporary files and opens them for writing
+ *
+ * Entry:
+ * ptf -- pointer to an array of temp file structures
+ * ctf -- count of temp files to init
+ * pfntemp -- callback for generating a temp filename
+ * perf -- error code structure
+ *
+ * Exit-success:
+ * return value is TRUE
+ * ptf->szName has name of open file
+ * ptf->hf has file handle
+ * ptf->cb length field init'd to 0
+ *
+ * Exit-failure:
+ * return code FALSE, error structure filled in
+ *
+ */
+
+BOOL CrTempFiles(TF *ptf,
+ int ctf,
+ PFNFCIGETTEMPFILE pfntemp,
+ PERF perf)
+{
+ int tfIndex;
+ int iRetry;
+
+ for (tfIndex=0; tfIndex<ctf; tfIndex++) {
+ ptf[tfIndex].hf = -1; // init all temp file handles to -1
+ ptf[tfIndex].cb = 0; // length == empty
+ }
+
+ for (tfIndex=0; tfIndex< ctf;tfIndex++)
+ {
+
+ iRetry = 11; // Try 10 times to create a temp file
+ while ((ptf[tfIndex].hf == -1) && iRetry--) {
+ if (pfntemp(ptf[tfIndex].szName,sizeof(ptf[tfIndex].szName))) {
+ //** Create file, must not already exists
+ ptf[tfIndex].hf = _open(ptf[tfIndex].szName,
+ _O_CREAT | _O_EXCL | _O_BINARY | _O_RDWR,
+ _S_IREAD | _S_IWRITE );
+ }
+ }
+ //** Were we able to create the temp file?
+ if (ptf[tfIndex].hf == -1) {
+ ErfSetCodes(perf,FCIERR_TEMP_FILE,errno);
+ goto error;
+ }
+ }
+
+ //** Success
+ return TRUE;
+
+error:
+ //** Close and destroy any files we created
+ for (tfIndex=0; tfIndex<ctf; tfIndex++) {
+ if (ptf[tfIndex].hf != -1) {
+ _close(ptf[tfIndex].hf);
+ _unlink(ptf[tfIndex].szName);
+ }
+ }
+ return FALSE;
+}
+
+
+/*** NukeTempFiles -- close and delete open temp files
+ *
+ * Entry:
+ * ptf -- points to an open temp file structure array
+ * ctf -- number of files to nuke
+ * perf -- error structure
+ *
+ * Exit-success:
+ * return TRUE
+ * temp files closed and deleted
+ *
+ * Exit-failure:
+ * return FALSE, error structure filled in
+ */
+BOOL NukeTempFiles(TF *ptf,int ctf,PERF perf)
+{
+
+ BOOL fOK=TRUE;
+ int tfIndex;
+
+ //** Close and delete temp files; we record an error occurence, but
+ // continue going because we want to close and delete as many as
+ // possible.
+ for (tfIndex=0; tfIndex<ctf; tfIndex++)
+ {
+ if (_close(ptf[tfIndex].hf)) {
+ ErfSetCodes(perf,FCIERR_TEMP_FILE,errno);
+ fOK = FALSE;
+ }
+ ptf[tfIndex].hf = -1; // file no longer open
+
+ if (-1 == _unlink(ptf[tfIndex].szName)) {
+ ErfSetCodes(perf,FCIERR_TEMP_FILE,errno);
+ fOK = FALSE;
+ }
+ }
+
+ return fOK;
+}
+
+
+/*** WriteCount -- Write into temp file, count bytes
+ *
+ * Entry:
+ * ptf - pointer to temp file structure
+ * pv - buffer pointer
+ * cb - count to write
+ * perf - error structure
+ *
+ * Exit-Success:
+ * Returns TRUE if the write occurred properly
+ *
+ * Exit-Failure:
+ * Returns FALSE, error struct fille din
+ */
+int WriteCount(TF *ptf,
+ const void *pv,
+ unsigned int cb,
+ PERF perf)
+{
+ ptf->cb += cb; // keep track of how much we've written
+ if (cb != (unsigned)_write(ptf->hf,pv,cb))
+ {
+ ErfSetCodes(perf,FCIERR_TEMP_FILE,0);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/*** WritePszTmp -- writes a psz string to temp file
+ *
+ * Entry:
+ * ptf - pointer to temp file structure
+ * psz - string to write
+ * perf - error structure
+ *
+ * Exit-Success:
+ * returns TRUE
+ *
+ * Exit-Failure:
+ * returns FALSE, error struct filled in (TEMP file error)
+ */
+BOOL WritePszTmp(TF *ptf,char *psz,PERF perf)
+{
+ return WriteCount(ptf,psz,1+strlen(psz),perf);
+}
+
+
+/*** MCIDestroyCompressionGlobal -- Destroy the currently selected compressor
+ *
+ * Entry:
+ * pfol - Pointer to folder context
+ *
+ * Exit-Success:
+ * returns TRUE
+ *
+ * Exit-Failure:
+ * returns FALSE, error structure filled in
+ */
+BOOL MCIDestroyCompressionGlobal(PFOL pfol)
+{
+ BOOL fOK=TRUE;
+
+ switch(CompressionTypeFromTCOMP(pfol->typeCompress)) {
+ case tcompBAD: // no existing compression
+ break; // nothing to do
+
+ case tcompTYPE_NONE:
+ break; //no action needed for null compressor
+
+ case tcompTYPE_MSZIP:
+ if (MCI_ERROR_NO_ERROR != MCIDestroyCompression(pfol->mch)) {
+ ErfSetCodes(pfol->perf,FCIERR_MCI_FAIL,0);
+ fOK = FALSE;
+ }
+ break;
+
+#ifndef BIT16
+ case tcompTYPE_QUANTUM:
+ if (MCI_ERROR_NO_ERROR != QCIDestroyCompression(pfol->mch)) {
+ ErfSetCodes(pfol->perf,FCIERR_MCI_FAIL,0);
+ fOK = FALSE;
+ }
+ break;
+#endif
+
+ default:
+ ErfSetCodes(pfol->perf,FCIERR_BAD_COMPR_TYPE,0);
+ }
+
+ //** Now free the buffers
+ if (pfol->pchCompr) {
+ (*pfol->pfnfree)(pfol->pchCompr);
+ pfol->pchCompr = NULL; // Simplify error cleanup
+ }
+
+ if (pfol->pchUncompr) {
+ (*pfol->pfnfree)(pfol->pchUncompr);
+ pfol->pchUncompr = NULL; // Simplify error cleanup
+ }
+
+ return fOK;
+}
+
+
+/*** MCICreateCompressionGlobal -- Create the currently selected compressor
+ *
+ * Entry:
+ * pfol - Pointer to folder context
+ *
+ * Exit-Success:
+ * Returns TRUE
+ *
+ * Exit-Failure:
+ * Returns FALSE, error structure filled in
+ */
+BOOL MCICreateCompressionGlobal(PFOL pfol)
+{
+#ifndef BIT16
+ QUANTUMCONFIGURATION qcfg;
+#endif
+
+ pfol->cbSrcBuffer = CB_MAX_CHUNK;
+ pfol->pchCompr = NULL; // Simplify error cleanup
+ pfol->pchUncompr = NULL; // Simplify error cleanup
+
+ switch(CompressionTypeFromTCOMP(pfol->typeCompress)) {
+ case tcompBAD: // no new compressor
+ return TRUE; // all done if no compressor enabled
+
+ case tcompTYPE_NONE:
+ pfol->cbDstBuffer = pfol->cbSrcBuffer;
+ break;
+
+ case tcompTYPE_MSZIP:
+ if (MCI_ERROR_NO_ERROR != MCICreateCompression(&pfol->cbSrcBuffer,
+ pfol->pfnalloc,
+ pfol->pfnfree,
+ &pfol->cbDstBuffer,
+ &pfol->mch)) {
+ ErfSetCodes(pfol->perf,FCIERR_MCI_FAIL,0);
+ return FALSE;
+ }
+ break;
+
+#ifndef BIT16
+ case tcompTYPE_QUANTUM:
+ qcfg.CompressionLevel = CompressionLevelFromTCOMP(pfol->typeCompress);
+ qcfg.WindowBits = CompressionMemoryFromTCOMP(pfol->typeCompress);
+//BUGBUG 01-Jun-1994 bens What is 3rd member of QCICreate structure
+ qcfg.HackHack = -1; // Why?
+ if (MCI_ERROR_NO_ERROR != QCICreateCompression(&pfol->cbSrcBuffer,
+ &qcfg,
+ pfol->pfnalloc,
+ pfol->pfnfree,
+ &pfol->cbDstBuffer,
+ &pfol->mch)) {
+ ErfSetCodes(pfol->perf,FCIERR_MCI_FAIL,0);
+ return FALSE;
+ }
+ break;
+#endif
+
+ default:
+ ErfSetCodes(pfol->perf,FCIERR_BAD_COMPR_TYPE,0);
+ return FALSE;
+ }
+
+ //** Now allocate whatever buffers the selected compressor requested
+ if (NULL == (pfol->pchCompr=(char *)pfol->pfnalloc(pfol->cbDstBuffer))) {
+ ErfSetCodes(pfol->perf,FCIERR_ALLOC_FAIL,0);
+ goto error;
+ }
+
+ if (NULL == (pfol->pchUncompr=(char *)pfol->pfnalloc(pfol->cbSrcBuffer))) {
+ ErfSetCodes(pfol->perf,FCIERR_ALLOC_FAIL,0);
+ goto error;
+ }
+
+ return TRUE;
+
+error:
+ MCIDestroyCompressionGlobal(pfol); // Clean up
+ return FALSE; // Failure
+}
+
+
+/*** MCIResetCompressionGlobal -- reset the currently selected compressor
+ *
+ * Entry:
+ * pfol -- pointer to folder context
+ *
+ * Exit-success:
+ * returns TRUE
+ *
+ * Exit-failure:
+ * returns FALSE, error structure filled in
+ */
+BOOL MCIResetCompressionGlobal(PFOL pfol)
+{
+ switch(CompressionTypeFromTCOMP(pfol->typeCompress)) {
+ case tcompBAD:
+ case tcompTYPE_NONE:
+ break; // no action for null compressor or none installed
+
+ case tcompTYPE_MSZIP:
+ if (MCI_ERROR_NO_ERROR != MCIResetCompression(pfol->mch)) {
+ ErfSetCodes(pfol->perf,FCIERR_MCI_FAIL,0);
+ return FALSE;
+ }
+ break;
+
+#ifndef BIT16
+ case tcompTYPE_QUANTUM:
+ if (MCI_ERROR_NO_ERROR != QCIResetCompression(pfol->mch)) {
+ ErfSetCodes(pfol->perf,FCIERR_MCI_FAIL,0);
+ return FALSE;
+ }
+ break;
+#endif
+
+ default:
+ ErfSetCodes(pfol->perf,FCIERR_BAD_COMPR_TYPE,0);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/*** MCICompressGlobal -- Compress with the currently selected compressor
+ *
+ * Entry:
+ * pfol - Pointer to folder context
+ * cbData - Location to return the compressed size
+ *
+ * Exit-Success:
+ * Returns TRUE
+ *
+ * Exit-Failure:
+ * Returns FALSE, error filled in
+ */
+BOOL MCICompressGlobal(PFOL pfol,USHORT *pcbData)
+{
+ UINT cbData;
+
+ switch(CompressionTypeFromTCOMP(pfol->typeCompress)) {
+ case tcompTYPE_NONE:
+ memcpy(pfol->pchCompr,pfol->pchUncompr,*pcbData=pfol->cbBuffered);
+ break;
+
+ case tcompTYPE_MSZIP:
+ if (MCI_ERROR_NO_ERROR != MCICompress(pfol->mch,
+ pfol->pchUncompr,
+ pfol->cbBuffered,
+ pfol->pchCompr,
+ pfol->cbDstBuffer,
+ &cbData)) {
+ ErfSetCodes(pfol->perf,FCIERR_MCI_FAIL,0);
+ return FALSE;
+ }
+ //** Step down
+ *pcbData = (USHORT)cbData;
+ break;
+
+#ifndef BIT16
+ case tcompTYPE_QUANTUM:
+ if (MCI_ERROR_NO_ERROR != QCICompress(pfol->mch,
+ pfol->pchUncompr,
+ pfol->cbBuffered,
+ pfol->pchCompr,
+ pfol->cbDstBuffer,
+ &cbData)) {
+ ErfSetCodes(pfol->perf,FCIERR_MCI_FAIL,0);
+ return FALSE;
+ }
+ //** Step down
+ *pcbData = (USHORT)cbData;
+ break;
+#endif
+
+ default:
+ ErfSetCodes(pfol->perf,FCIERR_BAD_COMPR_TYPE,0);
+ return FALSE; // Fatal error -- no valid compressor initialized
+ }
+
+#ifndef REMOVE_CHICAGO_M6_HACK
+//BUGBUG 18-May-1994 bens Hack for Chicago M6
+// AndyHi & Co. are very risk averse, and so do not want to pick up a
+// version of FDI.LIB newer than 302. Unfortunately, 302 has a bug
+// in both FCI.LIB and FDI.LIB that cause diamond.exe to Assert() when
+// an incompressible block is generated, and cause extract.exe (fdi.lib,
+// really) to detect corrupted compressed data when an incompressible
+// block is encountered.
+//
+// So, FCI has a temporary option to detect and fail when incompressible
+// data is encountered, and DIAMOND.EXE has a switch to turn on this
+// checking! Once Chicago M6 is released, we can destroy all this code!
+//
+ //** Check for incompressible data and fail if told to do so;
+ if ((pfol->fFailOnIncompressible) && // Fail if incompressible
+ (cbData > pfol->cbSrcBuffer)) { // Output bigger than source buffer
+ ErfSetCodes(pfol->perf,FCIERR_M6_HACK_INCOMPRESSIBLE,0);
+ return FALSE; // Fatal error -- no valid compressor initialized
+ }
+#endif
+
+ return TRUE;
+}