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

📄 srmpmsg.cxx

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

    SrmpMsg.cxx

Abstract:

	After SAX interpretter is through with an item, calls into
	this function to process it.
     
--*/


#include <msxml2.h>
#include <winsock.h>

#include "SrmpAccept.hxx"
#include "SrmpParse.hxx"
#include "sc.hxx"
#include "MqProps.h"
#include "ph.h"
#include "scqman.hxx"
#include "scqueue.hxx"
#include "fntoken.h"
#include <service.h>


//
//  Interface functions.
//
BOOL BreakMsmqStreamId(const WCHAR *szBuffer, LONGLONG *pSeqId);


// Make sure an end node is visited one and only one time, mark it off as visited.
#define PathCheckAndSet(state)            CheckAndSet(cMsgProps.dwPathSet,   (state))
#define ServiceCheckAndSet(state)         CheckAndSet(cMsgProps.dwServiceSet,(state))
#define PropsCheckAndSet(state)           CheckAndSet(cMsgProps.dwPropertiesSet,(state))
#define StreamCheckAndSet(state)          CheckAndSet(cMsgProps.dwStreamSet,(state))
#define StreamRcptCheckAndSet(state)      CheckAndSet(cMsgProps.dwStreamRcptSet,(state))
#define DeliveryRcptCheckAndSet(state)    CheckAndSet(cMsgProps.dwDeliveryRcptSet,(state))
#define CommitRcptCheckAndSet(state)      CheckAndSet(cMsgProps.dwCommitRcptSet,(state))
#define MsmqRcptCheckAndSet(state)        CheckAndSet(cMsgProps.dwMsmqSet,(state))

CSrmpMessageProperties::CSrmpMessageProperties(PSrmpIOCTLPacket pIOCTL) {
	pHttpParams = pIOCTL;
	SVSUTIL_ASSERT(pHttpParams->contentType == CONTENT_TYPE_XML || pHttpParams->contentType == CONTENT_TYPE_MIME);

	absoluteTimeToLive   = INFINITE;
	absoluteTimeToQueue  = INFINITE;
	priority             = DEFAULT_M_PRIORITY;
	acknowledgeType      = DEFAULT_M_ACKNOWLEDGE;
	EodSeqId             = i64NoneMSMQSeqId;

	szAdminQueue = szResponseQueue = szDestQueue = szOrderQueue = szStreamIdBuf = szTitle = NULL;
	bstrEnvelope = NULL;

	fTrace = fLast = fFirst = auditing = delivery = 0;
	sentTime = 0;

	classValue = 0;
	bodyType = applicationTag = 0;
	pCorrelationID = 0;

	EodStreamId = 0;
	EodPrevSeqNo = EodSeqNo = 0;

	EodAckStreamId = 0;
	EodAckSeqId    = EodAckSeqNo = 0;

	szFrom = szRelatesTo  = 0;
	ccRelatesTo = ccFrom  = 0;

	// Keep track of what vars have been set already during SAX processing.
	dwHeaderSet = dwPathSet = dwServiceSet = dwPropertiesSet = dwStreamSet = dwStreamRcptSet =
	dwDeliveryRcptSet =  dwCommitRcptSet = dwMsmqSet = 0;

	memset(&messageId,0,sizeof(messageId));
	memset(&connectorType,0,sizeof(connectorType));
	memset(&connectorId,0,sizeof(connectorId));
	memset(&SourceQmGuid,0,sizeof(SourceQmGuid));
	memset(&destQueue,0,sizeof(destQueue));
	memset(&adminQueue,0,sizeof(adminQueue));
	memset(&responseQueue,0,sizeof(responseQueue));
}

CSrmpMessageProperties::~CSrmpMessageProperties() {
	if (szTitle)
		g_funcFree(szTitle, g_pvFreeData);

	if (szStreamIdBuf)
		g_funcFree(szStreamIdBuf,g_pvFreeData);

	if (szOrderQueue)
		g_funcFree(szOrderQueue,g_pvFreeData);

//	if (EodStreamId)  Do not free!  Points into szStreamIdBuf!
//		g_funcFree(EodStreamId,g_pvFreeData);

	if (pCorrelationID)
		g_funcFree(pCorrelationID,g_pvFreeData);

	if (EodAckStreamId)
		g_funcFree(EodAckStreamId,g_pvFreeData);

	if (szRelatesTo)
		g_funcFree(szRelatesTo,g_pvFreeData);

	if (szFrom)
		g_funcFree(szFrom,g_pvFreeData);

	if (bstrEnvelope)
		SysFreeString(bstrEnvelope);

	if (szDestQueue)
		g_funcFree(szDestQueue,g_pvFreeData);

	if (szResponseQueue)
		g_funcFree(szResponseQueue,g_pvFreeData);

	if (szAdminQueue)
		g_funcFree(szAdminQueue,g_pvFreeData);

	//if (szProviderName)
	//	g_funcFree(szProviderName,g_pvFreeData);
}


//
//  <path>
// 
HRESULT CSrmpToMsmq::HandlePath(void) {
	if (IsHeaderSet(SRMP_ST_PATH))
		return E_FAIL;
	SetHeader(SRMP_ST_PATH);

	if (! IsSetSrmp(cMsgProps.dwPathSet,SRMP_ST_PATH_ID) ||
	    ! IsSetSrmp(cMsgProps.dwPathSet,SRMP_ST_PATH_ACTION)) {
		return E_FAIL;
	}

	// if <to> isn't set, spec says 'ultimate destination is indicated by the last "via" in the "fwd" element'
	if (! IsSetSrmp(cMsgProps.dwPathSet,SRMP_ST_PATH_TO)) {
		if (! cMsgProps.fwdViaBuf.pBuffer)
			return E_FAIL;

		WCHAR *szStart = (WCHAR*) cMsgProps.fwdViaBuf.pBuffer;
		int   ccChars  = cMsgProps.fwdViaBuf.uiNextIn / sizeof(WCHAR);
		WCHAR *pszTrav = szStart;
		WCHAR *pszLastVisited;

		while (pszTrav - szStart <= ccChars) {
			pszLastVisited = pszTrav;
			pszTrav += wcslen(pszTrav)+1;
		}
		SVSUTIL_ASSERT(pszTrav-1-szStart == ccChars);

		if (! UriToQueueFormat(pszLastVisited,pszLastVisited-pszTrav-1,&cMsgProps.destQueue,&cMsgProps.szDestQueue))
			return E_FAIL;
		SetSrmp(cMsgProps.dwPathSet,SRMP_ST_PATH_TO);
	}
	
	return S_OK;
}

// Converts <path><id>uuid:XXXXX</id></path>
HRESULT CSrmpToMsmq::HandlePathId(void) {
	PathCheckAndSet(SRMP_ST_PATH_ID);
	WCHAR *szBuf = GetBuffer();

	if (IsEmpty())
		return E_FAIL;

	DWORD nscan;
	int n = swscanf(szBuf,UUIDREFERENCE_PREFIX L"%d" UUIDREFERENCE_SEPERATOR L"%n",
	                &cMsgProps.messageId.Uniquifier,&nscan);

	if (n == 1) {
		if (! StringToGuid(szBuf + nscan,&cMsgProps.messageId.Lineage))
			return E_FAIL;
		return S_OK;
	}

	const GUID  xNonMSMQMessageIdGuid  = {0x75d1aae4,0x8e23,0x400a,0x8c,0x33,0x99,0x64,0x8e,0x35,0xe7,0xb9};
	const ULONG xNonMSMQMessageIdIndex = 1;

	cMsgProps.messageId.Uniquifier = xNonMSMQMessageIdIndex;
	cMsgProps.messageId.Lineage    = xNonMSMQMessageIdGuid;
	return S_OK;
}

HRESULT CSrmpToMsmq::HandlePathTo(void) {
	PathCheckAndSet(SRMP_ST_PATH_TO);
	if (IsEmpty())
		return E_FAIL;

	return UriToQueueFormat(GetBuffer(),GetNumChars(),&cMsgProps.destQueue,&cMsgProps.szDestQueue) ? S_OK : E_FAIL;
}

HRESULT CSrmpToMsmq::HandlePathRev(void) {
	PathCheckAndSet(SRMP_ST_PATH_REV);
	return S_OK;
}

const WCHAR szEmpty[] = L"";

HRESULT CSrmpToMsmq::HandlePathRevVia(void) {
	// It is acceptable to have multiple VIA entries
	SetSrmp(cMsgProps.dwPathSet,SRMP_ST_PATH_REV_VIA);
	const WCHAR *szVia = GetBuffer();
	DWORD ccVia        = GetNumChars();

	// 1st element in <rev><via> list has special meaning in desktop MSMQ, preserve this while at same time store in revViaBuf.
	if (! IsEmpty() && (NULL == cMsgProps.revViaBuf.pBuffer)) {
		if (!UriToQueueFormat(GetBuffer(),GetNumChars(),&cMsgProps.responseQueue,&cMsgProps.szResponseQueue))
			return E_FAIL;
	}

	// +1 makes sure \0 is included.
	return cMsgProps.revViaBuf.AppendWSTR(szVia,ccVia+1) ? S_OK : E_FAIL;
}

HRESULT CSrmpToMsmq::HandlePathFrom(void) {
	PathCheckAndSet(SRMP_ST_PATH_FROM);
	if (IsEmpty())
		return E_FAIL;

	if (NULL == (cMsgProps.szFrom = AllocCharData()))
		return E_FAIL;

	cMsgProps.ccFrom = GetNumChars() + 1;
	return S_OK;
}

HRESULT CSrmpToMsmq::HandlePathAction(void) {
	PathCheckAndSet(SRMP_ST_PATH_ACTION);
	// Like XP: We require action to begin with "MSMQ:", if it doesn't we 
	// won't save it but we won't halt parsing, either.
	if (GetNumChars() <= ccMSMQPrefix)
		return S_OK;

	if (wcsncmp(GetBuffer(),cszMSMQPrefix,ccMSMQPrefix) != 0)
		return S_OK;

	if (NULL == (cMsgProps.szTitle = AllocCharData(ccMSMQPrefix)))
		return E_FAIL;

	return S_OK;
}

HRESULT CSrmpToMsmq::HandlePathRelatesTo(void) {
	PathCheckAndSet(SRMP_ST_PATH_RELATESTO);
	if (IsEmpty())
		return E_FAIL;

	if (NULL == (cMsgProps.szRelatesTo = AllocCharData()))
		return E_FAIL;

	cMsgProps.ccRelatesTo = GetNumChars() + 1;
	return S_OK;
}

HRESULT CSrmpToMsmq::HandlePathFixed(void) {
	PathCheckAndSet(SRMP_ST_PATH_FIXED);
	return S_OK;
}

HRESULT CSrmpToMsmq::HandlePathFwd(void) {
	PathCheckAndSet(SRMP_ST_PATH_FWD);
	return S_OK;
}

// need to have a URL and a FORMAT version of this...
//int IsURLLocalMachine(const WCHAR *szURL, BOOL fGeneratedLocally) {
//	if (0 == wcsicmp(gMachine->lpszHostName,szURL))
//		return TRUE;
//
//	if (fGeneratedLocally && (0==wcsicmp(gMachine->lpszHostName,L"localhost")))
//		return TRUE;
//
//	return FALSE;
//}

HRESULT CSrmpToMsmq::HandlePathFwdVia(void) {
	// It is acceptable to have multiple VIA entries
//	BOOL  fFirst       = ! (IsSetSrmp(cMsgProps.dwPathSet,SRMP_ST_PATH_FWD_VIA));
	const WCHAR *szVia = GetBuffer();
	DWORD ccVia        = GetNumChars();

	SetSrmp(cMsgProps.dwPathSet,SRMP_ST_PATH_FWD_VIA);
/*	if (fFirst) {
		// check that 1st element is local device or is empty.
//		if (!IsEmpty() && !IsURLLocalMachine(szVia))
//			return E_FAIL;

		// first <via> element is discarded, return immediatly.
		return S_OK;
	}
*/

	// +1 to make sure NULL is included.
	return cMsgProps.fwdViaBuf.AppendWSTR(szVia,ccVia+1) ? S_OK : E_FAIL;
}

HRESULT CSrmpToMsmq::HandlePathFault(void) {
	PathCheckAndSet(SRMP_ST_PATH_FAULT);
	return S_OK;
}

//
// <services>
// 
HRESULT CSrmpToMsmq::HandleServices(void) {
	if (IsHeaderSet(SRMP_ST_SERVICES))
		return E_FAIL;
	SetHeader(SRMP_ST_SERVICES);

	return S_OK;
}

HRESULT CSrmpToMsmq::HandleServicesDurable(void) {
	ServiceCheckAndSet(SRMP_ST_SERVICES_DURABLE);
	cMsgProps.delivery = MQMSG_DELIVERY_RECOVERABLE;
	return S_OK;
}

HRESULT CSrmpToMsmq::HandleServicesFilterDups(void) {
	ServiceCheckAndSet(SRMP_ST_SERVICES_FILTERDUPLICATES);
	return S_OK;
}


//
// <services><commitmentReceiptRequest>
//
HRESULT CSrmpToMsmq::HandleServicesCommitRcpt(void) {
	ServiceCheckAndSet(SRMP_ST_SERVICES_COMMITMENTRECEIPTREQUEST);

	if (! IsSetSrmp(cMsgProps.dwServiceSet,SRMP_ST_SERVICES_COMMITMENTRECEIPTREQUEST_SENDTO))
		return E_FAIL;

	return S_OK;
}

HRESULT CSrmpToMsmq::HandleServicesCommitRcptPositevOnly(void) {
	ServiceCheckAndSet(SRMP_ST_SERVICES_COMMITMENTRECEIPTREQUEST_POSITIVEONLY);
	cMsgProps.acknowledgeType |= MQMSG_ACKNOWLEDGMENT_POS_RECEIVE;
	return S_OK;
}

HRESULT CSrmpToMsmq::HandleServicesCommitRcptNegativeOnly(void) {
	ServiceCheckAndSet(SRMP_ST_SERVICES_COMMITMENTRECEIPTREQUEST_NEGATIVEONLY);
	cMsgProps.acknowledgeType |= MQMSG_ACKNOWLEDGMENT_NEG_RECEIVE;
	return S_OK;
}

HRESULT CSrmpToMsmq::HandleServicesCommitRcptSendBy(void) {
	ServiceCheckAndSet(SRMP_ST_SERVICES_COMMITMENTRECEIPTREQUEST_SENDBY);
	return S_OK;
}

HRESULT CSrmpToMsmq::HandleServicesCommitRcptSendTo(void) {
	ServiceCheckAndSet(SRMP_ST_SERVICES_COMMITMENTRECEIPTREQUEST_SENDTO);

	if (!UriToQueueFormat(GetBuffer(),GetNumChars(),&cMsgProps.adminQueue,&cMsgProps.szAdminQueue))
		return E_FAIL;
	return S_OK;
}

//
// <services><deliveryReceiptRequest>
//
HRESULT CSrmpToMsmq::HandleServicesDelRcptRequest(void) {
	ServiceCheckAndSet(SRMP_ST_SERVICES_DELIVERYRECEIPTREQUEST);
	
	if (! IsSetSrmp(cMsgProps.dwServiceSet,SRMP_ST_SERVICES_DELIVERYRECEIPTREQUEST_SENDTO))
		return E_FAIL;
	return S_OK;
}

HRESULT CSrmpToMsmq::HandleServicesDelRcptRequestSendTo(void) {
	ServiceCheckAndSet(SRMP_ST_SERVICES_DELIVERYRECEIPTREQUEST_SENDTO);

	cMsgProps.acknowledgeType |= MQMSG_ACKNOWLEDGMENT_POS_ARRIVAL;
	if (!UriToQueueFormat(GetBuffer(),GetNumChars(),&cMsgProps.adminQueue,&cMsgProps.szAdminQueue))
		return E_FAIL;
	return S_OK;
}

HRESULT CSrmpToMsmq::HandleServicesDelRcptRequestSendBy(void) {
	ServiceCheckAndSet(SRMP_ST_SERVICES_DELIVERYRECEIPTREQUEST_SENDBY);
	return S_OK;
}

//
// <Properties>
//
HRESULT CSrmpToMsmq::HandleProps(void) {
	if (IsHeaderSet(SRMP_ST_PROPERTIES))
		return E_FAIL;
	SetHeader(SRMP_ST_PROPERTIES);

	// Note: XP MSMQ router does not check for expiresAt, but latest version of spec requires it.
	if (! IsSetSrmp(cMsgProps.dwPropertiesSet,SRMP_ST_PROPERTIES_EXPIRESAT))

⌨️ 快捷键说明

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