*ppv = static_cast<IExternalConnection*>(this);
else
return (*ppv = 0), E_NOINTERFACE;
reinterpret_cast<IUnknown*>(*ppv)->AddRef();
return S_OK;
}
STDMETHODIMP_(ULONG)
ChatSessionClass::AddRef(void)
{
return 2;
}
STDMETHODIMP_(ULONG)
ChatSessionClass::Release(void)
{
return 1;
}
// IExternalConnection methods
STDMETHODIMP_(DWORD)
ChatSessionClass::AddConnection(DWORD extconn, DWORD)
{
if (extconn & EXTCONN_STRONG)
{
ModuleLock();
return InterlockedIncrement(&m_cStrongLocks);
}
return 0;
}
STDMETHODIMP_(DWORD)
ChatSessionClass::ReleaseConnection(DWORD extconn, DWORD,
BOOL bLastReleaseKillsStub)
{
if (extconn & EXTCONN_STRONG)
{
LONG res = InterlockedDecrement(&m_cStrongLocks);
if (res == 0 && bLastReleaseKillsStub)
CoDisconnectObject(
static_cast<IExternalConnection*>(this), 0);
ModuleUnlock();
return res;
}
return 0;
}
// IChatSessionManager methods
STDMETHODIMP
ChatSessionClass::GetSessionNames(IEnumString **ppes)
{
if (ppes == 0)
return E_INVALIDARG;
if (*ppes = new SessionNamesEnumerator(this))
{
(*ppes)->AddRef();
return S_OK;
}
else
return E_OUTOFMEMORY;
}
STDMETHODIMP
ChatSessionClass::FindSession(const OLECHAR *pwszSessionName,
BOOL bDontCreate,
BOOL bAllowAnonymousAccess,
IChatSession **ppcs)
{
if (ppcs == 0)
return E_INVALIDARG;
HRESULT hr = E_FAIL;
*ppcs = 0;
OLECHAR *pwszUser = GetCaller();
Lock();
SESSIONMAP::iterator it = m_sessions.find(pwszSessionName);
if (it == m_sessions.end())
{
if (bDontCreate)
hr = E_FAIL;
else if (!bAllowAnonymousAccess
&& wcscmp(pwszUser, L'anonymous') == 0)
hr = E_ACCESSDENIED;
else
{
ChatSession *pNew =
new ChatSession(pwszSessionName,
bAllowAnonymousAccess != FALSE);
if (pNew)
{
pNew->AddRef();
m_sessions.insert(
pair<wstring,
ChatSession*>(pwszSessionName,
pNew));
(*ppcs = pNew)->AddRef();
hr = S_OK;
}
else
hr = E_OUTOFMEMORY;
}
}
else
{
(*ppcs = (*it).second)->AddRef();
hr = S_OK;