Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2061 lines
69 KiB

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