583 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			583 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
//-----------------------------------------------------------------------------
 | 
						|
//
 | 
						|
//
 | 
						|
//  File: ConnSched.cpp
 | 
						|
//
 | 
						|
//  Description:  Implementation of CConnScheduler class, which provides a stub
 | 
						|
//      implementation of IConnectionScheduler for aqueue.dll.
 | 
						|
//
 | 
						|
//  Author: mikeswa
 | 
						|
//
 | 
						|
//  Copyright (C) 1998 Microsoft Corporation
 | 
						|
//
 | 
						|
//-----------------------------------------------------------------------------
 | 
						|
 | 
						|
#include <windows.h>
 | 
						|
#include <transmem.h>
 | 
						|
#include "consched.h"
 | 
						|
#include "catmsgq.h"
 | 
						|
 | 
						|
#define DEFAULT_DOMAIN_LENGTH   256 //initial 
 | 
						|
#define ACTION_SIG 'ntcA'
 | 
						|
 | 
						|
//---[ eScheduleAction ]-------------------------------------------------------
 | 
						|
//
 | 
						|
//
 | 
						|
//  Description: Enum describing the possible actions that can happen
 | 
						|
//
 | 
						|
//  
 | 
						|
//-----------------------------------------------------------------------------
 | 
						|
typedef enum eScheduleAction
 | 
						|
{
 | 
						|
    SCHEDULE_ACTION_RETRY   = 0x000000001,
 | 
						|
    SCHEDULE_ACTION_ENABLE  = 0x000000002,
 | 
						|
    SCHEDULE_ACTION_DISABLE = 0x000000003,
 | 
						|
};
 | 
						|
 | 
						|
eScheduleAction g_eScheduleAction = SCHEDULE_ACTION_RETRY; //encourage symbols
 | 
						|
 | 
						|
//---[ CScheduledAction ]------------------------------------------------------
 | 
						|
//
 | 
						|
//
 | 
						|
//  Hungarian: pSchedAct
 | 
						|
//
 | 
						|
//  Description: Class that represent a single queued action for the scheduler
 | 
						|
//
 | 
						|
//  
 | 
						|
//-----------------------------------------------------------------------------
 | 
						|
class CScheduledAction
 | 
						|
{
 | 
						|
public:
 | 
						|
    CScheduledAction(DWORD dwAction);
 | 
						|
    ~CScheduledAction();
 | 
						|
    HRESULT HrInit(DWORD cbDomain, LPSTR szDomain);
 | 
						|
    DWORD   m_dwSig;    //signature used when to make verify dequeued object
 | 
						|
    DWORD   m_dwAction; //Action to start
 | 
						|
    DWORD   m_cbDomain; //# bytes in domain name
 | 
						|
    LPSTR   m_szDomain; //domain name string
 | 
						|
    CHAR    m_szBuffer[DEFAULT_DOMAIN_LENGTH]; //default buffer to use
 | 
						|
};
 | 
						|
 | 
						|
//---[ CScheduledAction::CScheduledAction ]------------------------------------
 | 
						|
//
 | 
						|
//
 | 
						|
//  Description: 
 | 
						|
//      Class constructor for CScheduledAction
 | 
						|
//  Parameters:
 | 
						|
//      Action to create object for
 | 
						|
//  Returns:
 | 
						|
//      -
 | 
						|
//
 | 
						|
//-----------------------------------------------------------------------------
 | 
						|
inline CScheduledAction::CScheduledAction(DWORD dwAction)
 | 
						|
{
 | 
						|
    m_dwSig    = ACTION_SIG;
 | 
						|
    m_dwAction = dwAction;
 | 
						|
    m_cbDomain = 0;
 | 
						|
    m_szDomain = NULL;
 | 
						|
    m_szBuffer[0] = '\0';
 | 
						|
}
 | 
						|
 | 
						|
//---[ CScheduledAction::~CScheduledAction ]-----------------------------------
 | 
						|
//
 | 
						|
//
 | 
						|
//  Description: 
 | 
						|
//      Class destructor
 | 
						|
//  Parameters:
 | 
						|
//      -
 | 
						|
//  Returns:
 | 
						|
//      -
 | 
						|
//
 | 
						|
//-----------------------------------------------------------------------------
 | 
						|
inline CScheduledAction::~CScheduledAction()
 | 
						|
{
 | 
						|
    if (m_szDomain && (m_szDomain != m_szBuffer))
 | 
						|
    {
 | 
						|
        _ASSERT( m_cbDomain >= DEFAULT_DOMAIN_LENGTH);
 | 
						|
        FreePv(m_szDomain);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
//---[ CScheduledAction::HrInit ]----------------------------------------------
 | 
						|
//
 | 
						|
//
 | 
						|
//  Description: 
 | 
						|
//      Initializes a CScheduleAction object... will allocate a buffer for the
 | 
						|
//      string name if neccessary
 | 
						|
//  Parameters:
 | 
						|
//      cbDomain    # bytes in domain name
 | 
						|
//      szDomain    Domain Name string
 | 
						|
//  Returns:
 | 
						|
//      -
 | 
						|
//
 | 
						|
//-----------------------------------------------------------------------------
 | 
						|
HRESULT inline CScheduledAction::HrInit(DWORD cbDomain, LPSTR szDomain)
 | 
						|
{
 | 
						|
    HRESULT hr = S_OK;
 | 
						|
    if (cbDomain >= DEFAULT_DOMAIN_LENGTH)
 | 
						|
    {
 | 
						|
        m_szDomain = (LPSTR) pvMalloc(cbDomain+sizeof(CHAR));
 | 
						|
        if (!m_szDomain)
 | 
						|
        {
 | 
						|
            hr = E_OUTOFMEMORY;
 | 
						|
            goto Exit;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        m_szDomain = m_szBuffer;
 | 
						|
    }
 | 
						|
 | 
						|
    m_cbDomain = cbDomain;
 | 
						|
    memcpy(m_szDomain, szDomain, cbDomain+sizeof(CHAR));
 | 
						|
 | 
						|
  Exit:
 | 
						|
    return hr;
 | 
						|
}
 | 
						|
 | 
						|
//---[ SCHED_THREAD_PARAM ]----------------------------------------------------
 | 
						|
//
 | 
						|
//
 | 
						|
//  Description: Struct used to pass thread parameters to threads created to
 | 
						|
//      handle scheduled actions/
 | 
						|
//
 | 
						|
//  
 | 
						|
//-----------------------------------------------------------------------------
 | 
						|
typedef struct _SCHED_THREAD_PARAM
 | 
						|
{
 | 
						|
    CScheduledAction *pSchedAct;    //scheduled action
 | 
						|
    CConnScheduler *pConnSched;     //object that can process action
 | 
						|
    DWORD           dwDelay;  //time to sleep before action
 | 
						|
} SCHED_THREAD_PARAM, *PSCHED_THREAD_PARAM;
 | 
						|
 | 
						|
 | 
						|
//---[ StartConnectionSchedulerThread ]----------------------------------------
 | 
						|
//
 | 
						|
//
 | 
						|
//  Description: 
 | 
						|
//      Function used to start a Connection Scheduler thread
 | 
						|
//  Parameters:
 | 
						|
//      lpThreadParam - actually a this pointer for a CMsgConversion Obj.
 | 
						|
//  Returns:
 | 
						|
//      HRESULT indicating success or failure.
 | 
						|
//
 | 
						|
//-----------------------------------------------------------------------------
 | 
						|
DWORD  WINAPI StartConnectionSchedulerThread(LPVOID lpThreadParam)
 | 
						|
{
 | 
						|
    HRESULT hr = S_OK;
 | 
						|
    bool    fCOMInit = false;
 | 
						|
    PSCHED_THREAD_PARAM pSchedThreadParam = (PSCHED_THREAD_PARAM) lpThreadParam;
 | 
						|
    CScheduledAction *pSchedAct = pSchedThreadParam->pSchedAct;
 | 
						|
    CConnScheduler   *pConnSched = pSchedThreadParam->pConnSched;
 | 
						|
 | 
						|
    _ASSERT(pSchedAct && pConnSched);
 | 
						|
 | 
						|
    hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
 | 
						|
    if (FAILED(hr))
 | 
						|
        goto Exit;
 | 
						|
 | 
						|
    fCOMInit = true;
 | 
						|
 | 
						|
    if (ACTION_SIG != pSchedAct->m_dwSig) 
 | 
						|
    {
 | 
						|
        hr = E_INVALIDARG;
 | 
						|
        goto Exit;
 | 
						|
    }
 | 
						|
 | 
						|
    hr = pConnSched->HrProcessAction(pSchedAct, pSchedThreadParam->dwDelay);
 | 
						|
    if (FAILED(hr))
 | 
						|
        goto Exit;
 | 
						|
 | 
						|
  Exit:
 | 
						|
 | 
						|
    if (pConnSched)
 | 
						|
        pConnSched->Release();
 | 
						|
 | 
						|
    if (pSchedThreadParam)
 | 
						|
        delete pSchedThreadParam;
 | 
						|
 | 
						|
    if (fCOMInit)
 | 
						|
        CoUninitialize();
 | 
						|
 | 
						|
    return ((DWORD) hr);
 | 
						|
}
 | 
						|
 | 
						|
//---[ CConnScheduler::CConnScheduler ]----------------------------------------
 | 
						|
//
 | 
						|
//
 | 
						|
//  Description: 
 | 
						|
//      Class constructor for CConnScheduler
 | 
						|
//  Parameters:
 | 
						|
//      -
 | 
						|
//  Returns:
 | 
						|
//      -
 | 
						|
//
 | 
						|
//-----------------------------------------------------------------------------
 | 
						|
CConnScheduler::CConnScheduler(CCatMsgQueue *pcmq, IScheduleManager *pISchedMgr)
 | 
						|
{
 | 
						|
    _ASSERT(pcmq);
 | 
						|
    _ASSERT(pISchedMgr);
 | 
						|
 | 
						|
    m_pcmq = pcmq;
 | 
						|
    m_pISchedMgr = pISchedMgr;
 | 
						|
 | 
						|
    m_pcmq->AddRef();
 | 
						|
    m_pISchedMgr->AddRef();
 | 
						|
 | 
						|
    m_hShutdown = NULL;
 | 
						|
}
 | 
						|
 | 
						|
//---[ CConnScheduler::~CConnScheduler ]---------------------------------------
 | 
						|
//
 | 
						|
//
 | 
						|
//  Description: 
 | 
						|
//      Class destructor for CConnScheduler
 | 
						|
//  Parameters:
 | 
						|
//
 | 
						|
//  Returns:
 | 
						|
//
 | 
						|
//
 | 
						|
//-----------------------------------------------------------------------------
 | 
						|
CConnScheduler::~CConnScheduler()
 | 
						|
{
 | 
						|
    if (m_pcmq)
 | 
						|
        m_pcmq->Release();
 | 
						|
 | 
						|
    if (m_pISchedMgr)
 | 
						|
        m_pISchedMgr->Release();
 | 
						|
 | 
						|
    if (m_hShutdown)
 | 
						|
    {
 | 
						|
        CloseHandle(m_hShutdown);
 | 
						|
    }
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
//---[ CConnScheduler::HrInit ]------------------------------------------------
 | 
						|
//
 | 
						|
//
 | 
						|
//  Description: 
 | 
						|
//      
 | 
						|
//  Parameters:
 | 
						|
//      -
 | 
						|
//  Returns:
 | 
						|
//      -
 | 
						|
//
 | 
						|
//-----------------------------------------------------------------------------
 | 
						|
HRESULT CConnScheduler::HrInit()
 | 
						|
{
 | 
						|
    HRESULT hr = S_OK;
 | 
						|
 | 
						|
    hr = HrInitSyncShutdown();
 | 
						|
 | 
						|
    m_hShutdown = CreateEvent(NULL, TRUE, FALSE, NULL);
 | 
						|
    if (!m_hShutdown)
 | 
						|
    {
 | 
						|
        hr = HRESULT_FROM_WIN32(GetLastError());
 | 
						|
        goto Exit;
 | 
						|
    }
 | 
						|
 | 
						|
  Exit:
 | 
						|
    return hr;
 | 
						|
}
 | 
						|
 | 
						|
//---[ CConnScheduler::HrDeinit ]----------------------------------------------
 | 
						|
//
 | 
						|
//
 | 
						|
//  Description: 
 | 
						|
//      Signals an orderly shutdown
 | 
						|
//  Parameters:
 | 
						|
//      -
 | 
						|
//  Returns:
 | 
						|
//      -
 | 
						|
//
 | 
						|
//-----------------------------------------------------------------------------
 | 
						|
HRESULT CConnScheduler::HrDeinit()
 | 
						|
{
 | 
						|
    HRESULT hr = S_OK;
 | 
						|
 | 
						|
    if (!SetEvent(m_hShutdown))
 | 
						|
    {
 | 
						|
        hr = HRESULT_FROM_WIN32(GetLastError());
 | 
						|
        goto Exit;
 | 
						|
    }
 | 
						|
 | 
						|
    SignalShutdown();
 | 
						|
 | 
						|
    if (m_pcmq)
 | 
						|
    {
 | 
						|
        m_pcmq->Release();
 | 
						|
        m_pcmq = NULL;
 | 
						|
    }
 | 
						|
 | 
						|
    if (m_pISchedMgr)
 | 
						|
    {
 | 
						|
        m_pISchedMgr->Release();
 | 
						|
        m_pISchedMgr = NULL;
 | 
						|
    }
 | 
						|
 | 
						|
    Sleep(1000); //given retry threads a chance to shutdown.
 | 
						|
  Exit:
 | 
						|
    return hr;
 | 
						|
}
 | 
						|
 | 
						|
//---[ CConnScheduler::HrProcessAction ]--------------------------------------
 | 
						|
//
 | 
						|
//
 | 
						|
//  Description: 
 | 
						|
//      Processes a single schedule action
 | 
						|
//  Parameters:
 | 
						|
//      pSchedAct           object that encapsulates scheduled action
 | 
						|
//      cDelayMilliseconds  Time in millseconds to delay processing of action
 | 
						|
//  Returns:
 | 
						|
//      S_OK on success
 | 
						|
//
 | 
						|
//-----------------------------------------------------------------------------
 | 
						|
HRESULT CConnScheduler::HrProcessAction(CScheduledAction *pSchedAct, 
 | 
						|
                                        DWORD dwDelayMilliseconds)
 | 
						|
{
 | 
						|
    HRESULT hr = S_OK;
 | 
						|
    DWORD   dwWaitResult = 0;
 | 
						|
    BOOL    fLocked = FALSE;
 | 
						|
    _ASSERT(m_pISchedMgr);
 | 
						|
    _ASSERT(m_hShutdown);
 | 
						|
    _ASSERT(pSchedAct);
 | 
						|
    _ASSERT(pSchedAct->m_szDomain);
 | 
						|
    _ASSERT(pSchedAct->m_cbDomain);
 | 
						|
 | 
						|
    hr = HrLock();
 | 
						|
    if (FAILED(hr))
 | 
						|
        goto Exit;
 | 
						|
 | 
						|
    fLocked = TRUE;
 | 
						|
 | 
						|
    dwWaitResult = WaitForSingleObject(m_hShutdown, dwDelayMilliseconds);
 | 
						|
    if (WAIT_OBJECT_0 == dwWaitResult) //shutdown
 | 
						|
    {
 | 
						|
        hr = AQUEUE_E_SHUTDOWN;
 | 
						|
        goto Exit;
 | 
						|
    }
 | 
						|
 | 
						|
    _ASSERT(WAIT_TIMEOUT == dwWaitResult);
 | 
						|
 | 
						|
    if (pSchedAct->m_dwAction & SCHEDULE_ACTION_RETRY)
 | 
						|
    {
 | 
						|
        hr = m_pISchedMgr->EnableOutboundConnections(pSchedAct->m_cbDomain, 
 | 
						|
                        pSchedAct->m_szDomain, 0);
 | 
						|
        if (FAILED(hr))
 | 
						|
            goto Exit;
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        _ASSERT(0 || "Invalid Arg");
 | 
						|
    }
 | 
						|
 | 
						|
  Exit:
 | 
						|
    if (fLocked)
 | 
						|
        HrUnlock();
 | 
						|
 | 
						|
    return hr;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
//---[ CConnScheduler::QueryInterface ]----------------------------------------
 | 
						|
//
 | 
						|
//
 | 
						|
//  Description: 
 | 
						|
//      QueryInterface for IConnectionScheduler
 | 
						|
//  Parameters:
 | 
						|
//
 | 
						|
//  Returns:
 | 
						|
//      S_OK on success
 | 
						|
//
 | 
						|
//
 | 
						|
//-----------------------------------------------------------------------------
 | 
						|
STDMETHODIMP CConnScheduler::QueryInterface(REFIID riid, LPVOID * ppvObj)
 | 
						|
{
 | 
						|
    HRESULT hr = S_OK;
 | 
						|
 | 
						|
    if (!ppvObj)
 | 
						|
    {
 | 
						|
        hr = E_INVALIDARG;
 | 
						|
        goto Exit;
 | 
						|
    }
 | 
						|
 | 
						|
    if (IID_IUnknown == riid)
 | 
						|
    {
 | 
						|
        *ppvObj = static_cast<IConnectionScheduler *>(this);
 | 
						|
    }
 | 
						|
    else if (IID_IConnectionScheduler == riid)
 | 
						|
    {
 | 
						|
        *ppvObj = static_cast<IConnectionScheduler *>(this);
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        *ppvObj = NULL;
 | 
						|
        hr = E_NOINTERFACE;
 | 
						|
        goto Exit;
 | 
						|
    }
 | 
						|
 | 
						|
    static_cast<IUnknown *>(*ppvObj)->AddRef();
 | 
						|
 | 
						|
  Exit:
 | 
						|
    return hr;
 | 
						|
}
 | 
						|
 | 
						|
//---[ CConnScheduler::ConnectionReleased ]------------------------------------
 | 
						|
//
 | 
						|
//
 | 
						|
//  Description: 
 | 
						|
//      Implements IConnectionScheduler::ConnectionRelease().  Called when 
 | 
						|
//      SMTP releases a connection and is used to handle retry logic
 | 
						|
//  Parameters:
 | 
						|
//      IN  cbDomainName    String length of domain name
 | 
						|
//      IN  szDomainName    Domain name of connection that was released
 | 
						|
//      IN  dwScheduleID    Schedule ID of this connection
 | 
						|
//      IN  cFailedMessages Number of messages that were attempted and failed
 | 
						|
//                          by the particular connection instance being released
 | 
						|
//      IN  cUntiredMessages The number of messages that have not been attempted
 | 
						|
//                          For this <domain, schedule>
 | 
						|
//      IN  cOutstandingConnections  The number of other outstanding connections
 | 
						|
//                          for this <domain, schedule>
 | 
						|
//      OUT pfAllowImmediateRetry  Should we allow any further connections to 
 | 
						|
//                          be created for this <domain, schedule>
 | 
						|
//  Returns:
 | 
						|
//      S_OK on success
 | 
						|
//
 | 
						|
//  REVIEW:
 | 
						|
//      Will we really want to expose this functionality externally?  It might
 | 
						|
//      make sense to have another internal object that makes calls to ISMTP
 | 
						|
//-----------------------------------------------------------------------------
 | 
						|
STDMETHODIMP CConnScheduler::ConnectionReleased(
 | 
						|
   					IN  DWORD cbDomainName,
 | 
						|
					IN  char szDomainName[],
 | 
						|
					IN  DWORD dwScheduleID,
 | 
						|
					IN  DWORD dwConnectionStatus,		//eConnectionStatus
 | 
						|
					IN  DWORD cFailedMessages,		//# of failed message for *this* connection
 | 
						|
					IN  DWORD cUntriedMessages,		//# of untried messages in queue
 | 
						|
					IN  DWORD cOutstandingConnections,//# of other active connections for this domain
 | 
						|
					OUT BOOL *pfAllowImmediateRetry)
 | 
						|
{
 | 
						|
    TraceFunctEnterEx((LPARAM) this, "CConnScheduler::ConnectionReleased");
 | 
						|
    HRESULT hr = S_OK;
 | 
						|
    CScheduledAction *pSchedAct = NULL;
 | 
						|
    PSCHED_THREAD_PARAM pThreadParam = NULL;
 | 
						|
    HANDLE  hThread = NULL;
 | 
						|
    DWORD   dwThreadID = 0;
 | 
						|
    BOOL    fLocked = FALSE;
 | 
						|
 | 
						|
 | 
						|
    _ASSERT(pfAllowImmediateRetry);
 | 
						|
 | 
						|
    hr = HrLock();
 | 
						|
    if (FAILED(hr))
 | 
						|
        goto Exit;
 | 
						|
 | 
						|
    fLocked = TRUE;
 | 
						|
        
 | 
						|
    if (!cFailedMessages && (CONNECTION_STATUS_OK == dwConnectionStatus))
 | 
						|
    {
 | 
						|
        *pfAllowImmediateRetry = TRUE;
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        DebugTrace((LPARAM) dwConnectionStatus, "INFO: Remote Domain %s scheduled for retry", szDomainName);
 | 
						|
        pSchedAct = new CScheduledAction(SCHEDULE_ACTION_RETRY);
 | 
						|
        hr = pSchedAct->HrInit(cbDomainName, szDomainName);
 | 
						|
        if (FAILED(hr))
 | 
						|
            goto Exit;
 | 
						|
 | 
						|
        pThreadParam = (PSCHED_THREAD_PARAM) pvMalloc(sizeof(SCHED_THREAD_PARAM));
 | 
						|
        if (!pThreadParam)
 | 
						|
        {
 | 
						|
            hr = E_OUTOFMEMORY;
 | 
						|
            goto Exit;
 | 
						|
        }
 | 
						|
 | 
						|
        pThreadParam->pSchedAct = pSchedAct;
 | 
						|
        pThreadParam->pConnSched = this;
 | 
						|
        if (FAILED(m_pcmq->HrGetConnectionRetry(&(pThreadParam->dwDelay))))
 | 
						|
        {
 | 
						|
            pThreadParam->dwDelay = 60000;
 | 
						|
        }
 | 
						|
 | 
						|
        AddRef();
 | 
						|
 | 
						|
        hThread = CreateThread(
 | 
						|
                    NULL,
 | 
						|
                    0,
 | 
						|
                    StartConnectionSchedulerThread,
 | 
						|
                    (LPVOID) pThreadParam,
 | 
						|
                    0,
 | 
						|
                    &dwThreadID);
 | 
						|
 | 
						|
        if (NULL == hThread)
 | 
						|
        {
 | 
						|
            hr = HRESULT_FROM_WIN32(GetLastError());
 | 
						|
            goto Exit;
 | 
						|
        }
 | 
						|
 | 
						|
        if (!CloseHandle(hThread))
 | 
						|
        {
 | 
						|
            hr = HRESULT_FROM_WIN32(GetLastError());
 | 
						|
            goto Exit;
 | 
						|
        }
 | 
						|
        hThread = NULL;
 | 
						|
 | 
						|
        pThreadParam = NULL;
 | 
						|
        pSchedAct = NULL;
 | 
						|
        *pfAllowImmediateRetry = FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
  Exit:
 | 
						|
    if (pSchedAct)
 | 
						|
        delete pSchedAct;
 | 
						|
 | 
						|
    if (pThreadParam)
 | 
						|
    {
 | 
						|
        Release();
 | 
						|
        FreePv(pThreadParam);
 | 
						|
    }
 | 
						|
 | 
						|
    if (fLocked)
 | 
						|
        HrUnlock();
 | 
						|
 | 
						|
    TraceFunctLeave();
 | 
						|
    return hr;
 | 
						|
}
 | 
						|
 | 
						|
//---[ CConnScheduler::NewRemoteDomain ]---------------------------------------
 | 
						|
//
 | 
						|
//
 | 
						|
//  Description: 
 | 
						|
//      Implements IConnectionScheduler::NewRemoteDomain().  For MM1, this is 
 | 
						|
//      just a stub implementation with no actual scheduling happening (all
 | 
						|
//      domains are approved for immediate connections.
 | 
						|
//  Parameters:
 | 
						|
//      IN  cbDomainName    String length of domain name
 | 
						|
//      IN  szDomainName    Domain name of next hop link that was created
 | 
						|
//      IN  dwScheduleID    Schedule ID of this connection
 | 
						|
//      OUT pfAllowImmediateConnection Should we allow any further connections to 
 | 
						|
//                          be created for this <domain, schedule> befote
 | 
						|
//                          IScheduleManager::EnableOutboundConnections is called.
 | 
						|
//  Returns:
 | 
						|
//      S_OK on success
 | 
						|
//
 | 
						|
//-----------------------------------------------------------------------------
 | 
						|
STDMETHODIMP CConnScheduler::NewRemoteDomain(
 | 
						|
					IN  DWORD cbDomainName,
 | 
						|
					IN  char szDomainName[],
 | 
						|
					IN  DWORD dwScheduleID,
 | 
						|
					OUT BOOL *pfAllowImmediateConnection)
 | 
						|
{
 | 
						|
    HRESULT hr = S_OK;
 | 
						|
    _ASSERT(pfAllowImmediateConnection);
 | 
						|
 | 
						|
    *pfAllowImmediateConnection = TRUE;
 | 
						|
 | 
						|
    return hr;
 | 
						|
}
 | 
						|
 | 
						|
 |