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.

1229 lines
25 KiB

  1. /*++
  2. Copyright (C) 1996-2001 Microsoft Corporation
  3. Module Name:
  4. ProvResv.cpp
  5. Abstract:
  6. History:
  7. --*/
  8. #include "PreComp.h"
  9. #include <wbemint.h>
  10. #include <stdio.h>
  11. #include "CGlobals.h"
  12. #include "ProvObjectSink.h"
  13. #ifdef INTERNAL_IDENTIFY
  14. /******************************************************************************
  15. *
  16. * Name:
  17. *
  18. *
  19. * Description:
  20. *
  21. *
  22. *****************************************************************************/
  23. HRESULT CCommon_IWbemSyncObjectSink :: Begin_IWbemObjectSink (
  24. DWORD a_ProcessIdentifier ,
  25. HANDLE &a_IdentifyToken ,
  26. BOOL &a_Impersonating ,
  27. IUnknown *&a_OldContext ,
  28. IServerSecurity *&a_OldSecurity ,
  29. BOOL &a_IsProxy ,
  30. IUnknown *&a_Interface ,
  31. BOOL &a_Revert ,
  32. IUnknown *&a_Proxy
  33. )
  34. {
  35. HRESULT t_Result = S_OK ;
  36. a_IdentifyToken = NULL ;
  37. a_Revert = FALSE ;
  38. a_Proxy = NULL ;
  39. a_Impersonating = FALSE ;
  40. a_OldContext = NULL ;
  41. a_OldSecurity = NULL ;
  42. t_Result = ProviderSubSystem_Common_Globals :: BeginCallbackImpersonation ( a_OldContext , a_OldSecurity , a_Impersonating ) ;
  43. if ( SUCCEEDED ( t_Result ) )
  44. {
  45. if ( a_ProcessIdentifier )
  46. {
  47. t_Result = CoImpersonateClient () ;
  48. if ( SUCCEEDED ( t_Result ) )
  49. {
  50. DWORD t_ImpersonationLevel = ProviderSubSystem_Common_Globals :: GetCurrentImpersonationLevel () ;
  51. CoRevertToSelf () ;
  52. if ( t_ImpersonationLevel == RPC_C_IMP_LEVEL_IMPERSONATE || t_ImpersonationLevel == RPC_C_IMP_LEVEL_DELEGATE )
  53. {
  54. t_Result = ProviderSubSystem_Common_Globals :: SetProxyState (
  55. m_ProxyContainer ,
  56. ProxyIndex_IWbemObjectSink ,
  57. IID_IWbemObjectSink ,
  58. m_InterceptedSink ,
  59. a_Proxy ,
  60. a_Revert
  61. ) ;
  62. }
  63. else
  64. {
  65. t_Result = ProviderSubSystem_Common_Globals :: SetProxyState_PrvHost (
  66. m_ProxyContainer ,
  67. ProxyIndex_Internal_IWbemObjectSink ,
  68. IID_Internal_IWbemObjectSink ,
  69. m_Internal_InterceptedSink ,
  70. a_Proxy ,
  71. a_Revert ,
  72. a_ProcessIdentifier ,
  73. a_IdentifyToken
  74. ) ;
  75. }
  76. }
  77. }
  78. else
  79. {
  80. t_Result = ProviderSubSystem_Common_Globals :: SetProxyState (
  81. m_ProxyContainer ,
  82. ProxyIndex_IWbemObjectSink ,
  83. IID_IWbemObjectSink ,
  84. m_InterceptedSink ,
  85. a_Proxy ,
  86. a_Revert
  87. ) ;
  88. }
  89. if ( t_Result == WBEM_E_NOT_FOUND )
  90. {
  91. a_Interface = m_InterceptedSink ;
  92. a_IsProxy = FALSE ;
  93. t_Result = S_OK ;
  94. }
  95. else
  96. {
  97. if ( SUCCEEDED ( t_Result ) )
  98. {
  99. a_IsProxy = TRUE ;
  100. a_Interface = ( IUnknown * ) a_Proxy ;
  101. // Set cloaking on the proxy
  102. // =========================
  103. DWORD t_ImpersonationLevel = ProviderSubSystem_Common_Globals :: GetCurrentImpersonationLevel () ;
  104. t_Result = ProviderSubSystem_Common_Globals :: SetCloaking (
  105. a_Interface ,
  106. RPC_C_AUTHN_LEVEL_CONNECT ,
  107. t_ImpersonationLevel
  108. ) ;
  109. if ( FAILED ( t_Result ) )
  110. {
  111. if ( a_IdentifyToken )
  112. {
  113. HRESULT t_TempResult = ProviderSubSystem_Common_Globals :: RevertProxyState_PrvHost (
  114. m_ProxyContainer ,
  115. ProxyIndex_Internal_IWbemObjectSink ,
  116. a_Proxy ,
  117. a_Revert ,
  118. a_ProcessIdentifier ,
  119. a_IdentifyToken
  120. ) ;
  121. }
  122. else
  123. {
  124. HRESULT t_TempResult = ProviderSubSystem_Common_Globals :: RevertProxyState (
  125. m_ProxyContainer ,
  126. ProxyIndex_IWbemObjectSink ,
  127. a_Proxy ,
  128. a_Revert
  129. ) ;
  130. }
  131. }
  132. }
  133. }
  134. if ( FAILED ( t_Result ) )
  135. {
  136. ProviderSubSystem_Common_Globals :: EndImpersonation ( a_OldContext , a_OldSecurity , a_Impersonating ) ;
  137. }
  138. }
  139. return t_Result ;
  140. }
  141. /******************************************************************************
  142. *
  143. * Name:
  144. *
  145. *
  146. * Description:
  147. *
  148. *
  149. *****************************************************************************/
  150. HRESULT CCommon_IWbemSyncObjectSink :: End_IWbemObjectSink (
  151. DWORD a_ProcessIdentifier ,
  152. HANDLE a_IdentifyToken ,
  153. BOOL a_Impersonating ,
  154. IUnknown *a_OldContext ,
  155. IServerSecurity *a_OldSecurity ,
  156. BOOL a_IsProxy ,
  157. IUnknown *a_Interface ,
  158. BOOL a_Revert ,
  159. IUnknown *a_Proxy
  160. )
  161. {
  162. CoRevertToSelf () ;
  163. if ( a_Proxy )
  164. {
  165. if ( a_IdentifyToken )
  166. {
  167. HRESULT t_TempResult = ProviderSubSystem_Common_Globals :: RevertProxyState_PrvHost (
  168. m_ProxyContainer ,
  169. ProxyIndex_Internal_IWbemObjectSink ,
  170. a_Proxy ,
  171. a_Revert ,
  172. a_ProcessIdentifier ,
  173. a_IdentifyToken
  174. ) ;
  175. }
  176. else
  177. {
  178. HRESULT t_TempResult = ProviderSubSystem_Common_Globals :: RevertProxyState (
  179. m_ProxyContainer ,
  180. ProxyIndex_IWbemObjectSink ,
  181. a_Proxy ,
  182. a_Revert
  183. ) ;
  184. }
  185. }
  186. ProviderSubSystem_Common_Globals :: EndImpersonation ( a_OldContext , a_OldSecurity , a_Impersonating ) ;
  187. return S_OK ;
  188. }
  189. #endif
  190. /******************************************************************************
  191. *
  192. * Name:
  193. *
  194. *
  195. * Description:
  196. *
  197. *
  198. *****************************************************************************/
  199. #pragma warning( disable : 4355 )
  200. CCommon_IWbemSyncObjectSink :: CCommon_IWbemSyncObjectSink (
  201. WmiAllocator &a_Allocator ,
  202. IWbemObjectSink *a_InterceptedSink ,
  203. IUnknown *a_Unknown ,
  204. CWbemGlobal_IWmiObjectSinkController *a_Controller ,
  205. ULONG a_Dependant
  206. ) : ObjectSinkContainerElement (
  207. a_Controller ,
  208. a_InterceptedSink
  209. ) ,
  210. m_InterceptedSink ( a_InterceptedSink ) ,
  211. #ifdef INTERNAL_IDENTIFY
  212. m_Internal_InterceptedSink ( NULL ) ,
  213. m_ProxyContainer ( a_Allocator , ProxyIndex_ObjectSink_Size , MAX_PROXIES )
  214. #endif
  215. m_GateClosed ( FALSE ) ,
  216. m_InProgress ( 0 ) ,
  217. m_Unknown ( a_Unknown ) ,
  218. m_StatusCalled ( FALSE ) ,
  219. m_Dependant ( a_Dependant )
  220. {
  221. if ( m_Unknown )
  222. {
  223. m_Unknown->AddRef () ;
  224. }
  225. if ( m_InterceptedSink )
  226. {
  227. m_InterceptedSink->AddRef () ;
  228. #ifdef INTERNAL_IDENTIFY
  229. HRESULT t_TempResult = m_InterceptedSink->QueryInterface ( IID_Internal_IWbemObjectSink , ( void ** ) & m_Internal_InterceptedSink ) ;
  230. #endif
  231. }
  232. }
  233. #pragma warning( default : 4355 )
  234. /******************************************************************************
  235. *
  236. * Name:
  237. *
  238. *
  239. * Description:
  240. *
  241. *
  242. *****************************************************************************/
  243. CCommon_IWbemSyncObjectSink :: ~CCommon_IWbemSyncObjectSink ()
  244. {
  245. }
  246. /******************************************************************************
  247. *
  248. * Name:
  249. *
  250. *
  251. * Description:
  252. *
  253. *
  254. *****************************************************************************/
  255. void CCommon_IWbemSyncObjectSink :: CallBackInternalRelease ()
  256. {
  257. #ifdef INTERNAL_IDENTIFY
  258. WmiStatusCode t_StatusCode = m_ProxyContainer.UnInitialize () ;
  259. #endif
  260. if ( ! InterlockedCompareExchange ( & m_StatusCalled , 0 , 0 ) )
  261. {
  262. m_InterceptedSink->SetStatus (
  263. 0 ,
  264. WBEM_E_UNEXPECTED ,
  265. NULL ,
  266. NULL
  267. ) ;
  268. }
  269. if ( m_InterceptedSink )
  270. {
  271. m_InterceptedSink->Release () ;
  272. }
  273. #ifdef INTERNAL_IDENTIFY
  274. if ( m_Internal_InterceptedSink )
  275. {
  276. m_Internal_InterceptedSink->Release () ;
  277. }
  278. #endif
  279. if ( m_Unknown )
  280. {
  281. m_Unknown->Release () ;
  282. }
  283. }
  284. /******************************************************************************
  285. *
  286. * Name:
  287. *
  288. *
  289. * Description:
  290. *
  291. *
  292. *****************************************************************************/
  293. STDMETHODIMP CCommon_IWbemSyncObjectSink :: QueryInterface (
  294. REFIID iid ,
  295. LPVOID FAR *iplpv
  296. )
  297. {
  298. *iplpv = NULL ;
  299. if ( iid == IID_IUnknown )
  300. {
  301. *iplpv = ( LPVOID ) this ;
  302. }
  303. else if ( iid == IID_IWbemObjectSink )
  304. {
  305. *iplpv = ( LPVOID ) ( IWbemObjectSink * ) this ;
  306. }
  307. else if ( iid == IID_IWbemShutdown )
  308. {
  309. *iplpv = ( LPVOID ) ( IWbemShutdown * ) this ;
  310. }
  311. if ( *iplpv )
  312. {
  313. ( ( LPUNKNOWN ) *iplpv )->AddRef () ;
  314. return ResultFromScode ( S_OK ) ;
  315. }
  316. else
  317. {
  318. return ResultFromScode ( E_NOINTERFACE ) ;
  319. }
  320. }
  321. /******************************************************************************
  322. *
  323. * Name:
  324. *
  325. *
  326. * Description:
  327. *
  328. *
  329. *****************************************************************************/
  330. STDMETHODIMP_(ULONG) CCommon_IWbemSyncObjectSink :: AddRef ( void )
  331. {
  332. return ObjectSinkContainerElement :: AddRef () ;
  333. }
  334. /******************************************************************************
  335. *
  336. * Name:
  337. *
  338. *
  339. * Description:
  340. *
  341. *
  342. *****************************************************************************/
  343. STDMETHODIMP_(ULONG) CCommon_IWbemSyncObjectSink :: Release ( void )
  344. {
  345. return ObjectSinkContainerElement :: Release () ;
  346. }
  347. /******************************************************************************
  348. *
  349. * Name:
  350. *
  351. *
  352. * Description:
  353. *
  354. *
  355. *****************************************************************************/
  356. HRESULT CCommon_IWbemSyncObjectSink :: SinkInitialize ()
  357. {
  358. HRESULT t_Result = S_OK ;
  359. #ifdef INTERNAL_IDENTIFY
  360. WmiStatusCode t_StatusCode = m_ProxyContainer.Initialize () ;
  361. if ( t_StatusCode != e_StatusCode_Success )
  362. {
  363. t_Result = WBEM_E_OUT_OF_MEMORY ;
  364. }
  365. #endif
  366. return t_Result ;
  367. }
  368. /******************************************************************************
  369. *
  370. * Name:
  371. *
  372. *
  373. * Description:
  374. *
  375. *
  376. *****************************************************************************/
  377. HRESULT CCommon_IWbemSyncObjectSink :: Indicate (
  378. long a_ObjectCount ,
  379. IWbemClassObject **a_ObjectArray
  380. )
  381. {
  382. HRESULT t_Result = S_OK ;
  383. InterlockedIncrement ( & m_InProgress ) ;
  384. if ( m_GateClosed == 1 )
  385. {
  386. t_Result = WBEM_E_SHUTTING_DOWN ;
  387. }
  388. else
  389. {
  390. t_Result = Helper_Indicate (
  391. a_ObjectCount ,
  392. a_ObjectArray
  393. ) ;
  394. #ifdef DBG
  395. if ( FAILED ( t_Result ) )
  396. {
  397. OutputDebugString ( L"\nCCommon_IWbemSyncObjectSink :: Indicate - Failure () " ) ;
  398. }
  399. #endif
  400. }
  401. InterlockedDecrement ( & m_InProgress ) ;
  402. return t_Result ;
  403. }
  404. #ifdef INTERNAL_IDENTIFY
  405. /******************************************************************************
  406. *
  407. * Name:
  408. *
  409. *
  410. * Description:
  411. *
  412. *
  413. *****************************************************************************/
  414. HRESULT CCommon_IWbemSyncObjectSink :: Helper_Indicate (
  415. long a_ObjectCount ,
  416. IWbemClassObject **a_ObjectArray
  417. )
  418. {
  419. BOOL t_Impersonating ;
  420. IUnknown *t_OldContext ;
  421. IServerSecurity *t_OldSecurity ;
  422. BOOL t_IsProxy ;
  423. IUnknown *t_Interface ;
  424. BOOL t_Revert ;
  425. IUnknown *t_Proxy ;
  426. DWORD t_ProcessIdentifier = GetCurrentProcessId () ;
  427. HANDLE t_IdentifyToken = NULL ;
  428. HRESULT t_Result = Begin_IWbemObjectSink (
  429. t_ProcessIdentifier ,
  430. t_IdentifyToken ,
  431. t_Impersonating ,
  432. t_OldContext ,
  433. t_OldSecurity ,
  434. t_IsProxy ,
  435. t_Interface ,
  436. t_Revert ,
  437. t_Proxy
  438. ) ;
  439. if ( SUCCEEDED ( t_Result ) )
  440. {
  441. if ( t_IdentifyToken )
  442. {
  443. WmiInternalContext t_InternalContext ;
  444. t_InternalContext.m_IdentifyHandle = ( unsigned __int64 ) t_IdentifyToken ;
  445. t_InternalContext.m_ProcessIdentifier = t_ProcessIdentifier ;
  446. t_Result = ( ( Internal_IWbemObjectSink * ) t_Interface )->Internal_Indicate (
  447. t_InternalContext ,
  448. a_ObjectCount ,
  449. a_ObjectArray
  450. ) ;
  451. }
  452. else
  453. {
  454. t_Result = ( ( IWbemObjectSink * ) t_Interface )->Indicate (
  455. a_ObjectCount ,
  456. a_ObjectArray
  457. ) ;
  458. }
  459. End_IWbemObjectSink (
  460. t_ProcessIdentifier ,
  461. t_IdentifyToken ,
  462. t_Impersonating ,
  463. t_OldContext ,
  464. t_OldSecurity ,
  465. t_IsProxy ,
  466. t_Interface ,
  467. t_Revert ,
  468. t_Proxy
  469. ) ;
  470. }
  471. return t_Result ;
  472. }
  473. /******************************************************************************
  474. *
  475. * Name:
  476. *
  477. *
  478. * Description:
  479. *
  480. *
  481. *****************************************************************************/
  482. HRESULT CCommon_IWbemSyncObjectSink :: Helper_SetStatus (
  483. long a_Flags ,
  484. HRESULT a_Result ,
  485. BSTR a_StringParam ,
  486. IWbemClassObject *a_ObjectParam
  487. )
  488. {
  489. BOOL t_Impersonating ;
  490. IUnknown *t_OldContext ;
  491. IServerSecurity *t_OldSecurity ;
  492. BOOL t_IsProxy ;
  493. IUnknown *t_Interface ;
  494. BOOL t_Revert ;
  495. IUnknown *t_Proxy ;
  496. DWORD t_ProcessIdentifier = GetCurrentProcessId () ;
  497. HANDLE t_IdentifyToken = NULL ;
  498. HRESULT t_Result = Begin_IWbemObjectSink (
  499. t_ProcessIdentifier ,
  500. t_IdentifyToken ,
  501. t_Impersonating ,
  502. t_OldContext ,
  503. t_OldSecurity ,
  504. t_IsProxy ,
  505. t_Interface ,
  506. t_Revert ,
  507. t_Proxy
  508. ) ;
  509. if ( SUCCEEDED ( t_Result ) )
  510. {
  511. BSTR t_StringParam = NULL ;
  512. if ( a_StringParam )
  513. {
  514. t_StringParam = SysAllocString ( a_StringParam ) ;
  515. if ( t_StringParam == NULL )
  516. {
  517. t_Result = WBEM_E_OUT_OF_MEMORY ;
  518. }
  519. }
  520. if ( SUCCEEDED ( t_Result ) )
  521. {
  522. if ( t_IdentifyToken )
  523. {
  524. WmiInternalContext t_InternalContext ;
  525. t_InternalContext.m_IdentifyHandle = ( unsigned __int64 ) t_IdentifyToken ;
  526. t_InternalContext.m_ProcessIdentifier = t_ProcessIdentifier ;
  527. t_Result = ( ( Internal_IWbemObjectSink * ) t_Interface )->Internal_SetStatus (
  528. t_InternalContext ,
  529. a_Flags ,
  530. a_Result ,
  531. t_StringParam ,
  532. a_ObjectParam
  533. ) ;
  534. }
  535. else
  536. {
  537. t_Result = ( ( IWbemObjectSink * ) t_Interface )->SetStatus (
  538. a_Flags ,
  539. a_Result ,
  540. t_StringParam ,
  541. a_ObjectParam
  542. ) ;
  543. }
  544. }
  545. SysFreeString ( t_StringParam ) ;
  546. End_IWbemObjectSink (
  547. t_ProcessIdentifier ,
  548. t_IdentifyToken ,
  549. t_Impersonating ,
  550. t_OldContext ,
  551. t_OldSecurity ,
  552. t_IsProxy ,
  553. t_Interface ,
  554. t_Revert ,
  555. t_Proxy
  556. ) ;
  557. }
  558. return t_Result ;
  559. }
  560. #else
  561. /******************************************************************************
  562. *
  563. * Name:
  564. *
  565. *
  566. * Description:
  567. *
  568. *
  569. *****************************************************************************/
  570. HRESULT CCommon_IWbemSyncObjectSink :: Helper_Indicate (
  571. long a_ObjectCount ,
  572. IWbemClassObject **a_ObjectArray
  573. )
  574. {
  575. HRESULT t_Result = m_InterceptedSink->Indicate (
  576. a_ObjectCount ,
  577. a_ObjectArray
  578. ) ;
  579. return t_Result ;
  580. }
  581. /******************************************************************************
  582. *
  583. * Name:
  584. *
  585. *
  586. * Description:
  587. *
  588. *
  589. *****************************************************************************/
  590. HRESULT CCommon_IWbemSyncObjectSink :: Helper_SetStatus (
  591. long a_Flags ,
  592. HRESULT a_Result ,
  593. BSTR a_StringParam ,
  594. IWbemClassObject *a_ObjectParam
  595. )
  596. {
  597. HRESULT t_Result = S_OK ;
  598. BSTR t_StringParam = NULL ;
  599. if ( a_StringParam )
  600. {
  601. t_StringParam = SysAllocString ( a_StringParam ) ;
  602. if ( t_StringParam == NULL )
  603. {
  604. t_Result = WBEM_E_OUT_OF_MEMORY ;
  605. }
  606. }
  607. if ( SUCCEEDED ( t_Result ) )
  608. {
  609. t_Result = m_InterceptedSink->SetStatus (
  610. a_Flags ,
  611. a_Result ,
  612. t_StringParam ,
  613. a_ObjectParam
  614. ) ;
  615. SysFreeString ( t_StringParam ) ;
  616. }
  617. return t_Result ;
  618. }
  619. #endif
  620. /******************************************************************************
  621. *
  622. * Name:
  623. *
  624. *
  625. * Description:
  626. *
  627. *
  628. *****************************************************************************/
  629. HRESULT CCommon_IWbemSyncObjectSink :: SetStatus (
  630. long a_Flags ,
  631. HRESULT a_Result ,
  632. BSTR a_StringParam ,
  633. IWbemClassObject *a_ObjectParam
  634. )
  635. {
  636. #if 0
  637. OutputDebugString ( L"\nCCommon_IWbemSyncObjectSink :: SetStatus ()" ) ;
  638. #endif
  639. HRESULT t_Result = S_OK ;
  640. InterlockedIncrement ( & m_InProgress ) ;
  641. if ( m_GateClosed == 1 )
  642. {
  643. t_Result = WBEM_E_SHUTTING_DOWN ;
  644. }
  645. else
  646. {
  647. switch ( a_Flags )
  648. {
  649. case WBEM_STATUS_PROGRESS:
  650. {
  651. t_Result = Helper_SetStatus (
  652. a_Flags ,
  653. a_Result ,
  654. a_StringParam ,
  655. a_ObjectParam
  656. ) ;
  657. }
  658. break ;
  659. case WBEM_STATUS_COMPLETE:
  660. {
  661. if ( ! InterlockedCompareExchange ( & m_StatusCalled , 1 , 0 ) )
  662. {
  663. t_Result = Helper_SetStatus (
  664. a_Flags ,
  665. a_Result ,
  666. a_StringParam ,
  667. a_ObjectParam
  668. ) ;
  669. }
  670. }
  671. break ;
  672. default:
  673. {
  674. t_Result = WBEM_E_INVALID_PARAMETER ;
  675. }
  676. break ;
  677. }
  678. }
  679. InterlockedDecrement ( & m_InProgress ) ;
  680. return t_Result ;
  681. }
  682. /******************************************************************************
  683. *
  684. * Name:
  685. *
  686. *
  687. * Description:
  688. *
  689. *
  690. *****************************************************************************/
  691. HRESULT CCommon_IWbemSyncObjectSink :: Shutdown (
  692. LONG a_Flags ,
  693. ULONG a_MaxMilliSeconds ,
  694. IWbemContext *a_Context
  695. )
  696. {
  697. HRESULT t_Result = S_OK ;
  698. InterlockedIncrement ( & m_GateClosed ) ;
  699. if ( ! InterlockedCompareExchange ( & m_StatusCalled , 1 , 0 ) )
  700. {
  701. t_Result = Helper_SetStatus (
  702. 0 ,
  703. WBEM_E_SHUTTING_DOWN ,
  704. NULL ,
  705. NULL
  706. ) ;
  707. }
  708. bool t_Acquired = false ;
  709. while ( ! t_Acquired )
  710. {
  711. if ( m_InProgress == 0 )
  712. {
  713. t_Acquired = true ;
  714. break ;
  715. }
  716. if ( SwitchToThread () == FALSE )
  717. {
  718. }
  719. }
  720. return t_Result ;
  721. }
  722. /******************************************************************************
  723. *
  724. * Name:
  725. *
  726. *
  727. * Description:
  728. *
  729. *
  730. *****************************************************************************/
  731. #pragma warning( disable : 4355 )
  732. CCommon_Batching_IWbemSyncObjectSink :: CCommon_Batching_IWbemSyncObjectSink (
  733. WmiAllocator &a_Allocator ,
  734. IWbemObjectSink *a_InterceptedSink ,
  735. IUnknown *a_Unknown ,
  736. CWbemGlobal_IWmiObjectSinkController *a_Controller ,
  737. ULONG a_Dependant
  738. ) : CCommon_IWbemSyncObjectSink (
  739. a_Allocator ,
  740. a_InterceptedSink ,
  741. a_Unknown ,
  742. a_Controller ,
  743. a_Dependant
  744. ) ,
  745. m_Queue ( a_Allocator ) ,
  746. m_Size ( 0 ),
  747. m_CriticalSection(NOTHROW_LOCK)
  748. {
  749. }
  750. #pragma warning( default : 4355 )
  751. /******************************************************************************
  752. *
  753. * Name:
  754. *
  755. *
  756. * Description:
  757. *
  758. *
  759. *****************************************************************************/
  760. CCommon_Batching_IWbemSyncObjectSink :: ~CCommon_Batching_IWbemSyncObjectSink ()
  761. {
  762. ULONG t_Count = m_Queue.Size();
  763. for ( ULONG t_Index = 0 ; t_Index < t_Count ; t_Index ++ )
  764. {
  765. IWbemClassObject *t_ClassObject ;
  766. WmiStatusCode t_StatusCode = m_Queue.Top ( t_ClassObject ) ;
  767. if ( t_StatusCode == e_StatusCode_Success )
  768. {
  769. t_ClassObject->Release () ;
  770. t_StatusCode = m_Queue.DeQueue () ;
  771. }
  772. }
  773. m_Queue.UnInitialize () ;
  774. WmiHelper :: DeleteCriticalSection ( & m_CriticalSection );
  775. }
  776. /******************************************************************************
  777. *
  778. * Name:
  779. *
  780. *
  781. * Description:
  782. *
  783. *
  784. *****************************************************************************/
  785. HRESULT CCommon_Batching_IWbemSyncObjectSink :: SinkInitialize ()
  786. {
  787. HRESULT t_Result = CCommon_IWbemSyncObjectSink :: SinkInitialize () ;
  788. if ( SUCCEEDED ( t_Result ) )
  789. {
  790. WmiStatusCode t_StatusCode = WmiHelper :: InitializeCriticalSection ( & m_CriticalSection );
  791. if ( t_StatusCode == e_StatusCode_Success )
  792. {
  793. t_StatusCode = m_Queue.Initialize () ;
  794. if ( t_StatusCode == e_StatusCode_Success )
  795. {
  796. }
  797. else
  798. {
  799. t_Result = WBEM_E_OUT_OF_MEMORY ;
  800. }
  801. }
  802. else
  803. {
  804. t_Result = WBEM_E_OUT_OF_MEMORY ;
  805. }
  806. }
  807. return t_Result ;
  808. }
  809. class CReleaseMe
  810. {
  811. private:
  812. IUnknown * m_pUnk;
  813. public:
  814. CReleaseMe(IUnknown * pUnk):m_pUnk(pUnk){};
  815. ~CReleaseMe(){ m_pUnk->Release(); };
  816. };
  817. /******************************************************************************
  818. *
  819. * Name:
  820. *
  821. *
  822. * Description:
  823. *
  824. *
  825. *****************************************************************************/
  826. HRESULT CCommon_Batching_IWbemSyncObjectSink :: Indicate (
  827. long a_ObjectCount ,
  828. IWbemClassObject **a_ObjectArray
  829. )
  830. {
  831. HRESULT t_Result = S_OK ;
  832. if ( m_GateClosed == 0 )
  833. {
  834. WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection ( & m_CriticalSection , FALSE ) ;
  835. if ( t_StatusCode == e_StatusCode_Success )
  836. {
  837. for ( LONG t_Index = 0 ; SUCCEEDED ( t_Result ) && ( t_Index < a_ObjectCount ) ; t_Index ++ )
  838. {
  839. if ( a_ObjectArray [ t_Index ] )
  840. {
  841. IWbemClassObject *t_ClonedObject = NULL ;
  842. t_Result = a_ObjectArray [ t_Index ]->Clone ( &t_ClonedObject ) ;
  843. if ( SUCCEEDED ( t_Result ) )
  844. {
  845. CReleaseMe rmCloned(t_ClonedObject);
  846. ULONG t_ObjectSize = 0 ;
  847. _IWmiObject *t_Object ;
  848. HRESULT t_TempResult = t_ClonedObject->QueryInterface ( IID__IWmiObject , ( void ** ) & t_Object ) ;
  849. if ( SUCCEEDED ( t_TempResult ) )
  850. {
  851. CReleaseMe rmQIed(t_Object);
  852. t_TempResult = t_Object->GetObjectMemory (
  853. NULL ,
  854. 0 ,
  855. & t_ObjectSize
  856. );
  857. if ( t_TempResult == WBEM_E_BUFFER_TOO_SMALL )
  858. {
  859. WmiStatusCode t_StatusCode = m_Queue.EnQueue ( t_ClonedObject ) ;
  860. if ( t_StatusCode == e_StatusCode_Success )
  861. {
  862. t_ClonedObject ->AddRef();
  863. m_Size = m_Size + t_ObjectSize ;
  864. }
  865. else
  866. {
  867. t_Result = WBEM_E_OUT_OF_MEMORY ;
  868. }
  869. if ( SUCCEEDED(t_Result) &&
  870. (( m_Size ) >= ProviderSubSystem_Common_Globals :: GetTransmitSize () ))
  871. {
  872. ULONG t_Count = m_Queue.Size () ;
  873. IWbemClassObject **t_Array = new IWbemClassObject * [ t_Count ] ;
  874. if ( t_Array )
  875. {
  876. IWbemClassObject *t_ClassObject ;
  877. WmiStatusCode t_StatusCode ;
  878. ULONG t_InnerIndex = 0 ;
  879. while ( ( t_StatusCode = m_Queue.Top ( t_ClassObject ) ) == e_StatusCode_Success )
  880. {
  881. t_Array [ t_InnerIndex ] = t_ClassObject ;
  882. t_InnerIndex ++ ;
  883. t_StatusCode = m_Queue.DeQueue() ;
  884. }
  885. m_Size = 0 ;
  886. WmiHelper :: LeaveCriticalSection ( & m_CriticalSection ) ;
  887. t_Result = CCommon_IWbemSyncObjectSink :: Indicate ( t_Count , t_Array ) ;
  888. for ( t_InnerIndex = 0 ; t_InnerIndex < t_Count ; t_InnerIndex ++ )
  889. {
  890. t_Array [ t_InnerIndex ]->Release () ;
  891. }
  892. delete [] t_Array ;
  893. t_StatusCode = WmiHelper :: EnterCriticalSection ( & m_CriticalSection , FALSE ) ;
  894. if ( t_StatusCode == e_StatusCode_Success )
  895. {
  896. }
  897. else
  898. {
  899. t_Result = WBEM_E_OUT_OF_MEMORY ;
  900. }
  901. }
  902. else
  903. {
  904. t_Result = WBEM_E_OUT_OF_MEMORY ;
  905. WmiHelper :: LeaveCriticalSection ( & m_CriticalSection );
  906. }
  907. }
  908. }
  909. else
  910. {
  911. t_Result = WBEM_E_CRITICAL_ERROR ;
  912. }
  913. }
  914. else
  915. {
  916. t_Result = WBEM_E_CRITICAL_ERROR ;
  917. }
  918. }
  919. }
  920. }
  921. WmiHelper :: LeaveCriticalSection ( & m_CriticalSection );
  922. return t_Result ;
  923. }
  924. else
  925. {
  926. return WBEM_E_OUT_OF_MEMORY ;
  927. }
  928. }
  929. else
  930. {
  931. return WBEM_E_SHUTTING_DOWN ;
  932. }
  933. }
  934. /******************************************************************************
  935. *
  936. * Name:
  937. *
  938. *
  939. * Description:
  940. *
  941. *
  942. *****************************************************************************/
  943. HRESULT CCommon_Batching_IWbemSyncObjectSink :: SetStatus (
  944. long a_Flags ,
  945. HRESULT a_Result ,
  946. BSTR a_StringParam ,
  947. IWbemClassObject *a_ObjectParam
  948. )
  949. {
  950. HRESULT t_Result = S_OK ;
  951. switch ( a_Flags )
  952. {
  953. case WBEM_STATUS_COMPLETE:
  954. {
  955. if ( m_GateClosed == 0 )
  956. {
  957. WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection ( & m_CriticalSection , FALSE );
  958. if ( t_StatusCode == e_StatusCode_Success )
  959. {
  960. LONG t_Count = m_Queue.Size () ;
  961. if ( t_Count )
  962. {
  963. IWbemClassObject **t_Array = new IWbemClassObject * [ m_Queue.Size () ] ;
  964. if ( t_Array )
  965. {
  966. for ( LONG t_Index = 0 ; t_Index < t_Count ; t_Index ++ )
  967. {
  968. IWbemClassObject *t_ClassObject ;
  969. WmiStatusCode t_StatusCode = m_Queue.Top ( t_ClassObject ) ;
  970. if ( t_StatusCode == e_StatusCode_Success )
  971. {
  972. t_Array [ t_Index ] = t_ClassObject ;
  973. t_StatusCode = m_Queue.DeQueue () ;
  974. }
  975. }
  976. WmiHelper :: LeaveCriticalSection ( & m_CriticalSection );
  977. t_Result = CCommon_IWbemSyncObjectSink :: Indicate ( t_Count , t_Array ) ;
  978. for ( t_Index = 0 ; t_Index < t_Count ; t_Index ++ )
  979. {
  980. if ( t_Array [ t_Index ] )
  981. {
  982. t_Array [ t_Index ]->Release () ;
  983. }
  984. }
  985. delete [] t_Array ;
  986. }
  987. else
  988. {
  989. WmiHelper :: LeaveCriticalSection ( & m_CriticalSection );
  990. t_Result = WBEM_E_OUT_OF_MEMORY ;
  991. }
  992. }
  993. else
  994. {
  995. WmiHelper :: LeaveCriticalSection ( & m_CriticalSection );
  996. }
  997. }
  998. else
  999. {
  1000. t_Result = WBEM_E_OUT_OF_MEMORY ;
  1001. }
  1002. }
  1003. if ( FAILED ( t_Result ) )
  1004. {
  1005. a_Result = t_Result ;
  1006. }
  1007. t_Result = CCommon_IWbemSyncObjectSink :: SetStatus (
  1008. a_Flags ,
  1009. a_Result ,
  1010. a_StringParam ,
  1011. a_ObjectParam
  1012. ) ;
  1013. }
  1014. break ;
  1015. default:
  1016. {
  1017. t_Result = CCommon_IWbemSyncObjectSink :: SetStatus (
  1018. a_Flags ,
  1019. a_Result ,
  1020. a_StringParam ,
  1021. a_ObjectParam
  1022. ) ;
  1023. }
  1024. break ;
  1025. }
  1026. return t_Result ;
  1027. }