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