⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chatsession.cpp

📁 com编程
💻 CPP
📖 第 1 页 / 共 2 页
字号:
            }
            break;
        }
    }
    Unlock();
    if (pcFetched)
        *pcFetched = cActual;
    return cElems == cActual ? S_OK : S_FALSE;
}

STDMETHODIMP 
StatementEnumerator::Skip(ULONG cElems)
{
    Lock();
    ULONG cActual = 0;
    while (cActual < cElems 
           && m_cursor != m_pThis->m_statements.end())
    {
        m_cursor++;
        cActual++;
    }
    Unlock();
    return cElems == cActual ? S_OK : S_FALSE;
}

STDMETHODIMP 
StatementEnumerator::Reset(void)
{
    Lock();
    m_cursor = m_pThis->m_statements.begin();
    Unlock();
    return S_OK;
}

STDMETHODIMP 
StatementEnumerator::Clone(IEnumString **ppes)
{
    if (ppes == 0)
        return E_INVALIDARG;
    if (*ppes = new StatementEnumerator(m_pThis))
        return S_OK;
    return E_OUTOFMEMORY;
}

// class ChatSessionClass /////////////////////

ChatSessionClass::ChatSessionClass(void)
: m_cStrongLocks(0)
{
    InitializeCriticalSection(&m_csSessionLock);
}

ChatSessionClass::~ChatSessionClass(void)
{
    DeleteCriticalSection(&m_csSessionLock);
}

void
ChatSessionClass::Lock(void)
{
    EnterCriticalSection(&m_csSessionLock);
}

void
ChatSessionClass::Unlock(void)
{
    LeaveCriticalSection(&m_csSessionLock);
}
// helper method to protect access to DeleteSession
// to only allow COMChat Admins to delete groups
bool 
ChatSessionClass::CheckAccess(const OLECHAR *pwszUser)
{
    if (wcscmp(pwszUser, L"anonymous") == 0)
        return false;

    TRUSTEEW trustee = {
        0, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_NAME, 
        TRUSTEE_IS_USER, const_cast<OLECHAR*>(pwszUser)
    };
    BOOL bIsAllowed;
    HRESULT hr = g_pacAdmins->IsAccessAllowed(&trustee,0,
                                              COM_RIGHTS_EXECUTE,
                                              &bIsAllowed);
    if (FAILED(hr))
        bIsAllowed = false;
    return SUCCEEDED(hr) && bIsAllowed != FALSE;
}


// IUnknown methods
STDMETHODIMP 
ChatSessionClass::QueryInterface(REFIID riid, void **ppv)
{
    if (riid == IID_IUnknown)
        *ppv = static_cast<IChatSessionManager*>(this);
    else if (riid == IID_IChatSessionManager)
        *ppv = static_cast<IChatSessionManager*>(this);
    else if (riid == IID_IExternalConnection)
        *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;
    }
    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)
{
    if (ppes == 0)
        return E_INVALIDARG;
    SessionNamesEnumerator *pCloneSource = m_pCloneSource;
    if (pCloneSource == 0) // we are the source
        m_pCloneSource = this;
    *ppes = new SessionNamesEnumerator(pCloneSource);
    if (*ppes)
    {
        (*ppes)->AddRef();
        return S_OK;
    }
    return E_OUTOFMEMORY;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -