Source code of Windows XP (NT5)
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.

733 lines
18 KiB

  1. #include "inc.h"
  2. #define GUID_FORMAT_W L"{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}"
  3. DEFINE_GUID(GUID_NULL, 0L, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  4. CMD_ENTRY g_rgIfCmdTable[] = {
  5. {TOKEN_STATS, PrintStats},
  6. {TOKEN_INFO, PrintInfo},
  7. {TOKEN_NAME, PrintName},
  8. {TOKEN_GUID, PrintGuid},
  9. };
  10. int
  11. __cdecl
  12. ScanHexFormat(
  13. IN const WCHAR* pwszBuffer,
  14. IN ULONG ulCharCount,
  15. IN const WCHAR* pwszFormat,
  16. ...
  17. )
  18. /*++
  19. Routine Description:
  20. Scans a source Buffer and places values from that buffer into the parameters
  21. as specified by Format.
  22. Arguments:
  23. pwszBuffer Source buffer which is to be scanned.
  24. ulCharCount Maximum length in characters for which Buffer is searched.
  25. This implies that Buffer need not be UNICODE_NULL terminated.
  26. Format Format string which defines both the acceptable string form as
  27. contained in pwszBuffer
  28. Return Value:
  29. Returns the number of parameters filled if the end of the Buffer is reached,
  30. else -1 on an error.
  31. --*/
  32. {
  33. va_list ArgList;
  34. int iFormatItems;
  35. va_start(ArgList, pwszFormat);
  36. //
  37. // Count of number of parameters filled
  38. //
  39. iFormatItems = 0;
  40. while(TRUE)
  41. {
  42. switch (*pwszFormat)
  43. {
  44. case UNICODE_NULL:
  45. {
  46. //
  47. // end of string
  48. //
  49. return (*pwszBuffer && ulCharCount) ? -1 : iFormatItems;
  50. }
  51. case L'%':
  52. {
  53. //
  54. // Format specifier
  55. //
  56. pwszFormat++;
  57. if (*pwszFormat != L'%')
  58. {
  59. ULONG ulNumber;
  60. int iWidth;
  61. int iLong;
  62. PVOID pvPointer;
  63. //
  64. // So it isnt a %%
  65. //
  66. iLong = 0;
  67. iWidth = 0;
  68. while(TRUE)
  69. {
  70. if((*pwszFormat >= L'0') &&
  71. (*pwszFormat <= L'9'))
  72. {
  73. iWidth = iWidth * 10 + *pwszFormat - '0';
  74. }
  75. else
  76. {
  77. if(*pwszFormat == L'l')
  78. {
  79. iLong++;
  80. }
  81. else
  82. {
  83. if((*pwszFormat == L'X') ||
  84. (*pwszFormat == L'x'))
  85. {
  86. break;
  87. }
  88. }
  89. }
  90. //
  91. // Move to the next specifier
  92. //
  93. pwszFormat++;
  94. }
  95. pwszFormat++;
  96. for(ulNumber = 0; iWidth--; pwszBuffer++, ulCharCount--)
  97. {
  98. if(!ulCharCount)
  99. {
  100. return -1;
  101. }
  102. ulNumber *= 16;
  103. if((*pwszBuffer >= L'0') &&
  104. (*pwszBuffer <= L'9'))
  105. {
  106. ulNumber += (*pwszBuffer - L'0');
  107. }
  108. else
  109. {
  110. if((*pwszBuffer >= L'a') &&
  111. (*pwszBuffer <= L'f'))
  112. {
  113. ulNumber += (*pwszBuffer - L'a' + 10);
  114. }
  115. else
  116. {
  117. if((*pwszBuffer >= L'A') &&
  118. (*pwszBuffer <= L'F'))
  119. {
  120. ulNumber += (*pwszBuffer - L'A' + 10);
  121. }
  122. else
  123. {
  124. return -1;
  125. }
  126. }
  127. }
  128. }
  129. pvPointer = va_arg(ArgList, PVOID);
  130. if(iLong)
  131. {
  132. *(PULONG)pvPointer = ulNumber;
  133. }
  134. else
  135. {
  136. *(PUSHORT)pvPointer = (USHORT)ulNumber;
  137. }
  138. iFormatItems++;
  139. break;
  140. }
  141. //
  142. // NO BREAK
  143. //
  144. }
  145. default:
  146. {
  147. if (!ulCharCount || (*pwszBuffer != *pwszFormat))
  148. {
  149. return -1;
  150. }
  151. pwszBuffer++;
  152. ulCharCount--;
  153. pwszFormat++;
  154. break;
  155. }
  156. }
  157. }
  158. }
  159. DWORD
  160. ConvertGuidToString(
  161. IN GUID *pGuid,
  162. OUT PWCHAR pwszBuffer
  163. )
  164. /*++
  165. Routine Description:
  166. Constructs the standard string version of a GUID, in the form:
  167. "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}".
  168. Arguments:
  169. pGuid Contains the GUID to translate.
  170. pwszBuffer Space for storing the string. Must be >= 39 * sizeof(WCHAR)
  171. Return Value:
  172. --*/
  173. {
  174. return swprintf(pwszBuffer,
  175. GUID_FORMAT_W,
  176. pGuid->Data1,
  177. pGuid->Data2,
  178. pGuid->Data3,
  179. pGuid->Data4[0],
  180. pGuid->Data4[1],
  181. pGuid->Data4[2],
  182. pGuid->Data4[3],
  183. pGuid->Data4[4],
  184. pGuid->Data4[5],
  185. pGuid->Data4[6],
  186. pGuid->Data4[7]);
  187. }
  188. DWORD
  189. ConvertStringToGuid(
  190. IN PWCHAR pwszGuid,
  191. IN ULONG ulStringLen,
  192. OUT GUID *pGuid
  193. )
  194. /*++
  195. Routine Description:
  196. Retrieves a the binary format of a textual GUID presented in the standard
  197. string version of a GUID: "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}".
  198. Arguments:
  199. GuidString -
  200. Place from which to retrieve the textual form of the GUID.
  201. Guid -
  202. Place in which to put the binary form of the GUID.
  203. Return Value:
  204. Returns STATUS_SUCCESS if the buffer contained a valid GUID, else
  205. STATUS_INVALID_PARAMETER if the string was invalid.
  206. --*/
  207. {
  208. USHORT Data4[8];
  209. int Count;
  210. if (ScanHexFormat(pwszGuid,
  211. ulStringLen/sizeof(WCHAR),
  212. GUID_FORMAT_W,
  213. &pGuid->Data1,
  214. &pGuid->Data2,
  215. &pGuid->Data3,
  216. &Data4[0],
  217. &Data4[1],
  218. &Data4[2],
  219. &Data4[3],
  220. &Data4[4],
  221. &Data4[5],
  222. &Data4[6],
  223. &Data4[7]) == -1)
  224. {
  225. return ERROR_INVALID_PARAMETER;
  226. }
  227. for(Count = 0; Count < sizeof(Data4)/sizeof(Data4[0]); Count++)
  228. {
  229. pGuid->Data4[Count] = (UCHAR)Data4[Count];
  230. }
  231. return NO_ERROR;
  232. }
  233. VOID
  234. HandleInterface(
  235. LONG lNumArgs,
  236. PWCHAR rgpwszArgs[]
  237. )
  238. {
  239. LONG lIndex;
  240. if(lNumArgs < 2)
  241. {
  242. DisplayMessage(HMSG_IF_USAGE);
  243. return;
  244. }
  245. lIndex = ParseCommand(g_rgIfCmdTable,
  246. sizeof(g_rgIfCmdTable)/sizeof(CMD_ENTRY),
  247. rgpwszArgs[1]);
  248. if(lIndex is -1)
  249. {
  250. DisplayMessage(HMSG_IF_USAGE);
  251. return;
  252. }
  253. g_rgIfCmdTable[lIndex].pfnHandler(lNumArgs - 1,
  254. &rgpwszArgs[1]);
  255. return;
  256. }
  257. VOID
  258. PrintStats(
  259. LONG lNumArgs,
  260. PWCHAR rgpwszArgs[]
  261. )
  262. {
  263. DWORD dwResult, i, j;
  264. PMIB_IFTABLE pTable;
  265. dwResult = AllocateAndGetIfTableFromStack(&pTable,
  266. TRUE,
  267. GetProcessHeap(),
  268. HEAP_NO_SERIALIZE,
  269. FALSE);
  270. if(dwResult isnot NO_ERROR)
  271. {
  272. PWCHAR pwszEntry;
  273. pwszEntry = MakeString(STR_IFTABLE);
  274. if(pwszEntry)
  275. {
  276. DisplayMessage(EMSG_RETRIEVAL_ERROR1,
  277. dwResult,
  278. pwszEntry);
  279. FreeString(pwszEntry);
  280. }
  281. else
  282. {
  283. DisplayMessage(EMSG_RETRIEVAL_ERROR2,
  284. dwResult);
  285. }
  286. return;
  287. }
  288. if(pTable->dwNumEntries is 0)
  289. {
  290. PWCHAR pwszEntryType;
  291. pwszEntryType = MakeString(TOKEN_INTERFACE);
  292. if(pwszEntryType)
  293. {
  294. DisplayMessage(EMSG_NO_ENTRIES1,
  295. pwszEntryType);
  296. FreeString(pwszEntryType);
  297. }
  298. else
  299. {
  300. DisplayMessage(EMSG_NO_ENTRIES2);
  301. }
  302. HeapFree(GetProcessHeap(),
  303. HEAP_NO_SERIALIZE,
  304. pTable);
  305. return;
  306. }
  307. for(i = 0; i < pTable->dwNumEntries; i++)
  308. {
  309. PWCHAR pwszIfType, pwszAdmin, pwszOper;
  310. WCHAR rgwcDescr[MAXLEN_IFDESCR + 1];
  311. WCHAR rgwcPhysAddr[3*MAXLEN_PHYSADDR + 8];
  312. switch(pTable->table[i].dwType)
  313. {
  314. case IF_TYPE_OTHER:
  315. {
  316. pwszIfType = MakeString(STR_OTHER);
  317. break;
  318. }
  319. case IF_TYPE_ETHERNET_CSMACD:
  320. {
  321. pwszIfType = MakeString(STR_ETHERNET);
  322. break;
  323. }
  324. case IF_TYPE_ISO88025_TOKENRING:
  325. {
  326. pwszIfType = MakeString(STR_TOKENRING);
  327. break;
  328. }
  329. case IF_TYPE_FDDI:
  330. {
  331. pwszIfType = MakeString(STR_FDDI);
  332. break;
  333. }
  334. case IF_TYPE_PPP:
  335. {
  336. pwszIfType = MakeString(STR_PPP);
  337. break;
  338. }
  339. case IF_TYPE_SOFTWARE_LOOPBACK:
  340. {
  341. pwszIfType = MakeString(STR_LOOPBACK);
  342. break;
  343. }
  344. case IF_TYPE_SLIP:
  345. {
  346. pwszIfType = MakeString(STR_SLIP);
  347. break;
  348. }
  349. }
  350. switch(pTable->table[i].dwAdminStatus)
  351. {
  352. case IF_ADMIN_STATUS_UP:
  353. {
  354. pwszAdmin = MakeString(STR_UP);
  355. break;
  356. }
  357. case IF_ADMIN_STATUS_DOWN:
  358. {
  359. pwszAdmin = MakeString(STR_DOWN);
  360. break;
  361. }
  362. case IF_ADMIN_STATUS_TESTING:
  363. {
  364. pwszAdmin = MakeString(STR_TESTING);
  365. break;
  366. }
  367. }
  368. switch(pTable->table[i].dwOperStatus)
  369. {
  370. case IF_OPER_STATUS_NON_OPERATIONAL:
  371. {
  372. pwszOper = MakeString(STR_NON_OPERATIONAL);
  373. break;
  374. }
  375. case IF_OPER_STATUS_UNREACHABLE:
  376. {
  377. pwszOper = MakeString(STR_UNREACHABLE);
  378. break;
  379. }
  380. case IF_OPER_STATUS_DISCONNECTED:
  381. {
  382. pwszOper = MakeString(STR_DISCONNECTED);
  383. break;
  384. }
  385. case IF_OPER_STATUS_CONNECTING:
  386. {
  387. pwszOper = MakeString(STR_CONNECTING);
  388. break;
  389. }
  390. case IF_OPER_STATUS_CONNECTED:
  391. {
  392. pwszOper = MakeString(STR_CONNECTED);
  393. break;
  394. }
  395. case IF_OPER_STATUS_OPERATIONAL:
  396. {
  397. pwszOper = MakeString(STR_OPERATIONAL);
  398. break;
  399. }
  400. }
  401. MultiByteToWideChar(CP_ACP,
  402. 0,
  403. pTable->table[i].bDescr,
  404. -1,
  405. rgwcDescr,
  406. MAXLEN_IFDESCR);
  407. rgwcDescr[MAXLEN_IFDESCR] = UNICODE_NULL;
  408. PhysAddrToUnicode(rgwcPhysAddr,
  409. pTable->table[i].bPhysAddr,
  410. pTable->table[i].dwPhysAddrLen);
  411. DisplayMessage(MSG_IF_INFO,
  412. pTable->table[i].wszName,
  413. pTable->table[i].dwIndex,
  414. pwszIfType,
  415. pTable->table[i].dwMtu,
  416. pTable->table[i].dwSpeed,
  417. rgwcPhysAddr,
  418. pwszAdmin,
  419. pwszOper,
  420. pTable->table[i].dwLastChange,
  421. pTable->table[i].dwInOctets,
  422. pTable->table[i].dwInUcastPkts,
  423. pTable->table[i].dwInNUcastPkts,
  424. pTable->table[i].dwInDiscards,
  425. pTable->table[i].dwInErrors,
  426. pTable->table[i].dwInUnknownProtos,
  427. pTable->table[i].dwOutOctets,
  428. pTable->table[i].dwOutUcastPkts,
  429. pTable->table[i].dwOutNUcastPkts,
  430. pTable->table[i].dwOutDiscards,
  431. pTable->table[i].dwOutErrors,
  432. pTable->table[i].dwOutQLen,
  433. rgwcDescr);
  434. FreeString(pwszIfType);
  435. FreeString(pwszAdmin);
  436. FreeString(pwszOper);
  437. }
  438. }
  439. VOID
  440. PrintInfo(
  441. LONG lNumArgs,
  442. PWCHAR rgpwszArgs[]
  443. )
  444. {
  445. DWORD dwResult, i, dwCount;
  446. PIP_INTERFACE_NAME_INFO pTable;
  447. dwResult = NhpAllocateAndGetInterfaceInfoFromStack(&pTable,
  448. &dwCount,
  449. TRUE,
  450. GetProcessHeap(),
  451. HEAP_NO_SERIALIZE);
  452. if(dwResult isnot NO_ERROR)
  453. {
  454. PWCHAR pwszEntry;
  455. pwszEntry = MakeString(STR_IFTABLE);
  456. if(pwszEntry)
  457. {
  458. DisplayMessage(EMSG_RETRIEVAL_ERROR1,
  459. dwResult,
  460. pwszEntry);
  461. FreeString(pwszEntry);
  462. }
  463. else
  464. {
  465. DisplayMessage(EMSG_RETRIEVAL_ERROR2,
  466. dwResult);
  467. }
  468. return;
  469. }
  470. if(dwCount is 0)
  471. {
  472. PWCHAR pwszEntryType;
  473. pwszEntryType = MakeString(TOKEN_INTERFACE);
  474. if(pwszEntryType)
  475. {
  476. DisplayMessage(EMSG_NO_ENTRIES1,
  477. pwszEntryType);
  478. FreeString(pwszEntryType);
  479. }
  480. else
  481. {
  482. DisplayMessage(EMSG_NO_ENTRIES2);
  483. }
  484. HeapFree(GetProcessHeap(),
  485. HEAP_NO_SERIALIZE,
  486. pTable);
  487. return;
  488. }
  489. for(i = 0; i < dwCount; i++)
  490. {
  491. WCHAR pwszDeviceGuid[40], pwszIfGuid[40];
  492. WCHAR pwszName[300];
  493. GUID *pGuid;
  494. DWORD dwSize;
  495. ConvertGuidToString(&(pTable[i].DeviceGuid),
  496. pwszDeviceGuid);
  497. ConvertGuidToString(&(pTable[i].InterfaceGuid),
  498. pwszIfGuid);
  499. if(IsEqualGUID(&(pTable[i].InterfaceGuid),
  500. &(GUID_NULL)))
  501. {
  502. pGuid = &(pTable[i].DeviceGuid);
  503. }
  504. else
  505. {
  506. pGuid = &(pTable[i].InterfaceGuid);
  507. }
  508. dwSize = sizeof(pwszName);
  509. dwResult = NhGetInterfaceNameFromGuid(pGuid,
  510. pwszName,
  511. &dwSize,
  512. FALSE,
  513. TRUE);
  514. ASSERT(dwResult == NO_ERROR);
  515. wprintf(L"%d %s %s %s\n",
  516. pTable[i].Index,
  517. pwszDeviceGuid,
  518. pwszIfGuid,
  519. pwszName);
  520. }
  521. }
  522. VOID
  523. PrintName(
  524. LONG lNumArgs,
  525. PWCHAR rgpwszArgs[]
  526. )
  527. {
  528. ULONG ulSize;
  529. GUID Guid;
  530. WCHAR rgwcIfName[MAX_INTERFACE_NAME_LEN + 2];
  531. //
  532. // The command line at this point should read:
  533. // NAME {Guid}
  534. //
  535. if(lNumArgs != 2)
  536. {
  537. DisplayMessage(HMSG_IF_NAME_USAGE);
  538. return;
  539. }
  540. if(ConvertStringToGuid(rgpwszArgs[1],
  541. wcslen(rgpwszArgs[1]) * sizeof(WCHAR),
  542. &Guid) isnot NO_ERROR)
  543. {
  544. DisplayMessage(HMSG_IF_NAME_USAGE);
  545. return;
  546. }
  547. ulSize = sizeof(rgwcIfName);
  548. if(NhGetInterfaceNameFromGuid(&Guid,
  549. rgwcIfName,
  550. &ulSize,
  551. FALSE,
  552. TRUE) isnot NO_ERROR)
  553. {
  554. DisplayMessage(EMSG_NO_SUCH_IF);
  555. return;
  556. }
  557. wprintf(L"%s\n", rgwcIfName);
  558. }
  559. VOID
  560. PrintGuid(
  561. LONG lNumArgs,
  562. PWCHAR rgpwszArgs[]
  563. )
  564. {
  565. GUID Guid;
  566. WCHAR rgwcString[40];
  567. //
  568. // The command line at this point should read:
  569. // GUID "Name"
  570. //
  571. if(lNumArgs != 2)
  572. {
  573. DisplayMessage(HMSG_IF_GUID_USAGE);
  574. return;
  575. }
  576. if(NhGetGuidFromInterfaceName(rgpwszArgs[1],
  577. &Guid,
  578. FALSE,
  579. TRUE) isnot NO_ERROR)
  580. {
  581. DisplayMessage(EMSG_NO_SUCH_IF);
  582. return;
  583. }
  584. ConvertGuidToString(&Guid,
  585. rgwcString);
  586. wprintf(L"%s\n", rgwcString);
  587. }