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.

803 lines
16 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. #include <wbemutil.h>
  14. #ifdef DBG
  15. fn__uncaught_exception InterlockedGuard::__uncaught_exception = NULL;
  16. InterlockedGuard::FunctLoader InterlockedGuard::FunctLoader_;
  17. #endif
  18. /******************************************************************************
  19. *
  20. * Name:
  21. *
  22. *
  23. * Description:
  24. *
  25. *
  26. *****************************************************************************/
  27. #pragma warning( disable : 4355 )
  28. CCommon_IWbemSyncObjectSink :: CCommon_IWbemSyncObjectSink (
  29. WmiAllocator &a_Allocator ,
  30. IWbemObjectSink *a_InterceptedSink ,
  31. IUnknown *a_Unknown ,
  32. CWbemGlobal_IWmiObjectSinkController *a_Controller ,
  33. ULONG a_Dependant
  34. ) : ObjectSinkContainerElement (
  35. a_Controller ,
  36. a_InterceptedSink
  37. ) ,
  38. m_InterceptedSink ( a_InterceptedSink ) ,
  39. m_GateClosed ( 0 ) ,
  40. m_InProgress ( 0 ) ,
  41. m_Unknown ( a_Unknown ) ,
  42. m_StatusCalled ( FALSE ) ,
  43. m_Dependant ( a_Dependant )
  44. {
  45. if ( m_Unknown )
  46. {
  47. m_Unknown->AddRef () ;
  48. }
  49. if ( m_InterceptedSink )
  50. {
  51. m_InterceptedSink->AddRef () ;
  52. }
  53. }
  54. #pragma warning( default : 4355 )
  55. /******************************************************************************
  56. *
  57. * Name:
  58. *
  59. *
  60. * Description:
  61. *
  62. *
  63. *****************************************************************************/
  64. CCommon_IWbemSyncObjectSink :: ~CCommon_IWbemSyncObjectSink ()
  65. {
  66. }
  67. /******************************************************************************
  68. *
  69. * Name:
  70. *
  71. *
  72. * Description:
  73. *
  74. *
  75. *****************************************************************************/
  76. void CCommon_IWbemSyncObjectSink :: CallBackInternalRelease ()
  77. {
  78. if ( ! InterlockedCompareExchange ( & m_StatusCalled , 0 , 0 ) )
  79. {
  80. m_InterceptedSink->SetStatus (
  81. 0 ,
  82. WBEM_E_UNEXPECTED ,
  83. NULL ,
  84. NULL
  85. ) ;
  86. }
  87. if ( m_InterceptedSink )
  88. {
  89. m_InterceptedSink->Release () ;
  90. }
  91. if ( m_Unknown )
  92. {
  93. m_Unknown->Release () ;
  94. }
  95. }
  96. /******************************************************************************
  97. *
  98. * Name:
  99. *
  100. *
  101. * Description:
  102. *
  103. *
  104. *****************************************************************************/
  105. STDMETHODIMP CCommon_IWbemSyncObjectSink :: QueryInterface (
  106. REFIID iid ,
  107. LPVOID FAR *iplpv
  108. )
  109. {
  110. *iplpv = NULL ;
  111. if ( iid == IID_IUnknown )
  112. {
  113. *iplpv = ( LPVOID ) this ;
  114. }
  115. else if ( iid == IID_IWbemObjectSink )
  116. {
  117. *iplpv = ( LPVOID ) ( IWbemObjectSink * ) this ;
  118. }
  119. else if ( iid == IID_IWbemShutdown )
  120. {
  121. *iplpv = ( LPVOID ) ( IWbemShutdown * ) this ;
  122. }
  123. if ( *iplpv )
  124. {
  125. ( ( LPUNKNOWN ) *iplpv )->AddRef () ;
  126. return ResultFromScode ( S_OK ) ;
  127. }
  128. else
  129. {
  130. return ResultFromScode ( E_NOINTERFACE ) ;
  131. }
  132. }
  133. /******************************************************************************
  134. *
  135. * Name:
  136. *
  137. *
  138. * Description:
  139. *
  140. *
  141. *****************************************************************************/
  142. STDMETHODIMP_(ULONG) CCommon_IWbemSyncObjectSink :: AddRef ( void )
  143. {
  144. return ObjectSinkContainerElement :: AddRef () ;
  145. }
  146. /******************************************************************************
  147. *
  148. * Name:
  149. *
  150. *
  151. * Description:
  152. *
  153. *
  154. *****************************************************************************/
  155. STDMETHODIMP_(ULONG) CCommon_IWbemSyncObjectSink :: Release ( void )
  156. {
  157. return ObjectSinkContainerElement :: Release () ;
  158. }
  159. /******************************************************************************
  160. *
  161. * Name:
  162. *
  163. *
  164. * Description:
  165. *
  166. *
  167. *****************************************************************************/
  168. HRESULT CCommon_IWbemSyncObjectSink :: SinkInitialize ()
  169. {
  170. HRESULT t_Result = S_OK ;
  171. return t_Result ;
  172. }
  173. /******************************************************************************
  174. *
  175. * Name:
  176. *
  177. *
  178. * Description:
  179. *
  180. *
  181. *****************************************************************************/
  182. HRESULT CCommon_IWbemSyncObjectSink :: Indicate (
  183. long a_ObjectCount ,
  184. IWbemClassObject **a_ObjectArray
  185. )
  186. {
  187. HRESULT t_Result = S_OK ;
  188. InterlockedGuard ig(&m_InProgress);
  189. if ( m_GateClosed )
  190. {
  191. t_Result = WBEM_E_SHUTTING_DOWN ;
  192. }
  193. else
  194. {
  195. t_Result = Helper_Indicate (
  196. a_ObjectCount ,
  197. a_ObjectArray
  198. ) ;
  199. #ifdef DBG
  200. if ( FAILED ( t_Result ) )
  201. {
  202. DbgPrintfA(0,"CCommon_IWbemSyncObjectSink :: Indicate - %08x",t_Result) ;
  203. }
  204. #endif
  205. }
  206. return t_Result ;
  207. }
  208. /******************************************************************************
  209. *
  210. * Name:
  211. *
  212. *
  213. * Description:
  214. *
  215. *
  216. *****************************************************************************/
  217. HRESULT CCommon_IWbemSyncObjectSink :: Helper_Indicate (
  218. long a_ObjectCount ,
  219. IWbemClassObject **a_ObjectArray
  220. )
  221. {
  222. HRESULT t_Result = m_InterceptedSink->Indicate (
  223. a_ObjectCount ,
  224. a_ObjectArray
  225. ) ;
  226. return t_Result ;
  227. }
  228. /******************************************************************************
  229. *
  230. * Name:
  231. *
  232. *
  233. * Description:
  234. *
  235. *
  236. *****************************************************************************/
  237. HRESULT CCommon_IWbemSyncObjectSink :: Helper_SetStatus (
  238. long a_Flags ,
  239. HRESULT a_Result ,
  240. BSTR a_StringParam ,
  241. IWbemClassObject *a_ObjectParam
  242. )
  243. {
  244. HRESULT t_Result = S_OK ;
  245. BSTR t_StringParam = NULL ;
  246. if ( a_StringParam )
  247. {
  248. t_StringParam = SysAllocString ( a_StringParam ) ;
  249. if ( t_StringParam == NULL )
  250. {
  251. t_Result = WBEM_E_OUT_OF_MEMORY ;
  252. }
  253. }
  254. if ( SUCCEEDED ( t_Result ) )
  255. {
  256. t_Result = m_InterceptedSink->SetStatus (
  257. a_Flags ,
  258. a_Result ,
  259. t_StringParam ,
  260. a_ObjectParam
  261. ) ;
  262. SysFreeString ( t_StringParam ) ;
  263. }
  264. return t_Result ;
  265. }
  266. /******************************************************************************
  267. *
  268. * Name:
  269. *
  270. *
  271. * Description:
  272. *
  273. *
  274. *****************************************************************************/
  275. HRESULT CCommon_IWbemSyncObjectSink :: SetStatus (
  276. long a_Flags ,
  277. HRESULT a_Result ,
  278. BSTR a_StringParam ,
  279. IWbemClassObject *a_ObjectParam
  280. )
  281. {
  282. HRESULT t_Result = S_OK ;
  283. InterlockedGuard ig(&m_InProgress);
  284. if ( m_GateClosed )
  285. {
  286. t_Result = WBEM_E_SHUTTING_DOWN ;
  287. }
  288. else
  289. {
  290. switch ( a_Flags )
  291. {
  292. case WBEM_STATUS_PROGRESS:
  293. {
  294. t_Result = Helper_SetStatus (
  295. a_Flags ,
  296. a_Result ,
  297. a_StringParam ,
  298. a_ObjectParam
  299. ) ;
  300. }
  301. break ;
  302. case WBEM_STATUS_COMPLETE:
  303. {
  304. if ( ! InterlockedCompareExchange ( & m_StatusCalled , 1 , 0 ) )
  305. {
  306. t_Result = Helper_SetStatus (
  307. a_Flags ,
  308. a_Result ,
  309. a_StringParam ,
  310. a_ObjectParam
  311. ) ;
  312. }
  313. }
  314. break ;
  315. default:
  316. {
  317. t_Result = WBEM_E_INVALID_PARAMETER ;
  318. }
  319. break ;
  320. }
  321. }
  322. return t_Result ;
  323. }
  324. /******************************************************************************
  325. *
  326. * Name:
  327. *
  328. *
  329. * Description:
  330. *
  331. *
  332. *****************************************************************************/
  333. HRESULT CCommon_IWbemSyncObjectSink :: Shutdown (
  334. LONG a_Flags ,
  335. ULONG a_MaxMilliSeconds ,
  336. IWbemContext *a_Context
  337. )
  338. {
  339. HRESULT t_Result = S_OK ;
  340. InterlockedIncrement ( & m_GateClosed ) ;
  341. if ( ! InterlockedCompareExchange ( & m_StatusCalled , 1 , 0 ) )
  342. {
  343. t_Result = Helper_SetStatus (
  344. 0 ,
  345. WBEM_E_SHUTTING_DOWN ,
  346. NULL ,
  347. NULL
  348. ) ;
  349. }
  350. bool t_Acquired = false ;
  351. while ( ! t_Acquired )
  352. {
  353. if ( m_InProgress == 0 )
  354. {
  355. t_Acquired = true ;
  356. break ;
  357. }
  358. if ( SwitchToThread () == FALSE )
  359. {
  360. }
  361. }
  362. return t_Result ;
  363. }
  364. /******************************************************************************
  365. *
  366. * Name:
  367. *
  368. *
  369. * Description:
  370. *
  371. *
  372. *****************************************************************************/
  373. #pragma warning( disable : 4355 )
  374. CCommon_Batching_IWbemSyncObjectSink :: CCommon_Batching_IWbemSyncObjectSink (
  375. WmiAllocator &a_Allocator ,
  376. IWbemObjectSink *a_InterceptedSink ,
  377. IUnknown *a_Unknown ,
  378. CWbemGlobal_IWmiObjectSinkController *a_Controller ,
  379. ULONG a_Dependant
  380. ) : CCommon_IWbemSyncObjectSink (
  381. a_Allocator ,
  382. a_InterceptedSink ,
  383. a_Unknown ,
  384. a_Controller ,
  385. a_Dependant
  386. ) ,
  387. m_Queue ( a_Allocator ) ,
  388. m_Size ( 0 ),
  389. m_CriticalSection(NOTHROW_LOCK)
  390. {
  391. }
  392. #pragma warning( default : 4355 )
  393. /******************************************************************************
  394. *
  395. * Name:
  396. *
  397. *
  398. * Description:
  399. *
  400. *
  401. *****************************************************************************/
  402. CCommon_Batching_IWbemSyncObjectSink :: ~CCommon_Batching_IWbemSyncObjectSink ()
  403. {
  404. ULONG t_Count = m_Queue.Size();
  405. for ( ULONG t_Index = 0 ; t_Index < t_Count ; t_Index ++ )
  406. {
  407. IWbemClassObject *t_ClassObject ;
  408. WmiStatusCode t_StatusCode = m_Queue.Top ( t_ClassObject ) ;
  409. if ( t_StatusCode == e_StatusCode_Success )
  410. {
  411. t_ClassObject->Release () ;
  412. t_StatusCode = m_Queue.DeQueue () ;
  413. }
  414. }
  415. m_Queue.UnInitialize () ;
  416. WmiHelper :: DeleteCriticalSection ( & m_CriticalSection );
  417. }
  418. /******************************************************************************
  419. *
  420. * Name:
  421. *
  422. *
  423. * Description:
  424. *
  425. *
  426. *****************************************************************************/
  427. HRESULT CCommon_Batching_IWbemSyncObjectSink :: SinkInitialize ()
  428. {
  429. HRESULT t_Result = CCommon_IWbemSyncObjectSink :: SinkInitialize () ;
  430. if ( SUCCEEDED ( t_Result ) )
  431. {
  432. WmiStatusCode t_StatusCode = WmiHelper :: InitializeCriticalSection ( & m_CriticalSection );
  433. if ( t_StatusCode == e_StatusCode_Success )
  434. {
  435. t_StatusCode = m_Queue.Initialize () ;
  436. if ( t_StatusCode == e_StatusCode_Success )
  437. {
  438. }
  439. else
  440. {
  441. t_Result = WBEM_E_OUT_OF_MEMORY ;
  442. }
  443. }
  444. else
  445. {
  446. t_Result = WBEM_E_OUT_OF_MEMORY ;
  447. }
  448. }
  449. return t_Result ;
  450. }
  451. class CReleaseMe
  452. {
  453. private:
  454. IUnknown * m_pUnk;
  455. public:
  456. CReleaseMe(IUnknown * pUnk):m_pUnk(pUnk){};
  457. ~CReleaseMe(){ m_pUnk->Release(); };
  458. };
  459. /******************************************************************************
  460. *
  461. * Name:
  462. *
  463. *
  464. * Description:
  465. *
  466. *
  467. *****************************************************************************/
  468. HRESULT CCommon_Batching_IWbemSyncObjectSink :: Indicate (
  469. long a_ObjectCount ,
  470. IWbemClassObject **a_ObjectArray
  471. )
  472. {
  473. HRESULT t_Result = S_OK ;
  474. if ( m_GateClosed == 0 )
  475. {
  476. WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection ( & m_CriticalSection , FALSE ) ;
  477. if ( t_StatusCode == e_StatusCode_Success )
  478. {
  479. for ( LONG t_Index = 0 ; SUCCEEDED ( t_Result ) && ( t_Index < a_ObjectCount ) ; t_Index ++ )
  480. {
  481. if ( a_ObjectArray [ t_Index ] )
  482. {
  483. IWbemClassObject *t_ClonedObject = NULL ;
  484. t_Result = a_ObjectArray [ t_Index ]->Clone ( &t_ClonedObject ) ;
  485. if ( SUCCEEDED ( t_Result ) )
  486. {
  487. CReleaseMe rmCloned(t_ClonedObject);
  488. ULONG t_ObjectSize = 0 ;
  489. _IWmiObject *t_Object ;
  490. HRESULT t_TempResult = t_ClonedObject->QueryInterface ( IID__IWmiObject , ( void ** ) & t_Object ) ;
  491. if ( SUCCEEDED ( t_TempResult ) )
  492. {
  493. CReleaseMe rmQIed(t_Object);
  494. t_TempResult = t_Object->GetObjectMemory (
  495. NULL ,
  496. 0 ,
  497. & t_ObjectSize
  498. );
  499. if ( t_TempResult == WBEM_E_BUFFER_TOO_SMALL )
  500. {
  501. WmiStatusCode t_StatusCode = m_Queue.EnQueue ( t_ClonedObject ) ;
  502. if ( t_StatusCode == e_StatusCode_Success )
  503. {
  504. t_ClonedObject ->AddRef();
  505. m_Size = m_Size + t_ObjectSize ;
  506. }
  507. else
  508. {
  509. t_Result = WBEM_E_OUT_OF_MEMORY ;
  510. }
  511. if ( SUCCEEDED(t_Result) &&
  512. (( m_Size ) >= ProviderSubSystem_Common_Globals :: GetTransmitSize () ))
  513. {
  514. ULONG t_Count = m_Queue.Size () ;
  515. IWbemClassObject **t_Array = new IWbemClassObject * [ t_Count ] ;
  516. if ( t_Array )
  517. {
  518. IWbemClassObject *t_ClassObject ;
  519. WmiStatusCode t_StatusCode ;
  520. ULONG t_InnerIndex = 0 ;
  521. while ( ( t_StatusCode = m_Queue.Top ( t_ClassObject ) ) == e_StatusCode_Success )
  522. {
  523. t_Array [ t_InnerIndex ] = t_ClassObject ;
  524. t_InnerIndex ++ ;
  525. t_StatusCode = m_Queue.DeQueue() ;
  526. }
  527. m_Size = 0 ;
  528. WmiHelper :: LeaveCriticalSection ( & m_CriticalSection ) ;
  529. t_Result = CCommon_IWbemSyncObjectSink :: Indicate ( t_Count , t_Array ) ;
  530. for ( t_InnerIndex = 0 ; t_InnerIndex < t_Count ; t_InnerIndex ++ )
  531. {
  532. t_Array [ t_InnerIndex ]->Release () ;
  533. }
  534. delete [] t_Array ;
  535. t_StatusCode = WmiHelper :: EnterCriticalSection ( & m_CriticalSection , FALSE ) ;
  536. if ( t_StatusCode == e_StatusCode_Success )
  537. {
  538. }
  539. else
  540. {
  541. t_Result = WBEM_E_OUT_OF_MEMORY ;
  542. }
  543. }
  544. else
  545. {
  546. t_Result = WBEM_E_OUT_OF_MEMORY ;
  547. }
  548. }
  549. }
  550. else
  551. {
  552. t_Result = WBEM_E_CRITICAL_ERROR ;
  553. }
  554. }
  555. else
  556. {
  557. t_Result = WBEM_E_CRITICAL_ERROR ;
  558. }
  559. }
  560. }
  561. }
  562. WmiHelper :: LeaveCriticalSection ( & m_CriticalSection );
  563. return t_Result ;
  564. }
  565. else
  566. {
  567. return WBEM_E_OUT_OF_MEMORY ;
  568. }
  569. }
  570. else
  571. {
  572. return WBEM_E_SHUTTING_DOWN ;
  573. }
  574. }
  575. /******************************************************************************
  576. *
  577. * Name:
  578. *
  579. *
  580. * Description:
  581. *
  582. *
  583. *****************************************************************************/
  584. HRESULT CCommon_Batching_IWbemSyncObjectSink :: SetStatus (
  585. long a_Flags ,
  586. HRESULT a_Result ,
  587. BSTR a_StringParam ,
  588. IWbemClassObject *a_ObjectParam
  589. )
  590. {
  591. HRESULT t_Result = S_OK ;
  592. switch ( a_Flags )
  593. {
  594. case WBEM_STATUS_COMPLETE:
  595. {
  596. if ( m_GateClosed == 0 )
  597. {
  598. WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection ( & m_CriticalSection , FALSE );
  599. if ( t_StatusCode == e_StatusCode_Success )
  600. {
  601. LONG t_Count = m_Queue.Size () ;
  602. if ( t_Count )
  603. {
  604. IWbemClassObject **t_Array = new IWbemClassObject * [ m_Queue.Size () ] ;
  605. if ( t_Array )
  606. {
  607. for ( LONG t_Index = 0 ; t_Index < t_Count ; t_Index ++ )
  608. {
  609. IWbemClassObject *t_ClassObject ;
  610. WmiStatusCode t_StatusCode = m_Queue.Top ( t_ClassObject ) ;
  611. if ( t_StatusCode == e_StatusCode_Success )
  612. {
  613. t_Array [ t_Index ] = t_ClassObject ;
  614. t_StatusCode = m_Queue.DeQueue () ;
  615. }
  616. }
  617. WmiHelper :: LeaveCriticalSection ( & m_CriticalSection );
  618. t_Result = CCommon_IWbemSyncObjectSink :: Indicate ( t_Count , t_Array ) ;
  619. for ( t_Index = 0 ; t_Index < t_Count ; t_Index ++ )
  620. {
  621. if ( t_Array [ t_Index ] )
  622. {
  623. t_Array [ t_Index ]->Release () ;
  624. }
  625. }
  626. delete [] t_Array ;
  627. }
  628. else
  629. {
  630. WmiHelper :: LeaveCriticalSection ( & m_CriticalSection );
  631. t_Result = WBEM_E_OUT_OF_MEMORY ;
  632. }
  633. }
  634. else
  635. {
  636. WmiHelper :: LeaveCriticalSection ( & m_CriticalSection );
  637. }
  638. }
  639. else
  640. {
  641. t_Result = WBEM_E_OUT_OF_MEMORY ;
  642. }
  643. }
  644. if ( FAILED ( t_Result ) )
  645. {
  646. a_Result = t_Result ;
  647. }
  648. t_Result = CCommon_IWbemSyncObjectSink :: SetStatus (
  649. a_Flags ,
  650. a_Result ,
  651. a_StringParam ,
  652. a_ObjectParam
  653. ) ;
  654. }
  655. break ;
  656. default:
  657. {
  658. t_Result = CCommon_IWbemSyncObjectSink :: SetStatus (
  659. a_Flags ,
  660. a_Result ,
  661. a_StringParam ,
  662. a_ObjectParam
  663. ) ;
  664. }
  665. break ;
  666. }
  667. return t_Result ;
  668. }