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.

912 lines
24 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 vInputPortNumber;
  268. CNodeConfiguration NodeConfig;
  269. BSTR strPortNumber = NULL;
  270. IWbemClassObject* pOutputInstance = NULL;
  271. try {
  272. strPortNumber = SysAllocString( MOF_PARAM::PORT_NUMBER );
  273. if( !strPortNumber )
  274. throw _com_error( WBEM_E_OUT_OF_MEMORY );
  275. //get the host ID address
  276. DWORD dwHostID = 0;
  277. DWORD dwClusterIpOrIndex = 0;
  278. dwHostID = ExtractHostID( wstring( (*a_pParsedPath->m_paKeys)->m_vValue.bstrVal ) );
  279. if ((DWORD)-1 == dwHostID)
  280. throw _com_error( WBEM_E_NOT_FOUND );
  281. dwClusterIpOrIndex = ExtractClusterIP( wstring( (*a_pParsedPath->m_paKeys)->m_vValue.bstrVal ) );
  282. if ((DWORD)-1 == dwClusterIpOrIndex)
  283. throw _com_error( WBEM_E_NOT_FOUND );
  284. CWlbsClusterWrapper* pCluster = g_pWlbsControl->GetClusterFromIpOrIndex(dwClusterIpOrIndex);
  285. if (pCluster == NULL)
  286. throw _com_error( WBEM_E_NOT_FOUND );
  287. //always let the provider peform control operations on the local host
  288. if( dwHostID == pCluster->GetHostID() )
  289. dwHostID = WLBS_LOCAL_HOST;
  290. //get the output object instance
  291. GetMethodOutputInstance( MOF_NODE::szName,
  292. a_strMethodName,
  293. &pOutputInstance );
  294. //determine and execute the MOF method
  295. if( _wcsicmp(a_strMethodName, MOF_NODE::pMethods[MOF_NODE::DISABLE] ) == 0) {
  296. if( !a_pIInParams )
  297. throw _com_error( WBEM_E_INVALID_PARAMETER );
  298. // The "Disable" method does NOT take vip as a parameter, so, if there is any port rule
  299. // that is specific to a vip (other than the "all vip"), we fail this method.
  300. // The "EffectiveVersion" registry value is checked for a value of CVY_VERSION_FULL to
  301. // see of there is any port rule that is specific to a vip
  302. pCluster->GetNodeConfig(NodeConfig);
  303. if(NodeConfig.dwEffectiveVersion == CVY_VERSION_FULL)
  304. throw _com_error( WBEM_E_INVALID_OPERATION );
  305. //get the port number
  306. hRes = a_pIInParams->Get
  307. ( strPortNumber,
  308. 0,
  309. &vInputPortNumber,
  310. NULL,
  311. NULL
  312. );
  313. if( FAILED( hRes ) ) {
  314. throw _com_error( hRes );
  315. }
  316. //make sure the port number is not NULL
  317. if( vInputPortNumber.vt != VT_I4)
  318. throw _com_error( WBEM_E_INVALID_PARAMETER );
  319. //call Disable method
  320. dwReturnValue = g_pWlbsControl->Disable
  321. (
  322. pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  323. dwHostID,
  324. NULL,
  325. dwNumHosts,
  326. IpAddressFromAbcdWsz(CVY_DEF_ALL_VIP), // "All Vip"
  327. (long)vInputPortNumber
  328. );
  329. } else if(_wcsicmp(a_strMethodName, MOF_NODE::pMethods[MOF_NODE::ENABLE] ) == 0) {
  330. if( !a_pIInParams )
  331. throw _com_error( WBEM_E_INVALID_PARAMETER );
  332. // The "Enable" method does NOT take vip as a parameter, so, if there is any port rule
  333. // that is specific to a vip (other than the "all vip"), we fail this method.
  334. // The "EffectiveVersion" registry value is checked for a value of CVY_VERSION_FULL to
  335. // see of there is any port rule that is specific to a vip
  336. pCluster->GetNodeConfig(NodeConfig);
  337. if(NodeConfig.dwEffectiveVersion == CVY_VERSION_FULL)
  338. throw _com_error( WBEM_E_INVALID_OPERATION );
  339. //get the port number
  340. hRes = a_pIInParams->Get
  341. (
  342. strPortNumber,
  343. 0,
  344. &vInputPortNumber,
  345. NULL,
  346. NULL
  347. );
  348. if( FAILED( hRes ) ) {
  349. throw _com_error( hRes );
  350. }
  351. if( vInputPortNumber.vt != VT_I4)
  352. throw _com_error(WBEM_E_INVALID_PARAMETER);
  353. //call Enable method
  354. dwReturnValue = g_pWlbsControl->Enable
  355. (
  356. pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  357. dwHostID,
  358. NULL,
  359. dwNumHosts,
  360. IpAddressFromAbcdWsz(CVY_DEF_ALL_VIP), // "All Vip"
  361. (long)vInputPortNumber
  362. );
  363. } else if(_wcsicmp(a_strMethodName, MOF_NODE::pMethods[MOF_NODE::DRAIN] ) == 0) {
  364. if( !a_pIInParams )
  365. throw _com_error( WBEM_E_INVALID_PARAMETER );
  366. // The "Drain" method does NOT take vip as a parameter, so, if there is any port rule
  367. // that is specific to a vip (other than the "all vip"), we fail this method.
  368. // The "EffectiveVersion" registry value is checked for a value of CVY_VERSION_FULL to
  369. // see of there is any port rule that is specific to a vip
  370. pCluster->GetNodeConfig(NodeConfig);
  371. if(NodeConfig.dwEffectiveVersion == CVY_VERSION_FULL)
  372. throw _com_error( WBEM_E_INVALID_OPERATION );
  373. //get the port number
  374. hRes = a_pIInParams->Get
  375. (
  376. strPortNumber,
  377. 0,
  378. &vInputPortNumber,
  379. NULL,
  380. NULL
  381. );
  382. if( FAILED( hRes ) ) {
  383. throw _com_error( hRes );
  384. }
  385. if( vInputPortNumber.vt != VT_I4)
  386. throw _com_error(WBEM_E_INVALID_PARAMETER);
  387. //call Drain method
  388. dwReturnValue = g_pWlbsControl->Drain
  389. (
  390. pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  391. dwHostID,
  392. NULL,
  393. dwNumHosts,
  394. IpAddressFromAbcdWsz(CVY_DEF_ALL_VIP), // "All Vip"
  395. (long)vInputPortNumber
  396. );
  397. } else if(_wcsicmp(a_strMethodName, MOF_NODE::pMethods[MOF_NODE::DRAINSTOP]) == 0) {
  398. //call DrainStop method
  399. dwReturnValue = g_pWlbsControl->DrainStop( pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  400. dwHostID, NULL, dwNumHosts);
  401. } else if(_wcsicmp(a_strMethodName, MOF_NODE::pMethods[MOF_NODE::RESUME] ) == 0) {
  402. //call Resume method
  403. dwReturnValue = g_pWlbsControl->Resume( pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  404. dwHostID, NULL, dwNumHosts);
  405. } else if(_wcsicmp(a_strMethodName, MOF_NODE::pMethods[MOF_NODE::START] ) == 0) {
  406. //call Start method
  407. dwReturnValue = g_pWlbsControl->Start( pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  408. dwHostID, NULL, dwNumHosts);
  409. } else if(_wcsicmp(a_strMethodName, MOF_NODE::pMethods[MOF_NODE::STOP] ) == 0) {
  410. //call Stop method
  411. dwReturnValue = g_pWlbsControl->Stop( pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  412. dwHostID, NULL, dwNumHosts);
  413. } else if(_wcsicmp(a_strMethodName, MOF_NODE::pMethods[MOF_NODE::SUSPEND] ) == 0) {
  414. //call Suspend method
  415. dwReturnValue = g_pWlbsControl->Suspend( pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  416. dwHostID, NULL, dwNumHosts);
  417. } else {
  418. throw _com_error(WBEM_E_METHOD_NOT_IMPLEMENTED);
  419. }
  420. //set the return value
  421. vReturnValue = (long)dwReturnValue;
  422. hRes = pOutputInstance->Put( _bstr_t(L"ReturnValue"), 0, &vReturnValue, 0 );
  423. if( FAILED( hRes ) ) {
  424. throw _com_error( hRes );
  425. }
  426. //send the results back to WinMgMt
  427. hRes = m_pResponseHandler->Indicate(1, &pOutputInstance);
  428. if( FAILED( hRes ) ) {
  429. throw _com_error( hRes );
  430. }
  431. if( strPortNumber ) {
  432. SysFreeString(strPortNumber);
  433. strPortNumber = NULL;
  434. }
  435. m_pResponseHandler->SetStatus( 0, WBEM_S_NO_ERROR, NULL, NULL );
  436. hRes = WBEM_S_NO_ERROR;
  437. }
  438. catch(CErrorWlbsControl Err) {
  439. IWbemClassObject* pWbemExtStat = NULL;
  440. CreateExtendedStatus( m_pNameSpace,
  441. &pWbemExtStat,
  442. Err.Error(),
  443. (PWCHAR)(Err.Description()) );
  444. m_pResponseHandler->SetStatus(0, WBEM_E_FAILED, NULL, pWbemExtStat);
  445. if( strPortNumber ) {
  446. SysFreeString(strPortNumber);
  447. strPortNumber = NULL;
  448. }
  449. if( pOutputInstance ) {
  450. pOutputInstance->Release();
  451. pOutputInstance = NULL;
  452. }
  453. if( pWbemExtStat )
  454. pWbemExtStat->Release();
  455. //do not return WBEM_E_FAILED, this causes a race condition
  456. hRes = WBEM_S_NO_ERROR;
  457. }
  458. catch(_com_error HResErr ) {
  459. m_pResponseHandler->SetStatus(0, HResErr.Error(), NULL, NULL);
  460. if( strPortNumber ) {
  461. SysFreeString(strPortNumber);
  462. strPortNumber = NULL;
  463. }
  464. if( pOutputInstance ) {
  465. pOutputInstance->Release();
  466. pOutputInstance = NULL;
  467. }
  468. hRes = HResErr.Error();
  469. }
  470. catch(...) {
  471. if( strPortNumber ) {
  472. SysFreeString(strPortNumber);
  473. strPortNumber = NULL;
  474. }
  475. if( pOutputInstance ) {
  476. pOutputInstance->Release();
  477. pOutputInstance = NULL;
  478. }
  479. throw;
  480. }
  481. return hRes;
  482. }
  483. ////////////////////////////////////////////////////////////////////////////////
  484. //
  485. // CWLBS_Node::FindInstance
  486. //
  487. // Purpose: This routine determines if a host is within the local cluster. If
  488. // it is, then the host's data is obtained and returned via the
  489. // IWbemClassObject interface.
  490. //
  491. ////////////////////////////////////////////////////////////////////////////////
  492. void CWLBS_Node::FindInstance
  493. (
  494. IWbemClassObject** a_ppWbemInstance,
  495. const ParsedObjectPath* a_pParsedPath
  496. )
  497. {
  498. try {
  499. //get the key property
  500. //throws _com_error
  501. //get the name key property and convert to ANSI
  502. //throws _com_error
  503. wstring szRequestedHostName = ( *a_pParsedPath->m_paKeys)->m_vValue.bstrVal;
  504. DWORD dwClustIpOrIndex = ExtractClusterIP( szRequestedHostName );
  505. CWlbsClusterWrapper* pCluster = g_pWlbsControl->GetClusterFromIpOrIndex(dwClustIpOrIndex);
  506. if( pCluster == NULL )
  507. throw _com_error( WBEM_E_NOT_FOUND );
  508. WLBS_RESPONSE Response;
  509. DWORD dwHostID = ExtractHostID( szRequestedHostName );
  510. if ((DWORD)-1 == dwHostID)
  511. throw _com_error( WBEM_E_NOT_FOUND );
  512. //always let the provider peform control operations on the local host
  513. if( dwHostID == pCluster->GetHostID() )
  514. {
  515. dwHostID = WLBS_LOCAL_HOST;
  516. }
  517. DWORD dwNumHosts = 1;
  518. //call the api query function
  519. g_pWlbsControl->Query( pCluster,
  520. dwHostID ,
  521. &Response ,
  522. &dwNumHosts,
  523. NULL );
  524. if( dwNumHosts == 0 )
  525. throw _com_error( WBEM_E_NOT_FOUND );
  526. //if requested, fill a MOF instance structure
  527. if(a_ppWbemInstance) {
  528. //get the Wbem class instance
  529. SpawnInstance( MOF_NODE::szName, a_ppWbemInstance );
  530. //Convert status to string description
  531. FillWbemInstance(pCluster, *a_ppWbemInstance, &Response );
  532. }
  533. }
  534. catch(...) {
  535. if( *a_ppWbemInstance ) {
  536. delete *a_ppWbemInstance;
  537. *a_ppWbemInstance = NULL;
  538. }
  539. throw;
  540. }
  541. }
  542. ////////////////////////////////////////////////////////////////////////////////
  543. //
  544. // CWLBS_Node::FindAllInstances
  545. //
  546. // Purpose: This executes a WLBS query and returns Response structures upon
  547. // success. It always performs a local query to get the local host
  548. // so that disabling remote control will not prevent it from
  549. // enumerating. The dedicated IP address is added to the structure
  550. // within the CWlbsControlWrapper::Query call.
  551. //
  552. ////////////////////////////////////////////////////////////////////////////////
  553. void CWLBS_Node::FindAllInstances
  554. (
  555. CWlbsClusterWrapper* pCluster,
  556. WLBS_RESPONSE** a_ppResponse,
  557. long& a_nNumNodes
  558. )
  559. {
  560. WLBS_RESPONSE Response[WLBS_MAX_HOSTS];
  561. WLBS_RESPONSE LocalResponse;
  562. ASSERT(pCluster);
  563. ZeroMemory(Response, WLBS_MAX_HOSTS * sizeof(WLBS_RESPONSE));
  564. DWORD dwNumHosts = WLBS_MAX_HOSTS;
  565. a_nNumNodes = 0; //this will contain the number of nodes returned
  566. try {
  567. //get the local host
  568. DWORD dwLocalNode = 1;
  569. g_pWlbsControl->Query( pCluster,
  570. WLBS_LOCAL_HOST,
  571. &LocalResponse,
  572. &dwLocalNode,
  573. NULL);
  574. try {
  575. //we only want remote hosts
  576. if( pCluster->GetClusterIP() != 0 )
  577. {
  578. g_pWlbsControl->Query( pCluster,
  579. WLBS_ALL_HOSTS,
  580. Response,
  581. &dwNumHosts,
  582. NULL );
  583. }
  584. else
  585. {
  586. dwNumHosts = 0;
  587. }
  588. } catch (CErrorWlbsControl Err) {
  589. dwNumHosts = 0;
  590. if (Err.Error() != WLBS_TIMEOUT)
  591. {
  592. throw;
  593. }
  594. }
  595. //this wastes memory if the local node
  596. //has remote control enabled
  597. a_nNumNodes = dwNumHosts + 1;
  598. if( a_ppResponse ) {
  599. *a_ppResponse = new WLBS_RESPONSE[a_nNumNodes];
  600. if( !*a_ppResponse )
  601. throw _com_error( WBEM_E_OUT_OF_MEMORY );
  602. //copy the local host
  603. (*a_ppResponse)[0] = LocalResponse;
  604. int j = 1;
  605. for(DWORD i = 1; i <= dwNumHosts; i++ )
  606. {
  607. //do not copy the local host again should it have remote control enabled
  608. if( Response[i-1].id == LocalResponse.id )
  609. {
  610. //we received the local node twice, so we reduce the count
  611. //by one
  612. a_nNumNodes--;
  613. continue;
  614. }
  615. (*a_ppResponse)[j] = Response[i-1];
  616. j++;
  617. }
  618. }
  619. } catch (...) {
  620. if ( *a_ppResponse )
  621. {
  622. delete [] *a_ppResponse;
  623. *a_ppResponse = NULL;
  624. }
  625. throw;
  626. }
  627. }
  628. ////////////////////////////////////////////////////////////////////////////////
  629. //
  630. // CWLBS_Node::FillWbemInstance
  631. //
  632. // Purpose: This function copies all of the data from a node configuration
  633. // structure to a WBEM instance.
  634. //
  635. ////////////////////////////////////////////////////////////////////////////////
  636. void CWLBS_Node::FillWbemInstance
  637. (
  638. CWlbsClusterWrapper* pCluster,
  639. IWbemClassObject* a_pWbemInstance,
  640. WLBS_RESPONSE* a_pResponse
  641. )
  642. {
  643. namespace NODE = MOF_NODE;
  644. ASSERT( a_pWbemInstance );
  645. ASSERT( a_pResponse );
  646. wstring wstrHostName;
  647. ConstructHostName( wstrHostName, pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  648. a_pResponse->id );
  649. //HOST NAME
  650. HRESULT hRes = a_pWbemInstance->Put
  651. (
  652. _bstr_t( NODE::pProperties[NODE::NAME] ) ,
  653. 0 ,
  654. &_variant_t(wstrHostName.c_str()),
  655. NULL
  656. );
  657. if( FAILED( hRes ) )
  658. throw _com_error( hRes );
  659. //HOST ID
  660. hRes = a_pWbemInstance->Put
  661. (
  662. _bstr_t( NODE::pProperties[NODE::HOSTID] ) ,
  663. 0 ,
  664. &_variant_t((long)(a_pResponse->id)),
  665. NULL
  666. );
  667. if( FAILED( hRes ) )
  668. throw _com_error( hRes );
  669. //CREATCLASS
  670. hRes = a_pWbemInstance->Put
  671. (
  672. _bstr_t( NODE::pProperties[NODE::CREATCLASS] ),
  673. 0 ,
  674. &_variant_t(NODE::szName),
  675. NULL
  676. );
  677. if( FAILED( hRes ) )
  678. throw _com_error( hRes );
  679. //IP ADDRESS
  680. wstring szIPAddress;
  681. AddressToString( a_pResponse->address, szIPAddress );
  682. hRes = a_pWbemInstance->Put
  683. (
  684. _bstr_t( NODE::pProperties[NODE::IPADDRESS] ),
  685. 0 ,
  686. &_variant_t(szIPAddress.c_str()),
  687. NULL
  688. );
  689. if( FAILED( hRes ) )
  690. throw _com_error( hRes );
  691. //STATUS
  692. hRes = a_pWbemInstance->Put
  693. (
  694. _bstr_t( NODE::pProperties[NODE::STATUS] ) ,
  695. 0 ,
  696. &_variant_t((long)a_pResponse->status),
  697. NULL
  698. );
  699. if( FAILED( hRes ) )
  700. throw _com_error( hRes );
  701. }