Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1338 lines
38 KiB

  1. //-----------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: D L G A D D R . C P P
  7. //
  8. // Contents: CTcpAddrPage implementation
  9. //
  10. // Notes: CTcpAddrPage is the IP Address page
  11. //
  12. // Author: tongl 5 Nov, 1997
  13. //-----------------------------------------------------------------------
  14. #include "pch.h"
  15. #pragma hdrstop
  16. #include "tcpipobj.h"
  17. #include "dlgaddr.h"
  18. #include "resource.h"
  19. #include "tcpconst.h"
  20. #include "tcperror.h"
  21. #include "tcphelp.h"
  22. #include "tcputil.h"
  23. #include "ncatlui.h"
  24. #include "ncstl.h"
  25. #include "ncui.h"
  26. #include "ncsvc.h"
  27. #include "ncperms.h"
  28. #include "dlgaddrm.h"
  29. #include "dlgdns.h"
  30. #include "dlgwins.h"
  31. #include "dlgatm.h"
  32. #include "dlgopt.h"
  33. #include "dlgras.h"
  34. CTcpAddrPage::CTcpAddrPage(CTcpipcfg * ptcpip, const DWORD * adwHelpIDs) :
  35. m_pageBackup(ptcpip, g_aHelpIDS_IDD_BACK_UP),
  36. m_hBackupPage(NULL)
  37. {
  38. Assert(ptcpip);
  39. m_ptcpip = ptcpip;
  40. m_adwHelpIDs = adwHelpIDs;
  41. m_pAdapterInfo = ptcpip->GetConnectionAdapterInfo();
  42. m_fModified = FALSE;
  43. m_fPropShtOk = FALSE;
  44. m_fPropShtModified = FALSE;
  45. m_fLmhostsFileReset = FALSE;
  46. //IPSec is removed from connection UI
  47. // m_fIpsecPolicySet = FALSE;
  48. m_ConnType = m_ptcpip->GetConnectionType();
  49. Assert(m_ConnType != CONNECTION_UNSET);
  50. m_fRasNotAdmin = m_ptcpip->IsRasNotAdmin();
  51. m_pIpSettingsPage = NULL;
  52. m_pTcpDnsPage = NULL;
  53. m_pTcpWinsPage = NULL;
  54. m_pAtmArpcPage = NULL;
  55. m_pTcpOptionsPage = NULL;
  56. m_pTcpRasPage = NULL;
  57. }
  58. CTcpAddrPage::~CTcpAddrPage()
  59. {
  60. FreeCollectionAndItem(m_vstrWarnedDupIpList);
  61. }
  62. LRESULT CTcpAddrPage::OnInitDialog(UINT uMsg, WPARAM wParam,
  63. LPARAM lParam, BOOL& fHandled)
  64. {
  65. // limit the field ranges for the address fields
  66. m_ipAddress.Create(m_hWnd, IDC_IPADDR_IP);
  67. m_ipAddress.SetFieldRange(0, c_iIPADDR_FIELD_1_LOW, c_iIPADDR_FIELD_1_HIGH);
  68. m_ipDnsPrimary.Create(m_hWnd, IDC_DNS_PRIMARY);
  69. m_ipDnsPrimary.SetFieldRange(0, c_iIPADDR_FIELD_1_LOW, c_iIPADDR_FIELD_1_HIGH);
  70. m_ipDnsSecondary.Create(m_hWnd, IDC_DNS_SECONDARY);
  71. m_ipDnsSecondary.SetFieldRange(0, c_iIPADDR_FIELD_1_LOW, c_iIPADDR_FIELD_1_HIGH);
  72. if (m_ConnType == CONNECTION_LAN)
  73. {
  74. // these are for Lan connections only
  75. m_ipSubnetMask.Create(m_hWnd, IDC_IPADDR_SUB);
  76. m_ipDefGateway.Create(m_hWnd, IDC_IPADDR_GATE);
  77. m_ipDefGateway.SetFieldRange(0, c_iIPADDR_FIELD_1_LOW, c_iIPADDR_FIELD_1_HIGH);
  78. }
  79. if (!FHasPermission(NCPERM_AllowAdvancedTCPIPConfig))
  80. {
  81. ::EnableWindow(GetDlgItem(IDC_IPADDR_ADVANCED), FALSE);
  82. }
  83. return 0;
  84. }
  85. LRESULT CTcpAddrPage::OnContextMenu(UINT uMsg, WPARAM wParam,
  86. LPARAM lParam, BOOL& fHandled)
  87. {
  88. ShowContextHelp(m_hWnd, HELP_CONTEXTMENU, m_adwHelpIDs);
  89. return 0;
  90. }
  91. LRESULT CTcpAddrPage::OnHelp(UINT uMsg, WPARAM wParam,
  92. LPARAM lParam, BOOL& fHandled)
  93. {
  94. LPHELPINFO lphi = reinterpret_cast<LPHELPINFO>(lParam);
  95. Assert(lphi);
  96. if (HELPINFO_WINDOW == lphi->iContextType)
  97. {
  98. ShowContextHelp(static_cast<HWND>(lphi->hItemHandle), HELP_WM_HELP,
  99. m_adwHelpIDs);
  100. }
  101. return 0;
  102. }
  103. LRESULT CTcpAddrPage::OnActive(int idCtrl, LPNMHDR pnmh, BOOL& fHandled)
  104. {
  105. m_fSetInitialValue = TRUE;
  106. SetInfo();
  107. m_fSetInitialValue = FALSE;
  108. ::SetWindowLongPtr(m_hWnd, DWLP_MSGRESULT, 0);
  109. return 0;
  110. }
  111. LRESULT CTcpAddrPage::OnKillActive(int idCtrl, LPNMHDR pnmh, BOOL& fHandled)
  112. {
  113. // All error values are loaded and then checked here
  114. // while all non-error values are checked in OnApply
  115. BOOL fError = FALSE; // Allow page to lose active status
  116. HWND hWndFocus = 0;
  117. // If the ip address and subnet mask on this page mismatch,
  118. // just raise error and do not update the UI
  119. if (m_ConnType == CONNECTION_LAN)
  120. {
  121. if (m_ipAddress.IsBlank() && !m_ipSubnetMask.IsBlank())
  122. {
  123. NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_INVALID_NO_IP,
  124. MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK);
  125. hWndFocus = (HWND) m_ipAddress;
  126. fError = TRUE;
  127. }
  128. else if (!m_ipAddress.IsBlank() && m_ipSubnetMask.IsBlank())
  129. {
  130. NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_INVALID_NOSUBNET,
  131. MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK);
  132. hWndFocus = (HWND) m_ipSubnetMask;
  133. fError = TRUE;
  134. }
  135. }
  136. if (!m_ipDnsPrimary.IsBlank() && !m_ipDnsSecondary.IsBlank())
  137. {
  138. tstring strPrimaryDns;
  139. tstring strSecondDns;
  140. m_ipDnsPrimary.GetAddress(&strPrimaryDns);
  141. m_ipDnsSecondary.GetAddress(&strSecondDns);
  142. if (strPrimaryDns == strSecondDns)
  143. {
  144. NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_DUP_SECOND_DNS,
  145. MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK);
  146. hWndFocus = (HWND) m_ipDnsSecondary;
  147. fError = TRUE;
  148. }
  149. }
  150. // Now, update in memory structure
  151. if (!fError)
  152. {
  153. UpdateInfo();
  154. if (m_ConnType != CONNECTION_LAN)
  155. {
  156. if (!m_pAdapterInfo->m_fEnableDhcp)
  157. {
  158. // simply make sure ip address is not empty for RAS connections
  159. if (!m_pAdapterInfo->m_vstrIpAddresses.size())
  160. {
  161. NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_INVALID_NO_IP,
  162. MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK);
  163. hWndFocus = (HWND) m_ipAddress;
  164. fError = TRUE;
  165. }
  166. else
  167. {
  168. DWORD ardwIp[4];
  169. GetNodeNum(m_pAdapterInfo->m_vstrIpAddresses[0]->c_str(), ardwIp);
  170. if (ardwIp[0] > c_iIPADDR_FIELD_1_HIGH || ardwIp[0] < c_iIPADDR_FIELD_1_LOW)
  171. {
  172. IPAlertPrintf(m_hWnd, IDS_INCORRECT_IP_FIELD_1,
  173. ardwIp[0],
  174. c_iIPADDR_FIELD_1_LOW, c_iIPADDR_FIELD_1_HIGH);
  175. hWndFocus = (HWND) m_ipAddress;
  176. fError = TRUE;
  177. }
  178. }
  179. }
  180. }
  181. else // for Lan connections
  182. {
  183. // Check validate IP address and duplication on each card before
  184. // allowing the page to lose focus
  185. IP_VALIDATION_ERR err;
  186. // Validate IP Address for adapter used in this connection
  187. if ((err = ValidateIp(m_pAdapterInfo)) != ERR_NONE)
  188. {
  189. switch(err)
  190. {
  191. case ERR_HOST_ALL0:
  192. NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_INVALID_HOST_ALL_0,
  193. MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK);
  194. hWndFocus = (HWND) m_ipAddress;
  195. break;
  196. case ERR_HOST_ALL1:
  197. NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_INVALID_HOST_ALL_1,
  198. MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK);
  199. hWndFocus = (HWND) m_ipAddress;
  200. break;
  201. case ERR_SUBNET_ALL0:
  202. NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_INVALID_SUBNET_ALL_0,
  203. MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK);
  204. hWndFocus = (HWND) m_ipSubnetMask;
  205. break;
  206. case ERR_NO_IP:
  207. NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_INVALID_NO_IP,
  208. MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK);
  209. hWndFocus = (HWND) m_ipAddress;
  210. break;
  211. case ERR_NO_SUBNET:
  212. NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_INVALID_NOSUBNET,
  213. MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK);
  214. hWndFocus = (HWND) m_ipSubnetMask;
  215. break;
  216. case ERR_UNCONTIGUOUS_SUBNET:
  217. NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_ERROR_UNCONTIGUOUS_SUBNET,
  218. MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK);
  219. hWndFocus = (HWND) m_ipSubnetMask;
  220. break;
  221. default:
  222. NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_INCORRECT_IPADDRESS,
  223. MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK);
  224. hWndFocus = (HWND) m_ipAddress;
  225. break;
  226. }
  227. fError = TRUE;
  228. }
  229. if ((!fError) && (!m_pAdapterInfo->m_fEnableDhcp))
  230. {
  231. // Check ip address duplicates between this adapter and any other
  232. // enabled LAN adapters in our first memory list
  233. // same adapter
  234. if (FHasDuplicateIp(m_pAdapterInfo))
  235. {
  236. // duplicate IP address on same adapter is an error
  237. NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_DUPLICATE_IP_ERROR,
  238. MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK);
  239. fError = TRUE;
  240. }
  241. // different adapter
  242. if (!fError)
  243. {
  244. // The pvcard is a readonly version of the first memory state
  245. const VCARD * pvcard = m_ptcpip->GetConstAdapterInfoVector();
  246. int iDupCard;
  247. VSTR_ITER iterIpBegin = m_pAdapterInfo->m_vstrIpAddresses.begin();
  248. VSTR_ITER iterIpEnd = m_pAdapterInfo->m_vstrIpAddresses.end();
  249. VSTR_ITER iterIp = iterIpBegin;
  250. for( ; iterIp != iterIpEnd ; ++iterIp)
  251. {
  252. if ((iDupCard=CheckForDuplicates(pvcard, m_pAdapterInfo, **iterIp)) >=0)
  253. {
  254. Assert((*pvcard)[iDupCard]->m_guidInstanceId != m_pAdapterInfo->m_guidInstanceId);
  255. // duplicate IP address between different adapters is not necessarily an error
  256. // we raise a warning(requested by bug# 158578)
  257. if (!FAlreadyWarned(**iterIp))
  258. {
  259. FARPROC pfnHrGetPnpDeviceStatus;
  260. HMODULE hNetman;
  261. HRESULT hrTmp;
  262. NETCON_STATUS ncStatus = NCS_CONNECTED;
  263. hrTmp = HrLoadLibAndGetProc(L"netman.dll", "HrGetPnpDeviceStatus",
  264. &hNetman, &pfnHrGetPnpDeviceStatus);
  265. if (SUCCEEDED(hrTmp))
  266. {
  267. hrTmp = (*(PHRGETPNPDEVICESTATUS)pfnHrGetPnpDeviceStatus)(
  268. &((*pvcard)[iDupCard]->m_guidInstanceId),
  269. &ncStatus);
  270. FreeLibrary(hNetman);
  271. }
  272. UINT uIdMsg = IDS_DUPLICATE_IP_WARNING;
  273. if (SUCCEEDED(hrTmp) &&
  274. (NCS_HARDWARE_MALFUNCTION == ncStatus ||
  275. NCS_HARDWARE_NOT_PRESENT == ncStatus))
  276. {
  277. // bug 286379, if the dup card is malfunctioning or not physically present,
  278. // we should give a more specific error
  279. uIdMsg = IDS_DUP_MALFUNCTION_IP_WARNING;
  280. }
  281. //here is the normal case: both cards are functioning
  282. if (NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, uIdMsg,
  283. MB_APPLMODAL | MB_ICONINFORMATION | MB_YESNO,
  284. (*iterIp)->c_str(),
  285. (*pvcard)[iDupCard]->m_strDescription.c_str()) == IDYES)
  286. {
  287. fError = TRUE; // NOT ok to leave the UI
  288. }
  289. else
  290. {
  291. // user said the dup is ok, don't warn them again
  292. m_vstrWarnedDupIpList.push_back(new tstring((*iterIp)->c_str()));
  293. }
  294. }
  295. }
  296. if (fError)
  297. break;
  298. }
  299. }
  300. }
  301. }
  302. if (fError) // page not going away, we should update the Ui with what's in memory
  303. SetInfo();
  304. }
  305. //we need to change focus to the control that contains invalidate data
  306. if (fError && hWndFocus)
  307. ::SetFocus(hWndFocus);
  308. ::SetWindowLongPtr(m_hWnd, DWLP_MSGRESULT, fError);
  309. return fError;
  310. }
  311. LRESULT CTcpAddrPage::OnApply(int idCtrl, LPNMHDR pnmh, BOOL& fHandled)
  312. {
  313. BOOL nResult = PSNRET_NOERROR;
  314. if(m_fLmhostsFileReset) // if lmhosts has been reset
  315. {
  316. m_ptcpip->SetSecondMemoryLmhostsFileReset();
  317. }
  318. //IPSec is removed from connection UI
  319. /*
  320. if (m_fIpsecPolicySet)
  321. {
  322. m_ptcpip->SetSecondMemoryIpsecPolicySet();
  323. }
  324. */
  325. //Bug 232011, warning the user that the local IP address will be set as the primary DNS
  326. // server address if DHCP is disabled and DNS server list is empty, if DNS server service
  327. // is installed.
  328. if((!m_pAdapterInfo->m_fEnableDhcp) && (m_pAdapterInfo->m_vstrDnsServerList.size() == 0))
  329. {
  330. CServiceManager scm;
  331. CService svc;
  332. HRESULT hr = scm.HrOpenService (&svc, c_szSvcDnsServer, NO_LOCK,
  333. SC_MANAGER_CONNECT, SERVICE_QUERY_STATUS);
  334. if(SUCCEEDED(hr))
  335. {
  336. NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_TCPIP_DNS_EMPTY,
  337. MB_OK | MB_APPLMODAL | MB_ICONEXCLAMATION);
  338. }
  339. }
  340. if (!IsModified())
  341. {
  342. ::SetWindowLongPtr(m_hWnd, DWLP_MSGRESULT, nResult);
  343. return nResult;
  344. }
  345. m_ptcpip->SetSecondMemoryModified();
  346. SetModifiedTo(FALSE); // this page is no longer modified
  347. ::SetWindowLongPtr(m_hWnd, DWLP_MSGRESULT, nResult);
  348. return nResult;
  349. }
  350. LRESULT CTcpAddrPage::OnCancel(int idCtrl, LPNMHDR pnmh, BOOL& fHandled)
  351. {
  352. return 0;
  353. }
  354. LRESULT CTcpAddrPage::OnDhcpButton(WORD wNotifyCode, WORD wID,
  355. HWND hWndCtl, BOOL& fHandled)
  356. {
  357. switch(wNotifyCode)
  358. {
  359. case BN_CLICKED:
  360. case BN_DOUBLECLICKED:
  361. if (!m_pAdapterInfo->m_fEnableDhcp) // if Dhcp was disabled
  362. {
  363. // turn on DHCP button and disable the ip and subnet controls
  364. m_pAdapterInfo->m_fEnableDhcp = TRUE;
  365. EnableGroup(m_pAdapterInfo->m_fEnableDhcp);
  366. PageModified();
  367. FreeCollectionAndItem(m_pAdapterInfo->m_vstrIpAddresses);
  368. m_ipAddress.ClearAddress();
  369. if (m_ConnType == CONNECTION_LAN)
  370. {
  371. FreeCollectionAndItem(m_pAdapterInfo->m_vstrSubnetMask);
  372. FreeCollectionAndItem(m_pAdapterInfo->m_vstrDefaultGateway);
  373. FreeCollectionAndItem(m_pAdapterInfo->m_vstrDefaultGatewayMetric);
  374. m_ipSubnetMask.ClearAddress();
  375. m_ipDefGateway.ClearAddress();
  376. }
  377. } // if !m_pAdapterInfo->m_fEnableDhcp
  378. break;
  379. } // switch
  380. return 0;
  381. }
  382. LRESULT CTcpAddrPage::OnFixedButton(WORD wNotifyCode, WORD wID, HWND hWndCtl,
  383. BOOL& fHandled)
  384. {
  385. switch(wNotifyCode)
  386. {
  387. case BN_CLICKED:
  388. case BN_DOUBLECLICKED:
  389. if (m_pAdapterInfo->m_fEnableDhcp)
  390. {
  391. PageModified();
  392. // turn off DHCP button and enable the ip and subnet controls
  393. m_pAdapterInfo->m_fEnableDhcp = FALSE;
  394. EnableGroup(m_pAdapterInfo->m_fEnableDhcp);
  395. }
  396. break;
  397. } // switch
  398. return 0;
  399. }
  400. LRESULT CTcpAddrPage::OnDnsDhcp(WORD wNotifyCode, WORD wID,
  401. HWND hWndCtl, BOOL& fHandled)
  402. {
  403. switch(wNotifyCode)
  404. {
  405. case BN_CLICKED:
  406. case BN_DOUBLECLICKED:
  407. PageModified();
  408. FreeCollectionAndItem(m_pAdapterInfo->m_vstrDnsServerList);
  409. m_ipDnsPrimary.ClearAddress();
  410. m_ipDnsSecondary.ClearAddress();
  411. EnableStaticDns(FALSE);
  412. break;
  413. } // switch
  414. return 0;
  415. }
  416. LRESULT CTcpAddrPage::OnDnsFixed(WORD wNotifyCode, WORD wID,
  417. HWND hWndCtl, BOOL& fHandled)
  418. {
  419. switch(wNotifyCode)
  420. {
  421. case BN_CLICKED:
  422. case BN_DOUBLECLICKED:
  423. PageModified();
  424. EnableStaticDns(TRUE);
  425. ::SetFocus(GetDlgItem(IDC_DNS_PRIMARY));
  426. break;
  427. } // switch
  428. return 0;
  429. }
  430. LRESULT CTcpAddrPage::OnAdvancedButton(WORD wNotifyCode, WORD wID,
  431. HWND hWndCtl, BOOL& fHandled)
  432. {
  433. switch (wNotifyCode)
  434. {
  435. case BN_CLICKED:
  436. case BN_DOUBLECLICKED:
  437. BOOL fErr = FALSE;
  438. if (m_ConnType == CONNECTION_LAN)
  439. {
  440. // check inconsistency between ip address & subnet mask
  441. if (m_ipAddress.IsBlank() && !m_ipSubnetMask.IsBlank())
  442. {
  443. NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_INVALID_NO_IP,
  444. MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK);
  445. ::SetFocus(m_ipAddress);
  446. fErr = TRUE;
  447. }
  448. else if (!m_ipAddress.IsBlank() && m_ipSubnetMask.IsBlank())
  449. {
  450. NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_INVALID_NOSUBNET,
  451. MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK);
  452. ::SetFocus(m_ipSubnetMask);
  453. fErr = TRUE;
  454. }
  455. }
  456. if (!m_ipDnsPrimary.IsBlank() && !m_ipDnsSecondary.IsBlank())
  457. {
  458. tstring strPrimaryDns;
  459. tstring strSecondDns;
  460. m_ipDnsPrimary.GetAddress(&strPrimaryDns);
  461. m_ipDnsSecondary.GetAddress(&strSecondDns);
  462. if (strPrimaryDns == strSecondDns)
  463. {
  464. NcMsgBox(m_hWnd, IDS_MSFT_TCP_TEXT, IDS_DUP_SECOND_DNS,
  465. MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK);
  466. ::SetFocus(m_ipDnsSecondary);
  467. fErr = TRUE;
  468. }
  469. }
  470. if (!fErr)
  471. {
  472. // update our in memory structure with what's in the controls
  473. UpdateInfo();
  474. // Bring up the advanced pages
  475. ADAPTER_INFO adapterInfo;
  476. adapterInfo = *m_pAdapterInfo;
  477. GLOBAL_INFO glbInfo;
  478. glbInfo = *(m_ptcpip->GetGlobalInfo());
  479. int iRet = DoPropertySheet(&adapterInfo, &glbInfo);
  480. if (iRet != -1)
  481. {
  482. if (m_fPropShtOk && m_fPropShtModified)
  483. {
  484. // Something changed, so mark the page as modified
  485. PageModified();
  486. // Reset values
  487. m_fPropShtOk = FALSE;
  488. m_fPropShtModified = FALSE;
  489. // Update second memory info structure
  490. *m_pAdapterInfo = adapterInfo;
  491. GLOBAL_INFO * pGlbInfo = m_ptcpip->GetGlobalInfo();
  492. *pGlbInfo = glbInfo;
  493. }
  494. }
  495. // Update the controls with new data
  496. SetInfo();
  497. }
  498. break;
  499. }
  500. return 0;
  501. }
  502. //Show or Hide the backup configuration page depend on the
  503. //current settings of dhcp vs static
  504. void CTcpAddrPage::ShowOrHideBackupPage()
  505. {
  506. if (IsDlgButtonChecked(IDC_IP_DHCP) || IsDlgButtonChecked(IDC_DNS_DHCP))
  507. {
  508. //show the backup configuration page
  509. if (NULL == m_hBackupPage)
  510. {
  511. m_hBackupPage = m_pageBackup.CreatePage(IDD_BACK_UP, 0);
  512. Assert(m_hBackupPage);
  513. if (m_hBackupPage)
  514. {
  515. ::SendMessage(GetParent(), PSM_ADDPAGE, 0, (LPARAM) m_hBackupPage);
  516. }
  517. }
  518. }
  519. else
  520. {
  521. //hide the backup configuration page
  522. if (NULL != m_hBackupPage)
  523. {
  524. ::SendMessage(GetParent(), PSM_REMOVEPAGE, 1, (LPARAM) m_hBackupPage);
  525. m_hBackupPage = NULL;
  526. }
  527. }
  528. }
  529. int CTcpAddrPage::DoPropertySheet(ADAPTER_INFO * pAdapterDlg,
  530. GLOBAL_INFO * pGlbDlg)
  531. {
  532. Assert(pAdapterDlg);
  533. Assert(pGlbDlg);
  534. HRESULT hr = S_OK;
  535. int iRet = -1;
  536. HPROPSHEETPAGE *ahpsp = NULL;
  537. int cPages = 0;
  538. // Create property pages
  539. // ahpsp is allocated memory by CoTaskMemAlloc
  540. hr = HrSetupPropPages(pAdapterDlg, pGlbDlg, &ahpsp, &cPages);
  541. if (SUCCEEDED(hr))
  542. {
  543. // Show the property sheet
  544. PROPSHEETHEADER psh = {0};
  545. psh.dwSize = sizeof(PROPSHEETHEADER);
  546. psh.dwFlags = PSH_NOAPPLYNOW;
  547. psh.hwndParent = ::GetActiveWindow();
  548. psh.hInstance = _Module.GetModuleInstance();
  549. psh.pszIcon = NULL;
  550. psh.pszCaption = (PWSTR)SzLoadIds(IDS_TCP_ADV_HEADER);
  551. psh.nPages = cPages;
  552. psh.phpage = ahpsp;
  553. iRet = PropertySheet(&psh);
  554. if (-1 == iRet)
  555. {
  556. DWORD dwError = GetLastError();
  557. TraceError("CTcpAddrPage::DoPropertySheet", HRESULT_FROM_WIN32(dwError));
  558. }
  559. }
  560. if (m_pIpSettingsPage)
  561. {
  562. delete m_pIpSettingsPage;
  563. m_pIpSettingsPage = NULL;
  564. }
  565. if (m_pTcpDnsPage)
  566. {
  567. delete m_pTcpDnsPage;
  568. m_pTcpDnsPage = NULL;
  569. }
  570. if (m_pTcpWinsPage)
  571. {
  572. delete m_pTcpWinsPage;
  573. m_pTcpWinsPage = NULL;
  574. }
  575. if (m_pAtmArpcPage)
  576. {
  577. delete m_pAtmArpcPage;
  578. m_pAtmArpcPage = NULL;
  579. }
  580. if (m_pTcpOptionsPage)
  581. {
  582. delete m_pTcpOptionsPage;
  583. m_pTcpOptionsPage = NULL;
  584. }
  585. if (m_pTcpRasPage)
  586. {
  587. delete m_pTcpRasPage;
  588. m_pTcpRasPage = NULL;
  589. }
  590. if (ahpsp)
  591. CoTaskMemFree(ahpsp);
  592. return iRet;
  593. }
  594. HRESULT CTcpAddrPage::HrSetupPropPages( ADAPTER_INFO * pAdapterDlg,
  595. GLOBAL_INFO * pGlbDlg,
  596. HPROPSHEETPAGE ** pahpsp, INT * pcPages)
  597. {
  598. HRESULT hr = S_OK;
  599. // initialize output parameters
  600. int cPages = 0;
  601. HPROPSHEETPAGE *ahpsp = NULL;
  602. // Set up the property pages
  603. cPages = 4;
  604. if (m_ConnType == CONNECTION_LAN)
  605. {
  606. m_pIpSettingsPage = new CIpSettingsPage(this, pAdapterDlg,
  607. g_aHelpIDs_IDD_IPADDR_ADV);
  608. if (m_pIpSettingsPage == NULL)
  609. {
  610. CORg(E_OUTOFMEMORY);
  611. }
  612. }
  613. else
  614. {
  615. m_pTcpRasPage = new CTcpRasPage(this, pAdapterDlg, g_aHelpIDs_IDD_OPT_RAS);
  616. if (m_pTcpRasPage == NULL)
  617. {
  618. CORg(E_OUTOFMEMORY);
  619. }
  620. }
  621. m_pTcpDnsPage = new CTcpDnsPage(this, pAdapterDlg,
  622. pGlbDlg, g_aHelpIDs_IDD_TCP_DNS);
  623. m_pTcpWinsPage = new CTcpWinsPage(m_ptcpip, this, pAdapterDlg,
  624. pGlbDlg, g_aHelpIDs_IDD_TCP_WINS);
  625. if ((m_pTcpDnsPage == NULL) ||
  626. (m_pTcpWinsPage == NULL))
  627. {
  628. CORg(E_OUTOFMEMORY);
  629. }
  630. if (pAdapterDlg->m_fIsAtmAdapter)
  631. {
  632. m_pAtmArpcPage = new CAtmArpcPage(this, pAdapterDlg,
  633. g_aHelpIDs_IDD_ATM_ARPC);
  634. if (m_pAtmArpcPage == NULL)
  635. {
  636. CORg(E_OUTOFMEMORY);
  637. }
  638. cPages++;
  639. }
  640. //After removing the IPSec connection UI, there are no options to
  641. //put in the option tab. So we just go ahead remove it.
  642. if (!pAdapterDlg->m_fIsRasFakeAdapter)
  643. {
  644. m_pTcpOptionsPage = new CTcpOptionsPage(this, pAdapterDlg, pGlbDlg,
  645. g_aHelpIDs_IDD_TCP_OPTIONS);
  646. if (m_pTcpOptionsPage == NULL)
  647. {
  648. CORg(E_OUTOFMEMORY);
  649. }
  650. }
  651. else
  652. {
  653. //we remove the option tab for the ras connections
  654. cPages--;
  655. }
  656. // Allocate a buffer large enough to hold the handles to all of our
  657. // property pages.
  658. ahpsp = (HPROPSHEETPAGE *)CoTaskMemAlloc(sizeof(HPROPSHEETPAGE)
  659. * cPages);
  660. if (!ahpsp)
  661. {
  662. CORg(E_OUTOFMEMORY);
  663. }
  664. cPages =0;
  665. if (m_ConnType == CONNECTION_LAN)
  666. {
  667. ahpsp[cPages++] = m_pIpSettingsPage->CreatePage(IDD_IPADDR_ADV, 0);
  668. }
  669. else
  670. {
  671. ahpsp[cPages++] = m_pTcpRasPage->CreatePage(IDD_OPT_RAS, 0);
  672. }
  673. ahpsp[cPages++] = m_pTcpDnsPage->CreatePage(IDD_TCP_DNS, 0);
  674. ahpsp[cPages++] = m_pTcpWinsPage->CreatePage(IDD_TCP_WINS, 0);
  675. if (pAdapterDlg->m_fIsAtmAdapter)
  676. {
  677. ahpsp[cPages++] = m_pAtmArpcPage->CreatePage(IDD_ATM_ARPC, 0);
  678. }
  679. if (!pAdapterDlg->m_fIsRasFakeAdapter && m_pTcpOptionsPage)
  680. {
  681. ahpsp[cPages++] = m_pTcpOptionsPage->CreatePage(IDD_TCP_OPTIONS, 0);
  682. }
  683. *pahpsp = ahpsp;
  684. *pcPages = cPages;
  685. Error:
  686. if (FAILED(hr))
  687. {
  688. if (m_pIpSettingsPage)
  689. {
  690. delete m_pIpSettingsPage;
  691. m_pIpSettingsPage = NULL;
  692. }
  693. if (m_pTcpDnsPage)
  694. {
  695. delete m_pTcpDnsPage;
  696. m_pTcpDnsPage = NULL;
  697. }
  698. if (m_pTcpWinsPage)
  699. {
  700. delete m_pTcpWinsPage;
  701. m_pTcpWinsPage = NULL;
  702. }
  703. if (m_pAtmArpcPage)
  704. {
  705. delete m_pAtmArpcPage;
  706. m_pAtmArpcPage = NULL;
  707. }
  708. if (m_pTcpOptionsPage)
  709. {
  710. delete m_pTcpOptionsPage;
  711. m_pTcpOptionsPage = NULL;
  712. }
  713. if (m_pTcpRasPage)
  714. {
  715. delete m_pTcpRasPage;
  716. m_pTcpRasPage = NULL;
  717. }
  718. }
  719. return hr;
  720. }
  721. LRESULT CTcpAddrPage::OnIpAddrIp(WORD wNotifyCode, WORD wID,
  722. HWND hWndCtl, BOOL& fHandled)
  723. {
  724. switch (wNotifyCode)
  725. {
  726. case EN_CHANGE:
  727. PageModified();
  728. break;
  729. }
  730. return 0;
  731. }
  732. LRESULT CTcpAddrPage::OnIpAddrSub(WORD wNotifyCode, WORD wID,
  733. HWND hWndCtl, BOOL& fHandled)
  734. {
  735. switch (wNotifyCode)
  736. {
  737. case EN_CHANGE:
  738. PageModified();
  739. break;
  740. case EN_SETFOCUS:
  741. // if the subnet mask is blank, create a mask and insert it into
  742. // the control
  743. if (!m_ipAddress.IsBlank() && m_ipSubnetMask.IsBlank())
  744. {
  745. tstring strSubnetMask;
  746. tstring strIpAddress;
  747. m_ipAddress.GetAddress(&strIpAddress);
  748. // generate the mask and update the control, and internal structure
  749. GenerateSubnetMask(m_ipAddress, &strSubnetMask);
  750. m_ipSubnetMask.SetAddress(strSubnetMask.c_str());
  751. ReplaceFirstAddress(&(m_pAdapterInfo->m_vstrSubnetMask),
  752. strSubnetMask.c_str());
  753. }
  754. break;
  755. }
  756. return 0;
  757. }
  758. LRESULT CTcpAddrPage::OnIpAddrGateway(WORD wNotifyCode, WORD wID,
  759. HWND hWndCtl, BOOL& fHandled)
  760. {
  761. switch (wNotifyCode)
  762. {
  763. case EN_CHANGE:
  764. PageModified();
  765. break;
  766. }
  767. return 0;
  768. }
  769. LRESULT CTcpAddrPage::OnDnsPrimary(WORD wNotifyCode, WORD wID,
  770. HWND hWndCtl, BOOL& fHandled)
  771. {
  772. switch (wNotifyCode)
  773. {
  774. case EN_CHANGE:
  775. PageModified();
  776. break;
  777. }
  778. return 0;
  779. }
  780. LRESULT CTcpAddrPage::OnDnsSecondary(WORD wNotifyCode, WORD wID,
  781. HWND hWndCtl, BOOL& fHandled)
  782. {
  783. switch (wNotifyCode)
  784. {
  785. case EN_CHANGE:
  786. PageModified();
  787. break;
  788. }
  789. return 0;
  790. }
  791. LRESULT CTcpAddrPage::OnIpFieldChange(int idCtrl, LPNMHDR pnmh, BOOL& fHandled)
  792. {
  793. LPNMIPADDRESS lpnmipa;
  794. int iLow = c_iIpLow;
  795. int iHigh = c_iIpHigh;
  796. switch(idCtrl)
  797. {
  798. case IDC_IPADDR_IP:
  799. case IDC_IPADDR_GATE:
  800. case IDC_DNS_PRIMARY:
  801. case IDC_DNS_SECONDARY:
  802. lpnmipa = (LPNMIPADDRESS) pnmh;
  803. if (0==lpnmipa->iField)
  804. {
  805. iLow = c_iIPADDR_FIELD_1_LOW;
  806. iHigh = c_iIPADDR_FIELD_1_HIGH;
  807. };
  808. IpCheckRange(lpnmipa,
  809. m_hWnd,
  810. iLow,
  811. iHigh,
  812. (IDC_IPADDR_IP == idCtrl || IDC_IPADDR_GATE == idCtrl));
  813. break;
  814. case IDC_IPADDR_SUB:
  815. lpnmipa = (LPNMIPADDRESS) pnmh;
  816. IpCheckRange(lpnmipa, m_hWnd, iLow, iHigh);
  817. break;
  818. default:
  819. break;
  820. }
  821. return 0;
  822. }
  823. void CTcpAddrPage::EnableGroup(BOOL fEnableDhcp)
  824. {
  825. BOOL fStaticIp = !fEnableDhcp;
  826. CheckDlgButton(IDC_IP_DHCP, fEnableDhcp);
  827. CheckDlgButton(IDC_IP_FIXED, fStaticIp);
  828. ::EnableWindow(GetDlgItem(IDC_IPADDR_IPTEXT), fStaticIp);
  829. ::EnableWindow(GetDlgItem(IDC_IPADDR_IP), fStaticIp);
  830. if (m_ConnType == CONNECTION_LAN)
  831. {
  832. ::EnableWindow(GetDlgItem(IDC_IPADDR_SUBTEXT), fStaticIp);
  833. ::EnableWindow(GetDlgItem(IDC_IPADDR_SUB), fStaticIp);
  834. ::EnableWindow(GetDlgItem(IDC_IPADDR_GATE), fStaticIp);
  835. ::EnableWindow(GetDlgItem(IDC_IPADDR_GATETEXT), fStaticIp);
  836. }
  837. if (!fEnableDhcp) // enforce DNS address option
  838. {
  839. CheckDlgButton(IDC_DNS_DHCP, FALSE);
  840. CheckDlgButton(IDC_DNS_FIXED, TRUE);
  841. ::EnableWindow(GetDlgItem(IDC_DNS_DHCP), FALSE);
  842. EnableStaticDns(TRUE);
  843. }
  844. else
  845. {
  846. ::EnableWindow(GetDlgItem(IDC_DNS_DHCP), TRUE);
  847. }
  848. if (CONNECTION_LAN == m_ConnType)
  849. {
  850. ShowOrHideBackupPage();
  851. }
  852. }
  853. void CTcpAddrPage::EnableStaticDns(BOOL fUseStaticDns)
  854. {
  855. ::EnableWindow(GetDlgItem(IDC_DNS_PRIMARY), fUseStaticDns);
  856. ::EnableWindow(GetDlgItem(IDC_DNS_PRIMARY_TEXT), fUseStaticDns);
  857. ::EnableWindow(GetDlgItem(IDC_DNS_SECONDARY), fUseStaticDns);
  858. ::EnableWindow(GetDlgItem(IDC_DNS_SECONDARY_TEXT), fUseStaticDns);
  859. }
  860. // Set info to controls using the data in m_pAdapterInfo
  861. void CTcpAddrPage::SetInfo()
  862. {
  863. Assert(m_pAdapterInfo);
  864. // Dhcp Ip address is not allowed when Dhcp server is installed or
  865. // it is a SLIP connection
  866. // const GLOBAL_INFO * pglb = m_ptcpip->GetConstGlobalInfo();
  867. // if ((pglb->m_fDhcpServerInstalled) || (m_ConnType == CONNECTION_RAS_SLIP))
  868. if (m_ConnType == CONNECTION_RAS_SLIP)
  869. {
  870. ::EnableWindow(GetDlgItem(IDC_IP_DHCP), FALSE);
  871. m_pAdapterInfo->m_fEnableDhcp = 0;
  872. }
  873. EnableGroup(m_pAdapterInfo->m_fEnableDhcp);
  874. // Set Ip address
  875. if(m_pAdapterInfo->m_fEnableDhcp == 0) //Dhcp disabled, static IP
  876. {
  877. tstring strTmp;
  878. if (fQueryFirstAddress(m_pAdapterInfo->m_vstrIpAddresses, &strTmp))
  879. m_ipAddress.SetAddress(strTmp.c_str());
  880. else
  881. m_ipAddress.ClearAddress();
  882. }
  883. else //Dhcp enabled
  884. {
  885. m_ipAddress.ClearAddress();
  886. FreeCollectionAndItem(m_pAdapterInfo->m_vstrIpAddresses);
  887. }
  888. // Set Subnet mask and default gateway if Lan connection
  889. if (m_ConnType == CONNECTION_LAN)
  890. {
  891. if(m_pAdapterInfo->m_fEnableDhcp == 0) //Dhcp disabled, static IP
  892. {
  893. tstring strTmp;
  894. if (fQueryFirstAddress(m_pAdapterInfo->m_vstrSubnetMask, &strTmp))
  895. m_ipSubnetMask.SetAddress(strTmp.c_str());
  896. else
  897. m_ipSubnetMask.ClearAddress();
  898. if (fQueryFirstAddress(m_pAdapterInfo->m_vstrDefaultGateway, &strTmp))
  899. m_ipDefGateway.SetAddress(strTmp.c_str());
  900. else
  901. m_ipDefGateway.ClearAddress();
  902. }
  903. else //Dhcp enabled
  904. {
  905. m_ipSubnetMask.ClearAddress();
  906. FreeCollectionAndItem(m_pAdapterInfo->m_vstrSubnetMask);
  907. tstring strGateway;
  908. if (fQueryFirstAddress(m_pAdapterInfo->m_vstrDefaultGateway, &strGateway))
  909. m_ipDefGateway.SetAddress(strGateway.c_str());
  910. else
  911. m_ipDefGateway.ClearAddress();
  912. }
  913. }
  914. // Set Dns addresses
  915. BOOL fUseStaticDns = ((!m_pAdapterInfo->m_fEnableDhcp) ||
  916. (m_pAdapterInfo->m_vstrDnsServerList.size() >0));
  917. CheckDlgButton(IDC_DNS_DHCP, !fUseStaticDns);
  918. CheckDlgButton(IDC_DNS_FIXED, fUseStaticDns);
  919. EnableStaticDns(fUseStaticDns);
  920. if (fUseStaticDns)
  921. {
  922. tstring strTmp;
  923. if (fQueryFirstAddress(m_pAdapterInfo->m_vstrDnsServerList, &strTmp))
  924. m_ipDnsPrimary.SetAddress(strTmp.c_str());
  925. else
  926. m_ipDnsPrimary.ClearAddress();
  927. if (fQuerySecondAddress(m_pAdapterInfo->m_vstrDnsServerList, &strTmp))
  928. m_ipDnsSecondary.SetAddress(strTmp.c_str());
  929. else
  930. m_ipDnsSecondary.ClearAddress();
  931. }
  932. else
  933. {
  934. m_ipDnsPrimary.ClearAddress();
  935. m_ipDnsSecondary.ClearAddress();
  936. }
  937. }
  938. // Update info in m_pAdapterInfo with what's in the controls
  939. void CTcpAddrPage::UpdateInfo()
  940. {
  941. Assert(m_pAdapterInfo);
  942. if (!m_pAdapterInfo->m_fEnableDhcp) // If DHCP disabled
  943. {
  944. tstring strNewAddress;
  945. // ip address & subnet mask
  946. if (!m_ipAddress.IsBlank())
  947. {
  948. m_ipAddress.GetAddress(&strNewAddress);
  949. ReplaceFirstAddress(&(m_pAdapterInfo->m_vstrIpAddresses),
  950. strNewAddress.c_str());
  951. if (m_ConnType == CONNECTION_LAN)
  952. {
  953. if (m_ipSubnetMask.IsBlank())
  954. {
  955. SendDlgItemMessage(IDC_IPADDR_SUB, WM_SETFOCUS, 0, 0);
  956. }
  957. else
  958. {
  959. m_ipSubnetMask.GetAddress(&strNewAddress);
  960. ReplaceFirstAddress(&(m_pAdapterInfo->m_vstrSubnetMask),
  961. strNewAddress.c_str());
  962. }
  963. }
  964. }
  965. else // no ip address
  966. {
  967. if (m_ConnType == CONNECTION_LAN)
  968. {
  969. if (m_ipSubnetMask.IsBlank())
  970. {
  971. // delete the first ip address and subnet mask
  972. if (m_pAdapterInfo->m_vstrIpAddresses.size())
  973. {
  974. FreeVectorItem(m_pAdapterInfo->m_vstrIpAddresses, 0);
  975. if (!m_pAdapterInfo->m_vstrIpAddresses.empty())
  976. m_ipAddress.SetAddress(m_pAdapterInfo->m_vstrIpAddresses[0]->c_str());
  977. if (m_pAdapterInfo->m_vstrSubnetMask.size())
  978. {
  979. FreeVectorItem(m_pAdapterInfo->m_vstrSubnetMask, 0);
  980. if (!m_pAdapterInfo->m_vstrSubnetMask.empty())
  981. m_ipSubnetMask.SetAddress(m_pAdapterInfo->m_vstrSubnetMask[0]->c_str());
  982. }
  983. }
  984. }
  985. else
  986. {
  987. AssertSz(FALSE, "No ip address.");
  988. }
  989. }
  990. else // RAS connection, simply delete IP address
  991. {
  992. if (m_pAdapterInfo->m_vstrIpAddresses.size())
  993. {
  994. FreeVectorItem(m_pAdapterInfo->m_vstrIpAddresses, 0);
  995. }
  996. }
  997. }
  998. // default gateway
  999. if (m_ConnType == CONNECTION_LAN)
  1000. {
  1001. if (!m_ipDefGateway.IsBlank())
  1002. {
  1003. m_ipDefGateway.GetAddress(&strNewAddress);
  1004. ReplaceFirstAddress(&(m_pAdapterInfo->m_vstrDefaultGateway),
  1005. strNewAddress.c_str());
  1006. int iSize = m_pAdapterInfo->m_vstrDefaultGatewayMetric.size();
  1007. if (m_pAdapterInfo->m_vstrDefaultGatewayMetric.size() == 0)
  1008. {
  1009. WCHAR buf[IP_LIMIT];
  1010. //if there is no default gateway before (that's the reason metric list is
  1011. //empty), we add the default metric for it
  1012. _ltot(c_dwDefaultMetricOfGateway, buf, 10);
  1013. m_pAdapterInfo->m_vstrDefaultGatewayMetric.push_back(new tstring(buf));
  1014. }
  1015. }
  1016. else
  1017. {
  1018. if (m_pAdapterInfo->m_vstrDefaultGateway.size() >0)
  1019. {
  1020. FreeVectorItem(m_pAdapterInfo->m_vstrDefaultGateway, 0);
  1021. if (!m_pAdapterInfo->m_vstrDefaultGateway.empty())
  1022. m_ipDefGateway.SetAddress(m_pAdapterInfo->m_vstrDefaultGateway[0]->c_str());
  1023. if (m_pAdapterInfo->m_vstrDefaultGatewayMetric.size() >0)
  1024. FreeVectorItem(m_pAdapterInfo->m_vstrDefaultGatewayMetric, 0);
  1025. }
  1026. }
  1027. }
  1028. }
  1029. // DNS addresses
  1030. UpdateAddressList(&(m_pAdapterInfo->m_vstrDnsServerList),
  1031. m_ipDnsPrimary, m_ipDnsSecondary);
  1032. }
  1033. // Update a vector of strings with values from two IP address
  1034. // controls
  1035. void CTcpAddrPage::UpdateAddressList(VSTR * pvstrList,
  1036. IpControl& ipPrimary,
  1037. IpControl& ipSecondary)
  1038. {
  1039. tstring str;
  1040. if (pvstrList->size()<=2) // if the list did not have more than two addresses
  1041. {
  1042. // Free the list
  1043. FreeCollectionAndItem(*pvstrList);
  1044. // Insert new addresses if any
  1045. if (!ipPrimary.IsBlank())
  1046. {
  1047. ipPrimary.GetAddress(&str);
  1048. pvstrList->push_back(new tstring(str.c_str()));
  1049. }
  1050. if (!ipSecondary.IsBlank())
  1051. {
  1052. ipSecondary.GetAddress(&str);
  1053. pvstrList->push_back(new tstring(str.c_str()));
  1054. }
  1055. }
  1056. else
  1057. {
  1058. // Replace addresses if they exists
  1059. if (!ipSecondary.IsBlank())
  1060. {
  1061. ipSecondary.GetAddress(&str);
  1062. ReplaceSecondAddress(pvstrList, str.c_str());
  1063. }
  1064. else
  1065. {
  1066. FreeVectorItem(*pvstrList, 1);
  1067. }
  1068. if (!ipPrimary.IsBlank())
  1069. {
  1070. ipPrimary.GetAddress(&str);
  1071. ReplaceFirstAddress(pvstrList, str.c_str());
  1072. }
  1073. else
  1074. {
  1075. FreeVectorItem(*pvstrList, 0);
  1076. }
  1077. //fix Bug 425112: Update the UI if either of the IP control
  1078. //is blank because sometimes UpdateInfo get called twice (which
  1079. // will make us delete the address twice if we dont update the UI)
  1080. if (ipPrimary.IsBlank() || ipSecondary.IsBlank())
  1081. {
  1082. if (!pvstrList->empty())
  1083. {
  1084. ipPrimary.SetAddress((*pvstrList)[0]->c_str());
  1085. }
  1086. if (pvstrList->size() >= 2)
  1087. {
  1088. ipSecondary.SetAddress((*pvstrList)[1]->c_str());
  1089. }
  1090. }
  1091. }
  1092. }