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.
 
 
 
 
 
 

592 lines
14 KiB

#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;
}
*/