//----------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1997. // // File: D L G A D D R . C P P // // Contents: CTcpAddrPage implementation // // Notes: CTcpAddrPage is the IP Address page // // Author: tongl 5 Nov, 1997 //----------------------------------------------------------------------- #include "pch.h" #pragma hdrstop #include "tcpipobj.h" #include "dlgaddr.h" #include "resource.h" #include "tcpconst.h" #include "tcperror.h" #include "tcphelp.h" #include "tcputil.h" #include "ncatlui.h" #include "ncstl.h" #include "ncui.h" #include "ncsvc.h" #include "ncperms.h" #include "dlgaddrm.h" #include "dlgdns.h" #include "dlgwins.h" #include "dlgatm.h" #include "dlgopt.h" #include "dlgras.h" CTcpAddrPage::CTcpAddrPage(CTcpipcfg * ptcpip, const DWORD * adwHelpIDs) : m_pageBackup(ptcpip, g_aHelpIDS_IDD_BACK_UP), m_hBackupPage(NULL) { Assert(ptcpip); m_ptcpip = ptcpip; m_adwHelpIDs = adwHelpIDs; m_pAdapterInfo = ptcpip->GetConnectionAdapterInfo(); m_fModified = FALSE; m_fPropShtOk = FALSE; m_fPropShtModified = FALSE; m_fLmhostsFileReset = FALSE; //IPSec is removed from connection UI // m_fIpsecPolicySet = FALSE; m_ConnType = m_ptcpip->GetConnectionType(); Assert(m_ConnType != CONNECTION_UNSET); m_fRasNotAdmin = m_ptcpip->IsRasNotAdmin(); m_pIpSettingsPage = NULL; m_pTcpDnsPage = NULL; m_pTcpWinsPage = NULL; m_pAtmArpcPage = NULL; m_pTcpOptionsPage = NULL; m_pTcpRasPage = NULL; } CTcpAddrPage::~CTcpAddrPage() { FreeCollectionAndItem(m_vstrWarnedDupIpList); } LRESULT CTcpAddrPage::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& fHandled) { // limit the field ranges for the address fields m_ipAddress.Create(m_hWnd, IDC_IPADDR_IP); m_ipAddress.SetFieldRange(0, c_iIPADDR_FIELD_1_LOW, c_iIPADDR_FIELD_1_HIGH); m_ipDnsPrimary.Create(m_hWnd, IDC_DNS_PRIMARY); m_ipDnsPrimary.SetFieldRange(0, c_iIPADDR_FIELD_1_LOW, c_iIPADDR_FIELD_1_HIGH); m_ipDnsSecondary.Create(m_hWnd, IDC_DNS_SECONDARY); m_ipDnsSecondary.SetFieldRange(0, c_iIPADDR_FIELD_1_LOW, c_iIPADDR_FIELD_1_HIGH); if (m_ConnType == CONNECTION_LAN) { // these are for Lan connections only m_ipSubnetMask.Create(m_hWnd, IDC_IPADDR_SUB); m_ipDefGateway.Create(m_hWnd, IDC_IPADDR_GATE); m_ipDefGateway.SetFieldRange(0, c_iIPADDR_FIELD_1_LOW, c_iIPADDR_FIELD_1_HIGH); } if (!FHasPermission(NCPERM_AllowAdvancedTCPIPConfig)) { ::EnableWindow(GetDlgItem(IDC_IPADDR_ADVANCED), FALSE); } return 0; } LRESULT CTcpAddrPage::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& fHandled) { ShowContextHelp(m_hWnd, HELP_CONTEXTMENU, m_adwHelpIDs); return 0; } LRESULT CTcpAddrPage::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 CTcpAddrPage::OnActive(int idCtrl, LPNMHDR pnmh, BOOL& fHandled) { m_fSetInitialValue = TRUE; SetInfo(); m_fSetInitialValue = FALSE; ::SetWindowLongPtr(m_hWnd, DWLP_MSGRESULT, 0); return 0; } LRESULT CTcpAddrPage::OnKillActive(int idCtrl, LPNMHDR pnmh, BOOL& fHandled) { // All error values are loaded and then checked here // while all non-error values are checked in OnApply BOOL fError = FALSE; // Allow page to lose active status HWND hWndFocus = 0; // If the ip address and subnet mask on this page mismatch, // just raise error and do not update the UI if (m_ConnType == CONNECTION_LAN) { if (m_ipAddress.IsBlank() && !m_ipSubnetMask.IsBlank()) { NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_INVALID_NO_IP, MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK); hWndFocus = (HWND) m_ipAddress; fError = TRUE; } else if (!m_ipAddress.IsBlank() && m_ipSubnetMask.IsBlank()) { NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_INVALID_NOSUBNET, MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK); hWndFocus = (HWND) m_ipSubnetMask; fError = TRUE; } } if (!m_ipDnsPrimary.IsBlank() && !m_ipDnsSecondary.IsBlank()) { tstring strPrimaryDns; tstring strSecondDns; m_ipDnsPrimary.GetAddress(&strPrimaryDns); m_ipDnsSecondary.GetAddress(&strSecondDns); if (strPrimaryDns == strSecondDns) { NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_DUP_SECOND_DNS, MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK); hWndFocus = (HWND) m_ipDnsSecondary; fError = TRUE; } } // Now, update in memory structure if (!fError) { UpdateInfo(); if (m_ConnType != CONNECTION_LAN) { if (!m_pAdapterInfo->m_fEnableDhcp) { // simply make sure ip address is not empty for RAS connections if (!m_pAdapterInfo->m_vstrIpAddresses.size()) { NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_INVALID_NO_IP, MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK); hWndFocus = (HWND) m_ipAddress; fError = TRUE; } else { DWORD ardwIp[4]; GetNodeNum(m_pAdapterInfo->m_vstrIpAddresses[0]->c_str(), ardwIp); if (ardwIp[0] > c_iIPADDR_FIELD_1_HIGH || ardwIp[0] < c_iIPADDR_FIELD_1_LOW) { IPAlertPrintf(m_hWnd, IDS_INCORRECT_IP_FIELD_1, ardwIp[0], c_iIPADDR_FIELD_1_LOW, c_iIPADDR_FIELD_1_HIGH); hWndFocus = (HWND) m_ipAddress; fError = TRUE; } } } } else // for Lan connections { // Check validate IP address and duplication on each card before // allowing the page to lose focus IP_VALIDATION_ERR err; // Validate IP Address for adapter used in this connection if ((err = ValidateIp(m_pAdapterInfo)) != ERR_NONE) { switch(err) { case ERR_HOST_ALL0: NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_INVALID_HOST_ALL_0, MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK); hWndFocus = (HWND) m_ipAddress; break; case ERR_HOST_ALL1: NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_INVALID_HOST_ALL_1, MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK); hWndFocus = (HWND) m_ipAddress; break; case ERR_SUBNET_ALL0: NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_INVALID_SUBNET_ALL_0, MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK); hWndFocus = (HWND) m_ipSubnetMask; break; case ERR_NO_IP: NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_INVALID_NO_IP, MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK); hWndFocus = (HWND) m_ipAddress; break; case ERR_NO_SUBNET: NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_INVALID_NOSUBNET, MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK); hWndFocus = (HWND) m_ipSubnetMask; break; case ERR_UNCONTIGUOUS_SUBNET: NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_ERROR_UNCONTIGUOUS_SUBNET, MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK); hWndFocus = (HWND) m_ipSubnetMask; break; default: NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_INCORRECT_IPADDRESS, MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK); hWndFocus = (HWND) m_ipAddress; break; } 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; } // different adapter if (!fError) { // The pvcard is a readonly version of the first memory state const VCARD * pvcard = m_ptcpip->GetConstAdapterInfoVector(); int iDupCard; VSTR_ITER iterIpBegin = m_pAdapterInfo->m_vstrIpAddresses.begin(); VSTR_ITER iterIpEnd = m_pAdapterInfo->m_vstrIpAddresses.end(); VSTR_ITER iterIp = iterIpBegin; for( ; iterIp != iterIpEnd ; ++iterIp) { if ((iDupCard=CheckForDuplicates(pvcard, m_pAdapterInfo, **iterIp)) >=0) { Assert((*pvcard)[iDupCard]->m_guidInstanceId != m_pAdapterInfo->m_guidInstanceId); // duplicate IP address between different adapters is not necessarily an error // we raise a warning(requested by bug# 158578) if (!FAlreadyWarned(**iterIp)) { FARPROC pfnHrGetPnpDeviceStatus; HMODULE hNetman; HRESULT hrTmp; NETCON_STATUS ncStatus = NCS_CONNECTED; hrTmp = HrLoadLibAndGetProc(L"netman.dll", "HrGetPnpDeviceStatus", &hNetman, &pfnHrGetPnpDeviceStatus); if (SUCCEEDED(hrTmp)) { hrTmp = (*(PHRGETPNPDEVICESTATUS)pfnHrGetPnpDeviceStatus)( &((*pvcard)[iDupCard]->m_guidInstanceId), &ncStatus); FreeLibrary(hNetman); } UINT uIdMsg = IDS_DUPLICATE_IP_WARNING; if (SUCCEEDED(hrTmp) && (NCS_HARDWARE_MALFUNCTION == ncStatus || NCS_HARDWARE_NOT_PRESENT == ncStatus)) { // bug 286379, if the dup card is malfunctioning or not physically present, // we should give a more specific error uIdMsg = IDS_DUP_MALFUNCTION_IP_WARNING; } //here is the normal case: both cards are functioning if (NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, uIdMsg, MB_APPLMODAL | MB_ICONINFORMATION | MB_YESNO, (*iterIp)->c_str(), (*pvcard)[iDupCard]->m_strDescription.c_str()) == IDYES) { fError = TRUE; // NOT ok to leave the UI } else { // user said the dup is ok, don't warn them again m_vstrWarnedDupIpList.push_back(new tstring((*iterIp)->c_str())); } } } if (fError) break; } } } } if (fError) // page not going away, we should update the Ui with what's in memory SetInfo(); } //we need to change focus to the control that contains invalidate data if (fError && hWndFocus) ::SetFocus(hWndFocus); ::SetWindowLongPtr(m_hWnd, DWLP_MSGRESULT, fError); return fError; } LRESULT CTcpAddrPage::OnApply(int idCtrl, LPNMHDR pnmh, BOOL& fHandled) { BOOL nResult = PSNRET_NOERROR; if(m_fLmhostsFileReset) // if lmhosts has been reset { m_ptcpip->SetSecondMemoryLmhostsFileReset(); } //IPSec is removed from connection UI /* if (m_fIpsecPolicySet) { m_ptcpip->SetSecondMemoryIpsecPolicySet(); } */ //Bug 232011, warning the user that the local IP address will be set as the primary DNS // server address if DHCP is disabled and DNS server list is empty, if DNS server service // is installed. if((!m_pAdapterInfo->m_fEnableDhcp) && (m_pAdapterInfo->m_vstrDnsServerList.size() == 0)) { CServiceManager scm; CService svc; HRESULT hr = scm.HrOpenService (&svc, c_szSvcDnsServer, NO_LOCK, SC_MANAGER_CONNECT, SERVICE_QUERY_STATUS); if(SUCCEEDED(hr)) { NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_TCPIP_DNS_EMPTY, MB_OK | MB_APPLMODAL | MB_ICONEXCLAMATION); } } if (!IsModified()) { ::SetWindowLongPtr(m_hWnd, DWLP_MSGRESULT, nResult); return nResult; } m_ptcpip->SetSecondMemoryModified(); SetModifiedTo(FALSE); // this page is no longer modified ::SetWindowLongPtr(m_hWnd, DWLP_MSGRESULT, nResult); return nResult; } LRESULT CTcpAddrPage::OnCancel(int idCtrl, LPNMHDR pnmh, BOOL& fHandled) { return 0; } LRESULT CTcpAddrPage::OnDhcpButton(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled) { switch(wNotifyCode) { case BN_CLICKED: case BN_DOUBLECLICKED: if (!m_pAdapterInfo->m_fEnableDhcp) // if Dhcp was disabled { // turn on DHCP button and disable the ip and subnet controls m_pAdapterInfo->m_fEnableDhcp = TRUE; EnableGroup(m_pAdapterInfo->m_fEnableDhcp); PageModified(); FreeCollectionAndItem(m_pAdapterInfo->m_vstrIpAddresses); m_ipAddress.ClearAddress(); if (m_ConnType == CONNECTION_LAN) { FreeCollectionAndItem(m_pAdapterInfo->m_vstrSubnetMask); FreeCollectionAndItem(m_pAdapterInfo->m_vstrDefaultGateway); FreeCollectionAndItem(m_pAdapterInfo->m_vstrDefaultGatewayMetric); m_ipSubnetMask.ClearAddress(); m_ipDefGateway.ClearAddress(); } } // if !m_pAdapterInfo->m_fEnableDhcp break; } // switch return 0; } LRESULT CTcpAddrPage::OnFixedButton(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled) { switch(wNotifyCode) { case BN_CLICKED: case BN_DOUBLECLICKED: if (m_pAdapterInfo->m_fEnableDhcp) { PageModified(); // turn off DHCP button and enable the ip and subnet controls m_pAdapterInfo->m_fEnableDhcp = FALSE; EnableGroup(m_pAdapterInfo->m_fEnableDhcp); } break; } // switch return 0; } LRESULT CTcpAddrPage::OnDnsDhcp(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled) { switch(wNotifyCode) { case BN_CLICKED: case BN_DOUBLECLICKED: PageModified(); FreeCollectionAndItem(m_pAdapterInfo->m_vstrDnsServerList); m_ipDnsPrimary.ClearAddress(); m_ipDnsSecondary.ClearAddress(); EnableStaticDns(FALSE); break; } // switch return 0; } LRESULT CTcpAddrPage::OnDnsFixed(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled) { switch(wNotifyCode) { case BN_CLICKED: case BN_DOUBLECLICKED: PageModified(); EnableStaticDns(TRUE); ::SetFocus(GetDlgItem(IDC_DNS_PRIMARY)); break; } // switch return 0; } LRESULT CTcpAddrPage::OnAdvancedButton(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled) { switch (wNotifyCode) { case BN_CLICKED: case BN_DOUBLECLICKED: BOOL fErr = FALSE; if (m_ConnType == CONNECTION_LAN) { // check inconsistency between ip address & subnet mask if (m_ipAddress.IsBlank() && !m_ipSubnetMask.IsBlank()) { NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_INVALID_NO_IP, MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK); ::SetFocus(m_ipAddress); fErr = TRUE; } else if (!m_ipAddress.IsBlank() && m_ipSubnetMask.IsBlank()) { NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_INVALID_NOSUBNET, MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK); ::SetFocus(m_ipSubnetMask); fErr = TRUE; } } if (!m_ipDnsPrimary.IsBlank() && !m_ipDnsSecondary.IsBlank()) { tstring strPrimaryDns; tstring strSecondDns; m_ipDnsPrimary.GetAddress(&strPrimaryDns); m_ipDnsSecondary.GetAddress(&strSecondDns); if (strPrimaryDns == strSecondDns) { NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_DUP_SECOND_DNS, MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK); ::SetFocus(m_ipDnsSecondary); fErr = TRUE; } } if (!fErr) { // update our in memory structure with what's in the controls UpdateInfo(); // Bring up the advanced pages ADAPTER_INFO adapterInfo; adapterInfo = *m_pAdapterInfo; GLOBAL_INFO glbInfo; glbInfo = *(m_ptcpip->GetGlobalInfo()); int iRet = DoPropertySheet(&adapterInfo, &glbInfo); if (iRet != -1) { if (m_fPropShtOk && m_fPropShtModified) { // Something changed, so mark the page as modified PageModified(); // Reset values m_fPropShtOk = FALSE; m_fPropShtModified = FALSE; // Update second memory info structure *m_pAdapterInfo = adapterInfo; GLOBAL_INFO * pGlbInfo = m_ptcpip->GetGlobalInfo(); *pGlbInfo = glbInfo; } } // Update the controls with new data SetInfo(); } break; } return 0; } //Show or Hide the backup configuration page depend on the //current settings of dhcp vs static void CTcpAddrPage::ShowOrHideBackupPage() { if (IsDlgButtonChecked(IDC_IP_DHCP) || IsDlgButtonChecked(IDC_DNS_DHCP)) { //show the backup configuration page if (NULL == m_hBackupPage) { m_hBackupPage = m_pageBackup.CreatePage(IDD_BACK_UP, 0); Assert(m_hBackupPage); if (m_hBackupPage) { ::SendMessage(GetParent(), PSM_ADDPAGE, 0, (LPARAM) m_hBackupPage); } } } else { //hide the backup configuration page if (NULL != m_hBackupPage) { ::SendMessage(GetParent(), PSM_REMOVEPAGE, 1, (LPARAM) m_hBackupPage); m_hBackupPage = NULL; } } } int CTcpAddrPage::DoPropertySheet(ADAPTER_INFO * pAdapterDlg, GLOBAL_INFO * pGlbDlg) { Assert(pAdapterDlg); Assert(pGlbDlg); HRESULT hr = S_OK; int iRet = -1; HPROPSHEETPAGE *ahpsp = NULL; int cPages = 0; // Create property pages // ahpsp is allocated memory by CoTaskMemAlloc hr = HrSetupPropPages(pAdapterDlg, pGlbDlg, &ahpsp, &cPages); if (SUCCEEDED(hr)) { // Show the property sheet PROPSHEETHEADER psh = {0}; psh.dwSize = sizeof(PROPSHEETHEADER); psh.dwFlags = PSH_NOAPPLYNOW; psh.hwndParent = ::GetActiveWindow(); psh.hInstance = _Module.GetModuleInstance(); psh.pszIcon = NULL; psh.pszCaption = (PWSTR)SzLoadIds(IDS_TCP_ADV_HEADER); psh.nPages = cPages; psh.phpage = ahpsp; iRet = PropertySheet(&psh); if (-1 == iRet) { DWORD dwError = GetLastError(); TraceError("CTcpAddrPage::DoPropertySheet", HRESULT_FROM_WIN32(dwError)); } } if (m_pIpSettingsPage) { delete m_pIpSettingsPage; m_pIpSettingsPage = NULL; } if (m_pTcpDnsPage) { delete m_pTcpDnsPage; m_pTcpDnsPage = NULL; } if (m_pTcpWinsPage) { delete m_pTcpWinsPage; m_pTcpWinsPage = NULL; } if (m_pAtmArpcPage) { delete m_pAtmArpcPage; m_pAtmArpcPage = NULL; } if (m_pTcpOptionsPage) { delete m_pTcpOptionsPage; m_pTcpOptionsPage = NULL; } if (m_pTcpRasPage) { delete m_pTcpRasPage; m_pTcpRasPage = NULL; } if (ahpsp) CoTaskMemFree(ahpsp); return iRet; } HRESULT CTcpAddrPage::HrSetupPropPages( ADAPTER_INFO * pAdapterDlg, GLOBAL_INFO * pGlbDlg, HPROPSHEETPAGE ** pahpsp, INT * pcPages) { HRESULT hr = S_OK; // initialize output parameters int cPages = 0; HPROPSHEETPAGE *ahpsp = NULL; // Set up the property pages cPages = 4; if (m_ConnType == CONNECTION_LAN) { m_pIpSettingsPage = new CIpSettingsPage(this, pAdapterDlg, g_aHelpIDs_IDD_IPADDR_ADV); if (m_pIpSettingsPage == NULL) { CORg(E_OUTOFMEMORY); } } else { m_pTcpRasPage = new CTcpRasPage(this, pAdapterDlg, g_aHelpIDs_IDD_OPT_RAS); if (m_pTcpRasPage == NULL) { CORg(E_OUTOFMEMORY); } } m_pTcpDnsPage = new CTcpDnsPage(this, pAdapterDlg, pGlbDlg, g_aHelpIDs_IDD_TCP_DNS); m_pTcpWinsPage = new CTcpWinsPage(m_ptcpip, this, pAdapterDlg, pGlbDlg, g_aHelpIDs_IDD_TCP_WINS); if ((m_pTcpDnsPage == NULL) || (m_pTcpWinsPage == NULL)) { CORg(E_OUTOFMEMORY); } if (pAdapterDlg->m_fIsAtmAdapter) { m_pAtmArpcPage = new CAtmArpcPage(this, pAdapterDlg, g_aHelpIDs_IDD_ATM_ARPC); if (m_pAtmArpcPage == NULL) { CORg(E_OUTOFMEMORY); } cPages++; } //After removing the IPSec connection UI, there are no options to //put in the option tab. So we just go ahead remove it. if (!pAdapterDlg->m_fIsRasFakeAdapter) { m_pTcpOptionsPage = new CTcpOptionsPage(this, pAdapterDlg, pGlbDlg, g_aHelpIDs_IDD_TCP_OPTIONS); if (m_pTcpOptionsPage == NULL) { CORg(E_OUTOFMEMORY); } } else { //we remove the option tab for the ras connections cPages--; } // Allocate a buffer large enough to hold the handles to all of our // property pages. ahpsp = (HPROPSHEETPAGE *)CoTaskMemAlloc(sizeof(HPROPSHEETPAGE) * cPages); if (!ahpsp) { CORg(E_OUTOFMEMORY); } cPages =0; if (m_ConnType == CONNECTION_LAN) { ahpsp[cPages++] = m_pIpSettingsPage->CreatePage(IDD_IPADDR_ADV, 0); } else { ahpsp[cPages++] = m_pTcpRasPage->CreatePage(IDD_OPT_RAS, 0); } ahpsp[cPages++] = m_pTcpDnsPage->CreatePage(IDD_TCP_DNS, 0); ahpsp[cPages++] = m_pTcpWinsPage->CreatePage(IDD_TCP_WINS, 0); if (pAdapterDlg->m_fIsAtmAdapter) { ahpsp[cPages++] = m_pAtmArpcPage->CreatePage(IDD_ATM_ARPC, 0); } if (!pAdapterDlg->m_fIsRasFakeAdapter && m_pTcpOptionsPage) { ahpsp[cPages++] = m_pTcpOptionsPage->CreatePage(IDD_TCP_OPTIONS, 0); } *pahpsp = ahpsp; *pcPages = cPages; Error: if (FAILED(hr)) { if (m_pIpSettingsPage) { delete m_pIpSettingsPage; m_pIpSettingsPage = NULL; } if (m_pTcpDnsPage) { delete m_pTcpDnsPage; m_pTcpDnsPage = NULL; } if (m_pTcpWinsPage) { delete m_pTcpWinsPage; m_pTcpWinsPage = NULL; } if (m_pAtmArpcPage) { delete m_pAtmArpcPage; m_pAtmArpcPage = NULL; } if (m_pTcpOptionsPage) { delete m_pTcpOptionsPage; m_pTcpOptionsPage = NULL; } if (m_pTcpRasPage) { delete m_pTcpRasPage; m_pTcpRasPage = NULL; } } return hr; } LRESULT CTcpAddrPage::OnIpAddrIp(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled) { switch (wNotifyCode) { case EN_CHANGE: PageModified(); break; } return 0; } LRESULT CTcpAddrPage::OnIpAddrSub(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled) { switch (wNotifyCode) { case EN_CHANGE: PageModified(); break; case EN_SETFOCUS: // if the subnet mask is blank, create a mask and insert it into // the control if (!m_ipAddress.IsBlank() && m_ipSubnetMask.IsBlank()) { tstring strSubnetMask; tstring strIpAddress; m_ipAddress.GetAddress(&strIpAddress); // generate the mask and update the control, and internal structure GenerateSubnetMask(m_ipAddress, &strSubnetMask); m_ipSubnetMask.SetAddress(strSubnetMask.c_str()); ReplaceFirstAddress(&(m_pAdapterInfo->m_vstrSubnetMask), strSubnetMask.c_str()); } break; } return 0; } LRESULT CTcpAddrPage::OnIpAddrGateway(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled) { switch (wNotifyCode) { case EN_CHANGE: PageModified(); break; } return 0; } LRESULT CTcpAddrPage::OnDnsPrimary(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled) { switch (wNotifyCode) { case EN_CHANGE: PageModified(); break; } return 0; } LRESULT CTcpAddrPage::OnDnsSecondary(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled) { switch (wNotifyCode) { case EN_CHANGE: PageModified(); break; } return 0; } LRESULT CTcpAddrPage::OnIpFieldChange(int idCtrl, LPNMHDR pnmh, BOOL& fHandled) { LPNMIPADDRESS lpnmipa; int iLow = c_iIpLow; int iHigh = c_iIpHigh; switch(idCtrl) { case IDC_IPADDR_IP: case IDC_IPADDR_GATE: case IDC_DNS_PRIMARY: case IDC_DNS_SECONDARY: 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, (IDC_IPADDR_IP == idCtrl || IDC_IPADDR_GATE == idCtrl)); break; case IDC_IPADDR_SUB: lpnmipa = (LPNMIPADDRESS) pnmh; IpCheckRange(lpnmipa, m_hWnd, iLow, iHigh); break; default: break; } return 0; } void CTcpAddrPage::EnableGroup(BOOL fEnableDhcp) { BOOL fStaticIp = !fEnableDhcp; CheckDlgButton(IDC_IP_DHCP, fEnableDhcp); CheckDlgButton(IDC_IP_FIXED, fStaticIp); ::EnableWindow(GetDlgItem(IDC_IPADDR_IPTEXT), fStaticIp); ::EnableWindow(GetDlgItem(IDC_IPADDR_IP), fStaticIp); if (m_ConnType == CONNECTION_LAN) { ::EnableWindow(GetDlgItem(IDC_IPADDR_SUBTEXT), fStaticIp); ::EnableWindow(GetDlgItem(IDC_IPADDR_SUB), fStaticIp); ::EnableWindow(GetDlgItem(IDC_IPADDR_GATE), fStaticIp); ::EnableWindow(GetDlgItem(IDC_IPADDR_GATETEXT), fStaticIp); } if (!fEnableDhcp) // enforce DNS address option { CheckDlgButton(IDC_DNS_DHCP, FALSE); CheckDlgButton(IDC_DNS_FIXED, TRUE); ::EnableWindow(GetDlgItem(IDC_DNS_DHCP), FALSE); EnableStaticDns(TRUE); } else { ::EnableWindow(GetDlgItem(IDC_DNS_DHCP), TRUE); } if (CONNECTION_LAN == m_ConnType) { ShowOrHideBackupPage(); } } void CTcpAddrPage::EnableStaticDns(BOOL fUseStaticDns) { ::EnableWindow(GetDlgItem(IDC_DNS_PRIMARY), fUseStaticDns); ::EnableWindow(GetDlgItem(IDC_DNS_PRIMARY_TEXT), fUseStaticDns); ::EnableWindow(GetDlgItem(IDC_DNS_SECONDARY), fUseStaticDns); ::EnableWindow(GetDlgItem(IDC_DNS_SECONDARY_TEXT), fUseStaticDns); } // Set info to controls using the data in m_pAdapterInfo void CTcpAddrPage::SetInfo() { Assert(m_pAdapterInfo); // Dhcp Ip address is not allowed when Dhcp server is installed or // it is a SLIP connection // const GLOBAL_INFO * pglb = m_ptcpip->GetConstGlobalInfo(); // if ((pglb->m_fDhcpServerInstalled) || (m_ConnType == CONNECTION_RAS_SLIP)) if (m_ConnType == CONNECTION_RAS_SLIP) { ::EnableWindow(GetDlgItem(IDC_IP_DHCP), FALSE); m_pAdapterInfo->m_fEnableDhcp = 0; } EnableGroup(m_pAdapterInfo->m_fEnableDhcp); // Set Ip address if(m_pAdapterInfo->m_fEnableDhcp == 0) //Dhcp disabled, static IP { tstring strTmp; if (fQueryFirstAddress(m_pAdapterInfo->m_vstrIpAddresses, &strTmp)) m_ipAddress.SetAddress(strTmp.c_str()); else m_ipAddress.ClearAddress(); } else //Dhcp enabled { m_ipAddress.ClearAddress(); FreeCollectionAndItem(m_pAdapterInfo->m_vstrIpAddresses); } // Set Subnet mask and default gateway if Lan connection if (m_ConnType == CONNECTION_LAN) { if(m_pAdapterInfo->m_fEnableDhcp == 0) //Dhcp disabled, static IP { tstring strTmp; if (fQueryFirstAddress(m_pAdapterInfo->m_vstrSubnetMask, &strTmp)) m_ipSubnetMask.SetAddress(strTmp.c_str()); else m_ipSubnetMask.ClearAddress(); if (fQueryFirstAddress(m_pAdapterInfo->m_vstrDefaultGateway, &strTmp)) m_ipDefGateway.SetAddress(strTmp.c_str()); else m_ipDefGateway.ClearAddress(); } else //Dhcp enabled { m_ipSubnetMask.ClearAddress(); FreeCollectionAndItem(m_pAdapterInfo->m_vstrSubnetMask); tstring strGateway; if (fQueryFirstAddress(m_pAdapterInfo->m_vstrDefaultGateway, &strGateway)) m_ipDefGateway.SetAddress(strGateway.c_str()); else m_ipDefGateway.ClearAddress(); } } // Set Dns addresses BOOL fUseStaticDns = ((!m_pAdapterInfo->m_fEnableDhcp) || (m_pAdapterInfo->m_vstrDnsServerList.size() >0)); CheckDlgButton(IDC_DNS_DHCP, !fUseStaticDns); CheckDlgButton(IDC_DNS_FIXED, fUseStaticDns); EnableStaticDns(fUseStaticDns); if (fUseStaticDns) { tstring strTmp; if (fQueryFirstAddress(m_pAdapterInfo->m_vstrDnsServerList, &strTmp)) m_ipDnsPrimary.SetAddress(strTmp.c_str()); else m_ipDnsPrimary.ClearAddress(); if (fQuerySecondAddress(m_pAdapterInfo->m_vstrDnsServerList, &strTmp)) m_ipDnsSecondary.SetAddress(strTmp.c_str()); else m_ipDnsSecondary.ClearAddress(); } else { m_ipDnsPrimary.ClearAddress(); m_ipDnsSecondary.ClearAddress(); } } // Update info in m_pAdapterInfo with what's in the controls void CTcpAddrPage::UpdateInfo() { Assert(m_pAdapterInfo); if (!m_pAdapterInfo->m_fEnableDhcp) // If DHCP disabled { tstring strNewAddress; // ip address & subnet mask if (!m_ipAddress.IsBlank()) { m_ipAddress.GetAddress(&strNewAddress); ReplaceFirstAddress(&(m_pAdapterInfo->m_vstrIpAddresses), strNewAddress.c_str()); if (m_ConnType == CONNECTION_LAN) { if (m_ipSubnetMask.IsBlank()) { SendDlgItemMessage(IDC_IPADDR_SUB, WM_SETFOCUS, 0, 0); } else { m_ipSubnetMask.GetAddress(&strNewAddress); ReplaceFirstAddress(&(m_pAdapterInfo->m_vstrSubnetMask), strNewAddress.c_str()); } } } else // no ip address { if (m_ConnType == CONNECTION_LAN) { if (m_ipSubnetMask.IsBlank()) { // delete the first ip address and subnet mask if (m_pAdapterInfo->m_vstrIpAddresses.size()) { FreeVectorItem(m_pAdapterInfo->m_vstrIpAddresses, 0); if (!m_pAdapterInfo->m_vstrIpAddresses.empty()) m_ipAddress.SetAddress(m_pAdapterInfo->m_vstrIpAddresses[0]->c_str()); if (m_pAdapterInfo->m_vstrSubnetMask.size()) { FreeVectorItem(m_pAdapterInfo->m_vstrSubnetMask, 0); if (!m_pAdapterInfo->m_vstrSubnetMask.empty()) m_ipSubnetMask.SetAddress(m_pAdapterInfo->m_vstrSubnetMask[0]->c_str()); } } } else { AssertSz(FALSE, "No ip address."); } } else // RAS connection, simply delete IP address { if (m_pAdapterInfo->m_vstrIpAddresses.size()) { FreeVectorItem(m_pAdapterInfo->m_vstrIpAddresses, 0); } } } // default gateway if (m_ConnType == CONNECTION_LAN) { if (!m_ipDefGateway.IsBlank()) { m_ipDefGateway.GetAddress(&strNewAddress); ReplaceFirstAddress(&(m_pAdapterInfo->m_vstrDefaultGateway), strNewAddress.c_str()); int iSize = m_pAdapterInfo->m_vstrDefaultGatewayMetric.size(); if (m_pAdapterInfo->m_vstrDefaultGatewayMetric.size() == 0) { WCHAR buf[IP_LIMIT]; //if there is no default gateway before (that's the reason metric list is //empty), we add the default metric for it _ltot(c_dwDefaultMetricOfGateway, buf, 10); m_pAdapterInfo->m_vstrDefaultGatewayMetric.push_back(new tstring(buf)); } } else { if (m_pAdapterInfo->m_vstrDefaultGateway.size() >0) { FreeVectorItem(m_pAdapterInfo->m_vstrDefaultGateway, 0); if (!m_pAdapterInfo->m_vstrDefaultGateway.empty()) m_ipDefGateway.SetAddress(m_pAdapterInfo->m_vstrDefaultGateway[0]->c_str()); if (m_pAdapterInfo->m_vstrDefaultGatewayMetric.size() >0) FreeVectorItem(m_pAdapterInfo->m_vstrDefaultGatewayMetric, 0); } } } } // DNS addresses UpdateAddressList(&(m_pAdapterInfo->m_vstrDnsServerList), m_ipDnsPrimary, m_ipDnsSecondary); } // Update a vector of strings with values from two IP address // controls void CTcpAddrPage::UpdateAddressList(VSTR * pvstrList, IpControl& ipPrimary, IpControl& ipSecondary) { tstring str; if (pvstrList->size()<=2) // if the list did not have more than two addresses { // Free the list FreeCollectionAndItem(*pvstrList); // Insert new addresses if any if (!ipPrimary.IsBlank()) { ipPrimary.GetAddress(&str); pvstrList->push_back(new tstring(str.c_str())); } if (!ipSecondary.IsBlank()) { ipSecondary.GetAddress(&str); pvstrList->push_back(new tstring(str.c_str())); } } else { // Replace addresses if they exists if (!ipSecondary.IsBlank()) { ipSecondary.GetAddress(&str); ReplaceSecondAddress(pvstrList, str.c_str()); } else { FreeVectorItem(*pvstrList, 1); } if (!ipPrimary.IsBlank()) { ipPrimary.GetAddress(&str); ReplaceFirstAddress(pvstrList, str.c_str()); } else { FreeVectorItem(*pvstrList, 0); } //fix Bug 425112: Update the UI if either of the IP control //is blank because sometimes UpdateInfo get called twice (which // will make us delete the address twice if we dont update the UI) if (ipPrimary.IsBlank() || ipSecondary.IsBlank()) { if (!pvstrList->empty()) { ipPrimary.SetAddress((*pvstrList)[0]->c_str()); } if (pvstrList->size() >= 2) { ipSecondary.SetAddress((*pvstrList)[1]->c_str()); } } } }