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.

484 lines
11 KiB

  1. //-------------------------------------------------------------------------------------
  2. // T_SafeVector.h
  3. //
  4. // The follwing template classes provide a way of creating and accessing SafeArrays.
  5. // They are derived from the C++ standard library (STL) vector class and can be used
  6. // the same way. They can be accessed just like an array (with the [] operator).
  7. //
  8. // Use the constructors or assignment operators to extract the SafeArray from a
  9. // SAFEARRAY* or array variant (VARIANT or _variant_t). The elements will be
  10. // copied into the vector. Use the GetSafeArray() or GetVariant() methods to pack
  11. // the elements back into a SafeArray.
  12. //
  13. // To create a new SafeArray, declare a varaible of the appropriate type and call
  14. // resize() to set the size, or push_back() to grow the array. Call GetSafeArray()
  15. // or GetVariant() to produce a SafeArray.
  16. //
  17. // See the T_SafeVector2 class at the bottom of this file for more information
  18. // about the constructors, extractors, and assignment operators.
  19. //
  20. // Use the following pre-defined array types:
  21. //
  22. // Array Type - Element Type
  23. // -----------------------------------------------------------------------------
  24. // _bstr_tSafeVector - BSTR (uses _bstr_t)
  25. // longSafeVector - long
  26. // shortSafeVector - short
  27. // byteSafeVector - byte
  28. // boolSafeVector - bool
  29. // CWbemClassObjectSafeVector - IWbemClassObject (uses CWbemClassObject)
  30. //
  31. // Copyright (c)1997 - 1999 Microsoft Corporation, All Rights Reserved
  32. //------------------------------------------------------------------------------------
  33. #if !defined(__T_SafeVector_H)
  34. #define __T_SafeVector_H
  35. #pragma once
  36. #pragma warning( disable : 4786) // identifier was truncated to 'number' characters in the debug information
  37. #pragma warning( disable : 4503) // decorated name length exceeded, name was truncated
  38. typedef std::vector<_bstr_t> _bstr_tVec;
  39. typedef std::vector<long> longVec;
  40. typedef std::vector<short> shortVec;
  41. typedef std::vector<unsigned char> byteVec;
  42. typedef std::vector<bool> boolVec;
  43. #if !defined(NO_WBEM)
  44. typedef std::vector<CWbemClassObject> coVec;
  45. #endif
  46. template<typename TNContainer,typename TNDataType>
  47. class T_SAExtractScaler
  48. {
  49. public:
  50. void SetToContainer(TNContainer& _cont,void * pData,int l,int u)
  51. {
  52. TNDataType * pWalk = reinterpret_cast<TNDataType *>(pData);
  53. for(;l < (u+1);l++,pWalk++)
  54. {
  55. _cont.push_back( *pWalk);
  56. }
  57. }
  58. void GetFromContainer
  59. (
  60. TNContainer& _cont,
  61. void * pData,
  62. typename TNContainer::iterator walk,
  63. typename TNContainer::iterator finish
  64. )
  65. {
  66. TNDataType * pWalk = reinterpret_cast<TNDataType *>(pData);
  67. for(;walk != finish;walk++,pWalk++)
  68. {
  69. *pWalk = *walk;
  70. }
  71. }
  72. _bstr_t FormatDebugOutput
  73. (
  74. typename TNContainer::iterator first,
  75. typename TNContainer::iterator item,
  76. typename TNContainer::iterator last
  77. )
  78. {
  79. _bstr_t sRet;
  80. try
  81. {
  82. _variant_t v;
  83. v = v.operator=(TNDataType(*item));
  84. v.ChangeType(VT_BSTR);
  85. sRet = (_bstr_t) v;
  86. if( (item+1)!=last )
  87. {
  88. sRet += ", ";
  89. }
  90. }
  91. catch(_com_error&)
  92. {
  93. sRet = "Not supported";
  94. }
  95. return sRet;
  96. }
  97. };
  98. template<typename TNContainer>
  99. class T_Extract_bstr_t
  100. {
  101. public:
  102. T_Extract_bstr_t()
  103. {
  104. }
  105. void SetToContainer(TNContainer& _cont,void * pData,int l,int u)
  106. {
  107. BSTR * pWalk = reinterpret_cast<BSTR*>(pData);
  108. for(;l < (u+1);l++,pWalk++)
  109. {
  110. _cont.push_back( _bstr_t(*pWalk,true) );
  111. }
  112. }
  113. void GetFromContainer
  114. (
  115. TNContainer& _cont,
  116. void * pData,
  117. typename TNContainer::iterator walk,
  118. typename TNContainer::iterator finish
  119. )
  120. {
  121. BSTR * pWalk = reinterpret_cast<BSTR*>(pData);
  122. for(;walk != finish;walk++,pWalk++)
  123. {
  124. *pWalk = (*walk).copy();
  125. }
  126. }
  127. _bstr_t FormatDebugOutput
  128. (
  129. typename TNContainer::iterator first,
  130. typename TNContainer::iterator item,
  131. typename TNContainer::iterator last
  132. )
  133. {
  134. _bstr_t sRet;
  135. sRet += "\"";
  136. sRet += (*item);
  137. sRet += "\"";
  138. if( (item+1)!=last )
  139. {
  140. sRet += ", ";
  141. }
  142. return sRet;
  143. }
  144. };
  145. #if !defined(NO_WBEM)
  146. template<typename TNContainer>
  147. class T_Extract_IUnknown
  148. {
  149. public:
  150. T_Extract_IUnknown()
  151. {
  152. }
  153. void SetToContainer(TNContainer& _cont,void * pData,int l,int u)
  154. {
  155. IUnknown ** pWalk = reinterpret_cast<IUnknown **>(pData);
  156. for(;l< (u+1);l++,pWalk++)
  157. {
  158. _cont.push_back( CWbemClassObject((IWbemClassObject*)*pWalk) );
  159. }
  160. }
  161. void GetFromContainer
  162. (
  163. TNContainer& _cont,
  164. void * pData,
  165. TNContainer::iterator walk,
  166. TNContainer::iterator finish
  167. )
  168. {
  169. IUnknown ** pWalk = reinterpret_cast<IUnknown **>(pData);
  170. for(;walk != finish;walk++,pWalk++)
  171. {
  172. (*walk)->AddRef();
  173. *pWalk = (*walk);
  174. }
  175. }
  176. _bstr_t FormatDebugOutput
  177. (
  178. TNContainer::iterator first,
  179. TNContainer::iterator item,
  180. TNContainer::iterator last
  181. )
  182. {
  183. _bstr_t sRet;
  184. try
  185. {
  186. _variant_t v( long(item -first) );
  187. v.ChangeType(VT_BSTR);
  188. _variant_t v2( long(last-first-1) );
  189. v2.ChangeType(VT_BSTR);
  190. sRet += "Object [";
  191. sRet += (_bstr_t)v;
  192. sRet += " of ";
  193. sRet += (_bstr_t)v2;
  194. sRet += "]\n";
  195. sRet += (*item).GetObjectText();
  196. if( (item+1) != last )
  197. {
  198. sRet += "\n";
  199. }
  200. }
  201. catch(_com_error&)
  202. {
  203. sRet = "Not supported";
  204. }
  205. return sRet;
  206. }
  207. };
  208. #endif
  209. typedef T_SAExtractScaler<longVec,long> __exptExtractlong;
  210. typedef T_SAExtractScaler<shortVec,short> __exptExtractshort;
  211. typedef T_SAExtractScaler<byteVec,unsigned char> __exptExtractbyte;
  212. typedef T_SAExtractScaler<boolVec,bool> __exptExtractbool;
  213. typedef T_Extract_bstr_t<_bstr_tVec> __exptExtract_bstr_t;
  214. #if !defined(NO_WBEM)
  215. typedef T_Extract_IUnknown<coVec> __exptExtractco;
  216. #endif
  217. template<typename TNContainer,typename TNExtractor>
  218. class T_SafeArrayImp
  219. {
  220. public:
  221. void ConstructContainerFromSafeArray
  222. (
  223. TNExtractor& _extract,
  224. TNContainer& _cont,
  225. SAFEARRAY * _pSA
  226. )
  227. {
  228. long l = 0;
  229. long u = 0;
  230. HRESULT hr;
  231. void * pData;
  232. hr = SafeArrayGetLBound(_pSA,1,&l);
  233. hr = SafeArrayGetUBound(_pSA,1,&u);
  234. hr = SafeArrayAccessData(_pSA,&pData);
  235. if(hr == S_OK)
  236. {
  237. _extract.SetToContainer(_cont,pData,l,u);
  238. SafeArrayUnaccessData(_pSA);
  239. }
  240. }
  241. SAFEARRAY * ConstructSafeArrayFromConatiner
  242. (
  243. TNExtractor& _extract,
  244. VARTYPE _vt,
  245. TNContainer& _cont,
  246. typename TNContainer::iterator start,
  247. typename TNContainer::iterator finish
  248. )
  249. {
  250. HRESULT hr = S_OK;
  251. SAFEARRAY * pRet = NULL;
  252. SAFEARRAYBOUND rgsabound[1];
  253. void * pData;
  254. rgsabound[0].lLbound = 0;
  255. rgsabound[0].cElements = _cont.size();
  256. pRet = SafeArrayCreate(_vt,1,rgsabound);
  257. if(pRet)
  258. {
  259. hr = SafeArrayAccessData(pRet,&pData);
  260. if(hr == S_OK)
  261. {
  262. _extract.GetFromContainer(_cont,pData,start,finish);
  263. SafeArrayUnaccessData(pRet);
  264. }
  265. }
  266. return pRet;
  267. }
  268. };
  269. ///////////////////////////////////////////////////////////////////////////
  270. // T_SafeVector2
  271. //
  272. // Derived from TNContainer which should be a type of STL vector.
  273. // Provides for the conversion between vector and SafeArray.
  274. //
  275. template
  276. <
  277. VARTYPE TNVariant,
  278. typename TNDataType,
  279. typename TNContainer = std::vector<TNDataType>,
  280. typename TNExtractor = T_SAExtractScaler<TNContainer,TNDataType>
  281. >
  282. class T_SafeVector2 : public TNContainer
  283. {
  284. private:
  285. T_SafeArrayImp<TNContainer,TNExtractor> m_Array;
  286. protected:
  287. public:
  288. T_SafeVector2()
  289. {
  290. }
  291. // copy constructor
  292. T_SafeVector2(const TNContainer& _copy) : TNContainer(_copy)
  293. {
  294. }
  295. // Construct vector from array variant, extracts elements
  296. T_SafeVector2(_variant_t& _ValueArray)
  297. {
  298. if(_ValueArray.vt & VT_ARRAY)
  299. {
  300. m_Array.ConstructContainerFromSafeArray(TNExtractor(),*this,_ValueArray.parray);
  301. }
  302. }
  303. // Construct vector from SAFEARRAY, extracts elements
  304. T_SafeVector2(SAFEARRAY * _pArray)
  305. {
  306. m_Array.ConstructContainerFromSafeArray(TNExtractor(),*this,_pArray);
  307. }
  308. // assign vector from array variant, extracts elements
  309. T_SafeVector2& operator=(_variant_t& _ValueArray)
  310. {
  311. clear();
  312. if(_ValueArray.vt & VT_ARRAY)
  313. {
  314. m_Array.ConstructContainerFromSafeArray(TNExtractor(),*this,_ValueArray.parray);
  315. }
  316. return *this;
  317. }
  318. // assign vector from SAFEARRAY, extracts elements
  319. T_SafeVector2& operator=(SAFEARRAY * _pArray)
  320. {
  321. clear();
  322. m_Array.ConstructContainerFromSafeArray(TNExtractor(),*this,_pArray);
  323. return *this;
  324. }
  325. // assign vector from another vector, copies elements
  326. T_SafeVector2& operator=(const TNContainer& _copy)
  327. {
  328. TNContainer::operator=(_copy);
  329. return *this;
  330. }
  331. ~T_SafeVector2()
  332. {
  333. }
  334. // create SafeArray from a portion of the vector elements and return a SAFEARRAY*
  335. SAFEARRAY * GetSafeArray(typename TNContainer::iterator start, typename TNContainer::iterator finish)
  336. {
  337. return m_Array.ConstructSafeArrayFromConatiner(TNExtractor(),TNVariant,*this,start,finish);
  338. }
  339. // create SafeArray from the vector elements and return a SAFEARRAY*
  340. SAFEARRAY * GetSafeArray()
  341. {
  342. return GetSafeArray(begin(),end());
  343. }
  344. // create SafeArray from a portion of the vector elements and return as an array variant
  345. _variant_t GetVariant(typename TNContainer::iterator start, typename TNContainer::iterator finish)
  346. {
  347. _variant_t vRet;
  348. vRet.vt = TNVariant|VT_ARRAY;
  349. vRet.parray = GetSafeArray(start,finish);
  350. return vRet;
  351. }
  352. // create SafeArray from the vector elements and return as an array variant
  353. _variant_t GetVariant()
  354. {
  355. return GetVariant(begin(),end());
  356. }
  357. _bstr_t FormatDebugOutput()
  358. {
  359. _bstr_t sOutput;
  360. for(iterator walk = begin();walk != end();walk++)
  361. {
  362. sOutput += TNExtractor().FormatDebugOutput(begin(),walk,end());
  363. }
  364. return sOutput;
  365. }
  366. };
  367. typedef T_SafeVector2
  368. <
  369. VT_BSTR,
  370. _bstr_t,
  371. _bstr_tVec,
  372. T_Extract_bstr_t<_bstr_tVec>
  373. >
  374. _bstr_tSafeVector;
  375. typedef T_SafeVector2<VT_I4,long> longSafeVector;
  376. typedef T_SafeVector2<VT_I2,short> shortSafeVector;
  377. typedef T_SafeVector2<VT_UI1,unsigned char> byteSafeVector;
  378. typedef T_SafeVector2<VT_BOOL,bool> boolSafeVector;
  379. #if !defined(NO_WBEM)
  380. typedef T_SafeVector2
  381. <
  382. VT_UNKNOWN,
  383. CWbemClassObject,
  384. std::vector<CWbemClassObject>,
  385. T_Extract_IUnknown<std::vector<CWbemClassObject> >
  386. >
  387. CWbemClassObjectSafeVector;
  388. #endif
  389. #endif // __T_SafeVector_H