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.

654 lines
18 KiB

  1. #include "Common.h"
  2. #include "MWmiInstance.h"
  3. #include "MWmiObject.h"
  4. #include "MTrace.h"
  5. #include "wlbsctrl.h"
  6. #include "MIPAddressAdmin.h"
  7. #include "WTokens.h"
  8. #include <winsock2.h>
  9. #include <vector>
  10. #include <memory>
  11. using namespace std;
  12. // History:
  13. // --------
  14. //
  15. //
  16. // Revised by : mhakim
  17. // Date : 02-12-01
  18. // Reason : remote control was checked by default, changed to unchecked.
  19. int
  20. WlbsAddressToString( DWORD address, wchar_t* buf, PDWORD len );
  21. //WLBS_STATUS
  22. DWORD
  23. Common::getHostsInCluster( _bstr_t clusterIP, vector< HostProperties >* hostPropertiesStore )
  24. {
  25. return WLBS_BAD_PARAMS;
  26. DWORD retValue;
  27. DWORD cluster;
  28. WLBS_RESPONSE response[ WLBS_MAX_HOSTS ];
  29. DWORD num_host = WLBS_MAX_HOSTS;
  30. DWORD host_map;
  31. wchar_t buf[ Common::BUF_SIZE];
  32. BOOL retBOOL;
  33. int i;
  34. DWORD len;
  35. HostProperties hp;
  36. char *char_buf;
  37. // do init call
  38. // retValue = WlbsInit (L"wlbs", WLBS_API_VER, NULL);
  39. // convert clusterIP into DWORD representation.
  40. cluster = inet_addr( clusterIP );
  41. if( cluster == INADDR_NONE )
  42. {
  43. TRACE( MTrace::SEVERE_ERROR, "cluster ip is invalid\n" );
  44. return WLBS_BAD_PARAMS;
  45. }
  46. // do wlbs query.
  47. // retValue = WlbsQuery( cluster, WLBS_ALL_HOSTS, response, &num_host, &host_map, NULL);
  48. if( retValue == WLBS_TIMEOUT )
  49. {
  50. return retValue;
  51. }
  52. // fill in the vector container.
  53. for( i = 0; i < num_host; ++i )
  54. {
  55. // get dip
  56. len = Common::BUF_SIZE;
  57. char_buf = inet_ntoa( *( ( struct in_addr *) &(response[i].address)));
  58. if( char_buf == NULL )
  59. {
  60. TRACE( MTrace::SEVERE_ERROR, "invalid ip address obtained\n");
  61. continue;
  62. }
  63. CharToWChar( char_buf,
  64. strlen( char_buf ) + 1,
  65. buf,
  66. Common::BUF_SIZE );
  67. hp.hIP = buf;
  68. // get host id.
  69. hp.hID = response[i].id;
  70. // get host status
  71. hp.hostStatus = response[i].status;
  72. hostPropertiesStore->push_back( hp );
  73. }
  74. return retValue;
  75. }
  76. void
  77. Common::getWLBSErrorString( DWORD errStatus, // IN
  78. _bstr_t& errString, // OUT
  79. _bstr_t& extErrString // OUT
  80. )
  81. {
  82. switch( errStatus )
  83. {
  84. case 1000 :
  85. errString = L"WLBS_OK";
  86. extErrString = L"WLBS_OK The operation completed successfully. \n";
  87. break;
  88. case 1001 :
  89. errString = L"WLBS_ALREADY";
  90. extErrString = L"WLBS_ALREADY The specified target is already in the state that the requested operation would produce. \n";
  91. break;
  92. case 1002 :
  93. errString = L"WLBS_DRAIN_STOP";
  94. extErrString = L"WLBS_DRAIN_STOP One or more nodes reported a drain stop operation. \n";
  95. break;
  96. case 1003 :
  97. errString = L"WLBS_BAD_PARAMS";
  98. extErrString = L"WLBS_BAD_PARAMS Bad configuration parameters in a node's registry prevented the node from starting cluster operations. \n" ;
  99. break;
  100. case 1004 :
  101. errString = L"WLBS_NOT_FOUND";
  102. extErrString = L"WLBS_NOT_FOUND The specified port number was not found in any port rule.. \n";
  103. break;
  104. case 1005 :
  105. errString = L"WLBS_STOPPED";
  106. extErrString = L"WLBS_STOPPED Cluster operations have stopped on at least one node. \n";
  107. break;
  108. case 1006 :
  109. errString = L"WLBS_CONVERGING";
  110. extErrString = L"WLBS_CONVERGING The cluster is converging. \n";
  111. break;
  112. case 1007 :
  113. errString = L"WLBS_CONVERGED";
  114. extErrString = L"WLBS_CONVERGED The cluster has converged successfully. \n";
  115. break;
  116. case 1008 :
  117. errString = L"WLBS_DEFAULT";
  118. extErrString = L"WLBS_DEFAULT The specified node has converged as the default host. \n";
  119. break;
  120. case 1009 :
  121. errString = L"WLBS_DRAINING";
  122. extErrString = L"WLBS_DRAINING One or more nodes are draining. \n";
  123. break;
  124. case 1013 :
  125. errString = L"WLBS_SUSPENDED";
  126. extErrString = L"WLBS_SUSPENDED Cluster operations have been suspended on one or more nodes. \n" ;
  127. break;
  128. case 1050 :
  129. errString = L"WLBS_REBOOT";
  130. extErrString = L"WLBS_REBOOT The node must be rebooted for the specified configuration changes to take effect. \n" ;
  131. break;
  132. case 1100 :
  133. errString = L"WLBS_INIT_ERROR";
  134. extErrString = L"WLBS_INIT_ERROR An internal error prevented initialization of the cluster control module. \n" ;
  135. break;
  136. case 1101 :
  137. errString = L"WLBS_BAD_PASSW";
  138. extErrString = L"WLBS_BAD_PASSW The specified password was not accepted by the cluster. \n";
  139. break;
  140. case 1102:
  141. errString = L"WLBS_IO_ERROR";
  142. extErrString = L"WLBS_IO_ERROR A local I/O error prevents communication with the Network Load Balancing driver. \n " ;
  143. break;
  144. case 1103 :
  145. errString = L"WLBS_TIMEOUT";
  146. extErrString = L"WLBS_TIMEOUT The requested operation timed out without receiving a response from the specified node. \n";
  147. break;
  148. case 1150 :
  149. errString = L"WLBS_PORT_OVERLAP";
  150. extErrString = L"WLBS_PORT_OVERLAP At least one of the port numbers in the specified port rule is currently listed in at least one other port rule. \n";
  151. break;
  152. case 1151 :
  153. errString = L"WLBS_BAD_PORT_PARAMS";
  154. extErrString = L"WLBS_BAD_PORT_PARAMS The settings for one or more port rules contain one or more invalid values. \n";
  155. break;
  156. case 1152 :
  157. errString = L"WLBS_MAX_PORT_RULES";
  158. extErrString = L"WLBS_MAX_PORT_RULES The cluster contains the maximum number of port rules. \n";
  159. break;
  160. case 1153 :
  161. errString = L"WLBS_TRUNCATED";
  162. extErrString = L"WLBS_TRUNCATED The return value has been truncated. \n";
  163. break;
  164. case 1154 :
  165. errString = L"WLBS_REG_ERROR";
  166. extErrString = L"WLBS_REG_ERROR An internal registry access error occurred. ";
  167. break;
  168. default :
  169. errString = L"WLBS_UNKNOWN";
  170. extErrString = L"unknown error. Contact zubaira head of wlbs project.\n";
  171. }
  172. }
  173. DWORD
  174. Common::getNLBNicInfoForWin2k( const _bstr_t& machineIP, NicInfo& nicInfo )
  175. {
  176. MWmiObject machine( machineIP,
  177. L"root\\microsoftnlb",
  178. L"Administrator",
  179. L"" );
  180. vector<MWmiInstance> instanceStore;
  181. machine.getInstances( L"NlbsNic",
  182. &instanceStore );
  183. // input parameters are none.
  184. //
  185. vector<MWmiParameter *> inputParameters;
  186. // output parameters which are of interest.
  187. //
  188. vector<MWmiParameter *> outputParameters;
  189. MWmiParameter ReturnValue(L"ReturnValue");
  190. outputParameters.push_back( &ReturnValue );
  191. for( int i = 0; i < instanceStore.size(); ++i )
  192. {
  193. instanceStore[i].runMethod( L"isBound",
  194. inputParameters,
  195. outputParameters );
  196. if( long( ReturnValue.getValue() ) == 1 )
  197. {
  198. // this is the nic we are looking for as
  199. // for win2k there can only be one nic.
  200. vector<MWmiParameter *> parameterStore;
  201. MWmiParameter AdapterGuid(L"AdapterGuid");
  202. parameterStore.push_back( &AdapterGuid );
  203. MWmiParameter FullName(L"FullName");
  204. parameterStore.push_back( &FullName );
  205. MWmiParameter FriendlyName(L"FriendlyName");
  206. parameterStore.push_back( &FriendlyName );
  207. instanceStore[i].getParameters( parameterStore );
  208. nicInfo.fullNicName = FullName.getValue();
  209. nicInfo.adapterGuid = AdapterGuid.getValue();
  210. nicInfo.friendlyName = FriendlyName.getValue();
  211. // we also need to get all the ip addresses
  212. // on this nic
  213. MIPAddressAdmin ipAdmin( machineIP, nicInfo.fullNicName );
  214. ipAdmin.getIPAddresses( &nicInfo.ipsOnNic,
  215. &nicInfo.subnetMasks );
  216. // check if this nic is dhcp or not.
  217. ipAdmin.isDHCPEnabled( nicInfo.dhcpEnabled );
  218. return 0;
  219. }
  220. }
  221. // this should not happen, as how come there is no nic
  222. // with nlbs bound.
  223. TRACE(MTrace::SEVERE_ERROR, L"not able to find nic on win2k\n");
  224. throw _com_error( WBEM_E_NOT_FOUND );
  225. }
  226. DWORD
  227. Common::getNLBNicInfoForWhistler( const _bstr_t& machineIP, const _bstr_t& guid, NicInfo& nicInfo )
  228. {
  229. MWmiObject machine( machineIP,
  230. L"root\\microsoftnlb",
  231. L"Administrator",
  232. L"" );
  233. vector<MWmiInstance> instanceStore;
  234. machine.getInstances( L"NlbsNic",
  235. &instanceStore );
  236. // input parameters are none.
  237. //
  238. vector<MWmiParameter *> inputParameters;
  239. // output parameters which are of interest.
  240. //
  241. vector<MWmiParameter *> outputParameters;
  242. MWmiParameter ReturnValue(L"ReturnValue");
  243. outputParameters.push_back( &ReturnValue );
  244. vector<MWmiParameter *> parameterStore;
  245. MWmiParameter AdapterGuid(L"AdapterGuid");
  246. parameterStore.push_back( &AdapterGuid );
  247. MWmiParameter FullName(L"FullName");
  248. parameterStore.push_back( &FullName );
  249. MWmiParameter FriendlyName(L"FriendlyName");
  250. parameterStore.push_back( &FriendlyName );
  251. for( int i = 0; i < instanceStore.size(); ++i )
  252. {
  253. instanceStore[i].getParameters( parameterStore );
  254. if( _bstr_t( AdapterGuid.getValue()) == guid )
  255. {
  256. nicInfo.fullNicName = FullName.getValue();
  257. nicInfo.adapterGuid = AdapterGuid.getValue();
  258. nicInfo.friendlyName = FriendlyName.getValue();
  259. // we also need to get all the ip addresses
  260. // on this nic
  261. MIPAddressAdmin ipAdmin( machineIP, nicInfo.fullNicName );
  262. ipAdmin.getIPAddresses( &nicInfo.ipsOnNic,
  263. &nicInfo.subnetMasks );
  264. return 0;
  265. }
  266. }
  267. // this should not happen, as how come there is no nic
  268. // with nlbs bound with guid specified.
  269. TRACE(MTrace::SEVERE_ERROR, L"not able to find nic with guid on whistler\n");
  270. throw _com_error( WBEM_E_NOT_FOUND );
  271. }
  272. _bstr_t
  273. Common::mapNicToClusterIP( const _bstr_t& machineIP,
  274. const _bstr_t& fullNicName )
  275. {
  276. //
  277. // ensure that nic is present, and bound to nlbs
  278. // on nic specified.
  279. MWmiObject machine( machineIP,
  280. L"root\\microsoftnlb",
  281. L"administrator",
  282. L"" );
  283. vector<MWmiInstance> instanceStore;
  284. _bstr_t relPath = L"NlbsNic.FullName=\"" + fullNicName + "\"";
  285. machine.getSpecificInstance( L"NlbsNic",
  286. relPath,
  287. &instanceStore );
  288. // input parameters are none.
  289. //
  290. vector<MWmiParameter *> inputParameters;
  291. // output parameters which are of interest.
  292. //
  293. vector<MWmiParameter *> outputParameters;
  294. MWmiParameter ReturnValue(L"ReturnValue");
  295. outputParameters.push_back( &ReturnValue );
  296. instanceStore[0].runMethod( L"IsBound",
  297. inputParameters,
  298. outputParameters );
  299. if( long( ReturnValue.getValue() ) == 1 )
  300. {
  301. // it is bound so proceed.
  302. }
  303. else if( long( ReturnValue.getValue() ) == 0 )
  304. {
  305. TRACE( MTrace::SEVERE_ERROR,
  306. L"Nic does not have nlb bound to it" );
  307. throw _com_error( WBEM_E_NOT_FOUND );
  308. }
  309. else
  310. {
  311. TRACE( MTrace::SEVERE_ERROR,
  312. L"Not able to check if nlb is bound or not" );
  313. throw _com_error( WBEM_E_NOT_FOUND );
  314. }
  315. // get guid for this instance
  316. vector<MWmiParameter* > parameterStore;
  317. MWmiParameter AdapterGuid(L"AdapterGuid");
  318. parameterStore.push_back( &AdapterGuid );
  319. instanceStore[0].getParameters( parameterStore );
  320. //
  321. // find clustersettingclass mapping to this nic.
  322. //
  323. // set parameters to get.
  324. //
  325. parameterStore.erase( parameterStore.begin(),
  326. parameterStore.end() );
  327. MWmiParameter Name(L"Name");
  328. parameterStore.push_back( &Name );
  329. // get guid
  330. // This parameter not present on win2k nlbs provider.
  331. //
  332. MWmiParameter NLBAdapterGuid(L"AdapterGuid");
  333. parameterStore.push_back( &NLBAdapterGuid );
  334. // get instances of clustersetting class.
  335. //
  336. instanceStore.erase( instanceStore.begin(),
  337. instanceStore.end() );
  338. bool found = false;
  339. machine.getInstances( L"Microsoftnlb_ClusterSetting",
  340. &instanceStore );
  341. found = false;
  342. for( int i = 0; i < instanceStore.size(); ++i )
  343. {
  344. try
  345. {
  346. instanceStore[i].getParameters( parameterStore );
  347. }
  348. catch( _com_error e )
  349. {
  350. // the above operation can fail on win2k machines.
  351. // if so we need to handle exception. This clustersetting is the actual one
  352. // required.
  353. found = true;
  354. break; // get out of for loop.
  355. }
  356. if( _bstr_t( NLBAdapterGuid.getValue()) == _bstr_t( AdapterGuid.getValue() ) )
  357. {
  358. // right object found
  359. found = true;
  360. break;
  361. }
  362. }
  363. if( found == false )
  364. {
  365. TRACE(MTrace::SEVERE_ERROR, L"this is unexpected and a bug. NlbsNic and ClusterSetting class guids may not be matching\n");
  366. throw _com_error( WBEM_E_UNEXPECTED );
  367. }
  368. _bstr_t name = _bstr_t( Name.getValue() );
  369. WTokens tok;
  370. vector<wstring> tokens;
  371. tok.init( wstring( name ),
  372. L":" );
  373. tokens = tok.tokenize();
  374. return tokens[0].c_str();
  375. }
  376. // default constructor
  377. //
  378. NicInfo::NicInfo()
  379. :
  380. fullNicName( L"Not set"),
  381. adapterGuid( L"Not set"),
  382. friendlyName( L"Not set")
  383. {}
  384. // equality operator
  385. //
  386. bool
  387. NicInfo::operator==( const NicInfo& objToCompare )
  388. {
  389. if( ( fullNicName == objToCompare.fullNicName )
  390. &&
  391. ( adapterGuid == objToCompare.adapterGuid )
  392. )
  393. {
  394. return true;
  395. }
  396. else
  397. {
  398. return false;
  399. }
  400. }
  401. // inequality operator
  402. //
  403. bool
  404. NicInfo::operator!=( const NicInfo& objToCompare )
  405. {
  406. return !operator==(objToCompare );
  407. }
  408. // default constructor
  409. //
  410. ClusterProperties::ClusterProperties()
  411. {
  412. cIP = L"0.0.0.0";
  413. cSubnetMask = L"0.0.0.0";
  414. cFullInternetName = L"www.nlb-cluster.com";
  415. cNetworkAddress = L"00-00-00-00-00-00";
  416. multicastSupportEnabled = false;
  417. // Edited (mhakim 12-02-01 )
  418. // remote control was on by default, changed it to mimic core
  419. // and now off.
  420. // remoteControlEnabled = true;
  421. remoteControlEnabled = false;
  422. password = L"";
  423. igmpSupportEnabled = false;
  424. clusterIPToMulticastIP = true;
  425. }
  426. // equality operator
  427. //
  428. bool
  429. ClusterProperties::operator==( const ClusterProperties& objToCompare )
  430. {
  431. bool btemp1, btemp2; // Variables to pass to below function. Returned values not used
  432. return !HaveClusterPropertiesChanged(objToCompare, &btemp1, &btemp2);
  433. }
  434. // equality operator
  435. //
  436. bool
  437. ClusterProperties::HaveClusterPropertiesChanged( const ClusterProperties& objToCompare,
  438. bool *pbOnlyClusterNameChanged,
  439. bool *pbClusterIpChanged)
  440. {
  441. *pbClusterIpChanged = false;
  442. *pbOnlyClusterNameChanged = false;
  443. if( cIP != objToCompare.cIP )
  444. {
  445. *pbClusterIpChanged = true;
  446. return true;
  447. }
  448. else if (
  449. ( cSubnetMask != objToCompare.cSubnetMask )
  450. ||
  451. ( cNetworkAddress != objToCompare.cNetworkAddress )
  452. ||
  453. ( multicastSupportEnabled != objToCompare.multicastSupportEnabled )
  454. ||
  455. ( igmpSupportEnabled != objToCompare.igmpSupportEnabled )
  456. ||
  457. ( clusterIPToMulticastIP != objToCompare.clusterIPToMulticastIP )
  458. )
  459. {
  460. return true;
  461. }
  462. else if (
  463. ( cFullInternetName != objToCompare.cFullInternetName )
  464. ||
  465. ( remoteControlEnabled != objToCompare.remoteControlEnabled )
  466. )
  467. {
  468. *pbOnlyClusterNameChanged = true;
  469. return true;
  470. }
  471. else if (
  472. ( remoteControlEnabled == true )
  473. &&
  474. ( password != objToCompare.password )
  475. )
  476. {
  477. *pbOnlyClusterNameChanged = true;
  478. return true;
  479. }
  480. return false;
  481. }
  482. // inequality operator
  483. //
  484. bool
  485. ClusterProperties::operator!=( const ClusterProperties& objToCompare )
  486. {
  487. bool btemp1, btemp2; // Variables to pass to below function. Returned values not used
  488. return HaveClusterPropertiesChanged(objToCompare, &btemp1, &btemp2);
  489. }
  490. // default constructor
  491. //
  492. HostProperties::HostProperties()
  493. {
  494. // TODO set all properties with default values.
  495. }
  496. // equality operator
  497. //
  498. bool
  499. HostProperties::operator==( const HostProperties& objToCompare )
  500. {
  501. if( ( hIP == objToCompare.hIP )
  502. &&
  503. ( hSubnetMask == objToCompare.hSubnetMask )
  504. &&
  505. ( hID == objToCompare.hID )
  506. &&
  507. ( initialClusterStateActive == objToCompare.initialClusterStateActive )
  508. &&
  509. ( hostStatus == objToCompare.hostStatus )
  510. &&
  511. ( nicInfo == objToCompare.nicInfo )
  512. &&
  513. ( machineName == objToCompare.machineName )
  514. )
  515. {
  516. return true;
  517. }
  518. else
  519. {
  520. return false;
  521. }
  522. }
  523. // inequality operator
  524. //
  525. bool
  526. HostProperties::operator!=( const HostProperties& objToCompare )
  527. {
  528. return !operator==(objToCompare );
  529. }