📄 srmpmsg.cxx
字号:
}
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 + -