1131 lines
30 KiB
C++
1131 lines
30 KiB
C++
/**********************************************************************/
|
|
/** Microsoft Windows/NT **/
|
|
/** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
|
|
/**********************************************************************/
|
|
|
|
/*
|
|
server.cpp
|
|
Tapi server node handler
|
|
|
|
FILE HISTORY:
|
|
|
|
*/
|
|
|
|
#include "stdafx.h"
|
|
#include "server.h" // Server definition
|
|
#include "provider.h"
|
|
#include "servpp.h" // server property sheet
|
|
#include "tapidb.h"
|
|
#include "drivers.h"
|
|
|
|
CTimerMgr g_TimerMgr;
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CTimerArray implementation
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CTimerMgr::CTimerMgr()
|
|
{
|
|
|
|
}
|
|
|
|
CTimerMgr::~CTimerMgr()
|
|
{
|
|
CTimerDesc * pTimerDesc;
|
|
|
|
for (int i = (int)GetUpperBound(); i >= 0; --i)
|
|
{
|
|
pTimerDesc = GetAt(i);
|
|
if (pTimerDesc->uTimer != 0)
|
|
FreeTimer(i);
|
|
|
|
delete pTimerDesc;
|
|
}
|
|
|
|
}
|
|
|
|
int
|
|
CTimerMgr::AllocateTimer
|
|
(
|
|
ITFSNode * pNode,
|
|
CTapiServer * pServer,
|
|
UINT uTimerValue,
|
|
TIMERPROC TimerProc
|
|
)
|
|
{
|
|
CSingleLock slTimerMgr(&m_csTimerMgr);
|
|
|
|
// get a lock on the timer mgr for the scope of this
|
|
// function.
|
|
slTimerMgr.Lock();
|
|
|
|
CTimerDesc * pTimerDesc = NULL;
|
|
|
|
// look for an empty slot
|
|
for (int i = (int)GetUpperBound(); i >= 0; --i)
|
|
{
|
|
pTimerDesc = GetAt(i);
|
|
if (pTimerDesc->uTimer == 0)
|
|
break;
|
|
}
|
|
|
|
// did we find one? if not allocate one
|
|
if (i < 0)
|
|
{
|
|
pTimerDesc = new CTimerDesc;
|
|
Add(pTimerDesc);
|
|
i = (int)GetUpperBound();
|
|
}
|
|
|
|
pTimerDesc->uTimer = SetTimer(NULL, (UINT) i, uTimerValue, TimerProc);
|
|
if (pTimerDesc->uTimer == 0)
|
|
return -1;
|
|
|
|
pTimerDesc->spNode.Set(pNode);
|
|
pTimerDesc->pServer = pServer;
|
|
pTimerDesc->timerProc = TimerProc;
|
|
|
|
return i;
|
|
}
|
|
|
|
void
|
|
CTimerMgr::FreeTimer
|
|
(
|
|
UINT_PTR uEventId
|
|
)
|
|
{
|
|
CSingleLock slTimerMgr(&m_csTimerMgr);
|
|
|
|
// get a lock on the timer mgr for the scope of this
|
|
// function.
|
|
slTimerMgr.Lock();
|
|
|
|
CTimerDesc * pTimerDesc;
|
|
|
|
Assert(uEventId <= (UINT) GetUpperBound());
|
|
if (uEventId > (UINT) GetUpperBound())
|
|
return;
|
|
|
|
pTimerDesc = GetAt((int) uEventId);
|
|
::KillTimer(NULL, pTimerDesc->uTimer);
|
|
|
|
pTimerDesc->spNode.Release();
|
|
pTimerDesc->pServer = NULL;
|
|
pTimerDesc->uTimer = 0;
|
|
}
|
|
|
|
CTimerDesc *
|
|
CTimerMgr::GetTimerDesc
|
|
(
|
|
UINT_PTR uEventId
|
|
)
|
|
{
|
|
CSingleLock slTimerMgr(&m_csTimerMgr);
|
|
|
|
// the caller of this function should lock the timer mgr
|
|
// while accessing this pointer
|
|
CTimerDesc * pTimerDesc;
|
|
|
|
for (int i = (int)GetUpperBound(); i >= 0; --i)
|
|
{
|
|
pTimerDesc = GetAt(i);
|
|
if (pTimerDesc->uTimer == (UINT) uEventId)
|
|
return pTimerDesc;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void
|
|
CTimerMgr::ChangeInterval
|
|
(
|
|
UINT_PTR uEventId,
|
|
UINT uNewInterval
|
|
)
|
|
{
|
|
CSingleLock slTimerMgr(&m_csTimerMgr);
|
|
|
|
// get a lock on the timer mgr for the scope of this
|
|
// function.
|
|
slTimerMgr.Lock();
|
|
|
|
Assert(uEventId <= (UINT) GetUpperBound());
|
|
if (uEventId > (UINT) GetUpperBound())
|
|
return;
|
|
|
|
CTimerDesc tempTimerDesc;
|
|
CTimerDesc * pTimerDesc;
|
|
|
|
pTimerDesc = GetAt((int) uEventId);
|
|
|
|
// kill the old timer
|
|
::KillTimer(NULL, pTimerDesc->uTimer);
|
|
|
|
// set a new one with the new interval
|
|
pTimerDesc->uTimer = ::SetTimer(NULL, (UINT) uEventId, uNewInterval, pTimerDesc->timerProc);
|
|
}
|
|
|
|
VOID CALLBACK
|
|
StatisticsTimerProc
|
|
(
|
|
HWND hwnd,
|
|
UINT uMsg,
|
|
UINT_PTR idEvent,
|
|
DWORD dwTime
|
|
)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
CSingleLock slTimerMgr(&g_TimerMgr.m_csTimerMgr);
|
|
|
|
// get a lock on the timer mgr for the scope of this
|
|
// function.
|
|
slTimerMgr.Lock();
|
|
|
|
// on the timer, get the timer descriptor for this event
|
|
// Call into the appropriate handler to update the stats.
|
|
CTimerDesc * pTimerDesc;
|
|
|
|
pTimerDesc = g_TimerMgr.GetTimerDesc(idEvent);
|
|
|
|
pTimerDesc->pServer->m_bStatsOnly = TRUE;
|
|
pTimerDesc->pServer->OnRefreshStats(pTimerDesc->spNode,
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
0);
|
|
pTimerDesc->pServer->m_bStatsOnly = FALSE;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
Class CTapiServer implementation
|
|
---------------------------------------------------------------------------*/
|
|
|
|
/*--------------------------------------------------------------------------
|
|
Constructor and destructor
|
|
Description
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
CTapiServer::CTapiServer
|
|
(
|
|
ITFSComponentData * pComponentData
|
|
) : CMTTapiHandler(pComponentData),
|
|
m_bStatsOnly(FALSE),
|
|
m_StatsTimerId(-1),
|
|
m_dwOptions(0)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
}
|
|
|
|
CTapiServer::~CTapiServer()
|
|
{
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CTapiServer::InitializeNode
|
|
Initializes node specific data
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CTapiServer::InitializeNode
|
|
(
|
|
ITFSNode * pNode
|
|
)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
|
|
|
|
HRESULT hr = hrOK;
|
|
CString strTemp;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
CORg (CreateTapiInfo(&m_spTapiInfo));
|
|
|
|
BuildDisplayName(&strTemp);
|
|
|
|
SetDisplayName(strTemp);
|
|
|
|
// Make the node immediately visible
|
|
pNode->SetVisibilityState(TFS_VIS_SHOW);
|
|
pNode->SetData(TFS_DATA_COOKIE, (LPARAM) pNode);
|
|
pNode->SetData(TFS_DATA_IMAGEINDEX, ICON_IDX_SERVER);
|
|
pNode->SetData(TFS_DATA_OPENIMAGEINDEX, ICON_IDX_SERVER);
|
|
pNode->SetData(TFS_DATA_USER, (LPARAM) this);
|
|
pNode->SetData(TFS_DATA_TYPE, TAPISNAP_SERVER);
|
|
|
|
SetColumnStringIDs(&aColumns[TAPISNAP_SERVER][0]);
|
|
SetColumnWidths(&aColumnWidths[TAPISNAP_SERVER][0]);
|
|
|
|
COM_PROTECT_ERROR_LABEL;
|
|
}
|
|
COM_PROTECT_CATCH
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CTapiServer::OnCreateNodeId2
|
|
Returns a unique string for this node
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT CTapiServer::OnCreateNodeId2(ITFSNode * pNode, CString & strId, DWORD * dwFlags)
|
|
{
|
|
const GUID * pGuid = pNode->GetNodeType();
|
|
|
|
CString strGuid;
|
|
|
|
StringFromGUID2(*pGuid, strGuid.GetBuffer(256), 256);
|
|
strGuid.ReleaseBuffer();
|
|
|
|
strId = GetName() + strGuid;
|
|
|
|
return hrOK;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CTapiServer::GetImageIndex
|
|
-
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
int
|
|
CTapiServer::GetImageIndex(BOOL bOpenImage)
|
|
{
|
|
int nIndex = -1;
|
|
switch (m_nState)
|
|
{
|
|
case notLoaded:
|
|
nIndex = ICON_IDX_SERVER;
|
|
break;
|
|
|
|
case loading:
|
|
nIndex = ICON_IDX_SERVER_BUSY;
|
|
break;
|
|
|
|
case loaded:
|
|
nIndex = ICON_IDX_SERVER_CONNECTED;
|
|
break;
|
|
|
|
case unableToLoad:
|
|
nIndex = ICON_IDX_SERVER_LOST_CONNECTION;
|
|
break;
|
|
default:
|
|
ASSERT(FALSE);
|
|
}
|
|
|
|
return nIndex;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CTapiServer::OnHaveData
|
|
When the background thread enumerates nodes to be added to the UI,
|
|
we get called back here. We override this to force expansion of the
|
|
node so that things show up correctly.
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
void
|
|
CTapiServer::OnHaveData
|
|
(
|
|
ITFSNode * pParentNode,
|
|
ITFSNode * pNewNode
|
|
)
|
|
{
|
|
CMTTapiHandler::OnHaveData(pParentNode, pNewNode);
|
|
ExpandNode(pParentNode, TRUE);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CTapiServer::OnHaveData
|
|
Description
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
void
|
|
CTapiServer::OnHaveData
|
|
(
|
|
ITFSNode * pParentNode,
|
|
DWORD dwData,
|
|
DWORD dwType
|
|
)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
|
|
// This is how we get non-node data back from the background thread.
|
|
switch (dwType)
|
|
{
|
|
case TAPI_QDATA_REFRESH_STATS:
|
|
{
|
|
// tell all of the provider nodes to clear their status caches
|
|
// if any of the nodes is the selected node, then they should
|
|
// repaint the window
|
|
SPITFSNodeEnum spNodeEnum;
|
|
SPITFSNode spCurrentNode;
|
|
ULONG nNumReturned;
|
|
|
|
CORg(pParentNode->GetEnum(&spNodeEnum));
|
|
|
|
CORg(spNodeEnum->Next(1, &spCurrentNode, &nNumReturned));
|
|
while (nNumReturned)
|
|
{
|
|
if (spCurrentNode->GetData(TFS_DATA_TYPE) == TAPISNAP_PROVIDER)
|
|
{
|
|
CProviderHandler * pProvider = GETHANDLER(CProviderHandler, spCurrentNode);
|
|
|
|
pProvider->UpdateStatus(spCurrentNode);
|
|
}
|
|
|
|
spCurrentNode.Release();
|
|
spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
COM_PROTECT_ERROR_LABEL;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
Overridden base handler functions
|
|
---------------------------------------------------------------------------*/
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CTapiServer::OnAddMenuItems
|
|
Description
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP
|
|
CTapiServer::OnAddMenuItems
|
|
(
|
|
ITFSNode * pNode,
|
|
LPCONTEXTMENUCALLBACK pContextMenuCallback,
|
|
LPDATAOBJECT lpDataObject,
|
|
DATA_OBJECT_TYPES type,
|
|
DWORD dwType,
|
|
long * pInsertionAllowed
|
|
)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
|
|
|
|
LONG fFlags = 0;
|
|
HRESULT hr = S_OK;
|
|
CString strMenuItem;
|
|
|
|
if (m_nState != loaded || !m_spTapiInfo->IsLocalMachine() || !m_spTapiInfo->IsAdmin())
|
|
{
|
|
fFlags |= MF_GRAYED;
|
|
}
|
|
|
|
if (type == CCT_SCOPE)
|
|
{
|
|
if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP)
|
|
{
|
|
strMenuItem.LoadString(IDS_ADD_PROVIDER);
|
|
hr = LoadAndAddMenuItem( pContextMenuCallback,
|
|
strMenuItem,
|
|
IDS_ADD_PROVIDER,
|
|
CCM_INSERTIONPOINTID_PRIMARY_TOP,
|
|
fFlags );
|
|
ASSERT( SUCCEEDED(hr) );
|
|
}
|
|
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CTapiServer::OnCommand
|
|
Description
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP
|
|
CTapiServer::OnCommand
|
|
(
|
|
ITFSNode * pNode,
|
|
long nCommandId,
|
|
DATA_OBJECT_TYPES type,
|
|
LPDATAOBJECT pDataObject,
|
|
DWORD dwType
|
|
)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
switch (nCommandId)
|
|
{
|
|
case IDS_ADD_PROVIDER:
|
|
OnAddProvider(pNode);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CTapiServer::HasPropertyPages
|
|
Implementation of ITFSNodeHandler::HasPropertyPages
|
|
NOTE: the root node handler has to over-ride this function to
|
|
handle the snapin manager property page (wizard) case!!!
|
|
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP
|
|
CTapiServer::HasPropertyPages
|
|
(
|
|
ITFSNode * pNode,
|
|
LPDATAOBJECT pDataObject,
|
|
DATA_OBJECT_TYPES type,
|
|
DWORD dwType
|
|
)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
HRESULT hr = hrOK;
|
|
|
|
if (dwType & TFS_COMPDATA_CREATE)
|
|
{
|
|
// This is the case where we are asked to bring up property
|
|
// pages when the user is adding a new snapin. These calls
|
|
// are forwarded to the root node to handle. Only for the root node
|
|
hr = hrOK;
|
|
Assert(FALSE); // should never get here
|
|
}
|
|
else
|
|
{
|
|
// we have property pages in the normal case, but don't put the
|
|
// menu up if we are not loaded yet
|
|
if ( (m_nState == loaded) ||
|
|
(m_nState == unableToLoad) )
|
|
{
|
|
hr = hrOK;
|
|
}
|
|
else
|
|
{
|
|
hr = hrFalse;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CTapiServer::CreatePropertyPages
|
|
Description
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP
|
|
CTapiServer::CreatePropertyPages
|
|
(
|
|
ITFSNode * pNode,
|
|
LPPROPERTYSHEETCALLBACK lpProvider,
|
|
LPDATAOBJECT pDataObject,
|
|
LONG_PTR handle,
|
|
DWORD dwType
|
|
)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
//
|
|
// Create the property page
|
|
//
|
|
SPIComponentData spComponentData;
|
|
m_spNodeMgr->GetComponentData(&spComponentData);
|
|
|
|
CServerProperties * pServerProp = new CServerProperties(pNode, spComponentData, m_spTFSCompData, m_spTapiInfo, NULL, loaded == m_nState);
|
|
|
|
pServerProp->m_strMachineName = m_strServerAddress;
|
|
|
|
// fill in the auto refresh info
|
|
pServerProp->m_pageRefresh.m_dwRefreshInterval = GetAutoRefreshInterval();
|
|
pServerProp->m_pageRefresh.m_bAutoRefresh = GetOptions() & TAPISNAP_OPTIONS_REFRESH ? TRUE : FALSE;
|
|
|
|
// initialze the service information
|
|
if (!pServerProp->FInit())
|
|
{
|
|
delete pServerProp;
|
|
return E_FAIL;
|
|
}
|
|
|
|
//
|
|
// Object gets deleted when the page is destroyed
|
|
//
|
|
Assert(lpProvider != NULL);
|
|
|
|
return pServerProp->CreateModelessSheet(lpProvider, handle);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CTapiServer::OnPropertyChange
|
|
Description
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CTapiServer::OnPropertyChange
|
|
(
|
|
ITFSNode * pNode,
|
|
LPDATAOBJECT pDataobject,
|
|
DWORD dwType,
|
|
LPARAM arg,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
|
|
|
|
CServerProperties * pServerProp = reinterpret_cast<CServerProperties *>(lParam);
|
|
|
|
LONG_PTR changeMask = 0;
|
|
|
|
// tell the property page to do whatever now that we are back on the
|
|
// main thread
|
|
pServerProp->OnPropertyChange(TRUE, &changeMask);
|
|
|
|
pServerProp->AcknowledgeNotify();
|
|
|
|
if (changeMask)
|
|
pNode->ChangeNode(changeMask);
|
|
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CTapiServer::OnDelete
|
|
The base handler calls this when MMC sends a MMCN_DELETE for a
|
|
scope pane item. We just call our delete command handler.
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CTapiServer::OnDelete
|
|
(
|
|
ITFSNode * pNode,
|
|
LPARAM arg,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
return OnDelete(pNode);
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CTapiServer::OnNotifyExiting
|
|
We override this for the server node because we don't want the
|
|
icon to change when the thread goes away. Normal behavior is that
|
|
the node's icon changes to a wait cursor when the background thread
|
|
is running. If we are only doing stats collection, then we
|
|
don't want the icon to change.
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CTapiServer::OnNotifyExiting
|
|
(
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
CTapiServerQueryObj * pQuery = (CTapiServerQueryObj *) lParam;
|
|
|
|
if (!pQuery->m_bStatsOnly)
|
|
OnChangeState(m_spNode);
|
|
|
|
ReleaseThreadHandler();
|
|
|
|
Unlock();
|
|
|
|
return hrOK;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
Command handlers
|
|
---------------------------------------------------------------------------*/
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CTapiServer::OnRefresh
|
|
Default implementation for the refresh functionality
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CTapiServer::OnRefresh
|
|
(
|
|
ITFSNode * pNode,
|
|
LPDATAOBJECT pDataObject,
|
|
DWORD dwType,
|
|
LPARAM arg,
|
|
LPARAM param
|
|
)
|
|
{
|
|
m_spTapiInfo->Destroy();
|
|
|
|
return CMTHandler::OnRefresh(pNode, pDataObject, dwType, arg, param);
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CTapiServer::OnRefreshStats
|
|
Default implementation for the Stats refresh functionality
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CTapiServer::OnRefreshStats
|
|
(
|
|
ITFSNode * pNode,
|
|
LPDATAOBJECT pDataObject,
|
|
DWORD dwType,
|
|
LPARAM arg,
|
|
LPARAM param
|
|
)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
HRESULT hr = hrOK;
|
|
SPITFSNode spNode;
|
|
SPITFSNodeHandler spHandler;
|
|
ITFSQueryObject * pQuery = NULL;
|
|
|
|
if (m_bExpanded == FALSE)
|
|
{
|
|
// we cannot get statistics if the node hasn't been expanded yet
|
|
return hr;
|
|
}
|
|
|
|
// only do stats refresh if the server was loaded correctly.
|
|
if (m_nState != loaded)
|
|
return hr;
|
|
|
|
BOOL bLocked = IsLocked();
|
|
if (bLocked)
|
|
{
|
|
// cannot refresh stats if this node is locked
|
|
return hr;
|
|
}
|
|
|
|
Lock();
|
|
|
|
//OnChangeState(pNode);
|
|
|
|
pQuery = OnCreateQuery(pNode);
|
|
Assert(pQuery);
|
|
|
|
// notify the UI to change icon, if needed
|
|
//Verify(SUCCEEDED(pComponentData->ChangeNode(this, SCOPE_PANE_CHANGE_ITEM_ICON)));
|
|
|
|
Verify(StartBackgroundThread(pNode, m_spTFSCompData->GetHiddenWnd(), pQuery));
|
|
|
|
pQuery->Release();
|
|
|
|
return hrOK;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CTapiServer::OnAddProvider()
|
|
Description
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CTapiServer::OnAddProvider(ITFSNode * pNode)
|
|
{
|
|
CDriverSetup dlgDrivers(pNode, m_spTapiInfo);
|
|
|
|
dlgDrivers.DoModal();
|
|
if (dlgDrivers.m_fDriverAdded)
|
|
{
|
|
OnRefresh(pNode, NULL, 0, NULL, NULL);
|
|
}
|
|
|
|
return hrOK;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CTapiServer::OnDelete()
|
|
Description
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CTapiServer::OnDelete(ITFSNode * pNode)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
CString strMessage;
|
|
AfxFormatString1(strMessage, IDS_WARN_SERVER_DELETE, m_strServerAddress);
|
|
|
|
if (AfxMessageBox(strMessage, MB_YESNO) == IDYES)
|
|
{
|
|
// remove this node from the list, there's nothing we need to tell
|
|
// the server, it's just our local list of servers
|
|
SPITFSNode spParent;
|
|
|
|
pNode->GetParent(&spParent);
|
|
spParent->RemoveChild(pNode);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CTapiServer::RemoveProvider()
|
|
Removes a provider from the scope pane - UI only
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CTapiServer::RemoveProvider(ITFSNode * pNode, DWORD dwProviderID)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
SPITFSNodeEnum spNodeEnum;
|
|
SPITFSNode spCurrentNode;
|
|
ULONG nNumReturned;
|
|
|
|
CORg(pNode->GetEnum(&spNodeEnum));
|
|
|
|
CORg(spNodeEnum->Next(1, &spCurrentNode, &nNumReturned));
|
|
while (nNumReturned)
|
|
{
|
|
if (spCurrentNode->GetData(TFS_DATA_TYPE) == TAPISNAP_PROVIDER)
|
|
{
|
|
CProviderHandler * pProvider = GETHANDLER(CProviderHandler, spCurrentNode);
|
|
|
|
if (dwProviderID == pProvider->GetID())
|
|
{
|
|
pNode->RemoveChild(spCurrentNode);
|
|
break;
|
|
}
|
|
}
|
|
|
|
spCurrentNode.Release();
|
|
spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
|
|
}
|
|
|
|
Error:
|
|
return hr;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CTapiServer::AddProvider()
|
|
Adds a provider from the scope pane - UI only
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CTapiServer::AddProvider(ITFSNode * pNode, CTapiProvider * pProvider)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
|
|
|
|
HRESULT hr = hrOK;
|
|
SPITFSNode spProviderNode;
|
|
CProviderHandler *pProviderHandler = new CProviderHandler(m_spTFSCompData);
|
|
|
|
CreateContainerTFSNode(&spProviderNode,
|
|
&GUID_TapiProviderNodeType,
|
|
pProviderHandler,
|
|
pProviderHandler,
|
|
m_spNodeMgr);
|
|
|
|
// Tell the handler to initialize any specific data
|
|
pProviderHandler->InitData(*pProvider, m_spTapiInfo);
|
|
pProviderHandler->InitializeNode(spProviderNode);
|
|
|
|
pNode->AddChild(spProviderNode);
|
|
pProviderHandler->Release();
|
|
|
|
return hr;
|
|
}
|
|
|
|
DWORD CTapiServer::GetCachedLineBuffSize()
|
|
{
|
|
return m_spTapiInfo->GetCachedLineBuffSize();
|
|
}
|
|
|
|
VOID CTapiServer::SetCachedLineBuffSize(DWORD dwLineSize)
|
|
{
|
|
m_spTapiInfo->SetCachedLineBuffSize(dwLineSize);
|
|
}
|
|
|
|
DWORD CTapiServer::GetCachedPhoneBuffSize()
|
|
{
|
|
return m_spTapiInfo->GetCachedPhoneBuffSize();
|
|
}
|
|
|
|
VOID CTapiServer::SetCachedPhoneBuffSize(DWORD dwPhoneSize)
|
|
{
|
|
m_spTapiInfo->SetCachedPhoneBuffSize(dwPhoneSize);
|
|
}
|
|
|
|
BOOL CTapiServer::IsCacheDirty()
|
|
{
|
|
return m_spTapiInfo->IsCacheDirty();
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
Server manipulation functions
|
|
---------------------------------------------------------------------------*/
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CTapiServer::BuildDisplayName
|
|
Builds the string that goes in the UI for this server
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CTapiServer::BuildDisplayName
|
|
(
|
|
CString * pstrDisplayName
|
|
)
|
|
{
|
|
if (pstrDisplayName)
|
|
{
|
|
*pstrDisplayName = GetName();
|
|
}
|
|
|
|
return hrOK;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CTapiServer::SetAutoRefresh
|
|
Description
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CTapiServer::SetAutoRefresh
|
|
(
|
|
ITFSNode * pNode,
|
|
BOOL bOn,
|
|
DWORD dwRefreshInterval
|
|
)
|
|
{
|
|
BOOL bCurrentAutoRefresh = IsAutoRefreshEnabled();
|
|
|
|
if (bCurrentAutoRefresh &&
|
|
!bOn)
|
|
{
|
|
// turning off the timer
|
|
g_TimerMgr.FreeTimer(m_StatsTimerId);
|
|
}
|
|
else
|
|
if (!bCurrentAutoRefresh &&
|
|
bOn)
|
|
{
|
|
// gotta turn on the timer
|
|
m_StatsTimerId = g_TimerMgr.AllocateTimer(pNode, this, dwRefreshInterval, StatisticsTimerProc);
|
|
}
|
|
else
|
|
if (bOn &&
|
|
m_dwRefreshInterval != dwRefreshInterval)
|
|
{
|
|
// time to change the timer
|
|
g_TimerMgr.ChangeInterval(m_StatsTimerId, dwRefreshInterval);
|
|
}
|
|
|
|
if (bOn)
|
|
m_dwOptions |= TAPISNAP_OPTIONS_REFRESH;
|
|
else
|
|
m_dwOptions &= ~TAPISNAP_OPTIONS_REFRESH;
|
|
|
|
m_dwRefreshInterval = dwRefreshInterval;
|
|
|
|
return hrOK;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CTapiServer::SetAutoRefresh
|
|
Description
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
void
|
|
CTapiServer::SetExtensionName()
|
|
{
|
|
CString strName;
|
|
strName.LoadString(IDS_TELEPHONY);
|
|
SetDisplayName(strName);
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CTapiServer::UpdateStandardVerbs
|
|
Updates the standard verbs depending upon the state of the node
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
void
|
|
CTapiServer::UpdateConsoleVerbs
|
|
(
|
|
IConsoleVerb * pConsoleVerb,
|
|
LONG_PTR dwNodeType,
|
|
BOOL bMultiSelect
|
|
)
|
|
{
|
|
BOOL bStates[ARRAYLEN(g_ConsoleVerbs)];
|
|
MMC_BUTTON_STATE * ButtonState;
|
|
int i;
|
|
|
|
if (bMultiSelect)
|
|
{
|
|
ButtonState = g_ConsoleVerbStatesMultiSel[dwNodeType];
|
|
for (i = 0; i < ARRAYLEN(g_ConsoleVerbs); bStates[i++] = TRUE);
|
|
}
|
|
else
|
|
{
|
|
ButtonState = g_ConsoleVerbStates[dwNodeType];
|
|
switch (m_nState)
|
|
{
|
|
case loaded:
|
|
for (i = 0; i < ARRAYLEN(g_ConsoleVerbs); bStates[i++] = TRUE);
|
|
break;
|
|
|
|
case notLoaded:
|
|
case loading:
|
|
for (i = 0; i < ARRAYLEN(g_ConsoleVerbs); bStates[i++] = FALSE);
|
|
break;
|
|
|
|
case unableToLoad:
|
|
for (i = 0; i < ARRAYLEN(g_ConsoleVerbs); bStates[i++] = FALSE);
|
|
bStates[MMC_VERB_REFRESH & 0x000F] = TRUE;
|
|
bStates[MMC_VERB_DELETE & 0x000F] = TRUE;
|
|
bStates[MMC_VERB_PROPERTIES & 0x000F] = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
EnableVerbs(pConsoleVerb, ButtonState, bStates);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
Background thread functionality
|
|
---------------------------------------------------------------------------*/
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CTapiServer::OnCreateQuery
|
|
Description
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
ITFSQueryObject*
|
|
CTapiServer::OnCreateQuery(ITFSNode * pNode)
|
|
{
|
|
CTapiServerQueryObj* pQuery =
|
|
new CTapiServerQueryObj(m_spTFSCompData, m_spNodeMgr);
|
|
|
|
pQuery->m_strServer = GetName();
|
|
pQuery->m_spTapiInfo.Set(m_spTapiInfo);
|
|
pQuery->m_bStatsOnly = m_bStatsOnly;
|
|
|
|
return pQuery;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CTapiServerQueryObj::Execute()
|
|
Description
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP
|
|
CTapiServerQueryObj::Execute()
|
|
{
|
|
HRESULT hr;
|
|
|
|
if (m_bStatsOnly)
|
|
{
|
|
// we post this message esentially to get back on the main thread
|
|
// so that we can update the UI
|
|
AddToQueue(NULL, TAPI_QDATA_REFRESH_STATS);
|
|
return hrFalse;
|
|
}
|
|
|
|
m_spTapiInfo->SetComputerName(m_strServer);
|
|
|
|
// close the connection with the server if there is one
|
|
m_spTapiInfo->Destroy();
|
|
|
|
// reset state
|
|
m_spTapiInfo->Reset();
|
|
|
|
hr = m_spTapiInfo->Initialize();
|
|
if (FAILED(hr))
|
|
{
|
|
Trace1("CTapiServerQueryObj::Execute() - Initialize failed! %lx\n", hr);
|
|
PostError(WIN32_FROM_HRESULT(hr));
|
|
return hrFalse;
|
|
}
|
|
|
|
hr = m_spTapiInfo->EnumProviders();
|
|
if (FAILED(hr))
|
|
{
|
|
Trace1("CTapiServerQueryObj::Execute() - EnumProviders failed! %lx\n", hr);
|
|
PostError(WIN32_FROM_HRESULT(hr));
|
|
return hrFalse;
|
|
}
|
|
else
|
|
{
|
|
hr = m_spTapiInfo->EnumAvailableProviders();
|
|
if (FAILED(hr))
|
|
{
|
|
Trace1("CTapiServerQueryObj::Execute() - EnumAvailableProviders failed! %lx\n", hr);
|
|
PostError(WIN32_FROM_HRESULT(hr));
|
|
return hrFalse;
|
|
}
|
|
else
|
|
{
|
|
}
|
|
}
|
|
|
|
CTapiConfigInfo tapiConfigInfo;
|
|
|
|
hr = m_spTapiInfo->EnumConfigInfo();
|
|
if (FAILED(hr))
|
|
{
|
|
Trace1("CTapiServerQueryObj::Execute() - EnumConfigInfo failed! %lx\n", hr);
|
|
PostError(WIN32_FROM_HRESULT(hr));
|
|
return hrFalse;
|
|
}
|
|
else
|
|
{
|
|
}
|
|
|
|
hr = m_spTapiInfo->EnumDevices(DEVICE_LINE);
|
|
if (FAILED(hr))
|
|
{
|
|
Trace1("CTapiServerQueryObj::Execute() - EnumDevices(DEVICE_LINE) failed! %lx\n", hr);
|
|
PostError(WIN32_FROM_HRESULT(hr));
|
|
return hrFalse;
|
|
}
|
|
else
|
|
{
|
|
}
|
|
|
|
hr = m_spTapiInfo->EnumDevices(DEVICE_PHONE);
|
|
if (FAILED(hr))
|
|
{
|
|
Trace1("CTapiServerQueryObj::Execute() - EnumDevices(DEVICE_PHONE) failed! %lx\n", hr);
|
|
PostError(WIN32_FROM_HRESULT(hr));
|
|
return hrFalse;
|
|
}
|
|
else
|
|
{
|
|
}
|
|
|
|
//
|
|
for (int i = 0; i < m_spTapiInfo->GetProviderCount(); i++)
|
|
{
|
|
CTapiProvider tapiProvider;
|
|
SPITFSNode spProviderNode;
|
|
CProviderHandler *pProviderHandler = new CProviderHandler(m_spTFSCompData);
|
|
|
|
CreateContainerTFSNode(&spProviderNode,
|
|
&GUID_TapiProviderNodeType,
|
|
pProviderHandler,
|
|
pProviderHandler,
|
|
m_spNodeMgr);
|
|
|
|
// Tell the handler to initialize any specific data
|
|
m_spTapiInfo->GetProviderInfo(&tapiProvider, i);
|
|
|
|
pProviderHandler->InitData(tapiProvider, m_spTapiInfo);
|
|
pProviderHandler->InitializeNode(spProviderNode);
|
|
|
|
AddToQueue(spProviderNode);
|
|
pProviderHandler->Release();
|
|
}
|
|
|
|
|
|
return hrFalse;
|
|
}
|
|
|
|
|
|
|