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.

1883 lines
54 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. summary.cpp
  7. IPX summary node implementation.
  8. FILE HISTORY:
  9. */
  10. #include "stdafx.h"
  11. #include "util.h"
  12. #include "summary.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 "column.h" // ComponentConfigStream
  22. #include "rtrui.h"
  23. #include "sumprop.h" // IP Summary property page
  24. #include "ipxutil.h" // IPX formatting helper functions
  25. #include "routprot.h"
  26. #include "ipxrtdef.h"
  27. #include "rtrerr.h" // FormatRasErrorMessage
  28. /*---------------------------------------------------------------------------
  29. Keep this in sync with the column ids in summary.h
  30. ---------------------------------------------------------------------------*/
  31. extern const ContainerColumnInfo s_rgIfViewColumnInfo[];
  32. const ContainerColumnInfo s_rgIfViewColumnInfo[] =
  33. {
  34. { IDS_IPX_COL_NAME, CON_SORT_BY_STRING, TRUE, COL_IF_NAME },
  35. { IDS_IPX_COL_TYPE, CON_SORT_BY_STRING, TRUE, COL_STRING },
  36. { IDS_IPX_COL_ADMINSTATE, CON_SORT_BY_STRING, TRUE, COL_STATUS },
  37. { IDS_IPX_COL_OPERSTATE, CON_SORT_BY_STRING, TRUE, COL_STATUS },
  38. { IDS_IPX_COL_NETWORK, CON_SORT_BY_STRING, TRUE, COL_IPXNET },
  39. { IDS_IPX_COL_PACKETS_SENT, CON_SORT_BY_DWORD, TRUE, COL_LARGE_NUM },
  40. { IDS_IPX_COL_PACKETS_RCVD, CON_SORT_BY_DWORD, TRUE, COL_LARGE_NUM },
  41. { IDS_IPX_COL_OUT_FILTERED, CON_SORT_BY_DWORD, FALSE, COL_LARGE_NUM },
  42. { IDS_IPX_COL_OUT_DROPPED, CON_SORT_BY_DWORD, FALSE, COL_LARGE_NUM },
  43. { IDS_IPX_COL_IN_FILTERED, CON_SORT_BY_DWORD, FALSE, COL_LARGE_NUM },
  44. { IDS_IPX_COL_IN_NOROUTES, CON_SORT_BY_DWORD, FALSE, COL_LARGE_NUM },
  45. { IDS_IPX_COL_IN_DROPPED, CON_SORT_BY_DWORD, FALSE, COL_LARGE_NUM },
  46. };
  47. /*---------------------------------------------------------------------------
  48. IPXSummaryHandler implementation
  49. ---------------------------------------------------------------------------*/
  50. IPXSummaryHandler::IPXSummaryHandler(ITFSComponentData *pCompData)
  51. : BaseContainerHandler(pCompData, COLUMNS_SUMMARY,
  52. s_rgIfViewColumnInfo),
  53. m_ulConnId(0),
  54. m_ulRefreshConnId(0),
  55. m_ulStatsConnId(0)
  56. {
  57. // Setup the verb states
  58. m_rgButtonState[MMC_VERB_REFRESH_INDEX] = ENABLED;
  59. m_bState[MMC_VERB_REFRESH_INDEX] = TRUE;
  60. }
  61. STDMETHODIMP IPXSummaryHandler::QueryInterface(REFIID riid, LPVOID *ppv)
  62. {
  63. // Is the pointer bad?
  64. if (ppv == NULL)
  65. return E_INVALIDARG;
  66. // Place NULL in *ppv in case of failure
  67. *ppv = NULL;
  68. // This is the non-delegating IUnknown implementation
  69. if (riid == IID_IUnknown)
  70. *ppv = (LPVOID) this;
  71. else if (riid == IID_IRtrAdviseSink)
  72. *ppv = &m_IRtrAdviseSink;
  73. else
  74. return BaseContainerHandler::QueryInterface(riid, ppv);
  75. // If we're going to return an interface, AddRef it first
  76. if (*ppv)
  77. {
  78. ((LPUNKNOWN) *ppv)->AddRef();
  79. return hrOK;
  80. }
  81. else
  82. return E_NOINTERFACE;
  83. }
  84. /*!--------------------------------------------------------------------------
  85. IPXSummaryHandler::DestroyHandler
  86. Implementation of ITFSNodeHandler::DestroyHandler
  87. Author: KennT
  88. ---------------------------------------------------------------------------*/
  89. STDMETHODIMP IPXSummaryHandler::DestroyHandler(ITFSNode *pNode)
  90. {
  91. IPXConnection * pIpxConn;
  92. pIpxConn = GET_IPXSUMMARY_NODEDATA(pNode);
  93. pIpxConn->Release();
  94. if (m_ulRefreshConnId)
  95. {
  96. SPIRouterRefresh spRefresh;
  97. if (m_spRouterInfo)
  98. m_spRouterInfo->GetRefreshObject(&spRefresh);
  99. if (spRefresh)
  100. spRefresh->UnadviseRefresh(m_ulRefreshConnId);
  101. }
  102. m_ulRefreshConnId = 0;
  103. if (m_ulStatsConnId)
  104. {
  105. SPIRouterRefresh spRefresh;
  106. if (m_spRouterInfo)
  107. m_spRouterInfo->GetRefreshObject(&spRefresh);
  108. if (spRefresh)
  109. spRefresh->UnadviseRefresh(m_ulStatsConnId);
  110. }
  111. m_ulStatsConnId = 0;
  112. if (m_ulConnId)
  113. m_spRtrMgrInfo->RtrUnadvise(m_ulConnId);
  114. m_ulConnId = 0;
  115. m_spRtrMgrInfo.Release();
  116. // WaitForStatisticsWindow(&m_IpxStats);
  117. m_spRouterInfo.Release();
  118. return hrOK;
  119. }
  120. /*---------------------------------------------------------------------------
  121. Menu data structure for our menus
  122. ---------------------------------------------------------------------------*/
  123. static const SRouterNodeMenu s_rgIfNodeMenu[] =
  124. {
  125. { IDS_MENU_IPXSUM_NEW_INTERFACE, 0,
  126. CCM_INSERTIONPOINTID_PRIMARY_TOP },
  127. { IDS_MENU_SEPARATOR, 0,
  128. CCM_INSERTIONPOINTID_PRIMARY_TOP },
  129. };
  130. /*!--------------------------------------------------------------------------
  131. IPXSummaryHandler::OnAddMenuItems
  132. Implementation of ITFSNodeHandler::OnAddMenuItems
  133. Author: KennT
  134. ---------------------------------------------------------------------------*/
  135. STDMETHODIMP IPXSummaryHandler::OnAddMenuItems(
  136. ITFSNode *pNode,
  137. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  138. LPDATAOBJECT lpDataObject,
  139. DATA_OBJECT_TYPES type,
  140. DWORD dwType,
  141. long *pInsertionAllowed)
  142. {
  143. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  144. HRESULT hr = S_OK;
  145. IPXSummaryHandler::SMenuData menuData;
  146. COM_PROTECT_TRY
  147. {
  148. menuData.m_spNode.Set(pNode);
  149. hr = AddArrayOfMenuItems(pNode, s_rgIfNodeMenu,
  150. DimensionOf(s_rgIfNodeMenu),
  151. pContextMenuCallback,
  152. *pInsertionAllowed,
  153. reinterpret_cast<INT_PTR>(&menuData));
  154. }
  155. COM_PROTECT_CATCH;
  156. return hr;
  157. }
  158. /*!--------------------------------------------------------------------------
  159. IPXSummaryHandler::OnCommand
  160. Implementation of ITFSNodeHandler::OnCommand
  161. Author: KennT
  162. ---------------------------------------------------------------------------*/
  163. STDMETHODIMP IPXSummaryHandler::OnCommand(ITFSNode *pNode, long nCommandId,
  164. DATA_OBJECT_TYPES type,
  165. LPDATAOBJECT pDataObject,
  166. DWORD dwType)
  167. {
  168. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  169. HRESULT hr = S_OK;
  170. COM_PROTECT_TRY
  171. {
  172. switch (nCommandId)
  173. {
  174. case IDS_MENU_IPXSUM_NEW_INTERFACE:
  175. hr = OnNewInterface();
  176. if (!FHrSucceeded(hr))
  177. DisplayErrorMessage(NULL, hr);
  178. break;
  179. case IDS_MENU_SYNC:
  180. SynchronizeNodeData(pNode);
  181. break;
  182. }
  183. }
  184. COM_PROTECT_CATCH;
  185. return hrOK;
  186. }
  187. /*!--------------------------------------------------------------------------
  188. IPXSummaryHandler::OnExpand
  189. -
  190. Author: KennT
  191. ---------------------------------------------------------------------------*/
  192. HRESULT IPXSummaryHandler::OnExpand(ITFSNode *pNode,
  193. LPDATAOBJECT pDataObject,
  194. DWORD dwType,
  195. LPARAM arg,
  196. LPARAM lParam)
  197. {
  198. HRESULT hr = hrOK;
  199. SPIEnumInterfaceInfo spEnumIf;
  200. SPIInterfaceInfo spIf;
  201. SPIRtrMgrInterfaceInfo spRmIf;
  202. // Windows NT Bug: 288427
  203. // This flag may also get set inside of the OnChange() call.
  204. // The OnChange() will enumerate and all interfaces.
  205. // They may have been added as the result of an OnChange()
  206. // because they were added before the OnExpand() was called.
  207. //
  208. // WARNING! Be careful about adding anything to this function,
  209. // since the m_bExpanded can be set in another function.
  210. // ----------------------------------------------------------------
  211. if (m_bExpanded)
  212. return hrOK;
  213. COM_PROTECT_TRY
  214. {
  215. CORg( m_spRouterInfo->EnumInterface(&spEnumIf) );
  216. while (spEnumIf->Next(1, &spIf, NULL) == hrOK)
  217. {
  218. if (spIf->FindRtrMgrInterface(PID_IPX, &spRmIf) == hrOK)
  219. {
  220. // Now we create an interface node for this interface
  221. AddInterfaceNode(pNode, spIf, FALSE, NULL);
  222. }
  223. spRmIf.Release();
  224. spIf.Release();
  225. }
  226. //$CLIENT: Add the client interface (setup default data)
  227. // the only thing that we can do in synchronize is to
  228. // get the Administrative status
  229. AddInterfaceNode(pNode, NULL, TRUE, NULL);
  230. m_bExpanded = TRUE;
  231. // Now that we have all of the nodes, update the data for
  232. // all of the nodes
  233. SynchronizeNodeData(pNode);
  234. COM_PROTECT_ERROR_LABEL;
  235. }
  236. COM_PROTECT_CATCH;
  237. m_bExpanded = TRUE;
  238. return hr;
  239. }
  240. /*!--------------------------------------------------------------------------
  241. IPXSummaryHandler::GetString
  242. Implementation of ITFSNodeHandler::GetString
  243. We don't need to do anything, since our root node is an extension
  244. only and thus can't do anything to the node text.
  245. Author: KennT
  246. ---------------------------------------------------------------------------*/
  247. STDMETHODIMP_(LPCTSTR) IPXSummaryHandler::GetString(ITFSNode *pNode, int nCol)
  248. {
  249. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  250. HRESULT hr = hrOK;
  251. COM_PROTECT_TRY
  252. {
  253. if (m_stTitle.IsEmpty())
  254. m_stTitle.LoadString(IDS_IPXSUMMARY_TITLE);
  255. }
  256. COM_PROTECT_CATCH;
  257. return m_stTitle;
  258. }
  259. /*!--------------------------------------------------------------------------
  260. IPXSummaryHandler::OnCreateDataObject
  261. -
  262. Author: KennT
  263. ---------------------------------------------------------------------------*/
  264. STDMETHODIMP IPXSummaryHandler::OnCreateDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, IDataObject **ppDataObject)
  265. {
  266. HRESULT hr = hrOK;
  267. COM_PROTECT_TRY
  268. {
  269. Assert(m_spRtrMgrInfo);
  270. CORg( CreateDataObjectFromRtrMgrInfo(m_spRtrMgrInfo,
  271. type, cookie, m_spTFSCompData,
  272. ppDataObject) );
  273. COM_PROTECT_ERROR_LABEL;
  274. }
  275. COM_PROTECT_CATCH;
  276. return hr;
  277. }
  278. /*!--------------------------------------------------------------------------
  279. IPXSummaryHandler::Init
  280. -
  281. Author: KennT
  282. ---------------------------------------------------------------------------*/
  283. HRESULT IPXSummaryHandler::Init(IRtrMgrInfo *pRmInfo, IPXAdminConfigStream *pConfigStream)
  284. {
  285. m_spRtrMgrInfo.Set(pRmInfo);
  286. if (pRmInfo)
  287. pRmInfo->GetParentRouterInfo(&m_spRouterInfo);
  288. m_pConfigStream = pConfigStream;
  289. // Also need to register for change notifications
  290. Assert(m_ulConnId == 0);
  291. m_spRtrMgrInfo->RtrAdvise(&m_IRtrAdviseSink, &m_ulConnId, 0);
  292. // m_IpxStats.SetConfigInfo(pConfigStream, IPXSTRM_STATS_IPX);
  293. return hrOK;
  294. }
  295. HRESULT IPXSummaryHandler::OnResultRefresh(ITFSComponent * pComponent, LPDATAOBJECT pDataObject, MMC_COOKIE cookie, LPARAM arg, LPARAM lParam)
  296. {
  297. HRESULT hr = hrOK;
  298. SPITFSNode spNode, spParent;
  299. SPITFSResultHandler spParentRH;
  300. m_spNodeMgr->FindNode(cookie, &spNode);
  301. // forward this command to the parent to handle
  302. CORg (spNode->GetParent(&spParent));
  303. CORg (spParent->GetResultHandler(&spParentRH));
  304. CORg (spParentRH->Notify(pComponent, spParent->GetData(TFS_DATA_COOKIE), pDataObject, MMCN_REFRESH, arg, lParam));
  305. Error:
  306. return hrOK;
  307. }
  308. /*!--------------------------------------------------------------------------
  309. IPXSummaryHandler::ConstructNode
  310. Initializes the root node (sets it up).
  311. Author: KennT
  312. ---------------------------------------------------------------------------*/
  313. HRESULT IPXSummaryHandler::ConstructNode(ITFSNode *pNode, LPCTSTR pszName,
  314. IPXConnection *pIpxConn)
  315. {
  316. Assert(pIpxConn);
  317. HRESULT hr = hrOK;
  318. if (pNode == NULL)
  319. return hrOK;
  320. COM_PROTECT_TRY
  321. {
  322. // Need to initialize the data for the root node
  323. pNode->SetData(TFS_DATA_IMAGEINDEX, IMAGE_IDX_IPX_NODE_GENERAL);
  324. pNode->SetData(TFS_DATA_OPENIMAGEINDEX, IMAGE_IDX_IPX_NODE_GENERAL);
  325. pNode->SetData(TFS_DATA_SCOPEID, 0);
  326. // This is a leaf node in the scope pane
  327. pNode->SetData(TFS_DATA_SCOPE_LEAF_NODE, TRUE);
  328. m_cookie = reinterpret_cast<DWORD_PTR>(pNode);
  329. pNode->SetData(TFS_DATA_COOKIE, m_cookie);
  330. pNode->SetNodeType(&GUID_IPXSummaryNodeType);
  331. // Setup the node data
  332. pIpxConn->AddRef();
  333. SET_IPXSUMMARY_NODEDATA(pNode, pIpxConn);
  334. // m_IpxStats.SetConnectionData(pIpxConn);
  335. }
  336. COM_PROTECT_CATCH;
  337. if (!FHrSucceeded(hr))
  338. {
  339. SET_IPXSUMMARY_NODEDATA(pNode, NULL);
  340. }
  341. return hr;
  342. }
  343. /*!--------------------------------------------------------------------------
  344. IPXSummaryHandler::AddInterfaceNode
  345. -
  346. Author: KennT
  347. ---------------------------------------------------------------------------*/
  348. HRESULT IPXSummaryHandler::AddInterfaceNode(ITFSNode *pParent, IInterfaceInfo *pIf, BOOL fClient, ITFSNode **ppNewNode)
  349. {
  350. IPXSummaryInterfaceHandler * pHandler;
  351. SPITFSResultHandler spHandler;
  352. SPITFSNode spNode;
  353. HRESULT hr = hrOK;
  354. IPXConnection * pIPXConn;
  355. BaseIPXResultNodeData * pResultData = NULL;
  356. int cBlocks = 0;
  357. SPIInfoBase spInfoBase;
  358. SPIRtrMgrInterfaceInfo spRmIf;
  359. // Create the handler for this node
  360. pHandler = new IPXSummaryInterfaceHandler(m_spTFSCompData);
  361. spHandler = pHandler;
  362. CORg( pHandler->Init(m_spRtrMgrInfo, pIf, pParent) );
  363. pIPXConn = GET_IPXSUMMARY_NODEDATA(pParent);
  364. // Create a result item node (or a leaf node)
  365. CORg( CreateLeafTFSNode(&spNode,
  366. NULL,
  367. static_cast<ITFSNodeHandler *>(pHandler),
  368. static_cast<ITFSResultHandler *>(pHandler),
  369. m_spNodeMgr) );
  370. CORg( pHandler->ConstructNode(spNode, pIf, pIPXConn) );
  371. pResultData = GET_BASEIPXRESULT_NODEDATA(spNode);
  372. Assert(pResultData);
  373. ASSERT_BASEIPXRESULT_NODEDATA(pResultData);
  374. pResultData->m_fClient = fClient;
  375. if (pIf)
  376. {
  377. pIf->FindRtrMgrInterface(PID_IPX, &spRmIf);
  378. if (spRmIf)
  379. spRmIf->GetInfoBase(NULL, NULL, NULL, &spInfoBase);
  380. if (spInfoBase)
  381. spInfoBase->GetInfo(NULL, &cBlocks);
  382. }
  383. else
  384. {
  385. // This is a client, make it visible
  386. cBlocks = 1;
  387. }
  388. //Set the infobase here
  389. if ( !pResultData->m_fClient )
  390. pHandler->SetInfoBase (spInfoBase );
  391. // Make the node immediately visible
  392. if (cBlocks)
  393. {
  394. CORg( spNode->SetVisibilityState(TFS_VIS_SHOW) );
  395. CORg( spNode->Show() );
  396. }
  397. else
  398. CORg( spNode->SetVisibilityState(TFS_VIS_HIDE) );
  399. CORg( pParent->AddChild(spNode) );
  400. if (ppNewNode)
  401. *ppNewNode = spNode.Transfer();
  402. Error:
  403. return hr;
  404. }
  405. /*!--------------------------------------------------------------------------
  406. IPXSummaryHandler::SynchronizeNodeData
  407. -
  408. Author: KennT
  409. ---------------------------------------------------------------------------*/
  410. HRESULT IPXSummaryHandler::SynchronizeNodeData(ITFSNode *pThisNode)
  411. {
  412. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  413. HRESULT hr = hrOK;
  414. BOOL fIsServiceRunning;
  415. SPITFSNodeEnum spEnum;
  416. SPITFSNode spNode;
  417. BaseIPXResultNodeData * pResultData = NULL;
  418. IPXSummaryList IPXSumList;
  419. IPXSummaryListEntry *pIPXSum = NULL;
  420. POSITION pos;
  421. CString st;
  422. SPIInterfaceInfo spIf;
  423. int i;
  424. SPIInfoBase spInfoBase;
  425. SPIRtrMgrInterfaceInfo spRmIf;
  426. InfoBlock * pBlock;
  427. IPXSummaryListEntry clientIPX;
  428. TCHAR szNumber[32];
  429. CString stNotAvailable;
  430. COM_PROTECT_TRY
  431. {
  432. //
  433. // If the service is started, retrieve the IP interface-stats table
  434. // and update the stats for each node.
  435. //
  436. CORg( IsRouterServiceRunning(m_spRouterInfo->GetMachineName(), NULL) );
  437. fIsServiceRunning = (hr == hrOK);
  438. // Gather all of the data
  439. GetIPXSummaryData(pThisNode, &IPXSumList);
  440. stNotAvailable.LoadString(IDS_IPX_NOT_AVAILABLE);
  441. // Now match the data up to the nodes
  442. pThisNode->GetEnum(&spEnum);
  443. spEnum->Reset();
  444. for ( ; spEnum->Next(1, &spNode, NULL) == hrOK; spNode.Release())
  445. {
  446. pResultData = GET_BASEIPXRESULT_NODEDATA(spNode);
  447. Assert(pResultData);
  448. ASSERT_BASEIPXRESULT_NODEDATA(pResultData);
  449. spIf.Release();
  450. spIf.Set(pResultData->m_spIf);
  451. spRmIf.Release();
  452. spInfoBase.Release();
  453. // If we don't have an spIf, then this HAS to be the
  454. // client interface
  455. if (pResultData->m_fClient)
  456. {
  457. GetClientInterfaceData(&clientIPX, m_spRtrMgrInfo);
  458. pIPXSum = &clientIPX;
  459. }
  460. else
  461. {
  462. // Look for this interface in the IPXSummaryList
  463. pIPXSum = NULL;
  464. pos = IPXSumList.GetHeadPosition();
  465. while (pos)
  466. {
  467. pIPXSum = IPXSumList.GetNext(pos);
  468. if (StriCmp(pIPXSum->m_stId, spIf->GetId()) == 0)
  469. break;
  470. pIPXSum = NULL;
  471. }
  472. // Update the interface type and administrative state
  473. spIf->FindRtrMgrInterface(PID_IPX, &spRmIf);
  474. spRmIf->GetInfoBase(NULL, NULL, NULL, &spInfoBase);
  475. pBlock = NULL;
  476. if (spInfoBase)
  477. spInfoBase->GetBlock(IPX_INTERFACE_INFO_TYPE, &pBlock, 0);
  478. if (pIPXSum)
  479. {
  480. if (pBlock)
  481. pIPXSum->m_dwAdminState =
  482. ((PIPX_IF_INFO)pBlock->pData)->AdminState;
  483. pIPXSum->m_dwIfType = spIf->GetInterfaceType();
  484. pIPXSum->m_stTitle = spIf->GetTitle();
  485. }
  486. }
  487. // As a default fill in all of the strings with a '-'
  488. for (i=0; i<IPXSUM_MAX_COLUMNS; i++)
  489. {
  490. pResultData->m_rgData[i].m_stData = stNotAvailable;
  491. pResultData->m_rgData[i].m_dwData = 0;
  492. }
  493. if (spIf)
  494. {
  495. pResultData->m_rgData[IPXSUM_SI_NAME].m_stData = spIf->GetTitle();
  496. pResultData->m_rgData[IPXSUM_SI_TYPE].m_stData =
  497. IpxTypeToCString(spIf->GetInterfaceType());
  498. }
  499. else if (pIPXSum)
  500. {
  501. pResultData->m_rgData[IPXSUM_SI_NAME].m_stData = pIPXSum->m_stTitle;
  502. pResultData->m_rgData[IPXSUM_SI_TYPE].m_stData =
  503. IpxTypeToCString(pIPXSum->m_dwIfType);
  504. }
  505. // Did we find an entry for this interface?
  506. if (pIPXSum)
  507. {
  508. pResultData->m_rgData[IPXSUM_SI_ADMINSTATE].m_stData =
  509. IpxAdminStateToCString(pIPXSum->m_dwAdminState);
  510. pResultData->m_rgData[IPXSUM_SI_ADMINSTATE].m_dwData =
  511. pIPXSum->m_dwAdminState;
  512. pResultData->m_rgData[IPXSUM_SI_OPERSTATE].m_stData =
  513. IpxOperStateToCString(pIPXSum->m_dwOperState);
  514. if (!pResultData->m_fClient)
  515. {
  516. FormatIpxNetworkNumber(szNumber,
  517. DimensionOf(szNumber),
  518. pIPXSum->m_network,
  519. DimensionOf(pIPXSum->m_network));
  520. st = szNumber;
  521. pResultData->m_rgData[IPXSUM_SI_NETWORK].m_stData = st;
  522. memcpy(&pResultData->m_rgData[IPXSUM_SI_NETWORK].m_dwData,
  523. pIPXSum->m_network, sizeof(DWORD));
  524. FillInNumberData(pResultData, IPXSUM_SI_PACKETS_SENT,
  525. pIPXSum->m_dwSent);
  526. FillInNumberData(pResultData, IPXSUM_SI_PACKETS_RCVD,
  527. pIPXSum->m_dwRcvd);
  528. FillInNumberData(pResultData, IPXSUM_SI_OUT_FILTERED,
  529. pIPXSum->m_dwOutFiltered);
  530. FillInNumberData(pResultData, IPXSUM_SI_OUT_DROPPED,
  531. pIPXSum->m_dwOutDropped);
  532. FillInNumberData(pResultData, IPXSUM_SI_IN_FILTERED,
  533. pIPXSum->m_dwInFiltered);
  534. FillInNumberData(pResultData, IPXSUM_SI_IN_NOROUTES,
  535. pIPXSum->m_dwInNoRoutes);
  536. FillInNumberData(pResultData, IPXSUM_SI_IN_DROPPED,
  537. pIPXSum->m_dwInDropped);
  538. }
  539. else
  540. pResultData->m_rgData[IPXSUM_SI_NETWORK].m_dwData = (DWORD) -1;
  541. }
  542. // Force MMC to redraw the nodes
  543. spNode->ChangeNode(RESULT_PANE_CHANGE_ITEM_DATA);
  544. }
  545. COM_PROTECT_ERROR_LABEL;
  546. }
  547. COM_PROTECT_CATCH;
  548. while (!IPXSumList.IsEmpty())
  549. delete IPXSumList.RemoveHead();
  550. return hr;
  551. }
  552. /*!--------------------------------------------------------------------------
  553. IPXSummaryHandler::GetClientInterfaceData
  554. -
  555. Author: KennT
  556. ---------------------------------------------------------------------------*/
  557. HRESULT IPXSummaryHandler::GetClientInterfaceData(IPXSummaryListEntry *pClient,
  558. IRtrMgrInfo *pRm)
  559. {
  560. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  561. SPIInfoBase spInfoBase;
  562. InfoBlock * pIpxBlock;
  563. InfoBlock * pWanBlock;
  564. HRESULT hr = hrOK;
  565. BOOL fSave = FALSE;
  566. pRm->GetInfoBase(NULL, NULL, NULL, &spInfoBase);
  567. if (spInfoBase == NULL)
  568. {
  569. CORg( CreateInfoBase(&spInfoBase) );
  570. }
  571. if (spInfoBase->GetBlock(IPX_INTERFACE_INFO_TYPE, &pIpxBlock, 0) != hrOK)
  572. {
  573. // We couldn't find the block, add it in
  574. IPX_IF_INFO ipx;
  575. ipx.AdminState = ADMIN_STATE_ENABLED;
  576. ipx.NetbiosAccept = ADMIN_STATE_DISABLED;
  577. ipx.NetbiosDeliver = ADMIN_STATE_DISABLED;
  578. CORg( spInfoBase->AddBlock(IPX_INTERFACE_INFO_TYPE,
  579. sizeof(ipx),
  580. (PBYTE) &ipx,
  581. 1,
  582. 0) );
  583. CORg( spInfoBase->GetBlock(IPX_INTERFACE_INFO_TYPE,
  584. &pIpxBlock, 0) );
  585. fSave = TRUE;
  586. }
  587. if (spInfoBase->GetBlock(IPXWAN_INTERFACE_INFO_TYPE, &pWanBlock, 0) != hrOK)
  588. {
  589. // We couldn't find the block, add it in
  590. IPXWAN_IF_INFO wan;
  591. wan.AdminState = ADMIN_STATE_ENABLED;
  592. CORg( spInfoBase->AddBlock(IPXWAN_INTERFACE_INFO_TYPE,
  593. sizeof(wan),
  594. (PBYTE) &wan,
  595. 1,
  596. 0) );
  597. CORg( spInfoBase->GetBlock(IPXWAN_INTERFACE_INFO_TYPE,
  598. &pWanBlock, 0) );
  599. fSave = TRUE;
  600. }
  601. pClient->m_stTitle.LoadString(IDS_IPX_DIAL_IN_CLIENTS);
  602. pClient->m_dwAdminState = ((PIPX_IF_INFO)pIpxBlock->pData)->AdminState;
  603. pClient->m_dwIfType = ROUTER_IF_TYPE_CLIENT;
  604. pClient->m_dwOperState = (DWORD) -1;
  605. pClient->m_dwSent = (DWORD) -1;
  606. pClient->m_dwRcvd = (DWORD) -1;
  607. pClient->m_dwOutFiltered = (DWORD) -1;
  608. pClient->m_dwOutDropped = (DWORD) -1;
  609. pClient->m_dwInFiltered = (DWORD) -1;
  610. pClient->m_dwInNoRoutes = (DWORD) -1;
  611. pClient->m_dwInDropped = (DWORD) -1;
  612. if (fSave)
  613. {
  614. pRm->Save(NULL, // pszMachine
  615. NULL, // hMachine
  616. NULL, // hTransport
  617. NULL, // pGlobalInfo
  618. spInfoBase, // pClientInfo
  619. 0); // dwDeleteProtocolId
  620. }
  621. Error:
  622. return hr;
  623. }
  624. /*!--------------------------------------------------------------------------
  625. IPXSummaryHandler::GetIPXSummaryData
  626. -
  627. Author: KennT
  628. ---------------------------------------------------------------------------*/
  629. HRESULT IPXSummaryHandler::GetIPXSummaryData(ITFSNode *pThisNode,
  630. IPXSummaryList *pIpxSumList)
  631. {
  632. HRESULT hr = hrOK;
  633. IPXConnection * pIPXConn;
  634. IPX_MIB_GET_INPUT_DATA MibGetInputData;
  635. DWORD IfSize = sizeof(IPX_INTERFACE);
  636. PIPX_INTERFACE pIpxIf = NULL;
  637. SPMprMibBuffer spMib;
  638. IPXSummaryListEntry *pEntry = NULL;
  639. DWORD dwErr;
  640. pIPXConn = GET_IPXSUMMARY_NODEDATA(pThisNode);
  641. // Enumerate through all of the interfaces and grab the data
  642. // Get the interface table
  643. MibGetInputData.TableId = IPX_INTERFACE_TABLE;
  644. dwErr = ::MprAdminMIBEntryGetFirst(pIPXConn->GetMibHandle(),
  645. PID_IPX,
  646. IPX_PROTOCOL_BASE,
  647. &MibGetInputData,
  648. sizeof(IPX_MIB_GET_INPUT_DATA),
  649. (LPVOID *) &pIpxIf,
  650. &IfSize);
  651. hr = HRESULT_FROM_WIN32(dwErr);
  652. spMib = (LPBYTE) pIpxIf;
  653. while (FHrSucceeded(hr))
  654. {
  655. pEntry = new IPXSummaryListEntry;
  656. pEntry->m_stId = pIpxIf->InterfaceName;
  657. memcpy(pEntry->m_network, pIpxIf->NetNumber,
  658. sizeof(pEntry->m_network));
  659. pEntry->m_dwOperState = pIpxIf->IfStats.IfOperState;
  660. pEntry->m_dwSent = pIpxIf->IfStats.OutDelivers;
  661. pEntry->m_dwRcvd = pIpxIf->IfStats.InDelivers;
  662. pEntry->m_dwOutFiltered = pIpxIf->IfStats.OutFiltered;
  663. pEntry->m_dwOutDropped = pIpxIf->IfStats.OutDiscards;
  664. pEntry->m_dwInFiltered = pIpxIf->IfStats.InFiltered;
  665. pEntry->m_dwInNoRoutes = pIpxIf->IfStats.InNoRoutes;
  666. pEntry->m_dwInDropped = pIpxIf->IfStats.InDiscards;
  667. pIpxSumList->AddTail(pEntry);
  668. pEntry = NULL;
  669. // Get the next data set
  670. MibGetInputData.MibIndex.InterfaceTableIndex.InterfaceIndex =
  671. pIpxIf->InterfaceIndex;
  672. spMib.Free();
  673. pIpxIf = NULL;
  674. dwErr = ::MprAdminMIBEntryGetNext(pIPXConn->GetMibHandle(),
  675. PID_IPX,
  676. IPX_PROTOCOL_BASE,
  677. &MibGetInputData,
  678. sizeof(IPX_MIB_GET_INPUT_DATA),
  679. (LPVOID *) &pIpxIf,
  680. &IfSize);
  681. hr = HRESULT_FROM_WIN32(dwErr);
  682. spMib = (PBYTE) pIpxIf;
  683. }
  684. //Error:
  685. if (pEntry)
  686. delete pEntry;
  687. if (!FHrSucceeded(hr) && (hr != HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS)))
  688. {
  689. // clean out the list
  690. while (!pIpxSumList->IsEmpty())
  691. delete pIpxSumList->RemoveHead();
  692. }
  693. return hr;
  694. }
  695. /*!--------------------------------------------------------------------------
  696. IPXSummaryHandler::AddMenuItems
  697. Implementation of ITFSResultHandler::AddMenuItems
  698. Use this to add commands to the context menu of the blank areas
  699. of the result pane.
  700. Author: KennT
  701. ---------------------------------------------------------------------------*/
  702. STDMETHODIMP IPXSummaryHandler::AddMenuItems(ITFSComponent *pComponent,
  703. MMC_COOKIE cookie,
  704. LPDATAOBJECT pDataObject,
  705. LPCONTEXTMENUCALLBACK pCallback,
  706. long *pInsertionAllowed)
  707. {
  708. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  709. HRESULT hr = hrOK;
  710. SPITFSNode spNode;
  711. m_spNodeMgr->FindNode(cookie, &spNode);
  712. // Call through to the regular OnAddMenuItems
  713. hr = OnAddMenuItems(spNode,
  714. pCallback,
  715. pDataObject,
  716. CCT_RESULT,
  717. TFS_COMPDATA_CHILD_CONTEXTMENU,
  718. pInsertionAllowed);
  719. return hr;
  720. }
  721. /*!--------------------------------------------------------------------------
  722. IPXSummaryHandler::Command
  723. -
  724. Author: KennT
  725. ---------------------------------------------------------------------------*/
  726. STDMETHODIMP IPXSummaryHandler::Command(ITFSComponent *pComponent,
  727. MMC_COOKIE cookie,
  728. int nCommandID,
  729. LPDATAOBJECT pDataObject)
  730. {
  731. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  732. SPITFSNode spNode;
  733. HRESULT hr = hrOK;
  734. m_spNodeMgr->FindNode(cookie, &spNode);
  735. hr = OnCommand(spNode,
  736. nCommandID,
  737. CCT_RESULT,
  738. pDataObject,
  739. TFS_COMPDATA_CHILD_CONTEXTMENU);
  740. return hr;
  741. }
  742. /*!--------------------------------------------------------------------------
  743. IPXSummaryHandler::OnNewInterface
  744. -
  745. Author: KennT
  746. ---------------------------------------------------------------------------*/
  747. HRESULT IPXSummaryHandler::OnNewInterface()
  748. {
  749. SPIRtrMgrInterfaceInfo spRmIf;
  750. SPIInterfaceInfo spIf;
  751. SPITFSNode spNode;
  752. SPITFSNode spSummaryNode;
  753. SPITFSNode spNewNode;
  754. SPIComponentData spComponentData;
  755. HRESULT hr = hrOK;
  756. SPITFSNodeEnum spEnumNode;
  757. BaseIPXResultNodeData * pData;
  758. CWnd * pWnd;
  759. CString stIfTitle;
  760. m_spNodeMgr->FindNode(m_cookie, &spSummaryNode);
  761. spSummaryNode->Notify(TFS_NOTIFY_REMOVE_DELETED_NODES, 0);
  762. //
  763. // Retrieve the IPX router-manager info object
  764. // We already have this in m_spRtrMgrInfo
  765. //
  766. Assert(m_spRtrMgrInfo);
  767. // Display the UI for adding interfaces
  768. pWnd = CWnd::FromHandle(::FindMMCMainWindow());
  769. if (!AddRmInterfacePrompt(m_spRouterInfo, m_spRtrMgrInfo, &spRmIf, pWnd))
  770. return hrOK;
  771. //
  772. // Get the interface which we are adding IPX to.
  773. //
  774. CORg( m_spRouterInfo->FindInterface(spRmIf->GetInterfaceId(),
  775. &spIf) );
  776. Assert(spIf);
  777. //
  778. // Add the interface to the IPX router-manager
  779. //
  780. CORg( spIf->AddRtrMgrInterface(spRmIf, NULL /* pInfoBase */) );
  781. // We need to add an interface node (do it manually rather
  782. // than through the refresh mechanism).
  783. CORg( AddInterfaceNode(spSummaryNode, spIf, FALSE, &spNewNode) );
  784. // Show IPX interface configuration
  785. spComponentData.HrQuery(m_spTFSCompData);
  786. stIfTitle.Format(IDS_IPX_INTERFACE_TITLE, spIf->GetTitle());
  787. DoPropertiesOurselvesSinceMMCSucks(spNewNode,
  788. spComponentData,
  789. stIfTitle);
  790. Error:
  791. return hr;
  792. }
  793. ImplementEmbeddedUnknown(IPXSummaryHandler, IRtrAdviseSink)
  794. STDMETHODIMP IPXSummaryHandler::EIRtrAdviseSink::OnChange(LONG_PTR ulConn,
  795. DWORD dwChangeType, DWORD dwObjectType, LPARAM lUserParam, LPARAM lParam)
  796. {
  797. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  798. InitPThis(IPXSummaryHandler, IRtrAdviseSink);
  799. SPITFSNode spThisNode;
  800. SPITFSNode spNode;
  801. SPITFSNodeEnum spEnumNode;
  802. SPIEnumInterfaceInfo spEnumIf;
  803. SPIInterfaceInfo spIf;
  804. BOOL fFound;
  805. BOOL fPleaseAdd;
  806. BaseIPXResultNodeData * pData;
  807. HRESULT hr = hrOK;
  808. pThis->m_spNodeMgr->FindNode(pThis->m_cookie, &spThisNode);
  809. if (dwObjectType == ROUTER_OBJ_RmIf)
  810. {
  811. if (dwChangeType == ROUTER_CHILD_ADD)
  812. {
  813. // Enumerate through the list of interfaces looking for
  814. // the interfaces that have this protocol. If we find
  815. // one, look for this interface in our list of nodes.
  816. spThisNode->GetEnum(&spEnumNode);
  817. CORg( pThis->m_spRouterInfo->EnumInterface(&spEnumIf) );
  818. spEnumIf->Reset();
  819. fPleaseAdd = FALSE;
  820. for (; spEnumIf->Next(1, &spIf, NULL) == hrOK; spIf.Release())
  821. {
  822. // Look for this interface in our list of nodes
  823. // If it's there than continue on
  824. fFound = FALSE;
  825. spEnumNode->Reset();
  826. spNode.Release();
  827. for (; spEnumNode->Next(1, &spNode, NULL) == hrOK; spNode.Release())
  828. {
  829. pData = GET_BASEIPXRESULT_NODEDATA(spNode);
  830. Assert(pData);
  831. ASSERT_BASEIPXRESULT_NODEDATA(pData);
  832. if (!pData->m_fClient && StriCmpW(pData->m_spIf->GetId(), spIf->GetId()) == 0)
  833. {
  834. fFound = TRUE;
  835. break;
  836. }
  837. }
  838. // If the interface was not found in the list of nodes,
  839. // then it is a candidate. Now we have to see if the
  840. // interface supports this transport.
  841. if (!fFound && (spIf->FindRtrMgrInterface(pThis->m_spRtrMgrInfo->GetTransportId(), NULL) == hrOK))
  842. {
  843. // If this interface has this transport, and is NOT in
  844. // the current list of nodes then add this interface
  845. // to the UI
  846. pThis->AddInterfaceNode(spThisNode, spIf, FALSE, NULL);
  847. fPleaseAdd = TRUE;
  848. }
  849. }
  850. // If it's not expanded, then we haven't added
  851. // the dial-in clients node.
  852. if (!pThis->m_bExpanded)
  853. {
  854. //$CLIENT: Add the client interface (setup default data)
  855. // the only thing that we can do in synchronize is to
  856. // get the Administrative status
  857. pThis->AddInterfaceNode(spThisNode, NULL, TRUE, NULL);
  858. fPleaseAdd = TRUE;
  859. }
  860. // Now that we have all of the nodes, update the data for
  861. // all of the nodes
  862. if (fPleaseAdd)
  863. pThis->SynchronizeNodeData(spThisNode);
  864. // Windows NT Bug : 288247
  865. // Set this here, so that we can avoid the nodes being
  866. // added in the OnExpand().
  867. pThis->m_bExpanded = TRUE;
  868. }
  869. else if (dwChangeType == ROUTER_CHILD_DELETE)
  870. {
  871. // Go through the list of nodes, if we cannot find the
  872. // node in the list of interfaces, delete the node
  873. spThisNode->GetEnum(&spEnumNode);
  874. spEnumNode->Reset();
  875. while (spEnumNode->Next(1, &spNode, NULL) == hrOK)
  876. {
  877. // Get the node data, look for the interface
  878. pData = GET_BASEIPXRESULT_NODEDATA(spNode);
  879. ASSERT_BASEIPXRESULT_NODEDATA(pData);
  880. //$CLIENT: if this is a client interface, we can't
  881. // delete the node
  882. if (!pData->m_fClient &&
  883. (LookupRtrMgrInterface(pThis->m_spRouterInfo,
  884. pData->m_spIf->GetId(),
  885. pThis->m_spRtrMgrInfo->GetTransportId(),
  886. NULL) != hrOK))
  887. {
  888. // cannot find the interface, release this node!
  889. spThisNode->RemoveChild(spNode);
  890. spNode->Destroy();
  891. }
  892. spNode.Release();
  893. spIf.Release();
  894. }
  895. }
  896. }
  897. else if (dwChangeType == ROUTER_REFRESH)
  898. {
  899. if (ulConn == pThis->m_ulStatsConnId)
  900. {
  901. // pThis->m_IpxStats.PostRefresh();
  902. }
  903. else
  904. {
  905. pThis->SynchronizeNodeData(spThisNode);
  906. }
  907. }
  908. Error:
  909. return hrOK;
  910. }
  911. /*!--------------------------------------------------------------------------
  912. IPXSummaryHandler::OnResultShow
  913. -
  914. Author: KennT
  915. ---------------------------------------------------------------------------*/
  916. HRESULT IPXSummaryHandler::OnResultShow(ITFSComponent *pTFSComponent, MMC_COOKIE cookie, LPARAM arg, LPARAM lParam)
  917. {
  918. BOOL bSelect = (BOOL) arg;
  919. HRESULT hr = hrOK;
  920. SPIRouterRefresh spRefresh;
  921. SPITFSNode spNode;
  922. BaseContainerHandler::OnResultShow(pTFSComponent, cookie, arg, lParam);
  923. if (bSelect)
  924. {
  925. // Call synchronize on this node
  926. m_spNodeMgr->FindNode(cookie, &spNode);
  927. if (spNode)
  928. SynchronizeNodeData(spNode);
  929. }
  930. // Un/Register for refresh advises
  931. if (m_spRouterInfo)
  932. m_spRouterInfo->GetRefreshObject(&spRefresh);
  933. if (spRefresh)
  934. {
  935. if (bSelect)
  936. {
  937. if (m_ulRefreshConnId == 0)
  938. spRefresh->AdviseRefresh(&m_IRtrAdviseSink, &m_ulRefreshConnId, 0);
  939. if (m_ulStatsConnId == 0)
  940. spRefresh->AdviseRefresh(&m_IRtrAdviseSink, &m_ulStatsConnId, 0);
  941. }
  942. else
  943. {
  944. if (m_ulRefreshConnId)
  945. spRefresh->UnadviseRefresh(m_ulRefreshConnId);
  946. m_ulRefreshConnId = 0;
  947. // We do not clean up the stats refresh on not show, since the
  948. // dialogs may still be up.
  949. }
  950. }
  951. return hr;
  952. }
  953. /*!--------------------------------------------------------------------------
  954. IPXSummaryHandler::CompareItems
  955. -
  956. Author: KennT
  957. ---------------------------------------------------------------------------*/
  958. STDMETHODIMP_(int) IPXSummaryHandler::CompareItems(
  959. ITFSComponent * pComponent,
  960. MMC_COOKIE cookieA,
  961. MMC_COOKIE cookieB,
  962. int nCol)
  963. {
  964. // Get the strings from the nodes and use that as a basis for
  965. // comparison.
  966. SPITFSNode spNode;
  967. SPITFSResultHandler spResult;
  968. m_spNodeMgr->FindNode(cookieA, &spNode);
  969. spNode->GetResultHandler(&spResult);
  970. return spResult->CompareItems(pComponent, cookieA, cookieB, nCol);
  971. }
  972. /*---------------------------------------------------------------------------
  973. Class: IPXSummaryInterfaceHandler
  974. ---------------------------------------------------------------------------*/
  975. IPXSummaryInterfaceHandler::IPXSummaryInterfaceHandler(ITFSComponentData *pCompData)
  976. : BaseIPXResultHandler(pCompData, COLUMNS_SUMMARY),
  977. m_ulConnId(0)
  978. {
  979. m_rgButtonState[MMC_VERB_PROPERTIES_INDEX] = ENABLED;
  980. m_bState[MMC_VERB_PROPERTIES_INDEX] = TRUE;
  981. m_rgButtonState[MMC_VERB_REFRESH_INDEX] = ENABLED;
  982. m_bState[MMC_VERB_REFRESH_INDEX] = TRUE;
  983. m_verbDefault = MMC_VERB_PROPERTIES;
  984. }
  985. static const DWORD s_rgInterfaceImageMap[] =
  986. {
  987. ROUTER_IF_TYPE_HOME_ROUTER, IMAGE_IDX_WAN_CARD,
  988. ROUTER_IF_TYPE_FULL_ROUTER, IMAGE_IDX_WAN_CARD,
  989. ROUTER_IF_TYPE_CLIENT, IMAGE_IDX_WAN_CARD,
  990. ROUTER_IF_TYPE_DEDICATED, IMAGE_IDX_LAN_CARD,
  991. ROUTER_IF_TYPE_INTERNAL, IMAGE_IDX_LAN_CARD,
  992. ROUTER_IF_TYPE_LOOPBACK, IMAGE_IDX_LAN_CARD,
  993. -1, IMAGE_IDX_WAN_CARD, // sentinel value
  994. };
  995. /*!--------------------------------------------------------------------------
  996. IPXSummaryInterfaceHandler::ConstructNode
  997. Initializes the Domain node (sets it up).
  998. Author: KennT
  999. ---------------------------------------------------------------------------*/
  1000. HRESULT IPXSummaryInterfaceHandler::ConstructNode(ITFSNode *pNode, IInterfaceInfo *pIfInfo, IPXConnection *pIPXConn)
  1001. {
  1002. HRESULT hr = hrOK;
  1003. int i;
  1004. if (pNode == NULL)
  1005. return hrOK;
  1006. COM_PROTECT_TRY
  1007. {
  1008. // Find the right image index for this type of node
  1009. if (pIfInfo)
  1010. {
  1011. for (i=0; i<DimensionOf(s_rgInterfaceImageMap); i+=2)
  1012. {
  1013. if ((pIfInfo->GetInterfaceType() == s_rgInterfaceImageMap[i]) ||
  1014. (-1 == s_rgInterfaceImageMap[i]))
  1015. break;
  1016. }
  1017. }
  1018. else
  1019. {
  1020. i = 2; // if no interface, assume this is a client interface
  1021. }
  1022. // We allow deleting of demand-dial nodes only (not on
  1023. // interfaces or the client node).
  1024. if (pIfInfo &&
  1025. (pIfInfo->GetInterfaceType() == ROUTER_IF_TYPE_FULL_ROUTER))
  1026. {
  1027. m_rgButtonState[MMC_VERB_DELETE_INDEX] = ENABLED;
  1028. m_bState[MMC_VERB_DELETE_INDEX] = TRUE;
  1029. }
  1030. pNode->SetData(TFS_DATA_IMAGEINDEX, s_rgInterfaceImageMap[i+1]);
  1031. pNode->SetData(TFS_DATA_OPENIMAGEINDEX, s_rgInterfaceImageMap[i+1]);
  1032. pNode->SetData(TFS_DATA_SCOPEID, 0);
  1033. pNode->SetData(TFS_DATA_COOKIE, reinterpret_cast<DWORD_PTR>(pNode));
  1034. //$ Review: kennt, what are the different type of interfaces
  1035. // do we distinguish based on the same list as above? (i.e. the
  1036. // one for image indexes).
  1037. pNode->SetNodeType(&GUID_IPXSummaryInterfaceNodeType);
  1038. BaseIPXResultNodeData::Init(pNode, pIfInfo, pIPXConn);
  1039. //now load the info base for this object
  1040. hr = LoadInfoBase(pIPXConn);
  1041. }
  1042. COM_PROTECT_CATCH
  1043. return hr;
  1044. }
  1045. /*!--------------------------------------------------------------------------
  1046. IPXSummaryInterfaceHandler::OnCreateDataObject
  1047. -
  1048. Author: KennT
  1049. ---------------------------------------------------------------------------*/
  1050. STDMETHODIMP IPXSummaryInterfaceHandler::OnCreateDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, IDataObject **ppDataObject)
  1051. {
  1052. HRESULT hr = hrOK;
  1053. COM_PROTECT_TRY
  1054. {
  1055. CORg( CreateDataObjectFromInterfaceInfo(m_spInterfaceInfo,
  1056. type, cookie, m_spTFSCompData,
  1057. ppDataObject) );
  1058. COM_PROTECT_ERROR_LABEL;
  1059. }
  1060. COM_PROTECT_CATCH;
  1061. return hr;
  1062. }
  1063. /*!--------------------------------------------------------------------------
  1064. IPXSummaryInterfaceHandler::OnCreateDataObject
  1065. Implementation of ITFSResultHandler::OnCreateDataObject
  1066. Author: KennT
  1067. ---------------------------------------------------------------------------*/
  1068. STDMETHODIMP IPXSummaryInterfaceHandler::OnCreateDataObject(ITFSComponent *pComp, MMC_COOKIE cookie, DATA_OBJECT_TYPES type, IDataObject **ppDataObject)
  1069. {
  1070. HRESULT hr = hrOK;
  1071. COM_PROTECT_TRY
  1072. {
  1073. CORg( CreateDataObjectFromInterfaceInfo(m_spInterfaceInfo,
  1074. type, cookie, m_spTFSCompData,
  1075. ppDataObject) );
  1076. COM_PROTECT_ERROR_LABEL;
  1077. }
  1078. COM_PROTECT_CATCH;
  1079. return hr;
  1080. }
  1081. /*!--------------------------------------------------------------------------
  1082. IPXSummaryInterfaceHandler::RefreshInterface
  1083. -
  1084. Author: KennT
  1085. ---------------------------------------------------------------------------*/
  1086. void IPXSummaryInterfaceHandler::RefreshInterface(MMC_COOKIE cookie)
  1087. {
  1088. SPITFSNode spNode;
  1089. m_spNodeMgr->FindNode(cookie, &spNode);
  1090. // Can't do it for a single node at this time, just refresh the
  1091. // whole thing.
  1092. ForwardCommandToParent(spNode, IDS_MENU_SYNC,
  1093. CCT_RESULT, NULL, 0);
  1094. }
  1095. /*!--------------------------------------------------------------------------
  1096. IPXSummaryInterfaceHandler::Init
  1097. -
  1098. Author: KennT
  1099. ---------------------------------------------------------------------------*/
  1100. HRESULT IPXSummaryInterfaceHandler::Init(IRtrMgrInfo *pRm, IInterfaceInfo *pIfInfo, ITFSNode *pParent)
  1101. {
  1102. m_spRm.Set(pRm);
  1103. m_spInterfaceInfo.Set(pIfInfo);
  1104. if (pRm)
  1105. pRm->GetParentRouterInfo(&m_spRouterInfo);
  1106. BaseIPXResultHandler::Init(pIfInfo, pParent);
  1107. return hrOK;
  1108. }
  1109. /*!--------------------------------------------------------------------------
  1110. IPXSummaryInterfaceHandler::DestroyResultHandler
  1111. -
  1112. Author: KennT
  1113. ---------------------------------------------------------------------------*/
  1114. STDMETHODIMP IPXSummaryInterfaceHandler::DestroyResultHandler(MMC_COOKIE cookie)
  1115. {
  1116. m_spInterfaceInfo.Release();
  1117. m_spRouterInfo.Release();
  1118. BaseIPXResultHandler::DestroyResultHandler(cookie);
  1119. return hrOK;
  1120. }
  1121. /*---------------------------------------------------------------------------
  1122. This is the list of commands that will show up for the result pane
  1123. nodes.
  1124. ---------------------------------------------------------------------------*/
  1125. static const SRouterNodeMenu s_rgIfMenu[] =
  1126. {
  1127. // Add items that go at the top here
  1128. { IDS_MENU_IPX_IF_ENABLE, IPXSummaryInterfaceHandler::GetEnableFlags,
  1129. CCM_INSERTIONPOINTID_PRIMARY_TOP },
  1130. { IDS_MENU_IPX_IF_DISABLE, IPXSummaryInterfaceHandler::GetDisableFlags,
  1131. CCM_INSERTIONPOINTID_PRIMARY_TOP },
  1132. { IDS_MENU_SEPARATOR, 0,
  1133. CCM_INSERTIONPOINTID_PRIMARY_TOP },
  1134. { IDS_MENU_UPDATE_ROUTES, IPXSummaryInterfaceHandler::GetUpdateRoutesFlags,
  1135. CCM_INSERTIONPOINTID_PRIMARY_TOP },
  1136. };
  1137. /*!--------------------------------------------------------------------------
  1138. IPXSummaryInterfaceHandler::AddMenuItems
  1139. Implementation of ITFSResultHandler::AddMenuItems
  1140. Author: KennT
  1141. ---------------------------------------------------------------------------*/
  1142. STDMETHODIMP IPXSummaryInterfaceHandler::AddMenuItems(
  1143. ITFSComponent *pComponent,
  1144. MMC_COOKIE cookie,
  1145. LPDATAOBJECT lpDataObject,
  1146. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  1147. long *pInsertionAllowed)
  1148. {
  1149. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1150. HRESULT hr = S_OK;
  1151. ULONG ulFlags;
  1152. UINT i;
  1153. CString stMenu;
  1154. SPITFSNode spNode;
  1155. IPXSummaryInterfaceHandler::SMenuData * pmenuData = new IPXSummaryInterfaceHandler::SMenuData;
  1156. COM_PROTECT_TRY
  1157. {
  1158. m_spNodeMgr->FindNode(cookie, &spNode);
  1159. // Now go through and add our menu items
  1160. pmenuData->m_spNode.Set(spNode);
  1161. pmenuData->m_spInterfaceInfo.Set(m_spInterfaceInfo);
  1162. //Reload the infobase in case it has changed
  1163. LoadInfoBase(NULL);
  1164. pmenuData->m_spInfoBaseCopy = m_spInfoBase;
  1165. hr = AddArrayOfMenuItems(spNode, s_rgIfMenu,
  1166. DimensionOf(s_rgIfMenu),
  1167. pContextMenuCallback,
  1168. *pInsertionAllowed,
  1169. reinterpret_cast<INT_PTR>(pmenuData));
  1170. }
  1171. COM_PROTECT_CATCH;
  1172. return hr;
  1173. }
  1174. ULONG IPXSummaryInterfaceHandler::GetUpdateRoutesFlags(const SRouterNodeMenu *pMenuData, INT_PTR pUserData)
  1175. {
  1176. DWORD dwIfType;
  1177. SMenuData * pData = reinterpret_cast<SMenuData *>(pUserData);
  1178. if (pData->m_spInterfaceInfo)
  1179. dwIfType = pData->m_spInterfaceInfo->GetInterfaceType();
  1180. else
  1181. dwIfType = ROUTER_IF_TYPE_INTERNAL;
  1182. if ((dwIfType == ROUTER_IF_TYPE_LOOPBACK) ||
  1183. (dwIfType == ROUTER_IF_TYPE_INTERNAL))
  1184. return 0xFFFFFFFF;
  1185. else
  1186. return 0;
  1187. }
  1188. ULONG IPXSummaryInterfaceHandler::GetEnableFlags(const SRouterNodeMenu *pMenuData, INT_PTR pUserData)
  1189. {
  1190. SMenuData * pData = reinterpret_cast<SMenuData *>(pUserData);
  1191. //BOOL bInterfaceIsEnabled = pData->m_spInterfaceInfo->IsInterfaceEnabled();
  1192. IPX_IF_INFO * pIpxIf = NULL;
  1193. (pData->m_spInfoBaseCopy)->GetData(IPX_INTERFACE_INFO_TYPE, 0, (BYTE **) &pIpxIf);
  1194. if ( pIpxIf )
  1195. return (pIpxIf->AdminState == ADMIN_STATE_DISABLED ? 0: 0xFFFFFFFF );
  1196. else
  1197. return 0xFFFFFFFF;
  1198. //if the interface is enabled then dont add the enable menu item
  1199. //if (pData->m_spInterfaceInfo)
  1200. //return pData->m_spInterfaceInfo->IsInterfaceEnabled() ? 0xFFFFFFFF : 0;
  1201. //else
  1202. //return 0xFFFFFFFF;
  1203. }
  1204. ULONG IPXSummaryInterfaceHandler::GetDisableFlags(const SRouterNodeMenu *pMenuData, INT_PTR pUserData)
  1205. {
  1206. SMenuData * pData = reinterpret_cast<SMenuData *>(pUserData);
  1207. IPX_IF_INFO * pIpxIf = NULL;
  1208. (pData->m_spInfoBaseCopy)->GetData(IPX_INTERFACE_INFO_TYPE, 0, (BYTE **) &pIpxIf);
  1209. if ( pIpxIf )
  1210. return (pIpxIf->AdminState == ADMIN_STATE_ENABLED ? 0: 0xFFFFFFFF );
  1211. else
  1212. return 0xFFFFFFFF;
  1213. /*
  1214. SMenuData * pData = reinterpret_cast<SMenuData *>(pUserData);
  1215. BOOL bInterfaceIsEnabled = pData->m_spInterfaceInfo->IsInterfaceEnabled();
  1216. ATLASSERT("This is wrong!");
  1217. if (pData->m_spInterfaceInfo)
  1218. return pData->m_spInterfaceInfo->IsInterfaceEnabled() ? 0: 0xFFFFFFFF;
  1219. else
  1220. return 0xFFFFFFFF;
  1221. */
  1222. }
  1223. /*!--------------------------------------------------------------------------
  1224. IPXSummaryInterfaceHandler::Command
  1225. -
  1226. Author: KennT
  1227. ---------------------------------------------------------------------------*/
  1228. STDMETHODIMP IPXSummaryInterfaceHandler::Command(ITFSComponent *pComponent,
  1229. MMC_COOKIE cookie,
  1230. int nCommandID,
  1231. LPDATAOBJECT pDataObject)
  1232. {
  1233. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1234. HRESULT hr = hrOK;
  1235. switch (nCommandID)
  1236. {
  1237. case IDS_MENU_UPDATE_ROUTES:
  1238. hr = OnUpdateRoutes(cookie);
  1239. break;
  1240. case IDS_MENU_IPX_IF_ENABLE:
  1241. hr = OnEnableDisableIPX ( TRUE, cookie );
  1242. break;
  1243. case IDS_MENU_IPX_IF_DISABLE:
  1244. hr = OnEnableDisableIPX ( FALSE, cookie );
  1245. break;
  1246. }
  1247. if (!FHrSucceeded(hr))
  1248. DisplayTFSErrorMessage(NULL);
  1249. else
  1250. RefreshInterface(cookie);
  1251. return hr;
  1252. }
  1253. HRESULT IPXSummaryInterfaceHandler::SaveChanges()
  1254. {
  1255. HRESULT hr = hrOK;
  1256. HANDLE hTransport = NULL, hInterface = NULL;
  1257. DWORD dwErr = NO_ERROR;
  1258. // By this time each page should have written its information out
  1259. // to the infobase
  1260. if (m_spInfoBase)
  1261. {
  1262. if (m_bClientInfoBase)
  1263. {
  1264. Assert(m_spRm);
  1265. CORg( m_spRm->Save(m_spRm->GetMachineName(), 0, 0, NULL,
  1266. m_spInfoBase, 0));
  1267. }
  1268. else
  1269. {
  1270. // For IPX, we need to have the protocol information in the
  1271. // infobase, BEFORE we add the interface to the running router.
  1272. Assert(m_spRmIf);
  1273. //
  1274. // Need to set the infobase back to the registry
  1275. //
  1276. m_pIPXConn->DisconnectFromConfigServer();
  1277. CWRg( ::MprConfigInterfaceGetHandle(
  1278. m_pIPXConn->GetConfigHandle(),
  1279. (LPTSTR) m_spRmIf->GetInterfaceId(),
  1280. &hInterface) );
  1281. // Get the transport handle
  1282. dwErr = ::MprConfigInterfaceTransportGetHandle(
  1283. m_pIPXConn->GetConfigHandle(),
  1284. hInterface,// need hInterface
  1285. PID_IPX,
  1286. &hTransport);
  1287. if (dwErr != ERROR_SUCCESS)
  1288. {
  1289. RtrMgrInterfaceCB rmIfCB;
  1290. m_spRmIf->CopyCB(&rmIfCB);
  1291. dwErr = ::MprConfigInterfaceTransportAdd(
  1292. m_pIPXConn->GetConfigHandle(),
  1293. hInterface,
  1294. m_spRmIf->GetTransportId(),
  1295. rmIfCB.szId,
  1296. NULL, 0, &hTransport);
  1297. }
  1298. CWRg( dwErr );
  1299. m_spRmIf->SetInfoBase(NULL, hInterface, hTransport, m_spInfoBase);
  1300. //
  1301. // Reload the infobase (to get the new data before calling
  1302. // the final save).
  1303. //
  1304. m_spInfoBase.Release();
  1305. m_spRmIf->GetInfoBase(NULL, hInterface, hTransport, &m_spInfoBase);
  1306. //
  1307. // Perform the final save (since we are passing in a non-NULL
  1308. // infobase pointer) this will commit the information back
  1309. // to the running router.
  1310. //
  1311. CORg( m_spRmIf->Save(m_spInterfaceInfo->GetMachineName(),
  1312. NULL, hInterface, hTransport, m_spInfoBase, 0));
  1313. }
  1314. }
  1315. Error:
  1316. return hr;
  1317. }
  1318. HRESULT IPXSummaryInterfaceHandler::LoadInfoBase( IPXConnection *pIPXConn)
  1319. {
  1320. Assert(pIPXConn);
  1321. HRESULT hr = hrOK;
  1322. HANDLE hTransport = NULL;
  1323. LPCOLESTR pszInterfaceId = NULL;
  1324. SPIInfoBase spInfoBase;
  1325. BYTE * pDefault;
  1326. int cBlocks = 0;
  1327. if ( pIPXConn )
  1328. {
  1329. m_pIPXConn = pIPXConn;
  1330. pIPXConn->AddRef();
  1331. }
  1332. // If configuring the client-interface, load the client-interface info,
  1333. // otherwise, retrieve the interface being configured and load
  1334. // its info.
  1335. // The client interface doesn't have an ID
  1336. if (m_spInterfaceInfo)
  1337. pszInterfaceId = m_spInterfaceInfo->GetId();
  1338. if ((pszInterfaceId == NULL) || (StrLenW(pszInterfaceId) == 0))
  1339. {
  1340. // Get the transport handle
  1341. CWRg( ::MprConfigTransportGetHandle(m_pIPXConn->GetConfigHandle(),
  1342. PID_IPX,
  1343. &hTransport) );
  1344. // Load the client interface info
  1345. CORg( m_spRm->GetInfoBase(m_pIPXConn->GetConfigHandle(),
  1346. hTransport,
  1347. NULL,
  1348. &spInfoBase) );
  1349. m_bClientInfoBase = TRUE;
  1350. }
  1351. else
  1352. {
  1353. m_spRmIf.Release();
  1354. CORg( m_spInterfaceInfo->FindRtrMgrInterface(PID_IPX,
  1355. &m_spRmIf) );
  1356. //
  1357. //$ Opt: This should be made into a sync call rather
  1358. // than a Load.
  1359. //
  1360. // Reload the information for this router-manager interface
  1361. // This call could fail for valid reasons (if we are creating
  1362. // a new interface, for example).
  1363. //
  1364. m_spRmIf->Load(m_spInterfaceInfo->GetMachineName(), NULL, NULL, NULL);
  1365. //
  1366. // The parameters are all NULL so that we can use the
  1367. // default RPC handles.
  1368. //
  1369. m_spRmIf->GetInfoBase(NULL, NULL, NULL, &spInfoBase);
  1370. m_bClientInfoBase = FALSE;
  1371. }
  1372. if (!spInfoBase)
  1373. {
  1374. // No info was found for the inteface
  1375. // allocate a new InfoBase instead
  1376. CORg( CreateInfoBase(&spInfoBase) );
  1377. }
  1378. m_spInfoBase.Release();
  1379. CORg( AddIpxPerInterfaceBlocks(m_spInterfaceInfo, spInfoBase) );
  1380. m_spInfoBase = spInfoBase.Transfer();
  1381. Error:
  1382. return hr;
  1383. }
  1384. HRESULT IPXSummaryInterfaceHandler::OnEnableDisableIPX(BOOL fEnable,
  1385. MMC_COOKIE cookie)
  1386. {
  1387. HRESULT hr = hrOK;
  1388. IPX_IF_INFO * pIpxIf = NULL;
  1389. CORg( m_spInfoBase->GetData(IPX_INTERFACE_INFO_TYPE, 0, (BYTE **) &pIpxIf) );
  1390. pIpxIf->AdminState = (fEnable ? ADMIN_STATE_ENABLED: ADMIN_STATE_DISABLED);
  1391. //now save the change here
  1392. hr = SaveChanges();
  1393. Error:
  1394. return hr;
  1395. }
  1396. /*!--------------------------------------------------------------------------
  1397. IPXSummaryInterfaceHandler::HasPropertyPages
  1398. -
  1399. Author: KennT
  1400. ---------------------------------------------------------------------------*/
  1401. STDMETHODIMP IPXSummaryInterfaceHandler::HasPropertyPages
  1402. (
  1403. ITFSNode * pNode,
  1404. LPDATAOBJECT pDataObject,
  1405. DATA_OBJECT_TYPES type,
  1406. DWORD dwType
  1407. )
  1408. {
  1409. return hrTrue;
  1410. }
  1411. /*!--------------------------------------------------------------------------
  1412. IPXSummaryInterfaceHandler::CreatePropertyPages
  1413. -
  1414. Author: KennT
  1415. ---------------------------------------------------------------------------*/
  1416. STDMETHODIMP IPXSummaryInterfaceHandler::CreatePropertyPages
  1417. (
  1418. ITFSNode * pNode,
  1419. LPPROPERTYSHEETCALLBACK lpProvider,
  1420. LPDATAOBJECT pDataObject,
  1421. LONG_PTR handle,
  1422. DWORD dwType
  1423. )
  1424. {
  1425. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1426. HRESULT hr = hrOK;
  1427. IPXSummaryInterfaceProperties * pProperties = NULL;
  1428. SPIComponentData spComponentData;
  1429. CString stTitle;
  1430. CORg( m_spNodeMgr->GetComponentData(&spComponentData) );
  1431. if (m_spInterfaceInfo)
  1432. stTitle.Format(IDS_IPXSUMMARY_IF_PAGE_TITLE,
  1433. m_spInterfaceInfo->GetTitle());
  1434. else
  1435. stTitle.LoadString(IDS_IPXSUMMARY_CLIENT_IF_PAGE_TITLE);
  1436. pProperties = new IPXSummaryInterfaceProperties(pNode, spComponentData,
  1437. m_spTFSCompData, stTitle);
  1438. CORg( pProperties->Init(m_spRm, m_spInterfaceInfo) );
  1439. if (lpProvider)
  1440. hr = pProperties->CreateModelessSheet(lpProvider, handle);
  1441. else
  1442. hr = pProperties->DoModelessSheet();
  1443. Error:
  1444. return hr;
  1445. }
  1446. /*!--------------------------------------------------------------------------
  1447. IPXSummaryInterfaceHandler::CreatePropertyPages
  1448. Implementation of ResultHandler::CreatePropertyPages
  1449. Author: KennT
  1450. ---------------------------------------------------------------------------*/
  1451. STDMETHODIMP IPXSummaryInterfaceHandler::CreatePropertyPages
  1452. (
  1453. ITFSComponent * pComponent,
  1454. MMC_COOKIE cookie,
  1455. LPPROPERTYSHEETCALLBACK lpProvider,
  1456. LPDATAOBJECT pDataObject,
  1457. LONG_PTR handle
  1458. )
  1459. {
  1460. // Forward this call onto the NodeHandler::CreatePropertyPages
  1461. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1462. HRESULT hr = hrOK;
  1463. SPITFSNode spNode;
  1464. Assert( m_spNodeMgr );
  1465. CORg( m_spNodeMgr->FindNode(cookie, &spNode) );
  1466. // Call the ITFSNodeHandler::CreatePropertyPages
  1467. hr = CreatePropertyPages(spNode, lpProvider, pDataObject, handle, 0);
  1468. Error:
  1469. return hr;
  1470. }
  1471. /*!--------------------------------------------------------------------------
  1472. IPXSummaryInterfaceHandler::OnResultDelete
  1473. -
  1474. Author: KennT
  1475. ---------------------------------------------------------------------------*/
  1476. HRESULT IPXSummaryInterfaceHandler::OnResultDelete(ITFSComponent *pComponent,
  1477. LPDATAOBJECT pDataObject,
  1478. MMC_COOKIE cookie,
  1479. LPARAM arg,
  1480. LPARAM param)
  1481. {
  1482. return OnRemoveInterface();
  1483. }
  1484. /*!--------------------------------------------------------------------------
  1485. IPXSummaryInterfaceHandler::OnRemoveInterface
  1486. -
  1487. Author: KennT
  1488. ---------------------------------------------------------------------------*/
  1489. HRESULT IPXSummaryInterfaceHandler::OnRemoveInterface()
  1490. {
  1491. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1492. // Prompt the user to make certain that IPX should be removed
  1493. // from this interface
  1494. SPIRouterInfo spRouterInfo;
  1495. HRESULT hr = hrOK;
  1496. SPITFSNodeHandler spHandler;
  1497. // Addref this node so that it won't get deleted before we're out
  1498. // of this function
  1499. spHandler.Set(this);
  1500. if (AfxMessageBox(IDS_PROMPT_VERIFY_REMOVE_INTERFACE, MB_YESNO|MB_DEFBUTTON2) == IDNO)
  1501. return HRESULT_FROM_WIN32(ERROR_CANCELLED);
  1502. // Remove IPX from the interface
  1503. hr = m_spInterfaceInfo->DeleteRtrMgrInterface(PID_IPX, TRUE);
  1504. if (!FHrSucceeded(hr))
  1505. {
  1506. AfxMessageBox(IDS_ERR_DELETE_INTERFACE);
  1507. }
  1508. return hr;
  1509. }
  1510. HRESULT IPXSummaryInterfaceHandler::OnUpdateRoutes(MMC_COOKIE cookie)
  1511. {
  1512. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1513. BaseIPXResultNodeData * pData;
  1514. SPITFSNode spNode;
  1515. DWORD dwErr = ERROR_SUCCESS;
  1516. HRESULT hr = hrOK;
  1517. CString stServiceDesc;
  1518. m_spNodeMgr->FindNode(cookie, &spNode);
  1519. pData = GET_BASEIPXRESULT_NODEDATA(spNode);
  1520. ASSERT_BASEIPXRESULT_NODEDATA(pData);
  1521. // Check to see if the service is started, if it isn't
  1522. // start it
  1523. CORg( IsRouterServiceRunning(m_spInterfaceInfo->GetMachineName(), NULL) );
  1524. if (hr != hrOK)
  1525. {
  1526. // Ask the user if they want to start the service
  1527. if (AfxMessageBox(IDS_PROMPT_SERVICESTART, MB_YESNO) != IDYES)
  1528. CWRg( ERROR_CANCELLED );
  1529. // Else start the service
  1530. stServiceDesc.LoadString(IDS_RRAS_SERVICE_DESC);
  1531. dwErr = TFSStartService(m_spInterfaceInfo->GetMachineName(), c_szRouter, stServiceDesc);
  1532. if (dwErr != NO_ERROR)
  1533. {
  1534. CWRg( dwErr );
  1535. }
  1536. }
  1537. // Update the routes
  1538. CWRg( UpdateRoutes(m_spInterfaceInfo->GetMachineName(),
  1539. m_spInterfaceInfo->GetId(),
  1540. PID_IPX,
  1541. NULL) );
  1542. Error:
  1543. AddRasErrorMessage(hr);
  1544. return hr;
  1545. }