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

📄 contentdirectoryservice.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//

#include "av_dcp.h"
#include "av_upnp.h"

using namespace av_upnp;

/////////////////////////////////////////////////////////////////////////////
// ContentDirectoryServiceImpl

namespace av_upnp
{
namespace details
{
    const DWORD g_nCDMinModeratedEventSleepPeriodms = 2000; // as specified by CDS's spec, the min time between moderated events
}
}


ContentDirectoryServiceImpl::ContentDirectoryServiceImpl()
    : m_pContentDirectory(NULL),
      ModeratedEventSupport(details::g_nCDMinModeratedEventSleepPeriodms),
      m_bSystemUpdateIDChanged(false)
{
    InitErrDescrips();
    InitToolkitErrs();
    InitDISPIDs();
}


ContentDirectoryServiceImpl::~ContentDirectoryServiceImpl()
{
    if(m_pContentDirectory)
        const DWORD retUnadvise = m_pContentDirectory->Unadvise(this);
        // if Unadvise() fails, we can do nothing but ignore.
}


DWORD ContentDirectoryServiceImpl::Init(/* [in] */ IContentDirectory* pIContentDirectory)
{
    if(m_pContentDirectory)
        return ERROR_AV_ALREADY_INITED;

    if(!pIContentDirectory)
        return ERROR_AV_POINTER;


    m_pContentDirectory = pIContentDirectory;


    const DWORD retAdvise = m_pContentDirectory->Advise(this);
    if(SUCCESS_AV != retAdvise)
        return retAdvise;

    return SUCCESS_AV;
}



//
// IEventSink
//

DWORD ContentDirectoryServiceImpl::OnStateChanged(
                                    /*[in]*/ LPCWSTR pszStateVariableName,
                                    /*[in*/  LPCWSTR pszValue)
{
    if(!pszStateVariableName || !pszValue)
        return ERROR_AV_POINTER;

    DWORD ret = SUCCESS_AV;

    ce::gate<ce::critical_section> csEventsLock(m_csEvents);

    if(0 == wcscmp(ContentDirectoryState::SystemUpdateID, pszStateVariableName))
    {
        // This is a moderated event
        // Mark that this moderated variable has been updated and store its value for get_ to retrieve later on

        if(!m_bSystemUpdateIDChanged)
        {
            m_bSystemUpdateIDChanged = true;

            // no updates -> an update exists, notify TimedEventCaller
            AddRefModeratedEvent();
        }
    }
    else if(0 == wcscmp(ContentDirectoryState::ContainerUpdateIDs, pszStateVariableName))
    {
        // This is a moderated event
        // Mark that this moderated variable has been updated and store its value for get_ to retrieve later on

        wstring             strContainerID, strUpdateID;
        wstring::size_type  n;
        
        strContainerID = pszValue;
        
        if(wstring::npos == (n = strContainerID.find(L",")))
            return ERROR_AV_INVALID_STATEVAR;
        
        strContainerID.resize(n);
        strUpdateID = pszValue + n + 1;
        
        if(strContainerID.empty())
            return ERROR_AV_INVALID_STATEVAR;
        
        if(strUpdateID.empty())
            return ERROR_AV_INVALID_STATEVAR;
        
        if(wstring::npos != strUpdateID.find(L","))
            return ERROR_AV_INVALID_STATEVAR;

        ContainerUpdateIDsMap::iterator it;
        
        it = m_mapContainerUpdateIDs.find(strContainerID);
        
        if(m_mapContainerUpdateIDs.end() == it)
        {
            if(m_mapContainerUpdateIDs.end() == m_mapContainerUpdateIDs.insert(strContainerID, strUpdateID))
                return ERROR_AV_OOM;
            
            if(1 == m_mapContainerUpdateIDs.size())
                // no updates -> an update exists, notify TimedEventCaller
                AddRefModeratedEvent();
        }
        else
            it->second = strUpdateID;
    }
    else
    {
        if(0 == wcscmp(ContentDirectoryState::TransferIDs, pszStateVariableName))
        {
            // This is a non-moderated event that CDSImpl implements, store its new value for get_ to retrieve
            // (and pass on to IEventSinkSupport like all non-moderated events)

            m_strTransferIDs = pszValue;
        }

        // This is a non-moderated event, pass on to IEventSinkSupport to notify subscriber

        ret = IEventSinkSupport::OnStateChanged(pszStateVariableName, pszValue);
    }


    return ret;
}

        
DWORD ContentDirectoryServiceImpl::OnStateChanged(
                                    /*[in]*/ LPCWSTR pszStateVariableName,
                                    /*[in*/  long nValue)
{
    if(!pszStateVariableName)
        return ERROR_AV_POINTER;


    // Convert nValue from a long to a LPCWSTR and pass on to the string version of OnStateChanged()

    wstring   strValue;
    const int nltowLimit = 33;
    
    strValue.reserve(nltowLimit);

    _ltow(nValue, strValue.get_buffer(), 10);

    return OnStateChanged(pszStateVariableName, strValue);
}


DWORD ContentDirectoryServiceImpl::OnStateChanged(
        /*[in]*/  LPCWSTR pszStateVariableName,
        /*[in]*/  LPCWSTR pszChannel,
        /*[in]*/  long nValue)
{
    // This overload of OnStateChanged is only for RenderingControl use
    return ERROR_AV_UPNP_ACTION_FAILED;
}



//
// TimedEventCallee
//

void ContentDirectoryServiceImpl::TimedEventCall()
{
    // If a state variable has been updated:
    // Send update to IEventSinkSupport, reset the updated flag, and remove this var's Ref from TimedEventCaller.
    // Ignore return values, we can't do anything in response here.

    ce::gate<ce::critical_section> csEventsLock(m_csEvents);

    if(m_bSystemUpdateIDChanged)
    {
        IEventSinkSupport::OnStateChanged(ContentDirectoryState::SystemUpdateID, (LPCWSTR)NULL);

        m_bSystemUpdateIDChanged = false;
        ReleaseModeratedEvent();
    }

    if(!m_mapContainerUpdateIDs.empty())
    {
        IEventSinkSupport::OnStateChanged(ContentDirectoryState::ContainerUpdateIDs, (LPCWSTR)NULL);

        m_mapContainerUpdateIDs.clear();
        ReleaseModeratedEvent();
    }
}



//
// IUPnPService_ContentDirectory1
//

STDMETHODIMP ContentDirectoryServiceImpl::get_TransferIDs(BSTR* pTransferIDs)
{
    if(!pTransferIDs)
        return E_POINTER;

   
    ce::gate<ce::critical_section> csEventsLock(m_csEvents);

    *pTransferIDs = SysAllocString(m_strTransferIDs);
    
    if(!*pTransferIDs)
        return m_ErrReport.ReportError(ERROR_AV_OOM);

    return S_OK;
}


// get_A_ARG_TYPE_foo() methods are implemented only to satisfy upnp's devicehost, they are not used

STDMETHODIMP ContentDirectoryServiceImpl::get_A_ARG_TYPE_ObjectID(BSTR* pA_ARG_TYPE_ObjectID)
{
    return S_OK;
}


STDMETHODIMP ContentDirectoryServiceImpl::get_A_ARG_TYPE_Result(BSTR* pA_ARG_TYPE_Result)
{
    return S_OK;
}


STDMETHODIMP ContentDirectoryServiceImpl::get_A_ARG_TYPE_SearchCriteria(BSTR* pA_ARG_TYPE_SearchCriteria)
{
    return S_OK;
}


STDMETHODIMP ContentDirectoryServiceImpl::get_A_ARG_TYPE_BrowseFlag(BSTR* pA_ARG_TYPE_BrowseFlag)
{
    return S_OK;
}


STDMETHODIMP ContentDirectoryServiceImpl::get_A_ARG_TYPE_Filter(BSTR* pA_ARG_TYPE_Filter)
{
    return S_OK;
}


STDMETHODIMP ContentDirectoryServiceImpl::get_A_ARG_TYPE_SortCriteria(BSTR* pA_ARG_TYPE_SortCriteria)
{
    return S_OK;
}


STDMETHODIMP ContentDirectoryServiceImpl::get_A_ARG_TYPE_Index(unsigned long* pA_ARG_TYPE_Index)
{
    return S_OK;
}


STDMETHODIMP ContentDirectoryServiceImpl::get_A_ARG_TYPE_Count(unsigned long* pA_ARG_TYPE_Count)
{
    return S_OK;
}


STDMETHODIMP ContentDirectoryServiceImpl::get_A_ARG_TYPE_UpdateID(unsigned long* pA_ARG_TYPE_UpdateID)
{
    return S_OK;
}


STDMETHODIMP ContentDirectoryServiceImpl::get_A_ARG_TYPE_TransferID(unsigned long* pA_ARG_TYPE_TransferID)
{
    return S_OK;
}


STDMETHODIMP ContentDirectoryServiceImpl::get_A_ARG_TYPE_TransferStatus(BSTR* pA_ARG_TYPE_TransferStatus)
{
    return S_OK;
}


STDMETHODIMP ContentDirectoryServiceImpl::get_A_ARG_TYPE_TransferLength(BSTR* pA_ARG_TYPE_TransferLength)
{
    return S_OK;
}


STDMETHODIMP ContentDirectoryServiceImpl::get_A_ARG_TYPE_TransferTotal(BSTR* pA_ARG_TYPE_TransferTotal)
{
    return S_OK;
}


STDMETHODIMP ContentDirectoryServiceImpl::get_A_ARG_TYPE_TagValueList(BSTR* pA_ARG_TYPE_TagValueList)

⌨️ 快捷键说明

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