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.

8429 lines
220 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. info.cpp
  7. FILE HISTORY:
  8. Wei Jiang : 10/27/98 --- Add SetExternalRefreshObject to
  9. IRouterInfo and RouterInfo implementation
  10. to allow multiple router info the share
  11. the same AutoRefresh settings.
  12. */
  13. #include "stdafx.h"
  14. #include "lsa.h"
  15. #include "infoi.h"
  16. #include "rtrstr.h" // common router strings
  17. #include "refresh.h" // RouterRefreshObject
  18. #include "routprot.h"
  19. #include "rtrutilp.h"
  20. long s_cConnections = 1; // use for AdviseSink connection ids
  21. TFSCORE_API(HRESULT) CreateRouterInfo(IRouterInfo **ppRouterInfo, HWND hWndSync, LPCWSTR szMachine)
  22. {
  23. Assert(ppRouterInfo);
  24. HRESULT hr = hrOK;
  25. RouterInfo * pRouterInfo = NULL;
  26. COM_PROTECT_TRY
  27. {
  28. pRouterInfo = new RouterInfo(hWndSync, szMachine);
  29. *ppRouterInfo = pRouterInfo;
  30. }
  31. COM_PROTECT_CATCH;
  32. return hr;
  33. }
  34. IMPLEMENT_WEAKREF_ADDREF_RELEASE(RouterInfo);
  35. STDMETHODIMP RouterInfo::QueryInterface(REFIID iid,void **ppv)
  36. {
  37. *ppv = 0;
  38. if (iid == IID_IUnknown)
  39. *ppv = (IUnknown *) (IRouterInfo *) this;
  40. else if (iid == IID_IRouterInfo)
  41. *ppv = (IRouterInfo *) this;
  42. else if (iid == IID_IRouterRefreshAccess)
  43. *ppv = (IRouterRefreshAccess *) this;
  44. else if (iid == IID_IRouterAdminAccess)
  45. *ppv = (IRouterAdminAccess *) this;
  46. else
  47. return E_NOINTERFACE;
  48. ((IUnknown *) *ppv)->AddRef();
  49. return hrOK;
  50. }
  51. DEBUG_DECLARE_INSTANCE_COUNTER(RouterInfo)
  52. RouterInfo::RouterInfo(HWND hWndSync, LPCWSTR machineName)
  53. : m_bDisconnect(FALSE),
  54. m_hWndSync(hWndSync),
  55. m_dwRouterType(0),
  56. m_dwFlags(0),
  57. m_hMachineConfig(NULL),
  58. m_hMachineAdmin(NULL),
  59. m_fIsAdminInfoSet(FALSE),
  60. m_pbPassword(NULL),
  61. m_stMachine(machineName),
  62. m_cPassword(0)
  63. {
  64. DEBUG_INCREMENT_INSTANCE_COUNTER(RouterInfo);
  65. InitializeCriticalSection(&m_critsec);
  66. m_VersionInfo.dwRouterVersion = 0;
  67. m_VersionInfo.dwOsMajorVersion = 0;
  68. m_VersionInfo.dwOsMinorVersion = 0;
  69. m_VersionInfo.dwOsServicePack = 0;
  70. m_VersionInfo.dwOsBuildNo = 0;
  71. m_VersionInfo.dwOsFlags = 0;
  72. m_VersionInfo.dwRouterFlags = 0;
  73. }
  74. RouterInfo::~RouterInfo()
  75. {
  76. DEBUG_DECREMENT_INSTANCE_COUNTER(RouterInfo);
  77. Unload();
  78. DeleteCriticalSection(&m_critsec);
  79. ::ZeroMemory(m_pbPassword, m_cPassword);
  80. delete m_pbPassword;
  81. m_pbPassword = NULL;
  82. m_cPassword = 0;
  83. }
  84. STDMETHODIMP_(DWORD) RouterInfo::GetFlags()
  85. {
  86. RtrCriticalSection rtrCritSec(&m_critsec);
  87. return m_dwFlags;
  88. }
  89. STDMETHODIMP RouterInfo::SetFlags(DWORD dwFlags)
  90. {
  91. RtrCriticalSection rtrCritSec(&m_critsec);
  92. HRESULT hr = hrOK;
  93. COM_PROTECT_TRY
  94. {
  95. m_dwFlags = dwFlags;
  96. }
  97. COM_PROTECT_CATCH;
  98. return hr;
  99. }
  100. /*!--------------------------------------------------------------------------
  101. RouterInfo::Load
  102. Implementation of IRouterInfo::Load
  103. Author: KennT
  104. ---------------------------------------------------------------------------*/
  105. STDMETHODIMP RouterInfo::Load(LPCOLESTR pszMachine,
  106. HANDLE hMachine
  107. )
  108. {
  109. HRESULT hr = hrOK;
  110. RtrCriticalSection rtrCritSec(&m_critsec);
  111. TCHAR* psz;
  112. POSITION pos;
  113. DWORD dwErr, dwType, dwSize, dwRouterType;
  114. WCHAR* pwsz, wszMachine[MAX_PATH+3];
  115. HKEY hkMachine = NULL;
  116. USES_CONVERSION;
  117. COM_PROTECT_TRY
  118. {
  119. // Unload any existing information
  120. // ------------------------------------------------------------
  121. Unload();
  122. if (!pszMachine)
  123. {
  124. m_stMachine = TEXT("");
  125. pwsz = NULL;
  126. }
  127. else
  128. {
  129. m_stMachine = pszMachine;
  130. pwsz = StrnCpyWFromT(wszMachine, pszMachine, MAX_PATH);
  131. }
  132. // Get the version info
  133. // ------------------------------------------------------------
  134. CWRg( ConnectRegistry(GetMachineName(), &hkMachine) );
  135. CORg( QueryRouterVersionInfo(hkMachine, &m_VersionInfo) );
  136. // Get the router type
  137. // ------------------------------------------------------------
  138. CORg( QueryRouterType(hkMachine, &dwRouterType, &m_VersionInfo) );
  139. m_dwRouterType = dwRouterType;
  140. // If 'hmachine' was not specified, connect
  141. // ------------------------------------------------------------
  142. CORg( TryToConnect(pwsz, hMachine) );
  143. Assert(m_hMachineConfig);
  144. hMachine = m_hMachineConfig;
  145. MprConfigServerRefresh(m_hMachineConfig);
  146. // If the caller did not specify a list of LAN adapters,
  147. // load a list of the LAN adapters from HKLM\Soft\MS\NT\NetworkCards
  148. // ------------------------------------------------------------
  149. CORg( RouterInfo::LoadInstalledInterfaceList(OLE2CT(pszMachine),
  150. &m_IfCBList) );
  151. // This will fix a lot of weird bugs.
  152. // If the router has not been configured (if the configured flag
  153. // has not been set), then we can skip the rest of the
  154. // configuration section.
  155. // ------------------------------------------------------------
  156. // if (!(m_VersionInfo.dwRouterFlags & RouterSnapin_IsConfigured))
  157. // {
  158. // hr = hrOK;
  159. // goto Error;
  160. // }
  161. if (m_VersionInfo.dwRouterFlags & RouterSnapin_IsConfigured)
  162. {
  163. // If the caller did not specify a list of router-managers,
  164. // load a list of the router-managers from HKLM\Soft\MS\Router
  165. // ------------------------------------------------------------
  166. CORg( RouterInfo::LoadInstalledRtrMgrList(pszMachine,
  167. &m_RmCBList) );
  168. // Load a list with the routing-protocols for each router-manager
  169. // ------------------------------------------------------------
  170. pos = m_RmCBList.GetHeadPosition();
  171. while (pos)
  172. {
  173. SRtrMgrCB* pcb = m_RmCBList.GetNext(pos);
  174. CORg( RouterInfo::LoadInstalledRtrMgrProtocolList(
  175. pszMachine, pcb->dwTransportId,
  176. &m_RmProtCBList,
  177. this));
  178. }
  179. // Load router-level info
  180. // ------------------------------------------------------------
  181. MPR_SERVER_0* pInfo;
  182. dwErr = ::MprConfigServerGetInfo(m_hMachineConfig,
  183. 0,
  184. (LPBYTE *) &pInfo
  185. );
  186. if (dwErr == NO_ERROR)
  187. {
  188. m_SRouterCB.dwLANOnlyMode = pInfo->fLanOnlyMode;
  189. ::MprConfigBufferFree(pInfo);
  190. }
  191. // Load the router-managers
  192. // ------------------------------------------------------------
  193. CORg( LoadRtrMgrList() );
  194. }
  195. // Load the interfaces
  196. // ------------------------------------------------------------
  197. CORg( LoadInterfaceList() );
  198. hr = hrOK;
  199. COM_PROTECT_ERROR_LABEL;
  200. }
  201. COM_PROTECT_CATCH;
  202. if (hkMachine)
  203. DisconnectRegistry( hkMachine );
  204. if (!FHrSucceeded(hr))
  205. Unload();
  206. return hr;
  207. }
  208. /*!--------------------------------------------------------------------------
  209. RouterInfo::Save
  210. -
  211. Author: KennT
  212. ---------------------------------------------------------------------------*/
  213. STDMETHODIMP RouterInfo::Save(LPCOLESTR pszMachine,
  214. HANDLE hMachine )
  215. {
  216. RtrCriticalSection rtrCritSec(&m_critsec);
  217. return hrOK;
  218. }
  219. /*!--------------------------------------------------------------------------
  220. RouterInfo::Unload
  221. -
  222. Author: KennT
  223. ---------------------------------------------------------------------------*/
  224. STDMETHODIMP RouterInfo::Unload( )
  225. {
  226. HRESULT hr = hrOK;
  227. RtrCriticalSection rtrCritSec(&m_critsec);
  228. COM_PROTECT_TRY
  229. {
  230. // Destroy all COM objects, this includes interface and
  231. // router-manager objects
  232. // ------------------------------------------------------------
  233. Destruct();
  234. // Empty the list loaded using RouterInfo::LoadInstalledRtrMgrList
  235. // ------------------------------------------------------------
  236. while (!m_RmCBList.IsEmpty())
  237. delete m_RmCBList.RemoveHead();
  238. // Empty the list loaded using RouterInfo::LoadInstalledRmProtList
  239. // ------------------------------------------------------------
  240. while (!m_RmProtCBList.IsEmpty())
  241. delete m_RmProtCBList.RemoveHead();
  242. // Empty the list loaded using RouterInfo::LoadInstalledInterfaceList
  243. // ------------------------------------------------------------
  244. while (!m_IfCBList.IsEmpty())
  245. delete m_IfCBList.RemoveHead();
  246. DoDisconnect();
  247. m_dwRouterType = 0;
  248. }
  249. COM_PROTECT_CATCH;
  250. return hr;
  251. }
  252. /*!--------------------------------------------------------------------------
  253. RouterInfo::Merge
  254. -
  255. Author: KennT
  256. ---------------------------------------------------------------------------*/
  257. STDMETHODIMP RouterInfo::Merge(IRouterInfo *pNewRouter)
  258. {
  259. RtrCriticalSection rtrCritSec(&m_critsec);
  260. HRESULT hr = hrOK;
  261. RouterCB routerCB;
  262. COM_PROTECT_TRY
  263. {
  264. // There are several steps to this process, we need to sync
  265. // up the CBs and then the objects. However, we should also
  266. // do a sanity check to see that all of the objects have CBs
  267. // but not vice versa (there may be CBs that don't running
  268. // objects associated with them).
  269. // ------------------------------------------------------------
  270. // Merge the basic router dta
  271. // ------------------------------------------------------------
  272. pNewRouter->CopyCB(&routerCB);
  273. m_SRouterCB.LoadFrom(&routerCB);
  274. // Copy over the version information
  275. // ------------------------------------------------------------
  276. pNewRouter->GetRouterVersionInfo(&m_VersionInfo);
  277. // Sync up the RtrMgrCB
  278. // ------------------------------------------------------------
  279. CORg( MergeRtrMgrCB(pNewRouter) );
  280. // Sync up the InterfaceCB
  281. // ------------------------------------------------------------
  282. CORg( MergeInterfaceCB(pNewRouter) );
  283. // Sync up the RtrMgrProtocolCB
  284. // ------------------------------------------------------------
  285. CORg( MergeRtrMgrProtocolCB(pNewRouter) );
  286. // Sync up the RtrMgrs
  287. // ------------------------------------------------------------
  288. CORg( MergeRtrMgrs(pNewRouter) );
  289. // Sync up the Interfaces
  290. // ------------------------------------------------------------
  291. CORg( MergeInterfaces(pNewRouter) );
  292. m_dwRouterType = pNewRouter->GetRouterType();
  293. COM_PROTECT_ERROR_LABEL;
  294. }
  295. COM_PROTECT_CATCH;
  296. return hrOK;
  297. }
  298. /*!--------------------------------------------------------------------------
  299. RouterInfo::GetRefreshObject
  300. -
  301. Author: KennT
  302. ---------------------------------------------------------------------------*/
  303. STDMETHODIMP RouterInfo::GetRefreshObject(IRouterRefresh **ppRefresh)
  304. {
  305. HRESULT hr = hrOK;
  306. COM_PROTECT_TRY
  307. {
  308. // ------------------------------------------------------------
  309. if ((IRouterRefresh*)m_spRefreshObject && ppRefresh)
  310. {
  311. *ppRefresh = m_spRefreshObject;
  312. (*ppRefresh)->AddRef();
  313. }
  314. else
  315. {
  316. if (ppRefresh)
  317. *ppRefresh = NULL;
  318. hr = E_FAIL;
  319. }
  320. }
  321. COM_PROTECT_CATCH;
  322. return hr;
  323. }
  324. /*!--------------------------------------------------------------------------
  325. RouterInfo::SetExternalRefreshObject
  326. -
  327. To make multiple RouterInfo share the same AutoRefresh Object, use this
  328. function.
  329. Author: WeiJiang
  330. ---------------------------------------------------------------------------*/
  331. STDMETHODIMP RouterInfo::SetExternalRefreshObject(IRouterRefresh *pRefresh)
  332. {
  333. HRESULT hr = hrOK;
  334. m_spRefreshObject.Release();
  335. // set to nothing is also allowed
  336. m_spRefreshObject.Set(pRefresh);
  337. return hr;
  338. }
  339. /*!--------------------------------------------------------------------------
  340. RouterInfo::CopyCB
  341. -
  342. Author: KennT
  343. ---------------------------------------------------------------------------*/
  344. STDMETHODIMP RouterInfo::CopyCB(RouterCB *pRouterCB)
  345. {
  346. Assert(pRouterCB);
  347. RtrCriticalSection rtrCritSec(&m_critsec);
  348. HRESULT hr = hrOK;
  349. COM_PROTECT_TRY
  350. {
  351. pRouterCB->dwLANOnlyMode = m_SRouterCB.dwLANOnlyMode;
  352. }
  353. COM_PROTECT_CATCH;
  354. return hr;
  355. }
  356. /*!--------------------------------------------------------------------------
  357. RouterInfo::GetMachineName
  358. -
  359. Author: KennT
  360. ---------------------------------------------------------------------------*/
  361. STDMETHODIMP_(LPCOLESTR) RouterInfo::GetMachineName()
  362. {
  363. //$UNICODE : kennt, assumes that we are native UNICODE
  364. // Assumes OLE == W
  365. // ----------------------------------------------------------------
  366. RtrCriticalSection rtrCritSec(&m_critsec);
  367. return (LPCTSTR) m_stMachine;
  368. }
  369. /*!--------------------------------------------------------------------------
  370. RouterInfo::GetRouterType
  371. -
  372. Author: KennT
  373. ---------------------------------------------------------------------------*/
  374. STDMETHODIMP_(DWORD) RouterInfo::GetRouterType()
  375. {
  376. RtrCriticalSection rtrCritSec(&m_critsec);
  377. return m_dwRouterType;
  378. }
  379. STDMETHODIMP RouterInfo::GetRouterVersionInfo(RouterVersionInfo *pVerInfo)
  380. {
  381. RtrCriticalSection rtrCritSec(&m_critsec);
  382. HRESULT hr = hrOK;
  383. COM_PROTECT_TRY
  384. {
  385. *pVerInfo = m_VersionInfo;
  386. pVerInfo->dwSize = sizeof(RouterVersionInfo);
  387. }
  388. COM_PROTECT_CATCH;
  389. return hr;
  390. }
  391. /*!--------------------------------------------------------------------------
  392. RouterInfo::EnumRtrMgrCB
  393. -
  394. Author: KennT
  395. ---------------------------------------------------------------------------*/
  396. STDMETHODIMP RouterInfo::EnumRtrMgrCB( IEnumRtrMgrCB **ppEnumRtrMgrCB)
  397. {
  398. RtrCriticalSection rtrCritSec(&m_critsec);
  399. HRESULT hr = hrOK;
  400. COM_PROTECT_TRY
  401. {
  402. hr = CreateEnumFromSRmCBList(&m_RmCBList, ppEnumRtrMgrCB);
  403. }
  404. COM_PROTECT_CATCH;
  405. return hr;
  406. }
  407. /*!--------------------------------------------------------------------------
  408. RouterInfo::EnumInterfaceCB
  409. -
  410. Author: KennT
  411. ---------------------------------------------------------------------------*/
  412. STDMETHODIMP RouterInfo::EnumInterfaceCB( IEnumInterfaceCB **ppEnumInterfaceCB)
  413. {
  414. RtrCriticalSection rtrCritSec(&m_critsec);
  415. HRESULT hr = hrOK;
  416. COM_PROTECT_TRY
  417. {
  418. hr = CreateEnumFromSIfCBList(&m_IfCBList, ppEnumInterfaceCB);
  419. }
  420. COM_PROTECT_CATCH;
  421. return hr;
  422. }
  423. /*!--------------------------------------------------------------------------
  424. RouterInfo::EnumRtrMgrProtocolCB
  425. -
  426. Author: KennT
  427. ---------------------------------------------------------------------------*/
  428. HRESULT RouterInfo::EnumRtrMgrProtocolCB(IEnumRtrMgrProtocolCB **ppEnumRmProtCB)
  429. {
  430. RtrCriticalSection rtrCritSec(&m_critsec);
  431. HRESULT hr = hrOK;
  432. COM_PROTECT_TRY
  433. {
  434. hr = CreateEnumFromSRmProtCBList(&m_RmProtCBList, ppEnumRmProtCB);
  435. }
  436. COM_PROTECT_CATCH;
  437. return hr;
  438. }
  439. /*!--------------------------------------------------------------------------
  440. RouterInfo::EnumRtrMgrInterfaceCB
  441. -
  442. Author: KennT
  443. ---------------------------------------------------------------------------*/
  444. HRESULT RouterInfo::EnumRtrMgrInterfaceCB(IEnumRtrMgrInterfaceCB **ppEnumRmIfCB)
  445. {
  446. RtrCriticalSection rtrCritSec(&m_critsec);
  447. return E_NOTIMPL;
  448. }
  449. /*!--------------------------------------------------------------------------
  450. EnumRtrMgrProtocolInterfaceCB
  451. -
  452. Author: KennT
  453. ---------------------------------------------------------------------------*/
  454. HRESULT RouterInfo::EnumRtrMgrProtocolInterfaceCB(IEnumRtrMgrProtocolInterfaceCB **ppEnumRmProtIfCB)
  455. {
  456. RtrCriticalSection rtrCritSec(&m_critsec);
  457. return E_NOTIMPL;
  458. }
  459. /*!--------------------------------------------------------------------------
  460. RouterInfo::EnumRtrMgr
  461. -
  462. Author: KennT
  463. ---------------------------------------------------------------------------*/
  464. STDMETHODIMP RouterInfo::EnumRtrMgr( IEnumRtrMgrInfo **ppEnumRtrMgr)
  465. {
  466. RtrCriticalSection rtrCritSec(&m_critsec);
  467. HRESULT hr = hrOK;
  468. COM_PROTECT_TRY
  469. {
  470. hr = CreateEnumFromRmList(&m_RmList, ppEnumRtrMgr);
  471. }
  472. COM_PROTECT_CATCH;
  473. return hr;
  474. }
  475. /*!--------------------------------------------------------------------------
  476. RouterInfo::FindRtrMgr
  477. S_OK is returned if a RtrMgrInfo is found.
  478. S_FALSE is returned if a RtrMgrInfo was NOT found.
  479. error codes returned otherwise.
  480. Author: KennT
  481. ---------------------------------------------------------------------------*/
  482. STDMETHODIMP RouterInfo::FindRtrMgr( DWORD dwTransportId,
  483. IRtrMgrInfo **ppInfo)
  484. {
  485. RtrCriticalSection rtrCritSec(&m_critsec);
  486. HRESULT hr = hrFalse;
  487. POSITION pos;
  488. SPIRtrMgrInfo sprm;
  489. SRmData rmData;
  490. COM_PROTECT_TRY
  491. {
  492. if (ppInfo)
  493. *ppInfo = NULL;
  494. // Look through the list of rtr mgrs for the one that matches
  495. // ------------------------------------------------------------
  496. pos = m_RmList.GetHeadPosition();
  497. while (pos)
  498. {
  499. rmData = m_RmList.GetNext(pos);
  500. sprm.Set( rmData.m_pRmInfo );
  501. Assert(sprm);
  502. if (sprm->GetTransportId() == dwTransportId)
  503. {
  504. hr = hrOK;
  505. if (ppInfo)
  506. {
  507. *ppInfo = sprm.Transfer();
  508. }
  509. break;
  510. }
  511. }
  512. }
  513. COM_PROTECT_CATCH;
  514. return hr;
  515. }
  516. /*!--------------------------------------------------------------------------
  517. RouterInfo::AddRtrMgr
  518. -
  519. Author: KennT
  520. ---------------------------------------------------------------------------*/
  521. STDMETHODIMP RouterInfo::AddRtrMgr( IRtrMgrInfo *pInfo,
  522. IInfoBase *pGlobalInfo,
  523. IInfoBase *pClientInfo)
  524. {
  525. RtrCriticalSection rtrCritSec(&m_critsec);
  526. HRESULT hr = hrOK;
  527. DWORD dwConnection = 0;
  528. SRmData rmData;
  529. Assert(pInfo);
  530. COM_PROTECT_TRY
  531. {
  532. // Fail if there is a duplicate
  533. // ------------------------------------------------------------
  534. if (FHrOK(FindRtrMgr(pInfo->GetTransportId(), NULL)))
  535. CORg(E_INVALIDARG);
  536. //$ Review: kennt, if any of these calls fail, how do we
  537. // clean up correctly?
  538. // ------------------------------------------------------------
  539. // save the new structure
  540. // ------------------------------------------------------------
  541. CORg( pInfo->Save(GetMachineName(),
  542. m_hMachineConfig,
  543. NULL,
  544. pGlobalInfo,
  545. pClientInfo,
  546. 0) );
  547. // add the new structure to our list
  548. // ------------------------------------------------------------
  549. rmData.m_pRmInfo = pInfo;
  550. m_RmList.AddTail(rmData);
  551. pInfo->AddWeakRef();
  552. pInfo->SetParentRouterInfo(this);
  553. m_AdviseList.NotifyChange(ROUTER_CHILD_ADD, ROUTER_OBJ_Rm, 0);
  554. COM_PROTECT_ERROR_LABEL;
  555. }
  556. COM_PROTECT_CATCH;
  557. return hr;
  558. }
  559. /*!--------------------------------------------------------------------------
  560. RouterInfo::DeleteRtrMgr
  561. -
  562. This function deletes a router-manager from the router.
  563. A side-effect of this deletion is that all RtrMgrInterfaceInfo
  564. objects which refer to this router-manager are also deleted.
  565. Author: KennT
  566. ---------------------------------------------------------------------------*/
  567. STDMETHODIMP RouterInfo::DeleteRtrMgr( DWORD dwTransportId, BOOL fRemove )
  568. {
  569. RtrCriticalSection rtrCritSec(&m_critsec);
  570. HRESULT hr = hrOK;
  571. HRESULT hrIf;
  572. POSITION pos;
  573. POSITION posRM;
  574. POSITION posIf;
  575. SPIRtrMgrInfo sprm;
  576. SPIInterfaceInfo spIf;
  577. SRmData rmData;
  578. COM_PROTECT_TRY
  579. {
  580. pos = m_RmList.GetHeadPosition();
  581. while (pos)
  582. {
  583. posRM = pos;
  584. rmData = m_RmList.GetNext(pos);
  585. sprm.Set( rmData.m_pRmInfo );
  586. Assert(sprm);
  587. if (sprm->GetTransportId() == dwTransportId)
  588. break;
  589. sprm.Release();
  590. }
  591. // did we find a router-manager?
  592. // ------------------------------------------------------------
  593. if (sprm)
  594. {
  595. // get a list of the InterfaceInfo objects for
  596. // interfaces over which this router-manager is configured
  597. // --------------------------------------------------------
  598. posIf = m_IfList.GetHeadPosition();
  599. while (posIf)
  600. {
  601. spIf.Set( m_IfList.GetNext(posIf) );
  602. hrIf = spIf->FindRtrMgrInterface(dwTransportId, NULL);
  603. // go through the list and remove the router-manager from
  604. // each interface
  605. // ----------------------------------------------------
  606. if (hrIf == hrFalse)
  607. {
  608. spIf->DeleteRtrMgrInterface(dwTransportId, fRemove);
  609. }
  610. }
  611. // remove the router-manager from our list
  612. // --------------------------------------------------------
  613. Assert(rmData.m_pRmInfo == sprm);
  614. SRmData::Destroy( &rmData );
  615. m_RmList.RemoveAt(posRM);
  616. // finally, remove the router-manger itself
  617. // --------------------------------------------------------
  618. if (fRemove)
  619. sprm->Delete(GetMachineName(), NULL);
  620. m_AdviseList.NotifyChange(ROUTER_CHILD_DELETE, ROUTER_OBJ_Rm, 0);
  621. }
  622. else
  623. hr = E_INVALIDARG;
  624. }
  625. COM_PROTECT_CATCH;
  626. return hr;
  627. }
  628. /*!--------------------------------------------------------------------------
  629. RouterInfo::ReleaseRtrMgr
  630. This function will release the AddRef() that this object has
  631. on the child. This allows us to transfer child objects from
  632. one router to another.
  633. Author: KennT
  634. ---------------------------------------------------------------------------*/
  635. STDMETHODIMP RouterInfo::ReleaseRtrMgr( DWORD dwTransportId )
  636. {
  637. HRESULT hr = hrOK;
  638. POSITION pos, posRm;
  639. SRmData rmData;
  640. COM_PROTECT_TRY
  641. {
  642. pos = m_RmList.GetHeadPosition();
  643. while (pos)
  644. {
  645. // Save the position (so that we can delete it)
  646. posRm = pos;
  647. rmData = m_RmList.GetNext(pos);
  648. if (rmData.m_pRmInfo &&
  649. (rmData.m_pRmInfo->GetTransportId() == dwTransportId))
  650. {
  651. // When releasing, we need to disconnect (since the
  652. // main handle is controlled by the router info).
  653. rmData.m_pRmInfo->DoDisconnect();
  654. rmData.m_pRmInfo->ReleaseWeakRef();
  655. rmData.m_pRmInfo = NULL;
  656. // release this node from the list
  657. m_RmList.RemoveAt(posRm);
  658. break;
  659. }
  660. }
  661. }
  662. COM_PROTECT_CATCH;
  663. return hr;
  664. }
  665. /*!--------------------------------------------------------------------------
  666. RouterInfo::EnumInterface
  667. -
  668. Author: KennT
  669. ---------------------------------------------------------------------------*/
  670. STDMETHODIMP RouterInfo::EnumInterface(IEnumInterfaceInfo **ppEnumInterface)
  671. {
  672. RtrCriticalSection rtrCritSec(&m_critsec);
  673. HRESULT hr = hrOK;
  674. COM_PROTECT_TRY
  675. {
  676. hr = CreateEnumFromInterfaceList(&m_IfList, ppEnumInterface);
  677. }
  678. COM_PROTECT_CATCH;
  679. return hr;
  680. }
  681. /*!--------------------------------------------------------------------------
  682. RouterInfo::FindInterface
  683. S_OK is returned if an InterfaceInfo is found.
  684. S_FALSE is returned if an InterfaceInfo was NOT found.
  685. error codes returned otherwise.
  686. Author: KennT
  687. ---------------------------------------------------------------------------*/
  688. STDMETHODIMP RouterInfo::FindInterface(LPCOLESTR pszInterface,
  689. IInterfaceInfo **ppInfo)
  690. {
  691. RtrCriticalSection rtrCritSec(&m_critsec);
  692. HRESULT hr = hrFalse;
  693. POSITION pos;
  694. SPIInterfaceInfo spIf;
  695. COM_PROTECT_TRY
  696. {
  697. if (ppInfo)
  698. *ppInfo = NULL;
  699. // Look through the list of rtr mgrs for the one that matches
  700. // ------------------------------------------------------------
  701. pos = m_IfList.GetHeadPosition();
  702. while (pos)
  703. {
  704. spIf.Set(m_IfList.GetNext(pos));
  705. Assert(spIf);
  706. if (StriCmpW(spIf->GetId(), pszInterface) == 0)
  707. {
  708. hr = hrOK;
  709. if (ppInfo)
  710. {
  711. *ppInfo = spIf.Transfer();
  712. }
  713. break;
  714. }
  715. }
  716. }
  717. COM_PROTECT_CATCH;
  718. return hr;
  719. }
  720. /*!--------------------------------------------------------------------------
  721. RouterInfo::FindInterfaceByName
  722. -
  723. Author: KennT
  724. ---------------------------------------------------------------------------*/
  725. HRESULT RouterInfo::FindInterfaceByName(LPCOLESTR pszName,
  726. IInterfaceInfo **ppInfo)
  727. {
  728. RtrCriticalSection rtrCritSec(&m_critsec);
  729. HRESULT hr = hrFalse;
  730. POSITION pos;
  731. SPIInterfaceInfo spIf;
  732. COM_PROTECT_TRY
  733. {
  734. if (ppInfo)
  735. *ppInfo = NULL;
  736. // Look through the list of rtr mgrs for the one that matches
  737. // ------------------------------------------------------------
  738. pos = m_IfList.GetHeadPosition();
  739. while (pos)
  740. {
  741. spIf.Set(m_IfList.GetNext(pos));
  742. Assert(spIf);
  743. if (StriCmpW(spIf->GetTitle(), pszName) == 0)
  744. {
  745. hr = hrOK;
  746. if (ppInfo)
  747. {
  748. *ppInfo = spIf.Transfer();
  749. }
  750. break;
  751. }
  752. }
  753. }
  754. COM_PROTECT_CATCH;
  755. return hr;
  756. }
  757. /*!--------------------------------------------------------------------------
  758. RouterInfo::AddInterfaceInternal
  759. fForce - if this is TRUE, then we require that the Save succeeded.
  760. else, we ignore the error.
  761. fAddToRouter - if this is TRUE, we call the InterfaceInfo::Save,
  762. else, we do not call it (and do not change router state).
  763. fMoveRmIf - if this is TRUE, we have to convert the RtrMgrIf's to
  764. point to the one's in THIS router info.
  765. Author: KennT
  766. ---------------------------------------------------------------------------*/
  767. HRESULT RouterInfo::AddInterfaceInternal(IInterfaceInfo *pInfo,
  768. BOOL fForce,
  769. BOOL fAddToRouter)
  770. {
  771. RtrCriticalSection rtrCritSec(&m_critsec);
  772. HRESULT hr = hrOK;
  773. Assert(pInfo);
  774. COM_PROTECT_TRY
  775. {
  776. // Fail if there is a duplicate
  777. // ------------------------------------------------------------
  778. if (FHrOK(FindInterface(pInfo->GetId(), NULL)))
  779. CORg(E_INVALIDARG);
  780. // Also need to check that the friendly name is unique.
  781. // ------------------------------------------------------------
  782. if (FHrOK(FindInterfaceByName(pInfo->GetTitle(), NULL)))
  783. CORg(E_INVALIDARG);
  784. //$ Review: kennt, if any of these calls fail, how do we
  785. // clean up correctly?
  786. // ------------------------------------------------------------
  787. if (fAddToRouter)
  788. {
  789. // save the new structure
  790. // --------------------------------------------------------
  791. hr = pInfo->Save(GetMachineName(), m_hMachineConfig, NULL);
  792. if (fForce)
  793. CORg( hr );
  794. }
  795. // add the new structure to our list
  796. // ------------------------------------------------------------
  797. m_IfList.AddTail(pInfo);
  798. pInfo->AddWeakRef();
  799. pInfo->SetParentRouterInfo(this);
  800. m_AdviseList.NotifyChange(ROUTER_CHILD_ADD, ROUTER_OBJ_If, 0);
  801. COM_PROTECT_ERROR_LABEL;
  802. }
  803. COM_PROTECT_CATCH;
  804. return hr;
  805. }
  806. /*!--------------------------------------------------------------------------
  807. RouterInfo::NotifyRtrMgrInterfaceOfMove
  808. Notify the appropriate RouterManagers that a new interface
  809. has been added.
  810. Author: KennT
  811. ---------------------------------------------------------------------------*/
  812. HRESULT RouterInfo::NotifyRtrMgrInterfaceOfMove(IInterfaceInfo *pIf)
  813. {
  814. HRESULT hr = hrOK;
  815. SPIEnumRtrMgrInterfaceInfo spEnumRmIf;
  816. SPIRtrMgrInterfaceInfo spRmIf;
  817. SPIEnumRtrMgrProtocolInterfaceInfo spEnumRmProtIf;
  818. SPIRtrMgrInfo spRm;
  819. SPIRtrMgrProtocolInterfaceInfo spRmProtIf;
  820. SPIRtrMgrProtocolInfo spRmProt;
  821. pIf->EnumRtrMgrInterface(&spEnumRmIf);
  822. while (spEnumRmIf->Next(1, &spRmIf, NULL) == hrOK)
  823. {
  824. // Find the appropriate router manager and have them
  825. // send a notification.
  826. // ------------------------------------------------------------
  827. FindRtrMgr(spRmIf->GetTransportId(), &spRm);
  828. if (spRm)
  829. {
  830. spRm->RtrNotify(ROUTER_CHILD_ADD, ROUTER_OBJ_RmIf, 0);
  831. // Now for each router-manager, enumerate the protocols
  832. // --------------------------------------------------------
  833. spRmIf->EnumRtrMgrProtocolInterface(&spEnumRmProtIf);
  834. while (spEnumRmProtIf->Next(1, &spRmProtIf, NULL) == hrOK)
  835. {
  836. spRm->FindRtrMgrProtocol(spRmProtIf->GetProtocolId(),
  837. &spRmProt);
  838. if (spRmProt)
  839. {
  840. spRmProt->RtrNotify(ROUTER_CHILD_ADD, ROUTER_OBJ_RmProtIf,
  841. 0);
  842. }
  843. spRmProt.Release();
  844. spRmProtIf.Release();
  845. }
  846. }
  847. spEnumRmProtIf.Release();
  848. spRm.Release();
  849. spRmIf.Release();
  850. }
  851. return hr;
  852. }
  853. /*!--------------------------------------------------------------------------
  854. RouterInfo::AddInterface
  855. -
  856. Author: KennT
  857. ---------------------------------------------------------------------------*/
  858. STDMETHODIMP RouterInfo::AddInterface(IInterfaceInfo *pInfo)
  859. {
  860. return AddInterfaceInternal(pInfo,
  861. TRUE /* bForce */,
  862. TRUE /* fAddToRouter */);
  863. }
  864. /*!--------------------------------------------------------------------------
  865. RouterInfo::DeleteInterface
  866. -
  867. This function deletes the named CInterfaceInfo from the router.
  868. As a side-effect, all the contained CRmInterfaceInfo objects
  869. are also deleted.
  870. Author: KennT
  871. ---------------------------------------------------------------------------*/
  872. STDMETHODIMP RouterInfo::DeleteInterface(LPCOLESTR pszInterface, BOOL fRemove)
  873. {
  874. return RemoveInterfaceInternal(pszInterface, fRemove);
  875. }
  876. /*!--------------------------------------------------------------------------
  877. RouterInfo::ReleaseInterface
  878. This function will release the AddRef() that this object has
  879. on the child. This allows us to transfer child objects from
  880. one router to another.
  881. Author: KennT
  882. ---------------------------------------------------------------------------*/
  883. STDMETHODIMP RouterInfo::ReleaseInterface( LPCOLESTR pszInterface )
  884. {
  885. HRESULT hr = hrOK;
  886. POSITION pos, posIf;
  887. SPIInterfaceInfo spIf;
  888. COM_PROTECT_TRY
  889. {
  890. pos = m_IfList.GetHeadPosition();
  891. while (pos)
  892. {
  893. // Save the position (so that we can delete it)
  894. posIf = pos;
  895. spIf.Set( m_IfList.GetNext(pos) );
  896. if (spIf &&
  897. (StriCmpW(spIf->GetId(), pszInterface) == 0))
  898. {
  899. // When releasing, we need to disconnect (since the
  900. // main handle is controlled by the router info).
  901. spIf->DoDisconnect();
  902. spIf->ReleaseWeakRef();
  903. spIf.Release();
  904. // release this node from the list
  905. m_IfList.RemoveAt(posIf);
  906. break;
  907. }
  908. spIf.Release();
  909. }
  910. }
  911. COM_PROTECT_CATCH;
  912. return hr;
  913. }
  914. HRESULT RouterInfo::RemoveInterfaceInternal(LPCOLESTR pszIf, BOOL fRemoveFromRouter)
  915. {
  916. RtrCriticalSection rtrCritSec(&m_critsec);
  917. HRESULT hr = hrOK;
  918. POSITION pos, posIf;
  919. SPIInterfaceInfo spIf;
  920. COM_PROTECT_TRY
  921. {
  922. pos = m_IfList.GetHeadPosition();
  923. while (pos)
  924. {
  925. posIf = pos;
  926. spIf.Set( m_IfList.GetNext(pos) );
  927. if (StriCmpW(spIf->GetId(), pszIf) == 0)
  928. break;
  929. spIf.Release();
  930. }
  931. if (!spIf)
  932. hr = E_INVALIDARG;
  933. else
  934. {
  935. // Remove the interface from our list
  936. // --------------------------------------------------------
  937. spIf->Destruct();
  938. spIf->ReleaseWeakRef(); // remove list addref
  939. m_IfList.RemoveAt(posIf);
  940. // Need to remove the RtrMgrInterfaceInfos from the list.
  941. // --------------------------------------------------------
  942. SPIEnumRtrMgrInterfaceInfo spEnumRmIf;
  943. SPIRtrMgrInterfaceInfo spRmIf;
  944. spIf->EnumRtrMgrInterface(&spEnumRmIf);
  945. for (spEnumRmIf->Reset();
  946. hrOK == spEnumRmIf->Next(1, &spRmIf, NULL);
  947. spRmIf.Release())
  948. {
  949. DWORD dwTransportId = spRmIf->GetTransportId();
  950. spRmIf.Release();
  951. spIf->DeleteRtrMgrInterface(dwTransportId, fRemoveFromRouter);
  952. }
  953. if (fRemoveFromRouter)
  954. {
  955. // Delete the interface from the router
  956. // ----------------------------------------------------
  957. spIf->Delete(GetMachineName(), NULL);
  958. // If this is a WAN interface, delete it from the
  959. // phonebook-file
  960. // version # greater than Win2K, this will be done in MprAdminInterfaceDelete, which is called in Delete
  961. // fix 91331
  962. DWORD dwMajor = 0, dwMinor = 0, dwBuildNo = 0;
  963. HKEY hkeyMachine = NULL;
  964. // Ignore the failure code, what else can we do?
  965. // ------------------------------------------------------------
  966. DWORD dwErr = ConnectRegistry(GetMachineName(), &hkeyMachine);
  967. if (dwErr == ERROR_SUCCESS)
  968. {
  969. dwErr = GetNTVersion(hkeyMachine, &dwMajor, &dwMinor, &dwBuildNo)
  970. ;
  971. DisconnectRegistry(hkeyMachine);
  972. }
  973. DWORD dwVersionCombine = MAKELONG( dwBuildNo, MAKEWORD(dwMinor, dwMajor));
  974. DWORD dwVersionCombineNT50 = MAKELONG ( VER_BUILD_WIN2K, MAKEWORD(VER_MINOR_WIN2K, VER_MAJOR_WIN2K));
  975. // if the version is greater than Win2K release
  976. if(dwVersionCombine > dwVersionCombineNT50)
  977. ; // skip
  978. else
  979. // end if fix 91331
  980. {
  981. // ----------------------------------------------------
  982. if (spIf->GetInterfaceType() == ROUTER_IF_TYPE_FULL_ROUTER)
  983. hr = RasPhoneBookRemoveInterface(GetMachineName(),
  984. pszIf);
  985. }
  986. }
  987. m_AdviseList.NotifyChange(ROUTER_CHILD_DELETE, ROUTER_OBJ_If, 0);
  988. }
  989. }
  990. COM_PROTECT_CATCH;
  991. return hr;
  992. }
  993. STDMETHODIMP RouterInfo::RtrAdvise(IRtrAdviseSink *pRtrAdviseSink,
  994. LONG_PTR *pulConnection,
  995. LPARAM lUserParam)
  996. {
  997. Assert(pRtrAdviseSink);
  998. Assert(pulConnection);
  999. RtrCriticalSection rtrCritSec(&m_critsec);
  1000. LONG_PTR ulConnId;
  1001. HRESULT hr = hrOK;
  1002. COM_PROTECT_TRY
  1003. {
  1004. ulConnId = (LONG_PTR) InterlockedIncrement(&s_cConnections);
  1005. CORg( m_AdviseList.AddConnection(pRtrAdviseSink, ulConnId, lUserParam) );
  1006. *pulConnection = ulConnId;
  1007. COM_PROTECT_ERROR_LABEL;
  1008. }
  1009. COM_PROTECT_CATCH;
  1010. return hr;
  1011. }
  1012. STDMETHODIMP RouterInfo::RtrNotify(DWORD dwChangeType, DWORD dwObjectType,
  1013. LPARAM lParam)
  1014. {
  1015. RtrCriticalSection rtrCritSec(&m_critsec);
  1016. HRESULT hr = hrOK;
  1017. COM_PROTECT_TRY
  1018. {
  1019. m_AdviseList.NotifyChange(dwChangeType, dwObjectType, lParam);
  1020. }
  1021. COM_PROTECT_CATCH;
  1022. return hr;
  1023. }
  1024. STDMETHODIMP RouterInfo::RtrUnadvise(LONG_PTR dwConnection)
  1025. {
  1026. RtrCriticalSection rtrCritSec(&m_critsec);
  1027. return m_AdviseList.RemoveConnection(dwConnection);
  1028. }
  1029. //---------------------------------------------------------------------------
  1030. // Function: CRouterInfo::LoadInstalledRtrMgrList
  1031. //
  1032. // This function builds a list of the router manager's available
  1033. // for installation. The list contains RtrMgrCB structures.
  1034. //---------------------------------------------------------------------------
  1035. HRESULT RouterInfo::LoadInstalledRtrMgrList(LPCTSTR pszMachine,
  1036. SRtrMgrCBList *pRmCBList)
  1037. {
  1038. DWORD dwErr;
  1039. HKEY hkeyMachine = 0;
  1040. RegKey regkey;
  1041. RegKey regkeyRM;
  1042. RegKey::CREGKEY_KEY_INFO regKeyInfo;
  1043. RegKeyIterator regkeyIter;
  1044. HRESULT hr, hrIter;
  1045. CString stKey;
  1046. DWORD dwData;
  1047. DWORD cchValue;
  1048. SPSZ spszValue;
  1049. SPSRtrMgrCB spSRtrMgrCB;
  1050. // connect to the registry
  1051. // ----------------------------------------------------------------
  1052. CWRg( ConnectRegistry(pszMachine, &hkeyMachine) );
  1053. // open HKLM\Software\Microsoft\Router\CurrentVersion\RouterManagers
  1054. // ----------------------------------------------------------------
  1055. CWRg( regkey.Open(hkeyMachine, c_szRouterManagersKey, KEY_READ) );
  1056. // enumerate the keys
  1057. // ----------------------------------------------------------------
  1058. CORg( regkeyIter.Init(&regkey) );
  1059. for (hrIter = regkeyIter.Next(&stKey); hrIter == hrOK; hrIter = regkeyIter.Next(&stKey))
  1060. {
  1061. // cleanup from the previous loop
  1062. // ------------------------------------------------------------
  1063. regkeyRM.Close();
  1064. // open the key
  1065. // ------------------------------------------------------------
  1066. dwErr = regkeyRM.Open(regkey, stKey, KEY_READ);
  1067. if (dwErr == ERROR_SUCCESS)
  1068. {
  1069. // Get this information so that we can be more efficient
  1070. // at allocating space.
  1071. // --------------------------------------------------------
  1072. dwErr = regkeyRM.QueryKeyInfo(&regKeyInfo);
  1073. }
  1074. if (dwErr != ERROR_SUCCESS)
  1075. {
  1076. continue;
  1077. }
  1078. // Allocate a space for the largest value (we're reading
  1079. // in strings).
  1080. // ------------------------------------------------------------
  1081. spszValue.Free();
  1082. cchValue = MaxCchFromCb( regKeyInfo.dwMaxValueData );
  1083. spszValue = new TCHAR[ MinTCharNeededForCch(cchValue) ];
  1084. Assert(spszValue);
  1085. do {
  1086. // allocate a new structure for this router-manager
  1087. // --------------------------------------------------------
  1088. spSRtrMgrCB = new SRtrMgrCB;
  1089. Assert(spSRtrMgrCB);
  1090. spSRtrMgrCB->stId = stKey;
  1091. // read the ProtocolId value
  1092. // --------------------------------------------------------
  1093. dwErr = regkeyRM.QueryValue(c_szProtocolId, dwData);
  1094. if (dwErr != ERROR_SUCCESS) { break; }
  1095. spSRtrMgrCB->dwTransportId = dwData;
  1096. // read the DLLPath value
  1097. // --------------------------------------------------------
  1098. dwErr = regkeyRM.QueryValue(c_szDLLPath, spszValue, cchValue,TRUE);
  1099. if (dwErr != ERROR_SUCCESS) { break; }
  1100. spSRtrMgrCB->stDLLPath = spszValue;
  1101. //
  1102. // read the ConfigDLL value
  1103. //
  1104. //dwErr = regkeyRM.QueryValue(c_szConfigDLL,spszValue,cchValue,TRUE);
  1105. //if (dwErr != ERROR_SUCCESS) { break; }
  1106. //spSRtrMgrCB->stConfigDLL = spszValue;
  1107. // read the Title value
  1108. // --------------------------------------------------------
  1109. dwErr = regkeyRM.QueryValue(c_szTitle, spszValue, cchValue, FALSE);
  1110. if (dwErr != ERROR_SUCCESS)
  1111. spSRtrMgrCB->stTitle = spSRtrMgrCB->stId;
  1112. else
  1113. spSRtrMgrCB->stTitle = spszValue;
  1114. // add the object to our list
  1115. // --------------------------------------------------------
  1116. pRmCBList->AddTail(spSRtrMgrCB);
  1117. // Release the pointer, it belongs to pRmCBList now.
  1118. // --------------------------------------------------------
  1119. spSRtrMgrCB.Transfer();
  1120. } while(FALSE);
  1121. // If there was an error with the registry values, we
  1122. // ignore it and go onto the nextkey.
  1123. // ------------------------------------------------------------
  1124. regkeyRM.Close();
  1125. }
  1126. if (!FHrSucceeded(hrIter))
  1127. hr = hrIter;
  1128. Error:
  1129. if (hkeyMachine)
  1130. DisconnectRegistry(hkeyMachine);
  1131. return hr;
  1132. }
  1133. HRESULT RouterInfo::LoadInstalledRtrMgrProtocolList(LPCTSTR pszMachine,
  1134. DWORD dwTransportId, SRtrMgrProtocolCBList *pRmProtCBList, RouterInfo * pRouter)
  1135. {
  1136. WCHAR * pszPassword = NULL;
  1137. int nPasswordLen = 0;
  1138. UCHAR ucSeed = 0x83; //why?
  1139. HRESULT hr = hrOK;
  1140. if ( pRouter->IsAdminInfoSet() )
  1141. {
  1142. pRouter->GetUserPassword(NULL, &nPasswordLen );
  1143. pszPassword = (WCHAR *) new WCHAR [(nPasswordLen /sizeof(WCHAR)) + 1 ];
  1144. pRouter->GetUserPassword( (BYTE *)pszPassword, &nPasswordLen );
  1145. pszPassword[nPasswordLen/sizeof(WCHAR) ] = 0;
  1146. RtlDecodeW(ucSeed, pszPassword);
  1147. hr = RouterInfo::LoadInstalledRtrMgrProtocolList( pszMachine,
  1148. dwTransportId,
  1149. pRmProtCBList,
  1150. pRouter->GetUserName(),
  1151. pszPassword,
  1152. pRouter->GetDomainName() );
  1153. if ( pszPassword )
  1154. {
  1155. ZeroMemory ( pszPassword, nPasswordLen );
  1156. delete pszPassword;
  1157. }
  1158. }
  1159. else
  1160. {
  1161. hr = RouterInfo::LoadInstalledRtrMgrProtocolList( pszMachine,
  1162. dwTransportId,
  1163. pRmProtCBList,
  1164. NULL,
  1165. NULL,
  1166. NULL );
  1167. }
  1168. return hr;
  1169. }
  1170. HRESULT RouterInfo::LoadInstalledRtrMgrProtocolList(LPCTSTR pszMachine,
  1171. DWORD dwTransportId, SRtrMgrProtocolCBList *pRmProtCBList, IRouterInfo * pRouter)
  1172. {
  1173. WCHAR * pszPassword = NULL;
  1174. int nPasswordLen = 0;
  1175. UCHAR ucSeed = 0x83; //why?
  1176. HRESULT hr = hrOK;
  1177. SPIRouterAdminAccess spAdmin;
  1178. spAdmin.HrQuery(pRouter);
  1179. if (spAdmin && spAdmin->IsAdminInfoSet())
  1180. {
  1181. spAdmin->GetUserPassword(NULL, &nPasswordLen );
  1182. pszPassword = (WCHAR *) new WCHAR [(nPasswordLen /sizeof(WCHAR)) + 1 ];
  1183. spAdmin->GetUserPassword( (BYTE *)pszPassword, &nPasswordLen );
  1184. pszPassword[nPasswordLen/sizeof(WCHAR) ] = 0;
  1185. RtlDecodeW(ucSeed, pszPassword);
  1186. hr = RouterInfo::LoadInstalledRtrMgrProtocolList( pszMachine,
  1187. dwTransportId,
  1188. pRmProtCBList,
  1189. spAdmin->GetUserName(),
  1190. pszPassword,
  1191. spAdmin->GetDomainName() );
  1192. if ( pszPassword )
  1193. {
  1194. ZeroMemory ( pszPassword, nPasswordLen );
  1195. delete pszPassword;
  1196. }
  1197. }
  1198. else
  1199. {
  1200. hr = RouterInfo::LoadInstalledRtrMgrProtocolList( pszMachine,
  1201. dwTransportId,
  1202. pRmProtCBList,
  1203. NULL,
  1204. NULL,
  1205. NULL );
  1206. }
  1207. return hr;
  1208. }
  1209. //---------------------------------------------------------------------------
  1210. // Function: CRouterInfo::QueryInstalledRmProtList
  1211. //
  1212. // This function builds a list of the routing protocols which can be added
  1213. // to the specified router manager.
  1214. //---------------------------------------------------------------------------
  1215. HRESULT RouterInfo::LoadInstalledRtrMgrProtocolList(
  1216. LPCTSTR pszMachine,
  1217. DWORD dwTransportId,
  1218. SRtrMgrProtocolCBList * pSRmProtCBList,
  1219. LPCWSTR lpwszUserName,
  1220. LPCWSTR lpwszPassword ,
  1221. LPCWSTR lpwszDomain
  1222. )
  1223. {
  1224. Assert(pSRmProtCBList);
  1225. DWORD dwErr;
  1226. HKEY hkey, hkrm, hkeyMachine = 0;
  1227. HRESULT hr = hrOK;
  1228. RegKey regkeyRM;
  1229. RegKey regkeyProt;
  1230. RegKey::CREGKEY_KEY_INFO regKeyInfo;
  1231. RegKeyIterator regkeyIter;
  1232. HRESULT hrIter;
  1233. SPSZ spszValue;
  1234. SPSZ spszRm;
  1235. ULONG cchValue;
  1236. CString stKey;
  1237. SPSRtrMgrProtocolCB spSRmProtCB;
  1238. DWORD dwData;
  1239. BOOL f64BitAdmin = FALSE;
  1240. BOOL f64BitLocal = FALSE;
  1241. TCHAR szLocalMachineName[MAX_COMPUTERNAME_LENGTH + 1];
  1242. DWORD dwLocalMachineNameSize = MAX_COMPUTERNAME_LENGTH + 1;
  1243. if ( lpwszUserName )
  1244. CWRg( IsWindows64Bit(pszMachine, lpwszUserName, lpwszPassword, lpwszDomain, &f64BitAdmin) );
  1245. else
  1246. CWRg( IsWindows64Bit(pszMachine, NULL, NULL, NULL, &f64BitAdmin) );
  1247. GetComputerName ( szLocalMachineName, &dwLocalMachineNameSize );
  1248. if ( !lstrcmp ( szLocalMachineName, pszMachine ) )
  1249. {
  1250. f64BitLocal = f64BitAdmin;
  1251. }
  1252. else
  1253. {
  1254. CWRg( IsWindows64Bit(szLocalMachineName, NULL, NULL, NULL, &f64BitLocal) );
  1255. }
  1256. // connect to the registry
  1257. // ----------------------------------------------------------------
  1258. CWRg( ConnectRegistry(pszMachine, &hkeyMachine) );
  1259. // open the key for the specified router-manager
  1260. // under HKLM\Software\Microsoft\Router\RouterManagers
  1261. // ----------------------------------------------------------------
  1262. CWRg( FindRmSoftwareKey(hkeyMachine, dwTransportId, &hkrm, &spszRm) );
  1263. // The transport was found, so its registry key is in 'hkrm'
  1264. // ----------------------------------------------------------------
  1265. regkeyRM.Attach(hkrm);
  1266. // enumerate the keys
  1267. // ----------------------------------------------------------------
  1268. CORg( regkeyIter.Init(&regkeyRM) );
  1269. for (hrIter=regkeyIter.Next(&stKey); hrIter==hrOK; hrIter=regkeyIter.Next(&stKey))
  1270. {
  1271. // Cleanup from the previous loop
  1272. // ------------------------------------------------------------
  1273. regkeyProt.Close();
  1274. // open the key
  1275. // ------------------------------------------------------------
  1276. dwErr = regkeyProt.Open(regkeyRM, stKey, KEY_READ);
  1277. if (dwErr != ERROR_SUCCESS)
  1278. {
  1279. continue;
  1280. }
  1281. do {
  1282. // allocate a new structure for this protocol
  1283. // --------------------------------------------------------
  1284. spSRmProtCB.Free();
  1285. spSRmProtCB = new SRtrMgrProtocolCB;
  1286. Assert(spSRmProtCB);
  1287. spSRmProtCB->stId = stKey;
  1288. spSRmProtCB->dwTransportId = dwTransportId;
  1289. spSRmProtCB->stRtrMgrId = spszRm;
  1290. // get information about the key's values
  1291. // --------------------------------------------------------
  1292. dwErr = regkeyProt.QueryKeyInfo(&regKeyInfo);
  1293. if (dwErr != ERROR_SUCCESS) { break; }
  1294. // allocate space to hold the longest of the values
  1295. // --------------------------------------------------------
  1296. spszValue.Free();
  1297. cchValue = (regKeyInfo.dwMaxValueData)/sizeof(TCHAR);
  1298. spszValue = new TCHAR[cchValue * (2/sizeof(TCHAR))];
  1299. Assert(spszValue);
  1300. // read the ProtocolId value
  1301. // --------------------------------------------------------
  1302. dwErr = regkeyProt.QueryValue(c_szProtocolId, dwData);
  1303. if (dwErr != ERROR_SUCCESS) { break; }
  1304. //#if IA64
  1305. //OSPF node should be shown iff we are a 32 bit machine administering
  1306. //a 32 bit machine
  1307. if ( f64BitAdmin || f64BitLocal )
  1308. if( dwData == PROTO_IP_OSPF ) {break;}
  1309. //#endif
  1310. spSRmProtCB->dwProtocolId = dwData;
  1311. // read the Flags value
  1312. //
  1313. dwErr = regkeyProt.QueryValue(c_szFlags, dwData);
  1314. if (dwErr != ERROR_SUCCESS)
  1315. spSRmProtCB->dwFlags = 0;
  1316. else
  1317. spSRmProtCB->dwFlags = dwData;
  1318. //
  1319. // read the DLLName value
  1320. // --------------------------------------------------------
  1321. dwErr = regkeyProt.QueryValue(c_szDLLName, spszValue, cchValue,
  1322. TRUE);
  1323. if (dwErr != ERROR_SUCCESS)
  1324. spSRmProtCB->stDLLName.Empty();
  1325. else
  1326. spSRmProtCB->stDLLName = (LPCTSTR)spszValue;
  1327. //
  1328. // read the ConfigDLL value
  1329. //
  1330. //dwErr = regkeyProt.QueryValue(c_szConfigDLL, spszValue, cchValue,
  1331. // TRUE);
  1332. //if (dwErr != ERROR_SUCCESS) { break; }
  1333. //spSRmProtCB->stConfigDLL = (LPCTSTR)spszValue;
  1334. // read the ConfigCLSID value
  1335. // --------------------------------------------------------
  1336. dwErr = regkeyProt.QueryValue(c_szConfigCLSID, spszValue, cchValue, FALSE);
  1337. // Ignore the error code, if there is no CLSID, just NULL out
  1338. // the GUID, note that we can't depend on the key necessarily
  1339. // being there (for NT4 reasons).
  1340. // --------------------------------------------------------
  1341. ::ZeroMemory(&(spSRmProtCB->guidConfig), sizeof(GUID));
  1342. if ((dwErr != ERROR_SUCCESS) ||
  1343. !FHrSucceeded(CLSIDFromString(T2OLE((LPTSTR)(LPCTSTR) spszValue),
  1344. &(spSRmProtCB->guidConfig))))
  1345. memset(&(spSRmProtCB->guidConfig), 0xff, sizeof(GUID));
  1346. // read the AdminUICLSID value
  1347. // --------------------------------------------------------
  1348. dwErr = regkeyProt.QueryValue(c_szAdminUICLSID, spszValue, cchValue, FALSE);
  1349. // Ignore the error code, if there is no CLSID, just NULL out
  1350. // the GUID, note that we can't depend on the key necessarily
  1351. // being there (for NT4 reasons).
  1352. // --------------------------------------------------------
  1353. ::ZeroMemory(&(spSRmProtCB->guidAdminUI), sizeof(GUID));
  1354. if ((dwErr != ERROR_SUCCESS) ||
  1355. !FHrSucceeded(CLSIDFromString(T2OLE((LPTSTR)(LPCTSTR) spszValue),
  1356. &(spSRmProtCB->guidAdminUI))))
  1357. memset(&(spSRmProtCB->guidAdminUI), 0xff, sizeof(GUID));
  1358. // read the VendorName value
  1359. // --------------------------------------------------------
  1360. dwErr = regkeyProt.QueryValue(c_szVendorName, spszValue, cchValue, FALSE);
  1361. // Ignore the error code, if there is no value, just NULL out
  1362. // the value, note that we can't depend on the key necessarily
  1363. // being there (for NT4 reasons).
  1364. // --------------------------------------------------------
  1365. if (dwErr == ERROR_SUCCESS)
  1366. spSRmProtCB->stVendorName = spszValue;
  1367. // read the Title value
  1368. // --------------------------------------------------------
  1369. dwErr = regkeyProt.QueryValue(c_szTitle, spszValue, cchValue,
  1370. FALSE);
  1371. if (dwErr != ERROR_SUCCESS)
  1372. spSRmProtCB->stTitle = spSRmProtCB->stId;
  1373. else
  1374. spSRmProtCB->stTitle = (LPCTSTR)spszValue;
  1375. // add the object to our list
  1376. // --------------------------------------------------------
  1377. pSRmProtCBList->AddTail(spSRmProtCB);
  1378. // Let this go, it's under the control of the protList
  1379. // --------------------------------------------------------
  1380. spSRmProtCB.Transfer();
  1381. dwErr = ERROR_SUCCESS;
  1382. } while(FALSE);
  1383. }
  1384. Error:
  1385. if (hkeyMachine)
  1386. DisconnectRegistry(hkeyMachine);
  1387. return hr;
  1388. }
  1389. //---------------------------------------------------------------------------
  1390. // Function: CRouterInfo::LoadInstalledInterfaceList
  1391. //
  1392. // This function builds a list of network cards available for addition
  1393. // to the router manager.
  1394. //---------------------------------------------------------------------------
  1395. HRESULT RouterInfo::LoadInstalledInterfaceList(LPCTSTR pszMachine,
  1396. SInterfaceCBList *pSIfCBList)
  1397. {
  1398. DWORD dwErr;
  1399. HKEY hkeyMachine = 0;
  1400. RegKey regkeyNC;
  1401. RegKey regkeyCard;
  1402. CStringList ipCardList;
  1403. CStringList ipxCardList;
  1404. RegKeyIterator regkeyIter;
  1405. HRESULT hrIter;
  1406. CString stKey;
  1407. SPSInterfaceCB spSIfCB;
  1408. HRESULT hr = hrOK;
  1409. BOOL fNT4;
  1410. LPCTSTR pszKey;
  1411. CString stServiceName;
  1412. CNetcardRegistryHelper ncreghelp;
  1413. DWORD ifBindFlags = 0;
  1414. // connect to the registry
  1415. // ----------------------------------------------------------------
  1416. CWRg( ConnectRegistry(pszMachine, &hkeyMachine) );
  1417. //$NT5: kennt, changes made to read NT5 specific information
  1418. // ----------------------------------------------------------------
  1419. CWRg( IsNT4Machine(hkeyMachine, &fNT4) );
  1420. // open HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards
  1421. // ----------------------------------------------------------------
  1422. pszKey = fNT4 ? c_szNetworkCardsKey : c_szNetworkCardsNT5Key;
  1423. CWRg( regkeyNC.Open(hkeyMachine, pszKey, KEY_READ) );
  1424. // get the netcards that IP and IPX are bound to
  1425. // ----------------------------------------------------------------
  1426. CORg( ::LoadLinkageList(pszMachine, hkeyMachine, TEXT("tcpip"),
  1427. &ipCardList) );
  1428. CORg( ::LoadLinkageList(pszMachine, hkeyMachine, TEXT("nwlnkipx"),
  1429. &ipxCardList) );
  1430. // enumerate the subkeys, and for each key,
  1431. // make an addition to our list
  1432. // ----------------------------------------------------------------
  1433. CWRg( regkeyIter.Init(&regkeyNC) );
  1434. hrIter = regkeyIter.Next(&stKey);
  1435. for (; hrIter == hrOK; hrIter=regkeyIter.Next(&stKey))
  1436. {
  1437. ifBindFlags = 0;
  1438. regkeyCard.Close();
  1439. // now open the key
  1440. // ------------------------------------------------------------
  1441. dwErr = regkeyCard.Open(regkeyNC, stKey, KEY_READ);
  1442. if (dwErr != ERROR_SUCCESS)
  1443. continue;
  1444. // setup the helper class
  1445. // ------------------------------------------------------------
  1446. ncreghelp.Initialize(fNT4, regkeyCard, stKey,
  1447. pszMachine);
  1448. do {
  1449. // read the ServiceName
  1450. // --------------------------------------------------------
  1451. //$NT5: the service name is not in the same format as NT4
  1452. // this will need to be done differently.
  1453. // --------------------------------------------------------
  1454. if (fNT4)
  1455. {
  1456. dwErr = ncreghelp.ReadServiceName();
  1457. if (dwErr != ERROR_SUCCESS)
  1458. break;
  1459. stServiceName = ncreghelp.GetServiceName();
  1460. }
  1461. else
  1462. stServiceName = stKey;
  1463. // if the service name is not in the IP or IPX adapter list,
  1464. // then ignore this netcard because it is not a real netcard
  1465. // --------------------------------------------------------
  1466. if (ipCardList.Find((LPCTSTR) stServiceName))
  1467. {
  1468. ifBindFlags |= InterfaceCB_BindToIp;
  1469. }
  1470. // Now check IPX
  1471. // ------------------------------------------------
  1472. {
  1473. BOOL fFound = TRUE;
  1474. CString stNewServiceName;
  1475. do
  1476. {
  1477. if (ipxCardList.Find((LPCTSTR) stServiceName))
  1478. break;
  1479. stNewServiceName = stServiceName + c_szEthernetSNAP;
  1480. if (ipxCardList.Find((LPCTSTR) stNewServiceName))
  1481. break;
  1482. stNewServiceName = stServiceName + c_szEthernetII;
  1483. if (ipxCardList.Find((LPCTSTR) stNewServiceName))
  1484. break;
  1485. stNewServiceName = stServiceName + c_szEthernet8022;
  1486. if (ipxCardList.Find((LPCTSTR) stNewServiceName))
  1487. break;
  1488. stNewServiceName = stServiceName + c_szEthernet8023;
  1489. if (ipxCardList.Find((LPCTSTR) stNewServiceName))
  1490. break;
  1491. fFound = FALSE;
  1492. } while (FALSE);
  1493. if (fFound)
  1494. ifBindFlags |= InterfaceCB_BindToIpx;
  1495. }
  1496. // If we didn't find it in IP or IPX
  1497. // break out of the loop
  1498. // ----------------------------------------------------
  1499. if (ifBindFlags == 0)
  1500. break;
  1501. // ignore NdisWan adapters
  1502. // --------------------------------------------------------
  1503. if (_wcsnicmp( (const wchar_t *)stServiceName,
  1504. L"NdisWan",
  1505. (sizeof(L"NdisWan")-1)/sizeof (WCHAR)) == 0 ) {
  1506. break;
  1507. }
  1508. // allocate an SSInterfaceCB
  1509. // --------------------------------------------------------
  1510. spSIfCB = new SInterfaceCB;
  1511. Assert(spSIfCB);
  1512. spSIfCB->stId = (LPCTSTR) stServiceName;
  1513. spSIfCB->dwIfType = ROUTER_IF_TYPE_DEDICATED;
  1514. spSIfCB->dwBindFlags = ifBindFlags;
  1515. // read the title
  1516. // --------------------------------------------------------
  1517. dwErr = ncreghelp.ReadTitle();
  1518. if (dwErr != ERROR_SUCCESS)
  1519. spSIfCB->stTitle = spSIfCB->stId;
  1520. else
  1521. spSIfCB->stTitle = (LPCTSTR) ncreghelp.GetTitle();
  1522. // read the device
  1523. // --------------------------------------------------------
  1524. dwErr = ncreghelp.ReadDeviceName();
  1525. if (dwErr != ERROR_SUCCESS)
  1526. spSIfCB->stDeviceName = spSIfCB->stTitle;
  1527. else
  1528. spSIfCB->stDeviceName = (LPCTSTR) ncreghelp.GetDeviceName();
  1529. // add the SSInterfaceCB to the callers list
  1530. // --------------------------------------------------------
  1531. pSIfCBList->AddTail(spSIfCB);
  1532. spSIfCB.Transfer();
  1533. dwErr = NO_ERROR;
  1534. } while (FALSE);
  1535. if (dwErr != NO_ERROR)
  1536. {
  1537. hr = HRESULT_FROM_WIN32(dwErr);
  1538. break;
  1539. }
  1540. }
  1541. Error:
  1542. if (hkeyMachine)
  1543. DisconnectRegistry(hkeyMachine);
  1544. return dwErr;
  1545. }
  1546. //---------------------------------------------------------------------------
  1547. // Function: CRouterInfo::LoadRtrMgrList
  1548. //---------------------------------------------------------------------------
  1549. HRESULT RouterInfo::LoadRtrMgrList()
  1550. {
  1551. RtrCriticalSection rtrCritSec(&m_critsec);
  1552. BOOL bFound = TRUE;
  1553. SPIRtrMgrInfo spRmInfo;
  1554. BYTE* pItemTable = NULL;
  1555. MPR_TRANSPORT_0* ptransport;
  1556. DWORD dwErr, i, dwEntries, dwTotal;
  1557. HRESULT hr = hrOK;
  1558. USES_CONVERSION;
  1559. // Enumerate the transports configured
  1560. // ----------------------------------------------------------------
  1561. dwErr = ::MprConfigTransportEnum(
  1562. m_hMachineConfig,
  1563. 0,
  1564. &pItemTable,
  1565. (DWORD)-1,
  1566. &dwEntries,
  1567. &dwTotal,
  1568. NULL
  1569. );
  1570. if (dwErr != NO_ERROR && dwErr != ERROR_NO_MORE_ITEMS)
  1571. return HRESULT_FROM_WIN32(dwErr);
  1572. // Create router-manager objects for each transport
  1573. // ----------------------------------------------------------------
  1574. for (i = 0, ptransport = (MPR_TRANSPORT_0*)pItemTable;
  1575. i < dwEntries;
  1576. i++, ptransport++) {
  1577. // See if the transport is already in our list,
  1578. // and if not create an object for it.
  1579. // ------------------------------------------------------------
  1580. FindRtrMgr(ptransport->dwTransportId, &spRmInfo);
  1581. if (spRmInfo == NULL)
  1582. {
  1583. // Construct a CRmInfo object on this transport
  1584. // --------------------------------------------------------
  1585. spRmInfo = new RtrMgrInfo(ptransport->dwTransportId,
  1586. W2T(ptransport->wszTransportName), this);
  1587. spRmInfo->SetFlags( RouterSnapin_InSyncWithRouter );
  1588. Assert(spRmInfo);
  1589. bFound = FALSE;
  1590. }
  1591. else
  1592. bFound = TRUE;
  1593. // Load the information for the transport,
  1594. // including its list of protocols
  1595. // ------------------------------------------------------------
  1596. hr = spRmInfo->Load(GetMachineName(),
  1597. m_hMachineConfig,
  1598. ptransport->hTransport);
  1599. if (!FHrSucceeded(hr))
  1600. {
  1601. spRmInfo->Destruct();
  1602. spRmInfo.Release();
  1603. continue;
  1604. }
  1605. // Add the router manager object to our list
  1606. // ------------------------------------------------------------
  1607. if (bFound == FALSE)
  1608. {
  1609. SRmData rmData;
  1610. rmData.m_pRmInfo = spRmInfo;
  1611. m_RmList.AddTail(rmData);
  1612. CONVERT_TO_WEAKREF(spRmInfo);
  1613. spRmInfo.Transfer();
  1614. }
  1615. }
  1616. //Error:
  1617. if (pItemTable)
  1618. ::MprConfigBufferFree(pItemTable);
  1619. return hr;
  1620. }
  1621. //---------------------------------------------------------------------------
  1622. // Function: RouterInfo::LoadInterfaceList
  1623. //---------------------------------------------------------------------------
  1624. HRESULT RouterInfo::LoadInterfaceList()
  1625. {
  1626. RtrCriticalSection rtrCritSec(&m_critsec);
  1627. BOOL bAdd;
  1628. BYTE* pItemTable = NULL;
  1629. SPIInterfaceInfo spIfInfo;
  1630. MPR_INTERFACE_0* pinterface;
  1631. DWORD dwErr, i;
  1632. DWORD dwEntries = 0, dwTotal = 0;
  1633. HRESULT hr = hrOK;
  1634. HRESULT tmpHr = hrOK;
  1635. SPMprServerHandle sphMprServer;
  1636. BOOL fMprAdmin = TRUE; // was MprAdminInterfaceEnum used?
  1637. USES_CONVERSION;
  1638. // Windows NT Bug : 180752
  1639. // Should try to enumerate with MprAdminInterfaceEnum first.
  1640. dwErr = ConnectRouter(GetMachineName(), &sphMprServer);
  1641. if (dwErr == NO_ERROR)
  1642. {
  1643. dwErr = ::MprAdminInterfaceEnum(sphMprServer,
  1644. 0,
  1645. (BYTE **) &pItemTable,
  1646. (DWORD) -1,
  1647. &dwEntries,
  1648. &dwTotal,
  1649. NULL);
  1650. }
  1651. if (dwErr != NO_ERROR)
  1652. {
  1653. Assert(pItemTable == NULL);
  1654. // MprConfigInterfaceEnum is used, not MprAdminIntefaceEnum
  1655. // ------------------------------------------------------------
  1656. fMprAdmin = FALSE;
  1657. // Enumerate the interfaces configured
  1658. // ------------------------------------------------------------
  1659. dwErr = ::MprConfigInterfaceEnum(
  1660. m_hMachineConfig,
  1661. 0,
  1662. &pItemTable,
  1663. (DWORD)-1,
  1664. &dwEntries,
  1665. &dwTotal,
  1666. NULL
  1667. );
  1668. }
  1669. if (dwErr != NO_ERROR && dwErr != ERROR_NO_MORE_ITEMS)
  1670. return HRESULT_FROM_WIN32(dwErr);
  1671. // Delete interface-objects for interfaces which don't exist anymore
  1672. // ----------------------------------------------------------------
  1673. POSITION pos = m_IfList.GetHeadPosition();
  1674. while (pos) {
  1675. POSITION postemp = pos;
  1676. spIfInfo.Set( m_IfList.GetNext(pos) );
  1677. // See if the interface is in the new table
  1678. // ------------------------------------------------------------
  1679. for (i = 0, pinterface = (MPR_INTERFACE_0*)pItemTable;
  1680. i < dwEntries;
  1681. i++, pinterface++)
  1682. {
  1683. if (StriCmpW(OLE2CW(spIfInfo->GetId()), pinterface->wszInterfaceName) == 0)
  1684. break;
  1685. }
  1686. // Go on if the interface was found
  1687. // ------------------------------------------------------------
  1688. if (i < dwEntries)
  1689. {
  1690. // Update the interface's settings
  1691. // --------------------------------------------------------
  1692. spIfInfo->SetInterfaceEnabledState( pinterface->fEnabled );
  1693. continue;
  1694. }
  1695. // The interface-object was not found and is obsolete; delete it
  1696. // ------------------------------------------------------------
  1697. m_IfList.RemoveAt(postemp);
  1698. spIfInfo->Destruct();
  1699. spIfInfo->ReleaseWeakRef(); // remove list addref
  1700. spIfInfo.Release(); // this will release the sp addref
  1701. }
  1702. // Create interface objects for each new interface
  1703. // ----------------------------------------------------------------
  1704. for (i = 0, pinterface = (MPR_INTERFACE_0*)pItemTable;
  1705. i < dwEntries;
  1706. i++, pinterface++)
  1707. {
  1708. spIfInfo.Release();
  1709. // See if the interface exists,
  1710. // and if not create a new interface object
  1711. // ------------------------------------------------------------
  1712. FindInterface(W2OLE(pinterface->wszInterfaceName), &spIfInfo);
  1713. if (spIfInfo == NULL)
  1714. {
  1715. SInterfaceCB * pSIfCB = NULL;
  1716. bAdd = TRUE;
  1717. // Find the CB that corresponds to this interface
  1718. // --------------------------------------------------------
  1719. pSIfCB = FindInterfaceCB(pinterface->wszInterfaceName);
  1720. // Construct a CInterfaceInfo object on this interface
  1721. // --------------------------------------------------------
  1722. spIfInfo = new InterfaceInfo(W2T(pinterface->wszInterfaceName),
  1723. pinterface->dwIfType,
  1724. pinterface->fEnabled,
  1725. pSIfCB ? pSIfCB->dwBindFlags :
  1726. (InterfaceCB_BindToIp | InterfaceCB_BindToIpx),
  1727. this);
  1728. spIfInfo->SetFlags( RouterSnapin_InSyncWithRouter );
  1729. Assert(spIfInfo);
  1730. }
  1731. else
  1732. bAdd = FALSE;
  1733. // Load the information for the interface
  1734. // ------------------------------------------------------------
  1735. tmpHr = spIfInfo->Load(GetMachineName(),
  1736. m_hMachineConfig, NULL);
  1737. if (!FHrSucceeded(tmpHr))
  1738. {
  1739. spIfInfo->Destruct();
  1740. spIfInfo.Release();
  1741. continue;
  1742. }
  1743. // add the object to our interface list
  1744. // ------------------------------------------------------------
  1745. if (bAdd)
  1746. {
  1747. m_IfList.AddTail(spIfInfo);
  1748. CONVERT_TO_WEAKREF(spIfInfo);
  1749. spIfInfo.Transfer();
  1750. }
  1751. }
  1752. //Error:
  1753. if (pItemTable)
  1754. {
  1755. if (fMprAdmin)
  1756. ::MprAdminBufferFree(pItemTable);
  1757. else
  1758. ::MprConfigBufferFree(pItemTable);
  1759. }
  1760. return hr;
  1761. }
  1762. /*!--------------------------------------------------------------------------
  1763. RouterInfo::ReviveStrongRef
  1764. Override of CWeakRef::ReviveStrongRef
  1765. Author: KennT
  1766. ---------------------------------------------------------------------------*/
  1767. void RouterInfo::ReviveStrongRef()
  1768. {
  1769. // Don't need to do anything
  1770. }
  1771. /*!--------------------------------------------------------------------------
  1772. RouterInfo::OnLastStrongRef
  1773. Override of CWeakRef::OnLastStrongRef
  1774. On the last strong reference for the router info indicates that
  1775. there are no strong pointers to any object in the hierarchy. Thus
  1776. we are free to remove all of our internal pointers.
  1777. Author: KennT
  1778. ---------------------------------------------------------------------------*/
  1779. void RouterInfo::OnLastStrongRef()
  1780. {
  1781. RtrCriticalSection rtrCritSec(&m_critsec);
  1782. Destruct();
  1783. }
  1784. /*!--------------------------------------------------------------------------
  1785. RouterInfo::Destruct
  1786. Implementation of IRouterInfo::Destruct
  1787. Author: KennT
  1788. ---------------------------------------------------------------------------*/
  1789. STDMETHODIMP RouterInfo::Destruct()
  1790. {
  1791. RtrCriticalSection rtrCritSec(&m_critsec);
  1792. IInterfaceInfo * pIf;
  1793. SRmData rmData;
  1794. // Destroy the interface objects
  1795. // ----------------------------------------------------------------
  1796. while (!m_IfList.IsEmpty())
  1797. {
  1798. pIf = m_IfList.RemoveHead();
  1799. pIf->Destruct();
  1800. pIf->ReleaseWeakRef();
  1801. }
  1802. // Destroy the router-manager objects
  1803. // ----------------------------------------------------------------
  1804. while (!m_RmList.IsEmpty())
  1805. {
  1806. rmData = m_RmList.RemoveHead();
  1807. SRmData::Destroy( &rmData );
  1808. }
  1809. return hrOK;
  1810. }
  1811. /*!--------------------------------------------------------------------------
  1812. RouterInfo::TryToConnect
  1813. If we are already connected, then the handle passed in is
  1814. ignored.
  1815. Otherwise, if "hMachine" was not specified, connect to the
  1816. config on the specified machine.
  1817. Author: KennT
  1818. ---------------------------------------------------------------------------*/
  1819. HRESULT RouterInfo::TryToConnect(LPCWSTR pswzMachine, HANDLE hMachine)
  1820. {
  1821. RtrCriticalSection rtrCritSec(&m_critsec);
  1822. HRESULT hr = hrOK;
  1823. if (m_hMachineConfig == NULL)
  1824. {
  1825. if (hMachine)
  1826. {
  1827. m_hMachineConfig = hMachine;
  1828. m_bDisconnect = FALSE;
  1829. }
  1830. else
  1831. {
  1832. CWRg( ::MprConfigServerConnect((LPWSTR) pswzMachine,
  1833. &m_hMachineConfig) );
  1834. m_bDisconnect = TRUE;
  1835. }
  1836. }
  1837. Error:
  1838. return hr;
  1839. }
  1840. STDMETHODIMP RouterInfo::OnChange(LONG_PTR ulConnection,
  1841. DWORD dwChangeType,
  1842. DWORD dwObjectType,
  1843. LPARAM lUserParam,
  1844. LPARAM lParam)
  1845. {
  1846. RtrCriticalSection rtrCritSec(&m_critsec);
  1847. HRESULT hr = hrOK;
  1848. COM_PROTECT_TRY
  1849. {
  1850. }
  1851. COM_PROTECT_CATCH;
  1852. return hr;
  1853. }
  1854. /*!--------------------------------------------------------------------------
  1855. RouterInfo::MergeRtrMgrCB
  1856. -
  1857. Author: KennT
  1858. ---------------------------------------------------------------------------*/
  1859. HRESULT RouterInfo::MergeRtrMgrCB(IRouterInfo *pNewRouter)
  1860. {
  1861. HRESULT hr = hrOK;
  1862. SPIEnumRtrMgrCB spRmCB;
  1863. RtrMgrCB rmCB;
  1864. SRtrMgrCB * pSRmCB;
  1865. POSITION pos, posDelete;
  1866. // Set the internal data on the SRtrMgrCBs to 0
  1867. // ----------------------------------------------------------------
  1868. pos = m_RmCBList.GetHeadPosition();
  1869. while (pos)
  1870. {
  1871. pSRmCB = m_RmCBList.GetNext(pos);
  1872. Assert(pSRmCB);
  1873. pSRmCB->dwPrivate = 0;
  1874. }
  1875. CORg( pNewRouter->EnumRtrMgrCB(&spRmCB) );
  1876. while (spRmCB->Next(1, &rmCB, NULL) == hrOK)
  1877. {
  1878. // Now look for this rmCB in our current list
  1879. // If we find it, mark the CB
  1880. // If we do not find it, add this RmCB
  1881. // ------------------------------------------------------------
  1882. pSRmCB = FindRtrMgrCB(rmCB.dwTransportId);
  1883. if (pSRmCB)
  1884. {
  1885. pSRmCB->dwPrivate = 1;
  1886. }
  1887. else
  1888. {
  1889. // Add this CB to the internal list
  1890. // --------------------------------------------------------
  1891. SRtrMgrCB * pNewSRmCB = new SRtrMgrCB;
  1892. pNewSRmCB->LoadFrom(&rmCB);
  1893. pNewSRmCB->dwPrivate = 1;
  1894. m_RmCBList.AddTail(pNewSRmCB);
  1895. }
  1896. }
  1897. // Now go through the internal list and delete all items that we
  1898. // didn't find in the new list
  1899. // ----------------------------------------------------------------
  1900. pos = m_RmCBList.GetHeadPosition();
  1901. while (pos)
  1902. {
  1903. pSRmCB = m_RmCBList.GetNext(pos);
  1904. Assert(pSRmCB);
  1905. if (pSRmCB->dwPrivate == 0)
  1906. {
  1907. posDelete = m_RmCBList.Find(pSRmCB);
  1908. m_RmCBList.RemoveAt(posDelete);
  1909. delete pSRmCB;
  1910. }
  1911. }
  1912. Error:
  1913. return hr;
  1914. }
  1915. /*!--------------------------------------------------------------------------
  1916. RouterInfo::MergeInterfaceCB
  1917. -
  1918. Author: KennT
  1919. ---------------------------------------------------------------------------*/
  1920. HRESULT RouterInfo::MergeInterfaceCB(IRouterInfo *pNewRouter)
  1921. {
  1922. HRESULT hr = hrOK;
  1923. SPIEnumInterfaceCB spIfCB;
  1924. InterfaceCB IfCB;
  1925. SInterfaceCB * pSIfCB;
  1926. POSITION pos, posDelete;
  1927. // Set the internal data on the SInterfaceCBs to 0
  1928. // ----------------------------------------------------------------
  1929. pos = m_IfCBList.GetHeadPosition();
  1930. while (pos)
  1931. {
  1932. pSIfCB = m_IfCBList.GetNext(pos);
  1933. Assert(pSIfCB);
  1934. pSIfCB->dwPrivate = 0;
  1935. }
  1936. CORg( pNewRouter->EnumInterfaceCB(&spIfCB) );
  1937. while (spIfCB->Next(1, &IfCB, NULL) == hrOK)
  1938. {
  1939. // Now look for this IfCB in our current list
  1940. // If we find it, mark the CB
  1941. // If we do not find it, add this IfCB
  1942. // ------------------------------------------------------------
  1943. pSIfCB = FindInterfaceCB(IfCB.szId);
  1944. if (pSIfCB)
  1945. {
  1946. // We found it, update the internal data
  1947. // --------------------------------------------------------
  1948. pSIfCB->bEnable = IfCB.bEnable;
  1949. pSIfCB->dwPrivate = 1;
  1950. }
  1951. else
  1952. {
  1953. // Add this CB to the internal list
  1954. // --------------------------------------------------------
  1955. SInterfaceCB * pNewSIfCB = new SInterfaceCB;
  1956. pNewSIfCB->LoadFrom(&IfCB);
  1957. pNewSIfCB->dwPrivate = 1;
  1958. m_IfCBList.AddTail(pNewSIfCB);
  1959. }
  1960. }
  1961. // Now go through the internal list and delete all items that we
  1962. // didn't find in the new list
  1963. // ----------------------------------------------------------------
  1964. pos = m_IfCBList.GetHeadPosition();
  1965. while (pos)
  1966. {
  1967. pSIfCB = m_IfCBList.GetNext(pos);
  1968. Assert(pSIfCB);
  1969. if (pSIfCB->dwPrivate == 0)
  1970. {
  1971. posDelete = m_IfCBList.Find(pSIfCB);
  1972. m_IfCBList.RemoveAt(posDelete);
  1973. delete pSIfCB;
  1974. }
  1975. }
  1976. Error:
  1977. return hr;
  1978. }
  1979. /*!--------------------------------------------------------------------------
  1980. RouterInfo::MergeRtrMgrProtocolCB
  1981. -
  1982. Author: KennT
  1983. ---------------------------------------------------------------------------*/
  1984. HRESULT RouterInfo::MergeRtrMgrProtocolCB(IRouterInfo *pNewRouter)
  1985. {
  1986. HRESULT hr = hrOK;
  1987. SPIEnumRtrMgrProtocolCB spRmProtCB;
  1988. RtrMgrProtocolCB RmProtCB;
  1989. SRtrMgrProtocolCB * pSRmProtCB;
  1990. POSITION pos, posDelete;
  1991. // Set the internal data on the SRtrMgrProtocolCBs to 0
  1992. // ----------------------------------------------------------------
  1993. pos = m_RmProtCBList.GetHeadPosition();
  1994. while (pos)
  1995. {
  1996. pSRmProtCB = m_RmProtCBList.GetNext(pos);
  1997. Assert(pSRmProtCB);
  1998. pSRmProtCB->dwPrivate = 0;
  1999. }
  2000. CORg( pNewRouter->EnumRtrMgrProtocolCB(&spRmProtCB) );
  2001. while (spRmProtCB->Next(1, &RmProtCB, NULL) == hrOK)
  2002. {
  2003. // Now look for this RmProtCB in our current list
  2004. // If we find it, mark the CB
  2005. // If we do not find it, add this RmProtCB
  2006. // ------------------------------------------------------------
  2007. pSRmProtCB = FindRtrMgrProtocolCB(RmProtCB.dwTransportId,
  2008. RmProtCB.dwProtocolId);
  2009. if (pSRmProtCB)
  2010. {
  2011. pSRmProtCB->dwPrivate = 1;
  2012. }
  2013. else
  2014. {
  2015. // Add this CB to the internal list
  2016. // --------------------------------------------------------
  2017. SRtrMgrProtocolCB * pNewSRmProtCB = new SRtrMgrProtocolCB;
  2018. pNewSRmProtCB->LoadFrom(&RmProtCB);
  2019. pNewSRmProtCB->dwPrivate = 1;
  2020. m_RmProtCBList.AddTail(pNewSRmProtCB);
  2021. }
  2022. }
  2023. // Now go through the internal list and delete all items that we
  2024. // didn't find in the new list
  2025. // ----------------------------------------------------------------
  2026. pos = m_RmProtCBList.GetHeadPosition();
  2027. while (pos)
  2028. {
  2029. pSRmProtCB = m_RmProtCBList.GetNext(pos);
  2030. Assert(pSRmProtCB);
  2031. if (pSRmProtCB->dwPrivate == 0)
  2032. {
  2033. posDelete = m_RmProtCBList.Find(pSRmProtCB);
  2034. m_RmProtCBList.RemoveAt(posDelete);
  2035. delete pSRmProtCB;
  2036. }
  2037. }
  2038. Error:
  2039. return hr;
  2040. }
  2041. /*!--------------------------------------------------------------------------
  2042. RouterInfo::MergeRtrMgrs
  2043. -
  2044. Author: KennT
  2045. ---------------------------------------------------------------------------*/
  2046. HRESULT RouterInfo::MergeRtrMgrs(IRouterInfo *pNewRouter)
  2047. {
  2048. RtrCriticalSection rtrCritSec(&m_critsec);
  2049. SPIEnumRtrMgrInfo spEnumRm;
  2050. SPIRtrMgrInfo spRm;
  2051. HRESULT hr = hrOK;
  2052. CDWordArray oldDWArray;
  2053. CDWordArray newDWArray;
  2054. int cOld, cNew;
  2055. int i, j;
  2056. DWORD dwTemp;
  2057. Assert(pNewRouter);
  2058. COM_PROTECT_TRY
  2059. {
  2060. // Need to sync up RtrMgrInfo
  2061. //
  2062. // The general algorithm is to build up two arrays
  2063. // the first array contains the transport ids for this object
  2064. // the second array contains the ids for the new object
  2065. //
  2066. // We then go through and remove all transports that are in
  2067. // BOTH lists.
  2068. //
  2069. // This will leave us with the first array containing the
  2070. // ids of the transports that need to be deleted from this object.
  2071. //
  2072. // The second array will have the list of ids of transports that
  2073. // have to be added to this object from the second object.
  2074. // ------------------------------------------------------------
  2075. // Get the list of transports that are in the new object
  2076. // ------------------------------------------------------------
  2077. CORg( pNewRouter->EnumRtrMgr(&spEnumRm) );
  2078. spEnumRm->Reset();
  2079. while (spEnumRm->Next(1, &spRm, NULL) == hrOK)
  2080. {
  2081. newDWArray.Add(spRm->GetTransportId());
  2082. spRm.Release();
  2083. }
  2084. spEnumRm.Release();
  2085. spRm.Release();
  2086. // Get the list of transports that are in this object
  2087. // ------------------------------------------------------------
  2088. CORg( this->EnumRtrMgr(&spEnumRm) );
  2089. spEnumRm->Reset();
  2090. while (spEnumRm->Next(1, &spRm, NULL) == hrOK)
  2091. {
  2092. oldDWArray.Add(spRm->GetTransportId());
  2093. spRm.Release();
  2094. }
  2095. spEnumRm.Release();
  2096. spRm.Release();
  2097. // Ok now go through both lists, removing from the lists
  2098. // transports that are in both lists.
  2099. // ------------------------------------------------------------
  2100. cOld = oldDWArray.GetSize();
  2101. cNew = newDWArray.GetSize();
  2102. for (i=cOld; --i>=0; )
  2103. {
  2104. dwTemp = oldDWArray.GetAt(i);
  2105. for (j=cNew; --j>=0; )
  2106. {
  2107. if (dwTemp == newDWArray.GetAt(j))
  2108. {
  2109. SPIRtrMgrInfo spRm1;
  2110. SPIRtrMgrInfo spRm2;
  2111. this->FindRtrMgr(dwTemp, &spRm1);
  2112. pNewRouter->FindRtrMgr(dwTemp, &spRm2);
  2113. Assert(spRm1);
  2114. Assert(spRm2);
  2115. spRm1->Merge(spRm2);
  2116. // remove both instances
  2117. // ------------------------------------------------
  2118. newDWArray.RemoveAt(j);
  2119. oldDWArray.RemoveAt(i);
  2120. // Need to update the size of the new array
  2121. // ------------------------------------------------
  2122. cNew--;
  2123. break;
  2124. }
  2125. }
  2126. }
  2127. // oldDWArray now contains the transports that should be
  2128. // removed.
  2129. // ------------------------------------------------------------
  2130. if (oldDWArray.GetSize())
  2131. {
  2132. for (i=oldDWArray.GetSize(); --i>=0; )
  2133. {
  2134. DeleteRtrMgr(oldDWArray.GetAt(i), FALSE);
  2135. }
  2136. }
  2137. // newDWArray contains the transports that should be added
  2138. // ------------------------------------------------------------
  2139. if (newDWArray.GetSize())
  2140. {
  2141. for (i=newDWArray.GetSize(); --i>= 0; )
  2142. {
  2143. hr = pNewRouter->FindRtrMgr(newDWArray.GetAt(i), &spRm);
  2144. Assert(hr == hrOK);
  2145. Assert(spRm);
  2146. // Do a sanity check, make sure that this RtrMgr is
  2147. // in the RtrMgrCB list
  2148. // ----------------------------------------------------
  2149. Assert(FindRtrMgrCB(spRm->GetTransportId()));
  2150. // Add this router manager, to the router info.
  2151. // ----------------------------------------------------
  2152. if (spRm)
  2153. {
  2154. AddRtrMgr(spRm, NULL, NULL);
  2155. // Remove this router manager from its previous router
  2156. // ------------------------------------------------
  2157. pNewRouter->ReleaseRtrMgr(spRm->GetTransportId());
  2158. }
  2159. spRm.Release();
  2160. }
  2161. }
  2162. COM_PROTECT_ERROR_LABEL;
  2163. }
  2164. COM_PROTECT_CATCH;
  2165. return hr;
  2166. }
  2167. /*!--------------------------------------------------------------------------
  2168. RouterInfo::MergeInterfaces
  2169. -
  2170. Author: KennT
  2171. ---------------------------------------------------------------------------*/
  2172. HRESULT RouterInfo::MergeInterfaces(IRouterInfo *pNewRouter)
  2173. {
  2174. RtrCriticalSection rtrCritSec(&m_critsec);
  2175. SPIEnumInterfaceInfo spEnumIf;
  2176. SPIInterfaceInfo spIf;
  2177. HRESULT hr = hrOK;
  2178. CStringArray oldStArray;
  2179. CStringArray newStArray;
  2180. int cOld, cNew;
  2181. int i, j;
  2182. CString stTemp;
  2183. Assert(pNewRouter);
  2184. COM_PROTECT_TRY
  2185. {
  2186. // Need to sync up InterfaceInfo
  2187. // ------------------------------------------------------------
  2188. //
  2189. // The general algorithm is to build up two arrays
  2190. // the first array contains the protocol ids for this object
  2191. // the second array contains the ids for the new object
  2192. //
  2193. // We then go through and remove all protocols that are in
  2194. // BOTH lists.
  2195. //
  2196. // This will leave us with the first array containing the
  2197. // ids of the protocols that need to be deleted from this object.
  2198. //
  2199. // The second array will have the list of ids of protocols that
  2200. // have to be added to this object from the second object.
  2201. // ------------------------------------------------------------
  2202. // Get the list of protocols that are in the new object
  2203. // ------------------------------------------------------------
  2204. CORg( pNewRouter->EnumInterface(&spEnumIf) );
  2205. spEnumIf->Reset();
  2206. while (spEnumIf->Next(1, &spIf, NULL) == hrOK)
  2207. {
  2208. newStArray.Add(spIf->GetId());
  2209. spIf.Release();
  2210. }
  2211. spEnumIf.Release();
  2212. spIf.Release();
  2213. // Get the list of protocols that are in this object
  2214. // ------------------------------------------------------------
  2215. CORg( this->EnumInterface(&spEnumIf) );
  2216. spEnumIf->Reset();
  2217. while (spEnumIf->Next(1, &spIf, NULL) == hrOK)
  2218. {
  2219. oldStArray.Add(spIf->GetId());
  2220. spIf.Release();
  2221. }
  2222. spEnumIf.Release();
  2223. spIf.Release();
  2224. // Ok now go through both lists, removing from the lists
  2225. // protocols that are in both lists.
  2226. // ------------------------------------------------------------
  2227. cOld = oldStArray.GetSize();
  2228. cNew = newStArray.GetSize();
  2229. for (i=cOld; --i>=0; )
  2230. {
  2231. stTemp = oldStArray.GetAt(i);
  2232. for (j=cNew; --j>=0; )
  2233. {
  2234. if (stTemp == newStArray.GetAt(j))
  2235. {
  2236. SPIInterfaceInfo spIf1;
  2237. SPIInterfaceInfo spIf2;
  2238. this->FindInterface(stTemp, &spIf1);
  2239. pNewRouter->FindInterface(stTemp, &spIf2);
  2240. Assert(spIf1);
  2241. Assert(spIf2);
  2242. spIf1->Merge(spIf2);
  2243. // remove both instances
  2244. // ------------------------------------------------
  2245. newStArray.RemoveAt(j);
  2246. oldStArray.RemoveAt(i);
  2247. // Need to update the size of the new array
  2248. // ------------------------------------------------
  2249. cNew--;
  2250. break;
  2251. }
  2252. }
  2253. }
  2254. // oldStArray now contains the protocols that should be
  2255. // removed.
  2256. // ------------------------------------------------------------
  2257. if (oldStArray.GetSize())
  2258. {
  2259. for (i=oldStArray.GetSize(); --i>=0; )
  2260. {
  2261. RemoveInterfaceInternal(oldStArray.GetAt(i),
  2262. FALSE /* fRemoveFromRouter */ );
  2263. }
  2264. }
  2265. // newStArray contains the protocols that should be added
  2266. // ------------------------------------------------------------
  2267. if (newStArray.GetSize())
  2268. {
  2269. for (i=newStArray.GetSize(); --i>= 0; )
  2270. {
  2271. hr = pNewRouter->FindInterface(newStArray.GetAt(i), &spIf);
  2272. Assert(hr == hrOK);
  2273. Assert(spIf);
  2274. // Do a sanity check, make sure that this Interface is
  2275. // in the InterfaceCB list
  2276. // This is only true if this is a LAN adapter.
  2277. // Assert(FindInterfaceCB(spIf->GetId()));
  2278. // We allow errors to not affect whether or not
  2279. // the interface is added to the UI (this allows us
  2280. // to stay in sync with the merged routerinfo).
  2281. // ----------------------------------------------------
  2282. if (spIf)
  2283. {
  2284. hr = AddInterfaceInternal(spIf, FALSE, FALSE);
  2285. // Send the RmIf notifications
  2286. // ------------------------------------------------
  2287. if (FHrOK(hr))
  2288. NotifyRtrMgrInterfaceOfMove(spIf);
  2289. // Remove this interface from its previous router
  2290. // ------------------------------------------------
  2291. pNewRouter->ReleaseInterface(spIf->GetId());
  2292. }
  2293. spIf.Release();
  2294. }
  2295. }
  2296. COM_PROTECT_ERROR_LABEL;
  2297. }
  2298. COM_PROTECT_CATCH;
  2299. return hr;
  2300. }
  2301. /*!--------------------------------------------------------------------------
  2302. RouterInfo::FindRtrMgrCB
  2303. -
  2304. Author: KennT
  2305. ---------------------------------------------------------------------------*/
  2306. SRtrMgrCB * RouterInfo::FindRtrMgrCB(DWORD dwTransportId)
  2307. {
  2308. POSITION pos;
  2309. SRtrMgrCB * pSRmCB = NULL;
  2310. pos = m_RmCBList.GetHeadPosition();
  2311. while (pos)
  2312. {
  2313. pSRmCB = m_RmCBList.GetNext(pos);
  2314. Assert(pSRmCB);
  2315. if (pSRmCB->dwTransportId == dwTransportId)
  2316. return pSRmCB;
  2317. }
  2318. return NULL;
  2319. }
  2320. /*!--------------------------------------------------------------------------
  2321. RouterInfo::FindRtrMgrProtocolCB
  2322. -
  2323. Author: KennT
  2324. ---------------------------------------------------------------------------*/
  2325. SRtrMgrProtocolCB * RouterInfo::FindRtrMgrProtocolCB(DWORD dwTransportId, DWORD dwProtocolId)
  2326. {
  2327. POSITION pos;
  2328. SRtrMgrProtocolCB * pSRmProtCB = NULL;
  2329. pos = m_RmProtCBList.GetHeadPosition();
  2330. while (pos)
  2331. {
  2332. pSRmProtCB = m_RmProtCBList.GetNext(pos);
  2333. Assert(pSRmProtCB);
  2334. if ((pSRmProtCB->dwTransportId == dwTransportId) &&
  2335. (pSRmProtCB->dwProtocolId == dwProtocolId))
  2336. return pSRmProtCB;
  2337. }
  2338. return NULL;
  2339. }
  2340. /*!--------------------------------------------------------------------------
  2341. RouterInfo::FindInterfaceCB
  2342. -
  2343. Author: KennT
  2344. ---------------------------------------------------------------------------*/
  2345. SInterfaceCB * RouterInfo::FindInterfaceCB(LPCTSTR pszInterfaceId)
  2346. {
  2347. POSITION pos;
  2348. SInterfaceCB * pSIfCB = NULL;
  2349. pos = m_IfCBList.GetHeadPosition();
  2350. while (pos)
  2351. {
  2352. pSIfCB = m_IfCBList.GetNext(pos);
  2353. Assert(pSIfCB);
  2354. if (StriCmp(pSIfCB->stTitle, pszInterfaceId) == 0)
  2355. return pSIfCB;
  2356. }
  2357. return NULL;
  2358. }
  2359. /*!--------------------------------------------------------------------------
  2360. RouterInfo::Disconnect
  2361. Removes connections made by this object.
  2362. Author: KennT
  2363. ---------------------------------------------------------------------------*/
  2364. void RouterInfo::Disconnect()
  2365. {
  2366. if (m_bDisconnect)
  2367. ::MprConfigServerDisconnect(m_hMachineConfig);
  2368. m_bDisconnect = FALSE;
  2369. m_hMachineConfig = NULL;
  2370. }
  2371. /*!--------------------------------------------------------------------------
  2372. RouterInfo::DoDisconnect
  2373. We are to disconnect our connections from the server.
  2374. This means calling MprConfigServerDisconnect() on our
  2375. connections.
  2376. Author: KennT
  2377. ---------------------------------------------------------------------------*/
  2378. STDMETHODIMP RouterInfo::DoDisconnect()
  2379. {
  2380. HRESULT hr = hrOK;
  2381. SPIEnumRtrMgrInfo spEnumRm;
  2382. SPIRtrMgrInfo spRm;
  2383. SPIEnumInterfaceInfo spEnumIf;
  2384. SPIInterfaceInfo spIf;
  2385. COM_PROTECT_TRY
  2386. {
  2387. // Disconnect ourselves
  2388. // ------------------------------------------------------------
  2389. Disconnect();
  2390. // Notify the advise sinks of a disconnect.
  2391. // ------------------------------------------------------------
  2392. RtrNotify(ROUTER_DO_DISCONNECT, 0, 0);
  2393. // Now tell all child objects to disconnect.
  2394. // ------------------------------------------------------------
  2395. HRESULT hrIter = hrOK;
  2396. // Tell each of the router-managers to disconnect.
  2397. // ------------------------------------------------------------
  2398. EnumRtrMgr(&spEnumRm);
  2399. spEnumRm->Reset();
  2400. while (spEnumRm->Next(1, &spRm, NULL) == hrOK)
  2401. {
  2402. spRm->DoDisconnect();
  2403. spRm.Release();
  2404. }
  2405. // Tell each interface to disconnect.
  2406. // ------------------------------------------------------------
  2407. EnumInterface(&spEnumIf);
  2408. spEnumIf->Reset();
  2409. while (spEnumIf->Next(1, &spIf, NULL) == hrOK)
  2410. {
  2411. spIf->DoDisconnect();
  2412. spIf.Release();
  2413. }
  2414. }
  2415. COM_PROTECT_CATCH;
  2416. return hr;
  2417. }
  2418. /*!--------------------------------------------------------------------------
  2419. RouterInfo::IsAdminInfoSet
  2420. -
  2421. Author: KennT
  2422. ---------------------------------------------------------------------------*/
  2423. STDMETHODIMP_(BOOL) RouterInfo::IsAdminInfoSet()
  2424. {
  2425. return m_fIsAdminInfoSet;
  2426. }
  2427. STDMETHODIMP_(LPCOLESTR) RouterInfo::GetUserName()
  2428. {
  2429. if (m_fIsAdminInfoSet)
  2430. return (LPCOLESTR) m_stUserName;
  2431. else
  2432. return NULL;
  2433. }
  2434. STDMETHODIMP_(LPCOLESTR) RouterInfo::GetDomainName()
  2435. {
  2436. if (m_fIsAdminInfoSet && !m_stDomain.IsEmpty())
  2437. return (LPCOLESTR) m_stDomain;
  2438. else
  2439. return NULL;
  2440. }
  2441. STDMETHODIMP RouterInfo::GetUserPassword(BYTE *pPassword, int *pcPassword)
  2442. {
  2443. HRESULT hr = hrOK;
  2444. if (pPassword == NULL)
  2445. {
  2446. Assert(pcPassword);
  2447. *pcPassword = m_cPassword;
  2448. return hr;
  2449. }
  2450. Assert(pPassword);
  2451. Assert(pcPassword);
  2452. COM_PROTECT_TRY
  2453. {
  2454. if (!m_fIsAdminInfoSet)
  2455. {
  2456. *pcPassword = 0;
  2457. }
  2458. else
  2459. {
  2460. CopyMemory(pPassword, m_pbPassword, m_cPassword);
  2461. *pcPassword = m_cPassword;
  2462. }
  2463. }
  2464. COM_PROTECT_CATCH;
  2465. return hr;
  2466. }
  2467. STDMETHODIMP RouterInfo::SetInfo(LPCOLESTR pszName,
  2468. LPCOLESTR pszDomain,
  2469. LPBYTE pPassword,
  2470. int cPassword)
  2471. {
  2472. HRESULT hr = hrOK;
  2473. Assert(pszName);
  2474. COM_PROTECT_TRY
  2475. {
  2476. m_stUserName = pszName;
  2477. m_stDomain = pszDomain;
  2478. // Allocate space for the password
  2479. delete m_pbPassword;
  2480. m_pbPassword = NULL;
  2481. m_cPassword = 0;
  2482. if (cPassword)
  2483. {
  2484. m_pbPassword = new BYTE[cPassword];
  2485. CopyMemory(m_pbPassword, pPassword, cPassword);
  2486. m_cPassword = cPassword;
  2487. }
  2488. m_fIsAdminInfoSet = TRUE;
  2489. }
  2490. COM_PROTECT_CATCH;
  2491. return hr;
  2492. }
  2493. /*---------------------------------------------------------------------------
  2494. RtrMgrInfo implementation
  2495. ---------------------------------------------------------------------------*/
  2496. IMPLEMENT_WEAKREF_ADDREF_RELEASE(RtrMgrInfo);
  2497. IMPLEMENT_SIMPLE_QUERYINTERFACE(RtrMgrInfo, IRtrMgrInfo)
  2498. DEBUG_DECLARE_INSTANCE_COUNTER(RtrMgrInfo)
  2499. RtrMgrInfo::RtrMgrInfo(DWORD dwTransportId,
  2500. LPCTSTR pszTransportName,
  2501. RouterInfo *pRouterInfo)
  2502. : m_hMachineConfig(NULL),
  2503. m_hTransport(NULL),
  2504. m_bDisconnect(FALSE),
  2505. m_dwFlags(0)
  2506. {
  2507. DEBUG_INCREMENT_INSTANCE_COUNTER(RtrMgrInfo);
  2508. m_cb.dwTransportId = dwTransportId;
  2509. m_cb.stId = pszTransportName;
  2510. // There is a case in the old code where pRouterInfo == NULL
  2511. // It is in the CAddRouterManager dialog, however this is
  2512. // not called from anywhere in the code.
  2513. // ----------------------------------------------------------------
  2514. Assert(pRouterInfo);
  2515. m_pRouterInfoParent = static_cast<IRouterInfo *>(pRouterInfo);
  2516. if (m_pRouterInfoParent)
  2517. m_pRouterInfoParent->AddRef();
  2518. InitializeCriticalSection(&m_critsec);
  2519. }
  2520. RtrMgrInfo::~RtrMgrInfo()
  2521. {
  2522. Assert(m_pRouterInfoParent == NULL);
  2523. Assert(m_AdviseList.IsEmpty());
  2524. Destruct();
  2525. DEBUG_DECREMENT_INSTANCE_COUNTER(RtrMgrInfo);
  2526. DeleteCriticalSection(&m_critsec);
  2527. }
  2528. void RtrMgrInfo::ReviveStrongRef()
  2529. {
  2530. RtrCriticalSection rtrCritSec(&m_critsec);
  2531. if (m_pRouterInfoParent)
  2532. {
  2533. CONVERT_TO_STRONGREF(m_pRouterInfoParent);
  2534. }
  2535. }
  2536. void RtrMgrInfo::OnLastStrongRef()
  2537. {
  2538. RtrCriticalSection rtrCritSec(&m_critsec);
  2539. if (m_pRouterInfoParent)
  2540. {
  2541. CONVERT_TO_WEAKREF(m_pRouterInfoParent);
  2542. }
  2543. if (m_fDestruct)
  2544. Destruct();
  2545. }
  2546. STDMETHODIMP RtrMgrInfo::Destruct()
  2547. {
  2548. RtrCriticalSection rtrCritSec(&m_critsec);
  2549. IRouterInfo * pParent;
  2550. m_fDestruct = TRUE;
  2551. if (!m_fStrongRef)
  2552. {
  2553. // Release the parent pointer
  2554. // ------------------------------------------------------------
  2555. pParent = m_pRouterInfoParent;
  2556. m_pRouterInfoParent = NULL;
  2557. if (pParent)
  2558. pParent->ReleaseWeakRef();
  2559. // Release the data
  2560. // ------------------------------------------------------------
  2561. Unload();
  2562. }
  2563. return hrOK;
  2564. }
  2565. STDMETHODIMP_(DWORD) RtrMgrInfo::GetFlags()
  2566. {
  2567. RtrCriticalSection rtrCritSec(&m_critsec);
  2568. return m_dwFlags;
  2569. }
  2570. STDMETHODIMP RtrMgrInfo::SetFlags(DWORD dwFlags)
  2571. {
  2572. RtrCriticalSection rtrCritSec(&m_critsec);
  2573. HRESULT hr = hrOK;
  2574. COM_PROTECT_TRY
  2575. {
  2576. m_dwFlags = dwFlags;
  2577. }
  2578. COM_PROTECT_CATCH;
  2579. return hr;
  2580. }
  2581. /*!--------------------------------------------------------------------------
  2582. RtrMgrInfo::Load
  2583. -
  2584. Loads a CRmInfo structure from the registry
  2585. Author: KennT
  2586. ---------------------------------------------------------------------------*/
  2587. STDMETHODIMP RtrMgrInfo::Load(LPCOLESTR pszMachine,
  2588. HANDLE hMachine,
  2589. HANDLE hTransport
  2590. )
  2591. {
  2592. RtrCriticalSection rtrCritSec(&m_critsec);
  2593. HRESULT hr = hrOK;
  2594. SPIEnumRtrMgrCB spEnumRmCB;
  2595. IEnumRtrMgrCB * pEnumRmCB;
  2596. BOOL bFound;
  2597. RtrMgrCB RmCBTemp;
  2598. USES_CONVERSION;
  2599. COM_PROTECT_TRY
  2600. {
  2601. // Discard any existing information
  2602. // ------------------------------------------------------------
  2603. Unload();
  2604. m_stMachine = (pszMachine ? pszMachine : TEXT(""));
  2605. // if 'hMachine' was not specified, connect to the config
  2606. // on the specified machine
  2607. // ------------------------------------------------------------
  2608. Assert(m_hMachineConfig == NULL);
  2609. CORg( TryToConnect(OLE2CW(pszMachine), &hMachine) );
  2610. // if 'hTransport' was not specified, connect to the transport
  2611. // ------------------------------------------------------------
  2612. if (hTransport)
  2613. m_hTransport = hTransport;
  2614. else
  2615. {
  2616. CWRg( ::MprConfigTransportGetHandle(hMachine,
  2617. GetTransportId(),
  2618. &hTransport));
  2619. m_hTransport = hTransport;
  2620. }
  2621. // Retrieve the title, dll-path, and config-dll from the Software key;
  2622. // ------------------------------------------------------------
  2623. Assert(m_pRouterInfoParent);
  2624. CORg( m_pRouterInfoParent->EnumRtrMgrCB(&pEnumRmCB) );
  2625. spEnumRmCB = pEnumRmCB;
  2626. // Find the control-block for the router-manager being loaded
  2627. // ------------------------------------------------------------
  2628. bFound = FALSE;
  2629. pEnumRmCB->Reset();
  2630. while (pEnumRmCB->Next(1, &RmCBTemp, NULL) == hrOK)
  2631. {
  2632. // Get the next control-block
  2633. // --------------------------------------------------------
  2634. if (RmCBTemp.dwTransportId != GetTransportId())
  2635. continue;
  2636. m_cb.stTitle = OLE2CT(RmCBTemp.szId);
  2637. m_cb.stDLLPath= OLE2CT(RmCBTemp.szTitle);
  2638. //m_cb.stConfigDLL = OLE2CT(RmCBTemp.szConfigDLL);
  2639. bFound = TRUE;
  2640. break;
  2641. }
  2642. if (!bFound)
  2643. m_cb.stTitle = m_cb.stId;
  2644. // Load the list of routing-protocols for this router-manager
  2645. // ------------------------------------------------------------
  2646. CWRg( LoadRtrMgrInfo(hMachine,
  2647. hTransport) );
  2648. COM_PROTECT_ERROR_LABEL;
  2649. }
  2650. COM_PROTECT_CATCH;
  2651. if (!FHrSucceeded(hr))
  2652. Unload();
  2653. return hr;
  2654. }
  2655. /*!--------------------------------------------------------------------------
  2656. RtrMgrInfo::Save
  2657. -
  2658. This function saves the information for a CRmInfo in the registry.
  2659. Author: KennT
  2660. ---------------------------------------------------------------------------*/
  2661. STDMETHODIMP RtrMgrInfo::Save(LPCOLESTR pszMachine,
  2662. HANDLE hMachine,
  2663. HANDLE hTransport,
  2664. IInfoBase * pGlobalInfo,
  2665. IInfoBase * pClientInfo,
  2666. DWORD dwDeleteProtocolId)
  2667. {
  2668. RtrCriticalSection rtrCritSec(&m_critsec);
  2669. HRESULT hr = hrOK;
  2670. DWORD dwErr;
  2671. LPWSTR pwsz = NULL;
  2672. WCHAR wszTransport[MAX_TRANSPORT_NAME_LEN+1];
  2673. SPWSZ spwszDll;
  2674. COM_PROTECT_TRY
  2675. {
  2676. // If we are already connected (i.e. 'm_hMachineConfig' is non-NULL)
  2677. // then the handle passed in is ignored.
  2678. //
  2679. // Otherwise, if 'hMachine' was not specified, connect to the config
  2680. // on the specified machine
  2681. // ------------------------------------------------------------
  2682. CORg( TryToConnect(OLE2CW(pszMachine), &hMachine) );
  2683. // If we are already connected (i.e. 'm_hTransport' is non-NULL)
  2684. // then the handle passed in is ignored.
  2685. //
  2686. // Otherwise, if 'hTransport' wasn't passed in, try to get a handle
  2687. // to the transport; if that fails, create the transport.
  2688. // ------------------------------------------------------------
  2689. if (m_hTransport)
  2690. hTransport = m_hTransport;
  2691. else if (hTransport)
  2692. m_hTransport = hTransport;
  2693. else
  2694. {
  2695. // Get a handle to the transport
  2696. // --------------------------------------------------------
  2697. dwErr = ::MprConfigTransportGetHandle(hMachine,
  2698. m_cb.dwTransportId, &hTransport);
  2699. if (dwErr != NO_ERROR)
  2700. {
  2701. // We couldn't get a handle to the transport,
  2702. // so now attempt to create it.
  2703. //
  2704. // Convert transport-name to Unicode
  2705. // ----------------------------------------------------
  2706. if (!m_cb.stId.GetLength())
  2707. pwsz = NULL;
  2708. else
  2709. pwsz = StrCpyWFromT(wszTransport, m_cb.stId);
  2710. // Convert the DLL path to Unicode
  2711. // ----------------------------------------------------
  2712. spwszDll = StrDupWFromT(m_cb.stDLLPath);
  2713. // Create the transport
  2714. // ----------------------------------------------------
  2715. CWRg( ::MprConfigTransportCreate(hMachine,
  2716. GetTransportId(),
  2717. pwsz,
  2718. NULL,
  2719. 0,
  2720. NULL,
  2721. 0,
  2722. spwszDll,
  2723. &hTransport
  2724. ));
  2725. }
  2726. }
  2727. // Now save the global info for the transport
  2728. // ------------------------------------------------------------
  2729. CWRg( SaveRtrMgrInfo(hMachine,
  2730. hTransport,
  2731. pGlobalInfo,
  2732. pClientInfo,
  2733. dwDeleteProtocolId) );
  2734. COM_PROTECT_ERROR_LABEL;
  2735. }
  2736. COM_PROTECT_CATCH;
  2737. return hr;
  2738. }
  2739. /*!--------------------------------------------------------------------------
  2740. RtrMgrInfo::Unload
  2741. Implementation of IRtrMgrInfo::Unload
  2742. Author: KennT
  2743. ---------------------------------------------------------------------------*/
  2744. STDMETHODIMP RtrMgrInfo::Unload( )
  2745. {
  2746. RtrCriticalSection rtrCritSec(&m_critsec);
  2747. HRESULT hr = hrOK;
  2748. IRtrMgrProtocolInfo * pRmProt;
  2749. COM_PROTECT_TRY
  2750. {
  2751. while (!m_RmProtList.IsEmpty())
  2752. {
  2753. pRmProt = m_RmProtList.RemoveHead();
  2754. pRmProt->Destruct();
  2755. pRmProt->ReleaseWeakRef();
  2756. }
  2757. DoDisconnect();
  2758. }
  2759. COM_PROTECT_CATCH;
  2760. return hr;
  2761. }
  2762. /*!--------------------------------------------------------------------------
  2763. RtrMgrInfo::Delete
  2764. -
  2765. This function removes the information associated with a router-manager
  2766. from the registry.
  2767. Author: KennT
  2768. ---------------------------------------------------------------------------*/
  2769. STDMETHODIMP RtrMgrInfo::Delete(LPCOLESTR pszMachine,
  2770. HANDLE hMachine)
  2771. {
  2772. RtrCriticalSection rtrCritSec(&m_critsec);
  2773. HRESULT hr = hrOK;
  2774. HANDLE hTransport = NULL;
  2775. COM_PROTECT_TRY
  2776. {
  2777. //
  2778. // If already connected, the handle passed in is ignored;
  2779. //
  2780. // Otherwise, if 'hMachine' was not specified, connect to the config
  2781. // on the specified machine
  2782. //
  2783. CORg( TryToConnect(OLE2CW(pszMachine), &hMachine) );
  2784. //
  2785. // Attempt to get a handle for the transport
  2786. //
  2787. CWRg( ::MprConfigTransportGetHandle(hMachine,
  2788. m_cb.dwTransportId,
  2789. &hTransport
  2790. ) );
  2791. //
  2792. // Delete the transport
  2793. //
  2794. CWRg( ::MprConfigTransportDelete(hMachine, hTransport) );
  2795. m_hTransport = NULL;
  2796. COM_PROTECT_ERROR_LABEL;
  2797. }
  2798. COM_PROTECT_CATCH;
  2799. return hr;
  2800. }
  2801. /*!--------------------------------------------------------------------------
  2802. RtrMgrInfo::SetInfoBase
  2803. -
  2804. Author: KennT
  2805. ---------------------------------------------------------------------------*/
  2806. STDMETHODIMP RtrMgrInfo::SetInfoBase(IInfoBase* pGlobalInfo,
  2807. IInfoBase* pClientInfo )
  2808. {
  2809. RtrCriticalSection rtrCritSec(&m_critsec);
  2810. HRESULT hr = hrOK;
  2811. MPR_SERVER_HANDLE hRouter = NULL;
  2812. BYTE* pGlobalInfoData = NULL, *pClientInfoData = NULL;
  2813. DWORD dwGlobalInfoDataSize = 0, dwClientInfoDataSize = 0;
  2814. DWORD dwErr;
  2815. COM_PROTECT_TRY
  2816. {
  2817. //
  2818. // Format the router-manager's data as an opaque block
  2819. //
  2820. if (pGlobalInfo)
  2821. CORg( pGlobalInfo->WriteTo(&pGlobalInfoData, &dwGlobalInfoDataSize) );
  2822. //
  2823. // Format the client-interface's data as an opaque block
  2824. //
  2825. if (pClientInfo)
  2826. CORg( pClientInfo->WriteTo(&pClientInfoData, &dwClientInfoDataSize) );
  2827. //
  2828. // Connect to the router
  2829. //
  2830. CORg( ConnectRouter(GetMachineName(), &hRouter) );
  2831. //
  2832. // Set the new info for the router-manager
  2833. //
  2834. dwErr = MprAdminTransportSetInfo(hRouter,
  2835. GetTransportId(),
  2836. pGlobalInfoData,
  2837. dwGlobalInfoDataSize,
  2838. pClientInfoData,
  2839. dwClientInfoDataSize
  2840. );
  2841. if ((dwErr == RPC_S_SERVER_UNAVAILABLE) ||
  2842. (dwErr == RPC_S_UNKNOWN_IF))
  2843. dwErr = NO_ERROR;
  2844. CWRg( dwErr );
  2845. COM_PROTECT_ERROR_LABEL;
  2846. }
  2847. COM_PROTECT_CATCH;
  2848. CoTaskMemFree( pGlobalInfoData );
  2849. CoTaskMemFree( pClientInfoData );
  2850. if (hRouter)
  2851. ::MprAdminServerDisconnect(hRouter);
  2852. return hr;
  2853. }
  2854. /*!--------------------------------------------------------------------------
  2855. RtrMgrInfo::GetInfoBase
  2856. -
  2857. Author: KennT
  2858. ---------------------------------------------------------------------------*/
  2859. STDMETHODIMP RtrMgrInfo::GetInfoBase(HANDLE hMachine,
  2860. HANDLE hTransport,
  2861. IInfoBase **ppGlobalInfo,
  2862. IInfoBase **ppClientInfo)
  2863. {
  2864. RtrCriticalSection rtrCritSec(&m_critsec);
  2865. HRESULT hr = hrOK;
  2866. COM_PROTECT_TRY
  2867. {
  2868. CORg( TryToGetAllHandles(m_stMachine,
  2869. &hMachine,
  2870. &hTransport) );
  2871. hr = ::LoadInfoBase(hMachine ? hMachine : m_hMachineConfig,
  2872. hTransport ? hTransport : m_hTransport,
  2873. ppGlobalInfo, ppClientInfo);
  2874. COM_PROTECT_ERROR_LABEL;
  2875. }
  2876. COM_PROTECT_CATCH;
  2877. return hr;
  2878. }
  2879. /*!--------------------------------------------------------------------------
  2880. RtrMgrInfo::Merge
  2881. -
  2882. Author: KennT
  2883. ---------------------------------------------------------------------------*/
  2884. STDMETHODIMP RtrMgrInfo::Merge(IRtrMgrInfo *pNewRm)
  2885. {
  2886. RtrCriticalSection rtrCritSec(&m_critsec);
  2887. SPIEnumRtrMgrProtocolInfo spEnumRmProt;
  2888. SPIRtrMgrProtocolInfo spRmProt;
  2889. HRESULT hr = hrOK;
  2890. CDWordArray oldDWArray;
  2891. CDWordArray newDWArray;
  2892. int cOld, cNew;
  2893. int i, j;
  2894. DWORD dwTemp;
  2895. RtrMgrCB rmCB;
  2896. Assert(pNewRm);
  2897. Assert(pNewRm->GetTransportId() == GetTransportId());
  2898. COM_PROTECT_TRY
  2899. {
  2900. pNewRm->CopyRtrMgrCB(&rmCB);
  2901. m_cb.LoadFrom(&rmCB);
  2902. //
  2903. // The general algorithm is to build up two arrays
  2904. // the first array contains the protocol ids for this object
  2905. // the second array contains the ids for the new object
  2906. //
  2907. // We then go through and remove all protocols that are in
  2908. // BOTH lists.
  2909. //
  2910. // This will leave us with the first array containing the
  2911. // ids of the protocols that need to be deleted from this object.
  2912. //
  2913. // The second array will have the list of ids of protocols that
  2914. // have to be added to this object from the second object.
  2915. //
  2916. // Get the list of protocols that are in the new object
  2917. CORg( pNewRm->EnumRtrMgrProtocol(&spEnumRmProt) );
  2918. spEnumRmProt->Reset();
  2919. while (spEnumRmProt->Next(1, &spRmProt, NULL) == hrOK)
  2920. {
  2921. newDWArray.Add(spRmProt->GetProtocolId());
  2922. spRmProt.Release();
  2923. }
  2924. spEnumRmProt.Release();
  2925. spRmProt.Release();
  2926. // Get the list of protocols that are in this object
  2927. CORg( this->EnumRtrMgrProtocol(&spEnumRmProt) );
  2928. spEnumRmProt->Reset();
  2929. while (spEnumRmProt->Next(1, &spRmProt, NULL) == hrOK)
  2930. {
  2931. oldDWArray.Add(spRmProt->GetProtocolId());
  2932. spRmProt.Release();
  2933. }
  2934. spEnumRmProt.Release();
  2935. spRmProt.Release();
  2936. // Ok now go through both lists, removing from the lists
  2937. // protocols that are in both lists.
  2938. cOld = oldDWArray.GetSize();
  2939. cNew = newDWArray.GetSize();
  2940. for (i=cOld; --i>=0; )
  2941. {
  2942. dwTemp = oldDWArray.GetAt(i);
  2943. for (j=cNew; --j>=0; )
  2944. {
  2945. if (dwTemp == newDWArray.GetAt(j))
  2946. {
  2947. // remove both instances
  2948. newDWArray.RemoveAt(j);
  2949. oldDWArray.RemoveAt(i);
  2950. // Need to update the size of the new array
  2951. cNew--;
  2952. break;
  2953. }
  2954. }
  2955. }
  2956. // oldDWArray now contains the protocols that should be
  2957. // removed.
  2958. if (oldDWArray.GetSize())
  2959. {
  2960. for (i=oldDWArray.GetSize(); --i>=0; )
  2961. {
  2962. DeleteRtrMgrProtocol(oldDWArray.GetAt(i), FALSE);
  2963. }
  2964. }
  2965. // newDWArray contains the protocols that should be added
  2966. if (newDWArray.GetSize())
  2967. {
  2968. for (i=newDWArray.GetSize(); --i>= 0; )
  2969. {
  2970. hr = pNewRm->FindRtrMgrProtocol(
  2971. newDWArray.GetAt(i), &spRmProt);
  2972. Assert(hr == hrOK);
  2973. if (spRmProt)
  2974. {
  2975. AddRtrMgrProtocol(spRmProt, NULL, NULL);
  2976. // Remove this rmprot from its old router
  2977. // ------------------------------------------------
  2978. pNewRm->ReleaseRtrMgrProtocol(spRmProt->GetProtocolId());
  2979. }
  2980. spRmProt.Release();
  2981. }
  2982. }
  2983. COM_PROTECT_ERROR_LABEL;
  2984. }
  2985. COM_PROTECT_CATCH;
  2986. return hr;
  2987. }
  2988. /*!--------------------------------------------------------------------------
  2989. RtrMgrInfo::GetId
  2990. -
  2991. Author: KennT
  2992. ---------------------------------------------------------------------------*/
  2993. STDMETHODIMP_(LPCOLESTR) RtrMgrInfo::GetId()
  2994. {
  2995. RtrCriticalSection rtrCritSec(&m_critsec);
  2996. return m_cb.stId;
  2997. }
  2998. /*!--------------------------------------------------------------------------
  2999. RtrMgrInfo::SetId
  3000. -
  3001. Author: KennT
  3002. ---------------------------------------------------------------------------*/
  3003. STDMETHODIMP RtrMgrInfo::SetId(LPCOLESTR pszId)
  3004. {
  3005. RtrCriticalSection rtrCritSec(&m_critsec);
  3006. HRESULT hr = hrOK;
  3007. COM_PROTECT_TRY
  3008. {
  3009. m_cb.stId = pszId;
  3010. }
  3011. COM_PROTECT_CATCH;
  3012. return hr;
  3013. }
  3014. /*!--------------------------------------------------------------------------
  3015. RtrMgrInfo::GetTransportId
  3016. -
  3017. Author: KennT
  3018. ---------------------------------------------------------------------------*/
  3019. STDMETHODIMP_(DWORD) RtrMgrInfo::GetTransportId()
  3020. {
  3021. RtrCriticalSection rtrCritSec(&m_critsec);
  3022. return m_cb.dwTransportId;
  3023. }
  3024. /*!--------------------------------------------------------------------------
  3025. RtrMgrInfo::GetTitle
  3026. -
  3027. Author: KennT
  3028. ---------------------------------------------------------------------------*/
  3029. STDMETHODIMP_(LPCOLESTR) RtrMgrInfo::GetTitle()
  3030. {
  3031. RtrCriticalSection rtrCritSec(&m_critsec);
  3032. //$UNICODE
  3033. // This assumes that we are native UNICODE
  3034. // and that OLECHAR == WCHAR
  3035. return m_cb.stTitle;
  3036. }
  3037. /*!--------------------------------------------------------------------------
  3038. RtrMgrInfo::CopyRtrMgrCB
  3039. -
  3040. Author: KennT
  3041. ---------------------------------------------------------------------------*/
  3042. STDMETHODIMP RtrMgrInfo::CopyRtrMgrCB(RtrMgrCB *pRmCB)
  3043. {
  3044. RtrCriticalSection rtrCritSec(&m_critsec);
  3045. HRESULT hr = hrOK;
  3046. COM_PROTECT_TRY
  3047. {
  3048. m_cb.SaveTo(pRmCB);
  3049. }
  3050. COM_PROTECT_CATCH;
  3051. return hr;
  3052. }
  3053. /*!--------------------------------------------------------------------------
  3054. RtrMgrInfo::GetMachineName
  3055. -
  3056. Author: KennT
  3057. ---------------------------------------------------------------------------*/
  3058. LPCOLESTR RtrMgrInfo::GetMachineName()
  3059. {
  3060. RtrCriticalSection rtrCritSec(&m_critsec);
  3061. //$UNICODE
  3062. // This assumes that we are native UNICODE and that
  3063. // OLECHAR == WCHAR
  3064. return m_stMachine;
  3065. }
  3066. /*!--------------------------------------------------------------------------
  3067. RtrMgrInfo::EnumRtrMgrProtocol
  3068. -
  3069. Author: KennT
  3070. ---------------------------------------------------------------------------*/
  3071. STDMETHODIMP RtrMgrInfo::EnumRtrMgrProtocol(IEnumRtrMgrProtocolInfo ** ppEnumRmProt)
  3072. {
  3073. RtrCriticalSection rtrCritSec(&m_critsec);
  3074. HRESULT hr = hrOK;
  3075. COM_PROTECT_TRY
  3076. {
  3077. hr = CreateEnumFromRtrMgrProtocolList(&m_RmProtList, ppEnumRmProt);
  3078. }
  3079. COM_PROTECT_CATCH;
  3080. return hr;
  3081. }
  3082. /*!--------------------------------------------------------------------------
  3083. RtrMgrInfo::FindRtrMgrProtocol
  3084. S_OK is returned if a RtrMgrInfo is found.
  3085. S_FALSE is returned if a RtrMgrInfo was NOT found.
  3086. error codes returned otherwise.
  3087. -
  3088. Author: KennT
  3089. ---------------------------------------------------------------------------*/
  3090. STDMETHODIMP RtrMgrInfo::FindRtrMgrProtocol(DWORD dwProtocolId,
  3091. IRtrMgrProtocolInfo **ppRmProtInfo)
  3092. {
  3093. RtrCriticalSection rtrCritSec(&m_critsec);
  3094. HRESULT hr = hrFalse;
  3095. POSITION pos;
  3096. SPIRtrMgrProtocolInfo spRmProt;
  3097. COM_PROTECT_TRY
  3098. {
  3099. if (ppRmProtInfo)
  3100. *ppRmProtInfo = NULL;
  3101. // Look through the list of rtr mgrs for the one that matches
  3102. pos = m_RmProtList.GetHeadPosition();
  3103. while (pos)
  3104. {
  3105. spRmProt.Set(m_RmProtList.GetNext(pos));
  3106. Assert(spRmProt);
  3107. if (spRmProt->GetProtocolId() == dwProtocolId)
  3108. {
  3109. hr = hrOK;
  3110. if (ppRmProtInfo)
  3111. {
  3112. // The spRmProt::Set, does a strong reference
  3113. // so we don't need to convert to a strong reference
  3114. *ppRmProtInfo = spRmProt.Transfer();
  3115. }
  3116. break;
  3117. }
  3118. }
  3119. }
  3120. COM_PROTECT_CATCH;
  3121. return hr;
  3122. }
  3123. /*!--------------------------------------------------------------------------
  3124. RtrMgrInfo::AddRtrMgrProtocol
  3125. -
  3126. Author: KennT
  3127. ---------------------------------------------------------------------------*/
  3128. STDMETHODIMP RtrMgrInfo::AddRtrMgrProtocol(IRtrMgrProtocolInfo *pInfo,
  3129. IInfoBase * pGlobalInfo,
  3130. IInfoBase * pClientInfo)
  3131. {
  3132. RtrCriticalSection rtrCritSec(&m_critsec);
  3133. Assert(pInfo);
  3134. HRESULT hr = hrOK;
  3135. COM_PROTECT_TRY
  3136. {
  3137. //
  3138. // Fail if there is a duplicate
  3139. //
  3140. if (FHrOK(FindRtrMgrProtocol(pInfo->GetProtocolId(), NULL)))
  3141. CORg(E_INVALIDARG);
  3142. //
  3143. // Save the router-manager's data
  3144. //
  3145. if (pGlobalInfo || pClientInfo)
  3146. {
  3147. CORg( Save(GetMachineName(),
  3148. m_hMachineConfig,
  3149. m_hTransport,
  3150. pGlobalInfo,
  3151. pClientInfo,
  3152. 0) );
  3153. }
  3154. //
  3155. // Add the routing-protocol to the list
  3156. //
  3157. m_RmProtList.AddTail(pInfo);
  3158. pInfo->AddWeakRef();
  3159. pInfo->SetParentRtrMgrInfo(this);
  3160. m_AdviseList.NotifyChange(ROUTER_CHILD_ADD, ROUTER_OBJ_RmProt, 0);
  3161. COM_PROTECT_ERROR_LABEL;
  3162. }
  3163. COM_PROTECT_CATCH;
  3164. return hr;
  3165. }
  3166. /*!--------------------------------------------------------------------------
  3167. RtrMgrInfo::DeleteRtrMgrProtocol
  3168. -
  3169. Author: KennT
  3170. ---------------------------------------------------------------------------*/
  3171. STDMETHODIMP RtrMgrInfo::DeleteRtrMgrProtocol( DWORD dwProtocolId, BOOL fRemove )
  3172. {
  3173. RtrCriticalSection rtrCritSec(&m_critsec);
  3174. HRESULT hr = hrOK;
  3175. SPIRtrMgrProtocolInfo spRmProt;
  3176. POSITION pos, posRmProt;
  3177. SPIEnumInterfaceInfo spEnumIf;
  3178. SPIEnumRtrMgrInterfaceInfo spEnumRmIf;
  3179. SPIInterfaceInfo spIf;
  3180. SPIRtrMgrInterfaceInfo spRmIf;
  3181. COM_PROTECT_TRY
  3182. {
  3183. //
  3184. // Find the routing-protocol to be deleted
  3185. //
  3186. pos = m_RmProtList.GetHeadPosition();
  3187. while (pos)
  3188. {
  3189. posRmProt = pos;
  3190. spRmProt.Set( m_RmProtList.GetNext(pos) );
  3191. Assert(spRmProt);
  3192. if (spRmProt->GetProtocolId() == dwProtocolId)
  3193. break;
  3194. spRmProt.Release();
  3195. }
  3196. if (!spRmProt)
  3197. CORg( E_INVALIDARG );
  3198. // We should also go through and remove the protocols
  3199. // from any interfaces that use the protocols
  3200. if (m_pRouterInfoParent)
  3201. {
  3202. // Ask the parent for its list of interfaces
  3203. m_pRouterInfoParent->EnumInterface(&spEnumIf);
  3204. for (;spEnumIf->Next(1, &spIf, NULL) == hrOK; spIf.Release())
  3205. {
  3206. // Now enumerate through all of the RtrMgrs on this interface
  3207. spEnumRmIf.Release();
  3208. spRmIf.Release();
  3209. spIf->EnumRtrMgrInterface(&spEnumRmIf);
  3210. for (;spEnumRmIf->Next(1, &spRmIf, NULL) == hrOK;
  3211. spRmIf.Release())
  3212. {
  3213. if (spRmIf->GetTransportId() == GetTransportId())
  3214. {
  3215. // Call this on all interfaces, it should just
  3216. // fail if the protocol is not on that interface
  3217. spRmIf->DeleteRtrMgrProtocolInterface(dwProtocolId,
  3218. fRemove);
  3219. break;
  3220. }
  3221. }
  3222. }
  3223. }
  3224. //
  3225. // save the updated information, removing any block
  3226. // belonging to the deleted routing-protocol
  3227. //
  3228. if (fRemove)
  3229. CORg( Save(GetMachineName(),
  3230. m_hMachineConfig,
  3231. m_hTransport,
  3232. NULL,
  3233. NULL,
  3234. dwProtocolId) );
  3235. //
  3236. // remove the protocol from our list
  3237. //
  3238. spRmProt->Destruct();
  3239. spRmProt->ReleaseWeakRef();
  3240. // spRmProt.Transfer();
  3241. m_RmProtList.RemoveAt(posRmProt);
  3242. m_AdviseList.NotifyChange(ROUTER_CHILD_DELETE, ROUTER_OBJ_RmProt, 0);
  3243. COM_PROTECT_ERROR_LABEL;
  3244. }
  3245. COM_PROTECT_CATCH;
  3246. return hr;
  3247. }
  3248. /*!--------------------------------------------------------------------------
  3249. RtrMgrInfo::ReleaseRtrMgrProtocol
  3250. This function will release the AddRef() that this object has
  3251. on the child. This allows us to transfer child objects from
  3252. one router to another.
  3253. Author: KennT
  3254. ---------------------------------------------------------------------------*/
  3255. STDMETHODIMP RtrMgrInfo::ReleaseRtrMgrProtocol( DWORD dwProtocolId )
  3256. {
  3257. HRESULT hr = hrOK;
  3258. POSITION pos, posRmProt;
  3259. SPIRtrMgrProtocolInfo spRmProt;
  3260. COM_PROTECT_TRY
  3261. {
  3262. pos = m_RmProtList.GetHeadPosition();
  3263. while (pos)
  3264. {
  3265. // Save the position (so that we can delete it)
  3266. posRmProt = pos;
  3267. spRmProt.Set( m_RmProtList.GetNext(pos) );
  3268. if (spRmProt &&
  3269. (spRmProt->GetProtocolId() == dwProtocolId))
  3270. {
  3271. // When releasing, we need to disconnect (since the
  3272. // main handle is controlled by the router info).
  3273. spRmProt->DoDisconnect();
  3274. spRmProt->ReleaseWeakRef();
  3275. spRmProt.Release();
  3276. // release this node from the list
  3277. m_RmProtList.RemoveAt(posRmProt);
  3278. break;
  3279. }
  3280. spRmProt.Release();
  3281. }
  3282. }
  3283. COM_PROTECT_CATCH;
  3284. return hr;
  3285. }
  3286. /*!--------------------------------------------------------------------------
  3287. RtrMgrInfo::RtrAdvise
  3288. -
  3289. Author: KennT
  3290. ---------------------------------------------------------------------------*/
  3291. STDMETHODIMP RtrMgrInfo::RtrAdvise(IRtrAdviseSink *pRtrAdviseSink,
  3292. LONG_PTR *pulConnection,
  3293. LPARAM lUserParam)
  3294. {
  3295. RtrCriticalSection rtrCritSec(&m_critsec);
  3296. Assert(pRtrAdviseSink);
  3297. Assert(pulConnection);
  3298. LONG_PTR ulConnId;
  3299. HRESULT hr = hrOK;
  3300. COM_PROTECT_TRY
  3301. {
  3302. ulConnId = (LONG_PTR) InterlockedIncrement(&s_cConnections);
  3303. CORg( m_AdviseList.AddConnection(pRtrAdviseSink, ulConnId, lUserParam) );
  3304. *pulConnection = ulConnId;
  3305. COM_PROTECT_ERROR_LABEL;
  3306. }
  3307. COM_PROTECT_CATCH;
  3308. return hr;
  3309. }
  3310. /*!--------------------------------------------------------------------------
  3311. RtrMgrInfo::RtrNotify
  3312. -
  3313. Author: KennT
  3314. ---------------------------------------------------------------------------*/
  3315. STDMETHODIMP RtrMgrInfo::RtrNotify(DWORD dwChangeType, DWORD dwObjectType,
  3316. LPARAM lParam)
  3317. {
  3318. RtrCriticalSection rtrCritSec(&m_critsec);
  3319. HRESULT hr = hrOK;
  3320. COM_PROTECT_TRY
  3321. {
  3322. m_AdviseList.NotifyChange(dwChangeType, dwObjectType, lParam);
  3323. }
  3324. COM_PROTECT_CATCH;
  3325. return hr;
  3326. }
  3327. /*!--------------------------------------------------------------------------
  3328. RtrMgrInfo::RtrUnadvise
  3329. -
  3330. Author: KennT
  3331. ---------------------------------------------------------------------------*/
  3332. STDMETHODIMP RtrMgrInfo::RtrUnadvise(LONG_PTR ulConnection)
  3333. {
  3334. RtrCriticalSection rtrCritSec(&m_critsec);
  3335. return m_AdviseList.RemoveConnection(ulConnection);
  3336. }
  3337. /*!--------------------------------------------------------------------------
  3338. RtrMgrInfo::LoadRtrMgrInfo
  3339. -
  3340. Author: KennT
  3341. ---------------------------------------------------------------------------*/
  3342. HRESULT RtrMgrInfo::LoadRtrMgrInfo(HANDLE hMachine,
  3343. HANDLE hTransport)
  3344. {
  3345. RtrCriticalSection rtrCritSec(&m_critsec);
  3346. HRESULT hr = hrOK;
  3347. SPIInfoBase spGlobalInfo;
  3348. SPIEnumInfoBlock spEnumInfoBlock;
  3349. SPIEnumRtrMgrProtocolCB spEnumRmProtCB;
  3350. InfoBlock * pBlock;
  3351. RtrMgrProtocolCB RmProtCB;
  3352. RtrMgrProtocolInfo *pRmProt = NULL;
  3353. //
  3354. // If reloading, always load the global info, whether or not
  3355. // the caller has requested that it be loaded, since it will be needed
  3356. // to build the list of installed protocols.
  3357. //
  3358. //$ Review: kennt, what do we do with an error? This case was not
  3359. // checked previously.
  3360. GetInfoBase(hMachine, hTransport, &spGlobalInfo, NULL);
  3361. //
  3362. // We are reloading, so we need to rebuild the list of protocols.
  3363. // Get a list of the installed routing-protocols;
  3364. //
  3365. CORg( m_pRouterInfoParent->EnumRtrMgrProtocolCB(&spEnumRmProtCB) );
  3366. //
  3367. // Go through the list of blocks in the global info
  3368. // constructing a CRmProtInfo for each one that corresponds
  3369. // to a routing-protocol
  3370. //
  3371. CORg( spGlobalInfo->QueryBlockList(&spEnumInfoBlock) );
  3372. spEnumInfoBlock->Reset();
  3373. while (spEnumInfoBlock->Next(1, &pBlock, NULL) == hrOK)
  3374. {
  3375. //
  3376. // When a routing protocol is removed, its block is left in place,
  3377. // but with zero-length data.
  3378. // We skip such blocks since they don't represent installed protocols.
  3379. //
  3380. if (!pBlock->dwSize)
  3381. continue;
  3382. //
  3383. // Try to find a routing protocol whose protocol-ID
  3384. // is the same as this block's type
  3385. //
  3386. spEnumRmProtCB->Reset();
  3387. while (spEnumRmProtCB->Next(1, &RmProtCB, NULL) == hrOK)
  3388. {
  3389. //
  3390. // If this isn't the protocol's control block, continue
  3391. //
  3392. if (RmProtCB.dwProtocolId != pBlock->dwType)
  3393. continue;
  3394. //
  3395. // This is the control block, so construct a new CRmProtInfo
  3396. //
  3397. pRmProt = new RtrMgrProtocolInfo(RmProtCB.dwProtocolId,
  3398. RmProtCB.szId,
  3399. GetTransportId(),
  3400. m_cb.stId,
  3401. this);
  3402. Assert(pRmProt);
  3403. pRmProt->SetCB(&RmProtCB);
  3404. //
  3405. // Add the new protocol to our list
  3406. //
  3407. m_RmProtList.AddTail(pRmProt);
  3408. CONVERT_TO_WEAKREF(pRmProt);
  3409. pRmProt = NULL;
  3410. break;
  3411. }
  3412. }
  3413. Error:
  3414. if (pRmProt)
  3415. pRmProt->Release();
  3416. return hr;
  3417. }
  3418. /*!--------------------------------------------------------------------------
  3419. RtrMgrInfo::SaveRtrMgrInfo
  3420. -
  3421. Author: KennT
  3422. ---------------------------------------------------------------------------*/
  3423. HRESULT RtrMgrInfo::SaveRtrMgrInfo(HANDLE hMachine,
  3424. HANDLE hTransport,
  3425. IInfoBase *pGlobalInfo,
  3426. IInfoBase *pClientInfo,
  3427. DWORD dwDeleteProtocolId)
  3428. {
  3429. RtrCriticalSection rtrCritSec(&m_critsec);
  3430. HRESULT hr = hrOK;
  3431. SPIInfoBase spGlobalInfoTemp;
  3432. SPIInfoBase spClientInfoTemp;
  3433. DWORD dwGlobalBytesSize, dwClientBytesSize;
  3434. LPBYTE pGlobalBytes = NULL, pClientBytes = NULL;
  3435. COM_PROTECT_TRY
  3436. {
  3437. //
  3438. // If asked to delete a protocol, delete it now
  3439. //
  3440. if (dwDeleteProtocolId)
  3441. {
  3442. //
  3443. // If either global-info or client info was not given
  3444. // load the unspecified parameters so that they can be updated
  3445. // after the protocol to be deleted has been removed
  3446. //
  3447. if (!pGlobalInfo || !pClientInfo)
  3448. {
  3449. GetInfoBase(hMachine, hTransport,
  3450. pGlobalInfo ? NULL : &spGlobalInfoTemp,
  3451. pClientInfo ? NULL : &spClientInfoTemp
  3452. );
  3453. if (pGlobalInfo == NULL)
  3454. pGlobalInfo = spGlobalInfoTemp;
  3455. if (pClientInfo == NULL)
  3456. pClientInfo = spClientInfoTemp;
  3457. }
  3458. //
  3459. // Now remove the protocol specified
  3460. //
  3461. pGlobalInfo->SetData(dwDeleteProtocolId, 0, NULL, 0, 0);
  3462. pClientInfo->SetData(dwDeleteProtocolId, 0, NULL, 0, 0);
  3463. }
  3464. //
  3465. // Now update the information in the registry
  3466. // Convert the global-info to raw bytes
  3467. //
  3468. if (pGlobalInfo)
  3469. CORg( pGlobalInfo->WriteTo(&pGlobalBytes, &dwGlobalBytesSize) );
  3470. //
  3471. // Now convert the client-info to raw bytes
  3472. //
  3473. if (pClientInfo)
  3474. CORg( pClientInfo->WriteTo(&pClientBytes, &dwClientBytesSize) );
  3475. //
  3476. // Save the information to the persistent store
  3477. //
  3478. CWRg( ::MprConfigTransportSetInfo(hMachine,
  3479. hTransport,
  3480. pGlobalBytes,
  3481. dwGlobalBytesSize,
  3482. pClientBytes,
  3483. dwClientBytesSize,
  3484. NULL
  3485. ) );
  3486. //
  3487. // Finally, update the info of the running router-manager if possible
  3488. //
  3489. CORg( SetInfoBase(pGlobalInfo, pClientInfo) );
  3490. COM_PROTECT_ERROR_LABEL;
  3491. }
  3492. COM_PROTECT_CATCH;
  3493. CoTaskMemFree( pGlobalBytes );
  3494. CoTaskMemFree( pClientBytes );
  3495. return hrOK;
  3496. }
  3497. /*!--------------------------------------------------------------------------
  3498. RtrMgrInfo::TryToConnect
  3499. -
  3500. Author: KennT
  3501. ---------------------------------------------------------------------------*/
  3502. HRESULT RtrMgrInfo::TryToConnect(LPCWSTR pswzMachine, HANDLE *phMachine)
  3503. {
  3504. RtrCriticalSection rtrCritSec(&m_critsec);
  3505. HRESULT hr = hrOK;
  3506. if (m_hMachineConfig)
  3507. *phMachine = m_hMachineConfig;
  3508. else if (*phMachine)
  3509. {
  3510. m_hMachineConfig = *phMachine;
  3511. m_bDisconnect = FALSE;
  3512. }
  3513. else
  3514. {
  3515. //$ Review: kennt, this function does not take a LPCWSTR,
  3516. // is this a mistake or does it modify the parameters?
  3517. CWRg( ::MprConfigServerConnect((LPWSTR) pswzMachine, phMachine) );
  3518. m_hMachineConfig = *phMachine;
  3519. m_bDisconnect = TRUE;
  3520. }
  3521. Error:
  3522. return hr;
  3523. }
  3524. /*!--------------------------------------------------------------------------
  3525. RtrMgrInfo::GetParentRouterInfo
  3526. -
  3527. Author: KennT
  3528. ---------------------------------------------------------------------------*/
  3529. HRESULT RtrMgrInfo::GetParentRouterInfo(IRouterInfo **ppParent)
  3530. {
  3531. RtrCriticalSection rtrCritSec(&m_critsec);
  3532. *ppParent = m_pRouterInfoParent;
  3533. if (*ppParent)
  3534. (*ppParent)->AddRef();
  3535. return hrOK;
  3536. }
  3537. /*!--------------------------------------------------------------------------
  3538. RtrMgrInfo::SetParentRouterInfo
  3539. -
  3540. Author: KennT
  3541. ---------------------------------------------------------------------------*/
  3542. HRESULT RtrMgrInfo::SetParentRouterInfo(IRouterInfo *pParent)
  3543. {
  3544. RtrCriticalSection rtrCritSec(&m_critsec);
  3545. IRouterInfo * pTemp;
  3546. pTemp = m_pRouterInfoParent;
  3547. m_pRouterInfoParent = NULL;
  3548. if (m_fStrongRef)
  3549. {
  3550. if (pTemp)
  3551. pTemp->Release();
  3552. if (pParent)
  3553. pParent->AddRef();
  3554. }
  3555. else
  3556. {
  3557. if (pTemp)
  3558. pTemp->ReleaseWeakRef();
  3559. if (pParent)
  3560. pParent->AddWeakRef();
  3561. }
  3562. m_pRouterInfoParent = pParent;
  3563. return hrOK;
  3564. }
  3565. /*!--------------------------------------------------------------------------
  3566. RtrMgrInfo::Disconnect
  3567. -
  3568. Author: KennT
  3569. ---------------------------------------------------------------------------*/
  3570. void RtrMgrInfo::Disconnect()
  3571. {
  3572. if (m_bDisconnect && m_hMachineConfig)
  3573. ::MprConfigServerDisconnect(m_hMachineConfig);
  3574. m_bDisconnect = FALSE;
  3575. m_hMachineConfig = NULL;
  3576. m_hTransport = NULL;
  3577. }
  3578. /*!--------------------------------------------------------------------------
  3579. RtrMgrInfo::DoDisconnect
  3580. Removes the connections held by this object.
  3581. Author: KennT
  3582. ---------------------------------------------------------------------------*/
  3583. STDMETHODIMP RtrMgrInfo::DoDisconnect()
  3584. {
  3585. HRESULT hr = hrOK;
  3586. SPIEnumRtrMgrProtocolInfo spEnumRmProt;
  3587. SPIRtrMgrProtocolInfo spRmProt;
  3588. COM_PROTECT_TRY
  3589. {
  3590. // Disconnect our data.
  3591. // ------------------------------------------------------------
  3592. Disconnect();
  3593. // Notify the advise sinks of a disconnect.
  3594. // ------------------------------------------------------------
  3595. RtrNotify(ROUTER_DO_DISCONNECT, 0, 0);
  3596. // Now tell all child objects to disconnect.
  3597. // ------------------------------------------------------------
  3598. HRESULT hrIter = hrOK;
  3599. EnumRtrMgrProtocol(&spEnumRmProt);
  3600. spEnumRmProt->Reset();
  3601. while (spEnumRmProt->Next(1, &spRmProt, NULL) == hrOK)
  3602. {
  3603. spRmProt->DoDisconnect();
  3604. spRmProt.Release();
  3605. }
  3606. }
  3607. COM_PROTECT_CATCH;
  3608. return hr;
  3609. }
  3610. HRESULT RtrMgrInfo::TryToGetAllHandles(LPCOLESTR pszMachine,
  3611. HANDLE *phMachine,
  3612. HANDLE *phTransport)
  3613. {
  3614. HRESULT hr = hrOK;
  3615. Assert(phMachine);
  3616. Assert(phTransport);
  3617. //
  3618. // If already loaded, the handle passed in is ignored.
  3619. //
  3620. // Otherwise, if 'hMachine' was not specified, connect to the config
  3621. // on the specified machine
  3622. //
  3623. CORg( TryToConnect(pszMachine, phMachine) );
  3624. //
  3625. // Get a handle to the interface-transport
  3626. //
  3627. //
  3628. // If 'hIfTransport' was not specified, connect
  3629. //
  3630. if (phTransport)
  3631. {
  3632. if (m_hTransport)
  3633. *phTransport = m_hTransport;
  3634. else if (*phTransport)
  3635. m_hTransport = *phTransport;
  3636. else
  3637. {
  3638. //
  3639. // Get a handle to the interface-transport
  3640. //
  3641. CWRg( ::MprConfigTransportGetHandle(
  3642. *phMachine,
  3643. GetTransportId(),
  3644. phTransport
  3645. ) );
  3646. m_hTransport = *phTransport;
  3647. }
  3648. }
  3649. Error:
  3650. return hr;
  3651. }
  3652. /*---------------------------------------------------------------------------
  3653. RtrMgrProtocolInfo Implementation
  3654. ---------------------------------------------------------------------------*/
  3655. TFSCORE_API(HRESULT) CreateRtrMgrProtocolInfo(
  3656. IRtrMgrProtocolInfo **ppRmProtInfo,
  3657. const RtrMgrProtocolCB *pRmProtCB)
  3658. {
  3659. Assert(ppRmProtInfo);
  3660. Assert(pRmProtCB);
  3661. HRESULT hr = hrOK;
  3662. IRtrMgrProtocolInfo * pRmProt = NULL;
  3663. RtrMgrProtocolInfo * prmp;
  3664. USES_CONVERSION;
  3665. COM_PROTECT_TRY
  3666. {
  3667. prmp = new RtrMgrProtocolInfo(pRmProtCB->dwProtocolId,
  3668. W2CT(pRmProtCB->szId),
  3669. pRmProtCB->dwTransportId,
  3670. W2CT(pRmProtCB->szRtrMgrId),
  3671. NULL);
  3672. prmp->SetCB(pRmProtCB);
  3673. *ppRmProtInfo = prmp;
  3674. }
  3675. COM_PROTECT_CATCH;
  3676. return hr;
  3677. }
  3678. IMPLEMENT_WEAKREF_ADDREF_RELEASE(RtrMgrProtocolInfo);
  3679. IMPLEMENT_SIMPLE_QUERYINTERFACE(RtrMgrProtocolInfo, IRtrMgrProtocolInfo)
  3680. DEBUG_DECLARE_INSTANCE_COUNTER(RtrMgrProtocolInfo)
  3681. RtrMgrProtocolInfo::RtrMgrProtocolInfo(DWORD dwProtocolId,
  3682. LPCTSTR lpszId,
  3683. DWORD dwTransportId,
  3684. LPCTSTR lpszRm,
  3685. RtrMgrInfo * pRmInfo)
  3686. : m_dwFlags(0)
  3687. {
  3688. DEBUG_INCREMENT_INSTANCE_COUNTER(RtrMgrProtocolInfo);
  3689. m_cb.dwProtocolId = dwProtocolId;
  3690. m_cb.stId = lpszId;
  3691. m_cb.dwTransportId = dwTransportId;
  3692. m_cb.stRtrMgrId = lpszRm;
  3693. m_pRtrMgrInfoParent = pRmInfo;
  3694. if (m_pRtrMgrInfoParent)
  3695. m_pRtrMgrInfoParent->AddRef();
  3696. InitializeCriticalSection(&m_critsec);
  3697. }
  3698. RtrMgrProtocolInfo::~RtrMgrProtocolInfo()
  3699. {
  3700. Assert(m_pRtrMgrInfoParent == NULL);
  3701. Destruct();
  3702. DEBUG_DECREMENT_INSTANCE_COUNTER(RtrMgrProtocolInfo);
  3703. DeleteCriticalSection(&m_critsec);
  3704. }
  3705. void RtrMgrProtocolInfo::ReviveStrongRef()
  3706. {
  3707. RtrCriticalSection rtrCritSec(&m_critsec);
  3708. if (m_pRtrMgrInfoParent)
  3709. {
  3710. CONVERT_TO_STRONGREF(m_pRtrMgrInfoParent);
  3711. }
  3712. }
  3713. void RtrMgrProtocolInfo::OnLastStrongRef()
  3714. {
  3715. RtrCriticalSection rtrCritSec(&m_critsec);
  3716. if (m_pRtrMgrInfoParent)
  3717. {
  3718. CONVERT_TO_WEAKREF(m_pRtrMgrInfoParent);
  3719. }
  3720. if (m_fDestruct)
  3721. Destruct();
  3722. }
  3723. STDMETHODIMP RtrMgrProtocolInfo::Destruct()
  3724. {
  3725. RtrCriticalSection rtrCritSec(&m_critsec);
  3726. IRtrMgrInfo * pParent;
  3727. m_fDestruct = TRUE;
  3728. if (!m_fStrongRef)
  3729. {
  3730. // Release the parent pointer
  3731. pParent = m_pRtrMgrInfoParent;
  3732. m_pRtrMgrInfoParent = NULL;
  3733. if (pParent)
  3734. pParent->ReleaseWeakRef();
  3735. // release any data
  3736. }
  3737. return hrOK;
  3738. }
  3739. STDMETHODIMP_(DWORD) RtrMgrProtocolInfo::GetFlags()
  3740. {
  3741. RtrCriticalSection rtrCritSec(&m_critsec);
  3742. return m_dwFlags;
  3743. }
  3744. STDMETHODIMP RtrMgrProtocolInfo::SetFlags(DWORD dwFlags)
  3745. {
  3746. RtrCriticalSection rtrCritSec(&m_critsec);
  3747. HRESULT hr = hrOK;
  3748. COM_PROTECT_TRY
  3749. {
  3750. m_dwFlags = dwFlags;
  3751. }
  3752. COM_PROTECT_CATCH;
  3753. return hr;
  3754. }
  3755. /*!--------------------------------------------------------------------------
  3756. RtrMgrProtocolInfo::GetProtocolId
  3757. -
  3758. Author: KennT
  3759. ---------------------------------------------------------------------------*/
  3760. STDMETHODIMP_(DWORD) RtrMgrProtocolInfo::GetProtocolId()
  3761. {
  3762. RtrCriticalSection rtrCritSec(&m_critsec);
  3763. return m_cb.dwProtocolId;
  3764. }
  3765. /*!--------------------------------------------------------------------------
  3766. RtrMgrProtocolInfo::GetTitle
  3767. -
  3768. Author: KennT
  3769. ---------------------------------------------------------------------------*/
  3770. STDMETHODIMP_(LPCOLESTR) RtrMgrProtocolInfo::GetTitle()
  3771. {
  3772. RtrCriticalSection rtrCritSec(&m_critsec);
  3773. //$UNICODE : kennt, assumes OLECHAR == WCHAR and that
  3774. // we are native UNICODE
  3775. return m_cb.stTitle;
  3776. }
  3777. /*!--------------------------------------------------------------------------
  3778. RtrMgrProtocolInfo::GetTransportId
  3779. -
  3780. Author: KennT
  3781. ---------------------------------------------------------------------------*/
  3782. STDMETHODIMP_(DWORD) RtrMgrProtocolInfo::GetTransportId()
  3783. {
  3784. RtrCriticalSection rtrCritSec(&m_critsec);
  3785. return m_cb.dwTransportId;
  3786. }
  3787. /*!--------------------------------------------------------------------------
  3788. RtrMgrProtocolInfo::CopyCB
  3789. -
  3790. Author: KennT
  3791. ---------------------------------------------------------------------------*/
  3792. STDMETHODIMP RtrMgrProtocolInfo::CopyCB(RtrMgrProtocolCB *pRmProtCB)
  3793. {
  3794. RtrCriticalSection rtrCritSec(&m_critsec);
  3795. HRESULT hr = hrOK;
  3796. COM_PROTECT_TRY
  3797. {
  3798. m_cb.SaveTo(pRmProtCB);
  3799. }
  3800. COM_PROTECT_CATCH;
  3801. return hr;
  3802. }
  3803. /*!--------------------------------------------------------------------------
  3804. RtrMgrProtocolInfo::SetCB
  3805. -
  3806. Author: KennT
  3807. ---------------------------------------------------------------------------*/
  3808. HRESULT RtrMgrProtocolInfo::SetCB(const RtrMgrProtocolCB *pcb)
  3809. {
  3810. RtrCriticalSection rtrCritSec(&m_critsec);
  3811. m_cb.LoadFrom(pcb);
  3812. return hrOK;
  3813. }
  3814. /*!--------------------------------------------------------------------------
  3815. RtrMgrProtocolInfo::GetParentRtrMgrInfo
  3816. -
  3817. Author: KennT
  3818. ---------------------------------------------------------------------------*/
  3819. STDMETHODIMP RtrMgrProtocolInfo::GetParentRtrMgrInfo(IRtrMgrInfo **ppParent)
  3820. {
  3821. RtrCriticalSection rtrCritSec(&m_critsec);
  3822. *ppParent = m_pRtrMgrInfoParent;
  3823. if (*ppParent)
  3824. (*ppParent)->AddRef();
  3825. return hrOK;
  3826. }
  3827. /*!--------------------------------------------------------------------------
  3828. RtrMgrProtocolInfo::SetParentRtrMgrInfo
  3829. -
  3830. Author: KennT
  3831. ---------------------------------------------------------------------------*/
  3832. STDMETHODIMP RtrMgrProtocolInfo::SetParentRtrMgrInfo(IRtrMgrInfo *pParent)
  3833. {
  3834. RtrCriticalSection rtrCritSec(&m_critsec);
  3835. IRtrMgrInfo * pTemp;
  3836. pTemp = m_pRtrMgrInfoParent;
  3837. m_pRtrMgrInfoParent = NULL;
  3838. if (m_fStrongRef)
  3839. {
  3840. if (pTemp)
  3841. pTemp->Release();
  3842. if (pParent)
  3843. pParent->AddRef();
  3844. }
  3845. else
  3846. {
  3847. if (pTemp)
  3848. pTemp->ReleaseWeakRef();
  3849. if (pParent)
  3850. pParent->AddWeakRef();
  3851. }
  3852. m_pRtrMgrInfoParent = pParent;
  3853. return hrOK;
  3854. }
  3855. /*!--------------------------------------------------------------------------
  3856. RtrMgrProtocolInfo::RtrAdvise
  3857. -
  3858. Author: KennT
  3859. ---------------------------------------------------------------------------*/
  3860. STDMETHODIMP RtrMgrProtocolInfo::RtrAdvise(IRtrAdviseSink *pRtrAdviseSink,
  3861. LONG_PTR *pulConnection,
  3862. LPARAM lUserParam)
  3863. {
  3864. Assert(pRtrAdviseSink);
  3865. Assert(pulConnection);
  3866. RtrCriticalSection rtrCritSec(&m_critsec);
  3867. LONG_PTR ulConnId;
  3868. HRESULT hr = hrOK;
  3869. COM_PROTECT_TRY
  3870. {
  3871. ulConnId = (LONG_PTR) InterlockedIncrement(&s_cConnections);
  3872. CORg( m_AdviseList.AddConnection(pRtrAdviseSink, ulConnId, lUserParam) );
  3873. *pulConnection = ulConnId;
  3874. COM_PROTECT_ERROR_LABEL;
  3875. }
  3876. COM_PROTECT_CATCH;
  3877. return hr;
  3878. }
  3879. /*!--------------------------------------------------------------------------
  3880. RtrMgrProtocolInfo::RtrNotify
  3881. -
  3882. Author: KennT
  3883. ---------------------------------------------------------------------------*/
  3884. STDMETHODIMP RtrMgrProtocolInfo::RtrNotify(DWORD dwChangeType, DWORD dwObjectType,
  3885. LPARAM lParam)
  3886. {
  3887. RtrCriticalSection rtrCritSec(&m_critsec);
  3888. HRESULT hr = hrOK;
  3889. COM_PROTECT_TRY
  3890. {
  3891. m_AdviseList.NotifyChange(dwChangeType, dwObjectType, lParam);
  3892. }
  3893. COM_PROTECT_CATCH;
  3894. return hr;
  3895. }
  3896. /*!--------------------------------------------------------------------------
  3897. RtrMgrProtocolInfo::RtrUnadvise
  3898. -
  3899. Author: KennT
  3900. ---------------------------------------------------------------------------*/
  3901. STDMETHODIMP RtrMgrProtocolInfo::RtrUnadvise(LONG_PTR ulConnection)
  3902. {
  3903. RtrCriticalSection rtrCritSec(&m_critsec);
  3904. return m_AdviseList.RemoveConnection(ulConnection);
  3905. }
  3906. /*!--------------------------------------------------------------------------
  3907. RtrMgrProtocolInfo::Disconnect
  3908. -
  3909. Author: KennT
  3910. ---------------------------------------------------------------------------*/
  3911. void RtrMgrProtocolInfo::Disconnect()
  3912. {
  3913. }
  3914. /*!--------------------------------------------------------------------------
  3915. RtrMgrProtocolInfo::DoDisconnect
  3916. Implementation of IRtrMgrProtocolInfo::DoDisconnect
  3917. Author: KennT
  3918. ---------------------------------------------------------------------------*/
  3919. STDMETHODIMP RtrMgrProtocolInfo::DoDisconnect()
  3920. {
  3921. HRESULT hr = hrOK;
  3922. COM_PROTECT_TRY
  3923. {
  3924. // Disconnect our data.
  3925. // ------------------------------------------------------------
  3926. Disconnect();
  3927. // Notify the advise sinks of a disconnect.
  3928. // ------------------------------------------------------------
  3929. RtrNotify(ROUTER_DO_DISCONNECT, 0, 0);
  3930. }
  3931. COM_PROTECT_CATCH;
  3932. return hr;
  3933. }
  3934. /*---------------------------------------------------------------------------
  3935. InterfaceInfo Implementation
  3936. ---------------------------------------------------------------------------*/
  3937. TFSCORE_API(HRESULT) CreateInterfaceInfo(IInterfaceInfo **ppInterfaceInfo,
  3938. LPCWSTR pswzInterfaceId,
  3939. DWORD dwInterfaceType)
  3940. {
  3941. Assert(ppInterfaceInfo);
  3942. HRESULT hr = hrOK;
  3943. InterfaceInfo * pInterfaceInfo = NULL;
  3944. USES_CONVERSION;
  3945. COM_PROTECT_TRY
  3946. {
  3947. pInterfaceInfo = new InterfaceInfo(W2CT(pswzInterfaceId),
  3948. dwInterfaceType,
  3949. TRUE,
  3950. InterfaceCB_BindToIp | InterfaceCB_BindToIpx,
  3951. NULL);
  3952. *ppInterfaceInfo = pInterfaceInfo;
  3953. }
  3954. COM_PROTECT_CATCH;
  3955. return hr;
  3956. }
  3957. IMPLEMENT_WEAKREF_ADDREF_RELEASE(InterfaceInfo)
  3958. IMPLEMENT_SIMPLE_QUERYINTERFACE(InterfaceInfo, IInterfaceInfo)
  3959. DEBUG_DECLARE_INSTANCE_COUNTER(InterfaceInfo)
  3960. InterfaceInfo::InterfaceInfo(LPCTSTR pszId,
  3961. DWORD dwIfType,
  3962. BOOL bEnable,
  3963. DWORD dwBindFlags,
  3964. RouterInfo *pRouterInfo)
  3965. : m_hMachineConfig(NULL),
  3966. m_hInterface(NULL),
  3967. m_bDisconnect(FALSE),
  3968. m_dwFlags(0)
  3969. {
  3970. DEBUG_INCREMENT_INSTANCE_COUNTER(InterfaceInfo);
  3971. m_cb.stId = pszId;
  3972. m_cb.dwIfType = dwIfType;
  3973. m_cb.bEnable = bEnable;
  3974. m_cb.dwBindFlags = dwBindFlags;
  3975. m_pRouterInfoParent = pRouterInfo;
  3976. if (m_pRouterInfoParent)
  3977. m_pRouterInfoParent->AddRef();
  3978. InitializeCriticalSection(&m_critsec);
  3979. }
  3980. InterfaceInfo::~InterfaceInfo()
  3981. {
  3982. Assert(m_pRouterInfoParent == NULL);
  3983. Destruct();
  3984. DEBUG_DECREMENT_INSTANCE_COUNTER(InterfaceInfo);
  3985. DeleteCriticalSection(&m_critsec);
  3986. }
  3987. void InterfaceInfo::ReviveStrongRef()
  3988. {
  3989. RtrCriticalSection rtrCritSec(&m_critsec);
  3990. if (m_pRouterInfoParent)
  3991. {
  3992. CONVERT_TO_STRONGREF(m_pRouterInfoParent);
  3993. }
  3994. }
  3995. void InterfaceInfo::OnLastStrongRef()
  3996. {
  3997. RtrCriticalSection rtrCritSec(&m_critsec);
  3998. if (m_pRouterInfoParent)
  3999. {
  4000. CONVERT_TO_WEAKREF(m_pRouterInfoParent);
  4001. }
  4002. if (m_fDestruct)
  4003. Destruct();
  4004. }
  4005. STDMETHODIMP InterfaceInfo::Destruct()
  4006. {
  4007. RtrCriticalSection rtrCritSec(&m_critsec);
  4008. IRouterInfo * pParent;
  4009. m_fDestruct = TRUE;
  4010. if (!m_fStrongRef)
  4011. {
  4012. pParent = m_pRouterInfoParent;
  4013. m_pRouterInfoParent = NULL;
  4014. if (pParent)
  4015. pParent->ReleaseWeakRef();
  4016. // release any data
  4017. Unload();
  4018. }
  4019. return hrOK;
  4020. }
  4021. STDMETHODIMP_(DWORD) InterfaceInfo::GetFlags()
  4022. {
  4023. RtrCriticalSection rtrCritSec(&m_critsec);
  4024. return m_dwFlags;
  4025. }
  4026. STDMETHODIMP InterfaceInfo::SetFlags(DWORD dwFlags)
  4027. {
  4028. RtrCriticalSection rtrCritSec(&m_critsec);
  4029. HRESULT hr = hrOK;
  4030. COM_PROTECT_TRY
  4031. {
  4032. m_dwFlags = dwFlags;
  4033. }
  4034. COM_PROTECT_CATCH;
  4035. return hr;
  4036. }
  4037. /*!--------------------------------------------------------------------------
  4038. InterfaceInfo::Load
  4039. -
  4040. Author: KennT
  4041. ---------------------------------------------------------------------------*/
  4042. STDMETHODIMP InterfaceInfo::Load(LPCOLESTR pszMachine,
  4043. HANDLE hMachine,
  4044. HANDLE hInterface)
  4045. {
  4046. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  4047. RtrCriticalSection rtrCritSec(&m_critsec);
  4048. HRESULT hr = hrOK;
  4049. DWORD dwSize = 0;
  4050. MPR_INTERFACE_0 *pinterface = NULL;
  4051. SPIEnumInterfaceCB spEnumInterfaceCB;
  4052. InterfaceCB ifCB;
  4053. SPSZ spszTitle;
  4054. CString stTitle;
  4055. DWORD dwIfType;
  4056. BOOL bFound = FALSE;
  4057. COM_PROTECT_TRY
  4058. {
  4059. //
  4060. // Discard any existing information
  4061. //
  4062. Unload();
  4063. m_stMachine = OLE2CT(pszMachine ? pszMachine : TEXT(""));
  4064. //
  4065. // If 'hMachine' was not specified, connect to the config
  4066. // on the specified machine
  4067. //
  4068. Assert(m_hMachineConfig == NULL);
  4069. CORg( TryToConnect(OLE2CW(pszMachine), &hMachine) );
  4070. //
  4071. // If 'hInterface' was not specified, connect to the interface
  4072. //
  4073. CORg( TryToGetIfHandle(hMachine, OLE2CW(GetId()), &hInterface) );
  4074. //
  4075. // Get information for the interface
  4076. //
  4077. CWRg( ::MprConfigInterfaceGetInfo(
  4078. hMachine,
  4079. hInterface,
  4080. 0,
  4081. (LPBYTE*)&pinterface,
  4082. &dwSize
  4083. ) );
  4084. // Windows NT Bug ?
  4085. // If this interface is a removed adapter, do not show it.
  4086. // This check needs to be made only for MprConfigInterfacEnum
  4087. // ------------------------------------------------------------
  4088. if ((pinterface->dwConnectionState == ROUTER_IF_STATE_UNREACHABLE) &&
  4089. (pinterface->fUnReachabilityReasons == MPR_INTERFACE_NO_DEVICE))
  4090. {
  4091. CORg( E_INVALIDARG );
  4092. }
  4093. //
  4094. // Save the interface type and enabled/disabled status
  4095. //
  4096. m_cb.dwIfType = (DWORD)pinterface->dwIfType;
  4097. m_cb.bEnable = pinterface->fEnabled;
  4098. ::MprConfigBufferFree(pinterface);
  4099. if (m_pRouterInfoParent)
  4100. {
  4101. //
  4102. // The caller has supplied a list of LAN adapters ('pifcbList'),
  4103. // or this object is contained in a 'CRouterInfo' which will have
  4104. // already loaded the LAN interface control-blocks;
  4105. // search through the list to find our title,
  4106. //
  4107. m_pRouterInfoParent->EnumInterfaceCB(&spEnumInterfaceCB);
  4108. spEnumInterfaceCB->Reset();
  4109. while (spEnumInterfaceCB->Next(1, &ifCB, NULL) == hrOK)
  4110. {
  4111. if (StriCmp(ifCB.szId, OLE2CT(GetId())) == 0)
  4112. {
  4113. m_cb.stTitle = ifCB.szTitle;
  4114. m_cb.stDeviceName = ifCB.szDevice;
  4115. bFound = TRUE;
  4116. break;
  4117. }
  4118. else
  4119. {
  4120. // Windows NT bug 103770
  4121. // Need to check to see if the pcb->sID is a prefix
  4122. // of the Id string (if so it may be the IPX case
  4123. // so use that ID).
  4124. stTitle = GetId();
  4125. if (stTitle.Find((LPCTSTR) ifCB.szId) == 0)
  4126. {
  4127. // Need to check to see that the extension
  4128. // is what we think it is.
  4129. LPCTSTR pszExt = ((LPCTSTR) stTitle +
  4130. lstrlen(ifCB.szId));
  4131. if ((*pszExt == 0) ||
  4132. (lstrcmpi(pszExt, c_szEthernetSNAP) == 0) ||
  4133. (lstrcmpi(pszExt, c_szEthernetII) == 0) ||
  4134. (lstrcmpi(pszExt, c_szEthernet8022) == 0) ||
  4135. (lstrcmpi(pszExt, c_szEthernet8023) == 0))
  4136. {
  4137. m_cb.stTitle = ifCB.szTitle;
  4138. m_cb.stTitle += _T(" (");
  4139. m_cb.stTitle += pszExt + 1; // add 1 to skip over /
  4140. m_cb.stTitle += _T(")");
  4141. bFound = TRUE;
  4142. break;
  4143. }
  4144. }
  4145. }
  4146. }
  4147. }
  4148. if (!bFound)
  4149. {
  4150. //
  4151. // Read the title directly from the registry
  4152. //
  4153. hr = InterfaceInfo::FindInterfaceTitle(OLE2CT(GetMachineName()),
  4154. OLE2CT(GetId()),
  4155. &spszTitle);
  4156. if (FHrOK(hr))
  4157. m_cb.stTitle = spszTitle;
  4158. else
  4159. m_cb.stTitle = OLE2CT(GetId());
  4160. hr = hrOK;
  4161. }
  4162. //
  4163. // Load the list of router-managers on this interface
  4164. //
  4165. CORg( LoadRtrMgrInterfaceList() );
  4166. COM_PROTECT_ERROR_LABEL;
  4167. }
  4168. COM_PROTECT_CATCH;
  4169. if (!FHrSucceeded(hr))
  4170. Unload();
  4171. return hr;
  4172. }
  4173. /*!--------------------------------------------------------------------------
  4174. InterfaceInfo::Save
  4175. -
  4176. Saves the changes to a CInterfaceInfo to the registry.
  4177. Author: KennT
  4178. ---------------------------------------------------------------------------*/
  4179. STDMETHODIMP InterfaceInfo::Save(LPCOLESTR pszMachine,
  4180. HANDLE hMachine,
  4181. HANDLE hInterface)
  4182. {
  4183. RtrCriticalSection rtrCritSec(&m_critsec);
  4184. HRESULT hr = hrOK;
  4185. DWORD dwErr;
  4186. MPR_INTERFACE_0 mprInterface;
  4187. WCHAR wszInterface[MAX_INTERFACE_NAME_LEN+1];
  4188. MPR_SERVER_HANDLE hrouter = NULL;
  4189. MPR_IPINIP_INTERFACE_0 mprTunnelInterface;
  4190. BOOL fIpInIpMapping = FALSE;
  4191. COM_PROTECT_TRY
  4192. {
  4193. //
  4194. // If already connected, the handle passed in is ignored;
  4195. //
  4196. // Otherwise, if 'hMachine' was not specified, connect to the config
  4197. // on the specified machine
  4198. //
  4199. CORg( TryToConnect(OLE2CW(pszMachine), &hMachine) );
  4200. //
  4201. // Convert the interface name to Unicode
  4202. //
  4203. StrCpyWFromOle(wszInterface, GetId());
  4204. ZeroMemory(&mprInterface, sizeof(mprInterface));
  4205. StrCpyW(mprInterface.wszInterfaceName, wszInterface);
  4206. mprInterface.dwIfType = (ROUTER_INTERFACE_TYPE) GetInterfaceType();
  4207. mprInterface.fEnabled = IsInterfaceEnabled();
  4208. //
  4209. // If already connected, use the existing interface-handle.
  4210. //
  4211. // Otherwise, if the interface-handle wasn't passed in,
  4212. // try to get a handle to the interface; if that fails,
  4213. // create the interface.
  4214. //
  4215. hr = TryToGetIfHandle(hMachine, wszInterface, &hInterface);
  4216. if (!FHrSucceeded(hr))
  4217. {
  4218. if (GetInterfaceType() == ROUTER_IF_TYPE_TUNNEL1)
  4219. {
  4220. //
  4221. // If we are creating a tunnel, we need to register
  4222. // the GUID-to-friendly name mapping.
  4223. //
  4224. ::ZeroMemory(&mprTunnelInterface,
  4225. sizeof(mprTunnelInterface));
  4226. StrnCpyW(mprTunnelInterface.wszFriendlyName,
  4227. GetTitle(),
  4228. MAX_INTERFACE_NAME_LEN);
  4229. CORg( CLSIDFromString(wszInterface,
  4230. &(mprTunnelInterface.Guid)) );
  4231. CWRg( MprSetupIpInIpInterfaceFriendlyNameCreate(
  4232. (LPOLESTR) GetMachineName(),
  4233. &mprTunnelInterface
  4234. ) );
  4235. // The mapping was created.
  4236. // If we get an error, we need to delete the mapping.
  4237. fIpInIpMapping = TRUE;
  4238. }
  4239. //
  4240. // We couldn't get a handle to the interface,
  4241. // so now attempt to create it.
  4242. //
  4243. CWRg( ::MprConfigInterfaceCreate(
  4244. hMachine,
  4245. 0,
  4246. (LPBYTE)&mprInterface,
  4247. &hInterface
  4248. ) );
  4249. m_hInterface = hInterface;
  4250. }
  4251. //
  4252. // Save the current settings for the interface.
  4253. //
  4254. CWRg( ::MprConfigInterfaceSetInfo(
  4255. hMachine,
  4256. hInterface,
  4257. 0,
  4258. (LPBYTE)&mprInterface
  4259. ) );
  4260. //
  4261. // Now notify the router-service of the new interface
  4262. //
  4263. //
  4264. // Attempt to connect to the router-service
  4265. //
  4266. //$ Review: kennt, what happens if the call to ConnectRouter()
  4267. // fails, we don't have an error code
  4268. if (ConnectRouter(OLE2CT(GetMachineName()), (HANDLE*)&hrouter) == NO_ERROR)
  4269. {
  4270. //
  4271. // The router is running; attempt to get a handle to the interface
  4272. //
  4273. dwErr = ::MprAdminInterfaceGetHandle(hrouter,
  4274. wszInterface,
  4275. &hInterface,
  4276. FALSE
  4277. );
  4278. if (dwErr != NO_ERROR)
  4279. {
  4280. //
  4281. // We couldn't get a handle to the interface,
  4282. // so try creating it.
  4283. //
  4284. dwErr = ::MprAdminInterfaceCreate(
  4285. hrouter,
  4286. 0,
  4287. (BYTE*)&mprInterface,
  4288. &hInterface
  4289. );
  4290. }
  4291. else
  4292. {
  4293. //
  4294. // Save the current settings for the interface.
  4295. //
  4296. dwErr = ::MprAdminInterfaceSetInfo(hrouter,
  4297. hInterface,
  4298. 0,
  4299. (LPBYTE)&mprInterface
  4300. );
  4301. }
  4302. ::MprAdminServerDisconnect(hrouter);
  4303. if ((dwErr == RPC_S_SERVER_UNAVAILABLE) ||
  4304. (dwErr == RPC_S_UNKNOWN_IF))
  4305. dwErr = NO_ERROR;
  4306. if (dwErr != NO_ERROR)
  4307. hr = HRESULT_FROM_WIN32(dwErr);
  4308. }
  4309. COM_PROTECT_ERROR_LABEL;
  4310. }
  4311. COM_PROTECT_CATCH;
  4312. if (!FHrSucceeded(hr) && fIpInIpMapping)
  4313. {
  4314. // Assume : that the the mprTunnelInterface.Guid was
  4315. // initialized, since to reach there they would have had
  4316. // to gone through the CLSIDFromString() call.
  4317. MprSetupIpInIpInterfaceFriendlyNameDelete((LPOLESTR) GetMachineName(),
  4318. &(mprTunnelInterface.Guid)
  4319. );
  4320. }
  4321. return hr;
  4322. }
  4323. /*!--------------------------------------------------------------------------
  4324. InterfaceInfo::Delete
  4325. -
  4326. Author: KennT
  4327. ---------------------------------------------------------------------------*/
  4328. STDMETHODIMP InterfaceInfo::Delete(LPCOLESTR pszMachine,
  4329. HANDLE hMachine)
  4330. {
  4331. RtrCriticalSection rtrCritSec(&m_critsec);
  4332. HRESULT hr = hrOK;
  4333. DWORD dwErr;
  4334. HANDLE hInterface;
  4335. WCHAR wszInterface[MAX_INTERFACE_NAME_LEN+1];
  4336. MPR_SERVER_HANDLE hrouter = NULL;
  4337. GUID guidTunnel;
  4338. COM_PROTECT_TRY
  4339. {
  4340. // If already connected, the handle passed in is ignored;
  4341. //
  4342. // Otherwise, if 'hMachine' was not specified, connect to the config
  4343. // on the specified machine
  4344. // ------------------------------------------------------------
  4345. CORg( TryToConnect(OLE2CW(pszMachine), &hMachine) );
  4346. StrCpyWFromOle(wszInterface, GetId());
  4347. // Try to get a handle to the interface
  4348. // ------------------------------------------------------------
  4349. CWRg( ::MprConfigInterfaceGetHandle(hMachine,
  4350. wszInterface,
  4351. &hInterface
  4352. ) );
  4353. // Delete the interface
  4354. // ------------------------------------------------------------
  4355. dwErr = ::MprConfigInterfaceDelete(
  4356. hMachine, hInterface
  4357. );
  4358. m_hInterface = NULL;
  4359. CWRg( dwErr );
  4360. // If this interface is a tunnel, we need to remove the
  4361. // GUID-to-Friendly name mapping
  4362. // ------------------------------------------------------------
  4363. if (GetInterfaceType() == ROUTER_IF_TYPE_TUNNEL1)
  4364. {
  4365. if (FHrOK(CLSIDFromString((LPTSTR) GetId(),
  4366. &guidTunnel)))
  4367. {
  4368. // If this call fails, we can't do anything about it
  4369. // ----------------------------------------------------
  4370. MprSetupIpInIpInterfaceFriendlyNameDelete((LPTSTR) pszMachine,
  4371. &guidTunnel);
  4372. }
  4373. }
  4374. // Remove the interface from the router if it is running
  4375. // ------------------------------------------------------------
  4376. if (ConnectRouter(OLE2CT(GetMachineName()), (HANDLE*)&hrouter) == NO_ERROR)
  4377. {
  4378. // The router is running; get a handle to the interface
  4379. // --------------------------------------------------------
  4380. dwErr = ::MprAdminInterfaceGetHandle(
  4381. hrouter,
  4382. wszInterface,
  4383. &hInterface,
  4384. FALSE
  4385. );
  4386. if (dwErr == NO_ERROR)
  4387. {
  4388. // Delete the interface
  4389. // ----------------------------------------------------
  4390. dwErr = ::MprAdminInterfaceDelete(
  4391. hrouter,
  4392. hInterface
  4393. );
  4394. }
  4395. ::MprAdminServerDisconnect(hrouter);
  4396. if ((dwErr == RPC_S_SERVER_UNAVAILABLE) ||
  4397. (dwErr == RPC_S_UNKNOWN_IF))
  4398. dwErr = NO_ERROR;
  4399. hr = HRESULT_FROM_WIN32(dwErr);
  4400. }
  4401. // Windows NT Bug: 138738
  4402. // Need to remove the interface from the router managers
  4403. // when deleting the interface.
  4404. // ------------------------------------------------------------
  4405. // Clear out all information for this interface
  4406. // ------------------------------------------------------------
  4407. if (FHrSucceeded(hr))
  4408. {
  4409. SPIEnumRtrMgrInterfaceInfo spEnumRmIf;
  4410. SPIRtrMgrInterfaceInfo spRmIf;
  4411. // Remove the Router Managers from this interface
  4412. // --------------------------------------------------------
  4413. EnumRtrMgrInterface(&spEnumRmIf);
  4414. while (spEnumRmIf->Next(1, &spRmIf, NULL) == hrOK)
  4415. {
  4416. DWORD dwTransportId = spRmIf->GetTransportId();
  4417. spRmIf.Release();
  4418. DeleteRtrMgrInterface(dwTransportId, TRUE);
  4419. }
  4420. }
  4421. COM_PROTECT_ERROR_LABEL;
  4422. }
  4423. COM_PROTECT_CATCH;
  4424. return hr;
  4425. }
  4426. /*!--------------------------------------------------------------------------
  4427. InterfaceInfo::Unload
  4428. -
  4429. Author: KennT
  4430. ---------------------------------------------------------------------------*/
  4431. STDMETHODIMP InterfaceInfo::Unload( )
  4432. {
  4433. RtrCriticalSection rtrCritSec(&m_critsec);
  4434. HRESULT hr = hrOK;
  4435. IRtrMgrInterfaceInfo * pRmIf;
  4436. COM_PROTECT_TRY
  4437. {
  4438. //
  4439. // Free all the contained router-manager structures in our list
  4440. //
  4441. while (!m_RmIfList.IsEmpty())
  4442. {
  4443. pRmIf = m_RmIfList.RemoveHead();
  4444. pRmIf->Destruct();
  4445. pRmIf->ReleaseWeakRef();
  4446. }
  4447. DoDisconnect();
  4448. }
  4449. COM_PROTECT_CATCH;
  4450. return hr;
  4451. }
  4452. /*!--------------------------------------------------------------------------
  4453. InterfaceInfo::Merge
  4454. -
  4455. Author: KennT
  4456. ---------------------------------------------------------------------------*/
  4457. STDMETHODIMP InterfaceInfo::Merge(IInterfaceInfo *pNewIf)
  4458. {
  4459. RtrCriticalSection rtrCritSec(&m_critsec);
  4460. HRESULT hr = hrOK;
  4461. HRESULT hrT;
  4462. SPIEnumRtrMgrInterfaceInfo spEnumRmIf;
  4463. SPIRtrMgrInterfaceInfo spRmIf;
  4464. SPIRtrMgrInfo spRm;
  4465. SPIRtrMgrProtocolInfo spRmProt;
  4466. SPIRtrMgrProtocolInterfaceInfo spRmProtIf;
  4467. SPIEnumRtrMgrProtocolInterfaceInfo spEnumRmProtIf;
  4468. CDWordArray oldDWArray;
  4469. CDWordArray newDWArray;
  4470. int cOld, cNew;
  4471. int i, j;
  4472. DWORD dwTemp;
  4473. InterfaceCB ifCB;
  4474. Assert(pNewIf);
  4475. Assert(lstrcmpi(pNewIf->GetId(), GetId()) == 0);
  4476. COM_PROTECT_TRY
  4477. {
  4478. // Need to sync up the interface CB Data
  4479. pNewIf->CopyCB(&ifCB);
  4480. m_cb.LoadFrom(&ifCB);
  4481. // Need to sync up the RtrMgrInterface list
  4482. // They are identified by transport ids, so we can
  4483. // use the two array method used by
  4484. // IRtrMgrInterfaceInfo::Merge
  4485. // Get the list of RtrMgrs that are in the new object
  4486. CORg( pNewIf->EnumRtrMgrInterface(&spEnumRmIf) );
  4487. spEnumRmIf->Reset();
  4488. while (spEnumRmIf->Next(1, &spRmIf, NULL) == hrOK)
  4489. {
  4490. newDWArray.Add(spRmIf->GetTransportId());
  4491. spRmIf.Release();
  4492. }
  4493. spEnumRmIf.Release();
  4494. spRmIf.Release();
  4495. // Get the list of interfaces that are in this object
  4496. CORg( this->EnumRtrMgrInterface(&spEnumRmIf) );
  4497. spEnumRmIf->Reset();
  4498. while (spEnumRmIf->Next(1, &spRmIf, NULL) == hrOK)
  4499. {
  4500. oldDWArray.Add(spRmIf->GetTransportId());
  4501. spRmIf.Release();
  4502. }
  4503. spEnumRmIf.Release();
  4504. spRmIf.Release();
  4505. // Ok now go through both lists, removing from the lists
  4506. // interfaces that are in both lists.
  4507. cOld = oldDWArray.GetSize();
  4508. cNew = newDWArray.GetSize();
  4509. for (i=cOld; --i>=0; )
  4510. {
  4511. dwTemp = oldDWArray.GetAt(i);
  4512. for (j=cNew; --j>=0; )
  4513. {
  4514. if (dwTemp == newDWArray.GetAt(j))
  4515. {
  4516. SPIRtrMgrInterfaceInfo spRmIf1;
  4517. SPIRtrMgrInterfaceInfo spRmIf2;
  4518. this->FindRtrMgrInterface(dwTemp, &spRmIf1);
  4519. pNewIf->FindRtrMgrInterface(dwTemp, &spRmIf2);
  4520. Assert(spRmIf1);
  4521. Assert(spRmIf2);
  4522. spRmIf1->Merge(spRmIf2);
  4523. // remove both instances
  4524. newDWArray.RemoveAt(j);
  4525. oldDWArray.RemoveAt(i);
  4526. // Need to update the size of the new array
  4527. cNew--;
  4528. break;
  4529. }
  4530. }
  4531. }
  4532. // oldDWArray now contains the interfaces that should be
  4533. // removed.
  4534. if (oldDWArray.GetSize())
  4535. {
  4536. for (i=oldDWArray.GetSize(); --i>=0; )
  4537. {
  4538. // Windows NT Bug: 132993, if this interface
  4539. // is one that is purely local (mostly because
  4540. // it is a new interface), then we should not
  4541. // delete it.
  4542. SPIRtrMgrInterfaceInfo spRmIfTemp;
  4543. FindRtrMgrInterface(oldDWArray.GetAt(i),
  4544. &spRmIfTemp);
  4545. Assert(spRmIfTemp);
  4546. if (spRmIfTemp->GetFlags() & RouterSnapin_InSyncWithRouter)
  4547. DeleteRtrMgrInterface(oldDWArray.GetAt(i), FALSE);
  4548. }
  4549. }
  4550. // newDWArray contains the interfaces that should be added
  4551. if (newDWArray.GetSize())
  4552. {
  4553. for (i=newDWArray.GetSize(); --i>= 0; )
  4554. {
  4555. hr = pNewIf->FindRtrMgrInterface(
  4556. newDWArray.GetAt(i), &spRmIf);
  4557. Assert(hr == hrOK);
  4558. if (spRmIf)
  4559. {
  4560. AddRtrMgrInterface(spRmIf, NULL);
  4561. // Remove this rmif from its old interface
  4562. // ------------------------------------------------
  4563. pNewIf->ReleaseRtrMgrInterface(spRmIf->GetTransportId());
  4564. // We need to do the notify ourselves (because
  4565. // of the NULL infobase) the notifications won't
  4566. // get sent.
  4567. spRmIf->RtrNotify(ROUTER_CHILD_ADD, ROUTER_OBJ_RmIf, 0);
  4568. if (m_pRouterInfoParent)
  4569. {
  4570. spRm.Release();
  4571. hrT = m_pRouterInfoParent->FindRtrMgr(spRmIf->GetTransportId(), &spRm);
  4572. if (FHrOK(hrT))
  4573. {
  4574. spRm->RtrNotify(ROUTER_CHILD_ADD, ROUTER_OBJ_RmIf, 0);
  4575. // In addition, we will have to let the objects
  4576. // know that the interfaces are also being added
  4577. spEnumRmProtIf.Release();
  4578. spRmProtIf.Release();
  4579. spRmIf->EnumRtrMgrProtocolInterface(&spEnumRmProtIf);
  4580. for(; spEnumRmProtIf->Next(1, &spRmProtIf, NULL) == hrOK; spRmProtIf.Release())
  4581. {
  4582. spRmProt.Release();
  4583. spRm->FindRtrMgrProtocol(spRmProtIf->GetProtocolId(),
  4584. &spRmProt);
  4585. if (spRmProt)
  4586. spRmProt->RtrNotify(ROUTER_CHILD_ADD, ROUTER_OBJ_RmProtIf, 0);
  4587. }
  4588. }
  4589. }
  4590. }
  4591. spRmIf.Release();
  4592. }
  4593. }
  4594. COM_PROTECT_ERROR_LABEL;
  4595. }
  4596. COM_PROTECT_CATCH;
  4597. return hr;
  4598. }
  4599. /*!--------------------------------------------------------------------------
  4600. InterfaceInfo::GetId
  4601. -
  4602. Author: KennT
  4603. ---------------------------------------------------------------------------*/
  4604. STDMETHODIMP_(LPCOLESTR) InterfaceInfo::GetId()
  4605. {
  4606. RtrCriticalSection rtrCritSec(&m_critsec);
  4607. //$UNICODE : kennt, assumes native unicode and OLECHAR==WCHAR
  4608. return m_cb.stId;
  4609. }
  4610. /*!--------------------------------------------------------------------------
  4611. InterfaceInfo::GetInterfaceType
  4612. -
  4613. Author: KennT
  4614. ---------------------------------------------------------------------------*/
  4615. STDMETHODIMP_(DWORD) InterfaceInfo::GetInterfaceType()
  4616. {
  4617. RtrCriticalSection rtrCritSec(&m_critsec);
  4618. return m_cb.dwIfType;
  4619. }
  4620. /*!--------------------------------------------------------------------------
  4621. InterfaceInfo::GetDeviceName
  4622. -
  4623. Author: KennT
  4624. ---------------------------------------------------------------------------*/
  4625. STDMETHODIMP_(LPCOLESTR) InterfaceInfo::GetDeviceName()
  4626. {
  4627. RtrCriticalSection rtrCritSec(&m_critsec);
  4628. return m_cb.stDeviceName;
  4629. }
  4630. /*!--------------------------------------------------------------------------
  4631. InterfaceInfo::GetTitle
  4632. -
  4633. Author: KennT
  4634. ---------------------------------------------------------------------------*/
  4635. STDMETHODIMP_(LPCOLESTR) InterfaceInfo::GetTitle()
  4636. {
  4637. RtrCriticalSection rtrCritSec(&m_critsec);
  4638. //$UNICODE : kennt, assumes native unicode and OLECHAR==WCHAR
  4639. return m_cb.stTitle;
  4640. }
  4641. /*!--------------------------------------------------------------------------
  4642. InterfaceInfo::SetTitle
  4643. -
  4644. Author: KennT
  4645. ---------------------------------------------------------------------------*/
  4646. STDMETHODIMP InterfaceInfo::SetTitle(LPCOLESTR pszTitle)
  4647. {
  4648. RtrCriticalSection rtrCritSec(&m_critsec);
  4649. HRESULT hr = hrOK;
  4650. COM_PROTECT_TRY
  4651. {
  4652. m_cb.stTitle = pszTitle;
  4653. }
  4654. COM_PROTECT_CATCH;
  4655. return hr;
  4656. }
  4657. /*!--------------------------------------------------------------------------
  4658. InterfaceInfo::IsInterfaceEnabled
  4659. -
  4660. Author: KennT
  4661. ---------------------------------------------------------------------------*/
  4662. STDMETHODIMP_(BOOL) InterfaceInfo::IsInterfaceEnabled()
  4663. {
  4664. RtrCriticalSection rtrCritSec(&m_critsec);
  4665. return m_cb.bEnable;
  4666. }
  4667. /*!--------------------------------------------------------------------------
  4668. InterfaceInfo::SetInterfaceEnabledState
  4669. -
  4670. Author: KennT
  4671. ---------------------------------------------------------------------------*/
  4672. STDMETHODIMP InterfaceInfo::SetInterfaceEnabledState( BOOL bEnabled)
  4673. {
  4674. RtrCriticalSection rtrCritSec(&m_critsec);
  4675. m_cb.bEnable = bEnabled;
  4676. return hrOK;
  4677. }
  4678. /*!--------------------------------------------------------------------------
  4679. InterfaceInfo::CopyCB
  4680. -
  4681. Author: KennT
  4682. ---------------------------------------------------------------------------*/
  4683. STDMETHODIMP InterfaceInfo::CopyCB(InterfaceCB *pifcb)
  4684. {
  4685. RtrCriticalSection rtrCritSec(&m_critsec);
  4686. HRESULT hr = hrOK;
  4687. COM_PROTECT_TRY
  4688. {
  4689. m_cb.SaveTo(pifcb);
  4690. }
  4691. COM_PROTECT_CATCH;
  4692. return hr;
  4693. }
  4694. /*!--------------------------------------------------------------------------
  4695. InterfaceInfo::FindInterfaceTitle
  4696. -
  4697. This function retrieves the title of the given interface.
  4698. The argument 'LpszIf' should contain the ID of the interface,
  4699. for instance "EPRO1".
  4700. Author: WeiJiang
  4701. ---------------------------------------------------------------------------*/
  4702. HRESULT InterfaceInfo::FindInterfaceTitle(LPCTSTR pszMachine,
  4703. LPCTSTR pszInterface,
  4704. LPTSTR *ppszTitle)
  4705. {
  4706. HRESULT hr = hrOK;
  4707. DWORD dwErr = ERROR_SUCCESS;
  4708. HKEY hkeyMachine = NULL;
  4709. BOOL fNT4;
  4710. COM_PROTECT_TRY
  4711. {
  4712. //
  4713. // connect to the registry
  4714. //
  4715. CWRg( ConnectRegistry(pszMachine, &hkeyMachine) );
  4716. CWRg( IsNT4Machine(hkeyMachine, &fNT4) );
  4717. if (hkeyMachine)
  4718. DisconnectRegistry(hkeyMachine);
  4719. if(fNT4)
  4720. hr = RegFindInterfaceTitle(pszMachine, pszInterface, ppszTitle);
  4721. else
  4722. {
  4723. //$NT5
  4724. SPMprConfigHandle sphConfig;
  4725. LPWSTR pswz;
  4726. CString stMachineName = pszMachine;
  4727. TCHAR szDesc[1024];
  4728. if (stMachineName.IsEmpty())
  4729. pswz = NULL;
  4730. else
  4731. pswz = (LPTSTR) (LPCTSTR) stMachineName;
  4732. dwErr = ::MprConfigServerConnect(pswz,
  4733. &sphConfig);
  4734. if (dwErr == ERROR_SUCCESS)
  4735. {
  4736. dwErr = ::MprConfigGetFriendlyName(sphConfig,
  4737. (LPTSTR)pszInterface,
  4738. szDesc,
  4739. sizeof(szDesc));
  4740. if(dwErr == ERROR_SUCCESS)
  4741. *ppszTitle = StrDup((LPCTSTR) szDesc);
  4742. }
  4743. hr = HRESULT_FROM_WIN32(dwErr);
  4744. // If we can't find the title by using the Mpr APIS,
  4745. // try to access the registry directly (using the setup APIs)
  4746. // --------------------------------------------------------
  4747. if (dwErr != ERROR_SUCCESS)
  4748. {
  4749. hr = SetupFindInterfaceTitle(pswz, pszInterface,
  4750. ppszTitle);
  4751. }
  4752. }
  4753. COM_PROTECT_ERROR_LABEL;
  4754. }
  4755. COM_PROTECT_CATCH;
  4756. return hr;
  4757. }
  4758. /*!--------------------------------------------------------------------------
  4759. InterfaceInfo::GetMachineName
  4760. -
  4761. Author: KennT
  4762. ---------------------------------------------------------------------------*/
  4763. STDMETHODIMP_(LPCOLESTR) InterfaceInfo::GetMachineName()
  4764. {
  4765. RtrCriticalSection rtrCritSec(&m_critsec);
  4766. //$UNICODE : kennt, assumes native unicode and OLECHAR==WCHAR
  4767. return m_stMachine;
  4768. }
  4769. /*!--------------------------------------------------------------------------
  4770. InterfaceInfo::SetMachineName
  4771. -
  4772. Author: KennT
  4773. ---------------------------------------------------------------------------*/
  4774. STDMETHODIMP InterfaceInfo::SetMachineName(LPCOLESTR pszMachineName)
  4775. {
  4776. RtrCriticalSection rtrCritSec(&m_critsec);
  4777. HRESULT hr = hrOK;
  4778. COM_PROTECT_TRY
  4779. {
  4780. m_stMachine = pszMachineName;
  4781. }
  4782. COM_PROTECT_CATCH;
  4783. return hr;
  4784. }
  4785. /*!--------------------------------------------------------------------------
  4786. InterfaceInfo::GetParentRouterInfo
  4787. -
  4788. Author: KennT
  4789. ---------------------------------------------------------------------------*/
  4790. STDMETHODIMP InterfaceInfo::GetParentRouterInfo(IRouterInfo **ppRouterInfo)
  4791. {
  4792. RtrCriticalSection rtrCritSec(&m_critsec);
  4793. HRESULT hr = hrOK;
  4794. COM_PROTECT_TRY
  4795. {
  4796. *ppRouterInfo = m_pRouterInfoParent;
  4797. if (*ppRouterInfo)
  4798. (*ppRouterInfo)->AddRef();
  4799. }
  4800. COM_PROTECT_CATCH;
  4801. return hr;
  4802. }
  4803. /*!--------------------------------------------------------------------------
  4804. InterfaceInfo::SetParentRouterInfo
  4805. -
  4806. Author: KennT
  4807. ---------------------------------------------------------------------------*/
  4808. HRESULT InterfaceInfo::SetParentRouterInfo(IRouterInfo *pParent)
  4809. {
  4810. RtrCriticalSection rtrCritSec(&m_critsec);
  4811. IRouterInfo * pTemp;
  4812. pTemp = m_pRouterInfoParent;
  4813. m_pRouterInfoParent = NULL;
  4814. if (m_fStrongRef)
  4815. {
  4816. if (pTemp)
  4817. pTemp->Release();
  4818. if (pParent)
  4819. pParent->AddRef();
  4820. }
  4821. else
  4822. {
  4823. if (pTemp)
  4824. pTemp->ReleaseWeakRef();
  4825. if (pParent)
  4826. pParent->AddWeakRef();
  4827. }
  4828. m_pRouterInfoParent = pParent;
  4829. return hrOK;
  4830. }
  4831. /*!--------------------------------------------------------------------------
  4832. InterfaceInfo::EnumRtrMgrInterface
  4833. -
  4834. Author: KennT
  4835. ---------------------------------------------------------------------------*/
  4836. STDMETHODIMP InterfaceInfo::EnumRtrMgrInterface( IEnumRtrMgrInterfaceInfo **ppEnumRmIf)
  4837. {
  4838. RtrCriticalSection rtrCritSec(&m_critsec);
  4839. HRESULT hr = hrOK;
  4840. COM_PROTECT_TRY
  4841. {
  4842. hr = CreateEnumFromRtrMgrInterfaceList(&m_RmIfList, ppEnumRmIf);
  4843. }
  4844. COM_PROTECT_CATCH;
  4845. return hr;
  4846. }
  4847. /*!--------------------------------------------------------------------------
  4848. InterfaceInfo::AddRtrMgrInterface
  4849. -
  4850. Author: KennT
  4851. ---------------------------------------------------------------------------*/
  4852. STDMETHODIMP InterfaceInfo::AddRtrMgrInterface( IRtrMgrInterfaceInfo *pRmIf,
  4853. IInfoBase *pIfInfo)
  4854. {
  4855. Assert(pRmIf);
  4856. RtrCriticalSection rtrCritSec(&m_critsec);
  4857. HRESULT hr = hrOK;
  4858. HRESULT hrT;
  4859. SPIRtrMgrInfo spRm;
  4860. COM_PROTECT_TRY
  4861. {
  4862. //
  4863. // Fail if there is a duplicate
  4864. //
  4865. if (FHrOK(FindRtrMgrInterface(pRmIf->GetTransportId(), NULL)))
  4866. CORg( E_INVALIDARG );
  4867. //
  4868. // Save the new router-manager
  4869. //
  4870. CORg( pRmIf->Save(GetMachineName(),
  4871. m_hMachineConfig, m_hInterface, NULL, pIfInfo, 0) );
  4872. //
  4873. // Add the new router-manager structure to the list
  4874. //
  4875. m_RmIfList.AddTail(pRmIf);
  4876. pRmIf->AddWeakRef();
  4877. pRmIf->SetParentInterfaceInfo(this);
  4878. // We don't notify of a new interface since we haven't
  4879. // actually saved the interface back down to the router
  4880. if (pIfInfo)
  4881. {
  4882. m_AdviseList.NotifyChange(ROUTER_CHILD_ADD, ROUTER_OBJ_RmIf, 0);
  4883. if (m_pRouterInfoParent)
  4884. {
  4885. hrT = m_pRouterInfoParent->FindRtrMgr(pRmIf->GetTransportId(), &spRm);
  4886. if (FHrOK(hrT))
  4887. spRm->RtrNotify(ROUTER_CHILD_ADD, ROUTER_OBJ_RmIf, 0);
  4888. }
  4889. }
  4890. COM_PROTECT_ERROR_LABEL;
  4891. }
  4892. COM_PROTECT_CATCH;
  4893. return hr;
  4894. }
  4895. /*!--------------------------------------------------------------------------
  4896. InterfaceInfo::DeleteRtrMgrInterface
  4897. -
  4898. Author: KennT
  4899. ---------------------------------------------------------------------------*/
  4900. STDMETHODIMP InterfaceInfo::DeleteRtrMgrInterface(DWORD dwTransportId, BOOL fRemove)
  4901. {
  4902. RtrCriticalSection rtrCritSec(&m_critsec);
  4903. HRESULT hr = hrOK, hrT;
  4904. SPIRtrMgrInterfaceInfo spRmIf;
  4905. POSITION pos, posRmIf;
  4906. SPIRtrMgrInfo spRm;
  4907. SPIEnumRtrMgrProtocolInterfaceInfo spEnumRmProtIf;
  4908. SPIRtrMgrProtocolInterfaceInfo spRmProtIf;
  4909. COM_PROTECT_TRY
  4910. {
  4911. //
  4912. // Find the router-manager to be deleted
  4913. //
  4914. pos = m_RmIfList.GetHeadPosition();
  4915. while (pos)
  4916. {
  4917. posRmIf = pos;
  4918. spRmIf.Set( m_RmIfList.GetNext(pos) );
  4919. if (spRmIf->GetTransportId() == dwTransportId)
  4920. break;
  4921. spRmIf.Release();
  4922. }
  4923. if (!spRmIf)
  4924. CORg( E_INVALIDARG );
  4925. // Delete all RtrMgrProtocolInterfaces from the router manager
  4926. spRmIf->EnumRtrMgrProtocolInterface(&spEnumRmProtIf);
  4927. while (spEnumRmProtIf->Next(1, &spRmProtIf, NULL) == hrOK)
  4928. {
  4929. DWORD dwProtocolId = spRmProtIf->GetProtocolId();
  4930. spRmProtIf.Release();
  4931. spRmIf->DeleteRtrMgrProtocolInterface(dwProtocolId, fRemove);
  4932. }
  4933. //
  4934. // Remove the router-manager from our list
  4935. //
  4936. m_RmIfList.RemoveAt(posRmIf);
  4937. spRmIf->Destruct();
  4938. spRmIf->ReleaseWeakRef();
  4939. //
  4940. // Remove the router-manager from the registry and the router
  4941. //
  4942. if (fRemove)
  4943. spRmIf->Delete(GetMachineName(), NULL, NULL);
  4944. m_AdviseList.NotifyChange(ROUTER_CHILD_DELETE, ROUTER_OBJ_RmIf, 0);
  4945. if (m_pRouterInfoParent)
  4946. {
  4947. hrT = m_pRouterInfoParent->FindRtrMgr(spRmIf->GetTransportId(), &spRm);
  4948. if (FHrOK(hrT))
  4949. spRm->RtrNotify(ROUTER_CHILD_DELETE, ROUTER_OBJ_RmIf, 0);
  4950. }
  4951. spRmIf.Release();
  4952. COM_PROTECT_ERROR_LABEL;
  4953. }
  4954. COM_PROTECT_CATCH;
  4955. return hr;
  4956. }
  4957. /*!--------------------------------------------------------------------------
  4958. InterfaceInfo::ReleaseRtrMgrInterface
  4959. This function will release the AddRef() that this object has
  4960. on the child. This allows us to transfer child objects from
  4961. one router to another.
  4962. Author: KennT
  4963. ---------------------------------------------------------------------------*/
  4964. STDMETHODIMP InterfaceInfo::ReleaseRtrMgrInterface( DWORD dwTransportId )
  4965. {
  4966. HRESULT hr = hrOK;
  4967. POSITION pos, posRmIf;
  4968. SPIRtrMgrInterfaceInfo spRmIf;
  4969. COM_PROTECT_TRY
  4970. {
  4971. pos = m_RmIfList.GetHeadPosition();
  4972. while (pos)
  4973. {
  4974. // Save the position (so that we can delete it)
  4975. posRmIf = pos;
  4976. spRmIf.Set( m_RmIfList.GetNext(pos) );
  4977. if (spRmIf &&
  4978. (spRmIf->GetTransportId() == dwTransportId))
  4979. {
  4980. // When releasing, we need to disconnect (since the
  4981. // main handle is controlled by the router info).
  4982. spRmIf->DoDisconnect();
  4983. spRmIf->ReleaseWeakRef();
  4984. spRmIf.Release();
  4985. // release this node from the list
  4986. m_RmIfList.RemoveAt(posRmIf);
  4987. break;
  4988. }
  4989. spRmIf.Release();
  4990. }
  4991. }
  4992. COM_PROTECT_CATCH;
  4993. return hr;
  4994. }
  4995. /*!--------------------------------------------------------------------------
  4996. InterfaceInfo::FindRtrMgrInterface
  4997. S_OK is returned if a RtrMgrInfo is found.
  4998. S_FALSE is returned if a RtrMgrInfo was NOT found.
  4999. error codes returned otherwise.
  5000. Author: KennT
  5001. ---------------------------------------------------------------------------*/
  5002. STDMETHODIMP InterfaceInfo::FindRtrMgrInterface( DWORD dwTransportId,
  5003. IRtrMgrInterfaceInfo **ppInfo)
  5004. {
  5005. RtrCriticalSection rtrCritSec(&m_critsec);
  5006. HRESULT hr = hrFalse;
  5007. POSITION pos;
  5008. SPIRtrMgrInterfaceInfo spRmIf;
  5009. COM_PROTECT_TRY
  5010. {
  5011. if (ppInfo)
  5012. *ppInfo = NULL;
  5013. pos = m_RmIfList.GetHeadPosition();
  5014. while (pos)
  5015. {
  5016. spRmIf.Set( m_RmIfList.GetNext(pos) );
  5017. if (spRmIf->GetTransportId() == dwTransportId)
  5018. {
  5019. hr = hrOK;
  5020. if (ppInfo)
  5021. *ppInfo = spRmIf.Transfer();
  5022. break;
  5023. }
  5024. }
  5025. }
  5026. COM_PROTECT_CATCH;
  5027. return hr;
  5028. }
  5029. /*!--------------------------------------------------------------------------
  5030. InterfaceInfo::RtrAdvise
  5031. -
  5032. Author: KennT
  5033. ---------------------------------------------------------------------------*/
  5034. STDMETHODIMP InterfaceInfo::RtrAdvise( IRtrAdviseSink *pRtrAdviseSink,
  5035. LONG_PTR *pulConnection, LPARAM lUserParam)
  5036. {
  5037. Assert(pRtrAdviseSink);
  5038. Assert(pulConnection);
  5039. RtrCriticalSection rtrCritSec(&m_critsec);
  5040. LONG_PTR ulConnId;
  5041. HRESULT hr = hrOK;
  5042. COM_PROTECT_TRY
  5043. {
  5044. ulConnId = (LONG_PTR) InterlockedIncrement(&s_cConnections);
  5045. CORg( m_AdviseList.AddConnection(pRtrAdviseSink, ulConnId, lUserParam) );
  5046. *pulConnection = ulConnId;
  5047. COM_PROTECT_ERROR_LABEL;
  5048. }
  5049. COM_PROTECT_CATCH;
  5050. return hr;
  5051. }
  5052. /*!--------------------------------------------------------------------------
  5053. InterfaceInfo::RtrNotify
  5054. -
  5055. Author: KennT
  5056. ---------------------------------------------------------------------------*/
  5057. STDMETHODIMP InterfaceInfo::RtrNotify(DWORD dwChangeType, DWORD dwObjectType,
  5058. LPARAM lParam)
  5059. {
  5060. RtrCriticalSection rtrCritSec(&m_critsec);
  5061. HRESULT hr = hrOK;
  5062. COM_PROTECT_TRY
  5063. {
  5064. m_AdviseList.NotifyChange(dwChangeType, dwObjectType, lParam);
  5065. }
  5066. COM_PROTECT_CATCH;
  5067. return hr;
  5068. }
  5069. /*!--------------------------------------------------------------------------
  5070. InterfaceInfo::RtrUnadvise
  5071. -
  5072. Author: KennT
  5073. ---------------------------------------------------------------------------*/
  5074. STDMETHODIMP InterfaceInfo::RtrUnadvise( LONG_PTR ulConnection)
  5075. {
  5076. RtrCriticalSection rtrCritSec(&m_critsec);
  5077. return m_AdviseList.RemoveConnection(ulConnection);
  5078. }
  5079. /*!--------------------------------------------------------------------------
  5080. InterfaceInfo::LoadRtrMgrInterfaceList
  5081. -
  5082. Author: KennT
  5083. ---------------------------------------------------------------------------*/
  5084. HRESULT InterfaceInfo::LoadRtrMgrInterfaceList()
  5085. {
  5086. RtrCriticalSection rtrCritSec(&m_critsec);
  5087. BOOL bAdd;
  5088. LPBYTE pItemTable = NULL;
  5089. SPIRtrMgrInterfaceInfo spRmIf;
  5090. DWORD dwErr, i, dwEntries, dwTotal;
  5091. HRESULT hr = hrOK;
  5092. MPR_IFTRANSPORT_0 *piftransport;
  5093. TCHAR szTransport[MAX_TRANSPORT_NAME_LEN+1];
  5094. USES_CONVERSION;
  5095. //
  5096. // Now enumerate the transports on this interface
  5097. //
  5098. dwErr = ::MprConfigInterfaceTransportEnum(
  5099. m_hMachineConfig,
  5100. m_hInterface,
  5101. 0,
  5102. &pItemTable,
  5103. (DWORD)-1,
  5104. &dwEntries,
  5105. &dwTotal,
  5106. NULL
  5107. );
  5108. if (dwErr != NO_ERROR && dwErr != ERROR_NO_MORE_ITEMS)
  5109. CWRg( dwErr );
  5110. //
  5111. // Construct a CRmInterfaceInfo for each transport enumerated
  5112. //
  5113. for (i = 0, piftransport = (MPR_IFTRANSPORT_0*)pItemTable;
  5114. i < dwEntries;
  5115. i++, piftransport++)
  5116. {
  5117. FindRtrMgrInterface(piftransport->dwTransportId, &spRmIf);
  5118. if (spRmIf)
  5119. bAdd = FALSE;
  5120. else
  5121. {
  5122. bAdd = TRUE;
  5123. StrCpyTFromW(szTransport, piftransport->wszIfTransportName);
  5124. //
  5125. // Construct a CRmInterfaceInfo object for this transport
  5126. //
  5127. spRmIf = new RtrMgrInterfaceInfo(piftransport->dwTransportId,
  5128. szTransport,
  5129. OLE2CT(GetId()),
  5130. GetInterfaceType(),
  5131. this);
  5132. spRmIf->SetFlags(RouterSnapin_InSyncWithRouter);
  5133. }
  5134. //
  5135. // Load the information for this CRmInterfaceInfo,
  5136. // indicating to it that it should load its list of protocols.
  5137. //
  5138. hr = spRmIf->Load(GetMachineName(), m_hMachineConfig, m_hInterface,
  5139. piftransport->hIfTransport );
  5140. if (!FHrSucceeded(hr))
  5141. {
  5142. spRmIf->Destruct();
  5143. spRmIf.Release();
  5144. continue;
  5145. }
  5146. //
  5147. // Add the router-manager interface to our list
  5148. //
  5149. if (bAdd)
  5150. {
  5151. m_RmIfList.AddTail(spRmIf);
  5152. CONVERT_TO_WEAKREF(spRmIf);
  5153. spRmIf.Transfer();
  5154. }
  5155. }
  5156. Error:
  5157. if (pItemTable)
  5158. ::MprConfigBufferFree(pItemTable);
  5159. return hr;
  5160. }
  5161. /*!--------------------------------------------------------------------------
  5162. InterfaceInfo::TryToConnect
  5163. -
  5164. Author: KennT
  5165. ---------------------------------------------------------------------------*/
  5166. HRESULT InterfaceInfo::TryToConnect(LPCWSTR pswzMachine, HANDLE *phMachine)
  5167. {
  5168. RtrCriticalSection rtrCritSec(&m_critsec);
  5169. HRESULT hr = hrOK;
  5170. if (m_hMachineConfig)
  5171. *phMachine = m_hMachineConfig;
  5172. else if (*phMachine)
  5173. {
  5174. m_hMachineConfig = *phMachine;
  5175. m_bDisconnect = FALSE;
  5176. }
  5177. else
  5178. {
  5179. //$ Review: kennt, this function does not take a LPCWSTR,
  5180. // is this a mistake or does it modify the parameters?
  5181. CWRg( ::MprConfigServerConnect((LPWSTR) pswzMachine, phMachine) );
  5182. m_hMachineConfig = *phMachine;
  5183. m_bDisconnect = TRUE;
  5184. }
  5185. Error:
  5186. return hr;
  5187. }
  5188. /*!--------------------------------------------------------------------------
  5189. InterfaceInfo::TryToGetIfHandle
  5190. -
  5191. Author: KennT
  5192. ---------------------------------------------------------------------------*/
  5193. HRESULT InterfaceInfo::TryToGetIfHandle(HANDLE hMachine,
  5194. LPCWSTR pswzInterface,
  5195. HANDLE *phInterface)
  5196. {
  5197. RtrCriticalSection rtrCritSec(&m_critsec);
  5198. HRESULT hr = hrOK;
  5199. if (m_hInterface)
  5200. *phInterface = m_hInterface;
  5201. else if (*phInterface)
  5202. m_hInterface = *phInterface;
  5203. else
  5204. {
  5205. //
  5206. // Get a handle to the interface
  5207. //
  5208. CWRg(::MprConfigInterfaceGetHandle(hMachine,
  5209. (LPWSTR) pswzInterface,
  5210. phInterface
  5211. ) );
  5212. m_hInterface = *phInterface;
  5213. }
  5214. Error:
  5215. return hr;
  5216. }
  5217. /*!--------------------------------------------------------------------------
  5218. InterfaceInfo::Disconnect
  5219. -
  5220. Author: KennT
  5221. ---------------------------------------------------------------------------*/
  5222. void InterfaceInfo::Disconnect()
  5223. {
  5224. if (m_bDisconnect && m_hMachineConfig)
  5225. ::MprConfigServerDisconnect(m_hMachineConfig);
  5226. m_bDisconnect = FALSE;
  5227. m_hMachineConfig = NULL;
  5228. m_hInterface = NULL;
  5229. }
  5230. /*!--------------------------------------------------------------------------
  5231. InterfaceInfo::DoDisconnect
  5232. -
  5233. Author: KennT
  5234. ---------------------------------------------------------------------------*/
  5235. STDMETHODIMP InterfaceInfo::DoDisconnect()
  5236. {
  5237. HRESULT hr = hrOK;
  5238. SPIEnumRtrMgrInterfaceInfo spEnumRmIf;
  5239. SPIRtrMgrInterfaceInfo spRmIf;
  5240. COM_PROTECT_TRY
  5241. {
  5242. // Disconnect our data.
  5243. // ------------------------------------------------------------
  5244. Disconnect();
  5245. // Notify the advise sinks of a disconnect.
  5246. // ------------------------------------------------------------
  5247. RtrNotify(ROUTER_DO_DISCONNECT, 0, 0);
  5248. // Now tell all child objects to disconnect.
  5249. // ------------------------------------------------------------
  5250. HRESULT hrIter = hrOK;
  5251. EnumRtrMgrInterface(&spEnumRmIf);
  5252. spEnumRmIf->Reset();
  5253. while (spEnumRmIf->Next(1, &spRmIf, NULL) == hrOK)
  5254. {
  5255. spRmIf->DoDisconnect();
  5256. spRmIf.Release();
  5257. }
  5258. }
  5259. COM_PROTECT_CATCH;
  5260. return hr;
  5261. }
  5262. /*---------------------------------------------------------------------------
  5263. IRtrMgrInterfaceInfo Implementation
  5264. ---------------------------------------------------------------------------*/
  5265. TFSCORE_API(HRESULT) CreateRtrMgrInterfaceInfo(IRtrMgrInterfaceInfo **ppRmIf,
  5266. LPCWSTR pszId,
  5267. DWORD dwTransportId,
  5268. LPCWSTR pswzInterfaceId,
  5269. DWORD dwIfType)
  5270. {
  5271. Assert(ppRmIf);
  5272. HRESULT hr = hrOK;
  5273. IRtrMgrInterfaceInfo * pRmIf = NULL;
  5274. USES_CONVERSION;
  5275. COM_PROTECT_TRY
  5276. {
  5277. pRmIf = new RtrMgrInterfaceInfo(dwTransportId,
  5278. W2CT(pszId),
  5279. W2CT(pswzInterfaceId),
  5280. dwIfType,
  5281. NULL);
  5282. *ppRmIf = pRmIf;
  5283. }
  5284. COM_PROTECT_CATCH;
  5285. return hr;
  5286. }
  5287. IMPLEMENT_WEAKREF_ADDREF_RELEASE(RtrMgrInterfaceInfo)
  5288. IMPLEMENT_SIMPLE_QUERYINTERFACE(RtrMgrInterfaceInfo, IRtrMgrInterfaceInfo)
  5289. DEBUG_DECLARE_INSTANCE_COUNTER(RtrMgrInterfaceInfo)
  5290. RtrMgrInterfaceInfo::RtrMgrInterfaceInfo(DWORD dwTransportId,
  5291. LPCTSTR pszId,
  5292. LPCTSTR pszIfId,
  5293. DWORD dwIfType,
  5294. InterfaceInfo *pInterfaceInfo)
  5295. : m_hMachineConfig(NULL),
  5296. m_hInterface(NULL),
  5297. m_hIfTransport(NULL),
  5298. m_bDisconnect(FALSE),
  5299. m_dwFlags(0)
  5300. {
  5301. m_cb.dwTransportId = dwTransportId;
  5302. m_cb.stId = pszId;
  5303. m_cb.stInterfaceId = pszIfId;
  5304. m_cb.dwIfType = dwIfType;
  5305. DEBUG_INCREMENT_INSTANCE_COUNTER(RtrMgrInterfaceInfo);
  5306. m_pInterfaceInfoParent = pInterfaceInfo;
  5307. if (m_pInterfaceInfoParent)
  5308. m_pInterfaceInfoParent->AddRef();
  5309. InitializeCriticalSection(&m_critsec);
  5310. }
  5311. RtrMgrInterfaceInfo::~RtrMgrInterfaceInfo()
  5312. {
  5313. Assert(m_pInterfaceInfoParent == NULL);
  5314. Destruct();
  5315. DEBUG_DECREMENT_INSTANCE_COUNTER(RtrMgrInterfaceInfo);
  5316. DeleteCriticalSection(&m_critsec);
  5317. }
  5318. void RtrMgrInterfaceInfo::ReviveStrongRef()
  5319. {
  5320. RtrCriticalSection rtrCritSec(&m_critsec);
  5321. if (m_pInterfaceInfoParent)
  5322. {
  5323. CONVERT_TO_STRONGREF(m_pInterfaceInfoParent);
  5324. }
  5325. }
  5326. void RtrMgrInterfaceInfo::OnLastStrongRef()
  5327. {
  5328. RtrCriticalSection rtrCritSec(&m_critsec);
  5329. if (m_pInterfaceInfoParent)
  5330. {
  5331. CONVERT_TO_WEAKREF(m_pInterfaceInfoParent);
  5332. }
  5333. if (m_fDestruct)
  5334. Destruct();
  5335. }
  5336. STDMETHODIMP RtrMgrInterfaceInfo::Destruct()
  5337. {
  5338. RtrCriticalSection rtrCritSec(&m_critsec);
  5339. IInterfaceInfo * pParent;
  5340. m_fDestruct = TRUE;
  5341. if (!m_fStrongRef)
  5342. {
  5343. pParent = m_pInterfaceInfoParent;
  5344. m_pInterfaceInfoParent = NULL;
  5345. if (pParent)
  5346. pParent->ReleaseWeakRef();
  5347. Unload();
  5348. }
  5349. return hrOK;
  5350. }
  5351. STDMETHODIMP_(DWORD) RtrMgrInterfaceInfo::GetFlags()
  5352. {
  5353. RtrCriticalSection rtrCritSec(&m_critsec);
  5354. return m_dwFlags;
  5355. }
  5356. STDMETHODIMP RtrMgrInterfaceInfo::SetFlags(DWORD dwFlags)
  5357. {
  5358. RtrCriticalSection rtrCritSec(&m_critsec);
  5359. HRESULT hr = hrOK;
  5360. COM_PROTECT_TRY
  5361. {
  5362. m_dwFlags = dwFlags;
  5363. }
  5364. COM_PROTECT_CATCH;
  5365. return hr;
  5366. }
  5367. /*!--------------------------------------------------------------------------
  5368. RtrMgrInterfaceInfo::Load
  5369. -
  5370. Author: KennT
  5371. ---------------------------------------------------------------------------*/
  5372. STDMETHODIMP RtrMgrInterfaceInfo::Load(LPCOLESTR pszMachine,
  5373. HANDLE hMachine,
  5374. HANDLE hInterface,
  5375. HANDLE hIfTransport)
  5376. {
  5377. RtrCriticalSection rtrCritSec(&m_critsec);
  5378. HRESULT hr = hrOK;
  5379. DWORD dwErr;
  5380. DWORD dwSize = 0;
  5381. MPR_INTERFACE_0 *pinterface = NULL;
  5382. SPIInterfaceInfo spIf;
  5383. SPIRouterInfo spRouter;
  5384. SPIEnumInterfaceCB spEnumIfCB;
  5385. InterfaceCB ifCB;
  5386. SPSZ spsz;
  5387. COM_PROTECT_TRY
  5388. {
  5389. //
  5390. // Discard any information already loaded
  5391. //
  5392. Unload();
  5393. m_stMachine = (pszMachine ? pszMachine : TEXT(""));
  5394. //
  5395. // If 'hMachine' was not specified, connect to the config
  5396. // on the specified machine
  5397. //
  5398. Assert(m_hMachineConfig == NULL);
  5399. CORg( TryToGetAllHandles(T2CW((LPTSTR)(LPCTSTR) m_stMachine),
  5400. &hMachine, &hInterface, &hIfTransport) );
  5401. //
  5402. // Get information about the interface
  5403. //
  5404. CWRg(::MprConfigInterfaceGetInfo(
  5405. hMachine,
  5406. hInterface,
  5407. 0,
  5408. (LPBYTE*)&pinterface,
  5409. &dwSize
  5410. ) );
  5411. //
  5412. // Save the interface type
  5413. //
  5414. m_cb.dwIfType = (DWORD)pinterface->dwIfType;
  5415. //
  5416. // If this isn't a LAN card, the interface-ID is the title;
  5417. // otherwise, retrieve the title from the Software key
  5418. //
  5419. if (GetInterfaceType() != (DWORD)ROUTER_IF_TYPE_DEDICATED)
  5420. {
  5421. m_cb.stTitle = OLE2CT(GetInterfaceId());
  5422. }
  5423. else
  5424. {
  5425. // Can we get to the router info object?
  5426. if (m_pInterfaceInfoParent)
  5427. m_pInterfaceInfoParent->GetParentRouterInfo(&spRouter);
  5428. if (spRouter)
  5429. {
  5430. //
  5431. // This object is contained in a 'CRouterInfo',
  5432. // which will have already loaded the LAN interface
  5433. // control-blocks search through that list to find our title,
  5434. //
  5435. BOOL bFound = FALSE;
  5436. CORg( spRouter->EnumInterfaceCB(&spEnumIfCB) );
  5437. spEnumIfCB->Reset();
  5438. while (spEnumIfCB->Next(1, &ifCB, NULL) == hrOK)
  5439. {
  5440. if (StriCmpW(ifCB.szId, GetInterfaceId()) == 0)
  5441. {
  5442. m_cb.stTitle = OLE2CT(ifCB.szId);
  5443. bFound = TRUE;
  5444. break;
  5445. }
  5446. }
  5447. if (!bFound)
  5448. {
  5449. hr = InterfaceInfo::FindInterfaceTitle(OLE2CT(GetMachineName()),
  5450. OLE2CT(GetInterfaceId()),
  5451. &spsz);
  5452. if (FHrOK(hr))
  5453. m_cb.stTitle = spsz;
  5454. else
  5455. m_cb.stTitle = OLE2CT(GetInterfaceId());
  5456. hr = hrOK;
  5457. }
  5458. }
  5459. else
  5460. {
  5461. //
  5462. // Read the title directly from the registry
  5463. //
  5464. hr = InterfaceInfo::FindInterfaceTitle(OLE2CT(GetMachineName()),
  5465. OLE2CT(GetInterfaceId()),
  5466. &spsz);
  5467. if (FHrOK(hr))
  5468. m_cb.stTitle = spsz;
  5469. else
  5470. m_cb.stTitle = OLE2CT(GetInterfaceId());
  5471. hr = hrOK;
  5472. }
  5473. }
  5474. //
  5475. // Load the list of routing-protocols active on this interface
  5476. //
  5477. CORg( LoadRtrMgrInterfaceInfo(hMachine, hInterface, hIfTransport) );
  5478. COM_PROTECT_ERROR_LABEL;
  5479. }
  5480. COM_PROTECT_CATCH;
  5481. if (pinterface)
  5482. ::MprConfigBufferFree(pinterface);
  5483. return hr;
  5484. }
  5485. /*!--------------------------------------------------------------------------
  5486. RtrMgrInterfaceInfo::Save
  5487. -
  5488. Author: KennT
  5489. ---------------------------------------------------------------------------*/
  5490. STDMETHODIMP RtrMgrInterfaceInfo::Save(
  5491. LPCOLESTR pszMachine,
  5492. HANDLE hMachine,
  5493. HANDLE hInterface,
  5494. HANDLE hIfTransport,
  5495. IInfoBase* pInterfaceInfo,
  5496. DWORD dwDeleteProtocolId)
  5497. {
  5498. RtrCriticalSection rtrCritSec(&m_critsec);
  5499. HRESULT hr = hrOK;
  5500. DWORD dwErr;
  5501. COM_PROTECT_TRY
  5502. {
  5503. //$ OPT : We reuse the handles (if they exist), so why
  5504. // do we pass in the machine name? What we should do is
  5505. // to release all the handles first.
  5506. Assert(m_stMachine.CompareNoCase(pszMachine) == 0);
  5507. hr = TryToGetAllHandles(pszMachine,
  5508. &hMachine,
  5509. &hInterface,
  5510. &hIfTransport);
  5511. if (!FHrSucceeded(hr) && (hIfTransport == NULL))
  5512. {
  5513. dwErr = ::MprConfigInterfaceTransportGetHandle(hMachine,
  5514. hInterface, GetTransportId(), &hIfTransport);
  5515. if (dwErr != NO_ERROR)
  5516. {
  5517. //
  5518. // We couldn't connect so try creating the interface-transport;
  5519. // First convert the transport-name to Unicode
  5520. //
  5521. WCHAR wszTransport[MAX_TRANSPORT_NAME_LEN+1];
  5522. StrCpyWFromT(wszTransport, m_cb.stId);
  5523. //
  5524. // Create the interface-transport
  5525. //
  5526. CWRg( ::MprConfigInterfaceTransportAdd(hMachine, hInterface,
  5527. GetTransportId(), wszTransport,
  5528. NULL, 0, &hIfTransport) );
  5529. }
  5530. m_hIfTransport = hIfTransport;
  5531. }
  5532. //
  5533. // Update the registry and our infobase with the current information
  5534. //
  5535. CORg( SaveRtrMgrInterfaceInfo(
  5536. hMachine, hInterface, hIfTransport, pInterfaceInfo,
  5537. dwDeleteProtocolId
  5538. ) );
  5539. COM_PROTECT_ERROR_LABEL;
  5540. }
  5541. COM_PROTECT_CATCH;
  5542. return hr;
  5543. }
  5544. /*!--------------------------------------------------------------------------
  5545. RtrMgrInterfaceInfo::Unload
  5546. -
  5547. Author: KennT
  5548. ---------------------------------------------------------------------------*/
  5549. STDMETHODIMP RtrMgrInterfaceInfo::Unload( )
  5550. {
  5551. RtrCriticalSection rtrCritSec(&m_critsec);
  5552. HRESULT hr = hrOK;
  5553. IRtrMgrProtocolInterfaceInfo * pRmProtIf;
  5554. COM_PROTECT_TRY
  5555. {
  5556. while (!m_RmProtIfList.IsEmpty())
  5557. {
  5558. pRmProtIf = m_RmProtIfList.RemoveHead();
  5559. pRmProtIf->Destruct();
  5560. pRmProtIf->ReleaseWeakRef();
  5561. }
  5562. DoDisconnect();
  5563. }
  5564. COM_PROTECT_CATCH;
  5565. return hr;
  5566. }
  5567. /*!--------------------------------------------------------------------------
  5568. RtrMgrInterfaceInfo::Delete
  5569. -
  5570. Author: KennT
  5571. ---------------------------------------------------------------------------*/
  5572. STDMETHODIMP RtrMgrInterfaceInfo::Delete(LPCOLESTR pszMachine,
  5573. HANDLE hMachine,
  5574. HANDLE hInterface)
  5575. {
  5576. RtrCriticalSection rtrCritSec(&m_critsec);
  5577. MPR_SERVER_HANDLE hrouter = NULL;
  5578. HRESULT hr = hrOK;
  5579. DWORD dwErr;
  5580. HANDLE hIfTransport = NULL;
  5581. WCHAR wszInterface[MAX_INTERFACE_NAME_LEN+1];
  5582. USES_CONVERSION;
  5583. COM_PROTECT_TRY
  5584. {
  5585. //
  5586. //$ OPT, kennt : why is the machine name passed in here?
  5587. //
  5588. CORg( TryToGetAllHandles(pszMachine,
  5589. &hMachine,
  5590. &hInterface,
  5591. NULL) );
  5592. do
  5593. {
  5594. //
  5595. // Get a handle to the interface-transport
  5596. //
  5597. dwErr = ::MprConfigInterfaceTransportGetHandle(
  5598. hMachine,
  5599. hInterface,
  5600. GetTransportId(),
  5601. &hIfTransport
  5602. );
  5603. if (dwErr == NO_ERROR)
  5604. {
  5605. //
  5606. // Remove the interface-transport
  5607. //
  5608. dwErr = ::MprConfigInterfaceTransportRemove(
  5609. hMachine,
  5610. hInterface,
  5611. hIfTransport
  5612. );
  5613. }
  5614. m_hIfTransport = NULL;
  5615. } while(FALSE);
  5616. //
  5617. // Now remove the router-manager from the interface
  5618. // with the currently running router
  5619. //
  5620. if (ConnectRouter(OLE2CT(pszMachine), (HANDLE*)&hrouter) == NO_ERROR)
  5621. {
  5622. //
  5623. // Convert ID into Unicode
  5624. //
  5625. StrnCpyWFromOle(wszInterface, GetInterfaceId(),
  5626. DimensionOf(wszInterface));
  5627. //
  5628. // The router is running; if the interface exists, remove it
  5629. //
  5630. dwErr = ::MprAdminInterfaceGetHandle(
  5631. hrouter,
  5632. wszInterface,
  5633. &hInterface,
  5634. FALSE
  5635. );
  5636. if (dwErr == NO_ERROR)
  5637. {
  5638. //
  5639. // Remove the interface-transport
  5640. //
  5641. dwErr = ::MprAdminInterfaceTransportRemove(
  5642. hrouter,
  5643. hInterface,
  5644. GetTransportId()
  5645. );
  5646. }
  5647. ::MprAdminServerDisconnect(hrouter);
  5648. if ((dwErr == RPC_S_SERVER_UNAVAILABLE) ||
  5649. (dwErr == RPC_S_UNKNOWN_IF))
  5650. dwErr = NO_ERROR;
  5651. CWRg( dwErr );
  5652. }
  5653. COM_PROTECT_ERROR_LABEL;
  5654. }
  5655. COM_PROTECT_CATCH;
  5656. return hr;
  5657. }
  5658. /*!--------------------------------------------------------------------------
  5659. RtrMgrInterfaceInfo::Merge
  5660. -
  5661. Author: KennT
  5662. ---------------------------------------------------------------------------*/
  5663. STDMETHODIMP RtrMgrInterfaceInfo::Merge(IRtrMgrInterfaceInfo *pNewRmIf)
  5664. {
  5665. RtrCriticalSection rtrCritSec(&m_critsec);
  5666. SPIEnumRtrMgrProtocolInterfaceInfo spEnumRmProtIf;
  5667. SPIRtrMgrProtocolInterfaceInfo spRmProtIf;
  5668. HRESULT hr = hrOK;
  5669. CDWordArray oldDWArray;
  5670. CDWordArray newDWArray;
  5671. int cOld, cNew;
  5672. int i, j;
  5673. DWORD dwTemp;
  5674. RtrMgrInterfaceCB rmIfCB;
  5675. Assert(pNewRmIf);
  5676. Assert(pNewRmIf->GetTransportId() == GetTransportId());
  5677. Assert(lstrcmpi(pNewRmIf->GetId(), GetId()) == 0);
  5678. COM_PROTECT_TRY
  5679. {
  5680. // Need to sync up RtrMgrInterfaceInfo
  5681. pNewRmIf->CopyCB(&rmIfCB);
  5682. m_cb.LoadFrom(&rmIfCB);
  5683. //
  5684. // The general algorithm is to build up two arrays
  5685. // the first array contains the protocol ids for this object
  5686. // the second array contains the ids for the new object
  5687. //
  5688. // We then go through and remove all protocols that are in
  5689. // BOTH lists.
  5690. //
  5691. // This will leave us with the first array containing the
  5692. // ids of the protocols that need to be deleted from this object.
  5693. //
  5694. // The second array will have the list of ids of protocols that
  5695. // have to be added to this object from the second object.
  5696. //
  5697. // Get the list of protocols that are in the new object
  5698. CORg( pNewRmIf->EnumRtrMgrProtocolInterface(&spEnumRmProtIf) );
  5699. spEnumRmProtIf->Reset();
  5700. while (spEnumRmProtIf->Next(1, &spRmProtIf, NULL) == hrOK)
  5701. {
  5702. newDWArray.Add(spRmProtIf->GetProtocolId());
  5703. spRmProtIf.Release();
  5704. }
  5705. spEnumRmProtIf.Release();
  5706. spRmProtIf.Release();
  5707. // Get the list of protocols that are in this object
  5708. CORg( this->EnumRtrMgrProtocolInterface(&spEnumRmProtIf) );
  5709. spEnumRmProtIf->Reset();
  5710. while (spEnumRmProtIf->Next(1, &spRmProtIf, NULL) == hrOK)
  5711. {
  5712. oldDWArray.Add(spRmProtIf->GetProtocolId());
  5713. spRmProtIf.Release();
  5714. }
  5715. spEnumRmProtIf.Release();
  5716. spRmProtIf.Release();
  5717. // Ok now go through both lists, removing from the lists
  5718. // protocols that are in both lists.
  5719. cOld = oldDWArray.GetSize();
  5720. cNew = newDWArray.GetSize();
  5721. for (i=cOld; --i>=0; )
  5722. {
  5723. dwTemp = oldDWArray.GetAt(i);
  5724. for (j=cNew; --j>=0; )
  5725. {
  5726. if (dwTemp == newDWArray.GetAt(j))
  5727. {
  5728. // remove both instances
  5729. newDWArray.RemoveAt(j);
  5730. oldDWArray.RemoveAt(i);
  5731. // Need to update the size of the new array
  5732. cNew--;
  5733. break;
  5734. }
  5735. }
  5736. }
  5737. // oldDWArray now contains the protocols that should be
  5738. // removed.
  5739. if (oldDWArray.GetSize())
  5740. {
  5741. for (i=oldDWArray.GetSize(); --i>=0; )
  5742. {
  5743. // Windows NT Bug: 132993, we need to make sure that
  5744. // we don't delete the local interfaces
  5745. SPIRtrMgrProtocolInterfaceInfo spRmProtIfTemp;
  5746. FindRtrMgrProtocolInterface(oldDWArray.GetAt(i),
  5747. &spRmProtIfTemp);
  5748. Assert(spRmProtIfTemp);
  5749. if (spRmProtIfTemp->GetFlags() & RouterSnapin_InSyncWithRouter)
  5750. DeleteRtrMgrProtocolInterface(oldDWArray.GetAt(i), FALSE);
  5751. }
  5752. }
  5753. // newDWArray contains the protocols that should be added
  5754. if (newDWArray.GetSize())
  5755. {
  5756. for (i=newDWArray.GetSize(); --i>= 0; )
  5757. {
  5758. hr = pNewRmIf->FindRtrMgrProtocolInterface(
  5759. newDWArray.GetAt(i), &spRmProtIf);
  5760. Assert(hr == hrOK);
  5761. if (spRmProtIf)
  5762. {
  5763. AddRtrMgrProtocolInterface(spRmProtIf, NULL);
  5764. // Remove this rmprotif from its old RMinterface
  5765. // ------------------------------------------------
  5766. pNewRmIf->ReleaseRtrMgrProtocolInterface(
  5767. spRmProtIf->GetProtocolId());
  5768. }
  5769. spRmProtIf.Release();
  5770. }
  5771. }
  5772. COM_PROTECT_ERROR_LABEL;
  5773. }
  5774. COM_PROTECT_CATCH;
  5775. return hr;
  5776. }
  5777. /*!--------------------------------------------------------------------------
  5778. RtrMgrInterfaceInfo::SetInfo
  5779. -
  5780. This function updates the information in use by the router-manager
  5781. if it is currently running.
  5782. Author: KennT
  5783. ---------------------------------------------------------------------------*/
  5784. STDMETHODIMP RtrMgrInterfaceInfo::SetInfo(DWORD dwIfInfoSize,
  5785. PBYTE pInterfaceInfoData)
  5786. {
  5787. RtrCriticalSection rtrCritSec(&m_critsec);
  5788. HRESULT hr = hrOK;
  5789. DWORD dwErr;
  5790. MPR_SERVER_HANDLE hrouter = NULL;
  5791. HANDLE hinterface = NULL;
  5792. COM_PROTECT_TRY
  5793. {
  5794. //
  5795. // Connect to the router
  5796. //
  5797. CWRg( ConnectRouter(OLE2CT(GetMachineName()), (HANDLE*)&hrouter) );
  5798. do {
  5799. //
  5800. // Get the handle to the interface
  5801. //
  5802. WCHAR wszInterface[MAX_INTERFACE_NAME_LEN+1];
  5803. StrCpyWFromT(wszInterface, GetInterfaceId());
  5804. dwErr = ::MprAdminInterfaceGetHandle(
  5805. hrouter,
  5806. wszInterface,
  5807. &hinterface,
  5808. FALSE
  5809. );
  5810. if (dwErr != NO_ERROR) { hinterface = NULL; break; }
  5811. //
  5812. // Set the new info for the router-manager
  5813. //
  5814. dwErr = ::MprAdminInterfaceTransportSetInfo(
  5815. hrouter,
  5816. hinterface,
  5817. m_cb.dwTransportId,
  5818. pInterfaceInfoData,
  5819. dwIfInfoSize
  5820. );
  5821. //
  5822. // If that failed, we assume that the router-manager
  5823. // has not been added, and we attempt an add;
  5824. // otherwise, we set the new information
  5825. //
  5826. if (dwErr != NO_ERROR && dwErr != RPC_S_SERVER_UNAVAILABLE)
  5827. {
  5828. //
  5829. // Attempt to add the router-manager on the interface
  5830. //
  5831. DWORD dwErr1 = ::MprAdminInterfaceTransportAdd(
  5832. hrouter,
  5833. hinterface,
  5834. m_cb.dwTransportId,
  5835. pInterfaceInfoData,
  5836. dwIfInfoSize
  5837. );
  5838. if (dwErr1 == NO_ERROR)
  5839. dwErr = dwErr1;
  5840. }
  5841. } while (FALSE);
  5842. if ((dwErr == RPC_S_SERVER_UNAVAILABLE) ||
  5843. (dwErr == RPC_S_UNKNOWN_IF))
  5844. dwErr = NO_ERROR;
  5845. CWRg(dwErr);
  5846. COM_PROTECT_ERROR_LABEL;
  5847. }
  5848. COM_PROTECT_CATCH;
  5849. // If we fail to contact the server, then we will get these
  5850. // errors. The most common occurrence is that the router is
  5851. // not running.
  5852. if ((hr == HResultFromWin32(RPC_S_SERVER_UNAVAILABLE)) ||
  5853. (hr == HResultFromWin32(RPC_S_UNKNOWN_IF)))
  5854. hr = hrOK;
  5855. if (hrouter)
  5856. ::MprAdminServerDisconnect(hrouter);
  5857. return hr;
  5858. }
  5859. /*!--------------------------------------------------------------------------
  5860. RtrMgrInterfaceInfo::SetInfoBase
  5861. -
  5862. Author: KennT
  5863. ---------------------------------------------------------------------------*/
  5864. STDMETHODIMP RtrMgrInterfaceInfo::SetInfoBase(HANDLE hMachine,
  5865. HANDLE hInterface,
  5866. HANDLE hIfTransport,
  5867. IInfoBase *pInfoBase)
  5868. {
  5869. RtrCriticalSection rtrCritSec(&m_critsec);
  5870. HRESULT hr = hrOK;
  5871. LPBYTE pIfBytes = NULL;
  5872. DWORD dwIfBytesSize = 0;
  5873. COM_PROTECT_TRY
  5874. {
  5875. if (pInfoBase)
  5876. {
  5877. //
  5878. // If already loaded, the handles passed in are ignored.
  5879. //
  5880. // Otherwise, if not specified, a connection will be made.
  5881. //
  5882. CORg( TryToGetAllHandles(T2CW((LPTSTR)(LPCTSTR) m_stMachine),
  5883. &hMachine, &hInterface, &hIfTransport) );
  5884. //
  5885. // Convert the CInfoBase to a byte-array
  5886. //
  5887. CWRg( pInfoBase->WriteTo(&pIfBytes, &dwIfBytesSize) );
  5888. //
  5889. // Save the information to the persistent store
  5890. //
  5891. CWRg( ::MprConfigInterfaceTransportSetInfo(
  5892. hMachine,
  5893. hInterface,
  5894. hIfTransport,
  5895. pIfBytes,
  5896. dwIfBytesSize
  5897. ) );
  5898. }
  5899. COM_PROTECT_ERROR_LABEL;
  5900. }
  5901. COM_PROTECT_CATCH;
  5902. CoTaskMemFree( pIfBytes );
  5903. return hr;
  5904. }
  5905. /*!--------------------------------------------------------------------------
  5906. RtrMgrInterfaceInfo::GetInfoBase
  5907. -
  5908. Author: KennT
  5909. ---------------------------------------------------------------------------*/
  5910. STDMETHODIMP RtrMgrInterfaceInfo::GetInfoBase(HANDLE hMachine,
  5911. HANDLE hInterface,
  5912. HANDLE hIfTransport,
  5913. IInfoBase **ppInfoBase)
  5914. {
  5915. Assert(ppInfoBase);
  5916. RtrCriticalSection rtrCritSec(&m_critsec);
  5917. HRESULT hr = hrOK;
  5918. LPBYTE pIfBytes = NULL;
  5919. DWORD dwIfBytesSize;
  5920. SPIInfoBase spInfoBase;
  5921. COM_PROTECT_TRY
  5922. {
  5923. *ppInfoBase = NULL;
  5924. //
  5925. // If already loaded, the handles passed in are ignored.
  5926. //
  5927. // Otherwise, if not specified, a connection will be made.
  5928. //
  5929. CORg( TryToGetAllHandles(T2CW((LPTSTR)(LPCTSTR) m_stMachine),
  5930. &hMachine, &hInterface, &hIfTransport) );
  5931. CORg( CreateInfoBase(&spInfoBase) );
  5932. //
  5933. // Retrieve the info for the interface transport
  5934. //
  5935. CWRg( ::MprConfigInterfaceTransportGetInfo(
  5936. hMachine, hInterface, hIfTransport,
  5937. &pIfBytes,
  5938. &dwIfBytesSize
  5939. ));
  5940. //
  5941. // Parse the interface info for the router-manager
  5942. //
  5943. CORg( spInfoBase->LoadFrom(dwIfBytesSize, pIfBytes) );
  5944. *ppInfoBase = spInfoBase.Transfer();
  5945. COM_PROTECT_ERROR_LABEL;
  5946. }
  5947. COM_PROTECT_CATCH;
  5948. if (pIfBytes) { ::MprConfigBufferFree(pIfBytes); }
  5949. return hr;
  5950. }
  5951. /*!--------------------------------------------------------------------------
  5952. RtrMgrInterfaceInfo::GetId
  5953. -
  5954. Author: KennT
  5955. ---------------------------------------------------------------------------*/
  5956. STDMETHODIMP_(LPCOLESTR) RtrMgrInterfaceInfo::GetId()
  5957. {
  5958. RtrCriticalSection rtrCritSec(&m_critsec);
  5959. return m_cb.stId;
  5960. }
  5961. /*!--------------------------------------------------------------------------
  5962. RtrMgrInterfaceInfo::SetId
  5963. -
  5964. Author: KennT
  5965. ---------------------------------------------------------------------------*/
  5966. STDMETHODIMP RtrMgrInterfaceInfo::SetId(LPCOLESTR pszId)
  5967. {
  5968. RtrCriticalSection rtrCritSec(&m_critsec);
  5969. HRESULT hr = hrOK;
  5970. COM_PROTECT_TRY
  5971. {
  5972. m_cb.stId = pszId;
  5973. }
  5974. COM_PROTECT_CATCH;
  5975. return hr;
  5976. }
  5977. /*!--------------------------------------------------------------------------
  5978. RtrMgrInterfaceInfo::GetTransportId
  5979. -
  5980. Author: KennT
  5981. ---------------------------------------------------------------------------*/
  5982. STDMETHODIMP_(DWORD) RtrMgrInterfaceInfo::GetTransportId()
  5983. {
  5984. RtrCriticalSection rtrCritSec(&m_critsec);
  5985. return m_cb.dwTransportId;
  5986. }
  5987. /*!--------------------------------------------------------------------------
  5988. RtrMgrInterfaceInfo::GetInterfaceId
  5989. -
  5990. Author: KennT
  5991. ---------------------------------------------------------------------------*/
  5992. STDMETHODIMP_(LPCOLESTR) RtrMgrInterfaceInfo::GetInterfaceId()
  5993. {
  5994. RtrCriticalSection rtrCritSec(&m_critsec);
  5995. //$UNICODE : kennt, assumes native unicode and OLECHAR==WCHAR
  5996. return m_cb.stInterfaceId;
  5997. }
  5998. /*!--------------------------------------------------------------------------
  5999. RtrMgrInterfaceInfo::GetInterfaceType
  6000. -
  6001. Author: KennT
  6002. ---------------------------------------------------------------------------*/
  6003. STDMETHODIMP_(DWORD) RtrMgrInterfaceInfo::GetInterfaceType()
  6004. {
  6005. RtrCriticalSection rtrCritSec(&m_critsec);
  6006. return m_cb.dwIfType;
  6007. }
  6008. /*!--------------------------------------------------------------------------
  6009. RtrMgrInterfaceInfo::GetTitle
  6010. -
  6011. Author: KennT
  6012. ---------------------------------------------------------------------------*/
  6013. STDMETHODIMP_(LPCOLESTR) RtrMgrInterfaceInfo::GetTitle()
  6014. {
  6015. RtrCriticalSection rtrCritSec(&m_critsec);
  6016. //$UNICODE : kennt, assumes native unicode and OLECHAR==WCHAR
  6017. return m_cb.stTitle;
  6018. }
  6019. /*!--------------------------------------------------------------------------
  6020. RtrMgrInterfaceInfo::SetTitle
  6021. -
  6022. Author: KennT
  6023. ---------------------------------------------------------------------------*/
  6024. STDMETHODIMP RtrMgrInterfaceInfo::SetTitle(LPCOLESTR pszTitle)
  6025. {
  6026. RtrCriticalSection rtrCritSec(&m_critsec);
  6027. HRESULT hr = hrOK;
  6028. COM_PROTECT_TRY
  6029. {
  6030. m_cb.stTitle = pszTitle;
  6031. }
  6032. COM_PROTECT_CATCH;
  6033. return hr;
  6034. }
  6035. /*!--------------------------------------------------------------------------
  6036. RtrMgrInterfaceInfo::CopyCB
  6037. -
  6038. Author: KennT
  6039. ---------------------------------------------------------------------------*/
  6040. STDMETHODIMP RtrMgrInterfaceInfo::CopyCB(RtrMgrInterfaceCB *pRmIfCB)
  6041. {
  6042. RtrCriticalSection rtrCritSec(&m_critsec);
  6043. HRESULT hr = hrOK;
  6044. COM_PROTECT_TRY
  6045. {
  6046. m_cb.SaveTo(pRmIfCB);
  6047. }
  6048. COM_PROTECT_CATCH;
  6049. return hr;
  6050. }
  6051. /*!--------------------------------------------------------------------------
  6052. RtrMgrInterfaceInfo::GetMachineName
  6053. -
  6054. Author: KennT
  6055. ---------------------------------------------------------------------------*/
  6056. STDMETHODIMP_(LPCOLESTR) RtrMgrInterfaceInfo::GetMachineName()
  6057. {
  6058. RtrCriticalSection rtrCritSec(&m_critsec);
  6059. //$UNICODE : kennt, assumes native unicode and OLECHAR==WCHAR
  6060. return m_stMachine;
  6061. }
  6062. /*!--------------------------------------------------------------------------
  6063. RtrMgrInterfaceInfo::SetMachineName
  6064. -
  6065. Author: KennT
  6066. ---------------------------------------------------------------------------*/
  6067. STDMETHODIMP RtrMgrInterfaceInfo::SetMachineName(LPCOLESTR pszMachineName)
  6068. {
  6069. RtrCriticalSection rtrCritSec(&m_critsec);
  6070. HRESULT hr = hrOK;
  6071. COM_PROTECT_TRY
  6072. {
  6073. m_stMachine = pszMachineName;
  6074. }
  6075. COM_PROTECT_CATCH;
  6076. return hr;
  6077. }
  6078. /*!--------------------------------------------------------------------------
  6079. RtrMgrInterfaceInfo::EnumRtrMgrProtocolInterface
  6080. -
  6081. Author: KennT
  6082. ---------------------------------------------------------------------------*/
  6083. STDMETHODIMP RtrMgrInterfaceInfo::EnumRtrMgrProtocolInterface( IEnumRtrMgrProtocolInterfaceInfo **ppEnumRmProtIf)
  6084. {
  6085. RtrCriticalSection rtrCritSec(&m_critsec);
  6086. HRESULT hr = hrOK;
  6087. COM_PROTECT_TRY
  6088. {
  6089. hr = CreateEnumFromRtrMgrProtocolInterfaceList(&m_RmProtIfList,
  6090. ppEnumRmProtIf);
  6091. }
  6092. COM_PROTECT_CATCH;
  6093. return hr;
  6094. }
  6095. /*!--------------------------------------------------------------------------
  6096. RtrMgrInterfaceInfo::FindRtrMgrProtocolInterface
  6097. -
  6098. Author: KennT
  6099. ---------------------------------------------------------------------------*/
  6100. STDMETHODIMP RtrMgrInterfaceInfo::FindRtrMgrProtocolInterface( DWORD dwProtocolId,
  6101. IRtrMgrProtocolInterfaceInfo **ppInfo)
  6102. {
  6103. RtrCriticalSection rtrCritSec(&m_critsec);
  6104. HRESULT hr = hrFalse;
  6105. POSITION pos;
  6106. SPIRtrMgrProtocolInterfaceInfo spRmProtIf;
  6107. COM_PROTECT_TRY
  6108. {
  6109. if (ppInfo)
  6110. *ppInfo = NULL;
  6111. // Look through the list of rtr mgrs for the one that matches
  6112. pos = m_RmProtIfList.GetHeadPosition();
  6113. while (pos)
  6114. {
  6115. spRmProtIf.Set(m_RmProtIfList.GetNext(pos));
  6116. Assert(spRmProtIf);
  6117. if (spRmProtIf->GetProtocolId() == dwProtocolId)
  6118. {
  6119. hr = hrOK;
  6120. if (ppInfo)
  6121. *ppInfo = spRmProtIf.Transfer();
  6122. break;
  6123. }
  6124. }
  6125. }
  6126. COM_PROTECT_CATCH;
  6127. return hr;
  6128. }
  6129. /*!--------------------------------------------------------------------------
  6130. RtrMgrInterfaceInfo::AddRtrMgrProtocolInterface
  6131. -
  6132. Author: KennT
  6133. ---------------------------------------------------------------------------*/
  6134. STDMETHODIMP RtrMgrInterfaceInfo::AddRtrMgrProtocolInterface( IRtrMgrProtocolInterfaceInfo *pInfo,
  6135. IInfoBase *pInterfaceInfo)
  6136. {
  6137. Assert(pInfo);
  6138. RtrCriticalSection rtrCritSec(&m_critsec);
  6139. HRESULT hr = hrOK;
  6140. COM_PROTECT_TRY
  6141. {
  6142. //
  6143. // Fail if there is a duplicate
  6144. //
  6145. if (FHrOK(FindRtrMgrProtocolInterface(pInfo->GetProtocolId(), NULL)))
  6146. CORg( E_INVALIDARG );
  6147. //
  6148. // Save the new information if specified
  6149. //
  6150. if (pInterfaceInfo)
  6151. {
  6152. CORg( Save(GetMachineName(),
  6153. m_hMachineConfig,
  6154. m_hInterface,
  6155. m_hIfTransport,
  6156. pInterfaceInfo,
  6157. 0) );
  6158. }
  6159. //
  6160. // Add the new routing-protocol to our list
  6161. //
  6162. m_RmProtIfList.AddTail(pInfo);
  6163. pInfo->AddWeakRef();
  6164. pInfo->SetParentRtrMgrInterfaceInfo(this);
  6165. NotifyOfRmProtIfAdd(pInfo, m_pInterfaceInfoParent);
  6166. COM_PROTECT_ERROR_LABEL;
  6167. }
  6168. COM_PROTECT_CATCH;
  6169. return hr;
  6170. }
  6171. /*!--------------------------------------------------------------------------
  6172. RtrMgrInterfaceInfo::DeleteRtrMgrProtocolInterface
  6173. -
  6174. Author: KennT
  6175. ---------------------------------------------------------------------------*/
  6176. STDMETHODIMP RtrMgrInterfaceInfo::DeleteRtrMgrProtocolInterface( DWORD dwProtocolId, BOOL fRemove)
  6177. {
  6178. RtrCriticalSection rtrCritSec(&m_critsec);
  6179. HRESULT hr = hrOK;
  6180. SPIRtrMgrProtocolInterfaceInfo spRmProtIf;
  6181. SPIRtrMgrProtocolInfo spRmProt;
  6182. SPIRouterInfo spRouterInfo;
  6183. POSITION pos;
  6184. POSITION posRmProtIf;
  6185. HRESULT hrT;
  6186. COM_PROTECT_TRY
  6187. {
  6188. //
  6189. // Find the routing-protocol to be deleted
  6190. //
  6191. pos = m_RmProtIfList.GetHeadPosition();
  6192. while (pos)
  6193. {
  6194. posRmProtIf = pos;
  6195. spRmProtIf.Set( m_RmProtIfList.GetNext(pos) );
  6196. if (spRmProtIf->GetProtocolId() == dwProtocolId)
  6197. break;
  6198. spRmProtIf.Release();
  6199. }
  6200. if (spRmProtIf == NULL)
  6201. CORg( E_INVALIDARG );
  6202. //
  6203. // Save the updated information, removing the protocol's block
  6204. //
  6205. if (fRemove)
  6206. {
  6207. hr= Save(GetMachineName(),
  6208. m_hMachineConfig,
  6209. m_hInterface,
  6210. m_hIfTransport,
  6211. NULL,
  6212. dwProtocolId) ;
  6213. if (!FHrSucceeded(hr) &&
  6214. (hr != HRESULT_FROM_WIN32(ERROR_NO_SUCH_INTERFACE)))
  6215. CORg(hr);
  6216. }
  6217. //
  6218. // Remove the protocol from our list
  6219. //
  6220. m_RmProtIfList.RemoveAt(posRmProtIf);
  6221. spRmProtIf->Destruct();
  6222. spRmProtIf->ReleaseWeakRef();
  6223. m_AdviseList.NotifyChange(ROUTER_CHILD_DELETE, ROUTER_OBJ_RmProtIf, 0);
  6224. // Also need to advise the RmProt
  6225. if (m_pInterfaceInfoParent)
  6226. {
  6227. hrT = m_pInterfaceInfoParent->GetParentRouterInfo(&spRouterInfo);
  6228. if (FHrOK(hrT))
  6229. hrT = LookupRtrMgrProtocol(spRouterInfo,
  6230. spRmProtIf->GetTransportId(),
  6231. spRmProtIf->GetProtocolId(),
  6232. &spRmProt);
  6233. if (FHrOK(hrT))
  6234. spRmProt->RtrNotify(ROUTER_CHILD_DELETE, ROUTER_OBJ_RmProtIf, 0);
  6235. }
  6236. Assert(FindRtrMgrProtocolInterface(dwProtocolId, NULL) != hrOK);
  6237. COM_PROTECT_ERROR_LABEL;
  6238. }
  6239. COM_PROTECT_CATCH;
  6240. return hr;
  6241. }
  6242. /*!--------------------------------------------------------------------------
  6243. RtrMgrInterfaceInfo::ReleaseRtrMgrProtocolInterface
  6244. This function will release the AddRef() that this object has
  6245. on the child. This allows us to transfer child objects from
  6246. one router to another.
  6247. Author: KennT
  6248. ---------------------------------------------------------------------------*/
  6249. STDMETHODIMP RtrMgrInterfaceInfo::ReleaseRtrMgrProtocolInterface( DWORD dwProtocolId )
  6250. {
  6251. HRESULT hr = hrOK;
  6252. POSITION pos, posRmProtIf;
  6253. SPIRtrMgrProtocolInterfaceInfo spRmProtIf;
  6254. COM_PROTECT_TRY
  6255. {
  6256. pos = m_RmProtIfList.GetHeadPosition();
  6257. while (pos)
  6258. {
  6259. // Save the position (so that we can delete it)
  6260. posRmProtIf = pos;
  6261. spRmProtIf.Set( m_RmProtIfList.GetNext(pos) );
  6262. if (spRmProtIf &&
  6263. (spRmProtIf->GetProtocolId() == dwProtocolId))
  6264. {
  6265. // When releasing, we need to disconnect (since the
  6266. // main handle is controlled by the router info).
  6267. spRmProtIf->DoDisconnect();
  6268. spRmProtIf->ReleaseWeakRef();
  6269. spRmProtIf.Release();
  6270. // release this node from the list
  6271. m_RmProtIfList.RemoveAt(posRmProtIf);
  6272. break;
  6273. }
  6274. spRmProtIf.Release();
  6275. }
  6276. }
  6277. COM_PROTECT_CATCH;
  6278. return hr;
  6279. }
  6280. /*!--------------------------------------------------------------------------
  6281. RtrMgrInterfaceInfo::RtrAdvise
  6282. -
  6283. Author: KennT
  6284. ---------------------------------------------------------------------------*/
  6285. STDMETHODIMP RtrMgrInterfaceInfo::RtrAdvise( IRtrAdviseSink *pRtrAdviseSink,
  6286. LONG_PTR *pulConnection,
  6287. LPARAM lUserParam)
  6288. {
  6289. Assert(pRtrAdviseSink);
  6290. Assert(pulConnection);
  6291. RtrCriticalSection rtrCritSec(&m_critsec);
  6292. LONG_PTR ulConnId;
  6293. HRESULT hr = hrOK;
  6294. COM_PROTECT_TRY
  6295. {
  6296. ulConnId = (LONG_PTR) InterlockedIncrement(&s_cConnections);
  6297. CORg( m_AdviseList.AddConnection(pRtrAdviseSink, ulConnId, lUserParam) );
  6298. *pulConnection = ulConnId;
  6299. COM_PROTECT_ERROR_LABEL;
  6300. }
  6301. COM_PROTECT_CATCH;
  6302. return hr;
  6303. }
  6304. /*!--------------------------------------------------------------------------
  6305. RtrMgrInterfaceInfo::RtrNotify
  6306. -
  6307. Author: KennT
  6308. ---------------------------------------------------------------------------*/
  6309. STDMETHODIMP RtrMgrInterfaceInfo::RtrNotify(DWORD dwChangeType, DWORD dwObjectType,
  6310. LPARAM lParam)
  6311. {
  6312. RtrCriticalSection rtrCritSec(&m_critsec);
  6313. HRESULT hr = hrOK;
  6314. COM_PROTECT_TRY
  6315. {
  6316. m_AdviseList.NotifyChange(dwChangeType, dwObjectType, lParam);
  6317. }
  6318. COM_PROTECT_CATCH;
  6319. return hr;
  6320. }
  6321. /*!--------------------------------------------------------------------------
  6322. RtrMgrInterfaceInfo::RtrUnadvise
  6323. -
  6324. Author: KennT
  6325. ---------------------------------------------------------------------------*/
  6326. STDMETHODIMP RtrMgrInterfaceInfo::RtrUnadvise( LONG_PTR ulConnection)
  6327. {
  6328. RtrCriticalSection rtrCritSec(&m_critsec);
  6329. return m_AdviseList.RemoveConnection(ulConnection);
  6330. }
  6331. /*!--------------------------------------------------------------------------
  6332. RtrMgrInterfaceInfo::LoadRtrMgrInterfaceInfo
  6333. -
  6334. Author: KennT
  6335. ---------------------------------------------------------------------------*/
  6336. HRESULT RtrMgrInterfaceInfo::LoadRtrMgrInterfaceInfo(HANDLE hMachine,
  6337. HANDLE hInterface,
  6338. HANDLE hIfTransport)
  6339. {
  6340. RtrCriticalSection rtrCritSec(&m_critsec);
  6341. DWORD dwErr;
  6342. SPIInfoBase spInterfaceInfoBase;
  6343. HRESULT hr = hrOK;
  6344. SPIEnumInfoBlock spEnumBlock;
  6345. SPIRouterInfo spRouterInfo;
  6346. SPIEnumRtrMgrProtocolCB spEnumRmProtCB;
  6347. SRtrMgrProtocolCBList SRmProtCBList;
  6348. InfoBlock * pInfoBlock;
  6349. RtrMgrProtocolCB rmprotCB;
  6350. SPIRtrMgrProtocolInterfaceInfo spRmProtIf;
  6351. //
  6352. // If the caller doesn't want the data for the router-manager,
  6353. // and we need to reload, use the infobase on the stack.
  6354. // Otherwise, create an infobase to be loaded and returned to the caller
  6355. //
  6356. CORg( GetInfoBase(hMachine, hInterface, hIfTransport, &spInterfaceInfoBase) );
  6357. //
  6358. // Now we need to build the list of protocols active on this interface,
  6359. // by examining the blocks in the interface's data.
  6360. //
  6361. // Get a list of the blocks in the interface info
  6362. //
  6363. CORg( spInterfaceInfoBase->QueryBlockList(&spEnumBlock) );
  6364. //
  6365. // Get a list of the routing-protocols installed
  6366. //
  6367. // If possible, we use the routing-protocol control-block list
  6368. // loaded by our containing 'CRouterInfo', to save us from
  6369. // having to load our own in order to interpret the protocols' blocks
  6370. // inside the 'GlobalInfo'.
  6371. //
  6372. // Traverse back through the object hierarchy to get our RouterInfo
  6373. // object
  6374. if (m_pInterfaceInfoParent)
  6375. {
  6376. m_pInterfaceInfoParent->GetParentRouterInfo(&spRouterInfo);
  6377. }
  6378. if (spRouterInfo)
  6379. {
  6380. CORg( spRouterInfo->EnumRtrMgrProtocolCB(&spEnumRmProtCB) );
  6381. }
  6382. else
  6383. {
  6384. CORg( RouterInfo::LoadInstalledRtrMgrProtocolList(GetMachineName(),
  6385. GetTransportId(),
  6386. &SRmProtCBList,
  6387. spRouterInfo) );
  6388. CORg( CreateEnumFromSRmProtCBList(&SRmProtCBList, &spEnumRmProtCB) );
  6389. }
  6390. //
  6391. // Go through the blocks and for each one, see if the block type
  6392. // is the same as the protocol ID for some protocol
  6393. //
  6394. spEnumBlock->Reset();
  6395. while (spEnumBlock->Next(1, &pInfoBlock, NULL) == hrOK)
  6396. {
  6397. //
  6398. // When a routing protocol is removed, its block is left in place,
  6399. // but with zero-length data.
  6400. // We skip such blocks since they don't represent installed protocols.
  6401. //
  6402. if (pInfoBlock->dwSize == 0)
  6403. continue;
  6404. //
  6405. // Look through the installed protocols for a protocol
  6406. // whose ID is the same as this block's type
  6407. //
  6408. spEnumRmProtCB->Reset();
  6409. while (spEnumRmProtCB->Next(1, &rmprotCB, NULL) == hrOK)
  6410. {
  6411. //
  6412. // If this isn't what we're looking for, continue
  6413. //
  6414. if ((pInfoBlock->dwType != rmprotCB.dwProtocolId) ||
  6415. (GetTransportId() != rmprotCB.dwTransportId))
  6416. continue;
  6417. //
  6418. // This is the block we're looking for;
  6419. // construct a CRmProtInterfaceInfo using the control block
  6420. //
  6421. RtrMgrProtocolInterfaceInfo *pRmProtIf = new
  6422. RtrMgrProtocolInterfaceInfo(rmprotCB.dwProtocolId,
  6423. rmprotCB.szId,
  6424. GetTransportId(),
  6425. rmprotCB.szRtrMgrId,
  6426. GetInterfaceId(),
  6427. GetInterfaceType(),
  6428. this);
  6429. spRmProtIf = pRmProtIf;
  6430. spRmProtIf->SetFlags(RouterSnapin_InSyncWithRouter);
  6431. pRmProtIf->m_cb.stTitle = rmprotCB.szTitle;
  6432. //
  6433. // Add the new protocol to our list
  6434. //
  6435. m_RmProtIfList.AddTail(pRmProtIf);
  6436. pRmProtIf->AddWeakRef();
  6437. spRmProtIf.Release();
  6438. NotifyOfRmProtIfAdd(pRmProtIf, m_pInterfaceInfoParent);
  6439. break;
  6440. }
  6441. }
  6442. Error:
  6443. //
  6444. // Empty the list if we got data for it
  6445. //
  6446. if (!SRmProtCBList.IsEmpty())
  6447. {
  6448. while (!SRmProtCBList.IsEmpty())
  6449. delete SRmProtCBList.RemoveHead();
  6450. }
  6451. return hr;
  6452. }
  6453. /*!--------------------------------------------------------------------------
  6454. RtrMgrInterfaceInfo::SaveRtrMgrInterfaceInfo
  6455. -
  6456. This function saves a router-manager's interface information,
  6457. removing blocks for protocols which have been deleted,
  6458. given an infobase derived from CInfoBase.
  6459. Author: KennT
  6460. ---------------------------------------------------------------------------*/
  6461. HRESULT RtrMgrInterfaceInfo::SaveRtrMgrInterfaceInfo(HANDLE hMachine,
  6462. HANDLE hInterface,
  6463. HANDLE hIfTransport,
  6464. IInfoBase *pInterfaceInfoBase,
  6465. DWORD dwDeleteProtocolId)
  6466. {
  6467. RtrCriticalSection rtrCritSec(&m_critsec);
  6468. HRESULT hr = hrOK;
  6469. SPIInfoBase spIfInfoBase;
  6470. LPBYTE pIfBytes = NULL;
  6471. DWORD dwIfBytesSize = 0;
  6472. //
  6473. // If the caller wants a protocol's block to be deleted first,
  6474. // do so before saving the data.
  6475. //
  6476. if (dwDeleteProtocolId)
  6477. {
  6478. //
  6479. // If no data was given but we've been asked to delete a protocol,
  6480. // we need to load the existing data, so that the protocol's block
  6481. // can be removed from the infobase.
  6482. //
  6483. if (pInterfaceInfoBase == NULL)
  6484. {
  6485. CORg( CreateInfoBase(&spIfInfoBase) );
  6486. pInterfaceInfoBase = spIfInfoBase;
  6487. //
  6488. // Retrieve the existing data
  6489. //
  6490. CWRg( ::MprConfigInterfaceTransportGetInfo(
  6491. hMachine,
  6492. hInterface,
  6493. hIfTransport,
  6494. &pIfBytes,
  6495. &dwIfBytesSize
  6496. ) );
  6497. //
  6498. // Parse the data into a list of blocks
  6499. //
  6500. CWRg( pInterfaceInfoBase->LoadFrom(dwIfBytesSize, pIfBytes) );
  6501. }
  6502. //
  6503. // Delete the protocol specified
  6504. //
  6505. pInterfaceInfoBase->SetData(dwDeleteProtocolId, 0, NULL, 0, 0);
  6506. }
  6507. //
  6508. // Convert the CInfoBase to a byte-array
  6509. //
  6510. if (pInterfaceInfoBase)
  6511. CWRg( pInterfaceInfoBase->WriteTo(&pIfBytes, &dwIfBytesSize) );
  6512. //
  6513. // Save the information to the persistent store
  6514. //
  6515. CWRg( ::MprConfigInterfaceTransportSetInfo(
  6516. hMachine,
  6517. hInterface,
  6518. hIfTransport,
  6519. pIfBytes,
  6520. dwIfBytesSize
  6521. ) );
  6522. //
  6523. // Update the info of the running router-manager
  6524. //
  6525. if (pInterfaceInfoBase)
  6526. CWRg( SetInfo(dwIfBytesSize, pIfBytes) );
  6527. // We have now saved the information to the registry and to
  6528. // the running router. We now mark it as such.
  6529. m_dwFlags |= RouterSnapin_InSyncWithRouter;
  6530. Error:
  6531. CoTaskMemFree( pIfBytes );
  6532. return hr;
  6533. }
  6534. /*!--------------------------------------------------------------------------
  6535. RtrMgrInterfaceInfo::TryToConnect
  6536. -
  6537. Author: KennT
  6538. ---------------------------------------------------------------------------*/
  6539. HRESULT RtrMgrInterfaceInfo::TryToConnect(LPCWSTR pswzMachine, HANDLE *phMachine)
  6540. {
  6541. RtrCriticalSection rtrCritSec(&m_critsec);
  6542. HRESULT hr = hrOK;
  6543. if (m_hMachineConfig)
  6544. *phMachine = m_hMachineConfig;
  6545. else if (*phMachine)
  6546. {
  6547. m_hMachineConfig = *phMachine;
  6548. m_bDisconnect = FALSE;
  6549. }
  6550. else
  6551. {
  6552. //$ Review: kennt, this function does not take a LPCWSTR,
  6553. // is this a mistake or does it modify the parameters?
  6554. CWRg( ::MprConfigServerConnect((LPWSTR) pswzMachine, phMachine) );
  6555. m_hMachineConfig = *phMachine;
  6556. m_bDisconnect = TRUE;
  6557. }
  6558. Error:
  6559. return hr;
  6560. }
  6561. /*!--------------------------------------------------------------------------
  6562. RtrMgrInterfaceInfo::NotifyOfRmProtIfAdd
  6563. -
  6564. Author: KennT
  6565. ---------------------------------------------------------------------------*/
  6566. HRESULT RtrMgrInterfaceInfo::NotifyOfRmProtIfAdd(IRtrMgrProtocolInterfaceInfo *pRmProtIf,
  6567. IInterfaceInfo *pParentIf)
  6568. {
  6569. HRESULT hr = hrOK;
  6570. m_AdviseList.NotifyChange(ROUTER_CHILD_ADD, ROUTER_OBJ_RmProtIf, 0);
  6571. // Also notify the RtrMgrProtocol object that interfaces have
  6572. // been added.
  6573. if (pParentIf)
  6574. {
  6575. SPIRouterInfo spRouterInfo;
  6576. SPIRtrMgrProtocolInfo spRmProtInfo;
  6577. HRESULT hrT; // this hr is ignored
  6578. // If these calls fail, it doesn't matter the operation still
  6579. // is considered successful
  6580. hrT = pParentIf->GetParentRouterInfo(&spRouterInfo);
  6581. if (FHrSucceeded(hrT))
  6582. {
  6583. hrT = LookupRtrMgrProtocol(spRouterInfo,
  6584. pRmProtIf->GetTransportId(),
  6585. pRmProtIf->GetProtocolId(),
  6586. &spRmProtInfo);
  6587. }
  6588. if (FHrOK(hrT))
  6589. hrT = spRmProtInfo->RtrNotify(ROUTER_CHILD_ADD,
  6590. ROUTER_OBJ_RmProtIf, 0);
  6591. }
  6592. return hr;
  6593. }
  6594. /*!--------------------------------------------------------------------------
  6595. RtrMgrInterfaceInfo::TryToGetIfHandle
  6596. -
  6597. Author: KennT
  6598. ---------------------------------------------------------------------------*/
  6599. HRESULT RtrMgrInterfaceInfo::TryToGetIfHandle(HANDLE hMachine,
  6600. LPCWSTR pswzInterface,
  6601. HANDLE *phInterface)
  6602. {
  6603. RtrCriticalSection rtrCritSec(&m_critsec);
  6604. HRESULT hr = hrOK;
  6605. if (m_hInterface)
  6606. *phInterface = m_hInterface;
  6607. else if (*phInterface)
  6608. m_hInterface = *phInterface;
  6609. else
  6610. {
  6611. //
  6612. // Get a handle to the interface
  6613. //
  6614. CWRg(::MprConfigInterfaceGetHandle(hMachine,
  6615. (LPWSTR) pswzInterface,
  6616. phInterface
  6617. ) );
  6618. m_hInterface = *phInterface;
  6619. }
  6620. Error:
  6621. return hr;
  6622. }
  6623. /*!--------------------------------------------------------------------------
  6624. RtrMgrInterfaceInfo::GetParentInterfaceInfo
  6625. -
  6626. Author: KennT
  6627. ---------------------------------------------------------------------------*/
  6628. STDMETHODIMP RtrMgrInterfaceInfo::GetParentInterfaceInfo(IInterfaceInfo **ppParent)
  6629. {
  6630. RtrCriticalSection rtrCritSec(&m_critsec);
  6631. *ppParent = m_pInterfaceInfoParent;
  6632. if (*ppParent)
  6633. (*ppParent)->AddRef();
  6634. return hrOK;
  6635. }
  6636. /*!--------------------------------------------------------------------------
  6637. RtrMgrInterfaceInfo::SetParentInterfaceInfo
  6638. -
  6639. Author: KennT
  6640. ---------------------------------------------------------------------------*/
  6641. STDMETHODIMP RtrMgrInterfaceInfo::SetParentInterfaceInfo(IInterfaceInfo *pParent)
  6642. {
  6643. RtrCriticalSection rtrCritSec(&m_critsec);
  6644. IInterfaceInfo * pTemp;
  6645. pTemp = m_pInterfaceInfoParent;
  6646. m_pInterfaceInfoParent = NULL;
  6647. if (m_fStrongRef)
  6648. {
  6649. if (pTemp)
  6650. pTemp->Release();
  6651. if (pParent)
  6652. pParent->AddRef();
  6653. }
  6654. else
  6655. {
  6656. if (pTemp)
  6657. pTemp->ReleaseWeakRef();
  6658. if (pParent)
  6659. pParent->AddWeakRef();
  6660. }
  6661. m_pInterfaceInfoParent = pParent;
  6662. return hrOK;
  6663. }
  6664. /*!--------------------------------------------------------------------------
  6665. RtrMgrInterfaceInfo::Disconnect
  6666. -
  6667. Author: KennT
  6668. ---------------------------------------------------------------------------*/
  6669. void RtrMgrInterfaceInfo::Disconnect()
  6670. {
  6671. if (m_bDisconnect && m_hMachineConfig)
  6672. ::MprConfigServerDisconnect(m_hMachineConfig);
  6673. m_bDisconnect = FALSE;
  6674. m_hMachineConfig = NULL;
  6675. m_hInterface = NULL;
  6676. m_hIfTransport = NULL;
  6677. }
  6678. /*!--------------------------------------------------------------------------
  6679. RtrMgrInterfaceInfo::DoDisconnect
  6680. -
  6681. Author: KennT
  6682. ---------------------------------------------------------------------------*/
  6683. STDMETHODIMP RtrMgrInterfaceInfo::DoDisconnect()
  6684. {
  6685. HRESULT hr = hrOK;
  6686. SPIEnumRtrMgrProtocolInterfaceInfo spEnumRmProtIf;
  6687. SPIRtrMgrProtocolInterfaceInfo spRmProtIf;
  6688. COM_PROTECT_TRY
  6689. {
  6690. // Disconnect our data.
  6691. // ------------------------------------------------------------
  6692. Disconnect();
  6693. // Notify the advise sinks of a disconnect.
  6694. // ------------------------------------------------------------
  6695. RtrNotify(ROUTER_DO_DISCONNECT, 0, 0);
  6696. // Now tell all child objects to disconnect.
  6697. // ------------------------------------------------------------
  6698. HRESULT hrIter = hrOK;
  6699. EnumRtrMgrProtocolInterface(&spEnumRmProtIf);
  6700. spEnumRmProtIf->Reset();
  6701. while (spEnumRmProtIf->Next(1, &spRmProtIf, NULL) == hrOK)
  6702. {
  6703. spRmProtIf->DoDisconnect();
  6704. spRmProtIf.Release();
  6705. }
  6706. }
  6707. COM_PROTECT_CATCH;
  6708. return hr;
  6709. }
  6710. /*!--------------------------------------------------------------------------
  6711. RtrMgrInterfaceInfo::TryToGetAllHandles
  6712. -
  6713. Author: KennT
  6714. ---------------------------------------------------------------------------*/
  6715. HRESULT RtrMgrInterfaceInfo::TryToGetAllHandles(LPCOLESTR pszMachine,
  6716. HANDLE *phMachine,
  6717. HANDLE *phInterface,
  6718. HANDLE *phTransport)
  6719. {
  6720. HRESULT hr = hrOK;
  6721. Assert(phMachine);
  6722. Assert(phInterface);
  6723. //
  6724. // If already loaded, the handle passed in is ignored.
  6725. //
  6726. // Otherwise, if 'hMachine' was not specified, connect to the config
  6727. // on the specified machine
  6728. //
  6729. CORg( TryToConnect(pszMachine, phMachine) );
  6730. //
  6731. // If already loaded, the handle passed in is ignored;
  6732. //
  6733. // Otherwise, if 'hInterface' was not specified,
  6734. // get the interface handle
  6735. //
  6736. CORg( TryToGetIfHandle(*phMachine, GetInterfaceId(), phInterface) );
  6737. //
  6738. // Get a handle to the interface-transport
  6739. //
  6740. //
  6741. // If 'hIfTransport' was not specified, connect
  6742. //
  6743. if (phTransport)
  6744. {
  6745. if (m_hIfTransport)
  6746. *phTransport = m_hIfTransport;
  6747. else if (*phTransport)
  6748. m_hIfTransport = *phTransport;
  6749. else
  6750. {
  6751. //
  6752. // Get a handle to the interface-transport
  6753. //
  6754. CWRg( ::MprConfigInterfaceTransportGetHandle(
  6755. *phMachine,
  6756. *phInterface,
  6757. GetTransportId(),
  6758. phTransport
  6759. ) );
  6760. m_hIfTransport = *phTransport;
  6761. }
  6762. }
  6763. Error:
  6764. return hr;
  6765. }
  6766. /*---------------------------------------------------------------------------
  6767. IRtrMgrProtocolInterfaceInfo Implementation
  6768. ---------------------------------------------------------------------------*/
  6769. TFSCORE_API(HRESULT) CreateRtrMgrProtocolInterfaceInfo(
  6770. IRtrMgrProtocolInterfaceInfo **ppRmProtIfInfo,
  6771. const RtrMgrProtocolInterfaceCB *pRmProtIfCB)
  6772. {
  6773. Assert(ppRmProtIfInfo);
  6774. Assert(pRmProtIfCB);
  6775. HRESULT hr = hrOK;
  6776. IRtrMgrProtocolInterfaceInfo * pRmProtIf = NULL;
  6777. USES_CONVERSION;
  6778. COM_PROTECT_TRY
  6779. {
  6780. *ppRmProtIfInfo = new RtrMgrProtocolInterfaceInfo(
  6781. pRmProtIfCB->dwProtocolId,
  6782. W2CT(pRmProtIfCB->szId),
  6783. pRmProtIfCB->dwTransportId,
  6784. W2CT(pRmProtIfCB->szRtrMgrId),
  6785. W2CT(pRmProtIfCB->szInterfaceId),
  6786. pRmProtIfCB->dwIfType,
  6787. NULL);
  6788. }
  6789. COM_PROTECT_CATCH;
  6790. return hr;
  6791. }
  6792. IMPLEMENT_WEAKREF_ADDREF_RELEASE(RtrMgrProtocolInterfaceInfo)
  6793. IMPLEMENT_SIMPLE_QUERYINTERFACE(RtrMgrProtocolInterfaceInfo, IRtrMgrProtocolInterfaceInfo)
  6794. DEBUG_DECLARE_INSTANCE_COUNTER(RtrMgrProtocolInterfaceInfo)
  6795. RtrMgrProtocolInterfaceInfo::RtrMgrProtocolInterfaceInfo(DWORD dwProtocolId,
  6796. LPCTSTR pszId,
  6797. DWORD dwTransportId,
  6798. LPCTSTR pszRmId,
  6799. LPCTSTR pszIfId,
  6800. DWORD dwIfType,
  6801. RtrMgrInterfaceInfo *pRmIf)
  6802. : m_dwFlags(0)
  6803. {
  6804. m_cb.dwProtocolId = dwProtocolId;
  6805. m_cb.stId = pszId;
  6806. m_cb.dwTransportId = dwTransportId;
  6807. m_cb.stRtrMgrId = pszRmId;
  6808. m_cb.stInterfaceId = pszIfId;
  6809. m_cb.dwIfType = dwIfType;
  6810. DEBUG_INCREMENT_INSTANCE_COUNTER(RtrMgrProtocolInterfaceInfo);
  6811. m_pRtrMgrInterfaceInfoParent = pRmIf;
  6812. if (m_pRtrMgrInterfaceInfoParent)
  6813. m_pRtrMgrInterfaceInfoParent->AddRef();
  6814. InitializeCriticalSection(&m_critsec);
  6815. }
  6816. RtrMgrProtocolInterfaceInfo::~RtrMgrProtocolInterfaceInfo()
  6817. {
  6818. Assert(m_pRtrMgrInterfaceInfoParent == NULL);
  6819. Destruct();
  6820. DEBUG_DECREMENT_INSTANCE_COUNTER(RtrMgrProtocolInterfaceInfo);
  6821. DeleteCriticalSection(&m_critsec);
  6822. }
  6823. void RtrMgrProtocolInterfaceInfo::ReviveStrongRef()
  6824. {
  6825. RtrCriticalSection rtrCritSec(&m_critsec);
  6826. if (m_pRtrMgrInterfaceInfoParent)
  6827. {
  6828. CONVERT_TO_STRONGREF(m_pRtrMgrInterfaceInfoParent);
  6829. }
  6830. }
  6831. void RtrMgrProtocolInterfaceInfo::OnLastStrongRef()
  6832. {
  6833. RtrCriticalSection rtrCritSec(&m_critsec);
  6834. if (m_pRtrMgrInterfaceInfoParent)
  6835. {
  6836. CONVERT_TO_WEAKREF(m_pRtrMgrInterfaceInfoParent);
  6837. }
  6838. if (m_fDestruct)
  6839. Destruct();
  6840. }
  6841. STDMETHODIMP RtrMgrProtocolInterfaceInfo::Destruct()
  6842. {
  6843. RtrCriticalSection rtrCritSec(&m_critsec);
  6844. IRtrMgrInterfaceInfo * pParent;
  6845. m_fDestruct = TRUE;
  6846. if (!m_fStrongRef)
  6847. {
  6848. pParent = m_pRtrMgrInterfaceInfoParent;
  6849. m_pRtrMgrInterfaceInfoParent = NULL;
  6850. if (pParent)
  6851. pParent->ReleaseWeakRef();
  6852. // Unload();
  6853. }
  6854. return hrOK;
  6855. }
  6856. STDMETHODIMP_(DWORD) RtrMgrProtocolInterfaceInfo::GetFlags()
  6857. {
  6858. RtrCriticalSection rtrCritSec(&m_critsec);
  6859. return m_dwFlags;
  6860. }
  6861. STDMETHODIMP RtrMgrProtocolInterfaceInfo::SetFlags(DWORD dwFlags)
  6862. {
  6863. RtrCriticalSection rtrCritSec(&m_critsec);
  6864. HRESULT hr = hrOK;
  6865. COM_PROTECT_TRY
  6866. {
  6867. m_dwFlags = dwFlags;
  6868. }
  6869. COM_PROTECT_CATCH;
  6870. return hr;
  6871. }
  6872. /*!--------------------------------------------------------------------------
  6873. RtrMgrProtocolInterfaceInfo::GetProtocolId
  6874. -
  6875. Author: KennT
  6876. ---------------------------------------------------------------------------*/
  6877. STDMETHODIMP_(DWORD) RtrMgrProtocolInterfaceInfo::GetProtocolId()
  6878. {
  6879. RtrCriticalSection rtrCritSec(&m_critsec);
  6880. return m_cb.dwProtocolId;
  6881. }
  6882. /*!--------------------------------------------------------------------------
  6883. RtrMgrProtocolInterfaceInfo::GetTransportId
  6884. -
  6885. Author: KennT
  6886. ---------------------------------------------------------------------------*/
  6887. STDMETHODIMP_(DWORD) RtrMgrProtocolInterfaceInfo::GetTransportId()
  6888. {
  6889. RtrCriticalSection rtrCritSec(&m_critsec);
  6890. return m_cb.dwTransportId;
  6891. }
  6892. /*!--------------------------------------------------------------------------
  6893. RtrMgrProtocolInterfaceInfo::GetInterfaceId
  6894. -
  6895. Author: KennT
  6896. ---------------------------------------------------------------------------*/
  6897. STDMETHODIMP_(LPCOLESTR) RtrMgrProtocolInterfaceInfo::GetInterfaceId()
  6898. {
  6899. RtrCriticalSection rtrCritSec(&m_critsec);
  6900. return m_cb.stInterfaceId;
  6901. }
  6902. /*!--------------------------------------------------------------------------
  6903. RtrMgrProtocolInterfaceInfo::GetInterfaceType
  6904. -
  6905. Author: KennT
  6906. ---------------------------------------------------------------------------*/
  6907. STDMETHODIMP_(DWORD) RtrMgrProtocolInterfaceInfo::GetInterfaceType()
  6908. {
  6909. RtrCriticalSection rtrCritSec(&m_critsec);
  6910. return m_cb.dwIfType;
  6911. }
  6912. /*!--------------------------------------------------------------------------
  6913. RtrMgrProtocolInterfaceInfo::GetTitle
  6914. -
  6915. Author: KennT
  6916. ---------------------------------------------------------------------------*/
  6917. STDMETHODIMP_(LPCOLESTR) RtrMgrProtocolInterfaceInfo::GetTitle()
  6918. {
  6919. RtrCriticalSection rtrCritSec(&m_critsec);
  6920. return m_cb.stTitle;
  6921. }
  6922. /*!--------------------------------------------------------------------------
  6923. RtrMgrProtocolInterfaceInfo::SetTitle
  6924. -
  6925. Author: KennT
  6926. ---------------------------------------------------------------------------*/
  6927. STDMETHODIMP RtrMgrProtocolInterfaceInfo::SetTitle(LPCOLESTR pszTitle)
  6928. {
  6929. //$UNICODE
  6930. // This assumes that we are native UNICODE
  6931. // and that OLECHAR == WCHAR
  6932. RtrCriticalSection rtrCritSec(&m_critsec);
  6933. HRESULT hr = hrOK;
  6934. COM_PROTECT_TRY
  6935. {
  6936. m_cb.stTitle = pszTitle;
  6937. }
  6938. COM_PROTECT_CATCH;
  6939. return hr;
  6940. }
  6941. /*!--------------------------------------------------------------------------
  6942. RtrMgrProtocolInterfaceInfo::CopyCB
  6943. -
  6944. Author: KennT
  6945. ---------------------------------------------------------------------------*/
  6946. STDMETHODIMP RtrMgrProtocolInterfaceInfo::CopyCB(RtrMgrProtocolInterfaceCB * pRmProtCB)
  6947. {
  6948. RtrCriticalSection rtrCritSec(&m_critsec);
  6949. HRESULT hr = hrOK;
  6950. COM_PROTECT_TRY
  6951. {
  6952. m_cb.SaveTo(pRmProtCB);
  6953. }
  6954. COM_PROTECT_CATCH;
  6955. return hr;
  6956. }
  6957. /*!--------------------------------------------------------------------------
  6958. RtrMgrProtocolInterfaceInfo::RtrAdvise
  6959. -
  6960. Author: KennT
  6961. ---------------------------------------------------------------------------*/
  6962. STDMETHODIMP RtrMgrProtocolInterfaceInfo::RtrAdvise( IRtrAdviseSink *pRtrAdviseSink,
  6963. LONG_PTR *pulConnection, LPARAM lUserParam)
  6964. {
  6965. Assert(pRtrAdviseSink);
  6966. Assert(pulConnection);
  6967. RtrCriticalSection rtrCritSec(&m_critsec);
  6968. LONG_PTR ulConnId;
  6969. HRESULT hr = hrOK;
  6970. COM_PROTECT_TRY
  6971. {
  6972. ulConnId = (LONG_PTR) InterlockedIncrement(&s_cConnections);
  6973. CORg( m_AdviseList.AddConnection(pRtrAdviseSink, ulConnId, lUserParam) );
  6974. *pulConnection = ulConnId;
  6975. COM_PROTECT_ERROR_LABEL;
  6976. }
  6977. COM_PROTECT_CATCH;
  6978. return hr;
  6979. }
  6980. /*!--------------------------------------------------------------------------
  6981. RtrMgrProtocolInterfaceInfo::RtrNotify
  6982. -
  6983. Author: KennT
  6984. ---------------------------------------------------------------------------*/
  6985. STDMETHODIMP RtrMgrProtocolInterfaceInfo::RtrNotify(DWORD dwChangeType, DWORD dwObjectType,
  6986. LPARAM lParam)
  6987. {
  6988. RtrCriticalSection rtrCritSec(&m_critsec);
  6989. HRESULT hr = hrOK;
  6990. COM_PROTECT_TRY
  6991. {
  6992. m_AdviseList.NotifyChange(dwChangeType, dwObjectType, lParam);
  6993. }
  6994. COM_PROTECT_CATCH;
  6995. return hr;
  6996. }
  6997. /*!--------------------------------------------------------------------------
  6998. RtrMgrProtocolInterfaceInfo::RtrUnadvise
  6999. -
  7000. Author: KennT
  7001. ---------------------------------------------------------------------------*/
  7002. STDMETHODIMP RtrMgrProtocolInterfaceInfo::RtrUnadvise( LONG_PTR ulConnection)
  7003. {
  7004. RtrCriticalSection rtrCritSec(&m_critsec);
  7005. return m_AdviseList.RemoveConnection(ulConnection);
  7006. }
  7007. /*!--------------------------------------------------------------------------
  7008. RtrMgrProtocolInterfaceInfo::GetParentRtrMgrInterfaceInfo
  7009. -
  7010. Author: KennT
  7011. ---------------------------------------------------------------------------*/
  7012. STDMETHODIMP RtrMgrProtocolInterfaceInfo::GetParentRtrMgrInterfaceInfo( IRtrMgrInterfaceInfo **ppParent)
  7013. {
  7014. RtrCriticalSection rtrCritSec(&m_critsec);
  7015. HRESULT hr = hrOK;
  7016. COM_PROTECT_TRY
  7017. {
  7018. *ppParent = m_pRtrMgrInterfaceInfoParent;
  7019. if (*ppParent)
  7020. (*ppParent)->AddRef();
  7021. }
  7022. COM_PROTECT_CATCH;
  7023. return hr;
  7024. }
  7025. /*!--------------------------------------------------------------------------
  7026. RtrMgrProtocolInterfaceInfo::SetParentRtrMgrInterfaceInfo
  7027. -
  7028. Author: KennT
  7029. ---------------------------------------------------------------------------*/
  7030. STDMETHODIMP RtrMgrProtocolInterfaceInfo::SetParentRtrMgrInterfaceInfo(IRtrMgrInterfaceInfo *pParent)
  7031. {
  7032. RtrCriticalSection rtrCritSec(&m_critsec);
  7033. IRtrMgrInterfaceInfo * pTemp;
  7034. pTemp = m_pRtrMgrInterfaceInfoParent;
  7035. m_pRtrMgrInterfaceInfoParent = NULL;
  7036. if (m_fStrongRef)
  7037. {
  7038. if (pTemp)
  7039. pTemp->Release();
  7040. if (pParent)
  7041. pParent->AddRef();
  7042. }
  7043. else
  7044. {
  7045. if (pTemp)
  7046. pTemp->ReleaseWeakRef();
  7047. if (pParent)
  7048. pParent->AddWeakRef();
  7049. }
  7050. m_pRtrMgrInterfaceInfoParent = pParent;
  7051. return hrOK;
  7052. }
  7053. void RtrMgrProtocolInterfaceInfo::Disconnect()
  7054. {
  7055. }
  7056. STDMETHODIMP RtrMgrProtocolInterfaceInfo::DoDisconnect()
  7057. {
  7058. HRESULT hr = hrOK;
  7059. COM_PROTECT_TRY
  7060. {
  7061. // Disconnect our data.
  7062. // ------------------------------------------------------------
  7063. Disconnect();
  7064. // Notify the advise sinks of a disconnect.
  7065. // ------------------------------------------------------------
  7066. RtrNotify(ROUTER_DO_DISCONNECT, 0, 0);
  7067. }
  7068. COM_PROTECT_CATCH;
  7069. return hr;
  7070. }
  7071. /*!--------------------------------------------------------------------------
  7072. LoadInfoBase
  7073. -
  7074. Author: KennT
  7075. ---------------------------------------------------------------------------*/
  7076. TFSCORE_API(HRESULT) LoadInfoBase(HANDLE hMachine,
  7077. HANDLE hTransport,
  7078. IInfoBase **ppGlobalInfo,
  7079. IInfoBase **ppClientInfo)
  7080. {
  7081. HRESULT hr = hrOK;
  7082. SPIInfoBase spGlobalInfo;
  7083. SPIInfoBase spClientInfo;
  7084. DWORD dwGlobalBytesSize, dwClientBytesSize;
  7085. BYTE * pGlobalBytes = NULL;
  7086. BYTE * pClientBytes = NULL;
  7087. COM_PROTECT_TRY
  7088. {
  7089. if (ppGlobalInfo)
  7090. CORg( CreateInfoBase(&spGlobalInfo) );
  7091. if (ppClientInfo)
  7092. CORg( CreateInfoBase(&spClientInfo) );
  7093. //
  7094. // Retrieve information for the transport
  7095. //
  7096. CWRg( ::MprConfigTransportGetInfo(
  7097. hMachine,
  7098. hTransport,
  7099. spGlobalInfo ? &pGlobalBytes : NULL,
  7100. spGlobalInfo ? &dwGlobalBytesSize : NULL,
  7101. spClientInfo ? &pClientBytes : NULL,
  7102. spClientInfo ? &dwClientBytesSize : NULL,
  7103. NULL
  7104. ));
  7105. //
  7106. // Load the global info for the router-manager
  7107. //
  7108. if (spGlobalInfo)
  7109. {
  7110. CWRg( spGlobalInfo->LoadFrom(dwGlobalBytesSize, pGlobalBytes) );
  7111. }
  7112. //
  7113. // Load the client info for the router-manager
  7114. //
  7115. if (spClientInfo)
  7116. {
  7117. CWRg( spClientInfo->LoadFrom(dwClientBytesSize, pClientBytes) );
  7118. }
  7119. if (ppGlobalInfo)
  7120. *ppGlobalInfo = spGlobalInfo.Transfer();
  7121. if (ppClientInfo)
  7122. *ppClientInfo = spClientInfo.Transfer();
  7123. COM_PROTECT_ERROR_LABEL;
  7124. }
  7125. COM_PROTECT_CATCH;
  7126. if (pGlobalBytes) { ::MprConfigBufferFree(pGlobalBytes); }
  7127. if (pClientBytes) { ::MprConfigBufferFree(pClientBytes); }
  7128. return hr;
  7129. }