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.

604 lines
21 KiB

  1. /*++
  2. Copyright (C) 2000-2001 Microsoft Corporation
  3. Module Name:
  4. WmiFinalizer2
  5. Abstract:
  6. Implementation of the finalizer. The finalizer if the class which
  7. delivers the resultant objects back to the client. It could do
  8. that sychronously or asynchronously.
  9. History:
  10. paulall 27-Mar-2000 Created.
  11. marioh 20-Aug-2000 Batching capabilities added
  12. marioh 17-Oct-2000 Major updates completed
  13. --*/
  14. #include <flexarry.h>
  15. #include <wbemcore.h>
  16. #ifndef __FINALIZER__
  17. #define __FINALIZER__
  18. #define DEFAULT_BATCH_TRANSMIT_BYTES 0x40000 // 128K, Max batching size to deliver on one indicate call
  19. #define MAX_SINGLE_OBJECT_SIZE 0x200000 // Max single object size
  20. #define ABANDON_PROXY_THRESHOLD 60000 // Max proxy timeout [60secs]
  21. #define MAX_BUFFER_SIZE_BEFORE_SLOWDOWN 0x400000 // Max size of queue before slowdown of inbound flow
  22. #define LOWER_AUTH_LEVEL_NOTSET 0xFFFFFFFF
  23. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  24. // Finalizer constructor exceptions
  25. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  26. class CWmiFinalizerEnumerator;
  27. class CWmiFinalizerInboundSink;
  28. class CWmiFinalizerEnumeratorSink;
  29. class CWmiFinalizerCallResult;
  30. class CWmiFinalizer ;
  31. class CWmiFinalizerObj
  32. {
  33. public:
  34. IWbemClassObject *m_pObj;
  35. enum ObjectType {
  36. unknown,
  37. object,
  38. status,
  39. shutdown,
  40. set
  41. } m_objectType;
  42. BSTR m_bStr;
  43. HRESULT m_hRes;
  44. HRESULT m_hArb ;
  45. void* m_pvObj;
  46. _IWmiFinalizer* m_pFin ;
  47. IID m_iid;
  48. ULONG m_uSize;
  49. ULONG m_lFlags;
  50. CWmiFinalizerObj(ObjectType objType) : m_pObj(NULL), m_objectType(objType), m_lFlags(0), m_bStr(NULL), m_hRes(0), m_pvObj(0), m_uSize(0), m_pFin ( NULL ), m_hArb ( WBEM_S_ARB_NOTHROTTLING ) {}
  51. CWmiFinalizerObj(IWbemClassObject *pObj, _IWmiFinalizer* pFin ) ;
  52. CWmiFinalizerObj(ULONG lFlags, REFIID riid, void *pvObj) ;
  53. CWmiFinalizerObj(ULONG lFlags, HRESULT hRes, BSTR bStr, IWbemClassObject *pObj) ;
  54. CWmiFinalizerObj(CWmiFinalizerObj& obj);
  55. virtual ~CWmiFinalizerObj();
  56. };
  57. struct InsertableEvent
  58. {
  59. LIST_ENTRY m_Entry;
  60. CWmiFinalizerEnumerator * pEnum;
  61. DWORD ThreadId;
  62. };
  63. class CWmiFinalizer : public _IWmiFinalizer,
  64. public _IWmiArbitratee,
  65. public IWbemShutdown
  66. {
  67. private:
  68. LONG m_lRefCount; // External/client refcount
  69. LONG m_lInternalRefCount; // Internal refcount
  70. public:
  71. enum QueueStatus {
  72. NoError,
  73. RequestReleased,
  74. CallCancelled,
  75. QuotaViolation,
  76. QueueFailure
  77. };
  78. private:
  79. QueueStatus m_hStatus; // Status once thread is woken up from PullObjects
  80. BOOL m_bSetStatusEnqueued; // We've recieved and enqueued the setstatus (COMPLETE)
  81. BOOL m_bSetStatusWithError; // SetStatus called with error
  82. BOOL m_bTaskInitialized ; // Has SetTaskHandle been called?
  83. BOOL m_bClonedFinalizer ; // Is this a cloned finalizer?
  84. BOOL m_bSetStatusDelivered ; // Has the setstatus been delivered?
  85. ULONG m_ulOperationType; // Sync/Semisync/Async
  86. ULONG m_ulSemisyncWakeupCall; // For semisync operations, once number of objects on the queue reaches this, wake up client
  87. IWbemClassObject** m_apAsyncDeliveryBuffer; // Used during async deliveries for batching objects together
  88. ULONG m_ulAsyncDeliveryCount; // Used during async deliveries for the number of objects to deliver in one batch
  89. ULONG m_ulAsyncDeliverySize; // Async deliver size
  90. LONG m_lCurrentlyDelivering; // Are we in the process of already delivering the batch
  91. LONG m_lCurrentlyCancelling; // Special case for cancellations
  92. enum {
  93. forwarding_type_none = 0,
  94. forwarding_type_fast = 1, //Use pass through mechanism
  95. forwarding_type_decoupled = 2 //Pass off to another thread for delivery
  96. } m_uForwardingType;
  97. enum {
  98. FinalizerBatch_StatusMsg = 0,
  99. FinalizerBatch_BufferOverFlow = 1,
  100. FinalizerBatch_NoError = 2
  101. } m_enumBatchStatus;
  102. enum {
  103. PauseInboundDelivery = 0,
  104. ResumeInboundDelivery = 1,
  105. };
  106. enum {
  107. Operation_Type_Async = 0,
  108. Operation_Type_Semisync = 1,
  109. Operation_Type_Sync = 2
  110. };
  111. _IWmiCoreHandle *m_phTask; // Task associated with this finalizer
  112. _IWmiArbitrator *m_pArbitrator; // Access to arbitrator to help keep control of system
  113. IID m_iidDestSink; // Client destination sink with async deliveries [IID]
  114. IWbemObjectSink *m_pDestSink; // Client destination sink with async deliveries
  115. CFlexArray m_inboundSinks; // Array of inbound sinks [not sure we need safe array since we only support one inbound sink]
  116. CFlexArray m_objects; // Object queue. All objects are inserted into this array [except async fasttrack]
  117. CFlexArray m_enumerators ; // All enumerators associated with this finalizer (cloning)
  118. HRESULT m_hresFinalResult; // Final result of operation
  119. CWmiFinalizerCallResult *m_pCallResult; // CallResult
  120. bool m_bSetStatusCalled; // Has anyone called setstatus yet?
  121. CCritSec m_destCS; // Protects the destination sink
  122. CCritSec m_arbitratorCS; // Protects the arbitrator
  123. bool m_bRestartable; // Is the enumerator restartable
  124. bool m_bSetStatusConsumed; // Have we finished the operation?
  125. LONG m_lMemoryConsumption ; // Control for checking memory consumption
  126. ULONG m_ulStatus; // Status used to determine what woke a client from PullObjects
  127. ULONG m_uCurObjectPosition; // Keeps a current object position in object queue for restartable purposes
  128. HANDLE m_hResultReceived;
  129. HANDLE m_hCancelEvent; // Threads that are waiting on objects will wake up in case of cancelled operation
  130. HANDLE m_hWaitForSetStatus ;
  131. ULONG m_ulQueueSize; // Total current object queue size
  132. LONG m_bCancelledCall; // Has the call been cancelled?
  133. BOOL m_bNaughtyClient; // Did we stop delivering due to client being naughty?
  134. protected:
  135. static DWORD WINAPI ThreadBootstrap ( PVOID pvContext );
  136. static VOID WINAPI ProxyThreshold ( PVOID pvContext, BOOLEAN bTimerOrWait );
  137. HRESULT BootstrapDeliveryThread ( );
  138. VOID ProxyThresholdImp ( );
  139. ULONG AsyncDeliveryProcessor();
  140. HRESULT TriggerShutdown();
  141. HRESULT ShutdownFinalizer();
  142. HRESULT DeliverPushObject(bool bDoPassthrough);
  143. HRESULT QueueOperation(CWmiFinalizerObj *pObj);
  144. HRESULT DequeueObject(CWmiFinalizerObj **ppObj, CWmiFinalizerEnumerator* pEnum );
  145. HRESULT BuildTransmitBuffer ( );
  146. HRESULT DeliverSingleObjFromQueue ( );
  147. HRESULT DeliverBatch ( );
  148. HRESULT CancelCall();
  149. HRESULT CancelCall( int Line ){m_LineCancelCall = Line; return CancelCall(); };
  150. VOID ZeroAsyncDeliveryBuffer ( );
  151. public:
  152. CWmiFinalizer(CCoreServices *pSrvs);
  153. ~CWmiFinalizer();
  154. STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID FAR* ppvObj);
  155. STDMETHOD_(ULONG, AddRef)(THIS);
  156. STDMETHOD_(ULONG, Release)(THIS);
  157. STDMETHOD_(ULONG, InternalAddRef)(THIS);
  158. STDMETHOD_(ULONG, InternalRelease)(THIS);
  159. void CallBackRelease () ;
  160. STDMETHOD(Configure)(
  161. /*[in]*/ ULONG uConfigID,
  162. /*[in]*/ ULONG uValue
  163. );
  164. // Allows decoupled & fast-track configuration with no thread switches
  165. STDMETHOD(SetTaskHandle)(
  166. /*[in]*/ _IWmiCoreHandle *phTask
  167. );
  168. // Task handle has user-specific stuff. Finalizer just
  169. // passes this through to _IWmiArbitrator::CheckTask
  170. STDMETHOD(SetDestinationSink)(
  171. /*[in]*/ ULONG uFlags,
  172. /*[in]*/ REFIID riid,
  173. /*[in], iid_is(riid)]*/ LPVOID pSink
  174. );
  175. // For async operations
  176. STDMETHOD(SetSelfDestructCallback)(
  177. /*[in]*/ ULONG uFlags,
  178. /*[in]*/ IWbemObjectSink *pSink
  179. );
  180. // The callback called during final Release(); Set() is called with the task handle, followed by SetStatus()
  181. //
  182. STDMETHOD(GetStatus)(
  183. /*[out]*/ ULONG* pFlags
  184. );
  185. STDMETHOD(NewInboundSink)(
  186. /*[in]*/ ULONG uFlags,
  187. /*[out]*/ IWbemObjectSink **pSink
  188. );
  189. STDMETHOD(Merge)(
  190. /*[in]*/ ULONG uFlags,
  191. /*[in]*/ REFIID riid,
  192. /*[in]*/ LPVOID pObj
  193. );
  194. // Allows merging another Finalizer, _IWmiCache, etc.
  195. // For sorting, we will create a sorted _IWmiCache and merge it in later when
  196. // the sort is completed.
  197. // For setting, getting objects
  198. STDMETHOD(SetResultObject)(
  199. /*[in]*/ ULONG uFlags,
  200. /*[in]*/ REFIID riid,
  201. /*[in]*/ LPVOID pObj
  202. );
  203. STDMETHOD(GetResultObject)(
  204. /*[in]*/ ULONG uFlags,
  205. /*[in]*/ REFIID riid,
  206. /*[out, iid_is(riid)]*/ LPVOID *pObj
  207. );
  208. // Support _IWmiObject, IWbemClassObject, etc.
  209. // IEnumWbemClassObject
  210. // _IWmiCache
  211. // For status-only operations
  212. STDMETHOD(SetOperationResult)(
  213. /*[in]*/ ULONG uFlags,
  214. /*[in]*/ HRESULT hRes
  215. );
  216. STDMETHOD(GetOperationResult)(
  217. /*[in]*/ ULONG uFlags,
  218. /*[in]*/ ULONG uTimeout,
  219. /*[out]*/ HRESULT *phRes
  220. );
  221. //Set status is called from the inbound sink to notify us of the status.
  222. //We will queue up the request and pass it on to the client if necessary
  223. HRESULT SetStatus(
  224. /*[in]*/ long lFlags,
  225. /*[in]*/ HRESULT hResult,
  226. /*[in]*/ BSTR strParam,
  227. /*[in]*/ IWbemClassObject* pObjParam
  228. );
  229. STDMETHOD(CancelTask) (
  230. /*[in]*/ ULONG uFlags
  231. );
  232. STDMETHOD(DumpDebugInfo) (
  233. /*[in]*/ ULONG uFlags,
  234. /*[in]*/ const BSTR fHandle
  235. );
  236. STDMETHOD(Shutdown)(
  237. /*[in]*/ LONG uReason,
  238. /*[in]*/ ULONG uMaxMilliseconds,
  239. /*[in]*/ IWbemContext *pCtx);
  240. //When the sink goes away, in the destructor, it will call back to unregister
  241. //itself. That way we know when they are all done. If they are all gone
  242. //we can send the status back to the client and we are all done!
  243. HRESULT GetFinalResult ( ) { return m_hresFinalResult ; }
  244. HRESULT CancelWaitHandle ( );
  245. HRESULT SetClientCancellationHandle ( HANDLE ) ;
  246. HRESULT NotifyClientOfCancelledCall ( ) ;
  247. BOOL IsValidDestinationSink ( ) ;
  248. HRESULT ReleaseDestinationSink ( ) ;
  249. HRESULT ReportMemoryUsage ( ULONG, LONG ) ;
  250. HRESULT CancelTaskInternal ( );
  251. HRESULT Reset ( ); // If there is an EnumClassObject calling Reset, it calls back into us...
  252. HRESULT SetSinkToIdentity ( IWbemObjectSink* ); // Waits until the timeout for a new object to arrive, or a shutdown state
  253. HRESULT WaitForCompletion ( ULONG uTimeout ); // Wait for the operition to complete.
  254. HRESULT NextAsync ( CWmiFinalizerEnumerator* pEnum );
  255. HRESULT Skip ( long lTimeout, ULONG nCount, CWmiFinalizerEnumerator* pEnum );
  256. HRESULT PullObjects ( long lTimeout, ULONG uCount, IWbemClassObject** apObjects, ULONG* puReturned, CWmiFinalizerEnumerator* pEnum, BOOL bAddToObjQueue=TRUE, BOOL bSetErrorObj=TRUE );
  257. HRESULT Set ( long lFlags, REFIID riid, void *pComObject );
  258. HRESULT Indicate ( long lObjectCount, IWbemClassObject** apObjArray );
  259. HRESULT UnregisterInboundSink( CWmiFinalizerInboundSink *pSink );
  260. HRESULT GetNextObject ( CWmiFinalizerObj **ppObj );
  261. HRESULT ZapWriteOnlyProps ( IWbemClassObject *pObj );
  262. BOOL HasWriteOnlyProps ( IWbemClassObject* pObj );
  263. HRESULT DoSetStatusCancel ( IWbemObjectSink * pSink, HRESULT lParam );
  264. HRESULT DoSetStatus ( IWbemObjectSink * psink, long lFlags, HRESULT lParam, BSTR strParam,
  265. IWbemClassObject* pObjParam, BOOL bAllowMultipleCalls = FALSE );
  266. HRESULT DoIndicate ( IWbemObjectSink * psink, int nBatchSize, IWbemClassObject **pBatch );
  267. HRESULT FinalizerLowerAuthLevel ( IWbemObjectSink * psink, DWORD* pdwLastAuthnLevel );
  268. IWbemObjectSink* ReturnProtectedDestinationSink ( );
  269. bool GetSetStatusConsumed ( ) { return m_bSetStatusConsumed; }
  270. bool IsRestartable ( void ) { return m_bRestartable; }
  271. LONG GetInternalStatus ( ) { return m_hStatus; }
  272. void SetInternalStatus ( QueueStatus lStatus ) { m_hStatus = lStatus; }
  273. ULONG GetObjectQueueSize ( ) { return m_objects.Size(); }
  274. LONG IsCallCancelled ( ) { return m_bCancelledCall; }
  275. VOID UpdateStatus ( ULONG ulFlags ) { m_ulStatus |= ulFlags; }
  276. VOID SetSemisyncWakeupCall ( ULONG ulNum ) { m_ulSemisyncWakeupCall = ulNum; }
  277. ULONG GetSemisyncWakeupCall ( ) { return m_ulSemisyncWakeupCall; }
  278. HRESULT NotifyAllEnumeratorsOfCompletion ( ) ;
  279. HRESULT UnregisterEnumerator ( CWmiFinalizerEnumerator* ) ;
  280. // Other public:
  281. static void Dump(FILE* f);
  282. CCritSec m_cs; // Protects the object queue
  283. int m_LineCancelCall;
  284. };
  285. //*****************************************************************************
  286. //**** ****
  287. //**** Private WmiFinalizer classes... ****
  288. //**** ****
  289. //*****************************************************************************
  290. class CWmiFinalizerInboundSink : public IWbemObjectSink
  291. {
  292. private:
  293. LONG m_lRefCount;
  294. LONG m_lInternalRefCount;
  295. CWmiFinalizer * m_pFinalizer;
  296. bool m_bSetStatusCalled;
  297. LIST_ENTRY m_Entry;
  298. public:
  299. CWmiFinalizerInboundSink(CWmiFinalizer *pFinalizer);
  300. ~CWmiFinalizerInboundSink();
  301. STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID FAR* ppvObj);
  302. STDMETHOD_(ULONG, AddRef)(THIS);
  303. STDMETHOD_(ULONG, Release)(THIS);
  304. STDMETHOD_(ULONG, InternalAddRef)(THIS);
  305. STDMETHOD_(ULONG, InternalRelease)(THIS);
  306. void CallBackRelease () ;
  307. STDMETHOD(Indicate)(
  308. /*[in]*/ long lObjectCount,
  309. /*[in, size_is(lObjectCount)]*/
  310. IWbemClassObject** apObjArray
  311. );
  312. STDMETHOD(SetStatus)(
  313. /*[in]*/ long lFlags,
  314. /*[in]*/ HRESULT hResult,
  315. /*[in]*/ BSTR strParam,
  316. /*[in]*/ IWbemClassObject* pObjParam
  317. );
  318. STDMETHOD(Set)(
  319. /*[in]*/ long lFlags,
  320. /*[in]*/ REFIID riid,
  321. /*[in, iid_is(riid)]*/ void *pComObject
  322. );
  323. };
  324. class CWmiFinalizerEnumerator : public IEnumWbemClassObject, IWbemFetchSmartEnum
  325. {
  326. private:
  327. LONG m_lRefCount;
  328. LONG m_lInternalRefCount;
  329. ULONG m_ulCount;
  330. HANDLE m_hSignalCompletion;
  331. CWmiFinalizer* m_pFinalizer;
  332. IServerSecurity* m_pSec;
  333. IWbemObjectSink* m_pDestSink;
  334. _IWbemEnumMarshaling* m_pEnumMarshal;
  335. CCritSec m_clientLock;
  336. CIdentitySecurity m_Security;
  337. LIST_ENTRY m_Entry;
  338. LIST_ENTRY m_HeadNextAsync;
  339. protected:
  340. // ============================
  341. // SMART ENUM!!!!!!!!!!!!!
  342. // ============================
  343. class XSmartEnum : public IWbemWCOSmartEnum
  344. {
  345. private:
  346. CWmiFinalizerEnumerator* m_pOuter;
  347. public:
  348. XSmartEnum( CWmiFinalizerEnumerator* pOuter ) : m_pOuter( pOuter ) {};
  349. ~XSmartEnum(){};
  350. STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID FAR* ppvObj);
  351. STDMETHOD_(ULONG, AddRef)(THIS);
  352. STDMETHOD_(ULONG, Release)(THIS);
  353. // IWbemWCOSmartEnum Methods
  354. STDMETHOD(Next)( REFGUID proxyGUID, LONG lTimeout,
  355. ULONG uCount, ULONG* puReturned, ULONG* pdwBuffSize,
  356. BYTE** pBuffer);
  357. } m_XSmartEnum;
  358. friend XSmartEnum;
  359. public:
  360. CWmiFinalizerEnumerator(CWmiFinalizer *pFinalizer);
  361. ~CWmiFinalizerEnumerator();
  362. void Add_NextAsync(InsertableEvent * pInsert);
  363. void Remove_NextAsync(InsertableEvent * pInsert);
  364. STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID FAR* ppvObj);
  365. STDMETHOD_(ULONG, AddRef)(THIS);
  366. STDMETHOD_(ULONG, Release)(THIS);
  367. STDMETHOD_(ULONG, InternalAddRef)(THIS);
  368. STDMETHOD_(ULONG, InternalRelease)(THIS);
  369. static DWORD WINAPI ThreadBootstrapNextAsync ( PVOID pvContext );
  370. void CallBackRelease();
  371. HRESULT _NextAsync();
  372. HRESULT SetCompletionSignalEvent(){ if ( m_hSignalCompletion ) SetEvent (m_hSignalCompletion); return WBEM_S_NO_ERROR; }
  373. IWbemObjectSink* GetDestSink(){ return m_pDestSink; }
  374. VOID NULLDestSink(){ m_pDestSink = NULL; }
  375. HRESULT ReleaseFinalizer(){ if ( m_pFinalizer ) m_pFinalizer->Release(); return WBEM_S_NO_ERROR; }
  376. // ============================
  377. // IEnumWbemClassObject methods
  378. // ============================
  379. STDMETHOD(Reset)();
  380. STDMETHOD(Next)(
  381. /*[in]*/ long lTimeout,
  382. /*[in]*/ ULONG uCount,
  383. /*[out, size_is(uCount), length_is(*puReturned)]*/ IWbemClassObject** apObjects,
  384. /*[out]*/ ULONG* puReturned
  385. );
  386. STDMETHOD(NextAsync)(
  387. /*[in]*/ ULONG uCount,
  388. /*[in]*/ IWbemObjectSink* pSink
  389. );
  390. STDMETHOD(Clone)(
  391. /*[out]*/ IEnumWbemClassObject** ppEnum
  392. );
  393. STDMETHOD(Skip)(
  394. /*[in]*/ long lTimeout,
  395. /*[in]*/ ULONG nCount
  396. );
  397. // ===========================
  398. // IWbemFetchSmartEnum methods
  399. // ===========================
  400. STDMETHOD (GetSmartEnum) (
  401. /*[out]*/ IWbemWCOSmartEnum** ppSmartEnum
  402. );
  403. BOOL HasSmartEnum(){ return (NULL != m_pEnumMarshal); };
  404. ULONG m_uCurObjectPosition ;
  405. HANDLE m_hWaitOnResultSet ;
  406. ULONG m_ulSemisyncWakeupCall;
  407. BOOL m_bSetStatusConsumed ;
  408. };
  409. class CWmiFinalizerCallResult : IWbemCallResult
  410. {
  411. private:
  412. LONG m_lInternalRefCount;
  413. LONG m_lRefCount;
  414. CWmiFinalizer *m_pFinalizer;
  415. long m_lFlags;
  416. HRESULT m_hResult;
  417. BSTR m_strParam;
  418. IWbemClassObject *m_pObj;
  419. IWbemClassObject *m_pErrorObj;
  420. IWbemServices *m_pServices;
  421. bool m_bGotObject;
  422. bool m_bGotServices;
  423. CIdentitySecurity m_Security;
  424. LIST_ENTRY m_Entry;
  425. public:
  426. CWmiFinalizerCallResult(CWmiFinalizer *pFinalizer);
  427. ~CWmiFinalizerCallResult();
  428. STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID FAR* ppvObj);
  429. STDMETHOD_(ULONG, AddRef)(THIS);
  430. STDMETHOD_(ULONG, Release)(THIS);
  431. STDMETHOD_(ULONG, InternalAddRef)(THIS);
  432. STDMETHOD_(ULONG, InternalRelease)(THIS);
  433. STDMETHOD(GetResultObject)(
  434. /*[in]*/ long lTimeout,
  435. /*[out]*/ IWbemClassObject** ppResultObject
  436. );
  437. STDMETHOD(GetResultString)(
  438. /*[in]*/ long lTimeout,
  439. /*[out]*/ BSTR* pstrResultString
  440. );
  441. STDMETHOD(GetResultServices)(
  442. /*[in]*/ long lTimeout,
  443. /*[out]*/ IWbemServices** ppServices
  444. );
  445. STDMETHOD(GetCallStatus)(
  446. /*[in]*/ long lTimeout,
  447. /*[out]*/ long* plStatus
  448. );
  449. STDMETHOD(GetResult)(
  450. /*[in]*/ long lTimeout,
  451. /*[in]*/ long lFlags,
  452. /*[in]*/ REFIID riid,
  453. /*[out, iid_is(riid)]*/ void **ppvResult
  454. );
  455. HRESULT SetStatus(
  456. /*[in]*/ long lFlags,
  457. /*[in]*/ HRESULT hResult,
  458. /*[in]*/ BSTR strParam,
  459. /*[in]*/ IWbemClassObject* pObjParam
  460. );
  461. void SetErrorInfo();
  462. };
  463. #endif