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.

1540 lines
36 KiB

  1. /*++
  2. Copyright(c) 2001 Microsoft Corporation
  3. Module Name:
  4. NLB Manager
  5. File Name:
  6. tprov.cpp
  7. Abstract:
  8. Test harness for nlb manager provider code
  9. History:
  10. 04/08/01 JosephJ Created
  11. --*/
  12. #include "tprov.h"
  13. #include "tprov.tmh"
  14. BOOL g_Silent = FALSE;
  15. typedef enum
  16. {
  17. DO_USAGE,
  18. DO_NICLIST,
  19. DO_IPADDR,
  20. DO_NLBCFG,
  21. DO_NLBBIND,
  22. DO_UPDATE,
  23. DO_WMIUPDATE,
  24. DO_CLEANREG
  25. } COMMAND_TYPE;
  26. VOID do_usage(VOID);
  27. VOID do_niclist(VOID);
  28. VOID do_ipaddr(VOID);
  29. VOID do_nlbcfg(VOID);
  30. VOID do_nlbbind(VOID);
  31. VOID do_update(VOID);
  32. VOID do_wmiupdate(VOID);
  33. VOID do_cleanreg(VOID);
  34. VOID test_add_ips(LPCWSTR szNic);
  35. VOID test_bind_nlb(LPCWSTR szNic);
  36. VOID test_cfg_nlb(LPCWSTR szNic);
  37. VOID test_update(LPCWSTR szMachine, LPCWSTR szNic);
  38. void test(int argc, WCHAR* argv[]);
  39. void test(int argc, WCHAR* argv[]);
  40. void test_safearray(void);
  41. VOID test_exfcfgclass(void);
  42. BOOL read_guid(LPWSTR *pszNic);
  43. BOOL read_machinename(LPWSTR *pszNic);
  44. COMMAND_TYPE
  45. parse_args(int argc, WCHAR* argv[]);
  46. void
  47. display_config(
  48. LPCWSTR szNicGuid,
  49. NLB_EXTENDED_CLUSTER_CONFIGURATION *pCfg
  50. );
  51. VOID
  52. display_ip_info(
  53. IN UINT NumIpAddresses,
  54. IN NLB_IP_ADDRESS_INFO *pIpInfo
  55. );
  56. WBEMSTATUS
  57. read_ip_info(
  58. IN LPCWSTR szNic,
  59. OUT UINT *pNumIpAddresses,
  60. OUT NLB_IP_ADDRESS_INFO **ppIpInfo
  61. );
  62. int __cdecl wmain(int argc, WCHAR* argv[], WCHAR* envp[])
  63. {
  64. int nRetCode = 0;
  65. //
  66. // Enable tracing
  67. //
  68. WPP_INIT_TRACING(L"Microsoft\\NLB\\TPROV");
  69. #if 0
  70. // test_port_rule_string();
  71. // test_safearray();
  72. // test_tmgr(argc, argv);
  73. test_exfcfgclass();
  74. #else
  75. NlbConfigurationUpdate::Initialize();
  76. test(argc, argv);
  77. NlbConfigurationUpdate::Deinitialize();
  78. #endif
  79. //
  80. // Disable tracing
  81. //
  82. WPP_CLEANUP();
  83. return nRetCode;
  84. }
  85. NLB_EXTENDED_CLUSTER_CONFIGURATION MyOldCfg;
  86. NLB_EXTENDED_CLUSTER_CONFIGURATION MyNewCfg;
  87. VOID
  88. display_log(WCHAR *pLog)
  89. {
  90. static UINT previous_length;
  91. UINT current_length;
  92. current_length = wcslen(pLog);
  93. if (previous_length > current_length)
  94. {
  95. previous_length = 0;
  96. }
  97. wprintf(pLog+previous_length);
  98. previous_length = current_length;
  99. }
  100. LPCWSTR NicGuids[] = {
  101. L"{AD4DA14D-CAAE-42DD-97E3-5355E55247C2}",
  102. L"{B2CD5533-5091-4F49-B80F-A07844B14209}",
  103. L"{EBE09517-07B4-4E88-AAF1-E06F5540608B}",
  104. L"{ABEA4318-5EE8-4DEC-AF3C-B4AEDE61454E}",
  105. L"{66A1869A-BF85-4D95-BBAB-07FA5B4449D4}",
  106. L"{AEEE83AF-AA48-4599-94BB-7C458D63CEED}",
  107. L"{D0536EEE-2CE0-4E8D-BFEC-0A608CFD81B9}"
  108. };
  109. UINT Trial;
  110. void test(int argc, WCHAR* argv[])
  111. {
  112. COMMAND_TYPE cmd;
  113. cmd = parse_args(argc, argv);
  114. switch(cmd)
  115. {
  116. case DO_USAGE: do_usage();
  117. break;
  118. case DO_NICLIST: do_niclist();
  119. break;
  120. case DO_IPADDR: do_ipaddr();
  121. break;
  122. case DO_NLBCFG: do_nlbcfg();
  123. break;
  124. case DO_NLBBIND: do_nlbbind();
  125. break;
  126. case DO_UPDATE: do_update();
  127. break;
  128. case DO_WMIUPDATE: do_wmiupdate();
  129. break;
  130. case DO_CLEANREG: do_cleanreg();
  131. break;
  132. }
  133. return;
  134. }
  135. void
  136. display_config(
  137. LPCWSTR szNicGuid,
  138. NLB_EXTENDED_CLUSTER_CONFIGURATION *pCfg
  139. )
  140. {
  141. if (g_Silent) return;
  142. printf("\nNLB Configuration for NIC %ws\n", szNicGuid);
  143. printf("\tfValidNlbCfg=%d\n", pCfg->fValidNlbCfg);
  144. printf("\tGeneration=%d\n", pCfg->Generation);
  145. printf("\tfBound=%d\n", pCfg->fBound);
  146. printf("\tfAddDedicatedIp=%d\n", pCfg->fAddDedicatedIp);
  147. UINT AddrCount = pCfg->NumIpAddresses;
  148. display_ip_info(AddrCount, pCfg->pIpAddressInfo);
  149. if (pCfg->fBound)
  150. {
  151. printf("\n");
  152. printf("\tNLB configuration:\n");
  153. if (pCfg->fValidNlbCfg)
  154. {
  155. printf("\t\tClusterIP: {%ws,%ws}\n",
  156. pCfg->NlbParams.cl_ip_addr,
  157. pCfg->NlbParams.cl_net_mask
  158. );
  159. printf("\t\tDedicatedIP: {%ws,%ws}\n",
  160. pCfg->NlbParams.ded_ip_addr,
  161. pCfg->NlbParams.ded_net_mask
  162. );
  163. }
  164. else
  165. {
  166. printf("**invalid configuration**\n");
  167. }
  168. }
  169. printf("\n");
  170. return;
  171. }
  172. VOID
  173. test_add_ips(LPCWSTR szNic)
  174. //
  175. // Go through a set of IPs on this NIC
  176. //
  177. {
  178. WBEMSTATUS Status = WBEM_NO_ERROR;
  179. UINT NumIpAddresses= 0;
  180. NLB_IP_ADDRESS_INFO *pIpInfo = NULL;
  181. while(1)
  182. {
  183. //
  184. // Get the current list of ip addresses
  185. //
  186. Status = CfgUtilGetIpAddressesAndFriendlyName(
  187. szNic,
  188. &NumIpAddresses,
  189. &pIpInfo,
  190. NULL // szFriendly name
  191. );
  192. if (FAILED(Status))
  193. {
  194. printf("Error 0x%08lx getting ip address list for %ws\n",
  195. (UINT) Status, szNic);
  196. pIpInfo = NULL;
  197. goto end;
  198. }
  199. //
  200. // display what we find.
  201. //
  202. display_ip_info(NumIpAddresses, pIpInfo);
  203. if (pIpInfo!=NULL)
  204. {
  205. delete pIpInfo;
  206. pIpInfo = NULL;
  207. }
  208. //
  209. // Read the list ip address and subnet masks from the input
  210. //
  211. Status = read_ip_info(szNic, &NumIpAddresses, &pIpInfo);
  212. if (FAILED(Status))
  213. {
  214. printf("Quitting test_add_ips\n");
  215. break;
  216. }
  217. //
  218. // Set the specified IPs
  219. //
  220. 1 && (Status = CfgUtilSetStaticIpAddresses(
  221. szNic,
  222. NumIpAddresses,
  223. pIpInfo
  224. ));
  225. if (FAILED(Status))
  226. {
  227. printf("CfgUtilSetStaticIpAddresses failed with status 0x%08lx\n",
  228. Status);
  229. }
  230. else
  231. {
  232. printf("Successfully set the specified IPs on the NIC\n");
  233. }
  234. }
  235. end:
  236. if (pIpInfo != NULL)
  237. {
  238. delete pIpInfo;
  239. }
  240. }
  241. VOID
  242. test_bind_nlb(LPCWSTR szNic)
  243. {
  244. WBEMSTATUS Status;
  245. BOOL fBound = FALSE;
  246. printf("\nRunning bind/unbind test for NIC %ws...\n\n", szNic);
  247. while(1)
  248. {
  249. //
  250. // Check NLB bind state
  251. //
  252. printf("Checking if NLB is bound...\n");
  253. Status = CfgUtilCheckIfNlbBound(szNic, &fBound);
  254. if (FAILED(Status))
  255. {
  256. printf("CfgUtilCheckIfNlbBound fails with error 0x%08lx\n", (UINT)Status);
  257. break;
  258. }
  259. printf(
  260. "NLB is %wsbound\n\n",
  261. (fBound) ? L"" : L"NOT "
  262. );
  263. printf("Enter 'b' to bind, 'u' to unbind or 'q' to quit\n:");
  264. WCHAR Temp[32] = L"";
  265. while (wscanf(L" %1[buq]", Temp)!=1)
  266. {
  267. printf("Incorrect input. Try again.\n");
  268. }
  269. if (*Temp == 'b')
  270. {
  271. printf("Attempting to bind NLB...\n");
  272. fBound = TRUE;
  273. }
  274. else if (*Temp == 'u')
  275. {
  276. printf("Attempting to unbind NLB\n");
  277. fBound = FALSE;
  278. }
  279. else
  280. {
  281. printf("Quitting\n");
  282. break;
  283. }
  284. #if 1
  285. Status = CfgUtilChangeNlbBindState(szNic, fBound);
  286. if (FAILED(Status))
  287. {
  288. printf("CfgUtilChangeNlbBindState fails with error %08lx\n",
  289. (UINT) Status);
  290. }
  291. else
  292. {
  293. printf(
  294. "%ws completed successfully\n",
  295. (fBound) ? L"Bind" : L"Unbind"
  296. );
  297. }
  298. #endif // 0
  299. printf("\n");
  300. }
  301. }
  302. VOID
  303. test_cfg_nlb(LPCWSTR szNic)
  304. {
  305. WBEMSTATUS Status;
  306. printf("\nRunning update NLB config test for NIC %ws...\n\n", szNic);
  307. while (1)
  308. {
  309. WLBS_REG_PARAMS Params;
  310. ZeroMemory(&Params, sizeof(Params));
  311. //
  312. // Read NLB config
  313. //
  314. Status = CfgUtilGetNlbConfig(szNic, &Params);
  315. if (FAILED(Status))
  316. {
  317. printf("CfgUtilGetNlbConfig fails with error 0x%08lx\n", (UINT)Status);
  318. break;
  319. }
  320. printf("NLB configuration:\n");
  321. printf(
  322. "\tClusterIP: {%ws,%ws}\n",
  323. Params.cl_ip_addr,
  324. Params.cl_net_mask
  325. );
  326. //
  327. // Make some modifications
  328. //
  329. printf("\nEnter new {cluster-ip-addr,subnet-mask} or 'q' to quit\n:");
  330. while(1)
  331. {
  332. NLB_IP_ADDRESS_INFO Info;
  333. INT i = wscanf(
  334. L" { %15[0-9.] , %15[0-9.] }",
  335. Info.IpAddress,
  336. Info.SubnetMask
  337. );
  338. if (i!=2)
  339. {
  340. WCHAR Temp[100] = L"";
  341. wscanf(L"%64ws", Temp);
  342. if (!_wcsicmp(Temp, L"q"))
  343. {
  344. printf("Quitting\n");
  345. goto end;
  346. }
  347. else
  348. {
  349. printf("Badly formed input. Try again\n");
  350. }
  351. }
  352. else
  353. {
  354. wcscpy(Params.cl_ip_addr, Info.IpAddress);
  355. wcscpy(Params.cl_net_mask, Info.SubnetMask);
  356. break;
  357. }
  358. }
  359. //
  360. // Write NLB config
  361. //
  362. #if 1
  363. printf("\nAttempting to update NLB configuration...\n");
  364. Status = CfgUtilSetNlbConfig(szNic, &Params);
  365. if (FAILED(Status))
  366. {
  367. printf("CfgUtilSetNlbConfig fails with error %08lx\n",
  368. (UINT) Status);
  369. }
  370. else
  371. {
  372. printf("change completed successfully\n");
  373. }
  374. #endif // 0
  375. printf("\n");
  376. }
  377. end:
  378. return;
  379. }
  380. VOID
  381. test_update(
  382. LPCWSTR szMachineName, // NULL == don't use wmi
  383. LPCWSTR szNicGuid
  384. )
  385. {
  386. WBEMSTATUS Status;
  387. WCHAR *pLog = NULL;
  388. WBEMSTATUS CompletionStatus;
  389. UINT Generation;
  390. printf("\nRunning high-level update NLB config test for NIC %ws...\n\n", szNicGuid);
  391. while(1)
  392. {
  393. BOOL fSetDefaults = FALSE;
  394. UINT NumIpAddresses = 0;
  395. NLB_IP_ADDRESS_INFO *pIpInfo = NULL;
  396. BOOL fUnbind = FALSE;
  397. //
  398. // Clean up config info
  399. //
  400. if (MyOldCfg.pIpAddressInfo!=NULL)
  401. {
  402. delete MyOldCfg.pIpAddressInfo;
  403. }
  404. ZeroMemory(&MyOldCfg, sizeof(MyOldCfg));
  405. if (MyNewCfg.pIpAddressInfo!=NULL)
  406. {
  407. delete MyNewCfg.pIpAddressInfo;
  408. }
  409. ZeroMemory(&MyNewCfg, sizeof(MyNewCfg));
  410. printf("TEST: Going to get configuration for NIC %ws\n", szNicGuid);
  411. MyBreak(L"Break before calling GetConfiguration.\n");
  412. if (szMachineName==NULL)
  413. {
  414. Status = NlbConfigurationUpdate::GetConfiguration(
  415. szNicGuid,
  416. &MyOldCfg
  417. );
  418. }
  419. else
  420. {
  421. Status = NlbHostGetConfiguration(
  422. szMachineName,
  423. szNicGuid,
  424. &MyOldCfg
  425. );
  426. }
  427. if (FAILED(Status))
  428. {
  429. goto end;
  430. }
  431. display_config(szNicGuid, &MyOldCfg);
  432. if (MyOldCfg.fBound)
  433. {
  434. printf("\nEnter 2 or more {cluster-ip-addr,subnet-mask} or none to unbind or 'q' to quit. The first entry is the dedicated-ip.\n");
  435. if (!MyOldCfg.fValidNlbCfg)
  436. {
  437. //
  438. // We're bound, but nlb params are bad. Set defaults.
  439. //
  440. fSetDefaults = TRUE;
  441. }
  442. }
  443. else
  444. {
  445. //
  446. // We're previously unbound. Set defaults.
  447. //
  448. fSetDefaults = TRUE;
  449. printf("\nEnter 2 or more {cluster-ip-addr,subnet-mask} or 'q' to quit. The first entry is the dedicated-ip.\n");
  450. }
  451. while(1)
  452. {
  453. //
  454. // Read the list ip address and subnet masks from the input
  455. //
  456. Status = read_ip_info(szNicGuid, &NumIpAddresses, &pIpInfo);
  457. if (FAILED(Status))
  458. {
  459. printf("Quitting\n");
  460. goto end;
  461. }
  462. if (NumIpAddresses < 2)
  463. {
  464. if (MyOldCfg.fBound)
  465. {
  466. if (NumIpAddresses == 0)
  467. {
  468. fUnbind = TRUE;
  469. break;
  470. }
  471. else
  472. {
  473. printf("Wrong number of IP addresses -- enter either 0 or >= 2.\n");
  474. }
  475. }
  476. else
  477. {
  478. printf("Wrong number of IP addresses. Enter >= 2 IP addresses.");
  479. }
  480. }
  481. else
  482. {
  483. //
  484. // >= 2 addresses. First one is the dip and the 2nd is the vip.
  485. //
  486. break;
  487. }
  488. if (pIpInfo != NULL)
  489. {
  490. delete pIpInfo;
  491. pIpInfo = NULL;
  492. }
  493. }
  494. if (fUnbind)
  495. {
  496. //
  497. // We're to unbind.
  498. //
  499. ZeroMemory(&MyNewCfg, sizeof(MyNewCfg));
  500. MyNewCfg.fValidNlbCfg = TRUE;
  501. MyNewCfg.fBound = FALSE;
  502. //
  503. // Set the list of ip address to have present on unbind to
  504. // be the dedicated ip address, if there is one, otherwise zero,
  505. // in which case the adapter will be switched to DHCP after NLB
  506. // is unbound
  507. //
  508. if (MyOldCfg.NlbParams.ded_ip_addr[0]!=0)
  509. {
  510. NLB_IP_ADDRESS_INFO *pIpInfo;
  511. pIpInfo = new NLB_IP_ADDRESS_INFO;
  512. if (pIpInfo == NULL)
  513. {
  514. printf("TEST: allocation failure; can't add IP on unbind.\n");
  515. }
  516. else
  517. {
  518. wcscpy(pIpInfo->IpAddress, MyOldCfg.NlbParams.ded_ip_addr);
  519. wcscpy(pIpInfo->SubnetMask, MyOldCfg.NlbParams.ded_net_mask);
  520. MyNewCfg.NumIpAddresses = 1;
  521. MyNewCfg.pIpAddressInfo = pIpInfo;
  522. }
  523. }
  524. }
  525. else
  526. {
  527. if (fSetDefaults)
  528. {
  529. CfgUtilInitializeParams(&MyNewCfg.NlbParams);
  530. MyNewCfg.fValidNlbCfg = TRUE;
  531. MyNewCfg.fBound = TRUE;
  532. }
  533. else
  534. {
  535. MyNewCfg = MyOldCfg; // struct copy
  536. ASSERT(MyNewCfg.fValidNlbCfg == TRUE);
  537. ASSERT(MyNewCfg.fBound == TRUE);
  538. }
  539. //
  540. // Now Add the dedicated and cluster IPs.
  541. //
  542. ASSERT(NumIpAddresses >= 2);
  543. wcscpy(MyNewCfg.NlbParams.ded_ip_addr, pIpInfo[0].IpAddress);
  544. wcscpy(MyNewCfg.NlbParams.ded_net_mask, pIpInfo[0].SubnetMask);
  545. wcscpy(MyNewCfg.NlbParams.cl_ip_addr, pIpInfo[1].IpAddress);
  546. wcscpy(MyNewCfg.NlbParams.cl_net_mask, pIpInfo[1].SubnetMask);
  547. //
  548. // If more IPs, we explicitly add the ip list, else leave it null.
  549. //
  550. if (NumIpAddresses > 2)
  551. {
  552. MyNewCfg.pIpAddressInfo = pIpInfo;
  553. MyNewCfg.NumIpAddresses = NumIpAddresses;
  554. }
  555. else
  556. {
  557. MyNewCfg.fAddDedicatedIp = TRUE; // says to add dedicated ip.
  558. MyNewCfg.pIpAddressInfo=NULL;
  559. MyNewCfg.NumIpAddresses=0;
  560. delete pIpInfo;
  561. pIpInfo = NULL;
  562. }
  563. }
  564. display_config(szNicGuid, &MyNewCfg);
  565. printf("Going to update configuration for NIC %ws\n", szNicGuid);
  566. MyBreak(L"Break before calling DoUpdate.\n");
  567. if (szMachineName==NULL)
  568. {
  569. Status = NlbConfigurationUpdate::DoUpdate(
  570. szNicGuid,
  571. L"tprov.exe",
  572. &MyNewCfg,
  573. &Generation,
  574. &pLog
  575. );
  576. }
  577. else
  578. {
  579. Status = NlbHostDoUpdate(
  580. szMachineName,
  581. szNicGuid,
  582. L"tprov.exe",
  583. &MyNewCfg,
  584. &Generation,
  585. &pLog
  586. );
  587. }
  588. if (pLog != NULL)
  589. {
  590. display_log(pLog);
  591. delete pLog;
  592. pLog = NULL;
  593. }
  594. if (Status == WBEM_S_PENDING)
  595. {
  596. printf(
  597. "Waiting for pending operation %d...\n",
  598. Generation
  599. );
  600. }
  601. while (Status == WBEM_S_PENDING)
  602. {
  603. Sleep(1000);
  604. if (szMachineName == NULL)
  605. {
  606. Status = NlbConfigurationUpdate::GetUpdateStatus(
  607. szNicGuid,
  608. Generation,
  609. FALSE, // FALSE == Don't delete completion record
  610. &CompletionStatus,
  611. &pLog
  612. );
  613. }
  614. else
  615. {
  616. Status = NlbHostGetUpdateStatus(
  617. szMachineName,
  618. szNicGuid,
  619. Generation,
  620. &CompletionStatus,
  621. &pLog
  622. );
  623. }
  624. if (pLog != NULL)
  625. {
  626. display_log(pLog);
  627. delete pLog;
  628. pLog = NULL;
  629. }
  630. if (!FAILED(Status))
  631. {
  632. Status = CompletionStatus;
  633. }
  634. }
  635. printf(
  636. "Final status of update %d is 0x%08lx\n",
  637. Generation,
  638. Status
  639. );
  640. }
  641. end:
  642. return;
  643. }
  644. VOID
  645. display_ip_info(
  646. IN UINT NumIpAddresses,
  647. IN NLB_IP_ADDRESS_INFO *pIpInfo
  648. )
  649. {
  650. UINT AddrCount = NumIpAddresses;
  651. printf("\tNumIpAddresses=%d\n", AddrCount);
  652. if (AddrCount != 0)
  653. {
  654. printf("\tAddress\t\tMask\n");
  655. if (pIpInfo == NULL)
  656. {
  657. printf("ERROR: IpAddressInfo is NULL!\n");
  658. goto end;
  659. }
  660. for (UINT u=0;u<AddrCount; u++)
  661. {
  662. printf(
  663. "\t{%-15ws, %ws}\n",
  664. pIpInfo[u].IpAddress,
  665. pIpInfo[u].SubnetMask
  666. );
  667. }
  668. }
  669. end:
  670. return;
  671. }
  672. WBEMSTATUS
  673. read_ip_info(
  674. IN LPCWSTR szNic,
  675. OUT UINT *pNumIpAddresses,
  676. OUT NLB_IP_ADDRESS_INFO **ppIpInfo
  677. )
  678. {
  679. NLB_IP_ADDRESS_INFO *pIpInfo;
  680. WBEMSTATUS Status = WBEM_NO_ERROR;
  681. #define MAX_READ_IPS 10
  682. printf("Enter zero or more {ip-address,subnet-mask} followed by '.'\n"
  683. "(or 'q' to quit)\n:");
  684. pIpInfo = new NLB_IP_ADDRESS_INFO[MAX_READ_IPS];
  685. if (pIpInfo == NULL)
  686. {
  687. Status = WBEM_E_OUT_OF_MEMORY;
  688. goto end;
  689. }
  690. for (UINT Index=0; Index<MAX_READ_IPS; Index++)
  691. {
  692. NLB_IP_ADDRESS_INFO *pInfo = pIpInfo+Index;
  693. INT i = wscanf(
  694. //L" { %15ws , %15ws }",
  695. //L"{%15ws,%15ws}",
  696. //L"{%ws,%ws}",
  697. //L"{%[0-9.],%[0-9.]}",
  698. L" { %15[0-9.] , %15[0-9.] }",
  699. pInfo->IpAddress,
  700. pInfo->SubnetMask
  701. );
  702. if (i!=2)
  703. {
  704. WCHAR Temp[100];
  705. wscanf(L"%64ws", Temp);
  706. if (!_wcsicmp(Temp, L"q"))
  707. {
  708. Status = WBEM_E_OUT_OF_MEMORY;
  709. break;
  710. }
  711. else if (!_wcsicmp(Temp, L"."))
  712. {
  713. break;
  714. }
  715. else
  716. {
  717. printf("Badly formed input. Try again\n");
  718. Index--;
  719. }
  720. }
  721. }
  722. *pNumIpAddresses = Index;
  723. end:
  724. if (FAILED(Status))
  725. {
  726. if (pIpInfo != NULL)
  727. {
  728. delete pIpInfo;
  729. pIpInfo = NULL;
  730. }
  731. }
  732. *ppIpInfo = pIpInfo;
  733. return Status;
  734. }
  735. COMMAND_TYPE
  736. parse_args(int argc, WCHAR* argv[])
  737. /*++
  738. tprov [niclist|ipaddr|nlbcfg|nlbbind]
  739. --*/
  740. {
  741. COMMAND_TYPE ret = DO_USAGE;
  742. if (argc!=2)
  743. {
  744. if (argc!=1)
  745. {
  746. printf("ERROR: wrong number of arguments\n");
  747. }
  748. goto end;
  749. }
  750. if (!wcscmp(argv[1], L"niclist"))
  751. {
  752. ret = DO_NICLIST;
  753. }
  754. else if (!wcscmp(argv[1], L"ipaddr"))
  755. {
  756. ret = DO_IPADDR;
  757. }
  758. else if (!wcscmp(argv[1], L"nlbcfg"))
  759. {
  760. ret = DO_NLBCFG;
  761. }
  762. else if (!wcscmp(argv[1], L"nlbbind"))
  763. {
  764. ret = DO_NLBBIND;
  765. }
  766. else if (!wcscmp(argv[1], L"update"))
  767. {
  768. ret = DO_UPDATE;
  769. }
  770. else if (!wcscmp(argv[1], L"wmiupdate"))
  771. {
  772. ret = DO_WMIUPDATE;
  773. }
  774. else if (!wcscmp(argv[1], L"cleanreg"))
  775. {
  776. ret = DO_CLEANREG;
  777. }
  778. else
  779. {
  780. printf("ERROR: unknown argument\n");
  781. }
  782. end:
  783. return ret;
  784. }
  785. VOID
  786. do_usage(VOID)
  787. {
  788. printf("Usage:\n\n\tprov [niclist|ipaddr|nlbbind|nlbcfg]\n");
  789. printf("\tniclist -- display the list of NICs\n");
  790. printf("\tipaddr -- change the static ip addresses on a NIC\n");
  791. printf("\tnlbbind -- bind NLB to or unbind NLB from a NIC\n");
  792. printf("\tnlbcfg -- change NLB configuration on a NIC\n");
  793. printf("\tupdate -- update overall configuration on a NIC\n");
  794. printf("\twmiupdate -- WMI version of the update\n");
  795. printf("\n");
  796. }
  797. VOID do_niclist(VOID)
  798. {
  799. LPWSTR *pszNics = NULL;
  800. UINT NumNics = 0;
  801. UINT NumNlbBound = 0;
  802. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  803. // printf("\n\tniclist is unimplemented.\n");
  804. Status = CfgUtilsGetNlbCompatibleNics(&pszNics, &NumNics, &NumNlbBound);
  805. if (FAILED(Status))
  806. {
  807. printf("CfgUtilsGetNlbCompatibleNics returns error 0x%08lx\n",
  808. (UINT) Status);
  809. pszNics = NULL;
  810. goto end;
  811. }
  812. if (NumNics == 0)
  813. {
  814. printf("No compatible local adapter guids.\n");
  815. }
  816. else
  817. {
  818. printf("Local Adapter Guids (%lu bound to NLB):\n", NumNlbBound);
  819. for (UINT u = 0; u<NumNics; u++)
  820. {
  821. LPCWSTR szNic = pszNics[u];
  822. LPWSTR szFriendlyName = NULL;
  823. UINT NumIpAddresses= 0;
  824. NLB_IP_ADDRESS_INFO *pIpInfo = NULL;
  825. //
  826. // Get the current list of ip addresses
  827. //
  828. Status = CfgUtilGetIpAddressesAndFriendlyName(
  829. szNic,
  830. &NumIpAddresses,
  831. &pIpInfo,
  832. &szFriendlyName
  833. );
  834. if (FAILED(Status))
  835. {
  836. pIpInfo = NULL;
  837. szFriendlyName = NULL;
  838. // wprintf(L"%ws\t<null>\t<null>\n", szNic);
  839. wprintf(L"Error getting ip addresses for %ws\n", szNic);
  840. }
  841. else
  842. {
  843. LPCWSTR szCIpAddress = L"";
  844. LPCWSTR szCFriendlyName = L"";
  845. if (NumIpAddresses>0)
  846. {
  847. szCIpAddress = pIpInfo[0].IpAddress;
  848. }
  849. if (szFriendlyName != NULL)
  850. {
  851. szCFriendlyName = szFriendlyName;
  852. }
  853. wprintf(
  854. L"%ws %-15ws \"%ws\"\n",
  855. szNic,
  856. szCIpAddress,
  857. szCFriendlyName
  858. );
  859. }
  860. if (pIpInfo != NULL)
  861. {
  862. delete pIpInfo;
  863. pIpInfo = NULL;
  864. }
  865. if (szFriendlyName != NULL)
  866. {
  867. delete szFriendlyName;
  868. szFriendlyName = NULL;
  869. }
  870. }
  871. }
  872. end:
  873. if (pszNics != NULL)
  874. {
  875. delete pszNics;
  876. pszNics = NULL;
  877. }
  878. }
  879. VOID do_ipaddr(VOID)
  880. {
  881. LPWSTR szNic = NULL;
  882. if (!read_guid(&szNic))
  883. {
  884. szNic = NULL;
  885. goto end;
  886. }
  887. test_add_ips(szNic);
  888. end:
  889. if (szNic!=NULL)
  890. {
  891. delete szNic;
  892. }
  893. }
  894. VOID do_nlbcfg(VOID)
  895. {
  896. LPWSTR szNic = NULL;
  897. if (!read_guid(&szNic))
  898. {
  899. szNic = NULL;
  900. goto end;
  901. }
  902. test_cfg_nlb(szNic);
  903. end:
  904. if (szNic!=NULL)
  905. {
  906. delete szNic;
  907. }
  908. }
  909. VOID do_nlbbind(VOID)
  910. {
  911. LPWSTR szNic = NULL;
  912. if (!read_guid(&szNic))
  913. {
  914. szNic = NULL;
  915. goto end;
  916. }
  917. test_bind_nlb(szNic);
  918. end:
  919. if (szNic!=NULL)
  920. {
  921. delete szNic;
  922. }
  923. }
  924. VOID do_update(VOID)
  925. {
  926. LPWSTR szNic = NULL;
  927. if (!read_guid(&szNic))
  928. {
  929. szNic = NULL;
  930. goto end;
  931. }
  932. test_update(NULL, szNic); // NULL == don't use WMI
  933. end:
  934. if (szNic!=NULL)
  935. {
  936. delete szNic;
  937. }
  938. }
  939. VOID do_wmiupdate(VOID)
  940. {
  941. LPWSTR szNic = NULL;
  942. LPWSTR szMachineName = NULL;
  943. if (!read_machinename(&szMachineName))
  944. {
  945. szMachineName = NULL;
  946. goto end;
  947. }
  948. if (!read_guid(&szNic))
  949. {
  950. szNic = NULL;
  951. goto end;
  952. }
  953. test_update(szMachineName, szNic); // TRUE == use WMI
  954. end:
  955. if (szNic!=NULL)
  956. {
  957. delete szNic;
  958. }
  959. if (szMachineName!=NULL)
  960. {
  961. delete szMachineName;
  962. }
  963. }
  964. VOID do_cleanreg(VOID)
  965. {
  966. printf("Unimplemented\n");
  967. }
  968. BOOL read_guid(
  969. LPWSTR *pszNic
  970. )
  971. {
  972. BOOL fRet = FALSE;
  973. #if 1
  974. WCHAR rgTemp[256];
  975. printf("\nEnter NIC GUID\n:");
  976. while (wscanf(L" %40[-{}a-fA-F0-9]", rgTemp)!=1)
  977. {
  978. wscanf(L" %200s", rgTemp);
  979. printf("Incorrect format. Please try again.\n");
  980. }
  981. #else
  982. LPCWSTR rgTemp = L"{AD4DA14D-CAAE-42DD-97E3-5355E55247C2}";
  983. #endif // 0
  984. LPWSTR szNic = new WCHAR[wcslen(rgTemp)+1];
  985. if (szNic != NULL)
  986. {
  987. wcscpy(szNic, rgTemp);
  988. fRet = TRUE;
  989. }
  990. *pszNic = szNic;
  991. return fRet;
  992. }
  993. BOOL read_machinename(
  994. LPWSTR *pszMachineName
  995. )
  996. {
  997. BOOL fRet = FALSE;
  998. #if 0
  999. WCHAR rgTemp[256];
  1000. printf("\nEnter Machine Name (or '.' for local)\n:");
  1001. while (wscanf(L" %[a-zA-Z0-9._-]", rgTemp)!=1)
  1002. {
  1003. wscanf(L" %200s", rgTemp);
  1004. printf("Incorrect format. Please try again.\n");
  1005. }
  1006. if (!wcscmp(rgTemp, L"."))
  1007. {
  1008. // convert "." to ""
  1009. *rgTemp=0;
  1010. }
  1011. #else
  1012. LPCWSTR rgTemp = L"JOSEPHJ4E";
  1013. #endif
  1014. LPWSTR szMachineName = new WCHAR[wcslen(rgTemp)+1];
  1015. if (szMachineName != NULL)
  1016. {
  1017. wcscpy(szMachineName, rgTemp);
  1018. fRet = TRUE;
  1019. }
  1020. *pszMachineName = szMachineName;
  1021. return fRet;
  1022. }
  1023. void test_safearray(void)
  1024. {
  1025. SAFEARRAY *pSA;
  1026. LPCWSTR pInStrings[] =
  1027. {
  1028. L"String1",
  1029. #if 1
  1030. L"String2",
  1031. L"String3",
  1032. #endif // 0
  1033. NULL // must be last.
  1034. };
  1035. LPWSTR *pOutStrings;
  1036. UINT NumInStrings=0;
  1037. UINT NumOutStrings=0;
  1038. WBEMSTATUS Status;
  1039. //
  1040. // Find count of strings...
  1041. //
  1042. for (NumInStrings=0; pInStrings[NumInStrings]!=NULL; NumInStrings++)
  1043. {
  1044. ;
  1045. }
  1046. Status = CfgUtilSafeArrayFromStrings(
  1047. pInStrings,
  1048. NumInStrings,
  1049. &pSA
  1050. );
  1051. if (FAILED(Status))
  1052. {
  1053. printf("CfgUtilSafeArrayFromStrings failed with error 0x%08lx\n", (UINT)Status);
  1054. pSA = NULL;
  1055. goto end;
  1056. }
  1057. Status = CfgUtilStringsFromSafeArray(
  1058. pSA,
  1059. &pOutStrings,
  1060. &NumOutStrings
  1061. );
  1062. if (FAILED(Status))
  1063. {
  1064. printf("CfgUtilStringsFromSafeArray failed with error 0x%08lx\n", (UINT)Status);
  1065. pOutStrings = NULL;
  1066. goto end;
  1067. }
  1068. //
  1069. // Check that they match
  1070. //
  1071. if (NumOutStrings != NumInStrings)
  1072. {
  1073. printf("ERROR: NumOutStrings != NumInStrings.\n");
  1074. goto end;
  1075. }
  1076. for (UINT u=0; u < NumInStrings; u++)
  1077. {
  1078. if (wcscmp(pInStrings[u], pOutStrings[u]))
  1079. {
  1080. printf("MISMATCH: %ws->%ws\n", pInStrings[u], pOutStrings[u]);
  1081. }
  1082. else
  1083. {
  1084. printf("MATCH: %ws->%ws\n", pInStrings[u], pOutStrings[u]);
  1085. }
  1086. }
  1087. end:
  1088. if (pSA!=NULL)
  1089. {
  1090. SafeArrayDestroy(pSA);
  1091. pSA = NULL;
  1092. }
  1093. if (pOutStrings!=NULL)
  1094. {
  1095. delete pOutStrings;
  1096. pOutStrings = NULL;
  1097. }
  1098. return;
  1099. }
  1100. VOID test_exfcfgclass(void)
  1101. /*
  1102. tests some of the methods of class NLB_EXTENDED_CLUSTER_CONFIGURATION
  1103. 1. Initialize Cfg
  1104. 2. Set a bunch of fields
  1105. 3. display Cfg
  1106. 4. Get and set a bunch of fields on new
  1107. 5. display cfg
  1108. */
  1109. {
  1110. typedef enum
  1111. {
  1112. DO_STRINGS,
  1113. DO_SAFEARRAY,
  1114. DO_STRINGPAIR,
  1115. DO_END
  1116. } TEST_COMMAND;
  1117. TEST_COMMAND cmd;
  1118. printf("Test of NLB_EXTENDED_CLUSTER_CONFIGURATION methods...\n");
  1119. UINT u1=100000L;
  1120. while(u1--> 0)
  1121. {
  1122. g_Silent = TRUE;
  1123. for (cmd=DO_STRINGS; cmd<DO_END; cmd=(TEST_COMMAND)((UINT)cmd + 1))
  1124. {
  1125. NLB_EXTENDED_CLUSTER_CONFIGURATION Cfg;
  1126. NLB_EXTENDED_CLUSTER_CONFIGURATION NewCfg;
  1127. WBEMSTATUS Status = WBEM_NO_ERROR;
  1128. CfgUtilInitializeParams(&Cfg.NlbParams);
  1129. CfgUtilInitializeParams(&NewCfg.NlbParams);
  1130. //
  1131. // Set a bunch of fields in Cfg
  1132. //
  1133. {
  1134. #define TPROV_NUM_ADDRESSES 2
  1135. #define TPROV_NUM_PORTS 1
  1136. LPCWSTR rgszNetworkAddresses[TPROV_NUM_ADDRESSES] = {
  1137. L"10.0.0.1/255.0.0.0",
  1138. L"10.0.0.2/255.0.0.0"
  1139. };
  1140. LPCWSTR rgszIpAddresses[TPROV_NUM_ADDRESSES] = {
  1141. L"10.0.0.1",
  1142. L"10.0.0.2"
  1143. };
  1144. LPCWSTR rgszSubnetMasks[TPROV_NUM_ADDRESSES] = {
  1145. L"255.255.255.0",
  1146. L"255.255.0.0"
  1147. };
  1148. LPCWSTR rgszPortRules[TPROV_NUM_PORTS] = {
  1149. L"ip=1.1.1.1 protocol=TCP start=80 end=288 mode=SINGLE"
  1150. };
  1151. UINT NumOldNetworkAddresses = TPROV_NUM_ADDRESSES;
  1152. UINT NumOldPortRules=TPROV_NUM_PORTS;
  1153. Cfg.fValidNlbCfg = TRUE;
  1154. Cfg.Generation = 123;
  1155. Cfg.fBound = TRUE;
  1156. if (cmd == DO_STRINGS)
  1157. {
  1158. Status = Cfg.SetNetworkAddresses(
  1159. rgszNetworkAddresses,
  1160. NumOldNetworkAddresses
  1161. );
  1162. }
  1163. else if (cmd == DO_SAFEARRAY)
  1164. {
  1165. SAFEARRAY *pOldSA = NULL;
  1166. Status = CfgUtilSafeArrayFromStrings(
  1167. rgszNetworkAddresses,
  1168. NumOldNetworkAddresses,
  1169. &pOldSA
  1170. );
  1171. if (FAILED(Status))
  1172. {
  1173. printf("ERROR: couldn't create safe array!\n");
  1174. pOldSA = NULL;
  1175. }
  1176. if (pOldSA != NULL)
  1177. {
  1178. Status = Cfg.SetNetworkAddressesSafeArray(pOldSA);
  1179. SafeArrayDestroy(pOldSA);
  1180. pOldSA = NULL;
  1181. }
  1182. }
  1183. else if (cmd = DO_STRINGPAIR)
  1184. {
  1185. Status = Cfg.SetNetworkAddresPairs(
  1186. rgszIpAddresses,
  1187. rgszSubnetMasks,
  1188. NumOldNetworkAddresses
  1189. );
  1190. }
  1191. Status = Cfg.SetPortRules(rgszPortRules, NumOldPortRules);
  1192. Cfg.SetClusterNetworkAddress(L"10.0.0.11/255.0.0.0");
  1193. Cfg.SetDedicatedNetworkAddress(L"10.0.0.1/255.0.0.0");
  1194. Cfg.SetTrafficMode(
  1195. NLB_EXTENDED_CLUSTER_CONFIGURATION::TRAFFIC_MODE_UNICAST
  1196. );
  1197. Cfg.SetHostPriority(10);
  1198. Cfg.SetClusterModeOnStart(
  1199. NLB_EXTENDED_CLUSTER_CONFIGURATION::START_MODE_STOPPED
  1200. );
  1201. Cfg.SetRemoteControlEnabled(TRUE);
  1202. Cfg.fValidNlbCfg = TRUE;
  1203. }
  1204. display_config(L"<dummy nic:old>", &Cfg);
  1205. //
  1206. // Get all the fields and push it into NewCfg;
  1207. //
  1208. {
  1209. UINT NumNetworkAddresses = 0;
  1210. UINT NumPortRules=0;
  1211. LPWSTR *pszNetworkAddresses=NULL;
  1212. LPWSTR *pszIpAddresses=NULL;
  1213. LPWSTR *pszSubnetMasks=NULL;
  1214. LPWSTR *pszPortRules=NULL;
  1215. LPWSTR szClusterAddress = NULL;
  1216. LPWSTR szDedicatedAddress = NULL;
  1217. UINT Generation=0;
  1218. BOOL NlbBound=FALSE;
  1219. BOOL ValidNlbConfig=FALSE;
  1220. SAFEARRAY *pSA = NULL;
  1221. NLB_EXTENDED_CLUSTER_CONFIGURATION::TRAFFIC_MODE
  1222. TrafficMode=NLB_EXTENDED_CLUSTER_CONFIGURATION::TRAFFIC_MODE_UNICAST;
  1223. NLB_EXTENDED_CLUSTER_CONFIGURATION::START_MODE
  1224. StartMode=NLB_EXTENDED_CLUSTER_CONFIGURATION::START_MODE_STOPPED;
  1225. UINT HostPriority=0;
  1226. BOOL RemoteControlEnabled=FALSE;
  1227. //
  1228. // GET
  1229. //
  1230. Generation = Cfg.GetGeneration();
  1231. NlbBound = Cfg.IsNlbBound();
  1232. ValidNlbConfig = Cfg.IsValidNlbConfig();
  1233. if (cmd == DO_STRINGS)
  1234. {
  1235. Status = Cfg.GetNetworkAddresses(
  1236. &pszNetworkAddresses,
  1237. &NumNetworkAddresses
  1238. );
  1239. }
  1240. else if (cmd == DO_SAFEARRAY)
  1241. {
  1242. Status = Cfg.GetNetworkAddressesSafeArray(&pSA);
  1243. if (FAILED(Status))
  1244. {
  1245. pSA = NULL;
  1246. }
  1247. }
  1248. else if (cmd = DO_STRINGPAIR)
  1249. {
  1250. Status = Cfg.GetNetworkAddressPairs(
  1251. &pszIpAddresses, // free using delete
  1252. &pszSubnetMasks, // free using delete
  1253. &NumNetworkAddresses
  1254. );
  1255. }
  1256. Status = Cfg.GetPortRules(&pszPortRules, &NumPortRules);
  1257. Status = Cfg.GetClusterNetworkAddress(&szClusterAddress);
  1258. Status = Cfg.GetDedicatedNetworkAddress(&szDedicatedAddress);
  1259. TrafficMode = Cfg.GetTrafficMode();
  1260. HostPriority = Cfg.GetHostPriority();
  1261. StartMode = Cfg.GetClusterModeOnStart();
  1262. RemoteControlEnabled = Cfg.GetRemoteControlEnabled();
  1263. //
  1264. // SET
  1265. //
  1266. NewCfg.fValidNlbCfg = ValidNlbConfig;
  1267. NewCfg.Generation = Generation;
  1268. NewCfg.fBound = NlbBound;
  1269. if (cmd == DO_STRINGS)
  1270. {
  1271. Status = NewCfg.SetNetworkAddresses(
  1272. (LPCWSTR*) pszNetworkAddresses,
  1273. NumNetworkAddresses
  1274. );
  1275. }
  1276. else if (cmd == DO_SAFEARRAY)
  1277. {
  1278. if (pSA != NULL)
  1279. {
  1280. Status = NewCfg.SetNetworkAddressesSafeArray(pSA);
  1281. SafeArrayDestroy(pSA);
  1282. pSA = NULL;
  1283. }
  1284. }
  1285. else if (cmd = DO_STRINGPAIR)
  1286. {
  1287. Status = NewCfg.SetNetworkAddresPairs(
  1288. (LPCWSTR*) pszIpAddresses,
  1289. (LPCWSTR*) pszSubnetMasks,
  1290. NumNetworkAddresses
  1291. );
  1292. }
  1293. Status = NewCfg.SetPortRules((LPCWSTR*)pszPortRules, NumPortRules);
  1294. NewCfg.SetClusterNetworkAddress(szClusterAddress);
  1295. NewCfg.SetDedicatedNetworkAddress(szDedicatedAddress);
  1296. NewCfg.SetTrafficMode(TrafficMode);
  1297. NewCfg.SetHostPriority(HostPriority);
  1298. NewCfg.SetClusterModeOnStart(StartMode);
  1299. NewCfg.SetRemoteControlEnabled(RemoteControlEnabled);
  1300. delete (pszNetworkAddresses);
  1301. delete (pszIpAddresses);
  1302. delete (pszSubnetMasks);
  1303. delete (pszPortRules);
  1304. delete (szClusterAddress);
  1305. delete (szDedicatedAddress);
  1306. }
  1307. display_config(L"<dummy nic:new>", &NewCfg);
  1308. }
  1309. }
  1310. printf("... end test\n");
  1311. }