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.

1587 lines
45 KiB

  1. //-----------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: D L G A D D R M . C P P
  7. //
  8. // Contents: Implementation of CIpsSettingPage, CAddressDialog and
  9. // CGatewayDialog
  10. //
  11. // Notes: CIpSettingsPage is the Advanced IP Addressing dialog
  12. //
  13. // Author: tongl 5 Nov 1997
  14. //
  15. //-----------------------------------------------------------------------
  16. #include "pch.h"
  17. #pragma hdrstop
  18. #include "tcpipobj.h"
  19. #include "dlgaddrm.h"
  20. #include "ncatlui.h"
  21. #include "ncstl.h"
  22. #include "resource.h"
  23. #include "tcpconst.h"
  24. #include "tcperror.h"
  25. #include "dlgaddr.h"
  26. #include "tcphelp.h"
  27. #include "tcputil.h"
  28. // CIpSettingsPage
  29. CIpSettingsPage::CIpSettingsPage(CTcpAddrPage * pTcpAddrPage,
  30. ADAPTER_INFO * pAdapterInfo,
  31. const DWORD * adwHelpIDs)
  32. {
  33. m_pParentDlg = pTcpAddrPage;
  34. Assert(pTcpAddrPage != NULL);
  35. Assert(pAdapterInfo != NULL);
  36. m_pAdapterInfo = pAdapterInfo;
  37. m_adwHelpIDs = adwHelpIDs;
  38. m_uiRemovedMetric = c_dwDefaultMetricOfGateway;
  39. // Initialize internal states
  40. m_fModified = FALSE;
  41. m_fEditState = FALSE;
  42. }
  43. CIpSettingsPage::~CIpSettingsPage()
  44. {
  45. }
  46. LRESULT CIpSettingsPage::OnInitDialog(UINT uMsg, WPARAM wParam,
  47. LPARAM lParam, BOOL & fHandled)
  48. {
  49. WCHAR szAdd[16];
  50. // Get the IP address Add and Edit button Text and remove ellipse
  51. GetDlgItemText(IDC_IPADDR_ADDIP, szAdd, celems(szAdd));
  52. szAdd[lstrlen(szAdd) - c_cchRemoveCharatersFromEditOrAddButton] = 0;
  53. m_strAdd = szAdd;
  54. // Repos the windows relative to the static text at top
  55. HWND hText = ::GetDlgItem(m_pParentDlg->m_hWnd, IDC_IPADDR_TEXT);
  56. RECT rect;
  57. if (hText)
  58. {
  59. ::GetWindowRect(hText, &rect);
  60. SetWindowPos(NULL, rect.left, rect.top-16, 0,0,
  61. SWP_NOZORDER|SWP_NOSIZE|SWP_NOACTIVATE);
  62. }
  63. m_hIpListView = GetDlgItem(IDC_IPADDR_ADVIP);
  64. LV_COLUMN lvCol; // list view column structure
  65. int index, iNewItem;
  66. // Calculate column width
  67. ::GetClientRect(m_hIpListView, &rect);
  68. int colWidth = (rect.right/c_nColumns);
  69. // The mask specifies that the fmt, width and pszText members
  70. // of the structure are valid
  71. lvCol.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT ;
  72. lvCol.fmt = LVCFMT_LEFT; // left-align column
  73. lvCol.cx = colWidth; // width of column in pixels
  74. // Add the two columns and header text.
  75. for (index = 0; index < c_nColumns; index++)
  76. {
  77. // column header text
  78. if (0==index) // first column
  79. {
  80. lvCol.pszText = (PWSTR) SzLoadIds(IDS_IPADDRESS_TEXT);
  81. }
  82. else
  83. {
  84. lvCol.pszText = (PWSTR) SzLoadIds(IDS_SUBNET_TXT);
  85. }
  86. iNewItem = ListView_InsertColumn(m_hIpListView, index, &lvCol);
  87. AssertSz((iNewItem == index), "Invalid item inserted to list view !");
  88. }
  89. // assign hwnds for controls
  90. m_hAddIp = GetDlgItem(IDC_IPADDR_ADDIP);
  91. m_hEditIp = GetDlgItem(IDC_IPADDR_EDITIP);
  92. m_hRemoveIp = GetDlgItem(IDC_IPADDR_REMOVEIP);
  93. m_hGatewayListView = GetDlgItem(IDC_IPADDR_GATE);
  94. // Calculate column width
  95. ::GetClientRect(m_hGatewayListView, &rect);
  96. colWidth = (rect.right/c_nColumns);
  97. // The mask specifies that the fmt, width and pszText members
  98. // of the structure are valid
  99. lvCol.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT ;
  100. lvCol.fmt = LVCFMT_LEFT; // left-align column
  101. lvCol.cx = colWidth; // width of column in pixels
  102. // Add the two columns and header text.
  103. for (index = 0; index < c_nColumns; index++)
  104. {
  105. // column header text
  106. if (0==index) // first column
  107. {
  108. lvCol.pszText = (PWSTR) SzLoadIds(IDS_GATEWAY_TEXT);
  109. }
  110. else
  111. {
  112. lvCol.pszText = (PWSTR) SzLoadIds(IDS_METRIC_TEXT);
  113. }
  114. iNewItem = ListView_InsertColumn(m_hGatewayListView, index, &lvCol);
  115. }
  116. m_hAddGateway = GetDlgItem(IDC_IPADDR_ADDGATE);
  117. m_hEditGateway = GetDlgItem(IDC_IPADDR_EDITGATE);
  118. m_hRemoveGateway = GetDlgItem(IDC_IPADDR_REMOVEGATE);
  119. SendDlgItemMessage(IDC_IPADDR_METRIC, EM_LIMITTEXT, MAX_METRIC_DIGITS, 0);
  120. // do this last
  121. UINT uiMetric = m_pAdapterInfo->m_dwInterfaceMetric;
  122. if (c_dwDefaultIfMetric == uiMetric)
  123. {
  124. CheckDlgButton(IDC_AUTO_METRIC, TRUE);
  125. ::EnableWindow(GetDlgItem(IDC_IPADDR_METRIC), FALSE);
  126. ::EnableWindow(GetDlgItem(IDC_STATIC_IF_METRIC), FALSE);
  127. }
  128. else
  129. {
  130. if (uiMetric > MAX_METRIC)
  131. {
  132. uiMetric = MAX_METRIC;
  133. }
  134. SetDlgItemInt(IDC_IPADDR_METRIC, uiMetric, FALSE);
  135. }
  136. SetIpInfo(); // do this before SetGatewayInfo
  137. SetIpButtons();
  138. SetGatewayInfo();
  139. SetGatewayButtons();
  140. return 0;
  141. }
  142. LRESULT CIpSettingsPage::OnContextMenu(UINT uMsg, WPARAM wParam,
  143. LPARAM lParam, BOOL& fHandled)
  144. {
  145. ShowContextHelp(m_hWnd, HELP_CONTEXTMENU, m_adwHelpIDs);
  146. return 0;
  147. }
  148. LRESULT CIpSettingsPage::OnHelp(UINT uMsg, WPARAM wParam,
  149. LPARAM lParam, BOOL& fHandled)
  150. {
  151. LPHELPINFO lphi = reinterpret_cast<LPHELPINFO>(lParam);
  152. Assert(lphi);
  153. if (HELPINFO_WINDOW == lphi->iContextType)
  154. {
  155. ShowContextHelp(static_cast<HWND>(lphi->hItemHandle), HELP_WM_HELP,
  156. m_adwHelpIDs);
  157. }
  158. return 0;
  159. }
  160. // notify handlers for the property page
  161. LRESULT CIpSettingsPage::OnActive(int idCtrl, LPNMHDR pnmh, BOOL& fHandled)
  162. {
  163. return 0;
  164. }
  165. LRESULT CIpSettingsPage::OnKillActive(int idCtrl, LPNMHDR pnmh, BOOL& fHandled)
  166. {
  167. UpdateIpList(); // update the info for the current adapter
  168. UpdateGatewayList();
  169. //Validate IP address
  170. BOOL fError = FALSE;
  171. UINT uiMetric;
  172. HWND hFocus = NULL;
  173. if (IsDlgButtonChecked(IDC_AUTO_METRIC))
  174. {
  175. if (m_pAdapterInfo->m_dwInterfaceMetric != c_dwDefaultIfMetric)
  176. {
  177. m_pAdapterInfo->m_dwInterfaceMetric = c_dwDefaultIfMetric;
  178. PageModified();
  179. }
  180. }
  181. else
  182. {
  183. uiMetric = GetDlgItemInt(IDC_IPADDR_METRIC, &fError, FALSE);
  184. if (fError && uiMetric >= 1 && uiMetric <= MAX_METRIC)
  185. {
  186. if (m_pAdapterInfo->m_dwInterfaceMetric != uiMetric)
  187. {
  188. m_pAdapterInfo->m_dwInterfaceMetric = uiMetric;
  189. PageModified();
  190. }
  191. fError = FALSE;
  192. }
  193. else
  194. {
  195. TCHAR szBuf[32] = {0};
  196. wsprintf(szBuf, L"%u", MAX_METRIC);
  197. NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_INVALID_METRIC,
  198. MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK, szBuf);
  199. hFocus = GetDlgItem(IDC_IPADDR_METRIC);
  200. fError = TRUE;
  201. }
  202. }
  203. IP_VALIDATION_ERR err = ERR_NONE;
  204. if ((err = ValidateIp(m_pAdapterInfo)) != ERR_NONE)
  205. {
  206. NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, GetIPValidationErrorMessageID(err),
  207. MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK);
  208. fError = TRUE;
  209. }
  210. if ((!fError) && (!m_pAdapterInfo->m_fEnableDhcp))
  211. {
  212. // Check ip address duplicates between this adapter and any other
  213. // enabled LAN adapters in our first memory list
  214. // same adapter
  215. if (FHasDuplicateIp(m_pAdapterInfo))
  216. {
  217. // duplicate IP address on same adapter is an error
  218. NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_DUPLICATE_IP_ERROR,
  219. MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK);
  220. fError = TRUE;
  221. }
  222. }
  223. if (fError)
  224. {
  225. SetIpInfo(); // do this before SetGatewayInfo due to cache'd data
  226. SetIpButtons();
  227. SetGatewayInfo();
  228. SetGatewayButtons();
  229. }
  230. if (fError && hFocus)
  231. {
  232. ::SetFocus(hFocus);
  233. }
  234. ::SetWindowLongPtr(m_hWnd, DWLP_MSGRESULT, fError);
  235. return fError;
  236. }
  237. LRESULT CIpSettingsPage::OnApply(int idCtrl, LPNMHDR pnmh, BOOL& fHandled)
  238. {
  239. BOOL nResult = PSNRET_NOERROR;
  240. if (!IsModified())
  241. {
  242. ::SetWindowLongPtr(m_hWnd, DWLP_MSGRESULT, nResult);
  243. return nResult;
  244. }
  245. // pass the info back to its parent dialog
  246. m_pParentDlg->m_fPropShtOk = TRUE;
  247. if(!m_pParentDlg->m_fPropShtModified)
  248. m_pParentDlg->m_fPropShtModified = IsModified();
  249. SetModifiedTo(FALSE); // this page is no longer modified
  250. ::SetWindowLongPtr(m_hWnd, DWLP_MSGRESULT, nResult);
  251. return nResult;
  252. }
  253. LRESULT CIpSettingsPage::OnCancel(int idCtrl, LPNMHDR pnmh, BOOL& fHandled)
  254. {
  255. return 0;
  256. }
  257. LRESULT CIpSettingsPage::OnQueryCancel(int idCtrl, LPNMHDR pnmh, BOOL& fHandled)
  258. {
  259. return 0;
  260. }
  261. void CIpSettingsPage::UpdateIpList()
  262. {
  263. // update the IP addresses list for the specified adapter
  264. FreeCollectionAndItem(m_pAdapterInfo->m_vstrIpAddresses);
  265. FreeCollectionAndItem(m_pAdapterInfo->m_vstrSubnetMask);
  266. if (m_pAdapterInfo->m_fEnableDhcp)
  267. {
  268. TraceTag(ttidTcpip, "[UpdateIpList] adapter %S has Dhcp enabled",
  269. m_pAdapterInfo->m_strDescription.c_str());
  270. return;
  271. }
  272. int nlvCount = ListView_GetItemCount(m_hIpListView);
  273. LV_ITEM lvItem;
  274. lvItem.mask = LVIF_TEXT;
  275. for (int j=0; j< nlvCount; j++)
  276. {
  277. WCHAR buf[IP_LIMIT];
  278. lvItem.pszText = buf;
  279. lvItem.cchTextMax = celems(buf);
  280. lvItem.iItem = j;
  281. lvItem.iSubItem = 0;
  282. ListView_GetItem(m_hIpListView, &lvItem);
  283. Assert(buf);
  284. m_pAdapterInfo->m_vstrIpAddresses.push_back(new tstring(buf));
  285. lvItem.iItem = j;
  286. lvItem.iSubItem = 1;
  287. ListView_GetItem(m_hIpListView, &lvItem);
  288. Assert(buf);
  289. m_pAdapterInfo->m_vstrSubnetMask.push_back(new tstring(buf));
  290. }
  291. }
  292. LRESULT CIpSettingsPage::OnAddIp(WORD wNotifyCode, WORD wID,
  293. HWND hWndCtl, BOOL& fHandled)
  294. {
  295. m_fEditState = FALSE;
  296. CAddressDialog * pDlgAddr = new CAddressDialog(this, g_aHelpIDs_IDD_IPADDR_ADV_CHANGEIP);
  297. if (pDlgAddr == NULL)
  298. {
  299. return(ERROR_NOT_ENOUGH_MEMORY);
  300. }
  301. pDlgAddr->m_strNewIpAddress = m_strRemovedIpAddress;
  302. pDlgAddr->m_strNewSubnetMask = m_strRemovedSubnetMask;
  303. // See if the address is added
  304. if (pDlgAddr->DoModal() == IDOK)
  305. {
  306. int nCount = ListView_GetItemCount(m_hIpListView);
  307. LV_ITEM lvItem;
  308. lvItem.mask = LVIF_TEXT | LVIF_PARAM;
  309. lvItem.lParam =0;
  310. lvItem.stateMask = LVIS_FOCUSED | LVIS_SELECTED;
  311. lvItem.state = 0;
  312. // IP address
  313. lvItem.iItem=nCount;
  314. lvItem.iSubItem=0;
  315. lvItem.pszText= (PWSTR)(pDlgAddr->m_strNewIpAddress.c_str());
  316. SendDlgItemMessage(IDC_IPADDR_ADVIP, LVM_INSERTITEM, 0, (LPARAM)&lvItem);
  317. // Subnet mask
  318. lvItem.iItem=nCount;
  319. lvItem.iSubItem=1;
  320. lvItem.pszText= (PWSTR)(pDlgAddr->m_strNewSubnetMask.c_str());
  321. SendDlgItemMessage(IDC_IPADDR_ADVIP, LVM_SETITEMTEXT, nCount, (LPARAM)&lvItem);
  322. SetIpButtons();
  323. // empty strings, this removes the saved address from RemoveIP
  324. pDlgAddr->m_strNewIpAddress = L"";
  325. pDlgAddr->m_strNewSubnetMask = L"";
  326. }
  327. m_strRemovedIpAddress = pDlgAddr->m_strNewIpAddress;
  328. m_strRemovedSubnetMask = pDlgAddr->m_strNewSubnetMask;
  329. delete pDlgAddr;
  330. return 0;
  331. }
  332. LRESULT CIpSettingsPage::OnEditIp(WORD wNotifyCode, WORD wID,
  333. HWND hWndCtl, BOOL& fHandled)
  334. {
  335. m_fEditState = TRUE;
  336. // get the user selection and allow the user to edit the ip/subnet pair
  337. int itemSelected = ListView_GetNextItem(m_hIpListView, -1, LVNI_SELECTED);
  338. CAddressDialog * pDlgAddr = new CAddressDialog(this,
  339. g_aHelpIDs_IDD_IPADDR_ADV_CHANGEIP,
  340. itemSelected);
  341. pDlgAddr->m_strNewIpAddress = m_strRemovedIpAddress;
  342. pDlgAddr->m_strNewSubnetMask = m_strRemovedSubnetMask;
  343. if (itemSelected != -1)
  344. {
  345. WCHAR buf[IP_LIMIT];
  346. // save off the removed address and delete if from the listview
  347. LV_ITEM lvItem;
  348. lvItem.mask = LVIF_TEXT;
  349. // Get IP address
  350. lvItem.iItem = itemSelected;
  351. lvItem.iSubItem = 0;
  352. lvItem.pszText = buf;
  353. lvItem.cchTextMax = celems(buf);
  354. ListView_GetItem(m_hIpListView, &lvItem);
  355. pDlgAddr->m_strNewIpAddress = buf;
  356. // Get Subnet mask
  357. lvItem.iItem = itemSelected;
  358. lvItem.iSubItem = 1;
  359. lvItem.pszText = buf;
  360. lvItem.cchTextMax = celems(buf);
  361. ListView_GetItem(m_hIpListView, &lvItem);
  362. pDlgAddr->m_strNewSubnetMask = buf;
  363. // See if the address is added
  364. if (pDlgAddr->DoModal() == IDOK)
  365. {
  366. int nCount = ListView_GetItemCount(m_hIpListView);
  367. Assert(nCount>0);
  368. LV_ITEM lvItem;
  369. lvItem.mask = LVIF_TEXT;
  370. lvItem.iItem = itemSelected;
  371. // IP address
  372. lvItem.pszText = (PWSTR) pDlgAddr->m_strNewIpAddress.c_str();
  373. lvItem.iSubItem = 0;
  374. SendDlgItemMessage(IDC_IPADDR_ADVIP, LVM_SETITEM, 0, (LPARAM)&lvItem);
  375. // Subnet mask
  376. lvItem.pszText = (PWSTR) pDlgAddr->m_strNewSubnetMask.c_str();
  377. lvItem.iSubItem = 1;
  378. SendDlgItemMessage(IDC_IPADDR_ADVIP, LVM_SETITEM, 0, (LPARAM)&lvItem);
  379. }
  380. }
  381. else
  382. {
  383. NcMsgBox(::GetActiveWindow(), IDS_MSFT_TCP_TEXT, IDS_ITEM_NOT_SELECTED,
  384. MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK);
  385. }
  386. // don't save this ip/sub pair
  387. m_strRemovedIpAddress = L"";;
  388. m_strRemovedSubnetMask = L"";;
  389. delete pDlgAddr;
  390. return 0;
  391. }
  392. LRESULT CIpSettingsPage::OnRemoveIp(WORD wNotifyCode, WORD wID,
  393. HWND hWndCtl, BOOL& fHandled)
  394. {
  395. // get the current selected item and remove it
  396. int itemSelected = ListView_GetNextItem(m_hIpListView, -1,
  397. LVNI_SELECTED);
  398. if (itemSelected != -1)
  399. {
  400. WCHAR buf[IP_LIMIT];
  401. LV_ITEM lvItem;
  402. lvItem.mask = LVIF_TEXT;
  403. lvItem.pszText = buf;
  404. lvItem.cchTextMax = celems(buf);
  405. // save off the removed address and delete it from the listview
  406. lvItem.iItem = itemSelected;
  407. lvItem.iSubItem = 0;
  408. ListView_GetItem(m_hIpListView, &lvItem);
  409. m_strRemovedIpAddress = buf;
  410. lvItem.iItem = itemSelected;
  411. lvItem.iSubItem = 1;
  412. ListView_GetItem(m_hIpListView, &lvItem);
  413. m_strRemovedSubnetMask = buf;
  414. SendDlgItemMessage(IDC_IPADDR_ADVIP, LVM_DELETEITEM,
  415. (WPARAM)itemSelected, 0);
  416. ListView_SetItemState(m_hIpListView, 0, LVIS_SELECTED,
  417. LVIS_SELECTED);
  418. SetIpButtons();
  419. PageModified();
  420. }
  421. else
  422. {
  423. NcMsgBox(::GetActiveWindow(), IDS_MSFT_TCP_TEXT,
  424. IDS_ITEM_NOT_SELECTED,
  425. MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK);
  426. }
  427. return 0;
  428. }
  429. INT CALLBACK GatewayCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lSort)
  430. {
  431. return (INT)lParam1 - (INT)lParam2;
  432. }
  433. LRESULT CIpSettingsPage::OnAddGate(WORD wNotifyCode, WORD wID,
  434. HWND hWndCtl, BOOL& fHandled)
  435. {
  436. m_fEditState = FALSE;
  437. CGatewayDialog * pDlgGate = new CGatewayDialog(this, g_aHelpIDs_IDD_IPADDR_ADV_CHANGEGATE);
  438. if (pDlgGate == NULL)
  439. {
  440. return(ERROR_NOT_ENOUGH_MEMORY);
  441. }
  442. pDlgGate->m_strNewGate = m_strRemovedGateway;
  443. pDlgGate->m_uiNewMetric = m_uiRemovedMetric;
  444. if (pDlgGate->DoModal() == IDOK)
  445. {
  446. WCHAR buf[256] = {0};
  447. LV_ITEM lvItem;
  448. int cItem = ListView_GetItemCount(m_hGatewayListView);
  449. lvItem.mask = LVIF_TEXT | LVIF_PARAM;
  450. lvItem.lParam = (LPARAM)pDlgGate->m_uiNewMetric;
  451. lvItem.stateMask = LVIS_FOCUSED | LVIS_SELECTED;
  452. lvItem.state = 0;
  453. lvItem.iItem = cItem;
  454. lvItem.iSubItem = 0;
  455. lvItem.pszText = (PWSTR)(pDlgGate->m_strNewGate.c_str());
  456. lvItem.iItem = (int)SendDlgItemMessage(IDC_IPADDR_GATE, LVM_INSERTITEM,
  457. 0, (LPARAM)&lvItem);
  458. lvItem.iSubItem=1;
  459. lvItem.pszText = buf;
  460. if (0 == lvItem.lParam)
  461. {
  462. lstrcpynW(buf, SzLoadIds(IDS_AUTO_GW_METRIC), celems(buf));
  463. }
  464. else
  465. {
  466. _ltot((INT)lvItem.lParam, buf, 10);
  467. }
  468. SendDlgItemMessage(IDC_IPADDR_GATE, LVM_SETITEMTEXT,
  469. lvItem.iItem, (LPARAM)&lvItem);
  470. ListView_SetItemState(m_hGatewayListView, lvItem.iItem, LVIS_SELECTED,
  471. LVIS_SELECTED);
  472. SetGatewayButtons();
  473. pDlgGate->m_strNewGate = L"";
  474. pDlgGate->m_uiNewMetric = c_dwDefaultMetricOfGateway;
  475. ListView_SortItems(m_hGatewayListView, GatewayCompareProc, 0);
  476. }
  477. m_strRemovedGateway = pDlgGate->m_strNewGate;
  478. m_uiRemovedMetric = pDlgGate->m_uiNewMetric;
  479. delete pDlgGate;
  480. return TRUE;
  481. }
  482. LRESULT CIpSettingsPage::OnEditGate(WORD wNotifyCode, WORD wID,
  483. HWND hWndCtl, BOOL& fHandled)
  484. {
  485. m_fEditState = TRUE;
  486. int itemSelected = ListView_GetNextItem(m_hGatewayListView, -1, LVNI_SELECTED);
  487. CGatewayDialog * pDlgGate = new CGatewayDialog(this,
  488. g_aHelpIDs_IDD_IPADDR_ADV_CHANGEGATE,
  489. itemSelected
  490. );
  491. pDlgGate->m_strNewGate = m_strRemovedGateway;
  492. pDlgGate->m_uiNewMetric = m_uiRemovedMetric;
  493. // get the user selection and allow the user to edit the ip/subnet pair
  494. if (itemSelected != -1)
  495. {
  496. WCHAR buf[256] = {0};
  497. LV_ITEM lvItem;
  498. // Get gateway
  499. lvItem.mask = LVIF_TEXT | LVIF_PARAM;
  500. lvItem.iItem = itemSelected;
  501. lvItem.iSubItem = 0;
  502. lvItem.pszText = buf;
  503. lvItem.cchTextMax = celems(buf);
  504. ListView_GetItem(m_hGatewayListView, &lvItem);
  505. pDlgGate->m_strNewGate = buf;
  506. pDlgGate->m_uiNewMetric = (UINT)lvItem.lParam;
  507. if (pDlgGate->DoModal() == IDOK)
  508. {
  509. lvItem.mask = LVIF_TEXT | LVIF_PARAM;
  510. lvItem.iItem = itemSelected;
  511. lvItem.lParam = pDlgGate->m_uiNewMetric;
  512. lvItem.iSubItem = 0;
  513. lvItem.pszText = (PWSTR) pDlgGate->m_strNewGate.c_str();
  514. SendDlgItemMessage(IDC_IPADDR_GATE, LVM_SETITEM, 0,
  515. (LPARAM)&lvItem);
  516. lvItem.iSubItem = 1;
  517. lvItem.pszText = buf;
  518. if (0 == lvItem.lParam)
  519. {
  520. lstrcpynW(buf, SzLoadIds(IDS_AUTO_GW_METRIC), celems(buf));
  521. }
  522. else
  523. {
  524. _ltot((INT)lvItem.lParam, buf, 10);
  525. }
  526. SendDlgItemMessage(IDC_IPADDR_GATE, LVM_SETITEMTEXT, itemSelected,
  527. (LPARAM)&lvItem);
  528. ListView_SetItemState(m_hGatewayListView, itemSelected,
  529. LVIS_SELECTED, LVIS_SELECTED);
  530. ListView_SortItems(m_hGatewayListView, GatewayCompareProc, 0);
  531. }
  532. }
  533. else
  534. {
  535. NcMsgBox(::GetActiveWindow(), IDS_MSFT_TCP_TEXT, IDS_ITEM_NOT_SELECTED,
  536. MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK);
  537. }
  538. // don't save this ip/sub pair
  539. m_strRemovedGateway = L"";;
  540. m_uiRemovedMetric = c_dwDefaultMetricOfGateway;
  541. delete pDlgGate;
  542. return 0;
  543. }
  544. LRESULT CIpSettingsPage::OnRemoveGate(WORD wNotifyCode, WORD wID,
  545. HWND hWndCtl, BOOL& fHandled)
  546. {
  547. // get the current selected item and remove it
  548. int itemSelected = ListView_GetNextItem(m_hGatewayListView, -1,
  549. LVNI_SELECTED);
  550. if (itemSelected != -1)
  551. {
  552. WCHAR buf[IP_LIMIT];
  553. LV_ITEM lvItem;
  554. lvItem.pszText = buf;
  555. lvItem.cchTextMax = celems(buf);
  556. // save off the removed address and delete it from the listview
  557. lvItem.mask = LVIF_TEXT;
  558. lvItem.iItem = itemSelected;
  559. lvItem.iSubItem = 0;
  560. ListView_GetItem(m_hGatewayListView, &lvItem);
  561. m_strRemovedGateway = buf;
  562. lvItem.mask = LVIF_PARAM;
  563. lvItem.iItem = itemSelected;
  564. lvItem.iSubItem = 1;
  565. ListView_GetItem(m_hGatewayListView, &lvItem);
  566. m_uiRemovedMetric = (UINT)lvItem.lParam;
  567. SendDlgItemMessage(IDC_IPADDR_GATE, LVM_DELETEITEM,
  568. (WPARAM)itemSelected, 0);
  569. ListView_SetItemState(m_hGatewayListView, 0, LVIS_SELECTED,
  570. LVIS_SELECTED);
  571. SetGatewayButtons();
  572. PageModified();
  573. }
  574. else
  575. {
  576. NcMsgBox(::GetActiveWindow(), IDS_MSFT_TCP_TEXT,
  577. IDS_ITEM_NOT_SELECTED,
  578. MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK);
  579. }
  580. return 0;
  581. }
  582. LRESULT CIpSettingsPage::OnAutoMetric(WORD wNotifyCode, WORD wID,
  583. HWND hWndCtl, BOOL& fHandled)
  584. {
  585. BOOL fEnable = FALSE;
  586. switch(wNotifyCode)
  587. {
  588. case BN_CLICKED:
  589. case BN_DOUBLECLICKED:
  590. fEnable = !IsDlgButtonChecked(IDC_AUTO_METRIC);
  591. ::EnableWindow(GetDlgItem(IDC_STATIC_IF_METRIC), fEnable);
  592. ::EnableWindow(GetDlgItem(IDC_IPADDR_METRIC), fEnable);
  593. if (!fEnable)
  594. {
  595. ::SetWindowText(GetDlgItem(IDC_IPADDR_METRIC), _T(""));
  596. }
  597. PageModified();
  598. break;
  599. }
  600. return 0;
  601. }
  602. void CIpSettingsPage::SetIpInfo()
  603. {
  604. Assert(m_hIpListView);
  605. BOOL ret = ListView_DeleteAllItems(m_hIpListView);
  606. Assert(ret);
  607. LV_ITEM lvItem;
  608. lvItem.mask = LVIF_TEXT | LVIF_PARAM;
  609. lvItem.lParam =0;
  610. lvItem.stateMask = LVIS_FOCUSED | LVIS_SELECTED;
  611. lvItem.state = 0;
  612. // if DHCP is enabled, show it in the listview
  613. if (m_pAdapterInfo->m_fEnableDhcp)
  614. {
  615. EnableIpButtons(FALSE);
  616. lvItem.iItem=0;
  617. lvItem.iSubItem=0;
  618. lvItem.pszText=(PWSTR)SzLoadIds(IDS_DHCPENABLED_TEXT);
  619. SendDlgItemMessage(IDC_IPADDR_ADVIP, LVM_INSERTITEM, 0, (LPARAM)&lvItem);
  620. }
  621. else
  622. {
  623. EnableIpButtons(TRUE);
  624. VSTR_ITER iterIpAddress = m_pAdapterInfo->m_vstrIpAddresses.begin();
  625. VSTR_ITER iterSubnetMask = m_pAdapterInfo->m_vstrSubnetMask.begin();
  626. int item=0;
  627. for(; iterIpAddress != m_pAdapterInfo->m_vstrIpAddresses.end() ;
  628. ++iterIpAddress, ++iterSubnetMask)
  629. {
  630. if(**iterIpAddress == L"")
  631. continue;
  632. // Add the IP address to the list box
  633. lvItem.iItem=item;
  634. lvItem.iSubItem=0;
  635. lvItem.pszText=(PWSTR)(*iterIpAddress)->c_str();
  636. SendDlgItemMessage(IDC_IPADDR_ADVIP, LVM_INSERTITEM,
  637. item, (LPARAM)&lvItem);
  638. // Add the subnet and increment the item
  639. tstring strSubnetMask;
  640. if (iterSubnetMask == m_pAdapterInfo->m_vstrSubnetMask.end())
  641. strSubnetMask = L"0.0.0.0";
  642. else
  643. strSubnetMask = **iterSubnetMask;
  644. lvItem.iItem=item;
  645. lvItem.iSubItem=1;
  646. lvItem.pszText=(PWSTR)strSubnetMask.c_str();
  647. SendDlgItemMessage(IDC_IPADDR_ADVIP, LVM_SETITEMTEXT,
  648. item, (LPARAM)&lvItem);
  649. ++item;
  650. }
  651. }
  652. }
  653. void CIpSettingsPage::SetIpButtons()
  654. {
  655. if (!m_pAdapterInfo->m_fEnableDhcp)
  656. {
  657. Assert(m_hRemoveIp);
  658. Assert(m_hEditIp);
  659. Assert(m_hAddIp);
  660. Assert(m_hIpListView);
  661. int nCount = ListView_GetItemCount(m_hIpListView);
  662. ::EnableWindow(m_hRemoveIp, nCount);
  663. ::EnableWindow(m_hEditIp, nCount);
  664. if (nCount == 0)
  665. {
  666. // remove the default on the remove button
  667. ::SendMessage(m_hRemoveIp, BM_SETSTYLE, (WPARAM)BS_PUSHBUTTON, TRUE );
  668. ::SetFocus(m_hIpListView);
  669. }
  670. }
  671. }
  672. void CIpSettingsPage::SetGatewayButtons()
  673. {
  674. int nCount = ListView_GetItemCount(m_hGatewayListView);
  675. ::EnableWindow(m_hAddGateway, nCount < MAX_GATEWAY);
  676. ::EnableWindow(m_hRemoveGateway, nCount);
  677. ::EnableWindow(m_hEditGateway, nCount);
  678. if (nCount == 0)
  679. {
  680. // remove the default on the remove button
  681. ::SendMessage(m_hRemoveGateway, BM_SETSTYLE, (WPARAM)BS_PUSHBUTTON, TRUE );
  682. ::SetFocus(m_hGatewayListView);
  683. }
  684. else if (nCount == MAX_GATEWAY)
  685. {
  686. ::SetFocus(m_hEditGateway);
  687. }
  688. }
  689. void CIpSettingsPage::UpdateGatewayList()
  690. {
  691. // update the gateway address list for the specified adapter
  692. FreeCollectionAndItem(m_pAdapterInfo->m_vstrDefaultGateway);
  693. FreeCollectionAndItem(m_pAdapterInfo->m_vstrDefaultGatewayMetric);
  694. int nCount = ListView_GetItemCount(m_hGatewayListView);
  695. for (int j=0; j< nCount; j++)
  696. {
  697. WCHAR buf[IP_LIMIT];
  698. LV_ITEM lvItem;
  699. lvItem.pszText = buf;
  700. lvItem.cchTextMax = celems(buf);
  701. lvItem.iItem = j;
  702. lvItem.mask = LVIF_TEXT;
  703. lvItem.iSubItem = 0;
  704. ListView_GetItem(m_hGatewayListView, &lvItem);
  705. m_pAdapterInfo->m_vstrDefaultGateway.push_back(new tstring(buf));
  706. lvItem.mask = LVIF_PARAM;
  707. lvItem.iSubItem = 1;
  708. ListView_GetItem(m_hGatewayListView, &lvItem);
  709. _ltot((INT)lvItem.lParam, buf, 10);
  710. m_pAdapterInfo->m_vstrDefaultGatewayMetric.push_back(new tstring(buf));
  711. }
  712. }
  713. void CIpSettingsPage::SetGatewayInfo()
  714. {
  715. Assert(m_hGatewayListView);
  716. BOOL ret = ListView_DeleteAllItems(m_hGatewayListView);
  717. Assert(ret);
  718. LV_ITEM lvItem;
  719. lvItem.mask = LVIF_TEXT | LVIF_PARAM;
  720. lvItem.lParam =0;
  721. lvItem.stateMask = LVIS_FOCUSED | LVIS_SELECTED;
  722. lvItem.state = 0;
  723. VSTR_ITER iterGateway = m_pAdapterInfo->m_vstrDefaultGateway.begin();
  724. VSTR_ITER iterMetric = m_pAdapterInfo->m_vstrDefaultGatewayMetric.begin();
  725. WCHAR buf[256] = {0};
  726. int cItem = 0;
  727. for(; iterGateway != m_pAdapterInfo->m_vstrDefaultGateway.end() ;
  728. ++iterGateway )
  729. {
  730. if(**iterGateway == L"")
  731. continue;
  732. lvItem.iItem=cItem;
  733. lvItem.iSubItem=0;
  734. lvItem.pszText=(PWSTR)(*iterGateway)->c_str();
  735. if (iterMetric == m_pAdapterInfo->m_vstrDefaultGatewayMetric.end())
  736. {
  737. lvItem.lParam = (LPARAM)c_dwDefaultMetricOfGateway;
  738. }
  739. else
  740. {
  741. PWSTR pszEnd;
  742. lvItem.lParam = wcstoul((*iterMetric)->c_str(), &pszEnd, 0);
  743. if (!lvItem.lParam)
  744. lvItem.lParam = (LPARAM)c_dwDefaultMetricOfGateway;
  745. ++iterMetric;
  746. }
  747. cItem = (int)SendDlgItemMessage(IDC_IPADDR_GATE, LVM_INSERTITEM,
  748. 0, (LPARAM)&lvItem);
  749. lvItem.iItem = cItem;
  750. lvItem.iSubItem=1;
  751. lvItem.pszText = buf;
  752. if (0 == lvItem.lParam)
  753. {
  754. lstrcpynW(buf, SzLoadIds(IDS_AUTO_GW_METRIC), celems(buf));
  755. }
  756. else
  757. {
  758. _ltot((INT)lvItem.lParam, buf, 10);
  759. }
  760. SendDlgItemMessage(IDC_IPADDR_GATE, LVM_SETITEMTEXT,
  761. lvItem.iItem, (LPARAM)&lvItem);
  762. cItem++;
  763. }
  764. ListView_SortItems(m_hGatewayListView, GatewayCompareProc, 0);
  765. ListView_SetItemState(m_hGatewayListView, 0, LVIS_SELECTED, LVIS_SELECTED);
  766. }
  767. void CIpSettingsPage::EnableIpButtons(BOOL fState)
  768. {
  769. Assert(m_hAddIp);
  770. Assert(m_hEditIp);
  771. Assert(m_hRemoveIp);
  772. if (m_hAddIp && m_hEditIp && m_hRemoveIp)
  773. {
  774. ::EnableWindow(m_hAddIp, fState);
  775. ::EnableWindow(m_hEditIp, fState);
  776. ::EnableWindow(m_hRemoveIp, fState);
  777. }
  778. }
  779. ////////////////////////////////////////////////////////////////////
  780. /// Add, Edit, and Remove dialog for IP address
  781. /// Dialog creation overides
  782. //
  783. // iIndex - the index of the IP address in the list view of the parent dlg
  784. // -1 if this is a new address
  785. CAddressDialog::CAddressDialog(CIpSettingsPage * pDlgAdv,
  786. const DWORD* adwHelpIDs,
  787. int iIndex)
  788. {
  789. m_pParentDlg = pDlgAdv;
  790. m_hButton = 0;
  791. m_adwHelpIDs = adwHelpIDs;
  792. m_iIndex = iIndex;
  793. }
  794. LRESULT CAddressDialog::OnInitDialog(UINT uMsg, WPARAM wParam,
  795. LPARAM lParam, BOOL& fHandled)
  796. {
  797. // replace the "Text" button with the add or edit
  798. if (m_pParentDlg->m_fEditState == FALSE)
  799. SetDlgItemText(IDOK, m_pParentDlg->m_strAdd.c_str());
  800. m_ipAddress.Create(m_hWnd,IDC_IPADDR_ADV_CHANGEIP_IP);
  801. m_ipAddress.SetFieldRange(0, c_iIPADDR_FIELD_1_LOW, c_iIPADDR_FIELD_1_HIGH);
  802. m_ipSubnetMask.Create(m_hWnd, IDC_IPADDR_ADV_CHANGEIP_SUB);
  803. // if editing an ip address fill the controls with the current information
  804. // if removing an ip address save it and fill the add dialog with it next time
  805. HWND hList = ::GetDlgItem(m_pParentDlg->m_hWnd, IDC_IPADDR_ADVIP);
  806. RECT rect;
  807. ::GetWindowRect(hList, &rect);
  808. SetWindowPos(NULL, rect.left, rect.top, 0,0,
  809. SWP_NOZORDER|SWP_NOSIZE|SWP_NOACTIVATE);
  810. m_hButton = GetDlgItem(IDOK);
  811. // add the address that was just removed
  812. if (m_strNewIpAddress.size())
  813. {
  814. m_ipAddress.SetAddress(m_strNewIpAddress.c_str());
  815. m_ipSubnetMask.SetAddress(m_strNewSubnetMask.c_str());
  816. ::EnableWindow(m_hButton, TRUE);
  817. }
  818. else
  819. {
  820. m_strNewIpAddress = L"";
  821. m_strNewSubnetMask = L"";
  822. // the ip and subnet are blank, so there's nothing to add
  823. ::EnableWindow(m_hButton, FALSE);
  824. }
  825. return 0;
  826. }
  827. LRESULT CAddressDialog::OnContextMenu(UINT uMsg, WPARAM wParam,
  828. LPARAM lParam, BOOL& fHandled)
  829. {
  830. ShowContextHelp(m_hWnd, HELP_CONTEXTMENU, m_adwHelpIDs);
  831. return 0;
  832. }
  833. LRESULT CAddressDialog::OnHelp(UINT uMsg, WPARAM wParam,
  834. LPARAM lParam, BOOL& fHandled)
  835. {
  836. LPHELPINFO lphi = reinterpret_cast<LPHELPINFO>(lParam);
  837. Assert(lphi);
  838. if (HELPINFO_WINDOW == lphi->iContextType)
  839. {
  840. ShowContextHelp(static_cast<HWND>(lphi->hItemHandle), HELP_WM_HELP,
  841. m_adwHelpIDs);
  842. }
  843. return 0;
  844. }
  845. LRESULT CAddressDialog::OnChangeIp(WORD wNotifyCode, WORD wID,
  846. HWND hWndCtl, BOOL& fHandled)
  847. {
  848. switch(wNotifyCode)
  849. {
  850. case EN_CHANGE:
  851. OnIpChange();
  852. break;
  853. case EN_SETFOCUS:
  854. OnEditSetFocus(IDC_IPADDR_ADV_CHANGEIP_IP);
  855. break;
  856. default:
  857. break;
  858. }
  859. return 0;
  860. }
  861. LRESULT CAddressDialog::OnChangeSub(WORD wNotifyCode, WORD wID,
  862. HWND hWndCtl, BOOL& fHandled)
  863. {
  864. switch(wNotifyCode)
  865. {
  866. case EN_CHANGE:
  867. OnSubnetChange();
  868. break;
  869. case EN_SETFOCUS:
  870. OnEditSetFocus(IDC_IPADDR_ADV_CHANGEIP_SUB);
  871. break;
  872. default:
  873. break;
  874. }
  875. return 0;
  876. }
  877. LRESULT CAddressDialog::OnIpFieldChange(int idCtrl, LPNMHDR pnmh,
  878. BOOL& fHandled)
  879. {
  880. LPNMIPADDRESS lpnmipa;
  881. int iLow = c_iIpLow;
  882. int iHigh = c_iIpHigh;
  883. switch(idCtrl)
  884. {
  885. case IDC_IPADDR_ADV_CHANGEIP_IP:
  886. lpnmipa = (LPNMIPADDRESS) pnmh;
  887. if (0==lpnmipa->iField)
  888. {
  889. iLow = c_iIPADDR_FIELD_1_LOW;
  890. iHigh = c_iIPADDR_FIELD_1_HIGH;
  891. };
  892. IpCheckRange(lpnmipa, m_hWnd, iLow, iHigh, TRUE);
  893. break;
  894. case IDC_IPADDR_ADV_CHANGEIP_SUB:
  895. lpnmipa = (LPNMIPADDRESS) pnmh;
  896. IpCheckRange(lpnmipa, m_hWnd, iLow, iHigh);
  897. break;
  898. default:
  899. break;
  900. }
  901. return 0;
  902. }
  903. void CAddressDialog::OnIpChange()
  904. {
  905. Assert(m_hButton);
  906. if (m_ipAddress.IsBlank())
  907. ::EnableWindow(m_hButton, FALSE);
  908. else
  909. ::EnableWindow(m_hButton, TRUE);
  910. }
  911. void CAddressDialog::OnSubnetChange()
  912. {
  913. OnIpChange();
  914. }
  915. void CAddressDialog::OnEditSetFocus(WORD nId)
  916. {
  917. if (nId != IDC_IPADDR_ADV_CHANGEIP_SUB)
  918. return;
  919. tstring strSubnetMask;
  920. tstring strIpAddress;
  921. // if the subnet mask is blank, create a mask and insert it into the control
  922. if (!m_ipAddress.IsBlank() && m_ipSubnetMask.IsBlank())
  923. {
  924. m_ipAddress.GetAddress(&strIpAddress);
  925. // generate the mask and update the control, and internal structure
  926. GenerateSubnetMask(m_ipAddress, &strSubnetMask);
  927. m_ipSubnetMask.SetAddress(strSubnetMask.c_str());
  928. }
  929. }
  930. LRESULT CAddressDialog::OnOk(WORD wNotifyCode, WORD wID,
  931. HWND hWndCtl, BOOL& fHandled)
  932. {
  933. // set the subnet Mask
  934. OnEditSetFocus(IDC_IPADDR_ADV_CHANGEIP_SUB);
  935. tstring strIp;
  936. tstring strSubnetMask;
  937. // Get the current address from the control and add them to the adapter if valid
  938. m_ipAddress.GetAddress(&strIp);
  939. m_ipSubnetMask.GetAddress(&strSubnetMask);
  940. if (!IsContiguousSubnet(strSubnetMask.c_str()))
  941. {
  942. NcMsgBox(::GetActiveWindow(),
  943. IDS_MSFT_TCP_TEXT,
  944. IDS_ERROR_UNCONTIGUOUS_SUBNET,
  945. MB_APPLMODAL | MB_ICONSTOP | MB_OK);
  946. ::SetFocus(m_ipSubnetMask);
  947. return 0;
  948. }
  949. IP_VALIDATION_ERR err = IsValidIpandSubnet(strIp.c_str(), strSubnetMask.c_str());
  950. if (ERR_NONE != err)
  951. {
  952. NcMsgBox(::GetActiveWindow(),
  953. IDS_MSFT_TCP_TEXT,
  954. GetIPValidationErrorMessageID(err),
  955. MB_APPLMODAL | MB_ICONSTOP | MB_OK);
  956. ::SetFocus(m_ipAddress);
  957. return 0;
  958. }
  959. int iIndex = SearchListViewItem(m_pParentDlg->m_hIpListView, 0, strIp.c_str());
  960. if (-1 != iIndex && iIndex != m_iIndex)
  961. {
  962. NcMsgBox(::GetActiveWindow(),
  963. IDS_MSFT_TCP_TEXT,
  964. IDS_DUP_IPADDRESS,
  965. MB_APPLMODAL | MB_ICONSTOP | MB_OK,
  966. strIp.c_str());
  967. return 0;
  968. }
  969. if (m_pParentDlg->m_fEditState == FALSE)
  970. {
  971. // Get the current address from the control and add them to the adapter if valid
  972. m_strNewIpAddress = strIp;
  973. m_strNewSubnetMask = strSubnetMask;
  974. m_pParentDlg->m_fModified = TRUE;
  975. EndDialog(IDOK);
  976. }
  977. else // see if either changed
  978. {
  979. if (strIp != m_strNewIpAddress || strSubnetMask != m_strNewSubnetMask)
  980. {
  981. m_strNewIpAddress = strIp; // update save addresses
  982. m_strNewSubnetMask = strSubnetMask;
  983. m_pParentDlg->m_fModified = TRUE;
  984. EndDialog(IDOK);
  985. }
  986. else
  987. {
  988. EndDialog(IDCANCEL);
  989. }
  990. }
  991. return 0;
  992. }
  993. LRESULT CAddressDialog::OnCancel(WORD wNotifyCode, WORD wID,
  994. HWND hWndCtl, BOOL& fHandled)
  995. {
  996. EndDialog(IDCANCEL);
  997. return 0;
  998. }
  999. //+---------------------------------------------------------------------------
  1000. //
  1001. // Purpose: Ensure the mouse cursor over the dialog is an Arrow.
  1002. //
  1003. LRESULT CAddressDialog::OnSetCursor (
  1004. UINT uMsg,
  1005. WPARAM wParam,
  1006. LPARAM lParam,
  1007. BOOL& bHandled)
  1008. {
  1009. if (LOWORD(lParam) == HTCLIENT)
  1010. {
  1011. SetCursor(LoadCursor(NULL, IDC_ARROW));
  1012. }
  1013. return 0;
  1014. }
  1015. ///////////////////////////////////////////////////////////////////////////////
  1016. /// Add, Edit, and Remove dialog for Gateway address
  1017. /// Dialog creation overides
  1018. CGatewayDialog::CGatewayDialog(CIpSettingsPage * pDlgAdv,
  1019. const DWORD* adwHelpIDs,
  1020. int iIndex) :
  1021. m_fValidMetric(TRUE),
  1022. m_iIndex (iIndex)
  1023. {
  1024. m_pParentDlg = pDlgAdv;
  1025. m_hButton = 0;
  1026. m_adwHelpIDs = adwHelpIDs;
  1027. }
  1028. LRESULT CGatewayDialog::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& fHandled)
  1029. {
  1030. // replace the "Text" button with the add or edit
  1031. // change the ok button to add if we are not editing
  1032. if (m_pParentDlg->m_fEditState == FALSE)
  1033. SetDlgItemText(IDOK, m_pParentDlg->m_strAdd.c_str());
  1034. m_ipGateAddress.Create(m_hWnd,IDC_IPADDR_ADV_CHANGE_GATEWAY);
  1035. m_ipGateAddress.SetFieldRange(0, c_iIPADDR_FIELD_1_LOW, c_iIPADDR_FIELD_1_HIGH);
  1036. SendDlgItemMessage(IDC_IPADDR_ADV_CHANGE_METRIC, EM_LIMITTEXT, MAX_METRIC_DIGITS, 0);
  1037. HWND hList = ::GetDlgItem(m_pParentDlg->m_hWnd, IDC_IPADDR_GATE);
  1038. RECT rect;
  1039. ::GetWindowRect(hList, &rect);
  1040. SetWindowPos(NULL, rect.left, rect.top, 0,0,
  1041. SWP_NOZORDER|SWP_NOSIZE|SWP_NOACTIVATE);
  1042. m_hButton = GetDlgItem(IDOK);
  1043. // add the address that was just removed
  1044. if (m_strNewGate.size())
  1045. {
  1046. m_ipGateAddress.SetAddress(m_strNewGate.c_str());
  1047. ::EnableWindow(m_hButton, TRUE);
  1048. }
  1049. else
  1050. {
  1051. m_strNewGate = L"";
  1052. ::EnableWindow(m_hButton, FALSE);
  1053. }
  1054. //initialize the metric controls
  1055. BOOL fAutoMetric = (0 == m_uiNewMetric);
  1056. CheckDlgButton(IDC_IPADDR_ADV_CHANGE_AUTOMETRIC, fAutoMetric);
  1057. if (fAutoMetric)
  1058. {
  1059. SetDlgItemText(IDC_IPADDR_ADV_CHANGE_METRIC, L"");
  1060. ::EnableWindow(GetDlgItem(IDC_IPADDR_ADV_CHANGE_METRIC), FALSE);
  1061. ::EnableWindow(GetDlgItem(IDC_IPADDR_ADV_CHANGE_METRIC_STATIC), FALSE);
  1062. }
  1063. else
  1064. {
  1065. SetDlgItemInt(IDC_IPADDR_ADV_CHANGE_METRIC, m_uiNewMetric);
  1066. }
  1067. m_fValidMetric = TRUE;
  1068. return TRUE;
  1069. }
  1070. LRESULT CGatewayDialog::OnContextMenu(UINT uMsg, WPARAM wParam,
  1071. LPARAM lParam, BOOL& fHandled)
  1072. {
  1073. ShowContextHelp(m_hWnd, HELP_CONTEXTMENU, m_adwHelpIDs);
  1074. return 0;
  1075. }
  1076. LRESULT CGatewayDialog::OnHelp(UINT uMsg, WPARAM wParam,
  1077. LPARAM lParam, BOOL& fHandled)
  1078. {
  1079. LPHELPINFO lphi = reinterpret_cast<LPHELPINFO>(lParam);
  1080. Assert(lphi);
  1081. if (HELPINFO_WINDOW == lphi->iContextType)
  1082. {
  1083. ShowContextHelp(static_cast<HWND>(lphi->hItemHandle), HELP_WM_HELP,
  1084. m_adwHelpIDs);
  1085. }
  1086. return 0;
  1087. }
  1088. LRESULT CGatewayDialog::OnGatewayChange(WORD wNotifyCode, WORD wID,
  1089. HWND hWndCtl, BOOL& fHandled)
  1090. {
  1091. switch (wNotifyCode)
  1092. {
  1093. case EN_CHANGE:
  1094. Assert(m_hButton);
  1095. if (m_ipGateAddress.IsBlank() || !m_fValidMetric)
  1096. ::EnableWindow(m_hButton, FALSE);
  1097. else
  1098. ::EnableWindow(m_hButton, TRUE);
  1099. break;
  1100. default:
  1101. break;
  1102. }
  1103. return 0;
  1104. }
  1105. LRESULT CGatewayDialog::OnMetricChange(WORD wNotifyCode, WORD wID,
  1106. HWND hWndCtl, BOOL& fHandled)
  1107. {
  1108. switch (wNotifyCode)
  1109. {
  1110. case EN_CHANGE:
  1111. if (!IsDlgButtonChecked(IDC_IPADDR_ADV_CHANGE_AUTOMETRIC))
  1112. {
  1113. BOOL bTranslated;
  1114. UINT nValue;
  1115. nValue = GetDlgItemInt(IDC_IPADDR_ADV_CHANGE_METRIC, &bTranslated,
  1116. FALSE);
  1117. m_fValidMetric = bTranslated;
  1118. if (!m_fValidMetric || m_ipGateAddress.IsBlank())
  1119. ::EnableWindow(m_hButton, FALSE);
  1120. else
  1121. ::EnableWindow(m_hButton, TRUE);
  1122. }
  1123. break;
  1124. default:
  1125. break;
  1126. }
  1127. return 0;
  1128. }
  1129. LRESULT CGatewayDialog::OnIpFieldChange(int idCtrl, LPNMHDR pnmh,
  1130. BOOL& fHandled)
  1131. {
  1132. LPNMIPADDRESS lpnmipa = (LPNMIPADDRESS) pnmh;
  1133. int iLow = c_iIpLow;
  1134. int iHigh = c_iIpHigh;
  1135. if (0==lpnmipa->iField)
  1136. {
  1137. iLow = c_iIPADDR_FIELD_1_LOW;
  1138. iHigh = c_iIPADDR_FIELD_1_HIGH;
  1139. };
  1140. IpCheckRange(lpnmipa, m_hWnd, iLow, iHigh, TRUE);
  1141. return 0;
  1142. }
  1143. LRESULT CGatewayDialog::OnOk(WORD wNotifyCode, WORD wID,
  1144. HWND hWndCtl, BOOL& fHandled)
  1145. {
  1146. tstring strGateway;
  1147. m_ipGateAddress.GetAddress(&strGateway);
  1148. // Validate
  1149. if (!FIsIpInRange(strGateway.c_str()))
  1150. {
  1151. // makes ip address lose focus so the control gets
  1152. // IPN_FIELDCHANGED notification
  1153. // also makes it consistent for when short-cut is used
  1154. ::SetFocus(m_hButton);
  1155. return 0;
  1156. }
  1157. int iIndex = -1;
  1158. iIndex = SearchListViewItem(m_pParentDlg->m_hGatewayListView, 0, strGateway.c_str());
  1159. if (-1 != iIndex && iIndex != m_iIndex)
  1160. {
  1161. NcMsgBox(::GetActiveWindow(),
  1162. IDS_MSFT_TCP_TEXT,
  1163. IDS_DUP_GATEWAY,
  1164. MB_APPLMODAL | MB_ICONSTOP | MB_OK,
  1165. strGateway.c_str());
  1166. return 0;
  1167. }
  1168. BOOL bTranslated;
  1169. UINT uiMetric = 0;
  1170. //Get the metric. If auto-metric is selected, the metric valud is 0.
  1171. //Otherwise get the metric value from the edit control
  1172. if (!IsDlgButtonChecked(IDC_IPADDR_ADV_CHANGE_AUTOMETRIC))
  1173. {
  1174. uiMetric = GetDlgItemInt(IDC_IPADDR_ADV_CHANGE_METRIC,
  1175. &bTranslated,
  1176. FALSE);
  1177. if (uiMetric < 1 || uiMetric > MAX_METRIC)
  1178. {
  1179. HWND hFocus = NULL;
  1180. TCHAR szBuf[32] = {0};
  1181. wsprintf(szBuf, L"%u", MAX_METRIC);
  1182. NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_INVALID_METRIC,
  1183. MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK, szBuf);
  1184. hFocus = GetDlgItem(IDC_IPADDR_ADV_CHANGE_METRIC);
  1185. if (hFocus)
  1186. {
  1187. ::SetFocus(hFocus);
  1188. }
  1189. return 0;
  1190. }
  1191. }
  1192. if (m_pParentDlg->m_fEditState == FALSE)
  1193. {
  1194. // Get the current address from the control and add them to the adapter if valid
  1195. m_strNewGate = strGateway;
  1196. m_uiNewMetric = uiMetric;
  1197. m_pParentDlg->m_fModified = TRUE;
  1198. EndDialog(IDOK);
  1199. }
  1200. else // see if either changed
  1201. {
  1202. if (strGateway != m_strNewGate || uiMetric != m_uiNewMetric)
  1203. {
  1204. m_pParentDlg->m_fModified = TRUE;
  1205. m_strNewGate = strGateway;
  1206. m_uiNewMetric = uiMetric;
  1207. EndDialog(IDOK);
  1208. }
  1209. else
  1210. {
  1211. EndDialog(IDCANCEL);
  1212. }
  1213. }
  1214. return 0;
  1215. }
  1216. LRESULT CGatewayDialog::OnCancel(WORD wNotifyCode, WORD wID,
  1217. HWND hWndCtl, BOOL& fHandled)
  1218. {
  1219. EndDialog(IDCANCEL);
  1220. return 0;
  1221. }
  1222. LRESULT CGatewayDialog::OnAutoMetric(WORD wNotifyCode, WORD wID,
  1223. HWND hWndCtl, BOOL& fHandled)
  1224. {
  1225. BOOL fEnable = FALSE;
  1226. BOOL bTranslated;
  1227. UINT nValue;
  1228. switch(wNotifyCode)
  1229. {
  1230. case BN_CLICKED:
  1231. case BN_DOUBLECLICKED:
  1232. fEnable = !IsDlgButtonChecked(IDC_IPADDR_ADV_CHANGE_AUTOMETRIC);
  1233. ::EnableWindow(GetDlgItem(IDC_IPADDR_ADV_CHANGE_METRIC_STATIC), fEnable);
  1234. ::EnableWindow(GetDlgItem(IDC_IPADDR_ADV_CHANGE_METRIC), fEnable);
  1235. if (!fEnable)
  1236. {
  1237. ::SetWindowText(GetDlgItem(IDC_IPADDR_ADV_CHANGE_METRIC), _T(""));
  1238. m_fValidMetric = TRUE;
  1239. }
  1240. else
  1241. {
  1242. nValue = GetDlgItemInt(IDC_IPADDR_ADV_CHANGE_METRIC, &bTranslated,
  1243. FALSE);
  1244. m_fValidMetric = bTranslated;
  1245. }
  1246. if (m_ipGateAddress.IsBlank())
  1247. {
  1248. ::EnableWindow(m_hButton, FALSE);
  1249. }
  1250. else if (!fEnable)
  1251. {
  1252. //if the ip address has been filled in and we are using auto-metric,
  1253. //enable the "OK" button
  1254. ::EnableWindow(m_hButton, TRUE);
  1255. }
  1256. else
  1257. {
  1258. //if the address has been fileed in and we are using manual metric,
  1259. //disable the "OK" button when the metric edit box doesn't contain
  1260. //valid number
  1261. ::EnableWindow(m_hButton, m_fValidMetric);
  1262. }
  1263. break;
  1264. }
  1265. return 0;
  1266. }
  1267. //+---------------------------------------------------------------------------
  1268. //
  1269. // Purpose: Ensure the mouse cursor over the dialog is an Arrow.
  1270. //
  1271. LRESULT CGatewayDialog::OnSetCursor (
  1272. UINT uMsg,
  1273. WPARAM wParam,
  1274. LPARAM lParam,
  1275. BOOL& bHandled)
  1276. {
  1277. if (LOWORD(lParam) == HTCLIENT)
  1278. {
  1279. SetCursor(LoadCursor(NULL, IDC_ARROW));
  1280. }
  1281. return 0;
  1282. }