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.

838 lines
20 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 "handles.h"
  15. #include "classfac.h"
  16. #include "evtcons.h"
  17. #ifdef ICECAP_PROFILE
  18. #include <icapexp.h>
  19. #endif
  20. //initialise the statics
  21. LONG CModHandleClassFactory::locksInProgress = 0;
  22. LONG CGroupHandleClassFactory::locksInProgress = 0;
  23. LONG CClassHandleClassFactory::locksInProgress = 0;
  24. LONG CNotificationClassHandleClassFactory::locksInProgress = 0;
  25. LONG CExtNotificationClassHandleClassFactory::locksInProgress = 0;
  26. LONG CSMIRClassFactory::locksInProgress = 0;
  27. LONG CSMIRClassFactory::objectsInProgress = 0;
  28. LONG CModHandleClassFactory::objectsInProgress = 0;
  29. LONG CGroupHandleClassFactory::objectsInProgress = 0;
  30. LONG CClassHandleClassFactory::objectsInProgress = 0;
  31. LONG CNotificationClassHandleClassFactory::objectsInProgress = 0;
  32. LONG CExtNotificationClassHandleClassFactory::objectsInProgress = 0;
  33. CSMIRClassFactory :: CSMIRClassFactory (CLSID m_clsid)
  34. :CSMIRGenericClassFactory(m_clsid)
  35. {
  36. bConstructed=300;
  37. }
  38. //***************************************************************************
  39. //
  40. // CSMIRClassFactory::QueryInterface
  41. //
  42. // Purpose: Standard Ole routines needed for all interfaces
  43. //
  44. //***************************************************************************
  45. STDMETHODIMP CSMIRClassFactory::QueryInterface (REFIID iid , PVOID FAR *iplpv)
  46. {
  47. *iplpv=NULL;
  48. if ((iid==IID_IUnknown)||(iid==IID_IClassFactory))
  49. {
  50. *iplpv=(LPVOID) this;
  51. ((LPUNKNOWN)*iplpv)->AddRef();
  52. return ResultFromScode (S_OK);
  53. }
  54. return ResultFromScode (E_NOINTERFACE);
  55. }
  56. //***************************************************************************
  57. //
  58. // CSMIRClassFactory::LockServer
  59. //
  60. // Purpose:
  61. // Increments or decrements the lock count of the DLL. If the
  62. // lock count goes to zero and there are no objects, the DLL
  63. // is allowed to unload. See DllCanUnloadNow.
  64. //
  65. // Parameters:
  66. // fLock BOOL specifying whether to increment or
  67. // decrement the lock count.
  68. //
  69. // Return Value:
  70. // HRESULT NOERROR always.
  71. //***************************************************************************
  72. STDMETHODIMP CSMIRClassFactory :: LockServer (BOOL fLock)
  73. {
  74. /*
  75. * Place code in critical section
  76. */
  77. if (fLock)
  78. {
  79. locksInProgress ++;
  80. }
  81. else
  82. {
  83. if(locksInProgress)
  84. locksInProgress --;
  85. }
  86. return S_OK;
  87. }
  88. CSMIRClassFactory :: ~CSMIRClassFactory ( void )
  89. {
  90. };
  91. //***************************************************************************
  92. //
  93. // CSMIRClassFactory::CreateInstance
  94. //
  95. // Purpose: Instantiates a SMIR object returning an interface pointer.
  96. //
  97. // Parameters:
  98. // pUnkOuter LPUNKNOWN to the controlling IUnknown if we are
  99. // being used in an aggregation.
  100. // riid REFIID identifying the interface the caller
  101. // desires to have for the new object.
  102. // ppvObj PPVOID in which to store the desired
  103. // interface pointer for the new object.
  104. //
  105. // Return Value:
  106. // HRESULT S_OK if successful, otherwise E_NOINTERFACE
  107. // if we cannot support the requested interface.
  108. //***************************************************************************
  109. STDMETHODIMP CSMIRClassFactory :: CreateInstance (LPUNKNOWN pUnkOuter, REFIID riid,
  110. LPVOID FAR * ppvObject)
  111. {
  112. HRESULT status=S_OK;
  113. LPUNKNOWN lObj=NULL;
  114. *ppvObject= NULL;
  115. //dont support aggregation
  116. if (pUnkOuter)
  117. {
  118. return ResultFromScode(CLASS_E_NOAGGREGATION);
  119. }
  120. //create the correct interface
  121. if((IID_ISMIR_Interrogative==riid)||
  122. (IID_ISMIR_Administrative==riid)||
  123. (IID_ISMIR_Database == riid) ||
  124. (IID_ISMIRWbemConfiguration == riid) ||
  125. (IID_ISMIR_Notify == riid)||
  126. (IID_IConnectionPointContainer==riid)||
  127. (IID_IUnknown==riid))
  128. {
  129. /*OK the interrogative, administrative and notify interfaces
  130. *are contained in the smir interface so just create the smir
  131. */
  132. try
  133. {
  134. lObj = (LPUNKNOWN)(new CSmir);
  135. }
  136. catch (...)
  137. {
  138. lObj = NULL;
  139. }
  140. }
  141. else
  142. {
  143. return ResultFromScode (E_NOINTERFACE);
  144. }
  145. if (NULL==lObj)
  146. {
  147. return ResultFromScode(E_OUTOFMEMORY);
  148. }
  149. status=lObj->QueryInterface (riid , ppvObject);
  150. if (FAILED (status))
  151. {
  152. delete lObj;
  153. }
  154. return status;
  155. }
  156. //***************************************************************************
  157. //
  158. // CModHandleClassFactory::QueryInterface
  159. //
  160. // Purpose: Standard Ole routines needed for all interfaces
  161. //
  162. //***************************************************************************
  163. STDMETHODIMP CModHandleClassFactory::QueryInterface (REFIID iid , PVOID FAR *iplpv)
  164. {
  165. *iplpv=NULL;
  166. if ((iid==IID_IUnknown)||(iid==IID_IClassFactory))
  167. {
  168. *iplpv=(LPVOID) this;
  169. ((LPUNKNOWN)*iplpv)->AddRef();
  170. return ResultFromScode (S_OK);
  171. }
  172. return ResultFromScode (E_NOINTERFACE);
  173. }
  174. //***************************************************************************
  175. //
  176. // CGroupHandleClassFactory::LockServer
  177. //
  178. // Purpose:
  179. // Increments or decrements the lock count of the DLL. If the
  180. // lock count goes to zero and there are no objects, the DLL
  181. // is allowed to unload. See DllCanUnloadNow.
  182. //
  183. // Parameters:
  184. // fLock BOOL specifying whether to increment or
  185. // decrement the lock count.
  186. //
  187. // Return Value:
  188. // HRESULT NOERROR always.
  189. //***************************************************************************
  190. STDMETHODIMP CModHandleClassFactory :: LockServer (BOOL fLock)
  191. {
  192. /*
  193. * Place code in critical section
  194. */
  195. if (fLock)
  196. {
  197. locksInProgress ++;
  198. }
  199. else
  200. {
  201. if(locksInProgress)
  202. locksInProgress --;
  203. }
  204. return S_OK;
  205. }
  206. //***************************************************************************
  207. //
  208. // CModHandleClassFactory::CreateInstance
  209. //
  210. // Purpose: Instantiates a SMIR object returning an interface pointer.
  211. //
  212. // Parameters:
  213. // pUnkOuter LPUNKNOWN to the controlling IUnknown if we are
  214. // being used in an aggregation.
  215. // riid REFIID identifying the interface the caller
  216. // desires to have for the new object.
  217. // ppvObj PPVOID in which to store the desired
  218. // interface pointer for the new object.
  219. //
  220. // Return Value:
  221. // HRESULT S_OK if successful, otherwise E_NOINTERFACE
  222. // if we cannot support the requested interface.
  223. //***************************************************************************
  224. STDMETHODIMP CModHandleClassFactory :: CreateInstance (LPUNKNOWN pUnkOuter, REFIID riid,
  225. LPVOID FAR * ppvObject)
  226. {
  227. HRESULT status=S_OK;
  228. LPUNKNOWN lObj=NULL;
  229. *ppvObject= NULL;
  230. //dont support aggregation
  231. if (pUnkOuter)
  232. {
  233. return ResultFromScode(CLASS_E_NOAGGREGATION);
  234. }
  235. //create the correct interface
  236. if((IID_ISMIR_ModHandle==riid)||
  237. (IID_IUnknown==riid))
  238. {
  239. try
  240. {
  241. lObj=(LPUNKNOWN) new CSmirModuleHandle;
  242. }
  243. catch(...)
  244. {
  245. lObj = NULL;
  246. }
  247. }
  248. else
  249. {
  250. return ResultFromScode (E_NOINTERFACE);
  251. }
  252. if (NULL==lObj)
  253. {
  254. return ResultFromScode(E_OUTOFMEMORY);
  255. }
  256. status=lObj->QueryInterface (riid , ppvObject);
  257. if (FAILED (status))
  258. {
  259. delete lObj;
  260. }
  261. return status;
  262. }
  263. //***************************************************************************
  264. //
  265. // CClassHandleClassFactory::QueryInterface
  266. //
  267. // Purpose: Standard Ole routines needed for all interfaces
  268. //
  269. //***************************************************************************
  270. STDMETHODIMP CClassHandleClassFactory::QueryInterface (REFIID iid , PVOID FAR *iplpv)
  271. {
  272. *iplpv=NULL;
  273. if ((iid==IID_IUnknown)||(iid==IID_IClassFactory))
  274. {
  275. *iplpv=(LPVOID) this;
  276. ((LPUNKNOWN)*iplpv)->AddRef();
  277. return ResultFromScode (S_OK);
  278. }
  279. return ResultFromScode (E_NOINTERFACE);
  280. }
  281. //***************************************************************************
  282. //
  283. // CGroupHandleClassFactory::LockServer
  284. //
  285. // Purpose:
  286. // Increments or decrements the lock count of the DLL. If the
  287. // lock count goes to zero and there are no objects, the DLL
  288. // is allowed to unload. See DllCanUnloadNow.
  289. //
  290. // Parameters:
  291. // fLock BOOL specifying whether to increment or
  292. // decrement the lock count.
  293. //
  294. // Return Value:
  295. // HRESULT NOERROR always.
  296. //***************************************************************************
  297. STDMETHODIMP CClassHandleClassFactory :: LockServer (BOOL fLock)
  298. {
  299. /*
  300. * Place code in critical section
  301. */
  302. if (fLock)
  303. {
  304. locksInProgress ++;
  305. }
  306. else
  307. {
  308. if(locksInProgress)
  309. locksInProgress --;
  310. }
  311. return S_OK;
  312. }
  313. //***************************************************************************
  314. //
  315. // CClassHandleClassFactory::CreateInstance
  316. //
  317. // Purpose: Instantiates a SMIR object returning an interface pointer.
  318. //
  319. // Parameters:
  320. // pUnkOuter LPUNKNOWN to the controlling IUnknown if we are
  321. // being used in an aggregation.
  322. // riid REFIID identifying the interface the caller
  323. // desires to have for the new object.
  324. // ppvObj PPVOID in which to store the desired
  325. // interface pointer for the new object.
  326. //
  327. // Return Value:
  328. // HRESULT S_OK if successful, otherwise E_NOINTERFACE
  329. // if we cannot support the requested interface.
  330. //***************************************************************************
  331. STDMETHODIMP CClassHandleClassFactory :: CreateInstance (LPUNKNOWN pUnkOuter, REFIID riid,
  332. LPVOID FAR * ppvObject)
  333. {
  334. HRESULT status=S_OK;
  335. LPUNKNOWN lObj=NULL;
  336. *ppvObject= NULL;
  337. //dont support aggregation
  338. if (pUnkOuter)
  339. {
  340. return ResultFromScode(CLASS_E_NOAGGREGATION);
  341. }
  342. //create the correct interface
  343. if((IID_ISMIR_ClassHandle==riid)||
  344. (IID_IUnknown==riid))
  345. {
  346. try
  347. {
  348. lObj=(LPUNKNOWN) new CSmirClassHandle;
  349. }
  350. catch(...)
  351. {
  352. lObj = NULL;
  353. }
  354. }
  355. else
  356. {
  357. return ResultFromScode (E_NOINTERFACE);
  358. }
  359. if (NULL==lObj)
  360. {
  361. return ResultFromScode(E_OUTOFMEMORY);
  362. }
  363. status=lObj->QueryInterface (riid , ppvObject);
  364. if (FAILED (status))
  365. {
  366. delete lObj;
  367. }
  368. return status;
  369. }
  370. //***************************************************************************
  371. //
  372. // CGroupHandleClassFactory::QueryInterface
  373. //
  374. // Purpose: Standard Ole routines needed for all interfaces
  375. //
  376. //***************************************************************************
  377. STDMETHODIMP CGroupHandleClassFactory::QueryInterface (REFIID iid , PVOID FAR *iplpv)
  378. {
  379. *iplpv=NULL;
  380. if ((iid==IID_IUnknown)||(iid==IID_IClassFactory))
  381. {
  382. *iplpv=(LPVOID) this;
  383. ((LPUNKNOWN)*iplpv)->AddRef();
  384. return ResultFromScode (S_OK);
  385. }
  386. return ResultFromScode (E_NOINTERFACE);
  387. }
  388. //***************************************************************************
  389. //
  390. // CGroupHandleClassFactory::LockServer
  391. //
  392. // Purpose:
  393. // Increments or decrements the lock count of the DLL. If the
  394. // lock count goes to zero and there are no objects, the DLL
  395. // is allowed to unload. See DllCanUnloadNow.
  396. //
  397. // Parameters:
  398. // fLock BOOL specifying whether to increment or
  399. // decrement the lock count.
  400. //
  401. // Return Value:
  402. // HRESULT NOERROR always.
  403. //***************************************************************************
  404. STDMETHODIMP CGroupHandleClassFactory :: LockServer (BOOL fLock)
  405. {
  406. /*
  407. * Place code in critical section
  408. */
  409. if (fLock)
  410. {
  411. locksInProgress ++;
  412. }
  413. else
  414. {
  415. if(locksInProgress)
  416. locksInProgress --;
  417. }
  418. return S_OK;
  419. }
  420. //***************************************************************************
  421. //
  422. // CGroupHandleClassFactory::CreateInstance
  423. //
  424. // Purpose: Instantiates a SMIR object returning an interface pointer.
  425. //
  426. // Parameters:
  427. // pUnkOuter LPUNKNOWN to the controlling IUnknown if we are
  428. // being used in an aggregation.
  429. // riid REFIID identifying the interface the caller
  430. // desires to have for the new object.
  431. // ppvObj PPVOID in which to store the desired
  432. // interface pointer for the new object.
  433. //
  434. // Return Value:
  435. // HRESULT S_OK if successful, otherwise E_NOINTERFACE
  436. // if we cannot support the requested interface.
  437. //***************************************************************************
  438. STDMETHODIMP CGroupHandleClassFactory :: CreateInstance (LPUNKNOWN pUnkOuter, REFIID riid,
  439. LPVOID FAR * ppvObject)
  440. {
  441. HRESULT status=S_OK;
  442. LPUNKNOWN lObj=NULL;
  443. *ppvObject= NULL;
  444. //dont support aggregation
  445. if (pUnkOuter)
  446. {
  447. return ResultFromScode(CLASS_E_NOAGGREGATION);
  448. }
  449. //create the correct interface
  450. if((IID_ISMIR_GroupHandle==riid)||
  451. (IID_IUnknown==riid))
  452. {
  453. try
  454. {
  455. lObj=(LPUNKNOWN) new CSmirGroupHandle;
  456. }
  457. catch(...)
  458. {
  459. lObj = NULL;
  460. }
  461. }
  462. else
  463. {
  464. return ResultFromScode (E_NOINTERFACE);
  465. }
  466. if (NULL==lObj)
  467. {
  468. return ResultFromScode(E_OUTOFMEMORY);
  469. }
  470. status=lObj->QueryInterface (riid , ppvObject);
  471. if (FAILED (status))
  472. {
  473. delete lObj;
  474. }
  475. return status;
  476. }
  477. //***************************************************************************
  478. //
  479. // CSMIRClassFactory::CSMIRClassFactory
  480. // CSMIRClassFactory::~CSMIRClassFactory
  481. //
  482. // Constructor Parameters:
  483. // None
  484. //***************************************************************************
  485. CSMIRGenericClassFactory :: CSMIRGenericClassFactory (CLSID iid)
  486. {
  487. m_referenceCount=0;
  488. }
  489. CSMIRGenericClassFactory::~CSMIRGenericClassFactory ()
  490. {
  491. }
  492. STDMETHODIMP_(ULONG) CSMIRGenericClassFactory :: AddRef ()
  493. {
  494. /*criticalSection.Lock();
  495. m_referenceCount++;
  496. criticalSection.Unlock();
  497. */
  498. InterlockedIncrement(&m_referenceCount);
  499. return m_referenceCount;
  500. }
  501. STDMETHODIMP_(ULONG) CSMIRGenericClassFactory :: Release ()
  502. {
  503. //if ((--m_referenceCount)==0)
  504. long ret;
  505. if ((ret=InterlockedDecrement(&m_referenceCount))==0)
  506. {
  507. delete this;
  508. return 0;
  509. }
  510. else
  511. {
  512. return ret;
  513. }
  514. }
  515. //****************************NotificationClass stuff*****************
  516. //***************************************************************************
  517. //
  518. // CNotificationClassHandleClassFactory::QueryInterface
  519. //
  520. // Purpose: Standard Ole routines needed for all interfaces
  521. //
  522. //***************************************************************************
  523. STDMETHODIMP CNotificationClassHandleClassFactory::QueryInterface (REFIID iid , PVOID FAR *iplpv)
  524. {
  525. *iplpv=NULL;
  526. if ((iid==IID_IUnknown)||(iid==IID_IClassFactory))
  527. {
  528. *iplpv=(LPVOID) this;
  529. ((LPUNKNOWN)*iplpv)->AddRef();
  530. return ResultFromScode (S_OK);
  531. }
  532. return ResultFromScode (E_NOINTERFACE);
  533. }
  534. //***************************************************************************
  535. //
  536. // CNotificationClassHandleClassFactory::LockServer
  537. //
  538. // Purpose:
  539. // Increments or decrements the lock count of the DLL. If the
  540. // lock count goes to zero and there are no objects, the DLL
  541. // is allowed to unload. See DllCanUnloadNow.
  542. //
  543. // Parameters:
  544. // fLock BOOL specifying whether to increment or
  545. // decrement the lock count.
  546. //
  547. // Return Value:
  548. // HRESULT NOERROR always.
  549. //***************************************************************************
  550. STDMETHODIMP CNotificationClassHandleClassFactory :: LockServer (BOOL fLock)
  551. {
  552. /*
  553. * Place code in critical section
  554. */
  555. if (fLock)
  556. {
  557. locksInProgress ++;
  558. }
  559. else
  560. {
  561. if(locksInProgress)
  562. locksInProgress --;
  563. }
  564. return S_OK;
  565. }
  566. //***************************************************************************
  567. //
  568. // CNotificationClassHandleClassFactory::CreateInstance
  569. //
  570. // Purpose: Instantiates a SMIR object returning an interface pointer.
  571. //
  572. // Parameters:
  573. // pUnkOuter LPUNKNOWN to the controlling IUnknown if we are
  574. // being used in an aggregation.
  575. // riid REFIID identifying the interface the caller
  576. // desires to have for the new object.
  577. // ppvObj PPVOID in which to store the desired
  578. // interface pointer for the new object.
  579. //
  580. // Return Value:
  581. // HRESULT S_OK if successful, otherwise E_NOINTERFACE
  582. // if we cannot support the requested interface.
  583. //***************************************************************************
  584. STDMETHODIMP CNotificationClassHandleClassFactory :: CreateInstance (LPUNKNOWN pUnkOuter,
  585. REFIID riid, LPVOID FAR * ppvObject)
  586. {
  587. HRESULT status=S_OK;
  588. LPUNKNOWN lObj=NULL;
  589. *ppvObject= NULL;
  590. //dont support aggregation
  591. if (pUnkOuter)
  592. {
  593. return ResultFromScode(CLASS_E_NOAGGREGATION);
  594. }
  595. //create the correct interface
  596. if((IID_ISMIR_NotificationClassHandle==riid)||
  597. (IID_IUnknown==riid))
  598. {
  599. try
  600. {
  601. lObj=(LPUNKNOWN) new CSmirNotificationClassHandle;
  602. }
  603. catch(...)
  604. {
  605. lObj = NULL;
  606. }
  607. }
  608. else
  609. {
  610. return ResultFromScode (E_NOINTERFACE);
  611. }
  612. if (NULL==lObj)
  613. {
  614. return ResultFromScode(E_OUTOFMEMORY);
  615. }
  616. status=lObj->QueryInterface (riid , ppvObject);
  617. if (FAILED (status))
  618. {
  619. delete lObj;
  620. }
  621. return status;
  622. }
  623. //***************************************************************************
  624. //
  625. // CExtNotificationClassHandleClassFactory::QueryInterface
  626. //
  627. // Purpose: Standard Ole routines needed for all interfaces
  628. //
  629. //***************************************************************************
  630. STDMETHODIMP CExtNotificationClassHandleClassFactory::QueryInterface (REFIID iid , PVOID FAR *iplpv)
  631. {
  632. *iplpv=NULL;
  633. if ((iid==IID_IUnknown)||(iid==IID_IClassFactory))
  634. {
  635. *iplpv=(LPVOID) this;
  636. ((LPUNKNOWN)*iplpv)->AddRef();
  637. return ResultFromScode (S_OK);
  638. }
  639. return ResultFromScode (E_NOINTERFACE);
  640. }
  641. //***************************************************************************
  642. //
  643. // CExtNotificationClassHandleClassFactory::LockServer
  644. //
  645. // Purpose:
  646. // Increments or decrements the lock count of the DLL. If the
  647. // lock count goes to zero and there are no objects, the DLL
  648. // is allowed to unload. See DllCanUnloadNow.
  649. //
  650. // Parameters:
  651. // fLock BOOL specifying whether to increment or
  652. // decrement the lock count.
  653. //
  654. // Return Value:
  655. // HRESULT NOERROR always.
  656. //***************************************************************************
  657. STDMETHODIMP CExtNotificationClassHandleClassFactory :: LockServer (BOOL fLock)
  658. {
  659. /*
  660. * Place code in critical section
  661. */
  662. if (fLock)
  663. {
  664. locksInProgress ++;
  665. }
  666. else
  667. {
  668. if(locksInProgress)
  669. locksInProgress --;
  670. }
  671. return S_OK;
  672. }
  673. //***************************************************************************
  674. //
  675. // CExtNotificationClassHandleClassFactory::CreateInstance
  676. //
  677. // Purpose: Instantiates a SMIR object returning an interface pointer.
  678. //
  679. // Parameters:
  680. // pUnkOuter LPUNKNOWN to the controlling IUnknown if we are
  681. // being used in an aggregation.
  682. // riid REFIID identifying the interface the caller
  683. // desires to have for the new object.
  684. // ppvObj PPVOID in which to store the desired
  685. // interface pointer for the new object.
  686. //
  687. // Return Value:
  688. // HRESULT S_OK if successful, otherwise E_NOINTERFACE
  689. // if we cannot support the requested interface.
  690. //***************************************************************************
  691. STDMETHODIMP CExtNotificationClassHandleClassFactory :: CreateInstance (LPUNKNOWN pUnkOuter,
  692. REFIID riid, LPVOID FAR * ppvObject)
  693. {
  694. HRESULT status=S_OK;
  695. LPUNKNOWN lObj=NULL;
  696. *ppvObject= NULL;
  697. //dont support aggregation
  698. if (pUnkOuter)
  699. {
  700. return ResultFromScode(CLASS_E_NOAGGREGATION);
  701. }
  702. //create the correct interface
  703. if((IID_ISMIR_ExtNotificationClassHandle==riid)||
  704. (IID_IUnknown==riid))
  705. {
  706. try
  707. {
  708. lObj=(LPUNKNOWN) new CSmirExtNotificationClassHandle;
  709. }
  710. catch (...)
  711. {
  712. lObj = NULL;
  713. }
  714. }
  715. else
  716. {
  717. return ResultFromScode (E_NOINTERFACE);
  718. }
  719. if (NULL==lObj)
  720. {
  721. return ResultFromScode(E_OUTOFMEMORY);
  722. }
  723. status=lObj->QueryInterface (riid , ppvObject);
  724. if (FAILED (status))
  725. {
  726. delete lObj;
  727. }
  728. return status;
  729. }