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.

1145 lines
32 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. root.cpp
  7. FILE HISTORY:
  8. */
  9. #include "stdafx.h"
  10. #include "root.h"
  11. #include "server.h"
  12. #include "tregkey.h"
  13. #include "service.h"
  14. #include "ncglobal.h" // network console global defines
  15. #include "addserv.h"
  16. unsigned int g_cfMachineName = RegisterClipboardFormat(L"MMC_SNAPIN_MACHINE_NAME");
  17. LPOLESTR g_RootTaskOverBitmaps[ROOT_TASK_MAX] =
  18. {
  19. L"/wlcmroll.bmp",
  20. L"/srvrroll.bmp",
  21. };
  22. LPOLESTR g_RootTaskOffBitmaps[ROOT_TASK_MAX] =
  23. {
  24. L"/wlcm.bmp",
  25. L"/srvr.bmp",
  26. };
  27. UINT g_RootTaskText[ROOT_TASK_MAX] =
  28. {
  29. IDS_ROOT_TASK_GETTING_STARTED,
  30. IDS_ROOT_TASK_ADD_SERVER,
  31. };
  32. UINT g_RootTaskHelp[ROOT_TASK_MAX] =
  33. {
  34. IDS_ROOT_TASK_GETTING_STARTED_HELP,
  35. IDS_ROOT_TASK_ADD_SERVER_HELP,
  36. };
  37. HRESULT
  38. CRootTasks::Init(BOOL bExtension, BOOL bThisMachine, BOOL bNetServices)
  39. {
  40. HRESULT hr = hrOK;
  41. MMC_TASK mmcTask;
  42. int nPos = 0;
  43. int nFinish = ROOT_TASK_MAX;
  44. m_arrayMouseOverBitmaps.SetSize(ROOT_TASK_MAX);
  45. m_arrayMouseOffBitmaps.SetSize(ROOT_TASK_MAX);
  46. m_arrayTaskText.SetSize(ROOT_TASK_MAX);
  47. m_arrayTaskHelp.SetSize(ROOT_TASK_MAX);
  48. // setup path for reuse
  49. OLECHAR szBuffer[MAX_PATH*2]; // that should be enough
  50. lstrcpy (szBuffer, L"res://");
  51. ::GetModuleFileName(_Module.GetModuleInstance(), szBuffer + lstrlen(szBuffer), MAX_PATH);
  52. OLECHAR * temp = szBuffer + lstrlen(szBuffer);
  53. if (bExtension)
  54. nPos = ROOT_TASK_MAX;
  55. /*
  56. if (bExtension && bThisMachine)
  57. {
  58. nPos = ROOT_TASK_MAX - 2;
  59. nFinish = ROOT_TASK_MAX - 1;
  60. }
  61. else
  62. if (bExtension && bNetServices)
  63. {
  64. nPos = ROOT_TASK_MAX - 1;
  65. nFinish = ROOT_TASK_MAX;
  66. }
  67. */
  68. for (nPos; nPos < nFinish; nPos++)
  69. {
  70. m_arrayMouseOverBitmaps[nPos] = szBuffer;
  71. m_arrayMouseOffBitmaps[nPos] = szBuffer;
  72. m_arrayMouseOverBitmaps[nPos] += g_RootTaskOverBitmaps[nPos];
  73. m_arrayMouseOffBitmaps[nPos] += g_RootTaskOffBitmaps[nPos];
  74. m_arrayTaskText[nPos].LoadString(g_RootTaskText[nPos]);
  75. m_arrayTaskHelp[nPos].LoadString(g_RootTaskHelp[nPos]);
  76. AddTask((LPTSTR) (LPCTSTR) m_arrayMouseOverBitmaps[nPos],
  77. (LPTSTR) (LPCTSTR) m_arrayMouseOffBitmaps[nPos],
  78. (LPTSTR) (LPCTSTR) m_arrayTaskText[nPos],
  79. (LPTSTR) (LPCTSTR) m_arrayTaskHelp[nPos],
  80. MMC_ACTION_ID,
  81. nPos);
  82. }
  83. return hr;
  84. }
  85. /*---------------------------------------------------------------------------
  86. CIpsmRootHandler::CIpsmRootHandler
  87. Description
  88. Author: NSun
  89. ---------------------------------------------------------------------------*/
  90. CIpsmRootHandler::CIpsmRootHandler(ITFSComponentData *pCompData) : CIpsmHandler(pCompData)
  91. {
  92. //m_bTaskPadView = FUseTaskpadsByDefault(NULL);
  93. m_bTaskPadView = FALSE;
  94. }
  95. /*!--------------------------------------------------------------------------
  96. CIpsmRootHandler::InitializeNode
  97. Initializes node specific data
  98. Author: NSun
  99. ---------------------------------------------------------------------------*/
  100. HRESULT
  101. CIpsmRootHandler::InitializeNode
  102. (
  103. ITFSNode * pNode
  104. )
  105. {
  106. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  107. CString strTemp;
  108. strTemp.LoadString(IDS_ROOT_NODENAME);
  109. SetDisplayName(strTemp);
  110. // Make the node immediately visible
  111. //pNode->SetVisibilityState(TFS_VIS_SHOW);
  112. pNode->SetData(TFS_DATA_COOKIE, 0);
  113. pNode->SetData(TFS_DATA_IMAGEINDEX, ICON_IDX_PRODUCT);
  114. pNode->SetData(TFS_DATA_OPENIMAGEINDEX, ICON_IDX_PRODUCT);
  115. pNode->SetData(TFS_DATA_USER, (LPARAM) this);
  116. pNode->SetData(TFS_DATA_TYPE, IPSMSNAP_ROOT);
  117. SetColumnStringIDs(&aColumns[IPSMSNAP_ROOT][0]);
  118. SetColumnWidths(&aColumnWidths[IPSMSNAP_ROOT][0]);
  119. m_strTaskpadTitle.LoadString(IDS_ROOT_TASK_TITLE);
  120. return hrOK;
  121. }
  122. /*---------------------------------------------------------------------------
  123. Overridden base handler functions
  124. ---------------------------------------------------------------------------*/
  125. /*!--------------------------------------------------------------------------
  126. CIpsmRootHandler::GetString
  127. Implementation of ITFSNodeHandler::GetString
  128. Author: KennT
  129. ---------------------------------------------------------------------------*/
  130. STDMETHODIMP_(LPCTSTR)
  131. CIpsmRootHandler::GetString
  132. (
  133. ITFSNode * pNode,
  134. int nCol
  135. )
  136. {
  137. if (nCol == 0 || nCol == -1)
  138. return GetDisplayName();
  139. else
  140. return NULL;
  141. }
  142. /*---------------------------------------------------------------------------
  143. CIpsmRootHandler::OnExpand
  144. Handles enumeration of a scope item
  145. Author: NSun
  146. ---------------------------------------------------------------------------*/
  147. HRESULT
  148. CIpsmRootHandler::OnExpand
  149. (
  150. ITFSNode * pNode,
  151. LPDATAOBJECT pDataObject,
  152. DWORD dwType,
  153. LPARAM arg,
  154. LPARAM param
  155. )
  156. {
  157. HRESULT hr = hrOK;
  158. if (m_bExpanded)
  159. return hr;
  160. // do the default handling
  161. hr = CIpsmHandler::OnExpand(pNode, pDataObject, dwType, arg, param);
  162. if (dwType & TFS_COMPDATA_EXTENSION)
  163. {
  164. // we are extending somebody. Get the computer name and check that machine
  165. hr = CheckMachine(pNode, pDataObject);
  166. }
  167. else
  168. {
  169. int iVisibleCount = 0;
  170. int iTotalCount = 0;
  171. pNode->GetChildCount(&iVisibleCount, &iTotalCount);
  172. if (0 == iTotalCount)
  173. {
  174. // check to see if we need to add the local machine to the list
  175. hr = CheckMachine(pNode, NULL);
  176. }
  177. }
  178. return hr;
  179. }
  180. /*---------------------------------------------------------------------------
  181. CIpsmRootHandler::OnAddMenuItems
  182. Description
  183. Author: NSun
  184. ---------------------------------------------------------------------------*/
  185. STDMETHODIMP
  186. CIpsmRootHandler::OnAddMenuItems
  187. (
  188. ITFSNode * pNode,
  189. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  190. LPDATAOBJECT lpDataObject,
  191. DATA_OBJECT_TYPES type,
  192. DWORD dwType,
  193. long * pInsertionAllowed
  194. )
  195. {
  196. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  197. HRESULT hr = S_OK;
  198. CString strMenuItem;
  199. if (type == CCT_SCOPE)
  200. {
  201. // these menu items go in the new menu,
  202. // only visible from scope pane
  203. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP)
  204. {
  205. strMenuItem.LoadString(IDS_ADD_MACHINE);
  206. hr = LoadAndAddMenuItem( pContextMenuCallback,
  207. strMenuItem,
  208. IDS_ADD_MACHINE,
  209. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  210. 0 );
  211. ASSERT( SUCCEEDED(hr) );
  212. }
  213. }
  214. return hr;
  215. }
  216. /*---------------------------------------------------------------------------
  217. CIpsmRootHandler::OnCommand
  218. Description
  219. Author: NSun
  220. ---------------------------------------------------------------------------*/
  221. STDMETHODIMP
  222. CIpsmRootHandler::OnCommand
  223. (
  224. ITFSNode * pNode,
  225. long nCommandId,
  226. DATA_OBJECT_TYPES type,
  227. LPDATAOBJECT pDataObject,
  228. DWORD dwType
  229. )
  230. {
  231. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  232. HRESULT hr = S_OK;
  233. switch (nCommandId)
  234. {
  235. case IDS_ADD_MACHINE:
  236. OnAddMachine(pNode);
  237. break;
  238. default:
  239. break;
  240. }
  241. return hr;
  242. }
  243. /*!--------------------------------------------------------------------------
  244. CIpsmRootHandler::AddMenuItems
  245. Over-ride this to add our view menu item
  246. Author: NSun
  247. ---------------------------------------------------------------------------*/
  248. STDMETHODIMP
  249. CIpsmRootHandler::AddMenuItems
  250. (
  251. ITFSComponent * pComponent,
  252. MMC_COOKIE cookie,
  253. LPDATAOBJECT pDataObject,
  254. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  255. long * pInsertionAllowed
  256. )
  257. {
  258. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  259. HRESULT hr = S_OK;
  260. CString strMenuItem;
  261. /*
  262. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_VIEW)
  263. {
  264. strMenuItem.LoadString(IDS_VIEW_TASKPAD);
  265. hr = LoadAndAddMenuItem( pContextMenuCallback,
  266. strMenuItem,
  267. IDS_VIEW_TASKPAD,
  268. CCM_INSERTIONPOINTID_PRIMARY_VIEW,
  269. (m_bTaskPadView) ? MF_CHECKED : 0 );
  270. }
  271. */
  272. return hr;
  273. }
  274. /*!--------------------------------------------------------------------------
  275. CIpsmRootHandler::Command
  276. Handles commands for the current view
  277. Author: NSun
  278. ---------------------------------------------------------------------------*/
  279. STDMETHODIMP
  280. CIpsmRootHandler::Command
  281. (
  282. ITFSComponent * pComponent,
  283. MMC_COOKIE cookie,
  284. int nCommandID,
  285. LPDATAOBJECT pDataObject
  286. )
  287. {
  288. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  289. HRESULT hr = S_OK;
  290. switch (nCommandID)
  291. {
  292. case MMCC_STANDARD_VIEW_SELECT:
  293. m_bTaskPadView = FALSE;
  294. break;
  295. case IDS_VIEW_TASKPAD:
  296. {
  297. // if we are not viewing the taskpad presently, re-select the node
  298. // so that the taskpad is visible
  299. SPIConsole spConsole;
  300. SPITFSNode spNode;
  301. m_bTaskPadView = !m_bTaskPadView;
  302. m_spResultNodeMgr->FindNode(cookie, &spNode);
  303. m_spTFSCompData->GetConsole(&spConsole);
  304. spConsole->SelectScopeItem(spNode->GetData(TFS_DATA_SCOPEID));
  305. }
  306. break;
  307. }
  308. return hr;
  309. }
  310. /*!--------------------------------------------------------------------------
  311. CIpsmRootHandler::HasPropertyPages
  312. Implementation of ITFSNodeHandler::HasPropertyPages
  313. NOTE: the root node handler has to over-ride this function to
  314. handle the snapin manager property page (wizard) case!!!
  315. Author: KennT
  316. ---------------------------------------------------------------------------*/
  317. STDMETHODIMP
  318. CIpsmRootHandler::HasPropertyPages
  319. (
  320. ITFSNode * pNode,
  321. LPDATAOBJECT pDataObject,
  322. DATA_OBJECT_TYPES type,
  323. DWORD dwType
  324. )
  325. {
  326. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  327. HRESULT hr = hrOK;
  328. if (dwType & TFS_COMPDATA_CREATE)
  329. {
  330. // This is the case where we are asked to bring up property
  331. // pages when the user is adding a new snapin. These calls
  332. // are forwarded to the root node to handle.
  333. hr = hrFalse;
  334. }
  335. else
  336. {
  337. // we have property pages in the normal case
  338. hr = hrFalse;
  339. }
  340. return hr;
  341. }
  342. /*---------------------------------------------------------------------------
  343. CIpsmRootHandler::CreatePropertyPages
  344. Description
  345. Author: NSun
  346. ---------------------------------------------------------------------------*/
  347. STDMETHODIMP
  348. CIpsmRootHandler::CreatePropertyPages
  349. (
  350. ITFSNode * pNode,
  351. LPPROPERTYSHEETCALLBACK lpProvider,
  352. LPDATAOBJECT pDataObject,
  353. LONG_PTR handle,
  354. DWORD dwType
  355. )
  356. {
  357. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  358. HRESULT hr = hrOK;
  359. HPROPSHEETPAGE hPage;
  360. Assert(pNode->GetData(TFS_DATA_COOKIE) == 0);
  361. if (dwType & TFS_COMPDATA_CREATE)
  362. {
  363. //
  364. // We are loading this snapin for the first time, put up a property
  365. // page to allow them to name this thing.
  366. //
  367. }
  368. else
  369. {
  370. //
  371. // Object gets deleted when the page is destroyed
  372. //
  373. }
  374. return hr;
  375. }
  376. /*---------------------------------------------------------------------------
  377. CIpsmRootHandler::OnPropertyChange
  378. Description
  379. Author: NSun
  380. ---------------------------------------------------------------------------*/
  381. HRESULT
  382. CIpsmRootHandler::OnPropertyChange
  383. (
  384. ITFSNode * pNode,
  385. LPDATAOBJECT pDataobject,
  386. DWORD dwType,
  387. LPARAM arg,
  388. LPARAM lParam
  389. )
  390. {
  391. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  392. return hrOK;
  393. }
  394. /*!--------------------------------------------------------------------------
  395. CIpsmRootHandler::TaskPadNotify
  396. -
  397. Author: NSun
  398. ---------------------------------------------------------------------------*/
  399. STDMETHODIMP
  400. CIpsmRootHandler::TaskPadNotify
  401. (
  402. ITFSComponent * pComponent,
  403. MMC_COOKIE cookie,
  404. LPDATAOBJECT pDataObject,
  405. VARIANT * arg,
  406. VARIANT * param
  407. )
  408. {
  409. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  410. if (arg->vt == VT_I4)
  411. {
  412. switch (arg->lVal)
  413. {
  414. case ROOT_TASK_GETTING_STARTED:
  415. {
  416. SPIDisplayHelp spDisplayHelp;
  417. SPIConsole spConsole;
  418. pComponent->GetConsole(&spConsole);
  419. HRESULT hr = spConsole->QueryInterface (IID_IDisplayHelp, (LPVOID*) &spDisplayHelp);
  420. ASSERT (SUCCEEDED (hr));
  421. if ( SUCCEEDED (hr) )
  422. {
  423. LPCTSTR pszHelpFile = m_spTFSCompData->GetHTMLHelpFileName();
  424. if (pszHelpFile == NULL)
  425. break;
  426. CString szHelpFilePath;
  427. UINT nLen = ::GetWindowsDirectory (szHelpFilePath.GetBufferSetLength(2 * MAX_PATH), 2 * MAX_PATH);
  428. if (nLen == 0)
  429. return E_FAIL;
  430. szHelpFilePath.ReleaseBuffer();
  431. szHelpFilePath += g_szDefaultHelpTopic;
  432. hr = spDisplayHelp->ShowTopic (T2OLE ((LPTSTR)(LPCTSTR) szHelpFilePath));
  433. ASSERT (SUCCEEDED (hr));
  434. }
  435. }
  436. break;
  437. case ROOT_TASK_ADD_SERVER:
  438. {
  439. SPITFSNode spNode;
  440. m_spResultNodeMgr->FindNode(cookie, &spNode);
  441. OnAddMachine(spNode);
  442. }
  443. break;
  444. default:
  445. Panic1("CIpsmRootHandler::TaskPadNotify - Unrecognized command! %d", arg->lVal);
  446. break;
  447. }
  448. }
  449. return hrOK;
  450. }
  451. /*!--------------------------------------------------------------------------
  452. CBaseResultHandler::EnumTasks
  453. -
  454. Author: NSun
  455. ---------------------------------------------------------------------------*/
  456. STDMETHODIMP
  457. CIpsmRootHandler::EnumTasks
  458. (
  459. ITFSComponent * pComponent,
  460. MMC_COOKIE cookie,
  461. LPDATAOBJECT pDataObject,
  462. LPOLESTR pszTaskGroup,
  463. IEnumTASK ** ppEnumTask
  464. )
  465. {
  466. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  467. HRESULT hr = hrOK;
  468. CRootTasks * pTasks = NULL;
  469. SPIEnumTask spEnumTasks;
  470. SPINTERNAL spInternal = ExtractInternalFormat(pDataObject);
  471. BOOL bExtension = FALSE;
  472. BOOL bAddThisMachineTasks = FALSE;
  473. BOOL bAddNetServicesTasks = FALSE;
  474. const CLSID * pNodeClsid = &CLSID_IpsmSnapin;
  475. CString strMachineGroup = NETCONS_ROOT_THIS_MACHINE;
  476. CString strNetServicesGroup = NETCONS_ROOT_NET_SERVICES;
  477. if ((spInternal == NULL) || (*pNodeClsid != spInternal->m_clsid))
  478. bExtension = TRUE;
  479. if (bExtension &&
  480. strMachineGroup.CompareNoCase(pszTaskGroup) == 0)
  481. {
  482. // There are multiple taskpad groups in the network console
  483. // we need to make sure we are extending the correct one.
  484. bAddThisMachineTasks = TRUE;
  485. }
  486. if (bExtension &&
  487. strNetServicesGroup.CompareNoCase(pszTaskGroup) == 0)
  488. {
  489. // There are multiple taskpad groups in the network console
  490. // we need to make sure we are extending the correct one.
  491. bAddNetServicesTasks = TRUE;
  492. }
  493. COM_PROTECT_TRY
  494. {
  495. pTasks = new CRootTasks();
  496. spEnumTasks = pTasks;
  497. if (!(bExtension && !bAddThisMachineTasks && !bAddNetServicesTasks))
  498. CORg (pTasks->Init(bExtension, bAddThisMachineTasks, bAddNetServicesTasks));
  499. CORg (pTasks->QueryInterface (IID_IEnumTASK, (void **)ppEnumTask));
  500. COM_PROTECT_ERROR_LABEL;
  501. }
  502. COM_PROTECT_CATCH
  503. return hr;
  504. }
  505. /*!--------------------------------------------------------------------------
  506. CIpsmRootHandler::TaskPadGetTitle
  507. -
  508. Author: NSun
  509. ---------------------------------------------------------------------------*/
  510. STDMETHODIMP
  511. CIpsmRootHandler::TaskPadGetTitle
  512. (
  513. ITFSComponent * pComponent,
  514. MMC_COOKIE cookie,
  515. LPOLESTR pszGroup,
  516. LPOLESTR * ppszTitle
  517. )
  518. {
  519. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  520. *ppszTitle = (LPOLESTR) CoTaskMemAlloc (sizeof(OLECHAR)*(lstrlen(m_strTaskpadTitle)+1));
  521. if (!ppszTitle)
  522. return E_OUTOFMEMORY;
  523. lstrcpy (*ppszTitle, m_strTaskpadTitle);
  524. return S_OK;
  525. }
  526. /*---------------------------------------------------------------------------
  527. CIpsmRootHandler::OnGetResultViewType
  528. Return the result view that this node is going to support
  529. Author: NSun
  530. ---------------------------------------------------------------------------*/
  531. HRESULT
  532. CIpsmRootHandler::OnGetResultViewType
  533. (
  534. ITFSComponent * pComponent,
  535. MMC_COOKIE cookie,
  536. LPOLESTR * ppViewType,
  537. long * pViewOptions
  538. )
  539. {
  540. // if we aren't displaying the taskpad, use the default stuff...
  541. if (!m_bTaskPadView)
  542. return CIpsmHandler::OnGetResultViewType(pComponent, cookie, ppViewType, pViewOptions);
  543. //TODO Should we keep that?
  544. //
  545. // In this code we are defaulting to a taskpad view for this node all the time.
  546. // It is the snapins responsibility to put up a view menu selection that has a
  547. // selection for the taskpad. Do that in AddMenuItems.
  548. //
  549. //
  550. // We will use the default DHTML provided by MMC. It actually resides as a
  551. // resource inside MMC.EXE. We just get the path to it and use that.
  552. // The one piece of magic here is the text following the '#'. That is the special
  553. // way we have of identifying they taskpad we are talking about. Here we say we are
  554. // wanting to show a taskpad that we refer to as "CMTP1". We will actually see this
  555. // string pass back to us later. If someone is extending our taskpad, they also need
  556. // to know what this secret string is.
  557. //
  558. *pViewOptions = MMC_VIEW_OPTIONS_NONE;
  559. OLECHAR szBuffer[MAX_PATH*2]; // a little extra
  560. lstrcpy (szBuffer, L"res://");
  561. OLECHAR * temp = szBuffer + lstrlen(szBuffer);
  562. //TODO need to hook up the ipsecmon help file
  563. // get "res://"-type string for custom taskpad
  564. // the string after the # gets handed back to us in future calls...
  565. // should be unique for each node
  566. ::GetModuleFileName (NULL, temp, MAX_PATH);
  567. lstrcat (szBuffer, L"/default.htm#TAPIROOT");
  568. // alloc and copy bitmap resource string
  569. *ppViewType = (LPOLESTR)CoTaskMemAlloc (sizeof(OLECHAR)*(lstrlen(szBuffer)+1));
  570. if (!*ppViewType)
  571. return E_OUTOFMEMORY; // or S_FALSE ???
  572. lstrcpy (*ppViewType, szBuffer);
  573. return S_OK;
  574. }
  575. /*!--------------------------------------------------------------------------
  576. CIpsmRootHandler::OnResultSelect
  577. For nodes with task pads, we override the select message to set
  578. the selected node. Nodes with taskpads do not get the MMCN_SHOW
  579. message which is where we normall set the selected node
  580. Author: NSun
  581. ---------------------------------------------------------------------------*/
  582. HRESULT CIpsmRootHandler::OnResultSelect(ITFSComponent *pComponent, LPDATAOBJECT pDataObject, MMC_COOKIE cookie, LPARAM arg, LPARAM lParam)
  583. {
  584. HRESULT hr = hrOK;
  585. CORg(DoTaskpadResultSelect(pComponent, pDataObject, cookie, arg, lParam, m_bTaskPadView));
  586. CORg(CIpsmHandler::OnResultSelect(pComponent, pDataObject, cookie, arg, lParam));
  587. Error:
  588. return hr;
  589. }
  590. /*---------------------------------------------------------------------------
  591. Command handlers
  592. ---------------------------------------------------------------------------*/
  593. /*---------------------------------------------------------------------------
  594. CIpsmRootHandler::OnAddMachine
  595. Description
  596. Author: NSun
  597. ---------------------------------------------------------------------------*/
  598. HRESULT
  599. CIpsmRootHandler::OnAddMachine
  600. (
  601. ITFSNode * pNode
  602. )
  603. {
  604. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  605. HRESULT hr = hrOK;
  606. /*
  607. GETCOMPUTERSELECTIONINFO info;
  608. PDSSELECTIONLIST pSelList = NULL;
  609. LPCTSTR attrs[] = {_T("dNSHostName")};
  610. ZeroMemory(&info, sizeof(GETCOMPUTERSELECTIONINFO));
  611. info.cbSize = sizeof(GETCOMPUTERSELECTIONINFO);
  612. info.hwndParent = FindMMCMainWindow();
  613. info.flObjectPicker = 0; // not allow multiple selection
  614. info.flDsObjectPicker = DSOP_SCOPE_DIRECTORY |
  615. DSOP_SCOPE_DOMAIN_TREE |
  616. DSOP_SCOPE_EXTERNAL_TRUSTED_DOMAINS;
  617. info.flStartingScope = DSOP_SCOPE_DIRECTORY;
  618. info.ppDsSelList = &pSelList;
  619. info.cRequestedAttributes = 1;
  620. info.aptzRequestedAttributes = attrs;
  621. hr = GetComputerSelection(&info);
  622. if(hr != S_OK) // assume the API will display error message, if there is
  623. return hr;
  624. CString strTemp = pSelList->aDsSelection[0].pwzName;
  625. if (strTemp.Left(2) == _T("\\\\"))
  626. strTemp = pSelList->aDsSelection[0].pwzName[2];
  627. */
  628. CAddServ dlgAddServ(CWnd::FromHandle(FindMMCMainWindow()));
  629. if (IDOK != dlgAddServ.DoModal())
  630. {
  631. return hr;
  632. }
  633. CString strTemp = dlgAddServ.m_stComputerName;
  634. // if the machine is already in the list, don't bother.
  635. if (IsServerInList(pNode, strTemp))
  636. {
  637. AfxMessageBox(IDS_ERR_SERVER_IN_LIST);
  638. }
  639. else
  640. {
  641. AddServer(_T(""), strTemp, TRUE, IPSMSNAP_OPTIONS_REFRESH, IPSECMON_REFRESH_INTERVAL_DEFAULT);
  642. }
  643. return hr;
  644. }
  645. /*---------------------------------------------------------------------------
  646. CIpsmRootHandler::AddServer
  647. Description
  648. Author: NSun
  649. ---------------------------------------------------------------------------*/
  650. HRESULT
  651. CIpsmRootHandler::AddServer
  652. (
  653. LPCWSTR pServerIp,
  654. LPCTSTR pServerName,
  655. BOOL bNewServer,
  656. DWORD dwServerOptions,
  657. DWORD dwRefreshInterval,
  658. BOOL bExtension,
  659. DWORD dwLineBuffSize,
  660. DWORD dwPhoneBuffSize
  661. )
  662. {
  663. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  664. HRESULT hr = hrOK;
  665. CIpsmServer * pServer = NULL;
  666. SPITFSNodeHandler spHandler;
  667. SPITFSNode spNode, spRootNode;
  668. // Create a handler for the node
  669. try
  670. {
  671. pServer = new CIpsmServer(m_spTFSCompData);
  672. //pServer->SetName(pServerName);
  673. // Do this so that it will get released correctly
  674. spHandler = pServer;
  675. }
  676. catch(...)
  677. {
  678. hr = E_OUTOFMEMORY;
  679. }
  680. CORg( hr );
  681. //
  682. // Create the server container information
  683. //
  684. CreateContainerTFSNode(&spNode,
  685. &GUID_IpsmServerNodeType,
  686. pServer,
  687. pServer,
  688. m_spNodeMgr);
  689. // Tell the handler to initialize any specific data
  690. pServer->SetName(pServerName);
  691. pServer->InitializeNode((ITFSNode *) spNode);
  692. if (dwServerOptions & IPSMSNAP_OPTIONS_EXTENSION)
  693. {
  694. pServer->SetExtensionName();
  695. }
  696. // Mask out the auto refresh option because we set it next
  697. pServer->SetOptions(dwServerOptions & ~IPSMSNAP_OPTIONS_REFRESH);
  698. // if we got a valid refresh interval, then set it.
  699. pServer->SetAutoRefresh(spNode, dwServerOptions & IPSMSNAP_OPTIONS_REFRESH, dwRefreshInterval);
  700. pServer->SetDnsResolve(spNode, dwServerOptions & IPSMSNAP_OPTIONS_DNS);
  701. AddServerSortedName(spNode, bNewServer);
  702. if (bNewServer)
  703. {
  704. // need to get our node descriptor
  705. CORg(m_spNodeMgr->GetRootNode(&spRootNode));
  706. spRootNode->SetData(TFS_DATA_DIRTY, TRUE);
  707. }
  708. Error:
  709. return hr;
  710. }
  711. /*---------------------------------------------------------------------------
  712. CIpsmRootHandler::IsServerInList
  713. Description
  714. Author: NSun
  715. ---------------------------------------------------------------------------*/
  716. BOOL
  717. CIpsmRootHandler::IsServerInList
  718. (
  719. ITFSNode * pRootNode,
  720. LPCTSTR pszMachineName
  721. )
  722. {
  723. HRESULT hr = hrOK;
  724. SPITFSNodeEnum spNodeEnum;
  725. SPITFSNode spCurrentNode;
  726. ULONG nNumReturned = 0;
  727. DWORD dwIpAddressCurrent;
  728. BOOL bFound = FALSE;
  729. CString strNewName = pszMachineName;
  730. // get the enumerator for this node
  731. pRootNode->GetEnum(&spNodeEnum);
  732. spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
  733. while (nNumReturned)
  734. {
  735. // walk the list of servers and see if it already exists
  736. CIpsmServer * pServer = GETHANDLER(CIpsmServer, spCurrentNode);
  737. if (strNewName.CompareNoCase(pServer->GetName()) == 0)
  738. {
  739. bFound = TRUE;
  740. break;
  741. }
  742. // get the next Server in the list
  743. spCurrentNode.Release();
  744. spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
  745. }
  746. return bFound;
  747. }
  748. /*---------------------------------------------------------------------------
  749. CIpsmRootHandler::AddServerSortedIp
  750. Description
  751. Author: NSun
  752. ---------------------------------------------------------------------------*/
  753. HRESULT
  754. CIpsmRootHandler::AddServerSortedIp
  755. (
  756. ITFSNode * pNewNode,
  757. BOOL bNewServer
  758. )
  759. {
  760. HRESULT hr = hrOK;
  761. SPITFSNodeEnum spNodeEnum;
  762. SPITFSNode spCurrentNode;
  763. SPITFSNode spPrevNode;
  764. SPITFSNode spRootNode;
  765. ULONG nNumReturned = 0;
  766. DWORD dwIpAddressCurrent = 0;
  767. DWORD dwIpAddressTarget;
  768. CIpsmServer * pServer;
  769. // get our target address
  770. pServer = GETHANDLER(CIpsmServer, pNewNode);
  771. //pServer->GetIpAddress(&dwIpAddressTarget);
  772. // need to get our node descriptor
  773. CORg(m_spNodeMgr->GetRootNode(&spRootNode));
  774. // get the enumerator for this node
  775. CORg(spRootNode->GetEnum(&spNodeEnum));
  776. CORg(spNodeEnum->Next(1, &spCurrentNode, &nNumReturned));
  777. while (nNumReturned)
  778. {
  779. // walk the list of servers and see if it already exists
  780. pServer = GETHANDLER(CIpsmServer, spCurrentNode);
  781. //pServer->GetIpAddress(&dwIpAddressCurrent);
  782. //if (dwIpAddressCurrent > dwIpAddressTarget)
  783. //{
  784. // Found where we need to put it, break out
  785. break;
  786. //}
  787. // get the next Server in the list
  788. spPrevNode.Set(spCurrentNode);
  789. spCurrentNode.Release();
  790. spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
  791. }
  792. // Add the node in based on the PrevNode pointer
  793. if (spPrevNode)
  794. {
  795. if (bNewServer)
  796. {
  797. if (spPrevNode->GetData(TFS_DATA_SCOPEID) != NULL)
  798. {
  799. pNewNode->SetData(TFS_DATA_RELATIVE_FLAGS, SDI_PREVIOUS);
  800. pNewNode->SetData(TFS_DATA_RELATIVE_SCOPEID, spPrevNode->GetData(TFS_DATA_SCOPEID));
  801. }
  802. }
  803. CORg(spRootNode->InsertChild(spPrevNode, pNewNode));
  804. }
  805. else
  806. {
  807. // add to the head
  808. if (m_bExpanded)
  809. {
  810. pNewNode->SetData(TFS_DATA_RELATIVE_FLAGS, SDI_FIRST);
  811. }
  812. CORg(spRootNode->AddChild(pNewNode));
  813. }
  814. Error:
  815. return hr;
  816. }
  817. /*---------------------------------------------------------------------------
  818. CIpsmRootHandler::AddServerSortedName
  819. Description
  820. Author: NSun
  821. ---------------------------------------------------------------------------*/
  822. HRESULT
  823. CIpsmRootHandler::AddServerSortedName
  824. (
  825. ITFSNode * pNewNode,
  826. BOOL bNewServer
  827. )
  828. {
  829. HRESULT hr = hrOK;
  830. SPITFSNodeEnum spNodeEnum;
  831. SPITFSNode spCurrentNode;
  832. SPITFSNode spPrevNode;
  833. SPITFSNode spRootNode;
  834. ULONG nNumReturned = 0;
  835. CString strTarget, strCurrent;
  836. CIpsmServer * pServer;
  837. // get our target address
  838. pServer = GETHANDLER(CIpsmServer, pNewNode);
  839. strTarget = pServer->GetName();
  840. // need to get our node descriptor
  841. CORg(m_spNodeMgr->GetRootNode(&spRootNode));
  842. // get the enumerator for this node
  843. CORg(spRootNode->GetEnum(&spNodeEnum));
  844. CORg(spNodeEnum->Next(1, &spCurrentNode, &nNumReturned));
  845. while (nNumReturned)
  846. {
  847. // walk the list of servers and see if it already exists
  848. pServer = GETHANDLER(CIpsmServer, spCurrentNode);
  849. strCurrent = pServer->GetName();
  850. if (strTarget.Compare(strCurrent) < 0)
  851. {
  852. // Found where we need to put it, break out
  853. break;
  854. }
  855. // get the next Server in the list
  856. spPrevNode.Set(spCurrentNode);
  857. spCurrentNode.Release();
  858. spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
  859. }
  860. // Add the node in based on the PrevNode pointer
  861. if (spPrevNode)
  862. {
  863. if (bNewServer)
  864. {
  865. if (spPrevNode->GetData(TFS_DATA_SCOPEID) != NULL)
  866. {
  867. pNewNode->SetData(TFS_DATA_RELATIVE_FLAGS, SDI_PREVIOUS);
  868. pNewNode->SetData(TFS_DATA_RELATIVE_SCOPEID, spPrevNode->GetData(TFS_DATA_SCOPEID));
  869. }
  870. }
  871. CORg(spRootNode->InsertChild(spPrevNode, pNewNode));
  872. }
  873. else
  874. {
  875. // add to the head
  876. if (m_bExpanded)
  877. {
  878. pNewNode->SetData(TFS_DATA_RELATIVE_FLAGS, SDI_FIRST);
  879. }
  880. CORg(spRootNode->AddChild(pNewNode));
  881. }
  882. Error:
  883. return hr;
  884. }
  885. /*---------------------------------------------------------------------------
  886. CIpsmRootHandler::CheckMachine
  887. adds the machine to the list of servers.
  888. Author: NSun
  889. ---------------------------------------------------------------------------*/
  890. HRESULT
  891. CIpsmRootHandler::CheckMachine
  892. (
  893. ITFSNode * pRootNode,
  894. LPDATAOBJECT pDataObject
  895. )
  896. {
  897. HRESULT hr = hrOK;
  898. // Get the local machine name and check to see if the service
  899. // is installed.
  900. CString strMachineName;
  901. LPTSTR pBuf;
  902. DWORD dwLength = MAX_COMPUTERNAME_LENGTH + 1;
  903. BOOL bExtension = (pDataObject != NULL);
  904. if (!bExtension)
  905. {
  906. pBuf = strMachineName.GetBuffer(dwLength);
  907. GetComputerName(pBuf, &dwLength);
  908. strMachineName.ReleaseBuffer();
  909. }
  910. else
  911. {
  912. strMachineName = Extract<TCHAR>(pDataObject, (CLIPFORMAT) g_cfMachineName, COMPUTERNAME_LEN_MAX);
  913. }
  914. if (strMachineName.IsEmpty())
  915. {
  916. DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
  917. LPTSTR pBuf = strMachineName.GetBuffer(dwSize);
  918. ::GetComputerName(pBuf, &dwSize);
  919. strMachineName.ReleaseBuffer();
  920. }
  921. // if the machine is already in the list, don't bother.
  922. if (IsServerInList(pRootNode, strMachineName))
  923. return hr;
  924. if (bExtension)
  925. RemoveOldEntries(pRootNode, strMachineName);
  926. // we always add the local machine or whatever machine we are pointed at even if
  927. // we are an extension
  928. // OK. add it to the list.
  929. DWORD dwFlags = 0;
  930. if (bExtension)
  931. dwFlags |= IPSMSNAP_OPTIONS_EXTENSION;
  932. dwFlags |= IPSMSNAP_OPTIONS_REFRESH;
  933. AddServer(_T(""), strMachineName, TRUE, dwFlags, IPSECMON_REFRESH_INTERVAL_DEFAULT, bExtension);
  934. return hr;
  935. }
  936. // when running as an extension, it is possible that we were saved as "local machine"
  937. // which means that if the saved console file was moved to another machine we need to remove
  938. // the old entry that was saved
  939. HRESULT
  940. CIpsmRootHandler::RemoveOldEntries(ITFSNode * pNode, LPCTSTR pszAddr)
  941. {
  942. HRESULT hr = hrOK;
  943. SPITFSNodeEnum spNodeEnum;
  944. SPITFSNode spCurrentNode;
  945. ULONG nNumReturned = 0;
  946. CIpsmServer * pServer;
  947. CString strCurAddr;
  948. // get the enumerator for this node
  949. CORg(pNode->GetEnum(&spNodeEnum));
  950. CORg(spNodeEnum->Next(1, &spCurrentNode, &nNumReturned));
  951. while (nNumReturned)
  952. {
  953. // walk the list of servers and see if it already exists
  954. pServer = GETHANDLER(CIpsmServer, spCurrentNode);
  955. strCurAddr = pServer->GetName();
  956. if (strCurAddr.CompareNoCase(pszAddr) != 0)
  957. {
  958. CORg (pNode->RemoveChild(spCurrentNode));
  959. }
  960. spCurrentNode.Release();
  961. spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
  962. }
  963. Error:
  964. return hr;
  965. }