Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1868 lines
51 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. srview.cpp
  7. Static routes node implementation.
  8. FILE HISTORY:
  9. */
  10. #include "stdafx.h"
  11. #include "util.h"
  12. #include "srview.h"
  13. #include "reg.h"
  14. #include "ipxadmin.h"
  15. #include "rtrutil.h" // smart MPR handle pointers
  16. #include "ipxstrm.h" // IPXAdminConfigStream
  17. #include "strmap.h" // XXXtoCString functions
  18. #include "service.h" // TFS service APIs
  19. #include "format.h" // FormatNumber function
  20. #include "coldlg.h" // columndlg
  21. #include "ipxutil.h"
  22. #include "column.h" // ComponentConfigStream
  23. #include "rtrui.h"
  24. #include "routprot.h" // IP_LOCAL
  25. #include "rtrres.h"
  26. #include "dumbprop.h"
  27. #include "IpxStaticRoute.h"
  28. /*---------------------------------------------------------------------------
  29. Keep this in sync with the column ids in srview.h
  30. ---------------------------------------------------------------------------*/
  31. extern const ContainerColumnInfo s_rgSRViewColumnInfo[];
  32. const ContainerColumnInfo s_rgSRViewColumnInfo[] =
  33. {
  34. { IDS_IPX_SR_COL_NAME, CON_SORT_BY_STRING, TRUE, COL_IF_NAME },
  35. { IDS_IPX_SR_COL_NETWORK, CON_SORT_BY_STRING, TRUE, COL_IPXNET },
  36. { IDS_IPX_SR_COL_NEXT_HOP, CON_SORT_BY_STRING, TRUE, COL_STRING },
  37. { IDS_IPX_SR_COL_TICK_COUNT, CON_SORT_BY_DWORD, TRUE, COL_SMALL_NUM },
  38. { IDS_IPX_SR_COL_HOP_COUNT, CON_SORT_BY_DWORD, TRUE, COL_SMALL_NUM },
  39. };
  40. /*---------------------------------------------------------------------------
  41. IpxSRHandler implementation
  42. ---------------------------------------------------------------------------*/
  43. DEBUG_DECLARE_INSTANCE_COUNTER(IpxSRHandler)
  44. IpxSRHandler::IpxSRHandler(ITFSComponentData *pCompData)
  45. : BaseContainerHandler(pCompData, COLUMNS_STATICROUTES,
  46. s_rgSRViewColumnInfo),
  47. m_ulConnId(0),
  48. m_ulRefreshConnId(0)
  49. {
  50. // Setup the verb states
  51. m_rgButtonState[MMC_VERB_REFRESH_INDEX] = ENABLED;
  52. m_bState[MMC_VERB_REFRESH_INDEX] = TRUE;
  53. DEBUG_INCREMENT_INSTANCE_COUNTER(IpxSRHandler)
  54. }
  55. IpxSRHandler::~IpxSRHandler()
  56. {
  57. DEBUG_DECREMENT_INSTANCE_COUNTER(IpxSRHandler)
  58. }
  59. STDMETHODIMP IpxSRHandler::QueryInterface(REFIID riid, LPVOID *ppv)
  60. {
  61. // Is the pointer bad?
  62. if (ppv == NULL)
  63. return E_INVALIDARG;
  64. // Place NULL in *ppv in case of failure
  65. *ppv = NULL;
  66. // This is the non-delegating IUnknown implementation
  67. if (riid == IID_IUnknown)
  68. *ppv = (LPVOID) this;
  69. else if (riid == IID_IRtrAdviseSink)
  70. *ppv = &m_IRtrAdviseSink;
  71. else
  72. return BaseContainerHandler::QueryInterface(riid, ppv);
  73. // If we're going to return an interface, AddRef it first
  74. if (*ppv)
  75. {
  76. ((LPUNKNOWN) *ppv)->AddRef();
  77. return hrOK;
  78. }
  79. else
  80. return E_NOINTERFACE;
  81. }
  82. /*!--------------------------------------------------------------------------
  83. IpxSRHandler::DestroyHandler
  84. Implementation of ITFSNodeHandler::DestroyHandler
  85. Author: KennT
  86. ---------------------------------------------------------------------------*/
  87. STDMETHODIMP IpxSRHandler::DestroyHandler(ITFSNode *pNode)
  88. {
  89. IPXConnection * pIPXConn;
  90. pIPXConn = GET_IPX_SR_NODEDATA(pNode);
  91. pIPXConn->Release();
  92. if (m_ulRefreshConnId)
  93. {
  94. SPIRouterRefresh spRefresh;
  95. if (m_spRouterInfo)
  96. m_spRouterInfo->GetRefreshObject(&spRefresh);
  97. if (spRefresh)
  98. spRefresh->UnadviseRefresh(m_ulRefreshConnId);
  99. }
  100. m_ulRefreshConnId = 0;
  101. if (m_ulConnId)
  102. m_spRtrMgrInfo->RtrUnadvise(m_ulConnId);
  103. m_ulConnId = 0;
  104. m_spRtrMgrInfo.Release();
  105. m_spRouterInfo.Release();
  106. return hrOK;
  107. }
  108. /*!--------------------------------------------------------------------------
  109. IpxSRHandler::HasPropertyPages
  110. Implementation of ITFSNodeHandler::HasPropertyPages
  111. NOTE: the root node handler has to over-ride this function to
  112. handle the snapin manager property page (wizard) case!!!
  113. Author: KennT
  114. ---------------------------------------------------------------------------*/
  115. STDMETHODIMP
  116. IpxSRHandler::HasPropertyPages
  117. (
  118. ITFSNode * pNode,
  119. LPDATAOBJECT pDataObject,
  120. DATA_OBJECT_TYPES type,
  121. DWORD dwType
  122. )
  123. {
  124. return hrFalse;
  125. }
  126. /*---------------------------------------------------------------------------
  127. Menu data structure for our menus
  128. ---------------------------------------------------------------------------*/
  129. static const SRouterNodeMenu s_rgIfNodeMenu[] =
  130. {
  131. { IDS_MENU_IPX_SR_NEW_ROUTE, 0,
  132. CCM_INSERTIONPOINTID_PRIMARY_TOP },
  133. { IDS_MENU_SEPARATOR, 0,
  134. CCM_INSERTIONPOINTID_PRIMARY_TOP },
  135. { IDS_MENU_IPX_SR_TASK_ROUTING, 0,
  136. CCM_INSERTIONPOINTID_PRIMARY_TOP },
  137. };
  138. /*!--------------------------------------------------------------------------
  139. IpxSRHandler::OnAddMenuItems
  140. Implementation of ITFSNodeHandler::OnAddMenuItems
  141. Author: KennT
  142. ---------------------------------------------------------------------------*/
  143. STDMETHODIMP IpxSRHandler::OnAddMenuItems(
  144. ITFSNode *pNode,
  145. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  146. LPDATAOBJECT lpDataObject,
  147. DATA_OBJECT_TYPES type,
  148. DWORD dwType,
  149. long *pInsertionAllowed)
  150. {
  151. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  152. HRESULT hr = S_OK;
  153. IpxSRHandler::SMenuData menuData;
  154. COM_PROTECT_TRY
  155. {
  156. menuData.m_spNode.Set(pNode);
  157. hr = AddArrayOfMenuItems(pNode, s_rgIfNodeMenu,
  158. DimensionOf(s_rgIfNodeMenu),
  159. pContextMenuCallback,
  160. *pInsertionAllowed,
  161. reinterpret_cast<INT_PTR>(&menuData));
  162. }
  163. COM_PROTECT_CATCH;
  164. return hr;
  165. }
  166. /*!--------------------------------------------------------------------------
  167. IpxSRHandler::OnCommand
  168. Implementation of ITFSNodeHandler::OnCommand
  169. Author: KennT
  170. ---------------------------------------------------------------------------*/
  171. STDMETHODIMP IpxSRHandler::OnCommand(ITFSNode *pNode, long nCommandId,
  172. DATA_OBJECT_TYPES type,
  173. LPDATAOBJECT pDataObject,
  174. DWORD dwType)
  175. {
  176. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  177. HRESULT hr = S_OK;
  178. COM_PROTECT_TRY
  179. {
  180. switch (nCommandId)
  181. {
  182. case IDS_MENU_IPX_SR_NEW_ROUTE:
  183. hr = OnNewRoute(pNode);
  184. if (!FHrSucceeded(hr))
  185. DisplayErrorMessage(NULL, hr);
  186. break;
  187. case IDS_MENU_IPX_SR_TASK_ROUTING:
  188. hr = ForwardCommandToParent(pNode,
  189. IDS_MENU_IPXSUM_TASK_ROUTING_TABLE,
  190. type, pDataObject, dwType);
  191. break;
  192. case IDS_MENU_SYNC:
  193. SynchronizeNodeData(pNode);
  194. break;
  195. }
  196. }
  197. COM_PROTECT_CATCH;
  198. return hr;
  199. }
  200. /*!--------------------------------------------------------------------------
  201. IpxSRHandler::GenerateListOfRoutes
  202. -
  203. Author: KennT
  204. ---------------------------------------------------------------------------*/
  205. HRESULT IpxSRHandler::GenerateListOfRoutes(ITFSNode *pNode, IpxSRList *pSRList)
  206. {
  207. Assert(pSRList);
  208. HRESULT hr = hrOK;
  209. SPIEnumInterfaceInfo spEnumIf;
  210. SPIInterfaceInfo spIf;
  211. SPIRtrMgrInterfaceInfo spRmIf;
  212. SPIInfoBase spInfoBase;
  213. PIPX_STATIC_ROUTE_INFO pRoute;
  214. InfoBlock * pBlock;
  215. int i;
  216. IpxSRListEntry * pSREntry;
  217. COM_PROTECT_TRY
  218. {
  219. // Ok go through and find all of the static routes
  220. CORg( m_spRouterInfo->EnumInterface(&spEnumIf) );
  221. for (; spEnumIf->Next(1, &spIf, NULL) == hrOK; spIf.Release())
  222. {
  223. // Get the next interface
  224. spRmIf.Release();
  225. if (spIf->FindRtrMgrInterface(PID_IPX, &spRmIf) != hrOK)
  226. continue;
  227. // Load IP information for this interface
  228. spInfoBase.Release();
  229. if (spRmIf->GetInfoBase(NULL, NULL, NULL, &spInfoBase) != hrOK)
  230. continue;
  231. // Retrieve the data for the IPX_STATIC_ROUTE_INFO block
  232. if (spInfoBase->GetBlock(IPX_STATIC_ROUTE_INFO_TYPE, &pBlock, 0) != hrOK)
  233. continue;
  234. pRoute = (PIPX_STATIC_ROUTE_INFO) pBlock->pData;
  235. // Update our list of routes with the routes read from this
  236. // interface
  237. for (i=0; i<(int) pBlock->dwCount; i++, pRoute++)
  238. {
  239. pSREntry = new IpxSRListEntry;
  240. pSREntry->m_spIf.Set(spIf);
  241. pSREntry->m_route = *pRoute;
  242. pSRList->AddTail(pSREntry);
  243. }
  244. }
  245. }
  246. COM_PROTECT_CATCH;
  247. if (!FHrSucceeded(hr))
  248. {
  249. // Should make sure that we get the SRList cleaned up
  250. while (!pSRList->IsEmpty())
  251. delete pSRList->RemoveHead();
  252. }
  253. Error:
  254. return hr;
  255. }
  256. /*!--------------------------------------------------------------------------
  257. IpxSRHandler::OnExpand
  258. -
  259. Author: KennT
  260. ---------------------------------------------------------------------------*/
  261. HRESULT IpxSRHandler::OnExpand(ITFSNode *pNode,LPDATAOBJECT pDataObject, DWORD dwType, LPARAM arg,LPARAM lParam)
  262. {
  263. HRESULT hr = hrOK;
  264. IpxSRList SRList;
  265. IpxSRListEntry * pSREntry;
  266. if (m_bExpanded)
  267. return hrOK;
  268. COM_PROTECT_TRY
  269. {
  270. // Ok go through and find all of the static routes
  271. CORg( GenerateListOfRoutes(pNode, &SRList) );
  272. // Now iterate through the list of static routes adding them
  273. // all in. Ideally we could merge this into the Refresh code,
  274. // but the refresh code can't assume a blank slate.
  275. while (!SRList.IsEmpty())
  276. {
  277. pSREntry = SRList.RemoveHead();
  278. AddStaticRouteNode(pNode, pSREntry);
  279. delete pSREntry;
  280. }
  281. COM_PROTECT_ERROR_LABEL;
  282. }
  283. COM_PROTECT_CATCH;
  284. // Should make sure that we get the SRList cleaned up
  285. while (!SRList.IsEmpty())
  286. delete SRList.RemoveHead();
  287. m_bExpanded = TRUE;
  288. return hr;
  289. }
  290. /*!--------------------------------------------------------------------------
  291. IpxSRHandler::GetString
  292. Implementation of ITFSNodeHandler::GetString
  293. We don't need to do anything, since our root node is an extension
  294. only and thus can't do anything to the node text.
  295. Author: KennT
  296. ---------------------------------------------------------------------------*/
  297. STDMETHODIMP_(LPCTSTR) IpxSRHandler::GetString(ITFSNode *pNode, int nCol)
  298. {
  299. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  300. HRESULT hr = hrOK;
  301. COM_PROTECT_TRY
  302. {
  303. if (m_stTitle.IsEmpty())
  304. m_stTitle.LoadString(IDS_IPX_SR_TITLE);
  305. }
  306. COM_PROTECT_CATCH;
  307. return m_stTitle;
  308. }
  309. /*!--------------------------------------------------------------------------
  310. IpxSRHandler::OnCreateDataObject
  311. -
  312. Author: KennT
  313. ---------------------------------------------------------------------------*/
  314. STDMETHODIMP IpxSRHandler::OnCreateDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, IDataObject **ppDataObject)
  315. {
  316. HRESULT hr = hrOK;
  317. COM_PROTECT_TRY
  318. {
  319. Assert(m_spRtrMgrInfo);
  320. CORg( CreateDataObjectFromRtrMgrInfo(m_spRtrMgrInfo,
  321. type, cookie, m_spTFSCompData,
  322. ppDataObject) );
  323. COM_PROTECT_ERROR_LABEL;
  324. }
  325. COM_PROTECT_CATCH;
  326. return hr;
  327. }
  328. /*!--------------------------------------------------------------------------
  329. IpxSRHandler::Init
  330. -
  331. Author: KennT
  332. ---------------------------------------------------------------------------*/
  333. HRESULT IpxSRHandler::Init(IRtrMgrInfo *pRmInfo, IPXAdminConfigStream *pConfigStream)
  334. {
  335. m_spRtrMgrInfo.Set(pRmInfo);
  336. if (pRmInfo)
  337. pRmInfo->GetParentRouterInfo(&m_spRouterInfo);
  338. m_pConfigStream = pConfigStream;
  339. // Also need to register for change notifications
  340. Assert(m_ulConnId == 0);
  341. m_spRtrMgrInfo->RtrAdvise(&m_IRtrAdviseSink, &m_ulConnId, 0);
  342. return hrOK;
  343. }
  344. /*!--------------------------------------------------------------------------
  345. IpxSRHandler::ConstructNode
  346. Initializes the root node (sets it up).
  347. Author: KennT
  348. ---------------------------------------------------------------------------*/
  349. HRESULT IpxSRHandler::ConstructNode(ITFSNode *pNode, LPCTSTR pszName,
  350. IPXConnection *pIPXConn)
  351. {
  352. Assert(pIPXConn);
  353. HRESULT hr = hrOK;
  354. if (pNode == NULL)
  355. return hrOK;
  356. COM_PROTECT_TRY
  357. {
  358. // Need to initialize the data for the root node
  359. pNode->SetData(TFS_DATA_IMAGEINDEX, IMAGE_IDX_IPX_NODE_GENERAL);
  360. pNode->SetData(TFS_DATA_OPENIMAGEINDEX, IMAGE_IDX_IPX_NODE_GENERAL);
  361. pNode->SetData(TFS_DATA_SCOPEID, 0);
  362. // This is a leaf node in the scope pane
  363. pNode->SetData(TFS_DATA_SCOPE_LEAF_NODE, TRUE);
  364. m_cookie = reinterpret_cast<DWORD_PTR>(pNode);
  365. pNode->SetData(TFS_DATA_COOKIE, m_cookie);
  366. pNode->SetNodeType(&GUID_IPXStaticRoutesNodeType);
  367. // Setup the node data
  368. pIPXConn->AddRef();
  369. SET_IPX_SR_NODEDATA(pNode, pIPXConn);
  370. }
  371. COM_PROTECT_CATCH;
  372. if (!FHrSucceeded(hr))
  373. {
  374. SET_IPX_SR_NODEDATA(pNode, NULL);
  375. }
  376. return hr;
  377. }
  378. /*!--------------------------------------------------------------------------
  379. IpxSRHandler::AddStaticRouteNode
  380. -
  381. Author: KennT
  382. ---------------------------------------------------------------------------*/
  383. HRESULT IpxSRHandler::AddStaticRouteNode(ITFSNode *pParent, IpxSRListEntry *pRoute)
  384. {
  385. IpxRouteHandler * pHandler;
  386. SPITFSResultHandler spHandler;
  387. SPITFSNode spNode;
  388. HRESULT hr = hrOK;
  389. BaseIPXResultNodeData * pData;
  390. IPXConnection * pIPXConn;
  391. // Create the handler for this node
  392. pHandler = new IpxRouteHandler(m_spTFSCompData);
  393. spHandler = pHandler;
  394. CORg( pHandler->Init(pRoute->m_spIf, pParent) );
  395. pIPXConn = GET_IPX_SR_NODEDATA(pParent);
  396. // Create a result item node (or a leaf node)
  397. CORg( CreateLeafTFSNode(&spNode,
  398. NULL,
  399. static_cast<ITFSNodeHandler *>(pHandler),
  400. static_cast<ITFSResultHandler *>(pHandler),
  401. m_spNodeMgr) );
  402. CORg( pHandler->ConstructNode(spNode, pRoute->m_spIf, pIPXConn) );
  403. pData = GET_BASEIPXRESULT_NODEDATA(spNode);
  404. Assert(pData);
  405. ASSERT_BASEIPXRESULT_NODEDATA(pData);
  406. // Set the data for this node
  407. SetRouteData(pData, pRoute);
  408. // Make the node immediately visible
  409. CORg( spNode->SetVisibilityState(TFS_VIS_SHOW) );
  410. CORg( pParent->AddChild(spNode) );
  411. Error:
  412. return hr;
  413. }
  414. /*!--------------------------------------------------------------------------
  415. IpxSRHandler::SynchronizeNodeData
  416. -
  417. Author: KennT
  418. ---------------------------------------------------------------------------*/
  419. HRESULT IpxSRHandler::SynchronizeNodeData(ITFSNode *pNode)
  420. {
  421. HRESULT hr = hrOK;
  422. BaseIPXResultNodeData * pNodeData;
  423. SPITFSNodeEnum spNodeEnum;
  424. SPITFSNode spChildNode;
  425. BOOL fFound;
  426. IpxSRList SRList;
  427. IpxSRList newSRList;
  428. IpxSRListEntry * pSREntry;
  429. COM_PROTECT_TRY
  430. {
  431. // Mark all of the nodes
  432. CORg( pNode->GetEnum(&spNodeEnum) );
  433. MarkAllNodes(pNode, spNodeEnum);
  434. // Go out and grab the data, merge the new data in with the old data
  435. // This is the data-gathering code and this is what should go
  436. // on the background thread for the refresh code.
  437. CORg( GenerateListOfRoutes(pNode, &SRList) );
  438. while (!SRList.IsEmpty())
  439. {
  440. pSREntry = SRList.RemoveHead();
  441. // Look for this entry in our current list of nodes
  442. spNodeEnum->Reset();
  443. spChildNode.Release();
  444. fFound = FALSE;
  445. for (;spNodeEnum->Next(1, &spChildNode, NULL) == hrOK; spChildNode.Release())
  446. {
  447. TCHAR szNumber[32];
  448. pNodeData = GET_BASEIPXRESULT_NODEDATA(spChildNode);
  449. Assert(pNodeData);
  450. ASSERT_BASEIPXRESULT_NODEDATA(pNodeData);
  451. FormatMACAddress(szNumber,
  452. DimensionOf(szNumber),
  453. pSREntry->m_route.NextHopMacAddress,
  454. DimensionOf(pSREntry->m_route.NextHopMacAddress));
  455. if ((memcmp(&(pNodeData->m_rgData[IPX_SR_SI_NETWORK].m_dwData),
  456. pSREntry->m_route.Network,
  457. sizeof(pSREntry->m_route.Network)) == 0) &&
  458. (StriCmp(pNodeData->m_spIf->GetId(), pSREntry->m_spIf->GetId()) == 0) &&
  459. (StriCmp(pNodeData->m_rgData[IPX_SR_SI_NEXT_HOP].m_stData, szNumber) == 0))
  460. {
  461. // Ok, this route already exists, update the metric
  462. // and mark it
  463. Assert(pNodeData->m_dwMark == FALSE);
  464. pNodeData->m_dwMark = TRUE;
  465. fFound = TRUE;
  466. SetRouteData(pNodeData, pSREntry);
  467. // Force MMC to redraw the node
  468. spChildNode->ChangeNode(RESULT_PANE_CHANGE_ITEM_DATA);
  469. break;
  470. }
  471. }
  472. if (fFound)
  473. delete pSREntry;
  474. else
  475. newSRList.AddTail(pSREntry);
  476. }
  477. // Now remove all nodes that were not marked
  478. RemoveAllUnmarkedNodes(pNode, spNodeEnum);
  479. // Now iterate through the list of static routes adding them
  480. // all in. Ideally we could merge this into the Refresh code,
  481. // but the refresh code can't assume a blank slate.
  482. POSITION pos;
  483. while (!newSRList.IsEmpty())
  484. {
  485. pSREntry = newSRList.RemoveHead();
  486. AddStaticRouteNode(pNode, pSREntry);
  487. delete pSREntry;
  488. }
  489. COM_PROTECT_ERROR_LABEL;
  490. }
  491. COM_PROTECT_CATCH;
  492. while (!SRList.IsEmpty())
  493. delete SRList.RemoveHead();
  494. while (!newSRList.IsEmpty())
  495. delete newSRList.RemoveHead();
  496. return hr;
  497. }
  498. /*!--------------------------------------------------------------------------
  499. IpxSRHandler::MarkAllNodes
  500. -
  501. Author: KennT
  502. ---------------------------------------------------------------------------*/
  503. HRESULT IpxSRHandler::MarkAllNodes(ITFSNode *pNode, ITFSNodeEnum *pEnum)
  504. {
  505. SPITFSNode spChildNode;
  506. BaseIPXResultNodeData * pNodeData;
  507. pEnum->Reset();
  508. for ( ;pEnum->Next(1, &spChildNode, NULL) == hrOK; spChildNode.Release())
  509. {
  510. pNodeData = GET_BASEIPXRESULT_NODEDATA(spChildNode);
  511. Assert(pNodeData);
  512. ASSERT_BASEIPXRESULT_NODEDATA(pNodeData);
  513. pNodeData->m_dwMark = FALSE;
  514. }
  515. return hrOK;
  516. }
  517. /*!--------------------------------------------------------------------------
  518. IpxSRHandler::RemoveAllUnmarkedNodes
  519. -
  520. Author: KennT
  521. ---------------------------------------------------------------------------*/
  522. HRESULT IpxSRHandler::RemoveAllUnmarkedNodes(ITFSNode *pNode, ITFSNodeEnum *pEnum)
  523. {
  524. HRESULT hr = hrOK;
  525. SPITFSNode spChildNode;
  526. BaseIPXResultNodeData * pNodeData;
  527. pEnum->Reset();
  528. for ( ;pEnum->Next(1, &spChildNode, NULL) == hrOK; spChildNode.Release())
  529. {
  530. pNodeData = GET_BASEIPXRESULT_NODEDATA(spChildNode);
  531. Assert(pNodeData);
  532. ASSERT_BASEIPXRESULT_NODEDATA(pNodeData);
  533. if (pNodeData->m_dwMark == FALSE)
  534. {
  535. pNode->RemoveChild(spChildNode);
  536. spChildNode->Destroy();
  537. }
  538. }
  539. return hr;
  540. }
  541. /*---------------------------------------------------------------------------
  542. This is the set of menus that will appear when a right-click is
  543. done on the blank area of the result pane.
  544. ---------------------------------------------------------------------------*/
  545. static const SRouterNodeMenu s_rgIfResultNodeMenu[] =
  546. {
  547. { IDS_MENU_IPX_SR_NEW_ROUTE, 0,
  548. CCM_INSERTIONPOINTID_PRIMARY_TOP },
  549. { IDS_MENU_SEPARATOR, 0,
  550. CCM_INSERTIONPOINTID_PRIMARY_TOP },
  551. { IDS_MENU_IPX_SR_TASK_ROUTING, 0,
  552. CCM_INSERTIONPOINTID_PRIMARY_TOP },
  553. };
  554. /*!--------------------------------------------------------------------------
  555. IpxSRHandler::AddMenuItems
  556. Implementation of ITFSResultHandler::AddMenuItems
  557. Use this to add commands to the context menu of the blank areas
  558. of the result pane.
  559. Author: KennT
  560. ---------------------------------------------------------------------------*/
  561. STDMETHODIMP IpxSRHandler::AddMenuItems(ITFSComponent *pComponent,
  562. MMC_COOKIE cookie,
  563. LPDATAOBJECT pDataObject,
  564. LPCONTEXTMENUCALLBACK pCallback,
  565. long *pInsertionAllowed)
  566. {
  567. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  568. HRESULT hr = hrOK;
  569. SPITFSNode spNode;
  570. IpxSRHandler::SMenuData menuData;
  571. COM_PROTECT_TRY
  572. {
  573. m_spNodeMgr->FindNode(cookie, &spNode);
  574. menuData.m_spNode.Set(spNode);
  575. hr = AddArrayOfMenuItems(spNode,
  576. s_rgIfResultNodeMenu,
  577. DimensionOf(s_rgIfResultNodeMenu),
  578. pCallback,
  579. *pInsertionAllowed,
  580. reinterpret_cast<INT_PTR>(&menuData));
  581. }
  582. COM_PROTECT_CATCH;
  583. return hr;
  584. }
  585. /*!--------------------------------------------------------------------------
  586. IpxSRHandler::Command
  587. -
  588. Author: KennT
  589. ---------------------------------------------------------------------------*/
  590. STDMETHODIMP IpxSRHandler::Command(ITFSComponent *pComponent,
  591. MMC_COOKIE cookie,
  592. int nCommandID,
  593. LPDATAOBJECT pDataObject)
  594. {
  595. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  596. SPITFSNode spNode;
  597. HRESULT hr = hrOK;
  598. switch (nCommandID)
  599. {
  600. case IDS_MENU_IPX_SR_NEW_ROUTE:
  601. {
  602. m_spNodeMgr->FindNode(cookie, &spNode);
  603. hr = OnNewRoute(spNode);
  604. if (!FHrSucceeded(hr))
  605. DisplayErrorMessage(NULL, hr);
  606. }
  607. break;
  608. case IDS_MENU_IPX_SR_TASK_ROUTING:
  609. {
  610. m_spNodeMgr->FindNode(cookie, &spNode);
  611. hr = ForwardCommandToParent(spNode,
  612. IDS_MENU_IPXSUM_TASK_ROUTING_TABLE,
  613. CCT_RESULT, NULL, 0
  614. );
  615. }
  616. break;
  617. }
  618. return hr;
  619. }
  620. /*!--------------------------------------------------------------------------
  621. IpxSRHandler::CompareItems
  622. -
  623. Author: KennT
  624. ---------------------------------------------------------------------------*/
  625. STDMETHODIMP_(int) IpxSRHandler::CompareItems(
  626. ITFSComponent * pComponent,
  627. MMC_COOKIE cookieA,
  628. MMC_COOKIE cookieB,
  629. int nCol)
  630. {
  631. // Get the strings from the nodes and use that as a basis for
  632. // comparison.
  633. SPITFSNode spNode;
  634. SPITFSResultHandler spResult;
  635. m_spNodeMgr->FindNode(cookieA, &spNode);
  636. spNode->GetResultHandler(&spResult);
  637. return spResult->CompareItems(pComponent, cookieA, cookieB, nCol);
  638. }
  639. /*!--------------------------------------------------------------------------
  640. IpxSRHandler::OnNewRoute
  641. -
  642. Author: KennT
  643. ---------------------------------------------------------------------------*/
  644. HRESULT IpxSRHandler::OnNewRoute(ITFSNode *pNode)
  645. {
  646. HRESULT hr = hrOK;
  647. IpxSRListEntry SREntry;
  648. CStaticRouteDlg srdlg(&SREntry, 0, m_spRouterInfo);
  649. SPIInfoBase spInfoBase;
  650. SPIRtrMgrInterfaceInfo spRmIf;
  651. IPXConnection * pIPXConn;
  652. InfoBlock * pBlock;
  653. pIPXConn = GET_IPX_SR_NODEDATA(pNode);
  654. Assert(pIPXConn);
  655. ::ZeroMemory(&(SREntry.m_route), sizeof(SREntry.m_route));
  656. if (srdlg.DoModal() == IDOK)
  657. {
  658. CORg( SREntry.m_spIf->FindRtrMgrInterface(PID_IPX, &spRmIf) );
  659. CORg( spRmIf->GetInfoBase(pIPXConn->GetConfigHandle(),
  660. NULL,
  661. NULL,
  662. &spInfoBase));
  663. // Ok, go ahead and add the route
  664. // Get the IPX_STATIC_ROUTE_INFO block from the interface
  665. spInfoBase->GetBlock(IPX_STATIC_ROUTE_INFO_TYPE, &pBlock, 0);
  666. CORg( AddStaticRoute(&SREntry, spInfoBase, pBlock) );
  667. // Update the interface information
  668. CORg( spRmIf->Save(SREntry.m_spIf->GetMachineName(),
  669. pIPXConn->GetConfigHandle(),
  670. NULL,
  671. NULL,
  672. spInfoBase,
  673. 0));
  674. // Refresh the node
  675. SynchronizeNodeData(pNode);
  676. }
  677. Error:
  678. return hr;
  679. }
  680. ImplementEmbeddedUnknown(IpxSRHandler, IRtrAdviseSink)
  681. STDMETHODIMP IpxSRHandler::EIRtrAdviseSink::OnChange(LONG_PTR ulConn,
  682. DWORD dwChangeType, DWORD dwObjectType, LPARAM lUserParam, LPARAM lParam)
  683. {
  684. InitPThis(IpxSRHandler, IRtrAdviseSink);
  685. HRESULT hr = hrOK;
  686. COM_PROTECT_TRY
  687. {
  688. if (dwChangeType == ROUTER_REFRESH)
  689. {
  690. SPITFSNode spNode;
  691. Assert(ulConn == pThis->m_ulRefreshConnId);
  692. pThis->m_spNodeMgr->FindNode(pThis->m_cookie, &spNode);
  693. pThis->SynchronizeNodeData(spNode);
  694. }
  695. }
  696. COM_PROTECT_CATCH;
  697. return hr;
  698. }
  699. HRESULT IpxSRHandler::OnResultRefresh(ITFSComponent * pComponent, LPDATAOBJECT pDataObject, MMC_COOKIE cookie, LPARAM arg, LPARAM lParam)
  700. {
  701. HRESULT hr = hrOK;
  702. SPITFSNode spNode, spParent;
  703. SPITFSResultHandler spParentRH;
  704. m_spNodeMgr->FindNode(cookie, &spNode);
  705. // forward this command to the parent to handle
  706. CORg (spNode->GetParent(&spParent));
  707. CORg (spParent->GetResultHandler(&spParentRH));
  708. CORg (spParentRH->Notify(pComponent, spParent->GetData(TFS_DATA_COOKIE), pDataObject, MMCN_REFRESH, arg, lParam));
  709. Error:
  710. return hrOK;
  711. }
  712. /*!--------------------------------------------------------------------------
  713. IpxSRHandler::OnResultShow
  714. -
  715. Author: KennT
  716. ---------------------------------------------------------------------------*/
  717. HRESULT IpxSRHandler::OnResultShow(ITFSComponent *pTFSComponent, MMC_COOKIE cookie, LPARAM arg, LPARAM lParam)
  718. {
  719. BOOL bSelect = (BOOL) arg;
  720. HRESULT hr = hrOK;
  721. SPIRouterRefresh spRefresh;
  722. SPITFSNode spNode;
  723. BaseContainerHandler::OnResultShow(pTFSComponent, cookie, arg, lParam);
  724. if (bSelect)
  725. {
  726. // Call synchronize on this node
  727. m_spNodeMgr->FindNode(cookie, &spNode);
  728. if (spNode)
  729. SynchronizeNodeData(spNode);
  730. }
  731. // Un/Register for refresh advises
  732. if (m_spRouterInfo)
  733. m_spRouterInfo->GetRefreshObject(&spRefresh);
  734. if (spRefresh)
  735. {
  736. if (bSelect)
  737. {
  738. if (m_ulRefreshConnId == 0)
  739. spRefresh->AdviseRefresh(&m_IRtrAdviseSink, &m_ulRefreshConnId, 0);
  740. }
  741. else
  742. {
  743. if (m_ulRefreshConnId)
  744. spRefresh->UnadviseRefresh(m_ulRefreshConnId);
  745. m_ulRefreshConnId = 0;
  746. }
  747. }
  748. return hr;
  749. }
  750. /*---------------------------------------------------------------------------
  751. Class: IpxRouteHandler
  752. ---------------------------------------------------------------------------*/
  753. IpxRouteHandler::IpxRouteHandler(ITFSComponentData *pCompData)
  754. : BaseIPXResultHandler(pCompData, COLUMNS_STATICROUTES),
  755. m_ulConnId(0)
  756. {
  757. m_rgButtonState[MMC_VERB_PROPERTIES_INDEX] = ENABLED;
  758. m_bState[MMC_VERB_PROPERTIES_INDEX] = TRUE;
  759. m_rgButtonState[MMC_VERB_DELETE_INDEX] = ENABLED;
  760. m_bState[MMC_VERB_DELETE_INDEX] = TRUE;
  761. m_rgButtonState[MMC_VERB_REFRESH_INDEX] = ENABLED;
  762. m_bState[MMC_VERB_REFRESH_INDEX] = TRUE;
  763. m_verbDefault = MMC_VERB_PROPERTIES;
  764. }
  765. /*!--------------------------------------------------------------------------
  766. IpxRouteHandler::ConstructNode
  767. Initializes the Domain node (sets it up).
  768. Author: KennT
  769. ---------------------------------------------------------------------------*/
  770. HRESULT IpxRouteHandler::ConstructNode(ITFSNode *pNode, IInterfaceInfo *pIfInfo, IPXConnection *pIPXConn)
  771. {
  772. HRESULT hr = hrOK;
  773. int i;
  774. if (pNode == NULL)
  775. return hrOK;
  776. COM_PROTECT_TRY
  777. {
  778. // Need to initialize the data for the Domain node
  779. pNode->SetData(TFS_DATA_SCOPEID, 0);
  780. // We don't want icons for these nodes.
  781. pNode->SetData(TFS_DATA_IMAGEINDEX, IMAGE_IDX_IPX_NODE_GENERAL);
  782. pNode->SetData(TFS_DATA_OPENIMAGEINDEX, IMAGE_IDX_IPX_NODE_GENERAL);
  783. pNode->SetData(TFS_DATA_COOKIE, reinterpret_cast<DWORD_PTR>(pNode));
  784. //$ Review: kennt, what are the different type of interfaces
  785. // do we distinguish based on the same list as above? (i.e. the
  786. // one for image indexes).
  787. pNode->SetNodeType(&GUID_IPXStaticRoutesResultNodeType);
  788. BaseIPXResultNodeData::Init(pNode, pIfInfo, pIPXConn);
  789. }
  790. COM_PROTECT_CATCH
  791. return hr;
  792. }
  793. /*!--------------------------------------------------------------------------
  794. IpxRouteHandler::OnCreateDataObject
  795. -
  796. Author: KennT
  797. ---------------------------------------------------------------------------*/
  798. STDMETHODIMP IpxRouteHandler::OnCreateDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, IDataObject **ppDataObject)
  799. {
  800. HRESULT hr = hrOK;
  801. COM_PROTECT_TRY
  802. {
  803. CORg( CreateDataObjectFromInterfaceInfo(m_spInterfaceInfo,
  804. type, cookie, m_spTFSCompData,
  805. ppDataObject) );
  806. COM_PROTECT_ERROR_LABEL;
  807. }
  808. COM_PROTECT_CATCH;
  809. return hr;
  810. }
  811. /*!--------------------------------------------------------------------------
  812. IpxRouteHandler::OnCreateDataObject
  813. Implementation of ITFSResultHandler::OnCreateDataObject
  814. Author: KennT
  815. ---------------------------------------------------------------------------*/
  816. STDMETHODIMP IpxRouteHandler::OnCreateDataObject(ITFSComponent *pComp, MMC_COOKIE cookie, DATA_OBJECT_TYPES type, IDataObject **ppDataObject)
  817. {
  818. HRESULT hr = hrOK;
  819. COM_PROTECT_TRY
  820. {
  821. CORg( CreateDataObjectFromInterfaceInfo(m_spInterfaceInfo,
  822. type, cookie, m_spTFSCompData,
  823. ppDataObject) );
  824. COM_PROTECT_ERROR_LABEL;
  825. }
  826. COM_PROTECT_CATCH;
  827. return hr;
  828. }
  829. /*!--------------------------------------------------------------------------
  830. IpxRouteHandler::Init
  831. -
  832. Author: KennT
  833. ---------------------------------------------------------------------------*/
  834. HRESULT IpxRouteHandler::Init(IInterfaceInfo *pIfInfo, ITFSNode *pParent)
  835. {
  836. Assert(pIfInfo);
  837. m_spInterfaceInfo.Set(pIfInfo);
  838. if (pIfInfo)
  839. pIfInfo->GetParentRouterInfo(&m_spRouterInfo);
  840. BaseIPXResultHandler::Init(pIfInfo, pParent);
  841. return hrOK;
  842. }
  843. /*!--------------------------------------------------------------------------
  844. IpxRouteHandler::DestroyResultHandler
  845. -
  846. Author: KennT
  847. ---------------------------------------------------------------------------*/
  848. STDMETHODIMP IpxRouteHandler::DestroyResultHandler(MMC_COOKIE cookie)
  849. {
  850. m_spInterfaceInfo.Release();
  851. BaseIPXResultHandler::DestroyResultHandler(cookie);
  852. return hrOK;
  853. }
  854. /*!--------------------------------------------------------------------------
  855. IpxRouteHandler::AddMenuItems
  856. Implementation of ITFSResultHandler::AddMenuItems
  857. Author: KennT
  858. ---------------------------------------------------------------------------*/
  859. STDMETHODIMP IpxRouteHandler::AddMenuItems(
  860. ITFSComponent *pComponent,
  861. MMC_COOKIE cookie,
  862. LPDATAOBJECT lpDataObject,
  863. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  864. long *pInsertionAllowed)
  865. {
  866. return hrOK;
  867. }
  868. /*!--------------------------------------------------------------------------
  869. IpxRouteHandler::Command
  870. -
  871. Author: KennT
  872. ---------------------------------------------------------------------------*/
  873. STDMETHODIMP IpxRouteHandler::Command(ITFSComponent *pComponent,
  874. MMC_COOKIE cookie,
  875. int nCommandID,
  876. LPDATAOBJECT pDataObject)
  877. {
  878. return hrOK;
  879. }
  880. /*!--------------------------------------------------------------------------
  881. IpxRouteHandler::HasPropertyPages
  882. -
  883. Author: KennT
  884. ---------------------------------------------------------------------------*/
  885. STDMETHODIMP IpxRouteHandler::HasPropertyPages
  886. (
  887. ITFSNode * pNode,
  888. LPDATAOBJECT pDataObject,
  889. DATA_OBJECT_TYPES type,
  890. DWORD dwType
  891. )
  892. {
  893. return S_OK;
  894. /* AFX_MANAGE_STATE(AfxGetStaticModuleState());
  895. // Need to fill in a IpxSRListEntry
  896. IpxSRListEntry SREntry;
  897. IpxSRListEntry SREntryOld;
  898. SPIRouterInfo spRouterInfo;
  899. HRESULT hr = hrOK;
  900. CORg( m_spInterfaceInfo->GetParentRouterInfo(&spRouterInfo) );
  901. BaseIPXResultNodeData * pNodeData;
  902. pNodeData = GET_BASEIPXRESULT_NODEDATA(pNode);
  903. Assert(pNodeData);
  904. ASSERT_BASEIPXRESULT_NODEDATA(pNodeData);
  905. // Fill in our SREntry
  906. SREntry.LoadFrom(pNodeData);
  907. SREntryOld.LoadFrom(pNodeData);
  908. {
  909. CStaticRouteDlg srdlg(&SREntry, SR_DLG_MODIFY, spRouterInfo);
  910. if (srdlg.DoModal() == IDOK)
  911. {
  912. // Updates the route info for this route
  913. ModifyRouteInfo(pNode, &SREntry, &SREntryOld);
  914. // Update the data in the UI
  915. SetRouteData(pNodeData, &SREntry);
  916. m_spInterfaceInfo.Set(SREntry.m_spIf);
  917. // Force a refresh
  918. pNode->ChangeNode(RESULT_PANE_CHANGE_ITEM_DATA);
  919. }
  920. }
  921. Error:
  922. return hrOK;*/
  923. }
  924. STDMETHODIMP IpxRouteHandler::HasPropertyPages(ITFSComponent *pComponent,
  925. MMC_COOKIE cookie,
  926. LPDATAOBJECT pDataObject)
  927. {
  928. SPITFSNode spNode;
  929. m_spNodeMgr->FindNode(cookie, &spNode);
  930. return HasPropertyPages(spNode, pDataObject, CCT_RESULT, 0);
  931. }
  932. /*!--------------------------------------------------------------------------
  933. IpxRouteHandler::CreatePropertyPages
  934. Implementation of ResultHandler::CreatePropertyPages
  935. Author: KennT
  936. ---------------------------------------------------------------------------*/
  937. STDMETHODIMP IpxRouteHandler::CreatePropertyPages
  938. (
  939. ITFSComponent * pComponent,
  940. MMC_COOKIE cookie,
  941. LPPROPERTYSHEETCALLBACK lpProvider,
  942. LPDATAOBJECT pDataObject,
  943. LONG_PTR handle
  944. )
  945. {
  946. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  947. HRESULT hr = hrOK;
  948. SPITFSNode spNode;
  949. Assert( m_spNodeMgr );
  950. CORg( m_spNodeMgr->FindNode(cookie, &spNode) );
  951. // Call the ITFSNodeHandler::CreatePropertyPages
  952. hr = CreatePropertyPages(spNode, lpProvider, pDataObject, handle, 0);
  953. Error:
  954. return hr;
  955. }
  956. /*!--------------------------------------------------------------------------
  957. IpxRouteHandler::CreatePropertyPages
  958. Implementation of NodeHandler::CreatePropertyPages
  959. Author: Deonb
  960. ---------------------------------------------------------------------------*/
  961. STDMETHODIMP IpxRouteHandler::CreatePropertyPages
  962. (
  963. ITFSNode * pNode,
  964. LPPROPERTYSHEETCALLBACK lpProvider,
  965. LPDATAOBJECT pDataObject,
  966. LONG_PTR handle,
  967. DWORD dwType
  968. )
  969. {
  970. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  971. HRESULT hr = hrOK;
  972. IpxStaticRoutePropertySheet *pProperties = NULL;
  973. SPIComponentData spComponentData;
  974. CString stTitle;
  975. CComPtr<IInterfaceInfo> spInterfaceInfo;
  976. BaseIPXResultNodeData * pNodeData;
  977. CORg( m_spNodeMgr->GetComponentData(&spComponentData) );
  978. if (m_spInterfaceInfo)
  979. stTitle.Format(IDS_IPXSUMMARY_IF_PAGE_TITLE,
  980. m_spInterfaceInfo->GetTitle());
  981. else
  982. stTitle.LoadString(IDS_IPXSUMMARY_CLIENT_IF_PAGE_TITLE);
  983. pProperties = new IpxStaticRoutePropertySheet(pNode, spComponentData,
  984. m_spTFSCompData, stTitle);
  985. pNodeData = GET_BASEIPXRESULT_NODEDATA(pNode);
  986. Assert(pNodeData);
  987. ASSERT_BASEIPXRESULT_NODEDATA(pNodeData);
  988. CORg( m_spNodeMgr->GetComponentData(&spComponentData) );
  989. spInterfaceInfo = m_spInterfaceInfo;
  990. CORg( pProperties->Init(pNodeData, spInterfaceInfo) );
  991. if (lpProvider)
  992. hr = pProperties->CreateModelessSheet(lpProvider, handle);
  993. else
  994. hr = pProperties->DoModelessSheet();
  995. Error:
  996. return hr;
  997. }
  998. /*!--------------------------------------------------------------------------
  999. IpxRouteHandler::OnResultDelete
  1000. -
  1001. Author: KennT
  1002. ---------------------------------------------------------------------------*/
  1003. HRESULT IpxRouteHandler::OnResultDelete(ITFSComponent *pComponent,
  1004. LPDATAOBJECT pDataObject,
  1005. MMC_COOKIE cookie,
  1006. LPARAM arg,
  1007. LPARAM param)
  1008. {
  1009. SPITFSNode spNode;
  1010. m_spNodeMgr->FindNode(cookie, &spNode);
  1011. return OnRemoveStaticRoute(spNode);
  1012. }
  1013. /*!--------------------------------------------------------------------------
  1014. IpxRouteHandler::OnRemoveStaticRoute
  1015. -
  1016. Author: KennT
  1017. ---------------------------------------------------------------------------*/
  1018. HRESULT IpxRouteHandler::OnRemoveStaticRoute(ITFSNode *pNode)
  1019. {
  1020. HRESULT hr = hrOK;
  1021. SPIInfoBase spInfoBase;
  1022. SPIRtrMgrInterfaceInfo spRmIf;
  1023. IPXConnection *pIPXConn;
  1024. SPITFSNode spNodeParent;
  1025. BaseIPXResultNodeData * pData;
  1026. IpxSRListEntry SREntry;
  1027. CWaitCursor wait;
  1028. pNode->GetParent(&spNodeParent);
  1029. pIPXConn = GET_IPX_SR_NODEDATA(spNodeParent);
  1030. Assert(pIPXConn);
  1031. pData = GET_BASEIPXRESULT_NODEDATA(pNode);
  1032. Assert(pData);
  1033. ASSERT_BASEIPXRESULT_NODEDATA(pData);
  1034. //
  1035. // Load the old interface's information
  1036. //
  1037. Assert(lstrcmpi(m_spInterfaceInfo->GetId(), pData->m_spIf->GetId()) == 0);
  1038. CORg( m_spInterfaceInfo->FindRtrMgrInterface(PID_IPX, &spRmIf) );
  1039. CORg( spRmIf->GetInfoBase(pIPXConn->GetConfigHandle(),
  1040. NULL,
  1041. NULL,
  1042. &spInfoBase));
  1043. SREntry.LoadFrom(pData);
  1044. CORg( RemoveStaticRoute(&SREntry, spInfoBase) );
  1045. // Update the interface information
  1046. CORg( spRmIf->Save(m_spInterfaceInfo->GetMachineName(),
  1047. pIPXConn->GetConfigHandle(),
  1048. NULL,
  1049. NULL,
  1050. spInfoBase,
  1051. 0));
  1052. // Refresh the node
  1053. ParentRefresh(pNode);
  1054. Error:
  1055. return hr;
  1056. }
  1057. /*!--------------------------------------------------------------------------
  1058. IpxRouteHandler::RemoveStaticRoute
  1059. -
  1060. Author: KennT
  1061. ---------------------------------------------------------------------------*/
  1062. HRESULT IpxRouteHandler::RemoveStaticRoute(IpxSRListEntry *pSREntry,
  1063. IInfoBase *pInfoBase)
  1064. {
  1065. HRESULT hr = hrOK;
  1066. InfoBlock * pBlock;
  1067. PIPX_STATIC_ROUTE_INFO pRow;
  1068. INT i;
  1069. // Get the IPX_STATIC_ROUTE_INFO block from the interface
  1070. CORg( pInfoBase->GetBlock(IPX_STATIC_ROUTE_INFO_TYPE, &pBlock, 0) );
  1071. // Look for the removed route in the IPX_STATIC_ROUTE_INFO
  1072. pRow = (IPX_STATIC_ROUTE_INFO*) pBlock->pData;
  1073. for (i = 0; i < (INT)pBlock->dwCount; i++, pRow++)
  1074. {
  1075. // Compare this route to the removed one
  1076. if (FAreTwoRoutesEqual(pRow, &(pSREntry->m_route)))
  1077. {
  1078. // This is the removed route, so modify this block
  1079. // to exclude the route:
  1080. // Decrement the number of routes
  1081. --pBlock->dwCount;
  1082. if (pBlock->dwCount && (i < (INT)pBlock->dwCount))
  1083. {
  1084. // Overwrite this route with the ones which follow it
  1085. ::memmove(pRow,
  1086. pRow + 1,
  1087. (pBlock->dwCount - i) * sizeof(*pRow));
  1088. }
  1089. break;
  1090. }
  1091. }
  1092. Error:
  1093. return hr;
  1094. }
  1095. /*!--------------------------------------------------------------------------
  1096. IpxRouteHandler::ModifyRouteInfo
  1097. -
  1098. Author: KennT
  1099. ---------------------------------------------------------------------------*/
  1100. HRESULT IpxRouteHandler::ModifyRouteInfo(ITFSNode *pNode,
  1101. IpxSRListEntry *pSREntryNew,
  1102. IpxSRListEntry *pSREntryOld)
  1103. {
  1104. Assert(pSREntryNew);
  1105. Assert(pSREntryOld);
  1106. INT i;
  1107. HRESULT hr = hrOK;
  1108. InfoBlock* pBlock;
  1109. SPIInfoBase spInfoBase;
  1110. SPIRtrMgrInterfaceInfo spRmIf;
  1111. SPITFSNode spNodeParent;
  1112. IPXConnection * pIPXConn;
  1113. IPX_STATIC_ROUTE_INFO *psr, *psrOld;
  1114. IPX_STATIC_ROUTE_INFO IpxRow;
  1115. CWaitCursor wait;
  1116. pNode->GetParent(&spNodeParent);
  1117. pIPXConn = GET_IPX_SR_NODEDATA(spNodeParent);
  1118. Assert(pIPXConn);
  1119. // Remove the old route if it is on another interface
  1120. if (lstrcmpi(pSREntryOld->m_spIf->GetId(), pSREntryNew->m_spIf->GetId()) != 0)
  1121. {
  1122. // the outgoing interface for a route is to be changed.
  1123. CORg( pSREntryOld->m_spIf->FindRtrMgrInterface(PID_IPX, &spRmIf) );
  1124. CORg( spRmIf->GetInfoBase(pIPXConn->GetConfigHandle(),
  1125. NULL,
  1126. NULL,
  1127. &spInfoBase));
  1128. // Remove the old interface
  1129. CORg( RemoveStaticRoute(pSREntryOld, spInfoBase) );
  1130. // Update the interface information
  1131. CORg( spRmIf->Save(pSREntryOld->m_spIf->GetMachineName(),
  1132. pIPXConn->GetConfigHandle(),
  1133. NULL,
  1134. NULL,
  1135. spInfoBase,
  1136. 0));
  1137. }
  1138. spRmIf.Release();
  1139. spInfoBase.Release();
  1140. // Either
  1141. // (a) a route is being modified (on the same interface)
  1142. // (b) a route is being moved from one interface to another.
  1143. // Retrieve the configuration for the interface to which the route
  1144. // is now attached;
  1145. CORg( pSREntryNew->m_spIf->FindRtrMgrInterface(PID_IPX, &spRmIf) );
  1146. CORg( spRmIf->GetInfoBase(pIPXConn->GetConfigHandle(),
  1147. NULL,
  1148. NULL,
  1149. &spInfoBase));
  1150. // Get the IPX_STATIC_ROUTE_INFO block from the interface
  1151. hr = spInfoBase->GetBlock(IPX_STATIC_ROUTE_INFO_TYPE, &pBlock, 0);
  1152. if (!FHrOK(hr))
  1153. {
  1154. //
  1155. // No IPX_STATIC_ROUTE_INFO block was found; we create a new block
  1156. // with the new route, and add that block to the interface-info
  1157. //
  1158. CORg( AddStaticRoute(pSREntryNew, spInfoBase, NULL) );
  1159. }
  1160. else
  1161. {
  1162. //
  1163. // An IPX_STATIC_ROUTE_INFO block was found.
  1164. //
  1165. // We are modifying an existing route.
  1166. // If the route's interface was not changed when it was modified,
  1167. // look for the existing route in the IPX_STATIC_ROUTE_INFO, and then
  1168. // update its parameters.
  1169. // Otherwise, write a completely new route in the IPX_STATIC_ROUTE_INFO;
  1170. //
  1171. if (lstrcmpi(pSREntryOld->m_spIf->GetId(), pSREntryNew->m_spIf->GetId()) == 0)
  1172. {
  1173. //
  1174. // The route's interface was not changed when it was modified;
  1175. // We now look for it amongst the existing routes
  1176. // for this interface.
  1177. // The route's original parameters are in 'preOld',
  1178. // so those are the parameters with which we search
  1179. // for a route to modify
  1180. //
  1181. psr = (IPX_STATIC_ROUTE_INFO*)pBlock->pData;
  1182. for (i = 0; i < (INT)pBlock->dwCount; i++, psr++)
  1183. {
  1184. // Compare this route to the re-configured one
  1185. if (!FAreTwoRoutesEqual(&(pSREntryOld->m_route), psr))
  1186. continue;
  1187. // This is the route which was modified;
  1188. // We can now modify the parameters for the route in-place.
  1189. *psr = pSREntryNew->m_route;
  1190. break;
  1191. }
  1192. }
  1193. else
  1194. {
  1195. CORg( AddStaticRoute(pSREntryNew, spInfoBase, pBlock) );
  1196. }
  1197. }
  1198. // Save the updated information
  1199. CORg( spRmIf->Save(pSREntryNew->m_spIf->GetMachineName(),
  1200. pIPXConn->GetConfigHandle(),
  1201. NULL,
  1202. NULL,
  1203. spInfoBase,
  1204. 0));
  1205. Error:
  1206. return hr;
  1207. }
  1208. /*!--------------------------------------------------------------------------
  1209. IpxRouteHandler::ParentRefresh
  1210. -
  1211. Author: KennT
  1212. ---------------------------------------------------------------------------*/
  1213. HRESULT IpxRouteHandler::ParentRefresh(ITFSNode *pNode)
  1214. {
  1215. return ForwardCommandToParent(pNode, IDS_MENU_SYNC,
  1216. CCT_RESULT, NULL, 0);
  1217. }
  1218. //----------------------------------------------------------------------------
  1219. // Class: CStaticRouteDlg
  1220. //
  1221. //----------------------------------------------------------------------------
  1222. //----------------------------------------------------------------------------
  1223. // Function: CStaticRouteDlg::CStaticRouteDlg
  1224. //
  1225. // Constructor: initialize the base-class and the dialog's data.
  1226. //----------------------------------------------------------------------------
  1227. CStaticRouteDlg::CStaticRouteDlg(IpxSRListEntry * pSREntry,
  1228. DWORD dwFlags,
  1229. IRouterInfo *pRouter,
  1230. CWnd *pParent)
  1231. : CBaseDialog(IDD_STATIC_ROUTE, pParent),
  1232. m_pSREntry(pSREntry),
  1233. m_dwFlags(dwFlags)
  1234. {
  1235. //{{AFX_DATA_INIT(CStaticRouteDlg)
  1236. //}}AFX_DATA_INIT
  1237. m_spRouterInfo.Set(pRouter);
  1238. // SetHelpMap(m_dwHelpMap);
  1239. }
  1240. //----------------------------------------------------------------------------
  1241. // Function: CStaticRouteDlg::DoDataExchange
  1242. //----------------------------------------------------------------------------
  1243. VOID
  1244. CStaticRouteDlg::DoDataExchange(
  1245. CDataExchange* pDX
  1246. ) {
  1247. CBaseDialog::DoDataExchange(pDX);
  1248. //{{AFX_DATA_MAP(CStaticRouteDlg)
  1249. DDX_Control(pDX, IDC_SRD_COMBO_INTERFACE, m_cbInterfaces);
  1250. DDX_Control(pDX, IDC_SRD_SPIN_TICK_COUNT, m_spinTickCount);
  1251. DDX_Control(pDX, IDC_SRD_SPIN_HOP_COUNT, m_spinHopCount);
  1252. //}}AFX_DATA_MAP
  1253. }
  1254. BEGIN_MESSAGE_MAP(CStaticRouteDlg, CBaseDialog)
  1255. //{{AFX_MSG_MAP(CStaticRouteDlg)
  1256. //}}AFX_MSG_MAP
  1257. END_MESSAGE_MAP()
  1258. DWORD CStaticRouteDlg::m_dwHelpMap[] =
  1259. {
  1260. // IDC_SRD_DESTINATION, HIDC_SRD_DESTINATION,
  1261. // IDC_SRD_NETMASK, HIDC_SRD_NETMASK,
  1262. // IDC_SRD_GATEWAY, HIDC_SRD_GATEWAY,
  1263. // IDC_SRD_METRIC, HIDC_SRD_METRIC,
  1264. // IDC_SRD_SPINMETRIC, HIDC_SRD_SPINMETRIC,
  1265. // IDC_SRD_INTERFACES, HIDC_SRD_INTERFACES,
  1266. 0,0
  1267. };
  1268. //----------------------------------------------------------------------------
  1269. // Function: CStaticRouteDlg::OnInitDialog
  1270. //
  1271. // Handles the 'WM_INITDIALOG' message for the dialog.
  1272. //----------------------------------------------------------------------------
  1273. BOOL
  1274. CStaticRouteDlg::OnInitDialog(
  1275. )
  1276. {
  1277. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1278. SPIEnumInterfaceInfo spEnumIf;
  1279. SPIInterfaceInfo spIf;
  1280. SPIRtrMgrInterfaceInfo spRmIf;
  1281. TCHAR szNumber[32];
  1282. CBaseDialog::OnInitDialog();
  1283. // initialize the controls
  1284. m_spinHopCount.SetRange(0, 15);
  1285. m_spinHopCount.SetBuddy(GetDlgItem(IDC_SRD_EDIT_HOP_COUNT));
  1286. m_spinTickCount.SetRange(0, UD_MAXVAL);
  1287. m_spinTickCount.SetBuddy(GetDlgItem(IDC_SRD_EDIT_TICK_COUNT));
  1288. ((CEdit *) GetDlgItem(IDC_SRD_EDIT_NETWORK_NUMBER))->LimitText(8);
  1289. ((CEdit *) GetDlgItem(IDC_SRD_EDIT_NEXT_HOP))->LimitText(12);
  1290. // Get a list of the interfaces enabled for IPX routing.
  1291. m_spRouterInfo->EnumInterface(&spEnumIf);
  1292. for( ; spEnumIf->Next(1, &spIf, NULL) == hrOK; spIf.Release())
  1293. {
  1294. spRmIf.Release();
  1295. if (spIf->FindRtrMgrInterface(PID_IPX, &spRmIf) != hrOK)
  1296. continue;
  1297. // Add the interface to the combobox
  1298. INT i = m_cbInterfaces.AddString(spIf->GetTitle());
  1299. m_cbInterfaces.SetItemData(i, (DWORD_PTR)m_ifidList.AddTail(spIf->GetId()));
  1300. }
  1301. if (!m_cbInterfaces.GetCount())
  1302. {
  1303. AfxMessageBox(IDS_ERR_NO_IPX_INTERFACES);
  1304. EndDialog(IDCANCEL);
  1305. return FALSE;
  1306. }
  1307. m_cbInterfaces.SetCurSel(0);
  1308. //
  1309. // If we were given a route to modify, set the dialog up
  1310. // with the parameters in the route
  1311. //
  1312. if ((m_dwFlags & SR_DLG_MODIFY) == 0)
  1313. {
  1314. // No route was given, so leave the controls blank
  1315. }
  1316. else
  1317. {
  1318. // A route to be edited was given, so initialize the controls
  1319. FormatIpxNetworkNumber(szNumber,
  1320. DimensionOf(szNumber),
  1321. m_pSREntry->m_route.Network,
  1322. sizeof(m_pSREntry->m_route.Network));
  1323. SetDlgItemText(IDC_SRD_EDIT_NETWORK_NUMBER, szNumber);
  1324. FormatMACAddress(szNumber,
  1325. DimensionOf(szNumber),
  1326. m_pSREntry->m_route.NextHopMacAddress,
  1327. sizeof(m_pSREntry->m_route.NextHopMacAddress));
  1328. SetDlgItemText(IDC_SRD_EDIT_NEXT_HOP, szNumber);
  1329. m_cbInterfaces.SelectString(-1, m_pSREntry->m_spIf->GetTitle());
  1330. m_spinHopCount.SetPos(m_pSREntry->m_route.HopCount);
  1331. m_spinTickCount.SetPos(m_pSREntry->m_route.TickCount);
  1332. // Disable the network number, next hop, and interface
  1333. GetDlgItem(IDC_SRD_EDIT_NETWORK_NUMBER)->EnableWindow(FALSE);
  1334. GetDlgItem(IDC_SRD_EDIT_NEXT_HOP)->EnableWindow(FALSE);
  1335. GetDlgItem(IDC_SRD_COMBO_INTERFACE)->EnableWindow(FALSE);
  1336. }
  1337. return TRUE;
  1338. }
  1339. //----------------------------------------------------------------------------
  1340. // Function: CStaticRouteDlg::OnOK
  1341. //
  1342. // Handles 'BN_CLICKED' notification from the 'OK' button.
  1343. //----------------------------------------------------------------------------
  1344. VOID
  1345. CStaticRouteDlg::OnOK(
  1346. ) {
  1347. CString st;
  1348. SPIInterfaceInfo spIf;
  1349. CString stIf;
  1350. POSITION pos;
  1351. do
  1352. {
  1353. // Get the route's outgoing interface
  1354. INT item = m_cbInterfaces.GetCurSel();
  1355. if (item == CB_ERR)
  1356. break;
  1357. pos = (POSITION)m_cbInterfaces.GetItemData(item);
  1358. stIf = (LPCTSTR)m_ifidList.GetAt(pos);
  1359. m_spRouterInfo->FindInterface(stIf, &spIf);
  1360. m_pSREntry->m_spIf.Set(spIf);
  1361. // Get the rest of the data
  1362. GetDlgItemText(IDC_SRD_EDIT_NETWORK_NUMBER, st);
  1363. ConvertNetworkNumberToBytes(st,
  1364. m_pSREntry->m_route.Network,
  1365. sizeof(m_pSREntry->m_route.Network));
  1366. GetDlgItemText(IDC_SRD_EDIT_NEXT_HOP, st);
  1367. ConvertMACAddressToBytes(st,
  1368. m_pSREntry->m_route.NextHopMacAddress,
  1369. sizeof(m_pSREntry->m_route.NextHopMacAddress));
  1370. m_pSREntry->m_route.TickCount = (USHORT) m_spinTickCount.GetPos();
  1371. m_pSREntry->m_route.HopCount = (USHORT) m_spinHopCount.GetPos();
  1372. CBaseDialog::OnOK();
  1373. } while(FALSE);
  1374. }
  1375. /*!--------------------------------------------------------------------------
  1376. IpxSRListEntry::LoadFrom
  1377. -
  1378. Author: KennT
  1379. ---------------------------------------------------------------------------*/
  1380. void IpxSRListEntry::LoadFrom(BaseIPXResultNodeData *pNodeData)
  1381. {
  1382. m_spIf.Set(pNodeData->m_spIf);
  1383. ConvertNetworkNumberToBytes(pNodeData->m_rgData[IPX_SR_SI_NETWORK].m_stData,
  1384. m_route.Network,
  1385. DimensionOf(m_route.Network));
  1386. // This is not the correct byte order to do comparisons, but it
  1387. // can be used for equality
  1388. memcpy(&pNodeData->m_rgData[IPX_SR_SI_NETWORK].m_dwData,
  1389. m_route.Network,
  1390. sizeof(DWORD));
  1391. m_route.TickCount = (USHORT) pNodeData->m_rgData[IPX_SR_SI_TICK_COUNT].m_dwData;
  1392. m_route.HopCount = (USHORT) pNodeData->m_rgData[IPX_SR_SI_HOP_COUNT].m_dwData;
  1393. // Need to convert the MAC address into a byte array
  1394. ConvertMACAddressToBytes(pNodeData->m_rgData[IPX_SR_SI_NEXT_HOP].m_stData,
  1395. m_route.NextHopMacAddress,
  1396. DimensionOf(m_route.NextHopMacAddress));
  1397. }
  1398. /*!--------------------------------------------------------------------------
  1399. IpxSRListEntry::SaveTo
  1400. -
  1401. Author: KennT
  1402. ---------------------------------------------------------------------------*/
  1403. void IpxSRListEntry::SaveTo(BaseIPXResultNodeData *pNodeData)
  1404. {
  1405. TCHAR szNumber[32];
  1406. pNodeData->m_spIf.Set(m_spIf);
  1407. pNodeData->m_rgData[IPX_SR_SI_NAME].m_stData = m_spIf->GetTitle();
  1408. FormatIpxNetworkNumber(szNumber,
  1409. DimensionOf(szNumber),
  1410. m_route.Network,
  1411. DimensionOf(m_route.Network));
  1412. pNodeData->m_rgData[IPX_SR_SI_NETWORK].m_stData = szNumber;
  1413. memcpy(&(pNodeData->m_rgData[IPX_SR_SI_NETWORK].m_dwData),
  1414. m_route.Network,
  1415. sizeof(DWORD));
  1416. FormatMACAddress(szNumber,
  1417. DimensionOf(szNumber),
  1418. m_route.NextHopMacAddress,
  1419. DimensionOf(m_route.NextHopMacAddress));
  1420. pNodeData->m_rgData[IPX_SR_SI_NEXT_HOP].m_stData = szNumber;
  1421. FormatNumber(m_route.TickCount,
  1422. szNumber,
  1423. DimensionOf(szNumber),
  1424. FALSE);
  1425. pNodeData->m_rgData[IPX_SR_SI_TICK_COUNT].m_stData = szNumber;
  1426. pNodeData->m_rgData[IPX_SR_SI_TICK_COUNT].m_dwData = m_route.TickCount;
  1427. FormatNumber(m_route.HopCount,
  1428. szNumber,
  1429. DimensionOf(szNumber),
  1430. FALSE);
  1431. pNodeData->m_rgData[IPX_SR_SI_HOP_COUNT].m_stData = szNumber;
  1432. pNodeData->m_rgData[IPX_SR_SI_HOP_COUNT].m_dwData = m_route.HopCount;
  1433. }
  1434. /*!--------------------------------------------------------------------------
  1435. SetRouteData
  1436. -
  1437. Author: KennT
  1438. ---------------------------------------------------------------------------*/
  1439. HRESULT SetRouteData(BaseIPXResultNodeData *pData,
  1440. IpxSRListEntry *pRoute)
  1441. {
  1442. pRoute->SaveTo(pData);
  1443. return hrOK;
  1444. }
  1445. /*!--------------------------------------------------------------------------
  1446. AddStaticRoute
  1447. This function ASSUMES that the route is NOT in the block.
  1448. Author: KennT
  1449. ---------------------------------------------------------------------------*/
  1450. HRESULT AddStaticRoute(IpxSRListEntry *pSREntryNew,
  1451. IInfoBase *pInfoBase,
  1452. InfoBlock *pBlock)
  1453. {
  1454. IPX_STATIC_ROUTE_INFO srRow;
  1455. HRESULT hr = hrOK;
  1456. if (pBlock == NULL)
  1457. {
  1458. //
  1459. // No IPX_STATIC_ROUTE_INFO block was found; we create a new block
  1460. // with the new route, and add that block to the interface-info
  1461. //
  1462. CORg( pInfoBase->AddBlock(IPX_STATIC_ROUTE_INFO_TYPE,
  1463. sizeof(IPX_STATIC_ROUTE_INFO),
  1464. (LPBYTE) &(pSREntryNew->m_route), 1, 0) );
  1465. }
  1466. else
  1467. {
  1468. // Either the route is completely new, or it is a route
  1469. // which was moved from one interface to another.
  1470. // Set a new block as the IPX_STATIC_ROUTE_INFO,
  1471. // and include the re-configured route in the new block.
  1472. PIPX_STATIC_ROUTE_INFO psrTable;
  1473. psrTable = new IPX_STATIC_ROUTE_INFO[pBlock->dwCount + 1];
  1474. Assert(psrTable);
  1475. // Copy the original table of routes
  1476. ::memcpy(psrTable, pBlock->pData,
  1477. pBlock->dwCount * sizeof(IPX_STATIC_ROUTE_INFO));
  1478. // Append the new route
  1479. psrTable[pBlock->dwCount] = pSREntryNew->m_route;
  1480. // Replace the old route-table with the new one
  1481. CORg( pInfoBase->SetData(IPX_STATIC_ROUTE_INFO_TYPE,
  1482. sizeof(IPX_STATIC_ROUTE_INFO),
  1483. (LPBYTE) psrTable, pBlock->dwCount + 1, 0) );
  1484. }
  1485. Error:
  1486. return hr;
  1487. }
  1488. BOOL FAreTwoRoutesEqual(IPX_STATIC_ROUTE_INFO *pRoute1,
  1489. IPX_STATIC_ROUTE_INFO *pRoute2)
  1490. {
  1491. return (memcmp(pRoute1->Network, pRoute2->Network,
  1492. sizeof(pRoute1->Network)) == 0) &&
  1493. (memcmp(pRoute1->NextHopMacAddress, pRoute2->NextHopMacAddress,
  1494. sizeof(pRoute1->NextHopMacAddress)) == 0);
  1495. }