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.

1499 lines
29 KiB

  1. // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
  2. #include "precomp.h"
  3. #include <provexpt.h>
  4. #include <cordefs.h>
  5. #include <corafx.h>
  6. #include <objbase.h>
  7. #include <wbemidl.h>
  8. #include <smir.h>
  9. #include <corstore.h>
  10. #include <notify.h>
  11. #include <snmplog.h>
  12. #include <autoptr.h>
  13. extern ISmirDatabase* g_pNotifyInt;
  14. extern CCorrCacheNotify *gp_notify;
  15. CCorrGroupArray::CCorrGroupArray()
  16. {
  17. SetSize(0, 10000);
  18. }
  19. int _cdecl compare( const void *arg1, const void *arg2 )
  20. {
  21. CCorrObjectID tmp1;
  22. (*(CCorrGroupIdItem**)arg1)->GetGroupID(tmp1);
  23. CCorrObjectID tmp2;
  24. (*(CCorrGroupIdItem**)arg2)->GetGroupID(tmp2);
  25. switch (tmp1.CompareWith(tmp2))
  26. {
  27. case ECorrAreEqual:
  28. break;
  29. case ECorrFirstLess:
  30. return -1;
  31. case ECorrFirstGreater:
  32. return 1;
  33. }
  34. return 0;
  35. }
  36. void CCorrGroupArray::Sort()
  37. {
  38. if (GetSize())
  39. {
  40. //CObject** temp = GetData();
  41. qsort((void *)GetData(), (size_t)GetSize(),
  42. sizeof( CCorrGroupIdItem * ), compare );
  43. }
  44. FreeExtra();
  45. }
  46. //============================================================================
  47. // CCorrGroupArray::~CCorrGroupArray
  48. //
  49. // This is the CCorrGroupArray class's only desstructor. If there are any items in
  50. // the queue they are deleted.
  51. //
  52. //
  53. // Parameters:
  54. //
  55. // none
  56. //
  57. // Returns:
  58. //
  59. // none
  60. //
  61. //============================================================================
  62. CCorrGroupArray::~CCorrGroupArray()
  63. {
  64. for (int x = 0; x < GetSize(); x++)
  65. {
  66. CCorrGroupIdItem * item = GetAt(x);
  67. delete item;
  68. }
  69. RemoveAll();
  70. }
  71. //============================================================================
  72. // CCorrGroupIdItem::CCorrGroupIdItem
  73. //
  74. // This is the CCorrGroupIdItem class's only constructor. This class is derived from
  75. // the CObject class. This is so the MFC template storage classes can be
  76. // used. It is used to store a CString value in a list.
  77. //
  78. //
  79. // Parameters:
  80. //
  81. // CString * str A pointer to the CString object to be stored.
  82. //
  83. // Returns:
  84. //
  85. // none
  86. //
  87. //============================================================================
  88. CCorrGroupIdItem::CCorrGroupIdItem(IN const CCorrObjectID& ID, IN ISmirGroupHandle* grpH)
  89. : m_groupId(ID)
  90. {
  91. m_index = 0;
  92. if (grpH)
  93. {
  94. m_groupHandles.AddHead(grpH);
  95. }
  96. }
  97. void CCorrGroupIdItem::GetGroupID(OUT CCorrObjectID& ID) const
  98. {
  99. m_groupId.ExtractOID(ID);
  100. }
  101. void CCorrGroupIdItem::DebugOutputItem(CString* msg) const
  102. {
  103. CString debugstr;
  104. CCorrObjectID tmp;
  105. m_groupId.ExtractOID(tmp);
  106. tmp.GetString(debugstr);
  107. if (!debugstr.GetLength())
  108. {
  109. debugstr = L"Error retrieving Group Object OID";
  110. }
  111. if (msg)
  112. {
  113. debugstr += L"\t\t:\t";
  114. debugstr += *msg;
  115. }
  116. debugstr += L"\n";
  117. DebugMacro6(
  118. SnmpDebugLog::s_SnmpDebugLog->WriteFileAndLine(__FILE__,__LINE__,
  119. debugstr);
  120. )
  121. }
  122. //============================================================================
  123. // CCorrGroupIdItem::~CCorrGroupIdItem
  124. //
  125. // This is the CCorrGroupIdItem class's only destructor. It frees the memory used
  126. // to store the CString members.
  127. //
  128. //
  129. // Parameters:
  130. //
  131. // none
  132. //
  133. // Returns:
  134. //
  135. // none
  136. //
  137. //============================================================================
  138. CCorrGroupIdItem::~CCorrGroupIdItem()
  139. {
  140. while (!m_groupHandles.IsEmpty())
  141. {
  142. (m_groupHandles.RemoveHead())->Release();
  143. }
  144. }
  145. CCorrObjectID::CCorrObjectID(IN const CCorrObjectID& ID) : m_Ids(NULL)
  146. {
  147. m_length = ID.m_length;
  148. if (m_length)
  149. {
  150. m_Ids = new UINT[m_length];
  151. memcpy(m_Ids, ID.m_Ids, m_length*sizeof(UINT));
  152. }
  153. }
  154. CCorrObjectID::CCorrObjectID(IN const char* str) : m_Ids(NULL)
  155. {
  156. m_length = 0;
  157. if (NULL != str)
  158. {
  159. size_t InputLen = strlen(str);
  160. if (InputLen > MAX_OID_STRING) return; //string is too long.
  161. char temp[MAX_OID_STRING + 1];
  162. strcpy(temp, str);
  163. BOOL bad = FALSE;
  164. char* temp1 = temp;
  165. UINT temp2[MAX_OID_LENGTH];
  166. CString dot(".");
  167. if (dot.GetAt(0) == temp[0])
  168. {
  169. temp1++;
  170. }
  171. istrstream istr(temp1);
  172. char d;
  173. istr >> temp2[0];
  174. m_length++;
  175. if (istr.bad() || istr.fail())
  176. {
  177. bad = TRUE;
  178. }
  179. while(!istr.eof() && !bad)
  180. {
  181. istr >> d;
  182. if (istr.bad() || istr.fail())
  183. {
  184. bad = TRUE;
  185. }
  186. if (d != dot.GetAt(0))
  187. {
  188. bad = TRUE;
  189. }
  190. if (m_length < MAX_OID_LENGTH)
  191. {
  192. istr >> temp2[m_length++];
  193. if (istr.bad() || istr.fail())
  194. {
  195. bad = TRUE;
  196. }
  197. }
  198. else
  199. {
  200. bad = TRUE;
  201. }
  202. }
  203. if (!bad)
  204. {
  205. m_Ids = new UINT[m_length];
  206. memcpy(m_Ids, temp2, m_length*sizeof(UINT));
  207. }
  208. else
  209. {
  210. m_length = 0;
  211. }
  212. }
  213. }
  214. CCorrObjectID::CCorrObjectID(IN const UINT* ids, IN const UINT len) : m_Ids(NULL)
  215. {
  216. if (len <= MAX_OID_LENGTH)
  217. {
  218. m_length = len;
  219. }
  220. else
  221. {
  222. m_length = 0;
  223. }
  224. if (m_length)
  225. {
  226. m_Ids = new UINT[m_length];
  227. memcpy(m_Ids, ids, m_length*sizeof(UINT));
  228. }
  229. }
  230. void CCorrObjectID::Set(IN const UINT* ids, IN const UINT len)
  231. {
  232. if (m_length)
  233. {
  234. delete [] m_Ids;
  235. }
  236. if (len <= MAX_OID_LENGTH)
  237. {
  238. m_length = len;
  239. }
  240. else
  241. {
  242. m_length = 0;
  243. }
  244. if (m_length)
  245. {
  246. m_Ids = new UINT[m_length];
  247. memcpy(m_Ids, ids, m_length*sizeof(UINT));
  248. }
  249. else
  250. {
  251. m_Ids = NULL;
  252. }
  253. }
  254. char* CCorrObjectID::GetString() const
  255. {
  256. char * ret = NULL;
  257. if (m_length)
  258. {
  259. ret = new char[BYTES_PER_FIELD*m_length];
  260. ostrstream s(ret, BYTES_PER_FIELD*m_length);
  261. s << m_Ids[0];
  262. UINT i = 1;
  263. char dot = '.';
  264. while (i < m_length)
  265. {
  266. s << dot << m_Ids[i++];
  267. }
  268. s << ends;
  269. }
  270. return ret;
  271. }
  272. #define AVERAGE_OID_LENGTH 20
  273. wchar_t* CCorrObjectID::GetWideString() const
  274. {
  275. wchar_t *returnValue = NULL ;
  276. ULONG totalLength = 0 ;
  277. ULONG reallocLength = AVERAGE_OID_LENGTH ;
  278. wchar_t *reallocArray = new wchar_t [ reallocLength ] ;
  279. if (reallocArray == NULL)
  280. {
  281. throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  282. }
  283. wmilib::auto_ptr<WCHAR> t_ReallocWrap ( reallocArray );
  284. ULONG objectIdentifierLength = m_length ;
  285. ULONG index = 0 ;
  286. while ( index < objectIdentifierLength )
  287. {
  288. wchar_t stringValue [ 40 ] ;
  289. _ultow ( m_Ids [ index ] , stringValue , 10 );
  290. ULONG stringLength = wcslen ( stringValue ) ;
  291. if ( ( totalLength + stringLength + 1 ) >= reallocLength )
  292. {
  293. ULONG t_Max = max( stringLength + 1 , AVERAGE_OID_LENGTH ) ;
  294. reallocLength = reallocLength + t_Max ;
  295. wchar_t *t_newReallocArray = new wchar_t [ reallocLength ] ;
  296. CopyMemory ( t_newReallocArray , t_ReallocWrap.get () , totalLength * sizeof ( wchar_t ) ) ;
  297. t_ReallocWrap.reset ( t_newReallocArray ) ;
  298. }
  299. wcscpy ( & ( t_ReallocWrap.get () [ totalLength ] ) , stringValue ) ;
  300. totalLength = totalLength + stringLength ;
  301. index ++ ;
  302. if ( index < objectIdentifierLength )
  303. {
  304. if ( ( totalLength + 1 + 1 ) >= reallocLength )
  305. {
  306. reallocLength = reallocLength + AVERAGE_OID_LENGTH ;
  307. wchar_t *t_newReallocArray = new wchar_t [ reallocLength ] ;
  308. CopyMemory ( t_newReallocArray , t_ReallocWrap.get () , totalLength * sizeof ( wchar_t ) ) ;
  309. t_ReallocWrap.reset ( t_newReallocArray ) ;
  310. }
  311. wcscpy ( & ( t_ReallocWrap.get ()[ totalLength ] ) , L"." ) ;
  312. totalLength ++ ;
  313. }
  314. }
  315. returnValue = new wchar_t [ totalLength + 1 ] ;
  316. if ( objectIdentifierLength )
  317. {
  318. wcscpy ( returnValue , t_ReallocWrap.get () ) ;
  319. }
  320. else
  321. {
  322. returnValue [ 0 ] = 0 ;
  323. }
  324. return returnValue ;
  325. }
  326. void CCorrObjectID::GetString(CString& str) const
  327. {
  328. wchar_t* oid = GetWideString();
  329. try
  330. {
  331. str = oid;
  332. }
  333. catch(...)
  334. {
  335. delete [] oid;
  336. throw;
  337. }
  338. delete [] oid;
  339. }
  340. ECorrCompResult CCorrObjectID::CompareWith(IN const CCorrObjectID& second) const
  341. {
  342. if (0 == m_length)
  343. {
  344. if (0 == second.m_length)
  345. {
  346. return ECorrAreEqual;
  347. }
  348. else
  349. {
  350. return ECorrFirstLess;
  351. }
  352. }
  353. if (0 == second.m_length)
  354. {
  355. return ECorrFirstGreater;
  356. }
  357. ECorrCompResult res = ECorrAreEqual;
  358. if (m_length <= second.m_length)
  359. {
  360. for (UINT i = 0; i < m_length; i++)
  361. {
  362. if (m_Ids[i] != second.m_Ids[i])
  363. {
  364. if (m_Ids[i] < second.m_Ids[i])
  365. {
  366. return ECorrFirstLess;
  367. }
  368. else
  369. {
  370. return ECorrFirstGreater;
  371. }
  372. }
  373. }
  374. if (m_length < second.m_length)
  375. {
  376. res = ECorrFirstLess;
  377. }
  378. }
  379. else
  380. {
  381. for (UINT i = 0; i < second.m_length; i++)
  382. {
  383. if (m_Ids[i] != second.m_Ids[i])
  384. {
  385. if (m_Ids[i] < second.m_Ids[i])
  386. {
  387. return ECorrFirstLess;
  388. }
  389. else
  390. {
  391. return ECorrFirstGreater;
  392. }
  393. }
  394. }
  395. res = ECorrFirstGreater;
  396. }
  397. return res;
  398. }
  399. BOOL CCorrObjectID::IsSubRange(IN const CCorrObjectID& child) const
  400. {
  401. if (m_length >= child.m_length)
  402. {
  403. return FALSE;
  404. }
  405. for (UINT i=0; i<m_length; i++)
  406. {
  407. if (m_Ids[i] != child.m_Ids[i])
  408. {
  409. return FALSE;
  410. }
  411. }
  412. return TRUE;
  413. }
  414. BOOL CCorrObjectID::operator ==(IN const CCorrObjectID& second) const
  415. {
  416. if (ECorrAreEqual == CompareWith(second))
  417. {
  418. return TRUE;
  419. }
  420. else
  421. {
  422. return FALSE;
  423. }
  424. }
  425. BOOL CCorrObjectID::operator !=(IN const CCorrObjectID& second) const
  426. {
  427. if (ECorrAreEqual == CompareWith(second))
  428. {
  429. return FALSE;
  430. }
  431. else
  432. {
  433. return TRUE;
  434. }
  435. }
  436. BOOL CCorrObjectID::operator <(IN const CCorrObjectID& second) const
  437. {
  438. if (ECorrFirstLess == CompareWith(second))
  439. {
  440. return TRUE;
  441. }
  442. else
  443. {
  444. return FALSE;
  445. }
  446. }
  447. BOOL CCorrObjectID::operator >(IN const CCorrObjectID& second) const
  448. {
  449. if (ECorrFirstGreater == CompareWith(second))
  450. {
  451. return TRUE;
  452. }
  453. else
  454. {
  455. return FALSE;
  456. }
  457. }
  458. BOOL CCorrObjectID::operator <=(IN const CCorrObjectID& second) const
  459. {
  460. ECorrCompResult res = CompareWith(second);
  461. if ((ECorrAreEqual == res) || (ECorrFirstLess == res))
  462. {
  463. return TRUE;
  464. }
  465. else
  466. {
  467. return FALSE;
  468. }
  469. }
  470. BOOL CCorrObjectID::operator >=(IN const CCorrObjectID& second) const
  471. {
  472. ECorrCompResult res = CompareWith(second);
  473. if ((ECorrAreEqual == res) || (ECorrFirstGreater == res))
  474. {
  475. return TRUE;
  476. }
  477. else
  478. {
  479. return FALSE;
  480. }
  481. }
  482. CCorrObjectID& CCorrObjectID::operator =(IN const CCorrObjectID& ID)
  483. {
  484. if (m_length)
  485. {
  486. delete [] m_Ids;
  487. }
  488. m_length = ID.m_length;
  489. if (m_length)
  490. {
  491. m_Ids = new UINT[m_length];
  492. memcpy(m_Ids, ID.m_Ids, m_length*sizeof(UINT));
  493. }
  494. else
  495. {
  496. m_Ids = NULL;
  497. }
  498. return *this;
  499. }
  500. CCorrObjectID& CCorrObjectID::operator +=(IN const CCorrObjectID& ID)
  501. {
  502. if((m_length + ID.m_length) > MAX_OID_LENGTH)
  503. {
  504. if(m_length)
  505. {
  506. delete [] m_Ids;
  507. m_Ids = NULL;
  508. }
  509. m_length = 0;
  510. }
  511. else
  512. {
  513. if (ID.m_length)
  514. {
  515. UINT* newIds = new UINT[m_length + ID.m_length];
  516. if(m_length)
  517. {
  518. memcpy(newIds, m_Ids, m_length*sizeof(UINT));
  519. delete [] m_Ids;
  520. m_Ids = NULL;
  521. }
  522. memcpy(&(newIds[m_length]), ID.m_Ids, ID.m_length*sizeof(UINT));
  523. m_Ids = newIds;
  524. m_length += ID.m_length;
  525. }
  526. }
  527. return *this;
  528. }
  529. CCorrObjectID& CCorrObjectID::operator ++()
  530. {
  531. if (m_length)
  532. {
  533. m_Ids[m_length - 1]++;
  534. }
  535. return *this;
  536. }
  537. CCorrObjectID& CCorrObjectID::operator --()
  538. {
  539. if (m_length)
  540. {
  541. m_Ids[m_length - 1]--;
  542. }
  543. return *this;
  544. }
  545. CCorrObjectID& CCorrObjectID::operator -=(IN const UINT sub)
  546. {
  547. if (sub && (m_length > sub))
  548. {
  549. m_length -= sub;
  550. UINT* newIds = new UINT[m_length];
  551. memcpy(newIds, m_Ids, m_length*sizeof(UINT));
  552. delete [] m_Ids;
  553. m_Ids = newIds;
  554. }
  555. else if (sub == m_length)
  556. {
  557. m_length = 0;
  558. delete [] m_Ids;
  559. m_Ids = NULL;
  560. }
  561. return *this;
  562. }
  563. CCorrObjectID& CCorrObjectID::operator /=(IN const UINT sub)
  564. {
  565. if (sub && (m_length > sub))
  566. {
  567. m_length -= sub;
  568. UINT* newIds = new UINT[m_length];
  569. memcpy(newIds, &(m_Ids[sub]), m_length*sizeof(UINT));
  570. delete [] m_Ids;
  571. m_Ids = newIds;
  572. }
  573. else if (sub == m_length)
  574. {
  575. m_length = 0;
  576. delete [] m_Ids;
  577. m_Ids = NULL;
  578. }
  579. return *this;
  580. }
  581. CCorrObjectID::~CCorrObjectID()
  582. {
  583. if (m_length)
  584. {
  585. delete [] m_Ids;
  586. }
  587. }
  588. //============================================================================
  589. // CCorrRangeTableItem::CCorrRangeTableItem
  590. //
  591. // This is the CCorrRangeTableItem class's only constructor. This class is derived from
  592. // the CObject class. This is so the MFC template storage classes can be
  593. // used. It is used to store a CString value in a list.
  594. //
  595. //
  596. // Parameters:
  597. //
  598. // CString * str A pointer to the CString object to be stored.
  599. //
  600. // Returns:
  601. //
  602. // none
  603. //
  604. //============================================================================
  605. CCorrRangeTableItem::CCorrRangeTableItem(IN const CCorrObjectID& startID,
  606. IN const CCorrObjectID& endID,
  607. IN CCorrGroupIdItem* grpID)
  608. {
  609. m_groupId = grpID;
  610. CCorrObjectID temp;
  611. m_groupId->GetGroupID(temp);
  612. CCorrObjectID startRange = startID;
  613. startRange /= temp.GetLength();
  614. CCorrObjectID endRange = endID;
  615. endRange /= (temp.GetLength() - 1);
  616. m_startRange.Set(startRange);
  617. m_endRange.Set(endRange);
  618. }
  619. //============================================================================
  620. // CCorrRangeTableItem::~CCorrRangeTableItem
  621. //
  622. // This is the CCorrRangeTableItem class's only destructor. It frees the memory used
  623. // to store the CString members.
  624. //
  625. //
  626. // Parameters:
  627. //
  628. // none
  629. //
  630. // Returns:
  631. //
  632. // none
  633. //
  634. //============================================================================
  635. CCorrRangeTableItem::~CCorrRangeTableItem()
  636. {
  637. }
  638. BOOL CCorrRangeTableItem::GetStartRange(OUT CCorrObjectID& start) const
  639. {
  640. if (!m_groupId)
  641. return FALSE;
  642. m_groupId->GetGroupID(start);
  643. CCorrObjectID tmp;
  644. m_startRange.ExtractOID(tmp);
  645. start += tmp;
  646. return TRUE;
  647. }
  648. BOOL CCorrRangeTableItem::GetEndRange(OUT CCorrObjectID& end) const
  649. {
  650. if (!m_groupId)
  651. return FALSE;
  652. m_groupId->GetGroupID(end);
  653. end -= 1;
  654. CCorrObjectID tmp;
  655. m_endRange.ExtractOID(tmp);
  656. end += tmp;
  657. return TRUE;
  658. }
  659. CCorrRangeTableItem::ECorrRangeResult CCorrRangeTableItem::
  660. IsInRange(IN const CCorrObjectID& ID) const
  661. {
  662. CCorrObjectID a;
  663. GetStartRange(a);
  664. if (ID == a)
  665. {
  666. return ECorrEqualToStart;
  667. }
  668. if (ID < a)
  669. {
  670. return ECorrBeforeStart;
  671. }
  672. CCorrObjectID b;
  673. GetEndRange(b);
  674. if (ID == b)
  675. {
  676. return ECorrEqualToEnd;
  677. }
  678. if (ID > b)
  679. {
  680. return ECorrAfterEnd;
  681. }
  682. return ECorrInRange;
  683. }
  684. void CCorrRangeTableItem::DebugOutputRange() const
  685. {
  686. DebugMacro6(
  687. if (m_groupId)
  688. {
  689. CString debugstr;
  690. CCorrObjectID tmp;
  691. m_groupId->GetGroupID(tmp);
  692. tmp.GetString(debugstr);
  693. CString out1;
  694. CCorrObjectID start;
  695. GetStartRange(start);
  696. start.GetString(out1);
  697. CString out2;
  698. CCorrObjectID end;
  699. GetEndRange(end);
  700. end.GetString(out2);
  701. debugstr += "\t\t:\t\t";
  702. debugstr += out1;
  703. debugstr += "\t\t:\t\t";
  704. debugstr += out2;
  705. debugstr += "\t\tGroup : Start : End\n";
  706. SnmpDebugLog::s_SnmpDebugLog->WriteFileAndLine(__FILE__,__LINE__,
  707. debugstr);
  708. }
  709. else
  710. {
  711. SnmpDebugLog::s_SnmpDebugLog->WriteFileAndLine(__FILE__,__LINE__,
  712. L"Attempt to output empty RangeTableItem\n");
  713. }
  714. )
  715. }
  716. //============================================================================
  717. // CCorrRangeList::~CCorrRangeList
  718. //
  719. // This is the CCorrRangeList class's only desstructor. If there are any items in
  720. // the queue they are deleted.
  721. //
  722. //
  723. // Parameters:
  724. //
  725. // none
  726. //
  727. // Returns:
  728. //
  729. // none
  730. //
  731. //============================================================================
  732. CCorrRangeList::~CCorrRangeList()
  733. {
  734. while(!IsEmpty())
  735. {
  736. CCorrRangeTableItem * item = RemoveHead();
  737. delete item;
  738. }
  739. }
  740. //============================================================================
  741. // CCorrRangeList::Add
  742. //
  743. // This public method is called to add a CCorrRangeTableItem into this CCorrRangeList. The
  744. // CCorrRangeTableItem is not added if it is already present in the list. If this is the
  745. // case a pointer to the matching item in the list is returned.
  746. //
  747. //
  748. // Parameters:
  749. //
  750. // CCorrRangeTableItem * newItem A pointer to the CCorrRangeTableItem to be added.
  751. //
  752. // Returns:
  753. //
  754. // CCorrRangeTableItem * A pointer to the item if is in the list. NULL if
  755. // the item was not found and was added.
  756. //
  757. //============================================================================
  758. BOOL CCorrRangeList::Add(IN CCorrRangeTableItem* newItem)
  759. {
  760. AddTail(newItem); //empty or all items smaller
  761. return TRUE;
  762. }
  763. BOOL CCorrRangeList::GetLastEndOID(OUT CCorrObjectID& end) const
  764. {
  765. if (IsEmpty())
  766. {
  767. return FALSE;
  768. }
  769. return (GetTail()->GetEndRange(end));
  770. }
  771. CCorrGroupMask::CCorrGroupMask(IN const TCorrMaskLength sze) : m_mask(NULL)
  772. {
  773. m_size = sze;
  774. if (m_size)
  775. {
  776. TCorrMaskLength x = m_size / (sizeof(TCorrMaskUnit)*BITS_PER_BYTE);
  777. if (m_size % (sizeof(TCorrMaskUnit)*BITS_PER_BYTE))
  778. {
  779. x++;
  780. }
  781. m_mask = new TCorrMaskUnit[x];
  782. ZeroMemory((PVOID)m_mask, (DWORD)(sizeof(TCorrMaskUnit)*x));
  783. }
  784. }
  785. BOOL CCorrGroupMask::IsBitSet(IN const TCorrMaskLength bit)const
  786. {
  787. TCorrMaskLength x = bit / (sizeof(TCorrMaskUnit)*BITS_PER_BYTE);
  788. TCorrMaskLength val = bit % (sizeof(TCorrMaskUnit)*BITS_PER_BYTE);
  789. return (((m_mask[x] >> val) & 1) == 1);
  790. }
  791. void CCorrGroupMask::SetBit(IN const TCorrMaskLength bit, IN const BOOL On)
  792. {
  793. BOOL IsBit = IsBitSet(bit);
  794. if ((IsBit && On) || (!IsBit && !On))
  795. {
  796. return;
  797. }
  798. else
  799. {
  800. TCorrMaskLength x = bit / (sizeof(TCorrMaskUnit)*BITS_PER_BYTE);
  801. TCorrMaskLength val = bit % (sizeof(TCorrMaskUnit)*BITS_PER_BYTE);
  802. TCorrMaskLength maskval = 1;
  803. maskval <<= val;
  804. if (On)
  805. {
  806. m_mask[x] += maskval;
  807. }
  808. else
  809. {
  810. m_mask[x] -= maskval;
  811. }
  812. }
  813. }
  814. CCorrGroupMask::~CCorrGroupMask()
  815. {
  816. if (m_mask)
  817. {
  818. delete [] m_mask;
  819. }
  820. }
  821. CCorrCache::CCorrCache( ISmirInterrogator *a_ISmirInterrogator ) : m_Groups (NULL)
  822. {
  823. m_ValidCache = TRUE;
  824. m_Ref_Count = 0;
  825. m_size = 0;
  826. BuildCacheAndSetNotify( a_ISmirInterrogator );
  827. if (m_groupTable.GetSize())
  828. {
  829. m_Groups = new CCorrGroupMask(m_size);
  830. BuildRangeTable();
  831. }
  832. }
  833. CCorrCache::~CCorrCache()
  834. {
  835. if (m_Groups)
  836. {
  837. delete m_Groups;
  838. }
  839. }
  840. void CCorrCache::InvalidateCache()
  841. {
  842. m_Lock.Lock();
  843. if (!m_Ref_Count)
  844. {
  845. delete this;
  846. }
  847. else
  848. {
  849. m_ValidCache = FALSE;
  850. m_Lock.Unlock();
  851. }
  852. }
  853. BOOL CCorrCache::BuildCacheAndSetNotify( ISmirInterrogator *a_ISmirInterrogator )
  854. {
  855. LPUNKNOWN pInterrogativeInt = NULL;
  856. // ===============================================================
  857. // The following relies on the current thread having been
  858. // initialised for OLE (i.e. by the use of CoInitialize)
  859. // ===============================================================
  860. HRESULT hr = S_OK ;
  861. if ( a_ISmirInterrogator )
  862. {
  863. hr = a_ISmirInterrogator->QueryInterface (
  864. IID_ISMIR_Interrogative, (void**)&pInterrogativeInt
  865. );
  866. }
  867. else
  868. {
  869. hr = CoCreateInstance (CLSID_SMIR_Database,
  870. NULL, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
  871. IID_ISMIR_Interrogative, (void**)&pInterrogativeInt);
  872. }
  873. if (NULL == pInterrogativeInt)
  874. {
  875. return FALSE;
  876. }
  877. IEnumGroup *pTEnumSmirGroup = NULL;
  878. //enum all groups
  879. hr = ((ISmirInterrogator*)pInterrogativeInt)->EnumGroups(&pTEnumSmirGroup, NULL);
  880. //now use the enumerator
  881. if(NULL == pTEnumSmirGroup)
  882. {
  883. pInterrogativeInt->Release();
  884. return FALSE;
  885. }
  886. ISmirGroupHandle *phModule=NULL;
  887. DebugMacro6(
  888. SnmpDebugLog::s_SnmpDebugLog->WriteFileAndLine(__FILE__,__LINE__,
  889. L"CCorrCache::BuildCacheAndSetNotify - Accessing SMIR Getting Groups\n");
  890. )
  891. for(int iCount=0; S_OK == pTEnumSmirGroup->Next(1, &phModule, NULL); iCount++)
  892. {
  893. //DO SOMETHING WITH THE GROUP HANDLE
  894. //eg get the name
  895. BSTR szName=NULL;
  896. char buff[1024];
  897. LPSTR pbuff = buff;
  898. int lbuff = sizeof(buff);
  899. phModule->GetGroupOID(&szName);
  900. if (FALSE == WideCharToMultiByte(CP_ACP, 0,
  901. szName, -1, pbuff, lbuff, NULL, NULL))
  902. {
  903. DWORD lasterr = GetLastError();
  904. SysFreeString(szName);
  905. phModule->Release();
  906. DebugMacro6(
  907. SnmpDebugLog::s_SnmpDebugLog->WriteFileAndLine(__FILE__,__LINE__,
  908. L"CCorrCache::BuildCacheAndSetNotify - Error bad BSTR conversion\n");
  909. )
  910. continue;
  911. }
  912. SysFreeString(szName);
  913. CCorrObjectID grpId(buff);
  914. CCorrObjectID zero;
  915. if (zero != grpId)
  916. {
  917. CCorrGroupIdItem* groupId = new CCorrGroupIdItem(grpId, phModule);
  918. m_groupTable.Add(groupId);
  919. m_size++;
  920. }
  921. DebugMacro6(
  922. SnmpDebugLog::s_SnmpDebugLog->WriteFileAndLine(__FILE__,__LINE__,
  923. L"%s\n", buff);
  924. )
  925. }
  926. DebugMacro6(
  927. SnmpDebugLog::s_SnmpDebugLog->WriteFileAndLine(__FILE__,__LINE__,
  928. L"CCorrCache::BuildCacheAndSetNotify - Finished accessing SMIR Getting Groups\n");
  929. )
  930. pTEnumSmirGroup->Release();
  931. if (NULL == g_pNotifyInt)
  932. {
  933. hr = pInterrogativeInt->QueryInterface(IID_ISMIR_Database,
  934. (void **) &g_pNotifyInt);
  935. if(SUCCEEDED(hr))
  936. {
  937. if( gp_notify== NULL)
  938. {
  939. DWORD dw;
  940. gp_notify = new CCorrCacheNotify();
  941. gp_notify->AddRef();
  942. hr = g_pNotifyInt->AddNotify(gp_notify, &dw);
  943. if(SUCCEEDED(hr))
  944. {
  945. gp_notify->SetCookie(dw);
  946. }
  947. }
  948. }
  949. }
  950. else
  951. {
  952. if( gp_notify== NULL)
  953. {
  954. DWORD dw;
  955. gp_notify = new CCorrCacheNotify();
  956. gp_notify->AddRef();
  957. hr = g_pNotifyInt->AddNotify(gp_notify, &dw);
  958. if(SUCCEEDED(hr))
  959. {
  960. gp_notify->SetCookie(dw);
  961. }
  962. }
  963. }
  964. pInterrogativeInt->Release();
  965. if ((NULL == gp_notify) || (0 == gp_notify->GetCookie()))
  966. {
  967. return FALSE;
  968. }
  969. return TRUE;
  970. }
  971. #pragma warning (disable:4018)
  972. BOOL CCorrCache::BuildRangeTable()
  973. {
  974. UINT pos = 0;
  975. TCorrMaskLength posIndex = 0;
  976. TCorrMaskLength nextIndex = 1;
  977. m_groupTable.Sort();
  978. DebugMacro6(
  979. SnmpDebugLog::s_SnmpDebugLog->WriteFileAndLine(__FILE__,__LINE__,
  980. L"CCorrCache::BuildRangeTable - Printing sorted group table...\n");
  981. for (int x = 0; x < m_groupTable.GetSize(); x++)
  982. {
  983. CCorrGroupIdItem * i = m_groupTable.GetAt(x);
  984. i->DebugOutputItem();
  985. }
  986. SnmpDebugLog::s_SnmpDebugLog->WriteFileAndLine(__FILE__,__LINE__,
  987. L"CCorrCache::BuildRangeTable - Finished printing sorted group table...\n");
  988. )
  989. while (pos < m_groupTable.GetSize())
  990. {
  991. UINT nextpos = pos + 1;
  992. DoGroupEntry(&pos, &nextpos, &posIndex, &nextIndex);
  993. pos = nextpos;
  994. posIndex = nextIndex++;
  995. }
  996. return TRUE;
  997. }
  998. #pragma warning (default:4018)
  999. #pragma warning (disable:4018)
  1000. void CCorrCache::DoGroupEntry(UINT* current, UINT* next,
  1001. TCorrMaskLength* cIndex, TCorrMaskLength* nIndex)
  1002. {
  1003. CCorrGroupIdItem* alpha = m_groupTable.GetAt(*current);
  1004. CCorrObjectID a;
  1005. alpha->GetGroupID(a);
  1006. CCorrObjectID End(a);
  1007. ++End;
  1008. if (*next < m_groupTable.GetSize())
  1009. {
  1010. CCorrGroupIdItem* beta = m_groupTable.GetAt(*next);
  1011. CCorrObjectID b;
  1012. beta->GetGroupID(b);
  1013. //check for duplicates
  1014. while ((a == b) && (*next < m_groupTable.GetSize()))
  1015. {
  1016. DebugMacro6(
  1017. SnmpDebugLog::s_SnmpDebugLog->WriteFileAndLine(__FILE__,__LINE__,
  1018. L"Deleting duplicate non MIB2 group... ");
  1019. beta->DebugOutputItem();
  1020. )
  1021. //add the group handles to the one not being deleted
  1022. while (!beta->m_groupHandles.IsEmpty())
  1023. {
  1024. alpha->m_groupHandles.AddTail(beta->m_groupHandles.RemoveHead());
  1025. }
  1026. m_groupTable.RemoveAt(*next);
  1027. delete beta;
  1028. beta = m_groupTable.GetAt(*next);
  1029. beta->GetGroupID(b);
  1030. }
  1031. //after checking for duplicates, check we still meet the initial condition
  1032. if (*next < m_groupTable.GetSize())
  1033. {
  1034. //if the next item is not a child of this
  1035. if ((a.GetLength() >= b.GetLength()) || (!a.IsSubRange(b)))
  1036. {
  1037. CCorrObjectID c;
  1038. CCorrRangeTableItem* newEntry;
  1039. if (!m_rangeTable.GetLastEndOID(c) || !a.IsSubRange(c))
  1040. {
  1041. //add whole of a-range to rangetable
  1042. newEntry = new CCorrRangeTableItem(a, End, alpha);
  1043. }
  1044. else
  1045. {
  1046. //add from c to end of a-range to rangetable
  1047. newEntry = new CCorrRangeTableItem(c, End, alpha);
  1048. }
  1049. newEntry->DebugOutputRange();
  1050. m_rangeTable.Add(newEntry);
  1051. alpha->SetIndex(*cIndex);
  1052. m_Groups->SetBit(*cIndex);
  1053. }
  1054. else //the next item is a child so add a subrange and do the child - recurse!
  1055. {
  1056. CCorrObjectID c;
  1057. CCorrRangeTableItem* newEntry;
  1058. if (!m_rangeTable.GetLastEndOID(c) || !a.IsSubRange(c))
  1059. {
  1060. //add start of a-range to start of b to rangetable
  1061. newEntry = new CCorrRangeTableItem(a, b, alpha);
  1062. }
  1063. else
  1064. {
  1065. //add from c to start of b to rangetable
  1066. newEntry = new CCorrRangeTableItem(c, b, alpha);
  1067. }
  1068. newEntry->DebugOutputRange();
  1069. m_rangeTable.Add(newEntry);
  1070. UINT temp = (*next)++;
  1071. TCorrMaskLength tempIndex = (*nIndex)++;
  1072. DoGroupEntry(&temp, next, &tempIndex, nIndex);
  1073. if (*next >= m_groupTable.GetSize())
  1074. {
  1075. m_rangeTable.GetLastEndOID(c);
  1076. ////add from c to end of a-range to rangetable
  1077. newEntry = new CCorrRangeTableItem(c, End, alpha);
  1078. m_rangeTable.Add(newEntry);
  1079. alpha->SetIndex(*cIndex);
  1080. m_Groups->SetBit(*cIndex);
  1081. newEntry->DebugOutputRange();
  1082. }
  1083. //while the new next one(s) is a child add it first - recurse AGAIN!
  1084. while(!m_Groups->IsBitSet(*cIndex))
  1085. {
  1086. DoGroupEntry(current, next, cIndex, nIndex);
  1087. }
  1088. }
  1089. }
  1090. }
  1091. //if this is the last item then add it.
  1092. if (*current == m_groupTable.GetUpperBound())
  1093. {
  1094. //add whole of a-range to rangetable
  1095. CCorrRangeTableItem* newEntry = new CCorrRangeTableItem(a, End, alpha);
  1096. m_rangeTable.Add(newEntry);
  1097. alpha->SetIndex(*cIndex);
  1098. m_Groups->SetBit(*cIndex);
  1099. newEntry->DebugOutputRange();
  1100. }
  1101. }
  1102. #pragma warning (default:4018)
  1103. void CCorrCache::AddRef()
  1104. {
  1105. m_Lock.Lock();
  1106. m_Ref_Count++;
  1107. m_Lock.Unlock();
  1108. }
  1109. void CCorrCache::DecRef()
  1110. {
  1111. m_Lock.Lock();
  1112. if (m_Ref_Count)
  1113. m_Ref_Count--;
  1114. if (!m_Ref_Count && !m_ValidCache)
  1115. {
  1116. delete this;
  1117. return;
  1118. }
  1119. m_Lock.Unlock();
  1120. }
  1121. CCorrEncodedOID::CCorrEncodedOID(IN const CCorrObjectID& src_oid) : m_ids(NULL), m_length(0), m_chopped(0)
  1122. {
  1123. Set(src_oid);
  1124. }
  1125. void CCorrEncodedOID::Set(IN const CCorrObjectID& src_oid)
  1126. {
  1127. m_chopped = 0;
  1128. UINT x = 0;
  1129. UINT oidlength = src_oid.GetLength();
  1130. if (oidlength > MAX_OID_LENGTH)
  1131. {
  1132. DebugMacro6(
  1133. SnmpDebugLog::s_SnmpDebugLog->WriteFileAndLine(__FILE__,__LINE__,
  1134. L"CCorrEncodedOID::Set: Truncating OID from %d to %d components", oidlength, MAX_OID_LENGTH);
  1135. )
  1136. oidlength = MAX_OID_LENGTH;
  1137. }
  1138. if (oidlength)
  1139. {
  1140. UCHAR buff[MAX_OID_LENGTH*MAX_BYTES_PER_FIELD];
  1141. const UINT* oid_ids = src_oid.GetIds();
  1142. for (UINT i = 0; i < oidlength; i++)
  1143. {
  1144. UINT val = oid_ids[i];
  1145. //get the top four bits and store in byte
  1146. //BIT7 means next byte is part of this UINT
  1147. if (val >= BIT28)
  1148. {
  1149. buff[x++] = (UCHAR) (BIT7 + ((val & HI4BITS) >> 28));
  1150. }
  1151. //get the top four bits and store in byte
  1152. //BIT7 means next byte is part of this UINT
  1153. if (val >= BIT21)
  1154. {
  1155. buff[x++] = BIT7 + ((val & HIMID7BITS) >> 21);
  1156. }
  1157. //get the top four bits and store in byte
  1158. //BIT7 means next byte is part of this UINT
  1159. if (val >= BIT14)
  1160. {
  1161. buff[x++] = BIT7 + ((val & MID7BITS) >> 14);
  1162. }
  1163. //get the top four bits and store in byte
  1164. //BIT7 means next byte is part of this UINT
  1165. if (val >= BIT7)
  1166. {
  1167. buff[x++] = BIT7 + ((val & LOMID7BITS) >> 7);
  1168. }
  1169. //get the next seven bits and store in byte
  1170. buff[x++] = (val & LO7BITS);
  1171. }
  1172. //Remove the standard 1.3.6.1 if necessary...
  1173. if ((1 == buff[0]) && (3 == buff[1]) &&
  1174. (6 == buff[2]) && (1 == buff[3]))
  1175. {
  1176. m_chopped = 1;
  1177. m_ids = new UCHAR[x-4];
  1178. m_length = x-4;
  1179. memcpy(m_ids, &buff[4], m_length*sizeof(UCHAR));
  1180. }
  1181. else
  1182. {
  1183. m_ids = new UCHAR[x];
  1184. m_length = x;
  1185. memcpy(m_ids, buff, m_length*sizeof(UCHAR));
  1186. }
  1187. }
  1188. else
  1189. {
  1190. m_ids = NULL;
  1191. }
  1192. }
  1193. void CCorrEncodedOID::ExtractOID(OUT CCorrObjectID& src_oid) const
  1194. {
  1195. if (m_length)
  1196. {
  1197. UINT buff[MAX_OID_LENGTH];
  1198. UINT x = 0;
  1199. //Add the standard 1.3.6.1 if necessary...
  1200. if (m_chopped == 1)
  1201. {
  1202. buff[0] = 1;
  1203. buff[1] = 3;
  1204. buff[2] = 6;
  1205. buff[3] = 1;
  1206. x = 4;
  1207. }
  1208. for (UINT i = 0; (i < m_length) && (x < MAX_OID_LENGTH); i++)
  1209. {
  1210. //extract the value of the byte
  1211. buff[x] = m_ids[i] & LO7BITS;
  1212. //are there more bytes for this UINT
  1213. while ((i < m_length) && (m_ids[i] & 128))
  1214. {
  1215. //shift the value by a "byte" and extract tbe next byte.
  1216. buff[x] = buff[x] << 7;
  1217. buff[x] += m_ids[++i] & LO7BITS;
  1218. }
  1219. x++;
  1220. if ((x == MAX_OID_LENGTH) && (i < m_length))
  1221. {
  1222. DebugMacro6(
  1223. SnmpDebugLog::s_SnmpDebugLog->WriteFileAndLine(__FILE__,__LINE__,
  1224. L"CCorrEncodedOID::ExtractOID: Truncating OID %d components - SHOULD NEVER HAPPEN", MAX_OID_LENGTH);
  1225. )
  1226. }
  1227. }
  1228. src_oid.Set(buff, x);
  1229. }
  1230. else
  1231. {
  1232. src_oid.Set(NULL, 0);
  1233. }
  1234. }
  1235. CCorrEncodedOID::~CCorrEncodedOID()
  1236. {
  1237. delete [] m_ids;
  1238. }
  1239. CCorrCacheWrapper::CCorrCacheWrapper(IN CCorrCache* cachePtr) : m_lockit(NULL)
  1240. {
  1241. m_lockit = new CCriticalSection();
  1242. m_CachePtr = cachePtr;
  1243. }
  1244. CCorrCache* CCorrCacheWrapper::GetCache()
  1245. {
  1246. m_lockit->Lock();
  1247. return m_CachePtr;
  1248. }
  1249. CCorrCacheWrapper::~CCorrCacheWrapper()
  1250. {
  1251. delete m_lockit;
  1252. }