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.

1095 lines
31 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: T C P I P O B J . C P P
  7. //
  8. // Contents: TCP/IP notify object
  9. //
  10. // Notes:
  11. //
  12. // Author: tongl
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include "ncreg.h"
  18. #include "ncstl.h"
  19. #include "tcpconst.h"
  20. #include "tcpipobj.h"
  21. #include "tcputil.h"
  22. extern const WCHAR c_szBiNdisAtm[];
  23. extern const WCHAR c_szInfId_MS_NetBT[];
  24. extern const WCHAR c_szInfId_MS_NetBT_SMB[];
  25. HICON g_hiconUpArrow;
  26. HICON g_hiconDownArrow;
  27. // Constructor
  28. CTcpipcfg::CTcpipcfg()
  29. : m_ipaddr(NULL),
  30. m_pUnkContext(NULL),
  31. m_pnc(NULL),
  32. m_pnccTcpip(NULL),
  33. m_pTcpipPrivate(NULL),
  34. m_pnccWins(NULL),
  35. m_fRemoving(FALSE),
  36. m_fInstalling(FALSE),
  37. m_fUpgradeCleanupDnsKey(FALSE),
  38. m_fUpgradeGlobalDnsDomain(FALSE),
  39. m_pSecondMemoryAdapterInfo(NULL)
  40. { }
  41. //+---------------------------------------------------------------------------
  42. // INetCfgComponentControl
  43. //
  44. //+---------------------------------------------------------------------------
  45. // Member: CTcpipcfg::Initialize
  46. //
  47. STDMETHODIMP CTcpipcfg::Initialize(INetCfgComponent * pnccTcpip,
  48. INetCfg * pncNetCfg,
  49. BOOL fInstalling)
  50. {
  51. HRESULT hr = S_OK;
  52. Assert(pncNetCfg);
  53. Assert(pnccTcpip);
  54. m_fRemoving = FALSE;
  55. m_fInstalling = FALSE;
  56. m_fSaveRegistry = FALSE;
  57. m_ConnType = CONNECTION_UNSET;
  58. m_fReconfig = FALSE;
  59. // we havn't changed LmHost file
  60. m_fLmhostsFileSet = FALSE;
  61. // IPSec is removed from connection UI
  62. // we have not change ipsec policy
  63. //m_fIpsecPolicySet = FALSE;
  64. // by default, this should be an admin
  65. m_fRasNotAdmin = FALSE;
  66. m_fNoPopupsDuringPnp = FALSE;
  67. Validate_INetCfgNotify_Initialize(pnccTcpip, pncNetCfg, fInstalling);
  68. do // psudo loop ( so we don't use goto's on err )
  69. {
  70. // in case of Initialize called twice, for resurect the component
  71. ReleaseObj(m_pnc);
  72. m_pnc = NULL;
  73. ReleaseObj(m_pnccTcpip);
  74. m_pnccTcpip = NULL;
  75. ReleaseObj(m_pTcpipPrivate);
  76. m_pTcpipPrivate = NULL;
  77. ReleaseObj(m_pnccWins);
  78. m_pnccWins = NULL;
  79. // store reference to the INetCfg in our object
  80. m_pnc = pncNetCfg;
  81. m_pnc->AddRef();
  82. // Store a reference to the INetCfgComponent for tcpip in our object
  83. m_pnccTcpip = pnccTcpip;
  84. m_pnccTcpip->AddRef();
  85. hr = pnccTcpip->QueryInterface(
  86. IID_INetCfgComponentPrivate,
  87. reinterpret_cast<void**>(&m_pTcpipPrivate));
  88. if (FAILED(hr))
  89. break;
  90. // Get a copy of the WINS component and store in our object
  91. // NOTE: WINS client is not necessarily installed yet!
  92. // we also try to get a pointer at the Install sections
  93. hr = pncNetCfg->FindComponent(c_szInfId_MS_NetBT,
  94. &m_pnccWins);
  95. if (FAILED(hr))
  96. break;
  97. if (S_FALSE == hr) // NetBt not found
  98. {
  99. if (!fInstalling) // We are in trouble if NetBt is not there
  100. {
  101. TraceError("CTcpipcfg::Initialize - NetBt has not been installed yet", hr);
  102. break;
  103. }
  104. else // We are ok since tcpip will install netbt
  105. {
  106. hr = S_OK;
  107. }
  108. }
  109. // Set default global parameters
  110. hr = m_glbGlobalInfo.HrSetDefaults();
  111. if (FAILED(hr))
  112. break;
  113. // If tcpip is being installed, we don't have any cards to load
  114. if (!fInstalling)
  115. {
  116. // Get list of cards which are currently in the system + if they are bound
  117. hr = HrGetNetCards();
  118. if (SUCCEEDED(hr))
  119. {
  120. // Let's read parameters from registry
  121. hr = HrLoadSettings();
  122. }
  123. }
  124. } while(FALSE);
  125. // Have we got any bound cards ?
  126. m_fHasBoundCardOnInit = FHasBoundCard();
  127. if (SUCCEEDED(hr))
  128. {
  129. hr = S_OK;
  130. }
  131. Validate_INetCfgNotify_Initialize_Return(hr);
  132. TraceError("CTcpipcfg::Initialize", hr);
  133. return hr;
  134. }
  135. //+---------------------------------------------------------------------------
  136. // Member: CTcpipcfg::Validate
  137. //
  138. STDMETHODIMP CTcpipcfg::Validate()
  139. {
  140. return S_OK;
  141. }
  142. //+---------------------------------------------------------------------------
  143. // Member: CTcpipcfg::Cancel
  144. //
  145. STDMETHODIMP CTcpipcfg::CancelChanges()
  146. {
  147. // Note: first memory state is release in destructor
  148. // If the lmhosts file was set, we need to roll it back to the backup
  149. if (m_fLmhostsFileSet)
  150. {
  151. ResetLmhostsFile();
  152. m_fLmhostsFileSet = FALSE;
  153. }
  154. return S_OK;
  155. }
  156. //+---------------------------------------------------------------------------
  157. // Member: CTcpipcfg::ApplyRegistryChanges
  158. //
  159. STDMETHODIMP CTcpipcfg::ApplyRegistryChanges()
  160. {
  161. HRESULT hr = S_OK;
  162. HRESULT hrTmp = S_OK;
  163. if (m_fRemoving)
  164. {
  165. // (nsun) we should remove the Nt4 duplicate registry here because the cards
  166. // may have been marked as deleted
  167. hr = HrRemoveNt4DuplicateRegistry();
  168. ReleaseObj(m_pnccWins);
  169. m_pnccWins = NULL;
  170. // $REVIEW(tongl 9/29/97): Removing ServiceProvider value from registry
  171. // Remove "Tcpip" from the:
  172. // System\CurrentControlSet\Control\ServiceProvider\Order\ProviderOrder value
  173. hrTmp = ::HrRegRemoveStringFromMultiSz(c_szTcpip,
  174. HKEY_LOCAL_MACHINE,
  175. c_szSrvProvOrderKey,
  176. c_szProviderOrderVal,
  177. STRING_FLAG_REMOVE_ALL);
  178. if (SUCCEEDED(hr))
  179. hr = hrTmp;
  180. }
  181. else
  182. {
  183. // Cleanup the adapters marked as for deletion from the memory structure
  184. // Change made for #95637
  185. for(size_t i = 0 ; i < m_vcardAdapterInfo.size() ; ++i)
  186. {
  187. if (m_vcardAdapterInfo[i]->m_fDeleted)
  188. {
  189. //delete it
  190. FreeVectorItem(m_vcardAdapterInfo, i);
  191. i--; //move the pointer back ?
  192. }
  193. }
  194. if (m_fSaveRegistry)
  195. {
  196. // Save info in first memory state to registry
  197. // m_glbGlobalInfo and m_vcardAdapterInfo
  198. hrTmp = HrSaveSettings();
  199. if (SUCCEEDED(hr))
  200. hr = hrTmp;
  201. }
  202. else
  203. {
  204. // No change
  205. hr = S_FALSE;
  206. }
  207. }
  208. Validate_INetCfgNotify_Apply_Return(hr);
  209. TraceError("CTcpipcfg::ApplyRegistryChanges", (hr == S_FALSE) ? S_OK : hr);
  210. return hr;
  211. }
  212. //+---------------------------------------------------------------------------
  213. // Member: CTcpipcfg::ApplyPnpChanges
  214. //
  215. STDMETHODIMP CTcpipcfg::ApplyPnpChanges(IN INetCfgPnpReconfigCallback* pICallback)
  216. {
  217. HRESULT hr = S_OK;
  218. HRESULT hrTmp = S_OK;
  219. Assert(pICallback);
  220. if (!m_fRemoving)
  221. {
  222. if(!m_fInstalling)
  223. {
  224. if (m_fReconfig)
  225. {
  226. // Notify protocols/services of changes
  227. // Notify Tcpip of any changes in the IP Addresses
  228. hrTmp = HrNotifyDhcp();
  229. if (S_OK == hr)
  230. hr = hrTmp;
  231. // reconfig tcpip
  232. hrTmp = HrReconfigIp(pICallback);
  233. if (S_OK == hr)
  234. hr = hrTmp;
  235. // reconfig netbt
  236. hrTmp = HrReconfigNbt(pICallback);
  237. if (S_OK == hr)
  238. hr = hrTmp;
  239. // reconfig dns
  240. hrTmp = HrReconfigDns();
  241. if (S_OK == hr)
  242. hr = hrTmp;
  243. }
  244. if (IsBindOrderChanged())
  245. {
  246. //notify DNS cache of binding order changes
  247. hrTmp = HrReconfigDns(TRUE);
  248. if (S_OK == hr)
  249. hr = hrTmp;
  250. }
  251. }
  252. //IPSec is removed from connection UI
  253. // if (m_fIpsecPolicySet)
  254. // hrTmp = HrSetActiveIpsecPolicy();
  255. if (S_OK == hr)
  256. hr = hrTmp;
  257. }
  258. // Current state has been applied, reset the flags and
  259. // "Old" value of parameters
  260. if (S_OK == hr)
  261. {
  262. ReInitializeInternalState();
  263. }
  264. TraceError("CTcpipcfg::ApplyPnpChanges", hr);
  265. return hr;
  266. }
  267. //+---------------------------------------------------------------------------
  268. // INetCfgComponentSetUp
  269. //
  270. //+---------------------------------------------------------------------------
  271. // Member: CTcpipcfg::Install
  272. //
  273. STDMETHODIMP CTcpipcfg::Install(DWORD dwSetupFlags)
  274. {
  275. HRESULT hr;
  276. Validate_INetCfgNotify_Install(dwSetupFlags);
  277. m_fSaveRegistry = TRUE;
  278. m_fInstalling = TRUE;
  279. // Install the WINS client on behalf of TCPIP.
  280. Assert(!m_pnccWins);
  281. hr = HrInstallComponentOboComponent(m_pnc, NULL,
  282. GUID_DEVCLASS_NETTRANS,
  283. c_szInfId_MS_NetBT, m_pnccTcpip,
  284. &m_pnccWins);
  285. if (SUCCEEDED(hr))
  286. {
  287. Assert(m_pnccWins);
  288. hr = HrInstallComponentOboComponent(m_pnc, NULL,
  289. GUID_DEVCLASS_NETTRANS,
  290. c_szInfId_MS_NetBT_SMB, m_pnccTcpip,
  291. NULL);
  292. }
  293. TraceError("CTcpipcfg::Install", hr);
  294. return hr;
  295. }
  296. //+---------------------------------------------------------------------------
  297. // Member: CTcpipcfg::Upgrade
  298. //
  299. STDMETHODIMP CTcpipcfg::Upgrade(DWORD dwSetupFlags,
  300. DWORD dwUpgradeFomBuildNo )
  301. {
  302. HrCleanUpPerformRouterDiscoveryFromRegistry();
  303. HrUpdateNt4RegistryPermission();
  304. return S_FALSE;
  305. }
  306. //+---------------------------------------------------------------------------
  307. // Member: CTcpipcfg::ReadAnswerFile
  308. //
  309. // Purpose: Reads the appropriate fields from the given answer file into
  310. // our in-memory state.
  311. //
  312. // Arguments:
  313. // pszAnswerFile [in] Filename of answer file for upgrade.
  314. // pszAnswerSection [in] Comma-separated list of sections in the
  315. // file appropriate to this component.
  316. //
  317. // Returns: HRESULT, Error code.
  318. //
  319. // Author: tongl 7 May 1997
  320. //
  321. // Notes:
  322. //
  323. STDMETHODIMP CTcpipcfg::ReadAnswerFile( PCWSTR pszAnswerFile,
  324. PCWSTR pszAnswerSection)
  325. {
  326. m_fSaveRegistry = TRUE;
  327. if (pszAnswerFile && pszAnswerSection)
  328. {
  329. // Process answer file
  330. (void) HrProcessAnswerFile(pszAnswerFile, pszAnswerSection);
  331. }
  332. return S_OK;
  333. }
  334. //+---------------------------------------------------------------------------
  335. // Member: CTcpipcfg::Removing
  336. //
  337. STDMETHODIMP CTcpipcfg::Removing()
  338. {
  339. HRESULT hr;
  340. m_fRemoving = TRUE;
  341. // Remove NetBt protocol. This doesn't actually remove the
  342. // component, it simply marks it as needing to be removed,
  343. // and in Apply() it will be fully removed.
  344. hr = HrRemoveComponentOboComponent(
  345. m_pnc, GUID_DEVCLASS_NETTRANS,
  346. c_szInfId_MS_NetBT, m_pnccTcpip);
  347. if (SUCCEEDED(hr))
  348. {
  349. // remove NetBt_SMB
  350. hr = HrRemoveComponentOboComponent(
  351. m_pnc, GUID_DEVCLASS_NETTRANS,
  352. c_szInfId_MS_NetBT_SMB, m_pnccTcpip);
  353. }
  354. TraceError("CTcpipcfg::Removing", hr);
  355. return hr;
  356. }
  357. // INetCfgProperties
  358. STDMETHODIMP CTcpipcfg::SetContext(IUnknown * pUnk)
  359. {
  360. // release previous context, if any
  361. ReleaseObj(m_pUnkContext);
  362. m_pUnkContext = NULL;
  363. if (pUnk) // set the new context
  364. {
  365. m_pUnkContext = pUnk;
  366. m_pUnkContext->AddRef();
  367. }
  368. return S_OK;
  369. }
  370. STDMETHODIMP CTcpipcfg::MergePropPages(
  371. IN OUT DWORD* pdwDefPages,
  372. OUT LPBYTE* pahpspPrivate,
  373. OUT UINT* pcPages,
  374. IN HWND hwndParent,
  375. OUT PCWSTR* pszStartPage)
  376. {
  377. Validate_INetCfgProperties_MergePropPages (
  378. pdwDefPages, pahpspPrivate, pcPages, hwndParent, pszStartPage);
  379. // Initialize output parameter
  380. HPROPSHEETPAGE *ahpsp = NULL;
  381. int cPages = 0;
  382. // We don't want any default pages to be shown
  383. *pdwDefPages = 0;
  384. *pcPages = NULL;
  385. *pahpspPrivate = NULL;
  386. // get the connection context in which we are bringing up the UI
  387. HRESULT hr = HrSetConnectionContext();
  388. if (SUCCEEDED(hr))
  389. {
  390. AssertSz(((CONNECTION_LAN == m_ConnType)||
  391. (CONNECTION_RAS_PPP == m_ConnType)||
  392. (CONNECTION_RAS_SLIP == m_ConnType)||
  393. (CONNECTION_RAS_VPN == m_ConnType)),
  394. "How come we don't know the connection type yet on MergePropPages?");
  395. // Initialize the common controls library
  396. INITCOMMONCONTROLSEX icc;
  397. icc.dwSize = sizeof(icc);
  398. icc.dwICC = ICC_INTERNET_CLASSES;
  399. SideAssert(InitCommonControlsEx(&icc));
  400. hr = HrSetupPropSheets(&ahpsp, &cPages);
  401. if (SUCCEEDED(hr))
  402. {
  403. *pahpspPrivate = (LPBYTE)ahpsp;
  404. *pcPages = cPages;
  405. // Set the global up\down arrows
  406. if (!g_hiconUpArrow && !g_hiconDownArrow)
  407. {
  408. g_hiconUpArrow = (HICON)LoadImage(_Module.GetResourceInstance(),
  409. MAKEINTRESOURCE(IDI_UP_ARROW),
  410. IMAGE_ICON, 16, 16, 0);
  411. g_hiconDownArrow = (HICON)LoadImage(_Module.GetResourceInstance(),
  412. MAKEINTRESOURCE(IDI_DOWN_ARROW),
  413. IMAGE_ICON, 16, 16, 0);
  414. }
  415. }
  416. else
  417. {
  418. *pcPages = 0;
  419. CoTaskMemFree(ahpsp);
  420. }
  421. }
  422. Validate_INetCfgProperties_MergePropPages_Return(hr);
  423. TraceError("CTcpipcfg::MergePropPages", hr);
  424. return hr;
  425. }
  426. STDMETHODIMP CTcpipcfg::ValidateProperties(HWND hwndSheet)
  427. {
  428. return S_OK;
  429. }
  430. STDMETHODIMP CTcpipcfg::CancelProperties()
  431. {
  432. // If the lmhosts file was set, we need to roll it back to the backup
  433. if (m_fSecondMemoryLmhostsFileReset)
  434. {
  435. ResetLmhostsFile();
  436. }
  437. // Release second memory state
  438. ExitProperties();
  439. return S_OK;
  440. }
  441. STDMETHODIMP CTcpipcfg::ApplyProperties()
  442. {
  443. HRESULT hr = S_OK;
  444. if (!m_fReconfig)
  445. {
  446. m_fReconfig = m_fSecondMemoryModified ||
  447. m_fSecondMemoryLmhostsFileReset;
  448. //IPSec is removed from connection UI
  449. // || m_fSecondMemoryIpsecPolicySet;
  450. }
  451. if (!m_fLmhostsFileSet)
  452. m_fLmhostsFileSet = m_fSecondMemoryLmhostsFileReset;
  453. //IPSec is removed from connection UI
  454. //if (!m_fIpsecPolicySet)
  455. // m_fIpsecPolicySet = m_fSecondMemoryIpsecPolicySet;
  456. if (!m_fSaveRegistry)
  457. m_fSaveRegistry = m_fSecondMemoryModified;
  458. // Copy info from second memory state to first memory state
  459. if (m_fSecondMemoryModified)
  460. {
  461. m_glbGlobalInfo = m_glbSecondMemoryGlobalInfo;
  462. hr = HrSaveAdapterInfo();
  463. }
  464. // Release second memory state
  465. ExitProperties();
  466. Validate_INetCfgProperties_ApplyProperties_Return(hr);
  467. TraceError("CTcpipcfg::ApplyProperties", hr);
  468. return hr;
  469. }
  470. STDMETHODIMP CTcpipcfg::QueryBindingPath(DWORD dwChangeFlag,
  471. INetCfgBindingPath * pncbp)
  472. {
  473. HRESULT hr = S_OK;
  474. // If the binding is to an atm adapter (i.e. interface = ndisatm),
  475. // then return NETCFG_S_DISABLE_QUERY
  476. //
  477. if (dwChangeFlag & NCN_ADD)
  478. {
  479. INetCfgComponent* pnccLastComponent;
  480. PWSTR pszInterfaceName;
  481. hr = HrGetLastComponentAndInterface(pncbp,
  482. &pnccLastComponent,
  483. &pszInterfaceName);
  484. if (SUCCEEDED(hr))
  485. {
  486. // If adding an adapter through interface ndisatm,
  487. // we want to disable the binding interface since it's
  488. // the IP over ATM direct binding
  489. if (0 == lstrcmpW(c_szBiNdisAtm, pszInterfaceName))
  490. {
  491. hr = NETCFG_S_DISABLE_QUERY;
  492. }
  493. ReleaseObj (pnccLastComponent);
  494. CoTaskMemFree (pszInterfaceName);
  495. }
  496. }
  497. TraceError("CTcpipcfg::QueryBindingPath",
  498. (NETCFG_S_DISABLE_QUERY == hr) ? S_OK : hr);
  499. return hr;
  500. }
  501. STDMETHODIMP CTcpipcfg::NotifyBindingPath(
  502. DWORD dwChangeFlag,
  503. INetCfgBindingPath * pncbp)
  504. {
  505. Assert(!(dwChangeFlag & NCN_ADD && dwChangeFlag & NCN_REMOVE));
  506. Assert(!(dwChangeFlag & NCN_ENABLE && dwChangeFlag & NCN_DISABLE));
  507. // If we are told to add a card, we must be told at the same time whether the
  508. // binding is enabled or disabled
  509. Assert(FImplies((dwChangeFlag & NCN_ADD),
  510. ((dwChangeFlag & NCN_ENABLE)||(dwChangeFlag & NCN_DISABLE))));
  511. HRESULT hr = S_OK;
  512. Validate_INetCfgBindNotify_NotifyBindingPath(dwChangeFlag, pncbp);
  513. INetCfgComponent * pnccLastComponent;
  514. PWSTR pszInterfaceName;
  515. hr = HrGetLastComponentAndInterface(pncbp,
  516. &pnccLastComponent,
  517. &pszInterfaceName);
  518. if (SUCCEEDED(hr))
  519. {
  520. #if DBG
  521. GUID guidNetClass;
  522. hr = pnccLastComponent->GetClassGuid (&guidNetClass);
  523. AssertSz(
  524. SUCCEEDED(hr) &&
  525. IsEqualGUID(guidNetClass, GUID_DEVCLASS_NET),
  526. "Why the last component on the path is not an adapter?");
  527. #endif
  528. // If we are adding/removing cards, set m_fSaveRegistry
  529. // so we apply the changes to registry
  530. if (dwChangeFlag & (NCN_ADD | NCN_REMOVE))
  531. m_fSaveRegistry = TRUE;
  532. hr = HrAdapterBindNotify(pnccLastComponent,
  533. dwChangeFlag,
  534. pszInterfaceName);
  535. ReleaseObj (pnccLastComponent);
  536. CoTaskMemFree (pszInterfaceName);
  537. }
  538. if (SUCCEEDED(hr))
  539. hr = S_OK;
  540. Validate_INetCfgBindNotify_NotifyBindingPath_Return(hr);
  541. TraceError("CTcpipcfg::NotifyBindingPath", hr);
  542. return hr;
  543. }
  544. //+---------------------------------------------------------------------------
  545. // INetCfgComponentUpperEdge
  546. //
  547. // Return an array of interface ids for an adapter bound to
  548. // this component. If the specified adapter does not have explicit
  549. // interfaces exported from it, S_FALSE is returned.
  550. // pAdapter is the adapter in question.
  551. // pdwNumInterfaces is the address of a DWORD where the count of elements
  552. // returned via ppguidInterfaceIds is stored.
  553. // ppguidInterfaceIds is the address of a pointer where an allocated
  554. // block of memory is returned. This memory is an array of interface ids.
  555. // *ppguidInterfaceIds should be free with CoTaskMemFree if S_OK is returned.
  556. // if S_FALSE is returned, *pdwNumInterfaces and *ppguidInterfaceIds should
  557. // be NULL.
  558. //
  559. HRESULT
  560. CTcpipcfg::GetInterfaceIdsForAdapter (
  561. INetCfgComponent* pnccAdapter,
  562. DWORD* pdwNumInterfaces,
  563. GUID** ppguidInterfaceIds)
  564. {
  565. Assert (pnccAdapter);
  566. Assert (pdwNumInterfaces);
  567. HRESULT hr = S_FALSE;
  568. // Initialize output parameters.
  569. //
  570. *pdwNumInterfaces = 0;
  571. if (ppguidInterfaceIds)
  572. {
  573. *ppguidInterfaceIds = NULL;
  574. }
  575. ADAPTER_INFO* pAdapterInfo = PAdapterFromNetcfgComponent(pnccAdapter);
  576. if (pAdapterInfo &&
  577. pAdapterInfo->m_fIsWanAdapter &&
  578. pAdapterInfo->m_fIsMultipleIfaceMode)
  579. {
  580. hr = GetGuidArrayFromIfaceColWithCoTaskMemAlloc(
  581. pAdapterInfo->m_IfaceIds,
  582. ppguidInterfaceIds,
  583. pdwNumInterfaces);
  584. }
  585. TraceHr(ttidError, FAL, hr, (S_FALSE == hr),
  586. "CTcpipcfg::GetInterfaceIdsForAdapter");
  587. return hr;
  588. }
  589. // Add the specified number of new interfaces to the specified adapter.
  590. // The implementation will choose the interface ids.
  591. //
  592. HRESULT
  593. CTcpipcfg::AddInterfacesToAdapter (
  594. INetCfgComponent* pnccAdapter,
  595. DWORD dwNumInterfaces)
  596. {
  597. Assert (pnccAdapter);
  598. HRESULT hr = S_FALSE;
  599. ADAPTER_INFO* pAdapterInfo;
  600. if ((NULL == pnccAdapter) || (0 == dwNumInterfaces))
  601. {
  602. hr = E_INVALIDARG;
  603. goto end_AddInterfacesToAdapter;
  604. }
  605. pAdapterInfo = PAdapterFromNetcfgComponent(pnccAdapter);
  606. if (pAdapterInfo &&
  607. pAdapterInfo->m_fIsWanAdapter)
  608. {
  609. AddInterfacesToAdapterInfo(
  610. pAdapterInfo,
  611. dwNumInterfaces);
  612. pAdapterInfo->m_fIsMultipleIfaceMode = TRUE;
  613. pAdapterInfo->m_fNewlyChanged = TRUE;
  614. m_fSaveRegistry = TRUE;
  615. m_fReconfig = TRUE;
  616. // Notify the binding engine that our upper edge has changed.
  617. //
  618. (VOID)m_pTcpipPrivate->NotifyUpperEdgeConfigChange ();
  619. hr = S_OK;
  620. }
  621. end_AddInterfacesToAdapter:
  622. TraceErrorSkip1("CTcpipcfg::AddInterfacesToAdapter", hr, S_FALSE);
  623. return hr;
  624. }
  625. // Remove the specified interface ids from the specified adapter.
  626. // pguidInterfaceIds is the array of ids to be removed. dwNumInterfaces
  627. // is the count in that array.
  628. //
  629. HRESULT
  630. CTcpipcfg::RemoveInterfacesFromAdapter (
  631. INetCfgComponent* pnccAdapter,
  632. DWORD dwNumInterfaces,
  633. const GUID* pguidInterfaceIds)
  634. {
  635. Assert (pnccAdapter);
  636. Assert (pguidInterfaceIds);
  637. HRESULT hr = E_UNEXPECTED;
  638. ADAPTER_INFO* pAdapterInfo;
  639. if ((NULL == pnccAdapter) ||
  640. (0 == dwNumInterfaces) ||
  641. (NULL == pguidInterfaceIds))
  642. {
  643. hr = E_INVALIDARG;
  644. goto end_RemoveInterfacesFromAdapter;
  645. }
  646. pAdapterInfo = PAdapterFromNetcfgComponent(pnccAdapter);
  647. AssertSz( pAdapterInfo,
  648. "CTcpipcfg::AddInterfacesToAdapter cannot find the adapter "
  649. "GUID from the adapter list");
  650. if (pAdapterInfo &&
  651. pAdapterInfo->m_fIsWanAdapter &&
  652. pAdapterInfo->m_fIsMultipleIfaceMode)
  653. {
  654. DWORD dwNumRemoved = 0;
  655. IFACEITER iter;
  656. for (DWORD i = 0; i < dwNumInterfaces; i++)
  657. {
  658. iter = find(pAdapterInfo->m_IfaceIds.begin(),
  659. pAdapterInfo->m_IfaceIds.end(),
  660. pguidInterfaceIds[i]);
  661. if (iter != pAdapterInfo->m_IfaceIds.end())
  662. {
  663. pAdapterInfo->m_IfaceIds.erase(iter);
  664. dwNumRemoved++;
  665. }
  666. }
  667. //$REVIEW (nsun) mark the adapter as NewlyAdded so that we will re-write its adapter registry
  668. if (dwNumRemoved > 0)
  669. {
  670. pAdapterInfo->m_fNewlyChanged = TRUE;
  671. m_fSaveRegistry = TRUE;
  672. }
  673. // Notify the binding engine that our upper edge has changed.
  674. //
  675. (VOID)m_pTcpipPrivate->NotifyUpperEdgeConfigChange ();
  676. hr = (dwNumRemoved == dwNumInterfaces) ? S_OK : S_FALSE;
  677. }
  678. end_RemoveInterfacesFromAdapter:
  679. TraceError("CTcpipcfg::RemoveInterfacesFromAdapter", hr);
  680. return hr;
  681. }
  682. //+---------------------------------------------------------------------------
  683. // ITcpipProperties
  684. //
  685. // The following two methods are for remote tcpip configuration.
  686. /*
  687. typedef struct tagREMOTE_IPINFO
  688. {
  689. DWORD dwEnableDhcp;
  690. PWSTR pszIpAddrList;
  691. PWSTR pszSubnetMaskList;
  692. PWSTR pszOptionList;
  693. } REMOTE_IPINFO;
  694. */
  695. HRESULT CTcpipcfg::GetIpInfoForAdapter(const GUID* pguidAdapter,
  696. REMOTE_IPINFO** ppRemoteIpInfo)
  697. {
  698. Assert(pguidAdapter);
  699. Assert(ppRemoteIpInfo);
  700. // Initialize the output parameter.
  701. //
  702. *ppRemoteIpInfo = NULL;
  703. HRESULT hr = S_OK;
  704. ADAPTER_INFO* pAdapter = PAdapterFromInstanceGuid(pguidAdapter);
  705. if (pAdapter)
  706. {
  707. // get the strings from the list
  708. tstring strIpAddressList;
  709. ConvertColStringToString(pAdapter->m_vstrIpAddresses,
  710. c_chListSeparator,
  711. strIpAddressList);
  712. tstring strSubnetMaskList;
  713. ConvertColStringToString(pAdapter->m_vstrSubnetMask,
  714. c_chListSeparator,
  715. strSubnetMaskList);
  716. //bug 272647 add gateway metric and interface metric into REMOTE_IPINFO
  717. tstring strOptionList;
  718. ConstructOptionListString(pAdapter,
  719. strOptionList);
  720. // allocate buffer for the output param
  721. DWORD dwBytes = sizeof(REMOTE_IPINFO) +
  722. sizeof(WCHAR)*(strIpAddressList.length() + 1) +
  723. sizeof(WCHAR)*(strSubnetMaskList.length() + 1) +
  724. sizeof(WCHAR)*(strOptionList.length() + 1);
  725. PVOID pbBuf;
  726. hr = HrCoTaskMemAlloc(dwBytes, &pbBuf);
  727. if (SUCCEEDED(hr))
  728. {
  729. ZeroMemory(pbBuf, dwBytes);
  730. REMOTE_IPINFO * pRemoteIpInfo = reinterpret_cast<REMOTE_IPINFO *>(pbBuf);
  731. pRemoteIpInfo->dwEnableDhcp = pAdapter->m_fEnableDhcp;
  732. BYTE* pbByte = reinterpret_cast<BYTE*>(pbBuf);
  733. // ip address
  734. pbByte+= sizeof(REMOTE_IPINFO);
  735. pRemoteIpInfo->pszwIpAddrList = reinterpret_cast<WCHAR *>(pbByte);
  736. lstrcpyW(pRemoteIpInfo->pszwIpAddrList, strIpAddressList.c_str());
  737. // subnet mask
  738. pbByte += sizeof(WCHAR)*(strIpAddressList.length() + 1);
  739. pRemoteIpInfo->pszwSubnetMaskList = reinterpret_cast<WCHAR *>(pbByte);
  740. lstrcpyW(pRemoteIpInfo->pszwSubnetMaskList, strSubnetMaskList.c_str());
  741. // default gateway
  742. pbByte += sizeof(WCHAR)*(strSubnetMaskList.length() + 1);
  743. pRemoteIpInfo->pszwOptionList = reinterpret_cast<WCHAR *>(pbByte);
  744. lstrcpyW(pRemoteIpInfo->pszwOptionList, strOptionList.c_str());
  745. *ppRemoteIpInfo = pRemoteIpInfo;
  746. }
  747. }
  748. else
  749. {
  750. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  751. }
  752. TraceError("CTcpipcfg::GetIpInfoForAdapter", hr);
  753. return hr;
  754. }
  755. HRESULT CTcpipcfg::SetIpInfoForAdapter(const GUID* pguidAdapter,
  756. REMOTE_IPINFO* pRemoteIpInfo)
  757. {
  758. Assert(pguidAdapter);
  759. Assert(pRemoteIpInfo);
  760. HRESULT hr = S_OK;
  761. ADAPTER_INFO* pAdapter = PAdapterFromInstanceGuid(pguidAdapter);
  762. if (pAdapter)
  763. {
  764. // Tell INetCfg that our component is dirty
  765. Assert(m_pTcpipPrivate);
  766. m_pTcpipPrivate->SetDirty();
  767. // set the flags so we write this to registry & send notification
  768. // at apply
  769. m_fSaveRegistry = TRUE;
  770. m_fReconfig = TRUE;
  771. // copy over the info to our data structure
  772. pAdapter->m_fEnableDhcp = !!pRemoteIpInfo->dwEnableDhcp;
  773. ConvertStringToColString(pRemoteIpInfo->pszwIpAddrList,
  774. c_chListSeparator,
  775. pAdapter->m_vstrIpAddresses);
  776. ConvertStringToColString(pRemoteIpInfo->pszwSubnetMaskList,
  777. c_chListSeparator,
  778. pAdapter->m_vstrSubnetMask);
  779. hr = HrParseOptionList(pRemoteIpInfo->pszwOptionList, pAdapter);
  780. //we only try to set the m_fNoPopupsDuringPnp when it is currently FALSE
  781. if (SUCCEEDED(hr) &&
  782. (!m_fNoPopupsDuringPnp) &&
  783. NULL != pRemoteIpInfo->pszwOptionList)
  784. {
  785. BOOL fDisablePopup = FALSE;
  786. hr = GetPnpPopupSettingFromOptionList(pRemoteIpInfo->pszwOptionList,
  787. &fDisablePopup);
  788. if (S_OK == hr)
  789. {
  790. m_fNoPopupsDuringPnp = fDisablePopup;
  791. }
  792. else if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
  793. {
  794. //it's ok if the option list string doesn't contain this setting
  795. hr = S_OK;
  796. }
  797. }
  798. }
  799. else
  800. {
  801. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  802. }
  803. TraceError("CTcpipcfg::SetIpInfoForAdapter", hr);
  804. return hr;
  805. }
  806. STDMETHODIMP
  807. CTcpipcfg::GetUiInfo (
  808. RASCON_IPUI* pIpui)
  809. {
  810. HRESULT hr = S_OK;
  811. // Validate parameters.
  812. //
  813. if (!pIpui)
  814. {
  815. hr = E_POINTER;
  816. }
  817. else
  818. {
  819. ZeroMemory (pIpui, sizeof(*pIpui));
  820. ADAPTER_INFO* pAdapter = PAdapterFromInstanceGuid(
  821. &m_guidCurrentConnection);
  822. if (pAdapter)
  823. {
  824. if (!pAdapter->m_fEnableDhcp &&
  825. pAdapter->m_vstrIpAddresses.size())
  826. {
  827. pIpui->dwFlags |= RCUIF_USE_IP_ADDR;
  828. lstrcpyW(pIpui->pszwIpAddr,
  829. pAdapter->m_vstrIpAddresses[0]->c_str());
  830. }
  831. if (pAdapter->m_vstrDnsServerList.size() > 0)
  832. {
  833. pIpui->dwFlags |= RCUIF_USE_NAME_SERVERS;
  834. lstrcpyW(pIpui->pszwDnsAddr,
  835. pAdapter->m_vstrDnsServerList[0]->c_str());
  836. if (pAdapter->m_vstrDnsServerList.size() > 1)
  837. {
  838. lstrcpyW(pIpui->pszwDns2Addr,
  839. pAdapter->m_vstrDnsServerList[1]->c_str());
  840. }
  841. }
  842. if (pAdapter->m_vstrWinsServerList.size() > 0)
  843. {
  844. pIpui->dwFlags |= RCUIF_USE_NAME_SERVERS;
  845. lstrcpyW(pIpui->pszwWinsAddr,
  846. pAdapter->m_vstrWinsServerList[0]->c_str());
  847. if (pAdapter->m_vstrWinsServerList.size() > 1)
  848. {
  849. lstrcpyW(pIpui->pszwWins2Addr,
  850. pAdapter->m_vstrWinsServerList[1]->c_str());
  851. }
  852. }
  853. if (pAdapter->m_fUseRemoteGateway)
  854. {
  855. pIpui->dwFlags |= RCUIF_USE_REMOTE_GATEWAY;
  856. }
  857. if (pAdapter->m_fUseIPHeaderCompression)
  858. {
  859. pIpui->dwFlags |= RCUIF_USE_HEADER_COMPRESSION;
  860. }
  861. if (pAdapter->m_fDisableDynamicUpdate)
  862. {
  863. pIpui->dwFlags |= RCUIF_USE_DISABLE_REGISTER_DNS;
  864. }
  865. if (pAdapter->m_fEnableNameRegistration)
  866. {
  867. pIpui->dwFlags |= RCUIF_USE_PRIVATE_DNS_SUFFIX;
  868. }
  869. if (c_dwEnableNetbios == pAdapter->m_dwNetbiosOptions)
  870. {
  871. pIpui->dwFlags |= RCUIF_ENABLE_NBT;
  872. }
  873. lstrcpynW(pIpui->pszwDnsSuffix,
  874. pAdapter->m_strDnsDomain.c_str(),
  875. sizeof(pIpui->pszwDnsSuffix)/sizeof(pIpui->pszwDnsSuffix[0]));
  876. pIpui->dwFrameSize = pAdapter->m_dwFrameSize;
  877. }
  878. else
  879. {
  880. hr = E_UNEXPECTED;
  881. }
  882. }
  883. TraceError("CTcpipcfg::GetUiInfo", hr);
  884. return hr;
  885. }