Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

448 lines
14 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. root.cpp
  7. Root node information (the root node is not displayed
  8. in the MMC framework but contains information such as
  9. all of the subnodes in this snapin).
  10. FILE HISTORY:
  11. */
  12. #include "stdafx.h"
  13. #include "util.h"
  14. #include "ipxroot.h"
  15. #include "ipxconn.h"
  16. #include "reg.h"
  17. #include "rtrui.h"
  18. #include "ipxstats.h" // for MVR_IPX_COUNT
  19. /*---------------------------------------------------------------------------
  20. IPXRootHandler implementation
  21. ---------------------------------------------------------------------------*/
  22. DEBUG_DECLARE_INSTANCE_COUNTER(IPXRootHandler)
  23. extern const ContainerColumnInfo s_rgIpxStatsColumnInfo[];
  24. extern const ContainerColumnInfo s_rgIpxRoutingStatsColumnInfo[];
  25. extern const ContainerColumnInfo s_rgIpxServiceStatsColumnInfo[];
  26. struct _ViewInfoColumnEntry
  27. {
  28. UINT m_ulId;
  29. UINT m_cColumns;
  30. const ContainerColumnInfo *m_prgColumn;
  31. };
  32. static const struct _ViewInfoColumnEntry s_rgViewColumnInfo[] =
  33. {
  34. { IPXSTRM_STATS_IPX, MVR_IPX_COUNT, s_rgIpxStatsColumnInfo },
  35. { IPXSTRM_STATS_ROUTING, MVR_IPXROUTING_COUNT, s_rgIpxRoutingStatsColumnInfo },
  36. { IPXSTRM_STATS_SERVICE, MVR_IPXSERVICE_COUNT, s_rgIpxServiceStatsColumnInfo },
  37. };
  38. IPXRootHandler::IPXRootHandler(ITFSComponentData *pCompData)
  39. : RootHandler(pCompData)
  40. {
  41. DEBUG_INCREMENT_INSTANCE_COUNTER(IPXRootHandler)
  42. Assert(DimensionOf(s_rgViewColumnInfo) <= IPXSTRM_MAX_COUNT);
  43. m_ConfigStream.Init(DimensionOf(s_rgViewColumnInfo));
  44. // This will initialize the view information for the statistics
  45. // dialogs. (which is why the fConfigurableColumns is set to TRUE).
  46. for (int i=0; i<DimensionOf(s_rgViewColumnInfo); i++)
  47. {
  48. m_ConfigStream.InitViewInfo(s_rgViewColumnInfo[i].m_ulId,
  49. TRUE /*fConfigurableColumns*/,
  50. s_rgViewColumnInfo[i].m_cColumns,
  51. TRUE,
  52. s_rgViewColumnInfo[i].m_prgColumn);
  53. }
  54. }
  55. /*!--------------------------------------------------------------------------
  56. IPXRootHandler::QueryInterface
  57. -
  58. Author: KennT
  59. ---------------------------------------------------------------------------*/
  60. STDMETHODIMP IPXRootHandler::QueryInterface(REFIID riid, LPVOID *ppv)
  61. {
  62. // Is the pointer bad?
  63. if (ppv == NULL)
  64. return E_INVALIDARG;
  65. // Place NULL in *ppv in case of failure
  66. *ppv = NULL;
  67. // This is the non-delegating IUnknown implementation
  68. if (riid == IID_IUnknown)
  69. *ppv = (LPVOID) this;
  70. else if (riid == IID_IRtrAdviseSink)
  71. *ppv = &m_IRtrAdviseSink;
  72. else
  73. return RootHandler::QueryInterface(riid, ppv);
  74. // If we're going to return an interface, AddRef it first
  75. if (*ppv)
  76. {
  77. ((LPUNKNOWN) *ppv)->AddRef();
  78. return hrOK;
  79. }
  80. else
  81. return E_NOINTERFACE;
  82. }
  83. STDMETHODIMP IPXRootHandler::GetClassID
  84. (
  85. CLSID *pClassID
  86. )
  87. {
  88. ASSERT(pClassID != NULL);
  89. // Copy the CLSID for this snapin
  90. *pClassID = CLSID_IPXAdminExtension;
  91. return hrOK;
  92. }
  93. /*!--------------------------------------------------------------------------
  94. IPXRootHandler::ConstructNode
  95. -
  96. Author: EricDav
  97. ---------------------------------------------------------------------------*/
  98. HRESULT IPXRootHandler::ConstructNode(ITFSNode *pNode)
  99. {
  100. HRESULT hr = hrOK;
  101. EnumDynamicExtensions(pNode);
  102. CORg (RootHandler::ConstructNode(pNode));
  103. Error:
  104. return hr;
  105. }
  106. /*!--------------------------------------------------------------------------
  107. IPXRootHandler::OnExpand
  108. -
  109. Author: KennT
  110. ---------------------------------------------------------------------------*/
  111. HRESULT IPXRootHandler::OnExpand(ITFSNode *pNode,
  112. LPDATAOBJECT pDataObject,
  113. DWORD dwType,
  114. LPARAM arg,
  115. LPARAM lParam)
  116. {
  117. HRESULT hr = hrOK;
  118. LONG_PTR ulConnId;
  119. SPIRouterInfo spRouterInfo;
  120. SPIRouterRefresh spRefresh;
  121. BOOL fAddedAsLocal = FALSE;
  122. // Grab the router info from the dataobject
  123. spRouterInfo.Query(pDataObject);
  124. Assert(spRouterInfo);
  125. // Register for refresh notifications on the main router info
  126. // (We do not need to register for IP changes, just the refresh)
  127. spRouterInfo->GetRefreshObject(&spRefresh);
  128. Assert(spRefresh);
  129. spRefresh->AdviseRefresh(&m_IRtrAdviseSink,
  130. &ulConnId,
  131. pNode->GetData(TFS_DATA_COOKIE));
  132. // Setup the Router to connection id mappings
  133. // The IID_IRouterRefresh tells the RtrObjMap to use
  134. // the Refresh advise.
  135. AddRtrObj(ulConnId, IID_IRouterRefresh, spRouterInfo);
  136. fAddedAsLocal = ExtractComputerAddedAsLocal(pDataObject);
  137. SetComputerAddedAsLocal(ulConnId, fAddedAsLocal);
  138. if (fAddedAsLocal)
  139. AddScopeItem(_T(""), (HSCOPEITEM) lParam);
  140. else
  141. AddScopeItem(spRouterInfo->GetMachineName(), (HSCOPEITEM) lParam);
  142. // Add the node
  143. AddRemoveIPXRootNode(pNode, spRouterInfo, fAddedAsLocal);
  144. return hr;
  145. }
  146. /*!--------------------------------------------------------------------------
  147. IPXRootHandler::OnCreateDataObject
  148. Implementation of ITFSNodeHandler::OnCreateDataObject
  149. Author: KennT
  150. ---------------------------------------------------------------------------*/
  151. STDMETHODIMP IPXRootHandler::OnCreateDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, IDataObject **ppDataObject)
  152. {
  153. HRESULT hr = hrOK;
  154. SPIRouterInfo spRouterInfo;
  155. COM_PROTECT_TRY
  156. {
  157. // this will always be NULL
  158. if (spRouterInfo == NULL)
  159. {
  160. // If we haven't created the sub nodes yet, we still have to
  161. // create a dataobject.
  162. CDataObject * pObject = NULL;
  163. SPIDataObject spDataObject;
  164. SPITFSNode spNode;
  165. SPITFSNodeHandler spHandler;
  166. pObject = new CDataObject;
  167. spDataObject = pObject; // do this so that it gets released correctly
  168. Assert(pObject != NULL);
  169. // Save cookie and type for delayed rendering
  170. pObject->SetType(type);
  171. pObject->SetCookie(cookie);
  172. // Store the coclass with the data object
  173. pObject->SetClsid(*(m_spTFSCompData->GetCoClassID()));
  174. pObject->SetTFSComponentData(m_spTFSCompData);
  175. pObject->SetDynExt(&m_dynExtensions);
  176. hr = pObject->QueryInterface(IID_IDataObject,
  177. reinterpret_cast<void**>(ppDataObject));
  178. }
  179. else
  180. hr = CreateDataObjectFromRouterInfo(spRouterInfo,
  181. type, cookie, m_spTFSCompData,
  182. ppDataObject, &m_dynExtensions);
  183. }
  184. COM_PROTECT_CATCH;
  185. return hr;
  186. }
  187. /*!--------------------------------------------------------------------------
  188. IPXRootHandler::SearchIPXRoutingNodes
  189. -
  190. Author: KennT
  191. ---------------------------------------------------------------------------*/
  192. HRESULT IPXRootHandler::SearchIPXRoutingNodes(ITFSNode *pParent,
  193. LPCTSTR pszMachineName,
  194. BOOL fAddedAsLocal,
  195. ITFSNode **ppChild)
  196. {
  197. HRESULT hr = hrFalse;
  198. SPITFSNodeEnum spNodeEnum;
  199. SPITFSNode spNode;
  200. // Enumerate through all of the child nodes and return the
  201. // first node that matches the GUID and the name.
  202. CORg( pParent->GetEnum(&spNodeEnum) );
  203. while ( spNodeEnum->Next(1, &spNode, NULL) == hrOK )
  204. {
  205. if (*(spNode->GetNodeType()) == GUID_IPXNodeType)
  206. {
  207. // determin if the spChild is the same for the required routerinfo
  208. // -- compare the names
  209. IPXConnection * pIPXConn = GET_IPXADMIN_NODEDATA((ITFSNode*)spNode);
  210. Assert(pIPXConn);
  211. // if the child is not for the same machine --
  212. // routerinfo, it doesn't count
  213. if ((0 == StriCmp(pIPXConn->GetMachineName(), pszMachineName)) ||
  214. (IsLocalMachine(pIPXConn->GetMachineName()) &&
  215. IsLocalMachine(pszMachineName)))
  216. {
  217. if (pIPXConn->IsComputerAddedAsLocal() == fAddedAsLocal)
  218. break;
  219. }
  220. }
  221. spNode.Release();
  222. }
  223. if (spNode)
  224. {
  225. if (ppChild)
  226. *ppChild = spNode.Transfer();
  227. hr = hrOK;
  228. }
  229. Error:
  230. return hr;
  231. }
  232. /*!--------------------------------------------------------------------------
  233. IPXRootHandler::AddRemoveIPXRootNode
  234. -
  235. Author: KennT
  236. ---------------------------------------------------------------------------*/
  237. HRESULT IPXRootHandler::AddRemoveIPXRootNode(ITFSNode *pNode,
  238. IRouterInfo *pRouter,
  239. BOOL fAddedAsLocal)
  240. {
  241. HRESULT hr = hrOK;
  242. SPITFSNodeHandler spHandler;
  243. IPXAdminNodeHandler * pHandler = NULL;
  244. SPITFSNode spChild;
  245. SPITFSNode spNode;
  246. RouterVersionInfo versionInfo;
  247. HSCOPEITEM hScopeItem = NULL;
  248. pRouter->GetRouterVersionInfo(&versionInfo);
  249. pRouter->FindRtrMgr(PID_IPX, NULL);
  250. // Search for an already existing node
  251. // ----------------------------------------------------------------
  252. SearchIPXRoutingNodes(pNode, pRouter->GetMachineName(), fAddedAsLocal, &spChild);
  253. if ((versionInfo.dwRouterFlags & RouterSnapin_IsConfigured) &&
  254. (pRouter->FindRtrMgr(PID_IPX, NULL) == hrOK))
  255. {
  256. // Ok, the router is configured, and there is an IPX rtrmgr
  257. if (spChild == NULL)
  258. {
  259. // add the IPX node
  260. // --------------------------------------------------------
  261. pHandler = new IPXAdminNodeHandler(m_spTFSCompData);
  262. spHandler = pHandler;
  263. CORg( pHandler->Init(pRouter, &m_ConfigStream) );
  264. CreateContainerTFSNode(&spNode,
  265. &GUID_IPXNodeType,
  266. static_cast<ITFSNodeHandler *>(pHandler),
  267. static_cast<ITFSResultHandler *>(pHandler),
  268. m_spNodeMgr);
  269. // Call to the node handler to init the node data
  270. pHandler->ConstructNode(spNode, fAddedAsLocal);
  271. // Make the node immediately visible
  272. spNode->SetVisibilityState(TFS_VIS_SHOW);
  273. if ( FHrOK(pNode->AddChild(spNode)) )
  274. {
  275. // Add the cookie to the node map
  276. if (fAddedAsLocal)
  277. GetScopeItem(_T(""), &hScopeItem);
  278. else
  279. GetScopeItem(pRouter->GetMachineName(), &hScopeItem);
  280. AddCookie(hScopeItem, (MMC_COOKIE)
  281. spNode->GetData(TFS_DATA_COOKIE));
  282. }
  283. else
  284. {
  285. // Remove this node
  286. // ----------------------------------------------------
  287. pNode->RemoveChild(spNode);
  288. spNode->Destroy();
  289. spNode.Release();
  290. }
  291. // I don't think we need this here
  292. // AddDynamicNamespaceExtensions(pNode);
  293. }
  294. }
  295. else
  296. {
  297. if (spChild)
  298. {
  299. // Remove this node
  300. // --------------------------------------------------------
  301. pNode->RemoveChild(spChild);
  302. spChild->Destroy();
  303. spChild.Release();
  304. }
  305. }
  306. Error:
  307. return hr;
  308. }
  309. /*---------------------------------------------------------------------------
  310. Embedded IRtrAdviseSink
  311. ---------------------------------------------------------------------------*/
  312. ImplementEmbeddedUnknown(IPXRootHandler, IRtrAdviseSink)
  313. /*!--------------------------------------------------------------------------
  314. IPXRootHandler::EIRtrAdviseSink::OnChange
  315. -
  316. Author: KennT
  317. ---------------------------------------------------------------------------*/
  318. STDMETHODIMP IPXRootHandler::EIRtrAdviseSink::OnChange(LONG_PTR ulConn,
  319. DWORD dwChangeType, DWORD dwObjectType, LPARAM lUserParam, LPARAM lParam)
  320. {
  321. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  322. InitPThis(IPXRootHandler, IRtrAdviseSink);
  323. SPITFSNode spThisNode;
  324. SPIRouterInfo spRouter;
  325. HSCOPEITEM hScopeItem, hOldScopeItem;
  326. HRESULT hr = hrOK;
  327. BOOL fAddedAsLocal = FALSE;
  328. COM_PROTECT_TRY
  329. {
  330. if ((dwChangeType == ROUTER_REFRESH) ||
  331. (dwChangeType == ROUTER_CHILD_ADD) ||
  332. (dwChangeType == ROUTER_CHILD_DELETE))
  333. {
  334. pThis->GetRtrObj(ulConn, (IUnknown **) &spRouter);
  335. Assert(spRouter);
  336. // The lUserParam passed into the refresh is the cookie for
  337. // this machine node.
  338. // --------------------------------------------------------
  339. pThis->m_spNodeMgr->FindNode(lUserParam, &spThisNode);
  340. // Get the proper scope item for this node.
  341. // If this call fails, then we haven't expanded this node yet,
  342. // and thus can't add child nodes to it.
  343. // --------------------------------------------------------
  344. fAddedAsLocal = pThis->IsComputerAddedAsLocal(ulConn);
  345. if (fAddedAsLocal)
  346. hr = pThis->GetScopeItem(_T(""), &hScopeItem);
  347. else
  348. hr = pThis->GetScopeItem(spRouter->GetMachineName(), &hScopeItem);
  349. if (FHrOK(hr))
  350. {
  351. // Get the old one and save it. place the new one in the node.
  352. // ----------------------------------------------------
  353. hOldScopeItem = spThisNode->GetData(TFS_DATA_SCOPEID);
  354. spThisNode->SetData(TFS_DATA_SCOPEID, hScopeItem);
  355. // Look to see if we need the IPX root node
  356. // ----------------------------------------------------
  357. pThis->AddRemoveIPXRootNode(spThisNode, spRouter, fAddedAsLocal);
  358. }
  359. }
  360. }
  361. COM_PROTECT_CATCH;
  362. // Restore the scope item
  363. if (spThisNode)
  364. spThisNode->SetData(TFS_DATA_SCOPEID, hOldScopeItem);
  365. return hr;
  366. }
  367. STDMETHODIMP IPXRootHandler::DestroyHandler(ITFSNode *pNode)
  368. {
  369. RemoveAllRtrObj();
  370. return hrOK;
  371. }