3542 lines
101 KiB
C++
3542 lines
101 KiB
C++
|
|
|
|
// ***************************************************************************
|
|
//
|
|
// Copyright (c) 1997-1999 Microsoft Corporation
|
|
//
|
|
// XMLTOWMI.CPP
|
|
//
|
|
// rajesh 3/25/2000 Created.
|
|
//
|
|
// Contains the implementation of the component that implements the IXMLWbemConvertor
|
|
// interface
|
|
//
|
|
// ***************************************************************************
|
|
|
|
|
|
#include "precomp.h"
|
|
#include <olectl.h>
|
|
#include <wbemcli.h>
|
|
#include <wbemint.h>
|
|
|
|
#include "wmiconv.h"
|
|
#include "xmlToWmi.h"
|
|
#include "maindll.h"
|
|
|
|
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
* Conversion to Text to Wbem Object has been cut from the WHistler Feature List and hence commented out
|
|
*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
|
|
// INitialize the class - static variables
|
|
LPCWSTR CXml2Wmi::VALUE_TAG = L"VALUE";
|
|
LPCWSTR CXml2Wmi::VALUEARRAY_TAG = L"VALUE.ARRAY";
|
|
LPCWSTR CXml2Wmi::VALUEREFERENCE_TAG = L"VALUE.REFERENCE";
|
|
LPCWSTR CXml2Wmi::CLASS_TAG = L"CLASS";
|
|
LPCWSTR CXml2Wmi::INSTANCE_TAG = L"INSTANCE";
|
|
LPCWSTR CXml2Wmi::CLASSNAME_TAG = L"CLASSNAME";
|
|
LPCWSTR CXml2Wmi::LOCALCLASSPATH_TAG = L"LOCALCLASSPATH";
|
|
LPCWSTR CXml2Wmi::CLASSPATH_TAG = L"CLASSPATH";
|
|
LPCWSTR CXml2Wmi::INSTANCENAME_TAG = L"INSTANCENAME";
|
|
LPCWSTR CXml2Wmi::LOCALINSTANCEPATH_TAG = L"LOCALINSTANCEPATH";
|
|
LPCWSTR CXml2Wmi::INSTANCEPATH_TAG = L"INSTANCEPATH";
|
|
LPCWSTR CXml2Wmi::LOCALNAMESPACEPATH_TAG = L"LOCALNAMESPACEPATH";
|
|
LPCWSTR CXml2Wmi::NAMESPACEPATH_TAG = L"NAMESPACEPATH";
|
|
LPCWSTR CXml2Wmi::KEYBINDING_TAG = L"KEYBINDING";
|
|
LPCWSTR CXml2Wmi::KEYVALUE_TAG = L"KEYVALUE";
|
|
LPCWSTR CXml2Wmi::QUALIFIER_TAG = L"QUALIFIER";
|
|
LPCWSTR CXml2Wmi::PARAMETER_TAG = L"PARAMETER";
|
|
LPCWSTR CXml2Wmi::PARAMETERARRAY_TAG = L"PARAMETER.ARRAY";
|
|
LPCWSTR CXml2Wmi::PARAMETERREFERENCE_TAG = L"PARAMETER.REFERENCE";
|
|
LPCWSTR CXml2Wmi::PARAMETERREFARRAY_TAG = L"PARAMETER.REFARRAY";
|
|
LPCWSTR CXml2Wmi::PARAMETEROBJECT_TAG = L"PARAMETER.OBJECT";
|
|
LPCWSTR CXml2Wmi::PARAMETEROBJECTARRAY_TAG = L"PARAMETER.OBJECTARRAY";
|
|
LPCWSTR CXml2Wmi::REF_WSTR = L"ref";
|
|
LPCWSTR CXml2Wmi::OBJECT_WSTR = L"object";
|
|
LPCWSTR CXml2Wmi::EQUALS_SIGN = L"=";
|
|
LPCWSTR CXml2Wmi::QUOTE_SIGN = L"\"";
|
|
LPCWSTR CXml2Wmi::DOT_SIGN = L".";
|
|
LPCWSTR CXml2Wmi::COMMA_SIGN = L",";
|
|
|
|
extern long g_cObj;
|
|
|
|
CXml2Wmi::CXml2Wmi()
|
|
{
|
|
m_cRef = 0;
|
|
InterlockedIncrement(&g_cObj);
|
|
}
|
|
|
|
CXml2Wmi::~CXml2Wmi()
|
|
{
|
|
InterlockedDecrement(&g_cObj);
|
|
}
|
|
|
|
STDMETHODIMP CXml2Wmi::QueryInterface (
|
|
|
|
IN REFIID riid,
|
|
OUT LPVOID *ppv
|
|
)
|
|
{
|
|
*ppv=NULL;
|
|
|
|
if (IID_IUnknown==riid)
|
|
*ppv = reinterpret_cast<IUnknown*>(this);
|
|
else if (IID_IXMLWbemConvertor==riid)
|
|
*ppv = reinterpret_cast<IXMLWbemConvertor*>(this);
|
|
|
|
if (NULL!=*ppv)
|
|
{
|
|
((LPUNKNOWN)*ppv)->AddRef();
|
|
return NOERROR;
|
|
}
|
|
|
|
return ResultFromScode(E_NOINTERFACE);
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CXml2Wmi::AddRef(void)
|
|
{
|
|
InterlockedIncrement(&m_cRef);
|
|
return m_cRef;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CXml2Wmi::Release(void)
|
|
{
|
|
InterlockedDecrement(&m_cRef);
|
|
if (0L!=m_cRef)
|
|
return m_cRef;
|
|
delete this;
|
|
return 0;
|
|
}
|
|
|
|
// This function maps an IXMLDOMNode that represents a CLASS or an INSTANCE
|
|
// to an IWbemClassObject. The caller should Release() this object when done with it
|
|
HRESULT CXml2Wmi::MapObjectToWMI(IUnknown *pXmlDOMNode, IWbemContext *pInputFlags,
|
|
BSTR strNamespace, BSTR strServer, IWbemClassObject **ppObject)
|
|
{
|
|
HRESULT result = E_FAIL;
|
|
|
|
// Get the IXMLDOMElement interface from the input object
|
|
IXMLDOMElement *pObjectNode = NULL;
|
|
if(SUCCEEDED(result = pXmlDOMNode->QueryInterface(IID_IXMLDOMElement, (LPVOID *)&pObjectNode)))
|
|
{
|
|
BSTR strDocName = NULL;
|
|
if(SUCCEEDED(result = pObjectNode->get_nodeName(&strDocName)))
|
|
{
|
|
// This has to be an INSTANCE or a CLASS
|
|
if(_wcsicmp(strDocName, L"CLASS") == 0)
|
|
result = CXml2Wmi::MapClass(pObjectNode, ppObject, strNamespace, strServer, false, true);
|
|
else if(_wcsicmp(strDocName, L"INSTANCE") == 0)
|
|
result = CXml2Wmi::MapInstance(pObjectNode, ppObject, strNamespace, strServer, true);
|
|
else
|
|
result = WBEM_E_INVALID_SYNTAX;
|
|
SysFreeString(strDocName);
|
|
}
|
|
pObjectNode->Release();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
HRESULT CXml2Wmi::MapPropertyToWMI(IUnknown *pXmlDOMNode, IWbemClassObject *pObject, BSTR strPropertyName, IWbemContext *pInputFlags)
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
HRESULT CXml2Wmi::MapInstanceNameToWMI(IUnknown *pXmlDOMNode, IWbemContext *pInputFlags, BSTR *pstrInstanceName)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
// Get the IXMLDOMElement interface from the input object
|
|
IXMLDOMNode *pNode = NULL;
|
|
if(SUCCEEDED(hr = pXmlDOMNode->QueryInterface(IID_IXMLDOMNode, (LPVOID *)&pNode)))
|
|
{
|
|
LPWSTR pszName = NULL;
|
|
if(SUCCEEDED(hr = MapInstanceName(pNode, &pszName)))
|
|
{
|
|
*pstrInstanceName = NULL;
|
|
if((*pstrInstanceName) = SysAllocString(pszName))
|
|
{
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
delete [] pszName;
|
|
}
|
|
pNode->Release();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CXml2Wmi::MapClassNameToWMI(IUnknown *pXmlDOMNode, IWbemContext *pInputFlags, BSTR *pstrClassName)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
// Get the IXMLDOMElement interface from the input object
|
|
IXMLDOMNode *pNode = NULL;
|
|
if(SUCCEEDED(hr = pXmlDOMNode->QueryInterface(IID_IXMLDOMNode, (LPVOID *)&pNode)))
|
|
{
|
|
LPWSTR pszName = NULL;
|
|
if(SUCCEEDED(hr = MapClassName(pNode, &pszName)))
|
|
{
|
|
*pstrClassName = NULL;
|
|
if((*pstrClassName) = SysAllocString(pszName))
|
|
{
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
delete [] pszName;
|
|
}
|
|
pNode->Release();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CXml2Wmi::MapInstancePathToWMI(IUnknown *pXmlDOMNode, IWbemContext *pInputFlags, BSTR *pstrInstancePath)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
// Get the IXMLDOMElement interface from the input object
|
|
IXMLDOMNode *pNode = NULL;
|
|
if(SUCCEEDED(hr = pXmlDOMNode->QueryInterface(IID_IXMLDOMNode, (LPVOID *)&pNode)))
|
|
{
|
|
LPWSTR pszName = NULL;
|
|
if(SUCCEEDED(hr = MapInstancePath(pNode, &pszName)))
|
|
{
|
|
*pstrInstancePath = NULL;
|
|
if((*pstrInstancePath) = SysAllocString(pszName))
|
|
{
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
delete [] pszName;
|
|
}
|
|
pNode->Release();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CXml2Wmi::MapClassPathToWMI(IUnknown *pXmlDOMNode, IWbemContext *pInputFlags, BSTR *pstrClassPath)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
// Get the IXMLDOMElement interface from the input object
|
|
IXMLDOMNode *pNode = NULL;
|
|
if(SUCCEEDED(hr = pXmlDOMNode->QueryInterface(IID_IXMLDOMNode, (LPVOID *)&pNode)))
|
|
{
|
|
LPWSTR pszName = NULL;
|
|
if(SUCCEEDED(hr = MapClassPath(pNode, &pszName)))
|
|
{
|
|
*pstrClassPath = NULL;
|
|
if((*pstrClassPath) = SysAllocString(pszName))
|
|
{
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
delete [] pszName;
|
|
}
|
|
pNode->Release();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
HRESULT CXml2Wmi::MapClass (
|
|
IXMLDOMElement *pXml,
|
|
IWbemClassObject **ppClass,
|
|
BSTR strSpecifiedNamespace, BSTR strSpecifiedServer,
|
|
bool bMakeInstance,
|
|
bool bAllowWMIExtensions
|
|
)
|
|
{
|
|
// This function expects either a <CLASS> document or an <INSTANCE> document
|
|
// When it gets an INSTANCE element, it assumes that the property values
|
|
// are default values for the class properties
|
|
HRESULT hr = E_FAIL;
|
|
*ppClass = NULL;
|
|
if(pXml && ppClass)
|
|
{
|
|
// Create a Free Form Object
|
|
_IWmiFreeFormObject *pObj = NULL;
|
|
if(SUCCEEDED(hr = g_pObjectFactory->Create(NULL, 0, CLSID__WmiFreeFormObject, IID__IWmiFreeFormObject, (LPVOID *)&pObj)))
|
|
{
|
|
// Add the properties of the object
|
|
// Note that we cannot add methods and qualifiers to a free form object
|
|
// So we only add properties, and then use the IWbemClassObject interface
|
|
// to add methods and qualifiers
|
|
// Also, Get the __NAMESPACE and __SERVER at this time
|
|
BSTR strServer = NULL, strNamespace = NULL;
|
|
IXMLDOMNode *pAbstractQualifierNode = NULL;
|
|
if(SUCCEEDED(hr = CreateWMIProperties(bAllowWMIExtensions, pObj, pXml, bMakeInstance, &strServer, &strNamespace, &pAbstractQualifierNode)))
|
|
{
|
|
// Now we switch over to IWbemClassObject since we possibly need it from now
|
|
IWbemClassObject *pClass = NULL;
|
|
if(SUCCEEDED(hr = pObj->QueryInterface(IID_IWbemClassObject, (LPVOID *)&pClass)))
|
|
{
|
|
// Special case for abstract classes
|
|
// If a class is abstract, we need to set the abstract qualifier on the class
|
|
// before calling SetDerivation() as per Sanj's rules
|
|
// Hence we do it at this time, if applicable
|
|
if(pAbstractQualifierNode)
|
|
{
|
|
hr = MakeObjectAbstract(pClass, pAbstractQualifierNode);
|
|
pAbstractQualifierNode->Release();
|
|
}
|
|
|
|
// Set the name of the class first
|
|
if(SUCCEEDED(hr) && SUCCEEDED(hr = SetDerivationAndClassName(pObj, pXml, bMakeInstance)))
|
|
{
|
|
// Decorate the object
|
|
if(SUCCEEDED(hr = DecorateObject(pObj, (strSpecifiedServer)? strSpecifiedServer : strServer, (strSpecifiedNamespace)? strSpecifiedNamespace : strNamespace)))
|
|
{
|
|
// 1. Add methods
|
|
if(SUCCEEDED(hr = CreateWMIMethods(bAllowWMIExtensions, pClass, pXml)))
|
|
{
|
|
// 2. Add Qualifiers
|
|
if(SUCCEEDED(hr = AddObjectQualifiers(bAllowWMIExtensions, pXml, pClass)))
|
|
{
|
|
// 3. Convert weak property refs and embedded objects to strong ones
|
|
// We could not do this on free-form objects, while adding the properties
|
|
if(SUCCEEDED(hr = FixRefsAndEmbeddedObjects(pXml, pClass)))
|
|
{
|
|
*ppClass = pClass;
|
|
pClass->AddRef();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
pClass->Release();
|
|
}
|
|
SysFreeString(strServer);
|
|
SysFreeString(strNamespace);
|
|
}
|
|
pObj->Release();
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
// This function sets the class name of a class
|
|
// and its derivation if any
|
|
HRESULT CXml2Wmi::SetDerivationAndClassName(_IWmiFreeFormObject *pObj, IXMLDOMElement *pXML, bool bMakeInstance)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// First set the derivation
|
|
BSTR strSuperClassName = NULL;
|
|
if(SUCCEEDED(GetBstrAttribute(pXML, g_strSuperClass, &strSuperClassName)))
|
|
{
|
|
hr = pObj->SetDerivation(0, 1, strSuperClassName);
|
|
SysFreeString(strSuperClassName);
|
|
}
|
|
|
|
// Next set the class name
|
|
BSTR strName = NULL;
|
|
if(bMakeInstance)
|
|
hr = GetBstrAttribute(pXML, g_strClassName, &strName);
|
|
else
|
|
hr = GetBstrAttribute(pXML, g_strName, &strName);
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = pObj->SetClassName(0, strName);
|
|
SysFreeString(strName);
|
|
}
|
|
else
|
|
hr = WBEM_E_INVALID_SYNTAX; // We could not get the NAME attribute on the <CLASS>
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CXml2Wmi::MapInstance (
|
|
IXMLDOMElement *pXml,
|
|
IWbemClassObject **ppInstance,
|
|
BSTR strNamespace, BSTR strServer,
|
|
bool bAllowWMIExtensions
|
|
)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
if(SUCCEEDED(hr = MapClass(pXml, ppInstance, strNamespace, strServer, true, bAllowWMIExtensions)))
|
|
{
|
|
// Make it an instance
|
|
_IWmiFreeFormObject *pFreeForm = NULL;
|
|
if(SUCCEEDED(hr = (*ppInstance)->QueryInterface(IID__IWmiFreeFormObject, (LPVOID *)&pFreeForm)))
|
|
{
|
|
if(SUCCEEDED(hr = pFreeForm->MakeInstance(0)))
|
|
{
|
|
}
|
|
pFreeForm->Release();
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
// Creates all the properties in a class/instance
|
|
// All strongly typed ref properties and embedded properties are mapped as
|
|
// weakly typed ones since the free-form object allows only such properties
|
|
HRESULT CXml2Wmi::CreateWMIProperties(bool bAllowWMIExtensions,
|
|
_IWmiFreeFormObject *pObj, IXMLDOMElement *pXML,
|
|
bool bMakeInstance,
|
|
BSTR *pstrServer, BSTR *pstrNamespace,
|
|
IXMLDOMNode **ppAbstractQualifierNode)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
// Go thru all the properties of the class
|
|
IXMLDOMNodeList *pNodeList = NULL;
|
|
bool bError = false;
|
|
if (SUCCEEDED(pXML->get_childNodes (&pNodeList)))
|
|
{
|
|
IXMLDOMNode *pNode = NULL;
|
|
while (!bError && SUCCEEDED(pNodeList->nextNode (&pNode)) &&pNode)
|
|
{
|
|
// We're interested only in simple properties, embedded objects, ref properties
|
|
// and arrays of such types
|
|
BSTR strNodeName = NULL;
|
|
if (SUCCEEDED(pNode->get_nodeName (&strNodeName)))
|
|
{
|
|
if(_wcsicmp(strNodeName, L"PROPERTY") == 0 ||
|
|
_wcsicmp(strNodeName, L"PROPERTY.ARRAY") == 0 ||
|
|
_wcsicmp(strNodeName, L"PROPERTY.REFERENCE") == 0 ||
|
|
_wcsicmp(strNodeName, L"PROPERTY.REFARRAY") == 0 ||
|
|
(_wcsicmp(strNodeName, L"PROPERTY.OBJECT") == 0 && bAllowWMIExtensions)||
|
|
(_wcsicmp(strNodeName, L"PROPERTY.OBJECTARRAY") == 0 && bAllowWMIExtensions))
|
|
{
|
|
IXMLDOMElement *pPropElement = NULL;
|
|
if(SUCCEEDED(hr = pNode->QueryInterface(IID_IXMLDOMElement, (LPVOID *)&pPropElement)))
|
|
{
|
|
BSTR strName = NULL;
|
|
// Get the Name of the property
|
|
if(SUCCEEDED(hr = GetBstrAttribute(pPropElement, g_strName, &strName)))
|
|
{
|
|
// See if it is one of the Decorative Properties
|
|
if(_wcsicmp(strName, L"__NAMESPACE") == 0)
|
|
pPropElement->get_text(pstrNamespace);
|
|
else if(_wcsicmp(strName, L"__SERVER") == 0)
|
|
pPropElement->get_text(pstrServer);
|
|
else if(_wcsnicmp(strName, L"__", 2) == 0)
|
|
{
|
|
// Ignore other system properties
|
|
}
|
|
else if(FAILED(hr = CreateAWMIProperty(strNodeName, pObj, pPropElement, strName, bMakeInstance)))
|
|
bError = true;
|
|
SysFreeString(strName);
|
|
}
|
|
else
|
|
{
|
|
hr = WBEM_E_INVALID_SYNTAX;
|
|
bError = true;
|
|
}
|
|
pPropElement->Release();
|
|
}
|
|
else
|
|
bError = true;
|
|
}
|
|
// We need to check if this class is an abstract class
|
|
else if(_wcsicmp(strNodeName, L"QUALIFIER") == 0)
|
|
{
|
|
// Get the Name of the Qualifier
|
|
BSTR strQualifierName = NULL;
|
|
if(SUCCEEDED(GetBstrAttribute (pNode, g_strName, &strQualifierName)))
|
|
{
|
|
// We're looking for the "abstract" qualifier
|
|
if(_wcsicmp(strQualifierName, L"abstract") == 0)
|
|
{
|
|
*ppAbstractQualifierNode = pNode;
|
|
pNode->AddRef();
|
|
}
|
|
SysFreeString(strQualifierName);
|
|
}
|
|
}
|
|
|
|
SysFreeString(strNodeName);
|
|
}
|
|
pNode->Release();
|
|
pNode = NULL;
|
|
}
|
|
pNodeList->Release();
|
|
}
|
|
|
|
if(bError)
|
|
return hr;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CXml2Wmi::CreateAWMIProperty(BSTR strNodeName, _IWmiFreeFormObject *pObj, IXMLDOMElement *pXML, BSTR strName, bool bMakeInstance)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
BSTR strClassOrigin = NULL;
|
|
|
|
// No need to check whether this was successful - ClassOrigin info is optional.
|
|
GetBstrAttribute(pXML, g_strClassOrigin, &strClassOrigin);
|
|
|
|
if(_wcsicmp(strNodeName, L"PROPERTY") == 0)
|
|
hr = CreateSimpleProperty(strName, pObj, pXML, strClassOrigin, bMakeInstance);
|
|
else if(_wcsicmp(strNodeName, L"PROPERTY.ARRAY") == 0)
|
|
hr = CreateArrayProperty(strName, pObj, pXML, strClassOrigin, bMakeInstance);
|
|
else if(_wcsicmp(strNodeName, L"PROPERTY.REFERENCE") == 0)
|
|
hr = CreateReferenceProperty(strName, pObj, pXML, strClassOrigin, bMakeInstance);
|
|
else if(_wcsicmp(strNodeName, L"PROPERTY.REFARRAY") == 0)
|
|
hr = CreateRefArrayProperty(strName, pObj, pXML, strClassOrigin, bMakeInstance);
|
|
else if(_wcsicmp(strNodeName, L"PROPERTY.OBJECT") == 0)
|
|
hr = CreateObjectProperty(strName, pObj, pXML, strClassOrigin, bMakeInstance);
|
|
else if(_wcsicmp(strNodeName, L"PROPERTY.OBJECTARRAY") == 0)
|
|
hr = CreateObjectArrayProperty(strName, pObj, pXML, strClassOrigin, bMakeInstance);
|
|
else
|
|
hr = WBEM_E_INVALID_PROPERTY;
|
|
|
|
SysFreeString(strClassOrigin);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CXml2Wmi::CreateSimpleProperty(LPCWSTR pszName, _IWmiFreeFormObject *pObj, IXMLDOMElement *pXML, LPCWSTR pszClassOrigin, bool bMakeInstance)
|
|
{
|
|
HRESULT hr = WBEM_E_INVALID_SYNTAX;
|
|
BSTR strType = NULL;
|
|
// Get the Type of the property
|
|
if(SUCCEEDED(hr = GetBstrAttribute(pXML, g_strType, &strType)))
|
|
{
|
|
// Get the Value of the Property - this value is optional
|
|
BSTR strValue = NULL;
|
|
IXMLDOMElement *pValue = NULL;
|
|
if(SUCCEEDED(hr = GetFirstImmediateElement(pXML, &pValue, L"VALUE")))
|
|
{
|
|
// This is a simple property - its text value should be enough for mapping
|
|
hr = pValue->get_text(&strValue);
|
|
pValue->Release();
|
|
}
|
|
else
|
|
hr = S_OK;
|
|
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
if(_wcsicmp(strType, L"boolean") == 0)
|
|
hr = MapStringValue(pszName, pObj, strValue, CIM_BOOLEAN, pszClassOrigin, bMakeInstance);
|
|
else if(_wcsicmp(strType, L"string") == 0)
|
|
hr = MapStringValue(pszName, pObj, strValue, CIM_STRING, pszClassOrigin, bMakeInstance);
|
|
else if(_wcsicmp(strType, L"char16") == 0)
|
|
hr = MapStringValue(pszName, pObj, strValue, CIM_CHAR16, pszClassOrigin, bMakeInstance);
|
|
else if(_wcsicmp(strType, L"uint8") == 0)
|
|
hr = MapStringValue(pszName, pObj, strValue, CIM_UINT8, pszClassOrigin, bMakeInstance);
|
|
else if(_wcsicmp(strType, L"sint8") == 0)
|
|
hr = MapStringValue(pszName, pObj, strValue, CIM_SINT8, pszClassOrigin, bMakeInstance);
|
|
else if(_wcsicmp(strType, L"uint16") == 0)
|
|
hr = MapStringValue(pszName, pObj, strValue, CIM_UINT16, pszClassOrigin, bMakeInstance);
|
|
else if(_wcsicmp(strType, L"sint16") == 0)
|
|
hr = MapStringValue(pszName, pObj, strValue, CIM_SINT16, pszClassOrigin, bMakeInstance);
|
|
else if(_wcsicmp(strType, L"uint32") == 0)
|
|
hr = MapStringValue(pszName, pObj, strValue, CIM_UINT32, pszClassOrigin, bMakeInstance);
|
|
else if(_wcsicmp(strType, L"sint32") == 0)
|
|
hr = MapStringValue(pszName, pObj, strValue, CIM_SINT32, pszClassOrigin, bMakeInstance);
|
|
else if(_wcsicmp(strType, L"uint64") == 0)
|
|
hr = MapStringValue(pszName, pObj, strValue, CIM_UINT64, pszClassOrigin, bMakeInstance);
|
|
else if(_wcsicmp(strType, L"sint64") == 0)
|
|
hr = MapStringValue(pszName, pObj, strValue, CIM_SINT64, pszClassOrigin, bMakeInstance);
|
|
else if(_wcsicmp(strType, L"datetime") == 0)
|
|
hr = MapStringValue(pszName, pObj, strValue, CIM_DATETIME, pszClassOrigin, bMakeInstance);
|
|
else if(_wcsicmp(strType, L"real32") == 0)
|
|
hr = MapStringValue(pszName, pObj, strValue, CIM_REAL32, pszClassOrigin, bMakeInstance);
|
|
else if(_wcsicmp(strType, L"real64") == 0)
|
|
hr = MapStringValue(pszName, pObj, strValue, CIM_REAL64, pszClassOrigin, bMakeInstance);
|
|
else
|
|
hr = WBEM_E_INVALID_PROPERTY;
|
|
}
|
|
|
|
SysFreeString(strValue);
|
|
SysFreeString(strType);
|
|
}
|
|
else
|
|
hr = WBEM_E_INVALID_SYNTAX;
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CXml2Wmi::MapStringValue (LPCWSTR pszName, _IWmiFreeFormObject *pObj, BSTR bsValue, CIMTYPE cimtype, LPCWSTR pszClassOrigin, bool bMakeInstance)
|
|
{
|
|
// RAJESHR First we need to remove any CDATA section from the string value
|
|
// Even though the WMI implementation used CDATA (if necessary) only for CIM_STRING and CIM_DATETIME,
|
|
// other implementations might use a CDATA to escape other values as well
|
|
|
|
long lFlag = (bMakeInstance) ? WMIOBJECT_FREEFORM_FLAG_WRITE_TO_INSTANCE : 0;
|
|
|
|
// If there is no value then it is simple - we just need to create a property of the appropriate type
|
|
if(!bsValue)
|
|
return pObj->AddProperty(pszName, lFlag, 0, 0, cimtype, NULL);
|
|
|
|
|
|
// We create a value - buffer representations as required by the IWmiFreeFormObject interface
|
|
HRESULT hr = WBEM_E_TYPE_MISMATCH;
|
|
// We're assuming it's not an array
|
|
if (!(cimtype & CIM_FLAG_ARRAY))
|
|
{
|
|
switch (cimtype)
|
|
{
|
|
// RAJESHR - more rigorous syntax checking
|
|
case CIM_UINT8:
|
|
case CIM_SINT8:
|
|
{
|
|
BYTE iVal = 0;
|
|
int x;
|
|
if(swscanf(bsValue, L"%d", &x))
|
|
{
|
|
iVal = (BYTE)x;
|
|
hr = pObj->AddProperty(pszName, lFlag, 1, 1, cimtype, &iVal);
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
}
|
|
break;
|
|
|
|
case CIM_UINT16:
|
|
case CIM_SINT16:
|
|
{
|
|
SHORT iVal = 0;
|
|
iVal = (SHORT) wcstol (bsValue, NULL, 0);
|
|
hr = pObj->AddProperty(pszName, lFlag, 2, 1, cimtype, &iVal);
|
|
}
|
|
break;
|
|
|
|
case CIM_UINT32:
|
|
case CIM_SINT32:
|
|
{
|
|
LONG iVal = 0;
|
|
iVal = (LONG) wcstol (bsValue, NULL, 0);
|
|
hr = pObj->AddProperty(pszName, lFlag, 4, 1, cimtype, &iVal);
|
|
}
|
|
break;
|
|
|
|
case CIM_REAL32:
|
|
{
|
|
float fVal = 0;
|
|
fVal = (float) wcstod (bsValue, NULL);
|
|
hr = pObj->AddProperty(pszName, lFlag, 4, 1, cimtype, &fVal);
|
|
}
|
|
break;
|
|
|
|
case CIM_REAL64:
|
|
{
|
|
double fVal = 0;
|
|
fVal = (double) wcstod (bsValue, NULL);
|
|
hr = pObj->AddProperty(pszName, lFlag, 8, 1, cimtype, &fVal);
|
|
}
|
|
break;
|
|
|
|
case CIM_BOOLEAN:
|
|
{
|
|
SHORT bVal = 0;
|
|
if (0 == _wcsicmp (bsValue, L"TRUE"))
|
|
bVal = 1;
|
|
hr = pObj->AddProperty(pszName, lFlag, 2, 1, cimtype, &bVal);
|
|
}
|
|
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
|
|
|
|
SHORT cVal = 0;
|
|
if(_wcsnicmp(bsValue, L"\\x", 2) == 0)
|
|
// It is an escaped value
|
|
swscanf (bsValue+2, L"%x", &(cVal));
|
|
else
|
|
// It is a normal value
|
|
swscanf (bsValue, L"%c", &(cVal));
|
|
hr = pObj->AddProperty(pszName, lFlag,2, 1, cimtype, &cVal);
|
|
}
|
|
break;
|
|
|
|
case CIM_UINT64:
|
|
case CIM_SINT64:
|
|
{
|
|
__int64 iVal = 0;
|
|
if(swscanf(bsValue, L"%I64d", &iVal))
|
|
{
|
|
hr = pObj->AddProperty(pszName, lFlag, 8, 1, cimtype, &iVal);
|
|
}
|
|
else hr = E_FAIL;
|
|
}
|
|
break;
|
|
|
|
case CIM_STRING:
|
|
case CIM_DATETIME:
|
|
{
|
|
hr = pObj->AddProperty(pszName, lFlag, (wcslen(bsValue) + 1)*2, 1, cimtype, bsValue);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CXml2Wmi::MapStringArrayValue (
|
|
LPCWSTR pszName,
|
|
_IWmiFreeFormObject *pObj,
|
|
IXMLDOMElement *pValueArrayNode,
|
|
CIMTYPE cimtype,
|
|
LPCWSTR pszClassOrigin, bool bMakeInstance)
|
|
{
|
|
HRESULT hr = WBEM_E_TYPE_MISMATCH;
|
|
long lFlag = (bMakeInstance) ? WMIOBJECT_FREEFORM_FLAG_WRITE_TO_INSTANCE : 0;
|
|
|
|
// If there is no value then it is simple - we just need to create a property of the appropriate type
|
|
if(!pValueArrayNode)
|
|
return pObj->AddProperty(pszName, lFlag, 0, 0, cimtype|CIM_FLAG_ARRAY, NULL);
|
|
|
|
|
|
switch(cimtype)
|
|
{
|
|
// We need to separate this into a NULL separated string
|
|
case CIM_STRING:
|
|
{
|
|
// We need to get its text for calculating the length of
|
|
// the buffer required
|
|
BSTR bsValue = NULL;
|
|
if(SUCCEEDED(hr = pValueArrayNode->get_text (&bsValue)))
|
|
{
|
|
// Go thru the child nodes
|
|
IXMLDOMNodeList *pValueList = NULL;
|
|
if (SUCCEEDED (pValueArrayNode->get_childNodes (&pValueList)))
|
|
{
|
|
// It's length is calculated this way
|
|
LONG lArraylength = 0;
|
|
// No of strings - One NULL character for each string
|
|
pValueList->get_length (&lArraylength);
|
|
// Plus the actual content
|
|
LONG length = lArraylength + wcslen(bsValue);
|
|
|
|
// Allocate the string
|
|
LPWSTR pszValue = NULL;
|
|
if(pszValue = new WCHAR[length + 1])
|
|
{
|
|
pszValue[0] = NULL;
|
|
|
|
// Now fill up the array
|
|
IXMLDOMNode *pValue = NULL;
|
|
bool error = false;
|
|
ULONG dwBufferLen = 0;
|
|
|
|
// Get the next VALUE element
|
|
while (!error &&
|
|
SUCCEEDED(pValueList->nextNode(&pValue)) && pValue)
|
|
{
|
|
BSTR strValName = NULL;
|
|
if (SUCCEEDED(pValue->get_nodeName (&strValName)))
|
|
{
|
|
if (0 == _wcsicmp (strValName, L"VALUE"))
|
|
{
|
|
// Get the value of the string
|
|
BSTR bsStringValue = NULL;
|
|
if(SUCCEEDED(pValue->get_text (&bsStringValue)))
|
|
{
|
|
// Concatenate it to the list we're building
|
|
wcscat(pszValue + dwBufferLen, bsStringValue);
|
|
dwBufferLen += (wcslen(bsStringValue) + 1);
|
|
pszValue[dwBufferLen] = NULL;
|
|
}
|
|
else
|
|
error = true;
|
|
SysFreeString (bsStringValue);
|
|
}
|
|
else
|
|
{
|
|
// unexpected element
|
|
error = true;
|
|
}
|
|
|
|
SysFreeString (strValName);
|
|
}
|
|
else
|
|
error = true;
|
|
|
|
pValue->Release ();
|
|
pValue = NULL;
|
|
}
|
|
|
|
if(!error)
|
|
{
|
|
hr = pObj->AddProperty(pszName, lFlag, dwBufferLen*2, lArraylength, cimtype|CIM_FLAG_ARRAY, pszValue);
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
delete [] pszValue;
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
pValueList->Release();
|
|
}
|
|
SysFreeString(bsValue);
|
|
}
|
|
}
|
|
break;
|
|
case CIM_DATETIME:
|
|
{
|
|
// This needs to be an array of primitive values
|
|
// Go thru the child nodes
|
|
IXMLDOMNodeList *pValueList = NULL;
|
|
if (SUCCEEDED (pValueArrayNode->get_childNodes (&pValueList)))
|
|
{
|
|
// It's length is calculated this way
|
|
LONG lArrayLength = 0;
|
|
// No of strings - One NULL character for each string
|
|
pValueList->get_length (&lArrayLength);
|
|
// Plus the actual content
|
|
LONG length = lArrayLength*25 + lArrayLength; // 25 is the lenght of CIM_DATETIME
|
|
|
|
// Allocate the string
|
|
LPWSTR pszValue = NULL;
|
|
if(pszValue = new WCHAR[length + 1])
|
|
{
|
|
pszValue[0] = NULL;
|
|
|
|
// Now fill up the array
|
|
IXMLDOMNode *pValue = NULL;
|
|
bool error = false;
|
|
ULONG dwBufferLen = 0;
|
|
|
|
// Get the next VALUE element
|
|
while (!error &&
|
|
SUCCEEDED(pValueList->nextNode(&pValue)) && pValue)
|
|
{
|
|
BSTR strValName = NULL;
|
|
if (SUCCEEDED(pValue->get_nodeName (&strValName)))
|
|
{
|
|
if (0 == _wcsicmp (strValName, VALUE_TAG))
|
|
{
|
|
// Get the value of the string
|
|
BSTR bsValue = NULL;
|
|
if(SUCCEEDED(pValue->get_text (&bsValue)))
|
|
{
|
|
// Concatenate it to the list we're building
|
|
wcscat(pszValue + dwBufferLen, bsValue);
|
|
dwBufferLen += (wcslen(bsValue) + 1);
|
|
pszValue[dwBufferLen] = NULL;
|
|
}
|
|
else
|
|
error = true;
|
|
SysFreeString (bsValue);
|
|
}
|
|
else
|
|
{
|
|
// unexpected element
|
|
error = true;
|
|
}
|
|
|
|
SysFreeString (strValName);
|
|
}
|
|
else
|
|
error = true;
|
|
|
|
pValue->Release ();
|
|
pValue = NULL;
|
|
}
|
|
|
|
if(!error)
|
|
{
|
|
hr = pObj->AddProperty(pszName, lFlag, dwBufferLen*2, lArrayLength, cimtype|CIM_FLAG_ARRAY, pszValue);
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
delete [] pszValue;
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
pValueList->Release();
|
|
}
|
|
}
|
|
break;
|
|
case CIM_BOOLEAN:
|
|
{
|
|
// This needs to be an array of primitive values
|
|
// Go thru the child nodes
|
|
IXMLDOMNodeList *pValueList = NULL;
|
|
if (SUCCEEDED (pValueArrayNode->get_childNodes (&pValueList)))
|
|
{
|
|
// Get the number of child elements - this should be the lenght of the array required
|
|
LONG lArraylength = 0;
|
|
pValueList->get_length (&lArraylength);
|
|
|
|
// Allocate the string
|
|
SHORT *pszValue = NULL;
|
|
if(pszValue = new SHORT[lArraylength])
|
|
{
|
|
// Now fill up the array
|
|
IXMLDOMNode *pValue = NULL;
|
|
bool error = false;
|
|
|
|
LONG lIndex = 0;
|
|
// Get the next VALUE element
|
|
while (!error &&
|
|
SUCCEEDED(pValueList->nextNode(&pValue)) && pValue)
|
|
{
|
|
BSTR strValName = NULL;
|
|
if (SUCCEEDED(pValue->get_nodeName (&strValName)))
|
|
{
|
|
if (0 == _wcsicmp (strValName, VALUE_TAG))
|
|
{
|
|
// Get the value of the string
|
|
BSTR bsValue = NULL;
|
|
if(SUCCEEDED(pValue->get_text (&bsValue)))
|
|
{
|
|
pszValue[lIndex] = 0;
|
|
if (0 == _wcsicmp (bsValue, L"TRUE"))
|
|
pszValue[lIndex] = 1;
|
|
lIndex++;
|
|
}
|
|
else
|
|
error = true;
|
|
SysFreeString (bsValue);
|
|
}
|
|
else
|
|
{
|
|
// unexpected element
|
|
error = true;
|
|
}
|
|
|
|
SysFreeString (strValName);
|
|
}
|
|
else
|
|
error = true;
|
|
|
|
pValue->Release ();
|
|
pValue = NULL;
|
|
}
|
|
|
|
if(!error)
|
|
{
|
|
hr = pObj->AddProperty(pszName, lFlag, lArraylength*2, lArraylength, cimtype|CIM_FLAG_ARRAY, pszValue);
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
delete [] pszValue;
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
pValueList->Release();
|
|
}
|
|
}
|
|
break;
|
|
case CIM_UINT8:
|
|
case CIM_SINT8:
|
|
{
|
|
// This needs to be an array of primitive values
|
|
// Go thru the child nodes
|
|
IXMLDOMNodeList *pValueList = NULL;
|
|
if (SUCCEEDED (pValueArrayNode->get_childNodes (&pValueList)))
|
|
{
|
|
// Get the number of child elements - this should be the lenght of the array required
|
|
LONG lArraylength = 0;
|
|
pValueList->get_length (&lArraylength);
|
|
|
|
// Allocate the array
|
|
LPBYTE pszValue = NULL;
|
|
if(pszValue = new BYTE[lArraylength])
|
|
{
|
|
// Now fill up the array
|
|
IXMLDOMNode *pValue = NULL;
|
|
bool error = false;
|
|
|
|
LONG lIndex = 0;
|
|
// Get the next VALUE element
|
|
while (!error &&
|
|
SUCCEEDED(pValueList->nextNode(&pValue)) && pValue)
|
|
{
|
|
BSTR strValName = NULL;
|
|
if (SUCCEEDED(pValue->get_nodeName (&strValName)))
|
|
{
|
|
if (0 == _wcsicmp (strValName, VALUE_TAG))
|
|
{
|
|
// Get the value of the string
|
|
BSTR bsValue = NULL;
|
|
if(SUCCEEDED(pValue->get_text (&bsValue)))
|
|
{
|
|
pszValue[lIndex] = 0;
|
|
pszValue[lIndex++] = (BYTE) wcstol (bsValue, NULL, 0);
|
|
}
|
|
else
|
|
error = true;
|
|
SysFreeString (bsValue);
|
|
}
|
|
else
|
|
{
|
|
// unexpected element
|
|
error = true;
|
|
}
|
|
|
|
SysFreeString (strValName);
|
|
}
|
|
else
|
|
error = true;
|
|
|
|
pValue->Release ();
|
|
pValue = NULL;
|
|
}
|
|
|
|
if(!error)
|
|
{
|
|
hr = pObj->AddProperty(pszName, lFlag, lArraylength*1, lArraylength, cimtype|CIM_FLAG_ARRAY, pszValue);
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
delete [] pszValue;
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
pValueList->Release();
|
|
}
|
|
}
|
|
break;
|
|
case CIM_UINT16:
|
|
case CIM_SINT16:
|
|
{
|
|
// This needs to be an array of primitive values
|
|
// Go thru the child nodes
|
|
IXMLDOMNodeList *pValueList = NULL;
|
|
if (SUCCEEDED (pValueArrayNode->get_childNodes (&pValueList)))
|
|
{
|
|
// Get the number of child elements - this should be the lenght of the array required
|
|
LONG lArraylength = 0;
|
|
pValueList->get_length (&lArraylength);
|
|
|
|
// Allocate the array
|
|
SHORT *pszValue = NULL;
|
|
if(pszValue = new SHORT[lArraylength])
|
|
{
|
|
// Now fill up the array
|
|
IXMLDOMNode *pValue = NULL;
|
|
bool error = false;
|
|
|
|
LONG lIndex = 0;
|
|
// Get the next VALUE element
|
|
while (!error &&
|
|
SUCCEEDED(pValueList->nextNode(&pValue)) && pValue)
|
|
{
|
|
BSTR strValName = NULL;
|
|
if (SUCCEEDED(pValue->get_nodeName (&strValName)))
|
|
{
|
|
if (0 == _wcsicmp (strValName, VALUE_TAG))
|
|
{
|
|
// Get the value of the string
|
|
BSTR bsValue = NULL;
|
|
if(SUCCEEDED(pValue->get_text (&bsValue)))
|
|
{
|
|
pszValue[lIndex] = 0;
|
|
pszValue[lIndex++] = (SHORT) wcstol (bsValue, NULL, 0);
|
|
}
|
|
else
|
|
error = true;
|
|
SysFreeString (bsValue);
|
|
}
|
|
else
|
|
{
|
|
// unexpected element
|
|
error = true;
|
|
}
|
|
|
|
SysFreeString (strValName);
|
|
}
|
|
else
|
|
error = true;
|
|
|
|
pValue->Release ();
|
|
pValue = NULL;
|
|
}
|
|
|
|
if(!error)
|
|
{
|
|
hr = pObj->AddProperty(pszName, lFlag, lArraylength*2, lArraylength, cimtype|CIM_FLAG_ARRAY, pszValue);
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
delete [] pszValue;
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
pValueList->Release();
|
|
}
|
|
}
|
|
break;
|
|
case CIM_UINT32:
|
|
case CIM_SINT32:
|
|
{
|
|
// This needs to be an array of primitive values
|
|
// Go thru the child nodes
|
|
IXMLDOMNodeList *pValueList = NULL;
|
|
if (SUCCEEDED (pValueArrayNode->get_childNodes (&pValueList)))
|
|
{
|
|
// Get the number of child elements - this should be the lenght of the array required
|
|
LONG lArraylength = 0;
|
|
pValueList->get_length (&lArraylength);
|
|
|
|
// Allocate the array
|
|
LONG *pszValue = NULL;
|
|
if(pszValue = new LONG[lArraylength])
|
|
{
|
|
// Now fill up the array
|
|
IXMLDOMNode *pValue = NULL;
|
|
bool error = false;
|
|
|
|
LONG lIndex = 0;
|
|
// Get the next VALUE element
|
|
while (!error &&
|
|
SUCCEEDED(pValueList->nextNode(&pValue)) && pValue)
|
|
{
|
|
BSTR strValName = NULL;
|
|
if (SUCCEEDED(pValue->get_nodeName (&strValName)))
|
|
{
|
|
if (0 == _wcsicmp (strValName, VALUE_TAG))
|
|
{
|
|
// Get the value of the string
|
|
BSTR bsValue = NULL;
|
|
if(SUCCEEDED(pValue->get_text (&bsValue)))
|
|
{
|
|
pszValue[lIndex] = 0;
|
|
pszValue[lIndex++] = (LONG) wcstol (bsValue, NULL, 0);
|
|
}
|
|
else
|
|
error = true;
|
|
SysFreeString (bsValue);
|
|
}
|
|
else
|
|
{
|
|
// unexpected element
|
|
error = true;
|
|
}
|
|
|
|
SysFreeString (strValName);
|
|
}
|
|
else
|
|
error = true;
|
|
|
|
pValue->Release ();
|
|
pValue = NULL;
|
|
}
|
|
|
|
if(!error)
|
|
{
|
|
hr = pObj->AddProperty(pszName, lFlag, lArraylength*4, lArraylength, cimtype|CIM_FLAG_ARRAY, pszValue);
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
delete [] pszValue;
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
pValueList->Release();
|
|
}
|
|
}
|
|
break;
|
|
case CIM_UINT64:
|
|
case CIM_SINT64:
|
|
{
|
|
// This needs to be an array of primitive values
|
|
// Go thru the child nodes
|
|
IXMLDOMNodeList *pValueList = NULL;
|
|
if (SUCCEEDED (pValueArrayNode->get_childNodes (&pValueList)))
|
|
{
|
|
// Get the number of child elements - this should be the lenght of the array required
|
|
LONG lArraylength = 0;
|
|
pValueList->get_length (&lArraylength);
|
|
|
|
// Allocate the array
|
|
__int64 *pszValue = NULL;
|
|
if(pszValue = new __int64[lArraylength])
|
|
{
|
|
// Now fill up the array
|
|
IXMLDOMNode *pValue = NULL;
|
|
bool error = false;
|
|
|
|
LONG lIndex = 0;
|
|
// Get the next VALUE element
|
|
while (!error &&
|
|
SUCCEEDED(pValueList->nextNode(&pValue)) && pValue)
|
|
{
|
|
BSTR strValName = NULL;
|
|
if (SUCCEEDED(pValue->get_nodeName (&strValName)))
|
|
{
|
|
if (0 == _wcsicmp (strValName, VALUE_TAG))
|
|
{
|
|
// Get the value of the string
|
|
BSTR bsValue = NULL;
|
|
if(SUCCEEDED(pValue->get_text (&bsValue)))
|
|
{
|
|
pszValue[lIndex] = 0;
|
|
swscanf(bsValue, L"%I64d", &pszValue[lIndex]);
|
|
}
|
|
else
|
|
error = true;
|
|
SysFreeString (bsValue);
|
|
}
|
|
else
|
|
{
|
|
// unexpected element
|
|
error = true;
|
|
}
|
|
|
|
SysFreeString (strValName);
|
|
}
|
|
else
|
|
error = true;
|
|
|
|
pValue->Release ();
|
|
pValue = NULL;
|
|
}
|
|
|
|
if(!error)
|
|
{
|
|
hr = pObj->AddProperty(pszName, lFlag, lArraylength*8, lArraylength, cimtype|CIM_FLAG_ARRAY, pszValue);
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
delete [] pszValue;
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
pValueList->Release();
|
|
}
|
|
}
|
|
break;
|
|
case CIM_CHAR16:
|
|
{
|
|
// This needs to be an array of primitive values
|
|
// Go thru the child nodes
|
|
IXMLDOMNodeList *pValueList = NULL;
|
|
if (SUCCEEDED (pValueArrayNode->get_childNodes (&pValueList)))
|
|
{
|
|
// Get the number of child elements - this should be the lenght of the array required
|
|
LONG lArraylength = 0;
|
|
pValueList->get_length (&lArraylength);
|
|
|
|
// Allocate the array
|
|
SHORT *pszValue = NULL;
|
|
if(pszValue = new SHORT[lArraylength])
|
|
{
|
|
// Now fill up the array
|
|
IXMLDOMNode *pValue = NULL;
|
|
bool error = false;
|
|
|
|
LONG lIndex = 0;
|
|
// Get the next VALUE element
|
|
while (!error &&
|
|
SUCCEEDED(pValueList->nextNode(&pValue)) && pValue)
|
|
{
|
|
BSTR strValName = NULL;
|
|
if (SUCCEEDED(pValue->get_nodeName (&strValName)))
|
|
{
|
|
if (0 == _wcsicmp (strValName, VALUE_TAG))
|
|
{
|
|
// Get the value of the string
|
|
BSTR bsValue = NULL;
|
|
if(SUCCEEDED(pValue->get_text (&bsValue)))
|
|
{
|
|
pszValue[lIndex] = 0;
|
|
if(_wcsnicmp(bsValue, L"\\x", 2) == 0)
|
|
// It is an escaped value
|
|
swscanf (bsValue+2, L"%x", &(pszValue[lIndex]));
|
|
else
|
|
// It is a normal value
|
|
swscanf (bsValue, L"%c", &(pszValue[lIndex]));
|
|
}
|
|
else
|
|
error = true;
|
|
SysFreeString (bsValue);
|
|
}
|
|
else
|
|
{
|
|
// unexpected element
|
|
error = true;
|
|
}
|
|
|
|
SysFreeString (strValName);
|
|
}
|
|
else
|
|
error = true;
|
|
|
|
pValue->Release ();
|
|
pValue = NULL;
|
|
}
|
|
|
|
if(!error)
|
|
{
|
|
hr = pObj->AddProperty(pszName, lFlag, lArraylength*2, lArraylength, cimtype|CIM_FLAG_ARRAY, pszValue);
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
delete [] pszValue;
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
pValueList->Release();
|
|
}
|
|
}
|
|
break;
|
|
case CIM_REAL32:
|
|
{
|
|
// This needs to be an array of primitive values
|
|
// Go thru the child nodes
|
|
IXMLDOMNodeList *pValueList = NULL;
|
|
if (SUCCEEDED (pValueArrayNode->get_childNodes (&pValueList)))
|
|
{
|
|
// Get the number of child elements - this should be the lenght of the array required
|
|
LONG lArraylength = 0;
|
|
pValueList->get_length (&lArraylength);
|
|
|
|
// Allocate the array
|
|
float *pszValue = NULL;
|
|
if(pszValue = new float[lArraylength])
|
|
{
|
|
// Now fill up the array
|
|
IXMLDOMNode *pValue = NULL;
|
|
bool error = false;
|
|
|
|
LONG lIndex = 0;
|
|
// Get the next VALUE element
|
|
while (!error &&
|
|
SUCCEEDED(pValueList->nextNode(&pValue)) && pValue)
|
|
{
|
|
BSTR strValName = NULL;
|
|
if (SUCCEEDED(pValue->get_nodeName (&strValName)))
|
|
{
|
|
if (0 == _wcsicmp (strValName, VALUE_TAG))
|
|
{
|
|
// Get the value of the string
|
|
BSTR bsValue = NULL;
|
|
if(SUCCEEDED(pValue->get_text (&bsValue)))
|
|
{
|
|
pszValue[lIndex] = 0;
|
|
pszValue[lIndex] = (float) wcstod (bsValue, NULL);
|
|
}
|
|
else
|
|
error = true;
|
|
SysFreeString (bsValue);
|
|
}
|
|
else
|
|
{
|
|
// unexpected element
|
|
error = true;
|
|
}
|
|
|
|
SysFreeString (strValName);
|
|
}
|
|
else
|
|
error = true;
|
|
|
|
pValue->Release ();
|
|
pValue = NULL;
|
|
}
|
|
|
|
if(!error)
|
|
{
|
|
hr = pObj->AddProperty(pszName, lFlag, lArraylength*4, lArraylength, cimtype|CIM_FLAG_ARRAY, pszValue);
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
delete [] pszValue;
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
pValueList->Release();
|
|
}
|
|
}
|
|
break;
|
|
case CIM_REAL64:
|
|
{
|
|
// This needs to be an array of primitive values
|
|
// Go thru the child nodes
|
|
IXMLDOMNodeList *pValueList = NULL;
|
|
if (SUCCEEDED (pValueArrayNode->get_childNodes (&pValueList)))
|
|
{
|
|
// Get the number of child elements - this should be the lenght of the array required
|
|
LONG lArraylength = 0;
|
|
pValueList->get_length (&lArraylength);
|
|
|
|
// Allocate the array
|
|
double *pszValue = NULL;
|
|
if(pszValue = new double[lArraylength])
|
|
{
|
|
// Now fill up the array
|
|
IXMLDOMNode *pValue = NULL;
|
|
bool error = false;
|
|
|
|
LONG lIndex = 0;
|
|
// Get the next VALUE element
|
|
while (!error &&
|
|
SUCCEEDED(pValueList->nextNode(&pValue)) && pValue)
|
|
{
|
|
BSTR strValName = NULL;
|
|
if (SUCCEEDED(pValue->get_nodeName (&strValName)))
|
|
{
|
|
if (0 == _wcsicmp (strValName, VALUE_TAG))
|
|
{
|
|
// Get the value of the string
|
|
BSTR bsValue = NULL;
|
|
if(SUCCEEDED(pValue->get_text (&bsValue)))
|
|
{
|
|
pszValue[lIndex] = 0;
|
|
pszValue[lIndex] = (double) wcstod (bsValue, NULL);
|
|
}
|
|
else
|
|
error = true;
|
|
SysFreeString (bsValue);
|
|
}
|
|
else
|
|
{
|
|
// unexpected element
|
|
error = true;
|
|
}
|
|
|
|
SysFreeString (strValName);
|
|
}
|
|
else
|
|
error = true;
|
|
|
|
pValue->Release ();
|
|
pValue = NULL;
|
|
}
|
|
|
|
if(!error)
|
|
{
|
|
hr = pObj->AddProperty(pszName, lFlag, lArraylength*8, lArraylength, cimtype|CIM_FLAG_ARRAY, pszValue);
|
|
}
|
|
else
|
|
hr = WBEM_E_INVALID_SYNTAX;
|
|
delete [] pszValue;
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
pValueList->Release();
|
|
}
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CXml2Wmi::CreateArrayProperty(LPCWSTR pszName, _IWmiFreeFormObject *pObj, IXMLDOMElement *pXML, LPCWSTR pszClassOrigin, bool lFlag)
|
|
{
|
|
HRESULT hr = WBEM_E_INVALID_SYNTAX;
|
|
BSTR strType = NULL;
|
|
// Get the Type of the property
|
|
if(SUCCEEDED(hr = GetBstrAttribute(pXML, g_strType, &strType)))
|
|
{
|
|
// Get the Value (VALUE.ARRAY) of the Property - this value is optional
|
|
// Hence we dont check for return values
|
|
IXMLDOMElement *pValueArrayNode = NULL;
|
|
GetFirstImmediateElement(pXML, &pValueArrayNode, VALUEARRAY_TAG);
|
|
|
|
if(_wcsicmp(strType, L"boolean") == 0)
|
|
hr = MapStringArrayValue(pszName, pObj, pValueArrayNode, CIM_BOOLEAN, pszClassOrigin, lFlag);
|
|
else if(_wcsicmp(strType, L"string") == 0)
|
|
hr = MapStringArrayValue(pszName, pObj, pValueArrayNode, CIM_STRING, pszClassOrigin, lFlag);
|
|
else if(_wcsicmp(strType, L"char16") == 0)
|
|
hr = MapStringArrayValue(pszName, pObj, pValueArrayNode, CIM_CHAR16, pszClassOrigin, lFlag);
|
|
else if(_wcsicmp(strType, L"uint8") == 0)
|
|
hr = MapStringArrayValue(pszName, pObj, pValueArrayNode, CIM_UINT8, pszClassOrigin, lFlag);
|
|
else if(_wcsicmp(strType, L"sint8") == 0)
|
|
hr = MapStringArrayValue(pszName, pObj, pValueArrayNode, CIM_SINT8, pszClassOrigin, lFlag);
|
|
else if(_wcsicmp(strType, L"uint16") == 0)
|
|
hr = MapStringArrayValue(pszName, pObj, pValueArrayNode, CIM_UINT16, pszClassOrigin, lFlag);
|
|
else if(_wcsicmp(strType, L"sint16") == 0)
|
|
hr = MapStringArrayValue(pszName, pObj, pValueArrayNode, CIM_SINT16, pszClassOrigin, lFlag);
|
|
else if(_wcsicmp(strType, L"uint32") == 0)
|
|
hr = MapStringArrayValue(pszName, pObj, pValueArrayNode, CIM_UINT32, pszClassOrigin, lFlag);
|
|
else if(_wcsicmp(strType, L"sint32") == 0)
|
|
hr = MapStringArrayValue(pszName, pObj, pValueArrayNode, CIM_SINT32, pszClassOrigin, lFlag);
|
|
else if(_wcsicmp(strType, L"uint64") == 0)
|
|
hr = MapStringArrayValue(pszName, pObj, pValueArrayNode, CIM_UINT64, pszClassOrigin, lFlag);
|
|
else if(_wcsicmp(strType, L"sint64") == 0)
|
|
hr = MapStringArrayValue(pszName, pObj, pValueArrayNode, CIM_SINT64, pszClassOrigin, lFlag);
|
|
else if(_wcsicmp(strType, L"datetime") == 0)
|
|
hr = MapStringArrayValue(pszName, pObj, pValueArrayNode, CIM_DATETIME, pszClassOrigin, lFlag);
|
|
else if(_wcsicmp(strType, L"real32") == 0)
|
|
hr = MapStringArrayValue(pszName, pObj, pValueArrayNode, CIM_REAL32, pszClassOrigin, lFlag);
|
|
else if(_wcsicmp(strType, L"real64") == 0)
|
|
hr = MapStringArrayValue(pszName, pObj, pValueArrayNode, CIM_REAL64, pszClassOrigin, lFlag);
|
|
else
|
|
hr = WBEM_E_INVALID_PROPERTY;
|
|
|
|
// Release he optional VALUE.ARRAY node
|
|
if(pValueArrayNode)
|
|
pValueArrayNode->Release();
|
|
|
|
SysFreeString(strType);
|
|
}
|
|
else
|
|
hr = WBEM_E_INVALID_SYNTAX;
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CXml2Wmi::CreateReferenceProperty(LPCWSTR pszName, _IWmiFreeFormObject *pObj, IXMLDOMElement *pXML, LPCWSTR pszClassOrigin, bool bMakeInstance)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
IXMLDOMNodeList *pNodeList = NULL;
|
|
long lFlag = (bMakeInstance) ? WMIOBJECT_FREEFORM_FLAG_WRITE_TO_INSTANCE : 0;
|
|
|
|
// We will be getting a PROPERTY.REFERENCE into this function
|
|
// Besides having the optional REFERENCECLASS attribute which identifies the
|
|
// class whose reference it is, it can also have a VALUE.REFERENCE sub element
|
|
// As per the free form object interfaces, we can add a reference property only
|
|
// as a weak-reference and later we have to use IWbemClassObject to get the qualifiers
|
|
// and set the correct reference class name to make it a strog type
|
|
|
|
// See if there is a VALUE.REFERENCE child element
|
|
IXMLDOMElement *pValueRef = NULL;
|
|
if(SUCCEEDED(hr = GetFirstImmediateElement(pXML, &pValueRef, L"VALUE.REFERENCE")))
|
|
{
|
|
BSTR strRefValue = NULL;
|
|
BOOL bUseSysFreeString = FALSE;
|
|
if(SUCCEEDED(GetSingleRefValue(pValueRef, &strRefValue, bUseSysFreeString)))
|
|
{
|
|
hr = pObj->AddProperty(pszName, lFlag, wcslen(strRefValue)*2 + 1, 1, CIM_REFERENCE, strRefValue);
|
|
|
|
// Only in the MapClassName() case a BSTR is allocated. In the others it is an LPWSTR
|
|
if (bUseSysFreeString)
|
|
SysFreeString(strRefValue);
|
|
else
|
|
delete [] strRefValue;
|
|
}
|
|
pValueRef->Release();
|
|
}
|
|
else // Add the property without a default value
|
|
hr = pObj->AddProperty(pszName, lFlag, 0, 0, CIM_REFERENCE, NULL);
|
|
|
|
|
|
return hr;
|
|
}
|
|
|
|
// In this function, we expect to get a VALUE.REFERENCE element
|
|
// and will convert it to a WMI Objectpath or objectname
|
|
HRESULT CXml2Wmi::GetSingleRefValue(IXMLDOMElement *pValueRef, BSTR *pstrValue, BOOL &bUseSysFreeString)
|
|
{
|
|
HRESULT hr = WBEM_E_INVALID_SYNTAX;
|
|
bUseSysFreeString = FALSE;
|
|
// Check the child nodes of this to see if it is a CLASSPATH, LOCALCLASSPATH,
|
|
// INSTANCEPATH, LOCALINSTANCEPATH, CLASSNAME or INSTANCENAME
|
|
// or even a VALUE (for Scoped and UMI paths)
|
|
IXMLDOMNodeList *pNodeList = NULL;
|
|
if (pValueRef && SUCCEEDED(pValueRef->get_childNodes (&pNodeList)) && pNodeList)
|
|
{
|
|
long length = 0;
|
|
if (SUCCEEDED(pNodeList->get_length (&length)) && (1 == length))
|
|
{
|
|
IXMLDOMNode *pValue = NULL;
|
|
if (SUCCEEDED(pValueRef->get_firstChild (&pValue)))
|
|
{
|
|
// Next node could be a CLASSPATH, LOCALCLASSPATH, INSTANCEPATH,
|
|
// LOCALINSTANCEPATH, CLASSNAME or INSTANCENAME or even a VALUE (for Scoped and UMI paths)
|
|
BSTR strNodeName = NULL;
|
|
if(SUCCEEDED(pValue->get_nodeName(&strNodeName)))
|
|
{
|
|
*pstrValue = NULL;
|
|
if (_wcsicmp(strNodeName, CLASSNAME_TAG) == 0)
|
|
{
|
|
hr = MapClassName (pValue, pstrValue);
|
|
bUseSysFreeString = TRUE;
|
|
}
|
|
else if (_wcsicmp(strNodeName, LOCALCLASSPATH_TAG) == 0)
|
|
{
|
|
hr = MapLocalClassPath (pValue, pstrValue);
|
|
}
|
|
else if (_wcsicmp(strNodeName, CLASSPATH_TAG) == 0)
|
|
{
|
|
hr = MapClassPath (pValue, pstrValue);
|
|
}
|
|
else if (_wcsicmp(strNodeName, INSTANCENAME_TAG) == 0)
|
|
{
|
|
hr = MapInstanceName (pValue, pstrValue);
|
|
}
|
|
else if (_wcsicmp(strNodeName, LOCALINSTANCEPATH_TAG) == 0)
|
|
{
|
|
hr = MapLocalInstancePath (pValue, pstrValue);
|
|
}
|
|
else if (_wcsicmp(strNodeName, INSTANCEPATH_TAG) == 0)
|
|
{
|
|
hr = MapInstancePath (pValue, pstrValue);
|
|
}
|
|
else if (_wcsicmp(strNodeName, VALUE_TAG) == 0)
|
|
{
|
|
// Just get its contents
|
|
// RAJESHR - what if it is escaped CDATA? We need to unescape it
|
|
hr = pValue->get_text(pstrValue);
|
|
}
|
|
|
|
SysFreeString(strNodeName);
|
|
}
|
|
pValue->Release ();
|
|
}
|
|
}
|
|
pNodeList->Release ();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CXml2Wmi::CreateRefArrayProperty(LPCWSTR pszName, _IWmiFreeFormObject *pObj, IXMLDOMElement *pXML, LPCWSTR pszClassOrigin, bool bMakeInstance)
|
|
{
|
|
HRESULT hr = WBEM_E_INVALID_SYNTAX;
|
|
IXMLDOMNodeList *pNodeList = NULL;
|
|
long lFlag = (bMakeInstance) ? WMIOBJECT_FREEFORM_FLAG_WRITE_TO_INSTANCE : 0;
|
|
|
|
// We will be getting a PROPERTY.REFARRAY into this function
|
|
// Besides having the optional REFERENCECLASS attribute which identifies the
|
|
// class whose reference it is, it can also have a VALUE.REFARRAY sub element
|
|
// As per the free form object interfaces, we can add a reference property only
|
|
// as a weak-reference and later we have to use IWbemClassObject to get the qualifiers
|
|
// and set the correct reference class name to make it a strog type
|
|
|
|
// See if there is a VALUE.REFARRAY child element
|
|
IXMLDOMElement *pValueRefArray = NULL;
|
|
if(SUCCEEDED(GetFirstImmediateElement(pXML, &pValueRefArray, L"VALUE.REFARRAY")))
|
|
{
|
|
// GO thru each of its children looking for a VALUE.REFERENCE element
|
|
IXMLDOMNodeList *pNodeList = NULL;
|
|
if (SUCCEEDED(hr = pXML->get_childNodes (&pNodeList)))
|
|
{
|
|
// We need to create here, a single BSTR with NULL separated values,
|
|
// as required by the free-form object
|
|
// Allocate the string, we assume that the maximum length required is less
|
|
// than the length of the XML under this element
|
|
BSTR strTotalValue = NULL;
|
|
if(SUCCEEDED(hr = pXML->get_xml(&strTotalValue)))
|
|
{
|
|
UINT uLen = SysStringLen(strTotalValue);
|
|
SysFreeString(strTotalValue); // Free it immediately - we just wanted its length
|
|
LPWSTR pszFinalValue = NULL;
|
|
if(pszFinalValue = new WCHAR[uLen])
|
|
{
|
|
UINT uNextStart = 0;
|
|
pszFinalValue[0] = NULL;
|
|
|
|
IXMLDOMNode *pNode = NULL;
|
|
int i=0;
|
|
while (SUCCEEDED(hr) && SUCCEEDED(pNodeList->nextNode (&pNode)) && pNode )
|
|
{
|
|
BSTR strNodeName = NULL;
|
|
if (SUCCEEDED(hr = pNode->get_nodeName (&strNodeName)))
|
|
{
|
|
if(_wcsicmp(strNodeName, L"VALUE.REFERENCE") == 0)
|
|
{
|
|
IXMLDOMElement *pValueElement = NULL;
|
|
if(SUCCEEDED(hr = pNode->QueryInterface(IID_IXMLDOMElement, (LPVOID *)&pValueElement)))
|
|
{
|
|
BSTR strRefValue = NULL;
|
|
BOOL bUseSysFreeString = FALSE;
|
|
if(SUCCEEDED(hr = GetSingleRefValue(pValueElement, &strRefValue, bUseSysFreeString)))
|
|
{
|
|
// Concatenate it to the string of null-separated values we are building up
|
|
wcscat(pszFinalValue+uNextStart, strRefValue);
|
|
|
|
// Add a NULL separator
|
|
uNextStart += wcslen(strRefValue);
|
|
pszFinalValue[uNextStart++] = NULL;
|
|
|
|
// Only in the MapClassName() case a BSTR is allocated. In the others it is an LPWSTR
|
|
if (bUseSysFreeString)
|
|
SysFreeString(strRefValue);
|
|
else
|
|
delete [] strRefValue;
|
|
}
|
|
pValueElement->Release();
|
|
}
|
|
}
|
|
SysFreeString(strNodeName);
|
|
}
|
|
pNode->Release();
|
|
pNode = NULL;
|
|
}
|
|
|
|
if(SUCCEEDED(hr))
|
|
hr = pObj->AddProperty(pszName, lFlag, uNextStart, 1, CIM_REFERENCE|CIM_FLAG_ARRAY, pszFinalValue);
|
|
else
|
|
hr = WBEM_E_INVALID_SYNTAX;
|
|
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
pNodeList->Release();
|
|
}
|
|
pValueRefArray->Release();
|
|
}
|
|
else // Add the property without a default value
|
|
hr = pObj->AddProperty(pszName, lFlag, 0, 0, CIM_REFERENCE | CIM_FLAG_ARRAY, NULL);
|
|
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CXml2Wmi::GetSingleObject(IXMLDOMElement *pValueObject, _IWmiObject **ppEmbeddedObject)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
if (pValueObject)
|
|
{
|
|
// Check the child nodes of this to see if it is a CLASS or INSTANCE
|
|
IXMLDOMNode *pValue = NULL;
|
|
if (SUCCEEDED(hr = pValueObject->get_firstChild (&pValue)))
|
|
{
|
|
// Get the IXMLDOMElement interface
|
|
IXMLDOMElement *pElement = NULL;
|
|
if(SUCCEEDED(hr = pValue->QueryInterface(IID_IXMLDOMElement, (LPVOID *)&pElement)))
|
|
{
|
|
// Next node could be a CLASS or INSTANCE
|
|
BSTR strNodeName = NULL;
|
|
if(SUCCEEDED(hr = pElement->get_nodeName(&strNodeName)))
|
|
{
|
|
IWbemClassObject *pWmiObject = NULL;
|
|
if (_wcsicmp(strNodeName, CLASS_TAG) == 0)
|
|
hr = MapClass (pElement, &pWmiObject, NULL, NULL, false, true);
|
|
else if (_wcsicmp(strNodeName, INSTANCE_TAG) == 0)
|
|
hr = MapInstance (pElement, &pWmiObject, NULL, NULL, true);
|
|
else
|
|
hr = WBEM_E_INVALID_SYNTAX;
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
*ppEmbeddedObject = NULL;
|
|
hr = pWmiObject->QueryInterface(IID__IWmiObject, (LPVOID *)ppEmbeddedObject);
|
|
pWmiObject->Release();
|
|
}
|
|
|
|
SysFreeString(strNodeName);
|
|
}
|
|
pElement->Release();
|
|
}
|
|
pValue->Release ();
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CXml2Wmi::CreateObjectProperty(LPCWSTR pszName, _IWmiFreeFormObject *pObj, IXMLDOMElement *pXML, LPCWSTR pszClassOrigin, bool bMakeInstance)
|
|
{
|
|
HRESULT hr = WBEM_E_INVALID_SYNTAX;
|
|
IXMLDOMNodeList *pNodeList = NULL;
|
|
long lFlag = (bMakeInstance) ? WMIOBJECT_FREEFORM_FLAG_WRITE_TO_INSTANCE : 0;
|
|
|
|
// We will be getting a PROPERTY.OBJECT into this function
|
|
// Besides having the optional REFERENCECLASS attribute which identifies the
|
|
// class whose embedded object it is, it can also have a VALUE.OBJECT sub element
|
|
// As per the free form object interfaces, we can add an embedded object property property only
|
|
// as a weak-reference and later we have to use IWbemClassObject to get the qualifiers
|
|
// and set the correct class name to make it a strong type
|
|
|
|
// See if there is a VALUE.OBJECT child element
|
|
IXMLDOMElement *pValueObject = NULL;
|
|
if(SUCCEEDED(hr = GetFirstImmediateElement(pXML, &pValueObject, L"VALUE.OBJECT")))
|
|
{
|
|
_IWmiObject *pEmbeddedObject = NULL;
|
|
if(SUCCEEDED(hr = GetSingleObject(pValueObject, &pEmbeddedObject)))
|
|
{
|
|
// Set the Property
|
|
hr = pObj->AddProperty(pszName, lFlag, sizeof(_IWmiObject *), 1, CIM_OBJECT, &pEmbeddedObject);
|
|
pEmbeddedObject->Release();
|
|
}
|
|
pValueObject->Release();
|
|
}
|
|
else // Add the property without a default value
|
|
hr = pObj->AddProperty(pszName, lFlag, 0, 0, CIM_OBJECT, NULL);
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CXml2Wmi::CreateObjectArrayProperty(LPCWSTR pszName, _IWmiFreeFormObject *pObj, IXMLDOMElement *pXML, LPCWSTR pszClassOrigin, bool bMakeInstance)
|
|
{
|
|
HRESULT hr = WBEM_E_INVALID_SYNTAX;
|
|
IXMLDOMNodeList *pNodeList = NULL;
|
|
long lFlag = (bMakeInstance) ? WMIOBJECT_FREEFORM_FLAG_WRITE_TO_INSTANCE : 0;
|
|
|
|
// We will be getting a PROPERTY.OBJECTARRAY into this function
|
|
// Besides having the optional REFERENCECLASS attribute which identifies the
|
|
// class whose reference it is, it can also have a VALUE.OBJECTARRAY sub element
|
|
// As per the free form object interfaces, we can add an object property only
|
|
// as a weak-reference and later we have to use IWbemClassObject to get the qualifiers
|
|
// and set the correct reference class name to make it a strong type
|
|
|
|
// See if there is a VALUE.OBJECTARRAY child element
|
|
IXMLDOMElement *pValueObjArray = NULL;
|
|
if(SUCCEEDED(hr = GetFirstImmediateElement(pXML, &pValueObjArray, L"VALUE.OBJECTARRAY")))
|
|
{
|
|
// GO thru each of its children looking for a VALUE.OBJECT element
|
|
IXMLDOMNodeList *pNodeList = NULL;
|
|
if (SUCCEEDED(pValueObjArray->get_childNodes (&pNodeList)))
|
|
{
|
|
// As per the free-form interface, at this point, we need to Create an
|
|
// array of _IWmiFreeFormObject here, so we need to know the array length
|
|
// Get the number of child elements - this should be the lenght of the array required
|
|
LONG lArraylength = 0;
|
|
pNodeList->get_length (&lArraylength);
|
|
|
|
_IWmiObject **ppObjects = NULL;
|
|
if(ppObjects = new _IWmiObject *[lArraylength])
|
|
{
|
|
IXMLDOMNode *pNode = NULL;
|
|
LONG i=0;
|
|
while (SUCCEEDED(hr) && SUCCEEDED(pNodeList->nextNode (&pNode)) &&pNode)
|
|
{
|
|
BSTR strNodeName = NULL;
|
|
if (SUCCEEDED(pNode->get_nodeName (&strNodeName)))
|
|
{
|
|
if(_wcsicmp(strNodeName, L"VALUE.OBJECT") == 0)
|
|
{
|
|
IXMLDOMElement *pValueElement = NULL;
|
|
if(SUCCEEDED(hr = pNode->QueryInterface(IID_IXMLDOMElement, (LPVOID *)&pValueElement)))
|
|
{
|
|
if(SUCCEEDED(hr = GetSingleObject(pValueElement, &ppObjects[i])))
|
|
i++;
|
|
pValueElement->Release();
|
|
}
|
|
}
|
|
SysFreeString(strNodeName);
|
|
}
|
|
pNode->Release();
|
|
pNode = NULL;
|
|
}
|
|
|
|
// Add the property to the object
|
|
if(SUCCEEDED(hr))
|
|
hr = pObj->AddProperty(pszName, lFlag, sizeof(_IWmiObject *)*lArraylength, lArraylength, CIM_OBJECT|CIM_FLAG_ARRAY, *ppObjects);
|
|
else
|
|
hr = WBEM_E_INVALID_SYNTAX;
|
|
|
|
// Release all the objects in the array
|
|
for(LONG j=0; j<i; j++)
|
|
ppObjects[j]->Release();
|
|
delete [] ppObjects;
|
|
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
pNodeList->Release();
|
|
}
|
|
pValueObjArray->Release();
|
|
}
|
|
else // Add the property without a default value
|
|
hr = pObj->AddProperty(pszName, lFlag, 0, 0, CIM_OBJECT|CIM_FLAG_ARRAY, NULL);
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
HRESULT CXml2Wmi::GetBstrAttribute(IXMLDOMNode *pNode, const BSTR strAttributeName, BSTR *pstrAttributeValue)
|
|
{
|
|
HRESULT result = E_FAIL;
|
|
*pstrAttributeValue = NULL;
|
|
|
|
IXMLDOMElement *pElement = NULL;
|
|
if(SUCCEEDED(result = pNode->QueryInterface(IID_IXMLDOMElement, (LPVOID *)&pElement)))
|
|
{
|
|
VARIANT var;
|
|
VariantInit(&var);
|
|
if(SUCCEEDED(result = pElement->getAttribute(strAttributeName, &var)))
|
|
{
|
|
if(var.bstrVal)
|
|
{
|
|
*pstrAttributeValue = var.bstrVal;
|
|
var.bstrVal = NULL;
|
|
// No need to clear the variant since we took over its memory
|
|
}
|
|
else
|
|
result = E_FAIL;
|
|
}
|
|
pElement->Release();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
HRESULT CXml2Wmi::GetFirstImmediateElement(IXMLDOMNode *pParent, IXMLDOMElement **ppChildElement, LPCWSTR pszName)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
// Now cycle thru the children
|
|
IXMLDOMNodeList *pNodeList = NULL;
|
|
BOOL bFound = FALSE;
|
|
if (SUCCEEDED(hr = pParent->get_childNodes (&pNodeList)))
|
|
{
|
|
IXMLDOMNode *pNode = NULL;
|
|
while (!bFound && SUCCEEDED(pNodeList->nextNode (&pNode)) && pNode)
|
|
{
|
|
// Get the name of the child
|
|
BSTR strNodeName = NULL;
|
|
if (SUCCEEDED(hr = pNode->get_nodeName (&strNodeName)))
|
|
{
|
|
// We're interested only in PROPERTIES at this point
|
|
if(_wcsicmp(strNodeName, pszName) == 0)
|
|
{
|
|
*ppChildElement = NULL;
|
|
hr = pNode->QueryInterface(IID_IXMLDOMElement, (LPVOID *)ppChildElement);
|
|
bFound = TRUE;
|
|
}
|
|
SysFreeString(strNodeName);
|
|
}
|
|
pNode->Release();
|
|
pNode = NULL;
|
|
}
|
|
pNodeList->Release();
|
|
}
|
|
|
|
if(bFound)
|
|
return hr;
|
|
return E_FAIL;
|
|
}
|
|
|
|
|
|
HRESULT CXml2Wmi::MapClassName (IXMLDOMNode *pNode, BSTR *pstrXML)
|
|
{
|
|
*pstrXML = NULL;
|
|
return GetBstrAttribute(pNode, g_strName, pstrXML);
|
|
}
|
|
|
|
|
|
HRESULT CXml2Wmi::MapLocalClassPath (IXMLDOMNode *pNode, LPWSTR *ppszClassPath)
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
|
|
// We expect a LOCALNAMESPACEPATH followed by CLASSNAME
|
|
IXMLDOMNodeList *pNodeList = NULL;
|
|
if (pNode && SUCCEEDED(hr = pNode->get_childNodes (&pNodeList)) && pNodeList)
|
|
{
|
|
IXMLDOMNode *pLocalNSPathNode = NULL;
|
|
// Next node should be a LOCALNAMESPACEPATH
|
|
if (SUCCEEDED(hr = pNodeList->nextNode (&pLocalNSPathNode)) && pLocalNSPathNode)
|
|
{
|
|
BSTR strNSNodeName = NULL;
|
|
if (SUCCEEDED(hr = pLocalNSPathNode->get_nodeName(&strNSNodeName)) &&
|
|
strNSNodeName )
|
|
{
|
|
if(_wcsicmp(strNSNodeName, LOCALNAMESPACEPATH_TAG) == 0)
|
|
{
|
|
LPWSTR pszLocalNamespace = NULL;
|
|
if(SUCCEEDED(hr = ParseLocalNamespacePath(pLocalNSPathNode, &pszLocalNamespace)))
|
|
{
|
|
// Next node should be the classname
|
|
IXMLDOMNode *pClassNameNode = NULL;
|
|
if (SUCCEEDED(hr = pNodeList->nextNode (&pClassNameNode)) && pClassNameNode)
|
|
{
|
|
BSTR strNSClassName = NULL;
|
|
if (SUCCEEDED(hr = pClassNameNode->get_nodeName(&strNSClassName)) &&
|
|
strNSClassName )
|
|
{
|
|
if (_wcsicmp(strNSClassName, CLASSNAME_TAG) == 0)
|
|
{
|
|
BSTR strClassName = NULL;
|
|
if (SUCCEEDED(hr = GetBstrAttribute (pClassNameNode,
|
|
g_strName, &strClassName)))
|
|
{
|
|
// Phew - finally we have all the info!
|
|
|
|
*ppszClassPath = NULL;
|
|
if((*ppszClassPath) = new WCHAR [wcslen(pszLocalNamespace)
|
|
+ wcslen(strClassName) + 2])
|
|
{
|
|
wcscpy (*ppszClassPath, pszLocalNamespace);
|
|
wcscat (*ppszClassPath, L":");
|
|
wcscat (*ppszClassPath, strClassName);
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
|
|
SysFreeString (strClassName);
|
|
}
|
|
}
|
|
else
|
|
hr = WBEM_E_INVALID_SYNTAX;
|
|
|
|
SysFreeString (strNSClassName);
|
|
}
|
|
pClassNameNode->Release ();
|
|
}
|
|
delete [] pszLocalNamespace;
|
|
}
|
|
}
|
|
else
|
|
hr = WBEM_E_INVALID_SYNTAX;
|
|
SysFreeString (strNSNodeName);
|
|
}
|
|
pLocalNSPathNode->Release ();
|
|
}
|
|
|
|
pNodeList->Release ();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CXml2Wmi::MapClassPath (IXMLDOMNode *pNode, LPWSTR *ppszClassPath)
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
|
|
// We expect a NAMESPACEPATH followed by CLASSNAME
|
|
IXMLDOMNodeList *pNodeList = NULL;
|
|
if (pNode && SUCCEEDED(pNode->get_childNodes (&pNodeList)) && pNodeList)
|
|
{
|
|
IXMLDOMNode *pNSPathNode = NULL;
|
|
|
|
// Next node should be a NAMESPACEPATH
|
|
if (SUCCEEDED(pNodeList->nextNode (&pNSPathNode)) && pNSPathNode)
|
|
{
|
|
BSTR strNSNodeName = NULL;
|
|
|
|
if (SUCCEEDED(pNSPathNode->get_nodeName(&strNSNodeName)) && strNSNodeName)
|
|
{
|
|
if(_wcsicmp(strNSNodeName, NAMESPACEPATH_TAG) == 0)
|
|
{
|
|
BSTR strHost = NULL;
|
|
LPWSTR pszNamespace = NULL;
|
|
|
|
if (SUCCEEDED (hr = ParseNamespacePath(pNSPathNode, &strHost, &pszNamespace)))
|
|
{
|
|
// Next node should be the CLASSNAME
|
|
IXMLDOMNode *pClassNameNode = NULL;
|
|
|
|
if (SUCCEEDED(pNodeList->nextNode (&pClassNameNode)) && pClassNameNode)
|
|
{
|
|
BSTR strNSClassName = NULL;
|
|
|
|
if (SUCCEEDED(pClassNameNode->get_nodeName(&strNSClassName)) && strNSClassName)
|
|
{
|
|
if (_wcsicmp(strNSClassName, CLASSNAME_TAG) == 0)
|
|
{
|
|
BSTR strClassName = NULL;
|
|
|
|
if (SUCCEEDED(GetBstrAttribute (pClassNameNode,
|
|
g_strName, &strClassName)))
|
|
{
|
|
// Phew - finally we have all the info!
|
|
|
|
*ppszClassPath = NULL;
|
|
if((*ppszClassPath) = new WCHAR [wcslen(strHost)
|
|
+ wcslen(pszNamespace) + wcslen(strClassName) + 5])
|
|
{
|
|
wcscpy (*ppszClassPath, L"\\\\");
|
|
wcscat (*ppszClassPath, strHost);
|
|
wcscat (*ppszClassPath, L"\\");
|
|
wcscat (*ppszClassPath, pszNamespace);
|
|
wcscat (*ppszClassPath, L":");
|
|
wcscat (*ppszClassPath, strClassName);
|
|
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
SysFreeString (strClassName);
|
|
}
|
|
}
|
|
else
|
|
hr = WBEM_E_INVALID_SYNTAX;
|
|
|
|
SysFreeString (strNSClassName);
|
|
}
|
|
|
|
pClassNameNode->Release ();
|
|
}
|
|
|
|
SysFreeString (strHost);
|
|
delete [] pszNamespace;
|
|
}
|
|
}
|
|
else
|
|
hr = WBEM_E_INVALID_SYNTAX;
|
|
|
|
SysFreeString (strNSNodeName);
|
|
}
|
|
pNSPathNode->Release ();
|
|
}
|
|
pNodeList->Release ();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// HRESULT CXml2Wmi::MapInstanceName
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Maps an XML INSTANCENAME element into its WMI VARIANT equivalent form
|
|
//
|
|
// PARAMETERS:
|
|
//
|
|
// pNode XML element node
|
|
// curValue Placeholder for new value (set on return)
|
|
//
|
|
// RETURN VALUES:
|
|
//
|
|
//
|
|
//***************************************************************************
|
|
HRESULT CXml2Wmi::MapInstanceName (IXMLDOMNode *pNode, LPWSTR *ppszInstanceName)
|
|
{
|
|
return ParseInstanceName(pNode, ppszInstanceName);
|
|
}
|
|
|
|
HRESULT CXml2Wmi::MapLocalInstancePath (IXMLDOMNode *pNode, LPWSTR *ppszInstancePath)
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
|
|
// Expecting (LOCALNAMESPACEPATH followed by INSTANCENAME
|
|
IXMLDOMNodeList *pNodeList = NULL;
|
|
|
|
if (pNode && SUCCEEDED(pNode->get_childNodes (&pNodeList)) && pNodeList)
|
|
{
|
|
IXMLDOMNode *pLocalNSPathNode = NULL;
|
|
|
|
// Next node should be a LOCALNAMESPACEPATH
|
|
if (SUCCEEDED(pNodeList->nextNode (&pLocalNSPathNode)) && pLocalNSPathNode)
|
|
{
|
|
BSTR strNSNodeName = NULL;
|
|
|
|
if (SUCCEEDED(pLocalNSPathNode->get_nodeName(&strNSNodeName)) && strNSNodeName )
|
|
{
|
|
if (_wcsicmp(strNSNodeName, LOCALNAMESPACEPATH_TAG) == 0)
|
|
{
|
|
LPWSTR pszLocalNamespace = NULL;
|
|
if(SUCCEEDED(ParseLocalNamespacePath(pLocalNSPathNode, &pszLocalNamespace)))
|
|
{
|
|
// Next node should be the INSTANCENAME
|
|
IXMLDOMNode *pInstanceNameNode = NULL;
|
|
if (SUCCEEDED(pNodeList->nextNode (&pInstanceNameNode)) && pInstanceNameNode)
|
|
{
|
|
BSTR strNSInstanceName = NULL;
|
|
if (SUCCEEDED(pInstanceNameNode->get_nodeName(&strNSInstanceName)) &&
|
|
strNSInstanceName && (_wcsicmp(strNSInstanceName, INSTANCENAME_TAG) == 0))
|
|
{
|
|
LPWSTR pszInstanceName = NULL;
|
|
if (SUCCEEDED(hr = ParseInstanceName (pInstanceNameNode,
|
|
&pszInstanceName)))
|
|
{
|
|
// Phew - finally we have all the info!
|
|
|
|
*ppszInstancePath = NULL;
|
|
if((*ppszInstancePath) = new WCHAR [wcslen(pszLocalNamespace)
|
|
+ wcslen(pszInstanceName) + 2])
|
|
{
|
|
wcscpy (*ppszInstancePath, pszLocalNamespace);
|
|
wcscat (*ppszInstancePath, L":");
|
|
wcscat (*ppszInstancePath, pszInstanceName);
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
delete [] pszInstanceName;
|
|
}
|
|
|
|
SysFreeString (strNSInstanceName);
|
|
}
|
|
pInstanceNameNode->Release ();
|
|
}
|
|
delete [] pszLocalNamespace;
|
|
}
|
|
}
|
|
else
|
|
hr = WBEM_E_INVALID_SYNTAX;
|
|
SysFreeString (strNSNodeName);
|
|
}
|
|
|
|
pLocalNSPathNode->Release ();
|
|
}
|
|
pNodeList->Release ();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CXml2Wmi::MapInstancePath (IXMLDOMNode *pNode, LPWSTR *ppXML)
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
|
|
// Expecting NAMESPACEPATH followed by INSTANCENAME
|
|
IXMLDOMNodeList *pNodeList = NULL;
|
|
if (pNode && SUCCEEDED(pNode->get_childNodes (&pNodeList)) && pNodeList)
|
|
{
|
|
IXMLDOMNode *pNSPathNode = NULL;
|
|
// Next node should be a NAMESPACEPATH
|
|
if (SUCCEEDED(pNodeList->nextNode (&pNSPathNode)) && pNSPathNode)
|
|
{
|
|
BSTR strNSNodeName = NULL;
|
|
if (SUCCEEDED(pNSPathNode->get_nodeName(&strNSNodeName)) && strNSNodeName )
|
|
{
|
|
if (_wcsicmp(strNSNodeName, NAMESPACEPATH_TAG) == 0)
|
|
{
|
|
BSTR strHost = NULL;
|
|
LPWSTR pszNamespace = NULL;
|
|
|
|
if (SUCCEEDED (ParseNamespacePath(pNSPathNode, &strHost, &pszNamespace)))
|
|
{
|
|
// Next node should be the INSTANCENAME
|
|
IXMLDOMNode *pInstanceNameNode = NULL;
|
|
if (SUCCEEDED(pNodeList->nextNode (&pInstanceNameNode)) && pInstanceNameNode)
|
|
{
|
|
BSTR strNSInstanceName = NULL;
|
|
if (SUCCEEDED(pInstanceNameNode->get_nodeName(&strNSInstanceName)) && strNSInstanceName )
|
|
{
|
|
if (_wcsicmp(strNSInstanceName, INSTANCENAME_TAG) == 0)
|
|
{
|
|
LPWSTR pszInstanceName = NULL;
|
|
|
|
if (SUCCEEDED(ParseInstanceName (pInstanceNameNode,
|
|
&pszInstanceName)))
|
|
{
|
|
// Phew - finally we have all the info!
|
|
|
|
*ppXML = NULL;
|
|
if((*ppXML) = new WCHAR [wcslen(strHost)
|
|
+ wcslen(pszNamespace) + wcslen(pszInstanceName) + 5])
|
|
{
|
|
wcscpy (*ppXML, L"\\\\");
|
|
wcscat (*ppXML, strHost);
|
|
wcscat (*ppXML, L"\\");
|
|
wcscat (*ppXML, pszNamespace);
|
|
wcscat (*ppXML, L":");
|
|
wcscat (*ppXML, pszInstanceName);
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
delete [] pszInstanceName;
|
|
}
|
|
}
|
|
else
|
|
hr = WBEM_E_INVALID_SYNTAX;
|
|
SysFreeString (strNSInstanceName);
|
|
}
|
|
|
|
pInstanceNameNode->Release ();
|
|
}
|
|
|
|
SysFreeString (strHost);
|
|
delete [] pszNamespace;
|
|
}
|
|
}
|
|
else
|
|
hr = WBEM_E_INVALID_SYNTAX;
|
|
SysFreeString (strNSNodeName);
|
|
}
|
|
pNSPathNode->Release ();
|
|
}
|
|
pNodeList->Release ();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CXml2Wmi::ParseLocalNamespacePath(IXMLDOMNode *pLocalNamespaceNode, LPWSTR *ppLocalNamespacePath)
|
|
{
|
|
// Go thru the children collecting the NAME attribute and concatenating
|
|
// This requires 2 passes since we dont know the length
|
|
//=============================================================
|
|
|
|
DWORD dwLength=0;
|
|
*ppLocalNamespacePath = NULL;
|
|
HRESULT result = E_FAIL;
|
|
|
|
IXMLDOMNodeList *pChildren = NULL;
|
|
if(SUCCEEDED(result = pLocalNamespaceNode->get_childNodes(&pChildren)))
|
|
{
|
|
IXMLDOMNode *pNextChild = NULL;
|
|
while(SUCCEEDED(pChildren->nextNode(&pNextChild)) && pNextChild)
|
|
{
|
|
BSTR strAttributeValue = NULL;
|
|
if(SUCCEEDED(GetBstrAttribute(pNextChild, g_strName, &strAttributeValue)) && strAttributeValue)
|
|
{
|
|
dwLength += wcslen(strAttributeValue);
|
|
dwLength ++; // For the back slash
|
|
SysFreeString(strAttributeValue);
|
|
}
|
|
pNextChild->Release();
|
|
pNextChild = NULL;
|
|
}
|
|
|
|
// Allocate memory
|
|
if(*ppLocalNamespacePath = new WCHAR[dwLength + 1])
|
|
{
|
|
(*ppLocalNamespacePath)[0] = 0;
|
|
|
|
// Once more, we make a pass thru the child nodes
|
|
pNextChild = NULL;
|
|
pChildren->reset();
|
|
while(SUCCEEDED(pChildren->nextNode(&pNextChild)) && pNextChild)
|
|
{
|
|
BSTR strAttributeValue = NULL;
|
|
if(SUCCEEDED(GetBstrAttribute(pNextChild, g_strName, &strAttributeValue)) && strAttributeValue)
|
|
{
|
|
wcscat(*ppLocalNamespacePath, strAttributeValue);
|
|
wcscat(*ppLocalNamespacePath, L"\\");
|
|
SysFreeString(strAttributeValue);
|
|
}
|
|
|
|
pNextChild->Release();
|
|
pNextChild = NULL;
|
|
}
|
|
|
|
// Remove the last back slash
|
|
(*ppLocalNamespacePath)[dwLength-1] = NULL;
|
|
result = S_OK;
|
|
}
|
|
else
|
|
result = E_OUTOFMEMORY;
|
|
pChildren->Release();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// Parse an instance name
|
|
HRESULT CXml2Wmi::ParseInstanceName(IXMLDOMNode *pNode, LPWSTR *ppszInstanceName)
|
|
{
|
|
HRESULT result = E_FAIL;
|
|
|
|
// First get the class name
|
|
BSTR strClassName = NULL;
|
|
if(SUCCEEDED(GetBstrAttribute(pNode, g_strClassName, &strClassName)))
|
|
{
|
|
// See if the child is a KEYBINDING or KEYVALUE
|
|
IXMLDOMNode *pChildNode = NULL;
|
|
if(SUCCEEDED(pNode->get_firstChild(&pChildNode)) && pChildNode)
|
|
{
|
|
BSTR strNodeName = NULL;
|
|
if(SUCCEEDED(result = pChildNode->get_nodeName(&strNodeName)))
|
|
{
|
|
// Look ahead
|
|
if(_wcsicmp(strNodeName, KEYBINDING_TAG) == 0)
|
|
{
|
|
result = ParseKeyBinding(pNode, strClassName, ppszInstanceName);
|
|
}
|
|
else if (_wcsicmp(strNodeName, KEYVALUE_TAG) == 0)
|
|
{
|
|
// This is case where a class has a single key property
|
|
LPWSTR pszValue = NULL;
|
|
if(SUCCEEDED(result = ParseKeyValue(pNode, &pszValue)))
|
|
{
|
|
*ppszInstanceName = NULL;
|
|
if((*ppszInstanceName) = new WCHAR[wcslen(strClassName) + wcslen(pszValue) + 2])
|
|
{
|
|
wcscpy(*ppszInstanceName, strClassName);
|
|
wcscat(*ppszInstanceName, EQUALS_SIGN);
|
|
wcscat(*ppszInstanceName, pszValue);
|
|
result = S_OK;
|
|
}
|
|
else
|
|
result = E_OUTOFMEMORY;
|
|
delete [] pszValue;
|
|
}
|
|
}
|
|
SysFreeString(strNodeName);
|
|
}
|
|
pChildNode->Release();
|
|
}
|
|
SysFreeString(strClassName);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
// Parse one KEYVALUE element
|
|
//
|
|
HRESULT CXml2Wmi::ParseKeyValue(IXMLDOMNode *pNode, LPWSTR *ppszValue)
|
|
{
|
|
HRESULT result = E_FAIL;
|
|
BSTR strType = NULL;
|
|
*ppszValue = NULL;
|
|
|
|
// There is the possibility of the optioanl VALUE_TYPE attribute
|
|
// The absence of this indicates a string value
|
|
BOOLEAN isString = FALSE;
|
|
if(SUCCEEDED(GetBstrAttribute(pNode, g_strValueType, &strType)))
|
|
{
|
|
if(_wcsicmp(strType, L"string") == 0) // Enclose it in double-quotes
|
|
isString = TRUE;
|
|
SysFreeString(strType);
|
|
}
|
|
else // It's a string by default
|
|
{
|
|
isString = TRUE;
|
|
}
|
|
|
|
if(isString) // Escape the appropriate characters and enclose it in double-quotes
|
|
{
|
|
// RAJESHR - What if there is a CDATA section here?
|
|
// In that case, we need to unescape the CDATA encoding before anything
|
|
BSTR strTemp = NULL;
|
|
if(SUCCEEDED(pNode->get_text(&strTemp)))
|
|
{
|
|
LPWSTR pszEscapedTemp = NULL;
|
|
if(pszEscapedTemp = EscapeSpecialCharacters(strTemp))
|
|
{
|
|
if((*ppszValue) = new WCHAR[wcslen(pszEscapedTemp) + 3])
|
|
{
|
|
wcscpy(*ppszValue, QUOTE_SIGN);
|
|
wcscat(*ppszValue, pszEscapedTemp);
|
|
wcscat(*ppszValue, QUOTE_SIGN);
|
|
result = S_OK;
|
|
}
|
|
else
|
|
result = E_OUTOFMEMORY;
|
|
delete [] pszEscapedTemp;
|
|
}
|
|
else
|
|
result = E_OUTOFMEMORY;
|
|
SysFreeString(strTemp);
|
|
}
|
|
}
|
|
else // BOOLEAN or Numeric
|
|
{
|
|
BSTR bstrVal = NULL;
|
|
if(SUCCEEDED(result = pNode->get_text(&bstrVal)))
|
|
{
|
|
if(*ppszValue = new WCHAR[wcslen(bstrVal) + 1])
|
|
wcscpy(*ppszValue, bstrVal);
|
|
else
|
|
result = E_OUTOFMEMORY;
|
|
SysFreeString(bstrVal);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// Parse one key binding. Return <propName>=<value>
|
|
HRESULT CXml2Wmi::ParseOneKeyBinding(IXMLDOMNode *pNode, LPWSTR *ppszValue)
|
|
{
|
|
HRESULT result = E_FAIL;
|
|
*ppszValue = NULL;
|
|
|
|
// First get the property name
|
|
BSTR strPropertyName = NULL;
|
|
if(SUCCEEDED(GetBstrAttribute(pNode, g_strName, &strPropertyName)))
|
|
{
|
|
// See if the child is a KEYVALUE or VALUE.REFERENCE
|
|
IXMLDOMNode *pChildNode = NULL;
|
|
if(SUCCEEDED(pNode->get_firstChild(&pChildNode)) && pChildNode)
|
|
{
|
|
BSTR strNodeName = NULL;
|
|
if(SUCCEEDED(pChildNode->get_nodeName(&strNodeName)))
|
|
{
|
|
// Look ahead
|
|
if(_wcsicmp(strNodeName, KEYVALUE_TAG) == 0)
|
|
{
|
|
LPWSTR pszValue = NULL;
|
|
if(SUCCEEDED(ParseKeyValue(pChildNode, &pszValue)))
|
|
{
|
|
// COncatenate them with an '=' inbetween
|
|
if(*ppszValue = new WCHAR [ wcslen(strPropertyName) + wcslen(pszValue) + 2])
|
|
{
|
|
wcscpy(*ppszValue, strPropertyName);
|
|
wcscat(*ppszValue, EQUALS_SIGN);
|
|
wcscat(*ppszValue, pszValue);
|
|
result = S_OK;
|
|
}
|
|
else
|
|
result = E_OUTOFMEMORY;
|
|
delete [] pszValue;
|
|
}
|
|
}
|
|
else if (_wcsicmp(strNodeName, VALUEREFERENCE_TAG) == 0)
|
|
{
|
|
IXMLDOMElement * pChildElement = NULL;
|
|
if(SUCCEEDED(pChildNode->QueryInterface(IID_IXMLDOMElement, (LPVOID *)&pChildElement)))
|
|
{
|
|
BSTR strRefValue = NULL;
|
|
BOOL bUseSysFreeString = FALSE;
|
|
if(SUCCEEDED(GetSingleRefValue(pChildElement, &strRefValue, bUseSysFreeString)))
|
|
{
|
|
if(SUCCEEDED(FormRefValueKeyBinding(ppszValue, strPropertyName, strRefValue)))
|
|
result = S_OK;
|
|
|
|
// Only in the MapClassName() case a BSTR is allocated. In the others it is an LPWSTR
|
|
if (bUseSysFreeString)
|
|
SysFreeString(strRefValue);
|
|
else
|
|
delete [] strRefValue;
|
|
}
|
|
pChildElement->Release();
|
|
}
|
|
}
|
|
SysFreeString(strNodeName);
|
|
}
|
|
pChildNode->Release();
|
|
}
|
|
SysFreeString(strPropertyName);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// Parse a KEY binding
|
|
HRESULT CXml2Wmi::ParseKeyBinding(IXMLDOMNode *pNode, BSTR strClassName, LPWSTR *ppszInstanceName)
|
|
{
|
|
HRESULT result = E_FAIL;
|
|
|
|
*ppszInstanceName = NULL;
|
|
if(!((*ppszInstanceName) = new WCHAR [ wcslen(strClassName) + 2]))
|
|
return E_OUTOFMEMORY;
|
|
|
|
wcscpy(*ppszInstanceName, strClassName);
|
|
wcscat(*ppszInstanceName, DOT_SIGN);
|
|
|
|
// Go thru each of the key bindings
|
|
//=======================================================
|
|
IXMLDOMNodeList *pBindings = NULL;
|
|
if(SUCCEEDED(pNode->get_childNodes(&pBindings)))
|
|
{
|
|
IXMLDOMNode *pNextBinding = NULL;
|
|
BOOL bError = FALSE;
|
|
while(!bError && SUCCEEDED(pBindings->nextNode(&pNextBinding)) && pNextBinding)
|
|
{
|
|
LPWSTR pszNextValue = NULL;
|
|
if(SUCCEEDED(ParseOneKeyBinding(pNextBinding, &pszNextValue)))
|
|
{
|
|
LPWSTR pTemp = NULL;
|
|
if(pTemp = new WCHAR [wcslen(*ppszInstanceName) + wcslen(pszNextValue) + 2])
|
|
{
|
|
wcscpy(pTemp, *ppszInstanceName);
|
|
wcscat(pTemp, pszNextValue);
|
|
wcscat(pTemp, COMMA_SIGN);
|
|
|
|
delete [] (*ppszInstanceName);
|
|
*ppszInstanceName = pTemp;
|
|
}
|
|
else
|
|
{
|
|
result = E_OUTOFMEMORY;
|
|
bError = TRUE;
|
|
}
|
|
|
|
delete [] pszNextValue;
|
|
}
|
|
else
|
|
bError = TRUE;
|
|
|
|
pNextBinding->Release();
|
|
pNextBinding = NULL;
|
|
}
|
|
|
|
if(!bError)
|
|
result = S_OK;
|
|
pBindings->Release();
|
|
}
|
|
|
|
if(SUCCEEDED(result))
|
|
{
|
|
// Get rid of the last comma
|
|
(*ppszInstanceName)[wcslen(*ppszInstanceName) - 1] = NULL;
|
|
}
|
|
else
|
|
{
|
|
delete [] (*ppszInstanceName);
|
|
*ppszInstanceName = NULL;
|
|
}
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
HRESULT CXml2Wmi::ParseNamespacePath(IXMLDOMNode *pLocalNamespaceNode, BSTR *pstrHost, LPWSTR *ppszLocalNamespace)
|
|
{
|
|
HRESULT result = E_FAIL;
|
|
|
|
*pstrHost = NULL;
|
|
*ppszLocalNamespace = NULL;
|
|
|
|
// Get the HOST name first
|
|
IXMLDOMNode *pFirstNode = NULL, *pSecondNode = NULL;
|
|
if(SUCCEEDED(pLocalNamespaceNode->get_firstChild(&pFirstNode)) && pFirstNode)
|
|
{
|
|
// Get the Namespace part
|
|
if(SUCCEEDED (pFirstNode->get_text(pstrHost)))
|
|
{
|
|
if(SUCCEEDED(pLocalNamespaceNode->get_lastChild(&pSecondNode)))
|
|
{
|
|
// Get the instance path
|
|
if(SUCCEEDED(ParseLocalNamespacePath(pSecondNode, ppszLocalNamespace)))
|
|
{
|
|
result = S_OK;
|
|
}
|
|
pSecondNode->Release();
|
|
}
|
|
}
|
|
pFirstNode->Release();
|
|
}
|
|
|
|
// In case the failure was in pasring the namespace,
|
|
// we need to make sure that the allocation for the host name
|
|
// is released
|
|
if(FAILED(result) && *pstrHost)
|
|
{
|
|
SysFreeString(*pstrHost);
|
|
*pstrHost = NULL;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// A function to escape newlines, tabs etc. from a property value
|
|
LPWSTR CXml2Wmi::EscapeSpecialCharacters(LPCWSTR strInputString)
|
|
{
|
|
// Escape all the quotes - This code taken from winmgmt\common\var.cpp
|
|
// ====================================================================
|
|
|
|
int nStrLen = wcslen(strInputString);
|
|
LPWSTR wszValue = NULL;
|
|
if(wszValue = new WCHAR[nStrLen*2+10])
|
|
{
|
|
LPWSTR pwc = wszValue;
|
|
for(int i = 0; i < (int)nStrLen; i++)
|
|
{
|
|
switch(strInputString[i])
|
|
{
|
|
case L'\n':
|
|
*(pwc++) = L'\\';
|
|
*(pwc++) = L'n';
|
|
break;
|
|
case L'\t':
|
|
*(pwc++) = L'\\';
|
|
*(pwc++) = L't';
|
|
break;
|
|
case L'"':
|
|
case L'\\':
|
|
*(pwc++) = L'\\';
|
|
*(pwc++) = strInputString[i];
|
|
break;
|
|
default:
|
|
*(pwc++) = strInputString[i];
|
|
break;
|
|
}
|
|
}
|
|
*pwc = 0;
|
|
}
|
|
return wszValue;
|
|
}
|
|
|
|
|
|
HRESULT CXml2Wmi::AddObjectQualifiers (
|
|
bool bAllowWMIExtensions,
|
|
IXMLDOMElement *pXml,
|
|
IWbemClassObject *pObject
|
|
)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
// Get the object qualifeir set
|
|
IWbemQualifierSet *pQuals = NULL;
|
|
if(FAILED(hr = pObject->GetQualifierSet(&pQuals)))
|
|
return hr;
|
|
|
|
// Add the object qualifiers and the property/Method qualifiers
|
|
// Cycle thru the child nodes looking for QUALIFIER, PROPERTY* or METHOD nodes
|
|
|
|
IXMLDOMNodeList *pNodeList = NULL;
|
|
if (SUCCEEDED(pXml->get_childNodes (&pNodeList)))
|
|
{
|
|
IXMLDOMNode *pNode = NULL;
|
|
bool bError = false;
|
|
while (!bError && SUCCEEDED(pNodeList->nextNode (&pNode)) && pNode)
|
|
{
|
|
BSTR strNodeName = NULL;
|
|
if (SUCCEEDED(pNode->get_nodeName (&strNodeName)))
|
|
{
|
|
// This one is an object qualifier
|
|
if(_wcsicmp(strNodeName, L"QUALIFIER") == 0)
|
|
{
|
|
if(FAILED(hr = AddQualifier(pNode, pQuals, true)))
|
|
bError = TRUE;
|
|
}
|
|
|
|
// This one is a property qualifier
|
|
// No need to add method qualifiers - we have already done them
|
|
else if(_wcsicmp(strNodeName, L"PROPERTY") == 0 ||
|
|
_wcsicmp(strNodeName, L"PROPERTY.ARRAY") == 0 ||
|
|
_wcsicmp(strNodeName, L"PROPERTY.REFERENCE") == 0 ||
|
|
_wcsicmp(strNodeName, L"PROPERTY.REFARRAY") == 0 ||
|
|
(_wcsicmp(strNodeName, L"PROPERTY.OBJECT") == 0 && bAllowWMIExtensions) ||
|
|
(_wcsicmp(strNodeName, L"PROPERTY.OBJECTARRAY") == 0 && bAllowWMIExtensions))
|
|
{
|
|
// Get the property name
|
|
BSTR strPropertyName = NULL;
|
|
if(SUCCEEDED(GetBstrAttribute(pNode, g_strName, &strPropertyName)))
|
|
{
|
|
if(_wcsnicmp(strPropertyName, L"__", 2) == 0)
|
|
{
|
|
// Ignore other system properties
|
|
}
|
|
else
|
|
{
|
|
IWbemQualifierSet *pPropSet = NULL;
|
|
if(SUCCEEDED(pObject->GetPropertyQualifierSet(strPropertyName, &pPropSet)))
|
|
{
|
|
if(FAILED(hr = AddElementQualifiers(pNode, pPropSet)))
|
|
bError = TRUE;
|
|
pPropSet->Release();
|
|
}
|
|
else
|
|
bError = TRUE;
|
|
}
|
|
SysFreeString(strPropertyName);
|
|
}
|
|
}
|
|
SysFreeString(strNodeName);
|
|
}
|
|
pNode->Release();
|
|
pNode = NULL;
|
|
}
|
|
|
|
if(bError)
|
|
{
|
|
// If hr does not indicate a failure, then we indicate
|
|
// a generic failure
|
|
if(SUCCEEDED(hr))
|
|
hr = WBEM_E_FAILED;
|
|
}
|
|
else
|
|
hr = S_OK;
|
|
pNodeList->Release();
|
|
}
|
|
pQuals->Release();
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CXml2Wmi::AddElementQualifiers (
|
|
IXMLDOMNode* pXml,
|
|
IWbemQualifierSet *pQuals
|
|
)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
// Cycle thru the child nodes looking for QUALIFIER nodes
|
|
IXMLDOMNodeList *pNodeList = NULL;
|
|
if (SUCCEEDED(pXml->get_childNodes (&pNodeList)))
|
|
{
|
|
IXMLDOMNode *pNode = NULL;
|
|
bool bError = false;
|
|
while (!bError && SUCCEEDED(pNodeList->nextNode (&pNode)) && pNode)
|
|
{
|
|
BSTR strNodeName = NULL;
|
|
if (SUCCEEDED(pNode->get_nodeName (&strNodeName)))
|
|
{
|
|
// Check if this is a node we're interested in - A QUALIFIER node
|
|
if(_wcsicmp(strNodeName, L"QUALIFIER") == 0)
|
|
{
|
|
if(FAILED(hr = AddQualifier(pNode, pQuals)))
|
|
bError = TRUE;
|
|
}
|
|
SysFreeString(strNodeName);
|
|
}
|
|
pNode->Release();
|
|
pNode = NULL;
|
|
}
|
|
|
|
if(bError)
|
|
{
|
|
// If hr does not indicate a failure, then we indicate
|
|
// a generic failure
|
|
if(SUCCEEDED(hr))
|
|
hr = WBEM_E_FAILED;
|
|
}
|
|
else
|
|
hr = S_OK;
|
|
pNodeList->Release();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CXml2Wmi::CreateParametersInstance(IWbemClassObject **pParamObject)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
// Create a Free Form Object
|
|
_IWmiFreeFormObject *pObj = NULL;
|
|
*pParamObject = NULL;
|
|
if(SUCCEEDED(hr = g_pObjectFactory->Create(NULL, 0, CLSID__WmiFreeFormObject, IID__IWmiFreeFormObject, (LPVOID *)&pObj)))
|
|
{
|
|
// Set the class name on it
|
|
if(SUCCEEDED(hr = pObj->SetClassName(0, L"__Parameters")))
|
|
{
|
|
// if(SUCCEEDED(hr = pObj->MakeInstance(0)))
|
|
hr = pObj->QueryInterface(IID_IWbemClassObject, (LPVOID *)pParamObject);
|
|
}
|
|
pObj->Release();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
// Creates all the Methods in a class
|
|
HRESULT CXml2Wmi::CreateWMIMethods(bool bAllowWMIExtensions, IWbemClassObject *pObj, IXMLDOMElement *pXML)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// Now cycle thru the properties
|
|
IXMLDOMNodeList *pNodeList = NULL;
|
|
bool bError = false;
|
|
if (SUCCEEDED(pXML->get_childNodes (&pNodeList)))
|
|
{
|
|
IXMLDOMNode *pNode = NULL;
|
|
while (!bError && SUCCEEDED(pNodeList->nextNode (&pNode)) &&pNode)
|
|
{
|
|
BSTR strNodeName = NULL;
|
|
if (SUCCEEDED(pNode->get_nodeName (&strNodeName)))
|
|
{
|
|
if(_wcsicmp(strNodeName, L"METHOD") == 0 )
|
|
{
|
|
IXMLDOMElement *pMethodElement = NULL;
|
|
if(SUCCEEDED(pNode->QueryInterface(IID_IXMLDOMElement, (LPVOID *)&pMethodElement)))
|
|
{
|
|
if(FAILED(hr = CreateAWMIMethod(bAllowWMIExtensions, pObj, pMethodElement)))
|
|
bError = true;
|
|
pMethodElement->Release();
|
|
}
|
|
else
|
|
bError = true;
|
|
}
|
|
SysFreeString(strNodeName);
|
|
}
|
|
pNode->Release();
|
|
pNode = NULL;
|
|
}
|
|
pNodeList->Release();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
// Creates a Methods in a class
|
|
HRESULT CXml2Wmi::CreateAWMIMethod(bool bAllowWMIExtensions, IWbemClassObject *pObj, IXMLDOMElement *pMethod)
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
|
|
if (pMethod)
|
|
{
|
|
BSTR strName = NULL;
|
|
BSTR strType = NULL;
|
|
|
|
// Get the attributes we need for the mapping
|
|
GetBstrAttribute (pMethod, g_strName, &strName);
|
|
GetBstrAttribute (pMethod, g_strType, &strType);
|
|
|
|
// The method should atleast have a name
|
|
if (strName)
|
|
{
|
|
// Put a provisional version of the method
|
|
// so we can get the qualifier set
|
|
if (SUCCEEDED(hr = pObj->PutMethod(strName, 0, NULL, NULL)))
|
|
{
|
|
IWbemQualifierSet *pQualSet = NULL;
|
|
IWbemClassObject *pInParameters = NULL;
|
|
IWbemClassObject *pOutParameters = NULL;
|
|
|
|
if (SUCCEEDED(hr = pObj->GetMethodQualifierSet (strName, &pQualSet)))
|
|
{
|
|
// If we have a return value, set that
|
|
if (strType && (0 < wcslen (strType)))
|
|
{
|
|
CIMTYPE cimtype = CIM_ILLEGAL;
|
|
|
|
if (CIM_ILLEGAL == (cimtype = CimtypeFromString (strType)))
|
|
hr = WBEM_E_FAILED;
|
|
else if (SUCCEEDED(hr = CreateParametersInstance(&pOutParameters)))
|
|
hr = pOutParameters->Put (L"ReturnValue", 0, NULL, cimtype);
|
|
}
|
|
|
|
|
|
// The content of this element should be 0 or
|
|
// more QUALIFIER elements followed by 0 or more
|
|
// PARAMETER.* elements.
|
|
VARIANT_BOOL bHasChildNodes;
|
|
|
|
if (SUCCEEDED(pMethod->hasChildNodes (&bHasChildNodes)) &&
|
|
(VARIANT_TRUE == bHasChildNodes))
|
|
{
|
|
IXMLDOMNodeList *pNodeList = NULL;
|
|
// We can be in one of 3 states whilst iterating
|
|
// this list - parsing qualifiers or parsing the value
|
|
enum {
|
|
parsingQualifiers,
|
|
parsingParameters
|
|
} parseState = parsingQualifiers;
|
|
|
|
if (SUCCEEDED(pMethod->get_childNodes (&pNodeList)))
|
|
{
|
|
IXMLDOMNode *pNode = NULL;
|
|
ULONG paramId = 0;
|
|
|
|
while (SUCCEEDED(hr) && SUCCEEDED(pNodeList->nextNode (&pNode)) &&pNode)
|
|
{
|
|
BSTR strNodeName = NULL;
|
|
|
|
if (SUCCEEDED(pNode->get_nodeName (&strNodeName)))
|
|
{
|
|
if (parsingQualifiers == parseState)
|
|
{
|
|
if (0 == _wcsicmp(strNodeName, QUALIFIER_TAG))
|
|
hr = AddQualifier (pNode, pQualSet);
|
|
else
|
|
parseState = parsingParameters;
|
|
}
|
|
|
|
if (parsingParameters == parseState)
|
|
{
|
|
if (0 == _wcsicmp(strNodeName, PARAMETER_TAG))
|
|
{
|
|
hr = MapParameter (pNode, &pInParameters,
|
|
&pOutParameters,
|
|
paramId, false);
|
|
paramId++;
|
|
}
|
|
else if (0 == _wcsicmp(strNodeName,
|
|
PARAMETERARRAY_TAG))
|
|
{
|
|
hr = MapParameter (pNode,
|
|
&pInParameters, &pOutParameters,
|
|
paramId, true);
|
|
paramId++;
|
|
}
|
|
else if (0 == _wcsicmp(strNodeName,
|
|
PARAMETERREFERENCE_TAG))
|
|
{
|
|
hr = MapReferenceOrObjectParameter (pNode,
|
|
&pInParameters, &pOutParameters,
|
|
paramId, false, true);
|
|
paramId++;
|
|
}
|
|
else if (0 == _wcsicmp(strNodeName,
|
|
PARAMETERREFARRAY_TAG))
|
|
{
|
|
hr = MapReferenceOrObjectParameter (pNode,
|
|
&pInParameters, &pOutParameters,
|
|
paramId, true, true);
|
|
paramId++;
|
|
}
|
|
else if (0 == _wcsicmp(strNodeName,
|
|
PARAMETEROBJECT_TAG) && bAllowWMIExtensions)
|
|
{
|
|
hr = MapReferenceOrObjectParameter (pNode,
|
|
&pInParameters, &pOutParameters,
|
|
paramId, false, false);
|
|
paramId++;
|
|
}
|
|
else if (0 == _wcsicmp(strNodeName,
|
|
PARAMETEROBJECTARRAY_TAG) && bAllowWMIExtensions)
|
|
{
|
|
hr = MapReferenceOrObjectParameter (pNode,
|
|
&pInParameters, &pOutParameters,
|
|
paramId, true, false);
|
|
paramId++;
|
|
}
|
|
else
|
|
hr = WBEM_E_FAILED; // Parse error
|
|
}
|
|
|
|
SysFreeString (strNodeName);
|
|
}
|
|
|
|
pNode->Release ();
|
|
pNode = NULL;
|
|
}
|
|
|
|
pNodeList->Release ();
|
|
}
|
|
}
|
|
|
|
pQualSet->Release ();
|
|
}
|
|
|
|
// Put it all together
|
|
if (SUCCEEDED (hr))
|
|
hr = pObj->PutMethod (strName, 0, pInParameters, pOutParameters);
|
|
|
|
if (pInParameters)
|
|
pInParameters->Release ();
|
|
|
|
if (pOutParameters)
|
|
pOutParameters->Release ();
|
|
}
|
|
}
|
|
else
|
|
hr = WBEM_E_INVALID_METHOD;
|
|
|
|
SysFreeString (strName);
|
|
SysFreeString (strType);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CXml2Wmi::MapParameter (
|
|
IXMLDOMNode *pParameter,
|
|
IWbemClassObject **ppInParameters,
|
|
IWbemClassObject **ppOutParameters,
|
|
ULONG paramId,
|
|
bool bIsArray
|
|
)
|
|
{
|
|
HRESULT hr = WBEM_E_INVALID_SYNTAX;
|
|
bool bIsInParameter = false;
|
|
bool bIsOutParameter = false;
|
|
BSTR bsName = NULL;
|
|
CIMTYPE cimtype = CIM_ILLEGAL;
|
|
long iArraySize = 0;
|
|
|
|
if (DetermineParameterCharacteristics (pParameter, bIsArray, bIsInParameter,
|
|
bIsOutParameter, bsName, cimtype, iArraySize, false, NULL))
|
|
{
|
|
if (bIsInParameter)
|
|
{
|
|
if (!(*ppInParameters))
|
|
hr = CreateParametersInstance (ppInParameters);
|
|
|
|
if (*ppInParameters)
|
|
{
|
|
if (SUCCEEDED(hr = (*ppInParameters)->Put (bsName, 0, NULL, cimtype)))
|
|
{
|
|
// Now do the qualifiers
|
|
IWbemQualifierSet *pQualSet = NULL;
|
|
if (SUCCEEDED(hr = (*ppInParameters)->GetPropertyQualifierSet
|
|
(bsName, &pQualSet)))
|
|
{
|
|
hr = MapParameterQualifiers (pParameter, pQualSet, paramId,
|
|
bIsArray, iArraySize, true);
|
|
pQualSet->Release ();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (bIsOutParameter)
|
|
{
|
|
if (!(*ppOutParameters))
|
|
CreateParametersInstance(ppOutParameters);
|
|
|
|
if (*ppOutParameters)
|
|
{
|
|
if (SUCCEEDED(hr = (*ppOutParameters)->Put (bsName, 0, NULL, cimtype)))
|
|
{
|
|
// Now do the qualifiers
|
|
IWbemQualifierSet *pQualSet = NULL;
|
|
|
|
if (SUCCEEDED(hr = (*ppOutParameters)->GetPropertyQualifierSet
|
|
(bsName, &pQualSet)))
|
|
{
|
|
hr = MapParameterQualifiers (pParameter, pQualSet, paramId,
|
|
bIsArray, iArraySize, false);
|
|
pQualSet->Release ();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
SysFreeString (bsName);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
bool CXml2Wmi::DetermineParameterCharacteristics (
|
|
IXMLDOMNode *pParameter,
|
|
bool bIsArray,
|
|
bool &bIsInParameter,
|
|
bool &bIsOutParameter,
|
|
BSTR &bsName,
|
|
CIMTYPE &cimtype,
|
|
long &iArraySize,
|
|
bool bIsReference,
|
|
BSTR *pbsReferenceClass)
|
|
{
|
|
bool result = false;
|
|
bIsInParameter = false;
|
|
bIsOutParameter = false;
|
|
|
|
// Get name
|
|
GetBstrAttribute (pParameter, g_strName, &bsName);
|
|
|
|
if (bsName)
|
|
{
|
|
if (bIsArray)
|
|
{
|
|
// Get the arraysize (if any)
|
|
BSTR bsArraySize = NULL;
|
|
GetBstrAttribute (pParameter, g_strArraySize, &bsArraySize);
|
|
if (bsArraySize)
|
|
iArraySize = wcstol (bsArraySize, NULL, 0);
|
|
SysFreeString (bsArraySize);
|
|
}
|
|
|
|
// Now get the cimtype
|
|
if (bIsReference)
|
|
{
|
|
cimtype = CIM_REFERENCE;
|
|
if (pbsReferenceClass)
|
|
GetBstrAttribute (pParameter, g_strReferenceClass, pbsReferenceClass);
|
|
}
|
|
else
|
|
{
|
|
BSTR bsCimtype = NULL;
|
|
GetBstrAttribute (pParameter, g_strType, &bsCimtype);
|
|
cimtype = CimtypeFromString (bsCimtype);
|
|
SysFreeString (bsCimtype);
|
|
}
|
|
|
|
if (CIM_ILLEGAL != cimtype)
|
|
{
|
|
if (bIsArray)
|
|
cimtype |= CIM_FLAG_ARRAY;
|
|
|
|
result = true;
|
|
|
|
// Now find out if the method is an in or out
|
|
// (or both) parameter - need to go through
|
|
// qualifier list
|
|
IXMLDOMNodeList *pNodeList = NULL;
|
|
if (SUCCEEDED(pParameter->get_childNodes (&pNodeList)))
|
|
{
|
|
IXMLDOMNode *pNode = NULL;
|
|
HRESULT hr = S_OK;
|
|
|
|
while (SUCCEEDED(hr) && SUCCEEDED(pNodeList->nextNode (&pNode)) &&pNode)
|
|
{
|
|
BSTR strNodeName = NULL;
|
|
if (SUCCEEDED(pNode->get_nodeName (&strNodeName)))
|
|
{
|
|
if (0 == _wcsicmp(strNodeName, QUALIFIER_TAG))
|
|
{
|
|
BSTR bsName = NULL;
|
|
GetBstrAttribute (pNode, g_strName, &bsName);
|
|
if (bsName)
|
|
{
|
|
bool bCandidate = false;
|
|
bool bsIn = true;
|
|
|
|
if (0 == _wcsicmp (bsName, L"IN"))
|
|
bCandidate = true;
|
|
else if (0 == _wcsicmp (bsName, L"OUT"))
|
|
{
|
|
bCandidate = true;
|
|
bsIn = false;
|
|
}
|
|
|
|
if (bCandidate)
|
|
{
|
|
BSTR bsType = NULL;
|
|
GetBstrAttribute (pNode, g_strType, &bsType);
|
|
if (bsType && (0 == _wcsicmp (bsType, L"boolean")))
|
|
{
|
|
BSTR bsValue = NULL;
|
|
if (SUCCEEDED(pNode->get_text(&bsValue)) &&
|
|
bsValue && (0 == _wcsicmp (bsValue, L"TRUE")))
|
|
{
|
|
if (bsIn)
|
|
bIsInParameter = true;
|
|
else
|
|
bIsOutParameter = true;
|
|
}
|
|
SysFreeString(bsValue);
|
|
}
|
|
SysFreeString (bsType);
|
|
}
|
|
|
|
SysFreeString (bsName);
|
|
}
|
|
}
|
|
|
|
SysFreeString (strNodeName);
|
|
}
|
|
|
|
pNode->Release ();
|
|
pNode = NULL;
|
|
}
|
|
|
|
pNodeList->Release ();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!result)
|
|
{
|
|
SysFreeString (bsName);
|
|
bsName = NULL;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
HRESULT CXml2Wmi::MapParameterQualifiers (
|
|
IXMLDOMNode *pParameter,
|
|
IWbemQualifierSet *pQualSet,
|
|
ULONG paramId,
|
|
bool bIsArray,
|
|
long iArraySize,
|
|
bool bIsInParameter
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
IXMLDOMNodeList *pNodeList = NULL;
|
|
if (SUCCEEDED(pParameter->get_childNodes (&pNodeList)))
|
|
{
|
|
IXMLDOMNode *pNode = NULL;
|
|
|
|
while (SUCCEEDED(hr) && SUCCEEDED(pNodeList->nextNode (&pNode)) &&pNode)
|
|
{
|
|
BSTR strNodeName = NULL;
|
|
if (SUCCEEDED(pNode->get_nodeName (&strNodeName)))
|
|
{
|
|
if (0 == _wcsicmp(strNodeName, QUALIFIER_TAG))
|
|
{
|
|
// We must only add the IN qualifier to an In parameter,
|
|
// and the OUT parameter to an Out parameter
|
|
BSTR bsName = NULL;
|
|
GetBstrAttribute (pNode, g_strName, &bsName);
|
|
if (bsName)
|
|
{
|
|
if (0 == _wcsicmp (bsName, L"IN"))
|
|
{
|
|
if (bIsInParameter)
|
|
hr = AddQualifier (pNode, pQualSet);
|
|
}
|
|
else if (0 == _wcsicmp (bsName, L"OUT"))
|
|
{
|
|
if (!bIsInParameter)
|
|
hr = AddQualifier (pNode, pQualSet);
|
|
}
|
|
else
|
|
hr = AddQualifier (pNode, pQualSet);
|
|
SysFreeString (bsName);
|
|
}
|
|
}
|
|
SysFreeString (strNodeName);
|
|
}
|
|
|
|
pNode->Release ();
|
|
pNode = NULL;
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
long flavor = WBEM_FLAVOR_NOT_OVERRIDABLE |
|
|
WBEM_FLAVOR_FLAG_PROPAGATE_TO_DERIVED_CLASS;
|
|
// Add in the parameter id
|
|
VARIANT var;
|
|
VariantInit (&var);
|
|
var.vt = VT_I4;
|
|
var.lVal = paramId;
|
|
hr = pQualSet->Put (L"ID", &var, flavor);
|
|
VariantClear (&var);
|
|
|
|
if (SUCCEEDED(hr) && bIsArray && (0 < iArraySize))
|
|
{
|
|
// Add in MIN and MAX qualifiers
|
|
var.vt = VT_I4;
|
|
var.lVal = iArraySize;
|
|
|
|
if (SUCCEEDED(hr = pQualSet->Put (L"MAX", &var, flavor)))
|
|
hr = pQualSet->Put (L"MIN", &var, flavor);
|
|
}
|
|
}
|
|
|
|
pNodeList->Release ();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CXml2Wmi::MapReferenceOrObjectParameter (
|
|
IXMLDOMNode *pParameter,
|
|
IWbemClassObject **ppInParameters,
|
|
IWbemClassObject **ppOutParameters,
|
|
ULONG paramId,
|
|
bool bIsArray,
|
|
bool bIsReference
|
|
)
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
bool bIsInParameter = false;
|
|
bool bIsOutParameter = false;
|
|
BSTR bsName = NULL;
|
|
BSTR bsReferenceClass = NULL;
|
|
long iArraySize = 0;
|
|
CIMTYPE cimtype = CIM_ILLEGAL;
|
|
|
|
if (DetermineParameterCharacteristics (pParameter, bIsArray, bIsInParameter,
|
|
bIsOutParameter, bsName, cimtype, iArraySize,
|
|
true, &bsReferenceClass))
|
|
{
|
|
// The above function always returns CIM_REFERENCE for both references
|
|
// and embedded objects - but we know better
|
|
if(!bIsReference)
|
|
cimtype = CIM_OBJECT;
|
|
|
|
if (bIsInParameter)
|
|
{
|
|
if (!(*ppInParameters))
|
|
CreateParametersInstance(ppInParameters);
|
|
|
|
if (*ppInParameters)
|
|
{
|
|
if (SUCCEEDED(hr = (*ppInParameters)->Put (bsName, 0, NULL, cimtype)))
|
|
{
|
|
// Now do the qualifiers
|
|
IWbemQualifierSet *pQualSet = NULL;
|
|
|
|
if (SUCCEEDED(hr = (*ppInParameters)->GetPropertyQualifierSet
|
|
(bsName, &pQualSet)))
|
|
{
|
|
hr = MapParameterQualifiers (pParameter, pQualSet, paramId,
|
|
bIsArray, iArraySize, true);
|
|
|
|
// If a strong reference, add it now
|
|
if (bsReferenceClass)
|
|
SetReferenceOrObjectClass (pQualSet, bsReferenceClass, bIsReference);
|
|
|
|
pQualSet->Release ();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (bIsOutParameter)
|
|
{
|
|
if (!(*ppOutParameters))
|
|
hr = CreateParametersInstance (ppOutParameters);
|
|
|
|
if (*ppOutParameters)
|
|
{
|
|
if (SUCCEEDED(hr = (*ppOutParameters)->Put (bsName, 0, NULL, cimtype)))
|
|
{
|
|
// Now do the qualifiers
|
|
IWbemQualifierSet *pQualSet = NULL;
|
|
|
|
if (SUCCEEDED(hr = (*ppOutParameters)->GetPropertyQualifierSet
|
|
(bsName, &pQualSet)))
|
|
{
|
|
hr = MapParameterQualifiers (pParameter, pQualSet, paramId,
|
|
bIsArray, iArraySize, false);
|
|
// If a strong reference, add it now
|
|
if (bsReferenceClass)
|
|
SetReferenceOrObjectClass (pQualSet, bsReferenceClass, bIsReference);
|
|
|
|
pQualSet->Release ();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
SysFreeString(bsReferenceClass);
|
|
SysFreeString (bsName);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CXml2Wmi::SetReferenceOrObjectClass (
|
|
IWbemQualifierSet *pQualSet,
|
|
BSTR strReferenceClass,
|
|
bool bIsReference
|
|
)
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
int strLen = (bIsReference)? wcslen(REF_WSTR) : wcslen(OBJECT_WSTR);
|
|
bool bIsStrongReference = (strReferenceClass && (0 < wcslen(strReferenceClass)));
|
|
|
|
if (bIsStrongReference)
|
|
strLen += wcslen(strReferenceClass) + 1; // 1 for the ":" separator
|
|
|
|
WCHAR *pRef = NULL;
|
|
if(pRef = new WCHAR [strLen + 1])
|
|
{
|
|
(bIsReference)? wcscpy (pRef, REF_WSTR) : wcscpy(pRef, OBJECT_WSTR);
|
|
if (bIsStrongReference)
|
|
{
|
|
wcscat (pRef, L":");
|
|
wcscat (pRef, strReferenceClass);
|
|
}
|
|
|
|
VARIANT curValue;
|
|
VariantInit (&curValue);
|
|
curValue.vt = VT_BSTR;
|
|
curValue.bstrVal = NULL;
|
|
if(curValue.bstrVal = SysAllocString (pRef))
|
|
{
|
|
hr = pQualSet->Put(L"CIMTYPE", &curValue,
|
|
WBEM_FLAVOR_FLAG_PROPAGATE_TO_DERIVED_CLASS|
|
|
WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE|
|
|
WBEM_FLAVOR_NOT_OVERRIDABLE);
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
VariantClear (&curValue);
|
|
delete [] pRef;
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CXml2Wmi::FixRefsAndEmbeddedObjects(IXMLDOMElement *pMethod, IWbemClassObject *pObj)
|
|
{
|
|
// In this function we've to go thru all the reference and embedded properties (and arrays of those kind)
|
|
// and convert them to strong references if applicable, by adding appropriate qualifiers
|
|
// The reason we do this is that the Free-Form object interfaces do not allow you to add qualifers,
|
|
// but allow only properties. Hence we initially added these properties as weak references.
|
|
// Now we have to add qualifiers to make them strong references in those cases where applicable
|
|
|
|
// Go thru all the properties of the class
|
|
IXMLDOMNodeList *pNodeList = NULL;
|
|
bool bError = false;
|
|
if (SUCCEEDED(pMethod->get_childNodes (&pNodeList)))
|
|
{
|
|
IXMLDOMNode *pNode = NULL;
|
|
while (!bError && SUCCEEDED(pNodeList->nextNode (&pNode)) &&pNode)
|
|
{
|
|
BSTR strNodeName = NULL;
|
|
// We work only on 4 kinds of properties in this functions
|
|
if (SUCCEEDED(pNode->get_nodeName (&strNodeName)))
|
|
{
|
|
if( _wcsicmp(strNodeName, L"PROPERTY.REFERENCE") == 0 ||
|
|
_wcsicmp(strNodeName, L"PROPERTY.OBJECT") == 0 ||
|
|
_wcsicmp(strNodeName, L"PROPERTY.OBJECTARRAY") == 0 ||
|
|
_wcsicmp(strNodeName, L"PROPERTY.REFARRAY") == 0 )
|
|
{
|
|
IXMLDOMElement *pPropElement = NULL;
|
|
if(SUCCEEDED(pNode->QueryInterface(IID_IXMLDOMElement, (LPVOID *)&pPropElement)))
|
|
{
|
|
bool bIsRef = false;
|
|
if( _wcsicmp(strNodeName, L"PROPERTY.REFERENCE") == 0 ||
|
|
_wcsicmp(strNodeName, L"PROPERTY.REFARRAY") == 0 )
|
|
bIsRef = true;
|
|
|
|
// Fix the property
|
|
if(FAILED(FixRefOrEmbeddedProperty(pPropElement, pObj, bIsRef)))
|
|
bError = true;
|
|
pPropElement->Release();
|
|
}
|
|
else
|
|
bError = true;
|
|
}
|
|
SysFreeString(strNodeName);
|
|
}
|
|
pNode->Release();
|
|
pNode = NULL;
|
|
}
|
|
pNodeList->Release();
|
|
}
|
|
if(bError)
|
|
return E_FAIL;
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
HRESULT CXml2Wmi::FixRefOrEmbeddedProperty(IXMLDOMElement *pProperty, IWbemClassObject *pObj, bool bIsRef)
|
|
{
|
|
// In this, we have a PROPERTY.REFERENCE or PROPERTY.OBJECT
|
|
HRESULT hr = E_FAIL;
|
|
// Get the name of the property
|
|
BSTR strName = NULL;
|
|
if(SUCCEEDED(hr = GetBstrAttribute (pProperty, g_strName, &strName)))
|
|
{
|
|
BSTR strReferenceClass = NULL;
|
|
// Get the strong type (if any) of the reference/embedded object
|
|
if(SUCCEEDED(GetBstrAttribute (pProperty, g_strReferenceClass, &strReferenceClass)))
|
|
{
|
|
// Set the qualifier on the property
|
|
hr = FixAProperty(pObj, strName, strReferenceClass, bIsRef);
|
|
SysFreeString(strReferenceClass);
|
|
}
|
|
else
|
|
hr = S_OK; // This is an anonymous reference/object - No qualifier required
|
|
SysFreeString(strName);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CXml2Wmi::FixAProperty(IWbemClassObject *pObj, BSTR strPropName, BSTR strRefClass, bool bIsRef)
|
|
{
|
|
// Get the Property Qualifier Set
|
|
IWbemQualifierSet *pSet = NULL;
|
|
HRESULT hr = E_FAIL;
|
|
if(SUCCEEDED(pObj->GetPropertyQualifierSet(strPropName, &pSet)))
|
|
{
|
|
VARIANT vQualValue;
|
|
VariantInit(&vQualValue);
|
|
|
|
LPWSTR pszQualValue = NULL;
|
|
if(pszQualValue = new WCHAR[6 + 1 + wcslen(strRefClass) + 1])
|
|
{
|
|
if(bIsRef)
|
|
wcscpy(pszQualValue, L"ref:");
|
|
else
|
|
wcscpy(pszQualValue, L"object:");
|
|
wcscat(pszQualValue, strRefClass);
|
|
BSTR strQualValue = NULL;
|
|
if(strQualValue = SysAllocString(pszQualValue))
|
|
{
|
|
vQualValue.vt = VT_BSTR;
|
|
vQualValue.bstrVal = strQualValue;
|
|
|
|
hr = pSet->Put(L"CIMTYPE", &vQualValue,
|
|
WBEM_FLAVOR_FLAG_PROPAGATE_TO_DERIVED_CLASS|
|
|
WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE|
|
|
WBEM_FLAVOR_NOT_OVERRIDABLE);
|
|
|
|
VariantClear(&vQualValue);
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
delete [] pszQualValue;
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
pSet->Release();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CXml2Wmi::DecorateObject(_IWmiFreeFormObject *pObj, BSTR strServer, BSTR strNamespace)
|
|
{
|
|
// We need to set the __SERVER and and _NAMESPACE properties
|
|
bool bFreeServer = false;
|
|
if(!strServer)
|
|
{
|
|
bFreeServer = true;
|
|
strServer = SysAllocString(L".");
|
|
}
|
|
|
|
_IWmiObject *pWmiObj = NULL;
|
|
if(SUCCEEDED(pObj->QueryInterface(IID__IWmiObject, (LPVOID *)&pWmiObj)))
|
|
{
|
|
// It is OK to fail
|
|
pWmiObj->SetDecoration(strServer, strNamespace);
|
|
pWmiObj->Release();
|
|
}
|
|
|
|
if(bFreeServer)
|
|
SysFreeString(strServer);
|
|
|
|
// It is OK if we cant decorate every object
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
// Forms a string of the form pszPropertyName="pszRefValue"
|
|
// That is, adds double quotes around the value and also
|
|
// escapes any double quotes in the pszRefValue
|
|
HRESULT CXml2Wmi::FormRefValueKeyBinding(LPWSTR *ppszValue, LPCWSTR pszPropertyName, LPCWSTR pszRefValue)
|
|
{
|
|
HRESULT result = S_OK;
|
|
LPWSTR pszEscapedStringValue = NULL;
|
|
if(pszEscapedStringValue = EscapeSpecialCharacters(pszRefValue))
|
|
{
|
|
// Add suffucuent memory for the '=' and the 2 double-quotes
|
|
if((*ppszValue) = new WCHAR[wcslen(pszPropertyName) + wcslen(pszEscapedStringValue) + 4])
|
|
{
|
|
wcscpy(*ppszValue, pszPropertyName);
|
|
wcscat(*ppszValue, EQUALS_SIGN);
|
|
wcscat(*ppszValue, QUOTE_SIGN);
|
|
wcscat(*ppszValue, pszEscapedStringValue);
|
|
wcscat(*ppszValue, QUOTE_SIGN);
|
|
result = S_OK;
|
|
}
|
|
else
|
|
result = E_OUTOFMEMORY;
|
|
delete [] pszEscapedStringValue;
|
|
}
|
|
else
|
|
result = E_OUTOFMEMORY;
|
|
return result;
|
|
}
|
|
|
|
*/ |