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.
2062 lines
69 KiB
2062 lines
69 KiB
/*++
|
|
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;
|
|
|
|
// holds the value of the next trigger id
|
|
#pragma data_seg(".ProviderSeg")
|
|
_declspec(dllexport) DWORD m_dwNextTriggerID = 0;
|
|
#pragma data_seg()
|
|
|
|
|
|
CTriggerProvider::CTriggerProvider(
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
Constructor for CTriggerProvider class for initialization.
|
|
|
|
Arguments:
|
|
None.
|
|
|
|
Return Value:
|
|
None.
|
|
--*/
|
|
{
|
|
// 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;
|
|
m_MaxTriggers = FALSE;
|
|
}
|
|
|
|
CTriggerProvider::~CTriggerProvider(
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
Destructor for CTriggerProvider class.
|
|
|
|
Arguments:
|
|
None.
|
|
|
|
Return Value:
|
|
None.
|
|
--*/
|
|
{
|
|
// 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 ( NULL != m_pwszLocale )
|
|
{
|
|
delete [] m_pwszLocale;
|
|
}
|
|
// update the no. of provider instances count
|
|
InterlockedDecrement( ( LPLONG ) &g_dwInstances );
|
|
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CTriggerProvider::QueryInterface(
|
|
IN REFIID riid,
|
|
OUT LPVOID* ppv
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
Returns a pointer to a specified interface on an object
|
|
to which a client currently holds an interface pointer.
|
|
|
|
Arguments:
|
|
[IN] riid : Identifier of the interface being requested.
|
|
[OUT] ppv : 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.
|
|
--*/
|
|
{
|
|
// initialy set to NULL
|
|
*ppv = NULL;
|
|
|
|
// check whether interface requested is one we have
|
|
if ( IID_IUnknown == riid )
|
|
{
|
|
// need IUnknown interface
|
|
*ppv = this;
|
|
}
|
|
else if ( IID_IWbemEventConsumerProvider == riid )
|
|
{
|
|
// need IEventConsumerProvider interface
|
|
*ppv = static_cast<IWbemEventConsumerProvider*>( this );
|
|
}
|
|
else if ( IID_IWbemServices == riid )
|
|
{
|
|
// need IWbemServices interface
|
|
*ppv = static_cast<IWbemServices*>( this );
|
|
}
|
|
else if ( IID_IWbemProviderInit == riid )
|
|
{
|
|
// 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
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG)
|
|
CTriggerProvider::AddRef(
|
|
void
|
|
)
|
|
/*++
|
|
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.
|
|
--*/
|
|
{
|
|
// increment the reference count ... thread safe
|
|
return InterlockedIncrement( ( LPLONG ) &m_dwCount );
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG)
|
|
CTriggerProvider::Release(
|
|
void
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
The Release method decreases the reference count of the object by 1.
|
|
|
|
Arguments:
|
|
none.
|
|
|
|
Return Value:
|
|
Returns the new reference count.
|
|
--*/
|
|
{
|
|
// 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 ( 0 == dwCount )
|
|
{
|
|
// free the current factory instance
|
|
delete this;
|
|
}
|
|
|
|
// return the no. of instances references left
|
|
return dwCount;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CTriggerProvider::Initialize(
|
|
IN LPWSTR wszUser,
|
|
IN LONG lFlags,
|
|
IN LPWSTR wszNamespace,
|
|
IN LPWSTR wszLocale,
|
|
IN IWbemServices* pNamespace,
|
|
IN IWbemContext* pCtx,
|
|
OUT IWbemProviderInitSink* pInitSink )
|
|
/*++
|
|
Routine Description:
|
|
This is the implemention of IWbemProviderInit. The
|
|
method is need to initialize with CIMOM.
|
|
|
|
Arguments:
|
|
[IN] wszUser : pointer to user name.
|
|
[IN] lFlags : Reserved.
|
|
[IN] wszNamespace : contains the namespace of WMI.
|
|
[IN] wszLocale : Locale Name.
|
|
[IN] pNamespace : pointer to IWbemServices.
|
|
[IN] pCtx : IwbemContext pointer associated for initialization.
|
|
[OUT] pInitSink : a pointer to IWbemProviderInitSink for
|
|
reporting the initialization status.
|
|
|
|
Return Value:
|
|
returns HRESULT value.
|
|
--*/
|
|
{
|
|
HRESULT hRes = 0;
|
|
IEnumWbemClassObject *pINTEConsumer = NULL;
|
|
DWORD dwReturned = 0;
|
|
DWORD dwTrigId = 0;
|
|
VARIANT varTrigId;
|
|
DWORD i = 0;
|
|
|
|
if( ( NULL == pNamespace ) || ( NULL == pInitSink ) )
|
|
{
|
|
// return failure
|
|
return WBEM_E_FAILED;
|
|
}
|
|
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 ( NULL != pCtx )
|
|
{
|
|
m_pContext = pCtx;
|
|
m_pContext->AddRef();
|
|
}
|
|
|
|
// save the locale information ( if exist )
|
|
if ( NULL != wszLocale )
|
|
{
|
|
m_pwszLocale = new WCHAR [ StringLength( wszLocale, 0 ) + 1 ];
|
|
if ( NULL == m_pwszLocale )
|
|
{
|
|
// 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 ( 0 != dwReturned )
|
|
{
|
|
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 ) )
|
|
{
|
|
if( m_dwNextTriggerID >= MAX_TRIGGEID_VALUE )
|
|
{
|
|
hRes = WBEM_E_FAILED;
|
|
}
|
|
else
|
|
{
|
|
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 e.Error();
|
|
}
|
|
return hRes;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CTriggerProvider::ExecMethodAsync(
|
|
IN const BSTR bstrObjectPath,
|
|
IN const BSTR bstrMethodName,
|
|
IN long lFlags,
|
|
IN IWbemContext* pICtx,
|
|
IN IWbemClassObject* pIInParams,
|
|
OUT IWbemObjectSink* pIResultSink
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
This is the Async function implementation.
|
|
The methods supported is named CreateETrigger and DeleteETrigger.
|
|
|
|
Arguments:
|
|
[IN] bstrObjectPath : path of the object for which the method is executed.
|
|
[IN] bstrMethodName : Name of the method for the object.
|
|
[IN] lFlags : WBEM_FLAG_SEND_STATUS.
|
|
[IN] pICtx : a pointer to IWbemContext.
|
|
[IN] pIInParams : this points to an IWbemClassObject object
|
|
that contains the properties acting as
|
|
inbound parameters for method execution.
|
|
[OUT] pIResultSink : The object sink receives the result of the method call.
|
|
|
|
Return Value:
|
|
returns HRESULT.
|
|
--*/
|
|
{
|
|
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;
|
|
LPTSTR lpResStr = NULL;
|
|
try
|
|
{
|
|
//set out parameters
|
|
hRes = m_pServices->GetObject( _bstr_t( 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( ( StringCompare( bstrMethodName, CREATE_METHOD_NAME, TRUE, 0 ) == 0 ) ||
|
|
( StringCompare( bstrMethodName, CREATE_METHOD_NAME_EX, TRUE, 0 ) == 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 ) )
|
|
{
|
|
hRes = pIInParams->Get( IN_TRIGGER_USER, 0, &varRUser, NULL, NULL );
|
|
if( SUCCEEDED( hRes ) )
|
|
{
|
|
EnterCriticalSection( &g_critical_sec );
|
|
hRes = ValidateParams( varTriggerName, varTriggerAction,
|
|
varTriggerQuery, varRUser );
|
|
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 );
|
|
// changed on 07/12/02 to send error instead of warning if account info not set
|
|
if( ( SUCCEEDED( hRes ) ) || ( ERROR_TASK_SCHDEULE_SERVICE_STOP == hRes1 ) )
|
|
{
|
|
// increment the class member variable by one to get the new unique trigger id
|
|
//for the next instance
|
|
if( MAX_TRIGGEID_VALUE > m_dwNextTriggerID )
|
|
{
|
|
m_dwNextTriggerID = m_dwNextTriggerID + 1;
|
|
}
|
|
else
|
|
{
|
|
m_MaxTriggers = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
LeaveCriticalSection( &g_critical_sec );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
VariantClear( &varTriggerAction );
|
|
VariantClear( &varRUser );
|
|
VariantClear( &varRPwd );
|
|
VariantClear( &varTriggerDesc );
|
|
VariantClear( &varTriggerQuery );
|
|
}
|
|
else if( ( StringCompare( bstrMethodName, DELETE_METHOD_NAME, TRUE, 0 ) == 0 ) ||
|
|
( StringCompare( bstrMethodName, DELETE_METHOD_NAME_EX, TRUE, 0 ) == 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( ( StringCompare( bstrMethodName, QUERY_METHOD_NAME, TRUE, 0 ) == 0 ) ||
|
|
( StringCompare( bstrMethodName, QUERY_METHOD_NAME_EX, TRUE, 0 ) == 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 = L"";
|
|
hRes = CoImpersonateClient();
|
|
if( SUCCEEDED( hRes ) )
|
|
{
|
|
varRUser.vt = VT_BSTR;
|
|
varRUser.bstrVal = SysAllocString( L"" );
|
|
hRes = pIOutParams->Put( OUT_RUNAS_USER , 0, &varRUser, 0 );
|
|
VariantClear( &varRUser );
|
|
if( SUCCEEDED( hRes ) )
|
|
{
|
|
hRes = QueryTrigger( varScheduledTaskName, szRunAsUser );
|
|
if( SUCCEEDED( hRes ) )
|
|
{
|
|
VariantInit( &varRUser );
|
|
varRUser.vt = VT_BSTR;
|
|
varRUser.bstrVal = SysAllocString( szRunAsUser );
|
|
hRes = pIOutParams->Put( OUT_RUNAS_USER , 0, &varRUser, 0 );
|
|
}
|
|
}
|
|
}
|
|
CoRevertToSelf();
|
|
LeaveCriticalSection( &g_critical_sec );
|
|
}
|
|
VariantClear( &varScheduledTaskName );
|
|
VariantClear( &varRUser );
|
|
}
|
|
else
|
|
{
|
|
hRes = WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
if( ( StringCompare( bstrMethodName, CREATE_METHOD_NAME, TRUE, 0 ) == 0 ) ||
|
|
( StringCompare( bstrMethodName, CREATE_METHOD_NAME_EX, TRUE, 0 ) == 0 ) )
|
|
{
|
|
lpResStr = ( LPTSTR ) AllocateMemory( MAX_RES_STRING1 );
|
|
|
|
if ( lpResStr != NULL )
|
|
{
|
|
// changed on 07/12/02 to log error if account info is not set instead of success
|
|
if( ( SUCCEEDED( hRes ) ) || ( ERROR_TASK_SCHDEULE_SERVICE_STOP == hRes1 ) )
|
|
{
|
|
LoadStringW( g_hModule, IDS_CREATED, lpResStr, GetBufferSize(lpResStr)/sizeof(WCHAR) );
|
|
if( hRes1 != NO_ERROR )// write invalid user into log file
|
|
{
|
|
LPTSTR lpResStr1 = NULL;
|
|
lpResStr1 = ( LPTSTR ) AllocateMemory( MAX_RES_STRING1 );
|
|
if ( lpResStr1 != NULL )
|
|
{
|
|
if( hRes1 == ERROR_TASK_SCHDEULE_SERVICE_STOP )
|
|
{
|
|
hRes = WBEM_S_NO_ERROR;
|
|
LoadStringW( g_hModule,IDS_INFO_SERVICE_STOPPED, lpResStr1, GetBufferSize(lpResStr1)/sizeof(WCHAR) );
|
|
StringConcat( lpResStr, lpResStr1, GetBufferSize(lpResStr)/sizeof(WCHAR) );
|
|
}
|
|
FreeMemory( (LPVOID*)&lpResStr1 );
|
|
}
|
|
}
|
|
ErrorLog( lpResStr, ( LPWSTR )_bstr_t( varTriggerName ), ( m_dwNextTriggerID - 1 ) );
|
|
}
|
|
else
|
|
{
|
|
LoadStringW( g_hModule, IDS_CREATE_FAILED, lpResStr, GetBufferSize(lpResStr)/sizeof(WCHAR) );
|
|
ErrorLog( lpResStr, ( LPWSTR )_bstr_t( varTriggerName ), ( m_dwNextTriggerID - 1 ) );
|
|
}
|
|
FreeMemory( (LPVOID*)&lpResStr );
|
|
}
|
|
else
|
|
{
|
|
hRes = E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
else if( ( StringCompare( bstrMethodName, DELETE_METHOD_NAME, TRUE, 0 ) == 0 ) ||
|
|
( StringCompare( bstrMethodName, DELETE_METHOD_NAME_EX, TRUE, 0 ) == 0 ) )
|
|
{
|
|
lpResStr = ( LPTSTR ) AllocateMemory( MAX_RES_STRING1 );
|
|
|
|
if ( lpResStr != NULL )
|
|
{
|
|
if(( SUCCEEDED( hRes ) ) )
|
|
{
|
|
LoadStringW( g_hModule, IDS_DELETED, lpResStr, GetBufferSize(lpResStr)/sizeof(WCHAR) );
|
|
ErrorLog( lpResStr, ( LPWSTR )_bstr_t( varTriggerName ), dwTrigId );
|
|
}
|
|
else
|
|
{
|
|
LoadStringW( g_hModule, IDS_DELETE_FAILED, lpResStr, GetBufferSize(lpResStr)/sizeof(WCHAR) );
|
|
ErrorLog( lpResStr,( LPWSTR )_bstr_t( varTriggerName ), dwTrigId );
|
|
}
|
|
FreeMemory( (LPVOID*)&lpResStr );
|
|
|
|
}
|
|
else
|
|
{
|
|
hRes = E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
|
|
VariantClear( &varTriggerName );
|
|
VariantInit( &varTemp );
|
|
V_VT( &varTemp ) = VT_I4;
|
|
|
|
if ( NO_ERROR != hRes1 )
|
|
{
|
|
if( StringCompare( bstrMethodName, CREATE_METHOD_NAME, TRUE, 0 ) == 0 )
|
|
{
|
|
V_I4( &varTemp ) = WARNING_INVALID_USER;
|
|
}
|
|
else
|
|
{
|
|
V_I4( &varTemp ) = hRes1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( StringCompare( bstrMethodName, CREATE_METHOD_NAME, TRUE, 0 ) == 0 )
|
|
{
|
|
if ( hRes == ERROR_TRIGNAME_ALREADY_EXIST_EX )
|
|
{
|
|
hRes = ( HRESULT )ERROR_TRIGNAME_ALREADY_EXIST;
|
|
}
|
|
}
|
|
if( StringCompare( bstrMethodName, DELETE_METHOD_NAME, TRUE, 0 ) == 0 )
|
|
{
|
|
if ( hRes == ERROR_TRIGGER_NOT_FOUND_EX )
|
|
{
|
|
hRes = ( HRESULT )ERROR_TRIGGER_NOT_FOUND;
|
|
}
|
|
if ( hRes == ERROR_TRIGGER_NOT_DELETED_EX )
|
|
{
|
|
hRes = ( HRESULT )ERROR_TRIGGER_NOT_DELETED;
|
|
}
|
|
}
|
|
if( StringCompare( bstrMethodName, QUERY_METHOD_NAME, TRUE, 0 ) == 0 )
|
|
{
|
|
if ( hRes == ERROR_TRIGGER_CORRUPTED_EX )
|
|
{
|
|
hRes = WBEM_NO_ERROR;
|
|
}
|
|
if ( hRes == ERROR_INVALID_USER_EX )
|
|
{
|
|
hRes = WBEM_NO_ERROR;
|
|
}
|
|
}
|
|
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)
|
|
{
|
|
VariantClear( &varTriggerName );
|
|
FREESTRING( lpResStr );
|
|
SAFERELEASE( pIOutParams );
|
|
pIResultSink->SetStatus( 0, hRes, NULL, NULL );
|
|
return e.Error();
|
|
}
|
|
catch( CHeap_Exception )
|
|
{
|
|
VariantClear( &varTriggerName );
|
|
FREESTRING( lpResStr );
|
|
SAFERELEASE( pIOutParams );
|
|
hRes = E_OUTOFMEMORY;
|
|
pIResultSink->SetStatus( 0, hRes, NULL, NULL );
|
|
return hRes;
|
|
}
|
|
|
|
return hRes;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CTriggerProvider::CreateTrigger(
|
|
IN VARIANT varTName,
|
|
IN VARIANT varTDesc,
|
|
IN VARIANT varTAction,
|
|
IN VARIANT varTQuery,
|
|
IN VARIANT varRUser,
|
|
IN VARIANT varRPwd,
|
|
OUT HRESULT *phRes
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
This routine creates the instance of TriggerEventConsumer,
|
|
__EventFilter and __FilterToConsumerBinding classes.
|
|
|
|
Arguments:
|
|
[IN] varTName : Trigger Name.
|
|
[IN] VarTDesc : Trigger Description.
|
|
[IN] varTAction : Trigger Action.
|
|
[IN] varTQuery : Trigger Query.
|
|
[IN] varRUser : Run as user name.
|
|
[IN] varRPwd : Run as Password.
|
|
[OUT] phRes : Return value of scedule task creation.
|
|
Return Value:
|
|
S_OK if successful.
|
|
Otherwise failure error code.
|
|
--*/
|
|
{
|
|
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
|
|
SecureZeroMemory( szTemp, MAX_RES_STRING1 * sizeof( TCHAR ) );
|
|
SecureZeroMemory( szTemp1, MAX_RES_STRING1 * sizeof( TCHAR ) );
|
|
SecureZeroMemory( szFName, MAX_RES_STRING1 * sizeof( TCHAR ) );
|
|
VariantInit( &varTemp );
|
|
if ( NULL != phRes )
|
|
{
|
|
*phRes = S_OK;
|
|
}
|
|
|
|
// changed on 07/12/02 just moved the block of code
|
|
/**************************************************************************
|
|
|
|
CREATING TriggerEventConsumer INSTANCE
|
|
|
|
***************************************************************************/
|
|
|
|
//get NTEventConsumer class object
|
|
hRes =m_pServices->GetObject( _bstr_t( CONSUMER_CLASS ), 0, 0, &pINtLogEventClass, NULL );
|
|
|
|
//if unable to get the object of TriggerEventConsumer return error
|
|
if( FAILED( hRes ) )
|
|
{
|
|
SAFERELEASE( pINtLogEventClass );// safer side
|
|
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( pINewInstance );
|
|
return hRes;
|
|
}
|
|
|
|
//get the unique trigger id by enumerating CmdTriggerConsumer class. if there are no triggers then
|
|
// intialize the trigger id to 1
|
|
|
|
hRes = m_pServices->ExecQuery( _bstr_t( QUERY_LANGUAGE ), _bstr_t( INSTANCE_EXISTS_QUERY ),
|
|
WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pIEnumClassObject );
|
|
if( FAILED( hRes ) )
|
|
{
|
|
SAFERELEASE( pIEnumClassObject );
|
|
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( 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( 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( 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( pINewInstance );
|
|
return hRes;
|
|
}
|
|
|
|
CHString szScheduler = L"";
|
|
CHString szRUser = (LPCWSTR)_bstr_t(varRUser.bstrVal);
|
|
{
|
|
do
|
|
{
|
|
GetUniqueTScheduler( szScheduler, m_dwNextTriggerID, varTName );
|
|
hRes = CoImpersonateClient();
|
|
if( FAILED( hRes ) )
|
|
{
|
|
SAFERELEASE( pINewInstance );
|
|
return hRes;
|
|
}
|
|
hRes = SetUserContext( varRUser, varRPwd, varTAction, szScheduler );
|
|
CoRevertToSelf();
|
|
if( HRESULT_FROM_WIN32 (ERROR_FILE_EXISTS ) != hRes )
|
|
{
|
|
break;
|
|
}
|
|
}while( 1 );
|
|
if( FAILED( hRes ) )
|
|
{
|
|
// changed on 07/12/02 not to handle user info not set as warning but as error
|
|
if( hRes == ERROR_TASK_SCHDEULE_SERVICE_STOP ) //to send a warning msg to client
|
|
{
|
|
*phRes = hRes;
|
|
}
|
|
else
|
|
{
|
|
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( 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 ) )
|
|
{
|
|
return hRes;
|
|
}
|
|
|
|
//get the current instance for binding it with __FilterToConsumerBinding class
|
|
StringCchPrintf( szTemp, SIZE_OF_ARRAY( 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( pINtLogEventClass );
|
|
return hRes;
|
|
}
|
|
|
|
/**************************************************************************
|
|
|
|
CREATING __EventFilter INSTANCE
|
|
|
|
***************************************************************************/
|
|
// get EventFilter class object
|
|
hRes = m_pServices->GetObject( _bstr_t( FILTER_CLASS ), 0, 0, &pIFilterClass, NULL );
|
|
|
|
if( FAILED( hRes ) )
|
|
{
|
|
SAFERELEASE( pINtLogEventClass );
|
|
SAFERELEASE( pIFilterClass );
|
|
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 ) )
|
|
{
|
|
SAFERELEASE( pINtLogEventClass );
|
|
SAFERELEASE( pINewInstance );
|
|
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( pINtLogEventClass );
|
|
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( pINtLogEventClass );
|
|
SAFERELEASE( pINewInstance );
|
|
return hRes;
|
|
}
|
|
|
|
//generate unique name for name key property of EventFilter class by concatinating
|
|
// current system date and time
|
|
|
|
GetSystemTime( &SysTime );
|
|
StringCchPrintf( szTemp, SIZE_OF_ARRAY( 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( pINtLogEventClass );
|
|
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 ) )
|
|
{
|
|
SAFERELEASE( pINtLogEventClass );
|
|
return hRes;
|
|
}
|
|
|
|
//get the current Eventfilter instance for binding filter to consumer
|
|
StringCchPrintf( szTemp1, SIZE_OF_ARRAY( 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 ) )
|
|
{
|
|
SAFERELEASE( pINtLogEventClass );
|
|
SAFERELEASE( pIFilterClass );
|
|
return hRes;
|
|
}
|
|
|
|
/**************************************************************************
|
|
|
|
BINDING FILTER TO CONSUMER
|
|
|
|
***************************************************************************/
|
|
|
|
// if association class exists...
|
|
if( ( hRes = m_pServices->GetObject( _bstr_t( 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)
|
|
{
|
|
SAFERELEASE( pINewInstance );
|
|
SAFERELEASE( pINtLogEventClass );
|
|
SAFERELEASE( pIFilterClass );
|
|
SAFERELEASE( pIBindClass );
|
|
SAFERELEASE( pIEnumClassObject );
|
|
return e.Error();
|
|
}
|
|
catch( CHeap_Exception )
|
|
{
|
|
SAFERELEASE( pINewInstance );
|
|
SAFERELEASE( pINtLogEventClass );
|
|
SAFERELEASE( pIFilterClass );
|
|
SAFERELEASE( pIBindClass );
|
|
SAFERELEASE( pIEnumClassObject );
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
return hRes;
|
|
}
|
|
|
|
HRESULT
|
|
CTriggerProvider::DeleteTrigger(
|
|
IN VARIANT varTName,
|
|
OUT DWORD *dwTrigId
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
This routine deletes the instance of TriggerEventConsumer,
|
|
__EventFilter and __FilterToConsumerBinding classes.
|
|
|
|
Arguments:
|
|
[IN] varTName : Trigger Name.
|
|
[OUT] dwTrigId : Trigger id.
|
|
|
|
Return Value:
|
|
WBEM_S_NO_ERROR if successful.
|
|
Otherwise failure error code.
|
|
--*/
|
|
{
|
|
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[MAX_RES_STRING1];
|
|
try
|
|
{
|
|
_bstr_t bstrBinInst;
|
|
CHString strTScheduler = L"";
|
|
|
|
SecureZeroMemory( szTemp, MAX_RES_STRING1 * sizeof( TCHAR ) );
|
|
SecureZeroMemory( szTemp1, MAX_RES_STRING1 * sizeof( TCHAR ) );
|
|
SecureZeroMemory( szwFilName, MAX_RES_STRING1 * sizeof( TCHAR ) );
|
|
|
|
StringCchPrintf( szTemp, SIZE_OF_ARRAY( szTemp ), TRIGGER_INSTANCE_NAME, varTName.bstrVal );
|
|
hRes = m_pServices->ExecQuery( _bstr_t( QUERY_LANGUAGE ), _bstr_t( szTemp ),
|
|
WBEM_FLAG_RETURN_IMMEDIATELY| WBEM_FLAG_FORWARD_ONLY, NULL,
|
|
&pIEventBinder );
|
|
|
|
SecureZeroMemory( szTemp, MAX_RES_STRING1 * sizeof( TCHAR ) );
|
|
if( FAILED( hRes ) )
|
|
{
|
|
return hRes;
|
|
}
|
|
while ( ( 1 == dwReturned ) && ( 0 == dwFlag ) )
|
|
{
|
|
// 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 ) && ( 1 == dwReturned ) )
|
|
{
|
|
dwFlag = 1;
|
|
|
|
} // If Service Succeeded
|
|
|
|
}
|
|
SAFERELEASE( pIEventBinder );
|
|
if( 0 == dwFlag )
|
|
{
|
|
SAFERELEASE( pINTCons );
|
|
return ERROR_TRIGGER_NOT_FOUND_EX;
|
|
}
|
|
|
|
VariantInit( &varTemp );
|
|
hRes = pINTCons->Get( TRIGGER_ID, 0, &varTemp, 0, NULL );
|
|
if (FAILED( hRes ) )
|
|
{
|
|
SAFERELEASE( pINTCons );
|
|
return hRes;
|
|
}
|
|
*dwTrigId = ( DWORD )varTemp.lVal;
|
|
VariantClear( &varTemp );
|
|
|
|
hRes = pINTCons->Get( TASK_SHEDULER, 0, &varTemp, 0, NULL );
|
|
if (FAILED( hRes ) )
|
|
{
|
|
SAFERELEASE( pINTCons );
|
|
return hRes;
|
|
}
|
|
SAFERELEASE( pINTCons );
|
|
strTScheduler = (LPCWSTR) _bstr_t(varTemp.bstrVal);
|
|
VariantClear( &varTemp );
|
|
if( strTScheduler.GetLength() > 0 )
|
|
{
|
|
hRes = CoImpersonateClient();
|
|
if( FAILED( hRes ) )
|
|
{
|
|
return hRes;
|
|
}
|
|
dwReturned = 0;
|
|
hRes = DeleteTaskScheduler( strTScheduler );
|
|
if ( FAILED( hRes ) && ( ERROR_TRIGGER_CORRUPTED_EX != hRes ) )
|
|
{
|
|
CoRevertToSelf();
|
|
return hRes;
|
|
}
|
|
hRes = CoRevertToSelf();
|
|
}
|
|
|
|
StringCchPrintf( szTemp, SIZE_OF_ARRAY( 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 ( ( 1 == dwReturned ) && ( 0 == dwFlag ) )
|
|
{
|
|
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 ) && ( 1 == dwReturned ) )
|
|
{
|
|
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( StringCompare( szTemp, strTemp, TRUE, 0 ) == 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( 1 == dwFlag )
|
|
{
|
|
//get the key properties for binding class
|
|
StringCchPrintf( szTemp1, SIZE_OF_ARRAY( 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_FOUND_EX;
|
|
}
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
SAFERELEASE( pINTCons );
|
|
SAFERELEASE( pIEventBinder );
|
|
return e.Error();
|
|
}
|
|
catch( CHeap_Exception )
|
|
{
|
|
SAFERELEASE( pINTCons );
|
|
SAFERELEASE( pIEventBinder );
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
return hRes;
|
|
}
|
|
|
|
HRESULT
|
|
CTriggerProvider::QueryTrigger(
|
|
IN VARIANT varScheduledTaskName,
|
|
OUT CHString &szRunAsUser
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
This routine queries task scheduler for account information
|
|
|
|
Arguments:
|
|
[IN] varScheduledTaskName : Task scheduler name.
|
|
[OUT] szRunAsUser : stores account information.
|
|
|
|
Return Value:
|
|
WBEM_S_NO_ERROR if successful.
|
|
Otherwise failure error code.
|
|
--*/
|
|
{
|
|
|
|
HRESULT hRes = 0;
|
|
ITaskScheduler *pITaskScheduler = NULL;
|
|
IEnumWorkItems *pIEnum = NULL;
|
|
ITask *pITask = NULL;
|
|
|
|
LPWSTR *lpwszNames = NULL;
|
|
DWORD dwFetchedTasks = 0;
|
|
DWORD dwTaskIndex = 0;
|
|
TCHAR szActualTask[MAX_STRING_LENGTH] = NULL_STRING;
|
|
try
|
|
{
|
|
hRes = GetTaskScheduler(&pITaskScheduler);
|
|
if ( FAILED( hRes ) )
|
|
{
|
|
SAFERELEASE( pITaskScheduler );
|
|
return hRes;
|
|
}
|
|
|
|
hRes = pITaskScheduler->SetTargetComputer( NULL );
|
|
if( FAILED( hRes ) )
|
|
{
|
|
SAFERELEASE( pITaskScheduler );
|
|
return hRes;
|
|
}
|
|
hRes = pITaskScheduler->Enum( &pIEnum );
|
|
if( FAILED( hRes ) )
|
|
{
|
|
SAFERELEASE( pITaskScheduler );
|
|
return hRes;
|
|
}
|
|
while ( SUCCEEDED( pIEnum->Next( 1,
|
|
&lpwszNames,
|
|
&dwFetchedTasks ) )
|
|
&& (dwFetchedTasks != 0))
|
|
{
|
|
dwTaskIndex = dwFetchedTasks-1;
|
|
StringCopy( szActualTask, lpwszNames[ --dwFetchedTasks ], SIZE_OF_ARRAY( szActualTask ) );
|
|
// Parse the TaskName to remove the .job extension.
|
|
szActualTask[StringLength( szActualTask, 0 ) - StringLength( JOB, 0 ) ] = NULL_CHAR;
|
|
StrTrim( szActualTask, TRIM_SPACES );
|
|
CHString strTemp;
|
|
strTemp = varScheduledTaskName.bstrVal;
|
|
if( StringCompare( szActualTask, strTemp, TRUE, 0 ) == 0 )
|
|
{
|
|
hRes = pITaskScheduler->Activate(lpwszNames[dwTaskIndex],IID_ITask,
|
|
(IUnknown**) &pITask);
|
|
CoTaskMemFree( lpwszNames[ dwFetchedTasks ] );
|
|
CoTaskMemFree( lpwszNames );
|
|
pIEnum->Release();
|
|
SAFERELEASE( pITaskScheduler );
|
|
if( SUCCEEDED( hRes ) )
|
|
{
|
|
LPWSTR lpwszUser = NULL;
|
|
hRes = pITask->GetAccountInformation( &lpwszUser );
|
|
if( SUCCEEDED( hRes ) )
|
|
{
|
|
if( 0 == StringLength( ( LPWSTR ) lpwszUser, 0 ) )
|
|
{
|
|
szRunAsUser = L"NT AUTHORITY\\SYSTEM";
|
|
}
|
|
else
|
|
{
|
|
szRunAsUser = ( LPWSTR ) lpwszUser;
|
|
}
|
|
SAFERELEASE( pITask );
|
|
return hRes;
|
|
}
|
|
else
|
|
{
|
|
SAFERELEASE( pITask );
|
|
return hRes;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( 0x80070005 == hRes )
|
|
{
|
|
return ERROR_INVALID_USER_EX;
|
|
}
|
|
else
|
|
{
|
|
return hRes;
|
|
}
|
|
}
|
|
}
|
|
CoTaskMemFree( lpwszNames[ dwFetchedTasks ] );
|
|
CoTaskMemFree( lpwszNames );
|
|
}
|
|
pIEnum->Release();
|
|
SAFERELEASE( pITaskScheduler );
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
SAFERELEASE( pITask );
|
|
SAFERELEASE( pITaskScheduler );
|
|
SAFERELEASE( pIEnum );
|
|
return e.Error();
|
|
}
|
|
catch( CHeap_Exception )
|
|
{
|
|
SAFERELEASE( pITask );
|
|
SAFERELEASE( pITaskScheduler );
|
|
SAFERELEASE( pIEnum );
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
return ERROR_TRIGGER_CORRUPTED_EX;
|
|
}
|
|
|
|
HRESULT
|
|
CTriggerProvider::ValidateParams(
|
|
IN VARIANT varTrigName,
|
|
IN VARIANT varTrigAction,
|
|
IN VARIANT varTrigQuery,
|
|
IN VARIANT varRUser
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
This routine validates input parameters trigger name,
|
|
Trigger Query, Trigger Desc, Trigger Action.
|
|
|
|
Arguments:
|
|
[IN] varTrigName : Trigger Name.
|
|
[IN] varTrigAction : Trigger Action.
|
|
[IN] varTrigQuery : Trigger Query.
|
|
[IN] varRUser : Trigger Query.
|
|
|
|
Return Value:
|
|
WBEM_S_NO_ERROR if successful.
|
|
WBEM_E_INVALID_PARAMETER if invalid inputs.
|
|
--*/
|
|
{
|
|
//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;
|
|
LONG lPos = 0;
|
|
try
|
|
{
|
|
CHString strTemp = L"";
|
|
if( TRUE == m_MaxTriggers )
|
|
{
|
|
return ( WBEM_E_INVALID_PARAMETER );
|
|
}
|
|
//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 );
|
|
}
|
|
|
|
if( varRUser.vt == VT_NULL )
|
|
{
|
|
return ( WBEM_E_INVALID_PARAMETER );
|
|
}
|
|
|
|
//validate run as user
|
|
strTemp = (LPCWSTR) _bstr_t(varRUser.bstrVal);
|
|
// user name should not be just '\'
|
|
if ( 0 == strTemp.CompareNoCase( L"\\" ) )
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
// user name should not contain invalid characters
|
|
if ( -1 != strTemp.FindOneOf( L"/[]:|<>+=;,?*" ) )
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
lPos = strTemp.Find( L'\\' );
|
|
if ( -1 != lPos )
|
|
{
|
|
// '\' character exists in the user name
|
|
// strip off the user info upto first '\' character
|
|
// check for one more '\' in the remaining string
|
|
// if it exists, invalid user
|
|
strTemp = strTemp.Mid( lPos + 1 );
|
|
lPos = strTemp.Find( L'\\' );
|
|
if ( -1 != lPos )
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
|
|
//validate trigger action
|
|
strTemp = (LPCWSTR) _bstr_t(varTrigAction.bstrVal);
|
|
if( strTemp.GetLength() > 262 )
|
|
{
|
|
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 );
|
|
}
|
|
|
|
// Triggername cannot be more than 196 characters.
|
|
if( MAX_TRIGGERNAME_LENGTH < strTemp.GetLength() )
|
|
{
|
|
return ( WBEM_E_INVALID_PARAMETER );
|
|
}
|
|
//validate trigger query
|
|
SecureZeroMemory( szTemp, MAX_RES_STRING1 * sizeof( TCHAR ) );
|
|
SecureZeroMemory( szTemp1, MAX_RES_STRING1 * sizeof( TCHAR ) );
|
|
|
|
strTemp = (LPCWSTR) _bstr_t(varTrigQuery.bstrVal);
|
|
StringCopy( szTemp, ( LPCWSTR )strTemp, 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);
|
|
SecureZeroMemory( szTemp, MAX_RES_STRING1 * sizeof( TCHAR ) );
|
|
StringCopy( szTemp, (LPCWSTR)strTemp, MAX_RES_STRING1 );
|
|
|
|
StringCchPrintf(szTemp1, SIZE_OF_ARRAY( szTemp1 ) , CONSUMER_QUERY, szTemp );
|
|
//query triggereventconsumer class
|
|
hRes = m_pServices->ExecQuery( _bstr_t( 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_EX;
|
|
}
|
|
else
|
|
{
|
|
return WBEM_S_NO_ERROR;
|
|
}
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
SAFERELEASE( pINTEConsumer );
|
|
return e.Error();
|
|
}
|
|
catch( CHeap_Exception )
|
|
{
|
|
SAFERELEASE( pINTEConsumer );
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
|
|
HRESULT
|
|
CTriggerProvider::SetUserContext(
|
|
IN VARIANT varRUser,
|
|
IN VARIANT varRPwd,
|
|
IN VARIANT varTAction,
|
|
IN CHString &szscheduler
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
This routine creates task scheduler.
|
|
|
|
Arguments:
|
|
[IN] varRUser : User name.
|
|
[IN] varRPwd : Password.
|
|
[IN] varTAction : TriggerAction.
|
|
[IN] szscheduler : Task scheduler name.
|
|
|
|
Return Value:
|
|
Returns HRESULT value.
|
|
--*/
|
|
{
|
|
HRESULT hRes = 0;
|
|
ITaskScheduler *pITaskScheduler = NULL;
|
|
ITaskTrigger *pITaskTrig = NULL;
|
|
ITask *pITask = NULL;
|
|
IPersistFile *pIPF = NULL;
|
|
try
|
|
{
|
|
CHString strTemp = L"";
|
|
CHString strTemp1 = L"";
|
|
|
|
SYSTEMTIME systime = {0,0,0,0,0,0,0,0};
|
|
WORD wTrigNumber = 0;
|
|
WCHAR wszCommand[ MAX_STRING_LENGTH ] = L"";
|
|
WCHAR wszApplName[ MAX_STRING_LENGTH ] = L"";
|
|
WCHAR wszParams[ MAX_STRING_LENGTH ] = L"";
|
|
WORD wStartDay = 0;
|
|
WORD wStartMonth = 0;
|
|
WORD wStartYear = 0;
|
|
WORD wStartHour = 0;
|
|
WORD wStartMin = 0;
|
|
|
|
TASK_TRIGGER TaskTrig;
|
|
SecureZeroMemory( &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);
|
|
StringCopy( wszCommand, (LPCWSTR) strTemp, SIZE_OF_ARRAY( wszCommand ) );
|
|
|
|
hRes = GetTaskScheduler( &pITaskScheduler );
|
|
if ( FAILED( hRes ) )
|
|
{
|
|
SAFERELEASE( pITaskScheduler );
|
|
return hRes;
|
|
}
|
|
hRes = pITaskScheduler->SetTargetComputer( NULL );
|
|
if( FAILED( hRes ) )
|
|
{
|
|
SAFERELEASE( pITaskScheduler );
|
|
return hRes;
|
|
}
|
|
|
|
hRes = pITaskScheduler->NewWorkItem( szscheduler, CLSID_CTask, IID_ITask,
|
|
( IUnknown** )&pITask );
|
|
SAFERELEASE( pITaskScheduler );
|
|
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;
|
|
}
|
|
if( FindOneOf2( wszApplName, L"|<>?*/", TRUE, 0 ) != -1 )
|
|
{
|
|
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;
|
|
}
|
|
|
|
strTemp = (LPCWSTR)_bstr_t(varRUser.bstrVal);
|
|
if( strTemp.CompareNoCase(L"system") == 0 )
|
|
{
|
|
hRes = pITask->SetAccountInformation(L"",NULL);
|
|
}
|
|
else if( strTemp.CompareNoCase(L"NT AUTHORITY\\SYSTEM") == 0 )
|
|
{
|
|
hRes = pITask->SetAccountInformation(L"",NULL);
|
|
}
|
|
else if( strTemp.CompareNoCase(L"") == 0 )
|
|
{
|
|
hRes = pITask->SetAccountInformation(L"",NULL);
|
|
}
|
|
else
|
|
{
|
|
strTemp1 = (LPCWSTR)_bstr_t(varRPwd.bstrVal);
|
|
hRes = pITask->SetAccountInformation( ( LPCWSTR ) strTemp, ( LPCWSTR )strTemp1 );
|
|
}
|
|
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 );
|
|
if ( FAILED( hRes ) )
|
|
{
|
|
if ( ( 0x80041315 != hRes ) && ( 0x800706B5 != hRes ) )
|
|
{
|
|
hRes = ERROR_INVALID_USER_EX;
|
|
}
|
|
}
|
|
SAFERELEASE( pIPF );
|
|
SAFERELEASE( pITask );
|
|
SAFERELEASE( pITaskTrig );
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
SAFERELEASE( pIPF );
|
|
SAFERELEASE( pITask );
|
|
SAFERELEASE( pITaskTrig );
|
|
SAFERELEASE( pITaskScheduler );
|
|
return e.Error();
|
|
}
|
|
catch( CHeap_Exception )
|
|
{
|
|
SAFERELEASE( pIPF );
|
|
SAFERELEASE( pITask );
|
|
SAFERELEASE( pITaskTrig );
|
|
SAFERELEASE( pITaskScheduler );
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
return hRes;
|
|
}
|
|
|
|
HRESULT
|
|
CTriggerProvider::DeleteTaskScheduler(
|
|
IN CHString strTScheduler
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
This routine deletes task scheduler.
|
|
|
|
Arguments:
|
|
[IN] szTScheduler : Task Scheduler name.
|
|
|
|
Return Value:
|
|
Returns HRESULT value.
|
|
--*/
|
|
{
|
|
HRESULT hRes = 0;
|
|
ITaskScheduler *pITaskScheduler = NULL;
|
|
IEnumWorkItems *pIEnum = NULL;
|
|
ITask *pITask = NULL;
|
|
LPWSTR *lpwszNames = NULL;
|
|
DWORD dwFetchedTasks = 0;
|
|
DWORD dwTaskIndex = 0;
|
|
TCHAR szActualTask[MAX_RES_STRING1] = NULL_STRING;
|
|
|
|
try
|
|
{
|
|
hRes = GetTaskScheduler( &pITaskScheduler );
|
|
if ( FAILED( hRes ) )
|
|
{
|
|
SAFERELEASE( pITaskScheduler );
|
|
return hRes;
|
|
}
|
|
hRes = pITaskScheduler->SetTargetComputer( NULL );
|
|
if( FAILED( hRes ) )
|
|
{
|
|
SAFERELEASE( pITaskScheduler );
|
|
return hRes;
|
|
}
|
|
|
|
// Enumerate the Work Items
|
|
hRes = pITaskScheduler->Enum( &pIEnum );
|
|
if( FAILED( hRes ) )
|
|
{
|
|
SAFERELEASE( pITaskScheduler );
|
|
SAFERELEASE( pIEnum );
|
|
return hRes;
|
|
}
|
|
|
|
while ( SUCCEEDED( pIEnum->Next( 1,
|
|
&lpwszNames,
|
|
&dwFetchedTasks ) )
|
|
&& (dwFetchedTasks != 0))
|
|
{
|
|
dwTaskIndex = dwFetchedTasks-1;
|
|
// Get the TaskName.
|
|
StringCopy( szActualTask, lpwszNames[ --dwFetchedTasks ], SIZE_OF_ARRAY( szActualTask ) );
|
|
// Parse the TaskName to remove the .job extension.
|
|
szActualTask[StringLength(szActualTask, 0 ) - StringLength( JOB, 0 ) ] = NULL_CHAR;
|
|
StrTrim( szActualTask, TRIM_SPACES );
|
|
|
|
if( StringCompare( szActualTask, strTScheduler, TRUE, 0 ) == 0 )
|
|
{
|
|
hRes = pITaskScheduler->Activate(lpwszNames[dwTaskIndex],IID_ITask,
|
|
(IUnknown**) &pITask);
|
|
if( FAILED( hRes ) )
|
|
{
|
|
CoTaskMemFree( lpwszNames[ dwFetchedTasks ] );
|
|
SAFERELEASE( pIEnum );
|
|
SAFERELEASE( pITaskScheduler );
|
|
if ( 0x80070005 == hRes || 0x8007000D == hRes ||
|
|
SCHED_E_UNKNOWN_OBJECT_VERSION == hRes || E_INVALIDARG == hRes )
|
|
{
|
|
return ERROR_TRIGGER_NOT_DELETED_EX;
|
|
}
|
|
else
|
|
{
|
|
return hRes;
|
|
}
|
|
}
|
|
hRes = pITaskScheduler->Delete( szActualTask );
|
|
CoTaskMemFree( lpwszNames[ dwFetchedTasks ] );
|
|
SAFERELEASE( pIEnum );
|
|
SAFERELEASE( pITask );
|
|
SAFERELEASE( pITaskScheduler );
|
|
return hRes;
|
|
}
|
|
CoTaskMemFree( lpwszNames[ dwFetchedTasks ] );
|
|
}
|
|
}
|
|
catch(_com_error& e)
|
|
{
|
|
SAFERELEASE( pITaskScheduler );
|
|
SAFERELEASE( pIEnum );
|
|
SAFERELEASE( pITask );
|
|
return e.Error();
|
|
}
|
|
SAFERELEASE( pITaskScheduler );
|
|
return ERROR_TRIGGER_CORRUPTED_EX;
|
|
}
|
|
|
|
HRESULT
|
|
CTriggerProvider::GetTaskScheduler(
|
|
OUT ITaskScheduler **ppITaskScheduler
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
This routine gets task scheduler interface.
|
|
|
|
Arguments:
|
|
[OUT] pITaskScheduler - Pointer to ITaskScheduler object.
|
|
|
|
Return Value:
|
|
Returns HRESULT.
|
|
--*/
|
|
{
|
|
HRESULT hRes = S_OK;
|
|
|
|
hRes = CoCreateInstance( CLSID_CTaskScheduler, NULL, CLSCTX_ALL,
|
|
IID_ITaskScheduler,(LPVOID*) ppITaskScheduler );
|
|
if( FAILED(hRes))
|
|
{
|
|
return hRes;
|
|
}
|
|
return hRes;
|
|
}
|
|
|
|
VOID
|
|
CTriggerProvider::GetUniqueTScheduler(
|
|
OUT CHString& szScheduler,
|
|
IN DWORD dwTrigID,
|
|
IN VARIANT varTrigName
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
This routine generates unique task scheduler name.
|
|
|
|
Arguments:
|
|
[OUT] szScheduler : Unique task scheduler name.
|
|
[IN] dwTrigID : Trigger id.
|
|
[IN] varTrigName : Trigger name.
|
|
|
|
Return Value:
|
|
none.
|
|
--*/
|
|
{
|
|
DWORD dwTickCount = 0;
|
|
TCHAR szTaskName[ MAX_RES_STRING1 ] = NULL_STRING;
|
|
CHString strTemp = L"";
|
|
|
|
strTemp = (LPCWSTR)_bstr_t(varTrigName.bstrVal);
|
|
dwTickCount = GetTickCount();
|
|
StringCchPrintf( szTaskName, SIZE_OF_ARRAY( szTaskName ), UNIQUE_TASK_NAME, ( LPCWSTR )strTemp, dwTrigID, dwTickCount );
|
|
|
|
szScheduler = szTaskName;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CTriggerProvider::FindConsumer(
|
|
IN IWbemClassObject* pLogicalConsumer,
|
|
OUT IWbemUnboundObjectSink** ppConsumer
|
|
)
|
|
/*++
|
|
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:
|
|
[IN] pLogicalConsumer : Pointer to the logical consumer object
|
|
to which the event objects are to be delivered.
|
|
[OUT] ppConsumer : 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.
|
|
--*/
|
|
{
|
|
// create the logical consumer.
|
|
CTriggerConsumer* pSink = new CTriggerConsumer();
|
|
|
|
// return it's "sink" interface.
|
|
return pSink->QueryInterface( IID_IWbemUnboundObjectSink, ( LPVOID* ) ppConsumer );
|
|
}
|