Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

384 lines
8.9 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 1998.
  5. //
  6. // File: conpt.hxx
  7. //
  8. // Contents: Connection point and container objects
  9. //
  10. // Classes: CConnectionPointContainer
  11. // CEnumConnectionPoints
  12. // CConnectionPointBase
  13. //
  14. // History: 7-Oct-94 Dlee Created
  15. // 12 Feb 98 AlanW Generalized
  16. //
  17. //----------------------------------------------------------------------------
  18. #pragma once
  19. //#include <dynarray.hxx>
  20. //#include <sem32.hxx>
  21. extern "C" {
  22. #include <olectl.h>
  23. }
  24. //
  25. // Forward referenced classes
  26. //
  27. class CConnectionPointContainer;
  28. //+-------------------------------------------------------------------------
  29. //
  30. // Class: CConnectionPointBase
  31. //
  32. // Purpose: Implements IConnectionPoint for ci/oledb.
  33. //
  34. // Interface: IConnectionPoint
  35. //
  36. // Notes:
  37. //
  38. //--------------------------------------------------------------------------
  39. class CConnectionPointBase : public IConnectionPoint
  40. {
  41. public:
  42. friend class CEnumConnectionsLite;
  43. CConnectionPointBase( REFIID riid )
  44. : _pContainer( 0 ),
  45. _pIContrUnk( 0 ),
  46. _cRefs( 1 ),
  47. _dwCookieGen( 0 ),
  48. _dwDefaultSpare( 0 ),
  49. _iidSink( riid ),
  50. _pAdviseHelper( 0 ),
  51. _pAdviseHelperContext( 0 ),
  52. _pUnadviseHelper( 0 ),
  53. _pUnadviseHelperContext( 0 )
  54. { }
  55. //
  56. // IUnknown methods.
  57. //
  58. STDMETHOD(QueryInterface) (THIS_ REFIID riid,LPVOID *ppiuk );
  59. STDMETHOD_(ULONG, AddRef) (THIS);
  60. STDMETHOD_(ULONG, Release) (THIS);
  61. //
  62. // IConnectionPoint methods.
  63. //
  64. STDMETHOD(GetConnectionInterface) (IID * piid);
  65. STDMETHOD(GetConnectionPointContainer)
  66. (IConnectionPointContainer ** ppCPC);
  67. STDMETHOD(Advise) (IUnknown * piunkNotify, DWORD * pdwCookie);
  68. STDMETHOD(Unadvise) (DWORD dwCookie);
  69. STDMETHOD(EnumConnections) (IEnumConnections ** ppEnum);
  70. //
  71. // Connection point container communication
  72. //
  73. void SetContainer( CConnectionPointContainer * pContainer )
  74. {
  75. Win4Assert( 0 == _pContainer );
  76. _pContainer = pContainer;
  77. }
  78. void SetContrUnk( IUnknown * pIContrUnk = 0 )
  79. {
  80. Win4Assert( 0 == _pIContrUnk && 1 == _cRefs );
  81. _pIContrUnk = pIContrUnk;
  82. }
  83. // return high-water mark of advises
  84. ULONG GetAdviseCount( )
  85. {
  86. return _xaConns.Count();
  87. }
  88. void Disconnect( );
  89. protected:
  90. class CConnectionContext
  91. {
  92. public:
  93. DWORD _dwAdviseCookie;
  94. DWORD _dwSpare;
  95. IUnknown * _pIUnk;
  96. CConnectionContext( IUnknown* pUnk = 0,
  97. DWORD dwCook = 0,
  98. DWORD dwSpare = 0)
  99. : _pIUnk( pUnk ),
  100. _dwAdviseCookie( dwCook ),
  101. _dwSpare( dwSpare )
  102. { }
  103. ~CConnectionContext( )
  104. {
  105. Release();
  106. }
  107. void Set(IUnknown* pUnk, DWORD dwCook, DWORD dwSpare = 0)
  108. {
  109. _pIUnk = pUnk;
  110. _dwAdviseCookie = dwCook;
  111. _dwSpare = dwSpare;
  112. }
  113. void Release( )
  114. {
  115. if ( _pIUnk )
  116. _pIUnk->Release();
  117. _pIUnk = 0;
  118. _dwAdviseCookie = 0;
  119. }
  120. };
  121. public:
  122. //
  123. // Advise management - need to be public because IRowsetAsynchNotification
  124. // calls these on embedded connection points.
  125. //
  126. typedef void (*PFNADVISEHELPER) (PVOID pHelperContext,
  127. CConnectionPointBase * pCP,
  128. CConnectionContext * pCC);
  129. typedef void (*PFNUNADVISEHELPER) (PVOID pHelperContext,
  130. CConnectionPointBase * pCP,
  131. CConnectionContext * pCC,
  132. CReleasableLock & lock);
  133. void SetAdviseHelper( PFNADVISEHELPER pHelper, PVOID pContext )
  134. {
  135. Win4Assert( 0 == _pAdviseHelper );
  136. Win4Assert( 0 == _pAdviseHelperContext );
  137. _pAdviseHelper = pHelper;
  138. _pAdviseHelperContext = pContext;
  139. }
  140. void SetUnadviseHelper( PFNUNADVISEHELPER pHelper, PVOID pContext )
  141. {
  142. Win4Assert( 0 == _pUnadviseHelper );
  143. Win4Assert( 0 == _pUnadviseHelperContext );
  144. _pUnadviseHelper = pHelper;
  145. _pUnadviseHelperContext = pContext;
  146. }
  147. protected:
  148. CConnectionContext * LokFindConnection( DWORD dwCookie );
  149. CConnectionContext * LokFindActiveConnection( unsigned & iConn );
  150. inline CMutexSem & GetMutex( );
  151. ULONG _cRefs;
  152. DWORD _dwCookieGen;
  153. DWORD _dwDefaultSpare;
  154. CConnectionPointContainer * _pContainer;
  155. IUnknown * _pIContrUnk;
  156. IID _iidSink;
  157. PFNADVISEHELPER _pAdviseHelper;
  158. PVOID _pAdviseHelperContext;
  159. PFNUNADVISEHELPER _pUnadviseHelper;
  160. PVOID _pUnadviseHelperContext;
  161. CDynArrayInPlaceNST<CConnectionContext> _xaConns;
  162. };
  163. //+-------------------------------------------------------------------------
  164. //
  165. // Class: CEnumConnectionsLite
  166. //
  167. // Purpose: Enumerates active advises in CConnectionPointBase
  168. //
  169. // Notes: Lightweight version, not an OLE object implementing
  170. // IEnumConnections
  171. //
  172. //--------------------------------------------------------------------------
  173. class CEnumConnectionsLite
  174. {
  175. public:
  176. CEnumConnectionsLite( CConnectionPointBase & rCP ) :
  177. _rCP( rCP ),
  178. _lock( rCP.GetMutex() ),
  179. _iConn( 0 )
  180. { }
  181. CConnectionPointBase::CConnectionContext * First()
  182. {
  183. _iConn = 0;
  184. return _rCP.LokFindActiveConnection(_iConn);
  185. }
  186. CConnectionPointBase::CConnectionContext * Next()
  187. {
  188. _iConn++;
  189. return _rCP.LokFindActiveConnection(_iConn);
  190. }
  191. private:
  192. CConnectionPointBase & _rCP;
  193. unsigned _iConn;
  194. CLock _lock;
  195. };
  196. //+-------------------------------------------------------------------------
  197. //
  198. // Class: CConnectionPointContainer
  199. //
  200. // Purpose: Implements IConnectionPointContainer for ci/oledb.
  201. //
  202. // Interface: IConnectionPointContainer
  203. //
  204. //--------------------------------------------------------------------------
  205. const unsigned maxConnectionPoints = 3;
  206. class CConnectionPointContainer : public IConnectionPointContainer
  207. {
  208. friend class CEnumConnectionPoints;
  209. public:
  210. //
  211. // IUnknown methods.
  212. //
  213. STDMETHOD(QueryInterface) (THIS_ REFIID riid,LPVOID *ppiuk );
  214. STDMETHOD_(ULONG, AddRef) (THIS);
  215. STDMETHOD_(ULONG, Release) (THIS);
  216. //
  217. // IConnectionPointContainer methods.
  218. //
  219. STDMETHOD(EnumConnectionPoints) (IEnumConnectionPoints ** ppEnum);
  220. STDMETHOD(FindConnectionPoint) (REFIID riid,
  221. IConnectionPoint ** ppPoint);
  222. //
  223. // Initialization and teardown
  224. //
  225. CConnectionPointContainer( unsigned maxConnPts,
  226. IUnknown & rContollingUnk,
  227. CCIOleDBError & ErrorObject);
  228. virtual ~CConnectionPointContainer();
  229. void AddConnectionPoint( REFIID riid, CConnectionPointBase * pIConnPoint );
  230. void RemoveConnectionPoint( IConnectionPoint * pIConnPoint );
  231. CMutexSem & GetMutex( )
  232. {
  233. return _mutex;
  234. }
  235. private:
  236. IUnknown & _rControllingUnk; // controlling unknown
  237. CCIOleDBError & _ErrorObject; // The controlling unknown's error obj
  238. class CConnectionPointContext
  239. {
  240. public:
  241. IID _iidConnPt;
  242. IConnectionPoint * _pIConnPt;
  243. };
  244. unsigned _cConnPt;
  245. CConnectionPointContext _aConnPt[maxConnectionPoints];
  246. CMutexSem _mutex;
  247. };
  248. //+-------------------------------------------------------------------------
  249. //
  250. // Class: CEnumConnectionPoints
  251. //
  252. // Purpose: Implements IEnumConnectionPoints for ci/oledb.
  253. //
  254. // Interface: IEnumConnectionPoints
  255. //
  256. //--------------------------------------------------------------------------
  257. class CEnumConnectionPoints : public IEnumConnectionPoints
  258. {
  259. public:
  260. CEnumConnectionPoints(CConnectionPointContainer &rContainer )
  261. : _rContainer(rContainer),
  262. _cRefs(1),
  263. _iConnPt(0)
  264. {
  265. rContainer.AddRef();
  266. }
  267. ~CEnumConnectionPoints( )
  268. {
  269. _rContainer.Release();
  270. }
  271. //
  272. // IUnknown methods.
  273. //
  274. STDMETHOD(QueryInterface) (THIS_ REFIID riid,LPVOID *ppiuk );
  275. STDMETHOD_(ULONG, AddRef) (THIS);
  276. STDMETHOD_(ULONG, Release) (THIS);
  277. //
  278. // IEnumConnectionPoints methods.
  279. //
  280. STDMETHOD(Next) (ULONG cConnections,
  281. IConnectionPoint **rgpcn,
  282. ULONG * pcFetched);
  283. STDMETHOD(Skip) (ULONG cConnections);
  284. STDMETHOD(Reset) (void);
  285. STDMETHOD(Clone) ( IEnumConnectionPoints **rgpcn );
  286. private:
  287. ULONG _cRefs;
  288. CConnectionPointContainer & _rContainer;
  289. unsigned _iConnPt;
  290. };
  291. CMutexSem & CConnectionPointBase::GetMutex( )
  292. {
  293. Win4Assert( _pContainer );
  294. return _pContainer->GetMutex();
  295. }