//----------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1997. // // File: D L G A D D R M . C P P // // Contents: Implementation of CIpsSettingPage, CAddressDialog and // CGatewayDialog // // Notes: CIpSettingsPage is the Advanced IP Addressing dialog // // Author: tongl 5 Nov 1997 // //----------------------------------------------------------------------- #include "pch.h" #pragma hdrstop #include "tcpipobj.h" #include "dlgaddrm.h" #include "ncatlui.h" #include "ncstl.h" #include "resource.h" #include "tcpconst.h" #include "tcperror.h" #include "dlgaddr.h" #include "tcphelp.h" #include "tcputil.h" // CIpSettingsPage CIpSettingsPage::CIpSettingsPage(CTcpAddrPage * pTcpAddrPage, ADAPTER_INFO * pAdapterInfo, const DWORD * adwHelpIDs) { m_pParentDlg = pTcpAddrPage; Assert(pTcpAddrPage != NULL); Assert(pAdapterInfo != NULL); m_pAdapterInfo = pAdapterInfo; m_adwHelpIDs = adwHelpIDs; m_uiRemovedMetric = c_dwDefaultMetricOfGateway; // Initialize internal states m_fModified = FALSE; m_fEditState = FALSE; } CIpSettingsPage::~CIpSettingsPage() { } LRESULT CIpSettingsPage::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & fHandled) { WCHAR szAdd[16]; // Get the IP address Add and Edit button Text and remove ellipse GetDlgItemText(IDC_IPADDR_ADDIP, szAdd, celems(szAdd)); szAdd[lstrlen(szAdd) - c_cchRemoveCharatersFromEditOrAddButton] = 0; m_strAdd = szAdd; // Repos the windows relative to the static text at top HWND hText = ::GetDlgItem(m_pParentDlg->m_hWnd, IDC_IPADDR_TEXT); RECT rect; if (hText) { ::GetWindowRect(hText, &rect); SetWindowPos(NULL, rect.left, rect.top-16, 0,0, SWP_NOZORDER|SWP_NOSIZE|SWP_NOACTIVATE); } m_hIpListView = GetDlgItem(IDC_IPADDR_ADVIP); LV_COLUMN lvCol; // list view column structure int index, iNewItem; // Calculate column width ::GetClientRect(m_hIpListView, &rect); int colWidth = (rect.right/c_nColumns); // The mask specifies that the fmt, width and pszText members // of the structure are valid lvCol.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT ; lvCol.fmt = LVCFMT_LEFT; // left-align column lvCol.cx = colWidth; // width of column in pixels // Add the two columns and header text. for (index = 0; index < c_nColumns; index++) { // column header text if (0==index) // first column { lvCol.pszText = (PWSTR) SzLoadIds(IDS_IPADDRESS_TEXT); } else { lvCol.pszText = (PWSTR) SzLoadIds(IDS_SUBNET_TXT); } iNewItem = ListView_InsertColumn(m_hIpListView, index, &lvCol); AssertSz((iNewItem == index), "Invalid item inserted to list view !"); } // assign hwnds for controls m_hAddIp = GetDlgItem(IDC_IPADDR_ADDIP); m_hEditIp = GetDlgItem(IDC_IPADDR_EDITIP); m_hRemoveIp = GetDlgItem(IDC_IPADDR_REMOVEIP); m_hGatewayListView = GetDlgItem(IDC_IPADDR_GATE); // Calculate column width ::GetClientRect(m_hGatewayListView, &rect); colWidth = (rect.right/c_nColumns); // The mask specifies that the fmt, width and pszText members // of the structure are valid lvCol.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT ; lvCol.fmt = LVCFMT_LEFT; // left-align column lvCol.cx = colWidth; // width of column in pixels // Add the two columns and header text. for (index = 0; index < c_nColumns; index++) { // column header text if (0==index) // first column { lvCol.pszText = (PWSTR) SzLoadIds(IDS_GATEWAY_TEXT); } else { lvCol.pszText = (PWSTR) SzLoadIds(IDS_METRIC_TEXT); } iNewItem = ListView_InsertColumn(m_hGatewayListView, index, &lvCol); } m_hAddGateway = GetDlgItem(IDC_IPADDR_ADDGATE); m_hEditGateway = GetDlgItem(IDC_IPADDR_EDITGATE); m_hRemoveGateway = GetDlgItem(IDC_IPADDR_REMOVEGATE); SendDlgItemMessage(IDC_IPADDR_METRIC, EM_LIMITTEXT, MAX_METRIC_DIGITS, 0); // do this last UINT uiMetric = m_pAdapterInfo->m_dwInterfaceMetric; if (c_dwDefaultIfMetric == uiMetric) { CheckDlgButton(IDC_AUTO_METRIC, TRUE); ::EnableWindow(GetDlgItem(IDC_IPADDR_METRIC), FALSE); ::EnableWindow(GetDlgItem(IDC_STATIC_IF_METRIC), FALSE); } else { if (uiMetric > MAX_METRIC) { uiMetric = MAX_METRIC; } SetDlgItemInt(IDC_IPADDR_METRIC, uiMetric, FALSE); } SetIpInfo(); // do this before SetGatewayInfo SetIpButtons(); SetGatewayInfo(); SetGatewayButtons(); return 0; } LRESULT CIpSettingsPage::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& fHandled) { ShowContextHelp(m_hWnd, HELP_CONTEXTMENU, m_adwHelpIDs); return 0; } LRESULT CIpSettingsPage::OnHelp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& fHandled) { LPHELPINFO lphi = reinterpret_cast(lParam); Assert(lphi); if (HELPINFO_WINDOW == lphi->iContextType) { ShowContextHelp(static_cast(lphi->hItemHandle), HELP_WM_HELP, m_adwHelpIDs); } return 0; } // notify handlers for the property page LRESULT CIpSettingsPage::OnActive(int idCtrl, LPNMHDR pnmh, BOOL& fHandled) { return 0; } LRESULT CIpSettingsPage::OnKillActive(int idCtrl, LPNMHDR pnmh, BOOL& fHandled) { UpdateIpList(); // update the info for the current adapter UpdateGatewayList(); //Validate IP address BOOL fError = FALSE; UINT uiMetric; HWND hFocus = NULL; if (IsDlgButtonChecked(IDC_AUTO_METRIC)) { if (m_pAdapterInfo->m_dwInterfaceMetric != c_dwDefaultIfMetric) { m_pAdapterInfo->m_dwInterfaceMetric = c_dwDefaultIfMetric; PageModified(); } } else { uiMetric = GetDlgItemInt(IDC_IPADDR_METRIC, &fError, FALSE); if (fError && uiMetric >= 1 && uiMetric <= MAX_METRIC) { if (m_pAdapterInfo->m_dwInterfaceMetric != uiMetric) { m_pAdapterInfo->m_dwInterfaceMetric = uiMetric; PageModified(); } fError = FALSE; } else { TCHAR szBuf[32] = {0}; wsprintf(szBuf, L"%u", MAX_METRIC); NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_INVALID_METRIC, MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK, szBuf); hFocus = GetDlgItem(IDC_IPADDR_METRIC); fError = TRUE; } } IP_VALIDATION_ERR err = ERR_NONE; if ((err = ValidateIp(m_pAdapterInfo)) != ERR_NONE) { NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, GetIPValidationErrorMessageID(err), MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK); fError = TRUE; } if ((!fError) && (!m_pAdapterInfo->m_fEnableDhcp)) { // Check ip address duplicates between this adapter and any other // enabled LAN adapters in our first memory list // same adapter if (FHasDuplicateIp(m_pAdapterInfo)) { // duplicate IP address on same adapter is an error NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_DUPLICATE_IP_ERROR, MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK); fError = TRUE; } } if (fError) { SetIpInfo(); // do this before SetGatewayInfo due to cache'd data SetIpButtons(); SetGatewayInfo(); SetGatewayButtons(); } if (fError && hFocus) { ::SetFocus(hFocus); } ::SetWindowLongPtr(m_hWnd, DWLP_MSGRESULT, fError); return fError; } LRESULT CIpSettingsPage::OnApply(int idCtrl, LPNMHDR pnmh, BOOL& fHandled) { BOOL nResult = PSNRET_NOERROR; if (!IsModified()) { ::SetWindowLongPtr(m_hWnd, DWLP_MSGRESULT, nResult); return nResult; } // pass the info back to its parent dialog m_pParentDlg->m_fPropShtOk = TRUE; if(!m_pParentDlg->m_fPropShtModified) m_pParentDlg->m_fPropShtModified = IsModified(); SetModifiedTo(FALSE); // this page is no longer modified ::SetWindowLongPtr(m_hWnd, DWLP_MSGRESULT, nResult); return nResult; } LRESULT CIpSettingsPage::OnCancel(int idCtrl, LPNMHDR pnmh, BOOL& fHandled) { return 0; } LRESULT CIpSettingsPage::OnQueryCancel(int idCtrl, LPNMHDR pnmh, BOOL& fHandled) { return 0; } void CIpSettingsPage::UpdateIpList() { // update the IP addresses list for the specified adapter FreeCollectionAndItem(m_pAdapterInfo->m_vstrIpAddresses); FreeCollectionAndItem(m_pAdapterInfo->m_vstrSubnetMask); if (m_pAdapterInfo->m_fEnableDhcp) { TraceTag(ttidTcpip, "[UpdateIpList] adapter %S has Dhcp enabled", m_pAdapterInfo->m_strDescription.c_str()); return; } int nlvCount = ListView_GetItemCount(m_hIpListView); LV_ITEM lvItem; lvItem.mask = LVIF_TEXT; for (int j=0; j< nlvCount; j++) { WCHAR buf[IP_LIMIT]; lvItem.pszText = buf; lvItem.cchTextMax = celems(buf); lvItem.iItem = j; lvItem.iSubItem = 0; ListView_GetItem(m_hIpListView, &lvItem); Assert(buf); m_pAdapterInfo->m_vstrIpAddresses.push_back(new tstring(buf)); lvItem.iItem = j; lvItem.iSubItem = 1; ListView_GetItem(m_hIpListView, &lvItem); Assert(buf); m_pAdapterInfo->m_vstrSubnetMask.push_back(new tstring(buf)); } } LRESULT CIpSettingsPage::OnAddIp(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled) { m_fEditState = FALSE; CAddressDialog * pDlgAddr = new CAddressDialog(this, g_aHelpIDs_IDD_IPADDR_ADV_CHANGEIP); if (pDlgAddr == NULL) { return(ERROR_NOT_ENOUGH_MEMORY); } pDlgAddr->m_strNewIpAddress = m_strRemovedIpAddress; pDlgAddr->m_strNewSubnetMask = m_strRemovedSubnetMask; // See if the address is added if (pDlgAddr->DoModal() == IDOK) { int nCount = ListView_GetItemCount(m_hIpListView); LV_ITEM lvItem; lvItem.mask = LVIF_TEXT | LVIF_PARAM; lvItem.lParam =0; lvItem.stateMask = LVIS_FOCUSED | LVIS_SELECTED; lvItem.state = 0; // IP address lvItem.iItem=nCount; lvItem.iSubItem=0; lvItem.pszText= (PWSTR)(pDlgAddr->m_strNewIpAddress.c_str()); SendDlgItemMessage(IDC_IPADDR_ADVIP, LVM_INSERTITEM, 0, (LPARAM)&lvItem); // Subnet mask lvItem.iItem=nCount; lvItem.iSubItem=1; lvItem.pszText= (PWSTR)(pDlgAddr->m_strNewSubnetMask.c_str()); SendDlgItemMessage(IDC_IPADDR_ADVIP, LVM_SETITEMTEXT, nCount, (LPARAM)&lvItem); SetIpButtons(); // empty strings, this removes the saved address from RemoveIP pDlgAddr->m_strNewIpAddress = L""; pDlgAddr->m_strNewSubnetMask = L""; } m_strRemovedIpAddress = pDlgAddr->m_strNewIpAddress; m_strRemovedSubnetMask = pDlgAddr->m_strNewSubnetMask; delete pDlgAddr; return 0; } LRESULT CIpSettingsPage::OnEditIp(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled) { m_fEditState = TRUE; // get the user selection and allow the user to edit the ip/subnet pair int itemSelected = ListView_GetNextItem(m_hIpListView, -1, LVNI_SELECTED); CAddressDialog * pDlgAddr = new CAddressDialog(this, g_aHelpIDs_IDD_IPADDR_ADV_CHANGEIP, itemSelected); pDlgAddr->m_strNewIpAddress = m_strRemovedIpAddress; pDlgAddr->m_strNewSubnetMask = m_strRemovedSubnetMask; if (itemSelected != -1) { WCHAR buf[IP_LIMIT]; // save off the removed address and delete if from the listview LV_ITEM lvItem; lvItem.mask = LVIF_TEXT; // Get IP address lvItem.iItem = itemSelected; lvItem.iSubItem = 0; lvItem.pszText = buf; lvItem.cchTextMax = celems(buf); ListView_GetItem(m_hIpListView, &lvItem); pDlgAddr->m_strNewIpAddress = buf; // Get Subnet mask lvItem.iItem = itemSelected; lvItem.iSubItem = 1; lvItem.pszText = buf; lvItem.cchTextMax = celems(buf); ListView_GetItem(m_hIpListView, &lvItem); pDlgAddr->m_strNewSubnetMask = buf; // See if the address is added if (pDlgAddr->DoModal() == IDOK) { int nCount = ListView_GetItemCount(m_hIpListView); Assert(nCount>0); LV_ITEM lvItem; lvItem.mask = LVIF_TEXT; lvItem.iItem = itemSelected; // IP address lvItem.pszText = (PWSTR) pDlgAddr->m_strNewIpAddress.c_str(); lvItem.iSubItem = 0; SendDlgItemMessage(IDC_IPADDR_ADVIP, LVM_SETITEM, 0, (LPARAM)&lvItem); // Subnet mask lvItem.pszText = (PWSTR) pDlgAddr->m_strNewSubnetMask.c_str(); lvItem.iSubItem = 1; SendDlgItemMessage(IDC_IPADDR_ADVIP, LVM_SETITEM, 0, (LPARAM)&lvItem); } } else { NcMsgBox(::GetActiveWindow(), IDS_MSFT_TCP_TEXT, IDS_ITEM_NOT_SELECTED, MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK); } // don't save this ip/sub pair m_strRemovedIpAddress = L"";; m_strRemovedSubnetMask = L"";; delete pDlgAddr; return 0; } LRESULT CIpSettingsPage::OnRemoveIp(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled) { // get the current selected item and remove it int itemSelected = ListView_GetNextItem(m_hIpListView, -1, LVNI_SELECTED); if (itemSelected != -1) { WCHAR buf[IP_LIMIT]; LV_ITEM lvItem; lvItem.mask = LVIF_TEXT; lvItem.pszText = buf; lvItem.cchTextMax = celems(buf); // save off the removed address and delete it from the listview lvItem.iItem = itemSelected; lvItem.iSubItem = 0; ListView_GetItem(m_hIpListView, &lvItem); m_strRemovedIpAddress = buf; lvItem.iItem = itemSelected; lvItem.iSubItem = 1; ListView_GetItem(m_hIpListView, &lvItem); m_strRemovedSubnetMask = buf; SendDlgItemMessage(IDC_IPADDR_ADVIP, LVM_DELETEITEM, (WPARAM)itemSelected, 0); ListView_SetItemState(m_hIpListView, 0, LVIS_SELECTED, LVIS_SELECTED); SetIpButtons(); PageModified(); } else { NcMsgBox(::GetActiveWindow(), IDS_MSFT_TCP_TEXT, IDS_ITEM_NOT_SELECTED, MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK); } return 0; } INT CALLBACK GatewayCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lSort) { return (INT)lParam1 - (INT)lParam2; } LRESULT CIpSettingsPage::OnAddGate(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled) { m_fEditState = FALSE; CGatewayDialog * pDlgGate = new CGatewayDialog(this, g_aHelpIDs_IDD_IPADDR_ADV_CHANGEGATE); if (pDlgGate == NULL) { return(ERROR_NOT_ENOUGH_MEMORY); } pDlgGate->m_strNewGate = m_strRemovedGateway; pDlgGate->m_uiNewMetric = m_uiRemovedMetric; if (pDlgGate->DoModal() == IDOK) { WCHAR buf[256] = {0}; LV_ITEM lvItem; int cItem = ListView_GetItemCount(m_hGatewayListView); lvItem.mask = LVIF_TEXT | LVIF_PARAM; lvItem.lParam = (LPARAM)pDlgGate->m_uiNewMetric; lvItem.stateMask = LVIS_FOCUSED | LVIS_SELECTED; lvItem.state = 0; lvItem.iItem = cItem; lvItem.iSubItem = 0; lvItem.pszText = (PWSTR)(pDlgGate->m_strNewGate.c_str()); lvItem.iItem = (int)SendDlgItemMessage(IDC_IPADDR_GATE, LVM_INSERTITEM, 0, (LPARAM)&lvItem); lvItem.iSubItem=1; lvItem.pszText = buf; if (0 == lvItem.lParam) { lstrcpynW(buf, SzLoadIds(IDS_AUTO_GW_METRIC), celems(buf)); } else { _ltot((INT)lvItem.lParam, buf, 10); } SendDlgItemMessage(IDC_IPADDR_GATE, LVM_SETITEMTEXT, lvItem.iItem, (LPARAM)&lvItem); ListView_SetItemState(m_hGatewayListView, lvItem.iItem, LVIS_SELECTED, LVIS_SELECTED); SetGatewayButtons(); pDlgGate->m_strNewGate = L""; pDlgGate->m_uiNewMetric = c_dwDefaultMetricOfGateway; ListView_SortItems(m_hGatewayListView, GatewayCompareProc, 0); } m_strRemovedGateway = pDlgGate->m_strNewGate; m_uiRemovedMetric = pDlgGate->m_uiNewMetric; delete pDlgGate; return TRUE; } LRESULT CIpSettingsPage::OnEditGate(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled) { m_fEditState = TRUE; int itemSelected = ListView_GetNextItem(m_hGatewayListView, -1, LVNI_SELECTED); CGatewayDialog * pDlgGate = new CGatewayDialog(this, g_aHelpIDs_IDD_IPADDR_ADV_CHANGEGATE, itemSelected ); pDlgGate->m_strNewGate = m_strRemovedGateway; pDlgGate->m_uiNewMetric = m_uiRemovedMetric; // get the user selection and allow the user to edit the ip/subnet pair if (itemSelected != -1) { WCHAR buf[256] = {0}; LV_ITEM lvItem; // Get gateway lvItem.mask = LVIF_TEXT | LVIF_PARAM; lvItem.iItem = itemSelected; lvItem.iSubItem = 0; lvItem.pszText = buf; lvItem.cchTextMax = celems(buf); ListView_GetItem(m_hGatewayListView, &lvItem); pDlgGate->m_strNewGate = buf; pDlgGate->m_uiNewMetric = (UINT)lvItem.lParam; if (pDlgGate->DoModal() == IDOK) { lvItem.mask = LVIF_TEXT | LVIF_PARAM; lvItem.iItem = itemSelected; lvItem.lParam = pDlgGate->m_uiNewMetric; lvItem.iSubItem = 0; lvItem.pszText = (PWSTR) pDlgGate->m_strNewGate.c_str(); SendDlgItemMessage(IDC_IPADDR_GATE, LVM_SETITEM, 0, (LPARAM)&lvItem); lvItem.iSubItem = 1; lvItem.pszText = buf; if (0 == lvItem.lParam) { lstrcpynW(buf, SzLoadIds(IDS_AUTO_GW_METRIC), celems(buf)); } else { _ltot((INT)lvItem.lParam, buf, 10); } SendDlgItemMessage(IDC_IPADDR_GATE, LVM_SETITEMTEXT, itemSelected, (LPARAM)&lvItem); ListView_SetItemState(m_hGatewayListView, itemSelected, LVIS_SELECTED, LVIS_SELECTED); ListView_SortItems(m_hGatewayListView, GatewayCompareProc, 0); } } else { NcMsgBox(::GetActiveWindow(), IDS_MSFT_TCP_TEXT, IDS_ITEM_NOT_SELECTED, MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK); } // don't save this ip/sub pair m_strRemovedGateway = L"";; m_uiRemovedMetric = c_dwDefaultMetricOfGateway; delete pDlgGate; return 0; } LRESULT CIpSettingsPage::OnRemoveGate(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled) { // get the current selected item and remove it int itemSelected = ListView_GetNextItem(m_hGatewayListView, -1, LVNI_SELECTED); if (itemSelected != -1) { WCHAR buf[IP_LIMIT]; LV_ITEM lvItem; lvItem.pszText = buf; lvItem.cchTextMax = celems(buf); // save off the removed address and delete it from the listview lvItem.mask = LVIF_TEXT; lvItem.iItem = itemSelected; lvItem.iSubItem = 0; ListView_GetItem(m_hGatewayListView, &lvItem); m_strRemovedGateway = buf; lvItem.mask = LVIF_PARAM; lvItem.iItem = itemSelected; lvItem.iSubItem = 1; ListView_GetItem(m_hGatewayListView, &lvItem); m_uiRemovedMetric = (UINT)lvItem.lParam; SendDlgItemMessage(IDC_IPADDR_GATE, LVM_DELETEITEM, (WPARAM)itemSelected, 0); ListView_SetItemState(m_hGatewayListView, 0, LVIS_SELECTED, LVIS_SELECTED); SetGatewayButtons(); PageModified(); } else { NcMsgBox(::GetActiveWindow(), IDS_MSFT_TCP_TEXT, IDS_ITEM_NOT_SELECTED, MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK); } return 0; } LRESULT CIpSettingsPage::OnAutoMetric(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled) { BOOL fEnable = FALSE; switch(wNotifyCode) { case BN_CLICKED: case BN_DOUBLECLICKED: fEnable = !IsDlgButtonChecked(IDC_AUTO_METRIC); ::EnableWindow(GetDlgItem(IDC_STATIC_IF_METRIC), fEnable); ::EnableWindow(GetDlgItem(IDC_IPADDR_METRIC), fEnable); if (!fEnable) { ::SetWindowText(GetDlgItem(IDC_IPADDR_METRIC), _T("")); } PageModified(); break; } return 0; } void CIpSettingsPage::SetIpInfo() { Assert(m_hIpListView); BOOL ret = ListView_DeleteAllItems(m_hIpListView); Assert(ret); LV_ITEM lvItem; lvItem.mask = LVIF_TEXT | LVIF_PARAM; lvItem.lParam =0; lvItem.stateMask = LVIS_FOCUSED | LVIS_SELECTED; lvItem.state = 0; // if DHCP is enabled, show it in the listview if (m_pAdapterInfo->m_fEnableDhcp) { EnableIpButtons(FALSE); lvItem.iItem=0; lvItem.iSubItem=0; lvItem.pszText=(PWSTR)SzLoadIds(IDS_DHCPENABLED_TEXT); SendDlgItemMessage(IDC_IPADDR_ADVIP, LVM_INSERTITEM, 0, (LPARAM)&lvItem); } else { EnableIpButtons(TRUE); VSTR_ITER iterIpAddress = m_pAdapterInfo->m_vstrIpAddresses.begin(); VSTR_ITER iterSubnetMask = m_pAdapterInfo->m_vstrSubnetMask.begin(); int item=0; for(; iterIpAddress != m_pAdapterInfo->m_vstrIpAddresses.end() ; ++iterIpAddress, ++iterSubnetMask) { if(**iterIpAddress == L"") continue; // Add the IP address to the list box lvItem.iItem=item; lvItem.iSubItem=0; lvItem.pszText=(PWSTR)(*iterIpAddress)->c_str(); SendDlgItemMessage(IDC_IPADDR_ADVIP, LVM_INSERTITEM, item, (LPARAM)&lvItem); // Add the subnet and increment the item tstring strSubnetMask; if (iterSubnetMask == m_pAdapterInfo->m_vstrSubnetMask.end()) strSubnetMask = L"0.0.0.0"; else strSubnetMask = **iterSubnetMask; lvItem.iItem=item; lvItem.iSubItem=1; lvItem.pszText=(PWSTR)strSubnetMask.c_str(); SendDlgItemMessage(IDC_IPADDR_ADVIP, LVM_SETITEMTEXT, item, (LPARAM)&lvItem); ++item; } } } void CIpSettingsPage::SetIpButtons() { if (!m_pAdapterInfo->m_fEnableDhcp) { Assert(m_hRemoveIp); Assert(m_hEditIp); Assert(m_hAddIp); Assert(m_hIpListView); int nCount = ListView_GetItemCount(m_hIpListView); ::EnableWindow(m_hRemoveIp, nCount); ::EnableWindow(m_hEditIp, nCount); if (nCount == 0) { // remove the default on the remove button ::SendMessage(m_hRemoveIp, BM_SETSTYLE, (WPARAM)BS_PUSHBUTTON, TRUE ); ::SetFocus(m_hIpListView); } } } void CIpSettingsPage::SetGatewayButtons() { int nCount = ListView_GetItemCount(m_hGatewayListView); ::EnableWindow(m_hAddGateway, nCount < MAX_GATEWAY); ::EnableWindow(m_hRemoveGateway, nCount); ::EnableWindow(m_hEditGateway, nCount); if (nCount == 0) { // remove the default on the remove button ::SendMessage(m_hRemoveGateway, BM_SETSTYLE, (WPARAM)BS_PUSHBUTTON, TRUE ); ::SetFocus(m_hGatewayListView); } else if (nCount == MAX_GATEWAY) { ::SetFocus(m_hEditGateway); } } void CIpSettingsPage::UpdateGatewayList() { // update the gateway address list for the specified adapter FreeCollectionAndItem(m_pAdapterInfo->m_vstrDefaultGateway); FreeCollectionAndItem(m_pAdapterInfo->m_vstrDefaultGatewayMetric); int nCount = ListView_GetItemCount(m_hGatewayListView); for (int j=0; j< nCount; j++) { WCHAR buf[IP_LIMIT]; LV_ITEM lvItem; lvItem.pszText = buf; lvItem.cchTextMax = celems(buf); lvItem.iItem = j; lvItem.mask = LVIF_TEXT; lvItem.iSubItem = 0; ListView_GetItem(m_hGatewayListView, &lvItem); m_pAdapterInfo->m_vstrDefaultGateway.push_back(new tstring(buf)); lvItem.mask = LVIF_PARAM; lvItem.iSubItem = 1; ListView_GetItem(m_hGatewayListView, &lvItem); _ltot((INT)lvItem.lParam, buf, 10); m_pAdapterInfo->m_vstrDefaultGatewayMetric.push_back(new tstring(buf)); } } void CIpSettingsPage::SetGatewayInfo() { Assert(m_hGatewayListView); BOOL ret = ListView_DeleteAllItems(m_hGatewayListView); Assert(ret); LV_ITEM lvItem; lvItem.mask = LVIF_TEXT | LVIF_PARAM; lvItem.lParam =0; lvItem.stateMask = LVIS_FOCUSED | LVIS_SELECTED; lvItem.state = 0; VSTR_ITER iterGateway = m_pAdapterInfo->m_vstrDefaultGateway.begin(); VSTR_ITER iterMetric = m_pAdapterInfo->m_vstrDefaultGatewayMetric.begin(); WCHAR buf[256] = {0}; int cItem = 0; for(; iterGateway != m_pAdapterInfo->m_vstrDefaultGateway.end() ; ++iterGateway ) { if(**iterGateway == L"") continue; lvItem.iItem=cItem; lvItem.iSubItem=0; lvItem.pszText=(PWSTR)(*iterGateway)->c_str(); if (iterMetric == m_pAdapterInfo->m_vstrDefaultGatewayMetric.end()) { lvItem.lParam = (LPARAM)c_dwDefaultMetricOfGateway; } else { PWSTR pszEnd; lvItem.lParam = wcstoul((*iterMetric)->c_str(), &pszEnd, 0); if (!lvItem.lParam) lvItem.lParam = (LPARAM)c_dwDefaultMetricOfGateway; ++iterMetric; } cItem = (int)SendDlgItemMessage(IDC_IPADDR_GATE, LVM_INSERTITEM, 0, (LPARAM)&lvItem); lvItem.iItem = cItem; lvItem.iSubItem=1; lvItem.pszText = buf; if (0 == lvItem.lParam) { lstrcpynW(buf, SzLoadIds(IDS_AUTO_GW_METRIC), celems(buf)); } else { _ltot((INT)lvItem.lParam, buf, 10); } SendDlgItemMessage(IDC_IPADDR_GATE, LVM_SETITEMTEXT, lvItem.iItem, (LPARAM)&lvItem); cItem++; } ListView_SortItems(m_hGatewayListView, GatewayCompareProc, 0); ListView_SetItemState(m_hGatewayListView, 0, LVIS_SELECTED, LVIS_SELECTED); } void CIpSettingsPage::EnableIpButtons(BOOL fState) { Assert(m_hAddIp); Assert(m_hEditIp); Assert(m_hRemoveIp); if (m_hAddIp && m_hEditIp && m_hRemoveIp) { ::EnableWindow(m_hAddIp, fState); ::EnableWindow(m_hEditIp, fState); ::EnableWindow(m_hRemoveIp, fState); } } //////////////////////////////////////////////////////////////////// /// Add, Edit, and Remove dialog for IP address /// Dialog creation overides // // iIndex - the index of the IP address in the list view of the parent dlg // -1 if this is a new address CAddressDialog::CAddressDialog(CIpSettingsPage * pDlgAdv, const DWORD* adwHelpIDs, int iIndex) { m_pParentDlg = pDlgAdv; m_hButton = 0; m_adwHelpIDs = adwHelpIDs; m_iIndex = iIndex; } LRESULT CAddressDialog::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& fHandled) { // replace the "Text" button with the add or edit if (m_pParentDlg->m_fEditState == FALSE) SetDlgItemText(IDOK, m_pParentDlg->m_strAdd.c_str()); m_ipAddress.Create(m_hWnd,IDC_IPADDR_ADV_CHANGEIP_IP); m_ipAddress.SetFieldRange(0, c_iIPADDR_FIELD_1_LOW, c_iIPADDR_FIELD_1_HIGH); m_ipSubnetMask.Create(m_hWnd, IDC_IPADDR_ADV_CHANGEIP_SUB); // if editing an ip address fill the controls with the current information // if removing an ip address save it and fill the add dialog with it next time HWND hList = ::GetDlgItem(m_pParentDlg->m_hWnd, IDC_IPADDR_ADVIP); RECT rect; ::GetWindowRect(hList, &rect); SetWindowPos(NULL, rect.left, rect.top, 0,0, SWP_NOZORDER|SWP_NOSIZE|SWP_NOACTIVATE); m_hButton = GetDlgItem(IDOK); // add the address that was just removed if (m_strNewIpAddress.size()) { m_ipAddress.SetAddress(m_strNewIpAddress.c_str()); m_ipSubnetMask.SetAddress(m_strNewSubnetMask.c_str()); ::EnableWindow(m_hButton, TRUE); } else { m_strNewIpAddress = L""; m_strNewSubnetMask = L""; // the ip and subnet are blank, so there's nothing to add ::EnableWindow(m_hButton, FALSE); } return 0; } LRESULT CAddressDialog::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& fHandled) { ShowContextHelp(m_hWnd, HELP_CONTEXTMENU, m_adwHelpIDs); return 0; } LRESULT CAddressDialog::OnHelp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& fHandled) { LPHELPINFO lphi = reinterpret_cast(lParam); Assert(lphi); if (HELPINFO_WINDOW == lphi->iContextType) { ShowContextHelp(static_cast(lphi->hItemHandle), HELP_WM_HELP, m_adwHelpIDs); } return 0; } LRESULT CAddressDialog::OnChangeIp(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled) { switch(wNotifyCode) { case EN_CHANGE: OnIpChange(); break; case EN_SETFOCUS: OnEditSetFocus(IDC_IPADDR_ADV_CHANGEIP_IP); break; default: break; } return 0; } LRESULT CAddressDialog::OnChangeSub(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled) { switch(wNotifyCode) { case EN_CHANGE: OnSubnetChange(); break; case EN_SETFOCUS: OnEditSetFocus(IDC_IPADDR_ADV_CHANGEIP_SUB); break; default: break; } return 0; } LRESULT CAddressDialog::OnIpFieldChange(int idCtrl, LPNMHDR pnmh, BOOL& fHandled) { LPNMIPADDRESS lpnmipa; int iLow = c_iIpLow; int iHigh = c_iIpHigh; switch(idCtrl) { case IDC_IPADDR_ADV_CHANGEIP_IP: lpnmipa = (LPNMIPADDRESS) pnmh; if (0==lpnmipa->iField) { iLow = c_iIPADDR_FIELD_1_LOW; iHigh = c_iIPADDR_FIELD_1_HIGH; }; IpCheckRange(lpnmipa, m_hWnd, iLow, iHigh, TRUE); break; case IDC_IPADDR_ADV_CHANGEIP_SUB: lpnmipa = (LPNMIPADDRESS) pnmh; IpCheckRange(lpnmipa, m_hWnd, iLow, iHigh); break; default: break; } return 0; } void CAddressDialog::OnIpChange() { Assert(m_hButton); if (m_ipAddress.IsBlank()) ::EnableWindow(m_hButton, FALSE); else ::EnableWindow(m_hButton, TRUE); } void CAddressDialog::OnSubnetChange() { OnIpChange(); } void CAddressDialog::OnEditSetFocus(WORD nId) { if (nId != IDC_IPADDR_ADV_CHANGEIP_SUB) return; tstring strSubnetMask; tstring strIpAddress; // if the subnet mask is blank, create a mask and insert it into the control if (!m_ipAddress.IsBlank() && m_ipSubnetMask.IsBlank()) { m_ipAddress.GetAddress(&strIpAddress); // generate the mask and update the control, and internal structure GenerateSubnetMask(m_ipAddress, &strSubnetMask); m_ipSubnetMask.SetAddress(strSubnetMask.c_str()); } } LRESULT CAddressDialog::OnOk(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled) { // set the subnet Mask OnEditSetFocus(IDC_IPADDR_ADV_CHANGEIP_SUB); tstring strIp; tstring strSubnetMask; // Get the current address from the control and add them to the adapter if valid m_ipAddress.GetAddress(&strIp); m_ipSubnetMask.GetAddress(&strSubnetMask); if (!IsContiguousSubnet(strSubnetMask.c_str())) { NcMsgBox(::GetActiveWindow(), IDS_MSFT_TCP_TEXT, IDS_ERROR_UNCONTIGUOUS_SUBNET, MB_APPLMODAL | MB_ICONSTOP | MB_OK); ::SetFocus(m_ipSubnetMask); return 0; } IP_VALIDATION_ERR err = IsValidIpandSubnet(strIp.c_str(), strSubnetMask.c_str()); if (ERR_NONE != err) { NcMsgBox(::GetActiveWindow(), IDS_MSFT_TCP_TEXT, GetIPValidationErrorMessageID(err), MB_APPLMODAL | MB_ICONSTOP | MB_OK); ::SetFocus(m_ipAddress); return 0; } int iIndex = SearchListViewItem(m_pParentDlg->m_hIpListView, 0, strIp.c_str()); if (-1 != iIndex && iIndex != m_iIndex) { NcMsgBox(::GetActiveWindow(), IDS_MSFT_TCP_TEXT, IDS_DUP_IPADDRESS, MB_APPLMODAL | MB_ICONSTOP | MB_OK, strIp.c_str()); return 0; } if (m_pParentDlg->m_fEditState == FALSE) { // Get the current address from the control and add them to the adapter if valid m_strNewIpAddress = strIp; m_strNewSubnetMask = strSubnetMask; m_pParentDlg->m_fModified = TRUE; EndDialog(IDOK); } else // see if either changed { if (strIp != m_strNewIpAddress || strSubnetMask != m_strNewSubnetMask) { m_strNewIpAddress = strIp; // update save addresses m_strNewSubnetMask = strSubnetMask; m_pParentDlg->m_fModified = TRUE; EndDialog(IDOK); } else { EndDialog(IDCANCEL); } } return 0; } LRESULT CAddressDialog::OnCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled) { EndDialog(IDCANCEL); return 0; } //+--------------------------------------------------------------------------- // // Purpose: Ensure the mouse cursor over the dialog is an Arrow. // LRESULT CAddressDialog::OnSetCursor ( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { if (LOWORD(lParam) == HTCLIENT) { SetCursor(LoadCursor(NULL, IDC_ARROW)); } return 0; } /////////////////////////////////////////////////////////////////////////////// /// Add, Edit, and Remove dialog for Gateway address /// Dialog creation overides CGatewayDialog::CGatewayDialog(CIpSettingsPage * pDlgAdv, const DWORD* adwHelpIDs, int iIndex) : m_fValidMetric(TRUE), m_iIndex (iIndex) { m_pParentDlg = pDlgAdv; m_hButton = 0; m_adwHelpIDs = adwHelpIDs; } LRESULT CGatewayDialog::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& fHandled) { // replace the "Text" button with the add or edit // change the ok button to add if we are not editing if (m_pParentDlg->m_fEditState == FALSE) SetDlgItemText(IDOK, m_pParentDlg->m_strAdd.c_str()); m_ipGateAddress.Create(m_hWnd,IDC_IPADDR_ADV_CHANGE_GATEWAY); m_ipGateAddress.SetFieldRange(0, c_iIPADDR_FIELD_1_LOW, c_iIPADDR_FIELD_1_HIGH); SendDlgItemMessage(IDC_IPADDR_ADV_CHANGE_METRIC, EM_LIMITTEXT, MAX_METRIC_DIGITS, 0); HWND hList = ::GetDlgItem(m_pParentDlg->m_hWnd, IDC_IPADDR_GATE); RECT rect; ::GetWindowRect(hList, &rect); SetWindowPos(NULL, rect.left, rect.top, 0,0, SWP_NOZORDER|SWP_NOSIZE|SWP_NOACTIVATE); m_hButton = GetDlgItem(IDOK); // add the address that was just removed if (m_strNewGate.size()) { m_ipGateAddress.SetAddress(m_strNewGate.c_str()); ::EnableWindow(m_hButton, TRUE); } else { m_strNewGate = L""; ::EnableWindow(m_hButton, FALSE); } //initialize the metric controls BOOL fAutoMetric = (0 == m_uiNewMetric); CheckDlgButton(IDC_IPADDR_ADV_CHANGE_AUTOMETRIC, fAutoMetric); if (fAutoMetric) { SetDlgItemText(IDC_IPADDR_ADV_CHANGE_METRIC, L""); ::EnableWindow(GetDlgItem(IDC_IPADDR_ADV_CHANGE_METRIC), FALSE); ::EnableWindow(GetDlgItem(IDC_IPADDR_ADV_CHANGE_METRIC_STATIC), FALSE); } else { SetDlgItemInt(IDC_IPADDR_ADV_CHANGE_METRIC, m_uiNewMetric); } m_fValidMetric = TRUE; return TRUE; } LRESULT CGatewayDialog::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& fHandled) { ShowContextHelp(m_hWnd, HELP_CONTEXTMENU, m_adwHelpIDs); return 0; } LRESULT CGatewayDialog::OnHelp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& fHandled) { LPHELPINFO lphi = reinterpret_cast(lParam); Assert(lphi); if (HELPINFO_WINDOW == lphi->iContextType) { ShowContextHelp(static_cast(lphi->hItemHandle), HELP_WM_HELP, m_adwHelpIDs); } return 0; } LRESULT CGatewayDialog::OnGatewayChange(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled) { switch (wNotifyCode) { case EN_CHANGE: Assert(m_hButton); if (m_ipGateAddress.IsBlank() || !m_fValidMetric) ::EnableWindow(m_hButton, FALSE); else ::EnableWindow(m_hButton, TRUE); break; default: break; } return 0; } LRESULT CGatewayDialog::OnMetricChange(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled) { switch (wNotifyCode) { case EN_CHANGE: if (!IsDlgButtonChecked(IDC_IPADDR_ADV_CHANGE_AUTOMETRIC)) { BOOL bTranslated; UINT nValue; nValue = GetDlgItemInt(IDC_IPADDR_ADV_CHANGE_METRIC, &bTranslated, FALSE); m_fValidMetric = bTranslated; if (!m_fValidMetric || m_ipGateAddress.IsBlank()) ::EnableWindow(m_hButton, FALSE); else ::EnableWindow(m_hButton, TRUE); } break; default: break; } return 0; } LRESULT CGatewayDialog::OnIpFieldChange(int idCtrl, LPNMHDR pnmh, BOOL& fHandled) { LPNMIPADDRESS lpnmipa = (LPNMIPADDRESS) pnmh; int iLow = c_iIpLow; int iHigh = c_iIpHigh; if (0==lpnmipa->iField) { iLow = c_iIPADDR_FIELD_1_LOW; iHigh = c_iIPADDR_FIELD_1_HIGH; }; IpCheckRange(lpnmipa, m_hWnd, iLow, iHigh, TRUE); return 0; } LRESULT CGatewayDialog::OnOk(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled) { tstring strGateway; m_ipGateAddress.GetAddress(&strGateway); // Validate if (!FIsIpInRange(strGateway.c_str())) { // makes ip address lose focus so the control gets // IPN_FIELDCHANGED notification // also makes it consistent for when short-cut is used ::SetFocus(m_hButton); return 0; } int iIndex = -1; iIndex = SearchListViewItem(m_pParentDlg->m_hGatewayListView, 0, strGateway.c_str()); if (-1 != iIndex && iIndex != m_iIndex) { NcMsgBox(::GetActiveWindow(), IDS_MSFT_TCP_TEXT, IDS_DUP_GATEWAY, MB_APPLMODAL | MB_ICONSTOP | MB_OK, strGateway.c_str()); return 0; } BOOL bTranslated; UINT uiMetric = 0; //Get the metric. If auto-metric is selected, the metric valud is 0. //Otherwise get the metric value from the edit control if (!IsDlgButtonChecked(IDC_IPADDR_ADV_CHANGE_AUTOMETRIC)) { uiMetric = GetDlgItemInt(IDC_IPADDR_ADV_CHANGE_METRIC, &bTranslated, FALSE); if (uiMetric < 1 || uiMetric > MAX_METRIC) { HWND hFocus = NULL; TCHAR szBuf[32] = {0}; wsprintf(szBuf, L"%u", MAX_METRIC); NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_INVALID_METRIC, MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK, szBuf); hFocus = GetDlgItem(IDC_IPADDR_ADV_CHANGE_METRIC); if (hFocus) { ::SetFocus(hFocus); } return 0; } } if (m_pParentDlg->m_fEditState == FALSE) { // Get the current address from the control and add them to the adapter if valid m_strNewGate = strGateway; m_uiNewMetric = uiMetric; m_pParentDlg->m_fModified = TRUE; EndDialog(IDOK); } else // see if either changed { if (strGateway != m_strNewGate || uiMetric != m_uiNewMetric) { m_pParentDlg->m_fModified = TRUE; m_strNewGate = strGateway; m_uiNewMetric = uiMetric; EndDialog(IDOK); } else { EndDialog(IDCANCEL); } } return 0; } LRESULT CGatewayDialog::OnCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled) { EndDialog(IDCANCEL); return 0; } LRESULT CGatewayDialog::OnAutoMetric(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled) { BOOL fEnable = FALSE; BOOL bTranslated; UINT nValue; switch(wNotifyCode) { case BN_CLICKED: case BN_DOUBLECLICKED: fEnable = !IsDlgButtonChecked(IDC_IPADDR_ADV_CHANGE_AUTOMETRIC); ::EnableWindow(GetDlgItem(IDC_IPADDR_ADV_CHANGE_METRIC_STATIC), fEnable); ::EnableWindow(GetDlgItem(IDC_IPADDR_ADV_CHANGE_METRIC), fEnable); if (!fEnable) { ::SetWindowText(GetDlgItem(IDC_IPADDR_ADV_CHANGE_METRIC), _T("")); m_fValidMetric = TRUE; } else { nValue = GetDlgItemInt(IDC_IPADDR_ADV_CHANGE_METRIC, &bTranslated, FALSE); m_fValidMetric = bTranslated; } if (m_ipGateAddress.IsBlank()) { ::EnableWindow(m_hButton, FALSE); } else if (!fEnable) { //if the ip address has been filled in and we are using auto-metric, //enable the "OK" button ::EnableWindow(m_hButton, TRUE); } else { //if the address has been fileed in and we are using manual metric, //disable the "OK" button when the metric edit box doesn't contain //valid number ::EnableWindow(m_hButton, m_fValidMetric); } break; } return 0; } //+--------------------------------------------------------------------------- // // Purpose: Ensure the mouse cursor over the dialog is an Arrow. // LRESULT CGatewayDialog::OnSetCursor ( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { if (LOWORD(lParam) == HTCLIENT) { SetCursor(LoadCursor(NULL, IDC_ARROW)); } return 0; }