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.

833 lines
23 KiB

  1. #include "WLBS_Provider.h"
  2. #include "WLBS_Cluster.h"
  3. #include "ClusterWrapper.h"
  4. #include "ControlWrapper.h"
  5. #include "utils.h"
  6. #include "param.h"
  7. #include "wlbsutil.h"
  8. #include "wlbs_cluster.tmh" // for event tracing
  9. ////////////////////////////////////////////////////////////////////////////////
  10. //
  11. // CWLBS_Cluster::CWLBS_Cluster
  12. //
  13. // Purpose: Constructor
  14. //
  15. ////////////////////////////////////////////////////////////////////////////////
  16. CWLBS_Cluster::CWLBS_Cluster( CWbemServices* a_pNameSpace,
  17. IWbemObjectSink* a_pResponseHandler)
  18. : CWlbs_Root( a_pNameSpace, a_pResponseHandler )
  19. {
  20. }
  21. ////////////////////////////////////////////////////////////////////////////////
  22. //
  23. // CWLBS_Cluster::Create
  24. //
  25. // Purpose: This instantiates this class and is invoked from an array of
  26. // function pointers.
  27. //
  28. ////////////////////////////////////////////////////////////////////////////////
  29. CWlbs_Root* CWLBS_Cluster::Create
  30. (
  31. CWbemServices* a_pNameSpace,
  32. IWbemObjectSink* a_pResponseHandler
  33. )
  34. {
  35. g_pWlbsControl->CheckMembership();
  36. CWlbs_Root* pRoot = new CWLBS_Cluster( a_pNameSpace, a_pResponseHandler );
  37. if( !pRoot )
  38. throw _com_error( WBEM_E_OUT_OF_MEMORY );
  39. return pRoot;
  40. }
  41. ////////////////////////////////////////////////////////////////////////////////
  42. //
  43. // CWLBS_Cluster::GetInstance
  44. //
  45. // Purpose: This function retrieves an instance of a MOF Cluster class.
  46. //
  47. ////////////////////////////////////////////////////////////////////////////////
  48. HRESULT CWLBS_Cluster::GetInstance
  49. (
  50. const ParsedObjectPath* a_pParsedPath,
  51. long /*a_lFlags*/,
  52. IWbemContext* a_pIContex
  53. )
  54. {
  55. IWbemClassObject* pWlbsInstance = NULL;
  56. HRESULT hRes = 0;
  57. try {
  58. //get the name key property and convert to wstring
  59. //throws _com_error
  60. const WCHAR* wstrRequestedClusterName = (*a_pParsedPath->m_paKeys)->m_vValue.bstrVal;
  61. DWORD dwNumHosts = 0;
  62. //check to see if the requested cluster name matches the configured value
  63. // The name does not have host id in it.
  64. DWORD dwClusterIpOrIndex = IpAddressFromAbcdWsz(wstrRequestedClusterName);
  65. CWlbsClusterWrapper* pCluster = g_pWlbsControl->GetClusterFromIpOrIndex(dwClusterIpOrIndex);
  66. if (pCluster == NULL)
  67. throw _com_error( WBEM_E_NOT_FOUND );
  68. BOOL bGetStatus = TRUE;
  69. //this is an optimization check
  70. //if WinMgMt is calling this prior to an Exec call, then this
  71. //routine will not perform a cluster query call since the
  72. //status of the cluster is not required in this case
  73. if (a_pIContex) {
  74. VARIANT v;
  75. VariantInit( &v );
  76. HRESULT hRes = a_pIContex->GetValue(L"__GET_EXT_KEYS_ONLY", 0, &v);
  77. if ( FAILED( hRes ) ) {
  78. throw _com_error( WBEM_E_FAILED );
  79. }
  80. bGetStatus = FALSE;
  81. // CLD: Need to check return code for error
  82. if (S_OK != VariantClear( &v ))
  83. throw _com_error( WBEM_E_FAILED );
  84. }
  85. //call the API query function
  86. //dwStatus contains a cluster-wide status number
  87. DWORD dwStatus = 0;
  88. if ( bGetStatus )
  89. {
  90. dwStatus = g_pWlbsControl->Query( pCluster ,
  91. WLBS_ALL_HOSTS ,
  92. NULL ,
  93. &dwNumHosts ,
  94. NULL );
  95. if( !ClusterStatusOK( dwStatus ) )
  96. throw _com_error( WBEM_E_FAILED );
  97. }
  98. //get the Wbem class instance
  99. SpawnInstance( MOF_CLUSTER::szName, &pWlbsInstance );
  100. //Convert status to string description
  101. FillWbemInstance( pWlbsInstance, pCluster, dwStatus );
  102. //Send results to Wbem
  103. m_pResponseHandler->Indicate( 1, &pWlbsInstance );
  104. if( pWlbsInstance ) {
  105. pWlbsInstance->Release();
  106. pWlbsInstance = NULL;
  107. }
  108. m_pResponseHandler->SetStatus( 0, WBEM_S_NO_ERROR, NULL, NULL );
  109. hRes = WBEM_S_NO_ERROR;
  110. }
  111. catch(CErrorWlbsControl Err) {
  112. IWbemClassObject* pWbemExtStat = NULL;
  113. CreateExtendedStatus( m_pNameSpace,
  114. &pWbemExtStat,
  115. Err.Error(),
  116. (PWCHAR)(Err.Description()) );
  117. m_pResponseHandler->SetStatus(0, WBEM_E_FAILED, NULL, pWbemExtStat);
  118. if( pWbemExtStat )
  119. pWbemExtStat->Release();
  120. if( pWlbsInstance ) {
  121. pWlbsInstance->Release();
  122. pWlbsInstance = NULL;
  123. }
  124. //do not return WBEM_E_FAILED, this causes a race condition
  125. hRes = WBEM_S_NO_ERROR;
  126. }
  127. catch(_com_error HResErr ) {
  128. m_pResponseHandler->SetStatus(0, HResErr.Error(), NULL, NULL);
  129. if( pWlbsInstance ) {
  130. pWlbsInstance->Release();
  131. pWlbsInstance = NULL;
  132. }
  133. hRes = HResErr.Error();
  134. //transform Win32 error to a WBEM error
  135. if( hRes == ERROR_FILE_NOT_FOUND )
  136. hRes = WBEM_E_NOT_FOUND;
  137. }
  138. catch(...) {
  139. if( pWlbsInstance ) {
  140. pWlbsInstance->Release();
  141. pWlbsInstance = NULL;
  142. }
  143. throw;
  144. }
  145. return hRes;
  146. }
  147. ////////////////////////////////////////////////////////////////////////////////
  148. //
  149. // CWLBS_Cluster::EnumInstances
  150. //
  151. // Purpose: This function determines if the current host is in the cluster
  152. // and then obtains the configuration information for the cluster.
  153. //
  154. ////////////////////////////////////////////////////////////////////////////////
  155. HRESULT CWLBS_Cluster::EnumInstances
  156. (
  157. BSTR /*a_bstrClass*/,
  158. long /*a_lFlags*/,
  159. IWbemContext* a_pIContex
  160. )
  161. {
  162. IWbemClassObject* pWlbsInstance = NULL;
  163. HRESULT hRes = 0;
  164. try {
  165. DWORD dwNumClusters = 0;
  166. CWlbsClusterWrapper** ppCluster = NULL;
  167. g_pWlbsControl->EnumClusters(ppCluster, &dwNumClusters);
  168. if (dwNumClusters == 0)
  169. {
  170. throw _com_error( WBEM_E_NOT_FOUND );
  171. }
  172. BOOL bGetStatus = TRUE;
  173. //this is an optimization check
  174. //if WinMgMt is calling this prior to an Exec call, then this
  175. //routine will not perform a cluster query call since the
  176. //status of the cluster is not required in this case
  177. if (a_pIContex) {
  178. VARIANT v;
  179. VariantInit( &v );
  180. HRESULT hRes = a_pIContex->GetValue(L"__GET_EXT_KEYS_ONLY", 0, &v);
  181. if ( FAILED( hRes ) ) {
  182. throw _com_error( WBEM_E_FAILED );
  183. }
  184. bGetStatus = FALSE;
  185. // CLD: Need to check return code for error
  186. if (S_OK != VariantClear( &v ))
  187. throw _com_error( WBEM_E_FAILED );
  188. }
  189. for (DWORD i=0; i<dwNumClusters; i++)
  190. {
  191. //call the API query function
  192. //dwStatus contains a cluster-wide status number
  193. DWORD dwStatus = 0;
  194. if ( bGetStatus )
  195. {
  196. DWORD dwNumHosts = 0;
  197. try {
  198. dwStatus = g_pWlbsControl->Query( ppCluster[i],
  199. WLBS_ALL_HOSTS ,
  200. NULL ,
  201. &dwNumHosts ,
  202. NULL);
  203. } catch (CErrorWlbsControl Err)
  204. {
  205. //
  206. // Skip this cluster
  207. //
  208. TRACE_ERROR1("CWLBS_Cluster::EnumInstances skiped cluster %x",
  209. ppCluster[i]->GetClusterIP());
  210. continue;
  211. }
  212. if( !ClusterStatusOK( dwStatus ) )
  213. {
  214. //
  215. // Skip this cluster
  216. //
  217. TRACE_ERROR1("CWLBS_Cluster::EnumInstances skiped cluster %x",
  218. ppCluster[i]->GetClusterIP());
  219. continue;
  220. }
  221. }
  222. //get the Wbem class instance
  223. SpawnInstance( MOF_CLUSTER::szName, &pWlbsInstance );
  224. //Convert status to string description
  225. FillWbemInstance( pWlbsInstance, ppCluster[i], dwStatus );
  226. //send the results back to WinMgMt
  227. m_pResponseHandler->Indicate( 1, &pWlbsInstance );
  228. if( pWlbsInstance )
  229. pWlbsInstance->Release();
  230. }
  231. m_pResponseHandler->SetStatus( 0, WBEM_S_NO_ERROR, NULL, NULL );
  232. hRes = WBEM_S_NO_ERROR;
  233. }
  234. catch(CErrorWlbsControl Err) {
  235. IWbemClassObject* pWbemExtStat = NULL;
  236. CreateExtendedStatus( m_pNameSpace,
  237. &pWbemExtStat,
  238. Err.Error(),
  239. (PWCHAR)(Err.Description()) );
  240. m_pResponseHandler->SetStatus(0, WBEM_E_FAILED, NULL, pWbemExtStat);
  241. if( pWbemExtStat )
  242. pWbemExtStat->Release();
  243. if( pWlbsInstance )
  244. pWlbsInstance->Release();
  245. //do not return WBEM_E_FAILED, this causes a race condition
  246. hRes = WBEM_S_NO_ERROR;
  247. }
  248. catch( _com_error HResErr ) {
  249. m_pResponseHandler->SetStatus(0, HResErr.Error(), NULL, NULL);
  250. if( pWlbsInstance )
  251. {
  252. pWlbsInstance->Release();
  253. pWlbsInstance = NULL;
  254. }
  255. hRes = HResErr.Error();
  256. //transform Win32 error to a WBEM error
  257. if( hRes == ERROR_FILE_NOT_FOUND )
  258. hRes = WBEM_E_NOT_FOUND ;
  259. }
  260. catch(...) {
  261. if( pWlbsInstance )
  262. {
  263. pWlbsInstance->Release();
  264. pWlbsInstance = NULL;
  265. }
  266. throw;
  267. }
  268. return hRes;
  269. }
  270. ////////////////////////////////////////////////////////////////////////////////
  271. //
  272. // CWLBS_Cluster::ExecMethod
  273. //
  274. // Purpose: This executes the methods associated with the MOF
  275. // Cluster class.
  276. //
  277. ////////////////////////////////////////////////////////////////////////////////
  278. HRESULT CWLBS_Cluster::ExecMethod
  279. (
  280. const ParsedObjectPath* a_pParsedPath,
  281. const BSTR& a_strMethodName,
  282. long /*a_lFlags*/,
  283. IWbemContext* /*a_pIContex*/,
  284. IWbemClassObject* a_pIInParams
  285. )
  286. {
  287. IWbemClassObject* pOutputInstance = NULL;
  288. HRESULT hRes = 0;
  289. BSTR strPortNumber = NULL;
  290. BSTR strNumNodes = NULL;
  291. VARIANT vValue;
  292. CNodeConfiguration NodeConfig;
  293. VariantInit( &vValue );
  294. TRACE_VERB(L"-> CWLBS_Cluster::ExecMethod(%ws)", (WCHAR *) a_strMethodName);
  295. try {
  296. CWlbsClusterWrapper* pCluster = NULL;
  297. if (a_pParsedPath->m_paKeys == NULL)
  298. {
  299. //
  300. // No cluster IP specified
  301. //
  302. throw _com_error( WBEM_E_INVALID_PARAMETER );
  303. }
  304. else
  305. {
  306. const wchar_t* wstrRequestedClusterName = (*a_pParsedPath->m_paKeys)->m_vValue.bstrVal;
  307. //check to see if the requested cluster name matches the configured value
  308. // The name does not have host id in it.
  309. DWORD dwClusterIpOrIndex = IpAddressFromAbcdWsz(wstrRequestedClusterName);
  310. pCluster = g_pWlbsControl->GetClusterFromIpOrIndex(dwClusterIpOrIndex);
  311. }
  312. if (pCluster == NULL)
  313. throw _com_error( WBEM_E_NOT_FOUND );
  314. DWORD dwNumHosts = WLBS_MAX_HOSTS;
  315. DWORD dwReturnValue;
  316. DWORD dwClustIP;
  317. strPortNumber = SysAllocString( MOF_PARAM::PORT_NUMBER );
  318. strNumNodes = SysAllocString( MOF_PARAM::NUM_NODES );
  319. if( !strPortNumber || !strNumNodes )
  320. throw _com_error( WBEM_E_OUT_OF_MEMORY );
  321. dwClustIP = pCluster->GetClusterIpOrIndex(g_pWlbsControl);
  322. //get the output object instance
  323. GetMethodOutputInstance( MOF_CLUSTER::szName,
  324. a_strMethodName,
  325. &pOutputInstance);
  326. //*************************************************************************
  327. //
  328. //Determine and execute the MOF method
  329. //
  330. //*************************************************************************
  331. if( _wcsicmp( a_strMethodName, MOF_CLUSTER::pMethods[MOF_CLUSTER::DISABLE] ) == 0) {
  332. if( !a_pIInParams )
  333. throw _com_error( WBEM_E_INVALID_PARAMETER );
  334. // The "Disable" method does NOT take vip as a parameter, so, if there is any port rule
  335. // that is specific to a vip (other than the "all vip"), we fail this method.
  336. // The "EffectiveVersion" registry value is checked for a value of CVY_VERSION_FULL to
  337. // see of there is any port rule that is specific to a vip
  338. pCluster->GetNodeConfig(NodeConfig);
  339. if(NodeConfig.dwEffectiveVersion == CVY_VERSION_FULL)
  340. throw _com_error( WBEM_E_INVALID_OPERATION );
  341. //get the port number
  342. hRes = a_pIInParams->Get
  343. ( strPortNumber,
  344. 0,
  345. &vValue,
  346. NULL,
  347. NULL
  348. );
  349. if( FAILED( hRes ) )
  350. throw _com_error( hRes );
  351. //range checking is done by the API
  352. if( vValue.vt != VT_I4 )
  353. throw _com_error( WBEM_E_INVALID_PARAMETER );
  354. //call Disable method
  355. dwReturnValue = g_pWlbsControl->Disable
  356. (
  357. dwClustIP,
  358. WLBS_ALL_HOSTS,
  359. NULL,
  360. dwNumHosts,
  361. IpAddressFromAbcdWsz(CVY_DEF_ALL_VIP), // "All Vip"
  362. vValue.lVal
  363. );
  364. } else if(_wcsicmp( a_strMethodName, MOF_CLUSTER::pMethods[MOF_CLUSTER::ENABLE] ) == 0) {
  365. if( !a_pIInParams )
  366. throw _com_error( WBEM_E_INVALID_PARAMETER );
  367. // The "Enable" method does NOT take vip as a parameter, so, if there is any port rule
  368. // that is specific to a vip (other than the "all vip"), we fail this method.
  369. // The "EffectiveVersion" registry value is checked for a value of CVY_VERSION_FULL to
  370. // see of there is any port rule that is specific to a vip
  371. pCluster->GetNodeConfig(NodeConfig);
  372. if(NodeConfig.dwEffectiveVersion == CVY_VERSION_FULL)
  373. throw _com_error( WBEM_E_INVALID_OPERATION );
  374. //get the port number
  375. hRes = a_pIInParams->Get
  376. (
  377. strPortNumber,
  378. 0,
  379. &vValue,
  380. NULL,
  381. NULL
  382. );
  383. if( FAILED( hRes ) )
  384. throw _com_error( hRes );
  385. //range checking is done by the API
  386. if( vValue.vt != VT_I4 )
  387. throw _com_error( WBEM_E_INVALID_PARAMETER );
  388. //call Enable method
  389. dwReturnValue = g_pWlbsControl->Enable
  390. (
  391. dwClustIP,
  392. WLBS_ALL_HOSTS,
  393. NULL,
  394. dwNumHosts,
  395. IpAddressFromAbcdWsz(CVY_DEF_ALL_VIP), // "All Vip"
  396. vValue.lVal
  397. );
  398. } else if( _wcsicmp( a_strMethodName, MOF_CLUSTER::pMethods[MOF_CLUSTER::DRAIN] ) == 0 ) {
  399. if( !a_pIInParams )
  400. throw _com_error( WBEM_E_INVALID_PARAMETER );
  401. // The "Drain" method does NOT take vip as a parameter, so, if there is any port rule
  402. // that is specific to a vip (other than the "all vip"), we fail this method.
  403. // The "EffectiveVersion" registry value is checked for a value of CVY_VERSION_FULL to
  404. // see of there is any port rule that is specific to a vip
  405. pCluster->GetNodeConfig(NodeConfig);
  406. if(NodeConfig.dwEffectiveVersion == CVY_VERSION_FULL)
  407. throw _com_error( WBEM_E_INVALID_OPERATION );
  408. //get the port number
  409. hRes = a_pIInParams->Get
  410. (
  411. strPortNumber,
  412. 0,
  413. &vValue,
  414. NULL,
  415. NULL
  416. );
  417. if( FAILED( hRes ) )
  418. throw _com_error( hRes );
  419. //range checking is done by the API
  420. if( vValue.vt != VT_I4 )
  421. throw _com_error( WBEM_E_INVALID_PARAMETER );
  422. //call Drain method
  423. dwReturnValue = g_pWlbsControl->Drain
  424. (
  425. dwClustIP,
  426. WLBS_ALL_HOSTS,
  427. NULL,
  428. dwNumHosts,
  429. IpAddressFromAbcdWsz(CVY_DEF_ALL_VIP), // "All Vip"
  430. vValue.lVal
  431. );
  432. } else if(_wcsicmp(a_strMethodName, MOF_CLUSTER::pMethods[MOF_CLUSTER::DRAINSTOP]) == 0) {
  433. //call DrainStop method
  434. dwReturnValue = g_pWlbsControl->DrainStop(dwClustIP, WLBS_ALL_HOSTS, NULL, dwNumHosts);
  435. } else if(_wcsicmp(a_strMethodName, MOF_CLUSTER::pMethods[MOF_CLUSTER::RESUME] ) == 0) {
  436. //call Resume method
  437. dwReturnValue = g_pWlbsControl->Resume(dwClustIP, WLBS_ALL_HOSTS, NULL, dwNumHosts);
  438. } else if(_wcsicmp(a_strMethodName, MOF_CLUSTER::pMethods[MOF_CLUSTER::START] ) == 0) {
  439. //call Start method
  440. dwReturnValue = g_pWlbsControl->Start(dwClustIP, WLBS_ALL_HOSTS, NULL, dwNumHosts);
  441. } else if(_wcsicmp(a_strMethodName, MOF_CLUSTER::pMethods[MOF_CLUSTER::STOP] ) == 0) {
  442. //call Stop method
  443. dwReturnValue = g_pWlbsControl->Stop(dwClustIP, WLBS_ALL_HOSTS, NULL, dwNumHosts);
  444. } else if(_wcsicmp(a_strMethodName, MOF_CLUSTER::pMethods[MOF_CLUSTER::SUSPEND] ) == 0) {
  445. //call Suspend method
  446. dwReturnValue = g_pWlbsControl->Suspend(dwClustIP, WLBS_ALL_HOSTS, NULL, dwNumHosts);
  447. } else {
  448. throw _com_error( WBEM_E_METHOD_NOT_IMPLEMENTED );
  449. }
  450. //*************************************************************************
  451. //
  452. //Output Results
  453. //
  454. //*************************************************************************
  455. // CLD: Need to check return code for error
  456. if (S_OK != VariantClear( &vValue ))
  457. throw _com_error( WBEM_E_FAILED );
  458. //set the return value
  459. vValue.vt = VT_I4;
  460. vValue.lVal = static_cast<long>(dwReturnValue);
  461. hRes = pOutputInstance->Put(_bstr_t(L"ReturnValue"), 0, &vValue, 0);
  462. if( FAILED( hRes ) ) {
  463. throw _com_error( hRes );
  464. }
  465. //set the number of hosts property
  466. vValue.vt = VT_I4;
  467. vValue.lVal = static_cast<long>(dwNumHosts);
  468. hRes = pOutputInstance->Put(strNumNodes, 0, &vValue, 0);
  469. if( FAILED( hRes ) )
  470. throw _com_error( hRes );
  471. //send the results back to WinMgMt
  472. hRes = m_pResponseHandler->Indicate(1, &pOutputInstance);
  473. if( FAILED( hRes ) )
  474. throw _com_error( hRes );
  475. m_pResponseHandler->SetStatus(0, WBEM_S_NO_ERROR, NULL, NULL);
  476. //*************************************************************************
  477. //
  478. //Release Resources
  479. //
  480. //*************************************************************************
  481. //COM Interfaces
  482. if( pOutputInstance ) {
  483. pOutputInstance->Release();
  484. pOutputInstance = NULL;
  485. }
  486. //**** BSTRs ****
  487. if( strPortNumber ) {
  488. SysFreeString( strPortNumber );
  489. strPortNumber = NULL;
  490. }
  491. if( strNumNodes ) {
  492. SysFreeString( strNumNodes );
  493. strNumNodes = NULL;
  494. }
  495. //**** VARIANTs ****
  496. // CLD: Need to check return code for error
  497. if (S_OK != VariantClear( &vValue ))
  498. throw _com_error( WBEM_E_FAILED );
  499. hRes = WBEM_S_NO_ERROR;
  500. }
  501. catch(CErrorWlbsControl Err) {
  502. IWbemClassObject* pWbemExtStat = NULL;
  503. CreateExtendedStatus( m_pNameSpace,
  504. &pWbemExtStat,
  505. Err.Error(),
  506. (PWCHAR)(Err.Description()) );
  507. m_pResponseHandler->SetStatus(0, WBEM_E_FAILED, NULL, pWbemExtStat);
  508. if( pWbemExtStat )
  509. pWbemExtStat->Release();
  510. //COM Interfaces
  511. if( pOutputInstance ) {
  512. pOutputInstance->Release();
  513. pOutputInstance = NULL;
  514. }
  515. //**** BSTRs ****
  516. if( strPortNumber ) {
  517. SysFreeString( strPortNumber );
  518. strPortNumber = NULL;
  519. }
  520. if( strNumNodes ) {
  521. SysFreeString( strNumNodes );
  522. strNumNodes = NULL;
  523. }
  524. //**** VARIANTs ****
  525. // CLD: Need to check return code for error
  526. // No throw here since we are already throwing an exception. Also, given the comment below, not sure
  527. // what exception we'd return...
  528. VariantClear( &vValue );
  529. //do not return WBEM_E_FAILED, this causes a race condition
  530. hRes = WBEM_S_NO_ERROR;
  531. }
  532. catch( _com_error HResErr ) {
  533. //COM Interfaces
  534. if( pOutputInstance ) {
  535. pOutputInstance->Release();
  536. pOutputInstance = NULL;
  537. }
  538. //**** BSTRs ****
  539. if( strPortNumber ) {
  540. SysFreeString( strPortNumber );
  541. strPortNumber = NULL;
  542. }
  543. if( strNumNodes ) {
  544. SysFreeString( strNumNodes );
  545. strNumNodes = NULL;
  546. }
  547. //**** VARIANTs ****
  548. // CLD: Need to check return code for error
  549. // No throw here since we are already throwing an exception.
  550. VariantClear( &vValue );
  551. m_pResponseHandler->SetStatus(0, HResErr.Error(), NULL, NULL);
  552. hRes = HResErr.Error();
  553. }
  554. catch(...) {
  555. //COM Interfaces
  556. if( pOutputInstance ) {
  557. pOutputInstance->Release();
  558. pOutputInstance = NULL;
  559. }
  560. //**** BSTRs ****
  561. if( strPortNumber ) {
  562. SysFreeString( strPortNumber );
  563. strPortNumber = NULL;
  564. }
  565. if( strNumNodes ) {
  566. SysFreeString( strNumNodes );
  567. strNumNodes = NULL;
  568. }
  569. //**** VARIANTs ****
  570. // CLD: Need to check return code for error
  571. // No throw here since we are already throwing an exception
  572. VariantClear( &vValue );
  573. throw;
  574. }
  575. TRACE_VERB(L"<- CWLBS_Cluster::ExecMethod(%ws) returns 0x%08lx",
  576. (WCHAR *) a_strMethodName, (UINT) hRes);
  577. return hRes;
  578. }
  579. ////////////////////////////////////////////////////////////////////////////////
  580. //
  581. // CWLBS_Cluster::FillWbemInstance
  582. //
  583. // Purpose: This function copies all of the data from a cluster configuration
  584. // structure to a WBEM instance.
  585. //
  586. ////////////////////////////////////////////////////////////////////////////////
  587. void CWLBS_Cluster::FillWbemInstance
  588. (
  589. IWbemClassObject* a_pWbemInstance,
  590. CWlbsClusterWrapper* pCluster,
  591. const DWORD a_dwStatus
  592. )
  593. {
  594. namespace CLUSTER = MOF_CLUSTER;
  595. ASSERT( a_pWbemInstance );
  596. ASSERT(pCluster);
  597. CClusterConfiguration ClusterConfig;
  598. pCluster->GetClusterConfig( ClusterConfig );
  599. //InterconnectAddress
  600. wstring wstrClusterIp;
  601. AddressToString( pCluster->GetClusterIP(), wstrClusterIp );
  602. a_pWbemInstance->Put
  603. (
  604. _bstr_t( CLUSTER::pProperties[CLUSTER::IPADDRESS] ),
  605. 0 ,
  606. &_variant_t(wstrClusterIp.c_str()),
  607. NULL
  608. );
  609. //Name
  610. wstring wstrClusterIndex;
  611. AddressToString( pCluster->GetClusterIpOrIndex(g_pWlbsControl), wstrClusterIndex );
  612. a_pWbemInstance->Put
  613. (
  614. _bstr_t( CLUSTER::pProperties[CLUSTER::NAME] ),
  615. 0 ,
  616. &_variant_t(wstrClusterIndex.c_str()),
  617. NULL
  618. );
  619. //MaxNodes
  620. a_pWbemInstance->Put
  621. (
  622. _bstr_t( CLUSTER::pProperties[CLUSTER::MAXNODES] ),
  623. 0 ,
  624. &_variant_t(ClusterConfig.nMaxNodes),
  625. NULL
  626. );
  627. //ClusterState
  628. a_pWbemInstance->Put
  629. (
  630. _bstr_t( CLUSTER::pProperties[CLUSTER::CLUSSTATE] ),
  631. 0 ,
  632. &_variant_t((short)a_dwStatus),
  633. NULL
  634. );
  635. //CREATCLASS
  636. a_pWbemInstance->Put
  637. (
  638. _bstr_t( CLUSTER::pProperties[CLUSTER::CREATCLASS] ),
  639. 0 ,
  640. &_variant_t(CLUSTER::szName),
  641. NULL
  642. );
  643. }