📄 msg.cpp
字号:
// Supports intrinsic variant types
//
HRESULT CMSMQMessage::PutVarBody(VARIANT varBody)
{
VARTYPE vt = V_VT(&varBody);
void *pvBody;
HRESULT hresult = NOERROR;
EnterCriticalSection(&m_CSlocal);
// UNDONE: VT_BYREF?
switch (vt) {
case VT_I2:
case VT_UI2:
m_cbBody = 2;
pvBody = &varBody.iVal;
break;
case VT_I4:
case VT_UI4:
m_cbBody = 4;
pvBody = &varBody.lVal;
break;
case VT_R4:
m_cbBody = 4;
pvBody = &varBody.fltVal;
case VT_R8:
m_cbBody = 8;
pvBody = &varBody.dblVal;
break;
case VT_CY:
m_cbBody = sizeof(CY);
pvBody = &varBody.cyVal;
break;
case VT_DATE:
m_cbBody = sizeof(DATE);
pvBody = &varBody.date;
break;
case VT_BOOL:
m_cbBody = sizeof(VARIANT_BOOL);
pvBody = &varBody.boolVal;
break;
case VT_I1:
case VT_UI1:
m_cbBody = 1;
pvBody = &varBody.bVal;
break;
case VT_BSTR:
BSTR bstrBody;
IfFailGo(GetTrueBstr(&varBody, &bstrBody));
m_cbBody = SysStringByteLen(bstrBody);
pvBody = bstrBody;
break;
default:
IfFailGo(hresult = E_INVALIDARG);
break;
} // switch
m_vtBody = vt;
hresult = UpdateBodyBuffer((ULONG)m_cbBody, pvBody ? pvBody : L"");
// fall through...
Error:
LeaveCriticalSection(&m_CSlocal);
return CreateErrorHelper(hresult, m_ObjectType);
}
//=--------------------------------------------------------------------------=
// CMSMQMessage::PutBinBody
//=--------------------------------------------------------------------------=
// Sets message body
//
// Parameters:
// psaBody - [in] binary message body
//
// Output:
//
// Notes:
// Supports arrays of any type
// and persistent ActiveX objects:
// i.e. objects that support IPersistStream | IPersistStorage
// and IDispatch.
//
HRESULT CMSMQMessage::PutBinBody(VARIANT varBody)
{
SAFEARRAY *psa = NULL;
UINT nDim, i, cbElem, cbBody;
long lLBound, lUBound;
VOID *pvData;
VARTYPE vt = varBody.vt;
IPersistStream *ppersstm = NULL;
IPersistStorage *ppersstg = NULL;
#if 0 // not used outside of "unimplemented" areas
IUnknown *punk = NULL;
IDispatch *pdisp = NULL;
LARGE_INTEGER li;
ULARGE_INTEGER ulibMax;
STATSTG statstg;
#endif // 0
MSGTYPE msgtype;
ILockBytes *plockbytes = NULL;
IStream *pstm = NULL;
IStorage *pstg = NULL;
BOOL bLocked = FALSE;
HRESULT hresult = NOERROR;
cbBody = 0;
GLOBALFREE(m_hMem);
m_pbBody = NULL;
switch (vt) {
case VT_DISPATCH:
return E_INVALIDARG;
#if 0 // not implemented
//
// QI to IPersistStream
//
pdisp = varBody.pdispVal;
if (pdisp == NULL) {
return E_INVALIDARG;
}
hresult = pdisp->QueryInterface(IID_IPersistStream,
(LPVOID *)&ppersstm);
// try IPersistStorage...
if (FAILED(hresult)) {
IfFailGo(pdisp->QueryInterface(IID_IPersistStorage,
(LPVOID *)&ppersstg));
msgtype = MSGTYPE_STORAGE;
}
else {
msgtype = MSGTYPE_STREAM;
}
#endif // 0 not implemented
break;
case VT_UNKNOWN:
return E_INVALIDARG;
#if 0 // not implemnented
//
// QI to IPersistStream
//
punk = varBody.punkVal;
if (punk == NULL) {
return E_INVALIDARG;
}
//
hresult = punk->QueryInterface(IID_IPersistStream,
(LPVOID *)&ppersstm);
// try IPersistStorage...
if (FAILED(hresult)) {
IfFailGo(punk->QueryInterface(IID_IPersistStorage,
(LPVOID *)&ppersstg));
msgtype = MSGTYPE_STORAGE;
}
else {
msgtype = MSGTYPE_STREAM;
}
#endif // 0 not implemented
break;
default:
msgtype = MSGTYPE_BINARY;
} // switch
// Lock us down so other threads won't write a message behind our backs
EnterCriticalSection(&m_CSlocal);
bLocked = TRUE;
//
// allocate new global handle of size 0
//
IfNullFail(m_hMem = GLOBALALLOC_MOVEABLE_NONDISCARD(0));
switch (msgtype) {
case MSGTYPE_STREAM:
#if 0 // not implemented
hresult = CreateStreamOnHGlobal(
m_hMem, // NULL, // hGlobal
FALSE, // TRUE, // fDeleteOnRelease
&pstm);
// reset stream seek pointer
LISet32(li, 0);
IfFailGo(pstm->Seek(li, STREAM_SEEK_SET, NULL));
// save
IfFailGo(OleSaveToStream(ppersstm, pstm));
// How big is our stream?
IfFailGo(pstm->Stat(&statstg, STATFLAG_NONAME));
ulibMax = statstg.cbSize;
if (ulibMax.HighPart != 0) {
IfFailGo(hresult = E_INVALIDARG);
}
cbBody = ulibMax.LowPart;
m_vtBody = VT_STREAMED_OBJECT;
#endif // 0
break;
case MSGTYPE_BINARY:
//
// array: compute byte count
//
psa = varBody.parray;
if (psa) {
nDim = SafeArrayGetDim(psa);
cbElem = SafeArrayGetElemsize(psa);
for (i = 1; i <= nDim; i++) {
IfFailGo(SafeArrayGetLBound(psa, i, &lLBound));
IfFailGo(SafeArrayGetUBound(psa, i, &lUBound));
cbBody += (lUBound - lLBound + 1) * cbElem;
}
IfFailGo(SafeArrayAccessData(psa, &pvData));
IfFailGo(UpdateBodyBuffer(cbBody, pvData));
}
m_vtBody = VT_ARRAY | VT_UI1;
break;
case MSGTYPE_STORAGE:
#if 0 // not implemented
//
// Always create a new storage object.
// REVIEW: Be nice if, as we do for streams, we could
// cache an in-memory storage and reuse --
// but I know of no way to reset a storage.
//
IfFailGo(CreateILockBytesOnHGlobal(
m_hMem, // NULL, // hGlobal
FALSE, // TRUE, // fDeleteOnRelease
&plockbytes));
IfFailGo(StgCreateDocfileOnILockBytes(
plockbytes,
STGM_CREATE |
STGM_READWRITE |
STGM_SHARE_EXCLUSIVE,
0, //Reserved; must be zero
&pstg));
IfFailGo(OleSave(ppersstg, pstg, FALSE /* fSameAsLoad */));
#if DEBUG
STATSTG statstg2;
IfFailGo(pstg->Stat(&statstg2, STATFLAG_NONAME));
DWORD cbSize;
// use LocalSize on WinCE
cbSize = LocalSize(m_hMem);
#endif // DEBUG
// now get underlying ILockBytes stats
IfFailGo(plockbytes->Stat(&statstg, STATFLAG_NONAME));
ulibMax = statstg.cbSize;
ASSERT(ulibMax.HighPart == 0, L"storage too large.");
cbBody = ulibMax.LowPart;
m_vtBody = VT_STORED_OBJECT;
#endif // 0
break;
default:
ASSERT(0, L"unreachable?");
break;
} // switch
m_cbBody = cbBody;
m_pbBody = (BYTE *)GlobalLock(m_hMem);
ASSERT(m_pbBody, L"should have valid pointer.");
GLOBALUNLOCK(m_hMem);
// fall through...
Error:
if(bLocked)
LeaveCriticalSection(&m_CSlocal);
if (psa) {
SafeArrayUnaccessData(psa);
}
RELEASE(ppersstm);
RELEASE(ppersstg);
RELEASE(plockbytes);
RELEASE(pstm);
RELEASE(pstg);
return CreateErrorHelper(
hresult,
m_ObjectType);
}
//=--------------------------------------------------------------------------=
// CMSMQMessage::GetStreamedObject
//=--------------------------------------------------------------------------=
// Produce streamed object from binary message body
//
// Parameters:
// pvarBody - [out] pointer to object
//
// Output:
//
// Notes:
// Object must implement IPersistStream
//
#if 0 // Not yet implemented
HRESULT CMSMQMessage::GetStreamedObject(VARIANT FAR* pvarBody)
{
HRESULT hresult = NOERROR;
IUnknown *punk = NULL;
IDispatch *pdisp = NULL;
IStream *pstm = NULL;
IPersistStream *ppersstm = NULL;
ASSERT(pvarBody, L"bad variant.");
VariantClear(pvarBody);
// Attempt to load from an in-memory stream
if (m_hMem) {
ASSERT(m_hMem == GlobalHandle(m_pbBody), L"bad handle.");
IfFailGo(GetStreamOfBody(m_cbBody, m_pbBody, &pstm));
// load
IfFailGo(OleLoadFromStream(pstm,
IID_IPersistStream,
(void **)&ppersstm));
//
// Supports IDispatch? if not, return IUnknown
//
IfFailGo(ppersstm->QueryInterface(IID_IUnknown,
(LPVOID *)&punk));
RELEASE(ppersstm);
hresult = punk->QueryInterface(IID_IDispatch,
(LPVOID *)&pdisp);
if (SUCCEEDED(hresult)) {
//
// Setup returned object
//
V_VT(pvarBody) = VT_DISPATCH;
pvarBody->pdispVal = pdisp;
ADDREF(pvarBody->pdispVal); // ownership transfers
}
else {
//
// return IUnknown interface
//
V_VT(pvarBody) = VT_UNKNOWN;
pvarBody->punkVal = punk;
ADDREF(pvarBody->punkVal); // ownership transfers
}
}
else {
V_VT(pvarBody) = VT_ERROR;
}
// fall through...
Error:
RELEASE(punk);
RELEASE(pstm);
RELEASE(pdisp);
RELEASE(ppersstm);
return CreateErrorHelper(hresult, m_ObjectType);
}
#endif // 0
//=--------------------------------------------------------------------------=
// CMSMQMessage::GetStoredObject
//=--------------------------------------------------------------------------=
// Produce stored object from binary message body
//
// Parameters:
// pvarBody - [out] pointer to object
//
// Output:
//
// Notes:
// Object must implement IPersistStorage
//
#if 0 // not yet implemented
HRESULT CMSMQMessage::GetStoredObject(VARIANT FAR* pvarBody)
{
IUnknown *punk = NULL;
IDispatch *pdisp = NULL;
IStorage *pstg = NULL;
IPersistStorage *ppersstg = NULL;
HRESULT hresult = NOERROR;
#if DEBUG
LPOLESTR pwszGuid;
#endif // DEBUG
ASSERT(pvarBody, L"bad variant.");
VariantClear(pvarBody);
// Attempt to load from an in-memory storage
if (m_hMem) {
ASSERT(m_hMem == GlobalHandle(m_pbBody), L"bad handle.");
//
// try to load as a storage
//
IfFailGo(GetStorageOfBody(m_cbBody, m_pbBody, &pstg));
#if 0
//
// UNDONE: for some reason this doesn't work -- i.e. the returned
// object doesn't support IDispatch...
//
IfFailGo(OleLoad(pstg,
IID_IPersistStorage,
NULL, //Points to the client site for the object
(void **)&ppersstg));
#else
CLSID clsid;
IfFailGo(ReadClassStg(pstg, &clsid))
IfFailGo(CoCreateInstance(
clsid,
NULL,
CLSCTX_SERVER,
IID_IPersistStorage,
(LPVOID *)&ppersstg));
IfFailGo(ppersstg->Load(pstg));
#endif // 0
#if DEBUG
// get clsid
STATSTG statstg;
IfFailGo(pstg->Stat(&statstg, STATFLAG_NONAME));
StringFromCLSID(statstg.clsid, &pwszGuid);
#endif // DEBUG
#if 0
//
// Now setup returned object
//
V_VT(pvarBody) = VT_DISPATCH;
pvarBody->pdispVal = pdisp;
ADDREF(pvarBody->pdispVal); // ownership transfers
#else
//
// Supports IDispatch? if not, return IUnknown
//
IfFailGo(ppersstg->QueryInterface(IID_IUnknown,
(LPVOID *)&punk));
hresult = punk->QueryInterface(IID_IDispatch,
(LPVOID *)&pdisp);
if (SUCCEEDED(hresult)) {
//
// Setup returned object
//
V_VT(pvarBody) = VT_DISPATCH;
pvarBody->pdispVal = pdisp;
ADDREF(pvarBody->pdispVal); // ownership transfers
}
else {
//
// return IUnknown interface
//
V_VT(pvarBody) = VT_UNKNOWN;
pvarBody->punkVal = punk;
ADDREF(pvarBody->punkVal); // ownership transfers
}
#endif // 0
}
else {
V_VT(pvarBody) = VT_ERROR;
}
// fall through...
Error:
RELEASE(punk);
RELEASE(pstg);
RELEASE(ppersstg);
RELEASE(pdisp);
return CreateErrorHelper(hresult, m_ObjectTyp
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -