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.

417 lines
12 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 2001
  5. //
  6. // File: parserutil.cpp
  7. //
  8. // Contents: Helpful functions for manipulating and validating
  9. // generic command line arguments
  10. //
  11. // History: 07-Sep-2000 JeffJon Created
  12. //
  13. //
  14. //-----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #include "iostream.h"
  17. //+----------------------------------------------------------------------------
  18. //
  19. // Function: GetPasswdStr
  20. //
  21. // Synopsis: Reads a password string from stdin without echoing the keystrokes
  22. //
  23. // Arguments: [buf - OUT] : buffer to put string in
  24. // [buflen - IN] : size of the buffer
  25. // [&len - OUT] : length of the string placed into the buffer
  26. //
  27. // Returns: DWORD : 0 or ERROR_INSUFFICIENT_BUFFER if user typed too much.
  28. // Buffer contents are only valid on 0 return.
  29. //
  30. // History: 07-Sep-2000 JeffJon Created
  31. //
  32. //-----------------------------------------------------------------------------
  33. #define CR 0xD
  34. #define BACKSPACE 0x8
  35. DWORD GetPasswdStr(LPTSTR buf,
  36. DWORD buflen,
  37. PDWORD len)
  38. {
  39. TCHAR ch;
  40. TCHAR *bufPtr = buf;
  41. DWORD c;
  42. int err;
  43. DWORD mode;
  44. buflen -= 1; /* make space for null terminator */
  45. *len = 0; /* GP fault probe (a la API's) */
  46. GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &mode);
  47. SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE),
  48. (~(ENABLE_ECHO_INPUT|ENABLE_LINE_INPUT)) & mode);
  49. while (TRUE)
  50. {
  51. err = ReadConsole(GetStdHandle(STD_INPUT_HANDLE), &ch, 1, &c, 0);
  52. if (!err || c != 1)
  53. ch = 0xffff;
  54. if ((ch == CR) || (ch == 0xffff)) /* end of the line */
  55. break;
  56. if (ch == BACKSPACE)
  57. { /* back up one or two */
  58. /*
  59. * IF bufPtr == buf then the next two lines are
  60. * a no op.
  61. */
  62. if (bufPtr != buf)
  63. {
  64. bufPtr--;
  65. (*len)--;
  66. }
  67. }
  68. else
  69. {
  70. *bufPtr = ch;
  71. if (*len < buflen)
  72. bufPtr++ ; /* don't overflow buf */
  73. (*len)++; /* always increment len */
  74. }
  75. }
  76. SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), mode);
  77. *bufPtr = TEXT('\0'); /* null terminate the string */
  78. putwchar(TEXT('\n'));
  79. return ((*len <= buflen) ? 0 : ERROR_INSUFFICIENT_BUFFER);
  80. }
  81. //+--------------------------------------------------------------------------
  82. //
  83. // Function: ValidatePassword
  84. //
  85. // Synopsis: Password validation function called by parser
  86. //
  87. // Arguments: [pArg - IN] : pointer argument structure which contains
  88. // the value to be validated
  89. //
  90. // Returns: DWORD : ERROR_INVALID_PARAMETER if the argument record or
  91. // the value it contains is not valid
  92. // ERROR_NOT_ENOUGH_MEMORY
  93. // ERROR_SUCCESS if everything succeeded and it is a
  94. // valid password
  95. // Otherwise it is an error condition returned from
  96. // GetPasswdStr
  97. //
  98. // History: 07-Sep-2000 JeffJon Created
  99. //
  100. //---------------------------------------------------------------------------
  101. DWORD ValidatePassword(PVOID pArg, UINT IdStr)
  102. {
  103. PARG_RECORD pRec = (PARG_RECORD)pArg;
  104. if(!pRec || !pRec->strValue)
  105. return ERROR_INVALID_PARAMETER;
  106. if(wcscmp(pRec->strValue, L"*") != 0 )
  107. return ERROR_SUCCESS;
  108. CComBSTR sbstrPrompt;
  109. if(sbstrPrompt.LoadString(::GetModuleHandle(NULL),IdStr))
  110. {
  111. DisplayOutput(sbstrPrompt);
  112. }
  113. else
  114. DisplayOutput(L"Enter Password\n");
  115. WCHAR buffer[MAX_PASSWORD_LENGTH];
  116. DWORD len = 0;
  117. DWORD dwErr = GetPasswdStr(buffer,MAX_PASSWORD_LENGTH,&len);
  118. if(dwErr != ERROR_SUCCESS)
  119. return dwErr;
  120. LocalFree(pRec->strValue);
  121. pRec->strValue = (LPWSTR)LocalAlloc(LPTR,sizeof(WCHAR)*(len+1));
  122. if(!pRec->strValue)
  123. return ERROR_NOT_ENOUGH_MEMORY;
  124. else
  125. {
  126. wcscpy(pRec->strValue,buffer);
  127. return ERROR_SUCCESS;
  128. }
  129. }
  130. //+--------------------------------------------------------------------------
  131. //
  132. // Function: ValidateAdminPassword
  133. //
  134. // Synopsis: Password validation function called by parser for Admin
  135. //
  136. // Arguments: [pArg - IN] : pointer argument structure which contains
  137. // the value to be validated
  138. //
  139. // Returns: DWORD : ERROR_INVALID_PARAMETER if the argument record or
  140. // the value it contains is not valid
  141. // ERROR_SUCCESS if everything succeeded and it is a
  142. // valid password
  143. //
  144. // History: 07-Sep-2000 Hiteshr Created
  145. //
  146. //---------------------------------------------------------------------------
  147. DWORD ValidateAdminPassword(PVOID pArg)
  148. {
  149. return ValidatePassword(pArg,IDS_ADMIN_PASSWORD_PROMPT);
  150. }
  151. //+--------------------------------------------------------------------------
  152. //
  153. // Function: ValidateUserPassword
  154. //
  155. // Synopsis: Password validation function called by parser for Admin
  156. //
  157. // Arguments: [pArg - IN] : pointer argument structure which contains
  158. // the value to be validated
  159. //
  160. // Returns: DWORD : Same as ValidatePassword
  161. //
  162. // History: 07-Sep-2000 Hiteshr Created
  163. //
  164. //---------------------------------------------------------------------------
  165. DWORD ValidateUserPassword(PVOID pArg)
  166. {
  167. return ValidatePassword(pArg, IDS_USER_PASSWORD_PROMPT);
  168. }
  169. //+--------------------------------------------------------------------------
  170. //
  171. // Function: ValidateYesNo
  172. //
  173. // Synopsis: Password validation function called by parser for Admin
  174. //
  175. // Arguments: [pArg - IN] : pointer argument structure which contains
  176. // the value to be validated
  177. //
  178. // Returns: DWORD : Same as ValidatePassword
  179. //
  180. // History: 07-Sep-2000 Hiteshr Created
  181. //
  182. //---------------------------------------------------------------------------
  183. DWORD ValidateYesNo(PVOID pArg)
  184. {
  185. PARG_RECORD pRec = (PARG_RECORD)pArg;
  186. if(!pRec || !pRec->strValue)
  187. return ERROR_INVALID_PARAMETER;
  188. CComBSTR sbstrYes;
  189. CComBSTR sbstrNo;
  190. CComBSTR sbstrInput;
  191. if(!sbstrYes.LoadString(::GetModuleHandle(NULL),IDS_YES))
  192. {
  193. return ERROR_RESOURCE_DATA_NOT_FOUND;
  194. }
  195. if(!sbstrNo.LoadString(::GetModuleHandle(NULL), IDS_NO))
  196. {
  197. return ERROR_RESOURCE_DATA_NOT_FOUND;
  198. }
  199. sbstrYes.ToLower();
  200. sbstrNo.ToLower();
  201. sbstrInput = pRec->strValue;
  202. sbstrInput.ToLower();
  203. if( sbstrInput == sbstrYes )
  204. {
  205. LocalFree(pRec->strValue);
  206. pRec->bValue = TRUE;
  207. }
  208. else if( sbstrInput == sbstrNo )
  209. {
  210. LocalFree(pRec->strValue);
  211. pRec->bValue = FALSE;
  212. }
  213. else
  214. return ERROR_INVALID_PARAMETER;
  215. //
  216. // Have to set this to bool or else
  217. // FreeCmd will try to free the string
  218. // which AVs when the bool is true
  219. //
  220. pRec->fType = ARG_TYPE_BOOL;
  221. return ERROR_SUCCESS;
  222. }
  223. //+--------------------------------------------------------------------------
  224. //
  225. // Function: ValidateNever
  226. //
  227. // Synopsis: Password validation function called by parser for Admin
  228. // Verifies the value contains digits or "NEVER"
  229. //
  230. // Arguments: [pArg - IN] : pointer argument structure which contains
  231. // the value to be validated
  232. //
  233. // Returns: DWORD : Same as ValidatePassword
  234. //
  235. // History: 07-Sep-2000 JeffJon Created
  236. //
  237. //---------------------------------------------------------------------------
  238. DWORD ValidateNever(PVOID pArg)
  239. {
  240. PARG_RECORD pRec = (PARG_RECORD)pArg;
  241. if(!pRec)
  242. return ERROR_INVALID_PARAMETER;
  243. if (pRec->fType == ARG_TYPE_STR)
  244. {
  245. CComBSTR sbstrInput;
  246. sbstrInput = pRec->strValue;
  247. if( _wcsicmp(sbstrInput, g_bstrNever) )
  248. {
  249. return ERROR_INVALID_PARAMETER;
  250. }
  251. }
  252. return ERROR_SUCCESS;
  253. }
  254. //+--------------------------------------------------------------------------
  255. //
  256. // Function: ValidateGroupScope
  257. //
  258. // Synopsis: Makes sure that the value following the -scope switch is one
  259. // of (l/g/u)
  260. //
  261. // Arguments: [pArg - IN] : pointer argument structure which contains
  262. // the value to be validated
  263. //
  264. // Returns: DWORD : Same as ValidatePassword
  265. //
  266. // History: 18-Sep-2000 JeffJon Created
  267. //
  268. //---------------------------------------------------------------------------
  269. DWORD ValidateGroupScope(PVOID pArg)
  270. {
  271. DWORD dwReturn = ERROR_SUCCESS;
  272. PARG_RECORD pRec = (PARG_RECORD)pArg;
  273. if(!pRec || !pRec->strValue)
  274. return ERROR_INVALID_PARAMETER;
  275. CComBSTR sbstrInput;
  276. sbstrInput = pRec->strValue;
  277. sbstrInput.ToLower();
  278. if(sbstrInput == _T("l") ||
  279. sbstrInput == _T("g") ||
  280. sbstrInput == _T("u"))
  281. {
  282. dwReturn = ERROR_SUCCESS;
  283. }
  284. else
  285. {
  286. dwReturn = ERROR_INVALID_PARAMETER;
  287. }
  288. return dwReturn;
  289. }
  290. //+--------------------------------------------------------------------------
  291. //
  292. // Function: ParseNullSeparatedString
  293. //
  294. // Synopsis: Parses a '\0' separated list that ends in "\0\0" into a string
  295. // array
  296. //
  297. // Arguments: [psz - IN] : '\0' separated string to be parsed
  298. // [pszArr - OUT] : the array to receive the parsed strings
  299. // [pnArrEntries - OUT] : the number of strings parsed from the list
  300. //
  301. // Returns:
  302. //
  303. // History: 18-Sep-2000 JeffJon Created
  304. //
  305. //---------------------------------------------------------------------------
  306. void ParseNullSeparatedString(PTSTR psz,
  307. PTSTR** ppszArr,
  308. UINT* pnArrEntries)
  309. {
  310. //
  311. // Verify parameters
  312. //
  313. if (!psz ||
  314. !ppszArr ||
  315. !pnArrEntries)
  316. {
  317. ASSERT(psz);
  318. ASSERT(ppszArr);
  319. ASSERT(pnArrEntries);
  320. return;
  321. }
  322. //
  323. // Count the number of strings
  324. //
  325. UINT nCount = 0;
  326. PTSTR pszTemp = psz;
  327. while (true)
  328. {
  329. if (pszTemp[0] == _T('\0') &&
  330. pszTemp[1] == _T('\0'))
  331. {
  332. nCount++;
  333. break;
  334. }
  335. else if (pszTemp[0] == _T('\0') &&
  336. pszTemp[1] != _T('\0'))
  337. {
  338. nCount++;
  339. pszTemp++;
  340. }
  341. else
  342. {
  343. pszTemp++;
  344. }
  345. }
  346. *pnArrEntries = nCount;
  347. //
  348. // Allocate the array
  349. //
  350. *ppszArr = (PTSTR*)LocalAlloc(LPTR, nCount * sizeof(PTSTR));
  351. if (*ppszArr)
  352. {
  353. //
  354. // Copy the string pointers into the array
  355. //
  356. UINT nIdx = 0;
  357. pszTemp = psz;
  358. (*ppszArr)[nIdx] = pszTemp;
  359. nIdx++;
  360. while (true)
  361. {
  362. if (pszTemp[0] == _T('\0') &&
  363. pszTemp[1] == _T('\0'))
  364. {
  365. break;
  366. }
  367. else if (pszTemp[0] == _T('\0') &&
  368. pszTemp[1] != _T('\0'))
  369. {
  370. (*ppszArr)[nIdx] = &(pszTemp[1]);
  371. nIdx++;
  372. pszTemp++;
  373. }
  374. else
  375. {
  376. pszTemp++;
  377. }
  378. }
  379. }
  380. }