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.

415 lines
9.8 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. hextract.c
  5. Abstract:
  6. This is the main module for a header the file extractor.
  7. Author:
  8. Andre Vachon (andreva) 13-Feb-1992
  9. Mark Lucovsky (markl) 28-Jan-1991
  10. Revision History:
  11. --*/
  12. #include <assert.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <ctype.h>
  17. #include <common.ver>
  18. //
  19. // Function declarations
  20. //
  21. int
  22. ProcessParameters(
  23. int argc,
  24. char *argv[]
  25. );
  26. void
  27. ProcessSourceFile( void );
  28. void
  29. ProcessLine(
  30. char *s
  31. );
  32. //
  33. // Global Data
  34. //
  35. unsigned char LineFiltering = 0;
  36. char *LineTag;
  37. char *ExcludeLineTag;
  38. char *MultiLineTagStart;
  39. char *MultiLineTagEnd;
  40. char *CommentDelimiter = "//";
  41. char *OutputFileName;
  42. char *SourceFileName;
  43. char **SourceFileList;
  44. int SourceFileCount;
  45. FILE *SourceFile, *OutputFile;
  46. #define STRING_BUFFER_SIZE 1024
  47. char StringBuffer[STRING_BUFFER_SIZE];
  48. #define BUILD_VER_COMMENT "/*++ BUILD Version: "
  49. #define BUILD_VER_COMMENT_LENGTH (sizeof( BUILD_VER_COMMENT )-1)
  50. int OutputVersion = 0;
  51. #define szVERSION "1.3"
  52. char const szUsage[] =
  53. "Microsoft (R) HEXTRACT Version " szVERSION " (NT)\n"
  54. VER_LEGALCOPYRIGHT_STR ". All rights reserved.\n"
  55. "\n"
  56. "Usage: HEXTRACT [options] filename1 [filename2 ...]\n"
  57. "\n"
  58. "Options:\n"
  59. " -f - filtering is turned on:\n"
  60. " ULONG, UCHAR, USHORT & NTSTATUS are\n"
  61. " replaced with DWORD, BYTE, WORD & DWORD.\n"
  62. " -f2 - Same as -f except ULONGLONG and ULONG_PTR\n"
  63. " isn't converted\n"
  64. " -o filename - required existing output filename;\n"
  65. " output is appended to filename\n"
  66. " -xt string - supplies the tag for excluding one line\n"
  67. " -lt string - supplies the tag for extracting one line\n"
  68. " -bt string1 string2 - supplies the starting and ending tags for\n"
  69. " extracting multiple lines\n"
  70. " filename1 [filename2 ...] - supplies files from which the definitions\n"
  71. " are extracted\n"
  72. "\n"
  73. "To be parsed properly, the tag strings must be located within a comment\n"
  74. "delimited by //\n"
  75. ;
  76. int
  77. __cdecl main( argc, argv )
  78. int argc;
  79. char *argv[];
  80. {
  81. char achver[BUILD_VER_COMMENT_LENGTH];
  82. if (!ProcessParameters(argc, argv) || NULL == OutputFileName) {
  83. fprintf(stderr, szUsage);
  84. return 1;
  85. }
  86. if ( (OutputFile = fopen(OutputFileName,"r+")) == 0) {
  87. fprintf(stderr,"HEXTRACT: Unable to open output file %s for update access\n",OutputFileName);
  88. return 1;
  89. }
  90. if (fseek(OutputFile, 0L, SEEK_END) == -1) {
  91. fprintf(stderr, "HEXTRACT: Unable to seek to end of %s\n", OutputFileName);
  92. return 1;
  93. }
  94. OutputVersion = 0;
  95. #ifdef HEXTRACT_DEBUG
  96. fprintf(
  97. stderr,
  98. "%s\n%s\n%s\n%s\n",
  99. LineTag,
  100. ExcludeLineTag,
  101. MultiLineTagStart,
  102. MultiLineTagEnd);
  103. #endif
  104. while ( SourceFileCount-- ) {
  105. SourceFileName = *SourceFileList++;
  106. if ( (SourceFile = fopen(SourceFileName,"r")) == 0) {
  107. fprintf(stderr,"HEXTRACT: Unable to open source file %s for read access\n",SourceFileName);
  108. return 1;
  109. }
  110. ProcessSourceFile();
  111. fclose(SourceFile);
  112. }
  113. if (fseek(OutputFile, 0L, SEEK_SET) == -1) {
  114. fprintf(stderr, "HEXTRACT: Unable to seek to start of %s\n", OutputFileName);
  115. return 1;
  116. }
  117. if (1 == fread(achver, BUILD_VER_COMMENT_LENGTH, 1, OutputFile) &&
  118. !strncmp(achver, BUILD_VER_COMMENT, BUILD_VER_COMMENT_LENGTH)) {
  119. if (fseek(OutputFile, (long)BUILD_VER_COMMENT_LENGTH, SEEK_SET) == -1) {
  120. fprintf(stderr, "HEXTRACT: Unable to seek past comments in %s\n", OutputFileName);
  121. return 1;
  122. }
  123. fprintf(OutputFile, "%04d", OutputVersion);
  124. }
  125. if (fseek(OutputFile, 0L, SEEK_END) == -1) {
  126. fprintf(stderr, "HEXTRACT: Unable to seek to end of %s\n", OutputFileName);
  127. return 1;
  128. }
  129. fclose(OutputFile);
  130. return( 0 );
  131. }
  132. int
  133. ProcessParameters(
  134. int argc,
  135. char *argv[]
  136. )
  137. {
  138. char c, *p;
  139. while (--argc) {
  140. p = *++argv;
  141. //
  142. // if we have a delimiter for a parameter, case throught the valid
  143. // parameter. Otherwise, the rest of the parameters are the list of
  144. // input files.
  145. //
  146. if (*p == '/' || *p == '-') {
  147. //
  148. // Switch on all the valid delimiters. If we don't get a valid
  149. // one, return with an error.
  150. //
  151. c = *++p;
  152. switch (toupper( c )) {
  153. case 'F':
  154. c = *++p;
  155. if ( (toupper ( c )) == '2')
  156. LineFiltering = 2;
  157. else
  158. LineFiltering = 1;
  159. break;
  160. case 'O':
  161. argc--, argv++;
  162. OutputFileName = *argv;
  163. break;
  164. case 'L':
  165. c = *++p;
  166. if ( (toupper ( c )) != 'T')
  167. return 0;
  168. argc--, argv++;
  169. LineTag = *argv;
  170. break;
  171. case 'B':
  172. c = *++p;
  173. if ( (toupper ( c )) != 'T')
  174. return 0;
  175. argc--, argv++;
  176. MultiLineTagStart = *argv;
  177. argc--, argv++;
  178. MultiLineTagEnd = *argv;
  179. break;
  180. case 'X':
  181. c = *++p;
  182. if ( (toupper ( c )) != 'T')
  183. return 0;
  184. argc--, argv++;
  185. ExcludeLineTag = *argv;
  186. break;
  187. default:
  188. return 0;
  189. }
  190. } else {
  191. //
  192. // Make the assumptionthat we have a valid command line if and
  193. // only if we have a list of filenames.
  194. //
  195. SourceFileList = argv;
  196. SourceFileCount = argc;
  197. return 1;
  198. }
  199. }
  200. return 0;
  201. }
  202. void
  203. ProcessSourceFile( void )
  204. {
  205. char *s;
  206. char *comment;
  207. char *tag;
  208. char *test;
  209. s = fgets(StringBuffer,STRING_BUFFER_SIZE,SourceFile);
  210. if (s) {
  211. if (!strncmp( s, BUILD_VER_COMMENT, BUILD_VER_COMMENT_LENGTH )) {
  212. OutputVersion += atoi( s + BUILD_VER_COMMENT_LENGTH );
  213. }
  214. }
  215. while ( s ) {
  216. //
  217. // Check for a block with delimiters
  218. //
  219. if (NULL != MultiLineTagStart) {
  220. comment = strstr(s,CommentDelimiter);
  221. if ( comment ) {
  222. tag = strstr(comment,MultiLineTagStart);
  223. if ( tag ) {
  224. //
  225. // Now that we have found an opening tag, check each
  226. // following line for the closing tag, and then include it
  227. // in the ouput.
  228. //
  229. s = fgets(StringBuffer,STRING_BUFFER_SIZE,SourceFile);
  230. while ( s ) {
  231. int fProcess = 1;
  232. comment = strstr(s,CommentDelimiter);
  233. if ( comment ) {
  234. tag = strstr(comment,MultiLineTagEnd);
  235. if ( tag ) {
  236. goto bottom;
  237. }
  238. if (NULL != ExcludeLineTag &&
  239. strstr(comment,ExcludeLineTag)) {
  240. fProcess = 0;
  241. }
  242. }
  243. if (fProcess) {
  244. ProcessLine(s);
  245. }
  246. s = fgets(StringBuffer,STRING_BUFFER_SIZE,SourceFile);
  247. }
  248. fprintf(stderr,
  249. "HEXTRACT: %s without matching %s in %s\n",
  250. MultiLineTagStart,
  251. MultiLineTagEnd,
  252. OutputFileName);
  253. exit(1);
  254. }
  255. }
  256. }
  257. //
  258. // Check for a single line to output.
  259. //
  260. if (NULL != LineTag) {
  261. comment = strstr(s,CommentDelimiter);
  262. if ( comment ) {
  263. tag = strstr(comment,LineTag);
  264. if ( tag ) {
  265. *comment++ = '\n';
  266. *comment = '\0';
  267. ProcessLine(s);
  268. goto bottom;
  269. }
  270. }
  271. }
  272. bottom:
  273. s = fgets(StringBuffer,STRING_BUFFER_SIZE,SourceFile);
  274. }
  275. }
  276. void
  277. ProcessLine(
  278. char *s
  279. )
  280. {
  281. char *t;
  282. char *s1;
  283. if (LineFiltering) {
  284. s1 = s;
  285. //
  286. // This should be replaced by a data file describing an input token
  287. // and an output token which would be used for the filtering.
  288. //
  289. while (t = strstr(s1,"ULONG")) {
  290. if (LineFiltering == 2) {
  291. if (!memcmp(t, "ULONGLONG", 9)) {
  292. s1+=9;
  293. } else if (!memcmp(t, "ULONG_PTR", 9)) {
  294. s1+=9;
  295. } else {
  296. memcpy(t,"DWORD",5);
  297. }
  298. } else {
  299. memcpy(t,"DWORD",5);
  300. }
  301. }
  302. while (t = strstr(s,"UCHAR"))
  303. memcpy(t,"BYTE ",5);
  304. while (t = strstr(s,"USHORT"))
  305. memcpy(t,"WORD ",6);
  306. while (t = strstr(s,"NTSTATUS"))
  307. memcpy(t,"DWORD ",8);
  308. }
  309. fputs(s,OutputFile);
  310. }