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.

441 lines
16 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (c) Microsoft Corporation. All rights reserved.
  5. //
  6. // File: stdobj.hxx
  7. //
  8. // Contents: Standard component object support
  9. //
  10. // History: 3-June-93 MikeSe Created
  11. //
  12. // Notes: The contents of this file provide a standard infrastructure
  13. // for implementing (aggregatable) component objects, an amalgam
  14. // or work done by JohnEls and DonCl.
  15. //
  16. // The infrastructure supplies implementations of all the IUnknown
  17. // methods (both controlling and private), leaving the developer
  18. // to provide only the following:
  19. //
  20. // - initialisation
  21. // - destruction
  22. // - non-IUnknown methods of supported interfaces.
  23. //
  24. // The infrastructure assumes a static class factory object
  25. // (probably although not necessarily implemented using
  26. // CStdClassFactory) and a static description of the interfaces
  27. // supported or delegated through member variables.
  28. //
  29. // Summary of usage:
  30. //
  31. // 1. Declare your class as inheriting from CStdComponentObject.
  32. // Within the class definition, invoke the DECLARE_DELEGATED_UNKNOWN
  33. // macro to declare the required IUnknown methods. Do not include
  34. // IUnknown explicitly in the list of interface supported.
  35. //
  36. // 2. Use the BEGIN_CLASS, SUPPORTS(_EX), DELEGATES*
  37. // and END_CLASS macros to initialise the static class factory
  38. // and class descriptor for the class. This can be placed in any
  39. // convenient source file.
  40. //
  41. // These macros assume the following naming conventions, for
  42. // an implementation class named <cls>:
  43. //
  44. // - the class factory class is named <cls>CF.
  45. // - the class factory instance is named gcf<cls>Factory
  46. // - the class id for the class is named CLSID_<cls>
  47. // - the class descriptor for the class is named gcd<cls>Descriptor
  48. //
  49. // If you do not adhere to these conventions you will need to
  50. // duplicate the effect of the BEGIN_CLASS macro by hand, or
  51. // provide #define's of the above names to the actual names.
  52. //
  53. // 3. Implement class initialisation. A two-phase approach is used.
  54. // Any failure-free initialisation can be performed in the
  55. // constructor for the class, which *must* also invoke
  56. // the CStdComponentObject constructor, either through the
  57. // INIT_CLASS macro or an equivalent.
  58. //
  59. // If any of the initialisation is failure prone, provide an
  60. // implementation of the _InitInstance method which performs
  61. // this initialisation and returns an appropriate result code
  62. // in the contract of IClassFactory::CreateInstance.
  63. //
  64. // 4. Implement a destructor for your class, if you have any shutdown
  65. // requirements. The destructor should not assume that your
  66. // _InitInstance method (if any) has been called.
  67. //
  68. // 5. Implement the CreateInstance method for your class factory
  69. // (or _CreateInstance if using CStdClassFactory). This should
  70. // issue a 'new' on your class, and then invoke the (inherited)
  71. // InitInstance method.
  72. //
  73. // If you are using CStdClassFactory, you can use the
  74. // IMPLEMENT_CLASSFACTORY macro (defined in common\ih\stdclass.hxx)
  75. // to implement the _CreateInstance method, or in any case
  76. // you can look at the macro to get an idea of the general structure
  77. // you must follow.
  78. //
  79. //----------------------------------------------------------------------------
  80. #ifndef __STDOBJ_HXX__
  81. #define __STDOBJ_HXX__
  82. #include <windows.h>
  83. #include <ole2.h>
  84. #include <otrack.hxx>
  85. //+-------------------------------------------------------------------------
  86. //
  87. // Class: ITFDELTA
  88. //
  89. // Purpose: Defines an interface supported or delegated to.
  90. //
  91. // Notes: if piid is non-NULL
  92. // - a ulDelta with bit 31 set indicates a natively supported
  93. // interface, and (ulDelta&0x7FFFFFFF) gives the value which
  94. // must be added to the object's this pointer in order to
  95. // transform into the required interface pointer.
  96. // [in other words, the equivalent of doing (IFoo*)this]
  97. // - a ulDelta with bit 30 set indicates an interface pointer
  98. // which can be loaded directly from a member variable
  99. // at the offset (ulDelta&0x3FFFFFFF) from the object's this
  100. // pointer.
  101. // - otherwise ulDelta indicates an offset from the object's
  102. // this pointer to a member variable containing an IUnknown
  103. // pointer (a delegatee) which can be QI'd to get the interface
  104. // specified by piid.
  105. // if piid is NULL,
  106. // - ulDelta == 0x80000000L indicates the end of the table
  107. // for the class.
  108. // - otherwise, ulDelta gives the offset to an "else" delegatee
  109. // member variable. (See the DELEGATE_ELSE macro below).
  110. //
  111. //--------------------------------------------------------------------------
  112. class ITFDELTA
  113. {
  114. public:
  115. const IID * piid;
  116. ULONG ulDelta;
  117. };
  118. #define ITF_SUPPORTED 0x80000000L
  119. #define ITF_NO_QI 0x40000000L
  120. #define ITF_END 0x80000000L
  121. #define NOTDELEGATED(ulDelta) ((ulDelta & ITF_SUPPORTED)!=0)
  122. #define QIREQUIRED(ulDelta) ((ulDelta & ITF_NO_QI)==0)
  123. #define GETDELTA(ulDelta) (ulDelta & 0x3FFFFFFFL)
  124. #define MEMBEROFFSET(c,m) ((ULONG)&(((c *)0)->m))
  125. //+---------------------------------------------------------------------------
  126. //
  127. // Macros: SUPPORTS, SUPPORTS_EX, DELEGATES_DIRECT, DELEGATES_QI,
  128. // DELEGATES_ANY, END_INTERFACES
  129. //
  130. // These macros are used to declare ITFDELTA structures of various kinds.
  131. // They are intended to be used in conjunction with the BEGIN_CLASS and
  132. // END_CLASS macros (see below) and may not work correctly if used
  133. // otherwise.
  134. //
  135. // SUPPORTS is used to specify an interface that is supported directly
  136. // on the specified class.
  137. //
  138. // SUPPORTS_EX is used when an interface is inherited through more than one
  139. // parent, and you need to express which one to use.
  140. // SUPPORTS_EX(CFoo, IFoo, IPersist) says to use the IPersist inherited from
  141. // IFoo (as opposed to the one inherited from IPersistFile, say).
  142. //
  143. // DELEGATES_DIRECT specifies a member variable of the class which contains an
  144. // interface pointer to the specified interface.
  145. // IE: DELEGATES_DIRECT(CFoo,IFoo,_pmem) implies that _pmem is of type IFoo*.
  146. //
  147. // DELEGATES_QI is similar, except it specifies that the interface must be
  148. // obtained by issuing a QueryInterface on the pointer in the member variable.
  149. // (Thus the member variable can be of any type deriving from IUnknown). The
  150. // QueryInterface operation is permitted to fail.
  151. //
  152. // DELEGATES_ANY is similar to DELEGATES_QI except that any interface may
  153. // be requested from the referred to member variable. Thus it is a kind of
  154. // catchall.
  155. //
  156. // END_INTERFACES marks the end of the list. It is not used when END_CLASS
  157. // (see below) is used.
  158. //
  159. // Do not put semicolons at the ends of these statements.
  160. //
  161. // The built-in implementation of QueryInterface processes the ITFDELTA array
  162. // in the class descriptor in order, stopping as soon as the requested interface
  163. // is obtained. Thus DELEGATES_ANY entries, of which there may be several,
  164. // will normally appear last.
  165. //
  166. // If an interface which is part of a derivation chain is supported (eg:
  167. // IPersistStream, deriving from IPersist) then all the interfaces, except
  168. // IUnknown, must be listed. (i.e both IPersist and IPersistStream).
  169. //
  170. //----------------------------------------------------------------------------
  171. #define SUPPORTS(clsname, itfname) \
  172. { \
  173. &IID_##itfname, \
  174. ((ULONG)((VOID *) ((itfname *)(clsname *) ITF_SUPPORTED))) \
  175. },
  176. #define SUPPORTS_EX(clsname, itfprimary, itfname) \
  177. { \
  178. &IID_##itfname, \
  179. ((ULONG)(VOID *)(itfname *)((itfprimary *)((clsname *) ITF_SUPPORTED))) \
  180. },
  181. #define DELEGATES_DIRECT(clsname, itfname, iunkptr) \
  182. { \
  183. &IID_##itfname, \
  184. MEMBEROFFSET(clsname, iunkptr)|ITF_NO_QI \
  185. },
  186. #define DELEGATES_QI(clsname, itfname, iunkptr) \
  187. { \
  188. &IID_##itfname, \
  189. MEMBEROFFSET(clsname, iunkptr) \
  190. },
  191. #define DELEGATES_ANY(clsname, iunkptr) \
  192. { \
  193. NULL, \
  194. MEMBEROFFSET(clsname, iunkptr) \
  195. },
  196. #define END_INTERFACES \
  197. { \
  198. NULL, \
  199. ITF_END \
  200. }
  201. //+-------------------------------------------------------------------------
  202. //
  203. // Class: CLASSDESCRIPTION
  204. //
  205. // Purpose: Static description of class required by infrastructure.
  206. //
  207. // Notes: When creating a CLASSDESCRIPTOR, use the SUPPORTS etc.
  208. // macros to declare the entries in the aitfd array (or
  209. // better still, use BEGIN_CLASS etc to create the whole
  210. // descriptor).
  211. //
  212. //--------------------------------------------------------------------------
  213. #if _MSC_VER >= 1200
  214. #pragma warning(push)
  215. #endif
  216. #pragma warning ( disable: 4200 ) // valid use of open struct
  217. class CLASSDESCRIPTOR
  218. {
  219. public:
  220. const CLSID * pcls; // the class id
  221. char * pszClassName; // for object tracking, the
  222. // printable name of the class
  223. IClassFactory * pcf; // the class factory for the
  224. // class, assumed static
  225. ITFDELTA aitfd[]; // supported/delegated interfaces
  226. };
  227. #if _MSC_VER >= 1200
  228. #pragma warning(pop)
  229. #else
  230. #pragma warning ( default: 4200 )
  231. #endif
  232. //+-------------------------------------------------------------------------
  233. //
  234. // Macro: CLASSFACTORY_NAME, CLASSDESCRIPTOR_NAME
  235. //
  236. // Purpose: These macros generate the standard names for the class factory
  237. // and class descriptor instances for a class.
  238. //
  239. // Notes:
  240. //
  241. //--------------------------------------------------------------------------
  242. #define CLASSFACTORY_NAME(cls) gcf##cls##Factory
  243. #define CLASSDESCRIPTOR_NAME(cls) gcd##cls##Descriptor
  244. //+-------------------------------------------------------------------------
  245. //
  246. // Macro: BEGIN_CLASS
  247. //
  248. // Purpose: Declare the class factory and the first part of the
  249. // class descriptor.
  250. //
  251. // Notes: This macro is usually followed by zero or more ITFDELTA
  252. // declaration macros (SUPPORTS, etc) and then END_CLASS.
  253. //
  254. //--------------------------------------------------------------------------
  255. #define BEGIN_CLASS(cls) \
  256. cls##CF CLASSFACTORY_NAME(cls); \
  257. \
  258. CLASSDESCRIPTOR CLASSDESCRIPTOR_NAME(cls) = { \
  259. &CLSID_##cls, \
  260. #cls, \
  261. (IClassFactory*)&gcf##cls##Factory, \
  262. {
  263. //+-------------------------------------------------------------------------
  264. //
  265. // Macro: END_CLASS
  266. //
  267. // Purpose: Complete the declaration of the class descriptor.
  268. //
  269. // Notes:
  270. //
  271. //--------------------------------------------------------------------------
  272. #define END_CLASS \
  273. END_INTERFACES \
  274. } \
  275. };
  276. //+-------------------------------------------------------------------------
  277. //
  278. // Class: CStdComponentObject
  279. //
  280. // Purpose: Standard base class from which to derive aggregatable component
  281. // classes.
  282. //
  283. // Interface: CStdComponentObject [constructor]
  284. // InitInstance [second phase initialisation,
  285. // do not override].
  286. // ~CStdComponentObject [virtual destructor]
  287. // _InitInstance [virtual, override to provide
  288. // class-specific second phase
  289. // initialisation].
  290. // _QueryInterface [virtual, override to provide last
  291. // ditch QueryInterface operation ].
  292. //
  293. // Notes: "Last ditch" QI operation means anything which cannot be
  294. // described in a static ITFDELTA. The _QueryInterface method
  295. // (if provided) is invoked only if the requested interface
  296. // cannot be satisfied via the ITFDELTA table.
  297. //
  298. // The order of the method declarations is important, because
  299. // it allows us to safely cast a CStdComponentObject to an IUnknown
  300. // without actually deriving from it.
  301. //
  302. //--------------------------------------------------------------------------
  303. class CStdComponentObject: INHERIT_TRACKING
  304. {
  305. private:
  306. //
  307. // pseudo-IUnknown methods
  308. //
  309. STDMETHOD(PrimaryQueryInterface) (REFIID riid, void** ppv);
  310. STDMETHOD_(ULONG,PrimaryAddRef) (void);
  311. STDMETHOD_(ULONG,PrimaryRelease) (void);
  312. //
  313. // Two-phase constructor.
  314. //
  315. protected:
  316. CStdComponentObject ( const CLASSDESCRIPTOR * pcd );
  317. public:
  318. HRESULT InitInstance (
  319. IUnknown* punkOuter,
  320. REFIID riid,
  321. void** ppv );
  322. //
  323. // Destructor
  324. //
  325. virtual ~CStdComponentObject(void);
  326. protected:
  327. // Override the following method to provide last-ditch QueryInterface
  328. // behaviour.
  329. STDMETHOD(_QueryInterface) ( REFIID riid, void** ppv );
  330. // Override the following method to provide class-specific failure-prone
  331. // initialisation. Status codes returned must be in the set defined
  332. // as valid for IClassFactory::CreateInstance.
  333. STDMETHOD(_InitInstance) ( void );
  334. const CLASSDESCRIPTOR* _pcd;
  335. IUnknown* _punkControlling;
  336. };
  337. //+-------------------------------------------------------------------------
  338. //
  339. // Macro: DECLARE_DELEGATED_UNKNOWN
  340. //
  341. // Synopsis: Implements IUnknown methods that simply delegate to the
  342. // corresponding methods on the controlling IUnknown object.
  343. //
  344. // Note: Use this macro when declaring a subclass of CStdComponentObject.
  345. // Invoke it anywhere within the public portion of your class
  346. // definition. If you sub-subclass, you must invoke this macro
  347. // at each level. EG:
  348. //
  349. // class CMyMain: CStdComponentObject, IFoo
  350. //
  351. // class CMySub: CMyMain, IBar
  352. //
  353. // then both CMyMain and CMySub must DECLARE_DELEGATED_UNKNOWN.
  354. //
  355. //--------------------------------------------------------------------------
  356. #define DECLARE_DELEGATED_UNKNOWN \
  357. \
  358. STDMETHOD(QueryInterface) (REFIID riid, void** ppv) \
  359. { \
  360. return _punkControlling->QueryInterface(riid, ppv); \
  361. }; \
  362. \
  363. STDMETHOD_(ULONG,AddRef) () \
  364. { \
  365. return _punkControlling->AddRef(); \
  366. }; \
  367. \
  368. STDMETHOD_(ULONG,Release) () \
  369. { \
  370. return _punkControlling->Release(); \
  371. };
  372. //+-------------------------------------------------------------------------
  373. //
  374. // Macro: INIT_CLASS
  375. //
  376. // Purpose: Call constructor of base class correctly.
  377. //
  378. // Notes: This macro should be invoked in the initialisation
  379. // phase of the constructor for the component class
  380. // deriving from CStdComponentObject, viz:
  381. //
  382. // CMyClass::CMyClass ()
  383. // :INIT_CLASS(CMyClass)
  384. // other initialisations
  385. // {...
  386. //
  387. // Use of this macro requires the class descriptor to
  388. // be named according to the convention described previously.
  389. // If this is not so (eg: you didn't use BEGIN_CLASS) you
  390. // must write your own equivalent invocation.
  391. //
  392. // If you sub-subclass, you must declare the constructor
  393. // for the subclass appropriately, so that the class descriptor
  394. // for the sub-subclass can be passed through to CStdComponentObject.
  395. //
  396. //--------------------------------------------------------------------------
  397. #define INIT_CLASS(cls) CStdComponentObject ( &CLASSDESCRIPTOR_NAME(cls) )
  398. #endif // of ifndef __STDOBJ_HXX__