Leaked source code of windows server 2003
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.
 
 
 
 
 
 

828 lines
18 KiB

//***************************************************************************
//
// File:
//
// Module: MS SNMP Provider
//
// Purpose:
//
// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
//
//***************************************************************************
#include "precomp.h"
#include <provexpt.h>
#include <snmptempl.h>
#include <snmpmt.h>
#include <typeinfo.h>
#include <process.h>
#include <objbase.h>
#include <stdio.h>
#include <wbemidl.h>
#include <snmplog.h>
#include <snmpcl.h>
#include <snmpcont.h>
#include <snmptype.h>
#include <snmpauto.h>
#include <snmpevt.h>
#include <snmpthrd.h>
#include <snmpobj.h>
#include <smir.h>
#include <notify.h>
#include <evtdefs.h>
#include <evtthrd.h>
#include <evtmap.h>
#include <evtprov.h>
#include <evtreft.h>
extern CEventProviderWorkerThread* g_pWorkerThread ;
CReferentMapper::CReferentMapper()
{
}
CReferentMapper::~CReferentMapper()
{
}
HRESULT CReferentMapper::GetTypeAndIndexQuals(const wchar_t* prop, CIMTypeStruct& type, ULONG& index)
{
IWbemClassObject* propObj = NULL;
GetClassInstance(&propObj);
if (NULL == propObj)
{
return WBEM_E_FAILED;
}
IWbemQualifierSet* pQuals = NULL;
HRESULT result = propObj->GetPropertyQualifierSet((wchar_t*)prop, &pQuals);
if (FAILED(result))
{
return result;
}
VARIANT v;
result = pQuals->Get(EVENT_VBINDEX_QUAL, 0, &v, NULL);
if (FAILED(result))
{
pQuals->Release();
return result;
}
if (VT_I4 != v.vt)
{
VariantClear(&v);
return WBEM_E_FAILED;
}
index = v.lVal;
VariantClear(&v);
result = pQuals->Get(EVENT_CIMTYPE_QUAL, 0, &v, NULL);
pQuals->Release();
if (FAILED(result))
{
return result;
}
if (VT_BSTR != v.vt)
{
VariantClear(&v);
return WBEM_E_FAILED;
}
#ifdef WHITESPACE_IN_CIMTYPE
//Get rid of whitespace...
CString cimtype;
wchar_t* tmp = wcstok(v.bstrVal, WHITE_SPACE_CHARS);
while (NULL != tmp)
{
cimtype += tmp;
tmp = wcstok(NULL, WHITE_SPACE_CHARS);
}
#else //WHITESPACE_IN_CIMTYPE
CString cimtype = v.bstrVal;
#endif //WHITESPACE_IN_CIMTYPE
VariantClear(&v);
//determine if we're an object. If so get the classname...
CString temp = cimtype.Left(OBJECT_STR_LEN);
temp.MakeLower();
if (temp == OBJECT_STR)
{
type.strType = cimtype.Mid(OBJECT_STR_LEN, cimtype.GetLength());
type.fObject = TRUE;
}
else
{
type.fObject = FALSE;
}
return WBEM_NO_ERROR;
}
HRESULT CReferentMapper::GetSpecificPropertyValue(long lNumElements, MYWBEM_NAME_ELEMENT *aElements,
long lFlags, VARIANT *pvValue)
{
if ((lNumElements <= 0) || (NULL == aElements) || (NULL == pvValue))
{
DebugMacro9(
SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine (
__FILE__,__LINE__,
L"CReferentMapper::GetSpecificPropertyValue invalid parms\r\n");
)
return WBEM_E_INVALID_PARAMETER;
}
HRESULT status = WBEM_E_FAILED;
//specific properties after first two varbinds
if ((0 == aElements[0].m_nType) && (m_vbs.length > 2))
{
//first check it has the correct VBIndex and CIMType qualifiers...
CIMTypeStruct proptype;
ULONG propvbindex;
if (FAILED(GetTypeAndIndexQuals(aElements[0].Element.m_wszPropertyName,
proptype, propvbindex)))
{
DebugMacro9(
SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine (
__FILE__,__LINE__,
L"CReferentMapper::GetSpecificPropertyValue failed to get index quals\r\n");
)
return status;
}
if (propvbindex >= m_vbs.length)
{
DebugMacro9(
SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine (
__FILE__,__LINE__,
L"CReferentMapper::GetSpecificPropertyValue invalid index return TRUE\r\n");
)
return WBEM_NO_ERROR;
}
//we're zero indexed in this world!
propvbindex--;
if (lNumElements == 1)
{
if (m_vbs.vbs[propvbindex].fDone)
{
//we've done this one already,
//just get the property value and return it...
DebugMacro9(
SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine (
__FILE__,__LINE__,
L"CReferentMapper::GetSpecificPropertyValue return value\r\n");
)
return m_object->Get(aElements[0].Element.m_wszPropertyName, 0, pvValue, 0, 0);
}
if (proptype.fObject)
{
//get the embedded class object in full for the property asked for
IWbemClassObject* pObj = NULL;
if (SUCCEEDED(CreateEmbeddedProperty(&pObj, propvbindex,
aElements[0].Element.m_wszPropertyName, proptype.strType)))
{
//created the property, set the variant value and return successfully
//NOTE: as soon as the variant is cleared, the object will be released
pvValue->vt = VT_UNKNOWN;
pvValue->punkVal = pObj;
}
DebugMacro9(
SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine (
__FILE__,__LINE__,
L"CReferentMapper::GetSpecificPropertyValue return value\r\n");
)
return WBEM_NO_ERROR;
}
else
{
//MUST be an embedded property otherwise fail!
DebugMacro9(
SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine (
__FILE__,__LINE__,
L"CReferentMapper::GetSpecificPropertyValue invlaid params\r\n");
)
return WBEM_E_FAILED;
}
}
#ifdef FILTERING
will not compile as there are still a couple of TO DOs left undone...
else if (0 == aElements[1].m_nType)
{
if (lNumElements == 2)
{
//TO DO:
//======
//get a single property value of the embedded object
}
else if ((lNumElements == 3) && (1 == aElements[1].m_nType))
{
//TO DO:
//======
//only if we're an array property of the embedded object
}
}
#endif //FILTERING
}
return status;
}
HRESULT CReferentMapper::CreateEmbeddedProperty(IWbemClassObject** ppObj,
ULONG index,
const wchar_t* propertyName,
const wchar_t* className)
{
if (NULL == ppObj)
{
//invalid out parameter
DebugMacro9(
SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine (
__FILE__,__LINE__,
L"CReferentMapper::CreateEmbeddedProperty invalid parameter\r\n");
)
return WBEM_E_INVALID_PARAMETER;
}
IWbemClassObject* pClass = NULL;
//specify no correlation to the class provider
IWbemContext *pCtx = NULL;
HRESULT result = CoCreateInstance(CLSID_WbemContext, NULL,
CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
IID_IWbemContext, (void**)&pCtx);
if (SUCCEEDED(result))
{
VARIANT vCtx;
VariantInit (&vCtx);
vCtx.vt = VT_BOOL;
vCtx.boolVal = VARIANT_FALSE;
result = pCtx->SetValue(WBEM_CLASS_CORRELATE_CONTEXT_PROP, 0, &vCtx);
VariantClear(&vCtx);
if (FAILED(result))
{
pCtx->Release();
pCtx = NULL;
}
}
else
{
pCtx = NULL;
}
BSTR t_className = SysAllocString(className);
result = m_nspace->GetObject(t_className, pCtx, &pClass);
SysFreeString(t_className);
if (pCtx != NULL)
{
pCtx->Release();
}
if (FAILED(result))
{
return result;
}
result = pClass->SpawnInstance(0, ppObj);
if (FAILED(result))
{
pClass->Release();
return result;
}
//set the varbind as decoded and make sure the notification instance has been created...
IWbemClassObject* ptmpObj = NULL;
GetClassInstance(&ptmpObj);
if (NULL == m_object)
{
pClass->Release();
return WBEM_E_FAILED;
}
m_vbs.vbs[index].fDone = TRUE;
WbemSnmpClassObject snmpObj;
WbemSnmpErrorObject errorObj;
if (!snmpObj.Set(errorObj, pClass, FALSE))
{
pClass->Release();
(*ppObj)->Release();
*ppObj = NULL;
return WBEM_E_FAILED;
}
snmpObj.SetIsClass(FALSE);
snmpObj.ResetProperty () ;
WbemSnmpProperty *snmpProp = snmpObj.NextProperty ();
//set all properties to NULL...
while (snmpProp != NULL)
{
snmpProp->SetValue(*ppObj, (SnmpValue*)NULL);
snmpProp = snmpObj.NextProperty ();
}
snmpProp = snmpObj.FindProperty((wchar_t*)propertyName);
if (NULL == snmpProp)
{
pClass->Release();
(*ppObj)->Release();
*ppObj = NULL;
return WBEM_E_FAILED;
}
BOOL bSetKeyValue = FALSE;
if (!snmpProp->SetValue(&(m_vbs.vbs[index].pVarBind->GetValue())))
{
snmpProp->AddQualifier ( WBEM_QUALIFIER_TYPE_MISMATCH ) ;
WbemSnmpQualifier *qualifier = snmpProp->FindQualifier ( WBEM_QUALIFIER_TYPE_MISMATCH ) ;
if ( qualifier )
{
VARIANT tmp_V;
VariantInit(&tmp_V);
tmp_V.vt = VT_BOOL;
tmp_V.boolVal = VARIANT_TRUE;
qualifier->SetValue(tmp_V);
VariantClear(&tmp_V);
}
}
else
{
WbemSnmpQualifier *qualifier = snmpProp->FindQualifier ( WBEM_QUALIFIER_KEY ) ;
if ( qualifier )
{
VARIANT tmp_V;
VariantInit(&tmp_V);
if (qualifier->GetValue(tmp_V))
{
if ((VT_BOOL == tmp_V.vt) && (VARIANT_TRUE == tmp_V.boolVal))
{
bSetKeyValue = TRUE;
}
}
VariantClear(&tmp_V);
}
}
//have set the property, now set the key properties...
//first get the instance info...
const SnmpObjectIdentifier& id = m_vbs.vbs[index].pVarBind->GetInstance();
IWbemQualifierSet* pQuals = NULL;
result = pClass->GetPropertyQualifierSet((wchar_t*)propertyName, &pQuals);
if (FAILED(result))
{
pClass->Release();
(*ppObj)->Release();
*ppObj = NULL;
return WBEM_E_FAILED;
}
VARIANT v;
result = pQuals->Get(OID_ATTRIBUTE, 0, &v, NULL);
pQuals->Release();
if ((FAILED(result)) || (VT_BSTR != v.vt))
{
pClass->Release();
VariantClear(&v);
(*ppObj)->Release();
*ppObj = NULL;
return WBEM_E_FAILED;
}
SnmpObjectIdentifierType propoidtype(v.bstrVal);
VariantClear(&v);
if (!propoidtype.IsValid())
{
pClass->Release();
(*ppObj)->Release();
*ppObj = NULL;
return WBEM_E_FAILED;
}
SnmpObjectIdentifier propoid(propoidtype.GetValue(), propoidtype.GetValueLength());
SnmpObjectIdentifier* prefix = id.Cut(propoid);
BOOL fsuccess = FALSE;
SnmpObjectIdentifier* instinfo = new SnmpObjectIdentifier ( NULL , 0 ) ;
if ((prefix != NULL) && (*prefix == propoid))
{
fsuccess = id.Suffix(propoid.GetValueLength(),*instinfo);
if (instinfo->GetValue() == NULL)
{
fsuccess = FALSE;
snmpProp->AddQualifier ( WBEM_QUALIFIER_TYPE_MISMATCH ) ;
WbemSnmpQualifier *qualifier = snmpProp->FindQualifier ( WBEM_QUALIFIER_TYPE_MISMATCH ) ;
if ( qualifier )
{
VARIANT tmp_V;
VariantInit(&tmp_V);
tmp_V.vt = VT_BOOL;
tmp_V.boolVal = VARIANT_TRUE;
qualifier->SetValue(tmp_V);
VariantClear(&tmp_V);
}
}
}
if (prefix != NULL)
{
delete prefix;
}
if ( fsuccess )
{
if (snmpObj.IsKeyed())
{
snmpObj.ResetKeyProperty() ;
while ( fsuccess && (snmpProp = snmpObj.NextKeyProperty()) )
{
//set all the key properties using the instance info...
SnmpInstanceType *decodeValue = snmpProp->GetValue()->Copy();
SnmpObjectIdentifier t_DecodedValue = decodeValue->Decode(*instinfo) ;
SnmpObjectIdentifier *decodedObject = new SnmpObjectIdentifier( t_DecodedValue ) ;
if (*decodeValue)
{
if (!snmpProp->SetValue(decodeValue))
{
fsuccess = FALSE;
}
}
else
{
fsuccess = FALSE;
}
delete decodeValue ;
delete instinfo ;
instinfo = decodedObject ;
snmpProp = snmpObj.NextKeyProperty();
}
if (fsuccess && instinfo->GetValueLength())
{
//instance info left after keys have been set
fsuccess = FALSE;
}
}
else
{
if ( (0 != *(instinfo->GetValue())) || (1 != instinfo->GetValueLength()) )
{
//invalid instance info for scalar...
fsuccess = FALSE;
}
}
}
delete instinfo;
pClass->Release();
if (!fsuccess)
{
snmpObj.ResetKeyProperty () ;
VARIANT tmp_V;
VariantInit(&tmp_V);
tmp_V.vt = VT_BOOL;
tmp_V.boolVal = VARIANT_TRUE;
while ( snmpProp = snmpObj.NextKeyProperty () )
{
WbemSnmpQualifier *qualifier = NULL ;
snmpProp->AddQualifier ( WBEM_QUALIFIER_TYPE_MISMATCH ) ;
if ( qualifier = snmpProp->FindQualifier ( WBEM_QUALIFIER_TYPE_MISMATCH ) )
{
qualifier->SetValue(tmp_V);
}
else
{
// Problem Here
}
}
if (snmpProp = snmpObj.FindProperty((wchar_t*)propertyName))
{
WbemSnmpQualifier *qualifier = NULL ;
snmpProp->AddQualifier ( WBEM_QUALIFIER_TYPE_MISMATCH ) ;
if ( qualifier = snmpProp->FindQualifier ( WBEM_QUALIFIER_TYPE_MISMATCH ) )
{
qualifier->SetValue(tmp_V);
}
else
{
// Problem Here
}
}
VariantClear(&tmp_V);
}
//check that setting the key values hasn't altered our value, it may be a key
if ( bSetKeyValue && (snmpProp = snmpObj.FindProperty((wchar_t*)propertyName)) )
{
if (*(snmpProp->GetValue()->GetValueEncoding()) != m_vbs.vbs[index].pVarBind->GetValue())
{
//set it back to the varbind value and set the error qualifier on the property
snmpProp->SetValue(&(m_vbs.vbs[index].pVarBind->GetValue()));
WbemSnmpQualifier *qualifier = NULL ;
snmpProp->AddQualifier ( WBEM_QUALIFIER_VALUE_MISMATCH ) ;
if ( qualifier = snmpProp->FindQualifier ( WBEM_QUALIFIER_VALUE_MISMATCH ) )
{
VARIANT tmp_V;
VariantInit(&tmp_V);
tmp_V.vt = VT_BOOL;
tmp_V.boolVal = VARIANT_TRUE;
qualifier->SetValue(tmp_V);
VariantClear(&tmp_V);
}
else
{
// Problem Here
}
}
}
//generate class object from snmpObj and return success
if (snmpObj.Get(errorObj, *ppObj))
{
//add the property to the notification object...
VARIANT vObj;
vObj.vt = VT_UNKNOWN;
vObj.punkVal = *ppObj;
(*ppObj)->AddRef();
result = m_object->Put((wchar_t*)propertyName, 0, &vObj, 0);
if (SUCCEEDED(result))
{
VariantClear(&vObj);
DebugMacro9(
SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine (
__FILE__,__LINE__,
L"CReferentMapper::CreateEmbeddedProperty succeeded\r\n");
)
return WBEM_NO_ERROR;
}
else
{
VariantClear(&vObj);
(*ppObj)->Release();
*ppObj = NULL;
return WBEM_E_FAILED;
}
}
return WBEM_E_FAILED;
}
void CReferentMapper::GenerateInstance(IWbemClassObject** ppInst)
{
if (NULL == ppInst)
{
DebugMacro9(
SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine (
__FILE__,__LINE__,
L"CReferentMapper::GenerateInstance invalid parameter\r\n");
)
//invalid out parameter
return;
}
//set out parameter to NULL;
*ppInst = NULL;
IWbemClassObject *pObj = NULL;
GetClassInstance(&pObj);
if (NULL == pObj)
{
//failed to get class instance
DebugMacro9(
SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine (
__FILE__,__LINE__,
L"CReferentMapper::GenerateInstance failed to get class defn\r\n");
)
return;
}
//get all the property names and set their values...
SAFEARRAY* pPropNames;
HRESULT result = pObj->GetNames(NULL, WBEM_FLAG_NONSYSTEM_ONLY, NULL, &pPropNames);
if (FAILED(result))
{
//failed to get the property names
DebugMacro9(
SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine (
__FILE__,__LINE__,
L"CReferentMapper::GenerateInstance failed to get property array\r\n");
)
return;
}
//time to <insert expletive> around with a safearray...
//work out the size of the safearray and access the data
if(SafeArrayGetDim(pPropNames) != 1)
{
//wrong dimensions in this array
SafeArrayDestroy(pPropNames);
DebugMacro9(
SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine (
__FILE__,__LINE__,
L"CReferentMapper::GenerateInstance property array has wrong DIM\r\n");
)
return;
}
LONG arraylen = pPropNames->rgsabound[0].cElements;
BSTR *pbstr;
result = SafeArrayAccessData(pPropNames, (void **)&pbstr);
if(FAILED(result))
{
SafeArrayDestroy(pPropNames);
DebugMacro9(
SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine (
__FILE__,__LINE__,
L"CReferentMapper::GenerateInstance failed to access property array\r\n");
)
return;
}
DebugMacro9(
SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine (
__FILE__,__LINE__,
L"CReferentMapper::GenerateInstance set properties\r\n");
)
BOOL t_bSetProp = FALSE;
//iterate through the names and set the properties...
for (LONG i = 0; i < arraylen; i++)
{
VARIANT v;
MYWBEM_NAME_ELEMENT property_struct;
property_struct.m_nType = 0; //string value
property_struct.Element.m_wszPropertyName = pbstr[i];
result = GetPropertyValue(1, &property_struct, 0, &v);
if (FAILED(result))
{
DebugMacro9(
SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine (
__FILE__,__LINE__,
L"CReferentMapper::GenerateInstance failed to get value for %s\r\n",
pbstr[i]);
)
continue;
}
else
{
t_bSetProp = TRUE;
}
if ((v.vt != VT_NULL) && (v.vt != VT_EMPTY))
{
DebugMacro9(
SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine (
__FILE__,__LINE__,
L"CReferentMapper::GenerateInstance setting value for %s\r\n",
pbstr[i]);
)
result = pObj->Put(pbstr[i], 0, &v, 0);
DebugMacro9(
if (FAILED(result))
{
SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine (
__FILE__,__LINE__,
L"CReferentMapper::GenerateInstance failed setting value for %s\r\n",
pbstr[i]);
}
)
}
VariantClear(&v);
}
SafeArrayUnaccessData(pPropNames);
SafeArrayDestroy(pPropNames);
//if a single property has been put send it on....
if (t_bSetProp)
{
pObj->AddRef();
*ppInst = pObj;
}
DebugMacro9(
SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine (
__FILE__,__LINE__,
L"CReferentMapper::GenerateInstance finished\r\n");
)
}
void CReferentMapper::ResetData()
{
//do class specific stuff then call parent class's reset
CMapToEvent::ResetData();
}
BOOL CReferentMapper::GetSpecificClass()
{
//Build path of mapper instance...
CString path(EXTMAPPER_CLASS_PATH_PREFIX);
path += m_oid;
path += '\"';
BSTR pathstr = path.AllocSysString();
IWbemClassObject *pObj = NULL;
HRESULT result = g_pWorkerThread->GetServerWrap ()->GetMapperObject(pathstr, NULL, & pObj );
SysFreeString(pathstr);
if (result == S_OK)
{
VARIANT v;
VariantInit(&v);
result = pObj->Get(MAPPER_CLASS_EVENTCLASSPROP, 0, &v, NULL, NULL);
pObj->Release();
if (SUCCEEDED(result) && (VT_BSTR == v.vt))
{
m_class = v.bstrVal;
VariantClear(&v);
DebugMacro9(
SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine (
__FILE__,__LINE__,
L"CReferentMapper::GetSpecificClass got the specific class defn\r\n");
)
return TRUE;
}
else
{
VariantClear(&v);
}
}
DebugMacro9(
SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine (
__FILE__,__LINE__,
L"CReferentMapper::GetSpecificClass failed to get specific class defn\r\n");
)
return FALSE;
}