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.

319 lines
11 KiB

  1. //+-------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2000 - 2000
  5. //
  6. // File: comobjects.h
  7. //
  8. // Contents: Base code for com objects exported by Object Model.
  9. //
  10. // Classes: CMMCStrongReferences, CMMCIDispatchImpl
  11. //
  12. // History: 16-May-2000 AudriusZ Created
  13. //
  14. //--------------------------------------------------------------------
  15. #pragma once
  16. #ifndef COMOBJECTS_H_INCLUDED
  17. #define COMOBJECTS_H_INCLUDED
  18. /*+-------------------------------------------------------------------------*
  19. * class CComObjectObserver
  20. *
  21. * PURPOSE: The general interface for a class that observes com object events
  22. *
  23. * USAGE: Used by CMMCIDispatchImpl, so all ObjectModel objects inherit from it
  24. *
  25. *+-------------------------------------------------------------------------*/
  26. class CComObjectObserver : public CObserverBase
  27. {
  28. public:
  29. // request to break external references
  30. virtual SC ScOnDisconnectObjects() {DEFAULT_OBSERVER_METHOD;}
  31. };
  32. /*+-------------------------------------------------------------------------*
  33. * function GetComObjectEventSource
  34. *
  35. * PURPOSE: returns singleton for emmiting Com Object Events
  36. * Since ObjectModel com objects are implemented in EXE and DLL's
  37. * There is a need to have 'global' object per process to
  38. * be able to bradcast events to every object.
  39. *
  40. * USAGE: Used by
  41. * 1) CMMCIDispatchImpl to register objects
  42. * 2) CAMCMultiDocTemplate to bradcast 'cut off extenal references'
  43. *+-------------------------------------------------------------------------*/
  44. MMCBASE_API CEventSource<CComObjectObserver>& GetComObjectEventSource();
  45. /***************************************************************************\
  46. *
  47. * CLASS: CMMCStrongReferences
  48. *
  49. * PURPOSE: Implements static interface to count strong references put on MMC
  50. * Also implements the method to detect when the last stron reference was
  51. * released in order to start MMC exit procedure.
  52. *
  53. * Class is implemented as singleton object in mmcbase.dll
  54. *
  55. * USAGE: use CMMCStrongReferences::AddRef() and CMMCStrongReferences::Release()
  56. * to put/remove strong references on MMC.EXE
  57. * use CMMCStrongReferences::LastRefReleased() to inspect if the
  58. * last ref was released
  59. *
  60. \***************************************************************************/
  61. class MMCBASE_API CMMCStrongReferences
  62. {
  63. public:
  64. // public (static) interface
  65. static DWORD AddRef();
  66. static DWORD Release();
  67. static bool LastRefReleased();
  68. private:
  69. // implementation helpers
  70. CMMCStrongReferences();
  71. static CMMCStrongReferences& GetSingletonObject();
  72. DWORD InternalAddRef();
  73. DWORD InternalRelease();
  74. bool InternalLastRefReleased();
  75. // data members
  76. DWORD m_dwStrongRefs; // strong reference count
  77. bool m_bLastRefReleased; // have strong reference count ever go from one to zero
  78. };
  79. /***************************************************************************\
  80. *
  81. * CLASS: CMMCIDispatchImpl<typename _ComInterface, const GUID * _pguidClass = &GUID_NULL, const GUID* _pLibID = &LIBID_MMC20>
  82. * _ComInterface - Object Model interface implemented by the class
  83. * _pguidClass [optional] - pointer to CLSID for cocreatable objects
  84. * _pLibID [optional] - pointer to LIBID with _ComInterface's type info
  85. *
  86. * PURPOSE: Base for every com object defined by the MMC Object Model
  87. * implements common functionality, like:
  88. * - IDispatch
  89. * - ISupportErrorInfo
  90. * - IExternalConnection
  91. *
  92. * USAGE: Derive your object from CMMCIDispatchImpl<interface>
  93. * Define: BEGIN_MMC_COM_MAP(_Class) ... END_MMC_COM_MAP() in the class
  94. * Define COM_INTERFACE_ENTRY for each additional interface
  95. * ( DO NOT need to add IDispatch, ISupportErrorInfo, IExternalConnection
  96. * or implemented ObjecModel interface - these are added by the base class )
  97. *
  98. \***************************************************************************/
  99. template<
  100. typename _ComInterface,
  101. const GUID * _pguidClass = &GUID_NULL,
  102. const GUID * _pLibID = &LIBID_MMC20>
  103. class CMMCIDispatchImpl :
  104. public IDispatchImpl<_ComInterface, &__uuidof(_ComInterface), _pLibID>,
  105. // we can use the IMMCSupportErrorInfoImpl object because exactly one dispinterface is exposed from this object.
  106. public IMMCSupportErrorInfoImpl<&__uuidof(_ComInterface), _pguidClass>,
  107. public IExternalConnection,
  108. public CComObjectRoot,
  109. public CComObjectObserver
  110. {
  111. public:
  112. // typedef interface and this class [used by macros defined in the derived class]
  113. typedef _ComInterface MMCInterface;
  114. typedef CMMCIDispatchImpl<_ComInterface, _pguidClass, _pLibID> CMMCIDispatchImplClass;
  115. // interfaces implemented by this base class
  116. BEGIN_COM_MAP(CMMCIDispatchImplClass)
  117. COM_INTERFACE_ENTRY(IDispatch)
  118. COM_INTERFACE_ENTRY(ISupportErrorInfo)
  119. COM_INTERFACE_ENTRY(IExternalConnection)
  120. END_COM_MAP()
  121. CMMCIDispatchImpl()
  122. {
  123. // add itself as an observer for com object events
  124. GetComObjectEventSource().AddObserver(*static_cast<CComObjectObserver*>(this));
  125. #ifdef _MMC_NODE_MANAGER_ONLY_
  126. // Every object implemented by node manager should also register for typeinfo clenup
  127. static CMMCTypeInfoHolderWrapper wrapper(GetInfoHolder());
  128. #endif // _MMC_NODE_MANAGER_ONLY_
  129. }
  130. #ifdef _MMC_NODE_MANAGER_ONLY_
  131. // Every object implemented by node manager should also register for typeinfo clenup
  132. // the porpose of this static function is to ensure _tih is a static variable,
  133. // since static wrapper will hold on its address - it must be always valid
  134. static CComTypeInfoHolder& GetInfoHolder() { return _tih; }
  135. #endif // _MMC_NODE_MANAGER_ONLY_
  136. // implementation for IExternalConnection methods
  137. STDMETHOD_(DWORD, AddConnection)(DWORD extconn, DWORD dwreserved)
  138. {
  139. DWORD dwRefs = AddRef(); // addref itself
  140. // put a strong reference on MMC - this will prevent mmc from exiting
  141. if (extconn & EXTCONN_STRONG)
  142. dwRefs = CMMCStrongReferences::AddRef();
  143. return dwRefs;
  144. }
  145. STDMETHOD_(DWORD, ReleaseConnection)(DWORD extconn, DWORD dwreserved, BOOL fLastReleaseCloses)
  146. {
  147. DWORD dwStrongRefs = 0;
  148. DWORD dwRefs = 0;
  149. // release a strong reference on MMC
  150. if (extconn & EXTCONN_STRONG)
  151. {
  152. dwStrongRefs = CMMCStrongReferences::Release();
  153. }
  154. //release a ref on itself
  155. dwRefs = Release();
  156. // return a proper ref count
  157. return (extconn & EXTCONN_STRONG) ? dwStrongRefs : dwRefs;
  158. }
  159. /***************************************************************************\
  160. *
  161. * METHOD: ScOnDisconnectObjects
  162. *
  163. * PURPOSE: invoked when observed event (request to disconnect) occures
  164. * Disconnects from external connections
  165. *
  166. * PARAMETERS:
  167. *
  168. * RETURNS:
  169. * SC - result code
  170. *
  171. \***************************************************************************/
  172. virtual ::SC ScOnDisconnectObjects()
  173. {
  174. DECLARE_SC(sc, TEXT("CMMCIDispatchImpl<_ComInterface>::ScOnDisconnectObjects"));
  175. // QI for IUnknown
  176. IUnknownPtr spUnknown = this;
  177. // sanity check
  178. sc = ScCheckPointers( spUnknown, E_UNEXPECTED );
  179. if (sc)
  180. return sc;
  181. // cutt own references
  182. sc = CoDisconnectObject( spUnknown, 0/*dwReserved*/ );
  183. if (sc)
  184. return sc;
  185. return sc;
  186. }
  187. #ifdef DBG
  188. // this block is to catch mistakes when the Derived class does not use
  189. // BEGIN_MMC_COM_MAP() or END_MMC_COM_MAP() in its body
  190. virtual void _BEGIN_MMC_COM_MAP() = 0;
  191. virtual void _END_MMC_COM_MAP() = 0;
  192. #endif
  193. };
  194. /***************************************************************************\
  195. *
  196. * MACRO: BEGIN_MMC_COM_MAP
  197. *
  198. * PURPOSE: To be used in place of BEGIN_MMC_COM_MAP for com objects used in MMC Object Model
  199. *
  200. \***************************************************************************/
  201. #ifndef DBG
  202. // standard version
  203. #define BEGIN_MMC_COM_MAP(_Class) \
  204. BEGIN_COM_MAP(_Class) \
  205. COM_INTERFACE_ENTRY(MMCInterface)
  206. #else // DBG
  207. // same as above, but shuts off the trap placed in CMMCIDispatchImpl in debug mode
  208. #define BEGIN_MMC_COM_MAP(_Class) \
  209. virtual void _BEGIN_MMC_COM_MAP() {} \
  210. BEGIN_COM_MAP(_Class) \
  211. COM_INTERFACE_ENTRY(MMCInterface)
  212. #endif // DBG
  213. /***************************************************************************\
  214. *
  215. * MACRO: END_MMC_COM_MAP
  216. *
  217. * PURPOSE: To be used in place of END_COM_MAP for com objects used in MMC Object Model
  218. *
  219. \***************************************************************************/
  220. #ifndef DBG
  221. // standard version
  222. #define END_MMC_COM_MAP() \
  223. COM_INTERFACE_ENTRY_CHAIN(CMMCIDispatchImplClass) \
  224. END_COM_MAP()
  225. #else // DBG
  226. // same as above, but shuts off the trap placed in CMMCIDispatchImpl in debug mode
  227. #define END_MMC_COM_MAP() \
  228. COM_INTERFACE_ENTRY_CHAIN(CMMCIDispatchImplClass) \
  229. END_COM_MAP() \
  230. virtual void _END_MMC_COM_MAP() {}
  231. #endif // DBG
  232. /*+-------------------------------------------------------------------------*
  233. * class CConsoleEventDispatcher
  234. *
  235. *
  236. * PURPOSE: Interface for emitting com events from node manager side
  237. * implemented by CMMCApplication
  238. *
  239. *+-------------------------------------------------------------------------*/
  240. class CConsoleEventDispatcher
  241. {
  242. public:
  243. virtual SC ScOnContextMenuExecuted( PMENUITEM pMenuItem ) = 0;
  244. };
  245. /***************************************************************************\
  246. *
  247. * METHOD: CConsoleEventDispatcherProvider
  248. *
  249. * PURPOSE: this class is to wrap and maintain a pointer to CConsoleEventDispatcher
  250. * interface. Pointer is set by conui side and used from node manager side.
  251. * Pointer is discarded when when cleanup event is observed.
  252. *
  253. \***************************************************************************/
  254. class CConsoleEventDispatcherProvider
  255. {
  256. public:
  257. // public class members (static) to get/set interface pointer
  258. static SC MMCBASE_API ScSetConsoleEventDispatcher( CConsoleEventDispatcher *pDispatcher )
  259. {
  260. s_pDispatcher = pDispatcher;
  261. return SC(S_OK);
  262. }
  263. static SC MMCBASE_API ScGetConsoleEventDispatcher( CConsoleEventDispatcher *&pDispatcher )
  264. {
  265. pDispatcher = s_pDispatcher;
  266. return SC(S_OK);
  267. }
  268. private:
  269. // pointer to interface
  270. static MMCBASE_API CConsoleEventDispatcher *s_pDispatcher;
  271. };
  272. #endif // COMOBJECTS_H_INCLUDED