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.

481 lines
21 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995.
  5. //
  6. // File: NOUTIL.hxx
  7. //
  8. // Contents: Definitions of utility stuff for use
  9. //
  10. // Classes: StdClassFactory
  11. //
  12. // Functions:
  13. //
  14. // Macros:
  15. //
  16. // History:
  17. //
  18. //----------------------------------------------------------------------------
  19. #ifndef _NOUTIL_HXX_
  20. #define _NOUTIL_HXX_
  21. #include <formtrck.hxx>
  22. //+---------------------------------------------------------------------
  23. //
  24. // Generally useful #defines and inline functions for OLE2.
  25. //
  26. //------------------------------------------------------------------------
  27. // These are the major and minor version returned by OleBuildVersion
  28. #define OLE_MAJ_VER 0x0003
  29. #define OLE_MIN_VER 0x003A
  30. //---------------------------------------------------------------
  31. // SCODE and HRESULT macros
  32. //---------------------------------------------------------------
  33. #define OK(r) (SUCCEEDED(r))
  34. #define NOTOK(r) (FAILED(r))
  35. //---------------------------------------------------------------
  36. // IUnknown
  37. //---------------------------------------------------------------
  38. #define ADsIncrement(__ul) InterlockedIncrement((long *) &__ul)
  39. #define ADsDecrement(__ul) InterlockedDecrement((long *) &__ul)
  40. #define DECLARE_ADs_IUNKNOWN_METHODS \
  41. STDMETHOD(QueryInterface) (REFIID riid, LPVOID * ppv); \
  42. STDMETHOD_(ULONG, AddRef) (void); \
  43. STDMETHOD_(ULONG, Release) (void);
  44. #define DECLARE_ADs_STANDARD_IUNKNOWN(cls) \
  45. STDMETHOD(QueryInterface) (REFIID riid, LPVOID * ppv); \
  46. ULONG _ulRefs; \
  47. STDMETHOD_(ULONG, AddRef) (void) \
  48. { \
  49. ADsIncrement(_ulRefs); \
  50. return _ulRefs; \
  51. } \
  52. STDMETHOD_(ULONG, Release) (void) \
  53. { \
  54. if (!ADsDecrement(_ulRefs)) \
  55. { \
  56. ADsIncrement(_ulRefs); \
  57. delete this; \
  58. return 0; \
  59. } \
  60. return _ulRefs; \
  61. }
  62. #define DECLARE_ADs_DELEGATING_IUNKNOWN(cls) \
  63. IUnknown * _pUnkOuter; \
  64. STDMETHOD(QueryInterface) (REFIID iid, LPVOID * ppv) \
  65. { return _pUnkOuter->QueryInterface(iid, ppv); } \
  66. STDMETHOD_(ULONG, AddRef) (void) \
  67. { return _pUnkOuter->AddRef(); } \
  68. STDMETHOD_(ULONG, Release) (void) \
  69. { return _pUnkOuter->Release(); }
  70. #define DECLARE_DELEGATING_REFCOUNTING \
  71. IUnknown * _pUnkOuter; \
  72. STDMETHOD_(ULONG, AddRef) (void) \
  73. { return _pUnkOuter->AddRef(); } \
  74. STDMETHOD_(ULONG, Release) (void) \
  75. { return _pUnkOuter->Release(); }
  76. #if DBG == 0
  77. //
  78. // Retail versions of these macros
  79. //
  80. #define DECLARE_ADs_PRIVATE_IUNKNOWN(cls) \
  81. class PrivateUnknown : public IUnknown \
  82. { \
  83. private: \
  84. ULONG _ulRefs; \
  85. cls * My##cls(void) \
  86. { return CONTAINING_RECORD(this, cls, _PrivUnk); } \
  87. \
  88. public: \
  89. PrivateUnknown(void) \
  90. { _ulRefs = 1; } \
  91. \
  92. DECLARE_ADs_IUNKNOWN_METHODS \
  93. }; \
  94. friend class PrivateUnknown; \
  95. PrivateUnknown _PrivUnk;
  96. #define IMPLEMENT_ADs_PRIVATE_IUNKNOWN(cls) \
  97. STDMETHODIMP_(ULONG) cls::PrivateUnknown::AddRef( ) \
  98. { \
  99. ADsIncrement(_ulRefs); \
  100. return _ulRefs; \
  101. } \
  102. STDMETHODIMP_(ULONG) cls::PrivateUnknown::Release( ) \
  103. { \
  104. if (!ADsDecrement(_ulRefs)) \
  105. { \
  106. ADsIncrement(_ulRefs); \
  107. delete My##cls(); \
  108. return 0; \
  109. } \
  110. return _ulRefs; \
  111. }
  112. #define DECLARE_ADs_COMPOUND_IUNKNOWN(cls) \
  113. class PrivateUnknown : public IUnknown \
  114. { \
  115. friend class cls; \
  116. \
  117. public: \
  118. PrivateUnknown(void) \
  119. { _ulRefs = 1; _ulAllRefs = 1; } \
  120. \
  121. DECLARE_ADs_IUNKNOWN_METHODS \
  122. \
  123. private: \
  124. ULONG _ulRefs; \
  125. ULONG _ulAllRefs; \
  126. \
  127. cls * My##cls(void) \
  128. { return CONTAINING_RECORD(this, cls, _PrivUnk); } \
  129. }; \
  130. friend class PrivateUnknown; \
  131. PrivateUnknown _PrivUnk; \
  132. \
  133. ULONG SubAddRef(void); \
  134. ULONG SubRelease(void);
  135. #define IMPLEMENT_ADs_COMPOUND_IUNKNOWN(cls) \
  136. STDMETHODIMP_(ULONG) cls::PrivateUnknown::AddRef( ) \
  137. { \
  138. ADsIncrement(_ulAllRefs); \
  139. ADsIncrement(_ulRefs); \
  140. return _ulRefs; \
  141. } \
  142. STDMETHODIMP_(ULONG) cls::PrivateUnknown::Release( ) \
  143. { \
  144. if (!ADsDecrement(_ulRefs)) \
  145. { \
  146. My##cls()->Passivate(); \
  147. } \
  148. if (!ADsDecrement(_ulAllRefs)) \
  149. { \
  150. ADsIncrement(_ulAllRefs); \
  151. delete My##cls(); \
  152. return 0; \
  153. } \
  154. return _ulRefs; \
  155. } \
  156. ULONG cls::SubAddRef( ) \
  157. { \
  158. return ADsIncrement(_PrivUnk._ulAllRefs); \
  159. } \
  160. ULONG cls::SubRelease( ) \
  161. { \
  162. ULONG ul; \
  163. \
  164. ul = ADsDecrement(_PrivUnk._ulAllRefs); \
  165. if (!ul) \
  166. { \
  167. ADsIncrement(_PrivUnk._ulAllRefs); \
  168. delete this; \
  169. } \
  170. \
  171. return ul; \
  172. }
  173. #else // DBG == 0
  174. //
  175. // Debug versions of these macros
  176. //
  177. #define DECLARE_ADs_PRIVATE_IUNKNOWN(cls) \
  178. class PrivateUnknown : protected ObjectTracker, \
  179. public IUnknown \
  180. { \
  181. private: \
  182. cls * My##cls(void) \
  183. { return CONTAINING_RECORD(this, cls, _PrivUnk); } \
  184. \
  185. public: \
  186. PrivateUnknown(void) \
  187. { _ulRefs = 1; TrackClassName(#cls); } \
  188. \
  189. DECLARE_ADs_IUNKNOWN_METHODS \
  190. }; \
  191. friend class PrivateUnknown; \
  192. PrivateUnknown _PrivUnk;
  193. #define IMPLEMENT_ADs_PRIVATE_IUNKNOWN(cls) \
  194. STDMETHODIMP_(ULONG) cls::PrivateUnknown::AddRef( ) \
  195. { \
  196. StdAddRef(); \
  197. return _ulRefs; \
  198. } \
  199. STDMETHODIMP_(ULONG) cls::PrivateUnknown::Release( ) \
  200. { \
  201. if (!StdRelease()) \
  202. { \
  203. ADsIncrement(_ulRefs); \
  204. delete My##cls(); \
  205. return 0; \
  206. } \
  207. return _ulRefs; \
  208. }
  209. #define DECLARE_ADs_COMPOUND_IUNKNOWN(cls) \
  210. class PrivateUnknown : protected ObjectTracker, \
  211. public IUnknown \
  212. { \
  213. friend class cls; \
  214. \
  215. public: \
  216. PrivateUnknown(void) \
  217. { _ulNRefs = 1; _ulRefs = 1; TrackClassName(#cls); } \
  218. \
  219. DECLARE_ADs_IUNKNOWN_METHODS \
  220. \
  221. private: \
  222. ULONG _ulNRefs; \
  223. \
  224. cls * My##cls(void) \
  225. { return CONTAINING_RECORD(this, cls, _PrivUnk); } \
  226. }; \
  227. friend class PrivateUnknown; \
  228. PrivateUnknown _PrivUnk; \
  229. \
  230. ULONG SubAddRef(void); \
  231. ULONG SubRelease(void);
  232. #define IMPLEMENT_ADs_COMPOUND_IUNKNOWN(cls) \
  233. STDMETHODIMP_(ULONG) cls::PrivateUnknown::AddRef( ) \
  234. { \
  235. StdAddRef(); \
  236. ADsIncrement(_ulNRefs); \
  237. return _ulNRefs; \
  238. } \
  239. STDMETHODIMP_(ULONG) cls::PrivateUnknown::Release( ) \
  240. { \
  241. if (!ADsDecrement(_ulNRefs)) \
  242. { \
  243. My##cls()->Passivate(); \
  244. } \
  245. if (!StdRelease()) \
  246. { \
  247. ADsIncrement(_ulRefs); \
  248. delete My##cls(); \
  249. return 0; \
  250. } \
  251. return _ulNRefs; \
  252. } \
  253. ULONG cls::SubAddRef( ) \
  254. { \
  255. return _PrivUnk.StdAddRef(); \
  256. } \
  257. ULONG cls::SubRelease( ) \
  258. { \
  259. ULONG ul; \
  260. \
  261. ul = _PrivUnk.StdRelease(); \
  262. if (!ul) \
  263. { \
  264. ADsIncrement(_PrivUnk._ulRefs); \
  265. delete this; \
  266. } \
  267. \
  268. return ul; \
  269. }
  270. #endif // DBG == 0
  271. // The Detach method is no longer useful, now that we've
  272. // removed the parent class pointer
  273. #define DECLARE_ADs_SUBOBJECT_IUNKNOWN(cls, parent_cls, member) \
  274. DECLARE_ADs_IUNKNOWN_METHODS \
  275. parent_cls * My##parent_cls(void); \
  276. void Detach(void) \
  277. { ; }
  278. #define IMPLEMENT_ADs_SUBOBJECT_IUNKNOWN(cls, parent_cls, member) \
  279. inline parent_cls * cls::My##parent_cls(void) \
  280. { \
  281. return CONTAINING_RECORD(this, parent_cls, member); \
  282. } \
  283. STDMETHODIMP_(ULONG) cls::AddRef( ) \
  284. { return My##parent_cls()->SubAddRef(); } \
  285. STDMETHODIMP_(ULONG) cls::Release( ) \
  286. { return My##parent_cls()->SubRelease(); }
  287. //+------------------------------------------------------------------------
  288. //
  289. // NO_COPY *declares* the constructors and assignment operator for copying.
  290. // By not *defining* these functions, you can prevent your class from
  291. // accidentally being copied or assigned -- you will be notified by
  292. // a linkage error.
  293. //
  294. //-------------------------------------------------------------------------
  295. #define NO_COPY(cls) \
  296. cls(const cls&); \
  297. cls& operator=(const cls&);
  298. //+---------------------------------------------------------------------
  299. //
  300. // Miscellaneous useful OLE helper and debugging functions
  301. //
  302. //----------------------------------------------------------------------
  303. //
  304. // Some convenient OLE-related definitions and declarations
  305. //
  306. typedef unsigned short far * LPUSHORT;
  307. //REVIEW we are experimenting with a non-standard OLEMISC flag.
  308. #define OLEMISC_STREAMABLE 1024
  309. #include "misc.hxx"
  310. #if DBG == 1
  311. STDAPI_(void) PrintIID(DWORD dwFlags, REFIID riid);
  312. #define TRACEIID(iid) PrintIID(DEB_TRACE, iid)
  313. #else // DBG == 0
  314. #define TRACEIID(iid)
  315. #endif // DBG
  316. //+---------------------------------------------------------------------
  317. //
  318. // Interface wrapper for tracing method invocations
  319. //
  320. //----------------------------------------------------------------------
  321. #if DBG == 1
  322. LPVOID WatchInterface(REFIID riid, LPVOID pv, LPWSTR lpstr);
  323. #define WATCHINTERFACE(iid, p, lpstr) WatchInterface(iid, p, lpstr)
  324. #else // DBG == 0
  325. #define WATCHINTERFACE(iid, p, lpstr) (p)
  326. #endif // DBG
  327. //+---------------------------------------------------------------------
  328. //
  329. // Standard IClassFactory implementation
  330. //
  331. //----------------------------------------------------------------------
  332. //+---------------------------------------------------------------
  333. //
  334. // Class: StdClassFactory
  335. //
  336. // Purpose: Standard implementation of a class factory object
  337. //
  338. // Notes: **************!!!!!!!!!!!!!!!!!*************
  339. // TAKE NOTE --- The implementation of Release on this
  340. // class does not perform a delete. This is so you can
  341. // make the class factory a global static variable.
  342. // Use the CDynamicCF class below for an object
  343. // which is not global static data.
  344. //
  345. // ALSO - The refcount is initialized to 0, NOT 1!
  346. //
  347. //---------------------------------------------------------------
  348. class StdClassFactory: public IClassFactory
  349. {
  350. public:
  351. StdClassFactory(void) : _ulRefs(1) {};
  352. // IUnknown methods
  353. DECLARE_ADs_IUNKNOWN_METHODS;
  354. // IClassFactory methods
  355. STDMETHOD(LockServer) (BOOL fLock);
  356. // CreateInstance is left pure virtual.
  357. protected:
  358. ULONG _ulRefs;
  359. };
  360. //+---------------------------------------------------------------------------
  361. //
  362. // Class: CDynamicCF (DYNCF)
  363. //
  364. // Purpose: Class factory which exists on the heap, and whose Release
  365. // method does the normal thing.
  366. //
  367. // Interface: DECLARE_ADs_STANDARD_IUNKNOWN -- IUnknown methods
  368. //
  369. // LockServer -- Per IClassFactory.
  370. // CDynamicCF -- ctor.
  371. // ~CDynamicCF -- dtor.
  372. //
  373. // History: 6-22-94 adams Created
  374. // 7-13-94 adams Moved from ADs\inc\dyncf.hxx
  375. //
  376. //----------------------------------------------------------------------------
  377. class CDynamicCF: public IClassFactory
  378. {
  379. public:
  380. // IUnknown methods
  381. DECLARE_ADs_STANDARD_IUNKNOWN(CDynamicCF)
  382. // IClassFactory methods
  383. STDMETHOD(LockServer) (BOOL fLock);
  384. protected:
  385. CDynamicCF(void);
  386. virtual ~CDynamicCF(void);
  387. };
  388. #endif //__NOUTILS_HXX_