windows-nt/Source/XPSP1/NT/net/tapi/skywalker/tapi3/terminal.cpp

896 lines
18 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1997 - 1999 Microsoft Corporation
Module Name:
terminal.cpp
Abstract:
Implementation of terminals object for TAPI 3.0, that are
not handled by the terminal manager.
currently there are these terminals:
phone
Audio in and Audio out terminal associated with a phone device.
Each phone device can have up to 3 types of devices -
handset, headset, and speakerphone. So, a single phone device
can have 6 associated terminals!
Author:
mquinton - 4/17/97
Notes:
optional-notes
Revision History:
--*/
#include "stdafx.h"
HRESULT
WaitForPhoneReply(
DWORD dwID
);
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// CTerminal is the base terminal object that all other terminals are
// derived from. It implements the ITTerminal methods.
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// ITTerminal methods
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// get_Name
// Alloc and copy the name. The app is responsible for
// freeing
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
STDMETHODIMP
CTerminal::get_Name(
BSTR * ppName
)
{
LOG((TL_TRACE, "get_Name - enter" ));
if (TAPIIsBadWritePtr( ppName, sizeof (BSTR) ) )
{
LOG((TL_ERROR, "getName - bad pointer"));
return E_POINTER;
}
Lock();
*ppName = SysAllocString( m_pName );
Unlock();
if ( ( NULL == *ppName ) && ( NULL != m_pName ) )
{
LOG((TL_ERROR, "get_Name - SysAllocString Failed" ));
return E_OUTOFMEMORY;
}
LOG((TL_TRACE, "get_Name - exit - return S_OK" ));
return S_OK;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// get_State
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
STDMETHODIMP
CTerminal::get_State(
TERMINAL_STATE * pTerminalState
)
{
LOG((TL_TRACE, "get_State - enter" ));
if (TAPIIsBadWritePtr( pTerminalState, sizeof(TERMINAL_STATE) ) )
{
LOG((TL_ERROR, "get_State - bad pointer"));
return E_POINTER;
}
Lock();
*pTerminalState = m_State;
Unlock();
LOG((TL_TRACE, "get_State - exit - return SUCCESS" ));
return S_OK;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// get_TerminalType
// By definition, TAPI terminals are static
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
STDMETHODIMP
CTerminal::get_TerminalType(
TERMINAL_TYPE * pType
)
{
LOG((TL_TRACE, "get_TerminalType - enter" ));
if ( TAPIIsBadWritePtr( pType, sizeof( TERMINAL_TYPE ) ) )
{
LOG((TL_ERROR, "get_TerminalType - bad pointer"));
return E_POINTER;
}
Lock();
*pType = m_TerminalType;
Unlock();
LOG((TL_TRACE, "get_TerminalType - exit - return S_OK" ));
return S_OK;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// get_TerminalClass
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
STDMETHODIMP
CTerminal::get_TerminalClass(
BSTR * pTerminalClass
)
{
HRESULT hr = S_OK;
CLSID clsid;
LPWSTR pClass = NULL;
LOG((TL_TRACE, "get_TerminalClass - enter" ));
if ( TAPIIsBadWritePtr( pTerminalClass, sizeof( BSTR ) ) )
{
LOG((TL_ERROR, "get_TerminalClass - bad pointer"));
return E_POINTER;
}
Lock();
hr = StringFromIID(
m_Class,
&pClass
);
Unlock();
if (S_OK != hr)
{
return hr;
}
*pTerminalClass = SysAllocString( pClass );
if ( ( NULL == *pTerminalClass ) && ( NULL != pClass ) )
{
LOG((TL_ERROR, "get_TerminalClass - SysAllocString Failed" ));
return E_OUTOFMEMORY;
}
CoTaskMemFree( pClass );
LOG((TL_TRACE, "get_TerminalClass - exit - return SUCCESS" ));
return S_OK;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// get_MediaType
//
// returns the supported mediatype BSTR associated with this terminal.
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
STDMETHODIMP
CTerminal::get_MediaType(
long * plMediaType
)
{
if ( TAPIIsBadWritePtr( plMediaType, sizeof(long) ) )
{
LOG((TL_ERROR, "get_MediaType - inval pointer"));
return E_POINTER;
}
*plMediaType = m_lMediaType;
return S_OK;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// get_Direction
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
STDMETHODIMP
CTerminal::get_Direction(
TERMINAL_DIRECTION * pTerminalDirection
)
{
if (TAPIIsBadWritePtr( pTerminalDirection, sizeof( TERMINAL_DIRECTION ) ) )
{
LOG((TL_ERROR, "get_Direction - bad pointer"));
return E_POINTER;
}
Lock();
*pTerminalDirection = m_Direction;
Unlock();
return S_OK;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// GetTerminalNameFromPhoneCaps
//
// Creates a name for a phone device terminal based on the phone
// caps
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
PWSTR
GetTerminalNameFromPhoneCaps(
LPPHONECAPS pPhoneCaps,
DWORD dwHookSwitchDev,
DWORD dwPhoneID
)
{
PWSTR pszName;
PWSTR pszHookSwitchDevName = NULL;
//
// load the appropriate string to describe
// the hookswitch device
//
switch (dwHookSwitchDev)
{
case PHONEHOOKSWITCHDEV_SPEAKER:
{
pszHookSwitchDevName = MyLoadString( IDS_SPEAKERTERMINAL );
break;
}
case PHONEHOOKSWITCHDEV_HANDSET:
{
pszHookSwitchDevName = MyLoadString( IDS_HANDSETTERMINAL );
break;
}
case PHONEHOOKSWITCHDEV_HEADSET:
{
pszHookSwitchDevName = MyLoadString( IDS_HEADSETTERMINAL );
break;
}
default:
{
return NULL;
}
}
if ( NULL == pszHookSwitchDevName )
{
return NULL;
}
//
// if the sp supplies a name, use it
//
if ( 0 != pPhoneCaps->dwPhoneNameSize )
{
pszName = (PWSTR) ClientAlloc(
( pPhoneCaps->dwPhoneNameSize +
lstrlenW( pszHookSwitchDevName ) +
32 ) * sizeof(WCHAR)
);
if (NULL == pszName)
{
ClientFree( pszHookSwitchDevName );
return NULL;
}
CopyMemory(
pszName,
( ( (LPBYTE)pPhoneCaps ) + pPhoneCaps->dwPhoneNameOffset ),
pPhoneCaps->dwPhoneNameSize
);
}
else
{
PWSTR pszTempName;
//
// else create a name
//
pszTempName = MyLoadString( IDS_PHONEDEVICE );
if ( NULL == pszTempName )
{
ClientFree( pszHookSwitchDevName );
return NULL;
}
pszName = (PWSTR) ClientAlloc(
(lstrlenW( pszTempName ) +
lstrlenW( pszHookSwitchDevName ) +
32 ) * sizeof(WCHAR)
);
if (NULL == pszName)
{
ClientFree( pszHookSwitchDevName );
ClientFree( pszTempName );
return NULL;
}
wsprintfW(
pszName,
L"%s %d",
pszTempName,
dwPhoneID
);
ClientFree( pszTempName );
}
//
// put them together
//
lstrcatW(
pszName,
L" - "
);
lstrcatW(
pszName,
pszHookSwitchDevName
);
ClientFree( pszHookSwitchDevName );
return pszName;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//
// CTerminal::Create
//
// Static function to create an audio in terminal related to a phone
// device.
//
// pAddress
// Owning address
//
// dwPhoneID
// tapi 2 phone device ID related to this terminal
//
// pPhoneCaps
// PHONEDEVCAPS of the phone device
//
// dwHookSwitchDev
// PHONEHOOKSWITCHDEV_ bit of this phone device
//
// ppTerminal
// return the terminal here!
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
HRESULT
CTerminal::Create(
HPHONEAPP hPhoneApp,
DWORD dwPhoneID,
LPPHONECAPS pPhoneCaps,
DWORD dwHookSwitchDev,
TERMINAL_DIRECTION td,
DWORD dwAPIVersion,
ITTerminal ** ppTerminal
)
{
HRESULT hr = S_OK;
CComObject< CTerminal > * p;
//
// create CTerminal
//
hr = CComObject< CTerminal >::CreateInstance( &p );
if (!SUCCEEDED(hr))
{
LOG((TL_ERROR, "CreateInstance for Phone failed - %lx", hr));
return hr;
}
//
// save stuff
//
p->m_dwHookSwitchDev = dwHookSwitchDev;
p->m_dwPhoneID = dwPhoneID;
p->m_hPhoneApp = hPhoneApp;
p->m_Direction = td;
p->m_dwAPIVersion = dwAPIVersion;
//
// class depends on which hookswitchdev this is
//
switch( dwHookSwitchDev )
{
case PHONEHOOKSWITCHDEV_HANDSET:
p->m_Class = CLSID_HandsetTerminal;
break;
case PHONEHOOKSWITCHDEV_HEADSET:
p->m_Class = CLSID_HeadsetTerminal;
break;
case PHONEHOOKSWITCHDEV_SPEAKER:
p->m_Class = CLSID_SpeakerphoneTerminal;
break;
default:
break;
}
//
// create a name
//
p->m_pName = GetTerminalNameFromPhoneCaps(
pPhoneCaps,
dwHookSwitchDev,
dwPhoneID
);
//
// return the created terminal
//
p->AddRef();
*ppTerminal = p;
#if DBG
p->m_pDebug = (PWSTR) ClientAlloc( 1 );
#endif
return S_OK;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
STDMETHODIMP
CTerminal::get_Gain(long *pVal)
{
HRESULT hr;
ITPhoneMSPCallPrivate * pMSPCall;
LOG((TL_TRACE, "get_Gain - Enter"));
if ( TAPIIsBadWritePtr( pVal, sizeof(LONG) ) )
{
LOG((TL_ERROR, "get_Gain - bad pointer"));
return E_POINTER;
}
Lock();
if ( NULL == m_pMSPCall )
{
Unlock();
return TAPI_E_NOTERMINALSELECTED;
}
pMSPCall = m_pMSPCall;
pMSPCall->AddRef();
Unlock();
hr = pMSPCall->GetGain( pVal, m_dwHookSwitchDev );
pMSPCall->Release();
LOG((TL_TRACE, "get_Gain - Exit - return %lx", hr));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
STDMETHODIMP
CTerminal::put_Gain(long newVal)
{
HRESULT hr;
ITPhoneMSPCallPrivate * pMSPCall;
LOG((TL_TRACE, "put_Gain - Enter"));
Lock();
if ( NULL == m_pMSPCall )
{
Unlock();
return TAPI_E_NOTERMINALSELECTED;
}
pMSPCall = m_pMSPCall;
pMSPCall->AddRef();
Unlock();
hr = pMSPCall->PutGain( newVal, m_dwHookSwitchDev );
pMSPCall->Release();
LOG((TL_TRACE, "put_Gain - Exit - return %lx", hr));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
STDMETHODIMP
CTerminal::get_Balance(long *pVal)
{
LOG((TL_TRACE, "get_Balance - Enter"));
LOG((TL_TRACE, "get_Balance - Exit - return TAPI_E_NOTSUPPORTED"));
// not suppported
return TAPI_E_NOTSUPPORTED;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
STDMETHODIMP
CTerminal::put_Balance(long newVal)
{
LOG((TL_TRACE, "put_Balance - Enter"));
LOG((TL_TRACE, "put_Balance - Exit - return TAPI_E_NOTSUPPORTED"));
// not supported
return TAPI_E_NOTSUPPORTED;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
STDMETHODIMP
CTerminal::get_Volume(long *pVal)
{
HRESULT hr;
ITPhoneMSPCallPrivate * pMSPCall;
LOG((TL_TRACE, "get_Volume - Enter"));
if ( TAPIIsBadWritePtr( pVal, sizeof( long ) ) )
{
LOG((TL_ERROR, "get_Volume - bad pointer"));
return E_POINTER;
}
Lock();
if ( NULL == m_pMSPCall )
{
Unlock();
return TAPI_E_NOTERMINALSELECTED;
}
pMSPCall = m_pMSPCall;
pMSPCall->AddRef();
Unlock();
hr = pMSPCall->GetVolume( pVal, m_dwHookSwitchDev );
pMSPCall->Release();
LOG((TL_TRACE, "get_Volume - Exit - return %lx", hr));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
STDMETHODIMP
CTerminal::put_Volume(long newVal)
{
HRESULT hr;
ITPhoneMSPCallPrivate * pMSPCall;
LOG((TL_TRACE, "put_Volume - Enter"));
Lock();
if ( NULL == m_pMSPCall )
{
Unlock();
return TAPI_E_NOTERMINALSELECTED;
}
pMSPCall = m_pMSPCall;
pMSPCall->AddRef();
Unlock();
hr = pMSPCall->PutVolume( newVal, m_dwHookSwitchDev );
pMSPCall->Release();
LOG((TL_TRACE, "put_Volume - Exit - return %lx", hr));
return hr;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
STDMETHODIMP
CTerminal::GetHookSwitchDev(DWORD * pdwHookSwitchDev)
{
Lock();
*pdwHookSwitchDev = m_dwHookSwitchDev;
Unlock();
return S_OK;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
STDMETHODIMP
CTerminal::GetPhoneID(DWORD * pdwPhoneID)
{
Lock();
*pdwPhoneID = m_dwPhoneID;
Unlock();
return S_OK;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
STDMETHODIMP
CTerminal::GetHPhoneApp(HPHONEAPP * phPhoneApp)
{
Lock();
*phPhoneApp = m_hPhoneApp;
Unlock();
return S_OK;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
STDMETHODIMP
CTerminal::GetAPIVersion(DWORD * pdwAPIVersion)
{
Lock();
*pdwAPIVersion = m_dwAPIVersion;
Unlock();
return S_OK;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
STDMETHODIMP
CTerminal::SetMSPCall(ITPhoneMSPCallPrivate * pPhoneMSPCall)
{
Lock();
m_pMSPCall = pPhoneMSPCall;
if ( NULL != m_pMSPCall )
{
m_State = TS_INUSE;
}
else
{
m_State = TS_NOTINUSE;
}
Unlock();
return S_OK;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
void
CTerminal::FinalRelease()
{
if (NULL != m_pName)
{
ClientFree( m_pName );
}
#if DBG
if( m_pDebug != NULL )
{
ClientFree( m_pDebug );
m_pDebug = NULL;
}
#endif
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// CreateTerminalName
//
// Creates a terminal name for
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
PWSTR
CreateTerminalName(
CAddress * pAddress,
DWORD dwType,
long lMediaType
)
{
PWSTR pName;
WCHAR szTerminal[256];
WCHAR szMediaType[256];
DWORD dwSize;
//
// create the name
//
// first load the string "Terminal"
//
szTerminal[0] = L'\0';
szMediaType[0] = L'\0';
::LoadStringW(_Module.GetResourceInstance(), IDS_TERMINAL, szTerminal, 256);
dwSize = lstrlenW( szTerminal ) * sizeof (WCHAR);
switch (dwType)
{
case 0:
break;
case 1:
if ( LINEMEDIAMODE_DATAMODEM == lMediaType)
{
::LoadStringW(_Module.GetResourceInstance(), IDS_DATAMODEM, szMediaType, 256);
}
else if ( LINEMEDIAMODE_G3FAX == lMediaType)
{
::LoadStringW(_Module.GetResourceInstance(), IDS_G3FAX, szMediaType, 256);
}
dwSize += (lstrlenW( szMediaType ) * sizeof ( WCHAR ));
break;
default:
break;
}
//
// alloc enough memory for the name
//
dwSize += (lstrlenW( pAddress->GetAddressName() ) * sizeof(WCHAR));
dwSize += 32;
pName = (PWSTR) ClientAlloc( dwSize );
if (NULL == pName)
{
return NULL;
}
//
// terminal name should look like:
// "<addressname> (mediatype) Terminal"
//
lstrcpyW(
pName,
pAddress->GetAddressName()
);
lstrcatW(
pName,
L" "
);
if (dwType == 1)
{
lstrcatW(
pName,
szMediaType
);
lstrcatW(
pName,
L" "
);
}
lstrcatW(
pName,
szTerminal
);
return pName;
}