275 lines
10 KiB
C
275 lines
10 KiB
C
|
#ifndef __MSPADDR_H_
|
||
|
#define __MSPADDR_H_
|
||
|
|
||
|
typedef struct {
|
||
|
LIST_ENTRY Link;
|
||
|
MSP_EVENT_INFO MSPEventInfo;
|
||
|
} MSPEVENTITEM,*PMSPEVENTITEM;
|
||
|
|
||
|
MSPEVENTITEM *AllocateEventItem(SIZE_T nExtraBytes = 0);
|
||
|
WINBOOL FreeEventItem(MSPEVENTITEM *pEventItemToFree);
|
||
|
|
||
|
typedef HRESULT (*PFNCREATETERM)(CComPtr<IMoniker> pMoniker,MSP_HANDLE htAddress,ITTerminal **pTerm);
|
||
|
|
||
|
typedef struct {
|
||
|
DWORD dwMediaType;
|
||
|
const CLSID *clsidClassManager;
|
||
|
PFNCREATETERM pfnCreateTerm;
|
||
|
} STATIC_TERMINAL_TYPE;
|
||
|
|
||
|
class ATL_NO_VTABLE CPlugTerminalClassInfo : public IDispatchImpl<ITPluggableTerminalClassInfo,&IID_ITPluggableTerminalClassInfo,&LIBID_TAPI3Lib>,public CComObjectRootEx<CComMultiThreadModel>,public CMSPObjectSafetyImpl
|
||
|
{
|
||
|
public:
|
||
|
DECLARE_GET_CONTROLLING_UNKNOWN()
|
||
|
virtual HRESULT FinalConstruct(void);
|
||
|
BEGIN_COM_MAP(CPlugTerminalClassInfo)
|
||
|
COM_INTERFACE_ENTRY(ITPluggableTerminalClassInfo)
|
||
|
COM_INTERFACE_ENTRY(IDispatch)
|
||
|
COM_INTERFACE_ENTRY(IObjectSafety)
|
||
|
COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal,m_pFTM)
|
||
|
END_COM_MAP()
|
||
|
public:
|
||
|
CPlugTerminalClassInfo() : m_bstrName(NULL),m_bstrCompany(NULL),m_bstrVersion(NULL),m_bstrCLSID(NULL),m_bstrTerminalClass(NULL),m_lMediaType(1),m_Direction(TD_CAPTURE),m_pFTM(NULL)
|
||
|
{
|
||
|
}
|
||
|
~CPlugTerminalClassInfo() {
|
||
|
if(m_bstrName) {
|
||
|
SysFreeString(m_bstrName);
|
||
|
}
|
||
|
if(m_bstrCompany) {
|
||
|
SysFreeString(m_bstrCompany);
|
||
|
}
|
||
|
if(m_bstrVersion) {
|
||
|
SysFreeString(m_bstrVersion);
|
||
|
}
|
||
|
if(m_bstrCLSID) {
|
||
|
SysFreeString(m_bstrCLSID);
|
||
|
}
|
||
|
if(m_bstrTerminalClass) {
|
||
|
SysFreeString(m_bstrTerminalClass);
|
||
|
}
|
||
|
if(m_pFTM) {
|
||
|
m_pFTM->Release();
|
||
|
}
|
||
|
}
|
||
|
public:
|
||
|
STDMETHOD(get_Name)(BSTR *pName);
|
||
|
STDMETHOD(get_Company)(BSTR *pCompany);
|
||
|
STDMETHOD(get_Version)(BSTR *pVersion);
|
||
|
STDMETHOD(get_TerminalClass)(BSTR *pTerminalClass);
|
||
|
STDMETHOD(get_CLSID)(BSTR *pCLSID);
|
||
|
STDMETHOD(get_Direction)(TERMINAL_DIRECTION *pDirection);
|
||
|
STDMETHOD(get_MediaTypes)(long *pMediaTypes);
|
||
|
private:
|
||
|
CMSPCritSection m_CritSect;
|
||
|
BSTR m_bstrName;
|
||
|
BSTR m_bstrCompany;
|
||
|
BSTR m_bstrVersion;
|
||
|
BSTR m_bstrTerminalClass;
|
||
|
BSTR m_bstrCLSID;
|
||
|
long m_lMediaType;
|
||
|
TERMINAL_DIRECTION m_Direction;
|
||
|
IUnknown *m_pFTM;
|
||
|
private:
|
||
|
STDMETHOD(put_Name)(BSTR bstrName);
|
||
|
STDMETHOD(put_Company)(BSTR bstrCompany);
|
||
|
STDMETHOD(put_Version)(BSTR bstrVersion);
|
||
|
STDMETHOD(put_TerminalClass)(BSTR bstrTerminalClass);
|
||
|
STDMETHOD(put_CLSID)(BSTR bstrCLSID);
|
||
|
STDMETHOD(put_Direction)(TERMINAL_DIRECTION nDirection);
|
||
|
STDMETHOD(put_MediaTypes)(long nMediaTypes);
|
||
|
friend class CMSPAddress;
|
||
|
};
|
||
|
|
||
|
class ATL_NO_VTABLE CPlugTerminalSuperclassInfo : public IDispatchImpl<ITPluggableTerminalSuperclassInfo,&IID_ITPluggableTerminalSuperclassInfo,&LIBID_TAPI3Lib>,public CComObjectRootEx<CComMultiThreadModel>,public CMSPObjectSafetyImpl
|
||
|
{
|
||
|
public:
|
||
|
DECLARE_GET_CONTROLLING_UNKNOWN()
|
||
|
virtual HRESULT FinalConstruct(void);
|
||
|
BEGIN_COM_MAP(CPlugTerminalSuperclassInfo)
|
||
|
COM_INTERFACE_ENTRY(ITPluggableTerminalSuperclassInfo)
|
||
|
COM_INTERFACE_ENTRY(IDispatch)
|
||
|
COM_INTERFACE_ENTRY(IObjectSafety)
|
||
|
COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal,m_pFTM)
|
||
|
END_COM_MAP()
|
||
|
public:
|
||
|
CPlugTerminalSuperclassInfo() : m_bstrCLSID(NULL),m_bstrName(NULL),m_pFTM(NULL) {
|
||
|
}
|
||
|
~CPlugTerminalSuperclassInfo() {
|
||
|
if(m_bstrName) {
|
||
|
SysFreeString(m_bstrName);
|
||
|
}
|
||
|
if(m_bstrCLSID) {
|
||
|
SysFreeString(m_bstrCLSID);
|
||
|
}
|
||
|
if(m_pFTM) {
|
||
|
m_pFTM->Release();
|
||
|
}
|
||
|
}
|
||
|
public:
|
||
|
STDMETHOD(get_Name)(BSTR *pName);
|
||
|
STDMETHOD(get_CLSID)(BSTR *pCLSID);
|
||
|
private:
|
||
|
CMSPCritSection m_CritSect;
|
||
|
BSTR m_bstrCLSID;
|
||
|
BSTR m_bstrName;
|
||
|
IUnknown *m_pFTM;
|
||
|
private:
|
||
|
STDMETHOD(put_Name)(BSTR bstrName);
|
||
|
STDMETHOD(put_CLSID)(BSTR bstrCLSID);
|
||
|
friend class CMSPAddress;
|
||
|
};
|
||
|
|
||
|
class ATL_NO_VTABLE CMSPAddress : public CComObjectRootEx<CComMultiThreadModelNoCS>,public ITMSPAddress,public IDispatchImpl<ITTerminalSupport2,&IID_ITTerminalSupport2,&LIBID_TAPI3Lib>
|
||
|
{
|
||
|
public:
|
||
|
BEGIN_COM_MAP(CMSPAddress)
|
||
|
COM_INTERFACE_ENTRY(ITMSPAddress)
|
||
|
COM_INTERFACE_ENTRY(IDispatch)
|
||
|
COM_INTERFACE_ENTRY(ITTerminalSupport)
|
||
|
COM_INTERFACE_ENTRY(ITTerminalSupport2)
|
||
|
END_COM_MAP()
|
||
|
DECLARE_GET_CONTROLLING_UNKNOWN()
|
||
|
DECLARE_VQI()
|
||
|
CMSPAddress();
|
||
|
virtual ~CMSPAddress();
|
||
|
virtual ULONG MSPAddressAddRef(void) = 0;
|
||
|
virtual ULONG MSPAddressRelease(void) = 0;
|
||
|
STDMETHOD (Initialize) (MSP_HANDLE htEvent);
|
||
|
STDMETHOD (Shutdown) ();
|
||
|
STDMETHOD (CreateMSPCall) (MSP_HANDLE htCall,DWORD dwReserved,DWORD dwMediaType,IUnknown *pOuterUnknown,IUnknown **ppMSPCall) = 0;
|
||
|
STDMETHOD (ShutdownMSPCall) (IUnknown *pMSPCall) = 0;
|
||
|
STDMETHOD (ReceiveTSPData) (IUnknown *pMSPCall,LPBYTE pBuffer,DWORD dwBufferSize);
|
||
|
STDMETHOD (GetEvent) (DWORD *pdwSize,BYTE *pBuffer);
|
||
|
STDMETHOD (get_StaticTerminals) (VARIANT *pVariant);
|
||
|
STDMETHOD (EnumerateStaticTerminals) (IEnumTerminal **ppTerminalEnumerator);
|
||
|
STDMETHOD (get_DynamicTerminalClasses) (VARIANT *pVariant);
|
||
|
STDMETHOD (EnumerateDynamicTerminalClasses) (IEnumTerminalClass **ppTerminalClassEnumerator);
|
||
|
STDMETHOD (CreateTerminal) (BSTR pTerminalClass,long lMediaType,TERMINAL_DIRECTION Direction,ITTerminal **ppTerminal);
|
||
|
STDMETHOD (GetDefaultStaticTerminal) (long lMediaType,TERMINAL_DIRECTION Direction,ITTerminal **ppTerminal);
|
||
|
STDMETHOD (get_PluggableSuperclasses)(VARIANT *pVariant);
|
||
|
STDMETHOD (EnumeratePluggableSuperclasses)(IEnumPluggableSuperclassInfo **ppSuperclassEnumerator);
|
||
|
STDMETHOD (get_PluggableTerminalClasses)(BSTR bstrTerminalSuperclass,long lMediaType,VARIANT *pVariant);
|
||
|
STDMETHOD (EnumeratePluggableTerminalClasses)(CLSID iidTerminalSuperclass,long lMediaType,IEnumPluggableTerminalClassInfo **ppClassEnumerator);
|
||
|
protected:
|
||
|
virtual HRESULT GetStaticTerminals (DWORD *pdwNumTerminals,ITTerminal **ppTerminals);
|
||
|
virtual HRESULT GetDynamicTerminalClasses (DWORD *pdwNumClasses,IID *pTerminalClasses);
|
||
|
public:
|
||
|
virtual WINBOOL IsValidSetOfMediaTypes(DWORD dwMediaType,DWORD dwMask);
|
||
|
virtual HRESULT PostEvent(MSPEVENTITEM *EventItem);
|
||
|
virtual DWORD GetCallMediaTypes(void) = 0;
|
||
|
protected:
|
||
|
virtual HRESULT IsMonikerInTerminalList(IMoniker *pMoniker);
|
||
|
virtual HRESULT UpdateTerminalListForPnp(WINBOOL bDeviceArrival);
|
||
|
virtual HRESULT UpdateTerminalList(void);
|
||
|
virtual HRESULT ReceiveTSPAddressData(PBYTE pBuffer,DWORD dwSize);
|
||
|
public:
|
||
|
virtual HRESULT PnpNotifHandler(WINBOOL bDeviceArrival);
|
||
|
protected:
|
||
|
HANDLE m_htEvent;
|
||
|
LIST_ENTRY m_EventList;
|
||
|
CMSPCritSection m_EventDataLock;
|
||
|
ITTerminalManager *m_pITTerminalManager;
|
||
|
CMSPArray <ITTerminal *> m_Terminals;
|
||
|
WINBOOL m_fTerminalsUpToDate;
|
||
|
CMSPCritSection m_TerminalDataLock;
|
||
|
private:
|
||
|
static const STATIC_TERMINAL_TYPE m_saTerminalTypes[];
|
||
|
static const DWORD m_sdwTerminalTypesCount;
|
||
|
};
|
||
|
|
||
|
template <class T> HRESULT CreateMSPCallHelper(CMSPAddress *pCMSPAddress,MSP_HANDLE htCall,DWORD dwReserved,DWORD dwMediaType,IUnknown *pOuterUnknown,IUnknown **ppMSPCall,T **ppCMSPCall)
|
||
|
{
|
||
|
LOG((MSP_TRACE,"CreateMSPCallHelper - enter"));
|
||
|
HRESULT hr;
|
||
|
T *pMSPCall;
|
||
|
IUnknown *pUnknown = NULL;
|
||
|
if(IsBadReadPtr(pCMSPAddress,sizeof(CMSPAddress))) {
|
||
|
LOG((MSP_ERROR,"CreateMSPCallHelper - bad address pointer - exit E_POINTER"));
|
||
|
return E_POINTER;
|
||
|
}
|
||
|
if(IsBadReadPtr(pOuterUnknown,sizeof(IUnknown))) {
|
||
|
LOG((MSP_ERROR,"CreateMSPCallHelper - bad outer unknown - we require aggregation - exit E_POINTER"));
|
||
|
return E_POINTER;
|
||
|
}
|
||
|
if(IsBadReadPtr(ppMSPCall,sizeof(IUnknown *))) {
|
||
|
LOG((MSP_ERROR,"CreateMSPCallHelper - bad iunknown return ptr - exit E_POINTER"));
|
||
|
return E_POINTER;
|
||
|
}
|
||
|
if(IsBadReadPtr(ppCMSPCall,sizeof(T *))) {
|
||
|
LOG((MSP_ERROR,"CreateMSPCallHelper - bad class return ptr - exit E_POINTER"));
|
||
|
return E_POINTER;
|
||
|
}
|
||
|
if(! pCMSPAddress->IsValidSetOfMediaTypes(dwMediaType,pCMSPAddress->GetCallMediaTypes())) {
|
||
|
LOG((MSP_ERROR,"CreateMSPCallHelper - unsupported media types - exit TAPI_E_INVALIDMEDIATYPE"));
|
||
|
return TAPI_E_INVALIDMEDIATYPE;
|
||
|
}
|
||
|
CComAggObject<T> *pCall;
|
||
|
pCall = new CComAggObject<T>(pOuterUnknown);
|
||
|
if(!pCall) {
|
||
|
LOG((MSP_ERROR,"CreateMSPCallHelper - could not create agg call instance - exit E_OUTOFMEMORY"));
|
||
|
return E_OUTOFMEMORY;
|
||
|
}
|
||
|
hr = pCall->QueryInterface(IID_IUnknown,(void **)&pUnknown);
|
||
|
if(FAILED(hr)) {
|
||
|
LOG((MSP_ERROR,"CreateMSPCallHelper - QueryInterface failed: %x",hr));
|
||
|
delete pCall;
|
||
|
return hr;
|
||
|
}
|
||
|
hr = pCall->FinalConstruct();
|
||
|
if(FAILED(hr)) {
|
||
|
LOG((MSP_ERROR,"CreateMSPCallHelper - FinalConstruct failed: %x.",hr));
|
||
|
pUnknown->Release();
|
||
|
return hr;
|
||
|
}
|
||
|
pMSPCall = dynamic_cast<T *>(&(pCall->m_contained));
|
||
|
if(!pMSPCall) {
|
||
|
LOG((MSP_ERROR,"CreateMSPCallHelper - can not cast to agg object to class pointer - exit E_UNEXPECTED"));
|
||
|
pUnknown->Release();
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
hr = pMSPCall->Init(pCMSPAddress,htCall,dwReserved,dwMediaType);
|
||
|
if(FAILED(hr)) {
|
||
|
LOG((MSP_ERROR,"CreateMSPCallHelper - call init failed: %x",hr));
|
||
|
pUnknown->Release();
|
||
|
return hr;
|
||
|
}
|
||
|
*ppMSPCall = pUnknown;
|
||
|
*ppCMSPCall = pMSPCall;
|
||
|
LOG((MSP_TRACE,"CreateMSPCallHelper - exit S_OK"));
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
template <class T> HRESULT ShutdownMSPCallHelper(IUnknown *pUnknown,T **ppCMSPCall)
|
||
|
{
|
||
|
LOG((MSP_TRACE,"ShutdownMSPCallHelper - enter"));
|
||
|
if(IsBadReadPtr(pUnknown,sizeof(IUnknown))) {
|
||
|
LOG((MSP_ERROR,"ShutdownMSPCallHelper - bad IUnknown pointer - exit E_POINTER"));
|
||
|
return E_POINTER;
|
||
|
}
|
||
|
if(IsBadWritePtr(ppCMSPCall,sizeof(T *))) {
|
||
|
LOG((MSP_ERROR,"ShutdownMSPCallHelper - bad return pointer - exit E_POINTER"));
|
||
|
return E_POINTER;
|
||
|
}
|
||
|
T *pMSPCall;
|
||
|
CComAggObject<T> *pCall = dynamic_cast<CComAggObject<T> *> (pUnknown);
|
||
|
if(!pCall) {
|
||
|
LOG((MSP_ERROR,"ShutdownMSPCallHelper - can't cast unknown to agg object pointer - exit E_UNEXPECTED"));
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
pMSPCall = dynamic_cast<T *> (&(pCall->m_contained));
|
||
|
if(!pMSPCall) {
|
||
|
LOG((MSP_ERROR,"ShutdownMSPCallHelper - can't cast contained unknown to class pointer - exit E_UNEXPECTED"));
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
HRESULT hr = pMSPCall->ShutDown();
|
||
|
if(FAILED(hr)) {
|
||
|
LOG((MSP_ERROR,"ShutdownMSPCallHelper - ShutDownMSPCall failed: %x",hr));
|
||
|
return hr;
|
||
|
}
|
||
|
*ppCMSPCall = pMSPCall;
|
||
|
LOG((MSP_TRACE,"ShutdownMSPCallHelper - exit S_OK"));
|
||
|
return S_OK;
|
||
|
}
|
||
|
#endif
|