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

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