385 lines
8.9 KiB
C++
385 lines
8.9 KiB
C++
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
// Copyright (C) Microsoft Corporation, 1994 - 1998.
|
||
|
//
|
||
|
// File: conpt.hxx
|
||
|
//
|
||
|
// Contents: Connection point and container objects
|
||
|
//
|
||
|
// Classes: CConnectionPointContainer
|
||
|
// CEnumConnectionPoints
|
||
|
// CConnectionPointBase
|
||
|
//
|
||
|
// History: 7-Oct-94 Dlee Created
|
||
|
// 12 Feb 98 AlanW Generalized
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
//#include <dynarray.hxx>
|
||
|
//#include <sem32.hxx>
|
||
|
|
||
|
extern "C" {
|
||
|
#include <olectl.h>
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// Forward referenced classes
|
||
|
//
|
||
|
class CConnectionPointContainer;
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Class: CConnectionPointBase
|
||
|
//
|
||
|
// Purpose: Implements IConnectionPoint for ci/oledb.
|
||
|
//
|
||
|
// Interface: IConnectionPoint
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
class CConnectionPointBase : public IConnectionPoint
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
friend class CEnumConnectionsLite;
|
||
|
|
||
|
CConnectionPointBase( REFIID riid )
|
||
|
: _pContainer( 0 ),
|
||
|
_pIContrUnk( 0 ),
|
||
|
_cRefs( 1 ),
|
||
|
_dwCookieGen( 0 ),
|
||
|
_dwDefaultSpare( 0 ),
|
||
|
_iidSink( riid ),
|
||
|
_pAdviseHelper( 0 ),
|
||
|
_pAdviseHelperContext( 0 ),
|
||
|
_pUnadviseHelper( 0 ),
|
||
|
_pUnadviseHelperContext( 0 )
|
||
|
{ }
|
||
|
|
||
|
//
|
||
|
// IUnknown methods.
|
||
|
//
|
||
|
|
||
|
STDMETHOD(QueryInterface) (THIS_ REFIID riid,LPVOID *ppiuk );
|
||
|
STDMETHOD_(ULONG, AddRef) (THIS);
|
||
|
STDMETHOD_(ULONG, Release) (THIS);
|
||
|
|
||
|
//
|
||
|
// IConnectionPoint methods.
|
||
|
//
|
||
|
|
||
|
STDMETHOD(GetConnectionInterface) (IID * piid);
|
||
|
|
||
|
STDMETHOD(GetConnectionPointContainer)
|
||
|
(IConnectionPointContainer ** ppCPC);
|
||
|
|
||
|
STDMETHOD(Advise) (IUnknown * piunkNotify, DWORD * pdwCookie);
|
||
|
|
||
|
STDMETHOD(Unadvise) (DWORD dwCookie);
|
||
|
|
||
|
STDMETHOD(EnumConnections) (IEnumConnections ** ppEnum);
|
||
|
|
||
|
//
|
||
|
// Connection point container communication
|
||
|
//
|
||
|
void SetContainer( CConnectionPointContainer * pContainer )
|
||
|
{
|
||
|
Win4Assert( 0 == _pContainer );
|
||
|
_pContainer = pContainer;
|
||
|
}
|
||
|
|
||
|
void SetContrUnk( IUnknown * pIContrUnk = 0 )
|
||
|
{
|
||
|
Win4Assert( 0 == _pIContrUnk && 1 == _cRefs );
|
||
|
_pIContrUnk = pIContrUnk;
|
||
|
}
|
||
|
|
||
|
// return high-water mark of advises
|
||
|
ULONG GetAdviseCount( )
|
||
|
{
|
||
|
return _xaConns.Count();
|
||
|
}
|
||
|
|
||
|
void Disconnect( );
|
||
|
|
||
|
protected:
|
||
|
class CConnectionContext
|
||
|
{
|
||
|
public:
|
||
|
DWORD _dwAdviseCookie;
|
||
|
DWORD _dwSpare;
|
||
|
IUnknown * _pIUnk;
|
||
|
|
||
|
CConnectionContext( IUnknown* pUnk = 0,
|
||
|
DWORD dwCook = 0,
|
||
|
DWORD dwSpare = 0)
|
||
|
: _pIUnk( pUnk ),
|
||
|
_dwAdviseCookie( dwCook ),
|
||
|
_dwSpare( dwSpare )
|
||
|
{ }
|
||
|
|
||
|
~CConnectionContext( )
|
||
|
{
|
||
|
Release();
|
||
|
}
|
||
|
|
||
|
void Set(IUnknown* pUnk, DWORD dwCook, DWORD dwSpare = 0)
|
||
|
{
|
||
|
_pIUnk = pUnk;
|
||
|
_dwAdviseCookie = dwCook;
|
||
|
_dwSpare = dwSpare;
|
||
|
}
|
||
|
|
||
|
void Release( )
|
||
|
{
|
||
|
if ( _pIUnk )
|
||
|
_pIUnk->Release();
|
||
|
_pIUnk = 0;
|
||
|
_dwAdviseCookie = 0;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
public:
|
||
|
//
|
||
|
// Advise management - need to be public because IRowsetAsynchNotification
|
||
|
// calls these on embedded connection points.
|
||
|
//
|
||
|
|
||
|
typedef void (*PFNADVISEHELPER) (PVOID pHelperContext,
|
||
|
CConnectionPointBase * pCP,
|
||
|
CConnectionContext * pCC);
|
||
|
typedef void (*PFNUNADVISEHELPER) (PVOID pHelperContext,
|
||
|
CConnectionPointBase * pCP,
|
||
|
CConnectionContext * pCC,
|
||
|
CReleasableLock & lock);
|
||
|
|
||
|
void SetAdviseHelper( PFNADVISEHELPER pHelper, PVOID pContext )
|
||
|
{
|
||
|
Win4Assert( 0 == _pAdviseHelper );
|
||
|
Win4Assert( 0 == _pAdviseHelperContext );
|
||
|
|
||
|
_pAdviseHelper = pHelper;
|
||
|
_pAdviseHelperContext = pContext;
|
||
|
}
|
||
|
|
||
|
void SetUnadviseHelper( PFNUNADVISEHELPER pHelper, PVOID pContext )
|
||
|
{
|
||
|
Win4Assert( 0 == _pUnadviseHelper );
|
||
|
Win4Assert( 0 == _pUnadviseHelperContext );
|
||
|
|
||
|
_pUnadviseHelper = pHelper;
|
||
|
_pUnadviseHelperContext = pContext;
|
||
|
}
|
||
|
|
||
|
protected:
|
||
|
CConnectionContext * LokFindConnection( DWORD dwCookie );
|
||
|
CConnectionContext * LokFindActiveConnection( unsigned & iConn );
|
||
|
|
||
|
inline CMutexSem & GetMutex( );
|
||
|
|
||
|
ULONG _cRefs;
|
||
|
DWORD _dwCookieGen;
|
||
|
DWORD _dwDefaultSpare;
|
||
|
CConnectionPointContainer * _pContainer;
|
||
|
|
||
|
IUnknown * _pIContrUnk;
|
||
|
|
||
|
IID _iidSink;
|
||
|
|
||
|
PFNADVISEHELPER _pAdviseHelper;
|
||
|
PVOID _pAdviseHelperContext;
|
||
|
|
||
|
PFNUNADVISEHELPER _pUnadviseHelper;
|
||
|
PVOID _pUnadviseHelperContext;
|
||
|
|
||
|
CDynArrayInPlaceNST<CConnectionContext> _xaConns;
|
||
|
};
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Class: CEnumConnectionsLite
|
||
|
//
|
||
|
// Purpose: Enumerates active advises in CConnectionPointBase
|
||
|
//
|
||
|
// Notes: Lightweight version, not an OLE object implementing
|
||
|
// IEnumConnections
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
class CEnumConnectionsLite
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
CEnumConnectionsLite( CConnectionPointBase & rCP ) :
|
||
|
_rCP( rCP ),
|
||
|
_lock( rCP.GetMutex() ),
|
||
|
_iConn( 0 )
|
||
|
{ }
|
||
|
|
||
|
CConnectionPointBase::CConnectionContext * First()
|
||
|
{
|
||
|
_iConn = 0;
|
||
|
return _rCP.LokFindActiveConnection(_iConn);
|
||
|
}
|
||
|
|
||
|
CConnectionPointBase::CConnectionContext * Next()
|
||
|
{
|
||
|
_iConn++;
|
||
|
return _rCP.LokFindActiveConnection(_iConn);
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
|
||
|
CConnectionPointBase & _rCP;
|
||
|
unsigned _iConn;
|
||
|
CLock _lock;
|
||
|
};
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Class: CConnectionPointContainer
|
||
|
//
|
||
|
// Purpose: Implements IConnectionPointContainer for ci/oledb.
|
||
|
//
|
||
|
// Interface: IConnectionPointContainer
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
const unsigned maxConnectionPoints = 3;
|
||
|
|
||
|
class CConnectionPointContainer : public IConnectionPointContainer
|
||
|
{
|
||
|
friend class CEnumConnectionPoints;
|
||
|
|
||
|
public:
|
||
|
//
|
||
|
// IUnknown methods.
|
||
|
//
|
||
|
|
||
|
STDMETHOD(QueryInterface) (THIS_ REFIID riid,LPVOID *ppiuk );
|
||
|
|
||
|
STDMETHOD_(ULONG, AddRef) (THIS);
|
||
|
|
||
|
STDMETHOD_(ULONG, Release) (THIS);
|
||
|
|
||
|
//
|
||
|
// IConnectionPointContainer methods.
|
||
|
//
|
||
|
|
||
|
STDMETHOD(EnumConnectionPoints) (IEnumConnectionPoints ** ppEnum);
|
||
|
|
||
|
STDMETHOD(FindConnectionPoint) (REFIID riid,
|
||
|
IConnectionPoint ** ppPoint);
|
||
|
|
||
|
|
||
|
//
|
||
|
// Initialization and teardown
|
||
|
//
|
||
|
CConnectionPointContainer( unsigned maxConnPts,
|
||
|
IUnknown & rContollingUnk,
|
||
|
CCIOleDBError & ErrorObject);
|
||
|
virtual ~CConnectionPointContainer();
|
||
|
|
||
|
void AddConnectionPoint( REFIID riid, CConnectionPointBase * pIConnPoint );
|
||
|
|
||
|
void RemoveConnectionPoint( IConnectionPoint * pIConnPoint );
|
||
|
|
||
|
CMutexSem & GetMutex( )
|
||
|
{
|
||
|
return _mutex;
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
|
||
|
IUnknown & _rControllingUnk; // controlling unknown
|
||
|
CCIOleDBError & _ErrorObject; // The controlling unknown's error obj
|
||
|
|
||
|
class CConnectionPointContext
|
||
|
{
|
||
|
public:
|
||
|
IID _iidConnPt;
|
||
|
IConnectionPoint * _pIConnPt;
|
||
|
};
|
||
|
|
||
|
unsigned _cConnPt;
|
||
|
CConnectionPointContext _aConnPt[maxConnectionPoints];
|
||
|
CMutexSem _mutex;
|
||
|
};
|
||
|
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Class: CEnumConnectionPoints
|
||
|
//
|
||
|
// Purpose: Implements IEnumConnectionPoints for ci/oledb.
|
||
|
//
|
||
|
// Interface: IEnumConnectionPoints
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
|
||
|
class CEnumConnectionPoints : public IEnumConnectionPoints
|
||
|
{
|
||
|
|
||
|
public:
|
||
|
|
||
|
CEnumConnectionPoints(CConnectionPointContainer &rContainer )
|
||
|
: _rContainer(rContainer),
|
||
|
_cRefs(1),
|
||
|
_iConnPt(0)
|
||
|
{
|
||
|
rContainer.AddRef();
|
||
|
}
|
||
|
|
||
|
~CEnumConnectionPoints( )
|
||
|
{
|
||
|
_rContainer.Release();
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// IUnknown methods.
|
||
|
//
|
||
|
|
||
|
STDMETHOD(QueryInterface) (THIS_ REFIID riid,LPVOID *ppiuk );
|
||
|
|
||
|
STDMETHOD_(ULONG, AddRef) (THIS);
|
||
|
|
||
|
STDMETHOD_(ULONG, Release) (THIS);
|
||
|
|
||
|
//
|
||
|
// IEnumConnectionPoints methods.
|
||
|
//
|
||
|
|
||
|
STDMETHOD(Next) (ULONG cConnections,
|
||
|
IConnectionPoint **rgpcn,
|
||
|
ULONG * pcFetched);
|
||
|
|
||
|
STDMETHOD(Skip) (ULONG cConnections);
|
||
|
|
||
|
STDMETHOD(Reset) (void);
|
||
|
|
||
|
STDMETHOD(Clone) ( IEnumConnectionPoints **rgpcn );
|
||
|
|
||
|
private:
|
||
|
|
||
|
ULONG _cRefs;
|
||
|
|
||
|
CConnectionPointContainer & _rContainer;
|
||
|
|
||
|
unsigned _iConnPt;
|
||
|
|
||
|
};
|
||
|
|
||
|
CMutexSem & CConnectionPointBase::GetMutex( )
|
||
|
{
|
||
|
Win4Assert( _pContainer );
|
||
|
return _pContainer->GetMutex();
|
||
|
}
|
||
|
|