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.

1301 lines
36 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. provider.cpp
  7. Tapi provider node handler
  8. FILE HISTORY:
  9. */
  10. #include "stdafx.h"
  11. #include "provider.h" // Provider node definition
  12. #include "EditUser.h" // user editor
  13. #include "server.h"
  14. #include "tapi.h"
  15. /*---------------------------------------------------------------------------
  16. Class CProviderHandler implementation
  17. ---------------------------------------------------------------------------*/
  18. /*---------------------------------------------------------------------------
  19. Constructor and destructor
  20. Description
  21. Author: EricDav
  22. ---------------------------------------------------------------------------*/
  23. CProviderHandler::CProviderHandler
  24. (
  25. ITFSComponentData * pComponentData
  26. ) : CTapiHandler(pComponentData)
  27. {
  28. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  29. m_deviceType = DEVICE_LINE;
  30. }
  31. CProviderHandler::~CProviderHandler()
  32. {
  33. }
  34. /*!--------------------------------------------------------------------------
  35. CProviderHandler::InitializeNode
  36. Initializes node specific data
  37. Author: EricDav
  38. ---------------------------------------------------------------------------*/
  39. HRESULT
  40. CProviderHandler::InitializeNode
  41. (
  42. ITFSNode * pNode
  43. )
  44. {
  45. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  46. CString strTemp;
  47. BuildDisplayName(&strTemp);
  48. SetDisplayName(strTemp);
  49. // Make the node immediately visible
  50. pNode->SetVisibilityState(TFS_VIS_SHOW);
  51. pNode->SetData(TFS_DATA_COOKIE, (LPARAM) pNode);
  52. pNode->SetData(TFS_DATA_IMAGEINDEX, ICON_IDX_FOLDER_CLOSED);
  53. pNode->SetData(TFS_DATA_OPENIMAGEINDEX, ICON_IDX_FOLDER_OPEN);
  54. pNode->SetData(TFS_DATA_USER, (LPARAM) this);
  55. pNode->SetData(TFS_DATA_TYPE, TAPISNAP_PROVIDER);
  56. pNode->SetData(TFS_DATA_SCOPE_LEAF_NODE, TRUE);
  57. SetColumnStringIDs(&aColumns[TAPISNAP_PROVIDER][0]);
  58. SetColumnWidths(&aColumnWidths[TAPISNAP_PROVIDER][0]);
  59. return hrOK;
  60. }
  61. /*---------------------------------------------------------------------------
  62. CProviderHandler::OnCreateNodeId2
  63. Returns a unique string for this node
  64. Author: EricDav
  65. ---------------------------------------------------------------------------*/
  66. HRESULT CProviderHandler::OnCreateNodeId2(ITFSNode * pNode, CString & strId, DWORD * dwFlags)
  67. {
  68. const GUID * pGuid = pNode->GetNodeType();
  69. CString strProviderId, strGuid;
  70. StringFromGUID2(*pGuid, strGuid.GetBuffer(256), 256);
  71. strGuid.ReleaseBuffer();
  72. strProviderId.Format(_T("%d"), m_dwProviderID);
  73. strId = m_spTapiInfo->GetComputerName() + strProviderId + strGuid;
  74. return hrOK;
  75. }
  76. /*---------------------------------------------------------------------------
  77. CProviderHandler::GetImageIndex
  78. -
  79. Author: EricDav
  80. ---------------------------------------------------------------------------*/
  81. int
  82. CProviderHandler::GetImageIndex(BOOL bOpenImage)
  83. {
  84. int nIndex = -1;
  85. return nIndex;
  86. }
  87. /*---------------------------------------------------------------------------
  88. Overridden base handler functions
  89. ---------------------------------------------------------------------------*/
  90. /*---------------------------------------------------------------------------
  91. CProviderHandler::OnAddMenuItems
  92. Adds context menu items for the provider scope pane node
  93. Author: EricDav
  94. ---------------------------------------------------------------------------*/
  95. STDMETHODIMP
  96. CProviderHandler::OnAddMenuItems
  97. (
  98. ITFSNode * pNode,
  99. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  100. LPDATAOBJECT lpDataObject,
  101. DATA_OBJECT_TYPES type,
  102. DWORD dwType,
  103. long * pInsertionAllowed
  104. )
  105. {
  106. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  107. LONG fFlags = 0, fLoadingFlags = 0;
  108. HRESULT hr = S_OK;
  109. CString strMenuItem;
  110. /*
  111. if ( m_nState != loaded )
  112. {
  113. fFlags |= MF_GRAYED;
  114. }
  115. if ( m_nState == loading)
  116. {
  117. fLoadingFlags = MF_GRAYED;
  118. }
  119. */
  120. //Bug 305657 We cannot configure TSP remotely
  121. if (!m_spTapiInfo->IsLocalMachine() || !m_spTapiInfo->IsAdmin())
  122. {
  123. fFlags |= MF_GRAYED;
  124. }
  125. if (type == CCT_SCOPE)
  126. {
  127. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP)
  128. {
  129. if (m_dwFlags & AVAILABLEPROVIDER_CONFIGURABLE)
  130. {
  131. strMenuItem.LoadString(IDS_CONFIGURE_PROVIDER);
  132. hr = LoadAndAddMenuItem( pContextMenuCallback,
  133. strMenuItem,
  134. IDS_CONFIGURE_PROVIDER,
  135. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  136. fFlags );
  137. ASSERT( SUCCEEDED(hr) );
  138. }
  139. }
  140. }
  141. return hr;
  142. }
  143. /*!--------------------------------------------------------------------------
  144. CProviderHandler::AddMenuItems
  145. Adds context menu items for virtual list box (result pane) items
  146. Author: EricDav
  147. ---------------------------------------------------------------------------*/
  148. STDMETHODIMP
  149. CProviderHandler::AddMenuItems
  150. (
  151. ITFSComponent * pComponent,
  152. MMC_COOKIE cookie,
  153. LPDATAOBJECT pDataObject,
  154. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  155. long * pInsertionAllowed
  156. )
  157. {
  158. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  159. HRESULT hr = hrOK;
  160. CString strMenuItem;
  161. SPINTERNAL spInternal;
  162. LONG fFlags = 0;
  163. int nIndex;
  164. DWORD dwFlags;
  165. CTapiDevice tapiDevice;
  166. spInternal = ExtractInternalFormat(pDataObject);
  167. // virtual listbox notifications come to the handler of the node that is selected.
  168. // check to see if this notification is for a virtual listbox item or this provider
  169. // node itself.
  170. if (spInternal->HasVirtualIndex())
  171. {
  172. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP)
  173. {
  174. CTapiConfigInfo tapiConfigInfo;
  175. m_spTapiInfo->GetConfigInfo(&tapiConfigInfo);
  176. if (m_spTapiInfo->IsAdmin() &&
  177. tapiConfigInfo.m_dwFlags & TAPISERVERCONFIGFLAGS_ISSERVER)
  178. {
  179. fFlags = 0;
  180. }
  181. else
  182. {
  183. fFlags = MF_GRAYED;
  184. }
  185. // Check to see if this device can ONLY be used locally, if
  186. // so, gray the edit user menu item
  187. nIndex = spInternal->GetVirtualIndex();
  188. m_spTapiInfo->GetDeviceInfo(m_deviceType, &tapiDevice, m_dwProviderID, nIndex);
  189. if (m_deviceType == DEVICE_PHONE ||
  190. m_spTapiInfo->GetDeviceFlags (
  191. tapiDevice.m_dwProviderID,
  192. tapiDevice.m_dwPermanentID,
  193. &dwFlags
  194. ) ||
  195. (dwFlags & LINEDEVCAPFLAGS_LOCAL)
  196. )
  197. {
  198. fFlags = MF_GRAYED;
  199. }
  200. strMenuItem.LoadString(IDS_EDIT_USERS);
  201. hr = LoadAndAddMenuItem( pContextMenuCallback,
  202. strMenuItem,
  203. IDS_EDIT_USERS,
  204. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  205. fFlags );
  206. ASSERT( SUCCEEDED(hr) );
  207. }
  208. }
  209. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_VIEW)
  210. {
  211. strMenuItem.LoadString(IDS_VIEW_LINES);
  212. hr = LoadAndAddMenuItem( pContextMenuCallback,
  213. strMenuItem,
  214. IDS_VIEW_LINES,
  215. CCM_INSERTIONPOINTID_PRIMARY_VIEW,
  216. (m_deviceType == DEVICE_LINE) ? MF_CHECKED : 0 );
  217. ASSERT( SUCCEEDED(hr) );
  218. strMenuItem.LoadString(IDS_VIEW_PHONES);
  219. hr = LoadAndAddMenuItem( pContextMenuCallback,
  220. strMenuItem,
  221. IDS_VIEW_PHONES,
  222. CCM_INSERTIONPOINTID_PRIMARY_VIEW,
  223. (m_deviceType == DEVICE_PHONE) ? MF_CHECKED : 0 );
  224. ASSERT( SUCCEEDED(hr) );
  225. }
  226. return hr;
  227. }
  228. /*---------------------------------------------------------------------------
  229. CProviderHandler::OnCommand
  230. Handles context menu commands for provider scope pane node
  231. Author: EricDav
  232. ---------------------------------------------------------------------------*/
  233. STDMETHODIMP
  234. CProviderHandler::OnCommand
  235. (
  236. ITFSNode * pNode,
  237. long nCommandId,
  238. DATA_OBJECT_TYPES type,
  239. LPDATAOBJECT pDataObject,
  240. DWORD dwType
  241. )
  242. {
  243. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  244. HRESULT hr = S_OK;
  245. switch (nCommandId)
  246. {
  247. case IDS_CONFIGURE_PROVIDER:
  248. OnConfigureProvider(pNode);
  249. break;
  250. default:
  251. break;
  252. }
  253. return hr;
  254. }
  255. /*!--------------------------------------------------------------------------
  256. CProviderHandler::Command
  257. Handles context menu commands for virtual listbox items
  258. Author: EricDav
  259. ---------------------------------------------------------------------------*/
  260. STDMETHODIMP
  261. CProviderHandler::Command
  262. (
  263. ITFSComponent * pComponent,
  264. MMC_COOKIE cookie,
  265. int nCommandID,
  266. LPDATAOBJECT pDataObject
  267. )
  268. {
  269. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  270. HRESULT hr = S_OK;
  271. SPITFSNode spNode;
  272. m_spResultNodeMgr->FindNode(cookie, &spNode);
  273. switch (nCommandID)
  274. {
  275. case IDS_EDIT_USERS:
  276. OnEditUsers(pComponent, pDataObject, cookie);
  277. break;
  278. case IDS_VIEW_LINES:
  279. m_deviceType = DEVICE_LINE;
  280. // clear the listbox then set the size
  281. SetColumnInfo();
  282. UpdateColumnText(pComponent);
  283. UpdateListboxCount(spNode, TRUE);
  284. UpdateListboxCount(spNode);
  285. break;
  286. case IDS_VIEW_PHONES:
  287. m_deviceType = DEVICE_PHONE;
  288. // clear the listbox then set the size
  289. SetColumnInfo();
  290. UpdateColumnText(pComponent);
  291. UpdateListboxCount(spNode, TRUE);
  292. UpdateListboxCount(spNode);
  293. break;
  294. default:
  295. break;
  296. }
  297. return hr;
  298. }
  299. /*!--------------------------------------------------------------------------
  300. CProviderHandler::HasPropertyPages
  301. Implementation of ITFSNodeHandler::HasPropertyPages
  302. NOTE: the root node handler has to over-ride this function to
  303. handle the snapin manager property page (wizard) case!!!
  304. Author: KennT
  305. ---------------------------------------------------------------------------*/
  306. STDMETHODIMP
  307. CProviderHandler::HasPropertyPages
  308. (
  309. ITFSNode * pNode,
  310. LPDATAOBJECT pDataObject,
  311. DATA_OBJECT_TYPES type,
  312. DWORD dwType
  313. )
  314. {
  315. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  316. return hrFalse;
  317. }
  318. /*---------------------------------------------------------------------------
  319. CProviderHandler::CreatePropertyPages
  320. Description
  321. Author: EricDav
  322. ---------------------------------------------------------------------------*/
  323. STDMETHODIMP
  324. CProviderHandler::CreatePropertyPages
  325. (
  326. ITFSNode * pNode,
  327. LPPROPERTYSHEETCALLBACK lpProvider,
  328. LPDATAOBJECT pDataObject,
  329. LONG_PTR handle,
  330. DWORD dwType
  331. )
  332. {
  333. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  334. DWORD dwError;
  335. DWORD dwDynDnsFlags;
  336. //
  337. // Create the property page
  338. //
  339. SPIComponentData spComponentData;
  340. m_spNodeMgr->GetComponentData(&spComponentData);
  341. //CServerProperties * pServerProp = new CServerProperties(pNode, spComponentData, m_spTFSCompData, NULL);
  342. //
  343. // Object gets deleted when the page is destroyed
  344. //
  345. Assert(lpProvider != NULL);
  346. //return pServerProp->CreateModelessSheet(lpProvider, handle);
  347. return hrFalse;
  348. }
  349. /*---------------------------------------------------------------------------
  350. CProviderHandler::OnPropertyChange
  351. Description
  352. Author: EricDav
  353. ---------------------------------------------------------------------------*/
  354. HRESULT
  355. CProviderHandler::OnPropertyChange
  356. (
  357. ITFSNode * pNode,
  358. LPDATAOBJECT pDataobject,
  359. DWORD dwType,
  360. LPARAM arg,
  361. LPARAM lParam
  362. )
  363. {
  364. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  365. //CServerProperties * pServerProp = reinterpret_cast<CServerProperties *>(lParam);
  366. LONG_PTR changeMask = 0;
  367. // tell the property page to do whatever now that we are back on the
  368. // main thread
  369. //pServerProp->OnPropertyChange(TRUE, &changeMask);
  370. //pServerProp->AcknowledgeNotify();
  371. if (changeMask)
  372. pNode->ChangeNode(changeMask);
  373. return hrOK;
  374. }
  375. /*---------------------------------------------------------------------------
  376. CProviderHandler::OnExpand
  377. Handles enumeration of a scope item
  378. Author: EricDav
  379. ---------------------------------------------------------------------------*/
  380. HRESULT
  381. CProviderHandler::OnExpand
  382. (
  383. ITFSNode * pNode,
  384. LPDATAOBJECT pDataObject,
  385. DWORD dwType,
  386. LPARAM arg,
  387. LPARAM param
  388. )
  389. {
  390. HRESULT hr = hrOK;
  391. if (m_bExpanded)
  392. return hr;
  393. // do the default handling
  394. CORg (CTapiHandler::OnExpand(pNode, pDataObject, dwType, arg, param));
  395. Error:
  396. return hr;
  397. }
  398. /*!--------------------------------------------------------------------------
  399. CProviderHandler::OnResultSelect
  400. Handles the MMCN_SELECT notifcation
  401. Author: EricDav
  402. ---------------------------------------------------------------------------*/
  403. HRESULT
  404. CProviderHandler::OnResultSelect
  405. (
  406. ITFSComponent * pComponent,
  407. LPDATAOBJECT pDataObject,
  408. MMC_COOKIE cookie,
  409. LPARAM arg,
  410. LPARAM lParam
  411. )
  412. {
  413. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  414. HRESULT hr = hrOK;
  415. SPINTERNAL spInternal;
  416. SPIConsole spConsole;
  417. SPIConsoleVerb spConsoleVerb;
  418. SPITFSNode spNode;
  419. BOOL bStates[ARRAYLEN(g_ConsoleVerbs)];
  420. int i;
  421. LONG_PTR dwNodeType;
  422. BOOL fSelect = HIWORD(arg);
  423. if (!fSelect)
  424. return hr;
  425. if (m_spTapiInfo)
  426. {
  427. // Get the current count
  428. i = m_spTapiInfo->GetDeviceCount(m_deviceType, m_dwProviderID);
  429. // now notify the virtual listbox
  430. CORg ( m_spNodeMgr->GetConsole(&spConsole) );
  431. CORg ( spConsole->UpdateAllViews(pDataObject, i, RESULT_PANE_SET_VIRTUAL_LB_SIZE) );
  432. }
  433. // now update the verbs...
  434. spInternal = ExtractInternalFormat(pDataObject);
  435. Assert(spInternal);
  436. // virtual listbox notifications come to the handler of the node that is selected.
  437. // check to see if this notification is for a virtual listbox item or the active
  438. // registrations node itself.
  439. CORg (pComponent->GetConsoleVerb(&spConsoleVerb));
  440. if (spInternal->HasVirtualIndex())
  441. {
  442. // we gotta do special stuff for the virtual index items
  443. dwNodeType = TAPISNAP_DEVICE;
  444. for (i = 0; i < ARRAYLEN(g_ConsoleVerbs); bStates[i++] = FALSE);
  445. }
  446. else
  447. {
  448. // enable/disable delete depending if the provider supports it
  449. CORg (m_spNodeMgr->FindNode(cookie, &spNode));
  450. dwNodeType = spNode->GetData(TFS_DATA_TYPE);
  451. for (i = 0; i < ARRAYLEN(g_ConsoleVerbs); bStates[i++] = TRUE);
  452. //Per XZhang, hide "delete" context menu of provider nodes on remote machines
  453. if (!m_spTapiInfo->IsLocalMachine() || (m_dwFlags & AVAILABLEPROVIDER_REMOVABLE) == 0)
  454. {
  455. bStates[MMC_VERB_DELETE & 0x000F] = FALSE;
  456. }
  457. }
  458. EnableVerbs(spConsoleVerb, g_ConsoleVerbStates[dwNodeType], bStates);
  459. COM_PROTECT_ERROR_LABEL;
  460. return hr;
  461. }
  462. /*!--------------------------------------------------------------------------
  463. CProviderHandler::OnDelete
  464. The base handler calls this when MMC sends a MMCN_DELETE for a
  465. scope pane item. We just call our delete command handler.
  466. Author: EricDav
  467. ---------------------------------------------------------------------------*/
  468. HRESULT
  469. CProviderHandler::OnDelete
  470. (
  471. ITFSNode * pNode,
  472. LPARAM arg,
  473. LPARAM lParam
  474. )
  475. {
  476. return OnDelete(pNode);
  477. }
  478. /*---------------------------------------------------------------------------
  479. CProviderHandler::OnGetResultViewType
  480. Return the result view that this node is going to support
  481. Author: EricDav
  482. ---------------------------------------------------------------------------*/
  483. HRESULT
  484. CProviderHandler::OnGetResultViewType
  485. (
  486. ITFSComponent * pComponent,
  487. MMC_COOKIE cookie,
  488. LPOLESTR * ppViewType,
  489. long * pViewOptions
  490. )
  491. {
  492. if (cookie != NULL)
  493. {
  494. *pViewOptions = MMC_VIEW_OPTIONS_OWNERDATALIST | MMC_VIEW_OPTIONS_MULTISELECT;
  495. }
  496. return S_FALSE;
  497. }
  498. /*---------------------------------------------------------------------------
  499. CProviderHandler::GetVirtualImage
  500. Returns the image index for virtual listbox items
  501. Author: EricDav
  502. ---------------------------------------------------------------------------*/
  503. int
  504. CProviderHandler::GetVirtualImage
  505. (
  506. int nIndex
  507. )
  508. {
  509. return ICON_IDX_MACHINE;
  510. }
  511. /*---------------------------------------------------------------------------
  512. CProviderHandler::GetVirtualString
  513. returns a pointer to the string for virtual listbox items
  514. Author: EricDav
  515. ---------------------------------------------------------------------------*/
  516. LPCWSTR
  517. CProviderHandler::GetVirtualString
  518. (
  519. int nIndex,
  520. int nCol
  521. )
  522. {
  523. // check our cache to see if we have this one.
  524. //TapiStrRecord * ptsr = m_RecList.FindItem(nIndex);
  525. CString strStatus;
  526. TapiStrRecord tsr;
  527. if (!m_mapRecords.Lookup(nIndex, tsr))
  528. {
  529. Trace1("CProviderHandler::GetVirtualString - Index %d not in TAPI string cache\n", nIndex);
  530. // doesn't exist in our cache, need to add this one.
  531. if (!BuildTapiStrRecord(nIndex, tsr))
  532. {
  533. Trace0("CProviderHandler::BuildTapiStrRecord failed!\n");
  534. }
  535. //m_RecList.AddTail(ptsr);
  536. m_mapRecords.SetAt(nIndex, tsr);
  537. }
  538. if (!m_mapStatus.Lookup(nIndex, strStatus))
  539. {
  540. Trace1("CProviderHandler::GetVirtualString - Index %d not in status cache\n", nIndex);
  541. if (!BuildStatus(nIndex, strStatus))
  542. {
  543. Trace0("CProviderHandler::BuildStatus failed!\n");
  544. }
  545. }
  546. switch (nCol)
  547. {
  548. case 0:
  549. return tsr.strName;
  550. break;
  551. case 1:
  552. return tsr.strUsers;
  553. break;
  554. case 2:
  555. return strStatus;
  556. break;
  557. default:
  558. Panic0("CProviderHandler::GetVirtualString - Unknown column!\n");
  559. break;
  560. }
  561. return NULL;
  562. }
  563. /*---------------------------------------------------------------------------
  564. CProviderHandler::CacheHint
  565. MMC tells us which items it will need before it requests things
  566. Author: EricDav
  567. ---------------------------------------------------------------------------*/
  568. STDMETHODIMP
  569. CProviderHandler::CacheHint
  570. (
  571. int nStartIndex,
  572. int nEndIndex
  573. )
  574. {
  575. HRESULT hr = hrOK;;
  576. Trace2("CacheHint - Start %d, End %d\n", nStartIndex, nEndIndex);
  577. // the virtual listbox stores no strings and gives us cache hints for
  578. // everything, including individual querries. To avoid thrashing, only
  579. // clear our the cache if the request is large.
  580. if ((nEndIndex - nStartIndex) > 2)
  581. {
  582. m_mapRecords.RemoveAll();
  583. }
  584. TapiStrRecord tsr;
  585. CString strStatus;
  586. for (int i = nStartIndex; i <= nEndIndex; i++)
  587. {
  588. if (!BuildTapiStrRecord(i, tsr))
  589. continue;
  590. m_mapRecords.SetAt(i, tsr);
  591. // only refresh status records if they don't exist. Only the auto refresh
  592. // background thread cleans out the map...
  593. if (!m_mapStatus.Lookup(i, strStatus))
  594. {
  595. BuildStatus(i, strStatus);
  596. m_mapStatus.SetAt(i, strStatus);
  597. }
  598. }
  599. return hr;
  600. }
  601. /*---------------------------------------------------------------------------
  602. CProviderHandler::SortItems
  603. We are responsible for sorting of virtual listbox items
  604. Author: EricDav
  605. ---------------------------------------------------------------------------*/
  606. STDMETHODIMP
  607. CProviderHandler::SortItems
  608. (
  609. int nColumn,
  610. DWORD dwSortOptions,
  611. LPARAM lUserParam
  612. )
  613. {
  614. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  615. BEGIN_WAIT_CURSOR
  616. switch (nColumn)
  617. {
  618. case 0:
  619. m_spTapiInfo->SortDeviceInfo(m_deviceType, m_dwProviderID, INDEX_TYPE_NAME, dwSortOptions);
  620. break;
  621. case 1:
  622. m_spTapiInfo->SortDeviceInfo(m_deviceType, m_dwProviderID, INDEX_TYPE_USERS, dwSortOptions);
  623. break;
  624. // case 2:
  625. // m_spTapiInfo->SortDeviceInfo(m_deviceType, m_dwProviderID, INDEX_TYPE_STATUS, dwSortOptions);
  626. // break;
  627. }
  628. END_WAIT_CURSOR
  629. return hrOK;
  630. }
  631. /*!--------------------------------------------------------------------------
  632. CProviderHandler::OnResultUpdateView
  633. Implementation of ITFSResultHandler::OnResultUpdateView
  634. Author: EricDav
  635. ---------------------------------------------------------------------------*/
  636. HRESULT CProviderHandler::OnResultUpdateView
  637. (
  638. ITFSComponent *pComponent,
  639. LPDATAOBJECT pDataObject,
  640. LPARAM data,
  641. LONG_PTR hint
  642. )
  643. {
  644. HRESULT hr = hrOK;
  645. SPITFSNode spSelectedNode;
  646. pComponent->GetSelectedNode(&spSelectedNode);
  647. if (spSelectedNode == NULL)
  648. return S_OK; // no selection for our IComponentData
  649. if ( hint == TAPISNAP_UPDATE_STATUS )
  650. {
  651. SPINTERNAL spInternal = ExtractInternalFormat(pDataObject);
  652. ITFSNode * pNode = reinterpret_cast<ITFSNode *>(spInternal->m_cookie);
  653. SPITFSNode spSelectedNode;
  654. pComponent->GetSelectedNode(&spSelectedNode);
  655. if (pNode == spSelectedNode)
  656. {
  657. Trace1("CProviderHandler::OnResultUpdateView - Provider %x is selected, invalidating listbox.\n", m_dwProviderID);
  658. // if we are the selected node, then we need to update
  659. SPIResultData spResultData;
  660. CORg (pComponent->GetResultData(&spResultData));
  661. CORg (spResultData->SetItemCount((int) data, MMCLV_UPDATE_NOSCROLL));
  662. }
  663. }
  664. else
  665. {
  666. // we don't handle this message, let the base class do it.
  667. return CTapiHandler::OnResultUpdateView(pComponent, pDataObject, data, hint);
  668. }
  669. COM_PROTECT_ERROR_LABEL;
  670. return hr;
  671. }
  672. /*!--------------------------------------------------------------------------
  673. CProviderHandler::OnResultItemClkOrDblClk
  674. The user had double clicked on a line/phone. Invoke the edit users.
  675. Author: EricDav
  676. ---------------------------------------------------------------------------*/
  677. HRESULT
  678. CProviderHandler::OnResultItemClkOrDblClk
  679. (
  680. ITFSComponent * pComponent,
  681. MMC_COOKIE cookie,
  682. LPARAM arg,
  683. LPARAM lParam,
  684. BOOL bDoubleClick
  685. )
  686. {
  687. HRESULT hr = hrOK;
  688. if (bDoubleClick)
  689. {
  690. // first check to see if we are selected
  691. SPITFSNode spSelectedNode;
  692. pComponent->GetSelectedNode(&spSelectedNode);
  693. SPITFSNode spNode;
  694. m_spResultNodeMgr->FindNode(cookie, &spNode);
  695. if (spSelectedNode == spNode)
  696. {
  697. CTapiConfigInfo tapiConfigInfo;
  698. m_spTapiInfo->GetConfigInfo(&tapiConfigInfo);
  699. // check to see if they have access rights
  700. if (m_spTapiInfo->IsAdmin() &&
  701. tapiConfigInfo.m_dwFlags & TAPISERVERCONFIGFLAGS_ISSERVER)
  702. {
  703. // double click on a line/phone entry.
  704. SPIDataObject spDataObject;
  705. CORg (pComponent->GetCurrentDataObject(&spDataObject));
  706. OnEditUsers(pComponent, spDataObject, cookie);
  707. }
  708. }
  709. else
  710. {
  711. // we are being double clicked to open
  712. // let the base class handle this
  713. return CTapiHandler::OnResultItemClkOrDblClk(pComponent, cookie, arg, lParam, bDoubleClick);
  714. }
  715. }
  716. Error:
  717. return S_OK;
  718. }
  719. /*!--------------------------------------------------------------------------
  720. CProviderHandler::LoadColumns
  721. Set the correct column header and then call the base class
  722. Author: EricDav
  723. ---------------------------------------------------------------------------*/
  724. HRESULT
  725. CProviderHandler::LoadColumns
  726. (
  727. ITFSComponent * pComponent,
  728. MMC_COOKIE cookie,
  729. LPARAM arg,
  730. LPARAM lParam
  731. )
  732. {
  733. SetColumnInfo();
  734. return CTapiHandler::LoadColumns(pComponent, cookie, arg, lParam);
  735. }
  736. /*---------------------------------------------------------------------------
  737. Command handlers
  738. ---------------------------------------------------------------------------*/
  739. /*---------------------------------------------------------------------------
  740. CProviderHandler::OnConfigureProvider
  741. Configures a service provider
  742. Author: EricDav
  743. ---------------------------------------------------------------------------*/
  744. HRESULT
  745. CProviderHandler::OnConfigureProvider
  746. (
  747. ITFSNode * pNode
  748. )
  749. {
  750. HRESULT hr = hrOK;
  751. Assert(m_spTapiInfo);
  752. hr = m_spTapiInfo->ConfigureProvider(m_dwProviderID, NULL);
  753. if (FAILED(hr))
  754. {
  755. ::TapiMessageBox(WIN32_FROM_HRESULT(hr));
  756. }
  757. return hr;
  758. }
  759. /*---------------------------------------------------------------------------
  760. CProviderHandler::OnDelete
  761. Removes a service provider
  762. Author: EricDav
  763. ---------------------------------------------------------------------------*/
  764. HRESULT
  765. CProviderHandler::OnDelete
  766. (
  767. ITFSNode * pNode
  768. )
  769. {
  770. HRESULT hr = hrOK;
  771. SPITFSNode spNode;
  772. CString strMessage;
  773. pNode->GetParent(&spNode);
  774. CTapiServer * pServer = GETHANDLER(CTapiServer, spNode);
  775. // Ask the user to make sure
  776. AfxFormatString2(strMessage, IDS_WARN_PROVIDER_DELETE, m_strProviderName, pServer->GetName());
  777. if (AfxMessageBox(strMessage, MB_YESNO) == IDYES)
  778. {
  779. Assert(m_spTapiInfo);
  780. hr = m_spTapiInfo->RemoveProvider(m_dwProviderID, NULL);
  781. if (FAILED(hr))
  782. {
  783. ::TapiMessageBox(WIN32_FROM_HRESULT(hr));
  784. }
  785. else
  786. {
  787. // remove from the UI
  788. SPITFSNode spParent;
  789. CORg (pNode->GetParent(&spParent));
  790. CORg (spParent->RemoveChild(pNode));
  791. // update the list of installed providers
  792. CORg (m_spTapiInfo->EnumProviders());
  793. }
  794. }
  795. Error:
  796. return hr;
  797. }
  798. /*---------------------------------------------------------------------------
  799. CProviderHandler::OnEditUsers
  800. Allows different users to be assigned to a device
  801. Author: EricDav
  802. ---------------------------------------------------------------------------*/
  803. HRESULT
  804. CProviderHandler::OnEditUsers
  805. (
  806. ITFSComponent * pComponent,
  807. LPDATAOBJECT pDataObject,
  808. MMC_COOKIE cookie
  809. )
  810. {
  811. SPITFSNode spNode;
  812. SPINTERNAL spInternal;
  813. int nIndex;
  814. DWORD dwFlags;
  815. CTapiDevice tapiDevice;
  816. HRESULT hr = hrOK;
  817. spInternal = ExtractInternalFormat(pDataObject);
  818. // virtual listbox notifications come to the handler of the node that is selected.
  819. // assert that this notification is for a virtual listbox item
  820. Assert(spInternal);
  821. if (!spInternal->HasVirtualIndex() || m_deviceType == DEVICE_PHONE)
  822. return hr;
  823. nIndex = spInternal->GetVirtualIndex();
  824. Trace1("OnEditUsers - edit users for index %d\n", nIndex);
  825. m_spTapiInfo->GetDeviceInfo(m_deviceType, &tapiDevice, m_dwProviderID, nIndex);
  826. // Check to see if this device can be remoted
  827. hr = m_spTapiInfo->GetDeviceFlags (
  828. tapiDevice.m_dwProviderID,
  829. tapiDevice.m_dwPermanentID,
  830. &dwFlags
  831. );
  832. if (hr || (dwFlags & LINEDEVCAPFLAGS_LOCAL))
  833. {
  834. return hr;
  835. }
  836. CEditUsers dlgEditUsers(&tapiDevice);
  837. if (dlgEditUsers.DoModal() == IDOK)
  838. {
  839. if (dlgEditUsers.IsDirty())
  840. {
  841. hr = m_spTapiInfo->SetDeviceInfo(m_deviceType, &tapiDevice);
  842. if (FAILED(hr))
  843. {
  844. TapiMessageBox(WIN32_FROM_HRESULT(hr));
  845. }
  846. else
  847. {
  848. pComponent->GetSelectedNode(&spNode);
  849. // clear the listbox then set the size
  850. UpdateListboxCount(spNode, TRUE);
  851. UpdateListboxCount(spNode);
  852. }
  853. }
  854. }
  855. return hr;
  856. }
  857. /*---------------------------------------------------------------------------
  858. CProviderHandler::UpdateStatus
  859. -
  860. Author: EricDav
  861. ---------------------------------------------------------------------------*/
  862. HRESULT
  863. CProviderHandler::UpdateStatus
  864. (
  865. ITFSNode * pNode
  866. )
  867. {
  868. HRESULT hr = hrOK;
  869. SPIComponentData spComponentData;
  870. SPIConsole spConsole;
  871. IDataObject * pDataObject;
  872. SPIDataObject spDataObject;
  873. int i = 0;
  874. Trace1("CProviderHandler::UpdateStatus - Updating status for provider %x\n", m_dwProviderID);
  875. // clear our status strings
  876. m_mapStatus.RemoveAll();
  877. // force the listbox to update. We do this by setting the count and
  878. // telling it to invalidate the data
  879. CORg(m_spNodeMgr->GetComponentData(&spComponentData));
  880. CORg(m_spNodeMgr->GetConsole(&spConsole));
  881. // grab a data object to use
  882. CORg(spComponentData->QueryDataObject((MMC_COOKIE) pNode, CCT_RESULT, &pDataObject) );
  883. spDataObject = pDataObject;
  884. i = m_spTapiInfo->GetDeviceCount(m_deviceType, m_dwProviderID);
  885. CORg(spConsole->UpdateAllViews(pDataObject, i, TAPISNAP_UPDATE_STATUS));
  886. COM_PROTECT_ERROR_LABEL;
  887. return hr;
  888. }
  889. /*---------------------------------------------------------------------------
  890. Misc functions
  891. ---------------------------------------------------------------------------*/
  892. /*---------------------------------------------------------------------------
  893. CProviderHandler::BuildDisplayName
  894. Builds the string that goes in the UI for this server
  895. Author: EricDav
  896. ---------------------------------------------------------------------------*/
  897. HRESULT
  898. CProviderHandler::BuildDisplayName
  899. (
  900. CString * pstrDisplayName
  901. )
  902. {
  903. if (pstrDisplayName)
  904. {
  905. CString strName;
  906. *pstrDisplayName = GetDisplayName();
  907. }
  908. return hrOK;
  909. }
  910. /*---------------------------------------------------------------------------
  911. CProviderHandler::InitData
  912. Initializes data for this node
  913. Author: EricDav
  914. ---------------------------------------------------------------------------*/
  915. HRESULT
  916. CProviderHandler::InitData
  917. (
  918. CTapiProvider & tapiProvider,
  919. ITapiInfo * pTapiInfo
  920. )
  921. {
  922. m_strProviderName = tapiProvider.m_strName;
  923. m_dwProviderID = tapiProvider.m_dwProviderID;
  924. m_dwFlags = tapiProvider.m_dwFlags;
  925. m_spTapiInfo.Set(pTapiInfo);
  926. SetDisplayName(m_strProviderName);
  927. return hrOK;
  928. }
  929. /*---------------------------------------------------------------------------
  930. CProviderHandler::BuildTapiStrRecord
  931. Description
  932. Author: EricDav
  933. ---------------------------------------------------------------------------*/
  934. BOOL
  935. CProviderHandler::BuildTapiStrRecord(int nIndex, TapiStrRecord & tsr)
  936. {
  937. HRESULT hr = hrOK;
  938. CTapiDevice tapiDevice;
  939. CString strTemp;
  940. int i;
  941. if (!m_spTapiInfo)
  942. return FALSE;
  943. COM_PROTECT_TRY
  944. {
  945. CORg (m_spTapiInfo->GetDeviceInfo(m_deviceType, &tapiDevice, m_dwProviderID, nIndex));
  946. // set the index for this record
  947. //tsr.nIndex = nIndex;
  948. // name
  949. tsr.strName = tapiDevice.m_strName;
  950. // users
  951. tsr.strUsers.Empty();
  952. for (i = 0; i < tapiDevice.m_arrayUsers.GetSize(); i++)
  953. {
  954. if (!tapiDevice.m_arrayUsers[i].m_strFullName.IsEmpty())
  955. {
  956. tsr.strUsers += tapiDevice.m_arrayUsers[i].m_strFullName;
  957. }
  958. else
  959. {
  960. tsr.strUsers += tapiDevice.m_arrayUsers[i].m_strName;
  961. }
  962. if ((i + 1) != tapiDevice.m_arrayUsers.GetSize())
  963. tsr.strUsers += _T(", ");
  964. }
  965. COM_PROTECT_ERROR_LABEL;
  966. }
  967. COM_PROTECT_CATCH
  968. return SUCCEEDED(hr);
  969. }
  970. /*---------------------------------------------------------------------------
  971. CProviderHandler::BuildStatus
  972. Description
  973. Author: EricDav
  974. ---------------------------------------------------------------------------*/
  975. BOOL
  976. CProviderHandler::BuildStatus(int nIndex, CString & strStatus)
  977. {
  978. HRESULT hr = hrOK;
  979. // status
  980. hr = m_spTapiInfo->GetDeviceStatus(m_deviceType, &strStatus, m_dwProviderID, nIndex, NULL);
  981. if (strStatus.IsEmpty())
  982. strStatus.LoadString(IDS_NO_STATUS);
  983. return SUCCEEDED(hr);
  984. }
  985. /*---------------------------------------------------------------------------
  986. CProviderHandler::UpdateListboxCount
  987. Description
  988. Author: EricDav
  989. ---------------------------------------------------------------------------*/
  990. HRESULT
  991. CProviderHandler::UpdateListboxCount(ITFSNode * pNode, BOOL bClear)
  992. {
  993. HRESULT hr = hrOK;
  994. SPIComponentData spCompData;
  995. SPIConsole spConsole;
  996. IDataObject* pDataObject;
  997. SPIDataObject spDataObject;
  998. LONG_PTR command;
  999. int i;
  1000. COM_PROTECT_TRY
  1001. {
  1002. if (!m_spTapiInfo || bClear)
  1003. {
  1004. command = RESULT_PANE_CLEAR_VIRTUAL_LB;
  1005. i = 0;
  1006. }
  1007. else
  1008. {
  1009. command = RESULT_PANE_SET_VIRTUAL_LB_SIZE;
  1010. i = m_spTapiInfo->GetDeviceCount(m_deviceType, m_dwProviderID);
  1011. }
  1012. m_spNodeMgr->GetComponentData(&spCompData);
  1013. CORg ( spCompData->QueryDataObject((MMC_COOKIE) pNode, CCT_RESULT, &pDataObject) );
  1014. spDataObject = pDataObject;
  1015. CORg ( m_spNodeMgr->GetConsole(&spConsole) );
  1016. CORg ( spConsole->UpdateAllViews(spDataObject, i, command) );
  1017. COM_PROTECT_ERROR_LABEL;
  1018. }
  1019. COM_PROTECT_CATCH
  1020. return hr;
  1021. }
  1022. /*---------------------------------------------------------------------------
  1023. CProviderHandler::SetColumnInfo
  1024. Description
  1025. Author: EricDav
  1026. ---------------------------------------------------------------------------*/
  1027. void
  1028. CProviderHandler::SetColumnInfo()
  1029. {
  1030. // set the correct column header
  1031. if (m_deviceType == DEVICE_LINE)
  1032. {
  1033. aColumns[TAPISNAP_PROVIDER][0] = IDS_LINE_NAME;
  1034. }
  1035. else
  1036. {
  1037. aColumns[TAPISNAP_PROVIDER][0] = IDS_PHONE_NAME;
  1038. }
  1039. }
  1040. /*---------------------------------------------------------------------------
  1041. CProviderHandler::UpdateColumnText
  1042. Description
  1043. Author: EricDav
  1044. ---------------------------------------------------------------------------*/
  1045. HRESULT
  1046. CProviderHandler::UpdateColumnText(ITFSComponent * pComponent)
  1047. {
  1048. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1049. SPIHeaderCtrl spHeaderCtrl;
  1050. pComponent->GetHeaderCtrl(&spHeaderCtrl);
  1051. CString str;
  1052. int i = 0;
  1053. while (TRUE)
  1054. {
  1055. if ( 0 == aColumns[TAPISNAP_PROVIDER][i] )
  1056. break;
  1057. str.LoadString(aColumns[TAPISNAP_PROVIDER][i]);
  1058. spHeaderCtrl->SetColumnText(i, const_cast<LPTSTR>((LPCWSTR)str));
  1059. i++;
  1060. }
  1061. return hrOK;
  1062. }
  1063. /*---------------------------------------------------------------------------
  1064. Background thread functionality
  1065. ---------------------------------------------------------------------------*/
  1066. /*---------------------------------------------------------------------------
  1067. CProviderHandler::OnCreateQuery
  1068. Description
  1069. Author: EricDav
  1070. ---------------------------------------------------------------------------*/
  1071. ITFSQueryObject*
  1072. CProviderHandler::OnCreateQuery(ITFSNode * pNode)
  1073. {
  1074. CProviderHandlerQueryObj* pQuery =
  1075. new CProviderHandlerQueryObj(m_spTFSCompData, m_spNodeMgr);
  1076. //pQuery->m_strServer = NULL;
  1077. return pQuery;
  1078. }
  1079. /*---------------------------------------------------------------------------
  1080. CProviderHandlerQueryObj::Execute()
  1081. Description
  1082. Author: EricDav
  1083. ---------------------------------------------------------------------------*/
  1084. STDMETHODIMP
  1085. CProviderHandlerQueryObj::Execute()
  1086. {
  1087. return hrFalse;
  1088. }