📄 client.cpp
字号:
// function: HRESULT CSoapClient::VariantCopyToByRef(VARIANT *pvarDest, VARIANT *pvarSrc, LCID lcid)
//
// parameters:
//
// description:
// Converts variant type to its' BYREF type, clears the source
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CSoapClient::VariantCopyToByRef(VARIANT *pvarDest, VARIANT *pvarSrc, LCID lcid)
{
HRESULT hr = S_OK;
if ((pvarDest->vt & ~VT_BYREF) != pvarSrc->vt)
CHK(VariantChangeTypeEx(pvarSrc, pvarSrc, LCID_TOUSE, VARIANT_ALPHABOOL, pvarDest->vt & ~VT_BYREF));
ASSERT((pvarDest->vt & ~VT_BYREF) == pvarSrc->vt);
if ((pvarDest->vt & ~VT_BYREF) != pvarSrc->vt)
CHK(E_FAIL);
switch (pvarSrc->vt)
{
case VT_I1:
case VT_UI1:
// These have size of 1 byte
*(pvarDest->pbVal) = pvarSrc->bVal;
break;
case VT_BOOL:
case VT_I2:
case VT_UI2:
// These have size of 2 bytes
*(pvarDest->puiVal) = pvarSrc->uiVal;
break;
case VT_I4:
case VT_UI4:
case VT_R4:
case VT_ERROR:
// These have 4 byte size
*(pvarDest->pulVal) = pvarSrc->ulVal;
break;
case VT_I8:
case VT_UI8:
case VT_R8:
case VT_DATE:
// These have 8 byte size
*(pvarDest->pullVal) = pvarSrc->ullVal;
break;
case VT_DECIMAL:
// These have a 12 byte size
*(pvarDest->pdecVal) = pvarSrc->decVal;
break;
case VT_INT:
case VT_UINT:
case VT_PTR:
case VT_UNKNOWN:
case VT_DISPATCH:
// These have the size of an integer pointer
// (4 byte on 32 bit platform, 8 byte on 64bit platforms)
*(pvarDest->puintVal) = pvarSrc->uintVal;
break;
case VT_BSTR:
if (*(pvarDest->pbstrVal))
SysFreeString(*(pvarDest->pbstrVal));
*(pvarDest->pbstrVal) = pvarSrc->bstrVal;
pvarSrc->bstrVal = NULL;
break;
case VT_CY:
*(pvarDest->pcyVal) = pvarSrc->cyVal;
break;
default:
// arrays are 'or'-ed in, we can not recognize them that easy in the switch statement
if (V_ISARRAY(pvarSrc))
{
SAFEARRAY * psaSrc = V_ARRAY(pvarSrc);
SAFEARRAY * psaDest = *V_ARRAYREF(pvarDest);
// arrays with any of these bits set should not get touched by us
static const DWORD cNoTouchArray = (FADF_AUTO | FADF_STATIC | FADF_EMBEDDED | FADF_FIXEDSIZE | FADF_RESERVED);
if (psaDest)
{
if (psaDest->fFeatures & cNoTouchArray)
{
if (SUCCEEDED( SafeArrayCopyData(psaSrc, psaDest) ))
{
VariantClear(pvarSrc);
*V_ARRAYREF(pvarDest) = psaDest;
break;
}
}
else
{
CHK(SafeArrayDestroy(psaDest));
psaDest = NULL;
}
}
if (psaDest == NULL)
{
psaDest = psaSrc; // just take the existing one
*V_ARRAYREF(pvarDest) = psaDest;
V_ARRAY(pvarSrc) = NULL;
V_VT(pvarSrc) = VT_EMPTY;
break;
}
ERROR_ONHR0(E_INVALIDARG, CLIENT_IDS_ARRAYRESULTBYREF, SOAP_IDS_CLIENT);
}
ASSERT(FALSE);
CHK(E_INVALIDARG);
break;
}
pvarSrc->vt = VT_EMPTY;
Cleanup:
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: HRESULT CSoapClient::CheckForFault(ISoapReader *pISoapReader, BOOL *pbHasFault)
//
// parameters:
//
// description:
// Processes the SOAP FAULT response, sets up IErrorInfo and HRESULT from details, if there
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CSoapClient::CheckForFault(ISoapReader *pISoapReader, BOOL *pbHasFault)
{
HRESULT hr = S_OK;
HRESULT hresult = S_OK;
CAutoBSTR bstrfaultcode;
CAutoBSTR bstrfaultstring;
CAutoBSTR bstrfaultactor;
CAutoBSTR bstrdetail;
CAutoBSTR bstrTemp;
CAutoRefc<ICreateErrorInfo> pICrtErr;
CAutoRefc<IErrorInfo> pIErrInfo;
CAutoRefc<IXMLDOMDocument> pIXMLDOM;
CAutoRefc<IXMLDOMNode> pIXMLNodeFault;
CAutoRefc<IXMLDOMNode> pNodeTemp;
CAutoRefc<IXMLDOMNode> pNodeError;
CAutoRefc<IXMLDOMNode> pNodeHR;
CAutoRefc<IXMLDOMNode> pNodeServerErrorInfo;;
CClientFaultInfo *pFault;
CAutoFormat autoFormat;
WCHAR *achNameSpaces[] = { _T("s"), _T("e") };
WCHAR *achNameSpaceURIs[] = { (WCHAR *) g_pwstrEnvNS, (WCHAR *) g_pwstrMSErrorNS };
*pbHasFault = FALSE;
// Find out if there is a Fault envelope in the response message
CHK(pISoapReader->get_DOM(&pIXMLDOM));
hr = _XPATHUtilPrepareLanguage(pIXMLDOM, &(achNameSpaces[0]), &(achNameSpaceURIs[0]), 2);
if (FAILED(hr))
{
goto Cleanup;
}
hr = _XPATHUtilFindNodeFromRoot(pIXMLDOM, _T("//s:Envelope/s:Body/s:Fault"), &pIXMLNodeFault);
if (FAILED(hr))
{
// If there is no Fault element, return
_XPATHUtilResetLanguage(pIXMLDOM);
hr = S_OK;
goto Cleanup;
}
// if we have this, we have a fault, maybe an invalid, but it's a fault
*pbHasFault = true;
// get the faultcode element
CHK(autoFormat.sprintf(_T("%s"), g_pwstrFaultcode));
hr = pIXMLNodeFault->selectSingleNode(&autoFormat, &pNodeTemp);
if (hr != S_OK)
{
// check for incorrectly done namespace qualified errors
CHK(autoFormat.sprintf(_T("s:%s"), g_pwstrFaultcode));
hr = pIXMLNodeFault->selectSingleNode(&autoFormat, &pNodeTemp);
}
if (hr != S_OK)
{
hr = E_FAIL;
goto Cleanup;
}
// Create an error object here and fill in the parts
CHK(CreateErrorInfo(&pICrtErr));
CHK(pICrtErr->SetGUID(IID_ISOAPClient));
CHK(pNodeTemp->get_text(&bstrfaultcode));
pNodeTemp.Clear();
CHK(pICrtErr->SetSource(bstrfaultcode));
CHK(autoFormat.sprintf(_T("%s"), g_pwstrFaultstring));
hr = pIXMLNodeFault->selectSingleNode(&autoFormat, &pNodeTemp);
if (hr != S_OK)
{
CHK(autoFormat.sprintf(_T("s:%s"), g_pwstrFaultstring));
hr = pIXMLNodeFault->selectSingleNode(&autoFormat, &pNodeTemp);
}
if (hr != S_OK)
{
hr = E_FAIL;
goto Cleanup;
}
CHK(pNodeTemp->get_text(&bstrfaultstring));
pNodeTemp.Clear();
CHK(pICrtErr->SetDescription(bstrfaultstring));
CHK(autoFormat.sprintf(_T("%s"), g_pwstrFaultactor));
hr = pIXMLNodeFault->selectSingleNode(&autoFormat, &pNodeTemp);
if (hr != S_OK)
{
CHK(autoFormat.sprintf(_T("s:%s"), g_pwstrFaultactor));
hr = pIXMLNodeFault->selectSingleNode(&autoFormat, &pNodeTemp);
}
if (SUCCEEDED(hr) && pNodeTemp)
{
// actor is not a MUST
CHK(pNodeTemp->get_text(&bstrfaultactor));
}
pNodeTemp.Clear();
CHK(autoFormat.sprintf(_T("%s"), g_pwstrDetail));
hr = pIXMLNodeFault->selectSingleNode(&autoFormat, &pNodeTemp);
if (hr != S_OK)
{
CHK(autoFormat.sprintf(_T("s:%s"), g_pwstrDetail));
hr = pIXMLNodeFault->selectSingleNode(&autoFormat, &pNodeTemp);
}
if (SUCCEEDED(hr) && pNodeTemp)
{
// detail is not a MUST
// if we have a detail, we either find our subtree and get it out, OR
// we just take the string itself
CHK(autoFormat.sprintf(_T("e:%s"), g_pwstrErrorInfoElement));
hr = pNodeTemp->selectSingleNode(&autoFormat, &pNodeError);
if (SUCCEEDED(hr) && pNodeError)
{
// get the return HR OUT of the subtree
CHK(autoFormat.sprintf(_T(".//e:%s"), g_pwstrErrorReturnHR));
hr = pNodeError->selectSingleNode(&autoFormat, &pNodeHR);
if (SUCCEEDED(hr) && pNodeHR)
{
CHK(pNodeHR->get_text(&bstrTemp));
hresult = _wtoi(bstrTemp);
}
// check for special errorinfo information:
CHK(autoFormat.sprintf(_T(".//e:%s"), g_pwstrErrorServerElement));
hr = pNodeError->selectSingleNode(&autoFormat, &pNodeServerErrorInfo);
if (SUCCEEDED(hr) && pNodeServerErrorInfo)
{
pNodeHR.Clear();
bstrTemp.Clear();
CHK(autoFormat.sprintf(_T(".//e:%s"), g_pwstrErrorHelpFile));
hr = pNodeServerErrorInfo->selectSingleNode(&autoFormat, &pNodeHR);
if (SUCCEEDED(hr) && pNodeHR)
{
CHK(pNodeHR->get_text(&bstrTemp));
}
CHK(pICrtErr->SetHelpFile(bstrTemp));
pNodeHR.Clear();
bstrTemp.Clear();
CHK(autoFormat.sprintf(_T(".//e:%s"), g_pwstrErrorDescription));
hr = pNodeServerErrorInfo->selectSingleNode(&autoFormat, &pNodeHR);
if (SUCCEEDED(hr) && pNodeHR)
{
CHK(pNodeHR->get_text(&bstrTemp));
}
CHK(pICrtErr->SetDescription(bstrTemp));
pNodeHR.Clear();
bstrTemp.Clear();
CHK(autoFormat.sprintf(_T(".//e:%s"), g_pwstrErrorSource));
hr = pNodeServerErrorInfo->selectSingleNode(&autoFormat, &pNodeHR);
if (SUCCEEDED(hr) && pNodeHR)
{
CHK(pNodeHR->get_text(&bstrTemp));
}
CHK(pICrtErr->SetSource(bstrTemp));
pNodeHR.Clear();
bstrTemp.Clear();
CHK(autoFormat.sprintf(_T(".//e:%s"), g_pwstrErrorHelpContext));
hr = pNodeServerErrorInfo->selectSingleNode(&autoFormat, &pNodeHR);
if (SUCCEEDED(hr) && pNodeHR)
{
CHK(pNodeHR->get_text(&bstrTemp));
}
#ifndef UNDER_CE
CHK(pICrtErr->SetHelpContext(_wtoi(bstrTemp)));
#else
if(!bstrTemp){
CHK(pICrtErr->SetHelpContext(0));
}
else{
CHK(pICrtErr->SetHelpContext(_wtoi(bstrTemp)));
}
#endif
}
}
CHK(pNodeTemp->get_xml(&bstrdetail));
}
// We went through the whole fault message
CHK(pICrtErr->QueryInterface(IID_IErrorInfo, (void **)&pIErrInfo))
// Also set the m_SoapFaultInfo fields
hr = RetrieveFaultInfo(&pFault);
if (SUCCEEDED(hr))
{
pFault->SetErrorInfo(pIErrInfo);
pFault->SetFields(bstrfaultcode.PvReturn(),
bstrfaultstring.PvReturn(),
bstrfaultactor.PvReturn(),
bstrdetail.PvReturn());
}
else
{
CHK(SetErrorInfo(0L, pIErrInfo));
}
if (hresult != S_OK) // Return the hresult from the fault message
hr = hresult;
Cleanup:
return hr;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CSoapClient::InterfaceSupportsErrorInfo(REFIID riid)
//
// parameters:
//
// description:
//
// returns:
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CSoapClient::InterfaceSupportsErrorInfo(REFIID riid)
{
if (InlineIsEqualGUID(IID_ISOAPClient,riid))
return S_OK;
return S_FALSE;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: HRESULT CSoapClient::RetrieveThreadStore(CClientThreadStore **ppThreadStore, BOOL fCreateConnector)
//
// parameters:
//
// description:
//
// returns:
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CSoapClient::RetrieveThreadStore(CClientThreadStore **ppThreadStore, BOOL fCreateConnector)
{
HRESULT hr = S_OK;
CClientThreadStore * pStore;
CAutoRefc<ISoapConnector> pConnector;
CAutoRefc<ISoapSerializer> pSerializer;
pStore = m_threadInfo.Lookup(GetCurrentThreadId());
if (!pStore)
{
// first call on this thread, create one....
pStore = new CSoapObject<CClientThreadStore>(0);
if (!pStore)
{
hr = E_OUTOFMEMORY;
goto Cleanup;
}
// now create the objects we need to hold on to
// Instantiate a SoapSerializer object, initialize it
hr = CoCreateInstance(CLSID_SoapSerializer, NULL,
CLSCTX_INPROC_SERVER,
IID_ISoapSerializer,
(void**)&pSerializer);
if (FAILED(hr))
{
globalAddErro
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -