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.

1063 lines
28 KiB

  1. #include "WLBS_Provider.h"
  2. #include "WLBS_Node.h"
  3. #include "ClusterWrapper.h"
  4. #include "ControlWrapper.h"
  5. #include "utils.h"
  6. #include "wlbsutil.h"
  7. ////////////////////////////////////////////////////////////////////////////////
  8. //
  9. // CWLBS_Node::CWLBS_Node
  10. //
  11. // Purpose: Constructor
  12. //
  13. ////////////////////////////////////////////////////////////////////////////////
  14. CWLBS_Node::CWLBS_Node(CWbemServices* a_pNameSpace,
  15. IWbemObjectSink* a_pResponseHandler)
  16. : CWlbs_Root( a_pNameSpace, a_pResponseHandler )
  17. {
  18. }
  19. ////////////////////////////////////////////////////////////////////////////////
  20. //
  21. // CWLBS_Node::Create
  22. //
  23. // Purpose: This instantiates this class and is invoked from an array of
  24. // function pointers.
  25. //
  26. ////////////////////////////////////////////////////////////////////////////////
  27. CWlbs_Root* CWLBS_Node::Create
  28. (
  29. CWbemServices* a_pNameSpace,
  30. IWbemObjectSink* a_pResponseHandler
  31. )
  32. {
  33. g_pWlbsControl->CheckMembership();
  34. CWlbs_Root* pRoot = new CWLBS_Node( a_pNameSpace, a_pResponseHandler );
  35. if( !pRoot )
  36. throw _com_error( WBEM_E_OUT_OF_MEMORY );
  37. return pRoot;
  38. }
  39. ////////////////////////////////////////////////////////////////////////////////
  40. //
  41. // CWLBS_Node::GetInstance
  42. //
  43. // Purpose: Queries WLBS for desired node instance and sends results back
  44. // to WinMgMt.
  45. //
  46. ////////////////////////////////////////////////////////////////////////////////
  47. HRESULT CWLBS_Node::GetInstance
  48. (
  49. const ParsedObjectPath* a_pParsedPath,
  50. long /* a_lFlags */,
  51. IWbemContext* /* a_pIContex */
  52. )
  53. {
  54. IWbemClassObject* pWlbsInstance = NULL;
  55. HRESULT hRes = 0;
  56. try {
  57. //g_pWlbsControl->CheckConfiguration();
  58. //get the node
  59. FindInstance( &pWlbsInstance, a_pParsedPath );
  60. //send the results back to WinMgMt
  61. m_pResponseHandler->Indicate( 1, &pWlbsInstance );
  62. if( pWlbsInstance ) {
  63. pWlbsInstance->Release();
  64. pWlbsInstance = NULL;
  65. }
  66. m_pResponseHandler->SetStatus( 0, WBEM_S_NO_ERROR, NULL, NULL );
  67. hRes = WBEM_S_NO_ERROR;
  68. }
  69. catch(CErrorWlbsControl Err) {
  70. IWbemClassObject* pWbemExtStat = NULL;
  71. CreateExtendedStatus( m_pNameSpace,
  72. &pWbemExtStat,
  73. Err.Error(),
  74. (PWCHAR)(Err.Description()) );
  75. m_pResponseHandler->SetStatus(0, WBEM_E_FAILED, NULL, pWbemExtStat);
  76. if( pWbemExtStat )
  77. pWbemExtStat->Release();
  78. if( pWlbsInstance )
  79. pWlbsInstance->Release();
  80. //do not return WBEM_E_FAILED, this causes a race condition
  81. hRes = WBEM_S_NO_ERROR;
  82. }
  83. catch(_com_error HResErr ) {
  84. m_pResponseHandler->SetStatus(0, HResErr.Error(), NULL, NULL);
  85. if( pWlbsInstance )
  86. pWlbsInstance->Release();
  87. hRes = HResErr.Error();
  88. }
  89. catch(...) {
  90. if( pWlbsInstance ) {
  91. pWlbsInstance->Release();
  92. pWlbsInstance = NULL;
  93. }
  94. throw;
  95. }
  96. return hRes;
  97. }
  98. ////////////////////////////////////////////////////////////////////////////////
  99. //
  100. // CWLBS_Node::EnumInstances
  101. //
  102. // Purpose: Executes a WlbsQuery and sends data back to WinMgMt.
  103. //
  104. ////////////////////////////////////////////////////////////////////////////////
  105. HRESULT CWLBS_Node::EnumInstances
  106. (
  107. BSTR /* a_bstrClass */,
  108. long /* a_lFlags */,
  109. IWbemContext* /* a_pIContex */
  110. )
  111. {
  112. IWbemClassObject** ppWlbsInstance = NULL;
  113. WLBS_RESPONSE* pResponse = NULL;
  114. HRESULT hRes = 0;
  115. BSTR strClassName = NULL;
  116. long nNumNodes = 0;
  117. //g_pWlbsControl->CheckConfiguration();
  118. try {
  119. strClassName = SysAllocString( MOF_NODE::szName );
  120. if( !strClassName )
  121. throw _com_error( WBEM_E_OUT_OF_MEMORY );
  122. //declare an IWbemClassObject smart pointer
  123. IWbemClassObjectPtr pWlbsNodeClass;
  124. //get the MOF class object
  125. hRes = m_pNameSpace->GetObject(
  126. strClassName,
  127. 0,
  128. NULL,
  129. &pWlbsNodeClass,
  130. NULL );
  131. if( FAILED( hRes ) ) {
  132. throw _com_error( hRes );
  133. }
  134. DWORD dwNumClusters = 0;
  135. CWlbsClusterWrapper** ppCluster = NULL;
  136. g_pWlbsControl->EnumClusters(ppCluster, &dwNumClusters);
  137. if (dwNumClusters == 0)
  138. {
  139. throw _com_error( WBEM_E_NOT_FOUND );
  140. }
  141. for (DWORD iCluster=0; iCluster<dwNumClusters; iCluster++)
  142. {
  143. //call the API query function to find the nodes
  144. try {
  145. FindAllInstances(ppCluster[iCluster], &pResponse, nNumNodes );
  146. } catch (CErrorWlbsControl Err)
  147. {
  148. //
  149. // Skip this cluster
  150. //
  151. TRACE_ERROR1("CWLBS_Node::EnumInstances skiped cluster %x",
  152. ppCluster[iCluster]->GetClusterIP());
  153. continue;
  154. }
  155. //spawn an instance of the Node MOF class for each node found
  156. ppWlbsInstance = new IWbemClassObject *[nNumNodes];
  157. if( !ppWlbsInstance )
  158. throw _com_error( WBEM_E_OUT_OF_MEMORY );
  159. //initialize array
  160. ZeroMemory( ppWlbsInstance, nNumNodes * sizeof(IWbemClassObject *) );
  161. for(int i = 0; i < nNumNodes; i ++ ) {
  162. hRes = pWlbsNodeClass->SpawnInstance( 0, &ppWlbsInstance[i] );
  163. if( FAILED( hRes ) )
  164. throw _com_error( hRes );
  165. FillWbemInstance(ppCluster[iCluster], ppWlbsInstance[i], pResponse + i );
  166. }
  167. //send the results back to WinMgMt
  168. hRes = m_pResponseHandler->Indicate( nNumNodes, ppWlbsInstance );
  169. if( FAILED( hRes ) ) {
  170. throw _com_error( hRes );
  171. }
  172. if( ppWlbsInstance ) {
  173. for( i = 0; i < nNumNodes; i++ ) {
  174. if( ppWlbsInstance[i] ) {
  175. ppWlbsInstance[i]->Release();
  176. }
  177. }
  178. delete [] ppWlbsInstance;
  179. }
  180. if( pResponse )
  181. delete [] pResponse;
  182. }
  183. if( strClassName )
  184. SysFreeString(strClassName);
  185. m_pResponseHandler->SetStatus( 0, WBEM_S_NO_ERROR, NULL, NULL );
  186. hRes = WBEM_S_NO_ERROR;
  187. }
  188. catch(CErrorWlbsControl Err) {
  189. IWbemClassObject* pWbemExtStat = NULL;
  190. CreateExtendedStatus( m_pNameSpace,
  191. &pWbemExtStat,
  192. Err.Error(),
  193. (PWCHAR)(Err.Description()) );
  194. m_pResponseHandler->SetStatus(0, WBEM_E_FAILED, NULL, pWbemExtStat);
  195. if( pWbemExtStat )
  196. pWbemExtStat->Release();
  197. if( strClassName )
  198. SysFreeString( strClassName );
  199. if( ppWlbsInstance ) {
  200. for(int i = 0; i < nNumNodes; i++ ) {
  201. if( ppWlbsInstance[i] ) {
  202. ppWlbsInstance[i]->Release();
  203. }
  204. }
  205. delete [] ppWlbsInstance;
  206. }
  207. if( pResponse )
  208. delete [] pResponse;
  209. //do not return WBEM_E_FAILED, this causes a race condition
  210. hRes = WBEM_S_NO_ERROR;
  211. }
  212. catch(_com_error HResErr ) {
  213. m_pResponseHandler->SetStatus(0, HResErr.Error(), NULL, NULL);
  214. if( strClassName )
  215. SysFreeString( strClassName );
  216. if( ppWlbsInstance ) {
  217. for(int i = 0; i < nNumNodes; i++ ) {
  218. if( ppWlbsInstance[i] ) {
  219. ppWlbsInstance[i]->Release();
  220. }
  221. }
  222. delete [] ppWlbsInstance;
  223. }
  224. if( pResponse )
  225. delete [] pResponse;
  226. hRes = HResErr.Error();
  227. }
  228. catch(...) {
  229. if( strClassName )
  230. SysFreeString( strClassName );
  231. if( ppWlbsInstance ) {
  232. for(int i = 0; i < nNumNodes; i++ ) {
  233. if( ppWlbsInstance[i] ) {
  234. ppWlbsInstance[i]->Release();
  235. }
  236. }
  237. delete [] ppWlbsInstance;
  238. }
  239. if( pResponse )
  240. delete [] pResponse;
  241. throw;
  242. }
  243. return hRes;
  244. }
  245. ////////////////////////////////////////////////////////////////////////////////
  246. //
  247. // CWLBS_Node::ExecMethod
  248. //
  249. // Purpose: This executes the methods associated with the MOF
  250. // Node class.
  251. //
  252. ////////////////////////////////////////////////////////////////////////////////
  253. HRESULT CWLBS_Node::ExecMethod
  254. (
  255. const ParsedObjectPath* a_pParsedPath,
  256. const BSTR& a_strMethodName,
  257. long /* a_lFlags */,
  258. IWbemContext* /* a_pIContex */,
  259. IWbemClassObject* a_pIInParams
  260. )
  261. {
  262. DWORD dwNumHosts = 1;
  263. DWORD dwReturnValue;
  264. HRESULT hRes = 0;
  265. _variant_t vMofResponse;
  266. _variant_t vReturnValue;
  267. _variant_t vVip, vInputPortNumber;
  268. CNodeConfiguration NodeConfig;
  269. DWORD dwVip, dwPort;
  270. VARIANT vValue;
  271. BSTR strPortNumber = NULL;
  272. IWbemClassObject* pOutputInstance = NULL;
  273. try {
  274. strPortNumber = SysAllocString( MOF_PARAM::PORT_NUMBER );
  275. if( !strPortNumber )
  276. throw _com_error( WBEM_E_OUT_OF_MEMORY );
  277. //get the host ID address
  278. DWORD dwHostID = 0;
  279. DWORD dwClusterIpOrIndex = 0;
  280. dwHostID = ExtractHostID( wstring( (*a_pParsedPath->m_paKeys)->m_vValue.bstrVal ) );
  281. if ((DWORD)-1 == dwHostID)
  282. throw _com_error( WBEM_E_NOT_FOUND );
  283. dwClusterIpOrIndex = ExtractClusterIP( wstring( (*a_pParsedPath->m_paKeys)->m_vValue.bstrVal ) );
  284. if ((DWORD)-1 == dwClusterIpOrIndex)
  285. throw _com_error( WBEM_E_NOT_FOUND );
  286. CWlbsClusterWrapper* pCluster = g_pWlbsControl->GetClusterFromIpOrIndex(dwClusterIpOrIndex);
  287. if (pCluster == NULL)
  288. throw _com_error( WBEM_E_NOT_FOUND );
  289. //always let the provider peform control operations on the local host
  290. if( dwHostID == pCluster->GetHostID() )
  291. dwHostID = WLBS_LOCAL_HOST;
  292. //get the output object instance
  293. GetMethodOutputInstance( MOF_NODE::szName,
  294. a_strMethodName,
  295. &pOutputInstance );
  296. //determine and execute the MOF method
  297. if( _wcsicmp(a_strMethodName, MOF_NODE::pMethods[MOF_NODE::DISABLE] ) == 0) {
  298. if( !a_pIInParams )
  299. throw _com_error( WBEM_E_INVALID_PARAMETER );
  300. // The "Disable" method does NOT take vip as a parameter, so, if there is any port rule
  301. // that is specific to a vip (other than the "all vip"), we fail this method.
  302. // The "EffectiveVersion" registry value is checked for a value of CVY_VERSION_FULL to
  303. // see of there is any port rule that is specific to a vip
  304. pCluster->GetNodeConfig(NodeConfig);
  305. if(NodeConfig.dwEffectiveVersion == CVY_VERSION_FULL)
  306. throw _com_error( WBEM_E_INVALID_OPERATION );
  307. //get the port number
  308. hRes = a_pIInParams->Get
  309. ( strPortNumber,
  310. 0,
  311. &vInputPortNumber,
  312. NULL,
  313. NULL
  314. );
  315. if( FAILED( hRes ) ) {
  316. throw _com_error( hRes );
  317. }
  318. //make sure the port number is not NULL
  319. if( vInputPortNumber.vt != VT_I4)
  320. throw _com_error( WBEM_E_INVALID_PARAMETER );
  321. //call Disable method
  322. dwReturnValue = g_pWlbsControl->Disable
  323. (
  324. pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  325. dwHostID,
  326. NULL,
  327. dwNumHosts,
  328. IpAddressFromAbcdWsz(CVY_DEF_ALL_VIP), // "All Vip"
  329. (long)vInputPortNumber
  330. );
  331. } else if(_wcsicmp(a_strMethodName, MOF_NODE::pMethods[MOF_NODE::ENABLE] ) == 0) {
  332. if( !a_pIInParams )
  333. throw _com_error( WBEM_E_INVALID_PARAMETER );
  334. // The "Enable" 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. (
  344. strPortNumber,
  345. 0,
  346. &vInputPortNumber,
  347. NULL,
  348. NULL
  349. );
  350. if( FAILED( hRes ) ) {
  351. throw _com_error( hRes );
  352. }
  353. if( vInputPortNumber.vt != VT_I4)
  354. throw _com_error(WBEM_E_INVALID_PARAMETER);
  355. //call Enable method
  356. dwReturnValue = g_pWlbsControl->Enable
  357. (
  358. pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  359. dwHostID,
  360. NULL,
  361. dwNumHosts,
  362. IpAddressFromAbcdWsz(CVY_DEF_ALL_VIP), // "All Vip"
  363. (long)vInputPortNumber
  364. );
  365. } else if(_wcsicmp(a_strMethodName, MOF_NODE::pMethods[MOF_NODE::DRAIN] ) == 0) {
  366. if( !a_pIInParams )
  367. throw _com_error( WBEM_E_INVALID_PARAMETER );
  368. // The "Drain" method does NOT take vip as a parameter, so, if there is any port rule
  369. // that is specific to a vip (other than the "all vip"), we fail this method.
  370. // The "EffectiveVersion" registry value is checked for a value of CVY_VERSION_FULL to
  371. // see of there is any port rule that is specific to a vip
  372. pCluster->GetNodeConfig(NodeConfig);
  373. if(NodeConfig.dwEffectiveVersion == CVY_VERSION_FULL)
  374. throw _com_error( WBEM_E_INVALID_OPERATION );
  375. //get the port number
  376. hRes = a_pIInParams->Get
  377. (
  378. strPortNumber,
  379. 0,
  380. &vInputPortNumber,
  381. NULL,
  382. NULL
  383. );
  384. if( FAILED( hRes ) ) {
  385. throw _com_error( hRes );
  386. }
  387. if( vInputPortNumber.vt != VT_I4)
  388. throw _com_error(WBEM_E_INVALID_PARAMETER);
  389. //call Drain method
  390. dwReturnValue = g_pWlbsControl->Drain
  391. (
  392. pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  393. dwHostID,
  394. NULL,
  395. dwNumHosts,
  396. IpAddressFromAbcdWsz(CVY_DEF_ALL_VIP), // "All Vip"
  397. (long)vInputPortNumber
  398. );
  399. }else if( _wcsicmp( a_strMethodName, MOF_CLUSTER::pMethods[MOF_CLUSTER::DISABLE_EX] ) == 0) {
  400. if( !a_pIInParams )
  401. throw _com_error( WBEM_E_INVALID_PARAMETER );
  402. //get the vip
  403. hRes = a_pIInParams->Get
  404. (
  405. _bstr_t( MOF_PARAM::VIP ),
  406. 0,
  407. &vValue,
  408. NULL,
  409. NULL
  410. );
  411. if( vValue.vt != VT_BSTR )
  412. throw _com_error ( WBEM_E_INVALID_PARAMETER );
  413. dwVip = IpAddressFromAbcdWsz( vValue.bstrVal );
  414. //get the port number
  415. hRes = a_pIInParams->Get
  416. ( strPortNumber,
  417. 0,
  418. &vValue,
  419. NULL,
  420. NULL
  421. );
  422. if( FAILED( hRes ) )
  423. throw _com_error( hRes );
  424. //range checking is done by the API
  425. if( vValue.vt != VT_I4 )
  426. throw _com_error( WBEM_E_INVALID_PARAMETER );
  427. dwPort = vValue.lVal;
  428. //call Disable method
  429. dwReturnValue = g_pWlbsControl->Disable
  430. (
  431. pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  432. dwHostID,
  433. NULL,
  434. dwNumHosts,
  435. dwVip,
  436. dwPort
  437. );
  438. } else if(_wcsicmp( a_strMethodName, MOF_CLUSTER::pMethods[MOF_CLUSTER::ENABLE_EX] ) == 0) {
  439. if( !a_pIInParams )
  440. throw _com_error( WBEM_E_INVALID_PARAMETER );
  441. //get the vip
  442. hRes = a_pIInParams->Get
  443. (
  444. _bstr_t( MOF_PARAM::VIP ),
  445. 0,
  446. &vValue,
  447. NULL,
  448. NULL
  449. );
  450. if( vValue.vt != VT_BSTR )
  451. throw _com_error ( WBEM_E_INVALID_PARAMETER );
  452. dwVip = IpAddressFromAbcdWsz( vValue.bstrVal );
  453. //get the port number
  454. hRes = a_pIInParams->Get
  455. (
  456. strPortNumber,
  457. 0,
  458. &vValue,
  459. NULL,
  460. NULL
  461. );
  462. if( FAILED( hRes ) )
  463. throw _com_error( hRes );
  464. //range checking is done by the API
  465. if( vValue.vt != VT_I4 )
  466. throw _com_error( WBEM_E_INVALID_PARAMETER );
  467. dwPort = vValue.lVal;
  468. //call Enable method
  469. dwReturnValue = g_pWlbsControl->Enable
  470. (
  471. pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  472. dwHostID,
  473. NULL,
  474. dwNumHosts,
  475. dwVip,
  476. dwPort
  477. );
  478. } else if( _wcsicmp( a_strMethodName, MOF_CLUSTER::pMethods[MOF_CLUSTER::DRAIN_EX] ) == 0 ) {
  479. if( !a_pIInParams )
  480. throw _com_error( WBEM_E_INVALID_PARAMETER );
  481. //get the vip
  482. hRes = a_pIInParams->Get
  483. (
  484. _bstr_t( MOF_PARAM::VIP ),
  485. 0,
  486. &vValue,
  487. NULL,
  488. NULL
  489. );
  490. if( vValue.vt != VT_BSTR )
  491. throw _com_error ( WBEM_E_INVALID_PARAMETER );
  492. dwVip = IpAddressFromAbcdWsz( vValue.bstrVal );
  493. //get the port number
  494. hRes = a_pIInParams->Get
  495. (
  496. strPortNumber,
  497. 0,
  498. &vValue,
  499. NULL,
  500. NULL
  501. );
  502. if( FAILED( hRes ) )
  503. throw _com_error( hRes );
  504. //range checking is done by the API
  505. if( vValue.vt != VT_I4 )
  506. throw _com_error( WBEM_E_INVALID_PARAMETER );
  507. dwPort = vValue.lVal;
  508. //call Drain method
  509. dwReturnValue = g_pWlbsControl->Drain
  510. (
  511. pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  512. dwHostID,
  513. NULL,
  514. dwNumHosts,
  515. dwVip,
  516. dwPort
  517. );
  518. } else if(_wcsicmp(a_strMethodName, MOF_NODE::pMethods[MOF_NODE::DRAINSTOP]) == 0) {
  519. //call DrainStop method
  520. dwReturnValue = g_pWlbsControl->DrainStop( pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  521. dwHostID, NULL, dwNumHosts);
  522. } else if(_wcsicmp(a_strMethodName, MOF_NODE::pMethods[MOF_NODE::RESUME] ) == 0) {
  523. //call Resume method
  524. dwReturnValue = g_pWlbsControl->Resume( pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  525. dwHostID, NULL, dwNumHosts);
  526. } else if(_wcsicmp(a_strMethodName, MOF_NODE::pMethods[MOF_NODE::START] ) == 0) {
  527. //call Start method
  528. dwReturnValue = g_pWlbsControl->Start( pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  529. dwHostID, NULL, dwNumHosts);
  530. } else if(_wcsicmp(a_strMethodName, MOF_NODE::pMethods[MOF_NODE::STOP] ) == 0) {
  531. //call Stop method
  532. dwReturnValue = g_pWlbsControl->Stop( pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  533. dwHostID, NULL, dwNumHosts);
  534. } else if(_wcsicmp(a_strMethodName, MOF_NODE::pMethods[MOF_NODE::SUSPEND] ) == 0) {
  535. //call Suspend method
  536. dwReturnValue = g_pWlbsControl->Suspend( pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  537. dwHostID, NULL, dwNumHosts);
  538. } else {
  539. throw _com_error(WBEM_E_METHOD_NOT_IMPLEMENTED);
  540. }
  541. //set the return value
  542. vReturnValue = (long)dwReturnValue;
  543. hRes = pOutputInstance->Put( _bstr_t(L"ReturnValue"), 0, &vReturnValue, 0 );
  544. if( FAILED( hRes ) ) {
  545. throw _com_error( hRes );
  546. }
  547. //send the results back to WinMgMt
  548. hRes = m_pResponseHandler->Indicate(1, &pOutputInstance);
  549. if( FAILED( hRes ) ) {
  550. throw _com_error( hRes );
  551. }
  552. if( strPortNumber ) {
  553. SysFreeString(strPortNumber);
  554. strPortNumber = NULL;
  555. }
  556. m_pResponseHandler->SetStatus( 0, WBEM_S_NO_ERROR, NULL, NULL );
  557. hRes = WBEM_S_NO_ERROR;
  558. }
  559. catch(CErrorWlbsControl Err) {
  560. IWbemClassObject* pWbemExtStat = NULL;
  561. CreateExtendedStatus( m_pNameSpace,
  562. &pWbemExtStat,
  563. Err.Error(),
  564. (PWCHAR)(Err.Description()) );
  565. m_pResponseHandler->SetStatus(0, WBEM_E_FAILED, NULL, pWbemExtStat);
  566. if( strPortNumber ) {
  567. SysFreeString(strPortNumber);
  568. strPortNumber = NULL;
  569. }
  570. if( pOutputInstance ) {
  571. pOutputInstance->Release();
  572. pOutputInstance = NULL;
  573. }
  574. if( pWbemExtStat )
  575. pWbemExtStat->Release();
  576. //do not return WBEM_E_FAILED, this causes a race condition
  577. hRes = WBEM_S_NO_ERROR;
  578. }
  579. catch(_com_error HResErr ) {
  580. m_pResponseHandler->SetStatus(0, HResErr.Error(), NULL, NULL);
  581. if( strPortNumber ) {
  582. SysFreeString(strPortNumber);
  583. strPortNumber = NULL;
  584. }
  585. if( pOutputInstance ) {
  586. pOutputInstance->Release();
  587. pOutputInstance = NULL;
  588. }
  589. hRes = HResErr.Error();
  590. }
  591. catch(...) {
  592. if( strPortNumber ) {
  593. SysFreeString(strPortNumber);
  594. strPortNumber = NULL;
  595. }
  596. if( pOutputInstance ) {
  597. pOutputInstance->Release();
  598. pOutputInstance = NULL;
  599. }
  600. throw;
  601. }
  602. return hRes;
  603. }
  604. ////////////////////////////////////////////////////////////////////////////////
  605. //
  606. // CWLBS_Node::FindInstance
  607. //
  608. // Purpose: This routine determines if a host is within the local cluster. If
  609. // it is, then the host's data is obtained and returned via the
  610. // IWbemClassObject interface.
  611. //
  612. ////////////////////////////////////////////////////////////////////////////////
  613. void CWLBS_Node::FindInstance
  614. (
  615. IWbemClassObject** a_ppWbemInstance,
  616. const ParsedObjectPath* a_pParsedPath
  617. )
  618. {
  619. try {
  620. //get the key property
  621. //throws _com_error
  622. //get the name key property and convert to ANSI
  623. //throws _com_error
  624. wstring szRequestedHostName = ( *a_pParsedPath->m_paKeys)->m_vValue.bstrVal;
  625. DWORD dwClustIpOrIndex = ExtractClusterIP( szRequestedHostName );
  626. CWlbsClusterWrapper* pCluster = g_pWlbsControl->GetClusterFromIpOrIndex(dwClustIpOrIndex);
  627. if( pCluster == NULL )
  628. throw _com_error( WBEM_E_NOT_FOUND );
  629. WLBS_RESPONSE Response;
  630. DWORD dwHostID = ExtractHostID( szRequestedHostName );
  631. if ((DWORD)-1 == dwHostID)
  632. throw _com_error( WBEM_E_NOT_FOUND );
  633. //always let the provider peform control operations on the local host
  634. if( dwHostID == pCluster->GetHostID() )
  635. {
  636. dwHostID = WLBS_LOCAL_HOST;
  637. }
  638. DWORD dwNumHosts = 1;
  639. //call the api query function
  640. g_pWlbsControl->Query( pCluster,
  641. dwHostID ,
  642. &Response ,
  643. &dwNumHosts,
  644. NULL );
  645. if( dwNumHosts == 0 )
  646. throw _com_error( WBEM_E_NOT_FOUND );
  647. //if requested, fill a MOF instance structure
  648. if(a_ppWbemInstance) {
  649. //get the Wbem class instance
  650. SpawnInstance( MOF_NODE::szName, a_ppWbemInstance );
  651. //Convert status to string description
  652. FillWbemInstance(pCluster, *a_ppWbemInstance, &Response );
  653. }
  654. }
  655. catch(...) {
  656. if( *a_ppWbemInstance ) {
  657. delete *a_ppWbemInstance;
  658. *a_ppWbemInstance = NULL;
  659. }
  660. throw;
  661. }
  662. }
  663. ////////////////////////////////////////////////////////////////////////////////
  664. //
  665. // CWLBS_Node::FindAllInstances
  666. //
  667. // Purpose: This executes a WLBS query and returns Response structures upon
  668. // success. It always performs a local query to get the local host
  669. // so that disabling remote control will not prevent it from
  670. // enumerating. The dedicated IP address is added to the structure
  671. // within the CWlbsControlWrapper::Query call.
  672. //
  673. ////////////////////////////////////////////////////////////////////////////////
  674. void CWLBS_Node::FindAllInstances
  675. (
  676. CWlbsClusterWrapper* pCluster,
  677. WLBS_RESPONSE** a_ppResponse,
  678. long& a_nNumNodes
  679. )
  680. {
  681. WLBS_RESPONSE Response[WLBS_MAX_HOSTS];
  682. WLBS_RESPONSE LocalResponse;
  683. ASSERT(pCluster);
  684. ZeroMemory(Response, WLBS_MAX_HOSTS * sizeof(WLBS_RESPONSE));
  685. DWORD dwNumHosts = WLBS_MAX_HOSTS;
  686. a_nNumNodes = 0; //this will contain the number of nodes returned
  687. try {
  688. //get the local host
  689. DWORD dwLocalNode = 1;
  690. g_pWlbsControl->Query( pCluster,
  691. WLBS_LOCAL_HOST,
  692. &LocalResponse,
  693. &dwLocalNode,
  694. NULL);
  695. try {
  696. //we only want remote hosts
  697. if( pCluster->GetClusterIP() != 0 )
  698. {
  699. g_pWlbsControl->Query( pCluster,
  700. WLBS_ALL_HOSTS,
  701. Response,
  702. &dwNumHosts,
  703. NULL );
  704. }
  705. else
  706. {
  707. dwNumHosts = 0;
  708. }
  709. } catch (CErrorWlbsControl Err) {
  710. dwNumHosts = 0;
  711. if (Err.Error() != WLBS_TIMEOUT)
  712. {
  713. throw;
  714. }
  715. }
  716. //this wastes memory if the local node
  717. //has remote control enabled
  718. a_nNumNodes = dwNumHosts + 1;
  719. if( a_ppResponse ) {
  720. *a_ppResponse = new WLBS_RESPONSE[a_nNumNodes];
  721. if( !*a_ppResponse )
  722. throw _com_error( WBEM_E_OUT_OF_MEMORY );
  723. //copy the local host
  724. (*a_ppResponse)[0] = LocalResponse;
  725. int j = 1;
  726. for(DWORD i = 1; i <= dwNumHosts; i++ )
  727. {
  728. //do not copy the local host again should it have remote control enabled
  729. if( Response[i-1].id == LocalResponse.id )
  730. {
  731. //we received the local node twice, so we reduce the count
  732. //by one
  733. a_nNumNodes--;
  734. continue;
  735. }
  736. (*a_ppResponse)[j] = Response[i-1];
  737. j++;
  738. }
  739. }
  740. } catch (...) {
  741. if ( *a_ppResponse )
  742. {
  743. delete [] *a_ppResponse;
  744. *a_ppResponse = NULL;
  745. }
  746. throw;
  747. }
  748. }
  749. ////////////////////////////////////////////////////////////////////////////////
  750. //
  751. // CWLBS_Node::FillWbemInstance
  752. //
  753. // Purpose: This function copies all of the data from a node configuration
  754. // structure to a WBEM instance.
  755. //
  756. ////////////////////////////////////////////////////////////////////////////////
  757. void CWLBS_Node::FillWbemInstance
  758. (
  759. CWlbsClusterWrapper* pCluster,
  760. IWbemClassObject* a_pWbemInstance,
  761. WLBS_RESPONSE* a_pResponse
  762. )
  763. {
  764. namespace NODE = MOF_NODE;
  765. ASSERT( a_pWbemInstance );
  766. ASSERT( a_pResponse );
  767. wstring wstrHostName;
  768. ConstructHostName( wstrHostName, pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  769. a_pResponse->id );
  770. //HOST NAME
  771. HRESULT hRes = a_pWbemInstance->Put
  772. (
  773. _bstr_t( NODE::pProperties[NODE::NAME] ) ,
  774. 0 ,
  775. &_variant_t(wstrHostName.c_str()),
  776. NULL
  777. );
  778. if( FAILED( hRes ) )
  779. throw _com_error( hRes );
  780. //HOST ID
  781. hRes = a_pWbemInstance->Put
  782. (
  783. _bstr_t( NODE::pProperties[NODE::HOSTID] ) ,
  784. 0 ,
  785. &_variant_t((long)(a_pResponse->id)),
  786. NULL
  787. );
  788. if( FAILED( hRes ) )
  789. throw _com_error( hRes );
  790. //CREATCLASS
  791. hRes = a_pWbemInstance->Put
  792. (
  793. _bstr_t( NODE::pProperties[NODE::CREATCLASS] ),
  794. 0 ,
  795. &_variant_t(NODE::szName),
  796. NULL
  797. );
  798. if( FAILED( hRes ) )
  799. throw _com_error( hRes );
  800. //IP ADDRESS
  801. wstring szIPAddress;
  802. AddressToString( a_pResponse->address, szIPAddress );
  803. hRes = a_pWbemInstance->Put
  804. (
  805. _bstr_t( NODE::pProperties[NODE::IPADDRESS] ),
  806. 0 ,
  807. &_variant_t(szIPAddress.c_str()),
  808. NULL
  809. );
  810. if( FAILED( hRes ) )
  811. throw _com_error( hRes );
  812. //STATUS
  813. hRes = a_pWbemInstance->Put
  814. (
  815. _bstr_t( NODE::pProperties[NODE::STATUS] ) ,
  816. 0 ,
  817. &_variant_t((long)a_pResponse->status),
  818. NULL
  819. );
  820. if( FAILED( hRes ) )
  821. throw _com_error( hRes );
  822. }