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

📄 automationproxy.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:

                                psa = SafeArrayCreate(VT_UI1, 1, rgsabound);
                                
                                if(psa == NULL)
                                    return E_OUTOFMEMORY;

                                SafeArrayAccessData(psa, (void**)&pData);
                                
                                if(SDT_BIN_HEX == sdt)
                                {
                                    hr = ParseBinHex(pwszValue, cch, pData, &cbData, &pwcNext);
                                }
                                else
                                {
                                    Assert(SDT_BIN_BASE64 == sdt);

                                    hr = ParseBase64(pwszValue, cch, pData, &cbData, &pwcNext);
                                }
                                
                                if(SUCCEEDED(hr))
                                {
                                    pvarValue->parray = psa;
                                    pvarValue->vt = VT_ARRAY | VT_UI1;
                                    
                                    SafeArrayUnaccessData(psa);
                                    
                                    rgsabound[0].cElements = cbData;
                                    SafeArrayRedim(psa, rgsabound);
                                }
                                else
                                {
                                    SafeArrayUnaccessData(psa);
                                    SafeArrayDestroy(psa);
                                }
                            }
                            break;

        case SDT_BOOLEAN:   Assert(pvarValue->vt == VT_EMPTY);

                            if(0 == wcscmp(pwszValue, L"true") ||
                               0 == wcscmp(pwszValue, L"yes") ||
                               0 == wcscmp(pwszValue, L"1"))
                            {
                                pvarValue->vt = VT_BOOL;
                                pvarValue->boolVal = VARIANT_TRUE;
                                hr = S_OK;
                            }

                            if(0 == wcscmp(pwszValue, L"false") ||
                               0 == wcscmp(pwszValue, L"no") ||
                               0 == wcscmp(pwszValue, L"0"))
                            {
                                pvarValue->vt = VT_BOOL;
                                pvarValue->boolVal = VARIANT_FALSE;
                                hr = S_OK;
                            }
                            break;
    }

    return hr;
}


HRESULT 
CUPnPAutomationProxy::HrInvokeAction(
    UPNP_CONTROL_REQUEST    * pucreq,
    UPNP_CONTROL_RESPONSE   * pucresp)
{
    HRESULT                hr = S_OK;
    UPNP_CONTROL_RESPONSE  ucresp = {0};
    UPNP_ACTION            * pua = NULL;

    pua = LookupActionByName(pucreq->bstrActionName);

    if (pua)
    {
        // Check that we've got the right number of input arguments. 
        if (pua->cInArgs == pucreq->cInputArgs)
        {
            DWORD      cTotalArgs = 0;
            DWORD      cOutArgs = 0;
            VARIANTARG *rgvarg = NULL;
            VARIANTARG *rgvargData = NULL;
            VARIANT    varResult; 
            EXCEPINFO  excepInfo = {0};
            
            VariantInit(&varResult);

            // Build an array of arguments to pass to the service object.

            cTotalArgs = pua->cInArgs + pua->cOutArgs;

            if (pua->bRetVal)
            {
                Assert(cTotalArgs > 0);

                // In UTL, the retval is considered an out parameter. In the
                // automation world, it's considered separate, so reduce the
                // count of parameters by 1 if there is a retval.
                cTotalArgs--; 
            }

            cOutArgs = cTotalArgs - pua->cInArgs;

            if (cTotalArgs > 0)
            {
                rgvarg = new VARIANTARG[cTotalArgs];
                
                if (cOutArgs > 0)
                {
                    rgvargData = new VARIANTARG[cOutArgs];
                }

                if (rgvarg && (!cOutArgs || rgvargData))
                {
                    // Have to copy the arguments in reverse order. Out args
                    // go first.                     
                    
                    for (DWORD i = 0,
                         index = pua->cOutArgs - 1; 
                         SUCCEEDED(hr) && (i < cOutArgs); 
                         i++, index--)
                    {
                        const UPNP_STATE_VARIABLE * pusvRelated = NULL;

                        pusvRelated = pua->rgOutArgs[index].pusvRelated;

                        hr = HrVariantInitForXMLType(&rgvargData[i], pusvRelated->strDataType);

                        if (SUCCEEDED(hr))
                        {
                            rgvarg[i].vt = rgvargData[i].vt | VT_BYREF;
                            rgvarg[i].pdblVal = &(rgvargData[i].dblVal);

                            if (SUCCEEDED(hr))
                            {
                                TraceTag(ttidAutomationProxy,
                                         "CUPnPAutomationProxy::HrInvokeAction(): "
                                         "Successfully initialized output arg %d",
                                         i);
                            }
                            else
                            {
                                TraceError("CUPnPAutomationProxy::HrInvokeAction(): "
                                           "Failed to initialize output argument",
                                           hr);
                            }                        
                        }
                        else
                        {
                            TraceError("CUPnPAutomationProxy::HrInvokeAction(): "
                                       "Failed to initialize for XML data type",
                                       hr);
                        }
                    }

                    if (SUCCEEDED(hr))
                    {
                        // Now the in arguments. 
                        // i is the index into the array of arguments we'll 
                        // pass to IDispatch::Invoke. It starts at the first
                        // index after the out arguments. j is the index into
                        // the array of input arguments - it starts at the last
                        // and goes down to the first. 

                        for (DWORD i = cOutArgs, j = pucreq->cInputArgs - 1; 
                             i < cTotalArgs; 
                             i++, j--)
                        {
                            Assert(pucreq->rgvarInputArgs[j].vt == VT_BSTR);

                            VariantInit(&rgvarg[i]);

                            Decode(pucreq->rgvarInputArgs[j].bstrVal, pua->rgInArgs[j].pusvRelated->strDataType, &rgvarg[i]);
                        }
                    }
                }
                else
                {
                    hr = E_OUTOFMEMORY;
                    TraceError("CUPnPAutomationProxy::HrInvokeAction(): "
                               "Failed to allocate arguments array",
                               hr);
                }
            }
            else
            {
                rgvarg = NULL;
            }

            // Now we have the arguments sorted out. Execute the request. 

            if (SUCCEEDED(hr))
            {
                DISPPARAMS actionParams;
                
                actionParams.rgvarg = rgvarg;
                actionParams.cArgs = cTotalArgs;
                actionParams.rgdispidNamedArgs = NULL;
                actionParams.cNamedArgs = 0;

                hr = m_pdispService->Invoke(pua->dispid,
                                            IID_NULL,
                                            LOCALE_SYSTEM_DEFAULT,
                                            DISPATCH_METHOD,
                                            &actionParams,
                                            &varResult,
                                            &excepInfo, 
                                            NULL);
            }

            // Build a response.

            if (SUCCEEDED(hr))
            {
                UPNP_CONTROL_RESPONSE_DATA * pucrd = NULL;

                TraceTag(ttidAutomationProxy,
                         "CUPnPAutomationProxy::HrInvokeAction(): "
                         "Action %S executed successfully",
                         pua->strName);

                ucresp.bstrActionName = SysAllocString(pua->strName);

                if (ucresp.bstrActionName)
                {
                    ucresp.fSucceeded = TRUE;                
                    pucrd = &ucresp.ucrData;

                    if (pua->cOutArgs > 0)
                    {
                        pucrd->Success.rgvarOutputArgs = (VARIANT *) CoTaskMemAlloc(
                            pua->cOutArgs * sizeof(VARIANT));

                        if (pucrd->Success.rgvarOutputArgs)
                        {
                            DWORD dwStartIndex = 0;

                            pucrd->Success.cOutputArgs = pua->cOutArgs;

                            if (pua->bRetVal)
                            {
                                VariantInit(&pucrd->Success.rgvarOutputArgs[0]);

                                hr = StringizeVariant(&varResult, pua->rgOutArgs[0].pusvRelated->strDataType);
                                
                                if (SUCCEEDED(hr))
                                    hr = VariantCopy(&pucrd->Success.rgvarOutputArgs[0], &varResult);

                                if (SUCCEEDED(hr))
                                {
                                    dwStartIndex = 1;
                                    TraceTag(ttidAutomationProxy,
                                             "CUPnPAutomationProxy::"
                                             "HrInvokeAction(): "
                                             "Successfully copied retval");
                                }
                                else
                                {
                                    TraceError("CUPnPAutomationProxy::"
                                               "HrInvokeAction(): "
                                               "Failed to copy retval",
                                               hr);
                                }
                            }

                            if (SUCCEEDED(hr))
                            {
                                for (DWORD i = 0,
                                     j = cOutArgs + dwStartIndex - 1; 
                                     SUCCEEDED(hr) && (i < cOutArgs); 
                                     i++, j--)
                                {
                                    VariantInit(&pucrd->Success.rgvarOutputArgs[j]);
                                    
                                    hr = StringizeVariant(&rgvargData[i], pua->rgOutArgs[j].pusvRelated->strDataType);
                                
                                    if (SUCCEEDED(hr))
                                        hr = VariantCopy(&pucrd->Success.rgvarOutputArgs[j], &rgvargData[i]);

                                    if (SUCCEEDED(hr))
                                    {
                                        TraceTag(ttidAutomationProxy,
                                                 "CUPnPAutomationProxy::"
                                                 "HrInvokeAction(): "
                                                 "Successfully copied out arg %d",
                                                 j);
                                    }
                                    else
                                    {
                                        TraceError("CUPnPAutomationProxy::"
                                                   "HrInvokeAction(): "
                                                   "Failed to copy out arg",
                                                   hr);
                                    }
                                }
                            }

                        }
                        else
                        {
                            hr = E_OUTOFMEMORY;
                            TraceError("CUPnPAutomationProxy::HrInvokeAction(): "
                                       "Failed to allocate memory for out args",
                                       hr);
                        }

                    }
                    else
                    {
                        pucrd->Success.rgvarOutputArgs = NULL;
                        pucrd->Success.cOutputArgs = 0;
                    }
                }
                else
                {
                    hr = E_OUTOFMEMORY;
                    TraceError("CUPnPAutomationProxy::HrInvokeAction(): "
                               "Failed to allocate memory for action name",
                               hr);
                }

            }
            else if (DISP_E_EXCEPTION == hr)
            {
                UPNP_CONTROL_RESPONSE_DATA * pucrd = NULL;               

                TraceTag(ttidAutomationProxy,
                         "CUPnPAutomationProxy::HrInvokeAction(): "
                         "Action %S returned an exception",
                         pua->strName);
                
                // Fix up the HRESULT. Even though this is an error in the
                // UPnP sense, we are returning success because from the 
                // processing point of view, the request went through correctly 
                // and just returned a fault response. 
                hr = S_OK;

                ucresp.bstrActionName = SysAllocString(pua->strName);

                if (ucresp.bstrActionName)
                {
                    ucresp.fSucceeded = FALSE;
                    pucrd = &ucresp.ucrData;

                    // If the service object requested deferred fill-in of
                    // the exception info, call its callback function now. 

                    if (excepInfo.pfnDeferredFillIn)
                    {
                        hr = (*(excepInfo.pfnDeferredFillIn))(&excepInfo);

                        if (SUCCEEDED(hr))
                        {
                            TraceTag(ttidAutomationProxy,
                                     "CUPnPAutomationProxy::HrInvokeAction(): "
                                     "Successfully filled in "
                                     "deferred exception info");                                    
                        }
                        else
                        {
                            TraceError("CUPnPAutomationProxy::HrInvokeAction(): "
                                       "Failed to fill in "
                                       "deferred exception info",
                                       hr);
                        }
                    }

                    if (SUCCEEDED(hr))
                    {
                        hr = HrBuildFaultResponse(pucrd,
                                                  L"SOAP-ENV:Client",
                                                  L"UPnPError",
                                                  excepInfo.bstrSource,
                                                  excepInfo.bstrDescription);
                    }
                }
                else
                {
                    hr = E_OUTOFMEMORY;
                    TraceError("CUPnPAutomationProxy::HrInvokeAction(): "
                               "Failed to allocate memory for action name",
                               hr);

⌨️ 快捷键说明

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