home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Internet 2000 May / MICD_2000_05.iso / CBuilder5 / INSTALL / DATA1.CAB / Program_Built_Files / Include / mspaddr.h < prev    next >
C/C++ Source or Header  |  2000-02-01  |  11KB  |  424 lines

  1. /*++
  2.  
  3. Copyright (c) 1998-1999 Microsoft Corporation
  4.  
  5. Module Name:
  6.  
  7.     MSPaddr.h
  8.  
  9. Abstract:
  10.  
  11. Declaration of the CMSPAddress
  12.  
  13. --*/
  14.  
  15. #ifndef __MSPADDR_H_
  16. #pragma option push -b -a8 -pc -A- /*P_O_Push*/
  17. #define __MSPADDR_H_
  18.  
  19. typedef struct 
  20. {
  21.    LIST_ENTRY       Link;           // The link node. See ntrtl.h for detail.
  22.    MSP_EVENT_INFO   MSPEventInfo;   // The event code.
  23.    
  24. } MSPEVENTITEM, *PMSPEVENTITEM;
  25.  
  26. typedef HRESULT (*PFNCREATETERM) (
  27.     IN  CComPtr<IMoniker>   pMoniker,
  28.     IN  MSP_HANDLE          htAddress,
  29.     OUT ITTerminal        **pTerm
  30.     );
  31.  
  32. typedef struct
  33. {
  34.     DWORD                dwMediaType;
  35.     const CLSID        * clsidClassManager;
  36.     PFNCREATETERM        pfnCreateTerm;
  37.  
  38. } STATIC_TERMINAL_TYPE;
  39.  
  40. /*++
  41.  
  42. Class Description:
  43.  
  44.     Represents an MSP address.
  45.  
  46. --*/
  47.  
  48. class ATL_NO_VTABLE CMSPAddress : 
  49.     public CComObjectRootEx<CComMultiThreadModelNoCS>,
  50.     public ITMSPAddress,
  51.     public IDispatchImpl<ITTerminalSupport, &IID_ITTerminalSupport, &LIBID_TAPI3Lib>
  52. {
  53. public:
  54.  
  55. // No need for free thread marshaling, because the MSP address object is
  56. // always aggregated by the TAPI3 address object.
  57.  
  58. BEGIN_COM_MAP( CMSPAddress )
  59.     COM_INTERFACE_ENTRY( ITMSPAddress )
  60.     COM_INTERFACE_ENTRY( IDispatch )
  61.     COM_INTERFACE_ENTRY( ITTerminalSupport )
  62. END_COM_MAP()
  63.  
  64. // The DERIVED class should DECLARE_AGGREGATABLE(className)
  65.  
  66. DECLARE_GET_CONTROLLING_UNKNOWN()
  67.  
  68. DECLARE_VQI()
  69.  
  70.     CMSPAddress();
  71.     virtual ~CMSPAddress();
  72.     virtual ULONG MSPAddressAddRef(void) = 0;
  73.     virtual ULONG MSPAddressRelease(void) = 0;
  74.  
  75.  
  76.  
  77. // ITMSPAddress methods, called by TAPI.
  78.     STDMETHOD (Initialize) (
  79.         IN      MSP_HANDLE          htEvent
  80.         );
  81.  
  82.     STDMETHOD (Shutdown) ();
  83.  
  84.     STDMETHOD (CreateMSPCall) (
  85.         IN      MSP_HANDLE          htCall,
  86.         IN      DWORD               dwReserved,
  87.         IN      DWORD               dwMediaType,
  88.         IN      IUnknown *          pOuterUnknown,
  89.         OUT     IUnknown **         ppMSPCall
  90.         ) = 0;
  91.  
  92.     STDMETHOD (ShutdownMSPCall) (
  93.         IN      IUnknown *          pMSPCall
  94.         ) = 0;
  95.  
  96.     STDMETHOD (ReceiveTSPData) (
  97.         IN      IUnknown        *   pMSPCall,
  98.         IN      LPBYTE              pBuffer,
  99.         IN      DWORD               dwBufferSize
  100.         );
  101.  
  102.     STDMETHOD (GetEvent) (
  103.         IN OUT  DWORD *             pdwSize,
  104.         OUT     BYTE *              pBuffer
  105.         );
  106.  
  107. // ITTerminalSupport methods, called by TAPI and/or the app.
  108.     STDMETHOD (get_StaticTerminals) (
  109.             OUT  VARIANT * pVariant
  110.             );
  111.  
  112.     STDMETHOD (EnumerateStaticTerminals) (
  113.             OUT  IEnumTerminal ** ppTerminalEnumerator
  114.             );
  115.  
  116.     STDMETHOD (get_DynamicTerminalClasses) (
  117.             OUT  VARIANT * pVariant
  118.             );
  119.  
  120.     STDMETHOD (EnumerateDynamicTerminalClasses) (
  121.             OUT  IEnumTerminalClass ** ppTerminalClassEnumerator
  122.             );
  123.  
  124.     STDMETHOD (CreateTerminal) (
  125.             IN   BSTR pTerminalClass,
  126.             IN   long lMediaType,
  127.             IN   TERMINAL_DIRECTION Direction,
  128.             OUT  ITTerminal ** ppTerminal
  129.             );
  130.     
  131.     STDMETHOD (GetDefaultStaticTerminal) (
  132.         IN      long                lMediaType,
  133.         IN      TERMINAL_DIRECTION  Direction,
  134.         OUT     ITTerminal **       ppTerminal
  135.         );
  136.  
  137. protected:
  138.     // ITTerminalSupport helper methods
  139.  
  140.     virtual HRESULT GetStaticTerminals (
  141.         IN OUT  DWORD       *       pdwNumTerminals,
  142.         OUT     ITTerminal **       ppTerminals
  143.         );
  144.  
  145.     virtual HRESULT GetDynamicTerminalClasses (
  146.         IN OUT  DWORD *             pdwNumClasses,
  147.         OUT     IID *               pTerminalClasses
  148.         );
  149.  
  150. public:
  151. // methods used by the MSPCall object.
  152.  
  153.     //
  154.     // Check to see if the mediatype is non-zero and is in the mask.
  155.     // Your MSP can override this if it needs to do special checks on
  156.     // specific combinations of media types (e.g., can never have more
  157.     // than one media type on a call, can never have video without
  158.     // audio, etc.) The default implementation accepts any nonempty
  159.     // set of media types that is a subset of the set of all supported
  160.     // media types (specified via the GetCallMediaTypes method).
  161.     //
  162.     virtual BOOL IsValidSetOfMediaTypes(DWORD dwMediaType, DWORD dwMask);
  163.  
  164.     // Note: the eventItem must be allocated by malloc or new
  165.     // (when the event is processed, it is deleted).
  166.     virtual HRESULT PostEvent(
  167.         IN      MSPEVENTITEM *      EventItem
  168.         );
  169.  
  170. // method used by template function
  171.  
  172.     virtual DWORD GetCallMediaTypes(void) = 0;
  173.  
  174. protected:
  175.  
  176.     // Private helper function (protected so derived class can call it)
  177.  
  178.     virtual HRESULT UpdateTerminalList(void);
  179.  
  180.     virtual HRESULT ReceiveTSPAddressData(
  181.         IN      PBYTE               pBuffer,
  182.         IN      DWORD               dwSize
  183.         );
  184.     
  185. protected:
  186.  
  187.     // The handle to TAPI's event, which is used to notify TAPI that the MSP 
  188.     // wants to send data to it.
  189.     HANDLE              m_htEvent;
  190.  
  191.     // List of events.
  192.     LIST_ENTRY          m_EventList;
  193.  
  194.     // The lock that protects the data related to event handling with TAPI.
  195.     CMSPCritSection     m_EventDataLock;
  196.  
  197.  
  198.     // The pointer to the terminal manager object.
  199.     ITTerminalManager * m_pITTerminalManager;
  200.  
  201.     // The list of static terminals that can be used on the address.
  202.     CMSPArray <ITTerminal *>  m_Terminals;
  203.     BOOL                m_fTerminalsUpToDate;
  204.  
  205.     // The lock that protects the data members for terminal operations.
  206.     CMSPCritSection     m_TerminalDataLock;
  207.  
  208. private:
  209.     static const STATIC_TERMINAL_TYPE m_saTerminalTypes[];
  210.     static const DWORD m_sdwTerminalTypesCount;
  211. };
  212.  
  213. template <class T>
  214. HRESULT CreateMSPCallHelper(
  215.     IN      CMSPAddress *       pCMSPAddress,
  216.     IN      MSP_HANDLE          htCall,
  217.     IN      DWORD               dwReserved,
  218.     IN      DWORD               dwMediaType,
  219.     IN      IUnknown *          pOuterUnknown,
  220.     OUT     IUnknown **         ppMSPCall,
  221.     OUT     T **                ppCMSPCall
  222.     )
  223. {
  224.     LOG((MSP_TRACE, "CreateMSPCallHelper - enter"));
  225.  
  226.     HRESULT hr;
  227.     T * pMSPCall;
  228.     IUnknown *pUnknown = NULL;
  229.  
  230.     //
  231.     // Check parameters.
  232.     //
  233.  
  234.     if ( IsBadReadPtr(pCMSPAddress, sizeof(CMSPAddress) ) )
  235.     {
  236.         LOG((MSP_ERROR, "CreateMSPCallHelper - "
  237.             "bad address pointer - exit E_POINTER"));
  238.         
  239.         return E_POINTER;
  240.     }
  241.  
  242.     if ( IsBadReadPtr(pOuterUnknown, sizeof(IUnknown) ) )
  243.     {
  244.         LOG((MSP_ERROR, "CreateMSPCallHelper - "
  245.             "bad outer unknown - we require aggregation - exit E_POINTER"));
  246.         
  247.         return E_POINTER;
  248.     }
  249.  
  250.     if ( IsBadReadPtr(ppMSPCall, sizeof(IUnknown *) ) )
  251.     {
  252.         LOG((MSP_ERROR, "CreateMSPCallHelper - "
  253.             "bad iunknown return ptr - exit E_POINTER"));
  254.         
  255.         return E_POINTER;
  256.     }
  257.  
  258.     if ( IsBadReadPtr(ppCMSPCall, sizeof(T *) ) )
  259.     {
  260.         LOG((MSP_ERROR, "CreateMSPCallHelper - "
  261.             "bad class return ptr - exit E_POINTER"));
  262.         
  263.         return E_POINTER;
  264.     }
  265.  
  266.     if ( ! pCMSPAddress->IsValidSetOfMediaTypes(
  267.                                         dwMediaType,
  268.                                         pCMSPAddress->GetCallMediaTypes() ) )
  269.     {
  270.         LOG((MSP_ERROR, "CreateMSPCallHelper - "
  271.             "unsupported media types - exit TAPI_E_INVALIDMEDIATYPE"));
  272.         
  273.         return TAPI_E_INVALIDMEDIATYPE;
  274.     }
  275.  
  276.     // dwReserved is meaningless.
  277.     // We have no way of checking htCall.
  278.  
  279.     // the pOuterUnknown is not NULL. This object is going to be aggregated.
  280.     CComAggObject<T> * pCall;
  281.  
  282.     pCall = new CComAggObject<T>(pOuterUnknown);
  283.  
  284.     if (pCall == NULL)
  285.     {
  286.         LOG((MSP_ERROR, "CreateMSPCallHelper - "
  287.             "could not create agg call instance - exit E_OUTOFMEMORY"));
  288.  
  289.         return E_OUTOFMEMORY;
  290.     }
  291.  
  292.     // query the interface on the containing object.
  293.     hr = pCall->QueryInterface(IID_IUnknown, (void **)&pUnknown);
  294.  
  295.     if (FAILED(hr))
  296.     {
  297.         LOG((MSP_ERROR, "CreateMSPCallHelper - "
  298.             "QueryInterface failed: %x", hr));
  299.  
  300.         delete pCall;
  301.         return hr;
  302.     }
  303.  
  304.     hr = pCall->FinalConstruct();
  305.  
  306.     if (FAILED(hr))
  307.     {
  308.         LOG((MSP_ERROR, "CreateMSPCallHelper - "
  309.             "FinalConstruct failed: %x.", hr));
  310.  
  311.         pUnknown->Release();
  312.         return hr;
  313.     }
  314.  
  315.     // Get a pointer to the real MSPCall object.
  316.     pMSPCall = dynamic_cast<T *>(&(pCall->m_contained));
  317.     if (pMSPCall == NULL)
  318.     {
  319.         LOG((MSP_ERROR, "CreateMSPCallHelper - "
  320.             "can not cast to agg object to class pointer - "
  321.             "exit E_UNEXPECTED"));
  322.     
  323.         pUnknown->Release();
  324.         return E_UNEXPECTED;
  325.     }
  326.  
  327.     //
  328.     // initialize the call.
  329.     //
  330.     
  331.     hr = pMSPCall->Init(pCMSPAddress, htCall, dwReserved, dwMediaType);
  332.  
  333.     if (FAILED(hr))
  334.     {
  335.         LOG((MSP_ERROR, "CreateMSPCallHelper - "
  336.             "call init failed: %x", hr));
  337.  
  338.         pUnknown->Release();
  339.         return hr;
  340.     }
  341.  
  342.     *ppMSPCall = pUnknown;
  343.     *ppCMSPCall = pMSPCall;
  344.  
  345.     LOG((MSP_TRACE, "CreateMSPCallHelper - exit S_OK"));
  346.  
  347.     return hr;
  348. }
  349.  
  350. template <class T>
  351. HRESULT ShutdownMSPCallHelper(
  352.     IN      IUnknown *          pUnknown,
  353.     OUT     T **                ppCMSPCall
  354.     )
  355. {
  356.     LOG((MSP_TRACE, "ShutdownMSPCallHelper - enter"));
  357.  
  358.     if ( IsBadReadPtr(pUnknown, sizeof(IUnknown) ) )
  359.     {
  360.         LOG((MSP_ERROR, "ShutdownMSPCallHelper - "
  361.             "bad IUnknown pointer - exit E_POINTER"));
  362.  
  363.         return E_POINTER;
  364.     }
  365.     
  366.     if ( IsBadWritePtr(ppCMSPCall, sizeof(T *) ) )
  367.     {
  368.         LOG((MSP_ERROR, "ShutdownMSPCallHelper - "
  369.             "bad return pointer - exit E_POINTER"));
  370.  
  371.         return E_POINTER;
  372.     }
  373.  
  374.     T * pMSPCall;
  375.  
  376.     CComAggObject<T> * pCall = dynamic_cast<CComAggObject<T> *> (pUnknown);
  377.  
  378.     if (pCall == NULL)
  379.     {
  380.         LOG((MSP_ERROR, "ShutdownMSPCallHelper - "
  381.             "can't cast unknown to agg object pointer - exit E_UNEXPECTED"));
  382.     
  383.         return E_UNEXPECTED;
  384.     }
  385.  
  386.     //
  387.     // It was aggregated. Get a pointer to the real MSPCall object.
  388.     //
  389.  
  390.     pMSPCall = dynamic_cast<T *> (&(pCall->m_contained));
  391.  
  392.     if (pMSPCall == NULL)
  393.     {
  394.         LOG((MSP_ERROR, "ShutdownMSPCallHelper - "
  395.             "can't cast contained unknown to class pointer - "
  396.             "exit E_UNEXPECTED"));
  397.     
  398.         return E_UNEXPECTED;
  399.     }
  400.  
  401.     //
  402.     // Now we have a call to shut down. Shut it down.
  403.     //
  404.  
  405.     HRESULT hr = pMSPCall->ShutDown();
  406.  
  407.     if (FAILED(hr))
  408.     {
  409.         LOG((MSP_ERROR, "ShutdownMSPCallHelper - "
  410.             "ShutDownMSPCall failed: %x", hr));
  411.         
  412.         return hr;
  413.     }
  414.  
  415.     *ppCMSPCall = pMSPCall;
  416.  
  417.     LOG((MSP_TRACE, "ShutdownMSPCallHelper - exit S_OK"));
  418.  
  419.     return S_OK;
  420. }
  421.  
  422. #pragma option pop /*P_O_Pop*/
  423. #endif //__MSPADDRESS_H_
  424.