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

📄 srmpfwd.cxx

📁 Windows CE 6.0 Server 源码
💻 CXX
📖 第 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.
//
/*++


Module Name:

    SrmpFwd.cxx

Abstract:

    Forwards an SRMP data packet without modifying contents.
 
--*/


#include <windows.h>
#include <wininet.h>
#include <mq.h>

#include "sc.hxx"
#include "scsrmp.hxx"
#include "scsman.hxx"
#include "scpacket.hxx"
#include "SrmpAccept.hxx"
#include "scdefs.hxx"
#include "srmpparse.hxx"
#include "fntoken.h"
#include "scutil.hxx"
#include "scqueue.hxx"
#include "SrmpFwd.hxx"

BOOL CSrmpFwd::SetState(SRMP_TOKEN tok) {
	SRMP_STATE curState = GetState();
	SRMP_STATE newState = SRMP_ST_UNKNOWN;

	// we only care about a very small subset, no namespace checking needed if it made it this far.
	if (curState == SRMP_ST_UNINITIALIZED && tok == SRMP_TOK_ENVELOPE)
		newState = SRMP_ST_ENVELOPE;
	else if (curState == SRMP_ST_ENVELOPE && tok == SRMP_TOK_HEADER)
		newState = SRMP_ST_HEADER;
	else if (curState == SRMP_ST_HEADER && tok == SRMP_TOK_PATH)
		newState = SRMP_ST_PATH;
	else if (curState == SRMP_ST_PATH && tok == SRMP_TOK_FWD)
		newState = SRMP_ST_PATH_FWD;
	else if (curState == SRMP_ST_PATH_FWD && tok == SRMP_TOK_VIA)
		newState = SRMP_ST_PATH_FWD_VIA;
	else if (curState == SRMP_ST_PATH && tok == SRMP_TOK_REV)
		newState = SRMP_ST_PATH_REV;
	else if (curState == SRMP_ST_PATH_REV && tok == SRMP_TOK_VIA)
		newState = SRMP_ST_PATH_REV_VIA;

	if (! m_State.Push((void*)newState))
		return FALSE;

	return TRUE;
}


HRESULT STDMETHODCALLTYPE CSrmpFwd::endElement( 
    /* [in] */ const wchar_t __RPC_FAR *pwchNamespaceUri,
    /* [in] */ int cchNamespaceUri,
    /* [in] */ const wchar_t __RPC_FAR *pwchLocalName,
    /* [in] */ int cchLocalName,
    /* [in] */ const wchar_t __RPC_FAR *pwchQName,
    /* [in] */ int cchQName)
{
	SRMP_STATE oldState = GetState();
	HRESULT hr = E_FAIL;

	m_State.Pop();
	if (fSkipOutput) {
		fSkipOutput = FALSE;
		return S_OK;
	}

	// <rev> is present but is empty (i.e. <rev/>), then add <via>
	if (oldState == SRMP_ST_PATH_REV && !fFoundRevVia) {
		fFoundRevVia = TRUE;
		if (S_OK != characters(0,0) ||
		    FAILED(hr = WriteRevEntry(TRUE)))
			return hr;
	}

	/* If we ever break this code into public or have some other mechanism of injecting
	// extra XML tags into a forwarded envelope, now would be the time to do it.
	if (oldState == SRMP_ST_ENVELOPE) {
		// We're about to close </envelope>.  User may append whatever extra XML tags
		// they desire now.
	}
	*/
	return writeBuffer.endElement(pwchNamespaceUri,cchNamespaceUri,pwchLocalName,cchLocalName,pwchQName,cchQName);
}

void GetHttpPrefix(BOOL fSecure, WCHAR **ppszPrefix, DWORD *pccPrefix) {
	if (fSecure) {
		*ppszPrefix = (WCHAR*) cszHttpsPrefix;
		*pccPrefix  = ccHttpsPrefix;
	}
	else {
		*ppszPrefix = (WCHAR*) cszHttpPrefix;
		*pccPrefix  = ccHttpPrefix;
	}
}

HRESULT STDMETHODCALLTYPE CSrmpFwd::characters( 
    /* [in] */ const wchar_t __RPC_FAR *pwchChars,
    /* [in] */ int cchChars)
{
	if (! fSkipOutput)
		return writeBuffer.characters(pwchChars,cchChars);

	return S_OK;
}

HRESULT STDMETHODCALLTYPE CSrmpFwd::startElement( 
    /* [in] */ const wchar_t __RPC_FAR *pwchNamespaceUri,
    /* [in] */ int cchNamespaceUri,
    /* [in] */ const wchar_t __RPC_FAR *pwchLocalName,
    /* [in] */ int cchLocalName,
    /* [in] */ const wchar_t __RPC_FAR *pwchQName,
    /* [in] */ int cchQName,
    /* [in] */ ISAXAttributes __RPC_FAR *pAttributes)
{
	SVSUTIL_ASSERT(!fSkipOutput);

	SRMP_TOKEN token = GetToken(pwchLocalName,cchLocalName);
	HRESULT    hr;

	if (! SetState(token))
		return E_OUTOFMEMORY;

	SRMP_STATE curState = GetState();

	switch (curState) {
		case SRMP_ST_PATH_FWD_VIA:
			if (fwdViaState == SRMP_FWD_ONFIRST) {
				// swallow first <fwd><via> element (points to this CE server), allow all others to pass through.
				fwdViaState = SRMP_FWD_ONSECOND;
				fSkipOutput = TRUE;
				return S_OK;
			}
			else if (fwdViaState == SRMP_FWD_ONSECOND) {
				fwdViaState = SRMP_FWD_PASTSECOND;
				// the second <fwd><via> entry was used to setup the queue that we're sending to currently (will be first in this forwarded packet).
				// Use szQueueName rather than the original entry in case the original entry has been routed to a new destination.

				gMem->Lock();

				WCHAR *szHttpPref;
				DWORD ccHttpPref;
				GetHttpPrefix(pSession->IsSecure(),&szHttpPref,&ccHttpPref);

				// 1st call is to characters() due to way MXXMLWriter works; needs to possibly fixup element immediatly preceeding this one in buffer.
				if (S_OK != characters(0,0) ||
				    ! writeBuffer.StartTag(cszVia) ||
				    ! writeBuffer.AppendWSTR(szHttpPref,ccHttpPref) || 
				    ! writeBuffer.AppendWSTR(pSession->lpszHostName,wcslen(pSession->lpszHostName)) ||
				    ! writeBuffer.AppendWSTR(L"/",1) ||
				    ! writeBuffer.AppendWSTR(szQueueName,wcslen(szQueueName)) ||
				    ! writeBuffer.EndTag(cszVia)) {
				    gMem->Unlock();
				    return E_OUTOFMEMORY;
				}

				fSkipOutput = TRUE;
				gMem->Unlock();
				return S_OK;
			}
		break;

		case SRMP_ST_PATH_REV_VIA:
			// put name of CE box as 1st via entry
			if (!fFoundRevVia) {
				fFoundRevVia = TRUE;

				if ((FAILED(hr = writeBuffer.startElement(pwchNamespaceUri,cchNamespaceUri,pwchLocalName,cchLocalName,pwchQName,cchQName,pAttributes))))
					return hr;

				if (S_OK != characters(0,0))
					return E_OUTOFMEMORY;

				if (FAILED(hr = WriteRevEntry(FALSE)))
					return hr;

				if (FAILED(hr = writeBuffer.endElement(pwchNamespaceUri,cchNamespaceUri,pwchLocalName,cchLocalName,pwchQName,cchQName)))
					return hr;
				// "fall through" - add <rev><via> entry SAX has come across just like normal.
			}

		// fall through
		default:
			fSkipOutput = FALSE;
	}

	return writeBuffer.startElement(pwchNamespaceUri,cchNamespaceUri,pwchLocalName,cchLocalName,pwchQName,cchQName,pAttributes);
}

HRESULT CSrmpFwd::WriteRevEntry(BOOL fWriteRevTag) {
	if (fWriteRevTag) {
		if (! writeBuffer.StartTag(cszVia))
			return E_OUTOFMEMORY;
	}

	if (! writeBuffer.Encode(szRevEntry))
		return E_OUTOFMEMORY;

	if (fWriteRevTag) {
		if ( ! writeBuffer.EndTag(cszVia))
			return E_OUTOFMEMORY;
	}
	return S_OK;
}

const char cszHostHttpHeader[] = "Host:";
const char cszTextXML[]        = "text/xml";

BOOL SkipHeader(PSTR szHeader) {
	if (0 == _strnicmp(szHeader,cszHostHttpHeader,SVSUTIL_CONSTSTRLEN(cszHostHttpHeader)) ||
	    0 == _strnicmp(szHeader,cszContentLength, ccContentLength))
		return TRUE;
	return FALSE;
}

int ScSession::ForwardSrmpMessage(CSrmpFwd *pSrmpFwd, ScPacketImage *pPacketImage, WCHAR *wszURL) {
	CUserHeader            *pUserHeader             = pPacketImage->sect.pUserHeader;
	CCompoundMessageHeader *pCompoundMessageHeader  = pPacketImage->sect.pCompoundMessageHeader;
	CPropertyHeader        *pPropHeader             = pPacketImage->sect.pPropHeader;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -