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

  1. //////////////////////////////////////////////////////////////////////////////
  2. // ppm2pps
  3. //
  4. // Copyright (c) 1996-1999 Microsoft Corporation
  5. //
  6. // Dump contents of ppm file
  7. //
  8. //////////////////////////////////////////////////////////////////////////////
  9. #include <nt.h>
  10. #include <ntrtl.h>
  11. #include <nturtl.h>
  12. #include <windows.h>
  13. #include <imagehlp.h>
  14. #include <ctype.h>
  15. #include <stdlib.h>
  16. #include <stdio.h>
  17. #include <string.h>
  18. #include "gen.h"
  19. // string to put in front of all error messages so that BUILD can find them.
  20. const char *ErrMsgPrefix = "NMAKE : U8603: 'PPM2PPS' ";
  21. //
  22. // global variables
  23. BOOL fDebug; // global debug flag
  24. BOOL fDumpCCheck; // when set build ppswind.h for checking sizes/offsets
  25. HANDLE hFile;
  26. HANDLE hMapFile = NULL;
  27. PRBTREE pFunctions = NULL;
  28. PRBTREE pStructures = NULL;
  29. PRBTREE pTypedefs = NULL;
  30. PKNOWNTYPES NIL = NULL;
  31. // function prototypes
  32. void __cdecl ErrMsg(char *pch, ...);
  33. void __cdecl ExitErrMsg(BOOL bSysError, char *pch, ...);
  34. BOOL DumpTypedefs(FILE *filePpsfile, // file to write output
  35. BOOL fDumpNamedOnly, // when set don't do unnamed
  36. PRBTREE pHead); // known types function list
  37. BOOL DumpStructures(FILE *filePpsfile, // file to write output
  38. BOOL fDumpNamedOnly, // when set don't do unnamed
  39. PRBTREE pHead); // known types function list
  40. BOOL DumpFunctions(FILE *filePpsfile, // file to write output
  41. BOOL fDumpNamedOnly, // when set don't do unnamed
  42. PRBTREE pHead); // known types function list
  43. void Usage(char *s);
  44. BOOL ParseArguments(int argc, char *argv[], char *sPpmfile, char *sPpsfile,
  45. BOOL *pfDumpNamedOnly, BOOL *pfDebug,
  46. BOOL *pfDumpCCheck);
  47. BOOL DumpCCheckHeader(PRBTREE pTypedefs, // typedef lsit
  48. PRBTREE pStructs); // structs sit
  49. int __cdecl main(int argc, char *argv[])
  50. {
  51. void *pvPpmData = NULL;
  52. BOOL fDumpNamedOnly;
  53. char sPpmfile[MAX_PATH];
  54. char sPpsfile[MAX_PATH];
  55. FILE *pfilePpsfile;
  56. try {
  57. if (! ParseArguments(argc, argv, sPpmfile, sPpsfile,
  58. &fDumpNamedOnly, &fDebug, &fDumpCCheck))
  59. {
  60. Usage(argv[0]);
  61. return(-1);
  62. }
  63. if (*sPpmfile)
  64. {
  65. PCVMHEAPHEADER pHeader;
  66. pvPpmData = MapPpmFile(sPpmfile, TRUE);
  67. pHeader = (PCVMHEAPHEADER)pvPpmData;
  68. pFunctions = &pHeader->FuncsList;
  69. pTypedefs = &pHeader->TypeDefsList;
  70. pStructures =&pHeader->StructsList;
  71. NIL =&pHeader->NIL;
  72. pfilePpsfile = fopen(sPpsfile, "w");
  73. if (pfilePpsfile == 0)
  74. {
  75. ErrMsg("ERROR - Could not open output file %s\n", sPpsfile);
  76. CloseHandle(hFile);
  77. CloseHandle(hMapFile);
  78. return(-1);
  79. }
  80. if (DumpFunctions(pfilePpsfile, fDumpNamedOnly,
  81. pFunctions))
  82. {
  83. if (DumpStructures(pfilePpsfile, fDumpNamedOnly,
  84. pStructures))
  85. {
  86. DumpTypedefs(pfilePpsfile,fDumpNamedOnly, pTypedefs);
  87. }
  88. }
  89. fclose(pfilePpsfile);
  90. }
  91. if (fDumpCCheck && pTypedefs && pStructures)
  92. {
  93. DumpCCheckHeader(pTypedefs, pStructures);
  94. }
  95. CloseHandle(hFile);
  96. CloseHandle(hMapFile);
  97. } except(EXCEPTION_EXECUTE_HANDLER) {
  98. ExitErrMsg(FALSE,
  99. "ExceptionCode=%x\n",
  100. GetExceptionCode()
  101. );
  102. }
  103. return(0);
  104. }
  105. void
  106. DumpFuncinfo(FILE *pfilePpsfile, PFUNCINFO pf)
  107. {
  108. while (pf) {
  109. int i;
  110. fprintf(pfilePpsfile,
  111. "%s %s%s %s %s %s",
  112. TokenString[pf->tkDirection],
  113. (pf->fIsPtr64) ? "__ptr64 " : "",
  114. TokenString[pf->tkPreMod],
  115. TokenString[pf->tkSUE],
  116. pf->sType,
  117. TokenString[pf->tkPrePostMod]
  118. );
  119. i = pf->IndLevel;
  120. while (i--) {
  121. fprintf(pfilePpsfile, "*");
  122. }
  123. fprintf(pfilePpsfile,
  124. "%s %s",
  125. TokenString[pf->tkPostMod],
  126. (pf->sName) ? pf->sName : ""
  127. );
  128. pf = pf->pfuncinfoNext;
  129. if (pf) {
  130. fprintf(pfilePpsfile, ", ");
  131. }
  132. }
  133. }
  134. /////////////////////////////////////////////////////////////////////////////
  135. //
  136. // DumpCCheckHeader
  137. //
  138. // dump header file that can be used to check sizes in ppm file against
  139. // those that are generated by C
  140. //
  141. // returns TRUE on success
  142. //
  143. /////////////////////////////////////////////////////////////////////////////
  144. BOOL DumpCCheckHeader(PRBTREE pTypedefs, // typedef lsit
  145. PRBTREE pStructs) // structs lsit
  146. {
  147. PKNOWNTYPES pknwntyp, pknwntypBasic;
  148. FILE *pfile;
  149. pfile = fopen("ppswind.h", "w");
  150. if (pfile == NULL)
  151. {
  152. ErrMsg("Error opening ppwind.h for output\n");
  153. return(FALSE);
  154. }
  155. fprintf(pfile, "CCHECKSIZE cchecksize[] = {\n");
  156. //
  157. // typedefs
  158. pknwntyp = pTypedefs->pLastNodeInserted;
  159. while (pknwntyp) {
  160. if ((! isdigit(*pknwntyp->TypeName)) &&
  161. (strcmp(pknwntyp->TypeName,"...")) &&
  162. (strcmp(pknwntyp->TypeName,"()")) &&
  163. (strcmp(pknwntyp->BasicType, szFUNC)) &&
  164. (pknwntyp->Size > 0) &&
  165. (pknwntyp->dwScopeLevel == 0)) {
  166. pknwntypBasic = GetBasicType(pknwntyp->TypeName,
  167. pTypedefs, pStructs);
  168. if (! ( (pknwntypBasic == NULL) ||
  169. ( (! strcmp(pknwntypBasic->BaseName, szVOID)) &&
  170. (pknwntypBasic->pmeminfo == NULL)))) {
  171. fprintf(pfile, " { %4d, sizeof(%s), \"%s\"}, \n",
  172. pknwntyp->Size,
  173. pknwntyp->TypeName,
  174. pknwntyp->TypeName);
  175. }
  176. }
  177. pknwntyp = pknwntyp->Next;
  178. }
  179. //
  180. // structs
  181. pknwntyp = pStructs->pLastNodeInserted;
  182. while (pknwntyp) {
  183. if ((! isdigit(*pknwntyp->TypeName) &&
  184. (pknwntyp->pmeminfo)))
  185. {
  186. if (!(pknwntyp->Flags & BTI_ANONYMOUS) && (pknwntyp->Size > 0) && (pknwntyp->dwScopeLevel == 0)) {
  187. fprintf(pfile, " { %4d, sizeof(%s %s), \"%s %s\" }, \n",
  188. pknwntyp->Size,
  189. pknwntyp->BaseName,
  190. pknwntyp->TypeName,
  191. pknwntyp->BaseName,
  192. pknwntyp->TypeName);
  193. }
  194. }
  195. pknwntyp = pknwntyp->Next;
  196. }
  197. fprintf(pfile, " {0xffffffff, 0xffffffff, \"\"}\n");
  198. fprintf(pfile,"\n};\n");
  199. //
  200. // structs fields
  201. fprintf(pfile, "CCHECKOFFSET ccheckoffset[] = {\n");
  202. pknwntyp = pStructs->pLastNodeInserted;
  203. while (pknwntyp) {
  204. if (! isdigit(*pknwntyp->TypeName))
  205. {
  206. if (!(pknwntyp->Flags & BTI_ANONYMOUS) && !(pknwntyp->Flags & BTI_VIRTUALONLY) && (pknwntyp->Size > 0) && (pknwntyp->dwScopeLevel == 0)) {
  207. PMEMBERINFO pmeminfo = pknwntyp->pmeminfo;
  208. while (pmeminfo != NULL) {
  209. if ((pmeminfo->sName != NULL) && (*pmeminfo->sName != 0) && !(pmeminfo->bIsBitfield))
  210. {
  211. fprintf(pfile, " { %4d, (long) (& (((%s %s *)0)->%s)), \"%s\", \"%s\" },\n",
  212. pmeminfo->dwOffset,
  213. pknwntyp->BaseName,
  214. pknwntyp->TypeName,
  215. pmeminfo->sName,
  216. pknwntyp->TypeName,
  217. pmeminfo->sName);
  218. }
  219. pmeminfo = pmeminfo->pmeminfoNext;
  220. }
  221. }
  222. }
  223. pknwntyp = pknwntyp->Next;
  224. }
  225. fprintf(pfile, " {0xffffffff, 0xffffffff, \"\", \"\"}\n");
  226. fprintf(pfile,"\n};\n");
  227. fclose(pfile);
  228. return(TRUE);
  229. }
  230. /////////////////////////////////////////////////////////////////////////////
  231. //
  232. // DumpTypedefs
  233. //
  234. // dump structures from ppm file to output file
  235. //
  236. // returns TRUE on success
  237. //
  238. /////////////////////////////////////////////////////////////////////////////
  239. BOOL DumpTypedefs(FILE *pfilePpsfile, // file to write output
  240. BOOL fDumpNamedOnly, // when set don't do unnamed
  241. PRBTREE pHead) // known types function list
  242. {
  243. KNOWNTYPES *pknwntyp;
  244. pknwntyp = pHead->pLastNodeInserted;
  245. fprintf(pfilePpsfile,"[Typedefs]\n\n");
  246. while (pknwntyp) {
  247. fprintf(pfilePpsfile,
  248. "%2.1x|%2.1x|%2.1x|%s|%s|%s|%s|%s|",
  249. pknwntyp->Flags,
  250. pknwntyp->IndLevel,
  251. pknwntyp->Size,
  252. pknwntyp->BasicType,
  253. pknwntyp->BaseName ? pknwntyp->BaseName : szNULL,
  254. pknwntyp->FuncRet ? pknwntyp->FuncRet : szNULL,
  255. pknwntyp->FuncMod ? pknwntyp->FuncMod : szNULL,
  256. pknwntyp->TypeName
  257. );
  258. DumpFuncinfo(pfilePpsfile, pknwntyp->pfuncinfo);
  259. fprintf(pfilePpsfile, "|\n");
  260. pknwntyp = pknwntyp->Next;
  261. }
  262. return(TRUE);
  263. }
  264. /////////////////////////////////////////////////////////////////////////////
  265. //
  266. // DumpStructures
  267. //
  268. // dump structures from ppm file to output file
  269. //
  270. // returns TRUE on success
  271. //
  272. /////////////////////////////////////////////////////////////////////////////
  273. BOOL DumpStructures(FILE *pfilePpsfile, // file to write output
  274. BOOL fDumpNamedOnly, // when set don't do unnamed
  275. PRBTREE pHead) // known types function list
  276. {
  277. KNOWNTYPES *pknwntyp;
  278. DWORD dw;
  279. PMEMBERINFO pmeminfo;
  280. pknwntyp = pHead->pLastNodeInserted;
  281. fprintf(pfilePpsfile,"[Structures]\n\n");
  282. while (pknwntyp) {
  283. if (! fDumpNamedOnly || ! isdigit(*pknwntyp->TypeName)) {
  284. fprintf(pfilePpsfile,
  285. "%2.1x|%2.1x|%2.1x|%s|%s|%s|%s|%s|",
  286. pknwntyp->Flags,
  287. pknwntyp->IndLevel,
  288. pknwntyp->Size,
  289. pknwntyp->BasicType,
  290. pknwntyp->BaseName ? pknwntyp->BaseName : szNULL,
  291. pknwntyp->FuncRet ? pknwntyp->FuncRet : szNULL,
  292. pknwntyp->FuncMod ? pknwntyp->FuncMod : szNULL,
  293. pknwntyp->TypeName);
  294. // dump out the structure member info, if present
  295. pmeminfo = pknwntyp->pmeminfo;
  296. while (pmeminfo) {
  297. int i;
  298. fprintf(pfilePpsfile, "%s", pmeminfo->sType);
  299. i = pmeminfo->IndLevel;
  300. if (i) {
  301. fprintf(pfilePpsfile, " ");
  302. while (i--) {
  303. fprintf(pfilePpsfile, "*");
  304. }
  305. }
  306. if (pmeminfo->sName) {
  307. fprintf(pfilePpsfile, " %s", pmeminfo->sName);
  308. }
  309. fprintf(pfilePpsfile, " @ %d|", pmeminfo->dwOffset);
  310. pmeminfo = pmeminfo->pmeminfoNext;
  311. }
  312. // dump out the function info, if present
  313. DumpFuncinfo(pfilePpsfile, pknwntyp->pfuncinfo);
  314. fprintf(pfilePpsfile, "\n");
  315. }
  316. pknwntyp = pknwntyp->Next;
  317. }
  318. return(TRUE);
  319. }
  320. /////////////////////////////////////////////////////////////////////////////
  321. //
  322. // DumpFunctions
  323. //
  324. // dump fucntion prototypes from ppm file to output file
  325. //
  326. // returns TRUE on success
  327. //
  328. /////////////////////////////////////////////////////////////////////////////
  329. BOOL DumpFunctions(FILE *pfilePpsfile, // file to write output
  330. BOOL fDumpNamedOnly, // when set don't do unnamed
  331. PRBTREE pHead) // known types function list
  332. {
  333. KNOWNTYPES *pknwntyp;
  334. PFUNCINFO pf;
  335. pknwntyp = pHead->pLastNodeInserted;
  336. fprintf(pfilePpsfile,"[Functions]\n\n");
  337. while (pknwntyp) {
  338. fprintf(pfilePpsfile,
  339. "%s|%s|%s|%s|",
  340. (pknwntyp->Flags & BTI_DLLEXPORT) ? "dllexport" : "",
  341. pknwntyp->FuncRet,
  342. pknwntyp->FuncMod ? pknwntyp->FuncMod : szNULL,
  343. pknwntyp->TypeName
  344. );
  345. DumpFuncinfo(pfilePpsfile, pknwntyp->pfuncinfo);
  346. fprintf(pfilePpsfile, "|\n");
  347. pknwntyp = pknwntyp->Next;
  348. }
  349. return(TRUE);
  350. }
  351. /////////////////////////////////////////////////////////////////////////////
  352. //
  353. // Usgae
  354. //
  355. // tells how to use
  356. //
  357. //
  358. /////////////////////////////////////////////////////////////////////////////
  359. void Usage(char *s) // name of command invoked
  360. {
  361. printf("Usage:\n");
  362. printf(" %s -d -n -x <ppm file> <pps output file>\n", s);
  363. printf(" -d set debug flag\n");
  364. printf(" -n dumps only named structs/enums/unions\n");
  365. printf(" -x creates ppswind.h for size/offset checking\n");
  366. }
  367. /////////////////////////////////////////////////////////////////////////////
  368. //
  369. // ParseArgumaners
  370. //
  371. // parse arguments
  372. //
  373. // returnms FALSE on syntax error
  374. //
  375. /////////////////////////////////////////////////////////////////////////////
  376. BOOL ParseArguments(int argc, char *argv[], char *sPpmfile, char *sPpsfile,
  377. BOOL *pfDumpNamedOnly, BOOL *pfDebug,
  378. BOOL *pfDumpCCheck)
  379. {
  380. int i;
  381. *sPpmfile = 0;
  382. *sPpsfile = 0;
  383. *pfDumpNamedOnly = FALSE;
  384. *pfDebug = FALSE;
  385. *pfDumpCCheck = FALSE;
  386. for (i = 1; i < argc; i++)
  387. {
  388. if (*argv[i] == '-')
  389. {
  390. switch(tolower(argv[i][1]))
  391. {
  392. case 'd':
  393. {
  394. *pfDebug = TRUE;
  395. break;
  396. }
  397. case 'n':
  398. {
  399. *pfDumpNamedOnly = TRUE;
  400. break;
  401. }
  402. case 'x':
  403. {
  404. *pfDumpCCheck = TRUE;
  405. break;
  406. }
  407. default:
  408. {
  409. return(FALSE);
  410. }
  411. }
  412. } else {
  413. if (lstrlenA(argv[i]) >= MAX_PATH)
  414. {
  415. return(FALSE);
  416. }
  417. if (*sPpmfile == 0)
  418. {
  419. strcpy(sPpmfile, argv[i]);
  420. } else if (*sPpsfile == 0)
  421. {
  422. strcpy(sPpsfile, argv[i]);
  423. } else {
  424. return(FALSE);
  425. }
  426. }
  427. }
  428. return( *pfDumpCCheck || ((*sPpmfile != 0) && (*sPpsfile != 0)));
  429. }
  430. void
  431. HandlePreprocessorDirective(
  432. char *p
  433. )
  434. {
  435. ExitErrMsg(FALSE, "Preprocessor directives not allowed by ppm2pps\n");
  436. }