aboutsummaryrefslogtreecommitdiff
path: root/x86_64-w64-mingw32/include/mspaddr.h
blob: 21c1b38e9a08e9e6886d6a3449008b47afda03f8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
#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