WindowsXP-SP1/termsrv/setup/tsdiag/evntutl/events.cpp
2020-09-30 16:53:49 +02:00

169 lines
4.7 KiB
C++

/////////////////////////////////////////////////////////////////////////////
//
// Copyright: Microsoft Corp. 1997-1999. All rights reserved
//
/////////////////////////////////////////////////////////////////////////////
// Events.cpp : Implementation of CEvents
#include "stdafx.h"
#include "Evntutl.h"
#include "Events.h"
/////////////////////////////////////////////////////////////////////////////
// CEvents
STDMETHODIMP CEvents::InterfaceSupportsErrorInfo(REFIID riid)
{
static const IID* arr[] =
{
&IID_IEvents
};
for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
if (InlineIsEqualGUID(*arr[i],riid))
return S_OK;
}
return S_FALSE;
}
/*
Function: get_Count
Inputs: empty long
Outputs: number events available
Purpose: Allows user to determine the number of Events in a Log
*/
STDMETHODIMP CEvents::get_Count(long *pVal)
{
HRESULT hr = S_OK;
if (!GetNumberOfEventLogRecords(m_hLog, &m_Count)) hr = HRESULT_FROM_WIN32(GetLastError());
if (pVal) *pVal = m_Count;
else hr = E_POINTER;
return hr;
}
/*
Function: get_NewEnum
Inputs: empty IUnknown pointer
Outputs: IEnumVariant object filled with Event objects
Purpose: Allows user to use For Each syntax to do operations on all Events in a log
Notes: Events are returned oldest first
*/
STDMETHODIMP CEvents::get__NewEnum(LPUNKNOWN *pVal)
{
HRESULT hr = S_OK;
if (NULL == pVal) return E_POINTER;
*pVal = NULL;
if (SUCCEEDED(hr))
{
EnumVar* pEVar = new EnumVar;
hr = pEVar->Init(&m_pVector[0], &m_pVector[m_Count], NULL, AtlFlagCopy);
if (SUCCEEDED(hr))
hr = pEVar->QueryInterface(IID_IEnumVARIANT, (void**) pVal);
if FAILED(hr)
if (pEVar) delete pEVar;
}
return hr;
}
/*
Function: get_Item
Inputs: Valid integer Index , empty Variant
Outputs: variant dispatch pointer to an Event object
Purpose: Allows user to access individual EventLogs by number
Notes: Events are returned oldest first
*/
STDMETHODIMP CEvents::get_Item(long Index, VARIANT *pVal)
{
HRESULT hr = S_OK;
// perform checks and exit if there is a problem
if (NULL == pVal) return E_POINTER;
if ((Index < 1) || (Index > long(m_Count))) return E_INVALIDARG;
VariantInit(pVal);
pVal->vt = VT_UNKNOWN;
pVal->punkVal = NULL;
VariantCopy(pVal, &m_pVector[Index-1]);
return hr;
}
/*
Function: Init
Inputs: none
Outputs: HRESULT indicating what error if any occured
Purpose: Prepares a variant array filled with Log objects for 3 default logs.
*/
HRESULT CEvents::Init(HANDLE hLog, const LPCTSTR szEventLogName)
{
HRESULT hr = S_OK;
CComObject<CEvent>* pEvent;
BYTE* pBuffer;
EVENTLOGRECORD* pEventStructure;
const unsigned long MaxEventLength = 80000;
DWORD BytesRead = 0, BytesRequired = 0;
unsigned long i = 0;
if (hLog)
{
m_hLog = hLog;
GetNumberOfEventLogRecords(m_hLog, &m_Count);
if (m_pVector != NULL) delete []m_pVector;
m_pVector = new CComVariant[m_Count];
if (m_pVector)
{
pBuffer = new BYTE [MaxEventLength];
if (pBuffer)
{
pEventStructure = (EVENTLOGRECORD*) pBuffer;
// This loop fills a buffer with EventLog structures until there are no more to read
while (ReadEventLog(m_hLog, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
0, pEventStructure, MaxEventLength, &BytesRead, &BytesRequired))
{
// This inner loop should cut the buffer into individual EventLog structures
// and fill the Variant array with the resulting Event objects.
// It should finish when all the bytes read have been processed.
while (BytesRead > 0)
{
// create a CEvent object
hr = CComObject<CEvent>::CreateInstance(&pEvent);
if (SUCCEEDED(hr))
{
hr = pEvent->Init(pEventStructure, szEventLogName);
if (SUCCEEDED(hr))
{
// get IDispatch pointer and set the return pointer
CComVariant& var = m_pVector[i];
var.vt = VT_DISPATCH;
hr = pEvent->QueryInterface(IID_IDispatch, (void**)&var.pdispVal);
if (FAILED(hr)) BytesRead = 0; // dont do any more processing
i++;
}
else BytesRead = 0; // dont do any more processing
}
else BytesRead = 0;
BytesRead -= pEventStructure->Length; // decrement inner loop
// set pEventStructure to the next EventLog structure
pEventStructure = (EVENTLOGRECORD *)((BYTE*) pEventStructure + pEventStructure->Length);
}
if (FAILED(hr)) break; // dont do any more processing
pEventStructure = (EVENTLOGRECORD*) pBuffer;
}
delete [] pBuffer;
}
else hr = E_OUTOFMEMORY;
}
else hr = E_OUTOFMEMORY;
}
else hr = E_HANDLE;
return hr;
}