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

270 lines
7.2 KiB
C++

// sinkobject.cpp: implementation of the CSinkObject class.
//
// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
//
//////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "sinkobject.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
TreeNode * NewTreeNode(void)
{
TreeNode *pTheNode = new TreeNode;
pTheNode->bstrName = NULL;
pTheNode->pFirstChild = NULL;
pTheNode->pNextSibling = NULL;
return pTheNode;
}
CSinkObject::CSinkObject(TreeNode *pTheNode, IWbemServices *pNS,
CPtrList *pHistoryList, int iIcon /*=0*/)
{
m_cRef = 0;
m_pParentNode = pTheNode;
m_pNamespace = pNS;
m_pHist = CopyPtrList(pHistoryList);
m_iIcon = iIcon;
}
CSinkObject::~CSinkObject()
{
}
STDMETHODIMP CSinkObject::QueryInterface(REFIID riid, LPVOID FAR *ppv)
{
*ppv=NULL;
if (riid == IID_IUnknown || riid == IID_IWbemObjectSink)
*ppv=this;
if (*ppv != NULL)
{
((LPUNKNOWN)*ppv)->AddRef();
return NOERROR;
}
return E_NOINTERFACE;
}
STDMETHODIMP_(ULONG) CSinkObject::AddRef(void)
{
return ++m_cRef;
}
STDMETHODIMP_(ULONG) CSinkObject::Release(void)
{
if (--m_cRef != 0L)
return m_cRef;
delete this;
return 0L;
}
STDMETHODIMP CSinkObject::Indicate(long lObjectCount,
IWbemClassObject **ppObjArray)
{
VARIANT vPath, vServ, vName, vClass;
HRESULT hr;
WCHAR wcBuffer[200];
int iBufSize = 200;
BSTR bstrMyQuery = NULL;
WCHAR* wcpTheQuery = wcBuffer;
VariantInit(&vPath);
VariantInit(&vServ);
VariantInit(&vName);
VariantInit(&vClass);
for(int i = 0; i < lObjectCount; i++)
{
if(SUCCEEDED(hr = ppObjArray[i]->Get(L"__RELPATH", 0, &vPath, NULL,
NULL)))
{
if(!IsInHistory(V_BSTR(&vPath)))
{
// Do the history entry
TreeNode *pAddNode = NewTreeNode();
pAddNode->bstrName = SysAllocString(V_BSTR(&vPath));
m_pHist->AddTail(pAddNode);
hr = ppObjArray[i]->Get(L"__SERVER", 0, &vServ, NULL, NULL);
hr = ppObjArray[i]->Get(L"__NAMESPACE", 0, &vName, NULL, NULL);
hr = ppObjArray[i]->Get(L"__CLASS", 0, &vClass, NULL, NULL);
wcscpy(wcBuffer, L"\\\\");
wcscat(wcBuffer, V_BSTR(&vServ));
wcscat(wcBuffer, L"\\");
wcscat(wcBuffer, V_BSTR(&vName));
wcscat(wcBuffer, L":");
wcscat(wcBuffer, V_BSTR(&vPath));
// Create the new TreeNode and place it in the treelist
TreeNode *pTheNode = NewTreeNode();
pTheNode->bstrName = SysAllocString(wcBuffer);
// Set the item image
// This should depend on what type of association it is
pTheNode->iImage = m_iIcon;
if(m_pParentNode->pFirstChild == NULL)
m_pParentNode->pFirstChild = pTheNode;
else if(m_pParentNode->pFirstChild->pNextSibling == NULL)
m_pParentNode->pFirstChild->pNextSibling = pTheNode;
else
{
pTheNode->pNextSibling =
m_pParentNode->pFirstChild->pNextSibling;
m_pParentNode->pFirstChild->pNextSibling = pTheNode;
}
// If this a Win32_ComputerSystem we do not want to get it's
// associators because _EVERYTHING_ is associated with the
// system.
if(wcscmp(V_BSTR(&vClass), L"Win32_ComputerSystem") != 0)
{
WCHAR wcTheQuery[300];
BSTR bstrWQL = SysAllocString(L"WQL");
// Create our sink for the upcoming ComponentPart query
CSinkObject *pTheSinkCompOf = new CSinkObject(pTheNode,
m_pNamespace,
m_pHist, 2);
wcscpy(wcTheQuery, L"associators of {");
wcscat(wcTheQuery, V_BSTR(&vPath));
wcscat(wcTheQuery, L"} where assocclass=CIM_Component");
bstrMyQuery = SysAllocString(wcTheQuery);
hr = m_pNamespace->ExecQueryAsync(bstrWQL, bstrMyQuery, 0,
NULL, pTheSinkCompOf);
if(FAILED(hr))
TRACE(_T("*Indicate Component Query Failed\n"));
SysFreeString(bstrMyQuery);
// Create our sink for the upcoming ComponentGroup query
CSinkObject *pTheSinkOwnerOf = new CSinkObject(pTheNode,
m_pNamespace,
m_pHist, 3);
wcscpy(wcTheQuery, L"associators of {");
wcscat(wcTheQuery, V_BSTR(&vPath));
wcscat(wcTheQuery, L"} where assocclass=CIM_ElementSetting");
bstrMyQuery = SysAllocString(wcTheQuery);
hr = m_pNamespace->ExecQueryAsync(bstrWQL, bstrMyQuery, 0,
NULL, pTheSinkOwnerOf);
if(FAILED(hr))
TRACE(_T("*Indicate ElementSetting Query Failed\n"));
SysFreeString(bstrMyQuery);
// Create our sink for the upcoming Dependency query
CSinkObject *pTheSinkDepend = new CSinkObject(pTheNode,
m_pNamespace,
m_pHist, 4);
wcscpy(wcTheQuery, L"associators of {");
wcscat(wcTheQuery, V_BSTR(&vPath));
wcscat(wcTheQuery, L"} where assocclass=CIM_Dependency");
bstrMyQuery = SysAllocString(wcTheQuery);
hr = m_pNamespace->ExecQueryAsync(bstrWQL, bstrMyQuery, 0,
NULL, pTheSinkDepend);
if(FAILED(hr))
TRACE(_T("*Indicate Dependency Query Failed\n"));
// Create our sink for the upcoming SettingContext query
CSinkObject *pTheSinkSetCont = new CSinkObject(pTheNode, m_pNamespace,
m_pHist, 3);
wcscpy(wcTheQuery, L"associators of {");
wcscat(wcTheQuery, V_BSTR(&vPath));
wcscat(wcTheQuery, L"} where assocclass=CIM_SettingContext");
bstrMyQuery = SysAllocString(wcTheQuery);
hr = m_pNamespace->ExecQueryAsync(bstrWQL, bstrMyQuery, 0, NULL,
pTheSinkSetCont);
SysFreeString(bstrMyQuery);
// Create our sink for the upcoming DependencyContext query
CSinkObject *pTheSinkDepCont = new CSinkObject(pTheNode, m_pNamespace,
m_pHist, 4);
wcscpy(wcTheQuery, L"associators of {");
wcscat(wcTheQuery, V_BSTR(&vPath));
wcscat(wcTheQuery, L"} where assocclass=CIM_DependencyContext");
bstrMyQuery = SysAllocString(wcTheQuery);
hr = m_pNamespace->ExecQueryAsync(bstrWQL, bstrMyQuery, 0, NULL,
pTheSinkDepCont);
SysFreeString(bstrMyQuery);
SysFreeString(bstrWQL);
}
}
}
}
return WBEM_NO_ERROR;
}
STDMETHODIMP CSinkObject::SetStatus(long lFlags, long lParam, BSTR strParam,
IWbemClassObject* pObjParam)
{
m_pErrorObj = pObjParam;
if(pObjParam)
pObjParam->AddRef();
return WBEM_NO_ERROR;
}
bool CSinkObject::IsInHistory(BSTR bstrNewObj)
{
POSITION pPos;
void *pTmp;
TreeNode *pTheItem;
if((!m_pHist->IsEmpty()) && ((pPos = m_pHist->GetHeadPosition()) != NULL))
{
while(pPos != NULL)
{
pTmp = m_pHist->GetNext(pPos);
pTheItem = (TreeNode *)pTmp;
if(0 == wcscmp(pTheItem->bstrName, bstrNewObj))
return true;
}
}
return false;
}
CPtrList * CSinkObject::CopyPtrList(CPtrList *pList)
{
POSITION pPos;
void *pTmp;
CPtrList *pNewList = new CPtrList();
if((!pList->IsEmpty()) && ((pPos = pList->GetHeadPosition()) != NULL))
{
while(pPos != NULL)
{
pTmp = pList->GetNext(pPos);
pNewList->AddTail(pTmp);
}
}
return pNewList;
}