***************************************************************************/ // // Copyright (c) 2000-2001 Microsoft Corporation // // wmitoxml.cpp // // ramrao 13 Nov 2000 - Created // // // Declaration of CWMIToXML class // //***************************************************************************/ #include #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 // 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 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 , 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 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 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 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; }