Source code of Windows XP (NT5)
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.

301 lines
6.6 KiB

  1. /*++
  2. Copyright (C) 1997-2001 Microsoft Corporation
  3. Module Name:
  4. Abstract:
  5. History:
  6. --*/
  7. //***************************************************************************
  8. //
  9. // EVPROV
  10. //
  11. // Sample event provider.
  12. //
  13. //***************************************************************************
  14. #include <windows.h>
  15. #include <stdio.h>
  16. #include <wbemidl.h>
  17. #include "oahelp.inl"
  18. #include "evprov.h"
  19. //***************************************************************************
  20. //
  21. //***************************************************************************
  22. // ok
  23. CMyEventProvider::CMyEventProvider()
  24. {
  25. m_pNs = 0;
  26. m_pSink = 0;
  27. m_cRef = 0;
  28. m_pEventClassDef = 0;
  29. m_eStatus = Pending;
  30. m_hThread = 0;
  31. }
  32. //***************************************************************************
  33. //
  34. //***************************************************************************
  35. // ok
  36. CMyEventProvider::~CMyEventProvider()
  37. {
  38. if (m_hThread)
  39. CloseHandle(m_hThread);
  40. if (m_pNs)
  41. m_pNs->Release();
  42. if (m_pSink)
  43. m_pSink->Release();
  44. if (m_pEventClassDef)
  45. m_pEventClassDef->Release();
  46. }
  47. //***************************************************************************
  48. //
  49. //***************************************************************************
  50. // ok
  51. STDMETHODIMP CMyEventProvider::QueryInterface(REFIID riid, LPVOID * ppv)
  52. {
  53. *ppv = 0;
  54. if (IID_IUnknown==riid || IID_IWbemEventProvider==riid)
  55. {
  56. *ppv = (IWbemEventProvider *) this;
  57. AddRef();
  58. return NOERROR;
  59. }
  60. if (IID_IWbemProviderInit==riid)
  61. {
  62. *ppv = (IWbemProviderInit *) this;
  63. AddRef();
  64. return NOERROR;
  65. }
  66. return ResultFromScode(E_NOINTERFACE);
  67. }
  68. //***************************************************************************
  69. //
  70. //***************************************************************************
  71. // ok
  72. ULONG CMyEventProvider::AddRef()
  73. {
  74. return ++m_cRef;
  75. }
  76. //***************************************************************************
  77. //
  78. //***************************************************************************
  79. // ok
  80. ULONG CMyEventProvider::Release()
  81. {
  82. if (0 != --m_cRef)
  83. return m_cRef;
  84. // If here, we are shutting down.
  85. // ==============================
  86. m_eStatus = PendingStop;
  87. return 0;
  88. }
  89. //***************************************************************************
  90. //
  91. //***************************************************************************
  92. // ok
  93. HRESULT CMyEventProvider::ProvideEvents(
  94. /* [in] */ IWbemObjectSink __RPC_FAR *pSink,
  95. /* [in] */ long lFlags
  96. )
  97. {
  98. // Copy the sink.
  99. // ==============
  100. m_pSink = pSink;
  101. m_pSink->AddRef();
  102. // Create the event thread.
  103. // ========================
  104. DWORD dwTID;
  105. m_hThread = CreateThread(
  106. 0,
  107. 0,
  108. CMyEventProvider::EventThread,
  109. this,
  110. 0,
  111. &dwTID
  112. );
  113. // Wait for provider to be 'ready'.
  114. // ================================
  115. while (m_eStatus != Running)
  116. Sleep(100);
  117. return WBEM_NO_ERROR;
  118. }
  119. //***************************************************************************
  120. //
  121. // This particular provider, being in a DLL operates via its own thread.
  122. //
  123. // In practice, such a provider would probably be implemented within a
  124. // separate EXE.
  125. //
  126. //***************************************************************************
  127. // ok
  128. DWORD WINAPI CMyEventProvider::EventThread(LPVOID pArg)
  129. {
  130. // Make transition to the per-instance method.
  131. // ===========================================
  132. ((CMyEventProvider *)pArg)->InstanceThread();
  133. return 0;
  134. }
  135. //***************************************************************************
  136. //
  137. // Events are generated from here
  138. //
  139. //***************************************************************************
  140. // ok
  141. void CMyEventProvider::InstanceThread()
  142. {
  143. int nIteration = 0;
  144. m_eStatus = Running;
  145. while (m_eStatus == Running)
  146. {
  147. Sleep(2000); // Provide an event every two seconds
  148. // Generate a new event object.
  149. // ============================
  150. IWbemClassObject *pEvt = 0;
  151. HRESULT hRes = m_pEventClassDef->SpawnInstance(0, &pEvt);
  152. if (hRes != 0)
  153. continue; // Failed
  154. // Generate some values to put in the event.
  155. // =========================================
  156. wchar_t Buf[128];
  157. swprintf(Buf, L"Test Event <%d>", nIteration);
  158. CVARIANT vName(Buf);
  159. pEvt->Put(CBSTR(L"Name"), 0, vName, 0);
  160. CVARIANT vCount((LONG) nIteration);
  161. pEvt->Put(CBSTR(L"Value"), 0, vCount, 0);
  162. // Deliver the event to WinMgmt.
  163. // ============================
  164. hRes = m_pSink->Indicate(1, &pEvt);
  165. if (hRes)
  166. {
  167. // If here, delivery failed. Do something to report it.
  168. }
  169. pEvt->Release();
  170. nIteration++;
  171. }
  172. // When we get to here, we are no longer interested in the
  173. // provider and Release() has long since returned.
  174. m_eStatus = Stopped;
  175. delete this;
  176. }
  177. //***************************************************************************
  178. //
  179. //***************************************************************************
  180. // Inherited from IWbemProviderInit
  181. // ================================
  182. HRESULT CMyEventProvider::Initialize(
  183. /* [in] */ LPWSTR pszUser,
  184. /* [in] */ LONG lFlags,
  185. /* [in] */ LPWSTR pszNamespace,
  186. /* [in] */ LPWSTR pszLocale,
  187. /* [in] */ IWbemServices __RPC_FAR *pNamespace,
  188. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  189. /* [in] */ IWbemProviderInitSink __RPC_FAR *pInitSink
  190. )
  191. {
  192. // We don't care about most of the incoming parameters in this
  193. // simple sample. However, we will save the namespace pointer
  194. // and get our event class definition.
  195. // ===========================================================
  196. m_pNs = pNamespace;
  197. m_pNs->AddRef();
  198. // Grab the class definition for the event.
  199. // ======================================
  200. IWbemClassObject *pObj = 0;
  201. HRESULT hRes = m_pNs->GetObject(
  202. CBSTR(EVENTCLASS),
  203. 0,
  204. pCtx,
  205. &pObj,
  206. 0
  207. );
  208. if (hRes != 0)
  209. return WBEM_E_FAILED;
  210. m_pEventClassDef = pObj;
  211. // Tell WinMgmt that we're up and running.
  212. // =====================================
  213. pInitSink->SetStatus(0, WBEM_S_INITIALIZED);
  214. return WBEM_NO_ERROR;
  215. }