1 /*
2 * Test suite for Task interface
3 *
4 * Copyright (C) 2008 Google (Roy Shea)
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #define COBJMACROS
22
23 #include "corerror.h"
24 #include "mstask.h"
25 #include "wine/test.h"
26
27 static ITaskScheduler *test_task_scheduler;
28 static ITask *test_task;
29 static const WCHAR empty[] = {0};
30
setup_task(void)31 static BOOL setup_task(void)
32 {
33 HRESULT hres;
34 const WCHAR task_name[] = {'T','e','s','t','i','n','g', 0};
35
36 hres = CoCreateInstance(&CLSID_CTaskScheduler, NULL, CLSCTX_INPROC_SERVER,
37 &IID_ITaskScheduler, (void **) &test_task_scheduler);
38 if(hres != S_OK)
39 return FALSE;
40 hres = ITaskScheduler_NewWorkItem(test_task_scheduler, task_name, &CLSID_CTask,
41 &IID_ITask, (IUnknown**)&test_task);
42 if(hres != S_OK)
43 {
44 ITaskScheduler_Release(test_task_scheduler);
45 return FALSE;
46 }
47 return TRUE;
48 }
49
cleanup_task(void)50 static void cleanup_task(void)
51 {
52 ITask_Release(test_task);
53 ITaskScheduler_Release(test_task_scheduler);
54 }
55
path_resolve_name(LPCWSTR base_name)56 static LPCWSTR path_resolve_name(LPCWSTR base_name)
57 {
58 static WCHAR buffer[MAX_PATH];
59 int len;
60
61 len = SearchPathW(NULL, base_name, NULL, 0, NULL, NULL);
62 if (len == 0)
63 return base_name;
64 else if (len < MAX_PATH)
65 {
66 SearchPathW(NULL, base_name, NULL, MAX_PATH, buffer, NULL);
67 return buffer;
68 }
69 return NULL;
70 }
71
test_SetApplicationName_GetApplicationName(void)72 static void test_SetApplicationName_GetApplicationName(void)
73 {
74 BOOL setup;
75 HRESULT hres;
76 LPWSTR stored_name;
77 LPCWSTR full_name;
78 const WCHAR non_application_name[] = {'N','o','S','u','c','h',
79 'A','p','p','l','i','c','a','t','i','o','n', 0};
80 const WCHAR notepad_exe[] = {
81 'n','o','t','e','p','a','d','.','e','x','e', 0};
82 const WCHAR notepad[] = {'n','o','t','e','p','a','d', 0};
83
84 setup = setup_task();
85 ok(setup, "Failed to setup test_task\n");
86 if (!setup)
87 {
88 skip("Failed to create task. Skipping tests.\n");
89 return;
90 }
91
92 /* Attempt getting before setting application name */
93 hres = ITask_GetApplicationName(test_task, &stored_name);
94 ok(hres == S_OK, "GetApplicationName failed: %08x\n", hres);
95 if (hres == S_OK)
96 {
97 ok(!lstrcmpiW(stored_name, empty),
98 "Got %s, expected empty string\n", wine_dbgstr_w(stored_name));
99 CoTaskMemFree(stored_name);
100 }
101
102 /* Set application name to a nonexistent application and then get
103 * the application name that is actually stored */
104 hres = ITask_SetApplicationName(test_task, non_application_name);
105 ok(hres == S_OK, "Failed setting name %s: %08x\n",
106 wine_dbgstr_w(non_application_name), hres);
107 hres = ITask_GetApplicationName(test_task, &stored_name);
108 ok(hres == S_OK, "GetApplicationName failed: %08x\n", hres);
109 if (hres == S_OK)
110 {
111 full_name = path_resolve_name(non_application_name);
112 ok(!lstrcmpiW(stored_name, full_name), "Got %s, expected %s\n",
113 wine_dbgstr_w(stored_name), wine_dbgstr_w(full_name));
114 CoTaskMemFree(stored_name);
115 }
116
117 /* Set a valid application name with program type extension and then
118 * get the stored name */
119 hres = ITask_SetApplicationName(test_task, notepad_exe);
120 ok(hres == S_OK, "Failed setting name %s: %08x\n",
121 wine_dbgstr_w(notepad_exe), hres);
122 hres = ITask_GetApplicationName(test_task, &stored_name);
123 ok(hres == S_OK, "GetApplicationName failed: %08x\n", hres);
124 if (hres == S_OK)
125 {
126 full_name = path_resolve_name(notepad_exe);
127 ok(!lstrcmpiW(stored_name, full_name), "Got %s, expected %s\n",
128 wine_dbgstr_w(stored_name), wine_dbgstr_w(full_name));
129 CoTaskMemFree(stored_name);
130 }
131
132 /* Set a valid application name without program type extension and
133 * then get the stored name */
134 hres = ITask_SetApplicationName(test_task, notepad);
135 ok(hres == S_OK, "Failed setting name %s: %08x\n", wine_dbgstr_w(notepad), hres);
136 hres = ITask_GetApplicationName(test_task, &stored_name);
137 ok(hres == S_OK, "GetApplicationName failed: %08x\n", hres);
138 if (hres == S_OK)
139 {
140 full_name = path_resolve_name(notepad_exe); /* XP SP1 appends .exe */
141 if (lstrcmpiW(stored_name, full_name) != 0)
142 {
143 full_name = path_resolve_name(notepad);
144 ok(!lstrcmpiW(stored_name, full_name), "Got %s, expected %s\n",
145 wine_dbgstr_w(stored_name), wine_dbgstr_w(full_name));
146 }
147 CoTaskMemFree(stored_name);
148 }
149
150 /* After having a valid application name set, set application the name
151 * to a nonexistent application and then get the name that is
152 * actually stored */
153 hres = ITask_SetApplicationName(test_task, non_application_name);
154 ok(hres == S_OK, "Failed setting name %s: %08x\n",
155 wine_dbgstr_w(non_application_name), hres);
156 hres = ITask_GetApplicationName(test_task, &stored_name);
157 ok(hres == S_OK, "GetApplicationName failed: %08x\n", hres);
158 if (hres == S_OK)
159 {
160 full_name = path_resolve_name(non_application_name);
161 ok(!lstrcmpiW(stored_name, full_name), "Got %s, expected %s\n",
162 wine_dbgstr_w(stored_name), wine_dbgstr_w(full_name));
163 CoTaskMemFree(stored_name);
164 }
165
166 /* Clear application name */
167 hres = ITask_SetApplicationName(test_task, empty);
168 ok(hres == S_OK, "Failed setting name %s: %08x\n", wine_dbgstr_w(empty), hres);
169 hres = ITask_GetApplicationName(test_task, &stored_name);
170 ok(hres == S_OK, "GetApplicationName failed: %08x\n", hres);
171 if (hres == S_OK)
172 {
173 ok(!lstrcmpiW(stored_name, empty),
174 "Got %s, expected empty string\n", wine_dbgstr_w(stored_name));
175 CoTaskMemFree(stored_name);
176 }
177
178 cleanup_task();
179 return;
180 }
181
test_CreateTrigger(void)182 static void test_CreateTrigger(void)
183 {
184 BOOL setup;
185 HRESULT hres;
186 WORD trigger_index;
187 ITaskTrigger *test_trigger;
188
189 setup = setup_task();
190 ok(setup, "Failed to setup test_task\n");
191 if (!setup)
192 {
193 skip("Failed to create task. Skipping tests.\n");
194 return;
195 }
196
197 hres = ITask_CreateTrigger(test_task, &trigger_index, &test_trigger);
198 ok(hres == S_OK, "Failed to create trigger: 0x%08x\n", hres);
199 if (hres != S_OK)
200 {
201 cleanup_task();
202 return;
203 }
204
205 ITaskTrigger_Release(test_trigger);
206 cleanup_task();
207 return;
208 }
209
test_SetParameters_GetParameters(void)210 static void test_SetParameters_GetParameters(void)
211 {
212 BOOL setup;
213 HRESULT hres;
214 LPWSTR parameters;
215 const WCHAR parameters_a[] = {'f','o','o','.','t','x','t', 0};
216 const WCHAR parameters_b[] = {'f','o','o','.','t','x','t',' ',
217 'b','a','r','.','t','x','t', 0};
218
219 setup = setup_task();
220 ok(setup, "Failed to setup test_task\n");
221 if (!setup)
222 {
223 skip("Failed to create task. Skipping tests.\n");
224 return;
225 }
226
227 /* Get parameters before setting them */
228 hres = ITask_GetParameters(test_task, ¶meters);
229 ok(hres == S_OK, "GetParameters failed: %08x\n", hres);
230 if (hres == S_OK)
231 {
232 ok(!lstrcmpW(parameters, empty),
233 "Got %s, expected empty string\n", wine_dbgstr_w(parameters));
234 CoTaskMemFree(parameters);
235 }
236
237 /* Set parameters to a simple string */
238 hres = ITask_SetParameters(test_task, parameters_a);
239 ok(hres == S_OK, "Failed setting parameters %s: %08x\n",
240 wine_dbgstr_w(parameters_a), hres);
241 hres = ITask_GetParameters(test_task, ¶meters);
242 ok(hres == S_OK, "GetParameters failed: %08x\n", hres);
243 if (hres == S_OK)
244 {
245 ok(!lstrcmpW(parameters, parameters_a), "Got %s, expected %s\n",
246 wine_dbgstr_w(parameters), wine_dbgstr_w(parameters_a));
247 CoTaskMemFree(parameters);
248 }
249
250 /* Update parameters to a different simple string */
251 hres = ITask_SetParameters(test_task, parameters_b);
252 ok(hres == S_OK, "Failed setting parameters %s: %08x\n",
253 wine_dbgstr_w(parameters_b), hres);
254 hres = ITask_GetParameters(test_task, ¶meters);
255 ok(hres == S_OK, "GetParameters failed: %08x\n", hres);
256 if (hres == S_OK)
257 {
258 ok(!lstrcmpW(parameters, parameters_b), "Got %s, expected %s\n",
259 wine_dbgstr_w(parameters), wine_dbgstr_w(parameters_b));
260 CoTaskMemFree(parameters);
261 }
262
263 /* Clear parameters */
264 hres = ITask_SetParameters(test_task, empty);
265 ok(hres == S_OK, "Failed setting parameters %s: %08x\n",
266 wine_dbgstr_w(empty), hres);
267 hres = ITask_GetParameters(test_task, ¶meters);
268 ok(hres == S_OK, "GetParameters failed: %08x\n", hres);
269 if (hres == S_OK)
270 {
271 ok(!lstrcmpW(parameters, empty),
272 "Got %s, expected empty string\n", wine_dbgstr_w(parameters));
273 CoTaskMemFree(parameters);
274 }
275
276 cleanup_task();
277 return;
278 }
279
test_SetComment_GetComment(void)280 static void test_SetComment_GetComment(void)
281 {
282 BOOL setup;
283 HRESULT hres;
284 LPWSTR comment;
285 const WCHAR comment_a[] = {'C','o','m','m','e','n','t','.', 0};
286 const WCHAR comment_b[] = {'L','o','n','g','e','r',' ',
287 'c','o','m','m','e','n','t','.', 0};
288
289 setup = setup_task();
290 ok(setup, "Failed to setup test_task\n");
291 if (!setup)
292 {
293 skip("Failed to create task. Skipping tests.\n");
294 return;
295 }
296
297 /* Get comment before setting it*/
298 hres = ITask_GetComment(test_task, &comment);
299 ok(hres == S_OK, "GetComment failed: %08x\n", hres);
300 if (hres == S_OK)
301 {
302 ok(!lstrcmpW(comment, empty),
303 "Got %s, expected empty string\n", wine_dbgstr_w(comment));
304 CoTaskMemFree(comment);
305 }
306
307 /* Set comment to a simple string */
308 hres = ITask_SetComment(test_task, comment_a);
309 ok(hres == S_OK, "Failed setting comment %s: %08x\n",
310 wine_dbgstr_w(comment_a), hres);
311 hres = ITask_GetComment(test_task, &comment);
312 ok(hres == S_OK, "GetComment failed: %08x\n", hres);
313 if (hres == S_OK)
314 {
315 ok(!lstrcmpW(comment, comment_a), "Got %s, expected %s\n",
316 wine_dbgstr_w(comment), wine_dbgstr_w(comment_a));
317 CoTaskMemFree(comment);
318 }
319
320 /* Update comment to a different simple string */
321 hres = ITask_SetComment(test_task, comment_b);
322 ok(hres == S_OK, "Failed setting comment %s: %08x\n",
323 wine_dbgstr_w(comment_b), hres);
324 hres = ITask_GetComment(test_task, &comment);
325 ok(hres == S_OK, "GetComment failed: %08x\n", hres);
326 if (hres == S_OK)
327 {
328 ok(!lstrcmpW(comment, comment_b), "Got %s, expected %s\n",
329 wine_dbgstr_w(comment), wine_dbgstr_w(comment_b));
330 CoTaskMemFree(comment);
331 }
332
333 /* Clear comment */
334 hres = ITask_SetComment(test_task, empty);
335 ok(hres == S_OK, "Failed setting comment %s: %08x\n",
336 wine_dbgstr_w(empty), hres);
337 hres = ITask_GetComment(test_task, &comment);
338 ok(hres == S_OK, "GetComment failed: %08x\n", hres);
339 if (hres == S_OK)
340 {
341 ok(!lstrcmpW(comment, empty),
342 "Got %s, expected empty string\n", wine_dbgstr_w(comment));
343 CoTaskMemFree(comment);
344 }
345
346 cleanup_task();
347 return;
348 }
349
test_SetMaxRunTime_GetMaxRunTime(void)350 static void test_SetMaxRunTime_GetMaxRunTime(void)
351 {
352 BOOL setup;
353 HRESULT hres;
354 DWORD max_run_time;
355
356 setup = setup_task();
357 ok(setup, "Failed to setup test_task\n");
358 if (!setup)
359 {
360 skip("Failed to create task. Skipping tests.\n");
361 return;
362 }
363
364 /* Default time is 3 days:
365 * 3 days * 24 hours * 60 minutes * 60 seconds * 1000 ms = 259200000 */
366 max_run_time = 0;
367 hres = ITask_GetMaxRunTime(test_task, &max_run_time);
368 ok(hres == S_OK, "Failed to get max runtime: 0x%08x\n", hres);
369 ok(max_run_time == 259200000, "Expected 259200000: %d\n", max_run_time);
370
371 /* Basic set test */
372 max_run_time = 0;
373 hres = ITask_SetMaxRunTime(test_task, 1234);
374 ok(hres == S_OK, "Failed to set max runtime: 0x%08x\n", hres);
375 hres = ITask_GetMaxRunTime(test_task, &max_run_time);
376 ok(hres == S_OK, "Failed to get max runtime: 0x%08x\n", hres);
377 ok(max_run_time == 1234, "Expected 1234: %d\n", max_run_time);
378
379 /* Verify that time can be set to zero */
380 max_run_time = 1;
381 hres = ITask_SetMaxRunTime(test_task, 0);
382 ok(hres == S_OK, "Failed to set max runtime: 0x%08x\n", hres);
383 hres = ITask_GetMaxRunTime(test_task, &max_run_time);
384 ok(hres == S_OK, "Failed to get max runtime: 0x%08x\n", hres);
385 ok(max_run_time == 0, "Expected 0: %d\n", max_run_time);
386
387 /* Check resolution by setting time to one */
388 max_run_time = 0;
389 hres = ITask_SetMaxRunTime(test_task, 1);
390 ok(hres == S_OK, "Failed to set max runtime: 0x%08x\n", hres);
391 hres = ITask_GetMaxRunTime(test_task, &max_run_time);
392 ok(hres == S_OK, "Failed to get max runtime: 0x%08x\n", hres);
393 ok(max_run_time == 1, "Expected 1: %d\n", max_run_time);
394
395 /* Verify that time can be set to INFINITE */
396 max_run_time = 0;
397 hres = ITask_SetMaxRunTime(test_task, INFINITE);
398 ok(hres == S_OK, "Failed to set max runtime: 0x%08x\n", hres);
399 hres = ITask_GetMaxRunTime(test_task, &max_run_time);
400 ok(hres == S_OK, "Failed to get max runtime: 0x%08x\n", hres);
401 ok(max_run_time == INFINITE, "Expected INFINITE: %d\n", max_run_time);
402
403 cleanup_task();
404 return;
405 }
406
test_SetAccountInformation_GetAccountInformation(void)407 static void test_SetAccountInformation_GetAccountInformation(void)
408 {
409 BOOL setup;
410 HRESULT hres;
411 LPWSTR account_name;
412 const WCHAR dummy_account_name[] = {'N', 'o', 'S', 'u', 'c', 'h',
413 'A', 'c', 'c', 'o', 'u', 'n', 't', 0};
414 const WCHAR dummy_account_name_b[] = {'N', 'o', 'S', 'u', 'c', 'h',
415 'A', 'c', 'c', 'o', 'u', 'n', 't', 'B', 0};
416
417 setup = setup_task();
418 ok(setup, "Failed to setup test_task\n");
419 if (!setup)
420 {
421 skip("Failed to create task. Skipping tests.\n");
422 return;
423 }
424
425 /* Get account information before it is set */
426 hres = ITask_GetAccountInformation(test_task, &account_name);
427 /* WinXP returns HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND): 0x80070002 but
428 * Win2K returns SCHED_E_CANNOT_OPEN_TASK: 0x8004130d
429 * Win9x doesn't support security services */
430 if (hres == SCHED_E_NO_SECURITY_SERVICES || hres == SCHED_E_SERVICE_NOT_RUNNING)
431 {
432 win_skip("Security services are not supported\n");
433 cleanup_task();
434 return;
435 }
436 ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) ||
437 hres == SCHED_E_CANNOT_OPEN_TASK,
438 "Unset account name generated: 0x%08x\n", hres);
439
440 /* Attempt to set to a dummy account without a password */
441 /* This test passes on WinXP but fails on Win2K */
442 hres = ITask_SetAccountInformation(test_task, dummy_account_name, NULL);
443 ok(hres == S_OK,
444 "Failed setting dummy account with no password: %08x\n", hres);
445 hres = ITask_GetAccountInformation(test_task, &account_name);
446 ok(hres == S_OK ||
447 broken(hres == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) ||
448 hres == SCHED_E_CANNOT_OPEN_TASK ||
449 hres == 0x200), /* win2k */
450 "GetAccountInformation failed: %08x\n", hres);
451 if (hres == S_OK)
452 {
453 ok(!lstrcmpW(account_name, dummy_account_name),
454 "Got %s, expected %s\n", wine_dbgstr_w(account_name),
455 wine_dbgstr_w(dummy_account_name));
456 CoTaskMemFree(account_name);
457 }
458
459 /* Attempt to set to a dummy account with a (invalid) password */
460 /* This test passes on WinXP but fails on Win2K */
461 hres = ITask_SetAccountInformation(test_task, dummy_account_name_b,
462 dummy_account_name_b);
463 ok(hres == S_OK,
464 "Failed setting dummy account with password: %08x\n", hres);
465 hres = ITask_GetAccountInformation(test_task, &account_name);
466 ok(hres == S_OK ||
467 broken(hres == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) ||
468 hres == SCHED_E_CANNOT_OPEN_TASK ||
469 hres == 0x200), /* win2k */
470 "GetAccountInformation failed: %08x\n", hres);
471 if (hres == S_OK)
472 {
473 ok(!lstrcmpW(account_name, dummy_account_name_b),
474 "Got %s, expected %s\n", wine_dbgstr_w(account_name),
475 wine_dbgstr_w(dummy_account_name_b));
476 CoTaskMemFree(account_name);
477 }
478
479 /* Attempt to set to the local system account */
480 hres = ITask_SetAccountInformation(test_task, empty, NULL);
481 ok(hres == S_OK, "Failed setting system account: %08x\n", hres);
482 hres = ITask_GetAccountInformation(test_task, &account_name);
483 ok(hres == S_OK ||
484 broken(hres == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) ||
485 hres == SCHED_E_CANNOT_OPEN_TASK ||
486 hres == 0x200), /* win2k */
487 "GetAccountInformation failed: %08x\n", hres);
488 if (hres == S_OK)
489 {
490 ok(!lstrcmpW(account_name, empty),
491 "Got %s, expected empty string\n", wine_dbgstr_w(account_name));
492 CoTaskMemFree(account_name);
493 }
494
495 cleanup_task();
496 return;
497 }
498
START_TEST(task)499 START_TEST(task)
500 {
501 CoInitialize(NULL);
502 test_SetApplicationName_GetApplicationName();
503 test_CreateTrigger();
504 test_SetParameters_GetParameters();
505 test_SetComment_GetComment();
506 test_SetMaxRunTime_GetMaxRunTime();
507 test_SetAccountInformation_GetAccountInformation();
508 CoUninitialize();
509 }
510