windows-nt/Source/XPSP1/NT/ds/security/gina/refreshevent/test/evprov.cpp
2020-09-26 16:20:57 +08:00

314 lines
7.1 KiB
C++

// **************************************************************************
// Copyright (c) 1997-1999 Microsoft Corporation
//
// File: EVPROV.cpp
//
// Description:
// Sample event provider.
//
// History:
//
// **************************************************************************
#include <windows.h>
#include <stdio.h>
#include <wbemidl.h>
#include "oahelp.inl"
#include "evprov.h"
//***************************************************************************
//
//***************************************************************************
// ok
CMyEventProvider::CMyEventProvider()
{
m_pNs = 0;
m_pSink = 0;
m_cRef = 0;
m_pEventClassDef = 0;
m_eStatus = Pending;
m_hThread = 0;
}
//***************************************************************************
//
//***************************************************************************
// ok
CMyEventProvider::~CMyEventProvider()
{
if (m_hThread)
CloseHandle(m_hThread);
if (m_pNs)
m_pNs->Release();
if (m_pSink)
m_pSink->Release();
if (m_pEventClassDef)
m_pEventClassDef->Release();
}
//***************************************************************************
//
//***************************************************************************
// ok
STDMETHODIMP CMyEventProvider::QueryInterface(REFIID riid, LPVOID * ppv)
{
*ppv = 0;
if (IID_IUnknown==riid || IID_IWbemEventProvider==riid)
{
*ppv = (IWbemEventProvider *) this;
AddRef();
return NOERROR;
}
if (IID_IWbemProviderInit==riid)
{
*ppv = (IWbemProviderInit *) this;
AddRef();
return NOERROR;
}
return E_NOINTERFACE;
}
//***************************************************************************
//
//***************************************************************************
// ok
ULONG CMyEventProvider::AddRef()
{
return ++m_cRef;
}
//***************************************************************************
//
//***************************************************************************
// ok
ULONG CMyEventProvider::Release()
{
if (0 != --m_cRef)
return m_cRef;
// If here, we are shutting down.
// ==============================
m_eStatus = PendingStop;
return 0;
}
//***************************************************************************
//
//***************************************************************************
// ok
HRESULT CMyEventProvider::ProvideEvents(
/* [in] */ IWbemObjectSink __RPC_FAR *pSink,
/* [in] */ long lFlags
)
{
// Copy the sink.
// ==============
m_pSink = pSink;
m_pSink->AddRef();
// Create the event thread.
// ========================
DWORD dwTID;
m_hThread = CreateThread(
0,
0,
CMyEventProvider::EventThread,
this,
0,
&dwTID
);
// Wait for provider to be 'ready'.
// ================================
while (m_eStatus != Running)
Sleep(100);
return WBEM_NO_ERROR;
}
//***************************************************************************
//
// This particular provider, being in a DLL operates via its own thread.
//
// In practice, such a provider would probably be implemented within a
// separate EXE.
//
//***************************************************************************
// ok
DWORD WINAPI CMyEventProvider::EventThread(LPVOID pArg)
{
// Make transition to the per-instance method.
// ===========================================
((CMyEventProvider *)pArg)->InstanceThread();
return 0;
}
//***************************************************************************
//
// Events are generated from here
//
//***************************************************************************
// ok
void CMyEventProvider::InstanceThread()
{
int nIteration = 0;
m_eStatus = Running;
while (m_eStatus == Running)
{
Sleep(10000); // Provide an event every ten seconds
// Generate a new event object.
// ============================
IWbemClassObject *pEvt = 0;
HRESULT hRes = m_pEventClassDef->SpawnInstance(0, &pEvt);
if (hRes != 0)
continue; // Failed
// Generate some values to put in the event.
// =========================================
wchar_t Buf[128];
swprintf(Buf, L"Test Event <%d>", nIteration);
CVARIANT vName(Buf);
pEvt->Put(CBSTR(L"Name"), 0, vName, 0);
if (nIteration % 2)
swprintf(Buf, L"Machine");
else
swprintf(Buf, L"User");
CVARIANT vTarget(Buf);
pEvt->Put(CBSTR(L"MachineOrUser"), 0, vTarget, 0);
if (((nIteration >> 1) % 4) == 0)
swprintf(Buf, L"");
else if (((nIteration >> 1) % 4) == 1)
swprintf(Buf, L"Force");
else if (((nIteration >> 1) % 4) == 2)
swprintf(Buf, L"FetchAndStore");
else if (((nIteration >> 1) % 4) == 3)
swprintf(Buf, L"MergeAndApply");
CVARIANT vOption(Buf);
pEvt->Put(CBSTR(L"RefreshOption"), 0, vOption, 0);
// Deliver the event to CIMOM.
// ============================
hRes = m_pSink->Indicate(1, &pEvt);
if (hRes)
{
// If here, delivery failed. Do something to report it.
}
pEvt->Release();
nIteration++;
}
// When we get to here, we are no longer interested in the
// provider and Release() has long since returned.
m_eStatus = Stopped;
delete this;
}
//***************************************************************************
//
//***************************************************************************
// Inherited from IWbemProviderInit
// ================================
HRESULT CMyEventProvider::Initialize(
/* [in] */ LPWSTR pszUser,
/* [in] */ LONG lFlags,
/* [in] */ LPWSTR pszNamespace,
/* [in] */ LPWSTR pszLocale,
/* [in] */ IWbemServices __RPC_FAR *pNamespace,
/* [in] */ IWbemContext __RPC_FAR *pCtx,
/* [in] */ IWbemProviderInitSink __RPC_FAR *pInitSink
)
{
// We don't care about most of the incoming parameters in this
// simple sample. However, we will save the namespace pointer
// and get our event class definition.
// ===========================================================
m_pNs = pNamespace;
m_pNs->AddRef();
// Grab the class definition for the event.
// ======================================
IWbemClassObject *pObj = 0;
HRESULT hRes = m_pNs->GetObject(
CBSTR(EVENTCLASS),
0,
pCtx,
&pObj,
0
);
if (hRes != 0)
return WBEM_E_FAILED;
m_pEventClassDef = pObj;
// Tell CIMOM that we're up and running.
// =====================================
pInitSink->SetStatus(WBEM_S_INITIALIZED,0);
return WBEM_NO_ERROR;
}