windows-nt/Source/XPSP1/NT/inetsrv/query/h/conpt.hxx
2020-09-26 16:20:57 +08:00

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