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

1666 lines
47 KiB
C++

/*++
Copyright (c) 1997-1999 Microsoft Corporation
Module Name:
Address.h
Abstract:
Declaration of the CAddress
Author:
mquinton - 06/12/97
Notes:
Revision History:
--*/
#ifndef __ADDRESS_H_
#define __ADDRESS_H_
#include "resource.h" // main symbols
#ifdef USE_PHONEMSP
#include "terminal.h"
#endif USE_PHONEMSP
#include "ObjectSafeImpl.h"
#include <mspenum.h> // for CSafeComEnum
class CAddress;
class CTerminal;
class CTAPI;
extern CHashTable * gpLineHashTable;
extern CHashTable * gpHandleHashTable;
extern void RemoveHandleFromHashTable(ULONG_PTR Handle);
// address flag defines
#define ADDRESSFLAG_MSP 0x00000001
#define ADDRESSFLAG_WAVEOUTDEVICE 0x00000002
#define ADDRESSFLAG_WAVEINDEVICE 0x00000004
#define ADDRESSFLAG_PHONEDEVICE 0x00000008
#define ADDRESSFLAG_DATAMODEM 0x00000010
#define ADDRESSFLAG_PRIVATEOBJECTS 0x00000020
#define ADDRESSFLAG_CALLHUB 0x00000100
#define ADDRESSFLAG_CALLHUBTRACKING 0x00000200
#define ADDRESSFLAG_WAVEFULLDUPLEX 0x00000400
#define ADDRESSFLAG_NOCALLHUB 0x00010000
#define ADDRESSFLAG_DEVSTATECHANGE 0x00020000
#define ADDRESSFLAG_ADDRESSSTATECHANGE 0x00040000
#define ADDRESSFLAG_DEVCAPSCHANGE 0x00080000
#define ADDRESSFLAG_ADDRESSCAPSCHANGE 0x00100000
#define ADDRESSFLAG_AMREL (ADDRESSFLAG_MSP | ADDRESSFLAG_WAVEINDEVICE | ADDRESSFLAG_WAVEOUTDEVICE | ADDRESSFLAG_WAVEFULLDUPLEX)
#define CALLHUBSUPPORT_FULL 1
#define CALLHUBSUPPORT_NONE 3
#define CALLHUBSUPPORT_UNKNOWN 4
// Status message defines, set by LineSetStatusMessages( )
#define ALL_LINEDEVSTATE_MESSAGES (LINEDEVSTATE_OTHER | \
LINEDEVSTATE_RINGING | \
LINEDEVSTATE_CONNECTED | \
LINEDEVSTATE_DISCONNECTED | \
LINEDEVSTATE_MSGWAITON | \
LINEDEVSTATE_MSGWAITOFF | \
LINEDEVSTATE_INSERVICE | \
LINEDEVSTATE_OUTOFSERVICE | \
LINEDEVSTATE_MAINTENANCE | \
LINEDEVSTATE_OPEN | \
LINEDEVSTATE_CLOSE | \
LINEDEVSTATE_NUMCALLS | \
LINEDEVSTATE_NUMCOMPLETIONS | \
LINEDEVSTATE_TERMINALS | \
LINEDEVSTATE_ROAMMODE | \
LINEDEVSTATE_BATTERY | \
LINEDEVSTATE_SIGNAL | \
LINEDEVSTATE_DEVSPECIFIC | \
LINEDEVSTATE_REINIT | \
LINEDEVSTATE_LOCK | \
LINEDEVSTATE_CAPSCHANGE | \
LINEDEVSTATE_CONFIGCHANGE | \
LINEDEVSTATE_TRANSLATECHANGE | \
LINEDEVSTATE_COMPLCANCEL | \
LINEDEVSTATE_REMOVED)
#define ALL_LINEADDRESSSTATE_MESSAGES (LINEADDRESSSTATE_OTHER | \
LINEADDRESSSTATE_DEVSPECIFIC | \
LINEADDRESSSTATE_INUSEZERO | \
LINEADDRESSSTATE_INUSEONE | \
LINEADDRESSSTATE_INUSEMANY | \
LINEADDRESSSTATE_NUMCALLS | \
LINEADDRESSSTATE_FORWARD | \
LINEADDRESSSTATE_TERMINALS | \
LINEADDRESSSTATE_CAPSCHANGE)
/////////////////////////////////////////////////////////////////
// Intermediate classes used for DISPID encoding
template <class T>
class ITAddress2Vtbl : public ITAddress2
{
};
template <class T>
class ITAddressCapabilitiesVtbl : public ITAddressCapabilities
{
};
template <class T>
class ITMediaSupportVtbl : public ITMediaSupport
{
};
template <class T>
class ITAddressTranslationVtbl : public ITAddressTranslation
{
};
template <class T>
class ITLegacyAddressMediaControl2Vtbl : public ITLegacyAddressMediaControl2
{
};
/////////////////////////////////////////////////////////////////////////////
// CEventMasks
class CEventMasks
{
public:
CEventMasks()
{
m_dwTapiObjectMask = EM_NOSUBEVENTS;
m_dwAddressMask = EM_NOSUBEVENTS;
m_dwCallNotificationMask = EM_NOSUBEVENTS;
m_dwCallStateMask = EM_NOSUBEVENTS;
m_dwCallMediaMask = EM_NOSUBEVENTS;
m_dwCallHubMask = EM_NOSUBEVENTS;
m_dwCallInfoChangeMask = EM_NOSUBEVENTS;
m_dwQOSEventMask = EM_NOSUBEVENTS;
m_dwFileTerminalMask = EM_NOSUBEVENTS;
m_dwPrivateMask = EM_NOSUBEVENTS;
m_dwAddressDevSpecificMask = EM_NOSUBEVENTS;
m_dwPhoneDevSpecificMask = EM_NOSUBEVENTS;
}
~CEventMasks()
{
}
DECLARE_TRACELOG_CLASS(CEventMasks)
private:
//
// Event masks
// Some event come from MSP:
// TE_ADDRESS, TE_CALLMEDIA, TE_FILETERMINAL
//
DWORD m_dwTapiObjectMask; // TE_TAPIOBJECT
DWORD m_dwAddressMask; // TE_ADDRESS MSP
DWORD m_dwCallNotificationMask; // TE_CALLNOTIFICATION
DWORD m_dwCallStateMask; // TE_CALLSTATE
DWORD m_dwCallMediaMask; // TE_CALLMEDIA MSP
DWORD m_dwCallHubMask; // TE_CALLHUB
DWORD m_dwCallInfoChangeMask; // TE_CALLINFOCHANGE
DWORD m_dwQOSEventMask; // TE_QOSEVENT
DWORD m_dwFileTerminalMask; // TE_FILETERMINAL MSP
DWORD m_dwPrivateMask; // TE_PRIVATE MSP
DWORD m_dwAddressDevSpecificMask; // TE_ADDRESSDEVSPECIFIC
DWORD m_dwPhoneDevSpecificMask; // TE_PHONEDEVSPECIFIC
public:
// Constants
static const DWORD EM_ALLSUBEVENTS = 0x0FFFFFFF;
static const DWORD EM_NOSUBEVENTS = 0x00000000;
static const DWORD EM_ALLEVENTS = (DWORD)(-1);
public:
// Public methods
HRESULT SetSubEventFlag(
DWORD dwEvent, // The event
DWORD dwFlag, // The flag that should be setted
BOOL bEnable
);
HRESULT GetSubEventFlag(
DWORD dwEvent, // The event
DWORD dwFlag, // The flag that should be setted
BOOL* pEnable
);
DWORD GetSubEventMask(
TAPI_EVENT TapiEvent
);
BOOL IsSubEventValid(
TAPI_EVENT TapiEvent,
DWORD dwSubEvent,
BOOL bAcceptAllSubEvents,
BOOL bCallLevel
);
HRESULT CopyEventMasks(
CEventMasks* pEventMasks
);
HRESULT SetTapiSrvAddressEventMask(
IN HLINE hLine
);
HRESULT SetTapiSrvCallEventMask(
IN HCALL hCall
);
private:
ULONG64 GetTapiSrvEventMask(
IN BOOL bCallLevel);
DWORD GetTapiSrvLineStateMask();
DWORD GetTapiSrvAddrStateMask();
};
/////////////////////////////////////////////////////////////////////////////
// CAddress
class CAddress :
public CTAPIComObjectRoot<CAddress>,
public IDispatchImpl<ITAddress2Vtbl<CAddress>, &IID_ITAddress2, &LIBID_TAPI3Lib>,
public IDispatchImpl<ITAddressCapabilitiesVtbl<CAddress>, &IID_ITAddressCapabilities, &LIBID_TAPI3Lib>,
public IDispatchImpl<ITMediaSupportVtbl<CAddress>, &IID_ITMediaSupport, &LIBID_TAPI3Lib>,
public IDispatchImpl<ITAddressTranslationVtbl<CAddress>, &IID_ITAddressTranslation, &LIBID_TAPI3Lib>,
public IDispatchImpl<ITLegacyAddressMediaControl2Vtbl<CAddress>, &IID_ITLegacyAddressMediaControl2, &LIBID_TAPI3Lib>,
public CObjectSafeImpl
{
public:
CAddress() : m_pTAPI(NULL),
m_hLineApp(NULL),
m_hLine(NULL),
#ifdef USE_PHONEMSP
m_hPhoneApp(NULL),
#endif USE_PHONEMSP
m_dwAPIVersion(0),
m_dwDeviceID(0),
m_dwAddressID(0),
m_dwMediaModesSupported(0),
m_szAddress(NULL),
m_szAddressName(NULL),
m_szProviderName(NULL),
m_pMSPAggAddress(NULL),
m_pPrivate(NULL),
m_hMSPEvent(NULL),
m_hWaitEvent(NULL),
m_MSPContext(0),
m_dwAddressFlags(0),
m_fEnableCallHubTrackingOnLineOpen(TRUE),
m_bTapiSignaledShutdown(FALSE)
{
LOG((TL_TRACE, "CAddress[%p] - enter", this));
LOG((TL_TRACE, "CAddress - exit"));
}
~CAddress()
{
LOG((TL_TRACE, "~CAddress[%p] - enter", this));
LOG((TL_TRACE, "~CAddress - exit"));
}
DECLARE_DEBUG_ADDREF_RELEASE(CAddress)
DECLARE_QI()
DECLARE_MARSHALQI(CAddress)
DECLARE_TRACELOG_CLASS(CAddress)
BEGIN_COM_MAP(CAddress)
// COM_INTERFACE_ENTRY_FUNC(IID_IDispatch, 0, IDispatchQI)
COM_INTERFACE_ENTRY2(IDispatch, ITAddress2)
COM_INTERFACE_ENTRY(ITAddress)
COM_INTERFACE_ENTRY(ITAddress2)
COM_INTERFACE_ENTRY(ITMediaSupport)
COM_INTERFACE_ENTRY(ITAddressCapabilities)
COM_INTERFACE_ENTRY(ITAddressTranslation)
COM_INTERFACE_ENTRY(ITLegacyAddressMediaControl)
COM_INTERFACE_ENTRY(ITLegacyAddressMediaControl2)
COM_INTERFACE_ENTRY(IObjectSafety)
COM_INTERFACE_ENTRY_AGGREGATE_BLIND(m_pMSPAggAddress)
COM_INTERFACE_ENTRY_FUNC(IID_IMarshal, 0, IMarshalQI)
COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pFTM)
COM_INTERFACE_ENTRY_AGGREGATE_BLIND(m_pPrivate)
END_COM_MAP()
void FinalRelease();
private:
// tapi info
ITTAPI * m_pTAPI;
HLINEAPP m_hLineApp;
HLINE m_hLine;
#ifdef USE_PHONEMSP
HPHONEAPP m_hPhoneApp;
#endif USE_PHONEMSP
// caps/info that we keep around
// because it is used often
DWORD m_dwAPIVersion;
DWORD m_dwDeviceID;
DWORD m_dwAddressID;
DWORD m_dwMediaModesSupported;
DWORD m_dwProviderID;
PWSTR m_szAddress;
PWSTR m_szAddressName;
PWSTR m_szProviderName;
// m_dwAddressFlags keeps some info about the address
// see ADDRESSFLAG_ constants above
DWORD m_dwAddressFlags;
// tapi structures - using caching scheme
// so these can be NULL
LPLINEADDRESSCAPS m_pAddressCaps;
LPLINEDEVCAPS m_pDevCaps;
// current address state
ADDRESS_STATE m_AddressState;
// msp for this address
IUnknown * m_pMSPAggAddress;
// event for msp to signal on event
HANDLE m_hMSPEvent;
HANDLE m_hWaitEvent;
// Create a context handle for MSP Callback
ULONG_PTR m_MSPContext;
// IUnk for the private object
IUnknown * m_pPrivate;
// TAPI terminals owned by this address
TerminalArray m_TerminalArray;
// calls currently on this address
CallInfoArrayNR m_CallArray;
// list of "addresslines"
PtrList m_AddressLinesPtrList;
// list of call notification cookies
LongList m_NotificationCookies;
// addressline used for callhubtracking
AddressLineStruct * m_pCallHubTrackingLine;
// if true, we will do LineSetCallHubTracking in FindOrOpenALine
// it is only false if the user has called SetCallHubTracking(FALSE)
// on this address
BOOL m_fEnableCallHubTrackingOnLineOpen;
//
// this flag, when set, signals that the tapi object has signaled shutdown
// it is currently used to synchronize creation of new calls and call
// cleanup performed on tapi shutdown
//
BOOL m_bTapiSignaledShutdown;
HRESULT UpdateAddressCaps();
HRESULT UpdateLineDevCaps();
ITMSPAddress * GetMSPAddress();
HRESULT GetPhoneArrayFromTapiAndPrune(
PhoneArray *pPhoneArray,
BOOL bPreferredOnly
);
public:
BOOL IsValidAddressLine(AddressLineStruct *pAddressLine, BOOL bAddref = FALSE);
HRESULT MSPEvent();
#ifdef USE_PHONEMSP
HRESULT CreatePhoneDeviceMSP(
IUnknown * pUnk,
HLINE hLine,
IUnknown ** ppMSPAggAddress
);
#endif USE_PHONEMSP
HRESULT CreateStaticTerminalArray( TerminalArray& StaticTermArray );
HRESULT CreateDynamicTerminalClassesList( TerminalClassPtrList * pList );
HRESULT CreateMSPCall(
MSP_HANDLE hCall,
DWORD dwReserved,
long lMediaType,
IUnknown * pOuterUnk,
IUnknown ** ppStreamControl
);
DWORD GetDeviceID(){ return m_dwDeviceID; }
DWORD GetAPIVersion(){ return m_dwAPIVersion; }
DWORD GetAddressID(){ return m_dwAddressID; }
HLINEAPP GetHLineApp(){ return m_hLineApp; }
#ifdef USE_PHONEMSP
HPHONEAPP GetHPhoneApp(){ return m_hPhoneApp; }
#endif USE_PHONEMSP
BOOL HasMSP(){ return (m_pMSPAggAddress?TRUE:FALSE); }
BOOL HasWaveDevice(){ return m_dwAddressFlags & (ADDRESSFLAG_WAVEINDEVICE | ADDRESSFLAG_WAVEOUTDEVICE | ADDRESSFLAG_WAVEFULLDUPLEX); }
BOOL HasFullDuplexWaveDevice(){ return m_dwAddressFlags & ADDRESSFLAG_WAVEFULLDUPLEX; }
BOOL HasPhoneDevice(){ return m_dwAddressFlags & ADDRESSFLAG_PHONEDEVICE; }
DWORD GetMediaModes(){ return m_dwMediaModesSupported; }
PWSTR GetAddressName(){ return m_szAddressName; }
BOOL IsSPCallHubTrackingAddress(){ return m_dwAddressFlags & ADDRESSFLAG_CALLHUBTRACKING; }
BOOL IsSPCallHubAddress(){ return m_dwAddressFlags & ADDRESSFLAG_CALLHUB; }
CTAPI * GetTapi(BOOL bAddRefTapi = FALSE);
BOOL HasPrivateObjects(){return m_dwAddressFlags & ADDRESSFLAG_PRIVATEOBJECTS;}
DWORD GetProviderID(){return m_dwProviderID;}
BOOL GetMediaMode( long lMediaType, DWORD * pdwMediaMode );
HRESULT ShutdownMSPCall( IUnknown * pStreamControl );
HRESULT InitializeWaveDeviceIDs( HLINE hLine );
HRESULT AddNotificationLine( AddressLineStruct * pLine )
{
HRESULT hr = S_OK;
Lock();
try
{
m_AddressLinesPtrList.push_back( (PVOID)pLine );
}
catch(...)
{
LOG((TL_ERROR, "AddNotificationLine - failed to add to m_AddressLinesPtrList list - alloc failure" ));
hr = E_OUTOFMEMORY;
}
Unlock();
return hr;
}
HRESULT RegisterNotificationCookie(long lCookie);
HRESULT RemoveNotificationCookie(long lCookie);
void UnregisterAllCookies();
void AddressOnTapiShutdown();
void AddTerminal( ITTerminal * pTerminal )
{
Lock();
m_TerminalArray.Add( pTerminal );
Unlock();
}
HRESULT
AddCallNotification(
DWORD dwPrivs,
DWORD dwMediaModes,
long lInstance,
PVOID * ppRegister
);
HRESULT
RemoveCallNotification(
PVOID pRegister
);
HRESULT
SetCallHubTracking(
BOOL bSet
);
DWORD DoesThisAddressSupportCallHubs( CCall * pCall );
HRESULT
FindOrOpenALine(
DWORD dwMediaModes,
AddressLineStruct ** ppAddressLine
);
HRESULT
MaybeCloseALine(
AddressLineStruct ** ppAddressLine
);
HRESULT
InternalCreateCall(
PWSTR pszDestAddress,
long lAddressType,
long lMediaType,
CALL_PRIVILEGE cp,
BOOL bNeedToNotify,
HCALL hCall,
BOOL bExpose,
CCall ** ppCall
);
HRESULT Initialize(
ITTAPI * pTAPI,
HLINEAPP hLineApp,
#ifdef USE_PHONEMSP
HPHONEAPP hPhoneApp,
#endif USE_PHONEMSP
DWORD dwAPIVersion,
DWORD dwDeviceID,
DWORD dwAddressID,
DWORD dwProviderID,
LPLINEDEVCAPS pDevCaps,
DWORD dwEventFilterMask
);
HRESULT
AddCall(
ITCallInfo * pCallInfo
);
HRESULT
RemoveCall(
ITCallInfo * pCallInfo
);
void InService( DWORD dwType );
void OutOfService( DWORD dwType );
void CapsChange( BOOL );
HRESULT SaveAddressName(LPLINEDEVCAPS);
void SetAddrCapBuffer( LPVOID pBuf );
void SetLineDevCapBuffer( LPVOID pBuf );
HRESULT ReceiveTSPData(
IUnknown * pCall,
LPBYTE pBuffer,
DWORD dwSize
);
HRESULT HandleSendTSPData( MSP_EVENT_INFO * pEvent );
HRESULT HandleMSPAddressEvent( MSP_EVENT_INFO * pEvent );
HRESULT HandleMSPCallEvent( MSP_EVENT_INFO * pEvent );
HRESULT HandleMSPFileTerminalEvent( MSP_EVENT_INFO * pEvent);
HRESULT HandleMSPTTSTerminalEvent( MSP_EVENT_INFO * pEvent);
HRESULT HandleMSPASRTerminalEvent( MSP_EVENT_INFO * pEvent);
HRESULT HandleMSPToneTerminalEvent( MSP_EVENT_INFO * pEvent);
HRESULT HandleMSPPrivateEvent( MSP_EVENT_INFO * pEvent );
HRESULT ReleaseEvent( MSP_EVENT_INFO * pEvent );
// ITMediaSupport methods
STDMETHOD(get_MediaTypes)(long * plMediaTypes);
STDMETHOD(QueryMediaType)(
long lMediaType,
VARIANT_BOOL * pbSupport
);
// ITAddress methods
STDMETHOD(get_State)(ADDRESS_STATE * pAddressState);
STDMETHOD(get_AddressName)(BSTR * ppName);
STDMETHOD(get_ServiceProviderName)(BSTR * ppName);
STDMETHOD(get_TAPIObject)(ITTAPI ** ppTapiObject);
STDMETHOD(CreateCall)(
BSTR lpszDestAddress,
long lAddressType,
long lMediaType,
ITBasicCallControl ** ppCall
);
STDMETHOD(get_Calls)(VARIANT * pVariant);
STDMETHOD(EnumerateCalls)(IEnumCall ** ppCallEnum);
STDMETHOD(CreateForwardInfoObject)(ITForwardInformation ** ppForwardInfo);
STDMETHOD(Forward)(
ITForwardInformation * pForwardInfo,
ITBasicCallControl * pCall
);
STDMETHOD(get_CurrentForwardInfo)(
ITForwardInformation ** ppForwardInfo
);
STDMETHOD(get_DialableAddress)(BSTR * pDialableAddress);
STDMETHOD(put_MessageWaiting)(VARIANT_BOOL fMessageWaiting);
STDMETHOD(get_MessageWaiting)(VARIANT_BOOL * pfMessageWaiting);
STDMETHOD(put_DoNotDisturb)(VARIANT_BOOL fDoNotDisturb);
STDMETHOD(get_DoNotDisturb)(VARIANT_BOOL * pfDoNotDisturb);
STDMETHOD(get_LineID)(long * plLineID);
STDMETHOD(get_AddressID)(long * plAddressID);
// ITAddress2 methods
STDMETHOD(get_Phones)(VARIANT * pPhones);
STDMETHOD(EnumeratePhones)(IEnumPhone ** ppEnumPhone);
STDMETHOD(get_PreferredPhones)(VARIANT * pPhones);
STDMETHOD(EnumeratePreferredPhones)(IEnumPhone ** ppEnumPhone);
STDMETHOD(GetPhoneFromTerminal)(
ITTerminal * pTerminal,
ITPhone ** ppPhone
);
STDMETHOD(get_EventFilter)(
TAPI_EVENT TapiEvent,
long lSubEvent,
VARIANT_BOOL* pEnable
);
STDMETHOD(put_EventFilter)(
TAPI_EVENT TapiEvent,
long lSubEvent,
VARIANT_BOOL bEnable
);
STDMETHOD(DeviceSpecific)(
IN ITCallInfo *pCall,
IN BYTE *pParams,
IN DWORD dwSize
);
STDMETHOD(DeviceSpecificVariant)(
IN ITCallInfo *pCall,
IN VARIANT varDevSpecificByteArray
);
STDMETHOD(NegotiateExtVersion)(
IN long lLowVersion,
IN long lHighVersion,
IN long *plExtVersion
);
// itaddresscapabilities
STDMETHOD(get_AddressCapability)(ADDRESS_CAPABILITY AddressCap, long * plCapability);
STDMETHOD(get_AddressCapabilityString)(ADDRESS_CAPABILITY_STRING AddressCapString, BSTR * ppCapabilityString);
STDMETHOD(get_CallTreatments)(VARIANT * pVariant );
STDMETHOD(EnumerateCallTreatments)(IEnumBstr ** ppEnumCallTreatment );
STDMETHOD(get_CompletionMessages)(VARIANT * pVariant );
STDMETHOD(EnumerateCompletionMessages)(IEnumBstr ** ppEnumCompletionMessage );
STDMETHOD(get_DeviceClasses)(VARIANT * pVariant );
STDMETHOD(EnumerateDeviceClasses)(IEnumBstr ** ppEnumDeviceClass );
// ITAddressTranslation
STDMETHOD(TranslateAddress)(
BSTR pAddressToTranslate,
long ulCard,
long ulTranslateOptions,
ITAddressTranslationInfo ** ppTranslated
);
STDMETHOD(TranslateDialog)(
TAPIHWND hwndOwner,
BSTR pAddressIn
);
STDMETHOD(EnumerateLocations)(IEnumLocation ** ppEnumLocation );
STDMETHOD(get_Locations)(VARIANT * pVariant);
STDMETHOD(EnumerateCallingCards)(IEnumCallingCard ** ppEnumLocations );
STDMETHOD(get_CallingCards)(VARIANT * pVariant);
// ITLegacyAddressMediaControl
STDMETHOD(GetID)(
BSTR pDeviceClass,
DWORD * pdwSize,
BYTE ** ppDeviceID
);
STDMETHOD(GetDevConfig)(
BSTR pDeviceClass,
DWORD * pdwSize,
BYTE ** ppDeviceConfig
);
STDMETHOD(SetDevConfig)(
BSTR pDeviceClass,
DWORD dwSize,
BYTE * pDeviceConfig
);
// ITLegacyAddressMediaControl2
STDMETHOD(ConfigDialog)(
HWND hwndOwner,
BSTR pDeviceClass
);
STDMETHOD(ConfigDialogEdit)(
HWND hwndOwner,
BSTR pDeviceClass,
DWORD dwSizeIn,
BYTE * pDeviceConfigIn,
DWORD * pdwSizeOut,
BYTE ** ppDeviceConfigOut
);
// IDispatch Methods
STDMETHOD(GetIDsOfNames)(REFIID riid,
LPOLESTR* rgszNames,
UINT cNames,
LCID lcid,
DISPID* rgdispid
);
STDMETHOD(Invoke)(DISPID dispidMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS* pdispparams,
VARIANT* pvarResult,
EXCEPINFO* pexcepinfo,
UINT* puArgErr
);
STDMETHOD_(ULONG, InternalAddRef)()
{
DWORD dwR;
dwR = InterlockedIncrement(&m_dwRef);;
#if DBG
LogDebugAddRef(m_dwRef);
#endif
return dwR;
}
STDMETHOD_(ULONG, InternalRelease)()
{
DWORD dwR;
PtrList::iterator iter, end;
AddressLineStruct * pLine;
T3LINE * pt3Line;
LOG((TL_INFO, "InternalRelease - m_dwRef %d",m_dwRef ));
Lock();
gpLineHashTable->Lock();
gpHandleHashTable->Lock();
dwR = InterlockedDecrement(&m_dwRef);
// if ref count is 0 (means we entered function with 1) then we final release
if (0 == dwR)
{
// remove from the hash table, so any more messages
// from tapisrv are ignored
//
//
// release addresslines
//
LOG((TL_TRACE, "InternalRelease - final" ));
iter = m_AddressLinesPtrList.begin();
end = m_AddressLinesPtrList.end();
LOG((TL_INFO, "InternalRelease - m_AddressLinesPtrList size %d ", m_AddressLinesPtrList.size() ));
for ( ; iter != end; iter++ )
{
pLine = (AddressLineStruct *)(*iter);
pt3Line = &(pLine->t3Line);
if(FAILED(gpLineHashTable->Remove( (ULONG_PTR)(pt3Line->hLine) ) ))
{
LOG((TL_INFO, "InternalRelease - pLineHashTable->Remove failed" ));
}
}
gpLineHashTable->Unlock();
// remove from the handle hash table, so any more messages
// from msp are ignored
//
RemoveHandleFromHashTable(m_MSPContext);
// unregister all the cookies, so CTAPI::UnregisterNotifications
// does nothing if called later
UnregisterAllCookies();
gpHandleHashTable->Unlock();
// ExternalFinalRelease();
dwR = m_dwRef = 0;
Unlock();
LOG((TL_INFO, "InternalRelease - final OK dwR %d",dwR ));
}
else
{
gpLineHashTable->Unlock();
gpHandleHashTable->Unlock();
Unlock();
LOG((TL_INFO, "InternalRelease - not final dwR %d",dwR ));
}
#if DBG
LogDebugRelease( dwR );
#endif
return dwR;
}
//
// (implementing method from CObjectSafeImpl)
// check the aggregated objects to see if they support the interface requested.
// if they do, return the non-delegating IUnknown of the first object that
// supports the interface.
//
// it needs to be released by the caller.
//
HRESULT QIOnAggregates(REFIID riid, IUnknown **ppNonDelegatingUnknown);
public:
//
// Event filtering methods
//
HRESULT SetEventFilterMask(
IN DWORD dwEventFilterMask
);
// Get subevents mask
/*DWORD GetSubEventsMask(
IN int nEvent
);*/
// Get subevents mask
DWORD GetSubEventsMask(
IN TAPI_EVENT TapiEvent
);
private:
//
// Helper methods for event filtering
//
HRESULT SetSubEventFlag(
TAPI_EVENT TapiEvent,
DWORD dwSubEvent,
BOOL bEnable
);
HRESULT GetSubEventFlag(
TAPI_EVENT TapiEvent,
DWORD dwSubEvent,
BOOL* pEnable
);
HRESULT SetSubEventFlagToCalls(
TAPI_EVENT TapiEvent,
DWORD dwFlag,
BOOL bEnable
);
public:
CEventMasks m_EventMasks; // Event filtering masks
HRESULT GetEventMasks(
OUT CEventMasks* pEventMasks
);
};
////////////////////////////////////////////////////////////////////////
// CAddressTypeCollection
//
////////////////////////////////////////////////////////////////////////
class CAddressTypeCollection :
public CTAPIComObjectRoot<CAddressTypeCollection>,
public CComDualImpl<ITCollection, &IID_ITCollection, &LIBID_TAPI3Lib>,
public CObjectSafeImpl
{
public:
DECLARE_MARSHALQI(CAddressTypeCollection)
DECLARE_TRACELOG_CLASS(CAddressTypeCollection)
BEGIN_COM_MAP(CAddressTypeCollection)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(ITCollection)
COM_INTERFACE_ENTRY(IObjectSafety)
COM_INTERFACE_ENTRY_FUNC(IID_IMarshal, 0, IMarshalQI)
COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pFTM)
END_COM_MAP()
private:
DWORD m_dwSize;
CComVariant * m_Var;
public:
// initialize
HRESULT STDMETHODCALLTYPE Initialize(
PDWORD pdwAddressTypes,
DWORD dwElements
)
{
DWORD dw;
HRESULT hr = S_OK;
LOG((TL_TRACE, "Initialize - enter"));
// create variant array
m_dwSize = dwElements;
m_Var = new CComVariant[m_dwSize];
if (NULL == m_Var)
{
LOG((TL_ERROR, "Could not alloc for CComVariant array"));
hr = E_OUTOFMEMORY;
}
else
{
for (dw = 0; dw < m_dwSize; dw++)
{
// create a variant and add it to the collection
CComVariant& var = m_Var[dw];
var.vt = VT_I4;
var.lVal = pdwAddressTypes[dw];
}
}
LOG((TL_TRACE, "Initialize - exit"));
return hr;
}
STDMETHOD(get_Count)(
long* retval
)
{
HRESULT hr = S_OK;
LOG((TL_TRACE, "get_Count - enter"));
try
{
*retval = m_dwSize;
}
catch(...)
{
hr = E_INVALIDARG;
}
LOG((TL_TRACE, "get_Count - exit"));
return hr;
}
STDMETHOD(get_Item)(
long Index,
VARIANT* retval
)
{
HRESULT hr = S_OK;
LOG((TL_TRACE, "get_Item - enter"));
if (retval == NULL)
{
return E_POINTER;
}
try
{
VariantInit(retval);
}
catch(...)
{
hr = E_INVALIDARG;
}
if (S_OK != hr)
{
return hr;
}
retval->vt = VT_I4;
retval->lVal = 0;
// use 1-based index, VB like
if ((Index < 1) || (Index > m_dwSize))
{
return E_INVALIDARG;
}
VariantCopy(retval, &m_Var[Index-1]);
LOG((TL_TRACE, "get_Item - exit"));
return S_OK;
}
HRESULT STDMETHODCALLTYPE get__NewEnum(
IUnknown** retval
)
{
HRESULT hr = S_OK;
LOG((TL_TRACE, "get__NumEnum - enter"));
if (NULL == retval)
{
return E_POINTER;
}
*retval = NULL;
typedef CComObject<CSafeComEnum<IEnumVARIANT, &IID_IEnumVARIANT, VARIANT, _Copy<VARIANT> > > enumvar;
enumvar* p = new enumvar;
if (NULL == p)
{
LOG((TL_ERROR, "Could not alloc for enumvar"));
hr = E_OUTOFMEMORY;
}
else
{
hr = p->Init(&m_Var[0], &m_Var[m_dwSize], NULL, AtlFlagCopy);
if (SUCCEEDED(hr))
{
hr = p->QueryInterface(IID_IEnumVARIANT, (void**)retval);
}
if (FAILED(hr))
{
delete p;
}
}
LOG((TL_TRACE, "get__NewEnum - exit"));
return hr;
}
void FinalRelease()
{
LOG((TL_TRACE, "FinalRelease()"));
}
};
////////////////////////////////////////////////////////////////////////
// CTerminalClassCollection
//
////////////////////////////////////////////////////////////////////////
class CTerminalClassCollection :
public CTAPIComObjectRoot<CTerminalClassCollection>,
public CComDualImpl<ITCollection, &IID_ITCollection, &LIBID_TAPI3Lib>,
public CObjectSafeImpl
{
public:
DECLARE_MARSHALQI(CTerminalClassCollection)
DECLARE_TRACELOG_CLASS(CTerminalClassCollection)
BEGIN_COM_MAP(CTerminalClassCollection)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(ITCollection)
COM_INTERFACE_ENTRY(IObjectSafety)
COM_INTERFACE_ENTRY_FUNC(IID_IMarshal, 0, IMarshalQI)
COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pFTM)
END_COM_MAP()
private:
DWORD m_dwSize;
CComVariant * m_Var;
public:
// initialize
HRESULT STDMETHODCALLTYPE Initialize(
TerminalClassPtrList classlist
)
{
TerminalClassPtrList::iterator i;
HRESULT hr = S_OK;
DWORD dw = 0;
LOG((TL_TRACE, "Initialize - enter"));
// create variant array
m_dwSize = classlist.size();
m_Var = new CComVariant[m_dwSize];
if (NULL == m_Var)
{
LOG((TL_ERROR, "Could not alloc for CComVariant array"));
hr = E_OUTOFMEMORY;
}
else
{
for (i = classlist.begin(); i != classlist.end(); i++)
{
// create a variant and add it to the collection
CComVariant& var = m_Var[dw];
var.vt = VT_BSTR;
var.bstrVal = *i;
dw++;
}
}
LOG((TL_TRACE, "Initialize - exit"));
return hr;
}
STDMETHOD(get_Count)(
long* retval
)
{
HRESULT hr = S_OK;
LOG((TL_TRACE, "get_Count - enter"));
try
{
*retval = m_dwSize;
}
catch(...)
{
hr = E_INVALIDARG;
}
LOG((TL_TRACE, "get_Count - exit"));
return hr;
}
STDMETHOD(get_Item)(
long Index,
VARIANT* retval
)
{
HRESULT hr = S_OK;
LOG((TL_TRACE, "get_Item - enter"));
if (retval == NULL)
{
return E_POINTER;
}
try
{
VariantInit(retval);
}
catch(...)
{
hr = E_INVALIDARG;
}
if (S_OK != hr)
{
return hr;
}
retval->vt = VT_BSTR;
retval->bstrVal = NULL;
// use 1-based index, VB like
if ((Index < 1) || (Index > m_dwSize))
{
return E_INVALIDARG;
}
VariantCopy(retval, &m_Var[Index-1]);
LOG((TL_TRACE, "get_Item - exit"));
return S_OK;
}
HRESULT STDMETHODCALLTYPE get__NewEnum(
IUnknown** retval
)
{
HRESULT hr;
LOG((TL_TRACE, "get__NumEnum - enter"));
if (NULL == retval)
{
return E_POINTER;
}
*retval = NULL;
typedef CComObject<CSafeComEnum<IEnumVARIANT, &IID_IEnumVARIANT, VARIANT, _Copy<VARIANT> > > enumvar;
enumvar* p = new enumvar;
if ( NULL == m_Var )
{
LOG((TL_ERROR, "Internal variant is NULL"));
hr = E_FAIL;
}
else if ( NULL == p )
{
LOG((TL_ERROR, "Could not alloc for enumvar"));
hr = E_OUTOFMEMORY;
}
else
{
hr = p->Init(&m_Var[0], &m_Var[m_dwSize], NULL, AtlFlagCopy);
if (SUCCEEDED(hr))
{
hr = p->QueryInterface(IID_IEnumVARIANT, (void**)retval);
}
if (FAILED(hr))
{
delete p;
}
}
LOG((TL_TRACE, "get__NewEnum - exit"));
return hr;
}
void FinalRelease()
{
LOG((TL_INFO, "FinalRelease()"));
}
};
class CAddressEvent :
public CTAPIComObjectRoot<CAddressEvent>,
public CComDualImpl<ITAddressEvent, &IID_ITAddressEvent, &LIBID_TAPI3Lib>,
public CObjectSafeImpl
{
public:
DECLARE_MARSHALQI(CAddressEvent)
DECLARE_TRACELOG_CLASS(CAddressEvent)
BEGIN_COM_MAP(CAddressEvent)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(ITAddressEvent)
COM_INTERFACE_ENTRY(IObjectSafety)
COM_INTERFACE_ENTRY_FUNC(IID_IMarshal, 0, IMarshalQI)
COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pFTM)
END_COM_MAP()
static HRESULT FireEvent(
CAddress * pAddress,
ADDRESS_EVENT Event,
ITTerminal * pTerminal
);
void FinalRelease();
protected:
ITAddress * m_pAddress;
ADDRESS_EVENT m_Event;
ITTerminal * m_pTerminal;
#if DBG
PWSTR m_pDebug;
#endif
public:
//
// itaddressstateevent
//
STDMETHOD(get_Address)( ITAddress ** ppAddress );
STDMETHOD(get_Event)( ADDRESS_EVENT * pEvent );
STDMETHOD(get_Terminal)( ITTerminal ** ppTerminal );
};
class CAddressDevSpecificEvent :
public CTAPIComObjectRoot<CAddressDevSpecificEvent, CComMultiThreadModelNoCS>,
public CComDualImpl<ITAddressDeviceSpecificEvent, &IID_ITAddressDeviceSpecificEvent, &LIBID_TAPI3Lib>,
public CObjectSafeImpl
{
public:
DECLARE_MARSHALQI(CAddressDevSpecificEvent)
DECLARE_TRACELOG_CLASS(CAddressDevSpecificEvent)
BEGIN_COM_MAP(CAddressDevSpecificEvent)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(ITAddressDeviceSpecificEvent)
COM_INTERFACE_ENTRY(IObjectSafety)
COM_INTERFACE_ENTRY_FUNC(IID_IMarshal, 0, IMarshalQI)
COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pFTM)
END_COM_MAP()
static HRESULT FireEvent(
CAddress * pAddress,
CCall * pCall,
long lParam1,
long lParam2,
long lParam3
);
~CAddressDevSpecificEvent();
protected:
CAddressDevSpecificEvent();
//
// properties
//
ITAddress *m_pAddress;
ITCallInfo *m_pCall;
long m_l1;
long m_l2;
long m_l3;
#if DBG
PWSTR m_pDebug;
#endif
public:
STDMETHOD(get_Address)( ITAddress ** ppAddress );
STDMETHOD(get_Call) ( ITCallInfo ** ppCall );
STDMETHOD(get_lParam1)( long *plParam1 );
STDMETHOD(get_lParam2)( long *plParam2 );
STDMETHOD(get_lParam3)( long *plParam3 );
};
#define NUMFORWARDTYPES 18
typedef struct
{
DWORD dwForwardType;
BSTR bstrDestination;
BSTR bstrCaller;
DWORD dwCallerAddressType;
DWORD dwDestAddressType;
} MYFORWARDSTRUCT;
class CForwardInfo :
public CTAPIComObjectRoot<CForwardInfo>,
public CComDualImpl<ITForwardInformation2, &IID_ITForwardInformation2, &LIBID_TAPI3Lib>,
public CObjectSafeImpl
{
public:
DECLARE_MARSHALQI(CForwardInfo)
DECLARE_TRACELOG_CLASS(CForwardInfo)
BEGIN_COM_MAP(CForwardInfo)
COM_INTERFACE_ENTRY2(IDispatch, ITForwardInformation2)
COM_INTERFACE_ENTRY(ITForwardInformation)
COM_INTERFACE_ENTRY(ITForwardInformation2)
COM_INTERFACE_ENTRY(IObjectSafety)
COM_INTERFACE_ENTRY_FUNC(IID_IMarshal, 0, IMarshalQI)
COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pFTM)
END_COM_MAP()
HRESULT Initialize();
HRESULT CreateForwardList( LINEFORWARDLIST ** ppForwardList );
void FinalRelease();
protected:
MYFORWARDSTRUCT m_ForwardStructs[NUMFORWARDTYPES];
long m_lNumRings;
public:
STDMETHOD(put_NumRingsNoAnswer)(long lNumRings);
STDMETHOD(get_NumRingsNoAnswer)(long * plNumRings);
STDMETHOD(SetForwardType)(
long ForwardType,
BSTR pDestAddress,
BSTR pCallerAddress
);
STDMETHOD(get_ForwardTypeDestination)(
long ForwardType,
BSTR * ppDestAddress
);
STDMETHOD(get_ForwardTypeCaller)(
long Forwardtype,
BSTR * ppCallerAddress
);
STDMETHOD(GetForwardType)(
long ForwardType,
BSTR * ppDestinationAddress,
BSTR * ppCallerAddress
);
STDMETHOD(Clear)();
STDMETHOD(SetForwardType2)(
long ForwardType,
BSTR pDestAddress,
long DestAddressType,
BSTR pCallerAddress,
long CallerAddressType
);
STDMETHOD(GetForwardType2)(
long ForwardType,
BSTR * ppDestinationAddress,
long * pDestAddressType,
BSTR * ppCallerAddress,
long * pCallerAddressType
);
STDMETHOD(get_ForwardTypeDestinationAddressType)(
long ForwardType,
long * pDestAddressType
);
STDMETHOD(get_ForwardTypeCallerAddressType)(
long Forwardtype,
long * pCallerAddressType
);
};
#define FORWARDMODENEEDSCALLER(__dwMode__) \
( ( LINEFORWARDMODE_UNCONDSPECIFIC | LINEFORWARDMODE_BUSYSPECIFIC | \
LINEFORWARDMODE_NOANSWSPECIFIC | LINEFORWARDMODE_BUSYNASPECIFIC ) & \
(__dwMode__) )
////////////////////////////////////////////////////////////////////////
// CAddressTranslationInfo
//
////////////////////////////////////////////////////////////////////////
class CAddressTranslationInfo :
public CTAPIComObjectRoot<CAddressTranslationInfo>,
public CComDualImpl<ITAddressTranslationInfo, &IID_ITAddressTranslationInfo, &LIBID_TAPI3Lib>,
public CObjectSafeImpl
{
public:
CAddressTranslationInfo() : m_szDialableString(NULL),
m_szDisplayableString(NULL),
m_dwCurrentCountryCode(0),
m_dwDestinationCountryCode(0),
m_dwTranslationResults(0)
{}
DECLARE_MARSHALQI(CAddressTranslationInfo)
DECLARE_TRACELOG_CLASS(CAddressTranslationInfo)
BEGIN_COM_MAP(CAddressTranslationInfo)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(ITAddressTranslationInfo)
COM_INTERFACE_ENTRY(IObjectSafety)
COM_INTERFACE_ENTRY_FUNC(IID_IMarshal, 0, IMarshalQI)
COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pFTM)
END_COM_MAP()
HRESULT Initialize(
PWSTR pszDialableString,
PWSTR pszDisplayableString,
DWORD dwCurrentCountry,
DWORD dwDestCountry,
DWORD dwTranslateResults
);
void FinalRelease();
private:
DWORD m_dwCurrentCountryCode;
DWORD m_dwDestinationCountryCode;
DWORD m_dwTranslationResults;
PWSTR m_szDialableString;
PWSTR m_szDisplayableString;
public:
STDMETHOD(get_DialableString)(BSTR * ppDialableString );
STDMETHOD(get_DisplayableString)(BSTR * ppDisplayableString );
STDMETHOD(get_CurrentCountryCode)(long * CountryCode );
STDMETHOD(get_DestinationCountryCode)(long * CountryCode );
STDMETHOD(get_TranslationResults)(long * Results );
};
////////////////////////////////////////////////////////////////////////
// CLocationInfo
//
////////////////////////////////////////////////////////////////////////
class CLocationInfo:
public CTAPIComObjectRoot<CLocationInfo>,
public CComDualImpl<ITLocationInfo, &IID_ITLocationInfo, &LIBID_TAPI3Lib>,
public CObjectSafeImpl
{
public:
DECLARE_MARSHALQI(CLocationInfo)
DECLARE_TRACELOG_CLASS(CLocationInfo)
BEGIN_COM_MAP(CLocationInfo)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(ITLocationInfo)
COM_INTERFACE_ENTRY(IObjectSafety)
COM_INTERFACE_ENTRY_FUNC(IID_IMarshal, 0, IMarshalQI)
COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pFTM)
END_COM_MAP()
HRESULT Initialize(
PWSTR pszLocationName,
PWSTR pszCityCode,
PWSTR pszLocalAccessCode,
PWSTR pszLongDistanceAccessCode,
PWSTR pszTollPrefixList,
PWSTR pszCancelCallWaitingCode ,
DWORD dwPermanentLocationID,
DWORD dwCountryCode,
DWORD dwPreferredCardID,
DWORD dwCountryID,
DWORD dwOptions
);
void FinalRelease();
private:
DWORD m_dwPermanentLocationID;
DWORD m_dwCountryCode;
DWORD m_dwCountryID;
DWORD m_dwOptions;
DWORD m_dwPreferredCardID;
PWSTR m_szLocationName;
PWSTR m_szCityCode;
PWSTR m_szLocalAccessCode;
PWSTR m_szLongDistanceAccessCode;
PWSTR m_szTollPrefixList;
PWSTR m_szCancelCallWaitingCode;
public:
// ITLocationInfo
STDMETHOD(get_PermanentLocationID)(long * ulLocationID );
STDMETHOD(get_CountryCode)(long * ulCountryCode);
STDMETHOD(get_CountryID)(long * ulCountryID);
STDMETHOD(get_Options)(long * Options);
STDMETHOD(get_PreferredCardID)( long * ulCardID);
STDMETHOD(get_LocationName)(BSTR * ppLocationName );
STDMETHOD(get_CityCode)(BSTR * ppCode );
STDMETHOD(get_LocalAccessCode)(BSTR * ppCode );
STDMETHOD(get_LongDistanceAccessCode)(BSTR * ppCode );
STDMETHOD(get_TollPrefixList)(BSTR * ppTollList);
STDMETHOD(get_CancelCallWaitingCode)(BSTR * ppCode );
};
////////////////////////////////////////////////////////////////////////
// CCallingCard
//
////////////////////////////////////////////////////////////////////////
class CCallingCard:
public CTAPIComObjectRoot<CCallingCard>,
public CComDualImpl<ITCallingCard, &IID_ITCallingCard, &LIBID_TAPI3Lib>,
public CObjectSafeImpl
{
public:
DECLARE_MARSHALQI(CCallingCard)
DECLARE_TRACELOG_CLASS(CCallingCard)
BEGIN_COM_MAP(CCallingCard)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(ITCallingCard)
COM_INTERFACE_ENTRY(IObjectSafety)
COM_INTERFACE_ENTRY_FUNC(IID_IMarshal, 0, IMarshalQI)
COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pFTM)
END_COM_MAP()
HRESULT Initialize(
PWSTR pszCardName,
PWSTR pszSameAreaDialingRule,
PWSTR pszLongDistanceDialingRule,
PWSTR pszInternationalDialingRule,
DWORD dwPermanentCardID,
DWORD dwNumberOfDigits,
DWORD dwOptions
);
void FinalRelease();
private:
DWORD m_dwPermanentCardID;
DWORD m_dwNumberOfDigits;
DWORD m_dwOptions;
PWSTR m_szCardName;
PWSTR m_szSameAreaDialingRule;
PWSTR m_szLongDistanceDialingRule;
PWSTR m_szInternationalDialingRule;
public:
// ITCallingCard
STDMETHOD(get_PermanentCardID)(long * ulCardID);
STDMETHOD(get_NumberOfDigits)(long * ulDigits);
STDMETHOD(get_Options)(long * ulOptions);
STDMETHOD(get_CardName)(BSTR * ppCardName );
STDMETHOD(get_SameAreaDialingRule)(BSTR * ppRule );
STDMETHOD(get_LongDistanceDialingRule)(BSTR * ppRule );
STDMETHOD(get_InternationalDialingRule)(BSTR * ppRule );
};
/////////////////////////////////////////////////////////////////////////////
// _CopyBSTR is used in creating BSTR enumerators.
/////////////////////////////////////////////////////////////////////////////
class _CopyBSTR
{
public:
static void copy(BSTR *p1, BSTR *p2)
{
(*p1) = SysAllocString(*p2);
}
static void init(BSTR* p) {*p = NULL;}
static void destroy(BSTR* p) { SysFreeString(*p);}
};
#endif //__ADDRESS_H_