Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

857 lines
26 KiB

//***************************************************************************
//
// Copyright (c) 1997-2002 Microsoft Corporation, All Rights Reserved
//
//***************************************************************************
#include "wmicom.h"
#include "wdmshell.h"
#include "wmimof.h"
#include "wmimap.h"
#include <stdlib.h>
#include <winerror.h>
//=============================================================================================================
//*************************************************************************************************************
//
//
// CWMIStandardShell
//
//
//*************************************************************************************************************
//=============================================================================================================
CWMIStandardShell::CWMIStandardShell()
{
m_pClass = NULL;
m_pWDM = NULL;
m_fInit = FALSE;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
CWMIStandardShell::~CWMIStandardShell()
{
SAFE_DELETE_PTR(m_pWDM);
SAFE_DELETE_PTR(m_pClass);
m_fInit = FALSE;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CWMIStandardShell::Initialize(WCHAR * wcsClass, BOOL fInternalEvent, CHandleMap * pList,
BOOL fUpdate, ULONG uDesiredAccess,
IWbemServices __RPC_FAR * pServices,
IWbemServices __RPC_FAR * pRepository,
IWbemObjectSink __RPC_FAR * pHandler,
IWbemContext __RPC_FAR *pCtx)
{
HRESULT hr = WBEM_E_FAILED;
if( !m_fInit )
{
m_pClass = new CWMIProcessClass(0);
if( m_pClass )
{
hr = m_pClass->Initialize();
if( S_OK == hr )
{
m_pClass->WMI()->SetWMIPointers(pList,pServices,pRepository,pHandler,pCtx);
m_pClass->SetHiPerf(FALSE);
if( !fInternalEvent )
{
if( wcsClass )
{
hr = m_pClass->SetClass(wcsClass);
if( SUCCEEDED(hr))
{
if( !m_pClass->ValidClass())
{
hr = WBEM_E_INVALID_OBJECT;
}
}
}
}
else
{
if( wcsClass )
{
hr = m_pClass->SetClassName(wcsClass);
}
}
if( hr == S_OK )
{
m_pWDM = new CProcessStandardDataBlock();
if( m_pWDM )
{
m_pWDM->SetDesiredAccess(uDesiredAccess);
m_pWDM->SetClassProcessPtr(m_pClass);
m_pWDM->UpdateNamespace(fUpdate);
m_fInit = TRUE;
}
}
}
}
}
return hr;
}
//////////////////////////////////////////////////////////////////////////////////////
HRESULT CWMIStandardShell::SetGuidForEvent( WORD wType, WCHAR * wcsGuid, int cchSize )
{
HRESULT hRes = WBEM_E_FAILED;
if( m_fInit )
{
// ==============================================
// Inform the WMI we want to register for the
// event
// ==============================================
memset(wcsGuid,NULL,cchSize);
switch( wType ){
case MOF_ADDED:
hRes = S_OK;
m_pClass->SetHardCodedGuidType(wType);
hRes = StringCchCopyW ( wcsGuid, cchSize, WMI_RESOURCE_MOF_ADDED_GUID );
break;
case MOF_DELETED:
hRes = S_OK;
m_pClass->SetHardCodedGuidType(wType);
hRes = StringCchCopyW ( wcsGuid, cchSize, WMI_RESOURCE_MOF_REMOVED_GUID );
break;
case STANDARD_EVENT:
hRes = m_pClass->GetQualifierString( NULL, L"guid", wcsGuid, cchSize );
break;
}
}
return hRes;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CWMIStandardShell::ProcessSingleInstance( WCHAR * wcsInstanceName/*, PWNODE_SINGLE_INSTANCE pwSingle */)
{
HRESULT hr = WBEM_E_FAILED;
if( m_fInit )
{
//======================================================
// If we are not working with a specific guy, then
// query WMI to get it, if, of course it is valid
//======================================================
if( m_pClass->ValidClass() ){
/* if( pwSingle){
hr = m_pWDM->SetSingleInstancePtr((PWNODE_SINGLE_INSTANCE)pwSingle);
}
else{*/
hr = m_pWDM->OpenWMI();
if( hr == S_OK ){
hr = m_pWDM->QuerySingleInstance(wcsInstanceName);
}
// }
//======================================================
// If we got the data and a valid class, the process it
//======================================================
if( hr == S_OK )
{
hr = m_pWDM->ReadWMIDataBlockAndPutIntoWbemInstance();
if( SUCCEEDED(hr))
{
hr = m_pClass->SendInstanceBack();
}
}
}
}
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CWMIStandardShell::ProcessAllInstances( )
{
HRESULT hr = WBEM_E_FAILED;
if( m_fInit )
{
//======================================================
// If we are not working with a specific guy, then
// query WMI to get it
//======================================================
// if( pwAllNode ){
// hr = m_pWDM->SetAllInstancePtr((PWNODE_ALL_DATA)pwAllNode);
// }
// else{
hr = m_pWDM->OpenWMI();
if( hr == S_OK ){
hr = m_pWDM->QueryAllData();
}
// }
//======================================================
// If we got the data then process it
//======================================================
if( hr == S_OK ){
while( TRUE ){
hr = m_pWDM->ReadWMIDataBlockAndPutIntoWbemInstance();
if( hr == S_OK ){
hr = m_pClass->SendInstanceBack();
}
if( hr != S_OK ){
break;
}
if( !m_pWDM->MoreToProcess() ){
break;
}
}
}
}
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CWMIStandardShell::ExecuteMethod( WCHAR * wcsInstance, WCHAR * MethodName, IWbemClassObject * pParentClass,
IWbemClassObject * pInClassData,
IWbemClassObject * pInClass,
IWbemClassObject * pOutClass)
{
HRESULT hr = WBEM_E_FAILED;
if( m_fInit )
{
CWMIProcessClass MethodInput(0);
CWMIProcessClass MethodOutput(0);
if( SUCCEEDED( MethodInput.Initialize() ) && SUCCEEDED( MethodOutput.Initialize() ) )
{
MethodInput.SetWMIPointers(m_pClass);
MethodOutput.SetWMIPointers(m_pClass);
//======================================================
// Initialize all of the necessary stuff and get the
// definition of the class we are working with
//======================================================
if( pInClass )
{
hr = MethodInput.SetClass(pInClass);
if( hr != S_OK ){
return hr;
}
MethodInput.SetClassPointerOnly(pInClassData);
}
if( pOutClass ){
hr = MethodOutput.SetClass(pOutClass, MethodInput.GetNumberOfProperties () );
if( hr != S_OK ){
return hr;
}
}
//======================================================
// Notify WMI which class we are going to be executing
// methods on
//======================================================
hr = m_pWDM->OpenWMI();
if( hr == S_OK ){
m_pWDM->SetMethodInput(&MethodInput);
m_pWDM->SetMethodOutput(&MethodOutput);
m_pClass->SetClassPointerOnly(pParentClass);
// Create in Param Block
// ========================
BYTE * InputBuffer=NULL;
ULONG uInputBufferSize=0L;
hr = m_pWDM->CreateInParameterBlockForMethods(InputBuffer,uInputBufferSize);
if( hr == S_OK ){
// Allocate Out Param Block
// ========================
ULONG WMIMethodId = m_pClass->GetMethodId(MethodName);
//======================================================
// If we got the data then process it
//======================================================
hr = m_pWDM->CreateOutParameterBlockForMethods();
if( hr == S_OK ){
hr = m_pWDM->ExecuteMethod( WMIMethodId,wcsInstance, uInputBufferSize,InputBuffer);
}
}
SAFE_DELETE_ARRAY(InputBuffer);
}
}
}
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CWMIStandardShell::ProcessEvent( WORD wBinaryMofType, PWNODE_HEADER WnodeHeader)
{
HRESULT hr = S_OK;
if( m_fInit )
{
//===================================================
// If the image path is empty, it is a binary guid
// which we need to process
//===================================================
if( wBinaryMofType ){
hr = ProcessBinaryGuidsViaEvent( WnodeHeader, wBinaryMofType );
}
else{
//=======================================================
// Process the data event
//=======================================================
if( WnodeHeader->Flags & WNODE_FLAG_ALL_DATA ){
hr = m_pWDM->SetAllInstancePtr((PWNODE_ALL_DATA)WnodeHeader);
}
else if( WnodeHeader->Flags & WNODE_FLAG_SINGLE_INSTANCE ){
hr = m_pWDM->SetSingleInstancePtr((PWNODE_SINGLE_INSTANCE)WnodeHeader);
}
if( hr == S_OK ){
//===================================================================
// Process all wnodes.
//===================================================================
while( TRUE ){
if( S_OK == ( hr = m_pWDM->ReadWMIDataBlockAndPutIntoWbemInstance()) ){
//===========================================================
// Now, send it to all consumers registered for this event
//===========================================================
hr = m_pClass->SendInstanceBack();
}
//===============================================================
// If we errored out,we don't know that any of the pointers
// are ok, so get out of there.
//===============================================================
else{
break;
}
//===============================================================
// Process all of the instances for this event
//===============================================================
if( !m_pWDM->MoreToProcess() ){
break;
}
}
}
}
//============================================================================
// Since we never allocated anything, just used the incoming stuff,
// for cleanliness sake, init ptrs to null
//============================================================================
m_pWDM->InitDataBufferToNull();
}
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CWMIStandardShell::FillInAndSubmitWMIDataBlob( IWbemClassObject * pIClass, int nTypeOfPut, CVARIANT & vList)
{
HRESULT hr = WBEM_E_FAILED;
if( m_fInit )
{
hr = m_pWDM->OpenWMI();
if( hr == S_OK ){
// Now, work with the class we want to write
if( SUCCEEDED(m_pClass->SetClassPointerOnly(pIClass))){
if( nTypeOfPut == PUT_WHOLE_INSTANCE ){
hr = m_pWDM->ConstructDataBlock(TRUE) ;
if( S_OK == hr ){
hr = m_pWDM->SetSingleInstance();
}
}
else{
if(m_pWDM->GetListOfPropertiesToPut(nTypeOfPut,vList)){
hr = m_pWDM->PutSingleProperties();
}
else{
hr = WBEM_E_INVALID_CONTEXT;
}
}
}
}
}
return(hr);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CWMIStandardShell::QueryAndProcessAllBinaryGuidInstances(CNamespaceManagement & Namespace, BOOL & fMofHasChanged,
KeyList * pArrDriversInRegistry)
{
HRESULT hr = WBEM_E_FAILED;
if( m_fInit )
{
hr = WBEM_E_OUT_OF_MEMORY;
CAutoWChar wcsTmpKey(MAX_PATH*3);
if( wcsTmpKey.Valid() )
{
m_pClass->SetHardCodedGuidType(MOF_ADDED);
m_pClass->GetGuid();
hr = m_pWDM->OpenWMI();
if( hr == S_OK )
{
hr = m_pWDM->QueryAllData();
//======================================================
// If we got the data then process it
//======================================================
if( hr == S_OK )
{
while( SUCCEEDED ( hr ) )
{
hr = m_pWDM->ProcessNameBlock(FALSE);
if( hr == S_OK )
{
hr = m_pWDM->ProcessBinaryMofDataBlock(CVARIANT(m_pClass->GetClassName()),wcsTmpKey, MAX_PATH*3);
if( hr == S_OK )
{
hr = Namespace.UpdateQuery(L" and Name != ",wcsTmpKey);
if( pArrDriversInRegistry )
{
pArrDriversInRegistry->Remove(wcsTmpKey);
}
}
if( !m_pWDM->MoreToProcess() )
{
break;
}
}
}
}
}
}
}
return hr;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CWMIStandardShell::ProcessBinaryGuidsViaEvent( PWNODE_HEADER WnodeHeader, WORD wType )
{
HRESULT hr = WBEM_E_FAILED;
if( m_fInit )
{
//======================================================
// Initialize all of the necessary stuff and get the
// definition of the class we are working with
//======================================================
m_pClass->SetHardCodedGuidType(wType);
//==================================================================
// We are working with a specific guy, so we need to find out
// if it is a Binary Mof Guid to do a query all data on, or
// if it is a Resource Name and File to open up and extract
//==================================================================
if( WnodeHeader->Flags & WNODE_FLAG_ALL_DATA )
{
hr = m_pWDM->SetAllInstancePtr((PWNODE_ALL_DATA)WnodeHeader);
if(hr == S_OK)
{
hr = m_pWDM->ReadWMIDataBlockAndPutIntoWbemInstance();
}
}
else if( WnodeHeader->Flags & WNODE_FLAG_SINGLE_INSTANCE )
{
hr = m_pWDM->SetSingleInstancePtr((PWNODE_SINGLE_INSTANCE)WnodeHeader);
if( hr == S_OK )
{
hr = m_pWDM->ProcessDataBlock();
}
}
else
{
hr = WBEM_E_INVALID_PARAMETER;
}
}
return hr;
}
//************************************************************************************************************
//============================================================================================================
//
// CWMIHiPerfShell
//
//============================================================================================================
//************************************************************************************************************
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
CWMIHiPerfShell::CWMIHiPerfShell(BOOL fAutoCleanup)
{
m_fAutoCleanup = fAutoCleanup;
m_pWDM = NULL;
m_pClass = NULL;
m_fInit = FALSE;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CWMIHiPerfShell::Initialize (
BOOL fUpdate,
ULONG uDesiredAccess,
CHandleMap * pList,WCHAR * wcs,
IWbemServices __RPC_FAR * pServices,
IWbemServices __RPC_FAR * pRepository,
IWbemObjectSink __RPC_FAR * pHandler,
IWbemContext __RPC_FAR *pCtx
)
{
HRESULT hr = WBEM_E_FAILED;
m_pClass = new CWMIProcessClass(0);
if( m_pClass )
{
hr = m_pClass->Initialize();
if( S_OK == hr )
{
m_pClass->WMI()->SetWMIPointers(pList,pServices,pRepository,pHandler,pCtx);
m_pClass->SetHiPerf(TRUE);
m_pClass->SetClass(wcs);
m_pWDM = new CProcessHiPerfDataBlock;
if( m_pWDM )
{
m_pWDM->SetDesiredAccess(uDesiredAccess);
m_pWDM->UpdateNamespace(fUpdate);
m_pWDM->SetClassProcessPtr(m_pClass);
m_fInit = TRUE;
}
hr = S_OK;
}
}
return hr;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
CWMIHiPerfShell::~CWMIHiPerfShell()
{
if( m_fAutoCleanup )
{
SAFE_DELETE_PTR(m_pClass);
}
SAFE_DELETE_PTR(m_pWDM);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CWMIHiPerfShell::QueryAllHiPerfData()
{
HRESULT hr = WBEM_E_FAILED;
if( m_fInit )
{
//===============================================================
// There is only one handle for this class, so see if we can
// get it
//===============================================================
CAutoBlock(m_pHiPerfMap->GetCriticalSection());
HANDLE WMIHandle = 0;
hr = m_pWDM->GetWMIHandle(WMIHandle);
if( SUCCEEDED(hr))
{
// =====================================================
// Query for all of the objects for this class
// Add all the objects at once into the enumerator
// Handles are guaranteed to be open at this time
//======================================================
hr = QueryAllInstances(WMIHandle,NULL);
}
}
return hr;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CWMIHiPerfShell::RefreshCompleteList()
{
//=======================================================================
// Go through all the enumerators and instances to refresh everything
//=======================================================================
HRESULT hr = WBEM_E_FAILED;
if( m_fInit )
{
CAutoBlock(m_pHiPerfMap->GetCriticalSection());
HANDLE WMIHandle = 0;
IWbemHiPerfEnum * pEnum = NULL;
CWMIProcessClass * pSavedClass = m_pClass;
//==============================================================
//
//==============================================================
hr = m_pHiPerfMap->GetFirstHandle( WMIHandle, m_pClass, pEnum);
while( hr == S_OK )
{
if( WMIHandle )
{
m_pWDM->SetClassProcessPtr(m_pClass);
if( pEnum )
{
hr = QueryAllInstances(WMIHandle,pEnum);
}
else
{
hr = QuerySingleInstance(WMIHandle);
}
if(SUCCEEDED(hr))
{
hr = m_pHiPerfMap->GetNextHandle(WMIHandle,m_pClass,pEnum);
}
}
if( hr == WBEM_S_NO_MORE_DATA )
{
hr = S_OK;
break;
}
}
//================================================================
m_pClass = pSavedClass;
}
return hr;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CWMIHiPerfShell::HiPerfQuerySingleInstance(WCHAR * wcsInstance)
{
HRESULT hr = WBEM_E_FAILED;
if( m_fInit )
{
//======================================================
// Go through the list of handles and get the handles
// to send and how many there are, also, get the
// instance names
//======================================================
CAutoBlock(m_pHiPerfMap->GetCriticalSection());
IWbemObjectAccess * pAccess = NULL;
CWMIProcessClass * pClass = NULL;
HANDLE WMIHandle = 0;
ULONG_PTR lTmp = (ULONG_PTR)pAccess;
hr = m_pHiPerfMap->FindHandleAndGetClassPtr(WMIHandle,lTmp, pClass);
if( SUCCEEDED(hr))
{
hr = QuerySingleInstance(WMIHandle);
}
}
return hr;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CWMIHiPerfShell::AddAccessObjectToRefresher(IWbemObjectAccess *pAccess,
IWbemObjectAccess ** ppRefreshable,
ULONG_PTR *plId)
{
HRESULT hr = WBEM_E_FAILED;
if( m_fInit )
{
//======================================================
// Get the definition of the class we are working with
//======================================================
hr = m_pClass->SetAccess(pAccess);
if( SUCCEEDED(hr))
{
CAutoBlock(m_pHiPerfMap->GetCriticalSection());
HANDLE WMIHandle = 0;
CLSID Guid;
hr = m_pWDM->GetWMIHandle(WMIHandle);
if( SUCCEEDED(hr))
{
// =======================================================
// We have the WMI Handle, now add it to the hi perf map
// for this refresher
// =======================================================
if( m_pClass->GetANewAccessInstance() )
{
//====================================================
// Set the flag so we don't get a new instance for
// this anymore
//====================================================
m_pClass->GetNewInstance(FALSE);
hr = m_pClass->SetKeyFromAccessPointer();
if( SUCCEEDED(hr))
{
*ppRefreshable = m_pClass->GetAccessInstancePtr();
*plId = (ULONG_PTR)(*ppRefreshable);
hr = m_pHiPerfMap->Add(WMIHandle, *plId, m_pClass, NULL );
}
}
}
}
}
return hr;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CWMIHiPerfShell::AddEnumeratorObjectToRefresher(IWbemHiPerfEnum* pHiPerfEnum, ULONG_PTR *plId)
{
HRESULT hr = WBEM_E_FAILED;
if( m_fInit )
{
//===============================================================
// There is only one handle for this class, so see if we can
// get it
//===============================================================
HANDLE WMIHandle = 0;
CLSID Guid;
CAutoBlock(m_pHiPerfMap->GetCriticalSection());
hr = m_pWDM->GetWMIHandle(WMIHandle);
if( SUCCEEDED(hr))
{
*plId = (ULONG_PTR)pHiPerfEnum;
hr = m_pHiPerfMap->Add(WMIHandle, *plId, m_pClass,pHiPerfEnum);
}
}
return hr;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CWMIHiPerfShell::RemoveObjectFromHandleMap(ULONG_PTR lHiPerfId)
{
HRESULT hr = WBEM_E_FAILED;
if( m_fInit )
{
HANDLE hHandle = 0;
CHandleMap *pHandleMap = m_pClass->WMI()->HandleMap();
CAutoBlock(m_pHiPerfMap->GetCriticalSection());
//==============================================================
// First, delete the object from the map
//==============================================================
hr = m_pHiPerfMap->Delete( hHandle, lHiPerfId );
if( SUCCEEDED(hr))
{
//==========================================================
// If we got a handle back, then we know it is an access
// instance and we need to release the WMI Handle
//==========================================================
if( hHandle ){
hr = pHandleMap->ReleaseHandle(hHandle);
}
}
}
return hr;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// PRIVATE
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CWMIHiPerfShell::QueryAllInstances(HANDLE WMIHandle,IWbemHiPerfEnum* pHiPerfEnum)
{
HRESULT hr = WBEM_E_FAILED;
if( m_fInit )
{
long lCount = 0;
HandleList ids;
//==================================================
// Collect all of the WDM Handles to query all at
// once.
//==================================================
// 170635
if(SUCCEEDED(hr = ids.Add(WMIHandle)))
{
// =====================================================
// Query for all of the objects for this class
// Add all the objects at once into the enumerator
// Handles are guaranteed to be open at this time
//======================================================
HANDLE * pHandles = (HANDLE*)*(ids.List());
hr = m_pWDM->HiPerfQueryAllData(pHandles,ids.Size());
//======================================================
// If we got the data then process it
//======================================================
if( SUCCEEDED(hr))
{
//======================================================
// Get the list of ptrs
//======================================================
AccessList AccessList;
while( TRUE )
{
hr = m_pWDM->ReadWMIDataBlockAndPutIntoWbemInstance();
if( hr == S_OK )
{
IWbemObjectAccess * p = m_pClass->GetAccessInstancePtr();
if(SUCCEEDED(hr = AccessList.Add(p)))
{
lCount++;
}
}
if( hr != S_OK )
{
break;
}
if( !m_pWDM->MoreToProcess() )
{
break;
}
if( !pHiPerfEnum )
{
m_pClass->SendInstanceBack();
}
}
//======================================================
// Now, once we have collected them, send them off
// if asked to
//======================================================
if( pHiPerfEnum )
{
if( lCount > 0 )
{
long * pLong = new long[lCount];
if(pLong)
{
for(long l = 0; l < lCount; l++)
{
pLong[l] = l;
}
IWbemObjectAccess ** pAccess = (IWbemObjectAccess**)AccessList.List();
// Remove all the objects in the enumerator before adding the object
pHiPerfEnum->RemoveAll(0);
hr = pHiPerfEnum->AddObjects( 0L, AccessList.Size(), pLong, pAccess);
SAFE_DELETE_ARRAY(pLong);
}
else
{
hr = E_OUTOFMEMORY;
}
}
}
}
}
}
return hr;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CWMIHiPerfShell::QuerySingleInstance(HANDLE WMIHandle)
{
HRESULT hr = WBEM_E_FAILED;
if( m_fInit )
{
CVARIANT varName;
hr = m_pClass->GetKeyFromAccessPointer((CVARIANT *)&varName);
if(SUCCEEDED(hr))
{
WCHAR * p = varName.GetStr();
if(p)
{
hr = m_pWDM->HiPerfQuerySingleInstance(&WMIHandle, &p, 1,1);
//======================================================
// If we got the data, process it
//======================================================
if( SUCCEEDED(hr))
{
hr = m_pWDM->ReadWMIDataBlockAndPutIntoWbemInstance();
// if( hr == S_OK )
// {
// m_pClass->SendInstanceBack();
// }
}
}
else
{
hr = WBEM_E_FAILED;
}
}
}
return hr;
}