windows-nt/Source/XPSP1/NT/admin/cmdline/cmdevtgprov/triggerprovider.cpp
2020-09-26 16:20:57 +08:00

1755 lines
48 KiB
C++

//***************************************************************************
// Copyright (c) Microsoft Corporation
//
// Module Name:
// TRIGGERPROVIDER.CPP
//
// Abstract:
// Contains CTriggerProvider implementation.
//
// Author:
// Vasundhara .G
//
// Revision History:
// Vasundhara .G 9-oct-2k : Created It.
//***************************************************************************
#include "pch.h"
#include "General.h"
#include "EventConsumerProvider.h"
#include "TriggerConsumer.h"
#include "TriggerProvider.h"
#include "resource.h"
extern HMODULE g_hModule;
//
// general purpose macros
// ( some macros in this section might end abruptly ... this was done purposefully
// do not alter that part ... will result compiler errors
//
#define VALUE_GET( object, property, type, valueaddr, size ) \
hr = PropertyGet( object, property, type, valueaddr, size ); \
if ( FAILED( hr ) ) \
return hr;
//***************************************************************************
// Routine Description:
// Constructor for CTriggerProvider class for initialization.
//
// Arguments:
// None.
//
// Return Value:
// None.
//***************************************************************************
CTriggerProvider::CTriggerProvider()
{
// update the no. of provider instances count
InterlockedIncrement( ( LPLONG ) &g_dwInstances );
// initialize the reference count variable
m_dwCount = 0;
// initializations
m_pContext = NULL;
m_pServices = NULL;
m_pwszLocale = NULL;
m_dwNextTriggerID = 0;
}
//***************************************************************************
// Routine Description:
// Destructor for CTriggerProvider class.
//
// Arguments:
// None.
//
// Return Value:
// None.
//***************************************************************************
CTriggerProvider::~CTriggerProvider()
{
// release the services / namespace interface ( if exist )
SAFERELEASE( m_pServices );
// release the context interface ( if exist )
SAFERELEASE( m_pContext );
// if memory is allocated for storing locale information, free it
if ( m_pwszLocale != NULL )
{
delete [] m_pwszLocale;
}
// update the no. of provider instances count
InterlockedDecrement( ( LPLONG ) &g_dwInstances );
}
//***************************************************************************
// Routine Description:
// Returns a pointer to a specified interface on an object
// to which a client currently holds an interface pointer.
//
// Arguments:
// riid [in] : Identifier of the interface being requested.
// ppv [out] : Address of pointer variable that receives the
// interface pointer requested in riid. Upon
// successful return, *ppvObject contains the
// requested interface pointer to the object.
//
// Return Value:
// NOERROR if the interface is supported.
// E_NOINTERFACE if not.
//***************************************************************************
STDMETHODIMP CTriggerProvider::QueryInterface( REFIID riid, LPVOID* ppv )
{
// initialy set to NULL
*ppv = NULL;
// check whether interface requested is one we have
if ( riid == IID_IUnknown )
{
// need IUnknown interface
*ppv = this;
}
else if ( riid == IID_IWbemEventConsumerProvider )
{
// need IEventConsumerProvider interface
*ppv = static_cast<IWbemEventConsumerProvider*>( this );
}
else if ( riid == IID_IWbemServices )
{
// need IWbemServices interface
*ppv = static_cast<IWbemServices*>( this );
}
else if ( riid == IID_IWbemProviderInit )
{
// need IWbemProviderInit
*ppv = static_cast<IWbemProviderInit*>( this );
}
else
{
// request interface is not available
return E_NOINTERFACE;
}
// update the reference count
reinterpret_cast<IUnknown*>( *ppv )->AddRef();
return NOERROR; // inform success
}
//***************************************************************************
// Routine Description:
// The AddRef method increments the reference count for
// an interface on an object. It should be called for every
// new copy of a pointer to an interface on a given object.
//
// Arguments:
// none.
//
// Return Value:
// Returns the value of the new reference count.
//***************************************************************************
STDMETHODIMP_(ULONG) CTriggerProvider::AddRef( void )
{
// increment the reference count ... thread safe
return InterlockedIncrement( ( LPLONG ) &m_dwCount );
}
//***************************************************************************
// Routine Description:
// The Release method decreases the reference count of the object by 1.
//
// Arguments:
// none.
//
// Return Value:
// Returns the new reference count.
//***************************************************************************
STDMETHODIMP_(ULONG) CTriggerProvider::Release( void )
{
// decrement the reference count ( thread safe ) and check whether
// there are some more references or not ... based on the result value
DWORD dwCount = 0;
dwCount = InterlockedDecrement( ( LPLONG ) &m_dwCount );
if ( dwCount == 0 )
{
// free the current factory instance
delete this;
}
// return the no. of instances references left
return dwCount;
}
//***************************************************************************
// Routine Description:
// This is the implemention of IWbemProviderInit. The
// method is need to initialize with CIMOM.
//
// Arguments:
// wszUser [in] : pointer to user name.
// lFlags [in] : Reserved.
// wszNamespace [in] : contains the namespace of WMI.
// wszLocale [in] : Locale Name.
// pNamespace [in] : pointer to IWbemServices.
// pCtx [in] : IwbemContext pointer associated for initialization.
// pInitSink [out] : a pointer to IWbemProviderInitSink for
// reporting the initialization status.
//
// Return Value:
// returns HRESULT value.
//***************************************************************************
STDMETHODIMP CTriggerProvider::Initialize( LPWSTR wszUser, LONG lFlags,
LPWSTR wszNamespace, LPWSTR wszLocale,
IWbemServices* pNamespace, IWbemContext* pCtx,
IWbemProviderInitSink* pInitSink )
{
HRESULT hRes = 0;
IEnumWbemClassObject *pINTEConsumer = NULL;
DWORD dwReturned = 0;
DWORD dwTrigId = 0;
VARIANT varTrigId;
DWORD i = 0;
try
{
// save the namespace interface ... will be useful at later stages
m_pServices = pNamespace;
m_pServices->AddRef(); // update the reference
// also save the context interface ... will be userful at later stages ( if available )
if ( pCtx != NULL )
{
m_pContext = pCtx;
m_pContext->AddRef();
}
// save the locale information ( if exist )
if ( wszLocale != NULL )
{
m_pwszLocale = new WCHAR [ wcslen( wszLocale ) + 1 ];
if ( m_pwszLocale == NULL )
{
// update the sink accordingly
pInitSink->SetStatus( WBEM_E_FAILED, 0 );
// return failure
return WBEM_E_OUT_OF_MEMORY;
}
}
// Enumerate TriggerEventConsumer to get the Maximum trigger Id which can be later
// used to generate unique trigger id value.
hRes = m_pServices ->CreateInstanceEnum(
_bstr_t(CONSUMER_CLASS),
WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY,
m_pContext, &pINTEConsumer);
if (SUCCEEDED( hRes ) )
{
dwReturned = 1;
// Final Next will return with ulReturned = 0
while ( dwReturned != 0 )
{
IWbemClassObject *pINTCons[5];
// Enumerate through the resultset.
hRes = pINTEConsumer->Next( WBEM_INFINITE,
5, // return just one Logfile
pINTCons, // pointer to Logfile
&dwReturned ); // number obtained: one or zero
if ( SUCCEEDED( hRes ) )
{
// Get the trigger id value
for( i = 0; i < dwReturned; i++ )
{
VariantInit( &varTrigId );
hRes = pINTCons[i]->Get( TRIGGER_ID, 0, &varTrigId, 0, NULL );
SAFERELEASE( pINTCons[i] );
if ( SUCCEEDED( hRes ) )
{
dwTrigId = ( DWORD )varTrigId.lVal;
if( dwTrigId > m_dwNextTriggerID )
{
m_dwNextTriggerID = dwTrigId;
}
}
else
{
VariantClear( &varTrigId );
break;
}
VariantClear( &varTrigId );
}
}
else
{
break;
}
} //while
// got triggerId so set it
SAFERELEASE( pINTEConsumer );
}
//Let CIMOM know your initialized
//===============================
if ( SUCCEEDED( hRes ) )
{
// update the m_dwTrigId value
m_dwNextTriggerID = m_dwNextTriggerID + 1;
hRes = pInitSink->SetStatus( WBEM_S_INITIALIZED, 0 );
}
else
{
hRes = pInitSink->SetStatus( WBEM_E_FAILED, 0);
}
}
catch(_com_error& e)
{
hRes = pInitSink->SetStatus( WBEM_E_FAILED, 0);
return hRes;
}
return hRes;
}
//***************************************************************************
// Routine Description:
// This is the Async function implementation.
// The methods supported is named CreateETrigger and DeleteETrigger.
//
// Arguments:
// bstrObjectPath [in] : path of the object for which the method is executed.
// bstrMethodName [in] : Name of the method for the object.
// lFlags [in] : WBEM_FLAG_SEND_STATUS.
// pICtx [in] : a pointer to IWbemContext.
// pIInParams [in] : this points to an IWbemClassObject object
// that contains the properties acting as
// inbound parameters for method execution.
// pIResultSink [out] : The object sink receives the result of the method call.
//
// Return Value:
// returns HRESULT.
//***************************************************************************
STDMETHODIMP CTriggerProvider::ExecMethodAsync( const BSTR bstrObjectPath,
const BSTR bstrMethodName,
long lFlags,
IWbemContext* pICtx,
IWbemClassObject* pIInParams,
IWbemObjectSink* pIResultSink )
{
HRESULT hRes = 0;
HRESULT hRes1 = NO_ERROR;
IWbemClassObject *pIClass = NULL;
IWbemClassObject *pIOutClass = NULL;
IWbemClassObject *pIOutParams = NULL;
VARIANT varTriggerName, varTriggerAction, varTriggerQuery,
varTriggerDesc, varTemp, varRUser, varRPwd, varScheduledTaskName;
DWORD dwTrigId = 0;
try
{
//set out parameters
hRes = m_pServices->GetObject( CONSUMER_CLASS, 0, pICtx, &pIClass, NULL );
if( FAILED( hRes ) )
{
pIResultSink->SetStatus( 0, hRes, NULL, NULL );
return hRes;
}
// This method returns values, and so create an instance of the
// output argument class.
hRes = pIClass->GetMethod( bstrMethodName, 0, NULL , &pIOutClass );
SAFERELEASE( pIClass );
if( FAILED( hRes ) )
{
pIResultSink->SetStatus( 0, hRes, NULL, NULL );
return hRes;
}
hRes = pIOutClass->SpawnInstance( 0, &pIOutParams );
SAFERELEASE( pIOutClass );
if( FAILED( hRes ) )
{
pIResultSink->SetStatus( 0, hRes, NULL, NULL );
return hRes;
}
VariantInit( &varTriggerName );
//Check the method name
if( _wcsicmp( bstrMethodName, CREATE_METHOD_NAME ) == 0 )
{
// if client has called CreateETrigger then
// parse input params to get trigger name, trigger desc, trigger action
// and trigger query for creating new instances of TriggerEventConsumer,
// __EventFilter and __FilterToConsumerBinding classes
//initialize variables
VariantInit( &varTriggerAction );
VariantInit( &varTriggerQuery );
VariantInit( &varTriggerDesc );
VariantInit( &varRUser );
VariantInit( &varRPwd );
//Retrieve Trigger Name parameter from input params
hRes = pIInParams->Get( IN_TRIGGER_NAME, 0, &varTriggerName, NULL, NULL );
if( SUCCEEDED( hRes ) )
{
//Retrieve Trigger Action parameter from input params
hRes = pIInParams->Get( IN_TRIGGER_ACTION, 0, &varTriggerAction, NULL, NULL );
if( SUCCEEDED( hRes ) )
{
//Retrieve Trigger Query parameter from input params
hRes = pIInParams->Get( IN_TRIGGER_QUERY, 0, &varTriggerQuery, NULL, NULL );
if( SUCCEEDED( hRes ) )
{
//Retrieve Trigger Description parameter from input params
hRes = pIInParams->Get( IN_TRIGGER_DESC, 0, &varTriggerDesc, NULL, NULL );
if( SUCCEEDED( hRes ) )
{
EnterCriticalSection( &g_critical_sec );
hRes = ValidateParams( varTriggerName, varTriggerAction,
varTriggerQuery );
if( hRes == WBEM_S_NO_ERROR )
{
hRes = pIInParams->Get( IN_TRIGGER_USER, 0, &varRUser, NULL, NULL );
if( SUCCEEDED( hRes ) )
{
hRes = pIInParams->Get( IN_TRIGGER_PWD, 0, &varRPwd, NULL, NULL );
if( SUCCEEDED( hRes ) )
{
//call create trigger function to create the instances
hRes = CreateTrigger( varTriggerName, varTriggerDesc,
varTriggerAction, varTriggerQuery,
varRUser, varRPwd, &hRes1 );
if( ( hRes == WBEM_S_NO_ERROR ) || ( hRes == WARNING_INVALID_USER ) )
{
// increment the class member variable by one to get the new unique trigger id
//for the next instance
m_dwNextTriggerID = m_dwNextTriggerID + 1;
}
}
}
}
LeaveCriticalSection( &g_critical_sec );
}
}
}
}
VariantClear( &varTriggerAction );
VariantClear( &varRUser );
VariantClear( &varRPwd );
VariantClear( &varTriggerDesc );
VariantClear( &varTriggerQuery );
}
else if( _wcsicmp( bstrMethodName, DELETE_METHOD_NAME ) == 0 )
{
//Retrieve Trigger ID parameter from input params
hRes = pIInParams->Get( IN_TRIGGER_NAME, 0, &varTriggerName, NULL, NULL );
if( SUCCEEDED( hRes ) )
{
EnterCriticalSection( &g_critical_sec );
//call Delete trigger function to delete the instances
hRes = DeleteTrigger( varTriggerName, &dwTrigId );
LeaveCriticalSection( &g_critical_sec );
}
}
else if( _wcsicmp( bstrMethodName, QUERY_METHOD_NAME ) == 0 )
{
VariantInit( &varScheduledTaskName );
VariantInit( &varRUser );
//Retrieve schedule task name parameter from input params
hRes = pIInParams->Get( IN_TRIGGER_TSCHDULER, 0, &varScheduledTaskName, NULL, NULL );
if( SUCCEEDED( hRes ) )
{
EnterCriticalSection( &g_critical_sec );
//call query trigger function to query the runasuser
CHString szRunAsUser = NULL_STRING;
hRes = QueryTrigger( varScheduledTaskName, szRunAsUser );
varRUser.vt = VT_BSTR;
varRUser.bstrVal = SysAllocString( szRunAsUser );
hRes = pIOutParams->Put( OUT_RUNAS_USER , 0, &varRUser, 0 );
LeaveCriticalSection( &g_critical_sec );
}
VariantClear( &varScheduledTaskName );
VariantClear( &varRUser );
}
else
{
hRes = WBEM_E_INVALID_PARAMETER;
}
if( _wcsicmp( bstrMethodName, CREATE_METHOD_NAME ) == 0 )
{
LPTSTR lpResStr = NULL;
lpResStr = ( LPTSTR ) __calloc( MAX_RES_STRING1 + 1, sizeof( TCHAR ) );
if ( lpResStr != NULL )
{
if( ( hRes == WBEM_S_NO_ERROR ) || ( hRes == WARNING_INVALID_USER ) )
{
LoadStringW( g_hModule, IDS_CREATED, lpResStr, MAX_RES_STRING1 );
if( hRes1 != NO_ERROR )// write invalid user into log file
{
LPTSTR lpResStr1 = NULL;
BOOL bFlag = FALSE;
lpResStr1 = ( LPTSTR ) __calloc( MAX_RES_STRING1 + 1, sizeof( TCHAR ) );
if ( lpResStr1 != NULL )
{
if( hRes1 == ERROR_TASK_SCHDEULE_SERVICE_STOP )
{
hRes = WBEM_S_NO_ERROR;
LoadStringW( g_hModule,IDS_INFO_SERVICE_STOPPED, lpResStr1, MAX_RES_STRING1 );
lstrcat( lpResStr, lpResStr1 );
}
else if( hRes1 == ERROR_SCHDEULE_TASK_INVALID_USER )
{
hRes = WARNING_INVALID_USER;
LoadStringW( g_hModule, IDS_INFO_INVALID_USER, lpResStr1, MAX_RES_STRING1 );
lstrcat( lpResStr, lpResStr1 );
}
free( lpResStr1 );
}
}
ErrorLog( lpResStr, ( LPWSTR )_bstr_t( varTriggerName ), ( m_dwNextTriggerID - 1 ) );
}
else
{
LoadStringW( g_hModule, IDS_CREATE_FAILED, lpResStr, MAX_RES_STRING1 );
ErrorLog( lpResStr, ( LPWSTR )_bstr_t( varTriggerName ), ( m_dwNextTriggerID - 1 ) );
}
free( lpResStr );
}
else
{
hRes = E_OUTOFMEMORY;
}
}
else if( _wcsicmp( bstrMethodName, DELETE_METHOD_NAME ) == 0 )
{
LPTSTR lpResStr = NULL;
lpResStr = ( LPTSTR ) __calloc( MAX_RES_STRING1 + 1, sizeof( TCHAR ) );
if ( lpResStr != NULL )
{
if( hRes == WBEM_S_NO_ERROR )
{
LoadStringW( g_hModule, IDS_DELETED, lpResStr, MAX_RES_STRING1 );
ErrorLog( lpResStr, ( LPWSTR )_bstr_t( varTriggerName ), dwTrigId );
}
else
{
LoadStringW( g_hModule, IDS_DELETE_FAILED, lpResStr, MAX_RES_STRING1 );
ErrorLog( lpResStr,( LPWSTR )_bstr_t( varTriggerName ), dwTrigId );
}
free( lpResStr );
}
else
{
hRes = E_OUTOFMEMORY;
}
}
VariantInit( &varTemp );
V_VT( &varTemp ) = VT_I4;
V_I4( &varTemp ) = hRes;
// set out params
hRes = pIOutParams->Put( RETURN_VALUE , 0, &varTemp, 0 );
VariantClear( &varTemp );
if( SUCCEEDED( hRes ) )
{
// Send the output object back to the client via the sink. Then
hRes = pIResultSink->Indicate( 1, &pIOutParams );
}
//release all the resources
SAFERELEASE( pIOutParams );
hRes = pIResultSink->SetStatus( 0, WBEM_S_NO_ERROR, NULL, NULL );
}
catch(_com_error& e)
{
pIResultSink->SetStatus( 0, hRes, NULL, NULL );
return hRes;
}
catch( CHeap_Exception )
{
hRes = E_OUTOFMEMORY;
pIResultSink->SetStatus( 0, hRes, NULL, NULL );
return hRes;
}
return hRes;
}
//***************************************************************************
// Routine Description:
// This routine creates the instance of TriggerEventConsumer,
// __EventFilter and __FilterToConsumerBinding classes.
//
// Arguments:
// varTName [in] : Trigger Name.
// varTDesc [in] : Trigger Description.
// varTAction [in] : Trigger Action.
// varTQuery [in] : Trigger Query.
//
// Return Value:
// S_OK if successful.
// Otherwise failure error code.
//***************************************************************************
HRESULT CTriggerProvider::CreateTrigger( VARIANT varTName, VARIANT varTDesc,
VARIANT varTAction, VARIANT varTQuery,
VARIANT varRUser, VARIANT varRPwd,
HRESULT *phRes )
{
IWbemClassObject *pINtLogEventClass = 0;
IWbemClassObject *pIFilterClass = 0;
IWbemClassObject *pIBindClass = 0;
IWbemClassObject *pINewInstance = 0;
IEnumWbemClassObject *pIEnumClassObject = 0;
HRESULT hRes = 0;
DWORD dwTId = 0;
VARIANT varTemp;
TCHAR szTemp[MAX_RES_STRING1];
TCHAR szTemp1[MAX_RES_STRING1];
TCHAR szFName[MAX_RES_STRING1];
SYSTEMTIME SysTime;
BOOL bInvalidUser = FALSE;
try
{
_bstr_t bstrcurInst;
_bstr_t bstrcurInst1;
//initialize memory for temporary variables
memset( szTemp, 0, sizeof( szTemp ) );
memset( szTemp1, 0, sizeof(szTemp1 ) );
memset( szFName, 0, sizeof( szFName ) );
VariantInit( &varTemp );
if ( phRes != NULL )
{
*phRes = NO_ERROR;
}
/**************************************************************************
CREATING __EventFilter INSTANCE
***************************************************************************/
// get EventFilter class object
hRes = m_pServices->GetObject( FILTER_CLASS, 0, 0, &pIFilterClass, NULL );
if( FAILED( hRes ) )
{
return hRes;
}
// Create a new instance.
hRes = pIFilterClass->SpawnInstance( 0, &pINewInstance );
SAFERELEASE( pIFilterClass ); // Don't need the class any more
//return error if unable to spawn a new instance of EventFilter class
if( FAILED( hRes ) )
{
return hRes;
}
// set query property for the new instance
hRes = pINewInstance->Put( FILTER_QUERY, 0, &varTQuery, 0 );
//if failed to set the property return error
if( FAILED( hRes ) )
{
SAFERELEASE( pINewInstance );
return hRes;
}
VariantInit( &varTemp );
varTemp.vt = VT_BSTR;
varTemp.bstrVal = SysAllocString( QUERY_LANGUAGE );
// set query language property for the new instance .
hRes = pINewInstance->Put( FILTER_QUERY_LANGUAGE, 0, &varTemp, 0 );
VariantClear( &varTemp );
//if failed to set the property return error
if( FAILED( hRes ) )
{
SAFERELEASE( pINewInstance );
return hRes;
}
//generate unique name for name key property of EventFilter class by concatinating
// current system date and time
GetSystemTime( &SysTime );
wsprintf ( szTemp, FILTER_UNIQUE_NAME, m_dwNextTriggerID, SysTime.wHour, SysTime.wMinute,
SysTime.wSecond, SysTime.wMonth, SysTime.wDay, SysTime.wYear );
//set Filter name property
VariantInit( &varTemp );
varTemp.vt = VT_BSTR;
varTemp.bstrVal = SysAllocString( szTemp );
hRes = pINewInstance->Put( FILTER_NAME, 0, &varTemp, 0 );
VariantClear( &varTemp );
//if failed to set the property return error
if( FAILED( hRes ) )
{
SAFERELEASE( pINewInstance );
return hRes;
}
// Write the instance to WMI.
hRes = m_pServices->PutInstance( pINewInstance, 0, NULL, NULL );
SAFERELEASE( pINewInstance );
//if putinstance failed return error
if( FAILED( hRes ) )
{
return hRes;
}
//get the current Eventfilter instance for binding filter to consumer
wsprintf( szTemp1, BIND_FILTER_PATH );
bstrcurInst = _bstr_t(szTemp1) + _bstr_t(szTemp) + _bstr_t(BACK_SLASH);
pIFilterClass = NULL;
hRes = m_pServices->GetObject( bstrcurInst, 0L, NULL, &pIFilterClass, NULL );
//unable to get the current instance object return error
if( FAILED( hRes ) )
{
return hRes;
}
/**************************************************************************
CREATING TriggerEventConsumer INSTANCE
***************************************************************************/
//get NTEventConsumer class object
hRes =m_pServices->GetObject( CONSUMER_CLASS, 0, 0, &pINtLogEventClass, NULL );
//if unable to get the object of TriggerEventConsumer return error
if( FAILED( hRes ) )
{
SAFERELEASE( pINtLogEventClass );// safer side
SAFERELEASE( pIFilterClass );
return hRes;
}
// Create a new instance.
pINewInstance = NULL;
hRes = pINtLogEventClass->SpawnInstance( 0, &pINewInstance );
SAFERELEASE( pINtLogEventClass ); // Don't need the class any more
// if unable to spawn a instance return back to caller
if( FAILED( hRes ) )
{
SAFERELEASE( pIFilterClass );
return hRes;
}
//get the unique trigger id from CMethodPro memeber variable
hRes = m_pServices->ExecQuery( QUERY_LANGUAGE, INSTANCE_EXISTS_QUERY,
WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pIEnumClassObject );
if( FAILED( hRes ) )
{
SAFERELEASE( pIFilterClass );
SAFERELEASE( pINewInstance );
return hRes;
}
DWORD dwReturned = 0;
IWbemClassObject *pINTCons = NULL;
// Enumerate through the resultset.
hRes = pIEnumClassObject->Next( WBEM_INFINITE,
1, // return just one service
&pINTCons, // pointer to service
&dwReturned ); // number obtained: one or zero
if ( SUCCEEDED( hRes ) && ( dwReturned == 1 ) )
{
SAFERELEASE( pINTCons );
} // If Service Succeeded
else
{
m_dwNextTriggerID = 1;
}
SAFERELEASE( pIEnumClassObject );
dwTId = m_dwNextTriggerID;
VariantInit(&varTemp);
varTemp.vt = VT_I4;
varTemp.lVal = dwTId;
// set the trigger id property of NTEventConsumer
hRes = pINewInstance->Put( TRIGGER_ID, 0, &varTemp, 0 );
VariantClear( &varTemp );
//if failed to set the property return error
if( FAILED( hRes ) )
{
SAFERELEASE( pIFilterClass );
SAFERELEASE( pINewInstance );
return hRes;
}
// set Triggername property.
hRes = pINewInstance->Put( TRIGGER_NAME, 0, &varTName, 0 );
//if failed to set the property return error
if( FAILED( hRes ) )
{
SAFERELEASE( pIFilterClass );
SAFERELEASE( pINewInstance );
return hRes;
}
// set action property
hRes = pINewInstance->Put( TRIGGER_ACTION, 0, &varTAction, 0 );
//if failed to set the property return error
if( FAILED( hRes ) )
{
SAFERELEASE( pIFilterClass );
SAFERELEASE( pINewInstance );
return hRes;
}
//set desc property
hRes = pINewInstance->Put( TRIGGER_DESC, 0, &varTDesc, 0 );
//if failed to set the property return error
if( FAILED( hRes ) )
{
SAFERELEASE( pIFilterClass );
SAFERELEASE( pINewInstance );
return hRes;
}
CHString szScheduler = NULL_STRING;
CHString szRUser = (LPCWSTR)_bstr_t(varRUser.bstrVal);
if( ( varRUser.vt != VT_NULL ) && ( varRUser.vt != VT_EMPTY ) && ( szRUser.GetLength() > 0 ) )
{
GetUniqueTScheduler( szScheduler, m_dwNextTriggerID, varTName );
hRes = SetUserContext( varRUser, varRPwd, varTAction, szScheduler );
*phRes = hRes;
if( hRes == ERROR_SCHDEULE_TASK_INVALID_USER ||
( hRes == ERROR_TASK_SCHDEULE_SERVICE_STOP ) ) //to send a warning msg to client
{
bInvalidUser = TRUE;
}
if( FAILED( hRes ) )
{
//if user is not existing or service is stopped skip
if( ( hRes != ERROR_SCHDEULE_TASK_INVALID_USER ) && ( hRes != ERROR_TASK_SCHDEULE_SERVICE_STOP ) )
{
SAFERELEASE( pIFilterClass );
SAFERELEASE( pINewInstance );
return hRes;
}
}
}
VariantInit(&varTemp);
varTemp.vt = VT_BSTR;
varTemp.bstrVal = SysAllocString( szScheduler );
hRes = pINewInstance->Put( TASK_SHEDULER, 0, &varTemp, 0 );
VariantClear( &varTemp );
if( FAILED( hRes ) )
{
SAFERELEASE( pIFilterClass );
SAFERELEASE( pINewInstance );
return hRes;
}
// Write the instance to WMI.
hRes = m_pServices->PutInstance( pINewInstance, 0, 0, NULL );
SAFERELEASE( pINewInstance );
//if putinstance failed return error
if( FAILED( hRes ) )
{
SAFERELEASE( pIFilterClass );
return hRes;
}
//get the current instance for binding it with __FilterToConsumerBinding class
wsprintf( szTemp, BIND_CONSUMER_PATH, dwTId);
bstrcurInst1 = _bstr_t( szTemp );
pINtLogEventClass = NULL;
hRes = m_pServices->GetObject( bstrcurInst1, 0L, NULL, &pINtLogEventClass, NULL );
//if unable to get the current instance return error
if( FAILED( hRes ) )
{
SAFERELEASE( pIFilterClass );
return hRes;
}
/**************************************************************************
BINDING FILTER TO CONSUMER
***************************************************************************/
// if association class exists...
if( ( hRes = m_pServices->GetObject( BINDINGCLASS, 0L, NULL, &pIBindClass, NULL ) ) == S_OK )
{
// spawn a new instance.
pINewInstance = NULL;
if( ( hRes = pIBindClass->SpawnInstance( 0, &pINewInstance ) ) == WBEM_S_NO_ERROR )
{
// set consumer instance name
if ( ( hRes = pINtLogEventClass->Get( REL_PATH, 0L,
&varTemp, NULL, NULL ) ) == WBEM_S_NO_ERROR )
{
hRes = pINewInstance->Put( CONSUMER_BIND, 0, &varTemp, 0 );
VariantClear( &varTemp );
// set Filter ref
if ( ( hRes = pIFilterClass->Get( REL_PATH, 0L,
&varTemp, NULL, NULL ) ) == WBEM_S_NO_ERROR )
{
hRes = pINewInstance->Put( FILTER_BIND, 0, &varTemp, 0 );
VariantClear( &varTemp );
// putInstance
hRes = m_pServices->PutInstance( pINewInstance,
WBEM_FLAG_CREATE_OR_UPDATE, NULL, NULL );
}
}
SAFERELEASE( pINewInstance );
SAFERELEASE( pINtLogEventClass ); // Don't need the class any more
SAFERELEASE( pIFilterClass ); // Don't need the class any more
SAFERELEASE( pIBindClass );
}
else
{
SAFERELEASE( pINtLogEventClass ); // Don't need the class any more
SAFERELEASE( pIFilterClass ); // Don't need the class any more
SAFERELEASE( pIBindClass );
}
}
else
{
SAFERELEASE( pINtLogEventClass ); // Don't need the class any more
SAFERELEASE( pIFilterClass ); // Don't need the class any more
}
}
catch(_com_error& e)
{
return hRes;
}
catch( CHeap_Exception )
{
return E_OUTOFMEMORY;
}
if( ( hRes == WBEM_S_NO_ERROR ) && ( bInvalidUser == TRUE ) )
{
return WARNING_INVALID_USER;
}
return hRes;
}
//***************************************************************************
// Routine Description:
// This routine deletes the instance of TriggerEventConsumer,
// __EventFilter and __FilterToConsumerBinding classes.
//
// Arguments:
// varTName [in] : Trigger Name.
// dwTrigId [in\out] : Trigger id.
//
// Return Value:
// WBEM_S_NO_ERROR if successful.
// Otherwise failure error code.
//***************************************************************************
HRESULT CTriggerProvider::DeleteTrigger( VARIANT varTName, DWORD *dwTrigId )
{
HRESULT hRes = 0;
IEnumWbemClassObject *pIEventBinder = NULL;
IWbemClassObject *pINTCons = NULL;
DWORD dwReturned = 1;
DWORD i =0;
DWORD j = 0;
TCHAR szTemp[MAX_RES_STRING1];
TCHAR szTemp1[MAX_RES_STRING1];
VARIANT varTemp;
BSTR bstrFilInst = NULL;
DWORD dwFlag = 0;
wchar_t *szwTemp2 = NULL;
wchar_t szwFilName[100];
try
{
_bstr_t bstrBinInst;
CHString strTScheduler = NULL_STRING;
memset( szTemp, 0, sizeof( szTemp ) );
memset( szTemp1, 0, sizeof( szTemp1 ) );
memset( szwFilName, 0, sizeof( szwFilName ) );
wsprintf( szTemp, TRIGGER_INSTANCE_NAME, varTName.bstrVal );
hRes = m_pServices->ExecQuery( QUERY_LANGUAGE, _bstr_t( szTemp ),
WBEM_FLAG_RETURN_IMMEDIATELY| WBEM_FLAG_FORWARD_ONLY, NULL,
&pIEventBinder );
memset( szTemp, 0, sizeof( szTemp ) );
if( FAILED( hRes ) )
{
return hRes;
}
while ( ( dwReturned == 1 ) && ( dwFlag == 0 ) )
{
// Enumerate through the resultset.
hRes = pIEventBinder->Next( WBEM_INFINITE,
1, // return just one service
&pINTCons, // pointer to service
&dwReturned ); // number obtained: one or zero
if ( SUCCEEDED( hRes ) && ( dwReturned == 1 ) )
{
dwFlag = 1;
} // If Service Succeeded
}
SAFERELEASE( pIEventBinder );
if( dwFlag == 0 )
{
SAFERELEASE( pINTCons );
return ERROR_TRIGGER_NOT_FOUND;
}
VariantInit( &varTemp );
hRes = pINTCons->Get( TRIGGER_ID, 0, &varTemp, 0, NULL );
if (FAILED( hRes ) )
{
SAFERELEASE( pIEventBinder );
SAFERELEASE( pINTCons );
return hRes;
}
*dwTrigId = ( DWORD )varTemp.lVal;
VariantClear( &varTemp );
hRes = pINTCons->Get( TASK_SHEDULER, 0, &varTemp, 0, NULL );
if (FAILED( hRes ) )
{
SAFERELEASE( pIEventBinder );
SAFERELEASE( pINTCons );
return hRes;
}
SAFERELEASE( pINTCons );
strTScheduler = (LPCWSTR) _bstr_t(varTemp.bstrVal);
VariantClear( &varTemp );
if( strTScheduler.GetLength() > 0 )
{
hRes = DeleteTaskScheduler( strTScheduler );
if ( hRes != WBEM_S_NO_ERROR )
{
return hRes;
}
}
wsprintf( szTemp, BIND_CONSUMER_PATH, *dwTrigId );
//enumerate the binding class
hRes = m_pServices->CreateInstanceEnum(
_bstr_t(BINDINGCLASS),
WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY,
NULL, &pIEventBinder );
if ( SUCCEEDED( hRes ) )
{
dwReturned = 1;
dwFlag = 0;
//loop through all the instances of binding class to find that trigger
//id specified. If found loop out and proceed else return error
// Final Next will return with ulReturned = 0
while ( ( dwReturned == 1 ) && ( dwFlag == 0 ) )
{
IWbemClassObject *pIBind = NULL;
// Enumerate through the resultset.
hRes = pIEventBinder->Next( WBEM_INFINITE,
1, // return just one Logfile
&pIBind, // pointer to Logfile
&dwReturned ); // number obtained: one or zero
if ( SUCCEEDED( hRes ) && ( dwReturned == 1 ) )
{
VariantInit(&varTemp);
//get consumer property of binding class
hRes = pIBind->Get( CONSUMER_BIND, 0, &varTemp, 0, NULL );
if ( SUCCEEDED( hRes ) )
{
if (varTemp.vt != VT_NULL && varTemp.vt != VT_EMPTY)
{
CHString strTemp;
strTemp = varTemp.bstrVal;
//compare with the inputed value
if( wcscmp( szTemp, strTemp ) == 0 )
{
VariantClear( &varTemp );
//get the filter property
hRes = pIBind->Get( FILTER_BIND, 0, &varTemp, 0, NULL );
if ( hRes != WBEM_S_NO_ERROR )
{
SAFERELEASE( pIBind );
break;
}
bstrFilInst = SysAllocString( varTemp.bstrVal );
dwFlag = 1;
}
}
else
{
SAFERELEASE( pIBind );
break;
}
}
else
{
SAFERELEASE( pIBind );
break;
}
SAFERELEASE( pIBind );
VariantClear( &varTemp );
}
else
{
break;
}
} //end of while
SAFERELEASE( pIEventBinder );
}
else
{
return( hRes );
}
//if instance has been found delete the instances from consumer,filter
// and binding class
if( dwFlag == 1 )
{
//get the key properties for binding class
wsprintf( szTemp1, FILTER_PROP, szTemp );
szwTemp2 = (wchar_t *) bstrFilInst;
//manpulate the filter property value to insert the filter name property
// value in quotes
i =0;
while( szwTemp2[i] != EQUAL )
{
i++;
}
i += 2;
j = 0;
while( szwTemp2[i] != DOUBLE_QUOTE )
{
szwFilName[j] = ( wchar_t )szwTemp2[i];
i++;
j++;
}
szwFilName[j] = END_OF_STRING;
bstrBinInst = _bstr_t( szTemp1 ) + _bstr_t( szwFilName ) + _bstr_t(DOUBLE_SLASH);
//got it so delete the instance
hRes = m_pServices->DeleteInstance( bstrBinInst, 0, 0, NULL );
if( FAILED( hRes ) )
{
SysFreeString( bstrFilInst );
return hRes;
}
//deleting instance from EventFilter class
hRes = m_pServices->DeleteInstance( bstrFilInst, 0, 0, NULL );
if( FAILED( hRes ) )
{
SysFreeString( bstrFilInst );
return hRes;
}
//deleting instance from TriggerEventConsumer Class
hRes = m_pServices->DeleteInstance( _bstr_t(szTemp), 0, 0, NULL );
if( FAILED( hRes ) )
{
SysFreeString( bstrFilInst );
return hRes;
}
SysFreeString( bstrFilInst );
}
else
return( ERROR_TRIGGER_NOT_DELETED );
}
catch(_com_error& e)
{
return hRes;
}
catch( CHeap_Exception )
{
return E_OUTOFMEMORY;
}
return WBEM_S_NO_ERROR;
}
//***************************************************************************
// Routine Description:
// This routine queries task scheduler for account information
//
// Arguments:
// varScheduledTaskName [in] : Task scheduler name.
// szRunAsUser [out] : stores account information.
//
// Return Value:
// WBEM_S_NO_ERROR if successful.
// Otherwise failure error code.
//***************************************************************************
HRESULT CTriggerProvider::QueryTrigger( VARIANT varScheduledTaskName, CHString &szRunAsUser )
{
HRESULT hRes = 0;
ITaskScheduler *pITaskScheduler = NULL;
IEnumWorkItems *pIEnum = NULL;
ITask *pITask = NULL;
LPWSTR *lpwszNames = NULL;
DWORD dwFetchedTasks = 0;
TCHAR szActualTask[MAX_STRING_LENGTH] = NULL_STRING;
try
{
pITaskScheduler = GetTaskScheduler();
if ( pITaskScheduler == NULL )
{
hRes = E_FAIL;
return hRes;
}
hRes = pITaskScheduler->Enum( &pIEnum );
if( FAILED( hRes ) )
{
return hRes;
}
while ( SUCCEEDED( pIEnum->Next( 1,
&lpwszNames,
&dwFetchedTasks ) )
&& (dwFetchedTasks != 0))
{
while (dwFetchedTasks)
{
// Check whether the TaskName is present, if present
// then return arrJobs.
// Convert the Wide Charater to Multi Byte value.
GetCompatibleStringFromUnicode( lpwszNames[ --dwFetchedTasks ], szActualTask, SIZE_OF_ARRAY( szActualTask ) );
// Parse the TaskName to remove the .job extension.
szActualTask[lstrlen(szActualTask ) - lstrlen(JOB) ] = NULL_CHAR;
StrTrim( szActualTask, TRIM_SPACES );
CHString strTemp;
strTemp = varScheduledTaskName.bstrVal;
if( lstrcmpi( szActualTask, strTemp ) == 0 )
{
hRes = pITaskScheduler->Activate( szActualTask, IID_ITask, (IUnknown**) &pITask );
if( SUCCEEDED( hRes ) )
{
LPWSTR lpwszUser = NULL;
hRes = pITask->GetAccountInformation( &lpwszUser );
if( SUCCEEDED( hRes ) )
{
szRunAsUser = ( LPWSTR ) lpwszUser;
}
}
}
CoTaskMemFree( lpwszNames[ dwFetchedTasks ] );
}//end while
CoTaskMemFree( lpwszNames );
}
pIEnum->Release();
}
catch(_com_error& e)
{
return hRes;
}
catch( CHeap_Exception )
{
return E_OUTOFMEMORY;
}
return hRes;
}
//***************************************************************************
// Routine Description:
// This routine validates input parameters trigger name,
// Trigger Query, Trigger Desc, Trigger Action.
//
// Arguments:
// varTrigName [in]: Trigger Name.
// varTrigAction [in] : Trigger Action.
// varTrigQuery [in] : Trigger Query.
//
// Return Value:
// WBEM_S_NO_ERROR if successful.
// WBEM_E_INVALID_PARAMETER if invalid inputs.
//***************************************************************************
HRESULT CTriggerProvider::ValidateParams( VARIANT varTrigName,
VARIANT varTrigAction,
VARIANT varTrigQuery )
{
//local variables
HRESULT hRes = 0;
IEnumWbemClassObject *pINTEConsumer = NULL;
DWORD dwReturned = 0;
DWORD dwFlag = 0;
TCHAR szTemp[MAX_RES_STRING1];
TCHAR szTemp1[MAX_RES_STRING1];
LPTSTR lpSubStr = NULL;
try
{
CHString strTemp = NULL_STRING;
//check if input values are null
if ( varTrigName.vt == VT_NULL )
{
return ( WBEM_E_INVALID_PARAMETER );
}
if ( varTrigAction.vt == VT_NULL )
{
return ( WBEM_E_INVALID_PARAMETER );
}
if( varTrigQuery.vt == VT_NULL )
{
return ( WBEM_E_INVALID_PARAMETER );
}
//validate trigger name
strTemp = (LPCWSTR) _bstr_t(varTrigName.bstrVal);
dwReturned = strTemp.FindOneOf( L"[]:|<>+=;,?$#{}~^'@`!()*%\\/" );
if( dwReturned != -1 )
{
return ( WBEM_E_INVALID_PARAMETER );
}
//validate trigger query
memset( szTemp, 0, sizeof( szTemp ) );
memset( szTemp1, 0, sizeof( szTemp1 ) );
strTemp = (LPCWSTR) _bstr_t(varTrigQuery.bstrVal);
GetCompatibleStringFromUnicode( ( LPCWSTR )strTemp, szTemp, MAX_RES_STRING1 );
lpSubStr = _tcsstr( szTemp, _T( "__instancecreationevent where targetinstance isa \"win32_ntlogevent\"" ) );
if( lpSubStr == NULL )
{
return ( WBEM_E_INVALID_PARAMETER );
}
//make the SQL staements to query trigger event consumer class to check whether
//an instance with the inputted trigger is already exists
strTemp = (LPCWSTR) _bstr_t(varTrigName.bstrVal);
memset( szTemp, 0, sizeof( szTemp ) );
GetCompatibleStringFromUnicode( (LPCWSTR)strTemp, szTemp, MAX_RES_STRING1 );
wsprintf(szTemp1, CONSUMER_QUERY, szTemp );
//query triggereventconsumer class
hRes = m_pServices->ExecQuery( QUERY_LANGUAGE, _bstr_t( szTemp1 ),
WBEM_FLAG_RETURN_IMMEDIATELY| WBEM_FLAG_FORWARD_ONLY, NULL,
&pINTEConsumer );
//enumerate the result set of execquery for trigger name
dwReturned = 1;
if ( hRes == WBEM_S_NO_ERROR )
{
while ( ( dwReturned == 1 ) && ( dwFlag == 0 ) )
{
IWbemClassObject *pINTCons = NULL;
// Enumerate through the resultset.
hRes = pINTEConsumer->Next( WBEM_INFINITE,
1, // return just one service
&pINTCons, // pointer to service
&dwReturned ); // number obtained: one or zero
if ( SUCCEEDED( hRes ) && ( dwReturned == 1 ) )
{
SAFERELEASE( pINTCons );
dwFlag = 1;
} // If Service Succeeded
}
SAFERELEASE( pINTEConsumer );
}
if( dwFlag == 1 )
{
return ERROR_TRIGNAME_ALREADY_EXIST;
}
else
{
return WBEM_S_NO_ERROR;
}
}
catch(_com_error& e)
{
return hRes;
}
catch( CHeap_Exception )
{
return E_OUTOFMEMORY;
}
//return WBEM_S_NO_ERROR;
}
//***************************************************************************
// Routine Description:
// This routine creates task scheduler.
//
// Arguments:
// varTName [in] : Trigger Name.
// varRUser [in] : User name.
// varRPwd [in] : Password.
// varTAction [in] : TriggerAction.
// szscheduler [in] : Task scheduler name.
//
// Return Value:
// Returns HRESULT value.
//***************************************************************************
HRESULT CTriggerProvider::SetUserContext( VARIANT varRUser, VARIANT varRPwd,
VARIANT varTAction, CHString &szscheduler )
{
HRESULT hRes = 0;
ITaskScheduler *pITaskScheduler = NULL;
ITaskTrigger *pITaskTrig = NULL;
ITask *pITask = NULL;
IPersistFile *pIPF = NULL;
try
{
CHString strTemp = NULL_STRING;
CHString strTemp1 = NULL_STRING;
SYSTEMTIME systime = {0,0,0,0,0,0,0,0};
WORD wTrigNumber = 0;
WCHAR wszCommand[ MAX_STRING_LENGTH ] = NULL_STRING;
WCHAR wszApplName[ MAX_STRING_LENGTH ] = NULL_STRING;
WCHAR wszParams[ MAX_STRING_LENGTH ] = L"";
WORD wStartDay = 0;
WORD wStartMonth = 0;
WORD wStartYear = 0;
WORD wStartHour = 0;
WORD wStartMin = 0;
TASK_TRIGGER TaskTrig;
ZeroMemory(&TaskTrig, sizeof (TASK_TRIGGER));
TaskTrig.cbTriggerSize = sizeof (TASK_TRIGGER);
TaskTrig.Reserved1 = 0; // reserved field and must be set to 0.
TaskTrig.Reserved2 = 0; // reserved field and must be set to 0.
strTemp = (LPCWSTR) _bstr_t(varTAction.bstrVal);
if( GetAsUnicodeString( (LPCWSTR) strTemp, wszCommand, SIZE_OF_ARRAY( wszCommand ) ) == NULL )
{
return E_FAIL;
}
pITaskScheduler = GetTaskScheduler( );
if ( pITaskScheduler == NULL )
{
return E_FAIL;
}
hRes = pITaskScheduler->NewWorkItem( szscheduler, CLSID_CTask, IID_ITask,
( IUnknown** )&pITask );
if( FAILED( hRes ) )
{
return hRes;
}
hRes = pITask->QueryInterface( IID_IPersistFile, ( void ** ) &pIPF );
if ( FAILED( hRes ) )
{
SAFERELEASE( pIPF );
SAFERELEASE( pITask );
return hRes;
}
BOOL bRet = ProcessFilePath( wszCommand, wszApplName, wszParams );
if( bRet == FALSE )
{
SAFERELEASE( pIPF );
SAFERELEASE( pITask );
return WBEM_E_INVALID_PARAMETER;
}
hRes = pITask->SetApplicationName( wszApplName );
if ( FAILED( hRes ) )
{
SAFERELEASE( pIPF );
SAFERELEASE( pITask );
return hRes;
}
wchar_t* wcszStartIn = wcsrchr( wszApplName, _T('\\') );
if( wcszStartIn != NULL )
*( wcszStartIn ) = _T( '\0' );
hRes = pITask->SetWorkingDirectory( wszApplName );
if ( FAILED( hRes ) )
{
SAFERELEASE( pIPF );
SAFERELEASE( pITask );
return hRes;
}
hRes = pITask->SetParameters( wszParams );
if ( FAILED( hRes ) )
{
SAFERELEASE( pIPF );
SAFERELEASE( pITask );
return hRes;
}
DWORD dwMaxRunTimeMS = INFINITE;
hRes = pITask->SetMaxRunTime(dwMaxRunTimeMS);
if ( FAILED( hRes ) )
{
SAFERELEASE( pIPF );
SAFERELEASE( pITask );
return hRes;
}
if( varRUser.vt != VT_NULL && varRUser.vt != VT_EMPTY )
{
strTemp = (LPCWSTR)_bstr_t(varRUser.bstrVal);
strTemp1 = (LPCWSTR)_bstr_t(varRPwd.bstrVal);
hRes = pITask->SetAccountInformation( ( LPCWSTR ) strTemp, ( LPCWSTR )strTemp1 );
}
else
{
strTemp = (LPCWSTR)_bstr_t(varRUser.bstrVal);
hRes = pITask->SetAccountInformation( ( LPCWSTR )strTemp, NULL_STRING );
}
if ( FAILED( hRes ) )
{
SAFERELEASE( pIPF );
SAFERELEASE( pITask );
return hRes;
}
GetLocalTime(&systime);
wStartDay = systime.wDay;
wStartMonth = systime.wMonth;
wStartYear = systime.wYear - 1;
GetLocalTime(&systime);
wStartHour = systime.wHour;
wStartMin = systime.wMinute;
hRes = pITask->CreateTrigger( &wTrigNumber, &pITaskTrig );
if ( FAILED( hRes ) )
{
SAFERELEASE( pIPF );
SAFERELEASE( pITask );
SAFERELEASE( pITaskTrig );
return hRes;
}
TaskTrig.TriggerType = TASK_TIME_TRIGGER_ONCE;
TaskTrig.wStartHour = wStartHour;
TaskTrig.wStartMinute = wStartMin;
TaskTrig.wBeginDay = wStartDay;
TaskTrig.wBeginMonth = wStartMonth;
TaskTrig.wBeginYear = wStartYear;
hRes = pITaskTrig->SetTrigger( &TaskTrig );
if ( FAILED( hRes ) )
{
SAFERELEASE( pIPF );
SAFERELEASE( pITask );
SAFERELEASE( pITaskTrig );
return hRes;
}
hRes = pIPF->Save( NULL,TRUE );
SAFERELEASE( pIPF );
SAFERELEASE( pITask );
SAFERELEASE( pITaskTrig );
}
catch(_com_error& e)
{
return hRes;
}
catch( CHeap_Exception )
{
return E_OUTOFMEMORY;
}
return hRes;
}
//***************************************************************************
// Routine Description:
// This routine deletes task scheduler.
//
// Arguments:
// szTScheduler [in] : Task Scheduler name.
//
// Return Value:
// Returns HRESULT value.
//***************************************************************************
HRESULT CTriggerProvider::DeleteTaskScheduler( CHString strTScheduler )
{
HRESULT hRes = 0;
ITaskScheduler *pITaskScheduler = NULL;
IEnumWorkItems *pIEnum = NULL;
LPWSTR *lpwszNames = NULL;
DWORD dwFetchedTasks = 0;
TCHAR szActualTask[MAX_RES_STRING1] = NULL_STRING;
try
{
pITaskScheduler = GetTaskScheduler();
if ( pITaskScheduler == NULL )
{
return E_FAIL;
}
// Enumerate the Work Items
hRes = pITaskScheduler->Enum( &pIEnum );
if( FAILED( hRes ) )
{
SAFERELEASE( pIEnum );
return hRes;
}
while ( SUCCEEDED( pIEnum->Next( 1,
&lpwszNames,
&dwFetchedTasks ) )
&& (dwFetchedTasks != 0))
{
while (dwFetchedTasks)
{
// Check whether the TaskName is present, if present
// then return arrJobs.
// Convert the Wide Charater to Multi Byte value.
if ( GetCompatibleStringFromUnicode( lpwszNames[ --dwFetchedTasks ],
szActualTask,
SIZE_OF_ARRAY( szActualTask ) ) == NULL )
{
CoTaskMemFree( lpwszNames[ dwFetchedTasks] );
SAFERELEASE( pIEnum );
return hRes;
}
// Parse the TaskName to remove the .job extension.
szActualTask[lstrlen(szActualTask ) - lstrlen(JOB) ] = NULL_CHAR;
StrTrim( szActualTask, TRIM_SPACES );
if( lstrcmpi( szActualTask, strTScheduler ) == 0 )
{
hRes = pITaskScheduler->Delete( szActualTask );
CoTaskMemFree( lpwszNames[ dwFetchedTasks ] );
SAFERELEASE( pIEnum );
return hRes;
}
}//end while
}
}
catch(_com_error& e)
{
return hRes;
}
return ERROR_TRIGGER_NOT_DELETED;
}
//***************************************************************************
// Routine Description:
// This routine gets task scheduler interface.
//
// Arguments:
// none.
//
// Return Value:
// Returns ITaskScheduler interface.
//***************************************************************************
ITaskScheduler* CTriggerProvider::GetTaskScheduler()
{
HRESULT hRes = S_OK;
ITaskScheduler *pITaskScheduler = NULL;
hRes = CoCreateInstance( CLSID_CTaskScheduler, NULL, CLSCTX_ALL,
IID_ITaskScheduler,(LPVOID*) &pITaskScheduler );
if( FAILED(hRes))
{
return NULL;
}
hRes = pITaskScheduler->SetTargetComputer( NULL );
return pITaskScheduler;
}
//***************************************************************************
// Routine Description:
// This routine generates unique task scheduler name.
//
// Arguments:
// szScheduler [in\out] : Unique task scheduler name.
// dwTrigID [in] : Trigger id.
// varTrigName [in] : Trigger name.
//
// Return Value:
// none.
//***************************************************************************
VOID CTriggerProvider::GetUniqueTScheduler( CHString& szScheduler, DWORD dwTrigID, VARIANT varTrigName )
{
DWORD dwTickCount = 0;
TCHAR szTaskName[ MAX_RES_STRING1 ] = NULL_STRING;
CHString strTemp = NULL_STRING;
strTemp = (LPCWSTR)_bstr_t(varTrigName.bstrVal);
dwTickCount = GetTickCount();
wsprintf( szTaskName, UNIQUE_TASK_NAME, ( LPCWSTR )strTemp, dwTrigID, dwTickCount );
szScheduler = szTaskName;
}
//***************************************************************************
// Routine Description:
// When Windows Management needs to deliver events to a
// particular logical consumer, it will call the
// IWbemEventConsumerProvider::FindConsumer method so that
// the consumer provider can locate the associated consumer event sink.
//
// Arguments:
// pLogicalConsumer [in] : Pointer to the logical consumer object
// to which the event objects are to be delivered.
// ppConsumer [out]: Returns an event object sink to Windows
// Management. Windows Management calls
// AddRef for this pointer and deliver the
// events associated with the logical
// consumer to this sink.
//
// Return Value:
// returns an HRESULT object that indicates the status of the method call.
//***************************************************************************
STDMETHODIMP CTriggerProvider::FindConsumer( IWbemClassObject* pLogicalConsumer,
IWbemUnboundObjectSink** ppConsumer )
{
// create the logical consumer.
CTriggerConsumer* pSink = new CTriggerConsumer();
// return it's "sink" interface.
return pSink->QueryInterface( IID_IWbemUnboundObjectSink, ( LPVOID* ) ppConsumer );
}