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.

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