Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

305 lines
9.2 KiB

/*
* Microsoft Confidential
* Copyright (C) Microsoft Corporation 1994
* All Rights Reserved.
*
* MCI.C: Memory Compression Interface
*
* History:
* 20-Jan-1994 msliger Initial version (stub).
* 23-Jan-1994 msliger Real version (not a stub).
* 11-Feb-1994 msliger Changed M*ICreate() to adjust size.
* 13-Feb-1994 msliger revised type names, ie, UINT16 -> UINT.
* changed handles to HANDLEs.
* normalized MCI_MEMORY type.
* 24-Feb-1994 msliger Changed alloc,free to common typedefs.
* Changed MCI_MEMORY to MI_MEMORY.
* Restructured allocation/destruction.
* 15-Mar-1994 msliger Changes for 32 bits.
* 22-Mar-1994 msliger Changed interface USHORT to UINT.
* 26-Sep-1994 msliger Made FAR's match MCI.H.
*/
/* --- preprocessor ------------------------------------------------------- */
#include <stdio.h> /* for NULL */
#include <string.h> /* for memcpy() */
#include "mci.h" /* types, prototype verification, error codes */
#include "nfmcomp.h" /* features of NFMCOMP.C */
/* MAKE_SIGNATURE - Construct a structure signature
*
* Entry:
* a,b,c,d - four characters
*
* Exit:
* Returns constructed SIGNATURE
*
* Example:
* strct->signature = MAKE_SIGNATURE('b','e','n','s')
*/
#define MAKE_SIGNATURE(a,b,c,d) (a + (b<<8) + (c<<16) + (d<<24))
#define BAD_SIGNATURE (0L)
#define MCI_SIGNATURE MAKE_SIGNATURE('M','C','I','C')
/* --- MCI context structure ---------------------------------------------- */
typedef ULONG SIGNATURE; /* structure signature */
struct MCI_CONTEXT /* private structure */
{
SIGNATURE signature; /* for validation */
PFNFREE pfnFree; /* where the free() is */
UINT cbDataBlockMax; /* promised max data size */
MI_MEMORY buff1; /* work buffer */
MI_MEMORY buff2; /* work buffer */
MI_MEMORY work1; /* work buffer */
MI_MEMORY work2; /* work buffer */
#ifdef LGM
MI_MEMORY work3; /* work buffer */
MI_MEMORY work4; /* work buffer */
#endif
MI_MEMORY historyBuffer; /* history buffer */
char history; /* history is valid flag */
};
typedef struct MCI_CONTEXT FAR *PMCC_CONTEXT; /* a pointer to one */
#define PMCCfromHMC(h) ((PMCC_CONTEXT)(h)) /* handle to pointer */
#define HMCfromPMCC(p) ((MCI_CONTEXT_HANDLE)(p)) /* pointer to handle */
/* --- MCICreateCompression() --------------------------------------------- */
int FAR DIAMONDAPI MCICreateCompression(
UINT FAR * pcbDataBlockMax, /* max uncompressed data block */
PFNALLOC pfnma, /* Memory allocation function */
PFNFREE pfnmf, /* Memory free function */
UINT FAR * pcbDstBufferMin, /* gets required output buffer */
MCI_CONTEXT_HANDLE FAR *pmchHandle) /* gets newly-created handle */
{
PMCC_CONTEXT context; /* new context */
*pmchHandle = (MCI_CONTEXT_HANDLE) 0; /* wait until it's valid */
if ((*pcbDataBlockMax == 0) || (*pcbDataBlockMax > 32768u))
{
*pcbDataBlockMax = 32768u; /* help with source block size */
}
context = pfnma(sizeof(struct MCI_CONTEXT));
if (context == NULL)
{
return(MCI_ERROR_NOT_ENOUGH_MEMORY); /* if can't allocate */
}
context->signature = MCI_SIGNATURE;
context->history = 0; /* no compression history here */
context->pfnFree = pfnmf; /* remember where free() is */
context->cbDataBlockMax = *pcbDataBlockMax; /* remember agreement */
*pcbDstBufferMin = /* we'll expand sometimes */
*pcbDataBlockMax + MAX_GROWTH;
/* allocate all buffers */
context->buff1 = pfnma(LIT_BUFSIZE); /* literal buffer */
context->buff2 = pfnma(DIST_BUFSIZE); /* distance buffer */
#ifdef LGM
context->work1 = pfnma(2*256); /* one-char match heads */
context->work2 = pfnma(2*32768L); /* one-char list */
context->work3 = pfnma(2*32768L); /* two-char list */
context->work4 = pfnma(2*32768L); /* three-char list */
#else
context->work1 = pfnma(2*32768L); /* hash table */
context->work2 = pfnma(2*32768L); /* hash match links */
#endif
context->historyBuffer = pfnma(65536L); /* history data buffer */
if ((context->buff1 == NULL) || /* if any allocations failed */
(context->buff2 == NULL) ||
(context->work1 == NULL) ||
(context->work2 == NULL) ||
#ifdef LGM
(context->work3 == NULL) ||
(context->work4 == NULL) ||
#endif
(context->historyBuffer == NULL))
{
MCIDestroyCompression(HMCfromPMCC(context)); /* nuke it */
return(MCI_ERROR_NOT_ENOUGH_MEMORY); /* report failed */
}
if (NFMcompress_init(context->buff1,context->buff2) != NFMsuccess)
{
MCIDestroyCompression(HMCfromPMCC(context));
return(MCI_ERROR_NOT_ENOUGH_MEMORY);
}
/* pass context back to caller */
*pmchHandle = HMCfromPMCC(context);
return(MCI_ERROR_NO_ERROR);
}
/* --- MCICompress() ------------------------------------------------------ */
int FAR DIAMONDAPI MCICompress(
MCI_CONTEXT_HANDLE hmc, /* compression context */
void FAR * pbSrc, /* source buffer */
UINT cbSrc, /* source actual size */
void FAR * pbDst, /* target buffer */
UINT cbDst, /* size of target buffer */
UINT FAR * pcbResult) /* gets target actual size */
{
PMCC_CONTEXT context; /* pointer to the context */
void FAR * sourcePointer; /* used to copy data */
int result; /* return code */
context = PMCCfromHMC(hmc); /* get pointer from handle */
if (context->signature != MCI_SIGNATURE)
{
return(MCI_ERROR_BAD_PARAMETERS); /* missing signature */
}
if (cbSrc > context->cbDataBlockMax)
{
return(MCI_ERROR_BAD_PARAMETERS); /* violated max block promise */
}
if (cbDst < (context->cbDataBlockMax + MAX_GROWTH))
{
return(MCI_ERROR_BAD_PARAMETERS); /* violated min buffer request */
}
if (context->history)
{
sourcePointer = ((BYTE FAR *) context->historyBuffer) + (32 * 1024L);
}
else
{
sourcePointer = context->historyBuffer;
}
#ifdef BIT16
_fmemcpy(sourcePointer,pbSrc,cbSrc);
#else
memcpy(sourcePointer,pbSrc,cbSrc);
#endif
result = NFMcompress(context->historyBuffer,cbSrc,pbDst,cbDst,
context->work1, context->work2,
#ifdef LGM
context->work3, context->work4,
#endif
context->history, pcbResult);
if (cbSrc == 32768u)
{
context->history = 1; /* now we have history */
}
else
{
context->history = 0; /* no history after < 32K */
}
if (result)
{
return(MCI_ERROR_FAILED); /* report failure */
}
else
{
return(MCI_ERROR_NO_ERROR); /* report no failure */
}
}
/* --- MCIResetCompression() ---------------------------------------------- */
int DIAMONDAPI MCIResetCompression(MCI_CONTEXT_HANDLE hmc)
{
PMCC_CONTEXT context; /* pointer to the context */
context = PMCCfromHMC(hmc); /* get pointer from handle */
if (context->signature != MCI_SIGNATURE)
{
return(MCI_ERROR_BAD_PARAMETERS); /* missing signature */
}
context->history = 0; /* no compression history here */
return(MCI_ERROR_NO_ERROR); /* if tag is OK */
}
/* --- MCIDestroyCompression() -------------------------------------------- */
int DIAMONDAPI MCIDestroyCompression(MCI_CONTEXT_HANDLE hmc)
{
PMCC_CONTEXT context; /* pointer to context */
register PFNFREE pfree; /* quick pointer */
context = PMCCfromHMC(hmc); /* get pointer from handle */
if (context->signature != MCI_SIGNATURE)
{
return(MCI_ERROR_BAD_PARAMETERS); /* missing signature */
}
context->signature = BAD_SIGNATURE; /* destroy signature */
pfree = context->pfnFree; /* get pointer from struct */
if (context->buff1 != NULL)
{
pfree(context->buff1);
}
if (context->buff2 != NULL)
{
pfree(context->buff2);
}
if (context->work1 != NULL)
{
pfree(context->work1);
}
if (context->work2 != NULL)
{
pfree(context->work2);
}
#ifdef LGM
if (context->work3 != NULL)
{
pfree(context->work3);
}
if (context->work4 != NULL)
{
pfree(context->work4);
}
#endif
if (context->historyBuffer != NULL)
{
pfree(context->historyBuffer); /* self-destruct */
}
pfree(context);
return(MCI_ERROR_NO_ERROR); /* success */
}
/* ------------------------------------------------------------------------ */