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.

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