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.

653 lines
14 KiB

  1. /******************************************************************************
  2. Copyright(c) Microsoft Corporation
  3. Module Name:
  4. ScheduledTasks.cpp
  5. Abstract:
  6. This module initialises the OLE library,Interfaces, & reads the input data
  7. from the command line.This module calls the appropriate functions for acheiving
  8. the functionality of different options.
  9. Author:
  10. Raghu B 10-Sep-2000
  11. Revision History:
  12. Raghu B 10-Sep-2000 : Created it
  13. G.Surender Reddy 25-sep-2000 : Modified it
  14. [ Added error checking ]
  15. G.Surender Reddy 10-oct-2000 : Modified it
  16. [ Moved the strings to Resource table ]
  17. Venu Gopal Choudary 01-Mar-2001 : Modified it
  18. [ Added -change option]
  19. Venu Gopal Choudary 12-Mar-2001 : Modified it
  20. [ Added -run and -end options]
  21. ******************************************************************************/
  22. //common header files needed for this file
  23. #include "pch.h"
  24. #include "CommonHeaderFiles.h"
  25. //Helper functions used internally from this file
  26. HRESULT Init( ITaskScheduler **pITaskScheduler );
  27. VOID displayMainUsage();
  28. BOOL preProcessOptions( DWORD argc, LPCTSTR argv[], PBOOL pbUsage, PBOOL pbCreate,
  29. PBOOL pbQuery, PBOOL pbDelete, PBOOL pbChange, PBOOL pbRun, PBOOL pbEnd, PBOOL pbDefVal );
  30. /******************************************************************************
  31. Routine Description:
  32. This function process the options specified in the command line & routes to
  33. different appropriate options [-create,-query,-delete,-change,-run,-end]
  34. handling functions.This is the MAIN entry point for this utility.
  35. Arguments:
  36. [ in ] argc : The count of arguments specified in the command line
  37. [ in ] argv : Array of command line arguments
  38. Return Value :
  39. A DWORD value indicating EXIT_SUCCESS on success else
  40. EXIT_FAILURE on failure
  41. ******************************************************************************/
  42. DWORD _cdecl
  43. _tmain( DWORD argc, LPCTSTR argv[] )
  44. {
  45. // Declaring the main option switches as boolean values
  46. BOOL bUsage = FALSE;
  47. BOOL bCreate = FALSE;
  48. BOOL bQuery = FALSE;
  49. BOOL bDelete = FALSE;
  50. BOOL bChange = FALSE;
  51. BOOL bRun = FALSE;
  52. BOOL bEnd = FALSE;
  53. BOOL bDefVal = FALSE;
  54. DWORD dwRetStatus = EXIT_SUCCESS;
  55. HRESULT hr = S_OK;
  56. // Call the preProcessOptions function to find out the option selected by the user
  57. BOOL bValue = preProcessOptions( argc , argv , &bUsage , &bCreate , &bQuery , &bDelete ,
  58. &bChange , &bRun , &bEnd , &bDefVal );
  59. if(bValue == FALSE)
  60. {
  61. ReleaseGlobals();
  62. return EXIT_FAILURE;
  63. }
  64. // If ScheduledTasks.exe /?
  65. if( bUsage && ( bCreate + bQuery + bDelete + bChange + bRun + bEnd ) == 0 )
  66. {
  67. displayMainUsage();
  68. ReleaseGlobals();
  69. return EXIT_SUCCESS;
  70. }
  71. // If ScheduledTasks.exe -create option is selected
  72. if( bCreate == TRUE)
  73. {
  74. hr = CreateScheduledTask( argc, argv );
  75. ReleaseGlobals();
  76. if ( FAILED(hr) )
  77. {
  78. return EXIT_FAILURE;
  79. }
  80. else
  81. {
  82. return EXIT_SUCCESS;
  83. }
  84. }
  85. // If ScheduledTasks.exe -Query option is selected
  86. if( bQuery == TRUE )
  87. {
  88. dwRetStatus = QueryScheduledTasks( argc, argv );
  89. ReleaseGlobals();
  90. return dwRetStatus;
  91. }
  92. // If ScheduledTasks.exe -delete option is selected
  93. if( bDelete == TRUE)
  94. {
  95. dwRetStatus = DeleteScheduledTask( argc, argv );
  96. ReleaseGlobals();
  97. return dwRetStatus;
  98. }
  99. // If ScheduledTasks.exe -change option is selected
  100. if( bChange == TRUE)
  101. {
  102. dwRetStatus = ChangeScheduledTaskParams( argc, argv );
  103. ReleaseGlobals();
  104. return dwRetStatus;
  105. }
  106. // If ScheduledTasks.exe -run option is selected
  107. if( bRun == TRUE)
  108. {
  109. dwRetStatus = RunScheduledTask( argc, argv );
  110. ReleaseGlobals();
  111. return dwRetStatus;
  112. }
  113. // If ScheduledTasks.exe -end option is selected
  114. if( bEnd == TRUE)
  115. {
  116. dwRetStatus = TerminateScheduledTask( argc, argv );
  117. ReleaseGlobals();
  118. return dwRetStatus;
  119. }
  120. // If ScheduledTasks.exe option is selected
  121. if( bDefVal == TRUE )
  122. {
  123. dwRetStatus = QueryScheduledTasks( argc, argv );
  124. ReleaseGlobals();
  125. return dwRetStatus;
  126. }
  127. ReleaseGlobals();
  128. return dwRetStatus;
  129. }
  130. /******************************************************************************
  131. Routine Description:
  132. This function process the options specified in the command line & routes to
  133. different appropriate functions.
  134. Arguments:
  135. [ in ] argc : The count of arguments specified in the command line
  136. [ in ] argv : Array of command line arguments
  137. [ out ] pbUsage : pointer to flag for determining [usage] -? option
  138. [ out ] pbCreate : pointer to flag for determining -create option
  139. [ out ] pbQuery : pointer to flag for determining -query option
  140. [ out ] pbDelete : pointer to flag for determining -delete option
  141. [ out ] pbChange : pointer to flag for determining -change option
  142. [ out ] pbRun : pointer to flag for determining -run option
  143. [ out ] pbEnd : pointer to flag for determining -end option
  144. [ out ] pbDefVal : pointer to flag for determining default value
  145. Return Value :
  146. A BOOL value indicating TRUE on success else FALSE
  147. ******************************************************************************/
  148. BOOL
  149. preProcessOptions( DWORD argc, LPCTSTR argv[] , PBOOL pbUsage, PBOOL pbCreate,
  150. PBOOL pbQuery, PBOOL pbDelete , PBOOL pbChange , PBOOL pbRun , PBOOL pbEnd , PBOOL pbDefVal )
  151. {
  152. BOOL bOthers = FALSE;
  153. BOOL bParse = FALSE;
  154. //fill in the TCMDPARSER array
  155. TCMDPARSER cmdOptions[] = {
  156. {
  157. CMDOPTION_CREATE,
  158. 0,
  159. OPTION_COUNT,
  160. 0,
  161. pbCreate,
  162. NULL_STRING,
  163. NULL,
  164. NULL
  165. },
  166. {
  167. CMDOPTION_QUERY,
  168. 0,
  169. OPTION_COUNT,
  170. 0,
  171. pbQuery,
  172. NULL_STRING,
  173. NULL,
  174. NULL
  175. },
  176. {
  177. CMDOPTION_DELETE,
  178. 0,
  179. OPTION_COUNT,
  180. 0,
  181. pbDelete,
  182. NULL_STRING,
  183. NULL,
  184. NULL
  185. },
  186. {
  187. CMDOPTION_USAGE,
  188. CP_USAGE ,
  189. OPTION_COUNT,
  190. 0,
  191. pbUsage,
  192. NULL_STRING,
  193. NULL,
  194. NULL
  195. },
  196. {
  197. CMDOPTION_CHANGE,
  198. 0,
  199. OPTION_COUNT,
  200. 0,
  201. pbChange,
  202. NULL_STRING,
  203. NULL,
  204. NULL
  205. },
  206. {
  207. CMDOPTION_RUN,
  208. 0,
  209. OPTION_COUNT,
  210. 0,
  211. pbRun,
  212. NULL_STRING,
  213. NULL,
  214. NULL
  215. },
  216. {
  217. CMDOPTION_END,
  218. 0,
  219. OPTION_COUNT,
  220. 0,
  221. pbEnd,
  222. NULL_STRING,
  223. NULL,
  224. NULL
  225. },
  226. {
  227. CMDOTHEROPTIONS,
  228. CP_DEFAULT,
  229. 0,
  230. 0,
  231. &bOthers,
  232. NULL_STRING,
  233. NULL,
  234. NULL
  235. }
  236. };
  237. //if there is an error display app. error message
  238. if (( ( DoParseParam( argc, argv,SIZE_OF_ARRAY(cmdOptions), cmdOptions ) == FALSE ) &&
  239. ( bParse = TRUE ) ) ||
  240. ((*pbCreate + *pbQuery + *pbDelete + *pbChange + *pbRun + *pbEnd)> 1 ) ||
  241. ( *pbUsage && bOthers ) ||
  242. (( *pbCreate + *pbQuery + *pbDelete + *pbChange + *pbRun + *pbEnd + *pbUsage ) == 0 )
  243. )
  244. {
  245. if ( bParse == TRUE )
  246. {
  247. DISPLAY_MESSAGE( stderr, GetResString(IDS_LOGTYPE_ERROR ));
  248. DISPLAY_MESSAGE( stderr, GetReason() );
  249. return FALSE;
  250. }
  251. else if ( ( *pbCreate + *pbQuery + *pbDelete + *pbChange + *pbRun + *pbEnd + *pbUsage ) > 1 )
  252. {
  253. DISPLAY_MESSAGE( stderr, GetResString(IDS_RES_ERROR ));
  254. return FALSE;
  255. }
  256. else if( *pbCreate == TRUE )
  257. {
  258. DISPLAY_MESSAGE(stderr, GetResString(IDS_CREATE_USAGE));
  259. return FALSE;
  260. }
  261. else if( *pbQuery == TRUE )
  262. {
  263. DISPLAY_MESSAGE(stderr, GetResString(IDS_QUERY_USAGE));
  264. return FALSE;
  265. }
  266. else if( *pbDelete == TRUE )
  267. {
  268. DISPLAY_MESSAGE(stderr, GetResString(IDS_DELETE_SYNERROR));
  269. return FALSE;
  270. }
  271. else if( *pbChange == TRUE )
  272. {
  273. DISPLAY_MESSAGE(stderr, GetResString(IDS_CHANGE_SYNERROR));
  274. return FALSE;
  275. }
  276. else if( *pbRun == TRUE )
  277. {
  278. DISPLAY_MESSAGE(stderr, GetResString(IDS_RUN_SYNERROR));
  279. return FALSE;
  280. }
  281. else if( *pbEnd == TRUE )
  282. {
  283. DISPLAY_MESSAGE(stderr, GetResString(IDS_END_SYNERROR));
  284. return FALSE;
  285. }
  286. else if( ( *pbUsage && bOthers ) || ( !( *pbQuery ) && ( bOthers ) ) )
  287. {
  288. DISPLAY_MESSAGE( stderr, GetResString(IDS_RES_ERROR ));
  289. return FALSE;
  290. }
  291. else
  292. {
  293. *pbDefVal = TRUE;
  294. }
  295. }
  296. return TRUE;
  297. }
  298. /******************************************************************************
  299. Routine Description:
  300. This function fetches the ITaskScheduler Interface.It also connects to
  301. the remote machine if specified & helps to operate
  302. ITaskScheduler on the specified target m/c.
  303. Arguments:
  304. [ in ] szServer : server's name
  305. Return Value :
  306. ITaskScheduler interface pointer on success else NULL
  307. ******************************************************************************/
  308. ITaskScheduler*
  309. GetTaskScheduler( LPCTSTR szServer )
  310. {
  311. HRESULT hr = S_OK;
  312. ITaskScheduler *pITaskScheduler = NULL;
  313. WCHAR wszComputerName[ MAX_RES_STRING ] = NULL_U_STRING;
  314. WCHAR wszActualComputerName[ 2 * MAX_RES_STRING ] = DOMAIN_U_STRING;
  315. wchar_t* pwsz = NULL_U_STRING;
  316. WORD wSlashCount = 0 ;
  317. hr = Init( &pITaskScheduler );
  318. if( FAILED(hr))
  319. {
  320. DisplayErrorMsg(hr);
  321. return NULL;
  322. }
  323. //If the operation is on remote machine
  324. if( lstrlen(szServer) > 0 )
  325. {
  326. // Convert the server name specified by the user to wide char or unicode format
  327. if ( GetAsUnicodeString(szServer,wszComputerName, SIZE_OF_ARRAY(wszComputerName)) == NULL )
  328. {
  329. return NULL;
  330. }
  331. if( wszComputerName != NULL )
  332. {
  333. pwsz = wszComputerName;
  334. while ( ( *pwsz != NULL_U_CHAR ) && ( *pwsz == BACK_SLASH_U ) )
  335. {
  336. pwsz = _wcsinc(pwsz);
  337. wSlashCount++;
  338. }
  339. if( (wSlashCount == 2 ) ) // two back slashes are present
  340. {
  341. wcscpy( wszActualComputerName, wszComputerName );
  342. }
  343. else if ( wSlashCount == 0 )
  344. {
  345. //Append "\\" to computer name
  346. wcscat(wszActualComputerName,wszComputerName);
  347. }
  348. else
  349. {
  350. DISPLAY_MESSAGE (stderr, GetResString ( IDS_INVALID_NET_ADDRESS ));
  351. return NULL;
  352. }
  353. }
  354. hr = pITaskScheduler->SetTargetComputer( wszActualComputerName );
  355. }
  356. else
  357. {
  358. //Local Machine
  359. hr = pITaskScheduler->SetTargetComputer( NULL );
  360. }
  361. if( FAILED( hr ) )
  362. {
  363. DisplayErrorMsg(hr);
  364. return NULL;
  365. }
  366. return pITaskScheduler;
  367. }
  368. /******************************************************************************
  369. Routine Description:
  370. This function initialises the COM library & fetches the ITaskScheduler interface.
  371. Arguments:
  372. [ in ] pITaskScheduler : double pointer to taskscheduler interface
  373. Return Value:
  374. A HRESULT value indicating success code else failure code
  375. ******************************************************************************/
  376. HRESULT
  377. Init( ITaskScheduler **pITaskScheduler )
  378. {
  379. // Initalize the HRESULT value.
  380. HRESULT hr = S_OK;
  381. // Bring in the library
  382. hr = CoInitializeEx( NULL , COINIT_APARTMENTTHREADED );
  383. if (FAILED(hr))
  384. {
  385. return hr;
  386. }
  387. hr = CoInitializeSecurity(NULL, -1, NULL, NULL,
  388. RPC_C_AUTHN_LEVEL_NONE,
  389. RPC_C_IMP_LEVEL_IMPERSONATE,
  390. NULL, EOAC_NONE, 0 );
  391. if (FAILED(hr))
  392. {
  393. CoUninitialize();
  394. return hr;
  395. }
  396. // Create the pointer to Task Scheduler object
  397. // CLSID from the header file mstask.h
  398. // Fill the task schdeuler object.
  399. hr = CoCreateInstance( CLSID_CTaskScheduler, NULL, CLSCTX_ALL,
  400. IID_ITaskScheduler,(LPVOID*) pITaskScheduler );
  401. // Should we fail, unload the library
  402. if (FAILED(hr))
  403. {
  404. CoUninitialize();
  405. }
  406. return hr;
  407. }
  408. /******************************************************************************
  409. Routine Description:
  410. This function releases the ITaskScheduler & unloads the COM library
  411. Arguments:
  412. [ in ] pITaskScheduler : pointer to the ITaskScheduler
  413. Return Value :
  414. VOID
  415. ******************************************************************************/
  416. VOID
  417. Cleanup( ITaskScheduler *pITaskScheduler )
  418. {
  419. if (pITaskScheduler)
  420. {
  421. pITaskScheduler->Release();
  422. }
  423. // Unload the library, now that our pointer is freed.
  424. CoUninitialize();
  425. return;
  426. }
  427. /******************************************************************************
  428. Routine Description:
  429. This function displays the main usage help of this utility
  430. Arguments:
  431. None
  432. Return Value :
  433. VOID
  434. ******************************************************************************/
  435. VOID
  436. displayMainUsage()
  437. {
  438. DisplayUsage( IDS_MAINHLP1, IDS_MAINHLP21);
  439. return;
  440. }
  441. /******************************************************************************
  442. Routine Description:
  443. This function deletes the .job extension from the task name
  444. Arguments:
  445. [ in ] lpszTaskName : Task name
  446. Return Value :
  447. None
  448. ******************************************************************************/
  449. DWORD
  450. ParseTaskName( LPTSTR lpszTaskName )
  451. {
  452. if(lpszTaskName == NULL)
  453. return ERROR_INVALID_PARAMETER;
  454. // Remove the .Job extension from the task name
  455. lpszTaskName[lstrlen(lpszTaskName ) - lstrlen(JOB) ] = NULL_CHAR;
  456. return EXIT_SUCCESS;
  457. }
  458. /******************************************************************************
  459. Routine Description:
  460. This function displays the appropriate error message w.r.t HRESULT value
  461. Arguments:
  462. [ in ] hr : An HRESULT value
  463. Return Value :
  464. VOID
  465. ******************************************************************************/
  466. VOID
  467. DisplayErrorMsg(HRESULT hr)
  468. {
  469. TCHAR szErrorDesc[ MAX_RES_STRING ] = NULL_STRING;
  470. TCHAR szErrorString[ 2*MAX_RES_STRING ] = NULL_STRING;
  471. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, hr,
  472. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  473. szErrorDesc,SIZE_OF_ARRAY(szErrorDesc), NULL);
  474. //Append ERROR: string in front of the actual error message
  475. lstrcpy( szErrorString, GetResString(IDS_ERROR_STRING) );
  476. lstrcat( szErrorString,szErrorDesc );
  477. DISPLAY_MESSAGE( stderr, szErrorString );
  478. return;
  479. }
  480. /******************************************************************************
  481. Routine Description:
  482. This function displays the messages for usage of different option
  483. Arguments:
  484. [ in ] StartingMessage : First string to display
  485. [ in ] EndingMessage : Last string to display
  486. Return Value :
  487. DWORD
  488. ******************************************************************************/
  489. DWORD DisplayUsage( ULONG StartingMessage, ULONG EndingMessage )
  490. {
  491. ULONG ulCounter = 0;
  492. LPCTSTR lpszCurrentString = NULL;
  493. for( ulCounter = StartingMessage; ulCounter <= EndingMessage; ulCounter++ )
  494. {
  495. lpszCurrentString = GetResString( ulCounter );
  496. if( lpszCurrentString != NULL )
  497. {
  498. DISPLAY_MESSAGE( stdout, lpszCurrentString );
  499. }
  500. else
  501. {
  502. return ERROR_INVALID_PARAMETER;
  503. }
  504. }
  505. return ERROR_SUCCESS;
  506. }