mstask: Handle disabled tasks in ITask::GetNextRunTime().
[wine.git] / dlls / mstask / tests / task_trigger.c
bloba89fa62d1c4c7d16a95ea7a5a7e4380c8fb86fad
1 /*
2 * Test suite for Task interface
4 * Copyright (C) 2008 Google (Roy Shea)
5 * Copyright (C) 2018 Dmitry Timoshkov
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #define COBJMACROS
24 #include <corerror.h>
26 #include "mstask.h"
27 #include "wine/test.h"
29 static ITaskScheduler *test_task_scheduler;
31 static DWORD obj_refcount(void *obj_to_check)
33 IUnknown *obj = obj_to_check;
34 IUnknown_AddRef(obj);
35 return IUnknown_Release(obj);
38 static BOOL compare_trigger_state(TASK_TRIGGER found_state,
39 TASK_TRIGGER expected_state)
41 ok(found_state.cbTriggerSize == expected_state.cbTriggerSize,
42 "cbTriggerSize: Found %d but expected %d\n",
43 found_state.cbTriggerSize, expected_state.cbTriggerSize);
45 ok(found_state.Reserved1 == expected_state.Reserved1,
46 "Reserved1: Found %d but expected %d\n",
47 found_state.Reserved1, expected_state.Reserved1);
49 ok(found_state.wBeginYear == expected_state.wBeginYear,
50 "wBeginYear: Found %d but expected %d\n",
51 found_state.wBeginYear, expected_state.wBeginYear);
53 ok(found_state.wBeginMonth == expected_state.wBeginMonth,
54 "wBeginMonth: Found %d but expected %d\n",
55 found_state.wBeginMonth, expected_state.wBeginMonth);
57 ok(found_state.wBeginDay == expected_state.wBeginDay,
58 "wBeginDay: Found %d but expected %d\n",
59 found_state.wBeginDay, expected_state.wBeginDay);
61 ok(found_state.wEndYear == expected_state.wEndYear,
62 "wEndYear: Found %d but expected %d\n",
63 found_state.wEndYear, expected_state.wEndYear);
65 ok(found_state.wEndMonth == expected_state.wEndMonth,
66 "wEndMonth: Found %d but expected %d\n",
67 found_state.wEndMonth, expected_state.wEndMonth);
69 ok(found_state.wEndDay == expected_state.wEndDay,
70 "wEndDay: Found %d but expected %d\n",
71 found_state.wEndDay, expected_state.wEndDay);
73 ok(found_state.wStartHour == expected_state.wStartHour,
74 "wStartHour: Found %d but expected %d\n",
75 found_state.wStartHour, expected_state.wStartHour);
77 ok(found_state.wStartMinute == expected_state.wStartMinute,
78 "wStartMinute: Found %d but expected %d\n",
79 found_state.wStartMinute, expected_state.wStartMinute);
81 ok(found_state.MinutesDuration == expected_state.MinutesDuration,
82 "MinutesDuration: Found %d but expected %d\n",
83 found_state.MinutesDuration, expected_state.MinutesDuration);
85 ok(found_state.MinutesInterval == expected_state.MinutesInterval,
86 "MinutesInterval: Found %d but expected %d\n",
87 found_state.MinutesInterval, expected_state.MinutesInterval);
89 ok(found_state.rgFlags == expected_state.rgFlags,
90 "rgFlags: Found %d but expected %d\n",
91 found_state.rgFlags, expected_state.rgFlags);
93 ok(found_state.TriggerType == expected_state.TriggerType,
94 "TriggerType: Found %d but expected %d\n",
95 found_state.TriggerType, expected_state.TriggerType);
97 ok(found_state.Type.Daily.DaysInterval == expected_state.Type.Daily.DaysInterval,
98 "Type.Daily.DaysInterval: Found %d but expected %d\n",
99 found_state.Type.Daily.DaysInterval, expected_state.Type.Daily.DaysInterval);
101 ok(found_state.Reserved2 == expected_state.Reserved2,
102 "Reserved2: Found %d but expected %d\n",
103 found_state.Reserved2, expected_state.Reserved2);
105 ok(found_state.wRandomMinutesInterval == expected_state.wRandomMinutesInterval,
106 "wRandomMinutesInterval: Found %d but expected %d\n",
107 found_state.wRandomMinutesInterval, expected_state.wRandomMinutesInterval);
109 return TRUE;
112 static void test_SetTrigger_GetTrigger(void)
114 static const WCHAR task_name[] = { 'T','e','s','t','i','n','g',0 };
115 ITask *test_task;
116 ITaskTrigger *test_trigger;
117 HRESULT hres;
118 WORD idx;
119 TASK_TRIGGER trigger_state;
120 TASK_TRIGGER empty_trigger_state = {
121 sizeof(trigger_state), 0,
122 0, 0, 0,
123 0, 0, 0,
124 0, 0, 0, 0,
125 TASK_TRIGGER_FLAG_DISABLED, TASK_TIME_TRIGGER_DAILY, {{1}},
126 0, 0
128 TASK_TRIGGER normal_trigger_state = {
129 sizeof(trigger_state), 0,
130 1980, 1, 1,
131 2980, 2, 2,
132 3, 3,
133 0, 0,
134 TASK_TRIGGER_FLAG_DISABLED, TASK_TIME_TRIGGER_DAILY, {{1}},
135 0, 0
137 SYSTEMTIME time;
139 hres = ITaskScheduler_NewWorkItem(test_task_scheduler, task_name, &CLSID_CTask,
140 &IID_ITask, (IUnknown **)&test_task);
141 ok(hres == S_OK, "got %#x\n", hres);
143 hres = ITask_CreateTrigger(test_task, &idx, &test_trigger);
144 ok(hres == S_OK, "got %#x\n", hres);
146 hres = ITaskTrigger_SetTrigger(test_trigger, NULL);
147 ok(hres == E_INVALIDARG, "got %#x\n", hres);
149 hres = ITaskTrigger_GetTrigger(test_trigger, NULL);
150 ok(hres == E_INVALIDARG, "got %#x\n", hres);
152 /* Setup a trigger with base values for this test run */
153 GetLocalTime(&time);
154 empty_trigger_state.wStartHour = time.wHour;
155 empty_trigger_state.wStartMinute = time.wMinute;
156 empty_trigger_state.wBeginYear = time.wYear;
157 empty_trigger_state.wBeginMonth = time.wMonth;
158 empty_trigger_state.wBeginDay = time.wDay;
160 /* Test trigger state after trigger creation but before setting * state */
161 memset(&trigger_state, 0xcf, sizeof(trigger_state));
162 trigger_state.cbTriggerSize = sizeof(trigger_state);
163 hres = ITaskTrigger_GetTrigger(test_trigger, &trigger_state);
164 ok(hres == S_OK, "Failed to set trigger: 0x%08x\n", hres);
165 compare_trigger_state(trigger_state, empty_trigger_state);
167 /* Test setting basic empty trigger */
168 hres = ITaskTrigger_SetTrigger(test_trigger, &empty_trigger_state);
169 ok(hres == S_OK, "Failed to set trigger: 0x%08x\n", hres);
170 memset(&trigger_state, 0xcf, sizeof(trigger_state));
171 trigger_state.cbTriggerSize = sizeof(trigger_state);
172 hres = ITaskTrigger_GetTrigger(test_trigger, &trigger_state);
173 ok(hres == S_OK, "Failed to GetTrigger\n");
174 compare_trigger_state(trigger_state, empty_trigger_state);
176 /* Test setting basic non-empty trigger */
177 hres = ITaskTrigger_SetTrigger(test_trigger, &normal_trigger_state);
178 ok(hres == S_OK, "Failed to set trigger: 0x%08x\n", hres);
179 memset(&trigger_state, 0xcf, sizeof(trigger_state));
180 trigger_state.cbTriggerSize = sizeof(trigger_state);
181 hres = ITaskTrigger_GetTrigger(test_trigger, &trigger_state);
182 ok(hres == S_OK, "Failed to GetTrigger\n");
183 compare_trigger_state(trigger_state, normal_trigger_state);
185 /* The following tests modify the normal_trigger_state structure
186 * before each test, and return the normal_trigger_state structure
187 * back to its original valid state after each test. This keeps
188 * each test run independent. */
190 /* Test setting trigger with invalid cbTriggerSize */
191 normal_trigger_state.cbTriggerSize = sizeof(trigger_state) - 1;
192 hres = ITaskTrigger_SetTrigger(test_trigger, &normal_trigger_state);
193 ok(hres == E_INVALIDARG, "Expected E_INVALIDARG: 0x%08x\n", hres);
194 normal_trigger_state.cbTriggerSize = sizeof(trigger_state) + 1;
195 hres = ITaskTrigger_SetTrigger(test_trigger, &normal_trigger_state);
196 ok(hres == E_INVALIDARG, "Expected E_INVALIDARG: 0x%08x\n", hres);
197 normal_trigger_state.cbTriggerSize = sizeof(trigger_state);
199 /* Test setting trigger with invalid Reserved fields */
200 normal_trigger_state.Reserved1 = 80;
201 normal_trigger_state.Reserved2 = 80;
202 hres = ITaskTrigger_SetTrigger(test_trigger, &normal_trigger_state);
203 ok(hres == S_OK, "Failed to set trigger: 0x%08x\n", hres);
204 memset(&trigger_state, 0xcf, sizeof(trigger_state));
205 trigger_state.cbTriggerSize = sizeof(trigger_state);
206 hres = ITaskTrigger_GetTrigger(test_trigger, &trigger_state);
207 ok(hres == S_OK, "Expected S_OK: 0x%08x\n", hres);
208 ok(trigger_state.Reserved1 == 0 && trigger_state.Reserved2 == 0,
209 "Reserved fields should be set to zero\n");
210 normal_trigger_state.Reserved1 = 0;
211 normal_trigger_state.Reserved2 = 0;
213 /* Test setting trigger with invalid month */
214 normal_trigger_state.wBeginMonth = 0;
215 hres = ITaskTrigger_SetTrigger(test_trigger, &normal_trigger_state);
216 ok(hres == E_INVALIDARG, "Expected E_INVALIDARG: 0x%08x\n", hres);
217 normal_trigger_state.wBeginMonth = 13;
218 hres = ITaskTrigger_SetTrigger(test_trigger, &normal_trigger_state);
219 ok(hres == E_INVALIDARG, "Expected E_INVALIDARG: 0x%08x\n", hres);
220 normal_trigger_state.wBeginMonth = 1;
222 /* Test setting trigger with invalid begin date */
223 normal_trigger_state.wBeginDay = 0;
224 hres = ITaskTrigger_SetTrigger(test_trigger, &normal_trigger_state);
225 ok(hres == E_INVALIDARG, "Expected E_INVALIDARG: 0x%08x\n", hres);
226 normal_trigger_state.wBeginDay = 32;
227 hres = ITaskTrigger_SetTrigger(test_trigger, &normal_trigger_state);
228 ok(hres == E_INVALIDARG, "Expected E_INVALIDARG: 0x%08x\n", hres);
229 normal_trigger_state.wBeginMonth = 2;
230 normal_trigger_state.wBeginDay = 30;
231 hres = ITaskTrigger_SetTrigger(test_trigger, &normal_trigger_state);
232 ok(hres == E_INVALIDARG, "Expected E_INVALIDARG: 0x%08x\n", hres);
233 normal_trigger_state.wBeginMonth = 1;
234 normal_trigger_state.wBeginDay = 1;
236 /* Test setting trigger invalid end date */
237 normal_trigger_state.wEndYear = 0;
238 normal_trigger_state.wEndMonth = 200;
239 normal_trigger_state.wEndDay = 200;
240 hres = ITaskTrigger_SetTrigger(test_trigger, &normal_trigger_state);
241 ok(hres == S_OK, "Failed to set trigger: 0x%08x\n", hres);
242 memset(&trigger_state, 0xcf, sizeof(trigger_state));
243 trigger_state.cbTriggerSize = sizeof(trigger_state);
244 hres = ITaskTrigger_GetTrigger(test_trigger, &trigger_state);
245 ok(hres == S_OK, "Expected S_OK: 0x%08x\n", hres);
246 ok(trigger_state.wEndYear == 0, "End year should be 0: %d\n",
247 trigger_state.wEndYear);
248 ok(trigger_state.wEndMonth == 200, "End month should be 200: %d\n",
249 trigger_state.wEndMonth);
250 ok(trigger_state.wEndDay == 200, "End day should be 200: %d\n",
251 trigger_state.wEndDay);
252 normal_trigger_state.rgFlags =
253 TASK_TRIGGER_FLAG_DISABLED | TASK_TRIGGER_FLAG_HAS_END_DATE;
254 hres = ITaskTrigger_SetTrigger(test_trigger, &normal_trigger_state);
255 ok(hres == E_INVALIDARG, "Expected E_INVALIDARG: 0x%08x\n", hres);
256 normal_trigger_state.rgFlags = TASK_TRIGGER_FLAG_DISABLED;
257 normal_trigger_state.wEndYear = 2980;
258 normal_trigger_state.wEndMonth = 1;
259 normal_trigger_state.wEndDay = 1;
261 /* Test setting trigger with invalid hour or minute*/
262 normal_trigger_state.wStartHour = 24;
263 hres = ITaskTrigger_SetTrigger(test_trigger, &normal_trigger_state);
264 ok(hres == E_INVALIDARG, "Expected E_INVALIDARG: 0x%08x\n", hres);
265 normal_trigger_state.wStartHour = 60;
266 hres = ITaskTrigger_SetTrigger(test_trigger, &normal_trigger_state);
267 ok(hres == E_INVALIDARG, "Expected E_INVALIDARG: 0x%08x\n", hres);
268 normal_trigger_state.wStartHour = 3;
270 /* Test setting trigger with invalid duration / interval pairs */
271 normal_trigger_state.MinutesDuration = 5;
272 normal_trigger_state.MinutesInterval = 5;
273 hres = ITaskTrigger_SetTrigger(test_trigger, &normal_trigger_state);
274 ok(hres == E_INVALIDARG, "Expected E_INVALIDARG: 0x%08x\n", hres);
275 normal_trigger_state.MinutesDuration = 5;
276 normal_trigger_state.MinutesInterval = 6;
277 hres = ITaskTrigger_SetTrigger(test_trigger, &normal_trigger_state);
278 ok(hres == E_INVALIDARG, "Expected E_INVALIDARG: 0x%08x\n", hres);
279 normal_trigger_state.MinutesDuration = 0;
280 normal_trigger_state.MinutesInterval = 6;
281 hres = ITaskTrigger_SetTrigger(test_trigger, &normal_trigger_state);
282 ok(hres == E_INVALIDARG, "Expected E_INVALIDARG: 0x%08x\n", hres);
283 normal_trigger_state.MinutesDuration = 5;
284 normal_trigger_state.MinutesInterval = 0;
285 hres = ITaskTrigger_SetTrigger(test_trigger, &normal_trigger_state);
286 ok(hres == S_OK, "Failed to set trigger: 0x%08x\n", hres);
287 normal_trigger_state.MinutesDuration = 0;
288 normal_trigger_state.MinutesInterval = 0;
290 /* Test setting trigger with end date before start date */
291 normal_trigger_state.wEndYear = 1979;
292 hres = ITaskTrigger_SetTrigger(test_trigger, &normal_trigger_state);
293 ok(hres == S_OK, "Failed to set trigger: 0x%08x\n", hres);
294 normal_trigger_state.rgFlags =
295 TASK_TRIGGER_FLAG_DISABLED | TASK_TRIGGER_FLAG_HAS_END_DATE;
296 hres = ITaskTrigger_SetTrigger(test_trigger, &normal_trigger_state);
297 ok(hres == S_OK, "Failed to set trigger: 0x%08x\n", hres);
298 normal_trigger_state.rgFlags = TASK_TRIGGER_FLAG_DISABLED;
299 normal_trigger_state.wEndYear = 2980;
300 normal_trigger_state.wEndMonth = 1;
301 normal_trigger_state.wEndDay = 1;
304 /* Test setting trigger with invalid TriggerType and Type */
305 normal_trigger_state.TriggerType = TASK_TIME_TRIGGER_ONCE;
306 normal_trigger_state.Type.Weekly.WeeksInterval = 2;
307 normal_trigger_state.Type.Weekly.rgfDaysOfTheWeek = (TASK_MONDAY | TASK_TUESDAY);
308 hres = ITaskTrigger_SetTrigger(test_trigger, &normal_trigger_state);
309 ok(hres == S_OK, "Failed to set trigger: 0x%08x\n", hres);
310 memset(&trigger_state, 0xcf, sizeof(trigger_state));
311 trigger_state.cbTriggerSize = sizeof(trigger_state);
312 hres = ITaskTrigger_GetTrigger(test_trigger, &trigger_state);
313 ok(hres == S_OK, "Expected S_OK: 0x%08x\n", hres);
314 ok(trigger_state.Type.Weekly.WeeksInterval == 0xcfcf,
315 "Expected WeeksInterval set remain untouched: %d\n",
316 trigger_state.Type.Weekly.WeeksInterval);
317 ok(trigger_state.Type.Weekly.rgfDaysOfTheWeek == 0xcfcf,
318 "Expected WeeksInterval set remain untouched: %d\n",
319 trigger_state.Type.Weekly.rgfDaysOfTheWeek);
320 normal_trigger_state.TriggerType = TASK_TIME_TRIGGER_DAILY;
321 normal_trigger_state.Type.Daily.DaysInterval = 1;
322 hres = ITaskTrigger_SetTrigger(test_trigger, &normal_trigger_state);
323 ok(hres == S_OK, "Expected S_OK: 0x%08x\n", hres);
325 /* Test setting trigger with set wRandomMinutesInterval */
326 normal_trigger_state.wRandomMinutesInterval = 5;
327 hres = ITaskTrigger_SetTrigger(test_trigger, &normal_trigger_state);
328 ok(hres == S_OK, "Failed to set trigger: 0x%08x\n", hres);
329 memset(&trigger_state, 0xcf, sizeof(trigger_state));
330 trigger_state.cbTriggerSize = sizeof(trigger_state);
331 hres = ITaskTrigger_GetTrigger(test_trigger, &trigger_state);
332 ok(hres == S_OK, "Expected S_OK: 0x%08x\n", hres);
333 ok(trigger_state.wRandomMinutesInterval == 0,
334 "wRandomMinutesInterval should be set to zero\n");
335 normal_trigger_state.wRandomMinutesInterval = 0;
337 /* Test GetTrigger using invalid cbTriggerSiz in pTrigger. In
338 * contrast to available documentation, this succeeds in practice. */
339 hres = ITaskTrigger_SetTrigger(test_trigger, &normal_trigger_state);
340 ok(hres == S_OK, "Failed to set trigger: 0x%08x\n", hres);
341 memset(&trigger_state, 0xcf, sizeof(trigger_state));
342 trigger_state.cbTriggerSize = sizeof(trigger_state) - 1;
343 hres = ITaskTrigger_GetTrigger(test_trigger, &trigger_state);
344 ok(hres == S_OK, "Failed to GetTrigger\n");
345 ok(compare_trigger_state(trigger_state, normal_trigger_state),
346 "Invalid state\n");
347 memset(&trigger_state, 0xcf, sizeof(trigger_state));
348 trigger_state.cbTriggerSize = 0;
349 hres = ITaskTrigger_GetTrigger(test_trigger, &trigger_state);
350 ok(hres == S_OK, "Failed to GetTrigger\n");
351 ok(compare_trigger_state(trigger_state, normal_trigger_state),
352 "Invalid state\n");
354 ITaskTrigger_Release(test_trigger);
355 ITask_Release(test_task);
358 static void test_task_trigger(void)
360 static const WCHAR task_name[] = { 'T','e','s','t','i','n','g',0 };
361 HRESULT hr;
362 ITask *task;
363 ITaskTrigger *trigger, *trigger2;
364 WORD count, idx;
365 DWORD ref;
367 hr = ITaskScheduler_NewWorkItem(test_task_scheduler, task_name, &CLSID_CTask,
368 &IID_ITask, (IUnknown **)&task);
369 ok(hr == S_OK, "got %#x\n", hr);
371 count = 0xdead;
372 hr = ITask_GetTriggerCount(task, &count);
373 ok(hr == S_OK, "got %#x\n", hr);
374 ok(count == 0, "got %u\n", count);
376 hr = ITask_DeleteTrigger(task, 0);
377 ok(hr == SCHED_E_TRIGGER_NOT_FOUND, "got %#x\n", hr);
379 hr = ITask_GetTrigger(task, 0, &trigger);
380 ok(hr == SCHED_E_TRIGGER_NOT_FOUND, "got %#x\n", hr);
382 idx = 0xdead;
383 hr = ITask_CreateTrigger(task, &idx, &trigger);
384 ok(hr == S_OK, "got %#x\n", hr);
385 ok(idx == 0, "got %u\n", idx);
387 hr = ITask_GetTrigger(task, 0, &trigger2);
388 ok(hr == S_OK, "got %#x\n", hr);
389 ok(trigger != trigger2, "%p != %p\n", trigger, trigger2);
391 ref = ITaskTrigger_Release(trigger2);
392 ok(ref == 0, "got %u\n", ref);
394 ref = ITaskTrigger_Release(trigger);
395 ok(ref == 0, "got %u\n", ref);
397 count = 0xdead;
398 hr = ITask_GetTriggerCount(task, &count);
399 ok(hr == S_OK, "got %#x\n", hr);
400 ok(count == 1, "got %u\n", count);
402 hr = ITask_DeleteTrigger(task, 0);
403 ok(hr == S_OK, "got %#x\n", hr);
405 idx = 0xdead;
406 hr = ITask_CreateTrigger(task, &idx, &trigger);
407 ok(hr == S_OK, "got %#x\n", hr);
408 ok(idx == 0, "got %u\n", idx);
410 hr = ITask_DeleteTrigger(task, 0);
411 ok(hr == S_OK, "got %#x\n", hr);
413 count = 0xdead;
414 hr = ITask_GetTriggerCount(task, &count);
415 ok(hr == S_OK, "got %#x\n", hr);
416 ok(count == 0, "got %u\n", count);
418 ref = ITaskTrigger_Release(trigger);
419 ok(ref == 0, "got %u\n", ref);
421 ref = ITask_Release(task);
422 ok(ref == 0, "got %u\n", ref);
425 static void time_add_ms(SYSTEMTIME *st, DWORD ms)
427 union
429 FILETIME ft;
430 ULONGLONG ll;
431 } ftll;
432 BOOL ret;
434 trace("old: %u/%u/%u wday %u %u:%02u:%02u.%03u\n",
435 st->wDay, st->wMonth, st->wYear, st->wDayOfWeek,
436 st->wHour, st->wMinute, st->wSecond, st->wMilliseconds);
437 ret = SystemTimeToFileTime(st, &ftll.ft);
438 ok(ret, "SystemTimeToFileTime error %u\n", GetLastError());
440 ftll.ll += ms * (ULONGLONG)10000;
441 ret = FileTimeToSystemTime(&ftll.ft, st);
442 ok(ret, "FileTimeToSystemTime error %u\n", GetLastError());
443 trace("new: %u/%u/%u wday %u %u:%02u:%02u.%03u\n",
444 st->wDay, st->wMonth, st->wYear, st->wDayOfWeek,
445 st->wHour, st->wMinute, st->wSecond, st->wMilliseconds);
448 static void trigger_add_ms(TASK_TRIGGER *data, DWORD ms, SYSTEMTIME *ret)
450 SYSTEMTIME st;
452 st.wYear = data->wBeginYear;
453 st.wMonth = data->wBeginMonth;
454 st.wDayOfWeek = 0;
455 st.wDay = data->wBeginDay;
456 st.wHour = data->wStartHour;
457 st.wMinute = data->wStartMinute;
458 st.wSecond = 0;
459 st.wMilliseconds = 0;
461 time_add_ms(&st, ms);
463 data->wBeginYear = st.wYear;
464 data->wBeginMonth = st.wMonth;
465 data->wBeginDay = st.wDay;
466 data->wStartHour = st.wHour;
467 data->wStartMinute = st.wMinute;
469 *ret = st;
472 static void test_GetNextRunTime(void)
474 static const WCHAR task_name[] = { 'T','e','s','t','i','n','g',0 };
475 static const SYSTEMTIME st_empty;
476 HRESULT hr;
477 ITask *task;
478 ITaskTrigger *trigger;
479 TASK_TRIGGER data;
480 WORD idx;
481 SYSTEMTIME st, cmp;
483 hr = ITaskScheduler_NewWorkItem(test_task_scheduler, task_name, &CLSID_CTask,
484 &IID_ITask, (IUnknown **)&task);
485 ok(hr == S_OK, "got %#x\n", hr);
487 if (0) /* crashes under Windows */
488 hr = ITask_GetNextRunTime(task, NULL);
490 hr = ITask_SetFlags(task, TASK_FLAG_DISABLED);
491 ok(hr == S_OK, "got %#x\n", hr);
493 memset(&st, 0xff, sizeof(st));
494 hr = ITask_GetNextRunTime(task, &st);
495 ok(hr == SCHED_S_TASK_DISABLED, "got %#x\n", hr);
496 ok(!memcmp(&st, &st_empty, sizeof(st)), "got %u/%u/%u wday %u %u:%02u:%02u\n",
497 st.wDay, st.wMonth, st.wYear, st.wDayOfWeek,
498 st.wHour, st.wMinute, st.wSecond);
500 hr = ITask_SetFlags(task, 0);
501 ok(hr == S_OK, "got %#x\n", hr);
503 memset(&st, 0xff, sizeof(st));
504 hr = ITask_GetNextRunTime(task, &st);
505 ok(hr == SCHED_S_TASK_NO_VALID_TRIGGERS, "got %#x\n", hr);
506 ok(!memcmp(&st, &st_empty, sizeof(st)), "got %u/%u/%u wday %u %u:%02u:%02u\n",
507 st.wDay, st.wMonth, st.wYear, st.wDayOfWeek,
508 st.wHour, st.wMinute, st.wSecond);
510 hr = ITask_CreateTrigger(task, &idx, &trigger);
511 ok(hr == S_OK, "got %#x\n", hr);
513 memset(&st, 0xff, sizeof(st));
514 hr = ITask_GetNextRunTime(task, &st);
515 ok(hr == SCHED_S_TASK_NO_VALID_TRIGGERS, "got %#x\n", hr);
516 ok(!memcmp(&st, &st_empty, sizeof(st)), "got %u/%u/%u wday %u %u:%02u:%02u\n",
517 st.wDay, st.wMonth, st.wYear, st.wDayOfWeek,
518 st.wHour, st.wMinute, st.wSecond);
520 /* TASK_TIME_TRIGGER_ONCE */
522 hr = ITaskTrigger_GetTrigger(trigger, &data);
523 ok(hr == S_OK, "got %#x\n", hr);
524 data.rgFlags &= ~TASK_TRIGGER_FLAG_DISABLED;
525 data.TriggerType = TASK_TIME_TRIGGER_ONCE;
526 /* add 5 minutes to avoid races */
527 trigger_add_ms(&data, 5 * 60 * 1000, &cmp);
528 hr = ITaskTrigger_SetTrigger(trigger, &data);
529 ok(hr == S_OK, "got %#x\n", hr);
531 memset(&st, 0xff, sizeof(st));
532 hr = ITask_GetNextRunTime(task, &st);
533 ok(hr == S_OK, "got %#x\n", hr);
534 ok(!memcmp(&st, &cmp, sizeof(st)), "got %u/%u/%u wday %u %u:%02u:%02u\n",
535 st.wDay, st.wMonth, st.wYear, st.wDayOfWeek,
536 st.wHour, st.wMinute, st.wSecond);
538 /* TASK_TIME_TRIGGER_DAILY */
540 hr = ITaskTrigger_GetTrigger(trigger, &data);
541 ok(hr == S_OK, "got %#x\n", hr);
542 data.rgFlags &= ~TASK_TRIGGER_FLAG_DISABLED;
543 data.TriggerType = TASK_TIME_TRIGGER_DAILY;
544 data.Type.Daily.DaysInterval = 1;
545 hr = ITaskTrigger_SetTrigger(trigger, &data);
546 ok(hr == S_OK, "got %#x\n", hr);
548 memset(&st, 0xff, sizeof(st));
549 hr = ITask_GetNextRunTime(task, &st);
550 ok(hr == S_OK, "got %#x\n", hr);
551 ok(!memcmp(&st, &cmp, sizeof(st)), "got %u/%u/%u wday %u %u:%02u:%02u\n",
552 st.wDay, st.wMonth, st.wYear, st.wDayOfWeek,
553 st.wHour, st.wMinute, st.wSecond);
555 /* FIXME: TASK_TIME_TRIGGER_WEEKLY */
556 /* FIXME: TASK_TIME_TRIGGER_MONTHLYDATE */
557 /* FIXME: TASK_TIME_TRIGGER_MONTHLYDOW */
559 ITaskTrigger_Release(trigger);
560 ITask_Release(task);
563 static HRESULT get_task_trigger(ITask *task, WORD idx, TASK_TRIGGER *state)
565 HRESULT hr;
566 ITaskTrigger *trigger;
568 hr = ITask_GetTrigger(task, idx, &trigger);
569 if (hr != S_OK) return hr;
571 memset(state, 0x11, sizeof(*state));
572 hr = ITaskTrigger_GetTrigger(trigger, state);
574 ITaskTrigger_Release(trigger);
575 return hr;
578 static void test_trigger_manager(void)
580 static const WCHAR task_name[] = { 'T','e','s','t','i','n','g',0 };
581 HRESULT hr;
582 ITask *task;
583 ITaskTrigger *trigger0, *trigger1;
584 TASK_TRIGGER state0, state1, state;
585 WORD count, idx;
586 DWORD ref;
588 hr = ITaskScheduler_NewWorkItem(test_task_scheduler, task_name, &CLSID_CTask,
589 &IID_ITask, (IUnknown **)&task);
590 ok(hr == S_OK, "got %#x\n", hr);
591 ok(obj_refcount(task) == 1, "got %u\n", obj_refcount(task));
593 count = 0xdead;
594 hr = ITask_GetTriggerCount(task, &count);
595 ok(hr == S_OK, "got %#x\n", hr);
596 ok(count == 0, "got %u\n", count);
598 idx = 0xdead;
599 hr = ITask_CreateTrigger(task, &idx, &trigger0);
600 ok(hr == S_OK, "got %#x\n", hr);
601 ok(idx == 0, "got %u\n", idx);
602 ok(obj_refcount(task) == 2, "got %u\n", obj_refcount(task));
604 idx = 0xdead;
605 hr = ITask_CreateTrigger(task, &idx, &trigger1);
606 ok(hr == S_OK, "got %#x\n", hr);
607 ok(idx == 1, "got %u\n", idx);
608 ok(obj_refcount(task) == 3, "got %u\n", obj_refcount(task));
610 count = 0xdead;
611 hr = ITask_GetTriggerCount(task, &count);
612 ok(hr == S_OK, "got %#x\n", hr);
613 ok(count == 2, "got %u\n", count);
615 hr = ITaskTrigger_GetTrigger(trigger0, &state0);
616 ok(hr == S_OK, "got %#x\n", hr);
617 state0.wBeginYear = 3000;
618 state0.rgFlags = 0;
619 state0.TriggerType = TASK_TIME_TRIGGER_ONCE;
620 hr = ITaskTrigger_SetTrigger(trigger0, &state0);
621 ok(hr == S_OK, "got %#x\n", hr);
623 hr = get_task_trigger(task, 0, &state);
624 ok(hr == S_OK, "got %#x\n", hr);
625 ok(state.wBeginYear == 3000, "got %u\n", state.wBeginYear);
626 ok(state.TriggerType == TASK_TIME_TRIGGER_ONCE, "got %u\n", state.TriggerType);
628 hr = ITaskTrigger_GetTrigger(trigger1, &state1);
629 ok(hr == S_OK, "got %#x\n", hr);
630 state1.wBeginYear = 2000;
631 state1.rgFlags = 0;
632 state1.TriggerType = TASK_TIME_TRIGGER_DAILY;
633 hr = ITaskTrigger_SetTrigger(trigger1, &state1);
634 ok(hr == S_OK, "got %#x\n", hr);
636 hr = get_task_trigger(task, 1, &state);
637 ok(hr == S_OK, "got %#x\n", hr);
638 ok(state.wBeginYear == 2000, "got %u\n", state.wBeginYear);
639 ok(state.TriggerType == TASK_TIME_TRIGGER_DAILY, "got %u\n", state.TriggerType);
641 ref = ITaskTrigger_Release(trigger0);
642 ok(ref == 0, "got %u\n", ref);
643 ref = ITaskTrigger_Release(trigger1);
644 ok(ref == 0, "got %u\n", ref);
646 ok(obj_refcount(task) == 1, "got %u\n", obj_refcount(task));
648 hr = get_task_trigger(task, 0, &state);
649 ok(hr == S_OK, "got %#x\n", hr);
650 ok(state.wBeginYear == 3000, "got %u\n", state.wBeginYear);
651 ok(state.TriggerType == TASK_TIME_TRIGGER_ONCE, "got %u\n", state.TriggerType);
653 hr = get_task_trigger(task, 1, &state);
654 ok(hr == S_OK, "got %#x\n", hr);
655 ok(state.wBeginYear == 2000, "got %u\n", state.wBeginYear);
656 ok(state.TriggerType == TASK_TIME_TRIGGER_DAILY, "got %u\n", state.TriggerType);
658 hr = ITask_GetTrigger(task, 0, &trigger0);
659 ok(hr == S_OK, "got %#x\n", hr);
660 hr = ITask_GetTrigger(task, 1, &trigger1);
661 ok(hr == S_OK, "got %#x\n", hr);
663 hr = ITask_DeleteTrigger(task, 0);
664 ok(hr == S_OK, "got %#x\n", hr);
666 hr = get_task_trigger(task, 0, &state);
667 ok(hr == S_OK, "got %#x\n", hr);
668 ok(state.wBeginYear == 2000, "got %u\n", state.wBeginYear);
669 ok(state.TriggerType == TASK_TIME_TRIGGER_DAILY, "got %u\n", state.TriggerType);
671 hr = get_task_trigger(task, 1, &state);
672 ok(hr == SCHED_E_TRIGGER_NOT_FOUND, "got %#x\n", hr);
674 hr = ITaskTrigger_SetTrigger(trigger0, &state0);
675 ok(hr == S_OK, "got %#x\n", hr);
677 hr = ITaskTrigger_SetTrigger(trigger1, &state1);
678 ok(hr == E_FAIL, "got %#x\n", hr);
680 count = 0xdead;
681 hr = ITask_GetTriggerCount(task, &count);
682 ok(hr == S_OK, "got %#x\n", hr);
683 ok(count == 1, "got %u\n", count);
685 ok(obj_refcount(task) == 3, "got %u\n", obj_refcount(task));
687 ref = ITaskTrigger_Release(trigger0);
688 ok(ref == 0, "got %u\n", ref);
690 ref = ITaskTrigger_Release(trigger1);
691 ok(ref == 0, "got %u\n", ref);
693 ref = ITask_Release(task);
694 ok(ref == 0, "got %u\n", ref);
697 START_TEST(task_trigger)
699 HRESULT hr;
701 CoInitialize(NULL);
703 hr = CoCreateInstance(&CLSID_CTaskScheduler, NULL, CLSCTX_INPROC_SERVER,
704 &IID_ITaskScheduler, (void **)&test_task_scheduler);
705 ok(hr == S_OK, "error creating TaskScheduler instance %#x\n", hr);
707 test_SetTrigger_GetTrigger();
708 test_task_trigger();
709 test_GetNextRunTime();
710 test_trigger_manager();
712 ITaskScheduler_Release(test_task_scheduler);
713 CoUninitialize();