windows-nt/Source/XPSP1/NT/net/tapi/skywalker/tapi3/phonemsp.cpp
2020-09-26 16:20:57 +08:00

1475 lines
33 KiB
C++

/*++
Copyright (c) 1998-1999 Microsoft Corporation
Module Name:
phonemsp.cpp
Abstract:
Implements an MSP object for addresses that have phone terminals
this makes the MSP abstraction in the address object much easier,
since there will be no special cases for phone devices/terminals
Author:
mquinton - 9/24/98
Notes:
Revision History:
--*/
#include "stdafx.h"
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//
// CPhoneMSP::Initialize
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
STDMETHODIMP
CPhoneMSP::Initialize(
MSP_HANDLE hEvent
)
{
HRESULT hr = S_OK;
LOG((TL_TRACE, "Initialize - enter"));
Lock();
m_hEvent = (HANDLE)hEvent;
#if DBG
m_pDebug = (PWSTR) ClientAlloc( 1 );
#endif
Unlock();
LOG((TL_TRACE, "Initialize - exit - return %lx", hr));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//
// CPhoneMSP::Shutdown
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
STDMETHODIMP
CPhoneMSP::Shutdown()
{
HRESULT hr = E_NOTIMPL;
LOG((TL_TRACE, "Shutdown - enter"));
LOG((TL_TRACE, "Shutdown - exit - return %lx", hr));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//
// CPhoneMSP::CreateMSPCall
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
STDMETHODIMP
CPhoneMSP::CreateMSPCall(
MSP_HANDLE hCall,
DWORD dwReserved,
DWORD dwMediaType,
IUnknown * pOuterUnknown,
IUnknown ** ppStreamControl
)
{
HRESULT hr;
CComAggObject<CPhoneMSPCall> * pPhoneMSPCall;
ITPhoneMSPCallPrivate * pPhoneMSPCallPrivate;
LOG((TL_TRACE, "CreateMSPCall - enter"));
pPhoneMSPCall = new CComAggObject<CPhoneMSPCall>(pOuterUnknown);
if ( NULL == pPhoneMSPCall )
{
}
//
// save the aggregated interface in
// the msppointer
//
pPhoneMSPCall->QueryInterface(
IID_IUnknown,
(void **)ppStreamControl
);
//
// get to the real object
//
hr = (*ppStreamControl)->QueryInterface(
IID_ITPhoneMSPCallPrivate,
(void **)&pPhoneMSPCallPrivate
);
//
// initialize it
//
hr = pPhoneMSPCallPrivate->Initialize( this );
Lock();
AddCall( *ppStreamControl );
Unlock();
pPhoneMSPCallPrivate->Release();
LOG((TL_TRACE, "CreateMSPCall - exit - return %lx", hr));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//
// CPhoneMSP::ShutdownMSPCall
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
STDMETHODIMP
CPhoneMSP::ShutdownMSPCall(
IUnknown * pStreamControl
)
{
HRESULT hr = S_OK;
LOG((TL_TRACE, "ShutdownMSPCall - enter"));
Lock();
RemoveCall( pStreamControl );
Unlock();
LOG((TL_TRACE, "ShutdownMSPCall - exit - return %lx", hr));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//
// CPhoneMSP::ReceiveTSPData
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
STDMETHODIMP
CPhoneMSP::ReceiveTSPData(
IUnknown * pMSPCall,
BYTE * pBuffer,
DWORD dwSize
)
{
HRESULT hr = S_OK;
DWORD dwCommand;
ITPhoneMSPCallPrivate * pCall;
LOG((TL_TRACE, "ReceiveTSPData - enter"));
if ( NULL == pMSPCall )
{
LOG((TL_ERROR, "ReceiveTSPData - null call"));
return E_INVALIDARG;
}
dwCommand = *((LPDWORD)(pBuffer));
hr = pMSPCall->QueryInterface(
IID_ITPhoneMSPCallPrivate,
(void**)&pCall
);
if ( !SUCCEEDED(hr) )
{
LOG((TL_ERROR, "ReceiveTSPData - bad call"));
return E_FAIL;
}
LOG((TL_INFO, "ReceiveTSPData - command %d", dwCommand));
switch (dwCommand)
{
case 1: // Start Streaming
hr = pCall->OnConnect();
break;
case 2: // Stop Streaming
hr = pCall->OnDisconnect();
break;
default:
LOG((TL_ERROR, "ReceiveTSPData - invalid command "));
hr = E_FAIL;
break;
}
pCall->Release();
LOG((TL_TRACE, "ReceiveTSPData - exit - return %lx", hr));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//
// CPhoneMSP::GetEvent
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
STDMETHODIMP
CPhoneMSP::GetEvent(
DWORD * pdwSize,
byte * pEventBuffer
)
{
HRESULT hr = E_NOTIMPL;
LOG((TL_TRACE, "GetEvent - enter"));
LOG((TL_TRACE, "GetEvent - exit - return %lx", hr));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
HRESULT
CPhoneMSP::InitializeTerminals(
HPHONEAPP hPhoneApp,
DWORD dwAPIVersion,
DWORD dwPhoneDevice,
CAddress * pAddress
)
{
LPPHONECAPS pPhoneCaps = NULL;
HRESULT hr;
BOOL bSucceeded = FALSE;
ITStream * pStream;
LOG((TL_TRACE, "InitializeTerminals - enter"));
//
// get the phone caps
//
hr = PhoneGetDevCapsWithAlloc(
hPhoneApp,
dwPhoneDevice,
dwAPIVersion,
&pPhoneCaps
);
if (S_OK != hr)
{
if (NULL != pPhoneCaps)
{
ClientFree( pPhoneCaps );
}
LOG((TL_ERROR, "CreatePhoneTerminals - PhoneGetDevCaps failed - %lx", hr ));
return hr;
}
//
// check the hook switch devs
//
if (0 == pPhoneCaps->dwHookSwitchDevs)
{
LOG((TL_ERROR, "CreatePhoneTerminal - no hook switch devs!" ));
ClientFree( pPhoneCaps );
return E_UNEXPECTED;
}
//
// create terminal devices for each hook switch dev
// need to create an audio in and audio out terminal
// for each
//
ITTerminal * pTerminal;
if (pPhoneCaps->dwHookSwitchDevs & PHONEHOOKSWITCHDEV_HANDSET)
{
hr = CTerminal::Create(
hPhoneApp,
dwPhoneDevice,
pPhoneCaps,
PHONEHOOKSWITCHDEV_HANDSET,
TD_RENDER,
dwAPIVersion,
&pTerminal
);
if (SUCCEEDED(hr))
{
bSucceeded = TRUE;
AddTerminal( pTerminal );
pTerminal->Release();
}
hr = CTerminal::Create(
hPhoneApp,
dwPhoneDevice,
pPhoneCaps,
PHONEHOOKSWITCHDEV_HANDSET,
TD_CAPTURE,
dwAPIVersion,
&pTerminal
);
if (SUCCEEDED(hr))
{
bSucceeded = TRUE;
AddTerminal( pTerminal );
pTerminal->Release();
}
}
if (pPhoneCaps->dwHookSwitchDevs & PHONEHOOKSWITCHDEV_HEADSET)
{
hr = CTerminal::Create(
hPhoneApp,
dwPhoneDevice,
pPhoneCaps,
PHONEHOOKSWITCHDEV_HEADSET,
TD_RENDER,
dwAPIVersion,
&pTerminal
);
if (SUCCEEDED(hr))
{
bSucceeded = TRUE;
AddTerminal( pTerminal );
pTerminal->Release();
}
hr = CTerminal::Create(
hPhoneApp,
dwPhoneDevice,
pPhoneCaps,
PHONEHOOKSWITCHDEV_HEADSET,
TD_CAPTURE,
dwAPIVersion,
&pTerminal
);
if (SUCCEEDED(hr))
{
bSucceeded = TRUE;
AddTerminal( pTerminal );
pTerminal->Release();
}
}
if (pPhoneCaps->dwHookSwitchDevs & PHONEHOOKSWITCHDEV_SPEAKER)
{
hr = CTerminal::Create(
hPhoneApp,
dwPhoneDevice,
pPhoneCaps,
PHONEHOOKSWITCHDEV_SPEAKER,
TD_RENDER,
dwAPIVersion,
&pTerminal
);
if (SUCCEEDED(hr))
{
bSucceeded = TRUE;
AddTerminal( pTerminal );
pTerminal->Release();
}
hr = CTerminal::Create(
hPhoneApp,
dwPhoneDevice,
pPhoneCaps,
PHONEHOOKSWITCHDEV_SPEAKER,
TD_CAPTURE,
dwAPIVersion,
&pTerminal
);
if (SUCCEEDED(hr))
{
bSucceeded = TRUE;
AddTerminal( pTerminal );
pTerminal->Release();
}
}
//
// free memory
//
if (NULL != pPhoneCaps)
{
ClientFree( pPhoneCaps );
}
if ( !bSucceeded )
{
LOG((TL_WARN, "No phone terminals created"));
return E_FAIL;
}
LOG((TL_TRACE, "InitializeTerminals - exit"));
return S_OK;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
HRESULT
CPhoneMSP::VerifyTerminal( ITTerminal * pTerminal )
{
int iReturn;
Lock();
iReturn = m_TerminalArray.Find( pTerminal );
Unlock();
if ( -1 == iReturn )
{
return TAPI_E_INVALIDTERMINAL;
}
return S_OK;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
void
CPhoneMSP::AddTerminal( ITTerminal * pTerminal )
{
Lock();
m_TerminalArray.Add( pTerminal );
Unlock();
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//
// called in lock
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
void
CPhoneMSP::AddCall( IUnknown * pCall )
{
m_CallArray.Add( pCall );
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//
// called in lock
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
void
CPhoneMSP::RemoveCall( IUnknown * pCall )
{
m_CallArray.Remove( pCall );
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
void
CPhoneMSP::FinalRelease()
{
LOG((TL_TRACE, "FinalRelease - enter"));
#if DBG
ClientFree( m_pDebug );
#endif
m_TerminalArray.Shutdown();
m_CallArray.Shutdown();
LOG((TL_TRACE, "FinalRelease - exit"));
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//
// CPhoneMSP::get_StaticTerminals
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
STDMETHODIMP
CPhoneMSP::get_StaticTerminals(
VARIANT * pVariant
)
{
HRESULT hr = S_OK;
IDispatch * pDisp;
LOG((TL_TRACE, "get_StaticTerminals - enter"));
if (TAPIIsBadWritePtr( pVariant, sizeof(VARIANT) ) )
{
LOG((TL_ERROR, "get_StaticTerminals - bad pointer"));
return E_POINTER;
}
CComObject< CTapiCollection< ITTerminal > > * p;
CComObject< CTapiCollection< ITTerminal > >::CreateInstance( &p );
if (NULL == p)
{
LOG((TL_ERROR, "get_StaticTerminals - could not create collection" ));
return E_OUTOFMEMORY;
}
Lock();
// initialize
hr = p->Initialize( m_TerminalArray );
Unlock();
if (S_OK != hr)
{
LOG((TL_ERROR, "get_StaticTerminals - could not initialize collection" ));
delete p;
return hr;
}
//
// get the IDispatch interface
//
hr = p->_InternalQueryInterface(
IID_IDispatch,
(void **) &pDisp
);
if (S_OK != hr)
{
LOG((TL_ERROR, "get_StaticTerminals - could not get IDispatch interface" ));
delete p;
return hr;
}
//
// put it in the variant
//
VariantInit(pVariant);
pVariant->vt = VT_DISPATCH;
pVariant->pdispVal = pDisp;
LOG((
TL_TRACE,
"get_StaticTerminals - exit - return %lx",
hr
));
LOG((TL_TRACE, "get_StaticTerminals - exit"));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//
// CPhoneMSP::EnumerateStaticTerminals
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
STDMETHODIMP
CPhoneMSP::EnumerateStaticTerminals(IEnumTerminal ** ppEnumTerminal)
{
HRESULT hr = S_OK;
LOG((TL_TRACE, "EnumerateStaticTerminals - enter"));
if (TAPIIsBadWritePtr(ppEnumTerminal, sizeof( IEnumTerminal * ) ) )
{
LOG((TL_ERROR, "EnumerateStaticTerminals - bad pointer"));
return E_POINTER;
}
//
// create the enumerator
//
CComObject< CTapiEnum< IEnumTerminal, ITTerminal, &IID_IEnumTerminal > > * p;
hr = CComObject< CTapiEnum< IEnumTerminal, ITTerminal, &IID_IEnumTerminal > >
::CreateInstance( &p );
if (S_OK != hr)
{
LOG((TL_ERROR, "EnumerateStaticTerminals - could not create enum" ));
return hr;
}
Lock();
//
// initialize it with our terminal array
//
p->Initialize( m_TerminalArray );
Unlock();
//
// return it
//
*ppEnumTerminal = p;
LOG((
TL_TRACE,
"EnumerateStaticTerminals - exit - return %lx",
hr
));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//
// CPhoneMSP::get_DynamicTerminalClasses
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
STDMETHODIMP
CPhoneMSP::get_DynamicTerminalClasses(VARIANT * pVariant)
{
HRESULT hr = S_OK;
CComObject< CTerminalClassCollection > * p;
IDispatch * pDisp = NULL;
TerminalClassPtrList classlist;
LOG((TL_TRACE, "get_DynamicTerminalClasses - enter"));
if (TAPIIsBadWritePtr( pVariant, sizeof(VARIANT) ) )
{
LOG((TL_ERROR, "get_DynamicTerminalClasses - bad pointer"));
return E_POINTER;
}
classlist.clear();
//
// create the object
//
CComObject< CTerminalClassCollection >::CreateInstance( &p );
//
// init it
//
hr = p->Initialize( classlist );
//
// get the IDispatch interface
//
hr = p->_InternalQueryInterface( IID_IDispatch, (void **) &pDisp );
if (S_OK != hr)
{
LOG((TL_ERROR, "get_dynamicterminalclasses - could not get the IDispatch interface" ));
delete p;
return hr;
}
//
// put it in the variant
//
VariantInit(pVariant);
pVariant->vt = VT_DISPATCH;
pVariant->pdispVal = pDisp;
LOG((
TL_TRACE,
"get_DynamicTerminalClasses - exit - return %lx",
hr
));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//
// CPhoneMSP::EnumerateDynamicTerminalClasses
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
STDMETHODIMP
CPhoneMSP::EnumerateDynamicTerminalClasses(
IEnumTerminalClass ** ppTerminalClassEnumerator
)
{
HRESULT hr = S_OK;
TerminalClassPtrList termlist;
LOG((TL_TRACE, "EnumerateDynamicTerminalClasses - enter"));
if (TAPIIsBadWritePtr( ppTerminalClassEnumerator, sizeof(IEnumTerminalClass *) ) )
{
LOG((TL_ERROR, "EnumerateDynamicTerminalClasses - bad pointer"));
return E_POINTER;
}
termlist.clear();
//
// create the enumerator
//
CComObject< CTerminalClassEnum > * p;
CComObject< CTerminalClassEnum >::CreateInstance( &p );
if (NULL == p)
{
LOG((TL_TRACE, "_EnumDynTermClasses - create enum failed - return %lx", hr ));
return hr;
}
//
// init it
//
hr = p->Initialize( termlist );
if (!SUCCEEDED( hr ))
{
LOG((TL_TRACE, "_EnumDynTermClasses - init enum failed - return %lx", hr ));
delete p;
return hr;
}
*ppTerminalClassEnumerator = p;
LOG((
TL_TRACE,
"EnumerateDynamicTerminalClasses - exit - return %lx",
hr
));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//
// CPhoneMSP::CreateTerminal
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
STDMETHODIMP
CPhoneMSP::CreateTerminal(
BSTR TerminalClass,
long lMediaType,
TERMINAL_DIRECTION TerminalDirection,
ITTerminal ** ppTerminal
)
{
HRESULT hr = TAPI_E_NOTSUPPORTED;
LOG((TL_TRACE, "CreateTerminal - enter"));
LOG((
TL_TRACE,
"CreateTerminal - exit - return %lx",
hr
));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//
// CPhoneMSP::GetDefaultStaticTerminal
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
STDMETHODIMP
CPhoneMSP::GetDefaultStaticTerminal(
long lMediaType,
TERMINAL_DIRECTION Dir,
ITTerminal ** ppTerminal
)
{
HRESULT hr = S_OK;
int iSize, iCount;
LOG((TL_TRACE, "GetDefaultStaticTerminal - enter"));
if ( TAPIIsBadWritePtr( ppTerminal, sizeof (ITTerminal *) ) )
{
LOG((TL_TRACE, "GetDefaultStaticTerminal - bad pointer"));
return E_POINTER;
}
Lock();
iSize = m_TerminalArray.GetSize();
for ( iCount = 0; iCount < iSize; iCount++ )
{
TERMINAL_DIRECTION td;
long lTermMediaType;
hr = m_TerminalArray[iCount]->get_Direction( &td );
if ( SUCCEEDED(hr) )
{
hr = m_TerminalArray[iCount]->get_MediaType( &lTermMediaType );
if ( SUCCEEDED(hr) )
{
if ( ( td == Dir ) &&
( lTermMediaType == lMediaType ) )
{
*ppTerminal = m_TerminalArray[iCount];
(*ppTerminal)->AddRef();
Unlock();
LOG((
TL_TRACE,
"GetDefaultStaticTerminal - exit - return S_OK"
));
return S_OK;
}
}
}
}
Unlock();
hr = TAPI_E_INVALIDTERMINAL;
LOG((
TL_TRACE,
"GetDefaultStaticTerminal - exit - return %lx",
hr
));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//
// CreateStream
//
// dwMediaType - mediatype of new stream
//
// td - direction of new stream
//
// ppStream - returned stream
//
// always fails - phone terminals don't handle this type of
// functionality
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
STDMETHODIMP
CPhoneMSPCall::CreateStream(
long dwMediaType,
TERMINAL_DIRECTION td,
ITStream ** ppStream
)
{
HRESULT hr = TAPI_E_NOTSUPPORTED;
LOG((TL_TRACE, "CreateStream - enter"));
LOG((TL_TRACE, "CreateStream - exit - return %lx", hr));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//
// RemoveStream
//
// pStream - stream to remove
//
// always fail - phone terminals don't handle this type of
// functionality.
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
STDMETHODIMP
CPhoneMSPCall::RemoveStream(
ITStream * pStream
)
{
HRESULT hr = TAPI_E_NOTSUPPORTED;
LOG((TL_TRACE, "RemoveStream - enter"));
LOG((TL_TRACE, "RemoveStream - exit - return %lx", hr));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//
// EnumerateStreams
//
// ppEnumStream - returned enumerator
//
// enumerates the streams available. this should always be
// audio in and audio out
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
STDMETHODIMP
CPhoneMSPCall::EnumerateStreams(
IEnumStream ** ppEnumStream
)
{
HRESULT hr = S_OK;
LOG((TL_TRACE, "EnumerateStreams - enter"));
if (TAPIIsBadWritePtr(ppEnumStream, sizeof( IEnumStream * ) ) )
{
LOG((TL_ERROR, "EnumerateStreams - bad pointer"));
return E_POINTER;
}
//
// create the enumerator
//
CComObject< CTapiEnum< IEnumStream, ITStream, &IID_IEnumStream > > * p;
hr = CComObject< CTapiEnum< IEnumStream, ITStream, &IID_IEnumStream > >
::CreateInstance( &p );
if (S_OK != hr)
{
LOG((TL_ERROR, "EnumerateStreams - could not create enum" ));
return hr;
}
Lock();
//
// initialize it with our Stream array
//
p->Initialize( m_StreamArray );
Unlock();
//
// return it
//
*ppEnumStream = p;
LOG((TL_TRACE, "EnumerateStreams - exit - return %lx", hr));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//
// get_Streams
//
// pStreams - returned collection
//
// collection of streams - like enumeratestreams
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
STDMETHODIMP
CPhoneMSPCall::get_Streams(
VARIANT * pStreams
)
{
HRESULT hr = S_OK;
IDispatch * pDisp;
LOG((TL_TRACE, "get_Streams - enter"));
if (TAPIIsBadWritePtr( pStreams, sizeof(VARIANT) ) )
{
LOG((TL_ERROR, "get_Streams - bad pointer"));
return E_POINTER;
}
CComObject< CTapiCollection< ITStream > > * p;
CComObject< CTapiCollection< ITStream > >::CreateInstance( &p );
if (NULL == p)
{
LOG((TL_ERROR, "get_Streams - could not create collection" ));
return E_OUTOFMEMORY;
}
Lock();
// initialize
hr = p->Initialize( m_StreamArray );
Unlock();
if (S_OK != hr)
{
LOG((TL_ERROR, "get_Streams - could not initialize collection" ));
delete p;
return hr;
}
//
// get the IDispatch interface
//
hr = p->_InternalQueryInterface(
IID_IDispatch,
(void **) &pDisp
);
if (S_OK != hr)
{
LOG((TL_ERROR, "get_Streams - could not get IDispatch interface" ));
delete p;
return hr;
}
//
// put it in the variant
//
VariantInit(pStreams);
pStreams->vt = VT_DISPATCH;
pStreams->pdispVal = pDisp;
LOG((TL_TRACE, "get_Streams - exit - return %lx", hr));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
STDMETHODIMP
CPhoneMSPCall::Initialize(
CPhoneMSP * pPhoneMSP
)
{
HRESULT hr;
ITStream * pStream;
ITPhoneMSPCallPrivate * pCallPrivate;
hr = QueryInterface(
IID_ITPhoneMSPCallPrivate,
(void**)&pCallPrivate
);
if ( !SUCCEEDED(hr) )
{
LOG((TL_ERROR, "Initialize - out of memory" ));
return E_OUTOFMEMORY;
}
m_t3Phone.hPhone = NULL;
m_t3Phone.pMSPCall = pCallPrivate;
m_pPhoneMSP = pPhoneMSP;
hr = CStream::InternalCreateStream(
TAPIMEDIATYPE_AUDIO,
TD_RENDER,
pCallPrivate,
&pStream
);
if ( !SUCCEEDED(hr) )
{
pCallPrivate->Release();
LOG((TL_ERROR, "Initialize - out of memory" ));
return E_OUTOFMEMORY;
}
AddStream( pStream );
pStream->Release();
hr = CStream::InternalCreateStream(
TAPIMEDIATYPE_AUDIO,
TD_CAPTURE,
pCallPrivate,
&pStream
);
if ( !SUCCEEDED(hr) )
{
pCallPrivate->Release();
LOG((TL_ERROR, "Initialize - out of memory" ));
return E_OUTOFMEMORY;
}
AddStream( pStream );
pStream->Release();
pCallPrivate->Release();
return S_OK;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
void
CPhoneMSPCall::FinalRelease()
{
m_StreamArray.Shutdown();
m_TerminalArray.Shutdown();
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
void
CPhoneMSPCall::AddStream( ITStream * pStream )
{
Lock();
m_StreamArray.Add( pStream );
Unlock();
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
void
CPhoneMSPCall::AddTerminal( ITTerminalPrivate * pTerminal )
{
Lock();
m_TerminalArray.Add( pTerminal );
pTerminal->SetMSPCall( this );
if ( PHONEMSP_CONNECTED == m_State )
{
}
Unlock();
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
void
CPhoneMSPCall::RemoveTerminal( ITTerminalPrivate * pTerminal )
{
BOOL bRemoved;
Lock();
bRemoved = m_TerminalArray.Remove( pTerminal );
if ( bRemoved && (PHONEMSP_DISCONNECTED == m_State) )
{
pTerminal->SetMSPCall( NULL );
}
Unlock();
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
STDMETHODIMP
CPhoneMSPCall::OnConnect()
{
HRESULT hr = S_OK;
int iSize, iCount;
DWORD dwHookSwitchDev = 0;
HPHONEAPP hPhoneApp = NULL;
DWORD dwPhoneID = 0;
DWORD dwAPIVersion;
LOG((TL_TRACE, "OnConnect - enter"));
Lock();
m_State = PHONEMSP_CONNECTED;
iSize = m_TerminalArray.GetSize();
if ( 0 == iSize )
{
Unlock();
return S_OK;
}
for ( iCount = 0; iCount < iSize; iCount++ )
{
DWORD dwHoldHookSwitchDev;
m_TerminalArray[iCount]->GetHookSwitchDev( &dwHoldHookSwitchDev );
dwHookSwitchDev |= dwHoldHookSwitchDev;
}
m_TerminalArray[0]->GetHPhoneApp( &hPhoneApp );
m_TerminalArray[0]->GetPhoneID( &dwPhoneID );
m_TerminalArray[0]->GetAPIVersion( &dwAPIVersion );
if (m_t3Phone.hPhone == NULL)
{
hr = PhoneOpen(
hPhoneApp,
dwPhoneID,
&m_t3Phone,
dwAPIVersion,
PHONEPRIVILEGE_OWNER
);
if ( !SUCCEEDED(hr) )
{
}
}
ASYNCEVENTMSG Msg;
Msg.Msg = PRIVATE_PHONESETHOOKSWITCH;
Msg.TotalSize = sizeof (ASYNCEVENTMSG);
Msg.hDevice = (ULONG_PTR) this;
Msg.Param1 = PHONEHOOKSWITCHMODE_MICSPEAKER;
Msg.Param2 = dwHookSwitchDev;
AddRef();
QueueCallbackEvent( &Msg );
Unlock();
LOG((TL_TRACE,hr, "OnConnect - exit"));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
STDMETHODIMP
CPhoneMSPCall::OnDisconnect()
{
HRESULT hr = S_OK;
LOG((TL_TRACE, "OnDisconnect - enter"));
Lock();
if (m_t3Phone.hPhone != NULL)
{
hr = PhoneClose(m_t3Phone.hPhone);
m_t3Phone.hPhone = NULL;
}
m_State = PHONEMSP_DISCONNECTED;
Unlock();
LOG((TL_TRACE,hr, "OnDisconnect - exit"));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
STDMETHODIMP
CPhoneMSPCall::SelectTerminal( ITTerminalPrivate * pTerminal )
{
ITTerminal * pITTerminal;
HRESULT hr;
hr = pTerminal->QueryInterface(
IID_ITTerminal,
(void**) &pITTerminal
);
if ( SUCCEEDED(hr) )
{
hr = m_pPhoneMSP->VerifyTerminal( pITTerminal );
pITTerminal->Release();
if ( SUCCEEDED(hr) )
{
AddTerminal( pTerminal );
}
}
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
STDMETHODIMP
CPhoneMSPCall::UnselectTerminal( ITTerminalPrivate * pTerminal )
{
RemoveTerminal( pTerminal );
return S_OK;
}
STDMETHODIMP
CPhoneMSPCall::GetGain(long *pVal, DWORD dwHookSwitch)
{
HRESULT hr;
hr = PhoneGetGain(
m_t3Phone.hPhone,
dwHookSwitch,
(DWORD *)pVal
);
if ( ((long)hr) > 0 )
{
hr = WaitForPhoneReply( hr );
}
return hr;
}
STDMETHODIMP
CPhoneMSPCall::PutGain(long newVal, DWORD dwHookSwitch)
{
HRESULT hr;
hr = PhoneSetGain(
m_t3Phone.hPhone,
dwHookSwitch,
newVal
);
if ( ((long)hr) > 0 )
{
hr = WaitForPhoneReply( hr );
}
return hr;
}
STDMETHODIMP
CPhoneMSPCall::GetVolume(long *pVal, DWORD dwHookSwitch)
{
HRESULT hr;
hr = PhoneGetVolume(
m_t3Phone.hPhone,
dwHookSwitch,
(DWORD *)pVal
);
if ( ((long)hr) > 0 )
{
hr = WaitForPhoneReply( hr );
}
return hr;
}
STDMETHODIMP
CPhoneMSPCall::PutVolume(long newVal, DWORD dwHookSwitch)
{
HRESULT hr;
hr = PhoneSetVolume(
m_t3Phone.hPhone,
dwHookSwitch,
newVal
);
if ( ((long)hr) > 0 )
{
hr = WaitForPhoneReply( hr );
}
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
void
CPhoneMSPCall::HandlePrivateHookSwitch( PASYNCEVENTMSG pParams )
{
CPhoneMSPCall * pMSPCall;
HRESULT hr;
pMSPCall = (CPhoneMSPCall *)(pParams->hDevice);
hr = PhoneSetHookSwitch(
pMSPCall->m_t3Phone.hPhone,
pParams->Param2,
pParams->Param1
);
if ( SUCCEEDED(hr) )
{
hr = WaitForPhoneReply(hr);
}
pMSPCall->Release();
}