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.

591 lines
14 KiB

  1. #include "precomp.h"
  2. #include <olectl.h>
  3. #include <wbemidl.h>
  4. #include <wbemint.h>
  5. #include "wmiconv.h"
  6. #include "maindll.h"
  7. /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  8. * Conversion to Text to Wbem Object has been cut from the WHistler Feature List and hence commented out
  9. *!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  10. HRESULT CXml2Wmi::AddQualifier (
  11. IXMLDOMNode *pNode, // A <QUALIFIER> element
  12. IWbemQualifierSet *pQualSet,
  13. bool bIsObjectQualifier // Indicates whether this is for an object or for a property
  14. )
  15. {
  16. HRESULT hr = S_OK;
  17. BSTR strName = NULL;
  18. BSTR strType = NULL;
  19. BSTR strOverridable = NULL;
  20. BSTR strToSubclass = NULL;
  21. BSTR strToInstance = NULL;
  22. BSTR strAmended = NULL;
  23. // Get the Name of the Qualifier - this is a mandatory attribute
  24. if(SUCCEEDED(hr))
  25. hr = GetBstrAttribute (pNode, g_strName, &strName);
  26. // Dont map the CIMTYPE QUalifier
  27. // Dont map the "abstract" qualifiers for objects, but map them for properties (for whatever reason)
  28. if(SUCCEEDED(hr) && _wcsicmp(strName, L"CIMTYPE") == 0 ||
  29. (bIsObjectQualifier && _wcsicmp(strName, L"abstract") == 0))
  30. {
  31. SysFreeString(strName);
  32. return S_OK;
  33. }
  34. // Get a few more attributes - some of these are optional
  35. // In such cases, we dont check the return value
  36. if(SUCCEEDED(hr))
  37. hr = GetBstrAttribute (pNode, g_strType, &strType);
  38. if(SUCCEEDED(hr))
  39. GetBstrAttribute (pNode, g_strOverridable, &strOverridable);
  40. if(SUCCEEDED(hr))
  41. GetBstrAttribute (pNode, g_strToSubClass, &strToSubclass);
  42. if(SUCCEEDED(hr))
  43. GetBstrAttribute (pNode, g_strToInstance, &strToInstance);
  44. if(SUCCEEDED(hr))
  45. GetBstrAttribute (pNode, g_strAmended, &strAmended);
  46. // Build up the flavor of the Qualifier
  47. //======================================================
  48. long flavor = 0;
  49. if(SUCCEEDED(hr))
  50. {
  51. if (!strOverridable || (0 == _wcsicmp (strOverridable, L"true")))
  52. flavor |= WBEM_FLAVOR_OVERRIDABLE;
  53. else if (0 == _wcsicmp (strOverridable, L"false"))
  54. flavor |= WBEM_FLAVOR_NOT_OVERRIDABLE;
  55. else
  56. hr = WBEM_E_FAILED;
  57. }
  58. if (SUCCEEDED(hr))
  59. {
  60. if (!strToSubclass || (0 == _wcsicmp (strToSubclass, L"true")))
  61. flavor |= WBEM_FLAVOR_FLAG_PROPAGATE_TO_DERIVED_CLASS;
  62. else if (0 != _wcsicmp (strToSubclass, L"false"))
  63. hr = WBEM_E_FAILED;
  64. }
  65. if (SUCCEEDED(hr))
  66. {
  67. if (strToInstance && (0 == _wcsicmp (strToInstance, L"true")))
  68. flavor |= WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE;
  69. else if (strToInstance && (0 != _wcsicmp (strToInstance, L"false")))
  70. hr = WBEM_E_FAILED;
  71. }
  72. if (SUCCEEDED(hr))
  73. {
  74. if (strAmended && (0 == _wcsicmp (strAmended, L"true")))
  75. flavor |= WBEM_FLAVOR_AMENDED;
  76. else if (strAmended && (0 != _wcsicmp (strAmended, L"false")))
  77. hr = WBEM_E_FAILED;
  78. }
  79. // Map the Qualifier type
  80. CIMTYPE cimtype = CIM_ILLEGAL;
  81. if (CIM_ILLEGAL == (cimtype = CimtypeFromString (strType)))
  82. hr = WBEM_E_FAILED;
  83. // Map the Qualifier value
  84. //============================
  85. VARIANT value;
  86. VariantInit (&value);
  87. if (SUCCEEDED (hr))
  88. {
  89. IXMLDOMNodeList *pNodeList = NULL;
  90. long length = 0;
  91. if (SUCCEEDED(hr = pNode->get_childNodes (&pNodeList)))
  92. {
  93. if (SUCCEEDED(hr = pNodeList->get_length (&length)) && (1 == length))
  94. {
  95. // Get the first node
  96. IXMLDOMNode *pValueNode = NULL;
  97. if (SUCCEEDED(hr = pNodeList->nextNode (&pValueNode)) && pValueNode)
  98. {
  99. // Get its name
  100. BSTR strNodeName = NULL;
  101. if(SUCCEEDED(hr = pValueNode->get_nodeName(&strNodeName)))
  102. {
  103. if (0 == _wcsicmp(strNodeName, VALUE_TAG))
  104. {
  105. BSTR bsValue = NULL;
  106. if(SUCCEEDED(hr = pValueNode->get_text(&bsValue)))
  107. {
  108. hr = MapStringQualiferValue (bsValue, value, cimtype);
  109. SysFreeString (bsValue);
  110. }
  111. }
  112. else if (0 == _wcsicmp(strNodeName, VALUEARRAY_TAG))
  113. {
  114. hr = MapStringArrayQualiferValue (pValueNode, value, cimtype);
  115. }
  116. SysFreeString (strNodeName);
  117. }
  118. pValueNode->Release ();
  119. pValueNode = NULL;
  120. }
  121. }
  122. pNodeList->Release ();
  123. }
  124. }
  125. // Put it all together
  126. if (SUCCEEDED (hr))
  127. hr = pQualSet->Put (strName, &value, flavor);
  128. SysFreeString (strName);
  129. SysFreeString (strType);
  130. SysFreeString (strOverridable);
  131. SysFreeString (strToSubclass);
  132. SysFreeString (strToInstance);
  133. SysFreeString (strAmended);
  134. VariantClear (&value);
  135. return hr;
  136. }
  137. //***************************************************************************
  138. //
  139. // HRESULT CXml2Wmi::MapStringValue
  140. //
  141. // DESCRIPTION:
  142. //
  143. // Maps XML VALUE element content into its WMI VARIANT equivalent form
  144. //
  145. // PARAMETERS:
  146. //
  147. // bsValue the VALUE element content
  148. // curValue Placeholder for new value (set on return)
  149. // cimtype for mapping purposes
  150. //
  151. // RETURN VALUES:
  152. //
  153. //
  154. //***************************************************************************
  155. HRESULT CXml2Wmi::MapStringQualiferValue (BSTR bsValue, VARIANT &curValue, CIMTYPE cimtype)
  156. {
  157. HRESULT hr = WBEM_E_TYPE_MISMATCH;
  158. VariantInit (&curValue);
  159. // We're assuming it's not an array
  160. if (!(cimtype & CIM_FLAG_ARRAY))
  161. {
  162. switch (cimtype)
  163. {
  164. // RAJESHR - more rigorous syntax checking
  165. case CIM_UINT8:
  166. {
  167. curValue.vt = VT_UI1;
  168. curValue.bVal = (BYTE) wcstol (bsValue, NULL, 0);
  169. hr = S_OK;
  170. }
  171. break;
  172. case CIM_SINT8:
  173. case CIM_SINT16:
  174. {
  175. curValue.vt = VT_I2;
  176. curValue.iVal = (short) wcstol (bsValue, NULL, 0);
  177. hr = S_OK;
  178. }
  179. break;
  180. case CIM_UINT16:
  181. case CIM_UINT32:
  182. case CIM_SINT32:
  183. {
  184. curValue.vt = VT_I4;
  185. curValue.lVal = wcstol (bsValue, NULL, 0);
  186. hr = S_OK;
  187. }
  188. break;
  189. case CIM_REAL32:
  190. {
  191. curValue.vt = VT_R4;
  192. curValue.fltVal = (float) wcstod (bsValue, NULL);
  193. hr = S_OK;
  194. }
  195. break;
  196. case CIM_REAL64:
  197. {
  198. curValue.vt = VT_R8;
  199. curValue.dblVal = wcstod (bsValue, NULL);
  200. hr = S_OK;
  201. }
  202. break;
  203. case CIM_BOOLEAN:
  204. {
  205. curValue.vt = VT_BOOL;
  206. curValue.boolVal = (0 == _wcsicmp (bsValue, L"TRUE")) ?
  207. VARIANT_TRUE : VARIANT_FALSE;
  208. hr = S_OK;
  209. }
  210. break;
  211. case CIM_CHAR16:
  212. {
  213. // As per the XML Spec, the following are invalid character values in an XML Stream:
  214. // Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
  215. // As per the CIM Operations spec, they need to be escaped as follows:
  216. // If the value is not a legal XML character
  217. // (as defined in [2, section 2.2] by the Char production)
  218. // then it MUST be escaped using a \x<hex> escape convention
  219. // where <hex> is a hexadecimal constant consisting of
  220. // between one and four digits
  221. curValue.vt = VT_I2;
  222. if(_wcsnicmp(bsValue, L"\\x", 2) == 0)
  223. // It is an escaped value
  224. swscanf (bsValue+2, L"%x", &(curValue.iVal));
  225. else
  226. // It is a normal value
  227. swscanf (bsValue, L"%c", &(curValue.iVal));
  228. hr = S_OK;
  229. }
  230. break;
  231. case CIM_STRING:
  232. case CIM_UINT64:
  233. case CIM_SINT64:
  234. case CIM_DATETIME:
  235. {
  236. curValue.vt = VT_BSTR;
  237. curValue.bstrVal = SysAllocString (bsValue);
  238. hr = S_OK;
  239. }
  240. break;
  241. }
  242. }
  243. return hr;
  244. }
  245. //***************************************************************************
  246. //
  247. // HRESULT CXml2Wmi::MapStringArrayValue
  248. //
  249. // DESCRIPTION:
  250. //
  251. // Maps XML VALUE.ARRAY element content into its WMI VARIANT equivalent form
  252. //
  253. // PARAMETERS:
  254. //
  255. // pValueNode the VALUE.ARRAY node
  256. // curValue Placeholder for new value (set on return)
  257. // cimtype for mapping purposes
  258. //
  259. // RETURN VALUES:
  260. //
  261. //
  262. //***************************************************************************
  263. HRESULT CXml2Wmi::MapStringArrayQualiferValue (
  264. IXMLDOMNode *pValueNode,
  265. VARIANT &curValue,
  266. CIMTYPE cimtype
  267. )
  268. {
  269. HRESULT hr = WBEM_E_TYPE_MISMATCH;
  270. // Build a safearray value from the node list
  271. IXMLDOMNodeList *pValueList = NULL;
  272. if (SUCCEEDED (pValueNode->get_childNodes (&pValueList)))
  273. {
  274. long length = 0;
  275. pValueList->get_length (&length);
  276. SAFEARRAYBOUND rgsabound [1];
  277. rgsabound [0].lLbound = 0;
  278. rgsabound [0].cElements = length;
  279. VARTYPE vt = VTFromCIMType (cimtype & ~CIM_FLAG_ARRAY);
  280. SAFEARRAY *pArray = NULL;
  281. if( pArray = SafeArrayCreate (vt, 1, rgsabound))
  282. {
  283. IXMLDOMNode *pValue = NULL;
  284. long ix = 0;
  285. bool error = false;
  286. while (!error && SUCCEEDED(pValueList->nextNode(&pValue)) && pValue)
  287. {
  288. // Check whether this is a VALUE element
  289. BSTR strValName = NULL;
  290. if (SUCCEEDED(pValue->get_nodeName (&strValName)))
  291. {
  292. if (0 == _wcsicmp (strValName, VALUE_TAG))
  293. {
  294. BSTR bsValue = NULL;
  295. pValue->get_text (&bsValue);
  296. if(FAILED(MapStringQualiferValueIntoArray (bsValue, pArray, &ix, vt,
  297. cimtype & ~CIM_FLAG_ARRAY)))
  298. error = true;
  299. SysFreeString (bsValue);
  300. ix++;
  301. }
  302. else
  303. error = true;
  304. SysFreeString (strValName);
  305. }
  306. else
  307. error = true;
  308. pValue->Release ();
  309. pValue = NULL;
  310. }
  311. if(error)
  312. SafeArrayDestroy(pArray);
  313. else
  314. {
  315. curValue.vt = VT_ARRAY|vt;
  316. curValue.parray = pArray;
  317. hr = S_OK;
  318. }
  319. }
  320. else
  321. hr = E_OUTOFMEMORY;
  322. pValueList->Release();
  323. }
  324. return hr;
  325. }
  326. //***************************************************************************
  327. //
  328. // HRESULT CXml2Wmi::MapStringValueIntoArray
  329. //
  330. // DESCRIPTION:
  331. //
  332. // Maps XML VALUE.ARRAY/VALUE element content into its WMI VARIANT equivalent form
  333. //
  334. // PARAMETERS:
  335. //
  336. // bsValue the VALUE element content
  337. // pArray SAFEARRAY in which to map the value
  338. // ix index to map the value into
  339. // vt VARTYPE of the SAFEARRAY
  340. // cimtype for mapping purposes
  341. //
  342. // RETURN VALUES:
  343. //
  344. //
  345. //***************************************************************************
  346. HRESULT CXml2Wmi::MapStringQualiferValueIntoArray (
  347. BSTR bsValue,
  348. SAFEARRAY *pArray,
  349. long *ix,
  350. VARTYPE vt,
  351. CIMTYPE cimtype)
  352. {
  353. HRESULT hr = E_FAIL;
  354. switch (vt)
  355. {
  356. case VT_UI1:
  357. {
  358. BYTE bVal = (BYTE) wcstol (bsValue, NULL, 0);
  359. hr = SafeArrayPutElement (pArray, ix, &bVal);
  360. }
  361. break;
  362. case VT_I2:
  363. {
  364. short iVal;
  365. if (CIM_CHAR16 == cimtype)
  366. swscanf (bsValue, L"%c", &(iVal));
  367. else
  368. iVal = (short) wcstol (bsValue, NULL, 0);
  369. hr = SafeArrayPutElement (pArray, ix, &iVal);
  370. }
  371. break;
  372. case VT_I4:
  373. {
  374. long lVal = wcstol (bsValue, NULL, 0);
  375. hr = SafeArrayPutElement (pArray, ix, &lVal);
  376. }
  377. break;
  378. case VT_R4:
  379. {
  380. float fltVal = (float) wcstod (bsValue, NULL);
  381. hr = SafeArrayPutElement (pArray, ix, &fltVal);
  382. }
  383. break;
  384. case VT_R8:
  385. {
  386. double dblVal = wcstod (bsValue, NULL);
  387. hr = SafeArrayPutElement (pArray, ix, &dblVal);
  388. }
  389. break;
  390. case VT_BOOL:
  391. {
  392. VARIANT_BOOL boolVal = (0 == _wcsicmp (bsValue, L"TRUE")) ?
  393. VARIANT_TRUE : VARIANT_FALSE;
  394. hr = SafeArrayPutElement (pArray, ix, &boolVal);
  395. }
  396. break;
  397. case VT_BSTR:
  398. // No need to SysAllocString() since SafeArrayPutElement() does this automatically
  399. hr = SafeArrayPutElement (pArray, ix, bsValue);
  400. break;
  401. }
  402. return hr;
  403. }
  404. //***************************************************************************
  405. //
  406. // HRESULT CXml2Wmi::VTFromCIMType
  407. //
  408. // DESCRIPTION:
  409. //
  410. // Utility function to map CIMTYPE to its VARTYPE equivalent
  411. //
  412. // PARAMETERS:
  413. //
  414. // cimtype the CIMTYPE to be mapped
  415. //
  416. // RETURN VALUES:
  417. //
  418. // The corresponding VARTYPE, or VT_NULL if error
  419. //
  420. //***************************************************************************
  421. VARTYPE CXml2Wmi::VTFromCIMType (CIMTYPE cimtype)
  422. {
  423. VARTYPE vt = VT_NULL;
  424. switch (cimtype & ~CIM_FLAG_ARRAY)
  425. {
  426. case CIM_UINT8:
  427. vt = VT_UI1;
  428. break;
  429. case CIM_SINT8:
  430. case CIM_SINT16:
  431. vt = VT_I2;
  432. break;
  433. case CIM_UINT16:
  434. case CIM_UINT32:
  435. case CIM_SINT32:
  436. vt = VT_I4;
  437. break;
  438. case CIM_REAL32:
  439. vt = VT_R4;
  440. break;
  441. case CIM_REAL64:
  442. vt = VT_R8;
  443. break;
  444. case CIM_BOOLEAN:
  445. vt = VT_BOOL;
  446. break;
  447. case CIM_CHAR16:
  448. vt = VT_I2;
  449. break;
  450. case CIM_STRING:
  451. case CIM_UINT64:
  452. case CIM_SINT64:
  453. case CIM_DATETIME:
  454. vt = VT_BSTR;
  455. break;
  456. }
  457. return vt;
  458. }
  459. //***************************************************************************
  460. //
  461. // HRESULT CXmlToWmi::CIMTypeFromString
  462. //
  463. // DESCRIPTION:
  464. //
  465. // Utility function to map type attribute string to its CIMTYPE equivalent
  466. //
  467. // PARAMETERS:
  468. //
  469. // bsType the type string to be mapped
  470. //
  471. // RETURN VALUES:
  472. //
  473. // The corresponding CIMTYPE, or CIM_ILLEGAL if error
  474. //
  475. //***************************************************************************
  476. CIMTYPE CXml2Wmi::CimtypeFromString (BSTR bsType)
  477. {
  478. CIMTYPE cimtype = CIM_ILLEGAL;
  479. if (bsType)
  480. {
  481. if (0 == _wcsicmp (bsType, L"string"))
  482. cimtype = CIM_STRING;
  483. else if (0 == _wcsicmp (bsType, L"uint32"))
  484. cimtype = CIM_UINT32;
  485. else if (0 == _wcsicmp (bsType, L"boolean"))
  486. cimtype = CIM_BOOLEAN;
  487. else if (0 == _wcsicmp (bsType, L"sint32"))
  488. cimtype = CIM_SINT32;
  489. else if (0 == _wcsicmp (bsType, L"char16"))
  490. cimtype = CIM_CHAR16;
  491. else if (0 == _wcsicmp (bsType, L"uint8"))
  492. cimtype = CIM_UINT8;
  493. else if (0 == _wcsicmp (bsType, L"uint16"))
  494. cimtype = CIM_UINT16;
  495. else if (0 == _wcsicmp (bsType, L"sint16"))
  496. cimtype = CIM_SINT16;
  497. else if (0 == _wcsicmp (bsType, L"uint64"))
  498. cimtype = CIM_UINT64;
  499. else if (0 == _wcsicmp (bsType, L"sint64"))
  500. cimtype = CIM_SINT64;
  501. else if (0 == _wcsicmp (bsType, L"datetime"))
  502. cimtype = CIM_DATETIME;
  503. else if (0 == _wcsicmp (bsType, L"real32"))
  504. cimtype = CIM_REAL32;
  505. else if (0 == _wcsicmp (bsType, L"real64"))
  506. cimtype = CIM_REAL64;
  507. }
  508. return cimtype;
  509. }
  510. HRESULT CXml2Wmi::MakeObjectAbstract(IWbemClassObject *pObj, IXMLDOMNode *pAbstractQualifierNode)
  511. {
  512. HRESULT hr = E_FAIL;
  513. // Get the object qualifeir set
  514. IWbemQualifierSet *pQuals = NULL;
  515. if(SUCCEEDED(hr = pObj->GetQualifierSet(&pQuals)))
  516. {
  517. // Add the "abstract" qualiifer
  518. hr = AddQualifier(pAbstractQualifierNode, pQuals);
  519. pQuals->Release();
  520. }
  521. return hr;
  522. }
  523. */