📄 server.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:
// server.cpp
//
// Contents:
//
// Implementation of CSoapServer
//
//-----------------------------------------------------------------------------
#ifdef UNDER_CE
#include "WinCEUtils.h"
#endif
#include "soaphdr.h"
#include "wsdloper.h"
TYPEINFOIDS(ISOAPServer, MSSOAPLib)
BEGIN_INTERFACE_MAP(CSoapServer)
ADD_IUNKNOWN(CSoapServer, ISOAPServer)
ADD_INTERFACE(CSoapServer, ISOAPServer)
ADD_INTERFACE(CSoapServer, ISupportErrorInfo)
ADD_INTERFACE(CSoapServer, IDispatch)
END_INTERFACE_MAP(CSoapServer)
// those little helpers are used to avoid the try_catch problems otherwise
CServerFaultInfo * createFaultInfo(void)
{
return(new CServerFaultInfo());
}
void deleteFaultInfo(CServerFaultInfo *p)
{
delete p;
}
/////////////////////////////////////////////////////////////////////////////
// CSoapServer
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CSoapServer::Init( BSTR bstrWSDLFile, BSTR bstrWSMLFileSpec)
//
// parameters:
//
// description:
//
// returns:
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CSoapServer::Init(
/* [in] */ BSTR bstrWSDLFile,
/* [in] */ BSTR bstrWSMLFileSpec)
{
HRESULT hr = S_OK;
#ifndef UNDER_CE
VARIANT varPropValue;
#endif
SET_TRACE_LEVEL(3);
__try
{
// WSDL file name is required
if (!bstrWSDLFile || !(*bstrWSDLFile))
return E_INVALIDARG;
// WSML file is ALSO required on the server
if (!bstrWSMLFileSpec || !(*bstrWSMLFileSpec))
return E_INVALIDARG;
release(&m_pIWSDLReader);
m_serializerState = enSerializerInit;
// Instantiate IWSDLReader object and get an interface ptr back.
CHK(CoCreateInstance(CLSID_WSDLReader, NULL, CLSCTX_INPROC_SERVER, IID_IWSDLReader, (void**)&m_pIWSDLReader));
#ifndef UNDER_CE
V_VT(&varPropValue) = VT_BOOL;
V_BOOL(&varPropValue) = VARIANT_TRUE;
CHK(m_pIWSDLReader->setProperty(_T("ServerHTTPRequest"), varPropValue));
#endif
CHK(m_pIWSDLReader->Load(bstrWSDLFile, bstrWSMLFileSpec));
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
TRACE(("SoapServer - Init(): Exception fired \n"));
}
Cleanup:
if (FAILED(hr))
{
CServerFaultInfo *pSoapFaultInfo=0;
pSoapFaultInfo = createFaultInfo();
if (pSoapFaultInfo)
{
// this will setup the errinfo
pSoapFaultInfo->FaultMsgFromResourceHr(SOAP_IDS_SERVER, 0, hr,
NULL, NULL);
}
delete pSoapFaultInfo;
globalResetErrors();
}
return hr;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CSoapServer::SoapInvoke (VARIANT varInput, IUnknown *pStreamOut, BSTR bstrSoapAction)
//
// parameters:
//
// description:
//
// returns:
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CSoapServer::SoapInvoke (/* [in] */ VARIANT varInput, // some interface implementing a stream or similiar
IUnknown *pStreamOut,
BSTR bstrSoapAction)
{
HRESULT hr = S_OK;
VARIANT_BOOL bSuccess;
CAutoRefc<IEnumSoapMappers> pIEnumSoapMaps;
CAutoRefc<IWSDLPort> pIWSDLPort;
CAutoRefc<IWSDLOperation> pIWSDLOp;
CAutoRefc<ISoapReader> pISoapReader;
CAutoRefc<ISoapSerializer> pISoapSerializer;
CAutoRefc<ISOAPError> pISoapError;
CAutoBSTR bstrEncoding;
CServerFaultInfo *pSoapFaultInfo = 0;
TCHAR *pchEncStyle;
#ifndef UNDER_CE
try
{
#endif
TRACE( ("%5d: Entering Server::SoapInvoke\n", GetCurrentThreadId()) );
SetErrorInfo(0L, NULL);
m_serializerState = enSerializerInit;
// before checking anything else, create the faultinfo and the serializer (if possible)
pSoapFaultInfo = createFaultInfo();
CHK_MEM(pSoapFaultInfo);
CHK_BOOL(pStreamOut, E_INVALIDARG);
CHK(CoCreateInstance(CLSID_SoapSerializer, NULL, CLSCTX_INPROC_SERVER, IID_ISoapSerializer, (void**)&pISoapSerializer));
VARIANT vStream;
VariantInit(&vStream);
vStream.vt = VT_UNKNOWN;
V_UNKNOWN(&vStream) = pStreamOut;
CHK(pISoapSerializer->Init(vStream));
if (!m_pIWSDLReader)
{
globalAddError(SOAP_IDS_SERVER_NOTINITIALIZED, SOAP_IDS_SERVER, hr);
hr = E_FAIL;
goto Cleanup;
}
// Instantiate SoapReader to read the input message
CHK(CoCreateInstance(CLSID_SoapReader, NULL,
CLSCTX_INPROC_SERVER,
IID_ISoapReader,
(void**)&pISoapReader));
// Pass the XMLDOMDocument into SoapReader.
hr = pISoapReader->load(varInput, bstrSoapAction, &bSuccess);
if (!bSuccess || FAILED(hr))
{ // Try to obtain info from the interface, if no SOAP
// interface, we will construct a generic one later.
if (hr==S_FALSE)
{
// change this to invalid arg
hr = E_INVALIDARG;
}
if (!FAILED(hr))
{
hr = CONN_E_BAD_REQUEST;
}
else
{
globalAddError(SOAP_IDS_SERVER_COULDNOTLOADREQUEST, SOAP_IDS_SERVER, hr);
}
goto Cleanup;
}
// Pass the SoapReader to WSDLReader.
CHK(m_pIWSDLReader->ParseRequest(pISoapReader, &pIWSDLPort, &pIWSDLOp));
pSoapFaultInfo->SetCurrentPort(pIWSDLPort);
CHK(pIWSDLOp->get_preferredEncoding(&bstrEncoding));
// get the EncodingStyle from the operation
pchEncStyle = ((CWSDLOperation*)(IWSDLOperation*)pIWSDLOp)->getEncoding(false);
// start the envelope, so that headers can be written
CHK(pISoapSerializer->startEnvelope((BSTR)g_pwstrEnvPrefix, (BSTR)pchEncStyle, bstrEncoding));
m_serializerState = enSerializerEnvelope;
hr = pIWSDLOp->ExecuteOperation(pISoapReader, pISoapSerializer);
if (FAILED(hr))
{
CAutoBSTR bstrAddress;
// set the actor correctly
if (SUCCEEDED(pIWSDLPort->get_address(&bstrAddress)))
{
globalSetActor(bstrAddress);
}
CHK(hr);
}
// Construct the response message stream
CHK(ConstructSoapResponse(pSoapFaultInfo, pISoapSerializer, pIWSDLOp, pStreamOut));
#ifndef UNDER_CE
}
catch(...)
{
hr = E_UNEXPECTED;
}
#endif
Cleanup:
if (FAILED(hr))
hr = ConstructGenericSoapErrorMessage(pSoapFaultInfo, pISoapSerializer, 0, 0, hr, NULL, NULL);
TRACE( ("%5d: Exiting Server::SoapInvoke\n\n", GetCurrentThreadId()) );
deleteFaultInfo(pSoapFaultInfo);
return hr;
}
static INVOKE_METHOD rgSoapServerMembers[] =
{
{ L"Init", DISPID_SOAPSERVER_INIT },
{ L"SoapInvoke", DISPID_SOAPSERVER_SOAPINVOKE },
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CSoapServer::GetIDsOfNames( REFIID riid, OLECHAR FAR* FAR* rgszNames, UINT cNames,
// LCID lcid, DISPID FAR* rgdispid )
//
// parameters:
//
// description:
//
// returns:
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CSoapServer::GetIDsOfNames( REFIID riid, OLECHAR FAR* FAR* rgszNames, UINT cNames, LCID lcid, DISPID FAR* rgdispid )
{
HRESULT hr = S_OK;
__try
{
// try quick lookup first
hr = FindIdsOfNames( rgszNames, cNames, rgSoapServerMembers, NUMELEM(rgSoapServerMembers), lcid, &rgdispid[0] );
// not found?
if( hr == DISP_E_UNKNOWNNAME )
{
// try expensive typelib lookup
hr = CDispatchImpl<ISOAPServer>::GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
TRACE(("SoapServer - GetIDsOfNames(): Exception fired \n"));
}
return hr;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CSoapServer::Invoke( DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags,
// DISPPARAMS FAR* pdispparams, VARIANT FAR* pvarResult, EXCEPINFO FAR* pexcepinfo,
// UINT FAR* puArgErr)
//
// parameters:
//
// description:
//
// returns:
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CSoapServer::Invoke
(
DISPID dispidMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS FAR* pdispparams,
VARIANT FAR* pvarResult,
EXCEPINFO FAR* pexcepinfo,
UINT FAR* puArgErr
)
{
INVOKE_ARG rgArgs[4];
UINT cArgs = 0;
DISPID dispid = -1;
HRESULT hrErr;
__try
{
//check if pdispparams is NULL.
//if NULL is passed for pdispparams...
#ifndef UNDER_CE
if (pdispparams == NULL)
JMP_ERR((hrErr=E_INVALIDARG),errExit);
//NOTE: Adding this check requires that a non-null be passed even in the case of DISPATCH_PROPERTYGET.
dispid = (pdispparams->cNamedArgs && !(wFlags & (DISPATCH_PROPERTYPUT)))
? -1 : dispidMember;
#else
if (pdispparams == NULL)
{
hrErr = E_INVALIDARG;
JMP_ERR(1,errExit);
}
else
{
//NOTE: Adding this check requires that a non-null be passed even in the case of DISPATCH_PROPERTYGET.
dispid = (pdispparams->cNamedArgs && !(wFlags & (DISPATCH_PROPERTYPUT)))
? -1 : dispidMember;
}
#endif
switch( dispid )
{
case DISPID_SOAPSERVER_INIT:
{
static const VARTYPE rgTypes[] = { VT_BSTR, VT_BSTR };
cArgs = NUMELEM(rgTypes);
JMP_FAIL(hrErr = FailedError(PrepareInvokeArgs( pdispparams, rgArgs, rgTypes, cArgs ),
pexcepinfo), errExit );
hrErr = FailedError(Init(VARMEMBER(&rgArgs[0].vArg, bstrVal),
VARMEMBER(&rgArgs[1].vArg, bstrVal)), pexcepinfo );
break;
}
case DISPID_SOAPSERVER_SOAPINVOKE:
{
static const VARTYPE rgTypes[] = {VT_VARIANT, VT_UNKNOWN, VT_BSTR|VT_OPTIONAL};
cArgs = NUMELEM(rgTypes);
JMP_FAIL(hrErr = FailedError(PrepareInvokeArgs( pdispparams, rgArgs, rgTypes, cArgs ),
pexcepinfo), errExit );
hrErr = FailedError(SoapInvoke(rgArgs[0].vArg, VARMEMBER(&rgArgs[1].vArg, punkVal), VARMEMBER(&rgArgs[2].vArg, bstrVal) ), pexcepinfo);
break;
}
default:
hrErr = CDispatchImpl<ISOAPServer>::Invoke(
dispidMember,
riid,
lcid,
wFlags,
pdispparams,
pvarResult,
pexcepinfo,
puArgErr
) ;
if( pexcepinfo && pexcepinfo->scode )
hrErr = FailedError( pexcepinfo->scode, pexcepinfo );
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
TRACE(("SoapServer - Invoke(): Exception fired \n"));
}
errExit:
if( cArgs )
ClearInvokeArgs( rgArgs, cArgs );
return hrErr;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CSoapServer::InterfaceSupportsErrorInfo(REFIID riid)
//
// parameters:
//
// description:
//
// returns:
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CSoapServer::InterfaceSupportsErrorInfo(REFIID riid)
{
if (InlineIsEqualGUID(IID_ISOAPServer,riid))
return S_OK;
return S_FALSE;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CSoapServer::ConstructSoapResponse (CServerFaultInfo *pSoapFaultInfo, ISoapSerializer *pISoapSerializer,
// IWSDLOperation *pIWSDLOperation, IUnknown *pStreamOut)
//
// parameters:
//
// description:
//
// returns:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -