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

📄 upnp_proxy.h

📁 Windows CE 6.0 Server 源码
💻 H
📖 第 1 页 / 共 2 页
字号:
//
// 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.
//

#ifndef __UPNP_PROXY__
#define __UPNP_PROXY__

#include <safe_array.hxx>
#include <variant.h>

#ifndef ZONE_UPNP_PROXY_ERROR
#   define ZONE_UPNP_PROXY_ERROR DEBUGZONE(0)
#endif

#ifndef ZONE_UPNP_PROXY_WARN
#   define ZONE_UPNP_PROXY_WARN DEBUGZONE(1)
#endif

#ifndef ZONE_UPNP_PROXY_TRACE
#   define ZONE_UPNP_PROXY_TRACE DEBUGZONE(2)
#endif

#ifndef UPNP_PROXY_TEXT
#   define UPNP_PROXY_TEXT(string) TEXT("UPNP PROXY: ") TEXT(string)
#endif

namespace ce
{

class upnp_proxy
{
public:
    upnp_proxy(IUPnPService *pService = NULL)
        : m_pService(pService)
        {}
    
    void init(IUPnPService *pService)
    {
        assert(!m_pService);
        m_pService = pService;
    }
    
    // invoke
    HRESULT invoke(/* [in] */ LPCWSTR pszAction,
                   /* [in] */ DISPPARAMS* pdispparams, 
                   /* [in, out] */ VARIANT* pRetval)
    {
        HRESULT     hr;
        
#ifndef NO_INVOKE_FOR_UPNP_ACTIONS
        //
        // UPnP control point APIs on CE support invoking UPnP actions using IDispatch::Invoke
        //
        EXCEPINFO   ExcepInfo;
        UINT        uArgErr;
        DISPID      rgDispId[1];

        if(SUCCEEDED(hr = m_pService->GetIDsOfNames(IID_NULL, const_cast<LPOLESTR*>(&pszAction), 1, 0, rgDispId)))
        {
            hr =  m_pService->Invoke(rgDispId[0], IID_NULL, 0, DISPATCH_METHOD, pdispparams, pRetval, &ExcepInfo, &uArgErr);
        
            if(hr == DISP_E_EXCEPTION)
            {
                assert(FAILED(ExcepInfo.scode));
                
                hr = ExcepInfo.scode;
            }
        }
            
        return hr;
#else
        //
        // UPnP control point APIs on XP don't support invoking UPnP actions using IDispatch::Invoke
        // To use IUPnPService::InvokeAction we must copy arguments between safe arrays and DISPPARAMS structure
        //
        
        if(!pdispparams)
        {
            DEBUGMSG(ZONE_UPNP_PROXY_ERROR, (UPNP_PROXY_TEXT("pdispparams argument can't be NULL")));
            return E_POINTER;
        }
        
        unsigned i;
        long     j;
        
        // find first [in] argument
        for(i = 0; i < pdispparams->cArgs && (pdispparams->rgvarg[i].vt & VT_BYREF); ++i)
            ;
        
        ce::safe_array<ce::variant, VT_VARIANT> arrayIn(pdispparams->cArgs - i, 0);
        
        // copy [in] arguments to safe array; start from upper bound because DISPPARAMS arguments are in reverse order 
        for(j = arrayIn.ubound(); i < pdispparams->cArgs; ++i, --j)
        {
            assert(j >= arrayIn.lbound());
            
            arrayIn[j] = pdispparams->rgvarg[i];
        }
    
        // allocate BSTR action name
        ce::auto_bstr bstrAction;

        bstrAction = SysAllocString(pszAction);
        
        if(!bstrAction)
        {
            DEBUGMSG(ZONE_UPNP_PROXY_ERROR, (UPNP_PROXY_TEXT("OOM allocating BSTR action name \"%s\""), pszAction));
            return E_OUTOFMEMORY;
        }
        
        ce::variant vInArgs, vOutArgs;
        
        vInArgs.vt = VT_ARRAY | VT_VARIANT;
        vInArgs.parray = arrayIn.detach();

        // InvokeAction
        hr = m_pService->InvokeAction(bstrAction, vInArgs, &vOutArgs, pRetval);
        
        if(FAILED(hr))
        {
            DEBUGMSG(ZONE_UPNP_PROXY_WARN, (UPNP_PROXY_TEXT("Action \"%s\" failed 0x%08x"), pszAction, hr));
            return hr;
        }
        
        // transfer [out] arguemnts, if any, from safe array to DISPPARAMS
        if(vOutArgs.vt == (VT_ARRAY | VT_VARIANT))
        {
            ce::safe_array<ce::variant, VT_VARIANT> arrayOut;
            
            arrayOut.attach(vOutArgs.parray);
            
            arrayOut.lock();
            
            // copy [out] arguments starting from upper bound because arguments in DISPPARAMS are in reverse order
            for(i = 0, j = arrayOut.ubound(); j >= arrayOut.lbound() && i < pdispparams->cArgs; ++i, --j)
            {
                VARIANT* pvar = &arrayOut[j];
                
                assert(pvar);
                
                if((VT_BYREF | pvar->vt) != (pdispparams->rgvarg[i].vt))
                {
                    DEBUGMSG(ZONE_UPNP_PROXY_ERROR, (UPNP_PROXY_TEXT("Action \"%s\" returned [out] argument of type %d\n\tbut pdispparams->rgvarg[%d].vt = %d"), pszAction, pvar->vt, i, pdispparams->rgvarg[i].vt));
                    return E_INVALIDARG;
                }
                    
                switch(pvar->vt)
                {
                    case VT_I1:
                    case VT_UI1:
		                *V_UI1REF(pdispparams->rgvarg + i) = V_UI1(pvar);
      	                break;

                    case VT_I2:
                    case VT_UI2:
                    case VT_BOOL:
      	                *V_I2REF(pdispparams->rgvarg + i) = V_I2(pvar);
      	                break;

                    case VT_I4:
                    case VT_UI4:
                    case VT_INT:
                    case VT_UINT:
                    case VT_ERROR:
      	                *V_I4REF(pdispparams->rgvarg + i) = V_I4(pvar);
      	                break;

                    case VT_R4:
      	                *V_R4REF(pdispparams->rgvarg + i) = V_R4(pvar);
      	                break;

                    case VT_R8:
                    case VT_DATE:
      	                *V_R8REF(pdispparams->rgvarg + i) = V_R8(pvar);
      	                break;

                    case VT_CY:
      	                *V_CYREF(pdispparams->rgvarg + i) = V_CY(pvar);
      	                break;

                    case VT_BSTR:
    	                *V_BSTRREF(pdispparams->rgvarg + i) = SysAllocStringByteLen((char FAR *)V_BSTR(pvar), SysStringByteLen(V_BSTR(pvar)));
      	                break;

                    default:
                        assert(false);
                }
            }
        }
        
        return S_OK;

#endif // NO_INVOKE_FOR_UPNP_ACTIONS
    }
    
    
    //////////////////////////////////////////////
    // make UPnP call
    //////////////////////////////////////////////
    
    // 0 [in] argument
    HRESULT call(LPCWSTR pszAction, VARIANT* pRetval = NULL)
    {
        ce::safe_array<ce::variant, VT_VARIANT> arrayIn(0, 0);
        
        return invoke_action(pszAction, pRetval, *&arrayIn);
    }
    
    // 1 [in] argument
    template<typename T1>
    HRESULT call(LPCWSTR pszAction, T1 x1, VARIANT* pRetval = NULL)
    {
        ce::safe_array<ce::variant, VT_VARIANT> arrayIn(1);
        
        arrayIn[0] = x1;
            
        return invoke_action(pszAction, pRetval, *&arrayIn);
    }
    
    // 2 [in] arguments
    template<typename T1, typename T2>
    HRESULT call(LPCWSTR pszAction, T1 x1, T2 x2, VARIANT* pRetval = NULL)
    {
        ce::safe_array<ce::variant, VT_VARIANT> arrayIn(2);
        
        arrayIn[0] = x1;
        arrayIn[1] = x2;
            
        return invoke_action(pszAction, pRetval, *&arrayIn);
    }
    
    // 3 [in] arguments
    template<typename T1, typename T2, typename T3>
    HRESULT call(LPCWSTR pszAction, T1 x1, T2 x2, T3 x3, VARIANT* pRetval = NULL)
    {
        ce::safe_array<ce::variant, VT_VARIANT> arrayIn(3);
        
        arrayIn[0] = x1;
        arrayIn[1] = x2;
        arrayIn[2] = x3;
            
        return invoke_action(pszAction, pRetval, *&arrayIn);
    }
    
    // 4 [in] arguments
    template<typename T1, typename T2, typename T3, typename T4>
    HRESULT call(LPCWSTR pszAction, T1 x1, T2 x2, T3 x3, T4 x4, VARIANT* pRetval = NULL)
    {
        ce::safe_array<ce::variant, VT_VARIANT> arrayIn(4);
        
        arrayIn[0] = x1;
        arrayIn[1] = x2;
        arrayIn[2] = x3;
        arrayIn[3] = x4;
            
        return invoke_action(pszAction, pRetval, *&arrayIn);
    }
    
    // 5 [in] arguments
    template<typename T1, typename T2, typename T3, typename T4, typename T5>
    HRESULT call(LPCWSTR pszAction, T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, VARIANT* pRetval = NULL)
    {
        ce::safe_array<ce::variant, VT_VARIANT> arrayIn(5);
        
        arrayIn[0] = x1;
        arrayIn[1] = x2;
        arrayIn[2] = x3;
        arrayIn[3] = x4;
        arrayIn[4] = x5;
            
        return invoke_action(pszAction, pRetval, *&arrayIn);
    }
    
    // 6 [in] arguments
    template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
    HRESULT call(LPCWSTR pszAction, T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, T6 x6, VARIANT* pRetval = NULL)
    {
        ce::safe_array<ce::variant, VT_VARIANT> arrayIn(6);
        
        arrayIn[0] = x1;
        arrayIn[1] = x2;
        arrayIn[2] = x3;
        arrayIn[3] = x4;
        arrayIn[4] = x5;
        arrayIn[5] = x6;
            
        return invoke_action(pszAction, pRetval, *&arrayIn);
    }
    
    // 7 [in] arguments
    template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
    HRESULT call(LPCWSTR pszAction, T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, T6 x6, T7 x7, VARIANT* pRetval = NULL)
    {
        ce::safe_array<ce::variant, VT_VARIANT> arrayIn(7);
        
        arrayIn[0] = x1;
        arrayIn[1] = x2;
        arrayIn[2] = x3;
        arrayIn[3] = x4;
        arrayIn[4] = x5;
        arrayIn[5] = x6;
        arrayIn[6] = x7;
            
        return invoke_action(pszAction, pRetval, *&arrayIn);
    }
    
    // 8 [in] arguments
    template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
    HRESULT call(LPCWSTR pszAction, T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, T6 x6, T7 x7, T8 x8, VARIANT* pRetval = NULL)
    {
        ce::safe_array<ce::variant, VT_VARIANT> arrayIn(8);
        
        arrayIn[0] = x1;
        arrayIn[1] = x2;
        arrayIn[2] = x3;
        arrayIn[3] = x4;
        arrayIn[4] = x5;
        arrayIn[5] = x6;
        arrayIn[6] = x7;
        arrayIn[7] = x8;
            
        return invoke_action(pszAction, pRetval, *&arrayIn);
    }
    
    // 9 [in] arguments
    template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
    HRESULT call(LPCWSTR pszAction, T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, T6 x6, T7 x7, T8 x8, T9 x9, VARIANT* pRetval = NULL)
    {
        ce::safe_array<ce::variant, VT_VARIANT> arrayIn(9);
        
        arrayIn[0] = x1;
        arrayIn[1] = x2;
        arrayIn[2] = x3;
        arrayIn[3] = x4;
        arrayIn[4] = x5;
        arrayIn[5] = x6;
        arrayIn[6] = x7;
        arrayIn[7] = x8;

⌨️ 快捷键说明

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