2025-04-27 07:49:33 -04:00

484 lines
13 KiB
C++

#include "precomp.h"
#include <assert.h>
#include <stdio.h>
#include <objsafe.h>
#include <wbemcli.h>
#include <xmlparser.h>
#include "XMLTransportClientHelper.h"
#include "XMLClientPacket.h"
#include "XMLClientPacketFactory.h"
#include "HTTPConnectionAgent.h"
#include "myStream.h"
#include "MyPendingStream.h"
#include "putfact.h"
HRESULT STDMETHODCALLTYPE CCompileFactory::BeginChildren(
IXMLNodeSource* pSource,
XML_NODE_INFO* pNodeInfo)
{
// Make note of which DECLGROUP is being processed
// Set the types of elements to be manufactured by the factory
//============================================================
if(_wcsicmp(pNodeInfo->pwcText, L"DECLGROUP") == 0)
{
m_declGroupType = WMI_XML_DECLGROUP;
LPCWSTR pszElement = L"VALUE.OBJECT";
SetElements(&pszElement, 1);
}
else if(_wcsicmp(pNodeInfo->pwcText, L"DECLGROUP.WITHNAME") == 0)
{
m_declGroupType = WMI_XML_DECLGROUP_WITH_NAME;
LPCWSTR pszElement = L"VALUE.NAMEDOBJECT";
SetElements(&pszElement, 1);
}
else if(_wcsicmp(pNodeInfo->pwcText, L"DECLGROUP.WITHPATH") == 0)
{
m_declGroupType = WMI_XML_DECLGROUP_WITH_PATH;
LPCWSTR pszElement = L"VALUE.OBJECTWITHPATH";
SetElements(&pszElement, 1);
}
return S_OK;
}
HRESULT STDMETHODCALLTYPE CCompileFactory::EndChildren(
IXMLNodeSource* pSource,
BOOL fEmpty,
XML_NODE_INFO* pNodeInfo)
{
HRESULT hr = E_FAIL;
// See if it is the kind of elements we are manufacturing
if(IsInterestingElement(pNodeInfo->pwcText))
{
// Stop the stream from issuing any more data
m_pStream->SetPending(TRUE);
// Add the document to the list of documents that we have
hr = AddDocumentToList(m_pCurrentDocument);
m_pCurrentDocument->Release();
m_pCurrentDocument = NULL;
}
else
hr = S_OK;
//fwprintf(stderr, L"EndChildren() called for %s\n", pNodeInfo->pwcText);
return hr;
}
HRESULT STDMETHODCALLTYPE CCompileFactory::Error(
IXMLNodeSource* pSource,
HRESULT hrErrorCode,
USHORT cNumRecs,
XML_NODE_INFO __RPC_FAR **aNodeInfo)
{
BSTR strReason = NULL;
ULONG uLine = 0 , uPosition = 0;
pSource->GetErrorInfo(&strReason);
uLine = pSource->GetLineNumber();
uPosition = pSource->GetLinePosition();
fwprintf(stderr, L"An Error occured at Line:%d, Position%d, Source:%s, Reason%X\n",
uLine, uPosition, strReason, hrErrorCode);
return S_OK;
}
HRESULT STDMETHODCALLTYPE CCompileFactory::CreateNode(
IXMLNodeSource __RPC_FAR *pSource,
PVOID pNodeParent,
USHORT cNumRecs,
XML_NODE_INFO __RPC_FAR **aNodeInfo)
{
HRESULT hr = S_OK;
if(cNumRecs)
{
//fwprintf(stderr, L"CreateNode() called for %s with %d elements\n", (*aNodeInfo)->pwcText), cNumRecs;
switch( (aNodeInfo[0])->dwType)
{
case XML_ELEMENT:
{
// If it is an interesting element
// the (!pNodeParent) check leaves out embedded objects
if(IsInterestingElement(aNodeInfo[0]->pwcText))
{
if(!pNodeParent)
{
// Create a new document for the class or instance
if(m_pCurrentDocument)
{
m_pCurrentDocument->Release();
m_pCurrentDocument = NULL;
}
if(SUCCEEDED(hr = CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER,
IID_IXMLDOMDocument, (LPVOID *)&m_pCurrentDocument)))
{
// Make sure this is the parent node for this call
pNodeParent = m_pCurrentDocument;
}
}
// Otherwise it is an embedded object. Just add it to the parent below.
}
else
{
// Make a check as to whether this is the LOCALNAMESPACEPATH or NAMESPACEPATH in DECLGROUP and DECLGROUP.WITHNAME
if(!pNodeParent)
{
if (_wcsicmp(aNodeInfo[0]->pwcText, L"NAMESPACEPATH") == 0 ||_wcsicmp(aNodeInfo[0]->pwcText, L"NAMESPACEPATH") == 0)
{
if (_wcsicmp(aNodeInfo[0]->pwcText, L"NAMESPACEPATH") == 0)
m_bNamespacePathProvided = TRUE;
else if (_wcsicmp(aNodeInfo[0]->pwcText, L"NAMESPACEPATH") == 0)
m_bLocalNamespacePathProvided = TRUE;
}
else if (_wcsicmp(aNodeInfo[0]->pwcText, L"HOST") == 0)
{
m_bInHost = TRUE;
}
else if (_wcsicmp(aNodeInfo[0]->pwcText, L"NAMESPACE") == 0)
{
hr = AppendNamespace(aNodeInfo, cNumRecs);
}
}
}
// Create a XML DOM Node under the parent node
if(SUCCEEDED(hr) && m_pCurrentDocument)
{
IXMLDOMNode *pCurrentNode = NULL;
if(SUCCEEDED(hr = AddChildNode((IXMLDOMNode *)pNodeParent, aNodeInfo, cNumRecs, &pCurrentNode)))
{
// Set the parent for the children of this element
aNodeInfo[0]->pNode = pCurrentNode;
}
}
}
break;
case XML_PCDATA:
{
if(pNodeParent)
{
if(m_bInHost)
{
m_bInHost = FALSE;
hr = SetHost(aNodeInfo, cNumRecs);
}
else
hr = AddPCDATA((IXMLDOMNode *)pNodeParent, aNodeInfo);
}
else
{
// Nothing needs to be done. This is PCDATA in a node that we arent interested in
}
}
break;
case XML_CDATA:
{
if(pNodeParent)
{
hr = AddCDATA((IXMLDOMNode *)pNodeParent, aNodeInfo);
}
else
{
// Nothing needs to be done. This is PCDATA in a node that we arent interested in
}
}
}
}
else
fwprintf(stderr, L"CreateNode() called for with 0 elements\n");
assert(SUCCEEDED(hr));
return hr;
}
HRESULT CCompileFactory::AddDocumentToList(IXMLDOMDocument *pNewDocument)
{
HRESULT hr = S_OK;
if(1+m_dwNumDocuments > m_dwMaxNumDocuments)
{
// Reallocate an array
IXMLDOMDocument **ppNewArray = NULL;
m_dwMaxNumDocuments += 5; // Increase the size by 5
ppNewArray = new IXMLDOMDocument*[m_dwMaxNumDocuments];
if(ppNewArray)
{
// Copy old elements to this one
for(DWORD i=0; i<m_dwNumDocuments; i++)
ppNewArray[i] = m_ppDocuments[i];
delete [] m_ppDocuments;
m_ppDocuments = ppNewArray;
}
else
hr = E_OUTOFMEMORY;
}
// Copy the latest one
m_ppDocuments[m_dwNumDocuments++] = pNewDocument;
pNewDocument->AddRef();
assert(SUCCEEDED(hr));
return hr;
}
HRESULT CCompileFactory::AddChildNode(IXMLDOMNode *pNodeParent, XML_NODE_INFO **aNodeInfo, USHORT cNumRecs, IXMLDOMNode **ppCurrentNode)
{
HRESULT hr = E_FAIL;
BSTR strElementName = NULL;
if(strElementName = SysAllocString(aNodeInfo[0]->pwcText))
{
// Create a new Element in the document
*ppCurrentNode = NULL;
IXMLDOMElement *pNewElement = NULL;
if(SUCCEEDED(hr = m_pCurrentDocument->createElement(strElementName, &pNewElement)))
{
// Add the element to the parent node
if(SUCCEEDED(hr = pNodeParent->appendChild(pNewElement, NULL)))
{
// Add the attributes of the new element
if(SUCCEEDED(hr = AddAttributes(pNewElement, aNodeInfo, cNumRecs)))
{
pNewElement->AddRef();
*ppCurrentNode = pNewElement;
}
}
pNewElement->Release();
}
SysFreeString(strElementName);
}
else
hr = E_OUTOFMEMORY;
assert(SUCCEEDED(hr));
return hr;
}
HRESULT CCompileFactory::AddPCDATA(IXMLDOMNode *pNodeParent, XML_NODE_INFO **aNodeInfo)
{
HRESULT hr = S_OK;
BSTR strElementValue = NULL;
if(aNodeInfo[0]->dwType == XML_PCDATA)
{
// Just copy the text
if(strElementValue = SysAllocStringLen(aNodeInfo[0]->pwcText, aNodeInfo[0]->ulLen))
{
}
else
hr = E_OUTOFMEMORY;
}
else if(aNodeInfo[0]->dwType == XML_CDATA)
{
// Just copy the text - RAJESHR is this correct
if(strElementValue = SysAllocStringLen(aNodeInfo[0]->pwcText, aNodeInfo[0]->ulLen))
{
}
else
hr = E_OUTOFMEMORY;
}
if(strElementValue)
{
hr = pNodeParent->put_text(strElementValue);
SysFreeString(strElementValue);
}
return hr;
}
HRESULT CCompileFactory::AddCDATA(IXMLDOMNode *pNodeParent, XML_NODE_INFO **aNodeInfo)
{
return S_OK;
}
HRESULT CCompileFactory::AddAttributes(IXMLDOMElement *pElement, XML_NODE_INFO **aNodeInfo, USHORT cNumRecs)
{
// If the element has no attributes, then return.
if(cNumRecs <= 1)
return S_OK;
HRESULT hr = E_FAIL;
DWORD i=1;
while(i<cNumRecs)
{
if(aNodeInfo[i]->dwType == XML_ATTRIBUTE)
{
// Get the Attribute Name
BSTR strAttributeName = NULL;
if(strAttributeName = SysAllocStringLen(aNodeInfo[i]->pwcText, aNodeInfo[i]->ulLen))
{
// Get the attribute value
i++;
BSTR strAttributeValue = NULL;
if(aNodeInfo[i]->dwType == XML_PCDATA)
{
// Just copy the text
if(strAttributeValue = SysAllocStringLen(aNodeInfo[i]->pwcText, aNodeInfo[i]->ulLen))
{
}
else
hr = E_OUTOFMEMORY;
}
else if(aNodeInfo[i]->dwType == XML_CDATA)
{
// Just copy the text - RAJESHR is this correct
if(strAttributeValue = SysAllocStringLen(aNodeInfo[i]->pwcText, aNodeInfo[i]->ulLen))
{
}
else
hr = E_OUTOFMEMORY;
}
if(strAttributeValue)
{
VARIANT vValue;
VariantInit(&vValue);
vValue.vt = VT_BSTR;
vValue.bstrVal = strAttributeValue;
hr = pElement->setAttribute(strAttributeName, vValue);
VariantClear(&vValue);
}
SysFreeString(strAttributeName);
}
else
hr = E_OUTOFMEMORY;
}
i++; // Move on to the next element in the array
}
assert(SUCCEEDED(hr));
return hr;
}
HRESULT CCompileFactory::GetDocument(IXMLDOMDocument **ppDocument)
{
// See if there is one more document that can be given away
if(m_dwAvailableDocIndex >= m_dwNumDocuments)
return E_FAIL;
*ppDocument = m_ppDocuments[m_dwAvailableDocIndex++];
// Allow more data to be read from the stream if we dont have another document to be buffered
if(m_dwAvailableDocIndex > m_dwNumDocuments - 1)
m_pStream->SetPending(FALSE);
return S_OK;
}
BOOL CCompileFactory::IsInterestingElement(LPCWSTR pszElementName)
{
BOOL bRetVal = FALSE;
for(DWORD i=0; i<m_dwNumElements; i++)
{
if(_wcsicmp(m_pszElementNames[i], pszElementName) == 0)
{
bRetVal = TRUE;
break;
}
}
return bRetVal;
}
HRESULT CCompileFactory::SetHost(XML_NODE_INFO **aNodeInfo, USHORT cNumRecs)
{
HRESULT hr = E_FAIL;
// Just copy the value of the elementaNodeInfo[0]->pwcText,
delete [] m_pszHostName;
m_pszHostName = NULL;
if(m_pszHostName = new WCHAR [aNodeInfo[0]->ulLen + 1])
{
wcsncpy(m_pszHostName, aNodeInfo[0]->pwcText, aNodeInfo[0]->ulLen);
hr = S_OK;
}
else
hr = E_OUTOFMEMORY;
return hr;
}
HRESULT CCompileFactory::AppendNamespace(XML_NODE_INFO **aNodeInfo, USHORT cNumRecs)
{
HRESULT hr = E_FAIL;
// There's got to be exactly one attribute in a NAMESPACE element
if(cNumRecs == 3)
{
if(aNodeInfo[1]->dwType == XML_ATTRIBUTE)
{
// Get the NAME Attribute
if(_wcsnicmp(aNodeInfo[1]->pwcText, L"NAME", aNodeInfo[1]->ulLen) == 0)
{
// Get the attribute value
if(aNodeInfo[2]->dwType == XML_PCDATA)
{
// Just append the value of the attribute
LPCWSTR pszPreviousValue = m_pszLocalNamespacePath;
if(pszPreviousValue) // Append a "\" and then the namespace component
{
m_pszLocalNamespacePath = NULL;
if(m_pszLocalNamespacePath = new WCHAR [wcslen(pszPreviousValue) + 1 + aNodeInfo[2]->ulLen + 1])
{
wcscpy(m_pszLocalNamespacePath, pszPreviousValue);
wcscat(m_pszLocalNamespacePath, L"\\");
wcsncat(m_pszLocalNamespacePath, aNodeInfo[2]->pwcText, aNodeInfo[2]->ulLen);
hr = S_OK;
}
else
hr = E_OUTOFMEMORY;
}
else // Just copy the namespace component
{
m_pszLocalNamespacePath = NULL;
if(m_pszLocalNamespacePath = new WCHAR [aNodeInfo[2]->ulLen + 1])
{
wcsncpy(m_pszLocalNamespacePath, aNodeInfo[2]->pwcText, aNodeInfo[2]->ulLen);
hr = S_OK;
}
else
hr = E_OUTOFMEMORY;
}
}
else if(aNodeInfo[2]->dwType == XML_CDATA)
{
// Just append the value of the attribute
LPCWSTR pszPreviousValue = m_pszLocalNamespacePath;
if(pszPreviousValue) // Append a "\" and then the namespace component
{
m_pszLocalNamespacePath = NULL;
if(m_pszLocalNamespacePath = new WCHAR [wcslen(pszPreviousValue) + 1 + aNodeInfo[2]->ulLen + 1])
{
wcscpy(m_pszLocalNamespacePath, pszPreviousValue);
wcscat(m_pszLocalNamespacePath, L"\\");
wcsncat(m_pszLocalNamespacePath, aNodeInfo[2]->pwcText, aNodeInfo[2]->ulLen);
hr = S_OK;
}
else
hr = E_OUTOFMEMORY;
}
else // Just copy the namespace component
{
m_pszLocalNamespacePath = NULL;
if(m_pszLocalNamespacePath = new WCHAR [aNodeInfo[2]->ulLen + 1])
{
wcsncpy(m_pszLocalNamespacePath, aNodeInfo[2]->pwcText, aNodeInfo[2]->ulLen);
hr = S_OK;
}
else
hr = E_OUTOFMEMORY;
}
}
}
}
}
return hr;
}