(0)
{
wcscpy(m_wszSessionName, pwszSessionName);
InitializeCriticalSection(&m_csStatementLock);
InitializeCriticalSection(&m_csAdviseLock);
}
ChatSession::~ChatSession(void)
{
DeleteCriticalSection(&m_csStatementLock);
DeleteCriticalSection(&m_csAdviseLock);
// tear down connected listeners
while (m_pHeadListeners)
{
LISTENER *pThisNode = m_pHeadListeners;
if (pThisNode->pItf)
pThisNode->pItf->Release();
if (pThisNode->pwszUser)
CoTaskMemFree(pThisNode->pwszUser);
m_pHeadListeners = pThisNode->pNext;
delete pThisNode;
}
}
// helper methods ///////////
void ChatSession::Disconnect(void)
{
CoDisconnectObject(this, 0);
// tear down connected listeners
ALock();
while (m_pHeadListeners)
{
LISTENER *pThisNode = m_pHeadListeners;
if (pThisNode->pItf)
pThisNode->pItf->Release();
if (pThisNode->pwszUser)
CoTaskMemFree(pThisNode->pwszUser);
m_pHeadListeners = pThisNode->pNext;
delete pThisNode;
}
AUnlock();
}
// send the OnNewStatement event to all listeners
void
ChatSession::Fire_OnNewStatement(const OLECHAR *pwszUser,
const OLECHAR *pwszStatement)
{
ALock();
for (LISTENER *pNode = m_pHeadListeners;
pNode != 0; pNode = pNode->pNext)
{
if (pNode->pItf)
pNode->pItf->OnNewStatement(pwszUser, pwszStatement);
}
AUnlock();
}
// send the OnNewUser event to all listeners
void
ChatSession::Fire_OnNewUser(const OLECHAR *pwszUser)
{
ALock();
for (LISTENER *pNode = m_pHeadListeners;
pNode != 0; pNode = pNode->pNext)
{
if (pNode->pItf)
pNode->pItf->OnNewUser(pwszUser);
}
AUnlock();
}
// send the OnUserLeft event to all listeners
void
ChatSession::Fire_OnUserLeft(const OLECHAR *pwszUser)
{
ALock();
for (LISTENER *pNode = m_pHeadListeners;
pNode != 0; pNode = pNode->pNext)
{
if (pNode->pItf)
pNode->pItf->OnUserLeft(pwszUser);
}
AUnlock();
}
// lock wrappers
void ChatSession::SLock(void)
{
EnterCriticalSection(&m_csStatementLock);
}
void ChatSession::SUnlock(void)
{
LeaveCriticalSection(&m_csStatementLock);
}
void ChatSession::ALock(void)
{
EnterCriticalSection(&m_csAdviseLock);
}
void ChatSession::AUnlock(void)
{
LeaveCriticalSection(&m_csAdviseLock);
}
// helper method to check access to Say method
bool
ChatSession::CheckAccess(const OLECHAR *pwszUser)
{
if (wcscmp(pwszUser, L"anonymous") == 0)
return m_bAllowAnonymousAccess;
// form trustee from caller and use Access Control
// object hardwired to COMChat Users group
TRUSTEEW trustee = {
0, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_NAME,
TRUSTEE_IS_USER,
const_cast
(pwszUser)
};
BOOL bIsAllowed;
HRESULT hr = g_pacUsers->IsAccessAllowed(&trustee,0,
COM_RIGHTS_EXECUTE,
&bIsAllowed);
return SUCCEEDED(hr) && bIsAllowed != FALSE;
}
// IUnknown methods
STDMETHODIMP
ChatSession::QueryInterface(REFIID riid, void **ppv)
{
if (riid == IID_IUnknown)
*ppv = static_cast(this);
else if (riid == IID_IChatSession)
*ppv = static_cast(this);
else
return (*ppv = 0), E_NOINTERFACE;
reinterpret_cast(*ppv)->AddRef();
return S_OK;
}
STDMETHODIMP_(ULONG)
ChatSession::AddRef(void)
{
ModuleLock();
return InterlockedIncrement(&m_cRef);
}
STDMETHODIMP_(ULONG)
ChatSession::Release(void)
{
LONG res = InterlockedDecrement(&m_cRef);
if (res == 0)
delete this;
ModuleUnlock();
return res;
}
// IChatSession methods
STDMETHODIMP
ChatSession::get_SessionName(OLECHAR **ppwsz)
{
if (!ppwsz)
return E_INVALIDARG;