Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

503 lines
15 KiB

//////////////////////////////////////////////////////////////////////////////
// ppm2pps
//
// Copyright (c) 1996-1999 Microsoft Corporation
//
// Dump contents of ppm file
//
//////////////////////////////////////////////////////////////////////////////
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <imagehlp.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "gen.h"
// string to put in front of all error messages so that BUILD can find them.
const char *ErrMsgPrefix = "NMAKE : U8603: 'PPM2PPS' ";
//
// global variables
BOOL fDebug; // global debug flag
BOOL fDumpCCheck; // when set build ppswind.h for checking sizes/offsets
HANDLE hFile;
HANDLE hMapFile = NULL;
PRBTREE pFunctions = NULL;
PRBTREE pStructures = NULL;
PRBTREE pTypedefs = NULL;
PKNOWNTYPES NIL = NULL;
// function prototypes
void __cdecl ErrMsg(char *pch, ...);
void __cdecl ExitErrMsg(BOOL bSysError, char *pch, ...);
BOOL DumpTypedefs(FILE *filePpsfile, // file to write output
BOOL fDumpNamedOnly, // when set don't do unnamed
PRBTREE pHead); // known types function list
BOOL DumpStructures(FILE *filePpsfile, // file to write output
BOOL fDumpNamedOnly, // when set don't do unnamed
PRBTREE pHead); // known types function list
BOOL DumpFunctions(FILE *filePpsfile, // file to write output
BOOL fDumpNamedOnly, // when set don't do unnamed
PRBTREE pHead); // known types function list
void Usage(char *s);
BOOL ParseArguments(int argc, char *argv[], char *sPpmfile, char *sPpsfile,
BOOL *pfDumpNamedOnly, BOOL *pfDebug,
BOOL *pfDumpCCheck);
BOOL DumpCCheckHeader(PRBTREE pTypedefs, // typedef lsit
PRBTREE pStructs); // structs sit
int __cdecl main(int argc, char *argv[])
{
void *pvPpmData = NULL;
BOOL fDumpNamedOnly;
char sPpmfile[MAX_PATH];
char sPpsfile[MAX_PATH];
FILE *pfilePpsfile;
try {
if (! ParseArguments(argc, argv, sPpmfile, sPpsfile,
&fDumpNamedOnly, &fDebug, &fDumpCCheck))
{
Usage(argv[0]);
return(-1);
}
if (*sPpmfile)
{
PCVMHEAPHEADER pHeader;
pvPpmData = MapPpmFile(sPpmfile, TRUE);
pHeader = (PCVMHEAPHEADER)pvPpmData;
pFunctions = &pHeader->FuncsList;
pTypedefs = &pHeader->TypeDefsList;
pStructures =&pHeader->StructsList;
NIL =&pHeader->NIL;
pfilePpsfile = fopen(sPpsfile, "w");
if (pfilePpsfile == 0)
{
ErrMsg("ERROR - Could not open output file %s\n", sPpsfile);
CloseHandle(hFile);
CloseHandle(hMapFile);
return(-1);
}
if (DumpFunctions(pfilePpsfile, fDumpNamedOnly,
pFunctions))
{
if (DumpStructures(pfilePpsfile, fDumpNamedOnly,
pStructures))
{
DumpTypedefs(pfilePpsfile,fDumpNamedOnly, pTypedefs);
}
}
fclose(pfilePpsfile);
}
if (fDumpCCheck && pTypedefs && pStructures)
{
DumpCCheckHeader(pTypedefs, pStructures);
}
CloseHandle(hFile);
CloseHandle(hMapFile);
} except(EXCEPTION_EXECUTE_HANDLER) {
ExitErrMsg(FALSE,
"ExceptionCode=%x\n",
GetExceptionCode()
);
}
return(0);
}
void
DumpFuncinfo(FILE *pfilePpsfile, PFUNCINFO pf)
{
while (pf) {
int i;
fprintf(pfilePpsfile,
"%s %s%s %s %s %s",
TokenString[pf->tkDirection],
(pf->fIsPtr64) ? "__ptr64 " : "",
TokenString[pf->tkPreMod],
TokenString[pf->tkSUE],
pf->sType,
TokenString[pf->tkPrePostMod]
);
i = pf->IndLevel;
while (i--) {
fprintf(pfilePpsfile, "*");
}
fprintf(pfilePpsfile,
"%s %s",
TokenString[pf->tkPostMod],
(pf->sName) ? pf->sName : ""
);
pf = pf->pfuncinfoNext;
if (pf) {
fprintf(pfilePpsfile, ", ");
}
}
}
/////////////////////////////////////////////////////////////////////////////
//
// DumpCCheckHeader
//
// dump header file that can be used to check sizes in ppm file against
// those that are generated by C
//
// returns TRUE on success
//
/////////////////////////////////////////////////////////////////////////////
BOOL DumpCCheckHeader(PRBTREE pTypedefs, // typedef lsit
PRBTREE pStructs) // structs lsit
{
PKNOWNTYPES pknwntyp, pknwntypBasic;
FILE *pfile;
pfile = fopen("ppswind.h", "w");
if (pfile == NULL)
{
ErrMsg("Error opening ppwind.h for output\n");
return(FALSE);
}
fprintf(pfile, "CCHECKSIZE cchecksize[] = {\n");
//
// typedefs
pknwntyp = pTypedefs->pLastNodeInserted;
while (pknwntyp) {
if ((! isdigit(*pknwntyp->TypeName)) &&
(strcmp(pknwntyp->TypeName,"...")) &&
(strcmp(pknwntyp->TypeName,"()")) &&
(strcmp(pknwntyp->BasicType, szFUNC)) &&
(pknwntyp->Size > 0) &&
(pknwntyp->dwScopeLevel == 0)) {
pknwntypBasic = GetBasicType(pknwntyp->TypeName,
pTypedefs, pStructs);
if (! ( (pknwntypBasic == NULL) ||
( (! strcmp(pknwntypBasic->BaseName, szVOID)) &&
(pknwntypBasic->pmeminfo == NULL)))) {
fprintf(pfile, " { %4d, sizeof(%s), \"%s\"}, \n",
pknwntyp->Size,
pknwntyp->TypeName,
pknwntyp->TypeName);
}
}
pknwntyp = pknwntyp->Next;
}
//
// structs
pknwntyp = pStructs->pLastNodeInserted;
while (pknwntyp) {
if ((! isdigit(*pknwntyp->TypeName) &&
(pknwntyp->pmeminfo)))
{
if (!(pknwntyp->Flags & BTI_ANONYMOUS) && (pknwntyp->Size > 0) && (pknwntyp->dwScopeLevel == 0)) {
fprintf(pfile, " { %4d, sizeof(%s %s), \"%s %s\" }, \n",
pknwntyp->Size,
pknwntyp->BaseName,
pknwntyp->TypeName,
pknwntyp->BaseName,
pknwntyp->TypeName);
}
}
pknwntyp = pknwntyp->Next;
}
fprintf(pfile, " {0xffffffff, 0xffffffff, \"\"}\n");
fprintf(pfile,"\n};\n");
//
// structs fields
fprintf(pfile, "CCHECKOFFSET ccheckoffset[] = {\n");
pknwntyp = pStructs->pLastNodeInserted;
while (pknwntyp) {
if (! isdigit(*pknwntyp->TypeName))
{
if (!(pknwntyp->Flags & BTI_ANONYMOUS) && !(pknwntyp->Flags & BTI_VIRTUALONLY) && (pknwntyp->Size > 0) && (pknwntyp->dwScopeLevel == 0)) {
PMEMBERINFO pmeminfo = pknwntyp->pmeminfo;
while (pmeminfo != NULL) {
if ((pmeminfo->sName != NULL) && (*pmeminfo->sName != 0) && !(pmeminfo->bIsBitfield))
{
fprintf(pfile, " { %4d, (long) (& (((%s %s *)0)->%s)), \"%s\", \"%s\" },\n",
pmeminfo->dwOffset,
pknwntyp->BaseName,
pknwntyp->TypeName,
pmeminfo->sName,
pknwntyp->TypeName,
pmeminfo->sName);
}
pmeminfo = pmeminfo->pmeminfoNext;
}
}
}
pknwntyp = pknwntyp->Next;
}
fprintf(pfile, " {0xffffffff, 0xffffffff, \"\", \"\"}\n");
fprintf(pfile,"\n};\n");
fclose(pfile);
return(TRUE);
}
/////////////////////////////////////////////////////////////////////////////
//
// DumpTypedefs
//
// dump structures from ppm file to output file
//
// returns TRUE on success
//
/////////////////////////////////////////////////////////////////////////////
BOOL DumpTypedefs(FILE *pfilePpsfile, // file to write output
BOOL fDumpNamedOnly, // when set don't do unnamed
PRBTREE pHead) // known types function list
{
KNOWNTYPES *pknwntyp;
pknwntyp = pHead->pLastNodeInserted;
fprintf(pfilePpsfile,"[Typedefs]\n\n");
while (pknwntyp) {
fprintf(pfilePpsfile,
"%2.1x|%2.1x|%2.1x|%s|%s|%s|%s|%s|",
pknwntyp->Flags,
pknwntyp->IndLevel,
pknwntyp->Size,
pknwntyp->BasicType,
pknwntyp->BaseName ? pknwntyp->BaseName : szNULL,
pknwntyp->FuncRet ? pknwntyp->FuncRet : szNULL,
pknwntyp->FuncMod ? pknwntyp->FuncMod : szNULL,
pknwntyp->TypeName
);
DumpFuncinfo(pfilePpsfile, pknwntyp->pfuncinfo);
fprintf(pfilePpsfile, "|\n");
pknwntyp = pknwntyp->Next;
}
return(TRUE);
}
/////////////////////////////////////////////////////////////////////////////
//
// DumpStructures
//
// dump structures from ppm file to output file
//
// returns TRUE on success
//
/////////////////////////////////////////////////////////////////////////////
BOOL DumpStructures(FILE *pfilePpsfile, // file to write output
BOOL fDumpNamedOnly, // when set don't do unnamed
PRBTREE pHead) // known types function list
{
KNOWNTYPES *pknwntyp;
DWORD dw;
PMEMBERINFO pmeminfo;
pknwntyp = pHead->pLastNodeInserted;
fprintf(pfilePpsfile,"[Structures]\n\n");
while (pknwntyp) {
if (! fDumpNamedOnly || ! isdigit(*pknwntyp->TypeName)) {
fprintf(pfilePpsfile,
"%2.1x|%2.1x|%2.1x|%s|%s|%s|%s|%s|",
pknwntyp->Flags,
pknwntyp->IndLevel,
pknwntyp->Size,
pknwntyp->BasicType,
pknwntyp->BaseName ? pknwntyp->BaseName : szNULL,
pknwntyp->FuncRet ? pknwntyp->FuncRet : szNULL,
pknwntyp->FuncMod ? pknwntyp->FuncMod : szNULL,
pknwntyp->TypeName);
// dump out the structure member info, if present
pmeminfo = pknwntyp->pmeminfo;
while (pmeminfo) {
int i;
fprintf(pfilePpsfile, "%s", pmeminfo->sType);
i = pmeminfo->IndLevel;
if (i) {
fprintf(pfilePpsfile, " ");
while (i--) {
fprintf(pfilePpsfile, "*");
}
}
if (pmeminfo->sName) {
fprintf(pfilePpsfile, " %s", pmeminfo->sName);
}
fprintf(pfilePpsfile, " @ %d|", pmeminfo->dwOffset);
pmeminfo = pmeminfo->pmeminfoNext;
}
// dump out the function info, if present
DumpFuncinfo(pfilePpsfile, pknwntyp->pfuncinfo);
fprintf(pfilePpsfile, "\n");
}
pknwntyp = pknwntyp->Next;
}
return(TRUE);
}
/////////////////////////////////////////////////////////////////////////////
//
// DumpFunctions
//
// dump fucntion prototypes from ppm file to output file
//
// returns TRUE on success
//
/////////////////////////////////////////////////////////////////////////////
BOOL DumpFunctions(FILE *pfilePpsfile, // file to write output
BOOL fDumpNamedOnly, // when set don't do unnamed
PRBTREE pHead) // known types function list
{
KNOWNTYPES *pknwntyp;
PFUNCINFO pf;
pknwntyp = pHead->pLastNodeInserted;
fprintf(pfilePpsfile,"[Functions]\n\n");
while (pknwntyp) {
fprintf(pfilePpsfile,
"%s|%s|%s|%s|",
(pknwntyp->Flags & BTI_DLLEXPORT) ? "dllexport" : "",
pknwntyp->FuncRet,
pknwntyp->FuncMod ? pknwntyp->FuncMod : szNULL,
pknwntyp->TypeName
);
DumpFuncinfo(pfilePpsfile, pknwntyp->pfuncinfo);
fprintf(pfilePpsfile, "|\n");
pknwntyp = pknwntyp->Next;
}
return(TRUE);
}
/////////////////////////////////////////////////////////////////////////////
//
// Usgae
//
// tells how to use
//
//
/////////////////////////////////////////////////////////////////////////////
void Usage(char *s) // name of command invoked
{
printf("Usage:\n");
printf(" %s -d -n -x <ppm file> <pps output file>\n", s);
printf(" -d set debug flag\n");
printf(" -n dumps only named structs/enums/unions\n");
printf(" -x creates ppswind.h for size/offset checking\n");
}
/////////////////////////////////////////////////////////////////////////////
//
// ParseArgumaners
//
// parse arguments
//
// returnms FALSE on syntax error
//
/////////////////////////////////////////////////////////////////////////////
BOOL ParseArguments(int argc, char *argv[], char *sPpmfile, char *sPpsfile,
BOOL *pfDumpNamedOnly, BOOL *pfDebug,
BOOL *pfDumpCCheck)
{
int i;
*sPpmfile = 0;
*sPpsfile = 0;
*pfDumpNamedOnly = FALSE;
*pfDebug = FALSE;
*pfDumpCCheck = FALSE;
for (i = 1; i < argc; i++)
{
if (*argv[i] == '-')
{
switch(tolower(argv[i][1]))
{
case 'd':
{
*pfDebug = TRUE;
break;
}
case 'n':
{
*pfDumpNamedOnly = TRUE;
break;
}
case 'x':
{
*pfDumpCCheck = TRUE;
break;
}
default:
{
return(FALSE);
}
}
} else {
if (lstrlenA(argv[i]) >= MAX_PATH)
{
return(FALSE);
}
if (*sPpmfile == 0)
{
strcpy(sPpmfile, argv[i]);
} else if (*sPpsfile == 0)
{
strcpy(sPpsfile, argv[i]);
} else {
return(FALSE);
}
}
}
return( *pfDumpCCheck || ((*sPpmfile != 0) && (*sPpsfile != 0)));
}
void
HandlePreprocessorDirective(
char *p
)
{
ExitErrMsg(FALSE, "Preprocessor directives not allowed by ppm2pps\n");
}