270 lines
7.2 KiB
C++
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;
|
|
} |