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

📄 av_upnp_ctrl_internal.h

📁 Windows CE 6.0 Server 源码
💻 H
📖 第 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.
//

//
// Declarations for internal implementation of the UPnP AV toolkit's control point functionality
//

#ifndef __AV_UPNP_CTRL_INTERNAL_H
#define __AV_UPNP_CTRL_INTERNAL_H

#include <hash_map.hxx>
#include <hash_set.hxx>
#include <sync.hxx>
#include <auto_xxx.hxx>

#ifndef UNDER_CE
#   include "desktop.h"
#endif

#include "sax.h"
#include "upnp_proxy.h"
#include "av_upnp.h"


namespace av_upnp
{
namespace details
{

extern DWORD AVErrorFromUPnPError(HRESULT hr);
extern bool GetService(IUPnPServices* pServices, LPCWSTR pszServiceID, LPCWSTR pszServiceType, IUPnPService** ppService);

// IEventSourceImpl
template<typename T>
class IEventSourceImpl : public T,
                         public IEventSink
{
public:
    virtual ~IEventSourceImpl()
    {
        // Every call to Advise must be matched with a call to Unadvise
        assert(m_setSink.empty());
    }

// av::IEventSource
public:
    // Advise
    virtual DWORD Advise(
            /*[in]*/ IEventSink *pSubscriber)
    {
        if(!pSubscriber)
            return ERROR_AV_POINTER;
        
        ce::gate<ce::critical_section_with_copy> gate(m_csSinkSet);
    
        if(m_setSink.end() != m_setSink.insert(pSubscriber))
            return SUCCESS_AV;
        else
        {
            DEBUGMSG(ZONE_AV_ERROR, (AV_TEXT("OOM when inserting subscriber")));
            return ERROR_AV_OOM;
        }
    }

    // Unadvise
    virtual DWORD Unadvise(
            /*[in]*/ IEventSink *pSubscriber)
    {
        ce::gate<ce::critical_section_with_copy> gate(m_csSinkSet);
    
        if(!m_setSink.erase(pSubscriber))
            return ERROR_AV_POINTER;
        else
            return SUCCESS_AV;
    }

// av::IEventSink
public:
    virtual DWORD OnStateChanged(
        /*[in]*/  LPCWSTR pszStateVariableName,
        /*[in]*/  LPCWSTR pszValue)
    {
        ce::gate<ce::critical_section_with_copy> gate(m_csSinkSet);
        
        for(EventSinkSet::iterator it = m_setSink.begin(), itEnd = m_setSink.end(); it != itEnd; ++it)
            (*it)->OnStateChanged(pszStateVariableName, pszValue);
        
        return SUCCESS_AV;
    }
        
    virtual DWORD OnStateChanged(
        /*[in]*/  LPCWSTR pszStateVariableName,
        /*[in]*/  long nValue)
    {
        ce::gate<ce::critical_section_with_copy> gate(m_csSinkSet);
        
        for(EventSinkSet::iterator it = m_setSink.begin(), itEnd = m_setSink.end(); it != itEnd; ++it)
            (*it)->OnStateChanged(pszStateVariableName, nValue);
        
        return SUCCESS_AV;
    }
    
    virtual DWORD OnStateChanged(
        /*[in]*/  LPCWSTR pszStateVariableName,
        /*[in]*/  LPCWSTR pszChannel,
        /*[in]*/  long nValue)
    {
        ce::gate<ce::critical_section_with_copy> gate(m_csSinkSet);
        
        for(EventSinkSet::iterator it = m_setSink.begin(), itEnd = m_setSink.end(); it != itEnd; ++it)
            (*it)->OnStateChanged(pszStateVariableName, pszChannel, nValue);
            
        return SUCCESS_AV;
    }
        
protected:
    typedef ce::hash_set<IEventSink*> EventSinkSet;

    ce::critical_section_with_copy  m_csSinkSet;
    EventSinkSet                    m_setSink;
};


//
// IUPnPServiceCallbackImpl
//
class IUPnPServiceCallbackImpl : public IUPnPServiceCallback
{
// IUPnPServiceCallback
public:
    // ServiceInstanceDied
    STDMETHOD(ServiceInstanceDied)(
            /* [in] */ IUPnPService*)
    {
        return S_OK;
    }
    
// IUnknown
public:
    STDMETHOD(QueryInterface)(
            /* [in] */ REFIID riid,
            /* [in] */ LPVOID* ppv)
    {
        if(InlineIsEqualGUID(riid, IID_IUnknown) || 
           InlineIsEqualGUID(riid, IID_IUPnPServiceCallback))
        {
            *ppv = this;
            return S_OK;
        }
        else
            return E_NOINTERFACE;
    }

    STDMETHOD_(ULONG, AddRef)(void)
        {return 1; }

    STDMETHOD_(ULONG, Release)(void)
        {return 1; }    
};


//
// ServiceCtrl
// 
template<typename T>
class ServiceCtrl : public IEventSourceImpl<T>,
                    protected IUPnPServiceCallbackImpl
{
public:
    ~ServiceCtrl()
    {
        if(m_pCallbackPrivate)
            m_pCallbackPrivate->RemoveTransientCallback(m_dwCookie);
    }
    
    bool Init(IUPnPService* pService, IUPnPDevice* pDevice)
    {
        assert(pService);
        assert(pDevice);
        
        HRESULT hr;
        
        if(SUCCEEDED(hr = pService->QueryInterface(IID_IUPnPServiceCallbackPrivate, (void**)&m_pCallbackPrivate)))
        {
            if(FAILED(hr = m_pCallbackPrivate->AddTransientCallback(static_cast<IUPnPServiceCallbackImpl*>(this), &m_dwCookie)))
            {
                DEBUGMSG(ZONE_AV_ERROR, (AV_TEXT("AddTransientCallback failed with error 0x%08x"), hr));
                return false;
            }
        }
        else
        {
            DEBUGMSG(ZONE_AV_ERROR, (AV_TEXT("QueryInterface(IID_IUPnPServiceCallbackPrivate) failed 0x%08x"), hr));
            return false;
        }
        
        return true;
    }

// IUPnPServiceCallback
public:
    // StateVariableChanged
    STDMETHOD(StateVariableChanged)(
            /* [in] */ IUPnPService*,
            /* [in] */ LPCWSTR pcwszStateVarName,
            /* [in] */ VARIANT varValue)
    {
#ifdef DEBUG
        ce::variant varTemp;
        
        if(FAILED(VariantChangeType(&varTemp, &varValue, 0, VT_BSTR)))
            varTemp.bstrVal = L"<unknown>";

        DEBUGMSG(ZONE_AV_TRACE, (AV_TEXT("Event: %s=%s"), pcwszStateVarName, varTemp.bstrVal));
#endif        
        
        if(varValue.vt == VT_BSTR)
        {
            OnStateChanged(pcwszStateVarName, varValue.bstrVal);
        }
        else
        {
            ce::variant varDest;
            
            if(SUCCEEDED(VariantChangeType(&varDest, &varValue, 0, VT_I4)))
            {
                OnStateChanged(pcwszStateVarName, varDest.lVal);
            }
            else
            {
                DEBUGMSG(ZONE_AV_ERROR, (AV_TEXT("Received event of unsupported type %d for variable \"%s\""), varValue.vt, pcwszStateVarName));
            }
        }
        
        return S_OK;
    }
    
protected:
    CComPtr<IUPnPServiceCallbackPrivate>    m_pCallbackPrivate;
    DWORD                                   m_dwCookie;    
};


//
// LastChangeParsing
//
class LastChangeParsing : protected ce::SAXContentHandler
{
public:
    LastChangeParsing(LPCWSTR pszNamespace);
    
// ISAXContentHandler
protected:
    virtual HRESULT STDMETHODCALLTYPE startDocument(void);
    
    virtual HRESULT STDMETHODCALLTYPE startElement(
        /* [in] */ const wchar_t *pwchNamespaceUri,
        /* [in] */ int cchNamespaceUri,
        /* [in] */ const wchar_t *pwchLocalName,
        /* [in] */ int cchLocalName,
        /* [in] */ const wchar_t *pwchQName,
        /* [in] */ int cchQName,
        /* [in] */ ISAXAttributes *pAttributes);
    
    virtual HRESULT STDMETHODCALLTYPE endElement( 
        /* [in] */ const wchar_t *pwchNamespaceUri,
        /* [in] */ int cchNamespaceUri,
        /* [in] */ const wchar_t *pwchLocalName,
        /* [in] */ int cchLocalName,
        /* [in] */ const wchar_t *pwchQName,
        /* [in] */ int cchQName);

protected:
    virtual DWORD OnStateChanged(
        /*[in]*/  int     InstanceID,
        /*[in]*/  LPCWSTR pszStateVariableName,
        /*[in]*/  LPCWSTR pszValue) = 0;
        
    virtual DWORD OnStateChanged(
        /*[in]*/  int     InstanceID,
        /*[in]*/  LPCWSTR pszStateVariableName,
        /*[in]*/  long    nValue) = 0;

    virtual DWORD OnStateChanged(
        /*[in]*/  int     InstanceID,
        /*[in]*/  LPCWSTR pszStateVariableName,
        /*[in]*/  LPCWSTR pszChannel,
        /*[in]*/  long    nValue) = 0;

protected:
    struct StateVar
    {
        StateVar(bool bNumeric)
            : bNumeric(bNumeric)
            {}
        
        bool bNumeric;
    };
    
    int                             m_InstanceID;
    int                             m_nLevelsUnderInstanceID;
    bool                            m_bUnderInstanceID;
    wstring                         m_strEventElement;
    wstring                         m_strInstanceElement;
    ce::hash_map<wstring, StateVar> m_mapStateVars;
};


//
// IVirtualServiceRefCount
//
class IVirtualServiceRefCount
{
public:    
    virtual void ReleaseInstance(long InstanceID) = 0;
};


//
// VirtualServiceCtrl
//
template<typename I, typename T>
class VirtualServiceCtrl : private IUPnPServiceCallbackImpl,
                           private IVirtualServiceRefCount,
                           private LastChangeParsing
{
public:
    VirtualServiceCtrl()
        : LastChangeParsing(get_event_namespace<I>())
    {}
    
    ~VirtualServiceCtrl()
    {
        // Release must be called on every virtual service instance pointer obtained
        assert(m_mapInstances.empty());
        
        if(m_pCallbackPrivate)
            m_pCallbackPrivate->RemoveTransientCallback(m_dwCookie);
    }
    
    // Init
    bool Init(IUPnPService* pService, IUPnPDevice* pDevice)
    {
        assert(pService);
        assert(pDevice);
        
        // For now, hardcode which vars have numeric types in AVTransport and RenderingControl
        m_mapStateVars.insert(L"Brightness", true);
        m_mapStateVars.insert(L"Contrast", true);
        m_mapStateVars.insert(L"Sharpness", true);
        m_mapStateVars.insert(L"RedVideoGain", true);
        m_mapStateVars.insert(L"GreenVideoGain", true);
        m_mapStateVars.insert(L"BlueVideoGain", true);
        m_mapStateVars.insert(L"RedVideoBlackLevel", true);
        m_mapStateVars.insert(L"GreenVideoBlackLevel", true);
        m_mapStateVars.insert(L"BlueVideoBlackLevel", true);
        m_mapStateVars.insert(L"ColorTemperature", true);
        m_mapStateVars.insert(L"HorizontalKeystone", true);
        m_mapStateVars.insert(L"VerticalKeystone", true);
        m_mapStateVars.insert(L"Volume", true);
        m_mapStateVars.insert(L"VolumeDB", true);
        m_mapStateVars.insert(L"NumberOfTracks", true);
        m_mapStateVars.insert(L"CurrentTrack", true);
        
        m_pService = pService;
        

⌨️ 快捷键说明

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