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.

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