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.
 
 
 
 
 
 

225 lines
7.2 KiB

/*
* Microsoft Confidential
* Copyright (C) Microsoft Corporation 1994,1995
* All Rights Reserved.
*
* MDI.C: Memory Decompression Interface
*
* History:
* 20-Jan-1994 msliger Initial version.
* 11-Feb-1994 msliger Changed M*ICreate() to adjust size.
* 13-Feb-1994 msliger revised type names, ie, UINT16 -> UINT.
* changed handles to HANDLEs.
* 24-Feb-1994 msliger Changed alloc,free to common typedefs.
* 22-Mar-1994 msliger Changed interface USHORT to UINT.
* 15-Nov-1994 msliger NFMDECO no longer needs alloc/free.
* 31-Jan-1995 msliger Supported MDICreateDecompression query.
* 25-May-1995 msliger Dropped NFMuncompress, using NFM_Prepare()
* and NFM_Decompress(). Added INCR_TESTING.
*
* Compilation options:
*
* INCR_TESTING define to some number to cause incremental decompression
* (of not more than that many bytes per pass)
*
*/
/* --- preprocessor ------------------------------------------------------- */
#include <stdio.h> /* for NULL */
#include "mdi.h" /* types, prototype verification, error codes */
#include "nfmdeco.h" /* features of NFMDECO.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 MDI_SIGNATURE MAKE_SIGNATURE('M','D','I','C')
/* --- MDI context structure ---------------------------------------------- */
typedef ULONG SIGNATURE; /* structure signature */
struct MDI_CONTEXT /* private structure */
{
SIGNATURE signature; /* for validation */
PFNALLOC pfnAlloc; /* where the alloc() is */
PFNFREE pfnFree; /* where the free() is */
UINT cbDataBlockMax; /* promised max data size */
void *DecompContext;
};
typedef struct MDI_CONTEXT FAR *PMDC_CONTEXT; /* a pointer to one */
#define PMDCfromHMD(h) ((PMDC_CONTEXT)(h)) /* handle to pointer */
#define HMDfromPMDC(p) ((MDI_CONTEXT_HANDLE)(p)) /* pointer to handle */
/* --- MDICreateDecompression() ------------------------------------------- */
int DIAMONDAPI MDICreateDecompression(
UINT * pcbDataBlockMax, /* max uncompressed data block */
PFNALLOC pfnma, /* Memory allocation function */
PFNFREE pfnmf, /* Memory free function */
UINT * pcbSrcBufferMin, /* gets required input buffer */
MDI_CONTEXT_HANDLE * pmdhHandle) /* gets newly-created handle */
{
PMDC_CONTEXT context; /* new context */
if ((*pcbDataBlockMax == 0) || (*pcbDataBlockMax > 32768u))
{
*pcbDataBlockMax = 32768u; /* help with source block size */
}
*pcbSrcBufferMin = /* we'll expand sometimes */
*pcbDataBlockMax + MAX_GROWTH;
if (pmdhHandle == NULL) /* if no context requested, */
{
return(MDI_ERROR_NO_ERROR); /* return from query mode */
}
*pmdhHandle = (MDI_CONTEXT_HANDLE) 0; /* wait until it's valid */
context = pfnma(sizeof(struct MDI_CONTEXT));
if (context == NULL)
{
return(MDI_ERROR_NOT_ENOUGH_MEMORY); /* if can't allocate */
}
context->DecompContext = NFMInitializeContext(pfnma);
if(!context->DecompContext) {
pfnmf(context);
return(MDI_ERROR_NOT_ENOUGH_MEMORY); /* if can't allocate */
}
context->pfnAlloc = pfnma; /* remember where alloc() is */
context->pfnFree = pfnmf; /* remember where free() is */
context->cbDataBlockMax = *pcbDataBlockMax; /* remember agreement */
context->signature = MDI_SIGNATURE; /* install signature */
*pmdhHandle = HMDfromPMDC(context); /* pass context back to caller */
return(MDI_ERROR_NO_ERROR); /* tell caller all is well */
}
/* --- MDIDecompress() ---------------------------------------------------- */
int DIAMONDAPI MDIDecompress(
MDI_CONTEXT_HANDLE hmd, /* decompression context */
void FAR * pbSrc, /* source buffer */
UINT cbSrc, /* source actual size */
void FAR * pbDst, /* target buffer */
UINT * pcbResult) /* gets actual target size */
{
PMDC_CONTEXT context; /* pointer to the context */
int result; /* return code */
context = PMDCfromHMD(hmd); /* get pointer from handle */
if (context->signature != MDI_SIGNATURE)
{
return(MDI_ERROR_BAD_PARAMETERS); /* missing signature */
}
if (cbSrc > (context->cbDataBlockMax + MAX_GROWTH))
{
return(MDI_ERROR_BUFFER_OVERFLOW); /* violated max block promise */
}
result = NFM_Prepare(context->DecompContext, pbSrc, cbSrc, pbDst, context->cbDataBlockMax);
if (result == 0)
{
#ifndef INCR_TESTING
result = NFM_Decompress(context->DecompContext,pcbResult);
#else /* INCR_TESTING */
UINT cbChunk;
UINT cbActual;
cbActual = 0;
do
{
if ((*pcbResult - cbActual) < INCR_TESTING)
{
cbChunk = *pcbResult - cbActual;
}
else
{
cbChunk = INCR_TESTING;
}
result = NFM_Decompress(context->DecompContext,&cbChunk);
cbActual += cbChunk;
} while ((result == 0) && (cbActual < *pcbResult));
*pcbResult = cbActual;
#endif /* INCR_TESTING */
}
if (result == 0)
{
return(MDI_ERROR_NO_ERROR); /* report no failure */
}
else
{
return(MDI_ERROR_FAILED); /* report failure */
}
}
/* --- MDIResetDecompression() -------------------------------------------- */
int DIAMONDAPI MDIResetDecompression(MDI_CONTEXT_HANDLE hmd)
{
PMDC_CONTEXT context; /* pointer to the context */
context = PMDCfromHMD(hmd); /* get pointer from handle */
if (context->signature != MDI_SIGNATURE)
{
return(MDI_ERROR_BAD_PARAMETERS); /* missing signature */
}
return(MDI_ERROR_NO_ERROR); /* if tag is OK */
}
/* --- MDIDestroyDecompression() ------------------------------------------ */
int DIAMONDAPI MDIDestroyDecompression(MDI_CONTEXT_HANDLE hmd)
{
PMDC_CONTEXT context; /* pointer to the context */
context = PMDCfromHMD(hmd); /* get pointer from handle */
if (context->signature != MDI_SIGNATURE)
{
return(MDI_ERROR_BAD_PARAMETERS); /* missing signature */
}
context->signature = BAD_SIGNATURE; /* destroy signature */
NFMDestroyContext(context->DecompContext,context->pfnFree);
context->pfnFree(context); /* self-destruct */
return(MDI_ERROR_NO_ERROR); /* success */
}
/* ------------------------------------------------------------------------ */