|
|
//***************************************************************************
//
// Copyright � Microsoft Corporation. All rights reserved.
//
// Provider.CPP
//
// Purpose: Implementation of Provider class
//
//***************************************************************************
#include "precomp.h"
#include <assertbreak.h>
#include <objpath.h>
#include <cominit.h>
#include <brodcast.h>
#include <createmutexasprocess.h>
#include <stopwatch.h>
#include <SmartPtr.h>
#include <frqueryex.h>
#include "FWStrings.h"
#include "MultiPlat.h"
#include <helper.h>
// Must instantiate static members
CHString Provider::s_strComputerName;
////////////////////////////////////////////////////////////////////////
//
// Function: Provider ctor
//
//
//
// Inputs: name of this provider
//
// Outputs:
//
// Return:
//
// Comments: suggest that derived classes implement their provider's ctor thusly:
//
// MyProvider::MyProvider(const CHString& setName) :
// Provider(setName)
//
// that way, a *further* derived class can specify its own name
//
//
////////////////////////////////////////////////////////////////////////
Provider::Provider( LPCWSTR a_setName, LPCWSTR a_pszNameSpace /*=NULL*/ ) : CThreadBase(), m_pIMosProvider( NULL ), m_piClassObject( NULL ), m_name( a_setName ), m_strNameSpace( a_pszNameSpace ) { // Initialize the computer name, then register with the framework.
InitComputerName();
CWbemProviderGlue::FrameworkLogin( a_setName, this, a_pszNameSpace );
}
////////////////////////////////////////////////////////////////////////
//
// Function: Provider dtor
//
//
//
// Inputs: none.
//
// Outputs:
//
// Return:
//
// Comments: cleans up our pointer to the IMosProvider
//
////////////////////////////////////////////////////////////////////////
Provider::~Provider( void ) { // get out of the framework's hair
CWbemProviderGlue::FrameworkLogoff( (LPCWSTR)m_name, (LPCWSTR)m_strNameSpace ); // we can't release the interfaces here because CIMOM has a habit
// of shutting down when it still has interface pointers open.
/********************
// Release the pointer returned to us by GetNamespaceConnection(), which
// will return us an AddRefed pointer.
if ( NULL != m_pIMosProvider ) { m_pIMosProvider->Release(); }
// The class object is returned to us by IMOSProvider::GetObject, so
// we should try to release it here when we're done with it.
if ( NULL != m_piClassObject ) { m_piClassObject->Release(); } ******************************/ }
////////////////////////////////////////////////////////////////////////
//
// Function: Provider::InitComputerName
//
// Initializes our static computer name variable.
//
// Inputs: None.
//
// Outputs: None.
//
// Return: None.
//
// Comments: Because the idea behind creating providers is that
// a single static instance is instantiated, this function
// will most likely be called as part of DLL loading, we'll
// introduce some thread safety here using a named mutex
// but won't worry too much about it other than that.
//
////////////////////////////////////////////////////////////////////////
void Provider::InitComputerName( void ) { // For performance, check if the value is empty. Only if it
// is, should we then bother with going through a thread-safe
// static initialization. Because we are using a named mutex,
// multiple threads will get the same kernel object, and will
// be stop-gapped by the OS as they each acquire the mutex
// in turn.
if ( s_strComputerName.IsEmpty() ) { CreateMutexAsProcess createMutexAsProcess(WBEMPROVIDERSTATICMUTEX);
// Double check in case there was a conflict and somebody else
// got here first.
if ( s_strComputerName.IsEmpty() ) { DWORD dwBuffSize = MAX_COMPUTERNAME_LENGTH + 1;
// Make sure the string buffer will be big enough to handle the
// value.
LPWSTR pszBuffer = s_strComputerName.GetBuffer( dwBuffSize );
if ( NULL != pszBuffer ) { // Now grab the computer name and release the buffer, forcing
// it to reallocate itself to the new length.
if (!FRGetComputerName( pszBuffer, &dwBuffSize )) { StringCchCopyW( pszBuffer, MAX_COMPUTERNAME_LENGTH + 1, L"DEFAULT" ); } s_strComputerName.ReleaseBuffer(); } // IF NULL != pszBuffer
} // IF strComputerName.IsEmpty()
} // IF strComputerName.IsEmpty()
}
////////////////////////////////////////////////////////////////////////
//
// Function: Flush
//
// flushes out all unnecessary memory usage
// inlcuding the (unimplemented) cache
// and the class object we clone from
//
// Inputs: nope
//
// Outputs:
//
// Return: the eternal void
//
// Comments:
//
////////////////////////////////////////////////////////////////////////
void Provider::Flush() { // TODO: implement cache flush
BeginWrite();
if (m_piClassObject) { m_piClassObject->Release(); m_piClassObject = NULL; }
if ( NULL != m_pIMosProvider ) { m_pIMosProvider->Release(); m_pIMosProvider = NULL; } EndWrite(); }
////////////////////////////////////////////////////////////////////////
//
// Function: ValidateIMOSPointer
//
// Verifies in a threadsafe manner, that our IWBEMServices pointer
// is okay.
//
// Inputs: None.
//
// Outputs:
//
// Return: TRUE/FALSE success/failure
//
// Comments: Requires that our NameSpace be valid.
//
////////////////////////////////////////////////////////////////////////
BOOL Provider::ValidateIMOSPointer( ) { return TRUE; }
////////////////////////////////////////////////////////////////////////
//
// Function: CreateNewInstance
//
//
//
// Inputs: MethodContext* - context that this instance belongs to
//
// Outputs:
//
// Return: CInstance*
//
// Comments: caller is responsible for memory
//
////////////////////////////////////////////////////////////////////////
CInstance* Provider::CreateNewInstance( MethodContext* pMethodContext ) { HRESULT hr = WBEM_S_NO_ERROR; CInstance* pNewInstance = NULL; IWbemClassObjectPtr pClassObject (GetClassObjectInterface(pMethodContext), false);
IWbemClassObjectPtr piClone; hr = pClassObject->SpawnInstance(0, &piClone); if (SUCCEEDED(hr)) { // The Instance is responsible for its own AddRef/Releasing
pNewInstance = new CInstance(piClone, pMethodContext);
if (pNewInstance == NULL) { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; }
} else { throw CFramework_Exception(L"SpawnInstance failed", hr); }
return pNewInstance; }
////////////////////////////////////////////////////////////////////////
//
// Function: Commit
//
// sends instance to CIMOM
//
// Inputs: CInstance* pInstance - the instance to pass off to cimom,
// bool bCache - should we cache this puppy? (unimplemented)
//
// Outputs:
//
// Return:
//
// Comments: do not reference pointer once committed, it may not exist any more!
//
////////////////////////////////////////////////////////////////////////
HRESULT Provider::Commit(CInstance* pInstance, bool bCache /* = false*/) { HRESULT hRes = WBEM_S_NO_ERROR;
// allow derived classes to fill out extra info.
// GetExtendedProperties(pInstance);
hRes = pInstance->Commit();
// TODO: Implement cache
// if !bCache...
// We're done with pInstance, so...
pInstance->Release();
return hRes; }
////////////////////////////////////////////////////////////////////////
//
// Function: ExecuteQuery
//
//
//
// Inputs: IWbemContext __RPC_FAR * pCtx,
//
// Outputs:
//
// Return: HRESULT
//
// Comments: Calls a provider's ExecQuery function, or returns
//
////////////////////////////////////////////////////////////////////////
HRESULT Provider::ExecuteQuery( MethodContext* pContext, CFrameworkQuery& pQuery, long lFlags /*= 0L*/ ) { HRESULT hr = ValidateQueryFlags(lFlags); // Make sure we've got Managed Object Services avaliable, as we will need
// it to get WBEMClassObjects for constructing Instances.
if ( SUCCEEDED(hr) && ValidateIMOSPointer( ) ) { // Check to see if this is an extended query
CFrameworkQueryEx *pQuery2 = static_cast <CFrameworkQueryEx*>(&pQuery); if (pQuery2->IsExtended()) { // It is an extended query. Does the provider support them?
if (FAILED(ValidateQueryFlags(WBEM_FLAG_FORWARD_ONLY))) { // We have an extended query, but the provider doesn't support it
hr = WBEM_E_INVALID_QUERY; } }
if (SUCCEEDED(hr)) { // Tell cimom he's got work to do on the instances when we send
// them back.
pContext->QueryPostProcess(); // If the client hasn't overridden the class, we get back
// WBEM_E_PROVIDER_NOT_CAPABLE. In that case, call the enumerate, and let
// CIMOM do the work
PROVIDER_INSTRUMENTATION_START(pContext, StopWatch::ProviderTimer); hr = ExecQuery(pContext, pQuery, lFlags); PROVIDER_INSTRUMENTATION_START(pContext, StopWatch::FrameworkTimer); if (hr == WBEM_E_PROVIDER_NOT_CAPABLE) { // Get the instances
PROVIDER_INSTRUMENTATION_START(pContext, StopWatch::ProviderTimer); hr = CreateInstanceEnum(pContext, lFlags); PROVIDER_INSTRUMENTATION_START(pContext, StopWatch::FrameworkTimer); } } else { hr = WBEM_E_INVALID_QUERY; } } return hr; }
////////////////////////////////////////////////////////////////////////
//
// Function: CreateInstanceEnum
//
//
//
// Inputs: IWbemContext __RPC_FAR * pCtx,
// IWbemObjectSink __RPC_FAR * pResponseHandler
// Outputs:
//
// Return:
//
// Comments: enumerate all instances of this class
//
////////////////////////////////////////////////////////////////////////
HRESULT Provider::CreateInstanceEnum( MethodContext* pContext, long lFlags /*= 0L*/ ) { HRESULT sc = ValidateEnumerationFlags(lFlags);
// Make sure we've got Managed Object Services avaliable, as we will need
// it to get WBEMClassObjects for constructing Instances.
if ( SUCCEEDED(sc) && ValidateIMOSPointer( ) ) { PROVIDER_INSTRUMENTATION_START(pContext, StopWatch::ProviderTimer); sc = EnumerateInstances( pContext, lFlags ); PROVIDER_INSTRUMENTATION_START(pContext, StopWatch::FrameworkTimer); }
return sc; }
////////////////////////////////////////////////////////////////////////
//
// Function: PutInstance
//
// CIMOM wants us to put this instance.
//
// Inputs:
//
// Outputs:
//
// Return:
//
// Comments:
//
////////////////////////////////////////////////////////////////////////
HRESULT Provider::PutInstance(const CInstance& newInstance, long lFlags /*= 0L*/) { return WBEM_E_PROVIDER_NOT_CAPABLE; }
////////////////////////////////////////////////////////////////////////
//
// Function: PutInstance
//
// CIMOM wants us to put this instance.
//
// Inputs:
//
// Outputs:
//
// Return:
//
// Comments:
//
////////////////////////////////////////////////////////////////////////
HRESULT Provider::PutInstance( IWbemClassObject __RPC_FAR *pInst, long lFlags, MethodContext* pContext ) { HRESULT scode = ValidatePutInstanceFlags(lFlags);
// No need to AddRef()/Release() pInst here, since we're just
// passing it into the CInstance object, which should take
// care of that for us internally.
if (SUCCEEDED(scode)) { CInstancePtr pInstance (new CInstance( pInst, pContext ), false);
if ( NULL != pInstance ) { scode = PutInstance(*pInstance, lFlags); } else { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; } }
return scode; }
////////////////////////////////////////////////////////////////////////
//
// Function: DeleteInstance
//
// CIMOM wants us to delete this instance.
//
// Inputs:
//
// Outputs:
//
// Return:
//
// Comments:
//
////////////////////////////////////////////////////////////////////////
HRESULT Provider::DeleteInstance(const CInstance& newInstance, long lFlags /*= 0L*/) { return WBEM_E_PROVIDER_NOT_CAPABLE; }
////////////////////////////////////////////////////////////////////////
//
// Function: DeleteInstance
//
// CIMOM wants us to put this instance.
//
// Inputs:
//
// Outputs:
//
// Return:
//
// Comments:
//
////////////////////////////////////////////////////////////////////////
HRESULT Provider::DeleteInstance( ParsedObjectPath* pParsedObjectPath, long lFlags, MethodContext* pContext ) { HRESULT sc = ValidateDeletionFlags(lFlags);
// Make sure we've got Managed Object Services avaliable, as we will
// need it in order to create a brand new instance.
if ( SUCCEEDED(sc) && ValidateIMOSPointer( ) ) { CInstancePtr pInstance (CreateNewInstance( pContext ), false);
// Load up the instance keys
if ( SetKeyFromParsedObjectPath( pInstance, pParsedObjectPath ) ) { sc = DeleteInstance(*pInstance, lFlags); } else { sc = WBEM_E_INVALID_OBJECT_PATH; }
}
return sc; }
////////////////////////////////////////////////////////////////////////
//
// Function: ExecMethod
//
// CIMOM wants us to execute this method on this instance
//
// Inputs:
//
// Outputs:
//
// Return:
//
// Comments:
//
////////////////////////////////////////////////////////////////////////
HRESULT Provider::ExecMethod(const CInstance& pInstance, BSTR bstrMethodName, CInstance *pInParams, CInstance *pOutParams, long lFlags /*= 0L*/) { return WBEM_E_PROVIDER_NOT_CAPABLE; }
////////////////////////////////////////////////////////////////////////
//
// Function: ExecMethod
//
// CIMOM wants us to Execute this method on this instance
//
// Inputs:
//
// Outputs:
//
// Return:
//
// Comments:
//
////////////////////////////////////////////////////////////////////////
HRESULT Provider::ExecMethod( ParsedObjectPath *pParsedObjectPath, BSTR bstrMethodName, long lFlags, CInstance *pInParams, CInstance *pOutParams, MethodContext *pContext ) { HRESULT sc = ValidateMethodFlags(lFlags);
// Make sure we've got Managed Object Services avaliable, as we will
// need it in order to create a brand new instance.
if ( SUCCEEDED(sc) && ValidateIMOSPointer( ) ) {
CInstancePtr pInstance(CreateNewInstance( pContext ), false);
if ( SetKeyFromParsedObjectPath( pInstance, pParsedObjectPath ) ) { PROVIDER_INSTRUMENTATION_START(pContext, StopWatch::ProviderTimer); sc = ExecMethod(*pInstance, bstrMethodName, pInParams, pOutParams, lFlags); PROVIDER_INSTRUMENTATION_START(pContext, StopWatch::FrameworkTimer); } else { sc = WBEM_E_INVALID_OBJECT_PATH; }
}
return sc; }
////////////////////////////////////////////////////////////////////////
//
// Function: GetObject
//
// called by the framework in response to a GetObject from CIMOM
//
// Inputs: ParsedObjectPath* pParsedObjectPath - All the news
// thats fit to print.
// IWbemContext __RPC_FAR* pCtx
// IWbemObjectSink __RPC_FAR*pResponseHandler
//
//
// Outputs:
//
// Return:
//
// Comments:
//
////////////////////////////////////////////////////////////////////////
HRESULT Provider::GetObject( ParsedObjectPath *pParsedObjectPath, MethodContext *pContext, long lFlags /*= 0L*/ ) { HRESULT hr = ValidateGetObjFlags(lFlags);
// Make sure we've got Managed Object Services avaliable, as we will
// need it in order to create a brand new instance.
if ( SUCCEEDED(hr) && ValidateIMOSPointer( ) ) { CInstancePtr pInstance (CreateNewInstance( pContext ), false);
// Load up the instance keys
if ( SetKeyFromParsedObjectPath( pInstance, pParsedObjectPath ) ) { // Look for per-property gets
IWbemContextPtr pWbemContext (pContext->GetIWBEMContext(), false);
CFrameworkQueryEx CQuery; hr = CQuery.Init(pParsedObjectPath, pWbemContext, GetProviderName(), m_strNameSpace);
// Note that 'SUCCEEDED' DOESN'T mean that we have per-property gets. It
// just means that the query object was successfully initialized.
if (SUCCEEDED(hr)) { // Fill in key properties on query object
IWbemClassObjectPtr pWbemClassObject(pInstance->GetClassObjectInterface(), false); CQuery.Init2(pWbemClassObject);
PROVIDER_INSTRUMENTATION_START(pContext, StopWatch::ProviderTimer); hr = GetObject(pInstance, lFlags, CQuery); PROVIDER_INSTRUMENTATION_START(pContext, StopWatch::FrameworkTimer); } } else { hr = WBEM_E_INVALID_OBJECT_PATH; }
if (SUCCEEDED(hr)) { // Account for the possibility that we have a SUCCESS code back from GetObject.
HRESULT hRes = pInstance->Commit(); hr = __max((ULONG)hRes, (ULONG)hr); } }
return hr; }
////////////////////////////////////////////////////////////////////////
//
// Function: Provider::GetInstancePath
//
// Attempts to build an instance path for the supplied CInstance pointer.
//
// Inputs: const CInstance* pInstance - Instance to build path for.
//
// Outputs: CHString& strPath - Path from instance.
//
// Return: BOOL Success/Failure.
//
// Comments: This function was created to help support the internal
// short circuit we performed for obtaining local WBEM
// Provider objects. In this instance, we will use our
// computer system name, namespace and instance relative
// path to munge together a full WBEM Object Path. This
// is because only CIMOM objects will have this value set
// and when we perform our short circuit, we cut CIMOM
// out of the loop, so our instances don't have full
// object paths. This mostly helps out our association
// logic, although a weakness of this solution is that
// if the path that gets stored by CIMOM changes, we
// will then need to change this function.
//
////////////////////////////////////////////////////////////////////////
bool Provider::GetLocalInstancePath( const CInstance *pInstance, CHString& strPath ) { bool fReturn = false; CHString strRelativePath;
if (pInstance && pInstance->GetCHString( L"__RELPATH", strRelativePath ) ) { // We may want to use the OBJPath classes to piece this
// together for us at a later time.
strPath = MakeLocalPath(strRelativePath);
fReturn = true; }
return fReturn;
}
////////////////////////////////////////////////////////////////////////
//
// Function: Provider::MakeLocalPath
//
// Builds a full instance path from a relative path
//
// Inputs: const CHString &strRelPath - Relative path
//
// Outputs:
//
// Return: CHString& strPath - Path
//
// Comments: Consider using GetLocalInstance path before using
// this function.
//
////////////////////////////////////////////////////////////////////////
CHString Provider::MakeLocalPath( const CHString &strRelPath ) {
ASSERT_BREAK( (strRelPath.Find(L':') == -1) || ((strRelPath.Find(L'=') != -1) && (strRelPath.Find(L':') >= strRelPath.Find(L'=')) )); CHString sBase; sBase.Format(L"\\\\%s\\%s:%s", (LPCWSTR)s_strComputerName, m_strNameSpace.IsEmpty() ? DEFAULT_NAMESPACE: (LPCWSTR) m_strNameSpace, (LPCWSTR)strRelPath);
return sBase; }
////////////////////////////////////////////////////////////////////////
//
// Function: SetKeyFromParsedObjectPath
//
// called by the DeleteInstance and GetObject in order to load a
// CInstance* with the key values in an object path.
//
// Inputs: CInstance* pInstance - Instance to store
// key values in.
// ParsedObjectPath* pParsedObjectPath - All the news
// thats fit to print.
//
//
// Outputs:
//
// Return: BOOL Success/Failure
//
// Comments:
//
////////////////////////////////////////////////////////////////////////
BOOL Provider::SetKeyFromParsedObjectPath( CInstance *pInstance, ParsedObjectPath *pParsedPath ) { BOOL fReturn = TRUE; SAFEARRAY *pNames = NULL; long lLBound, lUBound; // populate instance - This exact same routine is in wbemglue.cpp. Changes here should be
// reflected there (or someone should move these two somewhere else. instance.cpp?).
for (DWORD i = 0; fReturn && i < (pParsedPath->m_dwNumKeys); i++) { if (pParsedPath->m_paKeys[i]) { // If a name was specified in the form class.keyname=value
if (pParsedPath->m_paKeys[i]->m_pName != NULL) { fReturn = pInstance->SetVariant(pParsedPath->m_paKeys[i]->m_pName, pParsedPath->m_paKeys[i]->m_vValue); } else { // There is a special case that you can say class=value
fReturn = FALSE; // only one key allowed in the format. Check the names on the path
if (pParsedPath->m_dwNumKeys == 1) { // Get the names from the object
if (m_piClassObject->GetNames(NULL, WBEM_FLAG_KEYS_ONLY, NULL, &pNames) == WBEM_S_NO_ERROR) { OnDelete<SAFEARRAY *,HRESULT(*)(SAFEARRAY *),SafeArrayDestroy> smartpNames(pNames);
BSTR t_bstrName = NULL ; SafeArrayGetLBound(pNames, 1, &lLBound); SafeArrayGetUBound(pNames, 1, &lUBound); // Only one key?
if ((lUBound - lLBound) == 0) { // Get the name of the key field and set it
if (SUCCEEDED(SafeArrayGetElement( pNames, &lUBound, &t_bstrName ))) { OnDeleteIf<BSTR,VOID(*)(BSTR),SysFreeString> smartt_bstrName(t_bstrName); fReturn = pInstance->SetVariant( t_bstrName, pParsedPath->m_paKeys[i]->m_vValue); } } } } ASSERT_BREAK(fReturn); // somebody lied about the number of keys or the datatype was wrong
} } else { ASSERT_BREAK(0); // somebody lied about the number of keys!
fReturn = FALSE; } } return fReturn; }
// sets the CreationClassName to the name of this provider
bool Provider::SetCreationClassName(CInstance* pInstance) { if (pInstance) { return pInstance->SetCHString(IDS_CreationClassName, m_name); } else { return false; } }
// flag validation - returns WBEM_E_UNSUPPORTED parameter if
// lFlags contains any flags not found in lAcceptableFlags
HRESULT Provider::ValidateFlags(long lFlags, FlagDefs lAcceptableFlags) { HRESULT hr = WBEM_S_NO_ERROR; // invert the acceptable flags, which then are the UNacceptable flags
if (lFlags & ~((long)lAcceptableFlags)) hr = WBEM_E_UNSUPPORTED_PARAMETER; else hr = WBEM_S_NO_ERROR;
return hr; } // base level validation routines
// you can override these in order to support a flag
// that is unknown to the base class
HRESULT Provider::ValidateEnumerationFlags(long lFlags) { return ValidateFlags(lFlags, EnumerationFlags); } HRESULT Provider::ValidateGetObjFlags(long lFlags) { return ValidateFlags(lFlags, GetObjFlags); } HRESULT Provider::ValidateMethodFlags(long lFlags) { return ValidateFlags(lFlags, MethodFlags); } HRESULT Provider::ValidateQueryFlags(long lFlags) { return ValidateFlags(lFlags, QueryFlags); } HRESULT Provider::ValidateDeletionFlags(long lFlags) { return ValidateFlags(lFlags, DeletionFlags); } HRESULT Provider::ValidatePutInstanceFlags(long lFlags) { return ValidateFlags(lFlags, PutInstanceFlags); }
IWbemClassObject* Provider::GetClassObjectInterface(MethodContext *pMethodContext) { IWbemClassObject *pObject = NULL;
if (ValidateIMOSPointer()) { BeginWrite(); FrameDynOnDeleteObjVoid < Provider, void ( CThreadBase:: * ) ( void ), &CThreadBase::EndWrite > SmartEndWrite ( const_cast < Provider* > ( this ) ) ;
if ( NULL == m_piClassObject ) { //calling back into winmgmt - no critsec!
SmartEndWrite.Exec ( ) ;
IWbemContextPtr pWbemContext;
if ( NULL != pMethodContext ) { pWbemContext.Attach(pMethodContext->GetIWBEMContext()); }
IWbemServicesPtr pServices(CWbemProviderGlue::GetNamespaceConnection( m_strNameSpace, pMethodContext ), false); if ( NULL != static_cast < IWbemServices* > ( pServices ) ) { HRESULT hr = pServices->GetObject( bstr_t( m_name ), 0L, pWbemContext, &pObject, NULL);
BeginWrite(); SmartEndWrite.ReSetExecFlag () ;
if (SUCCEEDED(hr)) { if (m_piClassObject == NULL) { m_piClassObject = pObject; pObject->AddRef(); } else { if (pObject) { pObject->Release(); pObject = NULL; }
pObject = m_piClassObject; pObject->AddRef(); } } else { if (pObject) { pObject->Release(); pObject = NULL; }
// belt & suspenders check. Won't hurt.
m_piClassObject = NULL;
throw CFramework_Exception(L"SpawnInstance failed", hr); } } else { throw CFramework_Exception(L"GetNamespaceConnection failed"); } } else { pObject = m_piClassObject; pObject->AddRef(); } }
return pObject; }
// If a provider wants to process queries, they should override this
HRESULT Provider::ExecQuery(MethodContext *pMethodContext, CFrameworkQuery& pQuery, long lFlags /*= 0L*/) { return WBEM_E_PROVIDER_NOT_CAPABLE; }
// find and create all instances of your class
HRESULT Provider::EnumerateInstances(MethodContext* pMethodContext, long lFlags /*= 0L*/) { return WBEM_E_PROVIDER_NOT_CAPABLE; }
// you will be given an object with the key properties filled in.
// you need to fill in all of the rest of the properties
HRESULT Provider::GetObject(CInstance* pInstance, long lFlags /*= 0L*/) { return WBEM_E_PROVIDER_NOT_CAPABLE; }
// You will be given an object with the key properties filled in.
// You can either fill in all the properties, or check the Query object
// to see what properties are required.
HRESULT Provider::GetObject(CInstance *pInstance, long lFlags, CFrameworkQuery &Query) { // If we are here, the provider didn't override this method. Fall back to the older
// call.
return GetObject(pInstance, lFlags); }
|