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.

523 lines
14 KiB

  1. //***************************************************************************
  2. //
  3. // MINISERV.CPP
  4. //
  5. // Module: OLE MS SNMP Property Provider
  6. //
  7. // Purpose: Implementation for the SnmpGetEventObject class.
  8. //
  9. // Copyright (c) 1996-2001 Microsoft Corporation, All Rights Reserved
  10. //
  11. //***************************************************************************
  12. #include "precomp.h"
  13. #include <provexpt.h>
  14. #include <snmptempl.h>
  15. #include <snmpmt.h>
  16. #include <typeinfo.h>
  17. #include <process.h>
  18. #include <objbase.h>
  19. #include <stdio.h>
  20. #include <wbemidl.h>
  21. #include "classfac.h"
  22. #include "guids.h"
  23. #include <snmpcont.h>
  24. #include <snmpevt.h>
  25. #include <snmpthrd.h>
  26. #include <snmplog.h>
  27. #include <snmpcl.h>
  28. #include <instpath.h>
  29. #include <snmptype.h>
  30. #include <snmpauto.h>
  31. #include <snmpobj.h>
  32. #include <genlex.h>
  33. #include <sql_1.h>
  34. #include <objpath.h>
  35. #include <provtree.h>
  36. #include <provdnf.h>
  37. #include "propprov.h"
  38. #include "propsnmp.h"
  39. #include "propget.h"
  40. #include "snmpget.h"
  41. GetOperation :: GetOperation (
  42. IN SnmpSession &sessionArg ,
  43. IN SnmpGetResponseEventObject *eventObjectArg
  44. ) : SnmpGetOperation ( sessionArg ) ,
  45. session ( & sessionArg ) ,
  46. varBindsReceived ( 0 ) ,
  47. erroredVarBindsReceived ( 0 ) ,
  48. eventObject ( eventObjectArg ) ,
  49. virtuals ( FALSE ) ,
  50. virtualsInitialised ( FALSE ) ,
  51. m_PropertyContainer ( NULL ) ,
  52. m_PropertyContainerLength ( 0 )
  53. {
  54. }
  55. GetOperation :: ~GetOperation ()
  56. {
  57. delete [] m_PropertyContainer ;
  58. session->DestroySession () ;
  59. }
  60. void GetOperation :: ReceiveResponse ()
  61. {
  62. // Inform creator all is done
  63. if ( varBindsReceived == 0 )
  64. {
  65. /*
  66. * Don't mask errors encountered previously
  67. */
  68. if ( eventObject->GetErrorObject ().GetWbemStatus () == S_OK )
  69. {
  70. eventObject->GetErrorObject ().SetStatus ( WBEM_SNMP_E_INVALID_OBJECT ) ;
  71. eventObject->GetErrorObject ().SetWbemStatus ( WBEM_E_NOT_FOUND ) ;
  72. eventObject->GetErrorObject ().SetMessage ( L"Instance unknown" ) ;
  73. }
  74. }
  75. else
  76. {
  77. if ( FAILED ( eventObject->GetErrorObject ().GetWbemStatus () ) )
  78. {
  79. if ( eventObject->GetErrorObject ().GetStatus () == WBEM_SNMP_E_TRANSPORT_NO_RESPONSE )
  80. {
  81. eventObject->GetErrorObject ().SetWbemStatus ( WBEM_S_TIMEDOUT ) ;
  82. }
  83. }
  84. }
  85. eventObject->ReceiveComplete () ;
  86. }
  87. void GetOperation :: ReceiveVarBindResponse (
  88. IN const ULONG &var_bind_index,
  89. IN const SnmpVarBind &requestVarBind ,
  90. IN const SnmpVarBind &replyVarBind ,
  91. IN const SnmpErrorReport &error
  92. )
  93. {
  94. varBindsReceived ++ ;
  95. IWbemClassObject *snmpObject = eventObject->GetInstanceObject () ;
  96. if ( ( typeid ( replyVarBind.GetValue () ) == typeid ( SnmpNoSuchObject ) ) || ( typeid ( replyVarBind.GetValue () ) == typeid ( SnmpNoSuchInstance ) ) )
  97. {
  98. }
  99. else
  100. {
  101. // Set Property value
  102. WbemSnmpProperty *property = m_PropertyContainer [ var_bind_index - 1 ] ;
  103. SnmpValue &value = replyVarBind.GetValue () ;
  104. // Set Property value
  105. if ( property->SetValue ( snmpObject , &value , SetValueRegardlessReturnCheck ) )
  106. {
  107. // Set worked
  108. }
  109. else
  110. {
  111. // Type Mismatch
  112. property->AddQualifier ( WBEM_QUALIFIER_TYPE_MISMATCH ) ;
  113. WbemSnmpQualifier *qualifier = property->FindQualifier ( WBEM_QUALIFIER_TYPE_MISMATCH ) ;
  114. if ( qualifier )
  115. {
  116. IWbemQualifierSet *t_QualifierSet = NULL;
  117. HRESULT result = snmpObject->GetPropertyQualifierSet ( property->GetName () , & t_QualifierSet ) ;
  118. if ( SUCCEEDED ( result ) )
  119. {
  120. SnmpIntegerType integer ( 1 , NULL ) ;
  121. qualifier->SetValue ( t_QualifierSet , integer ) ;
  122. }
  123. t_QualifierSet->Release () ;
  124. }
  125. }
  126. if ( virtuals && virtualsInitialised == FALSE )
  127. {
  128. // Get Phantom Key properties from first Variable Binding of Row
  129. BOOL status = TRUE ;
  130. SnmpObjectIdentifier decodeObject ( NULL , 0 ) ;
  131. //remove object info so we're left with instance (key) info only
  132. WbemSnmpQualifier *qualifier = property->FindQualifier ( WBEM_QUALIFIER_OBJECT_IDENTIFIER ) ;
  133. if ( qualifier )
  134. {
  135. SnmpInstanceType *value = qualifier->GetValue () ;
  136. if ( typeid ( *value ) == typeid ( SnmpObjectIdentifierType ) )
  137. {
  138. SnmpObjectIdentifierType *objectIdentifierType = ( SnmpObjectIdentifierType * ) value ;
  139. replyVarBind.GetInstance().Suffix( objectIdentifierType->GetValueLength () , decodeObject ) ;
  140. }
  141. }
  142. SnmpGetClassObject *t_SnmpObject = ( SnmpGetClassObject * ) eventObject->GetSnmpClassObject () ;
  143. WbemSnmpProperty *property ;
  144. t_SnmpObject->ResetKeyProperty () ;
  145. while ( status && ( property = t_SnmpObject->NextKeyProperty () ) )
  146. {
  147. // For each Phantom Key in Key Order consume instance information
  148. SnmpInstanceType *decodeValue = property->GetValue () ;
  149. decodeObject = decodeValue->Decode ( decodeObject ) ;
  150. if ( *decodeValue )
  151. {
  152. // Decode worked correctly
  153. const SnmpValue *value = decodeValue->GetValueEncoding () ;
  154. // Set Property value for Phantom Key
  155. property->SetValue ( snmpObject , value , SetValueRegardlessReturnCheck ) ;
  156. }
  157. else
  158. {
  159. // Decode Error therefore set TYPE MISMATCH for all Phantom keys
  160. WbemSnmpProperty *property ;
  161. t_SnmpObject->ResetKeyProperty () ;
  162. while ( property = t_SnmpObject->NextKeyProperty () )
  163. {
  164. WbemSnmpQualifier *qualifier = NULL ;
  165. property->AddQualifier ( WBEM_QUALIFIER_TYPE_MISMATCH ) ;
  166. if ( qualifier = property->FindQualifier ( WBEM_QUALIFIER_TYPE_MISMATCH ) )
  167. {
  168. // Property which is a phantom key could not be decoded correctly.
  169. IWbemQualifierSet *t_QualifierSet = NULL;
  170. HRESULT result = snmpObject->GetPropertyQualifierSet ( property->GetName () , & t_QualifierSet ) ;
  171. if ( SUCCEEDED ( result ) )
  172. {
  173. SnmpIntegerType integer ( 1 , NULL ) ;
  174. qualifier->SetValue ( t_QualifierSet , integer ) ;
  175. }
  176. t_QualifierSet->Release () ;
  177. }
  178. else
  179. {
  180. // Problem Here
  181. }
  182. }
  183. status = FALSE ;
  184. }
  185. }
  186. // Check we have consumed all instance information
  187. if ( decodeObject.GetValueLength () )
  188. {
  189. // Decode Error therefore set TYPE MISMATCH for all Phantom keys
  190. WbemSnmpProperty *property ;
  191. t_SnmpObject->ResetKeyProperty () ;
  192. while ( property = t_SnmpObject->NextKeyProperty () )
  193. {
  194. WbemSnmpQualifier *qualifier = NULL ;
  195. property->AddQualifier ( WBEM_QUALIFIER_TYPE_MISMATCH ) ;
  196. if ( qualifier = property->FindQualifier ( WBEM_QUALIFIER_TYPE_MISMATCH ) )
  197. {
  198. // Property which is a phantom key could not be decoded correctly.
  199. IWbemQualifierSet *t_QualifierSet = NULL;
  200. HRESULT result = snmpObject->GetPropertyQualifierSet ( property->GetName () , & t_QualifierSet ) ;
  201. if ( SUCCEEDED ( result ) )
  202. {
  203. SnmpIntegerType integer ( 1 , NULL ) ;
  204. qualifier->SetValue ( t_QualifierSet , integer ) ;
  205. }
  206. t_QualifierSet->Release () ;
  207. }
  208. else
  209. {
  210. // Problem Here
  211. }
  212. }
  213. }
  214. // No need to set Phantom keys for further columns of row
  215. virtualsInitialised = TRUE ;
  216. }
  217. }
  218. }
  219. #pragma warning (disable:4065)
  220. void GetOperation :: ReceiveErroredVarBindResponse(
  221. IN const ULONG &var_bind_index,
  222. IN const SnmpVarBind &requestVarBind ,
  223. IN const SnmpErrorReport &error
  224. )
  225. {
  226. erroredVarBindsReceived ++ ;
  227. WbemSnmpProperty *property = m_PropertyContainer [ var_bind_index - 1 ] ;
  228. switch ( error.GetError () )
  229. {
  230. case Snmp_Error:
  231. {
  232. switch ( error.GetStatus () )
  233. {
  234. case Snmp_No_Response:
  235. {
  236. eventObject->GetErrorObject ().SetStatus ( WBEM_SNMP_E_TRANSPORT_NO_RESPONSE ) ;
  237. eventObject->GetErrorObject ().SetWbemStatus ( WBEM_E_FAILED ) ;
  238. eventObject->GetErrorObject ().SetMessage ( L"No Response from device" ) ;
  239. }
  240. break;
  241. case Snmp_No_Such_Name:
  242. {
  243. // Invalid property requested
  244. }
  245. break ;
  246. case Snmp_Bad_Value:
  247. {
  248. wchar_t *prefix = UnicodeStringAppend ( L"Agent reported Bad Value for property \'" , property->GetName () ) ;
  249. wchar_t *stringBuffer = UnicodeStringAppend ( prefix , L"\'" ) ;
  250. delete [] prefix ;
  251. eventObject->GetErrorObject ().SetMessage ( stringBuffer ) ;
  252. delete [] stringBuffer ;
  253. eventObject->GetErrorObject ().SetStatus ( WBEM_SNMP_E_TRANSPORT_ERROR ) ;
  254. eventObject->GetErrorObject ().SetWbemStatus ( WBEM_E_FAILED ) ;
  255. }
  256. break ;
  257. case Snmp_Read_Only:
  258. {
  259. eventObject->GetErrorObject ().SetStatus ( WBEM_SNMP_E_TRANSPORT_ERROR ) ;
  260. eventObject->GetErrorObject ().SetWbemStatus ( WBEM_E_FAILED ) ;
  261. wchar_t *prefix = UnicodeStringAppend ( L"Agent reported Read Only for property \'" , property->GetName () ) ;
  262. wchar_t *stringBuffer = UnicodeStringAppend ( prefix , L"\'" ) ;
  263. delete [] prefix ;
  264. eventObject->GetErrorObject ().SetMessage ( stringBuffer ) ;
  265. delete [] stringBuffer ;
  266. }
  267. break ;
  268. case Snmp_Gen_Error:
  269. {
  270. eventObject->GetErrorObject ().SetStatus ( WBEM_SNMP_E_TRANSPORT_ERROR ) ;
  271. eventObject->GetErrorObject ().SetWbemStatus ( WBEM_E_FAILED ) ;
  272. wchar_t *prefix = UnicodeStringAppend ( L"Agent reported General Error for property \'" , property->GetName () ) ;
  273. wchar_t *stringBuffer = UnicodeStringAppend ( prefix , L"\'" ) ;
  274. delete [] prefix ;
  275. eventObject->GetErrorObject ().SetMessage ( stringBuffer ) ;
  276. delete [] stringBuffer ;
  277. }
  278. break ;
  279. case Snmp_Too_Big:
  280. {
  281. eventObject->GetErrorObject ().SetStatus ( WBEM_SNMP_E_TRANSPORT_ERROR ) ;
  282. eventObject->GetErrorObject ().SetWbemStatus ( WBEM_E_FAILED ) ;
  283. wchar_t *prefix = UnicodeStringAppend ( L"Agent reported Too Big for property \'" , property->GetName () ) ;
  284. wchar_t *stringBuffer = UnicodeStringAppend ( prefix , L"\'" ) ;
  285. delete [] prefix ;
  286. eventObject->GetErrorObject ().SetMessage ( stringBuffer ) ;
  287. delete [] stringBuffer ;
  288. }
  289. break ;
  290. default:
  291. {
  292. eventObject->GetErrorObject ().SetStatus ( WBEM_SNMP_E_TRANSPORT_ERROR ) ;
  293. eventObject->GetErrorObject ().SetWbemStatus ( WBEM_E_FAILED ) ;
  294. eventObject->GetErrorObject ().SetMessage ( L"Unknown transport failure" ) ;
  295. }
  296. break ;
  297. }
  298. }
  299. break ;
  300. case Snmp_Transport:
  301. {
  302. switch ( error.GetStatus () )
  303. {
  304. default:
  305. {
  306. eventObject->GetErrorObject ().SetStatus ( WBEM_SNMP_E_TRANSPORT_ERROR ) ;
  307. eventObject->GetErrorObject ().SetWbemStatus ( WBEM_E_FAILED ) ;
  308. eventObject->GetErrorObject ().SetMessage ( L"Unknown transport failure" ) ;
  309. }
  310. break ;
  311. }
  312. }
  313. break ;
  314. default:
  315. {
  316. // Cannot Happen
  317. }
  318. break ;
  319. }
  320. }
  321. #pragma warning (default:4065)
  322. void GetOperation :: FrameTooBig ()
  323. {
  324. }
  325. void GetOperation :: FrameOverRun ()
  326. {
  327. }
  328. void GetOperation :: Send ()
  329. {
  330. // Send Variable Bindings for requested properties
  331. SnmpVarBindList varBindList ;
  332. SnmpNull snmpNull ;
  333. SnmpObjectIdentifier instanceObjectIdentifier ( NULL , 0 ) ;
  334. IWbemClassObject *snmpObject = eventObject->GetInstanceObject () ;
  335. SnmpClassObject *t_SnmpObject = eventObject->GetSnmpClassObject () ;
  336. if ( t_SnmpObject )
  337. {
  338. // Encode Variable Binding instance for all key properties
  339. if ( t_SnmpObject->GetKeyPropertyCount () )
  340. {
  341. WbemSnmpProperty *property ;
  342. t_SnmpObject->ResetKeyProperty () ;
  343. while ( property = t_SnmpObject->NextKeyProperty () )
  344. {
  345. instanceObjectIdentifier = property->GetValue()->Encode ( instanceObjectIdentifier ) ;
  346. }
  347. }
  348. else
  349. {
  350. SnmpIntegerType integerType ( ( LONG ) 0 , NULL ) ;
  351. instanceObjectIdentifier = integerType.Encode ( instanceObjectIdentifier ) ;
  352. }
  353. virtuals = FALSE ;
  354. WbemSnmpProperty *property ;
  355. t_SnmpObject->ResetProperty () ;
  356. while ( property = t_SnmpObject->NextProperty () )
  357. {
  358. if ( property->IsKey () && property->IsVirtualKey () )
  359. {
  360. // There are some properties which are phantom
  361. virtuals = TRUE ;
  362. }
  363. if ( property->IsReadable () )
  364. {
  365. BOOL t_Status = ( t_SnmpObject->GetSnmpVersion () == 1 ) && ( property->IsSNMPV1Type () ) ;
  366. t_Status = t_Status || ( ( t_SnmpObject->GetSnmpVersion () == 2 ) && ( property->IsSNMPV2CType () ) ) ;
  367. if ( t_Status )
  368. {
  369. if ( property->IsVirtualKey () == FALSE )
  370. {
  371. m_PropertyContainerLength ++ ;
  372. }
  373. }
  374. }
  375. }
  376. m_PropertyContainer = new WbemSnmpProperty * [ m_PropertyContainerLength ] ;
  377. // Add Variable binding to Variable binding list
  378. // Insert new Object Identifier / Property Hash entries for newly created object
  379. ULONG t_Index = 0 ;
  380. t_SnmpObject->ResetProperty () ;
  381. while ( property = t_SnmpObject->NextProperty () )
  382. {
  383. if ( property->IsReadable () )
  384. {
  385. BOOL t_Status = ( t_SnmpObject->GetSnmpVersion () == 1 ) && ( property->IsSNMPV1Type () ) ;
  386. t_Status = t_Status || ( ( t_SnmpObject->GetSnmpVersion () == 2 ) && ( property->IsSNMPV2CType () ) ) ;
  387. if ( t_Status )
  388. {
  389. if ( property->IsVirtualKey () == FALSE )
  390. {
  391. WbemSnmpQualifier *qualifier = property->FindQualifier ( WBEM_QUALIFIER_OBJECT_IDENTIFIER ) ;
  392. if ( qualifier )
  393. {
  394. SnmpInstanceType *value = qualifier->GetValue () ;
  395. if ( typeid ( *value ) == typeid ( SnmpObjectIdentifierType ) )
  396. {
  397. SnmpObjectIdentifierType *objectIdentifierType = ( SnmpObjectIdentifierType * ) value ;
  398. SnmpObjectIdentifier *objectIdentifier = ( SnmpObjectIdentifier * ) objectIdentifierType->GetValueEncoding () ;
  399. SnmpObjectIdentifier requestIdentifier = *objectIdentifier + instanceObjectIdentifier ;
  400. SnmpObjectIdentifierType requestIdentifierType ( requestIdentifier ) ;
  401. m_PropertyContainer [ t_Index ] = property ;
  402. SnmpVarBind varBind ( requestIdentifier , snmpNull ) ;
  403. varBindList.Add ( varBind ) ;
  404. t_Index ++ ;
  405. }
  406. else
  407. {
  408. // Problem Here
  409. }
  410. }
  411. else
  412. {
  413. // Problem Here
  414. }
  415. }
  416. else
  417. {
  418. // Don't retrieve properties marked as virtual keys.
  419. }
  420. }
  421. }
  422. /*
  423. * Initialise value to NULL
  424. */
  425. property->SetValue ( snmpObject , ( SnmpValue * ) NULL ) ;
  426. }
  427. // Finally Send request
  428. SendRequest ( varBindList ) ;
  429. }
  430. else
  431. {
  432. // Problem Here
  433. }
  434. }