📄 client.cpp
字号:
//
// 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.
//
//+---------------------------------------------------------------------------------
//
//
// File:
// client.cpp
//
// Contents:
//
// CSoapClient class implementation
//
//----------------------------------------------------------------------------------
#ifdef UNDER_CE
#include "WinCEUtils.h"
#include "auto_xxx.hxx"
#endif
#include "soaphdr.h"
#include "wsdlutil.h"
#include "ensoapmp.h"
#include "soapmapr.h"
#include "wsdloper.h"
#pragma warning (disable : 4509)
TYPEINFOIDS(ISOAPClient, MSSOAPLib)
////////////////////////////////////////////////////////////////////////////////////////////////////
// Interface maps
////////////////////////////////////////////////////////////////////////////////////////////////////
BEGIN_INTERFACE_MAP(CSoapClient)
ADD_IUNKNOWN(CSoapClient, ISOAPClient)
ADD_INTERFACE(CSoapClient, ISOAPClient)
ADD_INTERFACE(CSoapClient, IDispatch)
ADD_INTERFACE(CSoapClient, ISupportErrorInfo)
END_INTERFACE_MAP(CSoapClient)
BEGIN_INTERFACE_MAP(CClientThreadStore)
ADD_IUNKNOWN(CClientThreadStore, IUnknown)
END_INTERFACE_MAP(CClientThreadStore)
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: void CClientFaultInfo::SetFields(BSTR bstrfaultcode, BSTR bstrfaultstring, BSTR bstrfaultactor, BSTR bstrdetail)
//
// parameters:
//
// description:
// Stores the BSTRs into the given fields
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
void CClientFaultInfo::SetFields(BSTR bstrfaultcode, BSTR bstrfaultstring, BSTR bstrfaultactor, BSTR bstrdetail)
{
ASSERT(!HasFaultInfo());
m_bstrfaultcode.Assign(bstrfaultcode, FALSE);
m_bstrfaultstring.Assign(bstrfaultstring, FALSE);
m_bstrfaultactor.Assign(bstrfaultactor, FALSE);
m_bstrdetail.Assign(bstrdetail, FALSE);
m_dwFaultCodeId = 0;
m_bhasFault = TRUE;;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: void CClientFaultInfo::PublishErrorInfo(void)
//
// parameters:
//
// description:
// Publishes COM error object
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
void CClientFaultInfo::PublishErrorInfo(void)
{
::SetErrorInfo(0, m_pErrorInfo);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: HRESULT CClientThreadStore::RetrieveConnector(ISoapConnector **pConnector)
//
// parameters:
//
// description:
// Retrieves connector from the client's store
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CClientThreadStore::RetrieveConnector(ISoapConnector **pConnector)
{
CHK_ARG(pConnector && ! *pConnector);
HRESULT hr = S_OK;
CComPointer<ISoapConnector> pConn;
CHK(m_ConnectorSet.RemoveHead(pConn));
pConn.AddRef();
*pConnector = pConn;
pConn = 0;
hr = S_OK;
Cleanup:
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: HRESULT CClientThreadStore::ReturnConnector(ISoapConnector *pConnector)
//
// parameters:
//
// description:
// Returns connector back to the client's store
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CClientThreadStore::ReturnConnector(ISoapConnector *pConnector)
{
CHK_ARG(pConnector);
HRESULT hr = S_OK;
CComPointer<ISoapConnector> pConn(pConnector);
CHK(m_ConnectorSet.InsertTail(pConn));
hr = S_OK;
Cleanup:
return hr;
}
/////////////////////////////////////////////////////////////////////////////
// CSoapClient
/////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: STDMETHODIMP CSoapClient::mssoapinit(BSTR bstrWSDLFile, BSTR bstrServiceName, BSTR bstrPort,
// BSTR bstrWSMLFile)
//
// parameters:
//
// description:
// Initializes soap client
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CSoapClient::mssoapinit(
/* [in] */ BSTR bstrWSDLFile,
/* [in, defaultvalue("")] */ BSTR bstrServiceName,
/* [in, defaultvalue("")] */ BSTR bstrPort,
/* [in, defaultvalue("")] */ BSTR bstrWSMLFile)
{
HRESULT hr = S_OK;
CAutoRefc<IEnumWSDLService> pIEnumWSDLServices;
CAutoRefc<IEnumWSDLPorts> pIEnumWSDLPorts;
CAutoRefc<IWSDLOperation> pIOperation;
long cFetched;
long lIndex;
CClientFaultInfo *pFaultInfo;
CCritSect critSect;
CCritSectWrapper csw;
#ifdef UNDER_CE
ce::auto_bstr bstr = NULL;
#endif
#ifndef CE_NO_EXCEPTIONS
try
#else
__try
#endif
{
critSect.Initialize();
CHK (csw.init(&critSect, TRUE));
CHK (csw.Enter());
globalResetErrors();
if (m_bflInitSuccess)
CHK (HRESULT_FROM_WIN32(ERROR_ALREADY_ASSIGNED));
// WSDL file name is required
if (!bstrWSDLFile)
CHK (E_INVALIDARG);
// Instantiate IWSDLReader object and get an interface ptr back.
CHK ( CoCreateInstance(CLSID_WSDLReader, NULL,
CLSCTX_INPROC_SERVER,
IID_IWSDLReader,
(void**)&m_pIWSDLReader) );
// set property if exist
#ifndef UNDER_CE
if (m_bUseServerHTTPRequest)
{
VARIANT varPropValue;
V_VT(&varPropValue) = VT_BOOL;
V_BOOL(&varPropValue) = VARIANT_TRUE;
CHK (m_pIWSDLReader->setProperty(_T("ServerHTTPRequest"), varPropValue));
}
#endif
// tell the reader that we are loading client side information
VARIANT varPropValue;
V_VT(&varPropValue) = VT_BOOL;
V_BOOL(&varPropValue) = VARIANT_FALSE;
#ifdef UNDER_CE
bstr = SysAllocString(_T("LoadOnServer"));
CHK_BOOL(bstr.valid(), E_OUTOFMEMORY);
CHK(m_pIWSDLReader->setProperty(bstr, varPropValue));
#else
CHK(m_pIWSDLReader->setProperty(_T("LoadOnServer"), varPropValue));
#endif
CHK(m_pIWSDLReader->Load(bstrWSDLFile, bstrWSMLFile));
CHK(m_pIWSDLReader->GetSoapServices(&pIEnumWSDLServices));
// If no servicename provided, use the first one
if (bstrServiceName && *bstrServiceName)
{
hr = pIEnumWSDLServices->Find(bstrServiceName, &m_pIWSDLService);
if (FAILED(hr))
{
globalAddError(SOAP_IDS_COULDNOTFINDSERVICE, SOAP_IDS_CLIENT, hr, bstrServiceName);
goto Cleanup;
}
}
else
{
// If no servicename provided, use the first one
hr = pIEnumWSDLServices->Next(1, &m_pIWSDLService, &cFetched);
if (FAILED(hr) || cFetched != 1) // Could not find it?
{
globalAddError(SOAP_IDS_NODEFAULTSERVICE, SOAP_IDS_CLIENT, hr);
hr = E_INVALIDARG;
goto Cleanup;
}
}
CHK(m_pIWSDLService->GetSoapPorts(&pIEnumWSDLPorts));
// Find the requested port
if (bstrPort && *bstrPort)
{
hr = pIEnumWSDLPorts->Find(bstrPort, &m_pIWSDLPort);
if (FAILED(hr))
{
globalAddError(SOAP_IDS_COULDNOTFINDPORT, SOAP_IDS_CLIENT, hr, bstrPort);
goto Cleanup;
}
}
else
{
// If no port provided, use the first one
hr = pIEnumWSDLPorts->Next(1, &m_pIWSDLPort, &cFetched);
if (FAILED(hr) || cFetched != 1) // Could not find it?
{
globalAddError(SOAP_IDS_NODEFAULTPORT, SOAP_IDS_CLIENT, hr);
hr = E_INVALIDARG;
goto Cleanup;
}
}
// Find the operations
CHK(m_pIWSDLPort->GetSoapOperations(&m_pIEnumWSDLOps));
// All is fine if we make it here.
CHK(m_pIEnumWSDLOps->Reset() );
CHK(m_pIEnumWSDLOps->Size(&lIndex));
CHK(m_abstrNames.SetSize(lIndex));
lIndex = 0;
while (((m_pIEnumWSDLOps->Next(1, &pIOperation, &cFetched)==S_OK) && pIOperation != 0))
{
WCHAR * name = NULL;
// let's prefill the encoding here as well
if (lIndex == 0)
{
m_bstrpreferredEncoding.Clear();
hr = pIOperation->get_preferredEncoding(&m_bstrpreferredEncoding);
if (FAILED(hr))
{
goto Cleanup;
}
}
CHK (allocateAndCopy (&name, pIOperation->getNameRef() ) );
pIOperation.Clear();
if (name)
{
//add name to the list of names, ownership is transfered
m_abstrNames.AddName(name);
}
lIndex++;
}
// we added all names at this point, now we can go ahead and sort them
m_abstrNames.Sort();
// Instantiate a SoapConnector object, initialize it
CHK(CoCreateInstance(CLSID_SoapConnectorFactory, NULL,
CLSCTX_INPROC_SERVER,
IID_ISoapConnectorFactory,
(void**)&m_pISoapConnFact));
m_bflInitSuccess = TRUE;
Cleanup:
ASSERT (hr == S_OK);
if (FAILED(hr))
{
// Do Reset first so it won't clear the error information
Reset();
if (SUCCEEDED(RetrieveFaultInfo(&pFaultInfo)))
{
pFaultInfo->FaultMsgFromResourceHr(SOAP_IDS_CLIENT, 0, hr, NULL, NULL);
}
}
return hr;
}
#ifndef CE_NO_EXCEPTIONS
catch (...)
#else
__except(1)
#endif
{
ASSERTTEXT (FALSE, "CSoapClient::mssoapinit - Unhandled Exception");
return E_FAIL;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: HRESULT CSoapClient::get_faultcode(BSTR * pbstrFaultcode)
//
// parameters:
//
// description:
// Returns the faultcode value from SOAP fault message
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CSoapClient::get_faultcode(BSTR * pbstrFaultcode)
{
HRESULT hr = S_OK;
CClientFaultInfo *pFaultInfo;
#ifndef CE_NO_EXCEPTIONS
try
#else
__try
#endif
{
if (!pbstrFaultcode)
return E_INVALIDARG;
*pbstrFaultcode = NULL;
hr = RetrieveFaultInfo(&pFaultInfo);
if (SUCCEEDED(hr))
{
if (pFaultInfo->HasFaultInfo())
{
*pbstrFaultcode = SysAllocString(pFaultInfo->getfaultcode());
if (!(*pbstrFaultcode))
hr = E_OUTOFMEMORY;
}
}
return hr;
}
#ifndef CE_NO_EXCEPTIONS
catch (...)
#else
__except(1)
#endif
{
ASSERTTEXT (FALSE, "CSoapClient::get_faultcode - Unhandled Exception");
return E_FAIL;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: HRESULT CSoapClient::get_faultstring(BSTR * pbstrFaultstring)
//
// parameters:
//
// description:
// Returns the faultstring value from SOAP fault message
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CSoapClient::get_faultstring(
/* [out, retval] */ BSTR * pbstrFaultstring)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -