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.

2232 lines
63 KiB

  1. /*++
  2. Copyright(c) 2001 Microsoft Corporation
  3. Module Name:
  4. NLB Manager
  5. File Name:
  6. NlbClient.cpp
  7. Abstract:
  8. Implementation of class NLBHost
  9. NLBHost is responsible for connecting to an NLB host and getting/setting
  10. its NLB-related configuration.
  11. History:
  12. 03/31/01 JosephJ Created
  13. 07/27/01 JosephJ Moved to current location (used to be called
  14. nlbhost.cpp under provider\tests).
  15. NLB client-side WMI utility functions to configure
  16. an NLB host.
  17. --*/
  18. #include "private.h"
  19. #include "nlbclient.tmh"
  20. extern BOOL g_Silent;
  21. BOOL g_Fake; // If true, operate in "fake mode" -- see NlbHostFake()
  22. WBEMSTATUS
  23. extract_GetClusterConfiguration_output_params(
  24. IN IWbemClassObjectPtr spWbemOutput,
  25. OUT PNLB_EXTENDED_CLUSTER_CONFIGURATION pCfg
  26. );
  27. WBEMSTATUS
  28. setup_GetClusterConfiguration_input_params(
  29. IN LPCWSTR szNic,
  30. IN IWbemClassObjectPtr spWbemInput
  31. );
  32. WBEMSTATUS
  33. setup_UpdateClusterConfiguration_input_params(
  34. IN LPCWSTR szClientDescription,
  35. IN LPCWSTR szNic,
  36. IN PNLB_EXTENDED_CLUSTER_CONFIGURATION pCfg,
  37. IN IWbemClassObjectPtr spWbemInput
  38. );
  39. WBEMSTATUS
  40. connect_to_server(
  41. IN PWMI_CONNECTION_INFO pConnInfo, // NULL implies local
  42. OUT IWbemServicesPtr &spWbemService // Smart pointer
  43. );
  44. VOID
  45. NlbHostFake(
  46. VOID)
  47. /*
  48. Makes the NlbHostXXX apis operate in "fake mode", where they don't
  49. actually connect to any real machines.
  50. */
  51. {
  52. g_Fake = TRUE;
  53. FakeInitialize();
  54. }
  55. WBEMSTATUS
  56. NlbHostGetConfiguration(
  57. IN PWMI_CONNECTION_INFO pConnInfo, // NULL implies local
  58. IN LPCWSTR szNicGuid,
  59. OUT PNLB_EXTENDED_CLUSTER_CONFIGURATION pCurrentCfg
  60. )
  61. {
  62. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  63. IWbemServicesPtr spWbemService = NULL; // Smart pointer
  64. IWbemClassObjectPtr spWbemInput = NULL; // smart pointer
  65. IWbemClassObjectPtr spWbemOutput = NULL; // smart pointer.
  66. LPWSTR pRelPath = NULL;
  67. TRACE_INFO("->%!FUNC!(GUID=%ws)", szNicGuid);
  68. if (g_Fake)
  69. {
  70. Status = FakeNlbHostGetConfiguration(pConnInfo, szNicGuid, pCurrentCfg);
  71. goto end;
  72. }
  73. //
  74. // Get interface to the NLB namespace on the specified machine
  75. //
  76. Status = connect_to_server(pConnInfo, REF spWbemService);
  77. if (FAILED(Status))
  78. {
  79. goto end;
  80. }
  81. //
  82. // Get wmi input instance to "GetClusterConfiguration" method
  83. //
  84. {
  85. Status = CfgUtilGetWmiInputInstanceAndRelPath(
  86. spWbemService,
  87. L"NlbsNic", // szClassName
  88. NULL, // szParameterName
  89. NULL, // szPropertyValue
  90. L"GetClusterConfiguration", // szMethodName,
  91. spWbemInput, // smart pointer
  92. &pRelPath // free using delete
  93. );
  94. if (FAILED(Status))
  95. {
  96. wprintf(
  97. L"ERROR 0x%08lx trying to get instance of GetClusterConfiguration\n",
  98. (UINT) Status
  99. );
  100. goto end;
  101. }
  102. }
  103. //
  104. // Setup params for the "GetClusterConfiguration" method
  105. // NOTE: spWbemInput could be NULL.
  106. //
  107. Status = setup_GetClusterConfiguration_input_params(
  108. szNicGuid,
  109. spWbemInput
  110. );
  111. if (FAILED(Status))
  112. {
  113. goto end;
  114. }
  115. //
  116. // Call the "GetClusterConfiguration" method
  117. //
  118. {
  119. HRESULT hr;
  120. if (!g_Silent)
  121. {
  122. wprintf(L"Going to get GetClusterConfiguration...\n");
  123. }
  124. hr = spWbemService->ExecMethod(
  125. _bstr_t(pRelPath),
  126. L"GetClusterConfiguration",
  127. 0,
  128. NULL,
  129. spWbemInput,
  130. &spWbemOutput,
  131. NULL
  132. );
  133. if( FAILED( hr) )
  134. {
  135. wprintf(L"GetClusterConfiguration returns with failure 0x%8lx\n",
  136. (UINT) hr);
  137. Status = WBEM_E_CRITICAL_ERROR;
  138. goto end;
  139. }
  140. else
  141. {
  142. if (!g_Silent)
  143. {
  144. wprintf(L"GetClusterConfiguration returns successfully\n");
  145. }
  146. }
  147. if (spWbemOutput == NULL)
  148. {
  149. //
  150. // Hmm --- no output ?!
  151. //
  152. printf("ExecMethod GetClusterConfiguration had no output");
  153. Status = WBEM_E_NOT_FOUND;
  154. goto end;
  155. }
  156. }
  157. //
  158. // Extract params from the "GetClusterConfiguration" method
  159. //
  160. Status = extract_GetClusterConfiguration_output_params(
  161. spWbemOutput,
  162. pCurrentCfg
  163. );
  164. end:
  165. if (pRelPath != NULL)
  166. {
  167. delete pRelPath;
  168. }
  169. spWbemService = NULL; // Smart pointer
  170. spWbemInput = NULL; // smart pointer
  171. spWbemOutput = NULL; // smart pointer.
  172. TRACE_INFO("<-%!FUNC! returns 0x%08lx", Status);
  173. return Status;
  174. }
  175. WBEMSTATUS
  176. NlbHostDoUpdate(
  177. IN PWMI_CONNECTION_INFO pConnInfo, // NULL implies local
  178. IN LPCWSTR szNicGuid,
  179. IN LPCWSTR szClientDescription,
  180. IN PNLB_EXTENDED_CLUSTER_CONFIGURATION pNewState,
  181. OUT UINT *pGeneration,
  182. OUT WCHAR **ppLog // free using delete operator.
  183. )
  184. {
  185. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  186. IWbemServicesPtr spWbemService = NULL; // Smart pointer
  187. IWbemClassObjectPtr spWbemInput = NULL; // smart pointer
  188. IWbemClassObjectPtr spWbemOutput = NULL; // smart pointer.
  189. LPWSTR pRelPath = NULL;
  190. TRACE_INFO("->%!FUNC!(GUID=%ws)", szNicGuid);
  191. *pGeneration = 0;
  192. *ppLog = NULL;
  193. if (g_Fake)
  194. {
  195. Status = FakeNlbHostDoUpdate(
  196. pConnInfo,
  197. szNicGuid,
  198. szClientDescription,
  199. pNewState,
  200. pGeneration,
  201. ppLog
  202. );
  203. goto end;
  204. }
  205. //
  206. // Get interface to the NLB namespace on the specified machine
  207. //
  208. Status = connect_to_server(pConnInfo, REF spWbemService);
  209. if (FAILED(Status))
  210. {
  211. goto end;
  212. }
  213. //
  214. // Get wmi input instance to "UpdateClusterConfiguration" method
  215. //
  216. {
  217. Status = CfgUtilGetWmiInputInstanceAndRelPath(
  218. spWbemService,
  219. L"NlbsNic", // szClassName
  220. NULL, // szParameterName
  221. NULL, // szPropertyValue
  222. L"UpdateClusterConfiguration", // szMethodName,
  223. spWbemInput, // smart pointer
  224. &pRelPath // free using delete
  225. );
  226. if (FAILED(Status))
  227. {
  228. wprintf(
  229. L"ERROR 0x%08lx trying to get instance of UpdateConfiguration\n",
  230. (UINT) Status
  231. );
  232. goto end;
  233. }
  234. }
  235. //
  236. // Setup params for the "UpdateClusterConfiguration" method
  237. // NOTE: spWbemInput could be NULL.
  238. //
  239. Status = setup_UpdateClusterConfiguration_input_params(
  240. szClientDescription,
  241. szNicGuid,
  242. pNewState,
  243. spWbemInput
  244. );
  245. if (FAILED(Status))
  246. {
  247. goto end;
  248. }
  249. //
  250. // Call the "UpdateClusterConfiguration" method
  251. //
  252. {
  253. HRESULT hr;
  254. wprintf(L"Going get UpdateClusterConfiguration...\n");
  255. hr = spWbemService->ExecMethod(
  256. _bstr_t(pRelPath),
  257. L"UpdateClusterConfiguration",
  258. 0,
  259. NULL,
  260. spWbemInput,
  261. &spWbemOutput,
  262. NULL
  263. );
  264. if( FAILED( hr) )
  265. {
  266. wprintf(L"UpdateConfiguration returns with failure 0x%8lx\n",
  267. (UINT) hr);
  268. goto end;
  269. }
  270. else
  271. {
  272. wprintf(L"UpdateConfiguration returns successfully\n");
  273. }
  274. if (spWbemOutput == NULL)
  275. {
  276. //
  277. // Hmm --- no output ?!
  278. //
  279. printf("ExecMethod UpdateConfiguration had no output");
  280. Status = WBEM_E_NOT_FOUND;
  281. goto end;
  282. }
  283. }
  284. //
  285. // Extract params from the "UpdateClusterConfiguration" method
  286. //
  287. {
  288. DWORD dwReturnValue = 0;
  289. Status = CfgUtilGetWmiDWORDParam(
  290. spWbemOutput,
  291. L"ReturnValue", // <--------------------------------
  292. &dwReturnValue
  293. );
  294. if (FAILED(Status))
  295. {
  296. wprintf(L"Attempt to read ReturnValue failed. Error=0x%08lx\n",
  297. (UINT) Status);
  298. goto end;
  299. }
  300. LPWSTR szLog = NULL;
  301. Status = CfgUtilGetWmiStringParam(
  302. spWbemOutput,
  303. L"Log", // <-------------------------
  304. &szLog
  305. );
  306. if (FAILED(Status))
  307. {
  308. szLog = NULL;
  309. }
  310. *ppLog = szLog;
  311. DWORD dwGeneration = 0;
  312. Status = CfgUtilGetWmiDWORDParam(
  313. spWbemOutput,
  314. L"NewGeneration", // <--------------------------------
  315. &dwGeneration
  316. );
  317. if (FAILED(Status))
  318. {
  319. //
  320. // Generation should always be specified for pending operations.
  321. // TODO: for successful operations also?
  322. //
  323. if ((WBEMSTATUS)dwReturnValue == WBEM_S_PENDING)
  324. {
  325. wprintf(L"Attempt to read NewGeneration for pending update failed. Error=0x%08lx\n",
  326. (UINT) Status);
  327. Status = WBEM_E_CRITICAL_ERROR;
  328. goto end;
  329. }
  330. dwGeneration = 0; // we don't care if it's not set for non-pending
  331. }
  332. *pGeneration = (UINT) dwGeneration;
  333. //
  334. // Make the return status reflect the true status of the update
  335. // operation.
  336. //
  337. Status = (WBEMSTATUS) dwReturnValue;
  338. }
  339. end:
  340. if (pRelPath != NULL)
  341. {
  342. delete pRelPath;
  343. }
  344. spWbemService = NULL; // Smart pointer
  345. spWbemInput = NULL; // smart pointer
  346. spWbemOutput = NULL; // smart pointer.
  347. TRACE_INFO("<-%!FUNC! returns 0x%08lx", Status);
  348. return Status;
  349. }
  350. WBEMSTATUS
  351. NlbHostControlCluster(
  352. IN PWMI_CONNECTION_INFO pConnInfo, // NULL implies local
  353. IN LPCWSTR szNicGuid,
  354. IN LPCWSTR szVip,
  355. IN DWORD *pdwPortNum,
  356. IN WLBS_OPERATION_CODES Operation,
  357. OUT DWORD *pdwOperationStatus,
  358. OUT DWORD *pdwClusterOrPortStatus,
  359. OUT DWORD *pdwHostMap
  360. )
  361. {
  362. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  363. IWbemServicesPtr spWbemService = NULL; // Smart pointer
  364. IWbemClassObjectPtr spWbemInput = NULL; // smart pointer
  365. IWbemClassObjectPtr spWbemOutput = NULL; // smart pointer.
  366. LPWSTR pRelPath = NULL;
  367. if (szVip && pdwPortNum)
  368. TRACE_INFO("->%!FUNC!(GUID=%ws), szVip : %ls, Port : 0x%x, Operation : %d", szNicGuid, szVip, *pdwPortNum, Operation);
  369. else
  370. TRACE_INFO("->%!FUNC!(GUID=%ws), szVip : N/A, Port : N/A, Operation : %d", szNicGuid, Operation);
  371. if (g_Fake)
  372. {
  373. Status = FakeNlbHostControlCluster(
  374. pConnInfo,
  375. szNicGuid,
  376. szVip,
  377. pdwPortNum,
  378. Operation,
  379. pdwOperationStatus,
  380. pdwClusterOrPortStatus,
  381. pdwHostMap
  382. );
  383. goto end;
  384. }
  385. // Initialize return variables to failure values
  386. if (pdwOperationStatus)
  387. *pdwOperationStatus = WLBS_FAILURE;
  388. if (pdwClusterOrPortStatus)
  389. *pdwClusterOrPortStatus = WLBS_FAILURE;
  390. if (pdwHostMap)
  391. *pdwHostMap = 0;
  392. //
  393. // Get interface to the NLB namespace on the specified machine
  394. //
  395. Status = connect_to_server(pConnInfo, REF spWbemService);
  396. if (FAILED(Status))
  397. {
  398. goto end;
  399. }
  400. //
  401. // Get wmi input instance to "ControlCluster" method
  402. //
  403. {
  404. Status = CfgUtilGetWmiInputInstanceAndRelPath(
  405. spWbemService,
  406. L"NlbsNic", // szClassName
  407. NULL, // szParameterName
  408. NULL, // szPropertyValue
  409. L"ControlCluster", // szMethodName,
  410. spWbemInput, // smart pointer
  411. &pRelPath // free using delete
  412. );
  413. if (FAILED(Status))
  414. {
  415. wprintf(
  416. L"ERROR 0x%08lx trying to get instance of UpdateConfiguration\n",
  417. (UINT) Status
  418. );
  419. goto end;
  420. }
  421. }
  422. // Setup input parameters
  423. // Put in Adapter GUID
  424. Status = CfgUtilSetWmiStringParam(
  425. spWbemInput,
  426. L"AdapterGuid",
  427. szNicGuid
  428. );
  429. if (FAILED(Status))
  430. {
  431. TRACE_CRIT(L"Error trying to set Adapter GUID : %ls",szNicGuid);
  432. goto end;
  433. }
  434. // If passed, Put in Virtual IP Address
  435. // Virtual IP Address will be passed only for port operations
  436. if (szVip)
  437. {
  438. Status = CfgUtilSetWmiStringParam(
  439. spWbemInput,
  440. L"VirtualIpAddress",
  441. szVip
  442. );
  443. if (FAILED(Status))
  444. {
  445. TRACE_CRIT(L"Error trying to set Virtual IP Address : %ls",szVip);
  446. goto end;
  447. }
  448. }
  449. // If passed, Put in Port Number
  450. // Port number will be passed only for port operations
  451. if (pdwPortNum)
  452. {
  453. CfgUtilSetWmiDWORDParam(
  454. spWbemInput,
  455. L"Port",
  456. *pdwPortNum
  457. );
  458. }
  459. // Put in Operation
  460. CfgUtilSetWmiDWORDParam(
  461. spWbemInput,
  462. L"Operation",
  463. (DWORD)Operation
  464. );
  465. //
  466. // Call the "ControlCluster" method
  467. //
  468. {
  469. HRESULT hr;
  470. wprintf(L"Going get ControlCluster...\n");
  471. hr = spWbemService->ExecMethod(
  472. _bstr_t(pRelPath),
  473. L"ControlCluster",
  474. 0,
  475. NULL,
  476. spWbemInput,
  477. &spWbemOutput,
  478. NULL
  479. );
  480. if( FAILED( hr) )
  481. {
  482. wprintf(L"ControlCluster returns with failure 0x%8lx\n",
  483. (UINT) hr);
  484. goto end;
  485. }
  486. //else
  487. //{
  488. // wprintf(L"ControlCluster returns successfully\n");
  489. //}
  490. if (spWbemOutput == NULL)
  491. {
  492. //
  493. // Hmm --- no output ?!
  494. //
  495. printf("ExecMethod ControlCluster had no output");
  496. Status = WBEM_E_NOT_FOUND;
  497. goto end;
  498. }
  499. }
  500. //
  501. // Extract output params from the "ControlCluster" method
  502. //
  503. {
  504. DWORD dwTemp;
  505. // Get return value
  506. Status = CfgUtilGetWmiDWORDParam(
  507. spWbemOutput,
  508. L"ReturnValue",
  509. &dwTemp
  510. );
  511. if (FAILED(Status))
  512. {
  513. wprintf(L"Attempt to read ReturnValue failed. Error=0x%08lx\n",
  514. (UINT) Status);
  515. goto end;
  516. }
  517. else
  518. {
  519. if (pdwOperationStatus)
  520. *pdwOperationStatus = dwTemp;
  521. }
  522. // Get Cluster or Port Status
  523. Status = CfgUtilGetWmiDWORDParam(
  524. spWbemOutput,
  525. L"CurrentState",
  526. &dwTemp
  527. );
  528. if (FAILED(Status))
  529. {
  530. wprintf(L"Attempt to read CurrentState failed. Error=0x%08lx\n",
  531. (UINT) Status);
  532. goto end;
  533. }
  534. else
  535. {
  536. if (pdwClusterOrPortStatus)
  537. *pdwClusterOrPortStatus = dwTemp;
  538. }
  539. // If present, Get Host Map
  540. // For port operations, Host Map will not be returned
  541. Status = CfgUtilGetWmiDWORDParam(
  542. spWbemOutput,
  543. L"HostMap",
  544. &dwTemp
  545. );
  546. if (FAILED(Status))
  547. {
  548. if ((Operation != WLBS_PORT_ENABLE)
  549. && (Operation != WLBS_PORT_DISABLE)
  550. && (Operation != WLBS_PORT_DRAIN)
  551. && (Operation != WLBS_QUERY_PORT_STATE)
  552. )
  553. {
  554. wprintf(L"Attempt to read HostMap failed. Error=0x%08lx\n", (UINT) Status);
  555. goto end;
  556. }
  557. }
  558. else
  559. {
  560. if (pdwHostMap)
  561. *pdwHostMap = dwTemp;
  562. }
  563. Status = WBEM_NO_ERROR;
  564. }
  565. end:
  566. if (pRelPath != NULL)
  567. {
  568. delete pRelPath;
  569. }
  570. spWbemService = NULL; // Smart pointer
  571. spWbemInput = NULL; // smart pointer
  572. spWbemOutput = NULL; // smart pointer.
  573. TRACE_INFO("<-%!FUNC! returns 0x%08lx", Status);
  574. return Status;
  575. }
  576. WBEMSTATUS
  577. NlbHostGetClusterMembers(
  578. IN PWMI_CONNECTION_INFO pConnInfo,
  579. IN LPCWSTR szNicGuid,
  580. OUT DWORD *pNumMembers,
  581. OUT NLB_CLUSTER_MEMBER_INFO **ppMembers // free using delete[]
  582. )
  583. {
  584. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  585. IWbemServicesPtr spWbemService = NULL; // Smart pointer
  586. IWbemClassObjectPtr spWbemInput = NULL; // smart pointer
  587. IWbemClassObjectPtr spWbemOutput = NULL; // smart pointer.
  588. LPWSTR pRelPath = NULL;
  589. GUID AdapterGuid;
  590. DWORD dwStatus;
  591. LPWSTR *pszHostIdList = NULL;
  592. LPWSTR *pszDedicatedIpAddressList = NULL;
  593. LPWSTR *pszHostNameList = NULL;
  594. UINT NumHostIds = 0;
  595. UINT NumDips = 0;
  596. UINT NumHostNames = 0;
  597. TRACE_VERB(L"->(GUID=%ws)", szNicGuid);
  598. ASSERT (pNumMembers != NULL);
  599. ASSERT (ppMembers != NULL);
  600. *pNumMembers = 0;
  601. *ppMembers = NULL;
  602. if (g_Fake)
  603. {
  604. TRACE_INFO(L"faking call");
  605. Status = FakeNlbHostGetClusterMembers(
  606. pConnInfo,
  607. szNicGuid,
  608. pNumMembers,
  609. ppMembers
  610. );
  611. goto end;
  612. }
  613. //
  614. // Get interface to the NLB namespace on the specified machine
  615. //
  616. Status = connect_to_server(pConnInfo, REF spWbemService);
  617. if (FAILED(Status))
  618. {
  619. goto end;
  620. }
  621. //
  622. // Get wmi input instance to "ControlCluster" method
  623. //
  624. {
  625. Status = CfgUtilGetWmiInputInstanceAndRelPath(
  626. spWbemService,
  627. L"NlbsNic", // szClassName
  628. NULL, // szParameterName
  629. NULL, // szPropertyValue
  630. L"GetClusterMembers", // szMethodName,
  631. spWbemInput, // smart pointer
  632. &pRelPath // free using delete
  633. );
  634. if (FAILED(Status))
  635. {
  636. wprintf(
  637. L"ERROR 0x%08lx trying to get instance of UpdateConfiguration\n",
  638. (UINT) Status
  639. );
  640. TRACE_CRIT(L"CfgUtilGetWmiInputInstanceAndRelPath failed with status 0x%x", Status);
  641. goto end;
  642. }
  643. }
  644. //
  645. // Setup input parameters
  646. //
  647. Status = CfgUtilSetWmiStringParam(
  648. spWbemInput,
  649. L"AdapterGuid",
  650. szNicGuid
  651. );
  652. if (FAILED(Status))
  653. {
  654. TRACE_CRIT(L"Error trying to set Adapter GUID : %ls", szNicGuid);
  655. goto end;
  656. }
  657. {
  658. HRESULT hr;
  659. wprintf(L"Calling GetClusterMembers...\n");
  660. hr = spWbemService->ExecMethod(
  661. _bstr_t(pRelPath),
  662. L"GetClusterMembers",
  663. 0,
  664. NULL,
  665. spWbemInput,
  666. &spWbemOutput,
  667. NULL
  668. );
  669. if( FAILED( hr) )
  670. {
  671. wprintf(L"GetClusterMembers returns with failure 0x%8lx\n",
  672. (UINT) hr);
  673. TRACE_CRIT(L"ExecMethod (GetClusterMembers) failed with hresult 0x%x", hr);
  674. goto end;
  675. }
  676. if (spWbemOutput == NULL)
  677. {
  678. //
  679. // Hmm --- no output ?!
  680. //
  681. printf("ExecMethod GetClusterMembers had no output");
  682. Status = WBEM_E_NOT_FOUND;
  683. TRACE_CRIT(L"ExecMethod (GetClusterMembers) failed with hresult 0x%x", hr);
  684. goto end;
  685. }
  686. }
  687. //
  688. // Extract output params from the "GetClusterMembers" method
  689. //
  690. {
  691. DWORD dwTemp;
  692. // Get return value
  693. Status = CfgUtilGetWmiDWORDParam(
  694. spWbemOutput,
  695. L"ReturnValue",
  696. &dwTemp
  697. );
  698. if (FAILED(Status))
  699. {
  700. wprintf(L"Attempt to read ReturnValue failed. Error=0x%08lx\n",
  701. (UINT) Status);
  702. TRACE_CRIT(L"Attempt to read ReturnValue failed. Error=0x%08lx", (UINT) Status);
  703. goto end;
  704. }
  705. else
  706. {
  707. dwStatus = dwTemp;
  708. }
  709. if (dwStatus != WBEM_S_NO_ERROR)
  710. {
  711. TRACE_CRIT(L"GetClusterMembers failed return status = 0x%x", dwStatus);
  712. Status = WBEM_NO_ERROR;
  713. goto end;
  714. }
  715. // Get the array of host IDs
  716. Status = CfgUtilGetWmiStringArrayParam(
  717. spWbemOutput,
  718. L"HostIds",
  719. &pszHostIdList,
  720. &NumHostIds
  721. );
  722. if (FAILED(Status))
  723. {
  724. pszHostIdList = NULL;
  725. NumHostIds = 0;
  726. wprintf(L"Attempt to read HostIds failed. Error=0x%08lx\n",
  727. (UINT) Status);
  728. TRACE_CRIT(L"Attempt to read HostIds failed. Error=0x%08lx", (UINT) Status);
  729. goto end;
  730. }
  731. // Get the array of Dedicated IPs
  732. Status = CfgUtilGetWmiStringArrayParam(
  733. spWbemOutput,
  734. L"DedicatedIpAddresses",
  735. &pszDedicatedIpAddressList,
  736. &NumDips
  737. );
  738. if (FAILED(Status))
  739. {
  740. pszDedicatedIpAddressList = NULL;
  741. NumDips = 0;
  742. wprintf(L"Attempt to read DedicatedIpAddresses failed. Error=0x%08lx\n",
  743. (UINT) Status);
  744. TRACE_CRIT(L"Attempt to read DedicatedIpAddresses failed. Error=0x%08lx", (UINT) Status);
  745. goto end;
  746. }
  747. // Get the array of host IDs
  748. Status = CfgUtilGetWmiStringArrayParam(
  749. spWbemOutput,
  750. L"HostNames",
  751. &pszHostNameList,
  752. &NumHostNames
  753. );
  754. if (FAILED(Status))
  755. {
  756. pszHostNameList = NULL;
  757. NumHostNames = 0;
  758. wprintf(L"Attempt to read HostNames failed. Error=0x%08lx\n",
  759. (UINT) Status);
  760. TRACE_CRIT(L"Attempt to read HostNames failed. Error=0x%08lx", (UINT) Status);
  761. goto end;
  762. }
  763. if (NumHostIds != NumDips || NumDips != NumHostNames)
  764. {
  765. TRACE_CRIT(L"Information arrays of host information are of different lengths. NumHostIds=%d, NumDips=%d, NumHostNames=%d", NumHostIds, NumDips, NumHostNames);
  766. Status = WBEM_E_FAILED;
  767. goto end;
  768. }
  769. *ppMembers = new NLB_CLUSTER_MEMBER_INFO[NumHostIds];
  770. if (*ppMembers == NULL)
  771. {
  772. TRACE_CRIT(L"Memory allocation for NLB_CLUSTER_MEMBER_INFO array failed");
  773. Status = WBEM_E_OUT_OF_MEMORY;
  774. goto end;
  775. }
  776. *pNumMembers = NumHostIds;
  777. //
  778. // Copy the string information into buffers for output
  779. //
  780. for (int i=0; i< NumHostIds; i++)
  781. {
  782. (*ppMembers)[i].HostId = wcstoul(pszHostIdList[i], NULL, 0);
  783. wcsncpy((*ppMembers)[i].DedicatedIpAddress, pszDedicatedIpAddressList[i], WLBS_MAX_CL_IP_ADDR);
  784. (*ppMembers)[i].DedicatedIpAddress[WLBS_MAX_CL_IP_ADDR - 1] = L'\0';
  785. wcsncpy((*ppMembers)[i].HostName, pszHostNameList[i], CVY_MAX_FQDN + 1);
  786. (*ppMembers)[i].HostName[CVY_MAX_FQDN] = L'\0';
  787. }
  788. Status = WBEM_NO_ERROR;
  789. }
  790. end:
  791. if (pRelPath != NULL)
  792. {
  793. delete pRelPath;
  794. }
  795. if (pszHostIdList != NULL)
  796. {
  797. delete [] pszHostIdList;
  798. }
  799. if (pszDedicatedIpAddressList != NULL)
  800. {
  801. delete [] pszDedicatedIpAddressList;
  802. }
  803. if (pszHostNameList != NULL)
  804. {
  805. delete [] pszHostNameList;
  806. }
  807. spWbemService = NULL; // Smart pointer
  808. spWbemInput = NULL; // smart pointer
  809. spWbemOutput = NULL; // smart pointer.
  810. TRACE_VERB(L"<- returns 0x%08lx", Status);
  811. return Status;
  812. }
  813. WBEMSTATUS
  814. NlbHostGetUpdateStatus(
  815. IN PWMI_CONNECTION_INFO pConnInfo, // NULL implies local
  816. IN LPCWSTR szNicGuid,
  817. IN UINT Generation,
  818. OUT WBEMSTATUS *pCompletionStatus,
  819. OUT WCHAR **ppLog // free using delete operator.
  820. )
  821. {
  822. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  823. IWbemServicesPtr spWbemService = NULL; // Smart pointer
  824. IWbemClassObjectPtr spWbemInput = NULL; // smart pointer
  825. IWbemClassObjectPtr spWbemOutput = NULL; // smart pointer.
  826. LPWSTR pRelPath = NULL;
  827. TRACE_INFO("->%!FUNC!(GUID=%ws)", szNicGuid);
  828. *ppLog = NULL;
  829. *pCompletionStatus = WBEM_E_CRITICAL_ERROR;
  830. if (g_Fake)
  831. {
  832. Status = FakeNlbHostGetUpdateStatus(
  833. pConnInfo,
  834. szNicGuid,
  835. Generation,
  836. pCompletionStatus,
  837. ppLog
  838. );
  839. goto end;
  840. }
  841. //
  842. // Get interface to the NLB namespace on the specified machine
  843. //
  844. Status = connect_to_server(pConnInfo, REF spWbemService);
  845. if (FAILED(Status))
  846. {
  847. goto end;
  848. }
  849. //
  850. // Get wmi input instance to "QueryConfigurationUpdateStatus" method
  851. //
  852. {
  853. Status = CfgUtilGetWmiInputInstanceAndRelPath(
  854. spWbemService,
  855. L"NlbsNic", // szClassName
  856. NULL, // szParameterName
  857. NULL, // szPropertyValue
  858. L"QueryConfigurationUpdateStatus", // szMethodName,
  859. spWbemInput, // smart pointer
  860. &pRelPath // free using delete
  861. );
  862. if (FAILED(Status))
  863. {
  864. wprintf(
  865. L"ERROR 0x%08lx trying to find instance to QueryUpdateStatus\n",
  866. (UINT) Status
  867. );
  868. goto end;
  869. }
  870. }
  871. //
  872. // Setup params for the "QueryConfigurationUpdateStatus" method
  873. // NOTE: spWbemInput could be NULL.
  874. //
  875. {
  876. Status = CfgUtilSetWmiStringParam(
  877. spWbemInput,
  878. L"AdapterGuid",
  879. szNicGuid
  880. );
  881. if (FAILED(Status))
  882. {
  883. wprintf(
  884. L"Couldn't set Adapter GUID parameter to QueryUpdateStatus\n");
  885. goto end;
  886. }
  887. Status = CfgUtilSetWmiDWORDParam(
  888. spWbemInput,
  889. L"Generation",
  890. Generation
  891. );
  892. if (FAILED(Status))
  893. {
  894. wprintf(
  895. L"Couldn't set Generation parameter to QueryUpdateStatus\n");
  896. goto end;
  897. }
  898. }
  899. //
  900. // Call the "QueryConfigurationUpdateStatus" method
  901. //
  902. {
  903. HRESULT hr;
  904. // wprintf(L"Going call QueryConfigurationUpdateStatus...\n");
  905. hr = spWbemService->ExecMethod(
  906. _bstr_t(pRelPath),
  907. L"QueryConfigurationUpdateStatus", // szMethodName,
  908. 0,
  909. NULL,
  910. spWbemInput,
  911. &spWbemOutput,
  912. NULL
  913. );
  914. if( FAILED( hr) )
  915. {
  916. wprintf(L"QueryConfigurationUpdateStatus returns with failure 0x%8lx\n",
  917. (UINT) hr);
  918. goto end;
  919. }
  920. else
  921. {
  922. // wprintf(L"QueryConfigurationUpdateStatus returns successfully\n");
  923. }
  924. if (spWbemOutput == NULL)
  925. {
  926. //
  927. // Hmm --- no output ?!
  928. //
  929. printf("ExecMethod QueryConfigurationUpdateStatus had no output");
  930. Status = WBEM_E_NOT_FOUND;
  931. goto end;
  932. }
  933. }
  934. //
  935. // Extract output params --- return code and log.
  936. //
  937. {
  938. DWORD dwReturnValue = 0;
  939. Status = CfgUtilGetWmiDWORDParam(
  940. spWbemOutput,
  941. L"ReturnValue", // <--------------------------------
  942. &dwReturnValue
  943. );
  944. if (FAILED(Status))
  945. {
  946. wprintf(L"Attempt to read ReturnValue failed. Error=0x%08lx\n",
  947. (UINT) Status);
  948. goto end;
  949. }
  950. *pCompletionStatus = (WBEMSTATUS) dwReturnValue;
  951. LPWSTR szLog = NULL;
  952. Status = CfgUtilGetWmiStringParam(
  953. spWbemOutput,
  954. L"Log", // <-------------------------
  955. &szLog
  956. );
  957. if (FAILED(Status))
  958. {
  959. szLog = NULL;
  960. }
  961. *ppLog = szLog;
  962. ASSERT(Status != WBEM_S_PENDING);
  963. }
  964. end:
  965. if (pRelPath != NULL)
  966. {
  967. delete pRelPath;
  968. }
  969. spWbemService = NULL; // Smart pointer
  970. spWbemInput = NULL; // smart pointer
  971. spWbemOutput = NULL; // smart pointer.
  972. TRACE_INFO("<-%!FUNC! returns 0x%08lx", Status);
  973. return Status;
  974. }
  975. WBEMSTATUS
  976. NlbHostPing(
  977. LPCWSTR szBindString,
  978. UINT Timeout, // In milliseconds.
  979. OUT ULONG *pResolvedIpAddress // in network byte order.
  980. )
  981. {
  982. WBEMSTATUS Status = WBEM_E_INVALID_PARAMETER;
  983. TRACE_INFO("->%!FUNC!(GUID=%ws)", szBindString);
  984. if (g_Fake)
  985. {
  986. Status = FakeNlbHostPing(szBindString, Timeout, pResolvedIpAddress);
  987. }
  988. else
  989. {
  990. Status = CfgUtilPing(szBindString, Timeout, pResolvedIpAddress);
  991. }
  992. TRACE_INFO("<-%!FUNC! returns 0x%08lx", Status);
  993. return Status;
  994. }
  995. WBEMSTATUS
  996. setup_GetClusterConfiguration_input_params(
  997. IN LPCWSTR szNic,
  998. IN IWbemClassObjectPtr spWbemInput
  999. )
  1000. /*
  1001. Setup the input wmi parameters for the GetClusterConfiguration method
  1002. */
  1003. {
  1004. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  1005. Status = CfgUtilSetWmiStringParam(
  1006. spWbemInput,
  1007. L"AdapterGuid",
  1008. szNic
  1009. );
  1010. return Status;
  1011. }
  1012. WBEMSTATUS
  1013. extract_GetClusterConfiguration_output_params(
  1014. IN IWbemClassObjectPtr spWbemOutput,
  1015. OUT PNLB_EXTENDED_CLUSTER_CONFIGURATION pCfg
  1016. )
  1017. {
  1018. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  1019. DWORD Generation = 0;
  1020. BOOL NlbBound = FALSE;
  1021. BOOL fDHCPEnabled = FALSE;
  1022. LPWSTR *pszNetworkAddresses= NULL;
  1023. UINT NumNetworkAddresses = 0;
  1024. BOOL ValidNlbCfg = FALSE;
  1025. LPWSTR szFriendlyName = NULL;
  1026. LPWSTR szClusterName = NULL;
  1027. LPWSTR szClusterNetworkAddress = NULL;
  1028. LPWSTR szTrafficMode = NULL;
  1029. NLB_EXTENDED_CLUSTER_CONFIGURATION::TRAFFIC_MODE
  1030. TrafficMode
  1031. = NLB_EXTENDED_CLUSTER_CONFIGURATION::TRAFFIC_MODE_UNICAST;
  1032. LPWSTR *pszPortRules = NULL;
  1033. UINT NumPortRules = 0;
  1034. DWORD HostPriority = 0;
  1035. LPWSTR szDedicatedNetworkAddress = NULL;
  1036. /*
  1037. NLB_EXTENDED_CLUSTER_CONFIGURATION::START_MODE
  1038. ClusterModeOnStart
  1039. = NLB_EXTENDED_CLUSTER_CONFIGURATION::START_MODE_STOPPED;
  1040. */
  1041. DWORD ClusterModeOnStart = CVY_HOST_STATE_STOPPED;
  1042. BOOL bPersistSuspendOnReboot = FALSE;
  1043. BOOL RemoteControlEnabled= FALSE;
  1044. DWORD dwHashedRemoteControlPassword = 0;
  1045. pCfg->Clear();
  1046. Status = CfgUtilGetWmiStringParam(
  1047. spWbemOutput,
  1048. L"FriendlyName", // <-------------------------
  1049. &szFriendlyName
  1050. );
  1051. if (FAILED(Status))
  1052. {
  1053. wprintf(L"Attempt to read Friendly Name failed. Error=0x%08lx\n",
  1054. (UINT) Status);
  1055. szFriendlyName = NULL;
  1056. // We don't treat this as a fatal error ...
  1057. }
  1058. Status = CfgUtilGetWmiDWORDParam(
  1059. spWbemOutput,
  1060. L"Generation", // <--------------------------------
  1061. &Generation
  1062. );
  1063. if (FAILED(Status))
  1064. {
  1065. wprintf(L"Attempt to read Generation failed. Error=0x%08lx\n",
  1066. (UINT) Status);
  1067. goto end;
  1068. }
  1069. Status = CfgUtilGetWmiStringArrayParam(
  1070. spWbemOutput,
  1071. L"NetworkAddresses", // <--------------------------------
  1072. &pszNetworkAddresses,
  1073. &NumNetworkAddresses
  1074. );
  1075. if (FAILED(Status))
  1076. {
  1077. wprintf(L"Attempt to read Network addresses failed. Error=0x%08lx\n",
  1078. (UINT) Status);
  1079. goto end;
  1080. }
  1081. Status = CfgUtilGetWmiBoolParam(
  1082. spWbemOutput,
  1083. L"DHCPEnabled", // <--------------------------------
  1084. &fDHCPEnabled
  1085. );
  1086. if (FAILED(Status))
  1087. {
  1088. fDHCPEnabled = FALSE;
  1089. }
  1090. Status = CfgUtilGetWmiBoolParam(
  1091. spWbemOutput,
  1092. L"NLBBound", // <--------------------------------
  1093. &NlbBound
  1094. );
  1095. if (FAILED(Status))
  1096. {
  1097. wprintf(L"Attempt to read NLBBound failed. Error=0x%08lx\n",
  1098. (UINT) Status);
  1099. goto end;
  1100. }
  1101. do // while false -- just to allow us to break out
  1102. {
  1103. ValidNlbCfg = FALSE;
  1104. if (!NlbBound)
  1105. {
  1106. if (!g_Silent)
  1107. {
  1108. wprintf(L"NLB is UNBOUND\n");
  1109. }
  1110. break;
  1111. }
  1112. Status = CfgUtilGetWmiStringParam(
  1113. spWbemOutput,
  1114. L"ClusterNetworkAddress", // <-------------------------
  1115. &szClusterNetworkAddress
  1116. );
  1117. if (FAILED(Status))
  1118. {
  1119. wprintf(L"Attempt to read Cluster IP failed. Error=0x%08lx\n",
  1120. (UINT) Status);
  1121. break;
  1122. }
  1123. if (!g_Silent)
  1124. {
  1125. wprintf(L"NLB is BOUND, and the cluster address is %ws\n",
  1126. szClusterNetworkAddress);
  1127. }
  1128. Status = CfgUtilGetWmiStringParam(
  1129. spWbemOutput,
  1130. L"ClusterName", // <-------------------------
  1131. &szClusterName
  1132. );
  1133. if (FAILED(Status))
  1134. {
  1135. wprintf(L"Attempt to read Cluster Name failed. Error=0x%08lx\n",
  1136. (UINT) Status);
  1137. break;
  1138. }
  1139. //
  1140. // Traffic mode
  1141. //
  1142. {
  1143. Status = CfgUtilGetWmiStringParam(
  1144. spWbemOutput,
  1145. L"TrafficMode", // <-------------------------
  1146. &szTrafficMode
  1147. );
  1148. if (FAILED(Status))
  1149. {
  1150. wprintf(L"Attempt to read Traffic Mode failed. Error=0x%08lx\n",
  1151. (UINT) Status);
  1152. break;
  1153. }
  1154. if (!_wcsicmp(szTrafficMode, L"UNICAST"))
  1155. {
  1156. TrafficMode =
  1157. NLB_EXTENDED_CLUSTER_CONFIGURATION::TRAFFIC_MODE_UNICAST;
  1158. }
  1159. else if (!_wcsicmp(szTrafficMode, L"MULTICAST"))
  1160. {
  1161. TrafficMode =
  1162. NLB_EXTENDED_CLUSTER_CONFIGURATION::TRAFFIC_MODE_MULTICAST;
  1163. }
  1164. else if (!_wcsicmp(szTrafficMode, L"IGMPMULTICAST"))
  1165. {
  1166. TrafficMode =
  1167. NLB_EXTENDED_CLUSTER_CONFIGURATION::TRAFFIC_MODE_IGMPMULTICAST;
  1168. }
  1169. }
  1170. // [OUT] String PortRules[],
  1171. Status = CfgUtilGetWmiStringArrayParam(
  1172. spWbemOutput,
  1173. L"PortRules", // <--------------------------------
  1174. &pszPortRules,
  1175. &NumPortRules
  1176. );
  1177. if (FAILED(Status))
  1178. {
  1179. wprintf(L"Attempt to read port rules failed. Error=0x%08lx\n",
  1180. (UINT) Status);
  1181. goto end;
  1182. }
  1183. Status = CfgUtilGetWmiDWORDParam(
  1184. spWbemOutput,
  1185. L"HostPriority", // <--------------------------------
  1186. &HostPriority
  1187. );
  1188. if (FAILED(Status))
  1189. {
  1190. wprintf(L"Attempt to read HostPriority failed. Error=0x%08lx\n",
  1191. (UINT) Status);
  1192. break;
  1193. }
  1194. Status = CfgUtilGetWmiStringParam(
  1195. spWbemOutput,
  1196. L"DedicatedNetworkAddress", // <-------------------------
  1197. &szDedicatedNetworkAddress
  1198. );
  1199. if (FAILED(Status))
  1200. {
  1201. wprintf(L"Attempt to read dedicated IP failed. Error=0x%08lx\n",
  1202. (UINT) Status);
  1203. break;
  1204. }
  1205. //
  1206. // StartMode
  1207. //
  1208. {
  1209. /*
  1210. BOOL StartMode = FALSE;
  1211. Status = CfgUtilGetWmiBoolParam(
  1212. spWbemOutput,
  1213. L"ClusterModeOnStart", // <-------------------------
  1214. &StartMode
  1215. );
  1216. if (FAILED(Status))
  1217. {
  1218. wprintf(L"Attempt to read ClusterModeOnStart failed. Error=0x%08lx\n",
  1219. (UINT) Status);
  1220. break;
  1221. }
  1222. if (StartMode)
  1223. {
  1224. ClusterModeOnStart =
  1225. NLB_EXTENDED_CLUSTER_CONFIGURATION::START_MODE_STARTED;
  1226. }
  1227. else
  1228. {
  1229. ClusterModeOnStart =
  1230. NLB_EXTENDED_CLUSTER_CONFIGURATION::START_MODE_STOPPED;
  1231. }
  1232. */
  1233. Status = CfgUtilGetWmiDWORDParam(
  1234. spWbemOutput,
  1235. L"ClusterModeOnStart", // <--------------------------------
  1236. &ClusterModeOnStart
  1237. );
  1238. if (FAILED(Status))
  1239. {
  1240. wprintf(L"Attempt to read ClusterModeOnStart failed. Error=0x%08lx\n",
  1241. (UINT) Status);
  1242. break;
  1243. }
  1244. }
  1245. Status = CfgUtilGetWmiBoolParam(
  1246. spWbemOutput,
  1247. L"PersistSuspendOnReboot", // <----------------------------
  1248. &bPersistSuspendOnReboot
  1249. );
  1250. if (FAILED(Status))
  1251. {
  1252. wprintf(L"Attempt to read PersistSuspendOnReboot failed. Error=0x%08lx\n",
  1253. (UINT) Status);
  1254. break;
  1255. }
  1256. Status = CfgUtilGetWmiBoolParam(
  1257. spWbemOutput,
  1258. L"RemoteControlEnabled", // <----------------------------
  1259. &RemoteControlEnabled
  1260. );
  1261. if (FAILED(Status))
  1262. {
  1263. wprintf(L"Attempt to read RemoteControlEnabled failed. Error=0x%08lx\n",
  1264. (UINT) Status);
  1265. break;
  1266. }
  1267. Status = CfgUtilGetWmiDWORDParam(
  1268. spWbemOutput,
  1269. L"HashedRemoteControlPassword", // <-----------
  1270. &dwHashedRemoteControlPassword
  1271. );
  1272. if (FAILED(Status))
  1273. {
  1274. wprintf(L"Attempt to read dwHashedRemoteControlPassword failed. Error=0x%08lx\n",
  1275. (UINT) Status);
  1276. //
  1277. // we set this to 0 on failure, but go on.
  1278. //
  1279. dwHashedRemoteControlPassword = 0;
  1280. }
  1281. ValidNlbCfg = TRUE;
  1282. } while (FALSE) ;
  1283. //
  1284. // Now let's set all the the parameters in Cfg
  1285. //
  1286. {
  1287. (VOID) pCfg->SetFriendlyName(szFriendlyName); // OK if szFriendlyName is NULL.
  1288. pCfg->Generation = Generation;
  1289. pCfg->fDHCP = fDHCPEnabled;
  1290. pCfg->fBound = NlbBound;
  1291. Status = pCfg->SetNetworkAddresses(
  1292. (LPCWSTR*) pszNetworkAddresses,
  1293. NumNetworkAddresses
  1294. );
  1295. if (FAILED(Status))
  1296. {
  1297. wprintf(L"Attempt to set NetworkAddresses failed. Error=0x%08lx\n",
  1298. (UINT) Status);
  1299. goto end;
  1300. }
  1301. pCfg->fValidNlbCfg = ValidNlbCfg;
  1302. pCfg->SetClusterName(szClusterName);
  1303. pCfg->SetClusterNetworkAddress(szClusterNetworkAddress);
  1304. pCfg->SetTrafficMode(TrafficMode);
  1305. Status = pCfg->SetPortRules((LPCWSTR*)pszPortRules, NumPortRules);
  1306. // Status = WBEM_NO_ERROR; // TODO -- change once port rules is done
  1307. if (FAILED(Status))
  1308. {
  1309. wprintf(L"Attempt to set PortRules failed. Error=0x%08lx\n",
  1310. (UINT) Status);
  1311. goto end;
  1312. }
  1313. pCfg->SetHostPriority(HostPriority);
  1314. pCfg->SetDedicatedNetworkAddress(szDedicatedNetworkAddress);
  1315. pCfg->SetClusterModeOnStart(ClusterModeOnStart);
  1316. pCfg->SetPersistSuspendOnReboot(bPersistSuspendOnReboot);
  1317. pCfg->SetRemoteControlEnabled(RemoteControlEnabled);
  1318. CfgUtilSetHashedRemoteControlPassword(
  1319. &pCfg->NlbParams,
  1320. dwHashedRemoteControlPassword
  1321. );
  1322. }
  1323. end:
  1324. delete szClusterNetworkAddress;
  1325. delete pszNetworkAddresses;
  1326. delete szFriendlyName;
  1327. delete szClusterName;
  1328. delete szTrafficMode;
  1329. delete pszPortRules;
  1330. delete szDedicatedNetworkAddress;
  1331. return Status;
  1332. }
  1333. WBEMSTATUS
  1334. setup_UpdateClusterConfiguration_input_params(
  1335. IN LPCWSTR szClientDescription,
  1336. IN LPCWSTR szNic,
  1337. IN PNLB_EXTENDED_CLUSTER_CONFIGURATION pCfg,
  1338. IN IWbemClassObjectPtr spWbemInput
  1339. )
  1340. /*
  1341. Setup the input wmi parameters for the UpdateGetClusterConfiguration method
  1342. [IN] String ClientDescription,
  1343. [IN] String AdapterGuid,
  1344. [IN] uint32 Generation,
  1345. [IN] Boolean PartialUpdate,
  1346. [IN] Boolean AddDedicatedIp,
  1347. [IN] Boolean AddClusterIps,
  1348. [IN] Boolean CheckForAddressConflicts,
  1349. [IN] String NetworkAddresses[], // "10.1.1.1/255.255.255.255"
  1350. [IN] Boolean NLBBound,
  1351. [IN] String ClusterNetworkAddress, // "10.1.1.1/255.0.0.0"
  1352. [IN] String ClusterName,
  1353. [IN] String TrafficMode, // UNICAST MULTICAST IGMPMULTICAST
  1354. [IN] String PortRules[],
  1355. [IN] uint32 HostPriority,
  1356. [IN] String DedicatedNetworkAddress, // "10.1.1.1/255.0.0.0"
  1357. [IN] uint32 ClusterModeOnStart, // 0 : STOPPED, 1 : STARTED, 2 : SUSPENDED
  1358. [IN] Boolean PersistSuspendOnReboot,
  1359. [IN] Boolean RemoteControlEnabled,
  1360. [IN] String RemoteControlPassword,
  1361. [IN] uint32 HashedRemoteControlPassword,
  1362. */
  1363. {
  1364. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  1365. (VOID) CfgUtilSetWmiStringParam(
  1366. spWbemInput,
  1367. L"ClientDescription",
  1368. szClientDescription
  1369. );
  1370. Status = CfgUtilSetWmiStringParam(
  1371. spWbemInput,
  1372. L"AdapterGuid",
  1373. szNic
  1374. );
  1375. if (FAILED(Status))
  1376. {
  1377. printf(
  1378. "Setup update params: Couldn't set adapter GUID"
  1379. " for NIC %ws\n",
  1380. szNic
  1381. );
  1382. goto end;
  1383. }
  1384. //
  1385. // Fill in NetworkAddresses[]
  1386. //
  1387. {
  1388. LPWSTR *pszAddresses = NULL;
  1389. UINT NumAddresses = 0;
  1390. Status = pCfg->GetNetworkAddresses(
  1391. &pszAddresses,
  1392. &NumAddresses
  1393. );
  1394. if (FAILED(Status))
  1395. {
  1396. printf(
  1397. "Setup update params: couldn't extract network addresses from Cfg"
  1398. " for NIC %ws\n",
  1399. szNic
  1400. );
  1401. goto end;
  1402. }
  1403. //
  1404. // Note it's ok to not specify any IP addresses -- in which case
  1405. // the default ip addresses will be set up.
  1406. //
  1407. if (pszAddresses != NULL)
  1408. {
  1409. Status = CfgUtilSetWmiStringArrayParam(
  1410. spWbemInput,
  1411. L"NetworkAddresses",
  1412. (LPCWSTR *)pszAddresses,
  1413. NumAddresses
  1414. );
  1415. delete pszAddresses;
  1416. pszAddresses = NULL;
  1417. }
  1418. }
  1419. if (!pCfg->IsNlbBound())
  1420. {
  1421. //
  1422. // NLB is not bound
  1423. //
  1424. Status = CfgUtilSetWmiBoolParam(spWbemInput, L"NLBBound", FALSE);
  1425. goto end;
  1426. }
  1427. else if (!pCfg->IsValidNlbConfig())
  1428. {
  1429. printf(
  1430. "Setup update params: NLB-specific configuration on NIC %ws is invalid\n",
  1431. szNic
  1432. );
  1433. Status = WBEM_E_INVALID_PARAMETER;
  1434. goto end;
  1435. }
  1436. Status = CfgUtilSetWmiBoolParam(spWbemInput, L"NLBBound", TRUE);
  1437. if (FAILED(Status))
  1438. {
  1439. printf("Error trying to set NLBBound parameter\n");
  1440. goto end;
  1441. }
  1442. //
  1443. // NLB is bound
  1444. //
  1445. Status = CfgUtilSetWmiBoolParam(spWbemInput, L"AddDedicatedIp",
  1446. pCfg->fAddDedicatedIp);
  1447. if (FAILED(Status)) goto end;
  1448. Status = CfgUtilSetWmiBoolParam(spWbemInput, L"AddClusterIps",
  1449. pCfg->fAddClusterIps);
  1450. if (FAILED(Status)) goto end;
  1451. Status = CfgUtilSetWmiBoolParam(spWbemInput, L"CheckForAddressConflicts",
  1452. pCfg->fCheckForAddressConflicts);
  1453. if (FAILED(Status)) goto end;
  1454. //
  1455. // Cluster name
  1456. //
  1457. {
  1458. LPWSTR szName = NULL;
  1459. Status = pCfg->GetClusterName(&szName);
  1460. if (FAILED(Status))
  1461. {
  1462. printf(
  1463. "Setup update params: Could not extract cluster name for NIC %ws\n",
  1464. szNic
  1465. );
  1466. goto end;
  1467. }
  1468. CfgUtilSetWmiStringParam(spWbemInput, L"ClusterName", szName);
  1469. delete (szName);
  1470. szName = NULL;
  1471. }
  1472. //
  1473. // Cluster and dedicated network addresses
  1474. //
  1475. {
  1476. LPWSTR szAddress = NULL;
  1477. Status = pCfg->GetClusterNetworkAddress(&szAddress);
  1478. if (FAILED(Status))
  1479. {
  1480. printf(
  1481. "Setup update params: Could not extract cluster address for NIC %ws\n",
  1482. szNic
  1483. );
  1484. goto end;
  1485. }
  1486. CfgUtilSetWmiStringParam(
  1487. spWbemInput,
  1488. L"ClusterNetworkAddress",
  1489. szAddress
  1490. );
  1491. delete (szAddress);
  1492. szAddress = NULL;
  1493. Status = pCfg->GetDedicatedNetworkAddress(&szAddress);
  1494. if (FAILED(Status))
  1495. {
  1496. printf(
  1497. "Setup update params: Could not extract dedicated address for NIC %ws\n",
  1498. szNic
  1499. );
  1500. goto end;
  1501. }
  1502. CfgUtilSetWmiStringParam(
  1503. spWbemInput,
  1504. L"DedicatedNetworkAddress",
  1505. szAddress
  1506. );
  1507. delete (szAddress);
  1508. szAddress = NULL;
  1509. }
  1510. //
  1511. // TrafficMode
  1512. //
  1513. {
  1514. LPCWSTR szMode = NULL;
  1515. switch(pCfg->GetTrafficMode())
  1516. {
  1517. case NLB_EXTENDED_CLUSTER_CONFIGURATION::TRAFFIC_MODE_UNICAST:
  1518. szMode = L"UNICAST";
  1519. break;
  1520. case NLB_EXTENDED_CLUSTER_CONFIGURATION::TRAFFIC_MODE_MULTICAST:
  1521. szMode = L"MULTICAST";
  1522. break;
  1523. case NLB_EXTENDED_CLUSTER_CONFIGURATION::TRAFFIC_MODE_IGMPMULTICAST:
  1524. szMode = L"IGMPMULTICAST";
  1525. break;
  1526. default:
  1527. assert(FALSE);
  1528. Status = WBEM_E_CRITICAL_ERROR;
  1529. goto end;
  1530. }
  1531. CfgUtilSetWmiStringParam(spWbemInput, L"TrafficMode", szMode);
  1532. }
  1533. CfgUtilSetWmiDWORDParam(
  1534. spWbemInput,
  1535. L"HostPriority",
  1536. pCfg->GetHostPriority()
  1537. );
  1538. /*
  1539. if (pCfg->GetClusterModeOnStart() ==
  1540. NLB_EXTENDED_CLUSTER_CONFIGURATION::START_MODE_STARTED)
  1541. {
  1542. CfgUtilSetWmiBoolParam(spWbemInput, L"ClusterModeOnStart", TRUE);
  1543. }
  1544. else
  1545. {
  1546. CfgUtilSetWmiBoolParam(spWbemInput, L"ClusterModeOnStart", FALSE);
  1547. }
  1548. */
  1549. CfgUtilSetWmiDWORDParam(
  1550. spWbemInput,
  1551. L"ClusterModeOnStart",
  1552. pCfg->GetClusterModeOnStart()
  1553. );
  1554. CfgUtilSetWmiBoolParam(
  1555. spWbemInput,
  1556. L"PersistSuspendOnReboot",
  1557. pCfg->GetPersistSuspendOnReboot()
  1558. );
  1559. CfgUtilSetWmiBoolParam(
  1560. spWbemInput,
  1561. L"RemoteControlEnabled",
  1562. pCfg->GetRemoteControlEnabled()
  1563. );
  1564. //
  1565. // Set the new password or hashed-password params, if specified.
  1566. //
  1567. {
  1568. // String RemoteControlPassword,
  1569. LPCWSTR szPwd = NULL;
  1570. szPwd = pCfg->GetNewRemoteControlPasswordRaw();
  1571. if (szPwd != NULL)
  1572. {
  1573. CfgUtilSetWmiStringParam(
  1574. spWbemInput,
  1575. L"RemoteControlPassword",
  1576. szPwd
  1577. );
  1578. }
  1579. else // only set the hashed pwd if szPwd is not specified.
  1580. {
  1581. DWORD dwHashedRemoteControlPassword;
  1582. BOOL fRet = FALSE;
  1583. fRet = pCfg->GetNewHashedRemoteControlPassword(
  1584. dwHashedRemoteControlPassword
  1585. );
  1586. if (fRet)
  1587. {
  1588. CfgUtilSetWmiDWORDParam(
  1589. spWbemInput,
  1590. L"HashedRemoteControlPassword",
  1591. dwHashedRemoteControlPassword
  1592. );
  1593. }
  1594. }
  1595. }
  1596. //
  1597. // String PortRules[],
  1598. //
  1599. {
  1600. LPWSTR *pszPortRules = NULL;
  1601. UINT NumPortRules = 0;
  1602. Status = pCfg->GetPortRules(
  1603. &pszPortRules,
  1604. &NumPortRules
  1605. );
  1606. if (FAILED(Status))
  1607. {
  1608. printf(
  1609. "Setup update params: couldn't extract port rules from Cfg"
  1610. " for NIC %ws\n",
  1611. szNic
  1612. );
  1613. goto end;
  1614. }
  1615. if (NumPortRules != 0)
  1616. {
  1617. Status = CfgUtilSetWmiStringArrayParam(
  1618. spWbemInput,
  1619. L"PortRules",
  1620. (LPCWSTR *)pszPortRules,
  1621. NumPortRules
  1622. );
  1623. delete pszPortRules;
  1624. pszPortRules = NULL;
  1625. }
  1626. }
  1627. Status = WBEM_NO_ERROR;
  1628. end:
  1629. wprintf(L"<-Setup update params returns 0x%08lx\n", (UINT) Status);
  1630. return Status;
  1631. }
  1632. WBEMSTATUS
  1633. NlbHostGetCompatibleNics(
  1634. PWMI_CONNECTION_INFO pConnInfo, // NULL implies local
  1635. OUT LPWSTR **ppszNics, // free using delete
  1636. OUT UINT *pNumNics, // free using delete
  1637. OUT UINT *pNumBoundToNlb
  1638. )
  1639. {
  1640. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  1641. IWbemServicesPtr spWbemService = NULL; // Smart pointer
  1642. IWbemClassObjectPtr spWbemInput = NULL; // smart pointer
  1643. IWbemClassObjectPtr spWbemOutput = NULL; // smart pointer.
  1644. LPWSTR pRelPath = NULL;
  1645. LPWSTR *pszNicList = NULL;
  1646. UINT NumNics = 0;
  1647. DWORD NumBoundToNlb = 0;
  1648. if (pConnInfo!=NULL)
  1649. {
  1650. TRACE_INFO("->%!FUNC!(Machine=%ws)", pConnInfo->szMachine);
  1651. }
  1652. else
  1653. {
  1654. TRACE_INFO("->%!FUNC! (Machine=<NULL>)");
  1655. }
  1656. if (g_Fake)
  1657. {
  1658. Status = FakeNlbHostGetCompatibleNics(
  1659. pConnInfo,
  1660. ppszNics,
  1661. pNumNics,
  1662. pNumBoundToNlb
  1663. );
  1664. goto end_fake;
  1665. }
  1666. *ppszNics = NULL;
  1667. *pNumNics = NULL;
  1668. *pNumBoundToNlb = NULL;
  1669. //
  1670. // Get interface to the NLB namespace on the specified machine
  1671. //
  1672. Status = connect_to_server(pConnInfo, REF spWbemService);
  1673. if (FAILED(Status))
  1674. {
  1675. goto end;
  1676. }
  1677. //
  1678. // Get wmi input instance to "GetCompatibleAdapterGuids" method
  1679. //
  1680. {
  1681. Status = CfgUtilGetWmiInputInstanceAndRelPath(
  1682. spWbemService,
  1683. L"NlbsNic", // szClassName
  1684. NULL, // L"AdapterGuid", // szParameterName
  1685. NULL, // szNicGuid, // szPropertyValue
  1686. L"GetCompatibleAdapterGuids", // szMethodName,
  1687. spWbemInput, // smart pointer
  1688. &pRelPath // free using delete
  1689. );
  1690. if (FAILED(Status))
  1691. {
  1692. TRACE_CRIT(
  1693. L"%!FUNC! ERROR 0x%08lx trying to get instance of GetCompatibleAdapterGuids",
  1694. (UINT) Status
  1695. );
  1696. goto end;
  1697. }
  1698. }
  1699. //
  1700. // Setup params for the "GetClusterConfiguration" method
  1701. // NOTE: spWbemInput could be NULL.
  1702. //
  1703. {
  1704. // NOTHING TO DO HERE -- no input params...
  1705. }
  1706. //
  1707. // Call the "GetCompatibleAdapterGuids" method
  1708. //
  1709. {
  1710. HRESULT hr;
  1711. TRACE_VERB(L"%!FUNC! Going get GetCompatibleAdapterGuids...");
  1712. hr = spWbemService->ExecMethod(
  1713. _bstr_t(pRelPath),
  1714. L"GetCompatibleAdapterGuids",
  1715. 0,
  1716. NULL,
  1717. spWbemInput,
  1718. &spWbemOutput,
  1719. NULL
  1720. );
  1721. if( FAILED( hr) )
  1722. {
  1723. TRACE_CRIT(L"%!FUNC! GetCompatibleAdapterGuids returns with failure 0x%8lx",
  1724. (UINT) hr);
  1725. Status = WBEM_E_CRITICAL_ERROR;
  1726. goto end;
  1727. }
  1728. else
  1729. {
  1730. TRACE_VERB(L"GetCompatibleAdapterGuids returns successfully");
  1731. }
  1732. if (spWbemOutput == NULL)
  1733. {
  1734. //
  1735. // Hmm --- no output ?!
  1736. //
  1737. TRACE_CRIT("%!FUNC! ExecMethod GetCompatibleAdapterGuids had no output");
  1738. Status = WBEM_E_NOT_FOUND;
  1739. goto end;
  1740. }
  1741. }
  1742. //
  1743. // Extract params from the method
  1744. //
  1745. // [OUT] String AdapterGuids[],
  1746. // [OUT] uint32 NumBoundToNlb
  1747. //
  1748. Status = CfgUtilGetWmiDWORDParam(
  1749. spWbemOutput,
  1750. L"NumBoundToNlb", // <--------------------------------
  1751. &NumBoundToNlb
  1752. );
  1753. if (FAILED(Status))
  1754. {
  1755. TRACE_CRIT(L"Attempt to read NumBoundToNlb failed. Error=0x%08lx\n",
  1756. (UINT) Status);
  1757. NumBoundToNlb = 0;
  1758. goto end;
  1759. }
  1760. Status = CfgUtilGetWmiStringArrayParam(
  1761. spWbemOutput,
  1762. L"AdapterGuids", // <--------------------------------
  1763. &pszNicList,
  1764. &NumNics
  1765. );
  1766. if (FAILED(Status))
  1767. {
  1768. TRACE_CRIT(L"%!FUNC! Attempt to read Adapter Guids failed. Error=0x%08lx",
  1769. (UINT) Status);
  1770. pszNicList = NULL;
  1771. NumNics = 0;
  1772. goto end;
  1773. }
  1774. end:
  1775. if (!FAILED(Status))
  1776. {
  1777. *ppszNics = pszNicList;
  1778. pszNicList = NULL;
  1779. *pNumNics = NumNics;
  1780. *pNumBoundToNlb = NumBoundToNlb;
  1781. }
  1782. delete pszNicList;
  1783. delete pRelPath;
  1784. end_fake:
  1785. spWbemService = NULL; // Smart pointer
  1786. spWbemInput = NULL; // smart pointer
  1787. spWbemOutput = NULL; // smart pointer.
  1788. TRACE_INFO("<-%!FUNC! returns 0x%08lx", Status);
  1789. return Status;
  1790. }
  1791. WBEMSTATUS
  1792. NlbHostGetMachineIdentification(
  1793. IN PWMI_CONNECTION_INFO pConnInfo, // NULL implies local
  1794. OUT LPWSTR *pszMachineName, // free using delete
  1795. OUT LPWSTR *pszMachineGuid, // free using delete -- may be null
  1796. OUT BOOL *pfNlbMgrProviderInstalled // If nlb manager provider is installed.
  1797. )
  1798. {
  1799. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  1800. IWbemServicesPtr spWbemService = NULL; // Smart pointer
  1801. if (pConnInfo!=NULL)
  1802. {
  1803. TRACE_INFO("->%!FUNC!(Machine=%ws)", pConnInfo->szMachine);
  1804. }
  1805. else
  1806. {
  1807. TRACE_INFO("->%!FUNC! (Machine=<NULL>)");
  1808. }
  1809. if (g_Fake)
  1810. {
  1811. Status = FakeNlbHostGetMachineIdentification(
  1812. pConnInfo,
  1813. pszMachineName,
  1814. pszMachineGuid,
  1815. pfNlbMgrProviderInstalled
  1816. );
  1817. goto end;
  1818. }
  1819. *pszMachineName = NULL;
  1820. *pszMachineGuid = NULL;
  1821. *pfNlbMgrProviderInstalled = FALSE;
  1822. //
  1823. // Get interface to the NLB namespace on the specified machine
  1824. //
  1825. Status = connect_to_server(pConnInfo, REF spWbemService);
  1826. if (FAILED(Status))
  1827. {
  1828. goto end;
  1829. }
  1830. *pfNlbMgrProviderInstalled = TRUE;
  1831. Status = CfgUtilGetWmiMachineName(spWbemService, pszMachineName);
  1832. if (FAILED(Status))
  1833. {
  1834. *pszMachineName = NULL;
  1835. }
  1836. end:
  1837. spWbemService = NULL; // Smart pointer
  1838. TRACE_INFO("<-%!FUNC! returns 0x%08lx", Status);
  1839. return Status;
  1840. }
  1841. WBEMSTATUS
  1842. connect_to_server(
  1843. IN PWMI_CONNECTION_INFO pConnInfo, // NULL implies local
  1844. OUT IWbemServicesPtr &spWbemService // Smart pointer
  1845. )
  1846. {
  1847. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  1848. #define _MaxLen 256
  1849. WCHAR NetworkResource[_MaxLen];
  1850. LPCWSTR szMachine = L".";
  1851. LPCWSTR szPassword = NULL;
  1852. LPCWSTR szUserName = NULL;
  1853. HRESULT hr;
  1854. WCHAR rgClearPassword[128];
  1855. //
  1856. // Get interface to the NLB namespace on the specified machine.
  1857. //
  1858. if (pConnInfo!=NULL)
  1859. {
  1860. szMachine = pConnInfo->szMachine;
  1861. szPassword = pConnInfo->szPassword;
  1862. szUserName = pConnInfo->szUserName;
  1863. }
  1864. hr = StringCbPrintf(
  1865. NetworkResource,
  1866. sizeof(NetworkResource),
  1867. L"\\\\%ws\\root\\microsoftnlb",
  1868. szMachine
  1869. );
  1870. if (hr != S_OK)
  1871. {
  1872. TRACE_CRIT(L"%!FUNC! NetworkResource truncated - %ws",
  1873. NetworkResource);
  1874. Status = WBEM_E_INVALID_PARAMETER;
  1875. goto end;
  1876. }
  1877. if (szPassword != NULL && *szPassword != 0)
  1878. {
  1879. //
  1880. // A non-null, non-empty password was passed in...
  1881. // It's encrypted, so we temporarily decrypt it here...
  1882. // (We zero it out right before returning from this function)
  1883. //
  1884. BOOL fRet = CfgUtilDecryptPassword(
  1885. szPassword,
  1886. ASIZE(rgClearPassword),
  1887. rgClearPassword
  1888. );
  1889. if (!fRet)
  1890. {
  1891. TRACE_INFO("Attempt to decrypt failed -- bailing");
  1892. Status = WBEM_E_INVALID_PARAMETER;
  1893. goto end;
  1894. }
  1895. szPassword = rgClearPassword;
  1896. }
  1897. TRACE_INFO("%!FUNC! Connecting to NLB on %ws ...", szMachine);
  1898. Status = CfgUtilConnectToServer(
  1899. NetworkResource,
  1900. szUserName, // szUser
  1901. szPassword, // szPassword
  1902. NULL, // szAuthority (domain)
  1903. &spWbemService
  1904. );
  1905. //
  1906. // Security BUGBUG zero out decrypted password.
  1907. //
  1908. if (FAILED(Status))
  1909. {
  1910. TRACE_CRIT(
  1911. "%!FUNC! ERROR 0x%lx connectiong to NLB on %ws",
  1912. (UINT) Status,
  1913. szMachine
  1914. );
  1915. }
  1916. else
  1917. {
  1918. TRACE_INFO(L"Successfully connected to NLB on %ws...", szMachine);
  1919. }
  1920. end:
  1921. SecureZeroMemory(rgClearPassword, sizeof(rgClearPassword));
  1922. return Status;
  1923. }