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.
664 lines
21 KiB
664 lines
21 KiB
#include "precomp.h"
|
|
#include <stdio.h>
|
|
#include <wbemutil.h>
|
|
#include <wbemcomn.h>
|
|
#include <GroupsForUser.h>
|
|
#include "evtlog.h"
|
|
#include <GenUtils.h>
|
|
#include <comdef.h>
|
|
#include <Sddl.h>
|
|
#undef _ASSERT
|
|
#include <atlbase.h>
|
|
|
|
#define EVENTLOG_PROPNAME_SERVER L"UNCServerName"
|
|
#define EVENTLOG_PROPNAME_SOURCE L"SourceName"
|
|
#define EVENTLOG_PROPNAME_EVENTID L"EventID"
|
|
#define EVENTLOG_PROPNAME_TYPE L"EventType"
|
|
#define EVENTLOG_PROPNAME_CATEGORY L"Category"
|
|
#define EVENTLOG_PROPNAME_NUMSTRINGS L"NumberOfInsertionStrings"
|
|
#define EVENTLOG_PROPNAME_STRINGS L"InsertionStringTemplates"
|
|
#define EVENTLOG_PROPNAME_CREATORSID L"CreatorSid"
|
|
#define EVENTLOG_PROPNAME_DATANAME L"NameOfRawDataProperty"
|
|
#define EVENTLOG_PROPNAME_SIDNAME L"NameOfUserSIDProperty"
|
|
|
|
HRESULT STDMETHODCALLTYPE CEventLogConsumer::XProvider::FindConsumer(
|
|
IWbemClassObject* pLogicalConsumer,
|
|
IWbemUnboundObjectSink** ppConsumer)
|
|
{
|
|
CEventLogSink* pSink = new CEventLogSink(m_pObject->m_pControl);
|
|
|
|
if(pSink == NULL)
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
|
|
HRESULT hres = pSink->Initialize(pLogicalConsumer);
|
|
|
|
if(FAILED(hres))
|
|
{
|
|
delete pSink;
|
|
*ppConsumer = NULL;
|
|
return hres;
|
|
}
|
|
else return pSink->QueryInterface(IID_IWbemUnboundObjectSink,
|
|
(void**)ppConsumer);
|
|
}
|
|
|
|
|
|
void* CEventLogConsumer::GetInterface(REFIID riid)
|
|
{
|
|
if(riid == IID_IWbemEventConsumerProvider)
|
|
return &m_XProvider;
|
|
else return NULL;
|
|
}
|
|
|
|
CEventLogSink::~CEventLogSink()
|
|
{
|
|
if(m_hEventLog)
|
|
DeregisterEventSource(m_hEventLog);
|
|
|
|
if(m_aTemplates)
|
|
delete [] m_aTemplates;
|
|
|
|
if(m_pSidCreator)
|
|
delete [] m_pSidCreator;
|
|
}
|
|
|
|
HRESULT CEventLogSink::Initialize(IWbemClassObject* pLogicalConsumer)
|
|
{
|
|
// Get the information
|
|
// ===================
|
|
|
|
HRESULT hres = WBEM_S_NO_ERROR;
|
|
CComVariant v;
|
|
|
|
// Get the server and source
|
|
// =========================
|
|
|
|
WString wsServer;
|
|
hres = pLogicalConsumer->Get(EVENTLOG_PROPNAME_SERVER, 0, &v, NULL, NULL);
|
|
|
|
if(FAILED(hres)) return hres;
|
|
|
|
if(V_VT(&v) == VT_BSTR)
|
|
wsServer = V_BSTR(&v);
|
|
|
|
VariantClear(&v);
|
|
|
|
WString wsSource;
|
|
hres = pLogicalConsumer->Get(EVENTLOG_PROPNAME_SOURCE, 0, &v, NULL, NULL);
|
|
if(SUCCEEDED(hres) && (V_VT(&v) == VT_BSTR))
|
|
wsSource = V_BSTR(&v);
|
|
|
|
VariantClear(&v);
|
|
|
|
m_hEventLog = RegisterEventSourceW(
|
|
( (wsServer.Length() == 0) ? NULL : (LPCWSTR)wsServer),
|
|
wsSource);
|
|
if(m_hEventLog == NULL)
|
|
{
|
|
ERRORTRACE((LOG_ESS, "Unable to register event source '%S' on server "
|
|
"'%S'. Error code: %X\n", (LPCWSTR)wsSource, (LPCWSTR)wsServer,
|
|
GetLastError()));
|
|
return WBEM_E_FAILED;
|
|
}
|
|
|
|
// Get event parameters
|
|
// ====================
|
|
|
|
hres = pLogicalConsumer->Get(EVENTLOG_PROPNAME_EVENTID, 0, &v, NULL, NULL);
|
|
if(SUCCEEDED(hres) && (V_VT(&v) == VT_I4))
|
|
m_dwEventId = V_I4(&v);
|
|
else
|
|
// This will mean we need to try to get the event information off of each
|
|
// event class as it arrives.
|
|
m_dwEventId = 0;
|
|
|
|
hres = pLogicalConsumer->Get(EVENTLOG_PROPNAME_TYPE, 0, &v, NULL, NULL);
|
|
if(FAILED(hres) || (V_VT(&v) != VT_I4))
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
m_dwType = V_I4(&v);
|
|
|
|
hres = pLogicalConsumer->Get(EVENTLOG_PROPNAME_CATEGORY, 0, &v, NULL, NULL);
|
|
if(FAILED(hres) || (V_VT(&v) != VT_I4))
|
|
m_dwCategory = 0;
|
|
else
|
|
m_dwCategory = V_I4(&v);
|
|
|
|
if (m_dwCategory > 0xFFFF)
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
|
|
|
|
// Get insertion strings
|
|
// =====================
|
|
|
|
// Only get this stuff if the logical consumer has an event id.
|
|
if (m_dwEventId)
|
|
{
|
|
hres = pLogicalConsumer->Get(EVENTLOG_PROPNAME_NUMSTRINGS, 0, &v,
|
|
NULL, NULL);
|
|
if(FAILED(hres) || (V_VT(&v) != VT_I4))
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
m_dwNumTemplates = V_I4(&v);
|
|
|
|
|
|
hres = pLogicalConsumer->Get(EVENTLOG_PROPNAME_STRINGS, 0, &v, NULL, NULL);
|
|
if(FAILED(hres))
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
|
|
// array of bstrs or null, else bail
|
|
if ((V_VT(&v) != (VT_BSTR | VT_ARRAY)) && (V_VT(&v) != VT_NULL))
|
|
{
|
|
VariantClear(&v);
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
if ((V_VT(&v) == VT_NULL) && (m_dwNumTemplates > 0))
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
|
|
if (m_dwNumTemplates > 0)
|
|
{
|
|
CVarVector vv(VT_BSTR, V_ARRAY(&v));
|
|
VariantClear(&v);
|
|
|
|
if (vv.Size() < m_dwNumTemplates)
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
|
|
m_aTemplates = new CTextTemplate[m_dwNumTemplates];
|
|
if(m_aTemplates == NULL)
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
|
|
for(DWORD i = 0; i < m_dwNumTemplates; i++)
|
|
{
|
|
m_aTemplates[i].SetTemplate(vv.GetAt(i).GetLPWSTR());
|
|
}
|
|
}
|
|
}
|
|
|
|
hres = pLogicalConsumer->Get(EVENTLOG_PROPNAME_DATANAME, 0, &v,
|
|
NULL, NULL);
|
|
if (SUCCEEDED(hres) && (v.vt == VT_BSTR) && (v.bstrVal != NULL))
|
|
{
|
|
m_dataName = v.bstrVal;
|
|
}
|
|
|
|
VariantClear(&v);
|
|
|
|
hres = pLogicalConsumer->Get(EVENTLOG_PROPNAME_SIDNAME, 0, &v,
|
|
NULL, NULL);
|
|
if (SUCCEEDED(hres) && (v.vt == VT_BSTR) && (v.bstrVal != NULL))
|
|
{
|
|
m_sidName = v.bstrVal;
|
|
}
|
|
|
|
VariantClear(&v);
|
|
|
|
hres = pLogicalConsumer->Get(EVENTLOG_PROPNAME_CREATORSID, 0, &v,
|
|
NULL, NULL);
|
|
|
|
if (SUCCEEDED(hres) && (v.vt != VT_NULL))
|
|
{
|
|
if((v.vt != (VT_ARRAY | VT_UI1)))
|
|
{
|
|
VariantClear(&v);
|
|
return WBEM_E_INVALID_OBJECT;
|
|
}
|
|
|
|
long ubound;
|
|
if(SUCCEEDED(hres = SafeArrayGetUBound(V_ARRAY(&v), 1, &ubound)))
|
|
{
|
|
PVOID pVoid;
|
|
if(SUCCEEDED(hres = SafeArrayAccessData(V_ARRAY(&v), &pVoid)))
|
|
{
|
|
m_pSidCreator = new BYTE[ubound +1];
|
|
if(m_pSidCreator == NULL)
|
|
hres = WBEM_E_OUT_OF_MEMORY;
|
|
else
|
|
memcpy(m_pSidCreator, pVoid, ubound + 1);
|
|
|
|
SafeArrayUnaccessData(V_ARRAY(&v));
|
|
}
|
|
}
|
|
}
|
|
VariantClear(&v);
|
|
|
|
return hres;
|
|
}
|
|
|
|
HRESULT CEventLogSink::XSink::GetDatEmbeddedObjectOut(IWbemClassObject* pObject, WCHAR* objectName, IWbemClassObject*& pEmbeddedObject)
|
|
{
|
|
HRESULT hr;
|
|
|
|
VARIANT vObject;
|
|
VariantInit(&vObject);
|
|
|
|
hr = pObject->Get(objectName, 0, &vObject, NULL, NULL);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
ERRORTRACE((LOG_ESS, "NT Event Log Consumer: could not retrieve %S, 0x%08X\n", objectName, hr));
|
|
}
|
|
else if ((vObject.vt != VT_UNKNOWN) || (vObject.punkVal == NULL)
|
|
|| FAILED(vObject.punkVal->QueryInterface(IID_IWbemClassObject, (void**)&pEmbeddedObject)))
|
|
{
|
|
ERRORTRACE((LOG_ESS, "NT Event Log Consumer: %S is not an embedded object\n", objectName));
|
|
hr = WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
VariantClear(&vObject);
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
HRESULT CEventLogSink::XSink::GetDatDataVariant(IWbemClassObject* pEventObj, WCHAR* dataName, VARIANT& vData)
|
|
{
|
|
WCHAR* propName = NULL;
|
|
IWbemClassObject* pDataObj = NULL;
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
// parse out data name
|
|
WCHAR* pDot;
|
|
if (pDot = wcschr(dataName, L'.'))
|
|
{
|
|
// found a dot, we're dealing with an embedded object
|
|
// mask out dot to make our life easier
|
|
*pDot = L'\0';
|
|
|
|
WCHAR* pNextDot;
|
|
pNextDot = wcschr(pDot+1, L'.');
|
|
|
|
if (pNextDot)
|
|
// we have a doubly embedded object, that's as deep as we support
|
|
{
|
|
// we now have three prop names with nulls between
|
|
*pNextDot = '\0';
|
|
IWbemClassObject* pIntermediateObj = NULL;
|
|
|
|
if (SUCCEEDED(hr = GetDatEmbeddedObjectOut(pEventObj, dataName, pIntermediateObj)))
|
|
{
|
|
hr = GetDatEmbeddedObjectOut(pIntermediateObj, pDot +1, pDataObj);
|
|
pIntermediateObj->Release();
|
|
}
|
|
|
|
propName = pNextDot +1;
|
|
|
|
// put dot back
|
|
*pDot = L'.';
|
|
|
|
// put dot dot back back
|
|
*pNextDot = L'.';
|
|
|
|
}
|
|
else
|
|
// we have a singly embedded object. cool.
|
|
{
|
|
hr = GetDatEmbeddedObjectOut(pEventObj, dataName, pDataObj);
|
|
|
|
// put dot back
|
|
*pDot = L'.';
|
|
|
|
propName = pDot +1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// not an embedded object
|
|
pDataObj = pEventObj;
|
|
pDataObj->AddRef();
|
|
|
|
propName = dataName;
|
|
}
|
|
|
|
if (SUCCEEDED(hr) && pDataObj)
|
|
{
|
|
if (FAILED(hr = pDataObj->Get(propName, 0, &vData, NULL, NULL)))
|
|
DEBUGTRACE((LOG_ESS, "NT Event Log Consumer: could not retrieve property '%S' 0x%08X\n", dataName, hr));
|
|
}
|
|
|
|
if (pDataObj)
|
|
pDataObj->Release();
|
|
|
|
return hr;
|
|
}
|
|
|
|
// assumes that dataName is a valid string
|
|
// retrieves data from event object
|
|
// upon return pData points at data contained in variant
|
|
// calls responsibility to clear variant (don't delete pData)
|
|
// void return, any errors are logged - we don't want to block an event log if we can avoid it
|
|
void CEventLogSink::XSink::GetDatData(IWbemClassObject* pEventObj, WCHAR* dataName,
|
|
VARIANT& vData, BYTE*& pData, DWORD& dataSize)
|
|
{
|
|
pData = NULL;
|
|
dataSize = 0;
|
|
HRESULT hr;
|
|
|
|
if (SUCCEEDED(GetDatDataVariant(pEventObj, dataName, vData)))
|
|
{
|
|
hr = VariantChangeType(&vData, &vData, 0, (VT_UI1 | VT_ARRAY));
|
|
|
|
if (FAILED(hr) || (vData.vt != (VT_UI1 | VT_ARRAY)))
|
|
{
|
|
ERRORTRACE((LOG_ESS, "NT Event Log Consumer: %S cannot be converted to a byte array (0x%08X)\n", dataName, hr));
|
|
VariantClear(&vData);
|
|
}
|
|
else
|
|
// should be good to go!
|
|
{
|
|
if (FAILED(hr = SafeArrayAccessData(vData.parray, (void**)&pData)))
|
|
{
|
|
ERRORTRACE((LOG_ESS, "NT Event Log Consumer: failed to access %S, 0x%08X\n", dataName, hr));
|
|
VariantClear(&vData);
|
|
}
|
|
|
|
long lDataSize;
|
|
SafeArrayGetUBound(vData.parray, 1, &lDataSize);
|
|
dataSize = (DWORD)lDataSize + 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
// assumes that dataName is a valid string
|
|
// retrieves data from event object
|
|
// void return, any errors are logged - we don't want to block an event log if we can avoid it
|
|
void CEventLogSink::XSink::GetDatSID(IWbemClassObject* pEventObj, WCHAR* dataName, PSID& pSid)
|
|
{
|
|
HRESULT hr;
|
|
|
|
VARIANT vData;
|
|
VariantInit(&vData);
|
|
|
|
pSid = NULL;
|
|
|
|
if (SUCCEEDED(hr = GetDatDataVariant(pEventObj, dataName, vData)))
|
|
{
|
|
if (vData.vt == (VT_UI1 | VT_ARRAY))
|
|
{
|
|
BYTE* pData;
|
|
|
|
// this should be a binary SID
|
|
if (FAILED(hr = SafeArrayAccessData(vData.parray, (void**)&pData)))
|
|
ERRORTRACE((LOG_ESS, "NT Event Log Consumer: failed to access %S, 0x%08X\n", dataName, hr));
|
|
else
|
|
{
|
|
if (IsValidSid((PSID)pData))
|
|
{
|
|
DWORD l = GetLengthSid((PSID)pData);
|
|
if (pSid = new BYTE[l])
|
|
CopySid(l, pSid, (PSID)pData);
|
|
}
|
|
}
|
|
}
|
|
else if ((vData.vt == VT_BSTR) && (vData.bstrVal != NULL))
|
|
{
|
|
PSID pLocalSid;
|
|
|
|
if (!ConvertStringSidToSid(vData.bstrVal, &pLocalSid))
|
|
ERRORTRACE((LOG_ESS, "NT Event Log Consumer: cannot convert %S to a SID\n", vData.bstrVal));
|
|
else
|
|
{
|
|
DWORD l = GetLengthSid(pLocalSid);
|
|
if (pSid = new BYTE[l])
|
|
CopySid(l, pSid, pLocalSid);
|
|
FreeSid(pLocalSid);
|
|
}
|
|
}
|
|
else
|
|
ERRORTRACE((LOG_ESS, "NT Event Log Consumer: %S is not a SID\n", dataName));
|
|
|
|
VariantClear(&vData);
|
|
}
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CEventLogSink::XSink::IndicateToConsumer(
|
|
IWbemClassObject* pLogicalConsumer, long lNumObjects,
|
|
IWbemClassObject** apObjects)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
if (IsNT())
|
|
{
|
|
PSID pSidSystem;
|
|
SID_IDENTIFIER_AUTHORITY id = SECURITY_NT_AUTHORITY;
|
|
|
|
if (AllocateAndInitializeSid(&id, 1,
|
|
SECURITY_LOCAL_SYSTEM_RID,
|
|
0, 0,0,0,0,0,0,&pSidSystem))
|
|
{
|
|
// guilty until proven innocent
|
|
hr = WBEM_E_ACCESS_DENIED;
|
|
|
|
// check to see if sid is either Local System or an admin of some sort...
|
|
if ((EqualSid(pSidSystem, m_pObject->m_pSidCreator)) ||
|
|
(S_OK == IsUserAdministrator(m_pObject->m_pSidCreator)))
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
// We're done with this
|
|
FreeSid(pSidSystem);
|
|
|
|
if (FAILED(hr))
|
|
return hr;
|
|
}
|
|
else
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
|
|
for(int i = 0; i < lNumObjects; i++)
|
|
{
|
|
int j;
|
|
BOOL bRes = FALSE;
|
|
|
|
// Do all events use the same ID?
|
|
if (m_pObject->m_dwEventId)
|
|
{
|
|
BSTR* astrStrings = new BSTR[m_pObject->m_dwNumTemplates];
|
|
if(astrStrings == NULL)
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
for(j = 0; j < m_pObject->m_dwNumTemplates; j++)
|
|
{
|
|
BSTR strText = m_pObject->m_aTemplates[j].Apply(apObjects[i]);
|
|
if(strText == NULL)
|
|
{
|
|
strText = SysAllocString(L"invalid log entry");
|
|
if(strText == NULL)
|
|
{
|
|
delete [] astrStrings;
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
}
|
|
astrStrings[j] = strText;
|
|
}
|
|
|
|
DWORD dataSize = NULL;
|
|
|
|
// data is actually held in the variant
|
|
// pData just makes access easier (clear the variant, don't delete pData!)
|
|
VARIANT vData;
|
|
VariantInit(&vData);
|
|
BYTE *pData = NULL;
|
|
|
|
PSID pSid = NULL;
|
|
|
|
if (m_pObject->m_dataName.Length() > 0)
|
|
GetDatData(apObjects[i], m_pObject->m_dataName, vData, pData, dataSize);
|
|
|
|
if (m_pObject->m_sidName.Length() > 0)
|
|
GetDatSID(apObjects[i], m_pObject->m_sidName, pSid);
|
|
|
|
bRes = ReportEventW(m_pObject->m_hEventLog, m_pObject->m_dwType,
|
|
m_pObject->m_dwCategory, m_pObject->m_dwEventId, pSid,
|
|
m_pObject->m_dwNumTemplates, dataSize,
|
|
(LPCWSTR*)astrStrings, pData);
|
|
|
|
// sid was allocated as an array of BYTE, not via AllocateAndInitializeSid
|
|
if (pSid)
|
|
delete[] pSid;
|
|
|
|
if (vData.vt == (VT_UI1 | VT_ARRAY))
|
|
SafeArrayUnaccessData(vData.parray);
|
|
|
|
VariantClear(&vData);
|
|
pData = NULL;
|
|
|
|
if(!bRes)
|
|
{
|
|
ERRORTRACE((LOG_ESS, "Failed to log an event: %X\n",
|
|
GetLastError()));
|
|
|
|
hr = WBEM_E_FAILED;
|
|
}
|
|
|
|
|
|
for(j = 0; j < m_pObject->m_dwNumTemplates; j++)
|
|
{
|
|
SysFreeString(astrStrings[j]);
|
|
}
|
|
delete [] astrStrings;
|
|
}
|
|
// If each event supplies its own ID, we have some work to do.
|
|
else
|
|
{
|
|
IWbemQualifierSet *pQuals = NULL;
|
|
|
|
if (SUCCEEDED(apObjects[i]->GetQualifierSet(&pQuals)))
|
|
{
|
|
_variant_t vMsgID;
|
|
|
|
if (SUCCEEDED(pQuals->Get(EVENTLOG_PROPNAME_EVENTID, 0, &vMsgID, NULL)) &&
|
|
((vMsgID.vt == VT_BSTR) || (vMsgID.vt == VT_I4)))
|
|
{
|
|
_variant_t vTemplates;
|
|
BSTR *pstrInsertionStrings = NULL;
|
|
DWORD nStrings = 0;
|
|
|
|
if (SUCCEEDED(pQuals->Get(
|
|
EVENTLOG_PROPNAME_STRINGS, 0, &vTemplates, NULL)) &&
|
|
vTemplates.vt == (VT_ARRAY | VT_BSTR) &&
|
|
vTemplates.parray->rgsabound[0].cElements > 0)
|
|
{
|
|
CTextTemplate *pTemplates;
|
|
|
|
nStrings = vTemplates.parray->rgsabound[0].cElements;
|
|
pTemplates = new CTextTemplate[nStrings];
|
|
if(pTemplates == NULL)
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
|
|
pstrInsertionStrings = new BSTR[nStrings];
|
|
if(pstrInsertionStrings == NULL)
|
|
{
|
|
delete [] pTemplates;
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
|
|
if (pTemplates && pstrInsertionStrings)
|
|
{
|
|
BSTR *pTemplateStrings = (BSTR*) vTemplates.parray->pvData;
|
|
|
|
for (j = 0; j < nStrings; j++)
|
|
{
|
|
pTemplates[j].SetTemplate(pTemplateStrings[j]);
|
|
pstrInsertionStrings[j] = pTemplates[j].Apply(apObjects[i]);
|
|
}
|
|
}
|
|
else
|
|
nStrings = 0;
|
|
|
|
if (pTemplates)
|
|
delete [] pTemplates;
|
|
}
|
|
|
|
|
|
DWORD dwEventID,
|
|
dwType,
|
|
dwCategory;
|
|
_variant_t vTemp;
|
|
WCHAR *szBad;
|
|
|
|
if (vMsgID.vt == VT_BSTR)
|
|
dwEventID = wcstoul(V_BSTR(&vMsgID), &szBad, 10);
|
|
else if (vMsgID.vt == VT_I4)
|
|
dwEventID = V_I4(&vMsgID);
|
|
|
|
if ((SUCCEEDED(pQuals->Get(EVENTLOG_PROPNAME_TYPE, 0, &vTemp, NULL))) &&
|
|
(V_VT(&vTemp) == VT_I4))
|
|
dwType = V_I4(&vTemp);
|
|
else
|
|
dwType = m_pObject->m_dwType;
|
|
|
|
if (SUCCEEDED(pQuals->Get(
|
|
EVENTLOG_PROPNAME_CATEGORY, 0, &vTemp, NULL)))
|
|
dwCategory = V_I4(&vTemp);
|
|
else
|
|
dwCategory = m_pObject->m_dwCategory;
|
|
|
|
DWORD dataSize = NULL;
|
|
// data is actually held in the variant
|
|
// pData just makes access easier (clear the variant, don't delete pData!)
|
|
VARIANT vData;
|
|
VariantInit(&vData);
|
|
BYTE *pData = NULL;
|
|
PSID pSid = NULL;
|
|
|
|
if (m_pObject->m_dataName.Length() > 0)
|
|
GetDatData(apObjects[i], m_pObject->m_dataName, vData, pData, dataSize);
|
|
|
|
if (m_pObject->m_sidName.Length() > 0)
|
|
GetDatSID(apObjects[i], m_pObject->m_sidName, pSid);
|
|
|
|
bRes =
|
|
ReportEventW(
|
|
m_pObject->m_hEventLog,
|
|
dwType,
|
|
dwCategory,
|
|
dwEventID,
|
|
pSid,
|
|
nStrings,
|
|
dataSize,
|
|
(LPCWSTR*) pstrInsertionStrings,
|
|
pData);
|
|
|
|
// sid was allocated as an array of BYTE, not via AllocateAndInitializeSid
|
|
if (pSid)
|
|
delete[] pSid;
|
|
|
|
if (vData.vt == (VT_UI1 | VT_ARRAY))
|
|
SafeArrayUnaccessData(vData.parray);
|
|
|
|
VariantClear(&vData);
|
|
pData = NULL;
|
|
|
|
if (!bRes)
|
|
{
|
|
ERRORTRACE((LOG_ESS, "Failed to log an event: %X\n",
|
|
GetLastError()));
|
|
|
|
hr = WBEM_E_FAILED;
|
|
}
|
|
|
|
for (j = 0; j < nStrings; j++)
|
|
SysFreeString(pstrInsertionStrings[j]);
|
|
|
|
delete [] pstrInsertionStrings;
|
|
|
|
} // SUCCEEDED(Get)
|
|
|
|
pQuals->Release();
|
|
|
|
} // SUCCEEDED(GetQualifierSet)
|
|
}
|
|
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
|
|
void* CEventLogSink::GetInterface(REFIID riid)
|
|
{
|
|
if(riid == IID_IWbemUnboundObjectSink)
|
|
return &m_XSink;
|
|
else return NULL;
|
|
}
|
|
|