382 lines
8.2 KiB
C++
382 lines
8.2 KiB
C++
// File: iMember.cpp
|
|
//
|
|
// INmMember interface (participant routines)
|
|
|
|
#include "precomp.h"
|
|
#include "imember.h"
|
|
#include "rostinfo.h"
|
|
#include "imanager.h" // for g_pNodeController
|
|
|
|
/* C N M M E M B E R */
|
|
/*-------------------------------------------------------------------------
|
|
%%Function: CNmMember Constructor
|
|
|
|
-------------------------------------------------------------------------*/
|
|
CNmMember::CNmMember(PWSTR pwszName, DWORD dwGCCID, DWORD dwFlags, ULONG uCaps,
|
|
REFGUID rguidNode, PVOID pwszUserInfo, UINT cbUserInfo) :
|
|
m_bstrName (SysAllocString(pwszName)),
|
|
m_dwGCCID (dwGCCID),
|
|
m_dwFlags (dwFlags),
|
|
m_uCaps (uCaps),
|
|
m_guidNode (rguidNode),
|
|
m_cbUserInfo (cbUserInfo),
|
|
m_uNmchCaps (0),
|
|
m_dwGccIdParent(INVALID_GCCID),
|
|
m_pwszUserInfo (NULL),
|
|
m_pConnection(NULL)
|
|
{
|
|
// Local state never changes
|
|
m_fLocal = 0 != (PF_LOCAL_NODE & m_dwFlags);
|
|
|
|
// check to see if we have the right GUID for local member
|
|
// guid will be NULL if we have H323 disabled.
|
|
ASSERT (!m_fLocal || (GUID_NULL == rguidNode) || (g_guidLocalNodeId == rguidNode));
|
|
|
|
SetUserInfo(pwszUserInfo, cbUserInfo);
|
|
|
|
DbgMsg(iZONE_OBJECTS, "Obj: %08X created CNmMember", this);
|
|
}
|
|
|
|
|
|
CNmMember::~CNmMember(void)
|
|
{
|
|
SysFreeString(m_bstrName);
|
|
|
|
delete m_pwszUserInfo;
|
|
if(m_pConnection)
|
|
m_pConnection->Release();
|
|
|
|
DbgMsg(iZONE_OBJECTS, "Obj: %08X destroyed CNmMember", this);
|
|
}
|
|
|
|
VOID CNmMember::SetGccIdParent(DWORD dwGccId)
|
|
{
|
|
m_dwGccIdParent = dwGccId;
|
|
if (0 == dwGccId)
|
|
{
|
|
// No Parent means this is the Top Provider
|
|
m_dwFlags |= PF_T120_TOP_PROV;
|
|
}
|
|
else
|
|
{
|
|
m_dwFlags &= ~PF_T120_TOP_PROV;
|
|
}
|
|
}
|
|
|
|
VOID CNmMember::SetUserInfo(PVOID pwszUserInfo, UINT cbUserInfo)
|
|
{
|
|
// clear out any previous data
|
|
delete m_pwszUserInfo;
|
|
m_cbUserInfo = 0;
|
|
|
|
if (0 == cbUserInfo)
|
|
{
|
|
m_pwszUserInfo = NULL;
|
|
}
|
|
else
|
|
{
|
|
m_pwszUserInfo = (PWSTR) new BYTE[cbUserInfo];
|
|
if (NULL == m_pwszUserInfo)
|
|
{
|
|
WARNING_OUT(("CNmMember: unable to alloc space for user data"));
|
|
}
|
|
else
|
|
{
|
|
m_cbUserInfo = cbUserInfo;
|
|
CopyMemory(m_pwszUserInfo, pwszUserInfo, m_cbUserInfo);
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL CNmMember::GetSecurityData(PBYTE * ppb, ULONG * pcb)
|
|
{
|
|
DWORD dwGCCID = FLocal() ? 0 : GetGCCID();
|
|
|
|
(* pcb) = 0;
|
|
(* ppb) = NULL;
|
|
|
|
// If this node is directly connected to the member, we use the transport data...
|
|
if (::T120_GetSecurityInfoFromGCCID(dwGCCID,NULL,pcb)) {
|
|
if (0 != (* pcb)) {
|
|
// We are directly connected and security data is valid.
|
|
(*ppb) = (PBYTE)CoTaskMemAlloc(*pcb);
|
|
if ((*ppb) != NULL)
|
|
{
|
|
::T120_GetSecurityInfoFromGCCID(dwGCCID,*ppb,pcb);
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
ERROR_OUT(("CoTaskMemAlloc failed in GetSecurityData"));
|
|
}
|
|
}
|
|
else if (GetUserData(g_csguidSecurity,ppb,pcb) == S_OK)
|
|
{
|
|
// We are not directly connected, so get security data from roster.
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
HRESULT CNmMember::ExtractUserData(LPTSTR psz, UINT cchMax, PWSTR pwszKey)
|
|
{
|
|
CRosterInfo ri;
|
|
HRESULT hr = ri.Load(GetUserInfo());
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
hr = ri.ExtractItem(NULL, pwszKey, psz, cchMax);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CNmMember::GetIpAddr(LPTSTR psz, UINT cchMax)
|
|
{
|
|
return ExtractUserData(psz, cchMax, (PWSTR) g_cwszIPTag);
|
|
}
|
|
|
|
///////////////////////////
|
|
// CNmMember:IUknown
|
|
|
|
ULONG STDMETHODCALLTYPE CNmMember::AddRef(void)
|
|
{
|
|
|
|
DBGENTRY(CNmMember::AddRef);
|
|
|
|
TRACE_OUT(("CNmMember [%ls]: AddRef this = 0x%X", m_bstrName ? m_bstrName : L"", this));
|
|
|
|
ULONG ul = RefCount::AddRef();
|
|
|
|
DBGEXIT(CNmMember::AddRef);
|
|
|
|
return ul;
|
|
}
|
|
|
|
ULONG STDMETHODCALLTYPE CNmMember::Release(void)
|
|
{
|
|
|
|
DBGENTRY(CNmMember::Release);
|
|
|
|
TRACE_OUT(("CNmMember [%ls]: Release this = 0x%X", m_bstrName ? m_bstrName : L"", this));
|
|
|
|
ULONG ul = RefCount::Release();
|
|
|
|
DBGEXIT(CNmMember::Release);
|
|
|
|
return ul;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CNmMember::QueryInterface(REFIID riid, PVOID *ppv)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if ((riid == IID_INmMember) || (riid == IID_IUnknown))
|
|
{
|
|
*ppv = (INmMember *)this;
|
|
ApiDebugMsg(("CNmMember::QueryInterface()"));
|
|
}
|
|
else
|
|
{
|
|
hr = E_NOINTERFACE;
|
|
*ppv = NULL;
|
|
ApiDebugMsg(("CNmMember::QueryInterface(): Called on unknown interface."));
|
|
}
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
AddRef();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
///////////////
|
|
// INmMember
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CNmMember::GetName(BSTR *pbstrName)
|
|
{
|
|
if (NULL == pbstrName)
|
|
return E_POINTER;
|
|
|
|
*pbstrName = SysAllocString(m_bstrName);
|
|
|
|
return *pbstrName ? S_OK : E_FAIL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CNmMember::GetID(ULONG *puID)
|
|
{
|
|
if (NULL == puID)
|
|
return E_POINTER;
|
|
|
|
*puID = m_dwGCCID;
|
|
return (0 != m_dwGCCID) ? S_OK : NM_E_NO_T120_CONFERENCE;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CNmMember::GetNmVersion(ULONG *puVersion)
|
|
{
|
|
if (NULL == puVersion)
|
|
return E_POINTER;
|
|
|
|
*puVersion = (ULONG) HIWORD(m_dwFlags & PF_VER_MASK);
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CNmMember::GetAddr(BSTR *pbstrAddr, NM_ADDR_TYPE *puType)
|
|
{
|
|
if ((NULL == pbstrAddr) || (NULL == puType))
|
|
return E_POINTER;
|
|
|
|
TCHAR szIp[MAX_PATH];
|
|
|
|
if (S_OK != GetIpAddr(szIp, CCHMAX(szIp)))
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
*puType = NM_ADDR_IP;
|
|
*pbstrAddr = SysAllocString(CUSTRING(szIp));
|
|
|
|
return *pbstrAddr ? S_OK : E_FAIL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CNmMember::SetUserData(REFGUID rguid, BYTE *pb, ULONG cb)
|
|
{
|
|
return m_UserData.AddUserData((GUID *)&rguid,(unsigned short)cb,pb);
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CNmMember::GetUserData(REFGUID rguid, BYTE **ppb, ULONG *pcb)
|
|
{
|
|
return m_UserData.GetUserData(rguid,ppb,pcb);
|
|
}
|
|
|
|
STDMETHODIMP CNmMember::GetConference(INmConference **ppConference)
|
|
{
|
|
return ::GetConference(ppConference);
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CNmMember::GetNmchCaps(ULONG *puCaps)
|
|
{
|
|
if (NULL == puCaps)
|
|
return E_POINTER;
|
|
|
|
if (m_dwFlags & PF_T120)
|
|
{
|
|
// this can be removed when NMCH_SHARE and NMCH_DATA is reliable
|
|
*puCaps = m_uNmchCaps | NMCH_SHARE | NMCH_DATA;
|
|
}
|
|
else
|
|
{
|
|
*puCaps = m_uNmchCaps;
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CNmMember::GetShareState(NM_SHARE_STATE *puState)
|
|
{
|
|
return(E_FAIL);
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CNmMember::IsSelf(void)
|
|
{
|
|
return m_fLocal ? S_OK : S_FALSE;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CNmMember::IsMCU(void)
|
|
{
|
|
return (m_dwFlags & PF_T120_MCU) ? S_OK : S_FALSE;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CNmMember::Eject(void)
|
|
{
|
|
if (m_fLocal)
|
|
return E_FAIL; // can't eject ourselves.
|
|
|
|
if (PF_T120 & m_dwFlags)
|
|
{
|
|
CNmMember * pMemberLocal = GetLocalMember();
|
|
if ((NULL == pMemberLocal) || !pMemberLocal->FTopProvider())
|
|
return E_FAIL; // only top providers should be allowed to do this
|
|
|
|
CConfObject * pco = ::GetConfObject();
|
|
if (NULL != pco)
|
|
{
|
|
ASSERT(g_pNodeController);
|
|
ASSERT(pco->GetConfHandle());
|
|
pco->GetConfHandle()->EjectUser(m_dwGCCID);
|
|
}
|
|
}
|
|
|
|
if (NULL != m_pConnection)
|
|
{
|
|
HRESULT hr = m_pConnection->Disconnect();
|
|
if (FAILED(hr))
|
|
{
|
|
WARNING_OUT(("m_pConnection->Disconnect() failed - hr = %s",
|
|
::GetHRESULTString(hr)));
|
|
}
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
// Utility Functions
|
|
|
|
|
|
/* G E T L O C A L M E M B E R */
|
|
/*-------------------------------------------------------------------------
|
|
%%Function: GetLocalMember
|
|
|
|
-------------------------------------------------------------------------*/
|
|
CNmMember * GetLocalMember(void)
|
|
{
|
|
CConfObject * pco = ::GetConfObject();
|
|
if (NULL == pco)
|
|
return NULL;
|
|
|
|
return pco->GetLocalMember();
|
|
}
|
|
|
|
|
|
/* P M E M B E R F R O M G C C I D */
|
|
/*-------------------------------------------------------------------------
|
|
%%Function: PMemberFromGCCID
|
|
|
|
-------------------------------------------------------------------------*/
|
|
CNmMember * PMemberFromGCCID(UINT uNodeID)
|
|
{
|
|
CConfObject* pco = ::GetConfObject();
|
|
if (NULL == pco)
|
|
return NULL;
|
|
|
|
return pco->PMemberFromGCCID(uNodeID);
|
|
}
|
|
|
|
|
|
/* P M E M B E R F R O M N O D E G U I D */
|
|
/*-------------------------------------------------------------------------
|
|
%%Function: PMemberFromNodeGuid
|
|
|
|
-------------------------------------------------------------------------*/
|
|
CNmMember * PMemberFromNodeGuid(REFGUID rguidNode)
|
|
{
|
|
CConfObject* pco = ::GetConfObject();
|
|
if (NULL == pco)
|
|
return NULL;
|
|
|
|
return pco->PMemberFromNodeGuid(rguidNode);
|
|
}
|
|
|
|
CNmMember * PDataMemberFromName(PCWSTR pwszName)
|
|
{
|
|
CConfObject* pco = ::GetConfObject();
|
|
if (NULL == pco)
|
|
return NULL;
|
|
|
|
return pco->PDataMemberFromName(pwszName);
|
|
}
|