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.

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