Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1475 lines
49 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. #include <winsock.h>
  8. #include "WLBS_PortRule.tmh"
  9. #include <strsafe.h>
  10. extern CWlbsControlWrapper* g_pWlbsControl;
  11. ////////////////////////////////////////////////////////////////////////////////
  12. //
  13. // CWLBS_PortRule::CWLBS_PortRule
  14. //
  15. // Purpose: Constructor
  16. //
  17. ////////////////////////////////////////////////////////////////////////////////
  18. CWLBS_PortRule::CWLBS_PortRule
  19. (
  20. CWbemServices* a_pNameSpace,
  21. IWbemObjectSink* a_pResponseHandler
  22. )
  23. : CWlbs_Root( a_pNameSpace, a_pResponseHandler )
  24. {
  25. }
  26. ////////////////////////////////////////////////////////////////////////////////
  27. //
  28. // CWLBS_PortRule::Create
  29. //
  30. // Purpose: This instantiates this class and is invoked from an array of
  31. // function pointers.
  32. //
  33. ////////////////////////////////////////////////////////////////////////////////
  34. CWlbs_Root* CWLBS_PortRule::Create
  35. (
  36. CWbemServices* a_pNameSpace,
  37. IWbemObjectSink* a_pResponseHandler
  38. )
  39. {
  40. CWlbs_Root* pRoot = new CWLBS_PortRule( a_pNameSpace, a_pResponseHandler );
  41. if( !pRoot )
  42. throw _com_error( WBEM_E_OUT_OF_MEMORY );
  43. return pRoot;
  44. }
  45. ////////////////////////////////////////////////////////////////////////////////
  46. //
  47. // CWLBS_PortRule::ExecMethod
  48. //
  49. // Purpose:
  50. //
  51. ////////////////////////////////////////////////////////////////////////////////
  52. HRESULT CWLBS_PortRule::ExecMethod
  53. (
  54. const ParsedObjectPath* a_pParsedPath,
  55. const BSTR& a_strMethodName,
  56. long /* a_lFlags */,
  57. IWbemContext* /* a_pIContex */,
  58. IWbemClassObject* a_pIInParams
  59. )
  60. {
  61. IWbemClassObject* pOutputInstance = NULL;
  62. VARIANT vValue;
  63. HRESULT hRes = 0;
  64. TRACE_CRIT("->%!FUNC!, Method Name : %ls",a_strMethodName);
  65. try {
  66. VariantInit( &vValue );
  67. //determine the method being executed
  68. if( _wcsicmp( a_strMethodName, MOF_PORTRULE::pMethods[MOF_PORTRULE::SETDEF] ) == 0 )
  69. {
  70. //get the node path
  71. hRes = a_pIInParams->Get
  72. (
  73. _bstr_t( MOF_PARAM::NODEPATH ),
  74. 0,
  75. &vValue,
  76. NULL,
  77. NULL
  78. );
  79. if( FAILED( hRes) )
  80. {
  81. TRACE_CRIT("%!FUNC!, Error trying to retreive Argument : %ls of method %ls, Throwing WBEM_E_FAILED exception", MOF_PARAM::NODEPATH, a_strMethodName);
  82. throw _com_error( WBEM_E_FAILED );
  83. }
  84. //this check may not be necessary since WMI will do some
  85. //parameter validation
  86. //if( vValue.vt != VT_BSTR )
  87. // throw _com_error ( WBEM_E_INVALID_PARAMETER );
  88. //parse node path
  89. CObjectPathParser PathParser;
  90. ParsedObjectPath *pParsedPath = NULL;
  91. try {
  92. int nStatus = PathParser.Parse( vValue.bstrVal, &pParsedPath );
  93. if(nStatus != 0) {
  94. if (NULL != pParsedPath)
  95. {
  96. PathParser.Free( pParsedPath );
  97. pParsedPath = NULL;
  98. }
  99. TRACE_CRIT("%!FUNC!, Error (0x%x) trying to parse Argument : %ls of method %ls, Throwing WBEM_E_INVALID_PARAMETER exception",nStatus, MOF_PARAM::NODEPATH, a_strMethodName);
  100. throw _com_error( WBEM_E_INVALID_PARAMETER );
  101. }
  102. //get the name key, which should be the only key
  103. if( *pParsedPath->m_paKeys == NULL )
  104. {
  105. TRACE_CRIT("%!FUNC!, Argument : %ls of method %ls does not contain key, Throwing WBEM_E_INVALID_PARAMETER exception",MOF_PARAM::NODEPATH, a_strMethodName);
  106. throw _com_error( WBEM_E_INVALID_PARAMETER );
  107. }
  108. DWORD dwReqClusterIpOrIndex = ExtractClusterIP( (*pParsedPath->m_paKeys)->m_vValue.bstrVal);
  109. DWORD dwReqHostID = ExtractHostID( (*pParsedPath->m_paKeys)->m_vValue.bstrVal);
  110. CWlbsClusterWrapper* pCluster = g_pWlbsControl->GetClusterFromIpOrIndex(
  111. dwReqClusterIpOrIndex);
  112. if (pCluster == NULL || (DWORD)-1 == dwReqHostID)
  113. {
  114. TRACE_CRIT("%!FUNC! ExtractClusterIP or ExtractHostID or GetClusterFromIpOrIndex failed, Throwing com_error WBEM_E_INVALID_PARAMETER exception");
  115. throw _com_error( WBEM_E_INVALID_PARAMETER );
  116. }
  117. // If the instance on which this method is called is NOT of type "PortRuleEx", then,
  118. // verify that we are operating in the "all vip" mode
  119. if (_wcsicmp(a_pParsedPath->m_pClass, MOF_CLASSES::g_szMOFClassList[MOF_CLASSES::PORTRULE_EX]) != 0)
  120. {
  121. // The "PortRule(Disabled/Failover/Loadbalanced)" classes do NOT contain the VIP property,
  122. // so, we do not want to operate on any cluster that has a port rule
  123. // that is specific to a vip (other than the "all vip")
  124. // The "EffectiveVersion" registry value is checked for a value of CVY_VERSION_FULL to
  125. // see of there is any port rule that is specific to a vip
  126. CNodeConfiguration NodeConfig;
  127. pCluster->GetNodeConfig(NodeConfig);
  128. if(NodeConfig.dwEffectiveVersion == CVY_VERSION_FULL)
  129. {
  130. TRACE_CRIT("%!FUNC! %ls method called on %ls class on a cluster that has per-vip port rules (Must call this method on the %ls class instead). Throwing com_error WBEM_E_INVALID_OPERATION exception", a_strMethodName,a_pParsedPath->m_pClass,MOF_CLASSES::g_szMOFClassList[MOF_CLASSES::PORTRULE_EX]);
  131. throw _com_error( WBEM_E_INVALID_OPERATION );
  132. }
  133. }
  134. //validate host ID
  135. if( dwReqHostID != pCluster->GetHostID())
  136. {
  137. TRACE_CRIT("%!FUNC! Host Id validation failed, Host Id passed : 0x%x, Host Id per system : 0x%x", dwReqHostID, pCluster->GetHostID());
  138. throw _com_error( WBEM_E_INVALID_PARAMETER );
  139. }
  140. //invoke method
  141. pCluster->SetPortRuleDefaults();
  142. }
  143. catch( ... ) {
  144. if( pParsedPath )
  145. {
  146. PathParser.Free( pParsedPath );
  147. pParsedPath = NULL;
  148. }
  149. throw;
  150. }
  151. } else {
  152. TRACE_CRIT("%!FUNC! %ls method NOT implemented, Throwing WBEM_E_METHOD_NOT_IMPLEMENTED exception",a_strMethodName);
  153. throw _com_error( WBEM_E_METHOD_NOT_IMPLEMENTED );
  154. }
  155. // CLD: Need to check return code for error
  156. if (S_OK != VariantClear( &vValue ))
  157. {
  158. TRACE_CRIT("%!FUNC! VariantClear() failed, Throwing WBEM_E_FAILED exception");
  159. throw _com_error( WBEM_E_FAILED );
  160. }
  161. if( pOutputInstance ) {
  162. pOutputInstance->Release();
  163. pOutputInstance = NULL;
  164. }
  165. m_pResponseHandler->SetStatus( 0, WBEM_S_NO_ERROR, NULL, NULL );
  166. hRes = WBEM_S_NO_ERROR;
  167. }
  168. catch(CErrorWlbsControl Err) {
  169. IWbemClassObject* pWbemExtStat = NULL;
  170. TRACE_CRIT("%!FUNC! Caught a Wlbs exception : 0x%x", Err.Error());
  171. CreateExtendedStatus( m_pNameSpace,
  172. &pWbemExtStat,
  173. Err.Error(),
  174. (PWCHAR)(Err.Description()) );
  175. m_pResponseHandler->SetStatus(0, WBEM_E_FAILED, NULL, pWbemExtStat);
  176. if( pWbemExtStat )
  177. pWbemExtStat->Release();
  178. // CLD: Need to check return code for error
  179. // No throw here since we are already throwing an exception.
  180. VariantClear( &vValue );
  181. if( pOutputInstance ) {
  182. pOutputInstance->Release();
  183. pOutputInstance = NULL;
  184. }
  185. //do not return WBEM_E_FAILED, this causes a race condition
  186. hRes = WBEM_S_NO_ERROR;
  187. }
  188. catch(_com_error HResErr ) {
  189. TRACE_CRIT("%!FUNC! Caught a com_error exception : 0x%x", HResErr.Error());
  190. m_pResponseHandler->SetStatus(0, HResErr.Error(), NULL, NULL);
  191. // CLD: Need to check return code for error
  192. // No throw here since we are already throwing an exception.
  193. VariantClear( &vValue );
  194. if( pOutputInstance ) {
  195. pOutputInstance->Release();
  196. }
  197. hRes = HResErr.Error();
  198. }
  199. catch ( ... ) {
  200. TRACE_CRIT("%!FUNC! Caught an exception");
  201. // CLD: Need to check return code for error
  202. // No throw here since we are already throwing an exception.
  203. VariantClear( &vValue );
  204. if( pOutputInstance ) {
  205. pOutputInstance->Release();
  206. }
  207. TRACE_CRIT("%!FUNC! Rethrowing exception");
  208. TRACE_CRIT("<-%!FUNC!");
  209. throw;
  210. }
  211. TRACE_CRIT("<-%!FUNC! return 0x%x", hRes);
  212. return hRes;
  213. }
  214. ////////////////////////////////////////////////////////////////////////////////
  215. //
  216. // CWLBS_PortRule::GetInstance
  217. //
  218. // Purpose: This function retrieves an instance of a MOF PortRule
  219. // class. The node does not have to be a member of a cluster.
  220. //
  221. ////////////////////////////////////////////////////////////////////////////////
  222. HRESULT CWLBS_PortRule::GetInstance
  223. (
  224. const ParsedObjectPath* a_pParsedPath,
  225. long /* a_lFlags */,
  226. IWbemContext* /* a_pIContex */
  227. )
  228. {
  229. IWbemClassObject* pWlbsInstance = NULL;
  230. HRESULT hRes = 0;
  231. TRACE_CRIT("->%!FUNC!");
  232. try {
  233. if( !a_pParsedPath )
  234. {
  235. TRACE_CRIT("%!FUNC! Did not pass class name & key of the instance to Get");
  236. throw _com_error( WBEM_E_FAILED );
  237. }
  238. wstring wstrHostName;
  239. wstrHostName = (*a_pParsedPath->m_paKeys)->m_vValue.bstrVal;
  240. CWlbsClusterWrapper* pCluster = GetClusterFromHostName(g_pWlbsControl, wstrHostName);
  241. if (pCluster == NULL)
  242. {
  243. TRACE_CRIT("%!FUNC! GetClusterFromHostName failed for Host name = %ls, Throwing com_error WBEM_E_NOT_FOUND exception",wstrHostName.data());
  244. throw _com_error( WBEM_E_NOT_FOUND );
  245. }
  246. DWORD dwVip, dwReqStartPort;
  247. // If the instance to be retreived is of type "PortRuleEx", then, retreive the vip, otherwise
  248. // verify that we are operating in the "all vip" mode
  249. if (_wcsicmp(a_pParsedPath->m_pClass, MOF_CLASSES::g_szMOFClassList[MOF_CLASSES::PORTRULE_EX]) == 0)
  250. {
  251. WCHAR *szVip;
  252. // The Keys are ordered alphabetically, hence "Name", "StartPort", "VirtualIpAddress" is the order
  253. dwReqStartPort = static_cast<DWORD>( (*(a_pParsedPath->m_paKeys + 1))->m_vValue.lVal );
  254. szVip = (*(a_pParsedPath->m_paKeys + 2))->m_vValue.bstrVal;
  255. // If the VIP is "All Vip", then, fill in the numeric value
  256. // directly from the macro, else use the conversion function.
  257. // This is 'cos INADDR_NONE, the return value of inet_addr
  258. // function (called by IpAddressFromAbcdWsz) in the failure
  259. // case, is equivalent to the numeric value of CVY_DEF_ALL_VIP
  260. if (_wcsicmp(szVip, CVY_DEF_ALL_VIP) == 0) {
  261. dwVip = CVY_ALL_VIP_NUMERIC_VALUE;
  262. }
  263. else {
  264. dwVip = IpAddressFromAbcdWsz( szVip );
  265. if (dwVip == INADDR_NONE)
  266. {
  267. TRACE_CRIT("%!FUNC! Invalid value (%ls) passed for %ls for Class %ls. Throwing com_error WBEM_E_INVALID_PARAMETER exception", szVip, MOF_PARAM::VIP, a_pParsedPath->m_pClass);
  268. throw _com_error ( WBEM_E_INVALID_PARAMETER );
  269. }
  270. }
  271. }
  272. else
  273. {
  274. // The "PortRule(Disabled/Failover/Loadbalanced)" classes do NOT contain the VIP property,
  275. // so, we do not want to operate on any cluster that has a port rule
  276. // that is specific to a vip (other than the "all vip")
  277. // The "EffectiveVersion" registry value is checked for a value of CVY_VERSION_FULL to
  278. // see of there is any port rule that is specific to a vip
  279. CNodeConfiguration NodeConfig;
  280. pCluster->GetNodeConfig(NodeConfig);
  281. if(NodeConfig.dwEffectiveVersion == CVY_VERSION_FULL)
  282. {
  283. TRACE_CRIT("%!FUNC! called on Class : %ls on a cluster that has per-vip port rules (Must call the \"Ex\" equivalent instead). Throwing com_error WBEM_E_INVALID_OPERATION exception", a_pParsedPath->m_pClass);
  284. throw _com_error( WBEM_E_INVALID_OPERATION );
  285. }
  286. dwReqStartPort = static_cast<DWORD>( (*(a_pParsedPath->m_paKeys + 1))->m_vValue.lVal );
  287. dwVip = IpAddressFromAbcdWsz(CVY_DEF_ALL_VIP);
  288. }
  289. WLBS_PORT_RULE PortRule;
  290. pCluster->GetPortRule(dwVip, dwReqStartPort, &PortRule );
  291. if( (dwVip != IpAddressFromAbcdWsz(PortRule.virtual_ip_addr))
  292. || (dwReqStartPort != PortRule.start_port) )
  293. {
  294. TRACE_CRIT("%!FUNC! could not retreive port rule for vip : 0x%x & port : 0x%x, Throwing com_error WBEM_E_NOT_FOUND exception", dwVip, dwReqStartPort);
  295. throw _com_error( WBEM_E_NOT_FOUND );
  296. }
  297. SpawnInstance( a_pParsedPath->m_pClass, &pWlbsInstance );
  298. FillWbemInstance(a_pParsedPath->m_pClass, pCluster, pWlbsInstance, &PortRule );
  299. //send the results back to WinMgMt
  300. m_pResponseHandler->Indicate( 1, &pWlbsInstance );
  301. if( pWlbsInstance )
  302. pWlbsInstance->Release();
  303. m_pResponseHandler->SetStatus( 0, WBEM_S_NO_ERROR, NULL, NULL );
  304. hRes = WBEM_S_NO_ERROR;
  305. }
  306. catch(CErrorWlbsControl Err) {
  307. IWbemClassObject* pWbemExtStat = NULL;
  308. TRACE_CRIT("%!FUNC! Caught a Wlbs exception : 0x%x", Err.Error());
  309. CreateExtendedStatus( m_pNameSpace,
  310. &pWbemExtStat,
  311. Err.Error(),
  312. (PWCHAR)(Err.Description()) );
  313. m_pResponseHandler->SetStatus(0, WBEM_E_FAILED, NULL, pWbemExtStat);
  314. if( pWbemExtStat )
  315. pWbemExtStat->Release();
  316. if( pWlbsInstance )
  317. pWlbsInstance->Release();
  318. //do not return WBEM_E_FAILED, this causes a race condition
  319. hRes = WBEM_S_NO_ERROR;
  320. }
  321. catch(_com_error HResErr ) {
  322. TRACE_CRIT("%!FUNC! Caught a com_error exception : 0x%x", HResErr.Error());
  323. m_pResponseHandler->SetStatus(0, HResErr.Error(), NULL, NULL);
  324. if( pWlbsInstance )
  325. pWlbsInstance->Release();
  326. hRes = HResErr.Error();
  327. }
  328. catch(...) {
  329. TRACE_CRIT("%!FUNC! Caught an exception");
  330. if( pWlbsInstance )
  331. pWlbsInstance->Release();
  332. TRACE_CRIT("%!FUNC! Rethrowing exception");
  333. TRACE_CRIT("<-%!FUNC!");
  334. throw;
  335. }
  336. TRACE_CRIT("<-%!FUNC! return 0x%x", hRes);
  337. return hRes;
  338. }
  339. ////////////////////////////////////////////////////////////////////////////////
  340. //
  341. // CWLBS_PortRule::EnumInstances
  342. //
  343. // Purpose: This function obtains the PortRule data for the current host.
  344. // The node does not have to be a member of a cluster for this
  345. // to succeed. However, NLB must be installed.
  346. //
  347. ////////////////////////////////////////////////////////////////////////////////
  348. HRESULT CWLBS_PortRule::EnumInstances
  349. (
  350. BSTR a_bstrClass,
  351. long /*a_lFlags*/,
  352. IWbemContext* /*a_pIContex*/
  353. )
  354. {
  355. IWbemClassObject** ppWlbsInstance = NULL;
  356. HRESULT hRes = 0;
  357. PWLBS_PORT_RULE pPortRules = NULL;
  358. DWORD dwNumRules = 0;
  359. CNodeConfiguration NodeConfig;
  360. TRACE_CRIT("->%!FUNC!");
  361. try {
  362. DWORD dwFilteringMode;
  363. if( _wcsicmp( a_bstrClass, MOF_PRFAIL::szName ) == 0 ) {
  364. dwFilteringMode = WLBS_SINGLE;
  365. } else if( _wcsicmp( a_bstrClass, MOF_PRLOADBAL::szName ) == 0 ) {
  366. dwFilteringMode = WLBS_MULTI;
  367. } else if( _wcsicmp( a_bstrClass, MOF_PRDIS::szName ) == 0 ) {
  368. dwFilteringMode = WLBS_NEVER;
  369. } else if( _wcsicmp( a_bstrClass, MOF_PORTRULE_EX::szName ) == 0 ) {
  370. dwFilteringMode = 0;
  371. } else {
  372. TRACE_CRIT("%!FUNC! Invalid Class name : %ls, Throwing WBEM_E_NOT_FOUND exception",a_bstrClass);
  373. throw _com_error( WBEM_E_NOT_FOUND );
  374. }
  375. DWORD dwNumClusters = 0;
  376. CWlbsClusterWrapper** ppCluster = NULL;
  377. g_pWlbsControl->EnumClusters(ppCluster, &dwNumClusters);
  378. if (dwNumClusters == 0)
  379. {
  380. TRACE_CRIT("%!FUNC! EnumClusters returned no clusters, Throwing WBEM_E_NOT_FOUND exception");
  381. throw _com_error( WBEM_E_NOT_FOUND );
  382. }
  383. //declare an IWbemClassObject smart pointer
  384. IWbemClassObjectPtr pWlbsClass;
  385. //get the MOF class object
  386. hRes = m_pNameSpace->GetObject(
  387. a_bstrClass,
  388. 0,
  389. NULL,
  390. &pWlbsClass,
  391. NULL );
  392. if( FAILED( hRes ) ) {
  393. TRACE_CRIT("%!FUNC! CWbemServices::GetObject failed with error : 0x%x, Throwing com_error exception", hRes);
  394. throw _com_error( hRes );
  395. }
  396. for (DWORD iCluster=0; iCluster<dwNumClusters; iCluster++)
  397. {
  398. // The filtering mode will NOT be zero only if the instances to be enumerated is
  399. // of type "PortRule(Disabled/Failover/Loadbalanced)"
  400. if (dwFilteringMode != 0)
  401. {
  402. // The "PortRule(Disabled/Failover/Loadbalanced)" classes do NOT contain the VIP property,
  403. // so, we do not want to return any port rule for a cluster that has a port rule
  404. // that is specific to a vip (other than the "all vip")
  405. // The "EffectiveVersion" registry value is checked for a value of CVY_VERSION_FULL to
  406. // see of there is any port rule that is specific to a vip
  407. ppCluster[iCluster]->GetNodeConfig(NodeConfig);
  408. if(NodeConfig.dwEffectiveVersion == CVY_VERSION_FULL)
  409. continue;
  410. }
  411. //call the API query function to find the port rules
  412. ppCluster[iCluster]->EnumPortRules( &pPortRules, &dwNumRules, dwFilteringMode );
  413. if( dwNumRules == 0 )
  414. continue; // Backporting fix for Winse bug
  415. // 24751 Querying for "Intrinsic events" on a class with zero instances causes error log entry in wbemcore.log
  416. //spawn an instance of the MOF class for each rule found
  417. ppWlbsInstance = new IWbemClassObject *[dwNumRules];
  418. if( !ppWlbsInstance )
  419. {
  420. TRACE_CRIT("%!FUNC! new failed, Throwing com_error WBEM_E_OUT_OF_MEMORY exception");
  421. throw _com_error( WBEM_E_OUT_OF_MEMORY );
  422. }
  423. //initialize array
  424. ZeroMemory( ppWlbsInstance, dwNumRules * sizeof(IWbemClassObject *) );
  425. for( DWORD i = 0; i < dwNumRules; i ++ ) {
  426. hRes = pWlbsClass->SpawnInstance( 0, &ppWlbsInstance[i] );
  427. if( FAILED( hRes ) )
  428. {
  429. TRACE_CRIT("%!FUNC! IWbemClassObjectPtr::SpawnInstance failed : 0x%x, Throwing com_error exception", hRes);
  430. throw _com_error( hRes );
  431. }
  432. FillWbemInstance(a_bstrClass, ppCluster[iCluster], *(ppWlbsInstance + i), pPortRules + i );
  433. }
  434. //send the results back to WinMgMt
  435. hRes = m_pResponseHandler->Indicate( dwNumRules, ppWlbsInstance );
  436. if( FAILED( hRes ) ) {
  437. TRACE_CRIT("%!FUNC! IWbemObjectSink::Indicate failed : 0x%x, Throwing com_error exception", hRes);
  438. throw _com_error( hRes );
  439. }
  440. if( ppWlbsInstance ) {
  441. for( i = 0; i < dwNumRules; i++ ) {
  442. if( ppWlbsInstance[i] ) {
  443. ppWlbsInstance[i]->Release();
  444. }
  445. }
  446. delete [] ppWlbsInstance;
  447. ppWlbsInstance = NULL;
  448. dwNumRules = NULL;
  449. }
  450. if( pPortRules )
  451. {
  452. delete [] pPortRules;
  453. pPortRules = NULL;
  454. }
  455. }
  456. m_pResponseHandler->SetStatus( 0, WBEM_S_NO_ERROR, NULL, NULL );
  457. hRes = WBEM_S_NO_ERROR;
  458. }
  459. catch(CErrorWlbsControl Err) {
  460. IWbemClassObject* pWbemExtStat = NULL;
  461. TRACE_CRIT("%!FUNC! Caught a Wlbs exception : 0x%x", Err.Error());
  462. CreateExtendedStatus( m_pNameSpace,
  463. &pWbemExtStat,
  464. Err.Error(),
  465. (PWCHAR)(Err.Description()) );
  466. m_pResponseHandler->SetStatus(0, WBEM_E_FAILED, NULL, pWbemExtStat);
  467. if( pWbemExtStat )
  468. pWbemExtStat->Release();
  469. if( ppWlbsInstance ) {
  470. for( DWORD i = 0; i < dwNumRules; i++ ) {
  471. if( ppWlbsInstance[i] ) {
  472. ppWlbsInstance[i]->Release();
  473. ppWlbsInstance[i] = NULL;
  474. }
  475. }
  476. delete [] ppWlbsInstance;
  477. }
  478. if( pPortRules )
  479. delete [] pPortRules;
  480. //do not return WBEM_E_FAILED, this causes a race condition
  481. hRes = WBEM_S_NO_ERROR;
  482. }
  483. catch(_com_error HResErr ) {
  484. TRACE_CRIT("%!FUNC! Caught a com_error exception : 0x%x", HResErr.Error());
  485. m_pResponseHandler->SetStatus(0, HResErr.Error(), NULL, NULL);
  486. if( ppWlbsInstance ) {
  487. for( DWORD i = 0; i < dwNumRules; i++ ) {
  488. if( ppWlbsInstance[i] ) {
  489. ppWlbsInstance[i]->Release();
  490. ppWlbsInstance[i] = NULL;
  491. }
  492. }
  493. delete [] ppWlbsInstance;
  494. }
  495. if( pPortRules )
  496. delete [] pPortRules;
  497. hRes = HResErr.Error();
  498. }
  499. catch(...) {
  500. TRACE_CRIT("%!FUNC! Caught an exception");
  501. if( ppWlbsInstance ) {
  502. for( DWORD i = 0; i < dwNumRules; i++ ) {
  503. if( ppWlbsInstance[i] ) {
  504. ppWlbsInstance[i]->Release();
  505. ppWlbsInstance[i] = NULL;
  506. }
  507. }
  508. delete [] ppWlbsInstance;
  509. }
  510. if( pPortRules )
  511. delete [] pPortRules;
  512. TRACE_CRIT("%!FUNC! Rethrowing exception");
  513. TRACE_CRIT("<-%!FUNC!");
  514. throw;
  515. }
  516. TRACE_CRIT("<-%!FUNC! return 0x%x", hRes);
  517. return hRes;
  518. }
  519. ////////////////////////////////////////////////////////////////////////////////
  520. //
  521. // CWLBS_PortRule::DeleteInstance
  522. //
  523. // Purpose: This function deletes an instance of a MOF PortRule
  524. // class. The node does not have to be a member of a cluster. However,
  525. // WLBS must be installed for this function to succeed.
  526. //
  527. ////////////////////////////////////////////////////////////////////////////////
  528. HRESULT CWLBS_PortRule::DeleteInstance
  529. (
  530. const ParsedObjectPath* a_pParsedPath,
  531. long /*a_lFlags*/,
  532. IWbemContext* /*a_pIContex*/
  533. )
  534. {
  535. HRESULT hRes = 0;
  536. TRACE_CRIT("->%!FUNC!");
  537. try {
  538. if( !a_pParsedPath )
  539. {
  540. TRACE_CRIT("%!FUNC! Did not pass class name & key of the instance to Delete");
  541. throw _com_error( WBEM_E_FAILED );
  542. }
  543. wstring wstrHostName;
  544. DWORD dwVip, dwReqStartPort;
  545. wstrHostName = (*a_pParsedPath->m_paKeys)->m_vValue.bstrVal;
  546. CWlbsClusterWrapper* pCluster = GetClusterFromHostName(g_pWlbsControl, wstrHostName);
  547. if (pCluster == NULL)
  548. {
  549. TRACE_CRIT("%!FUNC! GetClusterFromHostName failed for Host name = %ls, Throwing com_error WBEM_E_NOT_FOUND exception",wstrHostName.data());
  550. throw _com_error( WBEM_E_NOT_FOUND );
  551. }
  552. // If the instance to be deleted is of type "PortRuleEx", then, retreive the vip, otherwise
  553. // verify that we are operating in the "all vip" mode
  554. if (_wcsicmp(a_pParsedPath->m_pClass, MOF_CLASSES::g_szMOFClassList[MOF_CLASSES::PORTRULE_EX]) == 0)
  555. {
  556. WCHAR *szVip;
  557. // The Keys are ordered alphabetically, hence "Name", "StartPort", "VirtualIpAddress" is the order
  558. dwReqStartPort = static_cast<DWORD>( (*(a_pParsedPath->m_paKeys + 1))->m_vValue.lVal );
  559. szVip = (*(a_pParsedPath->m_paKeys + 2))->m_vValue.bstrVal;
  560. // If the VIP is "All Vip", then, fill in the numeric value
  561. // directly from the macro, else use the conversion function.
  562. // This is 'cos INADDR_NONE, the return value of inet_addr
  563. // function (called by IpAddressFromAbcdWsz) in the failure
  564. // case, is equivalent to the numeric value of CVY_DEF_ALL_VIP
  565. if (_wcsicmp(szVip, CVY_DEF_ALL_VIP) == 0) {
  566. dwVip = CVY_ALL_VIP_NUMERIC_VALUE;
  567. }
  568. else {
  569. dwVip = IpAddressFromAbcdWsz( szVip );
  570. if (dwVip == INADDR_NONE)
  571. {
  572. TRACE_CRIT("%!FUNC! Invalid value (%ls) passed for %ls for Class %ls. Throwing com_error WBEM_E_INVALID_PARAMETER exception", szVip, MOF_PARAM::VIP, a_pParsedPath->m_pClass);
  573. throw _com_error ( WBEM_E_INVALID_PARAMETER );
  574. }
  575. }
  576. }
  577. else
  578. {
  579. // The "PortRule(Disabled/Failover/Loadbalanced)" classes do NOT contain the VIP property,
  580. // so, we do not want to operate on any cluster that has a port rule
  581. // that is specific to a vip (other than the "all vip")
  582. // The "EffectiveVersion" registry value is checked for a value of CVY_VERSION_FULL to
  583. // see of there is any port rule that is specific to a vip
  584. CNodeConfiguration NodeConfig;
  585. pCluster->GetNodeConfig(NodeConfig);
  586. if(NodeConfig.dwEffectiveVersion == CVY_VERSION_FULL)
  587. {
  588. TRACE_CRIT("%!FUNC! called on Class : %ls on a cluster that has per-vip port rules (Must call the \"Ex\" equivalent instead). Throwing com_error WBEM_E_INVALID_OPERATION exception", a_pParsedPath->m_pClass);
  589. throw _com_error( WBEM_E_INVALID_OPERATION );
  590. }
  591. dwReqStartPort = static_cast<DWORD>( (*(a_pParsedPath->m_paKeys + 1))->m_vValue.lVal );
  592. dwVip = IpAddressFromAbcdWsz(CVY_DEF_ALL_VIP);
  593. }
  594. WLBS_PORT_RULE PortRule;
  595. // Get the port rule for this vip & port
  596. pCluster->GetPortRule(dwVip, dwReqStartPort, &PortRule );
  597. if( (dwVip != IpAddressFromAbcdWsz(PortRule.virtual_ip_addr)) || (dwReqStartPort != PortRule.start_port) )
  598. {
  599. TRACE_CRIT("%!FUNC! could not retreive port rule for vip : 0x%x & port : 0x%x, Throwing com_error WBEM_E_NOT_FOUND exception", dwVip, dwReqStartPort);
  600. throw _com_error( WBEM_E_NOT_FOUND );
  601. }
  602. // Delete the port rule for this vip & port
  603. pCluster->DeletePortRule(dwVip, dwReqStartPort );
  604. m_pResponseHandler->SetStatus( 0, WBEM_S_NO_ERROR, NULL, NULL );
  605. hRes = WBEM_S_NO_ERROR;
  606. }
  607. catch(CErrorWlbsControl Err) {
  608. IWbemClassObject* pWbemExtStat = NULL;
  609. TRACE_CRIT("%!FUNC! Caught a Wlbs exception : 0x%x", Err.Error());
  610. CreateExtendedStatus( m_pNameSpace,
  611. &pWbemExtStat,
  612. Err.Error(),
  613. (PWCHAR)(Err.Description()) );
  614. m_pResponseHandler->SetStatus(0, WBEM_E_FAILED, NULL, pWbemExtStat);
  615. if( pWbemExtStat )
  616. pWbemExtStat->Release();
  617. //do not return WBEM_E_FAILED, this causes a race condition
  618. hRes = WBEM_S_NO_ERROR;
  619. }
  620. catch(_com_error HResErr ) {
  621. TRACE_CRIT("%!FUNC! Caught a com_error exception : 0x%x", HResErr.Error());
  622. m_pResponseHandler->SetStatus(0, HResErr.Error(), NULL, NULL);
  623. hRes = HResErr.Error();
  624. }
  625. TRACE_CRIT("<-%!FUNC! return 0x%x", hRes);
  626. return hRes;
  627. }
  628. ////////////////////////////////////////////////////////////////////////////////
  629. //
  630. // CWLBS_PortRule::PutInstance
  631. //
  632. // Purpose: This function updates an instance of a PortRule
  633. // class. The host does not have to be a member of a cluster.
  634. //
  635. ////////////////////////////////////////////////////////////////////////////////
  636. HRESULT CWLBS_PortRule::PutInstance
  637. (
  638. IWbemClassObject* a_pInstance,
  639. long /*a_lFlags*/,
  640. IWbemContext* /*a_pIContex*/
  641. )
  642. {
  643. VARIANT vValue;
  644. HRESULT hRes = 0;
  645. namespace PR = MOF_PORTRULE_EX;
  646. WLBS_PORT_RULE NewRule; //the instance to put
  647. bool bPortRule_Ex;
  648. DWORD dwFilteringMode = 0; // Filtering Mode initialized to 0
  649. DWORD dwVip;
  650. WCHAR szClassName[256];
  651. TRACE_CRIT("->%!FUNC!");
  652. try {
  653. VariantInit( &vValue );
  654. //get the class name to determine port rule mode
  655. hRes = a_pInstance->Get( _bstr_t( L"__Class" ),
  656. 0,
  657. &vValue,
  658. NULL,
  659. NULL );
  660. if( FAILED( hRes ) )
  661. {
  662. TRACE_CRIT("%!FUNC! Error trying to retreive \"__Class\" property,IWbemClassObject::Get failed with error : 0x%x, Throwing com_error exception", hRes);
  663. throw _com_error( hRes );
  664. }
  665. StringCbCopy(szClassName, sizeof(szClassName), vValue.bstrVal);
  666. // If it is the extended port rule class, then, the namespaces are different
  667. if (_wcsicmp(szClassName, MOF_CLASSES::g_szMOFClassList[MOF_CLASSES::PORTRULE_EX]) == 0)
  668. {
  669. bPortRule_Ex = true;
  670. }
  671. else
  672. {
  673. bPortRule_Ex = false;
  674. }
  675. // Need to check return code for error
  676. if (S_OK != VariantClear( &vValue ))
  677. {
  678. TRACE_CRIT("%!FUNC! VariantClear() failed, Throwing WBEM_E_FAILED exception");
  679. throw _com_error( WBEM_E_FAILED );
  680. }
  681. //get the host name value
  682. hRes = a_pInstance->Get( _bstr_t( PR::pProperties[PR::NAME] ),
  683. 0,
  684. &vValue,
  685. NULL,
  686. NULL );
  687. if( FAILED( hRes ) )
  688. {
  689. TRACE_CRIT("%!FUNC! Error trying to retreive %ls property of Class : %ls,IWbemClassObject::Get failed with error : 0x%x, Throwing com_error exception",PR::pProperties[PR::NAME],szClassName, hRes);
  690. throw _com_error( hRes );
  691. }
  692. wstring wstrHostName( vValue.bstrVal );
  693. CWlbsClusterWrapper* pCluster = GetClusterFromHostName(g_pWlbsControl, wstrHostName);
  694. if (pCluster == NULL)
  695. {
  696. TRACE_CRIT("%!FUNC! GetClusterFromHostName failed for Host name = %ls, Throwing com_error WBEM_E_NOT_FOUND exception",wstrHostName.data());
  697. throw _com_error( WBEM_E_NOT_FOUND );
  698. }
  699. // CLD: Need to check return code for error
  700. if (S_OK != VariantClear( &vValue ))
  701. {
  702. TRACE_CRIT("%!FUNC! VariantClear() failed, Throwing WBEM_E_FAILED exception");
  703. throw _com_error( WBEM_E_FAILED );
  704. }
  705. // If the instance to be put is of type "PortRuleEx", then, retreive the vip, otherwise
  706. // verify that we are operating in the "all vip" mode
  707. if (bPortRule_Ex)
  708. {
  709. //get the vip
  710. hRes = a_pInstance->Get( _bstr_t( PR::pProperties[PR::VIP] ),
  711. 0,
  712. &vValue,
  713. NULL,
  714. NULL );
  715. if( FAILED( hRes ) )
  716. {
  717. TRACE_CRIT("%!FUNC! Error trying to retreive %ls property of Class : %ls,IWbemClassObject::Get failed with error : 0x%x, Throwing com_error exception",PR::pProperties[PR::VIP],szClassName, hRes);
  718. throw _com_error( hRes );
  719. }
  720. // If the VIP is "All Vip", then, fill in the numeric value
  721. // directly from the macro, else use the conversion function.
  722. // This is 'cos INADDR_NONE, the return value of inet_addr
  723. // function (called by IpAddressFromAbcdWsz) in the failure
  724. // case, is equivalent to the numeric value of CVY_DEF_ALL_VIP
  725. if (_wcsicmp(vValue.bstrVal, CVY_DEF_ALL_VIP) == 0) {
  726. dwVip = CVY_ALL_VIP_NUMERIC_VALUE;
  727. }
  728. else {
  729. dwVip = IpAddressFromAbcdWsz( vValue.bstrVal );
  730. if (dwVip == INADDR_NONE)
  731. {
  732. TRACE_CRIT("%!FUNC! Invalid value (%ls) passed for %ls for Class %ls. Throwing com_error WBEM_E_INVALID_PARAMETER exception", vValue.bstrVal, MOF_PARAM::VIP, szClassName);
  733. throw _com_error ( WBEM_E_INVALID_PARAMETER );
  734. }
  735. }
  736. StringCbCopy(NewRule.virtual_ip_addr, sizeof(NewRule.virtual_ip_addr), vValue.bstrVal);
  737. if (S_OK != VariantClear( &vValue ))
  738. {
  739. TRACE_CRIT("%!FUNC! VariantClear() failed, Throwing WBEM_E_FAILED exception");
  740. throw _com_error( WBEM_E_FAILED );
  741. }
  742. //get the filtering mode
  743. hRes = a_pInstance->Get( _bstr_t( PR::pProperties[PR::FILTERINGMODE] ),
  744. 0,
  745. &vValue,
  746. NULL,
  747. NULL );
  748. if( FAILED( hRes ) )
  749. {
  750. TRACE_CRIT("%!FUNC! Error trying to retreive %ls property of Class : %ls,IWbemClassObject::Get failed with error : 0x%x, Throwing com_error exception",PR::pProperties[PR::FILTERINGMODE],szClassName, hRes);
  751. throw _com_error( hRes );
  752. }
  753. dwFilteringMode = static_cast<DWORD>( vValue.lVal );
  754. }
  755. else
  756. {
  757. // The "PortRule(Disabled/Failover/Loadbalanced)" classes do NOT contain the VIP property,
  758. // so, we do not want to operate on any cluster that has a port rule
  759. // that is specific to a vip (other than the "all vip")
  760. // The "EffectiveVersion" registry value is checked for a value of CVY_VERSION_FULL to
  761. // see of there is any port rule that is specific to a vip
  762. CNodeConfiguration NodeConfig;
  763. pCluster->GetNodeConfig(NodeConfig);
  764. if(NodeConfig.dwEffectiveVersion == CVY_VERSION_FULL)
  765. {
  766. TRACE_CRIT("%!FUNC! Attempt to put an instance of %ls class on a cluster that has per-vip port rules (Must use %ls class instead). Throwing com_error WBEM_E_INVALID_OPERATION exception", szClassName,MOF_CLASSES::g_szMOFClassList[MOF_CLASSES::PORTRULE_EX]);
  767. throw _com_error( WBEM_E_INVALID_OPERATION );
  768. }
  769. StringCbCopy(NewRule.virtual_ip_addr, sizeof(NewRule.virtual_ip_addr), CVY_DEF_ALL_VIP);
  770. dwVip = CVY_ALL_VIP_NUMERIC_VALUE;
  771. }
  772. //retrieve start and end ports
  773. hRes = a_pInstance->Get( _bstr_t( PR::pProperties[PR::STPORT] ),
  774. 0,
  775. &vValue,
  776. NULL,
  777. NULL );
  778. if( FAILED( hRes ) )
  779. {
  780. TRACE_CRIT("%!FUNC! Error trying to retreive %ls property of Class : %ls,IWbemClassObject::Get failed with error : 0x%x, Throwing com_error exception",PR::pProperties[PR::STPORT], szClassName, hRes);
  781. throw _com_error( hRes );
  782. }
  783. NewRule.start_port = static_cast<DWORD>( vValue.lVal );
  784. hRes = a_pInstance->Get( _bstr_t( PR::pProperties[PR::EDPORT] ),
  785. 0,
  786. &vValue,
  787. NULL,
  788. NULL );
  789. if( FAILED( hRes ) )
  790. {
  791. TRACE_CRIT("%!FUNC! Error trying to retreive %ls property of Class : %ls,IWbemClassObject::Get failed with error : 0x%x, Throwing com_error exception",PR::pProperties[PR::EDPORT], szClassName, hRes);
  792. throw _com_error( hRes );
  793. }
  794. NewRule.end_port = static_cast<DWORD>( vValue.lVal );
  795. //get the protocol
  796. hRes = a_pInstance->Get( _bstr_t( PR::pProperties[PR::PROT] ),
  797. 0,
  798. &vValue,
  799. NULL,
  800. NULL );
  801. if( FAILED( hRes ) )
  802. {
  803. TRACE_CRIT("%!FUNC! Error trying to retreive %ls property of Class : %ls,IWbemClassObject::Get failed with error : 0x%x, Throwing com_error exception",PR::pProperties[PR::PROT], szClassName, hRes);
  804. throw _com_error( hRes );
  805. }
  806. NewRule.protocol = static_cast<DWORD>( vValue.lVal );
  807. if( (dwFilteringMode == WLBS_NEVER) || (_wcsicmp( szClassName, MOF_PRDIS::szName ) == 0)) {
  808. NewRule.mode = WLBS_NEVER;
  809. } else if( (dwFilteringMode == WLBS_SINGLE) || (_wcsicmp( szClassName, MOF_PRFAIL::szName ) == 0)) {
  810. NewRule.mode = WLBS_SINGLE;
  811. VARIANT vRulePriority;
  812. VariantInit( &vRulePriority );
  813. try {
  814. //get the rule priority
  815. hRes = a_pInstance->Get( _bstr_t( PR::pProperties[PR::PRIO] ),
  816. 0,
  817. &vRulePriority,
  818. NULL,
  819. NULL );
  820. if( FAILED( hRes ) )
  821. {
  822. TRACE_CRIT("%!FUNC! Error trying to retreive %ls property of Class : %ls,IWbemClassObject::Get failed with error : 0x%x, Throwing com_error exception",PR::pProperties[PR::PRIO], szClassName, hRes);
  823. throw _com_error( hRes );
  824. }
  825. }
  826. catch( ... ) {
  827. TRACE_CRIT("%!FUNC! Caught an exception");
  828. // CLD: Need to check return code for error
  829. // No throw here since we are already throwing an exception.
  830. VariantClear( &vRulePriority );
  831. TRACE_CRIT("%!FUNC! Rethrowing exception");
  832. throw;
  833. }
  834. NewRule.mode_data.single.priority = static_cast<DWORD>( vRulePriority.lVal );
  835. // CLD: Need to check return code for error
  836. if (S_OK != VariantClear( &vRulePriority ))
  837. {
  838. TRACE_CRIT("%!FUNC! VariantClear() failed, Throwing WBEM_E_FAILED exception");
  839. throw _com_error( WBEM_E_FAILED );
  840. }
  841. } else if( (dwFilteringMode == WLBS_MULTI) || (_wcsicmp( szClassName, MOF_PRLOADBAL::szName ) == 0)) {
  842. NewRule.mode = WLBS_MULTI;
  843. VARIANT v;
  844. VariantInit( &v );
  845. try {
  846. //get the affinity
  847. hRes = a_pInstance->Get( _bstr_t( PR::pProperties[PR::AFFIN] ),
  848. 0,
  849. &v,
  850. NULL,
  851. NULL );
  852. if( FAILED( hRes ) )
  853. {
  854. TRACE_CRIT("%!FUNC! Error trying to retreive %ls property of Class : %ls,IWbemClassObject::Get failed with error : 0x%x, Throwing com_error exception",PR::pProperties[PR::AFFIN], szClassName, hRes);
  855. throw _com_error( hRes );
  856. }
  857. NewRule.mode_data.multi.affinity = static_cast<WORD>( v.lVal );
  858. //get the equal load boolean
  859. hRes = a_pInstance->Get( _bstr_t( PR::pProperties[PR::EQLD] ),
  860. 0,
  861. &v,
  862. NULL,
  863. NULL );
  864. if( FAILED( hRes ) )
  865. {
  866. TRACE_CRIT("%!FUNC! Error trying to retreive %ls property of Class : %ls,IWbemClassObject::Get failed with error : 0x%x, Throwing com_error exception",PR::pProperties[PR::EQLD], szClassName, hRes);
  867. throw _com_error( hRes );
  868. }
  869. if( v.boolVal == -1 ) {
  870. NewRule.mode_data.multi.equal_load = 1;
  871. } else {
  872. NewRule.mode_data.multi.equal_load = 0;
  873. }
  874. //get the load
  875. hRes = a_pInstance->Get( _bstr_t( PR::pProperties[PR::LDWT] ),
  876. 0,
  877. &v,
  878. NULL,
  879. NULL );
  880. if( FAILED( hRes ) )
  881. {
  882. TRACE_CRIT("%!FUNC! Error trying to retreive %ls property of Class : %ls,IWbemClassObject::Get failed with error : 0x%x, Throwing com_error exception",PR::pProperties[PR::LDWT], szClassName, hRes);
  883. throw _com_error( hRes );
  884. }
  885. if( v.vt != VT_NULL )
  886. NewRule.mode_data.multi.load = static_cast<DWORD>( v.lVal );
  887. else
  888. NewRule.mode_data.multi.load = 0;
  889. } catch( ... ) {
  890. TRACE_CRIT("%!FUNC! Caught an exception");
  891. // CLD: Need to check return code for error
  892. // No throw here since we are already throwing an exception.
  893. VariantClear( &v );
  894. TRACE_CRIT("%!FUNC! Rethrowing exception");
  895. throw;
  896. }
  897. // CLD: Need to check return code for error
  898. if (S_OK != VariantClear( &v ))
  899. {
  900. TRACE_CRIT("%!FUNC! VariantClear() failed, Throwing WBEM_E_FAILED exception");
  901. throw _com_error( WBEM_E_FAILED );
  902. }
  903. }
  904. //delete the port rule but cache in case of failure
  905. WLBS_PORT_RULE OldRule;
  906. bool bOldRuleSaved = false;
  907. if( pCluster->RuleExists(dwVip, NewRule.start_port ) ) {
  908. pCluster->GetPortRule(dwVip, NewRule.start_port, &OldRule );
  909. bOldRuleSaved = true;
  910. pCluster->DeletePortRule(dwVip, NewRule.start_port );
  911. }
  912. //add the port rule, roll back if failed
  913. try {
  914. pCluster->PutPortRule( &NewRule );
  915. } catch(...) {
  916. TRACE_CRIT("%!FUNC! Caught an exception");
  917. if( bOldRuleSaved )
  918. pCluster->PutPortRule( &OldRule );
  919. TRACE_CRIT("%!FUNC! Rethrowing exception");
  920. throw;
  921. }
  922. //release resources
  923. // CLD: Need to check return code for error
  924. if (S_OK != VariantClear( &vValue ))
  925. {
  926. TRACE_CRIT("%!FUNC! VariantClear() failed, Throwing WBEM_E_FAILED exception");
  927. throw _com_error( WBEM_E_FAILED );
  928. }
  929. m_pResponseHandler->SetStatus( 0, WBEM_S_NO_ERROR, NULL, NULL );
  930. hRes = WBEM_S_NO_ERROR;
  931. }
  932. catch(CErrorWlbsControl Err) {
  933. IWbemClassObject* pWbemExtStat = NULL;
  934. TRACE_CRIT("%!FUNC! Caught a Wlbs exception : 0x%x", Err.Error());
  935. CreateExtendedStatus( m_pNameSpace,
  936. &pWbemExtStat,
  937. Err.Error(),
  938. (PWCHAR)(Err.Description()) );
  939. m_pResponseHandler->SetStatus(0, WBEM_E_FAILED, NULL, pWbemExtStat);
  940. if( pWbemExtStat )
  941. pWbemExtStat->Release();
  942. // CLD: Need to check return code for error
  943. // No throw here since we are already throwing an exception.
  944. VariantClear( &vValue );
  945. //do not return WBEM_E_FAILED, this causes a race condition
  946. hRes = WBEM_S_NO_ERROR;
  947. }
  948. catch(_com_error HResErr ) {
  949. TRACE_CRIT("%!FUNC! Caught a com_error exception : 0x%x", HResErr.Error());
  950. m_pResponseHandler->SetStatus(0, HResErr.Error(), NULL, NULL);
  951. // CLD: Need to check return code for error
  952. // No throw here since we are already throwing an exception.
  953. VariantClear( &vValue );
  954. hRes = HResErr.Error();
  955. }
  956. catch (...) {
  957. TRACE_CRIT("%!FUNC! Caught an exception");
  958. // CLD: Need to check return code for error
  959. // No throw here since we are already throwing an exception.
  960. VariantClear( &vValue );
  961. TRACE_CRIT("%!FUNC! Rethrowing exception");
  962. TRACE_CRIT("<-%!FUNC!");
  963. throw;
  964. }
  965. TRACE_CRIT("<-%!FUNC! return 0x%x", hRes);
  966. return hRes;
  967. }
  968. ////////////////////////////////////////////////////////////////////////////////
  969. //
  970. // CWLBS_PortRule::FillWbemInstance
  971. //
  972. // Purpose: This function copies all of the data from a node configuration
  973. // structure to a WBEM instance.
  974. //
  975. ////////////////////////////////////////////////////////////////////////////////
  976. void CWLBS_PortRule::FillWbemInstance
  977. (
  978. LPCWSTR a_szClassName,
  979. CWlbsClusterWrapper* pCluster,
  980. IWbemClassObject* a_pWbemInstance,
  981. const PWLBS_PORT_RULE& a_pPortRule
  982. )
  983. {
  984. namespace PR = MOF_PORTRULE_EX;
  985. bool bPortRule_Ex;
  986. TRACE_VERB("->%!FUNC!, ClassName : %ls", a_szClassName);
  987. ASSERT( a_pWbemInstance );
  988. // If it is the extended port rule class, then, the namespaces are different
  989. if (_wcsicmp(a_szClassName, MOF_CLASSES::g_szMOFClassList[MOF_CLASSES::PORTRULE_EX]) == 0)
  990. {
  991. bPortRule_Ex = true;
  992. }
  993. else
  994. {
  995. bPortRule_Ex = false;
  996. }
  997. wstring wstrHostName;
  998. ConstructHostName( wstrHostName, pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  999. pCluster->GetHostID());
  1000. //NAME
  1001. HRESULT hRes = a_pWbemInstance->Put
  1002. (
  1003. _bstr_t( PR::pProperties[PR::NAME] ) ,
  1004. 0 ,
  1005. &_variant_t(wstrHostName.c_str()),
  1006. NULL
  1007. );
  1008. if( FAILED( hRes ) )
  1009. throw _com_error( hRes );
  1010. // Fill in VIP if it is the extended port rule class
  1011. if (bPortRule_Ex) {
  1012. hRes = a_pWbemInstance->Put
  1013. (
  1014. _bstr_t( PR::pProperties[PR::VIP] ) ,
  1015. 0 ,
  1016. &_variant_t(a_pPortRule->virtual_ip_addr),
  1017. NULL
  1018. );
  1019. if( FAILED( hRes ) )
  1020. throw _com_error( hRes );
  1021. }
  1022. //STPORT
  1023. hRes = a_pWbemInstance->Put
  1024. (
  1025. _bstr_t( PR::pProperties[PR::STPORT] ),
  1026. 0 ,
  1027. &_variant_t(static_cast<long>(a_pPortRule->start_port)),
  1028. NULL
  1029. );
  1030. if( FAILED( hRes ) )
  1031. throw _com_error( hRes );
  1032. //EDPORT
  1033. hRes = a_pWbemInstance->Put
  1034. (
  1035. _bstr_t( PR::pProperties[PR::EDPORT] ),
  1036. 0 ,
  1037. &_variant_t(static_cast<long>(a_pPortRule->end_port)),
  1038. NULL
  1039. );
  1040. if( FAILED( hRes ) )
  1041. throw _com_error( hRes );
  1042. //ADAPTERGUID
  1043. GUID AdapterGuid = pCluster->GetAdapterGuid();
  1044. WCHAR szAdapterGuid[128];
  1045. StringFromGUID2(AdapterGuid, szAdapterGuid,
  1046. sizeof(szAdapterGuid)/sizeof(szAdapterGuid[0]) );
  1047. hRes = a_pWbemInstance->Put
  1048. (
  1049. _bstr_t( PR::pProperties[PR::ADAPTERGUID] ),
  1050. 0 ,
  1051. &_variant_t(szAdapterGuid),
  1052. NULL
  1053. );
  1054. if( FAILED( hRes ) )
  1055. throw _com_error( hRes );
  1056. //PROT
  1057. hRes = a_pWbemInstance->Put
  1058. (
  1059. _bstr_t( PR::pProperties[PR::PROT] ),
  1060. 0,
  1061. &_variant_t(static_cast<long>(a_pPortRule->protocol)),
  1062. NULL
  1063. );
  1064. if( FAILED( hRes ) )
  1065. throw _com_error( hRes );
  1066. // If it is the extended port rule class (containing all parameters of all filtering modes),
  1067. // initialize them with a "don't care" value (zero). The appropriate fields (depending on filtering mode)
  1068. // are filled in later.
  1069. if (bPortRule_Ex) {
  1070. hRes = a_pWbemInstance->Put ( _bstr_t( PR::pProperties[PR::EQLD] ), 0, &_variant_t(static_cast<long>(0)), NULL);
  1071. if( FAILED( hRes ) )
  1072. throw _com_error( hRes );
  1073. hRes = a_pWbemInstance->Put ( _bstr_t( PR::pProperties[PR::LDWT] ), 0, &_variant_t(static_cast<long>(0)), NULL);
  1074. if( FAILED( hRes ) )
  1075. throw _com_error( hRes );
  1076. hRes = a_pWbemInstance->Put ( _bstr_t( PR::pProperties[PR::AFFIN] ), 0, &_variant_t(static_cast<long>(0)), NULL);
  1077. if( FAILED( hRes ) )
  1078. throw _com_error( hRes );
  1079. hRes = a_pWbemInstance->Put (_bstr_t( PR::pProperties[PR::PRIO] ), 0, &_variant_t(static_cast<long>(0)), NULL);
  1080. if( FAILED( hRes ) )
  1081. throw _com_error( hRes );
  1082. }
  1083. // Fill in "Filtering Mode" if it is the Extended Port rule class
  1084. if (bPortRule_Ex) {
  1085. hRes = a_pWbemInstance->Put
  1086. (
  1087. _bstr_t( PR::pProperties[PR::FILTERINGMODE] ) ,
  1088. 0 ,
  1089. &_variant_t(static_cast<long>(a_pPortRule->mode)),
  1090. NULL
  1091. );
  1092. if( FAILED( hRes ) )
  1093. throw _com_error( hRes );
  1094. }
  1095. switch( a_pPortRule->mode ) {
  1096. case WLBS_SINGLE:
  1097. //PRIO
  1098. hRes = a_pWbemInstance->Put
  1099. (
  1100. _bstr_t( PR::pProperties[PR::PRIO] ),
  1101. 0 ,
  1102. &_variant_t(static_cast<long>(a_pPortRule->mode_data.single.priority)),
  1103. NULL
  1104. );
  1105. if( FAILED( hRes ) )
  1106. throw _com_error( hRes );
  1107. break;
  1108. case WLBS_MULTI:
  1109. //EQLD
  1110. hRes = a_pWbemInstance->Put
  1111. (
  1112. _bstr_t( PR::pProperties[PR::EQLD] ),
  1113. 0 ,
  1114. &_variant_t((a_pPortRule->mode_data.multi.equal_load != 0)),
  1115. NULL
  1116. );
  1117. if( FAILED( hRes ) )
  1118. throw _com_error( hRes );
  1119. //LDWT
  1120. hRes = a_pWbemInstance->Put
  1121. (
  1122. _bstr_t( PR::pProperties[PR::LDWT] ),
  1123. 0 ,
  1124. &_variant_t(static_cast<long>(a_pPortRule->mode_data.multi.load)),
  1125. NULL
  1126. );
  1127. if( FAILED( hRes ) )
  1128. throw _com_error( hRes );
  1129. //AFFIN
  1130. hRes = a_pWbemInstance->Put
  1131. (
  1132. _bstr_t( PR::pProperties[PR::AFFIN] ),
  1133. 0 ,
  1134. &_variant_t(static_cast<long>(a_pPortRule->mode_data.multi.affinity)),
  1135. NULL
  1136. );
  1137. if( FAILED( hRes ) )
  1138. throw _com_error( hRes );
  1139. break;
  1140. case WLBS_NEVER:
  1141. //there are no properties
  1142. break;
  1143. default:
  1144. throw _com_error( WBEM_E_FAILED );
  1145. }
  1146. // Fill in "PortState" if it is the Extended Port rule class
  1147. if (bPortRule_Ex) {
  1148. NLB_OPTIONS options;
  1149. WLBS_RESPONSE response;
  1150. DWORD num_responses = 1;
  1151. DWORD status, port_state;
  1152. options.state.port.VirtualIPAddress = WlbsResolve(a_pPortRule->virtual_ip_addr);
  1153. options.state.port.Num = a_pPortRule->start_port;
  1154. status = g_pWlbsControl->WlbsQueryState(pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  1155. WLBS_LOCAL_HOST,
  1156. IOCTL_CVY_QUERY_PORT_STATE,
  1157. &options,
  1158. &response,
  1159. &num_responses);
  1160. if (status != WLBS_OK)
  1161. {
  1162. TRACE_CRIT("%!FUNC! WlbsQueryState returned error : 0x%x, Throwing Wlbs error exception", status);
  1163. throw CErrorWlbsControl( status, CmdWlbsQueryPortState );
  1164. }
  1165. port_state = response.options.state.port.Status;
  1166. hRes = a_pWbemInstance->Put
  1167. (
  1168. _bstr_t( PR::pProperties[PR::PORTSTATE] ) ,
  1169. 0 ,
  1170. &_variant_t(static_cast<long>(port_state)),
  1171. NULL
  1172. );
  1173. if( FAILED( hRes ) )
  1174. throw _com_error( hRes );
  1175. }
  1176. TRACE_VERB("<-%!FUNC!");
  1177. }