/*++ Copyright (c) 1997-1999 Microsoft Corporation Module Name: acdgroup.cpp Abstract: Implementation of the ACD Group object for TAPI 3.0. CACDGroup class Author: noela - 11/04/97 Notes: optional-notes Revision History: --*/ #include "stdafx.h" HRESULT WaitForReply( DWORD ); ///////////////////////////////////////////////////////////////////////////// // CACDGroup //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Class : CACDGroup // Method : Initialize // // // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ STDMETHODIMP CACDGroup::Initialize ( PWSTR pszGroupName, GUID GroupHandle, CAgentHandler * pHandler ) { HRESULT hr = S_OK; LOG((TL_TRACE, "Initialize - enter" )); m_GroupHandle = GroupHandle; m_pHandler = pHandler; m_bActive = TRUE; // copy the destination address if (pszGroupName != NULL) { m_szName = (PWSTR) ClientAlloc((lstrlenW(pszGroupName) + 1) * sizeof (WCHAR)); if (m_szName != NULL) { lstrcpyW(m_szName,pszGroupName); } else { LOG((TL_ERROR, "Initialize - Alloc m_szName failed" )); hr = E_OUTOFMEMORY; } } else { LOG((TL_INFO, "Initialize - name is NULL" )); m_szName = NULL; } if ( SUCCEEDED(hr) ) { // Fire event here CACDGroupEvent::FireEvent(this, ACDGE_NEW_GROUP); } LOG((TL_TRACE, hr, "Initialize - exit" )); return hr; } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Class : CACDGroup // Method : FinalRelease // // // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void CACDGroup::FinalRelease() { LOG(( TL_TRACE, "FinalRelease ACD Group - %S", m_szName )); if ( m_szName != NULL ) { ClientFree(m_szName); } m_QueueArray.Shutdown(); LOG((TL_TRACE, "FinalRelease ACD Group - exit")); } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Class : CACDGroup // Method : SetActive // // // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void CACDGroup::SetActive() { if ( !m_bActive ) { LOG((TL_INFO, "SetActive - Set Group To Active")); m_bActive = TRUE; // Fire event here CACDGroupEvent::FireEvent(this, ACDGE_NEW_GROUP); } else { LOG((TL_INFO, "SetActive - Already Active")); } } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Class : CACDGroup // Method : SetInactive // // // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void CACDGroup::SetInactive() { if ( m_bActive ) { LOG((TL_INFO, "SetInactive - Set Group To Inactive")); m_bActive = FALSE; // Fire event here CACDGroupEvent::FireEvent(this, ACDGE_GROUP_REMOVED); } else { LOG((TL_INFO, "SetInactive - Already Inactive")); } } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Class : CACDGroup // Method : active // Overloaded function ! // // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ inline BOOL CACDGroup::active(HRESULT * hr) { if(m_bActive) { *hr = S_OK; } else { LOG((TL_ERROR, "Group inactive" )); *hr = E_UNEXPECTED; } return m_bActive; } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Class : CACDGroup // Method : UpdateAgentHandlerList // // // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ HRESULT CACDGroup::UpdateQueueArray() { HRESULT hr = S_OK; DWORD dwNumberOfEntries; LPLINEQUEUELIST pQueueList = NULL; LPLINEQUEUEENTRY pQueueEntry = NULL; PWSTR pszQueueName; DWORD dwQueueID, dwCount; int iCount; BOOL foundIt; CQueue * thisQueue = NULL; LOG((TL_TRACE, "UpdateQueueArray - enter")); // Call LineGetQueulist to get list of Queues hr = lineGetQueueList( m_pHandler->getHLine(), &m_GroupHandle, &pQueueList ); if( SUCCEEDED(hr) ) { dwNumberOfEntries = pQueueList->dwNumEntries; // Find position of 1st LINEQUEUEENTRY structure in the LINEQUEUELIST pQueueEntry = (LPLINEQUEUEENTRY) ((BYTE*)(pQueueList) + pQueueList->dwListOffset); // Run though the received list for (dwCount = 0; dwCount < dwNumberOfEntries; dwCount++) { int iCount; pszQueueName= (PWSTR)( (PBYTE)pQueueList + pQueueEntry->dwNameOffset); dwQueueID = pQueueEntry->dwQueueID; LOG((TL_INFO, "UpdateQueueArray - Queue Name : %S", pszQueueName)); LOG((TL_INFO, "UpdateQueueArray - Queue Handle : %d", dwQueueID)); // Run through the list of Queues & see if we already have this one in the list // by comparing IDs foundIt = FALSE; Lock(); for (iCount = 0; iCount < m_QueueArray.GetSize(); iCount++) { thisQueue = dynamic_cast*>(m_QueueArray[iCount]); if (thisQueue != NULL) { if ( dwQueueID == thisQueue->getID() ) { foundIt = TRUE; break; } } } Unlock(); if (foundIt == FALSE) { // Didn't match so lets add this Queue LOG((TL_INFO, "UpdateQueueArray - create new Queue")); CComObject * pQueue; hr = CComObject::CreateInstance( &pQueue ); if( SUCCEEDED(hr) ) { ITQueue * pITQueue; hr = pQueue->QueryInterface(IID_ITQueue, (void **)&pITQueue); if ( SUCCEEDED(hr) ) { // initialize the Queue hr = pQueue->Initialize(dwQueueID, pszQueueName, m_pHandler); if( SUCCEEDED(hr) ) { // add to list of CQueues Lock(); m_QueueArray.Add(pITQueue); Unlock(); pITQueue->Release(); LOG((TL_INFO, "UpdateQueueArray - Added Queue to list")); } else { LOG((TL_ERROR, "UpdateQueueArray - Initialize Queue failed" )); delete pQueue; } } else { LOG((TL_ERROR, "UpdateQueueArray - QueryInterface ITQueue failed" )); delete pQueue; } } else { LOG((TL_ERROR, "UpdateQueueArray - Create Queue failed" )); } } else // foundIt == TRUE { LOG((TL_INFO, "UpdateQueueArray - Queue Object exists for this entry" )); } // next entry in list pQueueEntry ++; } //for(dwCount = 0......) } else // LineGetQueuelist failed { LOG((TL_ERROR, "UpdateQueueArray - LineGetQueuelist failed")); } // finished with memory block so release if ( pQueueList != NULL ) ClientFree( pQueueList ); LOG((TL_TRACE, hr, "UpdateQueueArray - exit")); return hr; } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Class : CACDGroup // Interface : ITACDGroup // Method : EnumerateQueues // // // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ STDMETHODIMP CACDGroup::EnumerateQueues(IEnumQueue ** ppEnumQueue) { HRESULT hr = S_OK; LOG((TL_TRACE, "EnumerateQueues - enter")); if(!TAPIIsBadWritePtr( ppEnumQueue, sizeof(IEnumQueue *) ) ) { Lock(); UpdateQueueArray(); // // create the enumerator // CComObject< CTapiEnum > * pEnum; hr = CComObject< CTapiEnum > ::CreateInstance( &pEnum ); if ( SUCCEEDED(hr) ) { // // initialize it with our queue list // hr = pEnum->Initialize( m_QueueArray ); if ( SUCCEEDED(hr) ) { // return it *ppEnumQueue = pEnum; } else // failed to initialize { LOG((TL_ERROR, "EnumerateQueues - could not initialize enum" )); pEnum->Release(); } } else // failed to create enum { LOG((TL_ERROR, "EnumerateQueues - could not create enum" )); hr = E_POINTER; } Unlock(); } else { LOG((TL_ERROR, "EnumerateQueues - bad ppEnumQueue pointer")); hr = E_POINTER; } LOG((TL_TRACE, hr, "EnumerateQueues - exit")); return hr; } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Class : CACDGroup // Interface : ITACDGroup // Method : get_Queues // // Return a collection of queues // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ STDMETHODIMP CACDGroup::get_Queues(VARIANT * pVariant) { HRESULT hr = S_OK; IDispatch * pDisp = NULL; LOG((TL_TRACE, "get_Queues - enter")); if (!TAPIIsBadWritePtr( pVariant, sizeof(VARIANT) ) ) { UpdateQueueArray(); // // create the collection // CComObject< CTapiCollection< ITQueue > > * p; hr = CComObject< CTapiCollection< ITQueue > >::CreateInstance( &p ); if (SUCCEEDED(hr) ) { // initialize it with our address list Lock(); hr = p->Initialize( m_QueueArray ); Unlock(); if ( SUCCEEDED(hr) ) { // get the IDispatch interface hr = p->_InternalQueryInterface( IID_IDispatch, (void **) &pDisp ); if ( SUCCEEDED(hr) ) { // put it in the variant VariantInit(pVariant); pVariant->vt = VT_DISPATCH; pVariant->pdispVal = pDisp; } else { LOG((TL_ERROR, "get_Queues - could not get IDispatch interface" )); delete p; } } else { LOG((TL_ERROR, "get_Queues - could not initialize collection" )); delete p; } } else { LOG((TL_ERROR, "get_Queues - could not create collection" )); } } else { LOG((TL_ERROR, "get_Queues - bad pVariant pointer" )); hr = E_POINTER; } LOG((TL_TRACE, hr, "get_Queues - exit")); return hr; } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Class : CACDGroup // Interface : ITACDGroup // Method : get_Name // // // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ STDMETHODIMP CACDGroup::get_Name(BSTR * Name) { HRESULT hr = S_OK; LOG((TL_TRACE, "Name - enter" )); if(!TAPIIsBadWritePtr( Name, sizeof(BSTR) ) ) { if ( active(&hr) ) { Lock(); *Name = SysAllocString(m_szName); if (*Name == NULL) { hr = E_OUTOFMEMORY; } Unlock(); } } else { LOG((TL_ERROR, "Name - bad Name pointer" )); hr = E_POINTER; } LOG((TL_TRACE, hr, "Name - exit" )); return hr; } ///////////////////////////////////////////////////////////////////////////// // CACDGroup //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Class : CACDGroup // Method : FireEvent // // // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ HRESULT CACDGroupEvent::FireEvent(CACDGroup* pACDGroup, ACDGROUP_EVENT Event) { HRESULT hr = S_OK; CComObject * pEvent; IDispatch * pIDispatch; if ( IsBadReadPtr(pACDGroup, sizeof(CACDGroup)) ) { STATICLOG((TL_ERROR, "FireEvent - pACDGroup is an invalid pointer")); _ASSERTE(FALSE); return E_POINTER; } // // create event // hr = CComObject::CreateInstance( &pEvent ); if ( SUCCEEDED(hr) ) { // // initialize // pEvent->m_GroupEvent = Event; pEvent->m_pGroup= dynamic_cast(pACDGroup); pEvent->m_pGroup->AddRef(); // // get idisp interface // hr = pEvent->QueryInterface( IID_IDispatch, (void **)&pIDispatch ); if ( SUCCEEDED(hr) ) { // // get callback & fire event // CTAPI *pTapi = (pACDGroup->GetAgentHandler() )->GetTapi(); pTapi->Event( TE_ACDGROUP, pIDispatch ); // release stuff // pIDispatch->Release(); } else { STATICLOG((TL_ERROR, "FireEvent - Could not get disp interface of ACDGroupEvent object")); delete pEvent; } } else { STATICLOG((TL_ERROR, "FireEvent - Could not create ACDGroupEvent object")); } STATICLOG((TL_TRACE, hr, "FireEvent - exit")); return hr; } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Class : CACDGroup // Method : FinalRelease // // // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void CACDGroupEvent::FinalRelease() { m_pGroup->Release(); } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Class : CACDGroup // Interface : ITACDGroupEvent // Method : ACDGroup // // // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ STDMETHODIMP CACDGroupEvent::get_Group(ITACDGroup ** ppGroup) { HRESULT hr = S_OK; LOG((TL_TRACE, "(Event)ACDGroup - enter" )); if(!TAPIIsBadWritePtr( ppGroup, sizeof(ITACDGroup *) ) ) { *ppGroup = m_pGroup; m_pGroup->AddRef(); } else { LOG((TL_ERROR, "(Event)ACDGroup -bad ppGroup pointer")); hr = E_POINTER; } LOG((TL_TRACE, hr, "(Event)ACDGroup - exit")); return hr; } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Class : CACDGroup // Interface : ITACDGroupEvent // Method : Event // // // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ STDMETHODIMP CACDGroupEvent::get_Event(ACDGROUP_EVENT * pEvent) { HRESULT hr = S_OK; LOG((TL_TRACE, "Event - enter" )); if(!TAPIIsBadWritePtr( pEvent, sizeof(ACDGROUP_EVENT) ) ) { *pEvent = m_GroupEvent; } else { LOG((TL_TRACE, "Event - bad pEvent pointer")); hr = E_POINTER; } LOG((TL_TRACE, hr, "Event - exit")); return hr; }