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.

1695 lines
46 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. ripview.cpp
  7. IPX RIP node implementation.
  8. FILE HISTORY:
  9. */
  10. #include "stdafx.h"
  11. #include "util.h"
  12. #include "ripview.h"
  13. #include "reg.h"
  14. #include "rtrutil.h" // smart MPR handle pointers
  15. #include "ripstrm.h" // IPAdminConfigStream
  16. #include "strmap.h" // XXXtoCString functions
  17. #include "service.h" // TFS service APIs
  18. #include "format.h" // FormatNumber function
  19. #include "coldlg.h" // columndlg
  20. #include "column.h" // ComponentConfigStream
  21. #include "rtrui.h"
  22. #include "ripprop.h" // RIP property pages
  23. #include "routprot.h" // IP_LOCAL
  24. #include "ipxstrm.h"
  25. #include "ipxutil.h" // String conversions
  26. #include "globals.h" // IPX defaults
  27. /*---------------------------------------------------------------------------
  28. Keep this in sync with the column ids in ripview.h
  29. ---------------------------------------------------------------------------*/
  30. extern const ContainerColumnInfo s_rgRipViewColumnInfo[];
  31. const ContainerColumnInfo s_rgRipViewColumnInfo[] =
  32. {
  33. { IDS_RIP_COL_INTERFACE, CON_SORT_BY_STRING, TRUE, COL_IF_NAME },
  34. { IDS_RIP_COL_TYPE, CON_SORT_BY_STRING, TRUE, COL_IF_DEVICE },
  35. { IDS_RIP_COL_ACCEPT_ROUTES, CON_SORT_BY_STRING, FALSE, COL_STRING },
  36. { IDS_RIP_COL_SUPPLY_ROUTES, CON_SORT_BY_STRING, FALSE, COL_STRING },
  37. { IDS_RIP_COL_UPDATE_MODE, CON_SORT_BY_STRING, TRUE, COL_STRING },
  38. { IDS_RIP_COL_UPDATE_PERIOD, CON_SORT_BY_DWORD, FALSE, COL_DURATION },
  39. { IDS_RIP_COL_AGE_MULTIPLIER, CON_SORT_BY_DWORD, FALSE, COL_SMALL_NUM },
  40. { IDS_RIP_COL_ADMIN_STATE, CON_SORT_BY_STRING, TRUE, COL_STATUS },
  41. { IDS_RIP_COL_OPER_STATE, CON_SORT_BY_STRING, TRUE, COL_STATUS },
  42. { IDS_RIP_COL_PACKETS_SENT, CON_SORT_BY_DWORD, TRUE, COL_LARGE_NUM },
  43. { IDS_RIP_COL_PACKETS_RECEIVED, CON_SORT_BY_DWORD, TRUE, COL_LARGE_NUM },
  44. };
  45. /*---------------------------------------------------------------------------
  46. RipNodeHandler implementation
  47. ---------------------------------------------------------------------------*/
  48. RipNodeHandler::RipNodeHandler(ITFSComponentData *pCompData)
  49. : BaseContainerHandler(pCompData, RIP_COLUMNS,
  50. s_rgRipViewColumnInfo),
  51. m_ulConnId(0),
  52. m_ulRmConnId(0),
  53. m_ulRefreshConnId(0),
  54. m_ulStatsConnId(0)
  55. {
  56. // Setup the verb states
  57. m_rgButtonState[MMC_VERB_PROPERTIES_INDEX] = ENABLED;
  58. m_bState[MMC_VERB_PROPERTIES_INDEX] = TRUE;
  59. m_rgButtonState[MMC_VERB_REFRESH_INDEX] = ENABLED;
  60. m_bState[MMC_VERB_REFRESH_INDEX] = TRUE;
  61. }
  62. STDMETHODIMP RipNodeHandler::QueryInterface(REFIID riid, LPVOID *ppv)
  63. {
  64. // Is the pointer bad?
  65. if (ppv == NULL)
  66. return E_INVALIDARG;
  67. // Place NULL in *ppv in case of failure
  68. *ppv = NULL;
  69. // This is the non-delegating IUnknown implementation
  70. if (riid == IID_IUnknown)
  71. *ppv = (LPVOID) this;
  72. else if (riid == IID_IRtrAdviseSink)
  73. *ppv = &m_IRtrAdviseSink;
  74. else
  75. return BaseContainerHandler::QueryInterface(riid, ppv);
  76. // If we're going to return an interface, AddRef it first
  77. if (*ppv)
  78. {
  79. ((LPUNKNOWN) *ppv)->AddRef();
  80. return hrOK;
  81. }
  82. else
  83. return E_NOINTERFACE;
  84. }
  85. /*!--------------------------------------------------------------------------
  86. RipNodeHandler::DestroyHandler
  87. Implementation of ITFSNodeHandler::DestroyHandler
  88. Author: KennT
  89. ---------------------------------------------------------------------------*/
  90. STDMETHODIMP RipNodeHandler::DestroyHandler(ITFSNode *pNode)
  91. {
  92. IPXConnection * pIPXConn;
  93. pIPXConn = GET_RIP_NODEDATA(pNode);
  94. pIPXConn->Release();
  95. if (m_ulRefreshConnId)
  96. {
  97. SPIRouterRefresh spRefresh;
  98. if (m_spRouterInfo)
  99. m_spRouterInfo->GetRefreshObject(&spRefresh);
  100. if (spRefresh)
  101. spRefresh->UnadviseRefresh(m_ulRefreshConnId);
  102. }
  103. m_ulRefreshConnId = 0;
  104. if (m_ulStatsConnId)
  105. {
  106. SPIRouterRefresh spRefresh;
  107. if (m_spRouterInfo)
  108. m_spRouterInfo->GetRefreshObject(&spRefresh);
  109. if (spRefresh)
  110. spRefresh->UnadviseRefresh(m_ulStatsConnId);
  111. }
  112. m_ulStatsConnId = 0;
  113. if (m_ulConnId)
  114. m_spRmProt->RtrUnadvise(m_ulConnId);
  115. m_ulConnId = 0;
  116. m_spRmProt.Release();
  117. if (m_ulRmConnId)
  118. m_spRm->RtrUnadvise(m_ulRmConnId);
  119. m_ulRmConnId = 0;
  120. m_spRm.Release();
  121. WaitForStatisticsWindow(&m_RIPParamsStats);
  122. m_spRouterInfo.Release();
  123. return hrOK;
  124. }
  125. /*!--------------------------------------------------------------------------
  126. RipNodeHandler::HasPropertyPages
  127. Implementation of ITFSNodeHandler::HasPropertyPages
  128. NOTE: the root node handler has to over-ride this function to
  129. handle the snapin manager property page (wizard) case!!!
  130. Author: KennT
  131. ---------------------------------------------------------------------------*/
  132. STDMETHODIMP
  133. RipNodeHandler::HasPropertyPages
  134. (
  135. ITFSNode * pNode,
  136. LPDATAOBJECT pDataObject,
  137. DATA_OBJECT_TYPES type,
  138. DWORD dwType
  139. )
  140. {
  141. return hrOK;
  142. }
  143. /*!--------------------------------------------------------------------------
  144. RipNodeHandler::CreatePropertyPages
  145. -
  146. Author: KennT
  147. ---------------------------------------------------------------------------*/
  148. STDMETHODIMP
  149. RipNodeHandler::CreatePropertyPages
  150. (
  151. ITFSNode * pNode,
  152. LPPROPERTYSHEETCALLBACK lpProvider,
  153. LPDATAOBJECT pDataObject,
  154. LONG_PTR handle,
  155. DWORD dwType
  156. )
  157. {
  158. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  159. HRESULT hr = hrOK;
  160. RipProperties * pProperties = NULL;
  161. SPIComponentData spComponentData;
  162. CString stTitle;
  163. CORg( m_spNodeMgr->GetComponentData(&spComponentData) );
  164. pProperties = new RipProperties(pNode, spComponentData,
  165. m_spTFSCompData, stTitle);
  166. CORg( pProperties->Init(m_spRm) );
  167. if (lpProvider)
  168. hr = pProperties->CreateModelessSheet(lpProvider, handle);
  169. else
  170. hr = pProperties->DoModelessSheet();
  171. Error:
  172. return hr;
  173. }
  174. /*---------------------------------------------------------------------------
  175. Menu data structure for our menus
  176. ---------------------------------------------------------------------------*/
  177. static const SRouterNodeMenu s_rgIfNodeMenu[] =
  178. {
  179. { IDS_MENU_RIP_SHOW_PARAMS, 0,
  180. CCM_INSERTIONPOINTID_PRIMARY_TOP },
  181. };
  182. /*!--------------------------------------------------------------------------
  183. RipNodeHandler::OnAddMenuItems
  184. Implementation of ITFSNodeHandler::OnAddMenuItems
  185. Author: KennT
  186. ---------------------------------------------------------------------------*/
  187. STDMETHODIMP RipNodeHandler::OnAddMenuItems(
  188. ITFSNode *pNode,
  189. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  190. LPDATAOBJECT lpDataObject,
  191. DATA_OBJECT_TYPES type,
  192. DWORD dwType,
  193. long *pInsertionAllowed)
  194. {
  195. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  196. HRESULT hr = S_OK;
  197. RipNodeHandler::SMenuData menuData;
  198. COM_PROTECT_TRY
  199. {
  200. menuData.m_spNode.Set(pNode);
  201. hr = AddArrayOfMenuItems(pNode, s_rgIfNodeMenu,
  202. DimensionOf(s_rgIfNodeMenu),
  203. pContextMenuCallback,
  204. *pInsertionAllowed,
  205. reinterpret_cast<INT_PTR>(&menuData));
  206. }
  207. COM_PROTECT_CATCH;
  208. return hr;
  209. }
  210. /*!--------------------------------------------------------------------------
  211. RipNodeHandler::OnCommand
  212. Implementation of ITFSNodeHandler::OnCommand
  213. Author: KennT
  214. ---------------------------------------------------------------------------*/
  215. STDMETHODIMP RipNodeHandler::OnCommand(ITFSNode *pNode, long nCommandId,
  216. DATA_OBJECT_TYPES type,
  217. LPDATAOBJECT pDataObject,
  218. DWORD dwType)
  219. {
  220. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  221. HRESULT hr = S_OK;
  222. COM_PROTECT_TRY
  223. {
  224. switch (nCommandId)
  225. {
  226. case IDS_MENU_RIP_SHOW_PARAMS:
  227. CreateNewStatisticsWindow(&m_RIPParamsStats,
  228. ::FindMMCMainWindow(),
  229. IDD_STATS_NARROW);
  230. break;
  231. case IDS_MENU_SYNC:
  232. SynchronizeNodeData(pNode);
  233. break;
  234. }
  235. }
  236. COM_PROTECT_CATCH;
  237. return hr;
  238. }
  239. /*!--------------------------------------------------------------------------
  240. RipNodeHandler::OnExpand
  241. -
  242. Author: KennT
  243. ---------------------------------------------------------------------------*/
  244. HRESULT RipNodeHandler::OnExpand(ITFSNode *pNode,
  245. LPDATAOBJECT pDataObject,
  246. DWORD dwType,
  247. LPARAM arg,
  248. LPARAM lParam)
  249. {
  250. HRESULT hr = hrOK;
  251. SPIEnumInterfaceInfo spEnumIf;
  252. SPIInterfaceInfo spIf;
  253. SPIRtrMgrInterfaceInfo spRmIf;
  254. SPIInfoBase spInfoBase;
  255. if (m_bExpanded)
  256. return hrOK;
  257. COM_PROTECT_TRY
  258. {
  259. CORg( m_spRouterInfo->EnumInterface(&spEnumIf) );
  260. while (spEnumIf->Next(1, &spIf, NULL) == hrOK)
  261. {
  262. if (spIf->FindRtrMgrInterface(PID_IPX, &spRmIf) == hrOK)
  263. {
  264. if (spRmIf->FindRtrMgrProtocolInterface(IPX_PROTOCOL_RIP, NULL) == hrOK)
  265. {
  266. // Now we create an interface node for this interface
  267. AddInterfaceNode(pNode, spIf, FALSE);
  268. }
  269. }
  270. spRmIf.Release();
  271. spIf.Release();
  272. }
  273. //$CLIENT: Add the client interface (setup default data)
  274. // the only thing that we can do in synchronize is to
  275. // get the Administrative status
  276. AddInterfaceNode(pNode, NULL, TRUE);
  277. m_bExpanded = TRUE;
  278. // Now that we have all of the nodes, update the data for
  279. // all of the nodes
  280. SynchronizeNodeData(pNode);
  281. COM_PROTECT_ERROR_LABEL;
  282. }
  283. COM_PROTECT_CATCH;
  284. m_bExpanded = TRUE;
  285. return hr;
  286. }
  287. /*!--------------------------------------------------------------------------
  288. RipNodeHandler::GetString
  289. Implementation of ITFSNodeHandler::GetString
  290. We don't need to do anything, since our root node is an extension
  291. only and thus can't do anything to the node text.
  292. Author: KennT
  293. ---------------------------------------------------------------------------*/
  294. STDMETHODIMP_(LPCTSTR) RipNodeHandler::GetString(ITFSNode *pNode, int nCol)
  295. {
  296. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  297. HRESULT hr = hrOK;
  298. COM_PROTECT_TRY
  299. {
  300. if (m_stTitle.IsEmpty())
  301. m_stTitle.LoadString(IDS_IPX_RIP_TITLE);
  302. }
  303. COM_PROTECT_CATCH;
  304. return m_stTitle;
  305. }
  306. /*!--------------------------------------------------------------------------
  307. RipNodeHandler::OnCreateDataObject
  308. -
  309. Author: KennT
  310. ---------------------------------------------------------------------------*/
  311. STDMETHODIMP RipNodeHandler::OnCreateDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, IDataObject **ppDataObject)
  312. {
  313. HRESULT hr = hrOK;
  314. COM_PROTECT_TRY
  315. {
  316. Assert(m_spRmProt);
  317. CORg( CreateDataObjectFromRtrMgrProtocolInfo(m_spRmProt,
  318. type, cookie, m_spTFSCompData,
  319. ppDataObject) );
  320. COM_PROTECT_ERROR_LABEL;
  321. }
  322. COM_PROTECT_CATCH;
  323. return hr;
  324. }
  325. /*!--------------------------------------------------------------------------
  326. RipNodeHandler::Init
  327. -
  328. Author: KennT
  329. ---------------------------------------------------------------------------*/
  330. HRESULT RipNodeHandler::Init(IRouterInfo *pRouter, RipConfigStream *pConfigStream)
  331. {
  332. m_spRouterInfo.Set(pRouter);
  333. m_spRm.Release();
  334. pRouter->FindRtrMgr(PID_IPX, &m_spRm);
  335. m_spRmProt.Release();
  336. m_spRm->FindRtrMgrProtocol(IPX_PROTOCOL_RIP, &m_spRmProt);
  337. m_pConfigStream = pConfigStream;
  338. // Also need to register for change notifications from IPX_PROTOCOL_RIP
  339. Assert(m_ulConnId == 0);
  340. m_spRmProt->RtrAdvise(&m_IRtrAdviseSink, &m_ulConnId, 0);
  341. // Need to register for change notifications on the Router manager
  342. // This way we can add the necessary protocols when an interface
  343. // gets added.
  344. Assert(m_ulRmConnId == 0);
  345. m_spRm->RtrAdvise(&m_IRtrAdviseSink, &m_ulRmConnId, 0);
  346. m_RIPParamsStats.SetConfigInfo(pConfigStream, RIPSTRM_STATS_RIPPARAMS);
  347. return hrOK;
  348. }
  349. /*!--------------------------------------------------------------------------
  350. RipNodeHandler::ConstructNode
  351. Initializes the root node (sets it up).
  352. Author: KennT
  353. ---------------------------------------------------------------------------*/
  354. HRESULT RipNodeHandler::ConstructNode(ITFSNode *pNode)
  355. {
  356. HRESULT hr = hrOK;
  357. IPXConnection * pIPXConn = NULL;
  358. if (pNode == NULL)
  359. return hrOK;
  360. COM_PROTECT_TRY
  361. {
  362. // Need to initialize the data for the root node
  363. pNode->SetData(TFS_DATA_IMAGEINDEX, IMAGE_IDX_IPX_NODE_GENERAL);
  364. pNode->SetData(TFS_DATA_OPENIMAGEINDEX, IMAGE_IDX_IPX_NODE_GENERAL);
  365. pNode->SetData(TFS_DATA_SCOPEID, 0);
  366. // This is a leaf node in the scope pane
  367. pNode->SetData(TFS_DATA_SCOPE_LEAF_NODE, TRUE);
  368. m_cookie = reinterpret_cast<DWORD_PTR>(pNode);
  369. pNode->SetData(TFS_DATA_COOKIE, m_cookie);
  370. pNode->SetNodeType(&GUID_IPXRipNodeType);
  371. pIPXConn = new IPXConnection;
  372. pIPXConn->SetMachineName(m_spRouterInfo->GetMachineName());
  373. SET_RIP_NODEDATA(pNode, pIPXConn);
  374. m_RIPParamsStats.SetConnectionData(pIPXConn);
  375. }
  376. COM_PROTECT_CATCH;
  377. if (!FHrSucceeded(hr))
  378. {
  379. SET_RIP_NODEDATA(pNode, NULL);
  380. if (pIPXConn)
  381. pIPXConn->Release();
  382. }
  383. return hr;
  384. }
  385. /*!--------------------------------------------------------------------------
  386. RipNodeHandler::AddInterfaceNode
  387. -
  388. Author: KennT
  389. ---------------------------------------------------------------------------*/
  390. HRESULT RipNodeHandler::AddInterfaceNode(ITFSNode *pParent,
  391. IInterfaceInfo *pIf,
  392. BOOL fClient)
  393. {
  394. Assert(pParent);
  395. RipInterfaceHandler * pHandler;
  396. SPITFSResultHandler spHandler;
  397. SPITFSNode spNode;
  398. HRESULT hr = hrOK;
  399. BaseIPXResultNodeData * pData;
  400. IPXConnection * pIPXConn;
  401. SPIInfoBase spInfoBase;
  402. PRIP_IF_CONFIG pric = NULL;
  403. SPIRtrMgrInterfaceInfo spRmIf;
  404. // Create the handler for this node
  405. pHandler = new RipInterfaceHandler(m_spTFSCompData);
  406. spHandler = pHandler;
  407. CORg( pHandler->Init(pIf, m_spRouterInfo, pParent) );
  408. pIPXConn = GET_RIP_NODEDATA(pParent);
  409. // Create a result item node (or a leaf node)
  410. CORg( CreateLeafTFSNode(&spNode,
  411. NULL,
  412. static_cast<ITFSNodeHandler *>(pHandler),
  413. static_cast<ITFSResultHandler *>(pHandler),
  414. m_spNodeMgr) );
  415. CORg( pHandler->ConstructNode(spNode, pIf, pIPXConn) );
  416. pData = GET_BASEIPXRESULT_NODEDATA(spNode);
  417. Assert(pData);
  418. ASSERT_BASEIPXRESULT_NODEDATA(pData);
  419. pData->m_fClient = fClient;
  420. // If we don't have an interface, then this is a client node
  421. if (pIf)
  422. {
  423. pIf->FindRtrMgrInterface(PID_IPX, &spRmIf);
  424. if (spRmIf)
  425. spRmIf->GetInfoBase(NULL, NULL, NULL, &spInfoBase);
  426. if (spInfoBase)
  427. spInfoBase->GetData(IPX_PROTOCOL_RIP, 0, (LPBYTE *) &pric);
  428. Trace1("Adding RIP node : %s\n", pIf->GetTitle());
  429. }
  430. else
  431. {
  432. // This is a client, make it visible
  433. pric = (PRIP_IF_CONFIG) ULongToPtr(0xFFFFFFFF);
  434. Trace0("Adding client interface\n");
  435. }
  436. // if pric == NULL, then we are adding this protocol to the
  437. // interface and we need to hide the node.
  438. if (pric)
  439. {
  440. CORg( spNode->SetVisibilityState(TFS_VIS_SHOW) );
  441. CORg( spNode->Show() );
  442. }
  443. else
  444. CORg( spNode->SetVisibilityState(TFS_VIS_HIDE) );
  445. CORg( pParent->AddChild(spNode) );
  446. Error:
  447. return hr;
  448. }
  449. /*---------------------------------------------------------------------------
  450. This is the set of menus that will appear when a right-click is
  451. done on the blank area of the result pane.
  452. ---------------------------------------------------------------------------*/
  453. static const SRouterNodeMenu s_rgRipResultNodeMenu[] =
  454. {
  455. { IDS_MENU_RIP_SHOW_PARAMS, 0,
  456. CCM_INSERTIONPOINTID_PRIMARY_TOP },
  457. };
  458. /*!--------------------------------------------------------------------------
  459. RipNodeHandler::AddMenuItems
  460. Implementation of ITFSResultHandler::AddMenuItems
  461. Use this to add commands to the context menu of the blank areas
  462. of the result pane.
  463. Author: KennT
  464. ---------------------------------------------------------------------------*/
  465. STDMETHODIMP RipNodeHandler::AddMenuItems(ITFSComponent *pComponent,
  466. MMC_COOKIE cookie,
  467. LPDATAOBJECT pDataObject,
  468. LPCONTEXTMENUCALLBACK pCallback,
  469. long *pInsertionAllowed)
  470. {
  471. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  472. HRESULT hr = hrOK;
  473. SPITFSNode spNode;
  474. RipNodeHandler::SMenuData menuData;
  475. COM_PROTECT_TRY
  476. {
  477. m_spNodeMgr->FindNode(cookie, &spNode);
  478. menuData.m_spNode.Set(spNode);
  479. hr = AddArrayOfMenuItems(spNode,
  480. s_rgRipResultNodeMenu,
  481. DimensionOf(s_rgRipResultNodeMenu),
  482. pCallback,
  483. *pInsertionAllowed,
  484. reinterpret_cast<INT_PTR>(&menuData));
  485. }
  486. COM_PROTECT_CATCH;
  487. return hr;
  488. }
  489. /*!--------------------------------------------------------------------------
  490. RipNodeHandler::Command
  491. -
  492. Author: KennT
  493. ---------------------------------------------------------------------------*/
  494. STDMETHODIMP RipNodeHandler::Command(ITFSComponent *pComponent,
  495. MMC_COOKIE cookie,
  496. int nCommandID,
  497. LPDATAOBJECT pDataObject)
  498. {
  499. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  500. SPITFSNode spNode;
  501. HRESULT hr = hrOK;
  502. switch (nCommandID)
  503. {
  504. case IDS_MENU_RIP_SHOW_PARAMS:
  505. CreateNewStatisticsWindow(&m_RIPParamsStats,
  506. ::FindMMCMainWindow(),
  507. IDD_STATS_NARROW);
  508. break;
  509. }
  510. return hr;
  511. }
  512. ImplementEmbeddedUnknown(RipNodeHandler, IRtrAdviseSink)
  513. STDMETHODIMP RipNodeHandler::EIRtrAdviseSink::OnChange(LONG_PTR ulConn,
  514. DWORD dwChangeType, DWORD dwObjectType, LPARAM lUserParam, LPARAM lParam)
  515. {
  516. InitPThis(RipNodeHandler, IRtrAdviseSink);
  517. SPITFSNode spThisNode;
  518. SPITFSNode spNode;
  519. SPITFSNodeEnum spEnumNode;
  520. SPIEnumInterfaceInfo spEnumIf;
  521. SPIInterfaceInfo spIf;
  522. SPIRtrMgrInterfaceInfo spRmIf;
  523. SPIInfoBase spInfoBase;
  524. BOOL fPleaseAdd;
  525. BOOL fFound;
  526. BaseIPXResultNodeData * pData;
  527. HRESULT hr = hrOK;
  528. pThis->m_spNodeMgr->FindNode(pThis->m_cookie, &spThisNode);
  529. if (dwObjectType == ROUTER_OBJ_RmIf)
  530. {
  531. if (dwChangeType == ROUTER_CHILD_PREADD)
  532. {
  533. // Add RIP to the infobase
  534. pThis->AddProtocolToInfoBase(spThisNode);
  535. }
  536. else if (dwChangeType == ROUTER_CHILD_ADD)
  537. {
  538. // Add the protocol to the router mgr
  539. // We need to add the protocol to the interface (use
  540. // default values).
  541. pThis->AddProtocolToInterface(spThisNode);
  542. }
  543. }
  544. if (dwObjectType == ROUTER_OBJ_RmProtIf)
  545. {
  546. if (dwChangeType == ROUTER_CHILD_ADD)
  547. {
  548. // If the node hasn't been expanded yet, then we don't
  549. // need to do anything yet.
  550. if (pThis->m_bExpanded)
  551. {
  552. // Enumerate through the list of interfaces looking for
  553. // the interfaces that have this protocol. If we find
  554. // one, look for this interface in our list of nodes.
  555. spThisNode->GetEnum(&spEnumNode);
  556. CORg( pThis->m_spRouterInfo->EnumInterface(&spEnumIf) );
  557. spEnumIf->Reset();
  558. fPleaseAdd = FALSE;
  559. for (; spEnumIf->Next(1, &spIf, NULL) == hrOK; spIf.Release())
  560. {
  561. // Look for this interface in our list of nodes
  562. // If it's there than continue on
  563. fFound = FALSE;
  564. spEnumNode->Reset();
  565. spNode.Release();
  566. for (; spEnumNode->Next(1, &spNode, NULL) == hrOK; spNode.Release())
  567. {
  568. pData = GET_BASEIPXRESULT_NODEDATA(spNode);
  569. Assert(pData);
  570. ASSERT_BASEIPXRESULT_NODEDATA(pData);
  571. if (!pData->m_fClient && StriCmpW(pData->m_spIf->GetId(), spIf->GetId()) == 0)
  572. {
  573. fFound = TRUE;
  574. break;
  575. }
  576. }
  577. // If the interface was not found in the list of nodes,
  578. // then it is a candidate. Now we have to see if the
  579. // interface supports this transport.
  580. if (!fFound && (LookupRtrMgrProtocolInterface(spIf, PID_IPX, IPX_PROTOCOL_RIP, NULL) == hrOK))
  581. {
  582. // If this interface has this transport, and is NOT in
  583. // the current list of nodes then add this interface
  584. // to the UI
  585. // Grab the infobase
  586. // Load the infobase for this interface
  587. spRmIf.Release();
  588. spInfoBase.Release();
  589. hr = spIf->FindRtrMgrInterface(PID_IPX, &spRmIf);
  590. if (FHrOK(hr))
  591. {
  592. spRmIf->GetInfoBase(NULL, NULL, NULL, &spInfoBase);
  593. hr = pThis->AddInterfaceNode(spThisNode, spIf, FALSE);
  594. }
  595. fPleaseAdd = TRUE;
  596. }
  597. }
  598. // Now that we have all of the nodes, update the data for
  599. // all of the nodes
  600. if (fPleaseAdd)
  601. pThis->SynchronizeNodeData(spThisNode);
  602. }
  603. }
  604. else if (dwChangeType == ROUTER_CHILD_DELETE)
  605. {
  606. // Go through the list of nodes, if we cannot find the
  607. // node in the list of interfaces, delete the node
  608. spThisNode->GetEnum(&spEnumNode);
  609. spEnumNode->Reset();
  610. while (spEnumNode->Next(1, &spNode, NULL) == hrOK)
  611. {
  612. // Get the node data, look for the interface
  613. pData = GET_BASEIPXRESULT_NODEDATA(spNode);
  614. ASSERT_BASEIPXRESULT_NODEDATA(pData);
  615. if (pData->m_spIf &&
  616. LookupRtrMgrProtocolInterface(pData->m_spIf,
  617. PID_IPX, IPX_PROTOCOL_RIP, NULL) != hrOK)
  618. {
  619. // If this flag is set, then we are in the new
  620. // interface case, and we do not want to delete
  621. // this here since it will then deadlock.
  622. if ((spNode->GetVisibilityState() & TFS_VIS_DELETE) == 0)
  623. {
  624. // cannot find the interface, release this node!
  625. spThisNode->RemoveChild(spNode);
  626. spNode->Destroy();
  627. }
  628. }
  629. spNode.Release();
  630. spIf.Release();
  631. }
  632. }
  633. }
  634. else if (dwChangeType == ROUTER_REFRESH)
  635. {
  636. if (ulConn == pThis->m_ulStatsConnId)
  637. {
  638. pThis->m_RIPParamsStats.PostRefresh();
  639. }
  640. else
  641. pThis->SynchronizeNodeData(spThisNode);
  642. }
  643. else if (dwChangeType == ROUTER_DO_DISCONNECT)
  644. {
  645. IPXConnection * pIPXConn = NULL;
  646. pIPXConn = GET_RIP_NODEDATA(spThisNode);
  647. pIPXConn->DisconnectAll();
  648. }
  649. Error:
  650. return hr;
  651. }
  652. HRESULT RipNodeHandler::AddProtocolToInfoBase(ITFSNode *pThisNode)
  653. {
  654. HRESULT hr = hrOK;
  655. SPITFSNodeEnum spEnumNode;
  656. SPIRtrMgrInterfaceInfo spRmIf;
  657. SPIEnumInterfaceInfo spEnumIf;
  658. SPIInterfaceInfo spIf;
  659. SPITFSNode spNode;
  660. BaseIPXResultNodeData * pData;
  661. // Enumerate through the list of interfaces looking for
  662. // the interfaces that have this protocol. If we find
  663. // one, look for this interface in our list of nodes.
  664. pThisNode->GetEnum(&spEnumNode);
  665. CORg( m_spRouterInfo->EnumInterface(&spEnumIf) );
  666. spEnumIf->Reset();
  667. for (; spEnumIf->Next(1, &spIf, NULL) == hrOK; spIf.Release())
  668. {
  669. // Look for this interface in our list of nodes
  670. // If it's there than continue on
  671. spEnumNode->Reset();
  672. spNode.Release();
  673. spRmIf.Release();
  674. // If this interface has IPX but not RIP, add it
  675. if ((spIf->FindRtrMgrInterface(PID_IPX, &spRmIf) == hrOK) &&
  676. (LookupRtrMgrProtocolInterface(spIf, PID_IPX,
  677. IPX_PROTOCOL_RIP, NULL) != hrOK))
  678. {
  679. // Add RIP to this node
  680. SPIInfoBase spInfoBase;
  681. // We need to get the infobase for this and create
  682. // the RIP blocks (but do NOT save, let the property
  683. // sheet take care of that).
  684. spInfoBase.Release();
  685. if (!FHrOK(spRmIf->GetInfoBase(NULL, NULL, NULL, &spInfoBase)))
  686. {
  687. spRmIf->Load(spRmIf->GetMachineName(), NULL, NULL, NULL);
  688. spRmIf->GetInfoBase(NULL, NULL, NULL, &spInfoBase);
  689. }
  690. if (!spInfoBase)
  691. CreateInfoBase(&spInfoBase);
  692. if (!FHrOK(spInfoBase->ProtocolExists(IPX_PROTOCOL_RIP)))
  693. {
  694. // Add a RIP_IF_CONFIG block
  695. BYTE * pDefault;
  696. if (spIf->GetInterfaceType() == ROUTER_IF_TYPE_DEDICATED)
  697. pDefault = g_pIpxRipLanInterfaceDefault;
  698. else
  699. pDefault = g_pIpxRipInterfaceDefault;
  700. spInfoBase->AddBlock(IPX_PROTOCOL_RIP,
  701. sizeof(RIP_IF_CONFIG),
  702. pDefault,
  703. 1,
  704. 0);
  705. spRmIf->SetInfoBase(NULL, NULL, NULL, spInfoBase);
  706. }
  707. }
  708. }
  709. // Now that we have all of the nodes, update the data for
  710. // all of the nodes
  711. // if (fPleaseAdd)
  712. // pThis->SynchronizeNodeData(spThisNode);
  713. Error:
  714. return hr;
  715. }
  716. HRESULT RipNodeHandler::AddProtocolToInterface(ITFSNode *pThisNode)
  717. {
  718. HRESULT hr = hrOK;
  719. SPITFSNodeEnum spEnumNode;
  720. SPIRtrMgrInterfaceInfo spRmIf;
  721. SPIRtrMgrProtocolInterfaceInfo spRmProtIf;
  722. SPIEnumInterfaceInfo spEnumIf;
  723. SPIInterfaceInfo spIf;
  724. SPITFSNode spNode;
  725. BaseIPXResultNodeData * pData;
  726. // Enumerate through the list of interfaces looking for
  727. // the interfaces that have this protocol. If we find
  728. // one, look for this interface in our list of nodes.
  729. pThisNode->GetEnum(&spEnumNode);
  730. CORg( m_spRouterInfo->EnumInterface(&spEnumIf) );
  731. spEnumIf->Reset();
  732. for (; spEnumIf->Next(1, &spIf, NULL) == hrOK; spIf.Release())
  733. {
  734. // Look for this interface in our list of nodes
  735. // If it's there than continue on
  736. spEnumNode->Reset();
  737. spNode.Release();
  738. // If this interface has IPX but not RIP, add it
  739. if ((spIf->FindRtrMgrInterface(PID_IPX, NULL) == hrOK) &&
  740. (LookupRtrMgrProtocolInterface(spIf, PID_IPX,
  741. IPX_PROTOCOL_RIP, NULL) != hrOK))
  742. {
  743. // Add RIP to this node
  744. RtrMgrProtocolCB RmProtCB;
  745. RtrMgrProtocolInterfaceCB RmProtIfCB;
  746. SPIInfoBase spInfoBase;
  747. // Need to create an RmProtIf
  748. m_spRmProt->CopyCB(&RmProtCB);
  749. spRmProtIf.Release();
  750. RmProtIfCB.dwProtocolId = RmProtCB.dwProtocolId;
  751. StrnCpyW(RmProtIfCB.szId, RmProtCB.szId, RTR_ID_MAX);
  752. RmProtIfCB.dwTransportId = RmProtCB.dwTransportId;
  753. StrnCpyW(RmProtIfCB.szRtrMgrId, RmProtCB.szRtrMgrId, RTR_ID_MAX);
  754. StrnCpyW(RmProtIfCB.szInterfaceId, spIf->GetId(), RTR_ID_MAX);
  755. RmProtIfCB.dwIfType = spIf->GetInterfaceType();
  756. RmProtIfCB.szTitle[0] = 0;
  757. CORg( CreateRtrMgrProtocolInterfaceInfo(&spRmProtIf,
  758. &RmProtIfCB) );
  759. spRmProtIf->SetTitle(spIf->GetTitle());
  760. // Add this to the spRmIf
  761. spRmIf.Release();
  762. CORg( spIf->FindRtrMgrInterface(PID_IPX, &spRmIf) );
  763. Assert(spRmIf);
  764. // We need to get the infobase for this and create
  765. // the RIP blocks (but do NOT save, let the property
  766. // sheet take care of that).
  767. spInfoBase.Release();
  768. // spRmIf->Load(spRmIf->GetMachineName(), NULL, NULL, NULL);
  769. spRmIf->GetInfoBase(NULL, NULL, NULL, &spInfoBase);
  770. if (!spInfoBase)
  771. CreateInfoBase(&spInfoBase);
  772. if (!FHrOK(spInfoBase->ProtocolExists(IPX_PROTOCOL_RIP)))
  773. {
  774. // Add a RIP_IF_CONFIG block
  775. BYTE * pDefault;
  776. if (spIf->GetInterfaceType() == ROUTER_IF_TYPE_DEDICATED)
  777. pDefault = g_pIpxRipLanInterfaceDefault;
  778. else
  779. pDefault = g_pIpxRipInterfaceDefault;
  780. spInfoBase->AddBlock(IPX_PROTOCOL_RIP,
  781. sizeof(RIP_IF_CONFIG),
  782. pDefault,
  783. 1,
  784. 0);
  785. }
  786. CORg(spRmIf->AddRtrMgrProtocolInterface(spRmProtIf,
  787. spInfoBase /* pInfoBase */));
  788. }
  789. }
  790. // Now that we have all of the nodes, update the data for
  791. // all of the nodes
  792. // if (fPleaseAdd)
  793. // pThis->SynchronizeNodeData(spThisNode);
  794. Error:
  795. return hr;
  796. }
  797. /*!--------------------------------------------------------------------------
  798. RipNodeHandler::SynchronizeNodeData
  799. -
  800. Author: KennT
  801. ---------------------------------------------------------------------------*/
  802. HRESULT RipNodeHandler::SynchronizeNodeData(ITFSNode *pThisNode)
  803. {
  804. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  805. HRESULT hr = hrOK;
  806. SPITFSNodeEnum spNodeEnum;
  807. SPITFSNode spNode;
  808. CStringList ifidList;
  809. BaseIPXResultNodeData * pNodeData;
  810. RipList ripList;
  811. RipListEntry * pRipEntry = NULL;
  812. RipListEntry * pRipCurrent = NULL;
  813. int i;
  814. CString stNotAvailable;
  815. POSITION pos;
  816. COM_PROTECT_TRY
  817. {
  818. // Do the data gathering work (separate this from the rest of the
  819. // code so that we can move this part to a background thread later).
  820. stNotAvailable.LoadString(IDS_IPX_NOT_AVAILABLE);
  821. // We need to build up a list of interface ids
  822. pThisNode->GetEnum(&spNodeEnum);
  823. for (; spNodeEnum->Next(1, &spNode, NULL) == hrOK; spNode.Release() )
  824. {
  825. pNodeData = GET_BASEIPXRESULT_NODEDATA(spNode);
  826. Assert(pNodeData);
  827. ASSERT_BASEIPXRESULT_NODEDATA(pNodeData);
  828. pRipEntry = new RipListEntry;
  829. pRipEntry->m_spIf.Set(pNodeData->m_spIf);
  830. pRipEntry->m_spNode.Set(spNode);
  831. ::ZeroMemory(&(pRipEntry->m_info), sizeof(pRipEntry->m_info));
  832. ::ZeroMemory(&(pRipEntry->m_stats), sizeof(pRipEntry->m_stats));
  833. pRipEntry->m_fClient = pNodeData->m_fClient;
  834. pRipEntry->m_fFoundIfIndex = FALSE;
  835. pRipEntry->m_dwIfIndex = 0;
  836. // The data in the m_info struct is not up to date
  837. pRipEntry->m_fInfoUpdated = FALSE;
  838. ripList.AddTail(pRipEntry);
  839. pRipEntry = NULL;
  840. // Fill in the result data with '-'
  841. // This is a little bogus, but it's the easiest way, we
  842. // don't want to touch interface and relay_mode.
  843. for (i=RIP_SI_INTERFACE; i<RIP_SI_MAX_COLUMNS; i++)
  844. {
  845. pNodeData->m_rgData[i].m_stData = stNotAvailable;
  846. pNodeData->m_rgData[i].m_dwData = 0xFFFFFFFF;
  847. }
  848. // Fill in as much data as we can at this point
  849. if (pNodeData->m_fClient)
  850. {
  851. pNodeData->m_rgData[RIP_SI_INTERFACE].m_stData.LoadString(
  852. IDS_IPX_DIAL_IN_CLIENTS);
  853. pNodeData->m_rgData[RIP_SI_TYPE].m_stData =
  854. IpxTypeToCString(ROUTER_IF_TYPE_CLIENT);
  855. }
  856. else
  857. {
  858. pNodeData->m_rgData[RIP_SI_INTERFACE].m_stData =
  859. pNodeData->m_spIf->GetTitle();
  860. pNodeData->m_rgData[RIP_SI_TYPE].m_stData =
  861. IpxTypeToCString(pNodeData->m_spIf->GetInterfaceType());
  862. }
  863. }
  864. spNode.Release();
  865. // We can now use this list of ids, to get the data for each item
  866. hr = GetRipData(pThisNode, &ripList);
  867. // Now for each data item, fill in the appropriate data in
  868. // the node
  869. pos = ripList.GetHeadPosition();
  870. while (pos)
  871. {
  872. pRipCurrent = ripList.GetNext(pos);
  873. pNodeData = GET_BASEIPXRESULT_NODEDATA(pRipCurrent->m_spNode);
  874. Assert(pNodeData);
  875. ASSERT_BASEIPXRESULT_NODEDATA(pNodeData);
  876. if (pRipCurrent->m_fInfoUpdated)
  877. {
  878. pNodeData->m_rgData[RIP_SI_ACCEPT_ROUTES].m_stData =
  879. IpxAdminStateToCString(pRipCurrent->m_info.Listen);
  880. pNodeData->m_rgData[RIP_SI_SUPPLY_ROUTES].m_stData =
  881. IpxAdminStateToCString(pRipCurrent->m_info.Supply);
  882. pNodeData->m_rgData[RIP_SI_UPDATE_MODE].m_stData =
  883. RipSapUpdateModeToCString(pRipCurrent->m_info.UpdateMode);
  884. FillInNumberData(pNodeData, RIP_SI_UPDATE_PERIOD,
  885. pRipCurrent->m_info.PeriodicUpdateInterval);
  886. FillInNumberData(pNodeData, RIP_SI_AGE_MULTIPLIER,
  887. pRipCurrent->m_info.AgeIntervalMultiplier);
  888. pNodeData->m_rgData[RIP_SI_ADMIN_STATE].m_stData =
  889. IpxAdminStateToCString(pRipCurrent->m_info.AdminState);
  890. }
  891. if (FHrSucceeded(hr) && !pRipCurrent->m_fClient)
  892. {
  893. pNodeData->m_rgData[RIP_SI_OPER_STATE].m_stData =
  894. IpxOperStateToCString(pRipCurrent->m_stats.RipIfOperState);
  895. FillInNumberData(pNodeData, RIP_SI_PACKETS_SENT,
  896. pRipCurrent->m_stats.RipIfOutputPackets);
  897. FillInNumberData(pNodeData, RIP_SI_PACKETS_RECEIVED,
  898. pRipCurrent->m_stats.RipIfInputPackets);
  899. }
  900. pRipCurrent->m_spNode->ChangeNode(RESULT_PANE_CHANGE_ITEM_DATA);
  901. }
  902. }
  903. COM_PROTECT_CATCH;
  904. delete pRipEntry;
  905. while (!ripList.IsEmpty())
  906. delete ripList.RemoveTail();
  907. return hr;
  908. }
  909. /*!--------------------------------------------------------------------------
  910. RipNodeHandler::GetRipData
  911. -
  912. Author: KennT
  913. ---------------------------------------------------------------------------*/
  914. HRESULT RipNodeHandler::GetRipData(ITFSNode *pThisNode, RipList *pRipList)
  915. {
  916. HRESULT hr = hrOK;
  917. BOOL fIsServiceRunning;
  918. IPXConnection * pIPXConn;
  919. RIP_MIB_GET_INPUT_DATA MibGetInputData;
  920. SPIInfoBase spInfoBase;
  921. POSITION pos;
  922. RipListEntry * pRipEntry;
  923. int i;
  924. PRIP_INTERFACE pRipIf = NULL;
  925. DWORD cbRipIf;
  926. SPMprMibBuffer spMib;
  927. DWORD dwErr;
  928. SPIRtrMgrInterfaceInfo spRmIf;
  929. PRIP_IF_CONFIG pric;
  930. HRESULT hrIndex = hrOK;
  931. // Retrieve the IP interface table; we will need this in order to
  932. // map interface-names to interface-indices, and we will need the
  933. // interface-indices in order to query for RIP MIB information.
  934. //
  935. CORg( IsRouterServiceRunning(m_spRouterInfo->GetMachineName(), NULL) );
  936. fIsServiceRunning = (hr == hrOK);
  937. // Get the connection data
  938. pIPXConn = GET_RIP_NODEDATA(pThisNode);
  939. // Iterate through the list filling in the interface indexes
  940. hrIndex = FillInInterfaceIndex(pIPXConn, pRipList);
  941. // Iterate throught the list of entries, gathering data for each
  942. // interface
  943. pos = pRipList->GetHeadPosition();
  944. while (pos)
  945. {
  946. pRipEntry = pRipList->GetNext(pos);
  947. // if (!fIsServiceRunning)
  948. // continue;
  949. if (pRipEntry->m_fClient)
  950. {
  951. // Fill in the client data
  952. FillClientData(pRipEntry);
  953. continue;
  954. }
  955. // Load the infobase and get the data for this entry
  956. spRmIf.Release();
  957. spInfoBase.Release();
  958. CORg( pRipEntry->m_spIf->FindRtrMgrInterface(PID_IPX, &spRmIf) );
  959. if (!spRmIf)
  960. continue;
  961. CORg( spRmIf->Load(spRmIf->GetMachineName(), NULL, NULL, NULL) );
  962. CORg( spRmIf->GetInfoBase(NULL, NULL, NULL, &spInfoBase) );
  963. CORg( spInfoBase->GetData(IPX_PROTOCOL_RIP, 0, (LPBYTE *) &pric) );
  964. pRipEntry->m_info = pric->RipIfInfo;
  965. pRipEntry->m_fInfoUpdated = TRUE;
  966. if (!pRipEntry->m_fFoundIfIndex)
  967. continue;
  968. if (!fIsServiceRunning)
  969. continue;
  970. if (!FHrSucceeded(hrIndex))
  971. continue;
  972. // Now get the dynamic data from the MIBs
  973. spMib.Free();
  974. MibGetInputData.InterfaceIndex = pRipEntry->m_dwIfIndex;
  975. MibGetInputData.TableId = RIP_INTERFACE_TABLE;
  976. dwErr = ::MprAdminMIBEntryGet(pIPXConn->GetMibHandle(),
  977. PID_IPX,
  978. IPX_PROTOCOL_RIP,
  979. &MibGetInputData,
  980. sizeof(MibGetInputData),
  981. (LPVOID *) &pRipIf,
  982. &cbRipIf);
  983. spMib = (PBYTE) pRipIf;
  984. CWRg(dwErr);
  985. Assert(pRipIf);
  986. pRipEntry->m_stats = pRipIf->RipIfStats;
  987. }
  988. Error:
  989. return hr;
  990. }
  991. /*!--------------------------------------------------------------------------
  992. RipNodeHandler::FillInInterfaceIndex
  993. -
  994. Author: KennT
  995. ---------------------------------------------------------------------------*/
  996. HRESULT RipNodeHandler::FillInInterfaceIndex(IPXConnection *pIPXConn, RipList *pRipList)
  997. {
  998. HRESULT hr = hrOK;
  999. POSITION pos;
  1000. RipListEntry * pRipEntry;
  1001. IPX_MIB_GET_INPUT_DATA MibGetInputData;
  1002. DWORD IfSize = sizeof(IPX_INTERFACE);
  1003. PIPX_INTERFACE pIpxIf;
  1004. DWORD dwErr;
  1005. SPMprMibBuffer spMib;
  1006. USES_CONVERSION;
  1007. MibGetInputData.TableId = IPX_INTERFACE_TABLE;
  1008. dwErr = ::MprAdminMIBEntryGetFirst(pIPXConn->GetMibHandle(),
  1009. PID_IPX,
  1010. IPX_PROTOCOL_BASE,
  1011. &MibGetInputData,
  1012. sizeof(IPX_MIB_GET_INPUT_DATA),
  1013. (LPVOID *) &pIpxIf,
  1014. &IfSize);
  1015. hr = HRESULT_FROM_WIN32(dwErr);
  1016. spMib = (LPBYTE) pIpxIf;
  1017. while (FHrSucceeded(hr))
  1018. {
  1019. // go through the list of interfaces looking for a match
  1020. pos = pRipList->GetHeadPosition();
  1021. while (pos)
  1022. {
  1023. pRipEntry = pRipList->GetNext(pos);
  1024. // If this is the client interface, we don't need to
  1025. // look for an interface that matches
  1026. if (pRipEntry->m_fClient)
  1027. continue;
  1028. if (StriCmp(pRipEntry->m_spIf->GetId(),
  1029. A2CT((LPCSTR) pIpxIf->InterfaceName)) == 0)
  1030. {
  1031. Assert(pRipEntry->m_fFoundIfIndex == FALSE);
  1032. pRipEntry->m_dwIfIndex = pIpxIf->InterfaceIndex;
  1033. pRipEntry->m_fFoundIfIndex = TRUE;
  1034. break;
  1035. }
  1036. pRipEntry = NULL;
  1037. }
  1038. // Go onto the next interface
  1039. MibGetInputData.MibIndex.InterfaceTableIndex.InterfaceIndex =
  1040. pIpxIf->InterfaceIndex;
  1041. spMib.Free();
  1042. pIpxIf = NULL;
  1043. dwErr = ::MprAdminMIBEntryGetNext(pIPXConn->GetMibHandle(),
  1044. PID_IPX,
  1045. IPX_PROTOCOL_BASE,
  1046. &MibGetInputData,
  1047. sizeof(IPX_MIB_GET_INPUT_DATA),
  1048. (LPVOID *) &pIpxIf,
  1049. &IfSize);
  1050. hr = HRESULT_FROM_WIN32(dwErr);
  1051. spMib = (LPBYTE) pIpxIf;
  1052. }
  1053. //Error:
  1054. return hr == HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) ? hrOK : hr;
  1055. }
  1056. /*!--------------------------------------------------------------------------
  1057. RipNodeHandler::FillClientData
  1058. -
  1059. Author: KennT
  1060. ---------------------------------------------------------------------------*/
  1061. HRESULT RipNodeHandler::FillClientData(RipListEntry *pRipEntry)
  1062. {
  1063. HRESULT hr = hrOK;
  1064. SPIInfoBase spInfoBase;
  1065. PRIP_IF_CONFIG pric = NULL;
  1066. Assert(pRipEntry->m_fClient == TRUE);
  1067. Assert(pRipEntry->m_fFoundIfIndex == FALSE);
  1068. CORg( m_spRm->GetInfoBase(NULL, NULL, NULL, &spInfoBase) );
  1069. CORg( spInfoBase->GetData(IPX_PROTOCOL_RIP, 0, (LPBYTE *) &pric) );
  1070. pRipEntry->m_info = pric->RipIfInfo;
  1071. pRipEntry->m_fInfoUpdated = TRUE;
  1072. memset(&(pRipEntry->m_stats), 0xFF, sizeof(pRipEntry->m_stats));
  1073. pRipEntry->m_dwIfIndex = 0xFFFFFFFF;
  1074. Error:
  1075. return hr;
  1076. }
  1077. /*!--------------------------------------------------------------------------
  1078. RipNodeHandler::OnResultShow
  1079. -
  1080. Author: KennT
  1081. ---------------------------------------------------------------------------*/
  1082. HRESULT RipNodeHandler::OnResultShow(ITFSComponent *pTFSComponent, MMC_COOKIE cookie, LPARAM arg, LPARAM lParam)
  1083. {
  1084. BOOL bSelect = (BOOL) arg;
  1085. HRESULT hr = hrOK;
  1086. SPIRouterRefresh spRefresh;
  1087. SPITFSNode spNode;
  1088. BaseContainerHandler::OnResultShow(pTFSComponent, cookie, arg, lParam);
  1089. if (bSelect)
  1090. {
  1091. // Call synchronize on this node
  1092. m_spNodeMgr->FindNode(cookie, &spNode);
  1093. if (spNode)
  1094. SynchronizeNodeData(spNode);
  1095. }
  1096. // Un/Register for refresh advises
  1097. if (m_spRouterInfo)
  1098. m_spRouterInfo->GetRefreshObject(&spRefresh);
  1099. if (spRefresh)
  1100. {
  1101. if (bSelect)
  1102. {
  1103. if (m_ulRefreshConnId == 0)
  1104. spRefresh->AdviseRefresh(&m_IRtrAdviseSink, &m_ulRefreshConnId, 0);
  1105. if (m_ulStatsConnId == 0)
  1106. spRefresh->AdviseRefresh(&m_IRtrAdviseSink, &m_ulStatsConnId, 0);
  1107. }
  1108. else
  1109. {
  1110. if (m_ulRefreshConnId)
  1111. spRefresh->UnadviseRefresh(m_ulRefreshConnId);
  1112. m_ulRefreshConnId = 0;
  1113. }
  1114. }
  1115. return hr;
  1116. }
  1117. /*!--------------------------------------------------------------------------
  1118. RipNodeHandler::CompareItems
  1119. -
  1120. Author: KennT
  1121. ---------------------------------------------------------------------------*/
  1122. STDMETHODIMP_(int) RipNodeHandler::CompareItems(
  1123. ITFSComponent * pComponent,
  1124. MMC_COOKIE cookieA,
  1125. MMC_COOKIE cookieB,
  1126. int nCol)
  1127. {
  1128. // Get the strings from the nodes and use that as a basis for
  1129. // comparison.
  1130. SPITFSNode spNode;
  1131. SPITFSResultHandler spResult;
  1132. m_spNodeMgr->FindNode(cookieA, &spNode);
  1133. spNode->GetResultHandler(&spResult);
  1134. return spResult->CompareItems(pComponent, cookieA, cookieB, nCol);
  1135. }
  1136. /*---------------------------------------------------------------------------
  1137. Class: RipInterfaceHandler
  1138. ---------------------------------------------------------------------------*/
  1139. RipInterfaceHandler::RipInterfaceHandler(ITFSComponentData *pCompData)
  1140. : BaseIPXResultHandler(pCompData, RIP_COLUMNS),
  1141. m_ulConnId(0)
  1142. {
  1143. m_rgButtonState[MMC_VERB_PROPERTIES_INDEX] = ENABLED;
  1144. m_bState[MMC_VERB_PROPERTIES_INDEX] = TRUE;
  1145. m_rgButtonState[MMC_VERB_REFRESH_INDEX] = ENABLED;
  1146. m_bState[MMC_VERB_REFRESH_INDEX] = TRUE;
  1147. m_verbDefault = MMC_VERB_PROPERTIES;
  1148. }
  1149. static const DWORD s_rgInterfaceImageMap[] =
  1150. {
  1151. ROUTER_IF_TYPE_HOME_ROUTER, IMAGE_IDX_WAN_CARD,
  1152. ROUTER_IF_TYPE_FULL_ROUTER, IMAGE_IDX_WAN_CARD,
  1153. ROUTER_IF_TYPE_CLIENT, IMAGE_IDX_WAN_CARD,
  1154. ROUTER_IF_TYPE_DEDICATED, IMAGE_IDX_LAN_CARD,
  1155. ROUTER_IF_TYPE_INTERNAL, IMAGE_IDX_LAN_CARD,
  1156. ROUTER_IF_TYPE_LOOPBACK, IMAGE_IDX_LAN_CARD,
  1157. -1, IMAGE_IDX_WAN_CARD, // sentinel value
  1158. };
  1159. /*!--------------------------------------------------------------------------
  1160. RipInterfaceHandler::ConstructNode
  1161. Initializes the Domain node (sets it up).
  1162. Author: KennT
  1163. ---------------------------------------------------------------------------*/
  1164. HRESULT RipInterfaceHandler::ConstructNode(ITFSNode *pNode, IInterfaceInfo *pIfInfo, IPXConnection *pIPXConn)
  1165. {
  1166. HRESULT hr = hrOK;
  1167. int i;
  1168. DWORD dwIfType;
  1169. if (pNode == NULL)
  1170. return hrOK;
  1171. COM_PROTECT_TRY
  1172. {
  1173. // Need to initialize the data for the Domain node
  1174. // Find the right image index for this type of node
  1175. if (pIfInfo)
  1176. dwIfType = pIfInfo->GetInterfaceType();
  1177. else
  1178. dwIfType = ROUTER_IF_TYPE_CLIENT;
  1179. for (i=0; i<DimensionOf(s_rgInterfaceImageMap); i+=2)
  1180. {
  1181. if ((dwIfType == s_rgInterfaceImageMap[i]) ||
  1182. (-1 == s_rgInterfaceImageMap[i]))
  1183. break;
  1184. }
  1185. pNode->SetData(TFS_DATA_IMAGEINDEX, s_rgInterfaceImageMap[i+1]);
  1186. pNode->SetData(TFS_DATA_OPENIMAGEINDEX, s_rgInterfaceImageMap[i+1]);
  1187. pNode->SetData(TFS_DATA_SCOPEID, 0);
  1188. pNode->SetData(TFS_DATA_COOKIE, reinterpret_cast<DWORD_PTR>(pNode));
  1189. //$ Review: kennt, what are the different type of interfaces
  1190. // do we distinguish based on the same list as above? (i.e. the
  1191. // one for image indexes).
  1192. pNode->SetNodeType(&GUID_IPXRipInterfaceNodeType);
  1193. BaseIPXResultNodeData::Init(pNode, pIfInfo, pIPXConn);
  1194. }
  1195. COM_PROTECT_CATCH
  1196. return hr;
  1197. }
  1198. /*!--------------------------------------------------------------------------
  1199. RipInterfaceHandler::OnCreateDataObject
  1200. -
  1201. Author: KennT
  1202. ---------------------------------------------------------------------------*/
  1203. STDMETHODIMP RipInterfaceHandler::OnCreateDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, IDataObject **ppDataObject)
  1204. {
  1205. HRESULT hr = hrOK;
  1206. COM_PROTECT_TRY
  1207. {
  1208. CORg( CreateDataObjectFromInterfaceInfo(m_spInterfaceInfo,
  1209. type, cookie, m_spTFSCompData,
  1210. ppDataObject) );
  1211. COM_PROTECT_ERROR_LABEL;
  1212. }
  1213. COM_PROTECT_CATCH;
  1214. return hr;
  1215. }
  1216. /*!--------------------------------------------------------------------------
  1217. RipInterfaceHandler::OnCreateDataObject
  1218. Implementation of ITFSResultHandler::OnCreateDataObject
  1219. Author: KennT
  1220. ---------------------------------------------------------------------------*/
  1221. STDMETHODIMP RipInterfaceHandler::OnCreateDataObject(ITFSComponent *pComp, MMC_COOKIE cookie, DATA_OBJECT_TYPES type, IDataObject **ppDataObject)
  1222. {
  1223. HRESULT hr = hrOK;
  1224. COM_PROTECT_TRY
  1225. {
  1226. CORg( CreateDataObjectFromInterfaceInfo(m_spInterfaceInfo,
  1227. type, cookie, m_spTFSCompData,
  1228. ppDataObject) );
  1229. COM_PROTECT_ERROR_LABEL;
  1230. }
  1231. COM_PROTECT_CATCH;
  1232. return hr;
  1233. }
  1234. /*!--------------------------------------------------------------------------
  1235. RipInterfaceHandler::RefreshInterface
  1236. -
  1237. Author: KennT
  1238. ---------------------------------------------------------------------------*/
  1239. void RipInterfaceHandler::RefreshInterface(MMC_COOKIE cookie)
  1240. {
  1241. SPITFSNode spNode;
  1242. m_spNodeMgr->FindNode(cookie, &spNode);
  1243. ForwardCommandToParent(spNode, IDS_MENU_SYNC,
  1244. CCT_RESULT, NULL, 0);
  1245. }
  1246. /*!--------------------------------------------------------------------------
  1247. RipInterfaceHandler::Init
  1248. -
  1249. Author: KennT
  1250. ---------------------------------------------------------------------------*/
  1251. HRESULT RipInterfaceHandler::Init(IInterfaceInfo *pIfInfo,
  1252. IRouterInfo *pRouterInfo,
  1253. ITFSNode *pParent)
  1254. {
  1255. m_spInterfaceInfo.Set(pIfInfo);
  1256. BaseIPXResultHandler::Init(pIfInfo, pParent);
  1257. m_spRouterInfo.Set(pRouterInfo);
  1258. return hrOK;
  1259. }
  1260. /*!--------------------------------------------------------------------------
  1261. RipInterfaceHandler::DestroyResultHandler
  1262. -
  1263. Author: KennT
  1264. ---------------------------------------------------------------------------*/
  1265. STDMETHODIMP RipInterfaceHandler::DestroyResultHandler(MMC_COOKIE cookie)
  1266. {
  1267. m_spInterfaceInfo.Release();
  1268. BaseIPXResultHandler::DestroyResultHandler(cookie);
  1269. return hrOK;
  1270. }
  1271. /*---------------------------------------------------------------------------
  1272. This is the list of commands that will show up for the result pane
  1273. nodes.
  1274. ---------------------------------------------------------------------------*/
  1275. struct SIPInterfaceNodeMenu
  1276. {
  1277. ULONG m_sidMenu; // string/command id for this menu item
  1278. ULONG (RipInterfaceHandler:: *m_pfnGetMenuFlags)(RipInterfaceHandler::SMenuData *);
  1279. ULONG m_ulPosition;
  1280. };
  1281. /*!--------------------------------------------------------------------------
  1282. RipInterfaceHandler::AddMenuItems
  1283. Implementation of ITFSResultHandler::AddMenuItems
  1284. Author: KennT
  1285. ---------------------------------------------------------------------------*/
  1286. STDMETHODIMP RipInterfaceHandler::AddMenuItems(
  1287. ITFSComponent *pComponent,
  1288. MMC_COOKIE cookie,
  1289. LPDATAOBJECT lpDataObject,
  1290. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  1291. long *pInsertionAllowed)
  1292. {
  1293. return hrOK;
  1294. }
  1295. /*!--------------------------------------------------------------------------
  1296. RipInterfaceHandler::Command
  1297. -
  1298. Author: KennT
  1299. ---------------------------------------------------------------------------*/
  1300. STDMETHODIMP RipInterfaceHandler::Command(ITFSComponent *pComponent,
  1301. MMC_COOKIE cookie,
  1302. int nCommandID,
  1303. LPDATAOBJECT pDataObject)
  1304. {
  1305. return hrOK;
  1306. }
  1307. /*!--------------------------------------------------------------------------
  1308. RipInterfaceHandler::HasPropertyPages
  1309. -
  1310. Author: KennT
  1311. ---------------------------------------------------------------------------*/
  1312. STDMETHODIMP RipInterfaceHandler::HasPropertyPages
  1313. (
  1314. ITFSNode * pNode,
  1315. LPDATAOBJECT pDataObject,
  1316. DATA_OBJECT_TYPES type,
  1317. DWORD dwType
  1318. )
  1319. {
  1320. return hrTrue;
  1321. }
  1322. /*!--------------------------------------------------------------------------
  1323. RipInterfaceHandler::CreatePropertyPages
  1324. -
  1325. Author: KennT
  1326. ---------------------------------------------------------------------------*/
  1327. STDMETHODIMP RipInterfaceHandler::CreatePropertyPages
  1328. (
  1329. ITFSNode * pNode,
  1330. LPPROPERTYSHEETCALLBACK lpProvider,
  1331. LPDATAOBJECT pDataObject,
  1332. LONG_PTR handle,
  1333. DWORD dwType
  1334. )
  1335. {
  1336. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1337. HRESULT hr = hrOK;
  1338. RipInterfaceProperties * pProperties = NULL;
  1339. SPIComponentData spComponentData;
  1340. CString stTitle;
  1341. SPIRouterInfo spRouter;
  1342. SPIRtrMgrInfo spRm;
  1343. CORg( m_spNodeMgr->GetComponentData(&spComponentData) );
  1344. // stTitle.Format(IDS_RIP_GENERAL_PAGE_TITLE,
  1345. // m_spInterfaceInfo->GetTitle());
  1346. pProperties = new RipInterfaceProperties(pNode, spComponentData,
  1347. m_spTFSCompData, stTitle);
  1348. CORg( m_spRouterInfo->FindRtrMgr(PID_IPX, &spRm) );
  1349. CORg( pProperties->Init(m_spInterfaceInfo, spRm) );
  1350. if (lpProvider)
  1351. hr = pProperties->CreateModelessSheet(lpProvider, handle);
  1352. else
  1353. hr = pProperties->DoModelessSheet();
  1354. Error:
  1355. // Is this the right way to destroy the sheet?
  1356. if (!FHrSucceeded(hr))
  1357. delete pProperties;
  1358. return hr;
  1359. }
  1360. /*!--------------------------------------------------------------------------
  1361. RipInterfaceHandler::CreatePropertyPages
  1362. Implementation of ResultHandler::CreatePropertyPages
  1363. Author: KennT
  1364. ---------------------------------------------------------------------------*/
  1365. STDMETHODIMP RipInterfaceHandler::CreatePropertyPages
  1366. (
  1367. ITFSComponent * pComponent,
  1368. MMC_COOKIE cookie,
  1369. LPPROPERTYSHEETCALLBACK lpProvider,
  1370. LPDATAOBJECT pDataObject,
  1371. LONG_PTR handle
  1372. )
  1373. {
  1374. // Forward this call onto the NodeHandler::CreatePropertyPages
  1375. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1376. HRESULT hr = hrOK;
  1377. SPITFSNode spNode;
  1378. Assert( m_spNodeMgr );
  1379. CORg( m_spNodeMgr->FindNode(cookie, &spNode) );
  1380. // Call the ITFSNodeHandler::CreatePropertyPages
  1381. hr = CreatePropertyPages(spNode, lpProvider, pDataObject, handle, 0);
  1382. Error:
  1383. return hr;
  1384. }