1233 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1233 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| //***************************************************************************
 | |
| //
 | |
| //  WMITASK.CPP
 | |
| //
 | |
| //  raymcc  23-Apr-00       First oversimplified draft for Whistler
 | |
| //
 | |
| //***************************************************************************
 | |
| #include "precomp.h"
 | |
| 
 | |
| #include <windows.h>
 | |
| #include <stdio.h>
 | |
| #include <wbemcore.h>
 | |
| #include <wmiarbitrator.h>
 | |
| #include <wmifinalizer.h>
 | |
| #include <context.h>
 | |
| 
 | |
| static ULONG g_uNextTaskId = 1;
 | |
| static LONG  g_uTaskCount = 0;
 | |
| 
 | |
| #ifdef DBG
 | |
|   #define __DBG_TASK
 | |
| #endif
 | |
| 
 | |
| extern ULONG g_ulClientCallbackTimeout ;
 | |
| 
 | |
| //#define TASK_DETAIL_TRACKING
 | |
| 
 | |
| 
 | |
| //***************************************************************************
 | |
| //
 | |
| //***************************************************************************
 | |
| 
 | |
| CCritSec CWmiTask::m_TaskCs;
 | |
| 
 | |
| CWmiTask* CWmiTask::CreateTask ( )
 | |
| {
 | |
| 	return new CWmiTask ( ) ;
 | |
| }
 | |
| 
 | |
| //***************************************************************************
 | |
| //
 | |
| //***************************************************************************
 | |
| 
 | |
| CWmiTask::CWmiTask ( )
 | |
| {
 | |
| 	m_hResult = WBEM_E_CALL_CANCELLED ;
 | |
| 	m_uRefCount = 1;
 | |
|     m_uTaskType = 0;
 | |
|     m_uTaskStatus = 0;
 | |
|     m_uStartTime = 0;
 | |
|     m_uUpdateTime = 0;
 | |
|     m_uTaskId = InterlockedIncrement((LONG *) &g_uNextTaskId);
 | |
|     InterlockedIncrement((LONG *)&g_uTaskCount);
 | |
|     m_pUser = 0;
 | |
|     m_pNs = 0;
 | |
|     m_pAsyncClientSink = 0;
 | |
|     m_pWorkingFnz = 0;
 | |
|     m_pReqSink = 0;
 | |
|     m_uMemoryUsage = 0;
 | |
|     m_uTotalSleepTime = 0;
 | |
|     m_uCancelState = FALSE;
 | |
|     m_uLastSleepTime = 0;
 | |
|     m_hTimer = NULL;
 | |
|     m_pMainCtx = 0;
 | |
| 	m_hCompletion = NULL ;
 | |
| 	m_bReqSinkInitialized = FALSE ;
 | |
| 	m_bAccountedForThrottling = FALSE ;
 | |
| 	m_bCancelledDueToThrottling = FALSE ;
 | |
| 
 | |
| }
 | |
| 
 | |
| //***************************************************************************
 | |
| //
 | |
| //  CWmiTask::~CWmiTask
 | |
| //
 | |
| //***************************************************************************
 | |
| //
 | |
| CWmiTask::~CWmiTask()
 | |
| {
 | |
|     int i;
 | |
| 
 | |
|     CCheckedInCritSec _cs ( &m_csTask );
 | |
| 
 | |
| 	if ( m_pUser )
 | |
| 	{
 | |
| 		_cs.Leave ( ) ;
 | |
| 		m_pUser->Release ( ) ;
 | |
| 		_cs.Enter ( ) ;
 | |
| 		m_pUser = NULL ;
 | |
| 	}
 | |
| 
 | |
| 	if ( m_pNs )
 | |
| 	{
 | |
| 		_cs.Leave ( ) ;
 | |
| 		m_pNs->Release ( ) ;
 | |
| 		_cs.Enter ( ) ;
 | |
| 		m_pNs = NULL ;
 | |
| 	}
 | |
| 
 | |
| 	if ( m_pAsyncClientSink )
 | |
| 	{
 | |
| 		_cs.Leave ( ) ;
 | |
| 		m_pAsyncClientSink->Release ( ) ;
 | |
| 		_cs.Enter ( ) ;
 | |
| 		m_pAsyncClientSink = NULL ;
 | |
| 	}
 | |
| 
 | |
| 	if ( m_pReqSink )
 | |
| 	{
 | |
| 		_cs.Leave ( ) ;
 | |
| 		m_pReqSink->Release ( ) ;
 | |
| 		_cs.Enter ( ) ;
 | |
| 		m_pReqSink = NULL ;
 | |
| 	}
 | |
| 
 | |
| 	if ( m_pMainCtx )
 | |
| 	{
 | |
| 		_cs.Leave ( ) ;
 | |
| 		m_pMainCtx->Release ( ) ;
 | |
| 		_cs.Enter ( ) ;
 | |
| 		m_pMainCtx = NULL ;
 | |
| 	}
 | |
| 
 | |
|     // Release all provider/sink bindings.
 | |
|     // ===================================
 | |
| 
 | |
|     for (i = 0; i < m_aTaskProviders.Size(); i++)
 | |
|     {
 | |
|         STaskProvider *pTP = (STaskProvider *) m_aTaskProviders[i];
 | |
|         if (pTP)
 | |
|             delete pTP;
 | |
|     }
 | |
| 
 | |
|     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
|     // Release all Arbitratees
 | |
|     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| 	ReleaseArbitratees ( ) ;
 | |
|     
 | |
|     InterlockedDecrement((LONG *)&g_uTaskCount);
 | |
| 
 | |
| 	if ( m_hTimer )
 | |
| 	{
 | |
| 		CloseHandle ( m_hTimer );
 | |
| 		m_hTimer = NULL ;
 | |
| 	}
 | |
| 
 | |
| 	if ( m_hCompletion )
 | |
| 	{
 | |
| 		CloseHandle ( m_hCompletion ) ;
 | |
| 		m_hCompletion = NULL ;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| /*
 | |
|     * =============================================================================
 | |
| 	|
 | |
| 	| HRESULT CWmiTask::SignalCancellation ( )
 | |
| 	| ----------------------------------------
 | |
| 	| 
 | |
| 	| Signals the task to be cancelled
 | |
| 	|
 | |
| 	|
 | |
| 	* =============================================================================
 | |
| */
 | |
| 
 | |
| HRESULT CWmiTask::SignalCancellation ( )
 | |
| {
 | |
| 	HRESULT hRes = WBEM_S_NO_ERROR ;	
 | |
| 
 | |
| 	{
 | |
| 		CInCritSec _cs ( &m_csTask );
 | |
| 	
 | |
| 		if ( ( m_uTaskStatus != WMICORE_TASK_STATUS_CANCELLED ) && ( m_hTimer != NULL ) )
 | |
| 		{
 | |
| 			SetEvent ( m_hTimer ) ;
 | |
| 		}
 | |
| 	}
 | |
| 	return hRes ;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| /*
 | |
|     * =============================================================================
 | |
| 	|
 | |
| 	| HRESULT CWmiTask::SetTaskResult ( HRESULT hRes ) 
 | |
| 	| -------------------------------------------------
 | |
| 	| 
 | |
| 	| Sets the task result
 | |
| 	|
 | |
| 	|
 | |
| 	* =============================================================================
 | |
| */
 | |
| 
 | |
| HRESULT CWmiTask::SetTaskResult ( HRESULT hResult ) 
 | |
| {
 | |
| 	HRESULT hRes = WBEM_S_NO_ERROR ;
 | |
| 
 | |
| 	m_hResult = hResult ;
 | |
| 	return hRes ;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|     * =============================================================================
 | |
| 	|
 | |
| 	| HRESULT CWmiTask::UpdateMemoryUsage ( LONG lDelta )
 | |
| 	| ---------------------------------------------------
 | |
| 	| 
 | |
| 	| Updates the task memory usage
 | |
| 	|
 | |
| 	|
 | |
| 	* =============================================================================
 | |
| */
 | |
| 
 | |
| HRESULT CWmiTask::UpdateMemoryUsage ( LONG lDelta )
 | |
| {
 | |
| 	CInCritSec _cs ( &m_csTask );
 | |
| 
 | |
| 	m_uMemoryUsage += lDelta ;
 | |
| 
 | |
| 	return WBEM_S_NO_ERROR;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| /*
 | |
|     * =============================================================================
 | |
| 	|
 | |
| 	| HRESULT CWmiTask::UpdateTotalSleepTime ( ULONG uSleepTime )
 | |
| 	| -----------------------------------------------------------
 | |
| 	| 
 | |
| 	| Updates the tasks sleep time
 | |
| 	|
 | |
| 	|
 | |
| 	* =============================================================================
 | |
| */
 | |
| 
 | |
| HRESULT CWmiTask::UpdateTotalSleepTime ( ULONG uSleepTime )
 | |
| {
 | |
| 	CInCritSec _cs ( &m_csTask );
 | |
| 
 | |
| 	m_uTotalSleepTime += uSleepTime ;
 | |
| 	return WBEM_S_NO_ERROR;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| /*
 | |
|     * =============================================================================
 | |
| 	|
 | |
| 	| HRESULT CWmiTask::ReleaseArbitratees ( )
 | |
| 	| ----------------------------------------
 | |
| 	| 
 | |
| 	| Releases all the arbitratees (Finalizer, Merger currently)
 | |
| 	|
 | |
| 	| 
 | |
| 	|
 | |
| 	| 
 | |
| 	|
 | |
| 	* =============================================================================
 | |
| */
 | |
| 
 | |
| HRESULT CWmiTask::ReleaseArbitratees ( )
 | |
| {
 | |
| 	HRESULT hRes = WBEM_S_NO_ERROR ;
 | |
| 
 | |
| 	CInCritSec _cs ( &m_csTask );
 | |
| 
 | |
|     for (ULONG i = 0; i < m_aArbitratees.Size(); i++)
 | |
|     {
 | |
|         _IWmiArbitratee *pArbee = NULL ;
 | |
| 		pArbee = (_IWmiArbitratee*) m_aArbitratees[i];
 | |
|         if ( pArbee )
 | |
|         {
 | |
|             pArbee->Release ( );
 | |
|         }
 | |
|     }
 | |
| 	m_aArbitratees.Empty ( ) ;
 | |
| 	
 | |
| 	return hRes ;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| //***************************************************************************
 | |
| //
 | |
| //***************************************************************************
 | |
| HRESULT CWmiTask::SetRequestSink(CStdSink *pReqSink)
 | |
| {
 | |
|     if (pReqSink == 0)
 | |
|         return WBEM_E_INVALID_PARAMETER;
 | |
|     if (m_pReqSink != 0)
 | |
|         return WBEM_E_INVALID_OPERATION;
 | |
| 
 | |
|     CInCritSec _cs ( &m_csTask );
 | |
|     pReqSink->AddRef ( ) ;
 | |
|     m_pReqSink = pReqSink;
 | |
| 
 | |
| 	m_bReqSinkInitialized = TRUE ;
 | |
|     return WBEM_S_NO_ERROR;
 | |
| }
 | |
| 
 | |
| //***************************************************************************
 | |
| //
 | |
| //***************************************************************************
 | |
| // *
 | |
| ULONG CWmiTask::AddRef()
 | |
| {
 | |
|     InterlockedIncrement((LONG *) &m_uRefCount);
 | |
|     return m_uRefCount;
 | |
| }
 | |
| 
 | |
| //***************************************************************************
 | |
| //
 | |
| //***************************************************************************
 | |
| // *
 | |
| ULONG CWmiTask::Release()
 | |
| {
 | |
|     ULONG uNewCount = InterlockedDecrement((LONG *) &m_uRefCount);
 | |
|     if (0 != uNewCount)
 | |
|         return uNewCount;
 | |
|     delete this;
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| //***************************************************************************
 | |
| //
 | |
| //***************************************************************************
 | |
| // *
 | |
| HRESULT CWmiTask::QueryInterface(
 | |
|     IN REFIID riid,
 | |
|     OUT LPVOID *ppvObj
 | |
|     )
 | |
| {
 | |
|     *ppvObj = 0;
 | |
| 
 | |
|     if (IID_IUnknown==riid || IID__IWmiCoreHandle==riid)
 | |
|     {
 | |
|         *ppvObj = (_IWmiCoreHandle *)this;
 | |
|         AddRef();
 | |
|         return S_OK;
 | |
|     }
 | |
| 
 | |
|     return E_NOINTERFACE;
 | |
| }
 | |
| 
 | |
| 
 | |
| //***************************************************************************
 | |
| //
 | |
| //***************************************************************************
 | |
| // *
 | |
| HRESULT CWmiTask::GetHandleType(
 | |
|     ULONG *puType
 | |
|     )
 | |
| {
 | |
|     *puType = WMI_HANDLE_TASK;
 | |
|     return WBEM_S_NO_ERROR;
 | |
| }
 | |
| 
 | |
| //***************************************************************************
 | |
| //
 | |
| //***************************************************************************
 | |
| // *
 | |
| HRESULT CWmiTask::Initialize(
 | |
|     IN CWbemNamespace *pNs,
 | |
|     IN ULONG uTaskType,
 | |
|     IN IWbemContext *pCtx,
 | |
|     IN IWbemObjectSink *pAsyncClientSinkCopy
 | |
|     )
 | |
| {
 | |
|     HRESULT hRes;
 | |
| 
 | |
|     if (pNs == 0 || pCtx == 0)
 | |
|         return WBEM_E_INVALID_PARAMETER;
 | |
| 
 | |
|     m_pNs = pNs;
 | |
|     m_pNs->AddRef();
 | |
| 
 | |
|     m_uTaskType = uTaskType;
 | |
|     m_uStartTime = GetCurrentTime();
 | |
| 
 | |
|     // See if the task is primary or not.
 | |
|     // ==================================
 | |
| /*
 | |
|     if (pCtx)
 | |
|     {
 | |
|         IWbemCausalityAccess* pCA = NULL;
 | |
|         pCtx->QueryInterface(IID_IWbemCausalityAccess, (void**)&pCA);
 | |
|         if (pCA)
 | |
|         {
 | |
|             REQUESTID id;
 | |
|             hRes = pCA->GetParentId(&id);
 | |
|             if (hRes == S_FALSE)
 | |
|                 m_uTaskType |= WMICORE_TASK_TYPE_PRIMARY;
 | |
|             else
 | |
|                 m_uTaskType |= WMICORE_TASK_TYPE_DEPENDENT;
 | |
|             pCA->Release();
 | |
|         }
 | |
|         else
 | |
|             m_uTaskType |= WMICORE_TASK_TYPE_PRIMARY;
 | |
| 
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         m_uTaskType |= WMICORE_TASK_TYPE_PRIMARY;
 | |
|     }
 | |
| */
 | |
|     if (pCtx)
 | |
|     {
 | |
|         CWbemContext *pContext = (CWbemContext *) pCtx;
 | |
| 
 | |
|         GUID ParentId = GUID_NULL, RequestId = GUID_NULL;
 | |
|         LONG lNumParents = 0;
 | |
|         LONG lNumChildren = 0;
 | |
| 
 | |
|         pContext->GetParentId(&ParentId);
 | |
|         pContext->GetRequestId(&RequestId);
 | |
|         pContext->GetHistoryInfo(&lNumParents, &lNumChildren);
 | |
| 
 | |
|         if (ParentId != GUID_NULL)
 | |
|         {
 | |
|             m_uTaskType |= WMICORE_TASK_TYPE_DEPENDENT;
 | |
|         }
 | |
|         else
 | |
|             m_uTaskType |= WMICORE_TASK_TYPE_PRIMARY;
 | |
| 
 | |
|         m_pMainCtx = (CWbemContext *) pCtx;
 | |
|         m_pMainCtx->AddRef();
 | |
|     }
 | |
|     else
 | |
|     {
 | |
| 		// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 		// If we dont have a context check to see if the namespace is an ESS or Provider
 | |
| 		// initialized namespace, if so, set the task type to dependent.
 | |
| 		// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 		if ( pNs->GetIsESS ( ) || pNs->GetIsProvider ( ) )
 | |
| 		{
 | |
| 			m_uTaskType |= WMICORE_TASK_TYPE_DEPENDENT;
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			m_uTaskType |= WMICORE_TASK_TYPE_PRIMARY;
 | |
| 		}
 | |
|     }
 | |
| 
 | |
| 
 | |
|     if ((uTaskType & WMICORE_TASK_TYPE_ASYNC) && pAsyncClientSinkCopy)
 | |
|     {
 | |
|         m_pAsyncClientSink = pAsyncClientSinkCopy;
 | |
|         m_pAsyncClientSink->AddRef();
 | |
|     }
 | |
|     else
 | |
|         m_pAsyncClientSink = 0;
 | |
| 
 | |
| 
 | |
|     // Register this task with Arbitrator.
 | |
|     // ====================================
 | |
| 
 | |
|     _IWmiArbitrator *pArb = CWmiArbitrator::GetUnrefedArbitrator();
 | |
|     if (!pArb)
 | |
|         return WBEM_E_CRITICAL_ERROR;
 | |
| 
 | |
|     hRes = pArb->RegisterTask(this);
 | |
|     if (FAILED(hRes))
 | |
|         return hRes;
 | |
| 
 | |
|     return WBEM_S_NO_ERROR;
 | |
| }
 | |
| 
 | |
| //***************************************************************************
 | |
| //
 | |
| //***************************************************************************
 | |
| //
 | |
| HRESULT CWmiTask::SetFinalizer(_IWmiFinalizer *pFnz)
 | |
| {
 | |
|     if (pFnz == 0)
 | |
|         return WBEM_E_INVALID_PARAMETER;
 | |
| 
 | |
|     if (m_pWorkingFnz)
 | |
|         return WBEM_E_INVALID_OPERATION;
 | |
| 
 | |
|     m_pWorkingFnz = pFnz;
 | |
|     m_pWorkingFnz->AddRef();
 | |
| 
 | |
|     return WBEM_S_NO_ERROR;
 | |
| }
 | |
| 
 | |
| 
 | |
| //***************************************************************************
 | |
| //
 | |
| //***************************************************************************
 | |
| //
 | |
| HRESULT CWmiTask::GetFinalizer(_IWmiFinalizer **ppFnz)
 | |
| {
 | |
| 
 | |
| 	CInCritSec	ics( &m_csTask );
 | |
| 
 | |
| 	for ( int x = 0; x < m_aArbitratees.Size(); x++ )
 | |
| 	{
 | |
| 		_IWmiArbitratee*	pArbitratee = (_IWmiArbitratee*) m_aArbitratees[x];
 | |
| 
 | |
| 		if ( SUCCEEDED( pArbitratee->QueryInterface( IID__IWmiFinalizer, (void**) ppFnz ) ) )
 | |
| 		{
 | |
| 			break;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
|     return ( x < m_aArbitratees.Size() ? WBEM_S_NO_ERROR : WBEM_E_NOT_FOUND );
 | |
| }
 | |
| 
 | |
| 
 | |
| //***************************************************************************
 | |
| //
 | |
| //***************************************************************************
 | |
| //
 | |
| HRESULT CWmiTask::AddArbitratee( ULONG uFlags, _IWmiArbitratee* pArbitratee )
 | |
| {
 | |
|     HRESULT hRes = WBEM_S_NO_ERROR;
 | |
| 
 | |
|     if (pArbitratee == 0)
 | |
|         return WBEM_E_INVALID_PARAMETER;
 | |
| 
 | |
|     int nRes = CFlexArray::no_error;
 | |
|     {
 | |
|         CInCritSec _cs ( &m_csTask );
 | |
|         nRes = m_aArbitratees.Add (pArbitratee);
 | |
|     }
 | |
| 
 | |
|     if ( nRes != CFlexArray::no_error )
 | |
|     {
 | |
|         hRes = WBEM_E_OUT_OF_MEMORY;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         pArbitratee->AddRef();
 | |
|     }
 | |
| 
 | |
| 
 | |
|     return hRes;
 | |
| }
 | |
| 
 | |
| 
 | |
| //***************************************************************************
 | |
| //
 | |
| //***************************************************************************
 | |
| //
 | |
| HRESULT CWmiTask::RemoveArbitratee( ULONG uFlags, _IWmiArbitratee* pArbitratee )
 | |
| {
 | |
|     HRESULT hRes = WBEM_E_FAILED;
 | |
| 
 | |
|     if (pArbitratee == 0)
 | |
|         return WBEM_E_INVALID_PARAMETER;
 | |
| 
 | |
|     CInCritSec _cs ( &m_csTask );
 | |
|     for (int i = 0; i < m_aArbitratees.Size(); i++)
 | |
|     {
 | |
|         _IWmiArbitratee *pArbee = (_IWmiArbitratee*) m_aArbitratees[i];
 | |
| 
 | |
|         if (pArbee == pArbitratee)
 | |
|         {
 | |
|             m_aArbitratees.RemoveAt(i);
 | |
|             pArbee->Release();
 | |
|             hRes = WBEM_S_NO_ERROR;
 | |
|             break;
 | |
|         }
 | |
|     }
 | |
|     return hRes;
 | |
| }
 | |
| 
 | |
| //***************************************************************************
 | |
| //
 | |
| //***************************************************************************
 | |
| //
 | |
| HRESULT CWmiTask::GetArbitratedQuery( ULONG uFlags, _IWmiArbitratedQuery** ppArbitratedQuery )
 | |
| {
 | |
|     HRESULT hRes = E_NOINTERFACE;
 | |
| 
 | |
|     if (ppArbitratedQuery == 0)
 | |
|         return WBEM_E_INVALID_PARAMETER;
 | |
| 
 | |
|     {
 | |
|         CInCritSec _cs ( &m_csTask );
 | |
| 
 | |
| 		for ( int x = 0; FAILED( hRes ) && x < m_aArbitratees.Size(); x++ )
 | |
| 		{
 | |
| 			_IWmiArbitratee* pArb = (_IWmiArbitratee*) m_aArbitratees[x];
 | |
| 
 | |
| 			if ( NULL != pArb )
 | |
| 			{
 | |
| 				hRes = pArb->QueryInterface( IID__IWmiArbitratedQuery, (void**) ppArbitratedQuery );
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
|     }
 | |
| 
 | |
|     return hRes;
 | |
| }
 | |
| 
 | |
| 
 | |
| //***************************************************************************
 | |
| //
 | |
| //***************************************************************************
 | |
| HRESULT CWmiTask::GetPrimaryTask ( _IWmiCoreHandle** pPTask )
 | |
| {
 | |
|     HRESULT hRes = WBEM_S_NO_ERROR;
 | |
| 
 | |
|     if ( pPTask == NULL )
 | |
|     {
 | |
|         hRes = WBEM_E_INVALID_PARAMETER;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         *pPTask = (_IWmiCoreHandle*) this;
 | |
|     }
 | |
|     return hRes;
 | |
| }
 | |
| 
 | |
| 
 | |
| //***************************************************************************
 | |
| //
 | |
| //***************************************************************************
 | |
| //
 | |
| HRESULT CWmiTask::Cancel( HRESULT hResParam )
 | |
| {
 | |
|     HRESULT hRes = WBEM_S_NO_ERROR;
 | |
| 
 | |
| 	BOOL bCancelled = FALSE ;
 | |
| 
 | |
| 	// We'll want one of these in order to track statuses from all plausible locations if
 | |
| 	// we are performing a client originated cancel
 | |
| 	CStatusSink*	pStatusSink = NULL;
 | |
| 	
 | |
| 	if ( hResParam == WMIARB_CALL_CANCELLED_CLIENT )
 | |
| 	{
 | |
| 		pStatusSink = new CStatusSink;
 | |
| 
 | |
| 		if ( NULL == pStatusSink )
 | |
| 		{
 | |
| 			return WBEM_E_OUT_OF_MEMORY;
 | |
| 		}
 | |
| 
 | |
| 	}	// IF Client originated the call
 | |
| 
 | |
| 	// Auto Release
 | |
| 	CReleaseMe	rmStatusSink( pStatusSink );
 | |
| 
 | |
|     {
 | |
| 		CCheckedInCritSec _cs ( &m_csTask );
 | |
| 		if (m_uTaskStatus == WMICORE_TASK_STATUS_CANCELLED)
 | |
| 		{
 | |
| 			return WBEM_S_NO_ERROR; // Prevent reentrancy
 | |
| 		}
 | |
| 		m_uTaskStatus = WMICORE_TASK_STATUS_CANCELLED;
 | |
| 	}
 | |
| 
 | |
|     // Change this to an async scheduled request
 | |
|     // ==========================================
 | |
| 
 | |
|     if (CORE_TASK_TYPE(m_uTaskType) == WMICORE_TASK_EXEC_NOTIFICATION_QUERY)
 | |
|     {
 | |
|         CAsyncReq_RemoveNotifySink *pReq = new
 | |
|             CAsyncReq_RemoveNotifySink(m_pReqSink, pStatusSink);
 | |
|         if (!pReq)
 | |
| 		{
 | |
| 			return WBEM_E_OUT_OF_MEMORY;
 | |
| 		}
 | |
| 		else if ( NULL != pReq->GetContext() )
 | |
| 		{
 | |
| 
 | |
| 			pReq->SetForceRun ( 1 ) ;
 | |
| 
 | |
| 			// If we have a status sink, then we should wait until the operation
 | |
| 			// completes before continuing so we can get the proper status from the
 | |
| 			// sink.
 | |
| 			if ( NULL != pStatusSink )
 | |
| 			{
 | |
| 				hRes = ConfigMgr::EnqueueRequestAndWait(pReq);
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				hRes = ConfigMgr::EnqueueRequest(pReq);
 | |
| 			}
 | |
| 			bCancelled = TRUE ;
 | |
| 
 | |
| 		}	// ELSEIF NULL != pReq->GetContext()
 | |
| 		else
 | |
| 		{
 | |
| 			delete pReq;
 | |
| 			return WBEM_E_OUT_OF_MEMORY;
 | |
| 		}
 | |
|     }
 | |
| 
 | |
|     // If here, a normal task.  Loop through any providers and stop them.
 | |
|     // ==================================================================
 | |
| 	CFlexArray	aTempProviders;
 | |
| 
 | |
| 	// This could change while we're accessing, so do this in a critsec
 | |
| 	{
 | |
| 		CInCritSec	ics( &m_csTask );
 | |
| 
 | |
| 		for (int i = 0; SUCCEEDED( hRes ) && i < m_aTaskProviders.Size(); i++)
 | |
| 		{
 | |
| 			if ( aTempProviders.Add( m_aTaskProviders[i] ) != CFlexArray::no_error )
 | |
| 			{
 | |
| 				hRes = WBEM_E_OUT_OF_MEMORY;
 | |
| 			}
 | |
| 		}	// FOR i= 0;
 | |
| 
 | |
| 	}	// SCOPED critsec
 | |
| 
 | |
| 	// Cancel what we've got
 | |
| 	for (int i = 0; i < aTempProviders.Size(); i++)
 | |
| 	{
 | |
| 		STaskProvider *pTP = (STaskProvider *) aTempProviders[i];
 | |
| 		if (pTP)
 | |
| 		{
 | |
| 			pTP->Cancel( pStatusSink );
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 
 | |
|  	CStdSink* pTempSink = NULL;
 | |
|     {
 | |
|         CInCritSec _cs ( &m_csTask );
 | |
|         if (m_pReqSink)
 | |
|         {
 | |
|             pTempSink = m_pReqSink;
 | |
|             pTempSink->AddRef ( );
 | |
|             m_pReqSink->Release ( );
 | |
|             m_pReqSink = 0;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if ( pTempSink )
 | |
|     {
 | |
|         pTempSink->Cancel();
 | |
|         pTempSink->Release();
 | |
|     }
 | |
| 
 | |
|     // 
 | |
|     // Loop through all arbitratees and set the operation result to cancelled
 | |
|     // 
 | |
| 	if ( SUCCEEDED ( hRes ) )
 | |
| 	{
 | |
| 		if ( bCancelled == FALSE )
 | |
| 		{
 | |
| 			if ( !m_hCompletion && hResParam == WMIARB_CALL_CANCELLED_CLIENT )
 | |
| 			{
 | |
| 				m_hCompletion = CreateEvent ( NULL, TRUE, FALSE, NULL ) ;
 | |
| 				if ( m_hCompletion == NULL )
 | |
| 				{
 | |
| 					hRes = WBEM_E_OUT_OF_MEMORY ;
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			_IWmiFinalizer* pFinalizer = NULL ;
 | |
| 			if ( SUCCEEDED ( hRes ) )
 | |
| 			{
 | |
| 				if ( m_hCompletion && hResParam == WMIARB_CALL_CANCELLED_CLIENT )
 | |
| 				{
 | |
| 					//
 | |
| 					// We need the finalizer to set the client wakeup event
 | |
| 					// 
 | |
| 					hRes = GetFinalizer ( &pFinalizer ) ;
 | |
| 					if ( FAILED (hRes) )
 | |
| 					{
 | |
| 						hRes = WBEM_E_FAILED ;
 | |
| 					}
 | |
| 					else
 | |
| 					{
 | |
| 						((CWmiFinalizer*)pFinalizer)->SetClientCancellationHandle ( m_hCompletion ) ;
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 			CReleaseMe FinalizerRelease ( pFinalizer ) ;
 | |
| 
 | |
| 			//
 | |
| 			// only enter wait state if we successfully created and set the client wait event
 | |
| 			//
 | |
| 			if ( SUCCEEDED ( hRes ) )
 | |
| 			{
 | |
| 				if ( hResParam == WMIARB_CALL_CANCELLED_CLIENT || hResParam == WMIARB_CALL_CANCELLED_THROTTLING )
 | |
| 				{
 | |
| 					hRes = SetArbitrateesOperationResult ( 0, WBEM_E_CALL_CANCELLED_CLIENT ) ;
 | |
| 				}
 | |
| 				else
 | |
| 				{
 | |
| 					hRes = SetArbitrateesOperationResult ( 0, m_hResult ) ;
 | |
| 				}
 | |
| 				
 | |
| 				if ( m_hCompletion && hResParam == WMIARB_CALL_CANCELLED_CLIENT )
 | |
| 				{
 | |
| 					if ( ((CWmiFinalizer*)pFinalizer)->IsValidDestinationSink ( ) )
 | |
| 					{
 | |
| 						DWORD dwRet = CCoreQueue::QueueWaitForSingleObject ( m_hCompletion, g_ulClientCallbackTimeout ) ;
 | |
| 						if (dwRet == WAIT_TIMEOUT)
 | |
| 						{
 | |
| 							hRes = WBEM_S_TIMEDOUT ;
 | |
| 						}
 | |
| 					}
 | |
| 					
 | |
| 					((CWmiFinalizer*)pFinalizer)->CancelWaitHandle ( ) ;
 | |
| 			
 | |
| 					if ( m_hCompletion )
 | |
| 					{
 | |
| 						CloseHandle ( m_hCompletion ) ;
 | |
| 						m_hCompletion = NULL ;
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 
 | |
| 	//
 | |
| 	// We're done, get the final status from the status sink if we have one.
 | |
| 	//
 | |
| 	if ( NULL != pStatusSink )
 | |
| 	{
 | |
| 		hRes = pStatusSink->GetLastStatus();
 | |
| 	}
 | |
| 
 | |
| 	ReleaseArbitratees ( ) ;
 | |
| 	return hRes ;
 | |
| }
 | |
| 
 | |
| 
 | |
| //***************************************************************************
 | |
| //
 | |
| //***************************************************************************
 | |
| //
 | |
| STaskProvider::~STaskProvider()
 | |
| {
 | |
|     if (m_pProvSink)
 | |
|         m_pProvSink->LocalRelease();
 | |
|     ReleaseIfNotNULL(m_pProv);
 | |
| }
 | |
| 
 | |
| 
 | |
| //***************************************************************************
 | |
| //
 | |
| //***************************************************************************
 | |
| //
 | |
| HRESULT STaskProvider::Cancel( CStatusSink* pStatusSink )
 | |
| {
 | |
| 	HRESULT hRes = WBEM_S_NO_ERROR ;
 | |
|     IWbemServices   *pTmpProv = 0;
 | |
|     CProviderSink   *pTmpProvSink = 0;
 | |
| 
 | |
|     EnterCriticalSection(&CWmiTask::m_TaskCs);
 | |
|         if (m_pProv != 0)
 | |
|         {
 | |
|             pTmpProv = m_pProv;
 | |
|             m_pProv = 0;
 | |
|         }
 | |
|         if (m_pProvSink != 0)
 | |
|         {
 | |
|             pTmpProvSink = m_pProvSink;
 | |
|             m_pProvSink = 0;
 | |
|         }
 | |
|     LeaveCriticalSection(&CWmiTask::m_TaskCs);
 | |
| 
 | |
|     if (pTmpProvSink)
 | |
|     {
 | |
|         pTmpProvSink->Cancel();
 | |
|     }
 | |
| 
 | |
|     if (pTmpProv)
 | |
|     {
 | |
| 		hRes = ExecCancelOnNewRequest ( pTmpProv, pTmpProvSink, pStatusSink ) ;
 | |
|     }
 | |
| 
 | |
|     ReleaseIfNotNULL(pTmpProv);
 | |
|     ReleaseIfNotNULL(pTmpProvSink);
 | |
| 
 | |
|     return hRes ;
 | |
| }
 | |
| 
 | |
| // //////////////////////////////////////////////////////////////////////////////////////////
 | |
| //
 | |
| // Used when issuing CancelAsyncCall to providers associtated with the task.
 | |
| // Rather than calling CancelAsynCall directly on the provider, we create a brand
 | |
| // new request and execute it on a different thread. We do this to avoid hangs, since
 | |
| // PSS is waiting the Indicate/SetStatus call to return before servicing the CancelCallAsync.
 | |
| //
 | |
| // //////////////////////////////////////////////////////////////////////////////////////////
 | |
| HRESULT STaskProvider::ExecCancelOnNewRequest ( IWbemServices* pProv, CProviderSink* pSink, CStatusSink* pStatusSink )
 | |
| {
 | |
| 	HRESULT hRes = WBEM_S_NO_ERROR ;
 | |
| 
 | |
| 	//
 | |
| 	// Sanity check on params
 | |
| 	//
 | |
| 	if ( pSink == NULL )
 | |
| 	{
 | |
| 		hRes = WBEM_E_INVALID_PARAMETER ;
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
|         //
 | |
| 		// Create new request
 | |
| 		//
 | |
| 		CAsyncReq_CancelProvAsyncCall* pReq = new CAsyncReq_CancelProvAsyncCall ( pProv, pSink, pStatusSink ) ;
 | |
| 
 | |
|         if ( pReq == NULL )
 | |
|         {
 | |
|             hRes = WBEM_E_OUT_OF_MEMORY ;
 | |
|         }
 | |
| 		else if ( NULL != pReq->GetContext() )
 | |
| 		{
 | |
| 			pReq->SetForceRun ( 1 ) ;
 | |
| 			//
 | |
| 			// Enqueue the request
 | |
| 			//
 | |
| 
 | |
| 			// If we have a status sink, then we should wait until the operation
 | |
| 			// completes before continuing so we can get the proper status from the
 | |
| 			// sink.
 | |
| 			if ( NULL != pStatusSink )
 | |
| 			{
 | |
| 				hRes = ConfigMgr::EnqueueRequestAndWait(pReq);
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				hRes = ConfigMgr::EnqueueRequest(pReq);
 | |
| 			}
 | |
| 
 | |
| 			if ( FAILED ( hRes ) )
 | |
| 			{
 | |
| 				delete pReq ;
 | |
| 			}
 | |
| 		}	// ELSEIF pReq->GetContext() == NULL
 | |
| 		else
 | |
| 		{
 | |
| 			delete pReq;
 | |
|             hRes = WBEM_E_OUT_OF_MEMORY ;
 | |
| 		}
 | |
| 	}
 | |
| 	return hRes ;
 | |
| }
 | |
| 
 | |
| //***************************************************************************
 | |
| //
 | |
| //***************************************************************************
 | |
| //
 | |
| BOOL CWmiTask::IsESSNamespace ( )
 | |
| {
 | |
|     BOOL bRet = FALSE;
 | |
| 
 | |
|     if ( m_pNs )
 | |
|     {
 | |
|         bRet = m_pNs->GetIsESS ( );
 | |
|     }
 | |
| 
 | |
|     return bRet;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| //***************************************************************************
 | |
| //
 | |
| //***************************************************************************
 | |
| //
 | |
| BOOL CWmiTask::IsProviderNamespace ( )
 | |
| {
 | |
|     BOOL bRet = FALSE;
 | |
| 
 | |
|     if ( m_pNs )
 | |
|     {
 | |
|         bRet = m_pNs->GetIsProvider ( );
 | |
|     }
 | |
| 
 | |
|     return bRet;
 | |
| }
 | |
| 
 | |
| //***************************************************************************
 | |
| //
 | |
| //***************************************************************************
 | |
| //
 | |
| HRESULT CWmiTask::AddTaskProv(STaskProvider *p)
 | |
| {
 | |
| 	CInCritSec	ics( &m_csTask );
 | |
| 
 | |
| 	// There is a race condition in which the task could get cancelled just as we
 | |
| 	// are executing. In this case, the task status will indicate that it has been
 | |
| 	// cancelled, so we should not add it to the task providers list.
 | |
| 
 | |
|     if (m_uTaskStatus == WMICORE_TASK_STATUS_CANCELLED)
 | |
|         return WBEM_E_CALL_CANCELLED; // Prevent reentrancy
 | |
| 
 | |
|     int nRes = m_aTaskProviders.Add(p);
 | |
|     if (nRes)
 | |
|         return WBEM_E_OUT_OF_MEMORY;
 | |
|     return WBEM_S_NO_ERROR;
 | |
| }
 | |
| 
 | |
| //***************************************************************************
 | |
| //
 | |
| //***************************************************************************
 | |
| //
 | |
| HRESULT CWmiTask::HasMatchingSink(void *Test, IN REFIID riid)
 | |
| {
 | |
|     if (LPVOID(m_pAsyncClientSink) == LPVOID(Test))
 | |
|         return WBEM_S_NO_ERROR;
 | |
|     return WBEM_E_NOT_FOUND;
 | |
| }
 | |
| 
 | |
| //***************************************************************************
 | |
| //
 | |
| //***************************************************************************
 | |
| //
 | |
| HRESULT CWmiTask::CreateTimerEvent ( )
 | |
| {
 | |
|     HRESULT hRes = WBEM_S_NO_ERROR;
 | |
| 
 | |
|     {
 | |
| 		CCheckedInCritSec _cs ( &m_csTask );
 | |
| 		if ( !m_hTimer )
 | |
| 		{
 | |
| 			m_hTimer = CreateEvent ( NULL, TRUE, FALSE, NULL );
 | |
| 			if ( !m_hTimer )
 | |
| 			{
 | |
| 				hRes = WBEM_E_OUT_OF_MEMORY;
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
|     return hRes;
 | |
| }
 | |
| 
 | |
| 
 | |
| //***************************************************************************
 | |
| //
 | |
| //***************************************************************************
 | |
| HRESULT CWmiTask::SetArbitrateesOperationResult ( ULONG lFlags, HRESULT hResult )
 | |
| {
 | |
|     HRESULT hRes = WBEM_S_NO_ERROR;
 | |
| 
 | |
|     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
|     // Set the operation result of all Arbitratees
 | |
|     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
|     CFlexArray aTmp;
 | |
|     {
 | |
|         // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
|         // First grab all the arbitratees and stick them into
 | |
|         // a temp array
 | |
|         // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
|         CInCritSec _cs ( &m_csTask );
 | |
|         for (int i = 0; i < m_aArbitratees.Size(); i++)
 | |
|         {
 | |
|             _IWmiArbitratee *pArbee = (_IWmiArbitratee*) m_aArbitratees[i];
 | |
| 
 | |
|             if ( pArbee )
 | |
|             {
 | |
|                 int nRes = aTmp.Add (pArbee);
 | |
|                 if ( nRes != CFlexArray::no_error )
 | |
|                 {
 | |
|                     hRes = WBEM_E_OUT_OF_MEMORY;
 | |
|                     break;
 | |
|                 }
 | |
|                 pArbee->AddRef ( );
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
| 
 | |
|     if ( SUCCEEDED (hRes) )
 | |
|     {
 | |
|         // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
|         // Clear to set the operation result without problems
 | |
|         // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
|         for (int i = 0; i < aTmp.Size(); i++)
 | |
|         {
 | |
|             _IWmiArbitratee *pArbee = (_IWmiArbitratee*) aTmp[i];
 | |
|             if ( pArbee )
 | |
|             {
 | |
|                 pArbee->SetOperationResult(lFlags, hResult );
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
|     // Now clean everything up
 | |
|     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
|     for (int i = 0; i < aTmp.Size(); i++)
 | |
|     {
 | |
|         _IWmiArbitratee *pArbee = (_IWmiArbitratee*) aTmp[i];
 | |
|         if ( pArbee )
 | |
|         {
 | |
|             pArbee->Release ( );
 | |
|         }
 | |
|     }
 | |
|     return hRes;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| //***************************************************************************
 | |
| //
 | |
| //***************************************************************************
 | |
| //
 | |
| HRESULT CWmiTask::Dump(FILE* f)
 | |
| {
 | |
|     fprintf(f, "---Task = 0x%p----------------------------\n", this);
 | |
|     fprintf(f, "    Refcount        = %d\n", m_uRefCount);
 | |
|     fprintf(f, "    TaskStatus      = %u\n ", m_uTaskStatus);
 | |
|     fprintf(f, "    Task ID         = %u\n", m_uTaskId);
 | |
| 
 | |
|     // Task status
 | |
|     char *p = "<none>";
 | |
|     switch(m_uTaskStatus)
 | |
|     {
 | |
|         case WMICORE_TASK_STATUS_NEW: p = "WMICORE_TASK_STATUS_NEW"; break;
 | |
|         case WMICORE_TASK_STATUS_VALIDATED: p = "WMICORE_TASK_STATUS_VALIDATED"; break;
 | |
|         case WMICORE_TASK_STATUS_SUSPENDED: p = "WMICORE_TASK_STATUS_SUSPENDED"; break;
 | |
|         case WMICORE_TASK_STATUS_EXECUTING: p = "WMICORE_TASK_STATUS_EXECUTING"; break;
 | |
|         case WMICORE_TASK_STATUS_WAITING_ON_SUBTASKS: p = "WMICORE_TASK_STATUS_WAITING_ON_SUBTASKS"; break;
 | |
|         case WMICORE_TASK_STATUS_TIMED_OUT: p = "WMICORE_TASK_STATUS_TIMED_OUT"; break;
 | |
|         case WMICORE_TASK_STATUS_CORE_COMPLETED: p = "WMICORE_TASK_STATUS_CORE_COMPLETED"; break;
 | |
|         case WMICORE_TASK_STATUS_CLIENT_COMPLETED: p = "WMICORE_TASK_STATUS_CLIENT_COMPLETED"; break;
 | |
|         case WMICORE_TASK_STATUS_CANCELLED: p = "WMICORE_TASK_STATUS_CANCELLED"; break;
 | |
|         case WMICORE_TASK_STATUS_FAILED: p = "WMICORE_TASK_STATUS_FAILED"; break;
 | |
|     };
 | |
| 
 | |
|     fprintf(f, " %s\n", p);
 | |
| 
 | |
|     // Task type
 | |
|     p = "<none>";
 | |
|     switch(m_uTaskType & 0xFF)
 | |
|     {
 | |
|         case WMICORE_TASK_NULL: p = "WMICORE_TASK_NULL"; break;
 | |
|         case WMICORE_TASK_GET_OBJECT: p = "WMICORE_TASK_GET_OBJECT"; break;
 | |
|         case WMICORE_TASK_GET_INSTANCE: p = "WMICORE_TASK_GET_INSTANCE"; break;
 | |
|         case WMICORE_TASK_PUT_INSTANCE: p = "WMICORE_TASK_PUT_INSTANCE"; break;
 | |
|         case WMICORE_TASK_DELETE_INSTANCE: p = "WMICORE_TASK_DELETE_INSTANCE"; break;
 | |
|         case WMICORE_TASK_ENUM_INSTANCES:  p = "WMICORE_TASK_ENUM_INSTANCES"; break;
 | |
|         case WMICORE_TASK_GET_CLASS:    p = "WMICORE_TASK_GET_CLASS"; break;
 | |
|         case WMICORE_TASK_PUT_CLASS:    p = "WMICORE_TASK_PUT_CLASS"; break;
 | |
|         case WMICORE_TASK_DELETE_CLASS: p = "WMICORE_TASK_DELETE_CLASS"; break;
 | |
|         case WMICORE_TASK_ENUM_CLASSES: p = "WMICORE_TASK_ENUM_CLASSES"; break;
 | |
|         case WMICORE_TASK_EXEC_QUERY:   p = "WMICORE_TASK_EXEC_QUERY"; break;
 | |
|         case WMICORE_TASK_EXEC_METHOD:  p = "WMICORE_TASK_EXEC_METHOD"; break;
 | |
|         case WMICORE_TASK_OPEN:         p = "WMICORE_TASK_OPEN"; break;
 | |
|         case WMICORE_TASK_OPEN_SCOPE:   p = "WMICORE_TASK_OPEN_SCOPE"; break;
 | |
|         case WMICORE_TASK_OPEN_NAMESPACE: p = "WMICORE_TASK_OPEN_NAMESPACE"; break;
 | |
|         case WMICORE_TASK_EXEC_NOTIFICATION_QUERY: p = "WMICORE_TASK_EXEC_NOTIFICATION_QUERY"; break;
 | |
|     }
 | |
| 
 | |
|     fprintf(f, "    TaskType = [0x%X] %s ", m_uTaskType, p);
 | |
| 
 | |
|     if (m_uTaskType & WMICORE_TASK_TYPE_SYNC)
 | |
|         fprintf(f,  " WMICORE_TASK_TYPE_SYNC");
 | |
| 
 | |
|     if (m_uTaskType & WMICORE_TASK_TYPE_SEMISYNC)
 | |
|         fprintf(f, " WMICORE_TASK_TYPE_SEMISYNC");
 | |
| 
 | |
|     if (m_uTaskType & WMICORE_TASK_TYPE_ASYNC)
 | |
|         fprintf(f, " WMICORE_TASK_TYPE_ASYNC");
 | |
| 
 | |
|     if (m_uTaskType & WMICORE_TASK_TYPE_PRIMARY)
 | |
|         fprintf(f, " WMICORE_TASK_TYPE_PRIMARY");
 | |
| 
 | |
|     if (m_uTaskType & WMICORE_TASK_TYPE_DEPENDENT)
 | |
|         fprintf(f, " WMICORE_TASK_TYPE_DEPENDENT");
 | |
| 
 | |
|     fprintf(f, "\n");
 | |
| 
 | |
|     fprintf(f, "    Task Log Info = %S\n", LPWSTR(m_sDebugInfo));
 | |
|     fprintf(f, "    AsyncClientSink = 0x%p\n", m_pAsyncClientSink);
 | |
|     fprintf(f, "    Finalizer = 0x%p\n", m_pWorkingFnz);
 | |
| 
 | |
| 	CCheckedInCritSec	ics( &m_csTask );
 | |
| 
 | |
|     for (int i = 0; i < m_aTaskProviders.Size(); i++)
 | |
|     {
 | |
|         STaskProvider *pTP = (STaskProvider *) m_aTaskProviders[i];
 | |
|         fprintf(f, "    Task Provider [0x%p] Prov=0x%p Sink=0x%p\n", this, pTP->m_pProv, pTP->m_pProvSink);
 | |
|     }
 | |
| 	
 | |
| 	ics.Leave();
 | |
| 
 | |
|     DWORD dwAge = GetCurrentTime() - m_uStartTime;
 | |
| 
 | |
|     fprintf(f, "    CWbemNamespace = 0x%p\n", m_pNs);
 | |
|     fprintf(f, "    Task age = %d milliseconds\n", dwAge);
 | |
|     fprintf(f, "    Task last sleep time = %d ms\n", m_uLastSleepTime );
 | |
| 
 | |
|     fprintf(f, "\n");
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| /*
 | |
| int __cdecl CWmiTask::printf(const char *fmt, ...)
 | |
| {
 | |
| #ifdef TASK_DETAIL_TRACKING
 | |
|     static CRITICAL_SECTION csPrintf;
 | |
|     static BOOL bInit = FALSE;
 | |
| 
 | |
|     if (bInit == FALSE)
 | |
|     {
 | |
|         InitializeCriticalSection(&csPrintf);
 | |
|         bInit = TRUE;
 | |
|     }
 | |
| 
 | |
|     const int nBufSize = 0x8000;
 | |
|     static LONG Protect = -1;
 | |
|     char buffer[nBufSize];
 | |
| 
 | |
|     va_list argptr;
 | |
|     int cnt;
 | |
|     va_start(argptr, fmt);
 | |
|     cnt = _vsnprintf(buffer, nBufSize, fmt, argptr);
 | |
|     if (cnt == -1)
 | |
|         buffer[nBufSize] = 0; // Null terminate manually; see _vsnprintf spec
 | |
|     va_end(argptr);
 | |
| 
 | |
|     EnterCriticalSection(&csPrintf);
 | |
|     m_sDebugInfo += buffer;
 | |
|     LeaveCriticalSection(&csPrintf);
 | |
| 
 | |
|     return cnt;
 | |
| #else
 | |
|     return 0;
 | |
| #endif
 | |
| }
 | |
| */
 | |
| 
 |