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.

2365 lines
50 KiB

  1. //***************************************************************************
  2. //
  3. // File:
  4. //
  5. // Module: MS SNMP Provider
  6. //
  7. // Purpose:
  8. //
  9. // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
  10. //
  11. //***************************************************************************
  12. #include <precomp.h>
  13. #include "csmir.h"
  14. #include "smir.h"
  15. #include "handles.h"
  16. #include "classfac.h"
  17. #include "enum.h"
  18. #include "textdef.h"
  19. #include "helper.h"
  20. #include "bstring.h"
  21. #ifdef ICECAP_PROFILE
  22. #include <icapexp.h>
  23. #endif
  24. CEnumSmirMod :: CEnumSmirMod( CSmir *a_Smir )
  25. {
  26. //zero the reference count
  27. m_cRef=0;
  28. //set the index to the first element
  29. m_Index=0;
  30. //open the smir - create it if you can't open it
  31. IWbemServices * moServ = NULL ;
  32. IWbemContext *moContext = NULL ;
  33. SCODE res= CSmirAccess :: GetContext (a_Smir , &moContext);
  34. res= CSmirAccess :: Open(a_Smir,&moServ);
  35. if ((S_FALSE==res)||(NULL == moServ))
  36. {
  37. //we have a problem
  38. if ( moContext )
  39. moContext->Release () ;
  40. return;
  41. }
  42. //I have now opened the smir namespace so look at the module namespaces
  43. IEnumWbemClassObject *pEnum = NULL ;
  44. //enumerate all of the namespaces that have a __CLASS of MODULE
  45. CBString t_BStr (MODULE_NAMESPACE_NAME);
  46. SCODE sRes = moServ->CreateInstanceEnum(t_BStr.GetString (),
  47. RESERVED_WBEM_FLAG,moContext, &pEnum);
  48. if ( moContext )
  49. moContext->Release () ;
  50. moServ->Release();
  51. if (FAILED(sRes)||(NULL==pEnum))
  52. {
  53. //we have another problem or we have no modules to enumerate
  54. return;
  55. }
  56. ULONG uCount=1;
  57. IWbemClassObject *pSmirMosClassObject = NULL ;
  58. ULONG puReturned;
  59. //OK we have some so loop over the namespaces
  60. for(pEnum->Reset();S_OK==pEnum->Next(-1,uCount,&pSmirMosClassObject,&puReturned);)
  61. {
  62. ISmirModHandle *pTModule = NULL ;
  63. SCODE result = g_pClassFactoryHelper->CreateInstance(CLSID_SMIR_ModHandle,
  64. IID_ISMIR_ModHandle,(PVOID *)&pTModule);
  65. if (FAILED(result)||(NULL == pTModule))
  66. {
  67. //problem!
  68. pSmirMosClassObject->Release();
  69. pEnum->Release();
  70. //add some trace
  71. break;
  72. }
  73. /*things are looking good; we have the handle to the instance so get the info
  74. *some of there properties may be blank so be defensive (SysAllocStrig does
  75. *most of this for us)
  76. */
  77. //extract the properties
  78. *((CSmirModuleHandle*)pTModule) << pSmirMosClassObject;
  79. pSmirMosClassObject->Release();
  80. pSmirMosClassObject=NULL;
  81. m_IHandleArray.Add(pTModule);
  82. }
  83. pEnum->Release();
  84. /*as soon as this returns the caller (me) will addref and pass the
  85. *interface back to the [real] caller. => I will have to guard against
  86. *someone releasing the interface whilst I'm using it.
  87. */
  88. }
  89. CEnumSmirMod :: CEnumSmirMod(IEnumModule *pSmirMod)
  90. {
  91. //zero the reference count
  92. m_cRef=0;
  93. //set the index to the first element
  94. m_Index=0;
  95. if (NULL == pSmirMod)
  96. {
  97. return;
  98. }
  99. ULONG uCount=1;
  100. ISmirModHandle *pModule = NULL ;
  101. ULONG puReturned = 0;
  102. //OK loop over the module namespaces
  103. for(pSmirMod->Reset();S_OK==pSmirMod->Next(uCount,&pModule,&puReturned);)
  104. {
  105. ISmirModHandle *pTModule = NULL ;
  106. SCODE result = pModule->QueryInterface(IID_ISMIR_ModHandle,(void**)&pTModule );
  107. pModule->Release();
  108. if(S_OK != result)
  109. {
  110. //this is not going to happen! I know which interface it is.
  111. return ;
  112. }
  113. /*things are looking good; we have the handle to the instance so
  114. *add it to the array
  115. */
  116. m_IHandleArray.Add(pTModule);
  117. }
  118. }
  119. CEnumSmirMod :: ~CEnumSmirMod ()
  120. {
  121. /*let the EnumObjectArray empty the module array and delete the
  122. *modules I created
  123. */
  124. }
  125. /*
  126. * CEnumSmirMod::QueryInterface
  127. *
  128. * Purpose:
  129. * Manages the interfaces for this object which supports the
  130. * IUnknown interface.
  131. *
  132. * Parameters:
  133. * riid REFIID of the interface to return.
  134. * ppv PPVOID in which to store the pointer.
  135. *
  136. * Return Value:
  137. * SCODE NOERROR on success, E_NOINTERFACE if the
  138. * interface is not supported.
  139. */
  140. STDMETHODIMP CEnumSmirMod::QueryInterface(IN REFIID riid,
  141. OUT PPVOID ppv)
  142. {
  143. SetStructuredExceptionHandler seh;
  144. try
  145. {
  146. //Always NULL the out-parameters
  147. *ppv=NULL;
  148. if (IID_IUnknown==riid)
  149. *ppv=this;
  150. if (IID_ISMIR_ModuleEnumerator==riid)
  151. *ppv=this;
  152. if (NULL==*ppv)
  153. {
  154. return ResultFromScode(E_NOINTERFACE);
  155. }
  156. //AddRef any interface we'll return.
  157. ((LPUNKNOWN)*ppv)->AddRef();
  158. return NOERROR;
  159. }
  160. catch(Structured_Exception e_SE)
  161. {
  162. return E_UNEXPECTED;
  163. }
  164. catch(Heap_Exception e_HE)
  165. {
  166. return E_OUTOFMEMORY;
  167. }
  168. catch(...)
  169. {
  170. return E_UNEXPECTED;
  171. }
  172. }
  173. SCODE CEnumSmirMod::Clone(IN IEnumModule **ppenum)
  174. {
  175. SetStructuredExceptionHandler seh;
  176. try
  177. {
  178. if(NULL == ppenum)
  179. return E_INVALIDARG;
  180. int ModIndex = m_Index;
  181. PENUMSMIRMOD pTmpEnumSmirMod = new CEnumSmirMod(this);
  182. m_Index = ModIndex;
  183. //we have an enumerator so get the interface to pass back
  184. if(NULL == pTmpEnumSmirMod)
  185. {
  186. return ResultFromScode(E_OUTOFMEMORY);
  187. }
  188. pTmpEnumSmirMod->QueryInterface(IID_ISMIR_ModuleEnumerator,(void**)ppenum);
  189. return ResultFromScode(S_OK);
  190. }
  191. catch(Structured_Exception e_SE)
  192. {
  193. return E_UNEXPECTED;
  194. }
  195. catch(Heap_Exception e_HE)
  196. {
  197. return E_OUTOFMEMORY;
  198. }
  199. catch(...)
  200. {
  201. return E_UNEXPECTED;
  202. }
  203. }
  204. /*
  205. * CEnumSmirGroup::QueryInterface
  206. *
  207. * Purpose:
  208. * Manages the interfaces for this object which supports the
  209. * IUnknowninterface.
  210. *
  211. * Parameters:
  212. * riid REFIID of the interface to return.
  213. * ppv PPVOID in which to store the pointer.
  214. *
  215. * Return Value:
  216. * SCODE NOERROR on success, E_NOINTERFACE if the
  217. * interface is not supported.
  218. */
  219. STDMETHODIMP CEnumSmirGroup::QueryInterface(IN REFIID riid,
  220. OUT PPVOID ppv)
  221. {
  222. SetStructuredExceptionHandler seh;
  223. try
  224. {
  225. //Always NULL the out-parameters
  226. *ppv=NULL;
  227. if (IID_IUnknown==riid)
  228. *ppv=this;
  229. if (IID_ISMIR_GroupEnumerator==riid)
  230. *ppv=this;
  231. if (NULL==*ppv)
  232. return ResultFromScode(E_NOINTERFACE);
  233. //AddRef any interface we'll return.
  234. ((LPUNKNOWN)*ppv)->AddRef();
  235. return NOERROR;
  236. }
  237. catch(Structured_Exception e_SE)
  238. {
  239. return E_UNEXPECTED;
  240. }
  241. catch(Heap_Exception e_HE)
  242. {
  243. return E_OUTOFMEMORY;
  244. }
  245. catch(...)
  246. {
  247. return E_UNEXPECTED;
  248. }
  249. }
  250. SCODE CEnumSmirGroup::Clone(OUT IEnumGroup **ppenum)
  251. {
  252. SetStructuredExceptionHandler seh;
  253. try
  254. {
  255. if (NULL == ppenum)
  256. return E_INVALIDARG;
  257. int GroupIndex = m_Index;
  258. PENUMSMIRGROUP pTmpEnumSmirGroup = new CEnumSmirGroup(this);
  259. m_Index = GroupIndex;
  260. //we have an enumerator so get the interface to pass back
  261. if(NULL == pTmpEnumSmirGroup)
  262. {
  263. return ResultFromScode(E_OUTOFMEMORY);
  264. }
  265. pTmpEnumSmirGroup->QueryInterface(IID_ISMIR_GroupEnumerator,(void**)ppenum);
  266. return ResultFromScode(S_OK);
  267. }
  268. catch(Structured_Exception e_SE)
  269. {
  270. return E_UNEXPECTED;
  271. }
  272. catch(Heap_Exception e_HE)
  273. {
  274. return E_OUTOFMEMORY;
  275. }
  276. catch(...)
  277. {
  278. return E_UNEXPECTED;
  279. }
  280. }
  281. CEnumSmirGroup :: ~CEnumSmirGroup ()
  282. {
  283. /*let the EnumObjectArray empty the module array and delete the
  284. *modules I created
  285. */
  286. }
  287. CEnumSmirGroup :: CEnumSmirGroup (
  288. IN CSmir *a_Smir ,
  289. IN ISmirModHandle *hModule
  290. )
  291. {
  292. m_cRef=0;
  293. //set the index to the first element
  294. m_Index=0;
  295. //fill in the path etc
  296. if(NULL!=hModule)
  297. {
  298. IWbemServices * moServ = NULL ;
  299. IWbemContext *moContext = NULL ;
  300. SCODE res= CSmirAccess :: GetContext (a_Smir , &moContext);
  301. res= CSmirAccess :: Open(a_Smir,&moServ,hModule);
  302. if ((S_FALSE==res)||(NULL == (void*)moServ))
  303. {
  304. if ( moContext )
  305. moContext->Release () ;
  306. //we have a problem
  307. return;
  308. }
  309. //I have now opened the module namespace so look at the group namespaces
  310. IEnumWbemClassObject *pEnum = NULL ;
  311. CBString t_BStr (GROUP_NAMESPACE_NAME);
  312. SCODE sRes = moServ->CreateInstanceEnum (
  313. t_BStr.GetString (),
  314. RESERVED_WBEM_FLAG,
  315. moContext,
  316. &pEnum
  317. );
  318. if ( moContext )
  319. moContext->Release () ;
  320. moServ->Release();
  321. if (FAILED(sRes)||(NULL == pEnum))
  322. {
  323. //there are no instances
  324. return;
  325. }
  326. ULONG uCount=1;
  327. ULONG puReturned = 0 ;
  328. IWbemClassObject *pSmirMosClassObject = NULL ;
  329. pEnum->Reset();
  330. while(S_OK==pEnum->Next(-1,uCount,&pSmirMosClassObject,&puReturned))
  331. {
  332. ISmirGroupHandle *pTGroup = NULL ;
  333. SCODE result = g_pClassFactoryHelper->CreateInstance(CLSID_SMIR_GroupHandle,
  334. IID_ISMIR_GroupHandle, (PVOID *)&pTGroup);
  335. if (FAILED(result)||(NULL == pTGroup))
  336. {
  337. //we have a problem
  338. pSmirMosClassObject->Release();
  339. break;
  340. }
  341. //save the module name
  342. BSTR szModuleName = NULL ;
  343. hModule->GetName(&szModuleName);
  344. pTGroup->SetModuleName(szModuleName);
  345. SysFreeString(szModuleName);
  346. //extract the properties
  347. *((CSmirGroupHandle*)pTGroup) << pSmirMosClassObject;
  348. //release this resource here because we are in a loop
  349. pSmirMosClassObject->Release();
  350. m_IHandleArray.Add(pTGroup);
  351. }
  352. pEnum->Release();
  353. }
  354. else
  355. {
  356. //open the smir and enumerate the modules
  357. ISmirInterrogator *pInterrogativeInt = NULL ;
  358. SCODE result = a_Smir->QueryInterface (
  359. IID_ISMIR_Interrogative,
  360. ( void ** ) &pInterrogativeInt
  361. ) ;
  362. if (S_OK != result)
  363. {
  364. if(NULL != pInterrogativeInt)
  365. pInterrogativeInt->Release();
  366. return ;
  367. }
  368. IEnumModule *pEnumSmirMod = NULL ;
  369. //ok now let's use the interrogative interface
  370. result = pInterrogativeInt->EnumModules(&pEnumSmirMod);
  371. //now use the enumerator
  372. if((S_OK != result)||(NULL == pEnumSmirMod))
  373. {
  374. pInterrogativeInt->Release();
  375. //no modules
  376. return;
  377. }
  378. ISmirModHandle *phModule = NULL ;
  379. for(int iCount=0;S_OK==pEnumSmirMod->Next(1, &phModule, NULL);iCount++)
  380. {
  381. //we have the module so get the groups via the enumerator
  382. IEnumGroup *pEnumSmirGroup = NULL ;
  383. result = pInterrogativeInt->EnumGroups(&pEnumSmirGroup,phModule);
  384. //now use the enumerator
  385. if((S_OK == result)&&(pEnumSmirGroup))
  386. {
  387. ISmirGroupHandle *phGroup = NULL ;
  388. for(int iCount=0;S_OK==pEnumSmirGroup->Next(1, &phGroup, NULL);iCount++)
  389. {
  390. m_IHandleArray.Add(phGroup);
  391. }
  392. }
  393. phModule->Release();
  394. pEnumSmirGroup->Release();
  395. }
  396. pEnumSmirMod->Release();
  397. pInterrogativeInt->Release();
  398. }
  399. }
  400. CEnumSmirGroup :: CEnumSmirGroup(IN IEnumGroup *pSmirGroup)
  401. {
  402. //zero the reference count
  403. m_cRef=0;
  404. //set the index to the first element
  405. m_Index=0;
  406. if(NULL == pSmirGroup)
  407. {
  408. //bad args
  409. return;
  410. }
  411. ULONG uCount=1;
  412. ISmirGroupHandle *pGroup = NULL ;
  413. ULONG puReturned;
  414. //OK loop over the group namespaces
  415. for(pSmirGroup->Reset();S_OK==pSmirGroup->Next(uCount,&pGroup,&puReturned);)
  416. {
  417. ISmirGroupHandle *pTGroup =NULL ;
  418. SCODE result = pGroup->QueryInterface(IID_ISMIR_ModHandle,(void**)&pTGroup );
  419. pGroup->Release();
  420. if(S_OK != result)
  421. {
  422. //this is not going to happen! I know which interface it is.
  423. return ;
  424. }
  425. /*things are looking good; we have the handle to the instance so
  426. *add it to out array
  427. */
  428. m_IHandleArray.Add(pTGroup);
  429. }
  430. }
  431. /*
  432. * CEnumSmirClass::QueryInterface
  433. *
  434. * Purpose:
  435. * Manages the interfaces for this object which supports the
  436. * IUnknowninterface.
  437. *
  438. * Parameters:
  439. * riid REFIID of the interface to return.
  440. * ppv PPVOID in which to store the pointer.
  441. *
  442. * Return Value:
  443. * SCODE NOERROR on success, E_NOINTERFACE if the
  444. * interface is not supported.
  445. */
  446. STDMETHODIMP CEnumSmirClass :: QueryInterface(IN REFIID riid,
  447. OUT PPVOID ppv)
  448. {
  449. SetStructuredExceptionHandler seh;
  450. try
  451. {
  452. //Always NULL the out-parameters
  453. *ppv=NULL;
  454. if (IID_IUnknown==riid)
  455. *ppv=this;
  456. if (IID_ISMIR_ClassEnumerator==riid)
  457. *ppv=this;
  458. if (NULL==*ppv)
  459. return ResultFromScode(E_NOINTERFACE);
  460. //AddRef any interface we'll return.
  461. ((LPUNKNOWN)*ppv)->AddRef();
  462. return NOERROR;
  463. }
  464. catch(Structured_Exception e_SE)
  465. {
  466. return E_UNEXPECTED;
  467. }
  468. catch(Heap_Exception e_HE)
  469. {
  470. return E_OUTOFMEMORY;
  471. }
  472. catch(...)
  473. {
  474. return E_UNEXPECTED;
  475. }
  476. }
  477. STDMETHODIMP CEnumSmirClass::Clone(IEnumClass **ppenum)
  478. {
  479. SetStructuredExceptionHandler seh;
  480. try
  481. {
  482. if(NULL == ppenum)
  483. return E_INVALIDARG;
  484. int ClassIndex = m_Index;
  485. PENUMSMIRCLASS pTmpEnumSmirClass = new CEnumSmirClass(this);
  486. m_Index = ClassIndex;
  487. //we have an enumerator so get the interface to pass back
  488. if(NULL == pTmpEnumSmirClass)
  489. {
  490. return ResultFromScode(E_OUTOFMEMORY);
  491. }
  492. if(NOERROR == pTmpEnumSmirClass->QueryInterface(IID_ISMIR_ClassEnumerator,(void**)ppenum))
  493. return S_OK;
  494. return E_UNEXPECTED;
  495. }
  496. catch(Structured_Exception e_SE)
  497. {
  498. return E_UNEXPECTED;
  499. }
  500. catch(Heap_Exception e_HE)
  501. {
  502. return E_OUTOFMEMORY;
  503. }
  504. catch(...)
  505. {
  506. return E_UNEXPECTED;
  507. }
  508. }
  509. CEnumSmirClass :: CEnumSmirClass(IEnumClass *pSmirClass)
  510. {
  511. //zero the reference count
  512. m_cRef=0;
  513. //set the index to the first element
  514. m_Index=0;
  515. ULONG uCount=1;
  516. ISmirClassHandle *pClass = NULL ;
  517. ULONG puReturned;
  518. //OK loop through the enumerator
  519. for(pSmirClass->Reset();S_OK==pSmirClass->Next(uCount,&pClass,&puReturned);)
  520. {
  521. ISmirClassHandle *pTClass = NULL ;
  522. SCODE result = pClass->QueryInterface(IID_ISMIR_ClassHandle,(void**)&pTClass );
  523. pClass->Release();
  524. if(S_OK != result)
  525. {
  526. //this is not going to happen! I know which interface it is.
  527. return ;
  528. }
  529. /*things are looking good; we have the handle to the instance so
  530. *add it to out array
  531. */
  532. m_IHandleArray.Add(pTClass);
  533. }
  534. }
  535. /*enumerate all of the classes in the smir
  536. */
  537. CEnumSmirClass :: CEnumSmirClass(
  538. CSmir *a_Smir ,
  539. ISmirDatabase *pSmir,
  540. DWORD dwCookie
  541. )
  542. {
  543. //zero the reference count
  544. m_cRef=0;
  545. //set the index to the first element
  546. m_Index=0;
  547. //open the smir
  548. IWbemServices *moServ = NULL ; //pointer to the provider
  549. IWbemContext *moContext = NULL ;
  550. SCODE res= CSmirAccess :: GetContext (a_Smir , &moContext);
  551. res= CSmirAccess :: Open(a_Smir,&moServ);
  552. if ((S_FALSE==res)||(moServ == NULL))
  553. {
  554. if ( moContext )
  555. moContext->Release () ;
  556. //we have a problem
  557. return;
  558. }
  559. IEnumWbemClassObject *pEnum = NULL ;
  560. CBString t_Bstr(HMOM_SNMPOBJECTTYPE_STRING);
  561. SCODE sRes = moServ->CreateClassEnum (
  562. t_Bstr.GetString(),
  563. WBEM_FLAG_SHALLOW,
  564. moContext,
  565. &pEnum
  566. );
  567. if ( moContext )
  568. moContext->Release () ;
  569. moServ->Release();
  570. if (FAILED(sRes)||(NULL==pEnum))
  571. {
  572. //problem or we have no classes to enumerate
  573. return ;
  574. }
  575. //we have some classes so add them to the enumerator
  576. ULONG uCount=1;
  577. IWbemClassObject *pSmirMosClassObject = NULL ;
  578. ULONG puReturned = 0 ;
  579. //loop over the classes
  580. for(pEnum->Reset();S_OK==pEnum->Next(-1,uCount,&pSmirMosClassObject,&puReturned);)
  581. {
  582. ISmirClassHandle *pTClass = NULL ;
  583. //got one so wrap it to go
  584. res = g_pClassFactoryHelper->CreateInstance(CLSID_SMIR_ClassHandle,
  585. IID_ISMIR_ClassHandle, (PVOID *)&pTClass);
  586. if (FAILED(res))
  587. {
  588. //we have a problem
  589. pSmirMosClassObject->Release();
  590. return;
  591. }
  592. pTClass->SetWBEMClass(pSmirMosClassObject);
  593. //drop it in the enumeration array
  594. m_IHandleArray.Add(pTClass);
  595. //if this is an async enumeration signal the connectable object
  596. pSmirMosClassObject->Release();
  597. }
  598. pEnum->Release();
  599. }
  600. CEnumSmirClass :: CEnumSmirClass(
  601. CSmir *a_Smir ,
  602. ISmirDatabase *pSmir,
  603. ISmirGroupHandle *hGroup,
  604. DWORD dwCookie
  605. )
  606. {
  607. //zero the reference count
  608. m_cRef=0;
  609. //set the index to the first element
  610. m_Index=0;
  611. if(((CSmirGroupHandle*)hGroup)==NULL)
  612. {
  613. return;
  614. }
  615. //open the smir
  616. IWbemServices *moServ = NULL ; //pointer to the provider
  617. IWbemContext *moContext = NULL ;
  618. SCODE res= CSmirAccess :: GetContext (a_Smir , &moContext);
  619. res= CSmirAccess :: Open(a_Smir,&moServ,hGroup,CSmirAccess::eModule);
  620. if ((S_FALSE==res)||(moServ == NULL))
  621. {
  622. if ( moContext )
  623. moContext->Release () ;
  624. //we have a problem
  625. return;
  626. }
  627. BSTR szTmpGroupName = NULL ; //the group name
  628. BSTR szTmpModuleName = NULL ; //the module name
  629. hGroup->GetName(&szTmpGroupName); //the group name
  630. hGroup->GetModuleName(&szTmpModuleName); //the module name
  631. /*query for
  632. *associators of {\\.\root\default\SMIR\<module>:Group="<group>"}
  633. */
  634. CString sQuery(CString(SMIR_ASSOC_QUERY_STR1)
  635. +CString(OPEN_BRACE_STR)
  636. +CString(SMIR_NAMESPACE_FROM_ROOT)
  637. +CString(BACKSLASH_STR)
  638. +CString(szTmpModuleName)
  639. +CString(COLON_STR)
  640. +CString(GROUP_NAMESPACE_NAME)
  641. +CString(EQUALS_STR)
  642. +CString(QUOTE_STR)
  643. +CString(szTmpGroupName)
  644. +CString(QUOTE_STR)
  645. +CString(CLOSE_BRACE_STR)
  646. );
  647. BSTR szQuery = sQuery.AllocSysString();
  648. IEnumWbemClassObject *pEnum = NULL ;
  649. CBString t_QueryFormat (SMIR_ASSOC_QUERY1_TYPE);
  650. SCODE sRes = moServ->ExecQuery (
  651. t_QueryFormat.GetString (),
  652. szQuery,
  653. 0,
  654. moContext,
  655. &pEnum
  656. );
  657. SysFreeString(szQuery);
  658. if ( moContext )
  659. moContext->Release () ;
  660. moServ->Release();
  661. if (FAILED(sRes)||(NULL==pEnum))
  662. {
  663. //problem or we have no classes to enumerate
  664. SysFreeString(szTmpGroupName);
  665. SysFreeString(szTmpModuleName);
  666. return ;
  667. }
  668. ULONG uCount=1;
  669. IWbemClassObject *pSmirMosClassObject = NULL ;
  670. ULONG puReturned = 0;
  671. //loop over the classes
  672. for(pEnum->Reset();S_OK==pEnum->Next(-1,uCount,&pSmirMosClassObject,&puReturned);)
  673. {
  674. ISmirClassHandle *pTClass = NULL ;
  675. //got one so wrap it to go
  676. res = g_pClassFactoryHelper->CreateInstance(CLSID_SMIR_ClassHandle,
  677. IID_ISMIR_ClassHandle, (PVOID *)&pTClass);
  678. if (FAILED(res))
  679. {
  680. //we have a problem
  681. SysFreeString(szTmpGroupName);
  682. SysFreeString(szTmpModuleName);
  683. pSmirMosClassObject->Release();
  684. return;
  685. }
  686. //save the module name
  687. pTClass->SetModuleName(szTmpModuleName);
  688. //save the group name
  689. pTClass->SetGroupName(szTmpGroupName);
  690. pTClass->SetWBEMClass(pSmirMosClassObject);
  691. //drop it in the enumeration array
  692. m_IHandleArray.Add(pTClass);
  693. //if this is an async enumeration signal the connectable object
  694. pSmirMosClassObject->Release();
  695. }
  696. SysFreeString(szTmpModuleName);
  697. SysFreeString(szTmpGroupName);
  698. pEnum->Release();
  699. }
  700. CEnumSmirClass :: CEnumSmirClass(
  701. CSmir *a_Smir ,
  702. ISmirDatabase *pSmir,
  703. ISmirModHandle *hModule,
  704. DWORD dwCookie
  705. )
  706. {
  707. m_cRef=0;
  708. //set the index to the first element
  709. m_Index=0;
  710. IWbemServices *moServ = NULL ; //pointer to the provider
  711. IWbemContext *moContext = NULL ;
  712. SCODE res= CSmirAccess :: GetContext (a_Smir , &moContext);
  713. res= CSmirAccess :: Open(a_Smir,&moServ);
  714. //I have now opened the smir namespace so look at the classes
  715. IEnumWbemClassObject *pEnum = 0;
  716. BSTR szTmpModuleName = NULL;
  717. hModule->GetName(&szTmpModuleName);
  718. /*query for
  719. *associators of {\\.\root\default\SMIR:Module="RFC1213_MIB"} where AssocClass=ModuleToClassAssociator
  720. */
  721. CString sQuery(CString(SMIR_ASSOC_QUERY_STR1)
  722. +CString(OPEN_BRACE_STR)
  723. +CString(SMIR_NAMESPACE_FROM_ROOT)
  724. +CString(COLON_STR)
  725. +CString(MODULE_NAMESPACE_NAME)
  726. +CString(EQUALS_STR)
  727. +CString(QUOTE_STR)
  728. +CString(szTmpModuleName)
  729. +CString(QUOTE_STR)
  730. +CString(CLOSE_BRACE_STR)
  731. +CString(SMIR_ASSOC_QUERY_STR3)
  732. +CString(EQUALS_STR)
  733. +CString(SMIR_MODULE_ASSOC_CLASS_NAME)
  734. );
  735. BSTR szQuery = sQuery.AllocSysString();
  736. CBString t_QueryFormat (SMIR_ASSOC_QUERY1_TYPE);
  737. SCODE sRes = moServ->ExecQuery (
  738. t_QueryFormat.GetString (),
  739. szQuery,
  740. RESERVED_WBEM_FLAG,
  741. moContext,
  742. &pEnum
  743. );
  744. SysFreeString(szQuery);
  745. if ( moContext )
  746. moContext->Release () ;
  747. moServ->Release();
  748. if (FAILED(sRes)||(NULL==pEnum))
  749. {
  750. //problem or we have no classes to enumerate
  751. SysFreeString(szTmpModuleName);
  752. return ;
  753. }
  754. VARIANT pVal;
  755. VariantInit(&pVal);
  756. ULONG uCount=1;
  757. IWbemClassObject *pSmirMosClassObject = NULL ;
  758. ULONG puReturned = 0;
  759. for(pEnum->Reset();S_OK==pEnum->Next(-1,uCount,&pSmirMosClassObject,&puReturned);)
  760. {
  761. BSTR szTmpGroupName = NULL; //the group name (set when we find it)
  762. //find the group that this class belongs to (could be more than one group)
  763. //...
  764. //ok we have a class in the correct module so add it to the enumeration
  765. ISmirClassHandle *pTClass = NULL ;
  766. res = g_pClassFactoryHelper->CreateInstance(CLSID_SMIR_ClassHandle,
  767. IID_ISMIR_ClassHandle, (PVOID *)&pTClass);
  768. if (FAILED(res))
  769. {
  770. //we have a problem
  771. SysFreeString(szTmpModuleName);
  772. pSmirMosClassObject->Release();
  773. return;
  774. }
  775. //save the module name
  776. pTClass->SetModuleName(szTmpModuleName);
  777. pTClass->SetWBEMClass(pSmirMosClassObject);
  778. //drop it in the enumeration array
  779. m_IHandleArray.Add(pTClass);
  780. pSmirMosClassObject->Release();
  781. }
  782. SysFreeString(szTmpModuleName);
  783. pEnum->Release();
  784. }
  785. /*
  786. * CEnumSmir::Next
  787. * CEnumSmir::Skip
  788. * CEnumSmir::Reset
  789. *
  790. * Enumerator methods.
  791. */
  792. #pragma warning (disable:4018)
  793. SCODE CEnumSmirMod::Next(IN ULONG celt,
  794. OUT ISmirModHandle **phModule,
  795. OUT ULONG * pceltFetched)
  796. {
  797. SetStructuredExceptionHandler seh;
  798. try
  799. {
  800. if (NULL!=pceltFetched)
  801. *pceltFetched=0;
  802. if(celt>0)
  803. {
  804. //check that the arguments make sense
  805. if ((celt > 1)&&(NULL == pceltFetched))
  806. return ResultFromScode(S_FALSE);
  807. //get the number of elements in the zero based array
  808. int iSize = m_IHandleArray.GetSize();
  809. //get all of the elements requested or until we hit the end of the array
  810. int iLoop;
  811. for(iLoop=0; (iLoop<celt)&&(m_Index<iSize);iLoop++,m_Index++)
  812. {
  813. //what is the next module in the SMIR namespace
  814. //allocate the handle and save it
  815. ISmirModHandle* hTmpModule = m_IHandleArray.GetAt(m_Index);
  816. //this could throw an exception but it would be the caller's fault
  817. if(NULL != hTmpModule)
  818. {
  819. phModule[iLoop] = hTmpModule;
  820. //don't forget that I have a handle to this
  821. phModule[iLoop]->AddRef();
  822. if (NULL != pceltFetched)
  823. (*pceltFetched)++;
  824. }
  825. }
  826. //return based on the number requested
  827. return (iLoop==(celt-1))? ResultFromScode(S_FALSE): ResultFromScode(S_OK);
  828. }
  829. //he asked for 0 and that is what he got
  830. return ResultFromScode(S_OK);
  831. }
  832. catch(Structured_Exception e_SE)
  833. {
  834. return E_UNEXPECTED;
  835. }
  836. catch(Heap_Exception e_HE)
  837. {
  838. return E_OUTOFMEMORY;
  839. }
  840. catch(...)
  841. {
  842. return E_UNEXPECTED;
  843. }
  844. }
  845. #pragma warning (disable:4018)
  846. SCODE CEnumSmirMod::Skip(IN ULONG celt)
  847. {
  848. SetStructuredExceptionHandler seh;
  849. try
  850. {
  851. if ((m_Index+celt)<m_IHandleArray.GetSize())
  852. {
  853. m_Index += celt;
  854. return ResultFromScode(S_OK);
  855. }
  856. else
  857. {
  858. return ResultFromScode(S_FALSE);
  859. }
  860. }
  861. catch(Structured_Exception e_SE)
  862. {
  863. return E_UNEXPECTED;
  864. }
  865. catch(Heap_Exception e_HE)
  866. {
  867. return E_OUTOFMEMORY;
  868. }
  869. catch(...)
  870. {
  871. return E_UNEXPECTED;
  872. }
  873. }
  874. #pragma warning (default:4018)
  875. SCODE CEnumSmirMod::Reset(void)
  876. {
  877. m_Index=0;
  878. return ResultFromScode(S_OK);
  879. }
  880. /*
  881. * CEnumSmir::AddRef
  882. * CEnumSmir::Release
  883. *
  884. * Reference counting members. When Release sees a zero count
  885. * the object destroys itself.
  886. */
  887. ULONG CEnumSmirMod::AddRef(void)
  888. {
  889. SetStructuredExceptionHandler seh;
  890. try
  891. {
  892. return InterlockedIncrement(&m_cRef);
  893. }
  894. catch(Structured_Exception e_SE)
  895. {
  896. return 0;
  897. }
  898. catch(Heap_Exception e_HE)
  899. {
  900. return 0;
  901. }
  902. catch(...)
  903. {
  904. return 0;
  905. }
  906. }
  907. ULONG CEnumSmirMod::Release(void)
  908. {
  909. SetStructuredExceptionHandler seh;
  910. try
  911. {
  912. long ret;
  913. if (0!=(ret=InterlockedDecrement(&m_cRef)))
  914. return ret;
  915. delete this;
  916. return 0;
  917. }
  918. catch(Structured_Exception e_SE)
  919. {
  920. return 0;
  921. }
  922. catch(Heap_Exception e_HE)
  923. {
  924. return 0;
  925. }
  926. catch(...)
  927. {
  928. return 0;
  929. }
  930. }
  931. /*
  932. * CEnumSmir::Next
  933. * CEnumSmir::Skip
  934. * CEnumSmir::Reset
  935. *
  936. * Enumerator methods.
  937. */
  938. #pragma warning (disable:4018)
  939. SCODE CEnumSmirGroup::Next(IN ULONG celt,
  940. OUT ISmirGroupHandle **phModule,
  941. OUT ULONG * pceltFetched)
  942. {
  943. SetStructuredExceptionHandler seh;
  944. try
  945. {
  946. if (NULL!=pceltFetched)
  947. *pceltFetched=0;
  948. if(celt>0)
  949. {
  950. //check that the arguments make sense
  951. if ((celt > 1)&&(NULL == pceltFetched))
  952. return ResultFromScode(S_FALSE);
  953. //get the number of elements in the zero based array
  954. int iSize = m_IHandleArray.GetSize();
  955. //get all of the elements requested or until we hit the end of the array
  956. int iLoop;
  957. for(iLoop=0; (iLoop<celt)&&(m_Index<iSize);iLoop++,m_Index++)
  958. {
  959. //what is the next module in the SMIR namespace
  960. //allocate the handle and save it
  961. ISmirGroupHandle* hTmpModule = m_IHandleArray.GetAt(m_Index);
  962. //this could throw an exception but it would be the caller's fault
  963. if(NULL != hTmpModule)
  964. {
  965. phModule[iLoop] = hTmpModule;
  966. //don't forget that I have a handle to this
  967. phModule[iLoop]->AddRef();
  968. if (NULL != pceltFetched)
  969. (*pceltFetched)++;
  970. }
  971. }
  972. //return based on the number requested
  973. return (iLoop==(celt-1))? ResultFromScode(S_FALSE): ResultFromScode(S_OK);
  974. }
  975. //he asked for 0 and that is what he got
  976. return ResultFromScode(S_OK);
  977. }
  978. catch(Structured_Exception e_SE)
  979. {
  980. return E_UNEXPECTED;
  981. }
  982. catch(Heap_Exception e_HE)
  983. {
  984. return E_OUTOFMEMORY;
  985. }
  986. catch(...)
  987. {
  988. return E_UNEXPECTED;
  989. }
  990. }
  991. #pragma warning (disable:4018)
  992. SCODE CEnumSmirGroup::Skip(IN ULONG celt)
  993. {
  994. SetStructuredExceptionHandler seh;
  995. try
  996. {
  997. if ((m_Index+celt)<m_IHandleArray.GetSize())
  998. {
  999. m_Index += celt;
  1000. return ResultFromScode(S_OK);
  1001. }
  1002. else
  1003. {
  1004. return ResultFromScode(S_FALSE);
  1005. }
  1006. }
  1007. catch(Structured_Exception e_SE)
  1008. {
  1009. return E_UNEXPECTED;
  1010. }
  1011. catch(Heap_Exception e_HE)
  1012. {
  1013. return E_OUTOFMEMORY;
  1014. }
  1015. catch(...)
  1016. {
  1017. return E_UNEXPECTED;
  1018. }
  1019. }
  1020. #pragma warning (default:4018)
  1021. SCODE CEnumSmirGroup::Reset(void)
  1022. {
  1023. m_Index=0;
  1024. return ResultFromScode(S_OK);
  1025. }
  1026. /*
  1027. * CEnumSmir::AddRef
  1028. * CEnumSmir::Release
  1029. *
  1030. * Reference counting members. When Release sees a zero count
  1031. * the object destroys itself.
  1032. */
  1033. ULONG CEnumSmirGroup::AddRef(void)
  1034. {
  1035. SetStructuredExceptionHandler seh;
  1036. try
  1037. {
  1038. return InterlockedIncrement(&m_cRef);
  1039. }
  1040. catch(Structured_Exception e_SE)
  1041. {
  1042. return 0;
  1043. }
  1044. catch(Heap_Exception e_HE)
  1045. {
  1046. return 0;
  1047. }
  1048. catch(...)
  1049. {
  1050. return 0;
  1051. }
  1052. }
  1053. ULONG CEnumSmirGroup::Release(void)
  1054. {
  1055. SetStructuredExceptionHandler seh;
  1056. try
  1057. {
  1058. long ret;
  1059. if (0!=(ret=InterlockedDecrement(&m_cRef)))
  1060. return ret;
  1061. delete this;
  1062. return 0;
  1063. }
  1064. catch(Structured_Exception e_SE)
  1065. {
  1066. return 0;
  1067. }
  1068. catch(Heap_Exception e_HE)
  1069. {
  1070. return 0;
  1071. }
  1072. catch(...)
  1073. {
  1074. return 0;
  1075. }
  1076. }
  1077. /*
  1078. * CEnumSmir::Next
  1079. * CEnumSmir::Skip
  1080. * CEnumSmir::Reset
  1081. *
  1082. * Enumerator methods.
  1083. */
  1084. #pragma warning (disable:4018)
  1085. SCODE CEnumSmirClass::Next(IN ULONG celt,
  1086. OUT ISmirClassHandle **phModule,
  1087. OUT ULONG * pceltFetched)
  1088. {
  1089. SetStructuredExceptionHandler seh;
  1090. try
  1091. {
  1092. if (NULL!=pceltFetched)
  1093. *pceltFetched=0;
  1094. if(celt>0)
  1095. {
  1096. //check that the arguments make sense
  1097. if ((celt > 1)&&(NULL == pceltFetched))
  1098. return ResultFromScode(S_FALSE);
  1099. //get the number of elements in the zero based array
  1100. int iSize = m_IHandleArray.GetSize();
  1101. //get all of the elements requested or until we hit the end of the array
  1102. int iLoop;
  1103. for(iLoop=0; (iLoop<celt)&&(m_Index<iSize);iLoop++,m_Index++)
  1104. {
  1105. //what is the next module in the SMIR namespace
  1106. //allocate the handle and save it
  1107. ISmirClassHandle* hTmpModule = m_IHandleArray.GetAt(m_Index);
  1108. //this could throw an exception but it would be the caller's fault
  1109. if(NULL != hTmpModule)
  1110. {
  1111. phModule[iLoop] = hTmpModule;
  1112. //don't forget that I have a handle to this
  1113. phModule[iLoop]->AddRef();
  1114. if (NULL != pceltFetched)
  1115. (*pceltFetched)++;
  1116. }
  1117. }
  1118. //return based on the number requested
  1119. return (iLoop==(celt-1))? ResultFromScode(S_FALSE): ResultFromScode(S_OK);
  1120. }
  1121. //he asked for 0 and that is what he got
  1122. return ResultFromScode(S_OK);
  1123. }
  1124. catch(Structured_Exception e_SE)
  1125. {
  1126. return E_UNEXPECTED;
  1127. }
  1128. catch(Heap_Exception e_HE)
  1129. {
  1130. return E_OUTOFMEMORY;
  1131. }
  1132. catch(...)
  1133. {
  1134. return E_UNEXPECTED;
  1135. }
  1136. }
  1137. #pragma warning (disable:4018)
  1138. SCODE CEnumSmirClass::Skip(IN ULONG celt)
  1139. {
  1140. SetStructuredExceptionHandler seh;
  1141. try
  1142. {
  1143. if ((m_Index+celt)<m_IHandleArray.GetSize())
  1144. {
  1145. m_Index += celt;
  1146. return ResultFromScode(S_OK);
  1147. }
  1148. else
  1149. {
  1150. return ResultFromScode(S_FALSE);
  1151. }
  1152. }
  1153. catch(Structured_Exception e_SE)
  1154. {
  1155. return E_UNEXPECTED;
  1156. }
  1157. catch(Heap_Exception e_HE)
  1158. {
  1159. return E_OUTOFMEMORY;
  1160. }
  1161. catch(...)
  1162. {
  1163. return E_UNEXPECTED;
  1164. }
  1165. }
  1166. #pragma warning (default:4018)
  1167. SCODE CEnumSmirClass::Reset(void)
  1168. {
  1169. m_Index=0;
  1170. return ResultFromScode(S_OK);
  1171. }
  1172. /*
  1173. * CEnumSmir::AddRef
  1174. * CEnumSmir::Release
  1175. *
  1176. * Reference counting members. When Release sees a zero count
  1177. * the object destroys itself.
  1178. */
  1179. ULONG CEnumSmirClass::AddRef(void)
  1180. {
  1181. SetStructuredExceptionHandler seh;
  1182. try
  1183. {
  1184. return InterlockedIncrement(&m_cRef);
  1185. }
  1186. catch(Structured_Exception e_SE)
  1187. {
  1188. return 0;
  1189. }
  1190. catch(Heap_Exception e_HE)
  1191. {
  1192. return 0;
  1193. }
  1194. catch(...)
  1195. {
  1196. return 0;
  1197. }
  1198. }
  1199. ULONG CEnumSmirClass::Release(void)
  1200. {
  1201. SetStructuredExceptionHandler seh;
  1202. try
  1203. {
  1204. long ret;
  1205. if (0!=(ret=InterlockedDecrement(&m_cRef)))
  1206. return ret;
  1207. delete this;
  1208. return 0;
  1209. }
  1210. catch(Structured_Exception e_SE)
  1211. {
  1212. return 0;
  1213. }
  1214. catch(Heap_Exception e_HE)
  1215. {
  1216. return 0;
  1217. }
  1218. catch(...)
  1219. {
  1220. return 0;
  1221. }
  1222. }
  1223. //Notification Enum Classes
  1224. /*
  1225. * CEnumNotificationClass::QueryInterface
  1226. *
  1227. * Purpose:
  1228. * Manages the interfaces for this object which supports the
  1229. * IUnknowninterface.
  1230. *
  1231. * Parameters:
  1232. * riid REFIID of the interface to return.
  1233. * ppv PPVOID in which to store the pointer.
  1234. *
  1235. * Return Value:
  1236. * SCODE NOERROR on success, E_NOINTERFACE if the
  1237. * interface is not supported.
  1238. */
  1239. STDMETHODIMP CEnumNotificationClass :: QueryInterface(IN REFIID riid,
  1240. OUT PPVOID ppv)
  1241. {
  1242. SetStructuredExceptionHandler seh;
  1243. try
  1244. {
  1245. //Always NULL the out-parameters
  1246. *ppv=NULL;
  1247. if (IID_IUnknown==riid)
  1248. *ppv=this;
  1249. if (IID_ISMIR_EnumNotificationClass==riid)
  1250. *ppv=this;
  1251. if (NULL==*ppv)
  1252. return ResultFromScode(E_NOINTERFACE);
  1253. //AddRef any interface we'll return.
  1254. ((LPUNKNOWN)*ppv)->AddRef();
  1255. return NOERROR;
  1256. }
  1257. catch(Structured_Exception e_SE)
  1258. {
  1259. return E_UNEXPECTED;
  1260. }
  1261. catch(Heap_Exception e_HE)
  1262. {
  1263. return E_OUTOFMEMORY;
  1264. }
  1265. catch(...)
  1266. {
  1267. return E_UNEXPECTED;
  1268. }
  1269. }
  1270. SCODE CEnumNotificationClass::Clone(IEnumNotificationClass **ppenum)
  1271. {
  1272. SetStructuredExceptionHandler seh;
  1273. try
  1274. {
  1275. if(NULL == ppenum)
  1276. return E_INVALIDARG;
  1277. int ClassIndex = m_Index;
  1278. PENUMNOTIFICATIONCLASS pTmpEnumNotificationClass = new CEnumNotificationClass(this);
  1279. m_Index = ClassIndex;
  1280. //we have an enumerator so get the interface to pass back
  1281. if(NULL == pTmpEnumNotificationClass)
  1282. {
  1283. return ResultFromScode(E_OUTOFMEMORY);
  1284. }
  1285. if(NOERROR == pTmpEnumNotificationClass->QueryInterface(IID_ISMIR_EnumNotificationClass,(void**)ppenum))
  1286. return S_OK;
  1287. return E_UNEXPECTED;
  1288. }
  1289. catch(Structured_Exception e_SE)
  1290. {
  1291. return E_UNEXPECTED;
  1292. }
  1293. catch(Heap_Exception e_HE)
  1294. {
  1295. return E_OUTOFMEMORY;
  1296. }
  1297. catch(...)
  1298. {
  1299. return E_UNEXPECTED;
  1300. }
  1301. }
  1302. CEnumNotificationClass :: CEnumNotificationClass(IEnumNotificationClass *pSmirClass)
  1303. {
  1304. //zero the reference count
  1305. m_cRef=0;
  1306. //set the index to the first element
  1307. m_Index=0;
  1308. ULONG uCount=1;
  1309. ISmirNotificationClassHandle *pClass = NULL ;
  1310. ULONG puReturned;
  1311. //OK loop through the enumerator
  1312. for(pSmirClass->Reset();S_OK==pSmirClass->Next(uCount,&pClass,&puReturned);)
  1313. {
  1314. ISmirNotificationClassHandle *pTClass = NULL ;
  1315. SCODE result = pClass->QueryInterface(IID_ISMIR_NotificationClassHandle,(void**)&pTClass );
  1316. pClass->Release();
  1317. if(S_OK != result)
  1318. {
  1319. //this is not going to happen! I know which interface it is.
  1320. return ;
  1321. }
  1322. /*things are looking good; we have the handle to the instance so
  1323. *add it to out array
  1324. */
  1325. m_IHandleArray.Add(pTClass);
  1326. }
  1327. }
  1328. /*enumerate all of the classes in the smir
  1329. */
  1330. CEnumNotificationClass :: CEnumNotificationClass (
  1331. CSmir *a_Smir ,
  1332. ISmirDatabase *pSmir,
  1333. DWORD dwCookie
  1334. )
  1335. {
  1336. //zero the reference count
  1337. m_cRef=0;
  1338. //set the index to the first element
  1339. m_Index=0;
  1340. //open the smir
  1341. IWbemServices *moServ = NULL ; //pointer to the provider
  1342. IWbemContext *moContext = NULL ;
  1343. SCODE res= CSmirAccess :: GetContext (a_Smir , &moContext);
  1344. res= CSmirAccess :: Open(a_Smir,&moServ);
  1345. if ((S_FALSE==res)||(moServ == NULL))
  1346. {
  1347. if ( moContext )
  1348. moContext->Release () ;
  1349. //we have a problem
  1350. return;
  1351. }
  1352. //I have now opened the smir namespace so look at the classes
  1353. IEnumWbemClassObject *pEnum = NULL;
  1354. CBString t_Bstr(HMOM_SNMPNOTIFICATIONTYPE_STRING);
  1355. SCODE sRes = moServ->CreateClassEnum (
  1356. t_Bstr.GetString(),
  1357. WBEM_FLAG_SHALLOW,
  1358. moContext,
  1359. &pEnum
  1360. );
  1361. if ( moContext )
  1362. moContext->Release () ;
  1363. moServ->Release();
  1364. if (FAILED(sRes)||(NULL==pEnum))
  1365. {
  1366. //problem or we have no classes to enumerate
  1367. return ;
  1368. }
  1369. //we have some classes so add them to the enumerator
  1370. ULONG uCount=1;
  1371. IWbemClassObject *pSmirMosClassObject = NULL ;
  1372. ULONG puReturned;
  1373. //loop over the classes
  1374. for(pEnum->Reset();S_OK==pEnum->Next(-1,uCount,&pSmirMosClassObject,&puReturned);)
  1375. {
  1376. ISmirNotificationClassHandle *pTClass;
  1377. //got one so wrap it to go
  1378. res = g_pClassFactoryHelper->CreateInstance(CLSID_SMIR_NotificationClassHandle,
  1379. IID_ISMIR_NotificationClassHandle, (PVOID *)&pTClass);
  1380. if (FAILED(res))
  1381. {
  1382. //we have a problem
  1383. pSmirMosClassObject->Release();
  1384. return;
  1385. }
  1386. pTClass->SetWBEMNotificationClass(pSmirMosClassObject);
  1387. //drop it in the enumeration array
  1388. m_IHandleArray.Add(pTClass);
  1389. //if this is an async enumeration signal the connectable object
  1390. pSmirMosClassObject->Release();
  1391. }
  1392. pEnum->Release();
  1393. }
  1394. CEnumNotificationClass :: CEnumNotificationClass (
  1395. IN CSmir *a_Smir ,
  1396. ISmirDatabase *pSmir,
  1397. ISmirModHandle *hModule,
  1398. DWORD dwCookie
  1399. )
  1400. {
  1401. m_cRef=0;
  1402. //set the index to the first element
  1403. m_Index=0;
  1404. IWbemServices *moServ = NULL ; //pointer to the provider
  1405. IWbemContext *moContext = NULL ;
  1406. SCODE res= CSmirAccess :: GetContext (a_Smir , &moContext);
  1407. res= CSmirAccess :: Open(a_Smir,&moServ);
  1408. //I have now opened the smir namespace so look at the classes
  1409. if ( ! SUCCEEDED ( res ) )
  1410. {
  1411. if ( moContext )
  1412. moContext->Release () ;
  1413. return ;
  1414. }
  1415. IEnumWbemClassObject *pEnum = NULL ;
  1416. BSTR szTmpModuleName = NULL ;
  1417. hModule->GetName(&szTmpModuleName);
  1418. /*query for
  1419. *associators of {\\.\root\default\SMIR:Module="RFC1213_MIB"} where AssocClass=ModToNotificationClassAssoc
  1420. */
  1421. CString sQuery(CString(SMIR_ASSOC_QUERY_STR1)
  1422. +CString(OPEN_BRACE_STR)
  1423. +CString(SMIR_NAMESPACE_FROM_ROOT)
  1424. +CString(COLON_STR)
  1425. +CString(MODULE_NAMESPACE_NAME)
  1426. +CString(EQUALS_STR)
  1427. +CString(QUOTE_STR)
  1428. +CString(szTmpModuleName)
  1429. +CString(QUOTE_STR)
  1430. +CString(CLOSE_BRACE_STR)
  1431. +CString(SMIR_ASSOC_QUERY_STR3)
  1432. +CString(EQUALS_STR)
  1433. +CString(SMIR_MODULE_ASSOC_NCLASS_NAME)
  1434. );
  1435. BSTR szQuery = sQuery.AllocSysString();
  1436. CBString t_QueryFormat (SMIR_ASSOC_QUERY1_TYPE);
  1437. SCODE sRes = moServ->ExecQuery (
  1438. t_QueryFormat.GetString (),
  1439. szQuery,
  1440. RESERVED_WBEM_FLAG,
  1441. moContext,
  1442. &pEnum
  1443. );
  1444. SysFreeString(szQuery);
  1445. if ( moContext )
  1446. moContext->Release () ;
  1447. moServ->Release();
  1448. if (FAILED(sRes)||(NULL==pEnum))
  1449. {
  1450. //problem or we have no classes to enumerate
  1451. return ;
  1452. }
  1453. VARIANT pVal;
  1454. VariantInit(&pVal);
  1455. ULONG uCount=1;
  1456. IWbemClassObject *pSmirMosClassObject = NULL ;
  1457. ULONG puReturned = 0;
  1458. HRESULT enumResult = S_OK;
  1459. for(pEnum->Reset();S_OK==(enumResult = pEnum->Next(-1,uCount,&pSmirMosClassObject,&puReturned));)
  1460. {
  1461. BSTR szTmpGroupName = NULL; //the group name (set when we find it)
  1462. //find the group that this class belongs to (could be more than one group)
  1463. //...
  1464. //ok we have a class in the correct module so add it to the enumeration
  1465. ISmirNotificationClassHandle *pTClass = NULL ;
  1466. res = g_pClassFactoryHelper->CreateInstance(CLSID_SMIR_NotificationClassHandle,
  1467. IID_ISMIR_NotificationClassHandle, (PVOID *)&pTClass);
  1468. if (FAILED(res))
  1469. {
  1470. //we have a problem
  1471. SysFreeString(szTmpModuleName);
  1472. pSmirMosClassObject->Release();
  1473. return;
  1474. }
  1475. //save the module name
  1476. pTClass->SetModule(szTmpModuleName);
  1477. pTClass->SetWBEMNotificationClass(pSmirMosClassObject);
  1478. //drop it in the enumeration array
  1479. m_IHandleArray.Add(pTClass);
  1480. pSmirMosClassObject->Release();
  1481. }
  1482. SysFreeString(szTmpModuleName);
  1483. pEnum->Release();
  1484. }
  1485. /*
  1486. * CEnumNotificationClass::Next
  1487. * CEnumNotificationClass::Skip
  1488. * CEnumNotificationClass::Reset
  1489. *
  1490. */
  1491. #pragma warning (disable:4018)
  1492. SCODE CEnumNotificationClass::Next(IN ULONG celt,
  1493. OUT ISmirNotificationClassHandle **phClass,
  1494. OUT ULONG * pceltFetched)
  1495. {
  1496. SetStructuredExceptionHandler seh;
  1497. try
  1498. {
  1499. if (NULL!=pceltFetched)
  1500. *pceltFetched=0;
  1501. if(celt>0)
  1502. {
  1503. //check that the arguments make sense
  1504. if ((celt > 1)&&(NULL == pceltFetched))
  1505. return ResultFromScode(S_FALSE);
  1506. //get the number of elements in the zero based array
  1507. int iSize = m_IHandleArray.GetSize();
  1508. //get all of the elements requested or until we hit the end of the array
  1509. int iLoop;
  1510. for(iLoop=0; (iLoop<celt)&&(m_Index<iSize);iLoop++,m_Index++)
  1511. {
  1512. //what is the next class
  1513. //allocate the handle and save it
  1514. ISmirNotificationClassHandle* hTmpModule = m_IHandleArray.GetAt(m_Index);
  1515. //this could throw an exception but it would be the caller's fault
  1516. if(NULL != hTmpModule)
  1517. {
  1518. phClass[iLoop] = hTmpModule;
  1519. //don't forget that I have a handle to this
  1520. phClass[iLoop]->AddRef();
  1521. if (NULL != pceltFetched)
  1522. (*pceltFetched)++;
  1523. }
  1524. }
  1525. //return based on the number requested
  1526. return (iLoop==(celt-1))? ResultFromScode(S_FALSE): ResultFromScode(S_OK);
  1527. }
  1528. //he asked for 0 and that is what he got
  1529. return ResultFromScode(S_OK);
  1530. }
  1531. catch(Structured_Exception e_SE)
  1532. {
  1533. return E_UNEXPECTED;
  1534. }
  1535. catch(Heap_Exception e_HE)
  1536. {
  1537. return E_OUTOFMEMORY;
  1538. }
  1539. catch(...)
  1540. {
  1541. return E_UNEXPECTED;
  1542. }
  1543. }
  1544. #pragma warning (disable:4018)
  1545. SCODE CEnumNotificationClass::Skip(IN ULONG celt)
  1546. {
  1547. SetStructuredExceptionHandler seh;
  1548. try
  1549. {
  1550. if ((m_Index+celt)<m_IHandleArray.GetSize())
  1551. {
  1552. m_Index += celt;
  1553. return ResultFromScode(S_OK);
  1554. }
  1555. else
  1556. {
  1557. return ResultFromScode(S_FALSE);
  1558. }
  1559. }
  1560. catch(Structured_Exception e_SE)
  1561. {
  1562. return E_UNEXPECTED;
  1563. }
  1564. catch(Heap_Exception e_HE)
  1565. {
  1566. return E_OUTOFMEMORY;
  1567. }
  1568. catch(...)
  1569. {
  1570. return E_UNEXPECTED;
  1571. }
  1572. }
  1573. #pragma warning (default:4018)
  1574. SCODE CEnumNotificationClass::Reset(void)
  1575. {
  1576. m_Index=0;
  1577. return ResultFromScode(S_OK);
  1578. }
  1579. /*
  1580. * CEnumNotificationClass::AddRef
  1581. * CEnumNotificationClass::Release
  1582. *
  1583. * Reference counting members. When Release sees a zero count
  1584. * the object destroys itself.
  1585. */
  1586. ULONG CEnumNotificationClass::AddRef(void)
  1587. {
  1588. SetStructuredExceptionHandler seh;
  1589. try
  1590. {
  1591. return InterlockedIncrement(&m_cRef);
  1592. }
  1593. catch(Structured_Exception e_SE)
  1594. {
  1595. return 0;
  1596. }
  1597. catch(Heap_Exception e_HE)
  1598. {
  1599. return 0;
  1600. }
  1601. catch(...)
  1602. {
  1603. return 0;
  1604. }
  1605. }
  1606. ULONG CEnumNotificationClass::Release(void)
  1607. {
  1608. SetStructuredExceptionHandler seh;
  1609. try
  1610. {
  1611. long ret;
  1612. if (0!=(ret=InterlockedDecrement(&m_cRef)))
  1613. return ret;
  1614. delete this;
  1615. return 0;
  1616. }
  1617. catch(Structured_Exception e_SE)
  1618. {
  1619. return 0;
  1620. }
  1621. catch(Heap_Exception e_HE)
  1622. {
  1623. return 0;
  1624. }
  1625. catch(...)
  1626. {
  1627. return 0;
  1628. }
  1629. }
  1630. //ExtNotification Enum Classes
  1631. /*
  1632. * CEnumExtNotificationClass::QueryInterface
  1633. *
  1634. * Purpose:
  1635. * Manages the interfaces for this object which supports the
  1636. * IUnknowninterface.
  1637. *
  1638. * Parameters:
  1639. * riid REFIID of the interface to return.
  1640. * ppv PPVOID in which to store the pointer.
  1641. *
  1642. * Return Value:
  1643. * SCODE NOERROR on success, E_NOINTERFACE if the
  1644. * interface is not supported.
  1645. */
  1646. STDMETHODIMP CEnumExtNotificationClass :: QueryInterface(IN REFIID riid,
  1647. OUT PPVOID ppv)
  1648. {
  1649. SetStructuredExceptionHandler seh;
  1650. try
  1651. {
  1652. //Always NULL the out-parameters
  1653. *ppv=NULL;
  1654. if (IID_IUnknown==riid)
  1655. *ppv=this;
  1656. if (IID_ISMIR_EnumExtNotificationClass==riid)
  1657. *ppv=this;
  1658. if (NULL==*ppv)
  1659. return ResultFromScode(E_NOINTERFACE);
  1660. //AddRef any interface we'll return.
  1661. ((LPUNKNOWN)*ppv)->AddRef();
  1662. return NOERROR;
  1663. }
  1664. catch(Structured_Exception e_SE)
  1665. {
  1666. return E_UNEXPECTED;
  1667. }
  1668. catch(Heap_Exception e_HE)
  1669. {
  1670. return E_OUTOFMEMORY;
  1671. }
  1672. catch(...)
  1673. {
  1674. return E_UNEXPECTED;
  1675. }
  1676. }
  1677. SCODE CEnumExtNotificationClass::Clone(IEnumExtNotificationClass **ppenum)
  1678. {
  1679. SetStructuredExceptionHandler seh;
  1680. try
  1681. {
  1682. if(NULL == ppenum)
  1683. return E_INVALIDARG;
  1684. int ClassIndex = m_Index;
  1685. PENUMEXTNOTIFICATIONCLASS pTmpEnumNotificationClass = new CEnumExtNotificationClass(this);
  1686. m_Index = ClassIndex;
  1687. //we have an enumerator so get the interface to pass back
  1688. if(NULL == pTmpEnumNotificationClass)
  1689. {
  1690. return ResultFromScode(E_OUTOFMEMORY);
  1691. }
  1692. if(NOERROR == pTmpEnumNotificationClass->QueryInterface(IID_ISMIR_EnumExtNotificationClass,(void**)ppenum))
  1693. return S_OK;
  1694. return E_UNEXPECTED;
  1695. }
  1696. catch(Structured_Exception e_SE)
  1697. {
  1698. return 0;
  1699. }
  1700. catch(Heap_Exception e_HE)
  1701. {
  1702. return 0;
  1703. }
  1704. catch(...)
  1705. {
  1706. return 0;
  1707. }
  1708. }
  1709. CEnumExtNotificationClass :: CEnumExtNotificationClass(IEnumExtNotificationClass *pSmirClass)
  1710. {
  1711. //zero the reference count
  1712. m_cRef=0;
  1713. //set the index to the first element
  1714. m_Index=0;
  1715. ULONG uCount=1;
  1716. ISmirExtNotificationClassHandle *pClass = NULL ;
  1717. ULONG puReturned;
  1718. //OK loop through the enumerator
  1719. for(pSmirClass->Reset();S_OK==pSmirClass->Next(uCount,&pClass,&puReturned);)
  1720. {
  1721. ISmirExtNotificationClassHandle *pTClass = NULL ;
  1722. SCODE result = pClass->QueryInterface(IID_ISMIR_ExtNotificationClassHandle,(void**)&pTClass );
  1723. pClass->Release();
  1724. if(S_OK != result)
  1725. {
  1726. //this is not going to happen! I know which interface it is.
  1727. return ;
  1728. }
  1729. /*things are looking good; we have the handle to the instance so
  1730. *add it to out array
  1731. */
  1732. m_IHandleArray.Add(pTClass);
  1733. }
  1734. }
  1735. /*enumerate all of the classes in the smir
  1736. */
  1737. CEnumExtNotificationClass :: CEnumExtNotificationClass(
  1738. CSmir *a_Smir ,
  1739. ISmirDatabase *pSmir,
  1740. DWORD dwCookie
  1741. )
  1742. {
  1743. //zero the reference count
  1744. m_cRef=0;
  1745. //set the index to the first element
  1746. m_Index=0;
  1747. //open the smir
  1748. IWbemServices *moServ = NULL ; //pointer to the provider
  1749. IWbemContext *moContext = NULL ;
  1750. SCODE res= CSmirAccess :: GetContext (a_Smir , &moContext);
  1751. res= CSmirAccess :: Open(a_Smir,&moServ);
  1752. if ((S_FALSE==res)||(moServ == NULL))
  1753. {
  1754. //we have a problem
  1755. if ( moContext )
  1756. moContext->Release () ;
  1757. return;
  1758. }
  1759. //I have now opened the smir namespace so look at the classes
  1760. IEnumWbemClassObject *pEnum = NULL ;
  1761. CBString t_Bstr(HMOM_SNMPEXTNOTIFICATIONTYPE_STRING);
  1762. SCODE sRes = moServ->CreateClassEnum (
  1763. t_Bstr.GetString(),
  1764. WBEM_FLAG_SHALLOW,
  1765. moContext,
  1766. &pEnum
  1767. );
  1768. if ( moContext )
  1769. moContext->Release () ;
  1770. moServ->Release();
  1771. if (FAILED(sRes)||(NULL==pEnum))
  1772. {
  1773. //problem or we have no classes to enumerate
  1774. return ;
  1775. }
  1776. //we have some classes so add them to the enumerator
  1777. ULONG uCount=1;
  1778. IWbemClassObject *pSmirMosClassObject = NULL ;
  1779. ULONG puReturned;
  1780. //loop over the classes
  1781. for(pEnum->Reset();S_OK==pEnum->Next(-1,uCount,&pSmirMosClassObject,&puReturned);)
  1782. {
  1783. ISmirExtNotificationClassHandle *pTClass = NULL ;
  1784. //got one so wrap it to go
  1785. res = g_pClassFactoryHelper->CreateInstance(CLSID_SMIR_ExtNotificationClassHandle,
  1786. IID_ISMIR_ExtNotificationClassHandle, (PVOID *)&pTClass);
  1787. if (FAILED(res))
  1788. {
  1789. //we have a problem
  1790. pSmirMosClassObject->Release();
  1791. return;
  1792. }
  1793. pTClass->SetWBEMExtNotificationClass(pSmirMosClassObject);
  1794. //drop it in the enumeration array
  1795. m_IHandleArray.Add(pTClass);
  1796. pSmirMosClassObject->Release();
  1797. }
  1798. pEnum->Release();
  1799. }
  1800. CEnumExtNotificationClass :: CEnumExtNotificationClass (
  1801. CSmir *a_Smir ,
  1802. ISmirDatabase *pSmir,
  1803. ISmirModHandle *hModule,
  1804. DWORD dwCookie
  1805. )
  1806. {
  1807. m_cRef=0;
  1808. //set the index to the first element
  1809. m_Index=0;
  1810. IWbemServices *moServ = NULL ; //pointer to the provider
  1811. IWbemContext *moContext = NULL ;
  1812. SCODE res= CSmirAccess :: GetContext (a_Smir , &moContext);
  1813. res= CSmirAccess :: Open(a_Smir,&moServ);
  1814. if ( ! SUCCEEDED ( res ) )
  1815. {
  1816. if ( moContext )
  1817. moContext->Release () ;
  1818. return ;
  1819. }
  1820. //I have now opened the smir namespace so look at the classes
  1821. IEnumWbemClassObject *pEnum = NULL ;
  1822. BSTR szTmpModuleName = NULL;
  1823. hModule->GetName(&szTmpModuleName);
  1824. /*query for
  1825. *associators of {\\.\root\default\SMIR:Module="RFC1213_MIB"} where AssocClass=ModToExtNotificationClassAssoc
  1826. */
  1827. CString sQuery(CString(SMIR_ASSOC_QUERY_STR1)
  1828. +CString(OPEN_BRACE_STR)
  1829. +CString(SMIR_NAMESPACE_FROM_ROOT)
  1830. +CString(COLON_STR)
  1831. +CString(MODULE_NAMESPACE_NAME)
  1832. +CString(EQUALS_STR)
  1833. +CString(QUOTE_STR)
  1834. +CString(szTmpModuleName)
  1835. +CString(QUOTE_STR)
  1836. +CString(CLOSE_BRACE_STR)
  1837. +CString(SMIR_ASSOC_QUERY_STR3)
  1838. +CString(EQUALS_STR)
  1839. +CString(SMIR_MODULE_ASSOC_EXTNCLASS_NAME)
  1840. );
  1841. BSTR szQuery = sQuery.AllocSysString();
  1842. CBString t_QueryFormat (SMIR_ASSOC_QUERY1_TYPE);
  1843. SCODE sRes = moServ->ExecQuery (
  1844. t_QueryFormat.GetString (),
  1845. szQuery,
  1846. RESERVED_WBEM_FLAG,
  1847. moContext,
  1848. &pEnum
  1849. );
  1850. SysFreeString(szQuery);
  1851. if ( moContext )
  1852. moContext->Release () ;
  1853. moServ->Release();
  1854. if (FAILED(sRes)||(NULL==pEnum))
  1855. {
  1856. //problem or we have no classes to enumerate
  1857. return ;
  1858. }
  1859. VARIANT pVal;
  1860. VariantInit(&pVal);
  1861. ULONG uCount=1;
  1862. IWbemClassObject *pSmirMosClassObject = NULL ;
  1863. ULONG puReturned = 0;
  1864. for(pEnum->Reset();S_OK==pEnum->Next(-1,uCount,&pSmirMosClassObject,&puReturned);)
  1865. {
  1866. BSTR szTmpGroupName = NULL; //the group name (set when we find it)
  1867. //find the group that this class belongs to (could be more than one group)
  1868. //...
  1869. //ok we have a class in the correct module so add it to the enumeration
  1870. ISmirExtNotificationClassHandle *pTClass = NULL ;
  1871. res = g_pClassFactoryHelper->CreateInstance(CLSID_SMIR_ExtNotificationClassHandle,
  1872. IID_ISMIR_ExtNotificationClassHandle, (PVOID *)&pTClass);
  1873. if (FAILED(res))
  1874. {
  1875. //we have a problem
  1876. SysFreeString(szTmpModuleName);
  1877. pSmirMosClassObject->Release();
  1878. return;
  1879. }
  1880. //save the module name
  1881. pTClass->SetModule(szTmpModuleName);
  1882. pTClass->SetWBEMExtNotificationClass(pSmirMosClassObject);
  1883. //drop it in the enumeration array
  1884. m_IHandleArray.Add(pTClass);
  1885. pSmirMosClassObject->Release();
  1886. }
  1887. SysFreeString(szTmpModuleName);
  1888. pEnum->Release();
  1889. }
  1890. /*
  1891. * CEnumNotificationClass::Next
  1892. * CEnumNotificationClass::Skip
  1893. * CEnumNotificationClass::Reset
  1894. *
  1895. */
  1896. #pragma warning (disable:4018)
  1897. SCODE CEnumExtNotificationClass::Next(IN ULONG celt,
  1898. OUT ISmirExtNotificationClassHandle **phClass,
  1899. OUT ULONG * pceltFetched)
  1900. {
  1901. SetStructuredExceptionHandler seh;
  1902. try
  1903. {
  1904. if (NULL!=pceltFetched)
  1905. *pceltFetched=0;
  1906. if(celt>0)
  1907. {
  1908. //check that the arguments make sense
  1909. if ((celt > 1)&&(NULL == pceltFetched))
  1910. return ResultFromScode(S_FALSE);
  1911. //get the number of elements in the zero based array
  1912. int iSize = m_IHandleArray.GetSize();
  1913. //get all of the elements requested or until we hit the end of the array
  1914. int iLoop;
  1915. for(iLoop=0; (iLoop<celt)&&(m_Index<iSize);iLoop++,m_Index++)
  1916. {
  1917. //what is the next class
  1918. //allocate the handle and save it
  1919. ISmirExtNotificationClassHandle* hTmpModule = m_IHandleArray.GetAt(m_Index);
  1920. //this could throw an exception but it would be the caller's fault
  1921. if(NULL != hTmpModule)
  1922. {
  1923. phClass[iLoop] = hTmpModule;
  1924. //don't forget that I have a handle to this
  1925. phClass[iLoop]->AddRef();
  1926. if (NULL != pceltFetched)
  1927. (*pceltFetched)++;
  1928. }
  1929. }
  1930. //return based on the number requested
  1931. return (iLoop==(celt-1))? ResultFromScode(S_FALSE): ResultFromScode(S_OK);
  1932. }
  1933. //he asked for 0 and that is what he got
  1934. return ResultFromScode(S_OK);
  1935. }
  1936. catch(Structured_Exception e_SE)
  1937. {
  1938. return E_UNEXPECTED;
  1939. }
  1940. catch(Heap_Exception e_HE)
  1941. {
  1942. return E_OUTOFMEMORY;
  1943. }
  1944. catch(...)
  1945. {
  1946. return E_UNEXPECTED;
  1947. }
  1948. }
  1949. #pragma warning (disable:4018)
  1950. SCODE CEnumExtNotificationClass::Skip(IN ULONG celt)
  1951. {
  1952. SetStructuredExceptionHandler seh;
  1953. try
  1954. {
  1955. if ((m_Index+celt)<m_IHandleArray.GetSize())
  1956. {
  1957. m_Index += celt;
  1958. return ResultFromScode(S_OK);
  1959. }
  1960. else
  1961. {
  1962. return ResultFromScode(S_FALSE);
  1963. }
  1964. }
  1965. catch(Structured_Exception e_SE)
  1966. {
  1967. return E_UNEXPECTED;
  1968. }
  1969. catch(Heap_Exception e_HE)
  1970. {
  1971. return E_OUTOFMEMORY;
  1972. }
  1973. catch(...)
  1974. {
  1975. return E_UNEXPECTED;
  1976. }
  1977. }
  1978. #pragma warning (default:4018)
  1979. SCODE CEnumExtNotificationClass::Reset(void)
  1980. {
  1981. m_Index=0;
  1982. return ResultFromScode(S_OK);
  1983. }
  1984. /*
  1985. * CEnumNotificationClass::AddRef
  1986. * CEnumNotificationClass::Release
  1987. *
  1988. * Reference counting members. When Release sees a zero count
  1989. * the object destroys itself.
  1990. */
  1991. ULONG CEnumExtNotificationClass::AddRef(void)
  1992. {
  1993. SetStructuredExceptionHandler seh;
  1994. try
  1995. {
  1996. return InterlockedIncrement(&m_cRef);
  1997. }
  1998. catch(Structured_Exception e_SE)
  1999. {
  2000. return 0;
  2001. }
  2002. catch(Heap_Exception e_HE)
  2003. {
  2004. return 0;
  2005. }
  2006. catch(...)
  2007. {
  2008. return 0;
  2009. }
  2010. }
  2011. ULONG CEnumExtNotificationClass::Release(void)
  2012. {
  2013. SetStructuredExceptionHandler seh;
  2014. try
  2015. {
  2016. long ret;
  2017. if (0!=(ret=InterlockedDecrement(&m_cRef)))
  2018. return ret;
  2019. delete this;
  2020. return 0;
  2021. }
  2022. catch(Structured_Exception e_SE)
  2023. {
  2024. return 0;
  2025. }
  2026. catch(Heap_Exception e_HE)
  2027. {
  2028. return 0;
  2029. }
  2030. catch(...)
  2031. {
  2032. return 0;
  2033. }
  2034. }