1565 lines
38 KiB
C++
1565 lines
38 KiB
C++
***************************************************************************/
|
|
//
|
|
// Copyright (c) 2000-2001 Microsoft Corporation
|
|
//
|
|
// wmitoxml.cpp
|
|
//
|
|
// ramrao 13 Nov 2000 - Created
|
|
//
|
|
//
|
|
// Declaration of CWMIToXML class
|
|
//
|
|
//***************************************************************************/
|
|
|
|
#include <precomp.h>
|
|
#include "wmitoxml.h"
|
|
|
|
|
|
|
|
#define INITBUFFSIZE 10000
|
|
#define BUFFINCRSIZE 5000
|
|
|
|
#define CLASS_GENUS 1
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Constructor
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
CWMIToXML::CWMIToXML()
|
|
{
|
|
m_pIObject = NULL;
|
|
m_pConnection = NULL;
|
|
|
|
m_strUser = NULL;
|
|
m_strPassword = NULL;
|
|
m_strLocale = NULL;
|
|
|
|
m_bDCOMObj = TRUE;
|
|
|
|
|
|
m_lFlags = 0;
|
|
|
|
m_strWmiNamespace = NULL;
|
|
m_strWmiSchemaLoc = NULL;
|
|
m_strWmiSchemaPrefix = NULL;
|
|
|
|
m_strNamespace = NULL;
|
|
m_strNamespacePrefix = NULL;
|
|
m_bClass = TRUE;
|
|
m_pITmpStream = NULL;
|
|
|
|
m_pInstance = NULL;
|
|
m_pSchema = NULL;
|
|
|
|
// Set the initial size to 2 and growsize by 2
|
|
m_arrSchemaLocs.SetSize(0,2);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Destructor
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
CWMIToXML::~CWMIToXML()
|
|
{
|
|
SAFE_RELEASE_PTR(m_pIObject);
|
|
SAFE_FREE_SYSSTRING(m_strUser);
|
|
SAFE_FREE_SYSSTRING(m_strPassword);
|
|
SAFE_FREE_SYSSTRING(m_strLocale);
|
|
|
|
ReleaseSchemaLocs();
|
|
|
|
SAFE_FREE_SYSSTRING(m_strWmiNamespace);
|
|
SAFE_FREE_SYSSTRING(m_strWmiSchemaLoc);
|
|
SAFE_FREE_SYSSTRING(m_strWmiSchemaPrefix);
|
|
|
|
SAFE_FREE_SYSSTRING(m_strNamespace);
|
|
SAFE_FREE_SYSSTRING(m_strNamespacePrefix);
|
|
|
|
SAFE_DELETE_PTR(m_pInstance);
|
|
SAFE_DELETE_PTR(m_pSchema);
|
|
SAFE_DELETE_PTR(m_pConnection);
|
|
|
|
SAFE_RELEASE_PTR(m_pITmpStream);
|
|
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Initialization function to sent user credentials
|
|
//
|
|
// Returns S_OK
|
|
// E_OUTOFMEMORY
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIToXML::SetUserAuthentication(BSTR strUser,BSTR strPassword,BSTR strLocale)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
SAFE_FREE_SYSSTRING(m_strUser);
|
|
SAFE_FREE_SYSSTRING(m_strPassword);
|
|
SAFE_FREE_SYSSTRING(m_strLocale);
|
|
|
|
if(strUser)
|
|
{
|
|
if((m_strUser = SysAllocString(strUser)))
|
|
{
|
|
if(strPassword)
|
|
{
|
|
if(m_strPassword = SysAllocString(strPassword))
|
|
{
|
|
if(strLocale)
|
|
{
|
|
if(!(m_strLocale = SysAllocString(strLocale)))
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
SAFE_FREE_SYSSTRING(m_strUser);
|
|
SAFE_FREE_SYSSTRING(m_strPassword);
|
|
SAFE_FREE_SYSSTRING(m_strLocale);
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Gets Schema of a given class and puts data to the internal Stream
|
|
//
|
|
// Returns S_OK
|
|
// E_OUTOFMEMORY
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIToXML::GetSchema()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
IWbemQualifierSet *pQualifierSet = NULL;
|
|
|
|
if(WMIXML_INCLUDE_XSITYPE & m_lFlags)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
}
|
|
|
|
if(SUCCEEDED(hr) && SUCCEEDED(hr = InitSchemaObject()))
|
|
{
|
|
// Call this function to navigate thru the propertyies
|
|
// to find any embedded property and add includes for them
|
|
hr = AddPropertiesForSchemaToAppInfo(TRUE);
|
|
}
|
|
|
|
// Add Includes, set Target Namespace and namespaces
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = AddSchemaAttributesAndIncludes();
|
|
}
|
|
|
|
// writes schema data till the begining of the Annotation section
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = m_pSchema->BeginSchemaAndWriteTillBeginingOfAnnotation();
|
|
}
|
|
|
|
// Get Qualifiers of the class and add them to the Appinfo section
|
|
if(SUCCEEDED(hr) && SUCCEEDED(m_pIObject->GetQualifierSet(&pQualifierSet)))
|
|
{
|
|
hr = AddQualifiers(pQualifierSet);
|
|
}
|
|
SAFE_RELEASE_PTR(pQualifierSet);
|
|
|
|
// Add Properties and its qualifiers to Appinfo section
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = AddPropertiesForSchemaToAppInfo();
|
|
}
|
|
|
|
// Add methods to apppinfo section
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = AddMethods();
|
|
}
|
|
|
|
// End the annotation section
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = m_pSchema->EndAnnotation();
|
|
}
|
|
|
|
// Write data to the stream till the defination fo the complexType for the class
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = m_pSchema->PrepareStreamToAddPropertiesForComplexType();
|
|
}
|
|
|
|
// Add Properties as elements of the complex type
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = AddPropertiesForSchema();
|
|
}
|
|
|
|
// End the schema
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = m_pSchema->EndSchema();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function which goes thru the methods of a class and adds them to XML schema
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIToXML::AddMethods()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
BSTR strMethod = NULL;
|
|
LONG lFlavor = 0;
|
|
VARIANT vQual;
|
|
|
|
IWbemClassObject * pInObject = NULL;
|
|
IWbemClassObject * pOutObject = NULL;
|
|
IWbemQualifierSet * pQualifierSet = NULL;
|
|
|
|
VariantInit(&vQual);
|
|
|
|
// Enumerate the methods
|
|
hr = m_pIObject->BeginMethodEnumeration(0); //WBEM_FLAG_LOCAL_ONLY );
|
|
|
|
while(hr == S_OK)
|
|
{
|
|
if(S_OK == m_pIObject->NextMethod(0,&strMethod,&pInObject,&pOutObject))
|
|
{
|
|
if(SUCCEEDED(hr = m_pSchema->BeginMethod(strMethod)))
|
|
{
|
|
// Get and add method quallifiers
|
|
if(SUCCEEDED(hr = m_pIObject->GetMethodQualifierSet(strMethod,&pQualifierSet)))
|
|
{
|
|
hr = AddQualifiers(pQualifierSet);
|
|
SAFE_RELEASE_PTR(pQualifierSet);
|
|
}
|
|
|
|
// Add Input parameter object
|
|
if(SUCCEEDED(hr) && pInObject)
|
|
{
|
|
hr = AddMethodParameter(pInObject,FALSE);
|
|
}
|
|
|
|
// Add output parameter object
|
|
if(SUCCEEDED(hr) && pOutObject)
|
|
{
|
|
hr = AddMethodParameter(pOutObject,TRUE);
|
|
}
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = m_pSchema->EndMethod();
|
|
}
|
|
}
|
|
|
|
SAFE_FREE_SYSSTRING(strMethod);
|
|
SAFE_RELEASE_PTR(pInObject);
|
|
SAFE_RELEASE_PTR(pOutObject);
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
m_pIObject->EndMethodEnumeration();
|
|
|
|
|
|
return (hr == WBEM_S_NO_MORE_DATA) ? S_OK : hr;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function to go thru the qualifierset and add them to XML schema
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIToXML::AddQualifiers(IWbemQualifierSet *pQualifierSet)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
BSTR strQual = NULL;
|
|
LONG lFlavor = 0;
|
|
VARIANT vQual;
|
|
|
|
VariantInit(&vQual);
|
|
|
|
// Start the enumeration
|
|
hr = pQualifierSet->BeginEnumeration(WBEM_FLAG_LOCAL_ONLY);
|
|
|
|
while(hr == S_OK)
|
|
{
|
|
if(S_OK == pQualifierSet->Next(0,&strQual,&vQual,&lFlavor))
|
|
{
|
|
// Add quallifier
|
|
hr = m_pSchema->AddQualifier(strQual,&vQual,lFlavor);
|
|
VariantClear(&vQual);
|
|
SAFE_FREE_SYSSTRING(strQual);
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
pQualifierSet->EndEnumeration();
|
|
|
|
return (hr == WBEM_S_NO_MORE_DATA) ? S_OK : hr;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function to go thru the properties of the WMI object and add appInfo section
|
|
// for the XML schema
|
|
//
|
|
// bFindAddIncludes - TRUE - indicates the function to look for the list of <includes>
|
|
// and add them to the schema. Does not add properties to
|
|
// appinfo section
|
|
// FALSE - Adds properties to appinfo section if
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIToXML::AddPropertiesForSchemaToAppInfo(BOOL bFindAddIncludes)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
BSTR strProp = NULL;
|
|
LONG lFlavor = 0;
|
|
LONG cimtype = 0;
|
|
IWbemQualifierSet * pQualifierSet = NULL;
|
|
BOOL bChanged = TRUE;
|
|
VARIANT vProp;
|
|
BSTR strEmbeddedType = NULL;
|
|
|
|
VariantInit(&vProp);
|
|
|
|
hr = m_pIObject->BeginEnumeration(WBEM_FLAG_NONSYSTEM_ONLY );
|
|
// hr = m_pIObject->BeginEnumeration(WBEM_FLAG_LOCAL_ONLY );
|
|
|
|
|
|
while(hr == S_OK)
|
|
{
|
|
if(S_OK == (hr = m_pIObject->Next(0,&strProp,&vProp,&cimtype,&lFlavor)))
|
|
{
|
|
BOOL bAddToAppInfo = FALSE;
|
|
BOOL bQualifiers = FALSE;
|
|
|
|
if(IsEmbededType(cimtype))
|
|
{
|
|
hr = GetEmbeddedType(strProp,strEmbeddedType);
|
|
}
|
|
|
|
// Check if any Local property qualifiers exist for the property
|
|
if(SUCCEEDED(hr = m_pIObject->GetPropertyQualifierSet(strProp,&pQualifierSet)))
|
|
{
|
|
bQualifiers = CheckIfLocalQualifiersExist(pQualifierSet);
|
|
}
|
|
|
|
// Check if the property value is changed if property is
|
|
// propogated from a parent class
|
|
if(SUCCEEDED(hr) && (WBEM_FLAVOR_ORIGIN_PROPAGATED & lFlavor) )
|
|
{
|
|
// Not going to call this function once the bug from Sanjes about WBEM_FLAVOR_LOCAL only
|
|
// returns modified properties FIXX
|
|
hr = IsPropertyChange(strProp,bChanged);
|
|
}
|
|
|
|
// if property is changed or if there are qualifiers then
|
|
// property has to be added to appinfo
|
|
if(SUCCEEDED(hr) && ((bChanged || bQualifiers)))
|
|
{
|
|
bAddToAppInfo = TRUE;
|
|
}
|
|
|
|
// if property is not changed and if the property values
|
|
// is NULL then there is no need of adding this property to appinfo
|
|
// FIXX - check if this is the design
|
|
if(bChanged == FALSE && IsPropNull(&vProp))
|
|
{
|
|
bAddToAppInfo = FALSE;
|
|
}
|
|
|
|
// If the property is local or if there is any change in defauvalue or
|
|
// type of the property ( in terms of strongly typing
|
|
// the CIM_OBJECT type property add it to annotation section)
|
|
if(bAddToAppInfo)
|
|
{
|
|
// if the property is an strongly typed embedded object
|
|
// then add a <include ...> for the the schema for the
|
|
// class if not already added
|
|
if(strEmbeddedType && bFindAddIncludes)
|
|
{
|
|
hr = AddIncludesForClassIfAlreadyNotPresent(strEmbeddedType);
|
|
}
|
|
|
|
|
|
if(bFindAddIncludes == FALSE && SUCCEEDED(hr) && SUCCEEDED(hr = m_pSchema->BeginPropertyInAnnotation(strProp,0,&vProp,cimtype,lFlavor,strEmbeddedType)))
|
|
{
|
|
hr = AddQualifiers(pQualifierSet);
|
|
SAFE_RELEASE_PTR(pQualifierSet);
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = m_pSchema->EndPropertyInAnnotation();
|
|
}
|
|
}
|
|
}
|
|
VariantClear(&vProp);
|
|
SAFE_FREE_SYSSTRING(strProp);
|
|
SAFE_FREE_SYSSTRING(strEmbeddedType);
|
|
SAFE_RELEASE_PTR(pQualifierSet);
|
|
}
|
|
}
|
|
m_pIObject->EndEnumeration();
|
|
|
|
|
|
return (hr == WBEM_S_NO_MORE_DATA) ? S_OK : hr;
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function to go thru the properties of the WMI object and add it XML schema
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIToXML::AddPropertiesForSchema()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
BSTR strProp = NULL;
|
|
LONG lFlavor = 0;
|
|
LONG cimtype = 0;
|
|
BSTR strEmbeddedType = NULL;
|
|
|
|
|
|
hr = m_pIObject->BeginEnumeration(WBEM_FLAG_LOCAL_ONLY);
|
|
|
|
while(hr == S_OK)
|
|
{
|
|
if(S_OK == (hr = m_pIObject->Next(0,&strProp,NULL,&cimtype,&lFlavor)))
|
|
{
|
|
if(IsEmbededType(cimtype))
|
|
{
|
|
hr = GetEmbeddedType(strProp,strEmbeddedType);
|
|
}
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = m_pSchema->AddProperty(strProp,0,cimtype,lFlavor,strEmbeddedType);
|
|
}
|
|
SAFE_FREE_SYSSTRING(strEmbeddedType);
|
|
SAFE_FREE_SYSSTRING(strProp);
|
|
}
|
|
}
|
|
m_pIObject->EndEnumeration();
|
|
|
|
return (hr == WBEM_S_NO_MORE_DATA) ? S_OK : hr;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function to set the schema <include>, targetNamespace and other attributes of
|
|
// of XML schema to be returned
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIToXML::AddSchemaAttributesAndIncludes()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
|
|
hr = SetTargetNamespace();;
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = AddSchemaIncludes();
|
|
}
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = SetWMIStdSchemaInfo();
|
|
}
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function which goes thru the parameter object of the method and adds
|
|
// them to the XML schema
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIToXML::AddMethodParameter(IWbemClassObject *pObject, BOOL bReturnVal)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
BSTR strParam = NULL;
|
|
LONG lFlavor = 0;
|
|
LONG cimtype = 0;
|
|
VARIANT vVal;
|
|
|
|
VariantInit(&vVal);
|
|
|
|
|
|
hr = pObject->BeginEnumeration(WBEM_FLAG_NONSYSTEM_ONLY);
|
|
|
|
while(hr == S_OK)
|
|
{
|
|
if(S_OK == (hr = pObject->Next(0,&strParam,&vVal,&cimtype,&lFlavor)))
|
|
{
|
|
if(bReturnVal)
|
|
{
|
|
hr = m_pSchema->BeginReturnVal(strParam,cimtype);
|
|
}
|
|
else
|
|
{
|
|
hr = m_pSchema->BeginParameter(strParam,cimtype,&vVal,lFlavor);
|
|
}
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
IWbemQualifierSet * pQualifierSet = NULL;
|
|
// add qualifiers for the paramters/return values
|
|
if(SUCCEEDED(hr = pObject->GetPropertyQualifierSet(strParam,&pQualifierSet)))
|
|
{
|
|
hr = AddQualifiers(pQualifierSet);
|
|
SAFE_RELEASE_PTR(pQualifierSet);
|
|
}
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
if(bReturnVal)
|
|
{
|
|
hr = m_pSchema->EndReturnVal();
|
|
}
|
|
else
|
|
{
|
|
hr = m_pSchema->EndParameter();
|
|
}
|
|
}
|
|
}
|
|
VariantClear(&vVal);
|
|
SAFE_FREE_SYSSTRING(strParam);
|
|
}
|
|
}
|
|
|
|
pObject->EndEnumeration();
|
|
|
|
return (hr == WBEM_S_NO_MORE_DATA) ? S_OK : hr;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function to release the string stored in SchemaLocations for <include> or schemaLocation
|
|
//
|
|
// Parameter
|
|
// bReleaseInUnderlyingObject - Indicates if schema location from the underlying
|
|
// schema object has to be cleared
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
void CWMIToXML::ReleaseSchemaLocs(BOOL bReleaseInUnderlyingObject)
|
|
{
|
|
int nSize = m_arrSchemaLocs.GetSize();
|
|
for(int lIndex = 0 ; lIndex < nSize ; lIndex ++)
|
|
{
|
|
SysFreeString((BSTR)m_arrSchemaLocs.ElementAt(lIndex));
|
|
}
|
|
m_arrSchemaLocs.RemoveAll();
|
|
|
|
if(bReleaseInUnderlyingObject && m_pSchema)
|
|
{
|
|
m_pSchema->ClearIncludes();
|
|
}
|
|
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function to set XMLNamespace of the document to be returned
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIToXML::SetXMLNamespace( BSTR strNamespace,
|
|
BSTR strNamespacePrefix)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
SAFE_FREE_SYSSTRING(m_strNamespace);
|
|
SAFE_FREE_SYSSTRING(m_strNamespacePrefix);
|
|
if(strNamespace)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
m_strNamespace = SysAllocString(strNamespace);
|
|
if(m_strNamespace)
|
|
{
|
|
hr = S_OK;
|
|
if(strNamespacePrefix)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
m_strNamespacePrefix = SysAllocString(strNamespacePrefix);
|
|
if(m_strNamespacePrefix)
|
|
{
|
|
hr = S_OK;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function to set the TargetNamespace on the schema to be returned
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIToXML::SetTargetNamespace()
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
if(m_strNamespace)
|
|
{
|
|
hr = m_pSchema->SetTargetNamespace(m_strNamespace,m_strNamespacePrefix);
|
|
}
|
|
return hr;
|
|
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function to initilize the member variable with WMI specific declaration details
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIToXML::SetWMIStandardSchemaLoc(BSTR strStdImportSchemaLoc,
|
|
BSTR strStdImportNamespace,
|
|
BSTR strNameSpaceprefix)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
SAFE_FREE_SYSSTRING(m_strWmiSchemaLoc);
|
|
SAFE_FREE_SYSSTRING(m_strWmiNamespace);
|
|
SAFE_FREE_SYSSTRING(m_strWmiSchemaPrefix);
|
|
|
|
if(strStdImportSchemaLoc && strStdImportNamespace)
|
|
{
|
|
hr = S_OK;
|
|
m_strWmiSchemaLoc = SysAllocString(strStdImportSchemaLoc);
|
|
m_strWmiNamespace = SysAllocString(strStdImportNamespace);
|
|
|
|
if(m_strWmiSchemaLoc && m_strWmiNamespace)
|
|
{
|
|
if(strNameSpaceprefix)
|
|
{
|
|
m_strWmiSchemaPrefix = SysAllocString(strNameSpaceprefix);
|
|
if(!m_strWmiSchemaPrefix)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function to set the <import> in the schema for WMI specific declarations
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIToXML::SetWMIStdSchemaInfo()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
if(IsClass())
|
|
{
|
|
if(m_strWmiNamespace)
|
|
{
|
|
hr = m_pSchema->SetWMIStdImport(m_strWmiNamespace,m_strWmiSchemaLoc,m_strWmiSchemaPrefix);
|
|
}
|
|
else
|
|
// set the default values
|
|
{
|
|
hr = m_pSchema->SetWMIStdImport(g_strStdNameSpace,g_strStdLoc,g_strStdPrefix);
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Set the schemalocation for to be used in the output XML.
|
|
// This function initializes the member variable
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIToXML::SetSchemaLocations(ULONG cSchema,BSTR *pstrSchemaLocation)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
BSTR strTemp = NULL;
|
|
|
|
|
|
// Release the schemaLocations and also the schemaLocations of the
|
|
// underlying schema object
|
|
ReleaseSchemaLocs(TRUE);
|
|
if(cSchema)
|
|
{
|
|
ULONG lSize = (ULONG)m_arrSchemaLocs.GetSize();
|
|
BOOL bFail = FALSE;
|
|
for(ULONG lIndex = 0 ; lIndex < cSchema ; lIndex++)
|
|
{
|
|
if(pstrSchemaLocation[lIndex])
|
|
{
|
|
if(strTemp = SysAllocString(pstrSchemaLocation[lIndex]))
|
|
{
|
|
if(-1 == m_arrSchemaLocs.Add((void *) strTemp))
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
bFail = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = E_INVALIDARG;
|
|
bFail = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(bFail)
|
|
{
|
|
ReleaseSchemaLocs(TRUE);
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Get Schemas to be included from the and call methods to add schema includes
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIToXML::AddSchemaIncludes()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
ULONG lSize = (ULONG)m_arrSchemaLocs.GetSize();
|
|
|
|
for(ULONG lIndex = 0 ; lIndex < lSize && SUCCEEDED(hr) ; lIndex++)
|
|
{
|
|
hr = m_pSchema->AddXSDInclude((BSTR)m_arrSchemaLocs.ElementAt(lIndex));
|
|
|
|
}
|
|
return hr;
|
|
|
|
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Set the WMI object to be converted
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIToXML::SetWMIObject(IWbemClassObject *pObject)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
SAFE_RELEASE_PTR(m_pIObject);
|
|
hr = pObject->QueryInterface(IID_IWbemClassObject , (void **)&m_pIObject);
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
VARIANT vGenus;
|
|
IXMLDOMNode *ptempNode = NULL;
|
|
VariantInit(&vGenus);
|
|
|
|
m_bClass = TRUE;
|
|
hr = m_pIObject->Get(GENUSPROP,0,&vGenus,NULL,NULL);
|
|
|
|
// if __GENUS property is not available then
|
|
// object is considered to be an instance
|
|
if(FAILED(hr) || (SUCCEEDED(hr) && vGenus.lVal != CLASS_GENUS) )
|
|
{
|
|
m_bClass = FALSE;
|
|
hr = S_OK;
|
|
}
|
|
|
|
// Checking if the object is a DCOM object
|
|
if(SUCCEEDED(m_pIObject->QueryInterface(IID_IXMLDOMNode , (void **)&ptempNode)))
|
|
{
|
|
SAFE_RELEASE_PTR(ptempNode);
|
|
m_bDCOMObj = FALSE;
|
|
}
|
|
}
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
SAFE_DELETE_PTR(m_pInstance);
|
|
SAFE_DELETE_PTR(m_pSchema);
|
|
if(m_bClass)
|
|
{
|
|
m_pSchema = new CWMIXMLSchema;
|
|
}
|
|
else
|
|
{
|
|
m_pInstance = new CWMIXMLInstance;
|
|
}
|
|
|
|
if(!m_pInstance && !m_pSchema)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Overloaded function to get XML of a given object and put data into BSTR
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIToXML::GetXML(BSTR & strOut)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
if(IsClass())
|
|
{
|
|
hr = GetSchema();
|
|
}
|
|
else
|
|
{
|
|
hr = GetInstance();
|
|
}
|
|
}
|
|
|
|
// call this function to dump the stream data
|
|
// to a file and also to output string
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
LogAndSetOutputString(m_pITmpStream,TRUE,&strOut);
|
|
}
|
|
SAFE_RELEASE_PTR(m_pITmpStream);
|
|
|
|
return hr;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Overloaded function to get XML of a given object and put data into the stream
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIToXML::GetXML(IStream *pStream)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
if(IsClass())
|
|
{
|
|
hr = GetSchema();
|
|
}
|
|
else
|
|
{
|
|
hr = GetInstance();
|
|
}
|
|
}
|
|
|
|
// call this function to Log the stream data to a file
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
LogAndSetOutputString(pStream);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function to initialize the SchemaObject member variable
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIToXML::InitSchemaObject()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
VARIANT vClass;
|
|
VARIANT vParentClass;
|
|
|
|
VariantInit(&vClass);
|
|
VariantInit(&vParentClass);
|
|
|
|
if(SUCCEEDED(hr = m_pSchema->FInit()))
|
|
{
|
|
// Get class name and parent class name
|
|
if(SUCCEEDED(hr = m_pIObject->Get(CLASSNAMEPROP,0,&vClass,NULL,NULL)) &&
|
|
SUCCEEDED(hr = m_pIObject->Get(PARENTCLASSPROP,0,&vParentClass,NULL,NULL)) )
|
|
{
|
|
hr = m_pSchema->SetWMIClass( vClass.vt == VT_BSTR ? vClass.bstrVal : NULL,
|
|
vParentClass.vt == VT_BSTR ? vParentClass.bstrVal : NULL);
|
|
|
|
// Add Include if parent class is not already set
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
m_pSchema->SetFlags(m_lFlags);
|
|
// Add include for the parent class if not alread present
|
|
hr = AddIncludesForClassIfAlreadyNotPresent(vParentClass.bstrVal);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = SetStream(m_pITmpStream);
|
|
}
|
|
|
|
VariantClear(&vClass);
|
|
VariantClear(&vParentClass);
|
|
|
|
return hr;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Put the data in the stream to the output BSTR if required and
|
|
// dump the contents of the stream to a file
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIToXML::LogAndSetOutputString(IStream *pStream ,BOOL bStrout,BSTR * pstrOut)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
UINT nLoggingLevel = 0;
|
|
STATSTG stat;
|
|
memset(&stat,0,sizeof(STATSTG));
|
|
|
|
hr = pStream->Stat(&stat,STATFLAG_NONAME );
|
|
hr = CopyStream(m_pITmpStream,pStream,!(m_lFlags & WMI_XMLINST_NONAMESPACE));
|
|
|
|
nLoggingLevel = GetLoggingLevel();
|
|
|
|
if(SUCCEEDED(hr) && (pstrOut || nLoggingLevel))
|
|
{
|
|
|
|
LARGE_INTEGER lCur;
|
|
LARGE_INTEGER lSeek;
|
|
ULONG cb = INITBUFFSIZE;
|
|
ULONG cbAlloc = cb;
|
|
char * pBuffer = NULL;
|
|
ULONG lBytesRead = 0;
|
|
|
|
memset(&lSeek,0,sizeof(LARGE_INTEGER));
|
|
memset(&lCur,0,sizeof(LARGE_INTEGER));
|
|
|
|
pBuffer = new char[cbAlloc];
|
|
|
|
memset(&stat,0,sizeof(STATSTG));
|
|
hr = pStream->Stat(&stat,STATFLAG_NONAME );
|
|
if(pBuffer)
|
|
{
|
|
|
|
// Store the current seek pointer
|
|
pStream->Seek(lSeek,STREAM_SEEK_CUR,(ULARGE_INTEGER *)&lCur);
|
|
|
|
pStream->Seek(lSeek,STREAM_SEEK_SET,NULL);
|
|
hr = pStream->Read(pBuffer,cb,&cb);
|
|
lBytesRead = cb;
|
|
while(hr == S_OK && (lBytesRead >= cbAlloc))
|
|
{
|
|
char *pTemp = pBuffer;
|
|
|
|
cbAlloc += BUFFINCRSIZE;
|
|
cb = BUFFINCRSIZE;
|
|
|
|
pBuffer = new char[cbAlloc];
|
|
if(pBuffer)
|
|
{
|
|
memcpy(pBuffer,pTemp,lBytesRead);
|
|
SAFE_DELETE_ARRAY(pTemp);
|
|
hr = pStream->Read(((BYTE *)pBuffer) + lBytesRead,cb,&cb);
|
|
lBytesRead += cb;
|
|
}
|
|
else
|
|
{
|
|
SAFE_DELETE_ARRAY(pTemp);
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
|
|
if(hr == S_OK)
|
|
{
|
|
pBuffer[lBytesRead] = 0;
|
|
if(bStrout)
|
|
{
|
|
WCHAR * pwcsOut = NULL;
|
|
if(SUCCEEDED(hr = CStringConversion::AllocateAndConvertAnsiToUnicode(pBuffer,pwcsOut)))
|
|
{
|
|
*pstrOut = NULL;
|
|
*pstrOut = SysAllocString(pwcsOut);
|
|
if(!*pstrOut)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
SAFE_DELETE_ARRAY(pwcsOut);
|
|
}
|
|
if(nLoggingLevel)
|
|
{
|
|
WriteToFile(pBuffer);
|
|
}
|
|
}
|
|
SAFE_DELETE_ARRAY(pBuffer);
|
|
// Reset the position to the previous one
|
|
pStream->Seek(lCur,STREAM_SEEK_SET,NULL);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Makes a connection to WMI and gets the Parentclass if alread not obtained
|
|
//
|
|
// FIXX - This function will not be use later after bug 251872 is fixed
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIToXML::GetClass(BSTR strClass,IWbemClassObject ** ppObject)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if(!m_pConnection)
|
|
{
|
|
// If the object is a DCOM object
|
|
if(IsDCOMObj())
|
|
{
|
|
BSTR strNamespace = NULL;
|
|
|
|
if(SUCCEEDED(hr = ExtractNamespace(strNamespace)))
|
|
{
|
|
m_pConnection = new CWMIConnection(strNamespace,m_strUser,m_strPassword,m_strLocale);
|
|
|
|
if(!m_pConnection)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
SAFE_FREE_SYSSTRING(strNamespace);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// do HTTP connection FIXX
|
|
}
|
|
}
|
|
|
|
hr = m_pConnection->GetObject(strClass ,ppObject);
|
|
|
|
if(ppObject == NULL && SUCCEEDED(hr))
|
|
{
|
|
hr = S_FALSE; // indicates that there is no parent class
|
|
}
|
|
|
|
|
|
return hr;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Makes a connection to WMI and gets the Parentclass if alread not obtained
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIToXML::ExtractNamespace(BSTR & strNamespace)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
VARIANT vNamespace;
|
|
VARIANT vServer;
|
|
|
|
SAFE_FREE_SYSSTRING(strNamespace);
|
|
|
|
VariantInit(&vNamespace);
|
|
VariantInit(&vServer);
|
|
|
|
if(SUCCEEDED(hr = m_pIObject->Get(NAMESPACE,0,&vNamespace,NULL,NULL)) &&
|
|
SUCCEEDED(hr = m_pIObject->Get(SERVER,0,&vServer,NULL,NULL)) )
|
|
{
|
|
if(vNamespace.vt == VT_BSTR && vServer.vt == VT_BSTR)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
|
|
WCHAR * pNamespace = NULL;
|
|
int nAllocsize = SysStringLen(vServer.bstrVal) + SysStringLen(vNamespace.bstrVal) + 10 ;
|
|
pNamespace = new WCHAR[nAllocsize];
|
|
if(pNamespace)
|
|
{
|
|
swprintf(pNamespace,L"\\\\%s\\%s" , vServer.bstrVal,vNamespace.bstrVal);
|
|
strNamespace = SysAllocString(pNamespace);
|
|
|
|
if(strNamespace)
|
|
{
|
|
hr = S_OK;
|
|
}
|
|
|
|
SAFE_DELETE_ARRAY(pNamespace);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
hr = E_FAIL;
|
|
}
|
|
}
|
|
|
|
VariantClear(&vNamespace);
|
|
VariantClear(&vServer);
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Checks if a property has changed as compared to the property from origin class if
|
|
// the property is propogated from the parent class
|
|
//
|
|
// FIXX - This function will not be use later after bug 251872 is fixed
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIToXML::IsPropertyChange(BSTR strProp,BOOL &bChange)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
IWbemClassObject * pOriginObj = NULL;
|
|
BSTR strClass = NULL;
|
|
LONG cimtype = 0;
|
|
|
|
|
|
VARIANT vOrigVal;
|
|
VARIANT vVal;
|
|
|
|
VariantInit(&vOrigVal);
|
|
VariantInit(&vVal);
|
|
|
|
bChange = FALSE;
|
|
|
|
if(SUCCEEDED(hr = m_pIObject->GetPropertyOrigin(strProp,&strClass)))
|
|
{
|
|
if(SUCCEEDED(hr = GetClass(strClass,&pOriginObj)))
|
|
{
|
|
hr = m_pIObject->Get(strProp,0,&vVal,&cimtype,NULL);
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = pOriginObj->Get(strProp,0,&vOrigVal,&cimtype,NULL);
|
|
}
|
|
|
|
if(SUCCEEDED(hr) && !(cimtype == CIM_OBJECT || cimtype == (CIM_OBJECT | CIM_FLAG_ARRAY)))
|
|
{
|
|
bChange = !(CompareData(&vVal,&vOrigVal));
|
|
}
|
|
|
|
// if the property is a object check if the property type is
|
|
// changed in the class
|
|
if(cimtype == CIM_OBJECT || cimtype == (CIM_OBJECT | CIM_FLAG_ARRAY))
|
|
{
|
|
VariantClear(&vVal);
|
|
VariantClear(&vOrigVal);
|
|
LONG lFlavor = 0;
|
|
|
|
hr = GetQualifier(strProp,CIMTYPEPROP,&vVal,&lFlavor,pOriginObj);
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = GetQualifier(strProp,CIMTYPEPROP,&vVal,&lFlavor);
|
|
}
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
if(_wcsicmp(vVal.bstrVal,vOrigVal.bstrVal))
|
|
{
|
|
bChange = TRUE;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
VariantClear(&vVal);
|
|
VariantClear(&vOrigVal);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Fetches a property / class qualifer
|
|
// strProperty is NULL indicates to get a class qualfier
|
|
// pIObject == NULL indicates that fetching has to be done on m_pIObject
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIToXML::GetQualifier(BSTR strProperty,
|
|
BSTR strQualifier ,
|
|
VARIANT * pvVal ,
|
|
LONG * plFlavor,
|
|
IWbemClassObject *pIObject)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
IWbemClassObject * pIObj = NULL;
|
|
IWbemQualifierSet * pIQualSet = NULL;
|
|
|
|
pIObj = pIObject == NULL ? m_pIObject : pIObject;
|
|
|
|
if(strProperty)
|
|
{
|
|
hr = pIObj->GetPropertyQualifierSet(strProperty,&pIQualSet);
|
|
}
|
|
else
|
|
{
|
|
hr = pIObj->GetQualifierSet(&pIQualSet);
|
|
}
|
|
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = pIQualSet->Get(strQualifier,0,pvVal,plFlavor);
|
|
}
|
|
|
|
SAFE_RELEASE_PTR(pIQualSet);
|
|
|
|
return hr;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Goes thru the list of Schema includes and Adds them if alread not present
|
|
// Called to add includes for embedded properties and parent classes
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIToXML::AddIncludesForClassIfAlreadyNotPresent(BSTR strClass)
|
|
{
|
|
BOOL bFound = FALSE;
|
|
BSTR strSchemaLocofClass = NULL;
|
|
HRESULT hr = S_OK;
|
|
ULONG cSchemaLocs = (ULONG)m_arrSchemaLocs.GetSize();
|
|
|
|
// get the schemaLocation of the given class using the Namespace of the
|
|
// the class( ie TargetNamespace)
|
|
if(SUCCEEDED(hr = GetSchemaLocationOfClass(strClass,strSchemaLocofClass)))
|
|
{
|
|
// go thru the list and check if it is already there
|
|
for(ULONG lIndex = 0 ; lIndex < cSchemaLocs ; lIndex++)
|
|
{
|
|
if(_wcsicmp(strSchemaLocofClass,(BSTR)m_arrSchemaLocs.ElementAt(lIndex)) == 0)
|
|
{
|
|
bFound = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// if <include> is not already added then add them
|
|
if(SUCCEEDED(hr) && bFound == FALSE)
|
|
{
|
|
if(-1 == m_arrSchemaLocs.Add((void *)strSchemaLocofClass))
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Constructs the SchemaLocation of the given class,
|
|
// Assumption: SchemaLocation/TargetNamespace of the class is already set
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIToXML::GetSchemaLocationOfClass(BSTR strClass ,BSTR & strSchemaLoc)
|
|
{
|
|
HRESULT hr = E_OUTOFMEMORY;
|
|
|
|
WCHAR * pStrSchemaLoc = NULL;
|
|
|
|
|
|
LONG lSize = SysStringLen(strClass) + SysStringLen(m_strNamespace) + + wcslen((WCHAR *)STR_CLASS_SCHEMALOC) + 2; // one for BackSlash
|
|
hr = E_OUTOFMEMORY;
|
|
|
|
if(pStrSchemaLoc = new WCHAR[lSize])
|
|
{
|
|
swprintf(pStrSchemaLoc , STR_CLASS_SCHEMALOC , m_strNamespace,strClass);
|
|
if(strSchemaLoc = SysAllocString(pStrSchemaLoc))
|
|
{
|
|
hr = S_OK;
|
|
}
|
|
SAFE_DELETE_ARRAY(pStrSchemaLoc);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Gets XML for the given instance
|
|
//
|
|
// Returns S_OK
|
|
// E_OUTOFMEMORY
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIToXML::GetInstance()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
IWbemQualifierSet *pQualifierSet = NULL;
|
|
|
|
// Initialize the object
|
|
if(SUCCEEDED(hr = InitInstanceObject()))
|
|
{
|
|
// This sets the SchemaLocation of the instance
|
|
hr = SetSchemaLocation();
|
|
}
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = m_pInstance->BeginInstance();
|
|
}
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = AddPropertiesForInstance();
|
|
}
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = m_pInstance->EndInstance();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function to initialize the instance object
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIToXML::InitInstanceObject()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
VARIANT vClass;
|
|
VariantInit(&vClass);
|
|
|
|
hr = m_pIObject->Get(CLASSNAMEPROP,0,&vClass,NULL,NULL);
|
|
|
|
// Not checking for the success of previous call as instances
|
|
// from queries may not have class names
|
|
hr = m_pInstance->FInit(m_lFlags,vClass.bstrVal);
|
|
|
|
VariantClear(&vClass);
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = SetStream(m_pITmpStream);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Sets the SchemaLocation of the instance
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIToXML::SetSchemaLocation()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
if(m_arrSchemaLocs.GetSize())
|
|
{
|
|
if(m_arrSchemaLocs.ElementAt(0))
|
|
{
|
|
hr = m_pInstance->SetSchemaLocation(m_strNamespace,(BSTR)m_arrSchemaLocs.ElementAt(0));
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function to go thru the properties of the WMI object and add it XML schema
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIToXML::AddPropertiesForInstance()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
BSTR strProp = NULL;
|
|
LONG lFlavor = 0;
|
|
LONG cimtype = 0;
|
|
VARIANT vProp;
|
|
BSTR strEmbeddedType = NULL;
|
|
IWbemClassObject * pIInstance = NULL;
|
|
|
|
|
|
VariantInit(&vProp);
|
|
|
|
hr = m_pIObject->BeginEnumeration(WBEM_FLAG_NONSYSTEM_ONLY );
|
|
|
|
|
|
while(hr == S_OK)
|
|
{
|
|
if(S_OK == (hr = m_pIObject->Next(0,&strProp,&vProp,&cimtype,&lFlavor)))
|
|
{
|
|
if(IsEmbededType(cimtype))
|
|
{
|
|
hr = GetEmbeddedType(strProp , strEmbeddedType);
|
|
}
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = m_pInstance->AddProperty(strProp,cimtype,IsPropNull(&vProp)? NULL:&vProp,strEmbeddedType);
|
|
}
|
|
|
|
SAFE_FREE_SYSSTRING(strEmbeddedType);
|
|
SAFE_FREE_SYSSTRING(strProp);
|
|
VariantClear(&vProp);
|
|
}
|
|
}
|
|
m_pIObject->EndEnumeration();
|
|
|
|
|
|
return (hr == WBEM_S_NO_MORE_DATA) ? S_OK : hr;
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// GetEmbeddedType
|
|
// Get the CIMTYPE qualifier of the embedded property and returns the object type of the
|
|
// embedded property
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIToXML::GetEmbeddedType(BSTR strProp , BSTR &strEmbeddedType)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
VARIANT vProp;
|
|
|
|
VariantInit(&vProp);
|
|
|
|
// get the CIMTYPE qualifier and compare it with Object
|
|
// to check if the embedded object is weakly typed or not
|
|
// If not weekly typed then get the name of the class
|
|
// of the embedded property
|
|
BSTR strCimtype = SysAllocString(CIMTYPEPROP);
|
|
if(SUCCEEDED(hr = GetQualifier(strProp,strCimtype ,&vProp)))
|
|
{
|
|
if(_wcsicmp(vProp.bstrVal,OBJECT))
|
|
{
|
|
WCHAR * pTempStr = new WCHAR[SysStringLen(vProp.bstrVal)];
|
|
WCHAR * pTempStr1 = new WCHAR[SysStringLen(vProp.bstrVal)];
|
|
if(pTempStr)
|
|
{
|
|
swscanf(vProp.bstrVal,L"%[^:]:%s",pTempStr1,pTempStr);
|
|
strEmbeddedType = SysAllocString(pTempStr);
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
SAFE_DELETE_ARRAY(pTempStr1);
|
|
SAFE_DELETE_ARRAY(pTempStr);
|
|
}
|
|
}
|
|
SAFE_FREE_SYSSTRING(strCimtype);
|
|
VariantClear(&vProp);
|
|
|
|
return hr;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// SetStream
|
|
// Sets the stream pointer to write
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIToXML::SetStream(IStream *pStream)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
if(SUCCEEDED(hr = CreateStreamOnHGlobal(NULL,TRUE,&m_pITmpStream)))
|
|
{
|
|
if(IsClass())
|
|
{
|
|
hr = m_pSchema->SetStream(m_pITmpStream);
|
|
}
|
|
else
|
|
{
|
|
hr = m_pInstance->SetStream(m_pITmpStream);
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Checks if any LOCAL qualifier exists in the qualifier set
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
BOOL CWMIToXML::CheckIfLocalQualifiersExist(IWbemQualifierSet * pQualifierSet)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
BSTR strQualifier = NULL;
|
|
|
|
if(SUCCEEDED(pQualifierSet->BeginEnumeration(WBEM_FLAG_LOCAL_ONLY)))
|
|
{
|
|
if(S_OK == pQualifierSet->Next(0,&strQualifier,NULL,NULL))
|
|
{
|
|
SAFE_FREE_SYSSTRING(strQualifier);
|
|
bRet = TRUE;
|
|
}
|
|
pQualifierSet->EndEnumeration();
|
|
}
|
|
return bRet;
|
|
}
|