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.

562 lines
12 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. genlvl.c
  5. Abstract:
  6. This module implements a program which generates the debug print filter
  7. component id enumeration and the system filter table that are used by
  8. various components in the system to dynamically filter debug print
  9. output.
  10. Two files are generated by this program. A header file that declares an
  11. enumeration of debug print filter component id, and a source file that
  12. declares and initializes the individual component filter variables.
  13. Author:
  14. David N. Cutler (davec) 7-Jan-2000
  15. Environment:
  16. User mode.
  17. Revision History:
  18. None.
  19. --*/
  20. #include <windows.h>
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <string.h>
  24. #include <malloc.h>
  25. //
  26. // Increment this everytime a change to this file is made.
  27. //
  28. #define GENLVL_VERSION "1.0"
  29. //
  30. // Define component name table.
  31. //
  32. #define MAXIMUM_NAMES 4096
  33. PCHAR ComponentNameTable[MAXIMUM_NAMES + 1] = {NULL};
  34. //
  35. // Define forward referenced prototypes.
  36. //
  37. ULONG
  38. InsertName(
  39. IN PCHAR NewName
  40. );
  41. ULONG
  42. GenerateCmHeaderFile(
  43. FILE *OutputFile
  44. );
  45. ULONG
  46. GenerateCmSourceFile(
  47. FILE *OutputFile
  48. );
  49. ULONG
  50. GenerateKdSourceFile(
  51. FILE *OutputFile
  52. );
  53. ULONG
  54. GenerateNtHeaderFile(
  55. FILE *OutputFile
  56. );
  57. //
  58. // Main program.
  59. //
  60. int __cdecl
  61. main(
  62. int argc,
  63. char *argv[]
  64. )
  65. {
  66. CHAR Buffer[132];
  67. CHAR CmHeaderFileName[128];
  68. FILE *CmHeaderFile;
  69. CHAR CmSourceFileName[128];
  70. FILE *CmSourceFile;
  71. ULONG Count;
  72. PCHAR ComponentDirectory;
  73. FILE *ComponentFile = NULL;
  74. CHAR ComponentFileName[128];
  75. int ExitCode = 0;
  76. CHAR NtHeaderFileName[128];
  77. FILE *NtHeaderFile = NULL;
  78. FILE *KdSourceFile = NULL;
  79. CHAR KdSourceFileName[128];
  80. PCHAR TargetDirectory;
  81. //
  82. // Parse arguments.
  83. //
  84. if (argc == 2 && (!strcmp(argv[1],"-?") || !strcmp(argv[1],"/?"))) {
  85. goto PrintUsage;
  86. }
  87. //
  88. // Determine name of target directory for generated files. This requires
  89. // the -t switch be specified and that the argument after the switch is
  90. // the target directory name. If no -t switch is specfied, then default
  91. // to ".".
  92. //
  93. if (argc >= 3 && !_stricmp(argv[1],"-t")) {
  94. TargetDirectory = argv[2];
  95. argc -= 2;
  96. argv += 2;
  97. } else {
  98. TargetDirectory = ".";
  99. }
  100. //
  101. // Determine name of the component id directory. This is the last input
  102. // command line argument. If a component id directory is not specified,
  103. // then default to ".".
  104. //
  105. if (argc >= 2) {
  106. ComponentDirectory = argv[1];
  107. argc -= 1;
  108. argv += 1;
  109. } else {
  110. ComponentDirectory = ".";
  111. }
  112. //
  113. // There should be no more arguments.
  114. //
  115. if (argc != 1) {
  116. printf("\n Manformed command line\n");
  117. ExitCode = 1;
  118. goto PrintUsage;
  119. }
  120. //
  121. // Open the component id input file.
  122. //
  123. sprintf(&ComponentFileName[0], "%s\\componentid.tab", ComponentDirectory);
  124. ComponentFile = fopen(&ComponentFileName[0], "r");
  125. if (!ComponentFile) {
  126. printf("\n Unable to open component id file %s\n", &ComponentFileName[0]);
  127. ExitCode = 1;
  128. goto PrintUsage;
  129. }
  130. //
  131. // Open the kernel debugger source output file.
  132. //
  133. sprintf(&KdSourceFileName[0], "%s\\dpfilter.c", TargetDirectory);
  134. KdSourceFile = fopen(&KdSourceFileName[0], "w");
  135. if (!KdSourceFile) {
  136. printf("\n Unable to open filter source file %s\n", &KdSourceFileName[0]);
  137. ExitCode = 1;
  138. goto PrintUsage;
  139. }
  140. //
  141. // Open the configuration manager header output file.
  142. //
  143. sprintf(&CmHeaderFileName[0], "%s\\dpfiltercm.h", TargetDirectory);
  144. CmHeaderFile = fopen(&CmHeaderFileName[0], "w");
  145. if (!CmHeaderFile) {
  146. printf("\n Unable to open filter source file %s\n", &CmHeaderFileName[0]);
  147. ExitCode = 1;
  148. goto PrintUsage;
  149. }
  150. //
  151. // Open the configuration manager source output file.
  152. //
  153. sprintf(&CmSourceFileName[0], "%s\\dpfiltercm.c", TargetDirectory);
  154. CmSourceFile = fopen(&CmSourceFileName[0], "w");
  155. if (!CmSourceFile) {
  156. printf("\n Unable to open filter source file %s\n", &CmSourceFileName[0]);
  157. ExitCode = 1;
  158. goto PrintUsage;
  159. }
  160. //
  161. // Open the ntrtl.w append header output file.
  162. //
  163. sprintf(&NtHeaderFileName[0], "%s\\dpfilter.h", TargetDirectory);
  164. NtHeaderFile = fopen(&NtHeaderFileName[0], "w");
  165. if (!NtHeaderFile) {
  166. printf("\n Unable to open filter header file %s\n", &NtHeaderFileName[0]);
  167. ExitCode = 1;
  168. PrintUsage:
  169. printf("GENLVL: Debug Print Filter Generator. Version " GENLVL_VERSION "\n");
  170. printf(" Usage: genlvl [-t target directory] [componentid.tab directory]\n");
  171. goto Exit;
  172. }
  173. //
  174. // Read component id table.
  175. //
  176. Count = 0;
  177. while (fgets(&Buffer[0], 132, ComponentFile) != NULL) {
  178. //
  179. // If the the line is null, begins with a blank, or begins with
  180. // a semicolon, then skip it.
  181. //
  182. if ((Buffer[0] == 0) ||
  183. (Buffer[0] == '\n') ||
  184. (Buffer[0] == ' ') ||
  185. (Buffer[0] == ';')) {
  186. continue;
  187. }
  188. //
  189. // Insert the component name in the component name table.
  190. //
  191. Count += InsertName(&Buffer[0]);
  192. if (Count >= MAXIMUM_NAMES) {
  193. printf(" Component name table overflow at name %s\n", &Buffer[0]);
  194. ExitCode = 1;
  195. goto Exit;
  196. }
  197. }
  198. //
  199. // Check to determine if an error of eof was encountered.
  200. //
  201. if (feof(ComponentFile) == 0) {
  202. printf(" Error encountered while reading component name file\n");
  203. ExitCode = 1;
  204. goto Exit;
  205. }
  206. //
  207. // Generate configuration manager header file.
  208. //
  209. if (GenerateCmHeaderFile(CmHeaderFile) == 0) {
  210. ExitCode = 1;
  211. goto Exit;
  212. }
  213. //
  214. // Generate configuration manager source file.
  215. //
  216. if (GenerateCmSourceFile(CmSourceFile) == 0) {
  217. ExitCode = 1;
  218. goto Exit;
  219. }
  220. //
  221. // Generate kernel debugger source file.
  222. //
  223. if (GenerateKdSourceFile(KdSourceFile) == 0) {
  224. ExitCode = 1;
  225. goto Exit;
  226. }
  227. //
  228. // Generate ntrtl.w append header file.
  229. //
  230. if (GenerateNtHeaderFile(NtHeaderFile) == 0) {
  231. ExitCode = 1;
  232. goto Exit;
  233. }
  234. //
  235. // Common program exit.
  236. //
  237. // Close any files that are open and exit with appropriate exit code.
  238. //
  239. Exit:
  240. if (CmHeaderFile != NULL) {
  241. fclose(CmHeaderFile);
  242. }
  243. if (CmSourceFile != NULL) {
  244. fclose(CmSourceFile);
  245. }
  246. if (ComponentFile != NULL) {
  247. fclose(ComponentFile);
  248. }
  249. if (KdSourceFile != NULL) {
  250. fclose(KdSourceFile);
  251. }
  252. if (NtHeaderFile != NULL) {
  253. fclose(NtHeaderFile);
  254. }
  255. return ExitCode;
  256. }
  257. ULONG
  258. GenerateCmHeaderFile(
  259. FILE *OutputFile
  260. )
  261. {
  262. ULONG Count;
  263. PCHAR Name;
  264. //
  265. // Generate opening comments.
  266. //
  267. fprintf(OutputFile, "//\n");
  268. fprintf(OutputFile, "// External component filter level definitions.\n");
  269. fprintf(OutputFile, "//\n");
  270. fprintf(OutputFile, "\n");
  271. //
  272. // Output all the component variable names.
  273. //
  274. Count = 0;
  275. while ((Name = ComponentNameTable[Count]) != NULL) {
  276. fprintf(OutputFile, "extern ULONG Kd_%s_Mask;\n", Name);
  277. Count += 1;
  278. }
  279. fprintf(OutputFile, "\n");
  280. return TRUE;
  281. }
  282. ULONG
  283. GenerateCmSourceFile(
  284. FILE *OutputFile
  285. )
  286. {
  287. ULONG Count;
  288. PCHAR Name;
  289. //
  290. // Generate opening comments.
  291. //
  292. fprintf(OutputFile, "//\n");
  293. fprintf(OutputFile, "// Debug print filter level initialization.\n");
  294. fprintf(OutputFile, "//\n");
  295. fprintf(OutputFile, "\n");
  296. //
  297. // Output all the component variable names.
  298. //
  299. Count = 0;
  300. while ((Name = ComponentNameTable[Count]) != NULL) {
  301. fprintf(OutputFile, " { L\"Session Manager\\\\Debug Print Filter\",\n");
  302. fprintf(OutputFile, " L\"%s\",\n", Name);
  303. fprintf(OutputFile, " &Kd_%s_Mask,\n", Name);
  304. fprintf(OutputFile, " NULL,\n");
  305. fprintf(OutputFile, " NULL\n");
  306. fprintf(OutputFile, " },\n");
  307. fprintf(OutputFile, "\n");
  308. Count += 1;
  309. }
  310. return TRUE;
  311. }
  312. ULONG
  313. GenerateKdSourceFile(
  314. FILE *OutputFile
  315. )
  316. {
  317. ULONG Count;
  318. PCHAR Name;
  319. //
  320. // Generate opening comments and typedef.
  321. //
  322. fprintf(OutputFile, "//\n");
  323. fprintf(OutputFile, "// Component filter levels.\n");
  324. fprintf(OutputFile, "//\n");
  325. fprintf(OutputFile, "\n");
  326. //
  327. // Output all the component variable names with initialization.
  328. //
  329. Count = 0;
  330. while ((Name = ComponentNameTable[Count]) != NULL) {
  331. fprintf(OutputFile, "ULONG Kd_%s_Mask = 0;\n", Name);
  332. Count += 1;
  333. }
  334. fprintf(OutputFile, "ULONG Kd_ENDOFTABLE_Mask = 0;\n");
  335. //
  336. // Output the initialization of the component variable table.
  337. //
  338. fprintf(OutputFile, "\n");
  339. fprintf(OutputFile, "//\n");
  340. fprintf(OutputFile, "// Component debug print filter table.\n");
  341. fprintf(OutputFile, "//\n");
  342. fprintf(OutputFile, "\n");
  343. fprintf(OutputFile, "PULONG KdComponentTable[] = {\n");
  344. Count = 0;
  345. while ((Name = ComponentNameTable[Count]) != NULL) {
  346. fprintf(OutputFile, " &Kd_%s_Mask,\n", Name);
  347. Count += 1;
  348. }
  349. //
  350. // Output one final dummy entry and close the initialization.
  351. //
  352. fprintf(OutputFile, " &Kd_ENDOFTABLE_Mask\n");
  353. fprintf(OutputFile, "};\n");
  354. fprintf(OutputFile, "\n");
  355. return TRUE;
  356. }
  357. ULONG
  358. GenerateNtHeaderFile(
  359. FILE *OutputFile
  360. )
  361. {
  362. ULONG Count;
  363. PCHAR Name;
  364. //
  365. // Generate opening comments and typedef.
  366. //
  367. fprintf(OutputFile, "//\n");
  368. fprintf(OutputFile, "// Component name filter id enumeration and levels.\n");
  369. fprintf(OutputFile, "//\n");
  370. fprintf(OutputFile, "\n");
  371. fprintf(OutputFile, "#define DPFLTR_ERROR_LEVEL 0\n");
  372. fprintf(OutputFile, "#define DPFLTR_WARNING_LEVEL 1\n");
  373. fprintf(OutputFile, "#define DPFLTR_TRACE_LEVEL 2\n");
  374. fprintf(OutputFile, "#define DPFLTR_INFO_LEVEL 3\n");
  375. fprintf(OutputFile, "#define DPFLTR_MASK 0x80000000\n");
  376. fprintf(OutputFile, "\n");
  377. fprintf(OutputFile, "typedef enum _DPFLTR_TYPE {\n");
  378. //
  379. // Output all the enumerations.
  380. //
  381. Count = 0;
  382. while ((Name = ComponentNameTable[Count]) != NULL) {
  383. fprintf(OutputFile, " DPFLTR_%s_ID = %d,\n", Name, Count);
  384. Count += 1;
  385. }
  386. //
  387. // Output one final dummy entry and close the enumeration.
  388. //
  389. fprintf(OutputFile, " DPFLTR_ENDOFTABLE_ID\n");
  390. fprintf(OutputFile, "} DPFLTR_TYPE;\n");
  391. fprintf(OutputFile, "\n");
  392. return TRUE;
  393. }
  394. //
  395. // Insert component name in component name table.
  396. //
  397. ULONG
  398. InsertName(
  399. IN PCHAR NewName
  400. )
  401. {
  402. ULONG Index;
  403. ULONG Length;
  404. PCHAR OldName;
  405. //
  406. // Convert the input string to upper case.
  407. //
  408. Length = 0;
  409. while (NewName[Length] != 0) {
  410. if (NewName[Length] == '\n') {
  411. NewName[Length] = 0;
  412. break;
  413. }
  414. NewName[Length] = (CHAR)toupper(NewName[Length]);
  415. Length += 1;
  416. }
  417. //
  418. // Search for a duplicate name in the component name table.
  419. //
  420. Index = 0;
  421. while ((OldName = ComponentNameTable[Index]) != NULL) {
  422. if (strcmp(OldName, NewName) == 0) {
  423. printf(" Duplicate component name %s ignored.\n", NewName);
  424. return 0;
  425. }
  426. Index += 1;
  427. }
  428. //
  429. // Allocate a new table entry, copy the new name to the entry, and
  430. // insert the new entry in the table.
  431. //
  432. OldName = malloc(Length + 1);
  433. if (!OldName) {
  434. printf("Out of memory\n");
  435. return 0;
  436. }
  437. strcpy(OldName, NewName);
  438. ComponentNameTable[Index] = OldName;
  439. ComponentNameTable[Index + 1] = NULL;
  440. return 1;
  441. }