|
|
/*** binfmt.c - Binary Data Format services
* * This module contains format services for converting binary data into format * text strings according to the format record. * * Copyright (c) 1995,1996 Microsoft Corporation * Author: Michael Tsang (MikeTs) * Created 11/06/95 * * MODIFICATION HISTORY */
#ifdef __UNASM
#pragma warning (disable: 4001)
#include "basedef.h"
#define USE_CRUNTIME
#include "binfmt.h"
typedef int (*PFNFMT)(char *, PFMTHDR, BYTE *, DWORD *);
//Local function prototypes
int FormatNum(char *pszBuffer, PFMTHDR pfmt, BYTE *pb, DWORD *pdwOffset); int FormatEnum(char *pszBuffer, PFMTHDR pfmt, BYTE *pb, DWORD *pdwOffset); int FormatBits(char *pszBuffer, PFMTHDR pfmt, BYTE *pb, DWORD *pdwOffset); int FormatString(char *pszBuffer, PFMTHDR pfmt, BYTE *pb, DWORD *pdwOffset); int GetData(BYTE bUnitSize, BYTE *pb, DWORD dwOffset, DWORD *pdwData); int PrintData(char *pszBuffer, BYTE bUnitSize, DWORD dwData, BOOL fPadSpace);
char szDefSep[] = SZ_SEP_SPACE; char szDefOffsetFmt[] = SZ_FMT_WORDOFFSET; PFNFMT FmtFuncTable[] = { FormatNum, //0: FMT_NUMBER
FormatEnum, //1: FMT_ENUM
FormatBits, //2: FMT_BITS
FormatString, //3: FMT_STRING
}; #define NUM_FMT_FUNCS (sizeof(FmtFuncTable)/sizeof(PFNFMT))
#ifdef FPRINTF
/***EP BinFPrintf - Binary fprintf
* * ENTRY * pfile -> output file * pszBuffer -> buffer to hold the formatted string * (if NULL, use internal buffer) * pfmt -> format record array * pb -> binary data buffer * pdwOffset -> offset to binary data buffer (if NULL, use internal) * pszOffsetFormat -> offset format string (can be NULL) * * EXIT-SUCCESS * returns FERR_NONE * EXIT-FAILURE * returns negative error code */
int BinFPrintf(FILE *pfile, char *pszBuffer, PFMT pfmt, BYTE *pb, DWORD *pdwOffset, char *pszOffsetFormat) { TRACENAME("BINFPRINTF") int rc = FERR_NONE; DWORD dwOffset = 0, dwOldOffset; DWORD dwData; char szBuff[256]; char *psz = pszBuffer? pszBuffer: szBuff; DWORD *pdw = pdwOffset? pdwOffset: &dwOffset;
ENTER(4, ("BinFPrintf(pszBuff=%lx,pfmt=%lx,pdwOffset=%lx,Offset=%lx)\n", pszBuffer, pfmt, pdwOffset, pdwOffset? *pdwOffset: 0));
if (pfmt != NULL) { BYTE i, j;
for (i = 0; pfmt[i].pfmtType != NULL; ++i) { if (pfmt[i].pszLabel != NULL) { if (pszOffsetFormat != NULL) { FPRINTF(pfile, pszOffsetFormat, *pdw, pfmt[i].pfmtType->bUnitSize); if (pfmt[i].pfmtType->dwfFormat & FMTF_NO_RAW_DATA) { FPRINTF(pfile, " "); } else { if (GetData(pfmt[i].pfmtType->bUnitSize, pb, *pdw, &dwData) == FERR_NONE) { PrintData(psz, pfmt[i].pfmtType->bUnitSize, dwData, TRUE); FPRINTF(pfile, psz); }
for (j = 1; j < pfmt[i].pfmtType->bUnitCnt; ++j) { if (GetData(pfmt[i].pfmtType->bUnitSize, pb, *pdw + j*pfmt[i].pfmtType->bUnitSize, &dwData) == FERR_NONE) { FPRINTF(pfile, ","); PrintData(psz, pfmt[i].pfmtType->bUnitSize, dwData, FALSE); FPRINTF(pfile, psz); } } } } if (pfmt[i].pszLabel[0] != '\0') FPRINTF(pfile, ";%s", pfmt[i].pszLabel); else FPRINTF(pfile, "\n"); }
dwOldOffset = *pdw; if ((pfmt[i].pszLabel != NULL) && (pfmt[i].pszLabel[0] == '\0')) { *pdw += pfmt[i].pfmtType->bUnitCnt*pfmt[i].pfmtType->bUnitSize; } else { if (pfmt[i].pszLabel == NULL) FPRINTF(pfile, ","); rc = BinSprintf(psz, pfmt[i].pfmtType, pb, pdw); if (rc == FERR_NONE) { char *psz1, *psz2; BOOL fSpace = FALSE, fInQuote = FALSE, fInString = FALSE;
for (psz1 = psz2 = psz; *psz2 != '\0'; ++psz2) { if (*psz2 == '"') { fSpace = FALSE; fInString = ~fInString; *psz1 = *psz2; psz1++; } else if (*psz2 == '\'') { fSpace = FALSE; fInQuote = ~fInQuote; *psz1 = *psz2; psz1++; } else if (*psz2 == ' ') { if (!fSpace && !fInString && !fInQuote && (psz1 != psz)) { *psz1 = ','; psz1++; } else if (fInString || fInQuote) { *psz1 = *psz2; psz1++; } fSpace = TRUE; } else { fSpace = FALSE; *psz1 = *psz2; psz1++; } }
if ((psz1 > psz) && (*(psz1 - 1) == ',')) *(psz1 - 1) = '\0'; else if ((psz1 > psz) && (*(psz1 - 1) == '\n') && (*(psz1 - 2) == ',')) { *(psz1 - 2) = '\n'; *(psz1 - 1) = '\0'; } else *psz1 = '\0'; FPRINTF(pfile, psz); } }
if (pfmt[i].lpfn != NULL) (*pfmt[i].lpfn)(pfile, pb, dwOldOffset); } }
EXIT(4, ("BinFPrintf=%d (Offset=%lx,Buff=%s)\n", rc, *pdwOffset, pszBuffer)); return rc; } //BinFPrintf
#endif //ifdef FPRINTF
/***EP BinSprintf - Binary sprintf
* * ENTRY * pszBuffer -> buffer to hold the formatted string * pfmt -> format record * pb -> binary data buffer * pdwOffset -> offset to binary data buffer * * EXIT-SUCCESS * returns FERR_NONE * EXIT-FAILURE * returns negative error code */
int BinSprintf(char *pszBuffer, PFMTHDR pfmt, BYTE *pb, DWORD *pdwOffset) { TRACENAME("BINSPRINTF") int rc = FERR_NONE;
ENTER(4, ("BinSprintf(fmt=%d,Offset=%lx)\n", pfmt->bFmtType, *pdwOffset));
if (pfmt->bFmtType >= NUM_FMT_FUNCS) rc = FERR_INVALID_FORMAT; else { int i; BYTE j; DWORD dwData;
*pszBuffer = '\0'; for (i = 0; (rc == FERR_NONE) && (i < pfmt->iRepeatCnt); ++i) { if (pfmt->dwfFormat & FMTF_PRINT_OFFSET) { SPRINTF(pszBuffer, pfmt->pszOffsetFmt? pfmt->pszOffsetFmt: szDefOffsetFmt, *pdwOffset); }
if (!(pfmt->dwfFormat & FMTF_NO_PRINT_DATA) && (GetData(pfmt->bUnitSize, pb, *pdwOffset, &dwData) == FERR_NONE)) { PrintData(pszBuffer, pfmt->bUnitSize, dwData, FALSE); STRCAT(pszBuffer, ";"); }
if (pfmt->pszLabel) STRCAT(pszBuffer, pfmt->pszLabel);
for (j = 0; (rc == FERR_NONE) && (j < pfmt->bUnitCnt); ++j) { rc = (*FmtFuncTable[pfmt->bFmtType]) (&pszBuffer[STRLEN(pszBuffer)], pfmt, pb, pdwOffset);
if (rc == FERR_NONE) { if (!(pfmt->dwfFormat & FMTF_NO_SEP)) { STRCAT(pszBuffer, pfmt->pszFieldSep? pfmt->pszFieldSep: szDefSep); }
if (!(pfmt->dwfFormat & FMTF_NO_INC_OFFSET)) *pdwOffset += pfmt->bUnitSize; } }
if ((rc == FERR_NONE) && !(pfmt->dwfFormat & FMTF_NO_EOL)) { STRCAT(pszBuffer, "\n"); } } }
EXIT(4, ("BinSprintf=%d (Offset=%lx,Buff=%s)\n", rc, *pdwOffset, pszBuffer)); return rc; } //BinSprintf
/***LP FormatNum - Format numbers
* * ENTRY * pszBuffer -> buffer to hold formatted string * pfmt -> format record * pb -> binary data buffer * pdwOffset -> offset to binary data buffer * * EXIT-SUCCESS * returns FERR_NONE * EXIT-FAILURE * returns negative error code */
int FormatNum(char *pszBuffer, PFMTHDR pfmt, BYTE *pb, DWORD *pdwOffset) { TRACENAME("FORMATNUM") int rc; PFMTNUM pfmtNum = (PFMTNUM)pfmt; DWORD dwData;
ENTER(5, ("FormatNum(Offset=%lx)\n", *pdwOffset));
if ((rc = GetData(pfmt->bUnitSize, pb, *pdwOffset, &dwData)) == FERR_NONE) { dwData &= pfmtNum->dwMask; dwData >>= pfmtNum->bShiftCnt;
SPRINTF(&pszBuffer[STRLEN(pszBuffer)], pfmtNum->pszNumFmt, dwData); }
EXIT(5, ("FormatNum=%d (Offset=%lx,Buff=%s)\n", rc, *pdwOffset, pszBuffer)); return rc; } //FormatNum
/***LP FormatEnum - Format enumerated values
* * ENTRY * pszBuffer -> buffer to hold formatted string * pfmt -> format record * pb -> binary data buffer * pdwOffset -> offset to binary data buffer * * EXIT-SUCCESS * returns FERR_NONE * EXIT-FAILURE * returns negative error code */
int FormatEnum(char *pszBuffer, PFMTHDR pfmt, BYTE *pb, DWORD *pdwOffset) { TRACENAME("FORMATENUM") int rc = FERR_NONE; PFMTENUM pfmtEnum = (PFMTENUM)pfmt; DWORD dwData;
ENTER(5, ("FormatEnum(Offset=%lx)\n", *pdwOffset));
if ((rc = GetData(pfmt->bUnitSize, pb, *pdwOffset, &dwData)) == FERR_NONE) { dwData &= pfmtEnum->dwMask; dwData >>= pfmtEnum->bShiftCnt;
if ((dwData < pfmtEnum->dwStartEnum) || (dwData > pfmtEnum->dwEndEnum)) STRCAT(pszBuffer, pfmtEnum->pszOutOfRange); else { dwData -= pfmtEnum->dwStartEnum; STRCAT(pszBuffer, pfmtEnum->ppszEnumNames[dwData]); } }
EXIT(5, ("FormatEnum=%d (Offset=%lx,Buff=%s)\n", rc, *pdwOffset, pszBuffer)); return rc; } //FormatEnum
/***LP FormatBits - Format bit values
* * ENTRY * pszBuffer -> buffer to hold formatted string * pfmt -> format record * pb -> binary data buffer * pdwOffset -> offset to binary data buffer * * EXIT-SUCCESS * returns FERR_NONE * EXIT-FAILURE * returns negative error code */
int FormatBits(char *pszBuffer, PFMTHDR pfmt, BYTE *pb, DWORD *pdwOffset) { TRACENAME("FORMATBITS") int rc = FERR_NONE; PFMTBITS pfmtBits = (PFMTBITS)pfmt; DWORD dwData;
ENTER(5, ("FormatBits(Offset=%lx)\n", *pdwOffset));
if ((rc = GetData(pfmt->bUnitSize, pb, *pdwOffset, &dwData)) == FERR_NONE) { int i, j; DWORD dw;
for (i = 31, j = 0; i >= 0; --i) { dw = 1L << i; if (pfmtBits->dwMask & dw) { if (dwData & dw) { if ((pfmtBits->ppszOnNames != NULL) && (pfmtBits->ppszOnNames[j] != NULL)) { STRCAT(pszBuffer, pfmtBits->ppszOnNames[j]); } } else { if ((pfmtBits->ppszOffNames != NULL) && (pfmtBits->ppszOffNames[j] != NULL)) { STRCAT(pszBuffer, pfmtBits->ppszOffNames[j]); } }
if (!(pfmt->dwfFormat & FMTF_NO_SEP)) { STRCAT(pszBuffer, pfmt->pszFieldSep? pfmt->pszFieldSep: szDefSep); }
j++; } } }
EXIT(5, ("FormatBits=%d (Offset=%lx,Buff=%s)\n", rc, *pdwOffset, pszBuffer)); return rc; } //FormatBits
/***LP FormatString - Format string data
* * ENTRY * pszBuffer -> buffer to hold formatted string * pfmt -> format record * pb -> binary data buffer * pdwOffset -> offset to binary data buffer * * EXIT-SUCCESS * returns FERR_NONE * EXIT-FAILURE * returns negative error code */
int FormatString(char *pszBuffer, PFMTHDR pfmt, BYTE *pb, DWORD *pdwOffset) { TRACENAME("FORMATSTRING") int rc = FERR_NONE;
ENTER(5, ("FormatString(Offset=%lx)\n", *pdwOffset));
pb += *pdwOffset; if (pfmt->dwfFormat & FMTF_STR_ASCIIZ) { pszBuffer[0] = '"'; STRCPY(pszBuffer + 1, (char *)pb); pszBuffer[STRLEN(pszBuffer)] = '"'; if ((pfmt->bUnitSize == 0) && !(pfmt->dwfFormat & FMTF_NO_INC_OFFSET)) *pdwOffset += STRLEN((char *)pb) + 3; } else if (pfmt->bUnitSize != 0) { if (isalnum(*pb) || (*pb == ' ')) { pszBuffer[0] = '\''; STRCPYN(pszBuffer + 1, (char *)pb, pfmt->bUnitSize); pszBuffer[pfmt->bUnitSize + 1] = '\''; pszBuffer[pfmt->bUnitSize + 2] = '\0'; } else { rc = PrintData(pszBuffer, pfmt->bUnitSize, *((PDWORD)pb), FALSE); } }
EXIT(5, ("FormatString=%d (Offset=%lx,Buff=%s)\n", rc, *pdwOffset, pszBuffer)); return rc; } //FormatString
/***LP GetData - Get data of appropriate size from the binary buffer
* * ENTRY * bUnitSize - size of data unit * pb -> data buffer * dwOffset - offset into data buffer * pdwData -> to hold data * * EXIT-SUCCESS * returns FERR_NONE * EXIT-FAILURE * returns negative error code */
int GetData(BYTE bUnitSize, BYTE *pb, DWORD dwOffset, DWORD *pdwData) { TRACENAME("GETDATA") int rc = FERR_NONE;
ENTER(6, ("GetData(UnitSize=%d,Data=%lx,Offset=%lx)\n", bUnitSize, *(DWORD *)pb, dwOffset));
pb += dwOffset; switch (bUnitSize) { case UNIT_BYTE: *pdwData = (DWORD)(*pb); break; case UNIT_WORD: *pdwData = (DWORD)(*((WORD *)pb)); break; case UNIT_DWORD: *pdwData = *(DWORD *)pb; break; default: rc = FERR_INVALID_UNITSIZE; }
EXIT(6, ("GetData=%d (Data=%lx)\n", rc, *pdwData)); return rc; } //GetData
/***LP PrintData - Print data value according to its size
* * ENTRY * pszBuffer -> buffer to hold formatted string * bUnitSize - size of data unit * dwData - number * fPadSpace - if TRUE pad space to 8 chars * * EXIT-SUCCESS * returns FERR_NONE * EXIT-FAILURE * returns negative error code */
int PrintData(char *pszBuffer, BYTE bUnitSize, DWORD dwData, BOOL fPadSpace) { TRACENAME("PRINTDATA") int rc = FERR_NONE;
ENTER(6, ("PrintData(UnitSize=%d,Data=%lx)\n", bUnitSize, dwData));
switch (bUnitSize) { case UNIT_BYTE: SPRINTF(pszBuffer, "%02x", (BYTE)dwData); if (fPadSpace) STRCAT(pszBuffer, " "); break; case UNIT_WORD: SPRINTF(pszBuffer, "%04x", (WORD)dwData); if (fPadSpace) STRCAT(pszBuffer, " "); break; case UNIT_DWORD: SPRINTF(pszBuffer, "%08lx", dwData); break; default: rc = FERR_INVALID_UNITSIZE; }
EXIT(6, ("PrintData=%d (Buff=%s)\n", rc, pszBuffer)); return rc; } //PrintData
#endif //ifdef __UNASM
|