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.
1499 lines
29 KiB
1499 lines
29 KiB
|
|
// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
|
|
|
|
#include "precomp.h"
|
|
#include <provexpt.h>
|
|
#include <cordefs.h>
|
|
#include <corafx.h>
|
|
#include <objbase.h>
|
|
#include <wbemidl.h>
|
|
#include <smir.h>
|
|
#include <corstore.h>
|
|
#include <notify.h>
|
|
#include <snmplog.h>
|
|
#include <autoptr.h>
|
|
|
|
extern ISmirDatabase* g_pNotifyInt;
|
|
extern CCorrCacheNotify *gp_notify;
|
|
|
|
CCorrGroupArray::CCorrGroupArray()
|
|
{
|
|
SetSize(0, 10000);
|
|
}
|
|
|
|
int _cdecl compare( const void *arg1, const void *arg2 )
|
|
{
|
|
CCorrObjectID tmp1;
|
|
(*(CCorrGroupIdItem**)arg1)->GetGroupID(tmp1);
|
|
CCorrObjectID tmp2;
|
|
(*(CCorrGroupIdItem**)arg2)->GetGroupID(tmp2);
|
|
|
|
switch (tmp1.CompareWith(tmp2))
|
|
{
|
|
case ECorrAreEqual:
|
|
break;
|
|
|
|
case ECorrFirstLess:
|
|
return -1;
|
|
|
|
case ECorrFirstGreater:
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void CCorrGroupArray::Sort()
|
|
{
|
|
if (GetSize())
|
|
{
|
|
//CObject** temp = GetData();
|
|
qsort((void *)GetData(), (size_t)GetSize(),
|
|
sizeof( CCorrGroupIdItem * ), compare );
|
|
}
|
|
|
|
FreeExtra();
|
|
}
|
|
|
|
|
|
//============================================================================
|
|
// CCorrGroupArray::~CCorrGroupArray
|
|
//
|
|
// This is the CCorrGroupArray class's only desstructor. If there are any items in
|
|
// the queue they are deleted.
|
|
//
|
|
//
|
|
// Parameters:
|
|
//
|
|
// none
|
|
//
|
|
// Returns:
|
|
//
|
|
// none
|
|
//
|
|
//============================================================================
|
|
|
|
CCorrGroupArray::~CCorrGroupArray()
|
|
{
|
|
for (int x = 0; x < GetSize(); x++)
|
|
{
|
|
CCorrGroupIdItem * item = GetAt(x);
|
|
delete item;
|
|
}
|
|
|
|
RemoveAll();
|
|
}
|
|
|
|
|
|
//============================================================================
|
|
// CCorrGroupIdItem::CCorrGroupIdItem
|
|
//
|
|
// This is the CCorrGroupIdItem class's only constructor. This class is derived from
|
|
// the CObject class. This is so the MFC template storage classes can be
|
|
// used. It is used to store a CString value in a list.
|
|
//
|
|
//
|
|
// Parameters:
|
|
//
|
|
// CString * str A pointer to the CString object to be stored.
|
|
//
|
|
// Returns:
|
|
//
|
|
// none
|
|
//
|
|
//============================================================================
|
|
|
|
CCorrGroupIdItem::CCorrGroupIdItem(IN const CCorrObjectID& ID, IN ISmirGroupHandle* grpH)
|
|
: m_groupId(ID)
|
|
{
|
|
m_index = 0;
|
|
|
|
if (grpH)
|
|
{
|
|
m_groupHandles.AddHead(grpH);
|
|
}
|
|
}
|
|
|
|
|
|
void CCorrGroupIdItem::GetGroupID(OUT CCorrObjectID& ID) const
|
|
{
|
|
m_groupId.ExtractOID(ID);
|
|
}
|
|
|
|
|
|
void CCorrGroupIdItem::DebugOutputItem(CString* msg) const
|
|
{
|
|
CString debugstr;
|
|
CCorrObjectID tmp;
|
|
m_groupId.ExtractOID(tmp);
|
|
tmp.GetString(debugstr);
|
|
|
|
if (!debugstr.GetLength())
|
|
{
|
|
debugstr = L"Error retrieving Group Object OID";
|
|
}
|
|
|
|
if (msg)
|
|
{
|
|
debugstr += L"\t\t:\t";
|
|
debugstr += *msg;
|
|
}
|
|
|
|
debugstr += L"\n";
|
|
DebugMacro6(
|
|
SnmpDebugLog::s_SnmpDebugLog->WriteFileAndLine(__FILE__,__LINE__,
|
|
debugstr);
|
|
)
|
|
|
|
}
|
|
|
|
|
|
//============================================================================
|
|
// CCorrGroupIdItem::~CCorrGroupIdItem
|
|
//
|
|
// This is the CCorrGroupIdItem class's only destructor. It frees the memory used
|
|
// to store the CString members.
|
|
//
|
|
//
|
|
// Parameters:
|
|
//
|
|
// none
|
|
//
|
|
// Returns:
|
|
//
|
|
// none
|
|
//
|
|
//============================================================================
|
|
|
|
CCorrGroupIdItem::~CCorrGroupIdItem()
|
|
{
|
|
while (!m_groupHandles.IsEmpty())
|
|
{
|
|
(m_groupHandles.RemoveHead())->Release();
|
|
}
|
|
}
|
|
|
|
|
|
CCorrObjectID::CCorrObjectID(IN const CCorrObjectID& ID) : m_Ids(NULL)
|
|
{
|
|
m_length = ID.m_length;
|
|
|
|
if (m_length)
|
|
{
|
|
m_Ids = new UINT[m_length];
|
|
memcpy(m_Ids, ID.m_Ids, m_length*sizeof(UINT));
|
|
}
|
|
}
|
|
|
|
|
|
CCorrObjectID::CCorrObjectID(IN const char* str) : m_Ids(NULL)
|
|
{
|
|
m_length = 0;
|
|
|
|
if (NULL != str)
|
|
{
|
|
size_t InputLen = strlen(str);
|
|
if (InputLen > MAX_OID_STRING) return; //string is too long.
|
|
|
|
char temp[MAX_OID_STRING + 1];
|
|
strcpy(temp, str);
|
|
|
|
BOOL bad = FALSE;
|
|
char* temp1 = temp;
|
|
UINT temp2[MAX_OID_LENGTH];
|
|
CString dot(".");
|
|
|
|
if (dot.GetAt(0) == temp[0])
|
|
{
|
|
temp1++;
|
|
}
|
|
|
|
istrstream istr(temp1);
|
|
char d;
|
|
|
|
istr >> temp2[0];
|
|
m_length++;
|
|
|
|
if (istr.bad() || istr.fail())
|
|
{
|
|
bad = TRUE;
|
|
}
|
|
|
|
while(!istr.eof() && !bad)
|
|
{
|
|
istr >> d;
|
|
|
|
if (istr.bad() || istr.fail())
|
|
{
|
|
bad = TRUE;
|
|
}
|
|
|
|
if (d != dot.GetAt(0))
|
|
{
|
|
bad = TRUE;
|
|
}
|
|
|
|
if (m_length < MAX_OID_LENGTH)
|
|
{
|
|
istr >> temp2[m_length++];
|
|
|
|
if (istr.bad() || istr.fail())
|
|
{
|
|
bad = TRUE;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
bad = TRUE;
|
|
}
|
|
}
|
|
|
|
if (!bad)
|
|
{
|
|
m_Ids = new UINT[m_length];
|
|
memcpy(m_Ids, temp2, m_length*sizeof(UINT));
|
|
}
|
|
else
|
|
{
|
|
m_length = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
CCorrObjectID::CCorrObjectID(IN const UINT* ids, IN const UINT len) : m_Ids(NULL)
|
|
{
|
|
if (len <= MAX_OID_LENGTH)
|
|
{
|
|
m_length = len;
|
|
}
|
|
else
|
|
{
|
|
m_length = 0;
|
|
}
|
|
|
|
if (m_length)
|
|
{
|
|
m_Ids = new UINT[m_length];
|
|
memcpy(m_Ids, ids, m_length*sizeof(UINT));
|
|
}
|
|
}
|
|
|
|
|
|
void CCorrObjectID::Set(IN const UINT* ids, IN const UINT len)
|
|
{
|
|
if (m_length)
|
|
{
|
|
delete [] m_Ids;
|
|
}
|
|
|
|
if (len <= MAX_OID_LENGTH)
|
|
{
|
|
m_length = len;
|
|
}
|
|
else
|
|
{
|
|
m_length = 0;
|
|
}
|
|
|
|
if (m_length)
|
|
{
|
|
m_Ids = new UINT[m_length];
|
|
memcpy(m_Ids, ids, m_length*sizeof(UINT));
|
|
}
|
|
else
|
|
{
|
|
m_Ids = NULL;
|
|
}
|
|
}
|
|
|
|
char* CCorrObjectID::GetString() const
|
|
{
|
|
char * ret = NULL;
|
|
|
|
if (m_length)
|
|
{
|
|
ret = new char[BYTES_PER_FIELD*m_length];
|
|
ostrstream s(ret, BYTES_PER_FIELD*m_length);
|
|
s << m_Ids[0];
|
|
UINT i = 1;
|
|
char dot = '.';
|
|
|
|
while (i < m_length)
|
|
{
|
|
s << dot << m_Ids[i++];
|
|
}
|
|
|
|
s << ends;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
#define AVERAGE_OID_LENGTH 20
|
|
wchar_t* CCorrObjectID::GetWideString() const
|
|
{
|
|
wchar_t *returnValue = NULL ;
|
|
|
|
ULONG totalLength = 0 ;
|
|
ULONG reallocLength = AVERAGE_OID_LENGTH ;
|
|
wchar_t *reallocArray = new wchar_t [ reallocLength ] ;
|
|
if (reallocArray == NULL)
|
|
{
|
|
throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
|
|
}
|
|
|
|
wmilib::auto_ptr<WCHAR> t_ReallocWrap ( reallocArray );
|
|
|
|
ULONG objectIdentifierLength = m_length ;
|
|
ULONG index = 0 ;
|
|
while ( index < objectIdentifierLength )
|
|
{
|
|
wchar_t stringValue [ 40 ] ;
|
|
_ultow ( m_Ids [ index ] , stringValue , 10 );
|
|
ULONG stringLength = wcslen ( stringValue ) ;
|
|
|
|
if ( ( totalLength + stringLength + 1 ) >= reallocLength )
|
|
{
|
|
ULONG t_Max = max( stringLength + 1 , AVERAGE_OID_LENGTH ) ;
|
|
reallocLength = reallocLength + t_Max ;
|
|
wchar_t *t_newReallocArray = new wchar_t [ reallocLength ] ;
|
|
CopyMemory ( t_newReallocArray , t_ReallocWrap.get () , totalLength * sizeof ( wchar_t ) ) ;
|
|
t_ReallocWrap.reset ( t_newReallocArray ) ;
|
|
}
|
|
|
|
wcscpy ( & ( t_ReallocWrap.get () [ totalLength ] ) , stringValue ) ;
|
|
totalLength = totalLength + stringLength ;
|
|
|
|
index ++ ;
|
|
if ( index < objectIdentifierLength )
|
|
{
|
|
if ( ( totalLength + 1 + 1 ) >= reallocLength )
|
|
{
|
|
reallocLength = reallocLength + AVERAGE_OID_LENGTH ;
|
|
wchar_t *t_newReallocArray = new wchar_t [ reallocLength ] ;
|
|
CopyMemory ( t_newReallocArray , t_ReallocWrap.get () , totalLength * sizeof ( wchar_t ) ) ;
|
|
t_ReallocWrap.reset ( t_newReallocArray ) ;
|
|
}
|
|
|
|
wcscpy ( & ( t_ReallocWrap.get ()[ totalLength ] ) , L"." ) ;
|
|
totalLength ++ ;
|
|
}
|
|
}
|
|
|
|
returnValue = new wchar_t [ totalLength + 1 ] ;
|
|
if ( objectIdentifierLength )
|
|
{
|
|
wcscpy ( returnValue , t_ReallocWrap.get () ) ;
|
|
}
|
|
else
|
|
{
|
|
returnValue [ 0 ] = 0 ;
|
|
}
|
|
|
|
return returnValue ;
|
|
}
|
|
|
|
void CCorrObjectID::GetString(CString& str) const
|
|
{
|
|
wchar_t* oid = GetWideString();
|
|
|
|
try
|
|
{
|
|
str = oid;
|
|
}
|
|
catch(...)
|
|
{
|
|
delete [] oid;
|
|
throw;
|
|
}
|
|
|
|
delete [] oid;
|
|
}
|
|
|
|
ECorrCompResult CCorrObjectID::CompareWith(IN const CCorrObjectID& second) const
|
|
{
|
|
if (0 == m_length)
|
|
{
|
|
if (0 == second.m_length)
|
|
{
|
|
return ECorrAreEqual;
|
|
}
|
|
else
|
|
{
|
|
return ECorrFirstLess;
|
|
}
|
|
}
|
|
|
|
if (0 == second.m_length)
|
|
{
|
|
return ECorrFirstGreater;
|
|
}
|
|
|
|
ECorrCompResult res = ECorrAreEqual;
|
|
|
|
if (m_length <= second.m_length)
|
|
{
|
|
for (UINT i = 0; i < m_length; i++)
|
|
{
|
|
if (m_Ids[i] != second.m_Ids[i])
|
|
{
|
|
if (m_Ids[i] < second.m_Ids[i])
|
|
{
|
|
return ECorrFirstLess;
|
|
}
|
|
else
|
|
{
|
|
return ECorrFirstGreater;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (m_length < second.m_length)
|
|
{
|
|
res = ECorrFirstLess;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (UINT i = 0; i < second.m_length; i++)
|
|
{
|
|
if (m_Ids[i] != second.m_Ids[i])
|
|
{
|
|
if (m_Ids[i] < second.m_Ids[i])
|
|
{
|
|
return ECorrFirstLess;
|
|
}
|
|
else
|
|
{
|
|
return ECorrFirstGreater;
|
|
}
|
|
}
|
|
}
|
|
|
|
res = ECorrFirstGreater;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
|
|
BOOL CCorrObjectID::IsSubRange(IN const CCorrObjectID& child) const
|
|
{
|
|
if (m_length >= child.m_length)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
for (UINT i=0; i<m_length; i++)
|
|
{
|
|
if (m_Ids[i] != child.m_Ids[i])
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL CCorrObjectID::operator ==(IN const CCorrObjectID& second) const
|
|
{
|
|
if (ECorrAreEqual == CompareWith(second))
|
|
{
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
BOOL CCorrObjectID::operator !=(IN const CCorrObjectID& second) const
|
|
{
|
|
if (ECorrAreEqual == CompareWith(second))
|
|
{
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
BOOL CCorrObjectID::operator <(IN const CCorrObjectID& second) const
|
|
{
|
|
if (ECorrFirstLess == CompareWith(second))
|
|
{
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
BOOL CCorrObjectID::operator >(IN const CCorrObjectID& second) const
|
|
{
|
|
if (ECorrFirstGreater == CompareWith(second))
|
|
{
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
BOOL CCorrObjectID::operator <=(IN const CCorrObjectID& second) const
|
|
{
|
|
ECorrCompResult res = CompareWith(second);
|
|
|
|
if ((ECorrAreEqual == res) || (ECorrFirstLess == res))
|
|
{
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
BOOL CCorrObjectID::operator >=(IN const CCorrObjectID& second) const
|
|
{
|
|
ECorrCompResult res = CompareWith(second);
|
|
|
|
if ((ECorrAreEqual == res) || (ECorrFirstGreater == res))
|
|
{
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
CCorrObjectID& CCorrObjectID::operator =(IN const CCorrObjectID& ID)
|
|
{
|
|
if (m_length)
|
|
{
|
|
delete [] m_Ids;
|
|
}
|
|
|
|
m_length = ID.m_length;
|
|
|
|
if (m_length)
|
|
{
|
|
m_Ids = new UINT[m_length];
|
|
memcpy(m_Ids, ID.m_Ids, m_length*sizeof(UINT));
|
|
}
|
|
else
|
|
{
|
|
m_Ids = NULL;
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
CCorrObjectID& CCorrObjectID::operator +=(IN const CCorrObjectID& ID)
|
|
{
|
|
if((m_length + ID.m_length) > MAX_OID_LENGTH)
|
|
{
|
|
if(m_length)
|
|
{
|
|
delete [] m_Ids;
|
|
m_Ids = NULL;
|
|
}
|
|
|
|
m_length = 0;
|
|
}
|
|
else
|
|
{
|
|
if (ID.m_length)
|
|
{
|
|
UINT* newIds = new UINT[m_length + ID.m_length];
|
|
|
|
if(m_length)
|
|
{
|
|
memcpy(newIds, m_Ids, m_length*sizeof(UINT));
|
|
delete [] m_Ids;
|
|
m_Ids = NULL;
|
|
}
|
|
|
|
memcpy(&(newIds[m_length]), ID.m_Ids, ID.m_length*sizeof(UINT));
|
|
m_Ids = newIds;
|
|
m_length += ID.m_length;
|
|
}
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
CCorrObjectID& CCorrObjectID::operator ++()
|
|
{
|
|
if (m_length)
|
|
{
|
|
m_Ids[m_length - 1]++;
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
CCorrObjectID& CCorrObjectID::operator --()
|
|
{
|
|
if (m_length)
|
|
{
|
|
m_Ids[m_length - 1]--;
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
CCorrObjectID& CCorrObjectID::operator -=(IN const UINT sub)
|
|
{
|
|
if (sub && (m_length > sub))
|
|
{
|
|
m_length -= sub;
|
|
UINT* newIds = new UINT[m_length];
|
|
memcpy(newIds, m_Ids, m_length*sizeof(UINT));
|
|
delete [] m_Ids;
|
|
m_Ids = newIds;
|
|
}
|
|
else if (sub == m_length)
|
|
{
|
|
m_length = 0;
|
|
delete [] m_Ids;
|
|
m_Ids = NULL;
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
CCorrObjectID& CCorrObjectID::operator /=(IN const UINT sub)
|
|
{
|
|
if (sub && (m_length > sub))
|
|
{
|
|
m_length -= sub;
|
|
UINT* newIds = new UINT[m_length];
|
|
memcpy(newIds, &(m_Ids[sub]), m_length*sizeof(UINT));
|
|
delete [] m_Ids;
|
|
m_Ids = newIds;
|
|
}
|
|
else if (sub == m_length)
|
|
{
|
|
m_length = 0;
|
|
delete [] m_Ids;
|
|
m_Ids = NULL;
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
CCorrObjectID::~CCorrObjectID()
|
|
{
|
|
if (m_length)
|
|
{
|
|
delete [] m_Ids;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
//============================================================================
|
|
// CCorrRangeTableItem::CCorrRangeTableItem
|
|
//
|
|
// This is the CCorrRangeTableItem class's only constructor. This class is derived from
|
|
// the CObject class. This is so the MFC template storage classes can be
|
|
// used. It is used to store a CString value in a list.
|
|
//
|
|
//
|
|
// Parameters:
|
|
//
|
|
// CString * str A pointer to the CString object to be stored.
|
|
//
|
|
// Returns:
|
|
//
|
|
// none
|
|
//
|
|
//============================================================================
|
|
|
|
CCorrRangeTableItem::CCorrRangeTableItem(IN const CCorrObjectID& startID,
|
|
IN const CCorrObjectID& endID,
|
|
IN CCorrGroupIdItem* grpID)
|
|
{
|
|
m_groupId = grpID;
|
|
CCorrObjectID temp;
|
|
m_groupId->GetGroupID(temp);
|
|
CCorrObjectID startRange = startID;
|
|
startRange /= temp.GetLength();
|
|
CCorrObjectID endRange = endID;
|
|
endRange /= (temp.GetLength() - 1);
|
|
m_startRange.Set(startRange);
|
|
m_endRange.Set(endRange);
|
|
}
|
|
|
|
|
|
//============================================================================
|
|
// CCorrRangeTableItem::~CCorrRangeTableItem
|
|
//
|
|
// This is the CCorrRangeTableItem class's only destructor. It frees the memory used
|
|
// to store the CString members.
|
|
//
|
|
//
|
|
// Parameters:
|
|
//
|
|
// none
|
|
//
|
|
// Returns:
|
|
//
|
|
// none
|
|
//
|
|
//============================================================================
|
|
|
|
CCorrRangeTableItem::~CCorrRangeTableItem()
|
|
{
|
|
|
|
}
|
|
|
|
|
|
BOOL CCorrRangeTableItem::GetStartRange(OUT CCorrObjectID& start) const
|
|
{
|
|
if (!m_groupId)
|
|
return FALSE;
|
|
|
|
m_groupId->GetGroupID(start);
|
|
CCorrObjectID tmp;
|
|
m_startRange.ExtractOID(tmp);
|
|
start += tmp;
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL CCorrRangeTableItem::GetEndRange(OUT CCorrObjectID& end) const
|
|
{
|
|
if (!m_groupId)
|
|
return FALSE;
|
|
|
|
m_groupId->GetGroupID(end);
|
|
end -= 1;
|
|
CCorrObjectID tmp;
|
|
m_endRange.ExtractOID(tmp);
|
|
end += tmp;
|
|
return TRUE;
|
|
}
|
|
|
|
CCorrRangeTableItem::ECorrRangeResult CCorrRangeTableItem::
|
|
IsInRange(IN const CCorrObjectID& ID) const
|
|
{
|
|
CCorrObjectID a;
|
|
|
|
GetStartRange(a);
|
|
|
|
if (ID == a)
|
|
{
|
|
return ECorrEqualToStart;
|
|
}
|
|
|
|
if (ID < a)
|
|
{
|
|
return ECorrBeforeStart;
|
|
}
|
|
|
|
CCorrObjectID b;
|
|
GetEndRange(b);
|
|
|
|
if (ID == b)
|
|
{
|
|
return ECorrEqualToEnd;
|
|
}
|
|
|
|
if (ID > b)
|
|
{
|
|
return ECorrAfterEnd;
|
|
}
|
|
|
|
return ECorrInRange;
|
|
}
|
|
|
|
|
|
void CCorrRangeTableItem::DebugOutputRange() const
|
|
{
|
|
DebugMacro6(
|
|
if (m_groupId)
|
|
{
|
|
CString debugstr;
|
|
CCorrObjectID tmp;
|
|
m_groupId->GetGroupID(tmp);
|
|
tmp.GetString(debugstr);
|
|
CString out1;
|
|
CCorrObjectID start;
|
|
GetStartRange(start);
|
|
start.GetString(out1);
|
|
CString out2;
|
|
CCorrObjectID end;
|
|
GetEndRange(end);
|
|
end.GetString(out2);
|
|
debugstr += "\t\t:\t\t";
|
|
debugstr += out1;
|
|
debugstr += "\t\t:\t\t";
|
|
debugstr += out2;
|
|
debugstr += "\t\tGroup : Start : End\n";
|
|
SnmpDebugLog::s_SnmpDebugLog->WriteFileAndLine(__FILE__,__LINE__,
|
|
debugstr);
|
|
}
|
|
else
|
|
{
|
|
SnmpDebugLog::s_SnmpDebugLog->WriteFileAndLine(__FILE__,__LINE__,
|
|
L"Attempt to output empty RangeTableItem\n");
|
|
}
|
|
)
|
|
}
|
|
|
|
|
|
//============================================================================
|
|
// CCorrRangeList::~CCorrRangeList
|
|
//
|
|
// This is the CCorrRangeList class's only desstructor. If there are any items in
|
|
// the queue they are deleted.
|
|
//
|
|
//
|
|
// Parameters:
|
|
//
|
|
// none
|
|
//
|
|
// Returns:
|
|
//
|
|
// none
|
|
//
|
|
//============================================================================
|
|
|
|
CCorrRangeList::~CCorrRangeList()
|
|
{
|
|
while(!IsEmpty())
|
|
{
|
|
CCorrRangeTableItem * item = RemoveHead();
|
|
delete item;
|
|
}
|
|
}
|
|
|
|
|
|
//============================================================================
|
|
// CCorrRangeList::Add
|
|
//
|
|
// This public method is called to add a CCorrRangeTableItem into this CCorrRangeList. The
|
|
// CCorrRangeTableItem is not added if it is already present in the list. If this is the
|
|
// case a pointer to the matching item in the list is returned.
|
|
//
|
|
//
|
|
// Parameters:
|
|
//
|
|
// CCorrRangeTableItem * newItem A pointer to the CCorrRangeTableItem to be added.
|
|
//
|
|
// Returns:
|
|
//
|
|
// CCorrRangeTableItem * A pointer to the item if is in the list. NULL if
|
|
// the item was not found and was added.
|
|
//
|
|
//============================================================================
|
|
|
|
BOOL CCorrRangeList::Add(IN CCorrRangeTableItem* newItem)
|
|
{
|
|
AddTail(newItem); //empty or all items smaller
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL CCorrRangeList::GetLastEndOID(OUT CCorrObjectID& end) const
|
|
{
|
|
if (IsEmpty())
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
return (GetTail()->GetEndRange(end));
|
|
}
|
|
|
|
|
|
CCorrGroupMask::CCorrGroupMask(IN const TCorrMaskLength sze) : m_mask(NULL)
|
|
{
|
|
m_size = sze;
|
|
|
|
if (m_size)
|
|
{
|
|
TCorrMaskLength x = m_size / (sizeof(TCorrMaskUnit)*BITS_PER_BYTE);
|
|
|
|
if (m_size % (sizeof(TCorrMaskUnit)*BITS_PER_BYTE))
|
|
{
|
|
x++;
|
|
}
|
|
|
|
m_mask = new TCorrMaskUnit[x];
|
|
ZeroMemory((PVOID)m_mask, (DWORD)(sizeof(TCorrMaskUnit)*x));
|
|
}
|
|
}
|
|
|
|
BOOL CCorrGroupMask::IsBitSet(IN const TCorrMaskLength bit)const
|
|
{
|
|
TCorrMaskLength x = bit / (sizeof(TCorrMaskUnit)*BITS_PER_BYTE);
|
|
TCorrMaskLength val = bit % (sizeof(TCorrMaskUnit)*BITS_PER_BYTE);
|
|
|
|
return (((m_mask[x] >> val) & 1) == 1);
|
|
}
|
|
|
|
void CCorrGroupMask::SetBit(IN const TCorrMaskLength bit, IN const BOOL On)
|
|
{
|
|
BOOL IsBit = IsBitSet(bit);
|
|
|
|
if ((IsBit && On) || (!IsBit && !On))
|
|
{
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
TCorrMaskLength x = bit / (sizeof(TCorrMaskUnit)*BITS_PER_BYTE);
|
|
TCorrMaskLength val = bit % (sizeof(TCorrMaskUnit)*BITS_PER_BYTE);
|
|
TCorrMaskLength maskval = 1;
|
|
maskval <<= val;
|
|
|
|
if (On)
|
|
{
|
|
m_mask[x] += maskval;
|
|
}
|
|
else
|
|
{
|
|
m_mask[x] -= maskval;
|
|
}
|
|
}
|
|
}
|
|
|
|
CCorrGroupMask::~CCorrGroupMask()
|
|
{
|
|
if (m_mask)
|
|
{
|
|
delete [] m_mask;
|
|
}
|
|
}
|
|
|
|
CCorrCache::CCorrCache( ISmirInterrogator *a_ISmirInterrogator ) : m_Groups (NULL)
|
|
{
|
|
m_ValidCache = TRUE;
|
|
m_Ref_Count = 0;
|
|
m_size = 0;
|
|
BuildCacheAndSetNotify( a_ISmirInterrogator );
|
|
|
|
if (m_groupTable.GetSize())
|
|
{
|
|
m_Groups = new CCorrGroupMask(m_size);
|
|
BuildRangeTable();
|
|
}
|
|
}
|
|
|
|
CCorrCache::~CCorrCache()
|
|
{
|
|
if (m_Groups)
|
|
{
|
|
delete m_Groups;
|
|
}
|
|
}
|
|
|
|
void CCorrCache::InvalidateCache()
|
|
{
|
|
m_Lock.Lock();
|
|
|
|
if (!m_Ref_Count)
|
|
{
|
|
delete this;
|
|
}
|
|
else
|
|
{
|
|
m_ValidCache = FALSE;
|
|
m_Lock.Unlock();
|
|
}
|
|
}
|
|
|
|
BOOL CCorrCache::BuildCacheAndSetNotify( ISmirInterrogator *a_ISmirInterrogator )
|
|
{
|
|
LPUNKNOWN pInterrogativeInt = NULL;
|
|
|
|
// ===============================================================
|
|
// The following relies on the current thread having been
|
|
// initialised for OLE (i.e. by the use of CoInitialize)
|
|
// ===============================================================
|
|
|
|
HRESULT hr = S_OK ;
|
|
|
|
if ( a_ISmirInterrogator )
|
|
{
|
|
hr = a_ISmirInterrogator->QueryInterface (
|
|
|
|
IID_ISMIR_Interrogative, (void**)&pInterrogativeInt
|
|
);
|
|
}
|
|
else
|
|
{
|
|
hr = CoCreateInstance (CLSID_SMIR_Database,
|
|
NULL, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
|
|
IID_ISMIR_Interrogative, (void**)&pInterrogativeInt);
|
|
}
|
|
|
|
if (NULL == pInterrogativeInt)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
IEnumGroup *pTEnumSmirGroup = NULL;
|
|
|
|
//enum all groups
|
|
hr = ((ISmirInterrogator*)pInterrogativeInt)->EnumGroups(&pTEnumSmirGroup, NULL);
|
|
|
|
//now use the enumerator
|
|
if(NULL == pTEnumSmirGroup)
|
|
{
|
|
pInterrogativeInt->Release();
|
|
return FALSE;
|
|
}
|
|
|
|
ISmirGroupHandle *phModule=NULL;
|
|
|
|
DebugMacro6(
|
|
SnmpDebugLog::s_SnmpDebugLog->WriteFileAndLine(__FILE__,__LINE__,
|
|
L"CCorrCache::BuildCacheAndSetNotify - Accessing SMIR Getting Groups\n");
|
|
)
|
|
|
|
|
|
for(int iCount=0; S_OK == pTEnumSmirGroup->Next(1, &phModule, NULL); iCount++)
|
|
{
|
|
//DO SOMETHING WITH THE GROUP HANDLE
|
|
|
|
//eg get the name
|
|
BSTR szName=NULL;
|
|
char buff[1024];
|
|
LPSTR pbuff = buff;
|
|
int lbuff = sizeof(buff);
|
|
phModule->GetGroupOID(&szName);
|
|
|
|
if (FALSE == WideCharToMultiByte(CP_ACP, 0,
|
|
szName, -1, pbuff, lbuff, NULL, NULL))
|
|
{
|
|
DWORD lasterr = GetLastError();
|
|
SysFreeString(szName);
|
|
phModule->Release();
|
|
DebugMacro6(
|
|
SnmpDebugLog::s_SnmpDebugLog->WriteFileAndLine(__FILE__,__LINE__,
|
|
L"CCorrCache::BuildCacheAndSetNotify - Error bad BSTR conversion\n");
|
|
)
|
|
continue;
|
|
}
|
|
|
|
SysFreeString(szName);
|
|
CCorrObjectID grpId(buff);
|
|
CCorrObjectID zero;
|
|
|
|
if (zero != grpId)
|
|
{
|
|
CCorrGroupIdItem* groupId = new CCorrGroupIdItem(grpId, phModule);
|
|
m_groupTable.Add(groupId);
|
|
m_size++;
|
|
}
|
|
|
|
DebugMacro6(
|
|
SnmpDebugLog::s_SnmpDebugLog->WriteFileAndLine(__FILE__,__LINE__,
|
|
L"%s\n", buff);
|
|
)
|
|
}
|
|
|
|
DebugMacro6(
|
|
SnmpDebugLog::s_SnmpDebugLog->WriteFileAndLine(__FILE__,__LINE__,
|
|
L"CCorrCache::BuildCacheAndSetNotify - Finished accessing SMIR Getting Groups\n");
|
|
)
|
|
pTEnumSmirGroup->Release();
|
|
|
|
if (NULL == g_pNotifyInt)
|
|
{
|
|
hr = pInterrogativeInt->QueryInterface(IID_ISMIR_Database,
|
|
(void **) &g_pNotifyInt);
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
if( gp_notify== NULL)
|
|
{
|
|
DWORD dw;
|
|
gp_notify = new CCorrCacheNotify();
|
|
gp_notify->AddRef();
|
|
hr = g_pNotifyInt->AddNotify(gp_notify, &dw);
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
gp_notify->SetCookie(dw);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( gp_notify== NULL)
|
|
{
|
|
DWORD dw;
|
|
gp_notify = new CCorrCacheNotify();
|
|
gp_notify->AddRef();
|
|
hr = g_pNotifyInt->AddNotify(gp_notify, &dw);
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
gp_notify->SetCookie(dw);
|
|
}
|
|
}
|
|
}
|
|
|
|
pInterrogativeInt->Release();
|
|
|
|
if ((NULL == gp_notify) || (0 == gp_notify->GetCookie()))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
#pragma warning (disable:4018)
|
|
|
|
BOOL CCorrCache::BuildRangeTable()
|
|
{
|
|
UINT pos = 0;
|
|
TCorrMaskLength posIndex = 0;
|
|
TCorrMaskLength nextIndex = 1;
|
|
m_groupTable.Sort();
|
|
|
|
DebugMacro6(
|
|
SnmpDebugLog::s_SnmpDebugLog->WriteFileAndLine(__FILE__,__LINE__,
|
|
L"CCorrCache::BuildRangeTable - Printing sorted group table...\n");
|
|
|
|
for (int x = 0; x < m_groupTable.GetSize(); x++)
|
|
{
|
|
CCorrGroupIdItem * i = m_groupTable.GetAt(x);
|
|
i->DebugOutputItem();
|
|
}
|
|
|
|
SnmpDebugLog::s_SnmpDebugLog->WriteFileAndLine(__FILE__,__LINE__,
|
|
L"CCorrCache::BuildRangeTable - Finished printing sorted group table...\n");
|
|
)
|
|
|
|
while (pos < m_groupTable.GetSize())
|
|
{
|
|
UINT nextpos = pos + 1;
|
|
DoGroupEntry(&pos, &nextpos, &posIndex, &nextIndex);
|
|
pos = nextpos;
|
|
posIndex = nextIndex++;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
#pragma warning (default:4018)
|
|
|
|
#pragma warning (disable:4018)
|
|
|
|
void CCorrCache::DoGroupEntry(UINT* current, UINT* next,
|
|
TCorrMaskLength* cIndex, TCorrMaskLength* nIndex)
|
|
{
|
|
CCorrGroupIdItem* alpha = m_groupTable.GetAt(*current);
|
|
CCorrObjectID a;
|
|
alpha->GetGroupID(a);
|
|
CCorrObjectID End(a);
|
|
++End;
|
|
|
|
if (*next < m_groupTable.GetSize())
|
|
{
|
|
CCorrGroupIdItem* beta = m_groupTable.GetAt(*next);
|
|
CCorrObjectID b;
|
|
beta->GetGroupID(b);
|
|
|
|
//check for duplicates
|
|
while ((a == b) && (*next < m_groupTable.GetSize()))
|
|
{
|
|
DebugMacro6(
|
|
SnmpDebugLog::s_SnmpDebugLog->WriteFileAndLine(__FILE__,__LINE__,
|
|
L"Deleting duplicate non MIB2 group... ");
|
|
beta->DebugOutputItem();
|
|
)
|
|
|
|
//add the group handles to the one not being deleted
|
|
while (!beta->m_groupHandles.IsEmpty())
|
|
{
|
|
alpha->m_groupHandles.AddTail(beta->m_groupHandles.RemoveHead());
|
|
}
|
|
|
|
m_groupTable.RemoveAt(*next);
|
|
delete beta;
|
|
beta = m_groupTable.GetAt(*next);
|
|
beta->GetGroupID(b);
|
|
}
|
|
|
|
//after checking for duplicates, check we still meet the initial condition
|
|
if (*next < m_groupTable.GetSize())
|
|
{
|
|
|
|
//if the next item is not a child of this
|
|
if ((a.GetLength() >= b.GetLength()) || (!a.IsSubRange(b)))
|
|
{
|
|
CCorrObjectID c;
|
|
CCorrRangeTableItem* newEntry;
|
|
|
|
if (!m_rangeTable.GetLastEndOID(c) || !a.IsSubRange(c))
|
|
{
|
|
//add whole of a-range to rangetable
|
|
newEntry = new CCorrRangeTableItem(a, End, alpha);
|
|
}
|
|
else
|
|
{
|
|
//add from c to end of a-range to rangetable
|
|
newEntry = new CCorrRangeTableItem(c, End, alpha);
|
|
}
|
|
|
|
newEntry->DebugOutputRange();
|
|
|
|
m_rangeTable.Add(newEntry);
|
|
alpha->SetIndex(*cIndex);
|
|
m_Groups->SetBit(*cIndex);
|
|
}
|
|
else //the next item is a child so add a subrange and do the child - recurse!
|
|
{
|
|
CCorrObjectID c;
|
|
CCorrRangeTableItem* newEntry;
|
|
|
|
if (!m_rangeTable.GetLastEndOID(c) || !a.IsSubRange(c))
|
|
{
|
|
//add start of a-range to start of b to rangetable
|
|
newEntry = new CCorrRangeTableItem(a, b, alpha);
|
|
}
|
|
else
|
|
{
|
|
//add from c to start of b to rangetable
|
|
newEntry = new CCorrRangeTableItem(c, b, alpha);
|
|
}
|
|
|
|
newEntry->DebugOutputRange();
|
|
|
|
m_rangeTable.Add(newEntry);
|
|
UINT temp = (*next)++;
|
|
TCorrMaskLength tempIndex = (*nIndex)++;
|
|
DoGroupEntry(&temp, next, &tempIndex, nIndex);
|
|
|
|
if (*next >= m_groupTable.GetSize())
|
|
{
|
|
m_rangeTable.GetLastEndOID(c);
|
|
////add from c to end of a-range to rangetable
|
|
newEntry = new CCorrRangeTableItem(c, End, alpha);
|
|
m_rangeTable.Add(newEntry);
|
|
alpha->SetIndex(*cIndex);
|
|
m_Groups->SetBit(*cIndex);
|
|
newEntry->DebugOutputRange();
|
|
}
|
|
|
|
//while the new next one(s) is a child add it first - recurse AGAIN!
|
|
while(!m_Groups->IsBitSet(*cIndex))
|
|
{
|
|
DoGroupEntry(current, next, cIndex, nIndex);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//if this is the last item then add it.
|
|
if (*current == m_groupTable.GetUpperBound())
|
|
{
|
|
//add whole of a-range to rangetable
|
|
CCorrRangeTableItem* newEntry = new CCorrRangeTableItem(a, End, alpha);
|
|
m_rangeTable.Add(newEntry);
|
|
alpha->SetIndex(*cIndex);
|
|
m_Groups->SetBit(*cIndex);
|
|
newEntry->DebugOutputRange();
|
|
}
|
|
}
|
|
|
|
#pragma warning (default:4018)
|
|
|
|
void CCorrCache::AddRef()
|
|
{
|
|
m_Lock.Lock();
|
|
m_Ref_Count++;
|
|
m_Lock.Unlock();
|
|
}
|
|
|
|
void CCorrCache::DecRef()
|
|
{
|
|
m_Lock.Lock();
|
|
|
|
if (m_Ref_Count)
|
|
m_Ref_Count--;
|
|
|
|
if (!m_Ref_Count && !m_ValidCache)
|
|
{
|
|
delete this;
|
|
return;
|
|
}
|
|
|
|
m_Lock.Unlock();
|
|
|
|
}
|
|
|
|
|
|
|
|
CCorrEncodedOID::CCorrEncodedOID(IN const CCorrObjectID& src_oid) : m_ids(NULL), m_length(0), m_chopped(0)
|
|
{
|
|
Set(src_oid);
|
|
}
|
|
|
|
void CCorrEncodedOID::Set(IN const CCorrObjectID& src_oid)
|
|
{
|
|
m_chopped = 0;
|
|
UINT x = 0;
|
|
UINT oidlength = src_oid.GetLength();
|
|
|
|
if (oidlength > MAX_OID_LENGTH)
|
|
{
|
|
DebugMacro6(
|
|
SnmpDebugLog::s_SnmpDebugLog->WriteFileAndLine(__FILE__,__LINE__,
|
|
L"CCorrEncodedOID::Set: Truncating OID from %d to %d components", oidlength, MAX_OID_LENGTH);
|
|
)
|
|
oidlength = MAX_OID_LENGTH;
|
|
}
|
|
|
|
if (oidlength)
|
|
{
|
|
UCHAR buff[MAX_OID_LENGTH*MAX_BYTES_PER_FIELD];
|
|
const UINT* oid_ids = src_oid.GetIds();
|
|
|
|
for (UINT i = 0; i < oidlength; i++)
|
|
{
|
|
UINT val = oid_ids[i];
|
|
|
|
//get the top four bits and store in byte
|
|
//BIT7 means next byte is part of this UINT
|
|
if (val >= BIT28)
|
|
{
|
|
buff[x++] = (UCHAR) (BIT7 + ((val & HI4BITS) >> 28));
|
|
}
|
|
|
|
//get the top four bits and store in byte
|
|
//BIT7 means next byte is part of this UINT
|
|
if (val >= BIT21)
|
|
{
|
|
buff[x++] = BIT7 + ((val & HIMID7BITS) >> 21);
|
|
}
|
|
|
|
//get the top four bits and store in byte
|
|
//BIT7 means next byte is part of this UINT
|
|
if (val >= BIT14)
|
|
{
|
|
buff[x++] = BIT7 + ((val & MID7BITS) >> 14);
|
|
}
|
|
|
|
//get the top four bits and store in byte
|
|
//BIT7 means next byte is part of this UINT
|
|
if (val >= BIT7)
|
|
{
|
|
buff[x++] = BIT7 + ((val & LOMID7BITS) >> 7);
|
|
}
|
|
|
|
//get the next seven bits and store in byte
|
|
buff[x++] = (val & LO7BITS);
|
|
}
|
|
|
|
//Remove the standard 1.3.6.1 if necessary...
|
|
if ((1 == buff[0]) && (3 == buff[1]) &&
|
|
(6 == buff[2]) && (1 == buff[3]))
|
|
{
|
|
m_chopped = 1;
|
|
m_ids = new UCHAR[x-4];
|
|
m_length = x-4;
|
|
memcpy(m_ids, &buff[4], m_length*sizeof(UCHAR));
|
|
}
|
|
else
|
|
{
|
|
m_ids = new UCHAR[x];
|
|
m_length = x;
|
|
memcpy(m_ids, buff, m_length*sizeof(UCHAR));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_ids = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
void CCorrEncodedOID::ExtractOID(OUT CCorrObjectID& src_oid) const
|
|
{
|
|
if (m_length)
|
|
{
|
|
UINT buff[MAX_OID_LENGTH];
|
|
UINT x = 0;
|
|
|
|
//Add the standard 1.3.6.1 if necessary...
|
|
if (m_chopped == 1)
|
|
{
|
|
buff[0] = 1;
|
|
buff[1] = 3;
|
|
buff[2] = 6;
|
|
buff[3] = 1;
|
|
x = 4;
|
|
}
|
|
|
|
for (UINT i = 0; (i < m_length) && (x < MAX_OID_LENGTH); i++)
|
|
{
|
|
//extract the value of the byte
|
|
buff[x] = m_ids[i] & LO7BITS;
|
|
|
|
//are there more bytes for this UINT
|
|
while ((i < m_length) && (m_ids[i] & 128))
|
|
{
|
|
//shift the value by a "byte" and extract tbe next byte.
|
|
buff[x] = buff[x] << 7;
|
|
buff[x] += m_ids[++i] & LO7BITS;
|
|
}
|
|
|
|
x++;
|
|
|
|
if ((x == MAX_OID_LENGTH) && (i < m_length))
|
|
{
|
|
DebugMacro6(
|
|
SnmpDebugLog::s_SnmpDebugLog->WriteFileAndLine(__FILE__,__LINE__,
|
|
L"CCorrEncodedOID::ExtractOID: Truncating OID %d components - SHOULD NEVER HAPPEN", MAX_OID_LENGTH);
|
|
)
|
|
}
|
|
}
|
|
|
|
src_oid.Set(buff, x);
|
|
}
|
|
else
|
|
{
|
|
src_oid.Set(NULL, 0);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
CCorrEncodedOID::~CCorrEncodedOID()
|
|
{
|
|
delete [] m_ids;
|
|
}
|
|
|
|
CCorrCacheWrapper::CCorrCacheWrapper(IN CCorrCache* cachePtr) : m_lockit(NULL)
|
|
{
|
|
m_lockit = new CCriticalSection();
|
|
m_CachePtr = cachePtr;
|
|
}
|
|
|
|
CCorrCache* CCorrCacheWrapper::GetCache()
|
|
{
|
|
m_lockit->Lock();
|
|
return m_CachePtr;
|
|
}
|
|
|
|
CCorrCacheWrapper::~CCorrCacheWrapper()
|
|
{
|
|
delete m_lockit;
|
|
}
|