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.

331 lines
8.1 KiB

  1. /*++
  2. Copyright (C) 1995-2001 Microsoft Corporation
  3. Module Name:
  4. DATACONV.CPP
  5. Abstract:
  6. Provides a some generic data conversion routines. In particular,
  7. OMSVariantChangeType and OMSVariantClear provide the same
  8. capabilities as the Ole VariantChangeType and VariantClear
  9. functions except that the OMS versions handle more data types.
  10. History:
  11. a-davj 19-Oct-95 Created.
  12. --*/
  13. #include "precomp.h"
  14. #include "resource.h"
  15. #include "CVariant.h"
  16. #include <ole2.h>
  17. //***************************************************************************
  18. //
  19. // char * WideToNarrow
  20. //
  21. // DESCRIPTION:
  22. //
  23. // Takes a WCHAR string and creates a MBS equivalent. The caller should
  24. // free the string when done.
  25. //
  26. // PARAMETERS:
  27. //
  28. // pConv UNICODE string to convert.
  29. //
  30. // RETURN VALUE:
  31. //
  32. // NULL if out of memory, otherwise a mbs string that the caller should free
  33. // via CoTaskMemFree.
  34. //
  35. //***************************************************************************
  36. char * WideToNarrow(
  37. IN LPCWSTR pConv)
  38. {
  39. char * cpRet = NULL;
  40. int iMBSLen = wcstombs(NULL,pConv,0) + 1;
  41. if(iMBSLen == 0)
  42. return NULL;
  43. cpRet = (char *)CoTaskMemAlloc(iMBSLen);
  44. if(cpRet)
  45. {
  46. memset(cpRet, 0, iMBSLen);
  47. wcstombs(cpRet,pConv,iMBSLen);
  48. }
  49. return cpRet;
  50. }
  51. int gDiag;
  52. char * WideToNarrowA(
  53. IN LPCWSTR pConv)
  54. {
  55. char * cpRet = NULL;
  56. int iMBSLen = wcstombs(NULL,pConv,0) + 1;
  57. if(iMBSLen == 0)
  58. return NULL;
  59. cpRet = new char[iMBSLen];
  60. gDiag = iMBSLen;
  61. if(cpRet)
  62. {
  63. memset(cpRet, 0, iMBSLen);
  64. wcstombs(cpRet,pConv,iMBSLen);
  65. }
  66. return cpRet;
  67. }
  68. //***************************************************************************
  69. //
  70. // SAFEARRAY * OMSSafeArrayCreate
  71. //
  72. // DESCRIPTION:
  73. //
  74. // Creates a safe array.
  75. //
  76. // PARAMETERS:
  77. //
  78. // vt element type
  79. // iNumElements number of elements
  80. //
  81. // RETURN VALUE:
  82. //
  83. // Returns null if there is a problem.
  84. //
  85. //***************************************************************************
  86. SAFEARRAY * OMSSafeArrayCreate(
  87. IN VARTYPE vt,
  88. IN int iNumElements)
  89. {
  90. if(iTypeSize(vt) < 1 || iNumElements < 1)
  91. return NULL;
  92. SAFEARRAYBOUND rgsabound[1];
  93. rgsabound[0].lLbound = 0;
  94. rgsabound[0].cElements = iNumElements;
  95. return SafeArrayCreate(vt,1,rgsabound);
  96. }
  97. //***************************************************************************
  98. //
  99. // SCODE OMSVariantChangeType
  100. //
  101. // DESCRIPTION:
  102. //
  103. // Converts a variant from one type into another. This functions takes the
  104. // same arguments and does the same action as the standard
  105. // VariantChangeType except that it also handles arrays.
  106. //
  107. //
  108. // PARAMETERS:
  109. //
  110. // pDest points to the variant which is to be updated
  111. // pSrc points to the variant that is the source
  112. // wFlags flags which are passed on to VariantChangeType
  113. // vtDest Type that the pDest is conveted to
  114. //
  115. // RETURN VALUE:
  116. //
  117. // S_OK All is well.
  118. // WBEM_E_INVALID_PARAMETER Invalid argument
  119. // WBEM_E_OUT_OF_MEMORY Out of memory
  120. // otherwise various return codes from VariantChangeType, or safe array
  121. // manipulation
  122. //
  123. //***************************************************************************
  124. HRESULT OMSVariantChangeType(
  125. IN OUT VARIANTARG * pDest,
  126. IN VARIANTARG *pSrc,
  127. IN USHORT wFlags,
  128. IN VARTYPE vtDest)
  129. {
  130. SCODE sc;
  131. // Verify arguments and clear out the destination
  132. if(pDest == NULL || pSrc == NULL || iTypeSize(vtDest)<1 || iTypeSize(pSrc->vt)<1)
  133. return WBEM_E_INVALID_PARAMETER; // Junk args
  134. OMSVariantClear(pDest);
  135. // if both are arrays,
  136. if(vtDest & VT_ARRAY && pSrc->vt & VT_ARRAY) {
  137. // Set the VARTYPES without the VT_ARRAY bits
  138. VARTYPE vtDestSimple = vtDest & ~VT_ARRAY;
  139. VARTYPE vtSrcSimple = pSrc->vt &~ VT_ARRAY;
  140. // Determine the size of the source array. Also make sure that the array
  141. // only has one dimension
  142. unsigned int uDim = SafeArrayGetDim(pSrc->parray);
  143. if(uDim != 1)
  144. return WBEM_E_FAILED; // Bad array, or too many dimensions
  145. long ix[2] = {0,0};
  146. long lLower, lUpper;
  147. sc = SafeArrayGetLBound(pSrc->parray,1,&lLower);
  148. if(sc != S_OK)
  149. return sc;
  150. sc = SafeArrayGetUBound(pSrc->parray,1,&lUpper);
  151. if(sc != S_OK)
  152. return sc;
  153. int iNumElements = lUpper - lLower +1;
  154. // Create a destination array of equal size
  155. SAFEARRAY * pDestArray = OMSSafeArrayCreate(vtDestSimple,iNumElements);
  156. if(pDestArray == NULL)
  157. return WBEM_E_FAILED; // Most likely a bad type!
  158. // For each element in the source array
  159. for(ix[0] = lLower; ix[0] <= lUpper && sc == S_OK; ix[0]++) {
  160. CVariant varSrc, varDest;
  161. // Set Temp CVariant to the source data
  162. sc = SafeArrayGetElement(pSrc->parray,ix,varSrc.GetDataPtr());
  163. if(sc != S_OK)
  164. break;
  165. varSrc.SetType(vtSrcSimple);
  166. // Convert to destination data using VariantConvert
  167. sc = VariantChangeType(varDest.GetVarPtr(),varSrc.GetVarPtr(),wFlags,vtDestSimple);
  168. if(sc != S_OK)
  169. break;
  170. // Set destination data into the array
  171. if(vtDestSimple == VT_BSTR || vtDestSimple == VT_UNKNOWN ||
  172. vtDestSimple == VT_DISPATCH)
  173. sc = SafeArrayPutElement(pDestArray,ix,(void *)varDest.GetBstr());
  174. else
  175. sc = SafeArrayPutElement(pDestArray,ix,(void *)varDest.GetDataPtr());
  176. }
  177. if(sc != S_OK){
  178. SafeArrayDestroy(pDestArray);
  179. }
  180. else {
  181. // set the VARTYPE of the destination
  182. pDest->vt = vtDest;
  183. pDest->parray = pDestArray;
  184. }
  185. return sc;
  186. }
  187. // if one, but not the other is an array, bail out
  188. if(vtDest & VT_ARRAY || pSrc->vt & VT_ARRAY)
  189. return WBEM_E_FAILED;
  190. // Attempt to use standard conversion
  191. return VariantChangeType(pDest,pSrc,wFlags,vtDest);
  192. }
  193. //***************************************************************************
  194. //
  195. // OMSVariantClear
  196. //
  197. // DESCRIPTION:
  198. //
  199. // Does the same as the Ole VariantClear function except
  200. // that it also sets the data to all 0.
  201. //
  202. // PARAMETERS:
  203. //
  204. // pClear Variant to be cleared.
  205. //
  206. // RETURN VALUE:
  207. //
  208. // Result from VariantClear, most always S_OK
  209. //
  210. //***************************************************************************
  211. HRESULT OMSVariantClear(
  212. IN OUT VARIANTARG * pClear)
  213. {
  214. HRESULT sc;
  215. sc = VariantClear(pClear);
  216. memset((void *)&pClear->lVal,0,8);
  217. return sc;
  218. }
  219. //***************************************************************************
  220. //
  221. // int ITypeSize
  222. //
  223. // DESCRIPTION:
  224. //
  225. // Gets the number of bytes acutally used to store
  226. // a variant type. 0 if the type is unknown
  227. //
  228. // PARAMETERS:
  229. //
  230. // vtTest Type in question.
  231. //
  232. //
  233. // RETURN VALUE:
  234. //
  235. // see description
  236. //
  237. //***************************************************************************
  238. int iTypeSize(
  239. IN VARTYPE vtTest)
  240. {
  241. int iRet;
  242. vtTest &= ~ VT_ARRAY; // get rid of possible array bit
  243. switch (vtTest) {
  244. case VT_UI1:
  245. case VT_LPSTR:
  246. iRet = 1;
  247. break;
  248. case VT_LPWSTR:
  249. case VT_BSTR:
  250. case VT_I2:
  251. iRet = 2;
  252. break;
  253. case VT_I4:
  254. case VT_R4:
  255. iRet = 4;
  256. break;
  257. case VT_R8:
  258. iRet = 8;
  259. break;
  260. case VT_BOOL:
  261. iRet = sizeof(VARIANT_BOOL);
  262. break;
  263. case VT_ERROR:
  264. iRet = sizeof(SCODE);
  265. break;
  266. case VT_CY:
  267. iRet = sizeof(CY);
  268. break;
  269. case VT_DATE:
  270. iRet = sizeof(DATE);
  271. break;
  272. case CIM_SINT64:
  273. case CIM_UINT64:
  274. iRet = 8;
  275. break;
  276. default:
  277. iRet = 0;
  278. }
  279. return iRet;
  280. }