Leaked source code of windows server 2003
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.

267 lines
10 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (c) Microsoft Corporation. All rights reserved.
  5. //
  6. // File: stdclass.hxx
  7. //
  8. // Contents: Helper class for implementing class factories.
  9. //
  10. // Macros: DECLARE_CLASSFACTORY
  11. // IMPLEMENT_CLASSFACTORY
  12. // DECLARE_CF_UNKNOWN_METHODS
  13. //
  14. // Classes: CStdFactory
  15. // CStdClassFactory
  16. //
  17. // Functions: DllAddRef
  18. // DllRelease
  19. //
  20. // History: 25-Mar-93 JohnEls Created.
  21. // 25-Apr-93 DavidBak Added dialog classes, message loop.
  22. // 28-May-93 MikeSe Split out from Pharos project
  23. // 2-Jul-93 ShannonC Split into CStdFactory and CStdClassFactory
  24. //
  25. // Summary of usage:
  26. //
  27. // 1. Declare your factory class as a subclass of CStdClassFactory
  28. // and implement the _CreateInstance method.
  29. //
  30. // If your class factory supports no interfaces other than
  31. // IClassFactory and has no instance data you can use the
  32. // DECLARE_CLASSFACTORY macro to do declare it.
  33. //
  34. // Otherwise you must do the declaration by hand. Then you
  35. // must implement the constructor for your class
  36. // including invoking the CStdClassFactory constructor in the
  37. // exact same way as DECLARE_CLASSFACTORY. In addition (if you
  38. // are supporting additional interfaces ) you must implement
  39. // the _QueryInterface method and also place an invocation
  40. // of DECLARE_CF_UNKNOWN_METHODS in your class definition.
  41. //
  42. // 2. Declare a single static instance of your class, in any
  43. // convenient source module (eg: the one containing the
  44. // implementation of _CreateInstance).
  45. //
  46. // 3. You DO NOT write implementations of DllGetClassObject or
  47. // DllCanUnloadNow; these are supplied automatically. However,
  48. // you must place exports for these functions in your .DEF file.
  49. // You can compose multiple classes into a single DLL simply
  50. // by linking the appropriate modules together. You must link
  51. // with $(COMMON)\SRC\STDCLASS\$(OBJDIR)\STDCLASS.LIB, which
  52. // should be listed in the LIBS line of FILELIST.MK *before*
  53. // $(CAIROLIB) [otherwise you will erroneously pick up
  54. // DllGetClassObject from ole2base.lib].
  55. //
  56. // If you are developing a LOCAL_SERVER rather than an
  57. // INPROC_SERVER you still need to link with the above library,
  58. // but you can safely ignore the Dll functions.
  59. //
  60. //
  61. //--------------------------------------------------------------------------
  62. #ifndef _STDCLASS_HXX_
  63. #define _STDCLASS_HXX_
  64. #include <windows.h>
  65. //+-------------------------------------------------------------------------
  66. //
  67. // Function: DllAddRef, DllRelease
  68. //
  69. // Synopsis: Bumps the DLL reference count
  70. //
  71. // Notes: These functions are used by INPROC_SERVER class implementors
  72. // whose class factories utilise the standard mechanism, and
  73. // hence inherit the standard implementations of DllGetClassObject
  74. // and DllCanUnloadNow.
  75. //
  76. // Call these functions to manipulate the reference count for
  77. // the DLL directly (as opposed to via AddRef/Release on a class
  78. // object).
  79. //
  80. //--------------------------------------------------------------------------
  81. STDAPI_(void) DllAddRef ( void );
  82. STDAPI_(void) DllRelease ( void );
  83. //+-------------------------------------------------------------------------
  84. //
  85. // Class: CStdClassFactory (cf)
  86. //
  87. // Synopsis: Standard implementation of a class factory. Class factory
  88. // implementations should inherit this class and implement the
  89. // method.
  90. //
  91. // Derivation: IClassFactory
  92. //
  93. // Notes: By deriving a class from this base class, you automatically
  94. // acquire implementations of DllGetClassObject and DllCanUnloadNow.
  95. // These can be ignored if implementing an LOCAL_SERVER.
  96. //
  97. //--------------------------------------------------------------------------
  98. class CStdClassFactory: public IClassFactory
  99. {
  100. public:
  101. CStdClassFactory ( REFCLSID rcls );
  102. //
  103. // IUnknown methods
  104. //
  105. STDMETHOD(QueryInterface) ( REFIID iid, void** ppv );
  106. STDMETHOD_(ULONG,AddRef) ( void );
  107. STDMETHOD_(ULONG,Release) ( void );
  108. //
  109. // IClassFactory methods
  110. //
  111. STDMETHOD(CreateInstance) (
  112. IUnknown* punkOuter,
  113. REFIID iidInterface,
  114. void** ppunkObject );
  115. STDMETHOD(LockServer) ( BOOL fLock );
  116. protected:
  117. friend HRESULT DllGetClassObject (
  118. REFCLSID rclsid,
  119. REFIID riid,
  120. LPVOID FAR* ppv );
  121. friend HRESULT DllCanUnloadNow ( void );
  122. friend void DllAddRef ( void );
  123. friend void DllRelease ( void );
  124. // must be provided in subclass. Behaviour is as for CreateInstance.
  125. STDMETHOD(_CreateInstance) (
  126. IUnknown* punkOuter,
  127. REFIID iidInterface,
  128. void** ppunkObject ) PURE;
  129. // overridden by subclass if the class supports interfaces
  130. // other than IClassFactory. Behaviour is as for QueryInterface
  131. // in respect of the additional interfaces. (Do not test for
  132. // IClassFactory or IUnknown).
  133. STDMETHOD(_QueryInterface) ( REFIID riid, void** ppv );
  134. static ULONG _gcDllRefs;
  135. static CStdClassFactory * _gpcfFirst;
  136. REFCLSID _rcls;
  137. CStdClassFactory * _pcfNext;
  138. ULONG _cRefs;
  139. };
  140. //+-------------------------------------------------------------------------
  141. //
  142. // Macro: DECLARE_CLASSFACTORY
  143. //
  144. // Synopsis: Declares a class factory.
  145. //
  146. // Arguments: [cls] -- The class of object that the class factory creates.
  147. //
  148. // Note: Use this macro to declare a subclass of CStdClassFactory
  149. // which does not support any interfaces other than IClassFactory.
  150. // If your class object supports additional interfaces or has
  151. // any member variables you should duplicate the behaviour
  152. // of this macro (in respect of calling the base class
  153. // constructor) and also:
  154. //
  155. // - override the _QueryInterface method
  156. // - use the DECLARE_CF_UNKNOWN_METHODS macro within your
  157. // derived class declaration.
  158. //
  159. //--------------------------------------------------------------------------
  160. #define DECLARE_CLASSFACTORY(cls) \
  161. \
  162. class cls##CF : public CStdClassFactory \
  163. { \
  164. public: \
  165. cls##CF() : \
  166. CStdClassFactory(CLSID_##cls) {}; \
  167. protected: \
  168. STDMETHOD(_CreateInstance)(IUnknown* pUnkOuter, \
  169. REFIID iidInterface, \
  170. void** ppv); \
  171. };
  172. //+-------------------------------------------------------------------------
  173. //
  174. // Macro: IMPLEMENT_CLASSFACTORY
  175. //
  176. // Synopsis: Implements the _CreateInstance method for a class factory.
  177. //
  178. // Arguments: [cls] -- The class of object that the class factory creates.
  179. // [ctrargs] -- A bracketed list of arguments to be passed
  180. // to the constructor of cls. Typically just ()
  181. //
  182. // Note: Use this macro when implementing a subclass of
  183. // CStdClassFactory that creates objects of a class derived
  184. // from CStdComponentObject.
  185. //
  186. //--------------------------------------------------------------------------
  187. #define IMPLEMENT_CLASSFACTORY(cls,ctrargs) \
  188. \
  189. STDMETHODIMP cls##CF::_CreateInstance( \
  190. IUnknown* punkOuter, \
  191. REFIID riid, \
  192. void** ppv) \
  193. { \
  194. cls* pInstance; \
  195. HRESULT hr; \
  196. \
  197. pInstance = new cls ctrargs; \
  198. if (pInstance == NULL) \
  199. { \
  200. hr = ResultFromScode(E_OUTOFMEMORY); \
  201. } \
  202. else \
  203. { \
  204. __try \
  205. { \
  206. hr = pInstance->InitInstance ( \
  207. punkOuter, \
  208. riid, \
  209. ppv ); \
  210. if ( FAILED(hr) ) \
  211. { \
  212. delete pInstance; \
  213. } \
  214. } \
  215. __except(EXCEPTION_EXECUTE_HANDLER) \
  216. { \
  217. delete pInstance; \
  218. hr = HRESULT_FROM_NT(GetExceptionCode()); \
  219. } \
  220. } \
  221. return hr; \
  222. }
  223. //+-------------------------------------------------------------------------
  224. //
  225. // Macro: DECLARE_CF_UNKNOWN_METHODS
  226. //
  227. // Synopsis: Declares and implements the IUnknown methods in a derived
  228. // class which supports interfaces other than IClassFactory.
  229. //
  230. // Note: Place an invocation of this macro within the declaration
  231. // of the derived class.
  232. //
  233. //--------------------------------------------------------------------------
  234. #define DECLARE_CF_UNKNOWN_METHODS \
  235. STDMETHOD(QueryInterface) ( REFIID riid, void ** ppv) \
  236. { return CStdClassFactory::QueryInterface(riid,ppv);}; \
  237. STDMETHOD_(ULONG,AddRef) ( void ) \
  238. { return CStdClassFactory::AddRef();}; \
  239. STDMETHOD_(ULONG,Release) ( void ) \
  240. { return CStdClassFactory::Release();};
  241. #endif // _STDCLASS_HXX_