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.
 
 
 
 
 
 

878 lines
20 KiB

/*++
Copyright (c) 1997 - 1999 Microsoft Corporation
Module Name:
queue.cpp
Abstract:
Implementation of the Queue object for TAPI 3.0.
CQueue class
Author:
noela - 11/04/97
Notes:
optional-notes
Revision History:
--*/
#include "stdafx.h"
/////////////////////////////////////////////////////////////////////////////
// CQueue
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class : CQueue
// Method : Constructor
//
//
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
CQueue::CQueue()
{
Lock();
m_dwHandle = 0;
m_bRequiresUpdating = TRUE;
m_dwMeasurementPeriod = 0;
m_dwTotalCallsQueued = 0;
m_dwCurrentCallsQueued = 0;
m_dwTotalCallsAdandoned = 0;
m_dwTotalCallsFlowedIn = 0;
m_dwTotalCallsFlowedOut = 0;
m_dwLongestEverWaitTime = 0;
m_dwCurrentLongestWaitTime = 0;
m_dwAverageWaitTime = 0;
m_dwFinalDisposition = 0;
Unlock();
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class : CQueue
// Method : UpdateInfo
//
//
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
STDMETHODIMP CQueue::UpdateInfo()
{
HRESULT hr = S_OK;
LINEQUEUEINFO QueueInfo;
LOG((TL_TRACE, "UpdateInfo - enter" ));
QueueInfo.dwTotalSize = sizeof(LINEQUEUEINFO);
QueueInfo.dwNeededSize = sizeof(LINEQUEUEINFO);
QueueInfo.dwUsedSize = sizeof(LINEQUEUEINFO);
// **************************************************
// Get Queue Info from Proxy
hr = lineGetQueueInfo(
m_pHandler->getHLine(),
m_dwHandle,
&QueueInfo);
if( SUCCEEDED(hr) )
{
// wait for async reply
hr = WaitForReply( hr );
if ( SUCCEEDED(hr) )
{
Lock();
m_dwMeasurementPeriod = QueueInfo.dwMeasurementPeriod;
m_dwTotalCallsQueued = QueueInfo.dwTotalCallsQueued;
m_dwCurrentCallsQueued = QueueInfo.dwCurrentCallsQueued;
m_dwTotalCallsAdandoned = QueueInfo.dwTotalCallsAbandoned;
m_dwTotalCallsFlowedIn = QueueInfo.dwTotalCallsFlowedIn;
m_dwTotalCallsFlowedOut = QueueInfo.dwTotalCallsFlowedOut;
m_dwLongestEverWaitTime = QueueInfo.dwLongestEverWaitTime;
m_dwCurrentLongestWaitTime = QueueInfo.dwCurrentLongestWaitTime;
m_dwAverageWaitTime = QueueInfo.dwAverageWaitTime;
m_dwFinalDisposition = QueueInfo.dwFinalDisposition;
m_bRequiresUpdating = FALSE;
Unlock();
}
else
{
LOG((TL_ERROR, "UpdateInfo - call to LineGetQueueInfo failed async" ));
}
}
else
{
LOG((TL_ERROR, "UpdateInfo - call to LineGetQueueInfo failed" ));
}
LOG((TL_TRACE, hr, "UpdateInfo - exit" ));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class : CQueue
// Method : CheckIfUpToDate
//
//
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
STDMETHODIMP CQueue::CheckIfUpToDate()
{
HRESULT hr = S_OK;
if (m_bRequiresUpdating)
{
hr = UpdateInfo();
}
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class : CQueue
// Method : Initialize
//
//
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
STDMETHODIMP CQueue::Initialize
(
DWORD dwQueueID,
PWSTR pszName,
CAgentHandler * pHandler
)
{
HRESULT hr = S_OK;
LOG((TL_TRACE, "Initialize - enter" ));
m_dwHandle = dwQueueID;
m_pHandler = pHandler;
m_bRequiresUpdating = TRUE;
// copy the destination address
if (pszName != NULL)
{
m_szName = (PWSTR) ClientAlloc((lstrlenW(pszName) + 1) * sizeof (WCHAR));
if (m_szName != NULL)
{
lstrcpyW(m_szName,pszName);
}
else
{
LOG((TL_ERROR, "Initialize - Alloc m_szName failed" ));
hr = E_OUTOFMEMORY;
}
}
else
{
LOG((TL_ERROR, "Initialize - name is NULL" ));
m_szName = NULL;
}
// Add this object into the Agnet Handler Hash table
m_pHandler->AddQueueToHash(m_dwHandle, this);
// Get Queue Info from Proxy
// UpdateInfo();
if ( SUCCEEDED(hr) )
{
CQueueEvent::FireEvent(this, ACDQE_NEW_QUEUE);
}
LOG((TL_TRACE, hr, "Initialize - exit" ));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class : CQueue
// Method : FinalRelease
//
//
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void CQueue::FinalRelease()
{
LOG((TL_TRACE, "FinalRelease Queue - %S", m_szName ));
if ( m_szName != NULL )
{
ClientFree(m_szName);
}
// Add this object into the Agnet Handler Hash table
m_pHandler->RemoveQueueFromHash(m_dwHandle);
LOG((TL_TRACE, "FinalRelease Queue - exit"));
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class : CQueue
// Interface : ITQueue
// Method : get_Name
//
//
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
STDMETHODIMP CQueue::get_Name(BSTR * Name)
{
HRESULT hr = S_OK;
LOG((TL_TRACE, "Name - enter" ));
Lock();
if (!TAPIIsBadWritePtr( Name, sizeof(BSTR ) ) )
{
*Name = SysAllocString(m_szName);
if (*Name == NULL)
{
hr = E_OUTOFMEMORY;
}
}
else
{
LOG((TL_ERROR, "Name - bad Name pointer"));
hr = E_POINTER;
}
Unlock();
LOG((TL_TRACE, hr, "Name - exit" ));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class : CQueue
// Interface : ITQueue
// Method : put_MeasurementPeriod
//
//
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
STDMETHODIMP CQueue::put_MeasurementPeriod(long ulPeriod)
{
HRESULT hr = S_OK;
LOG((TL_TRACE, "put_MeasurementPeriod - enter" ));
// ***************************************************
// Tell Proxy
hr = lineSetQueueMeasurementPeriod(
m_pHandler->getHLine(),
m_dwHandle,
ulPeriod);
if( SUCCEEDED(hr) )
{
// wait for async reply
hr = WaitForReply( hr );
if ( SUCCEEDED(hr) )
{
Lock();
m_dwMeasurementPeriod = ulPeriod;
Unlock();
}
else
{
LOG((TL_ERROR, "put_MeasurementPeriod - call to LineSetQueueMeasurementPeriod failed async" ));
}
}
else
{
LOG((TL_ERROR, "put_MeasurementPeriod - call to LineSetQueueMeasurementPeriod failed" ));
}
LOG((TL_TRACE, hr, "put_MeasurementPeriod - exit" ));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class : CQueue
// Interface : ITQueue
// Method : get_MeasurementPeriod
//
//
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
STDMETHODIMP CQueue::get_MeasurementPeriod (long * pulPeriod)
{
HRESULT hr = S_OK;
LOG((TL_TRACE, "get_MeasurementPeriod - enter" ));
if (!TAPIIsBadWritePtr( pulPeriod, sizeof(long) ) )
{
hr = CheckIfUpToDate();
if ( SUCCEEDED(hr) )
{
Lock();
*pulPeriod = m_dwMeasurementPeriod;
Unlock();
}
else
{
LOG((TL_ERROR, "get_MeasurementPeriod - Object update failed"));
}
}
else
{
LOG((TL_ERROR, "get_MeasurementPeriod - bad pulPeriod pointer"));
hr = E_POINTER;
}
LOG((TL_TRACE, hr, "get_MeasurementPeriod - exit" ));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class : CQueue
// Interface : ITQueue
// Method : TotalCallsQueued
//
//
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
STDMETHODIMP CQueue::get_TotalCallsQueued (long * pulCalls)
{
HRESULT hr = S_OK;
LOG((TL_TRACE, "TotalCallsQueued - enter" ));
if (!TAPIIsBadWritePtr( pulCalls, sizeof(long) ) )
{
hr = CheckIfUpToDate();
if ( SUCCEEDED(hr) )
{
Lock();
*pulCalls = m_dwTotalCallsQueued;
Unlock();
}
else
{
LOG((TL_ERROR, "get_TotalCallsQueued - Object update failed"));
}
}
else
{
LOG((TL_ERROR, "get_TotalCallsQueued - bad pulCalls pointer"));
hr = E_POINTER;
}
LOG((TL_TRACE, hr, "TotalCallsQueued - exit" ));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class : CQueue
// Interface : ITQueue
// Method : CurrentCallsQueued
//
//
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
STDMETHODIMP CQueue::get_CurrentCallsQueued (long * pulCalls)
{
HRESULT hr = S_OK;
LOG((TL_TRACE, "CurrentCallsQueued - enter" ));
if (!TAPIIsBadWritePtr( pulCalls, sizeof(long) ) )
{
hr = CheckIfUpToDate();
if ( SUCCEEDED(hr) )
{
Lock();
*pulCalls = m_dwCurrentCallsQueued;
Unlock();
}
else
{
LOG((TL_ERROR, "get_CurrentCallsQueued - Object update failed"));
}
}
else
{
LOG((TL_ERROR, "get_CurrentCallsQueued - bad pulCalls pointer"));
hr = E_POINTER;
}
LOG((TL_TRACE, hr, "CurrentCallsQueued - exit" ));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class : CQueue
// Interface : ITQueue
// Method : TotalCallsAbandoned
//
//
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
STDMETHODIMP CQueue::get_TotalCallsAbandoned (long * pulCalls)
{
HRESULT hr = S_OK;
LOG((TL_TRACE, "TotalCallsAbandoned - enter" ));
if (!TAPIIsBadWritePtr( pulCalls, sizeof(long) ) )
{
hr = CheckIfUpToDate();
if (SUCCEEDED(hr) )
{
Lock();
*pulCalls = m_dwTotalCallsAdandoned;
Unlock();
}
else
{
LOG((TL_ERROR, "get_TotalCallsAbandoned - Object update failed"));
}
}
else
{
LOG((TL_ERROR, "get_TotalCallsAbandoned - bad pulCalls pointer"));
hr = E_POINTER;
}
LOG((TL_TRACE, hr, "TotalCallsAbandoned - exit" ));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class : CQueue
// Interface : ITQueue
// Method : TotalCallsFlowedIn
//
//
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
STDMETHODIMP CQueue::get_TotalCallsFlowedIn (long * pulCalls)
{
HRESULT hr = S_OK;
LOG((TL_TRACE, "TotalCallsFlowedIn - enter" ));
if (!TAPIIsBadWritePtr( pulCalls, sizeof(long) ) )
{
hr = CheckIfUpToDate();
if (SUCCEEDED(hr) )
{
Lock();
*pulCalls = m_dwTotalCallsFlowedIn;
Unlock();
}
else
{
LOG((TL_ERROR, "get_TotalCallsFlowedIn - Object update failed"));
}
}
else
{
LOG((TL_ERROR, "get_TotalCallsFlowedIn - bad pulCalls pointer"));
hr = E_POINTER;
}
LOG((TL_TRACE, hr, "TotalCallsFlowedIn - exit" ));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class : CQueue
// Interface : ITQueue
// Method : TotalCallsFlowedIn
//
//
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
STDMETHODIMP CQueue::get_TotalCallsFlowedOut (long * pulCalls)
{
HRESULT hr = S_OK;
LOG((TL_TRACE, "TotalCallsFlowedOut - enter" ));
if (!TAPIIsBadWritePtr( pulCalls, sizeof(long) ) )
{
hr = CheckIfUpToDate();
if (SUCCEEDED(hr) )
{
Lock();
*pulCalls = m_dwTotalCallsFlowedOut;
Unlock();
}
else
{
LOG((TL_ERROR, "get_TotalCallsFlowedOut - Object update failed"));
}
}
else
{
LOG((TL_ERROR, "get_TotalCallsFlowedOut - bad pulCalls pointer"));
hr = E_POINTER;
}
LOG((TL_TRACE, hr, "TotalCallsFlowedOut - exit" ));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class : CQueue
// Interface : ITQueue
// Method : LongestEverWaitTime
//
//
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
STDMETHODIMP CQueue::get_LongestEverWaitTime (long * pulWaitTime)
{
HRESULT hr = S_OK;
LOG((TL_TRACE, "LongestEverWaitTime - enter" ));
if (!TAPIIsBadWritePtr( pulWaitTime, sizeof(long) ) )
{
hr = CheckIfUpToDate();
if (SUCCEEDED(hr) )
{
Lock();
*pulWaitTime = m_dwLongestEverWaitTime;
Unlock();
}
else
{
LOG((TL_ERROR, "get_LongestEverWaitTime - Object update failed"));
}
}
else
{
LOG((TL_ERROR, "get_LongestEverWaitTime - bad pulWaitTime pointer"));
hr = E_POINTER;
}
LOG((TL_TRACE, hr, "LongestEverWaitTime - exit" ));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class : CQueue
// Interface : ITQueue
// Method : CurrentLongestWaitTime
//
//
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
STDMETHODIMP CQueue::get_CurrentLongestWaitTime (long * pulWaitTime)
{
HRESULT hr = S_OK;
LOG((TL_TRACE, "CurrentLongestWaitTime - enter" ));
if (!TAPIIsBadWritePtr( pulWaitTime, sizeof(long) ) )
{
hr = CheckIfUpToDate();
if (SUCCEEDED(hr) )
{
Lock();
*pulWaitTime = m_dwCurrentLongestWaitTime;
Unlock();
}
else
{
LOG((TL_ERROR, "get_CurrentLongestWaitTime - Object update failed"));
}
}
else
{
LOG((TL_ERROR, "get_CurrentLongestWaitTime - bad pulWaitTime pointer"));
hr = E_POINTER;
}
LOG((TL_TRACE, hr, "CurrentLongestWaitTime - exit" ));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class : CQueue
// Interface : ITQueue
// Method : AverageWaitTime
//
//
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
STDMETHODIMP CQueue::get_AverageWaitTime (long * pulWaitTime)
{
HRESULT hr = S_OK;
LOG((TL_TRACE, "AverageWaitTime - enter" ));
if (!TAPIIsBadWritePtr( pulWaitTime, sizeof(long) ) )
{
hr = CheckIfUpToDate();
if (SUCCEEDED(hr) )
{
Lock();
*pulWaitTime = m_dwAverageWaitTime;
Unlock();
}
else
{
LOG((TL_ERROR, "get_AverageWaitTime - Object update failed"));
}
}
else
{
LOG((TL_ERROR, "get_AverageWaitTime - bad pulWaitTime pointer"));
hr = E_POINTER;
}
LOG((TL_TRACE, hr, "AverageWaitTime - exit" ));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class : CQueue
// Interface : ITQueue
// Method : FinalDisposition
//
//
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
STDMETHODIMP CQueue::get_FinalDisposition (long * pulCalls)
{
HRESULT hr = S_OK;
LOG((TL_TRACE, "FinalDisposition - enter" ));
if (!TAPIIsBadWritePtr( pulCalls, sizeof(long) ) )
{
hr = CheckIfUpToDate();
if (SUCCEEDED(hr) )
{
Lock();
*pulCalls = m_dwFinalDisposition;
Unlock();
}
else
{
LOG((TL_ERROR, "get_FinalDisposition - Object update failed"));
}
}
else
{
LOG((TL_ERROR, "get_FinalDisposition - bad pulCalls pointer"));
hr = E_POINTER;
}
LOG((TL_TRACE, hr, "FinalDisposition - exit" ));
return hr;
}
/////////////////////////////////////////////////////////////////////////////
// CQueueEvent
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class : CQueueEvent
// Method : FireEvent
//
//
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
HRESULT CQueueEvent::FireEvent(CQueue* pQueue, ACDQUEUE_EVENT Event)
{
HRESULT hr = S_OK;
CComObject<CQueueEvent> * pEvent;
IDispatch * pIDispatch;
if ( IsBadReadPtr(pQueue, sizeof(CQueue)) )
{
STATICLOG((TL_ERROR, "FireEvent - pQueue is an invalid pointer"));
return E_POINTER;
}
//
// create event
//
hr = CComObject<CQueueEvent>::CreateInstance( &pEvent );
if ( SUCCEEDED(hr) )
{
//
// initialize
//
pEvent->m_QueueEvent = Event;
pEvent->m_pQueue= dynamic_cast<ITQueue *>(pQueue);
pEvent->m_pQueue->AddRef();
//
// get idisp interface
//
hr = pEvent->QueryInterface( IID_IDispatch, (void **)&pIDispatch );
if ( SUCCEEDED(hr) )
{
//
// get callback & fire event
//
CTAPI *pTapi = (pQueue->GetAgentHandler() )->GetTapi();
pTapi->Event( TE_QUEUE, pIDispatch );
// release stuff
//
pIDispatch->Release();
}
else
{
STATICLOG((TL_ERROR, "FireEvent - Could not get disp interface of QueueEvent object"));
delete pEvent;
}
}
else
{
STATICLOG((TL_ERROR, "FireEvent - Could not create QueueEvent object"));
}
STATICLOG((TL_TRACE, hr, "FireEvent - exit"));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class : CQueueEvent
// Method : FinalRelease
//
//
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void CQueueEvent::FinalRelease()
{
m_pQueue->Release();
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class : CQueueEvent
// Interface : ITQueueEvent
// Method : Queue
//
//
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
STDMETHODIMP CQueueEvent::get_Queue(ITQueue ** ppQueue)
{
HRESULT hr = S_OK;
LOG((TL_TRACE, "(Event)Queue - enter" ));
if (!TAPIIsBadWritePtr( ppQueue, sizeof(ITQueue *) ) )
{
*ppQueue = m_pQueue;
m_pQueue->AddRef();
}
else
{
LOG((TL_ERROR, "(Event)Queue - bad ppQueue pointer"));
hr = E_POINTER;
}
LOG((TL_TRACE, hr, "(Event)Queue - exit"));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class : CQueueEvent
// Interface : ITQueueEvent
// Method : Event
//
//
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
STDMETHODIMP CQueueEvent::get_Event(ACDQUEUE_EVENT * pEvent)
{
HRESULT hr = S_OK;
LOG((TL_TRACE, "Event - enter" ));
if (!TAPIIsBadWritePtr( pEvent, sizeof(ACDQUEUE_EVENT) ) )
{
*pEvent = m_QueueEvent;
}
else
{
LOG((TL_ERROR, "Event - bad pEvent pointer"));
hr = E_POINTER;
}
LOG((TL_TRACE, hr, "Event - exit"));
return hr;
}