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.

1072 lines
36 KiB

  1. /******************************************************************************
  2. Copyright(c) Microsoft Corporation
  3. Module Name:
  4. delete.cpp
  5. Abstract:
  6. This module deletes the task(s) present in the system
  7. Author:
  8. Hari 10-Sep-2000
  9. Revision History:
  10. Hari 10-Sep-2000 : Created it
  11. G.Surender Reddy 25-Sep-2000 : Modified it [added error checking]
  12. G.Surender Reddy 31-Oct-2000 : Modified it
  13. [Moved strings to resource file]
  14. G.Surender Reddy 18-Nov-2000 : Modified it
  15. [Modified usage help to be displayed]
  16. G.Surender Reddy 15-Dec-2000 : Modified it
  17. [Removed getch() fn.& used Console API
  18. to read characters]
  19. G.Surender Reddy 22-Dec-2000 : Modified it
  20. [Rewrote the DisplayDeleteUsage() fn.]
  21. G.Surender Reddy 08-Jan-2001 : Modified it
  22. [Deleted the unused variables.]
  23. ******************************************************************************/
  24. //common header files needed for this file
  25. #include "pch.h"
  26. #include "CommonHeaderFiles.h"
  27. // Function declaration for the Usage function.
  28. VOID DisplayDeleteUsage();
  29. DWORD ConfirmDelete( LPCTSTR szTaskName , PBOOL pbFalg );
  30. /*****************************************************************************
  31. Routine Description:
  32. This routine deletes a specified scheduled task(s)
  33. Arguments:
  34. [ in ] argc : Number of command line arguments
  35. [ in ] argv : Array containing command line arguments
  36. Return Value :
  37. A DWORD value indicating EXIT_SUCCESS on success else
  38. EXIT_FAILURE on failure
  39. *****************************************************************************/
  40. DWORD
  41. DeleteScheduledTask(
  42. IN DWORD argc,
  43. IN LPCTSTR argv[]
  44. )
  45. {
  46. // Variables used to find whether Delete main option, Usage option
  47. // or the force option is specified or not
  48. BOOL bDelete = FALSE;
  49. BOOL bUsage = FALSE;
  50. BOOL bForce = FALSE;
  51. // Set the TaskSchduler object as NULL
  52. ITaskScheduler *pITaskScheduler = NULL;
  53. // Return value
  54. HRESULT hr = S_OK;
  55. // Initialising the variables that are passed to TCMDPARSER structure
  56. LPWSTR szServer = NULL;
  57. WCHAR szTaskName[ MAX_JOB_LEN ] = L"\0";
  58. LPWSTR szUser = NULL;
  59. LPWSTR szPassword = NULL;
  60. // For each task in all the tasks.
  61. WCHAR szEachTaskName[ MAX_JOB_LEN ];
  62. BOOL bWrongValue = FALSE;
  63. // Task name or the job name which is to be deleted
  64. WCHAR wszJobName[MAX_JOB_LEN] ;
  65. // Dynamic Array contaning array of jobs
  66. TARRAY arrJobs = NULL;
  67. // Loop Variable.
  68. DWORD dwJobCount = 0;
  69. //buffer for displaying error message
  70. WCHAR szMessage[2 * MAX_STRING_LENGTH] = L"\0";
  71. BOOL bNeedPassword = FALSE;
  72. BOOL bResult = FALSE;
  73. BOOL bCloseConnection = TRUE;
  74. BOOL bFlag = FALSE;
  75. TCMDPARSER2 cmdDeleteOptions[MAX_DELETE_OPTIONS];
  76. BOOL bReturn = FALSE;
  77. DWORD dwPolicy = 0;
  78. // /delete sub-options
  79. const WCHAR szDeleteOpt[] = L"delete";
  80. const WCHAR szDeleteHelpOpt[] = L"?";
  81. const WCHAR szDeleteServerOpt[] = L"s";
  82. const WCHAR szDeleteUserOpt[] = L"u";
  83. const WCHAR szDeletePwdOpt[] = L"p";
  84. const WCHAR szDeleteTaskNameOpt[] = L"tn";
  85. const WCHAR szDeleteForceOpt[] = L"f";
  86. // set all the fields to 0
  87. SecureZeroMemory( cmdDeleteOptions, sizeof( TCMDPARSER2 ) * MAX_DELETE_OPTIONS );
  88. //
  89. // fill the commandline parser
  90. //
  91. // /delete option
  92. StringCopyA( cmdDeleteOptions[ OI_DELETE_OPTION ].szSignature, "PARSER2\0", 8 );
  93. cmdDeleteOptions[ OI_DELETE_OPTION ].dwType = CP_TYPE_BOOLEAN;
  94. cmdDeleteOptions[ OI_DELETE_OPTION ].pwszOptions = szDeleteOpt;
  95. cmdDeleteOptions[ OI_DELETE_OPTION ].dwCount = 1;
  96. cmdDeleteOptions[ OI_DELETE_OPTION ].dwFlags = 0;
  97. cmdDeleteOptions[ OI_DELETE_OPTION ].pValue = &bDelete;
  98. // /? option
  99. StringCopyA( cmdDeleteOptions[ OI_DELETE_USAGE ].szSignature, "PARSER2\0", 8 );
  100. cmdDeleteOptions[ OI_DELETE_USAGE ].dwType = CP_TYPE_BOOLEAN;
  101. cmdDeleteOptions[ OI_DELETE_USAGE ].pwszOptions = szDeleteHelpOpt;
  102. cmdDeleteOptions[ OI_DELETE_USAGE ].dwCount = 1;
  103. cmdDeleteOptions[ OI_DELETE_USAGE ].dwFlags = CP2_USAGE;
  104. cmdDeleteOptions[ OI_DELETE_USAGE ].pValue = &bUsage;
  105. // /s option
  106. StringCopyA( cmdDeleteOptions[ OI_DELETE_SERVER ].szSignature, "PARSER2\0", 8 );
  107. cmdDeleteOptions[ OI_DELETE_SERVER ].dwType = CP_TYPE_TEXT;
  108. cmdDeleteOptions[ OI_DELETE_SERVER ].pwszOptions = szDeleteServerOpt;
  109. cmdDeleteOptions[ OI_DELETE_SERVER ].dwCount = 1;
  110. cmdDeleteOptions[ OI_DELETE_SERVER ].dwFlags = CP2_ALLOCMEMORY| CP2_VALUE_TRIMINPUT|CP2_VALUE_NONULL ;
  111. // /u option
  112. StringCopyA( cmdDeleteOptions[ OI_DELETE_USERNAME ].szSignature, "PARSER2\0", 8 );
  113. cmdDeleteOptions[ OI_DELETE_USERNAME ].dwType = CP_TYPE_TEXT;
  114. cmdDeleteOptions[ OI_DELETE_USERNAME ].pwszOptions = szDeleteUserOpt;
  115. cmdDeleteOptions[ OI_DELETE_USERNAME ].dwCount = 1;
  116. cmdDeleteOptions[ OI_DELETE_USERNAME ].dwFlags = CP2_ALLOCMEMORY| CP2_VALUE_TRIMINPUT|CP2_VALUE_NONULL ;
  117. // /p option
  118. StringCopyA( cmdDeleteOptions[ OI_DELETE_PASSWORD ].szSignature, "PARSER2\0", 8 );
  119. cmdDeleteOptions[ OI_DELETE_PASSWORD ].dwType = CP_TYPE_TEXT;
  120. cmdDeleteOptions[ OI_DELETE_PASSWORD ].pwszOptions = szDeletePwdOpt;
  121. cmdDeleteOptions[ OI_DELETE_PASSWORD ].dwCount = 1;
  122. cmdDeleteOptions[ OI_DELETE_PASSWORD ].dwActuals = 0;
  123. cmdDeleteOptions[ OI_DELETE_PASSWORD ].dwFlags = CP2_ALLOCMEMORY | CP2_VALUE_OPTIONAL;
  124. // /tn option
  125. StringCopyA( cmdDeleteOptions[ OI_DELETE_TASKNAME ].szSignature, "PARSER2\0", 8 );
  126. cmdDeleteOptions[ OI_DELETE_TASKNAME ].dwType = CP_TYPE_TEXT;
  127. cmdDeleteOptions[ OI_DELETE_TASKNAME ].pwszOptions = szDeleteTaskNameOpt;
  128. cmdDeleteOptions[ OI_DELETE_TASKNAME ].dwCount = 1;
  129. cmdDeleteOptions[ OI_DELETE_TASKNAME ].dwFlags = CP2_MANDATORY;
  130. cmdDeleteOptions[ OI_DELETE_TASKNAME ].pValue = szTaskName;
  131. cmdDeleteOptions[ OI_DELETE_TASKNAME ].dwLength = MAX_JOB_LEN;
  132. // /f option
  133. StringCopyA( cmdDeleteOptions[ OI_DELETE_FORCE ].szSignature, "PARSER2\0", 8 );
  134. cmdDeleteOptions[ OI_DELETE_FORCE ].dwType = CP_TYPE_BOOLEAN;
  135. cmdDeleteOptions[ OI_DELETE_FORCE ].pwszOptions = szDeleteForceOpt;
  136. cmdDeleteOptions[ OI_DELETE_FORCE ].dwCount = 1;
  137. cmdDeleteOptions[ OI_DELETE_FORCE ].pValue = &bForce;
  138. //parse command line arguments
  139. bReturn = DoParseParam2( argc, argv, 0, SIZE_OF_ARRAY(cmdDeleteOptions), cmdDeleteOptions, 0);
  140. if( FALSE == bReturn) // Invalid commandline
  141. {
  142. //display an error message
  143. ShowLastErrorEx ( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  144. ReleaseGlobals();
  145. return EXIT_FAILURE;
  146. }
  147. // get the buffer pointers allocated by command line parser
  148. szServer = (LPWSTR)cmdDeleteOptions[ OI_CREATE_SERVER ].pValue;
  149. szUser = (LPWSTR)cmdDeleteOptions[ OI_CREATE_USERNAME ].pValue;
  150. szPassword = (LPWSTR)cmdDeleteOptions[ OI_CREATE_PASSWORD ].pValue;
  151. if ( (argc > 3) && (bUsage == TRUE) )
  152. {
  153. ShowMessage ( stderr, GetResString (IDS_ERROR_DELETEPARAM) );
  154. FreeMemory((LPVOID*) &szServer);
  155. FreeMemory((LPVOID*) &szUser);
  156. FreeMemory((LPVOID*) &szPassword);
  157. return EXIT_FAILURE;
  158. }
  159. // Displaying delete usage if user specified -? with -delete option
  160. if( bUsage == TRUE )
  161. {
  162. DisplayDeleteUsage();
  163. FreeMemory((LPVOID*) &szServer);
  164. FreeMemory((LPVOID*) &szUser);
  165. FreeMemory((LPVOID*) &szPassword);
  166. return EXIT_SUCCESS;
  167. }
  168. // check for invalid user name
  169. if( ( cmdDeleteOptions[OI_DELETE_SERVER].dwActuals == 0 ) && ( cmdDeleteOptions[OI_DELETE_USERNAME].dwActuals == 1 ) )
  170. {
  171. ShowMessage(stderr, GetResString(IDS_DELETE_USER_BUT_NOMACHINE));
  172. FreeMemory((LPVOID*) &szServer);
  173. FreeMemory((LPVOID*) &szUser);
  174. FreeMemory((LPVOID*) &szPassword);
  175. return RETVAL_FAIL;
  176. }
  177. // check whether username is specified or not along with the password
  178. if ( cmdDeleteOptions[ OI_DELETE_USERNAME ].dwActuals == 0 && cmdDeleteOptions[OI_DELETE_PASSWORD].dwActuals == 1 )
  179. {
  180. // invalid syntax
  181. ShowMessage(stderr, GetResString(IDS_DPASSWORD_BUT_NOUSERNAME));
  182. FreeMemory((LPVOID*) &szServer);
  183. FreeMemory((LPVOID*) &szUser);
  184. FreeMemory((LPVOID*) &szPassword);
  185. return RETVAL_FAIL;
  186. }
  187. // check for the length of the taskname
  188. if( ( StringLength( szTaskName, 0 ) > MAX_JOB_LEN ) )
  189. {
  190. ShowMessage(stderr,GetResString(IDS_INVALID_TASKLENGTH));
  191. FreeMemory((LPVOID*) &szServer);
  192. FreeMemory((LPVOID*) &szUser);
  193. FreeMemory((LPVOID*) &szPassword);
  194. return EXIT_FAILURE;
  195. }
  196. // check whether the password (-p) specified in the command line or not
  197. // and also check whether '*' or empty is given for -p or not
  198. // check whether the password (-p) specified in the command line or not
  199. // and also check whether '*' or empty is given for -p or not
  200. // check the remote connectivity information
  201. if ( szServer != NULL )
  202. {
  203. //
  204. // if -u is not specified, we need to allocate memory
  205. // in order to be able to retrive the current user name
  206. //
  207. // case 1: -p is not at all specified
  208. // as the value for this switch is optional, we have to rely
  209. // on the dwActuals to determine whether the switch is specified or not
  210. // in this case utility needs to try to connect first and if it fails
  211. // then prompt for the password -- in fact, we need not check for this
  212. // condition explicitly except for noting that we need to prompt for the
  213. // password
  214. //
  215. // case 2: -p is specified
  216. // but we need to check whether the value is specified or not
  217. // in this case user wants the utility to prompt for the password
  218. // before trying to connect
  219. //
  220. // case 3: -p * is specified
  221. // user name
  222. if ( szUser == NULL )
  223. {
  224. szUser = (LPWSTR) AllocateMemory( MAX_STRING_LENGTH * sizeof( WCHAR ) );
  225. if ( szUser == NULL )
  226. {
  227. SaveLastError();
  228. return RETVAL_FAIL;
  229. }
  230. }
  231. // password
  232. if ( szPassword == NULL )
  233. {
  234. bNeedPassword = TRUE;
  235. szPassword = (LPWSTR)AllocateMemory( MAX_STRING_LENGTH * sizeof( WCHAR ) );
  236. if ( szPassword == NULL )
  237. {
  238. SaveLastError();
  239. return RETVAL_FAIL;
  240. }
  241. }
  242. // case 1
  243. if ( cmdDeleteOptions[ OI_DELETE_PASSWORD ].dwActuals == 0 )
  244. {
  245. // we need not do anything special here
  246. }
  247. // case 2
  248. else if ( cmdDeleteOptions[ OI_DELETE_PASSWORD ].pValue == NULL )
  249. {
  250. StringCopy( szPassword, L"*", GetBufferSize(szPassword)/sizeof(WCHAR));
  251. }
  252. // case 3
  253. else if ( StringCompareEx( szPassword, L"*", TRUE, 0 ) == 0 )
  254. {
  255. if ( ReallocateMemory( (LPVOID*)&szPassword,
  256. MAX_STRING_LENGTH * sizeof( WCHAR ) ) == FALSE )
  257. {
  258. SaveLastError();
  259. return RETVAL_FAIL;
  260. }
  261. // ...
  262. bNeedPassword = TRUE;
  263. }
  264. }
  265. if( ( IsLocalSystem( szServer ) == FALSE ) || ( cmdDeleteOptions[OI_DELETE_USERNAME].dwActuals == 1 ) )
  266. {
  267. bFlag = TRUE;
  268. // Establish the connection on a remote machine
  269. bResult = EstablishConnection(szServer,szUser,GetBufferSize(szUser)/sizeof(WCHAR),szPassword,GetBufferSize(szPassword)/sizeof(WCHAR), bNeedPassword );
  270. if (bResult == FALSE)
  271. {
  272. ShowLastErrorEx ( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  273. FreeMemory((LPVOID*) &szServer);
  274. FreeMemory((LPVOID*) &szUser);
  275. FreeMemory((LPVOID*) &szPassword);
  276. return EXIT_FAILURE ;
  277. }
  278. else
  279. {
  280. // though the connection is successfull, some conflict might have occured
  281. switch( GetLastError() )
  282. {
  283. case I_NO_CLOSE_CONNECTION:
  284. bCloseConnection = FALSE;
  285. break;
  286. // for mismatched credentials
  287. case E_LOCAL_CREDENTIALS:
  288. case ERROR_SESSION_CREDENTIAL_CONFLICT:
  289. {
  290. bCloseConnection = FALSE;
  291. ShowMessage( stderr, GetResString(IDS_ERROR_STRING) );
  292. ShowMessage( stderr, GetReason());
  293. FreeMemory((LPVOID*) &szServer);
  294. FreeMemory((LPVOID*) &szUser);
  295. FreeMemory((LPVOID*) &szPassword);
  296. return EXIT_FAILURE;
  297. }
  298. default :
  299. bCloseConnection = TRUE;
  300. }
  301. }
  302. //release memory for password
  303. FreeMemory((LPVOID*) &szPassword);
  304. }
  305. // Get the task Scheduler object for the machine.
  306. pITaskScheduler = GetTaskScheduler( szServer );
  307. // If the Task Scheduler is not defined then give the error message.
  308. if ( pITaskScheduler == NULL )
  309. {
  310. // close the connection that was established by the utility
  311. if ( (TRUE == bFlag) && (bCloseConnection == TRUE) )
  312. {
  313. CloseConnection( szServer );
  314. }
  315. Cleanup(pITaskScheduler);
  316. FreeMemory((LPVOID*) &szServer);
  317. FreeMemory((LPVOID*) &szUser);
  318. FreeMemory((LPVOID*) &szPassword);
  319. return EXIT_FAILURE;
  320. }
  321. //for holding values of parameters in FormatMessage()
  322. WCHAR* szValues[1] = {szTaskName};
  323. // Validate the Given Task and get as TARRAY in case of taskname
  324. // as *.
  325. arrJobs = ValidateAndGetTasks( pITaskScheduler, szTaskName);
  326. if( arrJobs == NULL )
  327. {
  328. if(StringCompare(szTaskName, ASTERIX, TRUE, 0) == 0)
  329. {
  330. ShowMessage(stdout,GetResString(IDS_TASKNAME_NOTASKS));
  331. // close the connection that was established by the utility
  332. if ( (TRUE == bFlag) && (bCloseConnection == TRUE) )
  333. {
  334. CloseConnection( szServer );
  335. }
  336. Cleanup(pITaskScheduler);
  337. FreeMemory((LPVOID*) &szServer);
  338. FreeMemory((LPVOID*) &szUser);
  339. FreeMemory((LPVOID*) &szPassword);
  340. return EXIT_SUCCESS;
  341. }
  342. else
  343. {
  344. StringCchPrintf( szMessage , SIZE_OF_ARRAY(szMessage) , GetResString(IDS_TASKNAME_NOTEXIST), _X( szTaskName ));
  345. ShowMessage(stderr, szMessage );
  346. }
  347. // close the connection that was established by the utility
  348. if ( (TRUE == bFlag) && (bCloseConnection == TRUE) )
  349. {
  350. CloseConnection( szServer );
  351. }
  352. Cleanup(pITaskScheduler);
  353. FreeMemory((LPVOID*) &szServer);
  354. FreeMemory((LPVOID*) &szUser);
  355. FreeMemory((LPVOID*) &szPassword);
  356. return EXIT_FAILURE;
  357. }
  358. // check whether the group policy prevented user from deleting tasks or not.
  359. if ( FALSE == GetGroupPolicy( szServer, szUser, TS_KEYPOLICY_DENY_DELETE , &dwPolicy ) )
  360. {
  361. // close the connection that was established by the utility
  362. if ( (TRUE == bFlag) && (bCloseConnection == TRUE) )
  363. {
  364. CloseConnection( szServer );
  365. }
  366. Cleanup(pITaskScheduler);
  367. FreeMemory((LPVOID*) &szServer);
  368. FreeMemory((LPVOID*) &szUser);
  369. FreeMemory((LPVOID*) &szPassword);
  370. return EXIT_FAILURE;
  371. }
  372. if ( dwPolicy > 0 )
  373. {
  374. ShowMessage ( stdout, GetResString (IDS_PREVENT_DELETE));
  375. // close the connection that was established by the utility
  376. if ( (TRUE == bFlag) && (bCloseConnection == TRUE) )
  377. {
  378. CloseConnection( szServer );
  379. }
  380. Cleanup(pITaskScheduler);
  381. FreeMemory((LPVOID*) &szServer);
  382. FreeMemory((LPVOID*) &szUser);
  383. FreeMemory((LPVOID*) &szPassword);
  384. return EXIT_SUCCESS;
  385. }
  386. // Confirm whether delete operation is to be perfromed
  387. if( !bForce && ConfirmDelete( szTaskName , &bWrongValue ) )
  388. {
  389. // close the connection that was established by the utility
  390. if ( (TRUE == bFlag) && (bCloseConnection == TRUE) )
  391. {
  392. CloseConnection( szServer );
  393. }
  394. Cleanup(pITaskScheduler);
  395. FreeMemory((LPVOID*) &szServer);
  396. FreeMemory((LPVOID*) &szUser);
  397. FreeMemory((LPVOID*) &szPassword);
  398. if ( bWrongValue == TRUE )
  399. {
  400. return EXIT_FAILURE;
  401. }
  402. else
  403. {
  404. return EXIT_SUCCESS;
  405. }
  406. }
  407. // Loop through all the Jobs.
  408. for( dwJobCount = 0; dwJobCount < DynArrayGetCount(arrJobs); dwJobCount++ )
  409. {
  410. // Get Each TaskName in the Array.
  411. StringCopy (szEachTaskName, DynArrayItemAsString( arrJobs, dwJobCount ), SIZE_OF_ARRAY(szEachTaskName) );
  412. StringCopy ( wszJobName, szEachTaskName , SIZE_OF_ARRAY(wszJobName));
  413. // Parse the Task so that .job is removed.
  414. if ( ParseTaskName( szEachTaskName ) )
  415. {
  416. Cleanup(pITaskScheduler);
  417. FreeMemory((LPVOID*) &szServer);
  418. FreeMemory((LPVOID*) &szUser);
  419. FreeMemory((LPVOID*) &szPassword);
  420. return EXIT_FAILURE;
  421. }
  422. // Calling the delete method of ITaskScheduler interface
  423. hr = pITaskScheduler->Delete(wszJobName);
  424. szValues[0] = (WCHAR*) szEachTaskName;
  425. // Based on the return value
  426. switch (hr)
  427. {
  428. case S_OK:
  429. StringCchPrintf ( szMessage, SIZE_OF_ARRAY(szMessage), GetResString(IDS_SUCCESS_DELETED), _X(szEachTaskName));
  430. ShowMessage ( stdout, _X(szMessage));
  431. break;
  432. case E_INVALIDARG:
  433. ShowMessage(stderr,GetResString(IDS_INVALID_ARG));
  434. // close the connection that was established by the utility
  435. if ( (TRUE == bFlag) && (bCloseConnection == TRUE) )
  436. {
  437. CloseConnection( szServer );
  438. }
  439. Cleanup(pITaskScheduler);
  440. FreeMemory((LPVOID*) &szServer);
  441. FreeMemory((LPVOID*) &szUser);
  442. FreeMemory((LPVOID*) &szPassword);
  443. return EXIT_FAILURE;
  444. case E_OUTOFMEMORY:
  445. ShowMessage(stderr,GetResString(IDS_NO_MEMORY));
  446. // close the connection that was established by the utility
  447. if ( (TRUE == bFlag) && (bCloseConnection == TRUE) )
  448. {
  449. CloseConnection( szServer );
  450. }
  451. Cleanup(pITaskScheduler);
  452. FreeMemory((LPVOID*) &szServer);
  453. FreeMemory((LPVOID*) &szUser);
  454. FreeMemory((LPVOID*) &szPassword);
  455. return EXIT_FAILURE;
  456. default:
  457. SetLastError ((DWORD) hr);
  458. ShowLastErrorEx ( stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
  459. // close the connection that was established by the utility
  460. if ( (TRUE == bFlag) && (bCloseConnection == TRUE) )
  461. {
  462. CloseConnection( szServer );
  463. }
  464. Cleanup(pITaskScheduler);
  465. FreeMemory((LPVOID*) &szServer);
  466. FreeMemory((LPVOID*) &szUser);
  467. FreeMemory((LPVOID*) &szPassword);
  468. return EXIT_FAILURE;
  469. }
  470. }
  471. // close the connection that was established by the utility
  472. if ( (TRUE == bFlag) && (bCloseConnection == TRUE) )
  473. {
  474. CloseConnection( szServer );
  475. }
  476. Cleanup(pITaskScheduler);
  477. FreeMemory((LPVOID*) &szServer);
  478. FreeMemory((LPVOID*) &szUser);
  479. FreeMemory((LPVOID*) &szPassword);
  480. return EXIT_SUCCESS;
  481. }
  482. /*****************************************************************************
  483. Routine Description:
  484. This routine displays the usage of -delete option
  485. Arguments:
  486. None
  487. Return Value :
  488. VOID
  489. ******************************************************************************/
  490. VOID
  491. DisplayDeleteUsage()
  492. {
  493. // Displaying delete usage
  494. DisplayUsage( IDS_DEL_HLP1, IDS_DEL_HLP23);
  495. }
  496. /******************************************************************************
  497. Routine Description:
  498. This function validates whether the tasks to be deleted are present
  499. in system & are valid.
  500. Arguments:
  501. [ in ] pITaskScheduler : Pointer to the ITaskScheduler Interface
  502. [ in ] szTaskName : Array containing Task name
  503. Return Value :
  504. Array of type TARRAY containing tasks
  505. ******************************************************************************/
  506. TARRAY
  507. ValidateAndGetTasks(
  508. IN ITaskScheduler *pITaskScheduler,
  509. IN LPCTSTR szTaskName
  510. )
  511. {
  512. // Dynamic Array of Jobs
  513. TARRAY arrJobs = NULL;
  514. // Enumerating WorkItems
  515. IEnumWorkItems *pIEnum = NULL;
  516. if( (pITaskScheduler == NULL ) || ( szTaskName == NULL ) )
  517. {
  518. return NULL;
  519. }
  520. // Create a Dynamic Array
  521. arrJobs = CreateDynamicArray();
  522. if (NULL == arrJobs)
  523. {
  524. return NULL;
  525. }
  526. // Enumerate the Work Items
  527. HRESULT hr = pITaskScheduler->Enum(&pIEnum);
  528. if( FAILED( hr) )
  529. {
  530. if( pIEnum )
  531. pIEnum->Release();
  532. DestroyDynamicArray(&arrJobs);
  533. return NULL;
  534. }
  535. // Names and Tasks fetches.
  536. LPWSTR *lpwszNames = NULL;
  537. DWORD dwFetchedTasks = 0;
  538. DWORD dwTasks = 0;
  539. ITask *pITask = NULL;//ITask interface
  540. // Task found or not
  541. BOOL blnFound = FALSE;
  542. // array containing the Actual Taskname .
  543. WCHAR szActualTask[MAX_STRING_LENGTH] = L"\0";
  544. WCHAR szTmpTaskName[MAX_STRING_LENGTH] = L"\0";
  545. // Enumerate all the Work Items
  546. while (SUCCEEDED(pIEnum->Next(TASKS_TO_RETRIEVE,
  547. &lpwszNames,
  548. &dwFetchedTasks))
  549. && (dwFetchedTasks != 0))
  550. {
  551. dwTasks = dwFetchedTasks - 1;
  552. // returns an pITask inteface for szEachTaskName
  553. hr = pITaskScheduler->Activate(lpwszNames[dwTasks],IID_ITask,
  554. (IUnknown**) &pITask);
  555. //case 1:
  556. // check whether the specified scheduled task is created under
  557. // some other user. If so, ignore the respective task and
  558. // continue to retrieve other tasks in the system.
  559. // If the taskname created under some other user return value
  560. // of above API must 0x80070005.
  561. //case 2:
  562. // check whether the respective .job file in %windir%\tasks\***.job is corrupted
  563. //or not. if corrupted, the above function fails and return the value
  564. // SCHED_E_UNKNOWN_OBJECT_VERSION. Eventhough, corrupted tasks would not shown in
  565. // UI..tasks would still exists in database..can remove specific/all task names
  566. // in task sheduler database.
  567. if (hr == 0x80070005 || hr == 0x8007000D || hr == SCHED_E_UNKNOWN_OBJECT_VERSION || hr == E_INVALIDARG )
  568. {
  569. // continue to retrieve other tasks
  570. continue;
  571. }
  572. if ( FAILED(hr))
  573. {
  574. CoTaskMemFree(lpwszNames[dwFetchedTasks]);
  575. if( pIEnum )
  576. {
  577. pIEnum->Release();
  578. }
  579. DestroyDynamicArray(&arrJobs);
  580. return NULL;
  581. }
  582. // If the Task Name is * then get parse the tokens
  583. // and append the jobs.
  584. if(StringCompare( szTaskName , ASTERIX, TRUE, 0) == 0 )
  585. {
  586. StringCopy(szActualTask, lpwszNames[--dwFetchedTasks], SIZE_OF_ARRAY(szActualTask));
  587. StringCopy ( szTmpTaskName, szActualTask , SIZE_OF_ARRAY(szTmpTaskName));
  588. // Parse the Task so that .job is removed.
  589. if ( ParseTaskName( szTmpTaskName ) )
  590. {
  591. CoTaskMemFree(lpwszNames[dwFetchedTasks]);
  592. if( pIEnum )
  593. {
  594. pIEnum->Release();
  595. }
  596. DestroyDynamicArray(&arrJobs);
  597. return NULL;
  598. }
  599. // Append the task in the job array
  600. DynArrayAppendString( arrJobs, szActualTask, StringLength( szActualTask, 0 ) );
  601. // Set the found flag as True.
  602. blnFound = TRUE;
  603. // Free the Named Task Memory.
  604. CoTaskMemFree(lpwszNames[dwFetchedTasks]);
  605. }
  606. else
  607. {
  608. StringCopy( szActualTask, lpwszNames[--dwFetchedTasks], SIZE_OF_ARRAY(szActualTask));
  609. StringCopy ( szTmpTaskName, szActualTask, SIZE_OF_ARRAY(szTmpTaskName) );
  610. // Parse the TaskName to remove the .job extension.
  611. if ( ParseTaskName( szTmpTaskName ) )
  612. {
  613. CoTaskMemFree(lpwszNames[dwFetchedTasks]);
  614. if( pIEnum )
  615. {
  616. pIEnum->Release();
  617. }
  618. DestroyDynamicArray(&arrJobs);
  619. return NULL;
  620. }
  621. // If the given Task matches with the TaskName present then form
  622. // the TARRAY with this task and return.
  623. if( StringCompare( szTmpTaskName, szTaskName, TRUE, 0 ) == 0 )
  624. {
  625. CoTaskMemFree(lpwszNames[dwFetchedTasks]);
  626. DynArrayAppendString( arrJobs, szActualTask,
  627. StringLength( szActualTask, 0 ) );
  628. if( pIEnum )
  629. pIEnum->Release();
  630. return arrJobs;
  631. }
  632. }
  633. }
  634. CoTaskMemFree(lpwszNames);
  635. if( pIEnum )
  636. pIEnum->Release();
  637. if( !blnFound )
  638. {
  639. DestroyDynamicArray(&arrJobs);
  640. return NULL;
  641. }
  642. // return the TARRAY object.
  643. return arrJobs;
  644. }
  645. DWORD
  646. ConfirmDelete(
  647. IN LPCTSTR szTaskName ,
  648. OUT PBOOL pbFalg
  649. )
  650. /*++
  651. Routine Description:
  652. This function confirms from the user really to delete the task(s).
  653. Arguments:
  654. [ in ] szTaskName : Array containing Task name
  655. [ out ] pbFalg : Boolean flag to check whether wrong information entered
  656. in the console or not.
  657. Return Value :
  658. EXIT_SUCCESS on success else EXIT_FAILURE
  659. --*/
  660. {
  661. // sub-local variables
  662. DWORD dwCharsRead = 0;
  663. DWORD dwPrevConsoleMode = 0;
  664. HANDLE hInputConsole = NULL;
  665. BOOL bIndirectionInput = FALSE;
  666. CHAR chAnsi = '\0';
  667. CHAR szAnsiBuf[ 10 ] = "\0";
  668. WCHAR chTmp = L'\0';
  669. WCHAR wch = L'\0';
  670. DWORD dwCharsWritten = 0;
  671. WCHAR szBuffer[MAX_RES_STRING];
  672. TCHAR szBackup[MAX_RES_STRING];
  673. TCHAR szTmpBuf[MAX_RES_STRING];
  674. WCHAR szMessage [2 * MAX_STRING_LENGTH];
  675. DWORD dwIndex = 0 ;
  676. BOOL bNoBreak = TRUE;
  677. //intialize the variables
  678. SecureZeroMemory ( szBuffer, SIZE_OF_ARRAY(szBuffer));
  679. SecureZeroMemory ( szTmpBuf, SIZE_OF_ARRAY(szTmpBuf));
  680. SecureZeroMemory ( szBackup, SIZE_OF_ARRAY(szBackup));
  681. SecureZeroMemory ( szMessage, SIZE_OF_ARRAY(szMessage));
  682. if ( szTaskName == NULL )
  683. {
  684. return FALSE;
  685. }
  686. // Get the handle for the standard input
  687. hInputConsole = GetStdHandle( STD_INPUT_HANDLE );
  688. if ( hInputConsole == INVALID_HANDLE_VALUE )
  689. {
  690. SaveLastError();
  691. // could not get the handle so return failure
  692. return EXIT_FAILURE;
  693. }
  694. MessageBeep(MB_ICONEXCLAMATION);
  695. // Check for the input redirect
  696. if( ( hInputConsole != (HANDLE)0x0000000F ) &&
  697. ( hInputConsole != (HANDLE)0x00000003 ) &&
  698. ( hInputConsole != INVALID_HANDLE_VALUE ) )
  699. {
  700. bIndirectionInput = TRUE;
  701. }
  702. // if there is no redirection
  703. if ( bIndirectionInput == FALSE )
  704. {
  705. // Get the current input mode of the input buffer
  706. if ( FALSE == GetConsoleMode( hInputConsole, &dwPrevConsoleMode ))
  707. {
  708. SaveLastError();
  709. // could not set the mode, return failure
  710. return EXIT_FAILURE;
  711. }
  712. // Set the mode such that the control keys are processed by the system
  713. if ( FALSE == SetConsoleMode( hInputConsole, ENABLE_PROCESSED_INPUT ) )
  714. {
  715. SaveLastError();
  716. // could not set the mode, return failure
  717. return EXIT_FAILURE;
  718. }
  719. }
  720. // Print the warning message.accoring to the taskname
  721. if( StringCompare( szTaskName , ASTERIX, TRUE, 0 ) == 0 )
  722. {
  723. ShowMessage(stdout, GetResString(IDS_WARN_DELETEALL));
  724. }
  725. else
  726. {
  727. StringCchPrintf ( szMessage, SIZE_OF_ARRAY(szMessage), GetResString(IDS_WARN_DELETE), _X(szTaskName));
  728. ShowMessage ( stdout, _X(szMessage));
  729. }
  730. // redirect the data into the console
  731. if ( bIndirectionInput == TRUE )
  732. {
  733. do {
  734. //read the contents of file
  735. if ( ReadFile(hInputConsole, &chAnsi, 1, &dwCharsRead, NULL) == FALSE )
  736. {
  737. SaveLastError();
  738. // could not get the handle so return failure
  739. return EXIT_FAILURE;
  740. }
  741. // check if number of characters read were zero.. or
  742. // any carriage return pressed..
  743. if ( dwCharsRead == 0 || chTmp == CARRIAGE_RETURN || chTmp == L'\n' || chTmp == L'\t' )
  744. {
  745. bNoBreak = FALSE;
  746. // exit from the loop
  747. break;
  748. }
  749. else
  750. {
  751. // convert the ANSI character into UNICODE character
  752. szAnsiBuf[ 0 ] = chAnsi;
  753. dwCharsRead = SIZE_OF_ARRAY( szBuffer );
  754. GetAsUnicodeString2( szAnsiBuf, szBuffer, &dwCharsRead );
  755. chTmp = szBuffer[ 0 ];
  756. }
  757. // write the contents to the console
  758. if ( FALSE == WriteFile ( GetStdHandle( STD_OUTPUT_HANDLE ), &chTmp, 1, &dwCharsRead, NULL ) )
  759. {
  760. SaveLastError();
  761. // could not get the handle so return failure
  762. return EXIT_FAILURE;
  763. }
  764. // copy the character
  765. wch = chTmp;
  766. StringCchPrintf ( szBackup, SIZE_OF_ARRAY(szBackup), L"%c" , wch );
  767. // increment the index
  768. dwIndex++;
  769. } while (TRUE == bNoBreak);
  770. }
  771. else
  772. {
  773. do {
  774. // Get the Character and loop accordingly.
  775. if ( ReadConsole( hInputConsole, &chTmp, 1, &dwCharsRead, NULL ) == FALSE )
  776. {
  777. SaveLastError();
  778. // Set the original console settings
  779. if ( FALSE == SetConsoleMode( hInputConsole, dwPrevConsoleMode ) )
  780. {
  781. SaveLastError();
  782. }
  783. // return failure
  784. return EXIT_FAILURE;
  785. }
  786. // check if number of chars read were zero..if so, continue...
  787. if ( dwCharsRead == 0 )
  788. {
  789. continue;
  790. }
  791. // check if any carriage return pressed...
  792. if ( chTmp == CARRIAGE_RETURN )
  793. {
  794. bNoBreak = FALSE;
  795. // exit from the loop
  796. break;
  797. }
  798. wch = chTmp;
  799. if ( wch != BACK_SPACE )
  800. {
  801. StringCchPrintf ( szTmpBuf, SIZE_OF_ARRAY(szTmpBuf), L"%c" , wch );
  802. StringConcat ( szBackup, szTmpBuf , SIZE_OF_ARRAY(szBackup));
  803. }
  804. // Check id back space is hit
  805. if ( wch == BACK_SPACE )
  806. {
  807. if ( dwIndex != 0 )
  808. {
  809. //
  810. // Remove a asterix from the console
  811. // move the cursor one character back
  812. StringCchPrintf( szBuffer, SIZE_OF_ARRAY(szBuffer), L"%c" , BACK_SPACE );
  813. if ( FALSE == WriteConsole( GetStdHandle( STD_OUTPUT_HANDLE ), szBuffer, 1,
  814. &dwCharsWritten, NULL ) )
  815. {
  816. SaveLastError();
  817. // return failure
  818. return EXIT_FAILURE;
  819. }
  820. // replace the existing character with space
  821. StringCchPrintf( szBuffer, SIZE_OF_ARRAY(szBuffer), L"%c" , BLANK_CHAR );
  822. if ( FALSE == WriteConsole( GetStdHandle( STD_OUTPUT_HANDLE ), szBuffer, 1,
  823. &dwCharsWritten, NULL ))
  824. {
  825. SaveLastError();
  826. // return failure
  827. return EXIT_FAILURE;
  828. }
  829. // now set the cursor at back position
  830. StringCchPrintf( szBuffer, SIZE_OF_ARRAY(szBuffer), L"%c" , BACK_SPACE );
  831. if ( FALSE == WriteConsole( GetStdHandle( STD_OUTPUT_HANDLE ), szBuffer, 1,
  832. &dwCharsWritten, NULL ))
  833. {
  834. SaveLastError();
  835. // return failure
  836. return EXIT_FAILURE;
  837. }
  838. szBackup [StringLength(szBackup, 0) - 1] = L'\0';
  839. // decrement the index
  840. dwIndex--;
  841. }
  842. // process the next character
  843. continue;
  844. }
  845. // write the contents onto console
  846. if ( FALSE == WriteFile ( GetStdHandle( STD_OUTPUT_HANDLE ), &wch, 1, &dwCharsRead, NULL ) )
  847. {
  848. SaveLastError();
  849. // return failure
  850. return EXIT_FAILURE;
  851. }
  852. // increment the index value
  853. dwIndex++;
  854. } while (TRUE == bNoBreak);
  855. }
  856. ShowMessage(stdout, _T("\n") );
  857. //StringCchPrintf( szBuffer, SIZE_OF_ARRAY(szBuffer), L"%c" , ch );
  858. if( (1 == dwIndex) && StringCompare ( szBackup, GetResString(IDS_UPPER_YES), TRUE, 0 ) == 0 ) {
  859. //Set the original console settings
  860. SetConsoleMode( hInputConsole, dwPrevConsoleMode );
  861. return EXIT_SUCCESS;
  862. }
  863. else if( (1 == dwIndex) && StringCompare ( szBackup, GetResString(IDS_UPPER_NO), TRUE, 0 ) == 0 )
  864. {
  865. // display a message as .. operation has been cancelled...
  866. ShowMessage ( stdout, GetResString (IDS_OPERATION_CANCELLED ) );
  867. SetConsoleMode( hInputConsole, dwPrevConsoleMode );
  868. return EXIT_FAILURE;
  869. }
  870. else
  871. {
  872. ShowMessage(stderr, GetResString( IDS_WRONG_INPUT_DELETE ));
  873. SetConsoleMode( hInputConsole, dwPrevConsoleMode );
  874. *pbFalg = TRUE;
  875. return EXIT_FAILURE;
  876. }
  877. //not returning anything as control never comes here...
  878. }