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.

470 lines
14 KiB

  1. #include "HostPage.h"
  2. #include "CommonUtils.h"
  3. #include "CommonNLB.h"
  4. #include "MIPAddress.h"
  5. #include "ResourceString.h"
  6. #include <vector>
  7. #include <algorithm>
  8. using namespace std;
  9. //
  10. // History:
  11. // --------
  12. //
  13. // Revised by : mhakim
  14. // Date : 02-14-01
  15. // Reason : Passing complete nic information instead of only the nic list.
  16. //
  17. // Reason : If nic selected is the one which has the connection ip, then
  18. // dip has to be connection ip.
  19. BEGIN_MESSAGE_MAP( HostPage, CPropertyPage )
  20. ON_EN_SETFOCUS( IDC_EDIT_DED_IP, OnGainFocusDedicatedIP )
  21. ON_EN_SETFOCUS( IDC_EDIT_DED_MASK, OnGainFocusDedicatedMask )
  22. ON_LBN_SELCHANGE(IDC_NIC, OnSelectedNicChanged )
  23. ON_WM_HELPINFO()
  24. ON_WM_CONTEXTMENU()
  25. END_MESSAGE_MAP()
  26. HostPage::HostPage( const _bstr_t& machine,
  27. ClusterData* p_clusterData,
  28. const vector<CommonNLB::NicNLBBound> listOfNics,
  29. const bool& isNewHost,
  30. UINT ID )
  31. :
  32. m_machine( machine ),
  33. m_clusterData( p_clusterData ),
  34. m_nicList( listOfNics ),
  35. m_isNewHost( isNewHost ),
  36. CPropertyPage( ID )
  37. {
  38. }
  39. void
  40. HostPage::DoDataExchange( CDataExchange* pDX )
  41. {
  42. DDX_Control( pDX, IDC_NIC, nicName );
  43. DDX_Control( pDX, IDC_EDIT_PRI, priority );
  44. DDX_Control( pDX, IDC_CHECK_ACTIVE, initialState );
  45. DDX_Control( pDX, IDC_NIC_DETAIL, detailedNicInfo );
  46. DDX_Control( pDX, IDC_EDIT_DED_IP, ipAddress );
  47. DDX_Control( pDX, IDC_EDIT_DED_MASK, subnetMask );
  48. }
  49. BOOL
  50. HostPage::OnInitDialog()
  51. {
  52. CPropertyPage::OnInitDialog();
  53. SetControlData();
  54. return TRUE;
  55. }
  56. void
  57. HostPage::SetControlData()
  58. {
  59. // fill in nic name.
  60. for( int i = 0; i < m_nicList.size(); ++i )
  61. {
  62. // using insertstring so we can add it to exact position.
  63. //
  64. nicName.InsertString( i, m_nicList[i].friendlyName );
  65. }
  66. // keep a track of nic selection.
  67. m_previousSelection = nicName.SelectString( -1,
  68. m_clusterData->hosts[m_machine].hp.nicInfo.friendlyName );
  69. // fill in detailed nic info.
  70. detailedNicInfo.SetWindowText( m_clusterData->hosts[m_machine].hp.nicInfo.fullNicName );
  71. // fill in priority.
  72. wchar_t buf[Common::BUF_SIZE];
  73. set<int> availHostIDS = m_clusterData->getAvailableHostIDS();
  74. // add this hosts priority.
  75. availHostIDS.insert( m_clusterData->hosts[m_machine].hp.hID );
  76. set<int>::iterator top;
  77. for( top = availHostIDS.begin();
  78. top != availHostIDS.end();
  79. ++top )
  80. {
  81. swprintf( buf, L"%d", *top );
  82. priority.AddString( buf );
  83. }
  84. // set selection to present hostid
  85. swprintf( buf, L"%d", m_clusterData->hosts[m_machine].hp.hID );
  86. priority.SelectString( -1, buf );
  87. // set initial cluster state.
  88. initialState.SetCheck(
  89. m_clusterData->hosts[m_machine].hp.initialClusterStateActive );
  90. // fill in host ip
  91. CommonUtils::fillCIPAddressCtrlString(
  92. ipAddress,
  93. m_clusterData->hosts[m_machine].hp.hIP );
  94. // set host mask.
  95. CommonUtils::fillCIPAddressCtrlString(
  96. subnetMask,
  97. m_clusterData->hosts[m_machine].hp.hSubnetMask );
  98. }
  99. // ReadControlData
  100. //
  101. void
  102. HostPage::ReadControlData()
  103. {
  104. wchar_t buf[Common::BUF_SIZE ];
  105. // fill in nic name.
  106. int currentSelection = nicName.GetCurSel();
  107. m_clusterData->hosts[m_machine].hp.nicInfo.fullNicName = m_nicList[currentSelection].fullNicName;
  108. m_clusterData->hosts[m_machine].hp.nicInfo.adapterGuid = m_nicList[currentSelection].adapterGuid;
  109. m_clusterData->hosts[m_machine].hp.nicInfo.friendlyName = m_nicList[currentSelection].friendlyName;
  110. m_clusterData->hosts[m_machine].hp.nicInfo.dhcpEnabled = m_nicList[currentSelection].dhcpEnabled;
  111. m_clusterData->hosts[m_machine].hp.nicInfo.ipsOnNic = m_nicList[currentSelection].ipsOnNic;
  112. m_clusterData->hosts[m_machine].hp.nicInfo.subnetMasks = m_nicList[currentSelection].subnetMasks;
  113. // fill in priority.
  114. int selectedPriorityIndex = priority.GetCurSel();
  115. priority.GetLBText( selectedPriorityIndex, buf );
  116. m_clusterData->hosts[m_machine].hp.hID = _wtoi( buf );
  117. // fill in host ip
  118. m_clusterData->hosts[m_machine].hp.hIP =
  119. CommonUtils::getCIPAddressCtrlString( ipAddress );
  120. // set host mask.
  121. m_clusterData->hosts[m_machine].hp.hSubnetMask =
  122. CommonUtils::getCIPAddressCtrlString( subnetMask );
  123. // set initial cluster state.
  124. m_clusterData->hosts[m_machine].hp.initialClusterStateActive =
  125. initialState.GetCheck() ? true : false;
  126. }
  127. void
  128. HostPage::OnOK()
  129. {
  130. CPropertyPage::OnOK();
  131. }
  132. bool
  133. HostPage::isDipConfiguredOK()
  134. {
  135. // if nic selected has the connection ip then
  136. // connection ip has to match the dip to ensure
  137. // future connectivity.
  138. //
  139. // if connection ip is same as dip then no need
  140. // to worry.
  141. //
  142. if( m_clusterData->hosts[m_machine].hp.hIP ==
  143. m_clusterData->hosts[m_machine].connectionIP )
  144. {
  145. return true;
  146. }
  147. // check if selected nic has connection ip.
  148. if( find( m_clusterData->hosts[m_machine].hp.nicInfo.ipsOnNic.begin(),
  149. m_clusterData->hosts[m_machine].hp.nicInfo.ipsOnNic.end(),
  150. m_clusterData->hosts[m_machine].connectionIP )
  151. !=
  152. m_clusterData->hosts[m_machine].hp.nicInfo.ipsOnNic.end() )
  153. {
  154. // the nic selected has the connection ip.
  155. return false;
  156. }
  157. // selected nic does not have connection ip, so dont care.
  158. return true;
  159. }
  160. BOOL
  161. HostPage::OnKillActive()
  162. {
  163. ReadControlData();
  164. // ip is blank
  165. // subnet is blank
  166. // valid
  167. if( ( m_clusterData->hosts[m_machine].hp.hIP == _bstr_t( L"0.0.0.0") )
  168. &&
  169. ( m_clusterData->hosts[m_machine].hp.hSubnetMask == _bstr_t( L"0.0.0.0") )
  170. )
  171. {
  172. // both ip and subnet can be blank or 0.0.0.0 in host page. both but not
  173. // either.
  174. //
  175. // this is empty, we just need to catch this case.
  176. }
  177. else if( m_clusterData->hosts[m_machine].hp.hIP == _bstr_t( L"0.0.0.0") )
  178. {
  179. // if only ip is blank or 0.0.0.0 then this is not allowed
  180. MessageBox( GETRESOURCEIDSTRING( IDS_PARM_DED_IP_BLANK ),
  181. GETRESOURCEIDSTRING( IDS_PARM_ERROR ),
  182. MB_ICONSTOP | MB_OK );
  183. CPropertyPage::OnCancel();
  184. return 0;
  185. }
  186. else
  187. {
  188. // check if ip is valid.
  189. bool isIPValid = MIPAddress::checkIfValid(m_clusterData->hosts[m_machine].hp.hIP );
  190. if( isIPValid != true )
  191. {
  192. MessageBox( GETRESOURCEIDSTRING( IDS_PARM_INVAL_DED_IP ),
  193. GETRESOURCEIDSTRING( IDS_PARM_ERROR ),
  194. MB_ICONSTOP | MB_OK );
  195. CPropertyPage::OnCancel();
  196. return 0;
  197. }
  198. // check if subnet is 0.0.0.0
  199. // if so ask user if he wants us to fill it or not.
  200. if( m_clusterData->hosts[m_machine].hp.hSubnetMask == _bstr_t( L"0.0.0.0") )
  201. {
  202. MessageBox( GETRESOURCEIDSTRING( IDS_PARM_DED_NM_BLANK ),
  203. GETRESOURCEIDSTRING( IDS_PARM_ERROR ),
  204. MB_ICONSTOP | MB_OK );
  205. MIPAddress::getDefaultSubnetMask( m_clusterData->hosts[m_machine].hp.hIP,
  206. m_clusterData->hosts[m_machine].hp.hSubnetMask
  207. );
  208. CommonUtils::fillCIPAddressCtrlString( subnetMask,
  209. m_clusterData->hosts[m_machine].hp.hSubnetMask );
  210. CPropertyPage::OnCancel();
  211. return 0;
  212. }
  213. // check if subnet is contiguous
  214. bool isSubnetContiguous = MIPAddress::isContiguousSubnetMask( m_clusterData->hosts[m_machine].hp.hSubnetMask );
  215. if( isSubnetContiguous == false )
  216. {
  217. MessageBox( GETRESOURCEIDSTRING( IDS_PARM_INVAL_DED_MASK ),
  218. GETRESOURCEIDSTRING( IDS_PARM_ERROR ),
  219. MB_ICONSTOP | MB_OK );
  220. CPropertyPage::OnCancel();
  221. return 0;
  222. }
  223. // check if ip address and subnet mask are valid as a pair
  224. bool isIPSubnetPairValid = MIPAddress::isValidIPAddressSubnetMaskPair( m_clusterData->hosts[m_machine].hp.hIP,
  225. m_clusterData->hosts[m_machine].hp.hSubnetMask );
  226. if( isIPSubnetPairValid == false )
  227. {
  228. MessageBox( GETRESOURCEIDSTRING( IDS_PARM_INVAL_DED_IP ),
  229. GETRESOURCEIDSTRING( IDS_PARM_ERROR ),
  230. MB_ICONSTOP | MB_OK );
  231. CPropertyPage::OnCancel();
  232. return 0;
  233. }
  234. }
  235. // Edited (mhakim 02-14-01 )
  236. //
  237. // check if dip is properly configured.
  238. //
  239. if( isDipConfiguredOK() != true )
  240. {
  241. MessageBox( GETRESOURCEIDSTRING( IDS_PARM_DIP_MISCONFIG ),
  242. GETRESOURCEIDSTRING( IDS_PARM_ERROR ),
  243. MB_ICONSTOP | MB_OK );
  244. // set the dedicated ip back to the connection ip.
  245. // and mask to derived from connection ip.
  246. //
  247. m_clusterData->hosts[m_machine].hp.hIP =
  248. m_clusterData->hosts[m_machine].connectionIP;
  249. MIPAddress::getDefaultSubnetMask( m_clusterData->hosts[m_machine].hp.hIP,
  250. m_clusterData->hosts[m_machine].hp.hSubnetMask
  251. );
  252. CommonUtils::fillCIPAddressCtrlString( ipAddress,
  253. m_clusterData->hosts[m_machine].hp.hIP );
  254. CommonUtils::fillCIPAddressCtrlString( subnetMask,
  255. m_clusterData->hosts[m_machine].hp.hSubnetMask );
  256. CPropertyPage::OnCancel();
  257. return 0;
  258. }
  259. // check if dip is non zero, it must
  260. // be present on nic selected.
  261. if( m_clusterData->hosts[m_machine].hp.hIP
  262. != _bstr_t(L"0.0.0.0") )
  263. {
  264. // check if the dip entered exists on that nic, if not display warning.
  265. if( find( m_clusterData->hosts[m_machine].hp.nicInfo.ipsOnNic.begin(),
  266. m_clusterData->hosts[m_machine].hp.nicInfo.ipsOnNic.end(),
  267. m_clusterData->hosts[m_machine].hp.hIP )
  268. ==
  269. m_clusterData->hosts[m_machine].hp.nicInfo.ipsOnNic.end() )
  270. {
  271. // the dip specified does not exist on
  272. // nic selected. Display warning.
  273. int ignoreWarning = MessageBox( GETRESOURCEIDSTRING( IDS_INVAL_DIP ),
  274. GETRESOURCEIDSTRING( IDS_PARM_WARN ),
  275. MB_ICONEXCLAMATION | MB_YESNO );
  276. if( ignoreWarning == IDNO )
  277. {
  278. CPropertyPage::OnCancel();
  279. return 0;
  280. }
  281. }
  282. }
  283. // check if nic selected is dhcp and also the connection nic.
  284. // if so this is not allowed.
  285. if( m_clusterData->hosts[m_machine].hp.nicInfo.dhcpEnabled == true )
  286. {
  287. if( find( m_clusterData->hosts[m_machine].hp.nicInfo.ipsOnNic.begin(),
  288. m_clusterData->hosts[m_machine].hp.nicInfo.ipsOnNic.end(),
  289. m_clusterData->hosts[m_machine].connectionIP )
  290. !=
  291. m_clusterData->hosts[m_machine].hp.nicInfo.ipsOnNic.end() )
  292. {
  293. // the nic selected has the connection ip.
  294. MessageBox( GETRESOURCEIDSTRING( IDS_INVAL_DHCP_NIC ),
  295. GETRESOURCEIDSTRING( IDS_PARM_ERROR ),
  296. MB_ICONSTOP | MB_OK );
  297. CPropertyPage::OnCancel();
  298. return 0;
  299. }
  300. }
  301. return CPropertyPage::OnKillActive();
  302. }
  303. void
  304. HostPage::OnSelectedNicChanged()
  305. {
  306. // do any changes if in fact
  307. // user has changed selection.
  308. // get current selection
  309. int currentSelection = nicName.GetCurSel();
  310. if( m_previousSelection == currentSelection )
  311. {
  312. // the nic is the same so no need
  313. // to do anything else.
  314. return;
  315. }
  316. m_previousSelection = currentSelection;
  317. detailedNicInfo.SetWindowText( m_nicList[currentSelection].fullNicName );
  318. if( find( m_nicList[currentSelection].ipsOnNic.begin(),
  319. m_nicList[currentSelection].ipsOnNic.end(),
  320. m_clusterData->hosts[m_machine].connectionIP )
  321. !=
  322. m_nicList[currentSelection].ipsOnNic.end() )
  323. {
  324. // this is the connection nic
  325. // make the dip the connectionIP
  326. CommonUtils::fillCIPAddressCtrlString(
  327. ipAddress,
  328. m_clusterData->hosts[m_machine].connectionIP );
  329. _bstr_t defaultConnectionIPSubnet;
  330. MIPAddress::getDefaultSubnetMask( m_clusterData->hosts[m_machine].connectionIP,
  331. defaultConnectionIPSubnet
  332. );
  333. CommonUtils::fillCIPAddressCtrlString(
  334. subnetMask,
  335. defaultConnectionIPSubnet );
  336. }
  337. else
  338. {
  339. // this is not the connection nic
  340. // make the dip blank.
  341. CommonUtils::fillCIPAddressCtrlString(
  342. ipAddress,
  343. L"0.0.0.0" );
  344. // make the subnet also blank.
  345. CommonUtils::fillCIPAddressCtrlString(
  346. subnetMask,
  347. L"0.0.0.0" );
  348. }
  349. }
  350. BOOL
  351. HostPage::OnHelpInfo (HELPINFO* helpInfo )
  352. {
  353. if( helpInfo->iContextType == HELPINFO_WINDOW )
  354. {
  355. ::WinHelp( static_cast<HWND> ( helpInfo->hItemHandle ), CVY_CTXT_HELP_FILE, HELP_WM_HELP, (ULONG_PTR ) g_aHelpIDs_IDD_HOST_PAGE);
  356. }
  357. return TRUE;
  358. }
  359. void
  360. HostPage::OnContextMenu( CWnd* pWnd, CPoint point )
  361. {
  362. ::WinHelp( m_hWnd, CVY_CTXT_HELP_FILE, HELP_CONTEXTMENU, (ULONG_PTR ) g_aHelpIDs_IDD_HOST_PAGE);
  363. }
  364. void
  365. HostPage::OnGainFocusDedicatedIP()
  366. {
  367. }
  368. void
  369. HostPage::OnGainFocusDedicatedMask()
  370. {
  371. // if dedicated ip is valid
  372. // and subnet mask is blank, then generate
  373. // the default subnet mask.
  374. _bstr_t ipAddressString = CommonUtils::getCIPAddressCtrlString( ipAddress );
  375. if( ( MIPAddress::checkIfValid( ipAddressString ) == true )
  376. &&
  377. ( subnetMask.IsBlank() == TRUE )
  378. )
  379. {
  380. _bstr_t subnetMaskString;
  381. MIPAddress::getDefaultSubnetMask( ipAddressString,
  382. subnetMaskString );
  383. CommonUtils::fillCIPAddressCtrlString( subnetMask,
  384. subnetMaskString );
  385. }
  386. }