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.

1070 lines
29 KiB

  1. #include "WLBS_Provider.h"
  2. #include "WLBS_PortRule.h"
  3. #include "ClusterWrapper.h"
  4. #include "ControlWrapper.h"
  5. #include "utils.h"
  6. #include "wlbsutil.h"
  7. extern CWlbsControlWrapper* g_pWlbsControl;
  8. ////////////////////////////////////////////////////////////////////////////////
  9. //
  10. // CWLBS_PortRule::CWLBS_PortRule
  11. //
  12. // Purpose: Constructor
  13. //
  14. ////////////////////////////////////////////////////////////////////////////////
  15. CWLBS_PortRule::CWLBS_PortRule
  16. (
  17. CWbemServices* a_pNameSpace,
  18. IWbemObjectSink* a_pResponseHandler
  19. )
  20. : CWlbs_Root( a_pNameSpace, a_pResponseHandler )
  21. {
  22. }
  23. ////////////////////////////////////////////////////////////////////////////////
  24. //
  25. // CWLBS_PortRule::Create
  26. //
  27. // Purpose: This instantiates this class and is invoked from an array of
  28. // function pointers.
  29. //
  30. ////////////////////////////////////////////////////////////////////////////////
  31. CWlbs_Root* CWLBS_PortRule::Create
  32. (
  33. CWbemServices* a_pNameSpace,
  34. IWbemObjectSink* a_pResponseHandler
  35. )
  36. {
  37. CWlbs_Root* pRoot = new CWLBS_PortRule( a_pNameSpace, a_pResponseHandler );
  38. if( !pRoot )
  39. throw _com_error( WBEM_E_OUT_OF_MEMORY );
  40. return pRoot;
  41. }
  42. ////////////////////////////////////////////////////////////////////////////////
  43. //
  44. // CWLBS_PortRule::ExecMethod
  45. //
  46. // Purpose:
  47. //
  48. ////////////////////////////////////////////////////////////////////////////////
  49. HRESULT CWLBS_PortRule::ExecMethod
  50. (
  51. const ParsedObjectPath* /* a_pParsedPath */,
  52. const BSTR& a_strMethodName,
  53. long /* a_lFlags */,
  54. IWbemContext* /* a_pIContex */,
  55. IWbemClassObject* a_pIInParams
  56. )
  57. {
  58. IWbemClassObject* pOutputInstance = NULL;
  59. VARIANT vValue;
  60. HRESULT hRes = 0;
  61. try {
  62. VariantInit( &vValue );
  63. //determine the method being executed
  64. if( _wcsicmp( a_strMethodName, MOF_PORTRULE::pMethods[MOF_PORTRULE::SETDEF] ) == 0 )
  65. {
  66. //get the node path
  67. hRes = a_pIInParams->Get
  68. (
  69. _bstr_t( MOF_PARAM::NODEPATH ),
  70. 0,
  71. &vValue,
  72. NULL,
  73. NULL
  74. );
  75. if( FAILED( hRes) )
  76. {
  77. throw _com_error( WBEM_E_FAILED );
  78. }
  79. //this check may not be necessary since WMI will do some
  80. //parameter validation
  81. //if( vValue.vt != VT_BSTR )
  82. // throw _com_error ( WBEM_E_INVALID_PARAMETER );
  83. //parse node path
  84. CObjectPathParser PathParser;
  85. ParsedObjectPath *pParsedPath = NULL;
  86. try {
  87. int nStatus = PathParser.Parse( vValue.bstrVal, &pParsedPath );
  88. if(nStatus != 0) {
  89. if (NULL != pParsedPath)
  90. {
  91. PathParser.Free( pParsedPath );
  92. pParsedPath = NULL;
  93. }
  94. throw _com_error( WBEM_E_INVALID_PARAMETER );
  95. }
  96. //get the name key, which should be the only key
  97. if( *pParsedPath->m_paKeys == NULL )
  98. {
  99. throw _com_error( WBEM_E_INVALID_PARAMETER );
  100. }
  101. DWORD dwReqClusterIpOrIndex = ExtractClusterIP( (*pParsedPath->m_paKeys)->m_vValue.bstrVal);
  102. DWORD dwReqHostID = ExtractHostID( (*pParsedPath->m_paKeys)->m_vValue.bstrVal);
  103. CWlbsClusterWrapper* pCluster = g_pWlbsControl->GetClusterFromIpOrIndex(
  104. dwReqClusterIpOrIndex);
  105. if (pCluster == NULL || (DWORD)-1 == dwReqHostID)
  106. throw _com_error( WBEM_E_INVALID_PARAMETER );
  107. // The "PortRule(Disabled/Failover/Loadbalanced)" classes do NOT contain the VIP property,
  108. // so, we do not want to operate on any cluster that has a port rule
  109. // that is specific to a vip (other than the "all vip")
  110. // The "EffectiveVersion" registry value is checked for a value of CVY_VERSION_FULL to
  111. // see of there is any port rule that is specific to a vip
  112. CNodeConfiguration NodeConfig;
  113. pCluster->GetNodeConfig(NodeConfig);
  114. if(NodeConfig.dwEffectiveVersion == CVY_VERSION_FULL)
  115. throw _com_error( WBEM_E_INVALID_OPERATION );
  116. //validate host ID
  117. if( dwReqHostID != pCluster->GetHostID())
  118. throw _com_error( WBEM_E_INVALID_PARAMETER );
  119. //invoke method
  120. pCluster->SetPortRuleDefaults();
  121. }
  122. catch( ... ) {
  123. if( pParsedPath )
  124. {
  125. PathParser.Free( pParsedPath );
  126. pParsedPath = NULL;
  127. }
  128. throw;
  129. }
  130. } else {
  131. throw _com_error( WBEM_E_METHOD_NOT_IMPLEMENTED );
  132. }
  133. // CLD: Need to check return code for error
  134. if (S_OK != VariantClear( &vValue ))
  135. throw _com_error( WBEM_E_FAILED );
  136. if( pOutputInstance ) {
  137. pOutputInstance->Release();
  138. pOutputInstance = NULL;
  139. }
  140. m_pResponseHandler->SetStatus( 0, WBEM_S_NO_ERROR, NULL, NULL );
  141. hRes = WBEM_S_NO_ERROR;
  142. }
  143. catch(CErrorWlbsControl Err) {
  144. IWbemClassObject* pWbemExtStat = NULL;
  145. CreateExtendedStatus( m_pNameSpace,
  146. &pWbemExtStat,
  147. Err.Error(),
  148. (PWCHAR)(Err.Description()) );
  149. m_pResponseHandler->SetStatus(0, WBEM_E_FAILED, NULL, pWbemExtStat);
  150. if( pWbemExtStat )
  151. pWbemExtStat->Release();
  152. // CLD: Need to check return code for error
  153. // No throw here since we are already throwing an exception.
  154. VariantClear( &vValue );
  155. if( pOutputInstance ) {
  156. pOutputInstance->Release();
  157. pOutputInstance = NULL;
  158. }
  159. //do not return WBEM_E_FAILED, this causes a race condition
  160. hRes = WBEM_S_NO_ERROR;
  161. }
  162. catch(_com_error HResErr ) {
  163. m_pResponseHandler->SetStatus(0, HResErr.Error(), NULL, NULL);
  164. // CLD: Need to check return code for error
  165. // No throw here since we are already throwing an exception.
  166. VariantClear( &vValue );
  167. if( pOutputInstance ) {
  168. pOutputInstance->Release();
  169. }
  170. hRes = HResErr.Error();
  171. }
  172. catch ( ... ) {
  173. // CLD: Need to check return code for error
  174. // No throw here since we are already throwing an exception.
  175. VariantClear( &vValue );
  176. if( pOutputInstance ) {
  177. pOutputInstance->Release();
  178. }
  179. throw;
  180. }
  181. return hRes;
  182. }
  183. ////////////////////////////////////////////////////////////////////////////////
  184. //
  185. // CWLBS_PortRule::GetInstance
  186. //
  187. // Purpose: This function retrieves an instance of a MOF PortRule
  188. // class. The node does not have to be a member of a cluster.
  189. //
  190. ////////////////////////////////////////////////////////////////////////////////
  191. HRESULT CWLBS_PortRule::GetInstance
  192. (
  193. const ParsedObjectPath* a_pParsedPath,
  194. long /* a_lFlags */,
  195. IWbemContext* /* a_pIContex */
  196. )
  197. {
  198. IWbemClassObject* pWlbsInstance = NULL;
  199. HRESULT hRes = 0;
  200. try {
  201. if( !a_pParsedPath )
  202. throw _com_error( WBEM_E_FAILED );
  203. wstring wstrHostName;
  204. wstrHostName = (*a_pParsedPath->m_paKeys)->m_vValue.bstrVal;
  205. DWORD dwReqStartPort = static_cast<DWORD>( (*(a_pParsedPath->m_paKeys + 1))->m_vValue.lVal );
  206. CWlbsClusterWrapper* pCluster = GetClusterFromHostName(g_pWlbsControl, wstrHostName);
  207. if (pCluster == NULL)
  208. {
  209. throw _com_error( WBEM_E_NOT_FOUND );
  210. }
  211. // The "PortRule(Disabled/Failover/Loadbalanced)" classes do NOT contain the VIP property,
  212. // so, we do not want to operate on any cluster that has a port rule
  213. // that is specific to a vip (other than the "all vip")
  214. // The "EffectiveVersion" registry value is checked for a value of CVY_VERSION_FULL to
  215. // see of there is any port rule that is specific to a vip
  216. CNodeConfiguration NodeConfig;
  217. pCluster->GetNodeConfig(NodeConfig);
  218. if(NodeConfig.dwEffectiveVersion == CVY_VERSION_FULL)
  219. throw _com_error( WBEM_E_INVALID_OPERATION );
  220. WLBS_PORT_RULE PortRule;
  221. pCluster->GetPortRule(IpAddressFromAbcdWsz(CVY_DEF_ALL_VIP), dwReqStartPort, &PortRule );
  222. if( dwReqStartPort != PortRule.start_port )
  223. throw _com_error( WBEM_E_NOT_FOUND );
  224. SpawnInstance( a_pParsedPath->m_pClass, &pWlbsInstance );
  225. FillWbemInstance(pCluster, pWlbsInstance, &PortRule );
  226. //send the results back to WinMgMt
  227. m_pResponseHandler->Indicate( 1, &pWlbsInstance );
  228. if( pWlbsInstance )
  229. pWlbsInstance->Release();
  230. m_pResponseHandler->SetStatus( 0, WBEM_S_NO_ERROR, NULL, NULL );
  231. hRes = WBEM_S_NO_ERROR;
  232. }
  233. catch(CErrorWlbsControl Err) {
  234. IWbemClassObject* pWbemExtStat = NULL;
  235. CreateExtendedStatus( m_pNameSpace,
  236. &pWbemExtStat,
  237. Err.Error(),
  238. (PWCHAR)(Err.Description()) );
  239. m_pResponseHandler->SetStatus(0, WBEM_E_FAILED, NULL, pWbemExtStat);
  240. if( pWbemExtStat )
  241. pWbemExtStat->Release();
  242. if( pWlbsInstance )
  243. pWlbsInstance->Release();
  244. //do not return WBEM_E_FAILED, this causes a race condition
  245. hRes = WBEM_S_NO_ERROR;
  246. }
  247. catch(_com_error HResErr ) {
  248. m_pResponseHandler->SetStatus(0, HResErr.Error(), NULL, NULL);
  249. if( pWlbsInstance )
  250. pWlbsInstance->Release();
  251. hRes = HResErr.Error();
  252. }
  253. catch(...) {
  254. if( pWlbsInstance )
  255. pWlbsInstance->Release();
  256. throw;
  257. }
  258. return hRes;
  259. }
  260. ////////////////////////////////////////////////////////////////////////////////
  261. //
  262. // CWLBS_PortRule::EnumInstances
  263. //
  264. // Purpose: This function obtains the PortRule data for the current host.
  265. // The node does not have to be a member of a cluster for this
  266. // to succeed. However, NLB must be installed.
  267. //
  268. ////////////////////////////////////////////////////////////////////////////////
  269. HRESULT CWLBS_PortRule::EnumInstances
  270. (
  271. BSTR a_bstrClass,
  272. long /*a_lFlags*/,
  273. IWbemContext* /*a_pIContex*/
  274. )
  275. {
  276. IWbemClassObject** ppWlbsInstance = NULL;
  277. HRESULT hRes = 0;
  278. PWLBS_PORT_RULE pPortRules = NULL;
  279. DWORD dwNumRules = 0;
  280. CNodeConfiguration NodeConfig;
  281. try {
  282. DWORD dwFilteringMode;
  283. if( _wcsicmp( a_bstrClass, MOF_PRFAIL::szName ) == 0 ) {
  284. dwFilteringMode = WLBS_SINGLE;
  285. } else if( _wcsicmp( a_bstrClass, MOF_PRLOADBAL::szName ) == 0 ) {
  286. dwFilteringMode = WLBS_MULTI;
  287. } else if( _wcsicmp( a_bstrClass, MOF_PRDIS::szName ) == 0 ) {
  288. dwFilteringMode = WLBS_NEVER;
  289. } else {
  290. throw _com_error( WBEM_E_NOT_FOUND );
  291. }
  292. DWORD dwNumClusters = 0;
  293. CWlbsClusterWrapper** ppCluster = NULL;
  294. g_pWlbsControl->EnumClusters(ppCluster, &dwNumClusters);
  295. if (dwNumClusters == 0)
  296. {
  297. throw _com_error( WBEM_E_NOT_FOUND );
  298. }
  299. //declare an IWbemClassObject smart pointer
  300. IWbemClassObjectPtr pWlbsClass;
  301. //get the MOF class object
  302. hRes = m_pNameSpace->GetObject(
  303. a_bstrClass,
  304. 0,
  305. NULL,
  306. &pWlbsClass,
  307. NULL );
  308. if( FAILED( hRes ) ) {
  309. throw _com_error( hRes );
  310. }
  311. for (DWORD iCluster=0; iCluster<dwNumClusters; iCluster++)
  312. {
  313. // The "PortRule(Disabled/Failover/Loadbalanced)" classes do NOT contain the VIP property,
  314. // so, we do not want to return any port rule for a cluster that has a port rule
  315. // that is specific to a vip (other than the "all vip")
  316. // The "EffectiveVersion" registry value is checked for a value of CVY_VERSION_FULL to
  317. // see of there is any port rule that is specific to a vip
  318. ppCluster[iCluster]->GetNodeConfig(NodeConfig);
  319. if(NodeConfig.dwEffectiveVersion == CVY_VERSION_FULL)
  320. continue;
  321. //call the API query function to find the port rules
  322. ppCluster[iCluster]->EnumPortRules( &pPortRules, &dwNumRules, dwFilteringMode );
  323. if( dwNumRules == 0 )
  324. throw _com_error( WBEM_E_NOT_FOUND );
  325. //spawn an instance of the MOF class for each rule found
  326. ppWlbsInstance = new IWbemClassObject *[dwNumRules];
  327. if( !ppWlbsInstance )
  328. throw _com_error( WBEM_E_OUT_OF_MEMORY );
  329. //initialize array
  330. ZeroMemory( ppWlbsInstance, dwNumRules * sizeof(IWbemClassObject *) );
  331. for( DWORD i = 0; i < dwNumRules; i ++ ) {
  332. hRes = pWlbsClass->SpawnInstance( 0, &ppWlbsInstance[i] );
  333. if( FAILED( hRes ) )
  334. throw _com_error( hRes );
  335. FillWbemInstance(ppCluster[iCluster], *(ppWlbsInstance + i), pPortRules + i );
  336. }
  337. //send the results back to WinMgMt
  338. hRes = m_pResponseHandler->Indicate( dwNumRules, ppWlbsInstance );
  339. if( FAILED( hRes ) ) {
  340. throw _com_error( hRes );
  341. }
  342. if( ppWlbsInstance ) {
  343. for( i = 0; i < dwNumRules; i++ ) {
  344. if( ppWlbsInstance[i] ) {
  345. ppWlbsInstance[i]->Release();
  346. }
  347. }
  348. delete [] ppWlbsInstance;
  349. ppWlbsInstance = NULL;
  350. dwNumRules = NULL;
  351. }
  352. if( pPortRules )
  353. {
  354. delete [] pPortRules;
  355. pPortRules = NULL;
  356. }
  357. }
  358. m_pResponseHandler->SetStatus( 0, WBEM_S_NO_ERROR, NULL, NULL );
  359. hRes = WBEM_S_NO_ERROR;
  360. }
  361. catch(CErrorWlbsControl Err) {
  362. IWbemClassObject* pWbemExtStat = NULL;
  363. CreateExtendedStatus( m_pNameSpace,
  364. &pWbemExtStat,
  365. Err.Error(),
  366. (PWCHAR)(Err.Description()) );
  367. m_pResponseHandler->SetStatus(0, WBEM_E_FAILED, NULL, pWbemExtStat);
  368. if( pWbemExtStat )
  369. pWbemExtStat->Release();
  370. if( ppWlbsInstance ) {
  371. for( DWORD i = 0; i < dwNumRules; i++ ) {
  372. if( ppWlbsInstance[i] ) {
  373. ppWlbsInstance[i]->Release();
  374. ppWlbsInstance[i] = NULL;
  375. }
  376. }
  377. delete [] ppWlbsInstance;
  378. }
  379. if( pPortRules )
  380. delete [] pPortRules;
  381. //do not return WBEM_E_FAILED, this causes a race condition
  382. hRes = WBEM_S_NO_ERROR;
  383. }
  384. catch(_com_error HResErr ) {
  385. m_pResponseHandler->SetStatus(0, HResErr.Error(), NULL, NULL);
  386. if( ppWlbsInstance ) {
  387. for( DWORD i = 0; i < dwNumRules; i++ ) {
  388. if( ppWlbsInstance[i] ) {
  389. ppWlbsInstance[i]->Release();
  390. ppWlbsInstance[i] = NULL;
  391. }
  392. }
  393. delete [] ppWlbsInstance;
  394. }
  395. if( pPortRules )
  396. delete [] pPortRules;
  397. hRes = HResErr.Error();
  398. }
  399. catch(...) {
  400. if( ppWlbsInstance ) {
  401. for( DWORD i = 0; i < dwNumRules; i++ ) {
  402. if( ppWlbsInstance[i] ) {
  403. ppWlbsInstance[i]->Release();
  404. ppWlbsInstance[i] = NULL;
  405. }
  406. }
  407. delete [] ppWlbsInstance;
  408. }
  409. if( pPortRules )
  410. delete [] pPortRules;
  411. throw;
  412. }
  413. return hRes;
  414. }
  415. ////////////////////////////////////////////////////////////////////////////////
  416. //
  417. // CWLBS_PortRule::DeleteInstance
  418. //
  419. // Purpose: This function deletes an instance of a MOF PortRule
  420. // class. The node does not have to be a member of a cluster. However,
  421. // WLBS must be installed for this function to succeed.
  422. //
  423. ////////////////////////////////////////////////////////////////////////////////
  424. HRESULT CWLBS_PortRule::DeleteInstance
  425. (
  426. const ParsedObjectPath* a_pParsedPath,
  427. long /*a_lFlags*/,
  428. IWbemContext* /*a_pIContex*/
  429. )
  430. {
  431. HRESULT hRes = 0;
  432. try {
  433. if( !a_pParsedPath )
  434. throw _com_error( WBEM_E_FAILED );
  435. wstring wstrHostName;
  436. wstrHostName = (*a_pParsedPath->m_paKeys)->m_vValue.bstrVal;
  437. DWORD dwReqStartPort = static_cast<DWORD>( (*(a_pParsedPath->m_paKeys + 1))->m_vValue.lVal );
  438. CWlbsClusterWrapper* pCluster = GetClusterFromHostName(g_pWlbsControl, wstrHostName);
  439. if (pCluster == NULL)
  440. {
  441. throw _com_error( WBEM_E_NOT_FOUND );
  442. }
  443. // The "PortRule(Disabled/Failover/Loadbalanced)" classes do NOT contain the VIP property,
  444. // so, we do not want to operate on any cluster that has a port rule
  445. // that is specific to a vip (other than the "all vip")
  446. // The "EffectiveVersion" registry value is checked for a value of CVY_VERSION_FULL to
  447. // see of there is any port rule that is specific to a vip
  448. CNodeConfiguration NodeConfig;
  449. pCluster->GetNodeConfig(NodeConfig);
  450. if(NodeConfig.dwEffectiveVersion == CVY_VERSION_FULL)
  451. throw _com_error( WBEM_E_INVALID_OPERATION );
  452. WLBS_PORT_RULE PortRule;
  453. // Get the "All Vip" port rule for this port
  454. pCluster->GetPortRule(IpAddressFromAbcdWsz(CVY_DEF_ALL_VIP), dwReqStartPort, &PortRule );
  455. if( dwReqStartPort != PortRule.start_port )
  456. throw _com_error( WBEM_E_NOT_FOUND );
  457. // Delete the "All Vip" port rule for this port
  458. pCluster->DeletePortRule(IpAddressFromAbcdWsz(CVY_DEF_ALL_VIP), dwReqStartPort );
  459. m_pResponseHandler->SetStatus( 0, WBEM_S_NO_ERROR, NULL, NULL );
  460. hRes = WBEM_S_NO_ERROR;
  461. }
  462. catch(CErrorWlbsControl Err) {
  463. IWbemClassObject* pWbemExtStat = NULL;
  464. CreateExtendedStatus( m_pNameSpace,
  465. &pWbemExtStat,
  466. Err.Error(),
  467. (PWCHAR)(Err.Description()) );
  468. m_pResponseHandler->SetStatus(0, WBEM_E_FAILED, NULL, pWbemExtStat);
  469. if( pWbemExtStat )
  470. pWbemExtStat->Release();
  471. //do not return WBEM_E_FAILED, this causes a race condition
  472. hRes = WBEM_S_NO_ERROR;
  473. }
  474. catch(_com_error HResErr ) {
  475. m_pResponseHandler->SetStatus(0, HResErr.Error(), NULL, NULL);
  476. hRes = HResErr.Error();
  477. }
  478. return hRes;
  479. }
  480. ////////////////////////////////////////////////////////////////////////////////
  481. //
  482. // CWLBS_PortRule::PutInstance
  483. //
  484. // Purpose: This function updates an instance of a PortRule
  485. // class. The host does not have to be a member of a cluster.
  486. //
  487. ////////////////////////////////////////////////////////////////////////////////
  488. HRESULT CWLBS_PortRule::PutInstance
  489. (
  490. IWbemClassObject* a_pInstance,
  491. long /*a_lFlags*/,
  492. IWbemContext* /*a_pIContex*/
  493. )
  494. {
  495. VARIANT vValue;
  496. HRESULT hRes = 0;
  497. WLBS_PORT_RULE NewRule; //the instance to put
  498. try {
  499. VariantInit( &vValue );
  500. //get the host name value
  501. hRes = a_pInstance->Get( _bstr_t( MOF_PORTRULE::pProperties[MOF_PORTRULE::NAME] ),
  502. 0,
  503. &vValue,
  504. NULL,
  505. NULL );
  506. if( FAILED( hRes ) )
  507. throw _com_error( hRes );
  508. wstring wstrHostName( vValue.bstrVal );
  509. CWlbsClusterWrapper* pCluster = GetClusterFromHostName(g_pWlbsControl, wstrHostName);
  510. if (pCluster == NULL)
  511. {
  512. throw _com_error( WBEM_E_NOT_FOUND );
  513. }
  514. // CLD: Need to check return code for error
  515. if (S_OK != VariantClear( &vValue ))
  516. throw _com_error( WBEM_E_FAILED );
  517. // The "PortRule(Disabled/Failover/Loadbalanced)" classes do NOT contain the VIP property,
  518. // so, we do not want to operate on any cluster that has a port rule
  519. // that is specific to a vip (other than the "all vip")
  520. // The "EffectiveVersion" registry value is checked for a value of CVY_VERSION_FULL to
  521. // see of there is any port rule that is specific to a vip
  522. CNodeConfiguration NodeConfig;
  523. pCluster->GetNodeConfig(NodeConfig);
  524. if(NodeConfig.dwEffectiveVersion == CVY_VERSION_FULL)
  525. throw _com_error( WBEM_E_INVALID_OPERATION );
  526. //retrieve start and end ports
  527. hRes = a_pInstance->Get( _bstr_t( MOF_PORTRULE::pProperties[MOF_PORTRULE::STPORT] ),
  528. 0,
  529. &vValue,
  530. NULL,
  531. NULL );
  532. if( FAILED( hRes ) )
  533. throw _com_error( hRes );
  534. NewRule.start_port = static_cast<DWORD>( vValue.lVal );
  535. hRes = a_pInstance->Get( _bstr_t( MOF_PORTRULE::pProperties[MOF_PORTRULE::EDPORT] ),
  536. 0,
  537. &vValue,
  538. NULL,
  539. NULL );
  540. if( FAILED( hRes ) )
  541. throw _com_error( hRes );
  542. NewRule.end_port = static_cast<DWORD>( vValue.lVal );
  543. //get the protocol
  544. hRes = a_pInstance->Get( _bstr_t( MOF_PORTRULE::pProperties[MOF_PORTRULE::PROT] ),
  545. 0,
  546. &vValue,
  547. NULL,
  548. NULL );
  549. if( FAILED( hRes ) )
  550. throw _com_error( hRes );
  551. NewRule.protocol = static_cast<DWORD>( vValue.lVal );
  552. //get the class name to determine port rule mode
  553. hRes = a_pInstance->Get( _bstr_t( L"__Class" ),
  554. 0,
  555. &vValue,
  556. NULL,
  557. NULL );
  558. if( FAILED( hRes ) )
  559. throw _com_error( hRes );
  560. if( _wcsicmp( vValue.bstrVal, MOF_PRDIS::szName ) == 0 ) {
  561. NewRule.mode = WLBS_NEVER;
  562. } else if(_wcsicmp( vValue.bstrVal, MOF_PRFAIL::szName ) == 0 ) {
  563. NewRule.mode = WLBS_SINGLE;
  564. VARIANT vRulePriority;
  565. VariantInit( &vRulePriority );
  566. try {
  567. //get the rule priority
  568. hRes = a_pInstance->Get( _bstr_t( MOF_PRFAIL::pProperties[MOF_PRFAIL::PRIO] ),
  569. 0,
  570. &vRulePriority,
  571. NULL,
  572. NULL );
  573. if( FAILED( hRes ) )
  574. throw _com_error( hRes );
  575. }
  576. catch( ... ) {
  577. // CLD: Need to check return code for error
  578. // No throw here since we are already throwing an exception.
  579. VariantClear( &vRulePriority );
  580. throw;
  581. }
  582. NewRule.mode_data.single.priority = static_cast<DWORD>( vRulePriority.lVal );
  583. // CLD: Need to check return code for error
  584. if (S_OK != VariantClear( &vRulePriority ))
  585. throw _com_error( WBEM_E_FAILED );
  586. } else if(_wcsicmp( vValue.bstrVal, MOF_PRLOADBAL::szName ) == 0 ) {
  587. NewRule.mode = WLBS_MULTI;
  588. VARIANT v;
  589. VariantInit( &v );
  590. try {
  591. //get the affinity
  592. hRes = a_pInstance->Get( _bstr_t( MOF_PRLOADBAL::pProperties[MOF_PRLOADBAL::AFFIN] ),
  593. 0,
  594. &v,
  595. NULL,
  596. NULL );
  597. if( FAILED( hRes ) )
  598. throw _com_error( hRes );
  599. NewRule.mode_data.multi.affinity = static_cast<WORD>( v.lVal );
  600. //get the equal load boolean
  601. hRes = a_pInstance->Get( _bstr_t( MOF_PRLOADBAL::pProperties[MOF_PRLOADBAL::EQLD] ),
  602. 0,
  603. &v,
  604. NULL,
  605. NULL );
  606. if( FAILED( hRes ) )
  607. throw _com_error( hRes );
  608. if( v.boolVal == -1 ) {
  609. NewRule.mode_data.multi.equal_load = 1;
  610. } else {
  611. NewRule.mode_data.multi.equal_load = 0;
  612. }
  613. //get the load
  614. hRes = a_pInstance->Get( _bstr_t( MOF_PRLOADBAL::pProperties[MOF_PRLOADBAL::LDWT] ),
  615. 0,
  616. &v,
  617. NULL,
  618. NULL );
  619. if( FAILED( hRes ) )
  620. throw _com_error( hRes );
  621. if( v.vt != VT_NULL )
  622. NewRule.mode_data.multi.load = static_cast<DWORD>( v.lVal );
  623. else
  624. NewRule.mode_data.multi.load = 0;
  625. } catch( ... ) {
  626. // CLD: Need to check return code for error
  627. // No throw here since we are already throwing an exception.
  628. VariantClear( &v );
  629. throw;
  630. }
  631. // CLD: Need to check return code for error
  632. if (S_OK != VariantClear( &v ))
  633. throw _com_error( WBEM_E_FAILED );
  634. }
  635. //delete the port rule but cache in case of failure
  636. WLBS_PORT_RULE OldRule;
  637. bool bOldRuleSaved = false;
  638. lstrcpy(NewRule.virtual_ip_addr, CVY_DEF_ALL_VIP);
  639. if( pCluster->RuleExists(IpAddressFromAbcdWsz(NewRule.virtual_ip_addr), NewRule.start_port ) ) {
  640. pCluster->GetPortRule(IpAddressFromAbcdWsz(NewRule.virtual_ip_addr), NewRule.start_port, &OldRule );
  641. bOldRuleSaved = true;
  642. pCluster->DeletePortRule(IpAddressFromAbcdWsz(NewRule.virtual_ip_addr), NewRule.start_port );
  643. }
  644. //add the port rule, roll back if failed
  645. try {
  646. pCluster->PutPortRule( &NewRule );
  647. } catch(...) {
  648. if( bOldRuleSaved )
  649. pCluster->PutPortRule( &OldRule );
  650. throw;
  651. }
  652. //release resources
  653. // CLD: Need to check return code for error
  654. if (S_OK != VariantClear( &vValue ))
  655. throw _com_error( WBEM_E_FAILED );
  656. m_pResponseHandler->SetStatus( 0, WBEM_S_NO_ERROR, NULL, NULL );
  657. hRes = WBEM_S_NO_ERROR;
  658. }
  659. catch(CErrorWlbsControl Err) {
  660. IWbemClassObject* pWbemExtStat = NULL;
  661. CreateExtendedStatus( m_pNameSpace,
  662. &pWbemExtStat,
  663. Err.Error(),
  664. (PWCHAR)(Err.Description()) );
  665. m_pResponseHandler->SetStatus(0, WBEM_E_FAILED, NULL, pWbemExtStat);
  666. if( pWbemExtStat )
  667. pWbemExtStat->Release();
  668. // CLD: Need to check return code for error
  669. // No throw here since we are already throwing an exception.
  670. VariantClear( &vValue );
  671. //do not return WBEM_E_FAILED, this causes a race condition
  672. hRes = WBEM_S_NO_ERROR;
  673. }
  674. catch(_com_error HResErr ) {
  675. m_pResponseHandler->SetStatus(0, HResErr.Error(), NULL, NULL);
  676. // CLD: Need to check return code for error
  677. // No throw here since we are already throwing an exception.
  678. VariantClear( &vValue );
  679. hRes = HResErr.Error();
  680. }
  681. catch (...) {
  682. // CLD: Need to check return code for error
  683. // No throw here since we are already throwing an exception.
  684. VariantClear( &vValue );
  685. throw;
  686. }
  687. return hRes;
  688. }
  689. ////////////////////////////////////////////////////////////////////////////////
  690. //
  691. // CWLBS_PortRule::FillWbemInstance
  692. //
  693. // Purpose: This function copies all of the data from a node configuration
  694. // structure to a WBEM instance.
  695. //
  696. ////////////////////////////////////////////////////////////////////////////////
  697. void CWLBS_PortRule::FillWbemInstance
  698. (
  699. CWlbsClusterWrapper* pCluster,
  700. IWbemClassObject* a_pWbemInstance,
  701. const PWLBS_PORT_RULE& a_pPortRule
  702. )
  703. {
  704. namespace PRFO = MOF_PRFAIL;
  705. namespace PRLB = MOF_PRLOADBAL;
  706. namespace PR = MOF_PORTRULE;
  707. ASSERT( a_pWbemInstance );
  708. wstring wstrHostName;
  709. ConstructHostName( wstrHostName, pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  710. pCluster->GetHostID());
  711. //NAME
  712. HRESULT hRes = a_pWbemInstance->Put
  713. (
  714. _bstr_t( PR::pProperties[PR::NAME] ) ,
  715. 0 ,
  716. &_variant_t(wstrHostName.c_str()),
  717. NULL
  718. );
  719. if( FAILED( hRes ) )
  720. throw _com_error( hRes );
  721. //STPORT
  722. hRes = a_pWbemInstance->Put
  723. (
  724. _bstr_t( PR::pProperties[PR::STPORT] ),
  725. 0 ,
  726. &_variant_t(static_cast<long>(a_pPortRule->start_port)),
  727. NULL
  728. );
  729. if( FAILED( hRes ) )
  730. throw _com_error( hRes );
  731. //EDPORT
  732. hRes = a_pWbemInstance->Put
  733. (
  734. _bstr_t( PR::pProperties[PR::EDPORT] ),
  735. 0 ,
  736. &_variant_t(static_cast<long>(a_pPortRule->end_port)),
  737. NULL
  738. );
  739. if( FAILED( hRes ) )
  740. throw _com_error( hRes );
  741. //ADAPTERGUID
  742. GUID AdapterGuid = pCluster->GetAdapterGuid();
  743. WCHAR szAdapterGuid[128];
  744. StringFromGUID2(AdapterGuid, szAdapterGuid,
  745. sizeof(szAdapterGuid)/sizeof(szAdapterGuid[0]) );
  746. hRes = a_pWbemInstance->Put
  747. (
  748. _bstr_t( PR::pProperties[PR::ADAPTERGUID] ),
  749. 0 ,
  750. &_variant_t(szAdapterGuid),
  751. NULL
  752. );
  753. if( FAILED( hRes ) )
  754. throw _com_error( hRes );
  755. //PROT
  756. hRes = a_pWbemInstance->Put
  757. (
  758. _bstr_t( PR::pProperties[PR::PROT] ),
  759. 0,
  760. &_variant_t(static_cast<long>(a_pPortRule->protocol)),
  761. NULL
  762. );
  763. if( FAILED( hRes ) )
  764. throw _com_error( hRes );
  765. switch( a_pPortRule->mode ) {
  766. case WLBS_SINGLE:
  767. //PRIO
  768. hRes = a_pWbemInstance->Put
  769. (
  770. _bstr_t( MOF_PRFAIL::pProperties[MOF_PRFAIL::PRIO] ),
  771. 0 ,
  772. &_variant_t(static_cast<long>(a_pPortRule->mode_data.single.priority)),
  773. NULL
  774. );
  775. if( FAILED( hRes ) )
  776. throw _com_error( hRes );
  777. break;
  778. case WLBS_MULTI:
  779. //EQLD
  780. hRes = a_pWbemInstance->Put
  781. (
  782. _bstr_t( PRLB::pProperties[PRLB::EQLD] ),
  783. 0 ,
  784. &_variant_t((a_pPortRule->mode_data.multi.equal_load != 0)),
  785. NULL
  786. );
  787. if( FAILED( hRes ) )
  788. throw _com_error( hRes );
  789. //LDWT
  790. hRes = a_pWbemInstance->Put
  791. (
  792. _bstr_t( PRLB::pProperties[PRLB::LDWT] ),
  793. 0 ,
  794. &_variant_t(static_cast<long>(a_pPortRule->mode_data.multi.load)),
  795. NULL
  796. );
  797. if( FAILED( hRes ) )
  798. throw _com_error( hRes );
  799. //AFFIN
  800. hRes = a_pWbemInstance->Put
  801. (
  802. _bstr_t( PRLB::pProperties[PRLB::AFFIN] ),
  803. 0 ,
  804. &_variant_t(static_cast<long>(a_pPortRule->mode_data.multi.affinity)),
  805. NULL
  806. );
  807. if( FAILED( hRes ) )
  808. throw _com_error( hRes );
  809. break;
  810. case WLBS_NEVER:
  811. //there are no properties
  812. break;
  813. default:
  814. throw _com_error( WBEM_E_FAILED );
  815. }
  816. }