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.

2021 lines
50 KiB

  1. /*++
  2. Copyright(c) 2001 Microsoft Corporation
  3. Module Name:
  4. NLB Manager
  5. File Name:
  6. nlbhost.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. --*/
  14. #include "tprov.h"
  15. #include "nlbhost.tmh"
  16. //
  17. // Static members of class NLBHost.
  18. //
  19. WSADATA NLBHost::s_WsaData;
  20. LONG NLBHost::s_InstanceCount;
  21. BOOL NLBHost::s_FatalError;
  22. BOOL NLBHost::s_WsaInitialized;
  23. BOOL NLBHost::s_ComInitialized;
  24. IWbemStatusCodeTextPtr NLBHost::s_sp_werr; // Smart pointer
  25. WBEMSTATUS
  26. extract_GetClusterConfiguration_output_params(
  27. IN IWbemClassObjectPtr spWbemOutput,
  28. OUT PNLB_EXTENDED_CLUSTER_CONFIGURATION pCfg
  29. );
  30. WBEMSTATUS
  31. setup_GetClusterConfiguration_input_params(
  32. IN LPCWSTR szNic,
  33. IN IWbemClassObjectPtr spWbemInput
  34. );
  35. WBEMSTATUS
  36. setup_UpdateClusterConfiguration_input_params(
  37. IN LPCWSTR szNic,
  38. IN PNLB_EXTENDED_CLUSTER_CONFIGURATION pCfg,
  39. IN IWbemClassObjectPtr spWbemInput
  40. );
  41. VOID
  42. NLBHost::mfn_LogHr(
  43. LPCWSTR pwszMessage,
  44. HRESULT hr
  45. )
  46. {
  47. if (s_sp_werr)
  48. {
  49. BSTR bstr1 = 0;
  50. BSTR bstr2 = 0;
  51. SCODE sc;
  52. sc = s_sp_werr->GetFacilityCodeText( hr,
  53. 0,
  54. 0,
  55. &bstr1 );
  56. if( sc != S_OK )
  57. {
  58. bstr2 = L"Unknown Error";
  59. }
  60. sc = s_sp_werr->GetErrorCodeText( hr,
  61. 0,
  62. 0,
  63. &bstr2 );
  64. if( sc != S_OK )
  65. {
  66. bstr2 = L"Unknown Code";
  67. }
  68. mfn_Log(
  69. L"%s %s: %s(hr=0x%08lx)",
  70. pwszMessage,
  71. (LPCWSTR) bstr1,
  72. (LPCWSTR) bstr2,
  73. hr
  74. );
  75. SysFreeString( bstr1 );
  76. SysFreeString( bstr2 );
  77. }
  78. else
  79. {
  80. mfn_Log(
  81. L"%s (hr=0x%08lx)",
  82. pwszMessage,
  83. hr
  84. );
  85. }
  86. }
  87. VOID
  88. NLBHost::mfn_Log(
  89. LPCWSTR pwszMessage,
  90. ...
  91. )
  92. {
  93. WCHAR wszBuffer[1024];
  94. wszBuffer[0] = 0;
  95. va_list arglist;
  96. va_start (arglist, pwszMessage);
  97. int cch = vswprintf(wszBuffer, pwszMessage, arglist);
  98. va_end (arglist);
  99. m_pfnLogger(m_pLoggerContext, wszBuffer);
  100. }
  101. NLBHost::NLBHost(
  102. const WCHAR * pBindString,
  103. const WCHAR * pFriendlyName,
  104. PFN_LOGGER pfnLogger,
  105. PVOID pLoggerContext
  106. )
  107. /*++
  108. Routine Description:
  109. Constructor for NLBHost.
  110. The constructor does not initiate any connections to the host. Connections
  111. to the host are initiated on demand (based on method calls).
  112. Arguments:
  113. pBindString - String used to connect to the remote host.
  114. pFriendlyName - Descriptive name of the host. Used for logging.
  115. pfnLogger - Function called to log textual information.
  116. pLoggerContext - Caller's context, passed in calls to pfnLogger
  117. --*/
  118. {
  119. m_BindString = pBindString; // implicit copy
  120. m_FriendlyName = pFriendlyName; // implicit copy
  121. m_pfnLogger = pfnLogger;
  122. m_pLoggerContext = pLoggerContext;
  123. if (InterlockedIncrement(&s_InstanceCount) == 1)
  124. {
  125. mfn_InitializeStaticFields();
  126. }
  127. InitializeCriticalSection(&m_Lock);
  128. mfn_Log(
  129. L"NLBHost(BindString=%s, FriendlyName=%s) constructor succeeded.",
  130. (LPCWSTR) pBindString,
  131. (LPCWSTR) pFriendlyName
  132. );
  133. }
  134. NLBHost::~NLBHost()
  135. /*++
  136. Routine Description:
  137. Destructor for NLBHost.
  138. --*/
  139. {
  140. mfn_Log(L"NLBHost distructor(%s).", (LPCWSTR) m_FriendlyName);
  141. ASSERT(m_fProcessing == FALSE); // Shouldn't be doing any processing when
  142. // calling the distructor.
  143. if (InterlockedDecrement(&s_InstanceCount)==0)
  144. {
  145. mfn_DeinitializeStaticFields();
  146. }
  147. DeleteCriticalSection(&m_Lock);
  148. }
  149. UINT
  150. NLBHost::Ping(
  151. VOID
  152. )
  153. {
  154. if (s_FatalError) return ERROR_INTERNAL_ERROR;
  155. return mfn_ping();
  156. }
  157. WBEMSTATUS
  158. NLBHost::GetHostInformation(
  159. OUT HostInformation **ppHostInfo
  160. )
  161. {
  162. WBEMSTATUS Status;
  163. HostInformation *pHostInfo = NULL;
  164. BOOL fConnected = FALSE;
  165. NicInformation *pNicInfo=NULL;
  166. if (s_FatalError)
  167. {
  168. Status = WBEM_E_CRITICAL_ERROR;
  169. goto end;
  170. }
  171. pHostInfo = new HostInformation;
  172. if (pHostInfo == NULL)
  173. {
  174. Status = WBEM_E_OUT_OF_MEMORY;
  175. goto end;
  176. }
  177. //
  178. // Connect to the host.
  179. //
  180. Status = mfn_connect();
  181. if (FAILED(Status)) goto end;
  182. fConnected = TRUE;
  183. #if 0
  184. //
  185. // Now find the instance and execute the method to get the host info.
  186. //
  187. mfn_find_host_instance();
  188. ... stuff parameters ...
  189. mfn_execute_method();
  190. #endif //
  191. pHostInfo->MachineName = L"ACME-Machine-Name";
  192. pNicInfo = pHostInfo->nicInformation;
  193. pNicInfo->fullNicName = L"ACME Full Nic Name";
  194. pNicInfo->adapterGuid = L"{AD4DA14D-CAAE-42DD-97E3-5355E55247C2}";
  195. pNicInfo->friendlyName = L"ACME Friendly Name";
  196. pHostInfo->NumNics = 1;
  197. end:
  198. if (fConnected)
  199. {
  200. mfn_disconnect();
  201. }
  202. if (FAILED(Status))
  203. {
  204. if (pHostInfo != NULL)
  205. {
  206. delete pHostInfo;
  207. }
  208. pHostInfo = NULL;
  209. }
  210. *ppHostInfo = pHostInfo;
  211. return Status;
  212. }
  213. //
  214. // Configuration operations:
  215. //
  216. WBEMSTATUS
  217. NLBHost::GetClusterConfiguration(
  218. IN const WCHAR* pNicGuid,
  219. OUT PNLB_EXTENDED_CLUSTER_CONFIGURATION pCfg
  220. )
  221. {
  222. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  223. IWbemClassObjectPtr spWbemInputInstance = NULL; // smart pointer
  224. BOOL fConnected = FALSE;
  225. LPWSTR pRelPath = NULL;
  226. IWbemClassObjectPtr spWbemOutput = NULL; // smart pointer.
  227. ZeroMemory(pCfg, sizeof(*pCfg));
  228. if (s_FatalError)
  229. {
  230. Status = WBEM_E_CRITICAL_ERROR;
  231. goto end;
  232. }
  233. //
  234. // Connect to the host.
  235. //
  236. Status = mfn_connect();
  237. if (FAILED(Status)) goto end;
  238. fConnected = TRUE;
  239. mfn_Log(
  240. L"NLBHost -- getting cluster configuration on NIC (%s).",
  241. pNicGuid
  242. );
  243. //
  244. // Get input instance and relpath...
  245. //
  246. Status = CfgUtilGetWmiInputInstanceAndRelPath(
  247. m_sp_pws,
  248. L"NlbsNic", // szClassName
  249. L"AdapterGuid", // szParameterName
  250. pNicGuid, // szPropertyValue
  251. L"GetClusterConfiguration", // szMethodName,
  252. spWbemInputInstance, // smart pointer
  253. &pRelPath // free using delete
  254. );
  255. if (FAILED(Status))
  256. {
  257. mfn_Log(
  258. L"NLBHost -- error 0x%08lx trying to find NIC instance\n",
  259. (UINT) Status
  260. );
  261. goto end;
  262. }
  263. //
  264. // NOTE: spWbemInputInstance could be NULL -- in fact it is
  265. // NULL because GetClusterConfiguration doesn't require input args
  266. //
  267. //
  268. // Run the Method!
  269. //
  270. {
  271. HRESULT hr;
  272. printf("Going to call GetClusterConfiguration\n");
  273. hr = m_sp_pws->ExecMethod(
  274. _bstr_t(pRelPath),
  275. L"GetClusterConfiguration",
  276. 0,
  277. NULL,
  278. spWbemInputInstance,
  279. &spWbemOutput,
  280. NULL
  281. );
  282. printf("GetClusterConfiguration returns\n");
  283. if( FAILED( hr) )
  284. {
  285. printf("IWbemServices::ExecMethod failure 0x%08lx\n", (UINT) hr);
  286. goto end;
  287. }
  288. else
  289. {
  290. printf("GetClusterConfiguration method returns SUCCESS!\n");
  291. }
  292. if (spWbemOutput == NULL)
  293. {
  294. //
  295. // Hmm --- no output ?!
  296. //
  297. printf("ExecMethod GetClusterConfiguration had no output\n");
  298. Status = WBEM_E_NOT_FOUND;
  299. goto end;
  300. }
  301. }
  302. //
  303. // Extract all the out parameters!
  304. //
  305. {
  306. DWORD dwRet=0;
  307. Status = CfgUtilGetWmiDWORDParam(
  308. spWbemOutput,
  309. L"ReturnValue",
  310. &dwRet
  311. );
  312. if (FAILED(Status))
  313. {
  314. printf("IWbemClassObject::Get failure\n");
  315. //
  316. // Let's ignore for now...
  317. //
  318. dwRet = 0;
  319. }
  320. Status = extract_GetClusterConfiguration_output_params(
  321. spWbemOutput,
  322. pCfg
  323. );
  324. }
  325. end:
  326. if (fConnected)
  327. {
  328. mfn_disconnect();
  329. }
  330. if (pRelPath != NULL)
  331. {
  332. delete pRelPath;
  333. }
  334. spWbemInputInstance = NULL; // smart pointer.
  335. return Status;
  336. }
  337. WBEMSTATUS
  338. NLBHost::SetClusterConfiguration(
  339. IN const WCHAR * pNicGuid,
  340. IN const PNLB_EXTENDED_CLUSTER_CONFIGURATION pCfg,
  341. IN UINT GenerationId,
  342. OUT UINT * pRequestId
  343. )
  344. {
  345. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  346. if (s_FatalError)
  347. {
  348. goto end;
  349. }
  350. mfn_Log(
  351. L"NLBHost -- setting cluster configuration on NIC (%s).",
  352. pNicGuid
  353. );
  354. *pRequestId = 123;
  355. Status = WBEM_S_PENDING;
  356. end:
  357. return Status;
  358. }
  359. WBEMSTATUS
  360. NLBHost::GetAsyncResult(
  361. IN UINT RequestId,
  362. OUT UINT * pGenerationId,
  363. OUT UINT * pResultCode,
  364. OUT _bstr_t * pResultText
  365. )
  366. {
  367. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  368. if (s_FatalError)
  369. {
  370. goto end;
  371. }
  372. mfn_Log(
  373. L"NLBHost -- checking result of Async operation %d\n",
  374. RequestId
  375. );
  376. *pGenerationId = 1;
  377. *pResultCode = 1;
  378. *pResultText = L"Result";
  379. Status = WBEM_NO_ERROR;
  380. end:
  381. return Status;
  382. }
  383. WBEMSTATUS
  384. NLBHost::mfn_connect(
  385. VOID
  386. )
  387. {
  388. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  389. HRESULT hr;
  390. _bstr_t serverPath;
  391. hr = CoCreateInstance(CLSID_WbemLocator, 0,
  392. CLSCTX_INPROC_SERVER,
  393. IID_IWbemLocator,
  394. (LPVOID *) &m_sp_pwl);
  395. if (FAILED(hr))
  396. {
  397. mfn_LogHr(L"CoCreateInstance IWebmLocator failed", hr);
  398. m_sp_pwl = NULL;
  399. goto end;
  400. }
  401. //
  402. serverPath = _bstr_t(L"\\\\") + m_BindString + L"\\root\\microsoftnlb";
  403. hr = m_sp_pwl->ConnectServer(
  404. serverPath,
  405. NULL, // strUser,
  406. NULL, // strPassword,
  407. NULL,
  408. 0,
  409. NULL,
  410. NULL,
  411. &m_sp_pws
  412. );
  413. // these have been found to be special cases where retrying may help.
  414. if( ( hr == 0x800706bf ) || ( hr == 0x80070767 ) || ( hr == 0x80070005 ) )
  415. {
  416. int delay = 250; // milliseconds
  417. int timesToRetry = 20;
  418. for( int i = 0; i < timesToRetry; ++i )
  419. {
  420. Sleep(delay);
  421. mfn_Log(L"connectserver recoverable failure, retrying.");
  422. hr = m_sp_pwl->ConnectServer(
  423. serverPath,
  424. NULL, // strUser,
  425. NULL, // strPassword,
  426. NULL,
  427. 0,
  428. NULL,
  429. NULL,
  430. &m_sp_pws );
  431. if( !FAILED( hr) )
  432. {
  433. break;
  434. }
  435. }
  436. }
  437. else if ( hr == 0x80041064 )
  438. {
  439. // trying to connect to local machine. Cannot use credentials.
  440. mfn_Log(L"Connecting to self. Retrying without using credentials");
  441. hr = m_sp_pwl->ConnectServer(
  442. serverPath,
  443. NULL,
  444. NULL,
  445. 0,
  446. NULL,
  447. 0,
  448. 0,
  449. &m_sp_pws
  450. );
  451. }
  452. if (FAILED(hr))
  453. {
  454. mfn_LogHr(L"Error connecting to server", hr);
  455. m_sp_pws = NULL;
  456. goto end;
  457. }
  458. else
  459. {
  460. mfn_Log(L"Successfully connected to server %s", serverPath);
  461. }
  462. // Set the proxy so that impersonation of the client occurs.
  463. //
  464. hr = CoSetProxyBlanket(
  465. m_sp_pws,
  466. RPC_C_AUTHN_WINNT,
  467. RPC_C_AUTHZ_DEFAULT, // RPC_C_AUTHZ_NAME,
  468. COLE_DEFAULT_PRINCIPAL, // NULL,
  469. RPC_C_AUTHN_LEVEL_DEFAULT,
  470. RPC_C_IMP_LEVEL_IMPERSONATE,
  471. COLE_DEFAULT_AUTHINFO, // NULL,
  472. EOAC_DEFAULT // EOAC_NONE
  473. );
  474. if (FAILED(hr))
  475. {
  476. mfn_LogHr(L"Error setting proxy blanket", hr);
  477. goto end;
  478. }
  479. else
  480. {
  481. mfn_Log(L"Successfully set up proxy settings.");
  482. }
  483. Status = WBEM_NO_ERROR;
  484. end:
  485. if (FAILED(Status))
  486. {
  487. if (m_sp_pws != NULL)
  488. {
  489. // Smart pointer.
  490. m_sp_pws = NULL;
  491. }
  492. if (m_sp_pwl != NULL)
  493. {
  494. // Smart pointer.
  495. m_sp_pwl = NULL;
  496. }
  497. }
  498. return Status;
  499. }
  500. VOID
  501. NLBHost::mfn_disconnect(
  502. VOID
  503. )
  504. {
  505. mfn_Log(L"Disconnecting from host %s", m_BindString);
  506. if (m_sp_pws != NULL)
  507. {
  508. // Smart pointer
  509. m_sp_pws = NULL;
  510. }
  511. if (m_sp_pwl != NULL)
  512. {
  513. // Smart pointer
  514. m_sp_pwl = NULL;
  515. }
  516. }
  517. VOID
  518. NLBHost::mfn_InitializeStaticFields(
  519. VOID
  520. )
  521. {
  522. s_FatalError = TRUE;
  523. // Initialize com.
  524. //
  525. HRESULT hr = CoInitializeEx(0, COINIT_MULTITHREADED);
  526. if ( FAILED(hr) )
  527. {
  528. mfn_Log(L"Failed to initialize COM library (hr=0x%08lx)", hr);
  529. goto end;
  530. }
  531. s_ComInitialized = TRUE;
  532. //
  533. // Initialize Winsock
  534. //
  535. int err = WSAStartup(MAKEWORD(2,2), &s_WsaData);
  536. mfn_Log(L"Initializing Winsock");
  537. err = WSAStartup(MAKEWORD(2,2), &s_WsaData);
  538. if (err) {
  539. mfn_Log(L"PING_WSASTARTUP_FAILED %d", GetLastError());
  540. goto end;
  541. }
  542. s_WsaInitialized = TRUE;
  543. s_FatalError = FALSE;
  544. //
  545. // Get some WMI interface pointers...
  546. //
  547. SCODE sc = CoCreateInstance(
  548. CLSID_WbemStatusCodeText,
  549. 0,
  550. CLSCTX_INPROC_SERVER,
  551. IID_IWbemStatusCodeText,
  552. (LPVOID *) &s_sp_werr
  553. );
  554. if( sc != S_OK )
  555. {
  556. s_sp_werr = NULL;
  557. mfn_Log(L"CoCreateInstance IWbemStatusCodeText failure\n");
  558. }
  559. end:
  560. if (s_FatalError)
  561. {
  562. mfn_DeinitializeStaticFields();
  563. }
  564. }
  565. VOID
  566. NLBHost::mfn_DeinitializeStaticFields(
  567. VOID
  568. )
  569. {
  570. if (s_sp_werr != NULL)
  571. {
  572. s_sp_werr = NULL; // Smart pointer
  573. }
  574. if (s_WsaInitialized)
  575. {
  576. mfn_Log(L"Deinitializing Winsock");
  577. WSACleanup();
  578. s_WsaInitialized = FALSE;
  579. }
  580. if (s_ComInitialized)
  581. {
  582. mfn_Log(L"Deinitializing COM");
  583. CoUninitialize();
  584. s_ComInitialized = FALSE;
  585. }
  586. }
  587. #if 0
  588. WBEMSTATUS
  589. extract_extended_config_from_wmi(
  590. IN IWbemClassObjectPtr &spWbemOutput,
  591. OUT PNLB_EXTENDED_CLUSTER_CONFIGURATION pCfg
  592. )
  593. {
  594. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  595. NLB_IP_ADDRESS_INFO *pIpInfo = NULL;
  596. UINT NumIpAddresses = 0;
  597. BOOL fNlbBound = FALSE;
  598. WLBS_REG_PARAMS NlbParams; // The WLBS-specific configuration
  599. BOOL fNlbParamsValid = FALSE;
  600. UINT Generation = 1;
  601. //
  602. // Verify that pCfg is indeed zero-initialized.
  603. // We are doing this because we want to make sure that the caller
  604. // doesn't pass in a perviously initialized pCfg which may have a non-null
  605. // ip address array.
  606. //
  607. {
  608. BYTE *pb = (BYTE*) pCfg;
  609. BYTE *pbEnd = (BYTE*) (pCfg+1);
  610. for (; pb < pbEnd; pb++)
  611. {
  612. if (*pb!=0)
  613. {
  614. printf(L"uninitialized pCfg\n");
  615. ASSERT(!"uninitialized pCfg");
  616. Status = WBEM_E_INVALID_PARAMETER;
  617. goto end;
  618. }
  619. }
  620. }
  621. //
  622. // Get the ip address list.
  623. //
  624. Status = CfgUtilGetStaticIpAddresses(
  625. m_szNicGuid,
  626. &NumIpAddresses,
  627. &pIpInfo
  628. );
  629. if (FAILED(Status))
  630. {
  631. printf("Error 0x%08lx getting ip address list for %ws\n",
  632. (UINT) Status, m_szNicGuid);
  633. mfn_Log(L"Error IP Address list on this NIC\n");
  634. pIpInfo = NULL;
  635. goto end;
  636. }
  637. //
  638. // TEST TEST TEST
  639. //
  640. if (0)
  641. {
  642. if (NumIpAddresses>1)
  643. {
  644. //
  645. // Let's munge the 2nd IP address
  646. //
  647. if (!_wcsicmp(pIpInfo[1].IpAddress, L"10.0.0.33"))
  648. {
  649. wcscpy(pIpInfo[1].IpAddress, L"10.0.0.44");
  650. }
  651. else
  652. {
  653. wcscpy(pIpInfo[1].IpAddress, L"10.0.0.33");
  654. }
  655. }
  656. MyBreak(L"Break just before calling CfgUtilSetStaticIpAddresses\n");
  657. Status = CfgUtilSetStaticIpAddresses(
  658. m_szNicGuid,
  659. NumIpAddresses,
  660. pIpInfo
  661. );
  662. }
  663. //
  664. // Check if NLB is bound
  665. //
  666. Status = CfgUtilCheckIfNlbBound(
  667. m_szNicGuid,
  668. &fNlbBound
  669. );
  670. if (FAILED(Status))
  671. {
  672. printf("Error 0x%08lx determining if NLB is bound to %ws\n",
  673. (UINT) Status, m_szNicGuid);
  674. mfn_Log(L"Error determining if NLB is bound to this NIC\n");
  675. goto end;
  676. }
  677. if (fNlbBound)
  678. {
  679. //
  680. // Get the latest NLB configuration information for this NIC.
  681. //
  682. Status = CfgUtilGetNlbConfig(
  683. m_szNicGuid,
  684. &NlbParams
  685. );
  686. if (FAILED(Status))
  687. {
  688. //
  689. // We don't consider a catastrophic failure.
  690. //
  691. printf("Error 0x%08lx reading NLB configuration for %ws\n",
  692. (UINT) Status, m_szNicGuid);
  693. mfn_Log(L"Error reading NLB configuration for this NIC\n");
  694. Status = WBEM_NO_ERROR;
  695. fNlbParamsValid = FALSE;
  696. ZeroMemory(&NlbParams, sizeof(NlbParams));
  697. }
  698. else
  699. {
  700. fNlbParamsValid = TRUE;
  701. }
  702. }
  703. //
  704. // Get the current generation
  705. //
  706. {
  707. BOOL fExists=FALSE;
  708. HKEY hKey = sfn_RegOpenKey(
  709. m_szNicGuid,
  710. NULL // NULL == root for this guid.,
  711. );
  712. Generation = 1; // We assume generation is 1 on error reading gen.
  713. if (hKey!=NULL)
  714. {
  715. LONG lRet;
  716. DWORD dwType;
  717. DWORD dwData;
  718. dwData = sizeof(Generation);
  719. lRet = RegQueryValueEx(
  720. hKey, // handle to key to query
  721. L"Generation", // address of name of value to query
  722. NULL, // reserved
  723. &dwType, // address of buffer for value type
  724. (LPBYTE) &Generation, // address of data buffer
  725. &dwData // address of data buffer size
  726. );
  727. if ( lRet != ERROR_SUCCESS
  728. || dwType != REG_DWORD
  729. || dwData != sizeof(Generation))
  730. {
  731. //
  732. // Couldn't read the generation. Let's assume it's
  733. // a starting value of 1.
  734. //
  735. printf("Error reading generation for %ws; assuming its 0\n",
  736. m_szNicGuid);
  737. Generation = 1;
  738. }
  739. }
  740. }
  741. //
  742. // Success ... fill out pCfg
  743. //
  744. pCfg->fValidNlbCfg = fNlbParamsValid;
  745. pCfg->Generation = Generation;
  746. pCfg->fBound = fNlbBound;
  747. pCfg->NumIpAddresses = NumIpAddresses;
  748. pCfg->pIpAddressInfo = pIpInfo;
  749. if (fNlbBound)
  750. {
  751. pCfg->NlbParams = NlbParams; // struct copy
  752. }
  753. Status = WBEM_NO_ERROR;
  754. end:
  755. if (FAILED(Status))
  756. {
  757. if (pIpInfo!=NULL)
  758. {
  759. delete pIpInfo;
  760. }
  761. pCfg->fValidNlbCfg = FALSE;
  762. }
  763. return Status;
  764. return WBEM_NO_ERROR;
  765. }
  766. #endif // 0
  767. WBEMSTATUS
  768. NlbHostGetConfiguration(
  769. IN LPCWSTR szMachine, // empty string for local
  770. IN LPCWSTR szNicGuid,
  771. OUT PNLB_EXTENDED_CLUSTER_CONFIGURATION pCurrentCfg
  772. )
  773. {
  774. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  775. IWbemServicesPtr spWbemService = NULL; // Smart pointer
  776. IWbemClassObjectPtr spWbemInput = NULL; // smart pointer
  777. IWbemClassObjectPtr spWbemOutput = NULL; // smart pointer.
  778. LPWSTR pRelPath = NULL;
  779. //
  780. // Get interface to the NLB namespace on the specified machine
  781. //
  782. {
  783. #define _MaxLen 256
  784. WCHAR NetworkResource[_MaxLen];
  785. if (*szMachine == 0)
  786. {
  787. szMachine = L".";
  788. }
  789. _snwprintf(NetworkResource, (_MaxLen-1), L"\\\\%ws\\root\\microsoftnlb",
  790. szMachine);
  791. NetworkResource[_MaxLen-1]=0;
  792. wprintf(L"Connecting to NLB on %ws ...\n", szMachine);
  793. Status = CfgUtilConnectToServer(
  794. NetworkResource,
  795. NULL, // szUser
  796. NULL, // szPassword
  797. NULL, // szAuthority (domain)
  798. &spWbemService
  799. );
  800. if (FAILED(Status))
  801. {
  802. wprintf(L"ERROR: COULD NOT CONNECT TO NLB ON %ws\n", szMachine);
  803. goto end;
  804. }
  805. wprintf(L"Successfully connected to NLB on %ws...\n", szMachine);
  806. }
  807. //
  808. // Get wmi input instance to "GetClusterConfiguration" method
  809. //
  810. {
  811. Status = CfgUtilGetWmiInputInstanceAndRelPath(
  812. spWbemService,
  813. L"NlbsNic", // szClassName
  814. L"AdapterGuid", // szParameterName
  815. szNicGuid, // szPropertyValue
  816. L"GetClusterConfiguration", // szMethodName,
  817. spWbemInput, // smart pointer
  818. &pRelPath // free using delete
  819. );
  820. if (FAILED(Status))
  821. {
  822. wprintf(
  823. L"ERROR 0x%08lx trying to get instance of GetClusterConfiguration\n",
  824. (UINT) Status
  825. );
  826. goto end;
  827. }
  828. }
  829. //
  830. // Setup params for the "GetClusterConfiguration" method
  831. // NOTE: spWbemInput could be NULL.
  832. //
  833. Status = setup_GetClusterConfiguration_input_params(
  834. szNicGuid,
  835. spWbemInput
  836. );
  837. if (FAILED(Status))
  838. {
  839. goto end;
  840. }
  841. //
  842. // Call the "GetClusterConfiguration" method
  843. //
  844. {
  845. HRESULT hr;
  846. wprintf(L"Going get GetClusterConfiguration...\n");
  847. hr = spWbemService->ExecMethod(
  848. _bstr_t(pRelPath),
  849. L"GetClusterConfiguration",
  850. 0,
  851. NULL,
  852. spWbemInput,
  853. &spWbemOutput,
  854. NULL
  855. );
  856. if( FAILED( hr) )
  857. {
  858. wprintf(L"GetClusterConfiguration returns with failure 0x%8lx\n",
  859. (UINT) hr);
  860. goto end;
  861. }
  862. else
  863. {
  864. wprintf(L"GetClusterConfiguration returns successfully\n");
  865. }
  866. if (spWbemOutput == NULL)
  867. {
  868. //
  869. // Hmm --- no output ?!
  870. //
  871. printf("ExecMethod GetClusterConfiguration had no output");
  872. Status = WBEM_E_NOT_FOUND;
  873. goto end;
  874. }
  875. }
  876. //
  877. // Extract params from the "GetClusterConfiguration" method
  878. //
  879. Status = extract_GetClusterConfiguration_output_params(
  880. spWbemOutput,
  881. pCurrentCfg
  882. );
  883. end:
  884. if (pRelPath != NULL)
  885. {
  886. delete pRelPath;
  887. }
  888. spWbemService = NULL; // Smart pointer
  889. spWbemInput = NULL; // smart pointer
  890. spWbemOutput = NULL; // smart pointer.
  891. return Status;
  892. }
  893. WBEMSTATUS
  894. NlbHostDoUpdate(
  895. IN LPCWSTR szMachine, // NULL or empty for local
  896. IN LPCWSTR szNicGuid,
  897. IN LPCWSTR szClientDescription,
  898. IN PNLB_EXTENDED_CLUSTER_CONFIGURATION pNewState,
  899. OUT UINT *pGeneration,
  900. OUT WCHAR **ppLog // free using delete operator.
  901. )
  902. {
  903. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  904. IWbemServicesPtr spWbemService = NULL; // Smart pointer
  905. IWbemClassObjectPtr spWbemInput = NULL; // smart pointer
  906. IWbemClassObjectPtr spWbemOutput = NULL; // smart pointer.
  907. LPWSTR pRelPath = NULL;
  908. *pGeneration = 0;
  909. *ppLog = NULL;
  910. //
  911. // Get interface to the NLB namespace on the specified machine
  912. //
  913. {
  914. #define _MaxLen 256
  915. WCHAR NetworkResource[_MaxLen];
  916. if (*szMachine == 0)
  917. {
  918. szMachine = L".";
  919. }
  920. _snwprintf(NetworkResource, (_MaxLen-1), L"\\\\%ws\\root\\microsoftnlb",
  921. szMachine);
  922. NetworkResource[_MaxLen-1]=0;
  923. wprintf(L"Connecting to NLB on %ws ...\n", szMachine);
  924. Status = CfgUtilConnectToServer(
  925. NetworkResource,
  926. NULL, // szUser
  927. NULL, // szPassword
  928. NULL, // szAuthority (domain)
  929. &spWbemService
  930. );
  931. if (FAILED(Status))
  932. {
  933. wprintf(L"ERROR: COULD NOT CONNECT TO NLB ON %ws\n", szMachine);
  934. goto end;
  935. }
  936. wprintf(L"Successfully connected to NLB on %ws...\n", szMachine);
  937. }
  938. //
  939. // Get wmi input instance to "UpdateClusterConfiguration" method
  940. //
  941. {
  942. Status = CfgUtilGetWmiInputInstanceAndRelPath(
  943. spWbemService,
  944. L"NlbsNic", // szClassName
  945. L"AdapterGuid", // szParameterName
  946. szNicGuid, // szPropertyValue
  947. L"UpdateClusterConfiguration", // szMethodName,
  948. spWbemInput, // smart pointer
  949. &pRelPath // free using delete
  950. );
  951. if (FAILED(Status))
  952. {
  953. wprintf(
  954. L"ERROR 0x%08lx trying to get instance of UpdateConfiguration\n",
  955. (UINT) Status
  956. );
  957. goto end;
  958. }
  959. }
  960. //
  961. // Setup params for the "UpdateClusterConfiguration" method
  962. // NOTE: spWbemInput could be NULL.
  963. //
  964. Status = setup_UpdateClusterConfiguration_input_params(
  965. szNicGuid,
  966. pNewState,
  967. spWbemInput
  968. );
  969. if (FAILED(Status))
  970. {
  971. goto end;
  972. }
  973. //
  974. // Call the "UpdateClusterConfiguration" method
  975. //
  976. {
  977. HRESULT hr;
  978. wprintf(L"Going get UpdateClusterConfiguration...\n");
  979. hr = spWbemService->ExecMethod(
  980. _bstr_t(pRelPath),
  981. L"UpdateClusterConfiguration",
  982. 0,
  983. NULL,
  984. spWbemInput,
  985. &spWbemOutput,
  986. NULL
  987. );
  988. if( FAILED( hr) )
  989. {
  990. wprintf(L"UpdateConfiguration returns with failure 0x%8lx\n",
  991. (UINT) hr);
  992. goto end;
  993. }
  994. else
  995. {
  996. wprintf(L"UpdateConfiguration returns successfully\n");
  997. }
  998. if (spWbemOutput == NULL)
  999. {
  1000. //
  1001. // Hmm --- no output ?!
  1002. //
  1003. printf("ExecMethod UpdateConfiguration had no output");
  1004. Status = WBEM_E_NOT_FOUND;
  1005. goto end;
  1006. }
  1007. }
  1008. //
  1009. // Extract params from the "UpdateClusterConfiguration" method
  1010. //
  1011. {
  1012. DWORD dwReturnValue = 0;
  1013. Status = CfgUtilGetWmiDWORDParam(
  1014. spWbemOutput,
  1015. L"ReturnValue", // <--------------------------------
  1016. &dwReturnValue
  1017. );
  1018. if (FAILED(Status))
  1019. {
  1020. wprintf(L"Attempt to read ReturnValue failed. Error=0x%08lx\n",
  1021. (UINT) Status);
  1022. goto end;
  1023. }
  1024. LPWSTR szLog = NULL;
  1025. Status = CfgUtilGetWmiStringParam(
  1026. spWbemOutput,
  1027. L"Log", // <-------------------------
  1028. &szLog
  1029. );
  1030. if (FAILED(Status))
  1031. {
  1032. szLog = NULL;
  1033. }
  1034. *ppLog = szLog;
  1035. DWORD dwGeneration = 0;
  1036. Status = CfgUtilGetWmiDWORDParam(
  1037. spWbemOutput,
  1038. L"NewGeneration", // <--------------------------------
  1039. &dwGeneration
  1040. );
  1041. if (FAILED(Status))
  1042. {
  1043. //
  1044. // Generation should always be specified for pending operations.
  1045. // TODO: for successful operations also?
  1046. //
  1047. if ((WBEMSTATUS)dwReturnValue == WBEM_S_PENDING)
  1048. {
  1049. wprintf(L"Attempt to read NewGeneration for pending update failed. Error=0x%08lx\n",
  1050. (UINT) Status);
  1051. Status = WBEM_E_CRITICAL_ERROR;
  1052. goto end;
  1053. }
  1054. dwGeneration = 0; // we don't care if it's not set for non-pending
  1055. }
  1056. *pGeneration = (UINT) dwGeneration;
  1057. //
  1058. // Make the return status reflect the true status of the update
  1059. // operation.
  1060. //
  1061. Status = (WBEMSTATUS) dwReturnValue;
  1062. }
  1063. end:
  1064. if (pRelPath != NULL)
  1065. {
  1066. delete pRelPath;
  1067. }
  1068. spWbemService = NULL; // Smart pointer
  1069. spWbemInput = NULL; // smart pointer
  1070. spWbemOutput = NULL; // smart pointer.
  1071. return Status;
  1072. }
  1073. WBEMSTATUS
  1074. NlbHostGetUpdateStatus(
  1075. IN LPCWSTR szMachine, // NULL or empty for local
  1076. IN LPCWSTR szNicGuid,
  1077. IN UINT Generation,
  1078. OUT WBEMSTATUS *pCompletionStatus,
  1079. OUT WCHAR **ppLog // free using delete operator.
  1080. )
  1081. {
  1082. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  1083. IWbemServicesPtr spWbemService = NULL; // Smart pointer
  1084. IWbemClassObjectPtr spWbemInput = NULL; // smart pointer
  1085. IWbemClassObjectPtr spWbemOutput = NULL; // smart pointer.
  1086. LPWSTR pRelPath = NULL;
  1087. *ppLog = NULL;
  1088. *pCompletionStatus = WBEM_E_CRITICAL_ERROR;
  1089. //
  1090. // Get interface to the NLB namespace on the specified machine
  1091. //
  1092. {
  1093. #define _MaxLen 256
  1094. WCHAR NetworkResource[_MaxLen];
  1095. if (*szMachine == 0)
  1096. {
  1097. szMachine = L".";
  1098. }
  1099. _snwprintf(NetworkResource, (_MaxLen-1), L"\\\\%ws\\root\\microsoftnlb",
  1100. szMachine);
  1101. NetworkResource[_MaxLen-1]=0;
  1102. // wprintf(L"Connecting to NLB on %ws ...\n", szMachine);
  1103. Status = CfgUtilConnectToServer(
  1104. NetworkResource,
  1105. NULL, // szUser
  1106. NULL, // szPassword
  1107. NULL, // szAuthority (domain)
  1108. &spWbemService
  1109. );
  1110. if (FAILED(Status))
  1111. {
  1112. wprintf(L"ERROR: COULD NOT CONNECT TO NLB ON %ws\n", szMachine);
  1113. goto end;
  1114. }
  1115. // wprintf(L"Successfully connected to NLB on %ws...\n", szMachine);
  1116. }
  1117. //
  1118. // Get wmi input instance to "QueryConfigurationUpdateStatus" method
  1119. //
  1120. {
  1121. Status = CfgUtilGetWmiInputInstanceAndRelPath(
  1122. spWbemService,
  1123. L"NlbsNic", // szClassName
  1124. L"AdapterGuid", // szParameterName
  1125. szNicGuid, // szPropertyValue
  1126. L"QueryConfigurationUpdateStatus", // szMethodName,
  1127. spWbemInput, // smart pointer
  1128. &pRelPath // free using delete
  1129. );
  1130. if (FAILED(Status))
  1131. {
  1132. wprintf(
  1133. L"ERROR 0x%08lx trying to find instance to QueryUpdateStatus\n",
  1134. (UINT) Status
  1135. );
  1136. goto end;
  1137. }
  1138. }
  1139. //
  1140. // Setup params for the "QueryConfigurationUpdateStatus" method
  1141. // NOTE: spWbemInput could be NULL.
  1142. //
  1143. {
  1144. Status = CfgUtilSetWmiStringParam(
  1145. spWbemInput,
  1146. L"AdapterGuid",
  1147. szNicGuid
  1148. );
  1149. if (FAILED(Status))
  1150. {
  1151. wprintf(
  1152. L"Couldn't set Adapter GUID parameter to QueryUpdateStatus\n");
  1153. goto end;
  1154. }
  1155. Status = CfgUtilSetWmiDWORDParam(
  1156. spWbemInput,
  1157. L"Generation",
  1158. Generation
  1159. );
  1160. if (FAILED(Status))
  1161. {
  1162. wprintf(
  1163. L"Couldn't set Generation parameter to QueryUpdateStatus\n");
  1164. goto end;
  1165. }
  1166. }
  1167. //
  1168. // Call the "QueryConfigurationUpdateStatus" method
  1169. //
  1170. {
  1171. HRESULT hr;
  1172. // wprintf(L"Going call QueryConfigurationUpdateStatus...\n");
  1173. hr = spWbemService->ExecMethod(
  1174. _bstr_t(pRelPath),
  1175. L"QueryConfigurationUpdateStatus", // szMethodName,
  1176. 0,
  1177. NULL,
  1178. spWbemInput,
  1179. &spWbemOutput,
  1180. NULL
  1181. );
  1182. if( FAILED( hr) )
  1183. {
  1184. wprintf(L"QueryConfigurationUpdateStatus returns with failure 0x%8lx\n",
  1185. (UINT) hr);
  1186. goto end;
  1187. }
  1188. else
  1189. {
  1190. // wprintf(L"QueryConfigurationUpdateStatus returns successfully\n");
  1191. }
  1192. if (spWbemOutput == NULL)
  1193. {
  1194. //
  1195. // Hmm --- no output ?!
  1196. //
  1197. printf("ExecMethod QueryConfigurationUpdateStatus had no output");
  1198. Status = WBEM_E_NOT_FOUND;
  1199. goto end;
  1200. }
  1201. }
  1202. //
  1203. // Extract output params --- return code and log.
  1204. //
  1205. {
  1206. DWORD dwReturnValue = 0;
  1207. Status = CfgUtilGetWmiDWORDParam(
  1208. spWbemOutput,
  1209. L"ReturnValue", // <--------------------------------
  1210. &dwReturnValue
  1211. );
  1212. if (FAILED(Status))
  1213. {
  1214. wprintf(L"Attempt to read ReturnValue failed. Error=0x%08lx\n",
  1215. (UINT) Status);
  1216. goto end;
  1217. }
  1218. *pCompletionStatus = (WBEMSTATUS) dwReturnValue;
  1219. LPWSTR szLog = NULL;
  1220. Status = CfgUtilGetWmiStringParam(
  1221. spWbemOutput,
  1222. L"Log", // <-------------------------
  1223. &szLog
  1224. );
  1225. if (FAILED(Status))
  1226. {
  1227. szLog = NULL;
  1228. }
  1229. *ppLog = szLog;
  1230. ASSERT(Status != WBEM_S_PENDING);
  1231. }
  1232. end:
  1233. if (pRelPath != NULL)
  1234. {
  1235. delete pRelPath;
  1236. }
  1237. spWbemService = NULL; // Smart pointer
  1238. spWbemInput = NULL; // smart pointer
  1239. spWbemOutput = NULL; // smart pointer.
  1240. return Status;
  1241. }
  1242. WBEMSTATUS
  1243. setup_GetClusterConfiguration_input_params(
  1244. IN LPCWSTR szNic,
  1245. IN IWbemClassObjectPtr spWbemInput
  1246. )
  1247. /*
  1248. Setup the input wmi parameters for the GetClusterConfiguration method
  1249. */
  1250. {
  1251. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  1252. Status = CfgUtilSetWmiStringParam(
  1253. spWbemInput,
  1254. L"AdapterGuid",
  1255. szNic
  1256. );
  1257. return Status;
  1258. }
  1259. WBEMSTATUS
  1260. extract_GetClusterConfiguration_output_params(
  1261. IN IWbemClassObjectPtr spWbemOutput,
  1262. OUT PNLB_EXTENDED_CLUSTER_CONFIGURATION pCfg
  1263. )
  1264. {
  1265. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  1266. DWORD Generation = 0;
  1267. BOOL NlbBound = FALSE;
  1268. LPWSTR *pszNetworkAddresses= NULL;
  1269. UINT NumNetworkAddresses = 0;
  1270. BOOL ValidNlbCfg = FALSE;
  1271. LPWSTR szClusterName = NULL;
  1272. LPWSTR szClusterNetworkAddress = NULL;
  1273. LPWSTR szTrafficMode = NULL;
  1274. NLB_EXTENDED_CLUSTER_CONFIGURATION::TRAFFIC_MODE
  1275. TrafficMode
  1276. = NLB_EXTENDED_CLUSTER_CONFIGURATION::TRAFFIC_MODE_UNICAST;
  1277. LPWSTR *pszPortRules = NULL;
  1278. UINT NumPortRules = 0;
  1279. DWORD HostPriority = 0;
  1280. LPWSTR szDedicatedNetworkAddress = NULL;
  1281. NLB_EXTENDED_CLUSTER_CONFIGURATION::START_MODE
  1282. ClusterModeOnStart
  1283. = NLB_EXTENDED_CLUSTER_CONFIGURATION::START_MODE_STOPPED;
  1284. BOOL RemoteControlEnabled= FALSE;
  1285. #if 0
  1286. [OUT] uint32 Generation,
  1287. [OUT] String NetworkAddresses[], // "10.1.1.1/255.0.0.0"
  1288. [OUT] Boolean NLBBound,
  1289. [OUT] String ClusterNetworkAddress, // "10.1.1.1/255.0.0.0"
  1290. [OUT] String ClusterName,
  1291. [OUT] String TrafficMode, // UNICAST MULTICAST IGMPMULTICAST
  1292. [OUT] String PortRules[],
  1293. [OUT] uint32 HostPriority,
  1294. [OUT] String DedicatedNetworkAddress, // "10.1.1.1/255.0.0.0"
  1295. [OUT] Boolean ClusterModeOnStart,
  1296. [OUT] Boolean RemoteControlEnabled
  1297. #endif // 0
  1298. Status = CfgUtilGetWmiDWORDParam(
  1299. spWbemOutput,
  1300. L"Generation", // <--------------------------------
  1301. &Generation
  1302. );
  1303. if (FAILED(Status))
  1304. {
  1305. wprintf(L"Attempt to read Generation failed. Error=0x%08lx\n",
  1306. (UINT) Status);
  1307. goto end;
  1308. }
  1309. Status = CfgUtilGetWmiStringArrayParam(
  1310. spWbemOutput,
  1311. L"NetworkAddresses", // <--------------------------------
  1312. &pszNetworkAddresses,
  1313. &NumNetworkAddresses
  1314. );
  1315. if (FAILED(Status))
  1316. {
  1317. wprintf(L"Attempt to read Network addresses failed. Error=0x%08lx\n",
  1318. (UINT) Status);
  1319. goto end;
  1320. }
  1321. Status = CfgUtilGetWmiBoolParam(
  1322. spWbemOutput,
  1323. L"NLBBound", // <--------------------------------
  1324. &NlbBound
  1325. );
  1326. if (FAILED(Status))
  1327. {
  1328. wprintf(L"Attempt to read NLBBound failed. Error=0x%08lx\n",
  1329. (UINT) Status);
  1330. goto end;
  1331. }
  1332. do // while false -- just to allow us to break out
  1333. {
  1334. ValidNlbCfg = FALSE;
  1335. if (!NlbBound)
  1336. {
  1337. wprintf(L"NLB is UNBOUND\n");
  1338. break;
  1339. }
  1340. Status = CfgUtilGetWmiStringParam(
  1341. spWbemOutput,
  1342. L"ClusterNetworkAddress", // <-------------------------
  1343. &szClusterNetworkAddress
  1344. );
  1345. if (FAILED(Status))
  1346. {
  1347. wprintf(L"Attempt to read Cluster IP failed. Error=0x%08lx\n",
  1348. (UINT) Status);
  1349. break;
  1350. }
  1351. wprintf(L"NLB is BOUND, and the cluster address is %ws\n",
  1352. szClusterNetworkAddress);
  1353. Status = CfgUtilGetWmiStringParam(
  1354. spWbemOutput,
  1355. L"ClusterName", // <-------------------------
  1356. &szClusterName
  1357. );
  1358. if (FAILED(Status))
  1359. {
  1360. wprintf(L"Attempt to read Cluster Name failed. Error=0x%08lx\n",
  1361. (UINT) Status);
  1362. break;
  1363. }
  1364. //
  1365. // Traffic mode
  1366. //
  1367. {
  1368. Status = CfgUtilGetWmiStringParam(
  1369. spWbemOutput,
  1370. L"TrafficMode", // <-------------------------
  1371. &szTrafficMode
  1372. );
  1373. if (FAILED(Status))
  1374. {
  1375. wprintf(L"Attempt to read Traffic Mode failed. Error=0x%08lx\n",
  1376. (UINT) Status);
  1377. break;
  1378. }
  1379. if (!_wcsicmp(szTrafficMode, L"UNICAST"))
  1380. {
  1381. TrafficMode =
  1382. NLB_EXTENDED_CLUSTER_CONFIGURATION::TRAFFIC_MODE_UNICAST;
  1383. }
  1384. else if (!_wcsicmp(szTrafficMode, L"MULTICAST"))
  1385. {
  1386. TrafficMode =
  1387. NLB_EXTENDED_CLUSTER_CONFIGURATION::TRAFFIC_MODE_MULTICAST;
  1388. }
  1389. else if (!_wcsicmp(szTrafficMode, L"IGMPMULTICAST"))
  1390. {
  1391. TrafficMode =
  1392. NLB_EXTENDED_CLUSTER_CONFIGURATION::TRAFFIC_MODE_IGMPMULTICAST;
  1393. }
  1394. }
  1395. // TODO: [OUT] String PortRules[],
  1396. Status = CfgUtilGetWmiDWORDParam(
  1397. spWbemOutput,
  1398. L"HostPriority", // <--------------------------------
  1399. &HostPriority
  1400. );
  1401. if (FAILED(Status))
  1402. {
  1403. wprintf(L"Attempt to read HostPriority failed. Error=0x%08lx\n",
  1404. (UINT) Status);
  1405. break;
  1406. }
  1407. Status = CfgUtilGetWmiStringParam(
  1408. spWbemOutput,
  1409. L"DedicatedNetworkAddress", // <-------------------------
  1410. &szDedicatedNetworkAddress
  1411. );
  1412. if (FAILED(Status))
  1413. {
  1414. wprintf(L"Attempt to read dedicated IP failed. Error=0x%08lx\n",
  1415. (UINT) Status);
  1416. break;
  1417. }
  1418. //
  1419. // StartMode
  1420. //
  1421. {
  1422. BOOL StartMode = FALSE;
  1423. Status = CfgUtilGetWmiBoolParam(
  1424. spWbemOutput,
  1425. L"ClusterModeOnStart", // <-------------------------
  1426. &StartMode
  1427. );
  1428. if (FAILED(Status))
  1429. {
  1430. wprintf(L"Attempt to read ClusterModeOnStart failed. Error=0x%08lx\n",
  1431. (UINT) Status);
  1432. break;
  1433. }
  1434. if (StartMode)
  1435. {
  1436. ClusterModeOnStart =
  1437. NLB_EXTENDED_CLUSTER_CONFIGURATION::START_MODE_STARTED;
  1438. }
  1439. else
  1440. {
  1441. ClusterModeOnStart =
  1442. NLB_EXTENDED_CLUSTER_CONFIGURATION::START_MODE_STOPPED;
  1443. }
  1444. }
  1445. Status = CfgUtilGetWmiBoolParam(
  1446. spWbemOutput,
  1447. L"RemoteControlEnabled", // <----------------------------
  1448. &RemoteControlEnabled
  1449. );
  1450. if (FAILED(Status))
  1451. {
  1452. wprintf(L"Attempt to read RemoteControlEnabled failed. Error=0x%08lx\n",
  1453. (UINT) Status);
  1454. break;
  1455. }
  1456. ValidNlbCfg = TRUE;
  1457. } while (FALSE) ;
  1458. //
  1459. // Now let's set all the the parameters in Cfg
  1460. //
  1461. {
  1462. pCfg->Generation = Generation;
  1463. pCfg->fBound = NlbBound;
  1464. Status = pCfg->SetNetworkAddresses(
  1465. (LPCWSTR*) pszNetworkAddresses,
  1466. NumNetworkAddresses
  1467. );
  1468. if (FAILED(Status))
  1469. {
  1470. wprintf(L"Attempt to set NetworkAddresses failed. Error=0x%08lx\n",
  1471. (UINT) Status);
  1472. goto end;
  1473. }
  1474. pCfg->fValidNlbCfg = ValidNlbCfg;
  1475. pCfg->SetClusterName(szClusterName);
  1476. pCfg->SetClusterNetworkAddress(szClusterNetworkAddress);
  1477. pCfg->SetTrafficMode(TrafficMode);
  1478. Status = pCfg->SetPortRules((LPCWSTR*)pszPortRules, NumPortRules);
  1479. Status = WBEM_NO_ERROR; // TODO -- change once port rules is done
  1480. if (FAILED(Status))
  1481. {
  1482. wprintf(L"Attempt to set PortRules failed. Error=0x%08lx\n",
  1483. (UINT) Status);
  1484. goto end;
  1485. }
  1486. pCfg->SetHostPriority(HostPriority);
  1487. pCfg->SetDedicatedNetworkAddress(szDedicatedNetworkAddress);
  1488. pCfg->SetClusterModeOnStart(ClusterModeOnStart);
  1489. pCfg->SetRemoteControlEnabled(RemoteControlEnabled);
  1490. }
  1491. end:
  1492. delete szClusterNetworkAddress;
  1493. delete pszNetworkAddresses;
  1494. delete szClusterName;
  1495. delete szTrafficMode;
  1496. delete pszPortRules;
  1497. delete szDedicatedNetworkAddress;
  1498. return Status;
  1499. }
  1500. WBEMSTATUS
  1501. setup_UpdateClusterConfiguration_input_params(
  1502. IN LPCWSTR szNic,
  1503. IN PNLB_EXTENDED_CLUSTER_CONFIGURATION pCfg,
  1504. IN IWbemClassObjectPtr spWbemInput
  1505. )
  1506. /*
  1507. Setup the input wmi parameters for the UpdateGetClusterConfiguration method
  1508. [IN] String ClientDescription,
  1509. [IN] String AdapterGuid,
  1510. [IN] uint32 Generation,
  1511. [IN] Boolean PartialUpdate,
  1512. [IN] String NetworkAddresses[], // "10.1.1.1/255.255.255.255"
  1513. [IN] Boolean NLBBound,
  1514. [IN] String ClusterNetworkAddress, // "10.1.1.1/255.0.0.0"
  1515. [IN] String ClusterName,
  1516. [IN] String TrafficMode, // UNICAST MULTICAST IGMPMULTICAST
  1517. [IN] String PortRules[],
  1518. [IN] uint32 HostPriority,
  1519. [IN] String DedicatedNetworkAddress, // "10.1.1.1/255.0.0.0"
  1520. [IN] Boolean ClusterModeOnStart,
  1521. [IN] Boolean RemoteControlEnabled,
  1522. [IN] String Password,
  1523. */
  1524. {
  1525. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  1526. Status = CfgUtilSetWmiStringParam(
  1527. spWbemInput,
  1528. L"AdapterGuid",
  1529. szNic
  1530. );
  1531. //
  1532. // Fill in NetworkAddresses[]
  1533. //
  1534. {
  1535. LPWSTR *pszAddresses = NULL;
  1536. UINT NumAddresses = 0;
  1537. Status = pCfg->GetNetworkAddresses(
  1538. &pszAddresses,
  1539. &NumAddresses
  1540. );
  1541. if (FAILED(Status))
  1542. {
  1543. printf(
  1544. "Setup update params: couldn't extract network addresses from Cfg"
  1545. " for NIC %ws\n",
  1546. szNic
  1547. );
  1548. goto end;
  1549. }
  1550. //
  1551. // Note it's ok to not specify any IP addresses -- in which case
  1552. // the default ip addresses will be set up.
  1553. //
  1554. if (pszAddresses != NULL)
  1555. {
  1556. Status = CfgUtilSetWmiStringArrayParam(
  1557. spWbemInput,
  1558. L"NetworkAddresses",
  1559. (LPCWSTR *)pszAddresses,
  1560. NumAddresses
  1561. );
  1562. delete pszAddresses;
  1563. pszAddresses = NULL;
  1564. }
  1565. }
  1566. if (!pCfg->IsNlbBound())
  1567. {
  1568. //
  1569. // NLB is not bound
  1570. //
  1571. Status = CfgUtilSetWmiBoolParam(spWbemInput, L"NLBBound", FALSE);
  1572. goto end;
  1573. }
  1574. else if (!pCfg->IsValidNlbConfig())
  1575. {
  1576. printf(
  1577. "Setup update params: NLB-specific configuration on NIC %ws is invalid\n",
  1578. szNic
  1579. );
  1580. Status = WBEM_E_INVALID_PARAMETER;
  1581. goto end;
  1582. }
  1583. Status = CfgUtilSetWmiBoolParam(spWbemInput, L"NLBBound", TRUE);
  1584. if (FAILED(Status))
  1585. {
  1586. printf("Error trying to set NLBBound parameter\n");
  1587. }
  1588. //
  1589. // NLB is bound
  1590. //
  1591. CfgUtilSetWmiBoolParam(spWbemInput, L"NLBBound", TRUE);
  1592. //
  1593. // Cluster name
  1594. //
  1595. {
  1596. LPWSTR szName = NULL;
  1597. Status = pCfg->GetClusterName(&szName);
  1598. if (FAILED(Status))
  1599. {
  1600. printf(
  1601. "Setup update params: Could not extract cluster name for NIC %ws\n",
  1602. szNic
  1603. );
  1604. goto end;
  1605. }
  1606. CfgUtilSetWmiStringParam(spWbemInput, L"ClusterName", szName);
  1607. delete (szName);
  1608. szName = NULL;
  1609. }
  1610. //
  1611. // Cluster and dedicated network addresses
  1612. //
  1613. {
  1614. LPWSTR szAddress = NULL;
  1615. Status = pCfg->GetClusterNetworkAddress(&szAddress);
  1616. if (FAILED(Status))
  1617. {
  1618. printf(
  1619. "Setup update params: Could not extract cluster address for NIC %ws\n",
  1620. szNic
  1621. );
  1622. goto end;
  1623. }
  1624. CfgUtilSetWmiStringParam(
  1625. spWbemInput,
  1626. L"ClusterNetworkAddress",
  1627. szAddress
  1628. );
  1629. delete (szAddress);
  1630. szAddress = NULL;
  1631. Status = pCfg->GetDedicatedNetworkAddress(&szAddress);
  1632. if (FAILED(Status))
  1633. {
  1634. printf(
  1635. "Setup update params: Could not extract dedicated address for NIC %ws\n",
  1636. szNic
  1637. );
  1638. goto end;
  1639. }
  1640. CfgUtilSetWmiStringParam(
  1641. spWbemInput,
  1642. L"DedicatedNetworkAddress",
  1643. szAddress
  1644. );
  1645. delete (szAddress);
  1646. szAddress = NULL;
  1647. }
  1648. //
  1649. // TrafficMode
  1650. //
  1651. {
  1652. LPCWSTR szMode = NULL;
  1653. switch(pCfg->GetTrafficMode())
  1654. {
  1655. case NLB_EXTENDED_CLUSTER_CONFIGURATION::TRAFFIC_MODE_UNICAST:
  1656. szMode = L"UNICAST";
  1657. break;
  1658. case NLB_EXTENDED_CLUSTER_CONFIGURATION::TRAFFIC_MODE_MULTICAST:
  1659. szMode = L"MULTICAST";
  1660. break;
  1661. case NLB_EXTENDED_CLUSTER_CONFIGURATION::TRAFFIC_MODE_IGMPMULTICAST:
  1662. szMode = L"IGMPMULTICAST";
  1663. break;
  1664. default:
  1665. assert(FALSE);
  1666. Status = WBEM_E_CRITICAL_ERROR;
  1667. goto end;
  1668. }
  1669. CfgUtilSetWmiStringParam(spWbemInput, L"TrafficMode", szMode);
  1670. }
  1671. CfgUtilSetWmiDWORDParam(
  1672. spWbemInput,
  1673. L"HostPriority",
  1674. pCfg->GetHostPriority()
  1675. );
  1676. if (pCfg->GetClusterModeOnStart() ==
  1677. NLB_EXTENDED_CLUSTER_CONFIGURATION::START_MODE_STARTED)
  1678. {
  1679. CfgUtilSetWmiBoolParam(spWbemInput, L"ClusterModeOnStart", TRUE);
  1680. }
  1681. else
  1682. {
  1683. CfgUtilSetWmiBoolParam(spWbemInput, L"ClusterModeOnStart", FALSE);
  1684. }
  1685. CfgUtilSetWmiBoolParam(
  1686. spWbemInput,
  1687. L"RemoteControlEnabled",
  1688. pCfg->GetRemoteControlEnabled()
  1689. );
  1690. //
  1691. // TODO: get port rules
  1692. // [OUT] String PortRules[],
  1693. //
  1694. Status = WBEM_NO_ERROR;
  1695. end:
  1696. wprintf(L"<-Setup update params returns 0x%08lx\n", (UINT) Status);
  1697. return Status;
  1698. }