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.

1605 lines
47 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: S T E E L H E A D . C P P
  7. //
  8. // Contents: Implementation of Steelhead configuration object.
  9. //
  10. // Notes:
  11. //
  12. // Author: shaunco 15 Jun 1997
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include <mprerror.h>
  18. #include <tdi.h> // must include for isnkrnl.h
  19. #include <isnkrnl.h>
  20. #include <rtinfo.h>
  21. #include "rasobj.h"
  22. #include "ncsvc.h"
  23. #include "netcfgp.h"
  24. #include "router.h"
  25. extern const WCHAR c_szBiNdis5[];
  26. extern const WCHAR c_szInfId_MS_NdisWan[];
  27. //+---------------------------------------------------------------------------
  28. // Static data for adding router managers.
  29. //
  30. static const WCHAR c_szRtrMgrIp [] = L"Ip";
  31. static const WCHAR c_szRtrMgrDllIp [] = L"%SystemRoot%\\System32\\iprtrmgr.dll";
  32. static const WCHAR c_szRtrMgrIpx [] = L"Ipx";
  33. static const WCHAR c_szRtrMgrDllIpx[] = L"%SystemRoot%\\System32\\ipxrtmgr.dll";
  34. static const ROUTER_MANAGER_INFO c_rmiIp =
  35. {
  36. PID_IP,
  37. 0,
  38. c_szRtrMgrIp,
  39. c_szRtrMgrDllIp,
  40. MakeIpInterfaceInfo,
  41. MakeIpTransportInfo,
  42. };
  43. static const ROUTER_MANAGER_INFO c_rmiIpx =
  44. {
  45. PID_IPX,
  46. ISN_FRAME_TYPE_AUTO,
  47. c_szRtrMgrIpx,
  48. c_szRtrMgrDllIpx ,
  49. MakeIpxInterfaceInfo,
  50. MakeIpxTransportInfo,
  51. };
  52. // These guids are defined in sdk\inc\ifguid.h
  53. // We need the string versions.
  54. //
  55. // DEFINE_GUID(GUID_IpLoopbackInterface, 0xca6c0780, 0x7526, 0x11d2, 0xba, 0xf4, 0x00, 0x60, 0x08, 0x15, 0xa4, 0xbd);
  56. // DEFINE_GUID(GUID_IpRasServerInterface, 0x6e06f030, 0x7526, 0x11d2, 0xba, 0xf4, 0x00, 0x60, 0x08, 0x15, 0xa4, 0xbd);
  57. // DEFINE_GUID(GUID_IpxInternalInterface, 0xa571ba70, 0x7527, 0x11d2, 0xba, 0xf4, 0x00, 0x60, 0x08, 0x15, 0xa4, 0xbd);
  58. //static const WCHAR c_szIpLoopbackInterface [] = L"ca6c0780-7526-11d2-00600815a4bd";
  59. //static const WCHAR c_szIpRasServerInterface [] = L"6e06f030-7526-11d2-00600815a4bd";
  60. //static const WCHAR c_szIpxInternalInterface [] = L"a571ba70-7527-11d2-00600815a4bd";
  61. // For Ipx, the adapter name is the bind name.
  62. // We need to create an interface per frame type.
  63. // The interface name is the adapter name followed
  64. // by these strings.
  65. //
  66. #pragma BEGIN_CONST_SECTION
  67. static const MAP_SZ_DWORD c_mapFrameType [] =
  68. {
  69. L"/EthII", MISN_FRAME_TYPE_ETHERNET_II,
  70. L"/802.3", MISN_FRAME_TYPE_802_3,
  71. L"/802.2", MISN_FRAME_TYPE_802_2,
  72. L"/SNAP", MISN_FRAME_TYPE_SNAP,
  73. };
  74. #pragma END_CONST_SECTION
  75. NOTHROW
  76. BOOL
  77. FMapFrameTypeToString (
  78. DWORD dwFrameType,
  79. PCWSTR* ppszFrameType)
  80. {
  81. Assert (ppszFrameType);
  82. for (int i = 0; i < celems (c_mapFrameType); i++)
  83. {
  84. if (dwFrameType == c_mapFrameType[i].dwValue)
  85. {
  86. *ppszFrameType = c_mapFrameType[i].pszValue;
  87. return TRUE;
  88. }
  89. }
  90. TraceTag (ttidRasCfg, "FMapFrameTypeToString: Unknown frame type %d!",
  91. dwFrameType);
  92. *ppszFrameType = NULL;
  93. return FALSE;
  94. }
  95. NOTHROW
  96. BOOL
  97. FMapStringToFrameType (
  98. PCWSTR pszFrameType,
  99. DWORD* pdwFrameType)
  100. {
  101. Assert (pszFrameType);
  102. Assert (pdwFrameType);
  103. for (int i = 0; i < celems (c_mapFrameType); i++)
  104. {
  105. if (0 == lstrcmpW (pszFrameType, c_mapFrameType[i].pszValue))
  106. {
  107. *pdwFrameType = c_mapFrameType[i].dwValue;
  108. return TRUE;
  109. }
  110. }
  111. TraceTag (ttidRasCfg, "FMapStringToFrameType: Unknown frame type %S!",
  112. pszFrameType);
  113. *pdwFrameType = NULL;
  114. return FALSE;
  115. }
  116. //+---------------------------------------------------------------------------
  117. //
  118. // Function: HrShouldRouteOverAdapter
  119. //
  120. // Purpose: Indicate if we should router over the adapter or not.
  121. //
  122. // Arguments:
  123. // pnccAdapter [in] Adapter to test.
  124. // ppszBindName [out] Returned bindname if S_OK is returned.
  125. //
  126. // Returns: S_OK if we should router over the adapter, S_FALSE if not.
  127. //
  128. // Author: shaunco 27 Aug 1997
  129. //
  130. // Notes:
  131. //
  132. HRESULT
  133. HrShouldRouteOverAdapter (
  134. INetCfgComponent* pnccAdapter,
  135. PWSTR* ppszBindName)
  136. {
  137. Assert (pnccAdapter);
  138. // Initialize the output parameter.
  139. //
  140. if (ppszBindName)
  141. {
  142. *ppszBindName = NULL;
  143. }
  144. // We should return S_OK if the adapter is physical or it supports
  145. // a binding interface of ndis5. S_FALSE otherwise.
  146. //
  147. DWORD dwCharacter;
  148. HRESULT hr = pnccAdapter->GetCharacteristics (&dwCharacter);
  149. if (SUCCEEDED(hr) && !(dwCharacter & NCF_PHYSICAL))
  150. {
  151. INetCfgComponentBindings* pnccBindings;
  152. hr = pnccAdapter->QueryInterface (
  153. IID_INetCfgComponentBindings,
  154. reinterpret_cast<VOID**>(&pnccBindings));
  155. if (SUCCEEDED(hr))
  156. {
  157. hr = pnccBindings->SupportsBindingInterface (
  158. NCF_UPPER, c_szBiNdis5);
  159. ReleaseObj (pnccBindings);
  160. }
  161. if (S_OK == hr)
  162. {
  163. // Only consider devices which are present.
  164. //
  165. // This check is made *after* the check for binding interface
  166. // match above for two reasons. 1) It's much more expensive
  167. // 2) for ndiswan devices which do not come online when they
  168. // are installed (e.g. ndiswannbfout), GetDeviceStatus will
  169. // fail. For this case we don't want to route over ndiswannbf
  170. // anyhow so we should just return S_FALSE and not a failure.
  171. //
  172. DWORD dwStatus;
  173. hr = pnccAdapter->GetDeviceStatus(&dwStatus);
  174. if (SUCCEEDED(hr) && (CM_PROB_DEVICE_NOT_THERE == dwStatus))
  175. {
  176. hr = S_FALSE;
  177. }
  178. }
  179. }
  180. // SupportsBindingInterface may return S_OK or S_FALSE.
  181. // We only want the bind name if we're going to return S_OK.
  182. //
  183. if ((S_OK == hr) && ppszBindName)
  184. {
  185. hr = pnccAdapter->GetBindName (ppszBindName);
  186. }
  187. TraceError ("HrShouldRouteOverAdapter", (S_FALSE == hr) ? S_OK : hr);
  188. return hr;
  189. }
  190. //+---------------------------------------------------------------------------
  191. //
  192. // Member: CSteelhead::CSteelhead
  193. //
  194. // Purpose: Constructor
  195. //
  196. // Arguments:
  197. // (none)
  198. //
  199. // Returns: Nothing.
  200. //
  201. // Author: shaunco 28 Jul 1997
  202. //
  203. // Notes:
  204. //
  205. CSteelhead::CSteelhead () : CRasBindObject ()
  206. {
  207. m_hMprConfig = NULL;
  208. m_hMprAdmin = NULL;
  209. m_fRemoving = FALSE;
  210. m_fUpdateRouterConfiguration = FALSE;
  211. m_pnccMe = NULL;
  212. }
  213. //+---------------------------------------------------------------------------
  214. //
  215. // Member: CSteelhead::~CSteelhead
  216. //
  217. // Purpose: Destructor
  218. //
  219. // Arguments:
  220. // (none)
  221. //
  222. // Returns: Nothing.
  223. //
  224. // Author: shaunco 28 Jul 1997
  225. //
  226. // Notes:
  227. //
  228. CSteelhead::~CSteelhead ()
  229. {
  230. Assert (!m_hMprConfig);
  231. Assert (!m_hMprAdmin);
  232. ReleaseObj (m_pnccMe);
  233. }
  234. //+---------------------------------------------------------------------------
  235. //
  236. // Member: CSteelhead::FAdapterExistsWithMatchingBindName
  237. //
  238. // Purpose:
  239. //
  240. // Arguments:
  241. // pszAdapterName [in]
  242. // ppnccAdapter [out]
  243. //
  244. // Returns:
  245. //
  246. // Author: shaunco 27 Aug 1997
  247. //
  248. // Notes:
  249. //
  250. BOOL
  251. CSteelhead::FAdapterExistsWithMatchingBindName (
  252. PCWSTR pszAdapterName,
  253. INetCfgComponent** ppnccAdapter)
  254. {
  255. Assert (pszAdapterName);
  256. Assert (ppnccAdapter);
  257. *ppnccAdapter = NULL;
  258. BOOL fFound = FALSE;
  259. // Enumerate physical adapters in the system.
  260. //
  261. HRESULT hr = S_OK;
  262. CIterNetCfgComponent nccIter (m_pnc, &GUID_DEVCLASS_NET);
  263. INetCfgComponent* pnccAdapter;
  264. while (!fFound && S_OK == (hr = nccIter.HrNext (&pnccAdapter)))
  265. {
  266. // Only consider this adapter if we should router over it.
  267. //
  268. PWSTR pszBindName;
  269. hr = HrShouldRouteOverAdapter (pnccAdapter, &pszBindName);
  270. if (S_OK == hr)
  271. {
  272. if (0 == lstrcmpW (pszAdapterName, pszBindName))
  273. {
  274. fFound = TRUE;
  275. *ppnccAdapter = pnccAdapter;
  276. AddRefObj (pnccAdapter);
  277. }
  278. CoTaskMemFree (pszBindName);
  279. }
  280. ReleaseObj (pnccAdapter);
  281. }
  282. return fFound;
  283. }
  284. //+---------------------------------------------------------------------------
  285. //
  286. // Member: CSteelhead::FIpxFrameTypeInUseOnAdapter
  287. //
  288. // Purpose:
  289. //
  290. // Arguments:
  291. // dwFrameType []
  292. // pszAdapterName []
  293. //
  294. // Returns:
  295. //
  296. // Author: shaunco 27 Aug 1997
  297. //
  298. // Notes:
  299. //
  300. BOOL
  301. CSteelhead::FIpxFrameTypeInUseOnAdapter (
  302. DWORD dwFrameType,
  303. PCWSTR pszAdapterName)
  304. {
  305. // Assume its not in use. If PnccIpx() is NULL, it means IPX is not
  306. // installed and the frame type is definately not in use on the adapter.
  307. //
  308. BOOL fRet = FALSE;
  309. if (PnccIpx())
  310. {
  311. // Get the private interface off of the INetCfgComponent for IPX
  312. // then we can query for a notify object interface
  313. //
  314. INetCfgComponentPrivate* pinccp;
  315. HRESULT hr = PnccIpx()->QueryInterface(
  316. IID_INetCfgComponentPrivate,
  317. reinterpret_cast<VOID**>(&pinccp));
  318. if (SUCCEEDED(hr))
  319. {
  320. IIpxAdapterInfo* pIpxAdapterInfo;
  321. hr = pinccp->QueryNotifyObject(
  322. IID_IIpxAdapterInfo,
  323. reinterpret_cast<VOID**>(&pIpxAdapterInfo));
  324. if (SUCCEEDED(hr))
  325. {
  326. // Get the frametypes in use for this adapter.
  327. //
  328. DWORD adwFrameType [MISN_FRAME_TYPE_MAX + 1];
  329. DWORD cdwFrameType;
  330. hr = pIpxAdapterInfo->GetFrameTypesForAdapter (
  331. pszAdapterName,
  332. celems (adwFrameType),
  333. adwFrameType,
  334. &cdwFrameType);
  335. if (SUCCEEDED(hr))
  336. {
  337. for (DWORD i = 0; i < cdwFrameType; i++)
  338. {
  339. if (dwFrameType == adwFrameType[i])
  340. {
  341. fRet = TRUE;
  342. break;
  343. }
  344. }
  345. }
  346. ReleaseObj (pIpxAdapterInfo);
  347. }
  348. ReleaseObj (pinccp);
  349. }
  350. }
  351. return fRet;
  352. }
  353. //+---------------------------------------------------------------------------
  354. //
  355. // Member: CSteelhead::FIpxFrameTypeInUseOnAdapter
  356. //
  357. // Purpose:
  358. //
  359. // Arguments:
  360. // pszFrameType []
  361. // pszAdapterName []
  362. //
  363. // Returns:
  364. //
  365. // Author: shaunco 27 Aug 1997
  366. //
  367. // Notes:
  368. //
  369. BOOL
  370. CSteelhead::FIpxFrameTypeInUseOnAdapter (
  371. PCWSTR pszFrameType,
  372. PCWSTR pszAdapterName)
  373. {
  374. // Assume its not in use. If PnccIpx() is NULL, it means IPX is not
  375. // installed and the frame type is definately not in use on the adapter.
  376. //
  377. BOOL fRet = FALSE;
  378. DWORD dwFrameType;
  379. if (PnccIpx() && FMapStringToFrameType (pszFrameType, &dwFrameType))
  380. {
  381. fRet = FIpxFrameTypeInUseOnAdapter (dwFrameType, pszAdapterName);
  382. }
  383. return fRet;
  384. }
  385. //+---------------------------------------------------------------------------
  386. //
  387. // Member: CSteelhead::HrEnsureRouterInterfaceForAdapter
  388. //
  389. // Purpose: Ensures the router interface block for the specified
  390. // interface (adapter) is present and that the specified router
  391. // manger is configured for that interface.
  392. //
  393. // Arguments:
  394. // dwIfType [in] Interface type
  395. // dwPacketType [in] The packet type (IPX only, ignored othewise)
  396. // pszAdapterName [in] The adapter name
  397. // pszInterfaceName [in] The interface name
  398. // rmi [in] The router manager
  399. //
  400. // Returns: S_OK or an error code.
  401. //
  402. // Author: shaunco 28 Jul 1997
  403. //
  404. // Notes:
  405. //
  406. HRESULT
  407. CSteelhead::HrEnsureRouterInterfaceForAdapter (
  408. ROUTER_INTERFACE_TYPE dwIfType,
  409. DWORD dwPacketType,
  410. PCWSTR pszAdapterName,
  411. PCWSTR pszInterfaceName,
  412. const ROUTER_MANAGER_INFO& rmi)
  413. {
  414. // Make sure the interface is created.
  415. //
  416. HANDLE hConfigInterface;
  417. HANDLE hAdminInterface;
  418. HRESULT hr = HrEnsureRouterInterface (
  419. dwIfType,
  420. pszInterfaceName,
  421. &hConfigInterface,
  422. &hAdminInterface);
  423. if (SUCCEEDED(hr))
  424. {
  425. // Ensure the router manager is added to the interface.
  426. //
  427. hr = HrEnsureRouterInterfaceTransport (
  428. pszAdapterName,
  429. dwPacketType,
  430. hConfigInterface,
  431. hAdminInterface,
  432. rmi);
  433. }
  434. TraceError ("CSteelhead::HrEnsureRouterInterfaceForAdapter", hr);
  435. return hr;
  436. }
  437. //+---------------------------------------------------------------------------
  438. //
  439. // Member: CSteelhead::HrEnsureIpxRouterInterfacesForAdapter
  440. //
  441. // Purpose:
  442. //
  443. // Arguments:
  444. // pszAdapterName []
  445. //
  446. // Returns:
  447. //
  448. // Author: shaunco 27 Aug 1997
  449. //
  450. // Notes:
  451. //
  452. HRESULT
  453. CSteelhead::HrEnsureIpxRouterInterfacesForAdapter (
  454. PCWSTR pszAdapterName)
  455. {
  456. AssertSz (PnccIpx(), "Why is this being called if IPX isn't installed?");
  457. // Get the IIpxAdapterInfo interface from the IPX notify object.
  458. // We'll use it to find out how adapters are configured under IPX.
  459. //
  460. IIpxAdapterInfo* pIpxAdapterInfo;
  461. HRESULT hr = HrQueryNotifyObject (
  462. PnccIpx(),
  463. IID_IIpxAdapterInfo,
  464. reinterpret_cast<VOID**>(&pIpxAdapterInfo));
  465. if (SUCCEEDED(hr))
  466. {
  467. // Get the frametypes in use for this adapter.
  468. //
  469. DWORD adwFrameType [MISN_FRAME_TYPE_MAX + 1];
  470. DWORD cdwFrameType;
  471. hr = pIpxAdapterInfo->GetFrameTypesForAdapter (
  472. pszAdapterName,
  473. celems (adwFrameType),
  474. adwFrameType,
  475. &cdwFrameType);
  476. if (SUCCEEDED(hr) && cdwFrameType)
  477. {
  478. // If more than one frame type is in use, or if there is only
  479. // one and it isn't auto, then we'll be creating interfaces
  480. // for those frame types explicitly.
  481. //
  482. if ((cdwFrameType > 1) ||
  483. ((1 == cdwFrameType) &&
  484. (ISN_FRAME_TYPE_AUTO != adwFrameType[0])))
  485. {
  486. for (DWORD i = 0; SUCCEEDED(hr) && (i < cdwFrameType); i++)
  487. {
  488. PCWSTR pszFrameType;
  489. if (FMapFrameTypeToString (adwFrameType[i], &pszFrameType))
  490. {
  491. // Make the interface name by catenating the
  492. // adapter (bind) name with the frame type.
  493. //
  494. WCHAR szInterfaceName [512];
  495. lstrcpyW (szInterfaceName, pszAdapterName);
  496. lstrcatW (szInterfaceName, pszFrameType);
  497. hr = HrEnsureRouterInterfaceForAdapter (
  498. ROUTER_IF_TYPE_DEDICATED,
  499. adwFrameType[i],
  500. pszAdapterName,
  501. szInterfaceName,
  502. c_rmiIpx);
  503. }
  504. }
  505. }
  506. // Otherwise, we'll create the interface for the auto frame
  507. // type case.
  508. //
  509. else
  510. {
  511. #ifdef DBG
  512. AssertSz (1 == cdwFrameType,
  513. "IPX should report at least one frame type. "
  514. "You may continue without a problem.");
  515. if (1 == cdwFrameType)
  516. {
  517. AssertSz (ISN_FRAME_TYPE_AUTO == adwFrameType[0],
  518. "Frame type should be auto here. "
  519. "You may continue without a problem.");
  520. }
  521. #endif
  522. hr = HrEnsureRouterInterfaceForAdapter (
  523. ROUTER_IF_TYPE_DEDICATED,
  524. ISN_FRAME_TYPE_AUTO,
  525. pszAdapterName,
  526. pszAdapterName,
  527. c_rmiIpx);
  528. }
  529. }
  530. ReleaseObj (pIpxAdapterInfo);
  531. }
  532. TraceError ("CSteelhead::HrEnsureIpxRouterInterfacesForAdapter", hr);
  533. return hr;
  534. }
  535. //+---------------------------------------------------------------------------
  536. //
  537. // Member: CSteelhead::HrEnsureRouterInterface
  538. //
  539. // Purpose: Ensures the specified router interface is present and
  540. // returns a handle to it.
  541. //
  542. // Arguments:
  543. // pszInterfaceName [in] The interface (adapter) name
  544. // phConfigInterface [out] Returned handle to the interface
  545. //
  546. // Returns: S_OK or an error code.
  547. //
  548. // Author: shaunco 28 Jul 1997
  549. //
  550. // Notes:
  551. //
  552. HRESULT
  553. CSteelhead::HrEnsureRouterInterface (
  554. ROUTER_INTERFACE_TYPE dwIfType,
  555. PCWSTR pszInterfaceName,
  556. HANDLE* phConfigInterface,
  557. HANDLE* phAdminInterface)
  558. {
  559. Assert (pszInterfaceName);
  560. Assert (phConfigInterface);
  561. Assert (phAdminInterface);
  562. // Initialize the output parameters.
  563. //
  564. *phConfigInterface = NULL;
  565. *phAdminInterface = NULL;
  566. HRESULT hrConfig;
  567. HRESULT hrAdmin;
  568. hrConfig = HrMprConfigInterfaceGetHandle (m_hMprConfig,
  569. const_cast<PWSTR>(pszInterfaceName),
  570. phConfigInterface);
  571. hrAdmin = HrMprAdminInterfaceGetHandle (m_hMprAdmin,
  572. const_cast<PWSTR>(pszInterfaceName),
  573. phAdminInterface, FALSE);
  574. if ((HRESULT_FROM_WIN32 (ERROR_NO_SUCH_INTERFACE ) == hrConfig) ||
  575. (HRESULT_FROM_WIN32 (ERROR_NO_SUCH_INTERFACE ) == hrAdmin))
  576. {
  577. // It's not installed, so we'll create it.
  578. //
  579. MPR_INTERFACE_0 ri0;
  580. ZeroMemory (&ri0, sizeof(ri0));
  581. ri0.hInterface = INVALID_HANDLE_VALUE;
  582. ri0.fEnabled = TRUE; // thanks gibbs
  583. ri0.dwIfType = dwIfType;
  584. // Copy the interface name into the buffer.
  585. //
  586. AssertSz (lstrlenW (pszInterfaceName) < celems (ri0.wszInterfaceName),
  587. "Bindname too big for MPR_INTERFACE_0 buffer.");
  588. lstrcpyW (ri0.wszInterfaceName, pszInterfaceName);
  589. // Create the interface.
  590. //
  591. if (HRESULT_FROM_WIN32 (ERROR_NO_SUCH_INTERFACE) == hrConfig)
  592. {
  593. hrConfig = HrMprConfigInterfaceCreate (
  594. m_hMprConfig, 0, (LPBYTE)&ri0, phConfigInterface);
  595. TraceTag (ttidRasCfg, "MprConfigInterfaceCreate for %S",
  596. pszInterfaceName);
  597. }
  598. if (HRESULT_FROM_WIN32 (ERROR_NO_SUCH_INTERFACE) == hrAdmin)
  599. {
  600. hrAdmin = HrMprAdminInterfaceCreate (
  601. m_hMprAdmin, 0, (LPBYTE)&ri0, phAdminInterface);
  602. TraceTag (ttidRasCfg, "MprAdminInterfaceCreate for %S",
  603. pszInterfaceName);
  604. }
  605. }
  606. TraceError ("CSteelhead::HrEnsureRouterInterface", hrConfig);
  607. return hrConfig;
  608. }
  609. //+---------------------------------------------------------------------------
  610. //
  611. // Member: CSteelhead::HrEnsureRouterInterfaceTransport
  612. //
  613. // Purpose: Ensures the specified router manager is configured over
  614. // the specified interface.
  615. //
  616. // Arguments:
  617. // pszAdapterName [in] The adapter name
  618. // dwPacketType [in] The packet type (IPX only, ignored otherwise)
  619. // hInterface [in] Handle to the interface
  620. // rmi [in] The router manager
  621. //
  622. // Returns: S_OK or an error code.
  623. //
  624. // Author: shaunco 28 Jul 1997
  625. //
  626. // Notes:
  627. //
  628. HRESULT
  629. CSteelhead::HrEnsureRouterInterfaceTransport (
  630. PCWSTR pszAdapterName,
  631. DWORD dwPacketType,
  632. HANDLE hConfigInterface,
  633. HANDLE hAdminInterface,
  634. const ROUTER_MANAGER_INFO& rmi)
  635. {
  636. Assert (hConfigInterface);
  637. // hAdminInterface may be NULL if the router is not running.
  638. HRESULT hrConfig;
  639. // See if the router manager is present on the interface.
  640. //
  641. HANDLE hIfTransport;
  642. hrConfig = HrMprConfigInterfaceTransportGetHandle (
  643. m_hMprConfig, hConfigInterface,
  644. rmi.dwTransportId, &hIfTransport);
  645. if (FAILED(hrConfig))
  646. {
  647. // Ensure the router manager is present.
  648. //
  649. hrConfig = HrEnsureRouterManager (rmi);
  650. if (SUCCEEDED(hrConfig))
  651. {
  652. // Create the interface info and add the router manager to
  653. // the interface.
  654. //
  655. PRTR_INFO_BLOCK_HEADER pibh;
  656. Assert (rmi.pfnMakeInterfaceInfo);
  657. rmi.pfnMakeInterfaceInfo (pszAdapterName,
  658. dwPacketType,
  659. (LPBYTE*)&pibh);
  660. hrConfig = HrMprConfigInterfaceTransportAdd (
  661. m_hMprConfig,
  662. hConfigInterface,
  663. rmi.dwTransportId,
  664. const_cast<PWSTR>(rmi.pszwTransportName),
  665. (LPBYTE)pibh,
  666. pibh->Size,
  667. &hIfTransport);
  668. TraceTag (ttidRasCfg, "MprConfigInterfaceTransportAdd for "
  669. "%S on %S",
  670. rmi.pszwTransportName,
  671. pszAdapterName);
  672. if (SUCCEEDED(hrConfig) && hAdminInterface)
  673. {
  674. Assert (m_hMprAdmin);
  675. (VOID) HrMprAdminInterfaceTransportAdd (
  676. m_hMprAdmin,
  677. hAdminInterface,
  678. rmi.dwTransportId,
  679. (LPBYTE)pibh,
  680. pibh->Size);
  681. TraceTag (ttidRasCfg, "MprAdminInterfaceTransportAdd for "
  682. "%S on %S",
  683. rmi.pszwTransportName,
  684. pszAdapterName);
  685. }
  686. MemFree (pibh);
  687. }
  688. }
  689. TraceError ("CSteelhead::HrEnsureRouterInterfaceTransport", hrConfig);
  690. return hrConfig;
  691. }
  692. //+---------------------------------------------------------------------------
  693. //
  694. // Member: CSteelhead::HrEnsureRouterManager
  695. //
  696. // Purpose: Ensures that the specified router manager is installed.
  697. //
  698. // Arguments:
  699. // rmi [in] The router manager.
  700. //
  701. // Returns: S_OK or an error code.
  702. //
  703. // Author: shaunco 28 Jul 1997
  704. //
  705. // Notes:
  706. //
  707. HRESULT
  708. CSteelhead::HrEnsureRouterManager (
  709. const ROUTER_MANAGER_INFO& rmi)
  710. {
  711. PRTR_INFO_BLOCK_HEADER pibhGlobal;
  712. BOOL fCreate = FALSE;
  713. // See if the router manager is installed.
  714. //
  715. HANDLE hTransport;
  716. HRESULT hr = HrMprConfigTransportGetHandle (m_hMprConfig,
  717. rmi.dwTransportId,
  718. &hTransport);
  719. if (HRESULT_FROM_WIN32 (ERROR_UNKNOWN_PROTOCOL_ID) == hr)
  720. {
  721. // It's not installed, we'll create it.
  722. //
  723. fCreate = TRUE;
  724. }
  725. else if (SUCCEEDED(hr))
  726. {
  727. // Its installed, see if its transport info is available.
  728. //
  729. DWORD dwSize;
  730. hr = HrMprConfigTransportGetInfo (m_hMprConfig, hTransport,
  731. (LPBYTE*)&pibhGlobal, &dwSize,
  732. NULL, NULL, NULL);
  733. if (SUCCEEDED(hr))
  734. {
  735. if (!pibhGlobal)
  736. {
  737. // Global info is missing, we'll create it.
  738. //
  739. fCreate = TRUE;
  740. }
  741. else
  742. {
  743. MprConfigBufferFree (pibhGlobal);
  744. }
  745. }
  746. }
  747. if (fCreate)
  748. {
  749. // Install the router manager.
  750. //
  751. Assert (rmi.pfnMakeTransportInfo);
  752. PRTR_INFO_BLOCK_HEADER pibhClient;
  753. rmi.pfnMakeTransportInfo ((LPBYTE*)&pibhGlobal,
  754. (LPBYTE*)&pibhClient);
  755. hr = HrMprConfigTransportCreate (
  756. m_hMprConfig,
  757. rmi.dwTransportId,
  758. const_cast<PWSTR>(rmi.pszwTransportName),
  759. (LPBYTE)pibhGlobal, (pibhGlobal) ? pibhGlobal->Size : 0,
  760. (LPBYTE)pibhClient, (pibhClient) ? pibhClient->Size : 0,
  761. const_cast<PWSTR>(rmi.pszwDllPath),
  762. &hTransport);
  763. (VOID) HrMprAdminTransportCreate (
  764. m_hMprAdmin,
  765. rmi.dwTransportId,
  766. const_cast<PWSTR>(rmi.pszwTransportName),
  767. (LPBYTE)pibhGlobal, (pibhGlobal) ? pibhGlobal->Size : 0,
  768. (LPBYTE)pibhClient, (pibhClient) ? pibhClient->Size : 0,
  769. const_cast<PWSTR>(rmi.pszwDllPath));
  770. MemFree (pibhGlobal);
  771. MemFree (pibhClient);
  772. }
  773. TraceError ("CSteelhead::HrEnsureRouterManager", hr);
  774. return hr;
  775. }
  776. //+---------------------------------------------------------------------------
  777. //
  778. // Member: CSteelhead::HrEnsureRouterManagerDeleted
  779. //
  780. // Purpose: Ensures that the specified router manager is not installed.
  781. //
  782. // Arguments:
  783. // rmi [in] The router manager.
  784. //
  785. // Returns: S_OK or an error code.
  786. //
  787. // Author: shaunco 6 Sep 1997
  788. //
  789. // Notes:
  790. //
  791. HRESULT CSteelhead::HrEnsureRouterManagerDeleted (
  792. const ROUTER_MANAGER_INFO& rmi)
  793. {
  794. // See if the router manager is installed.
  795. //
  796. HANDLE hTransport;
  797. HRESULT hr = HrMprConfigTransportGetHandle (m_hMprConfig,
  798. rmi.dwTransportId,
  799. &hTransport);
  800. if (SUCCEEDED(hr))
  801. {
  802. // It is installed, so we need to delete it.
  803. //
  804. (VOID) HrMprConfigTransportDelete (m_hMprConfig, hTransport);
  805. }
  806. TraceError ("CSteelhead::HrEnsureRouterManagerDeleted",
  807. (HRESULT_FROM_WIN32 (ERROR_UNKNOWN_PROTOCOL_ID) == hr)
  808. ? S_OK : hr);
  809. return hr;
  810. }
  811. //+---------------------------------------------------------------------------
  812. //
  813. // Member: CSteelhead::HrPassToAddInterfaces
  814. //
  815. // Purpose:
  816. //
  817. // Arguments:
  818. // (none)
  819. //
  820. // Returns:
  821. //
  822. // Author: shaunco 27 Aug 1997
  823. //
  824. // Notes:
  825. //
  826. HRESULT
  827. CSteelhead::HrPassToAddInterfaces ()
  828. {
  829. HRESULT hr = S_OK;
  830. // Enumerate physical adapters in the system.
  831. //
  832. CIterNetCfgComponent nccIter(m_pnc, &GUID_DEVCLASS_NET);
  833. INetCfgComponent* pnccAdapter;
  834. while (S_OK == (hr = nccIter.HrNext(&pnccAdapter)))
  835. {
  836. // Only consider this adapter if we should router over it.
  837. //
  838. PWSTR pszBindName;
  839. hr = HrShouldRouteOverAdapter (pnccAdapter, &pszBindName);
  840. if (S_OK == hr)
  841. {
  842. INetCfgComponentBindings* pnccBindingsIp = NULL;
  843. INetCfgComponentBindings* pnccBindingsIpx = NULL;
  844. // If Ip is bound to the adapter, create and interface
  845. // for it.
  846. //
  847. if (PnccIp())
  848. {
  849. hr = PnccIp()->QueryInterface (IID_INetCfgComponentBindings,
  850. reinterpret_cast<VOID**>(&pnccBindingsIp) );
  851. }
  852. if (PnccIp() && SUCCEEDED(hr) &&
  853. (S_OK == (hr = pnccBindingsIp->IsBoundTo (pnccAdapter))))
  854. {
  855. // Interface name is the same as the adapter name
  856. // is the same as the bind name.
  857. //
  858. hr = HrEnsureRouterInterfaceForAdapter (
  859. ROUTER_IF_TYPE_DEDICATED,
  860. 0,
  861. pszBindName,
  862. pszBindName,
  863. c_rmiIp);
  864. }
  865. ReleaseObj (pnccBindingsIp);
  866. // If Ipx is bound to the adapter, create the interface(s)
  867. // for it.
  868. if (PnccIpx())
  869. {
  870. hr = PnccIpx()->QueryInterface (IID_INetCfgComponentBindings,
  871. reinterpret_cast<VOID**>(&pnccBindingsIpx));
  872. }
  873. if (PnccIpx() &&
  874. (S_OK == (hr = pnccBindingsIpx->IsBoundTo( pnccAdapter )) ))
  875. {
  876. hr = HrEnsureIpxRouterInterfacesForAdapter (pszBindName);
  877. }
  878. ReleaseObj (pnccBindingsIpx);
  879. CoTaskMemFree (pszBindName);
  880. }
  881. ReleaseObj (pnccAdapter);
  882. }
  883. // Normalize the HRESULT. (i.e. don't return S_FALSE)
  884. if (S_FALSE == hr)
  885. {
  886. hr = S_OK;
  887. }
  888. TraceError ("CSteelhead::HrPassToAddInterfaces", hr);
  889. return hr;
  890. }
  891. //+---------------------------------------------------------------------------
  892. //
  893. // Member: CSteelhead::HrPassToRemoveInterfaces
  894. //
  895. // Purpose:
  896. //
  897. // Arguments:
  898. // (none)
  899. //
  900. // Returns:
  901. //
  902. // Author: shaunco 27 Aug 1997
  903. //
  904. // Notes:
  905. //
  906. HRESULT
  907. CSteelhead::HrPassToRemoveInterfaces (
  908. BOOL fFromRunningRouter)
  909. {
  910. // Enumerate all of the installed router interfaces.
  911. //
  912. MPR_INTERFACE_0* ari0;
  913. DWORD dwEntriesRead;
  914. DWORD dwTotalEntries;
  915. HRESULT hr;
  916. if (fFromRunningRouter)
  917. {
  918. Assert (m_hMprAdmin);
  919. hr = HrMprAdminInterfaceEnum (m_hMprAdmin, 0,
  920. reinterpret_cast<LPBYTE*>(&ari0),
  921. -1, &dwEntriesRead, &dwTotalEntries, NULL);
  922. }
  923. else
  924. {
  925. hr = HrMprConfigInterfaceEnum (m_hMprConfig, 0,
  926. reinterpret_cast<LPBYTE*>(&ari0),
  927. -1, &dwEntriesRead, &dwTotalEntries, NULL);
  928. }
  929. if (SUCCEEDED(hr))
  930. {
  931. // By passing -1, we want everything, so we should get everything.
  932. Assert (dwEntriesRead == dwTotalEntries);
  933. // Iterate all of the interfaces.
  934. //
  935. for (MPR_INTERFACE_0* pri0 = ari0; dwEntriesRead--; pri0++)
  936. {
  937. BOOL fDeleteInterface = FALSE;
  938. PCWSTR pszInternalAdapter = SzLoadIds (IDS_RAS_INTERNAL_ADAPTER);
  939. // If its the internal interface and IP and IPX are no longer
  940. // installed delete the interface.
  941. //
  942. if ((ROUTER_IF_TYPE_INTERNAL == pri0->dwIfType) &&
  943. !PnccIpx() && !PnccIp() &&
  944. (0 == lstrcmpW (pri0->wszInterfaceName, pszInternalAdapter)))
  945. {
  946. fDeleteInterface = TRUE;
  947. }
  948. else if (ROUTER_IF_TYPE_DEDICATED != pri0->dwIfType)
  949. {
  950. // Skip non-dedicated interfaces.
  951. //
  952. continue;
  953. }
  954. BOOL fSpecialIpxInterface = FALSE;
  955. INetCfgComponent* pnccAdapter = NULL;
  956. // Get the name of the interface and look for a '/' separator.
  957. // If present, it means this is a special IPX interface where
  958. // the first substring is the adapter name, and the second
  959. // substring is the frame type.
  960. //
  961. WCHAR* pchwSep = wcschr (pri0->wszInterfaceName, L'/');
  962. if (!fDeleteInterface && pchwSep)
  963. {
  964. fSpecialIpxInterface = TRUE;
  965. // Point to the frame type string.
  966. //
  967. PCWSTR pszFrameType = pchwSep;
  968. // Copy the adapter name into its own buffer.
  969. //
  970. WCHAR szAdapterName [MAX_INTERFACE_NAME_LEN+1];
  971. lstrcpynW (szAdapterName, pri0->wszInterfaceName,
  972. pchwSep - pri0->wszInterfaceName + 1);
  973. // If the frame type is not in use for the adapter, we need
  974. // to delete this interface. This condition happens when
  975. // IPX configuration is changed and the frame type is removed
  976. // from the adapter.
  977. //
  978. if (!FIpxFrameTypeInUseOnAdapter (pszFrameType,
  979. szAdapterName))
  980. {
  981. fDeleteInterface = TRUE;
  982. TraceTag (ttidRasCfg, "%S no longer in use on %S. "
  983. "Deleting the router interface.",
  984. pszFrameType, szAdapterName);
  985. }
  986. }
  987. // It's not a special interface, so just make sure an adapter
  988. // exists with a matching bind name. If not, we will delete
  989. // the interface.
  990. //
  991. else if (!fDeleteInterface)
  992. {
  993. if (!FAdapterExistsWithMatchingBindName (
  994. pri0->wszInterfaceName,
  995. &pnccAdapter))
  996. {
  997. fDeleteInterface = TRUE;
  998. TraceTag (ttidRasCfg, "%S no longer present. "
  999. "Deleting the router interface.",
  1000. pri0->wszInterfaceName);
  1001. }
  1002. }
  1003. // Delete the interface if we need to.
  1004. //
  1005. if (fDeleteInterface)
  1006. {
  1007. if (fFromRunningRouter)
  1008. {
  1009. MprAdminInterfaceDelete (m_hMprAdmin, pri0->hInterface);
  1010. }
  1011. else
  1012. {
  1013. MprConfigInterfaceDelete (m_hMprConfig, pri0->hInterface);
  1014. }
  1015. }
  1016. // If we don't need to delete the entire interface, check
  1017. // for transports on the interface that we may need to delete.
  1018. // Don't do this for the running router because there is
  1019. // no MprAdminInterfaceTransportEnum API.
  1020. //
  1021. else if (!fFromRunningRouter)
  1022. {
  1023. // If its not an IPX special interface, the adapter
  1024. // is the interface name. If it is an IPX special
  1025. // interface, then we would have already remove the entire
  1026. // interface above if it were invalid.
  1027. //
  1028. (VOID) HrPassToRemoveInterfaceTransports (
  1029. pri0,
  1030. (!fSpecialIpxInterface) ? pri0->wszInterfaceName
  1031. : NULL,
  1032. pnccAdapter);
  1033. }
  1034. ReleaseObj (pnccAdapter);
  1035. }
  1036. MprConfigBufferFree (ari0);
  1037. }
  1038. else if ((HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr) ||
  1039. (HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE) == hr) ||
  1040. (HRESULT_FROM_WIN32(RPC_S_UNKNOWN_IF) == hr))
  1041. {
  1042. hr = S_OK;
  1043. }
  1044. TraceError ("CSteelhead::HrPassToRemoveInterfaces", hr);
  1045. return hr;
  1046. }
  1047. //+---------------------------------------------------------------------------
  1048. //
  1049. // Member: CSteelhead::HrPassToRemoveInterfaceTransports
  1050. //
  1051. // Purpose:
  1052. //
  1053. // Arguments:
  1054. // hInterface []
  1055. // pszAdapterName []
  1056. //
  1057. // Returns:
  1058. //
  1059. // Author: shaunco 27 Aug 1997
  1060. //
  1061. // Notes:
  1062. //
  1063. HRESULT
  1064. CSteelhead::HrPassToRemoveInterfaceTransports (
  1065. MPR_INTERFACE_0* pri0,
  1066. PCWSTR pszAdapterName,
  1067. INetCfgComponent* pnccAdapter)
  1068. {
  1069. Assert (FImplies(pnccAdapter, pszAdapterName));
  1070. // Enumerate all of the transports active on the router interface.
  1071. //
  1072. MPR_IFTRANSPORT_0* arit0;
  1073. DWORD dwEntriesRead;
  1074. DWORD dwTotalEntries;
  1075. HRESULT hr = HrMprConfigInterfaceTransportEnum (m_hMprConfig,
  1076. pri0->hInterface, 0,
  1077. reinterpret_cast<LPBYTE*>(&arit0),
  1078. -1, &dwEntriesRead, &dwTotalEntries, NULL);
  1079. if (SUCCEEDED(hr))
  1080. {
  1081. // By passing -1, we want everything, so we should get everything.
  1082. Assert (dwEntriesRead == dwTotalEntries);
  1083. INetCfgComponentBindings* pnccBindingsIpx = NULL;
  1084. INetCfgComponentBindings* pnccBindingsIp = NULL;
  1085. if (PnccIp())
  1086. {
  1087. hr = PnccIp()->QueryInterface (IID_INetCfgComponentBindings,
  1088. reinterpret_cast<VOID**>(&pnccBindingsIp));
  1089. }
  1090. if (SUCCEEDED(hr))
  1091. {
  1092. if (PnccIpx())
  1093. {
  1094. hr = PnccIpx()->QueryInterface (IID_INetCfgComponentBindings,
  1095. reinterpret_cast<VOID**>(&pnccBindingsIpx));
  1096. }
  1097. if (SUCCEEDED(hr))
  1098. {
  1099. // Iterate all of the transports.
  1100. //
  1101. for (MPR_IFTRANSPORT_0* prit0 = arit0; dwEntriesRead--; prit0++)
  1102. {
  1103. BOOL fDeleteInterfaceTransport = FALSE;
  1104. if (prit0->dwTransportId == c_rmiIp.dwTransportId)
  1105. {
  1106. if (!PnccIp())
  1107. {
  1108. fDeleteInterfaceTransport = TRUE;
  1109. TraceTag (ttidRasCfg, "TCP/IP no longer present. "
  1110. "Deleting this transport from interface %S.",
  1111. pri0->wszInterfaceName);
  1112. }
  1113. else if (pnccAdapter &&
  1114. (S_OK != (hr = pnccBindingsIp->IsBoundTo (pnccAdapter))))
  1115. {
  1116. fDeleteInterfaceTransport = TRUE;
  1117. TraceTag (ttidRasCfg, "TCP/IP no longer bound. "
  1118. "Deleting this transport from interface %S.",
  1119. pri0->wszInterfaceName);
  1120. }
  1121. }
  1122. else if (prit0->dwTransportId == c_rmiIpx.dwTransportId)
  1123. {
  1124. if (!PnccIpx())
  1125. {
  1126. fDeleteInterfaceTransport = TRUE;
  1127. TraceTag (ttidRasCfg, "IPX no longer present. "
  1128. "Deleting this transport from interface %S.",
  1129. pri0->wszInterfaceName);
  1130. }
  1131. else if (pnccAdapter &&
  1132. (S_OK != (hr = pnccBindingsIpx->IsBoundTo (pnccAdapter))))
  1133. {
  1134. fDeleteInterfaceTransport = TRUE;
  1135. TraceTag (ttidRasCfg, "IPX no longer bound. "
  1136. "Deleting this transport from interface %S.",
  1137. pri0->wszInterfaceName);
  1138. }
  1139. else if (pszAdapterName)
  1140. {
  1141. Assert (PnccIpx());
  1142. // if frame type is not auto on this adapter, delete
  1143. // the transport
  1144. if (!FIpxFrameTypeInUseOnAdapter (ISN_FRAME_TYPE_AUTO,
  1145. pszAdapterName))
  1146. {
  1147. fDeleteInterfaceTransport = TRUE;
  1148. TraceTag (ttidRasCfg, "IPX Auto frame type no longer "
  1149. "in use on %S. "
  1150. "Deleting this transport from interface %S.",
  1151. pszAdapterName, pri0->wszInterfaceName);
  1152. }
  1153. }
  1154. }
  1155. if (fDeleteInterfaceTransport)
  1156. {
  1157. MprConfigInterfaceTransportRemove (
  1158. m_hMprConfig,
  1159. pri0->hInterface,
  1160. prit0->hIfTransport);
  1161. }
  1162. }
  1163. MprConfigBufferFree (arit0);
  1164. ReleaseObj (pnccBindingsIpx);
  1165. }
  1166. ReleaseObj (pnccBindingsIp);
  1167. }
  1168. }
  1169. else if (HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr)
  1170. {
  1171. // If there are no transports for this interface, that's okay.
  1172. //
  1173. hr = S_OK;
  1174. }
  1175. TraceError ("CSteelhead::HrPassToRemoveInterfaceTransports", hr);
  1176. return hr;
  1177. }
  1178. //+---------------------------------------------------------------------------
  1179. //
  1180. // Member: CSteelhead::HrUpdateRouterConfiguration
  1181. //
  1182. // Purpose: Updates the router configuration by ensuring router managers
  1183. // are installed for the protocols present on the system (IP and
  1184. // IPX). Further, router interfaces are created for each
  1185. // physical netcard present on the system.
  1186. //
  1187. // Arguments:
  1188. // (none)
  1189. //
  1190. // Returns: S_OK or an error code.
  1191. //
  1192. // Author: shaunco 28 Jul 1997
  1193. //
  1194. // Notes:
  1195. //
  1196. HRESULT
  1197. CSteelhead::HrUpdateRouterConfiguration ()
  1198. {
  1199. Assert (!m_hMprConfig);
  1200. HRESULT hr = HrMprConfigServerConnect (NULL, &m_hMprConfig);
  1201. if (SUCCEEDED(hr))
  1202. {
  1203. PCWSTR pszInternalAdapter = SzLoadIds (IDS_RAS_INTERNAL_ADAPTER);
  1204. PCWSTR pszLoopbackAdapter = SzLoadIds (IDS_RAS_LOOPBACK_ADAPTER);
  1205. // Connect to the running router if able.
  1206. // (m_hMprAdmin will be non-NULL if we do.)
  1207. //
  1208. Assert (!m_hMprAdmin);
  1209. (VOID) HrMprAdminServerConnect (NULL, &m_hMprAdmin);
  1210. // Ensure router managers are installed for the protocols
  1211. // we know about. Good to do this in case no physical adapters.
  1212. // are found below. We actually do this by ensuring the internal
  1213. // interface exists. This will implicitly ensure the router
  1214. // manger is created.
  1215. //
  1216. if (PnccIp())
  1217. {
  1218. (VOID) HrEnsureRouterInterfaceForAdapter (
  1219. ROUTER_IF_TYPE_LOOPBACK,
  1220. c_rmiIp.dwPacketType,
  1221. pszLoopbackAdapter,
  1222. pszLoopbackAdapter,
  1223. c_rmiIp);
  1224. (VOID) HrEnsureRouterInterfaceForAdapter (
  1225. ROUTER_IF_TYPE_INTERNAL,
  1226. c_rmiIp.dwPacketType,
  1227. pszInternalAdapter,
  1228. pszInternalAdapter,
  1229. c_rmiIp);
  1230. }
  1231. else
  1232. {
  1233. (VOID) HrEnsureRouterManagerDeleted (c_rmiIp);
  1234. }
  1235. if (PnccIpx())
  1236. {
  1237. (VOID) HrEnsureRouterInterfaceForAdapter (
  1238. ROUTER_IF_TYPE_INTERNAL,
  1239. c_rmiIpx.dwPacketType,
  1240. pszInternalAdapter,
  1241. pszInternalAdapter,
  1242. c_rmiIpx);
  1243. }
  1244. else
  1245. {
  1246. (VOID) HrEnsureRouterManagerDeleted (c_rmiIpx);
  1247. }
  1248. (VOID) HrPassToAddInterfaces ();
  1249. (VOID) HrPassToRemoveInterfaces (FALSE);
  1250. // If we have a connection to the running router, make a pass
  1251. // to remove interfaces from it.
  1252. //
  1253. if (m_hMprAdmin)
  1254. {
  1255. (VOID) HrPassToRemoveInterfaces (TRUE);
  1256. MprAdminServerDisconnect (m_hMprAdmin);
  1257. m_hMprAdmin = NULL;
  1258. }
  1259. MprConfigServerDisconnect (m_hMprConfig);
  1260. m_hMprConfig = NULL;
  1261. }
  1262. TraceError ("CSteelhead::HrUpdateRouterConfiguration", hr);
  1263. return hr;
  1264. }
  1265. //+---------------------------------------------------------------------------
  1266. // INetCfgComponentControl
  1267. //
  1268. STDMETHODIMP
  1269. CSteelhead::Initialize (
  1270. INetCfgComponent* pncc,
  1271. INetCfg* pnc,
  1272. BOOL fInstalling)
  1273. {
  1274. Validate_INetCfgNotify_Initialize (pncc, pnc, fInstalling);
  1275. // Hold on to our the component representing us and our host
  1276. // INetCfg object.
  1277. AddRefObj (m_pnccMe = pncc);
  1278. AddRefObj (m_pnc = pnc);
  1279. m_fUpdateRouterConfiguration = fInstalling;
  1280. return S_OK;
  1281. }
  1282. STDMETHODIMP
  1283. CSteelhead::Validate ()
  1284. {
  1285. return S_OK;
  1286. }
  1287. STDMETHODIMP
  1288. CSteelhead::CancelChanges ()
  1289. {
  1290. return S_OK;
  1291. }
  1292. STDMETHODIMP
  1293. CSteelhead::ApplyRegistryChanges ()
  1294. {
  1295. HRESULT hr = S_OK;
  1296. if (!m_fRemoving && m_fUpdateRouterConfiguration)
  1297. {
  1298. m_fUpdateRouterConfiguration = FALSE;
  1299. TraceTag (ttidRasCfg, "Updating Steelhead configuration.");
  1300. hr = HrFindOtherComponents ();
  1301. if (SUCCEEDED(hr))
  1302. {
  1303. hr = HrUpdateRouterConfiguration ();
  1304. ReleaseOtherComponents ();
  1305. }
  1306. if (FAILED(hr))
  1307. {
  1308. hr = NETCFG_S_REBOOT;
  1309. }
  1310. }
  1311. Validate_INetCfgNotify_Apply_Return (hr);
  1312. TraceError ("CSteelhead::ApplyRegistryChanges",
  1313. (NETCFG_S_REBOOT == hr) ? S_OK : hr);
  1314. return hr;
  1315. }
  1316. //+---------------------------------------------------------------------------
  1317. // INetCfgComponentSetup
  1318. //
  1319. STDMETHODIMP
  1320. CSteelhead::ReadAnswerFile (
  1321. PCWSTR pszAnswerFile,
  1322. PCWSTR pszAnswerSection)
  1323. {
  1324. return S_OK;
  1325. }
  1326. STDMETHODIMP
  1327. CSteelhead::Install (DWORD dwSetupFlags)
  1328. {
  1329. HRESULT hr;
  1330. Validate_INetCfgNotify_Install (dwSetupFlags);
  1331. // Install NdisWan.
  1332. hr = HrInstallComponentOboComponent (m_pnc, NULL,
  1333. GUID_DEVCLASS_NETTRANS,
  1334. c_szInfId_MS_NdisWan,
  1335. m_pnccMe,
  1336. NULL);
  1337. TraceError ("CSteelhead::Install", hr);
  1338. return hr;
  1339. }
  1340. STDMETHODIMP
  1341. CSteelhead::Removing ()
  1342. {
  1343. HRESULT hr;
  1344. m_fRemoving = TRUE;
  1345. // Remove NdisWan.
  1346. hr = HrRemoveComponentOboComponent (m_pnc,
  1347. GUID_DEVCLASS_NETTRANS,
  1348. c_szInfId_MS_NdisWan,
  1349. m_pnccMe);
  1350. TraceError ("CSteelhead::Removing", hr);
  1351. return hr;
  1352. }
  1353. STDMETHODIMP
  1354. CSteelhead::Upgrade (
  1355. DWORD dwSetupFlags,
  1356. DWORD dwUpgradeFromBuildNo)
  1357. {
  1358. return S_FALSE;
  1359. }
  1360. //+---------------------------------------------------------------------------
  1361. // INetCfgSystemNotify
  1362. //
  1363. STDMETHODIMP
  1364. CSteelhead::GetSupportedNotifications (
  1365. DWORD* pdwNotificationFlag)
  1366. {
  1367. Validate_INetCfgSystemNotify_GetSupportedNotifications (pdwNotificationFlag);
  1368. *pdwNotificationFlag = NCN_NET | NCN_NETTRANS |
  1369. NCN_ADD | NCN_REMOVE |
  1370. NCN_PROPERTYCHANGE;
  1371. return S_OK;
  1372. }
  1373. STDMETHODIMP
  1374. CSteelhead::SysQueryBindingPath (
  1375. DWORD dwChangeFlag,
  1376. INetCfgBindingPath* pncbp)
  1377. {
  1378. return S_OK;
  1379. }
  1380. STDMETHODIMP
  1381. CSteelhead::SysQueryComponent (
  1382. DWORD dwChangeFlag,
  1383. INetCfgComponent* pncc)
  1384. {
  1385. return S_OK;
  1386. }
  1387. STDMETHODIMP
  1388. CSteelhead::SysNotifyBindingPath (
  1389. DWORD dwChangeFlag,
  1390. INetCfgBindingPath* pncbp)
  1391. {
  1392. return S_FALSE;
  1393. }
  1394. STDMETHODIMP
  1395. CSteelhead::SysNotifyComponent (
  1396. DWORD dwChangeFlag,
  1397. INetCfgComponent* pncc)
  1398. {
  1399. HRESULT hr;
  1400. Validate_INetCfgSystemNotify_SysNotifyComponent (dwChangeFlag, pncc);
  1401. // Assume we won't be dirty as a result of this notification.
  1402. //
  1403. hr = S_FALSE;
  1404. if (!m_fUpdateRouterConfiguration)
  1405. {
  1406. // If we're being called for a change to a net device, make sure
  1407. // its physical before deciding we need to update our configuration.
  1408. //
  1409. GUID guidClass;
  1410. hr = pncc->GetClassGuid (&guidClass);
  1411. if (S_OK == hr)
  1412. {
  1413. if (GUID_DEVCLASS_NET == guidClass)
  1414. {
  1415. hr = HrShouldRouteOverAdapter (pncc, NULL);
  1416. if (S_OK == hr)
  1417. {
  1418. TraceTag (ttidRasCfg, "CSteelhead::SysNotifyComponent: "
  1419. "called for adapter install/remove.");
  1420. m_fUpdateRouterConfiguration = TRUE;
  1421. Assert (S_OK == hr);
  1422. }
  1423. }
  1424. else
  1425. {
  1426. TraceTag (ttidRasCfg, "CSteelhead::SysNotifyComponent: "
  1427. "called for protocol add/remove/change.");
  1428. // If we're called for non-net devices, we want to
  1429. // update our configuration. (GetSupportedNotifications
  1430. // controls how often we fall into this.)
  1431. //
  1432. m_fUpdateRouterConfiguration = TRUE;
  1433. Assert (S_OK == hr);
  1434. }
  1435. }
  1436. }
  1437. TraceHr (ttidError, FAL, hr, (S_FALSE == hr),
  1438. "CSteelhead::SysNotifyComponent", hr);
  1439. return hr;
  1440. }