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.

1195 lines
32 KiB

  1. // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
  2. #include "precomp.h"
  3. #include <provexpt.h>
  4. #include <snmptempl.h>
  5. #include <snmpmt.h>
  6. #include <typeinfo.h>
  7. #include <process.h>
  8. #include <objbase.h>
  9. #include <stdio.h>
  10. #include <wbemidl.h>
  11. #include "classfac.h"
  12. #include "guids.h"
  13. #include <snmpcont.h>
  14. #include <snmpevt.h>
  15. #include <snmpthrd.h>
  16. #include <snmplog.h>
  17. #include <snmpcl.h>
  18. #include <instpath.h>
  19. #include <snmptype.h>
  20. #include <snmpauto.h>
  21. #include <snmpobj.h>
  22. #include <genlex.h>
  23. #include <sql_1.h>
  24. #include <objpath.h>
  25. #include <provtree.h>
  26. #include <provdnf.h>
  27. #include "propprov.h"
  28. #include "propsnmp.h"
  29. #include "propinst.h"
  30. #include "propquery.h"
  31. #include "snmpnext.h"
  32. BOOL DecrementObjectIdentifier (
  33. SnmpObjectIdentifier &a_Object ,
  34. SnmpObjectIdentifier &a_DecrementedObject
  35. )
  36. {
  37. BOOL t_Status = TRUE ;
  38. ULONG t_ObjectLength = a_Object.GetValueLength () ;
  39. ULONG *t_ObjectValue = a_Object.GetValue () ;
  40. ULONG *t_DecrementedValue = new ULONG [ t_ObjectLength ] ;
  41. BOOL t_Decrement = TRUE ;
  42. for ( ULONG t_Index = t_ObjectLength ; t_Index > 0 ; t_Index -- )
  43. {
  44. ULONG t_Component = t_ObjectValue [ t_Index - 1 ] ;
  45. if ( t_Decrement )
  46. {
  47. if ( t_Component == 0 )
  48. {
  49. t_Component -- ;
  50. }
  51. else
  52. {
  53. t_Decrement = FALSE ;
  54. t_Component -- ;
  55. }
  56. }
  57. t_DecrementedValue [ t_Index - 1 ] = t_Component ;
  58. }
  59. a_DecrementedObject.SetValue ( t_DecrementedValue , t_ObjectLength ) ;
  60. delete [] t_DecrementedValue;
  61. t_Status = t_Decrement == FALSE ;
  62. return t_Status ;
  63. }
  64. BOOL IncrementObjectIdentifier (
  65. SnmpObjectIdentifier &a_Object ,
  66. SnmpObjectIdentifier &a_IncrementedObject
  67. )
  68. {
  69. BOOL t_Status = TRUE ;
  70. ULONG t_ObjectLength = a_Object.GetValueLength () ;
  71. ULONG *t_ObjectValue = a_Object.GetValue () ;
  72. ULONG *t_IncrementedValue = new ULONG [ t_ObjectLength ] ;
  73. BOOL t_Increment = TRUE ;
  74. for ( ULONG t_Index = t_ObjectLength ; t_Index > 0 ; t_Index -- )
  75. {
  76. ULONG t_Component = t_ObjectValue [ t_Index - 1 ] ;
  77. if ( t_Increment )
  78. {
  79. if ( t_Component == 0xFFFFFFFF )
  80. {
  81. t_Component ++ ;
  82. }
  83. else
  84. {
  85. t_Component ++ ;
  86. t_Increment = FALSE ;
  87. }
  88. }
  89. t_IncrementedValue [ t_Index - 1 ] = t_Component ;
  90. }
  91. a_IncrementedObject.SetValue ( t_IncrementedValue , t_ObjectLength ) ;
  92. delete [] t_IncrementedValue;
  93. t_Status = t_Increment == FALSE ;
  94. return t_Status ;
  95. }
  96. AutoRetrieveOperation :: AutoRetrieveOperation (
  97. IN SnmpSession &sessionArg ,
  98. IN SnmpInstanceResponseEventObject *eventObjectArg
  99. ) : SnmpAutoRetrieveOperation ( sessionArg ) ,
  100. session ( &sessionArg ) ,
  101. eventObject ( eventObjectArg ) ,
  102. varBindsReceived ( 0 ) ,
  103. erroredVarBindsReceived ( 0 ) ,
  104. rowVarBindsReceived ( 0 ) ,
  105. rowsReceived ( 0 ) ,
  106. snmpObject ( NULL ) ,
  107. virtuals ( FALSE ) ,
  108. virtualsInitialised ( FALSE ) ,
  109. m_PropertyContainer ( NULL ) ,
  110. m_PropertyContainerLength ( 0 )
  111. {
  112. }
  113. AutoRetrieveOperation :: ~AutoRetrieveOperation ()
  114. {
  115. if ( snmpObject )
  116. {
  117. snmpObject->Release () ;
  118. snmpObject = NULL;
  119. }
  120. delete [] m_PropertyContainer ;
  121. session->DestroySession () ;
  122. }
  123. void AutoRetrieveOperation :: ReceiveResponse ()
  124. {
  125. // Inform creator all is done
  126. eventObject->ReceiveComplete () ;
  127. }
  128. void AutoRetrieveOperation :: ReceiveRowResponse ()
  129. {
  130. // Receive of Row is not complete
  131. rowsReceived ++ ;
  132. // Inform Creator row has been received
  133. if ( snmpObject )
  134. {
  135. eventObject->ReceiveRow ( snmpObject ) ;
  136. snmpObject->Release () ;
  137. snmpObject = NULL;
  138. }
  139. // Insert new Object Identifier / Property Hash entries for newly created object
  140. IWbemClassObject *t_ClassObject = eventObject->GetInstanceObject () ;
  141. HRESULT t_Result = t_ClassObject->Clone ( & snmpObject ) ;
  142. if ( SUCCEEDED ( t_Result ) )
  143. {
  144. SnmpInstanceClassObject *t_SnmpObject = ( SnmpInstanceClassObject * ) eventObject->GetSnmpClassObject () ;
  145. WbemSnmpProperty *property ;
  146. t_SnmpObject->ResetProperty () ;
  147. while ( property = t_SnmpObject->NextProperty () )
  148. {
  149. /*
  150. * Initialise value to NULL
  151. */
  152. property->SetValue ( snmpObject , ( SnmpValue * ) NULL ) ;
  153. }
  154. }
  155. else
  156. {
  157. // Problem Here
  158. if ( t_Result == WBEM_E_OUT_OF_MEMORY )
  159. {
  160. throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR) ;
  161. }
  162. }
  163. virtualsInitialised = FALSE ;
  164. }
  165. void AutoRetrieveOperation :: ReceiveRowVarBindResponse (
  166. IN const ULONG &var_bind_index,
  167. IN const SnmpVarBind &requestVarBind ,
  168. IN const SnmpVarBind &replyVarBind ,
  169. IN const SnmpErrorReport &error
  170. )
  171. {
  172. rowVarBindsReceived ++ ;
  173. // Set Variable Binding Value for property
  174. WbemSnmpProperty *property = m_PropertyContainer [ var_bind_index - 1 ].m_Property ;
  175. SnmpValue &value = replyVarBind.GetValue () ;
  176. if ( property->SetValue ( snmpObject , &value , SetValueRegardlessReturnCheck ) )
  177. {
  178. // Set worked
  179. }
  180. else
  181. {
  182. // Type Mismatch
  183. property->AddQualifier ( WBEM_QUALIFIER_TYPE_MISMATCH ) ;
  184. WbemSnmpQualifier *qualifier = property->FindQualifier ( WBEM_QUALIFIER_TYPE_MISMATCH ) ;
  185. if ( qualifier )
  186. {
  187. if ( snmpObject )
  188. {
  189. IWbemQualifierSet *t_QualifierSet = NULL;
  190. HRESULT result = snmpObject->GetPropertyQualifierSet ( property->GetName () , & t_QualifierSet ) ;
  191. if ( SUCCEEDED ( result ) )
  192. {
  193. SnmpIntegerType integer ( 1 , NULL ) ;
  194. qualifier->SetValue ( t_QualifierSet , integer ) ;
  195. }
  196. if ( t_QualifierSet )
  197. {
  198. t_QualifierSet->Release () ;
  199. t_QualifierSet = NULL;
  200. }
  201. }
  202. }
  203. }
  204. if ( virtuals && virtualsInitialised == FALSE )
  205. //if ( virtualsInitialised == FALSE )
  206. {
  207. // Get Phantom Key properties from first Variable Binding of Row
  208. BOOL status = TRUE ;
  209. SnmpObjectIdentifier decodeObject = replyVarBind.GetInstance () ;
  210. SnmpInstanceClassObject *t_SnmpObject = ( SnmpInstanceClassObject * ) eventObject->GetSnmpClassObject () ;
  211. WbemSnmpProperty *property ;
  212. t_SnmpObject->ResetKeyProperty () ;
  213. while ( status && ( property = t_SnmpObject->NextKeyProperty () ) )
  214. {
  215. // For each Phantom Key in Key Order consume instance information
  216. SnmpInstanceType *decodeValue = property->GetValue () ;
  217. decodeObject = decodeValue->Decode ( decodeObject ) ;
  218. if ( *decodeValue )
  219. {
  220. // Decode worked correctly
  221. const SnmpValue *value = decodeValue->GetValueEncoding () ;
  222. // Set Property value for Key
  223. property->SetValue ( snmpObject , value , SetValueRegardlessReturnCheck ) ;
  224. }
  225. else
  226. {
  227. // Decode Error therefore set TYPE MISMATCH for all Phantom keys
  228. WbemSnmpProperty *property ;
  229. t_SnmpObject->ResetKeyProperty () ;
  230. while ( property = t_SnmpObject->NextKeyProperty () )
  231. {
  232. WbemSnmpQualifier *qualifier = NULL ;
  233. property->AddQualifier ( WBEM_QUALIFIER_TYPE_MISMATCH ) ;
  234. if ( qualifier = property->FindQualifier ( WBEM_QUALIFIER_TYPE_MISMATCH ) )
  235. {
  236. // Property which is a phantom key could not be decoded correctly.
  237. if ( snmpObject )
  238. {
  239. IWbemQualifierSet *t_QualifierSet = NULL;
  240. HRESULT result = snmpObject->GetPropertyQualifierSet ( property->GetName () , & t_QualifierSet ) ;
  241. if ( SUCCEEDED ( result ) )
  242. {
  243. SnmpIntegerType integer ( 1 , NULL ) ;
  244. qualifier->SetValue ( t_QualifierSet , integer ) ;
  245. }
  246. if ( t_QualifierSet )
  247. {
  248. t_QualifierSet->Release () ;
  249. t_QualifierSet = NULL;
  250. }
  251. }
  252. }
  253. else
  254. {
  255. // Problem Here
  256. }
  257. }
  258. status = FALSE ;
  259. }
  260. }
  261. // Check we have consumed all instance information
  262. if ( decodeObject.GetValueLength () )
  263. {
  264. // Decode Error therefore set TYPE MISMATCH for all Phantom keys
  265. WbemSnmpProperty *property ;
  266. t_SnmpObject->ResetKeyProperty () ;
  267. while ( property = t_SnmpObject->NextKeyProperty () )
  268. {
  269. WbemSnmpQualifier *qualifier = NULL ;
  270. property->AddQualifier ( WBEM_QUALIFIER_TYPE_MISMATCH ) ;
  271. if ( qualifier = property->FindQualifier ( WBEM_QUALIFIER_TYPE_MISMATCH ) )
  272. {
  273. // Property which is a phantom key could not be decoded correctly.
  274. if ( snmpObject )
  275. {
  276. IWbemQualifierSet *t_QualifierSet = NULL;
  277. HRESULT result = snmpObject->GetPropertyQualifierSet ( property->GetName () , & t_QualifierSet ) ;
  278. if ( SUCCEEDED ( result ) )
  279. {
  280. SnmpIntegerType integer ( 1 , NULL ) ;
  281. qualifier->SetValue ( t_QualifierSet , integer ) ;
  282. }
  283. if ( t_QualifierSet )
  284. {
  285. t_QualifierSet->Release () ;
  286. t_QualifierSet = NULL;
  287. }
  288. }
  289. }
  290. else
  291. {
  292. // Problem Here
  293. }
  294. }
  295. }
  296. // No need to set Phantom keys for further columns of row
  297. virtualsInitialised = TRUE ;
  298. }
  299. }
  300. void AutoRetrieveOperation :: ReceiveVarBindResponse (
  301. IN const ULONG &var_bind_index,
  302. IN const SnmpVarBind &requestVarBind ,
  303. IN const SnmpVarBind &replyVarBind ,
  304. IN const SnmpErrorReport &error
  305. )
  306. {
  307. varBindsReceived ++ ;
  308. }
  309. #pragma warning (disable:4065)
  310. void AutoRetrieveOperation :: ReceiveErroredVarBindResponse(
  311. IN const ULONG &var_bind_index,
  312. IN const SnmpVarBind &requestVarBind ,
  313. IN const SnmpErrorReport &error
  314. )
  315. {
  316. erroredVarBindsReceived ++ ;
  317. switch ( error.GetError () )
  318. {
  319. case Snmp_Error:
  320. {
  321. switch ( error.GetStatus () )
  322. {
  323. case Snmp_No_Response:
  324. {
  325. eventObject->GetErrorObject ().SetStatus ( WBEM_SNMP_E_TRANSPORT_NO_RESPONSE ) ;
  326. eventObject->GetErrorObject ().SetWbemStatus ( WBEM_E_FAILED ) ;
  327. eventObject->GetErrorObject ().SetMessage ( L"No Response from device" ) ;
  328. }
  329. break;
  330. case Snmp_No_Such_Name:
  331. {
  332. // End of MIB tree.
  333. }
  334. break ;
  335. default:
  336. {
  337. eventObject->GetErrorObject ().SetStatus ( WBEM_SNMP_E_TRANSPORT_ERROR ) ;
  338. eventObject->GetErrorObject ().SetWbemStatus ( WBEM_E_FAILED ) ;
  339. eventObject->GetErrorObject ().SetMessage ( L"Unknown transport failure" ) ;
  340. }
  341. break ;
  342. }
  343. }
  344. break ;
  345. case Snmp_Transport:
  346. {
  347. switch ( error.GetStatus () )
  348. {
  349. default:
  350. {
  351. eventObject->GetErrorObject ().SetStatus ( WBEM_SNMP_E_TRANSPORT_ERROR ) ;
  352. eventObject->GetErrorObject ().SetWbemStatus ( WBEM_E_FAILED ) ;
  353. eventObject->GetErrorObject ().SetMessage ( L"Unknown transport failure" ) ;
  354. }
  355. break ;
  356. }
  357. }
  358. break ;
  359. default:
  360. {
  361. // Cannot Happen
  362. }
  363. break ;
  364. }
  365. erroredVarBindsReceived ++ ;
  366. }
  367. #pragma warning (default:4065)
  368. void AutoRetrieveOperation :: FrameTooBig ()
  369. {
  370. }
  371. void AutoRetrieveOperation :: FrameOverRun ()
  372. {
  373. }
  374. void AutoRetrieveOperation :: Send ()
  375. {
  376. // Send Variable Bindings for requested properties
  377. SnmpNull snmpNull ;
  378. SnmpVarBindList varBindList ;
  379. SnmpVarBindList startVarBindList ;
  380. // Create class object for subsequent receipt of response
  381. IWbemClassObject *t_ClassObject = eventObject->GetInstanceObject () ;
  382. HRESULT t_Result = t_ClassObject->Clone ( & snmpObject ) ;
  383. if ( SUCCEEDED ( t_Result ) )
  384. {
  385. SnmpInstanceClassObject *t_SnmpObject = ( SnmpInstanceClassObject * ) eventObject->GetSnmpClassObject () ;
  386. SnmpInstanceClassObject *t_RequestSnmpObject = ( SnmpInstanceClassObject * ) eventObject->GetSnmpRequestClassObject () ;
  387. // Check for properties which are phantom
  388. virtualsInitialised = FALSE ;
  389. virtuals = FALSE ;
  390. WbemSnmpProperty *property ;
  391. t_SnmpObject->ResetKeyProperty () ;
  392. while ( property = t_SnmpObject->NextKeyProperty () )
  393. {
  394. if ( property->IsVirtualKey () )
  395. {
  396. // There are some properties which are phantom
  397. virtuals = TRUE ;
  398. }
  399. if ( ! t_RequestSnmpObject->FindProperty ( property->GetName () ) )
  400. {
  401. virtuals = TRUE ;
  402. }
  403. }
  404. t_SnmpObject->ResetProperty () ;
  405. while ( property = t_SnmpObject->NextProperty () )
  406. {
  407. if ( property->IsReadable () )
  408. {
  409. BOOL t_Status = ( t_SnmpObject->GetSnmpVersion () == 1 ) && ( property->IsSNMPV1Type () ) ;
  410. t_Status = t_Status || ( ( t_SnmpObject->GetSnmpVersion () == 2 ) && ( property->IsSNMPV2CType () ) ) ;
  411. if ( t_Status )
  412. {
  413. if ( property->IsVirtualKey () == FALSE )
  414. {
  415. m_PropertyContainerLength ++ ;
  416. }
  417. }
  418. }
  419. }
  420. m_PropertyContainer = new PropertyDefinition [ m_PropertyContainerLength ] ;
  421. // Add Variable binding to Variable binding list
  422. // Insert new Object Identifier / Property Hash entries for newly created object
  423. ULONG t_Index = 0 ;
  424. t_RequestSnmpObject->ResetProperty () ;
  425. while ( property = t_RequestSnmpObject->NextProperty () )
  426. {
  427. if ( property->IsReadable () )
  428. {
  429. BOOL t_Status = ( t_RequestSnmpObject->GetSnmpVersion () == 1 ) && ( property->IsSNMPV1Type () ) ;
  430. t_Status = t_Status || ( ( t_RequestSnmpObject->GetSnmpVersion () == 2 ) && ( property->IsSNMPV2CType () ) ) ;
  431. if ( t_Status )
  432. {
  433. if ( property->IsVirtualKey () == FALSE )
  434. {
  435. WbemSnmpQualifier *qualifier = property->FindQualifier ( WBEM_QUALIFIER_OBJECT_IDENTIFIER ) ;
  436. if ( qualifier )
  437. {
  438. SnmpInstanceType *value = qualifier->GetValue () ;
  439. if ( typeid ( *value ) == typeid ( SnmpObjectIdentifierType ) )
  440. {
  441. SnmpObjectIdentifier t_CurrentIdentifier ( 0 , NULL ) ;
  442. SnmpObjectIdentifier t_StartIdentifier ( 0 , NULL ) ;
  443. LONG t_Scoped = EvaluateInitialVarBind (
  444. t_Index ,
  445. t_CurrentIdentifier ,
  446. t_StartIdentifier
  447. ) ;
  448. m_PropertyContainer [ t_Index ].m_Property = property ;
  449. SnmpObjectIdentifierType requestIdentifierType ( * ( SnmpObjectIdentifierType * ) value ) ;
  450. SnmpObjectIdentifier t_RequestIdentifier = * ( SnmpObjectIdentifier * ) requestIdentifierType.GetValueEncoding () ;
  451. SnmpVarBind t_VarBind ( t_RequestIdentifier , snmpNull ) ;
  452. varBindList.Add ( t_VarBind ) ;
  453. if ( t_Scoped > 0 )
  454. {
  455. t_RequestIdentifier = t_RequestIdentifier + t_StartIdentifier ;
  456. }
  457. // Add Variable binding to list
  458. SnmpVarBind t_StartVarBind ( t_RequestIdentifier , snmpNull ) ;
  459. startVarBindList.Add ( t_StartVarBind ) ;
  460. t_Index ++ ;
  461. }
  462. }
  463. }
  464. else
  465. {
  466. // Don't Send properties marked as virtual key
  467. }
  468. }
  469. }
  470. /*
  471. * Initialise value to NULL
  472. */
  473. property->SetValue ( snmpObject , ( SnmpValue * ) NULL ) ;
  474. }
  475. // Finally Send request
  476. SendRequest ( varBindList , startVarBindList ) ;
  477. }
  478. else
  479. {
  480. }
  481. }
  482. LONG AutoRetrieveOperation :: EvaluateNextRequest (
  483. IN const ULONG &var_bind_index,
  484. IN const SnmpVarBind &requestVarBind ,
  485. IN const SnmpVarBind &replyVarBind ,
  486. IN SnmpVarBind &sendVarBind
  487. )
  488. {
  489. LONG t_Evaluation = 0 ;
  490. PartitionSet *t_Partition = eventObject->GetPartitionSet () ;
  491. if ( t_Partition )
  492. {
  493. BOOL t_Status = TRUE ;
  494. SnmpInstanceClassObject *t_SnmpObject = ( SnmpInstanceClassObject * ) eventObject->GetSnmpClassObject () ;
  495. ULONG t_KeyCount = t_SnmpObject->GetKeyPropertyCount () ;
  496. SnmpObjectIdentifier t_DecodeObject = replyVarBind.GetInstance () ;
  497. ULONG t_Index = 0 ;
  498. WbemSnmpProperty *t_Property ;
  499. t_SnmpObject->ResetKeyProperty () ;
  500. while ( t_Status && ( t_Property = t_SnmpObject->NextKeyProperty () ) )
  501. {
  502. // For each Key in Key Order consume instance information
  503. SnmpInstanceType *t_DecodeValue = t_Property->GetValue () ;
  504. t_DecodeObject = t_DecodeValue->Decode ( t_DecodeObject ) ;
  505. SnmpObjectIdentifier t_Encode ( 0 , NULL ) ;
  506. t_Encode = t_DecodeValue->Encode ( t_Encode ) ;
  507. m_PropertyContainer [ var_bind_index - 1 ].m_ObjectIdentifierComponent [ t_Index + 1 ] = ( SnmpObjectIdentifier * ) t_Encode.Copy () ;
  508. t_Index ++ ;
  509. }
  510. SnmpObjectIdentifier t_AdvanceObjectIdentifier ( 0 , NULL ) ;
  511. t_Evaluation = EvaluateResponse (
  512. var_bind_index - 1 ,
  513. t_KeyCount ,
  514. t_AdvanceObjectIdentifier
  515. ) ;
  516. if ( t_Evaluation > 0 )
  517. {
  518. SnmpNull t_SnmpNull ;
  519. SnmpVarBind t_VarBind ( t_AdvanceObjectIdentifier , t_SnmpNull ) ;
  520. sendVarBind = t_VarBind ;
  521. }
  522. for ( t_Index = 0 ; t_Index < m_PropertyContainer [ var_bind_index - 1 ].m_KeyCount ; t_Index ++ )
  523. {
  524. delete m_PropertyContainer [ var_bind_index - 1 ].m_ObjectIdentifierComponent [ t_Index + 1 ] ;
  525. m_PropertyContainer [ var_bind_index - 1 ].m_ObjectIdentifierComponent [ t_Index + 1 ] = NULL ;
  526. }
  527. }
  528. return t_Evaluation ;
  529. }
  530. LONG AutoRetrieveOperation :: EvaluateResponse (
  531. IN ULONG a_PropertyIndex ,
  532. IN ULONG &a_CurrentIndex ,
  533. IN SnmpObjectIdentifier &a_AdvanceObjectIdentifier
  534. )
  535. {
  536. LONG t_Evaluation = 0 ;
  537. BOOL t_UseStartAsAdvance = FALSE ;
  538. for ( ULONG t_Index = 0 ; t_Index < m_PropertyContainer [ a_PropertyIndex ].m_KeyCount ; t_Index ++ )
  539. {
  540. SnmpObjectIdentifier *t_Encode = m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierComponent [ t_Index + 1 ] ;
  541. SnmpObjectIdentifier *t_Start = m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierStart [ t_Index + 1 ] ;
  542. if ( t_Start )
  543. {
  544. /*
  545. * We have a start which is not negatively infinite
  546. */
  547. if ( *t_Encode > *t_Start )
  548. {
  549. /*
  550. * The encoded object from the device is greater than the start value, so add the encoded value
  551. * to the running total.
  552. */
  553. a_AdvanceObjectIdentifier = a_AdvanceObjectIdentifier + *t_Encode ;
  554. }
  555. else if ( *t_Encode == *t_Start )
  556. {
  557. a_AdvanceObjectIdentifier = a_AdvanceObjectIdentifier + *t_Encode ;
  558. }
  559. else
  560. {
  561. /*
  562. * Encoded value is less than start value so we need to advance to the start value
  563. */
  564. t_UseStartAsAdvance = TRUE ;
  565. /*
  566. * The encoded object from the device is less than the start value, so add the encoded value
  567. * to the running total.
  568. */
  569. a_AdvanceObjectIdentifier = a_AdvanceObjectIdentifier + *t_Start ;
  570. }
  571. }
  572. else
  573. {
  574. /*
  575. * Start is negatively infinite
  576. */
  577. if ( t_UseStartAsAdvance )
  578. {
  579. /*
  580. * We have already identified a starting position which is greater than the encoded value.
  581. * The new value is a negative infinite so we should stop here
  582. */
  583. t_Index ++ ;
  584. break ;
  585. }
  586. else
  587. {
  588. /*
  589. * The start position is negatively infinite and we haven't had to use a different value from the one
  590. * returned from the device.
  591. */
  592. a_AdvanceObjectIdentifier = a_AdvanceObjectIdentifier + *t_Encode ;
  593. }
  594. }
  595. /*
  596. * The value was not taken from the start value with an
  597. * infinite range on next key index, so we must check to see if the range is less than the 'end'
  598. */
  599. PartitionSet *t_KeyPartition = m_PropertyContainer [ a_PropertyIndex ].m_KeyPartition [ t_Index + 1 ] ;
  600. WmiRangeNode *t_Range = t_KeyPartition->GetRange () ;
  601. SnmpObjectIdentifier *t_End = m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierEnd [ t_Index + 1 ] ;
  602. if ( t_End )
  603. {
  604. BOOL t_InRange = ( ( t_Range->ClosedUpperBound () && ( *t_Encode <= *t_End ) ) ||
  605. ( ! t_Range->ClosedUpperBound () && ( *t_Encode < *t_End ) ) ) ;
  606. if ( t_InRange )
  607. {
  608. /*
  609. * We are still within the boundaries
  610. */
  611. }
  612. else
  613. {
  614. /*
  615. * Move to new partition because we have moved past end
  616. */
  617. SnmpObjectIdentifier t_StartObjectIdentifier ( 0 , NULL ) ;
  618. /*
  619. * Advance to the next partition, we will use the next partition starting point for next request
  620. */
  621. t_Evaluation = EvaluateSubsequentVarBind (
  622. a_PropertyIndex ,
  623. a_CurrentIndex ,
  624. a_AdvanceObjectIdentifier ,
  625. t_StartObjectIdentifier
  626. ) ;
  627. if ( t_Evaluation >= 0 )
  628. {
  629. a_AdvanceObjectIdentifier = t_StartObjectIdentifier ;
  630. }
  631. t_UseStartAsAdvance = FALSE ;
  632. t_Index ++ ;
  633. break ;
  634. }
  635. }
  636. else
  637. {
  638. /*
  639. * Range is infinite so go on to next
  640. */
  641. }
  642. }
  643. if ( t_UseStartAsAdvance )
  644. {
  645. /*
  646. * We have got all the way to the end without move to the end of a partition and have used new start position
  647. */
  648. PartitionSet *t_KeyPartition = m_PropertyContainer [ a_PropertyIndex ].m_KeyPartition [ t_Index ] ;
  649. WmiRangeNode *t_Range = t_KeyPartition->GetRange () ;
  650. if( t_Range->ClosedLowerBound () )
  651. {
  652. if ( ! DecrementObjectIdentifier ( a_AdvanceObjectIdentifier , a_AdvanceObjectIdentifier ) )
  653. {
  654. t_Evaluation = -1 ;
  655. return t_Evaluation ;
  656. }
  657. }
  658. t_Evaluation = 1 ;
  659. }
  660. return t_Evaluation ;
  661. }
  662. LONG AutoRetrieveOperation :: EvaluateInitialVarBind (
  663. ULONG a_PropertyIndex ,
  664. SnmpObjectIdentifier &a_CurrentIdentifier ,
  665. SnmpObjectIdentifier &a_StartIdentifier
  666. )
  667. {
  668. LONG t_Scoped = -1 ;
  669. PartitionSet *t_Partition = eventObject->GetPartitionSet () ;
  670. if ( t_Partition )
  671. {
  672. SnmpInstanceClassObject *t_SnmpObject = ( SnmpInstanceClassObject * ) eventObject->GetSnmpClassObject () ;
  673. ULONG t_KeyCount = t_SnmpObject->GetKeyPropertyCount () ;
  674. if ( ! m_PropertyContainer [ a_PropertyIndex ].m_PartitionIndex )
  675. {
  676. m_PropertyContainer [ a_PropertyIndex ].m_KeyCount = t_KeyCount ;
  677. m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierStart = new SnmpObjectIdentifier * [ t_KeyCount + 1 ] ;
  678. m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierEnd = new SnmpObjectIdentifier * [ t_KeyCount + 1 ] ;
  679. m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierComponent = new SnmpObjectIdentifier * [ t_KeyCount + 1 ] ;
  680. m_PropertyContainer [ a_PropertyIndex ].m_KeyPartition = new PartitionSet * [ t_KeyCount + 1 ] ;
  681. m_PropertyContainer [ a_PropertyIndex ].m_PartitionIndex = new ULONG [ t_KeyCount + 1 ] ;
  682. for ( ULONG t_Index = 0 ; t_Index <= t_KeyCount ; t_Index ++ )
  683. {
  684. m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierStart [ t_Index ] = NULL ;
  685. m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierEnd [ t_Index ] = NULL ;
  686. m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierComponent [ t_Index ] = NULL ;
  687. m_PropertyContainer [ a_PropertyIndex ].m_PartitionIndex [ t_Index ] = 0 ;
  688. m_PropertyContainer [ a_PropertyIndex ].m_KeyPartition [ t_Index ] = t_Partition ;
  689. t_Partition = t_Partition->GetPartition ( 0 ) ;
  690. }
  691. t_Scoped = EvaluateVarBind ( a_PropertyIndex , a_StartIdentifier ) ;
  692. }
  693. }
  694. return t_Scoped ;
  695. }
  696. LONG AutoRetrieveOperation :: EvaluateSubsequentVarBind (
  697. ULONG a_PropertyIndex ,
  698. ULONG &a_CurrentIndex ,
  699. SnmpObjectIdentifier &a_CurrentIdentifier ,
  700. SnmpObjectIdentifier &a_StartIdentifier
  701. )
  702. {
  703. LONG t_Scoped = -1 ;
  704. SnmpInstanceClassObject *t_SnmpObject = ( SnmpInstanceClassObject * ) eventObject->GetSnmpClassObject () ;
  705. ULONG t_KeyCount = t_SnmpObject->GetKeyPropertyCount () ;
  706. BOOL t_Complete = FALSE ;
  707. BOOL t_AdvanceInsidePartition = FALSE ;
  708. while ( ! t_Complete )
  709. {
  710. if ( a_CurrentIndex > 0 )
  711. {
  712. if ( t_AdvanceInsidePartition )
  713. {
  714. SnmpObjectIdentifier *t_Encode = m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierComponent [ a_CurrentIndex ] ;
  715. BOOL t_Incremented = IncrementObjectIdentifier ( *t_Encode , *t_Encode ) ;
  716. if ( t_Incremented )
  717. {
  718. t_Scoped = EvaluateResponse (
  719. a_PropertyIndex ,
  720. a_CurrentIndex ,
  721. a_StartIdentifier
  722. ) ;
  723. t_Complete = TRUE ;
  724. }
  725. else
  726. {
  727. /*
  728. * Increment failed so next time around loop to next partition
  729. */
  730. t_AdvanceInsidePartition = FALSE ;
  731. }
  732. }
  733. else
  734. {
  735. /*
  736. * Get the current partition index and increment to get next possible partition index
  737. */
  738. ULONG t_PartitionIndex = m_PropertyContainer [ a_PropertyIndex ].m_PartitionIndex [ a_CurrentIndex - 1 ] + 1 ;
  739. /*
  740. * Get the parent partition set associated with the current key partition
  741. */
  742. PartitionSet *t_ParentPartition = m_PropertyContainer [ a_PropertyIndex ].m_KeyPartition [ a_CurrentIndex - 1 ] ;
  743. /*
  744. * Check there are more partitions left to scan
  745. */
  746. if ( t_PartitionIndex >= t_ParentPartition->GetPartitionCount () )
  747. {
  748. if ( ! t_AdvanceInsidePartition )
  749. {
  750. /*
  751. * Reset the current partition value to NULL object identifier
  752. */
  753. *m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierComponent [ a_CurrentIndex ] = SnmpObjectIdentifier ( 0 , NULL ) ;
  754. /*
  755. * No more partitions for this key, move to previous key and attempt to get next value for that key
  756. */
  757. t_AdvanceInsidePartition = TRUE ;
  758. a_CurrentIndex -- ;
  759. /*
  760. * We are not in the scope for this key
  761. */
  762. t_Scoped = 0 ;
  763. }
  764. }
  765. else
  766. {
  767. /*
  768. * More partitions for this key
  769. *
  770. * Set the partition for the current ( keyindex == t_CurrentIndex - 1 ) to t_PartitionIndex
  771. */
  772. m_PropertyContainer [ a_PropertyIndex ].m_PartitionIndex [ a_CurrentIndex - 1 ] = t_PartitionIndex ;
  773. /*
  774. * Move to the next partition for ( keyIndex == t_CurrentIndex - 1 ) and t_PartitionIndex
  775. */
  776. m_PropertyContainer [ a_PropertyIndex ].m_KeyPartition [ a_CurrentIndex ] = t_ParentPartition->GetPartition ( t_PartitionIndex ) ;
  777. for ( ULONG t_Index = a_CurrentIndex ; t_Index < t_KeyCount ; t_Index ++ )
  778. {
  779. m_PropertyContainer [ a_PropertyIndex ].m_PartitionIndex [ t_Index ] = 0 ;
  780. }
  781. t_Scoped = EvaluateVarBind ( a_PropertyIndex , a_StartIdentifier ) ;
  782. if ( a_StartIdentifier < a_CurrentIdentifier )
  783. {
  784. a_StartIdentifier = a_CurrentIdentifier ;
  785. }
  786. PartitionSet *t_KeyPartition = m_PropertyContainer [ a_PropertyIndex ].m_KeyPartition [ a_CurrentIndex ] ;
  787. WmiRangeNode *t_Range = t_KeyPartition->GetRange () ;
  788. SnmpObjectIdentifier *t_End = m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierEnd [ a_CurrentIndex ] ;
  789. if ( t_End )
  790. {
  791. BOOL t_InRange = ( ( t_Range->ClosedUpperBound () && ( a_StartIdentifier <= *t_End ) ) ||
  792. ( ! t_Range->ClosedUpperBound () && ( a_StartIdentifier < *t_End ) ) ) ;
  793. if ( t_InRange )
  794. {
  795. t_Complete = TRUE ;
  796. }
  797. else
  798. {
  799. a_StartIdentifier = SnmpObjectIdentifier ( 0 , NULL ) ;
  800. }
  801. }
  802. else
  803. {
  804. t_Complete = TRUE ;
  805. }
  806. }
  807. }
  808. }
  809. else
  810. {
  811. t_Complete = TRUE ;
  812. }
  813. }
  814. return t_Scoped ;
  815. }
  816. LONG AutoRetrieveOperation :: EvaluateVarBind (
  817. ULONG a_PropertyIndex ,
  818. SnmpObjectIdentifier &a_StartIdentifier
  819. )
  820. {
  821. LONG t_Scoped = 0 ;
  822. SnmpInstanceClassObject *t_SnmpObject = ( SnmpInstanceClassObject * ) eventObject->GetSnmpClassObject () ;
  823. ULONG t_KeyCount = t_SnmpObject->GetKeyPropertyCount () ;
  824. BOOL t_FoundInfinite = FALSE ;
  825. WbemSnmpProperty *t_KeyProperty = NULL ;
  826. t_SnmpObject->ResetKeyProperty () ;
  827. for ( ULONG t_Index = 1 ; t_Index <= t_KeyCount ; t_Index ++ )
  828. {
  829. t_KeyProperty = t_SnmpObject->NextKeyProperty () ;
  830. PartitionSet *t_KeyPartition = m_PropertyContainer [ a_PropertyIndex ].m_KeyPartition [ t_Index ] ;
  831. WmiRangeNode *t_Range = t_KeyPartition->GetRange () ;
  832. if ( t_Range->InfiniteLowerBound () )
  833. {
  834. t_FoundInfinite = TRUE ;
  835. }
  836. else
  837. {
  838. // if we are in the middle partition we need to delete
  839. //
  840. // 00 <- 0 | 0 <---> n | n -> 00
  841. // infinite lowerbound | no infinite lowerbound | no infinite lowerbound
  842. //
  843. // it may be allocated before and none will delete it
  844. if ( m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierStart [ t_Index ] )
  845. {
  846. delete m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierStart [ t_Index ];
  847. m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierStart [ t_Index ] = NULL;
  848. }
  849. t_Scoped = 1 ;
  850. m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierStart [ t_Index ] = new SnmpObjectIdentifier ( 0 , NULL ) ;
  851. if ( typeid ( *t_Range ) == typeid ( WmiUnsignedIntegerRangeNode ) )
  852. {
  853. WmiUnsignedIntegerRangeNode *t_Node = ( WmiUnsignedIntegerRangeNode * ) t_Range ;
  854. ULONG t_Integer = t_Node->LowerBound () ;
  855. VARIANT t_Variant ;
  856. VariantInit ( & t_Variant ) ;
  857. t_Variant.vt = VT_I4 ;
  858. t_Variant.lVal = t_Integer ;
  859. t_KeyProperty->Encode ( t_Variant , * m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierStart [ t_Index ] ) ;
  860. if ( ! t_FoundInfinite )
  861. {
  862. t_KeyProperty->Encode ( t_Variant , a_StartIdentifier ) ;
  863. }
  864. VariantClear ( & t_Variant ) ;
  865. }
  866. else if ( typeid ( *t_Range ) == typeid ( WmiSignedIntegerRangeNode ) )
  867. {
  868. WmiSignedIntegerRangeNode *t_Node = ( WmiSignedIntegerRangeNode * ) t_Range ;
  869. LONG t_Integer = t_Node->LowerBound () ;
  870. VARIANT t_Variant ;
  871. VariantInit ( & t_Variant ) ;
  872. t_Variant.vt = VT_I4 ;
  873. t_Variant.lVal = t_Integer ;
  874. t_KeyProperty->Encode ( t_Variant , * m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierStart [ t_Index ] ) ;
  875. if ( ! t_FoundInfinite )
  876. {
  877. t_KeyProperty->Encode ( t_Variant , a_StartIdentifier ) ;
  878. }
  879. VariantClear ( & t_Variant ) ;
  880. }
  881. if ( typeid ( *t_Range ) == typeid ( WmiStringRangeNode ) )
  882. {
  883. WmiStringRangeNode *t_Node = ( WmiStringRangeNode * ) t_Range ;
  884. BSTR t_String = t_Node->LowerBound () ;
  885. VARIANT t_Variant ;
  886. VariantInit ( & t_Variant ) ;
  887. t_Variant.vt = VT_BSTR ;
  888. t_Variant.bstrVal = SysAllocString ( t_String ) ;
  889. t_KeyProperty->Encode ( t_Variant , * m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierStart [ t_Index ] ) ;
  890. if ( ! t_FoundInfinite )
  891. {
  892. t_KeyProperty->Encode ( t_Variant , a_StartIdentifier ) ;
  893. }
  894. VariantClear ( & t_Variant ) ;
  895. }
  896. }
  897. if ( ( t_Index == t_KeyCount ) && t_Range->ClosedLowerBound () )
  898. {
  899. BOOL t_Decremented = DecrementObjectIdentifier (
  900. a_StartIdentifier ,
  901. a_StartIdentifier
  902. ) ;
  903. t_Scoped = t_Decremented ? 1 : 0 ;
  904. }
  905. }
  906. t_SnmpObject->ResetKeyProperty () ;
  907. for ( t_Index = 1 ; t_Index <= t_KeyCount ; t_Index ++ )
  908. {
  909. PartitionSet *t_KeyPartition = m_PropertyContainer [ a_PropertyIndex ].m_KeyPartition [ t_Index ] ;
  910. WmiRangeNode *t_Range = t_KeyPartition->GetRange () ;
  911. t_KeyProperty = t_SnmpObject->NextKeyProperty () ;
  912. if ( ! t_Range->InfiniteUpperBound () )
  913. {
  914. // if we are in the middle partition we need to delete
  915. //
  916. // 00 <- 0 | 0 <---> n | n -> 00
  917. // no infinite upperbound | no infinite lowerbound | infinite lowerbound
  918. //
  919. // it may be allocated before and none will delete it
  920. if ( m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierEnd [ t_Index ] )
  921. {
  922. delete m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierEnd [ t_Index ];
  923. m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierEnd [ t_Index ] = NULL;
  924. }
  925. m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierEnd [ t_Index ] = new SnmpObjectIdentifier ( 0 , NULL ) ;
  926. if ( typeid ( *t_Range ) == typeid ( WmiUnsignedIntegerRangeNode ) )
  927. {
  928. WmiUnsignedIntegerRangeNode *t_Node = ( WmiUnsignedIntegerRangeNode * ) t_Range ;
  929. ULONG t_Integer = t_Node->UpperBound () ;
  930. VARIANT t_Variant ;
  931. VariantInit ( & t_Variant ) ;
  932. t_Variant.vt = VT_I4 ;
  933. t_Variant.lVal = t_Integer ;
  934. t_KeyProperty->Encode ( t_Variant , * m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierEnd [ t_Index ] ) ;
  935. VariantClear ( & t_Variant ) ;
  936. }
  937. else if ( typeid ( *t_Range ) == typeid ( WmiSignedIntegerRangeNode ) )
  938. {
  939. WmiSignedIntegerRangeNode *t_Node = ( WmiSignedIntegerRangeNode * ) t_Range ;
  940. LONG t_Integer = t_Node->UpperBound () ;
  941. VARIANT t_Variant ;
  942. VariantInit ( & t_Variant ) ;
  943. t_Variant.vt = VT_I4 ;
  944. t_Variant.lVal = t_Integer ;
  945. t_KeyProperty->Encode ( t_Variant , * m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierEnd [ t_Index ] ) ;
  946. VariantClear ( & t_Variant ) ;
  947. }
  948. if ( typeid ( *t_Range ) == typeid ( WmiStringRangeNode ) )
  949. {
  950. WmiStringRangeNode *t_Node = ( WmiStringRangeNode * ) t_Range ;
  951. BSTR t_String = t_Node->UpperBound () ;
  952. VARIANT t_Variant ;
  953. VariantInit ( & t_Variant ) ;
  954. t_Variant.vt = VT_BSTR ;
  955. t_Variant.bstrVal = SysAllocString ( t_String ) ;
  956. t_KeyProperty->Encode ( t_Variant , * m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierEnd [ t_Index ] ) ;
  957. VariantClear ( & t_Variant ) ;
  958. }
  959. if ( t_Range->ClosedUpperBound () )
  960. {
  961. SnmpObjectIdentifier *t_End = m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierEnd [ t_Index ] ;
  962. if ( IncrementObjectIdentifier ( * t_End , * t_End ) )
  963. {
  964. }
  965. else
  966. {
  967. if ( m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierEnd [ t_Index ] )
  968. {
  969. delete m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierEnd [ t_Index ];
  970. m_PropertyContainer [ a_PropertyIndex ].m_ObjectIdentifierEnd [ t_Index ] = NULL;
  971. }
  972. }
  973. }
  974. }
  975. }
  976. return t_Scoped ;
  977. }