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.

313 lines
7.1 KiB

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