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.

552 lines
12 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. #if DEVL
  4. typedef enum {
  5. CmdNone,
  6. CmdHelp,
  7. CmdGo,
  8. CmdList,
  9. CmdTrace,
  10. CmdSymbol,
  11. CmdTraceback,
  12. CmdCurrent,
  13. CmdNearestLabel,
  14. CmdBreak
  15. } InfCmd;
  16. BOOL StopAtLine = FALSE;
  17. CHAR CmdBuffer[256];
  18. #endif
  19. BOOL
  20. SdpReconstructLine(
  21. IN PINFLINE MasterLineArray,
  22. IN UINT MasterLineCount,
  23. IN UINT Line,
  24. OUT PUCHAR Buffer,
  25. IN UINT BufferSize
  26. )
  27. /*++
  28. Routine Description:
  29. Reconstruct a pseudo-line in an inf file, placing it into the
  30. global temporary buffer.
  31. Arguments:
  32. MasterLineArray - supplies master line array for inf in question
  33. MasterLineCount - supplies # of pseudo-lines in the inf
  34. Line - supplies pseudo-line # of line to dump
  35. Buffer - supplies output buffer
  36. BufferSize - supplies max # characters that fit into Buffer
  37. Return Value:
  38. None.
  39. --*/
  40. {
  41. PCHAR pIn;
  42. PCHAR pOut = Buffer;
  43. PINFLINE InfLine;
  44. UCHAR c;
  45. InfLine = &MasterLineArray[Line];
  46. pIn = InfLine->text.addr;
  47. memset(Buffer,0,BufferSize);
  48. if(InfLine->flags & INFLINE_SECTION) {
  49. *pOut++ = '[';
  50. lstrcpy(pOut,pIn);
  51. lstrcat(pOut,"]");
  52. } else {
  53. if(InfLine->flags & INFLINE_KEY) {
  54. lstrcpy(pOut,pIn);
  55. lstrcat(pOut," = ");
  56. pOut += lstrlen(pOut);
  57. pIn += lstrlen(pIn);
  58. }
  59. while(pIn < MasterLineArray[Line+1].text.addr) {
  60. switch(c = *pIn++) {
  61. case TOKEN_VARIABLE:
  62. *pOut++ = '$';
  63. *pOut++ = '(';
  64. break;
  65. case TOKEN_LIST_FROM_SECTION_NTH_ITEM:
  66. *pOut++ = '^';
  67. *pOut++ = '(';
  68. break;
  69. case TOKEN_LOCATE_ITEM_IN_LIST:
  70. *pOut++ = '~';
  71. *pOut++ = '(';
  72. break;
  73. case TOKEN_NTH_ITEM_FROM_LIST:
  74. *pOut++ = '*';
  75. *pOut++ = '(';
  76. break;
  77. case TOKEN_FIELD_ADDRESSOR:
  78. *pOut++ = '#';
  79. *pOut++ = '(';
  80. break;
  81. case TOKEN_APPEND_ITEM_TO_LIST:
  82. *pOut++ = '>';
  83. *pOut++ = '(';
  84. break;
  85. case TOKEN_LIST_START:
  86. *pOut++ = '{';
  87. break;
  88. case TOKEN_LIST_END:
  89. *pOut++ = '}';
  90. break;
  91. case TOKEN_SPACE:
  92. *pOut++ = ' ';
  93. break;
  94. case TOKEN_COMMA:
  95. *pOut++ = ',';
  96. break;
  97. case TOKEN_RIGHT_PAREN:
  98. *pOut++ = ')';
  99. break;
  100. default:
  101. if(IS_STRING_TOKEN(c)) {
  102. ULONG len;
  103. switch(c) {
  104. case TOKEN_STRING:
  105. len = (ULONG)(*pIn++) + 100;
  106. break;
  107. case TOKEN_LONG_STRING:
  108. len = (ULONG)((*pIn++) << 8) + (ULONG)(*pIn++);
  109. break;
  110. default:
  111. // short string
  112. len = c - TOKEN_SHORT_STRING;
  113. break;
  114. }
  115. strncpy(pOut,pIn,len);
  116. pOut += len;
  117. pIn += len;
  118. }
  119. break;
  120. }
  121. }
  122. }
  123. return(TRUE);
  124. }
  125. #if DEVL
  126. VOID
  127. SdTracingOn(
  128. VOID
  129. )
  130. /*++
  131. Routine Description:
  132. Turn inf tracing on.
  133. Arguments:
  134. None.
  135. Return Value:
  136. None.
  137. --*/
  138. {
  139. StopAtLine = !StopAtLine;
  140. DbgPrint("SETUP: INF Tracing %s.\n",StopAtLine ? "on; will break at next line" : "off");
  141. }
  142. InfCmd
  143. SdGetCmd(
  144. PCHAR *CharAfterCmd
  145. )
  146. /*++
  147. Routine Description:
  148. Fetch a command from the user.
  149. Arguments:
  150. CharAfterCmd - receives a pointer to the character that terminated
  151. the command string.
  152. Return Value:
  153. member of InfCmd enum indicating which command the user entered
  154. --*/
  155. {
  156. PCHAR p;
  157. while(1) {
  158. DbgPrompt("setup>",CmdBuffer,sizeof(CmdBuffer));
  159. if(CmdBuffer[0]) {
  160. p = strpbrk(CmdBuffer," \t");
  161. *CharAfterCmd = p ? p : strchr(CmdBuffer,'\0');
  162. switch(tolower(CmdBuffer[0])) {
  163. case 'd':
  164. return(CmdSymbol);
  165. case 'g':
  166. return(CmdGo);
  167. case 'h':
  168. case '?':
  169. return(CmdHelp);
  170. case 'k':
  171. return(CmdTraceback);
  172. case 'l':
  173. if(tolower(CmdBuffer[1]) == 'n') {
  174. return(CmdNearestLabel);
  175. }
  176. break;
  177. case 'r':
  178. return(CmdCurrent);
  179. case 't':
  180. return(CmdTrace);
  181. case 'u':
  182. return(CmdList);
  183. case 'x':
  184. return(CmdBreak);
  185. }
  186. DbgPrint("%s: unknown command\n",CmdBuffer);
  187. }
  188. }
  189. }
  190. PCHAR
  191. SdpFindSection(
  192. IN PPARSED_INF ParsedInf,
  193. IN UINT Line
  194. )
  195. /*++
  196. Routine Description:
  197. Determine the section name of given pseudo-line.
  198. Arguments:
  199. ParsedInf - supplies a pointer to the inf parse structure for the
  200. inf file in which the line is located.
  201. Line - supplies the pseudo-line.
  202. Return Value:
  203. Name of the section, or NULL if it can't be determined
  204. --*/
  205. {
  206. INT L;
  207. PCHAR Section = NULL;
  208. for(L=(INT)Line; L>=0; --L) {
  209. if(ParsedInf->MasterLineArray[L].flags & INFLINE_SECTION) {
  210. Section = ParsedInf->MasterLineArray[L].text.addr;
  211. break;
  212. }
  213. }
  214. return(Section);
  215. }
  216. VOID
  217. SdpCurrentLineOut(
  218. IN UINT Line
  219. )
  220. /*++
  221. Routine Description:
  222. Dump out a line in the current context.
  223. Arguments:
  224. Line - supplies pseudo-line number of line to dump
  225. Return Value:
  226. None.
  227. --*/
  228. {
  229. PCHAR Section;
  230. CHAR buf[1024];
  231. //
  232. // Determine the current section name by searching backwards for
  233. // a line with its section flag set.
  234. //
  235. Section = SdpFindSection(pLocalInfTempInfo()->pParsedInf,Line);
  236. DbgPrint("%s.INF:[%s]\n",pLocalInfPermInfo()->szName,Section ? Section : "???");
  237. SdpReconstructLine( pLocalInfTempInfo()->pParsedInf->MasterLineArray,
  238. pLocalInfTempInfo()->pParsedInf->MasterLineCount,
  239. Line,
  240. buf,
  241. 1024
  242. );
  243. DbgPrint("%s\n",buf);
  244. }
  245. VOID
  246. SdpInfDebugPrompt(
  247. IN UINT Line
  248. )
  249. /*++
  250. Routine Description:
  251. Debug prompt. Accept a command from the user and act on it.
  252. If we got here via SdBreakNow, then not all commands will function
  253. as one might expect -- for example, tracing won't return until the
  254. next line is actually interpreted.
  255. Arguments:
  256. None.
  257. Return Value:
  258. None.
  259. --*/
  260. {
  261. CHAR buf[1024];
  262. PCHAR Section;
  263. INT L;
  264. UINT UL;
  265. PCHAR NextChar;
  266. BOOL looping = TRUE;
  267. InfCmd cmd;
  268. PINFCONTEXT Context;
  269. BOOL Found;
  270. PPARSED_INF ParsedInf;
  271. if(!StopAtLine) {
  272. return;
  273. }
  274. DbgPrint("\n");
  275. SdpCurrentLineOut(Line);
  276. while(looping) {
  277. switch(cmd = SdGetCmd(&NextChar)) {
  278. case CmdHelp:
  279. DbgPrint("d <symbol> - print current value of <symbol>\n");
  280. DbgPrint("g - go\n");
  281. DbgPrint("h,? - print this message\n");
  282. DbgPrint("k - crude traceback\n");
  283. DbgPrint("ln - list nearest preceding line in section with a key\n");
  284. DbgPrint("r - list current line again\n");
  285. DbgPrint("t - trace one line\n");
  286. DbgPrint("u - list a few lines starting at current line\n");
  287. DbgPrint("x - break into debugger\n");
  288. DbgPrint("\n");
  289. break;
  290. case CmdGo:
  291. StopAtLine = FALSE;
  292. looping = FALSE;
  293. break;
  294. case CmdTrace:
  295. StopAtLine = TRUE;
  296. looping = FALSE;
  297. break;
  298. case CmdList:
  299. //
  300. // List out a few lines.
  301. //
  302. for(UL=Line+1; (UL<pLocalInfTempInfo()->pParsedInf->MasterLineCount) && (UL<Line+6); UL++) {
  303. SdpReconstructLine( pLocalInfTempInfo()->pParsedInf->MasterLineArray,
  304. pLocalInfTempInfo()->pParsedInf->MasterLineCount,
  305. UL,
  306. buf,
  307. 1024
  308. );
  309. DbgPrint("%s\n",buf);
  310. }
  311. DbgPrint("\n");
  312. break;
  313. case CmdBreak:
  314. DbgUserBreakPoint();
  315. break;
  316. case CmdSymbol:
  317. //
  318. // Look up a symbol.
  319. //
  320. if(*NextChar) {
  321. PCHAR Value = SzFindSymbolValueInSymTab(NextChar+1);
  322. if(Value) {
  323. DbgPrint("Value = %s\n",Value);
  324. } else {
  325. DbgPrint("Symbol not found.\n");
  326. }
  327. } else {
  328. DbgPrint("No symbol given.\n");
  329. }
  330. DbgPrint("\n");
  331. break;
  332. case CmdTraceback:
  333. //
  334. // Perform a sort of crude traceback.
  335. //
  336. Context = pLocalContext()->pNext;
  337. while(Context) {
  338. Section = SdpFindSection(Context->pInfTempInfo->pParsedInf,Context->CurrentLine-1);
  339. DbgPrint("%s.INF:[%s]\n",Context->pInfTempInfo->pInfPermInfo->szName,Section ? Section : "???");
  340. SdpReconstructLine( Context->pInfTempInfo->pParsedInf->MasterLineArray,
  341. Context->pInfTempInfo->pParsedInf->MasterLineCount,
  342. Context->CurrentLine-1,
  343. buf,
  344. 1024
  345. );
  346. DbgPrint(" %s\n",buf);
  347. Context = Context->pNext;
  348. }
  349. DbgPrint("\n");
  350. break;
  351. case CmdNearestLabel:
  352. //
  353. // Search backwards for the nearest line w/ a key.
  354. //
  355. ParsedInf = pLocalInfTempInfo()->pParsedInf;
  356. for(Found=FALSE,L=(INT)Line; L>=0; --L) {
  357. if(ParsedInf->MasterLineArray[L].flags & INFLINE_KEY) {
  358. Found = TRUE;
  359. break;
  360. }
  361. if(ParsedInf->MasterLineArray[L].flags & INFLINE_SECTION) {
  362. break;
  363. }
  364. }
  365. if(Found) {
  366. SdpReconstructLine( ParsedInf->MasterLineArray,
  367. ParsedInf->MasterLineCount,
  368. (UINT)L,
  369. buf,
  370. 1024
  371. );
  372. DbgPrint("%s\n",buf);
  373. } else {
  374. DbgPrint("Key not found in this section.\n");
  375. }
  376. DbgPrint("\n");
  377. break;
  378. case CmdCurrent:
  379. //
  380. // Print the current line again
  381. //
  382. SdpCurrentLineOut(Line);
  383. DbgPrint("\n");
  384. break;
  385. }
  386. }
  387. }
  388. VOID
  389. SdAtNewLine(
  390. IN UINT Line
  391. )
  392. /*++
  393. Routine Description:
  394. This routine should be called just before execution of a new line.
  395. Arguments:
  396. None.
  397. Return Value:
  398. None.
  399. --*/
  400. {
  401. SdpInfDebugPrompt(Line);
  402. }
  403. VOID
  404. SdBreakNow(
  405. VOID
  406. )
  407. /*++
  408. Routine Description:
  409. Break into the inf debug prompt now.
  410. Arguments:
  411. None.
  412. Return Value:
  413. None.
  414. --*/
  415. {
  416. StopAtLine = TRUE;
  417. SdpInfDebugPrompt(pLocalContext()->CurrentLine-1);
  418. }
  419. #endif // DEVL