Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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