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

📄 srmpmsg.cxx

📁 Windows CE 6.0 Server 源码
💻 CXX
📖 第 1 页 / 共 3 页
字号:
}

HRESULT CSrmpToMsmq::HandleMsmqEodLast(void) {
	MsmqRcptCheckAndSet(SRMP_ST_MSMQ_EOD_LAST);
	cMsgProps.fLast = TRUE;
	return S_OK;
}

HRESULT CSrmpToMsmq::HandleMsmqEodXConnectorId(void) {
	MsmqRcptCheckAndSet(SRMP_ST_MSMQ_EOD_XCONNECTORID);
	if (IsEmpty())
		return E_FAIL;

	return StringToGuid(GetBuffer(),&cMsgProps.connectorId) ? S_OK : E_FAIL;
}

// <msmq><provider>.  Security related, not supported on WinCE.
HRESULT CSrmpToMsmq::HandleMsmqProvider(void) {
	MsmqRcptCheckAndSet(SRMP_ST_MSMQ_PROVIDER);

	if (! IsSetSrmp(cMsgProps.dwMsmqSet,SRMP_ST_MSMQ_PROVIDER_TYPE) ||
	    ! IsSetSrmp(cMsgProps.dwMsmqSet,SRMP_ST_MSMQ_PROVIDER_NAME))
		return E_FAIL;

	return S_OK;
}

HRESULT CSrmpToMsmq::HandleMsmqProviderType(void) {
	MsmqRcptCheckAndSet(SRMP_ST_MSMQ_PROVIDER_TYPE);
	return S_OK;
}

HRESULT CSrmpToMsmq::HandleMsmqProviderName(void) {
	MsmqRcptCheckAndSet(SRMP_ST_MSMQ_PROVIDER_NAME);
	return S_OK;
}

DWORD CSrmpMessageProperties::CalculatePacketSize(DWORD *pdwBaseSize) {
	const QUEUE_FORMAT  *pAdminQueue     = (adminQueue.GetType() != QUEUE_FORMAT_TYPE_UNKNOWN) ? &adminQueue : NULL;
	const QUEUE_FORMAT  *pResponseQueue  = (responseQueue.GetType() != QUEUE_FORMAT_TYPE_UNKNOWN) ? &responseQueue : NULL;
	const GUID          *pGuidConnType   = (connectorType != GUID_NULL) ? &connectorType : NULL;
	const GUID          *pGuidConnId     = (connectorId   != GUID_NULL) ? &connectorId   : NULL;
	DWORD cbData = 0;
	PSTR  szData = 0; 

	DWORD cbPacket = 0;

	cbPacket  = CBaseHeader::CalcSectionSize ();
	cbPacket += CUserHeader::CalcSectionSize (&SourceQmGuid,&GUID_NULL,pGuidConnType,
	                                          &destQueue,pAdminQueue, pResponseQueue);

	if (IsXActIncluded())
		cbPacket += CXactHeader::CalcSectionSize(&EodSeqId,pGuidConnId);

	cMime.GetMimeAttachment(cszEnvelopeId,&szData,&cbData);
	cbPacket += CPropertyHeader::CalcSectionSize(szTitle ? wcslen(szTitle)+1 : 0,cbData,0);

	cbPacket += CSrmpEnvelopeHeader::CalcSectionSize(ccEnvelope);

	cbPacket += CCompoundMessageHeader::CalcSectionSize(pHttpParams->cbHeaders,pHttpParams->cbPost);

	if (EodStreamId) {
		DWORD ccEodStreamId = (wcslen(EodStreamId)+1)*sizeof(WCHAR);
		DWORD ccOrderQueue  = szOrderQueue ? (wcslen(szOrderQueue)+1)*sizeof(WCHAR) : 0;
		cbPacket += CEodHeader::CalcSectionSize(ccEodStreamId,ccOrderQueue);
	}

	if (EodAckStreamId)
		cbPacket += CEodAckHeader::CalcSectionSize((wcslen(EodAckStreamId)+1)*sizeof(WCHAR));

	*pdwBaseSize = cbPacket;

	if (revViaBuf.uiNextIn)
		cbPacket += CDataHeader::CalcSectionSize(revViaBuf.uiNextIn / sizeof(WCHAR),TRUE);

	if (fwdViaBuf.uiNextIn)
		cbPacket += CDataHeader::CalcSectionSize(fwdViaBuf.uiNextIn / sizeof(WCHAR),TRUE);

	if (szFrom || szRelatesTo)
		cbPacket += CSoapExtSection::CalcSectionSize(ccFrom,ccRelatesTo);

	return cbPacket;
}

BOOL CSrmpToMsmq::PutMessageInQueue(ScPacketImage *pImage) {
	ScQueue             *pQueue          = NULL;

	if (! (pQueue = gQueueMan->FindQueueByPacketImage (pImage, FALSE))) {
#if defined (SC_VERBOSE)
		scerror_DebugOut (VERBOSE_MASK_SESSION, L"User packet arrived to non-existent queue...\n");
#endif
		gQueueMan->ForwardTransactionalResponse (pImage, MQMSG_CLASS_NACK_BAD_DST_Q, NULL, NULL);
		gQueueMan->RejectPacket (pImage, MQMSG_CLASS_NACK_BAD_DST_Q);
	} else {
		//
		//	Put this thing in a queue...
		//
		//
		//	If we don't have resources, this will fail. In this case we'd
		//	better close the connection.
		//
		if (pQueue->qp.bTransactional) {
			if (! gQueueMan->StoreTransactionalPacket (pQueue, pImage, NULL, NULL))
				return FALSE;
		} else {
			pImage->hkOrderKey = ++pQueue->hkReceived;
			pImage->hkOrderKey |= (pImage->sect.pBaseHeader->GetPriority() ^ MQ_MAX_PRIORITY) << SCPACKET_ORD_TIMEBITS;
			ScPacket *pPacket = pQueue->MakePacket (pImage, -1, TRUE);

			if (! pPacket) {
#if defined (SC_VERBOSE)
				scerror_DebugOut (VERBOSE_MASK_SESSION, L"User packet from cannot be put into %s...\n", pQueue->lpszFormatName);
#endif
				gQueueMan->RejectPacket (pImage, MQMSG_CLASS_NACK_Q_EXCEED_QUOTA);
				return FALSE;
			} else
				gQueueMan->AcceptPacket (pPacket, MQMSG_CLASS_ACK_REACH_QUEUE, pQueue);
		}
	}
	return pQueue ? TRUE : FALSE;
}

BOOL CSrmpToMsmq::CreateAndInsertPacket(void) {
	ScPacket       *pPacket      = NULL;
	ScPacketImage  *pPacketImage = NULL;
	BOOL           fRet          = FALSE;

	if (! cMsgProps.VerifyProperties()) {
		SetBadRequest();
		return FALSE;
	}

	if (!fApiInitialized) {
		SetUnavailable();
		return FALSE;
	}

	gMem->Lock();
	if (glServiceState != SERVICE_STATE_ON) {
		SetUnavailable();
		goto done;
	}

	if (NULL == (pPacketImage = cMsgProps.BuildPacketImage()))
		goto done;

	SetSuccess(); // once we process message (regardless of other possible errors) we're done.
	if (! PutMessageInQueue(pPacketImage))
		goto done;

	fRet = TRUE;
done:
	if (!fRet && pPacketImage)
		g_funcFree (pPacketImage, g_pvFreeData);

	gMem->Unlock();
	return fRet;
}

// Convert cMsgProps to an MSMQ packet (including MIME info)
ScPacketImage * CSrmpMessageProperties::BuildPacketImage(void) {
	BOOL                fRet                 = FALSE;
	ScPacketImage       *pPacketImage        = NULL;
	CBaseHeader         *pBaseHeader         = NULL;
	CUserHeader         *pUserHeader         = NULL;
	CPropertyHeader     *pPropHeader         = NULL;
	CEodHeader          *pEodHeader          = NULL;
	CEodAckHeader       *pEodAckHeader       = NULL;
	CSrmpEnvelopeHeader* pSrmpEnvelopeHeader = NULL;
	CCompoundMessageHeader* pCmpndMsgHeader  = NULL;
	CDataHeader         *pFwdHeader          = NULL; 
	CDataHeader         *pRevHeader          = NULL; 
	CDataHeader         *pOrigURL            = NULL; 
	CSoapExtSection     *pSoapExtSection     = NULL;
	const QUEUE_FORMAT  *pAdminQueue     = (adminQueue.GetType() != QUEUE_FORMAT_TYPE_UNKNOWN) ? &adminQueue : NULL;
    const QUEUE_FORMAT  *pResponseQueue  = (responseQueue.GetType() != QUEUE_FORMAT_TYPE_UNKNOWN) ? &responseQueue : NULL;
	const GUID          *pGuidConnType   = (connectorType != GUID_NULL) ? &connectorType : NULL;
	const GUID          *pGuidConnId     = (connectorId   != GUID_NULL) ? &connectorId   : NULL;


	PSTR  szMimeBody    = NULL;
	DWORD cbMimeBody    = 0;
	DWORD cbMimeOffset;
	DWORD cbBaseSize = 0;

	DWORD               cbPacket;
	CHAR                *szData = NULL;
	DWORD               cbData  = 0;
	void                *pvPacketBuffer;

	const USHORT x_SRMP_ENVELOPE_ID = 400;
	const USHORT x_COMPOUND_MESSAGE_ID = 500;

	if (0 == (cbPacket = CalculatePacketSize(&cbBaseSize)))
		goto done;

	if (NULL == (pPacketImage = (ScPacketImage *)g_funcAlloc (sizeof(ScPacketImage) + cbPacket, g_pvAllocData))) {
		scerror_DebugOutM(VERBOSE_MASK_SRMP,(L"SRMP: unable to allocate memory!\r\n"));
		goto done;
	}

	pvPacketBuffer = (void *)((unsigned char *)pPacketImage + sizeof(ScPacketImage));
	memset (&pPacketImage->sect, 0, sizeof (pPacketImage->sect));
	memset (&pPacketImage->ucSourceAddr, 0, sizeof(pPacketImage->ucSourceAddr));

	pPacketImage->pvBinary = NULL;
	pPacketImage->pvExt    = NULL;
	pPacketImage->allflags = 0;
	// fSecureSession means not only over SSL but that client is using 
	// an authenticated client certificate, which currently CE web server doesn't support.
	// Note: BUG IN THE PROTOCOL. If this is set to FALSE, then no nacks can be generated
	// (because it is possible to cause DOS attack with acks).
	pPacketImage->flags.fSecureSession=!gMachine->fUntrustedNetwork;
	pPacketImage->flags.fSRMPGenerated     = TRUE;  // determines rules for handeling fwds
	pPacketImage->flags.fHaveIpv4Addr      = (pHttpParams->dwIP4Addr != INADDR_NONE);

	if (pPacketImage->flags.fHaveIpv4Addr)
		pPacketImage->ipSourceAddr.s_addr = pHttpParams->dwIP4Addr;

	// Base
	pBaseHeader = (CBaseHeader *)pvPacketBuffer;
	pBaseHeader->CBaseHeader::CBaseHeader (cbBaseSize);
	pBaseHeader->SetPriority (priority);
	pBaseHeader->SetTrace (fTrace);
	pBaseHeader->SetAbsoluteTimeToQueue (IsMSMQIncluded() ? absoluteTimeToQueue : absoluteTimeToLive);

	// UserHeader
	pUserHeader = (CUserHeader *)pBaseHeader->GetNextSection ();

	pUserHeader->CUserHeader::CUserHeader (&SourceQmGuid,
	                                       &GUID_NULL, 
	                                       &destQueue,
	                                       pAdminQueue,
	                                       pResponseQueue,
	                                       messageId.Uniquifier);

    if (pGuidConnType)
	    pUserHeader->SetConnectorType(pGuidConnType);

	pUserHeader->SetTimeToLiveDelta (IsMSMQIncluded() ? absoluteTimeToLive - absoluteTimeToQueue : 0);
	pUserHeader->SetSentTime (sentTime);
	pUserHeader->SetDelivery (delivery);
	pUserHeader->IncludeProperty (TRUE);
	pUserHeader->SetAuditing (auditing);

	// XAct
	if (IsXActIncluded()) {
		pUserHeader->IncludeXact(TRUE);
		CXactHeader *pXactHeader = (CXactHeader *)pUserHeader->GetNextSection ();

		pXactHeader->CXactHeader::CXactHeader (NULL);
		pXactHeader->SetCancelFollowUp(TRUE);
		pXactHeader->SetSeqID(EodSeqId);
		pXactHeader->SetSeqN(EodSeqNo);
		pXactHeader->SetPrevSeqN(EodPrevSeqNo);
		pXactHeader->SetFirstInXact(fFirst);
		pXactHeader->SetLastInXact(fLast);

		if (pGuidConnId)
			pXactHeader->SetConnectorQM(pGuidConnId);

		pPropHeader = (CPropertyHeader *)pXactHeader->GetNextSection ();
	} else
		pPropHeader = (CPropertyHeader *)pUserHeader->GetNextSection ();

	// Properties
	pPropHeader->CPropertyHeader::CPropertyHeader ();
	pPropHeader->SetClass (classValue);
	if (pCorrelationID)
		pPropHeader->SetCorrelationID (pCorrelationID);

	pPropHeader->SetAckType (acknowledgeType);
	pPropHeader->SetApplicationTag (applicationTag);
	pPropHeader->SetBodyType (bodyType);

	if (szTitle)
		pPropHeader->SetTitle (szTitle, wcslen (szTitle) + 1);

	if (cMime.GetMimeAttachment(cszEnvelopeId,&szData,&cbData))
		pPropHeader->SetMsgExtension ((const UCHAR*)szData, cbData);
	
	pPropHeader->SetHashAlg (0);
	pPropHeader->SetPrivLevel (MQMSG_PRIV_LEVEL_NONE);
	pPropHeader->SetEncryptAlg (0);


	// SrmpEnvelopeHeader section.
	pUserHeader->IncludeSrmp(TRUE);
	pSrmpEnvelopeHeader = (CSrmpEnvelopeHeader*) pPropHeader->GetNextSection();
	pSrmpEnvelopeHeader->CSrmpEnvelopeHeader::CSrmpEnvelopeHeader(bstrEnvelope,ccEnvelope,x_SRMP_ENVELOPE_ID);
	pCmpndMsgHeader = (CCompoundMessageHeader*) pSrmpEnvelopeHeader->GetNextSection();


	// CCompoundMessageHeader section.
	cMime.GetMimeAttachment(cszMimeBodyId,&szMimeBody,&cbMimeBody);
	cbMimeOffset = szMimeBody ? szMimeBody-pHttpParams->pszPost : 0;

	pCmpndMsgHeader->CCompoundMessageHeader::CCompoundMessageHeader((UCHAR*)pHttpParams->pszHeaders,pHttpParams->cbHeaders,(UCHAR*)pHttpParams->pszPost,
	                                         pHttpParams->cbPost,cbMimeBody,cbMimeOffset,x_COMPOUND_MESSAGE_ID);

	// EODHeader Section, <stream> information.
	if (EodStreamId) {
		pUserHeader->IncludeEod(TRUE);
		pEodHeader = (CEodHeader *) pCmpndMsgHeader->GetNextSection();

		const USHORT x_EOD_ID = 600;
		DWORD ccEodStreamId = (wcslen(EodStreamId)+1)*sizeof(WCHAR);
		DWORD ccOrderQueue  = szOrderQueue ? (wcslen(szOrderQueue)+1)*sizeof(WCHAR) : 0;

		pEodHeader->CEodHeader::CEodHeader(x_EOD_ID,ccEodStreamId,(UCHAR*)EodStreamId,
		                                   ccOrderQueue,(UCHAR*)szOrderQueue);

		pEodAckHeader = (CEodAckHeader *) pEodHeader->GetNextSection();
	}
	else
		pEodAckHeader = (CEodAckHeader *) pCmpndMsgHeader->GetNextSection();

	// <streamReceipt> information.
	if (EodAckStreamId) {
		pUserHeader->IncludeEodAck(TRUE);
		const USHORT x_EOD_ACK_ID = 700;
		pEodAckHeader->CEodAckHeader::CEodAckHeader(x_EOD_ACK_ID,&EodAckSeqId,&EodAckSeqNo,
		                                            (wcslen(EodAckStreamId)+1)*sizeof(WCHAR),(UCHAR*)EodAckStreamId);

		pFwdHeader = (CDataHeader *) pEodAckHeader->GetNextSection();
	}
	else
		pFwdHeader = (CDataHeader *) pEodAckHeader;

	// <fwd><via> elements
	if (fwdViaBuf.uiNextIn) {
		pPacketImage->flags.fFwdIncluded = TRUE;
		pFwdHeader->CDataHeader::CDataHeader((WCHAR*)fwdViaBuf.pBuffer,fwdViaBuf.uiNextIn / sizeof(WCHAR));
		pRevHeader = (CDataHeader*) pFwdHeader->GetNextSection();
	}
	else
		pRevHeader = (CDataHeader*) pFwdHeader;

	// <rev><via> 
	if (revViaBuf.uiNextIn) {
		pPacketImage->flags.fRevIncluded = TRUE;
		pRevHeader->CDataHeader::CDataHeader((WCHAR*)revViaBuf.pBuffer,revViaBuf.uiNextIn / sizeof(WCHAR));
		pSoapExtSection = (CSoapExtSection*) pRevHeader->GetNextSection();
	}
	else
		pSoapExtSection = (CSoapExtSection*) pRevHeader;

	if (szFrom || szRelatesTo) {
		pPacketImage->flags.fSoapExtIncluded = TRUE;
		pSoapExtSection->CSoapExtSection::CSoapExtSection(szFrom,ccFrom,szRelatesTo,ccRelatesTo);
		pOrigURL = (CDataHeader*) pSoapExtSection->GetNextSection();
	}
	else
		pOrigURL = (CDataHeader*) pSoapExtSection;

//	pPacketImage->flags.fOriginalURLIncluded = TRUE;
	if (! pPacketImage->PopulateSections ())
		goto done;

	fRet = TRUE;
done:
	if (!fRet && pPacketImage) {
		g_funcFree(pPacketImage, g_pvFreeData);
		return NULL;
	}
	return pPacketImage;
}

BOOL BreakMsmqStreamId(const WCHAR *szBuffer, LONGLONG *pSeqId) {
	static const WCHAR cDivider = L'\\';
	WCHAR *szTrav = (WCHAR*)wcschr(szBuffer,cDivider);
	if (! szTrav)
		return FALSE;

	*szTrav       = 0;
	*pSeqId       = _wtoi64(szTrav+1);
	return TRUE;
}

// Now that all data has been read, there's some extra fixups we need to perform.
BOOL CSrmpMessageProperties::VerifyProperties(void) {
	if (IsMSMQIncluded() && absoluteTimeToQueue > absoluteTimeToLive)
		return FALSE;

	if (!(dwHeaderSet & SRMP_ST_PATH) || !( dwHeaderSet & SRMP_ST_PROPERTIES))
		return FALSE;

	// Handle <stream>.  We can only properly process it at this stage since
	// handeling differs depending on whether <MSMQ>...</MSMQ> was included.
	if (szStreamIdBuf && IsMSMQIncluded()) {
		if (!BreakMsmqStreamId(szStreamIdBuf,&EodSeqId))
			return FALSE;
	}
	if (szStreamIdBuf)
		EodStreamId = szStreamIdBuf;

	return TRUE;
}

BOOL CSrmpMime::GetMimeAttachment(const CHAR *szContentId, CHAR **ppszData, DWORD *pcbData) {
	PMIME_ATTACHMENT pTrav = m_pMime;
	DWORD cbContentId      = strlen(szContentId);
	SVSUTIL_ASSERT(*ppszData == NULL && *pcbData == 0);

	while (pTrav) {
		if (0 == _strnicmp(szContentId,pTrav->szContentId,cbContentId)) {
			*ppszData = pTrav->szBody;
			*pcbData  = pTrav->cbBody;
			return TRUE;
		}
		pTrav = pTrav->pNext;
	}
	return FALSE;
}

⌨️ 快捷键说明

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