📄 qinfo.cpp
字号:
// Creates a new queue based on instance params (guidQueue etc.)
//
// Parameters:
// pvarTransactional [in, optional]
// isWorldReadable [in, optional]
//
// Output:
// HRESULT - S_OK, E_OUTOFMEMORY
//
// Notes:
//
HRESULT CMSMQQueueInfo::Create(
VARIANT *pvarTransactional,
VARIANT *pvarWorldReadable)
{
MQQUEUEPROPS queueprops;
ULONG uiFormatNameLen = FORMAT_NAME_INIT_BUFFER;
#if _DEBUG
ULONG uiFormatNameLenSave = uiFormatNameLen;
#endif // _DEBUG
BSTR bstrFormatName = NULL;
BOOL isTransactional, isWorldReadable;
#if 0 // no security
SECURITY_DESCRIPTOR sd;
SECURITY_DESCRIPTOR *psd;
#endif // 0
BYTE *pbBufDacl = NULL;
HRESULT hresult;
isTransactional = GetBool(pvarTransactional);
isWorldReadable = GetBool(pvarWorldReadable);
InitQueueProps(&queueprops);
IfFailGo(CreateQueueProps(TRUE,
8, // number of properties
&queueprops,
isTransactional,
PROPID_Q_TYPE,
PROPID_Q_LABEL,
PROPID_Q_PATHNAME,
PROPID_Q_JOURNAL,
PROPID_Q_QUOTA,
PROPID_Q_BASEPRIORITY,
PROPID_Q_AUTHENTICATE,
PROPID_Q_JOURNAL_QUOTA));
IfNullGo(bstrFormatName =
SysAllocStringLen(NULL, uiFormatNameLen));
#if 0 // no security
if (isWorldReadable) {
//
// construct a security descriptor for this queue
// that is world generic readable.
//
if (!GetWorldReadableSecurityDescriptor(&sd, &pbBufDacl)) {
IfFailGo(hresult = MQ_ERROR_ILLEGAL_SECURITY_DESCRIPTOR);
}
psd = &sd;
}
else {
//
// default Falcon security
//
psd = NULL;
}
#endif // 0
IfFailGo(MQCreateQueue(
NULL,
&queueprops,
bstrFormatName,
&uiFormatNameLen));
// FormatName mucking...
ASSERT(hresult != MQ_INFORMATION_FORMATNAME_BUFFER_TOO_SMALL,
L"Warning - insufficient format name buffer.");
#if _DEBUG
ASSERT(uiFormatNameLen <= uiFormatNameLenSave,
L"insufficient buffer.");
#endif
IfNullFail(SysReAllocString(&m_bstrFormatName, bstrFormatName));
//
// Note: we don't SetQueueProps or Refresh since for now
// MQCreateQueue is IN-only.
// need to update transactional field
//
EnterCriticalSection(&m_CSlocal);
m_isTransactional = isTransactional;
LeaveCriticalSection(&m_CSlocal);
Error:
delete [] pbBufDacl;
FreeQueueProps(&queueprops);
SysFreeString(bstrFormatName);
return CreateErrorHelper(hresult, m_ObjectType);
}
//=--------------------------------------------------------------------------=
// CMSMQQueueInfo::Delete
//=--------------------------------------------------------------------------=
// Deletes this queue
//
// Parameters:
//
// Output:
// HRESULT - S_OK, E_OUTOFMEMORY
//
// Notes:
//
HRESULT CMSMQQueueInfo::Delete()
{
HRESULT hresult = NOERROR;
//
// 2026: ensure we have a format name...
//
hresult = UpdateFormatName();
if (SUCCEEDED(hresult)) {
hresult = MQDeleteQueue(m_bstrFormatName);
}
return CreateErrorHelper(hresult, m_ObjectType);
}
//=--------------------------------------------------------------------------=
// CMSMQQueueInfo::Open
//=--------------------------------------------------------------------------=
// Opens this queue
//
// Parameters:
// lAccess IN
// lShareMode IN
// ppq OUT
//
// Output:
// HRESULT - S_OK, E_OUTOFMEMORY
//
// Notes:
//
HRESULT CMSMQQueueInfo::Open(long lAccess, long lShareMode, IMSMQQueue **ppq)
{
QUEUEHANDLE lHandle;
CMSMQQueue *pq = NULL;
HRESULT hresult;
// pessimism
*ppq = NULL;
if (lAccess != MQ_SEND_ACCESS &&
lAccess != MQ_RECEIVE_ACCESS &&
lAccess != MQ_PEEK_ACCESS) {
return CreateErrorHelper(E_INVALIDARG, m_ObjectType);
}
if (lShareMode != MQ_DENY_RECEIVE_SHARE &&
lShareMode != 0 /* MQ_DENY_NONE */) {
return CreateErrorHelper(E_INVALIDARG, m_ObjectType);
}
// ensure we have a format name...
IfFailGo(UpdateFormatName());
IfFailGo(MQOpenQueue(m_bstrFormatName,
lAccess,
lShareMode,
(QUEUEHANDLE *)&lHandle));
//
// 2536: only attempt to use the DS when
// the first prop is accessed... or Refresh
// is called explicitly.
//
#if 0
// We ignore errors since perhaps no DS...
hresult = Refresh();
#endif // 0
// Create MSMQQueue object and init with handle
IfNullFail((pq = new CMSMQQueue(NULL)));
IfFailGo(pq->Init(this, lHandle, lAccess, lShareMode));
*ppq = pq;
return NOERROR;
Error:
delete pq;
return CreateErrorHelper(hresult, m_ObjectType);
}
//=--------------------------------------------------------------------------=
// CMSMQQueueInfo::UpdateFormatName
//=--------------------------------------------------------------------------=
// Updates formatname member if necessary from pathname
//
// Parameters:
//
// Output:
// HRESULT - S_OK, E_OUTOFMEMORY
//
// Notes:
// sets m_bstrFormatName
//
HRESULT CMSMQQueueInfo::UpdateFormatName()
{
HRESULT hresult = NOERROR;
// error if no pathname nor formatname yet..
if ((m_bstrPathName == NULL) && (m_bstrFormatName == NULL)) {
return E_INVALIDARG;
}
//
// if no format name yet, synthesize from pathname
// 2026: check for formatname validity.
//
EnterCriticalSection(&m_CSlocal);
if (!m_isValidFormatName ||
(m_bstrFormatName == NULL) ||
SysStringLen(m_bstrFormatName) == 0) {
IfFailRet(GetFormatNameOfPathName(
m_bstrPathName,
&m_bstrFormatName));
m_isValidFormatName = TRUE;
};
LeaveCriticalSection(&m_CSlocal);
return hresult;
}
//=--------------------------------------------------------------------------=
// CMSMQQueueInfo::Refresh
//=--------------------------------------------------------------------------=
// Refreshes all queue properties from DS.
//
// Parameters:
//
// Output:
// HRESULT - S_OK, E_OUTOFMEMORY
//
// Notes:
//
HRESULT CMSMQQueueInfo::Refresh()
{
MQQUEUEPROPS queueprops;
HRESULT hresult = NOERROR;
InitQueueProps(&queueprops);
IfFailGo(UpdateFormatName());
IfFailGo(CreateQueueProps(
FALSE,
11,
&queueprops,
FALSE, // ignored
PROPID_Q_INSTANCE,
PROPID_Q_TYPE,
PROPID_Q_LABEL,
PROPID_Q_PATHNAME,
PROPID_Q_JOURNAL,
PROPID_Q_QUOTA,
PROPID_Q_BASEPRIORITY,
// PROPID_Q_PRIV_LEVEL,
PROPID_Q_AUTHENTICATE,
// PROPID_Q_TRANSACTION,
PROPID_Q_CREATE_TIME,
PROPID_Q_MODIFY_TIME,
PROPID_Q_JOURNAL_QUOTA
));
if (!IsDirectQueueOfFormatName(m_bstrFormatName)) {
IfFailGo(MQGetQueueProperties(m_bstrFormatName, &queueprops));
IfFailGoTo(SetQueueProps(&queueprops), Error2);
}else
{
// fall "around"...since falcon didn't touch this memory...
goto Error;
}
Error2:
FreeFalconBuffers(&queueprops);
// fall through...
Error:
FreeQueueProps(&queueprops);
return CreateErrorHelper(hresult, m_ObjectType);
}
//=--------------------------------------------------------------------------=
// CMSMQQueueInfo::Update
//=--------------------------------------------------------------------------=
// Updates queue properties in DS from ActiveX object.
//
// Parameters:
//
// Output:
// HRESULT - S_OK, E_OUTOFMEMORY
//
// Notes:
//
HRESULT CMSMQQueueInfo::Update()
{
MQQUEUEPROPS queueprops;
HRESULT hresult;
//
// CONSIDER: NOP if no props have changed since last Refresh.
// Better yet do this on a per-prop basis.
//
InitQueueProps(&queueprops);
IfFailGo(UpdateFormatName());
if (IsPrivateQueueOfFormatName(m_bstrFormatName)) {
IfFailGo(CreateQueueProps(
TRUE,
5,
&queueprops,
m_isTransactional,
PROPID_Q_TYPE,
PROPID_Q_LABEL,
// PROPID_Q_JOURNAL,
PROPID_Q_QUOTA,
// PROPID_Q_BASEPRIORITY,
PROPID_Q_PRIV_LEVEL,
// PROPID_Q_JOURNAL_QUOTA,
PROPID_Q_AUTHENTICATE
));
}
else {
IfFailGo(CreateQueueProps(
TRUE,
7,
&queueprops,
m_isTransactional,
PROPID_Q_TYPE,
PROPID_Q_LABEL,
PROPID_Q_JOURNAL,
PROPID_Q_QUOTA,
PROPID_Q_BASEPRIORITY,
// PROPID_Q_PRIV_LEVEL,
PROPID_Q_AUTHENTICATE,
PROPID_Q_JOURNAL_QUOTA
));
}
IfFailGo(UpdateFormatName());
// 1042: DIRECT queues aren't ds'able
if (!IsDirectQueueOfFormatName(m_bstrFormatName)) {
IfFailGo(MQSetQueueProperties(m_bstrFormatName, &queueprops));
}
// fall through...
Error:
FreeQueueProps(&queueprops);
return CreateErrorHelper(hresult, m_ObjectType);
}
//=--------------------------------------------------------------------------=
// CMSMQQueueInfo::get_IsWorldReadable
//=--------------------------------------------------------------------------=
//
// Parameters:
// pisWorldReadable [out]
//
// Output:
//
// Notes:
// Can't world readable state since other users can
// change queue's state dynamically.
//
HRESULT CMSMQQueueInfo::get_IsWorldReadable(
VARIANT_BOOL *pisWorldReadable)
{
return E_NOTIMPL;
#if 0 // no security support
PSECURITY_DESCRIPTOR psd = NULL;
BYTE rgbBufSecurityDescriptor[256];
BYTE *rgbBufSecurityDescriptor2 = NULL;
DWORD cbBuf, cbBuf2;
BOOL bDaclExists;
PACL pDacl;
BOOL bDefDacl;
BOOL isWorldReadable = FALSE;
PSID psidWorld = NULL;
DWORD dwMaskGenericRead = MQSEC_QUEUE_GENERIC_READ;
HRESULT hresult;
// UNDONE: null format name? for now UpdateFormatName
IfFailGo(UpdateFormatName());
psd = (PSECURITY_DESCRIPTOR)rgbBufSecurityDescriptor;
hresult = MQGetQueueSecurity(
m_bstrFormatName,
DACL_SECURITY_INFORMATION,
psd,
sizeof(rgbBufSecurityDescriptor),
&cbBuf);
if (FAILED(hresult)) {
if (hresult != MQ_ERROR_SECURITY_DESCRIPTOR_TOO_SMALL) {
return hresult;
}
IfNullRet(rgbBufSecurityDescriptor2 = new BYTE[cbBuf]);
//
// retry with large enough buffer
//
psd = (PSECURITY_DESCRIPTOR)rgbBufSecurityDescriptor2;
IfFailGo(MQGetQueueSecurity(
m_bstrFormatName,
DACL_SECURITY_INFORMATION,
psd,
cbBuf,
&cbBuf2));
ASSERT(cbBuf >= cbBuf2, L"bad buffer sizes!");
}
ASSERT(psd, L"should have security descriptor!");
IfNullGo(GetSecurityDescriptorDacl(
psd,
&bDaclExists,
&pDacl,
&bDefDacl));
if (!bDaclExists || !pDacl) {
isWorldReadable = TRUE;
}
else {
//
// Get the ACL's size information.
//
ACL_SIZE_INFORMATION DaclSizeInfo;
IfNullGo(GetAclInformation(
pDacl,
&DaclSizeInfo,
sizeof(ACL_SIZE_INFORMATION),
AclSizeInformation));
//
// Traverse the ACEs looking for world ACEs
//
SID_IDENTIFIER_AUTHORITY WorldAuth = SECURITY_WORLD_SID_AUTHORITY;
IfNullGo(AllocateAndInitializeSid(
&WorldAuth,
1,
SECURITY_WORLD_RID,
0,
0,
0,
0,
0,
0,
0,
&psidWorld));
DWORD i;
BOOL fDone;
for (i = 0, fDone = FALSE;
i < DaclSizeInfo.AceCount && !fDone;
i++) {
LPVOID pAce;
//
// Retrieve the ACE
//
IfNullGo(GetAce(pDacl, i, &pAce));
ACCESS_ALLOWED_ACE *pAceStruct = (ACCESS_ALLOWED_ACE *)pAce;
if (!EqualSid((PSID)&pAceStruct->SidStart, psidWorld)) {
continue;
}
//
// we've found another world
//
switch (pAceStruct->Header.AceType) {
case ACCESS_ALLOWED_ACE_TYPE:
dwMaskGenericRead &= ~pAceStruct->Mask;
if (!dwMaskGenericRead) {
isWorldReadable = TRUE;
fDone = TRUE;
}
break;
case ACCESS_DENIED_ACE_TYPE:
if (pAceStruct->Mask | MQSEC_QUEUE_GENERIC_READ) {
isWorldReadable = FALSE;
fDone = TRUE;
}
break;
default:
continue;
} // switch
} // for
}
//
// setup return
//
*pisWorldReadable = isWorldReadable;
//
// fall through...
//
Error:
delete [] rgbBufSecurityDescriptor2;
if (psidWorld) {
FreeSid(psidWorld);
}
return CreateErrorHelper(hresult, m_ObjectType);
#endif // 0 no security support
}
//=--------------------------------------------------------------------------=
// InitProps
//=--------------------------------------------------------------------------=
// Init DS props if not already refreshed...
//
HRESULT CMSMQQueueInfo::InitProps()
{
HRESULT hresult = NOERROR;
EnterCriticalSection(&m_CSlocal);
if (!m_isRefreshed) {
hresult = Refresh(); // ignore DS errors...
if (SUCCEEDED(hresult)) {
m_isRefreshed = TRUE;
}
}
LeaveCriticalSection(&m_CSlocal);
return hresult;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -