Leaked source code of windows server 2003
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
//-----------------------------------------------------------------------------
//
//
// File: localq.cpp
//
// Description: Implementation for local admin queues
//
// Author: Mike Swafford (MikeSwa)
//
// History:
// 2/23/99 - MikeSwa Created
//
// Copyright (C) 1999 Microsoft Corporation
//
//-----------------------------------------------------------------------------
#include "aqprecmp.h"
#include "localq.h"
#include "aqadmsvr.h"
#include "asyncq.inl"
//---[ CLocalLinkMsgQueue::CLocalLinkMsgQueue ]---------------------------------
//
//
// Description:
// Default constructor for CLocalLinkMsgQueue
// Parameters:
// IN paradmq Local async queue
// IN guidLink Router GUID to associate with this link
// IN paqinst CAQSvrInst for VSI
// Returns:
// -
// History:
// 2/23/99 - MikeSwa Created
//
//-----------------------------------------------------------------------------
CLocalLinkMsgQueue::CLocalLinkMsgQueue( CAsyncAdminMsgRefQueue *paradmq, GUID guidLink, CAQSvrInst *paqinst) : CLinkMsgQueue(guidLink) { TraceFunctEnterEx((LPARAM) this, "CLocalLinkMsgQueue::CLocalLinkMsgQueue"); //Initialize superclass with our own special GUID
_ASSERT(paradmq); m_paradmq = paradmq;
m_dwLocalLinkSig = LOCAL_LINK_MSG_QUEUE_SIG;
m_AQNotify.Init(paqinst, (CLinkMsgQueue *) this); m_paradmq->SetAQNotify(&m_AQNotify);
TraceFunctLeave(); }
#ifdef NEVER
//---[ CLinkMsgQueue::fSameNextHop ]-------------------------------------------
//
//
// Description:
// Used to determine if this link matches a given scheduleID/link pair
// Parameters:
// IN paqsched ScheduleID to check against
// IN szDomain Domain name to check against
// Returns:
// TRUE if it matches
// FALSE if it does not
// History:
// 2/23/99 - MikeSwa Created
//
//-----------------------------------------------------------------------------
BOOL CLocalLinkMsgQueue::fSameNextHop(CAQScheduleID *paqsched, LPSTR szDomain) { TraceFunctEnterEx((LPARAM) this, "CLocalLinkMsgQueue::fSameNextHop"); _ASSERT(paqsched);
if (!paqsched) return FALSE;
if (!fIsSameScheduleID(paqsched)) return FALSE;
//Don't need to check domain name since there is a special GUID to
//identify the local link. This will allow us to match both
//"LocalLink" (returned in LinkID) and whatever the current value of
//the default domain is (we don't have to worry about the clients
//version becoming outdated).
//Everything matched!
TraceFunctLeave(); return TRUE; } #endif //NEVER
//---[ CLocalLinkMsgQueue::fMatchesID ]--------------------------------------
//
//
// Description:
// Used to determine if this link matches a given scheduleID/link pair
// Parameters:
// IN QueueLinkID ID to match against
// Returns:
// TRUE if it matches
// FALSE if it does not
// History:
// 2/23/99 - MikeSwa Created
//
//-----------------------------------------------------------------------------
BOOL STDMETHODCALLTYPE CLocalLinkMsgQueue::fMatchesID(QUEUELINK_ID *pQueueLinkID) { _ASSERT(pQueueLinkID);
CAQScheduleID aqsched(pQueueLinkID->uuid, pQueueLinkID->dwId);
if (!fIsSameScheduleID(&aqsched)) return FALSE;
//Don't need to check domain name since there is a special GUID to
//identify the local link. This will allow us to match both
//"LocalLink" (returned in LinkID) and whatever the current value of
//the default domain is (we don't have to worry about the clients
//version becoming outdated).
//Everything matched!
return TRUE; }
//---[ CLocalLinkMsgQueue::HrApplyQueueAdminFunction ]-------------------------
//
//
// Description:
// Used by queue admin to apply a function all queues on this link
// Parameters:
// IN pIQueueAdminMessageFilter
// Returns:
// S_OK on success
// History:
// 2/23/99 - MikeSwa Created
//
//-----------------------------------------------------------------------------
STDMETHODIMP CLocalLinkMsgQueue::HrApplyQueueAdminFunction( IQueueAdminMessageFilter *pIQueueAdminMessageFilter) { TraceFunctEnterEx((LPARAM) this, "CLocalLinkMsgQueue::HrApplyQueueAdminFunction"); HRESULT hr = S_OK;
hr = CLinkMsgQueue::HrApplyQueueAdminFunction(pIQueueAdminMessageFilter);
if (FAILED(hr)) goto Exit;
_ASSERT(m_paradmq); hr = m_paradmq->HrApplyQueueAdminFunction(pIQueueAdminMessageFilter); if (FAILED(hr)) goto Exit;
Exit:
TraceFunctLeave(); return hr; }
//---[ CLocalLinkMsgQueue::HrGetLinkInfo ]-------------------------------------
//
//
// Description:
// Fills in the details for a LINK_INFO struct. RPC is resonsible for
// freeing memory.
// Parameters:
// IN OUT pliLinkInfo Ptr to link info struct to fill
// Returns:
// S_OK if successful
// E_OUTOFMEMORY if unable to allocate memory
// History:
// 2/23/99 - MikeSwa Created
// 7/1/99 - MikeSwa Added LinkDiagnostic
//
//-----------------------------------------------------------------------------
STDMETHODIMP CLocalLinkMsgQueue::HrGetLinkInfo(LINK_INFO *pliLinkInfo, HRESULT *phrLinkDiagnostic) { TraceFunctEnterEx((LPARAM) this, "CLocalLinkMsgQueue::HrApplyQueueAdminFunction"); HRESULT hr = S_OK; CRefCountedString *prstrDefaultDomain = NULL; hr = CLinkMsgQueue::HrGetLinkInfo(pliLinkInfo, phrLinkDiagnostic); QUEUE_INFO qi; FILETIME *pft = NULL;
_ASSERT(m_paradmq);
//
// Get our queue state from our base asyncq implementation
//
pliLinkInfo->fStateFlags = m_paradmq->dwQueueAdminLinkGetLinkState();
//
// If we are in retry, update our next scheduled connection
//
if (LI_RETRY & pliLinkInfo->fStateFlags) QueueAdminFileTimeToSystemTime(&m_ftNextRetry, &(pliLinkInfo->stNextScheduledConnection));
//This is the local link
pliLinkInfo->fStateFlags |= LI_TYPE_LOCAL_DELIVERY;
if (m_paqinst) prstrDefaultDomain = m_paqinst->prstrGetDefaultDomain();
//Copy Default local domain name instead of "LocalLink"
if (prstrDefaultDomain && prstrDefaultDomain->cbStrlen() && prstrDefaultDomain->szStr()) { if (pliLinkInfo->szLinkName) { QueueAdminFree(pliLinkInfo->szLinkName); pliLinkInfo->szLinkName = NULL; }
pliLinkInfo->szLinkName = wszQueueAdminConvertToUnicode( prstrDefaultDomain->szStr(), prstrDefaultDomain->cbStrlen()); if (!pliLinkInfo->szLinkName) { hr = E_OUTOFMEMORY; goto Exit; }
pliLinkInfo->szLinkName[prstrDefaultDomain->cbStrlen()] = '\0'; }
//Get the queue info from the local queue for size totals
ZeroMemory(&qi, sizeof(QUEUE_INFO)); hr = m_paradmq->HrGetQueueInfo(&qi); if (FAILED(hr)) goto Exit;
//Clean up allocated stuff
if (qi.szQueueName) QueueAdminFree(qi.szQueueName);
if (qi.szLinkName) QueueAdminFree(qi.szLinkName);
Exit:
if (prstrDefaultDomain) prstrDefaultDomain->Release();
TraceFunctLeave(); return hr; }
//---[ CLocalLinkMsgQueue::HrApplyActionToLink ]-------------------------------
//
//
// Description:
// Applies the specified QueueAdmin action to this link
// Parameters:
// IN la Link action to apply
// Returns:
// S_OK on success
// E_INVALIDARG if bogus action is given
// History:
// 2/23/99 - MikeSwa Created
//
//-----------------------------------------------------------------------------
STDMETHODIMP CLocalLinkMsgQueue::HrApplyActionToLink(LINK_ACTION la) { TraceFunctEnterEx((LPARAM) this, "CLocalLinkMsgQueue::HrApplyQueueAdminFunction"); HRESULT hr = S_OK;
//It is important to release that it does not make sense to re-apply these
//actions back to the LMQ, becuase it is actually the CAsyncRetryQueue
//that affects the state of this.
_ASSERT(m_paradmq);
if (LA_KICK == la) { //kick the link
m_paradmq->StartRetry(); } else if (LA_FREEZE == la) { //Admin wants this link to stop sending mail inbound to the store
m_paradmq->FreezeQueue(); } else if (LA_THAW == la) { //Thaw that which was previously frozen
m_paradmq->ThawQueue(); } else { //invalid arg
hr = E_INVALIDARG; goto Exit; }
Exit:
TraceFunctLeave(); return hr; }
//---[ CLocalLinkMsgQueue::HrGetNumQueues ]------------------------------------
//
//
// Description:
// Returns the number of queues on this link
// Parameters:
// OUT pcQueues # numbr of queues
// Returns:
// S_OK on success
// E_POINTER if pcQueues is not valid
// History:
// 2/23/99 - MikeSwa Created
//
//-----------------------------------------------------------------------------
STDMETHODIMP CLocalLinkMsgQueue::HrGetNumQueues(DWORD *pcQueues) { TraceFunctEnterEx((LPARAM) this, "CLocalLinkMsgQueue::HrApplyQueueAdminFunction"); HRESULT hr = S_OK; hr = CLinkMsgQueue::HrGetNumQueues(pcQueues); if (SUCCEEDED(hr)) { _ASSERT(pcQueues); (*pcQueues)++; //Add extra count for local async queue
}
TraceFunctLeave(); return hr; }
//---[ CLinkMsgQueue::HrGetQueueIDs ]--------------------------------------------
//
//
// Description:
// Gets the Queue IDs for DMQs associated with this link. Used by Queue
// Admin.
// Parameters:
// IN OUT pcQueues Sizeof array/ number of queues found
// IN OUT rgQueues Array to dump queue info into
// Returns:
// S_OK on success
// E_OUTOFMEMORY on out of memory failure
// HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) if array is too small
// History:
// 2/23/99 - MikeSwa Created
//
//-----------------------------------------------------------------------------
STDMETHODIMP CLocalLinkMsgQueue::HrGetQueueIDs( DWORD *pcQueues, QUEUELINK_ID *rgQueues) { TraceFunctEnterEx((LPARAM) this, "CLocalLinkMsgQueue::HrApplyQueueAdminFunction"); _ASSERT(pcQueues); _ASSERT(rgQueues); HRESULT hr = S_OK; //Check to make sure we have room for the additional queue ID
if (*pcQueues < (m_cQueues+1)) { hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); goto Exit; }
//Make sure that thread-safe check in CLinkMsgQueue allows room
//for our local queue.
(*pcQueues)--;
hr = CLinkMsgQueue::HrGetQueueIDs(pcQueues, rgQueues); if (FAILED(hr)) { //Tell caller we need room for our queue as well
if (HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) == hr) (*pcQueues)++;
goto Exit; }
hr = m_paradmq->HrGetQueueID(&rgQueues[*pcQueues]); if (FAILED(hr)) goto Exit;
(*pcQueues)++; Exit:
TraceFunctLeave(); return hr; }
|