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

📄 server.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// 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 + -