windows-nt/Source/XPSP1/NT/admin/wmi/wbem/winmgmt/eventprovshell/evprov.cpp
2020-09-26 16:20:57 +08:00

302 lines
6.6 KiB
C++

/*++
Copyright (C) 1997-2001 Microsoft Corporation
Module Name:
Abstract:
History:
--*/
//***************************************************************************
//
// EVPROV
//
// Sample event provider.
//
//***************************************************************************
#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 ResultFromScode(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(2000); // Provide an event every two 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);
CVARIANT vCount((LONG) nIteration);
pEvt->Put(CBSTR(L"Value"), 0, vCount, 0);
// Deliver the event to WinMgmt.
// ============================
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 WinMgmt that we're up and running.
// =====================================
pInitSink->SetStatus(0, WBEM_S_INITIALIZED);
return WBEM_NO_ERROR;
}