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.

477 lines
13 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // Job Schedule Application Unit Test
  4. //
  5. // Microsoft Windows
  6. // Copyright (C) Microsoft Corporation, 1992 - 1996.
  7. //
  8. // File: jobtest.cxx
  9. //
  10. // Contents: job object test harness
  11. //
  12. // History: 28-Apr-95 EricB created
  13. //
  14. //-----------------------------------------------------------------------------
  15. #include "headers.hxx"
  16. #pragma hdrstop
  17. #if defined(_CHICAGO_)
  18. #include "..\..\inc\job_cls.hxx"
  19. typedef HRESULT (* GETCLASSOBJECT)(REFCLSID cid, REFIID iid, void **ppvObj);
  20. #else
  21. #include <mstask.h>
  22. const int SCH_BIGBUF_LEN = 256;
  23. #endif
  24. DECLARE_INFOLEVEL(Sched);
  25. //+----------------------------------------------------------------------------
  26. // Macro: TEST_HR
  27. // Purpose: tests the HRESULT for error, takes "action" if found
  28. //-----------------------------------------------------------------------------
  29. #define TEST_HR(hr, str, action) \
  30. if (FAILED(hr)) \
  31. { \
  32. fprintf(stderr, #str " failed with error %lx\n", hr); \
  33. action; \
  34. }
  35. // flags
  36. #define JT_PERSISTENT 0x1
  37. #define JT_CREATE_JOB 0x2
  38. #define JT_EDIT_JOB 0x4
  39. #define JT_CREATE_TRIGGER 0x8
  40. #define JT_PRINT_TRIGGERS 0x10
  41. #define JT_PRINT_RUNS 0x20
  42. // prototypes
  43. void Usage(int ExitCode);
  44. HRESULT LoadJob(ITask * pJob, TCHAR * ptszFileName);
  45. HRESULT SaveJob(ITask * pJob, TCHAR * ptszFileName);
  46. HRESULT IsJobDirty(ITask * pJob);
  47. HRESULT EditJob(ITask * pJobEx);
  48. HRESULT PrintRunTimes(ITask * pJob, WORD cRuns);
  49. HRESULT PrintTriggers(ITask * pJob);
  50. //+----------------------------------------------------------------------------
  51. //
  52. // Function: main
  53. //
  54. // Synopsis: entry point
  55. //
  56. //-----------------------------------------------------------------------------
  57. int _cdecl
  58. main(int argc, char ** argv)
  59. {
  60. if (argc < 2)
  61. {
  62. Usage(EXIT_SUCCESS);
  63. }
  64. DWORD dwFlags = 0;
  65. WORD cRunsToPrint = 0;
  66. short iTrigger = SHRT_MAX;
  67. TCHAR * ptszFileName;
  68. char szMsg[80] = "\n** Job object test";
  69. LPTSTR ptszCmdLine = GetCommandLine();
  70. // skip the program name
  71. TCHAR * ptszToken = _tcspbrk(ptszCmdLine, TEXT(" \t"));
  72. // delimit the first token
  73. ptszToken = _tcstok(ptszToken, TEXT(" \t"));
  74. // parse command line
  75. do {
  76. switch (*ptszToken)
  77. {
  78. case TEXT('/'):
  79. case TEXT('-'):
  80. ptszToken = _tcsinc(ptszToken);
  81. switch(*ptszToken)
  82. {
  83. case TEXT('c'):
  84. case TEXT('C'):
  85. dwFlags |= JT_CREATE_JOB;
  86. strcat(szMsg, "; create");
  87. break;
  88. case TEXT('e'):
  89. case TEXT('E'):
  90. dwFlags |= JT_EDIT_JOB;
  91. strcat(szMsg, "; edit job");
  92. break;
  93. case TEXT('s'):
  94. case TEXT('S'):
  95. dwFlags |= JT_PRINT_TRIGGERS;
  96. strcat(szMsg, "; print trigger strings");
  97. break;
  98. case TEXT('r'):
  99. case TEXT('R'):
  100. dwFlags |= JT_PRINT_RUNS;
  101. ptszToken = _tcsinc(ptszToken);
  102. TCHAR * ptszNumRuns;
  103. ptszNumRuns = _tcstok(NULL, TEXT(" \t"));
  104. if (ptszNumRuns == NULL || *ptszNumRuns == TEXT('/') ||
  105. *ptszNumRuns == TEXT('-'))
  106. {
  107. Usage(EXIT_FAILURE);
  108. }
  109. cRunsToPrint = (WORD)_tcstol(ptszNumRuns, NULL, 10);
  110. strcat(szMsg, "; print runs");
  111. break;
  112. case TEXT('f'):
  113. case TEXT('F'):
  114. dwFlags |= JT_PERSISTENT;
  115. ptszToken = _tcsinc(ptszToken);
  116. ptszFileName = _tcstok(NULL, TEXT(" \t"));
  117. if (ptszFileName == NULL || *ptszFileName == TEXT('/') ||
  118. *ptszFileName == TEXT('-'))
  119. {
  120. Usage(EXIT_FAILURE);
  121. }
  122. sprintf(szMsg + strlen(szMsg), "; save %S", ptszFileName);
  123. break;
  124. case TEXT('h'):
  125. case TEXT('H'):
  126. case TEXT('?'):
  127. Usage(EXIT_SUCCESS);
  128. default:
  129. Usage(EXIT_FAILURE);
  130. }
  131. break;
  132. default:
  133. // not a switch character (/ or -)
  134. Usage(EXIT_FAILURE);
  135. }
  136. ptszToken = _tcstok(NULL, TEXT(" \t"));
  137. } while (ptszToken);
  138. strcat(szMsg, "\n");
  139. printf(szMsg);
  140. HRESULT hr;
  141. ITask * pJob;
  142. #if defined(_CHICAGO_) // don't use OLE on Chicago for now
  143. HINSTANCE hLib = LoadLibrary("c:\\windows\\schedulr.dll");
  144. if (!hLib)
  145. {
  146. fprintf(stderr, "LoadLibrary of schedulr.dll failed with error %d\n",
  147. GetLastError());
  148. goto Err0;
  149. }
  150. GETCLASSOBJECT GetClassObject;
  151. GetClassObject = (GETCLASSOBJECT)GetProcAddress(hLib, "DllGetClassObject");
  152. IClassFactory * pJobCF;
  153. hr = (*GetClassObject)(CLSID_CJob, IID_IClassFactory, (void **)&pJobCF);
  154. TEST_HR(hr, "DllGetClassObject(CLSID_CJob)", goto Err0);
  155. hr = pJobCF->CreateInstance(NULL, IID_ITask, (void **)&pJob);
  156. TEST_HR(hr, "CreateInstance(IID_ITask)", goto Err0);
  157. #else
  158. //hr = OleInitializeEx(NULL, COINIT_MULTITHREADED);
  159. hr = OleInitialize(NULL);
  160. TEST_HR(hr, "OleInitialize", return -1);
  161. hr = CoCreateInstance(CLSID_CJob, NULL, CLSCTX_INPROC_SERVER, IID_ITask,
  162. (void **)&pJob);
  163. TEST_HR(hr, "CoCreateInstance(CLSID_CJob)", goto Err0);
  164. #endif
  165. if (dwFlags & JT_PERSISTENT && !(dwFlags & JT_CREATE_JOB))
  166. {
  167. hr = LoadJob(pJob, ptszFileName);
  168. if (hr == ERROR_FILE_NOT_FOUND)
  169. {
  170. fprintf(stderr, "\nERROR, cannot specify /f on a non-existent "
  171. "file unless /c is also given!\n");
  172. goto Err1;
  173. }
  174. else
  175. {
  176. if (FAILED(hr))
  177. {
  178. goto Err1;
  179. }
  180. }
  181. }
  182. if (dwFlags & JT_EDIT_JOB)
  183. {
  184. hr = EditJob(pJob);
  185. if (hr == ERROR_CANCELLED)
  186. {
  187. goto cleanup;
  188. }
  189. if (FAILED(hr))
  190. {
  191. goto Err1;
  192. }
  193. }
  194. if (dwFlags & JT_CREATE_TRIGGER)
  195. {
  196. ITaskTrigger * pTrigger;
  197. hr = pJob->CreateTrigger(NULL, &pTrigger);
  198. if (FAILED(hr))
  199. {
  200. goto Err1;
  201. }
  202. pTrigger->Release();
  203. }
  204. if (dwFlags & JT_PRINT_TRIGGERS)
  205. {
  206. hr = PrintTriggers(pJob);
  207. if (FAILED(hr))
  208. {
  209. goto Err1;
  210. }
  211. }
  212. if (dwFlags & JT_PRINT_RUNS)
  213. {
  214. hr = PrintRunTimes(pJob, cRunsToPrint);
  215. if (FAILED(hr))
  216. {
  217. goto Err1;
  218. }
  219. }
  220. if (dwFlags & JT_CREATE_JOB)
  221. {
  222. hr = SaveJob(pJob, ptszFileName);
  223. if (FAILED(hr))
  224. {
  225. goto Err1;
  226. }
  227. }
  228. else
  229. {
  230. if ((dwFlags & JT_PERSISTENT) && (IsJobDirty(pJob) == S_OK))
  231. {
  232. hr = SaveJob(pJob, NULL);
  233. if (FAILED(hr))
  234. {
  235. goto Err1;
  236. }
  237. }
  238. }
  239. cleanup:
  240. pJob->Release();
  241. OleUninitialize();
  242. printf("\n** Test successfully completed! **\n");
  243. return(EXIT_SUCCESS);
  244. Err1:
  245. pJob->Release();
  246. Err0:
  247. #if !defined(_CHICAGO_) // don't use OLE on Chicago for now
  248. OleUninitialize();
  249. #endif
  250. printf("** Test failed.\n");
  251. return(EXIT_FAILURE);
  252. }
  253. //+----------------------------------------------------------------------------
  254. //
  255. // Function: IsJobDirty
  256. //
  257. // Synopsis: is the job object in core dirty?
  258. //
  259. //-----------------------------------------------------------------------------
  260. HRESULT
  261. IsJobDirty(ITask * pJob)
  262. {
  263. IPersistFile * pFile;
  264. HRESULT hr = pJob->QueryInterface(IID_IPersistFile, (void **)&pFile);
  265. TEST_HR(hr, "pJob->QueryInterface(IID_IPersistFile)", return hr);
  266. hr = pFile->IsDirty();
  267. pFile->Release();
  268. return hr;
  269. }
  270. //+----------------------------------------------------------------------------
  271. //
  272. // Function: LoadJob
  273. //
  274. // Synopsis: loads the job object from disk, if found
  275. //
  276. //-----------------------------------------------------------------------------
  277. HRESULT
  278. LoadJob(ITask * pJob, TCHAR * ptszFileName)
  279. {
  280. IPersistFile * pFile;
  281. HRESULT hr = pJob->QueryInterface(IID_IPersistFile, (void **)&pFile);
  282. TEST_HR(hr, "pJob->QueryInterface(IID_IPersistFile)", return hr);
  283. #if defined(UNICODE)
  284. hr = pFile->Load(ptszFileName, STGM_READWRITE | STGM_SHARE_EXCLUSIVE);
  285. #else // convert from ANSI to UNICODE
  286. WCHAR wszName[SCH_BIGBUF_LEN];
  287. MultiByteToWideChar(CP_ACP, 0, ptszFileName, -1, wszName, SCH_BIGBUF_LEN);
  288. hr = pFile->Load(wszName, STGM_READWRITE | STGM_SHARE_EXCLUSIVE);
  289. #endif
  290. if (hr == STG_E_FILENOTFOUND)
  291. {
  292. pFile->Release();
  293. return hr;
  294. }
  295. TEST_HR(hr, "pFile->Load", pFile->Release(); return hr);
  296. pFile->Release();
  297. return S_OK;
  298. }
  299. //+----------------------------------------------------------------------------
  300. //
  301. // Function: EditJob
  302. //
  303. // Synopsis: post the edit dialog for the job
  304. //
  305. //-----------------------------------------------------------------------------
  306. HRESULT
  307. EditJob(ITask * pJob)
  308. {
  309. HRESULT hr;
  310. hr = pJob->EditJob(GetDesktopWindow(), TRUE);
  311. return hr;
  312. }
  313. //+----------------------------------------------------------------------------
  314. //
  315. // Function: PrintRunTimes
  316. //
  317. // Synopsis: print out the next cRuns run times
  318. //
  319. //-----------------------------------------------------------------------------
  320. HRESULT
  321. PrintRunTimes(ITask * pJob, WORD cRuns)
  322. {
  323. SYSTEMTIME stNow;
  324. GetLocalTime(&stNow);
  325. LPSYSTEMTIME pstRuns;
  326. HRESULT hr;
  327. if (cRuns == 0)
  328. { // get runs for today
  329. SYSTEMTIME stEnd = stNow;
  330. stNow.wHour = stNow.wMinute = 0;
  331. stEnd.wHour = 23;
  332. stEnd.wMinute = 59;
  333. hr = pJob->GetRunTimes(&stNow, &stEnd, &cRuns, &pstRuns);
  334. TEST_HR(hr, "pJob->GetRunTimes", return hr);
  335. if (cRuns == 0)
  336. {
  337. printf("\nThere are no job runs scheduled for today.\n");
  338. return S_OK;
  339. }
  340. }
  341. else
  342. {
  343. hr = pJob->GetRunTimes(&stNow, NULL, &cRuns, &pstRuns);
  344. TEST_HR(hr, "pJob->GetRunTimes", return hr);
  345. }
  346. printf("\nThe next %d job run times: \n", cRuns);
  347. printf("-------------------------------------------------------------\n");
  348. for (WORD i = 0; i < cRuns; i++)
  349. {
  350. printf("%02d/%02d/%4d at %02d:%02d\n", pstRuns[i].wMonth,
  351. pstRuns[i].wDay, pstRuns[i].wYear, pstRuns[i].wHour,
  352. pstRuns[i].wMinute);
  353. }
  354. CoTaskMemFree(pstRuns);
  355. return S_OK;
  356. }
  357. //+----------------------------------------------------------------------------
  358. //
  359. // Function: PrintTriggers
  360. //
  361. // Synopsis: print out the trigger strings
  362. //
  363. //-----------------------------------------------------------------------------
  364. HRESULT
  365. PrintTriggers(ITask * pJob)
  366. {
  367. HRESULT hr;
  368. WCHAR * pwszTrigger;
  369. WORD cTriggers;
  370. hr = pJob->GetTriggerCount(&cTriggers);
  371. TEST_HR(hr, "pJob->GetTriggerCount", return hr)
  372. printf("\nPrint %d trigger string(s):\n\n", cTriggers);
  373. printf("Index\tValue\n");
  374. printf("-----\t-----------------------------------------------------\n");
  375. for (short i = 0; i < cTriggers; i++)
  376. {
  377. hr = pJob->GetTriggerString(i, &pwszTrigger);
  378. TEST_HR(hr, "pJob->GetTriggerString", return hr)
  379. printf("%d:\t%S\n", i, pwszTrigger);
  380. CoTaskMemFree(pwszTrigger);
  381. }
  382. return S_OK;
  383. }
  384. //+----------------------------------------------------------------------------
  385. //
  386. // Function: SaveJob
  387. //
  388. // Synopsis: saves the job object persistently
  389. //
  390. //-----------------------------------------------------------------------------
  391. HRESULT
  392. SaveJob(ITask * pJob, TCHAR * ptszFileName)
  393. {
  394. IPersistFile * pFile;
  395. HRESULT hr = pJob->QueryInterface(IID_IPersistFile, (void **)&pFile);
  396. TEST_HR(hr, "pJob->QueryInterface(IID_IPersistFile)", return hr);
  397. if (ptszFileName == NULL)
  398. {
  399. hr = pFile->Save(NULL, FALSE);
  400. }
  401. else
  402. {
  403. #if defined(UNICODE)
  404. hr = pFile->Save(ptszFileName, TRUE);
  405. #else // convert from ANSI to UNICODE
  406. WCHAR wszName[SCH_BIGBUF_LEN];
  407. MultiByteToWideChar(CP_ACP, 0, ptszFileName, -1, wszName,
  408. SCH_BIGBUF_LEN);
  409. hr = pFile->Save(wszName, TRUE);
  410. #endif
  411. }
  412. TEST_HR(hr, "pFile->Save", pFile->Release(); return hr);
  413. pFile->Release();
  414. return S_OK;
  415. }
  416. //+----------------------------------------------------------------------------
  417. //
  418. // Function: Usage
  419. //
  420. //-----------------------------------------------------------------------------
  421. void
  422. Usage(int ExitCode)
  423. {
  424. printf("\nJOBTEST: Job object test harness\n\n");
  425. if (ExitCode == EXIT_FAILURE)
  426. {
  427. printf("ERROR: incorrect command line!\n\n");
  428. }
  429. printf("Usage: jobtest [/c] [/e] [/s] [/t [<i>]] [/r <n>] [/f <file name>]\n");
  430. printf(" /c - create the job object (ignored without /f)\n");
  431. printf(" /e - edit the job object\n");
  432. printf(" /s - print out the string representation of the triggers\n");
  433. printf(" /t - edit a trigger; if an index i is not specified, create a new one\n");
  434. printf(" /r <n> - print out the next n run times for the job\n");
  435. printf(" n == 0 means prints today's jobs\n");
  436. printf(" /f - specify a filename, save changes to that file\n\n");
  437. printf("If /f is not specified, operations are performed on a temporary,\n"
  438. "in-core job object.\n");
  439. exit(ExitCode);
  440. }