#include #include #include #include #include #include #include #include "wmiconv.h" #include "xmltrnsf.h" #include "errors.h" #include "ui.h" #include "opns.h" #include "resource.h" static HRESULT FilterOutputFromSet(ISWbemXMLDocumentSet *pOutput, CXmlCompUI *pUI ); static HRESULT FilterOutputForSingleObject(IXMLDOMDocument *pOutput, CXmlCompUI *pUI ); static HRESULT CreateXMLTranslator(IWbemXMLConvertor **pConvertor); // Creates the Transformer control static HRESULT CreateControl(IWmiXMLTransformer **ppControl) { return CoCreateInstance (CLSID_WmiXMLTransformer, NULL, CLSCTX_INPROC_SERVER, IID_IWmiXMLTransformer, (LPVOID *)ppControl); } // Sets some properties that control the behaviour of the transformer control HRESULT SetCommonControlProperties(IWmiXMLTransformer *pControl, CXmlCompUI *pUI) { HRESULT hr = S_OK; // The type of encoding required if(SUCCEEDED(hr) && SUCCEEDED(hr = pControl->put_XMLEncodingType(pUI->m_iEncodingType))) { } // Qualifier Filter if(SUCCEEDED(hr) && SUCCEEDED(hr = pControl->put_QualifierFilter((pUI->m_bQualifierLevel)? VARIANT_TRUE : VARIANT_FALSE))) { } // Class Origin Filter if(SUCCEEDED(hr) && SUCCEEDED(hr = pControl->put_ClassOriginFilter((pUI->m_bClassOrigin)? VARIANT_TRUE : VARIANT_FALSE))) { } // Local Only if(SUCCEEDED(hr) && SUCCEEDED(hr = pControl->put_LocalOnly((pUI->m_bLocalOnly)? VARIANT_TRUE : VARIANT_FALSE))) { } // User name if(SUCCEEDED(hr) && pUI->m_pszUser) { BSTR strUser = NULL; if(strUser = SysAllocString(pUI->m_pszUser)) { if(SUCCEEDED(hr = pControl->put_User(strUser))) { } SysFreeString(strUser); } else hr = E_OUTOFMEMORY; } // Password if(SUCCEEDED(hr) && pUI->m_pszPassword) { BSTR strPasswd = NULL; if(strPasswd = SysAllocString(pUI->m_pszPassword)) { if(SUCCEEDED(hr = pControl->put_Password(strPasswd))) { } SysFreeString(strPasswd); } else hr = E_OUTOFMEMORY; } // Impersonation Level if(SUCCEEDED(hr) && SUCCEEDED(hr = pControl->put_ImpersonationLevel(pUI->m_dwImpersonationLevel))) { } // Authentication Level if(SUCCEEDED(hr) && SUCCEEDED(hr = pControl->put_AuthenticationLevel(pUI->m_dwAuthenticationLevel))) { } // Locale if(SUCCEEDED(hr) && pUI->m_pszLocale) { BSTR strLocale = NULL; if(strLocale = SysAllocString(pUI->m_pszLocale)) { if(SUCCEEDED(hr = pControl->put_Locale(strLocale))) { } SysFreeString(strLocale); } else hr = E_OUTOFMEMORY; } return hr; } HRESULT DoGetObject(CXmlCompUI *pUI) { HRESULT hr = E_FAIL; IWmiXMLTransformer *pControl = NULL; // Create the Backend Control if(SUCCEEDED(hr = CreateControl(&pControl))) { // Set most of the operation independent flags if(SUCCEEDED(hr = SetCommonControlProperties(pControl, pUI))) { // Set Object Path, Host Name and Namespace Path BSTR strObjectPath = NULL; if(strObjectPath = SysAllocString(pUI->m_pszObjectPath)) { // Do the operation IXMLDOMDocument *pOutput = NULL; if(SUCCEEDED(hr = pControl->GetObject(strObjectPath, NULL, &pOutput))) { hr = FilterOutputForSingleObject(pOutput, pUI); pOutput->Release(); } } else hr = E_OUTOFMEMORY; SysFreeString(strObjectPath); } pControl->Release(); } return hr; } HRESULT DoQuery(CXmlCompUI *pUI) { HRESULT hr = E_FAIL; IWmiXMLTransformer *pControl = NULL; // Create the Backend Control if(SUCCEEDED(hr = CreateControl(&pControl))) { // Set most of the operation independent flags if(SUCCEEDED(hr = SetCommonControlProperties(pControl, pUI))) { // Set Object Path, Host Name and Namespace Path BSTR strQuery = NULL; if(strQuery = SysAllocString(pUI->m_pszQuery)) { BSTR strNamespacePath = NULL; if(strNamespacePath = SysAllocString(pUI->m_pszNamespacePath)) { // Do the operation ISWbemXMLDocumentSet *pOutput = NULL; BSTR strQueryLanguage = NULL; if(strQueryLanguage = SysAllocString(L"WQL")) { if(SUCCEEDED(hr = pControl->ExecQuery(strNamespacePath, strQuery, strQueryLanguage, NULL, &pOutput))) { hr = FilterOutputFromSet(pOutput, pUI ); pOutput->Release(); } SysFreeString(strQueryLanguage); } } else hr = E_OUTOFMEMORY; SysFreeString(strNamespacePath); } else hr = E_OUTOFMEMORY; } pControl->Release(); } return hr; } HRESULT DoEnumInstance(CXmlCompUI *pUI) { HRESULT hr = E_FAIL; IWmiXMLTransformer *pControl = NULL; // Create the Backend Control if(SUCCEEDED(hr = CreateControl(&pControl))) { // Set most of the operation independent flags if(SUCCEEDED(hr = SetCommonControlProperties(pControl, pUI))) { // Set Object Path, Host Name and Namespace Path BSTR strObjectPath = NULL; if(strObjectPath = SysAllocString(pUI->m_pszObjectPath)) { // Do the operation ISWbemXMLDocumentSet *pOutput = NULL; if(SUCCEEDED(hr = pControl->EnumInstances(strObjectPath, (pUI->m_bDeep)? VARIANT_TRUE : VARIANT_FALSE, NULL, &pOutput))) { hr = FilterOutputFromSet(pOutput, pUI ); pOutput->Release(); } SysFreeString(strObjectPath); } else hr = E_OUTOFMEMORY; } pControl->Release(); } return hr; } HRESULT DoEnumClass(CXmlCompUI *pUI) { HRESULT hr = E_FAIL; IWmiXMLTransformer *pControl = NULL; // Create the Backend Control if(SUCCEEDED(hr = CreateControl(&pControl))) { // Set most of the operation independent flags if(SUCCEEDED(hr = SetCommonControlProperties(pControl, pUI))) { // Set Object Path, Host Name and Namespace Path BSTR strObjectPath = NULL; if(strObjectPath = SysAllocString(pUI->m_pszObjectPath)) { // Do the operation ISWbemXMLDocumentSet *pOutput = NULL; if(SUCCEEDED(hr = pControl->EnumClasses(strObjectPath, (pUI->m_bDeep)? VARIANT_TRUE : VARIANT_FALSE, NULL, &pOutput))) { hr = FilterOutputFromSet(pOutput, pUI ); pOutput->Release(); } } else hr = E_OUTOFMEMORY; SysFreeString(strObjectPath); } pControl->Release(); } return hr; } HRESULT DoEnumInstNames(CXmlCompUI *pUI) { HRESULT hr = E_FAIL; IWmiXMLTransformer *pControl = NULL; // Create the Backend Control if(SUCCEEDED(hr = CreateControl(&pControl))) { // Set most of the operation independent flags if(SUCCEEDED(hr = SetCommonControlProperties(pControl, pUI))) { // Set Object Path, Host Name and Namespace Path BSTR strObjectPath = NULL; if(strObjectPath = SysAllocString(pUI->m_pszObjectPath)) { // Do the operation ISWbemXMLDocumentSet *pOutput = NULL; if(SUCCEEDED(hr = pControl->EnumInstanceNames(strObjectPath, NULL, &pOutput))) { hr = FilterOutputFromSet(pOutput, pUI ); pOutput->Release(); } SysFreeString(strObjectPath); } else hr = E_OUTOFMEMORY; } pControl->Release(); } return hr; } HRESULT DoEnumClassNames(CXmlCompUI *pUI) { HRESULT hr = E_FAIL; IWmiXMLTransformer *pControl = NULL; // Create the Backend Control if(SUCCEEDED(hr = CreateControl(&pControl))) { // Set most of the operation independent flags if(SUCCEEDED(hr = SetCommonControlProperties(pControl, pUI))) { // Set Object Path, Host Name and Namespace Path BSTR strObjectPath = NULL; if(strObjectPath = SysAllocString(pUI->m_pszObjectPath)) { // Do the operation ISWbemXMLDocumentSet *pOutput = NULL; if(SUCCEEDED(hr = pControl->EnumClassNames(strObjectPath, (pUI->m_bDeep)? VARIANT_TRUE : VARIANT_FALSE, NULL, &pOutput))) { hr = FilterOutputFromSet(pOutput, pUI ); pOutput->Release(); } SysFreeString(strObjectPath); } else hr = E_OUTOFMEMORY; } pControl->Release(); } return hr; } STDMETHODIMP MapCommonHeaders (FILE *fp, CXmlCompUI *pUI) { // WRITESIG WriteOutputString(fp, pUI->m_bIsUTF8, L""); if (pUI->m_pszDTDURL) { WriteOutputString(fp, pUI->m_bIsUTF8, L"m_bIsUTF8, pUI->m_pszDTDURL); WriteOutputString(fp, pUI->m_bIsUTF8, L"\">"); } WriteOutputString(fp, pUI->m_bIsUTF8, L""); WriteOutputString(fp, pUI->m_bIsUTF8, L""); return S_OK; } STDMETHODIMP MapCommonTrailers (FILE *fp, CXmlCompUI *pUI) { WriteOutputString(fp, pUI->m_bIsUTF8, L""); WriteOutputString(fp, pUI->m_bIsUTF8, L""); return S_OK; } STDMETHODIMP MapDeclGroupHeaders (FILE *fp, CXmlCompUI *pUI ) { switch(pUI->m_iDeclGroupType) { case wmiXMLDeclGroup: WriteOutputString(fp, pUI->m_bIsUTF8, L""); break; case wmiXMLDeclGroupWithName: WriteOutputString(fp, pUI->m_bIsUTF8, L""); break; case wmiXMLDeclGroupWithPath: WriteOutputString(fp, pUI->m_bIsUTF8, L""); break; } return S_OK; } STDMETHODIMP MapDeclGroupTrailers (FILE *fp, CXmlCompUI *pUI) { switch(pUI->m_iDeclGroupType) { case wmiXMLDeclGroup: WriteOutputString(fp, pUI->m_bIsUTF8, L""); break; case wmiXMLDeclGroupWithName: WriteOutputString(fp, pUI->m_bIsUTF8, L""); break; case wmiXMLDeclGroupWithPath: WriteOutputString(fp, pUI->m_bIsUTF8, L""); break; } return S_OK; } HRESULT FilterOutputFromSet(ISWbemXMLDocumentSet *pOutput, CXmlCompUI *pUI ) { // Get the output file handle FILE *fp = NULL; if(pUI->m_pszOutputFileName) fp = _wfopen(pUI->m_pszOutputFileName, L"w"); else fp = stdout; if(!fp) { CreateMessage(XML_COMP_ERR_UNABLE_TO_OPEN_OUTPUT); return E_FAIL; } // Go thru each element in the set HRESULT hr = S_OK; if(SUCCEEDED(hr = MapCommonHeaders(fp, pUI))) { if(SUCCEEDED(hr = MapDeclGroupHeaders(fp, pUI))) { IXMLDOMDocument *pDoc = NULL; bool bError = false; while(!bError && SUCCEEDED(hr = pOutput->NextDocument(&pDoc)) && hr != S_FALSE) { if(SUCCEEDED(hr = WriteOneDeclGroupDocument(fp, pDoc, pUI))) { } else bError = true; pDoc->Release(); pDoc = NULL; } if(!bError && SUCCEEDED(hr = MapDeclGroupTrailers(fp, pUI))) { hr = MapCommonTrailers(fp, pUI); } } } // Close any file that we opened if(fp != stdout) fclose(fp); return hr; } HRESULT FilterOutputForSingleObject(IXMLDOMDocument *pOutput, CXmlCompUI *pUI ) { // Get the output file handle FILE *fp = NULL; if(pUI->m_pszOutputFileName) fp = _wfopen(pUI->m_pszOutputFileName, L"w"); else fp = stdout; if(!fp) { CreateMessage(XML_COMP_ERR_UNABLE_TO_OPEN_OUTPUT); return E_FAIL; } // Map the object to XML HRESULT hr = S_OK; if(SUCCEEDED(hr = MapCommonHeaders(fp, pUI))) { if(SUCCEEDED(hr = MapDeclGroupHeaders(fp, pUI))) { // We get a document with a CLASS or INSTANCE at the top level IXMLDOMElement *pTopElement = NULL; if(SUCCEEDED(hr = pOutput->get_documentElement(&pTopElement))) { if(SUCCEEDED(hr = WriteOneDeclGroupNode(fp, pTopElement, pUI))) { if(SUCCEEDED(hr = MapDeclGroupTrailers(fp, pUI))) { hr = MapCommonTrailers(fp, pUI); } } pTopElement->Release(); } } } // Close any file that we opened if(fp != stdout) fclose(fp); return hr; } HRESULT WriteOneDeclGroupNode(FILE *fp, IXMLDOMNode *pTopElement, CXmlCompUI *pUI ) { HRESULT hr = E_FAIL; BSTR strTopName = NULL; if(SUCCEEDED(hr = pTopElement->get_nodeName(&strTopName))) { switch(pUI->m_iDeclGroupType) { // In this case you have to extract a CLASS or an INSTANCE from // 1. CLASS or INSTANCE for GetObject and ENumClass // 2. VALUE.NAMEDINSTANCE for EnumInstance // 3. VALUE.OBJECTWITHPATH for ExecQuery case wmiXMLDeclGroup: if(_wcsicmp(strTopName, L"CLASS") == 0 || _wcsicmp(strTopName, L"INSTANCE") == 0 ) { WriteOutputString(fp, pUI->m_bIsUTF8, L""); hr = WriteNode(fp, pTopElement, pUI); WriteOutputString(fp, pUI->m_bIsUTF8, L""); } else if(_wcsicmp(strTopName, L"VALUE.NAMEDINSTANCE") == 0 ) { IXMLDOMElement *pInstance = NULL; if(SUCCEEDED(hr = GetFirstImmediateElement(pTopElement, &pInstance, L"INSTANCE"))) { WriteOutputString(fp, pUI->m_bIsUTF8, L""); hr = WriteNode(fp, pInstance, pUI); WriteOutputString(fp, pUI->m_bIsUTF8, L""); pInstance->Release(); } } else if(_wcsicmp(strTopName, L"VALUE.OBJECTWITHPATH") == 0 ) { IXMLDOMElement *pObject = NULL; if(SUCCEEDED(hr = GetFirstImmediateElement(pTopElement, &pObject, L"INSTANCE"))) { WriteOutputString(fp, pUI->m_bIsUTF8, L""); hr = WriteNode(fp, pObject, pUI); WriteOutputString(fp, pUI->m_bIsUTF8, L""); pObject->Release(); } else if(SUCCEEDED(hr = GetFirstImmediateElement(pTopElement, &pObject, L"CLASS"))) { WriteOutputString(fp, pUI->m_bIsUTF8, L""); hr = WriteNode(fp, pObject, pUI); WriteOutputString(fp, pUI->m_bIsUTF8, L""); pObject->Release(); } } else hr = E_FAIL; break; // In this case you have to create a VALUE.NAMEDOBJECT from // 1. CLASS or INSTANCE for GetObject and ENumClass - For this we need the name of the class/instance // 2. VALUE.NAMEDINSTANCE for EnumInstance - Pretty Straightforward // 3. VALUE.OBJECTWITHPATH for ExecQuery - Pretty Straightforward case wmiXMLDeclGroupWithName: if(_wcsicmp(strTopName, L"CLASS") == 0 || _wcsicmp(strTopName, L"INSTANCE") == 0 ) { hr = ConvertObjectToNamedObject(fp, pTopElement, pUI); } else if(_wcsicmp(strTopName, L"VALUE.NAMEDINSTANCE") == 0 ) { hr = ConvertNamedInstanceToNamedObject(fp, pTopElement, pUI); } else if(_wcsicmp(strTopName, L"VALUE.OBJECTWITHPATH") == 0 ) { hr = ConvertObjectWithPathToNamedObject(fp, pTopElement, pUI); } else hr = E_FAIL; break; // In this case you have to create a VALUE.OBJECTWITHPATH from // 1. CLASS or INSTANCE for GetObject and ENumClass - For this we need the full path of the class/instance // 2. VALUE.NAMEDINSTANCE for EnumInstance - For this we need the host and namespace of the class/instance // 3. VALUE.OBJECTWITHPATH for ExecQuery - Pretty Straightforward case wmiXMLDeclGroupWithPath: if(_wcsicmp(strTopName, L"CLASS") == 0 || _wcsicmp(strTopName, L"INSTANCE") == 0 ) { hr = ConvertObjectToObjectWithPath(fp, pTopElement, pUI); } else if(_wcsicmp(strTopName, L"VALUE.NAMEDINSTANCE") == 0 ) { // Get the CLASS or INSTANCE in it IXMLDOMElement *pObject = NULL; if(FAILED(hr = GetFirstImmediateElement(pTopElement, &pObject, L"INSTANCE"))) hr = GetFirstImmediateElement(pTopElement, &pObject, L"CLASS"); // Convert the CLASS or INSTANCE to VALUE.OBJECTWITHPATH if(SUCCEEDED(hr)) hr = ConvertObjectToObjectWithPath(fp, pTopElement, pUI); } else if(_wcsicmp(strTopName, L"VALUE.OBJECTWITHPATH") == 0 ) { hr = WriteNode(fp, pTopElement, pUI); } else hr = E_FAIL; break; } SysFreeString(strTopName); } return hr; } HRESULT WriteOneDeclGroupDocument(FILE *fp, IXMLDOMDocument *pDocument, CXmlCompUI *pUI ) { // Check the top level document - it can be CLASS, INSTANCE, VALUE.NAMEDINSTANCE or VALUE.OBJECTWITHPATH // Or it can be CLASSNAME or INSTANCENAME for an EnumClassName or EnumInstanceName operation IXMLDOMElement *pTopElement = NULL; HRESULT hr = E_FAIL; if(SUCCEEDED(hr = pDocument->get_documentElement(&pTopElement))) { hr = WriteOneDeclGroupNode(fp, pTopElement, pUI); pTopElement->Release(); } return hr; } HRESULT DoCompilation(IStream *pInputFile, CXmlCompUI *pUI) { HRESULT hr = E_FAIL; IWmiXMLTransformer *pControl = NULL; // Create the Backend Control if(SUCCEEDED(hr = CreateControl(&pControl))) { // Set most of the operation independent flags if(SUCCEEDED(hr = SetCommonControlProperties(pControl, pUI))) { // Wrap the inptu stream in a variant VARIANT vInput; if(SUCCEEDED(hr = SaveStreamToUnkVariant(pInputFile, &vInput))) { // Set Host Name and Namespace Path BSTR strNamespacePath = NULL; if(strNamespacePath = SysAllocString(pUI->m_pszNamespacePath)) { VARIANT_BOOL bStatus = VARIANT_FALSE; BSTR strErrors = NULL; // Do the operation if(SUCCEEDED(hr = pControl->Compile(&vInput, strNamespacePath, pUI->m_dwClassFlags, pUI->m_dwInstanceFlags, (pUI->m_iCommand == XML_COMP_WELL_FORM_CHECK)? WmiXMLCompilationWellFormCheck : ((pUI->m_iCommand == XML_COMP_VALIDITY_CHECK)? WmiXMLCompilationValidityCheck : WmiXMLCompilationFullCompileAndLoad), NULL, &bStatus))) { if(bStatus == VARIANT_FALSE) { hr = E_FAIL; if(SUCCEEDED(pControl->get_CompilationErrors(&strErrors))) { if(strErrors) fwprintf(stderr, strErrors); SysFreeString(strErrors); } } } } else hr = E_OUTOFMEMORY; SysFreeString(strNamespacePath); VariantClear(&vInput); } } pControl->Release(); } return hr; } HRESULT SaveStreamToBstrVariant (IStream *pStream, VARIANT *pVariant) { HRESULT result = E_FAIL; LARGE_INTEGER offset; offset.LowPart = offset.HighPart = 0; // Seek to the beginning of the stream if(SUCCEEDED(result = pStream->Seek (offset, STREAM_SEEK_SET, NULL))) { // Get the size of the stream STATSTG statstg; if (SUCCEEDED(result = pStream->Stat(&statstg, STATFLAG_NONAME))) { ULONG cbSize = (statstg.cbSize).LowPart; CHAR *pText = NULL; if(cbSize && (pText = new CHAR [cbSize])) { // Read the Ascii data ULONG cbActualRead = 0; if (SUCCEEDED(result = pStream->Read(pText, cbSize, &cbActualRead))) { // Convert to Unicode //======================= // Calculate size of the resulting Wide char string DWORD dwSizeOfBstr = MultiByteToWideChar( CP_ACP, /* codepage */ 0, /* character-type options */ pText, /* address of string to map */ cbActualRead, /* number of characters in string */ NULL, /* address of wide-character buffer */ 0); /* size of wide-character buffer */ if(dwSizeOfBstr > 0 ) { // ALllocate the wide char string LPWSTR theWcharString = NULL; if(theWcharString = new WCHAR [dwSizeOfBstr]) { //Convert the Ansi string to Bstr dwSizeOfBstr = MultiByteToWideChar( CP_ACP, /* codepage */ 0, /* character-type options */ pText, /* address of string to map */ cbActualRead, /* number of characters in string */ theWcharString, /* address of wide-character buffer */ dwSizeOfBstr); /* size of wide-character buffer */ BSTR strVal = NULL; if(strVal = SysAllocStringLen(theWcharString, dwSizeOfBstr)) { VariantInit(pVariant); pVariant->vt = VT_BSTR; pVariant->bstrVal = strVal; result = S_OK; } else result = E_OUTOFMEMORY; delete [] theWcharString; } else result = E_OUTOFMEMORY; } } delete [] pText; } else result = E_OUTOFMEMORY; } } return result; } HRESULT 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 WriteNode(FILE *fp, IXMLDOMNode *pOutputNode, CXmlCompUI *pUI) { HRESULT hr = S_OK; if(pOutputNode) { BSTR strXML = NULL; if(SUCCEEDED(hr = pOutputNode->get_xml(&strXML))) { WriteOutputString(fp, pUI->m_bIsUTF8, strXML, SysStringLen(strXML)); SysFreeString(strXML); } } return hr; } HRESULT ConvertNamedInstanceToNamedObject(FILE *fp, IXMLDOMNode *pTopElement, CXmlCompUI *pUI) { // Write the beginning tag WriteOutputString(fp, pUI->m_bIsUTF8, L""); // Write the INSTANCENAME tag and its contents IXMLDOMElement *pInstanceName = NULL; if(SUCCEEDED(GetFirstImmediateElement(pTopElement, &pInstanceName, L"INSTANCENAME"))) { WriteNode(fp, pInstanceName, pUI); pInstanceName->Release(); } // Write the INSTANCE tag and its contents IXMLDOMElement *pInstance = NULL; if(SUCCEEDED(GetFirstImmediateElement(pTopElement, &pInstance, L"INSTANCE"))) { WriteNode(fp, pInstance, pUI); pInstance->Release(); } // Write the terminating tag WriteOutputString(fp, pUI->m_bIsUTF8, L""); return S_OK; } HRESULT ConvertObjectWithPathToNamedObject(FILE *fp, IXMLDOMNode *pTopElement, CXmlCompUI *pUI) { // Write the beginning tag WriteOutputString(fp, pUI->m_bIsUTF8, L""); // This could be a class or an instance IXMLDOMElement *pClass = NULL; IXMLDOMElement *pInstancePath = NULL; // Get the INSTANCEPATH tag if(SUCCEEDED(GetFirstImmediateElement(pTopElement, &pInstancePath, L"INSTANCEPATH"))) { // Get the INSTANCENAME below the INSTANCEPATH IXMLDOMElement *pInstanceName = NULL; if(SUCCEEDED(GetFirstImmediateElement(pInstancePath, &pInstanceName, L"INSTANCENAME"))) { WriteNode(fp, pInstanceName, pUI); pInstanceName->Release(); } // Write the INSTANCE tag and its contents IXMLDOMElement *pInstance = NULL; if(SUCCEEDED(GetFirstImmediateElement(pTopElement, &pInstance, L"INSTANCE"))) { WriteNode(fp, pInstance, pUI); pInstanceName->Release(); } pInstancePath->Release(); } // Get the CLASS tag else if(SUCCEEDED(GetFirstImmediateElement(pTopElement, &pClass, L"CLASS"))) { WriteNode(fp, pClass, pUI); pClass->Release(); } // Write the terminating tag WriteOutputString(fp, pUI->m_bIsUTF8, L""); return S_OK; } HRESULT ConvertObjectToNamedObject(FILE *fp, IXMLDOMNode *pTopElement, CXmlCompUI *pUI ) { // From the UI, we get the path to the object // From the path, we get the name of the object (INSTANCENAME for instance, nothing for a CLASS) // From that and the CLASS or INSTANCE, we get a VALUE.NAMEDOBJECT BSTR strName = NULL; HRESULT hr = E_FAIL; if(SUCCEEDED(hr = pTopElement->get_nodeName(&strName))) { // Nothing much to be done for a class if(_wcsicmp(strName, L"CLASS") == 0) { // Write the beginning tag WriteOutputString(fp, pUI->m_bIsUTF8, L""); // Write the Class hr = WriteNode(fp, pTopElement, pUI); // Write the terminating tag WriteOutputString(fp, pUI->m_bIsUTF8, L""); } // For the instance, we need to use the UI to get the instance name else if(_wcsicmp(strName, L"INSTANCE") == 0) { // Create a stream IStream *pStream = NULL; if (SUCCEEDED(hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream))) { // Create the convertor IWbemXMLConvertor *pConvertor = NULL; if(SUCCEEDED(hr = CreateXMLTranslator(&pConvertor))) { // Get the XML representation in a Stream BSTR strInstanceName = NULL; if(strInstanceName = SysAllocString(pUI->m_pszObjectPath)) { if(SUCCEEDED(hr = pConvertor->MapInstanceNameToXML(strInstanceName, NULL, pStream))) { // Convert the stream to a DOM Element IXMLDOMElement *pInstanceName = NULL; if(SUCCEEDED(hr = ConvertStreamToDOM(pStream, &pInstanceName))) { // Write the beginning tag WriteOutputString(fp, pUI->m_bIsUTF8, L""); // Write the InstanceName WriteNode(fp, pInstanceName, pUI); // Write the Instance WriteNode(fp, pTopElement, pUI); // Write the terminating tag WriteOutputString(fp, pUI->m_bIsUTF8, L""); pInstanceName->Release(); } } SysFreeString(strInstanceName); } pConvertor->Release(); } pStream->Release(); } } SysFreeString(strName); } return hr; } HRESULT ConvertObjectToObjectWithPath(FILE *fp, IXMLDOMNode *pTopElement, CXmlCompUI *pUI ) { // From the UI, we get the path to the object // From the path, we get an INSTANCEPATH or CLASSPATH // From that and the CLASS or INSTANCE, we get a VALUE.OBJECTWITHPATH BSTR strName = NULL; HRESULT hr = E_FAIL; if(SUCCEEDED(hr = pTopElement->get_nodeName(&strName))) { // Create a stream IStream *pStream = NULL; if (SUCCEEDED(hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream))) { // Create the convertor IWbemXMLConvertor *pConvertor = NULL; if(SUCCEEDED(hr = CreateXMLTranslator(&pConvertor))) { // Get the XML representation in a Stream BSTR strObjectPath = NULL; if(strObjectPath = SysAllocString(pUI->m_pszObjectPath)) { // Get the Object Path if(_wcsicmp(strName, L"INSTANCE") == 0) hr = pConvertor->MapInstancePathToXML(strObjectPath, NULL, pStream); else if(_wcsicmp(strName, L"CLASS") == 0) hr = pConvertor->MapClassPathToXML(strObjectPath, NULL, pStream); else hr = E_FAIL; if(SUCCEEDED(hr)) { // Convert the stream to a DOM Element IXMLDOMElement *pObjectPath = NULL; if(SUCCEEDED(hr = ConvertStreamToDOM(pStream, &pObjectPath))) { // Write the beginning tag WriteOutputString(fp, pUI->m_bIsUTF8, L""); // Write the INSTANCEPATH/CLASSPATH WriteNode(fp, pObjectPath, pUI); // Write the INSTANCE/CLASS WriteNode(fp, pTopElement, pUI); // Write the terminating tag WriteOutputString(fp, pUI->m_bIsUTF8, L""); pObjectPath->Release(); } } SysFreeString(strObjectPath); } pConvertor->Release(); } pStream->Release(); } SysFreeString(strName); } return hr; } // RAJESHR - Remove this to read the GUID frm the registry on startup DEFINE_GUID(CLSID_WbemXMLConvertor, 0x610037ec, 0xce06, 0x11d3, 0x93, 0xfc, 0x0, 0x80, 0x5f, 0x85, 0x37, 0x71); HRESULT CreateXMLTranslator(IWbemXMLConvertor **pConvertor) { HRESULT result = E_FAIL; // Create the XMLAdaptor object //****************************************************** *pConvertor = NULL; if(SUCCEEDED(result = CoCreateInstance(CLSID_WbemXMLConvertor, 0, CLSCTX_INPROC_SERVER, IID_IWbemXMLConvertor, (LPVOID *) pConvertor))) { } return result; } HRESULT ConvertStreamToDOM(IStream *pStream, IXMLDOMElement **pInstanceName) { HRESULT hr = E_FAIL; VARIANT vInput; VariantInit(&vInput); vInput.vt = VT_UNKNOWN; vInput.punkVal = pStream; // Seek to the beginning of the stream //======================================== LARGE_INTEGER offset; offset.LowPart = offset.HighPart = 0; if(SUCCEEDED(hr = pStream->Seek (offset, STREAM_SEEK_SET, NULL))) { // Create an XML document for the stream //============================== IXMLDOMDocument *pDocument = NULL; if(SUCCEEDED(hr = CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument, (LPVOID *)&pDocument))) { // Load the Variant into the DOC VARIANT_BOOL bResult = VARIANT_TRUE; if(SUCCEEDED(hr = pDocument->put_async(VARIANT_FALSE)) && SUCCEEDED(hr = pDocument->put_validateOnParse(VARIANT_FALSE)) && SUCCEEDED(hr = pDocument->put_resolveExternals(VARIANT_FALSE)) ) { if(SUCCEEDED(hr = pDocument->load(vInput, &bResult))) { if(bResult == VARIANT_TRUE) { hr = pDocument->get_documentElement(pInstanceName); } else { hr = E_FAIL; // This code is for debugging only IXMLDOMParseError *pError = NULL; if(SUCCEEDED(pDocument->get_parseError(&pError))) { LONG errorCode = 0; pError->get_errorCode(&errorCode); LONG line=0, linepos=0; BSTR reason=NULL, srcText = NULL; if(SUCCEEDED(pError->get_line(&line)) && SUCCEEDED(pError->get_linepos(&linepos)) && SUCCEEDED(pError->get_reason(&reason)) && SUCCEEDED(pError->get_srcText(&srcText))) { } pError->Release(); if(reason) SysFreeString(reason); if(srcText) SysFreeString(srcText); pError->Release(); } } } } pDocument->Release(); } // No need to clear the variant since we didnt AddRef() the pStream } return hr; } HRESULT SaveStreamToUnkVariant (IStream *pStream, VARIANT *pVariant) { VariantInit(pVariant); pVariant->vt = VT_UNKNOWN; pVariant->punkVal = pStream; pStream->AddRef(); return S_OK; } // Converts LPWSTR to its UTF-8 encoding // Returns 0 if it fails // static DWORD ConvertWideStringToUTF8(LPCWSTR theWcharString, ULONG lNumberOfWideChars, LPSTR * lppszRetValue) { // Find the length of the Ansi string required DWORD dwBytesToWrite = WideCharToMultiByte( CP_UTF8, // UTF-8 code page 0, // performance and mapping flags theWcharString, // address of wide-character string lNumberOfWideChars, // number of characters in string NULL, // address of buffer for new string 0, // size of buffer NULL, // address of default for unmappable // characters NULL); // address of flag set when default char. used if(dwBytesToWrite == 0 ) return dwBytesToWrite; // Allocate the required length for the Ansi string *lppszRetValue = NULL; if(!(*lppszRetValue = new char[dwBytesToWrite])) return 0; // Convert BSTR to ANSI dwBytesToWrite = WideCharToMultiByte( CP_UTF8, // code page 0, // performance and mapping flags theWcharString, // address of wide-character string lNumberOfWideChars, // number of characters in string *lppszRetValue, // address of buffer for new string dwBytesToWrite, // size of buffer NULL, // address of default for unmappable // characters NULL // address of flag set when default // char. used ); return dwBytesToWrite; } void WriteOutputString(FILE *fp, BOOL bIsUTF8, LPCWSTR pszData, DWORD dwLen) { // If we're not being asked to write UTF-8, then no conversion needs to be done // Otherwise, we first need to convert the string to UTF8 and then write it if(bIsUTF8) { // Convert the unicode string to UTF8 DWORD dwBytesToWrite = 0; LPSTR pszUTF8 = NULL; if(dwBytesToWrite = ConvertWideStringToUTF8(pszData, (dwLen)? dwLen : wcslen(pszData), &pszUTF8)) { // Write the binary UTF8 bytes fwrite((LPVOID)pszUTF8, sizeof(char), dwBytesToWrite, fp); delete [] pszUTF8; } } else // Directly write a Unicode string fwrite((LPVOID)pszData, sizeof(WCHAR), (dwLen)? dwLen : wcslen(pszData), fp); }