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.

476 lines
11 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Establish, maintain, and translate alias command tokens.
  4. //
  5. // Copyright (C) Microsoft Corporation, 1999-2002.
  6. //
  7. // Revision History:
  8. //
  9. // [-] 08-Aug-1999 RichG Created.
  10. //
  11. //----------------------------------------------------------------------------
  12. #include "ntsdp.hpp"
  13. PALIAS g_AliasListHead; // List of alias elements
  14. ULONG g_NumAliases;
  15. HRESULT
  16. SetAlias(PCSTR SrcText, PCSTR DstText)
  17. {
  18. PALIAS PrevAlias;
  19. PALIAS CurAlias;
  20. PALIAS NewAlias;
  21. NewAlias = (PALIAS)malloc( sizeof(ALIAS) + strlen(SrcText) +
  22. strlen(DstText) + 2 );
  23. if (!NewAlias)
  24. {
  25. return E_OUTOFMEMORY;
  26. }
  27. //
  28. // Locate Alias, or insertion point
  29. //
  30. // This insertion scheme maintains a sorted list of
  31. // alias elements by name.
  32. //
  33. PrevAlias = NULL;
  34. CurAlias = g_AliasListHead;
  35. while (( CurAlias != NULL ) &&
  36. ( strcmp( SrcText, CurAlias->Name ) > 0 ))
  37. {
  38. PrevAlias = CurAlias;
  39. CurAlias = CurAlias->Next;
  40. }
  41. // If there is already an element by that name, clear it.
  42. if (CurAlias != NULL &&
  43. !strcmp(SrcText, CurAlias->Name))
  44. {
  45. PALIAS TmpAlias = CurAlias->Next;
  46. free(CurAlias);
  47. CurAlias = TmpAlias;
  48. g_NumAliases--;
  49. }
  50. NewAlias->Next = CurAlias;
  51. if (PrevAlias == NULL)
  52. {
  53. g_AliasListHead = NewAlias;
  54. }
  55. else
  56. {
  57. PrevAlias->Next = NewAlias;
  58. }
  59. NewAlias->Name = (PSTR)(NewAlias + 1);
  60. NewAlias->Value = NewAlias->Name + strlen(SrcText) + 1;
  61. strcpy( NewAlias->Name, SrcText );
  62. strcpy( NewAlias->Value, DstText );
  63. g_NumAliases++;
  64. NotifyChangeEngineState(DEBUG_CES_TEXT_REPLACEMENTS, DEBUG_ANY_ID, TRUE);
  65. return S_OK;
  66. }
  67. /*** ParseSetAlias - Set an alias expression
  68. *
  69. * Purpose:
  70. * From the current command line position at g_CurCmd,
  71. * read the alias name and value tokens. Once obtained
  72. * perform an alias list lookup to see if it is a redefinition.
  73. * If not allocate a new alias element and place it on the
  74. * alias element list.
  75. *
  76. *
  77. * Input:
  78. * Global: g_CurCmd - command line position
  79. * Global: g_AliasListHead
  80. *
  81. * Returns:
  82. * Status
  83. *
  84. * Exceptions:
  85. * error exit: SYNTAX errors
  86. *
  87. *************************************************************************/
  88. void
  89. ParseSetAlias(void)
  90. {
  91. PSTR AliasName;
  92. PSTR AliasValue;
  93. CHAR Ch;
  94. //
  95. // Locate alias name
  96. //
  97. PeekChar();
  98. AliasName = g_CurCmd;
  99. do
  100. {
  101. Ch = *g_CurCmd++;
  102. } while (Ch != ' ' && Ch != '\t' && Ch != '\0' && Ch != ';');
  103. if ( (ULONG_PTR)(g_CurCmd - 1) == (ULONG_PTR)AliasName )
  104. {
  105. error(SYNTAX);
  106. }
  107. *--g_CurCmd = '\0'; // Back up and null terminate
  108. // the alias name token
  109. g_CurCmd++; // -> next char
  110. //
  111. // Locate alias value, take remaining cmd line as value
  112. //
  113. PeekChar();
  114. AliasValue = g_CurCmd;
  115. do
  116. {
  117. Ch = *g_CurCmd++;
  118. } while (Ch != '\t' && Ch != '\0');
  119. if ( (ULONG_PTR)(g_CurCmd - 1) == (ULONG_PTR)AliasValue )
  120. {
  121. error(SYNTAX);
  122. }
  123. *--g_CurCmd = '\0'; // Back up and Null terminate
  124. // the alias value token
  125. if (SetAlias(AliasName, AliasValue) != S_OK)
  126. {
  127. error(MEMORY);
  128. }
  129. }
  130. HRESULT
  131. DeleteAlias(PCSTR SrcText)
  132. {
  133. PALIAS CurAlias;
  134. if (SrcText[0] == '*' && SrcText[1] == 0)
  135. {
  136. //
  137. // Delete all aliases
  138. //
  139. while ( g_AliasListHead != NULL )
  140. {
  141. //
  142. // Unchain the element and free it
  143. //
  144. CurAlias = g_AliasListHead->Next;
  145. free(g_AliasListHead);
  146. g_AliasListHead = CurAlias;
  147. }
  148. g_NumAliases = 0;
  149. }
  150. else
  151. {
  152. PALIAS PrevAlias;
  153. //
  154. // Locate and delete the specified alias
  155. //
  156. PrevAlias = NULL;
  157. CurAlias = g_AliasListHead;
  158. while (( CurAlias != NULL ) &&
  159. ( strcmp( SrcText, CurAlias->Name )))
  160. {
  161. PrevAlias = CurAlias;
  162. CurAlias = CurAlias->Next;
  163. }
  164. if ( CurAlias == NULL )
  165. {
  166. return E_NOINTERFACE;
  167. }
  168. //
  169. // Unchain the element and free it
  170. //
  171. if (PrevAlias == NULL)
  172. {
  173. g_AliasListHead = CurAlias->Next;
  174. }
  175. else
  176. {
  177. PrevAlias->Next = CurAlias->Next;
  178. }
  179. free( CurAlias );
  180. g_NumAliases--;
  181. }
  182. NotifyChangeEngineState(DEBUG_CES_TEXT_REPLACEMENTS, DEBUG_ANY_ID, TRUE);
  183. return S_OK;
  184. }
  185. /*** ParseDeleteAlias - Delete an alias expression
  186. *
  187. * Purpose:
  188. * From the current command line position at g_CurCmd,
  189. * read the ALias name and perform an alias list lookup
  190. * to see if it exists and unlink and delete the element.
  191. *
  192. *
  193. * Input:
  194. * Global: g_CurCmd - command line position
  195. * Global: g_AliasListHead
  196. *
  197. * Returns:
  198. * Status
  199. *
  200. * Exceptions:
  201. * error exit: SYNTAX errors or non-existent element
  202. *
  203. *************************************************************************/
  204. void
  205. ParseDeleteAlias(void)
  206. {
  207. PSTR AliasName;
  208. UCHAR Ch;
  209. //
  210. // Locate alias name on cmd line
  211. //
  212. PeekChar();
  213. AliasName = g_CurCmd;
  214. do
  215. {
  216. Ch = *g_CurCmd++;
  217. } while (Ch != ' ' && Ch != '\t' && Ch != '\0' && Ch != ';');
  218. if ( (ULONG_PTR)(g_CurCmd - 1) == (ULONG_PTR)AliasName )
  219. {
  220. error(SYNTAX);
  221. }
  222. *--g_CurCmd = '\0'; // Null terminate the token
  223. if (Ch != '\0')
  224. {
  225. g_CurCmd++;
  226. }
  227. if (DeleteAlias(AliasName) != S_OK)
  228. {
  229. error(NOTFOUND);
  230. }
  231. }
  232. /*** ListAliases - List the alias structures
  233. *
  234. * Purpose:
  235. * Read and display all of the alias list elements.
  236. *
  237. *
  238. * Input:
  239. * Global: g_AliasListHead
  240. *
  241. * Returns:
  242. * Status
  243. *
  244. * Exceptions:
  245. * None
  246. *
  247. *************************************************************************/
  248. void
  249. ListAliases(void)
  250. {
  251. PALIAS CurAlias;
  252. CurAlias = g_AliasListHead;
  253. if ( CurAlias == NULL )
  254. {
  255. dprintf( "No Alias entries to list. \n" );
  256. return;
  257. }
  258. dprintf (" Alias Value \n");
  259. dprintf (" ------- ------- \n");
  260. while ( CurAlias != NULL )
  261. {
  262. dprintf(" %-16s %s \n", CurAlias->Name, CurAlias->Value);
  263. CurAlias = CurAlias->Next;
  264. }
  265. }
  266. void
  267. DotAliasCmds(PDOT_COMMAND Cmd, DebugClient* Client)
  268. {
  269. PALIAS CurAlias = g_AliasListHead;
  270. while ( CurAlias != NULL )
  271. {
  272. dprintf("as %s %s\n", CurAlias->Name, CurAlias->Value);
  273. CurAlias = CurAlias->Next;
  274. }
  275. }
  276. /*** ReplaceAliases - Replace aliases in the given command string
  277. *
  278. * Purpose:
  279. * From the current command line position at g_CurCmd,
  280. * read each token and build a new command line, replacing
  281. * tokens with alias value data. A lookup is performed on
  282. * each original command line token to determine if it is
  283. * defined in the alias list. If so it is replaced on the
  284. * new command line, otherwise the original token is
  285. * placed on the new command line.
  286. *
  287. *************************************************************************/
  288. void
  289. ReplaceAliases(PSTR CommandString, ULONG CommandStringSize)
  290. {
  291. PSTR Command = CommandString;
  292. CHAR *Token;
  293. CHAR Ch;
  294. CHAR Delim[2];
  295. CHAR AliasCommandBuf[MAX_COMMAND]; // Alias build command area
  296. CHAR *AliasCommand;
  297. ULONG AliasCommandSize;
  298. ULONG TokenLen;
  299. PALIAS CurAlias;
  300. BOOLEAN LineEnd;
  301. ULONG StrLen;
  302. // If the incoming command looks like an alias-manipulation
  303. // command don't replace aliases.
  304. if (CommandString[0] == 'a' &&
  305. (CommandString[1] == 'd' ||
  306. CommandString[1] == 'l' ||
  307. CommandString[1] == 's'))
  308. {
  309. return;
  310. }
  311. // If the incoming command is all spaces it's probably
  312. // the result of control characters getting mapped to
  313. // spaces. Don't process it as there can't be any
  314. // aliases and we don't want the trailing space trimming
  315. // to remove the input space.
  316. while (*Command == ' ')
  317. {
  318. Command++;
  319. }
  320. if (*Command == 0)
  321. {
  322. return;
  323. }
  324. Command = CommandString;
  325. AliasCommand = AliasCommandBuf;
  326. AliasCommandSize = DIMA(AliasCommandBuf);
  327. ZeroMemory( AliasCommand, sizeof(AliasCommandBuf) );
  328. LineEnd = FALSE;
  329. do
  330. {
  331. //
  332. // Locate command line token
  333. //
  334. while (isspace(*Command))
  335. {
  336. PSTR AliasCmdEnd;
  337. StrLen = strlen(AliasCommand);
  338. AliasCmdEnd = AliasCommand + StrLen;
  339. if (StrLen + 1 == AliasCommandSize)
  340. {
  341. // Overflow.
  342. return;
  343. }
  344. *AliasCmdEnd++ = *Command++;
  345. *AliasCmdEnd = 0;
  346. }
  347. Token = Command;
  348. do
  349. {
  350. Ch = *Command++;
  351. } while (Ch != ' ' &&
  352. Ch != '\'' &&
  353. Ch != '"' &&
  354. Ch != ';' &&
  355. Ch != '\t' &&
  356. Ch != '\0');
  357. //
  358. // Preserve the token delimiter
  359. //
  360. Delim[0] = Ch;
  361. Delim[1] = '\0';
  362. if ( Ch == '\0' )
  363. {
  364. LineEnd = TRUE;
  365. }
  366. TokenLen = (ULONG)((Command - 1) - Token);
  367. if ( TokenLen != 0 )
  368. {
  369. *--Command = '\0'; // Null terminate the string
  370. Command++;
  371. Ch = *Command;
  372. //
  373. // Locate Alias or end of list
  374. //
  375. CurAlias = g_AliasListHead;
  376. while (( CurAlias != NULL ) &&
  377. ( strcmp( Token, CurAlias->Name )))
  378. {
  379. CurAlias = CurAlias->Next;
  380. }
  381. if ( CurAlias != NULL )
  382. {
  383. CatString( AliasCommand, CurAlias->Value, AliasCommandSize );
  384. }
  385. else
  386. {
  387. CatString( AliasCommand, Token, AliasCommandSize );
  388. }
  389. }
  390. CatString( AliasCommand, Delim, AliasCommandSize );
  391. } while( !LineEnd );
  392. //
  393. // Strip off any trailing blanks
  394. //
  395. AliasCommand += strlen( AliasCommand );
  396. Ch = *AliasCommand;
  397. while ( Ch == '\0' || Ch == ' ' )
  398. {
  399. *AliasCommand = '\0';
  400. Ch = *--AliasCommand;
  401. }
  402. //
  403. // Place the new command line in the command string buffer.
  404. //
  405. CopyString( CommandString, AliasCommandBuf, CommandStringSize );
  406. }