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.

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