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.

630 lines
20 KiB

  1. /******************************************************************************
  2. Copyright(c) Microsoft Corporation
  3. Module Name:
  4. run.cpp
  5. Abstract:
  6. This module runs the schedule task present in the system
  7. Author:
  8. Venu Gopal Choudary 12-Mar-2001
  9. Revision History:
  10. Venu Gopal Choudary 12-Mar-2001 : Created it
  11. ******************************************************************************/
  12. //common header files needed for this file
  13. #include "pch.h"
  14. #include "CommonHeaderFiles.h"
  15. // Function declaration for the Usage function.
  16. VOID DisplayRunUsage();
  17. /*****************************************************************************
  18. Routine Description:
  19. This routine runs the scheduled task(s)
  20. Arguments:
  21. [ in ] argc : Number of command line arguments
  22. [ in ] argv : Array containing command line arguments
  23. Return Value :
  24. A DWORD value indicating EXIT_SUCCESS on success else
  25. EXIT_FAILURE on failure
  26. *****************************************************************************/
  27. DWORD
  28. RunScheduledTask(
  29. IN DWORD argc,
  30. IN LPCTSTR argv[]
  31. )
  32. {
  33. // Variables used to find whether Run option, Usage option
  34. // are specified or not
  35. BOOL bRun = FALSE;
  36. BOOL bUsage = FALSE;
  37. DWORD dwPolicy = 0;
  38. // Set the TaskSchduler object as NULL
  39. ITaskScheduler *pITaskScheduler = NULL;
  40. // Return value
  41. HRESULT hr = S_OK;
  42. // Initialising the variables that are passed to TCMDPARSER structure
  43. LPWSTR szServer = NULL;
  44. WCHAR szTaskName[ MAX_JOB_LEN ] = L"\0";
  45. LPWSTR szUser = NULL;
  46. LPWSTR szPassword = NULL;
  47. // Dynamic Array contaning array of jobs
  48. TARRAY arrJobs = NULL;
  49. //buffer for displaying error message
  50. WCHAR szMessage[2 * MAX_STRING_LENGTH] = L"\0";
  51. BOOL bNeedPassword = FALSE;
  52. BOOL bResult = FALSE;
  53. BOOL bCloseConnection = TRUE;
  54. BOOL bFlag = FALSE;
  55. DWORD dwCheck = 0;
  56. TCMDPARSER2 cmdRunOptions[MAX_RUN_OPTIONS];
  57. BOOL bReturn = FALSE;
  58. // /run sub-options
  59. const WCHAR szRunOpt[] = L"run";
  60. const WCHAR szRunHelpOpt[] = L"?";
  61. const WCHAR szRunServerOpt[] = L"s";
  62. const WCHAR szRunUserOpt[] = L"u";
  63. const WCHAR szRunPwdOpt[] = L"p";
  64. const WCHAR szRunTaskNameOpt[] = L"tn";
  65. // set all the fields to 0
  66. SecureZeroMemory( cmdRunOptions, sizeof( TCMDPARSER2 ) * MAX_RUN_OPTIONS );
  67. //
  68. // fill the commandline parser
  69. //
  70. // /delete option
  71. StringCopyA( cmdRunOptions[ OI_RUN_OPTION ].szSignature, "PARSER2\0", 8 );
  72. cmdRunOptions[ OI_RUN_OPTION ].dwType = CP_TYPE_BOOLEAN;
  73. cmdRunOptions[ OI_RUN_OPTION ].pwszOptions = szRunOpt;
  74. cmdRunOptions[ OI_RUN_OPTION ].dwCount = 1;
  75. cmdRunOptions[ OI_RUN_OPTION ].dwFlags = 0;
  76. cmdRunOptions[ OI_RUN_OPTION ].pValue = &bRun;
  77. // /? option
  78. StringCopyA( cmdRunOptions[ OI_RUN_USAGE ].szSignature, "PARSER2\0", 8 );
  79. cmdRunOptions[ OI_RUN_USAGE ].dwType = CP_TYPE_BOOLEAN;
  80. cmdRunOptions[ OI_RUN_USAGE ].pwszOptions = szRunHelpOpt;
  81. cmdRunOptions[ OI_RUN_USAGE ].dwCount = 1;
  82. cmdRunOptions[ OI_RUN_USAGE ].dwFlags = CP2_USAGE;
  83. cmdRunOptions[ OI_RUN_USAGE ].pValue = &bUsage;
  84. // /s option
  85. StringCopyA( cmdRunOptions[ OI_RUN_SERVER ].szSignature, "PARSER2\0", 8 );
  86. cmdRunOptions[ OI_RUN_SERVER ].dwType = CP_TYPE_TEXT;
  87. cmdRunOptions[ OI_RUN_SERVER ].pwszOptions = szRunServerOpt;
  88. cmdRunOptions[ OI_RUN_SERVER ].dwCount = 1;
  89. cmdRunOptions[ OI_RUN_SERVER ].dwFlags = CP2_ALLOCMEMORY| CP2_VALUE_TRIMINPUT|CP2_VALUE_NONULL ;
  90. // /u option
  91. StringCopyA( cmdRunOptions[ OI_RUN_USERNAME ].szSignature, "PARSER2\0", 8 );
  92. cmdRunOptions[ OI_RUN_USERNAME ].dwType = CP_TYPE_TEXT;
  93. cmdRunOptions[ OI_RUN_USERNAME ].pwszOptions = szRunUserOpt;
  94. cmdRunOptions[ OI_RUN_USERNAME ].dwCount = 1;
  95. cmdRunOptions[ OI_RUN_USERNAME ].dwFlags = CP2_ALLOCMEMORY| CP2_VALUE_TRIMINPUT|CP2_VALUE_NONULL ;
  96. // /p option
  97. StringCopyA( cmdRunOptions[ OI_RUN_PASSWORD ].szSignature, "PARSER2\0", 8 );
  98. cmdRunOptions[ OI_RUN_PASSWORD ].dwType = CP_TYPE_TEXT;
  99. cmdRunOptions[ OI_RUN_PASSWORD ].pwszOptions = szRunPwdOpt;
  100. cmdRunOptions[ OI_RUN_PASSWORD ].dwCount = 1;
  101. cmdRunOptions[ OI_RUN_PASSWORD ].dwFlags = CP2_ALLOCMEMORY | CP2_VALUE_OPTIONAL;
  102. // /tn option
  103. StringCopyA( cmdRunOptions[ OI_RUN_TASKNAME ].szSignature, "PARSER2\0", 8 );
  104. cmdRunOptions[ OI_RUN_TASKNAME ].dwType = CP_TYPE_TEXT;
  105. cmdRunOptions[ OI_RUN_TASKNAME ].pwszOptions = szRunTaskNameOpt;
  106. cmdRunOptions[ OI_RUN_TASKNAME ].dwCount = 1;
  107. cmdRunOptions[ OI_RUN_TASKNAME ].dwFlags = CP2_MANDATORY;
  108. cmdRunOptions[ OI_RUN_TASKNAME ].pValue = szTaskName;
  109. cmdRunOptions[ OI_RUN_TASKNAME ].dwLength = MAX_JOB_LEN;
  110. //parse command line arguments
  111. bReturn = DoParseParam2( argc, argv, 0, SIZE_OF_ARRAY(cmdRunOptions), cmdRunOptions, 0);
  112. if( FALSE == bReturn) // Invalid commandline
  113. {
  114. //display an error message
  115. ShowLastErrorEx ( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  116. ReleaseGlobals();
  117. return EXIT_FAILURE;
  118. }
  119. // get the buffer pointers allocated by command line parser
  120. szServer = (LPWSTR)cmdRunOptions[ OI_RUN_SERVER ].pValue;
  121. szUser = (LPWSTR)cmdRunOptions[ OI_RUN_USERNAME ].pValue;
  122. szPassword = (LPWSTR)cmdRunOptions[ OI_RUN_PASSWORD ].pValue;
  123. if ( (argc > 3) && (bUsage == TRUE) )
  124. {
  125. ShowMessage ( stderr, GetResString (IDS_ERROR_RUNPARAM) );
  126. FreeMemory((LPVOID*) &szServer);
  127. FreeMemory((LPVOID*) &szUser);
  128. FreeMemory((LPVOID*) &szPassword);
  129. return EXIT_FAILURE;
  130. }
  131. // Displaying run usage if user specified -? with -run option
  132. if( bUsage == TRUE )
  133. {
  134. DisplayRunUsage();
  135. FreeMemory((LPVOID*) &szServer);
  136. FreeMemory((LPVOID*) &szUser);
  137. FreeMemory((LPVOID*) &szPassword);
  138. return EXIT_SUCCESS;
  139. }
  140. // check for invalid user name
  141. if( ( cmdRunOptions[OI_RUN_SERVER].dwActuals == 0 ) && ( cmdRunOptions[OI_RUN_USERNAME].dwActuals == 1 ) )
  142. {
  143. ShowMessage(stderr, GetResString(IDS_RUN_USER_BUT_NOMACHINE));
  144. FreeMemory((LPVOID*) &szServer);
  145. FreeMemory((LPVOID*) &szUser);
  146. FreeMemory((LPVOID*) &szPassword);
  147. return RETVAL_FAIL;
  148. }
  149. // check whether -ru is specified or not
  150. if ( cmdRunOptions[ OI_RUN_USERNAME ].dwActuals == 0 &&
  151. cmdRunOptions[ OI_RUN_PASSWORD ].dwActuals == 1 )
  152. {
  153. // invalid syntax
  154. ShowMessage(stderr, GetResString(IDS_RPASSWORD_BUT_NOUSERNAME));
  155. FreeMemory((LPVOID*) &szServer);
  156. FreeMemory((LPVOID*) &szUser);
  157. FreeMemory((LPVOID*) &szPassword);
  158. return RETVAL_FAIL;
  159. }
  160. // check for the length of taskname
  161. if( ( StringLength( szTaskName, 0 ) > MAX_JOB_LEN ) )
  162. {
  163. ShowMessage(stderr, GetResString( IDS_INVALID_TASKLENGTH ));
  164. FreeMemory((LPVOID*) &szServer);
  165. FreeMemory((LPVOID*) &szUser);
  166. FreeMemory((LPVOID*) &szPassword);
  167. return RETVAL_FAIL;
  168. }
  169. //for holding values of parameters in FormatMessage()
  170. WCHAR* szValues[1] = {NULL};
  171. // check whether the password (-p) specified in the command line or not
  172. // and also check whether '*' or empty is given for -p or not
  173. // check whether the password (-p) specified in the command line or not
  174. // and also check whether '*' or empty is given for -p or not
  175. // check whether the password (-p) specified in the command line or not
  176. // and also check whether '*' or empty is given for -p or not
  177. // check the remote connectivity information
  178. if ( szServer != NULL )
  179. {
  180. //
  181. // if -u is not specified, we need to allocate memory
  182. // in order to be able to retrive the current user name
  183. //
  184. // case 1: -p is not at all specified
  185. // as the value for this switch is optional, we have to rely
  186. // on the dwActuals to determine whether the switch is specified or not
  187. // in this case utility needs to try to connect first and if it fails
  188. // then prompt for the password -- in fact, we need not check for this
  189. // condition explicitly except for noting that we need to prompt for the
  190. // password
  191. //
  192. // case 2: -p is specified
  193. // but we need to check whether the value is specified or not
  194. // in this case user wants the utility to prompt for the password
  195. // before trying to connect
  196. //
  197. // case 3: -p * is specified
  198. // user name
  199. if ( szUser == NULL )
  200. {
  201. szUser = (LPWSTR) AllocateMemory( MAX_STRING_LENGTH * sizeof( WCHAR ) );
  202. if ( szUser == NULL )
  203. {
  204. SaveLastError();
  205. FreeMemory((LPVOID*) &szServer);
  206. FreeMemory((LPVOID*) &szUser);
  207. FreeMemory((LPVOID*) &szPassword);
  208. return RETVAL_FAIL;
  209. }
  210. }
  211. // password
  212. if ( szPassword == NULL )
  213. {
  214. bNeedPassword = TRUE;
  215. szPassword = (LPWSTR)AllocateMemory( MAX_STRING_LENGTH * sizeof( WCHAR ) );
  216. if ( szPassword == NULL )
  217. {
  218. SaveLastError();
  219. FreeMemory((LPVOID*) &szServer);
  220. FreeMemory((LPVOID*) &szUser);
  221. FreeMemory((LPVOID*) &szPassword);
  222. return RETVAL_FAIL;
  223. }
  224. }
  225. // case 1
  226. if ( cmdRunOptions[ OI_RUN_PASSWORD ].dwActuals == 0 )
  227. {
  228. // we need not do anything special here
  229. }
  230. // case 2
  231. else if ( cmdRunOptions[ OI_RUN_PASSWORD ].pValue == NULL )
  232. {
  233. StringCopy( szPassword, L"*", GetBufferSize(szPassword)/sizeof(WCHAR));
  234. }
  235. // case 3
  236. else if ( StringCompareEx( szPassword, L"*", TRUE, 0 ) == 0 )
  237. {
  238. if ( ReallocateMemory( (LPVOID*)&szPassword,
  239. MAX_STRING_LENGTH * sizeof( WCHAR ) ) == FALSE )
  240. {
  241. SaveLastError();
  242. FreeMemory((LPVOID*) &szServer);
  243. FreeMemory((LPVOID*) &szUser);
  244. FreeMemory((LPVOID*) &szPassword);
  245. return RETVAL_FAIL;
  246. }
  247. // ...
  248. bNeedPassword = TRUE;
  249. }
  250. }
  251. if( ( IsLocalSystem( szServer ) == FALSE ) || ( cmdRunOptions[OI_RUN_USERNAME].dwActuals == 1 ) )
  252. {
  253. bFlag = TRUE;
  254. // Establish the connection on a remote machine
  255. bResult = EstablishConnection(szServer,szUser,GetBufferSize(szUser)/sizeof(WCHAR),szPassword,GetBufferSize(szPassword)/sizeof(WCHAR), bNeedPassword );
  256. if (bResult == FALSE)
  257. {
  258. ShowLastErrorEx ( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  259. FreeMemory((LPVOID*) &szServer);
  260. FreeMemory((LPVOID*) &szUser);
  261. FreeMemory((LPVOID*) &szPassword);
  262. return EXIT_FAILURE ;
  263. }
  264. else
  265. {
  266. // though the connection is successfull, some conflict might have occured
  267. switch( GetLastError() )
  268. {
  269. case I_NO_CLOSE_CONNECTION:
  270. bCloseConnection = FALSE;
  271. break;
  272. case E_LOCAL_CREDENTIALS:
  273. case ERROR_SESSION_CREDENTIAL_CONFLICT:
  274. {
  275. bCloseConnection = FALSE;
  276. ShowLastErrorEx ( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  277. FreeMemory((LPVOID*) &szServer);
  278. FreeMemory((LPVOID*) &szUser);
  279. FreeMemory((LPVOID*) &szPassword);
  280. return EXIT_FAILURE;
  281. }
  282. default :
  283. bCloseConnection = TRUE;
  284. }
  285. }
  286. //release memory for password
  287. FreeMemory((LPVOID*) &szPassword);
  288. }
  289. // Get the task Scheduler object for the machine.
  290. pITaskScheduler = GetTaskScheduler( szServer );
  291. // If the Task Scheduler is not defined then give the error message.
  292. if ( pITaskScheduler == NULL )
  293. {
  294. // close the connection that was established by the utility
  295. if ( (TRUE == bFlag) && (bCloseConnection == TRUE) )
  296. {
  297. CloseConnection( szServer );
  298. }
  299. Cleanup(pITaskScheduler);
  300. FreeMemory((LPVOID*) &szServer);
  301. FreeMemory((LPVOID*) &szUser);
  302. FreeMemory((LPVOID*) &szPassword);
  303. return EXIT_FAILURE;
  304. }
  305. //check whether service is running or not
  306. if ((FALSE == CheckServiceStatus ( szServer , &dwCheck, TRUE)) && (0 != dwCheck) && ( GetLastError () != ERROR_ACCESS_DENIED))
  307. {
  308. // close the connection that was established by the utility
  309. if ( (TRUE == bFlag) && (bCloseConnection == TRUE) )
  310. {
  311. CloseConnection( szServer );
  312. }
  313. Cleanup(pITaskScheduler);
  314. FreeMemory((LPVOID*) &szServer);
  315. FreeMemory((LPVOID*) &szUser);
  316. FreeMemory((LPVOID*) &szPassword);
  317. if ( 1 == dwCheck )
  318. {
  319. ShowMessage ( stderr, GetResString (IDS_NOT_START_SERVICE));
  320. return EXIT_FAILURE;
  321. }
  322. else if (2 == dwCheck )
  323. {
  324. return EXIT_FAILURE;
  325. }
  326. else if (3 == dwCheck )
  327. {
  328. return EXIT_SUCCESS;
  329. }
  330. }
  331. // Validate the Given Task and get as TARRAY in case of taskname
  332. arrJobs = ValidateAndGetTasks( pITaskScheduler, szTaskName);
  333. if( arrJobs == NULL )
  334. {
  335. StringCchPrintf( szMessage , SIZE_OF_ARRAY(szMessage), GetResString(IDS_TASKNAME_NOTEXIST), _X( szTaskName ));
  336. ShowMessage(stderr, szMessage );
  337. if ( (TRUE == bFlag) && (bCloseConnection == TRUE) )
  338. {
  339. CloseConnection( szServer );
  340. }
  341. Cleanup(pITaskScheduler);
  342. FreeMemory((LPVOID*) &szServer);
  343. FreeMemory((LPVOID*) &szUser);
  344. FreeMemory((LPVOID*) &szPassword);
  345. return EXIT_FAILURE;
  346. }
  347. // check whether the group policy prevented user from running or not.
  348. if ( FALSE == GetGroupPolicy( szServer, szUser, TS_KEYPOLICY_DENY_EXECUTION, &dwPolicy ) )
  349. {
  350. if ( (TRUE == bFlag) && (bCloseConnection == TRUE) )
  351. {
  352. CloseConnection( szServer );
  353. }
  354. Cleanup(pITaskScheduler);
  355. FreeMemory((LPVOID*) &szServer);
  356. FreeMemory((LPVOID*) &szUser);
  357. FreeMemory((LPVOID*) &szPassword);
  358. return EXIT_FAILURE;
  359. }
  360. if ( dwPolicy > 0 )
  361. {
  362. ShowMessage ( stdout, GetResString (IDS_PREVENT_RUN));
  363. if ( (TRUE == bFlag) && (bCloseConnection == TRUE) )
  364. {
  365. CloseConnection( szServer );
  366. }
  367. Cleanup(pITaskScheduler);
  368. FreeMemory((LPVOID*) &szServer);
  369. FreeMemory((LPVOID*) &szUser);
  370. FreeMemory((LPVOID*) &szPassword);
  371. return EXIT_SUCCESS;
  372. }
  373. IPersistFile *pIPF = NULL;
  374. ITask *pITask = NULL;
  375. StringConcat ( szTaskName, JOB, SIZE_OF_ARRAY(szTaskName) );
  376. // returns an pITask inteface for szTaskName
  377. hr = pITaskScheduler->Activate(szTaskName,IID_ITask,
  378. (IUnknown**) &pITask);
  379. if (FAILED(hr))
  380. {
  381. SetLastError ((DWORD) hr);
  382. ShowLastErrorEx ( stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
  383. if( pIPF )
  384. pIPF->Release();
  385. if( pITask )
  386. pITask->Release();
  387. if ( (TRUE == bFlag) && (bCloseConnection == TRUE) )
  388. {
  389. CloseConnection( szServer );
  390. }
  391. Cleanup(pITaskScheduler);
  392. FreeMemory((LPVOID*) &szServer);
  393. FreeMemory((LPVOID*) &szUser);
  394. FreeMemory((LPVOID*) &szPassword);
  395. return EXIT_FAILURE;
  396. }
  397. WCHAR szTaskProperty[MAX_STRING_LENGTH] = L"\0";
  398. // get the status code
  399. hr = GetStatusCode(pITask,szTaskProperty);
  400. if (FAILED(hr))
  401. {
  402. SetLastError ((DWORD) hr);
  403. ShowLastErrorEx ( stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
  404. if( pIPF )
  405. pIPF->Release();
  406. if( pITask )
  407. pITask->Release();
  408. if ( (TRUE == bFlag) && (bCloseConnection == TRUE) )
  409. {
  410. CloseConnection( szServer );
  411. }
  412. Cleanup(pITaskScheduler);
  413. FreeMemory((LPVOID*) &szServer);
  414. FreeMemory((LPVOID*) &szUser);
  415. FreeMemory((LPVOID*) &szPassword);
  416. return EXIT_FAILURE;
  417. }
  418. // remove the .job extension from the taskname
  419. if ( ParseTaskName( szTaskName ) )
  420. {
  421. if( pIPF )
  422. pIPF->Release();
  423. if( pITask )
  424. pITask->Release();
  425. if ( (TRUE == bFlag) && (bCloseConnection == TRUE) )
  426. {
  427. CloseConnection( szServer );
  428. }
  429. Cleanup(pITaskScheduler);
  430. FreeMemory((LPVOID*) &szServer);
  431. FreeMemory((LPVOID*) &szUser);
  432. FreeMemory((LPVOID*) &szPassword);
  433. return EXIT_FAILURE;
  434. }
  435. // check whether the task already been running or not
  436. if ( (StringCompare(szTaskProperty , GetResString(IDS_STATUS_RUNNING), TRUE, 0) == 0 ))
  437. {
  438. szValues[0] = (WCHAR*) (szTaskName);
  439. StringCchPrintf ( szMessage, SIZE_OF_ARRAY(szMessage), GetResString(IDS_RUNNING_ALREADY), _X(szTaskName));
  440. ShowMessage(stdout, _X(szMessage));
  441. if( pIPF )
  442. pIPF->Release();
  443. if( pITask )
  444. pITask->Release();
  445. if ( (TRUE == bFlag) && (bCloseConnection == TRUE) )
  446. {
  447. CloseConnection( szServer );
  448. }
  449. Cleanup(pITaskScheduler);
  450. FreeMemory((LPVOID*) &szServer);
  451. FreeMemory((LPVOID*) &szUser);
  452. FreeMemory((LPVOID*) &szPassword);
  453. return EXIT_SUCCESS;
  454. }
  455. // run the scheduled task immediately
  456. hr = pITask->Run();
  457. if ( FAILED(hr) )
  458. {
  459. SetLastError ((DWORD) hr);
  460. ShowLastErrorEx ( stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
  461. if( pIPF )
  462. pIPF->Release();
  463. if( pITask )
  464. pITask->Release();
  465. if ( (TRUE == bFlag) && (bCloseConnection == TRUE) )
  466. {
  467. CloseConnection( szServer );
  468. }
  469. Cleanup(pITaskScheduler);
  470. FreeMemory((LPVOID*) &szServer);
  471. FreeMemory((LPVOID*) &szUser);
  472. FreeMemory((LPVOID*) &szPassword);
  473. return EXIT_FAILURE;
  474. }
  475. szValues[0] = (WCHAR*) (szTaskName);
  476. StringCchPrintf ( szMessage, SIZE_OF_ARRAY(szMessage), GetResString(IDS_RUN_SUCCESSFUL), _X(szTaskName));
  477. ShowMessage ( stdout, _X(szMessage));
  478. if( pIPF )
  479. pIPF->Release();
  480. if( pITask )
  481. pITask->Release();
  482. if ( (TRUE == bFlag) && (bCloseConnection == TRUE) )
  483. {
  484. CloseConnection( szServer );
  485. }
  486. Cleanup(pITaskScheduler);
  487. FreeMemory((LPVOID*) &szServer);
  488. FreeMemory((LPVOID*) &szUser);
  489. FreeMemory((LPVOID*) &szPassword);
  490. return EXIT_SUCCESS;
  491. }
  492. /*****************************************************************************
  493. Routine Description:
  494. This routine displays the usage of -run option
  495. Arguments:
  496. None
  497. Return Value :
  498. VOID
  499. ******************************************************************************/
  500. VOID
  501. DisplayRunUsage()
  502. {
  503. // Displaying run option usage
  504. DisplayUsage( IDS_RUN_HLP1, IDS_RUN_HLP17 );
  505. }