📄 msg.cpp
字号:
//
// 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.
//
//--------------------------------------------------------------------------=
// MSMQMessageObj.Cpp
//=--------------------------------------------------------------------------=
// the MSMQMessage object
//
//
//
// Needed for wincrypt.h
//
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0400
#endif
#include <windows.h>
#include <winreg.h>
#include <wincrypt.h>
#include <intsafe.h>
#include "IPServer.H"
#include "LocalObj.H"
#include "limits.h" // for UINT_MAX
#include "utilx.h"
#include "msg.H"
#include "qinfo.h"
#include "q.h"
//#include "txdtc.h" // no transaction support.
//#include "xact.h"
//#include "mtxdm.h"
//
// some message property buffer sizes
//
#define SENDERIDLEN 32
#define SENDERCERTLEN 4096
#if DEBUG
extern VOID RemBstrNode(void *pv);
#endif // DEBUG
extern IUnknown *GetPunk(VARIANT *pvar);
// for ASSERT and FAIL
//
SZTHISFILE
// debug...
#define new DEBUG_NEW
#if DEBUG
#define SysAllocString DebSysAllocString
#define SysReAllocString DebSysReAllocString
#define SysFreeString DebSysFreeString
#endif // DEBUG
extern UCHAR *AllocateCauVector (CAUB *pcau);
extern HGLOBAL AllocateBodyBuffer(
MQMSGPROPS *pmsgprops,
UINT iBody,
DWORD dwBodySize);
extern void DeleteCauVector (CAUB *pcau);
PROPREC g_rgmsgproprec[] = {
{PROPID_M_MSGID, VT_UI1|VT_VECTOR},
{PROPID_M_CORRELATIONID, VT_UI1|VT_VECTOR},
{PROPID_M_PRIORITY, VT_UI1},
{PROPID_M_DELIVERY, VT_UI1},
{PROPID_M_ACKNOWLEDGE, VT_UI1},
{PROPID_M_JOURNAL, VT_UI1},
{PROPID_M_APPSPECIFIC, VT_UI4},
{PROPID_M_LABEL, VT_LPWSTR},
{PROPID_M_LABEL_LEN, VT_UI4},
{PROPID_M_TIME_TO_BE_RECEIVED, VT_UI4},
{PROPID_M_TRACE, VT_UI1},
{PROPID_M_TIME_TO_REACH_QUEUE, VT_UI4},
{PROPID_M_SENDERID, VT_UI1|VT_VECTOR},
{PROPID_M_SENDERID_LEN, VT_UI4},
{PROPID_M_SENDERID_TYPE, VT_UI4},
{PROPID_M_PRIV_LEVEL, VT_UI4}, // must precede ENCRYPTION_ALG
{PROPID_M_AUTH_LEVEL, VT_UI4},
{PROPID_M_AUTHENTICATED, VT_UI4}, // must precede HASH_ALG
// {PROPID_M_HASH_ALG, VT_UI4},
// {PROPID_M_ENCRYPTION_ALG, VT_UI4},
{PROPID_M_SENDER_CERT, VT_UI1|VT_VECTOR},
{PROPID_M_SENDER_CERT_LEN, VT_UI4},
{PROPID_M_SRC_MACHINE_ID, VT_CLSID},
{PROPID_M_SENTTIME, VT_UI4},
{PROPID_M_ARRIVEDTIME, VT_UI4},
{PROPID_M_RESP_QUEUE, VT_LPWSTR},
{PROPID_M_RESP_QUEUE_LEN, VT_UI4},
{PROPID_M_ADMIN_QUEUE, VT_LPWSTR},
{PROPID_M_ADMIN_QUEUE_LEN, VT_UI4},
// {PROPID_M_SECURITY_CONTEXT, VT_UI4},
{PROPID_M_CLASS, VT_UI2},
{PROPID_M_BODY_TYPE, VT_UI4}
};
ULONG g_cPropRec = sizeof g_rgmsgproprec / sizeof g_rgmsgproprec[0];
PROPREC g_rgmsgproprecOptional[] = {
{PROPID_M_DEST_QUEUE, VT_LPWSTR},
{PROPID_M_DEST_QUEUE_LEN, VT_UI4},
{PROPID_M_BODY, VT_UI1|VT_VECTOR},
{PROPID_M_BODY_SIZE, VT_UI4}
};
ULONG g_cPropRecOptional = sizeof g_rgmsgproprecOptional / sizeof g_rgmsgproprecOptional[0];
#if 0 // not used
PROPREC g_rgproprecAsyncReceive[] = {
{PROPID_M_BODY, VT_UI1|VT_VECTOR},
{PROPID_M_BODY_SIZE, VT_UI4},
};
ULONG g_cPropRecAsyncReceive =
sizeof g_rgproprecAsyncReceive / sizeof g_rgproprecAsyncReceive[0];
#endif // 0
// typedef HRESULT (STDAPIVCALLTYPE * LPFNGetDispenserManager)(
// IDispenserManager **ppdispmgr);
//=--------------------------------------------------------------------------=
// HELPER: GetOptionalTransaction
//=--------------------------------------------------------------------------=
// Gets optional transaction
//
// Parameters:
// pvarTransaction [in]
// pptransaction [out]
// pisRealXact [out] TRUE if true pointer else enum.
//
// Output:
//
// Notes:
//
HRESULT GetOptionalTransaction(
VARIANT *pvarTransaction,
ITransaction **pptransaction,
BOOL *pisRealXact)
{
// IMSMQTransaction *pmqtransaction = NULL;
IDispatch *pdisp = NULL;
ITransaction *ptransaction = NULL;
HRESULT hresult = NOERROR;
//
// get optional transaction...
//
*pisRealXact = FALSE; // pessimism
pdisp = GetPdisp(pvarTransaction);
if (pdisp) {
#if 0 // no real Transaction support
IfFailGo(pdisp->QueryInterface(
IID_IMSMQTransaction,
(LPVOID *)&pmqtransaction));
ASSERT(pmqtransaction, L"should have a transaction.");
// extract ITransaction interface pointer
IfFailGo(pmqtransaction->get_Transaction((long*)&ptransaction));
ADDREF(ptransaction);
*pisRealXact = TRUE;
#else // 0
return E_NOTIMPL;
#endif
}
else {
//
// 1890: no explicit transaction supplied: use current
// Viper transaction if there is one... unless
// Nothing explicitly supplied in Variant. Note
// that if arg is NULL this means that it wasn't
// supplied as an optional param so just treat it
// like Nothing, i.e. don't user Viper.
//
// 1915: support:
// MQ_NO_TRANSACTION/VT_ERROR
// MQ_MTS_TRANSACTION
// MQ_XA_TRANSACTION
// MQ_SINGLE_MESSAGE
//
if (pvarTransaction) {
if (V_VT(pvarTransaction) == VT_ERROR) {
#ifndef _WIN32_CE // under ce, we use MQ_SINGLE_TRANSACTION only or NULL
ptransaction = (ITransaction *)MQ_MTS_TRANSACTION;
#else
ptransaction = (ITransaction *)MQ_NO_TANSACTION;
#endif _WIN32_CE
}
else {
UINT uXactType;
uXactType = GetNumber(pvarTransaction);
if (uXactType != (UINT)MQ_NO_TRANSACTION &&
// uXactType != (UINT)MQ_MTS_TRANSACTION &&
// uXactType != (UINT)MQ_XA_TRANSACTION &&
uXactType != (UINT)MQ_SINGLE_MESSAGE) {
IfFailGo(hresult = E_INVALIDARG);
}
ptransaction = (ITransaction *)uXactType;
}
} // if
}
*pptransaction = ptransaction;
Error:
#if 0 // no transaction
RELEASE(pmqtransaction);
#endif // 0
return hresult;
}
//=--------------------------------------------------------------------------=
// HELPER: VtOfPropIdRgproprec
//=--------------------------------------------------------------------------=
// Looks up propid in global vt array by propid and returns vt
//
// Parameters:
// propid [in] propid to lookup
//
// Output:
// returns ordinal of propid in global array, VT_ERROR if not found.
// Notes:
//
VARTYPE VtOfPropIdRgproprec(
MSGPROPID propid,
PROPREC *rgproprec,
UINT cPropRec)
{
UINT iProp;
for (iProp = 0; iProp < cPropRec; iProp++) {
if (rgproprec[iProp].m_propid == propid) {
return rgproprec[iProp].m_vt;
}
}
return VT_ERROR;
}
//=--------------------------------------------------------------------------=
// HELPER: VtOfPropId
//=--------------------------------------------------------------------------=
// Looks up propid in global vt array by propid and returns vt
//
// Parameters:
// propid [in] propid to lookup
//
// Output:
// returns ordinal of propid in global array, VT_ERROR if not found.
// Notes:
//
VARTYPE VtOfPropId(MSGPROPID propid)
{
return VtOfPropIdRgproprec(propid, g_rgmsgproprec, g_cPropRec);
}
//=--------------------------------------------------------------------------=
// HELPER: OrdinalOfPropId
//=--------------------------------------------------------------------------=
// Looks up propid in msgprops array and return ordinal
//
// Parameters:
// pmsgprops [in] lookup array
// propid [in] propid to lookup
//
// Output:
// returns ordinal of propid in msgprops array, -1 if not found.
// Notes:
//
UINT OrdinalOfPropId(MQMSGPROPS *pmsgprops, MSGPROPID propid)
{
UINT iProp;
for (iProp = 0; iProp < pmsgprops->cProp; iProp++) {
if (pmsgprops->aPropID[iProp] == propid) {
return iProp;
}
}
return UINT_MAX;
}
//=--------------------------------------------------------------------------=
// HELPER: AddPropRecRgproprec
//=--------------------------------------------------------------------------=
// Appends a propid to array
//
// Parameters:
// propid [in] propid to add
// prgproprec [out] array
// pcPropRec [in/out] array size
//
// Output:
//
// Notes:
// Reallocs array as needed.
//
HRESULT AddPropRecOfRgproprec(
MSGPROPID propid,
PROPREC *rgproprec,
UINT cPropRec,
PROPREC **prgproprecOut,
UINT *pcPropRecOut)
{
UINT cPropRecOut = *pcPropRecOut;
PROPREC proprec;
PROPREC *rgproprecOut = *prgproprecOut;
proprec.m_propid = propid;
proprec.m_vt = VtOfPropIdRgproprec(
propid,
rgproprec,
cPropRec);
ULONG cRgproprecAlloc; // (cPropRecOut + 1) * sizeof(PROPREC))
if (FAILED(ULongAdd(cPropRecOut,1,&cRgproprecAlloc)) ||
FAILED(ULongMult(cRgproprecAlloc,sizeof(PROPREC),&cRgproprecAlloc)))
{
return E_OUTOFMEMORY;
}
IfNullRet(rgproprecOut =
(PROPREC *)realloc(rgproprecOut,cRgproprecAlloc));
rgproprecOut[cPropRecOut++] = proprec;
*pcPropRecOut = cPropRecOut;
*prgproprecOut = rgproprecOut;
return NOERROR;
}
//=--------------------------------------------------------------------------=
// HELPER: AddPropRecOptional
//=--------------------------------------------------------------------------=
// Appends a propid to array
//
// Parameters:
// propid [in] propid to add
// prgproprec [out] array
// pcPropRec [in/out] array size
//
// Output:
//
// Notes:
// Reallocs array as needed.
//
HRESULT AddPropRecOptional(
MSGPROPID propid,
PROPREC **prgproprec,
UINT *pcPropRec)
{
return AddPropRecOfRgproprec(
propid,
g_rgmsgproprecOptional,
g_cPropRecOptional,
prgproprec,
pcPropRec);
}
//=--------------------------------------------------------------------------=
// HELPER: AddPropRec
//=--------------------------------------------------------------------------=
// Appends a propid to array
//
// Parameters:
// propid [in] propid to add
// prgproprec [out] array
// pcPropRec [in/out] array size
//
// Output:
//
// Notes:
// Reallocs array as needed.
//
HRESULT AddPropRec(
MSGPROPID propid,
PROPREC **prgproprec,
UINT *pcPropRec)
{
return AddPropRecOfRgproprec(
propid,
g_rgmsgproprec,
g_cPropRec,
prgproprec,
pcPropRec);
}
//=--------------------------------------------------------------------------=
// HELPER: AllocateVectorOfProperty
//=--------------------------------------------------------------------------=
// creates a new MSMQMessage object.
//
// Parameters:
// pmsgprops
// iProp
// cb
//
// Output:
//
// Notes:
//
UCHAR *AllocateVectorOfProperty(
MQMSGPROPS *pmsgprops,
UINT iProp,
UINT cb)
{
pmsgprops->aPropVar[iProp].caub.cElems = cb;
pmsgprops->aPropVar[iProp].caub.pElems = NULL;
return AllocateCauVector(&pmsgprops->aPropVar[iProp].caub);
}
//=--------------------------------------------------------------------------=
// HELPER: AllocateMessageProps
//=--------------------------------------------------------------------------=
// Allocate and init message prop arrays
//
HRESULT AllocateMessageProps(
MQMSGPROPS *pmsgprops,
PROPREC *rgproprec,
UINT cProp)
{
UINT i;
HRESULT hresult = NOERROR;
pmsgprops->aPropID = NULL;
pmsgprops->aPropVar = NULL;
pmsgprops->aStatus = NULL;
pmsgprops->cProp = cProp;
IfNullRet(pmsgprops->aPropID = new MSGPROPID[cProp]);
IfNullFail(pmsgprops->aPropVar = new MQPROPVARIANT[cProp]);
IfNullFail(pmsgprops->aStatus = new HRESULT[cProp]);
for (i = 0; i < cProp; i++) {
pmsgprops->aPropID[i] = rgproprec[i].m_propid;
pmsgprops->aPropVar[i].vt = rgproprec[i].m_vt;
}
Error:
return hresult;
}
//=--------------------------------------------------------------------------=
// HELPER: AllocateReceiveMessageProps
//=--------------------------------------------------------------------------=
// Allocate and init message prop arrays for receive.
//
HRESULT AllocateReceiveMessageProps(
BOOL wantDestQueue,
BOOL wantBody,
MQMSGPROPS *pmsgprops,
PROPREC *rgproprec,
UINT cProp,
UINT *pcPropOut)
{
MSGPROPID propid;
UINT i, cPropOut = cProp, cPropOld = cProp;
HRESULT hresult = NOERROR;
pmsgprops->aPropID = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -