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.

483 lines
14 KiB

  1. #include <precomp.h>
  2. #include "ErrCtrl.h"
  3. #include "Utils.h"
  4. #include "ArgParse.h"
  5. //----------------------------------------------------
  6. // Utility function for parsing an UINT type of argument;
  7. DWORD
  8. FnPaUint(LPWSTR *pwszArg, WCHAR wchTerm, UINT *pnValue)
  9. {
  10. DWORD dwErr = ERROR_SUCCESS;
  11. UINT nValue = 0;
  12. LPWSTR wszArg = (*pwszArg);
  13. if (*wszArg == L'\0' || *wszArg == wchTerm)
  14. dwErr = ERROR_BAD_FORMAT;
  15. else
  16. {
  17. for (nValue = 0; *wszArg != L'\0' && iswdigit(*wszArg); wszArg++)
  18. {
  19. if (*wszArg == wchTerm)
  20. break;
  21. nValue = nValue * 10 + ((*wszArg) - L'0');
  22. }
  23. if (*wszArg != wchTerm)
  24. dwErr = ERROR_BAD_FORMAT;
  25. else if (pnValue != NULL)
  26. *pnValue = nValue;
  27. }
  28. *pwszArg = wszArg;
  29. SetLastError(dwErr);
  30. return dwErr;
  31. }
  32. //----------------------------------------------------
  33. // Utility function for parsing two hexa digits (one byte)
  34. DWORD
  35. FnPaByte(LPWSTR *pwszArg, BYTE *pbtValue)
  36. {
  37. DWORD dwErr = ERROR_SUCCESS;
  38. BYTE btValue = 0;
  39. LPWSTR wszArg = (*pwszArg);
  40. if (iswxdigit(*wszArg))
  41. {
  42. btValue = HEX(*wszArg);
  43. wszArg++;
  44. }
  45. else
  46. dwErr = ERROR_BAD_FORMAT;
  47. if (dwErr == ERROR_SUCCESS && iswxdigit(*wszArg))
  48. {
  49. btValue <<= 4;
  50. btValue |= HEX(*wszArg);
  51. wszArg++;
  52. }
  53. else
  54. dwErr = ERROR_BAD_FORMAT;
  55. if (dwErr == ERROR_SUCCESS && pbtValue != NULL)
  56. *pbtValue = btValue;
  57. *pwszArg = wszArg;
  58. SetLastError(dwErr);
  59. return dwErr;
  60. }
  61. //----------------------------------------------------
  62. // Utility function for common postprocessing of argument parsing routines
  63. DWORD
  64. FnPaPostProcess(DWORD dwErr, PPARAM_DESCR_DATA pPDData, PPARAM_DESCR pPDEntry)
  65. {
  66. if (dwErr == ERROR_SUCCESS)
  67. {
  68. // it is guaranteed that when parsing the argument of a parameter
  69. // the parameter itself is encountered for the first time. Consequently
  70. // there is no need for checking whether this argumented param ever occured before.
  71. pPDData->dwArgumentedParams |= pPDEntry->nParamID;
  72. }
  73. SetLastError(dwErr);
  74. return dwErr;
  75. }
  76. //----------------------------------------------------
  77. // Parser for the Guid type of argument
  78. DWORD
  79. FnPaGuid(PPARAM_DESCR_DATA pPDData, PPARAM_DESCR pPDEntry, LPWSTR wszParamArg)
  80. {
  81. DWORD dwErr = ERROR_SUCCESS;
  82. LPWSTR wszGuid = NULL;
  83. UINT nGuidLen = wcslen(wszParamArg);
  84. if (nGuidLen < 1)
  85. dwErr = ERROR_BAD_FORMAT;
  86. if (dwErr == ERROR_SUCCESS)
  87. {
  88. // create a buffer for the GUID
  89. wszGuid = MemCAlloc((nGuidLen + 1) * sizeof(WCHAR));
  90. if (wszGuid == NULL)
  91. dwErr = GetLastError();
  92. }
  93. if (dwErr == ERROR_SUCCESS)
  94. {
  95. wcscpy(wszGuid, wszParamArg);
  96. MemFree(pPDData->wzcIntfEntry.wszGuid);
  97. // copy the GUID into the param descriptors data
  98. pPDData->wzcIntfEntry.wszGuid = wszGuid;
  99. }
  100. return FnPaPostProcess(dwErr, pPDData, pPDEntry);
  101. }
  102. //----------------------------------------------------
  103. // Parser for the argument of the "mask" parameter
  104. DWORD
  105. FnPaMask(PPARAM_DESCR_DATA pPDData, PPARAM_DESCR pPDEntry, LPWSTR wszParamArg)
  106. {
  107. DWORD dwErr = ERROR_SUCCESS;
  108. NDIS_802_11_NETWORK_INFRASTRUCTURE ndIm;
  109. dwErr = FnPaUint(&wszParamArg, L'\0', (UINT *)&ndIm);
  110. if (dwErr == ERROR_SUCCESS)
  111. {
  112. if (ndIm > Ndis802_11AutoUnknown)
  113. dwErr = ERROR_INVALID_DATA;
  114. else
  115. {
  116. pPDData->wzcIntfEntry.dwCtlFlags &= ~INTFCTL_CM_MASK;
  117. pPDData->wzcIntfEntry.dwCtlFlags |= ndIm;
  118. }
  119. }
  120. return FnPaPostProcess(dwErr, pPDData, pPDEntry);
  121. }
  122. //----------------------------------------------------
  123. // Parser for the argument of the "enabled" parameter
  124. DWORD
  125. FnPaEnabled(PPARAM_DESCR_DATA pPDData, PPARAM_DESCR pPDEntry, LPWSTR wszParamArg)
  126. {
  127. DWORD dwErr = ERROR_SUCCESS;
  128. BOOL bEnabled;
  129. dwErr = FnPaUint(&wszParamArg, L'\0', (UINT *)&bEnabled);
  130. if (dwErr == ERROR_SUCCESS)
  131. {
  132. if (bEnabled > 1)
  133. dwErr = ERROR_INVALID_DATA;
  134. else if (bEnabled)
  135. pPDData->wzcIntfEntry.dwCtlFlags |= INTFCTL_ENABLED;
  136. else
  137. pPDData->wzcIntfEntry.dwCtlFlags &= ~INTFCTL_ENABLED;
  138. }
  139. return FnPaPostProcess(dwErr, pPDData, pPDEntry);
  140. }
  141. //----------------------------------------------------
  142. // Parser for the argument of the "ssid" parameter
  143. DWORD
  144. FnPaSsid(PPARAM_DESCR_DATA pPDData, PPARAM_DESCR pPDEntry, LPWSTR wszParamArg)
  145. {
  146. DWORD dwErr = ERROR_SUCCESS;
  147. UINT nSsidWLen = wcslen(wszParamArg);
  148. UINT nSsidALen;
  149. LPBYTE pbtSsid = NULL;
  150. // ssid is hardcoded to 32 bytes in ntddndis.h
  151. pbtSsid = MemCAlloc(33);
  152. if (pbtSsid == NULL)
  153. dwErr = GetLastError();
  154. // trim out the '"' if any
  155. if (dwErr == ERROR_SUCCESS &&
  156. nSsidWLen > 2 && wszParamArg[0] == L'"' && wszParamArg[nSsidWLen-1] == '"')
  157. {
  158. wszParamArg++; nSsidWLen-=2;
  159. wszParamArg[nSsidWLen+1] = L'\0';
  160. }
  161. if (dwErr == ERROR_SUCCESS)
  162. {
  163. nSsidALen = WideCharToMultiByte(
  164. CP_ACP,
  165. 0,
  166. wszParamArg,
  167. wcslen(wszParamArg)+1,
  168. pbtSsid,
  169. 33,
  170. NULL,
  171. NULL);
  172. // the call above includes the '\0' in the count of
  173. // characters converted. Normalize the length then,
  174. // (failure => all "f"s which is higher than 32 hence error)
  175. nSsidALen--;
  176. // a valid SSID should contain at least 1 char, and no more than 32
  177. if (nSsidALen < 1 || nSsidALen > 32)
  178. dwErr = ERROR_INVALID_DATA;
  179. }
  180. if (dwErr == ERROR_SUCCESS)
  181. {
  182. pPDData->wzcIntfEntry.rdSSID.dwDataLen = nSsidALen;
  183. pPDData->wzcIntfEntry.rdSSID.pData = pbtSsid;
  184. }
  185. else
  186. MemFree(pbtSsid);
  187. return FnPaPostProcess(dwErr, pPDData, pPDEntry);
  188. }
  189. //----------------------------------------------------
  190. // Parser for the argument of the "bssid" parameter
  191. DWORD
  192. FnPaBssid(PPARAM_DESCR_DATA pPDData, PPARAM_DESCR pPDEntry, LPWSTR wszParamArg)
  193. {
  194. DWORD dwErr = ERROR_SUCCESS;
  195. PNDIS_802_11_MAC_ADDRESS pndMac = NULL;
  196. UINT i;
  197. // allocate space for the mac address
  198. pndMac = MemCAlloc(sizeof(NDIS_802_11_MAC_ADDRESS));
  199. if (pndMac == NULL)
  200. dwErr = GetLastError();
  201. for (i = 0; dwErr == ERROR_SUCCESS && i < sizeof(NDIS_802_11_MAC_ADDRESS); i++)
  202. {
  203. dwErr = FnPaByte(&wszParamArg, &((*pndMac)[i]));
  204. if (dwErr == ERROR_SUCCESS)
  205. {
  206. if (i != sizeof(NDIS_802_11_MAC_ADDRESS)-1 && *wszParamArg == L':')
  207. wszParamArg++;
  208. else if (i != sizeof(NDIS_802_11_MAC_ADDRESS)-1 || *wszParamArg != L'\0')
  209. dwErr = ERROR_BAD_FORMAT;
  210. }
  211. }
  212. if (dwErr == ERROR_SUCCESS)
  213. {
  214. pPDData->wzcIntfEntry.rdBSSID.dwDataLen = sizeof(NDIS_802_11_MAC_ADDRESS);
  215. pPDData->wzcIntfEntry.rdBSSID.pData = (LPBYTE)pndMac;
  216. }
  217. else
  218. {
  219. MemFree(pndMac);
  220. }
  221. return FnPaPostProcess(dwErr, pPDData, pPDEntry);
  222. }
  223. //----------------------------------------------------
  224. // Parser for the argument of the "im" parameter
  225. DWORD
  226. FnPaIm(PPARAM_DESCR_DATA pPDData, PPARAM_DESCR pPDEntry, LPWSTR wszParamArg)
  227. {
  228. DWORD dwErr = ERROR_SUCCESS;
  229. NDIS_802_11_NETWORK_INFRASTRUCTURE ndIm;
  230. dwErr = FnPaUint(&wszParamArg, L'\0', (UINT *)&ndIm);
  231. if (dwErr == ERROR_SUCCESS)
  232. {
  233. if (ndIm > Ndis802_11Infrastructure)
  234. dwErr = ERROR_INVALID_DATA;
  235. else
  236. pPDData->wzcIntfEntry.nInfraMode = ndIm;
  237. }
  238. return FnPaPostProcess(dwErr, pPDData, pPDEntry);
  239. }
  240. //----------------------------------------------------
  241. // Parser for the argument of the "am" parameter
  242. DWORD
  243. FnPaAm(PPARAM_DESCR_DATA pPDData, PPARAM_DESCR pPDEntry, LPWSTR wszParamArg)
  244. {
  245. DWORD dwErr = ERROR_SUCCESS;
  246. NDIS_802_11_AUTHENTICATION_MODE ndAm;
  247. dwErr = FnPaUint(&wszParamArg, L'\0', (UINT *)&ndAm);
  248. if (dwErr == ERROR_SUCCESS)
  249. {
  250. if (ndAm > Ndis802_11AuthModeShared)
  251. dwErr = ERROR_INVALID_DATA;
  252. else
  253. pPDData->wzcIntfEntry.nAuthMode = ndAm;
  254. }
  255. return FnPaPostProcess(dwErr, pPDData, pPDEntry);
  256. }
  257. //----------------------------------------------------
  258. // Parser for the argument of the "priv" parameter
  259. DWORD
  260. FnPaPriv(PPARAM_DESCR_DATA pPDData, PPARAM_DESCR pPDEntry, LPWSTR wszParamArg)
  261. {
  262. DWORD dwErr = ERROR_SUCCESS;
  263. NDIS_802_11_WEP_STATUS ndEncr;
  264. dwErr = FnPaUint(&wszParamArg, L'\0', (UINT *)&ndEncr);
  265. if (dwErr == ERROR_SUCCESS)
  266. {
  267. if (ndEncr != Ndis802_11WEPDisabled &&
  268. ndEncr != Ndis802_11WEPEnabled)
  269. dwErr = ERROR_INVALID_DATA;
  270. else
  271. {
  272. // change the semantic of nWepStatus according to XP SP (which expects a boolean!)
  273. pPDData->wzcIntfEntry.nWepStatus = ndEncr == Ndis802_11WEPDisabled ? 0 : 1;
  274. }
  275. }
  276. return FnPaPostProcess(dwErr, pPDData, pPDEntry);
  277. }
  278. //----------------------------------------------------
  279. // Parser for the argument of the "key" parameter
  280. DWORD
  281. FnPaKey(PPARAM_DESCR_DATA pPDData, PPARAM_DESCR pPDEntry, LPWSTR wszParamArg)
  282. {
  283. DWORD dwErr = ERROR_SUCCESS;
  284. UINT nKIdx, nKLen;
  285. BOOL bIsHex;
  286. PNDIS_802_11_WEP pndKey = NULL;
  287. // get the key index
  288. dwErr = FnPaUint(&wszParamArg, L':', &nKIdx);
  289. // check whether the key index is within permitted values
  290. if (dwErr == ERROR_SUCCESS && (nKIdx < 1 || nKIdx > 4))
  291. dwErr = ERROR_INVALID_DATA;
  292. // check the key material length
  293. if (dwErr == ERROR_SUCCESS)
  294. {
  295. wszParamArg++;
  296. nKLen = wcslen(wszParamArg);
  297. // trim out the '"' if any
  298. if (nKLen > 2 && wszParamArg[0] == L'"' && wszParamArg[nKLen-1] == '"')
  299. {
  300. wszParamArg++; nKLen-=2;
  301. }
  302. switch (nKLen)
  303. {
  304. case 10: // 5 bytes = 40 bits
  305. case 26: // 13 bytes = 104 bits
  306. case 32: // 16 bytes = 128 bits
  307. nKLen >>= 1;
  308. bIsHex = TRUE;
  309. break;
  310. case 5: // 5 bytes = 40 bits
  311. case 13: // 13 bytes = 104 bits
  312. case 16: // 16 bytes = 128 bits
  313. bIsHex = FALSE;
  314. break;
  315. default:
  316. dwErr = ERROR_BAD_LENGTH;
  317. break;
  318. }
  319. }
  320. // allocate space for the key material
  321. if (dwErr == ERROR_SUCCESS)
  322. {
  323. pndKey = MemCAlloc(FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial) + nKLen);
  324. if (pndKey == NULL)
  325. dwErr = GetLastError();
  326. else
  327. {
  328. pndKey->Length = FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial) + nKLen;
  329. pndKey->KeyIndex = nKIdx-1;
  330. pndKey->KeyLength = nKLen;
  331. }
  332. }
  333. // parse the key material and fill it in the allocated space
  334. if (dwErr == ERROR_SUCCESS)
  335. {
  336. if (bIsHex)
  337. {
  338. UINT i;
  339. for (i = 0; dwErr == ERROR_SUCCESS && i < pndKey->KeyLength; i++)
  340. dwErr = FnPaByte(&wszParamArg, &(pndKey->KeyMaterial[i]));
  341. }
  342. else
  343. {
  344. UINT nAnsi;
  345. nAnsi = WideCharToMultiByte(
  346. CP_ACP,
  347. 0,
  348. wszParamArg,
  349. nKLen,
  350. pndKey->KeyMaterial,
  351. pndKey->KeyLength,
  352. NULL,
  353. NULL);
  354. if (nAnsi != pndKey->KeyLength)
  355. dwErr = ERROR_BAD_FORMAT;
  356. else
  357. wszParamArg += pndKey->KeyLength;
  358. }
  359. }
  360. // if the key material proved to be correct, then pass the data in the pPDData
  361. if (dwErr == ERROR_SUCCESS)
  362. {
  363. _Asrt(*wszParamArg == L'\0' ||
  364. *wszParamArg == L'"',
  365. L"Code bug - key length incorrectly inferred.\n");
  366. pPDData->wzcIntfEntry.rdCtrlData.dwDataLen = pndKey->Length;
  367. pPDData->wzcIntfEntry.rdCtrlData.pData = (LPBYTE)pndKey;
  368. }
  369. else
  370. {
  371. MemFree(pndKey);
  372. }
  373. return FnPaPostProcess(dwErr, pPDData, pPDEntry);;
  374. }
  375. //----------------------------------------------------
  376. // Parser for the boolean argument for the "onex" parameter
  377. DWORD
  378. FnPaOneX(PPARAM_DESCR_DATA pPDData, PPARAM_DESCR pPDEntry, LPWSTR wszParamArg)
  379. {
  380. DWORD dwErr = ERROR_SUCCESS;
  381. BOOL bOneX;
  382. dwErr = FnPaUint(&wszParamArg, L'\0', (UINT *)&bOneX);
  383. if (dwErr == ERROR_SUCCESS)
  384. {
  385. if (bOneX != TRUE && bOneX != FALSE)
  386. dwErr = ERROR_INVALID_DATA;
  387. else
  388. {
  389. // save the parameter's argument
  390. pPDData->bOneX = bOneX;
  391. }
  392. }
  393. return FnPaPostProcess(dwErr, pPDData, pPDEntry);
  394. }
  395. //----------------------------------------------------
  396. // Parser for the "outfile" file name parameter
  397. FnPaOutFile(PPARAM_DESCR_DATA pPDData, PPARAM_DESCR pPDEntry, LPWSTR wszParamArg)
  398. {
  399. FILE *pfOut;
  400. DWORD dwErr = ERROR_SUCCESS;
  401. pfOut = _wfopen(wszParamArg, L"a+");
  402. if (pfOut == NULL)
  403. dwErr = GetLastError();
  404. if (dwErr == ERROR_SUCCESS)
  405. {
  406. CHAR szCrtDate[32];
  407. CHAR szCrtTime[32];
  408. pPDData->pfOut = pfOut;
  409. fprintf(pPDData->pfOut,"\n\n[%s - %s]\n",
  410. _strdate(szCrtDate), _strtime(szCrtTime));
  411. }
  412. return FnPaPostProcess(dwErr, pPDData, pPDEntry);
  413. }