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.
621 lines
14 KiB
621 lines
14 KiB
// EventInfo.cpp
|
|
|
|
#include "precomp.h"
|
|
#include "ProvInfo.h"
|
|
#include "EventInfo.h"
|
|
#include "NCProv.h"
|
|
#include "NCProvider.h"
|
|
#include <comutl.h>
|
|
|
|
|
|
#define COUNTOF(x) (sizeof(x)/sizeof(x[0]))
|
|
#define DWORD_ALIGNED(x) ((DWORD)((((x) * 8) + 31) & (~31)) / 8)
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CEventInfo
|
|
|
|
CEventInfo::CEventInfo() :
|
|
m_pPropFuncs(0)
|
|
{
|
|
}
|
|
|
|
CEventInfo::~CEventInfo()
|
|
{
|
|
}
|
|
|
|
BOOL GetClassQualifier(
|
|
IWbemClassObject *pObj,
|
|
LPCWSTR szQualifier,
|
|
VARIANT *pVal)
|
|
{
|
|
IWbemQualifierSet *pSet = NULL;
|
|
BOOL bRet = FALSE;
|
|
|
|
if (SUCCEEDED(pObj->GetQualifierSet(&pSet)))
|
|
{
|
|
if (SUCCEEDED(pSet->Get(szQualifier, 0, pVal, NULL)))
|
|
bRet = TRUE;
|
|
|
|
pSet->Release();
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
BOOL GetClassPropertyQualifier(
|
|
IWbemClassObject *pObj,
|
|
LPCWSTR szProperty,
|
|
LPCWSTR szQualifier,
|
|
VARIANT *pVal)
|
|
{
|
|
IWbemQualifierSet *pSet = NULL;
|
|
BOOL bRet = FALSE;
|
|
|
|
if (SUCCEEDED(pObj->GetPropertyQualifierSet(szProperty, &pSet)))
|
|
{
|
|
if (SUCCEEDED(pSet->Get(szQualifier, 0, pVal, NULL)))
|
|
bRet = TRUE;
|
|
|
|
pSet->Release();
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
#define MAX_EVENT_PROPS 1024
|
|
|
|
BOOL CEventInfo::InitFromBuffer(CClientInfo *pInfo, CBuffer *pBuffer)
|
|
{
|
|
WCHAR *pszEvent;
|
|
DWORD nProps,
|
|
dwStrSize;
|
|
BOOL bRet = FALSE;
|
|
|
|
m_pInfo = pInfo;
|
|
|
|
// Get the number of properties for this event layout.
|
|
nProps = pBuffer->ReadDWORD();
|
|
|
|
if ( nProps > MAX_EVENT_PROPS )
|
|
return FALSE;
|
|
|
|
pszEvent = pBuffer->ReadAlignedLenString(&dwStrSize);
|
|
|
|
if ( dwStrSize == 0 )
|
|
return FALSE;
|
|
|
|
// Prepare the array of property functions.
|
|
m_pPropFuncs.Init(nProps);
|
|
|
|
LPWSTR *pszProps = new LPWSTR[nProps];
|
|
|
|
if (pszProps)
|
|
{
|
|
for (DWORD i = 0; i < nProps; i++)
|
|
{
|
|
DWORD type = pBuffer->ReadDWORD();
|
|
DWORD dwSize;
|
|
LPCWSTR szProp = pBuffer->ReadAlignedLenString(&dwSize);
|
|
PROP_FUNC pFunc = TypeToPropFunc(type);
|
|
|
|
if ( pFunc == NULL || !m_pPropFuncs.AddVal(pFunc) )
|
|
{
|
|
delete [] pszProps;
|
|
return FALSE;
|
|
}
|
|
|
|
pszProps[i] = (BSTR) szProp;
|
|
}
|
|
|
|
bRet =
|
|
Init(
|
|
pInfo->m_pProvider->m_pProv->GetNamespace(),
|
|
pszEvent,
|
|
(LPCWSTR*) pszProps,
|
|
nProps,
|
|
FAILED_PROP_TRY_ARRAY);
|
|
|
|
delete [] pszProps;
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
BOOL CEventInfo::SetPropsWithBuffer(CBuffer *pBuffer)
|
|
{
|
|
if (!m_pObj)
|
|
return FALSE;
|
|
|
|
DWORD nProps = m_pPropFuncs.GetCount();
|
|
BOOL bRet = TRUE;
|
|
DWORD *pNullTable = (DWORD*) pBuffer->m_pCurrent;
|
|
|
|
if ( PBYTE(pNullTable + nProps/32) >
|
|
(pBuffer->m_pBuffer + pBuffer->m_dwSize) )
|
|
return FALSE;
|
|
|
|
// We need this as the offsets are relative from the beginning
|
|
// of the object packet (including the 2 DWORDs of header stuff).
|
|
|
|
m_pBitsBase = (LPBYTE) (pNullTable - 3);
|
|
_ASSERT( m_pBitsBase < pBuffer->m_pBuffer + pBuffer->m_dwSize );
|
|
m_cBitsBase = pBuffer->m_pBuffer + pBuffer->m_dwSize - m_pBitsBase;
|
|
|
|
m_pdwPropTable = pNullTable + (nProps / 32 + ((nProps % 32) != 0));
|
|
if ( PBYTE(m_pdwPropTable + nProps) >
|
|
(pBuffer->m_pBuffer + pBuffer->m_dwSize) )
|
|
return FALSE;
|
|
|
|
//
|
|
// here we should be safe to use the prop table now, but the
|
|
// use of bits base is checked against buffer overflow on a case by
|
|
// case basis.
|
|
//
|
|
|
|
for (m_iCurrentVar = 0;
|
|
m_iCurrentVar < nProps && bRet;
|
|
m_iCurrentVar++)
|
|
{
|
|
|
|
if ((pNullTable[m_iCurrentVar / 32] & (1 << (m_iCurrentVar % 32))))
|
|
{
|
|
PROP_FUNC pFunc = m_pPropFuncs[m_iCurrentVar];
|
|
|
|
_ASSERT(pFunc != NULL);
|
|
|
|
bRet = (this->*pFunc)();
|
|
|
|
_ASSERT(bRet);
|
|
}
|
|
#ifdef NO_WINMGMT
|
|
else
|
|
WriteNULL(m_iCurrentVar);
|
|
#endif
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
PROP_FUNC CEventInfo::TypeToPropFunc(DWORD type)
|
|
{
|
|
PROP_FUNC pRet;
|
|
BOOL bNonArray = (type & CIM_FLAG_ARRAY) == 0;
|
|
|
|
switch(type & ~CIM_FLAG_ARRAY)
|
|
{
|
|
case CIM_STRING:
|
|
case CIM_REFERENCE:
|
|
case CIM_DATETIME:
|
|
pRet = bNonArray ? ProcessString : ProcessStringArray;
|
|
break;
|
|
|
|
case CIM_UINT32:
|
|
case CIM_SINT32:
|
|
case CIM_REAL32:
|
|
pRet = bNonArray ? ProcessDWORD : ProcessArray4;
|
|
break;
|
|
|
|
case CIM_UINT16:
|
|
case CIM_SINT16:
|
|
case CIM_CHAR16:
|
|
case CIM_BOOLEAN:
|
|
pRet = bNonArray ? ProcessWORD : ProcessArray2;
|
|
break;
|
|
|
|
case CIM_SINT8:
|
|
case CIM_UINT8:
|
|
pRet = bNonArray ? ProcessBYTE : ProcessArray1;
|
|
break;
|
|
|
|
case CIM_SINT64:
|
|
case CIM_UINT64:
|
|
case CIM_REAL64:
|
|
pRet = bNonArray ? ProcessDWORD64 : ProcessArray8;
|
|
break;
|
|
|
|
case CIM_OBJECT:
|
|
pRet = bNonArray ? ProcessObject : NULL;
|
|
break;
|
|
|
|
// We'll use this for _IWmiObjects.
|
|
case CIM_IUNKNOWN:
|
|
pRet = bNonArray ? ProcessWmiObject : NULL;
|
|
break;
|
|
|
|
default:
|
|
// Bad type!
|
|
_ASSERT(FALSE);
|
|
pRet = NULL;
|
|
}
|
|
|
|
return pRet;
|
|
}
|
|
|
|
BOOL CEventInfo::ProcessString()
|
|
{
|
|
DWORD cData;
|
|
LPBYTE pData = GetPropDataPointer(m_iCurrentVar, cData );
|
|
|
|
if ( cData < sizeof(DWORD) )
|
|
return FALSE;
|
|
|
|
DWORD dwSize = *(DWORD*) pData;
|
|
BOOL bRet;
|
|
|
|
if ( dwSize > cData - sizeof(DWORD) )
|
|
return FALSE;
|
|
|
|
#ifndef NO_WINMGMT
|
|
bRet = WriteData( m_iCurrentVar,
|
|
pData + sizeof(DWORD),
|
|
dwSize );
|
|
#else
|
|
bRet = TRUE;
|
|
#endif
|
|
|
|
return bRet;
|
|
}
|
|
|
|
#define MAX_ARRAY_SIZE 4096
|
|
|
|
BOOL CEventInfo::ProcessStringArray()
|
|
{
|
|
DWORD cData;
|
|
LPBYTE pData = GetPropDataPointer(m_iCurrentVar, cData);
|
|
|
|
if ( cData < sizeof(DWORD) )
|
|
return FALSE;
|
|
|
|
DWORD nStrings = *(DWORD*) pData;
|
|
BOOL bRet;
|
|
VARIANT vValue;
|
|
SAFEARRAYBOUND sabound;
|
|
|
|
if ( nStrings > MAX_ARRAY_SIZE )
|
|
return FALSE;
|
|
|
|
sabound.lLbound = 0;
|
|
sabound.cElements = nStrings;
|
|
|
|
pData += sizeof(DWORD);
|
|
cData -= sizeof(DWORD);
|
|
|
|
if ((V_ARRAY(&vValue) = SafeArrayCreate(VT_BSTR, 1, &sabound)) != NULL)
|
|
{
|
|
BSTR *pStrings = (BSTR*) vValue.parray->pvData;
|
|
|
|
vValue.vt = VT_BSTR | VT_ARRAY;
|
|
|
|
for (DWORD i = 0; i < nStrings; i++)
|
|
{
|
|
if ( cData < sizeof(DWORD) )
|
|
break;
|
|
|
|
DWORD cLen = DWORD_ALIGNED(*(DWORD*)pData);
|
|
|
|
pData += sizeof(DWORD);
|
|
cData -= sizeof(DWORD);
|
|
|
|
if ( cLen > cData )
|
|
break;
|
|
|
|
pStrings[i] = SysAllocString((BSTR)pData);
|
|
|
|
if ( pStrings[i] == NULL )
|
|
break;
|
|
|
|
pData += cLen;
|
|
cData -= cLen;
|
|
}
|
|
|
|
if ( i != nStrings )
|
|
{
|
|
SafeArrayDestroy(V_ARRAY(&vValue));
|
|
return FALSE;
|
|
}
|
|
|
|
#ifndef NO_WINMGMT
|
|
HRESULT hr;
|
|
|
|
hr =
|
|
m_pObj->Put(
|
|
m_pProps[m_iCurrentVar].m_strName,
|
|
0,
|
|
&vValue,
|
|
0);
|
|
|
|
bRet = SUCCEEDED(hr);
|
|
|
|
if (!bRet)
|
|
bRet = TRUE;
|
|
#else
|
|
bRet = TRUE;
|
|
#endif
|
|
|
|
SafeArrayDestroy(V_ARRAY(&vValue));
|
|
}
|
|
else
|
|
bRet = FALSE;
|
|
|
|
return bRet;
|
|
}
|
|
|
|
BOOL CEventInfo::ProcessDWORD()
|
|
{
|
|
#ifndef NO_WINMGMT
|
|
return WriteDWORD(m_iCurrentVar, m_pdwPropTable[m_iCurrentVar]);
|
|
#else
|
|
|
|
//m_pBuffer->ReadDWORD();
|
|
|
|
return TRUE;
|
|
#endif
|
|
}
|
|
|
|
BOOL CEventInfo::ProcessBYTE()
|
|
{
|
|
BYTE cData = m_pdwPropTable[m_iCurrentVar];
|
|
|
|
#ifndef NO_WINMGMT
|
|
return WriteData(m_iCurrentVar, &cData, sizeof(cData));
|
|
#else
|
|
return TRUE;
|
|
#endif
|
|
}
|
|
|
|
BOOL CEventInfo::ProcessDWORD64()
|
|
{
|
|
DWORD cData;
|
|
DWORD64 *pdwData = (DWORD64*) GetPropDataPointer(m_iCurrentVar,cData);
|
|
if ( cData < sizeof(DWORD64) )
|
|
return FALSE;
|
|
|
|
#ifndef NO_WINMGMT
|
|
return WriteData(m_iCurrentVar, pdwData, sizeof(*pdwData));
|
|
#else
|
|
return TRUE;
|
|
#endif
|
|
}
|
|
|
|
BOOL CEventInfo::ProcessWORD()
|
|
{
|
|
WORD wData = m_pdwPropTable[m_iCurrentVar];
|
|
|
|
#ifndef NO_WINMGMT
|
|
return WriteData(m_iCurrentVar, &wData, sizeof(wData));
|
|
#else
|
|
return TRUE;
|
|
#endif
|
|
}
|
|
|
|
BOOL CEventInfo::ProcessScalarArray(DWORD dwItemSize)
|
|
{
|
|
DWORD cBits;
|
|
LPBYTE pBits = GetPropDataPointer(m_iCurrentVar,cBits);
|
|
BOOL bRet;
|
|
|
|
if ( cBits < sizeof(DWORD) )
|
|
return FALSE;
|
|
|
|
cBits -= sizeof(DWORD);
|
|
|
|
if ( cBits < (*(DWORD*)pBits) * dwItemSize )
|
|
return FALSE;
|
|
|
|
#ifndef NO_WINMGMT
|
|
bRet = WriteArrayData(m_iCurrentVar, pBits, dwItemSize);
|
|
#else
|
|
bRet = TRUE;
|
|
#endif
|
|
|
|
return bRet;
|
|
}
|
|
|
|
BOOL CEventInfo::ProcessArray1()
|
|
{
|
|
return ProcessScalarArray(1);
|
|
}
|
|
|
|
BOOL CEventInfo::ProcessArray2()
|
|
{
|
|
return ProcessScalarArray(2);
|
|
}
|
|
|
|
BOOL CEventInfo::ProcessArray4()
|
|
{
|
|
return ProcessScalarArray(4);
|
|
}
|
|
|
|
BOOL CEventInfo::ProcessArray8()
|
|
{
|
|
return ProcessScalarArray(8);
|
|
}
|
|
|
|
// Digs out an embedded object from the current buffer.
|
|
BOOL CEventInfo::GetEmbeddedObject(IUnknown **ppObj, LPBYTE pBits, DWORD cBits )
|
|
{
|
|
*ppObj = NULL;
|
|
CEventInfo* pEvent = new CEventInfo;
|
|
if ( pEvent == NULL )
|
|
return FALSE;
|
|
|
|
BOOL bRet = FALSE;
|
|
|
|
if ( cBits > sizeof(DWORD) )
|
|
{
|
|
DWORD dwSize = *(DWORD*)pBits;
|
|
cBits -= sizeof(DWORD);
|
|
|
|
if ( dwSize <= cBits )
|
|
{
|
|
CBuffer bufferObj( pBits+sizeof(DWORD),
|
|
dwSize,
|
|
CBuffer::ALIGN_NONE );
|
|
|
|
bRet =
|
|
pEvent->InitFromBuffer(m_pInfo, &bufferObj) &&
|
|
pEvent->SetPropsWithBuffer(&bufferObj);
|
|
}
|
|
}
|
|
|
|
if (bRet)
|
|
{
|
|
bRet =
|
|
SUCCEEDED(pEvent->m_pObj->QueryInterface(
|
|
IID_IUnknown, (LPVOID*) ppObj));
|
|
}
|
|
|
|
delete pEvent;
|
|
|
|
return bRet;
|
|
}
|
|
|
|
BOOL CEventInfo::ProcessObject()
|
|
{
|
|
_variant_t vObj;
|
|
BOOL bRet = FALSE;
|
|
LPBYTE pObjBegin = m_pBitsBase + m_pdwPropTable[m_iCurrentVar];
|
|
DWORD cObjBits = m_cBitsBase - m_pdwPropTable[m_iCurrentVar];
|
|
|
|
if (GetEmbeddedObject(&vObj.punkVal, pObjBegin, cObjBits))
|
|
{
|
|
vObj.vt = VT_UNKNOWN;
|
|
|
|
bRet =
|
|
SUCCEEDED(m_pObj->Put(
|
|
m_pProps[m_iCurrentVar].m_strName,
|
|
0,
|
|
&vObj,
|
|
0));
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
// Digs out an embedded object from the current buffer.
|
|
BOOL CEventInfo::GetWmiObject(_IWmiObject **ppObj, LPBYTE pBits, DWORD cBits )
|
|
{
|
|
if (m_pObjSpawner == NULL)
|
|
{
|
|
HRESULT hr;
|
|
|
|
hr =
|
|
m_pInfo->m_pProvider->m_pProv->GetNamespace()->GetObject(
|
|
CWbemBSTR( L"__NAMESPACE" ),
|
|
0,
|
|
NULL,
|
|
(IWbemClassObject**) (_IWmiObject**) &m_pObjSpawner,
|
|
NULL);
|
|
|
|
if (FAILED(hr))
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL bRet = FALSE;
|
|
_IWmiObject *pObjTemp = NULL;
|
|
|
|
if (SUCCEEDED(m_pObjSpawner->SpawnInstance(0, (IWbemClassObject**) &pObjTemp)))
|
|
{
|
|
if ( cBits >= sizeof(DWORD ) )
|
|
{
|
|
DWORD dwSize = *(DWORD*) pBits;
|
|
cBits -= sizeof(DWORD);
|
|
|
|
if ( dwSize <= cBits )
|
|
{
|
|
LPVOID pMem = CoTaskMemAlloc(dwSize);
|
|
|
|
if (pMem)
|
|
{
|
|
memcpy(pMem, pBits + sizeof(DWORD), dwSize);
|
|
if (SUCCEEDED(pObjTemp->SetObjectMemory(pMem, dwSize)))
|
|
{
|
|
*ppObj = pObjTemp;
|
|
|
|
bRet = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( !bRet )
|
|
pObjTemp->Release();
|
|
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
BOOL CEventInfo::ProcessWmiObject()
|
|
{
|
|
BOOL bRet;
|
|
LPBYTE pObjBegin = m_pBitsBase + m_pdwPropTable[m_iCurrentVar];
|
|
DWORD cObjBits = m_cBitsBase - m_pdwPropTable[m_iCurrentVar];
|
|
_IWmiObject *pObj = NULL;
|
|
|
|
if (GetWmiObject(&pObj, pObjBegin, cObjBits))
|
|
{
|
|
CProp &prop = m_pProps[m_iCurrentVar];
|
|
HRESULT hr;
|
|
|
|
hr =
|
|
m_pWmiObj->SetPropByHandle(
|
|
prop.m_lHandle,
|
|
0,
|
|
sizeof(_IWmiObject*),
|
|
&pObj);
|
|
|
|
pObj->Release();
|
|
|
|
bRet = SUCCEEDED(hr);
|
|
}
|
|
else
|
|
bRet = FALSE;
|
|
|
|
return bRet;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CEventInfoMap
|
|
|
|
CEventInfoMap::~CEventInfoMap()
|
|
{
|
|
while (m_mapNormalEvents.size())
|
|
{
|
|
CNormalInfoMapIterator item = m_mapNormalEvents.begin();
|
|
|
|
delete (*item).second;
|
|
|
|
m_mapNormalEvents.erase(item);
|
|
}
|
|
}
|
|
|
|
CEventInfo *CEventInfoMap::GetNormalEventInfo(DWORD dwIndex)
|
|
{
|
|
CEventInfo *pInfo;
|
|
CNormalInfoMapIterator item = m_mapNormalEvents.find(dwIndex);
|
|
|
|
if (item != m_mapNormalEvents.end())
|
|
pInfo = (*item).second;
|
|
else
|
|
pInfo = NULL;
|
|
|
|
return pInfo;
|
|
}
|
|
|
|
BOOL CEventInfoMap::AddNormalEventInfo(DWORD dwIndex, CEventInfo *pInfo)
|
|
{
|
|
m_mapNormalEvents[dwIndex] = pInfo;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
HRESULT CEventInfo::Indicate()
|
|
{
|
|
HRESULT hr;
|
|
hr = m_pSink->Indicate(1, &m_pObj);
|
|
return hr;
|
|
}
|
|
|