1 #ifndef __MSPADDR_H_
2 #define __MSPADDR_H_
3 
4 typedef struct {
5   LIST_ENTRY Link;
6   MSP_EVENT_INFO MSPEventInfo;
7 } MSPEVENTITEM,*PMSPEVENTITEM;
8 
9 MSPEVENTITEM *AllocateEventItem(SIZE_T nExtraBytes = 0);
10 WINBOOL FreeEventItem(MSPEVENTITEM *pEventItemToFree);
11 
12 typedef HRESULT (*PFNCREATETERM)(CComPtr<IMoniker> pMoniker,MSP_HANDLE htAddress,ITTerminal **pTerm);
13 
14 typedef struct {
15   DWORD dwMediaType;
16   const CLSID *clsidClassManager;
17   PFNCREATETERM pfnCreateTerm;
18 } STATIC_TERMINAL_TYPE;
19 
20 class ATL_NO_VTABLE CPlugTerminalClassInfo : public IDispatchImpl<ITPluggableTerminalClassInfo,&IID_ITPluggableTerminalClassInfo,&LIBID_TAPI3Lib>,public CComObjectRootEx<CComMultiThreadModel>,public CMSPObjectSafetyImpl
21 {
22 public:
23   DECLARE_GET_CONTROLLING_UNKNOWN()
24   virtual HRESULT FinalConstruct(void);
25   BEGIN_COM_MAP(CPlugTerminalClassInfo)
COM_INTERFACE_ENTRY(ITPluggableTerminalClassInfo)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()
31 public:
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   }
~CPlugTerminalClassInfo()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   }
55 public:
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);
63 private:
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;
73 private:
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 
84 class ATL_NO_VTABLE CPlugTerminalSuperclassInfo : public IDispatchImpl<ITPluggableTerminalSuperclassInfo,&IID_ITPluggableTerminalSuperclassInfo,&LIBID_TAPI3Lib>,public CComObjectRootEx<CComMultiThreadModel>,public CMSPObjectSafetyImpl
85 {
86 public:
87   DECLARE_GET_CONTROLLING_UNKNOWN()
88   virtual HRESULT FinalConstruct(void);
89   BEGIN_COM_MAP(CPlugTerminalSuperclassInfo)
COM_INTERFACE_ENTRY(ITPluggableTerminalSuperclassInfo)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()
95 public:
96   CPlugTerminalSuperclassInfo() : m_bstrCLSID(NULL),m_bstrName(NULL),m_pFTM(NULL) {
97   }
~CPlugTerminalSuperclassInfo()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   }
109 public:
110   STDMETHOD(get_Name)(BSTR *pName);
111   STDMETHOD(get_CLSID)(BSTR *pCLSID);
112 private:
113   CMSPCritSection m_CritSect;
114   BSTR m_bstrCLSID;
115   BSTR m_bstrName;
116   IUnknown *m_pFTM;
117 private:
118   STDMETHOD(put_Name)(BSTR bstrName);
119   STDMETHOD(put_CLSID)(BSTR bstrCLSID);
120   friend class CMSPAddress;
121 };
122 
123 class ATL_NO_VTABLE CMSPAddress : public CComObjectRootEx<CComMultiThreadModelNoCS>,public ITMSPAddress,public IDispatchImpl<ITTerminalSupport2,&IID_ITTerminalSupport2,&LIBID_TAPI3Lib>
124 {
125 public:
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);
154 protected:
155   virtual HRESULT GetStaticTerminals (DWORD *pdwNumTerminals,ITTerminal **ppTerminals);
156   virtual HRESULT GetDynamicTerminalClasses (DWORD *pdwNumClasses,IID *pTerminalClasses);
157 public:
158   virtual WINBOOL IsValidSetOfMediaTypes(DWORD dwMediaType,DWORD dwMask);
159   virtual HRESULT PostEvent(MSPEVENTITEM *EventItem);
160   virtual DWORD GetCallMediaTypes(void) = 0;
161 protected:
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);
166 public:
167   virtual HRESULT PnpNotifHandler(WINBOOL bDeviceArrival);
168 protected:
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;
176 private:
177   static const STATIC_TERMINAL_TYPE m_saTerminalTypes[];
178   static const DWORD m_sdwTerminalTypesCount;
179 };
180 
CreateMSPCallHelper(CMSPAddress * pCMSPAddress,MSP_HANDLE htCall,DWORD dwReserved,DWORD dwMediaType,IUnknown * pOuterUnknown,IUnknown ** ppMSPCall,T ** ppCMSPCall)181 template <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 
ShutdownMSPCallHelper(IUnknown * pUnknown,T ** ppCMSPCall)243 template <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