//*************************************************************************** // // File: // // Module: MS SNMP Provider // // Purpose: // // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved // //*************************************************************************** #include "precomp.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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 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; }