1#ifndef __MSPADDR_H_
2#define __MSPADDR_H_
3
4typedef struct {
5  LIST_ENTRY Link;
6  MSP_EVENT_INFO MSPEventInfo;
7} MSPEVENTITEM,*PMSPEVENTITEM;
8
9MSPEVENTITEM *AllocateEventItem(SIZE_T nExtraBytes = 0);
10WINBOOL FreeEventItem(MSPEVENTITEM *pEventItemToFree);
11
12typedef HRESULT (*PFNCREATETERM)(CComPtr<IMoniker> pMoniker,MSP_HANDLE htAddress,ITTerminal **pTerm);
13
14typedef struct {
15  DWORD dwMediaType;
16  const CLSID *clsidClassManager;
17  PFNCREATETERM pfnCreateTerm;
18} STATIC_TERMINAL_TYPE;
19
20class ATL_NO_VTABLE CPlugTerminalClassInfo : public IDispatchImpl<ITPluggableTerminalClassInfo,&IID_ITPluggableTerminalClassInfo,&LIBID_TAPI3Lib>,public CComObjectRootEx<CComMultiThreadModel>,public CMSPObjectSafetyImpl
21{
22public:
23  DECLARE_GET_CONTROLLING_UNKNOWN()
24  virtual HRESULT FinalConstruct(void);
25  BEGIN_COM_MAP(CPlugTerminalClassInfo)
26    COM_INTERFACE_ENTRY(ITPluggableTerminalClassInfo)
27    COM_INTERFACE_ENTRY(IDispatch)
28    COM_INTERFACE_ENTRY(IObjectSafety)
29    COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal,m_pFTM)
30  END_COM_MAP()
31public:
32  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)
33  {
34  }
35  ~CPlugTerminalClassInfo() {
36    if(m_bstrName) {
37      SysFreeString(m_bstrName);
38    }
39    if(m_bstrCompany) {
40      SysFreeString(m_bstrCompany);
41    }
42    if(m_bstrVersion) {
43      SysFreeString(m_bstrVersion);
44    }
45    if(m_bstrCLSID) {
46      SysFreeString(m_bstrCLSID);
47    }
48    if(m_bstrTerminalClass) {
49      SysFreeString(m_bstrTerminalClass);
50    }
51    if(m_pFTM) {
52      m_pFTM->Release();
53    }
54  }
55public:
56  STDMETHOD(get_Name)(BSTR *pName);
57  STDMETHOD(get_Company)(BSTR *pCompany);
58  STDMETHOD(get_Version)(BSTR *pVersion);
59  STDMETHOD(get_TerminalClass)(BSTR *pTerminalClass);
60  STDMETHOD(get_CLSID)(BSTR *pCLSID);
61  STDMETHOD(get_Direction)(TERMINAL_DIRECTION *pDirection);
62  STDMETHOD(get_MediaTypes)(__LONG32 *pMediaTypes);
63private:
64  CMSPCritSection m_CritSect;
65  BSTR m_bstrName;
66  BSTR m_bstrCompany;
67  BSTR m_bstrVersion;
68  BSTR m_bstrTerminalClass;
69  BSTR m_bstrCLSID;
70  __LONG32 m_lMediaType;
71  TERMINAL_DIRECTION m_Direction;
72  IUnknown *m_pFTM;
73private:
74  STDMETHOD(put_Name)(BSTR bstrName);
75  STDMETHOD(put_Company)(BSTR bstrCompany);
76  STDMETHOD(put_Version)(BSTR bstrVersion);
77  STDMETHOD(put_TerminalClass)(BSTR bstrTerminalClass);
78  STDMETHOD(put_CLSID)(BSTR bstrCLSID);
79  STDMETHOD(put_Direction)(TERMINAL_DIRECTION nDirection);
80  STDMETHOD(put_MediaTypes)(__LONG32 nMediaTypes);
81  friend class CMSPAddress;
82};
83
84class ATL_NO_VTABLE CPlugTerminalSuperclassInfo : public IDispatchImpl<ITPluggableTerminalSuperclassInfo,&IID_ITPluggableTerminalSuperclassInfo,&LIBID_TAPI3Lib>,public CComObjectRootEx<CComMultiThreadModel>,public CMSPObjectSafetyImpl
85{
86public:
87  DECLARE_GET_CONTROLLING_UNKNOWN()
88  virtual HRESULT FinalConstruct(void);
89  BEGIN_COM_MAP(CPlugTerminalSuperclassInfo)
90    COM_INTERFACE_ENTRY(ITPluggableTerminalSuperclassInfo)
91    COM_INTERFACE_ENTRY(IDispatch)
92    COM_INTERFACE_ENTRY(IObjectSafety)
93    COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal,m_pFTM)
94  END_COM_MAP()
95public:
96  CPlugTerminalSuperclassInfo() : m_bstrCLSID(NULL),m_bstrName(NULL),m_pFTM(NULL) {
97  }
98  ~CPlugTerminalSuperclassInfo() {
99    if(m_bstrName) {
100      SysFreeString(m_bstrName);
101    }
102    if(m_bstrCLSID) {
103      SysFreeString(m_bstrCLSID);
104    }
105    if(m_pFTM) {
106      m_pFTM->Release();
107    }
108  }
109public:
110  STDMETHOD(get_Name)(BSTR *pName);
111  STDMETHOD(get_CLSID)(BSTR *pCLSID);
112private:
113  CMSPCritSection m_CritSect;
114  BSTR m_bstrCLSID;
115  BSTR m_bstrName;
116  IUnknown *m_pFTM;
117private:
118  STDMETHOD(put_Name)(BSTR bstrName);
119  STDMETHOD(put_CLSID)(BSTR bstrCLSID);
120  friend class CMSPAddress;
121};
122
123class ATL_NO_VTABLE CMSPAddress : public CComObjectRootEx<CComMultiThreadModelNoCS>,public ITMSPAddress,public IDispatchImpl<ITTerminalSupport2,&IID_ITTerminalSupport2,&LIBID_TAPI3Lib>
124{
125public:
126  BEGIN_COM_MAP(CMSPAddress)
127    COM_INTERFACE_ENTRY(ITMSPAddress)
128    COM_INTERFACE_ENTRY(IDispatch)
129    COM_INTERFACE_ENTRY(ITTerminalSupport)
130    COM_INTERFACE_ENTRY(ITTerminalSupport2)
131  END_COM_MAP()
132  DECLARE_GET_CONTROLLING_UNKNOWN()
133  DECLARE_VQI()
134  CMSPAddress();
135  virtual ~CMSPAddress();
136  virtual ULONG MSPAddressAddRef(void) = 0;
137  virtual ULONG MSPAddressRelease(void) = 0;
138  STDMETHOD (Initialize) (MSP_HANDLE htEvent);
139  STDMETHOD (Shutdown) ();
140  STDMETHOD (CreateMSPCall) (MSP_HANDLE htCall,DWORD dwReserved,DWORD dwMediaType,IUnknown *pOuterUnknown,IUnknown **ppMSPCall) = 0;
141  STDMETHOD (ShutdownMSPCall) (IUnknown *pMSPCall) = 0;
142  STDMETHOD (ReceiveTSPData) (IUnknown *pMSPCall,LPBYTE pBuffer,DWORD dwBufferSize);
143  STDMETHOD (GetEvent) (DWORD *pdwSize,BYTE *pBuffer);
144  STDMETHOD (get_StaticTerminals) (VARIANT *pVariant);
145  STDMETHOD (EnumerateStaticTerminals) (IEnumTerminal **ppTerminalEnumerator);
146  STDMETHOD (get_DynamicTerminalClasses) (VARIANT *pVariant);
147  STDMETHOD (EnumerateDynamicTerminalClasses) (IEnumTerminalClass **ppTerminalClassEnumerator);
148  STDMETHOD (CreateTerminal) (BSTR pTerminalClass,__LONG32 lMediaType,TERMINAL_DIRECTION Direction,ITTerminal **ppTerminal);
149  STDMETHOD (GetDefaultStaticTerminal) (__LONG32 lMediaType,TERMINAL_DIRECTION Direction,ITTerminal **ppTerminal);
150  STDMETHOD (get_PluggableSuperclasses)(VARIANT *pVariant);
151  STDMETHOD (EnumeratePluggableSuperclasses)(IEnumPluggableSuperclassInfo **ppSuperclassEnumerator);
152  STDMETHOD (get_PluggableTerminalClasses)(BSTR bstrTerminalSuperclass,__LONG32 lMediaType,VARIANT *pVariant);
153  STDMETHOD (EnumeratePluggableTerminalClasses)(CLSID iidTerminalSuperclass,__LONG32 lMediaType,IEnumPluggableTerminalClassInfo **ppClassEnumerator);
154protected:
155  virtual HRESULT GetStaticTerminals (DWORD *pdwNumTerminals,ITTerminal **ppTerminals);
156  virtual HRESULT GetDynamicTerminalClasses (DWORD *pdwNumClasses,IID *pTerminalClasses);
157public:
158  virtual WINBOOL IsValidSetOfMediaTypes(DWORD dwMediaType,DWORD dwMask);
159  virtual HRESULT PostEvent(MSPEVENTITEM *EventItem);
160  virtual DWORD GetCallMediaTypes(void) = 0;
161protected:
162  virtual HRESULT IsMonikerInTerminalList(IMoniker *pMoniker);
163  virtual HRESULT UpdateTerminalListForPnp(WINBOOL bDeviceArrival);
164  virtual HRESULT UpdateTerminalList(void);
165  virtual HRESULT ReceiveTSPAddressData(PBYTE pBuffer,DWORD dwSize);
166public:
167  virtual HRESULT PnpNotifHandler(WINBOOL bDeviceArrival);
168protected:
169  HANDLE m_htEvent;
170  LIST_ENTRY m_EventList;
171  CMSPCritSection m_EventDataLock;
172  ITTerminalManager *m_pITTerminalManager;
173  CMSPArray <ITTerminal *> m_Terminals;
174  WINBOOL m_fTerminalsUpToDate;
175  CMSPCritSection m_TerminalDataLock;
176private:
177  static const STATIC_TERMINAL_TYPE m_saTerminalTypes[];
178  static const DWORD m_sdwTerminalTypesCount;
179};
180
181template <class T> HRESULT CreateMSPCallHelper(CMSPAddress *pCMSPAddress,MSP_HANDLE htCall,DWORD dwReserved,DWORD dwMediaType,IUnknown *pOuterUnknown,IUnknown **ppMSPCall,T **ppCMSPCall)
182{
183  LOG((MSP_TRACE,"CreateMSPCallHelper - enter"));
184  HRESULT hr;
185  T *pMSPCall;
186  IUnknown *pUnknown = NULL;
187  if(IsBadReadPtr(pCMSPAddress,sizeof(CMSPAddress))) {
188    LOG((MSP_ERROR,"CreateMSPCallHelper - bad address pointer - exit E_POINTER"));
189    return E_POINTER;
190  }
191  if(IsBadReadPtr(pOuterUnknown,sizeof(IUnknown))) {
192    LOG((MSP_ERROR,"CreateMSPCallHelper - bad outer unknown - we require aggregation - exit E_POINTER"));
193    return E_POINTER;
194  }
195  if(IsBadReadPtr(ppMSPCall,sizeof(IUnknown *))) {
196    LOG((MSP_ERROR,"CreateMSPCallHelper - bad iunknown return ptr - exit E_POINTER"));
197    return E_POINTER;
198  }
199  if(IsBadReadPtr(ppCMSPCall,sizeof(T *))) {
200    LOG((MSP_ERROR,"CreateMSPCallHelper - bad class return ptr - exit E_POINTER"));
201    return E_POINTER;
202  }
203  if(! pCMSPAddress->IsValidSetOfMediaTypes(dwMediaType,pCMSPAddress->GetCallMediaTypes())) {
204    LOG((MSP_ERROR,"CreateMSPCallHelper - unsupported media types - exit TAPI_E_INVALIDMEDIATYPE"));
205    return TAPI_E_INVALIDMEDIATYPE;
206  }
207  CComAggObject<T> *pCall;
208  pCall = new CComAggObject<T>(pOuterUnknown);
209  if(!pCall) {
210    LOG((MSP_ERROR,"CreateMSPCallHelper - could not create agg call instance - exit E_OUTOFMEMORY"));
211    return E_OUTOFMEMORY;
212  }
213  hr = pCall->QueryInterface(IID_IUnknown,(void **)&pUnknown);
214  if(FAILED(hr)) {
215    LOG((MSP_ERROR,"CreateMSPCallHelper - QueryInterface failed: %x",hr));
216    delete pCall;
217    return hr;
218  }
219  hr = pCall->FinalConstruct();
220  if(FAILED(hr)) {
221    LOG((MSP_ERROR,"CreateMSPCallHelper - FinalConstruct failed: %x.",hr));
222    pUnknown->Release();
223    return hr;
224  }
225  pMSPCall = dynamic_cast<T *>(&(pCall->m_contained));
226  if(!pMSPCall) {
227    LOG((MSP_ERROR,"CreateMSPCallHelper - can not cast to agg object to class pointer - exit E_UNEXPECTED"));
228    pUnknown->Release();
229    return E_UNEXPECTED;
230  }
231  hr = pMSPCall->Init(pCMSPAddress,htCall,dwReserved,dwMediaType);
232  if(FAILED(hr)) {
233    LOG((MSP_ERROR,"CreateMSPCallHelper - call init failed: %x",hr));
234    pUnknown->Release();
235    return hr;
236  }
237  *ppMSPCall = pUnknown;
238  *ppCMSPCall = pMSPCall;
239  LOG((MSP_TRACE,"CreateMSPCallHelper - exit S_OK"));
240  return hr;
241}
242
243template <class T> HRESULT ShutdownMSPCallHelper(IUnknown *pUnknown,T **ppCMSPCall)
244{
245  LOG((MSP_TRACE,"ShutdownMSPCallHelper - enter"));
246  if(IsBadReadPtr(pUnknown,sizeof(IUnknown))) {
247    LOG((MSP_ERROR,"ShutdownMSPCallHelper - bad IUnknown pointer - exit E_POINTER"));
248    return E_POINTER;
249  }
250  if(IsBadWritePtr(ppCMSPCall,sizeof(T *))) {
251    LOG((MSP_ERROR,"ShutdownMSPCallHelper - bad return pointer - exit E_POINTER"));
252    return E_POINTER;
253  }
254  T *pMSPCall;
255  CComAggObject<T> *pCall = dynamic_cast<CComAggObject<T> *> (pUnknown);
256  if(!pCall) {
257    LOG((MSP_ERROR,"ShutdownMSPCallHelper - can't cast unknown to agg object pointer - exit E_UNEXPECTED"));
258    return E_UNEXPECTED;
259  }
260  pMSPCall = dynamic_cast<T *> (&(pCall->m_contained));
261  if(!pMSPCall) {
262    LOG((MSP_ERROR,"ShutdownMSPCallHelper - can't cast contained unknown to class pointer - exit E_UNEXPECTED"));
263    return E_UNEXPECTED;
264  }
265  HRESULT hr = pMSPCall->ShutDown();
266  if(FAILED(hr)) {
267    LOG((MSP_ERROR,"ShutdownMSPCallHelper - ShutDownMSPCall failed: %x",hr));
268    return hr;
269  }
270  *ppCMSPCall = pMSPCall;
271  LOG((MSP_TRACE,"ShutdownMSPCallHelper - exit S_OK"));
272  return S_OK;
273}
274#endif
275