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.

322 lines
7.3 KiB

  1. /////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1998 Active Voice Corporation. All Rights Reserved.
  4. //
  5. // Active Agent(r) and Unified Communications(tm) are trademarks of Active Voice Corporation.
  6. //
  7. // Other brand and product names used herein are trademarks of their respective owners.
  8. //
  9. // The entire program and user interface including the structure, sequence, selection,
  10. // and arrangement of the dialog, the exclusively "yes" and "no" choices represented
  11. // by "1" and "2," and each dialog message are protected by copyrights registered in
  12. // the United States and by international treaties.
  13. //
  14. // Protected by one or more of the following United States patents: 5,070,526, 5,488,650,
  15. // 5,434,906, 5,581,604, 5,533,102, 5,568,540, 5,625,676, 5,651,054.
  16. //
  17. // Active Voice Corporation
  18. // Seattle, Washington
  19. // USA
  20. //
  21. /////////////////////////////////////////////////////////////////////////////////////////
  22. ////
  23. // arg.c - Windows command line argument functions
  24. ////
  25. #include "winlocal.h"
  26. #include <stdlib.h>
  27. #include "arg.h"
  28. #include "mem.h"
  29. #include "str.h"
  30. #include "trace.h"
  31. ////
  32. // private definitions
  33. ////
  34. #define MAXARGS 64
  35. // arg control struct
  36. //
  37. typedef struct ARG
  38. {
  39. DWORD dwVersion;
  40. HINSTANCE hInst;
  41. HTASK hTask;
  42. LPTSTR lpszCmdLine;
  43. LPTSTR lpszArgs;
  44. int argc;
  45. LPTSTR argv[MAXARGS];
  46. } ARG, FAR *LPARG;
  47. // helper functions
  48. //
  49. static LPARG ArgGetPtr(HARG hArg);
  50. static HARG ArgGetHandle(LPARG lpArg);
  51. ////
  52. // public functions
  53. ////
  54. // ArgInit - initialize arg engine, converting <lpszCmdLine> to argc and argv
  55. // <dwVersion> (i) must be ARG_VERSION
  56. // <hInst> (i) instance handle of calling module
  57. // <lpszCmdLine> (i) command line from WinMain()
  58. // return handle (NULL if error)
  59. //
  60. HARG DLLEXPORT WINAPI ArgInit(DWORD dwVersion, HINSTANCE hInst, LPCTSTR lpszCmdLine)
  61. {
  62. BOOL fSuccess = TRUE;
  63. LPARG lpArg = NULL;
  64. if (dwVersion != ARG_VERSION)
  65. fSuccess = TraceFALSE(NULL);
  66. else if (hInst == NULL)
  67. fSuccess = TraceFALSE(NULL);
  68. else if (lpszCmdLine == NULL)
  69. fSuccess = TraceFALSE(NULL);
  70. else if ((lpArg = (LPARG) MemAlloc(NULL, sizeof(ARG), 0)) == NULL)
  71. fSuccess = TraceFALSE(NULL);
  72. else
  73. {
  74. // #ifndef _WIN32
  75. TCHAR szModuleFileName[_MAX_PATH];
  76. size_t sizModuleFileName;
  77. // #endif
  78. LPTSTR lpsz;
  79. lpArg->dwVersion = dwVersion;
  80. lpArg->hInst = hInst;
  81. lpArg->hTask = GetCurrentTask();
  82. lpArg->lpszCmdLine = NULL;
  83. lpArg->lpszArgs = NULL;
  84. lpArg->argc = 0;
  85. lpArg->argv[0] = NULL;
  86. // #ifndef _WIN32
  87. // the 0th argument is always the name of the executable
  88. //
  89. sizModuleFileName = GetModuleFileName(hInst,
  90. szModuleFileName, SIZEOFARRAY(szModuleFileName));
  91. if ((lpArg->argv[lpArg->argc++] = StrDup(szModuleFileName)) == NULL)
  92. fSuccess = TraceFALSE(NULL);
  93. else
  94. // #endif
  95. // save a copy of the command line
  96. //
  97. if ((lpArg->lpszCmdLine = StrDup(lpszCmdLine)) == NULL)
  98. fSuccess = TraceFALSE(NULL);
  99. // save another copy of the command line to parse into args
  100. //
  101. else if ((lpArg->lpszArgs = StrDup(lpszCmdLine)) == NULL)
  102. fSuccess = TraceFALSE(NULL);
  103. lpsz = lpArg->lpszArgs;
  104. while (fSuccess)
  105. {
  106. // skip over leading white space
  107. //
  108. while (ChrIsSpace(*lpsz))
  109. lpsz = StrNextChr(lpsz);
  110. // check for end of command line
  111. //
  112. if (*lpsz == '\0')
  113. break;
  114. if (*lpsz == '\"')
  115. {
  116. // save pointer to beginning of argument, increment counter
  117. //
  118. if (lpArg->argc < MAXARGS)
  119. lpArg->argv[lpArg->argc++] = lpsz = StrNextChr(lpsz);
  120. // skip over argument body
  121. //
  122. while (*lpsz != '\0' && *lpsz != '\"')
  123. lpsz = StrNextChr(lpsz);
  124. }
  125. else
  126. {
  127. // save pointer to beginning of argument, increment counter
  128. //
  129. if (lpArg->argc < MAXARGS)
  130. lpArg->argv[lpArg->argc++] = lpsz;
  131. // skip over argument body
  132. //
  133. while (*lpsz != '\0' && !ChrIsSpace(*lpsz))
  134. lpsz = StrNextChr(lpsz);
  135. }
  136. // nul-terminate the argument
  137. //
  138. if (*lpsz != '\0')
  139. {
  140. *lpsz = '\0';
  141. ++lpsz; // lpsz = StrNextChr(lpsz) will not skip over \0
  142. }
  143. }
  144. }
  145. if (!fSuccess)
  146. {
  147. ArgTerm(ArgGetHandle(lpArg));
  148. lpArg = NULL;
  149. }
  150. return fSuccess ? ArgGetHandle(lpArg) : NULL;
  151. }
  152. // ArgTerm - shut down arg engine
  153. // <hArg> (i) handle returned from ArgInit
  154. // return 0 if success
  155. //
  156. int DLLEXPORT WINAPI ArgTerm(HARG hArg)
  157. {
  158. BOOL fSuccess = TRUE;
  159. LPARG lpArg;
  160. if ((lpArg = ArgGetPtr(hArg)) == NULL)
  161. fSuccess = TraceFALSE(NULL);
  162. else
  163. {
  164. if (lpArg->lpszCmdLine != NULL)
  165. {
  166. StrDupFree(lpArg->lpszCmdLine);
  167. lpArg->lpszCmdLine = NULL;
  168. }
  169. if (lpArg->lpszArgs != NULL)
  170. {
  171. StrDupFree(lpArg->lpszArgs);
  172. lpArg->lpszArgs = NULL;
  173. }
  174. // #ifndef _WIN32
  175. if (lpArg->argv[0] != NULL)
  176. {
  177. StrDupFree(lpArg->argv[0]);
  178. lpArg->argv[0] = NULL;
  179. }
  180. // #endif
  181. if ((lpArg = MemFree(NULL, lpArg)) != NULL)
  182. fSuccess = TraceFALSE(NULL);
  183. }
  184. return fSuccess ? 0 : -1;
  185. }
  186. // ArgGetCount - get argument count (argc)
  187. // <hArg> (i) handle returned from ArgInit
  188. // return number of arguments (argc) (0 if error)
  189. // there should always be at least one, since argv[0] is .EXE file name
  190. //
  191. int DLLEXPORT WINAPI ArgGetCount(HARG hArg)
  192. {
  193. BOOL fSuccess = TRUE;
  194. LPARG lpArg;
  195. if ((lpArg = ArgGetPtr(hArg)) == NULL)
  196. fSuccess = TraceFALSE(NULL);
  197. return fSuccess ? lpArg->argc : 0;
  198. }
  199. // ArgGet - get specified argument
  200. // <hArg> (i) handle returned from ArgInit
  201. // <iArg> (i) zero based index of argument to get
  202. // <lpszArg> (o) buffer to hold argument argv[iArg]
  203. // NULL do not copy; return static pointer instead
  204. // <sizArg> (i) size of buffer
  205. // return pointer to argument (NULL if error)
  206. //
  207. LPTSTR DLLEXPORT WINAPI ArgGet(HARG hArg, int iArg, LPTSTR lpszArg, int sizArg)
  208. {
  209. BOOL fSuccess = TRUE;
  210. LPARG lpArg;
  211. if ((lpArg = ArgGetPtr(hArg)) == NULL)
  212. fSuccess = TraceFALSE(NULL);
  213. // make sure iArg is not out of range
  214. //
  215. else if (iArg < 0 || iArg >= lpArg->argc)
  216. fSuccess = TraceFALSE(NULL);
  217. else
  218. {
  219. // copy arg if destination buffer specified
  220. //
  221. if (lpszArg != NULL)
  222. StrNCpy(lpszArg, lpArg->argv[iArg], sizArg);
  223. // otherwise just point to static copy of arg
  224. //
  225. else
  226. lpszArg = lpArg->argv[iArg];
  227. }
  228. return fSuccess ? lpszArg : NULL;
  229. }
  230. ////
  231. // helper functions
  232. ////
  233. // ArgGetPtr - verify that arg handle is valid,
  234. // <hArg> (i) handle returned from ArgInit
  235. // return corresponding arg pointer (NULL if error)
  236. //
  237. static LPARG ArgGetPtr(HARG hArg)
  238. {
  239. BOOL fSuccess = TRUE;
  240. LPARG lpArg;
  241. if ((lpArg = (LPARG) hArg) == NULL)
  242. fSuccess = TraceFALSE(NULL);
  243. else if (IsBadWritePtr(lpArg, sizeof(ARG)))
  244. fSuccess = TraceFALSE(NULL);
  245. #ifdef CHECKTASK
  246. // make sure current task owns the arg handle
  247. //
  248. else if (lpArg->hTask != GetCurrentTask())
  249. fSuccess = TraceFALSE(NULL);
  250. #endif
  251. return fSuccess ? lpArg : NULL;
  252. }
  253. // ArgGetHandle - verify that arg pointer is valid,
  254. // <lpArg> (i) pointer to ARG struct
  255. // return corresponding arg handle (NULL if error)
  256. //
  257. static HARG ArgGetHandle(LPARG lpArg)
  258. {
  259. BOOL fSuccess = TRUE;
  260. HARG hArg;
  261. if ((hArg = (HARG) lpArg) == NULL)
  262. fSuccess = TraceFALSE(NULL);
  263. return fSuccess ? hArg : NULL;
  264. }