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.

1176 lines
32 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(a_pParsedPath->m_pClass, 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(a_bstrClass, 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. DWORD dwVip, dwReqStartPort;
  437. wstrHostName = (*a_pParsedPath->m_paKeys)->m_vValue.bstrVal;
  438. CWlbsClusterWrapper* pCluster = GetClusterFromHostName(g_pWlbsControl, wstrHostName);
  439. if (pCluster == NULL)
  440. {
  441. throw _com_error( WBEM_E_NOT_FOUND );
  442. }
  443. // If the instance to be deleted is of type "PortRuleEx", then, retreive the vip, otherwise
  444. // verify that we are operating in the "all vip" mode
  445. if (_wcsicmp(a_pParsedPath->m_pClass, MOF_CLASSES::g_szMOFClassList[MOF_CLASSES::PRVIP]) == 0)
  446. {
  447. dwVip = IpAddressFromAbcdWsz((*(a_pParsedPath->m_paKeys + 1))->m_vValue.bstrVal);
  448. dwReqStartPort = static_cast<DWORD>( (*(a_pParsedPath->m_paKeys + 2))->m_vValue.lVal );
  449. }
  450. else
  451. {
  452. // The "PortRule(Disabled/Failover/Loadbalanced)" classes do NOT contain the VIP property,
  453. // so, we do not want to operate on any cluster that has a port rule
  454. // that is specific to a vip (other than the "all vip")
  455. // The "EffectiveVersion" registry value is checked for a value of CVY_VERSION_FULL to
  456. // see of there is any port rule that is specific to a vip
  457. CNodeConfiguration NodeConfig;
  458. pCluster->GetNodeConfig(NodeConfig);
  459. if(NodeConfig.dwEffectiveVersion == CVY_VERSION_FULL)
  460. throw _com_error( WBEM_E_INVALID_OPERATION );
  461. dwVip = IpAddressFromAbcdWsz(CVY_DEF_ALL_VIP);
  462. dwReqStartPort = static_cast<DWORD>( (*(a_pParsedPath->m_paKeys + 1))->m_vValue.lVal );
  463. }
  464. WLBS_PORT_RULE PortRule;
  465. // Get the port rule for this vip & port
  466. pCluster->GetPortRule(dwVip, dwReqStartPort, &PortRule );
  467. if( (dwVip != IpAddressFromAbcdWsz(PortRule.virtual_ip_addr)) || (dwReqStartPort != PortRule.start_port) )
  468. throw _com_error( WBEM_E_NOT_FOUND );
  469. // Delete the port rule for this vip & port
  470. pCluster->DeletePortRule(dwVip, dwReqStartPort );
  471. m_pResponseHandler->SetStatus( 0, WBEM_S_NO_ERROR, NULL, NULL );
  472. hRes = WBEM_S_NO_ERROR;
  473. }
  474. catch(CErrorWlbsControl Err) {
  475. IWbemClassObject* pWbemExtStat = NULL;
  476. CreateExtendedStatus( m_pNameSpace,
  477. &pWbemExtStat,
  478. Err.Error(),
  479. (PWCHAR)(Err.Description()) );
  480. m_pResponseHandler->SetStatus(0, WBEM_E_FAILED, NULL, pWbemExtStat);
  481. if( pWbemExtStat )
  482. pWbemExtStat->Release();
  483. //do not return WBEM_E_FAILED, this causes a race condition
  484. hRes = WBEM_S_NO_ERROR;
  485. }
  486. catch(_com_error HResErr ) {
  487. m_pResponseHandler->SetStatus(0, HResErr.Error(), NULL, NULL);
  488. hRes = HResErr.Error();
  489. }
  490. return hRes;
  491. }
  492. ////////////////////////////////////////////////////////////////////////////////
  493. //
  494. // CWLBS_PortRule::PutInstance
  495. //
  496. // Purpose: This function updates an instance of a PortRule
  497. // class. The host does not have to be a member of a cluster.
  498. //
  499. ////////////////////////////////////////////////////////////////////////////////
  500. HRESULT CWLBS_PortRule::PutInstance
  501. (
  502. IWbemClassObject* a_pInstance,
  503. long /*a_lFlags*/,
  504. IWbemContext* /*a_pIContex*/
  505. )
  506. {
  507. VARIANT vValue;
  508. HRESULT hRes = 0;
  509. WLBS_PORT_RULE NewRule; //the instance to put
  510. namespace PR, PRFO, PRLB;
  511. bool bPREx;
  512. try {
  513. VariantInit( &vValue );
  514. //get the class name to determine port rule mode
  515. hRes = a_pInstance->Get( _bstr_t( L"__Class" ),
  516. 0,
  517. &vValue,
  518. NULL,
  519. NULL );
  520. if( FAILED( hRes ) )
  521. throw _com_error( hRes );
  522. wcscpy(szClassName, vValue.bstrVal);
  523. // If it is a port rule class containing the VIP, then, the namespaces are different
  524. if (_wcsicmp(szClassName, MOF_CLASSES::g_szMOFClassList[MOF_CLASSES::PORTRULE_EX]) == 0)
  525. {
  526. bPREx = true;
  527. PR = PRFO = PRLB = MOF_PORTRULE_EX;
  528. }
  529. else
  530. {
  531. bPREx = false;
  532. PR = MOF_PORTRULE;
  533. PRFO = MOF_PRFAIL;
  534. PRLB = MOF_PRLOADBAL;
  535. }
  536. // Need to check return code for error
  537. if (S_OK != VariantClear( &vValue ))
  538. throw _com_error( WBEM_E_FAILED );
  539. //get the host name value
  540. hRes = a_pInstance->Get( _bstr_t( PR::pProperties[PR::NAME] ),
  541. 0,
  542. &vValue,
  543. NULL,
  544. NULL );
  545. if( FAILED( hRes ) )
  546. throw _com_error( hRes );
  547. wstring wstrHostName( vValue.bstrVal );
  548. CWlbsClusterWrapper* pCluster = GetClusterFromHostName(g_pWlbsControl, wstrHostName);
  549. if (pCluster == NULL)
  550. {
  551. throw _com_error( WBEM_E_NOT_FOUND );
  552. }
  553. // CLD: Need to check return code for error
  554. if (S_OK != VariantClear( &vValue ))
  555. throw _com_error( WBEM_E_FAILED );
  556. // If the instance to be put is of type "PortRuleEx", then, retreive the vip, otherwise
  557. // verify that we are operating in the "all vip" mode
  558. if (bPREx)
  559. {
  560. //get the vip
  561. hRes = a_pInstance->Get( _bstr_t( PR::pProperties[PR::VIP] ),
  562. 0,
  563. &vValue,
  564. NULL,
  565. NULL );
  566. if( FAILED( hRes ) )
  567. throw _com_error( hRes );
  568. wcscpy(NewRule.virtual_ip_addr, vValue.bstrVal);
  569. if (S_OK != VariantClear( &vValue ))
  570. throw _com_error( WBEM_E_FAILED );
  571. }
  572. else
  573. {
  574. // The "PortRule(Disabled/Failover/Loadbalanced)" classes do NOT contain the VIP property,
  575. // so, we do not want to operate on any cluster that has a port rule
  576. // that is specific to a vip (other than the "all vip")
  577. // The "EffectiveVersion" registry value is checked for a value of CVY_VERSION_FULL to
  578. // see of there is any port rule that is specific to a vip
  579. CNodeConfiguration NodeConfig;
  580. pCluster->GetNodeConfig(NodeConfig);
  581. if(NodeConfig.dwEffectiveVersion == CVY_VERSION_FULL)
  582. throw _com_error( WBEM_E_INVALID_OPERATION );
  583. wcscpy(NewRule.virtual_ip_addr, CVY_DEF_ALL_VIP);
  584. }
  585. //retrieve start and end ports
  586. hRes = a_pInstance->Get( _bstr_t( PR::pProperties[PR::STPORT] ),
  587. 0,
  588. &vValue,
  589. NULL,
  590. NULL );
  591. if( FAILED( hRes ) )
  592. throw _com_error( hRes );
  593. NewRule.start_port = static_cast<DWORD>( vValue.lVal );
  594. hRes = a_pInstance->Get( _bstr_t( PR::pProperties[PR::EDPORT] ),
  595. 0,
  596. &vValue,
  597. NULL,
  598. NULL );
  599. if( FAILED( hRes ) )
  600. throw _com_error( hRes );
  601. NewRule.end_port = static_cast<DWORD>( vValue.lVal );
  602. //get the protocol
  603. hRes = a_pInstance->Get( _bstr_t( PR::pProperties[PR::PROT] ),
  604. 0,
  605. &vValue,
  606. NULL,
  607. NULL );
  608. if( FAILED( hRes ) )
  609. throw _com_error( hRes );
  610. NewRule.protocol = static_cast<DWORD>( vValue.lVal );
  611. if( _wcsicmp( szClassName, MOF_PRDIS::szName ) == 0 ) {
  612. NewRule.mode = WLBS_NEVER;
  613. } else if(_wcsicmp( szClassName, PRFO::szName ) == 0 ) {
  614. NewRule.mode = WLBS_SINGLE;
  615. VARIANT vRulePriority;
  616. VariantInit( &vRulePriority );
  617. try {
  618. //get the rule priority
  619. hRes = a_pInstance->Get( _bstr_t( PRFO::pProperties[PRFO::PRIO] ),
  620. 0,
  621. &vRulePriority,
  622. NULL,
  623. NULL );
  624. if( FAILED( hRes ) )
  625. throw _com_error( hRes );
  626. }
  627. catch( ... ) {
  628. // CLD: Need to check return code for error
  629. // No throw here since we are already throwing an exception.
  630. VariantClear( &vRulePriority );
  631. throw;
  632. }
  633. NewRule.mode_data.single.priority = static_cast<DWORD>( vRulePriority.lVal );
  634. // CLD: Need to check return code for error
  635. if (S_OK != VariantClear( &vRulePriority ))
  636. throw _com_error( WBEM_E_FAILED );
  637. } else if(_wcsicmp( szClassName, PRLB::szName ) == 0 ) {
  638. NewRule.mode = WLBS_MULTI;
  639. VARIANT v;
  640. VariantInit( &v );
  641. try {
  642. //get the affinity
  643. hRes = a_pInstance->Get( _bstr_t( PRLB::pProperties[PRLB::AFFIN] ),
  644. 0,
  645. &v,
  646. NULL,
  647. NULL );
  648. if( FAILED( hRes ) )
  649. throw _com_error( hRes );
  650. NewRule.mode_data.multi.affinity = static_cast<WORD>( v.lVal );
  651. //get the equal load boolean
  652. hRes = a_pInstance->Get( _bstr_t( PRLB::pProperties[PRLB::EQLD] ),
  653. 0,
  654. &v,
  655. NULL,
  656. NULL );
  657. if( FAILED( hRes ) )
  658. throw _com_error( hRes );
  659. if( v.boolVal == -1 ) {
  660. NewRule.mode_data.multi.equal_load = 1;
  661. } else {
  662. NewRule.mode_data.multi.equal_load = 0;
  663. }
  664. //get the load
  665. hRes = a_pInstance->Get( _bstr_t( PRLB::pProperties[PRLB::LDWT] ),
  666. 0,
  667. &v,
  668. NULL,
  669. NULL );
  670. if( FAILED( hRes ) )
  671. throw _com_error( hRes );
  672. if( v.vt != VT_NULL )
  673. NewRule.mode_data.multi.load = static_cast<DWORD>( v.lVal );
  674. else
  675. NewRule.mode_data.multi.load = 0;
  676. } catch( ... ) {
  677. // CLD: Need to check return code for error
  678. // No throw here since we are already throwing an exception.
  679. VariantClear( &v );
  680. throw;
  681. }
  682. // CLD: Need to check return code for error
  683. if (S_OK != VariantClear( &v ))
  684. throw _com_error( WBEM_E_FAILED );
  685. }
  686. //delete the port rule but cache in case of failure
  687. WLBS_PORT_RULE OldRule;
  688. bool bOldRuleSaved = false;
  689. if( pCluster->RuleExists(IpAddressFromAbcdWsz(NewRule.virtual_ip_addr), NewRule.start_port ) ) {
  690. pCluster->GetPortRule(IpAddressFromAbcdWsz(NewRule.virtual_ip_addr), NewRule.start_port, &OldRule );
  691. bOldRuleSaved = true;
  692. pCluster->DeletePortRule(IpAddressFromAbcdWsz(NewRule.virtual_ip_addr), NewRule.start_port );
  693. }
  694. //add the port rule, roll back if failed
  695. try {
  696. pCluster->PutPortRule( &NewRule );
  697. } catch(...) {
  698. if( bOldRuleSaved )
  699. pCluster->PutPortRule( &OldRule );
  700. throw;
  701. }
  702. //release resources
  703. // CLD: Need to check return code for error
  704. if (S_OK != VariantClear( &vValue ))
  705. throw _com_error( WBEM_E_FAILED );
  706. m_pResponseHandler->SetStatus( 0, WBEM_S_NO_ERROR, NULL, NULL );
  707. hRes = WBEM_S_NO_ERROR;
  708. }
  709. catch(CErrorWlbsControl Err) {
  710. IWbemClassObject* pWbemExtStat = NULL;
  711. CreateExtendedStatus( m_pNameSpace,
  712. &pWbemExtStat,
  713. Err.Error(),
  714. (PWCHAR)(Err.Description()) );
  715. m_pResponseHandler->SetStatus(0, WBEM_E_FAILED, NULL, pWbemExtStat);
  716. if( pWbemExtStat )
  717. pWbemExtStat->Release();
  718. // CLD: Need to check return code for error
  719. // No throw here since we are already throwing an exception.
  720. VariantClear( &vValue );
  721. //do not return WBEM_E_FAILED, this causes a race condition
  722. hRes = WBEM_S_NO_ERROR;
  723. }
  724. catch(_com_error HResErr ) {
  725. m_pResponseHandler->SetStatus(0, HResErr.Error(), NULL, NULL);
  726. // CLD: Need to check return code for error
  727. // No throw here since we are already throwing an exception.
  728. VariantClear( &vValue );
  729. hRes = HResErr.Error();
  730. }
  731. catch (...) {
  732. // CLD: Need to check return code for error
  733. // No throw here since we are already throwing an exception.
  734. VariantClear( &vValue );
  735. throw;
  736. }
  737. return hRes;
  738. }
  739. ////////////////////////////////////////////////////////////////////////////////
  740. //
  741. // CWLBS_PortRule::FillWbemInstance
  742. //
  743. // Purpose: This function copies all of the data from a node configuration
  744. // structure to a WBEM instance.
  745. //
  746. ////////////////////////////////////////////////////////////////////////////////
  747. void CWLBS_PortRule::FillWbemInstance
  748. (
  749. LPCWSTR a_szClassName,
  750. CWlbsClusterWrapper* pCluster,
  751. IWbemClassObject* a_pWbemInstance,
  752. const PWLBS_PORT_RULE& a_pPortRule
  753. )
  754. {
  755. namespace PR, PRFO, PRLB;
  756. bool bPRVip;
  757. ASSERT( a_pWbemInstance );
  758. // If it is a port rule class containing the VIP, then, the namespaces are different
  759. if (_wcsicmp(a_szClassName, MOF_CLASSES::g_szMOFClassList[MOF_CLASSES::PORTRULE_EX]) == 0)
  760. {
  761. bPRVip = true;
  762. PR = PRFO = PRLB = MOF_PORTRULE_EX;
  763. }
  764. else
  765. {
  766. bPRVip = false;
  767. PR = MOF_PORTRULE;
  768. PRFO = MOF_PRFAIL;
  769. PRLB = MOF_PRLOADBAL;
  770. }
  771. wstring wstrHostName;
  772. ConstructHostName( wstrHostName, pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  773. pCluster->GetHostID());
  774. //NAME
  775. HRESULT hRes = a_pWbemInstance->Put
  776. (
  777. _bstr_t( PR::pProperties[PR::NAME] ) ,
  778. 0 ,
  779. &_variant_t(wstrHostName.c_str()),
  780. NULL
  781. );
  782. if( FAILED( hRes ) )
  783. throw _com_error( hRes );
  784. // Fill in VIP if it is a port rule class containing VIP
  785. if (bPRVip) {
  786. HRESULT hRes = a_pWbemInstance->Put
  787. (
  788. _bstr_t( PR::pProperties[PR::VIP] ) ,
  789. 0 ,
  790. &_variant_t(a_pPortRule->virtual_ip_addr),
  791. NULL
  792. );
  793. if( FAILED( hRes ) )
  794. throw _com_error( hRes );
  795. }
  796. //STPORT
  797. hRes = a_pWbemInstance->Put
  798. (
  799. _bstr_t( PR::pProperties[PR::STPORT] ),
  800. 0 ,
  801. &_variant_t(static_cast<long>(a_pPortRule->start_port)),
  802. NULL
  803. );
  804. if( FAILED( hRes ) )
  805. throw _com_error( hRes );
  806. //EDPORT
  807. hRes = a_pWbemInstance->Put
  808. (
  809. _bstr_t( PR::pProperties[PR::EDPORT] ),
  810. 0 ,
  811. &_variant_t(static_cast<long>(a_pPortRule->end_port)),
  812. NULL
  813. );
  814. if( FAILED( hRes ) )
  815. throw _com_error( hRes );
  816. //ADAPTERGUID
  817. GUID AdapterGuid = pCluster->GetAdapterGuid();
  818. WCHAR szAdapterGuid[128];
  819. StringFromGUID2(AdapterGuid, szAdapterGuid,
  820. sizeof(szAdapterGuid)/sizeof(szAdapterGuid[0]) );
  821. hRes = a_pWbemInstance->Put
  822. (
  823. _bstr_t( PR::pProperties[PR::ADAPTERGUID] ),
  824. 0 ,
  825. &_variant_t(szAdapterGuid),
  826. NULL
  827. );
  828. if( FAILED( hRes ) )
  829. throw _com_error( hRes );
  830. //PROT
  831. hRes = a_pWbemInstance->Put
  832. (
  833. _bstr_t( PR::pProperties[PR::PROT] ),
  834. 0,
  835. &_variant_t(static_cast<long>(a_pPortRule->protocol)),
  836. NULL
  837. );
  838. if( FAILED( hRes ) )
  839. throw _com_error( hRes );
  840. // If it is a port rule class containing all parameters of all filtering modes,
  841. // initialize them with a "don't care" value (zero). The appropriate fields (depending on filtering mode)
  842. // are filled in later.
  843. if (bPRVip) {
  844. hRes = a_pWbemInstance->Put ( _bstr_t( PRLB::pProperties[PRLB::EQLD] ), 0, &_variant_t(0), NULL);
  845. if( FAILED( hRes ) )
  846. throw _com_error( hRes );
  847. hRes = a_pWbemInstance->Put ( _bstr_t( PRLB::pProperties[PRLB::LDWT] ), 0, &_variant_t(0), NULL);
  848. if( FAILED( hRes ) )
  849. throw _com_error( hRes );
  850. hRes = a_pWbemInstance->Put ( _bstr_t( PRLB::pProperties[PRLB::AFFIN] ), 0, &_variant_t(0), NULL);
  851. if( FAILED( hRes ) )
  852. throw _com_error( hRes );
  853. hRes = a_pWbemInstance->Put (_bstr_t( PRFO::pProperties[PRFO::PRIO] ), 0, &_variant_t(0), NULL);
  854. if( FAILED( hRes ) )
  855. throw _com_error( hRes );
  856. }
  857. // TO BE DONE : Fill in the "FilteringMode" for the PortRuleEx class
  858. switch( a_pPortRule->mode ) {
  859. case WLBS_SINGLE:
  860. //PRIO
  861. hRes = a_pWbemInstance->Put
  862. (
  863. _bstr_t( PRFO::pProperties[PRFO::PRIO] ),
  864. 0 ,
  865. &_variant_t(static_cast<long>(a_pPortRule->mode_data.single.priority)),
  866. NULL
  867. );
  868. if( FAILED( hRes ) )
  869. throw _com_error( hRes );
  870. break;
  871. case WLBS_MULTI:
  872. //EQLD
  873. hRes = a_pWbemInstance->Put
  874. (
  875. _bstr_t( PRLB::pProperties[PRLB::EQLD] ),
  876. 0 ,
  877. &_variant_t((a_pPortRule->mode_data.multi.equal_load != 0)),
  878. NULL
  879. );
  880. if( FAILED( hRes ) )
  881. throw _com_error( hRes );
  882. //LDWT
  883. hRes = a_pWbemInstance->Put
  884. (
  885. _bstr_t( PRLB::pProperties[PRLB::LDWT] ),
  886. 0 ,
  887. &_variant_t(static_cast<long>(a_pPortRule->mode_data.multi.load)),
  888. NULL
  889. );
  890. if( FAILED( hRes ) )
  891. throw _com_error( hRes );
  892. //AFFIN
  893. hRes = a_pWbemInstance->Put
  894. (
  895. _bstr_t( PRLB::pProperties[PRLB::AFFIN] ),
  896. 0 ,
  897. &_variant_t(static_cast<long>(a_pPortRule->mode_data.multi.affinity)),
  898. NULL
  899. );
  900. if( FAILED( hRes ) )
  901. throw _com_error( hRes );
  902. break;
  903. case WLBS_NEVER:
  904. //there are no properties
  905. break;
  906. default:
  907. throw _com_error( WBEM_E_FAILED );
  908. }
  909. }