mirror of https://github.com/tongzx/nt5src
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
1301 lines
36 KiB
/**********************************************************************/
|
|
/** Microsoft Windows/NT **/
|
|
/** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
|
|
/**********************************************************************/
|
|
|
|
/*
|
|
provider.cpp
|
|
Tapi provider node handler
|
|
|
|
FILE HISTORY:
|
|
|
|
*/
|
|
|
|
#include "stdafx.h"
|
|
#include "provider.h" // Provider node definition
|
|
#include "EditUser.h" // user editor
|
|
#include "server.h"
|
|
#include "tapi.h"
|
|
|
|
/*---------------------------------------------------------------------------
|
|
Class CProviderHandler implementation
|
|
---------------------------------------------------------------------------*/
|
|
|
|
/*---------------------------------------------------------------------------
|
|
Constructor and destructor
|
|
Description
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
CProviderHandler::CProviderHandler
|
|
(
|
|
ITFSComponentData * pComponentData
|
|
) : CTapiHandler(pComponentData)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
m_deviceType = DEVICE_LINE;
|
|
}
|
|
|
|
|
|
CProviderHandler::~CProviderHandler()
|
|
{
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CProviderHandler::InitializeNode
|
|
Initializes node specific data
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CProviderHandler::InitializeNode
|
|
(
|
|
ITFSNode * pNode
|
|
)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
|
|
|
|
CString strTemp;
|
|
|
|
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_FOLDER_CLOSED);
|
|
pNode->SetData(TFS_DATA_OPENIMAGEINDEX, ICON_IDX_FOLDER_OPEN);
|
|
pNode->SetData(TFS_DATA_USER, (LPARAM) this);
|
|
pNode->SetData(TFS_DATA_TYPE, TAPISNAP_PROVIDER);
|
|
pNode->SetData(TFS_DATA_SCOPE_LEAF_NODE, TRUE);
|
|
|
|
SetColumnStringIDs(&aColumns[TAPISNAP_PROVIDER][0]);
|
|
SetColumnWidths(&aColumnWidths[TAPISNAP_PROVIDER][0]);
|
|
|
|
return hrOK;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CProviderHandler::OnCreateNodeId2
|
|
Returns a unique string for this node
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT CProviderHandler::OnCreateNodeId2(ITFSNode * pNode, CString & strId, DWORD * dwFlags)
|
|
{
|
|
const GUID * pGuid = pNode->GetNodeType();
|
|
|
|
CString strProviderId, strGuid;
|
|
|
|
StringFromGUID2(*pGuid, strGuid.GetBuffer(256), 256);
|
|
strGuid.ReleaseBuffer();
|
|
|
|
strProviderId.Format(_T("%d"), m_dwProviderID);
|
|
|
|
strId = m_spTapiInfo->GetComputerName() + strProviderId + strGuid;
|
|
|
|
return hrOK;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CProviderHandler::GetImageIndex
|
|
-
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
int
|
|
CProviderHandler::GetImageIndex(BOOL bOpenImage)
|
|
{
|
|
int nIndex = -1;
|
|
|
|
return nIndex;
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
Overridden base handler functions
|
|
---------------------------------------------------------------------------*/
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CProviderHandler::OnAddMenuItems
|
|
Adds context menu items for the provider scope pane node
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP
|
|
CProviderHandler::OnAddMenuItems
|
|
(
|
|
ITFSNode * pNode,
|
|
LPCONTEXTMENUCALLBACK pContextMenuCallback,
|
|
LPDATAOBJECT lpDataObject,
|
|
DATA_OBJECT_TYPES type,
|
|
DWORD dwType,
|
|
long * pInsertionAllowed
|
|
)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
|
|
|
|
LONG fFlags = 0, fLoadingFlags = 0;
|
|
HRESULT hr = S_OK;
|
|
CString strMenuItem;
|
|
/*
|
|
if ( m_nState != loaded )
|
|
{
|
|
fFlags |= MF_GRAYED;
|
|
}
|
|
|
|
if ( m_nState == loading)
|
|
{
|
|
fLoadingFlags = MF_GRAYED;
|
|
}
|
|
*/
|
|
//Bug 305657 We cannot configure TSP remotely
|
|
if (!m_spTapiInfo->IsLocalMachine() || !m_spTapiInfo->IsAdmin())
|
|
{
|
|
fFlags |= MF_GRAYED;
|
|
}
|
|
|
|
if (type == CCT_SCOPE)
|
|
{
|
|
if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP)
|
|
{
|
|
if (m_dwFlags & AVAILABLEPROVIDER_CONFIGURABLE)
|
|
{
|
|
strMenuItem.LoadString(IDS_CONFIGURE_PROVIDER);
|
|
hr = LoadAndAddMenuItem( pContextMenuCallback,
|
|
strMenuItem,
|
|
IDS_CONFIGURE_PROVIDER,
|
|
CCM_INSERTIONPOINTID_PRIMARY_TOP,
|
|
fFlags );
|
|
ASSERT( SUCCEEDED(hr) );
|
|
}
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CProviderHandler::AddMenuItems
|
|
Adds context menu items for virtual list box (result pane) items
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP
|
|
CProviderHandler::AddMenuItems
|
|
(
|
|
ITFSComponent * pComponent,
|
|
MMC_COOKIE cookie,
|
|
LPDATAOBJECT pDataObject,
|
|
LPCONTEXTMENUCALLBACK pContextMenuCallback,
|
|
long * pInsertionAllowed
|
|
)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
|
|
|
|
HRESULT hr = hrOK;
|
|
CString strMenuItem;
|
|
SPINTERNAL spInternal;
|
|
LONG fFlags = 0;
|
|
int nIndex;
|
|
DWORD dwFlags;
|
|
CTapiDevice tapiDevice;
|
|
|
|
spInternal = ExtractInternalFormat(pDataObject);
|
|
|
|
// virtual listbox notifications come to the handler of the node that is selected.
|
|
// check to see if this notification is for a virtual listbox item or this provider
|
|
// node itself.
|
|
if (spInternal->HasVirtualIndex())
|
|
{
|
|
if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP)
|
|
{
|
|
CTapiConfigInfo tapiConfigInfo;
|
|
|
|
m_spTapiInfo->GetConfigInfo(&tapiConfigInfo);
|
|
|
|
if (m_spTapiInfo->IsAdmin() &&
|
|
tapiConfigInfo.m_dwFlags & TAPISERVERCONFIGFLAGS_ISSERVER)
|
|
{
|
|
fFlags = 0;
|
|
}
|
|
else
|
|
{
|
|
fFlags = MF_GRAYED;
|
|
}
|
|
|
|
// Check to see if this device can ONLY be used locally, if
|
|
// so, gray the edit user menu item
|
|
nIndex = spInternal->GetVirtualIndex();
|
|
m_spTapiInfo->GetDeviceInfo(m_deviceType, &tapiDevice, m_dwProviderID, nIndex);
|
|
if (m_deviceType == DEVICE_PHONE ||
|
|
m_spTapiInfo->GetDeviceFlags (
|
|
tapiDevice.m_dwProviderID,
|
|
tapiDevice.m_dwPermanentID,
|
|
&dwFlags
|
|
) ||
|
|
(dwFlags & LINEDEVCAPFLAGS_LOCAL)
|
|
)
|
|
{
|
|
fFlags = MF_GRAYED;
|
|
}
|
|
|
|
strMenuItem.LoadString(IDS_EDIT_USERS);
|
|
hr = LoadAndAddMenuItem( pContextMenuCallback,
|
|
strMenuItem,
|
|
IDS_EDIT_USERS,
|
|
CCM_INSERTIONPOINTID_PRIMARY_TOP,
|
|
fFlags );
|
|
ASSERT( SUCCEEDED(hr) );
|
|
}
|
|
}
|
|
|
|
if (*pInsertionAllowed & CCM_INSERTIONALLOWED_VIEW)
|
|
{
|
|
strMenuItem.LoadString(IDS_VIEW_LINES);
|
|
hr = LoadAndAddMenuItem( pContextMenuCallback,
|
|
strMenuItem,
|
|
IDS_VIEW_LINES,
|
|
CCM_INSERTIONPOINTID_PRIMARY_VIEW,
|
|
(m_deviceType == DEVICE_LINE) ? MF_CHECKED : 0 );
|
|
ASSERT( SUCCEEDED(hr) );
|
|
|
|
strMenuItem.LoadString(IDS_VIEW_PHONES);
|
|
hr = LoadAndAddMenuItem( pContextMenuCallback,
|
|
strMenuItem,
|
|
IDS_VIEW_PHONES,
|
|
CCM_INSERTIONPOINTID_PRIMARY_VIEW,
|
|
(m_deviceType == DEVICE_PHONE) ? MF_CHECKED : 0 );
|
|
ASSERT( SUCCEEDED(hr) );
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CProviderHandler::OnCommand
|
|
Handles context menu commands for provider scope pane node
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP
|
|
CProviderHandler::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_CONFIGURE_PROVIDER:
|
|
OnConfigureProvider(pNode);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CProviderHandler::Command
|
|
Handles context menu commands for virtual listbox items
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP
|
|
CProviderHandler::Command
|
|
(
|
|
ITFSComponent * pComponent,
|
|
MMC_COOKIE cookie,
|
|
int nCommandID,
|
|
LPDATAOBJECT pDataObject
|
|
)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
|
|
|
|
HRESULT hr = S_OK;
|
|
SPITFSNode spNode;
|
|
|
|
m_spResultNodeMgr->FindNode(cookie, &spNode);
|
|
|
|
switch (nCommandID)
|
|
{
|
|
case IDS_EDIT_USERS:
|
|
OnEditUsers(pComponent, pDataObject, cookie);
|
|
break;
|
|
|
|
case IDS_VIEW_LINES:
|
|
m_deviceType = DEVICE_LINE;
|
|
|
|
// clear the listbox then set the size
|
|
SetColumnInfo();
|
|
UpdateColumnText(pComponent);
|
|
UpdateListboxCount(spNode, TRUE);
|
|
UpdateListboxCount(spNode);
|
|
break;
|
|
|
|
case IDS_VIEW_PHONES:
|
|
m_deviceType = DEVICE_PHONE;
|
|
|
|
// clear the listbox then set the size
|
|
SetColumnInfo();
|
|
UpdateColumnText(pComponent);
|
|
UpdateListboxCount(spNode, TRUE);
|
|
UpdateListboxCount(spNode);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CProviderHandler::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
|
|
CProviderHandler::HasPropertyPages
|
|
(
|
|
ITFSNode * pNode,
|
|
LPDATAOBJECT pDataObject,
|
|
DATA_OBJECT_TYPES type,
|
|
DWORD dwType
|
|
)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
return hrFalse;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CProviderHandler::CreatePropertyPages
|
|
Description
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP
|
|
CProviderHandler::CreatePropertyPages
|
|
(
|
|
ITFSNode * pNode,
|
|
LPPROPERTYSHEETCALLBACK lpProvider,
|
|
LPDATAOBJECT pDataObject,
|
|
LONG_PTR handle,
|
|
DWORD dwType
|
|
)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
DWORD dwError;
|
|
DWORD dwDynDnsFlags;
|
|
|
|
//
|
|
// Create the property page
|
|
//
|
|
SPIComponentData spComponentData;
|
|
m_spNodeMgr->GetComponentData(&spComponentData);
|
|
|
|
//CServerProperties * pServerProp = new CServerProperties(pNode, spComponentData, m_spTFSCompData, NULL);
|
|
|
|
//
|
|
// Object gets deleted when the page is destroyed
|
|
//
|
|
Assert(lpProvider != NULL);
|
|
|
|
//return pServerProp->CreateModelessSheet(lpProvider, handle);
|
|
return hrFalse;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CProviderHandler::OnPropertyChange
|
|
Description
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CProviderHandler::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;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CProviderHandler::OnExpand
|
|
Handles enumeration of a scope item
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CProviderHandler::OnExpand
|
|
(
|
|
ITFSNode * pNode,
|
|
LPDATAOBJECT pDataObject,
|
|
DWORD dwType,
|
|
LPARAM arg,
|
|
LPARAM param
|
|
)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
|
|
if (m_bExpanded)
|
|
return hr;
|
|
|
|
// do the default handling
|
|
CORg (CTapiHandler::OnExpand(pNode, pDataObject, dwType, arg, param));
|
|
|
|
Error:
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CProviderHandler::OnResultSelect
|
|
Handles the MMCN_SELECT notifcation
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CProviderHandler::OnResultSelect
|
|
(
|
|
ITFSComponent * pComponent,
|
|
LPDATAOBJECT pDataObject,
|
|
MMC_COOKIE cookie,
|
|
LPARAM arg,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
|
|
|
|
HRESULT hr = hrOK;
|
|
SPINTERNAL spInternal;
|
|
SPIConsole spConsole;
|
|
SPIConsoleVerb spConsoleVerb;
|
|
SPITFSNode spNode;
|
|
BOOL bStates[ARRAYLEN(g_ConsoleVerbs)];
|
|
int i;
|
|
LONG_PTR dwNodeType;
|
|
BOOL fSelect = HIWORD(arg);
|
|
|
|
if (!fSelect)
|
|
return hr;
|
|
|
|
if (m_spTapiInfo)
|
|
{
|
|
// Get the current count
|
|
i = m_spTapiInfo->GetDeviceCount(m_deviceType, m_dwProviderID);
|
|
|
|
// now notify the virtual listbox
|
|
CORg ( m_spNodeMgr->GetConsole(&spConsole) );
|
|
CORg ( spConsole->UpdateAllViews(pDataObject, i, RESULT_PANE_SET_VIRTUAL_LB_SIZE) );
|
|
}
|
|
|
|
// now update the verbs...
|
|
spInternal = ExtractInternalFormat(pDataObject);
|
|
Assert(spInternal);
|
|
|
|
// virtual listbox notifications come to the handler of the node that is selected.
|
|
// check to see if this notification is for a virtual listbox item or the active
|
|
// registrations node itself.
|
|
CORg (pComponent->GetConsoleVerb(&spConsoleVerb));
|
|
|
|
if (spInternal->HasVirtualIndex())
|
|
{
|
|
// we gotta do special stuff for the virtual index items
|
|
dwNodeType = TAPISNAP_DEVICE;
|
|
for (i = 0; i < ARRAYLEN(g_ConsoleVerbs); bStates[i++] = FALSE);
|
|
}
|
|
else
|
|
{
|
|
// enable/disable delete depending if the provider supports it
|
|
CORg (m_spNodeMgr->FindNode(cookie, &spNode));
|
|
dwNodeType = spNode->GetData(TFS_DATA_TYPE);
|
|
|
|
for (i = 0; i < ARRAYLEN(g_ConsoleVerbs); bStates[i++] = TRUE);
|
|
|
|
//Per XZhang, hide "delete" context menu of provider nodes on remote machines
|
|
if (!m_spTapiInfo->IsLocalMachine() || (m_dwFlags & AVAILABLEPROVIDER_REMOVABLE) == 0)
|
|
{
|
|
bStates[MMC_VERB_DELETE & 0x000F] = FALSE;
|
|
}
|
|
}
|
|
|
|
EnableVerbs(spConsoleVerb, g_ConsoleVerbStates[dwNodeType], bStates);
|
|
|
|
COM_PROTECT_ERROR_LABEL;
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CProviderHandler::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
|
|
CProviderHandler::OnDelete
|
|
(
|
|
ITFSNode * pNode,
|
|
LPARAM arg,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
return OnDelete(pNode);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CProviderHandler::OnGetResultViewType
|
|
Return the result view that this node is going to support
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CProviderHandler::OnGetResultViewType
|
|
(
|
|
ITFSComponent * pComponent,
|
|
MMC_COOKIE cookie,
|
|
LPOLESTR * ppViewType,
|
|
long * pViewOptions
|
|
)
|
|
{
|
|
if (cookie != NULL)
|
|
{
|
|
*pViewOptions = MMC_VIEW_OPTIONS_OWNERDATALIST | MMC_VIEW_OPTIONS_MULTISELECT;
|
|
}
|
|
|
|
return S_FALSE;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CProviderHandler::GetVirtualImage
|
|
Returns the image index for virtual listbox items
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
int
|
|
CProviderHandler::GetVirtualImage
|
|
(
|
|
int nIndex
|
|
)
|
|
{
|
|
return ICON_IDX_MACHINE;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CProviderHandler::GetVirtualString
|
|
returns a pointer to the string for virtual listbox items
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
LPCWSTR
|
|
CProviderHandler::GetVirtualString
|
|
(
|
|
int nIndex,
|
|
int nCol
|
|
)
|
|
{
|
|
// check our cache to see if we have this one.
|
|
//TapiStrRecord * ptsr = m_RecList.FindItem(nIndex);
|
|
CString strStatus;
|
|
TapiStrRecord tsr;
|
|
|
|
if (!m_mapRecords.Lookup(nIndex, tsr))
|
|
{
|
|
Trace1("CProviderHandler::GetVirtualString - Index %d not in TAPI string cache\n", nIndex);
|
|
|
|
// doesn't exist in our cache, need to add this one.
|
|
if (!BuildTapiStrRecord(nIndex, tsr))
|
|
{
|
|
Trace0("CProviderHandler::BuildTapiStrRecord failed!\n");
|
|
}
|
|
|
|
//m_RecList.AddTail(ptsr);
|
|
m_mapRecords.SetAt(nIndex, tsr);
|
|
}
|
|
|
|
if (!m_mapStatus.Lookup(nIndex, strStatus))
|
|
{
|
|
Trace1("CProviderHandler::GetVirtualString - Index %d not in status cache\n", nIndex);
|
|
|
|
if (!BuildStatus(nIndex, strStatus))
|
|
{
|
|
Trace0("CProviderHandler::BuildStatus failed!\n");
|
|
}
|
|
}
|
|
|
|
switch (nCol)
|
|
{
|
|
case 0:
|
|
return tsr.strName;
|
|
break;
|
|
|
|
case 1:
|
|
return tsr.strUsers;
|
|
break;
|
|
|
|
case 2:
|
|
return strStatus;
|
|
break;
|
|
|
|
default:
|
|
Panic0("CProviderHandler::GetVirtualString - Unknown column!\n");
|
|
break;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CProviderHandler::CacheHint
|
|
MMC tells us which items it will need before it requests things
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP
|
|
CProviderHandler::CacheHint
|
|
(
|
|
int nStartIndex,
|
|
int nEndIndex
|
|
)
|
|
{
|
|
HRESULT hr = hrOK;;
|
|
|
|
Trace2("CacheHint - Start %d, End %d\n", nStartIndex, nEndIndex);
|
|
|
|
// the virtual listbox stores no strings and gives us cache hints for
|
|
// everything, including individual querries. To avoid thrashing, only
|
|
// clear our the cache if the request is large.
|
|
if ((nEndIndex - nStartIndex) > 2)
|
|
{
|
|
m_mapRecords.RemoveAll();
|
|
}
|
|
|
|
TapiStrRecord tsr;
|
|
CString strStatus;
|
|
|
|
for (int i = nStartIndex; i <= nEndIndex; i++)
|
|
{
|
|
if (!BuildTapiStrRecord(i, tsr))
|
|
continue;
|
|
|
|
m_mapRecords.SetAt(i, tsr);
|
|
|
|
// only refresh status records if they don't exist. Only the auto refresh
|
|
// background thread cleans out the map...
|
|
if (!m_mapStatus.Lookup(i, strStatus))
|
|
{
|
|
BuildStatus(i, strStatus);
|
|
m_mapStatus.SetAt(i, strStatus);
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CProviderHandler::SortItems
|
|
We are responsible for sorting of virtual listbox items
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP
|
|
CProviderHandler::SortItems
|
|
(
|
|
int nColumn,
|
|
DWORD dwSortOptions,
|
|
LPARAM lUserParam
|
|
)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
|
|
|
|
BEGIN_WAIT_CURSOR
|
|
|
|
switch (nColumn)
|
|
{
|
|
case 0:
|
|
m_spTapiInfo->SortDeviceInfo(m_deviceType, m_dwProviderID, INDEX_TYPE_NAME, dwSortOptions);
|
|
break;
|
|
case 1:
|
|
m_spTapiInfo->SortDeviceInfo(m_deviceType, m_dwProviderID, INDEX_TYPE_USERS, dwSortOptions);
|
|
break;
|
|
// case 2:
|
|
// m_spTapiInfo->SortDeviceInfo(m_deviceType, m_dwProviderID, INDEX_TYPE_STATUS, dwSortOptions);
|
|
// break;
|
|
}
|
|
END_WAIT_CURSOR
|
|
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CProviderHandler::OnResultUpdateView
|
|
Implementation of ITFSResultHandler::OnResultUpdateView
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT CProviderHandler::OnResultUpdateView
|
|
(
|
|
ITFSComponent *pComponent,
|
|
LPDATAOBJECT pDataObject,
|
|
LPARAM data,
|
|
LONG_PTR hint
|
|
)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
SPITFSNode spSelectedNode;
|
|
|
|
pComponent->GetSelectedNode(&spSelectedNode);
|
|
if (spSelectedNode == NULL)
|
|
return S_OK; // no selection for our IComponentData
|
|
|
|
if ( hint == TAPISNAP_UPDATE_STATUS )
|
|
{
|
|
SPINTERNAL spInternal = ExtractInternalFormat(pDataObject);
|
|
ITFSNode * pNode = reinterpret_cast<ITFSNode *>(spInternal->m_cookie);
|
|
SPITFSNode spSelectedNode;
|
|
|
|
pComponent->GetSelectedNode(&spSelectedNode);
|
|
|
|
if (pNode == spSelectedNode)
|
|
{
|
|
Trace1("CProviderHandler::OnResultUpdateView - Provider %x is selected, invalidating listbox.\n", m_dwProviderID);
|
|
|
|
// if we are the selected node, then we need to update
|
|
SPIResultData spResultData;
|
|
|
|
CORg (pComponent->GetResultData(&spResultData));
|
|
CORg (spResultData->SetItemCount((int) data, MMCLV_UPDATE_NOSCROLL));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// we don't handle this message, let the base class do it.
|
|
return CTapiHandler::OnResultUpdateView(pComponent, pDataObject, data, hint);
|
|
}
|
|
|
|
COM_PROTECT_ERROR_LABEL;
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CProviderHandler::OnResultItemClkOrDblClk
|
|
The user had double clicked on a line/phone. Invoke the edit users.
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CProviderHandler::OnResultItemClkOrDblClk
|
|
(
|
|
ITFSComponent * pComponent,
|
|
MMC_COOKIE cookie,
|
|
LPARAM arg,
|
|
LPARAM lParam,
|
|
BOOL bDoubleClick
|
|
)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
|
|
if (bDoubleClick)
|
|
{
|
|
// first check to see if we are selected
|
|
SPITFSNode spSelectedNode;
|
|
pComponent->GetSelectedNode(&spSelectedNode);
|
|
|
|
SPITFSNode spNode;
|
|
m_spResultNodeMgr->FindNode(cookie, &spNode);
|
|
|
|
if (spSelectedNode == spNode)
|
|
{
|
|
CTapiConfigInfo tapiConfigInfo;
|
|
|
|
m_spTapiInfo->GetConfigInfo(&tapiConfigInfo);
|
|
|
|
// check to see if they have access rights
|
|
if (m_spTapiInfo->IsAdmin() &&
|
|
tapiConfigInfo.m_dwFlags & TAPISERVERCONFIGFLAGS_ISSERVER)
|
|
{
|
|
// double click on a line/phone entry.
|
|
SPIDataObject spDataObject;
|
|
|
|
CORg (pComponent->GetCurrentDataObject(&spDataObject));
|
|
|
|
OnEditUsers(pComponent, spDataObject, cookie);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// we are being double clicked to open
|
|
// let the base class handle this
|
|
return CTapiHandler::OnResultItemClkOrDblClk(pComponent, cookie, arg, lParam, bDoubleClick);
|
|
}
|
|
}
|
|
|
|
Error:
|
|
return S_OK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CProviderHandler::LoadColumns
|
|
Set the correct column header and then call the base class
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CProviderHandler::LoadColumns
|
|
(
|
|
ITFSComponent * pComponent,
|
|
MMC_COOKIE cookie,
|
|
LPARAM arg,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
SetColumnInfo();
|
|
|
|
return CTapiHandler::LoadColumns(pComponent, cookie, arg, lParam);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
Command handlers
|
|
---------------------------------------------------------------------------*/
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CProviderHandler::OnConfigureProvider
|
|
Configures a service provider
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CProviderHandler::OnConfigureProvider
|
|
(
|
|
ITFSNode * pNode
|
|
)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
|
|
Assert(m_spTapiInfo);
|
|
|
|
hr = m_spTapiInfo->ConfigureProvider(m_dwProviderID, NULL);
|
|
if (FAILED(hr))
|
|
{
|
|
::TapiMessageBox(WIN32_FROM_HRESULT(hr));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CProviderHandler::OnDelete
|
|
Removes a service provider
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CProviderHandler::OnDelete
|
|
(
|
|
ITFSNode * pNode
|
|
)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
SPITFSNode spNode;
|
|
CString strMessage;
|
|
|
|
pNode->GetParent(&spNode);
|
|
|
|
CTapiServer * pServer = GETHANDLER(CTapiServer, spNode);
|
|
|
|
// Ask the user to make sure
|
|
AfxFormatString2(strMessage, IDS_WARN_PROVIDER_DELETE, m_strProviderName, pServer->GetName());
|
|
|
|
if (AfxMessageBox(strMessage, MB_YESNO) == IDYES)
|
|
{
|
|
Assert(m_spTapiInfo);
|
|
|
|
hr = m_spTapiInfo->RemoveProvider(m_dwProviderID, NULL);
|
|
if (FAILED(hr))
|
|
{
|
|
::TapiMessageBox(WIN32_FROM_HRESULT(hr));
|
|
}
|
|
else
|
|
{
|
|
// remove from the UI
|
|
SPITFSNode spParent;
|
|
CORg (pNode->GetParent(&spParent));
|
|
|
|
CORg (spParent->RemoveChild(pNode));
|
|
|
|
// update the list of installed providers
|
|
CORg (m_spTapiInfo->EnumProviders());
|
|
}
|
|
}
|
|
|
|
Error:
|
|
return hr;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CProviderHandler::OnEditUsers
|
|
Allows different users to be assigned to a device
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CProviderHandler::OnEditUsers
|
|
(
|
|
ITFSComponent * pComponent,
|
|
LPDATAOBJECT pDataObject,
|
|
MMC_COOKIE cookie
|
|
)
|
|
{
|
|
SPITFSNode spNode;
|
|
SPINTERNAL spInternal;
|
|
int nIndex;
|
|
DWORD dwFlags;
|
|
CTapiDevice tapiDevice;
|
|
HRESULT hr = hrOK;
|
|
|
|
spInternal = ExtractInternalFormat(pDataObject);
|
|
|
|
// virtual listbox notifications come to the handler of the node that is selected.
|
|
// assert that this notification is for a virtual listbox item
|
|
Assert(spInternal);
|
|
if (!spInternal->HasVirtualIndex() || m_deviceType == DEVICE_PHONE)
|
|
return hr;
|
|
|
|
nIndex = spInternal->GetVirtualIndex();
|
|
Trace1("OnEditUsers - edit users for index %d\n", nIndex);
|
|
|
|
m_spTapiInfo->GetDeviceInfo(m_deviceType, &tapiDevice, m_dwProviderID, nIndex);
|
|
|
|
// Check to see if this device can be remoted
|
|
hr = m_spTapiInfo->GetDeviceFlags (
|
|
tapiDevice.m_dwProviderID,
|
|
tapiDevice.m_dwPermanentID,
|
|
&dwFlags
|
|
);
|
|
if (hr || (dwFlags & LINEDEVCAPFLAGS_LOCAL))
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
CEditUsers dlgEditUsers(&tapiDevice);
|
|
|
|
if (dlgEditUsers.DoModal() == IDOK)
|
|
{
|
|
if (dlgEditUsers.IsDirty())
|
|
{
|
|
hr = m_spTapiInfo->SetDeviceInfo(m_deviceType, &tapiDevice);
|
|
if (FAILED(hr))
|
|
{
|
|
TapiMessageBox(WIN32_FROM_HRESULT(hr));
|
|
}
|
|
else
|
|
{
|
|
pComponent->GetSelectedNode(&spNode);
|
|
|
|
// clear the listbox then set the size
|
|
UpdateListboxCount(spNode, TRUE);
|
|
UpdateListboxCount(spNode);
|
|
}
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CProviderHandler::UpdateStatus
|
|
-
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CProviderHandler::UpdateStatus
|
|
(
|
|
ITFSNode * pNode
|
|
)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
SPIComponentData spComponentData;
|
|
SPIConsole spConsole;
|
|
IDataObject * pDataObject;
|
|
SPIDataObject spDataObject;
|
|
int i = 0;
|
|
|
|
Trace1("CProviderHandler::UpdateStatus - Updating status for provider %x\n", m_dwProviderID);
|
|
|
|
// clear our status strings
|
|
m_mapStatus.RemoveAll();
|
|
|
|
// force the listbox to update. We do this by setting the count and
|
|
// telling it to invalidate the data
|
|
CORg(m_spNodeMgr->GetComponentData(&spComponentData));
|
|
CORg(m_spNodeMgr->GetConsole(&spConsole));
|
|
|
|
// grab a data object to use
|
|
CORg(spComponentData->QueryDataObject((MMC_COOKIE) pNode, CCT_RESULT, &pDataObject) );
|
|
spDataObject = pDataObject;
|
|
|
|
i = m_spTapiInfo->GetDeviceCount(m_deviceType, m_dwProviderID);
|
|
CORg(spConsole->UpdateAllViews(pDataObject, i, TAPISNAP_UPDATE_STATUS));
|
|
|
|
COM_PROTECT_ERROR_LABEL;
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
Misc functions
|
|
---------------------------------------------------------------------------*/
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CProviderHandler::BuildDisplayName
|
|
Builds the string that goes in the UI for this server
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CProviderHandler::BuildDisplayName
|
|
(
|
|
CString * pstrDisplayName
|
|
)
|
|
{
|
|
if (pstrDisplayName)
|
|
{
|
|
CString strName;
|
|
|
|
*pstrDisplayName = GetDisplayName();
|
|
}
|
|
|
|
return hrOK;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CProviderHandler::InitData
|
|
Initializes data for this node
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CProviderHandler::InitData
|
|
(
|
|
CTapiProvider & tapiProvider,
|
|
ITapiInfo * pTapiInfo
|
|
)
|
|
{
|
|
m_strProviderName = tapiProvider.m_strName;
|
|
m_dwProviderID = tapiProvider.m_dwProviderID;
|
|
m_dwFlags = tapiProvider.m_dwFlags;
|
|
|
|
m_spTapiInfo.Set(pTapiInfo);
|
|
|
|
SetDisplayName(m_strProviderName);
|
|
|
|
return hrOK;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CProviderHandler::BuildTapiStrRecord
|
|
Description
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
BOOL
|
|
CProviderHandler::BuildTapiStrRecord(int nIndex, TapiStrRecord & tsr)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
CTapiDevice tapiDevice;
|
|
CString strTemp;
|
|
int i;
|
|
|
|
if (!m_spTapiInfo)
|
|
return FALSE;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
CORg (m_spTapiInfo->GetDeviceInfo(m_deviceType, &tapiDevice, m_dwProviderID, nIndex));
|
|
|
|
// set the index for this record
|
|
//tsr.nIndex = nIndex;
|
|
|
|
// name
|
|
tsr.strName = tapiDevice.m_strName;
|
|
|
|
// users
|
|
tsr.strUsers.Empty();
|
|
for (i = 0; i < tapiDevice.m_arrayUsers.GetSize(); i++)
|
|
{
|
|
if (!tapiDevice.m_arrayUsers[i].m_strFullName.IsEmpty())
|
|
{
|
|
tsr.strUsers += tapiDevice.m_arrayUsers[i].m_strFullName;
|
|
}
|
|
else
|
|
{
|
|
tsr.strUsers += tapiDevice.m_arrayUsers[i].m_strName;
|
|
}
|
|
|
|
if ((i + 1) != tapiDevice.m_arrayUsers.GetSize())
|
|
tsr.strUsers += _T(", ");
|
|
}
|
|
COM_PROTECT_ERROR_LABEL;
|
|
}
|
|
COM_PROTECT_CATCH
|
|
|
|
return SUCCEEDED(hr);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CProviderHandler::BuildStatus
|
|
Description
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
BOOL
|
|
CProviderHandler::BuildStatus(int nIndex, CString & strStatus)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
|
|
// status
|
|
hr = m_spTapiInfo->GetDeviceStatus(m_deviceType, &strStatus, m_dwProviderID, nIndex, NULL);
|
|
|
|
if (strStatus.IsEmpty())
|
|
strStatus.LoadString(IDS_NO_STATUS);
|
|
|
|
return SUCCEEDED(hr);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CProviderHandler::UpdateListboxCount
|
|
Description
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CProviderHandler::UpdateListboxCount(ITFSNode * pNode, BOOL bClear)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
SPIComponentData spCompData;
|
|
SPIConsole spConsole;
|
|
IDataObject* pDataObject;
|
|
SPIDataObject spDataObject;
|
|
LONG_PTR command;
|
|
int i;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
if (!m_spTapiInfo || bClear)
|
|
{
|
|
command = RESULT_PANE_CLEAR_VIRTUAL_LB;
|
|
i = 0;
|
|
}
|
|
else
|
|
{
|
|
command = RESULT_PANE_SET_VIRTUAL_LB_SIZE;
|
|
i = m_spTapiInfo->GetDeviceCount(m_deviceType, m_dwProviderID);
|
|
}
|
|
|
|
m_spNodeMgr->GetComponentData(&spCompData);
|
|
|
|
CORg ( spCompData->QueryDataObject((MMC_COOKIE) pNode, CCT_RESULT, &pDataObject) );
|
|
spDataObject = pDataObject;
|
|
|
|
CORg ( m_spNodeMgr->GetConsole(&spConsole) );
|
|
|
|
CORg ( spConsole->UpdateAllViews(spDataObject, i, command) );
|
|
|
|
COM_PROTECT_ERROR_LABEL;
|
|
}
|
|
COM_PROTECT_CATCH
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CProviderHandler::SetColumnInfo
|
|
Description
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
void
|
|
CProviderHandler::SetColumnInfo()
|
|
{
|
|
// set the correct column header
|
|
if (m_deviceType == DEVICE_LINE)
|
|
{
|
|
aColumns[TAPISNAP_PROVIDER][0] = IDS_LINE_NAME;
|
|
}
|
|
else
|
|
{
|
|
aColumns[TAPISNAP_PROVIDER][0] = IDS_PHONE_NAME;
|
|
}
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CProviderHandler::UpdateColumnText
|
|
Description
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CProviderHandler::UpdateColumnText(ITFSComponent * pComponent)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
SPIHeaderCtrl spHeaderCtrl;
|
|
pComponent->GetHeaderCtrl(&spHeaderCtrl);
|
|
|
|
CString str;
|
|
int i = 0;
|
|
|
|
while (TRUE)
|
|
{
|
|
if ( 0 == aColumns[TAPISNAP_PROVIDER][i] )
|
|
break;
|
|
|
|
str.LoadString(aColumns[TAPISNAP_PROVIDER][i]);
|
|
|
|
spHeaderCtrl->SetColumnText(i, const_cast<LPTSTR>((LPCWSTR)str));
|
|
|
|
i++;
|
|
}
|
|
|
|
return hrOK;
|
|
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
Background thread functionality
|
|
---------------------------------------------------------------------------*/
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CProviderHandler::OnCreateQuery
|
|
Description
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
ITFSQueryObject*
|
|
CProviderHandler::OnCreateQuery(ITFSNode * pNode)
|
|
{
|
|
CProviderHandlerQueryObj* pQuery =
|
|
new CProviderHandlerQueryObj(m_spTFSCompData, m_spNodeMgr);
|
|
|
|
//pQuery->m_strServer = NULL;
|
|
|
|
return pQuery;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CProviderHandlerQueryObj::Execute()
|
|
Description
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP
|
|
CProviderHandlerQueryObj::Execute()
|
|
{
|
|
return hrFalse;
|
|
}
|
|
|
|
|
|
|