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

368 lines
9.9 KiB
C++

//***************************************************************************
//
// CLASSPRO.CPP
//
// Module: WINMGMT class provider sample code
//
// Purpose: Defines the CClassPro class. An object of this class is
// created by the class factory for each connection.
//
// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
//
//***************************************************************************
#include <objbase.h>
#include "sample.h"
#include <process.h>
InstDef MyDefs[] = {{L"a", 1}, {L"b", 2}, {L"c", 3}};
long glNumInst = sizeof(MyDefs)/sizeof(InstDef);
#define SAMPLE_CLASS_NAME L"ClassProvSamp"
//***************************************************************************
//
// CClassPro::CClassPro
// CClassPro::~CClassPro
//
//***************************************************************************
CClassPro::CClassPro(BSTR ObjectPath, BSTR User, BSTR Password, IWbemContext * pCtx)
{
m_pNamespace = NULL;
m_cRef=0;
InterlockedIncrement(&g_cObj);
return;
}
CClassPro::~CClassPro(void)
{
if(m_pNamespace)
m_pNamespace->Release();
InterlockedDecrement(&g_cObj);
return;
}
//***************************************************************************
//
// CClassPro::QueryInterface
// CClassPro::AddRef
// CClassPro::Release
//
// Purpose: IUnknown members for CClassPro object.
//***************************************************************************
STDMETHODIMP CClassPro::QueryInterface(REFIID riid, PPVOID ppv)
{
*ppv=NULL;
// Since we have dual inheritance, it is necessary to cast the return type
if(riid== IID_IWbemServices)
*ppv=(IWbemServices*)this;
if(IID_IUnknown==riid || riid== IID_IWbemProviderInit)
*ppv=(IWbemProviderInit*)this;
if (NULL!=*ppv) {
AddRef();
return NOERROR;
}
else
return E_NOINTERFACE;
}
STDMETHODIMP_(ULONG) CClassPro::AddRef(void)
{
return ++m_cRef;
}
STDMETHODIMP_(ULONG) CClassPro::Release(void)
{
ULONG nNewCount = InterlockedDecrement((long *)&m_cRef);
if (0L == nNewCount)
delete this;
return nNewCount;
}
/***********************************************************************
* *
* CClassPro::Initialize *
* *
* Purpose: This is the implementation of IWbemProviderInit. The method *
* is need to initialize with CIMOM. *
* *
***********************************************************************/
STDMETHODIMP CClassPro::Initialize(LPWSTR pszUser, LONG lFlags,
LPWSTR pszNamespace, LPWSTR pszLocale,
IWbemServices *pNamespace,
IWbemContext *pCtx,
IWbemProviderInitSink *pInitSink)
{
if(pNamespace)
pNamespace->AddRef();
m_pNamespace = pNamespace;
//Let CIMOM know you are initialized
//==================================
pInitSink->SetStatus(WBEM_S_INITIALIZED,0);
return WBEM_S_NO_ERROR;
}
//***************************************************************************
//
// CClassPro::CreateClassEnumAsync
//
// Purpose: Asynchronously enumerates the classes this provider supports.
// Note that this sample only supports one.
//
//***************************************************************************
SCODE CClassPro::CreateClassEnumAsync(const BSTR Superclass, long lFlags,
IWbemContext *pCtx, IWbemObjectSink *pHandler)
{
if(pHandler == NULL || m_pNamespace == NULL)
return WBEM_E_INVALID_PARAMETER;
SCODE sc = S_OK;
if(Superclass == NULL || wcslen(Superclass) == 0)
{
IWbemClassObject * pNewClass = NULL;
sc = CreateClass(m_pNamespace, &pNewClass, SAMPLE_CLASS_NAME, pCtx);
if(sc == S_OK)
{
// Send the object to the caller
pHandler->Indicate(1,&pNewClass);
pNewClass->Release();
}
}
// Set status
pHandler->SetStatus(0,sc,NULL, NULL);
return S_OK;
}
//***************************************************************************
//
// CClassPro::CreateInstanceEnumAsync
//
// Purpose: Asynchronously enumerates the instances.
//
//***************************************************************************
SCODE CClassPro::CreateInstanceEnumAsync( const BSTR RefStr, long lFlags, IWbemContext *pCtx,
IWbemObjectSink FAR* pHandler)
{
SCODE sc;
int iCnt;
IWbemClassObject FAR* pNewInst;
// Do a check of arguments and make sure we have pointer to Namespace
if(pHandler == NULL || m_pNamespace == NULL)
return WBEM_E_INVALID_PARAMETER;
for(iCnt=0; iCnt < glNumInst; iCnt++)
{
sc = CreateInst(m_pNamespace,MyDefs[iCnt].pwcKey,
MyDefs[iCnt].lValue, &pNewInst, RefStr, pCtx);
if(sc != S_OK)
break;
// Send the object to the caller
pHandler->Indicate(1,&pNewInst);
pNewInst->Release();
}
// Set status
pHandler->SetStatus(0,sc,NULL, NULL);
return sc;
}
//***************************************************************************
//
// CClassPro::GetObjectByPathAsync
//
// Purpose: Returns either an instance or a class.
//
//***************************************************************************
SCODE CClassPro::GetObjectAsync(const BSTR ObjectPath, long lFlags,IWbemContext *pCtx,
IWbemObjectSink FAR* pHandler)
{
SCODE sc;
IWbemClassObject FAR* pObj;
BOOL bOK = FALSE;
// Do a check of arguments and make sure we have pointer to Namespace
if(ObjectPath == NULL || pHandler == NULL || m_pNamespace == NULL)
return WBEM_E_INVALID_PARAMETER;
// If we are being asked for our class, get that
size_t i1 = wcslen(ObjectPath);
size_t i2 = wcslen(SAMPLE_CLASS_NAME);
if(i1 >= i2 && !_wcsicmp(&ObjectPath[i1-i2], SAMPLE_CLASS_NAME) )
{
IWbemClassObject * pNewClass = NULL;
sc = CreateClass(m_pNamespace, &pNewClass, SAMPLE_CLASS_NAME, pCtx);
if(sc == S_OK)
{
// Send the object to the caller
pHandler->Indicate(1,&pNewClass);
pNewClass->Release();
}
}
else if(S_OK ==GetByPath(ObjectPath,&pObj, pCtx))
{
pHandler->Indicate(1,&pObj);
pObj->Release();
bOK = TRUE;
sc = S_OK;
}
else
sc = WBEM_E_NOT_FOUND;
// Set Status
pHandler->SetStatus(0,sc, NULL, NULL);
return sc;
}
//***************************************************************************
//
// CClassPro::GetByPath
//
// Purpose: Creates an instance given a particular Path value.
//
//***************************************************************************
SCODE CClassPro::GetByPath(BSTR ObjectPath, IWbemClassObject FAR* FAR* ppObj, IWbemContext *pCtx)
{
SCODE sc = S_OK;
int iCnt;
// do a simple path parse. The path will look something like
// ClassProvSamp.MyKey="a"
// Create a test string with just the part between quotes.
WCHAR wcTest[MAX_PATH+1];
wcscpy(wcTest,ObjectPath);
WCHAR * pwcTest, * pwcCompare = NULL;
int iNumQuotes = 0;
for(pwcTest = wcTest; *pwcTest; pwcTest++)
if(*pwcTest == L'\"')
{
iNumQuotes++;
if(iNumQuotes == 1)
{
pwcCompare = pwcTest+1;
}
else if(iNumQuotes == 2)
{
*pwcTest = NULL;
break;
}
}
else if(*pwcTest == L'.')
*pwcTest = NULL; // issolate the class name.
if(iNumQuotes != 2)
return WBEM_E_FAILED;
// check the instance list for a match.
for(iCnt = 0; iCnt < glNumInst; iCnt++)
{
if(!_wcsicmp(MyDefs[iCnt].pwcKey, pwcCompare))
{
sc = CreateInst(m_pNamespace,MyDefs[iCnt].pwcKey,
MyDefs[iCnt].lValue, ppObj, wcTest, pCtx);
return sc;
}
}
return WBEM_E_NOT_FOUND;
}
SCODE CClassPro::PutClassAsync(
/* [in] */ IWbemClassObject __RPC_FAR *pObject,
/* [in] */ long lFlags,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
{
VARIANT var;
VariantInit(&var);
pObject->Get(L"__Class", 0, &var, NULL, NULL);
if(!_wcsicmp(SAMPLE_CLASS_NAME, var.bstrVal))
pResponseHandler->SetStatus(0,S_OK,NULL, NULL);
else
pResponseHandler->SetStatus(0,WBEM_E_NOT_FOUND,NULL, NULL);
return S_OK;
}
SCODE CClassPro::DeleteClassAsync(
/* [in] */ const BSTR Class,
/* [in] */ long lFlags,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
{
if(!_wcsicmp(SAMPLE_CLASS_NAME, Class))
pResponseHandler->SetStatus(0,S_OK,NULL, NULL);
else
pResponseHandler->SetStatus(0,WBEM_E_NOT_FOUND,NULL, NULL);
return S_OK;
}
SCODE CClassPro::PutInstanceAsync(
/* [in] */ IWbemClassObject __RPC_FAR *pInst,
/* [in] */ long lFlags,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
{
pResponseHandler->SetStatus(0,S_OK,NULL, NULL);
return S_OK;
}
SCODE CClassPro::DeleteInstanceAsync(
/* [in] */ const BSTR ObjectPath,
/* [in] */ long lFlags,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
{
pResponseHandler->SetStatus(0,S_OK,NULL, NULL);
return S_OK;
}