Leaked source code of windows server 2003
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.
 
 
 
 
 
 

447 lines
9.9 KiB

/* File: C:\WACKER\xfer\cmprs2.c (Created: 20-Jan-1994)
* created from HAWIN source file
* cmprs2.c -- Routines to implement data decompression
*
* Copyright 1989,1994 by Hilgraeve Inc. -- Monroe, MI
* All rights reserved
*
* $Revision: 1 $
* $Date: 10/05/98 1:16p $
*/
#include <windows.h>
#include <tdll\stdtyp.h>
#if !defined(BYTE)
#define BYTE unsigned char
#endif
#include "cmprs.h"
#include "cmprs.hh"
#if SHOW
// #include <stdio.h>
#endif
/* * * * * * * * * * * * * *
* Decompression routines *
* * * * * * * * * * * * * */
typedef struct s_dcmp_node DCMP_NODE;
struct s_dcmp_node
{
DCMP_NODE *pstLinkBack;
DCMP_NODE *pstLinkFwd;
BYTE ucChar;
};
#define NODE_CAST DCMP_NODE *
DCMP_NODE *pstDcmpTbl; // pointer to lookup table
DCMP_NODE *pstCode = NULL; // used to scan table for output
int (**ppfDcmpPutfunc)(void *, int); /* ptr. to ptr. to function used
by calling func */
int (*pfDcmpPutChar)(void *, int); /* ptr. to function used
internally to get data */
void *pPsave;
DCMP_NODE *pstTblLimit = NULL; /* pointer to table beyond 1st 256 nodes */
DCMP_NODE *pstExtraNode = NULL; /* pointer to additional node used in spec. case */
int fDcmpError; /* set TRUE if illegal code is received */
int fStartFresh = FALSE;
unsigned int usCodeMask; /* mask to isolate varible sized codes */
unsigned int usOldCode; /* last code received */
int mcFirstChar; /* final character of pattern readout, actually,
the FIRST character of pattern (characters
are read out in reverse order */
// #pragma optimize("lgea",on)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION: decompress_start
*
* DESCRIPTION:
*
*
* ARGUMENTS:
*
*
* RETURNS:
*
*/
int decompress_start(int (**put_func)(void *, int),
void *pP,
int fPauses)
{
unsigned int usCount;
DCMP_NODE *pstTmp;
if (!compress_enable())
return(FALSE);
pPsave = pP;
fFlushable = fPauses;
// Due to the use of based pointers, we must use compress_tblspace + 1
// in the following code. Otherwise, node 0 (which could have an offset
// of 0 looks like a NULL pointer.
// pstDcmpTbl = (DCMP_NODE *)(OFFSETOF(compress_tblspace) + 1);
pstDcmpTbl = (DCMP_NODE *)(compress_tblspace);
pstCode = NULL;
pstExtraNode = (NODE_CAST)&pstDcmpTbl[MAXNODES]; /* last node */
pstExtraNode->pstLinkFwd = NULL;
pstTblLimit = (NODE_CAST)&pstDcmpTbl[256];
for (usCount = 0, pstTmp = pstDcmpTbl; usCount < 256; ++usCount)
{
pstTmp->ucChar = (BYTE)usCount;
++pstTmp;
}
ulHoldReg = 0;
sBitsLeft = 0;
sCodeBits = 9;
usMaxCode = 512;
usCodeMask = (1 << sCodeBits) - 1;
usFreeCode = FIRSTFREE;
fDcmpError = FALSE;
fStartFresh = FALSE;
ppfDcmpPutfunc = put_func;
pfDcmpPutChar = *ppfDcmpPutfunc;
*ppfDcmpPutfunc = dcmp_putc;
usxCmprsStatus = COMPRESS_ACTIVE;
#if SHOW
printf("D decompress_start, sCodeBits=%d\n",
sCodeBits);
#endif
return(TRUE);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION: decompress_error
*
* DESCRIPTION:
*
*
* ARGUMENTS:
*
*
* RETURNS:
*
*/
int decompress_error(void)
{
return(fDcmpError);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION: dcmp_start
*
* DESCRIPTION:
*
*
* ARGUMENTS:
*
*
* RETURNS:
*
*/
int dcmp_start(void *pX, int mcStartChar)
{
unsigned int usCode;
ulHoldReg |= ((unsigned long)mcStartChar << sBitsLeft);
sBitsLeft += 8;
#if SHOW
printf("D %02X %08lX,%2d dcmp_start\n", mcStartChar,
ulHoldReg, sBitsLeft);
#endif
if (sBitsLeft >= sCodeBits)
{
usCode = (unsigned int)ulHoldReg & usCodeMask;
ulHoldReg >>= sCodeBits;
sBitsLeft -= sCodeBits;
#if SHOW
printf("D >> %03X %08lX,%2d sCodeBits=%d dcmp_start\n",
usCode, ulHoldReg, sBitsLeft, sCodeBits);
#endif
/* Table has just been cleared, code must be in range of 0 - 255 */
if (!IN_RANGE((INT)usCode, 0, 255))
{
#if SHOW
printf("D >> %03X ERROR: out of range\n",
usCode);
#endif
return(dcmp_abort());
}
else
{
#if SHOW
printf("D %02X dcmp_start\n", usCode);
#endif
mcStartChar = (*pfDcmpPutChar)(pPsave, mcFirstChar =
(INT)(usOldCode = usCode));
*ppfDcmpPutfunc = dcmp_putc;
}
}
return(mcStartChar);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION: dcmp_putc
*
* DESCRIPTION:
*
*
* ARGUMENTS:
*
*
* RETURNS:
*
*/
int dcmp_putc(void *pX, int mcInput)
{
unsigned int usCode;
unsigned int usInCode;
int mcPutResult;
DCMP_NODE *pstTmp;
ulHoldReg |= ((unsigned long)mcInput << sBitsLeft);
sBitsLeft += 8;
#if SHOW
printf("D %02X %08lX,%2d\n", mcInput, ulHoldReg, sBitsLeft);
#endif
if (sBitsLeft >= sCodeBits)
{
usCode = (unsigned int)ulHoldReg & usCodeMask;
ulHoldReg >>= sCodeBits;
sBitsLeft -= sCodeBits;
#if SHOW
printf("D >> %03X %08lX,%2d sCodeBits=%d\n",
usCode, ulHoldReg, sBitsLeft, sCodeBits);
#endif
if (usCode == STOPCODE)
{
if (!fFlushable)
decompress_stop();
else
{
// Pause in the data, leave lookup table intact but start
// receiving a fresh stream.
sBitsLeft = 0;
ulHoldReg = 0L;
fStartFresh = TRUE;
#if SHOW
printf("D %08lX,%2d setting fFreshStart\n",
ulHoldReg, sBitsLeft);
#endif
}
}
else if (usCode == CLEARCODE)
{
sCodeBits = 9;
usMaxCode = 512;
usCodeMask = (1 << sCodeBits) - 1;
usFreeCode = FIRSTFREE;
*ppfDcmpPutfunc = dcmp_start;
#if SHOW
printf("D CLEARCODE, sCodeBits=%d\n",
sCodeBits);
#endif
}
else if (usCode > (unsigned int)usFreeCode)
{
#if SHOW
printf("D ERROR: usCode > usFreeCode of %03X\n",
usFreeCode);
#endif
return(dcmp_abort());
}
else
{
pstCode = (NODE_CAST)&pstDcmpTbl[usInCode = usCode];
if (usCode == usFreeCode) /* spec. case k<w>k<w>k */
{
pstCode = (NODE_CAST)&pstDcmpTbl[usCode = usOldCode];
pstExtraNode->ucChar = (BYTE)mcFirstChar;
pstCode->pstLinkFwd = pstExtraNode;
#if SHOW
printf("D Special case: k<w>k<w>k\n");
#endif
}
else
pstCode->pstLinkFwd = NULL;
while(pstCode > pstTblLimit)
{
pstCode->pstLinkBack->pstLinkFwd = pstCode;
pstCode = pstCode->pstLinkBack;
}
mcFirstChar = pstCode->ucChar;
if (!fStartFresh)
{
#if SHOW
printf("D D Added %03X = %03X + %02X\n",
usFreeCode, usOldCode, mcFirstChar);
#endif
if (usFreeCode < MAXNODES)
{
pstTmp = (NODE_CAST)&pstDcmpTbl[usFreeCode++];
pstTmp->ucChar = (BYTE)mcFirstChar;
pstTmp->pstLinkBack = (NODE_CAST)&pstDcmpTbl[usOldCode];
}
}
fStartFresh = FALSE;
usOldCode = usInCode;
if (usFreeCode >= usMaxCode && sCodeBits < MAXCODEBITS)
{
++sCodeBits;
usCodeMask = (1 << sCodeBits) - 1;
usMaxCode *= 2;
#if SHOW
printf("D D New sCodeBits = %d\n",
sCodeBits);
#endif
}
while (pstCode != NULL)
{
#if SHOW
printf("D %02X ", pstCode->ucChar);
#endif
if ((mcPutResult = (*pfDcmpPutChar)(pPsave, pstCode->ucChar)) < 0)
{
if (mcPutResult == DCMP_UNFINISHED)
{
#if SHOW
printf("Interrupted");
#endif
pstCode = pstCode->pstLinkFwd; // to pick up later
mcInput = DCMP_UNFINISHED;
break;
}
else
{
#if SHOW
printf("ERROR: putc returned -1");
#endif
pstCode = NULL;
mcInput = ERROR;
break;
}
}
#if SHOW
printf("\n");
#endif
pstCode = pstCode->pstLinkFwd;
}
}
}
return(mcInput);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION: decompress_continue
*
* DESCRIPTION:
* Needed for compression in remote control. Picks up expansion of an
* output string after it has been interrupted.
*
* ARGUMENTS:
*
*
* RETURNS:
*
*/
int decompress_continue(void)
{
int mcPutResult;
int mcRetCode;
// Deliver an initial unfinished code so routines downstream can pick
// up midstream if necessary
if ((*pfDcmpPutChar)(pPsave, DCMP_UNFINISHED) == DCMP_UNFINISHED)
return DCMP_UNFINISHED;
// Now continue delivering any remaining expansion codes unless
// interrupted again
while (pstCode != NULL)
{
if ((mcPutResult = (*pfDcmpPutChar)(pPsave, pstCode->ucChar)) < 0)
{
if (mcPutResult == DCMP_UNFINISHED)
{
pstCode = pstCode->pstLinkFwd; // to pick up later
mcRetCode = DCMP_UNFINISHED;
break;
}
else
{
pstCode = NULL;
mcRetCode = ERROR;
break;
}
}
pstCode = pstCode->pstLinkFwd;
}
return mcRetCode;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION: dcmp_abort
*
* DESCRIPTION:
*
*
* ARGUMENTS:
*
*
* RETURNS:
*
*/
int dcmp_abort(void)
{
/* print error message or whatever */
fDcmpError = TRUE;
decompress_stop();
return(ERROR);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION: decompress_stop
*
* DESCRIPTION:
*
*
* ARGUMENTS:
*
*
* RETURNS:
*
*/
void decompress_stop(void)
{
#if SHOW
printf("D Decompress_stop\n");
#endif
if (ppfDcmpPutfunc != NULL)
{
*ppfDcmpPutfunc = pfDcmpPutChar;
ppfDcmpPutfunc = NULL;
}
usxCmprsStatus = COMPRESS_IDLE;
}
/* end of cmprs2.c */