// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved #include "precomp.h" #include #include #include #include #include #include #include #include #include "classfac.h" #include "guids.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "propprov.h" #include "propsnmp.h" #include "propinst.h" #include "propquery.h" #include "snmpnext.h" BOOL DecrementObjectIdentifier ( SnmpObjectIdentifier &a_Object , SnmpObjectIdentifier &a_DecrementedObject ) { BOOL t_Status = TRUE ; ULONG t_ObjectLength = a_Object.GetValueLength () ; ULONG *t_ObjectValue = a_Object.GetValue () ; ULONG *t_DecrementedValue = new ULONG [ t_ObjectLength ] ; BOOL t_Decrement = TRUE ; for ( ULONG t_Index = t_ObjectLength ; t_Index > 0 ; t_Index -- ) { ULONG t_Component = t_ObjectValue [ t_Index - 1 ] ; if ( t_Decrement ) { if ( t_Component == 0 ) { t_Component -- ; } else { t_Decrement = FALSE ; t_Component -- ; } } t_DecrementedValue [ t_Index - 1 ] = t_Component ; } a_DecrementedObject.SetValue ( t_DecrementedValue , t_ObjectLength ) ; delete [] t_DecrementedValue; t_Status = t_Decrement == FALSE ; return t_Status ; } BOOL IncrementObjectIdentifier ( SnmpObjectIdentifier &a_Object , SnmpObjectIdentifier &a_IncrementedObject ) { BOOL t_Status = TRUE ; ULONG t_ObjectLength = a_Object.GetValueLength () ; ULONG *t_ObjectValue = a_Object.GetValue () ; ULONG *t_IncrementedValue = new ULONG [ t_ObjectLength ] ; BOOL t_Increment = TRUE ; for ( ULONG t_Index = t_ObjectLength ; t_Index > 0 ; t_Index -- ) { ULONG t_Component = t_ObjectValue [ t_Index - 1 ] ; if ( t_Increment ) { if ( t_Component == 0xFFFFFFFF ) { t_Component ++ ; } else { t_Component ++ ; t_Increment = FALSE ; } } t_IncrementedValue [ t_Index - 1 ] = t_Component ; } a_IncrementedObject.SetValue ( t_IncrementedValue , t_ObjectLength ) ; delete [] t_IncrementedValue; t_Status = t_Increment == FALSE ; return t_Status ; } AutoRetrieveOperation :: AutoRetrieveOperation ( IN SnmpSession &sessionArg , IN SnmpInstanceResponseEventObject *eventObjectArg ) : SnmpAutoRetrieveOperation ( sessionArg ) , session ( &sessionArg ) , eventObject ( eventObjectArg ) , varBindsReceived ( 0 ) , erroredVarBindsReceived ( 0 ) , rowVarBindsReceived ( 0 ) , rowsReceived ( 0 ) , snmpObject ( NULL ) , virtuals ( FALSE ) , virtualsInitialised ( FALSE ) , m_PropertyContainer ( NULL ) , m_PropertyContainerLength ( 0 ) { } AutoRetrieveOperation :: ~AutoRetrieveOperation () { if ( snmpObject ) { snmpObject->Release () ; snmpObject = NULL; } delete [] m_PropertyContainer ; session->DestroySession () ; } void AutoRetrieveOperation :: ReceiveResponse () { // Inform creator all is done eventObject->ReceiveComplete () ; } void AutoRetrieveOperation :: ReceiveRowResponse () { // Receive of Row is not complete rowsReceived ++ ; // Inform Creator row has been received if ( snmpObject ) { eventObject->ReceiveRow ( snmpObject ) ; snmpObject->Release () ; snmpObject = NULL; } // Insert new Object Identifier / Property Hash entries for newly created object IWbemClassObject *t_ClassObject = eventObject->GetInstanceObject () ; HRESULT t_Result = t_ClassObject->Clone ( & snmpObject ) ; if ( SUCCEEDED ( t_Result ) ) { SnmpInstanceClassObject *t_SnmpObject = ( SnmpInstanceClassObject * ) eventObject->GetSnmpClassObject () ; WbemSnmpProperty *property ; t_SnmpObject->ResetProperty () ; while ( property = t_SnmpObject->NextProperty () ) { /* * Initialise value to NULL */ property->SetValue ( snmpObject , ( SnmpValue * ) NULL ) ; } } else { // Problem Here if ( t_Result == WBEM_E_OUT_OF_MEMORY ) { throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR) ; } } virtualsInitialised = FALSE ; } void AutoRetrieveOperation :: ReceiveRowVarBindResponse ( IN const ULONG &var_bind_index, IN const SnmpVarBind &requestVarBind , IN const SnmpVarBind &replyVarBind , IN const SnmpErrorReport &error ) { rowVarBindsReceived ++ ; // Set Variable Binding Value for property WbemSnmpProperty *property = m_PropertyContainer [ var_bind_index - 1 ].m_Property ; SnmpValue &value = replyVarBind.GetValue () ; if ( property->SetValue ( snmpObject , &value , SetValueRegardlessReturnCheck ) ) { // Set worked } else { // Type Mismatch property->AddQualifier ( WBEM_QUALIFIER_TYPE_MISMATCH ) ; WbemSnmpQualifier *qualifier = property->FindQualifier ( WBEM_QUALIFIER_TYPE_MISMATCH ) ; if ( qualifier ) { if ( snmpObject ) { IWbemQualifierSet *t_QualifierSet = NULL; HRESULT result = snmpObject->GetPropertyQualifierSet ( property->GetName () , & t_QualifierSet ) ; if ( SUCCEEDED ( result ) ) { SnmpIntegerType integer ( 1 , NULL ) ; qualifier->SetValue ( t_QualifierSet , integer ) ; } if ( t_QualifierSet ) { t_QualifierSet->Release () ; t_QualifierSet = NULL; } } } } if ( virtuals && virtualsInitialised == FALSE ) //if ( virtualsInitialised == FALSE ) { // Get Phantom Key properties from first Variable Binding of Row BOOL status = TRUE ; SnmpObjectIdentifier decodeObject = replyVarBind.GetInstance () ; SnmpInstanceClassObject *t_SnmpObject = ( SnmpInstanceClassObject * ) eventObject->GetSnmpClassObject () ; WbemSnmpProperty *property ; t_SnmpObject->ResetKeyProperty () ; while ( status && ( property = t_SnmpObject->NextKeyProperty () ) ) { // For each Phantom Key in Key Order consume instance information SnmpInstanceType *decodeValue = property->GetValue () ; decodeObject = decodeValue->Decode ( decodeObject ) ; if ( *decodeValue ) { // Decode worked correctly const SnmpValue *value = decodeValue->GetValueEncoding () ; // Set Property value for Key property->SetValue ( snmpObject , value , SetValueRegardlessReturnCheck ) ; } else { // Decode Error therefore set TYPE MISMATCH for all Phantom keys WbemSnmpProperty *property ; t_SnmpObject->ResetKeyProperty () ; while ( property = t_SnmpObject->NextKeyProperty () ) { WbemSnmpQualifier *qualifier = NULL ; property->AddQualifier ( WBEM_QUALIFIER_TYPE_MISMATCH ) ; if ( qualifier = property->FindQualifier ( WBEM_QUALIFIER_TYPE_MISMATCH ) ) { // Property which is a phantom key could not be decoded correctly. if ( snmpObject ) { IWbemQualifierSet *t_QualifierSet = NULL; HRESULT result = snmpObject->GetPropertyQualifierSet ( property->GetName () , & t_QualifierSet ) ; if ( SUCCEEDED ( result ) ) { SnmpIntegerType integer ( 1 , NULL ) ; qualifier->SetValue ( t_QualifierSet , integer ) ; } if ( t_QualifierSet ) { t_QualifierSet->Release () ; t_QualifierSet = NULL; } } } else { // Problem Here } } status = FALSE ; } } // Check we have consumed all instance information if ( decodeObject.GetValueLength () ) { // Decode Error therefore set TYPE MISMATCH for all Phantom keys WbemSnmpProperty *property ; t_SnmpObject->ResetKeyProperty () ; while ( property = t_SnmpObject->NextKeyProperty () ) { WbemSnmpQualifier *qualifier = NULL ; property->AddQualifier ( WBEM_QUALIFIER_TYPE_MISMATCH ) ; if ( qualifier = property->FindQualifier ( WBEM_QUALIFIER_TYPE_MISMATCH ) ) { // Property which is a phantom key could not be decoded correctly. if ( snmpObject ) { IWbemQualifierSet *t_QualifierSet = NULL; HRESULT result = snmpObject->GetPropertyQualifierSet ( property->GetName () , & t_QualifierSet ) ; if ( SUCCEEDED ( result ) ) { SnmpIntegerType integer ( 1 , NULL ) ; qualifier->SetValue ( t_QualifierSet , integer ) ; } if ( t_QualifierSet ) { t_QualifierSet->Release () ; t_QualifierSet = NULL; } } } else { // Problem Here } } } // No need to set Phantom keys for further columns of row virtualsInitialised = TRUE ; } } void AutoRetrieveOperation :: ReceiveVarBindResponse ( IN const ULONG &var_bind_index, IN const SnmpVarBind &requestVarBind , IN const SnmpVarBind &replyVarBind , IN const SnmpErrorReport &error ) { varBindsReceived ++ ; } #pragma warning (disable:4065) void AutoRetrieveOperation :: ReceiveErroredVarBindResponse( IN const ULONG &var_bind_index, IN const SnmpVarBind &requestVarBind , IN const SnmpErrorReport &error ) { erroredVarBindsReceived ++ ; switch ( error.GetError () ) { case Snmp_Error: { switch ( error.GetStatus () ) { case Snmp_No_Response: { eventObject->GetErrorObject ().SetStatus ( WBEM_SNMP_E_TRANSPORT_NO_RESPONSE ) ; eventObject->GetErrorObject ().SetWbemStatus ( WBEM_E_FAILED ) ; eventObject->GetErrorObject ().SetMessage ( L"No Response from device" ) ; } break; case Snmp_No_Such_Name: { // End of MIB tree. } break ; default: { eventObject->GetErrorObject ().SetStatus ( WBEM_SNMP_E_TRANSPORT_ERROR ) ; eventObject->GetErrorObject ().SetWbemStatus ( WBEM_E_FAILED ) ; eventObject->GetErrorObject ().SetMessage ( L"Unknown transport failure" ) ; } break ; } } break ; case Snmp_Transport: { switch ( error.GetStatus () ) { default: { eventObject->GetErrorObject ().SetStatus ( WBEM_SNMP_E_TRANSPORT_ERROR ) ; eventObject->GetErrorObject ().SetWbemStatus ( WBEM_E_FAILED ) ; eventObject->GetErrorObject ().SetMessage ( L"Unknown transport failure" ) ; } break ; } } break ; default: { // Cannot Happen } break ; } erroredVarBindsReceived ++ ; } #pragma warning (default:4065) void AutoRetrieveOperation :: FrameTooBig () { } void AutoRetrieveOperation :: FrameOverRun () { } void AutoRetrieveOperation :: Send () { // Send Variable Bindings for requested properties SnmpNull snmpNull ; SnmpVarBindList varBindList ; SnmpVarBindList startVarBindList ; // Create class object for subsequent receipt of response IWbemClassObject *t_ClassObject = eventObject->GetInstanceObject () ; HRESULT t_Result = t_ClassObject->Clone ( & snmpObject ) ; if ( SUCCEEDED ( t_Result ) ) { SnmpInstanceClassObject *t_SnmpObject = ( SnmpInstanceClassObject * ) eventObject->GetSnmpClassObject () ; SnmpInstanceClassObject *t_RequestSnmpObject = ( SnmpInstanceClassObject * ) eventObject->GetSnmpRequestClassObject () ; // Check for properties which are phantom virtualsInitialised = FALSE ; virtuals = FALSE ; WbemSnmpProperty *property ; t_SnmpObject->ResetKeyProperty () ; while ( property = t_SnmpObject->NextKeyProperty () ) { if ( property->IsVirtualKey () ) { // There are some properties which are phantom virtuals = TRUE ; } if ( ! t_RequestSnmpObject->FindProperty ( property->GetName () ) ) { virtuals = TRUE ; } } t_SnmpObject->ResetProperty () ; while ( property = t_SnmpObject->NextProperty () ) { if ( property->IsReadable () ) { BOOL t_Status = ( t_SnmpObject->GetSnmpVersion () == 1 ) && ( property->IsSNMPV1Type () ) ; t_Status = t_Status || ( ( t_SnmpObject->GetSnmpVersion () == 2 ) && ( property->IsSNMPV2CType () ) ) ; if ( t_Status ) { if ( property->IsVirtualKey () == FALSE ) { m_PropertyContainerLength ++ ; } } } } m_PropertyContainer = new PropertyDefinition [ m_PropertyContainerLength ] ; // Add Variable binding to Variable binding list // Insert new Object Identifier / Property Hash entries for newly created object ULONG t_Index = 0 ; t_RequestSnmpObject->ResetProperty () ; while ( property = t_RequestSnmpObject->NextProperty () ) { if ( property->IsReadable () ) { BOOL t_Status = ( t_RequestSnmpObject->GetSnmpVersion () == 1 ) && ( property->IsSNMPV1Type () ) ; t_Status = t_Status || ( ( t_RequestSnmpObject->GetSnmpVersion () == 2 ) && ( property->IsSNMPV2CType () ) ) ; if ( t_Status ) { if ( property->IsVirtualKey () == FALSE ) { WbemSnmpQualifier *qualifier = property->FindQualifier ( WBEM_QUALIFIER_OBJECT_IDENTIFIER ) ; if ( qualifier ) { SnmpInstanceType *value = qualifier->GetValue () ; if ( typeid ( *value ) == typeid ( SnmpObjectIdentifierType ) ) { SnmpObjectIdentifier t_CurrentIdentifier ( 0 , NULL ) ; SnmpObjectIdentifier t_StartIdentifier ( 0 , NULL ) ; LONG t_Scoped = EvaluateInitialVarBind ( t_Index , t_CurrentIdentifier , t_StartIdentifier ) ; m_PropertyContainer [ t_Index ].m_Property = property ; SnmpObjectIdentifierType requestIdentifierType ( * ( SnmpObjectIdentifierType * ) value ) ; SnmpObjectIdentifier t_RequestIdentifier = * ( SnmpObjectIdentifier * ) requestIdentifierType.GetValueEncoding () ; SnmpVarBind t_VarBind ( t_RequestIdentifier , snmpNull ) ; varBindList.Add ( t_VarBind ) ; if ( t_Scoped > 0 ) { t_RequestIdentifier = t_RequestIdentifier + t_StartIdentifier ; } // Add Variable binding to list SnmpVarBind t_StartVarBind ( t_RequestIdentifier , snmpNull ) ; startVarBindList.Add ( t_StartVarBind ) ; t_Index ++ ; } } } else { // Don't Send properties marked as virtual key } } } /* * Initialise value to NULL */ property->SetValue ( snmpObject , ( SnmpValue * ) NULL ) ; } // Finally Send request SendRequest ( varBindList , startVarBindList ) ; } else { } } LONG AutoRetrieveOperation :: EvaluateNextRequest ( IN const ULONG &var_bind_index, IN const SnmpVarBind &requestVarBind , IN const SnmpVarBind &replyVarBind , IN SnmpVarBind &sendVarBind ) { LONG t_Evaluation = 0 ; PartitionSet *t_Partition = eventObject->GetPartitionSet () ; if ( t_Partition ) { BOOL t_Status = TRUE ; SnmpInstanceClassObject *t_SnmpObject = ( SnmpInstanceClassObject * ) eventObject->GetSnmpClassObject () ; ULONG t_KeyCount = t_SnmpObject->GetKeyPropertyCount () ; SnmpObjectIdentifier t_DecodeObject = replyVarBind.GetInstance () ; ULONG t_Index = 0 ; WbemSnmpProperty *t_Property ; t_SnmpObject->ResetKeyProperty () ; while ( t_Status && ( t_Property = t_SnmpObject->NextKeyProperty () ) ) { // For each Key in Key Order consume instance information SnmpInstanceType *t_DecodeValue = t_Property->GetValue () ; t_DecodeObject = t_DecodeValue->Decode ( t_DecodeObject ) ; SnmpObjectIdentifier t_Encode ( 0 , NULL ) ; t_Encode = t_DecodeValue->Encode ( t_Encode ) ; m_PropertyContainer [ var_bind_index - 1 ].m_ObjectIdentifierComponent [ t_Index + 1 ] = ( SnmpObjectIdentifier * ) t_Encode.Copy () ; t_Index ++ ; } SnmpObjectIdentifier t_AdvanceObjectIdentifier ( 0 , NULL ) ; t_Evaluation = EvaluateResponse ( var_bind_index - 1 , t_KeyCount , t_AdvanceObjectIdentifier ) ; if ( t_Evaluation > 0 ) { SnmpNull t_SnmpNull ; SnmpVarBind t_VarBind ( t_AdvanceObjectIdentifier , t_SnmpNull ) ; sendVarBind = t_VarBind ; } for ( t_Index = 0 ; t_Index < m_PropertyContainer [ var_bind_index - 1 ].m_KeyCount ; t_Index ++ ) { delete m_PropertyContainer [ var_bind_index - 1 ].m_ObjectIdentifierComponent [ t_Index + 1 ] ; m_PropertyContainer [ var_bind_index - 1 ].m_ObjectIdentifierComponent [ t_Index + 1 ] = NULL ; } } return t_Evaluation ; } LONG AutoRetrieveOperation :: EvaluateResponse ( IN ULONG a_PropertyIndex , IN ULONG &a_CurrentIndex , IN SnmpObjectIdentifier &a_AdvanceObjectIdentifier ) { LONG t_Evaluation = 0 ; BOOL t_UseStartAsAdvance = FALSE ; for ( ULONG t_Index = 0 ; t_Index < m_PropertyContainer [ a_PropertyIndex ].m_KeyCount ; t_Index ++ ) { SnmpObjectIdentifier *t_Encode = m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierComponent [ t_Index + 1 ] ; SnmpObjectIdentifier *t_Start = m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierStart [ t_Index + 1 ] ; if ( t_Start ) { /* * We have a start which is not negatively infinite */ if ( *t_Encode > *t_Start ) { /* * The encoded object from the device is greater than the start value, so add the encoded value * to the running total. */ a_AdvanceObjectIdentifier = a_AdvanceObjectIdentifier + *t_Encode ; } else if ( *t_Encode == *t_Start ) { a_AdvanceObjectIdentifier = a_AdvanceObjectIdentifier + *t_Encode ; } else { /* * Encoded value is less than start value so we need to advance to the start value */ t_UseStartAsAdvance = TRUE ; /* * The encoded object from the device is less than the start value, so add the encoded value * to the running total. */ a_AdvanceObjectIdentifier = a_AdvanceObjectIdentifier + *t_Start ; } } else { /* * Start is negatively infinite */ if ( t_UseStartAsAdvance ) { /* * We have already identified a starting position which is greater than the encoded value. * The new value is a negative infinite so we should stop here */ t_Index ++ ; break ; } else { /* * The start position is negatively infinite and we haven't had to use a different value from the one * returned from the device. */ a_AdvanceObjectIdentifier = a_AdvanceObjectIdentifier + *t_Encode ; } } /* * The value was not taken from the start value with an * infinite range on next key index, so we must check to see if the range is less than the 'end' */ PartitionSet *t_KeyPartition = m_PropertyContainer [ a_PropertyIndex ].m_KeyPartition [ t_Index + 1 ] ; WmiRangeNode *t_Range = t_KeyPartition->GetRange () ; SnmpObjectIdentifier *t_End = m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierEnd [ t_Index + 1 ] ; if ( t_End ) { BOOL t_InRange = ( ( t_Range->ClosedUpperBound () && ( *t_Encode <= *t_End ) ) || ( ! t_Range->ClosedUpperBound () && ( *t_Encode < *t_End ) ) ) ; if ( t_InRange ) { /* * We are still within the boundaries */ } else { /* * Move to new partition because we have moved past end */ SnmpObjectIdentifier t_StartObjectIdentifier ( 0 , NULL ) ; /* * Advance to the next partition, we will use the next partition starting point for next request */ t_Evaluation = EvaluateSubsequentVarBind ( a_PropertyIndex , a_CurrentIndex , a_AdvanceObjectIdentifier , t_StartObjectIdentifier ) ; if ( t_Evaluation >= 0 ) { a_AdvanceObjectIdentifier = t_StartObjectIdentifier ; } t_UseStartAsAdvance = FALSE ; t_Index ++ ; break ; } } else { /* * Range is infinite so go on to next */ } } if ( t_UseStartAsAdvance ) { /* * We have got all the way to the end without move to the end of a partition and have used new start position */ PartitionSet *t_KeyPartition = m_PropertyContainer [ a_PropertyIndex ].m_KeyPartition [ t_Index ] ; WmiRangeNode *t_Range = t_KeyPartition->GetRange () ; if( t_Range->ClosedLowerBound () ) { if ( ! DecrementObjectIdentifier ( a_AdvanceObjectIdentifier , a_AdvanceObjectIdentifier ) ) { t_Evaluation = -1 ; return t_Evaluation ; } } t_Evaluation = 1 ; } return t_Evaluation ; } LONG AutoRetrieveOperation :: EvaluateInitialVarBind ( ULONG a_PropertyIndex , SnmpObjectIdentifier &a_CurrentIdentifier , SnmpObjectIdentifier &a_StartIdentifier ) { LONG t_Scoped = -1 ; PartitionSet *t_Partition = eventObject->GetPartitionSet () ; if ( t_Partition ) { SnmpInstanceClassObject *t_SnmpObject = ( SnmpInstanceClassObject * ) eventObject->GetSnmpClassObject () ; ULONG t_KeyCount = t_SnmpObject->GetKeyPropertyCount () ; if ( ! m_PropertyContainer [ a_PropertyIndex ].m_PartitionIndex ) { m_PropertyContainer [ a_PropertyIndex ].m_KeyCount = t_KeyCount ; m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierStart = new SnmpObjectIdentifier * [ t_KeyCount + 1 ] ; m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierEnd = new SnmpObjectIdentifier * [ t_KeyCount + 1 ] ; m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierComponent = new SnmpObjectIdentifier * [ t_KeyCount + 1 ] ; m_PropertyContainer [ a_PropertyIndex ].m_KeyPartition = new PartitionSet * [ t_KeyCount + 1 ] ; m_PropertyContainer [ a_PropertyIndex ].m_PartitionIndex = new ULONG [ t_KeyCount + 1 ] ; for ( ULONG t_Index = 0 ; t_Index <= t_KeyCount ; t_Index ++ ) { m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierStart [ t_Index ] = NULL ; m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierEnd [ t_Index ] = NULL ; m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierComponent [ t_Index ] = NULL ; m_PropertyContainer [ a_PropertyIndex ].m_PartitionIndex [ t_Index ] = 0 ; m_PropertyContainer [ a_PropertyIndex ].m_KeyPartition [ t_Index ] = t_Partition ; t_Partition = t_Partition->GetPartition ( 0 ) ; } t_Scoped = EvaluateVarBind ( a_PropertyIndex , a_StartIdentifier ) ; } } return t_Scoped ; } LONG AutoRetrieveOperation :: EvaluateSubsequentVarBind ( ULONG a_PropertyIndex , ULONG &a_CurrentIndex , SnmpObjectIdentifier &a_CurrentIdentifier , SnmpObjectIdentifier &a_StartIdentifier ) { LONG t_Scoped = -1 ; SnmpInstanceClassObject *t_SnmpObject = ( SnmpInstanceClassObject * ) eventObject->GetSnmpClassObject () ; ULONG t_KeyCount = t_SnmpObject->GetKeyPropertyCount () ; BOOL t_Complete = FALSE ; BOOL t_AdvanceInsidePartition = FALSE ; while ( ! t_Complete ) { if ( a_CurrentIndex > 0 ) { if ( t_AdvanceInsidePartition ) { SnmpObjectIdentifier *t_Encode = m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierComponent [ a_CurrentIndex ] ; BOOL t_Incremented = IncrementObjectIdentifier ( *t_Encode , *t_Encode ) ; if ( t_Incremented ) { t_Scoped = EvaluateResponse ( a_PropertyIndex , a_CurrentIndex , a_StartIdentifier ) ; t_Complete = TRUE ; } else { /* * Increment failed so next time around loop to next partition */ t_AdvanceInsidePartition = FALSE ; } } else { /* * Get the current partition index and increment to get next possible partition index */ ULONG t_PartitionIndex = m_PropertyContainer [ a_PropertyIndex ].m_PartitionIndex [ a_CurrentIndex - 1 ] + 1 ; /* * Get the parent partition set associated with the current key partition */ PartitionSet *t_ParentPartition = m_PropertyContainer [ a_PropertyIndex ].m_KeyPartition [ a_CurrentIndex - 1 ] ; /* * Check there are more partitions left to scan */ if ( t_PartitionIndex >= t_ParentPartition->GetPartitionCount () ) { if ( ! t_AdvanceInsidePartition ) { /* * Reset the current partition value to NULL object identifier */ *m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierComponent [ a_CurrentIndex ] = SnmpObjectIdentifier ( 0 , NULL ) ; /* * No more partitions for this key, move to previous key and attempt to get next value for that key */ t_AdvanceInsidePartition = TRUE ; a_CurrentIndex -- ; /* * We are not in the scope for this key */ t_Scoped = 0 ; } } else { /* * More partitions for this key * * Set the partition for the current ( keyindex == t_CurrentIndex - 1 ) to t_PartitionIndex */ m_PropertyContainer [ a_PropertyIndex ].m_PartitionIndex [ a_CurrentIndex - 1 ] = t_PartitionIndex ; /* * Move to the next partition for ( keyIndex == t_CurrentIndex - 1 ) and t_PartitionIndex */ m_PropertyContainer [ a_PropertyIndex ].m_KeyPartition [ a_CurrentIndex ] = t_ParentPartition->GetPartition ( t_PartitionIndex ) ; for ( ULONG t_Index = a_CurrentIndex ; t_Index < t_KeyCount ; t_Index ++ ) { m_PropertyContainer [ a_PropertyIndex ].m_PartitionIndex [ t_Index ] = 0 ; } t_Scoped = EvaluateVarBind ( a_PropertyIndex , a_StartIdentifier ) ; if ( a_StartIdentifier < a_CurrentIdentifier ) { a_StartIdentifier = a_CurrentIdentifier ; } PartitionSet *t_KeyPartition = m_PropertyContainer [ a_PropertyIndex ].m_KeyPartition [ a_CurrentIndex ] ; WmiRangeNode *t_Range = t_KeyPartition->GetRange () ; SnmpObjectIdentifier *t_End = m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierEnd [ a_CurrentIndex ] ; if ( t_End ) { BOOL t_InRange = ( ( t_Range->ClosedUpperBound () && ( a_StartIdentifier <= *t_End ) ) || ( ! t_Range->ClosedUpperBound () && ( a_StartIdentifier < *t_End ) ) ) ; if ( t_InRange ) { t_Complete = TRUE ; } else { a_StartIdentifier = SnmpObjectIdentifier ( 0 , NULL ) ; } } else { t_Complete = TRUE ; } } } } else { t_Complete = TRUE ; } } return t_Scoped ; } LONG AutoRetrieveOperation :: EvaluateVarBind ( ULONG a_PropertyIndex , SnmpObjectIdentifier &a_StartIdentifier ) { LONG t_Scoped = 0 ; SnmpInstanceClassObject *t_SnmpObject = ( SnmpInstanceClassObject * ) eventObject->GetSnmpClassObject () ; ULONG t_KeyCount = t_SnmpObject->GetKeyPropertyCount () ; BOOL t_FoundInfinite = FALSE ; WbemSnmpProperty *t_KeyProperty = NULL ; t_SnmpObject->ResetKeyProperty () ; for ( ULONG t_Index = 1 ; t_Index <= t_KeyCount ; t_Index ++ ) { t_KeyProperty = t_SnmpObject->NextKeyProperty () ; PartitionSet *t_KeyPartition = m_PropertyContainer [ a_PropertyIndex ].m_KeyPartition [ t_Index ] ; WmiRangeNode *t_Range = t_KeyPartition->GetRange () ; if ( t_Range->InfiniteLowerBound () ) { t_FoundInfinite = TRUE ; } else { // if we are in the middle partition we need to delete // // 00 <- 0 | 0 <---> n | n -> 00 // infinite lowerbound | no infinite lowerbound | no infinite lowerbound // // it may be allocated before and none will delete it if ( m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierStart [ t_Index ] ) { delete m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierStart [ t_Index ]; m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierStart [ t_Index ] = NULL; } t_Scoped = 1 ; m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierStart [ t_Index ] = new SnmpObjectIdentifier ( 0 , NULL ) ; if ( typeid ( *t_Range ) == typeid ( WmiUnsignedIntegerRangeNode ) ) { WmiUnsignedIntegerRangeNode *t_Node = ( WmiUnsignedIntegerRangeNode * ) t_Range ; ULONG t_Integer = t_Node->LowerBound () ; VARIANT t_Variant ; VariantInit ( & t_Variant ) ; t_Variant.vt = VT_I4 ; t_Variant.lVal = t_Integer ; t_KeyProperty->Encode ( t_Variant , * m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierStart [ t_Index ] ) ; if ( ! t_FoundInfinite ) { t_KeyProperty->Encode ( t_Variant , a_StartIdentifier ) ; } VariantClear ( & t_Variant ) ; } else if ( typeid ( *t_Range ) == typeid ( WmiSignedIntegerRangeNode ) ) { WmiSignedIntegerRangeNode *t_Node = ( WmiSignedIntegerRangeNode * ) t_Range ; LONG t_Integer = t_Node->LowerBound () ; VARIANT t_Variant ; VariantInit ( & t_Variant ) ; t_Variant.vt = VT_I4 ; t_Variant.lVal = t_Integer ; t_KeyProperty->Encode ( t_Variant , * m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierStart [ t_Index ] ) ; if ( ! t_FoundInfinite ) { t_KeyProperty->Encode ( t_Variant , a_StartIdentifier ) ; } VariantClear ( & t_Variant ) ; } if ( typeid ( *t_Range ) == typeid ( WmiStringRangeNode ) ) { WmiStringRangeNode *t_Node = ( WmiStringRangeNode * ) t_Range ; BSTR t_String = t_Node->LowerBound () ; VARIANT t_Variant ; VariantInit ( & t_Variant ) ; t_Variant.vt = VT_BSTR ; t_Variant.bstrVal = SysAllocString ( t_String ) ; t_KeyProperty->Encode ( t_Variant , * m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierStart [ t_Index ] ) ; if ( ! t_FoundInfinite ) { t_KeyProperty->Encode ( t_Variant , a_StartIdentifier ) ; } VariantClear ( & t_Variant ) ; } } if ( ( t_Index == t_KeyCount ) && t_Range->ClosedLowerBound () ) { BOOL t_Decremented = DecrementObjectIdentifier ( a_StartIdentifier , a_StartIdentifier ) ; t_Scoped = t_Decremented ? 1 : 0 ; } } t_SnmpObject->ResetKeyProperty () ; for ( t_Index = 1 ; t_Index <= t_KeyCount ; t_Index ++ ) { PartitionSet *t_KeyPartition = m_PropertyContainer [ a_PropertyIndex ].m_KeyPartition [ t_Index ] ; WmiRangeNode *t_Range = t_KeyPartition->GetRange () ; t_KeyProperty = t_SnmpObject->NextKeyProperty () ; if ( ! t_Range->InfiniteUpperBound () ) { // if we are in the middle partition we need to delete // // 00 <- 0 | 0 <---> n | n -> 00 // no infinite upperbound | no infinite lowerbound | infinite lowerbound // // it may be allocated before and none will delete it if ( m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierEnd [ t_Index ] ) { delete m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierEnd [ t_Index ]; m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierEnd [ t_Index ] = NULL; } m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierEnd [ t_Index ] = new SnmpObjectIdentifier ( 0 , NULL ) ; if ( typeid ( *t_Range ) == typeid ( WmiUnsignedIntegerRangeNode ) ) { WmiUnsignedIntegerRangeNode *t_Node = ( WmiUnsignedIntegerRangeNode * ) t_Range ; ULONG t_Integer = t_Node->UpperBound () ; VARIANT t_Variant ; VariantInit ( & t_Variant ) ; t_Variant.vt = VT_I4 ; t_Variant.lVal = t_Integer ; t_KeyProperty->Encode ( t_Variant , * m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierEnd [ t_Index ] ) ; VariantClear ( & t_Variant ) ; } else if ( typeid ( *t_Range ) == typeid ( WmiSignedIntegerRangeNode ) ) { WmiSignedIntegerRangeNode *t_Node = ( WmiSignedIntegerRangeNode * ) t_Range ; LONG t_Integer = t_Node->UpperBound () ; VARIANT t_Variant ; VariantInit ( & t_Variant ) ; t_Variant.vt = VT_I4 ; t_Variant.lVal = t_Integer ; t_KeyProperty->Encode ( t_Variant , * m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierEnd [ t_Index ] ) ; VariantClear ( & t_Variant ) ; } if ( typeid ( *t_Range ) == typeid ( WmiStringRangeNode ) ) { WmiStringRangeNode *t_Node = ( WmiStringRangeNode * ) t_Range ; BSTR t_String = t_Node->UpperBound () ; VARIANT t_Variant ; VariantInit ( & t_Variant ) ; t_Variant.vt = VT_BSTR ; t_Variant.bstrVal = SysAllocString ( t_String ) ; t_KeyProperty->Encode ( t_Variant , * m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierEnd [ t_Index ] ) ; VariantClear ( & t_Variant ) ; } if ( t_Range->ClosedUpperBound () ) { SnmpObjectIdentifier *t_End = m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierEnd [ t_Index ] ; if ( IncrementObjectIdentifier ( * t_End , * t_End ) ) { } else { if ( m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierEnd [ t_Index ] ) { delete m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierEnd [ t_Index ]; m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierEnd [ t_Index ] = NULL; } } } } } return t_Scoped ; }