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.

305 lines
7.2 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2000.
  5. //
  6. // File: C O M U T I L I T Y . H
  7. //
  8. // Contents: COM support classes and functions
  9. //
  10. // Notes:
  11. //
  12. // Author: mbend 17 Aug 2000
  13. //
  14. //----------------------------------------------------------------------------
  15. #pragma once
  16. #include "ncbase.h"
  17. // Macro to make the validation of COM pointers easier
  18. #ifndef CHECK_POINTER
  19. #define CHECK_POINTER( p ) if(!p) {return E_POINTER;}
  20. #endif // CHECK_POINTER
  21. // Macros for use with iid_is style functions
  22. // For regular COM pointers
  23. #define SAFE_QI( p ) __uuidof( p ), reinterpret_cast<void**>(&p)
  24. // For smart com pointers
  25. #define SMART_QI( p ) p.IID(), p.VoidAddressOf()
  26. // String routines
  27. HRESULT HrCoTaskMemAllocArray(long nNumber, long nElemSize, void ** ppv);
  28. HRESULT HrCoTaskMemAllocString(long nChars, wchar_t ** psz);
  29. HRESULT HrCoTaskMemAllocString(wchar_t * sz, wchar_t ** psz);
  30. template<class Type>
  31. inline HRESULT HrCoTaskMemAllocArray(long nNumber, Type ** parType)
  32. {
  33. return HrCoTaskMemAllocArray(nNumber, sizeof(Type), reinterpret_cast<void**>(parType));
  34. }
  35. HRESULT HrCoCreateInstanceBase(
  36. REFCLSID clsid,
  37. DWORD dwClsContext,
  38. REFIID riid,
  39. void ** ppv);
  40. HRESULT HrCoCreateInstanceInprocBase(
  41. REFCLSID clsid,
  42. REFIID riid,
  43. void ** ppv);
  44. HRESULT HrCoCreateInstanceLocalBase(
  45. REFCLSID clsid,
  46. REFIID riid,
  47. void ** ppv);
  48. HRESULT HrCoCreateInstanceServerBase(
  49. REFCLSID clsid,
  50. REFIID riid,
  51. void ** ppv);
  52. template <class Inter>
  53. HRESULT HrCoCreateInstance(
  54. const CLSID & clsid,
  55. DWORD dwClsContext,
  56. Inter ** ppInter)
  57. {
  58. return HrCoCreateInstanceBase(
  59. clsid,
  60. dwClsContext,
  61. __uuidof(Inter),
  62. reinterpret_cast<void**>(ppInter));
  63. }
  64. template <class Inter>
  65. HRESULT HrCoCreateInstanceInproc(
  66. const CLSID & clsid,
  67. Inter ** ppInter)
  68. {
  69. return HrCoCreateInstanceInprocBase(
  70. clsid,
  71. __uuidof(Inter),
  72. reinterpret_cast<void**>(ppInter));
  73. }
  74. template <class Inter>
  75. HRESULT HrCoCreateInstanceLocal(
  76. const CLSID & clsid,
  77. Inter ** ppInter)
  78. {
  79. return HrCoCreateInstanceLocalBase(
  80. clsid,
  81. __uuidof(Inter),
  82. reinterpret_cast<void**>(ppInter));
  83. }
  84. template <class Inter>
  85. HRESULT HrCoCreateInstanceServer(
  86. const CLSID & clsid,
  87. Inter ** ppInter)
  88. {
  89. return HrCoCreateInstanceServerBase(
  90. clsid,
  91. __uuidof(Inter),
  92. reinterpret_cast<void**>(ppInter));
  93. }
  94. HRESULT HrIsSameObject(const IUnknown * pUnk1, const IUnknown * pUnk2);
  95. HRESULT HrSetProxyBlanket(
  96. IUnknown * pUnkProxy,
  97. DWORD dwAuthnLevel,
  98. DWORD dwImpLevel,
  99. DWORD dwCapabilities);
  100. HRESULT HrEnableStaticCloaking(IUnknown * pUnkProxy);
  101. HRESULT HrCopyProxyIdentity(IUnknown * pUnkDest, IUnknown * pUnkSrc);
  102. template <class Inter>
  103. class HideAddRefAndRelease : public Inter {
  104. STDMETHOD_(ULONG, AddRef)()=0;
  105. STDMETHOD_(ULONG, Release)()=0;
  106. };
  107. template <class Type> class SmartComPtr
  108. {
  109. typedef SmartComPtr<Type> SmartComPtrType;
  110. typedef Type * PType;
  111. typedef const Type * CPType;
  112. public:
  113. // Default Constructor
  114. SmartComPtr() : m_pType(NULL) {}
  115. // Copy Constructor
  116. SmartComPtr(const SmartComPtrType & ref) : m_pType(NULL)
  117. {
  118. Init(ref.m_pType);
  119. }
  120. // Assignment operators
  121. SmartComPtrType & operator=(const SmartComPtrType & ref)
  122. {
  123. if(this != &ref) {
  124. Release();
  125. Init(ref.m_pType);
  126. }
  127. return *this;
  128. }
  129. SmartComPtrType & operator=(CPType pType)
  130. {
  131. Release();
  132. Init(pType);
  133. return *this;
  134. }
  135. HRESULT HrAttach(const IUnknown * pUnk)
  136. {
  137. Release();
  138. return InitUnknown(pUnk);
  139. }
  140. template <class Inter>
  141. HRESULT HrAttach(const SmartComPtr<Inter> & ref)
  142. {
  143. return HrAttach(ref.GetRawPointer());
  144. }
  145. ~SmartComPtr()
  146. {
  147. Release();
  148. }
  149. // Conversion operators
  150. // Bypass const for COM compatibility
  151. operator PType() const
  152. {
  153. return const_cast<PType>(m_pType);
  154. }
  155. // Smart pointer accessor
  156. HideAddRefAndRelease<Type>* operator->() const
  157. {
  158. return reinterpret_cast<HideAddRefAndRelease<Type>*>(m_pType);
  159. }
  160. // Address of operator (should only be used to pass a NULL void** to a QI like function)
  161. PType * AddressOf()
  162. {
  163. // It is probably a bug if m_pType is not NULL
  164. Assert(!m_pType);
  165. Release();
  166. m_pType = NULL;
  167. return &m_pType;
  168. }
  169. const IID & IID() const
  170. {
  171. return __uuidof(PType);
  172. }
  173. PType GetPointer()
  174. {
  175. PType pType = m_pType;
  176. if(pType) pType->AddRef();
  177. return pType;
  178. }
  179. PType GetRawPointer()
  180. {
  181. return m_pType;
  182. }
  183. CPType GetRawPointer() const
  184. {
  185. return m_pType;
  186. }
  187. void ** VoidAddressOf()
  188. {
  189. return reinterpret_cast<void**>(AddressOf());
  190. }
  191. // Pointer comparison - uses COM notion of identity
  192. template <class Inter>
  193. HRESULT HrIsEqual(const SmartComPtr<Inter> & ref) const
  194. {
  195. return HrIsSameObject(m_pType, ref.m_pType);
  196. }
  197. HRESULT HrIsEqual(const IUnknown * pUnk) const
  198. {
  199. return HrIsSameObject(m_pType, pUnk);
  200. }
  201. template <class Inter>
  202. bool operator==(const SmartComPtr<Inter> & ref) const
  203. {
  204. return S_OK == HrIsSameObject(m_pType, ref.m_pType);
  205. }
  206. bool operator==(const IUnknown * pUnk) const
  207. {
  208. return S_OK == HrIsSameObject(m_pType, pUnk);
  209. }
  210. operator bool() const
  211. {
  212. return !!m_pType;
  213. }
  214. bool operator!() const
  215. {
  216. return !m_pType;
  217. }
  218. HRESULT HrCreateInstance(const CLSID & clsid, DWORD clsctx)
  219. {
  220. Release();
  221. return HrCoCreateInstance(clsid, clsctx, &m_pType);
  222. }
  223. HRESULT HrCreateInstanceInproc(const CLSID & clsid)
  224. {
  225. Release();
  226. return HrCoCreateInstanceInproc(clsid, &m_pType);
  227. }
  228. HRESULT HrCreateInstanceLocal(const CLSID & clsid)
  229. {
  230. Release();
  231. return HrCoCreateInstanceLocal(clsid, &m_pType);
  232. }
  233. HRESULT HrCreateInstanceServer(const CLSID & clsid)
  234. {
  235. Release();
  236. return HrCoCreateInstanceServer(clsid, &m_pType);
  237. }
  238. HRESULT HrSetProxyBlanket(
  239. DWORD dwAuthnLevel,
  240. DWORD dwImpLevel,
  241. DWORD dwCapabilities)
  242. {
  243. return ::HrSetProxyBlanket(m_pType, dwAuthnLevel, dwImpLevel, dwCapabilities);
  244. }
  245. HRESULT HrEnableStaticCloaking()
  246. {
  247. return ::HrEnableStaticCloaking(m_pType);
  248. }
  249. HRESULT HrCopyProxyIdentity(IUnknown * pUnkSrc)
  250. {
  251. return ::HrCopyProxyIdentity(m_pType, pUnkSrc);
  252. }
  253. void Release()
  254. {
  255. ReleaseObj(m_pType);
  256. m_pType = NULL;
  257. }
  258. void Swap(SmartComPtrType & ref)
  259. {
  260. PType pType = m_pType;
  261. m_pType = ref.m_pType;
  262. ref.m_pType = pType;
  263. }
  264. private:
  265. PType m_pType;
  266. void Init(CPType pType)
  267. {
  268. Assert(!m_pType);
  269. m_pType = const_cast<PType>(pType);
  270. AddRefObj(m_pType);
  271. }
  272. HRESULT InitUnknown(const IUnknown * pUnk)
  273. {
  274. Assert(!m_pType);
  275. HRESULT hRes = E_POINTER;
  276. if(pUnk)
  277. {
  278. hRes = const_cast<IUnknown*>(pUnk)->QueryInterface(&m_pType);
  279. }
  280. return hRes;
  281. }
  282. };