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.

1489 lines
56 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(
  34. IN DWORD argc,
  35. IN LPCTSTR argv[]
  36. )
  37. {
  38. // Variables used to find whether Query main option or Usage option
  39. // specified or not
  40. BOOL bQuery = FALSE;
  41. BOOL bUsage = FALSE;
  42. BOOL bHeader = FALSE;
  43. BOOL bVerbose = FALSE;
  44. // Initialising the variables that are passed to TCMDPARSER structure
  45. LPWSTR szServer = NULL;
  46. LPWSTR szUser = NULL;
  47. LPWSTR szPassword = NULL;
  48. WCHAR szFormat [ MAX_STRING_LENGTH ] = L"\0";
  49. //Taskscheduler object to operate upon
  50. ITaskScheduler *pITaskScheduler = NULL;
  51. BOOL bNeedPassword = FALSE;
  52. BOOL bResult = FALSE;
  53. BOOL bCloseConnection = TRUE;
  54. TCMDPARSER2 cmdQueryOptions[MAX_QUERY_OPTIONS];
  55. BOOL bReturn = FALSE;
  56. // /query sub-options
  57. const WCHAR szQueryOpt[] = L"query";
  58. const WCHAR szQueryHelpOpt[] = L"?";
  59. const WCHAR szQueryServerOpt[] = L"s";
  60. const WCHAR szQueryUserOpt[] = L"u";
  61. const WCHAR szQueryPwdOpt[] = L"p";
  62. const WCHAR szQueryFormatOpt[] = L"fo";
  63. const WCHAR szQueryNoHeaderOpt[] = L"nh";
  64. const WCHAR szQueryVerboseOpt[] = L"v";
  65. const WCHAR szFormatValues[] = L"table|list|csv";
  66. // set all the fields to 0
  67. SecureZeroMemory( cmdQueryOptions, sizeof( TCMDPARSER2 ) * MAX_QUERY_OPTIONS );
  68. //
  69. // fill the commandline parser
  70. //
  71. // /delete option
  72. StringCopyA( cmdQueryOptions[ OI_QUERY_OPTION ].szSignature, "PARSER2\0", 8 );
  73. cmdQueryOptions[ OI_QUERY_OPTION ].dwType = CP_TYPE_BOOLEAN;
  74. cmdQueryOptions[ OI_QUERY_OPTION ].pwszOptions = szQueryOpt;
  75. cmdQueryOptions[ OI_QUERY_OPTION ].dwCount = 1;
  76. cmdQueryOptions[ OI_QUERY_OPTION ].dwFlags = 0;
  77. cmdQueryOptions[ OI_QUERY_OPTION ].pValue = &bQuery;
  78. // /? option
  79. StringCopyA( cmdQueryOptions[ OI_QUERY_USAGE ].szSignature, "PARSER2\0", 8 );
  80. cmdQueryOptions[ OI_QUERY_USAGE ].dwType = CP_TYPE_BOOLEAN;
  81. cmdQueryOptions[ OI_QUERY_USAGE ].pwszOptions = szQueryHelpOpt;
  82. cmdQueryOptions[ OI_QUERY_USAGE ].dwCount = 1;
  83. cmdQueryOptions[ OI_QUERY_USAGE ].dwFlags = CP2_USAGE;
  84. cmdQueryOptions[ OI_QUERY_USAGE ].pValue = &bUsage;
  85. // /s option
  86. StringCopyA( cmdQueryOptions[ OI_QUERY_SERVER ].szSignature, "PARSER2\0", 8 );
  87. cmdQueryOptions[ OI_QUERY_SERVER ].dwType = CP_TYPE_TEXT;
  88. cmdQueryOptions[ OI_QUERY_SERVER ].pwszOptions = szQueryServerOpt;
  89. cmdQueryOptions[ OI_QUERY_SERVER ].dwCount = 1;
  90. cmdQueryOptions[ OI_QUERY_SERVER ].dwFlags = CP2_ALLOCMEMORY| CP2_VALUE_TRIMINPUT|CP2_VALUE_NONULL ;
  91. // /u option
  92. StringCopyA( cmdQueryOptions[ OI_QUERY_USERNAME ].szSignature, "PARSER2\0", 8 );
  93. cmdQueryOptions[ OI_QUERY_USERNAME ].dwType = CP_TYPE_TEXT;
  94. cmdQueryOptions[ OI_QUERY_USERNAME ].pwszOptions = szQueryUserOpt;
  95. cmdQueryOptions[ OI_QUERY_USERNAME ].dwCount = 1;
  96. cmdQueryOptions[ OI_QUERY_USERNAME ].dwFlags = CP2_ALLOCMEMORY| CP2_VALUE_TRIMINPUT|CP2_VALUE_NONULL ;
  97. // /p option
  98. StringCopyA( cmdQueryOptions[ OI_QUERY_PASSWORD ].szSignature, "PARSER2\0", 8 );
  99. cmdQueryOptions[ OI_QUERY_PASSWORD ].dwType = CP_TYPE_TEXT;
  100. cmdQueryOptions[ OI_QUERY_PASSWORD ].pwszOptions = szQueryPwdOpt;
  101. cmdQueryOptions[ OI_QUERY_PASSWORD ].dwCount = 1;
  102. cmdQueryOptions[ OI_QUERY_PASSWORD ].dwActuals = 0;
  103. cmdQueryOptions[ OI_QUERY_PASSWORD ].dwFlags = CP2_ALLOCMEMORY | CP2_VALUE_OPTIONAL;
  104. // /fo option
  105. StringCopyA( cmdQueryOptions[ OI_QUERY_FORMAT ].szSignature, "PARSER2\0", 8 );
  106. cmdQueryOptions[ OI_QUERY_FORMAT ].dwType = CP_TYPE_TEXT;
  107. cmdQueryOptions[ OI_QUERY_FORMAT ].pwszOptions = szQueryFormatOpt;
  108. cmdQueryOptions[ OI_QUERY_FORMAT ].dwCount = 1;
  109. cmdQueryOptions[ OI_QUERY_FORMAT ].dwFlags = CP2_MODE_VALUES| CP2_VALUE_TRIMINPUT| CP2_VALUE_NONULL;
  110. cmdQueryOptions[ OI_QUERY_FORMAT ].pwszValues = szFormatValues;
  111. cmdQueryOptions[ OI_QUERY_FORMAT ].pValue = szFormat;
  112. cmdQueryOptions[ OI_QUERY_FORMAT ].dwLength = MAX_STRING_LENGTH;
  113. // /nh option
  114. StringCopyA( cmdQueryOptions[ OI_QUERY_NOHEADER ].szSignature, "PARSER2\0", 8 );
  115. cmdQueryOptions[ OI_QUERY_NOHEADER ].dwType = CP_TYPE_BOOLEAN;
  116. cmdQueryOptions[ OI_QUERY_NOHEADER ].pwszOptions = szQueryNoHeaderOpt;
  117. cmdQueryOptions[ OI_QUERY_NOHEADER ].dwCount = 1;
  118. cmdQueryOptions[ OI_QUERY_NOHEADER ].dwFlags = 0;
  119. cmdQueryOptions[ OI_QUERY_NOHEADER ].pValue = &bHeader;
  120. // /v option
  121. StringCopyA( cmdQueryOptions[ OI_QUERY_VERBOSE ].szSignature, "PARSER2\0", 8 );
  122. cmdQueryOptions[ OI_QUERY_VERBOSE ].dwType = CP_TYPE_BOOLEAN;
  123. cmdQueryOptions[ OI_QUERY_VERBOSE ].pwszOptions = szQueryVerboseOpt;
  124. cmdQueryOptions[ OI_QUERY_VERBOSE ].dwCount = 1;
  125. cmdQueryOptions[ OI_QUERY_VERBOSE ].dwFlags = 0;
  126. cmdQueryOptions[ OI_QUERY_VERBOSE ].pValue = &bVerbose;
  127. //parse command line arguments
  128. bReturn = DoParseParam2( argc, argv, 0, SIZE_OF_ARRAY(cmdQueryOptions), cmdQueryOptions, 0);
  129. if( FALSE == bReturn) // Invalid commandline
  130. {
  131. //display an error message
  132. ShowLastErrorEx ( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  133. ReleaseGlobals();
  134. return EXIT_FAILURE;
  135. }
  136. // get the buffer pointers allocated by command line parser
  137. szServer = (LPWSTR)cmdQueryOptions[ OI_QUERY_SERVER ].pValue;
  138. szUser = (LPWSTR)cmdQueryOptions[ OI_QUERY_USERNAME ].pValue;
  139. szPassword = (LPWSTR)cmdQueryOptions[ OI_QUERY_PASSWORD ].pValue;
  140. if ( (argc > 3) && (bUsage == TRUE) )
  141. {
  142. ShowMessage ( stderr, GetResString (IDS_ERROR_QUERYPARAM) );
  143. FreeMemory((LPVOID*) &szServer);
  144. FreeMemory((LPVOID*) &szUser);
  145. FreeMemory((LPVOID*) &szPassword);
  146. return EXIT_FAILURE;
  147. }
  148. // Displaying query usage if user specified -? with -query option
  149. if( bUsage == TRUE)
  150. {
  151. DisplayQueryUsage();
  152. FreeMemory((LPVOID*) &szServer);
  153. FreeMemory((LPVOID*) &szUser);
  154. FreeMemory((LPVOID*) &szPassword);
  155. return EXIT_SUCCESS;
  156. }
  157. if ( cmdQueryOptions[ OI_QUERY_USERNAME ].dwActuals == 0 && cmdQueryOptions[OI_QUERY_PASSWORD].dwActuals == 1 )
  158. {
  159. // invalid syntax
  160. ShowMessage(stderr, GetResString(IDS_QPASSWORD_BUT_NOUSERNAME));
  161. FreeMemory((LPVOID*) &szServer);
  162. FreeMemory((LPVOID*) &szUser);
  163. FreeMemory((LPVOID*) &szPassword);
  164. return RETVAL_FAIL;
  165. }
  166. // check for invalid user name
  167. if( ( cmdQueryOptions[OI_QUERY_SERVER].dwActuals == 0 ) && ( cmdQueryOptions[OI_QUERY_USERNAME].dwActuals == 1 ) )
  168. {
  169. ShowMessage(stderr, GetResString(IDS_QUERY_USER_BUT_NOMACHINE));
  170. FreeMemory((LPVOID*) &szServer);
  171. FreeMemory((LPVOID*) &szUser);
  172. FreeMemory((LPVOID*) &szPassword);
  173. return RETVAL_FAIL;
  174. }
  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 whether the password (-p) specified in the command line or not
  178. // and also check whether '*' or empty is given for -p or not
  179. // check whether the password (-p) specified in the command line or not
  180. // and also check whether '*' or empty is given for -p or not
  181. // check the remote connectivity information
  182. if ( szServer != NULL )
  183. {
  184. //
  185. // if -u is not specified, we need to allocate memory
  186. // in order to be able to retrive the current user name
  187. //
  188. // case 1: -p is not at all specified
  189. // as the value for this switch is optional, we have to rely
  190. // on the dwActuals to determine whether the switch is specified or not
  191. // in this case utility needs to try to connect first and if it fails
  192. // then prompt for the password -- in fact, we need not check for this
  193. // condition explicitly except for noting that we need to prompt for the
  194. // password
  195. //
  196. // case 2: -p is specified
  197. // but we need to check whether the value is specified or not
  198. // in this case user wants the utility to prompt for the password
  199. // before trying to connect
  200. //
  201. // case 3: -p * is specified
  202. // user name
  203. if ( szUser == NULL )
  204. {
  205. szUser = (LPWSTR) AllocateMemory( MAX_STRING_LENGTH * sizeof( WCHAR ) );
  206. if ( szUser == NULL )
  207. {
  208. SaveLastError();
  209. FreeMemory((LPVOID*) &szServer);
  210. FreeMemory((LPVOID*) &szUser);
  211. FreeMemory((LPVOID*) &szPassword);
  212. return RETVAL_FAIL;
  213. }
  214. }
  215. // password
  216. if ( szPassword == NULL )
  217. {
  218. bNeedPassword = TRUE;
  219. szPassword = (LPWSTR)AllocateMemory( MAX_STRING_LENGTH * sizeof( WCHAR ) );
  220. if ( szPassword == NULL )
  221. {
  222. SaveLastError();
  223. FreeMemory((LPVOID*) &szServer);
  224. FreeMemory((LPVOID*) &szUser);
  225. FreeMemory((LPVOID*) &szPassword);
  226. return RETVAL_FAIL;
  227. }
  228. }
  229. // case 1
  230. if ( cmdQueryOptions[ OI_QUERY_PASSWORD ].dwActuals == 0 )
  231. {
  232. // we need not do anything special here
  233. }
  234. // case 2
  235. else if ( cmdQueryOptions[ OI_QUERY_PASSWORD ].pValue == NULL )
  236. {
  237. StringCopy( szPassword, L"*", GetBufferSize(szPassword)/sizeof(WCHAR));
  238. }
  239. // case 3
  240. else if ( StringCompareEx( szPassword, L"*", TRUE, 0 ) == 0 )
  241. {
  242. if ( ReallocateMemory( (LPVOID*)&szPassword,
  243. MAX_STRING_LENGTH * sizeof( WCHAR ) ) == FALSE )
  244. {
  245. SaveLastError();
  246. FreeMemory((LPVOID*) &szServer);
  247. FreeMemory((LPVOID*) &szUser);
  248. FreeMemory((LPVOID*) &szPassword);
  249. return RETVAL_FAIL;
  250. }
  251. // ...
  252. bNeedPassword = TRUE;
  253. }
  254. }
  255. DWORD dwFormatType = SR_FORMAT_TABLE;//default format type(TABLE Format)
  256. BOOL bNoHeader = TRUE; // For LIST format type -nh switch is not applicable
  257. DWORD dwCheck = 0;
  258. //Determine the Format for display & check for error if any in format type
  259. if( StringCompare( szFormat , GetResString(IDS_QUERY_FORMAT_LIST), TRUE, 0 ) == 0 )
  260. {
  261. dwFormatType = SR_FORMAT_LIST;
  262. bNoHeader = FALSE;
  263. }
  264. else if( StringCompare( szFormat , GetResString(IDS_QUERY_FORMAT_CSV), TRUE, 0 ) == 0 )
  265. {
  266. dwFormatType = SR_FORMAT_CSV;
  267. }
  268. else
  269. {
  270. dwFormatType = SR_FORMAT_TABLE;
  271. }
  272. //If -n is specified for LIST or CSV then report error
  273. if( ( bNoHeader == FALSE ) && ( bHeader == TRUE ))
  274. {
  275. ShowMessage( stderr , GetResString(IDS_NOHEADER_NA ));
  276. FreeMemory((LPVOID*) &szServer);
  277. FreeMemory((LPVOID*) &szUser);
  278. FreeMemory((LPVOID*) &szPassword);
  279. return EXIT_FAILURE;
  280. }
  281. if( ( IsLocalSystem( szServer ) == FALSE ) || ( cmdQueryOptions[OI_QUERY_USERNAME].dwActuals == 1 ) )
  282. {
  283. // Establish the connection on a remote machine
  284. bResult = EstablishConnection(szServer,szUser,GetBufferSize(szUser)/sizeof(WCHAR),szPassword,GetBufferSize(szPassword)/sizeof(WCHAR), bNeedPassword );
  285. if (bResult == FALSE)
  286. {
  287. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  288. //ShowMessage( stderr, GetResString(IDS_ERROR_STRING) );
  289. //ShowMessage( stderr, GetReason());
  290. FreeMemory((LPVOID*) &szServer);
  291. FreeMemory((LPVOID*) &szUser);
  292. FreeMemory((LPVOID*) &szPassword);
  293. return EXIT_FAILURE ;
  294. }
  295. else
  296. {
  297. // though the connection is successfull, some conflict might have occured
  298. switch( GetLastError() )
  299. {
  300. case I_NO_CLOSE_CONNECTION:
  301. bCloseConnection = FALSE;
  302. break;
  303. case E_LOCAL_CREDENTIALS:
  304. case ERROR_SESSION_CREDENTIAL_CONFLICT:
  305. {
  306. bCloseConnection = FALSE;
  307. ShowMessage( stderr, GetResString(IDS_ERROR_STRING) );
  308. ShowMessage( stderr, GetReason());
  309. FreeMemory((LPVOID*) &szServer);
  310. FreeMemory((LPVOID*) &szUser);
  311. FreeMemory((LPVOID*) &szPassword);
  312. return EXIT_FAILURE;
  313. }
  314. default :
  315. bCloseConnection = TRUE;
  316. }
  317. }
  318. //release memory for password
  319. FreeMemory((LPVOID*) &szPassword);
  320. }
  321. //Fetch the TaskScheduler Interface to operate on
  322. pITaskScheduler = GetTaskScheduler( szServer );
  323. if(pITaskScheduler == NULL)
  324. {
  325. // close the connection that was established by the utility
  326. if ( bCloseConnection == TRUE )
  327. CloseConnection( szServer );
  328. Cleanup(pITaskScheduler);
  329. FreeMemory((LPVOID*) &szServer);
  330. FreeMemory((LPVOID*) &szUser);
  331. FreeMemory((LPVOID*) &szPassword);
  332. return EXIT_FAILURE;
  333. }
  334. // check whether the task scheduler service is running or not.
  335. if ( TRUE == CheckServiceStatus(szServer, &dwCheck, FALSE) )
  336. {
  337. ShowMessage ( stderr, GetResString (IDS_SERVICE_NOT_RUNNING) );
  338. }
  339. //Display the tasks & its properties in the user specified format
  340. HRESULT hr = DisplayTasks(pITaskScheduler,bVerbose,dwFormatType,bHeader);
  341. if(FAILED(hr))
  342. {
  343. // close the connection that was established by the utility
  344. if ( bCloseConnection == TRUE )
  345. CloseConnection( szServer );
  346. Cleanup(pITaskScheduler);
  347. FreeMemory((LPVOID*) &szServer);
  348. FreeMemory((LPVOID*) &szUser);
  349. FreeMemory((LPVOID*) &szPassword);
  350. return EXIT_FAILURE;
  351. }
  352. // close the connection that was established by the utility
  353. if ( bCloseConnection == TRUE )
  354. CloseConnection( szServer );
  355. Cleanup(pITaskScheduler);
  356. FreeMemory((LPVOID*) &szServer);
  357. FreeMemory((LPVOID*) &szUser);
  358. FreeMemory((LPVOID*) &szPassword);
  359. return EXIT_SUCCESS;
  360. }
  361. /******************************************************************************
  362. Routine Description:
  363. This function displays the usage of -query option.
  364. Arguments:
  365. None
  366. Return Value :
  367. VOID
  368. ******************************************************************************/
  369. VOID
  370. DisplayQueryUsage()
  371. {
  372. // Display the usage of -query option
  373. DisplayUsage( IDS_QUERY_HLP1, IDS_QUERY_HLP25);
  374. }
  375. /******************************************************************************
  376. Routine Description:
  377. This function retrieves the tasks present in the system & displays according to
  378. the user specified format.
  379. Arguments:
  380. [ in ] pITaskScheduler : Pointer to the ITaskScheduler Interface
  381. [ in ] bVerbose : flag indicating whether the out is to be filtered.
  382. [ in ] dwFormatType : Format type[TABLE,LIST,CSV etc]
  383. [ in ] bHeader : Whether the header should be displayed in the output
  384. Return Value :
  385. A HRESULT value indicating success code else failure code
  386. ******************************************************************************/
  387. HRESULT
  388. DisplayTasks(ITaskScheduler* pITaskScheduler,BOOL bVerbose,DWORD dwFormatType,
  389. BOOL bHeader)
  390. {
  391. //declarations
  392. LPWSTR lpwszComputerName = NULL;
  393. HRESULT hr = S_OK;
  394. WCHAR szServerName[MAX_STRING_LENGTH] = L"\0";
  395. WCHAR szResolvedServerName[MAX_STRING_LENGTH] = L"\0";
  396. LPWSTR lpszTemp = NULL;
  397. DWORD dwResolvedServerLen = 0;
  398. StringCopy( szServerName , GetResString(IDS_TASK_PROPERTY_NA), SIZE_OF_ARRAY(szServerName));
  399. //Retrieve the name of the computer on which TaskScheduler is operated
  400. hr = pITaskScheduler->GetTargetComputer(&lpwszComputerName);
  401. if( SUCCEEDED( hr ) )
  402. {
  403. lpszTemp = lpwszComputerName;
  404. //Remove the backslash[\\] from the computer name
  405. lpwszComputerName = _wcsspnp( lpwszComputerName , L"\\" );
  406. if ( lpwszComputerName == NULL )
  407. {
  408. ShowMessage(stderr,GetResString(IDS_CREATE_READERROR));
  409. CoTaskMemFree(lpszTemp);
  410. return S_FALSE;
  411. }
  412. StringCopy (szServerName, lpwszComputerName, SIZE_OF_ARRAY(szServerName) );
  413. CoTaskMemFree(lpszTemp);
  414. dwResolvedServerLen = SIZE_OF_ARRAY(szResolvedServerName);
  415. if ( IsValidIPAddress( szServerName ) == TRUE )
  416. {
  417. if( TRUE == GetHostByIPAddr( szServerName, szResolvedServerName , &dwResolvedServerLen, FALSE ) )
  418. {
  419. StringCopy( szServerName , szResolvedServerName, SIZE_OF_ARRAY(szServerName) );
  420. }
  421. else
  422. {
  423. StringCopy( szServerName , GetResString(IDS_TASK_PROPERTY_NA), SIZE_OF_ARRAY(szServerName));
  424. }
  425. }
  426. }
  427. //Initialize the TCOLUMNS structure array
  428. TCOLUMNS pVerboseCols[] =
  429. {
  430. {L"\0",WIDTH_HOSTNAME, SR_TYPE_STRING, COL_FORMAT_STRING, NULL, NULL},
  431. {L"\0",WIDTH_TASKNAME,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  432. {L"\0",WIDTH_NEXTRUNTIME,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  433. {L"\0",WIDTH_STATUS,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  434. {L"\0",WIDTH_MODE,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  435. {L"\0",WIDTH_LASTRUNTIME,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  436. {L"\0",WIDTH_LASTRESULT,SR_TYPE_NUMERIC|SR_VALUEFORMAT,COL_FORMAT_HEX,NULL,NULL},
  437. {L"\0",WIDTH_CREATOR,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  438. {L"\0",WIDTH_SCHEDULE,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  439. {L"\0",WIDTH_APPNAME,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  440. {L"\0",WIDTH_WORKDIRECTORY,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  441. {L"\0",WIDTH_COMMENT,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  442. {L"\0",WIDTH_TASKSTATE,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  443. {L"\0",WIDTH_TASKTYPE,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  444. {L"\0",WIDTH_TASKSTIME,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  445. {L"\0",WIDTH_TASKSDATE,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  446. {L"\0",WIDTH_TASKEDATE,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  447. {L"\0",WIDTH_TASKDAYS,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  448. {L"\0",WIDTH_TASKMONTHS,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  449. {L"\0",WIDTH_TASKRUNASUSER,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  450. {L"\0",WIDTH_TASKDELETE,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  451. {L"\0",WIDTH_TASKSTOP,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  452. {L"\0",WIDTH_TASK_RPTEVERY,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  453. {L"\0",WIDTH_TASK_UNTILRPTTIME,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  454. {L"\0",WIDTH_TASK_RPTDURATION,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  455. {L"\0",WIDTH_TASK_RPTRUNNING,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  456. {L"\0",WIDTH_TASKIDLE,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  457. {L"\0",WIDTH_TASKPOWER,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL}
  458. };
  459. TCOLUMNS pNonVerboseCols[] =
  460. {
  461. {L"\0",WIDTH_TASKNAME,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  462. {L"\0",WIDTH_NEXTRUNTIME,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL},
  463. {L"\0",WIDTH_STATUS,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL}
  464. };
  465. DWORD dwColCount = 0;
  466. int j = 0;
  467. //Load the column names for non verbose mode
  468. if ( (dwFormatType == SR_FORMAT_TABLE) || (dwFormatType == SR_FORMAT_CSV) )
  469. {
  470. for( dwColCount = IDS_COL_TASKNAME , j = 0 ; dwColCount <= IDS_COL_STATUS;
  471. dwColCount++,j++)
  472. {
  473. StringCopy(pNonVerboseCols[j].szColumn ,GetResString(dwColCount), MAX_RES_STRING);
  474. }
  475. }
  476. //Load the column names for verbose mode
  477. for( dwColCount = IDS_COL_HOSTNAME , j = 0 ; dwColCount <= IDS_COL_POWER;
  478. dwColCount++,j++)
  479. {
  480. StringCopy(pVerboseCols[j].szColumn ,GetResString(dwColCount), MAX_RES_STRING);
  481. }
  482. TARRAY pColData = CreateDynamicArray();
  483. if ( NULL == pColData )
  484. {
  485. return S_FALSE;
  486. }
  487. size_t iArrSize = SIZE_OF_ARRAY( pVerboseCols );
  488. //latest declarations
  489. WCHAR szTaskProperty[MAX_STRING_LENGTH] = L"\0";
  490. WCHAR szScheduleName[MAX_STRING_LENGTH] = L"\0";
  491. WCHAR szMessage[MAX_STRING_LENGTH] = L"\0";
  492. WCHAR szBuffer[MAX_STRING_LENGTH] = L"\0";
  493. WCHAR szTmpBuf[MAX_STRING_LENGTH] = L"\0";
  494. ITask *pITask = NULL;//ITask interface
  495. DWORD dwExitCode = 0;
  496. LPWSTR* lpwszNames = NULL;
  497. DWORD dwFetchedTasks = 0;
  498. int iTaskCount = 0;
  499. BOOL bTasksExists = FALSE;
  500. WCHAR szTime[MAX_DATETIME_LEN] = L"\0";
  501. WCHAR szDate[MAX_DATETIME_LEN] = L"\0";
  502. WCHAR szMode[MAX_STRING_LENGTH] = L"\0";
  503. //Index to the array of task names
  504. DWORD dwArrTaskIndex = 0;
  505. WORD wIdleMinutes = 0;
  506. WORD wDeadlineMinutes = 0 ;
  507. WCHAR szIdleTime[MAX_STRING_LENGTH] = L"\0";
  508. WCHAR szIdleRetryTime[MAX_STRING_LENGTH] = L"\0";
  509. WCHAR szTaskName[MAX_STRING_LENGTH] = L"\0";
  510. TASKPROPS tcTaskProperties;
  511. WCHAR* szValues[1] = {NULL};//for holding values of parameters in FormatMessage()
  512. BOOL bOnBattery = FALSE;
  513. BOOL bStopTask = FALSE;
  514. BOOL bNotScheduled = FALSE;
  515. DWORD dwNoTasks = 0;
  516. IEnumWorkItems *pIEnum = NULL;
  517. hr = pITaskScheduler->Enum(&pIEnum);//Get the IEnumWorkItems Interface
  518. if (FAILED(hr))
  519. {
  520. ShowMessage(stderr,GetResString(IDS_CREATE_READERROR));
  521. if( pIEnum )
  522. pIEnum->Release();
  523. return hr;
  524. }
  525. while (SUCCEEDED(pIEnum->Next(TASKS_TO_RETRIEVE,
  526. &lpwszNames,
  527. &dwFetchedTasks))
  528. && (dwFetchedTasks != 0))
  529. {
  530. bTasksExists = TRUE;
  531. dwArrTaskIndex = dwFetchedTasks - 1;
  532. StringCopy(szTaskName, lpwszNames[dwArrTaskIndex], SIZE_OF_ARRAY(szTaskName));
  533. if(szTaskName != NULL)
  534. {
  535. //remove the .job extension from the task name
  536. if (ParseTaskName(szTaskName))
  537. {
  538. CoTaskMemFree(lpwszNames[dwArrTaskIndex]);
  539. if(pIEnum)
  540. pIEnum->Release();
  541. if(pITask)
  542. pITask->Release();
  543. return S_FALSE;
  544. }
  545. }
  546. // return an pITask inteface for wszJobName
  547. hr = pITaskScheduler->Activate(lpwszNames[dwArrTaskIndex],IID_ITask,
  548. (IUnknown**) &pITask);
  549. //case 1:
  550. // check whether the specified scheduled task is created under
  551. // some other user. If so, ignore the respective task and
  552. // continue to retrieve other tasks in the system.
  553. // If the taskname created under some other user return value
  554. // of above API must 0x80070005.
  555. //case 2:
  556. // check whether the respective .job file in %windir%\tasks\***.job is corrupted
  557. //or not. if corrupted, the above function fails and return the value
  558. // SCHED_E_UNKNOWN_OBJECT_VERSION.
  559. if (hr == 0x80070005 || hr == 0x8007000D || hr == SCHED_E_UNKNOWN_OBJECT_VERSION || hr == E_INVALIDARG )
  560. {
  561. // check whether tasks are zero or not
  562. if ( dwNoTasks == 0 )
  563. {
  564. bTasksExists = FALSE;
  565. }
  566. // continue to retrieve other tasks
  567. continue;
  568. }
  569. else
  570. {
  571. // count the number of tasks which are accessible under logged-on
  572. // user
  573. ++dwNoTasks;
  574. }
  575. if ( ( FAILED(hr) ) || (pITask == NULL) )
  576. {
  577. SetLastError ((DWORD) hr);
  578. ShowLastErrorEx ( stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
  579. CoTaskMemFree(lpwszNames[dwArrTaskIndex]);
  580. if(pIEnum)
  581. pIEnum->Release();
  582. if(pITask)
  583. pITask->Release();
  584. return hr;
  585. }
  586. WORD wTriggerCount = 0;
  587. BOOL bMultiTriggers = FALSE;
  588. DWORD dwTaskFlags = 0;
  589. BOOL bInteractive = FALSE;
  590. hr = pITask->GetTriggerCount( &wTriggerCount );
  591. if ( FAILED(hr) )
  592. {
  593. SetLastError ((DWORD) hr);
  594. ShowLastErrorEx ( stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
  595. CoTaskMemFree(lpwszNames[dwArrTaskIndex]);
  596. if(pIEnum)
  597. pIEnum->Release();
  598. if(pITask)
  599. pITask->Release();
  600. return hr;
  601. }
  602. // check for multiple triggers
  603. if( wTriggerCount > 1)
  604. {
  605. bMultiTriggers = TRUE;
  606. }
  607. // check for not scheduled tasks
  608. if ( wTriggerCount == 0 )
  609. {
  610. bNotScheduled = TRUE;
  611. }
  612. for( WORD wCurrentTrigger = 0; ( bNotScheduled == TRUE ) || ( wCurrentTrigger < wTriggerCount );
  613. wCurrentTrigger++ )
  614. {
  615. //Start appending to the 2D array
  616. DynArrayAppendRow(pColData,(DWORD)iArrSize);
  617. // For LIST format
  618. if ( ( bVerbose == TRUE ) || (dwFormatType == SR_FORMAT_LIST ))
  619. {
  620. //Insert the server name
  621. DynArraySetString2(pColData,iTaskCount,HOSTNAME_COL_NUMBER,szServerName,0);
  622. }
  623. // For TABLE and CSV formats
  624. if ( ( bVerbose == FALSE ) && ( (dwFormatType == SR_FORMAT_TABLE) ||
  625. (dwFormatType == SR_FORMAT_CSV) ) )
  626. {
  627. DWORD dwTaskColNumber = TASKNAME_COL_NUMBER - 1;
  628. //Insert the task name for TABLE or CSV
  629. DynArraySetString2(pColData,iTaskCount,dwTaskColNumber,szTaskName,0);
  630. }
  631. else
  632. {
  633. //Insert the task name for verbose mode
  634. DynArraySetString2(pColData,iTaskCount,TASKNAME_COL_NUMBER,szTaskName,0);
  635. }
  636. StringCopy(szTime,L"\0", SIZE_OF_ARRAY(szTime));
  637. StringCopy(szDate,L"\0", SIZE_OF_ARRAY(szDate));
  638. // display the mode whether the system is running interactively under system
  639. // account or not
  640. hr = pITask->GetFlags(&dwTaskFlags);
  641. if ( FAILED(hr) )
  642. {
  643. SetLastError ((DWORD) hr);
  644. ShowLastErrorEx ( stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
  645. CoTaskMemFree(lpwszNames[dwArrTaskIndex]);
  646. if(pIEnum)
  647. pIEnum->Release();
  648. if(pITask)
  649. pITask->Release();
  650. return hr;
  651. }
  652. //find the next run time of the task
  653. hr = GetTaskRunTime(pITask,szTime,szDate,TASK_NEXT_RUNTIME,wCurrentTrigger);
  654. if (FAILED(hr))
  655. {
  656. StringCopy( szTaskProperty , GetResString(IDS_TASK_NEVER), SIZE_OF_ARRAY(szTaskProperty) );
  657. }
  658. else
  659. {
  660. if(StringCompare( szDate , GetResString( IDS_TASK_IDLE ), TRUE, 0 ) == 0 ||
  661. StringCompare( szDate , GetResString( IDS_TASK_SYSSTART ), TRUE, 0) == 0 ||
  662. StringCompare( szDate , GetResString( IDS_TASK_LOGON ), TRUE, 0) == 0 ||
  663. StringCompare( szDate , GetResString( IDS_TASK_NEVER ), TRUE, 0) == 0 )
  664. {
  665. StringCopy( szTaskProperty , szDate, SIZE_OF_ARRAY(szTaskProperty) );
  666. }
  667. else
  668. {
  669. StringCopy( szTaskProperty , szTime, SIZE_OF_ARRAY(szTaskProperty) );
  670. StringConcat( szTaskProperty , TIME_DATE_SEPERATOR, SIZE_OF_ARRAY(szTaskProperty));
  671. StringConcat( szTaskProperty , szDate, SIZE_OF_ARRAY(szTaskProperty));
  672. }
  673. }
  674. // check if task is already been disabled or not
  675. if ( (dwTaskFlags & TASK_FLAG_DISABLED) == TASK_FLAG_DISABLED )
  676. {
  677. StringCopy( szTaskProperty , GetResString(IDS_TASK_PROPERTY_DISABLED), SIZE_OF_ARRAY(szTaskProperty) );
  678. }
  679. if ( ( bVerbose == FALSE ) && ( (dwFormatType == SR_FORMAT_TABLE) ||
  680. (dwFormatType == SR_FORMAT_CSV) ) )
  681. {
  682. DWORD dwNextRunTime = NEXTRUNTIME_COL_NUMBER - 1;
  683. //Insert the task name for TABLE or CSV
  684. DynArraySetString2(pColData,iTaskCount,dwNextRunTime,szTaskProperty,0);
  685. }
  686. else
  687. {
  688. //Insert the Next run time of the task
  689. DynArraySetString2(pColData,iTaskCount,NEXTRUNTIME_COL_NUMBER,szTaskProperty,0);
  690. }
  691. //retrieve the status code
  692. hr = GetStatusCode(pITask,szTaskProperty);
  693. if (FAILED(hr))
  694. {
  695. StringCopy( szTaskProperty , GetResString(IDS_TASK_PROPERTY_NA), SIZE_OF_ARRAY(szTaskProperty) );
  696. }
  697. if ( ( bVerbose == FALSE ) && ( (dwFormatType == SR_FORMAT_TABLE) ||
  698. (dwFormatType == SR_FORMAT_CSV) ) )
  699. {
  700. DWORD dwStatusColNum = STATUS_COL_NUMBER - 1;
  701. //Insert the task name for TABLE or CSV
  702. DynArraySetString2(pColData,iTaskCount,dwStatusColNum,szTaskProperty,0);
  703. }
  704. else
  705. {
  706. //Insert the status string
  707. DynArraySetString2(pColData,iTaskCount,STATUS_COL_NUMBER,szTaskProperty,0);
  708. }
  709. if ( dwTaskFlags & TASK_FLAG_RUN_ONLY_IF_LOGGED_ON )
  710. {
  711. bInteractive = TRUE;
  712. }
  713. if( bVerbose) //If V [verbose mode is present ,show all other columns]
  714. {
  715. StringCopy(szTime,L"\0", SIZE_OF_ARRAY(szTime));
  716. StringCopy(szDate,L"\0", SIZE_OF_ARRAY(szDate));
  717. //Insert the server name
  718. //DynArraySetString2(pColData,iTaskCount,HOSTNAME_COL_NUMBER,szServerName,0);
  719. //find the last run time of the task
  720. hr = GetTaskRunTime(pITask,szTime,szDate,TASK_LAST_RUNTIME,wCurrentTrigger);
  721. if (FAILED(hr))
  722. {
  723. StringCopy( szTaskProperty , GetResString(IDS_TASK_NEVER), SIZE_OF_ARRAY(szTaskProperty) );
  724. }
  725. else
  726. {
  727. if(StringCompare( szDate , GetResString( IDS_TASK_IDLE ), TRUE, 0 ) == 0 ||
  728. StringCompare( szDate , GetResString( IDS_TASK_SYSSTART ), TRUE, 0) == 0 ||
  729. StringCompare( szDate , GetResString( IDS_TASK_LOGON ), TRUE, 0) == 0 ||
  730. StringCompare( szDate , GetResString( IDS_TASK_NEVER ), TRUE, 0) == 0 )
  731. {
  732. StringCopy( szTaskProperty , szDate, SIZE_OF_ARRAY(szTaskProperty));
  733. }
  734. else
  735. {
  736. StringCopy( szTaskProperty , szTime, SIZE_OF_ARRAY(szTaskProperty) );
  737. StringConcat( szTaskProperty , TIME_DATE_SEPERATOR, SIZE_OF_ARRAY(szTaskProperty));
  738. StringConcat( szTaskProperty , szDate, SIZE_OF_ARRAY(szTaskProperty));
  739. }
  740. }
  741. //Insert the task last run time
  742. DynArraySetString2(pColData,iTaskCount,LASTRUNTIME_COL_NUMBER,szTaskProperty,0);
  743. //retrieve the exit code
  744. pITask->GetExitCode(&dwExitCode);
  745. //Insert the Exit code
  746. DynArraySetDWORD2(pColData,iTaskCount,LASTRESULT_COL_NUMBER,dwExitCode);
  747. // Get the creator name for the task
  748. hr = GetCreator(pITask,szTaskProperty);
  749. if (FAILED(hr))
  750. {
  751. StringCopy( szTaskProperty , GetResString(IDS_TASK_PROPERTY_NA), SIZE_OF_ARRAY(szTaskProperty) );
  752. }
  753. if( StringCompare( szTaskProperty , L"\0", TRUE, 0 ) == 0 )
  754. {
  755. StringCopy( szTaskProperty , GetResString(IDS_QUERY_NA), SIZE_OF_ARRAY(szTaskProperty) );
  756. }
  757. //insert the creator name to 2D array
  758. DynArraySetString2(pColData,iTaskCount,CREATOR_COL_NUMBER,szTaskProperty,0);
  759. //retrieve the Trigger string
  760. hr = GetTriggerString(pITask,szTaskProperty,wCurrentTrigger);
  761. if (FAILED(hr))
  762. {
  763. StringCopy( szTaskProperty , GetResString(IDS_NOTSCHEDULED_TASK), SIZE_OF_ARRAY(szTaskProperty) );
  764. }
  765. // check if task is already been disabled or not
  766. if ( (dwTaskFlags & TASK_FLAG_DISABLED) == TASK_FLAG_DISABLED )
  767. {
  768. StringCopy( szTaskProperty , GetResString(IDS_TASK_PROPERTY_DISABLED), SIZE_OF_ARRAY(szTaskProperty) );
  769. }
  770. else
  771. {
  772. StringCopy(szScheduleName, szTaskProperty, SIZE_OF_ARRAY(szScheduleName));
  773. }
  774. //Insert the trigger string
  775. DynArraySetString2(pColData,iTaskCount,SCHEDULE_COL_NUMBER,szTaskProperty,0);
  776. //Get the application path associated with the task
  777. hr = GetApplicationToRun(pITask,szTaskProperty);
  778. if (FAILED(hr))
  779. {
  780. StringCopy( szTaskProperty , GetResString(IDS_TASK_PROPERTY_NA), SIZE_OF_ARRAY(szTaskProperty) );
  781. }
  782. if( StringCompare( szTaskProperty , L"\0", TRUE, 0 ) == 0 )
  783. {
  784. StringCopy( szTaskProperty , GetResString(IDS_QUERY_NA), SIZE_OF_ARRAY(szTaskProperty) );
  785. }
  786. //Insert the application associated with task
  787. DynArraySetString2(pColData,iTaskCount,TASKTORUN_COL_NUMBER,szTaskProperty,0);
  788. //Get the working directory of the task's associated application
  789. hr = GetWorkingDirectory(pITask,szTaskProperty);
  790. if (FAILED(hr))
  791. {
  792. StringCopy( szTaskProperty , GetResString(IDS_TASK_PROPERTY_NA), SIZE_OF_ARRAY(szTaskProperty) );
  793. }
  794. if( StringCompare( szTaskProperty , L"\0", TRUE, 0 ) == 0 )
  795. {
  796. StringCopy( szTaskProperty , GetResString(IDS_QUERY_NA), SIZE_OF_ARRAY(szTaskProperty) );
  797. }
  798. //Insert the app.working directory
  799. DynArraySetString2(pColData,iTaskCount,STARTIN_COL_NUMBER,szTaskProperty,0);
  800. //Get the comment name associated with the task
  801. hr = GetComment(pITask,szTaskProperty);
  802. if (FAILED(hr))
  803. {
  804. StringCopy( szTaskProperty , GetResString(IDS_TASK_PROPERTY_NA), SIZE_OF_ARRAY(szTaskProperty) );
  805. }
  806. //Insert the comment name
  807. if( StringCompare( szTaskProperty , L"\0", TRUE, 0 ) == 0 )
  808. {
  809. StringCopy( szTaskProperty , GetResString(IDS_QUERY_NA), SIZE_OF_ARRAY(szTaskProperty) );
  810. }
  811. DynArraySetString2(pColData,iTaskCount,COMMENT_COL_NUMBER,szTaskProperty,0);
  812. //Determine the task state properties
  813. //Determine the TASK_FLAG_DISABLED
  814. hr = GetTaskState(pITask,szTaskProperty,TASK_FLAG_DISABLED);
  815. if (FAILED(hr))
  816. {
  817. StringCopy( szTaskProperty , GetResString(IDS_TASK_PROPERTY_NA), SIZE_OF_ARRAY(szTaskProperty) );
  818. }
  819. //Insert the TASK_FLAG_DISABLED state
  820. DynArraySetString2(pColData,iTaskCount,TASKSTATE_COL_NUMBER,szTaskProperty,0);
  821. //Determine the TASK_FLAG_DELETE_WHEN_DONE
  822. hr = GetTaskState(pITask,szTaskProperty,TASK_FLAG_DELETE_WHEN_DONE );
  823. if (FAILED(hr))
  824. {
  825. StringCopy( szTaskProperty , GetResString(IDS_TASK_PROPERTY_NA), SIZE_OF_ARRAY(szTaskProperty) );
  826. }
  827. //Insert the TASK_FLAG_DELETE_WHEN_DONE state
  828. DynArraySetString2(pColData,iTaskCount,DELETE_IFNOTRESCHEDULED_COL_NUMBER,
  829. szTaskProperty,0);
  830. //TASK_FLAG_START_ONLY_IF_IDLE
  831. //initialise to neutral values
  832. StringCopy(szIdleTime, GetResString(IDS_TASK_PROPERTY_DISABLED), SIZE_OF_ARRAY(szIdleTime));
  833. StringCopy(szIdleRetryTime, szIdleTime, SIZE_OF_ARRAY(szIdleRetryTime));
  834. hr = GetTaskState(pITask,szTaskProperty,TASK_FLAG_START_ONLY_IF_IDLE);
  835. if (FAILED(hr))
  836. {
  837. StringCopy( szIdleTime , GetResString(IDS_TASK_PROPERTY_NA), SIZE_OF_ARRAY(szIdleTime) );
  838. StringCopy( szIdleRetryTime , GetResString(IDS_TASK_PROPERTY_NA), SIZE_OF_ARRAY(szIdleRetryTime) );
  839. }
  840. if(StringCompare(szTaskProperty,GetResString(IDS_TASK_PROPERTY_ENABLED), TRUE, 0) == 0 )
  841. {
  842. //Display the rest applicable Idle fields
  843. hr = pITask->GetIdleWait(&wIdleMinutes,&wDeadlineMinutes);
  844. if ( SUCCEEDED(hr))
  845. {
  846. StringCchPrintf(szIdleTime, SIZE_OF_ARRAY(szIdleTime), _T("%d"),wIdleMinutes);
  847. StringCchPrintf(szIdleRetryTime, SIZE_OF_ARRAY(szIdleRetryTime), _T("%d"),wDeadlineMinutes);
  848. }
  849. szValues[0] = (WCHAR*) szIdleTime;
  850. StringCchPrintf ( szMessage, SIZE_OF_ARRAY(szMessage), GetResString(IDS_COL_IDLE_ONLYSTART), szIdleTime );
  851. StringCopy( szBuffer, szMessage, SIZE_OF_ARRAY(szBuffer) );
  852. StringConcat( szBuffer, TIME_DATE_SEPERATOR, SIZE_OF_ARRAY(szBuffer) );
  853. szValues[0] = (WCHAR*) szIdleRetryTime;
  854. StringCchPrintf ( szMessage, SIZE_OF_ARRAY(szMessage), GetResString(IDS_COL_IDLE_NOTIDLE), szIdleRetryTime );
  855. StringConcat( szBuffer, szMessage, SIZE_OF_ARRAY(szBuffer) );
  856. //Get the property of ( kill task if computer goes idle)
  857. hr = GetTaskState(pITask,szTaskProperty,TASK_FLAG_KILL_ON_IDLE_END );
  858. if (FAILED(hr))
  859. {
  860. StringCopy( szTaskProperty , GetResString(IDS_TASK_PROPERTY_NA), SIZE_OF_ARRAY(szTaskProperty) );
  861. }
  862. if(StringCompare(szTaskProperty,GetResString(IDS_TASK_PROPERTY_ENABLED), TRUE, 0) == 0 )
  863. {
  864. StringConcat( szBuffer, TIME_DATE_SEPERATOR, SIZE_OF_ARRAY(szBuffer) );
  865. StringConcat( szBuffer, GetResString ( IDS_COL_IDLE_STOPTASK ), SIZE_OF_ARRAY(szBuffer) );
  866. }
  867. //Insert the property of ( kill task if computer goes idle)
  868. DynArraySetString2(pColData,iTaskCount,IDLE_COL_NUMBER,szBuffer,0);
  869. }
  870. else
  871. {
  872. DynArraySetString2(pColData,iTaskCount,IDLE_COL_NUMBER,szTaskProperty,0);
  873. }
  874. //Get the Power mgmt.properties
  875. hr = GetTaskState(pITask,szTaskProperty,TASK_FLAG_DONT_START_IF_ON_BATTERIES );
  876. if (FAILED(hr))
  877. {
  878. StringCopy( szTaskProperty , GetResString(IDS_TASK_PROPERTY_NA), SIZE_OF_ARRAY(szTaskProperty) );
  879. }
  880. if(StringCompare(szTaskProperty,GetResString(IDS_TASK_PROPERTY_ENABLED), TRUE, 0) ==0 )
  881. {
  882. StringCopy(szBuffer, GetResString (IDS_COL_POWER_NOSTART), SIZE_OF_ARRAY(szBuffer));
  883. bOnBattery = TRUE;
  884. }
  885. hr = GetTaskState(pITask,szTaskProperty,TASK_FLAG_KILL_IF_GOING_ON_BATTERIES);
  886. if (FAILED(hr))
  887. {
  888. StringCopy( szTaskProperty , GetResString(IDS_TASK_PROPERTY_NA), SIZE_OF_ARRAY(szTaskProperty) );
  889. }
  890. if(StringCompare(szTaskProperty,GetResString(IDS_TASK_PROPERTY_ENABLED), TRUE, 0) ==0 )
  891. {
  892. StringCopy( szMessage, GetResString (IDS_COL_POWER_STOP), SIZE_OF_ARRAY(szMessage));
  893. bStopTask = TRUE;
  894. }
  895. if ( ( bOnBattery == TRUE ) && ( bStopTask == TRUE ) )
  896. {
  897. StringCopy(szTmpBuf, szBuffer, SIZE_OF_ARRAY(szTmpBuf));
  898. StringConcat( szTmpBuf, TIME_DATE_SEPERATOR, SIZE_OF_ARRAY(szTmpBuf) );
  899. StringConcat( szTmpBuf, szMessage, SIZE_OF_ARRAY(szTmpBuf) );
  900. }
  901. else if ( ( bOnBattery == FALSE ) && ( bStopTask == TRUE ) )
  902. {
  903. StringCopy( szTmpBuf, szMessage, SIZE_OF_ARRAY(szTmpBuf) );
  904. }
  905. else if ( ( bOnBattery == TRUE ) && ( bStopTask == FALSE ) )
  906. {
  907. StringCopy( szTmpBuf, szBuffer, SIZE_OF_ARRAY(szTmpBuf) );
  908. }
  909. if( ( bOnBattery == FALSE ) && ( bStopTask == FALSE ) )
  910. {
  911. DynArraySetString2(pColData,iTaskCount,POWER_COL_NUMBER,szTaskProperty,0);
  912. }
  913. else
  914. {
  915. DynArraySetString2(pColData,iTaskCount,POWER_COL_NUMBER,szTmpBuf,0);
  916. }
  917. //Get RunAsUser
  918. hr = GetRunAsUser(pITask, szTaskProperty);
  919. if (FAILED(hr))
  920. {
  921. StringCopy( szTaskProperty , GetResString(IDS_USER_UNKNOWN), SIZE_OF_ARRAY(szTaskProperty) );
  922. }
  923. if( StringCompare( szTaskProperty , L"\0", TRUE, 0 ) == 0 )
  924. {
  925. StringCopy( szTaskProperty , NTAUTHORITY_USER, SIZE_OF_ARRAY(szTaskProperty) );
  926. // display the mode as background
  927. StringCopy ( szMode, GetResString (IDS_COL_MODE_BACKGROUND), SIZE_OF_ARRAY(szMode) );
  928. }
  929. else
  930. {
  931. if ( bInteractive == TRUE )
  932. {
  933. // display the mode as interactive
  934. StringCopy ( szMode, GetResString (IDS_COL_MODE_INTERACTIVE), SIZE_OF_ARRAY(szMode) );
  935. }
  936. else
  937. {
  938. StringCopy ( szMode, GetResString (IDS_COL_MODE_INTERACT_BACK), SIZE_OF_ARRAY(szMode) );
  939. }
  940. }
  941. DynArraySetString2(pColData, iTaskCount, MODE_COL_NUMBER, szMode, 0);
  942. DynArraySetString2(pColData,iTaskCount,RUNASUSER_COL_NUMBER,szTaskProperty,0);
  943. StringCopy( szTaskProperty , L"\0", SIZE_OF_ARRAY(szTaskProperty) );
  944. //Get the task's maximum run time & insert in the 2D array
  945. hr = GetMaxRunTime(pITask,szTaskProperty);
  946. if (FAILED(hr))
  947. {
  948. StringCopy( szTaskProperty , GetResString(IDS_TASK_PROPERTY_NA), SIZE_OF_ARRAY(szTaskProperty) );
  949. }
  950. DynArraySetString2(pColData,iTaskCount,STOPTASK_COL_NUMBER,szTaskProperty,0);
  951. hr = GetTaskProps(pITask,&tcTaskProperties,wCurrentTrigger, szScheduleName);
  952. if (FAILED(hr))
  953. {
  954. StringCopy( tcTaskProperties.szTaskType , GetResString(IDS_TASK_PROPERTY_NA), SIZE_OF_ARRAY(tcTaskProperties.szTaskType) );
  955. StringCopy( tcTaskProperties.szTaskStartTime , GetResString(IDS_TASK_PROPERTY_NA), SIZE_OF_ARRAY(tcTaskProperties.szTaskStartTime) );
  956. StringCopy( tcTaskProperties.szTaskEndDate , GetResString(IDS_TASK_PROPERTY_NA), SIZE_OF_ARRAY(tcTaskProperties.szTaskEndDate) );
  957. StringCopy( tcTaskProperties.szTaskDays , GetResString(IDS_TASK_PROPERTY_NA), SIZE_OF_ARRAY(tcTaskProperties.szTaskDays) );
  958. StringCopy( tcTaskProperties.szTaskMonths , GetResString(IDS_TASK_PROPERTY_NA), SIZE_OF_ARRAY(tcTaskProperties.szTaskMonths) );
  959. StringCopy( tcTaskProperties.szRepeatEvery , GetResString(IDS_TASK_PROPERTY_NA), SIZE_OF_ARRAY(tcTaskProperties.szRepeatEvery) );
  960. StringCopy( tcTaskProperties.szRepeatUntilTime , GetResString(IDS_TASK_PROPERTY_NA), SIZE_OF_ARRAY(tcTaskProperties.szRepeatUntilTime) );
  961. StringCopy( tcTaskProperties.szRepeatDuration , GetResString(IDS_TASK_PROPERTY_NA), SIZE_OF_ARRAY(tcTaskProperties.szRepeatDuration) );
  962. StringCopy( tcTaskProperties.szRepeatStop , GetResString(IDS_TASK_PROPERTY_NA), SIZE_OF_ARRAY(tcTaskProperties.szRepeatStop) );
  963. }
  964. //Insert Task Type
  965. DynArraySetString2(pColData,iTaskCount,TASKTYPE_COL_NUMBER,
  966. tcTaskProperties.szTaskType, 0);
  967. //Insert start time
  968. DynArraySetString2(pColData,iTaskCount,STARTTIME_COL_NUMBER,
  969. tcTaskProperties.szTaskStartTime, 0);
  970. //Insert start Date
  971. DynArraySetString2(pColData,iTaskCount,STARTDATE_COL_NUMBER,
  972. tcTaskProperties.szTaskStartDate, 0);
  973. //Insert Task idle time
  974. if( StringCompare( tcTaskProperties.szTaskType , GetResString(IDS_TASK_IDLE), TRUE, 0 ) == 0 )
  975. {
  976. hr = pITask->GetIdleWait(&wIdleMinutes,&wDeadlineMinutes);
  977. if ( SUCCEEDED(hr))
  978. {
  979. StringCchPrintf(szIdleTime, SIZE_OF_ARRAY(szIdleTime), _T("%d"),wIdleMinutes);
  980. }
  981. else
  982. {
  983. StringCopy( szIdleTime, GetResString(IDS_TASK_PROPERTY_NA), SIZE_OF_ARRAY(szIdleTime) );
  984. }
  985. }
  986. //Insert Task End date
  987. DynArraySetString2(pColData,iTaskCount,ENDDATE_COL_NUMBER,
  988. tcTaskProperties.szTaskEndDate, 0);
  989. //Insert days value
  990. DynArraySetString2(pColData,iTaskCount,DAYS_COL_NUMBER,
  991. tcTaskProperties.szTaskDays,0);
  992. //Insert months value
  993. DynArraySetString2(pColData,iTaskCount,MONTHS_COL_NUMBER,
  994. tcTaskProperties.szTaskMonths, 0);
  995. //Insert repeat every time
  996. DynArraySetString2(pColData,iTaskCount, REPEAT_EVERY_COL_NUMBER ,
  997. tcTaskProperties.szRepeatEvery,0);
  998. //Insert repeat until time
  999. DynArraySetString2(pColData,iTaskCount,REPEAT_UNTILTIME_COL_NUMBER,
  1000. tcTaskProperties.szRepeatUntilTime,0);
  1001. //Insert repeat duration
  1002. DynArraySetString2(pColData,iTaskCount,REPEAT_DURATION_COL_NUMBER,
  1003. tcTaskProperties.szRepeatDuration,0);
  1004. //Insert repeat stop if running
  1005. DynArraySetString2(pColData,iTaskCount,REPEAT_STOP_COL_NUMBER,
  1006. tcTaskProperties.szRepeatStop,0);
  1007. }//end of bVerbose
  1008. if( bMultiTriggers == TRUE)
  1009. {
  1010. iTaskCount++;
  1011. }
  1012. bNotScheduled = FALSE;
  1013. }//end of Trigger FOR loop
  1014. CoTaskMemFree(lpwszNames[dwArrTaskIndex]);
  1015. if( bMultiTriggers == FALSE)
  1016. iTaskCount++;
  1017. CoTaskMemFree(lpwszNames);
  1018. if( pITask )
  1019. pITask->Release();
  1020. }//End of the enumerating tasks
  1021. if(pIEnum)
  1022. pIEnum->Release();
  1023. //if there are no tasks display msg.
  1024. if( bTasksExists == FALSE )
  1025. {
  1026. DestroyDynamicArray(&pColData);
  1027. ShowMessage(stdout,GetResString(IDS_TASKNAME_NOTASKS));
  1028. return S_OK;
  1029. }
  1030. if (dwFormatType != SR_FORMAT_CSV)
  1031. {
  1032. ShowMessage(stdout,_T("\n"));
  1033. }
  1034. if( bVerbose == FALSE )
  1035. {
  1036. if ( dwFormatType == SR_FORMAT_LIST )
  1037. {
  1038. iArrSize = COL_SIZE_LIST; // for LIST non-verbose mode only 4 columns
  1039. }
  1040. else
  1041. {
  1042. iArrSize = COL_SIZE_VERBOSE; // for non-verbose mode only 3 columns
  1043. }
  1044. }
  1045. if(bHeader)
  1046. {
  1047. if ( ( bVerbose == FALSE ) &&
  1048. ( (dwFormatType == SR_FORMAT_TABLE) || (dwFormatType == SR_FORMAT_CSV) ) )
  1049. {
  1050. ShowResults((DWORD)iArrSize,pNonVerboseCols,SR_HIDECOLUMN|dwFormatType,pColData);
  1051. }
  1052. else
  1053. {
  1054. ShowResults((DWORD)iArrSize,pVerboseCols,SR_HIDECOLUMN|dwFormatType,pColData);
  1055. }
  1056. }
  1057. else
  1058. {
  1059. if ( ( bVerbose == FALSE ) &&
  1060. ( (dwFormatType == SR_FORMAT_TABLE) || (dwFormatType == SR_FORMAT_CSV) ) )
  1061. {
  1062. ShowResults((DWORD)iArrSize,pNonVerboseCols,dwFormatType,pColData);
  1063. }
  1064. else
  1065. {
  1066. ShowResults((DWORD)iArrSize,pVerboseCols,dwFormatType,pColData);
  1067. }
  1068. }
  1069. DestroyDynamicArray(&pColData);
  1070. return S_OK;
  1071. }
  1072. BOOL
  1073. CheckServiceStatus(
  1074. IN LPCTSTR szServer,
  1075. IN OUT DWORD *dwCheck,
  1076. IN BOOL bFlag
  1077. )
  1078. /*++
  1079. Routine Description:
  1080. This routine return if Task Scheduler services running or not.
  1081. Arguments:
  1082. [in] szServer : Server Name.
  1083. [in] bFlag : falg
  1084. Return Value:
  1085. BOOL : TRUE- Service is STOPEED.
  1086. FALSE- Otherwise.
  1087. --*/
  1088. {
  1089. SERVICE_STATUS ServiceStatus;
  1090. LPWSTR wszComputerName = NULL;
  1091. SC_HANDLE SCMgrHandle = NULL;
  1092. SC_HANDLE SCSerHandle = NULL;
  1093. LPWSTR pwsz = NULL;
  1094. WORD wSlashCount = 0;
  1095. WCHAR wszActualComputerName[ 2 * MAX_STRING_LENGTH ];
  1096. BOOL bCancel = FALSE;
  1097. BOOL bNobreak = TRUE;
  1098. SecureZeroMemory ( wszActualComputerName, SIZE_OF_ARRAY(wszActualComputerName));
  1099. wszComputerName = (LPWSTR)szServer;
  1100. if( IsLocalSystem(szServer) == FALSE )
  1101. {
  1102. StringCopy ( wszActualComputerName, DOMAIN_U_STRING, SIZE_OF_ARRAY(wszActualComputerName));
  1103. //check whether the server name prefixed with \\ or not.
  1104. if( wszComputerName != NULL )
  1105. {
  1106. pwsz = wszComputerName;
  1107. while ( ( *pwsz != NULL_U_CHAR ) && ( *pwsz == BACK_SLASH_U ) )
  1108. {
  1109. // server name prefixed with '\'..
  1110. // so..increment the pointer and count number of black slashes..
  1111. pwsz = _wcsinc(pwsz);
  1112. wSlashCount++;
  1113. }
  1114. if( (wSlashCount == 2 ) ) // two back slashes are present
  1115. {
  1116. StringCopy( wszActualComputerName, wszComputerName, SIZE_OF_ARRAY(wszActualComputerName) );
  1117. }
  1118. else if ( wSlashCount == 0 )
  1119. {
  1120. //Append "\\" to computer name
  1121. StringConcat(wszActualComputerName, wszComputerName, 2 * MAX_RES_STRING);
  1122. }
  1123. }
  1124. }
  1125. // open service manager
  1126. SCMgrHandle = OpenSCManager( wszActualComputerName, NULL, SC_MANAGER_CONNECT );
  1127. if ( NULL == SCMgrHandle)
  1128. {
  1129. *dwCheck = 1;
  1130. return FALSE;
  1131. }
  1132. // open service
  1133. SCSerHandle = OpenService( SCMgrHandle, SERVICE_NAME, SERVICE_START | SERVICE_QUERY_STATUS );
  1134. if ( NULL == SCSerHandle)
  1135. {
  1136. *dwCheck = 1;
  1137. CloseServiceHandle(SCMgrHandle);
  1138. return FALSE;
  1139. }
  1140. // get the status of service
  1141. if ( FALSE == QueryServiceStatus( SCSerHandle, &ServiceStatus) )
  1142. {
  1143. *dwCheck = 1;
  1144. CloseServiceHandle(SCMgrHandle);
  1145. CloseServiceHandle(SCSerHandle);
  1146. return FALSE;
  1147. }
  1148. //check whether the service status is running or not..
  1149. if ( ServiceStatus.dwCurrentState != SERVICE_RUNNING)
  1150. {
  1151. if ( TRUE == bFlag )
  1152. {
  1153. ShowMessage ( stdout, GetResString(IDS_CONFIRM_SERVICE));
  1154. if (EXIT_FAILURE == ConfirmInput(&bCancel))
  1155. {
  1156. *dwCheck = 2;
  1157. CloseServiceHandle(SCMgrHandle);
  1158. CloseServiceHandle(SCSerHandle);
  1159. return FALSE;
  1160. }
  1161. if ( TRUE == bCancel )
  1162. {
  1163. *dwCheck = 3;
  1164. CloseServiceHandle(SCMgrHandle);
  1165. CloseServiceHandle(SCSerHandle);
  1166. // operation cancelled.. return with success..
  1167. return FALSE;
  1168. }
  1169. // start the service
  1170. if (FALSE == StartService( SCSerHandle, 0, NULL))
  1171. {
  1172. *dwCheck = 1;
  1173. //release handles
  1174. CloseServiceHandle(SCMgrHandle);
  1175. CloseServiceHandle(SCSerHandle);
  1176. return FALSE;
  1177. }
  1178. else
  1179. {
  1180. // Since task scheduler service is taking some time to start..
  1181. // check whether the task scheduler service is started or not..
  1182. while (1)
  1183. {
  1184. // get the status of service
  1185. if ( FALSE == QueryServiceStatus( SCSerHandle, &ServiceStatus) )
  1186. {
  1187. *dwCheck = 1;
  1188. CloseServiceHandle(SCMgrHandle);
  1189. CloseServiceHandle(SCSerHandle);
  1190. return FALSE;
  1191. }
  1192. //check whether the service is started or not..
  1193. if (ServiceStatus.dwCurrentState != SERVICE_RUNNING)
  1194. {
  1195. // continue till service runs
  1196. continue;
  1197. }
  1198. else
  1199. {
  1200. // service is started ..
  1201. break;
  1202. }
  1203. }
  1204. //release handles
  1205. CloseServiceHandle(SCMgrHandle);
  1206. CloseServiceHandle(SCSerHandle);
  1207. return TRUE;
  1208. }
  1209. }
  1210. else
  1211. {
  1212. //release handles
  1213. CloseServiceHandle(SCMgrHandle);
  1214. CloseServiceHandle(SCSerHandle);
  1215. return TRUE;
  1216. }
  1217. }
  1218. //release handles
  1219. CloseServiceHandle(SCMgrHandle);
  1220. CloseServiceHandle(SCSerHandle);
  1221. return FALSE;
  1222. }