Сущность технологии СОМ. Библиотека программиста
Шрифт:
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;
}
Unlock;
CoTaskMemFree(pwszUser);
return hr;
}
STDMETHODIMP
ChatSessionClass::DeleteSession(const OLECHAR *pwszSessionName)
{
if (pwszSessionName == 0)
return E_INVALIDARG;
HRESULT hr = E_FAIL;
OLECHAR *pwszUser = GetCaller;
if (CheckAccess(pwszUser))
{
Lock;
SESSIONMAP::iterator it
= m_sessions.find(pwszSessionName);
if (it == m_sessions.end)
{
hr = E_FAIL;
}
else
{
(*it).second->Disconnect;
(*it).second->Release;
m_sessions.erase(it);
hr = S_OK;
}
Unlock;
}
else
hr = E_ACCESSDENIED;
CoTaskMemFree(pwszUser);
return hr;
}
// class SessionNamesEnumerator
vector<wstring>&
SessionNamesEnumerator::Strings(void)
{
if (m_pStrings)
return *m_pStrings;
else
return *(m_pCloneSource->m_pStrings);
}
void
SessionNamesEnumerator::Lock(void)
{
EnterCriticalSection(&m_csLock);
}
void
SessionNamesEnumerator::Unlock(void)
{
LeaveCriticalSection(&m_csLock);
}
SessionNamesEnumerator::SessionNamesEnumerator(
ChatSessionClass *pSessionClass)
: m_cRef(0),
m_pStrings(0),
m_pCloneSource(0)
{
typedef ChatSessionClass::SESSIONMAP::iterator iterator;
ChatSessionClass::SESSIONMAP &sessions
= pSessionClass->m_sessions;
m_pStrings = new vector<wstring>;
pSessionClass->Lock;
for (iterator it = sessions.begin;
it != sessions.end;
it++)
{
m_pStrings->push_back((*it).first);
}
pSessionClass->Unlock;
m_cursor = Strings.begin;
InitializeCriticalSection(&m_csLock);
}
SessionNamesEnumerator::SessionNamesEnumerator(
SessionNamesEnumerator *pCloneSource)
: m_cRef(0),
m_pStrings(0),
m_pCloneSource(pCloneSource)
{
m_pCloneSource->AddRef;
m_cursor = Strings.begin;
InitializeCriticalSection(&m_csLock);
}
SessionNamesEnumerator::~SessionNamesEnumerator(void)
{
if (m_pCloneSource)
m_pCloneSource->Release;
else if (m_pStrings)
delete m_pStrings;
DeleteCriticalSection(&m_csLock);
}
// IUnknown methods
STDMETHODIMP
SessionNamesEnumerator::QueryInterface(REFIID riid, void **ppv)
{
if (riid == IID_IUnknown)
*ppv = static_cast<IEnumString*>(this);
else if (riid == IID_IEnumString)
*ppv = static_cast<IEnumString*>(this);
else
return (*ppv = 0), E_NOINTERFACE;
reinterpret_cast<IUnknown*>(*ppv)->AddRef;
return S_OK;
}
STDMETHODIMP_(ULONG)
SessionNamesEnumerator::AddRef(void)
{
ModuleLock;
return InterlockedIncrement(&m_cRef);
}
STDMETHODIMP_(ULONG)
SessionNamesEnumerator::Release(void)
{
LONG res = InterlockedDecrement(&m_cRef);
if (res == 0)
delete this;
ModuleUnlock;
return res;
}
// IEnumString methods
STDMETHODIMP
SessionNamesEnumerator::Next(ULONG cElems, OLECHAR **rgElems,
ULONG *pcFetched)
{
if (cElems > 1 && pcFetched == 0)
return E_INVALIDARG;
ULONG cActual = 0;
vector<wstring> &rstrings = Strings;
Lock;
while (cActual < cElems
&& m_cursor != rstrings.end)
{
if (rgElems[cActual] = OLESTRDUP((*m_cursor).c_str))
{
m_cursor++;
cActual++;
}
else // allocation error, unwind
{
while (cActual > 0)
{
cActual–;
CoTaskMemFree(rgElems[cActual]);
rgElems[cActual] = 0;
}
break;
}
}
Unlock;
if (cActual)
*pcFetched = cActual;
return cActual == cElems ? S_OK : S_FALSE;
}
STDMETHODIMP
SessionNamesEnumerator::Skip(ULONG cElems)
{
ULONG cActual = 0;
vector<wstring> &rstrings = Strings;
Lock;
while (cActual < cElems
&& m_cursor != rstrings.end)
{
m_cursor++;
cActual++;
}
Unlock;
return cActual == cElems ? S_OK : S_FALSE;
}
STDMETHODIMP
SessionNamesEnumerator::Reset(void)
{
Lock;
m_cursor = Strings.begin;
Unlock;
return S_OK;
}
STDMETHODIMP
SessionNamesEnumerator::Clone(IEnumString **ppes)