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.

402 lines
12 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation
  3. Module Name:
  4. TRIGGERCONSUMER.CPP
  5. Abstract:
  6. Contains CEventConsumer implementation.
  7. Author:
  8. Vasundhara .G
  9. Revision History:
  10. Vasundhara .G 9-oct-2k : Created It.
  11. --*/
  12. #include "pch.h"
  13. #include "EventConsumerProvider.h"
  14. #include "General.h"
  15. #include "TriggerConsumer.h"
  16. #include "resource.h"
  17. extern HMODULE g_hModule;
  18. #define PROPERTY_COMMAND _T( "Action" )
  19. #define PROPERTY_TRIGID _T( "TriggerID" )
  20. #define PROPERTY_NAME _T( "TriggerName" )
  21. #define PROPERTY_SHEDULE _T( "ScheduledTaskName" )
  22. #define SPACE _T( " " )
  23. #define SLASH _T( "\\" )
  24. #define NEWLINE _T( "\0" )
  25. CTriggerConsumer::CTriggerConsumer(
  26. )
  27. /*++
  28. Routine Description:
  29. Constructor for CTriggerConsumer class for initialization.
  30. Arguments:
  31. None.
  32. Return Value:
  33. None.
  34. --*/
  35. {
  36. // initialize the reference count variable
  37. m_dwCount = 0;
  38. }
  39. CTriggerConsumer::~CTriggerConsumer(
  40. )
  41. /*++
  42. Routine Description:
  43. Desstructor for CTriggerConsumer class.
  44. Arguments:
  45. None.
  46. Return Value:
  47. None.
  48. --*/
  49. {
  50. // there is nothing much to do at this place ...
  51. }
  52. STDMETHODIMP
  53. CTriggerConsumer::QueryInterface(
  54. IN REFIID riid,
  55. OUT LPVOID* ppv
  56. )
  57. /*++
  58. Routine Description:
  59. Returns a pointer to a specified interface on an object
  60. to which a client currently holds an interface pointer.
  61. Arguments:
  62. [IN] riid : Identifier of the interface being requested.
  63. [OUT] ppv :Address of pointer variable that receives the
  64. interface pointer requested in riid. Upon successful
  65. return, *ppvObject contains the requested interface
  66. pointer to the object.
  67. Return Value:
  68. NOERROR if the interface is supported.
  69. E_NOINTERFACE if not.
  70. --*/
  71. {
  72. // initialy set to NULL
  73. *ppv = NULL;
  74. // check whether interface requested is one we have
  75. if ( riid == IID_IUnknown || riid == IID_IWbemUnboundObjectSink )
  76. {
  77. //
  78. // yes ... requested interface exists
  79. *ppv = this; // set the out parameter for the returning the requested interface
  80. this->AddRef(); // update the reference count
  81. return NOERROR; // inform success
  82. }
  83. // interface is not available
  84. return E_NOINTERFACE;
  85. }
  86. STDMETHODIMP_(ULONG)
  87. CTriggerConsumer::AddRef(
  88. void
  89. )
  90. /*++
  91. Routine Description:
  92. The AddRef method increments the reference count for
  93. an interface on an object. It should be called for every
  94. new copy of a pointer to an interface on a given object.
  95. Arguments:
  96. none.
  97. Return Value:
  98. Returns the value of the new reference count.
  99. --*/
  100. {
  101. // increment the reference count ... thread safe
  102. return InterlockedIncrement( ( LPLONG ) &m_dwCount );
  103. }
  104. STDMETHODIMP_(ULONG)
  105. CTriggerConsumer::Release(
  106. void
  107. )
  108. /*++
  109. Routine Description:
  110. The Release method decreases the reference count of the object by 1.
  111. Arguments:
  112. none.
  113. Return Value:
  114. Returns the new reference count.
  115. --*/
  116. {
  117. // decrement the reference count ( thread safe ) and check whether
  118. // there are some more references or not ... based on the result value
  119. DWORD dwCount = 0;
  120. dwCount = InterlockedDecrement( ( LPLONG ) &m_dwCount );
  121. if ( 0 == dwCount )
  122. {
  123. // free the current factory instance
  124. delete this;
  125. }
  126. // return the no. of instances references left
  127. return dwCount;
  128. }
  129. STDMETHODIMP
  130. CTriggerConsumer::IndicateToConsumer(
  131. IN IWbemClassObject* pLogicalConsumer,
  132. IN LONG lNumObjects,
  133. IN IWbemClassObject **ppObjects
  134. )
  135. /*++
  136. Routine Description:
  137. IndicateToConsumer method is called by Windows Management
  138. to actually deliver events to a consumer.
  139. Arguments:
  140. [IN] pLogicalCosumer : Pointer to the logical consumer object
  141. for which this set of objects is delivered.
  142. [IN] lNumObjects : Number of objects delivered in the array that follows.
  143. [IN] ppObjects : Pointer to an array of IWbemClassObject
  144. instances which represent the events delivered.
  145. Return Value:
  146. Returns WBEM_S_NO_ERROR if successful.
  147. Otherwise error.
  148. --*/
  149. {
  150. TCHAR szCommand[ MAX_STRING_LENGTH ] = NULL_STRING;
  151. TCHAR szName[ MAX_STRING_LENGTH ] = NULL_STRING;
  152. TCHAR szTask[ MAX_STRING_LENGTH ] = NULL_STRING;
  153. TCHAR szPath[ MAX_STRING_LENGTH ] = NULL_STRING;
  154. DWORD dwID = 0;
  155. HRESULT hRes = 0;
  156. BOOL bResult = FALSE;
  157. VARIANT varValue;
  158. VARIANT varScheduler;
  159. ITaskScheduler *pITaskScheduler = NULL;
  160. IEnumWorkItems *pIEnum = NULL;
  161. ITask *pITask = NULL;
  162. SecureZeroMemory( szCommand, MAX_STRING_LENGTH * sizeof( TCHAR ) );
  163. SecureZeroMemory( szName, MAX_STRING_LENGTH * sizeof( TCHAR ) );
  164. SecureZeroMemory( szPath, MAX_STRING_LENGTH * sizeof( TCHAR ) );
  165. SecureZeroMemory( szTask, MAX_STRING_LENGTH * sizeof( TCHAR ) );
  166. // get the 'Item' property values out of the embedded object.
  167. hRes = PropertyGet( pLogicalConsumer, PROPERTY_COMMAND, 0, szCommand, SIZE_OF_ARRAY( szCommand ) );
  168. if ( FAILED( hRes ) )
  169. {
  170. return hRes;
  171. }
  172. // get the trigger name.
  173. hRes = PropertyGet( pLogicalConsumer, PROPERTY_NAME, 0, szName, SIZE_OF_ARRAY( szName ) );
  174. if( FAILED( hRes ) )
  175. {
  176. return hRes;
  177. }
  178. VariantInit( &varScheduler );
  179. hRes = pLogicalConsumer->Get( PROPERTY_SHEDULE, 0, &varScheduler, NULL, NULL );
  180. if( FAILED( hRes ) )
  181. {
  182. VariantClear( &varScheduler );
  183. return hRes;
  184. }
  185. try
  186. {
  187. StringCopy( szTask, ( LPCWSTR ) _bstr_t( varScheduler ), SIZE_OF_ARRAY( szTask ) );
  188. }
  189. catch( _com_error& e )
  190. {
  191. VariantClear( &varScheduler );
  192. return e.Error();
  193. }
  194. VariantInit( &varValue );
  195. hRes = pLogicalConsumer->Get( PROPERTY_TRIGID, 0, &varValue, NULL, NULL );
  196. if( FAILED( hRes ) )
  197. {
  198. VariantClear( &varScheduler );
  199. VariantClear( &varValue );
  200. return hRes;
  201. }
  202. if( VT_NULL == varValue.vt || VT_EMPTY == varValue.vt )
  203. {
  204. VariantClear( &varScheduler );
  205. VariantClear( &varValue );
  206. return WBEM_E_INVALID_PARAMETER;
  207. }
  208. dwID = varValue.lVal;
  209. VariantClear( &varValue );
  210. try
  211. {
  212. LPWSTR *lpwszNames = NULL;
  213. DWORD dwFetchedTasks = 0;
  214. TCHAR szActualTask[MAX_STRING_LENGTH] = NULL_STRING;
  215. pITaskScheduler = GetTaskScheduler();
  216. if ( NULL == pITaskScheduler )
  217. {
  218. hRes = E_FAIL;
  219. ONFAILTHROWERROR( hRes );
  220. }
  221. hRes = pITaskScheduler->Enum( &pIEnum );
  222. ONFAILTHROWERROR( hRes );
  223. while ( SUCCEEDED( pIEnum->Next( 1,
  224. &lpwszNames,
  225. &dwFetchedTasks ) )
  226. && (dwFetchedTasks != 0))
  227. {
  228. while (dwFetchedTasks)
  229. {
  230. // Convert the Wide Charater to Multi Byte value.
  231. StringCopy( szActualTask, lpwszNames[ --dwFetchedTasks ], SIZE_OF_ARRAY( szActualTask ) );
  232. // Parse the TaskName to remove the .job extension.
  233. szActualTask[StringLength( szActualTask, 0 ) - StringLength( JOB, 0) ] = NULL_CHAR;
  234. StrTrim( szActualTask, TRIM_SPACES );
  235. CHString strTemp;
  236. strTemp = varScheduler.bstrVal;
  237. if( StringCompare( szActualTask, strTemp, TRUE, 0 ) == 0 )
  238. {
  239. hRes = pITaskScheduler->Activate( szActualTask, IID_ITask, (IUnknown**) &pITask );
  240. ONFAILTHROWERROR( hRes );
  241. hRes = pITask->Run();
  242. ONFAILTHROWERROR( hRes );
  243. bResult = TRUE;
  244. }
  245. CoTaskMemFree( lpwszNames[ dwFetchedTasks ] );
  246. }//end while
  247. CoTaskMemFree( lpwszNames );
  248. }
  249. EnterCriticalSection( &g_critical_sec );
  250. if( TRUE == bResult )
  251. {
  252. HRESULT phrStatus;
  253. Sleep( 10000 );
  254. hRes = pITask->GetStatus( &phrStatus );
  255. ONFAILTHROWERROR( hRes );
  256. switch(phrStatus)
  257. {
  258. case SCHED_S_TASK_READY:
  259. LoadStringW( g_hModule, IDS_TRIGGERED, szTask, MAX_STRING_LENGTH );
  260. break;
  261. case SCHED_S_TASK_RUNNING:
  262. LoadStringW( g_hModule, IDS_TRIGGERED, szTask, MAX_STRING_LENGTH );
  263. break;
  264. case SCHED_S_TASK_NOT_SCHEDULED:
  265. LoadStringW( g_hModule, IDS_TRIGGER_FAILED, szTask, MAX_STRING_LENGTH );
  266. break;
  267. default:
  268. LoadStringW( g_hModule, IDS_TRIGGER_NOT_FOUND, szTask, MAX_STRING_LENGTH );
  269. }
  270. ErrorLog( ( LPCTSTR ) szTask, szName, dwID );
  271. }
  272. else
  273. {
  274. LoadStringW( g_hModule, IDS_TRIGGER_NOT_FOUND, szTask, MAX_STRING_LENGTH );
  275. ErrorLog( ( LPCTSTR ) szTask, szName, dwID );
  276. }
  277. LeaveCriticalSection( &g_critical_sec );
  278. } //try
  279. catch(_com_error& e)
  280. {
  281. IWbemStatusCodeText *pIStatus = NULL;
  282. BSTR bstrErr = NULL;
  283. LPTSTR lpResStr = NULL;
  284. VariantClear( &varScheduler );
  285. lpResStr = ( LPTSTR ) AllocateMemory( MAX_RES_STRING );
  286. if ( NULL != lpResStr )
  287. {
  288. if (SUCCEEDED(CoCreateInstance(CLSID_WbemStatusCodeText, 0,
  289. CLSCTX_INPROC_SERVER,
  290. IID_IWbemStatusCodeText,
  291. (LPVOID*) &pIStatus)))
  292. {
  293. if (SUCCEEDED(pIStatus->GetErrorCodeText(e.Error(), 0, 0, &bstrErr)))
  294. {
  295. StringCopy( lpResStr, bstrErr, ( GetBufferSize( lpResStr )/ sizeof( WCHAR ) ) );
  296. }
  297. SAFEBSTRFREE(bstrErr);
  298. EnterCriticalSection( &g_critical_sec );
  299. LoadStringW( g_hModule, IDS_TRIGGER_FAILED, szTask, MAX_STRING_LENGTH );
  300. LoadStringW( g_hModule, IDS_ERROR_CODE, szCommand, MAX_STRING_LENGTH );
  301. StringCchPrintf( szPath, SIZE_OF_ARRAY( szPath ), szCommand, e.Error() );
  302. StringConcat( szTask, szPath, SIZE_OF_ARRAY( szTask ) );
  303. LoadStringW( g_hModule, IDS_REASON, szCommand, MAX_STRING_LENGTH );
  304. StringCchPrintf( szPath, SIZE_OF_ARRAY( szPath ), szCommand , lpResStr );
  305. StringConcat( szTask, szPath, SIZE_OF_ARRAY( szTask ) );
  306. ErrorLog( ( LPCTSTR ) szTask, szName, dwID );
  307. LeaveCriticalSection( &g_critical_sec );
  308. }
  309. SAFERELEASE( pITaskScheduler );
  310. SAFERELEASE( pIEnum );
  311. SAFERELEASE( pITask );
  312. SAFERELEASE(pIStatus);
  313. FreeMemory( (LPVOID*)&lpResStr );
  314. return( e.Error() );
  315. }
  316. }//catch
  317. catch( CHeap_Exception )
  318. {
  319. VariantClear( &varScheduler );
  320. SAFERELEASE( pITaskScheduler );
  321. SAFERELEASE( pIEnum );
  322. SAFERELEASE( pITask );
  323. return E_OUTOFMEMORY;
  324. }
  325. SAFERELEASE( pITaskScheduler );
  326. SAFERELEASE( pIEnum );
  327. SAFERELEASE( pITask );
  328. VariantClear( &varScheduler );
  329. return WBEM_S_NO_ERROR;
  330. }
  331. ITaskScheduler*
  332. CTriggerConsumer::GetTaskScheduler(
  333. )
  334. /*++
  335. Routine Description:
  336. This routine gets task scheduler interface.
  337. Arguments:
  338. none.
  339. Return Value:
  340. Returns ITaskScheduler interface.
  341. --*/
  342. {
  343. HRESULT hRes = S_OK;
  344. ITaskScheduler *pITaskScheduler = NULL;
  345. hRes = CoCreateInstance( CLSID_CTaskScheduler, NULL, CLSCTX_ALL,
  346. IID_ITaskScheduler,(LPVOID*) &pITaskScheduler );
  347. if( FAILED(hRes))
  348. {
  349. return NULL;
  350. }
  351. hRes = pITaskScheduler->SetTargetComputer( NULL );
  352. return pITaskScheduler;
  353. }