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.

1327 lines
33 KiB

  1. /******************************************************************************
  2. Copyright(c) Microsoft Corporation
  3. Module Name:
  4. change.cpp
  5. Abstract:
  6. This module changes the parameters of task(s) present in the system
  7. Author:
  8. Venu Gopal Choudary 01-Mar-2001
  9. Revision History:
  10. Venu Gopal Choudary 01-Mar-2001 : Created it
  11. ******************************************************************************/
  12. //common header files needed for this file
  13. #include "pch.h"
  14. #include "CommonHeaderFiles.h"
  15. // Function declaration for the Usage function.
  16. VOID DisplayChangeUsage();
  17. BOOL GetTheUserName( LPTSTR pszUserName, DWORD dwMaxUserNameSize );
  18. /*****************************************************************************
  19. Routine Description:
  20. This routine Changes the paraemters of a specified scheduled task(s)
  21. Arguments:
  22. [ in ] argc : Number of command line arguments
  23. [ in ] argv : Array containing command line arguments
  24. Return Value :
  25. A DWORD value indicating EXIT_SUCCESS on success else
  26. EXIT_FAILURE on failure
  27. *****************************************************************************/
  28. DWORD
  29. ChangeScheduledTaskParams( DWORD argc, LPCTSTR argv[] )
  30. {
  31. // Variables used to find whether Change option, Usage option
  32. // are specified or not
  33. BOOL bChange = FALSE;
  34. BOOL bUsage = FALSE;
  35. // Set the TaskSchduler object as NULL
  36. ITaskScheduler *pITaskScheduler = NULL;
  37. // Return value
  38. HRESULT hr = S_OK;
  39. // Initialising the variables that are passed to TCMDPARSER structure
  40. _TCHAR szServer[ MAX_STRING_LENGTH ] = NULL_STRING;
  41. _TCHAR szTaskName[ MAX_STRING_LENGTH ] = NULL_STRING;
  42. _TCHAR szTaskRun[ MAX_STRING_LENGTH ] = NULL_STRING;
  43. _TCHAR szUserName[MAX_STRING_LENGTH] = NULL_STRING;
  44. _TCHAR szPassword[MAX_STRING_LENGTH] = NULL_STRING;
  45. _TCHAR szRunAsUserName[MAX_STRING_LENGTH] = NULL_STRING;
  46. _TCHAR szRunAsPassword[MAX_STRING_LENGTH] = NULL_STRING;
  47. // Declarations related to Task name
  48. WCHAR wszJobName[MAX_TASKNAME_LEN] = NULL_U_STRING;
  49. WCHAR wszUserName[MAX_STRING_LENGTH] = NULL_U_STRING;
  50. WCHAR wszPassword[MAX_STRING_LENGTH] = NULL_U_STRING;
  51. WCHAR wszCommand[_MAX_FNAME] = NULL_U_STRING;
  52. WCHAR wszApplName[_MAX_FNAME] = NULL_U_STRING;
  53. // Dynamic Array contaning array of jobs
  54. TARRAY arrJobs = NULL;
  55. // Loop Variable.
  56. DWORD dwJobCount = 0;
  57. //buffer for displaying error message
  58. TCHAR szMessage[MAX_STRING_LENGTH] = NULL_STRING;
  59. BOOL bUserName = TRUE;
  60. BOOL bPassWord = TRUE;
  61. BOOL bSystemStatus = FALSE;
  62. BOOL bNeedPassword = FALSE;
  63. BOOL bResult = FALSE;
  64. BOOL bCloseConnection = TRUE;
  65. lstrcpy( szPassword, ASTERIX);
  66. lstrcpy( szRunAsPassword, ASTERIX);
  67. // Builiding the TCMDPARSER structure
  68. TCMDPARSER cmdOptions[] =
  69. {
  70. {
  71. CMDOPTION_CHANGE,
  72. CP_MAIN_OPTION,
  73. 1,
  74. 0,
  75. &bChange,
  76. NULL_STRING,
  77. NULL,
  78. NULL
  79. },
  80. {
  81. SWITCH_SERVER,
  82. CP_TYPE_TEXT | CP_VALUE_MANDATORY,
  83. 1,
  84. 0,
  85. &szServer,
  86. NULL_STRING,
  87. NULL,
  88. NULL
  89. },
  90. {
  91. SWITCH_USER,
  92. CP_TYPE_TEXT | CP_VALUE_MANDATORY,
  93. OPTION_COUNT,
  94. 0,
  95. &szUserName,
  96. NULL_STRING,
  97. NULL,
  98. NULL
  99. },
  100. {
  101. SWITCH_PASSWORD,
  102. CP_TYPE_TEXT | CP_VALUE_OPTIONAL,
  103. OPTION_COUNT,
  104. 0,
  105. &szPassword,
  106. NULL_STRING,
  107. NULL,
  108. NULL
  109. },
  110. {
  111. SWITCH_RUNAS_USER,
  112. CP_TYPE_TEXT | CP_VALUE_MANDATORY,
  113. OPTION_COUNT,
  114. 0,
  115. &szRunAsUserName,
  116. NULL_STRING,
  117. NULL,
  118. NULL
  119. },
  120. {
  121. SWITCH_RUNAS_PASSWORD,
  122. CP_TYPE_TEXT | CP_VALUE_OPTIONAL,
  123. OPTION_COUNT,
  124. 0,
  125. &szRunAsPassword,
  126. NULL_STRING,
  127. NULL,
  128. NULL
  129. },
  130. {
  131. SWITCH_TASKNAME,
  132. CP_TYPE_TEXT | CP_VALUE_MANDATORY | CP_MANDATORY ,
  133. 1,
  134. 0,
  135. &szTaskName,
  136. NULL_STRING,
  137. NULL,
  138. NULL
  139. },
  140. {
  141. SWITCH_TASKRUN,
  142. CP_TYPE_TEXT | CP_VALUE_MANDATORY,
  143. 1,
  144. 0,
  145. &szTaskRun,
  146. NULL_STRING,
  147. NULL,
  148. NULL
  149. },
  150. {
  151. CMDOPTION_USAGE,
  152. CP_USAGE ,
  153. 1,
  154. 0,
  155. &bUsage,
  156. NULL_STRING,
  157. NULL,
  158. NULL
  159. }
  160. };
  161. // Parsing the change option switches
  162. if ( DoParseParam( argc, argv, SIZE_OF_ARRAY(cmdOptions), cmdOptions ) == FALSE)
  163. {
  164. DISPLAY_MESSAGE( stderr, GetResString(IDS_LOGTYPE_ERROR ));
  165. DISPLAY_MESSAGE( stderr, GetReason() );
  166. return EXIT_FAILURE;
  167. }
  168. // triming the null spaces
  169. StrTrim(szServer, TRIM_SPACES );
  170. StrTrim(szUserName, TRIM_SPACES );
  171. StrTrim(szTaskName, TRIM_SPACES );
  172. StrTrim(szRunAsUserName, TRIM_SPACES );
  173. StrTrim(szTaskRun, TRIM_SPACES );
  174. // check whether password (-p) specified in the command line or not.
  175. if ( cmdOptions[OI_CHPASSWORD].dwActuals == 0 )
  176. {
  177. lstrcpy( szPassword, NULL_STRING );
  178. }
  179. // check whether run as password (-rp) specified in the command line or not.
  180. if ( cmdOptions[OI_CHRUNASPASSWORD].dwActuals == 0 )
  181. {
  182. lstrcpy( szRunAsPassword, NULL_STRING );
  183. }
  184. // Displaying change usage if user specified -? with -change option
  185. if( bUsage == TRUE )
  186. {
  187. DisplayChangeUsage();
  188. return EXIT_SUCCESS;
  189. }
  190. // check for -s, -ru, -rp or -tr options specified in the cmdline or not
  191. if( ( cmdOptions[OI_CHSERVER].dwActuals == 0 ) &&
  192. ( cmdOptions[OI_CHRUNASUSER].dwActuals == 0 ) &&
  193. ( cmdOptions[OI_CHRUNASPASSWORD].dwActuals == 0 ) &&
  194. ( cmdOptions[OI_CHTASKRUN].dwActuals == 0 ) )
  195. {
  196. DISPLAY_MESSAGE(stderr,GetResString(IDS_NO_CHANGE_OPTIONS));
  197. return RETVAL_FAIL;
  198. }
  199. // check for invalid server
  200. if( ( cmdOptions[OI_CHSERVER].dwActuals == 1 ) && ( lstrlen( szServer ) == 0 ) )
  201. {
  202. DISPLAY_MESSAGE(stderr, GetResString(IDS_NO_SERVER));
  203. return RETVAL_FAIL;
  204. }
  205. // check whether -u or -ru options specified respectively with -p or -rp options or not
  206. if ( cmdOptions[ OI_CHUSERNAME ].dwActuals == 0 && cmdOptions[ OI_CHPASSWORD ].dwActuals == 1 )
  207. {
  208. // invalid syntax
  209. DISPLAY_MESSAGE(stderr, GetResString(IDS_CHPASSWORD_BUT_NOUSERNAME));
  210. return RETVAL_FAIL; // indicate failure
  211. }
  212. // check for invalid user name
  213. if( ( cmdOptions[OI_CHSERVER].dwActuals == 0 ) && ( cmdOptions[OI_CHUSERNAME].dwActuals == 1 ) )
  214. {
  215. DISPLAY_MESSAGE(stderr, GetResString(IDS_CHANGE_USER_BUT_NOMACHINE));
  216. return RETVAL_FAIL;
  217. }
  218. // check for the length of user name
  219. if( ( cmdOptions[OI_CHSERVER].dwActuals == 1 ) && ( cmdOptions[OI_CHUSERNAME].dwActuals == 1 ) &&
  220. ( lstrlen( szUserName ) == 0 ) )
  221. {
  222. DISPLAY_MESSAGE(stderr, GetResString(IDS_INVALID_USERNAME));
  223. return RETVAL_FAIL;
  224. }
  225. // check for the length of username
  226. if( ( lstrlen( szUserName ) > MAX_USERNAME_LENGTH ) ||
  227. ( lstrlen( szRunAsUserName ) > MAX_USERNAME_LENGTH ) )
  228. {
  229. DISPLAY_MESSAGE(stderr,GetResString(IDS_INVALID_UNAME));
  230. return RETVAL_FAIL;
  231. }
  232. // check for the length of password
  233. if( ( lstrlen( szRunAsPassword ) > MAX_PASSWORD_LENGTH ) ||
  234. ( lstrlen( szPassword ) > MAX_PASSWORD_LENGTH ) )
  235. {
  236. DISPLAY_MESSAGE(stderr,GetResString(IDS_INVALID_PASSWORD));
  237. return RETVAL_FAIL;
  238. }
  239. // check for the length of taskname
  240. if( ( lstrlen( szTaskName ) > MAX_JOB_LEN ) || ( lstrlen(szTaskName) == 0 ) )
  241. {
  242. DISPLAY_MESSAGE( stderr, GetResString(IDS_INVALID_TASKLENGTH) );
  243. return RETVAL_FAIL;
  244. }
  245. // check for the length of task to run
  246. if( ( cmdOptions[OI_CHTASKRUN].dwActuals == 1 ) &&
  247. ( ( lstrlen( szTaskRun ) > MAX_TASK_LEN ) ||
  248. ( lstrlen ( szTaskRun ) == 0 ) ) )
  249. {
  250. DISPLAY_MESSAGE(stderr, GetResString(IDS_INVALID_TASKRUN));
  251. return RETVAL_FAIL;
  252. }
  253. // Convert the task name specified by the user to wide char or unicode format
  254. if( GetAsUnicodeString(szTaskName,wszJobName,SIZE_OF_ARRAY(wszJobName)) == NULL )
  255. {
  256. return RETVAL_FAIL;
  257. }
  258. //for holding values of parameters in FormatMessage()
  259. _TCHAR* szValues[1] = {NULL};
  260. BOOL bLocalMachine = FALSE;
  261. BOOL bRemoteMachine = FALSE;
  262. #ifdef _WIN64
  263. INT64 dwPos = 0;
  264. #else
  265. DWORD dwPos = 0;
  266. #endif
  267. // check whether remote machine specified or not
  268. if( cmdOptions[OI_CHSERVER].dwActuals == 1 )
  269. {
  270. bRemoteMachine = TRUE;
  271. }
  272. else
  273. {
  274. bLocalMachine = TRUE;
  275. }
  276. // check whether the password (-p) specified in the command line or not
  277. // and also check whether '*' or empty is given for -p or not
  278. if( ( IsLocalSystem( szServer ) == FALSE ) &&
  279. ( ( cmdOptions[OI_CHPASSWORD].dwActuals == 0 ) || ( lstrcmpi ( szPassword, ASTERIX ) == 0 ) ) )
  280. {
  281. bNeedPassword = TRUE;
  282. }
  283. // check whether server (-s) and username (-u) only specified along with the command or not
  284. if( ( IsLocalSystem( szServer ) == FALSE ) || ( cmdOptions[OI_CHUSERNAME].dwActuals == 1 ) )
  285. {
  286. // Establish the connection on a remote machine
  287. bResult = EstablishConnection(szServer,szUserName,SIZE_OF_ARRAY(szUserName),szPassword,SIZE_OF_ARRAY(szPassword), bNeedPassword );
  288. if (bResult == FALSE)
  289. {
  290. // displays the appropriate error message
  291. DISPLAY_MESSAGE( stderr, GetResString(IDS_ERROR_STRING) );
  292. DISPLAY_MESSAGE( stderr, GetReason());
  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. // check for mismatched credentials
  304. case E_LOCAL_CREDENTIALS:
  305. case ERROR_SESSION_CREDENTIAL_CONFLICT:
  306. {
  307. bCloseConnection = FALSE;
  308. DISPLAY_MESSAGE( stderr, GetResString(IDS_ERROR_STRING) );
  309. DISPLAY_MESSAGE( stderr, GetReason());
  310. return EXIT_FAILURE;
  311. }
  312. }
  313. }
  314. }
  315. // Get the task Scheduler object for the system.
  316. pITaskScheduler = GetTaskScheduler( szServer );
  317. // If the Task Scheduler is not defined then give the error message.
  318. if ( pITaskScheduler == NULL )
  319. {
  320. // close the connection that was established by the utility
  321. if ( bCloseConnection == TRUE )
  322. CloseConnection( szServer );
  323. Cleanup(pITaskScheduler);
  324. return EXIT_FAILURE;
  325. }
  326. // Validate the Given Task and get as TARRAY in case of taskname
  327. arrJobs = ValidateAndGetTasks( pITaskScheduler, szTaskName);
  328. if( arrJobs == NULL )
  329. {
  330. _stprintf( szMessage , GetResString(IDS_TASKNAME_NOTEXIST), szTaskName);
  331. DISPLAY_MESSAGE(stderr,szMessage);
  332. // close the connection that was established by the utility
  333. if ( bCloseConnection == TRUE )
  334. CloseConnection( szServer );
  335. Cleanup(pITaskScheduler);
  336. return EXIT_FAILURE;
  337. }
  338. IPersistFile *pIPF = NULL;
  339. ITask *pITask = NULL;
  340. // returns an pITask inteface for wszJobName
  341. hr = pITaskScheduler->Activate(wszJobName,IID_ITask,
  342. (IUnknown**) &pITask);
  343. if (FAILED(hr))
  344. {
  345. DisplayErrorMsg(hr);
  346. if( pIPF )
  347. pIPF->Release();
  348. if( pITask )
  349. pITask->Release();
  350. // close the connection that was established by the utility
  351. if ( bCloseConnection == TRUE )
  352. CloseConnection( szServer );
  353. Cleanup(pITaskScheduler);
  354. return EXIT_FAILURE;
  355. }
  356. //if the user name is not specifed set the current logged on user settings
  357. DWORD dwUserLen = MAX_USERNAME_LEN;
  358. DWORD dwResult = 0;
  359. BOOL bFlag = FALSE;
  360. ULONG ulLong = MAX_RES_STRING;
  361. TCHAR szBuffer[MAX_STRING_LENGTH] = NULL_STRING;
  362. TCHAR szRunAsUser[MAX_STRING_LENGTH] = NULL_STRING;
  363. // declaration for parameter arguments
  364. wchar_t* wcszParam = L"";
  365. // get the run as user name for a specified scheduled task
  366. hr = GetRunAsUser(pITask, szRunAsUser);
  367. if ( ( cmdOptions[OI_CHRUNASUSER].dwActuals == 1 ) &&
  368. ( (lstrlen( szRunAsUserName) == 0) || ( lstrcmpi(szRunAsUserName, NTAUTHORITY_USER ) == 0 ) ||
  369. (lstrcmpi(szRunAsUserName, SYSTEM_USER ) == 0 ) ) )
  370. {
  371. bSystemStatus = TRUE;
  372. bFlag = TRUE;
  373. }
  374. else if ( FAILED (hr) )
  375. {
  376. bFlag = TRUE;
  377. }
  378. // flag to check whether run as user name is "NT AUTHORITY\SYSTEM" or not
  379. if ( bFlag == FALSE )
  380. {
  381. // check for "NT AUTHORITY\SYSTEM" username
  382. if( ( ( cmdOptions[OI_CHRUNASUSER].dwActuals == 1 ) && ( lstrlen( szRunAsUserName) == 0 ) ) ||
  383. ( ( cmdOptions[OI_CHRUNASUSER].dwActuals == 1 ) && ( lstrlen( szRunAsUserName) == 0 ) && ( lstrlen(szRunAsPassword ) == 0 ) ) ||
  384. ( ( cmdOptions[OI_CHRUNASUSER].dwActuals == 1 ) && ( lstrcmpi(szRunAsUserName, NTAUTHORITY_USER ) == 0 ) && ( lstrlen(szRunAsPassword ) == 0 )) ||
  385. ( ( cmdOptions[OI_CHRUNASUSER].dwActuals == 1 ) && ( lstrcmpi(szRunAsUserName, NTAUTHORITY_USER ) == 0 ) ) ||
  386. ( ( cmdOptions[OI_CHRUNASUSER].dwActuals == 1 ) && ( lstrcmpi(szRunAsUserName, SYSTEM_USER) == 0 ) && ( lstrlen(szRunAsPassword ) == 0 ) ) ||
  387. ( ( cmdOptions[OI_CHRUNASUSER].dwActuals == 1 ) && ( lstrcmpi(szRunAsUserName, SYSTEM_USER ) == 0 ) ) )
  388. {
  389. bSystemStatus = TRUE;
  390. }
  391. }
  392. if ( bSystemStatus == FALSE )
  393. {
  394. //check the length of run as user name
  395. if ( (lstrlen( szRunAsUserName ) != 0 ))
  396. {
  397. // Convert the run as user name specified by the user to wide char or unicode format
  398. if ( GetAsUnicodeString(szRunAsUserName, wszUserName, SIZE_OF_ARRAY(wszUserName)) == NULL )
  399. {
  400. // close the connection that was established by the utility
  401. if ( bCloseConnection == TRUE )
  402. CloseConnection( szServer );
  403. return EXIT_FAILURE;
  404. }
  405. }
  406. else
  407. {
  408. bUserName = FALSE;
  409. }
  410. //check for the null password
  411. if ( ( lstrlen( szRunAsPassword ) != 0 ) && ( lstrcmpi ( szRunAsPassword, ASTERIX) != 0 ) )
  412. {
  413. // Convert the password specified by the user to wide char or unicode format
  414. if ( GetAsUnicodeString( szRunAsPassword, wszPassword, SIZE_OF_ARRAY(wszPassword)) == NULL )
  415. {
  416. // close the connection that was established by the utility
  417. if ( bCloseConnection == TRUE )
  418. CloseConnection( szServer );
  419. return EXIT_FAILURE;
  420. }
  421. bPassWord = TRUE;
  422. }
  423. else
  424. {
  425. // check whether -rp is specified or not
  426. if (cmdOptions[OI_CHRUNASPASSWORD].dwActuals == 1)
  427. {
  428. if( ( lstrcmpi( szRunAsPassword , NULL_STRING ) != 0 ) && ( lstrcmpi ( szRunAsPassword, ASTERIX) != 0 ) )
  429. {
  430. bPassWord = TRUE;
  431. }
  432. else if ( ( bSystemStatus == FALSE ) && ( lstrlen (szRunAsPassword) == 0 ) )
  433. {
  434. DISPLAY_MESSAGE (stderr, GetResString(IDS_NO_PASSWORD));
  435. // close the connection that was established by the utility
  436. if ( bCloseConnection == TRUE )
  437. CloseConnection( szServer );
  438. Cleanup(pITaskScheduler);
  439. return EXIT_FAILURE;
  440. }
  441. else if ( lstrcmpi ( szRunAsPassword, ASTERIX) == 0 )
  442. {
  443. bPassWord = FALSE;
  444. }
  445. }
  446. else if ( bSystemStatus == FALSE )
  447. {
  448. bPassWord = FALSE;
  449. }
  450. }
  451. }
  452. // check for the status of username and password
  453. if( ( bUserName == TRUE ) && ( bPassWord == FALSE ) )
  454. {
  455. // check for the local or remote system
  456. if ( (bLocalMachine == TRUE) || (bRemoteMachine == TRUE) )
  457. {
  458. szValues[0] = (_TCHAR*) (szRunAsUserName);
  459. FormatMessage(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
  460. GetResString(IDS_PROMPT_CHGPASSWD),0,MAKELANGID(LANG_NEUTRAL,
  461. SUBLANG_DEFAULT),szBuffer,
  462. MAX_STRING_LENGTH,(va_list*)szValues );
  463. DISPLAY_MESSAGE(stdout,szBuffer);
  464. // Get the password from the command line
  465. if (GetPassword( szRunAsPassword, MAX_PASSWORD_LENGTH ) == FALSE )
  466. {
  467. // close the connection that was established by the utility
  468. if ( bCloseConnection == TRUE )
  469. CloseConnection( szServer );
  470. return EXIT_FAILURE;
  471. }
  472. // check for the length of password
  473. if( lstrlen(szRunAsPassword) > MAX_PASSWORD_LENGTH )
  474. {
  475. DISPLAY_MESSAGE(stderr,GetResString(IDS_INVALID_PASSWORD));
  476. Cleanup(pITaskScheduler);
  477. return E_FAIL;
  478. }
  479. //check for the null password
  480. if( lstrcmpi( szRunAsPassword , NULL_STRING ) == 0 )
  481. {
  482. DISPLAY_MESSAGE (stderr, GetResString(IDS_NO_PASSWORD));
  483. if( pIPF )
  484. pIPF->Release();
  485. if( pITask )
  486. pITask->Release();
  487. // close the connection that was established by the utility
  488. if ( bCloseConnection == TRUE )
  489. CloseConnection( szServer );
  490. Cleanup(pITaskScheduler);
  491. return EXIT_FAILURE;
  492. }
  493. // check for the password length > 0
  494. if(lstrlen( szRunAsPassword ))
  495. {
  496. // Convert the password specified by the user to wide char or unicode format
  497. if ( GetAsUnicodeString( szRunAsPassword, wszPassword,SIZE_OF_ARRAY(wszPassword)) == NULL )
  498. {
  499. // close the connection that was established by the utility
  500. if ( bCloseConnection == TRUE )
  501. CloseConnection( szServer );
  502. return EXIT_FAILURE;
  503. }
  504. }
  505. }
  506. }
  507. // check for the status of user name and password
  508. else if( ( bUserName == FALSE ) && ( bPassWord == TRUE ) )
  509. {
  510. if ( (bLocalMachine == TRUE) || (bRemoteMachine == TRUE) )
  511. {
  512. if ( (bFlag == TRUE ) && ( bSystemStatus == FALSE ) )
  513. {
  514. DISPLAY_MESSAGE(stdout, GetResString(IDS_PROMPT_USERNAME));
  515. if ( GetTheUserName( szRunAsUserName, MAX_USERNAME_LENGTH) == FALSE )
  516. {
  517. DISPLAY_MESSAGE(stderr, GetResString( IDS_FAILED_TOGET_USER ) );
  518. // close the connection that was established by the utility
  519. if ( bCloseConnection == TRUE )
  520. CloseConnection( szServer );
  521. return EXIT_FAILURE;
  522. }
  523. // check for the length of username
  524. if( lstrlen(szRunAsUserName) > MAX_USERNAME_LENGTH )
  525. {
  526. DISPLAY_MESSAGE(stderr,GetResString(IDS_INVALID_UNAME ));
  527. // close the connection that was established by the utility
  528. if ( bCloseConnection == TRUE )
  529. CloseConnection( szServer );
  530. return EXIT_FAILURE;
  531. }
  532. if ( (lstrlen( szRunAsUserName) == 0) || ( lstrcmpi(szRunAsUserName, NTAUTHORITY_USER ) == 0 ) ||
  533. (lstrcmpi(szRunAsUserName, SYSTEM_USER ) == 0 ) )
  534. {
  535. bSystemStatus = TRUE;
  536. bFlag = TRUE;
  537. }
  538. else
  539. {
  540. // check for the length of run as user name
  541. if(lstrlen(szRunAsUserName))
  542. {
  543. // Convert the run as user name specified by the user to wide char or unicode format
  544. if (GetAsUnicodeString(szRunAsUserName, wszUserName, SIZE_OF_ARRAY(wszUserName)) == NULL )
  545. {
  546. // close the connection that was established by the utility
  547. if ( bCloseConnection == TRUE )
  548. CloseConnection( szServer );
  549. return EXIT_FAILURE;
  550. }
  551. }
  552. }
  553. }
  554. else
  555. {
  556. // Convert the run as user name specified by the user to wide char or unicode format
  557. if (GetAsUnicodeString( szRunAsUser, wszUserName, SIZE_OF_ARRAY(wszUserName)) == NULL )
  558. {
  559. // close the connection that was established by the utility
  560. if ( bCloseConnection == TRUE )
  561. CloseConnection( szServer );
  562. return EXIT_FAILURE;
  563. }
  564. }
  565. // check for the length of password > 0
  566. if(lstrlen(szRunAsPassword))
  567. {
  568. // Convert the password specified by the user to wide char or unicode format
  569. if (GetAsUnicodeString(szRunAsPassword, wszPassword, SIZE_OF_ARRAY(wszPassword)) == NULL )
  570. {
  571. // close the connection that was established by the utility
  572. if ( bCloseConnection == TRUE )
  573. CloseConnection( szServer );
  574. return EXIT_FAILURE;
  575. }
  576. }
  577. }
  578. }
  579. // check for the user name and password are not specified
  580. else if( ( bUserName == FALSE ) && ( bPassWord == FALSE ) )
  581. {
  582. if ( (bLocalMachine == TRUE) || (bRemoteMachine == TRUE) )
  583. {
  584. if ( (bFlag == TRUE ) && ( bSystemStatus == FALSE ) )
  585. {
  586. DISPLAY_MESSAGE(stdout, GetResString(IDS_PROMPT_USERNAME));
  587. if ( GetTheUserName( szRunAsUserName, MAX_USERNAME_LENGTH ) == FALSE )
  588. {
  589. DISPLAY_MESSAGE(stderr, GetResString( IDS_FAILED_TOGET_USER ) );
  590. // close the connection that was established by the utility
  591. if ( bCloseConnection == TRUE )
  592. CloseConnection( szServer );
  593. return EXIT_FAILURE;
  594. }
  595. // check for the length of username
  596. if( lstrlen(szRunAsUserName) > MAX_USERNAME_LENGTH )
  597. {
  598. DISPLAY_MESSAGE(stderr,GetResString(IDS_INVALID_UNAME ));
  599. // close the connection that was established by the utility
  600. if ( bCloseConnection == TRUE )
  601. CloseConnection( szServer );
  602. return EXIT_FAILURE;
  603. }
  604. if ( (lstrlen( szRunAsUserName) == 0) || ( lstrcmpi(szRunAsUserName, NTAUTHORITY_USER ) == 0 ) ||
  605. (lstrcmpi(szRunAsUserName, SYSTEM_USER ) == 0 ) )
  606. {
  607. bSystemStatus = TRUE;
  608. bFlag = TRUE;
  609. }
  610. else
  611. {
  612. if(lstrlen(szRunAsUserName))
  613. {
  614. // Convert the run as user name specified by the user to wide char or unicode format
  615. if ( GetAsUnicodeString(szRunAsUserName, wszUserName, SIZE_OF_ARRAY(wszUserName)) == NULL )
  616. {
  617. // close the connection that was established by the utility
  618. if ( bCloseConnection == TRUE )
  619. CloseConnection( szServer );
  620. return EXIT_FAILURE;
  621. }
  622. }
  623. }
  624. }
  625. else
  626. {
  627. // Convert the run as user name specified by the user to wide char or unicode format
  628. if (GetAsUnicodeString( szRunAsUser, wszUserName, SIZE_OF_ARRAY(wszUserName)) == NULL )
  629. {
  630. // close the connection that was established by the utility
  631. if ( bCloseConnection == TRUE )
  632. CloseConnection( szServer );
  633. return EXIT_FAILURE;
  634. }
  635. }
  636. if ( wcslen ( wszUserName ) != 0 )
  637. {
  638. szValues[0] = (_TCHAR*) (wszUserName);
  639. FormatMessage(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
  640. GetResString(IDS_PROMPT_CHGPASSWD),0,MAKELANGID(LANG_NEUTRAL,
  641. SUBLANG_DEFAULT),szBuffer,
  642. MAX_STRING_LENGTH,(va_list*)szValues );
  643. DISPLAY_MESSAGE(stdout,szBuffer);
  644. // Get the run as user password from the command line
  645. if ( GetPassword( szRunAsPassword, MAX_PASSWORD_LENGTH ) == FALSE )
  646. {
  647. // close the connection that was established by the utility
  648. if ( bCloseConnection == TRUE )
  649. CloseConnection( szServer );
  650. return EXIT_FAILURE;
  651. }
  652. // check for the length of password
  653. if( lstrlen(szRunAsPassword) > MAX_PASSWORD_LENGTH )
  654. {
  655. DISPLAY_MESSAGE(stderr,GetResString(IDS_INVALID_PASSWORD));
  656. Cleanup(pITaskScheduler);
  657. return E_FAIL;
  658. }
  659. //check for the null password
  660. if( lstrcmpi( szRunAsPassword , NULL_STRING ) == 0 )
  661. {
  662. DISPLAY_MESSAGE (stderr, GetResString(IDS_NO_PASSWORD));
  663. if( pIPF )
  664. pIPF->Release();
  665. if( pITask )
  666. pITask->Release();
  667. // close the connection that was established by the utility
  668. if ( bCloseConnection == TRUE )
  669. CloseConnection( szServer );
  670. Cleanup(pITaskScheduler);
  671. return EXIT_FAILURE;
  672. }
  673. if(lstrlen( szRunAsPassword ))
  674. {
  675. // Convert the password specified by the user to wide char or unicode format
  676. if (GetAsUnicodeString( szRunAsPassword, wszPassword,SIZE_OF_ARRAY(wszPassword)) == NULL )
  677. {
  678. // close the connection that was established by the utility
  679. if ( bCloseConnection == TRUE )
  680. CloseConnection( szServer );
  681. return EXIT_FAILURE;
  682. }
  683. }
  684. }
  685. }
  686. }
  687. // Return a pointer to a specified interface on an object
  688. hr = pITask->QueryInterface(IID_IPersistFile, (void **) &pIPF);
  689. if (FAILED(hr))
  690. {
  691. DisplayErrorMsg(hr);
  692. if( pIPF )
  693. pIPF->Release();
  694. if( pITask )
  695. pITask->Release();
  696. // close the connection that was established by the utility
  697. if ( bCloseConnection == TRUE )
  698. CloseConnection( szServer );
  699. Cleanup(pITaskScheduler);
  700. return EXIT_FAILURE;
  701. }
  702. if( cmdOptions[OI_CHTASKRUN].dwActuals == 0 )
  703. {
  704. LPWSTR lpwszApplicationName = NULL;
  705. LPWSTR lpwszParams = NULL;
  706. // get the application name
  707. hr = pITask->GetApplicationName(&lpwszApplicationName);
  708. if (FAILED(hr))
  709. {
  710. DisplayErrorMsg(hr);
  711. if( pIPF )
  712. pIPF->Release();
  713. if( pITask )
  714. pITask->Release();
  715. CoTaskMemFree( lpwszApplicationName );
  716. // close the connection that was established by the utility
  717. if ( bCloseConnection == TRUE )
  718. CloseConnection( szServer );
  719. Cleanup(pITaskScheduler);
  720. return EXIT_FAILURE;
  721. }
  722. // get the parameters
  723. hr = pITask->GetParameters(&lpwszParams);
  724. if (FAILED(hr))
  725. {
  726. DisplayErrorMsg(hr);
  727. if( pIPF )
  728. pIPF->Release();
  729. if( pITask )
  730. pITask->Release();
  731. CoTaskMemFree( lpwszParams );
  732. // close the connection that was established by the utility
  733. if ( bCloseConnection == TRUE )
  734. CloseConnection( szServer );
  735. Cleanup(pITaskScheduler);
  736. return EXIT_FAILURE;
  737. }
  738. lstrcpy(wszCommand,lpwszApplicationName);
  739. CoTaskMemFree( lpwszApplicationName );
  740. // set the task to run application name
  741. hr = pITask->SetApplicationName(wszCommand);
  742. if (FAILED(hr))
  743. {
  744. DisplayErrorMsg(hr);
  745. if( pIPF )
  746. pIPF->Release();
  747. if( pITask )
  748. pITask->Release();
  749. // close the connection that was established by the utility
  750. if ( bCloseConnection == TRUE )
  751. CloseConnection( szServer );
  752. Cleanup(pITaskScheduler);
  753. return EXIT_FAILURE;
  754. }
  755. lstrcpy(wszCommand,lpwszParams);
  756. CoTaskMemFree( lpwszParams );
  757. // set the task to run application name
  758. hr = pITask->SetParameters(wszCommand);
  759. if (FAILED(hr))
  760. {
  761. DisplayErrorMsg(hr);
  762. if( pIPF )
  763. pIPF->Release();
  764. if( pITask )
  765. pITask->Release();
  766. // close the connection that was established by the utility
  767. if ( bCloseConnection == TRUE )
  768. CloseConnection( szServer );
  769. Cleanup(pITaskScheduler);
  770. return EXIT_FAILURE;
  771. }
  772. }
  773. else
  774. {
  775. // Convert the task to run specified by the user to wide char or unicode format
  776. if ( GetAsUnicodeString(szTaskRun,wszCommand,SIZE_OF_ARRAY(wszCommand)) == NULL )
  777. {
  778. // close the connection that was established by the utility
  779. if ( bCloseConnection == TRUE )
  780. CloseConnection( szServer );
  781. return EXIT_FAILURE;
  782. }
  783. // check for .exe substring string in the given task to run string
  784. wchar_t wcszParam[MAX_RES_STRING] = L"";
  785. DWORD dwProcessCode = 0 ;
  786. dwProcessCode = ProcessFilePath(wszCommand,wszApplName,wcszParam);
  787. if(dwProcessCode == RETVAL_FAIL)
  788. {
  789. if( pIPF )
  790. pIPF->Release();
  791. if( pITask )
  792. pITask->Release();
  793. // close the connection that was established by the utility
  794. if ( bCloseConnection == TRUE )
  795. CloseConnection( szServer );
  796. Cleanup(pITaskScheduler);
  797. return EXIT_FAILURE;
  798. }
  799. // Set command name with ITask::SetApplicationName
  800. hr = pITask->SetApplicationName(wszApplName);
  801. if (FAILED(hr))
  802. {
  803. DisplayErrorMsg(hr);
  804. if( pIPF )
  805. pIPF->Release();
  806. if( pITask )
  807. pITask->Release();
  808. // close the connection that was established by the utility
  809. if ( bCloseConnection == TRUE )
  810. CloseConnection( szServer );
  811. Cleanup(pITaskScheduler);
  812. return EXIT_FAILURE;
  813. }
  814. //[Working directory = exe pathname - exe name]
  815. wchar_t* wcszStartIn = wcsrchr(wszApplName,_T('\\'));
  816. if(wcszStartIn != NULL)
  817. *( wcszStartIn ) = _T('\0');
  818. // set the working directory of command
  819. hr = pITask->SetWorkingDirectory(wszApplName);
  820. if (FAILED(hr))
  821. {
  822. DisplayErrorMsg(hr);
  823. if( pIPF )
  824. pIPF->Release();
  825. if( pITask )
  826. pITask->Release();
  827. // close the connection that was established by the utility
  828. if ( bCloseConnection == TRUE )
  829. CloseConnection( szServer );
  830. Cleanup(pITaskScheduler);
  831. return EXIT_FAILURE;
  832. }
  833. // set the command line parameters for the task
  834. hr = pITask->SetParameters(wcszParam);
  835. if (FAILED(hr))
  836. {
  837. DisplayErrorMsg(hr);
  838. if( pIPF )
  839. {
  840. pIPF->Release();
  841. }
  842. if( pITask )
  843. {
  844. pITask->Release();
  845. }
  846. // close the connection that was established by the utility
  847. if ( bCloseConnection == TRUE )
  848. CloseConnection( szServer );
  849. Cleanup(pITaskScheduler);
  850. return EXIT_FAILURE;
  851. }
  852. }
  853. if( bSystemStatus == TRUE )
  854. {
  855. // Change the account information to "NT AUTHORITY\SYSTEM" user
  856. hr = pITask->SetAccountInformation(L"",NULL);
  857. if ( FAILED(hr) )
  858. {
  859. DISPLAY_MESSAGE(stderr, GetResString(IDS_NTAUTH_SYSTEM_ERROR));
  860. if( pIPF )
  861. pIPF->Release();
  862. if( pITask )
  863. pITask->Release();
  864. // close the connection that was established by the utility
  865. if ( bCloseConnection == TRUE )
  866. CloseConnection( szServer );
  867. Cleanup(pITaskScheduler);
  868. return EXIT_FAILURE;
  869. }
  870. }
  871. else
  872. {
  873. // set the account information with the user name and password
  874. hr = pITask->SetAccountInformation(wszUserName,wszPassword);
  875. }
  876. if ((FAILED(hr)) && (hr != SCHED_E_NO_SECURITY_SERVICES))
  877. {
  878. DisplayErrorMsg(hr);
  879. if( pIPF )
  880. pIPF->Release();
  881. if( pITask )
  882. pITask->Release();
  883. // close the connection that was established by the utility
  884. if ( bCloseConnection == TRUE )
  885. CloseConnection( szServer );
  886. Cleanup(pITaskScheduler);
  887. return EXIT_FAILURE;
  888. }
  889. if ( bSystemStatus == TRUE )
  890. {
  891. szValues[0] = (_TCHAR*) (wszJobName);
  892. FormatMessage(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
  893. GetResString(IDS_NTAUTH_SYSTEM_CHANGE_INFO),0,MAKELANGID(LANG_NEUTRAL,
  894. SUBLANG_DEFAULT),szBuffer,
  895. MAX_STRING_LENGTH,(va_list*)szValues
  896. );
  897. DISPLAY_MESSAGE(stdout,szBuffer);
  898. }
  899. if( (cmdOptions[OI_CHRUNASPASSWORD].dwActuals == 1) && ( bSystemStatus == TRUE ) &&
  900. (lstrlen( szRunAsPassword ) != 0) )
  901. {
  902. DISPLAY_MESSAGE( stdout, GetResString( IDS_PASSWORD_NOEFFECT ) );
  903. }
  904. // save the copy of an object
  905. hr = pIPF->Save(NULL,TRUE);
  906. if( E_FAIL == hr )
  907. {
  908. DisplayErrorMsg(hr);
  909. if(pIPF)
  910. pIPF->Release();
  911. if(pITask)
  912. pITask->Release();
  913. // close the connection that was established by the utility
  914. if ( bCloseConnection == TRUE )
  915. CloseConnection( szServer );
  916. Cleanup(pITaskScheduler);
  917. return EXIT_FAILURE;
  918. }
  919. if (FAILED (hr))
  920. {
  921. DisplayErrorMsg(hr);
  922. if(pIPF)
  923. pIPF->Release();
  924. if(pITask)
  925. pITask->Release();
  926. // close the connection that was established by the utility
  927. if ( bCloseConnection == TRUE )
  928. CloseConnection( szServer );
  929. Cleanup(pITaskScheduler);
  930. return EXIT_FAILURE;
  931. }
  932. else
  933. {
  934. // to display a success message
  935. szValues[0] = (_TCHAR*) (wszJobName);
  936. FormatMessage(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
  937. GetResString(IDS_CHANGE_SUCCESSFUL),0,MAKELANGID(LANG_NEUTRAL,
  938. SUBLANG_DEFAULT),szBuffer,
  939. MAX_STRING_LENGTH,(va_list*)szValues
  940. );
  941. DISPLAY_MESSAGE(stdout,szBuffer);
  942. }
  943. if( pIPF )
  944. pIPF->Release();
  945. if( pITask )
  946. pITask->Release();
  947. // close the connection that was established by the utility
  948. if ( bCloseConnection == TRUE )
  949. CloseConnection( szServer );
  950. Cleanup(pITaskScheduler);
  951. return EXIT_SUCCESS;
  952. }
  953. /*****************************************************************************
  954. Routine Description:
  955. This routine displays the usage of -change option
  956. Arguments:
  957. None
  958. Return Value :
  959. VOID
  960. ******************************************************************************/
  961. VOID
  962. DisplayChangeUsage()
  963. {
  964. // Displaying -change option usage
  965. DisplayUsage( IDS_CHANGE_HLP1, IDS_CHANGE_HLP33 );
  966. }
  967. // ***************************************************************************
  968. // Routine Description:
  969. //
  970. // Takes the user name from the keyboard.While entering the user name
  971. // it displays the user name as it is.
  972. //
  973. // Arguments:
  974. //
  975. // [in] pszUserName -- String to store user name
  976. // [in] dwMaxUserNameSize -- Maximun size of the user name.
  977. //
  978. // Return Value:
  979. //
  980. // BOOL --If this function succeds returns TRUE otherwise returns FALSE.
  981. //
  982. // ***************************************************************************
  983. BOOL GetTheUserName( LPTSTR pszUserName, DWORD dwMaxUserNameSize )
  984. {
  985. // local variables
  986. TCHAR ch;
  987. DWORD dwIndex = 0;
  988. DWORD dwCharsRead = 0;
  989. DWORD dwCharsWritten = 0;
  990. DWORD dwPrevConsoleMode = 0;
  991. HANDLE hInputConsole = NULL;
  992. TCHAR szBuffer[ 10 ] = NULL_STRING;
  993. // check the input value
  994. if ( pszUserName == NULL )
  995. {
  996. SetLastError( ERROR_INVALID_PARAMETER );
  997. SaveLastError();
  998. return FALSE;
  999. }
  1000. // Get the handle for the standard input
  1001. hInputConsole = GetStdHandle( STD_INPUT_HANDLE );
  1002. if ( hInputConsole == NULL )
  1003. {
  1004. // could not get the handle so return failure
  1005. return FALSE;
  1006. }
  1007. // Get the current input mode of the input buffer
  1008. GetConsoleMode( hInputConsole, &dwPrevConsoleMode );
  1009. // Set the mode such that the control keys are processed by the system
  1010. if ( SetConsoleMode( hInputConsole, ENABLE_PROCESSED_INPUT ) == 0 )
  1011. {
  1012. // could not set the mode, return failure
  1013. return FALSE;
  1014. }
  1015. // Read the characters until a carriage return is hit
  1016. while( TRUE )
  1017. {
  1018. if ( ReadConsole( hInputConsole, &ch, 1, &dwCharsRead, NULL ) == 0 )
  1019. {
  1020. // Set the original console settings
  1021. SetConsoleMode( hInputConsole, dwPrevConsoleMode );
  1022. // return failure
  1023. return FALSE;
  1024. }
  1025. // Check for carraige return
  1026. if ( ch == CARRIAGE_RETURN )
  1027. {
  1028. DISPLAY_MESSAGE(stdout, _T("\n"));
  1029. // break from the loop
  1030. break;
  1031. }
  1032. // Check id back space is hit
  1033. if ( ch == BACK_SPACE )
  1034. {
  1035. if ( dwIndex != 0 )
  1036. {
  1037. //
  1038. // Remove a asterix from the console
  1039. // move the cursor one character back
  1040. FORMAT_STRING( szBuffer, _T( "%c" ), BACK_SPACE );
  1041. WriteConsole( GetStdHandle( STD_OUTPUT_HANDLE ), szBuffer, 1,
  1042. &dwCharsWritten, NULL );
  1043. // replace the existing character with space
  1044. FORMAT_STRING( szBuffer, _T( "%c" ), BLANK_CHAR );
  1045. WriteConsole( GetStdHandle( STD_OUTPUT_HANDLE ), szBuffer, 1,
  1046. &dwCharsWritten, NULL );
  1047. // now set the cursor at back position
  1048. FORMAT_STRING( szBuffer, _T( "%c" ), BACK_SPACE );
  1049. WriteConsole( GetStdHandle( STD_OUTPUT_HANDLE ), szBuffer, 1,
  1050. &dwCharsWritten, NULL );
  1051. // decrement the index
  1052. dwIndex--;
  1053. }
  1054. // process the next character
  1055. continue;
  1056. }
  1057. // if the max user name length has been reached then sound a beep
  1058. if ( dwIndex == ( dwMaxUserNameSize - 1 ) )
  1059. {
  1060. WriteConsole( GetStdHandle( STD_OUTPUT_HANDLE ), BEEP_SOUND, 1,
  1061. &dwCharsRead, NULL );
  1062. }
  1063. else
  1064. {
  1065. // store the input character
  1066. *( pszUserName + dwIndex ) = ch;
  1067. // display asterix onto the console
  1068. WriteConsole( GetStdHandle( STD_OUTPUT_HANDLE ), ( pszUserName + dwIndex ) , 1,
  1069. &dwCharsWritten, NULL );
  1070. dwIndex++;
  1071. }
  1072. }
  1073. // Add the NULL terminator
  1074. *( pszUserName + dwIndex ) = NULL_CHAR;
  1075. // Return success
  1076. return TRUE;
  1077. }