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.

455 lines
16 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. COMWrappers.h
  5. Abstract:
  6. Wrapper objects for COM
  7. Author:
  8. Hakki T. Bostanci (hakkib) 06-Apr-2000
  9. Revision History:
  10. --*/
  11. #ifndef _COM_WRAPPERS_H_
  12. #define _COM_WRAPPERS_H_
  13. //////////////////////////////////////////////////////////////////////////
  14. //
  15. // cross-references
  16. //
  17. #include "Wrappers.h"
  18. //////////////////////////////////////////////////////////////////////////
  19. //
  20. // vt_traits
  21. //
  22. // Traits class for mapping value types to the vt field and value offsets
  23. #define VT_F2O(field) FIELD_OFFSET(PROPVARIANT, field)
  24. #define VT_O2F(address, type, offset) (*(type *)((PBYTE) address + offset))
  25. template <class T> struct vt_traits { };
  26. template <> struct vt_traits<CHAR> { enum { vt = VT_I1, ofs = VT_F2O(cVal) }; };
  27. template <> struct vt_traits<UCHAR> { enum { vt = VT_UI1, ofs = VT_F2O(bVal) }; };
  28. template <> struct vt_traits<SHORT> { enum { vt = VT_I2, ofs = VT_F2O(iVal) }; };
  29. template <> struct vt_traits<USHORT> { enum { vt = VT_UI2, ofs = VT_F2O(uiVal) }; };
  30. template <> struct vt_traits<LONG> { enum { vt = VT_I4, ofs = VT_F2O(lVal) }; };
  31. template <> struct vt_traits<ULONG> { enum { vt = VT_UI4, ofs = VT_F2O(ulVal) }; };
  32. template <> struct vt_traits<INT> { enum { vt = VT_INT, ofs = VT_F2O(intVal) }; };
  33. template <> struct vt_traits<UINT> { enum { vt = VT_UINT, ofs = VT_F2O(uintVal) }; };
  34. template <> struct vt_traits<LARGE_INTEGER> { enum { vt = VT_I8, ofs = VT_F2O(hVal) }; };
  35. template <> struct vt_traits<ULARGE_INTEGER> { enum { vt = VT_UI8, ofs = VT_F2O(uhVal) }; };
  36. template <> struct vt_traits<FLOAT> { enum { vt = VT_R4, ofs = VT_F2O(fltVal) }; };
  37. template <> struct vt_traits<DOUBLE> { enum { vt = VT_R8, ofs = VT_F2O(dblVal) }; };
  38. template <> struct vt_traits<bool> { enum { vt = VT_BOOL, ofs = VT_F2O(boolVal) }; };
  39. //template <> struct vt_traits<SCODE> { enum { vt = VT_ERROR, ofs = VT_F2O(scode) }; };
  40. template <> struct vt_traits<CY> { enum { vt = VT_CY, ofs = VT_F2O(cyVal) }; };
  41. //template <> struct vt_traits<DATE> { enum { vt = VT_DATE, ofs = VT_F2O(date) }; };
  42. template <> struct vt_traits<FILETIME> { enum { vt = VT_FILETIME, ofs = VT_F2O(filetime) }; };
  43. //template <> struct vt_traits<CLSID *> { enum { vt = VT_CLSID, ofs = VT_F2O(puuid) }; };
  44. template <> struct vt_traits<CLIPDATA *> { enum { vt = VT_CF, ofs = VT_F2O(pclipdata) }; };
  45. template <> struct vt_traits<CComBSTR> { enum { vt = VT_BSTR, ofs = VT_F2O(bstrVal) }; };
  46. //?template <> struct vt_traits<BSTRBLOB> { enum { vt = VT_, ofs = VT_F2O(bstrblobVal) }; };
  47. template <> struct vt_traits<BLOB> { enum { vt = VT_BLOB, ofs = VT_F2O(blob) }; };
  48. template <> struct vt_traits<LPSTR> { enum { vt = VT_LPSTR, ofs = VT_F2O(pszVal) }; };
  49. template <> struct vt_traits<LPWSTR> { enum { vt = VT_LPWSTR, ofs = VT_F2O(pwszVal) }; };
  50. template <> struct vt_traits<CComPtr<IUnknown> > { enum { vt = VT_UNKNOWN, ofs = VT_F2O(punkVal) }; };
  51. template <> struct vt_traits<CComPtr<IDispatch> > { enum { vt = VT_DISPATCH, ofs = VT_F2O(pdispVal) }; };
  52. template <> struct vt_traits<CComPtr<IStream> > { enum { vt = VT_STREAM, ofs = VT_F2O(pStream) }; };
  53. template <> struct vt_traits<CComPtr<IStorage> > { enum { vt = VT_STORAGE, ofs = VT_F2O(pStorage) }; };
  54. //?template <> struct vt_traits<LPVERSIONEDSTREAM> { enum { vt = VT_, ofs = VT_F2O(pVersionedStream) }; };
  55. //?template <> struct vt_traits<LPSAFEARRAY> { enum { vt = VT_ARRAY | VT_, ofs = VT_F2O(parray) }; };
  56. template <> struct vt_traits<CAC> { enum { vt = VT_VECTOR | VT_I1, ofs = VT_F2O(cac) }; };
  57. template <> struct vt_traits<CAUB> { enum { vt = VT_VECTOR | VT_UI1, ofs = VT_F2O(caub) }; };
  58. template <> struct vt_traits<CAI> { enum { vt = VT_VECTOR | VT_I2, ofs = VT_F2O(cai) }; };
  59. template <> struct vt_traits<CAUI> { enum { vt = VT_VECTOR | VT_UI2, ofs = VT_F2O(caui) }; };
  60. template <> struct vt_traits<CAL> { enum { vt = VT_VECTOR | VT_I4, ofs = VT_F2O(cal) }; };
  61. template <> struct vt_traits<CAUL> { enum { vt = VT_VECTOR | VT_UI4, ofs = VT_F2O(caul) }; };
  62. template <> struct vt_traits<CAH> { enum { vt = VT_VECTOR | VT_I8, ofs = VT_F2O(cah) }; };
  63. template <> struct vt_traits<CAUH> { enum { vt = VT_VECTOR | VT_UI8, ofs = VT_F2O(cauh) }; };
  64. template <> struct vt_traits<CAFLT> { enum { vt = VT_VECTOR | VT_R4, ofs = VT_F2O(caflt) }; };
  65. template <> struct vt_traits<CADBL> { enum { vt = VT_VECTOR | VT_R8, ofs = VT_F2O(cadbl) }; };
  66. template <> struct vt_traits<CABOOL> { enum { vt = VT_VECTOR | VT_BOOL, ofs = VT_F2O(cabool) }; };
  67. template <> struct vt_traits<CASCODE> { enum { vt = VT_VECTOR | VT_ERROR, ofs = VT_F2O(cascode) }; };
  68. template <> struct vt_traits<CACY> { enum { vt = VT_VECTOR | VT_CY, ofs = VT_F2O(cacy) }; };
  69. template <> struct vt_traits<CADATE> { enum { vt = VT_VECTOR | VT_DATE, ofs = VT_F2O(cadate) }; };
  70. template <> struct vt_traits<CAFILETIME> { enum { vt = VT_VECTOR | VT_FILETIME, ofs = VT_F2O(cafiletime) }; };
  71. template <> struct vt_traits<CACLSID> { enum { vt = VT_VECTOR | VT_CLSID, ofs = VT_F2O(cauuid) }; };
  72. template <> struct vt_traits<CACLIPDATA> { enum { vt = VT_VECTOR | VT_CF, ofs = VT_F2O(caclipdata) }; };
  73. template <> struct vt_traits<CABSTR> { enum { vt = VT_VECTOR | VT_BSTR, ofs = VT_F2O(cabstr) }; };
  74. //?template <> struct vt_traits<CABSTRBLOB> { enum { vt = VT_VECTOR | VT_, ofs = VT_F2O(cabstrblob) }; };
  75. template <> struct vt_traits<CALPSTR> { enum { vt = VT_VECTOR | VT_LPSTR, ofs = VT_F2O(calpstr) }; };
  76. template <> struct vt_traits<CALPWSTR> { enum { vt = VT_VECTOR | VT_LPWSTR, ofs = VT_F2O(calpwstr) }; };
  77. template <> struct vt_traits<CAPROPVARIANT> { enum { vt = VT_VECTOR | VT_VARIANT, ofs = VT_F2O(capropvar) }; };
  78. //template <> struct vt_traits<CHAR *> { enum { vt = VT_BYREF | VT_I1, ofs = VT_F2O(cVal) }; };
  79. template <> struct vt_traits<UCHAR *> { enum { vt = VT_BYREF | VT_UI1, ofs = VT_F2O(bVal) }; };
  80. template <> struct vt_traits<SHORT *> { enum { vt = VT_BYREF | VT_I2, ofs = VT_F2O(iVal) }; };
  81. //template <> struct vt_traits<USHORT *> { enum { vt = VT_BYREF | VT_UI2, ofs = VT_F2O(uiVal) }; };
  82. template <> struct vt_traits<LONG *> { enum { vt = VT_BYREF | VT_I4, ofs = VT_F2O(lVal) }; };
  83. template <> struct vt_traits<ULONG *> { enum { vt = VT_BYREF | VT_UI4, ofs = VT_F2O(ulVal) }; };
  84. template <> struct vt_traits<INT *> { enum { vt = VT_BYREF | VT_INT, ofs = VT_F2O(intVal) }; };
  85. template <> struct vt_traits<UINT *> { enum { vt = VT_BYREF | VT_UINT, ofs = VT_F2O(uintVal) }; };
  86. template <> struct vt_traits<FLOAT *> { enum { vt = VT_BYREF | VT_R4, ofs = VT_F2O(fltVal) }; };
  87. template <> struct vt_traits<DOUBLE *> { enum { vt = VT_BYREF | VT_R8, ofs = VT_F2O(dblVal) }; };
  88. //template <> struct vt_traits<VARIANT_BOOL *> { enum { vt = VT_BYREF | VT_BOOL, ofs = VT_F2O(boolVal) }; };
  89. template <> struct vt_traits<DECIMAL *> { enum { vt = VT_BYREF | VT_DECIMAL, ofs = VT_F2O(scode) }; };
  90. //template <> struct vt_traits<SCODE *> { enum { vt = VT_BYREF | VT_ERROR, ofs = VT_F2O(scode) }; };
  91. template <> struct vt_traits<CY *> { enum { vt = VT_BYREF | VT_CY, ofs = VT_F2O(cyVal) }; };
  92. //template <> struct vt_traits<DATE *> { enum { vt = VT_BYREF | VT_DATE, ofs = VT_F2O(date) }; };
  93. template <> struct vt_traits<BSTR *> { enum { vt = VT_BYREF | VT_BSTR, ofs = VT_F2O(bstrVal) }; };
  94. template <> struct vt_traits<IUnknown **> { enum { vt = VT_BYREF | VT_UNKNOWN, ofs = VT_F2O(bstrVal) }; };
  95. template <> struct vt_traits<IDispatch **> { enum { vt = VT_BYREF | VT_DISPATCH, ofs = VT_F2O(bstrVal) }; };
  96. //?template <> struct vt_traits<LPSAFEARRAY *> { enum { vt = VT_BYREF | VT_ARRAY | VT_, ofs = VT_F2O(bstrVal) }; };
  97. template <> struct vt_traits<PROPVARIANT *> { enum { vt = VT_BYREF | VT_VARIANT, ofs = VT_F2O(bstrVal) }; };
  98. template <> struct vt_traits<DECIMAL> { enum { vt = VT_DECIMAL, ofs = VT_F2O(decVal) }; };
  99. //////////////////////////////////////////////////////////////////////////
  100. //
  101. // CPropVariant
  102. //
  103. // Wrapper class for the PROPVARIANT struct
  104. //
  105. class CPropVariant : public PROPVARIANT
  106. {
  107. // Constructors
  108. public:
  109. CPropVariant()
  110. {
  111. PropVariantInit(this);
  112. }
  113. ~CPropVariant()
  114. {
  115. PropVariantClear(this);
  116. }
  117. template <>
  118. CPropVariant(const CPropVariant &rhs)
  119. {
  120. PropVariantCopy(this, &rhs);
  121. }
  122. template <class T>
  123. CPropVariant(const T &rhs)
  124. {
  125. PropVariantInit(this);
  126. vt = vt_traits<T>::vt;
  127. VT_O2F(this, T, vt_traits<T>::ofs) = rhs;
  128. }
  129. template <>
  130. CPropVariant(const PROPVARIANT &rhs)
  131. {
  132. PropVariantCopy(this, &rhs);
  133. }
  134. template <>
  135. CPropVariant(const CLSID &rhs)
  136. {
  137. PropVariantInit(this);
  138. vt = VT_CLSID;
  139. puuid = (CLSID *) CoTaskMemAlloc(sizeof(CLSID));
  140. *puuid = rhs;
  141. }
  142. // Assignment Operators
  143. public:
  144. CPropVariant& operator =(const CPropVariant &rhs)
  145. {
  146. if (&rhs != this)
  147. {
  148. PropVariantClear(this);
  149. PropVariantCopy(this, &rhs);
  150. }
  151. return *this;
  152. }
  153. template <class T>
  154. CPropVariant& operator =(const T &rhs)
  155. {
  156. PropVariantClear(this);
  157. vt = vt_traits<T>::vt;
  158. VT_O2F(this, T, vt_traits<T>::ofs) = rhs;
  159. return *this;
  160. }
  161. template <>
  162. CPropVariant& operator =(const PROPVARIANT& rhs)
  163. {
  164. PropVariantClear(this);
  165. PropVariantCopy(this, &rhs);
  166. return *this;
  167. }
  168. template <>
  169. CPropVariant& operator =(const CLSID &rhs)
  170. {
  171. PropVariantClear(this);
  172. vt = VT_CLSID;
  173. puuid = (CLSID *) CoTaskMemAlloc(sizeof(CLSID));
  174. *puuid = rhs;
  175. return *this;
  176. }
  177. // Comparison Operators
  178. public:
  179. bool operator==(const PROPVARIANT& rhs) const
  180. {
  181. if (vt != rhs.vt)
  182. {
  183. return false;
  184. }
  185. switch (vt)
  186. {
  187. case VT_I1: return cVal == rhs.cVal;
  188. case VT_UI1: return bVal == rhs.bVal;
  189. case VT_I2: return iVal == rhs.iVal;
  190. case VT_UI2: return uiVal == rhs.uiVal;
  191. case VT_I4: return lVal == rhs.lVal;
  192. case VT_UI4: return ulVal == rhs.ulVal;
  193. case VT_INT: return intVal == rhs.intVal;
  194. case VT_UINT: return uintVal == rhs.uintVal;
  195. case VT_I8: return hVal.QuadPart == rhs.hVal.QuadPart;
  196. case VT_UI8: return uhVal.QuadPart == rhs.uhVal.QuadPart;
  197. case VT_R4: return fltVal == rhs.fltVal;
  198. case VT_R8: return dblVal == rhs.dblVal;
  199. case VT_BOOL: return boolVal == rhs.boolVal;
  200. case VT_ERROR: return scode == rhs.scode;
  201. case VT_CY: return cyVal.int64 == rhs.cyVal.int64;
  202. case VT_DATE: return date == rhs.date;
  203. case VT_FILETIME: return StructCmp(&filetime, &rhs.filetime) == 0;
  204. case VT_CLSID: return StructCmp(puuid, rhs.puuid) == 0;
  205. case VT_CF: return StructCmp(pclipdata, rhs.pclipdata) == 0;
  206. case VT_BSTR: return wcssafecmp(bstrVal, rhs.bstrVal) == 0;
  207. case VT_LPSTR: return strsafecmp(pszVal, rhs.pszVal) == 0;
  208. case VT_LPWSTR: return wcssafecmp(pwszVal, rhs.pwszVal) == 0;
  209. };
  210. ASSERT(FALSE);
  211. return false;
  212. }
  213. bool operator!=(const PROPVARIANT& rhs) const
  214. {
  215. return !(*this == rhs);
  216. }
  217. // Operations
  218. public:
  219. HRESULT Clear()
  220. {
  221. return PropVariantClear(this);
  222. }
  223. HRESULT Copy(const PROPVARIANT &rhs)
  224. {
  225. return PropVariantCopy(this, &rhs);
  226. }
  227. HRESULT ChangeType(VARTYPE vtNew)
  228. {
  229. // bugbug: VariantChangeType() cannot do all the work...
  230. return vt == vtNew ? S_OK :
  231. VariantChangeType((VARIANT*) this, (VARIANT*) this, 0, vtNew);
  232. }
  233. };
  234. //////////////////////////////////////////////////////////////////////////
  235. //
  236. // CPropSpec
  237. //
  238. // Wrapper class for the PROPSPEC struct
  239. //
  240. class CPropSpec : public PROPSPEC
  241. {
  242. public:
  243. CPropSpec()
  244. {
  245. }
  246. CPropSpec(LPOLESTR _lpwstr)
  247. {
  248. ulKind = PRSPEC_LPWSTR;
  249. lpwstr = _lpwstr;
  250. }
  251. CPropSpec(PROPID _propid)
  252. {
  253. ulKind = PRSPEC_PROPID;
  254. propid = _propid;
  255. }
  256. CPropSpec &operator =(LPOLESTR _lpwstr)
  257. {
  258. ulKind = PRSPEC_LPWSTR;
  259. lpwstr = _lpwstr;
  260. return *this;
  261. }
  262. CPropSpec &operator =(PROPID _propid)
  263. {
  264. ulKind = PRSPEC_PROPID;
  265. propid = _propid;
  266. return *this;
  267. }
  268. };
  269. //////////////////////////////////////////////////////////////////////////
  270. //
  271. // CStgMedium
  272. //
  273. // Wrapper class for the STGMEDIUM
  274. //
  275. class CStgMedium : public STGMEDIUM
  276. {
  277. DISABLE_COPY_CONTRUCTION(CStgMedium);
  278. public:
  279. CStgMedium()
  280. {
  281. ZeroMemory(this, sizeof(*this));
  282. }
  283. ~CStgMedium()
  284. {
  285. ReleaseStgMedium(this);
  286. }
  287. };
  288. //////////////////////////////////////////////////////////////////////////
  289. //
  290. // CStatPropStg
  291. //
  292. // Wrapper class for the STATPROPSTG struct
  293. //
  294. class CStatPropStg : public STATPROPSTG
  295. {
  296. DISABLE_COPY_CONTRUCTION(CStatPropStg);
  297. public:
  298. CStatPropStg()
  299. {
  300. ZeroMemory(this, sizeof(*this));
  301. }
  302. ~CStatPropStg()
  303. {
  304. CoTaskMemFree(lpwstrName);
  305. }
  306. bool operator ==(const CStatPropStg &rhs)
  307. {
  308. return
  309. vt == rhs.vt &&
  310. propid == rhs.propid &&
  311. wcssafecmp(lpwstrName, rhs.lpwstrName) == 0;
  312. }
  313. bool operator !=(const CStatPropStg &rhs)
  314. {
  315. return !(*this == rhs);
  316. }
  317. };
  318. //////////////////////////////////////////////////////////////////////////
  319. //
  320. // CComPtrArray
  321. //
  322. // Helper class for automatically releasing an array of interface pointers
  323. //
  324. template <class T>
  325. class CComPtrArray
  326. {
  327. DISABLE_COPY_CONTRUCTION(CComPtrArray);
  328. public:
  329. CComPtrArray()
  330. {
  331. m_pArray = 0;
  332. m_nItemCount = 0;
  333. }
  334. ~CComPtrArray()
  335. {
  336. Release();
  337. }
  338. void Release()
  339. {
  340. if (m_pArray)
  341. {
  342. for (int i = 0; i < m_nItemCount; ++i)
  343. {
  344. if (m_pArray[i])
  345. {
  346. m_pArray[i]->Release();
  347. }
  348. }
  349. CoTaskMemFree(m_pArray);
  350. m_pArray = 0;
  351. }
  352. m_nItemCount = 0;
  353. }
  354. operator T**()
  355. {
  356. return m_pArray;
  357. }
  358. bool operator!()
  359. {
  360. return m_pArray == 0;
  361. }
  362. T*** operator&()
  363. {
  364. ASSERT(m_pArray == 0);
  365. return &m_pArray;
  366. }
  367. LONG &ItemCount()
  368. {
  369. ASSERT(m_nItemCount == 0);
  370. return m_nItemCount;
  371. }
  372. private:
  373. T** m_pArray;
  374. LONG m_nItemCount;
  375. };
  376. //////////////////////////////////////////////////////////////////////////
  377. #endif //_COM_WRAPPERS_H_