Source code of Windows XP (NT5)
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.

1754 lines
48 KiB

  1. //***************************************************************************
  2. // Copyright (c) Microsoft Corporation
  3. //
  4. // Module Name:
  5. // TRIGGERPROVIDER.CPP
  6. //
  7. // Abstract:
  8. // Contains CTriggerProvider implementation.
  9. //
  10. // Author:
  11. // Vasundhara .G
  12. //
  13. // Revision History:
  14. // Vasundhara .G 9-oct-2k : Created It.
  15. //***************************************************************************
  16. #include "pch.h"
  17. #include "General.h"
  18. #include "EventConsumerProvider.h"
  19. #include "TriggerConsumer.h"
  20. #include "TriggerProvider.h"
  21. #include "resource.h"
  22. extern HMODULE g_hModule;
  23. //
  24. // general purpose macros
  25. // ( some macros in this section might end abruptly ... this was done purposefully
  26. // do not alter that part ... will result compiler errors
  27. //
  28. #define VALUE_GET( object, property, type, valueaddr, size ) \
  29. hr = PropertyGet( object, property, type, valueaddr, size ); \
  30. if ( FAILED( hr ) ) \
  31. return hr;
  32. //***************************************************************************
  33. // Routine Description:
  34. // Constructor for CTriggerProvider class for initialization.
  35. //
  36. // Arguments:
  37. // None.
  38. //
  39. // Return Value:
  40. // None.
  41. //***************************************************************************
  42. CTriggerProvider::CTriggerProvider()
  43. {
  44. // update the no. of provider instances count
  45. InterlockedIncrement( ( LPLONG ) &g_dwInstances );
  46. // initialize the reference count variable
  47. m_dwCount = 0;
  48. // initializations
  49. m_pContext = NULL;
  50. m_pServices = NULL;
  51. m_pwszLocale = NULL;
  52. m_dwNextTriggerID = 0;
  53. }
  54. //***************************************************************************
  55. // Routine Description:
  56. // Destructor for CTriggerProvider class.
  57. //
  58. // Arguments:
  59. // None.
  60. //
  61. // Return Value:
  62. // None.
  63. //***************************************************************************
  64. CTriggerProvider::~CTriggerProvider()
  65. {
  66. // release the services / namespace interface ( if exist )
  67. SAFERELEASE( m_pServices );
  68. // release the context interface ( if exist )
  69. SAFERELEASE( m_pContext );
  70. // if memory is allocated for storing locale information, free it
  71. if ( m_pwszLocale != NULL )
  72. {
  73. delete [] m_pwszLocale;
  74. }
  75. // update the no. of provider instances count
  76. InterlockedDecrement( ( LPLONG ) &g_dwInstances );
  77. }
  78. //***************************************************************************
  79. // Routine Description:
  80. // Returns a pointer to a specified interface on an object
  81. // to which a client currently holds an interface pointer.
  82. //
  83. // Arguments:
  84. // riid [in] : Identifier of the interface being requested.
  85. // ppv [out] : Address of pointer variable that receives the
  86. // interface pointer requested in riid. Upon
  87. // successful return, *ppvObject contains the
  88. // requested interface pointer to the object.
  89. //
  90. // Return Value:
  91. // NOERROR if the interface is supported.
  92. // E_NOINTERFACE if not.
  93. //***************************************************************************
  94. STDMETHODIMP CTriggerProvider::QueryInterface( REFIID riid, LPVOID* ppv )
  95. {
  96. // initialy set to NULL
  97. *ppv = NULL;
  98. // check whether interface requested is one we have
  99. if ( riid == IID_IUnknown )
  100. {
  101. // need IUnknown interface
  102. *ppv = this;
  103. }
  104. else if ( riid == IID_IWbemEventConsumerProvider )
  105. {
  106. // need IEventConsumerProvider interface
  107. *ppv = static_cast<IWbemEventConsumerProvider*>( this );
  108. }
  109. else if ( riid == IID_IWbemServices )
  110. {
  111. // need IWbemServices interface
  112. *ppv = static_cast<IWbemServices*>( this );
  113. }
  114. else if ( riid == IID_IWbemProviderInit )
  115. {
  116. // need IWbemProviderInit
  117. *ppv = static_cast<IWbemProviderInit*>( this );
  118. }
  119. else
  120. {
  121. // request interface is not available
  122. return E_NOINTERFACE;
  123. }
  124. // update the reference count
  125. reinterpret_cast<IUnknown*>( *ppv )->AddRef();
  126. return NOERROR; // inform success
  127. }
  128. //***************************************************************************
  129. // Routine Description:
  130. // The AddRef method increments the reference count for
  131. // an interface on an object. It should be called for every
  132. // new copy of a pointer to an interface on a given object.
  133. //
  134. // Arguments:
  135. // none.
  136. //
  137. // Return Value:
  138. // Returns the value of the new reference count.
  139. //***************************************************************************
  140. STDMETHODIMP_(ULONG) CTriggerProvider::AddRef( void )
  141. {
  142. // increment the reference count ... thread safe
  143. return InterlockedIncrement( ( LPLONG ) &m_dwCount );
  144. }
  145. //***************************************************************************
  146. // Routine Description:
  147. // The Release method decreases the reference count of the object by 1.
  148. //
  149. // Arguments:
  150. // none.
  151. //
  152. // Return Value:
  153. // Returns the new reference count.
  154. //***************************************************************************
  155. STDMETHODIMP_(ULONG) CTriggerProvider::Release( void )
  156. {
  157. // decrement the reference count ( thread safe ) and check whether
  158. // there are some more references or not ... based on the result value
  159. DWORD dwCount = 0;
  160. dwCount = InterlockedDecrement( ( LPLONG ) &m_dwCount );
  161. if ( dwCount == 0 )
  162. {
  163. // free the current factory instance
  164. delete this;
  165. }
  166. // return the no. of instances references left
  167. return dwCount;
  168. }
  169. //***************************************************************************
  170. // Routine Description:
  171. // This is the implemention of IWbemProviderInit. The
  172. // method is need to initialize with CIMOM.
  173. //
  174. // Arguments:
  175. // wszUser [in] : pointer to user name.
  176. // lFlags [in] : Reserved.
  177. // wszNamespace [in] : contains the namespace of WMI.
  178. // wszLocale [in] : Locale Name.
  179. // pNamespace [in] : pointer to IWbemServices.
  180. // pCtx [in] : IwbemContext pointer associated for initialization.
  181. // pInitSink [out] : a pointer to IWbemProviderInitSink for
  182. // reporting the initialization status.
  183. //
  184. // Return Value:
  185. // returns HRESULT value.
  186. //***************************************************************************
  187. STDMETHODIMP CTriggerProvider::Initialize( LPWSTR wszUser, LONG lFlags,
  188. LPWSTR wszNamespace, LPWSTR wszLocale,
  189. IWbemServices* pNamespace, IWbemContext* pCtx,
  190. IWbemProviderInitSink* pInitSink )
  191. {
  192. HRESULT hRes = 0;
  193. IEnumWbemClassObject *pINTEConsumer = NULL;
  194. DWORD dwReturned = 0;
  195. DWORD dwTrigId = 0;
  196. VARIANT varTrigId;
  197. DWORD i = 0;
  198. try
  199. {
  200. // save the namespace interface ... will be useful at later stages
  201. m_pServices = pNamespace;
  202. m_pServices->AddRef(); // update the reference
  203. // also save the context interface ... will be userful at later stages ( if available )
  204. if ( pCtx != NULL )
  205. {
  206. m_pContext = pCtx;
  207. m_pContext->AddRef();
  208. }
  209. // save the locale information ( if exist )
  210. if ( wszLocale != NULL )
  211. {
  212. m_pwszLocale = new WCHAR [ wcslen( wszLocale ) + 1 ];
  213. if ( m_pwszLocale == NULL )
  214. {
  215. // update the sink accordingly
  216. pInitSink->SetStatus( WBEM_E_FAILED, 0 );
  217. // return failure
  218. return WBEM_E_OUT_OF_MEMORY;
  219. }
  220. }
  221. // Enumerate TriggerEventConsumer to get the Maximum trigger Id which can be later
  222. // used to generate unique trigger id value.
  223. hRes = m_pServices ->CreateInstanceEnum(
  224. _bstr_t(CONSUMER_CLASS),
  225. WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY,
  226. m_pContext, &pINTEConsumer);
  227. if (SUCCEEDED( hRes ) )
  228. {
  229. dwReturned = 1;
  230. // Final Next will return with ulReturned = 0
  231. while ( dwReturned != 0 )
  232. {
  233. IWbemClassObject *pINTCons[5];
  234. // Enumerate through the resultset.
  235. hRes = pINTEConsumer->Next( WBEM_INFINITE,
  236. 5, // return just one Logfile
  237. pINTCons, // pointer to Logfile
  238. &dwReturned ); // number obtained: one or zero
  239. if ( SUCCEEDED( hRes ) )
  240. {
  241. // Get the trigger id value
  242. for( i = 0; i < dwReturned; i++ )
  243. {
  244. VariantInit( &varTrigId );
  245. hRes = pINTCons[i]->Get( TRIGGER_ID, 0, &varTrigId, 0, NULL );
  246. SAFERELEASE( pINTCons[i] );
  247. if ( SUCCEEDED( hRes ) )
  248. {
  249. dwTrigId = ( DWORD )varTrigId.lVal;
  250. if( dwTrigId > m_dwNextTriggerID )
  251. {
  252. m_dwNextTriggerID = dwTrigId;
  253. }
  254. }
  255. else
  256. {
  257. VariantClear( &varTrigId );
  258. break;
  259. }
  260. VariantClear( &varTrigId );
  261. }
  262. }
  263. else
  264. {
  265. break;
  266. }
  267. } //while
  268. // got triggerId so set it
  269. SAFERELEASE( pINTEConsumer );
  270. }
  271. //Let CIMOM know your initialized
  272. //===============================
  273. if ( SUCCEEDED( hRes ) )
  274. {
  275. // update the m_dwTrigId value
  276. m_dwNextTriggerID = m_dwNextTriggerID + 1;
  277. hRes = pInitSink->SetStatus( WBEM_S_INITIALIZED, 0 );
  278. }
  279. else
  280. {
  281. hRes = pInitSink->SetStatus( WBEM_E_FAILED, 0);
  282. }
  283. }
  284. catch(_com_error& e)
  285. {
  286. hRes = pInitSink->SetStatus( WBEM_E_FAILED, 0);
  287. return hRes;
  288. }
  289. return hRes;
  290. }
  291. //***************************************************************************
  292. // Routine Description:
  293. // This is the Async function implementation.
  294. // The methods supported is named CreateETrigger and DeleteETrigger.
  295. //
  296. // Arguments:
  297. // bstrObjectPath [in] : path of the object for which the method is executed.
  298. // bstrMethodName [in] : Name of the method for the object.
  299. // lFlags [in] : WBEM_FLAG_SEND_STATUS.
  300. // pICtx [in] : a pointer to IWbemContext.
  301. // pIInParams [in] : this points to an IWbemClassObject object
  302. // that contains the properties acting as
  303. // inbound parameters for method execution.
  304. // pIResultSink [out] : The object sink receives the result of the method call.
  305. //
  306. // Return Value:
  307. // returns HRESULT.
  308. //***************************************************************************
  309. STDMETHODIMP CTriggerProvider::ExecMethodAsync( const BSTR bstrObjectPath,
  310. const BSTR bstrMethodName,
  311. long lFlags,
  312. IWbemContext* pICtx,
  313. IWbemClassObject* pIInParams,
  314. IWbemObjectSink* pIResultSink )
  315. {
  316. HRESULT hRes = 0;
  317. HRESULT hRes1 = NO_ERROR;
  318. IWbemClassObject *pIClass = NULL;
  319. IWbemClassObject *pIOutClass = NULL;
  320. IWbemClassObject *pIOutParams = NULL;
  321. VARIANT varTriggerName, varTriggerAction, varTriggerQuery,
  322. varTriggerDesc, varTemp, varRUser, varRPwd, varScheduledTaskName;
  323. DWORD dwTrigId = 0;
  324. try
  325. {
  326. //set out parameters
  327. hRes = m_pServices->GetObject( CONSUMER_CLASS, 0, pICtx, &pIClass, NULL );
  328. if( FAILED( hRes ) )
  329. {
  330. pIResultSink->SetStatus( 0, hRes, NULL, NULL );
  331. return hRes;
  332. }
  333. // This method returns values, and so create an instance of the
  334. // output argument class.
  335. hRes = pIClass->GetMethod( bstrMethodName, 0, NULL , &pIOutClass );
  336. SAFERELEASE( pIClass );
  337. if( FAILED( hRes ) )
  338. {
  339. pIResultSink->SetStatus( 0, hRes, NULL, NULL );
  340. return hRes;
  341. }
  342. hRes = pIOutClass->SpawnInstance( 0, &pIOutParams );
  343. SAFERELEASE( pIOutClass );
  344. if( FAILED( hRes ) )
  345. {
  346. pIResultSink->SetStatus( 0, hRes, NULL, NULL );
  347. return hRes;
  348. }
  349. VariantInit( &varTriggerName );
  350. //Check the method name
  351. if( _wcsicmp( bstrMethodName, CREATE_METHOD_NAME ) == 0 )
  352. {
  353. // if client has called CreateETrigger then
  354. // parse input params to get trigger name, trigger desc, trigger action
  355. // and trigger query for creating new instances of TriggerEventConsumer,
  356. // __EventFilter and __FilterToConsumerBinding classes
  357. //initialize variables
  358. VariantInit( &varTriggerAction );
  359. VariantInit( &varTriggerQuery );
  360. VariantInit( &varTriggerDesc );
  361. VariantInit( &varRUser );
  362. VariantInit( &varRPwd );
  363. //Retrieve Trigger Name parameter from input params
  364. hRes = pIInParams->Get( IN_TRIGGER_NAME, 0, &varTriggerName, NULL, NULL );
  365. if( SUCCEEDED( hRes ) )
  366. {
  367. //Retrieve Trigger Action parameter from input params
  368. hRes = pIInParams->Get( IN_TRIGGER_ACTION, 0, &varTriggerAction, NULL, NULL );
  369. if( SUCCEEDED( hRes ) )
  370. {
  371. //Retrieve Trigger Query parameter from input params
  372. hRes = pIInParams->Get( IN_TRIGGER_QUERY, 0, &varTriggerQuery, NULL, NULL );
  373. if( SUCCEEDED( hRes ) )
  374. {
  375. //Retrieve Trigger Description parameter from input params
  376. hRes = pIInParams->Get( IN_TRIGGER_DESC, 0, &varTriggerDesc, NULL, NULL );
  377. if( SUCCEEDED( hRes ) )
  378. {
  379. EnterCriticalSection( &g_critical_sec );
  380. hRes = ValidateParams( varTriggerName, varTriggerAction,
  381. varTriggerQuery );
  382. if( hRes == WBEM_S_NO_ERROR )
  383. {
  384. hRes = pIInParams->Get( IN_TRIGGER_USER, 0, &varRUser, NULL, NULL );
  385. if( SUCCEEDED( hRes ) )
  386. {
  387. hRes = pIInParams->Get( IN_TRIGGER_PWD, 0, &varRPwd, NULL, NULL );
  388. if( SUCCEEDED( hRes ) )
  389. {
  390. //call create trigger function to create the instances
  391. hRes = CreateTrigger( varTriggerName, varTriggerDesc,
  392. varTriggerAction, varTriggerQuery,
  393. varRUser, varRPwd, &hRes1 );
  394. if( ( hRes == WBEM_S_NO_ERROR ) || ( hRes == WARNING_INVALID_USER ) )
  395. {
  396. // increment the class member variable by one to get the new unique trigger id
  397. //for the next instance
  398. m_dwNextTriggerID = m_dwNextTriggerID + 1;
  399. }
  400. }
  401. }
  402. }
  403. LeaveCriticalSection( &g_critical_sec );
  404. }
  405. }
  406. }
  407. }
  408. VariantClear( &varTriggerAction );
  409. VariantClear( &varRUser );
  410. VariantClear( &varRPwd );
  411. VariantClear( &varTriggerDesc );
  412. VariantClear( &varTriggerQuery );
  413. }
  414. else if( _wcsicmp( bstrMethodName, DELETE_METHOD_NAME ) == 0 )
  415. {
  416. //Retrieve Trigger ID parameter from input params
  417. hRes = pIInParams->Get( IN_TRIGGER_NAME, 0, &varTriggerName, NULL, NULL );
  418. if( SUCCEEDED( hRes ) )
  419. {
  420. EnterCriticalSection( &g_critical_sec );
  421. //call Delete trigger function to delete the instances
  422. hRes = DeleteTrigger( varTriggerName, &dwTrigId );
  423. LeaveCriticalSection( &g_critical_sec );
  424. }
  425. }
  426. else if( _wcsicmp( bstrMethodName, QUERY_METHOD_NAME ) == 0 )
  427. {
  428. VariantInit( &varScheduledTaskName );
  429. VariantInit( &varRUser );
  430. //Retrieve schedule task name parameter from input params
  431. hRes = pIInParams->Get( IN_TRIGGER_TSCHDULER, 0, &varScheduledTaskName, NULL, NULL );
  432. if( SUCCEEDED( hRes ) )
  433. {
  434. EnterCriticalSection( &g_critical_sec );
  435. //call query trigger function to query the runasuser
  436. CHString szRunAsUser = NULL_STRING;
  437. hRes = QueryTrigger( varScheduledTaskName, szRunAsUser );
  438. varRUser.vt = VT_BSTR;
  439. varRUser.bstrVal = SysAllocString( szRunAsUser );
  440. hRes = pIOutParams->Put( OUT_RUNAS_USER , 0, &varRUser, 0 );
  441. LeaveCriticalSection( &g_critical_sec );
  442. }
  443. VariantClear( &varScheduledTaskName );
  444. VariantClear( &varRUser );
  445. }
  446. else
  447. {
  448. hRes = WBEM_E_INVALID_PARAMETER;
  449. }
  450. if( _wcsicmp( bstrMethodName, CREATE_METHOD_NAME ) == 0 )
  451. {
  452. LPTSTR lpResStr = NULL;
  453. lpResStr = ( LPTSTR ) __calloc( MAX_RES_STRING1 + 1, sizeof( TCHAR ) );
  454. if ( lpResStr != NULL )
  455. {
  456. if( ( hRes == WBEM_S_NO_ERROR ) || ( hRes == WARNING_INVALID_USER ) )
  457. {
  458. LoadStringW( g_hModule, IDS_CREATED, lpResStr, MAX_RES_STRING1 );
  459. if( hRes1 != NO_ERROR )// write invalid user into log file
  460. {
  461. LPTSTR lpResStr1 = NULL;
  462. BOOL bFlag = FALSE;
  463. lpResStr1 = ( LPTSTR ) __calloc( MAX_RES_STRING1 + 1, sizeof( TCHAR ) );
  464. if ( lpResStr1 != NULL )
  465. {
  466. if( hRes1 == ERROR_TASK_SCHDEULE_SERVICE_STOP )
  467. {
  468. hRes = WBEM_S_NO_ERROR;
  469. LoadStringW( g_hModule,IDS_INFO_SERVICE_STOPPED, lpResStr1, MAX_RES_STRING1 );
  470. lstrcat( lpResStr, lpResStr1 );
  471. }
  472. else if( hRes1 == ERROR_SCHDEULE_TASK_INVALID_USER )
  473. {
  474. hRes = WARNING_INVALID_USER;
  475. LoadStringW( g_hModule, IDS_INFO_INVALID_USER, lpResStr1, MAX_RES_STRING1 );
  476. lstrcat( lpResStr, lpResStr1 );
  477. }
  478. free( lpResStr1 );
  479. }
  480. }
  481. ErrorLog( lpResStr, ( LPWSTR )_bstr_t( varTriggerName ), ( m_dwNextTriggerID - 1 ) );
  482. }
  483. else
  484. {
  485. LoadStringW( g_hModule, IDS_CREATE_FAILED, lpResStr, MAX_RES_STRING1 );
  486. ErrorLog( lpResStr, ( LPWSTR )_bstr_t( varTriggerName ), ( m_dwNextTriggerID - 1 ) );
  487. }
  488. free( lpResStr );
  489. }
  490. else
  491. {
  492. hRes = E_OUTOFMEMORY;
  493. }
  494. }
  495. else if( _wcsicmp( bstrMethodName, DELETE_METHOD_NAME ) == 0 )
  496. {
  497. LPTSTR lpResStr = NULL;
  498. lpResStr = ( LPTSTR ) __calloc( MAX_RES_STRING1 + 1, sizeof( TCHAR ) );
  499. if ( lpResStr != NULL )
  500. {
  501. if( hRes == WBEM_S_NO_ERROR )
  502. {
  503. LoadStringW( g_hModule, IDS_DELETED, lpResStr, MAX_RES_STRING1 );
  504. ErrorLog( lpResStr, ( LPWSTR )_bstr_t( varTriggerName ), dwTrigId );
  505. }
  506. else
  507. {
  508. LoadStringW( g_hModule, IDS_DELETE_FAILED, lpResStr, MAX_RES_STRING1 );
  509. ErrorLog( lpResStr,( LPWSTR )_bstr_t( varTriggerName ), dwTrigId );
  510. }
  511. free( lpResStr );
  512. }
  513. else
  514. {
  515. hRes = E_OUTOFMEMORY;
  516. }
  517. }
  518. VariantInit( &varTemp );
  519. V_VT( &varTemp ) = VT_I4;
  520. V_I4( &varTemp ) = hRes;
  521. // set out params
  522. hRes = pIOutParams->Put( RETURN_VALUE , 0, &varTemp, 0 );
  523. VariantClear( &varTemp );
  524. if( SUCCEEDED( hRes ) )
  525. {
  526. // Send the output object back to the client via the sink. Then
  527. hRes = pIResultSink->Indicate( 1, &pIOutParams );
  528. }
  529. //release all the resources
  530. SAFERELEASE( pIOutParams );
  531. hRes = pIResultSink->SetStatus( 0, WBEM_S_NO_ERROR, NULL, NULL );
  532. }
  533. catch(_com_error& e)
  534. {
  535. pIResultSink->SetStatus( 0, hRes, NULL, NULL );
  536. return hRes;
  537. }
  538. catch( CHeap_Exception )
  539. {
  540. hRes = E_OUTOFMEMORY;
  541. pIResultSink->SetStatus( 0, hRes, NULL, NULL );
  542. return hRes;
  543. }
  544. return hRes;
  545. }
  546. //***************************************************************************
  547. // Routine Description:
  548. // This routine creates the instance of TriggerEventConsumer,
  549. // __EventFilter and __FilterToConsumerBinding classes.
  550. //
  551. // Arguments:
  552. // varTName [in] : Trigger Name.
  553. // varTDesc [in] : Trigger Description.
  554. // varTAction [in] : Trigger Action.
  555. // varTQuery [in] : Trigger Query.
  556. //
  557. // Return Value:
  558. // S_OK if successful.
  559. // Otherwise failure error code.
  560. //***************************************************************************
  561. HRESULT CTriggerProvider::CreateTrigger( VARIANT varTName, VARIANT varTDesc,
  562. VARIANT varTAction, VARIANT varTQuery,
  563. VARIANT varRUser, VARIANT varRPwd,
  564. HRESULT *phRes )
  565. {
  566. IWbemClassObject *pINtLogEventClass = 0;
  567. IWbemClassObject *pIFilterClass = 0;
  568. IWbemClassObject *pIBindClass = 0;
  569. IWbemClassObject *pINewInstance = 0;
  570. IEnumWbemClassObject *pIEnumClassObject = 0;
  571. HRESULT hRes = 0;
  572. DWORD dwTId = 0;
  573. VARIANT varTemp;
  574. TCHAR szTemp[MAX_RES_STRING1];
  575. TCHAR szTemp1[MAX_RES_STRING1];
  576. TCHAR szFName[MAX_RES_STRING1];
  577. SYSTEMTIME SysTime;
  578. BOOL bInvalidUser = FALSE;
  579. try
  580. {
  581. _bstr_t bstrcurInst;
  582. _bstr_t bstrcurInst1;
  583. //initialize memory for temporary variables
  584. memset( szTemp, 0, sizeof( szTemp ) );
  585. memset( szTemp1, 0, sizeof(szTemp1 ) );
  586. memset( szFName, 0, sizeof( szFName ) );
  587. VariantInit( &varTemp );
  588. if ( phRes != NULL )
  589. {
  590. *phRes = NO_ERROR;
  591. }
  592. /**************************************************************************
  593. CREATING __EventFilter INSTANCE
  594. ***************************************************************************/
  595. // get EventFilter class object
  596. hRes = m_pServices->GetObject( FILTER_CLASS, 0, 0, &pIFilterClass, NULL );
  597. if( FAILED( hRes ) )
  598. {
  599. return hRes;
  600. }
  601. // Create a new instance.
  602. hRes = pIFilterClass->SpawnInstance( 0, &pINewInstance );
  603. SAFERELEASE( pIFilterClass ); // Don't need the class any more
  604. //return error if unable to spawn a new instance of EventFilter class
  605. if( FAILED( hRes ) )
  606. {
  607. return hRes;
  608. }
  609. // set query property for the new instance
  610. hRes = pINewInstance->Put( FILTER_QUERY, 0, &varTQuery, 0 );
  611. //if failed to set the property return error
  612. if( FAILED( hRes ) )
  613. {
  614. SAFERELEASE( pINewInstance );
  615. return hRes;
  616. }
  617. VariantInit( &varTemp );
  618. varTemp.vt = VT_BSTR;
  619. varTemp.bstrVal = SysAllocString( QUERY_LANGUAGE );
  620. // set query language property for the new instance .
  621. hRes = pINewInstance->Put( FILTER_QUERY_LANGUAGE, 0, &varTemp, 0 );
  622. VariantClear( &varTemp );
  623. //if failed to set the property return error
  624. if( FAILED( hRes ) )
  625. {
  626. SAFERELEASE( pINewInstance );
  627. return hRes;
  628. }
  629. //generate unique name for name key property of EventFilter class by concatinating
  630. // current system date and time
  631. GetSystemTime( &SysTime );
  632. wsprintf ( szTemp, FILTER_UNIQUE_NAME, m_dwNextTriggerID, SysTime.wHour, SysTime.wMinute,
  633. SysTime.wSecond, SysTime.wMonth, SysTime.wDay, SysTime.wYear );
  634. //set Filter name property
  635. VariantInit( &varTemp );
  636. varTemp.vt = VT_BSTR;
  637. varTemp.bstrVal = SysAllocString( szTemp );
  638. hRes = pINewInstance->Put( FILTER_NAME, 0, &varTemp, 0 );
  639. VariantClear( &varTemp );
  640. //if failed to set the property return error
  641. if( FAILED( hRes ) )
  642. {
  643. SAFERELEASE( pINewInstance );
  644. return hRes;
  645. }
  646. // Write the instance to WMI.
  647. hRes = m_pServices->PutInstance( pINewInstance, 0, NULL, NULL );
  648. SAFERELEASE( pINewInstance );
  649. //if putinstance failed return error
  650. if( FAILED( hRes ) )
  651. {
  652. return hRes;
  653. }
  654. //get the current Eventfilter instance for binding filter to consumer
  655. wsprintf( szTemp1, BIND_FILTER_PATH );
  656. bstrcurInst = _bstr_t(szTemp1) + _bstr_t(szTemp) + _bstr_t(BACK_SLASH);
  657. pIFilterClass = NULL;
  658. hRes = m_pServices->GetObject( bstrcurInst, 0L, NULL, &pIFilterClass, NULL );
  659. //unable to get the current instance object return error
  660. if( FAILED( hRes ) )
  661. {
  662. return hRes;
  663. }
  664. /**************************************************************************
  665. CREATING TriggerEventConsumer INSTANCE
  666. ***************************************************************************/
  667. //get NTEventConsumer class object
  668. hRes =m_pServices->GetObject( CONSUMER_CLASS, 0, 0, &pINtLogEventClass, NULL );
  669. //if unable to get the object of TriggerEventConsumer return error
  670. if( FAILED( hRes ) )
  671. {
  672. SAFERELEASE( pINtLogEventClass );// safer side
  673. SAFERELEASE( pIFilterClass );
  674. return hRes;
  675. }
  676. // Create a new instance.
  677. pINewInstance = NULL;
  678. hRes = pINtLogEventClass->SpawnInstance( 0, &pINewInstance );
  679. SAFERELEASE( pINtLogEventClass ); // Don't need the class any more
  680. // if unable to spawn a instance return back to caller
  681. if( FAILED( hRes ) )
  682. {
  683. SAFERELEASE( pIFilterClass );
  684. return hRes;
  685. }
  686. //get the unique trigger id from CMethodPro memeber variable
  687. hRes = m_pServices->ExecQuery( QUERY_LANGUAGE, INSTANCE_EXISTS_QUERY,
  688. WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pIEnumClassObject );
  689. if( FAILED( hRes ) )
  690. {
  691. SAFERELEASE( pIFilterClass );
  692. SAFERELEASE( pINewInstance );
  693. return hRes;
  694. }
  695. DWORD dwReturned = 0;
  696. IWbemClassObject *pINTCons = NULL;
  697. // Enumerate through the resultset.
  698. hRes = pIEnumClassObject->Next( WBEM_INFINITE,
  699. 1, // return just one service
  700. &pINTCons, // pointer to service
  701. &dwReturned ); // number obtained: one or zero
  702. if ( SUCCEEDED( hRes ) && ( dwReturned == 1 ) )
  703. {
  704. SAFERELEASE( pINTCons );
  705. } // If Service Succeeded
  706. else
  707. {
  708. m_dwNextTriggerID = 1;
  709. }
  710. SAFERELEASE( pIEnumClassObject );
  711. dwTId = m_dwNextTriggerID;
  712. VariantInit(&varTemp);
  713. varTemp.vt = VT_I4;
  714. varTemp.lVal = dwTId;
  715. // set the trigger id property of NTEventConsumer
  716. hRes = pINewInstance->Put( TRIGGER_ID, 0, &varTemp, 0 );
  717. VariantClear( &varTemp );
  718. //if failed to set the property return error
  719. if( FAILED( hRes ) )
  720. {
  721. SAFERELEASE( pIFilterClass );
  722. SAFERELEASE( pINewInstance );
  723. return hRes;
  724. }
  725. // set Triggername property.
  726. hRes = pINewInstance->Put( TRIGGER_NAME, 0, &varTName, 0 );
  727. //if failed to set the property return error
  728. if( FAILED( hRes ) )
  729. {
  730. SAFERELEASE( pIFilterClass );
  731. SAFERELEASE( pINewInstance );
  732. return hRes;
  733. }
  734. // set action property
  735. hRes = pINewInstance->Put( TRIGGER_ACTION, 0, &varTAction, 0 );
  736. //if failed to set the property return error
  737. if( FAILED( hRes ) )
  738. {
  739. SAFERELEASE( pIFilterClass );
  740. SAFERELEASE( pINewInstance );
  741. return hRes;
  742. }
  743. //set desc property
  744. hRes = pINewInstance->Put( TRIGGER_DESC, 0, &varTDesc, 0 );
  745. //if failed to set the property return error
  746. if( FAILED( hRes ) )
  747. {
  748. SAFERELEASE( pIFilterClass );
  749. SAFERELEASE( pINewInstance );
  750. return hRes;
  751. }
  752. CHString szScheduler = NULL_STRING;
  753. CHString szRUser = (LPCWSTR)_bstr_t(varRUser.bstrVal);
  754. if( ( varRUser.vt != VT_NULL ) && ( varRUser.vt != VT_EMPTY ) && ( szRUser.GetLength() > 0 ) )
  755. {
  756. GetUniqueTScheduler( szScheduler, m_dwNextTriggerID, varTName );
  757. hRes = SetUserContext( varRUser, varRPwd, varTAction, szScheduler );
  758. *phRes = hRes;
  759. if( hRes == ERROR_SCHDEULE_TASK_INVALID_USER ||
  760. ( hRes == ERROR_TASK_SCHDEULE_SERVICE_STOP ) ) //to send a warning msg to client
  761. {
  762. bInvalidUser = TRUE;
  763. }
  764. if( FAILED( hRes ) )
  765. {
  766. //if user is not existing or service is stopped skip
  767. if( ( hRes != ERROR_SCHDEULE_TASK_INVALID_USER ) && ( hRes != ERROR_TASK_SCHDEULE_SERVICE_STOP ) )
  768. {
  769. SAFERELEASE( pIFilterClass );
  770. SAFERELEASE( pINewInstance );
  771. return hRes;
  772. }
  773. }
  774. }
  775. VariantInit(&varTemp);
  776. varTemp.vt = VT_BSTR;
  777. varTemp.bstrVal = SysAllocString( szScheduler );
  778. hRes = pINewInstance->Put( TASK_SHEDULER, 0, &varTemp, 0 );
  779. VariantClear( &varTemp );
  780. if( FAILED( hRes ) )
  781. {
  782. SAFERELEASE( pIFilterClass );
  783. SAFERELEASE( pINewInstance );
  784. return hRes;
  785. }
  786. // Write the instance to WMI.
  787. hRes = m_pServices->PutInstance( pINewInstance, 0, 0, NULL );
  788. SAFERELEASE( pINewInstance );
  789. //if putinstance failed return error
  790. if( FAILED( hRes ) )
  791. {
  792. SAFERELEASE( pIFilterClass );
  793. return hRes;
  794. }
  795. //get the current instance for binding it with __FilterToConsumerBinding class
  796. wsprintf( szTemp, BIND_CONSUMER_PATH, dwTId);
  797. bstrcurInst1 = _bstr_t( szTemp );
  798. pINtLogEventClass = NULL;
  799. hRes = m_pServices->GetObject( bstrcurInst1, 0L, NULL, &pINtLogEventClass, NULL );
  800. //if unable to get the current instance return error
  801. if( FAILED( hRes ) )
  802. {
  803. SAFERELEASE( pIFilterClass );
  804. return hRes;
  805. }
  806. /**************************************************************************
  807. BINDING FILTER TO CONSUMER
  808. ***************************************************************************/
  809. // if association class exists...
  810. if( ( hRes = m_pServices->GetObject( BINDINGCLASS, 0L, NULL, &pIBindClass, NULL ) ) == S_OK )
  811. {
  812. // spawn a new instance.
  813. pINewInstance = NULL;
  814. if( ( hRes = pIBindClass->SpawnInstance( 0, &pINewInstance ) ) == WBEM_S_NO_ERROR )
  815. {
  816. // set consumer instance name
  817. if ( ( hRes = pINtLogEventClass->Get( REL_PATH, 0L,
  818. &varTemp, NULL, NULL ) ) == WBEM_S_NO_ERROR )
  819. {
  820. hRes = pINewInstance->Put( CONSUMER_BIND, 0, &varTemp, 0 );
  821. VariantClear( &varTemp );
  822. // set Filter ref
  823. if ( ( hRes = pIFilterClass->Get( REL_PATH, 0L,
  824. &varTemp, NULL, NULL ) ) == WBEM_S_NO_ERROR )
  825. {
  826. hRes = pINewInstance->Put( FILTER_BIND, 0, &varTemp, 0 );
  827. VariantClear( &varTemp );
  828. // putInstance
  829. hRes = m_pServices->PutInstance( pINewInstance,
  830. WBEM_FLAG_CREATE_OR_UPDATE, NULL, NULL );
  831. }
  832. }
  833. SAFERELEASE( pINewInstance );
  834. SAFERELEASE( pINtLogEventClass ); // Don't need the class any more
  835. SAFERELEASE( pIFilterClass ); // Don't need the class any more
  836. SAFERELEASE( pIBindClass );
  837. }
  838. else
  839. {
  840. SAFERELEASE( pINtLogEventClass ); // Don't need the class any more
  841. SAFERELEASE( pIFilterClass ); // Don't need the class any more
  842. SAFERELEASE( pIBindClass );
  843. }
  844. }
  845. else
  846. {
  847. SAFERELEASE( pINtLogEventClass ); // Don't need the class any more
  848. SAFERELEASE( pIFilterClass ); // Don't need the class any more
  849. }
  850. }
  851. catch(_com_error& e)
  852. {
  853. return hRes;
  854. }
  855. catch( CHeap_Exception )
  856. {
  857. return E_OUTOFMEMORY;
  858. }
  859. if( ( hRes == WBEM_S_NO_ERROR ) && ( bInvalidUser == TRUE ) )
  860. {
  861. return WARNING_INVALID_USER;
  862. }
  863. return hRes;
  864. }
  865. //***************************************************************************
  866. // Routine Description:
  867. // This routine deletes the instance of TriggerEventConsumer,
  868. // __EventFilter and __FilterToConsumerBinding classes.
  869. //
  870. // Arguments:
  871. // varTName [in] : Trigger Name.
  872. // dwTrigId [in\out] : Trigger id.
  873. //
  874. // Return Value:
  875. // WBEM_S_NO_ERROR if successful.
  876. // Otherwise failure error code.
  877. //***************************************************************************
  878. HRESULT CTriggerProvider::DeleteTrigger( VARIANT varTName, DWORD *dwTrigId )
  879. {
  880. HRESULT hRes = 0;
  881. IEnumWbemClassObject *pIEventBinder = NULL;
  882. IWbemClassObject *pINTCons = NULL;
  883. DWORD dwReturned = 1;
  884. DWORD i =0;
  885. DWORD j = 0;
  886. TCHAR szTemp[MAX_RES_STRING1];
  887. TCHAR szTemp1[MAX_RES_STRING1];
  888. VARIANT varTemp;
  889. BSTR bstrFilInst = NULL;
  890. DWORD dwFlag = 0;
  891. wchar_t *szwTemp2 = NULL;
  892. wchar_t szwFilName[100];
  893. try
  894. {
  895. _bstr_t bstrBinInst;
  896. CHString strTScheduler = NULL_STRING;
  897. memset( szTemp, 0, sizeof( szTemp ) );
  898. memset( szTemp1, 0, sizeof( szTemp1 ) );
  899. memset( szwFilName, 0, sizeof( szwFilName ) );
  900. wsprintf( szTemp, TRIGGER_INSTANCE_NAME, varTName.bstrVal );
  901. hRes = m_pServices->ExecQuery( QUERY_LANGUAGE, _bstr_t( szTemp ),
  902. WBEM_FLAG_RETURN_IMMEDIATELY| WBEM_FLAG_FORWARD_ONLY, NULL,
  903. &pIEventBinder );
  904. memset( szTemp, 0, sizeof( szTemp ) );
  905. if( FAILED( hRes ) )
  906. {
  907. return hRes;
  908. }
  909. while ( ( dwReturned == 1 ) && ( dwFlag == 0 ) )
  910. {
  911. // Enumerate through the resultset.
  912. hRes = pIEventBinder->Next( WBEM_INFINITE,
  913. 1, // return just one service
  914. &pINTCons, // pointer to service
  915. &dwReturned ); // number obtained: one or zero
  916. if ( SUCCEEDED( hRes ) && ( dwReturned == 1 ) )
  917. {
  918. dwFlag = 1;
  919. } // If Service Succeeded
  920. }
  921. SAFERELEASE( pIEventBinder );
  922. if( dwFlag == 0 )
  923. {
  924. SAFERELEASE( pINTCons );
  925. return ERROR_TRIGGER_NOT_FOUND;
  926. }
  927. VariantInit( &varTemp );
  928. hRes = pINTCons->Get( TRIGGER_ID, 0, &varTemp, 0, NULL );
  929. if (FAILED( hRes ) )
  930. {
  931. SAFERELEASE( pIEventBinder );
  932. SAFERELEASE( pINTCons );
  933. return hRes;
  934. }
  935. *dwTrigId = ( DWORD )varTemp.lVal;
  936. VariantClear( &varTemp );
  937. hRes = pINTCons->Get( TASK_SHEDULER, 0, &varTemp, 0, NULL );
  938. if (FAILED( hRes ) )
  939. {
  940. SAFERELEASE( pIEventBinder );
  941. SAFERELEASE( pINTCons );
  942. return hRes;
  943. }
  944. SAFERELEASE( pINTCons );
  945. strTScheduler = (LPCWSTR) _bstr_t(varTemp.bstrVal);
  946. VariantClear( &varTemp );
  947. if( strTScheduler.GetLength() > 0 )
  948. {
  949. hRes = DeleteTaskScheduler( strTScheduler );
  950. if ( hRes != WBEM_S_NO_ERROR )
  951. {
  952. return hRes;
  953. }
  954. }
  955. wsprintf( szTemp, BIND_CONSUMER_PATH, *dwTrigId );
  956. //enumerate the binding class
  957. hRes = m_pServices->CreateInstanceEnum(
  958. _bstr_t(BINDINGCLASS),
  959. WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY,
  960. NULL, &pIEventBinder );
  961. if ( SUCCEEDED( hRes ) )
  962. {
  963. dwReturned = 1;
  964. dwFlag = 0;
  965. //loop through all the instances of binding class to find that trigger
  966. //id specified. If found loop out and proceed else return error
  967. // Final Next will return with ulReturned = 0
  968. while ( ( dwReturned == 1 ) && ( dwFlag == 0 ) )
  969. {
  970. IWbemClassObject *pIBind = NULL;
  971. // Enumerate through the resultset.
  972. hRes = pIEventBinder->Next( WBEM_INFINITE,
  973. 1, // return just one Logfile
  974. &pIBind, // pointer to Logfile
  975. &dwReturned ); // number obtained: one or zero
  976. if ( SUCCEEDED( hRes ) && ( dwReturned == 1 ) )
  977. {
  978. VariantInit(&varTemp);
  979. //get consumer property of binding class
  980. hRes = pIBind->Get( CONSUMER_BIND, 0, &varTemp, 0, NULL );
  981. if ( SUCCEEDED( hRes ) )
  982. {
  983. if (varTemp.vt != VT_NULL && varTemp.vt != VT_EMPTY)
  984. {
  985. CHString strTemp;
  986. strTemp = varTemp.bstrVal;
  987. //compare with the inputed value
  988. if( wcscmp( szTemp, strTemp ) == 0 )
  989. {
  990. VariantClear( &varTemp );
  991. //get the filter property
  992. hRes = pIBind->Get( FILTER_BIND, 0, &varTemp, 0, NULL );
  993. if ( hRes != WBEM_S_NO_ERROR )
  994. {
  995. SAFERELEASE( pIBind );
  996. break;
  997. }
  998. bstrFilInst = SysAllocString( varTemp.bstrVal );
  999. dwFlag = 1;
  1000. }
  1001. }
  1002. else
  1003. {
  1004. SAFERELEASE( pIBind );
  1005. break;
  1006. }
  1007. }
  1008. else
  1009. {
  1010. SAFERELEASE( pIBind );
  1011. break;
  1012. }
  1013. SAFERELEASE( pIBind );
  1014. VariantClear( &varTemp );
  1015. }
  1016. else
  1017. {
  1018. break;
  1019. }
  1020. } //end of while
  1021. SAFERELEASE( pIEventBinder );
  1022. }
  1023. else
  1024. {
  1025. return( hRes );
  1026. }
  1027. //if instance has been found delete the instances from consumer,filter
  1028. // and binding class
  1029. if( dwFlag == 1 )
  1030. {
  1031. //get the key properties for binding class
  1032. wsprintf( szTemp1, FILTER_PROP, szTemp );
  1033. szwTemp2 = (wchar_t *) bstrFilInst;
  1034. //manpulate the filter property value to insert the filter name property
  1035. // value in quotes
  1036. i =0;
  1037. while( szwTemp2[i] != EQUAL )
  1038. {
  1039. i++;
  1040. }
  1041. i += 2;
  1042. j = 0;
  1043. while( szwTemp2[i] != DOUBLE_QUOTE )
  1044. {
  1045. szwFilName[j] = ( wchar_t )szwTemp2[i];
  1046. i++;
  1047. j++;
  1048. }
  1049. szwFilName[j] = END_OF_STRING;
  1050. bstrBinInst = _bstr_t( szTemp1 ) + _bstr_t( szwFilName ) + _bstr_t(DOUBLE_SLASH);
  1051. //got it so delete the instance
  1052. hRes = m_pServices->DeleteInstance( bstrBinInst, 0, 0, NULL );
  1053. if( FAILED( hRes ) )
  1054. {
  1055. SysFreeString( bstrFilInst );
  1056. return hRes;
  1057. }
  1058. //deleting instance from EventFilter class
  1059. hRes = m_pServices->DeleteInstance( bstrFilInst, 0, 0, NULL );
  1060. if( FAILED( hRes ) )
  1061. {
  1062. SysFreeString( bstrFilInst );
  1063. return hRes;
  1064. }
  1065. //deleting instance from TriggerEventConsumer Class
  1066. hRes = m_pServices->DeleteInstance( _bstr_t(szTemp), 0, 0, NULL );
  1067. if( FAILED( hRes ) )
  1068. {
  1069. SysFreeString( bstrFilInst );
  1070. return hRes;
  1071. }
  1072. SysFreeString( bstrFilInst );
  1073. }
  1074. else
  1075. return( ERROR_TRIGGER_NOT_DELETED );
  1076. }
  1077. catch(_com_error& e)
  1078. {
  1079. return hRes;
  1080. }
  1081. catch( CHeap_Exception )
  1082. {
  1083. return E_OUTOFMEMORY;
  1084. }
  1085. return WBEM_S_NO_ERROR;
  1086. }
  1087. //***************************************************************************
  1088. // Routine Description:
  1089. // This routine queries task scheduler for account information
  1090. //
  1091. // Arguments:
  1092. // varScheduledTaskName [in] : Task scheduler name.
  1093. // szRunAsUser [out] : stores account information.
  1094. //
  1095. // Return Value:
  1096. // WBEM_S_NO_ERROR if successful.
  1097. // Otherwise failure error code.
  1098. //***************************************************************************
  1099. HRESULT CTriggerProvider::QueryTrigger( VARIANT varScheduledTaskName, CHString &szRunAsUser )
  1100. {
  1101. HRESULT hRes = 0;
  1102. ITaskScheduler *pITaskScheduler = NULL;
  1103. IEnumWorkItems *pIEnum = NULL;
  1104. ITask *pITask = NULL;
  1105. LPWSTR *lpwszNames = NULL;
  1106. DWORD dwFetchedTasks = 0;
  1107. TCHAR szActualTask[MAX_STRING_LENGTH] = NULL_STRING;
  1108. try
  1109. {
  1110. pITaskScheduler = GetTaskScheduler();
  1111. if ( pITaskScheduler == NULL )
  1112. {
  1113. hRes = E_FAIL;
  1114. return hRes;
  1115. }
  1116. hRes = pITaskScheduler->Enum( &pIEnum );
  1117. if( FAILED( hRes ) )
  1118. {
  1119. return hRes;
  1120. }
  1121. while ( SUCCEEDED( pIEnum->Next( 1,
  1122. &lpwszNames,
  1123. &dwFetchedTasks ) )
  1124. && (dwFetchedTasks != 0))
  1125. {
  1126. while (dwFetchedTasks)
  1127. {
  1128. // Check whether the TaskName is present, if present
  1129. // then return arrJobs.
  1130. // Convert the Wide Charater to Multi Byte value.
  1131. GetCompatibleStringFromUnicode( lpwszNames[ --dwFetchedTasks ], szActualTask, SIZE_OF_ARRAY( szActualTask ) );
  1132. // Parse the TaskName to remove the .job extension.
  1133. szActualTask[lstrlen(szActualTask ) - lstrlen(JOB) ] = NULL_CHAR;
  1134. StrTrim( szActualTask, TRIM_SPACES );
  1135. CHString strTemp;
  1136. strTemp = varScheduledTaskName.bstrVal;
  1137. if( lstrcmpi( szActualTask, strTemp ) == 0 )
  1138. {
  1139. hRes = pITaskScheduler->Activate( szActualTask, IID_ITask, (IUnknown**) &pITask );
  1140. if( SUCCEEDED( hRes ) )
  1141. {
  1142. LPWSTR lpwszUser = NULL;
  1143. hRes = pITask->GetAccountInformation( &lpwszUser );
  1144. if( SUCCEEDED( hRes ) )
  1145. {
  1146. szRunAsUser = ( LPWSTR ) lpwszUser;
  1147. }
  1148. }
  1149. }
  1150. CoTaskMemFree( lpwszNames[ dwFetchedTasks ] );
  1151. }//end while
  1152. CoTaskMemFree( lpwszNames );
  1153. }
  1154. pIEnum->Release();
  1155. }
  1156. catch(_com_error& e)
  1157. {
  1158. return hRes;
  1159. }
  1160. catch( CHeap_Exception )
  1161. {
  1162. return E_OUTOFMEMORY;
  1163. }
  1164. return hRes;
  1165. }
  1166. //***************************************************************************
  1167. // Routine Description:
  1168. // This routine validates input parameters trigger name,
  1169. // Trigger Query, Trigger Desc, Trigger Action.
  1170. //
  1171. // Arguments:
  1172. // varTrigName [in]: Trigger Name.
  1173. // varTrigAction [in] : Trigger Action.
  1174. // varTrigQuery [in] : Trigger Query.
  1175. //
  1176. // Return Value:
  1177. // WBEM_S_NO_ERROR if successful.
  1178. // WBEM_E_INVALID_PARAMETER if invalid inputs.
  1179. //***************************************************************************
  1180. HRESULT CTriggerProvider::ValidateParams( VARIANT varTrigName,
  1181. VARIANT varTrigAction,
  1182. VARIANT varTrigQuery )
  1183. {
  1184. //local variables
  1185. HRESULT hRes = 0;
  1186. IEnumWbemClassObject *pINTEConsumer = NULL;
  1187. DWORD dwReturned = 0;
  1188. DWORD dwFlag = 0;
  1189. TCHAR szTemp[MAX_RES_STRING1];
  1190. TCHAR szTemp1[MAX_RES_STRING1];
  1191. LPTSTR lpSubStr = NULL;
  1192. try
  1193. {
  1194. CHString strTemp = NULL_STRING;
  1195. //check if input values are null
  1196. if ( varTrigName.vt == VT_NULL )
  1197. {
  1198. return ( WBEM_E_INVALID_PARAMETER );
  1199. }
  1200. if ( varTrigAction.vt == VT_NULL )
  1201. {
  1202. return ( WBEM_E_INVALID_PARAMETER );
  1203. }
  1204. if( varTrigQuery.vt == VT_NULL )
  1205. {
  1206. return ( WBEM_E_INVALID_PARAMETER );
  1207. }
  1208. //validate trigger name
  1209. strTemp = (LPCWSTR) _bstr_t(varTrigName.bstrVal);
  1210. dwReturned = strTemp.FindOneOf( L"[]:|<>+=;,?$#{}~^'@`!()*%\\/" );
  1211. if( dwReturned != -1 )
  1212. {
  1213. return ( WBEM_E_INVALID_PARAMETER );
  1214. }
  1215. //validate trigger query
  1216. memset( szTemp, 0, sizeof( szTemp ) );
  1217. memset( szTemp1, 0, sizeof( szTemp1 ) );
  1218. strTemp = (LPCWSTR) _bstr_t(varTrigQuery.bstrVal);
  1219. GetCompatibleStringFromUnicode( ( LPCWSTR )strTemp, szTemp, MAX_RES_STRING1 );
  1220. lpSubStr = _tcsstr( szTemp, _T( "__instancecreationevent where targetinstance isa \"win32_ntlogevent\"" ) );
  1221. if( lpSubStr == NULL )
  1222. {
  1223. return ( WBEM_E_INVALID_PARAMETER );
  1224. }
  1225. //make the SQL staements to query trigger event consumer class to check whether
  1226. //an instance with the inputted trigger is already exists
  1227. strTemp = (LPCWSTR) _bstr_t(varTrigName.bstrVal);
  1228. memset( szTemp, 0, sizeof( szTemp ) );
  1229. GetCompatibleStringFromUnicode( (LPCWSTR)strTemp, szTemp, MAX_RES_STRING1 );
  1230. wsprintf(szTemp1, CONSUMER_QUERY, szTemp );
  1231. //query triggereventconsumer class
  1232. hRes = m_pServices->ExecQuery( QUERY_LANGUAGE, _bstr_t( szTemp1 ),
  1233. WBEM_FLAG_RETURN_IMMEDIATELY| WBEM_FLAG_FORWARD_ONLY, NULL,
  1234. &pINTEConsumer );
  1235. //enumerate the result set of execquery for trigger name
  1236. dwReturned = 1;
  1237. if ( hRes == WBEM_S_NO_ERROR )
  1238. {
  1239. while ( ( dwReturned == 1 ) && ( dwFlag == 0 ) )
  1240. {
  1241. IWbemClassObject *pINTCons = NULL;
  1242. // Enumerate through the resultset.
  1243. hRes = pINTEConsumer->Next( WBEM_INFINITE,
  1244. 1, // return just one service
  1245. &pINTCons, // pointer to service
  1246. &dwReturned ); // number obtained: one or zero
  1247. if ( SUCCEEDED( hRes ) && ( dwReturned == 1 ) )
  1248. {
  1249. SAFERELEASE( pINTCons );
  1250. dwFlag = 1;
  1251. } // If Service Succeeded
  1252. }
  1253. SAFERELEASE( pINTEConsumer );
  1254. }
  1255. if( dwFlag == 1 )
  1256. {
  1257. return ERROR_TRIGNAME_ALREADY_EXIST;
  1258. }
  1259. else
  1260. {
  1261. return WBEM_S_NO_ERROR;
  1262. }
  1263. }
  1264. catch(_com_error& e)
  1265. {
  1266. return hRes;
  1267. }
  1268. catch( CHeap_Exception )
  1269. {
  1270. return E_OUTOFMEMORY;
  1271. }
  1272. //return WBEM_S_NO_ERROR;
  1273. }
  1274. //***************************************************************************
  1275. // Routine Description:
  1276. // This routine creates task scheduler.
  1277. //
  1278. // Arguments:
  1279. // varTName [in] : Trigger Name.
  1280. // varRUser [in] : User name.
  1281. // varRPwd [in] : Password.
  1282. // varTAction [in] : TriggerAction.
  1283. // szscheduler [in] : Task scheduler name.
  1284. //
  1285. // Return Value:
  1286. // Returns HRESULT value.
  1287. //***************************************************************************
  1288. HRESULT CTriggerProvider::SetUserContext( VARIANT varRUser, VARIANT varRPwd,
  1289. VARIANT varTAction, CHString &szscheduler )
  1290. {
  1291. HRESULT hRes = 0;
  1292. ITaskScheduler *pITaskScheduler = NULL;
  1293. ITaskTrigger *pITaskTrig = NULL;
  1294. ITask *pITask = NULL;
  1295. IPersistFile *pIPF = NULL;
  1296. try
  1297. {
  1298. CHString strTemp = NULL_STRING;
  1299. CHString strTemp1 = NULL_STRING;
  1300. SYSTEMTIME systime = {0,0,0,0,0,0,0,0};
  1301. WORD wTrigNumber = 0;
  1302. WCHAR wszCommand[ MAX_STRING_LENGTH ] = NULL_STRING;
  1303. WCHAR wszApplName[ MAX_STRING_LENGTH ] = NULL_STRING;
  1304. WCHAR wszParams[ MAX_STRING_LENGTH ] = L"";
  1305. WORD wStartDay = 0;
  1306. WORD wStartMonth = 0;
  1307. WORD wStartYear = 0;
  1308. WORD wStartHour = 0;
  1309. WORD wStartMin = 0;
  1310. TASK_TRIGGER TaskTrig;
  1311. ZeroMemory(&TaskTrig, sizeof (TASK_TRIGGER));
  1312. TaskTrig.cbTriggerSize = sizeof (TASK_TRIGGER);
  1313. TaskTrig.Reserved1 = 0; // reserved field and must be set to 0.
  1314. TaskTrig.Reserved2 = 0; // reserved field and must be set to 0.
  1315. strTemp = (LPCWSTR) _bstr_t(varTAction.bstrVal);
  1316. if( GetAsUnicodeString( (LPCWSTR) strTemp, wszCommand, SIZE_OF_ARRAY( wszCommand ) ) == NULL )
  1317. {
  1318. return E_FAIL;
  1319. }
  1320. pITaskScheduler = GetTaskScheduler( );
  1321. if ( pITaskScheduler == NULL )
  1322. {
  1323. return E_FAIL;
  1324. }
  1325. hRes = pITaskScheduler->NewWorkItem( szscheduler, CLSID_CTask, IID_ITask,
  1326. ( IUnknown** )&pITask );
  1327. if( FAILED( hRes ) )
  1328. {
  1329. return hRes;
  1330. }
  1331. hRes = pITask->QueryInterface( IID_IPersistFile, ( void ** ) &pIPF );
  1332. if ( FAILED( hRes ) )
  1333. {
  1334. SAFERELEASE( pIPF );
  1335. SAFERELEASE( pITask );
  1336. return hRes;
  1337. }
  1338. BOOL bRet = ProcessFilePath( wszCommand, wszApplName, wszParams );
  1339. if( bRet == FALSE )
  1340. {
  1341. SAFERELEASE( pIPF );
  1342. SAFERELEASE( pITask );
  1343. return WBEM_E_INVALID_PARAMETER;
  1344. }
  1345. hRes = pITask->SetApplicationName( wszApplName );
  1346. if ( FAILED( hRes ) )
  1347. {
  1348. SAFERELEASE( pIPF );
  1349. SAFERELEASE( pITask );
  1350. return hRes;
  1351. }
  1352. wchar_t* wcszStartIn = wcsrchr( wszApplName, _T('\\') );
  1353. if( wcszStartIn != NULL )
  1354. *( wcszStartIn ) = _T( '\0' );
  1355. hRes = pITask->SetWorkingDirectory( wszApplName );
  1356. if ( FAILED( hRes ) )
  1357. {
  1358. SAFERELEASE( pIPF );
  1359. SAFERELEASE( pITask );
  1360. return hRes;
  1361. }
  1362. hRes = pITask->SetParameters( wszParams );
  1363. if ( FAILED( hRes ) )
  1364. {
  1365. SAFERELEASE( pIPF );
  1366. SAFERELEASE( pITask );
  1367. return hRes;
  1368. }
  1369. DWORD dwMaxRunTimeMS = INFINITE;
  1370. hRes = pITask->SetMaxRunTime(dwMaxRunTimeMS);
  1371. if ( FAILED( hRes ) )
  1372. {
  1373. SAFERELEASE( pIPF );
  1374. SAFERELEASE( pITask );
  1375. return hRes;
  1376. }
  1377. if( varRUser.vt != VT_NULL && varRUser.vt != VT_EMPTY )
  1378. {
  1379. strTemp = (LPCWSTR)_bstr_t(varRUser.bstrVal);
  1380. strTemp1 = (LPCWSTR)_bstr_t(varRPwd.bstrVal);
  1381. hRes = pITask->SetAccountInformation( ( LPCWSTR ) strTemp, ( LPCWSTR )strTemp1 );
  1382. }
  1383. else
  1384. {
  1385. strTemp = (LPCWSTR)_bstr_t(varRUser.bstrVal);
  1386. hRes = pITask->SetAccountInformation( ( LPCWSTR )strTemp, NULL_STRING );
  1387. }
  1388. if ( FAILED( hRes ) )
  1389. {
  1390. SAFERELEASE( pIPF );
  1391. SAFERELEASE( pITask );
  1392. return hRes;
  1393. }
  1394. GetLocalTime(&systime);
  1395. wStartDay = systime.wDay;
  1396. wStartMonth = systime.wMonth;
  1397. wStartYear = systime.wYear - 1;
  1398. GetLocalTime(&systime);
  1399. wStartHour = systime.wHour;
  1400. wStartMin = systime.wMinute;
  1401. hRes = pITask->CreateTrigger( &wTrigNumber, &pITaskTrig );
  1402. if ( FAILED( hRes ) )
  1403. {
  1404. SAFERELEASE( pIPF );
  1405. SAFERELEASE( pITask );
  1406. SAFERELEASE( pITaskTrig );
  1407. return hRes;
  1408. }
  1409. TaskTrig.TriggerType = TASK_TIME_TRIGGER_ONCE;
  1410. TaskTrig.wStartHour = wStartHour;
  1411. TaskTrig.wStartMinute = wStartMin;
  1412. TaskTrig.wBeginDay = wStartDay;
  1413. TaskTrig.wBeginMonth = wStartMonth;
  1414. TaskTrig.wBeginYear = wStartYear;
  1415. hRes = pITaskTrig->SetTrigger( &TaskTrig );
  1416. if ( FAILED( hRes ) )
  1417. {
  1418. SAFERELEASE( pIPF );
  1419. SAFERELEASE( pITask );
  1420. SAFERELEASE( pITaskTrig );
  1421. return hRes;
  1422. }
  1423. hRes = pIPF->Save( NULL,TRUE );
  1424. SAFERELEASE( pIPF );
  1425. SAFERELEASE( pITask );
  1426. SAFERELEASE( pITaskTrig );
  1427. }
  1428. catch(_com_error& e)
  1429. {
  1430. return hRes;
  1431. }
  1432. catch( CHeap_Exception )
  1433. {
  1434. return E_OUTOFMEMORY;
  1435. }
  1436. return hRes;
  1437. }
  1438. //***************************************************************************
  1439. // Routine Description:
  1440. // This routine deletes task scheduler.
  1441. //
  1442. // Arguments:
  1443. // szTScheduler [in] : Task Scheduler name.
  1444. //
  1445. // Return Value:
  1446. // Returns HRESULT value.
  1447. //***************************************************************************
  1448. HRESULT CTriggerProvider::DeleteTaskScheduler( CHString strTScheduler )
  1449. {
  1450. HRESULT hRes = 0;
  1451. ITaskScheduler *pITaskScheduler = NULL;
  1452. IEnumWorkItems *pIEnum = NULL;
  1453. LPWSTR *lpwszNames = NULL;
  1454. DWORD dwFetchedTasks = 0;
  1455. TCHAR szActualTask[MAX_RES_STRING1] = NULL_STRING;
  1456. try
  1457. {
  1458. pITaskScheduler = GetTaskScheduler();
  1459. if ( pITaskScheduler == NULL )
  1460. {
  1461. return E_FAIL;
  1462. }
  1463. // Enumerate the Work Items
  1464. hRes = pITaskScheduler->Enum( &pIEnum );
  1465. if( FAILED( hRes ) )
  1466. {
  1467. SAFERELEASE( pIEnum );
  1468. return hRes;
  1469. }
  1470. while ( SUCCEEDED( pIEnum->Next( 1,
  1471. &lpwszNames,
  1472. &dwFetchedTasks ) )
  1473. && (dwFetchedTasks != 0))
  1474. {
  1475. while (dwFetchedTasks)
  1476. {
  1477. // Check whether the TaskName is present, if present
  1478. // then return arrJobs.
  1479. // Convert the Wide Charater to Multi Byte value.
  1480. if ( GetCompatibleStringFromUnicode( lpwszNames[ --dwFetchedTasks ],
  1481. szActualTask,
  1482. SIZE_OF_ARRAY( szActualTask ) ) == NULL )
  1483. {
  1484. CoTaskMemFree( lpwszNames[ dwFetchedTasks] );
  1485. SAFERELEASE( pIEnum );
  1486. return hRes;
  1487. }
  1488. // Parse the TaskName to remove the .job extension.
  1489. szActualTask[lstrlen(szActualTask ) - lstrlen(JOB) ] = NULL_CHAR;
  1490. StrTrim( szActualTask, TRIM_SPACES );
  1491. if( lstrcmpi( szActualTask, strTScheduler ) == 0 )
  1492. {
  1493. hRes = pITaskScheduler->Delete( szActualTask );
  1494. CoTaskMemFree( lpwszNames[ dwFetchedTasks ] );
  1495. SAFERELEASE( pIEnum );
  1496. return hRes;
  1497. }
  1498. }//end while
  1499. }
  1500. }
  1501. catch(_com_error& e)
  1502. {
  1503. return hRes;
  1504. }
  1505. return ERROR_TRIGGER_NOT_DELETED;
  1506. }
  1507. //***************************************************************************
  1508. // Routine Description:
  1509. // This routine gets task scheduler interface.
  1510. //
  1511. // Arguments:
  1512. // none.
  1513. //
  1514. // Return Value:
  1515. // Returns ITaskScheduler interface.
  1516. //***************************************************************************
  1517. ITaskScheduler* CTriggerProvider::GetTaskScheduler()
  1518. {
  1519. HRESULT hRes = S_OK;
  1520. ITaskScheduler *pITaskScheduler = NULL;
  1521. hRes = CoCreateInstance( CLSID_CTaskScheduler, NULL, CLSCTX_ALL,
  1522. IID_ITaskScheduler,(LPVOID*) &pITaskScheduler );
  1523. if( FAILED(hRes))
  1524. {
  1525. return NULL;
  1526. }
  1527. hRes = pITaskScheduler->SetTargetComputer( NULL );
  1528. return pITaskScheduler;
  1529. }
  1530. //***************************************************************************
  1531. // Routine Description:
  1532. // This routine generates unique task scheduler name.
  1533. //
  1534. // Arguments:
  1535. // szScheduler [in\out] : Unique task scheduler name.
  1536. // dwTrigID [in] : Trigger id.
  1537. // varTrigName [in] : Trigger name.
  1538. //
  1539. // Return Value:
  1540. // none.
  1541. //***************************************************************************
  1542. VOID CTriggerProvider::GetUniqueTScheduler( CHString& szScheduler, DWORD dwTrigID, VARIANT varTrigName )
  1543. {
  1544. DWORD dwTickCount = 0;
  1545. TCHAR szTaskName[ MAX_RES_STRING1 ] = NULL_STRING;
  1546. CHString strTemp = NULL_STRING;
  1547. strTemp = (LPCWSTR)_bstr_t(varTrigName.bstrVal);
  1548. dwTickCount = GetTickCount();
  1549. wsprintf( szTaskName, UNIQUE_TASK_NAME, ( LPCWSTR )strTemp, dwTrigID, dwTickCount );
  1550. szScheduler = szTaskName;
  1551. }
  1552. //***************************************************************************
  1553. // Routine Description:
  1554. // When Windows Management needs to deliver events to a
  1555. // particular logical consumer, it will call the
  1556. // IWbemEventConsumerProvider::FindConsumer method so that
  1557. // the consumer provider can locate the associated consumer event sink.
  1558. //
  1559. // Arguments:
  1560. // pLogicalConsumer [in] : Pointer to the logical consumer object
  1561. // to which the event objects are to be delivered.
  1562. // ppConsumer [out]: Returns an event object sink to Windows
  1563. // Management. Windows Management calls
  1564. // AddRef for this pointer and deliver the
  1565. // events associated with the logical
  1566. // consumer to this sink.
  1567. //
  1568. // Return Value:
  1569. // returns an HRESULT object that indicates the status of the method call.
  1570. //***************************************************************************
  1571. STDMETHODIMP CTriggerProvider::FindConsumer( IWbemClassObject* pLogicalConsumer,
  1572. IWbemUnboundObjectSink** ppConsumer )
  1573. {
  1574. // create the logical consumer.
  1575. CTriggerConsumer* pSink = new CTriggerConsumer();
  1576. // return it's "sink" interface.
  1577. return pSink->QueryInterface( IID_IWbemUnboundObjectSink, ( LPVOID* ) ppConsumer );
  1578. }