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.

1135 lines
31 KiB

  1. /******************************************************************************
  2. Copyright(c) Microsoft Corporation
  3. Module Name:
  4. query.cpp
  5. Abstract:
  6. This module queries the scheduled tasks present in the system & shows
  7. in the appropriate user specifed format.
  8. Author:
  9. G.Surender Reddy 10-Sep-2000
  10. Revision History:
  11. G.Surender Reddy 10-Sep-2000 : Created it
  12. G.Surender Reddy 25-Sep-2000 : Modified it
  13. [ Made changes to avoid memory leaks ]
  14. G.Surender Reddy 15-oct-2000 : Modified it
  15. [ Moved the strings to Resource table ]
  16. ******************************************************************************/
  17. //common header files needed for this file
  18. #include "pch.h"
  19. #include "CommonHeaderFiles.h"
  20. /******************************************************************************
  21. Routine Description:
  22. This function process the options specified in the command line ,
  23. Queries the tasks present in the system and displays according
  24. to the user specied format
  25. Arguments:
  26. [ in ] argc : The count of arguments specified in the command line
  27. [ in ] argv : Array of command line arguments
  28. Return Value :
  29. A DWORD value indicating EXIT_SUCCESS on success else
  30. EXIT_FAILURE on failure
  31. ******************************************************************************/
  32. DWORD
  33. QueryScheduledTasks( DWORD argc, LPCTSTR argv[] )
  34. {
  35. // Variables used to find whether Query main option or Usage option
  36. // specified or not
  37. BOOL bQuery = FALSE;
  38. BOOL bUsage = FALSE;
  39. BOOL bHeader = FALSE;
  40. BOOL bVerbose = FALSE;
  41. // Initialising the variables that are passed to TCMDPARSER structure
  42. STRING100 szServer = NULL_STRING;
  43. STRING100 szFormat = NULL_STRING;
  44. _TCHAR szUser[ MAX_STRING_LENGTH ] = NULL_STRING;
  45. _TCHAR szPassword[ MAX_STRING_LENGTH ] = NULL_STRING;
  46. //Taskscheduler object to operate upon
  47. ITaskScheduler *pITaskScheduler = NULL;
  48. BOOL bNeedPassword = FALSE;
  49. BOOL bResult = FALSE;
  50. BOOL bCloseConnection = TRUE;
  51. lstrcpy( szPassword, ASTERIX );
  52. // Builiding the TCMDPARSER structure
  53. TCMDPARSER cmdOptions[] = {
  54. {
  55. CMDOPTION_QUERY,
  56. CP_MAIN_OPTION,
  57. 0,
  58. 0,
  59. &bQuery,
  60. NULL_STRING,
  61. NULL,
  62. NULL
  63. },
  64. {
  65. SWITCH_SERVER,
  66. CP_TYPE_TEXT | CP_VALUE_MANDATORY,
  67. 1,
  68. 0,
  69. &szServer,
  70. NULL_STRING,
  71. NULL,
  72. NULL
  73. },
  74. {
  75. SWITCH_FORMAT,
  76. CP_TYPE_TEXT | CP_VALUE_MANDATORY,
  77. 1,
  78. 0,
  79. &szFormat,
  80. NULL_STRING,
  81. NULL,
  82. NULL
  83. },
  84. {
  85. SWITCH_NOHEADER,
  86. 1,
  87. 1,
  88. 0,
  89. &bHeader,
  90. NULL_STRING,
  91. NULL,
  92. NULL
  93. },
  94. {
  95. SWITCH_VERBOSE,
  96. 1,
  97. 1,
  98. 0,
  99. &bVerbose,
  100. NULL_STRING,
  101. NULL,
  102. NULL
  103. },
  104. {
  105. CMDOPTION_USAGE,
  106. CP_USAGE ,
  107. CP_VALUE_MANDATORY,
  108. 0,
  109. &bUsage,
  110. 0,
  111. 0
  112. },
  113. {
  114. SWITCH_USER,
  115. CP_TYPE_TEXT | CP_VALUE_MANDATORY,
  116. OPTION_COUNT,
  117. 0,
  118. &szUser,
  119. NULL_STRING,
  120. NULL,
  121. NULL
  122. },
  123. {
  124. SWITCH_PASSWORD,
  125. CP_TYPE_TEXT | CP_VALUE_OPTIONAL,
  126. OPTION_COUNT,
  127. 0,
  128. &szPassword,
  129. NULL_STRING,
  130. NULL,
  131. NULL
  132. }
  133. };
  134. // Parsing the query option switches
  135. if (DoParseParam( argc, argv,SIZE_OF_ARRAY(cmdOptions), cmdOptions ) == FALSE)
  136. {
  137. DISPLAY_MESSAGE( stderr, GetResString(IDS_LOGTYPE_ERROR ));
  138. DISPLAY_MESSAGE( stderr, GetReason() );
  139. //DISPLAY_MESSAGE(stdout,GetResString(IDS_QUERY_USAGE));
  140. return EXIT_FAILURE;
  141. }
  142. // triming the null spaces
  143. StrTrim(szServer, TRIM_SPACES );
  144. StrTrim(szFormat, TRIM_SPACES );
  145. // check whether password (-p) specified in the command line or not.
  146. if ( cmdOptions[OI_QPASSWORD].dwActuals == 0 )
  147. {
  148. lstrcpy( szPassword, NULL_STRING );
  149. }
  150. // Displaying query usage if user specified -? with -query option
  151. if( bUsage == TRUE)
  152. {
  153. DisplayQueryUsage();
  154. return EXIT_SUCCESS;
  155. }
  156. // check for -s option
  157. if( ( cmdOptions[OI_QSERVER].dwActuals == 1 ) &&
  158. ( ( lstrlen( szServer ) == 0 ) ) )
  159. {
  160. DISPLAY_MESSAGE(stderr,GetResString(IDS_NO_SERVER));
  161. return RETVAL_FAIL;
  162. }
  163. // check for -fo option
  164. if ( ( cmdOptions[OI_QFORMAT].dwActuals == 1 ) &&
  165. ( lstrlen ( szFormat ) == 0 ) )
  166. {
  167. //wrong format type
  168. DISPLAY_MESSAGE( stderr , GetResString(IDS_QUERY_FORMAT_ERR ));
  169. return EXIT_FAILURE;
  170. }
  171. if ( cmdOptions[ OI_QUSERNAME ].dwActuals == 0 && cmdOptions[OI_QPASSWORD].dwActuals == 1 )
  172. {
  173. // invalid syntax
  174. DISPLAY_MESSAGE(stderr, GetResString(IDS_QPASSWORD_BUT_NOUSERNAME));
  175. return RETVAL_FAIL;
  176. }
  177. // check for the length of username
  178. if( lstrlen( szUser ) > MAX_USERNAME_LENGTH )
  179. {
  180. DISPLAY_MESSAGE(stderr,GetResString(IDS_INVALID_UNAME));
  181. return RETVAL_FAIL;
  182. }
  183. // check for invalid user name
  184. if( ( cmdOptions[OI_QSERVER].dwActuals == 0 ) && ( cmdOptions[OI_QUSERNAME].dwActuals == 1 ) )
  185. {
  186. DISPLAY_MESSAGE(stderr, GetResString(IDS_QUERY_USER_BUT_NOMACHINE));
  187. return RETVAL_FAIL;
  188. }
  189. // check for the length of user name
  190. if( ( cmdOptions[OI_QSERVER].dwActuals == 1 ) && ( cmdOptions[OI_QUSERNAME].dwActuals == 1 ) &&
  191. ( lstrlen( szUser ) == 0 ) )
  192. {
  193. DISPLAY_MESSAGE(stderr, GetResString(IDS_INVALID_USERNAME));
  194. return RETVAL_FAIL;
  195. }
  196. // check for the length of password
  197. if( lstrlen( szPassword ) > MAX_PASSWORD_LENGTH )
  198. {
  199. DISPLAY_MESSAGE(stderr,GetResString(IDS_INVALID_PASSWORD));
  200. return RETVAL_FAIL;
  201. }
  202. // check whether the password (-p) specified in the command line or not
  203. // and also check whether '*' or empty is given for -p or not
  204. if( ( IsLocalSystem( szServer ) == FALSE )
  205. && ( ( cmdOptions[OI_QPASSWORD].dwActuals == 0 ) || ( lstrcmpi ( szPassword, ASTERIX ) == 0 ) ) )
  206. {
  207. bNeedPassword = TRUE;
  208. }
  209. DWORD dwFormatType = SR_FORMAT_TABLE;//default format type(TABLE Format)
  210. BOOL bNoHeader = TRUE; // For LIST format type -nh switch is not applicable
  211. //Determine the Format for display & check for error if any in format type
  212. if( lstrcmpi( szFormat , GetResString(IDS_QUERY_FORMAT_LIST) ) == 0 )
  213. {
  214. dwFormatType = SR_FORMAT_LIST;
  215. bNoHeader = FALSE;
  216. }
  217. else if( lstrcmpi( szFormat , GetResString(IDS_QUERY_FORMAT_CSV) ) == 0 )
  218. {
  219. dwFormatType = SR_FORMAT_CSV;
  220. }
  221. else
  222. {
  223. if( ( lstrlen( szFormat ) ) &&
  224. ( lstrcmpi( szFormat , GetResString(IDS_QUERY_FORMAT_TABLE) ) != 0 ) )
  225. {
  226. //wrong format type
  227. DISPLAY_MESSAGE( stderr , GetResString(IDS_QUERY_FORMAT_ERR ));
  228. return EXIT_FAILURE;
  229. }
  230. }
  231. //If -n is specified for LIST or CSV then report error
  232. if( ( bNoHeader == FALSE ) && ( bHeader == TRUE ))
  233. {
  234. DISPLAY_MESSAGE( stderr , GetResString(IDS_NOHEADER_NA ));
  235. return EXIT_FAILURE;
  236. }
  237. if( ( IsLocalSystem( szServer ) == FALSE ) || ( cmdOptions[OI_QUSERNAME].dwActuals == 1 ) )
  238. {
  239. // Establish the connection on a remote machine
  240. bResult = EstablishConnection(szServer,szUser,SIZE_OF_ARRAY(szUser),szPassword,SIZE_OF_ARRAY(szPassword), bNeedPassword );
  241. if (bResult == FALSE)
  242. {
  243. DISPLAY_MESSAGE( stderr, GetResString(IDS_ERROR_STRING) );
  244. DISPLAY_MESSAGE( stderr, GetReason());
  245. return EXIT_FAILURE ;
  246. }
  247. else
  248. {
  249. // though the connection is successfull, some conflict might have occured
  250. switch( GetLastError() )
  251. {
  252. case I_NO_CLOSE_CONNECTION:
  253. bCloseConnection = FALSE;
  254. break;
  255. case E_LOCAL_CREDENTIALS:
  256. case ERROR_SESSION_CREDENTIAL_CONFLICT:
  257. {
  258. bCloseConnection = FALSE;
  259. DISPLAY_MESSAGE( stderr, GetResString(IDS_ERROR_STRING) );
  260. DISPLAY_MESSAGE( stderr, GetReason());
  261. return EXIT_FAILURE;
  262. }
  263. }
  264. }
  265. }
  266. //Fetch the TaskScheduler Interface to operate on
  267. pITaskScheduler = GetTaskScheduler( szServer );
  268. if(pITaskScheduler == NULL)
  269. {
  270. // close the connection that was established by the utility
  271. if ( bCloseConnection == TRUE )
  272. CloseConnection( szServer );
  273. Cleanup(pITaskScheduler);
  274. return EXIT_FAILURE;
  275. }
  276. //Display the tasks & its properties in the user specified format
  277. HRESULT hr = DisplayTasks(pITaskScheduler,bVerbose,dwFormatType,bHeader);
  278. if(FAILED(hr))
  279. {
  280. // close the connection that was established by the utility
  281. if ( bCloseConnection == TRUE )
  282. CloseConnection( szServer );
  283. Cleanup(pITaskScheduler);
  284. return EXIT_FAILURE;
  285. }
  286. // close the connection that was established by the utility
  287. if ( bCloseConnection == TRUE )
  288. CloseConnection( szServer );
  289. Cleanup(pITaskScheduler);
  290. return EXIT_SUCCESS;
  291. }
  292. /******************************************************************************
  293. Routine Description:
  294. This function displays the usage of -query option.
  295. Arguments:
  296. None
  297. Return Value :
  298. VOID
  299. ******************************************************************************/
  300. VOID
  301. DisplayQueryUsage()
  302. {
  303. // Display the usage of -query option
  304. DisplayUsage( IDS_QUERY_HLP1, IDS_QUERY_HLP25);
  305. }
  306. /******************************************************************************
  307. Routine Description:
  308. This function retrieves the tasks present in the system & displays according to
  309. the user specified format.
  310. Arguments:
  311. [ in ] pITaskScheduler : Pointer to the ITaskScheduler Interface
  312. [ in ] bVerbose : flag indicating whether the out is to be filtered.
  313. [ in ] dwFormatType : Format type[TABLE,LIST,CSV etc]
  314. [ in ] bHeader : Whether the header should be displayed in the output
  315. Return Value :
  316. A HRESULT value indicating success code else failure code
  317. ******************************************************************************/
  318. HRESULT
  319. DisplayTasks(ITaskScheduler* pITaskScheduler,BOOL bVerbose,DWORD dwFormatType,
  320. BOOL bHeader)
  321. {
  322. //declarations
  323. LPWSTR lpwszComputerName = NULL;
  324. HRESULT hr = S_OK;
  325. STRING256 szServerName = NULL_STRING;
  326. STRING256 szResolvedServerName = NULL_STRING;
  327. LPTSTR lpszTemp = NULL;
  328. lstrcpy( szServerName , GetResString(IDS_TASK_PROPERTY_NA));
  329. //Retrieve the name of the computer on which TaskScheduler is operated
  330. hr = pITaskScheduler->GetTargetComputer(&lpwszComputerName);
  331. if( SUCCEEDED( hr ) )
  332. {
  333. lpszTemp = lpwszComputerName;
  334. //Remove the backslash[\\] from the computer name
  335. lpwszComputerName = _wcsspnp( lpwszComputerName , L"\\" );
  336. if ( lpwszComputerName == NULL )
  337. {
  338. DISPLAY_MESSAGE(stderr,GetResString(IDS_CREATE_READERROR));
  339. CoTaskMemFree(lpszTemp);
  340. return S_FALSE;
  341. }
  342. if (GetCompatibleStringFromUnicode( lpwszComputerName,szServerName,
  343. SIZE_OF_ARRAY(szServerName) ) == NULL )
  344. {
  345. DISPLAY_MESSAGE(stderr,GetResString(IDS_CREATE_READERROR));
  346. CoTaskMemFree(lpszTemp);
  347. return S_FALSE;
  348. }
  349. CoTaskMemFree(lpszTemp);
  350. if ( IsValidIPAddress( szServerName ) == TRUE )
  351. {
  352. if( TRUE == GetHostByIPAddr( szServerName, szResolvedServerName , FALSE ) )
  353. {
  354. lstrcpy( szServerName , szResolvedServerName );
  355. }
  356. else
  357. {
  358. lstrcpy( szServerName , GetResString(IDS_TASK_PROPERTY_NA));
  359. }
  360. }
  361. }
  362. //Initialize the TCOLUMNS structure array
  363. TCOLUMNS pVerboseCols[] =
  364. {
  365. {NULL_STRING,WIDTH_HOSTNAME, SR_TYPE_STRING, COL_FORMAT_STRING, NULL, NULL},
  366. {NULL_STRING,WIDTH_TASKNAME,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  367. {NULL_STRING,WIDTH_NEXTRUNTIME,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  368. {NULL_STRING,WIDTH_STATUS,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  369. {NULL_STRING,WIDTH_LASTRUNTIME,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  370. {NULL_STRING,WIDTH_LASTRESULT,SR_TYPE_NUMERIC|SR_VALUEFORMAT,COL_FORMAT_HEX,NULL,NULL},
  371. {NULL_STRING,WIDTH_CREATOR,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  372. {NULL_STRING,WIDTH_SCHEDULE,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  373. {NULL_STRING,WIDTH_APPNAME,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  374. {NULL_STRING,WIDTH_WORKDIRECTORY,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  375. {NULL_STRING,WIDTH_COMMENT,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  376. {NULL_STRING,WIDTH_TASKSTATE,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  377. {NULL_STRING,WIDTH_TASKTYPE,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  378. {NULL_STRING,WIDTH_TASKSTIME,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  379. {NULL_STRING,WIDTH_TASKSDATE,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  380. {NULL_STRING,WIDTH_TASKEDATE,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  381. {NULL_STRING,WIDTH_TASKDAYS,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  382. {NULL_STRING,WIDTH_TASKMONTHS,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  383. {NULL_STRING,WIDTH_TASKRUNASUSER,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  384. {NULL_STRING,WIDTH_TASKDELETE,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  385. {NULL_STRING,WIDTH_TASKSTOP,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  386. {NULL_STRING,WIDTH_TASK_RPTEVERY,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  387. {NULL_STRING,WIDTH_TASK_UNTILRPTTIME,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  388. {NULL_STRING,WIDTH_TASK_RPTDURATION,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  389. {NULL_STRING,WIDTH_TASK_RPTRUNNING,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  390. {NULL_STRING,WIDTH_TASKIDLE,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  391. {NULL_STRING,WIDTH_TASKPOWER,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL}
  392. };
  393. TCOLUMNS pNonVerboseCols[] =
  394. {
  395. {NULL_STRING,WIDTH_TASKNAME,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  396. {NULL_STRING,WIDTH_NEXTRUNTIME,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  397. {NULL_STRING,WIDTH_STATUS,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL}
  398. };
  399. DWORD dwColCount = 0;
  400. int j = 0;
  401. int k = 0;
  402. //Load the column names for non verbose mode
  403. if ( (dwFormatType == SR_FORMAT_TABLE) || (dwFormatType == SR_FORMAT_CSV) )
  404. {
  405. for( dwColCount = IDS_COL_TASKNAME , j = 0 ; dwColCount <= IDS_COL_STATUS;
  406. dwColCount++,j++)
  407. {
  408. lstrcpy(pNonVerboseCols[j].szColumn ,GetResString(dwColCount));
  409. }
  410. }
  411. //Load the column names for verbose mode
  412. for( dwColCount = IDS_COL_HOSTNAME , j = 0 ; dwColCount <= IDS_COL_POWER;
  413. dwColCount++,j++)
  414. {
  415. lstrcpy(pVerboseCols[j].szColumn ,GetResString(dwColCount));
  416. }
  417. TARRAY pColData = CreateDynamicArray();
  418. size_t iArrSize = SIZE_OF_ARRAY( pVerboseCols );
  419. //latest declarations
  420. _TCHAR szTaskProperty[MAX_STRING_LENGTH] = NULL_STRING;
  421. _TCHAR szScheduleName[MAX_STRING_LENGTH] = NULL_STRING;
  422. _TCHAR szMessage[MAX_STRING_LENGTH] = NULL_STRING;
  423. _TCHAR szBuffer[MAX_STRING_LENGTH] = NULL_STRING;
  424. _TCHAR szTmpBuf[MAX_STRING_LENGTH] = NULL_STRING;
  425. ITask *pITask = NULL;//ITask interface
  426. DWORD dwExitCode = 0;
  427. LPWSTR* lpwszNames = NULL;
  428. DWORD dwFetchedTasks = 0;
  429. LPTSTR lpStatus = NULL;
  430. int iTaskCount = 0;
  431. BOOL bTasksExists = FALSE;
  432. _TCHAR szTime[MAX_DATETIME_LEN] = NULL_STRING;
  433. _TCHAR szDate[MAX_DATETIME_LEN] = NULL_STRING;
  434. //Index to the array of task names
  435. DWORD dwArrTaskIndex = 0;
  436. WORD wIdleMinutes = 0;
  437. WORD wDeadlineMinutes = 0 ;
  438. STRING100 szIdleTime = NULL_STRING;
  439. STRING100 szIdleRetryTime = NULL_STRING;
  440. STRING256 szTaskName = NULL_STRING;
  441. TASKPROPS tcTaskProperties;
  442. _TCHAR* szValues[1] = {NULL};//for holding values of parameters in FormatMessage()
  443. BOOL bOnBattery = FALSE;
  444. BOOL bStopTask = FALSE;
  445. BOOL bNotScheduled = FALSE;
  446. IEnumWorkItems *pIEnum = NULL;
  447. hr = pITaskScheduler->Enum(&pIEnum);//Get the IEnumWorkItems Interface
  448. if (FAILED(hr))
  449. {
  450. DISPLAY_MESSAGE(stderr,GetResString(IDS_CREATE_READERROR));
  451. if( pIEnum )
  452. pIEnum->Release();
  453. return hr;
  454. }
  455. while (SUCCEEDED(pIEnum->Next(TASKS_TO_RETRIEVE,
  456. &lpwszNames,
  457. &dwFetchedTasks))
  458. && (dwFetchedTasks != 0))
  459. {
  460. bTasksExists = TRUE;
  461. dwArrTaskIndex = dwFetchedTasks - 1;
  462. if ( GetCompatibleStringFromUnicode(lpwszNames[dwArrTaskIndex],szTaskName,
  463. SIZE_OF_ARRAY(szTaskName)) == NULL )
  464. {
  465. CoTaskMemFree(lpwszNames[dwArrTaskIndex]);
  466. if(pIEnum)
  467. {
  468. pIEnum->Release();
  469. }
  470. if(pITask)
  471. {
  472. pITask->Release();
  473. }
  474. return S_FALSE;
  475. }
  476. if(szTaskName != NULL)
  477. {
  478. //remove the .job extension from the task name
  479. if (ParseTaskName(szTaskName))
  480. {
  481. CoTaskMemFree(lpwszNames[dwArrTaskIndex]);
  482. if(pIEnum)
  483. pIEnum->Release();
  484. if(pITask)
  485. pITask->Release();
  486. return S_FALSE;
  487. }
  488. }
  489. // return an pITask inteface for wszJobName
  490. hr = pITaskScheduler->Activate(lpwszNames[dwArrTaskIndex],IID_ITask,
  491. (IUnknown**) &pITask);
  492. if ( ( FAILED(hr) ) || (pITask == NULL) )
  493. {
  494. DisplayErrorMsg(hr);
  495. CoTaskMemFree(lpwszNames[dwArrTaskIndex]);
  496. if(pIEnum)
  497. pIEnum->Release();
  498. if(pITask)
  499. pITask->Release();
  500. return hr;
  501. }
  502. WORD wTriggerCount = 0;
  503. BOOL bMultiTriggers = FALSE;
  504. hr = pITask->GetTriggerCount( &wTriggerCount );
  505. // check for multiple triggers
  506. if( wTriggerCount > 1)
  507. {
  508. bMultiTriggers = TRUE;
  509. }
  510. // check for not scheduled tasks
  511. if ( wTriggerCount == 0 )
  512. {
  513. bNotScheduled = TRUE;
  514. }
  515. for( WORD wCurrentTrigger = 0; ( bNotScheduled == TRUE ) || ( wCurrentTrigger < wTriggerCount );
  516. wCurrentTrigger++ )
  517. {
  518. //Start appending to the 2D array
  519. DynArrayAppendRow(pColData,iArrSize);
  520. // For LIST format
  521. if ( ( bVerbose == TRUE ) || (dwFormatType == SR_FORMAT_LIST ))
  522. {
  523. //Insert the server name
  524. DynArraySetString2(pColData,iTaskCount,HOSTNAME_COL_NUMBER,szServerName,0);
  525. }
  526. // For TABLE and CSV formats
  527. if ( ( bVerbose == FALSE ) && ( (dwFormatType == SR_FORMAT_TABLE) ||
  528. (dwFormatType == SR_FORMAT_CSV) ) )
  529. {
  530. DWORD dwTaskColNumber = TASKNAME_COL_NUMBER - 1;
  531. //Insert the task name for TABLE or CSV
  532. DynArraySetString2(pColData,iTaskCount,dwTaskColNumber,szTaskName,0);
  533. }
  534. else
  535. {
  536. //Insert the task name for verbose mode
  537. DynArraySetString2(pColData,iTaskCount,TASKNAME_COL_NUMBER,szTaskName,0);
  538. }
  539. lstrcpy(szTime,NULL_STRING);
  540. lstrcpy(szDate,NULL_STRING);
  541. //find the next run time of the task
  542. hr = GetTaskRunTime(pITask,szTime,szDate,TASK_NEXT_RUNTIME,wCurrentTrigger);
  543. if (FAILED(hr))
  544. {
  545. lstrcpy( szTaskProperty , GetResString(IDS_TASK_NEVER) );
  546. }
  547. else
  548. {
  549. if(lstrcmpi( szDate , GetResString( IDS_TASK_IDLE ) ) == 0 ||
  550. lstrcmpi( szDate , GetResString( IDS_TASK_SYSSTART )) == 0 ||
  551. lstrcmpi( szDate , GetResString( IDS_TASK_LOGON )) == 0 ||
  552. lstrcmpi( szDate , GetResString( IDS_TASK_NEVER )) == 0 )
  553. {
  554. lstrcpy( szTaskProperty , szDate );
  555. }
  556. else
  557. {
  558. lstrcpy( szTaskProperty , szTime );
  559. lstrcat( szTaskProperty , TIME_DATE_SEPERATOR);
  560. lstrcat( szTaskProperty , szDate);
  561. }
  562. }
  563. if ( ( bVerbose == FALSE ) && ( (dwFormatType == SR_FORMAT_TABLE) ||
  564. (dwFormatType == SR_FORMAT_CSV) ) )
  565. {
  566. DWORD dwNextRunTime = NEXTRUNTIME_COL_NUMBER - 1;
  567. //Insert the task name for TABLE or CSV
  568. DynArraySetString2(pColData,iTaskCount,dwNextRunTime,szTaskProperty,0);
  569. }
  570. else
  571. {
  572. //Insert the Next run time of the task
  573. DynArraySetString2(pColData,iTaskCount,NEXTRUNTIME_COL_NUMBER,szTaskProperty,0);
  574. }
  575. //retrieve the status code
  576. hr = GetStatusCode(pITask,szTaskProperty);
  577. if (FAILED(hr))
  578. {
  579. lstrcpy( szTaskProperty , GetResString(IDS_TASK_PROPERTY_NA) );
  580. }
  581. if ( ( bVerbose == FALSE ) && ( (dwFormatType == SR_FORMAT_TABLE) ||
  582. (dwFormatType == SR_FORMAT_CSV) ) )
  583. {
  584. DWORD dwStatusColNum = STATUS_COL_NUMBER - 1;
  585. //Insert the task name for TABLE or CSV
  586. DynArraySetString2(pColData,iTaskCount,dwStatusColNum,szTaskProperty,0);
  587. }
  588. else
  589. {
  590. //Insert the status string
  591. DynArraySetString2(pColData,iTaskCount,STATUS_COL_NUMBER,szTaskProperty,0);
  592. }
  593. if( bVerbose) //If V [verbose mode is present ,show all other columns]
  594. {
  595. lstrcpy(szTime,NULL_STRING);
  596. lstrcpy(szDate,NULL_STRING);
  597. //Insert the server name
  598. //DynArraySetString2(pColData,iTaskCount,HOSTNAME_COL_NUMBER,szServerName,0);
  599. //find the last run time of the task
  600. hr = GetTaskRunTime(pITask,szTime,szDate,TASK_LAST_RUNTIME,wCurrentTrigger);
  601. if (FAILED(hr))
  602. {
  603. lstrcpy( szTaskProperty , GetResString(IDS_TASK_NEVER) );
  604. }
  605. else
  606. {
  607. if(lstrcmpi( szDate , GetResString( IDS_TASK_IDLE ) ) == 0 ||
  608. lstrcmpi( szDate , GetResString( IDS_TASK_SYSSTART )) == 0 ||
  609. lstrcmpi( szDate , GetResString( IDS_TASK_LOGON )) == 0 ||
  610. lstrcmpi( szDate , GetResString( IDS_TASK_NEVER )) == 0 )
  611. {
  612. lstrcpy( szTaskProperty , szDate );
  613. }
  614. else
  615. {
  616. lstrcpy( szTaskProperty , szTime );
  617. lstrcat( szTaskProperty , TIME_DATE_SEPERATOR);
  618. lstrcat( szTaskProperty , szDate);
  619. }
  620. }
  621. //Insert the task last run time
  622. DynArraySetString2(pColData,iTaskCount,LASTRUNTIME_COL_NUMBER,szTaskProperty,0);
  623. //retrieve the exit code
  624. pITask->GetExitCode(&dwExitCode);
  625. //Insert the Exit code
  626. DynArraySetDWORD2(pColData,iTaskCount,LASTRESULT_COL_NUMBER,dwExitCode);
  627. // Get the creator name for the task
  628. hr = GetCreator(pITask,szTaskProperty);
  629. if (FAILED(hr))
  630. {
  631. lstrcpy( szTaskProperty , GetResString(IDS_TASK_PROPERTY_NA) );
  632. }
  633. if( lstrcmpi( szTaskProperty , NULL_STRING ) == 0 )
  634. lstrcpy( szTaskProperty , GetResString(IDS_QUERY_NA) );
  635. //insert the creator name to 2D array
  636. DynArraySetString2(pColData,iTaskCount,CREATOR_COL_NUMBER,szTaskProperty,0);
  637. //retrieve the Trigger string
  638. hr = GetTriggerString(pITask,szTaskProperty,wCurrentTrigger);
  639. if (FAILED(hr))
  640. {
  641. lstrcpy( szTaskProperty , GetResString(IDS_NOTSCHEDULED_TASK) );
  642. }
  643. lstrcpy(szScheduleName, szTaskProperty);
  644. //Insert the trigger string
  645. DynArraySetString2(pColData,iTaskCount,SCHEDULE_COL_NUMBER,szTaskProperty,0);
  646. //Get the application path associated with the task
  647. hr = GetApplicationToRun(pITask,szTaskProperty);
  648. if (FAILED(hr))
  649. {
  650. lstrcpy( szTaskProperty , GetResString(IDS_TASK_PROPERTY_NA) );
  651. }
  652. if( lstrcmpi( szTaskProperty , NULL_STRING ) == 0 )
  653. lstrcpy( szTaskProperty , GetResString(IDS_QUERY_NA) );
  654. //Insert the application associated with task
  655. DynArraySetString2(pColData,iTaskCount,TASKTORUN_COL_NUMBER,szTaskProperty,0);
  656. //Get the working directory of the task's associated application
  657. hr = GetWorkingDirectory(pITask,szTaskProperty);
  658. if (FAILED(hr))
  659. {
  660. lstrcpy( szTaskProperty , GetResString(IDS_TASK_PROPERTY_NA) );
  661. }
  662. if( lstrcmpi( szTaskProperty , NULL_STRING ) == 0 )
  663. lstrcpy( szTaskProperty , GetResString(IDS_QUERY_NA) );
  664. //Insert the app.working directory
  665. DynArraySetString2(pColData,iTaskCount,STARTIN_COL_NUMBER,szTaskProperty,0);
  666. //Get the comment name associated with the task
  667. hr = GetComment(pITask,szTaskProperty);
  668. if (FAILED(hr))
  669. {
  670. lstrcpy( szTaskProperty , GetResString(IDS_TASK_PROPERTY_NA) );
  671. }
  672. //Insert the comment name
  673. if( lstrcmpi( szTaskProperty , NULL_STRING ) == 0 )
  674. lstrcpy( szTaskProperty , GetResString(IDS_QUERY_NA) );
  675. DynArraySetString2(pColData,iTaskCount,COMMENT_COL_NUMBER,szTaskProperty,0);
  676. //Determine the task state properties
  677. //Determine the TASK_FLAG_DISABLED
  678. hr = GetTaskState(pITask,szTaskProperty,TASK_FLAG_DISABLED);
  679. if (FAILED(hr))
  680. {
  681. lstrcpy( szTaskProperty , GetResString(IDS_TASK_PROPERTY_NA) );
  682. }
  683. //Insert the TASK_FLAG_DISABLED state
  684. DynArraySetString2(pColData,iTaskCount,TASKSTATE_COL_NUMBER,szTaskProperty,0);
  685. //Determine the TASK_FLAG_DELETE_WHEN_DONE
  686. hr = GetTaskState(pITask,szTaskProperty,TASK_FLAG_DELETE_WHEN_DONE );
  687. if (FAILED(hr))
  688. {
  689. lstrcpy( szTaskProperty , GetResString(IDS_TASK_PROPERTY_NA) );
  690. }
  691. //Insert the TASK_FLAG_DELETE_WHEN_DONE state
  692. DynArraySetString2(pColData,iTaskCount,DELETE_IFNOTRESCHEDULED_COL_NUMBER,
  693. szTaskProperty,0);
  694. //TASK_FLAG_START_ONLY_IF_IDLE
  695. //initialise to neutral values
  696. lstrcpy(szIdleTime,GetResString(IDS_TASK_PROPERTY_DISABLED));
  697. lstrcpy(szIdleRetryTime,szIdleTime);
  698. hr = GetTaskState(pITask,szTaskProperty,TASK_FLAG_START_ONLY_IF_IDLE);
  699. if (FAILED(hr))
  700. {
  701. lstrcpy( szIdleTime , GetResString(IDS_TASK_PROPERTY_NA) );
  702. lstrcpy( szIdleRetryTime , GetResString(IDS_TASK_PROPERTY_NA) );
  703. }
  704. if(lstrcmpi(szTaskProperty,GetResString(IDS_TASK_PROPERTY_ENABLED)) == 0 )
  705. {
  706. //Display the rest applicable Idle fields
  707. hr = pITask->GetIdleWait(&wIdleMinutes,&wDeadlineMinutes);
  708. if ( SUCCEEDED(hr))
  709. {
  710. FORMAT_STRING(szIdleTime,_T("%d"),wIdleMinutes);
  711. FORMAT_STRING(szIdleRetryTime,_T("%d"),wDeadlineMinutes);
  712. }
  713. szValues[0] = (_TCHAR*) szIdleTime;
  714. FormatMessage( FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
  715. GetResString(IDS_COL_IDLE_ONLYSTART),0,MAKELANGID(LANG_NEUTRAL,
  716. SUBLANG_DEFAULT),szMessage,
  717. MAX_STRING_LENGTH,(va_list*)szValues
  718. );
  719. lstrcpy( szBuffer, szMessage );
  720. lstrcat( szBuffer, TIME_DATE_SEPERATOR );
  721. szValues[0] = (_TCHAR*) szIdleRetryTime;
  722. FormatMessage( FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
  723. GetResString(IDS_COL_IDLE_NOTIDLE),0,MAKELANGID(LANG_NEUTRAL,
  724. SUBLANG_DEFAULT),szMessage,
  725. MAX_STRING_LENGTH,(va_list*)szValues
  726. );
  727. lstrcat( szBuffer, szMessage );
  728. //Get the property of ( kill task if computer goes idle)
  729. hr = GetTaskState(pITask,szTaskProperty,TASK_FLAG_KILL_ON_IDLE_END );
  730. if (FAILED(hr))
  731. {
  732. lstrcpy( szTaskProperty , GetResString(IDS_TASK_PROPERTY_NA) );
  733. }
  734. if(lstrcmpi(szTaskProperty,GetResString(IDS_TASK_PROPERTY_ENABLED)) == 0 )
  735. {
  736. lstrcat( szBuffer, TIME_DATE_SEPERATOR );
  737. lstrcat( szBuffer, GetResString ( IDS_COL_IDLE_STOPTASK ) );
  738. }
  739. //Insert the property of ( kill task if computer goes idle)
  740. DynArraySetString2(pColData,iTaskCount,IDLE_COL_NUMBER,szBuffer,0);
  741. }
  742. else
  743. {
  744. DynArraySetString2(pColData,iTaskCount,IDLE_COL_NUMBER,szTaskProperty,0);
  745. }
  746. //Get the Power mgmt.properties
  747. hr = GetTaskState(pITask,szTaskProperty,TASK_FLAG_DONT_START_IF_ON_BATTERIES );
  748. if (FAILED(hr))
  749. {
  750. lstrcpy( szTaskProperty , GetResString(IDS_TASK_PROPERTY_NA) );
  751. }
  752. if(lstrcmpi(szTaskProperty,GetResString(IDS_TASK_PROPERTY_ENABLED)) ==0 )
  753. {
  754. lstrcpy(szBuffer, GetResString (IDS_COL_POWER_NOSTART));
  755. bOnBattery = TRUE;
  756. }
  757. hr = GetTaskState(pITask,szTaskProperty,TASK_FLAG_KILL_IF_GOING_ON_BATTERIES);
  758. if (FAILED(hr))
  759. {
  760. lstrcpy( szTaskProperty , GetResString(IDS_TASK_PROPERTY_NA) );
  761. }
  762. if(lstrcmpi(szTaskProperty,GetResString(IDS_TASK_PROPERTY_ENABLED)) ==0 )
  763. {
  764. lstrcpy( szMessage, GetResString (IDS_COL_POWER_STOP));
  765. bStopTask = TRUE;
  766. }
  767. if ( ( bOnBattery == TRUE ) && ( bStopTask == TRUE ) )
  768. {
  769. lstrcpy(szTmpBuf, szBuffer);
  770. lstrcat( szTmpBuf, TIME_DATE_SEPERATOR );
  771. lstrcat( szTmpBuf, szMessage );
  772. }
  773. else if ( ( bOnBattery == FALSE ) && ( bStopTask == TRUE ) )
  774. {
  775. lstrcpy( szTmpBuf, szMessage );
  776. }
  777. else if ( ( bOnBattery == TRUE ) && ( bStopTask == FALSE ) )
  778. {
  779. lstrcpy( szTmpBuf, szBuffer );
  780. }
  781. if( ( bOnBattery == FALSE ) && ( bStopTask == FALSE ) )
  782. {
  783. DynArraySetString2(pColData,iTaskCount,POWER_COL_NUMBER,szTaskProperty,0);
  784. }
  785. else
  786. {
  787. DynArraySetString2(pColData,iTaskCount,POWER_COL_NUMBER,szTmpBuf,0);
  788. }
  789. //Get RunAsUser
  790. hr = GetRunAsUser(pITask, szTaskProperty);
  791. if (FAILED(hr))
  792. {
  793. lstrcpy( szTaskProperty , GetResString(IDS_USER_UNKNOWN) );
  794. }
  795. if( lstrcmpi( szTaskProperty , NULL_STRING ) == 0 )
  796. lstrcpy( szTaskProperty , NTAUTHORITY_USER );
  797. DynArraySetString2(pColData,iTaskCount,RUNASUSER_COL_NUMBER,szTaskProperty,0);
  798. lstrcpy( szTaskProperty , NULL_STRING );
  799. //Get the task's maximum run time & insert in the 2D array
  800. hr = GetMaxRunTime(pITask,szTaskProperty);
  801. if (FAILED(hr))
  802. {
  803. lstrcpy( szTaskProperty , GetResString(IDS_TASK_PROPERTY_NA) );
  804. }
  805. DynArraySetString2(pColData,iTaskCount,STOPTASK_COL_NUMBER,szTaskProperty,0);
  806. hr = GetTaskProps(pITask,&tcTaskProperties,wCurrentTrigger, szScheduleName);
  807. if (FAILED(hr))
  808. {
  809. lstrcpy( tcTaskProperties.szTaskType , GetResString(IDS_TASK_PROPERTY_NA) );
  810. lstrcpy( tcTaskProperties.szTaskStartTime , GetResString(IDS_TASK_PROPERTY_NA) );
  811. lstrcpy( tcTaskProperties.szTaskEndDate , GetResString(IDS_TASK_PROPERTY_NA) );
  812. lstrcpy( tcTaskProperties.szTaskDays , GetResString(IDS_TASK_PROPERTY_NA) );
  813. lstrcpy( tcTaskProperties.szTaskMonths , GetResString(IDS_TASK_PROPERTY_NA) );
  814. lstrcpy( tcTaskProperties.szRepeatEvery , GetResString(IDS_TASK_PROPERTY_NA) );
  815. lstrcpy( tcTaskProperties.szRepeatUntilTime , GetResString(IDS_TASK_PROPERTY_NA) );
  816. lstrcpy( tcTaskProperties.szRepeatDuration , GetResString(IDS_TASK_PROPERTY_NA) );
  817. lstrcpy( tcTaskProperties.szRepeatStop , GetResString(IDS_TASK_PROPERTY_NA) );
  818. }
  819. //Insert Task Type
  820. DynArraySetString2(pColData,iTaskCount,TASKTYPE_COL_NUMBER,
  821. tcTaskProperties.szTaskType, 0);
  822. //Insert start time
  823. DynArraySetString2(pColData,iTaskCount,STARTTIME_COL_NUMBER,
  824. tcTaskProperties.szTaskStartTime, 0);
  825. //Insert start Date
  826. DynArraySetString2(pColData,iTaskCount,STARTDATE_COL_NUMBER,
  827. tcTaskProperties.szTaskStartDate, 0);
  828. //Insert Task idle time
  829. if( lstrcmpi( tcTaskProperties.szTaskType , GetResString(IDS_TASK_IDLE) ) == 0 )
  830. {
  831. hr = pITask->GetIdleWait(&wIdleMinutes,&wDeadlineMinutes);
  832. if ( SUCCEEDED(hr))
  833. {
  834. FORMAT_STRING(szIdleTime,_T("%d"),wIdleMinutes);
  835. }
  836. else
  837. {
  838. lstrcpy( szIdleTime, GetResString(IDS_TASK_PROPERTY_NA) );
  839. }
  840. }
  841. //Insert Task End date
  842. DynArraySetString2(pColData,iTaskCount,ENDDATE_COL_NUMBER,
  843. tcTaskProperties.szTaskEndDate, 0);
  844. //Insert days value
  845. DynArraySetString2(pColData,iTaskCount,DAYS_COL_NUMBER,
  846. tcTaskProperties.szTaskDays,0);
  847. //Insert months value
  848. DynArraySetString2(pColData,iTaskCount,MONTHS_COL_NUMBER,
  849. tcTaskProperties.szTaskMonths, 0);
  850. //Insert repeat every time
  851. DynArraySetString2(pColData,iTaskCount, REPEAT_EVERY_COL_NUMBER ,
  852. tcTaskProperties.szRepeatEvery,0);
  853. //Insert repeat until time
  854. DynArraySetString2(pColData,iTaskCount,REPEAT_UNTILTIME_COL_NUMBER,
  855. tcTaskProperties.szRepeatUntilTime,0);
  856. //Insert repeat duration
  857. DynArraySetString2(pColData,iTaskCount,REPEAT_DURATION_COL_NUMBER,
  858. tcTaskProperties.szRepeatDuration,0);
  859. //Insert repeat stop if running
  860. DynArraySetString2(pColData,iTaskCount,REPEAT_STOP_COL_NUMBER,
  861. tcTaskProperties.szRepeatStop,0);
  862. }//end of bVerbose
  863. if( bMultiTriggers == TRUE)
  864. {
  865. iTaskCount++;
  866. }
  867. bNotScheduled = FALSE;
  868. }//end of Trigger FOR loop
  869. CoTaskMemFree(lpwszNames[dwArrTaskIndex]);
  870. if( bMultiTriggers == FALSE)
  871. iTaskCount++;
  872. CoTaskMemFree(lpwszNames);
  873. if( pITask )
  874. pITask->Release();
  875. }//End of the enumerating tasks
  876. if(pIEnum)
  877. pIEnum->Release();
  878. //if there are no tasks display msg.
  879. if(bTasksExists == FALSE)
  880. {
  881. DestroyDynamicArray(&pColData);
  882. DISPLAY_MESSAGE(stdout,GetResString(IDS_TASKNAME_NOTASKS));
  883. return S_OK;
  884. }
  885. DISPLAY_MESSAGE(stdout,_T("\n"));
  886. if( bVerbose == FALSE )
  887. {
  888. if ( dwFormatType == SR_FORMAT_LIST )
  889. {
  890. iArrSize = COL_SIZE_LIST; // for LIST non-verbose mode only 4 columns
  891. }
  892. else
  893. {
  894. iArrSize = COL_SIZE_VERBOSE; // for non-verbose mode only 3 columns
  895. }
  896. }
  897. if(bHeader)
  898. {
  899. if ( ( bVerbose == FALSE ) &&
  900. ( (dwFormatType == SR_FORMAT_TABLE) || (dwFormatType == SR_FORMAT_CSV) ) )
  901. {
  902. ShowResults(iArrSize,pNonVerboseCols,SR_HIDECOLUMN|dwFormatType,pColData);
  903. }
  904. else
  905. {
  906. ShowResults(iArrSize,pVerboseCols,SR_HIDECOLUMN|dwFormatType,pColData);
  907. }
  908. }
  909. else
  910. {
  911. if ( ( bVerbose == FALSE ) &&
  912. ( (dwFormatType == SR_FORMAT_TABLE) || (dwFormatType == SR_FORMAT_CSV) ) )
  913. {
  914. ShowResults(iArrSize,pNonVerboseCols,dwFormatType,pColData);
  915. }
  916. else
  917. {
  918. ShowResults(iArrSize,pVerboseCols,dwFormatType,pColData);
  919. }
  920. }
  921. DestroyDynamicArray(&pColData);
  922. return S_OK;
  923. }