📄 wsdloper.cpp
字号:
// take one of the buffer guys and use him
VARIANT* _pvBuffer = &(pvBuffer[lCallIndex]);
VariantInit(_pvBuffer);
memcpy(_pvBuffer, _pvarg, sizeof(VARIANT));
V_VT(_pvarg) = V_VT(_pvBuffer) | VT_BYREF;
if (lVarType == (LONG) VT_DECIMAL)
{
V_DECIMALREF(_pvarg) = &V_DECIMAL(_pvBuffer);
}
else
{
if (lVarType == (LONG) VT_VARIANT)
{
V_VT(_pvarg) = VT_VARIANT | VT_BYREF;
V_VARIANTREF(_pvarg) = _pvBuffer;
if (V_VT(_pvBuffer) == VT_VARIANT)
{
// in the case of a '[out] Variant *' parameter:
// we should not point to a variant instance since we can not marshall this
V_VT(_pvBuffer) = VT_EMPTY;
}
}
else
{
pvarg[lCallIndex].pulVal = &(pvBuffer[lCallIndex].ulVal);
}
}
}
}
}
release(&pSoapMapper);
}
}
#ifdef CE_NO_EXCEPTIONS
{
BOOL fException;
hr = SafeInvoke(pDispatch,
&fException,
dispid,
IID_NULL,
LOCALE_SYSTEM_DEFAULT,
DISPATCH_METHOD,
&dispparams,
&varRes,
&exceptInfo,
&uArgErr);
if(fException)
{
hr = E_FAIL;
globalAddError(WSDL_IDS_OPERCAUSEDEXECPTION, WSDL_IDS_OPERATION, hr, m_bstrMethodName);
TRACEL((1, "\nInvoke of serverobject failed !!!\n\n"));
}
}
#else
try
{
hr = pDispatch->Invoke(dispid,
IID_NULL,
LOCALE_SYSTEM_DEFAULT,
DISPATCH_METHOD,
&dispparams,
&varRes,
&exceptInfo,
&uArgErr);
}
catch(...)
{
hr = E_FAIL;
globalAddError(WSDL_IDS_OPERCAUSEDEXECPTION, WSDL_IDS_OPERATION, hr, m_bstrMethodName);
TRACEL((1, "\nInvoke of serverobject failed !!!\n\n"));
}
#endif
if (FAILED(hr))
{
setupInvokeError(pDispatch, &exceptInfo, dispparams.cArgs-uArgErr, hr);
goto Cleanup;
}
// now set the values as they were coming back
dwCookie = 0;
while ((hr = m_pEnumSoapMappers->getNext(&pSoapMapper, &dwCookie))==S_OK)
{
CHK ( pSoapMapper->get_callIndex(&lCallIndex) );
if (lCallIndex == -1)
{
// take the return variant
CHK(pSoapMapper->put_comValue(varRes));
}
else
{
lCallIndex = dispparams.cArgs - lCallIndex;
if (V_ISBYREF(&(pvarg[lCallIndex])))
{
hr = pSoapMapper->put_comValue(pvBuffer[lCallIndex]);
VariantClear(&(pvBuffer[lCallIndex]));
if (FAILED(hr))
{
goto Cleanup;
}
}
}
release(&pSoapMapper);
}
if (SUCCEEDED(hr))
{
// ignore S_FALSE from the loop above
hr = S_OK;
}
// if we arrived here, all is well. Write headers
CHK(soapHeaders.WriteHeaders(pISoapSerializer, pDispatch));
Cleanup:
for (long i=0;i< (long)dispparams.cArgs;i++)
{
VariantClear(&(pvarg[i]));
VariantClear(&(pvBuffer[i]));
}
// clear possible contents in excpetioninfo
::SysFreeString(exceptInfo.bstrSource);
::SysFreeString(exceptInfo.bstrDescription);
::SysFreeString(exceptInfo.bstrHelpFile);
VariantClear(&varRes);
delete [] pvarg;
delete [] pvBuffer;
return (hr);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: HRESULT CWSDLOperation::setupInvokeErrorIDispatch *pDispatch, EXCEPINFO *pxcepInfo, unsigned int uArgErr, HRESULT hrErrorCode)
//
// parameters:
//
// description:
//
// returns:
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CWSDLOperation::setupInvokeError(IDispatch *pDispatch,
EXCEPINFO *pxcepInfo, unsigned int uArgErr,
HRESULT hrErrorCode)
{
HRESULT hr = S_OK;
CAutoRefc<ISoapMapper> pSoapMapper=0;
LONG lCallIndex;
#ifndef UNDER_CE
LONG lRes;
#endif
CAutoBSTR bstrName;
DWORD dwCookie;
// lets check if the object supported ISoapError. If so, get the SoapError information
globalAddErrorFromISoapError(pDispatch, hrErrorCode);
switch (hrErrorCode)
{
case DISP_E_BADPARAMCOUNT:
case DISP_E_PARAMNOTOPTIONAL:
globalAddError(WSDL_IDS_EXECBADPARAMCOUNT, WSDL_IDS_OPERATION, hrErrorCode, m_bstrMethodName);
break;
case DISP_E_BADVARTYPE:
globalAddError(WSDL_IDS_EXECBADVARTYPE, WSDL_IDS_OPERATION, hrErrorCode, m_bstrMethodName);
break;
case DISP_E_EXCEPTION:
globalAddErrorFromErrorInfo(pxcepInfo, hrErrorCode);
break;
case DISP_E_MEMBERNOTFOUND:
globalAddError(WSDL_IDS_EXECMEMBERNOTFOUND, WSDL_IDS_OPERATION, hrErrorCode, m_bstrMethodName);
break;
case DISP_E_TYPEMISMATCH:
case DISP_E_OVERFLOW:
// find the right mapper
dwCookie = 0;
while ((hr = m_pEnumSoapMappers->getNext(&pSoapMapper, &dwCookie))==S_OK)
{
hr = pSoapMapper->get_callIndex(&lCallIndex);
if (FAILED(hr))
{
goto Cleanup;
}
if (lCallIndex == (long)uArgErr)
{
// take the return variant
hr = pSoapMapper->get_elementName(&bstrName);
if (FAILED(hr))
{
goto Cleanup;
}
globalAddError(WSDL_IDS_EXECBADTYPE, WSDL_IDS_OPERATION, hrErrorCode, bstrName);
goto Cleanup;
}
release(&pSoapMapper);
}
// if we ever got here, than this most likely a problem in the WSML file (parameter number != real numbers)
globalAddError(WSDL_IDS_EXECBADTYPE, WSDL_IDS_OPERATION, hrErrorCode, _T("unknown"));
hr = S_OK;
break;
default:
globalAddError(WSDL_IDS_EXECUNKNOWNERROR, WSDL_IDS_OPERATION, hrErrorCode, hrErrorCode);
}
Cleanup:
globalAddError(WSDL_IDS_EXECFAILED, WSDL_IDS_OPERATION, hrErrorCode, m_bstrMethodName);
ASSERT(hr==S_OK);
return (hr);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: HRESULT CWSDLOperation::Init(IXMLDOMNode *pOperationNode, ISoapTypeMapperFactory *ptypeFactory,
// TCHAR *pchPortType, BOOL fDocumentMode, BSTR bstrpreferredEncoding, BOOL fCreateHrefs)
//
// parameters:
//
// description:
// walks the service node, get's the information it needs and creates holding
// objects for the subparts
//
// returns:
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CWSDLOperation::Init(IXMLDOMNode *pOperationNode, ISoapTypeMapperFactory *ptypeFactory,
TCHAR *pchPortType, BOOL fDocumentMode,
BSTR bstrpreferredEncoding, BOOL fCreateHrefs)
{
HRESULT hr = E_FAIL;
CAutoRefc<IXMLDOMNode> pSoapAction=0;
CAutoRefc<IXMLDOMNode> pPortInfo=0;
CAutoFormat autoFormat;
ASSERT(pOperationNode!=0);
ASSERT(pchPortType!=0);
m_pWSDLInputMessage = new CWSDLMessagePart();
m_pWSDLOutputMessage = new CWSDLMessagePart();
m_pEnumSoapMappers = new CSoapObject<CEnumSoapMappers>(INITIAL_REFERENCE);
#ifdef UNDER_CE
if(!m_pWSDLInputMessage || !m_pWSDLOutputMessage || !m_pEnumSoapMappers)
{
if(m_pWSDLInputMessage)
delete m_pWSDLInputMessage;
if(m_pWSDLOutputMessage)
delete m_pWSDLOutputMessage;
if(m_pEnumSoapMappers)
delete m_pEnumSoapMappers;
hr = E_OUTOFMEMORY;
goto Cleanup;
}
#endif
m_fDocumentMode = fDocumentMode;
m_fCreateHrefs = fCreateHrefs;
CHK(m_bstrpreferedEncoding.Assign(bstrpreferredEncoding));
if (!m_pWSDLInputMessage || !m_pWSDLOutputMessage || !m_pEnumSoapMappers || !m_bstrpreferedEncoding)
{
hr = E_OUTOFMEMORY;
goto Cleanup;
}
hr = _WSDLUtilFindAttribute(pOperationNode, _T("name"), &m_bstrName);
if (FAILED(hr))
{
globalAddError(WSDL_IDS_OPERNONAME, WSDL_IDS_OPERATION, hr);
goto Cleanup;
}
CHK(_WSDLUtilFindExtensionInfo(pOperationNode, 0, &m_fCreateHrefs));
CHK(_WSDLUtilFindDocumentation(pOperationNode, &m_bstrDocumentation));
TRACEL((3, "Operation Init %S\n", m_bstrName));
// now get the soapaction
hr = pOperationNode->selectSingleNode(_T("./soap:operation"), &pSoapAction);
if (FAILED(hr))
{
globalAddError(WSDL_IDS_OPERNOSOAPOPER, WSDL_IDS_OPERATION, hr, m_bstrName);
goto Cleanup;
}
hr = _WSDLUtilFindAttribute(pSoapAction, _T("soapAction"), &m_bstrSoapAction);
if (FAILED(hr))
{
globalAddError(WSDL_IDS_OPERNOSOAPACTION, WSDL_IDS_OPERATION, hr, m_bstrName);
goto Cleanup;
}
CHK(autoFormat.sprintf(_T("//def:portType[@name=\"%s\"]/def:operation[@name=\"%s\"]"), pchPortType, m_bstrName));
hr = _XPATHUtilFindNodeFromRoot(pOperationNode, &autoFormat, &pPortInfo);
if (FAILED(hr))
{
globalAddError(WSDL_IDS_OPERNOTFOUNDINPORT, WSDL_IDS_OPERATION, hr, &autoFormat);
goto Cleanup;
}
// this does not have to be there, it's optional
if (SUCCEEDED(_WSDLUtilFindAttribute(pPortInfo, _T("parameterOrder"), &m_bstrparameterOrder)))
{
prepareOrderString();
}
// let's see if style was overwritten, ignore HR, as this is a valid to be absent
_WSDLUtilGetStyle(pSoapAction,&m_fDocumentMode);
hr = m_pWSDLInputMessage->Init(pOperationNode, ptypeFactory, pchPortType, _T("input"), m_bstrName, this);
if (FAILED(hr))
{
globalAddError(WSDL_IDS_OPERINITINPUTFA, WSDL_IDS_OPERATION, hr, m_bstrName);
goto Cleanup;
}
hr = m_pWSDLOutputMessage->Init(pOperationNode, ptypeFactory, pchPortType, _T("output"), m_bstrName, this);
if (FAILED(hr))
{
if (hr != E_NOINTERFACE)
{
globalAddError(WSDL_IDS_OPERINITOUTPUTFA, WSDL_IDS_OPERATION, hr, m_bstrName);
goto Cleanup;
}
}
// if the input/output messages return S_FALSE, that indicates that those messageparts were not
// speced for SOAPbinding, but something else. ignore that, as we can not be called on those
hr = S_OK;
Cleanup:
ASSERT(hr==S_OK);
return (hr);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: HRESULT CWSDLOperation::prepareOrderString(void)
//
// parameters:
//
// description:
// takes the parameterOrder attribute and strtoks it.
// while doing so it creates an array of pointers to the substrings
// returns:
// S_OK or E_OUTOFMEMORY
/////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CWSDLOperation::prepareOrderString(void)
{
TCHAR *pchToken;
ULONG ulOrder = 0;
ULONG ulCount = 16;
HRESULT hr = S_OK;
delete [] m_ppchparameterOrder;
m_cbparaOrder = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -