| #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)(__LONG32 *pMediaTypes); |
| private: |
| CMSPCritSection m_CritSect; |
| BSTR m_bstrName; |
| BSTR m_bstrCompany; |
| BSTR m_bstrVersion; |
| BSTR m_bstrTerminalClass; |
| BSTR m_bstrCLSID; |
| __LONG32 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)(__LONG32 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,__LONG32 lMediaType,TERMINAL_DIRECTION Direction,ITTerminal **ppTerminal); |
| STDMETHOD (GetDefaultStaticTerminal) (__LONG32 lMediaType,TERMINAL_DIRECTION Direction,ITTerminal **ppTerminal); |
| STDMETHOD (get_PluggableSuperclasses)(VARIANT *pVariant); |
| STDMETHOD (EnumeratePluggableSuperclasses)(IEnumPluggableSuperclassInfo **ppSuperclassEnumerator); |
| STDMETHOD (get_PluggableTerminalClasses)(BSTR bstrTerminalSuperclass,__LONG32 lMediaType,VARIANT *pVariant); |
| STDMETHOD (EnumeratePluggableTerminalClasses)(CLSID iidTerminalSuperclass,__LONG32 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 |