|
|
#include "precomp.h"
#include <olectl.h>
#include <wbemidl.h>
#include <wbemint.h>
#include "wmiconv.h"
#include "maindll.h"
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* Conversion to Text to Wbem Object has been cut from the WHistler Feature List and hence commented out *!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
HRESULT CXml2Wmi::AddQualifier ( IXMLDOMNode *pNode, // A <QUALIFIER> element
IWbemQualifierSet *pQualSet, bool bIsObjectQualifier // Indicates whether this is for an object or for a property
) { HRESULT hr = S_OK;
BSTR strName = NULL; BSTR strType = NULL; BSTR strOverridable = NULL; BSTR strToSubclass = NULL; BSTR strToInstance = NULL; BSTR strAmended = NULL;
// Get the Name of the Qualifier - this is a mandatory attribute
if(SUCCEEDED(hr)) hr = GetBstrAttribute (pNode, g_strName, &strName);
// Dont map the CIMTYPE QUalifier
// Dont map the "abstract" qualifiers for objects, but map them for properties (for whatever reason)
if(SUCCEEDED(hr) && _wcsicmp(strName, L"CIMTYPE") == 0 || (bIsObjectQualifier && _wcsicmp(strName, L"abstract") == 0)) { SysFreeString(strName); return S_OK; }
// Get a few more attributes - some of these are optional
// In such cases, we dont check the return value
if(SUCCEEDED(hr)) hr = GetBstrAttribute (pNode, g_strType, &strType); if(SUCCEEDED(hr)) GetBstrAttribute (pNode, g_strOverridable, &strOverridable); if(SUCCEEDED(hr)) GetBstrAttribute (pNode, g_strToSubClass, &strToSubclass); if(SUCCEEDED(hr)) GetBstrAttribute (pNode, g_strToInstance, &strToInstance); if(SUCCEEDED(hr)) GetBstrAttribute (pNode, g_strAmended, &strAmended);
// Build up the flavor of the Qualifier
//======================================================
long flavor = 0; if(SUCCEEDED(hr)) { if (!strOverridable || (0 == _wcsicmp (strOverridable, L"true"))) flavor |= WBEM_FLAVOR_OVERRIDABLE; else if (0 == _wcsicmp (strOverridable, L"false")) flavor |= WBEM_FLAVOR_NOT_OVERRIDABLE; else hr = WBEM_E_FAILED; } if (SUCCEEDED(hr)) { if (!strToSubclass || (0 == _wcsicmp (strToSubclass, L"true"))) flavor |= WBEM_FLAVOR_FLAG_PROPAGATE_TO_DERIVED_CLASS; else if (0 != _wcsicmp (strToSubclass, L"false")) hr = WBEM_E_FAILED; } if (SUCCEEDED(hr)) { if (strToInstance && (0 == _wcsicmp (strToInstance, L"true"))) flavor |= WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE; else if (strToInstance && (0 != _wcsicmp (strToInstance, L"false"))) hr = WBEM_E_FAILED; } if (SUCCEEDED(hr)) { if (strAmended && (0 == _wcsicmp (strAmended, L"true"))) flavor |= WBEM_FLAVOR_AMENDED; else if (strAmended && (0 != _wcsicmp (strAmended, L"false"))) hr = WBEM_E_FAILED; }
// Map the Qualifier type
CIMTYPE cimtype = CIM_ILLEGAL; if (CIM_ILLEGAL == (cimtype = CimtypeFromString (strType))) hr = WBEM_E_FAILED;
// Map the Qualifier value
//============================
VARIANT value; VariantInit (&value); if (SUCCEEDED (hr)) { IXMLDOMNodeList *pNodeList = NULL; long length = 0; if (SUCCEEDED(hr = pNode->get_childNodes (&pNodeList))) { if (SUCCEEDED(hr = pNodeList->get_length (&length)) && (1 == length)) { // Get the first node
IXMLDOMNode *pValueNode = NULL; if (SUCCEEDED(hr = pNodeList->nextNode (&pValueNode)) && pValueNode) { // Get its name
BSTR strNodeName = NULL; if(SUCCEEDED(hr = pValueNode->get_nodeName(&strNodeName))) { if (0 == _wcsicmp(strNodeName, VALUE_TAG)) { BSTR bsValue = NULL; if(SUCCEEDED(hr = pValueNode->get_text(&bsValue))) { hr = MapStringQualiferValue (bsValue, value, cimtype); SysFreeString (bsValue); } } else if (0 == _wcsicmp(strNodeName, VALUEARRAY_TAG)) { hr = MapStringArrayQualiferValue (pValueNode, value, cimtype); }
SysFreeString (strNodeName); } pValueNode->Release (); pValueNode = NULL; } }
pNodeList->Release (); } }
// Put it all together
if (SUCCEEDED (hr)) hr = pQualSet->Put (strName, &value, flavor);
SysFreeString (strName); SysFreeString (strType); SysFreeString (strOverridable); SysFreeString (strToSubclass); SysFreeString (strToInstance); SysFreeString (strAmended);
VariantClear (&value);
return hr; }
//***************************************************************************
//
// HRESULT CXml2Wmi::MapStringValue
//
// DESCRIPTION:
//
// Maps XML VALUE element content into its WMI VARIANT equivalent form
//
// PARAMETERS:
//
// bsValue the VALUE element content
// curValue Placeholder for new value (set on return)
// cimtype for mapping purposes
//
// RETURN VALUES:
//
//
//***************************************************************************
HRESULT CXml2Wmi::MapStringQualiferValue (BSTR bsValue, VARIANT &curValue, CIMTYPE cimtype) { HRESULT hr = WBEM_E_TYPE_MISMATCH; VariantInit (&curValue);
// We're assuming it's not an array
if (!(cimtype & CIM_FLAG_ARRAY)) { switch (cimtype) { // RAJESHR - more rigorous syntax checking
case CIM_UINT8: { curValue.vt = VT_UI1; curValue.bVal = (BYTE) wcstol (bsValue, NULL, 0); hr = S_OK; } break;
case CIM_SINT8: case CIM_SINT16: { curValue.vt = VT_I2; curValue.iVal = (short) wcstol (bsValue, NULL, 0); hr = S_OK; } break;
case CIM_UINT16: case CIM_UINT32: case CIM_SINT32: { curValue.vt = VT_I4; curValue.lVal = wcstol (bsValue, NULL, 0); hr = S_OK; } break;
case CIM_REAL32: { curValue.vt = VT_R4; curValue.fltVal = (float) wcstod (bsValue, NULL); hr = S_OK; } break;
case CIM_REAL64: { curValue.vt = VT_R8; curValue.dblVal = wcstod (bsValue, NULL); hr = S_OK; } break;
case CIM_BOOLEAN: { curValue.vt = VT_BOOL; curValue.boolVal = (0 == _wcsicmp (bsValue, L"TRUE")) ? VARIANT_TRUE : VARIANT_FALSE; hr = S_OK; } break;
case CIM_CHAR16: { // As per the XML Spec, the following are invalid character values in an XML Stream:
// Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
// As per the CIM Operations spec, they need to be escaped as follows:
// If the value is not a legal XML character
// (as defined in [2, section 2.2] by the Char production)
// then it MUST be escaped using a \x<hex> escape convention
// where <hex> is a hexadecimal constant consisting of
// between one and four digits
curValue.vt = VT_I2; if(_wcsnicmp(bsValue, L"\\x", 2) == 0) // It is an escaped value
swscanf (bsValue+2, L"%x", &(curValue.iVal)); else // It is a normal value
swscanf (bsValue, L"%c", &(curValue.iVal)); hr = S_OK; } break;
case CIM_STRING: case CIM_UINT64: case CIM_SINT64: case CIM_DATETIME: { curValue.vt = VT_BSTR; curValue.bstrVal = SysAllocString (bsValue); hr = S_OK; } break; } }
return hr; }
//***************************************************************************
//
// HRESULT CXml2Wmi::MapStringArrayValue
//
// DESCRIPTION:
//
// Maps XML VALUE.ARRAY element content into its WMI VARIANT equivalent form
//
// PARAMETERS:
//
// pValueNode the VALUE.ARRAY node
// curValue Placeholder for new value (set on return)
// cimtype for mapping purposes
//
// RETURN VALUES:
//
//
//***************************************************************************
HRESULT CXml2Wmi::MapStringArrayQualiferValue ( IXMLDOMNode *pValueNode, VARIANT &curValue, CIMTYPE cimtype ) { HRESULT hr = WBEM_E_TYPE_MISMATCH;
// Build a safearray value from the node list
IXMLDOMNodeList *pValueList = NULL;
if (SUCCEEDED (pValueNode->get_childNodes (&pValueList))) { long length = 0; pValueList->get_length (&length); SAFEARRAYBOUND rgsabound [1]; rgsabound [0].lLbound = 0; rgsabound [0].cElements = length; VARTYPE vt = VTFromCIMType (cimtype & ~CIM_FLAG_ARRAY); SAFEARRAY *pArray = NULL; if( pArray = SafeArrayCreate (vt, 1, rgsabound)) { IXMLDOMNode *pValue = NULL; long ix = 0; bool error = false; while (!error && SUCCEEDED(pValueList->nextNode(&pValue)) && pValue) { // Check whether this is a VALUE element
BSTR strValName = NULL; if (SUCCEEDED(pValue->get_nodeName (&strValName))) { if (0 == _wcsicmp (strValName, VALUE_TAG)) { BSTR bsValue = NULL; pValue->get_text (&bsValue); if(FAILED(MapStringQualiferValueIntoArray (bsValue, pArray, &ix, vt, cimtype & ~CIM_FLAG_ARRAY))) error = true;
SysFreeString (bsValue); ix++; } else error = true;
SysFreeString (strValName); } else error = true;
pValue->Release (); pValue = NULL; }
if(error) SafeArrayDestroy(pArray); else { curValue.vt = VT_ARRAY|vt; curValue.parray = pArray; hr = S_OK; } } else hr = E_OUTOFMEMORY;
pValueList->Release(); } return hr; }
//***************************************************************************
//
// HRESULT CXml2Wmi::MapStringValueIntoArray
//
// DESCRIPTION:
//
// Maps XML VALUE.ARRAY/VALUE element content into its WMI VARIANT equivalent form
//
// PARAMETERS:
//
// bsValue the VALUE element content
// pArray SAFEARRAY in which to map the value
// ix index to map the value into
// vt VARTYPE of the SAFEARRAY
// cimtype for mapping purposes
//
// RETURN VALUES:
//
//
//***************************************************************************
HRESULT CXml2Wmi::MapStringQualiferValueIntoArray ( BSTR bsValue, SAFEARRAY *pArray, long *ix, VARTYPE vt, CIMTYPE cimtype) { HRESULT hr = E_FAIL; switch (vt) { case VT_UI1: { BYTE bVal = (BYTE) wcstol (bsValue, NULL, 0); hr = SafeArrayPutElement (pArray, ix, &bVal); } break;
case VT_I2: { short iVal;
if (CIM_CHAR16 == cimtype) swscanf (bsValue, L"%c", &(iVal)); else iVal = (short) wcstol (bsValue, NULL, 0);
hr = SafeArrayPutElement (pArray, ix, &iVal); } break;
case VT_I4: { long lVal = wcstol (bsValue, NULL, 0); hr = SafeArrayPutElement (pArray, ix, &lVal); } break;
case VT_R4: { float fltVal = (float) wcstod (bsValue, NULL); hr = SafeArrayPutElement (pArray, ix, &fltVal); } break;
case VT_R8: { double dblVal = wcstod (bsValue, NULL); hr = SafeArrayPutElement (pArray, ix, &dblVal); } break;
case VT_BOOL: { VARIANT_BOOL boolVal = (0 == _wcsicmp (bsValue, L"TRUE")) ? VARIANT_TRUE : VARIANT_FALSE; hr = SafeArrayPutElement (pArray, ix, &boolVal); } break;
case VT_BSTR: // No need to SysAllocString() since SafeArrayPutElement() does this automatically
hr = SafeArrayPutElement (pArray, ix, bsValue); break; } return hr; }
//***************************************************************************
//
// HRESULT CXml2Wmi::VTFromCIMType
//
// DESCRIPTION:
//
// Utility function to map CIMTYPE to its VARTYPE equivalent
//
// PARAMETERS:
//
// cimtype the CIMTYPE to be mapped
//
// RETURN VALUES:
//
// The corresponding VARTYPE, or VT_NULL if error
//
//***************************************************************************
VARTYPE CXml2Wmi::VTFromCIMType (CIMTYPE cimtype) { VARTYPE vt = VT_NULL;
switch (cimtype & ~CIM_FLAG_ARRAY) { case CIM_UINT8: vt = VT_UI1; break;
case CIM_SINT8: case CIM_SINT16: vt = VT_I2; break;
case CIM_UINT16: case CIM_UINT32: case CIM_SINT32: vt = VT_I4; break;
case CIM_REAL32: vt = VT_R4; break;
case CIM_REAL64: vt = VT_R8; break;
case CIM_BOOLEAN: vt = VT_BOOL; break;
case CIM_CHAR16: vt = VT_I2; break;
case CIM_STRING: case CIM_UINT64: case CIM_SINT64: case CIM_DATETIME: vt = VT_BSTR; break; }
return vt; }
//***************************************************************************
//
// HRESULT CXmlToWmi::CIMTypeFromString
//
// DESCRIPTION:
//
// Utility function to map type attribute string to its CIMTYPE equivalent
//
// PARAMETERS:
//
// bsType the type string to be mapped
//
// RETURN VALUES:
//
// The corresponding CIMTYPE, or CIM_ILLEGAL if error
//
//***************************************************************************
CIMTYPE CXml2Wmi::CimtypeFromString (BSTR bsType) { CIMTYPE cimtype = CIM_ILLEGAL;
if (bsType) { if (0 == _wcsicmp (bsType, L"string")) cimtype = CIM_STRING; else if (0 == _wcsicmp (bsType, L"uint32")) cimtype = CIM_UINT32; else if (0 == _wcsicmp (bsType, L"boolean")) cimtype = CIM_BOOLEAN; else if (0 == _wcsicmp (bsType, L"sint32")) cimtype = CIM_SINT32; else if (0 == _wcsicmp (bsType, L"char16")) cimtype = CIM_CHAR16; else if (0 == _wcsicmp (bsType, L"uint8")) cimtype = CIM_UINT8; else if (0 == _wcsicmp (bsType, L"uint16")) cimtype = CIM_UINT16; else if (0 == _wcsicmp (bsType, L"sint16")) cimtype = CIM_SINT16; else if (0 == _wcsicmp (bsType, L"uint64")) cimtype = CIM_UINT64; else if (0 == _wcsicmp (bsType, L"sint64")) cimtype = CIM_SINT64; else if (0 == _wcsicmp (bsType, L"datetime")) cimtype = CIM_DATETIME; else if (0 == _wcsicmp (bsType, L"real32")) cimtype = CIM_REAL32; else if (0 == _wcsicmp (bsType, L"real64")) cimtype = CIM_REAL64; }
return cimtype; }
HRESULT CXml2Wmi::MakeObjectAbstract(IWbemClassObject *pObj, IXMLDOMNode *pAbstractQualifierNode) { HRESULT hr = E_FAIL;
// Get the object qualifeir set
IWbemQualifierSet *pQuals = NULL; if(SUCCEEDED(hr = pObj->GetQualifierSet(&pQuals))) { // Add the "abstract" qualiifer
hr = AddQualifier(pAbstractQualifierNode, pQuals); pQuals->Release(); } return hr; }
*/
|