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.

1333 lines
42 KiB

  1. #include "WLBS_Provider.h"
  2. #include "WLBS_Node.h"
  3. #include "ClusterWrapper.h"
  4. #include "ControlWrapper.h"
  5. #include "utils.h"
  6. #include "wlbsutil.h"
  7. #include <winsock.h>
  8. #include "wlbs_node.tmh" // for event tracing
  9. ////////////////////////////////////////////////////////////////////////////////
  10. //
  11. // CWLBS_Node::CWLBS_Node
  12. //
  13. // Purpose: Constructor
  14. //
  15. ////////////////////////////////////////////////////////////////////////////////
  16. CWLBS_Node::CWLBS_Node(CWbemServices* a_pNameSpace,
  17. IWbemObjectSink* a_pResponseHandler)
  18. : CWlbs_Root( a_pNameSpace, a_pResponseHandler )
  19. {
  20. }
  21. ////////////////////////////////////////////////////////////////////////////////
  22. //
  23. // CWLBS_Node::Create
  24. //
  25. // Purpose: This instantiates this class and is invoked from an array of
  26. // function pointers.
  27. //
  28. ////////////////////////////////////////////////////////////////////////////////
  29. CWlbs_Root* CWLBS_Node::Create
  30. (
  31. CWbemServices* a_pNameSpace,
  32. IWbemObjectSink* a_pResponseHandler
  33. )
  34. {
  35. g_pWlbsControl->CheckMembership();
  36. CWlbs_Root* pRoot = new CWLBS_Node( a_pNameSpace, a_pResponseHandler );
  37. if( !pRoot )
  38. throw _com_error( WBEM_E_OUT_OF_MEMORY );
  39. return pRoot;
  40. }
  41. ////////////////////////////////////////////////////////////////////////////////
  42. //
  43. // CWLBS_Node::GetInstance
  44. //
  45. // Purpose: Queries WLBS for desired node instance and sends results back
  46. // to WinMgMt.
  47. //
  48. ////////////////////////////////////////////////////////////////////////////////
  49. HRESULT CWLBS_Node::GetInstance
  50. (
  51. const ParsedObjectPath* a_pParsedPath,
  52. long /* a_lFlags */,
  53. IWbemContext* /* a_pIContex */
  54. )
  55. {
  56. IWbemClassObject* pWlbsInstance = NULL;
  57. HRESULT hRes = 0;
  58. TRACE_CRIT("->%!FUNC!");
  59. try {
  60. //g_pWlbsControl->CheckConfiguration();
  61. //get the node
  62. FindInstance( &pWlbsInstance, a_pParsedPath );
  63. //send the results back to WinMgMt
  64. m_pResponseHandler->Indicate( 1, &pWlbsInstance );
  65. if( pWlbsInstance ) {
  66. pWlbsInstance->Release();
  67. pWlbsInstance = NULL;
  68. }
  69. m_pResponseHandler->SetStatus( 0, WBEM_S_NO_ERROR, NULL, NULL );
  70. hRes = WBEM_S_NO_ERROR;
  71. }
  72. catch(CErrorWlbsControl Err) {
  73. IWbemClassObject* pWbemExtStat = NULL;
  74. TRACE_CRIT("%!FUNC! Caught a Wlbs exception : 0x%x", Err.Error());
  75. CreateExtendedStatus( m_pNameSpace,
  76. &pWbemExtStat,
  77. Err.Error(),
  78. (PWCHAR)(Err.Description()) );
  79. m_pResponseHandler->SetStatus(0, WBEM_E_FAILED, NULL, pWbemExtStat);
  80. if( pWbemExtStat )
  81. pWbemExtStat->Release();
  82. if( pWlbsInstance )
  83. pWlbsInstance->Release();
  84. //do not return WBEM_E_FAILED, this causes a race condition
  85. hRes = WBEM_S_NO_ERROR;
  86. }
  87. catch(_com_error HResErr ) {
  88. TRACE_CRIT("%!FUNC! Caught a com_error exception : 0x%x", HResErr.Error());
  89. m_pResponseHandler->SetStatus(0, HResErr.Error(), NULL, NULL);
  90. if( pWlbsInstance )
  91. pWlbsInstance->Release();
  92. hRes = HResErr.Error();
  93. }
  94. catch(...) {
  95. TRACE_CRIT("%!FUNC! Caught an exception");
  96. if( pWlbsInstance ) {
  97. pWlbsInstance->Release();
  98. pWlbsInstance = NULL;
  99. }
  100. TRACE_CRIT("%!FUNC! Rethrowing exception");
  101. TRACE_CRIT("<-%!FUNC!");
  102. throw;
  103. }
  104. TRACE_CRIT("<-%!FUNC! return 0x%x", hRes);
  105. return hRes;
  106. }
  107. ////////////////////////////////////////////////////////////////////////////////
  108. //
  109. // CWLBS_Node::EnumInstances
  110. //
  111. // Purpose: Executes a WlbsQuery and sends data back to WinMgMt.
  112. //
  113. ////////////////////////////////////////////////////////////////////////////////
  114. HRESULT CWLBS_Node::EnumInstances
  115. (
  116. BSTR /* a_bstrClass */,
  117. long /* a_lFlags */,
  118. IWbemContext* /* a_pIContex */
  119. )
  120. {
  121. IWbemClassObject** ppWlbsInstance = NULL;
  122. WLBS_RESPONSE* pResponse = NULL;
  123. HRESULT hRes = 0;
  124. BSTR strClassName = NULL;
  125. long nNumNodes = 0;
  126. //g_pWlbsControl->CheckConfiguration();
  127. TRACE_CRIT("->%!FUNC!");
  128. try {
  129. strClassName = SysAllocString( MOF_NODE::szName );
  130. if( !strClassName )
  131. {
  132. TRACE_CRIT("%!FUNC! SysAllocString failed, Throwing com_error WBEM_E_OUT_OF_MEMORY exception");
  133. throw _com_error( WBEM_E_OUT_OF_MEMORY );
  134. }
  135. //declare an IWbemClassObject smart pointer
  136. IWbemClassObjectPtr pWlbsNodeClass;
  137. //get the MOF class object
  138. hRes = m_pNameSpace->GetObject(
  139. strClassName,
  140. 0,
  141. NULL,
  142. &pWlbsNodeClass,
  143. NULL );
  144. if( FAILED( hRes ) ) {
  145. TRACE_CRIT("%!FUNC! CWbemServices::GetObject failed with error : 0x%x, Throwing com_error exception", hRes);
  146. throw _com_error( hRes );
  147. }
  148. DWORD dwNumClusters = 0;
  149. CWlbsClusterWrapper** ppCluster = NULL;
  150. g_pWlbsControl->EnumClusters(ppCluster, &dwNumClusters);
  151. if (dwNumClusters == 0)
  152. {
  153. TRACE_INFO("%!FUNC! CWlbsControlWrapper::EnumClusters() returned no clusters, Throwing com_error WBEM_E_NOT_FOUND exception" );
  154. throw _com_error( WBEM_E_NOT_FOUND );
  155. }
  156. for (DWORD iCluster=0; iCluster<dwNumClusters; iCluster++)
  157. {
  158. WLBS_RESPONSE ResponseLocalComputerName;
  159. ResponseLocalComputerName.options.identity.fqdn[0] = UNICODE_NULL;
  160. //call the API query function to find the nodes
  161. try {
  162. FindAllInstances(ppCluster[iCluster], &pResponse, nNumNodes, &ResponseLocalComputerName);
  163. } catch (CErrorWlbsControl Err)
  164. {
  165. //
  166. // Skip this cluster
  167. //
  168. TRACE_CRIT("%!FUNC! Caught a Wlbs exception : 0x%x, Skipping this cluster : 0x%x", Err.Error(),ppCluster[iCluster]->GetClusterIP());
  169. continue;
  170. }
  171. //spawn an instance of the Node MOF class for each node found
  172. ppWlbsInstance = new IWbemClassObject *[nNumNodes];
  173. if( !ppWlbsInstance )
  174. {
  175. TRACE_CRIT("%!FUNC! new failed, Throwing com_error WBEM_E_OUT_OF_MEMORY exception");
  176. throw _com_error( WBEM_E_OUT_OF_MEMORY );
  177. }
  178. //initialize array
  179. ZeroMemory( ppWlbsInstance, nNumNodes * sizeof(IWbemClassObject *) );
  180. for(int i = 0; i < nNumNodes; i ++ )
  181. {
  182. hRes = pWlbsNodeClass->SpawnInstance( 0, &ppWlbsInstance[i] );
  183. if( FAILED( hRes ) )
  184. {
  185. TRACE_CRIT("%!FUNC! IWbemClassObjectPtr::SpawnInstance failed : 0x%x, Throwing com_error exception", hRes);
  186. throw _com_error( hRes );
  187. }
  188. FillWbemInstance(ppCluster[iCluster],
  189. ppWlbsInstance[i],
  190. pResponse + i,
  191. (i == 0) // The first entry is always the local node. So, the local computer name must be passed for the first entry.
  192. ? &ResponseLocalComputerName
  193. : NULL);
  194. }
  195. //send the results back to WinMgMt
  196. hRes = m_pResponseHandler->Indicate( nNumNodes, ppWlbsInstance );
  197. if( FAILED( hRes ) ) {
  198. TRACE_CRIT("%!FUNC! IWbemObjectSink::Indicate failed : 0x%x, Throwing com_error exception", hRes);
  199. throw _com_error( hRes );
  200. }
  201. if( ppWlbsInstance ) {
  202. for( i = 0; i < nNumNodes; i++ ) {
  203. if( ppWlbsInstance[i] ) {
  204. ppWlbsInstance[i]->Release();
  205. }
  206. }
  207. delete [] ppWlbsInstance;
  208. }
  209. if( pResponse )
  210. delete [] pResponse;
  211. }
  212. if( strClassName )
  213. SysFreeString(strClassName);
  214. m_pResponseHandler->SetStatus( 0, WBEM_S_NO_ERROR, NULL, NULL );
  215. hRes = WBEM_S_NO_ERROR;
  216. }
  217. catch(CErrorWlbsControl Err) {
  218. IWbemClassObject* pWbemExtStat = NULL;
  219. TRACE_CRIT("%!FUNC! Caught a Wlbs exception : 0x%x", Err.Error());
  220. CreateExtendedStatus( m_pNameSpace,
  221. &pWbemExtStat,
  222. Err.Error(),
  223. (PWCHAR)(Err.Description()) );
  224. m_pResponseHandler->SetStatus(0, WBEM_E_FAILED, NULL, pWbemExtStat);
  225. if( pWbemExtStat )
  226. pWbemExtStat->Release();
  227. if( strClassName )
  228. SysFreeString( strClassName );
  229. if( ppWlbsInstance ) {
  230. for(int i = 0; i < nNumNodes; i++ ) {
  231. if( ppWlbsInstance[i] ) {
  232. ppWlbsInstance[i]->Release();
  233. }
  234. }
  235. delete [] ppWlbsInstance;
  236. }
  237. if( pResponse )
  238. delete [] pResponse;
  239. //do not return WBEM_E_FAILED, this causes a race condition
  240. hRes = WBEM_S_NO_ERROR;
  241. }
  242. catch(_com_error HResErr ) {
  243. TRACE_CRIT("%!FUNC! Caught a com_error exception : 0x%x", HResErr.Error());
  244. m_pResponseHandler->SetStatus(0, HResErr.Error(), NULL, NULL);
  245. if( strClassName )
  246. SysFreeString( strClassName );
  247. if( ppWlbsInstance ) {
  248. for(int i = 0; i < nNumNodes; i++ ) {
  249. if( ppWlbsInstance[i] ) {
  250. ppWlbsInstance[i]->Release();
  251. }
  252. }
  253. delete [] ppWlbsInstance;
  254. }
  255. if( pResponse )
  256. delete [] pResponse;
  257. hRes = HResErr.Error();
  258. }
  259. catch(...) {
  260. TRACE_CRIT("%!FUNC! Caught an exception");
  261. if( strClassName )
  262. SysFreeString( strClassName );
  263. if( ppWlbsInstance ) {
  264. for(int i = 0; i < nNumNodes; i++ ) {
  265. if( ppWlbsInstance[i] ) {
  266. ppWlbsInstance[i]->Release();
  267. }
  268. }
  269. delete [] ppWlbsInstance;
  270. }
  271. if( pResponse )
  272. delete [] pResponse;
  273. TRACE_CRIT("%!FUNC! Rethrowing exception");
  274. TRACE_CRIT("<-%!FUNC!");
  275. throw;
  276. }
  277. TRACE_CRIT("<-%!FUNC! return 0x%x", hRes);
  278. return hRes;
  279. }
  280. ////////////////////////////////////////////////////////////////////////////////
  281. //
  282. // CWLBS_Node::ExecMethod
  283. //
  284. // Purpose: This executes the methods associated with the MOF
  285. // Node class.
  286. //
  287. ////////////////////////////////////////////////////////////////////////////////
  288. HRESULT CWLBS_Node::ExecMethod
  289. (
  290. const ParsedObjectPath* a_pParsedPath,
  291. const BSTR& a_strMethodName,
  292. long /* a_lFlags */,
  293. IWbemContext* /* a_pIContex */,
  294. IWbemClassObject* a_pIInParams
  295. )
  296. {
  297. DWORD dwNumHosts = 0;
  298. DWORD dwReturnValue;
  299. HRESULT hRes = 0;
  300. _variant_t vMofResponse;
  301. _variant_t vReturnValue;
  302. _variant_t vVip, vInputPortNumber;
  303. CNodeConfiguration NodeConfig;
  304. DWORD dwVip, dwPort;
  305. VARIANT vValue;
  306. BSTR strPortNumber = NULL;
  307. IWbemClassObject* pOutputInstance = NULL;
  308. TRACE_CRIT("->%!FUNC!, Method Name : %ls",a_strMethodName);
  309. try {
  310. strPortNumber = SysAllocString( MOF_PARAM::PORT_NUMBER );
  311. if( !strPortNumber )
  312. {
  313. TRACE_CRIT("%!FUNC! SysAllocString failed, Throwing com_error WBEM_E_OUT_OF_MEMORY exception");
  314. throw _com_error( WBEM_E_OUT_OF_MEMORY );
  315. }
  316. //get the host ID address
  317. DWORD dwHostID = 0;
  318. DWORD dwClusterIpOrIndex = 0;
  319. dwHostID = ExtractHostID( wstring( (*a_pParsedPath->m_paKeys)->m_vValue.bstrVal ) );
  320. if ((DWORD)-1 == dwHostID)
  321. {
  322. TRACE_CRIT("%!FUNC! ExtractHostId failed, Throwing com_error WBEM_E_NOT_FOUND exception");
  323. throw _com_error( WBEM_E_NOT_FOUND );
  324. }
  325. dwClusterIpOrIndex = ExtractClusterIP( wstring( (*a_pParsedPath->m_paKeys)->m_vValue.bstrVal ) );
  326. if ((DWORD)-1 == dwClusterIpOrIndex)
  327. {
  328. TRACE_CRIT("%!FUNC! ExtractClusterIP failed, Throwing com_error WBEM_E_NOT_FOUND exception");
  329. throw _com_error( WBEM_E_NOT_FOUND );
  330. }
  331. CWlbsClusterWrapper* pCluster = g_pWlbsControl->GetClusterFromIpOrIndex(dwClusterIpOrIndex);
  332. if (pCluster == NULL)
  333. {
  334. TRACE_CRIT("%!FUNC! GetClusterFromIpOrIndex failed, Throwing com_error WBEM_E_NOT_FOUND exception");
  335. throw _com_error( WBEM_E_NOT_FOUND );
  336. }
  337. //always let the provider peform control operations on the local host
  338. if( dwHostID == pCluster->GetHostID() )
  339. dwHostID = WLBS_LOCAL_HOST;
  340. //get the output object instance
  341. GetMethodOutputInstance( MOF_NODE::szName,
  342. a_strMethodName,
  343. &pOutputInstance );
  344. //determine and execute the MOF method
  345. if( _wcsicmp(a_strMethodName, MOF_NODE::pMethods[MOF_NODE::DISABLE] ) == 0) {
  346. if( !a_pIInParams )
  347. {
  348. TRACE_CRIT("%!FUNC! No Input parameters passed for %ls method, Throwing com_error WBEM_E_INVALID_PARAMETER exception", a_strMethodName);
  349. throw _com_error( WBEM_E_INVALID_PARAMETER );
  350. }
  351. // The "Disable" method does NOT take vip as a parameter, so, if there is any port rule
  352. // that is specific to a vip (other than the "all vip"), we fail this method.
  353. // The "EffectiveVersion" registry value is checked for a value of CVY_VERSION_FULL to
  354. // see of there is any port rule that is specific to a vip
  355. pCluster->GetNodeConfig(NodeConfig);
  356. if(NodeConfig.dwEffectiveVersion == CVY_VERSION_FULL)
  357. {
  358. TRACE_CRIT("%!FUNC! %ls method called on a cluster that has per-vip port rules (Must call the \"Ex\" equivalent instead). Throwing com_error WBEM_E_INVALID_OPERATION exception", a_strMethodName);
  359. throw _com_error( WBEM_E_INVALID_OPERATION );
  360. }
  361. //get the port number
  362. hRes = a_pIInParams->Get
  363. ( strPortNumber,
  364. 0,
  365. &vInputPortNumber,
  366. NULL,
  367. NULL
  368. );
  369. if( FAILED( hRes ) ) {
  370. TRACE_CRIT("%!FUNC! Error (0x%x) trying retreive Argument %ls for method %ls, Throwing com_error exception", hRes,strPortNumber, a_strMethodName);
  371. throw _com_error( hRes );
  372. }
  373. //make sure the port number is not NULL
  374. if( vInputPortNumber.vt != VT_I4)
  375. {
  376. TRACE_CRIT("%!FUNC! Argument %ls for method %ls is NOT of type \"signed long\", Throwing com_error WBEM_E_INVALID_PARAMETER exception", strPortNumber, a_strMethodName);
  377. throw _com_error( WBEM_E_INVALID_PARAMETER );
  378. }
  379. //call Disable method
  380. dwReturnValue = g_pWlbsControl->Disable
  381. (
  382. pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  383. dwHostID,
  384. NULL,
  385. dwNumHosts,
  386. IpAddressFromAbcdWsz(CVY_DEF_ALL_VIP), // "All Vip"
  387. (long)vInputPortNumber
  388. );
  389. } else if(_wcsicmp(a_strMethodName, MOF_NODE::pMethods[MOF_NODE::ENABLE] ) == 0) {
  390. if( !a_pIInParams )
  391. {
  392. TRACE_CRIT("%!FUNC! No Input parameters passed for %ls method, Throwing com_error WBEM_E_INVALID_PARAMETER exception", a_strMethodName);
  393. throw _com_error( WBEM_E_INVALID_PARAMETER );
  394. }
  395. // The "Enable" method does NOT take vip as a parameter, so, if there is any port rule
  396. // that is specific to a vip (other than the "all vip"), we fail this method.
  397. // The "EffectiveVersion" registry value is checked for a value of CVY_VERSION_FULL to
  398. // see of there is any port rule that is specific to a vip
  399. pCluster->GetNodeConfig(NodeConfig);
  400. if(NodeConfig.dwEffectiveVersion == CVY_VERSION_FULL)
  401. {
  402. TRACE_CRIT("%!FUNC! %ls method called on a cluster that has per-vip port rules (Must call the \"Ex\" equivalent instead). Throwing com_error WBEM_E_INVALID_OPERATION exception", a_strMethodName);
  403. throw _com_error( WBEM_E_INVALID_OPERATION );
  404. }
  405. //get the port number
  406. hRes = a_pIInParams->Get
  407. (
  408. strPortNumber,
  409. 0,
  410. &vInputPortNumber,
  411. NULL,
  412. NULL
  413. );
  414. if( FAILED( hRes ) ) {
  415. TRACE_CRIT("%!FUNC! Error (0x%x) trying retreive Argument %ls for method %ls, Throwing com_error exception", hRes,strPortNumber, a_strMethodName);
  416. throw _com_error( hRes );
  417. }
  418. if( vInputPortNumber.vt != VT_I4)
  419. {
  420. TRACE_CRIT("%!FUNC! Argument %ls for method %ls is NOT of type \"signed long\", Throwing com_error WBEM_E_INVALID_PARAMETER exception", strPortNumber, a_strMethodName);
  421. throw _com_error(WBEM_E_INVALID_PARAMETER);
  422. }
  423. //call Enable method
  424. dwReturnValue = g_pWlbsControl->Enable
  425. (
  426. pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  427. dwHostID,
  428. NULL,
  429. dwNumHosts,
  430. IpAddressFromAbcdWsz(CVY_DEF_ALL_VIP), // "All Vip"
  431. (long)vInputPortNumber
  432. );
  433. } else if(_wcsicmp(a_strMethodName, MOF_NODE::pMethods[MOF_NODE::DRAIN] ) == 0) {
  434. if( !a_pIInParams )
  435. {
  436. TRACE_CRIT("%!FUNC! No Input parameters passed for %ls method, Throwing com_error WBEM_E_INVALID_PARAMETER exception", a_strMethodName);
  437. throw _com_error( WBEM_E_INVALID_PARAMETER );
  438. }
  439. // The "Drain" method does NOT take vip as a parameter, so, if there is any port rule
  440. // that is specific to a vip (other than the "all vip"), we fail this method.
  441. // The "EffectiveVersion" registry value is checked for a value of CVY_VERSION_FULL to
  442. // see of there is any port rule that is specific to a vip
  443. pCluster->GetNodeConfig(NodeConfig);
  444. if(NodeConfig.dwEffectiveVersion == CVY_VERSION_FULL)
  445. {
  446. TRACE_CRIT("%!FUNC! %ls method called on a cluster that has per-vip port rules (Must call the \"Ex\" equivalent instead). Throwing com_error WBEM_E_INVALID_OPERATION exception", a_strMethodName);
  447. throw _com_error( WBEM_E_INVALID_OPERATION );
  448. }
  449. //get the port number
  450. hRes = a_pIInParams->Get
  451. (
  452. strPortNumber,
  453. 0,
  454. &vInputPortNumber,
  455. NULL,
  456. NULL
  457. );
  458. if( FAILED( hRes ) ) {
  459. TRACE_CRIT("%!FUNC! Error (0x%x) trying retreive Argument %ls for method %ls, Throwing com_error exception", hRes,strPortNumber, a_strMethodName);
  460. throw _com_error( hRes );
  461. }
  462. if( vInputPortNumber.vt != VT_I4)
  463. {
  464. TRACE_CRIT("%!FUNC! Argument %ls for method %ls is NOT of type \"signed long\", Throwing com_error WBEM_E_INVALID_PARAMETER exception", strPortNumber, a_strMethodName);
  465. throw _com_error(WBEM_E_INVALID_PARAMETER);
  466. }
  467. //call Drain method
  468. dwReturnValue = g_pWlbsControl->Drain
  469. (
  470. pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  471. dwHostID,
  472. NULL,
  473. dwNumHosts,
  474. IpAddressFromAbcdWsz(CVY_DEF_ALL_VIP), // "All Vip"
  475. (long)vInputPortNumber
  476. );
  477. }else if( _wcsicmp( a_strMethodName, MOF_NODE::pMethods[MOF_NODE::DISABLE_EX] ) == 0) {
  478. if( !a_pIInParams )
  479. {
  480. TRACE_CRIT("%!FUNC! No Input parameters passed for %ls method, Throwing com_error WBEM_E_INVALID_PARAMETER exception", a_strMethodName);
  481. throw _com_error( WBEM_E_INVALID_PARAMETER );
  482. }
  483. // Remote operations are not allowed
  484. if (dwHostID != WLBS_LOCAL_HOST)
  485. {
  486. TRACE_CRIT("%!FUNC! Remote operations are NOT permitted for %ls method, Throwing com_error WBEM_E_INVALID_OPERATION exception", a_strMethodName);
  487. throw _com_error( WBEM_E_INVALID_OPERATION );
  488. }
  489. //get the vip
  490. hRes = a_pIInParams->Get
  491. (
  492. _bstr_t( MOF_PARAM::VIP ),
  493. 0,
  494. &vValue,
  495. NULL,
  496. NULL
  497. );
  498. if( vValue.vt != VT_BSTR )
  499. {
  500. TRACE_CRIT("%!FUNC! Argument %ls for method %ls is NOT of type \"BString\", Throwing com_error WBEM_E_INVALID_PARAMETER exception", MOF_PARAM::VIP, a_strMethodName);
  501. throw _com_error ( WBEM_E_INVALID_PARAMETER );
  502. }
  503. // If the VIP is "All Vip", then, fill in the numeric value
  504. // directly from the macro, else use the conversion function.
  505. // This is 'cos INADDR_NONE, the return value of inet_addr
  506. // function (called by IpAddressFromAbcdWsz) in the failure
  507. // case, is equivalent to the numeric value of CVY_DEF_ALL_VIP
  508. if (_wcsicmp(vValue.bstrVal, CVY_DEF_ALL_VIP) == 0) {
  509. dwVip = CVY_ALL_VIP_NUMERIC_VALUE;
  510. }
  511. else {
  512. dwVip = IpAddressFromAbcdWsz( vValue.bstrVal );
  513. if (dwVip == INADDR_NONE)
  514. {
  515. TRACE_CRIT("%!FUNC! Invalid value (%ls) passed for Argument %ls for method %ls. Throwing com_error WBEM_E_INVALID_PARAMETER exception", vValue.bstrVal, MOF_PARAM::VIP, a_strMethodName);
  516. throw _com_error ( WBEM_E_INVALID_PARAMETER );
  517. }
  518. }
  519. //get the port number
  520. hRes = a_pIInParams->Get
  521. ( strPortNumber,
  522. 0,
  523. &vValue,
  524. NULL,
  525. NULL
  526. );
  527. if( FAILED( hRes ) )
  528. {
  529. TRACE_CRIT("%!FUNC! Error (0x%x) trying retreive Argument %ls for method %ls, Throwing com_error exception", hRes,strPortNumber, a_strMethodName);
  530. throw _com_error( hRes );
  531. }
  532. //range checking is done by the API
  533. if( vValue.vt != VT_I4 )
  534. {
  535. TRACE_CRIT("%!FUNC! Argument %ls for method %ls is NOT of type \"signed long\", Throwing com_error WBEM_E_INVALID_PARAMETER exception", strPortNumber, a_strMethodName);
  536. throw _com_error( WBEM_E_INVALID_PARAMETER );
  537. }
  538. dwPort = vValue.lVal;
  539. //call Disable method
  540. dwReturnValue = g_pWlbsControl->Disable
  541. (
  542. pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  543. dwHostID,
  544. NULL,
  545. dwNumHosts,
  546. dwVip,
  547. dwPort
  548. );
  549. } else if(_wcsicmp( a_strMethodName, MOF_NODE::pMethods[MOF_NODE::ENABLE_EX] ) == 0) {
  550. if( !a_pIInParams )
  551. {
  552. TRACE_CRIT("%!FUNC! No Input parameters passed for %ls method, Throwing com_error WBEM_E_INVALID_PARAMETER exception", a_strMethodName);
  553. throw _com_error( WBEM_E_INVALID_PARAMETER );
  554. }
  555. // Remote operations are not allowed
  556. if (dwHostID != WLBS_LOCAL_HOST)
  557. {
  558. TRACE_CRIT("%!FUNC! Remote operations are NOT permitted for %ls method, Throwing com_error WBEM_E_INVALID_OPERATION exception", a_strMethodName);
  559. throw _com_error( WBEM_E_INVALID_OPERATION );
  560. }
  561. //get the vip
  562. hRes = a_pIInParams->Get
  563. (
  564. _bstr_t( MOF_PARAM::VIP ),
  565. 0,
  566. &vValue,
  567. NULL,
  568. NULL
  569. );
  570. if( vValue.vt != VT_BSTR )
  571. {
  572. TRACE_CRIT("%!FUNC! Argument %ls for method %ls is NOT of type \"string\", Throwing com_error WBEM_E_INVALID_PARAMETER exception", MOF_PARAM::VIP, a_strMethodName);
  573. throw _com_error ( WBEM_E_INVALID_PARAMETER );
  574. }
  575. // If the VIP is "All Vip", then, fill in the numeric value
  576. // directly from the macro, else use the conversion function.
  577. // This is 'cos INADDR_NONE, the return value of inet_addr
  578. // function (called by IpAddressFromAbcdWsz) in the failure
  579. // case, is equivalent to the numeric value of CVY_DEF_ALL_VIP
  580. if (_wcsicmp(vValue.bstrVal, CVY_DEF_ALL_VIP) == 0) {
  581. dwVip = CVY_ALL_VIP_NUMERIC_VALUE;
  582. }
  583. else {
  584. dwVip = IpAddressFromAbcdWsz( vValue.bstrVal );
  585. if (dwVip == INADDR_NONE)
  586. {
  587. TRACE_CRIT("%!FUNC! Invalid value (%ls) passed for Argument %ls for method %ls. Throwing com_error WBEM_E_INVALID_PARAMETER exception", vValue.bstrVal, MOF_PARAM::VIP, a_strMethodName);
  588. throw _com_error ( WBEM_E_INVALID_PARAMETER );
  589. }
  590. }
  591. //get the port number
  592. hRes = a_pIInParams->Get
  593. (
  594. strPortNumber,
  595. 0,
  596. &vValue,
  597. NULL,
  598. NULL
  599. );
  600. if( FAILED( hRes ) )
  601. {
  602. TRACE_CRIT("%!FUNC! Error (0x%x) trying retreive Argument %ls for method %ls, Throwing com_error exception", hRes,strPortNumber, a_strMethodName);
  603. throw _com_error( hRes );
  604. }
  605. //range checking is done by the API
  606. if( vValue.vt != VT_I4 )
  607. {
  608. TRACE_CRIT("%!FUNC! Argument %ls for method %ls is NOT of type \"signed long\", Throwing com_error WBEM_E_INVALID_PARAMETER exception", strPortNumber, a_strMethodName);
  609. throw _com_error( WBEM_E_INVALID_PARAMETER );
  610. }
  611. dwPort = vValue.lVal;
  612. //call Enable method
  613. dwReturnValue = g_pWlbsControl->Enable
  614. (
  615. pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  616. dwHostID,
  617. NULL,
  618. dwNumHosts,
  619. dwVip,
  620. dwPort
  621. );
  622. } else if( _wcsicmp( a_strMethodName, MOF_NODE::pMethods[MOF_NODE::DRAIN_EX] ) == 0 ) {
  623. if( !a_pIInParams )
  624. {
  625. TRACE_CRIT("%!FUNC! No Input parameters passed for %ls method, Throwing com_error WBEM_E_INVALID_PARAMETER exception", a_strMethodName);
  626. throw _com_error( WBEM_E_INVALID_PARAMETER );
  627. }
  628. // Remote operations are not allowed
  629. if (dwHostID != WLBS_LOCAL_HOST)
  630. {
  631. TRACE_CRIT("%!FUNC! Remote operations are NOT permitted for %ls method, Throwing com_error WBEM_E_INVALID_OPERATION exception", a_strMethodName);
  632. throw _com_error( WBEM_E_INVALID_OPERATION );
  633. }
  634. //get the vip
  635. hRes = a_pIInParams->Get
  636. (
  637. _bstr_t( MOF_PARAM::VIP ),
  638. 0,
  639. &vValue,
  640. NULL,
  641. NULL
  642. );
  643. if( vValue.vt != VT_BSTR )
  644. {
  645. TRACE_CRIT("%!FUNC! Argument %ls for method %ls is NOT of type \"BString\", Throwing com_error WBEM_E_INVALID_PARAMETER exception", MOF_PARAM::VIP, a_strMethodName);
  646. throw _com_error ( WBEM_E_INVALID_PARAMETER );
  647. }
  648. // If the VIP is "All Vip", then, fill in the numeric value
  649. // directly from the macro, else use the conversion function.
  650. // This is 'cos INADDR_NONE, the return value of inet_addr
  651. // function (called by IpAddressFromAbcdWsz) in the failure
  652. // case, is equivalent to the numeric value of CVY_DEF_ALL_VIP
  653. if (_wcsicmp(vValue.bstrVal, CVY_DEF_ALL_VIP) == 0) {
  654. dwVip = CVY_ALL_VIP_NUMERIC_VALUE;
  655. }
  656. else {
  657. dwVip = IpAddressFromAbcdWsz( vValue.bstrVal );
  658. if (dwVip == INADDR_NONE)
  659. {
  660. TRACE_CRIT("%!FUNC! Invalid value (%ls) passed for Argument %ls for method %ls. Throwing com_error WBEM_E_INVALID_PARAMETER exception", vValue.bstrVal, MOF_PARAM::VIP, a_strMethodName);
  661. throw _com_error ( WBEM_E_INVALID_PARAMETER );
  662. }
  663. }
  664. //get the port number
  665. hRes = a_pIInParams->Get
  666. (
  667. strPortNumber,
  668. 0,
  669. &vValue,
  670. NULL,
  671. NULL
  672. );
  673. if( FAILED( hRes ) )
  674. {
  675. TRACE_CRIT("%!FUNC! Error (0x%x) trying retreive Argument %ls for method %ls, Throwing com_error exception", hRes,strPortNumber, a_strMethodName);
  676. throw _com_error( hRes );
  677. }
  678. //range checking is done by the API
  679. if( vValue.vt != VT_I4 )
  680. {
  681. TRACE_CRIT("%!FUNC! Argument %ls for method %ls is NOT of type \"signed long\", Throwing com_error WBEM_E_INVALID_PARAMETER exception", strPortNumber, a_strMethodName);
  682. throw _com_error( WBEM_E_INVALID_PARAMETER );
  683. }
  684. dwPort = vValue.lVal;
  685. //call Drain method
  686. dwReturnValue = g_pWlbsControl->Drain
  687. (
  688. pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  689. dwHostID,
  690. NULL,
  691. dwNumHosts,
  692. dwVip,
  693. dwPort
  694. );
  695. } else if(_wcsicmp(a_strMethodName, MOF_NODE::pMethods[MOF_NODE::DRAINSTOP]) == 0) {
  696. //call DrainStop method
  697. dwReturnValue = g_pWlbsControl->DrainStop( pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  698. dwHostID, NULL, dwNumHosts);
  699. } else if(_wcsicmp(a_strMethodName, MOF_NODE::pMethods[MOF_NODE::RESUME] ) == 0) {
  700. //call Resume method
  701. dwReturnValue = g_pWlbsControl->Resume( pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  702. dwHostID, NULL, dwNumHosts);
  703. } else if(_wcsicmp(a_strMethodName, MOF_NODE::pMethods[MOF_NODE::START] ) == 0) {
  704. //call Start method
  705. dwReturnValue = g_pWlbsControl->Start( pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  706. dwHostID, NULL, dwNumHosts);
  707. } else if(_wcsicmp(a_strMethodName, MOF_NODE::pMethods[MOF_NODE::STOP] ) == 0) {
  708. //call Stop method
  709. dwReturnValue = g_pWlbsControl->Stop( pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  710. dwHostID, NULL, dwNumHosts);
  711. } else if(_wcsicmp(a_strMethodName, MOF_NODE::pMethods[MOF_NODE::SUSPEND] ) == 0) {
  712. //call Suspend method
  713. dwReturnValue = g_pWlbsControl->Suspend( pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  714. dwHostID, NULL, dwNumHosts);
  715. } else {
  716. TRACE_CRIT("%!FUNC! Invalid method name : %ls, passed. Throwing com_error WBEM_E_METHOD_NOT_IMPLEMENTED exception", a_strMethodName);
  717. throw _com_error(WBEM_E_METHOD_NOT_IMPLEMENTED);
  718. }
  719. //set the return value
  720. vReturnValue = (long)dwReturnValue;
  721. hRes = pOutputInstance->Put( _bstr_t(L"ReturnValue"), 0, &vReturnValue, 0 );
  722. if( FAILED( hRes ) ) {
  723. TRACE_CRIT("%!FUNC! IWbemClassObject::Put failed : 0x%x for \"ReturnValue\", Throwing com_error exception", hRes);
  724. throw _com_error( hRes );
  725. }
  726. //send the results back to WinMgMt
  727. hRes = m_pResponseHandler->Indicate(1, &pOutputInstance);
  728. if( FAILED( hRes ) ) {
  729. TRACE_CRIT("%!FUNC! IWbemObjectSink::Indicate failed : 0x%x, Throwing com_error exception", hRes);
  730. throw _com_error( hRes );
  731. }
  732. if( strPortNumber ) {
  733. SysFreeString(strPortNumber);
  734. strPortNumber = NULL;
  735. }
  736. m_pResponseHandler->SetStatus( 0, WBEM_S_NO_ERROR, NULL, NULL );
  737. hRes = WBEM_S_NO_ERROR;
  738. }
  739. catch(CErrorWlbsControl Err) {
  740. IWbemClassObject* pWbemExtStat = NULL;
  741. TRACE_CRIT("%!FUNC! Caught a Wlbs exception : 0x%x", Err.Error());
  742. CreateExtendedStatus( m_pNameSpace,
  743. &pWbemExtStat,
  744. Err.Error(),
  745. (PWCHAR)(Err.Description()) );
  746. m_pResponseHandler->SetStatus(0, WBEM_E_FAILED, NULL, pWbemExtStat);
  747. if( strPortNumber ) {
  748. SysFreeString(strPortNumber);
  749. strPortNumber = NULL;
  750. }
  751. if( pOutputInstance ) {
  752. pOutputInstance->Release();
  753. pOutputInstance = NULL;
  754. }
  755. if( pWbemExtStat )
  756. pWbemExtStat->Release();
  757. //do not return WBEM_E_FAILED, this causes a race condition
  758. hRes = WBEM_S_NO_ERROR;
  759. }
  760. catch(_com_error HResErr ) {
  761. TRACE_CRIT("%!FUNC! Caught a com_error exception : 0x%x", HResErr.Error());
  762. m_pResponseHandler->SetStatus(0, HResErr.Error(), NULL, NULL);
  763. if( strPortNumber ) {
  764. SysFreeString(strPortNumber);
  765. strPortNumber = NULL;
  766. }
  767. if( pOutputInstance ) {
  768. pOutputInstance->Release();
  769. pOutputInstance = NULL;
  770. }
  771. hRes = HResErr.Error();
  772. }
  773. catch(...) {
  774. TRACE_CRIT("%!FUNC! Caught an exception");
  775. if( strPortNumber ) {
  776. SysFreeString(strPortNumber);
  777. strPortNumber = NULL;
  778. }
  779. if( pOutputInstance ) {
  780. pOutputInstance->Release();
  781. pOutputInstance = NULL;
  782. }
  783. TRACE_CRIT("%!FUNC! Rethrowing exception");
  784. TRACE_CRIT("<-%!FUNC!");
  785. throw;
  786. }
  787. TRACE_CRIT("<-%!FUNC! return 0x%x", hRes);
  788. return hRes;
  789. }
  790. ////////////////////////////////////////////////////////////////////////////////
  791. //
  792. // CWLBS_Node::FindInstance
  793. //
  794. // Purpose: This routine determines if a host is within the local cluster. If
  795. // it is, then the host's data is obtained and returned via the
  796. // IWbemClassObject interface.
  797. //
  798. ////////////////////////////////////////////////////////////////////////////////
  799. void CWLBS_Node::FindInstance
  800. (
  801. IWbemClassObject** a_ppWbemInstance,
  802. const ParsedObjectPath* a_pParsedPath
  803. )
  804. {
  805. TRACE_VERB("->%!FUNC!");
  806. try {
  807. //get the key property
  808. //throws _com_error
  809. //get the name key property and convert to ANSI
  810. //throws _com_error
  811. wstring szRequestedHostName = ( *a_pParsedPath->m_paKeys)->m_vValue.bstrVal;
  812. DWORD dwClustIpOrIndex = ExtractClusterIP( szRequestedHostName );
  813. CWlbsClusterWrapper* pCluster = g_pWlbsControl->GetClusterFromIpOrIndex(dwClustIpOrIndex);
  814. if( pCluster == NULL )
  815. {
  816. TRACE_CRIT("%!FUNC! GetClusterFromIpOrIndex failed, Throwing com_error WBEM_E_NOT_FOUND exception");
  817. throw _com_error( WBEM_E_NOT_FOUND );
  818. }
  819. WLBS_RESPONSE Response;
  820. DWORD dwHostID = ExtractHostID( szRequestedHostName );
  821. if ((DWORD)-1 == dwHostID)
  822. {
  823. TRACE_CRIT("%!FUNC! ExtractHostId failed, Throwing com_error WBEM_E_NOT_FOUND exception");
  824. throw _com_error( WBEM_E_NOT_FOUND );
  825. }
  826. WLBS_RESPONSE ComputerNameResponse;
  827. WLBS_RESPONSE * pComputerNameResponse;
  828. //always let the provider peform control operations on the local host
  829. if( dwHostID == pCluster->GetHostID() )
  830. {
  831. dwHostID = WLBS_LOCAL_HOST;
  832. pComputerNameResponse = &ComputerNameResponse;
  833. pComputerNameResponse->options.identity.fqdn[0] = UNICODE_NULL;
  834. }
  835. else
  836. {
  837. pComputerNameResponse = NULL;
  838. }
  839. DWORD dwNumHosts = 1;
  840. //call the api query function
  841. g_pWlbsControl->Query( pCluster,
  842. dwHostID ,
  843. &Response ,
  844. pComputerNameResponse, // Query the local host's fqdn
  845. &dwNumHosts,
  846. NULL );
  847. if( dwNumHosts == 0 )
  848. {
  849. TRACE_CRIT("%!FUNC! CWlbsControlWrapper::Query() returned zero hosts, Throwing com_error WBEM_E_NOT_FOUND exception");
  850. throw _com_error( WBEM_E_NOT_FOUND );
  851. }
  852. //if requested, fill a MOF instance structure
  853. if(a_ppWbemInstance) {
  854. //get the Wbem class instance
  855. SpawnInstance( MOF_NODE::szName, a_ppWbemInstance );
  856. //Convert status to string description
  857. FillWbemInstance(pCluster, *a_ppWbemInstance, &Response, pComputerNameResponse);
  858. }
  859. }
  860. catch(...) {
  861. TRACE_CRIT("%!FUNC! Caught an exception");
  862. if( *a_ppWbemInstance ) {
  863. delete *a_ppWbemInstance;
  864. *a_ppWbemInstance = NULL;
  865. }
  866. TRACE_CRIT("%!FUNC! Rethrowing exception");
  867. TRACE_VERB("<-%!FUNC!");
  868. throw;
  869. }
  870. TRACE_VERB("<-%!FUNC!");
  871. }
  872. ////////////////////////////////////////////////////////////////////////////////
  873. //
  874. // CWLBS_Node::FindAllInstances
  875. //
  876. // Purpose: This executes a WLBS query and returns Response structures upon
  877. // success. It always performs a local query to get the local host
  878. // so that disabling remote control will not prevent it from
  879. // enumerating. The dedicated IP address is added to the structure
  880. // within the CWlbsControlWrapper::Query call.
  881. //
  882. ////////////////////////////////////////////////////////////////////////////////
  883. void CWLBS_Node::FindAllInstances
  884. (
  885. CWlbsClusterWrapper* pCluster,
  886. WLBS_RESPONSE** a_ppResponse,
  887. long& a_nNumNodes,
  888. WLBS_RESPONSE* a_pResponseLocalComputerName
  889. )
  890. {
  891. WLBS_RESPONSE Response[WLBS_MAX_HOSTS];
  892. WLBS_RESPONSE LocalResponse;
  893. TRACE_VERB("->%!FUNC!");
  894. ASSERT(pCluster);
  895. ZeroMemory(Response, WLBS_MAX_HOSTS * sizeof(WLBS_RESPONSE));
  896. DWORD dwNumHosts = WLBS_MAX_HOSTS;
  897. a_nNumNodes = 0; //this will contain the number of nodes returned
  898. try {
  899. //get the local host
  900. DWORD dwLocalNode = 1;
  901. g_pWlbsControl->Query( pCluster,
  902. WLBS_LOCAL_HOST,
  903. &LocalResponse,
  904. a_pResponseLocalComputerName, // Query the local computer's fqdn as well
  905. &dwLocalNode,
  906. NULL);
  907. try {
  908. //we only want remote hosts
  909. if( pCluster->GetClusterIP() != 0 )
  910. {
  911. g_pWlbsControl->Query( pCluster,
  912. WLBS_ALL_HOSTS,
  913. Response,
  914. NULL,
  915. &dwNumHosts,
  916. NULL );
  917. }
  918. else
  919. {
  920. dwNumHosts = 0;
  921. }
  922. } catch (CErrorWlbsControl Err) {
  923. TRACE_CRIT("%!FUNC! Caught a Wlbs exception : 0x%x", Err.Error());
  924. dwNumHosts = 0;
  925. if (Err.Error() != WLBS_TIMEOUT)
  926. {
  927. TRACE_CRIT("%!FUNC! Rethrowing exception since it is NOT a WLBS_TIMEOUT");
  928. throw;
  929. }
  930. }
  931. //this wastes memory if the local node
  932. //has remote control enabled
  933. a_nNumNodes = dwNumHosts + 1;
  934. if( a_ppResponse ) {
  935. *a_ppResponse = new WLBS_RESPONSE[a_nNumNodes];
  936. if( !*a_ppResponse )
  937. {
  938. TRACE_CRIT("%!FUNC! new failed a_nNumNodes = 0x%x, sizeof(WLBS_RESPONSE) = 0x%x, Throwing com_error WBEM_E_OUT_OF_MEMORY exception",a_nNumNodes, sizeof(WLBS_RESPONSE));
  939. throw _com_error( WBEM_E_OUT_OF_MEMORY );
  940. }
  941. //copy the local host
  942. (*a_ppResponse)[0] = LocalResponse;
  943. int j = 1;
  944. for(DWORD i = 1; i <= dwNumHosts; i++ )
  945. {
  946. //do not copy the local host again should it have remote control enabled
  947. if( Response[i-1].id == LocalResponse.id )
  948. {
  949. //we received the local node twice, so we reduce the count
  950. //by one
  951. a_nNumNodes--;
  952. continue;
  953. }
  954. (*a_ppResponse)[j] = Response[i-1];
  955. j++;
  956. }
  957. }
  958. } catch (...) {
  959. TRACE_CRIT("%!FUNC! Caught an exception");
  960. if ( *a_ppResponse )
  961. {
  962. delete [] *a_ppResponse;
  963. *a_ppResponse = NULL;
  964. }
  965. TRACE_CRIT("%!FUNC! Rethrowing exception");
  966. TRACE_VERB("<-%!FUNC!");
  967. throw;
  968. }
  969. TRACE_VERB("<-%!FUNC!");
  970. }
  971. ////////////////////////////////////////////////////////////////////////////////
  972. //
  973. // CWLBS_Node::FillWbemInstance
  974. //
  975. // Purpose: This function copies all of the data from a node configuration
  976. // structure to a WBEM instance.
  977. //
  978. ////////////////////////////////////////////////////////////////////////////////
  979. void CWLBS_Node::FillWbemInstance
  980. (
  981. CWlbsClusterWrapper* pCluster,
  982. IWbemClassObject* a_pWbemInstance,
  983. WLBS_RESPONSE* a_pResponse,
  984. WLBS_RESPONSE* a_pResponseLocalComputerName
  985. )
  986. {
  987. namespace NODE = MOF_NODE;
  988. TRACE_VERB("->%!FUNC!");
  989. ASSERT( a_pWbemInstance );
  990. ASSERT( a_pResponse );
  991. wstring wstrHostName;
  992. ConstructHostName( wstrHostName, pCluster->GetClusterIpOrIndex(g_pWlbsControl),
  993. a_pResponse->id );
  994. //HOST NAME
  995. HRESULT hRes = a_pWbemInstance->Put
  996. (
  997. _bstr_t( NODE::pProperties[NODE::NAME] ) ,
  998. 0 ,
  999. &_variant_t(wstrHostName.c_str()),
  1000. NULL
  1001. );
  1002. if( FAILED( hRes ) )
  1003. throw _com_error( hRes );
  1004. //HOST ID
  1005. hRes = a_pWbemInstance->Put
  1006. (
  1007. _bstr_t( NODE::pProperties[NODE::HOSTID] ) ,
  1008. 0 ,
  1009. &_variant_t((long)(a_pResponse->id)),
  1010. NULL
  1011. );
  1012. if( FAILED( hRes ) )
  1013. throw _com_error( hRes );
  1014. //CREATCLASS
  1015. hRes = a_pWbemInstance->Put
  1016. (
  1017. _bstr_t( NODE::pProperties[NODE::CREATCLASS] ),
  1018. 0 ,
  1019. &_variant_t(NODE::szName),
  1020. NULL
  1021. );
  1022. if( FAILED( hRes ) )
  1023. throw _com_error( hRes );
  1024. //IP ADDRESS
  1025. wstring szIPAddress;
  1026. AddressToString( a_pResponse->address, szIPAddress );
  1027. hRes = a_pWbemInstance->Put
  1028. (
  1029. _bstr_t( NODE::pProperties[NODE::IPADDRESS] ),
  1030. 0 ,
  1031. &_variant_t(szIPAddress.c_str()),
  1032. NULL
  1033. );
  1034. if( FAILED( hRes ) )
  1035. throw _com_error( hRes );
  1036. //STATUS
  1037. hRes = a_pWbemInstance->Put
  1038. (
  1039. _bstr_t( NODE::pProperties[NODE::STATUS] ) ,
  1040. 0 ,
  1041. &_variant_t((long)a_pResponse->status),
  1042. NULL
  1043. );
  1044. if( FAILED( hRes ) )
  1045. throw _com_error( hRes );
  1046. //COMPUTER NAME
  1047. WCHAR *szComputerName;
  1048. if (a_pResponseLocalComputerName) {
  1049. szComputerName = a_pResponseLocalComputerName->options.identity.fqdn;
  1050. }
  1051. else if (a_pResponse->options.query.flags & NLB_OPTIONS_QUERY_HOSTNAME) {
  1052. szComputerName = a_pResponse->options.query.hostname;
  1053. }
  1054. else{
  1055. szComputerName = L"";
  1056. }
  1057. hRes = a_pWbemInstance->Put
  1058. (
  1059. _bstr_t( NODE::pProperties[NODE::COMPUTERNAME] ) ,
  1060. 0 ,
  1061. &_variant_t(szComputerName),
  1062. NULL
  1063. );
  1064. if( FAILED( hRes ) )
  1065. throw _com_error( hRes );
  1066. TRACE_VERB("<-%!FUNC!");
  1067. }