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.

373 lines
7.5 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. parsearg.c
  5. Abstract:
  6. Argument Handling
  7. Author:
  8. MikeTs
  9. Environment:
  10. Any
  11. Revision History:
  12. --*/
  13. #include "pch.h"
  14. VOID
  15. ParseProgramInfo(
  16. PUCHAR ProgramName,
  17. PPROGINFO ProgramInfo
  18. )
  19. /*++
  20. Routine Description:
  21. This routine parses program path and module name
  22. Arguments:
  23. ProgramName - The Argv[0] from main()
  24. ProgramInfo - Program Information structure
  25. Return Value:
  26. None
  27. --*/
  28. {
  29. PUCHAR ptr;
  30. ProgramInfo->ProgPath = _strlwr(ProgramName);
  31. ptr = strrchr( ProgramName, '\\' );
  32. if (ptr != NULL) {
  33. *ptr = '\0';
  34. ProgramInfo->ProgName = ptr + 1;
  35. } else {
  36. ProgramInfo->ProgName = ProgramName;
  37. }
  38. ptr = strchr(ProgramInfo->ProgName, '.');
  39. if (ptr != NULL) {
  40. *ptr = '\0';
  41. }
  42. }
  43. ULONG
  44. ParseSwitches(
  45. PULONG ArgumentCount,
  46. PUCHAR **ArgumentList,
  47. PARGTYPE ArgumentArray,
  48. PPROGINFO ProgramInfo
  49. )
  50. /*++
  51. Routine Description:
  52. Parse command line switches
  53. Arguments:
  54. ArgumentCount - Pointer to the number of arguments
  55. ArgumentList - Pointer to the pointer to the list of arguments
  56. ArgumentArray - How to parse the arguments
  57. ProgramInfo - Program Specific structure
  58. Return Value:
  59. ULONG - Success = ARGERR_NONE
  60. --*/
  61. {
  62. PUCHAR argument;
  63. ULONG status = ARGERR_NONE;
  64. if (ProgramInfo->SwitchChars == NULL) {
  65. ProgramInfo->SwitchChars = DEF_SWITCHCHARS;
  66. }
  67. if (ProgramInfo->Separators == NULL) {
  68. ProgramInfo->Separators = DEF_SEPARATORS;
  69. }
  70. for (; *ArgumentCount; (*ArgumentCount)--, (*ArgumentList)++)
  71. {
  72. argument = **ArgumentList;
  73. if (strchr(ProgramInfo->SwitchChars, *argument)) {
  74. argument++;
  75. status = ParseArgSwitch(
  76. &argument,
  77. ArgumentArray,
  78. ProgramInfo
  79. );
  80. if (status != ARGERR_NONE) {
  81. PrintError( status, argument, ProgramInfo );
  82. break;
  83. }
  84. } else {
  85. break;
  86. }
  87. }
  88. return status;
  89. }
  90. ULONG
  91. ParseArgSwitch(
  92. PUCHAR *Argument,
  93. PARGTYPE ArgumentArray,
  94. PPROGINFO ProgramInfo
  95. )
  96. /*++
  97. Routine Description:
  98. Parse a command line switch
  99. Arguments
  100. Argument - Pointer to argument
  101. ArgumentArray - How to handle the argument
  102. ProgramInfo - Program Information Structure
  103. Return Value:
  104. ULONG
  105. --*/
  106. {
  107. BOOL found = FALSE;
  108. PARGTYPE tableEntry;
  109. PUCHAR argumentEnd;
  110. ULONG length = 0;
  111. ULONG status = ARGERR_NONE;
  112. tableEntry = ArgumentArray;
  113. while (tableEntry->ArgID[0]) {
  114. length = strlen(tableEntry->ArgID);
  115. if (tableEntry->ParseFlags & PF_NOI) {
  116. found = (strncmp(tableEntry->ArgID, *Argument, length) == 0);
  117. } else {
  118. found = (_strnicmp(tableEntry->ArgID, *Argument, length) == 0);
  119. }
  120. if (found) {
  121. break;
  122. }
  123. tableEntry++;
  124. }
  125. if (found) {
  126. *Argument += length;
  127. switch (tableEntry->ArgType) {
  128. case AT_STRING:
  129. case AT_NUM:
  130. if (tableEntry->ParseFlags & PF_SEPARATOR)
  131. {
  132. if (**Argument &&
  133. strchr(ProgramInfo->Separators, **Argument)) {
  134. (*Argument)++;
  135. } else {
  136. status = ARGERR_NO_SEPARATOR;
  137. break;
  138. }
  139. }
  140. if (tableEntry->ArgType == AT_STRING) {
  141. *(UCHAR **)tableEntry->ArgData = *Argument;
  142. } else {
  143. *(ULONG *)tableEntry->ArgData = (ULONG)
  144. strtoul(*Argument, &argumentEnd, tableEntry->ArgParam);
  145. if (*Argument == argumentEnd) {
  146. status = ARGERR_INVALID_NUM;
  147. break;
  148. }
  149. *Argument = argumentEnd;
  150. }
  151. if (tableEntry->ArgVerify) {
  152. status = (*tableEntry->ArgVerify)(Argument, tableEntry);
  153. }
  154. break;
  155. case AT_ENABLE:
  156. case AT_DISABLE:
  157. if (tableEntry->ArgType == AT_ENABLE) {
  158. *(ULONG *)tableEntry->ArgData |= tableEntry->ArgParam;
  159. } else {
  160. *(ULONG *)tableEntry->ArgData &= ~tableEntry->ArgParam;
  161. }
  162. if ( tableEntry->ArgVerify) {
  163. status = (*tableEntry->ArgVerify)(Argument, tableEntry);
  164. if (status == ARGERR_NONE) {
  165. break;
  166. }
  167. }
  168. if (**Argument) {
  169. if (strchr(ProgramInfo->SwitchChars, **Argument)) {
  170. (*Argument)++;
  171. }
  172. status = ParseArgSwitch(
  173. Argument,
  174. ArgumentArray,
  175. ProgramInfo
  176. );
  177. }
  178. break;
  179. case AT_ACTION:
  180. if (tableEntry->ParseFlags & PF_SEPARATOR)
  181. {
  182. if (**Argument &&
  183. strchr(ProgramInfo->Separators, **Argument)) {
  184. (*Argument)++;
  185. } else {
  186. status = ARGERR_NO_SEPARATOR;
  187. break;
  188. }
  189. }
  190. #pragma warning(disable: 4055)
  191. status = (*(PFNARG)tableEntry->ArgData)(Argument, tableEntry);
  192. #pragma warning(default: 4055)
  193. break;
  194. }
  195. } else {
  196. status = ARGERR_UNKNOWN_SWITCH;
  197. }
  198. return status;
  199. }
  200. VOID
  201. PrintError(
  202. ULONG ErrorCode,
  203. PUCHAR Argument,
  204. PPROGINFO ProgramInfo
  205. )
  206. /*++
  207. Routine Description:
  208. Print Appropriate Error Message according to error code
  209. Arguments:
  210. ErrorCode - The error which occured
  211. Argument - Argument in Error
  212. ProgramInfo - Program info structure
  213. Return Value:
  214. VOID
  215. --*/
  216. {
  217. switch (ErrorCode) {
  218. case ARGERR_UNKNOWN_SWITCH:
  219. fprintf(
  220. stderr,
  221. "%s: unknown switch \"%s\"\n",
  222. ProgramInfo->ProgName,
  223. Argument
  224. );
  225. break;
  226. case ARGERR_NO_SEPARATOR:
  227. fprintf(
  228. stderr,
  229. "%s: separator missing after the switch char '%c'\n",
  230. ProgramInfo->ProgName,
  231. *(Argument-1)
  232. );
  233. break;
  234. case ARGERR_INVALID_NUM:
  235. fprintf(
  236. stderr,
  237. "%s: invalid numeric switch \"%s\"\n",
  238. ProgramInfo->ProgName,
  239. Argument
  240. );
  241. break;
  242. case ARGERR_INVALID_TAIL:
  243. fprintf(
  244. stderr,
  245. "%s: invalid argument tail \"%s\"\n",
  246. ProgramInfo->ProgName,
  247. Argument
  248. );
  249. }
  250. }