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.

1339 lines
36 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 "machine.h"
  14. #include "rtrcfg.h"
  15. #include "resource.h"
  16. #include "ncglobal.h" // network console global defines
  17. #include "htmlhelp.h"
  18. #include "dmvstrm.h"
  19. #include "dmvroot.h"
  20. #include "dvsview.h"
  21. #include "refresh.h"
  22. #include "refrate.h"
  23. #include "rtrres.h"
  24. unsigned int g_cfMachineName = RegisterClipboardFormat(L"MMC_SNAPIN_MACHINE_NAME");
  25. // result message view stuff
  26. #define ROOT_MESSAGE_MAX_STRING 5
  27. typedef enum _ROOT_MESSAGES
  28. {
  29. ROOT_MESSAGE_MAIN,
  30. ROOT_MESSAGE_MAX
  31. };
  32. UINT g_uRootMessages[ROOT_MESSAGE_MAX][ROOT_MESSAGE_MAX_STRING] =
  33. {
  34. {IDS_ROOT_MESSAGE_TITLE, Icon_Information, IDS_ROOT_MESSAGE_BODY1, IDS_ROOT_MESSAGE_BODY2, 0},
  35. };
  36. DEBUG_DECLARE_INSTANCE_COUNTER(DMVRootHandler)
  37. // DMVRootHandler implementation
  38. /*
  39. extern const ContainerColumnInfo s_rgATLKInterfaceStatsColumnInfo[];
  40. extern const ContainerColumnInfo s_rgATLKGroupStatsColumnInfo[];
  41. struct _ViewInfoColumnEntry
  42. {
  43. UINT m_ulId;
  44. UINT m_cColumns;
  45. const ContainerColumnInfo *m_prgColumn;
  46. };
  47. */
  48. DMVRootHandler::DMVRootHandler(ITFSComponentData *pCompData)
  49. : RootHandler(pCompData),
  50. m_ulConnId(0),
  51. m_fAddedProtocolNode(FALSE)
  52. // m_dwRefreshInterval(DEFAULT_REFRESH_INTERVAL)
  53. {
  54. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  55. DEBUG_INCREMENT_INSTANCE_COUNTER(DMVRootHandler)
  56. //create one qeneral query placeholder
  57. m_ConfigStream.m_RQPersist.createQry(1);
  58. m_bExpanded=false;
  59. }
  60. DMVRootHandler::~DMVRootHandler()
  61. {
  62. m_spServerNodesRefreshObject.Release();
  63. m_spSummaryModeRefreshObject.Free();
  64. DEBUG_DECREMENT_INSTANCE_COUNTER(DMVRootHandler);
  65. };
  66. STDMETHODIMP DMVRootHandler::QueryInterface(REFIID riid, LPVOID *ppv)
  67. {
  68. // Is the pointer bad?
  69. if ( ppv == NULL )
  70. return E_INVALIDARG;
  71. // Place NULL in *ppv in case of failure
  72. *ppv = NULL;
  73. // This is the non-delegating IUnknown implementation
  74. if ( riid == IID_IUnknown )
  75. *ppv = (LPVOID) this;
  76. else
  77. return RootHandler::QueryInterface(riid, ppv);
  78. // If we're going to return an interface, AddRef it first
  79. if ( *ppv )
  80. {
  81. ((LPUNKNOWN) *ppv)->AddRef();
  82. return hrOK;
  83. }
  84. else
  85. return E_NOINTERFACE;
  86. }
  87. ///////////////////////////////////////////////////////////////////////////////
  88. //// IPersistStream interface members
  89. STDMETHODIMP DMVRootHandler::GetClassID
  90. (
  91. CLSID *pClassID
  92. )
  93. {
  94. ASSERT(pClassID != NULL);
  95. // Copy the CLSID for this snapin
  96. *pClassID = CLSID_RouterSnapin;
  97. return hrOK;
  98. }
  99. // Global refresh is to be shareed by multiple machine nodes and status node
  100. // in case of this snapin is created as extension, it not being used
  101. HRESULT DMVRootHandler::GetSummaryNodeRefreshObject(RouterRefreshObject** ppRefresh)
  102. {
  103. HRESULT hr = hrOK;
  104. HWND hWndSync = m_spTFSCompData->GetHiddenWnd();
  105. COM_PROTECT_TRY
  106. {
  107. // If there is no sync window, then there is no refresh object
  108. // ------------------------------------------------------------
  109. if (hWndSync
  110. || m_spSummaryModeRefreshObject) // added by WeiJiang 10/29/98 to allow external RefreshObject
  111. {
  112. if (!m_spSummaryModeRefreshObject)
  113. {
  114. try{
  115. RouterRefreshObject* pRefresh = new RouterRefreshObject(hWndSync);
  116. m_spSummaryModeRefreshObject = pRefresh;
  117. m_RefreshGroup.Join(pRefresh);
  118. }catch(...)
  119. {
  120. }
  121. if(m_spSummaryModeRefreshObject)
  122. {
  123. if(m_ConfigStream.m_dwRefreshInterval)
  124. {
  125. if(m_ConfigStream.m_bAutoRefresh)
  126. m_spSummaryModeRefreshObject->Start(m_ConfigStream.m_dwRefreshInterval);
  127. else
  128. m_spSummaryModeRefreshObject->SetRefreshInterval(m_ConfigStream.m_dwRefreshInterval);
  129. }
  130. }
  131. }
  132. if (ppRefresh)
  133. {
  134. *ppRefresh = m_spSummaryModeRefreshObject;
  135. (*ppRefresh)->AddRef();
  136. }
  137. }
  138. else
  139. {
  140. if (ppRefresh)
  141. *ppRefresh = NULL;
  142. hr = E_FAIL;
  143. }
  144. }
  145. COM_PROTECT_CATCH;
  146. return hr;
  147. }
  148. // Global refresh is to be shareed by multiple machine nodes and status node
  149. // in case of this snapin is created as extension, it not being used
  150. HRESULT DMVRootHandler::GetServerNodesRefreshObject(IRouterRefresh** ppRefresh)
  151. {
  152. HRESULT hr = hrOK;
  153. HWND hWndSync = m_spTFSCompData->GetHiddenWnd();
  154. COM_PROTECT_TRY
  155. {
  156. // If there is no sync window, then there is no refresh object
  157. // ------------------------------------------------------------
  158. if (hWndSync
  159. || (IRouterRefresh*)m_spServerNodesRefreshObject) // added by WeiJiang 10/29/98 to allow external RefreshObject
  160. {
  161. if ((IRouterRefresh*)m_spServerNodesRefreshObject == NULL)
  162. {
  163. RouterRefreshObject* pRefresh = new RouterRefreshObject(hWndSync);
  164. if(pRefresh)
  165. {
  166. m_spServerNodesRefreshObject = pRefresh;
  167. m_RefreshGroup.Join(pRefresh);
  168. if(m_ConfigStream.m_dwRefreshInterval)
  169. {
  170. if(m_ConfigStream.m_bAutoRefresh)
  171. m_spServerNodesRefreshObject->Start(m_ConfigStream.m_dwRefreshInterval);
  172. else
  173. m_spServerNodesRefreshObject->SetRefreshInterval(m_ConfigStream.m_dwRefreshInterval);
  174. }
  175. }
  176. }
  177. if (ppRefresh)
  178. {
  179. *ppRefresh = m_spServerNodesRefreshObject;
  180. (*ppRefresh)->AddRef();
  181. }
  182. }
  183. else
  184. {
  185. if (ppRefresh)
  186. *ppRefresh = NULL;
  187. hr = E_FAIL;
  188. }
  189. }
  190. COM_PROTECT_CATCH;
  191. return hr;
  192. }
  193. /*!--------------------------------------------------------------------------
  194. DMVRootHandler::Init
  195. ---------------------------------------------------------------------------*/
  196. HRESULT DMVRootHandler::Init(ITFSNode* pNode)
  197. {
  198. m_ConfigStream.Init(this, pNode);
  199. return hrOK;
  200. }
  201. /*!--------------------------------------------------------------------------
  202. DMVRootHandler::OnExpand
  203. -
  204. Author: KennT
  205. ---------------------------------------------------------------------------*/
  206. HRESULT DMVRootHandler::OnExpand(ITFSNode *pNode,LPDATAOBJECT pDataObject, DWORD dwType, LPARAM arg,LPARAM lParam)
  207. {
  208. HRESULT hr = hrOK;
  209. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  210. // For now create a new node handler for each new node,
  211. // this is rather bogus as it can get expensive. We can
  212. // consider creating only a single node handler for each
  213. // node type.
  214. MachineHandler * pHandler = NULL;
  215. SPITFSNodeHandler spHandler;
  216. SPITFSNodeHandler spStatusHandler;
  217. SPITFSNode spNodeS;
  218. SPITFSNode spNodeM;
  219. DomainStatusHandler * pStatusHandler = NULL;
  220. DWORD dw;
  221. int i;
  222. list<MachineNodeData *>::iterator itor;
  223. SPMachineNodeData spMachineData;
  224. MachineNodeData * pMachineData;
  225. SPIRouterRefresh spServerNodesRefresh;
  226. SPRouterRefreshObject spSummaryNodeRefresh;
  227. CString stMachineName;
  228. COM_PROTECT_TRY
  229. {
  230. if (dwType & TFS_COMPDATA_EXTENSION)
  231. {
  232. // we are extending the network management snapin.
  233. // Add a node for the machine
  234. // specified in the data object.
  235. stMachineName = Extract<TCHAR>(pDataObject, (CLIPFORMAT) g_cfMachineName, COMPUTERNAME_LEN_MAX);
  236. //create a machine handler
  237. pHandler = new MachineHandler(m_spTFSCompData);
  238. // Create a new machine data
  239. spMachineData = new MachineNodeData;
  240. spMachineData->Init(stMachineName);
  241. // Do this so that it will get released correctly
  242. spHandler = pHandler;
  243. pHandler->Init(stMachineName, NULL, NULL, NULL);
  244. if(!spServerNodesRefresh)
  245. GetServerNodesRefreshObject(&spServerNodesRefresh);
  246. if((IRouterRefresh*)spServerNodesRefresh)
  247. CORg(pHandler->SetExternalRefreshObject(spServerNodesRefresh));
  248. if(stMachineName.GetLength() == 0)
  249. stMachineName = GetLocalMachineName();
  250. // Create the root node for this sick puppy
  251. CORg( CreateContainerTFSNode(&spNodeM,
  252. &GUID_RouterMachineNodeType,
  253. pHandler,
  254. pHandler /* result handler */,
  255. m_spNodeMgr) );
  256. Assert(spNodeM);
  257. spNodeM->SetData(TFS_DATA_COOKIE, (LONG_PTR)(ITFSNode*)spNodeM);
  258. CORg(pHandler->ConstructNode(spNodeM, stMachineName, spMachineData) );
  259. pHandler->SetExtensionStatus(spNodeM, TRUE);
  260. // Make the node immediately visible
  261. spNodeM->SetVisibilityState(TFS_VIS_SHOW);
  262. pNode->AddChild(spNodeM);
  263. }
  264. else
  265. {
  266. //create a summary node
  267. if (!m_spStatusNode) // changed by Wei Jiang !m_bExpanded)
  268. {
  269. pStatusHandler = new DomainStatusHandler(m_spTFSCompData);
  270. Assert(pStatusHandler);
  271. m_pStatusHandler = pStatusHandler;
  272. spStatusHandler.Set(spHandler);
  273. CORg( pStatusHandler->Init(&m_ConfigStream, &m_serverlist) );
  274. if(!spSummaryNodeRefresh)
  275. GetSummaryNodeRefreshObject(&spSummaryNodeRefresh);
  276. if((RouterRefreshObject*)spSummaryNodeRefresh)
  277. CORg(pStatusHandler->SetExternalRefreshObject(spSummaryNodeRefresh));
  278. spHandler = pStatusHandler;
  279. CORg( CreateContainerTFSNode(&spNodeS,
  280. &GUID_DVSServerNodeType,
  281. static_cast<ITFSNodeHandler *>(pStatusHandler),
  282. static_cast<ITFSResultHandler *>(pStatusHandler),
  283. m_spNodeMgr) );
  284. Assert(spNodeS);
  285. m_spStatusNode.Set(spNodeS);
  286. // Call to the node handler to init the node data
  287. pStatusHandler->ConstructNode(spNodeS);
  288. // Make the node immediately visible
  289. spNodeS->SetVisibilityState(TFS_VIS_SHOW);
  290. pNode->AddChild(spNodeS);
  291. spHandler.Release();
  292. }
  293. else
  294. {
  295. spNodeS.Set(m_spStatusNode);
  296. spNodeS->GetHandler(&spStatusHandler);
  297. }
  298. // iterate the lazy list looking for machine nodes to create
  299. for (itor = m_serverlist.m_listServerNodesToExpand.begin();
  300. itor != m_serverlist.m_listServerNodesToExpand.end() ;
  301. itor++ )
  302. {
  303. pMachineData = *itor;
  304. //create a machine handler
  305. pHandler = new MachineHandler(m_spTFSCompData);
  306. // Do this so that it will get released correctly
  307. spHandler.Release();
  308. spHandler = pHandler;
  309. CORg(pHandler->Init(pMachineData->m_stMachineName,
  310. NULL, spStatusHandler, spNodeS));
  311. if(!(IRouterRefresh*)spServerNodesRefresh)
  312. GetServerNodesRefreshObject(&spServerNodesRefresh);
  313. if((IRouterRefresh*)spServerNodesRefresh)
  314. CORg(pHandler->SetExternalRefreshObject(spServerNodesRefresh));
  315. // Create the root node for this sick puppy
  316. CORg( CreateContainerTFSNode(&spNodeM,
  317. &GUID_RouterMachineNodeType,
  318. pHandler,
  319. pHandler /* result handler */,
  320. m_spNodeMgr) );
  321. Assert(spNodeM);
  322. spNodeM->SetData(TFS_DATA_COOKIE, (LONG_PTR)(ITFSNode*)spNodeM);
  323. // if the machine is local, then find the name,
  324. // but not change the name on the list
  325. // so, when persist the list, empty string will be persisted
  326. //
  327. // This is incorrect. For the local machine case, we
  328. // expect the NULL string to be passed down. It should
  329. // be transparent to this layer whether the machine is
  330. // local or not.
  331. // ----------------------------------------------------
  332. if (pMachineData && pMachineData->m_stMachineName.GetLength() != 0)
  333. stMachineName = pMachineData->m_stMachineName;
  334. else
  335. stMachineName.Empty();
  336. CORg( pHandler->ConstructNode(spNodeM, stMachineName, pMachineData) );
  337. // Make the node immediately visible
  338. spNodeM->SetVisibilityState(TFS_VIS_SHOW);
  339. pNode->AddChild(spNodeM);
  340. spNodeM.Release();
  341. }
  342. // Now that we've gone through the entire list, we have
  343. // to release the objects.
  344. m_serverlist.RemoveAllServerNodes();
  345. Assert(m_serverlist.m_listServerNodesToExpand.size() == 0);
  346. }
  347. COM_PROTECT_ERROR_LABEL;
  348. }
  349. COM_PROTECT_CATCH;
  350. m_bExpanded = true;
  351. return hr;
  352. }
  353. /*!--------------------------------------------------------------------------
  354. DMVRootHandler::OnCreateDataObject
  355. Implementation of ITFSNodeHandler::OnCreateDataObject
  356. Author: KennT
  357. ---------------------------------------------------------------------------*/
  358. STDMETHODIMP DMVRootHandler::OnCreateDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, IDataObject **ppDataObject)
  359. {
  360. HRESULT hr = hrOK;
  361. COM_PROTECT_TRY
  362. {
  363. // If we haven't created the sub nodes yet, we still have to
  364. // create a dataobject.
  365. CDataObject * pObject = NULL;
  366. SPIDataObject spDataObject;
  367. SPITFSNode spNode;
  368. SPITFSNodeHandler spHandler;
  369. pObject = new CDataObject;
  370. spDataObject = pObject; // do this so that it gets released correctly
  371. Assert(pObject != NULL);
  372. // Save cookie and type for delayed rendering
  373. pObject->SetType(type);
  374. pObject->SetCookie(cookie);
  375. // Store the coclass with the data object
  376. pObject->SetClsid(*(m_spTFSCompData->GetCoClassID()));
  377. pObject->SetTFSComponentData(m_spTFSCompData);
  378. hr = pObject->QueryInterface(IID_IDataObject,
  379. reinterpret_cast<void**>(ppDataObject));
  380. }
  381. COM_PROTECT_CATCH;
  382. return hr;
  383. }
  384. // ImplementEmbeddedUnknown(ATLKRootHandler, IRtrAdviseSink)
  385. /*!--------------------------------------------------------------------------
  386. DMVRootHandler::DestroyHandler
  387. -
  388. Author: KennT
  389. ---------------------------------------------------------------------------*/
  390. STDMETHODIMP DMVRootHandler::DestroyHandler(ITFSNode *pNode)
  391. {
  392. m_ulConnId = 0;
  393. return hrOK;
  394. }
  395. /*!--------------------------------------------------------------------------
  396. DMVRootHandler::HasPropertyPages
  397. Implementation of ITFSNodeHandler::HasPropertyPages
  398. NOTE: the root node handler has to over-ride this function to
  399. handle the snapin manager property page (wizard) case!!!
  400. Author: KennT
  401. ---------------------------------------------------------------------------*/
  402. STDMETHODIMP
  403. DMVRootHandler::HasPropertyPages
  404. (
  405. ITFSNode * pNode,
  406. LPDATAOBJECT pDataObject,
  407. DATA_OBJECT_TYPES type,
  408. DWORD dwType
  409. )
  410. {
  411. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  412. return S_FALSE;
  413. HRESULT hr = hrOK;
  414. if ( dwType & TFS_COMPDATA_CREATE )
  415. {
  416. // This is the case where we are asked to bring up property
  417. // pages when the user is adding a new snapin. These calls
  418. // are forwarded to the root node to handle.
  419. //
  420. // We do have a property page on startup.
  421. hr = hrOK;
  422. }
  423. else
  424. {
  425. hr = S_FALSE;
  426. }
  427. return hr;
  428. }
  429. /*!--------------------------------------------------------------------------
  430. DMVRootHandler::CreatePropertyPages
  431. Implementation of ITFSNodeHandler::CreatePropertyPages
  432. Author: KennT
  433. ---------------------------------------------------------------------------*/
  434. STDMETHODIMP
  435. DMVRootHandler::CreatePropertyPages(
  436. ITFSNode * pNode,
  437. LPPROPERTYSHEETCALLBACK lpProvider,
  438. LPDATAOBJECT pDataObject,
  439. LONG_PTR handle,
  440. DWORD dwType
  441. )
  442. {
  443. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  444. HRESULT hr = hrOK;
  445. HPROPSHEETPAGE hPage;
  446. Assert(pNode->GetData(TFS_DATA_COOKIE) == 0);
  447. return hr;
  448. }
  449. /*!--------------------------------------------------------------------------
  450. DMVRootHandler::GetString
  451. ---------------------------------------------------------------------------*/
  452. STDMETHODIMP_(LPCTSTR) DMVRootHandler::GetString(ITFSNode *pNode, int nCol)
  453. {
  454. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  455. static CString str;
  456. if ( m_strDomainName.GetLength() == 0 )
  457. {
  458. if ( str.GetLength() == 0 )
  459. str.LoadString(IDS_DMV_NODENAME_ROOT);
  460. return (LPCTSTR)str;
  461. }
  462. else
  463. return (LPCTSTR) m_strDomainName;
  464. }
  465. /*---------------------------------------------------------------------------
  466. Menu data structure for our menus
  467. ---------------------------------------------------------------------------*/
  468. static const SRouterNodeMenu s_rgDMVNodeMenu[] =
  469. {
  470. // Add items that go on the top menu here
  471. { IDS_DMV_MENU_ADDSVR, 0,
  472. CCM_INSERTIONPOINTID_PRIMARY_TOP},
  473. { IDS_MENU_SEPARATOR, 0,
  474. CCM_INSERTIONPOINTID_PRIMARY_TOP },
  475. { IDS_MENU_AUTO_REFRESH, DMVRootHandler::GetAutoRefreshFlags,
  476. CCM_INSERTIONPOINTID_PRIMARY_TOP },
  477. { IDS_MENU_REFRESH_RATE, DMVRootHandler::GetAutoRefreshFlags,
  478. CCM_INSERTIONPOINTID_PRIMARY_TOP },
  479. };
  480. ULONG DMVRootHandler::GetAutoRefreshFlags(const SRouterNodeMenu *pMenuData,
  481. INT_PTR pUserData)
  482. {
  483. SMenuData * pData = reinterpret_cast<SMenuData *>(pUserData);
  484. Assert(pData);
  485. ULONG uStatus = MF_GRAYED;
  486. SPIRouterRefresh spRefresh;
  487. pData->m_pDMVRootHandler->GetServerNodesRefreshObject(&spRefresh);
  488. if ((IRouterRefresh*)spRefresh)
  489. {
  490. uStatus = MF_ENABLED;
  491. if (pMenuData->m_sidMenu == IDS_MENU_AUTO_REFRESH && (spRefresh->IsRefreshStarted() == hrOK))
  492. {
  493. uStatus |= MF_CHECKED;
  494. }
  495. }
  496. return uStatus;
  497. }
  498. /*!--------------------------------------------------------------------------
  499. DomainStatusHandler::OnAddMenuItems
  500. Implementation of ITFSNodeHandler::OnAddMenuItems
  501. Author: KennT
  502. ---------------------------------------------------------------------------*/
  503. STDMETHODIMP DMVRootHandler::OnAddMenuItems(
  504. ITFSNode *pNode,
  505. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  506. LPDATAOBJECT lpDataObject,
  507. DATA_OBJECT_TYPES type,
  508. DWORD dwType,
  509. long *pInsertionAllowed)
  510. {
  511. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  512. HRESULT hr = S_OK;
  513. DMVRootHandler::SMenuData menuData;
  514. COM_PROTECT_TRY
  515. {
  516. menuData.m_spNode.Set(pNode);
  517. menuData.m_pDMVRootHandler = this; // non-AddRef'd !
  518. // Uncomment if you have items to add
  519. hr = AddArrayOfMenuItems(pNode, s_rgDMVNodeMenu,
  520. DimensionOf(s_rgDMVNodeMenu),
  521. pContextMenuCallback,
  522. *pInsertionAllowed,
  523. reinterpret_cast<INT_PTR>(&menuData));
  524. }
  525. COM_PROTECT_CATCH;
  526. return hr;
  527. }
  528. /*!--------------------------------------------------------------------------
  529. DMVRootHandler::QryAddServer
  530. ---------------------------------------------------------------------------*/
  531. HRESULT DMVRootHandler::QryAddServer(ITFSNode *pNode)
  532. {
  533. HRESULT hr = S_OK;
  534. DWORD dw=0;
  535. POSITION pos;
  536. CString szServer;
  537. RRASQryData qd;
  538. qd.dwCatFlag=RRAS_QRY_CAT_NONE;
  539. CWaitCursor wait;
  540. COM_PROTECT_TRY
  541. {
  542. if ( FHrSucceeded(hr=::RRASOpenQryDlg(NULL,qd)) )
  543. {
  544. if ( (hr!=S_OK) || (qd.dwCatFlag==RRAS_QRY_CAT_NONE) )
  545. return hr;
  546. if (qd.dwCatFlag==RRAS_QRY_CAT_MACHINE || qd.dwCatFlag == RRAS_QRY_CAT_THIS )
  547. { //specific machine query; add to array
  548. m_ConfigStream.m_RQPersist.add_Qry(qd);
  549. }
  550. else
  551. { //position 0 is the non-machine singleton query
  552. RRASQryData& qdGen=*(m_ConfigStream.m_RQPersist.m_v_pQData[0]);
  553. if (!( (qdGen.dwCatFlag==qd.dwCatFlag) &&
  554. (qdGen.strScope=qd.strScope) &&
  555. (qdGen.strFilter=qd.strFilter) ))
  556. {
  557. qdGen.dwCatFlag=qd.dwCatFlag;
  558. qdGen.strScope=qd.strScope;
  559. qdGen.strFilter=qd.strFilter;
  560. }
  561. }
  562. CStringArray sa;
  563. ::RRASExecQry(qd, dw, sa);
  564. //if there is only one server selected, select it
  565. hr = AddServersToList(sa,pNode);
  566. if ( S_OK == hr && (qd.dwCatFlag==RRAS_QRY_CAT_MACHINE || qd.dwCatFlag == RRAS_QRY_CAT_THIS ))
  567. {
  568. //select the scope item...
  569. //create a background thread to select the current node?
  570. //this sucks...
  571. //it really does...
  572. }
  573. }
  574. else
  575. {
  576. AfxMessageBox(IDS_DVS_DOMAINVIEWQRY);
  577. }
  578. }
  579. COM_PROTECT_CATCH;
  580. return hr;
  581. }
  582. HRESULT DMVRootHandler::ExecServerQry(ITFSNode* pNode)
  583. {
  584. HRESULT hr = S_OK;
  585. DWORD dw=0;
  586. CString szServer;
  587. SPITFSNode spParent;
  588. CStringArray sa;
  589. COM_PROTECT_TRY
  590. {
  591. for (int i=0;i<m_ConfigStream.m_RQPersist.m_v_pQData.size(); i++ )
  592. {
  593. RRASQryData& QData=*(m_ConfigStream.m_RQPersist.m_v_pQData[i]);
  594. if (QData.dwCatFlag==RRAS_QRY_CAT_NONE)
  595. continue;
  596. sa.RemoveAll();
  597. hr=::RRASExecQry(QData, dw, sa);
  598. if (!FHrSucceeded(hr))
  599. {
  600. TRACE0("RRASExexQry failed for this query\n");
  601. continue;
  602. }
  603. hr = AddServersToList(sa, pNode);
  604. if (! FHrSucceeded(hr) )
  605. AfxMessageBox(IDS_DVS_DOMAINVIEWQRY);
  606. }
  607. }
  608. COM_PROTECT_CATCH;
  609. return hr;
  610. }
  611. #define ___CAN_NOT_PUT_LOCAL_MACHINE_BY_NAME_AFTER_PUT_IN_LOCAL_
  612. /*!--------------------------------------------------------------------------
  613. DMVRootHandler::AddServersToList
  614. -
  615. Author: KennT
  616. ---------------------------------------------------------------------------*/
  617. HRESULT DMVRootHandler::AddServersToList(const CStringArray& sa, ITFSNode *pNode)
  618. {
  619. HRESULT hr = S_OK;
  620. bool found;
  621. SPITFSNodeEnum spNodeEnum;
  622. SPITFSNode spNode;
  623. MachineNodeData *pMachineData = NULL;
  624. // check for duplicate servernames
  625. for (int j = 0; j < sa.GetSize(); j++)
  626. {
  627. found=false;
  628. // Go through the list of nodes and check for nodes with
  629. // the same server name.
  630. spNodeEnum.Release();
  631. CORg( pNode->GetEnum(&spNodeEnum) );
  632. while ( spNodeEnum->Next(1, &spNode, NULL) == hrOK)
  633. {
  634. // Now get the data for this node (need to see if this is
  635. // a machine node).
  636. if (*(spNode->GetNodeType()) == GUID_DVSServerNodeType || *(spNode->GetNodeType()) == GUID_RouterMachineNodeType )
  637. {
  638. /*
  639. DMVNodeData * pData = GET_DMVNODEDATA( spNode );
  640. Assert(pData);
  641. pMachineData = pData->m_spMachineData;
  642. */
  643. pMachineData = GET_MACHINENODEDATA(spNode);
  644. Assert(pMachineData);
  645. #ifdef ___CAN_NOT_PUT_LOCAL_MACHINE_BY_NAME_AFTER_PUT_IN_LOCAL_
  646. if (pMachineData->m_stMachineName.CompareNoCase(sa[j]) == 0 || (pMachineData->m_fLocalMachine && sa[j].IsEmpty()))
  647. #else
  648. if ((pMachineData->m_stMachineName.CompareNoCase(sa[j]) == 0 && !pMachineData->m_fAddedAsLocal)
  649. || (pMachineData->m_fAddedAsLocal && sa[j].IsEmpty()))
  650. #endif
  651. {
  652. found = true;
  653. break;
  654. }
  655. }
  656. spNode.Release();
  657. }
  658. if (!found)
  659. {
  660. // add to working serverlist
  661. m_serverlist.AddServer(sa[j]);
  662. }
  663. }
  664. Error:
  665. // this causes the unexpanded server lists to be processed
  666. hr = OnExpand(pNode, NULL, 0, 0, 0 );
  667. if (hr == S_OK && m_spStatusNode && m_pStatusHandler)
  668. hr = m_pStatusHandler->OnExpand(m_spStatusNode, NULL, 0, 0, 0 );
  669. return hr;
  670. }
  671. /*!--------------------------------------------------------------------------
  672. DMVRootHandler::LoadPeristedServerList
  673. Adds the list of persisted servers to the list of
  674. servers to be added to the UI.
  675. Author: KennT
  676. ---------------------------------------------------------------------------*/
  677. HRESULT DMVRootHandler::LoadPersistedServerList()
  678. {
  679. HRESULT hr = S_OK;
  680. COM_PROTECT_TRY
  681. {
  682. if ( m_ConfigStream.m_RQPersist.m_v_pSData.size() > 0 )
  683. m_serverlist.removeall();
  684. for (int i=0;i<m_ConfigStream.m_RQPersist.m_v_pSData.size(); i++ )
  685. {
  686. m_serverlist.AddServer( *(m_ConfigStream.m_RQPersist.m_v_pSData[i]) );
  687. }
  688. }
  689. COM_PROTECT_CATCH;
  690. return hr;
  691. }
  692. /*!--------------------------------------------------------------------------
  693. DMVRootHandler::LoadPersistedServerListFromNode
  694. Reloads the persisted server list.
  695. Author: KennT
  696. ---------------------------------------------------------------------------*/
  697. HRESULT DMVRootHandler::LoadPersistedServerListFromNode()
  698. {
  699. HRESULT hr = S_OK;
  700. SPITFSNodeEnum spNodeEnum;
  701. SPITFSNode spNode;
  702. SPITFSNode spRootNode;
  703. MachineNodeData *pMachineData = NULL;
  704. COM_PROTECT_TRY
  705. {
  706. // Remove all servers from the of persisted list of servers
  707. m_ConfigStream.m_RQPersist.removeAllSrv();
  708. CORg(m_spNodeMgr->GetRootNode(&spRootNode));
  709. // replace with above (weijiang) -- using NodeMgr
  710. //CORg( m_spStatusNode->GetParent(&spRootNode) );
  711. // Go through the list of nodes and check for nodes with
  712. // the same server name.
  713. CORg( spRootNode->GetEnum(&spNodeEnum) );
  714. while ( spNodeEnum->Next(1, &spNode, NULL) == hrOK)
  715. {
  716. // Now get the data for this node (need to see if this is
  717. // a machine node).
  718. if (*(spNode->GetNodeType()) == GUID_RouterMachineNodeType)
  719. {
  720. //DMVNodeData * pData = GET_DMVNODEDATA( spNode );
  721. //Assert(pData);
  722. //pMachineData = pData->m_spMachineData;
  723. pMachineData = GET_MACHINENODEDATA(spNode);
  724. Assert(pMachineData);
  725. CString str;
  726. if(!pMachineData->m_fAddedAsLocal)
  727. str = pMachineData->m_stMachineName;
  728. m_ConfigStream.m_RQPersist.add_Srv( str );
  729. }
  730. spNode.Release();
  731. }
  732. COM_PROTECT_ERROR_LABEL;
  733. }
  734. COM_PROTECT_CATCH;
  735. return hr;
  736. }
  737. /*!--------------------------------------------------------------------------
  738. DMVRootHandler::OnCommand
  739. ---------------------------------------------------------------------------*/
  740. STDMETHODIMP DMVRootHandler::OnCommand(ITFSNode *pNode, long nCommandId,
  741. DATA_OBJECT_TYPES type,
  742. LPDATAOBJECT pDataObject,
  743. DWORD dwType)
  744. {
  745. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  746. HRESULT hr = S_OK;
  747. RegKey regkey;
  748. COM_PROTECT_TRY
  749. {
  750. switch ( nCommandId )
  751. {
  752. case IDS_DMV_MENU_ADDSVR:
  753. Assert( pNode);
  754. QryAddServer( pNode );
  755. break;
  756. case IDS_DMV_MENU_REBUILDSVRLIST:
  757. m_serverlist.removeall();
  758. m_spStatusNode.Release(); // wei Jiang
  759. // delete all the other nodes
  760. CORg(pNode->DeleteAllChildren(TRUE));
  761. ExecServerQry( pNode);
  762. GetConfigStream()->SetDirty(TRUE);
  763. break;
  764. case IDS_MENU_REFRESH_RATE:
  765. {
  766. CRefRateDlg refrate;
  767. SPIRouterRefresh spServerRefresh;
  768. SPRouterRefreshObject spStatusRefresh;
  769. DWORD rate;
  770. if(FAILED(GetServerNodesRefreshObject(&spServerRefresh)))
  771. break;
  772. if(!spServerRefresh)
  773. break;
  774. spServerRefresh->GetRefreshInterval(&rate);
  775. refrate.m_cRefRate = rate;
  776. if (refrate.DoModal() == IDOK)
  777. {
  778. spServerRefresh->SetRefreshInterval(refrate.m_cRefRate);
  779. // Summary Node
  780. if(FAILED(GetSummaryNodeRefreshObject(&spStatusRefresh)))
  781. break;
  782. if(!spStatusRefresh)
  783. break;
  784. spStatusRefresh->SetRefreshInterval(refrate.m_cRefRate);
  785. }
  786. GetConfigStream()->SetDirty(TRUE);
  787. }
  788. break;
  789. case IDS_MENU_AUTO_REFRESH:
  790. {
  791. SPIRouterRefresh spServerRefresh;
  792. SPRouterRefreshObject spStatusRefresh;
  793. if(FAILED(GetServerNodesRefreshObject(&spServerRefresh)))
  794. break;
  795. if(!spServerRefresh)
  796. break;
  797. if (spServerRefresh->IsRefreshStarted() == hrOK)
  798. spServerRefresh->Stop();
  799. else
  800. {
  801. DWORD rate;
  802. spServerRefresh->GetRefreshInterval(&rate);
  803. spServerRefresh->Start(rate);
  804. }
  805. // Summary Node
  806. if(FAILED(GetSummaryNodeRefreshObject(&spStatusRefresh)))
  807. break;
  808. if(!spStatusRefresh)
  809. break;
  810. if (spStatusRefresh->IsRefreshStarted() == hrOK)
  811. spStatusRefresh->Stop();
  812. else
  813. {
  814. DWORD rate;
  815. spStatusRefresh->GetRefreshInterval(&rate);
  816. spStatusRefresh->Start(rate);
  817. }
  818. GetConfigStream()->SetDirty(TRUE);
  819. }
  820. break;
  821. }
  822. COM_PROTECT_ERROR_LABEL;
  823. }
  824. COM_PROTECT_CATCH;
  825. return hr;
  826. }
  827. STDMETHODIMP DMVRootHandler::UserNotify(ITFSNode *pNode, LPARAM lParam, LPARAM lParam2)
  828. {
  829. HRESULT hr = hrOK;
  830. COM_PROTECT_TRY
  831. {
  832. switch (lParam)
  833. {
  834. case DMV_DELETE_SERVER_ENTRY:
  835. {
  836. LPCTSTR pszServer = (LPCTSTR) lParam2;
  837. m_serverlist.RemoveServer(pszServer);
  838. }
  839. break;
  840. default:
  841. hr = RootHandler::UserNotify(pNode, lParam, lParam2);
  842. break;
  843. }
  844. }
  845. COM_PROTECT_CATCH;
  846. return hr;
  847. }
  848. HRESULT DMVRootHandler::UpdateAllMachineIcons(ITFSNode* pRootNode)
  849. {
  850. SPITFSNodeEnum spMachineEnum;
  851. SPITFSNode spMachineNode;
  852. SPITFSNodeHandler spNodeHandler;
  853. HRESULT hr = S_OK;
  854. pRootNode->GetEnum(&spMachineEnum);
  855. while(hr == hrOK && spMachineEnum->Next(1, &spMachineNode, NULL) == hrOK)
  856. {
  857. if ((*spMachineNode->GetNodeType()) == GUID_RouterMachineNodeType)
  858. {
  859. spNodeHandler.Release();
  860. spMachineNode->GetHandler(&spNodeHandler);
  861. hr = spNodeHandler->UserNotify(spMachineNode, MACHINE_SYNCHRONIZE_ICON, NULL);
  862. }
  863. spMachineNode.Release();
  864. }
  865. return hr;
  866. }
  867. /*!--------------------------------------------------------------------------
  868. BaseRouterHandler::OnResultContextHelp
  869. -
  870. Author: MikeG (a-migall)
  871. ---------------------------------------------------------------------------*/
  872. HRESULT DMVRootHandler::OnResultContextHelp(ITFSComponent * pComponent,
  873. LPDATAOBJECT pDataObject,
  874. MMC_COOKIE cookie,
  875. LPARAM arg,
  876. LPARAM lParam)
  877. {
  878. // Not used...
  879. UNREFERENCED_PARAMETER(pDataObject);
  880. UNREFERENCED_PARAMETER(cookie);
  881. UNREFERENCED_PARAMETER(arg);
  882. UNREFERENCED_PARAMETER(lParam);
  883. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  884. return HrDisplayHelp(pComponent,
  885. m_spTFSCompData->GetHTMLHelpFileName(),
  886. _T("\\help\\rrasconcepts.chm::/sag_RRAStopnode.htm"));
  887. }
  888. /*!--------------------------------------------------------------------------
  889. DMVRootHandler::AddMenuItems
  890. Over-ride this to add our view menu item
  891. Author: EricDav
  892. ---------------------------------------------------------------------------*/
  893. STDMETHODIMP
  894. DMVRootHandler::AddMenuItems
  895. (
  896. ITFSComponent * pComponent,
  897. MMC_COOKIE cookie,
  898. LPDATAOBJECT pDataObject,
  899. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  900. long * pInsertionAllowed
  901. )
  902. {
  903. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  904. HRESULT hr = S_OK;
  905. SPITFSNode spNode;
  906. m_spNodeMgr->FindNode(cookie, &spNode);
  907. // Call through to the regular OnAddMenuItems
  908. hr = OnAddMenuItems(spNode,
  909. pContextMenuCallback,
  910. pDataObject,
  911. CCT_RESULT,
  912. TFS_COMPDATA_CHILD_CONTEXTMENU,
  913. pInsertionAllowed);
  914. return hr;
  915. }
  916. /*!--------------------------------------------------------------------------
  917. DMVRootHandler::Command
  918. Handles commands for the current view
  919. Author: EricDav
  920. ---------------------------------------------------------------------------*/
  921. STDMETHODIMP
  922. DMVRootHandler::Command
  923. (
  924. ITFSComponent * pComponent,
  925. MMC_COOKIE cookie,
  926. int nCommandID,
  927. LPDATAOBJECT pDataObject
  928. )
  929. {
  930. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  931. HRESULT hr = S_OK;
  932. switch (nCommandID)
  933. {
  934. case MMCC_STANDARD_VIEW_SELECT:
  935. break;
  936. default:
  937. {
  938. SPITFSNode spNode;
  939. m_spNodeMgr->FindNode(cookie, &spNode);
  940. hr = OnCommand(spNode,
  941. nCommandID,
  942. CCT_RESULT,
  943. pDataObject,
  944. TFS_COMPDATA_CHILD_CONTEXTMENU);
  945. }
  946. break;
  947. }
  948. return hr;
  949. }
  950. /*---------------------------------------------------------------------------
  951. DMVRootHandler::OnGetResultViewType
  952. Return the result view that this node is going to support
  953. Author: EricDav
  954. ---------------------------------------------------------------------------*/
  955. HRESULT
  956. DMVRootHandler::OnGetResultViewType
  957. (
  958. ITFSComponent * pComponent,
  959. MMC_COOKIE cookie,
  960. LPOLESTR * ppViewType,
  961. long * pViewOptions
  962. )
  963. {
  964. WCHAR wszURL[MAX_PATH+1] = {0};
  965. WCHAR wszSystemDirectory[MAX_PATH+1] = {0};
  966. GetSystemDirectoryW ( wszSystemDirectory, MAX_PATH);
  967. wsprintf( wszURL, L"res://%s\\mprsnap.dll/welcome.htm", wszSystemDirectory );
  968. //Send the URL back and see what happens
  969. *pViewOptions = MMC_VIEW_OPTIONS_NOLISTVIEWS;
  970. *ppViewType = SysAllocString(wszURL);
  971. return S_OK;
  972. //return BaseRouterHandler::OnGetResultViewType(pComponent, cookie, ppViewType, pViewOptions);
  973. }
  974. /*!--------------------------------------------------------------------------
  975. DMVRootHandler::OnResultSelect
  976. Update the result message here.
  977. Author: EricDav
  978. ---------------------------------------------------------------------------*/
  979. HRESULT DMVRootHandler::OnResultSelect(ITFSComponent *pComponent,
  980. LPDATAOBJECT pDataObject,
  981. MMC_COOKIE cookie,
  982. LPARAM arg,
  983. LPARAM lParam)
  984. {
  985. HRESULT hr = hrOK;
  986. SPITFSNode spRootNode;
  987. CORg(RootHandler::OnResultSelect(pComponent, pDataObject, cookie, arg, lParam));
  988. CORg(m_spNodeMgr->GetRootNode(&spRootNode));
  989. UpdateResultMessage(spRootNode);
  990. Error:
  991. return hr;
  992. }
  993. /*!--------------------------------------------------------------------------
  994. DMVRootHandler::UpdateResultMessage
  995. Determines what (if anything) to put in the result pane message
  996. Author: EricDav
  997. ---------------------------------------------------------------------------*/
  998. void DMVRootHandler::UpdateResultMessage(ITFSNode * pNode)
  999. {
  1000. HRESULT hr = hrOK;
  1001. int nMessage = ROOT_MESSAGE_MAIN; // default
  1002. int i;
  1003. CString strTitle, strBody, strTemp;
  1004. // now build the text strings
  1005. // first entry is the title
  1006. strTitle.LoadString(g_uRootMessages[nMessage][0]);
  1007. // second entry is the icon
  1008. // third ... n entries are the body strings
  1009. for (i = 2; g_uRootMessages[nMessage][i] != 0; i++)
  1010. {
  1011. strTemp.LoadString(g_uRootMessages[nMessage][i]);
  1012. strBody += strTemp;
  1013. }
  1014. ShowMessage(pNode, strTitle, strBody, (IconIdentifier) g_uRootMessages[nMessage][1]);
  1015. }
  1016. //------------------------------------------------------------------------
  1017. // implementation of CServerList
  1018. //------------------------------------------------------------------------
  1019. HRESULT CServerList::AddServer(const CString& servername)
  1020. {
  1021. HRESULT hr=S_OK;
  1022. COM_PROTECT_TRY
  1023. {
  1024. SPMachineNodeData spMachineData;
  1025. spMachineData = new MachineNodeData;
  1026. spMachineData->Init(servername);
  1027. m_listServerNodesToExpand.push_back(spMachineData);
  1028. spMachineData->AddRef();
  1029. m_listServerHandlersToExpand.push_back(spMachineData);
  1030. spMachineData->AddRef();
  1031. }
  1032. COM_PROTECT_CATCH;
  1033. return hr;
  1034. }
  1035. HRESULT CServerList::RemoveServer(LPCTSTR pszServerName)
  1036. {
  1037. HRESULT hr = hrOK;
  1038. COM_PROTECT_TRY
  1039. {
  1040. list< MachineNodeData * >::iterator it;
  1041. MachineNodeData * pData = NULL;
  1042. for (it= m_listServerHandlersToExpand.begin();
  1043. it!= m_listServerHandlersToExpand.end() ; it++ )
  1044. {
  1045. pData = *it;
  1046. }
  1047. if (pData)
  1048. {
  1049. pData->Release();
  1050. m_listServerHandlersToExpand.remove(pData);
  1051. }
  1052. pData = NULL;
  1053. for (it= m_listServerNodesToExpand.begin();
  1054. it!= m_listServerNodesToExpand.end() ; it++ )
  1055. {
  1056. pData = *it;
  1057. }
  1058. if (pData)
  1059. {
  1060. pData->Release();
  1061. m_listServerNodesToExpand.remove(pData);
  1062. }
  1063. }
  1064. COM_PROTECT_CATCH;
  1065. return hr;
  1066. }
  1067. HRESULT CServerList::RemoveAllServerNodes()
  1068. {
  1069. while (!m_listServerNodesToExpand.empty())
  1070. {
  1071. m_listServerNodesToExpand.front()->Release();
  1072. m_listServerNodesToExpand.pop_front();
  1073. }
  1074. return hrOK;
  1075. }
  1076. HRESULT CServerList::RemoveAllServerHandlers()
  1077. {
  1078. while (!m_listServerHandlersToExpand.empty())
  1079. {
  1080. m_listServerHandlersToExpand.front()->Release();
  1081. m_listServerHandlersToExpand.pop_front();
  1082. }
  1083. return hrOK;
  1084. }
  1085. HRESULT CServerList::removeall()
  1086. {
  1087. HRESULT hr=S_OK;
  1088. COM_PROTECT_TRY
  1089. {
  1090. RemoveAllServerNodes();
  1091. RemoveAllServerHandlers();
  1092. }
  1093. COM_PROTECT_CATCH;
  1094. return hr;
  1095. }