| 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) |
| 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 |
} |
| 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) |
| 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 |
} |
| 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 |
|
| 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 |
|
| 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 |