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.
 
 
 
 
 
 

1196 lines
32 KiB

// 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 "classfac.h"
#include "guids.h"
#include <snmpcont.h>
#include <snmpevt.h>
#include <snmpthrd.h>
#include <snmplog.h>
#include <snmpcl.h>
#include <instpath.h>
#include <snmptype.h>
#include <snmpauto.h>
#include <snmpobj.h>
#include <genlex.h>
#include <sql_1.h>
#include <objpath.h>
#include <provtree.h>
#include <provdnf.h>
#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 ;
}