Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/mstask/task.c | 39 +++++++++++++++++++++++++++++++++++++++ dlls/mstask/tests/task_trigger.c | 22 +++++++++++++++++++++- 2 files changed, 60 insertions(+), 1 deletion(-)
diff --git a/dlls/mstask/task.c b/dlls/mstask/task.c index 57ad0f7005..147050224c 100644 --- a/dlls/mstask/task.c +++ b/dlls/mstask/task.c @@ -466,6 +466,11 @@ static void filetime_add_days(FILETIME *ft, ULONG days) filetime_add_hours(ft, (ULONGLONG)days * 24); }
+static void filetime_add_weeks(FILETIME *ft, ULONG weeks) +{ + filetime_add_days(ft, (ULONGLONG)weeks * 7); +} + static HRESULT WINAPI MSTASK_ITask_GetNextRunTime(ITask *iface, SYSTEMTIME *rt) { TaskImpl *This = impl_from_ITask(iface); @@ -540,6 +545,40 @@ static HRESULT WINAPI MSTASK_ITask_GetNextRunTime(ITask *iface, SYSTEMTIME *rt) } break;
+ case TASK_TIME_TRIGGER_WEEKLY: + if (!This->trigger[i].Type.Weekly.rgfDaysOfTheWeek) + break; /* avoid infinite loop */ + + st = current_st; + st.wHour = This->trigger[i].wStartHour; + st.wMinute = This->trigger[i].wStartMinute; + st.wSecond = 0; + st.wMilliseconds = 0; + SystemTimeToFileTime(&st, ¤t_ft); + while (CompareFileTime(¤t_ft, &end_ft) < 0) + { + FileTimeToSystemTime(¤t_ft, &st); + + if (CompareFileTime(¤t_ft, &begin_ft) >= 0) + { + if (This->trigger[i].Type.Weekly.rgfDaysOfTheWeek & (1 << st.wDayOfWeek)) + { + if (!have_best_time || CompareFileTime(¤t_ft, &best_ft) < 0) + { + best_ft = current_ft; + have_best_time = TRUE; + } + break; + } + } + + if (st.wDayOfWeek == 0) /* Sunday, goto next week */ + filetime_add_weeks(¤t_ft, This->trigger[i].Type.Weekly.WeeksInterval - 1); + else /* check next weekday */ + filetime_add_days(¤t_ft, 1); + } + break; + default: FIXME("trigger type %u is not handled\n", This->trigger[i].TriggerType); break; diff --git a/dlls/mstask/tests/task_trigger.c b/dlls/mstask/tests/task_trigger.c index 328cae25fd..168d6f3421 100644 --- a/dlls/mstask/tests/task_trigger.c +++ b/dlls/mstask/tests/task_trigger.c @@ -552,7 +552,27 @@ static void test_GetNextRunTime(void) st.wDay, st.wMonth, st.wYear, st.wDayOfWeek, st.wHour, st.wMinute, st.wSecond);
- /* FIXME: TASK_TIME_TRIGGER_WEEKLY */ + /* TASK_TIME_TRIGGER_WEEKLY */ + + hr = ITaskTrigger_GetTrigger(trigger, &data); + ok(hr == S_OK, "got %#x\n", hr); + data.rgFlags &= ~TASK_TRIGGER_FLAG_DISABLED; + data.TriggerType = TASK_TIME_TRIGGER_WEEKLY; + data.Type.Weekly.WeeksInterval = 1; + /* add 3 days */ + time_add_ms(&cmp, 3 * 24 * 60 * 60 * 1000); + /* bits: TASK_SUNDAY = 1, TASK_MONDAY = 2, TASK_TUESDAY = 4, etc. */ + data.Type.Weekly.rgfDaysOfTheWeek = 1 << cmp.wDayOfWeek; /* wDayOfWeek is 0 based */ + hr = ITaskTrigger_SetTrigger(trigger, &data); + ok(hr == S_OK, "got %#x\n", hr); + + memset(&st, 0xff, sizeof(st)); + hr = ITask_GetNextRunTime(task, &st); + ok(hr == S_OK, "got %#x\n", hr); + ok(!memcmp(&st, &cmp, sizeof(st)), "got %u/%u/%u wday %u %u:%02u:%02u\n", + st.wDay, st.wMonth, st.wYear, st.wDayOfWeek, + st.wHour, st.wMinute, st.wSecond); + /* FIXME: TASK_TIME_TRIGGER_MONTHLYDATE */ /* FIXME: TASK_TIME_TRIGGER_MONTHLYDOW */