MspAddr.h
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:17k
源码类别:

模拟服务器

开发平台:

C/C++

  1. /*++
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. Module Name:
  4.     MSPaddr.h
  5. Abstract:
  6. Declaration of the CMSPAddress
  7. --*/
  8. #ifndef __MSPADDR_H_
  9. #define __MSPADDR_H_
  10. typedef struct 
  11. {
  12.    LIST_ENTRY       Link;           // The link node. See ntrtl.h for detail.
  13.    MSP_EVENT_INFO   MSPEventInfo;   // The event code.
  14.    
  15. } MSPEVENTITEM, *PMSPEVENTITEM;
  16. //
  17. // these functions should be used to allocate and deallocate MSPEVENTITEM
  18. // structures. In case of failure, the caller can call GetLastError()
  19. // to get exact cause of the failure.
  20. //
  21. //
  22. // nExtraBytes specifies how many extra (in addition to sizeof(MSPEVENTITEM)) 
  23. // bytes to allocate.
  24. //
  25. MSPEVENTITEM *AllocateEventItem(SIZE_T nExtraBytes = 0);
  26. BOOL FreeEventItem(MSPEVENTITEM *pEventItemToFree);
  27. typedef HRESULT (*PFNCREATETERM) (
  28.     IN  CComPtr<IMoniker>   pMoniker,
  29.     IN  MSP_HANDLE          htAddress,
  30.     OUT ITTerminal        **pTerm
  31.     );
  32. typedef struct
  33. {
  34.     DWORD                dwMediaType;
  35.     const CLSID        * clsidClassManager;
  36.     PFNCREATETERM        pfnCreateTerm;
  37. } STATIC_TERMINAL_TYPE;
  38. class ATL_NO_VTABLE CPlugTerminalClassInfo : 
  39.     public IDispatchImpl<ITPluggableTerminalClassInfo, &IID_ITPluggableTerminalClassInfo, &LIBID_TAPI3Lib>,
  40.     public CComObjectRootEx<CComMultiThreadModel>,
  41.     public CMSPObjectSafetyImpl
  42. {
  43. public:
  44. DECLARE_GET_CONTROLLING_UNKNOWN()
  45. virtual HRESULT FinalConstruct(void);
  46. BEGIN_COM_MAP(CPlugTerminalClassInfo)
  47.     COM_INTERFACE_ENTRY(ITPluggableTerminalClassInfo)
  48.     COM_INTERFACE_ENTRY(IDispatch)
  49.     COM_INTERFACE_ENTRY(IObjectSafety)
  50.         COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pFTM)
  51. END_COM_MAP()
  52. public:
  53.     CPlugTerminalClassInfo() :
  54.         m_bstrName(NULL),
  55.         m_bstrCompany(NULL),
  56.         m_bstrVersion(NULL),
  57.         m_bstrCLSID(NULL),
  58.         m_bstrTerminalClass(NULL),
  59.         m_lMediaType(1),
  60.         m_Direction(TD_CAPTURE),
  61.         m_pFTM(NULL)
  62.     {
  63.     }
  64.     ~CPlugTerminalClassInfo()
  65.     {
  66.         if( m_bstrName )
  67.         {
  68.             SysFreeString( m_bstrName );
  69.         }
  70.         if( m_bstrCompany )
  71.         {
  72.             SysFreeString( m_bstrCompany );
  73.         }
  74.         if( m_bstrVersion )
  75.         {
  76.             SysFreeString( m_bstrVersion );
  77.         }
  78.         if( m_bstrCLSID )
  79.         {
  80.             SysFreeString( m_bstrCLSID );
  81.         }
  82.         if( m_bstrTerminalClass )
  83.         {
  84.             SysFreeString( m_bstrTerminalClass );
  85.         }
  86.         if( m_pFTM )
  87.         {
  88.             m_pFTM->Release();
  89.         }
  90.     }
  91. public:
  92.     STDMETHOD(get_Name)(
  93.         /*[out, retval]*/ BSTR*     pName
  94.         );
  95.     STDMETHOD(get_Company)(
  96.         /*[out, retval]*/ BSTR*     pCompany
  97.         );
  98.     STDMETHOD(get_Version)(
  99.         /*[out, retval]*/ BSTR*     pVersion
  100.         );
  101.     STDMETHOD(get_TerminalClass)(
  102.         /*[out, retval]*/ BSTR*     pTerminalClass
  103.         );
  104.     STDMETHOD(get_CLSID)(
  105.         /*[out, retval]*/ BSTR*     pCLSID
  106.         );
  107.     STDMETHOD(get_Direction)(
  108.         /*[out, retval]*/ TERMINAL_DIRECTION*  pDirection
  109.         );
  110.     STDMETHOD(get_MediaTypes)(
  111.         /*[out, retval]*/ long*     pMediaTypes
  112.         );
  113. private:
  114.     CMSPCritSection     m_CritSect;     // Critical Section 
  115.     BSTR    m_bstrName;
  116.     BSTR    m_bstrCompany;
  117.     BSTR    m_bstrVersion;
  118.     BSTR    m_bstrTerminalClass;
  119.     BSTR    m_bstrCLSID;
  120.     long    m_lMediaType;
  121.     TERMINAL_DIRECTION   m_Direction;
  122.     IUnknown*            m_pFTM;         // pointer to the free threaded marshaler
  123. private:
  124.     STDMETHOD(put_Name)(
  125.         /*[in]*/    BSTR            bstrName
  126.         );
  127.     STDMETHOD(put_Company)(
  128.         /*[in]*/    BSTR            bstrCompany
  129.         );
  130.     STDMETHOD(put_Version)(
  131.        /*[in]*/    BSTR            bstrVersion
  132.         );
  133.     STDMETHOD(put_TerminalClass)(
  134.         /*[in]*/    BSTR            bstrTerminalClass
  135.         );
  136.     STDMETHOD(put_CLSID)(
  137.         /*[in]*/    BSTR            bstrCLSID
  138.         );
  139.     STDMETHOD(put_Direction)(
  140.         /*[in]*/    TERMINAL_DIRECTION  nDirection
  141.         );
  142.     STDMETHOD(put_MediaTypes)(
  143.         /*[in]*/    long            nMediaTypes
  144.         );
  145. friend class CMSPAddress;
  146. };
  147. class ATL_NO_VTABLE CPlugTerminalSuperclassInfo : 
  148.     public IDispatchImpl<ITPluggableTerminalSuperclassInfo, &IID_ITPluggableTerminalSuperclassInfo, &LIBID_TAPI3Lib>,
  149.     public CComObjectRootEx<CComMultiThreadModel>,
  150.     public CMSPObjectSafetyImpl
  151. {
  152. public:
  153. DECLARE_GET_CONTROLLING_UNKNOWN()
  154. virtual HRESULT FinalConstruct(void);
  155. BEGIN_COM_MAP(CPlugTerminalSuperclassInfo)
  156.     COM_INTERFACE_ENTRY(ITPluggableTerminalSuperclassInfo)
  157.     COM_INTERFACE_ENTRY(IDispatch)
  158.     COM_INTERFACE_ENTRY(IObjectSafety)
  159.         COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pFTM)
  160. END_COM_MAP()
  161. public:
  162.     CPlugTerminalSuperclassInfo() :
  163.         m_bstrCLSID(NULL),
  164.         m_bstrName(NULL),
  165.         m_pFTM(NULL)
  166.     {
  167.     }
  168.     ~CPlugTerminalSuperclassInfo()
  169.     {
  170.         if( m_bstrName )
  171.         {
  172.             SysFreeString( m_bstrName );
  173.         }
  174.         if( m_bstrCLSID )
  175.         {
  176.             SysFreeString( m_bstrCLSID );
  177.         }
  178.         if( m_pFTM )
  179.         {
  180.             m_pFTM->Release();
  181.         }
  182.     }
  183. public:
  184.     STDMETHOD(get_Name)(
  185.         /*[out, retval]*/ BSTR*          pName
  186.         );
  187.     STDMETHOD(get_CLSID)(
  188.         /*[out, retval]*/ BSTR*           pCLSID
  189.         );
  190. private:
  191.     CMSPCritSection     m_CritSect;     // Critical Section 
  192.     BSTR    m_bstrCLSID;
  193.     BSTR    m_bstrName;
  194.     IUnknown*            m_pFTM;         // pointer to the free threaded marshaler
  195. private:
  196.     STDMETHOD(put_Name)(
  197.         /*[in]*/          BSTR            bstrName
  198.         );
  199.     STDMETHOD(put_CLSID)(
  200.         /*[in]*/         BSTR            bstrCLSID
  201.         );
  202. friend class CMSPAddress;
  203. };
  204. /*++
  205. Class Description:
  206.     Represents an MSP address.
  207. --*/
  208. class ATL_NO_VTABLE CMSPAddress : 
  209.     public CComObjectRootEx<CComMultiThreadModelNoCS>,
  210.     public ITMSPAddress,
  211.     public IDispatchImpl<ITTerminalSupport2, &IID_ITTerminalSupport2, &LIBID_TAPI3Lib>
  212. {
  213. public:
  214. // No need for free thread marshaling, because the MSP address object is
  215. // always aggregated by the TAPI3 address object.
  216. BEGIN_COM_MAP( CMSPAddress )
  217.     COM_INTERFACE_ENTRY( ITMSPAddress )
  218.     COM_INTERFACE_ENTRY( IDispatch )
  219.     COM_INTERFACE_ENTRY( ITTerminalSupport )
  220.     COM_INTERFACE_ENTRY( ITTerminalSupport2 )
  221. END_COM_MAP()
  222. // The DERIVED class should DECLARE_AGGREGATABLE(className)
  223. DECLARE_GET_CONTROLLING_UNKNOWN()
  224. DECLARE_VQI()
  225.     CMSPAddress();
  226.     virtual ~CMSPAddress();
  227.     virtual ULONG MSPAddressAddRef(void) = 0;
  228.     virtual ULONG MSPAddressRelease(void) = 0;
  229. // ITMSPAddress methods, called by TAPI.
  230.     STDMETHOD (Initialize) (
  231.         IN      MSP_HANDLE          htEvent
  232.         );
  233.     STDMETHOD (Shutdown) ();
  234.     STDMETHOD (CreateMSPCall) (
  235.         IN      MSP_HANDLE          htCall,
  236.         IN      DWORD               dwReserved,
  237.         IN      DWORD               dwMediaType,
  238.         IN      IUnknown *          pOuterUnknown,
  239.         OUT     IUnknown **         ppMSPCall
  240.         ) = 0;
  241.     STDMETHOD (ShutdownMSPCall) (
  242.         IN      IUnknown *          pMSPCall
  243.         ) = 0;
  244.     STDMETHOD (ReceiveTSPData) (
  245.         IN      IUnknown        *   pMSPCall,
  246.         IN      LPBYTE              pBuffer,
  247.         IN      DWORD               dwBufferSize
  248.         );
  249.     STDMETHOD (GetEvent) (
  250.         IN OUT  DWORD *             pdwSize,
  251.         OUT     BYTE *              pBuffer
  252.         );
  253. // ITTerminalSupport methods, called by TAPI and/or the app.
  254.     STDMETHOD (get_StaticTerminals) (
  255.             OUT  VARIANT * pVariant
  256.             );
  257.     STDMETHOD (EnumerateStaticTerminals) (
  258.             OUT  IEnumTerminal ** ppTerminalEnumerator
  259.             );
  260.     STDMETHOD (get_DynamicTerminalClasses) (
  261.             OUT  VARIANT * pVariant
  262.             );
  263.     STDMETHOD (EnumerateDynamicTerminalClasses) (
  264.             OUT  IEnumTerminalClass ** ppTerminalClassEnumerator
  265.             );
  266.     STDMETHOD (CreateTerminal) (
  267.             IN   BSTR pTerminalClass,
  268.             IN   long lMediaType,
  269.             IN   TERMINAL_DIRECTION Direction,
  270.             OUT  ITTerminal ** ppTerminal
  271.             );
  272.     
  273.     STDMETHOD (GetDefaultStaticTerminal) (
  274.         IN      long                lMediaType,
  275.         IN      TERMINAL_DIRECTION  Direction,
  276.         OUT     ITTerminal **       ppTerminal
  277.         );
  278.     STDMETHOD (get_PluggableSuperclasses)( 
  279.         OUT VARIANT * pVariant
  280.         );
  281.     STDMETHOD (EnumeratePluggableSuperclasses)( 
  282.         OUT IEnumPluggableSuperclassInfo** ppSuperclassEnumerator 
  283.         );
  284.     STDMETHOD (get_PluggableTerminalClasses)( 
  285.         IN  BSTR bstrTerminalSuperclass,
  286.         IN  long lMediaType,
  287.         OUT VARIANT * pVariant
  288.         );
  289.     STDMETHOD (EnumeratePluggableTerminalClasses)(
  290.         IN  CLSID iidTerminalSuperclass,
  291.         IN  long lMediaType,
  292.         OUT IEnumPluggableTerminalClassInfo ** ppClassEnumerator 
  293.         );
  294. protected:
  295.     // ITTerminalSupport helper methods
  296.     virtual HRESULT GetStaticTerminals (
  297.         IN OUT  DWORD       *       pdwNumTerminals,
  298.         OUT     ITTerminal **       ppTerminals
  299.         );
  300.     virtual HRESULT GetDynamicTerminalClasses (
  301.         IN OUT  DWORD *             pdwNumClasses,
  302.         OUT     IID *               pTerminalClasses
  303.         );
  304. public:
  305. // methods used by the MSPCall object.
  306.     //
  307.     // Check to see if the mediatype is non-zero and is in the mask.
  308.     // Your MSP can override this if it needs to do special checks on
  309.     // specific combinations of media types (e.g., can never have more
  310.     // than one media type on a call, can never have video without
  311.     // audio, etc.) The default implementation accepts any nonempty
  312.     // set of media types that is a subset of the set of all supported
  313.     // media types (specified via the GetCallMediaTypes method).
  314.     //
  315.     virtual BOOL IsValidSetOfMediaTypes(DWORD dwMediaType, DWORD dwMask);
  316.     // Note: the eventItem must be allocated by malloc or new
  317.     // (when the event is processed, it is deleted).
  318.     virtual HRESULT PostEvent(
  319.         IN      MSPEVENTITEM *      EventItem
  320.         );
  321. // method used by template function
  322.     virtual DWORD GetCallMediaTypes(void) = 0;
  323. protected:
  324.     // Private helper function (protected so derived class can call it)
  325.     virtual HRESULT IsMonikerInTerminalList(IMoniker* pMoniker);
  326.     virtual HRESULT UpdateTerminalListForPnp(
  327.         IN      BOOL                bDeviceArrival
  328.         );
  329.     virtual HRESULT UpdateTerminalList(void);
  330.     virtual HRESULT ReceiveTSPAddressData(
  331.         IN      PBYTE               pBuffer,
  332.         IN      DWORD               dwSize
  333.         );
  334. public:
  335. // methods used by the MSPThread object.
  336.     virtual HRESULT PnpNotifHandler(
  337.         IN      BOOL                bDeviceArrival
  338.         );
  339.     
  340. protected:
  341.     // The handle to TAPI's event, which is used to notify TAPI that the MSP 
  342.     // wants to send data to it.
  343.     HANDLE              m_htEvent;
  344.     // List of events.
  345.     LIST_ENTRY          m_EventList;
  346.     // The lock that protects the data related to event handling with TAPI.
  347.     CMSPCritSection     m_EventDataLock;
  348.     // The pointer to the terminal manager object.
  349.     ITTerminalManager * m_pITTerminalManager;
  350.     // The list of static terminals that can be used on the address.
  351.     CMSPArray <ITTerminal *>  m_Terminals;
  352.     BOOL                m_fTerminalsUpToDate;
  353.     // The lock that protects the data members for terminal operations.
  354.     CMSPCritSection     m_TerminalDataLock;
  355. private:
  356.     static const STATIC_TERMINAL_TYPE m_saTerminalTypes[];
  357.     static const DWORD m_sdwTerminalTypesCount;
  358. };
  359. template <class T>
  360. HRESULT CreateMSPCallHelper(
  361.     IN      CMSPAddress *       pCMSPAddress,
  362.     IN      MSP_HANDLE          htCall,
  363.     IN      DWORD               dwReserved,
  364.     IN      DWORD               dwMediaType,
  365.     IN      IUnknown *          pOuterUnknown,
  366.     OUT     IUnknown **         ppMSPCall,
  367.     OUT     T **                ppCMSPCall
  368.     )
  369. {
  370.     LOG((MSP_TRACE, "CreateMSPCallHelper - enter"));
  371.     HRESULT hr;
  372.     T * pMSPCall;
  373.     IUnknown *pUnknown = NULL;
  374.     //
  375.     // Check parameters.
  376.     //
  377.     if ( IsBadReadPtr(pCMSPAddress, sizeof(CMSPAddress) ) )
  378.     {
  379.         LOG((MSP_ERROR, "CreateMSPCallHelper - "
  380.             "bad address pointer - exit E_POINTER"));
  381.         
  382.         return E_POINTER;
  383.     }
  384.     if ( IsBadReadPtr(pOuterUnknown, sizeof(IUnknown) ) )
  385.     {
  386.         LOG((MSP_ERROR, "CreateMSPCallHelper - "
  387.             "bad outer unknown - we require aggregation - exit E_POINTER"));
  388.         
  389.         return E_POINTER;
  390.     }
  391.     if ( IsBadReadPtr(ppMSPCall, sizeof(IUnknown *) ) )
  392.     {
  393.         LOG((MSP_ERROR, "CreateMSPCallHelper - "
  394.             "bad iunknown return ptr - exit E_POINTER"));
  395.         
  396.         return E_POINTER;
  397.     }
  398.     if ( IsBadReadPtr(ppCMSPCall, sizeof(T *) ) )
  399.     {
  400.         LOG((MSP_ERROR, "CreateMSPCallHelper - "
  401.             "bad class return ptr - exit E_POINTER"));
  402.         
  403.         return E_POINTER;
  404.     }
  405.     if ( ! pCMSPAddress->IsValidSetOfMediaTypes(
  406.                                         dwMediaType,
  407.                                         pCMSPAddress->GetCallMediaTypes() ) )
  408.     {
  409.         LOG((MSP_ERROR, "CreateMSPCallHelper - "
  410.             "unsupported media types - exit TAPI_E_INVALIDMEDIATYPE"));
  411.         
  412.         return TAPI_E_INVALIDMEDIATYPE;
  413.     }
  414.     // dwReserved is meaningless.
  415.     // We have no way of checking htCall.
  416.     // the pOuterUnknown is not NULL. This object is going to be aggregated.
  417.     CComAggObject<T> * pCall;
  418.     pCall = new CComAggObject<T>(pOuterUnknown);
  419.     if (pCall == NULL)
  420.     {
  421.         LOG((MSP_ERROR, "CreateMSPCallHelper - "
  422.             "could not create agg call instance - exit E_OUTOFMEMORY"));
  423.         return E_OUTOFMEMORY;
  424.     }
  425.     // query the interface on the containing object.
  426.     hr = pCall->QueryInterface(IID_IUnknown, (void **)&pUnknown);
  427.     if (FAILED(hr))
  428.     {
  429.         LOG((MSP_ERROR, "CreateMSPCallHelper - "
  430.             "QueryInterface failed: %x", hr));
  431.         delete pCall;
  432.         return hr;
  433.     }
  434.     hr = pCall->FinalConstruct();
  435.     if (FAILED(hr))
  436.     {
  437.         LOG((MSP_ERROR, "CreateMSPCallHelper - "
  438.             "FinalConstruct failed: %x.", hr));
  439.         pUnknown->Release();
  440.         return hr;
  441.     }
  442.     // Get a pointer to the real MSPCall object.
  443.     pMSPCall = dynamic_cast<T *>(&(pCall->m_contained));
  444.     if (pMSPCall == NULL)
  445.     {
  446.         LOG((MSP_ERROR, "CreateMSPCallHelper - "
  447.             "can not cast to agg object to class pointer - "
  448.             "exit E_UNEXPECTED"));
  449.     
  450.         pUnknown->Release();
  451.         return E_UNEXPECTED;
  452.     }
  453.     //
  454.     // initialize the call.
  455.     //
  456.     
  457.     hr = pMSPCall->Init(pCMSPAddress, htCall, dwReserved, dwMediaType);
  458.     if (FAILED(hr))
  459.     {
  460.         LOG((MSP_ERROR, "CreateMSPCallHelper - "
  461.             "call init failed: %x", hr));
  462.         pUnknown->Release();
  463.         return hr;
  464.     }
  465.     *ppMSPCall = pUnknown;
  466.     *ppCMSPCall = pMSPCall;
  467.     LOG((MSP_TRACE, "CreateMSPCallHelper - exit S_OK"));
  468.     return hr;
  469. }
  470. template <class T>
  471. HRESULT ShutdownMSPCallHelper(
  472.     IN      IUnknown *          pUnknown,
  473.     OUT     T **                ppCMSPCall
  474.     )
  475. {
  476.     LOG((MSP_TRACE, "ShutdownMSPCallHelper - enter"));
  477.     if ( IsBadReadPtr(pUnknown, sizeof(IUnknown) ) )
  478.     {
  479.         LOG((MSP_ERROR, "ShutdownMSPCallHelper - "
  480.             "bad IUnknown pointer - exit E_POINTER"));
  481.         return E_POINTER;
  482.     }
  483.     
  484.     if ( IsBadWritePtr(ppCMSPCall, sizeof(T *) ) )
  485.     {
  486.         LOG((MSP_ERROR, "ShutdownMSPCallHelper - "
  487.             "bad return pointer - exit E_POINTER"));
  488.         return E_POINTER;
  489.     }
  490.     T * pMSPCall;
  491.     CComAggObject<T> * pCall = dynamic_cast<CComAggObject<T> *> (pUnknown);
  492.     if (pCall == NULL)
  493.     {
  494.         LOG((MSP_ERROR, "ShutdownMSPCallHelper - "
  495.             "can't cast unknown to agg object pointer - exit E_UNEXPECTED"));
  496.     
  497.         return E_UNEXPECTED;
  498.     }
  499.     //
  500.     // It was aggregated. Get a pointer to the real MSPCall object.
  501.     //
  502.     pMSPCall = dynamic_cast<T *> (&(pCall->m_contained));
  503.     if (pMSPCall == NULL)
  504.     {
  505.         LOG((MSP_ERROR, "ShutdownMSPCallHelper - "
  506.             "can't cast contained unknown to class pointer - "
  507.             "exit E_UNEXPECTED"));
  508.     
  509.         return E_UNEXPECTED;
  510.     }
  511.     //
  512.     // Now we have a call to shut down. Shut it down.
  513.     //
  514.     HRESULT hr = pMSPCall->ShutDown();
  515.     if (FAILED(hr))
  516.     {
  517.         LOG((MSP_ERROR, "ShutdownMSPCallHelper - "
  518.             "ShutDownMSPCall failed: %x", hr));
  519.         
  520.         return hr;
  521.     }
  522.     *ppCMSPCall = pMSPCall;
  523.     LOG((MSP_TRACE, "ShutdownMSPCallHelper - exit S_OK"));
  524.     return S_OK;
  525. }
  526. #endif //__MSPADDRESS_H_