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.

168 lines
4.5 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright: Microsoft Corp. 1997-1999. All rights reserved
  4. //
  5. /////////////////////////////////////////////////////////////////////////////
  6. // Events.cpp : Implementation of CEvents
  7. #include "stdafx.h"
  8. #include "Evntutl.h"
  9. #include "Events.h"
  10. /////////////////////////////////////////////////////////////////////////////
  11. // CEvents
  12. STDMETHODIMP CEvents::InterfaceSupportsErrorInfo(REFIID riid)
  13. {
  14. static const IID* arr[] =
  15. {
  16. &IID_IEvents
  17. };
  18. for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
  19. {
  20. if (InlineIsEqualGUID(*arr[i],riid))
  21. return S_OK;
  22. }
  23. return S_FALSE;
  24. }
  25. /*
  26. Function: get_Count
  27. Inputs: empty long
  28. Outputs: number events available
  29. Purpose: Allows user to determine the number of Events in a Log
  30. */
  31. STDMETHODIMP CEvents::get_Count(long *pVal)
  32. {
  33. HRESULT hr = S_OK;
  34. if (!GetNumberOfEventLogRecords(m_hLog, &m_Count)) hr = HRESULT_FROM_WIN32(GetLastError());
  35. if (pVal) *pVal = m_Count;
  36. else hr = E_POINTER;
  37. return hr;
  38. }
  39. /*
  40. Function: get_NewEnum
  41. Inputs: empty IUnknown pointer
  42. Outputs: IEnumVariant object filled with Event objects
  43. Purpose: Allows user to use For Each syntax to do operations on all Events in a log
  44. Notes: Events are returned oldest first
  45. */
  46. STDMETHODIMP CEvents::get__NewEnum(LPUNKNOWN *pVal)
  47. {
  48. HRESULT hr = S_OK;
  49. if (NULL == pVal) return E_POINTER;
  50. *pVal = NULL;
  51. if (SUCCEEDED(hr))
  52. {
  53. EnumVar* pEVar = new EnumVar;
  54. hr = pEVar->Init(&m_pVector[0], &m_pVector[m_Count], NULL, AtlFlagCopy);
  55. if (SUCCEEDED(hr))
  56. hr = pEVar->QueryInterface(IID_IEnumVARIANT, (void**) pVal);
  57. if FAILED(hr)
  58. if (pEVar) delete pEVar;
  59. }
  60. return hr;
  61. }
  62. /*
  63. Function: get_Item
  64. Inputs: Valid integer Index , empty Variant
  65. Outputs: variant dispatch pointer to an Event object
  66. Purpose: Allows user to access individual EventLogs by number
  67. Notes: Events are returned oldest first
  68. */
  69. STDMETHODIMP CEvents::get_Item(long Index, VARIANT *pVal)
  70. {
  71. HRESULT hr = S_OK;
  72. // perform checks and exit if there is a problem
  73. if (NULL == pVal) return E_POINTER;
  74. if ((Index < 1) || (Index > long(m_Count))) return E_INVALIDARG;
  75. VariantInit(pVal);
  76. pVal->vt = VT_UNKNOWN;
  77. pVal->punkVal = NULL;
  78. VariantCopy(pVal, &m_pVector[Index-1]);
  79. return hr;
  80. }
  81. /*
  82. Function: Init
  83. Inputs: none
  84. Outputs: HRESULT indicating what error if any occured
  85. Purpose: Prepares a variant array filled with Log objects for 3 default logs.
  86. */
  87. HRESULT CEvents::Init(HANDLE hLog, const LPCTSTR szEventLogName)
  88. {
  89. HRESULT hr = S_OK;
  90. CComObject<CEvent>* pEvent;
  91. BYTE* pBuffer;
  92. EVENTLOGRECORD* pEventStructure;
  93. const unsigned long MaxEventLength = 80000;
  94. DWORD BytesRead = 0, BytesRequired = 0;
  95. unsigned long i = 0;
  96. if (hLog)
  97. {
  98. m_hLog = hLog;
  99. GetNumberOfEventLogRecords(m_hLog, &m_Count);
  100. if (m_pVector != NULL) delete []m_pVector;
  101. m_pVector = new CComVariant[m_Count];
  102. if (m_pVector)
  103. {
  104. pBuffer = new BYTE [MaxEventLength];
  105. if (pBuffer)
  106. {
  107. pEventStructure = (EVENTLOGRECORD*) pBuffer;
  108. // This loop fills a buffer with EventLog structures until there are no more to read
  109. while (ReadEventLog(m_hLog, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
  110. 0, pEventStructure, MaxEventLength, &BytesRead, &BytesRequired))
  111. {
  112. // This inner loop should cut the buffer into individual EventLog structures
  113. // and fill the Variant array with the resulting Event objects.
  114. // It should finish when all the bytes read have been processed.
  115. while (BytesRead > 0)
  116. {
  117. // create a CEvent object
  118. hr = CComObject<CEvent>::CreateInstance(&pEvent);
  119. if (SUCCEEDED(hr))
  120. {
  121. hr = pEvent->Init(pEventStructure, szEventLogName);
  122. if (SUCCEEDED(hr))
  123. {
  124. // get IDispatch pointer and set the return pointer
  125. CComVariant& var = m_pVector[i];
  126. var.vt = VT_DISPATCH;
  127. hr = pEvent->QueryInterface(IID_IDispatch, (void**)&var.pdispVal);
  128. if (FAILED(hr)) BytesRead = 0; // dont do any more processing
  129. i++;
  130. }
  131. else BytesRead = 0; // dont do any more processing
  132. }
  133. else BytesRead = 0;
  134. BytesRead -= pEventStructure->Length; // decrement inner loop
  135. // set pEventStructure to the next EventLog structure
  136. pEventStructure = (EVENTLOGRECORD *)((BYTE*) pEventStructure + pEventStructure->Length);
  137. }
  138. if (FAILED(hr)) break; // dont do any more processing
  139. pEventStructure = (EVENTLOGRECORD*) pBuffer;
  140. }
  141. delete [] pBuffer;
  142. }
  143. else hr = E_OUTOFMEMORY;
  144. }
  145. else hr = E_OUTOFMEMORY;
  146. }
  147. else hr = E_HANDLE;
  148. return hr;
  149. }