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.

496 lines
12 KiB

  1. //*************************************************************
  2. //
  3. // Copyright (c) Microsoft Corporation 1999 - 2000
  4. // All rights reserved
  5. //
  6. // variant.hxx
  7. //
  8. //*************************************************************
  9. #include "rsop.hxx"
  10. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  11. //
  12. // Function: CVariant::CVariant
  13. //
  14. // Purpose: Constructor for CVariant class. Initializes the
  15. // storage of the variant data.
  16. //
  17. // Params: none
  18. //
  19. // Return value: none
  20. //
  21. // Notes:
  22. //
  23. //------------------------------------------------------------
  24. CVariant::CVariant() :
  25. _iCurrentArrayIndex(0),
  26. _cMaxArrayElements(0)
  27. {
  28. VariantInit(&_var);
  29. }
  30. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  31. //
  32. // Function: CVariant::~CVariant
  33. //
  34. // Purpose: Denstructor for CVariant class. Frees any data
  35. // allocated to store variant data.
  36. //
  37. // Params: none
  38. //
  39. // Return value: none
  40. //
  41. // Notes:
  42. //
  43. //------------------------------------------------------------
  44. CVariant::~CVariant()
  45. {
  46. HRESULT hr;
  47. hr = VariantClear(&_var);
  48. ASSERT(SUCCEEDED(hr));
  49. }
  50. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  51. //
  52. // Function: CVariant::SetStringValue
  53. //
  54. // Purpose: Sets the type of the variant to VT_BSTR and creates
  55. // a bstr to store the string.
  56. //
  57. // Params: wszValue -- this unicode string is the value to
  58. // which we want to set this variant
  59. //
  60. // Return value: returns S_OK if successful, other
  61. // error code if not
  62. //
  63. // Notes: The variant should not be set to a value after
  64. // this is called -- otherwise, you may lose reference
  65. // to allocated memory -- the value is meant to be set
  66. // only once.
  67. //
  68. //------------------------------------------------------------
  69. HRESULT CVariant::SetStringValue(WCHAR* wszValue)
  70. {
  71. XBStr xString;
  72. ASSERT(VT_EMPTY == _var.vt);
  73. xString = wszValue;
  74. if (!xString)
  75. {
  76. return E_OUTOFMEMORY;
  77. }
  78. _var.vt = VT_BSTR;
  79. _var.bstrVal = xString.Acquire();
  80. return S_OK;
  81. }
  82. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  83. //
  84. // Function: CVariant::SetLongValue
  85. //
  86. // Purpose: Sets the type of the variant to VT_I4 and creates
  87. // a bstr to store the string.
  88. //
  89. // Params: lValue -- this LONG value is the value to
  90. // which we want to set this variant
  91. //
  92. // Return value: returns S_OK if successful, other
  93. // error code if not
  94. //
  95. // Notes: The variant should not be set to a value after
  96. // this is called -- otherwise, you may lose reference
  97. // to allocated memory -- the value is meant to be set
  98. // only once.
  99. //
  100. //------------------------------------------------------------
  101. HRESULT CVariant::SetLongValue(LONG lValue)
  102. {
  103. ASSERT(VT_EMPTY == _var.vt);
  104. _var.vt = VT_I4;
  105. _var.lVal = lValue;
  106. return S_OK;
  107. }
  108. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  109. //
  110. // Function: CVariant::SetBoolValue
  111. //
  112. // Purpose: Sets the type of the variant to VT_BOOL and stores the value
  113. //
  114. // Params: bValue -- this boolean value is the value to
  115. // which we want to set this variant
  116. //
  117. // Return value: returns S_OK if successful, other
  118. // error code if not
  119. //
  120. // Notes: The variant should not be set to a value after
  121. // this is called -- otherwise, you may lose reference
  122. // to allocated memory -- the value is meant to be set
  123. // only once.
  124. //
  125. //------------------------------------------------------------
  126. HRESULT CVariant::SetBoolValue(BOOL bValue)
  127. {
  128. ASSERT(VT_EMPTY == _var.vt);
  129. _var.vt = VT_BOOL;
  130. _var.boolVal = bValue ? VARIANT_TRUE : VARIANT_FALSE;
  131. return S_OK;
  132. }
  133. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  134. //
  135. // Function: CVariant::SetNextLongArrayElement
  136. //
  137. // Purpose: Adds an element in an array of strings to a
  138. // specified string
  139. //
  140. // Params: Value -- the value to which to add as an element
  141. // cMaxElements (optional) -- the maximum number
  142. // of elements in this array -- must be specified
  143. // the first time this method is called on this object
  144. //
  145. // Return value: returns S_OK if successful, other
  146. // error code if not
  147. //
  148. // Notes:
  149. //
  150. //------------------------------------------------------------
  151. HRESULT CVariant::SetNextLongArrayElement(
  152. LONG Value,
  153. DWORD cMaxElements)
  154. {
  155. HRESULT hr;
  156. //
  157. // Add the long to the correct index
  158. // in the array
  159. //
  160. hr = SetNextArrayElement(
  161. VT_I4,
  162. cMaxElements,
  163. &Value);
  164. return hr;
  165. }
  166. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  167. //
  168. // Function: CVariant::SetNextStringArrayElement
  169. //
  170. // Purpose: Adds an element to an array of strings
  171. //
  172. // Params: wszValue -- the value to which to add as an element
  173. // cMaxElements (optional) -- the maximum number
  174. // of elements in this array -- must be specified
  175. // the first time this method is called on this object
  176. //
  177. // Return value: returns S_OK if successful, other
  178. // error code if not
  179. //
  180. // Notes:
  181. //
  182. //------------------------------------------------------------
  183. HRESULT CVariant::SetNextStringArrayElement(
  184. WCHAR* wszValue,
  185. DWORD cMaxElements)
  186. {
  187. HRESULT hr;
  188. XBStr xString;
  189. //
  190. // Create a bstr from the supplied unicode string
  191. //
  192. xString = wszValue;
  193. if (!xString)
  194. {
  195. return E_OUTOFMEMORY;
  196. }
  197. //
  198. // Now add the unicode string to the correct index
  199. // in the array
  200. //
  201. hr = SetNextArrayElement(
  202. VT_BSTR,
  203. cMaxElements,
  204. xString);
  205. //
  206. // If we've succeeded in setting the element, it now
  207. // owns the reference, so we release our reference
  208. //
  209. if (SUCCEEDED(hr))
  210. {
  211. (void) xString.Acquire();
  212. }
  213. return hr;
  214. }
  215. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  216. //
  217. // Function: CVariant::SetNextByteArrayElement
  218. //
  219. // Purpose: Adds an element in an array of bytes to a byte array
  220. //
  221. // Params: byteValue -- the value to which to add as an element
  222. // cMaxElements (optional) -- the maximum number
  223. // of elements in this array -- must be specified
  224. // the first time this method is called on this object
  225. //
  226. // Return value: returns S_OK if successful, other
  227. // error code if not
  228. //
  229. // Notes:
  230. //
  231. //------------------------------------------------------------
  232. HRESULT CVariant::SetNextByteArrayElement(
  233. BYTE byteValue,
  234. DWORD cMaxElements)
  235. {
  236. HRESULT hr;
  237. //
  238. // Add the long to the correct index
  239. // in the array
  240. //
  241. hr = SetNextArrayElement(
  242. VT_UI1,
  243. cMaxElements,
  244. &byteValue);
  245. return hr;
  246. }
  247. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  248. //
  249. // Function: CVariant::IsStringValue
  250. //
  251. // Purpose: Determines whether this variant represents a string
  252. //
  253. // Params:
  254. //
  255. // Return value: returns TRUE if this is a string, FALSE if not
  256. //
  257. //------------------------------------------------------------
  258. BOOL CVariant::IsStringValue()
  259. {
  260. return VT_BSTR == _var.vt;
  261. }
  262. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  263. //
  264. // Function: CVariant::IsLongValue
  265. //
  266. // Purpose: Determines whether this variant represents a long
  267. //
  268. // Params:
  269. //
  270. // Return value: returns TRUE if this is a long, FALSE if not
  271. //
  272. //------------------------------------------------------------
  273. BOOL CVariant::IsLongValue()
  274. {
  275. return VT_I4 == _var.vt;
  276. }
  277. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  278. //
  279. // Function: CVariant::operator VARIANT*()
  280. //
  281. // Purpose: Casts this object into a VARIANT structure pointer
  282. //
  283. // Params:
  284. //
  285. // Return value: returns a pointer to a VARIANT structure
  286. //
  287. // Notes:
  288. //
  289. //------------------------------------------------------------
  290. CVariant::operator VARIANT*()
  291. {
  292. return &_var;
  293. }
  294. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  295. //
  296. // Function: CVariant::SetNextArrayElement
  297. //
  298. // Purpose: Adds an element to an array of objects of arbitrary
  299. // type
  300. //
  301. // Params: wszValue -- the value to which to set the element
  302. // cMaxElements (optional) -- the maximum number
  303. // of elements in this array -- must be specified
  304. // the first time this method is called on this object
  305. //
  306. // Return value: returns S_OK if successful, other
  307. // error code if not
  308. //
  309. // Notes:
  310. //
  311. //------------------------------------------------------------
  312. HRESULT CVariant::SetNextArrayElement(
  313. VARTYPE varType,
  314. DWORD cMaxElements,
  315. LPVOID pvData)
  316. {
  317. HRESULT hr;
  318. //
  319. // If this array contains no elements, return the hr
  320. // that lets the caller know that this array is full
  321. //
  322. if ( 0 == cMaxElements )
  323. {
  324. return S_FALSE;
  325. }
  326. //
  327. // The first time this method is called on this object,
  328. // we should allocate space for the array
  329. //
  330. if ( !_iCurrentArrayIndex )
  331. {
  332. ASSERT( cMaxElements );
  333. ASSERT( VT_EMPTY == _var.vt );
  334. //
  335. // Allocate space for the array with elements
  336. // of the caller specifed type and number
  337. //
  338. hr = InitializeArray(
  339. varType,
  340. cMaxElements);
  341. if (FAILED(hr))
  342. {
  343. return hr;
  344. }
  345. _cMaxArrayElements = cMaxElements;
  346. }
  347. ASSERT( ((DWORD) _iCurrentArrayIndex) < _cMaxArrayElements );
  348. //
  349. // Now add the polymorphic object's IUnknown
  350. // into the array
  351. //
  352. hr = SafeArrayPutElement(
  353. _var.parray,
  354. &_iCurrentArrayIndex,
  355. pvData);
  356. //
  357. // If we've filled up the array, return S_FALSE to
  358. // signal that no more elements can be added
  359. //
  360. if (SUCCEEDED(hr))
  361. {
  362. //
  363. // Increment our cursor into the array to the
  364. // next element
  365. //
  366. _iCurrentArrayIndex++;
  367. //
  368. // Check our current index -- if it's the same
  369. // as our maximum, we're full
  370. //
  371. if ( ((DWORD) _iCurrentArrayIndex) == _cMaxArrayElements)
  372. {
  373. hr = S_FALSE;
  374. }
  375. }
  376. return hr;
  377. }
  378. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  379. //
  380. // Function: CVariant::InitializeArray
  381. //
  382. // Purpose: Private method that allocates space for an array
  383. // of a specified size and element type
  384. //
  385. // Params: varType -- type of elements that will be in the array
  386. // cMaxElements -- the size, in elements, of the array
  387. //
  388. // Return value: returns ERROR_SUCCESS if successful, other
  389. // win32 error code if not
  390. //
  391. // Notes:
  392. //
  393. //------------------------------------------------------------
  394. HRESULT CVariant::InitializeArray(
  395. VARTYPE varType,
  396. DWORD cMaxElements)
  397. {
  398. SAFEARRAY* pSafeArray;
  399. SAFEARRAYBOUND arrayBound;
  400. //
  401. // Set the bounds of the array to be zero-based
  402. //
  403. arrayBound.lLbound = 0;
  404. arrayBound.cElements = cMaxElements;
  405. //
  406. // Allocate the array
  407. //
  408. pSafeArray = SafeArrayCreate(
  409. varType,
  410. 1, // 1 dimension
  411. &arrayBound);
  412. if (!pSafeArray)
  413. {
  414. return E_OUTOFMEMORY;
  415. }
  416. //
  417. // Set our state to refer to the allocated memory
  418. // with the specified type
  419. //
  420. _var.vt = VT_ARRAY | varType;
  421. _var.parray = pSafeArray;
  422. return S_OK;
  423. }