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.

4658 lines
163 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: T C P I P F U N C . C P P
  7. //
  8. // Contents: Various CTcpipcfg member functions that are not interface
  9. // methods
  10. //
  11. // Notes:
  12. //
  13. // Author: tongl 1 May 1997
  14. //
  15. //----------------------------------------------------------------------------
  16. #include "pch.h"
  17. #pragma hdrstop
  18. #include "tcpipobj.h"
  19. #include "ncatlui.h"
  20. #include "ncmisc.h"
  21. #include "ncpnp.h"
  22. #include "ncreg.h"
  23. #include "ncstl.h"
  24. #include "ncui.h"
  25. #include "tcpconst.h"
  26. #include "tcphelp.h"
  27. #include "tcputil.h"
  28. #include "dhcpcsdk.h"
  29. #include "dlgaddr.h"
  30. #include "atmcommon.h"
  31. #include "regkysec.h"
  32. #include "netconp.h"
  33. #define _PNP_POWER_
  34. #include "ntddip.h"
  35. #undef _PNP_POWER_
  36. #include <atmarpif.h>
  37. // sigh... llinfo.h is needed by ddwanarp.h
  38. #include <llinfo.h>
  39. #include <ddwanarp.h>
  40. extern const WCHAR c_szBiNdisAtm[];
  41. extern const WCHAR c_szBiNdis1394[];
  42. extern const WCHAR c_szBiNdisWanIp[];
  43. extern const WCHAR c_szEmpty[];
  44. extern const WCHAR c_szSvcDnscache[];
  45. extern void CopyVstr(VSTR * vstrDest, const VSTR & vstrSrc);
  46. typedef struct {
  47. PCWSTR pszValueName;
  48. DWORD dwType;
  49. } ValueType;
  50. const ValueType s_rgNt4Values[] = {
  51. {RGAS_ENABLE_DHCP, REG_DWORD},
  52. {RGAS_IPADDRESS, REG_MULTI_SZ},
  53. {RGAS_SUBNETMASK, REG_MULTI_SZ},
  54. {RGAS_DEFAULTGATEWAY, REG_MULTI_SZ}
  55. };
  56. //+---------------------------------------------------------------------------
  57. //
  58. // Member: CTcpipcfg::PAdapterFromInstanceGuid
  59. //
  60. // Purpose: Search the adapter info array for an entry with a matching
  61. // instance guid. Return a pointer to the ADAPTER_INFO if found.
  62. //
  63. // Arguments:
  64. // pGuid [in] pointer to instance guid to search for
  65. //
  66. // Returns: Valid pointer if found, NULL if not.
  67. //
  68. // Author: shaunco 1 Oct 1998
  69. //
  70. // Notes:
  71. //
  72. ADAPTER_INFO*
  73. CTcpipcfg::PAdapterFromInstanceGuid (
  74. const GUID* pGuid)
  75. {
  76. Assert (pGuid);
  77. for (VCARD::iterator iterAdapter = m_vcardAdapterInfo.begin();
  78. iterAdapter != m_vcardAdapterInfo.end();
  79. iterAdapter++)
  80. {
  81. ADAPTER_INFO* pAdapter = *iterAdapter;
  82. if (pAdapter->m_guidInstanceId == *pGuid)
  83. {
  84. return pAdapter;
  85. }
  86. }
  87. return NULL;
  88. }
  89. //+---------------------------------------------------------------------------
  90. //
  91. // Member: CTcpipcfg::PAdapterFromNetcfgComponent
  92. //
  93. // Purpose: Search the adapter info array for an entry with an instance
  94. // guid matching that of the specified INetCfgComponent.
  95. // Return a pointer to the ADAPTER_INFO if found.
  96. //
  97. // Arguments:
  98. // pncc [in] INetCfgComponent who's instance guid we are looking for.
  99. //
  100. // Returns: Valid pointer if found, NULL if not.
  101. //
  102. // Author: shaunco 1 Oct 1998
  103. //
  104. // Notes:
  105. //
  106. ADAPTER_INFO*
  107. CTcpipcfg::PAdapterFromNetcfgComponent (
  108. INetCfgComponent* pncc)
  109. {
  110. Assert (pncc);
  111. HRESULT hr;
  112. GUID guidAdapter;
  113. hr = pncc->GetInstanceGuid (&guidAdapter);
  114. if (SUCCEEDED(hr))
  115. {
  116. return PAdapterFromInstanceGuid (&guidAdapter);
  117. }
  118. return NULL;
  119. }
  120. // Called by CTcpipcfg::Initialize.
  121. // We walk the binding path from tcpip and load to first memory state
  122. // all netcards ( both physical cards and Wan adapters )
  123. HRESULT CTcpipcfg::HrGetNetCards()
  124. {
  125. HRESULT hr = S_OK;
  126. CIterNetCfgBindingPath ncbpIter(m_pnccTcpip);
  127. INetCfgBindingPath * pncbp;
  128. // Go through all binding paths in search of tcpip to netcard bindings
  129. while(SUCCEEDED(hr) && (hr = ncbpIter.HrNext(&pncbp)) == S_OK)
  130. {
  131. INetCfgComponent * pnccNetComponent;
  132. PWSTR pszInterfaceName;
  133. hr = HrGetLastComponentAndInterface(pncbp,
  134. &pnccNetComponent,
  135. &pszInterfaceName);
  136. if (SUCCEEDED(hr))
  137. {
  138. Assert(pnccNetComponent);
  139. // The last component should be of NET CLASS
  140. GUID guidClass;
  141. hr = pnccNetComponent->GetClassGuid(&guidClass);
  142. if (SUCCEEDED(hr) && IsEqualGUID(guidClass, GUID_DEVCLASS_NET))
  143. {
  144. PWSTR pszNetCardTcpipBindPath;
  145. hr = pnccNetComponent->GetBindName(&pszNetCardTcpipBindPath);
  146. AssertSz(SUCCEEDED(hr),
  147. "Net card on binding path with no bind path name!!");
  148. m_vstrBindOrder.push_back(new tstring(pszNetCardTcpipBindPath));
  149. hr = HrAddCard(pnccNetComponent,
  150. pszNetCardTcpipBindPath,
  151. pszInterfaceName);
  152. if (SUCCEEDED(hr))
  153. {
  154. GUID guidNetCard;
  155. hr = pnccNetComponent->GetInstanceGuid(&guidNetCard);
  156. if (SUCCEEDED(hr))
  157. {
  158. // Is the binding enabled?
  159. hr = pncbp->IsEnabled();
  160. // hr == S_OK if the card is enabled (ie: bound)
  161. if (S_OK == hr)
  162. { // bind the card in our data strucutres
  163. hr = HrBindCard(&guidNetCard, TRUE);
  164. }
  165. else if (S_FALSE == hr)
  166. {
  167. hr = HrUnBindCard(&guidNetCard, TRUE);
  168. }
  169. }
  170. }
  171. CoTaskMemFree(pszNetCardTcpipBindPath);
  172. }
  173. ReleaseObj(pnccNetComponent);
  174. CoTaskMemFree(pszInterfaceName);
  175. }
  176. ReleaseObj(pncbp);
  177. }
  178. if (S_FALSE == hr) // We just got to the end of the loop
  179. hr = S_OK;
  180. TraceError("CTcpipcfg::HrGetNetCards", hr);
  181. return hr;
  182. }
  183. BOOL CTcpipcfg::IsBindOrderChanged()
  184. {
  185. HRESULT hr = S_OK;
  186. VSTR vstrCurrentBindOrder;
  187. BOOL fChanged = FALSE;
  188. hr = HrLoadBindingOrder(&vstrCurrentBindOrder);
  189. if (SUCCEEDED(hr))
  190. {
  191. fChanged = !fIsSameVstr(vstrCurrentBindOrder, m_vstrBindOrder);
  192. FreeCollectionAndItem(vstrCurrentBindOrder);
  193. }
  194. return fChanged;
  195. }
  196. HRESULT CTcpipcfg::HrLoadBindingOrder(VSTR *pvstrBindOrder)
  197. {
  198. Assert(pvstrBindOrder);
  199. HRESULT hr = S_OK;
  200. CIterNetCfgBindingPath ncbpIter(m_pnccTcpip);
  201. INetCfgBindingPath * pncbp;
  202. INetCfgComponent * pnccLast;
  203. while (SUCCEEDED(hr) && S_OK == (hr = ncbpIter.HrNext(&pncbp)))
  204. {
  205. hr = HrGetLastComponentAndInterface(pncbp, &pnccLast, NULL);
  206. if (SUCCEEDED(hr))
  207. {
  208. Assert(pnccLast);
  209. // The last component should be of NET CLASS
  210. GUID guidClass;
  211. hr = pnccLast->GetClassGuid(&guidClass);
  212. if (SUCCEEDED(hr) && IsEqualGUID(guidClass, GUID_DEVCLASS_NET))
  213. {
  214. PWSTR pszNetCardTcpipBindPath;
  215. hr = pnccLast->GetBindName(&pszNetCardTcpipBindPath);
  216. AssertSz(SUCCEEDED(hr),
  217. "Net card on binding path with no bind path name!!");
  218. if (SUCCEEDED(hr))
  219. {
  220. pvstrBindOrder->push_back(new tstring(pszNetCardTcpipBindPath));
  221. CoTaskMemFree(pszNetCardTcpipBindPath);
  222. }
  223. }
  224. ReleaseObj(pnccLast);
  225. }
  226. ReleaseObj(pncbp);
  227. }
  228. if (S_FALSE == hr) // We just got to the end of the loop
  229. {
  230. hr = S_OK;
  231. }
  232. //if failed, clean up what we added
  233. if (FAILED(hr))
  234. {
  235. FreeCollectionAndItem(*pvstrBindOrder);
  236. }
  237. TraceError("CBindingsDlg::HrGetBindOrder", hr);
  238. return hr;
  239. }
  240. // Called by CTcpipcfg::CancelProperties and CTcpipcfg::ApplyProperties
  241. // Release second memory state
  242. void CTcpipcfg::ExitProperties()
  243. {
  244. delete m_pSecondMemoryAdapterInfo;
  245. m_pSecondMemoryAdapterInfo = NULL;
  246. }
  247. // Called by CTcpipcfg's destructor
  248. // Release all memory states
  249. void CTcpipcfg::FinalFree()
  250. {
  251. FreeCollectionAndItem(m_vcardAdapterInfo);
  252. FreeCollectionAndItem(m_vstrBindOrder);
  253. delete m_pSecondMemoryAdapterInfo;
  254. delete m_ipaddr;
  255. DeleteObject(g_hiconUpArrow);
  256. DeleteObject(g_hiconDownArrow);
  257. ReleaseObj(m_pnc);
  258. ReleaseObj(m_pTcpipPrivate);
  259. ReleaseObj(m_pnccTcpip);
  260. ReleaseObj(m_pnccWins);
  261. // Just a safty check to make sure the context is released.
  262. AssertSz((m_pUnkContext == NULL), "Why is context not released ?");
  263. ReleaseObj(m_pUnkContext) ;
  264. }
  265. // Called by CTcpipcfg::HrSetupPropSheets
  266. // Creates the second memory adapter info from the first
  267. // memory structure
  268. // Note: Bound cards only
  269. HRESULT CTcpipcfg::HrLoadAdapterInfo()
  270. {
  271. HRESULT hr = HRESULT_FROM_WIN32(ERROR_NO_MATCH);
  272. delete m_pSecondMemoryAdapterInfo;
  273. m_pSecondMemoryAdapterInfo = NULL;
  274. ADAPTER_INFO* pAdapter = PAdapterFromInstanceGuid(&m_guidCurrentConnection);
  275. if (pAdapter)
  276. {
  277. // enabled LAN adapter or any RAS Fake adapter
  278. if ((pAdapter->m_BindingState == BINDING_ENABLE) ||
  279. pAdapter->m_fIsRasFakeAdapter)
  280. {
  281. m_pSecondMemoryAdapterInfo = new ADAPTER_INFO;
  282. if (NULL == m_pSecondMemoryAdapterInfo)
  283. {
  284. hr = E_OUTOFMEMORY;
  285. }
  286. else
  287. {
  288. *m_pSecondMemoryAdapterInfo = *pAdapter;
  289. hr = S_OK;
  290. }
  291. }
  292. }
  293. AssertSz((S_OK == hr), "Can not raise UI on a disabled or non-exist adapter !");
  294. TraceError("CTcpipcfg::HrLoadAdapterInfo", hr);
  295. return hr;
  296. }
  297. // Called by CTcpipcfg::ApplyProperties
  298. // Saves the second memory state back into the first
  299. HRESULT CTcpipcfg::HrSaveAdapterInfo()
  300. {
  301. HRESULT hr = HRESULT_FROM_WIN32(ERROR_NO_MATCH);
  302. ADAPTER_INFO* pAdapter = PAdapterFromInstanceGuid(
  303. &m_pSecondMemoryAdapterInfo->m_guidInstanceId);
  304. if (pAdapter)
  305. {
  306. #ifdef DBG
  307. // The card can not get unbound while in tcpip's properties UI!
  308. if (!pAdapter->m_fIsRasFakeAdapter)
  309. {
  310. Assert(pAdapter->m_BindingState == BINDING_ENABLE);
  311. Assert(m_pSecondMemoryAdapterInfo->m_BindingState == BINDING_ENABLE);
  312. }
  313. #endif
  314. *pAdapter = *m_pSecondMemoryAdapterInfo;
  315. hr = S_OK;
  316. }
  317. AssertSz((S_OK == hr),
  318. "Adapter in second memory not found in first memory!");
  319. TraceError("CTcpipcfg::HrSaveAdapterInfo", hr);
  320. return hr;
  321. }
  322. // Called by CTcpipcfg::MergePropPages
  323. // Set the context in which the UI is brought up
  324. HRESULT CTcpipcfg::HrSetConnectionContext()
  325. {
  326. AssertSz(m_pUnkContext, "Invalid IUnknown pointer passed to CTcpipcfg::SetContext?");
  327. if (!m_pUnkContext)
  328. {
  329. return E_UNEXPECTED;
  330. }
  331. // Is this a lan connection ?
  332. GUID guidConn;
  333. INetLanConnectionUiInfo * pLanConnUiInfo;
  334. HRESULT hr = m_pUnkContext->QueryInterface( IID_INetLanConnectionUiInfo,
  335. reinterpret_cast<PVOID *>(&pLanConnUiInfo));
  336. if (SUCCEEDED(hr))
  337. {
  338. // yes, lan connection
  339. m_ConnType = CONNECTION_LAN;
  340. hr = pLanConnUiInfo->GetDeviceGuid(&guidConn);
  341. ReleaseObj(pLanConnUiInfo);
  342. }
  343. else
  344. {
  345. INetRasConnectionIpUiInfo * pRasConnUiInfo;
  346. // Is this a wan connection ?
  347. hr = m_pUnkContext->QueryInterface(IID_INetRasConnectionIpUiInfo,
  348. reinterpret_cast<PVOID *>(&pRasConnUiInfo));
  349. if (SUCCEEDED(hr))
  350. {
  351. // yes, RAS connection
  352. RASCON_IPUI info;
  353. if (SUCCEEDED(pRasConnUiInfo->GetUiInfo(&info)))
  354. {
  355. guidConn = info.guidConnection;
  356. //currently VPN connections only supports PPP frames, so
  357. //if RCUIF_VPN is set, RCUIF_PPP should also be there.
  358. //RCUIF_PPP and RCUIF_SLIP are mutually exclusive
  359. //m_ConnType is only used to show/hide the controls in the RAS
  360. //config UI.
  361. if (info.dwFlags & RCUIF_VPN)
  362. {
  363. m_ConnType = CONNECTION_RAS_VPN;
  364. }
  365. else
  366. {
  367. if (info.dwFlags & RCUIF_PPP)
  368. {
  369. m_ConnType = CONNECTION_RAS_PPP;
  370. }
  371. else if (info.dwFlags & RCUIF_SLIP)
  372. {
  373. m_ConnType = CONNECTION_RAS_SLIP;
  374. }
  375. }
  376. m_fRasNotAdmin = !!(info.dwFlags & RCUIF_NOT_ADMIN);
  377. AssertSz(((CONNECTION_RAS_PPP == m_ConnType)||
  378. (CONNECTION_RAS_SLIP == m_ConnType) ||
  379. (CONNECTION_RAS_VPN == m_ConnType)),
  380. "RAS connection type unknown ?");
  381. UpdateRasAdapterInfo (info);
  382. }
  383. }
  384. ReleaseObj(pRasConnUiInfo);
  385. }
  386. if (SUCCEEDED(hr))
  387. {
  388. m_guidCurrentConnection = guidConn;
  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 this is neither a LAN connection nor a RAS connection?");
  395. TraceError("CTcpipcfg::HrSetConnectionContext", hr);
  396. return hr;
  397. }
  398. // Called by CTcpipcfg::MergePropPages
  399. // Allocate property pages
  400. HRESULT CTcpipcfg::HrSetupPropSheets(HPROPSHEETPAGE ** pahpsp, INT * pcPages)
  401. {
  402. HRESULT hr = S_OK;
  403. int cPages = 0;
  404. HPROPSHEETPAGE *ahpsp = NULL;
  405. m_fSecondMemoryLmhostsFileReset = FALSE;
  406. m_fSecondMemoryModified = FALSE;
  407. //IPSec is removed from connection UI
  408. // m_fSecondMemoryIpsecPolicySet = FALSE;
  409. // copy in memory state to tcpip dialog memory state
  410. // Copy global Info
  411. m_glbSecondMemoryGlobalInfo = m_glbGlobalInfo;
  412. // Copy adapter card specific info
  413. hr = HrLoadAdapterInfo();
  414. // If we have found the matching adapter
  415. if (SUCCEEDED(hr))
  416. {
  417. cPages = 1;
  418. delete m_ipaddr;
  419. m_ipaddr = new CTcpAddrPage(this, g_aHelpIDs_IDD_TCP_IPADDR);
  420. // Allocate a buffer large enough to hold the handles to all of our
  421. // property pages.
  422. ahpsp = (HPROPSHEETPAGE *)CoTaskMemAlloc(sizeof(HPROPSHEETPAGE)
  423. * cPages);
  424. if (!ahpsp)
  425. {
  426. hr = E_OUTOFMEMORY;
  427. goto err;
  428. }
  429. cPages =0;
  430. Assert(m_ConnType != CONNECTION_UNSET);
  431. if (m_ConnType == CONNECTION_LAN)
  432. ahpsp[cPages++] = m_ipaddr->CreatePage(IDD_TCP_IPADDR, 0);
  433. else
  434. ahpsp[cPages++] = m_ipaddr->CreatePage(IDD_TCP_IPADDR_RAS, 0);
  435. *pahpsp = ahpsp;
  436. *pcPages = cPages;
  437. }
  438. else // if we don't have any bound cards, pop-up message box and don't show UI
  439. {
  440. NcMsgBox(::GetActiveWindow(), IDS_MSFT_TCP_TEXT, IDS_NO_BOUND_CARDS,
  441. MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK);
  442. AssertSz((0== *pcPages), "Invalid page number when no bound cards");
  443. AssertSz((NULL == *pahpsp), "Invalid page array pointer when no bound cards");
  444. }
  445. err:
  446. TraceError("CTcpipcfg::HrSetupPropSheets", hr);
  447. return hr;
  448. }
  449. // Is there any bound card on the list of physical adapters
  450. BOOL CTcpipcfg::FHasBoundCard()
  451. {
  452. BOOL fRet = FALSE;
  453. for (VCARD::iterator iterAdapter = m_vcardAdapterInfo.begin();
  454. iterAdapter != m_vcardAdapterInfo.end();
  455. iterAdapter++)
  456. {
  457. ADAPTER_INFO* pAdapter = *iterAdapter;
  458. if (pAdapter->m_BindingState == BINDING_ENABLE)
  459. {
  460. fRet = TRUE;
  461. break;
  462. }
  463. }
  464. return fRet;
  465. }
  466. // Called by CTcpipcfg::NotifyBindingPath
  467. // Handle bind notification of a physical card
  468. HRESULT CTcpipcfg::HrAdapterBindNotify(INetCfgComponent *pnccNetCard,
  469. DWORD dwChangeFlag,
  470. PCWSTR pszInterfaceName)
  471. {
  472. Assert(!(dwChangeFlag & NCN_ADD && dwChangeFlag & NCN_REMOVE));
  473. Assert(!(dwChangeFlag & NCN_ENABLE && dwChangeFlag & NCN_DISABLE));
  474. Assert(FImplies((dwChangeFlag & NCN_ADD),
  475. ((dwChangeFlag & NCN_ENABLE)||(dwChangeFlag & NCN_DISABLE))));
  476. Assert(pnccNetCard);
  477. GUID guidNetCard;
  478. HRESULT hr = pnccNetCard->GetInstanceGuid(&guidNetCard);
  479. if (SUCCEEDED(hr))
  480. {
  481. if (dwChangeFlag & NCN_ADD)
  482. {
  483. PWSTR pszNetCardTcpipBindPath;
  484. hr = pnccNetCard->GetBindName(&pszNetCardTcpipBindPath);
  485. AssertSz( SUCCEEDED(hr), "Net card on binding path with no bind path name!!");
  486. hr = HrAddCard(pnccNetCard,
  487. pszNetCardTcpipBindPath,
  488. pszInterfaceName);
  489. CoTaskMemFree(pszNetCardTcpipBindPath);
  490. }
  491. if (dwChangeFlag & NCN_ENABLE)
  492. {
  493. hr = HrBindCard(&guidNetCard);
  494. }
  495. if (dwChangeFlag & NCN_DISABLE)
  496. {
  497. hr = HrUnBindCard(&guidNetCard);
  498. }
  499. if (dwChangeFlag & NCN_REMOVE)
  500. {
  501. hr = HrDeleteCard(&guidNetCard);
  502. }
  503. }
  504. TraceError("CTcpipCfg::HrPhysicalCardBindNotify", hr);
  505. return hr;
  506. }
  507. // HrAddCard
  508. // Adds a card to the list of cards installed in the system
  509. // pnccNetCard the netcard's GUID in string form
  510. // szNetCardTcpipBindPath the bind path name from Tcpip to the card
  511. // strInterfaceName the upper interface name of the card
  512. HRESULT CTcpipcfg::HrAddCard(INetCfgComponent * pnccNetCard,
  513. PCWSTR pszCardTcpipBindPath,
  514. PCWSTR pszInterfaceName)
  515. {
  516. GUID guidNetCard;
  517. HRESULT hr = pnccNetCard->GetInstanceGuid(&guidNetCard);
  518. if (SUCCEEDED(hr))
  519. {
  520. // Get card bind name
  521. PWSTR pszNetCardBindName;
  522. hr = pnccNetCard->GetBindName(&pszNetCardBindName);
  523. AssertSz(SUCCEEDED(hr),
  524. "Net card on binding path with no bind name!!");
  525. // Get card description
  526. // This is only needed for physical cards
  527. //
  528. BOOL fFreeDescription = TRUE;
  529. PWSTR pszDescription;
  530. // If we can't get a description then give it a default one
  531. if (FAILED(pnccNetCard->GetDisplayName(&pszDescription)))
  532. {
  533. pszDescription = const_cast<PWSTR>(
  534. SzLoadIds(IDS_UNKNOWN_NETWORK_CARD));
  535. fFreeDescription = FALSE;
  536. }
  537. Assert (pszDescription);
  538. ADAPTER_INFO* pAdapter = PAdapterFromInstanceGuid(&guidNetCard);
  539. if (!pAdapter)
  540. {
  541. pAdapter = new ADAPTER_INFO;
  542. if (NULL == pAdapter)
  543. {
  544. return E_OUTOFMEMORY;
  545. }
  546. hr = pAdapter->HrSetDefaults(&guidNetCard,
  547. pszDescription,
  548. pszNetCardBindName,
  549. pszCardTcpipBindPath);
  550. if (SUCCEEDED(hr))
  551. {
  552. // add new card to our data structures and initialize it to default values
  553. m_vcardAdapterInfo.push_back(pAdapter);
  554. }
  555. else
  556. {
  557. delete pAdapter;
  558. pAdapter = NULL;
  559. }
  560. }
  561. else
  562. {
  563. // Set the flag that this card is now on the binding path
  564. pAdapter->m_fIsFromAnswerFile = FALSE;
  565. pAdapter->m_fDeleted = FALSE;
  566. // reset binding state
  567. pAdapter->m_BindingState = BINDING_UNSET;
  568. pAdapter->m_InitialBindingState = BINDING_UNSET;
  569. // Set CardDescription, BindName and BindPathName
  570. pAdapter->m_strDescription = pszDescription;
  571. pAdapter->m_strBindName = pszNetCardBindName;
  572. pAdapter->m_strTcpipBindPath = pszCardTcpipBindPath;
  573. pAdapter->m_strNetBtBindPath = c_szTcpip_;
  574. pAdapter->m_strNetBtBindPath += pAdapter->m_strTcpipBindPath;
  575. }
  576. if (SUCCEEDED(hr))
  577. {
  578. Assert(pAdapter);
  579. // set flags if ATM card or Wan adapter
  580. if (0 == lstrcmpW(pszInterfaceName, c_szBiNdisAtm))
  581. {
  582. pAdapter->m_fIsAtmAdapter = TRUE;
  583. }
  584. else if (0 == lstrcmpW(pszInterfaceName, c_szBiNdisWanIp))
  585. {
  586. pAdapter->m_fIsWanAdapter = TRUE;
  587. }
  588. else if (0 == lstrcmpW(pszInterfaceName, c_szBiNdis1394))
  589. {
  590. pAdapter->m_fIs1394Adapter = TRUE;
  591. }
  592. }
  593. if (fFreeDescription)
  594. {
  595. CoTaskMemFree(pszDescription);
  596. }
  597. CoTaskMemFree(pszNetCardBindName);
  598. }
  599. TraceError("CTcpipcfg::HrAddCard", hr);
  600. return hr;
  601. }
  602. //HrBindCard sets the state of a netcard in the list of installed
  603. // netcards to BOUND
  604. //
  605. // Note: fInitialize is only TRUE when this is called from Initialize,
  606. // the default is FALSE.
  607. //
  608. HRESULT CTcpipcfg::HrBindCard(const GUID* pguid, BOOL fInitialize)
  609. {
  610. ADAPTER_INFO* pAdapter = PAdapterFromInstanceGuid(pguid);
  611. if (pAdapter)
  612. {
  613. AssertSz(pAdapter->m_BindingState != BINDING_ENABLE,
  614. "the same netcard was bound twice to TCPIP");
  615. // Set binding state
  616. pAdapter->m_BindingState = BINDING_ENABLE;
  617. if (fInitialize)
  618. pAdapter->m_InitialBindingState = BINDING_ENABLE;
  619. }
  620. else
  621. {
  622. AssertSz(FALSE, "Attempt to bind a card which wasn't installed");
  623. }
  624. return S_OK;
  625. }
  626. //HrUnBindCard sets the state of a netcard in the list of installed
  627. // netcards to UNBOUND
  628. //
  629. // Note: fInitialize is only TRUE when this is called from Initialize,
  630. // the default is FALSE.
  631. //
  632. HRESULT CTcpipcfg::HrUnBindCard(const GUID* pguid, BOOL fInitialize)
  633. {
  634. ADAPTER_INFO* pAdapter = PAdapterFromInstanceGuid(pguid);
  635. if (pAdapter)
  636. {
  637. AssertSz(pAdapter->m_BindingState != BINDING_DISABLE,
  638. "attempt to unbind an unbound card");
  639. // Set binding state to disable
  640. pAdapter->m_BindingState = BINDING_DISABLE;
  641. if (fInitialize)
  642. pAdapter->m_InitialBindingState = BINDING_DISABLE;
  643. }
  644. else
  645. {
  646. AssertSz(FALSE, "Attempt to unbind a card which wasn't installed");
  647. }
  648. return S_OK;
  649. }
  650. // HrDeleteCard
  651. // Deletes a card from the list of cards installed in the system
  652. //
  653. HRESULT CTcpipcfg::HrDeleteCard(const GUID* pguid)
  654. {
  655. ADAPTER_INFO* pAdapter = PAdapterFromInstanceGuid(pguid);
  656. if (pAdapter)
  657. {
  658. pAdapter->m_fDeleted = TRUE;
  659. }
  660. else
  661. {
  662. AssertSz(FALSE, "A delete attempt was made on a card which doesn't exist");
  663. }
  664. return S_OK;
  665. }
  666. //Function to get the list of cards which have been added to the system
  667. //hkeyTcpipParam "Services\Tcpip\Parameters"
  668. HRESULT CTcpipcfg::MarkNewlyAddedCards(const HKEY hkeyTcpipParam)
  669. {
  670. //(08/19/98 nsun) changed from Tcpip\Parameters\Interfaces to Tcpip\Parameters\Adapters key
  671. // to support multiple interfaces
  672. HKEY hkeyAdapters;
  673. HRESULT hr = HrRegOpenKeyEx(hkeyTcpipParam,
  674. c_szAdaptersRegKey,
  675. KEY_READ, &hkeyAdapters);
  676. if (SUCCEEDED(hr))
  677. {
  678. VSTR vstrAdaptersInRegistry;
  679. Assert(vstrAdaptersInRegistry.empty());
  680. // Get the list of keys
  681. hr = HrLoadSubkeysFromRegistry(hkeyAdapters,
  682. &vstrAdaptersInRegistry);
  683. if (SUCCEEDED(hr))
  684. {
  685. //Go through the list of cards we currently have
  686. for (VCARD::iterator iterAdapter = m_vcardAdapterInfo.begin();
  687. iterAdapter != m_vcardAdapterInfo.end();
  688. iterAdapter++)
  689. {
  690. ADAPTER_INFO* pAdapter = *iterAdapter;
  691. BOOL fAdded = TRUE;
  692. // If we have a card in the list which isn't in registry
  693. // then we add that card to the list of added cards
  694. for(VSTR_CONST_ITER iter = vstrAdaptersInRegistry.begin();
  695. iter != vstrAdaptersInRegistry.end() ; ++iter)
  696. {
  697. if (lstrcmpiW((**iter).c_str(), pAdapter->m_strBindName.c_str()) == 0)
  698. {
  699. fAdded = FALSE;
  700. break;
  701. }
  702. }
  703. // if the card is new then mark it
  704. if (fAdded)
  705. {
  706. pAdapter->m_fNewlyChanged = TRUE;
  707. }
  708. }
  709. FreeCollectionAndItem(vstrAdaptersInRegistry);
  710. }
  711. RegCloseKey(hkeyAdapters);
  712. }
  713. else if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
  714. {
  715. TraceTag(ttidTcpip, "No existing card found.");
  716. hr = S_OK;
  717. }
  718. TraceError("CTcpipcfg::MarkNewlyAddedCards", hr);
  719. return hr;
  720. }
  721. //+------------------------------------------------------------------------------
  722. //
  723. // Function: HrLoadSettings, HrLoadTcpipRegistry, HrLoadWinsRegistry
  724. //
  725. // HrSaveSettings, HrSaveTcpipRegistry, HrSaveTcpipNdisWanRegistry,
  726. // HrSetMisc
  727. //
  728. // Purpose: Functions to Load/Set registry settings and other system info
  729. // during Initialize and Apply time
  730. //
  731. // Author: tongl 5/5/97
  732. //-------------------------------------------------------------------------------
  733. // Called by CTcpipcfg::Initialize
  734. // Load registry settings for a list of net cards
  735. HRESULT CTcpipcfg::HrLoadSettings()
  736. {
  737. HKEY hkey = NULL;
  738. // Load Tcpip's parameters
  739. HRESULT hrTcpip = S_OK;
  740. hrTcpip = m_pnccTcpip->OpenParamKey(&hkey);
  741. if (hrTcpip == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
  742. hrTcpip = S_OK;
  743. else if (SUCCEEDED(hrTcpip))
  744. {
  745. Assert(hkey);
  746. hrTcpip = HrLoadTcpipRegistry(hkey);
  747. RegCloseKey(hkey);
  748. }
  749. else
  750. Assert(!hkey);
  751. // Load NetBt's parameters
  752. HRESULT hrWins = S_OK;
  753. if (m_pnccWins)
  754. { // If Wins is not installed don't get WINS information
  755. hkey = NULL;
  756. hrWins = m_pnccWins->OpenParamKey(&hkey);
  757. if (hrWins == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
  758. hrWins = S_OK;
  759. else if (SUCCEEDED(hrWins))
  760. {
  761. Assert(hkey);
  762. hrWins = HrLoadWinsRegistry(hkey);
  763. RegCloseKey(hkey);
  764. }
  765. else
  766. Assert(!hkey);
  767. }
  768. HRESULT hr = S_OK;
  769. hr = SUCCEEDED(hrTcpip) ? hr : hrTcpip;
  770. hr = SUCCEEDED(hrWins) ? hr : hrWins;
  771. TraceError("CTcpipcfg::HrLoadSettings", hr);
  772. return hr;
  773. }
  774. // Called by CTcpipcfg::HrLoadSettings
  775. // Loads all information under the Services\Tcpip\Parameters registry key
  776. //
  777. // const HKEY hkeyTcpipParam : Handle to Services\Tcpip\Parameters
  778. HRESULT CTcpipcfg::HrLoadTcpipRegistry(const HKEY hkeyTcpipParam)
  779. {
  780. HRESULT hr = S_OK;
  781. HRESULT hrTmp = S_OK;
  782. Assert(hkeyTcpipParam);
  783. // Load global parameters
  784. // DNS server
  785. // For bug #147476: in NT5 upgrades, somehow the
  786. // global DNS server list is deleted, but not until after initialize exits
  787. // So I'm reading in the value here if it exists
  788. // DNS server list moved from global to per adapter
  789. hrTmp = HrRegQueryString(hkeyTcpipParam, RGAS_NAMESERVER, &m_strDnsServerList);
  790. tstring strDnsSuffixList;
  791. if FAILED(hrTmp = HrRegQueryString(hkeyTcpipParam, c_szSearchList,
  792. &strDnsSuffixList))
  793. {
  794. TraceTag(ttidTcpip, "CTcpipcfg::HrLoadTcpipRegistry");
  795. TraceTag(ttidTcpip, "Failed on loading SearchList, hr: %x", hr);
  796. hr = S_OK;
  797. }
  798. else
  799. {
  800. ConvertStringToColString(strDnsSuffixList.c_str(),
  801. c_chListSeparator,
  802. m_glbGlobalInfo.m_vstrDnsSuffixList);
  803. }
  804. m_glbGlobalInfo.m_fUseDomainNameDevolution =
  805. FRegQueryBool(hkeyTcpipParam,
  806. c_szUseDomainNameDevolution,
  807. m_glbGlobalInfo.m_fUseDomainNameDevolution);
  808. m_glbGlobalInfo.m_fEnableRouter = FRegQueryBool(hkeyTcpipParam, c_szIpEnableRouter,
  809. m_glbGlobalInfo.m_fEnableRouter);
  810. //(nsun 11/02/98) gloabl RRAS settings
  811. m_glbGlobalInfo.m_fEnableIcmpRedirect = FRegQueryBool(hkeyTcpipParam,
  812. c_szEnableICMPRedirect,
  813. m_glbGlobalInfo.m_fEnableIcmpRedirect);
  814. //PerformRouterDiscoveryDefault was removed to fix bug 405636
  815. m_glbGlobalInfo.m_fDeadGWDetectDefault = FRegQueryBool(hkeyTcpipParam,
  816. c_szDeadGWDetectDefault,
  817. m_glbGlobalInfo.m_fDeadGWDetectDefault);
  818. m_glbGlobalInfo.m_fDontAddDefaultGatewayDefault = FRegQueryBool(hkeyTcpipParam,
  819. c_szDontAddDefaultGatewayDefault,
  820. m_glbGlobalInfo.m_fDontAddDefaultGatewayDefault);
  821. m_glbGlobalInfo.m_fEnableFiltering = FRegQueryBool(hkeyTcpipParam,
  822. RGAS_SECURITY_ENABLE,
  823. m_glbGlobalInfo.m_fEnableFiltering);
  824. // Save old values
  825. m_glbGlobalInfo.ResetOldValues();
  826. // (08/18/98 nsun) read multiple interface settings for WAN adapters
  827. // Open CCS\Services\Tcpip\Parameters\Adapters key
  828. HKEY hkeyAdapters;
  829. hr = HrRegOpenKeyEx(hkeyTcpipParam, c_szAdaptersRegKey, KEY_READ,
  830. &hkeyAdapters);
  831. if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) // no adapters key
  832. hr = S_OK;
  833. else if (SUCCEEDED(hr))
  834. {
  835. for(VCARD::iterator iterAdapter = m_vcardAdapterInfo.begin();
  836. iterAdapter != m_vcardAdapterInfo.end() && SUCCEEDED(hr) ;
  837. iterAdapter ++)
  838. {
  839. //multiple interface only valid for WAN adapters
  840. if (!((*iterAdapter)->m_fIsWanAdapter))
  841. continue;
  842. ADAPTER_INFO * pAdapter = *iterAdapter;
  843. HKEY hkeyAdapterParam;
  844. hr = HrRegOpenKeyEx(hkeyAdapters,
  845. pAdapter->m_strBindName.c_str(),
  846. KEY_READ,
  847. &hkeyAdapterParam);
  848. if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
  849. {
  850. Assert("No registry settings for a WAN adapter on the "
  851. "bind path?!");
  852. TraceTag(ttidTcpip, "CTcpipcfg::HrLoadTcpipRegistry");
  853. TraceTag(ttidTcpip, "No registry settings for a WAN adapter "
  854. "on the bind path, set to defaults");
  855. // We just use the default values
  856. hr = S_OK;
  857. }
  858. else if (SUCCEEDED(hr))
  859. {
  860. TraceTag(ttidTcpip, "CTcpipcfg::HrLoadTcpipRegistry");
  861. TraceTag(ttidTcpip, "Loading multiple interface parameters "
  862. "for Adapter '%S'", pAdapter->m_strBindName.c_str());
  863. DWORD dwNumInterfaces;
  864. hr = HrRegQueryDword(hkeyAdapterParam,
  865. RGAS_NUMINTERFACES,
  866. &dwNumInterfaces);
  867. if (FAILED(hr))
  868. {
  869. // the Wan adapter is NOT in mode of supporting multiple
  870. // interfaces
  871. TraceTag(ttidTcpip, "No mutliple interface for the WAN "
  872. "adapter '%S'", pAdapter->m_strBindName.c_str());
  873. pAdapter->m_fIsMultipleIfaceMode = FALSE;
  874. hr = S_OK;
  875. }
  876. else
  877. {
  878. pAdapter->m_fIsMultipleIfaceMode = TRUE;
  879. // the WAN adapter supports multiple interface but not
  880. // interface is defined yet
  881. //
  882. if (0 != dwNumInterfaces)
  883. {
  884. GUID* aguidIds;
  885. DWORD cb;
  886. hr = HrRegQueryBinaryWithAlloc(hkeyAdapterParam,
  887. RGAS_IPINTERFACES,
  888. (LPBYTE*)&aguidIds,
  889. &cb);
  890. if (FAILED(hr))
  891. {
  892. AssertSz(FALSE, "NumInterfaces and IpInterfaces "
  893. "values conflicts");
  894. // the Wan adapter is NOT in mode of supporting
  895. // multiple interfaces
  896. //
  897. TraceTag(ttidTcpip, "NumInterfaces and IpInterfaces "
  898. "values conflicts for the WAN adapter '%S'",
  899. pAdapter->m_strBindName.c_str());
  900. hr = S_OK;
  901. }
  902. else if (NULL != aguidIds)
  903. {
  904. dwNumInterfaces = cb / sizeof(GUID);
  905. for(DWORD i = 0; i < dwNumInterfaces; i++)
  906. {
  907. pAdapter->m_IfaceIds.push_back(aguidIds[i]);
  908. }
  909. MemFree(aguidIds);
  910. }
  911. }
  912. }
  913. RegCloseKey(hkeyAdapterParam);
  914. }
  915. }
  916. RegCloseKey(hkeyAdapters);
  917. }
  918. // Get per adapter parameters
  919. // Open CCS\Services\Tcpip\Parameters\Interfaces key
  920. HKEY hkeyInterfaces;
  921. hr = HrRegOpenKeyEx(hkeyTcpipParam, c_szInterfacesRegKey, KEY_READ,
  922. &hkeyInterfaces);
  923. if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) //no adapter interfaces
  924. hr = S_OK;
  925. else if (SUCCEEDED(hr))
  926. {
  927. // Get all the subkeys currently in registry
  928. for(VCARD::iterator iterAdapter = m_vcardAdapterInfo.begin();
  929. iterAdapter != m_vcardAdapterInfo.end() && SUCCEEDED(hr) ;
  930. iterAdapter ++)
  931. {
  932. ADAPTER_INFO * pAdapter = *iterAdapter;
  933. if (pAdapter->m_fIsWanAdapter)
  934. {
  935. continue;
  936. }
  937. HKEY hkeyInterfaceParam;
  938. // Open CCS\Services\Tcpip\Parameters\Interfaces\<card bind path> key
  939. hr = HrRegOpenKeyEx(hkeyInterfaces,
  940. pAdapter->m_strTcpipBindPath.c_str(),
  941. KEY_READ,
  942. &hkeyInterfaceParam);
  943. if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
  944. {
  945. Assert("No registry settings for a card on the bind path?!");
  946. TraceTag(ttidTcpip, "CTcpipcfg::HrLoadTcpipRegistry");
  947. TraceTag(ttidTcpip, "No registry settings for a card on the bind path, set to defaults");
  948. // We just use the default values
  949. hr = S_OK;
  950. }
  951. else if (SUCCEEDED(hr))
  952. {
  953. TraceTag(ttidTcpip, "CTcpipcfg::HrLoadTcpipRegistry");
  954. TraceTag(ttidTcpip, "Loading parameters for Interface '%S'",
  955. pAdapter->m_strTcpipBindPath.c_str());
  956. pAdapter->m_fEnableDhcp = FRegQueryBool(hkeyInterfaceParam,
  957. RGAS_ENABLE_DHCP,
  958. pAdapter->m_fEnableDhcp);
  959. // Get ip address
  960. if (FAILED(hr = HrRegQueryColString(hkeyInterfaceParam,
  961. RGAS_IPADDRESS,
  962. &(pAdapter->m_vstrIpAddresses))))
  963. {
  964. TraceTag(ttidTcpip, "Failed on loading IpAddress, hr: %x", hr);
  965. hr = S_OK;
  966. }
  967. // Set subnet mask information
  968. if (FAILED(hr = HrRegQueryColString(hkeyInterfaceParam,
  969. RGAS_SUBNETMASK,
  970. &(pAdapter->m_vstrSubnetMask))))
  971. {
  972. TraceTag(ttidTcpip, "Failed on loading SubnetMask, hr: %x", hr);
  973. hr = S_OK;
  974. }
  975. // Set default gateway
  976. if (FAILED(hr = HrRegQueryColString(hkeyInterfaceParam,
  977. RGAS_DEFAULTGATEWAY,
  978. &(pAdapter->m_vstrDefaultGateway))))
  979. {
  980. TraceTag(ttidTcpip, "Failed on loading Default Gateway, hr: %x", hr);
  981. hr = S_OK;
  982. }
  983. if (FAILED(hr = HrRegQueryColString(hkeyInterfaceParam,
  984. RGAS_DEFAULTGATEWAYMETRIC,
  985. &(pAdapter->m_vstrDefaultGatewayMetric))))
  986. {
  987. TraceTag(ttidTcpip, "Failed on Loading Default Gateway Metric, hr: %x", hr);
  988. hr = S_OK;
  989. }
  990. // Dns domain
  991. if (FAILED(hr = HrRegQueryString(hkeyInterfaceParam,
  992. RGAS_DOMAIN,
  993. &(pAdapter->m_strDnsDomain))))
  994. {
  995. TraceTag(ttidTcpip, "Failed on loading DnsDomain, hr: %x", hr);
  996. hr = S_OK;
  997. }
  998. // Dns ip address dynamic update
  999. pAdapter->m_fDisableDynamicUpdate = !DnsIsDynamicRegistrationEnabled(
  1000. (LPWSTR)pAdapter->m_strTcpipBindPath.c_str());
  1001. // adapter Dns domain name registration
  1002. pAdapter->m_fEnableNameRegistration = DnsIsAdapterDomainNameRegistrationEnabled(
  1003. (LPWSTR)pAdapter->m_strTcpipBindPath.c_str());
  1004. // Dns server search list
  1005. tstring strDnsServerList;
  1006. if (FAILED(hr = HrRegQueryString(hkeyInterfaceParam,
  1007. RGAS_NAMESERVER,
  1008. &strDnsServerList)))
  1009. {
  1010. TraceTag(ttidTcpip, "Failed on loading Dns NameServer list, hr: %x", hr);
  1011. hr = S_OK;
  1012. }
  1013. else
  1014. {
  1015. ConvertStringToColString(strDnsServerList.c_str(),
  1016. c_chListSeparator,
  1017. pAdapter->m_vstrDnsServerList);
  1018. }
  1019. // Interface metric
  1020. if FAILED(hr = HrRegQueryDword(hkeyInterfaceParam,
  1021. c_szInterfaceMetric,
  1022. &(pAdapter->m_dwInterfaceMetric)))
  1023. {
  1024. TraceTag(ttidTcpip, "Failed on loading InterfaceMetric, hr: %x", hr);
  1025. hr = S_OK;
  1026. }
  1027. // TCP port filter
  1028. VSTR vstrTcpFilterList;
  1029. if (FAILED(hr = HrRegQueryColString(hkeyInterfaceParam,
  1030. RGAS_FILTERING_TCP,
  1031. &vstrTcpFilterList)))
  1032. {
  1033. TraceTag(ttidTcpip, "Failed on loading TCP filter list, hr: %x", hr);
  1034. hr = S_OK;
  1035. }
  1036. else
  1037. {
  1038. CopyVstr(&pAdapter->m_vstrTcpFilterList, vstrTcpFilterList);
  1039. FreeCollectionAndItem(vstrTcpFilterList);
  1040. }
  1041. // UDP port filter
  1042. VSTR vstrUdpFilterList;
  1043. if (FAILED(hr = HrRegQueryColString(hkeyInterfaceParam,
  1044. RGAS_FILTERING_UDP,
  1045. &vstrUdpFilterList)))
  1046. {
  1047. TraceTag(ttidTcpip, "Failed on loading UDP filter list, hr: %x", hr);
  1048. hr = S_OK;
  1049. }
  1050. else
  1051. {
  1052. CopyVstr(&pAdapter->m_vstrUdpFilterList, vstrUdpFilterList);
  1053. FreeCollectionAndItem(vstrUdpFilterList);
  1054. }
  1055. // IP port filter
  1056. VSTR vstrIpFilterList;
  1057. if (FAILED(hr = HrRegQueryColString(hkeyInterfaceParam,
  1058. RGAS_FILTERING_IP,
  1059. &vstrIpFilterList)))
  1060. {
  1061. TraceTag(ttidTcpip, "Failed on loading IP filter list, hr: %x", hr);
  1062. hr = S_OK;
  1063. }
  1064. else
  1065. {
  1066. CopyVstr(&pAdapter->m_vstrIpFilterList, vstrIpFilterList);
  1067. FreeCollectionAndItem(vstrIpFilterList);
  1068. }
  1069. if (FAILED(HrLoadBackupTcpSettings(hkeyInterfaceParam,
  1070. pAdapter)))
  1071. {
  1072. TraceTag(ttidTcpip, "Failed on loading Backup IP settings, hr: %x", hr);
  1073. hr = S_OK;
  1074. }
  1075. // ATM ARP client configurable parameters
  1076. if (pAdapter->m_fIsAtmAdapter)
  1077. {
  1078. HKEY hkeyAtmarpc = NULL;
  1079. // Open the Atmarpc subkey
  1080. hr = HrRegOpenKeyEx(hkeyInterfaceParam,
  1081. c_szAtmarpc,
  1082. KEY_READ,
  1083. &hkeyAtmarpc);
  1084. if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
  1085. {
  1086. AssertSz(FALSE,"No atmarpc subkey for an atm adapter on the bind path?!");
  1087. TraceTag(ttidTcpip, "Failed on opening atmarpc subkey, defaults will be used, hr: %x", hr);
  1088. hr = S_OK;
  1089. }
  1090. else if (SUCCEEDED(hr))
  1091. {
  1092. // ARP server address list
  1093. if (FAILED(hr = HrRegQueryColString(hkeyAtmarpc,
  1094. c_szREG_ARPServerList,
  1095. &(pAdapter->m_vstrARPServerList))))
  1096. {
  1097. TraceTag(ttidTcpip, "Failed on loading ARPServerList, hr: %x", hr);
  1098. hr = S_OK;
  1099. }
  1100. // MAR server address list
  1101. if (FAILED(hr = HrRegQueryColString(hkeyAtmarpc,
  1102. c_szREG_MARServerList,
  1103. &(pAdapter->m_vstrMARServerList))))
  1104. {
  1105. TraceTag(ttidTcpip, "Failed on loading MARServerList, hr: %x", hr);
  1106. hr = S_OK;
  1107. }
  1108. // Max Transmit Unit
  1109. if (FAILED(hr = HrRegQueryDword(hkeyAtmarpc,
  1110. c_szREG_MTU,
  1111. &(pAdapter->m_dwMTU))))
  1112. {
  1113. TraceTag(ttidTcpip, "Failed on loading MTU, hr: %x", hr);
  1114. hr = S_OK;
  1115. }
  1116. // PVC Only
  1117. pAdapter->m_fPVCOnly = FRegQueryBool(hkeyAtmarpc,
  1118. c_szREG_PVCOnly,
  1119. pAdapter->m_fPVCOnly);
  1120. RegCloseKey(hkeyAtmarpc);
  1121. }
  1122. }
  1123. (*iterAdapter)->ResetOldValues();
  1124. RegCloseKey(hkeyInterfaceParam);
  1125. }
  1126. }
  1127. RegCloseKey(hkeyInterfaces);
  1128. }
  1129. TraceError("CTcpipcfg::HrLoadTcpipRegistry", hr);
  1130. return hr;
  1131. }
  1132. // Called by CTcpipcfg::HrLoadSettings
  1133. // Loads all information under the Services\NetBt\Parameters registry key
  1134. //
  1135. // const HKEY hkeyWinsParam : Handle to Services\NetBt\Parameters
  1136. HRESULT CTcpipcfg::HrLoadWinsRegistry(const HKEY hkeyWinsParam)
  1137. {
  1138. HRESULT hr = S_OK;
  1139. // Global parameters
  1140. m_glbGlobalInfo.m_fEnableLmHosts = FRegQueryBool( hkeyWinsParam,
  1141. RGAS_ENABLE_LMHOSTS,
  1142. m_glbGlobalInfo.m_fEnableLmHosts);
  1143. // Save a copy of these values for non-reboot reconfiguration notification
  1144. m_glbGlobalInfo.m_fOldEnableLmHosts = m_glbGlobalInfo.m_fEnableLmHosts;
  1145. HKEY hkeyInterfaces;
  1146. hr = HrRegOpenKeyEx(hkeyWinsParam, c_szInterfacesRegKey,
  1147. KEY_READ, &hkeyInterfaces);
  1148. if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
  1149. hr = S_OK;
  1150. else if (SUCCEEDED(hr))
  1151. {
  1152. for(VCARD::iterator iterAdapter = m_vcardAdapterInfo.begin();
  1153. iterAdapter != m_vcardAdapterInfo.end();
  1154. iterAdapter ++)
  1155. {
  1156. ADAPTER_INFO * pAdapter = *iterAdapter;
  1157. // $REIVEW (nsun 10/05/98) We don't need to read NetBT settings the WAN adapter
  1158. if (pAdapter->m_fIsWanAdapter)
  1159. {
  1160. continue;
  1161. }
  1162. // Open the NetBt\Interfaces\<Something> to get per
  1163. // adapter NetBt settings
  1164. HKEY hkeyInterfaceParam;
  1165. hr = HrRegOpenKeyEx(hkeyInterfaces,
  1166. pAdapter->m_strNetBtBindPath.c_str(),
  1167. KEY_READ, &hkeyInterfaceParam);
  1168. if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
  1169. hr = S_OK;
  1170. else if (SUCCEEDED(hr))
  1171. {
  1172. TraceTag(ttidTcpip, "CTcpipcfg::HrLoadWinsRegistry");
  1173. TraceTag(ttidTcpip, "Interface '%S'", pAdapter->m_strNetBtBindPath.c_str());
  1174. // load wins server address list
  1175. if (FAILED(hr = HrRegQueryColString(hkeyInterfaceParam,
  1176. RGAS_NETBT_NAMESERVERLIST,
  1177. &(pAdapter->m_vstrWinsServerList))))
  1178. {
  1179. TraceTag(ttidTcpip, "Failed on loading NameServerList, hr: %x", hr);
  1180. hr = S_OK;
  1181. }
  1182. // Save a copy in m_strOldWinsServerList
  1183. CopyVstr(&(pAdapter->m_vstrOldWinsServerList),
  1184. pAdapter->m_vstrWinsServerList);
  1185. // load Netbios options
  1186. if (FAILED(hr = HrRegQueryDword(hkeyInterfaceParam,
  1187. RGAS_NETBT_NETBIOSOPTIONS,
  1188. &(pAdapter->m_dwNetbiosOptions))))
  1189. {
  1190. TraceTag(ttidTcpip, "Failed on loading NetbiosOptions, hr: %x", hr);
  1191. hr = S_OK;
  1192. }
  1193. // Save a copy in m_dwOldNetbiosOptions
  1194. pAdapter->m_dwOldNetbiosOptions = pAdapter->m_dwNetbiosOptions;
  1195. RegCloseKey(hkeyInterfaceParam);
  1196. }
  1197. }
  1198. RegCloseKey(hkeyInterfaces);
  1199. }
  1200. TraceError("CTcpipcfg::HrLoadWinsRegistry", hr);
  1201. return hr;
  1202. }
  1203. // Called by CTcpipcfg::Apply
  1204. // This function writes all changes to the registy and makes other
  1205. // appropriate changes to the system
  1206. HRESULT CTcpipcfg::HrSaveSettings()
  1207. {
  1208. HRESULT hr = S_OK;
  1209. HRESULT hrTcpip = S_OK;
  1210. HKEY hkeyTcpipParam = NULL;
  1211. Assert(m_pnccTcpip);
  1212. if (m_pnccTcpip)
  1213. {
  1214. hrTcpip = m_pnccTcpip->OpenParamKey(&hkeyTcpipParam);
  1215. // We use hr instead of hrTcpip because this operation is NOT part of
  1216. // HrSaveTcpipRegistry.
  1217. // We must get the list of Added Cards before anything else because
  1218. // otherwise the Adapter GUID keys will be written later and we will
  1219. // not know if they didn't exist in the system before.
  1220. if (SUCCEEDED(hrTcpip))
  1221. {
  1222. hrTcpip = MarkNewlyAddedCards(hkeyTcpipParam);
  1223. if (SUCCEEDED(hrTcpip))
  1224. {
  1225. Assert(hkeyTcpipParam);
  1226. hrTcpip = HrSaveTcpipRegistry(hkeyTcpipParam);
  1227. }
  1228. else
  1229. Assert(!hkeyTcpipParam);
  1230. }
  1231. }
  1232. HRESULT hrWins = S_OK;
  1233. HKEY hkeyWinsParam = NULL;
  1234. Assert(m_pnccWins);
  1235. if (m_pnccWins)
  1236. {
  1237. hrWins = m_pnccWins->OpenParamKey(&hkeyWinsParam);
  1238. if (SUCCEEDED(hrWins))
  1239. {
  1240. Assert(hkeyWinsParam);
  1241. hrWins = HrSaveWinsRegistry(hkeyWinsParam);
  1242. }
  1243. else
  1244. Assert(!hkeyWinsParam);
  1245. }
  1246. HRESULT hrMisc = S_OK;
  1247. //if hrTcpip == E_? then this is possible (thus no Assert)
  1248. // yes because hrTcpip can be set to E_? from HrSaveTcpipRegistry
  1249. if ((hkeyTcpipParam) && (hkeyWinsParam))
  1250. {
  1251. hrMisc = HrSetMisc(hkeyTcpipParam, hkeyWinsParam);
  1252. }
  1253. RegSafeCloseKey(hkeyTcpipParam);
  1254. RegSafeCloseKey(hkeyWinsParam);
  1255. hr = SUCCEEDED(hr) ? hrTcpip : hr;
  1256. hr = SUCCEEDED(hr) ? hrWins : hr;
  1257. hr = SUCCEEDED(hr) ? hrMisc : hr;
  1258. TraceError("CTcpipcfg::HrSaveSettings", hr);
  1259. return hr;
  1260. }
  1261. // Set global and adapter specific parameters under
  1262. // CCS\Services\TCpip\Parameters
  1263. // hkeyTcpipParam handle to reg key HKLM\Systems\CCS\Services\TCpip\Parameters
  1264. HRESULT CTcpipcfg::HrSaveTcpipRegistry(const HKEY hkeyTcpipParam)
  1265. {
  1266. // hr is the first error occurred,
  1267. // but we don't want to stop at the first error
  1268. HRESULT hr = S_OK;
  1269. HRESULT hrTmp = S_OK;
  1270. // Save global info
  1271. // DNS host name ( only on installing )
  1272. if (m_fInstalling)
  1273. {
  1274. if (!m_fUpgradeGlobalDnsDomain)
  1275. {
  1276. // Bug 299038, during install of tcpip, try to get the primary dns domain name
  1277. // create the global DNS domain as an empty string during clean install if
  1278. // we couldn't find the primary dns domain name (219090).
  1279. // if we already got the global Dns Domain when processing the answer file, we should
  1280. // use the value from the answer file
  1281. tstring strTmpDomain;
  1282. hrTmp = HrRegQueryString(hkeyTcpipParam,
  1283. RGAS_DOMAIN,
  1284. &strTmpDomain);
  1285. if (FAILED(hrTmp))
  1286. {
  1287. hrTmp = HrGetPrimaryDnsDomain(&strTmpDomain);
  1288. if (SUCCEEDED(hrTmp))
  1289. {
  1290. if (!SetComputerNameEx(ComputerNamePhysicalDnsDomain,
  1291. strTmpDomain.c_str()))
  1292. {
  1293. hrTmp = GetLastError();
  1294. TraceError("CTcpipcfg::HrSaveTcpipRegistry: SetComputerNameEx failed.", hrTmp);
  1295. }
  1296. }
  1297. else
  1298. {
  1299. //Bug #335626, some SrvApp directly retrive this value, so we need to create it for
  1300. //standalone machines
  1301. strTmpDomain = c_szEmpty;
  1302. }
  1303. //SetComputerNameEx() will write to "Domain" reg value after reboot. Per GlennC, it's ok to write
  1304. //the Domain value here to solve the SrvApp compatibility issue.
  1305. HrRegSetString(hkeyTcpipParam,
  1306. RGAS_DOMAIN,
  1307. strTmpDomain);
  1308. }
  1309. //the hrTmp get from this section should not affect the
  1310. //final return value
  1311. }
  1312. //
  1313. // 391590: We've saved the hostname from NT4 into the answerfile so that
  1314. // we can remember the exact (case-sensitive) string. If the
  1315. // saved DNS hostname is the same (except for case) as the current
  1316. // COMPUTERNAME, we set the NT5 DNS hostname to be the saved one,
  1317. // for SAP compatibility (they make case-sensitive comparisons).
  1318. // Otherwise, we use the regular COMPUTERNAME, lowercased, as the
  1319. // DNS hostname.
  1320. //
  1321. if (!lstrcmpiW(m_glbGlobalInfo.m_strHostName.c_str(),
  1322. m_glbGlobalInfo.m_strHostNameFromAnswerFile.c_str()))
  1323. {
  1324. hrTmp = HrRegSetString(hkeyTcpipParam,
  1325. RGAS_HOSTNAME,
  1326. m_glbGlobalInfo.m_strHostNameFromAnswerFile);
  1327. if (S_OK == hrTmp)
  1328. {
  1329. hrTmp = HrRegSetString(hkeyTcpipParam,
  1330. RGAS_NVHOSTNAME,
  1331. m_glbGlobalInfo.m_strHostNameFromAnswerFile);
  1332. }
  1333. }
  1334. else
  1335. {
  1336. hrTmp = HrRegSetString(hkeyTcpipParam,
  1337. RGAS_HOSTNAME,
  1338. m_glbGlobalInfo.m_strHostName);
  1339. if (S_OK == hrTmp)
  1340. {
  1341. hrTmp = HrRegSetString(hkeyTcpipParam,
  1342. RGAS_NVHOSTNAME,
  1343. m_glbGlobalInfo.m_strHostName);
  1344. }
  1345. }
  1346. TraceError("CTcpipcfg::HrSaveTcpipRegistry: Failed to set HostName.", hrTmp);
  1347. //the hrTmp get from this section should not affect the
  1348. //final return value
  1349. }
  1350. // Added per request from Stuart Kwan:
  1351. // only when the global DNS domain is read from answerfile
  1352. if (m_fUpgradeGlobalDnsDomain)
  1353. {
  1354. if (!SetComputerNameEx(ComputerNamePhysicalDnsDomain,
  1355. m_strUpgradeGlobalDnsDomain.c_str()))
  1356. {
  1357. hrTmp = GetLastError();
  1358. TraceError("CTcpipcfg::HrSaveTcpipRegistry: SetComputerNameEx failed.", hrTmp);
  1359. }
  1360. //If the registry value Services\Tcpip\Parameters\SyncDomainWithMembership != 0,
  1361. //Netlogon will try to overwirte the value with the member domain name when joining
  1362. //into the domain. (See NT bug 310143
  1363. //
  1364. //Due to bug WinSE 7317, most users don't want us to manually set SyncDomainWithMembership
  1365. //reg value as 0 here.
  1366. //
  1367. //As a workaround in order to upgarde the gloabl Dns domain name, the user has to
  1368. //add SyncDomainWithMembership reg value under tcpip parameters and make it as 0.
  1369. //In the unattended install case, there needs to be a line
  1370. // SyncDomainWithMembership=0
  1371. //in the global tcpip parameters section if the user want to specify a global DNS
  1372. //domain name that is different with the membership domain name.
  1373. //the hrTmp get from this section should not affect the
  1374. //final return value
  1375. }
  1376. // Dns suffix list
  1377. tstring strSearchList;
  1378. ConvertColStringToString(m_glbGlobalInfo.m_vstrDnsSuffixList,
  1379. c_chListSeparator,
  1380. strSearchList);
  1381. hrTmp = HrRegSetString(hkeyTcpipParam,
  1382. RGAS_SEARCHLIST,
  1383. strSearchList);
  1384. if (SUCCEEDED(hr))
  1385. hr = hrTmp;
  1386. // UseDomainNameDevolution
  1387. hrTmp = HrRegSetBool(hkeyTcpipParam,
  1388. c_szUseDomainNameDevolution,
  1389. m_glbGlobalInfo.m_fUseDomainNameDevolution);
  1390. if (SUCCEEDED(hr))
  1391. hr = hrTmp;
  1392. // IpEnableRouter
  1393. hrTmp = HrRegSetBool(hkeyTcpipParam,
  1394. c_szIpEnableRouter,
  1395. m_glbGlobalInfo.m_fEnableRouter);
  1396. if (SUCCEEDED(hr))
  1397. hr = hrTmp;
  1398. //(nsun 11/02/98) parameters of RRAS for unattended install
  1399. hrTmp = HrRegSetBool(hkeyTcpipParam,
  1400. c_szEnableICMPRedirect,
  1401. m_glbGlobalInfo.m_fEnableIcmpRedirect);
  1402. if (SUCCEEDED(hr))
  1403. hr = hrTmp;
  1404. hrTmp = HrRegSetBool(hkeyTcpipParam,
  1405. c_szDeadGWDetectDefault,
  1406. m_glbGlobalInfo.m_fDeadGWDetectDefault);
  1407. if (SUCCEEDED(hr))
  1408. hr = hrTmp;
  1409. hrTmp = HrRegSetBool(hkeyTcpipParam,
  1410. c_szDontAddDefaultGatewayDefault,
  1411. m_glbGlobalInfo.m_fDontAddDefaultGatewayDefault);
  1412. if (SUCCEEDED(hr))
  1413. hr = hrTmp;
  1414. hrTmp = HrRegSetBool(hkeyTcpipParam,
  1415. RGAS_SECURITY_ENABLE,
  1416. m_glbGlobalInfo.m_fEnableFiltering);
  1417. if (SUCCEEDED(hr))
  1418. hr = hrTmp;
  1419. // Adapter specific info (physical cards)
  1420. HKEY hkeyAdapters = NULL;
  1421. DWORD dwDisposition;
  1422. // Create or open the "Adapters" key under "Services\Tcpip\Parameters"
  1423. hrTmp = HrRegCreateKeyEx(hkeyTcpipParam, c_szAdaptersRegKey,
  1424. REG_OPTION_NON_VOLATILE, KEY_READ_WRITE_DELETE, NULL,
  1425. &hkeyAdapters, &dwDisposition);
  1426. if (SUCCEEDED(hrTmp))
  1427. {
  1428. Assert(hkeyAdapters);
  1429. for(VCARD::iterator iterAdapter = m_vcardAdapterInfo.begin();
  1430. iterAdapter != m_vcardAdapterInfo.end();
  1431. iterAdapter ++)
  1432. {
  1433. ADAPTER_INFO * pAdapter = *iterAdapter;
  1434. // No need to do this for RAS fake adapters
  1435. if (pAdapter->m_fIsRasFakeAdapter)
  1436. {
  1437. continue;
  1438. }
  1439. // Create specific card bindname key under
  1440. // "Services\Tcpip\Parameters\Adapters\<card bind name>"
  1441. //
  1442. HKEY hkeyAdapterParam;
  1443. hrTmp = HrRegCreateKeyEx(hkeyAdapters,
  1444. pAdapter->m_strBindName.c_str(),
  1445. REG_OPTION_NON_VOLATILE, KEY_READ_WRITE_DELETE, NULL,
  1446. &hkeyAdapterParam, &dwDisposition);
  1447. if (SUCCEEDED(hr))
  1448. hr = hrTmp;
  1449. if (SUCCEEDED(hrTmp))
  1450. {
  1451. Assert(hkeyAdapterParam);
  1452. // Set LLInterface and IpConfig for new cards
  1453. //
  1454. if (pAdapter->m_fNewlyChanged)
  1455. {
  1456. PCWSTR pszArpModule = c_szEmpty;
  1457. if (pAdapter->m_fIsWanAdapter)
  1458. {
  1459. pszArpModule = c_szWanArp;
  1460. }
  1461. else if (pAdapter->m_fIsAtmAdapter)
  1462. {
  1463. pszArpModule = c_szAtmArp;
  1464. }
  1465. else if (pAdapter->m_fIs1394Adapter)
  1466. {
  1467. pszArpModule = c_sz1394Arp;
  1468. }
  1469. hrTmp = HrRegSetSz(hkeyAdapterParam,
  1470. RGAS_LLINTERFACE,
  1471. pszArpModule);
  1472. if (SUCCEEDED(hr))
  1473. hr = hrTmp;
  1474. // (08/18/98 nsun) modified to support multiple interfaces of WAN adapter
  1475. VSTR vstrIpConfig;
  1476. if (!pAdapter->m_fIsMultipleIfaceMode)
  1477. {
  1478. HrRegDeleteValue(hkeyAdapterParam, RGAS_NUMINTERFACES);
  1479. tstring* pstr = new tstring(RGAS_TCPIP_PARAM_INTERFACES);
  1480. if (pstr == NULL)
  1481. {
  1482. return(E_OUTOFMEMORY);
  1483. }
  1484. pstr->append(pAdapter->m_strTcpipBindPath);
  1485. vstrIpConfig.push_back(pstr);
  1486. hrTmp = HrRegSetColString(hkeyAdapterParam,
  1487. RGAS_IPCONFIG,
  1488. vstrIpConfig);
  1489. }
  1490. else
  1491. {
  1492. AssertSz(pAdapter->m_fIsWanAdapter, "The card is not WAN adapter, but how can it support multiple interface.");
  1493. tstring strInterfaceName;
  1494. IFACEITER iterId;
  1495. for(iterId = pAdapter->m_IfaceIds.begin();
  1496. iterId != pAdapter->m_IfaceIds.end();
  1497. iterId++)
  1498. {
  1499. GetInterfaceName(
  1500. pAdapter->m_strTcpipBindPath.c_str(),
  1501. *iterId,
  1502. &strInterfaceName);
  1503. tstring* pstr = new tstring(RGAS_TCPIP_PARAM_INTERFACES);
  1504. pstr->append(strInterfaceName);
  1505. vstrIpConfig.push_back(pstr);
  1506. }
  1507. hrTmp = HrRegSetColString(hkeyAdapterParam,
  1508. RGAS_IPCONFIG,
  1509. vstrIpConfig);
  1510. if (SUCCEEDED(hr))
  1511. hr = hrTmp;
  1512. //$REVIEW (nsun 09/15/98) use NumInterfaces value to identify if the adapter is in the
  1513. //mode of supporting multiple interfaces. If the NumInterfaces
  1514. //exists, the adapter supports multiple interfaces.
  1515. //If NumInterfaces == 0, it means the adapter supports multiple interfaces
  1516. // but no interface is associated with it. So the IpInterfaces should not
  1517. // exists. The NumInterfaces and IpInterfaces should alwasy be consistent.
  1518. DWORD dwNumInterfaces = pAdapter->m_IfaceIds.size();
  1519. hrTmp = HrRegSetDword(hkeyAdapterParam,
  1520. RGAS_NUMINTERFACES,
  1521. dwNumInterfaces);
  1522. if (SUCCEEDED(hr))
  1523. hr = hrTmp;
  1524. if ( 0 != dwNumInterfaces )
  1525. {
  1526. GUID* aguid;
  1527. DWORD cguid;
  1528. hrTmp = GetGuidArrayFromIfaceColWithCoTaskMemAlloc(
  1529. pAdapter->m_IfaceIds,
  1530. &aguid,
  1531. &cguid);
  1532. if (SUCCEEDED(hr))
  1533. hr = hrTmp;
  1534. Assert(aguid);
  1535. hrTmp = HrRegSetBinary(hkeyAdapterParam,
  1536. RGAS_IPINTERFACES,
  1537. (BYTE*) aguid,
  1538. cguid * sizeof(GUID));
  1539. CoTaskMemFree(aguid);
  1540. }
  1541. else
  1542. {
  1543. hrTmp = HrRegDeleteValue(hkeyAdapterParam, RGAS_IPINTERFACES);
  1544. //It's fine that the IpInterfaces does not exist at all if
  1545. // the WAN adapter does not support multiple interfaces.
  1546. if (hrTmp == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
  1547. hrTmp = S_OK;
  1548. }
  1549. }
  1550. FreeCollectionAndItem(vstrIpConfig);
  1551. if (SUCCEEDED(hr))
  1552. hr = hrTmp;
  1553. }
  1554. RegCloseKey(hkeyAdapterParam);
  1555. }
  1556. }
  1557. RegCloseKey(hkeyAdapters);
  1558. }
  1559. else if (HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED) == hrTmp)
  1560. {
  1561. //for netcfg operators, we will get access denied error when opening this key
  1562. //however, it's ok because we don't need to touch the key when just updating the IP settings
  1563. hrTmp = S_OK;
  1564. }
  1565. if (SUCCEEDED(hr))
  1566. hr = hrTmp;
  1567. // Create or open the "Interfaces" key under "Services\Tcpip\Parameters"
  1568. //
  1569. HKEY hkeyInterfaces;
  1570. hrTmp = HrRegCreateKeyEx(hkeyTcpipParam, c_szInterfacesRegKey,
  1571. REG_OPTION_NON_VOLATILE, KEY_READ_WRITE_DELETE, NULL,
  1572. &hkeyInterfaces, &dwDisposition);
  1573. if (SUCCEEDED(hr))
  1574. hr = hrTmp;
  1575. if (SUCCEEDED(hrTmp))
  1576. {
  1577. Assert(hkeyInterfaces);
  1578. for(VCARD::iterator iterAdapter = m_vcardAdapterInfo.begin();
  1579. iterAdapter != m_vcardAdapterInfo.end();
  1580. iterAdapter ++)
  1581. {
  1582. if ((*iterAdapter)->m_fIsRasFakeAdapter)
  1583. {
  1584. continue;
  1585. }
  1586. ADAPTER_INFO * pAdapter = *iterAdapter;
  1587. //(08/20/98 nsun) modified to support multiple interfaces of WAN adapter
  1588. // NULL != pAdapter->m_IfaceIds means it's in multiple interface mode
  1589. if (pAdapter->m_fIsWanAdapter && pAdapter->m_fIsMultipleIfaceMode)
  1590. {
  1591. if (pAdapter->m_fNewlyChanged)
  1592. {
  1593. HrSaveMultipleInterfaceWanRegistry(hkeyInterfaces, pAdapter);
  1594. }
  1595. continue;
  1596. }
  1597. // Create specific card interface key under
  1598. // "Services\Tcpip\Parameters\Interfaces\<card bind path>"
  1599. //
  1600. HKEY hkeyInterfaceParam;
  1601. hrTmp = HrRegCreateKeyEx(hkeyInterfaces,
  1602. pAdapter->m_strTcpipBindPath.c_str(),
  1603. REG_OPTION_NON_VOLATILE, KEY_READ_WRITE_DELETE, NULL,
  1604. &hkeyInterfaceParam, &dwDisposition);
  1605. if (SUCCEEDED(hr))
  1606. hr = hrTmp;
  1607. if (SUCCEEDED(hrTmp))
  1608. {
  1609. Assert(hkeyInterfaceParam);
  1610. if (pAdapter->m_fNewlyChanged)
  1611. {
  1612. //Bug306259 If UseZeroBroadCast already exists (which means it is from the answer
  1613. // file), we should not overwrite it with the default value.
  1614. DWORD dwTmp;
  1615. hrTmp = HrRegQueryDword(hkeyInterfaceParam,
  1616. RGAS_USEZEROBROADCAST,
  1617. &dwTmp);
  1618. if (FAILED(hrTmp))
  1619. {
  1620. // ZeroBroadcast
  1621. hrTmp = HrRegSetDword(hkeyInterfaceParam,
  1622. RGAS_USEZEROBROADCAST,
  1623. 0);
  1624. if (SUCCEEDED(hr))
  1625. hr = hrTmp;
  1626. }
  1627. if (pAdapter->m_fIsWanAdapter)
  1628. { // For new RAS cards
  1629. hrTmp = HrSaveStaticWanRegistry(hkeyInterfaceParam);
  1630. }
  1631. else if (pAdapter->m_fIsAtmAdapter)
  1632. {
  1633. // For new ATM cards
  1634. hrTmp = HrSaveStaticAtmRegistry(hkeyInterfaceParam);
  1635. }
  1636. else if (pAdapter->m_fIs1394Adapter)
  1637. {
  1638. // For new NIC1394 cards
  1639. // (nothing to do).
  1640. hrTmp = S_OK;
  1641. }
  1642. else
  1643. {
  1644. //(nsun 11/02/98) set static RRAS parameters for unattended install
  1645. //if the values exists, that means they have been set as an unconfigurable
  1646. //parameter during upgrade,
  1647. //we should not set the default value.
  1648. DWORD dwTmp;
  1649. hrTmp = HrRegQueryDword(hkeyInterfaceParam,
  1650. c_szDeadGWDetect,
  1651. &dwTmp);
  1652. if (FAILED(hrTmp))
  1653. {
  1654. hrTmp = HrRegSetBool(hkeyInterfaceParam,
  1655. c_szDeadGWDetect,
  1656. m_glbGlobalInfo.m_fDeadGWDetectDefault);
  1657. }
  1658. }
  1659. if (SUCCEEDED(hr))
  1660. hr = hrTmp;
  1661. }
  1662. // For LAN cards and RAS fake guids
  1663. if (!pAdapter->m_fIsWanAdapter)
  1664. {
  1665. // Ip address etc
  1666. hrTmp = HrRegSetBool(hkeyInterfaceParam,
  1667. RGAS_ENABLE_DHCP,
  1668. pAdapter->m_fEnableDhcp);
  1669. if (SUCCEEDED(hr))
  1670. hr = hrTmp;
  1671. //warning: these VSTRs will contain pointers to strings
  1672. //that are either local to this function or
  1673. //that are also pointed to in another VSTR
  1674. // DO NOT call FreeCollectionAndItem on them!
  1675. VSTR vstrIpAddresses;
  1676. VSTR vstrSubnetMask;
  1677. tstring ZeroAddress(ZERO_ADDRESS);
  1678. if (pAdapter->m_fEnableDhcp)
  1679. {
  1680. vstrIpAddresses.push_back(&ZeroAddress);
  1681. vstrSubnetMask.push_back(&ZeroAddress);
  1682. }
  1683. else
  1684. {
  1685. vstrIpAddresses = pAdapter->m_vstrIpAddresses;
  1686. vstrSubnetMask = pAdapter->m_vstrSubnetMask;
  1687. }
  1688. hrTmp = HrRegSetColString(hkeyInterfaceParam,
  1689. RGAS_IPADDRESS,
  1690. vstrIpAddresses);
  1691. if (SUCCEEDED(hr))
  1692. hr = hrTmp;
  1693. hrTmp = HrRegSetColString(hkeyInterfaceParam,
  1694. RGAS_SUBNETMASK,
  1695. vstrSubnetMask);
  1696. if (SUCCEEDED(hr))
  1697. hr = hrTmp;
  1698. hrTmp = HrRegSetColString(hkeyInterfaceParam,
  1699. RGAS_DEFAULTGATEWAY,
  1700. pAdapter->m_vstrDefaultGateway);
  1701. if (SUCCEEDED(hr))
  1702. hr = hrTmp;
  1703. hrTmp = HrRegSetColString(hkeyInterfaceParam,
  1704. RGAS_DEFAULTGATEWAYMETRIC,
  1705. pAdapter->m_vstrDefaultGatewayMetric);
  1706. if (SUCCEEDED(hr))
  1707. hr = hrTmp;
  1708. // DNS name server list
  1709. tstring strNameServer;
  1710. ConvertColStringToString(pAdapter->m_vstrDnsServerList,
  1711. c_chListSeparator,
  1712. strNameServer);
  1713. hrTmp = HrRegSetString(hkeyInterfaceParam,
  1714. RGAS_NAMESERVER,
  1715. strNameServer);
  1716. if (SUCCEEDED(hr))
  1717. hr = hrTmp;
  1718. // DNS domain
  1719. hrTmp = HrRegSetString(hkeyInterfaceParam,
  1720. RGAS_DOMAIN,
  1721. pAdapter->m_strDnsDomain);
  1722. if (SUCCEEDED(hr))
  1723. hr = hrTmp;
  1724. // Dns ip address dynamic update
  1725. if (pAdapter->m_fDisableDynamicUpdate)
  1726. {
  1727. DnsDisableDynamicRegistration(
  1728. (LPWSTR)pAdapter->m_strTcpipBindPath.c_str());
  1729. }
  1730. else
  1731. {
  1732. DnsEnableDynamicRegistration(
  1733. (LPWSTR)pAdapter->m_strTcpipBindPath.c_str());
  1734. }
  1735. // adapter Dns domain name registration
  1736. if (pAdapter->m_fEnableNameRegistration)
  1737. {
  1738. DnsEnableAdapterDomainNameRegistration(
  1739. (LPWSTR)pAdapter->m_strTcpipBindPath.c_str());
  1740. }
  1741. else
  1742. {
  1743. DnsDisableAdapterDomainNameRegistration(
  1744. (LPWSTR)pAdapter->m_strTcpipBindPath.c_str());
  1745. }
  1746. // InterfaceMetric
  1747. if (c_dwDefaultIfMetric != pAdapter->m_dwInterfaceMetric)
  1748. {
  1749. hrTmp = HrRegSetDword(hkeyInterfaceParam,
  1750. c_szInterfaceMetric,
  1751. pAdapter->m_dwInterfaceMetric);
  1752. }
  1753. else
  1754. {
  1755. //The interface metric is default, remove that value.
  1756. //In such way, it would be much easier to upgrade if the default is changed
  1757. //in the future
  1758. hrTmp = HrRegDeleteValue(hkeyInterfaceParam,
  1759. c_szInterfaceMetric);
  1760. if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hrTmp)
  1761. hrTmp = S_OK;
  1762. }
  1763. if (SUCCEEDED(hr))
  1764. hr = hrTmp;
  1765. // TCPAllowedPorts
  1766. hrTmp = HrRegSetColString(hkeyInterfaceParam,
  1767. RGAS_FILTERING_TCP,
  1768. pAdapter->m_vstrTcpFilterList);
  1769. if (SUCCEEDED(hr))
  1770. hr = hrTmp;
  1771. // UDPAllowedPorts
  1772. hrTmp = HrRegSetColString(hkeyInterfaceParam,
  1773. RGAS_FILTERING_UDP,
  1774. pAdapter->m_vstrUdpFilterList);
  1775. if (SUCCEEDED(hr))
  1776. hr = hrTmp;
  1777. // IPAllowedPorts
  1778. hrTmp = HrRegSetColString(hkeyInterfaceParam,
  1779. RGAS_FILTERING_IP,
  1780. pAdapter->m_vstrIpFilterList);
  1781. if (SUCCEEDED(hr))
  1782. hr = hrTmp;
  1783. // For ATM cards only
  1784. if (pAdapter->m_fIsAtmAdapter)
  1785. {
  1786. HKEY hkeyAtmarpc;
  1787. // Open the Atmarpc subkey
  1788. hrTmp = HrRegCreateKeyEx(hkeyInterfaceParam,
  1789. c_szAtmarpc,
  1790. REG_OPTION_NON_VOLATILE,
  1791. KEY_READ_WRITE,
  1792. NULL,
  1793. &hkeyAtmarpc,
  1794. &dwDisposition);
  1795. if (SUCCEEDED(hrTmp))
  1796. {
  1797. hrTmp = HrRegSetColString(hkeyAtmarpc,
  1798. c_szREG_ARPServerList,
  1799. pAdapter->m_vstrARPServerList);
  1800. if (SUCCEEDED(hr))
  1801. hr = hrTmp;
  1802. hrTmp = HrRegSetColString(hkeyAtmarpc,
  1803. c_szREG_MARServerList,
  1804. pAdapter->m_vstrMARServerList);
  1805. if (SUCCEEDED(hr))
  1806. hr = hrTmp;
  1807. hrTmp = HrRegSetDword(hkeyAtmarpc,
  1808. c_szREG_MTU,
  1809. pAdapter->m_dwMTU);
  1810. if (SUCCEEDED(hr))
  1811. hr = hrTmp;
  1812. hrTmp = HrRegSetBool(hkeyAtmarpc,
  1813. c_szREG_PVCOnly,
  1814. pAdapter->m_fPVCOnly);
  1815. if (SUCCEEDED(hr))
  1816. hr = hrTmp;
  1817. RegCloseKey(hkeyAtmarpc);
  1818. }
  1819. }
  1820. hrTmp = HrDuplicateToNT4Location(hkeyInterfaceParam,
  1821. pAdapter);
  1822. if (SUCCEEDED(hr))
  1823. hr = hrTmp;
  1824. hrTmp = HrSaveBackupTcpSettings(hkeyInterfaceParam,
  1825. pAdapter);
  1826. if (SUCCEEDED(hr))
  1827. hr = hrTmp;
  1828. } // For LAN cards and RAS fake guids only
  1829. RegCloseKey(hkeyInterfaceParam);
  1830. }
  1831. }
  1832. RegCloseKey(hkeyInterfaces);
  1833. }
  1834. TraceError("CTcpipcfg::HrSaveTcpipRegistry", hr);
  1835. return hr;
  1836. }
  1837. HRESULT CTcpipcfg::HrSaveWinsRegistry(const HKEY hkeyWinsParam)
  1838. {
  1839. // hr is the first error occurred,
  1840. // but we don't want to stop at the first error
  1841. HRESULT hr = S_OK;
  1842. HRESULT hrTmp = S_OK;
  1843. // Global parameters
  1844. hrTmp = HrRegSetBool(hkeyWinsParam,
  1845. RGAS_ENABLE_LMHOSTS,
  1846. m_glbGlobalInfo.m_fEnableLmHosts);
  1847. if (SUCCEEDED(hr))
  1848. hr = hrTmp;
  1849. /*$REVIEW (nsun 2/17/98) Bug #293643 We don't want to change any unconfigurable values
  1850. // $REVIEW(tongl 8/3/97): Added NodeType settings #97364.
  1851. // If no adapter has static WINS address, then remove NodeType.
  1852. // otherwise, the user has specified the WINs server address for
  1853. // at least one adapters, set NodeType = 0x08 (H-NODE)
  1854. BOOL fNoWinsAddress = TRUE;
  1855. for (VCARD::iterator iterAdapter = m_vcardAdapterInfo.begin();
  1856. iterAdapter != m_vcardAdapterInfo.end();
  1857. iterAdapter++)
  1858. {
  1859. ADAPTER_INFO * pAdapter = *iterAdapter;
  1860. if ((!pAdapter->m_fIsWanAdapter)&&
  1861. (BINDING_ENABLE == pAdapter->m_BindingState)&&
  1862. (pAdapter->m_vstrWinsServerList.size()>0))
  1863. {
  1864. fNoWinsAddress = FALSE;
  1865. }
  1866. }
  1867. DWORD dwNodeType;
  1868. hrTmp = HrRegQueryDword(hkeyWinsParam,
  1869. c_szNodeType,
  1870. &dwNodeType);
  1871. // dwNodeType ==0 means the key did not exist before we apply
  1872. if (hrTmp == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
  1873. dwNodeType =0;
  1874. if (!m_fAnswerFileBasedInstall ||
  1875. (hrTmp == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)))
  1876. {
  1877. if (!fNoWinsAddress) // set NodeType to 0x08
  1878. {
  1879. if (dwNodeType != c_dwHNode)
  1880. {
  1881. hrTmp = HrRegSetDword(hkeyWinsParam,
  1882. c_szNodeType,
  1883. c_dwHNode);
  1884. if (SUCCEEDED(hr))
  1885. hr = hrTmp;
  1886. }
  1887. }
  1888. else // remove NodeType key
  1889. {
  1890. if (dwNodeType != 0)
  1891. {
  1892. hrTmp = HrRegDeleteValue(hkeyWinsParam,
  1893. c_szNodeType);
  1894. if (SUCCEEDED(hr))
  1895. hr = hrTmp;
  1896. }
  1897. }
  1898. }
  1899. */
  1900. // $REVIEW(tongl 12\1\97): Per agreement with Malam today(see email),
  1901. // NetBt will re-read NodeType when notified of wins address list change.
  1902. // Thus no need to notify change separately below.
  1903. /*
  1904. if (fNodeTypeChanged)
  1905. {
  1906. // Send notification to NetBt
  1907. TraceTag(ttidTcpip,"NodeType parameter changed, send notification on apply.");
  1908. SetReconfig();
  1909. // SetReconfigNbt();
  1910. }
  1911. */
  1912. // Adapter interface specific parameters
  1913. // Create the "Services\NetBt\Interfacess" key
  1914. HKEY hkeyInterfaces;
  1915. DWORD dwDisposition;
  1916. hrTmp = HrRegCreateKeyEx(hkeyWinsParam, c_szInterfacesRegKey,
  1917. REG_OPTION_NON_VOLATILE, KEY_READ_WRITE, NULL,
  1918. &hkeyInterfaces, &dwDisposition);
  1919. if (SUCCEEDED(hr))
  1920. hr = hrTmp;
  1921. if (SUCCEEDED(hrTmp))
  1922. {
  1923. for(VCARD::iterator iterAdapter = m_vcardAdapterInfo.begin();
  1924. iterAdapter != m_vcardAdapterInfo.end();
  1925. iterAdapter++)
  1926. {
  1927. ADAPTER_INFO * pAdapter = *iterAdapter;
  1928. //(10/05/98 nsun) modified to support multiple interfaces of WAN adapter
  1929. // NULL != pAdapter->m_IfaceIds means it's in multiple interface mode
  1930. if (pAdapter->m_fNewlyChanged &&
  1931. pAdapter->m_fIsWanAdapter &&
  1932. pAdapter->m_fIsMultipleIfaceMode)
  1933. {
  1934. HrSaveWinsMultipleInterfaceWanRegistry(hkeyInterfaces, pAdapter);
  1935. continue;
  1936. }
  1937. HKEY hkeyInterfaceParam;
  1938. hrTmp = HrRegCreateKeyEx(hkeyInterfaces,
  1939. pAdapter->m_strNetBtBindPath.c_str(),
  1940. REG_OPTION_NON_VOLATILE, KEY_READ_WRITE, NULL,
  1941. &hkeyInterfaceParam, &dwDisposition);
  1942. if (SUCCEEDED(hr))
  1943. hr = hrTmp;
  1944. if (SUCCEEDED(hrTmp))
  1945. {
  1946. // For new RAS cards, only set static values
  1947. if (pAdapter->m_fIsWanAdapter && pAdapter->m_fNewlyChanged)
  1948. {
  1949. hrTmp = HrRegSetMultiSz(hkeyInterfaceParam,
  1950. RGAS_NETBT_NAMESERVERLIST,
  1951. L"\0");
  1952. if (SUCCEEDED(hr))
  1953. hr = hrTmp;
  1954. }
  1955. else // if not RAS adapter
  1956. {
  1957. // set wins server address list
  1958. hrTmp = HrRegSetColString(hkeyInterfaceParam,
  1959. RGAS_NETBT_NAMESERVERLIST,
  1960. pAdapter->m_vstrWinsServerList);
  1961. if (SUCCEEDED(hr))
  1962. hr = hrTmp;
  1963. // set NetbiosOptions
  1964. hrTmp = HrRegSetDword(hkeyInterfaceParam,
  1965. RGAS_NETBT_NETBIOSOPTIONS,
  1966. pAdapter->m_dwNetbiosOptions);
  1967. if (SUCCEEDED(hr))
  1968. hr = hrTmp;
  1969. }
  1970. RegCloseKey(hkeyInterfaceParam);
  1971. }
  1972. }
  1973. RegCloseKey(hkeyInterfaces);
  1974. }
  1975. TraceError("CTcpipcfg::HrSaveWinsRegistry", hr);
  1976. return hr;
  1977. }
  1978. // Called by CTcpipcfg::SaveSettings
  1979. // Does a lot of miscelaneous actions when Apply is called
  1980. // Including cleaning up registry and remove isolated cards
  1981. //
  1982. // HKEY hkeyTcpipParam Serviess\Tcpip\Parameters
  1983. // HKEY hkeyWinsParam Services\NetBt\Parameters
  1984. HRESULT CTcpipcfg::HrSetMisc(const HKEY hkeyTcpipParam, const HKEY hkeyWinsParam)
  1985. {
  1986. HRESULT hr = S_OK;
  1987. HRESULT hrTmp = S_OK;
  1988. // Registry Cleanup !!
  1989. // We remove DNS domain and DNS server list in NT5 upgrades
  1990. if (m_fUpgradeCleanupDnsKey)
  1991. {
  1992. hrTmp = HrRegDeleteValue(hkeyTcpipParam, RGAS_NAMESERVER);
  1993. // $REVIEW(tongl 3/22/98): Per Stuart Kwan, global DNSDomain key
  1994. // is also used.
  1995. // hrTmp = HrRegDeleteValue(hkeyTcpipParam, RGAS_DOMAIN);
  1996. }
  1997. // remove all keys under the "Services\Tcpip\Parameters\Adapters" reg key
  1998. // that aren't in the list of net cards.
  1999. VSTR vstrNetCardsInTcpipReg;
  2000. HKEY hkeyAdapters = NULL;
  2001. hrTmp = HrRegOpenKeyEx(hkeyTcpipParam, c_szAdaptersRegKey, KEY_READ,
  2002. &hkeyAdapters);
  2003. if (SUCCEEDED(hrTmp))
  2004. {
  2005. hrTmp = HrLoadSubkeysFromRegistry(hkeyAdapters,
  2006. &vstrNetCardsInTcpipReg);
  2007. }
  2008. if (SUCCEEDED(hr))
  2009. hr = hrTmp;
  2010. if (SUCCEEDED(hr) && vstrNetCardsInTcpipReg.size() > 0)
  2011. {
  2012. // Step through the names of all the registry keys found
  2013. //
  2014. for (VSTR_CONST_ITER iter = vstrNetCardsInTcpipReg.begin();
  2015. iter != vstrNetCardsInTcpipReg.end();
  2016. ++iter)
  2017. {
  2018. // Find out if this particular key is in the list
  2019. // of installed Adapters
  2020. //
  2021. BOOL fFound = FALSE;
  2022. for (VCARD::iterator iterAdapter = m_vcardAdapterInfo.begin();
  2023. iterAdapter != m_vcardAdapterInfo.end();
  2024. iterAdapter++)
  2025. {
  2026. ADAPTER_INFO* pAdapter = *iterAdapter;
  2027. if (lstrcmpiW(pAdapter->m_strBindName.c_str(), (**iter).c_str()) == 0)
  2028. {
  2029. fFound = TRUE;
  2030. break;
  2031. }
  2032. }
  2033. if (!fFound)
  2034. {
  2035. // if it wasn't in the list of installed adapters
  2036. // then delete it
  2037. //
  2038. if (SUCCEEDED(hrTmp))
  2039. hrTmp = HrRegDeleteKeyTree(hkeyAdapters, (*iter)->c_str());
  2040. //maybe the key is not there. so we don't check whether this will fail.
  2041. HrDeleteBackupSettingsInDhcp((*iter)->c_str());
  2042. if (SUCCEEDED(hr))
  2043. hr = hrTmp;
  2044. }
  2045. }
  2046. }
  2047. FreeCollectionAndItem(vstrNetCardsInTcpipReg);
  2048. RegSafeCloseKey(hkeyAdapters);
  2049. //we also need to delete the duplicate reg values under Services\{adapter GUID}
  2050. HRESULT hrNt4 = S_OK;
  2051. HKEY hkeyServices = NULL;
  2052. DWORD dwDisposition;
  2053. hrNt4 = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegServices,
  2054. KEY_READ, &hkeyServices);
  2055. if (FAILED(hrNt4))
  2056. {
  2057. TraceTag(ttidTcpip, "HrSetMisc: Failed to open the Services reg key, hr: %x", hr);
  2058. }
  2059. // We remove all keys under the "Services\Tcpip\Parameters\Interfaces" reg key
  2060. // that aren't in our list of net cards.
  2061. VSTR vstrNetCardInterfacesInTcpipReg;
  2062. // Get a list of all keys under the "Services\Tcpip\Parameters\Interfaces" key
  2063. HKEY hkeyInterfaces = NULL;
  2064. hrTmp = HrRegOpenKeyEx(hkeyTcpipParam, c_szInterfacesRegKey, KEY_READ_WRITE_DELETE,
  2065. &hkeyInterfaces);
  2066. if (SUCCEEDED(hrTmp))
  2067. {
  2068. hrTmp = HrLoadSubkeysFromRegistry(hkeyInterfaces,
  2069. &vstrNetCardInterfacesInTcpipReg);
  2070. }
  2071. if (SUCCEEDED(hr))
  2072. hr = hrTmp;
  2073. if (SUCCEEDED(hrTmp) && vstrNetCardInterfacesInTcpipReg.size() > 0 )
  2074. {
  2075. // step through the names of all the registry keys found
  2076. for (VSTR_CONST_ITER iterTcpipReg = vstrNetCardInterfacesInTcpipReg.begin() ;
  2077. iterTcpipReg != vstrNetCardInterfacesInTcpipReg.end() ; ++iterTcpipReg)
  2078. {
  2079. // Find out if this particular key is in the list
  2080. // of installed Adapters
  2081. BOOL fFound = FALSE;
  2082. for (VCARD::iterator iterAdapter = m_vcardAdapterInfo.begin();
  2083. iterAdapter != m_vcardAdapterInfo.end();
  2084. iterAdapter++)
  2085. {
  2086. ADAPTER_INFO* pAdapter = *iterAdapter;
  2087. //(08/18/98 nsun) special case for WAN adapters with multiple interfaces
  2088. if (pAdapter->m_fIsWanAdapter && pAdapter->m_fIsMultipleIfaceMode)
  2089. {
  2090. IFACEITER iterId;
  2091. tstring strInterfaceName;
  2092. for(iterId = pAdapter->m_IfaceIds.begin();
  2093. iterId != pAdapter->m_IfaceIds.end();
  2094. iterId++)
  2095. {
  2096. GetInterfaceName(
  2097. pAdapter->m_strTcpipBindPath.c_str(),
  2098. *iterId,
  2099. &strInterfaceName);
  2100. if (lstrcmpiW(strInterfaceName.c_str(), (**iterTcpipReg).c_str()) == 0)
  2101. {
  2102. fFound = TRUE;
  2103. break;
  2104. }
  2105. }
  2106. if (fFound)
  2107. break;
  2108. }
  2109. else if (lstrcmpiW(pAdapter->m_strTcpipBindPath.c_str(), (**iterTcpipReg).c_str()) == 0)
  2110. {
  2111. fFound = TRUE;
  2112. break;
  2113. }
  2114. }
  2115. // if it wasn't in the list of installed adapters then delete it
  2116. if (!fFound)
  2117. {
  2118. // remove the key
  2119. if (SUCCEEDED(hrTmp))
  2120. hrTmp = HrRegDeleteKeyTree(hkeyInterfaces, (*iterTcpipReg)->c_str());
  2121. if (SUCCEEDED(hr))
  2122. hr = hrTmp;
  2123. if (SUCCEEDED(hrNt4))
  2124. {
  2125. hrTmp = HrRegDeleteKeyTree(hkeyServices, (*iterTcpipReg)->c_str());
  2126. if (FAILED(hrTmp))
  2127. {
  2128. TraceTag(ttidTcpip, "CTcpipcfg::SetMisc");
  2129. TraceTag(ttidTcpip, "Failed on deleting duplicated Nt4 layout key: Services\\%S, hr: %x",
  2130. (*iterTcpipReg)->c_str(), hrTmp);
  2131. hrTmp = S_OK;
  2132. }
  2133. }
  2134. }
  2135. }
  2136. }
  2137. RegSafeCloseKey(hkeyInterfaces);
  2138. RegSafeCloseKey(hkeyServices);
  2139. FreeCollectionAndItem(vstrNetCardInterfacesInTcpipReg);
  2140. // Now we remove all keys under the "SERVICES\NetBt\Parameters\Interfaces" reg key
  2141. // that aren't in our list of net cards.
  2142. VSTR vstrNetCardInterfacesInWinsReg;
  2143. // Get a list of all keys under the "Services\NetBt\Parameters\Interfaces" key
  2144. HKEY hkeyWinsInterfaces = NULL;
  2145. hrTmp = HrRegOpenKeyEx(hkeyWinsParam, c_szInterfacesRegKey, KEY_READ,
  2146. &hkeyWinsInterfaces);
  2147. // Get a list of all keys under the "SERVICES\NetBt\Parameters\Interfaces" key
  2148. hrTmp = HrLoadSubkeysFromRegistry( hkeyWinsInterfaces,
  2149. &vstrNetCardInterfacesInWinsReg);
  2150. if (SUCCEEDED(hr))
  2151. hr = hrTmp;
  2152. if (SUCCEEDED(hrTmp) && vstrNetCardInterfacesInWinsReg.size()>0 )
  2153. {
  2154. // Step through the names of all the registry keys found
  2155. for (VSTR_CONST_ITER iterWinsReg = vstrNetCardInterfacesInWinsReg.begin() ;
  2156. iterWinsReg != vstrNetCardInterfacesInWinsReg.end() ; ++iterWinsReg)
  2157. {
  2158. // Find out if this particular key is in the list
  2159. // of installed Adapters
  2160. BOOL fFound = FALSE;
  2161. // All net cards
  2162. for (VCARD::iterator iterAdapter = m_vcardAdapterInfo.begin();
  2163. iterAdapter != m_vcardAdapterInfo.end();
  2164. iterAdapter++)
  2165. {
  2166. ADAPTER_INFO* pAdapter = *iterAdapter;
  2167. //(10/05/98 nsun) special case for WAN adapters with multiple interfaces
  2168. if (pAdapter->m_fIsWanAdapter && pAdapter->m_fIsMultipleIfaceMode)
  2169. {
  2170. IFACEITER iterId;
  2171. tstring strNetBtBindPath;
  2172. for (iterId = pAdapter->m_IfaceIds.begin();
  2173. iterId != pAdapter->m_IfaceIds.end();
  2174. iterId++)
  2175. {
  2176. GetInterfaceName(
  2177. pAdapter->m_strNetBtBindPath.c_str(),
  2178. *iterId,
  2179. &strNetBtBindPath);
  2180. strNetBtBindPath.insert(0, c_szTcpip_);
  2181. if (lstrcmpiW(strNetBtBindPath.c_str(), (**iterWinsReg).c_str()) == 0)
  2182. {
  2183. fFound = TRUE;
  2184. break;
  2185. }
  2186. }
  2187. if (fFound)
  2188. break;
  2189. }
  2190. else if (lstrcmpiW(pAdapter->m_strNetBtBindPath.c_str(), (**iterWinsReg).c_str()) == 0)
  2191. {
  2192. fFound = TRUE;
  2193. break;
  2194. }
  2195. }
  2196. // if it wasn't in the list of installed adapters then delete it
  2197. if (!fFound)
  2198. {
  2199. hrTmp = HrRegDeleteKeyTree(hkeyWinsInterfaces, (*iterWinsReg)->c_str());
  2200. if (SUCCEEDED(hr))
  2201. hr = hrTmp;
  2202. }
  2203. }
  2204. }
  2205. FreeCollectionAndItem(vstrNetCardInterfacesInWinsReg);
  2206. RegSafeCloseKey(hkeyWinsInterfaces);
  2207. TraceError("CTcpipcfg::HrSetMisc", hr);
  2208. return hr;
  2209. }
  2210. // CTcpipcfg::HrGetDhcpOptions
  2211. //
  2212. // Gets the list of netcard dependend and netcard independent
  2213. // values to delete when DHCP is disabled. This list is obtained from:
  2214. // "Services\DHCP\Parameters\Options\#\RegLocation"
  2215. //
  2216. // GlobalOptions returns the non-netcard specific reg keys
  2217. // PerAdapterOptions returns the netcard specific reg keys
  2218. HRESULT CTcpipcfg::HrGetDhcpOptions(OUT VSTR * const GlobalOptions,
  2219. OUT VSTR * const PerAdapterOptions)
  2220. {
  2221. HRESULT hr = S_OK;
  2222. HRESULT hrTmp = S_OK;
  2223. HKEY hkeyDhcpOptions;
  2224. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE,
  2225. RGAS_DHCP_OPTIONS,
  2226. KEY_ENUMERATE_SUB_KEYS,
  2227. &hkeyDhcpOptions);
  2228. if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
  2229. hr = S_OK;
  2230. else if (SUCCEEDED(hr))
  2231. {
  2232. WCHAR szBuf[256];
  2233. FILETIME time;
  2234. DWORD dwSize = celems(szBuf);
  2235. DWORD dwRegIndex = 0;
  2236. while(SUCCEEDED(hrTmp = HrRegEnumKeyEx(hkeyDhcpOptions,
  2237. dwRegIndex++,
  2238. szBuf, &dwSize,
  2239. NULL, NULL, &time)))
  2240. {
  2241. dwSize = celems(szBuf);
  2242. HKEY hkeyRegLocation;
  2243. hrTmp = HrRegOpenKeyEx(hkeyDhcpOptions, szBuf,
  2244. KEY_QUERY_VALUE,
  2245. &hkeyRegLocation);
  2246. if (hrTmp == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
  2247. hrTmp = S_OK;
  2248. if (SUCCEEDED(hr))
  2249. hr = hrTmp;
  2250. if (hkeyRegLocation)
  2251. {
  2252. tstring strRegLocation;
  2253. hrTmp = HrRegQueryString(hkeyRegLocation,
  2254. RGAS_REG_LOCATION,
  2255. &strRegLocation);
  2256. if (hrTmp == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
  2257. hrTmp = S_OK;
  2258. if (SUCCEEDED(hr))
  2259. hr = hrTmp;
  2260. if (SUCCEEDED(hrTmp))
  2261. {
  2262. if (strRegLocation.find(TCH_QUESTION_MARK) == tstring::npos)
  2263. {
  2264. GlobalOptions->push_back(new tstring(strRegLocation));
  2265. }
  2266. else
  2267. {
  2268. PerAdapterOptions->push_back(new tstring(strRegLocation));
  2269. }
  2270. }
  2271. RegCloseKey(hkeyRegLocation);
  2272. }
  2273. }
  2274. if (hrTmp == HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS))
  2275. hrTmp = S_OK;
  2276. if (SUCCEEDED(hr))
  2277. hr = hrTmp;
  2278. RegCloseKey(hkeyDhcpOptions);
  2279. }
  2280. // Add default PerAdapterOption
  2281. // $REVIEW(tongl 5/11): This is directly from ncpa1.1
  2282. // What about DhcpNameServer under NetBt ??
  2283. //"System\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\?\\DhcpIPAddress"
  2284. PerAdapterOptions->push_back(new tstring(RGAS_DHCP_OPTION_IPADDRESS));
  2285. //"System\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\?\\DhcpSubnetMask"
  2286. PerAdapterOptions->push_back(new tstring(RGAS_DHCP_OPTION_SUBNETMASK));
  2287. //"System\\CurrentControlSet\\Services\\NetBT\\Parameters\\Interfaces\\?\\DhcpNameServerBackup"
  2288. PerAdapterOptions->push_back(new tstring(RGAS_DHCP_OPTION_NAMESERVERBACKUP));
  2289. TraceError("HrGetDhcpOptions", hr);
  2290. return hr;
  2291. }
  2292. //+---------------------------------------------------------------------------
  2293. //
  2294. // Member: CTcpipcfg::ReconfigIp
  2295. //
  2296. // Purpose: Notify Tcpip of configuration changes
  2297. //
  2298. // Arguments: INetCfgPnpReconfigCallback* pICallback
  2299. // the call back interface to handle Ndis Pnp reconfig
  2300. //
  2301. // Returns: HRESULT, S_OK on success, NETCFG_S_REBOOT otherwise
  2302. //
  2303. HRESULT CTcpipcfg::HrReconfigIp(INetCfgPnpReconfigCallback* pICallback)
  2304. {
  2305. HRESULT hr = S_OK;
  2306. HRESULT hrReconfig = S_OK;
  2307. //$$REVIEW bug 329542, we remove the Pnp notification on "EnableSecurityFilters".
  2308. //And then global PnP notification to tcp stack is not needed at all.
  2309. if (m_glbGlobalInfo.m_fEnableFiltering != m_glbGlobalInfo.m_fOldEnableFiltering)
  2310. {
  2311. hr = NETCFG_S_REBOOT;
  2312. }
  2313. IP_PNP_RECONFIG_REQUEST IpReconfigRequest;
  2314. ZeroMemory(&IpReconfigRequest, sizeof(IpReconfigRequest));
  2315. // DWORD version
  2316. IpReconfigRequest.version = IP_PNP_RECONFIG_VERSION;
  2317. IpReconfigRequest.arpConfigOffset = 0;
  2318. //we are only interested in gateway and interface metric, because other
  2319. //parameters cannot be changed from the UI
  2320. IpReconfigRequest.Flags = IP_PNP_FLAG_GATEWAY_LIST_UPDATE |
  2321. IP_PNP_FLAG_INTERFACE_METRIC_UPDATE ;
  2322. // Submit per adapter reconfig notifications
  2323. // gatewayListUpdate, filterListUpdate
  2324. for (VCARD::iterator iterAdapter = m_vcardAdapterInfo.begin();
  2325. iterAdapter != m_vcardAdapterInfo.end();
  2326. iterAdapter ++) // for each adapter
  2327. {
  2328. ADAPTER_INFO * pAdapter = *iterAdapter;
  2329. // If not wan adapter or RAS fake guid, and adapter is enabled
  2330. if ((!pAdapter->m_fIsWanAdapter) &&
  2331. (!pAdapter->m_fIsRasFakeAdapter) &&
  2332. (pAdapter->m_BindingState == BINDING_ENABLE) &&
  2333. (pAdapter->m_InitialBindingState != BINDING_DISABLE))
  2334. {
  2335. // gateway list
  2336. IpReconfigRequest.gatewayListUpdate =
  2337. !fIsSameVstr(pAdapter->m_vstrDefaultGateway,
  2338. pAdapter->m_vstrOldDefaultGateway) ||
  2339. !fIsSameVstr(pAdapter->m_vstrDefaultGatewayMetric,
  2340. pAdapter->m_vstrOldDefaultGatewayMetric);
  2341. IpReconfigRequest.InterfaceMetricUpdate =
  2342. !!(pAdapter->m_dwInterfaceMetric !=
  2343. pAdapter->m_dwOldInterfaceMetric);
  2344. if ((IpReconfigRequest.gatewayListUpdate) ||
  2345. (IpReconfigRequest.InterfaceMetricUpdate))
  2346. {
  2347. TraceTag(ttidTcpip, "Sending notification to Tcpip about parameter changes for adapter %S.", pAdapter->m_strBindName.c_str());
  2348. TraceTag(ttidTcpip, "Gateway list update: %d", IpReconfigRequest.gatewayListUpdate);
  2349. TraceTag(ttidTcpip, "Interface metric update: %d", IpReconfigRequest.InterfaceMetricUpdate);
  2350. hrReconfig = pICallback->SendPnpReconfig(NCRL_NDIS, c_szTcpip,
  2351. pAdapter->m_strTcpipBindPath.c_str(),
  2352. &IpReconfigRequest,
  2353. sizeof(IP_PNP_RECONFIG_REQUEST));
  2354. //we dont want to request reboot if the error is ERROR_FILE_NOT_FOUND
  2355. //because that means the card is not loaded by the stack yet. Usually this is
  2356. //because the card was disabled from the connection UI. When the card is re-enabled,
  2357. //the statck will reload the card and load all settings from the registry. So a reboot
  2358. //is not needed
  2359. if (FAILED(hrReconfig) &&
  2360. HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) != hrReconfig)
  2361. {
  2362. TraceTag(ttidTcpip,"Notifying tcpip of adapter specific parameter change returns failure, prompt for reboot ...");
  2363. hr = NETCFG_S_REBOOT;
  2364. }
  2365. }
  2366. // if ATM adapter, notify atmarp if any parameter has changed
  2367. if (pAdapter->m_fIsAtmAdapter)
  2368. {
  2369. hrReconfig = HrReconfigAtmArp(pAdapter, pICallback);
  2370. if (hrReconfig != S_OK)
  2371. {
  2372. TraceTag(ttidTcpip,"Notifying tcpip of ATM ARP cleint of parameter change returns failure, prompt for reboot ...");
  2373. hr = NETCFG_S_REBOOT;
  2374. }
  2375. }
  2376. else if (pAdapter->m_fIs1394Adapter)
  2377. {
  2378. // $REVIEW JosephJ: I don't think we need to do
  2379. // anything here, because we have no parameters to
  2380. // change.
  2381. }
  2382. // ask for reboot if filter list has changed
  2383. if (m_glbGlobalInfo.m_fEnableFiltering)
  2384. {
  2385. if (!fIsSameVstr(pAdapter->m_vstrTcpFilterList, pAdapter->m_vstrOldTcpFilterList) ||
  2386. !fIsSameVstr(pAdapter->m_vstrUdpFilterList, pAdapter->m_vstrOldUdpFilterList) ||
  2387. !fIsSameVstr(pAdapter->m_vstrIpFilterList, pAdapter->m_vstrOldIpFilterList))
  2388. {
  2389. TraceTag(ttidTcpip, "This is temporary, filter list changed, ask for reboot");
  2390. hr = NETCFG_S_REBOOT;
  2391. }
  2392. }
  2393. }
  2394. // Send Wanarp reconfig notification if necessary
  2395. //
  2396. else if (pAdapter->m_fIsWanAdapter && pAdapter->m_fNewlyChanged)
  2397. {
  2398. if (FAILED(HrReconfigWanarp(pAdapter, pICallback)))
  2399. {
  2400. TraceTag(ttidTcpip, "Wanarp failed its reconfig. Need to reboot.");
  2401. hr = NETCFG_S_REBOOT;
  2402. }
  2403. }
  2404. }
  2405. TraceError("CTcpipcfg::HrReconfigIp",hr);
  2406. return hr;
  2407. }
  2408. //+---------------------------------------------------------------------------
  2409. //
  2410. // Member: CTcpipcfg::HrReconfigAtmArp
  2411. //
  2412. // Purpose: Notify ATM ARP of configuration changes
  2413. //
  2414. // Arguments: none
  2415. //
  2416. // Returns: S_OK if success, NETCFG_S_REBOOT if failure
  2417. //
  2418. HRESULT CTcpipcfg::HrReconfigAtmArp(ADAPTER_INFO *pAdapterInfo,
  2419. INetCfgPnpReconfigCallback* pICallback)
  2420. {
  2421. HRESULT hr = S_OK;
  2422. // check if any parameter has changed
  2423. DWORD dwFlag = 0;
  2424. // arp server list
  2425. if (!fIsSameVstr(pAdapterInfo->m_vstrARPServerList,
  2426. pAdapterInfo->m_vstrOldARPServerList))
  2427. {
  2428. dwFlag |= ATMARPC_RECONFIG_FLAG_ARPS_LIST_CHANGED;
  2429. }
  2430. // mar server list
  2431. if (!fIsSameVstr(pAdapterInfo->m_vstrMARServerList,
  2432. pAdapterInfo->m_vstrOldMARServerList))
  2433. {
  2434. dwFlag |= ATMARPC_RECONFIG_FLAG_MARS_LIST_CHANGED;
  2435. }
  2436. // MTU
  2437. if (pAdapterInfo->m_dwMTU != pAdapterInfo->m_dwOldMTU)
  2438. {
  2439. dwFlag |= ATMARPC_RECONFIG_FLAG_MTU_CHANGED;
  2440. }
  2441. // PVC Only
  2442. if (pAdapterInfo->m_fPVCOnly != pAdapterInfo->m_fOldPVCOnly)
  2443. {
  2444. dwFlag |= ATMARPC_RECONFIG_FLAG_PVC_MODE_CHANGED;
  2445. }
  2446. if (dwFlag) // yep, some parameter has changed
  2447. {
  2448. tstring strIpConfigString = RGAS_TCPIP_PARAM_INTERFACES;
  2449. strIpConfigString += pAdapterInfo->m_strTcpipBindPath;
  2450. DWORD dwBytes = sizeof(IP_PNP_RECONFIG_REQUEST) +
  2451. sizeof(ATMARPC_PNP_RECONFIG_REQUEST) +
  2452. sizeof(USHORT) +
  2453. sizeof(WCHAR)*(strIpConfigString.length() + 1);
  2454. PVOID pvBuf;
  2455. hr = HrMalloc (dwBytes, &pvBuf);
  2456. if (SUCCEEDED(hr))
  2457. {
  2458. BYTE* pbByte = reinterpret_cast<BYTE*>(pvBuf);
  2459. // 1) fillup ip reconfig structure
  2460. IP_PNP_RECONFIG_REQUEST * pIpReconfig =
  2461. reinterpret_cast<IP_PNP_RECONFIG_REQUEST *>(pbByte);
  2462. pIpReconfig->version =1;
  2463. // set valid offset
  2464. pIpReconfig->arpConfigOffset = sizeof(IP_PNP_RECONFIG_REQUEST);
  2465. // set rest to default
  2466. // pIpReconfig->securityEnabled =0;
  2467. // pIpReconfig->filterListUpdate =0;
  2468. pIpReconfig->gatewayListUpdate =0;
  2469. pIpReconfig->IPEnableRouter =0;
  2470. // 2) fill up atmarp reconfig structure
  2471. pbByte += sizeof(IP_PNP_RECONFIG_REQUEST);
  2472. ATMARPC_PNP_RECONFIG_REQUEST * pAtmarpcReconfig =
  2473. reinterpret_cast<ATMARPC_PNP_RECONFIG_REQUEST *>(pbByte);
  2474. pAtmarpcReconfig->Version = ATMARPC_RECONFIG_VERSION;
  2475. pAtmarpcReconfig->OpType = ATMARPC_RECONFIG_OP_MOD_INTERFACE;
  2476. // now set specifically what has changed
  2477. pAtmarpcReconfig->Flags = dwFlag;
  2478. // set the interface
  2479. pAtmarpcReconfig->IfKeyOffset = sizeof(ATMARPC_PNP_RECONFIG_REQUEST);
  2480. pbByte += sizeof(ATMARPC_PNP_RECONFIG_REQUEST);
  2481. USHORT* puCount = reinterpret_cast<USHORT *>(pbByte);
  2482. Assert (strIpConfigString.length() <= USHRT_MAX);
  2483. *puCount = (USHORT)strIpConfigString.length();
  2484. pbByte += sizeof(USHORT);
  2485. WCHAR * pwszBindName = reinterpret_cast<WCHAR *>(pbByte);
  2486. lstrcpyW(pwszBindName, strIpConfigString.c_str());
  2487. TraceTag(ttidTcpip, "Sending notification to AtmArpC for adapter %S", pwszBindName);
  2488. TraceTag(ttidTcpip, "OpType: %d", pAtmarpcReconfig->OpType);
  2489. TraceTag(ttidTcpip, "Flags: %d", pAtmarpcReconfig->Flags);
  2490. TraceTag(ttidTcpip, "WChar Count: %d", *puCount);
  2491. // now send the notification
  2492. hr = pICallback->SendPnpReconfig(NCRL_NDIS, c_szTcpip,
  2493. pAdapterInfo->m_strTcpipBindPath.c_str(),
  2494. pvBuf,
  2495. dwBytes);
  2496. //we dont want to request reboot if the error is ERROR_FILE_NOT_FOUND
  2497. //because that means the card is not loaded by the stack yet. Usually this is
  2498. //because the card was disabled from the connection UI. When the card is re-enabled,
  2499. //the statck will reload the card and load all settings from the registry. So a reboot
  2500. //is not needed
  2501. if (FAILED(hr) && HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) != hr)
  2502. {
  2503. TraceError("pICallback->SendPnpReconfig to AtmArpC returns failure:", hr);
  2504. hr = NETCFG_S_REBOOT;
  2505. }
  2506. MemFree(pvBuf);
  2507. }
  2508. }
  2509. TraceError("CTcpipcfg::HrReconfigAtmArp",hr);
  2510. return hr;
  2511. }
  2512. //+---------------------------------------------------------------------------
  2513. //
  2514. // Member: CTcpipcfg::ReconfigNbt
  2515. //
  2516. // Purpose: Notify NetBt of configuration changes
  2517. //
  2518. // Arguments: none
  2519. //
  2520. // Returns: S_OK if success, NETCFG_S_REBOOT if failure
  2521. //
  2522. HRESULT CTcpipcfg::HrReconfigNbt(INetCfgPnpReconfigCallback* pICallback)
  2523. {
  2524. HRESULT hr = S_OK;
  2525. NETBT_PNP_RECONFIG_REQUEST NetbtReconfigRequest;
  2526. // DWORD version
  2527. NetbtReconfigRequest.version = 1;
  2528. // Notify NetBt of any wins address changes (per adapter)
  2529. for (VCARD::iterator iterAdapter = m_vcardAdapterInfo.begin();
  2530. iterAdapter != m_vcardAdapterInfo.end();
  2531. iterAdapter++) // for each adapter
  2532. {
  2533. ADAPTER_INFO * pAdapter = *iterAdapter;
  2534. // If not wan adapter, and adapter is enabled
  2535. if ((!pAdapter->m_fIsWanAdapter) &&
  2536. (!pAdapter->m_fIsRasFakeAdapter) &&
  2537. (pAdapter->m_BindingState == BINDING_ENABLE) &&
  2538. (pAdapter->m_InitialBindingState != BINDING_DISABLE))
  2539. {
  2540. if ( (!fIsSameVstr(pAdapter->m_vstrWinsServerList,
  2541. pAdapter->m_vstrOldWinsServerList)) ||
  2542. (pAdapter->m_dwNetbiosOptions != pAdapter->m_dwOldNetbiosOptions))
  2543. {
  2544. TraceTag(ttidTcpip, "Sending notification to NetBt for per adapter parameter changes.");
  2545. if ( FAILED( pICallback->SendPnpReconfig(NCRL_TDI, c_szNetBt,
  2546. pAdapter->m_strNetBtBindPath.c_str(),
  2547. NULL,
  2548. 0)))
  2549. {
  2550. TraceTag(ttidTcpip,"Notifying NetBt of Wins address change returns failure, prompt for reboot ...");
  2551. hr = NETCFG_S_REBOOT;
  2552. };
  2553. }
  2554. }
  2555. }
  2556. // Notify NetBt of any global parameter changes
  2557. if (m_fLmhostsFileSet ||
  2558. (m_glbGlobalInfo.m_fEnableLmHosts != m_glbGlobalInfo.m_fOldEnableLmHosts))
  2559. {
  2560. TraceTag(ttidTcpip, "Sending notification to NetBt about NetBt parameter changes.");
  2561. // $REVIEW(tongl 11/14/97): since we do need to send some notification to tcpip,
  2562. // we need to read the correct value of "EnableDns" from registry
  2563. // This is a temporary thing so Malam can keep the ability to reconfigure these
  2564. // settings that used to be configurable in NT5 Beta1.
  2565. // $REVIEW(nsun 04/14/99): Per MalaM, most users don't use this value and NetBT
  2566. // will ignore this value. We should remove it from the data struct after Beta3.
  2567. NetbtReconfigRequest.enumDnsOption = WinsThenDns;
  2568. // m_glbGlobalInfo.m_fDnsEnableWins ? WinsThenDns : DnsOnly;
  2569. NetbtReconfigRequest.fScopeIdUpdated = FALSE;
  2570. NetbtReconfigRequest.fLmhostsEnabled = !!m_glbGlobalInfo.m_fEnableLmHosts;
  2571. NetbtReconfigRequest.fLmhostsFileSet = !!m_fLmhostsFileSet;
  2572. TraceTag(ttidTcpip, "Sending notification to NetBt for global parameter changes.");
  2573. TraceTag(ttidTcpip, "fLmhostsEnabled: %d", NetbtReconfigRequest.fLmhostsEnabled);
  2574. TraceTag(ttidTcpip, "fLmhostsFileSet: %d", NetbtReconfigRequest.fLmhostsFileSet);
  2575. if ( FAILED(pICallback->SendPnpReconfig(NCRL_TDI, c_szNetBt,
  2576. c_szEmpty,
  2577. &NetbtReconfigRequest,
  2578. sizeof(NETBT_PNP_RECONFIG_REQUEST))) )
  2579. {
  2580. TraceTag(ttidTcpip,"Notifying NetBt component of DNS parameter change returns failure, prompt for reboot ...");
  2581. hr = NETCFG_S_REBOOT;
  2582. };
  2583. }
  2584. return hr;
  2585. }
  2586. //+---------------------------------------------------------------------------
  2587. //
  2588. // Member: CTcpipcfg::ReconfigDns
  2589. //
  2590. // Purpose: Notify DNS Cache resolver service of configuration changes
  2591. //
  2592. // Arguments: fDoReconfigWithoutCheckingParams
  2593. // default is FALSE
  2594. // if TRUE, then will do Dns reconfig with checking if there
  2595. // is paramter changes or not
  2596. //
  2597. // Returns: S_OK if success, NETCFG_S_REBOOT otherwise
  2598. //
  2599. HRESULT CTcpipcfg::HrReconfigDns(BOOL fDoReconfigWithoutCheckingParams)
  2600. {
  2601. // Submit a generic reconfig notification to the service
  2602. // if any of the DNS related parameters have changed.
  2603. BOOL fDnsParamChanged = fDoReconfigWithoutCheckingParams;
  2604. if (!fDnsParamChanged)
  2605. {
  2606. // Suffix list and UseDomainNameDevolution changed ?
  2607. BOOL fDnsSuffixChanged =
  2608. !fIsSameVstr(m_glbGlobalInfo.m_vstrDnsSuffixList,
  2609. m_glbGlobalInfo.m_vstrOldDnsSuffixList);
  2610. if (fDnsSuffixChanged) // suffix changed
  2611. {
  2612. fDnsParamChanged = TRUE;
  2613. }
  2614. else if (m_glbGlobalInfo.m_vstrDnsSuffixList.size() == 0)
  2615. {
  2616. if (m_glbGlobalInfo.m_fUseDomainNameDevolution !=
  2617. m_glbGlobalInfo.m_fOldUseDomainNameDevolution)
  2618. fDnsParamChanged = TRUE;
  2619. }
  2620. }
  2621. // $REVIEW(tongl 6/19/98): DNS also cares about IP address, subnet mask & gateway changes
  2622. if (!fDnsParamChanged)
  2623. {
  2624. // Has any IP setting changed ?
  2625. for (VCARD::iterator iterAdapter = m_vcardAdapterInfo.begin();
  2626. iterAdapter != m_vcardAdapterInfo.end();
  2627. iterAdapter++)
  2628. {
  2629. ADAPTER_INFO* pAdapter = *iterAdapter;
  2630. // If not wan adapter
  2631. if (!pAdapter->m_fIsWanAdapter)
  2632. {
  2633. if ( ((!!pAdapter->m_fEnableDhcp) !=
  2634. (!!pAdapter->m_fOldEnableDhcp)) ||
  2635. (!fIsSameVstr(pAdapter->m_vstrIpAddresses,
  2636. pAdapter->m_vstrOldIpAddresses)) ||
  2637. (!fIsSameVstr(pAdapter->m_vstrSubnetMask,
  2638. pAdapter->m_vstrOldSubnetMask)) ||
  2639. (!fIsSameVstr(pAdapter->m_vstrDefaultGateway,
  2640. pAdapter->m_vstrOldDefaultGateway)) ||
  2641. (!fIsSameVstr(pAdapter->m_vstrDefaultGatewayMetric,
  2642. pAdapter->m_vstrOldDefaultGatewayMetric))
  2643. )
  2644. {
  2645. fDnsParamChanged = TRUE;
  2646. break;
  2647. }
  2648. }
  2649. }
  2650. }
  2651. HRESULT hr = S_OK;
  2652. if (fDnsParamChanged)
  2653. {
  2654. TraceTag(ttidTcpip, "Sending notification to Dns about Dns and IP parameter changes.");
  2655. hr = HrSendServicePnpEvent(c_szSvcDnscache,
  2656. SERVICE_CONTROL_PARAMCHANGE);
  2657. if (FAILED(hr))
  2658. {
  2659. if (HRESULT_FROM_WIN32(ERROR_SERVICE_NOT_ACTIVE) == hr)
  2660. {
  2661. TraceTag(ttidTcpip,"Notifying dnscache service of parameter change failed because DNS cache is not active.");
  2662. hr = S_OK;
  2663. }
  2664. else
  2665. {
  2666. TraceTag(ttidTcpip,"Notifying dnscache service of parameter change failed, prompt for reboot ...");
  2667. hr = NETCFG_S_REBOOT;
  2668. }
  2669. }
  2670. }
  2671. TraceError("CTcpipcfg::HrReconfigDns",hr);
  2672. return hr;
  2673. }
  2674. HRESULT CTcpipcfg::HrReconfigWanarp(ADAPTER_INFO *pAdapterInfo,
  2675. INetCfgPnpReconfigCallback* pICallback)
  2676. {
  2677. HRESULT hr;
  2678. DWORD cbInfo;
  2679. WANARP_RECONFIGURE_INFO* pInfo;
  2680. const IFACECOL& Ifaces = pAdapterInfo->m_IfaceIds;
  2681. cbInfo = sizeof(WANARP_RECONFIGURE_INFO) + (sizeof(GUID) * Ifaces.size());
  2682. hr = HrMalloc(cbInfo, (PVOID*)&pInfo);
  2683. if (SUCCEEDED(hr))
  2684. {
  2685. // Populate the data in the WANARP_RECONFIGURE_INFO structure.
  2686. //
  2687. INT nIndex;
  2688. pInfo->dwVersion = WANARP_RECONFIGURE_VERSION;
  2689. pInfo->wrcOperation = WRC_ADD_INTERFACES;
  2690. pInfo->ulNumInterfaces = Ifaces.size();
  2691. IFACECOL::const_iterator iter;
  2692. for (iter = Ifaces.begin(), nIndex = 0; iter != Ifaces.end();
  2693. iter++, nIndex++)
  2694. {
  2695. pInfo->rgInterfaces[nIndex] = *iter;
  2696. }
  2697. TraceTag(ttidNetCfgPnp, "Sending NDIS reconfig Pnp event to Upper:%S "
  2698. "lower: %S for %d interfaces",
  2699. c_szTcpip,
  2700. pAdapterInfo->m_strTcpipBindPath.c_str(),
  2701. pInfo->ulNumInterfaces);
  2702. hr = pICallback->SendPnpReconfig(NCRL_NDIS, c_szTcpip,
  2703. pAdapterInfo->m_strTcpipBindPath.c_str(),
  2704. pInfo,
  2705. cbInfo);
  2706. // Send the notification.
  2707. //
  2708. MemFree(pInfo);
  2709. }
  2710. TraceError("CTcpipcfg::HrReconfigWanarp",hr);
  2711. return hr;
  2712. }
  2713. //+---------------------------------------------------------------------------
  2714. //
  2715. // Member: CTcpipcfg::HrSetActiveIpsecPolicy
  2716. //
  2717. // Purpose: Set a user chosen local policy
  2718. //
  2719. // Arguments: none
  2720. //
  2721. // Returns: S_OK if success, NETCFG_S_REBOOT otherwise
  2722. //
  2723. //IPSec is removed from connection UI
  2724. /*
  2725. HRESULT CTcpipcfg::HrSetActiveIpsecPolicy()
  2726. {
  2727. HRESULT hr = S_OK;
  2728. AssertSz(m_glbGlobalInfo.m_strIpsecPol != c_szIpsecUnset, "Ipsec policy unset ?");
  2729. if (m_glbGlobalInfo.m_strIpsecPol != c_szIpsecUnset)
  2730. {
  2731. // load the polstore dll & get export function
  2732. typedef HRESULT (WINAPI * PFNHrSetAssignedLocalPolicy)(GUID * pActivePolId);
  2733. HMODULE hPolStore;
  2734. FARPROC pfn;
  2735. hr = HrLoadLibAndGetProc (L"polstore.dll",
  2736. "HrSetAssignedLocalPolicy",
  2737. &hPolStore, &pfn);
  2738. if (S_OK == hr)
  2739. {
  2740. Assert(hPolStore != NULL);
  2741. Assert(pfn != NULL);
  2742. PFNHrSetAssignedLocalPolicy pfnHrSetAssignedLocalPolicy =
  2743. reinterpret_cast<PFNHrSetAssignedLocalPolicy>(pfn);
  2744. if (m_glbGlobalInfo.m_strIpsecPol == c_szIpsecNoPol)
  2745. {
  2746. // no ipsec
  2747. TraceTag(ttidTcpip, "Calling HrSetAssignedLocalPolicy with NULL.");
  2748. hr = (*pfnHrSetAssignedLocalPolicy)(NULL);
  2749. TraceTag(ttidTcpip, "HrSetActivePolicy returns hr: %x", hr);
  2750. }
  2751. else
  2752. {
  2753. WCHAR szPolicyGuid[c_cchGuidWithTerm];
  2754. BOOL fSucceeded = StringFromGUID2(m_glbGlobalInfo.m_guidIpsecPol,
  2755. szPolicyGuid,
  2756. c_cchGuidWithTerm);
  2757. TraceTag(ttidTcpip, "Calling HrSetActivePolicy with %S.", szPolicyGuid);
  2758. hr = (*pfnHrSetAssignedLocalPolicy)(&(m_glbGlobalInfo.m_guidIpsecPol));
  2759. TraceTag(ttidTcpip, "HrSetAssignedLocalPolicy returns hr: %x", hr);
  2760. }
  2761. if (FAILED(hr))
  2762. {
  2763. TraceError("Failed setting active ipsec policy.", hr);
  2764. NcMsgBoxWithWin32ErrorText(DwWin32ErrorFromHr(hr),
  2765. _Module.GetResourceInstance(),
  2766. ::GetActiveWindow(),
  2767. IDS_MSFT_TCP_TEXT,
  2768. IDS_WIN32_ERROR_FORMAT,
  2769. IDS_SET_IPSEC_FAILED,
  2770. MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK);
  2771. hr = S_OK;
  2772. }
  2773. FreeLibrary (hPolStore);
  2774. }
  2775. else
  2776. {
  2777. TraceTag(ttidTcpip,"Failed to get function HrSetActivePolicy from polstore.dll");
  2778. hr = S_OK;
  2779. }
  2780. }
  2781. TraceError("CTcpipcfg::HrSetActiveIpsecPolicy", hr);
  2782. return hr;
  2783. }
  2784. */
  2785. //+---------------------------------------------------------------------------
  2786. //
  2787. // Member: CTcpipcfg::HrSaveMultipleInterfaceWanRegistry
  2788. //
  2789. // Purpose: For WAN adapters with multiple interfaces, we need to check every
  2790. // interface to see if it is newly added. If so, create the interface
  2791. // subkey and set the default settings
  2792. //
  2793. // Arguments: hkeyInterface CCS\Services\Tcpip\Parameters\Interfaces key
  2794. // pAdapter ADAPTER_INFO pointer to settings of the WAN adapter
  2795. //
  2796. // Returns: S_OK if success, E_FAIL otherwise
  2797. //
  2798. // Author: nsun 08/29/98
  2799. HRESULT CTcpipcfg::HrSaveMultipleInterfaceWanRegistry(const HKEY hkeyInterfaces,
  2800. ADAPTER_INFO* pAdapter)
  2801. {
  2802. HRESULT hr = S_OK;
  2803. IFACEITER iterId;
  2804. tstring strInterfaceName;
  2805. for (iterId = pAdapter->m_IfaceIds.begin();
  2806. iterId != pAdapter->m_IfaceIds.end();
  2807. iterId ++)
  2808. {
  2809. GetInterfaceName(
  2810. pAdapter->m_strTcpipBindPath.c_str(),
  2811. *iterId,
  2812. &strInterfaceName);
  2813. HRESULT hrTmp;
  2814. HKEY hkeyInterfaceParam;
  2815. DWORD dwDisposition;
  2816. hrTmp = HrRegCreateKeyEx(hkeyInterfaces,
  2817. strInterfaceName.c_str(),
  2818. REG_OPTION_NON_VOLATILE, KEY_READ_WRITE, NULL,
  2819. &hkeyInterfaceParam, &dwDisposition);
  2820. if (SUCCEEDED(hrTmp))
  2821. {
  2822. //We don't set default settings if the WAN interface is NOT newly added.
  2823. if (REG_CREATED_NEW_KEY == dwDisposition)
  2824. {
  2825. hrTmp = HrRegSetDword(hkeyInterfaceParam,
  2826. RGAS_USEZEROBROADCAST,
  2827. 0);
  2828. if (SUCCEEDED(hr))
  2829. hr = hrTmp;
  2830. if (SUCCEEDED(hrTmp))
  2831. hrTmp = HrSaveStaticWanRegistry(hkeyInterfaceParam);
  2832. }
  2833. RegCloseKey(hkeyInterfaceParam);
  2834. }
  2835. if (SUCCEEDED(hr))
  2836. hr = hrTmp;
  2837. }
  2838. TraceError("CTcpipcfg::HrSaveTcpipRegistry", hr);
  2839. return hr;
  2840. }
  2841. //+---------------------------------------------------------------------------
  2842. //
  2843. // Member: CTcpipcfg::HrSaveWinsMultipleInterfaceWanRegistry
  2844. //
  2845. // Purpose: For WAN adapters with multiple interfaces, create the interface
  2846. // subkeys and set the default settings
  2847. //
  2848. // Arguments: hkeyInterface CCS\Services\NetBT\Parameters\Interfaces key
  2849. // pAdapter ADAPTER_INFO pointer to settings of the WAN adapter
  2850. //
  2851. // Returns: S_OK if success, E_FAIL otherwise
  2852. //
  2853. // Author: nsun 10/05/98
  2854. HRESULT CTcpipcfg::HrSaveWinsMultipleInterfaceWanRegistry(const HKEY hkeyInterfaces,
  2855. ADAPTER_INFO* pAdapter)
  2856. {
  2857. HRESULT hr = S_OK;
  2858. IFACEITER iterId;
  2859. tstring strInterfaceName;
  2860. for (iterId = pAdapter->m_IfaceIds.begin();
  2861. iterId != pAdapter->m_IfaceIds.end();
  2862. iterId++)
  2863. {
  2864. GetInterfaceName(
  2865. pAdapter->m_strNetBtBindPath.c_str(),
  2866. *iterId,
  2867. &strInterfaceName);
  2868. strInterfaceName.insert(0, c_szTcpip_);
  2869. HRESULT hrTmp;
  2870. HKEY hkeyInterfaceParam;
  2871. DWORD dwDisposition;
  2872. hrTmp = HrRegCreateKeyEx(hkeyInterfaces,
  2873. strInterfaceName.c_str(),
  2874. REG_OPTION_NON_VOLATILE, KEY_READ_WRITE, NULL,
  2875. &hkeyInterfaceParam, &dwDisposition);
  2876. if (SUCCEEDED(hrTmp))
  2877. {
  2878. //We don't set default settings if the WAN interface is NOT newly added.
  2879. if (REG_CREATED_NEW_KEY == dwDisposition)
  2880. {
  2881. VSTR vstrNameServerList;
  2882. hrTmp = HrRegSetColString(hkeyInterfaceParam,
  2883. RGAS_NETBT_NAMESERVERLIST,
  2884. vstrNameServerList);
  2885. if (SUCCEEDED(hr))
  2886. hr = hrTmp;
  2887. }
  2888. RegCloseKey(hkeyInterfaceParam);
  2889. }
  2890. if (SUCCEEDED(hr))
  2891. hr = hrTmp;
  2892. }
  2893. TraceError("CTcpipcfg::HrSaveTcpipRegistry", hr);
  2894. return hr;
  2895. }
  2896. //+---------------------------------------------------------------------------
  2897. //
  2898. // Member: CTcpipcfg::HrSaveStaticWanRegistry
  2899. //
  2900. // Purpose: Write static parameters for Wan adapters to registry
  2901. //
  2902. // Arguments: none
  2903. //
  2904. // Returns: S_OK if success, E_FAIL otherwise
  2905. //
  2906. HRESULT CTcpipcfg::HrSaveStaticWanRegistry(HKEY hkeyInterfaceParam)
  2907. {
  2908. HRESULT hr = S_OK;
  2909. HRESULT hrTmp;
  2910. // EnableDHCP = 0
  2911. // IPAddress = 0.0.0.0
  2912. // SubnetMask = 0.0.0.0
  2913. // DefaultGateWay =
  2914. hrTmp = HrRegSetBool(hkeyInterfaceParam,
  2915. RGAS_ENABLE_DHCP, FALSE);
  2916. hr = hrTmp;
  2917. hrTmp = HrRegSetMultiSz(hkeyInterfaceParam,
  2918. RGAS_IPADDRESS, L"0.0.0.0\0");
  2919. if (SUCCEEDED(hr))
  2920. hr = hrTmp;
  2921. hrTmp = HrRegSetMultiSz(hkeyInterfaceParam,
  2922. RGAS_SUBNETMASK, L"0.0.0.0\0");
  2923. if (SUCCEEDED(hr))
  2924. hr = hrTmp;
  2925. hrTmp = HrRegSetMultiSz(hkeyInterfaceParam,
  2926. RGAS_DEFAULTGATEWAY, L"\0");
  2927. if (SUCCEEDED(hr))
  2928. hr = hrTmp;
  2929. //(nsun 11/02/98) set static RRAS parameters for unattended install
  2930. hrTmp = HrRegSetBool(hkeyInterfaceParam,
  2931. c_szDeadGWDetect,
  2932. m_glbGlobalInfo.m_fDeadGWDetectDefault);
  2933. if (SUCCEEDED(hr))
  2934. hr = hrTmp;
  2935. hrTmp = HrRegSetBool(hkeyInterfaceParam,
  2936. c_szDontAddDefaultGateway,
  2937. m_glbGlobalInfo.m_fDontAddDefaultGatewayDefault);
  2938. if (SUCCEEDED(hr))
  2939. hr = hrTmp;
  2940. TraceError("CTcpipcfg::HrSaveStaticWanRegistry", hr);
  2941. return hr;
  2942. }
  2943. //+---------------------------------------------------------------------------
  2944. //
  2945. // Member: CTcpipcfg::HrSaveStaticAtmRegistry
  2946. //
  2947. // Purpose: Write static parameters for Wan adapters to registry
  2948. //
  2949. // Arguments: none
  2950. //
  2951. // Returns: S_OK if success, E_FAIL otherwise
  2952. //
  2953. HRESULT CTcpipcfg::HrSaveStaticAtmRegistry(HKEY hkeyInterfaceParam)
  2954. {
  2955. HRESULT hr = S_OK;
  2956. HRESULT hrTmp = S_OK;
  2957. HKEY hkeyAtmarpc;
  2958. DWORD dwDisposition;
  2959. // Open the Atmarpc subkey
  2960. hrTmp = HrRegCreateKeyEx(hkeyInterfaceParam,
  2961. c_szAtmarpc,
  2962. REG_OPTION_NON_VOLATILE,
  2963. KEY_READ_WRITE,
  2964. NULL,
  2965. &hkeyAtmarpc,
  2966. &dwDisposition);
  2967. if (SUCCEEDED(hrTmp))
  2968. {
  2969. // SapSelector
  2970. hrTmp = HrRegSetDword(hkeyAtmarpc,
  2971. c_szREG_SapSelector,
  2972. c_dwSapSelector);
  2973. hr = hrTmp;
  2974. // AddressResolutionTimeout
  2975. hrTmp = HrRegSetDword(hkeyAtmarpc,
  2976. c_szREG_AddressResolutionTimeout,
  2977. c_dwAddressResolutionTimeout);
  2978. if (SUCCEEDED(hr))
  2979. hr = hrTmp;
  2980. // ARPEntryAgingTimeout
  2981. hrTmp = HrRegSetDword(hkeyAtmarpc,
  2982. c_szREG_ARPEntryAgingTimeout,
  2983. c_dwARPEntryAgingTimeout);
  2984. if (SUCCEEDED(hr))
  2985. hr = hrTmp;
  2986. // InARPWaitTimeout
  2987. hrTmp = HrRegSetDword(hkeyAtmarpc,
  2988. c_szREG_SapSelector,
  2989. c_dwSapSelector);
  2990. if (SUCCEEDED(hr))
  2991. hr = hrTmp;
  2992. // MaxRegistrationAttempts
  2993. hrTmp = HrRegSetDword(hkeyAtmarpc,
  2994. c_szREG_InARPWaitTimeout,
  2995. c_dwInARPWaitTimeout);
  2996. if (SUCCEEDED(hr))
  2997. hr = hrTmp;
  2998. // MaxResolutionAttempts
  2999. hrTmp = HrRegSetDword(hkeyAtmarpc,
  3000. c_szREG_MaxResolutionAttempts,
  3001. c_dwMaxResolutionAttempts);
  3002. if (SUCCEEDED(hr))
  3003. hr = hrTmp;
  3004. // MinWaitAfterNak
  3005. hrTmp = HrRegSetDword(hkeyAtmarpc,
  3006. c_szREG_SapSelector,
  3007. c_dwSapSelector);
  3008. if (SUCCEEDED(hr))
  3009. hr = hrTmp;
  3010. // ServerConnectInterval
  3011. hrTmp = HrRegSetDword(hkeyAtmarpc,
  3012. c_szREG_MinWaitAfterNak,
  3013. c_dwMinWaitAfterNak);
  3014. if (SUCCEEDED(hr))
  3015. hr = hrTmp;
  3016. // ServerRefreshTimeout
  3017. hrTmp = HrRegSetDword(hkeyAtmarpc,
  3018. c_szREG_ServerRefreshTimeout,
  3019. c_dwServerRefreshTimeout);
  3020. if (SUCCEEDED(hr))
  3021. hr = hrTmp;
  3022. // ServerRegistrationTimeout
  3023. hrTmp = HrRegSetDword(hkeyAtmarpc,
  3024. c_szREG_ServerRegistrationTimeout,
  3025. c_dwServerRegistrationTimeout);
  3026. if (SUCCEEDED(hr))
  3027. hr = hrTmp;
  3028. // DefaultVcAgingTimeout
  3029. hrTmp = HrRegSetDword(hkeyAtmarpc,
  3030. c_szREG_DefaultVcAgingTimeout,
  3031. c_dwDefaultVcAgingTimeout);
  3032. if (SUCCEEDED(hr))
  3033. hr = hrTmp;
  3034. // MARSConnectInterval
  3035. hrTmp = HrRegSetDword(hkeyAtmarpc,
  3036. c_szREG_MARSConnectInterval,
  3037. c_dwMARSConnectInterval);
  3038. if (SUCCEEDED(hr))
  3039. hr = hrTmp;
  3040. // MARSRegistrationTimeout
  3041. hrTmp = HrRegSetDword(hkeyAtmarpc,
  3042. c_szREG_MARSRegistrationTimeout,
  3043. c_dwMARSRegistrationTimeout);
  3044. if (SUCCEEDED(hr))
  3045. hr = hrTmp;
  3046. // JoinTimeout
  3047. hrTmp = HrRegSetDword(hkeyAtmarpc,
  3048. c_szREG_JoinTimeout,
  3049. c_dwJoinTimeout);
  3050. if (SUCCEEDED(hr))
  3051. hr = hrTmp;
  3052. // LeaveTimeout
  3053. hrTmp = HrRegSetDword(hkeyAtmarpc,
  3054. c_szREG_LeaveTimeout,
  3055. c_dwLeaveTimeout);
  3056. if (SUCCEEDED(hr))
  3057. hr = hrTmp;
  3058. // MaxDelayBetweenMULTIs
  3059. hrTmp = HrRegSetDword(hkeyAtmarpc,
  3060. c_szREG_MaxDelayBetweenMULTIs,
  3061. c_dwMaxDelayBetweenMULTIs);
  3062. if (SUCCEEDED(hr))
  3063. hr = hrTmp;
  3064. RegCloseKey(hkeyAtmarpc);
  3065. }
  3066. TraceError("CTcpipcfg::HrSaveStaticAtmRegistry", hr);
  3067. return hr;
  3068. }
  3069. //+---------------------------------------------------------------------------
  3070. //
  3071. // Name: ReInitializeInternalState
  3072. //
  3073. // Purpose: Reinitialize internal state at the end of Apply if Apply SUCCEEDED
  3074. //
  3075. // Arguments:
  3076. //
  3077. // Returns: None
  3078. // Author: tongl 4 Sept 1997
  3079. // Notes: Fix bug# 105383
  3080. //
  3081. //
  3082. void CTcpipcfg::ReInitializeInternalState()
  3083. {
  3084. // Reset global and adapter parameter values if necessary
  3085. if (m_fSaveRegistry || m_fReconfig)
  3086. {
  3087. m_glbGlobalInfo.ResetOldValues();
  3088. for (VCARD::iterator iterAdapter = m_vcardAdapterInfo.begin();
  3089. iterAdapter != m_vcardAdapterInfo.end();
  3090. iterAdapter++)
  3091. {
  3092. ADAPTER_INFO* pAdapter = *iterAdapter;
  3093. pAdapter->ResetOldValues();
  3094. }
  3095. }
  3096. // Reset internal flags
  3097. m_fRemoving = FALSE;
  3098. m_fInstalling = FALSE;
  3099. m_fSaveRegistry = FALSE;
  3100. m_fReconfig = FALSE;
  3101. // Initialize the netbt_pnp_reconfig_request structure
  3102. m_fLmhostsFileSet = FALSE;
  3103. }
  3104. // This functions adds a new RAS fake GUID directly to our memory structure,
  3105. // and loads info from the RAS phone book.
  3106. HRESULT CTcpipcfg::UpdateRasAdapterInfo(
  3107. const RASCON_IPUI& RasInfo)
  3108. {
  3109. HRESULT hr;
  3110. ADAPTER_INFO* pAdapter;
  3111. hr = S_OK;
  3112. m_fSaveRegistry = TRUE;
  3113. WCHAR szGuid [c_cchGuidWithTerm];
  3114. StringFromGUID2(RasInfo.guidConnection, szGuid, c_cchGuidWithTerm);
  3115. pAdapter = PAdapterFromInstanceGuid(&RasInfo.guidConnection);
  3116. if (!pAdapter)
  3117. {
  3118. pAdapter = new ADAPTER_INFO;
  3119. hr = pAdapter->HrSetDefaults(&RasInfo.guidConnection,
  3120. c_szRasFakeAdapterDesc, szGuid, szGuid);
  3121. if (SUCCEEDED(hr))
  3122. {
  3123. m_vcardAdapterInfo.push_back(pAdapter);
  3124. pAdapter->m_fIsRasFakeAdapter = TRUE;
  3125. }
  3126. else
  3127. {
  3128. delete pAdapter;
  3129. pAdapter = NULL;
  3130. Assert (FAILED(hr));
  3131. }
  3132. }
  3133. else
  3134. {
  3135. //We need to set default even if the ras connection is already in our adapter list
  3136. //because we should update all the paramters based on the phone book
  3137. hr = pAdapter->HrSetDefaults(&RasInfo.guidConnection,
  3138. c_szRasFakeAdapterDesc, szGuid, szGuid);
  3139. pAdapter->m_fIsRasFakeAdapter = TRUE;
  3140. }
  3141. if (SUCCEEDED(hr))
  3142. {
  3143. Assert (pAdapter);
  3144. // Now see if we should overwrite some of the parameters
  3145. // from what's in the phone book
  3146. if (RasInfo.dwFlags & RCUIF_USE_IP_ADDR)
  3147. {
  3148. // use static IP address
  3149. pAdapter->m_fEnableDhcp = FALSE;
  3150. pAdapter->m_fOldEnableDhcp = FALSE;
  3151. pAdapter->m_vstrIpAddresses.push_back(new tstring(RasInfo.pszwIpAddr));
  3152. CopyVstr(&pAdapter->m_vstrOldIpAddresses,
  3153. pAdapter->m_vstrIpAddresses);
  3154. // generate the subnet mask
  3155. tstring strIpAddress = RasInfo.pszwIpAddr;
  3156. tstring strSubnetMask;
  3157. DWORD adwIpAddress[4];
  3158. GetNodeNum(strIpAddress.c_str(), adwIpAddress);
  3159. DWORD nValue = adwIpAddress[0];
  3160. if (nValue <= SUBNET_RANGE_1_MAX)
  3161. {
  3162. strSubnetMask = c_szBASE_SUBNET_MASK_1;
  3163. }
  3164. else if (nValue <= SUBNET_RANGE_2_MAX)
  3165. {
  3166. strSubnetMask = c_szBASE_SUBNET_MASK_2;
  3167. }
  3168. else if (nValue <= SUBNET_RANGE_3_MAX)
  3169. {
  3170. strSubnetMask = c_szBASE_SUBNET_MASK_3;
  3171. }
  3172. else
  3173. {
  3174. AssertSz(FALSE, "Invaid IP address ?");
  3175. }
  3176. pAdapter->m_vstrSubnetMask.push_back(new tstring(strSubnetMask.c_str()));
  3177. CopyVstr(&pAdapter->m_vstrOldSubnetMask,
  3178. pAdapter->m_vstrSubnetMask);
  3179. }
  3180. if (RasInfo.dwFlags & RCUIF_USE_NAME_SERVERS)
  3181. {
  3182. // use DNS and WINS addresses
  3183. if (RasInfo.pszwDnsAddr && lstrlenW(RasInfo.pszwDnsAddr))
  3184. pAdapter->m_vstrDnsServerList.push_back(new tstring(RasInfo.pszwDnsAddr));
  3185. if (RasInfo.pszwDns2Addr && lstrlenW(RasInfo.pszwDns2Addr))
  3186. pAdapter->m_vstrDnsServerList.push_back(new tstring(RasInfo.pszwDns2Addr));
  3187. CopyVstr(&pAdapter->m_vstrOldDnsServerList,
  3188. pAdapter->m_vstrDnsServerList);
  3189. if (RasInfo.pszwWinsAddr && lstrlenW(RasInfo.pszwWinsAddr))
  3190. pAdapter->m_vstrWinsServerList.push_back(new tstring(RasInfo.pszwWinsAddr));
  3191. if (RasInfo.pszwWins2Addr && lstrlenW(RasInfo.pszwWins2Addr))
  3192. pAdapter->m_vstrWinsServerList.push_back(new tstring(RasInfo.pszwWins2Addr));
  3193. CopyVstr(&pAdapter->m_vstrOldWinsServerList,
  3194. pAdapter->m_vstrWinsServerList);
  3195. }
  3196. pAdapter->m_fUseRemoteGateway = !!(RasInfo.dwFlags & RCUIF_USE_REMOTE_GATEWAY);
  3197. pAdapter->m_fUseIPHeaderCompression = !!(RasInfo.dwFlags & RCUIF_USE_HEADER_COMPRESSION);
  3198. pAdapter->m_dwFrameSize = RasInfo.dwFrameSize;
  3199. pAdapter->m_fIsDemandDialInterface = !!(RasInfo.dwFlags & RCUIF_DEMAND_DIAL);
  3200. pAdapter->m_fDisableDynamicUpdate = !!(RasInfo.dwFlags & RCUIF_USE_DISABLE_REGISTER_DNS);
  3201. pAdapter->m_fOldDisableDynamicUpdate = pAdapter->m_fDisableDynamicUpdate;
  3202. pAdapter->m_fEnableNameRegistration = !!(RasInfo.dwFlags & RCUIF_USE_PRIVATE_DNS_SUFFIX);
  3203. pAdapter->m_fOldEnableNameRegistration = pAdapter->m_fEnableNameRegistration;
  3204. if (RasInfo.dwFlags & RCUIF_ENABLE_NBT)
  3205. {
  3206. pAdapter->m_dwNetbiosOptions = c_dwEnableNetbios;
  3207. pAdapter->m_dwOldNetbiosOptions = c_dwEnableNetbios;
  3208. }
  3209. else
  3210. {
  3211. pAdapter->m_dwNetbiosOptions = c_dwDisableNetbios;
  3212. pAdapter->m_dwOldNetbiosOptions = c_dwDisableNetbios;
  3213. }
  3214. pAdapter->m_strDnsDomain = RasInfo.pszwDnsSuffix;
  3215. pAdapter->m_strOldDnsDomain = pAdapter->m_strDnsDomain;
  3216. }
  3217. TraceError("CTcpipcfg::UpdateRasAdapterInfo", hr);
  3218. return hr;
  3219. }
  3220. HRESULT CTcpipcfg::HrDuplicateToNT4Location(HKEY hkeyInterface, ADAPTER_INFO * pAdapter)
  3221. {
  3222. Assert(hkeyInterface);
  3223. Assert(pAdapter);
  3224. HRESULT hr = S_OK;
  3225. HKEY hkeyServices = NULL;
  3226. HKEY hkeyNt4 = NULL;
  3227. DWORD dwDisposition;
  3228. tstring strNt4SubKey = pAdapter->m_strBindName;
  3229. strNt4SubKey += c_szRegParamsTcpip;
  3230. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegServices,
  3231. KEY_READ, &hkeyServices);
  3232. if (FAILED(hr))
  3233. {
  3234. TraceTag(ttidTcpip, "HrRemoveNt4DuplicateRegistry: Failed to open the Services reg key, hr: %x", hr);
  3235. goto LERROR;
  3236. }
  3237. hr = HrRegCreateKeyEx(hkeyServices, strNt4SubKey.c_str(),
  3238. REG_OPTION_NON_VOLATILE, KEY_READ_WRITE_DELETE, NULL,
  3239. &hkeyNt4, &dwDisposition);
  3240. if (SUCCEEDED(hr))
  3241. {
  3242. HRESULT hrRead = S_OK;
  3243. HRESULT hrWrite = S_OK;
  3244. //Grant Network service and Netcfg OP the access to the NT4 key if
  3245. //this is a newly created key
  3246. //if the keys already have the ACEs, then the APIs wont add duplicate ones
  3247. //We ignore the return value since nothing can be done if it failed
  3248. //Also this is not critical for the system to run
  3249. if (REG_CREATED_NEW_KEY == dwDisposition)
  3250. {
  3251. HrSetSecurityForNetConfigOpsOnSubkeys(hkeyServices, strNt4SubKey.c_str());
  3252. HrSetSecurityForNetSvcOnSubkeys(hkeyServices, strNt4SubKey.c_str());
  3253. }
  3254. UINT cValues = sizeof(s_rgNt4Values)/sizeof(*s_rgNt4Values);
  3255. VSTR vstrTmp;
  3256. tstring strTmp;
  3257. DWORD dwTmp;
  3258. BOOL fTmp;
  3259. for (UINT i = 0; i < cValues; i++)
  3260. {
  3261. switch(s_rgNt4Values[i].dwType)
  3262. {
  3263. case REG_BOOL:
  3264. hrRead = HrRegQueryDword(hkeyInterface,
  3265. s_rgNt4Values[i].pszValueName,
  3266. &dwTmp);
  3267. if (SUCCEEDED(hrRead))
  3268. {
  3269. fTmp = !!dwTmp;
  3270. hrWrite = HrRegSetBool(hkeyNt4,
  3271. s_rgNt4Values[i].pszValueName,
  3272. fTmp);
  3273. }
  3274. break;
  3275. case REG_DWORD:
  3276. hrRead = HrRegQueryDword(hkeyInterface,
  3277. s_rgNt4Values[i].pszValueName,
  3278. &dwTmp);
  3279. if (SUCCEEDED(hrRead))
  3280. hrWrite = HrRegSetDword(hkeyNt4,
  3281. s_rgNt4Values[i].pszValueName,
  3282. dwTmp);
  3283. break;
  3284. case REG_SZ:
  3285. hrRead = HrRegQueryString(hkeyInterface,
  3286. s_rgNt4Values[i].pszValueName,
  3287. &strTmp);
  3288. if (SUCCEEDED(hrRead))
  3289. hrWrite = HrRegSetString(hkeyNt4,
  3290. s_rgNt4Values[i].pszValueName,
  3291. strTmp);
  3292. break;
  3293. case REG_MULTI_SZ:
  3294. hrRead = HrRegQueryColString( hkeyInterface,
  3295. s_rgNt4Values[i].pszValueName,
  3296. &vstrTmp);
  3297. if (SUCCEEDED(hrRead))
  3298. {
  3299. hrWrite = HrRegSetColString(hkeyNt4,
  3300. s_rgNt4Values[i].pszValueName,
  3301. vstrTmp);
  3302. DeleteColString(&vstrTmp);
  3303. }
  3304. break;
  3305. }
  3306. #ifdef ENABLETRACE
  3307. if(FAILED(hrRead))
  3308. {
  3309. TraceTag(ttidTcpip, "HrDuplicateToNT4Location: Failed on loading %S, hr: %x",
  3310. s_rgNt4Values[i].pszValueName, hr);
  3311. }
  3312. if(FAILED(hrWrite))
  3313. {
  3314. TraceTag(ttidError,
  3315. "HrDuplicateToNT4Location: failed to write %S to the registry. hr = %x.",
  3316. s_rgNt4Values[i].pszValueName, hrWrite);
  3317. }
  3318. #endif
  3319. if (SUCCEEDED(hr))
  3320. hr = hrWrite;
  3321. }
  3322. RegSafeCloseKey(hkeyNt4);
  3323. }
  3324. RegSafeCloseKey(hkeyServices);
  3325. LERROR:
  3326. TraceError("CTcpipcfg::HrDuplicateToNT4Location", hr);
  3327. return hr;
  3328. }
  3329. //To solve the compatibility issues of non-nt5 applications, we duplicate some important
  3330. //per interface tcpip parameters to the old NT4 location: Services\{adapter GUID}\Parameters\Tcpip
  3331. //We need to clean it up when removing tcpip
  3332. HRESULT CTcpipcfg::HrRemoveNt4DuplicateRegistry()
  3333. {
  3334. //we also need to delete the duplicate reg values under Services\{adapter GUID}
  3335. HRESULT hr = S_OK;
  3336. HRESULT hrTmp = S_OK;
  3337. HKEY hkeyServices = NULL;
  3338. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegServices,
  3339. KEY_READ_WRITE_DELETE, &hkeyServices);
  3340. if (FAILED(hr))
  3341. {
  3342. TraceTag(ttidTcpip, "HrRemoveNt4DuplicateRegistry: Failed to open the Services reg key, hr: %x", hr);
  3343. }
  3344. else
  3345. {
  3346. for (VCARD::iterator iterAdapter = m_vcardAdapterInfo.begin();
  3347. iterAdapter != m_vcardAdapterInfo.end();
  3348. iterAdapter++)
  3349. {
  3350. ADAPTER_INFO* pAdapter = *iterAdapter;
  3351. if (!pAdapter->m_fIsWanAdapter && !pAdapter->m_fIsRasFakeAdapter)
  3352. {
  3353. hrTmp = HrRegDeleteKeyTree(hkeyServices, pAdapter->m_strBindName.c_str());
  3354. #ifdef ENABLETRACE
  3355. if (FAILED(hrTmp))
  3356. {
  3357. TraceTag(ttidTcpip, "CTcpipcfg::HrRemoveNt4DuplicateRegistry");
  3358. TraceTag(ttidTcpip, "Failed on deleting duplicated Nt4 layout key: Services\\%S, hr: %x",
  3359. pAdapter->m_strBindName.c_str(), hrTmp);
  3360. }
  3361. #endif
  3362. }
  3363. }
  3364. RegSafeCloseKey(hkeyServices);
  3365. }
  3366. TraceError("CTcpipcfg::HrRemoveNt4DuplicateRegistry", hr);
  3367. return hr;
  3368. }
  3369. HRESULT CTcpipcfg::HrCleanUpPerformRouterDiscoveryFromRegistry()
  3370. {
  3371. HRESULT hr = S_OK;
  3372. HKEY hkey = NULL;
  3373. hr = m_pnccTcpip->OpenParamKey(&hkey);
  3374. if (SUCCEEDED(hr))
  3375. {
  3376. Assert(hkey);
  3377. HRESULT hrTemp = S_OK;
  3378. //delete the global PerformRouterDiscoveryDefault value
  3379. hrTemp = HrRegDeleteValue(hkey,
  3380. c_szPerformRouterDiscoveryDefault);
  3381. if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hrTemp)
  3382. hrTemp = S_OK;
  3383. if (SUCCEEDED(hr))
  3384. hr = hrTemp;
  3385. HKEY hkeyInterfaces = NULL;
  3386. hrTemp = HrRegOpenKeyEx(hkey,
  3387. c_szInterfacesRegKey,
  3388. KEY_READ,
  3389. &hkeyInterfaces);
  3390. if (SUCCEEDED(hrTemp) && hkeyInterfaces)
  3391. {
  3392. WCHAR szBuf[256];
  3393. DWORD dwSize = celems(szBuf);
  3394. FILETIME time;
  3395. DWORD dwRegIndex = 0;
  3396. while (SUCCEEDED(hrTemp = HrRegEnumKeyEx(hkeyInterfaces,
  3397. dwRegIndex++,
  3398. szBuf,
  3399. &dwSize,
  3400. NULL,
  3401. NULL,
  3402. &time)))
  3403. {
  3404. HKEY hkeyIf = NULL;
  3405. dwSize = celems(szBuf);
  3406. hrTemp = HrRegOpenKeyEx(hkeyInterfaces,
  3407. szBuf,
  3408. KEY_READ_WRITE_DELETE,
  3409. &hkeyIf);
  3410. if (SUCCEEDED(hr))
  3411. hr = hrTemp;
  3412. if (SUCCEEDED(hrTemp))
  3413. {
  3414. Assert(hkeyIf);
  3415. DWORD dwTemp = 0;
  3416. hrTemp = HrRegQueryDword(hkeyIf,
  3417. c_szPerformRouterDiscovery,
  3418. &dwTemp);
  3419. if (SUCCEEDED(hrTemp))
  3420. {
  3421. if (IP_IRDP_DISABLED != dwTemp)
  3422. {
  3423. hrTemp = HrRegDeleteValue(hkeyIf,
  3424. c_szPerformRouterDiscovery);
  3425. if (SUCCEEDED(hr))
  3426. hr = hrTemp;
  3427. }
  3428. }
  3429. else if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hrTemp)
  3430. {
  3431. hrTemp = S_OK;
  3432. }
  3433. if (SUCCEEDED(hr))
  3434. hr = hrTemp;
  3435. RegSafeCloseKey(hkeyIf);
  3436. }
  3437. }
  3438. if (HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hrTemp)
  3439. hrTemp = S_OK;
  3440. if (SUCCEEDED(hr))
  3441. hr = hrTemp;
  3442. RegSafeCloseKey(hkeyInterfaces);
  3443. }
  3444. RegSafeCloseKey(hkey);
  3445. }
  3446. else if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
  3447. {
  3448. hr = S_OK;
  3449. }
  3450. TraceError("CTcpipcfg::HrCleanUpPerformRouterDiscoveryFromRegistry", hr);
  3451. return hr;
  3452. }
  3453. HRESULT CTcpipcfg::HrSaveBackupTcpSettings(HKEY hkeyInterfaceParam, ADAPTER_INFO * pAdapter)
  3454. {
  3455. HRESULT hr = S_OK;
  3456. HKEY hkeyDhcpConfigs = NULL;
  3457. HKEY hkeyDhcpCfg = NULL;
  3458. DWORD dwDisposition = 0;
  3459. tstring strConfigurationName;
  3460. tstring strReg;
  3461. if (!pAdapter->m_BackupInfo.m_fAutoNet)
  3462. {
  3463. //Set the Configuration option name as "Alternate_{Interface GUID}"
  3464. strConfigurationName = c_szAlternate;
  3465. strConfigurationName += pAdapter->m_strBindName;
  3466. //construct the NULL terminator for the Multi_SZ
  3467. int cch = strConfigurationName.length() + 2;
  3468. WCHAR * pwsz = new WCHAR[cch];
  3469. if (NULL == pwsz)
  3470. return E_OUTOFMEMORY;
  3471. ZeroMemory(pwsz, sizeof(pwsz[0]) * cch);
  3472. lstrcpyW(pwsz, strConfigurationName.c_str());
  3473. hr = HrRegSetMultiSz(hkeyInterfaceParam,
  3474. c_szActiveConfigurations,
  3475. pwsz);
  3476. delete [] pwsz;
  3477. }
  3478. else
  3479. {
  3480. hr = HrRegDeleteValue(hkeyInterfaceParam,
  3481. c_szActiveConfigurations);
  3482. if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
  3483. hr = S_OK;
  3484. }
  3485. if (FAILED(hr))
  3486. {
  3487. TraceTag(ttidTcpip, "HrSaveBackupTcpSettings: Failed to create ActiveConfigurations value, hr: %x", hr);
  3488. goto LERROR;
  3489. }
  3490. hr = HrRegCreateKeyEx(HKEY_LOCAL_MACHINE, c_szDhcpConfigurations,
  3491. REG_OPTION_NON_VOLATILE, KEY_READ, NULL,
  3492. &hkeyDhcpConfigs, &dwDisposition);
  3493. if (FAILED(hr))
  3494. {
  3495. TraceTag(ttidTcpip, "HrSaveBackupTcpSettings: Failed to open the Services reg key, hr: %x", hr);
  3496. goto LERROR;
  3497. }
  3498. hr = HrRegCreateKeyEx(hkeyDhcpConfigs, strConfigurationName.c_str(),
  3499. REG_OPTION_NON_VOLATILE, KEY_READ_WRITE, NULL,
  3500. &hkeyDhcpCfg, &dwDisposition);
  3501. if (SUCCEEDED(hr))
  3502. {
  3503. DWORD pdwOptionData[2]; // buffer holding the option's Dwords
  3504. DWORD dwIdxData; // actual data to be saved into blob for each option
  3505. LPBYTE pRegRaw = NULL; // buffer holding the blob
  3506. DWORD cb = 0; // blob size in the pRegRaw buffer
  3507. DWORD cbMax = 0; // pRegRaw buffer size (assert(cb<=cbMax))
  3508. // fill in the blob pRegRaw to be written to the registry
  3509. //
  3510. // fill in option 50 (requested IpAddress = Fallback IpAddress)
  3511. pdwOptionData[0] = htonl(IPStringToDword(pAdapter->m_BackupInfo.m_strIpAddr.c_str()));
  3512. // the adapter's address can't be an empty string hence a 0.0.0.0 address
  3513. hr = HrSaveBackupDwordOption (
  3514. OPTION_REQUESTED_ADDRESS,
  3515. pdwOptionData,
  3516. 1,
  3517. &pRegRaw,
  3518. &cb,
  3519. &cbMax);
  3520. // fill in option 1 (Fallback subnet mask)
  3521. if (hr == S_OK)
  3522. {
  3523. pdwOptionData[0] =
  3524. htonl(IPStringToDword(pAdapter->m_BackupInfo.m_strSubnetMask.c_str()));
  3525. // the adapter's subnet mask can't be an empty string, hence a 0.0.0.0 address
  3526. hr = HrSaveBackupDwordOption (
  3527. OPTION_SUBNET_MASK,
  3528. pdwOptionData,
  3529. 1,
  3530. &pRegRaw,
  3531. &cb,
  3532. &cbMax);
  3533. }
  3534. // fill in option 3 if any Fallback gateway is specified
  3535. if (hr == S_OK)
  3536. {
  3537. dwIdxData = 0;
  3538. pdwOptionData[dwIdxData] =
  3539. htonl(IPStringToDword(pAdapter->m_BackupInfo.m_strDefGw.c_str()));
  3540. dwIdxData += (pdwOptionData[dwIdxData] != 0);
  3541. hr = HrSaveBackupDwordOption (
  3542. OPTION_ROUTER_ADDRESS,
  3543. pdwOptionData,
  3544. dwIdxData,
  3545. &pRegRaw,
  3546. &cb,
  3547. &cbMax);
  3548. }
  3549. // fill in option 6 if any Fallback DNS servers (maximum 2 supported for now) is specified
  3550. if (hr == S_OK)
  3551. {
  3552. dwIdxData = 0;
  3553. pdwOptionData[dwIdxData] =
  3554. htonl(IPStringToDword(pAdapter->m_BackupInfo.m_strPreferredDns.c_str()));
  3555. dwIdxData += (pdwOptionData[dwIdxData] != 0);
  3556. pdwOptionData[dwIdxData] =
  3557. htonl(IPStringToDword(pAdapter->m_BackupInfo.m_strAlternateDns.c_str()));
  3558. dwIdxData += (pdwOptionData[dwIdxData] != 0);
  3559. hr = HrSaveBackupDwordOption (
  3560. OPTION_DOMAIN_NAME_SERVERS,
  3561. pdwOptionData,
  3562. dwIdxData,
  3563. &pRegRaw,
  3564. &cb,
  3565. &cbMax);
  3566. }
  3567. // fill in option 44 if any Fallback WINS servers (maximum 2 supported for now) is specified
  3568. if (hr == S_OK)
  3569. {
  3570. dwIdxData = 0;
  3571. pdwOptionData[dwIdxData] =
  3572. htonl(IPStringToDword(pAdapter->m_BackupInfo.m_strPreferredWins.c_str()));
  3573. dwIdxData += (pdwOptionData[dwIdxData] != 0);
  3574. pdwOptionData[dwIdxData] =
  3575. htonl(IPStringToDword(pAdapter->m_BackupInfo.m_strAlternateWins.c_str()));
  3576. dwIdxData += (pdwOptionData[dwIdxData] != 0);
  3577. hr = HrSaveBackupDwordOption (
  3578. OPTION_NETBIOS_NAME_SERVER,
  3579. pdwOptionData,
  3580. dwIdxData,
  3581. &pRegRaw,
  3582. &cb,
  3583. &cbMax);
  3584. }
  3585. // write the blob to the registry
  3586. if (hr == S_OK)
  3587. {
  3588. hr = HrRegSetBinary(hkeyDhcpCfg,
  3589. c_szConfigOptions,
  3590. pRegRaw,
  3591. cb);
  3592. }
  3593. // free whatever mem was allocated
  3594. if (pRegRaw != NULL)
  3595. CoTaskMemFree(pRegRaw);
  3596. RegSafeCloseKey(hkeyDhcpCfg);
  3597. }
  3598. RegSafeCloseKey(hkeyDhcpConfigs);
  3599. LERROR:
  3600. return hr;
  3601. }
  3602. ///////////////////////////////////////////////////////////////////
  3603. // Fills in a DHCP DWORD option into a blob. Adjusts the size of
  3604. // the buffer holding the blob if needed and returns through the
  3605. // out params the new buffer, its size and the size of the blob
  3606. // it contains.
  3607. HRESULT CTcpipcfg::HrSaveBackupDwordOption (
  3608. /*IN*/ DWORD Option,
  3609. /*IN*/ DWORD OptionData[],
  3610. /*IN*/ DWORD OptionDataSz,
  3611. /*IN OUT*/ LPBYTE *ppBuffer,
  3612. /*IN OUT*/ LPDWORD pdwBlobSz,
  3613. /*IN OUT*/ LPDWORD pdwBufferSz)
  3614. {
  3615. DWORD dwBlobSz;
  3616. REG_BACKUP_INFO *pRegBackupInfo;
  3617. DWORD dwOptIdx;
  3618. // if no data is available at all, then don't save anything
  3619. if (OptionDataSz == 0)
  3620. return S_OK;
  3621. // calculate the memory size needed for the new updated blob.
  3622. // don't forget, REG_BACKUP_INFO already contains one DWORD from the Option's data
  3623. dwBlobSz = (*pdwBlobSz) + sizeof(REG_BACKUP_INFO) + (OptionDataSz-1)*sizeof(DWORD);
  3624. // check whether the buffer is large enough to hold the new blob
  3625. if ((*pdwBufferSz) < dwBlobSz)
  3626. {
  3627. HRESULT hr;
  3628. LPBYTE pNewBuffer;
  3629. DWORD dwBuffSz;
  3630. // get the expected size of the new buffer
  3631. dwBuffSz = (DWORD)(max((*pdwBufferSz) + BUFFER_ENLARGEMENT_CHUNK, dwBlobSz));
  3632. // if the pointer provided is NULL...
  3633. if (*ppBuffer == NULL)
  3634. {
  3635. // ...this means we have to do the initial allocation
  3636. pNewBuffer = (LPBYTE)CoTaskMemAlloc(dwBuffSz);
  3637. }
  3638. else
  3639. {
  3640. // ...otherwise is just a buffer enlargement so do a
  3641. // realloc in order to keep the original payload
  3642. pNewBuffer = (LPBYTE)CoTaskMemRealloc((*ppBuffer), dwBuffSz);
  3643. }
  3644. if (pNewBuffer == NULL)
  3645. return E_OUTOFMEMORY;
  3646. // starting from this point we don't expect any other errors
  3647. // so start update the output parameters
  3648. (*ppBuffer) = pNewBuffer;
  3649. (*pdwBufferSz) += dwBuffSz;
  3650. }
  3651. // get the mem storage seen as a REG_BACKUP_INFO struct
  3652. pRegBackupInfo = (REG_BACKUP_INFO *)((*ppBuffer) + (*pdwBlobSz));
  3653. (*pdwBlobSz) = dwBlobSz;
  3654. // update the blob by adding the new option
  3655. pRegBackupInfo->dwOptionId = Option;
  3656. pRegBackupInfo->dwClassLen = 0; // fallback options don't have a class
  3657. pRegBackupInfo->dwDataLen = OptionDataSz * sizeof(DWORD);
  3658. pRegBackupInfo->dwIsVendor = 0; // fallback options are not vendor options
  3659. pRegBackupInfo->dwExpiryTime = 0x7fffffff; // fallback options don't expire
  3660. // add all the Option's data
  3661. for (dwOptIdx = 0; dwOptIdx < OptionDataSz; dwOptIdx++)
  3662. {
  3663. pRegBackupInfo->dwData[dwOptIdx] = OptionData[dwOptIdx];
  3664. }
  3665. return S_OK;
  3666. }
  3667. HRESULT CTcpipcfg::HrLoadBackupTcpSettings(HKEY hkeyInterfaceParam, ADAPTER_INFO * pAdapter)
  3668. {
  3669. HRESULT hr = S_OK;
  3670. //construct the string "Alternate_{Interface GUID}"
  3671. tstring strConfigurationName = c_szAlternate;
  3672. strConfigurationName += pAdapter->m_strBindName;
  3673. // if ActiveConfigurations contain a string "Alternate_{Interface GUID}"
  3674. // then there is customized fall-back settings, otherwise Autonet
  3675. VSTR vstrTmp;
  3676. pAdapter->m_BackupInfo.m_fAutoNet = TRUE;
  3677. hr = HrRegQueryColString( hkeyInterfaceParam,
  3678. c_szActiveConfigurations,
  3679. &vstrTmp);
  3680. if (SUCCEEDED(hr))
  3681. {
  3682. BOOL fFound = FALSE;
  3683. for (int i = 0; i < (int)vstrTmp.size(); i++)
  3684. {
  3685. if (strConfigurationName == *vstrTmp[i])
  3686. {
  3687. pAdapter->m_BackupInfo.m_fAutoNet = FALSE;
  3688. break;
  3689. }
  3690. }
  3691. DeleteColString(&vstrTmp);
  3692. }
  3693. tstring strReg = c_szDhcpConfigurations;
  3694. strReg += _T("\\");
  3695. strReg += strConfigurationName;
  3696. HKEY hkeyDhcpConfig = NULL;
  3697. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, strReg.c_str(),
  3698. KEY_READ, &hkeyDhcpConfig);
  3699. if (SUCCEEDED(hr))
  3700. {
  3701. LPBYTE pBackupInfoForReg = NULL;
  3702. DWORD cb = 0;
  3703. hr = HrRegQueryBinaryWithAlloc(hkeyDhcpConfig,
  3704. c_szConfigOptions,
  3705. &pBackupInfoForReg,
  3706. &cb);
  3707. if (SUCCEEDED(hr))
  3708. {
  3709. LPBYTE pRaw;
  3710. pRaw = pBackupInfoForReg;
  3711. while (cb >= sizeof(REG_BACKUP_INFO))
  3712. {
  3713. REG_BACKUP_INFO *pOption;
  3714. pOption = (REG_BACKUP_INFO *)pRaw;
  3715. // don't forget REG_BACKUP_INFO already contains one DWORD from
  3716. // the data section. Although the statememnts below are somehow identical
  3717. // the compiler is expected to optimize the code: one constant generated
  3718. // at compile time for sizeof(REG_BACKUP_INFO) - sizeof(DWORD), and one
  3719. // register only used in both lines below.
  3720. cb -= sizeof(REG_BACKUP_INFO) - sizeof(DWORD);
  3721. pRaw += sizeof(REG_BACKUP_INFO) - sizeof(DWORD);
  3722. // since cb is DWORD take special care to avoid roll over
  3723. if (cb < pOption->dwDataLen)
  3724. break;
  3725. cb -= pOption->dwDataLen;
  3726. pRaw += pOption->dwDataLen;
  3727. HrLoadBackupOption(pOption, &pAdapter->m_BackupInfo);
  3728. }
  3729. MemFree(pBackupInfoForReg);
  3730. }
  3731. RegSafeCloseKey(hkeyDhcpConfig);
  3732. }
  3733. if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
  3734. {
  3735. //it's ok if the reg values are missing
  3736. hr = S_OK;
  3737. }
  3738. return hr;
  3739. }
  3740. ///////////////////////////////////////////////////////////////////
  3741. // transfers data from the registry raw representation of the option
  3742. // to the corresponding fields from the BACKUP_CFG_INFO structure
  3743. //
  3744. HRESULT CTcpipcfg::HrLoadBackupOption(
  3745. /*IN*/ REG_BACKUP_INFO *pOption,
  3746. /*OUT*/ BACKUP_CFG_INFO *pBackupInfo)
  3747. {
  3748. tstring *pIp1 = NULL;
  3749. tstring *pIp2 = NULL;
  3750. HRESULT hr = S_OK;
  3751. // depending on what the option is, have pIp1 & pIp2 point to the
  3752. // fields to be filled in from BACKUP_CFG_INFO
  3753. switch(pOption->dwOptionId)
  3754. {
  3755. case OPTION_REQUESTED_ADDRESS:
  3756. pIp1 = &pBackupInfo->m_strIpAddr;
  3757. break;
  3758. case OPTION_SUBNET_MASK:
  3759. pIp1 = &pBackupInfo->m_strSubnetMask;
  3760. break;
  3761. case OPTION_ROUTER_ADDRESS:
  3762. pIp1 = &pBackupInfo->m_strDefGw;
  3763. break;
  3764. case OPTION_DOMAIN_NAME_SERVERS:
  3765. pIp1 = &pBackupInfo->m_strPreferredDns;
  3766. pIp2 = &pBackupInfo->m_strAlternateDns;
  3767. break;
  3768. case OPTION_NETBIOS_NAME_SERVER:
  3769. pIp1 = &pBackupInfo->m_strPreferredWins;
  3770. pIp2 = &pBackupInfo->m_strAlternateWins;
  3771. break;
  3772. default:
  3773. return HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
  3774. }
  3775. // each option has at least one IpAddress value
  3776. DwordToIPString(ntohl(pOption->dwData[0]), *pIp1);
  3777. // if the option has more than one IpAddress (meaning two :-)
  3778. // and if it is supposed to allow 2 addresses to be specified
  3779. // then fill up the second field as well.
  3780. if (pOption->dwDataLen > sizeof(DWORD) && pIp2 != NULL)
  3781. DwordToIPString(ntohl(pOption->dwData[1]), *pIp2);
  3782. return hr;
  3783. }
  3784. //Cleanup the backup settings registry under System\Services\dhcp
  3785. // wszAdapterName GUID of the adapter of which we want to delete the registry
  3786. HRESULT CTcpipcfg::HrDeleteBackupSettingsInDhcp(LPCWSTR wszAdapterName)
  3787. {
  3788. HRESULT hr = S_OK;
  3789. HKEY hkeyDhcpConfigs = NULL;
  3790. HKEY hkeyDhcpCfg = NULL;
  3791. DWORD dwDisposition = 0;
  3792. tstring strConfigurationName = c_szAlternate;
  3793. strConfigurationName += wszAdapterName;;
  3794. hr = HrRegCreateKeyEx(HKEY_LOCAL_MACHINE, c_szDhcpConfigurations,
  3795. REG_OPTION_NON_VOLATILE, KEY_READ_WRITE_DELETE, NULL,
  3796. &hkeyDhcpConfigs, &dwDisposition);
  3797. if (FAILED(hr))
  3798. {
  3799. TraceTag(ttidTcpip, "HrDeleteBackupSettingsInDhcp: Failed to open the Services reg key, hr: %x", hr);
  3800. goto LERROR;
  3801. }
  3802. hr = HrRegDeleteKeyTree(hkeyDhcpConfigs, strConfigurationName.c_str());
  3803. RegSafeCloseKey(hkeyDhcpConfigs);
  3804. LERROR:
  3805. return hr;
  3806. }
  3807. HRESULT CTcpipcfg::HrSetSecurityForNetConfigOpsOnSubkeys(HKEY hkeyRoot, LPCWSTR strKeyName)
  3808. {
  3809. PSID psidGroup = NULL;
  3810. SID_IDENTIFIER_AUTHORITY sidAuth = SECURITY_NT_AUTHORITY;
  3811. HRESULT hr = S_OK;
  3812. if (AllocateAndInitializeSid(&sidAuth, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS, 0, 0, 0, 0, 0, 0, &psidGroup))
  3813. {
  3814. CRegKeySecurity rkSecurity;
  3815. hr = rkSecurity.RegOpenKey(hkeyRoot, strKeyName);
  3816. if (SUCCEEDED(hr))
  3817. {
  3818. hr = rkSecurity.GetKeySecurity();
  3819. if (SUCCEEDED(hr))
  3820. {
  3821. hr = rkSecurity.GrantRightsOnRegKey(psidGroup, KEY_READ_WRITE_DELETE, KEY_ALL);
  3822. }
  3823. rkSecurity.RegCloseKey();
  3824. }
  3825. FreeSid(psidGroup);
  3826. }
  3827. return hr;
  3828. }
  3829. HRESULT CTcpipcfg::HrSetSecurityForNetSvcOnSubkeys(HKEY hkeyRoot, LPCWSTR strKeyName)
  3830. {
  3831. PSID psidNetSvc = NULL;
  3832. SID_IDENTIFIER_AUTHORITY sidAuth = SECURITY_NT_AUTHORITY;
  3833. HRESULT hr = S_OK;
  3834. if (AllocateAndInitializeSid(&sidAuth, 1, SECURITY_NETWORK_SERVICE_RID, 0, 0, 0, 0, 0, 0, 0, &psidNetSvc))
  3835. {
  3836. CRegKeySecurity rkSecurity;
  3837. hr = rkSecurity.RegOpenKey(hkeyRoot, strKeyName);
  3838. if (SUCCEEDED(hr))
  3839. {
  3840. hr = rkSecurity.GetKeySecurity();
  3841. if (SUCCEEDED(hr))
  3842. {
  3843. hr = rkSecurity.GrantRightsOnRegKey(psidNetSvc, KEY_READ_WRITE_DELETE, KEY_ALL);
  3844. }
  3845. rkSecurity.RegCloseKey();
  3846. }
  3847. FreeSid(psidNetSvc);
  3848. }
  3849. return hr;
  3850. }
  3851. //Update the NT4 registry permission to grant Netcfg Op and Network Service access
  3852. //This is called during upgrade
  3853. HRESULT CTcpipcfg::HrUpdateNt4RegistryPermission()
  3854. {
  3855. HRESULT hr = S_OK;
  3856. HKEY hkeyServices = NULL;
  3857. tstring strNt4SubKey;
  3858. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE,
  3859. c_szRegServices,
  3860. KEY_READ,
  3861. &hkeyServices);
  3862. if (FAILED(hr))
  3863. {
  3864. TraceTag(ttidTcpip, "HrUpdateNt4RegistryPermission: Failed to open the Services reg key, hr: %x", hr);
  3865. return hr;
  3866. }
  3867. for(VCARD::iterator iterAdapter = m_vcardAdapterInfo.begin();
  3868. iterAdapter != m_vcardAdapterInfo.end();
  3869. iterAdapter ++)
  3870. {
  3871. ADAPTER_INFO * pAdapter = *iterAdapter;
  3872. if (pAdapter->m_fIsRasFakeAdapter || pAdapter->m_fIsWanAdapter)
  3873. {
  3874. continue;
  3875. }
  3876. strNt4SubKey = pAdapter->m_strBindName;
  3877. strNt4SubKey += c_szRegParamsTcpip;
  3878. //Grant Network service and Netcfg OP the access to the NT4 key
  3879. //if the keys already have the ACEs, then the APIs wont add duplicate ones
  3880. //
  3881. //We ignore the return value since nothing can be done if it failed
  3882. //Also this is not critical for the system to run
  3883. HrSetSecurityForNetConfigOpsOnSubkeys(hkeyServices, strNt4SubKey.c_str());
  3884. HrSetSecurityForNetSvcOnSubkeys(hkeyServices, strNt4SubKey.c_str());
  3885. }
  3886. RegSafeCloseKey(hkeyServices);
  3887. return hr;
  3888. }