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.

1130 lines
31 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. server.cpp
  7. Tapi server node handler
  8. FILE HISTORY:
  9. */
  10. #include "stdafx.h"
  11. #include "server.h" // Server definition
  12. #include "provider.h"
  13. #include "servpp.h" // server property sheet
  14. #include "tapidb.h"
  15. #include "drivers.h"
  16. CTimerMgr g_TimerMgr;
  17. /////////////////////////////////////////////////////////////////////
  18. //
  19. // CTimerArray implementation
  20. //
  21. /////////////////////////////////////////////////////////////////////
  22. CTimerMgr::CTimerMgr()
  23. {
  24. }
  25. CTimerMgr::~CTimerMgr()
  26. {
  27. CTimerDesc * pTimerDesc;
  28. for (int i = (int)GetUpperBound(); i >= 0; --i)
  29. {
  30. pTimerDesc = GetAt(i);
  31. if (pTimerDesc->uTimer != 0)
  32. FreeTimer(i);
  33. delete pTimerDesc;
  34. }
  35. }
  36. int
  37. CTimerMgr::AllocateTimer
  38. (
  39. ITFSNode * pNode,
  40. CTapiServer * pServer,
  41. UINT uTimerValue,
  42. TIMERPROC TimerProc
  43. )
  44. {
  45. CSingleLock slTimerMgr(&m_csTimerMgr);
  46. // get a lock on the timer mgr for the scope of this
  47. // function.
  48. slTimerMgr.Lock();
  49. CTimerDesc * pTimerDesc = NULL;
  50. // look for an empty slot
  51. for (int i = (int)GetUpperBound(); i >= 0; --i)
  52. {
  53. pTimerDesc = GetAt(i);
  54. if (pTimerDesc->uTimer == 0)
  55. break;
  56. }
  57. // did we find one? if not allocate one
  58. if (i < 0)
  59. {
  60. pTimerDesc = new CTimerDesc;
  61. Add(pTimerDesc);
  62. i = (int)GetUpperBound();
  63. }
  64. pTimerDesc->uTimer = SetTimer(NULL, (UINT) i, uTimerValue, TimerProc);
  65. if (pTimerDesc->uTimer == 0)
  66. return -1;
  67. pTimerDesc->spNode.Set(pNode);
  68. pTimerDesc->pServer = pServer;
  69. pTimerDesc->timerProc = TimerProc;
  70. return i;
  71. }
  72. void
  73. CTimerMgr::FreeTimer
  74. (
  75. UINT_PTR uEventId
  76. )
  77. {
  78. CSingleLock slTimerMgr(&m_csTimerMgr);
  79. // get a lock on the timer mgr for the scope of this
  80. // function.
  81. slTimerMgr.Lock();
  82. CTimerDesc * pTimerDesc;
  83. Assert(uEventId <= (UINT) GetUpperBound());
  84. if (uEventId > (UINT) GetUpperBound())
  85. return;
  86. pTimerDesc = GetAt((int) uEventId);
  87. ::KillTimer(NULL, pTimerDesc->uTimer);
  88. pTimerDesc->spNode.Release();
  89. pTimerDesc->pServer = NULL;
  90. pTimerDesc->uTimer = 0;
  91. }
  92. CTimerDesc *
  93. CTimerMgr::GetTimerDesc
  94. (
  95. UINT_PTR uEventId
  96. )
  97. {
  98. CSingleLock slTimerMgr(&m_csTimerMgr);
  99. // the caller of this function should lock the timer mgr
  100. // while accessing this pointer
  101. CTimerDesc * pTimerDesc;
  102. for (int i = (int)GetUpperBound(); i >= 0; --i)
  103. {
  104. pTimerDesc = GetAt(i);
  105. if (pTimerDesc->uTimer == (UINT) uEventId)
  106. return pTimerDesc;
  107. }
  108. return NULL;
  109. }
  110. void
  111. CTimerMgr::ChangeInterval
  112. (
  113. UINT_PTR uEventId,
  114. UINT uNewInterval
  115. )
  116. {
  117. CSingleLock slTimerMgr(&m_csTimerMgr);
  118. // get a lock on the timer mgr for the scope of this
  119. // function.
  120. slTimerMgr.Lock();
  121. Assert(uEventId <= (UINT) GetUpperBound());
  122. if (uEventId > (UINT) GetUpperBound())
  123. return;
  124. CTimerDesc tempTimerDesc;
  125. CTimerDesc * pTimerDesc;
  126. pTimerDesc = GetAt((int) uEventId);
  127. // kill the old timer
  128. ::KillTimer(NULL, pTimerDesc->uTimer);
  129. // set a new one with the new interval
  130. pTimerDesc->uTimer = ::SetTimer(NULL, (UINT) uEventId, uNewInterval, pTimerDesc->timerProc);
  131. }
  132. VOID CALLBACK
  133. StatisticsTimerProc
  134. (
  135. HWND hwnd,
  136. UINT uMsg,
  137. UINT_PTR idEvent,
  138. DWORD dwTime
  139. )
  140. {
  141. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  142. CSingleLock slTimerMgr(&g_TimerMgr.m_csTimerMgr);
  143. // get a lock on the timer mgr for the scope of this
  144. // function.
  145. slTimerMgr.Lock();
  146. // on the timer, get the timer descriptor for this event
  147. // Call into the appropriate handler to update the stats.
  148. CTimerDesc * pTimerDesc;
  149. pTimerDesc = g_TimerMgr.GetTimerDesc(idEvent);
  150. pTimerDesc->pServer->m_bStatsOnly = TRUE;
  151. pTimerDesc->pServer->OnRefreshStats(pTimerDesc->spNode,
  152. NULL,
  153. NULL,
  154. 0,
  155. 0);
  156. pTimerDesc->pServer->m_bStatsOnly = FALSE;
  157. }
  158. /*---------------------------------------------------------------------------
  159. Class CTapiServer implementation
  160. ---------------------------------------------------------------------------*/
  161. /*--------------------------------------------------------------------------
  162. Constructor and destructor
  163. Description
  164. Author: EricDav
  165. ---------------------------------------------------------------------------*/
  166. CTapiServer::CTapiServer
  167. (
  168. ITFSComponentData * pComponentData
  169. ) : CMTTapiHandler(pComponentData),
  170. m_bStatsOnly(FALSE),
  171. m_StatsTimerId(-1),
  172. m_dwOptions(0)
  173. {
  174. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  175. }
  176. CTapiServer::~CTapiServer()
  177. {
  178. }
  179. /*!--------------------------------------------------------------------------
  180. CTapiServer::InitializeNode
  181. Initializes node specific data
  182. Author: EricDav
  183. ---------------------------------------------------------------------------*/
  184. HRESULT
  185. CTapiServer::InitializeNode
  186. (
  187. ITFSNode * pNode
  188. )
  189. {
  190. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  191. HRESULT hr = hrOK;
  192. CString strTemp;
  193. COM_PROTECT_TRY
  194. {
  195. CORg (CreateTapiInfo(&m_spTapiInfo));
  196. BuildDisplayName(&strTemp);
  197. SetDisplayName(strTemp);
  198. // Make the node immediately visible
  199. pNode->SetVisibilityState(TFS_VIS_SHOW);
  200. pNode->SetData(TFS_DATA_COOKIE, (LPARAM) pNode);
  201. pNode->SetData(TFS_DATA_IMAGEINDEX, ICON_IDX_SERVER);
  202. pNode->SetData(TFS_DATA_OPENIMAGEINDEX, ICON_IDX_SERVER);
  203. pNode->SetData(TFS_DATA_USER, (LPARAM) this);
  204. pNode->SetData(TFS_DATA_TYPE, TAPISNAP_SERVER);
  205. SetColumnStringIDs(&aColumns[TAPISNAP_SERVER][0]);
  206. SetColumnWidths(&aColumnWidths[TAPISNAP_SERVER][0]);
  207. COM_PROTECT_ERROR_LABEL;
  208. }
  209. COM_PROTECT_CATCH
  210. return hr;
  211. }
  212. /*---------------------------------------------------------------------------
  213. CTapiServer::OnCreateNodeId2
  214. Returns a unique string for this node
  215. Author: EricDav
  216. ---------------------------------------------------------------------------*/
  217. HRESULT CTapiServer::OnCreateNodeId2(ITFSNode * pNode, CString & strId, DWORD * dwFlags)
  218. {
  219. const GUID * pGuid = pNode->GetNodeType();
  220. CString strGuid;
  221. StringFromGUID2(*pGuid, strGuid.GetBuffer(256), 256);
  222. strGuid.ReleaseBuffer();
  223. strId = GetName() + strGuid;
  224. return hrOK;
  225. }
  226. /*---------------------------------------------------------------------------
  227. CTapiServer::GetImageIndex
  228. -
  229. Author: EricDav
  230. ---------------------------------------------------------------------------*/
  231. int
  232. CTapiServer::GetImageIndex(BOOL bOpenImage)
  233. {
  234. int nIndex = -1;
  235. switch (m_nState)
  236. {
  237. case notLoaded:
  238. nIndex = ICON_IDX_SERVER;
  239. break;
  240. case loading:
  241. nIndex = ICON_IDX_SERVER_BUSY;
  242. break;
  243. case loaded:
  244. nIndex = ICON_IDX_SERVER_CONNECTED;
  245. break;
  246. case unableToLoad:
  247. nIndex = ICON_IDX_SERVER_LOST_CONNECTION;
  248. break;
  249. default:
  250. ASSERT(FALSE);
  251. }
  252. return nIndex;
  253. }
  254. /*---------------------------------------------------------------------------
  255. CTapiServer::OnHaveData
  256. When the background thread enumerates nodes to be added to the UI,
  257. we get called back here. We override this to force expansion of the
  258. node so that things show up correctly.
  259. Author: EricDav
  260. ---------------------------------------------------------------------------*/
  261. void
  262. CTapiServer::OnHaveData
  263. (
  264. ITFSNode * pParentNode,
  265. ITFSNode * pNewNode
  266. )
  267. {
  268. CMTTapiHandler::OnHaveData(pParentNode, pNewNode);
  269. ExpandNode(pParentNode, TRUE);
  270. }
  271. /*---------------------------------------------------------------------------
  272. CTapiServer::OnHaveData
  273. Description
  274. Author: EricDav
  275. ---------------------------------------------------------------------------*/
  276. void
  277. CTapiServer::OnHaveData
  278. (
  279. ITFSNode * pParentNode,
  280. DWORD dwData,
  281. DWORD dwType
  282. )
  283. {
  284. HRESULT hr = hrOK;
  285. // This is how we get non-node data back from the background thread.
  286. switch (dwType)
  287. {
  288. case TAPI_QDATA_REFRESH_STATS:
  289. {
  290. // tell all of the provider nodes to clear their status caches
  291. // if any of the nodes is the selected node, then they should
  292. // repaint the window
  293. SPITFSNodeEnum spNodeEnum;
  294. SPITFSNode spCurrentNode;
  295. ULONG nNumReturned;
  296. CORg(pParentNode->GetEnum(&spNodeEnum));
  297. CORg(spNodeEnum->Next(1, &spCurrentNode, &nNumReturned));
  298. while (nNumReturned)
  299. {
  300. if (spCurrentNode->GetData(TFS_DATA_TYPE) == TAPISNAP_PROVIDER)
  301. {
  302. CProviderHandler * pProvider = GETHANDLER(CProviderHandler, spCurrentNode);
  303. pProvider->UpdateStatus(spCurrentNode);
  304. }
  305. spCurrentNode.Release();
  306. spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
  307. }
  308. break;
  309. }
  310. }
  311. COM_PROTECT_ERROR_LABEL;
  312. }
  313. /*---------------------------------------------------------------------------
  314. Overridden base handler functions
  315. ---------------------------------------------------------------------------*/
  316. /*---------------------------------------------------------------------------
  317. CTapiServer::OnAddMenuItems
  318. Description
  319. Author: EricDav
  320. ---------------------------------------------------------------------------*/
  321. STDMETHODIMP
  322. CTapiServer::OnAddMenuItems
  323. (
  324. ITFSNode * pNode,
  325. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  326. LPDATAOBJECT lpDataObject,
  327. DATA_OBJECT_TYPES type,
  328. DWORD dwType,
  329. long * pInsertionAllowed
  330. )
  331. {
  332. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  333. LONG fFlags = 0;
  334. HRESULT hr = S_OK;
  335. CString strMenuItem;
  336. if (m_nState != loaded || !m_spTapiInfo->IsLocalMachine() || !m_spTapiInfo->IsAdmin())
  337. {
  338. fFlags |= MF_GRAYED;
  339. }
  340. if (type == CCT_SCOPE)
  341. {
  342. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP)
  343. {
  344. strMenuItem.LoadString(IDS_ADD_PROVIDER);
  345. hr = LoadAndAddMenuItem( pContextMenuCallback,
  346. strMenuItem,
  347. IDS_ADD_PROVIDER,
  348. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  349. fFlags );
  350. ASSERT( SUCCEEDED(hr) );
  351. }
  352. }
  353. return hr;
  354. }
  355. /*---------------------------------------------------------------------------
  356. CTapiServer::OnCommand
  357. Description
  358. Author: EricDav
  359. ---------------------------------------------------------------------------*/
  360. STDMETHODIMP
  361. CTapiServer::OnCommand
  362. (
  363. ITFSNode * pNode,
  364. long nCommandId,
  365. DATA_OBJECT_TYPES type,
  366. LPDATAOBJECT pDataObject,
  367. DWORD dwType
  368. )
  369. {
  370. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  371. HRESULT hr = S_OK;
  372. switch (nCommandId)
  373. {
  374. case IDS_ADD_PROVIDER:
  375. OnAddProvider(pNode);
  376. break;
  377. default:
  378. break;
  379. }
  380. return hr;
  381. }
  382. /*!--------------------------------------------------------------------------
  383. CTapiServer::HasPropertyPages
  384. Implementation of ITFSNodeHandler::HasPropertyPages
  385. NOTE: the root node handler has to over-ride this function to
  386. handle the snapin manager property page (wizard) case!!!
  387. Author: KennT
  388. ---------------------------------------------------------------------------*/
  389. STDMETHODIMP
  390. CTapiServer::HasPropertyPages
  391. (
  392. ITFSNode * pNode,
  393. LPDATAOBJECT pDataObject,
  394. DATA_OBJECT_TYPES type,
  395. DWORD dwType
  396. )
  397. {
  398. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  399. HRESULT hr = hrOK;
  400. if (dwType & TFS_COMPDATA_CREATE)
  401. {
  402. // This is the case where we are asked to bring up property
  403. // pages when the user is adding a new snapin. These calls
  404. // are forwarded to the root node to handle. Only for the root node
  405. hr = hrOK;
  406. Assert(FALSE); // should never get here
  407. }
  408. else
  409. {
  410. // we have property pages in the normal case, but don't put the
  411. // menu up if we are not loaded yet
  412. if ( (m_nState == loaded) ||
  413. (m_nState == unableToLoad) )
  414. {
  415. hr = hrOK;
  416. }
  417. else
  418. {
  419. hr = hrFalse;
  420. }
  421. }
  422. return hr;
  423. }
  424. /*---------------------------------------------------------------------------
  425. CTapiServer::CreatePropertyPages
  426. Description
  427. Author: EricDav
  428. ---------------------------------------------------------------------------*/
  429. STDMETHODIMP
  430. CTapiServer::CreatePropertyPages
  431. (
  432. ITFSNode * pNode,
  433. LPPROPERTYSHEETCALLBACK lpProvider,
  434. LPDATAOBJECT pDataObject,
  435. LONG_PTR handle,
  436. DWORD dwType
  437. )
  438. {
  439. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  440. //
  441. // Create the property page
  442. //
  443. SPIComponentData spComponentData;
  444. m_spNodeMgr->GetComponentData(&spComponentData);
  445. CServerProperties * pServerProp = new CServerProperties(pNode, spComponentData, m_spTFSCompData, m_spTapiInfo, NULL, loaded == m_nState);
  446. pServerProp->m_strMachineName = m_strServerAddress;
  447. // fill in the auto refresh info
  448. pServerProp->m_pageRefresh.m_dwRefreshInterval = GetAutoRefreshInterval();
  449. pServerProp->m_pageRefresh.m_bAutoRefresh = GetOptions() & TAPISNAP_OPTIONS_REFRESH ? TRUE : FALSE;
  450. // initialze the service information
  451. if (!pServerProp->FInit())
  452. {
  453. delete pServerProp;
  454. return E_FAIL;
  455. }
  456. //
  457. // Object gets deleted when the page is destroyed
  458. //
  459. Assert(lpProvider != NULL);
  460. return pServerProp->CreateModelessSheet(lpProvider, handle);
  461. }
  462. /*---------------------------------------------------------------------------
  463. CTapiServer::OnPropertyChange
  464. Description
  465. Author: EricDav
  466. ---------------------------------------------------------------------------*/
  467. HRESULT
  468. CTapiServer::OnPropertyChange
  469. (
  470. ITFSNode * pNode,
  471. LPDATAOBJECT pDataobject,
  472. DWORD dwType,
  473. LPARAM arg,
  474. LPARAM lParam
  475. )
  476. {
  477. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  478. CServerProperties * pServerProp = reinterpret_cast<CServerProperties *>(lParam);
  479. LONG_PTR changeMask = 0;
  480. // tell the property page to do whatever now that we are back on the
  481. // main thread
  482. pServerProp->OnPropertyChange(TRUE, &changeMask);
  483. pServerProp->AcknowledgeNotify();
  484. if (changeMask)
  485. pNode->ChangeNode(changeMask);
  486. return hrOK;
  487. }
  488. /*!--------------------------------------------------------------------------
  489. CTapiServer::OnDelete
  490. The base handler calls this when MMC sends a MMCN_DELETE for a
  491. scope pane item. We just call our delete command handler.
  492. Author: EricDav
  493. ---------------------------------------------------------------------------*/
  494. HRESULT
  495. CTapiServer::OnDelete
  496. (
  497. ITFSNode * pNode,
  498. LPARAM arg,
  499. LPARAM lParam
  500. )
  501. {
  502. return OnDelete(pNode);
  503. }
  504. /*!--------------------------------------------------------------------------
  505. CTapiServer::OnNotifyExiting
  506. We override this for the server node because we don't want the
  507. icon to change when the thread goes away. Normal behavior is that
  508. the node's icon changes to a wait cursor when the background thread
  509. is running. If we are only doing stats collection, then we
  510. don't want the icon to change.
  511. Author: EricDav
  512. ---------------------------------------------------------------------------*/
  513. HRESULT
  514. CTapiServer::OnNotifyExiting
  515. (
  516. LPARAM lParam
  517. )
  518. {
  519. CTapiServerQueryObj * pQuery = (CTapiServerQueryObj *) lParam;
  520. if (!pQuery->m_bStatsOnly)
  521. OnChangeState(m_spNode);
  522. ReleaseThreadHandler();
  523. Unlock();
  524. return hrOK;
  525. }
  526. /*---------------------------------------------------------------------------
  527. Command handlers
  528. ---------------------------------------------------------------------------*/
  529. /*!--------------------------------------------------------------------------
  530. CTapiServer::OnRefresh
  531. Default implementation for the refresh functionality
  532. Author: EricDav
  533. ---------------------------------------------------------------------------*/
  534. HRESULT
  535. CTapiServer::OnRefresh
  536. (
  537. ITFSNode * pNode,
  538. LPDATAOBJECT pDataObject,
  539. DWORD dwType,
  540. LPARAM arg,
  541. LPARAM param
  542. )
  543. {
  544. m_spTapiInfo->Destroy();
  545. return CMTHandler::OnRefresh(pNode, pDataObject, dwType, arg, param);
  546. }
  547. /*!--------------------------------------------------------------------------
  548. CTapiServer::OnRefreshStats
  549. Default implementation for the Stats refresh functionality
  550. Author: EricDav
  551. ---------------------------------------------------------------------------*/
  552. HRESULT
  553. CTapiServer::OnRefreshStats
  554. (
  555. ITFSNode * pNode,
  556. LPDATAOBJECT pDataObject,
  557. DWORD dwType,
  558. LPARAM arg,
  559. LPARAM param
  560. )
  561. {
  562. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  563. HRESULT hr = hrOK;
  564. SPITFSNode spNode;
  565. SPITFSNodeHandler spHandler;
  566. ITFSQueryObject * pQuery = NULL;
  567. if (m_bExpanded == FALSE)
  568. {
  569. // we cannot get statistics if the node hasn't been expanded yet
  570. return hr;
  571. }
  572. // only do stats refresh if the server was loaded correctly.
  573. if (m_nState != loaded)
  574. return hr;
  575. BOOL bLocked = IsLocked();
  576. if (bLocked)
  577. {
  578. // cannot refresh stats if this node is locked
  579. return hr;
  580. }
  581. Lock();
  582. //OnChangeState(pNode);
  583. pQuery = OnCreateQuery(pNode);
  584. Assert(pQuery);
  585. // notify the UI to change icon, if needed
  586. //Verify(SUCCEEDED(pComponentData->ChangeNode(this, SCOPE_PANE_CHANGE_ITEM_ICON)));
  587. Verify(StartBackgroundThread(pNode, m_spTFSCompData->GetHiddenWnd(), pQuery));
  588. pQuery->Release();
  589. return hrOK;
  590. }
  591. /*---------------------------------------------------------------------------
  592. CTapiServer::OnAddProvider()
  593. Description
  594. Author: EricDav
  595. ---------------------------------------------------------------------------*/
  596. HRESULT
  597. CTapiServer::OnAddProvider(ITFSNode * pNode)
  598. {
  599. CDriverSetup dlgDrivers(pNode, m_spTapiInfo);
  600. dlgDrivers.DoModal();
  601. if (dlgDrivers.m_fDriverAdded)
  602. {
  603. OnRefresh(pNode, NULL, 0, NULL, NULL);
  604. }
  605. return hrOK;
  606. }
  607. /*---------------------------------------------------------------------------
  608. CTapiServer::OnDelete()
  609. Description
  610. Author: EricDav
  611. ---------------------------------------------------------------------------*/
  612. HRESULT
  613. CTapiServer::OnDelete(ITFSNode * pNode)
  614. {
  615. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  616. HRESULT hr = S_OK;
  617. CString strMessage;
  618. AfxFormatString1(strMessage, IDS_WARN_SERVER_DELETE, m_strServerAddress);
  619. if (AfxMessageBox(strMessage, MB_YESNO) == IDYES)
  620. {
  621. // remove this node from the list, there's nothing we need to tell
  622. // the server, it's just our local list of servers
  623. SPITFSNode spParent;
  624. pNode->GetParent(&spParent);
  625. spParent->RemoveChild(pNode);
  626. }
  627. return hr;
  628. }
  629. /*---------------------------------------------------------------------------
  630. CTapiServer::RemoveProvider()
  631. Removes a provider from the scope pane - UI only
  632. Author: EricDav
  633. ---------------------------------------------------------------------------*/
  634. HRESULT
  635. CTapiServer::RemoveProvider(ITFSNode * pNode, DWORD dwProviderID)
  636. {
  637. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  638. HRESULT hr = S_OK;
  639. SPITFSNodeEnum spNodeEnum;
  640. SPITFSNode spCurrentNode;
  641. ULONG nNumReturned;
  642. CORg(pNode->GetEnum(&spNodeEnum));
  643. CORg(spNodeEnum->Next(1, &spCurrentNode, &nNumReturned));
  644. while (nNumReturned)
  645. {
  646. if (spCurrentNode->GetData(TFS_DATA_TYPE) == TAPISNAP_PROVIDER)
  647. {
  648. CProviderHandler * pProvider = GETHANDLER(CProviderHandler, spCurrentNode);
  649. if (dwProviderID == pProvider->GetID())
  650. {
  651. pNode->RemoveChild(spCurrentNode);
  652. break;
  653. }
  654. }
  655. spCurrentNode.Release();
  656. spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
  657. }
  658. Error:
  659. return hr;
  660. }
  661. /*---------------------------------------------------------------------------
  662. CTapiServer::AddProvider()
  663. Adds a provider from the scope pane - UI only
  664. Author: EricDav
  665. ---------------------------------------------------------------------------*/
  666. HRESULT
  667. CTapiServer::AddProvider(ITFSNode * pNode, CTapiProvider * pProvider)
  668. {
  669. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  670. HRESULT hr = hrOK;
  671. SPITFSNode spProviderNode;
  672. CProviderHandler *pProviderHandler = new CProviderHandler(m_spTFSCompData);
  673. CreateContainerTFSNode(&spProviderNode,
  674. &GUID_TapiProviderNodeType,
  675. pProviderHandler,
  676. pProviderHandler,
  677. m_spNodeMgr);
  678. // Tell the handler to initialize any specific data
  679. pProviderHandler->InitData(*pProvider, m_spTapiInfo);
  680. pProviderHandler->InitializeNode(spProviderNode);
  681. pNode->AddChild(spProviderNode);
  682. pProviderHandler->Release();
  683. return hr;
  684. }
  685. DWORD CTapiServer::GetCachedLineBuffSize()
  686. {
  687. return m_spTapiInfo->GetCachedLineBuffSize();
  688. }
  689. VOID CTapiServer::SetCachedLineBuffSize(DWORD dwLineSize)
  690. {
  691. m_spTapiInfo->SetCachedLineBuffSize(dwLineSize);
  692. }
  693. DWORD CTapiServer::GetCachedPhoneBuffSize()
  694. {
  695. return m_spTapiInfo->GetCachedPhoneBuffSize();
  696. }
  697. VOID CTapiServer::SetCachedPhoneBuffSize(DWORD dwPhoneSize)
  698. {
  699. m_spTapiInfo->SetCachedPhoneBuffSize(dwPhoneSize);
  700. }
  701. BOOL CTapiServer::IsCacheDirty()
  702. {
  703. return m_spTapiInfo->IsCacheDirty();
  704. }
  705. /*---------------------------------------------------------------------------
  706. Server manipulation functions
  707. ---------------------------------------------------------------------------*/
  708. /*---------------------------------------------------------------------------
  709. CTapiServer::BuildDisplayName
  710. Builds the string that goes in the UI for this server
  711. Author: EricDav
  712. ---------------------------------------------------------------------------*/
  713. HRESULT
  714. CTapiServer::BuildDisplayName
  715. (
  716. CString * pstrDisplayName
  717. )
  718. {
  719. if (pstrDisplayName)
  720. {
  721. *pstrDisplayName = GetName();
  722. }
  723. return hrOK;
  724. }
  725. /*---------------------------------------------------------------------------
  726. CTapiServer::SetAutoRefresh
  727. Description
  728. Author: EricDav
  729. ---------------------------------------------------------------------------*/
  730. HRESULT
  731. CTapiServer::SetAutoRefresh
  732. (
  733. ITFSNode * pNode,
  734. BOOL bOn,
  735. DWORD dwRefreshInterval
  736. )
  737. {
  738. BOOL bCurrentAutoRefresh = IsAutoRefreshEnabled();
  739. if (bCurrentAutoRefresh &&
  740. !bOn)
  741. {
  742. // turning off the timer
  743. g_TimerMgr.FreeTimer(m_StatsTimerId);
  744. }
  745. else
  746. if (!bCurrentAutoRefresh &&
  747. bOn)
  748. {
  749. // gotta turn on the timer
  750. m_StatsTimerId = g_TimerMgr.AllocateTimer(pNode, this, dwRefreshInterval, StatisticsTimerProc);
  751. }
  752. else
  753. if (bOn &&
  754. m_dwRefreshInterval != dwRefreshInterval)
  755. {
  756. // time to change the timer
  757. g_TimerMgr.ChangeInterval(m_StatsTimerId, dwRefreshInterval);
  758. }
  759. if (bOn)
  760. m_dwOptions |= TAPISNAP_OPTIONS_REFRESH;
  761. else
  762. m_dwOptions &= ~TAPISNAP_OPTIONS_REFRESH;
  763. m_dwRefreshInterval = dwRefreshInterval;
  764. return hrOK;
  765. }
  766. /*---------------------------------------------------------------------------
  767. CTapiServer::SetAutoRefresh
  768. Description
  769. Author: EricDav
  770. ---------------------------------------------------------------------------*/
  771. void
  772. CTapiServer::SetExtensionName()
  773. {
  774. CString strName;
  775. strName.LoadString(IDS_TELEPHONY);
  776. SetDisplayName(strName);
  777. }
  778. /*!--------------------------------------------------------------------------
  779. CTapiServer::UpdateStandardVerbs
  780. Updates the standard verbs depending upon the state of the node
  781. Author: EricDav
  782. ---------------------------------------------------------------------------*/
  783. void
  784. CTapiServer::UpdateConsoleVerbs
  785. (
  786. IConsoleVerb * pConsoleVerb,
  787. LONG_PTR dwNodeType,
  788. BOOL bMultiSelect
  789. )
  790. {
  791. BOOL bStates[ARRAYLEN(g_ConsoleVerbs)];
  792. MMC_BUTTON_STATE * ButtonState;
  793. int i;
  794. if (bMultiSelect)
  795. {
  796. ButtonState = g_ConsoleVerbStatesMultiSel[dwNodeType];
  797. for (i = 0; i < ARRAYLEN(g_ConsoleVerbs); bStates[i++] = TRUE);
  798. }
  799. else
  800. {
  801. ButtonState = g_ConsoleVerbStates[dwNodeType];
  802. switch (m_nState)
  803. {
  804. case loaded:
  805. for (i = 0; i < ARRAYLEN(g_ConsoleVerbs); bStates[i++] = TRUE);
  806. break;
  807. case notLoaded:
  808. case loading:
  809. for (i = 0; i < ARRAYLEN(g_ConsoleVerbs); bStates[i++] = FALSE);
  810. break;
  811. case unableToLoad:
  812. for (i = 0; i < ARRAYLEN(g_ConsoleVerbs); bStates[i++] = FALSE);
  813. bStates[MMC_VERB_REFRESH & 0x000F] = TRUE;
  814. bStates[MMC_VERB_DELETE & 0x000F] = TRUE;
  815. bStates[MMC_VERB_PROPERTIES & 0x000F] = TRUE;
  816. break;
  817. }
  818. }
  819. EnableVerbs(pConsoleVerb, ButtonState, bStates);
  820. }
  821. /*---------------------------------------------------------------------------
  822. Background thread functionality
  823. ---------------------------------------------------------------------------*/
  824. /*---------------------------------------------------------------------------
  825. CTapiServer::OnCreateQuery
  826. Description
  827. Author: EricDav
  828. ---------------------------------------------------------------------------*/
  829. ITFSQueryObject*
  830. CTapiServer::OnCreateQuery(ITFSNode * pNode)
  831. {
  832. CTapiServerQueryObj* pQuery =
  833. new CTapiServerQueryObj(m_spTFSCompData, m_spNodeMgr);
  834. pQuery->m_strServer = GetName();
  835. pQuery->m_spTapiInfo.Set(m_spTapiInfo);
  836. pQuery->m_bStatsOnly = m_bStatsOnly;
  837. return pQuery;
  838. }
  839. /*---------------------------------------------------------------------------
  840. CTapiServerQueryObj::Execute()
  841. Description
  842. Author: EricDav
  843. ---------------------------------------------------------------------------*/
  844. STDMETHODIMP
  845. CTapiServerQueryObj::Execute()
  846. {
  847. HRESULT hr;
  848. if (m_bStatsOnly)
  849. {
  850. // we post this message esentially to get back on the main thread
  851. // so that we can update the UI
  852. AddToQueue(NULL, TAPI_QDATA_REFRESH_STATS);
  853. return hrFalse;
  854. }
  855. m_spTapiInfo->SetComputerName(m_strServer);
  856. // close the connection with the server if there is one
  857. m_spTapiInfo->Destroy();
  858. // reset state
  859. m_spTapiInfo->Reset();
  860. hr = m_spTapiInfo->Initialize();
  861. if (FAILED(hr))
  862. {
  863. Trace1("CTapiServerQueryObj::Execute() - Initialize failed! %lx\n", hr);
  864. PostError(WIN32_FROM_HRESULT(hr));
  865. return hrFalse;
  866. }
  867. hr = m_spTapiInfo->EnumProviders();
  868. if (FAILED(hr))
  869. {
  870. Trace1("CTapiServerQueryObj::Execute() - EnumProviders failed! %lx\n", hr);
  871. PostError(WIN32_FROM_HRESULT(hr));
  872. return hrFalse;
  873. }
  874. else
  875. {
  876. hr = m_spTapiInfo->EnumAvailableProviders();
  877. if (FAILED(hr))
  878. {
  879. Trace1("CTapiServerQueryObj::Execute() - EnumAvailableProviders failed! %lx\n", hr);
  880. PostError(WIN32_FROM_HRESULT(hr));
  881. return hrFalse;
  882. }
  883. else
  884. {
  885. }
  886. }
  887. CTapiConfigInfo tapiConfigInfo;
  888. hr = m_spTapiInfo->EnumConfigInfo();
  889. if (FAILED(hr))
  890. {
  891. Trace1("CTapiServerQueryObj::Execute() - EnumConfigInfo failed! %lx\n", hr);
  892. PostError(WIN32_FROM_HRESULT(hr));
  893. return hrFalse;
  894. }
  895. else
  896. {
  897. }
  898. hr = m_spTapiInfo->EnumDevices(DEVICE_LINE);
  899. if (FAILED(hr))
  900. {
  901. Trace1("CTapiServerQueryObj::Execute() - EnumDevices(DEVICE_LINE) failed! %lx\n", hr);
  902. PostError(WIN32_FROM_HRESULT(hr));
  903. return hrFalse;
  904. }
  905. else
  906. {
  907. }
  908. hr = m_spTapiInfo->EnumDevices(DEVICE_PHONE);
  909. if (FAILED(hr))
  910. {
  911. Trace1("CTapiServerQueryObj::Execute() - EnumDevices(DEVICE_PHONE) failed! %lx\n", hr);
  912. PostError(WIN32_FROM_HRESULT(hr));
  913. return hrFalse;
  914. }
  915. else
  916. {
  917. }
  918. //
  919. for (int i = 0; i < m_spTapiInfo->GetProviderCount(); i++)
  920. {
  921. CTapiProvider tapiProvider;
  922. SPITFSNode spProviderNode;
  923. CProviderHandler *pProviderHandler = new CProviderHandler(m_spTFSCompData);
  924. CreateContainerTFSNode(&spProviderNode,
  925. &GUID_TapiProviderNodeType,
  926. pProviderHandler,
  927. pProviderHandler,
  928. m_spNodeMgr);
  929. // Tell the handler to initialize any specific data
  930. m_spTapiInfo->GetProviderInfo(&tapiProvider, i);
  931. pProviderHandler->InitData(tapiProvider, m_spTapiInfo);
  932. pProviderHandler->InitializeNode(spProviderNode);
  933. AddToQueue(spProviderNode);
  934. pProviderHandler->Release();
  935. }
  936. return hrFalse;
  937. }