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.

355 lines
8.5 KiB

  1. /*++
  2. Copyright (C) 1996-2001 Microsoft Corporation
  3. Module Name:
  4. UNK.H
  5. Abstract:
  6. IUnknown Helpers
  7. History:
  8. --*/
  9. #ifndef __WBEM_UNKNOWN__H_
  10. #define __WBEM_UNKNOWN__H_
  11. #include <objbase.h>
  12. #include "corepol.h"
  13. #pragma warning(disable : 4355)
  14. class POLARITY CLifeControl
  15. {
  16. public:
  17. virtual BOOL ObjectCreated(IUnknown* pv) = 0;
  18. virtual void ObjectDestroyed(IUnknown* pv) = 0;
  19. virtual void AddRef(IUnknown* pv) = 0;
  20. virtual void Release(IUnknown* pv) = 0;
  21. };
  22. class POLARITY CContainerControl : public CLifeControl
  23. {
  24. protected:
  25. IUnknown* m_pUnk;
  26. public:
  27. CContainerControl(IUnknown* pUnk) : m_pUnk(pUnk){}
  28. virtual BOOL ObjectCreated(IUnknown* pv){ return TRUE;};
  29. virtual void ObjectDestroyed(IUnknown* pv){};
  30. virtual void AddRef(IUnknown* pv){m_pUnk->AddRef();}
  31. virtual void Release(IUnknown* pv){m_pUnk->Release();}
  32. };
  33. class POLARITY CUnk : public IUnknown
  34. {
  35. public:// THIS IS DUE TO A VC++ BUG!!! protected:
  36. long m_lRef;
  37. CLifeControl* m_pControl;
  38. IUnknown* m_pOuter;
  39. IUnknown* GetUnknown() {return m_pOuter?m_pOuter:(IUnknown*)this;}
  40. virtual void* GetInterface(REFIID riid) = 0;
  41. virtual BOOL OnInitialize(){return TRUE;}
  42. public:
  43. CUnk(CLifeControl* pControl = NULL, IUnknown* pOuter = NULL);
  44. virtual ~CUnk();
  45. virtual BOOL Initialize();
  46. // non-delegating interface
  47. STDMETHOD(QueryInterface)(REFIID riid, void** ppv);
  48. STDMETHOD_(ULONG, AddRef)();
  49. STDMETHOD_(ULONG, Release)();
  50. IUnknown* GetInnerUnknown() {return this;}
  51. void SetControl(CLifeControl* pControl);
  52. };
  53. class POLARITY CUnkInternal : public IUnknown
  54. {
  55. protected:
  56. long m_lRef;
  57. CLifeControl* m_pControl;
  58. public:
  59. CUnkInternal( CLifeControl* pControl ) : m_pControl(pControl), m_lRef(0) {}
  60. virtual ~CUnkInternal() {}
  61. virtual void* GetInterface(REFIID riid) = 0;
  62. IUnknown* GetUnknown() { return (IUnknown*)this; }
  63. STDMETHOD(QueryInterface)(REFIID riid, void** ppv)
  64. {
  65. HRESULT hr = InternalQueryInterface( riid, ppv );
  66. if ( SUCCEEDED(hr) )
  67. AddRef();
  68. return hr;
  69. }
  70. STDMETHOD_(ULONG, AddRef)()
  71. {
  72. if ( m_pControl )
  73. m_pControl->ObjectCreated((IUnknown*)this);
  74. return InternalAddRef();
  75. }
  76. STDMETHOD_(ULONG, Release)()
  77. {
  78. CLifeControl* pControl = m_pControl;
  79. ULONG ulRef = InternalRelease();
  80. if ( pControl )
  81. pControl->ObjectDestroyed((IUnknown*)this);
  82. return ulRef;
  83. }
  84. HRESULT InternalQueryInterface( REFIID riid, void** ppv )
  85. {
  86. HRESULT hr;
  87. if( riid == IID_IUnknown )
  88. *ppv = (IUnknown*)this;
  89. else
  90. *ppv = GetInterface(riid);
  91. if ( *ppv != NULL )
  92. hr = S_OK;
  93. else
  94. hr = E_NOINTERFACE;
  95. return hr;
  96. }
  97. ULONG InternalAddRef()
  98. {
  99. return InterlockedIncrement(&m_lRef);
  100. }
  101. ULONG InternalRelease()
  102. {
  103. long lRef = InterlockedDecrement(&m_lRef);
  104. if(lRef == 0)
  105. delete this;
  106. return lRef;
  107. }
  108. };
  109. template <class TInterface, class TObject>
  110. class CImpl : public TInterface
  111. {
  112. protected:
  113. TObject* m_pObject;
  114. public:
  115. CImpl(TObject* pObject) : m_pObject(pObject){}
  116. ~CImpl(){}
  117. // delegating interface
  118. STDMETHOD(QueryInterface)(REFIID riid, void** ppv)
  119. {
  120. return m_pObject->GetUnknown()->QueryInterface(riid, ppv);
  121. }
  122. STDMETHOD_(ULONG, AddRef)()
  123. {
  124. return m_pObject->GetUnknown()->AddRef();
  125. }
  126. STDMETHOD_(ULONG, Release)()
  127. {
  128. return m_pObject->GetUnknown()->Release();
  129. }
  130. };
  131. template <class TInterface, const IID* t_piid>
  132. class CUnkBase : public TInterface
  133. {
  134. protected:
  135. long m_lRef;
  136. CLifeControl* m_pControl;
  137. public:
  138. typedef CUnkBase<TInterface, t_piid> TUnkBase;
  139. CUnkBase(CLifeControl* pControl = NULL)
  140. : m_pControl(pControl), m_lRef(0)
  141. {
  142. if ( m_pControl != NULL ) m_pControl->ObjectCreated(this);
  143. }
  144. virtual ~CUnkBase()
  145. {
  146. if ( m_pControl != NULL ) m_pControl->ObjectDestroyed(this);
  147. }
  148. ULONG STDMETHODCALLTYPE AddRef()
  149. {
  150. return InterlockedIncrement(&m_lRef);
  151. }
  152. ULONG STDMETHODCALLTYPE Release()
  153. {
  154. long lRef = InterlockedDecrement(&m_lRef);
  155. if(lRef == 0)
  156. delete this;
  157. return lRef;
  158. }
  159. HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppv)
  160. {
  161. if(riid == IID_IUnknown || riid == *t_piid)
  162. {
  163. AddRef();
  164. *ppv = this;
  165. return S_OK;
  166. }
  167. else return E_NOINTERFACE;
  168. }
  169. };
  170. template <class TInterface, const IID* t_piid, class TInterface2,
  171. const IID* t_piid2>
  172. class CUnkBase2 : public TInterface, public TInterface2
  173. {
  174. protected:
  175. long m_lRef;
  176. CLifeControl* m_pControl;
  177. public:
  178. typedef CUnkBase2<TInterface, t_piid, TInterface2, t_piid2> TUnkBase;
  179. CUnkBase2(CLifeControl* pControl = NULL) : m_pControl(pControl), m_lRef(0)
  180. {
  181. if (m_pControl != NULL)
  182. m_pControl->ObjectCreated((TInterface*)this);
  183. }
  184. virtual ~CUnkBase2()
  185. {
  186. if (m_pControl != NULL)
  187. m_pControl->ObjectDestroyed((TInterface*)this);
  188. }
  189. ULONG STDMETHODCALLTYPE AddRef()
  190. {
  191. return InterlockedIncrement(&m_lRef);
  192. }
  193. ULONG STDMETHODCALLTYPE Release()
  194. {
  195. long lRef = InterlockedDecrement(&m_lRef);
  196. if(lRef == 0)
  197. delete this;
  198. return lRef;
  199. }
  200. HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppv)
  201. {
  202. if(riid == IID_IUnknown || riid == *t_piid)
  203. {
  204. AddRef();
  205. *ppv = (TInterface*)this;
  206. return S_OK;
  207. }
  208. else if(riid == *t_piid2)
  209. {
  210. AddRef();
  211. *ppv = (TInterface2*)this;
  212. return S_OK;
  213. }
  214. else return E_NOINTERFACE;
  215. }
  216. };
  217. template<class TInterface1, class TInterface2>
  218. class CChild2 : public virtual TInterface1, public virtual TInterface2
  219. {
  220. };
  221. template<class TInterfaces>
  222. class CUnkTemplate : public TInterfaces
  223. {
  224. protected:
  225. IUnknown* m_pOuter;
  226. class CInnerUnk : public IUnknown
  227. {
  228. private:
  229. CUnkTemplate<TInterfaces>* m_pObject;
  230. long m_lRef;
  231. CLifeControl* m_pControl;
  232. public:
  233. CInnerUnk(CUnkTemplate<TInterfaces>* pObject, CLifeControl* pControl)
  234. {
  235. if(m_pControl) m_pControl->ObjectCreated(this);
  236. m_lRef++;
  237. GetUnknown()->AddRef();
  238. m_pObject->Initialize();
  239. GetUnknown()->Release();
  240. m_lRef--;
  241. }
  242. ~CInnerUnk()
  243. {
  244. if(m_pControl) m_pControl->ObjectDestroyed(this);
  245. }
  246. // non-delegating interface
  247. STDMETHOD(QueryInterface)(REFIID riid, void** ppv)
  248. {
  249. if(riid == IID_IUnknown)
  250. *ppv = (IUnknown*)&m_Inner;
  251. else
  252. *ppv = m_pObject->GetInterface(riid);
  253. if(*ppv)
  254. {
  255. AddRef();
  256. return S_OK;
  257. }
  258. else return E_NOINTERFACE;
  259. }
  260. STDMETHOD_(ULONG, AddRef)()
  261. {
  262. if(m_pControl) m_pControl->AddRef((IUnknown*)this);
  263. return InterlockedIncrement(&m_lRef);
  264. }
  265. STDMETHOD_(ULONG, Release)()
  266. {
  267. if(m_pControl) m_pControl->Release((IUnknown*)this);
  268. long lRef = InterlockedDecrement(&m_lRef);
  269. if(lRef == 0)
  270. {
  271. m_lRef++;
  272. delete m_pObject;
  273. }
  274. return lRef;
  275. }
  276. } m_Inner;
  277. IUnknown* GetUnknown()
  278. {return m_pOuter?m_pOuter:(IUnknown*)&m_Inner;}
  279. virtual void Initialize(){}
  280. public:
  281. CUnkTemplate(CLifeControl* pControl = NULL, IUnknown* pOuter = NULL)
  282. : m_Inner(this, pControl), m_pOuter(pOuter){}
  283. virtual ~CUnkTemplate(){}
  284. // delegating interface
  285. STDMETHOD(QueryInterface)(REFIID riid, void** ppv)
  286. {
  287. return GetUnknown()->QueryInterface(riid, ppv);
  288. }
  289. STDMETHOD_(ULONG, AddRef)()
  290. {
  291. return GetUnknown()->AddRef();
  292. }
  293. STDMETHOD_(ULONG, Release)()
  294. {
  295. return GetUnknown()->Release();
  296. }
  297. IUnknown* GetInnerUnknown() {return &m_Inner;}
  298. };
  299. #endif