windows-nt/Source/XPSP1/NT/net/mmc/tapi/server.cpp
2020-09-26 16:20:57 +08:00

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;
}