*ppv = static_cast<IChatSession*>(this);
else if (riid == IID_IChatSession)
*ppv = static_cast<IChatSession*>(this);
else
return (*ppv = 0), E_NOINTERFACE;
reinterpret_cast<IUnknown*>(*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;
else if ((*ppwsz = OLESTRDUP(m_wszSessionName)) == 0)
return E_OUTOFMEMORY;
return S_OK;
}
STDMETHODIMP
ChatSession::Say(const OLECHAR *pwszStatement)
{
HRESULT hr = S_OK;
// protect access to method
OLECHAR *pwszUser = GetCaller();
if (pwszUser && CheckAccess(pwszUser))
{
SLock();
try
{
wstring s = pwszUser;
s += L':';
s += pwszStatement;
m_statements.push_back(s);
}
catch(...)
{
hr = E_OUTOFMEMORY;
}
SUnlock();
if (SUCCEEDED(hr))
Fire_OnNewStatement(pwszUser, pwszStatement);
}
else
hr = E_ACCESSDENIED;
CoTaskMemFree(pwszUser);
return hr;
}
STDMETHODIMP
ChatSession::GetStatements(IEnumString **ppes)
{
if (ppes == 0)
return E_INVALIDARG;
*ppes = new StatementEnumerator(this);
if (*ppes == 0)
return E_OUTOFMEMORY;
(*ppes)->AddRef();
return S_OK;
}
STDMETHODIMP
ChatSession::Advise(IChatSessionEvents *pEventSink,
DWORD *pdwReg)
{
HRESULT hr = S_OK;
if (pEventSink == 0 || pdwReg == 0)
return E_INVALIDARG;
LISTENER *pNew = new LISTENER;
if (pNew == 0)
return E_OUTOFMEMORY;
OLECHAR *pwszUser = GetCaller();
if (pwszUser)
{
Fire_OnNewUser(pwszUser);
ALock();
pNew->pwszUser = pwszUser;
if (pNew->pItf = pEventSink)
pEventSink->AddRef();
pNew->pNext = m_pHeadListeners;
if (m_pHeadListeners)
m_pHeadListeners->pPrev = pNew;
pNew->pPrev = 0;
m_pHeadListeners = pNew;
AUnlock();
}
else