Dmitry Timoshkov : mstask: Implement ITask::GetNextRunTime() for ONCE trigger type.
Alexandre Julliard
julliard at winehq.org
Mon May 21 17:15:10 CDT 2018
Module: wine
Branch: master
Commit: ac322334fa4d6740e89c6f19361a66f063103a46
URL: https://source.winehq.org/git/wine.git/?a=commit;h=ac322334fa4d6740e89c6f19361a66f063103a46
Author: Dmitry Timoshkov <dmitry at baikal.ru>
Date: Mon May 21 18:17:47 2018 +0800
mstask: Implement ITask::GetNextRunTime() for ONCE trigger type.
Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/mstask/task.c | 90 ++++++++++++++++++++++++++++++++++++++--
dlls/mstask/tests/task_trigger.c | 81 +++++++++++++++++++++++++++++++++---
2 files changed, 163 insertions(+), 8 deletions(-)
diff --git a/dlls/mstask/task.c b/dlls/mstask/task.c
index d487aeb..c004764 100644
--- a/dlls/mstask/task.c
+++ b/dlls/mstask/task.c
@@ -408,11 +408,95 @@ static HRESULT WINAPI MSTASK_ITask_GetRunTimes(
return E_NOTIMPL;
}
-static HRESULT WINAPI MSTASK_ITask_GetNextRunTime(ITask *iface, SYSTEMTIME *st)
+static void get_begin_time(const TASK_TRIGGER *trigger, FILETIME *ft)
{
- FIXME("(%p, %p): stub\n", iface, st);
+ SYSTEMTIME st;
- memset(st, 0, sizeof(*st));
+ st.wYear = trigger->wBeginYear;
+ st.wMonth = trigger->wBeginMonth;
+ st.wDay = trigger->wBeginDay;
+ st.wDayOfWeek = 0;
+ st.wHour = 0;
+ st.wMinute = 0;
+ st.wSecond = 0;
+ st.wMilliseconds = 0;
+ SystemTimeToFileTime(&st, ft);
+}
+
+static void get_end_time(const TASK_TRIGGER *trigger, FILETIME *ft)
+{
+ SYSTEMTIME st;
+
+ if (!(trigger->rgFlags & TASK_TRIGGER_FLAG_HAS_END_DATE))
+ {
+ ft->dwHighDateTime = ~0u;
+ ft->dwLowDateTime = ~0u;
+ return;
+ }
+
+ st.wYear = trigger->wEndYear;
+ st.wMonth = trigger->wEndMonth;
+ st.wDay = trigger->wEndDay;
+ st.wDayOfWeek = 0;
+ st.wHour = 0;
+ st.wMinute = 0;
+ st.wSecond = 0;
+ st.wMilliseconds = 0;
+ SystemTimeToFileTime(&st, ft);
+}
+
+static HRESULT WINAPI MSTASK_ITask_GetNextRunTime(ITask *iface, SYSTEMTIME *rt)
+{
+ TaskImpl *This = impl_from_ITask(iface);
+ SYSTEMTIME st, current_st;
+ FILETIME current_ft, begin_ft, end_ft, best_ft;
+ BOOL have_best_time = FALSE;
+ DWORD i;
+
+ TRACE("(%p, %p)\n", iface, rt);
+
+ GetLocalTime(¤t_st);
+
+ for (i = 0; i < This->trigger_count; i++)
+ {
+ if (!(This->trigger[i].rgFlags & TASK_TRIGGER_FLAG_DISABLED))
+ {
+ get_begin_time(&This->trigger[i], &begin_ft);
+ get_end_time(&This->trigger[i], &end_ft);
+
+ switch (This->trigger[i].TriggerType)
+ {
+ case TASK_TIME_TRIGGER_ONCE:
+ 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);
+ if (CompareFileTime(&begin_ft, ¤t_ft) <= 0 && CompareFileTime(¤t_ft, &end_ft) < 0)
+ {
+ if (!have_best_time || CompareFileTime(¤t_ft, &best_ft) < 0)
+ {
+ best_ft = current_ft;
+ have_best_time = TRUE;
+ }
+ }
+ break;
+
+ default:
+ FIXME("trigger type %u is not handled\n", This->trigger[i].TriggerType);
+ break;
+ }
+ }
+ }
+
+ if (have_best_time)
+ {
+ FileTimeToSystemTime(&best_ft, rt);
+ return S_OK;
+ }
+
+ memset(rt, 0, sizeof(*rt));
return SCHED_S_TASK_NO_VALID_TRIGGERS;
}
diff --git a/dlls/mstask/tests/task_trigger.c b/dlls/mstask/tests/task_trigger.c
index 9a20a56..e880ce4 100644
--- a/dlls/mstask/tests/task_trigger.c
+++ b/dlls/mstask/tests/task_trigger.c
@@ -422,6 +422,53 @@ static void test_task_trigger(void)
ok(ref == 0, "got %u\n", ref);
}
+static void time_add_ms(SYSTEMTIME *st, DWORD ms)
+{
+ union
+ {
+ FILETIME ft;
+ ULONGLONG ll;
+ } ftll;
+ BOOL ret;
+
+ trace("old: %u/%u/%u wday %u %u:%02u:%02u.%03u\n",
+ st->wDay, st->wMonth, st->wYear, st->wDayOfWeek,
+ st->wHour, st->wMinute, st->wSecond, st->wMilliseconds);
+ ret = SystemTimeToFileTime(st, &ftll.ft);
+ ok(ret, "SystemTimeToFileTime error %u\n", GetLastError());
+
+ ftll.ll += ms * (ULONGLONG)10000;
+ ret = FileTimeToSystemTime(&ftll.ft, st);
+ ok(ret, "FileTimeToSystemTime error %u\n", GetLastError());
+ trace("new: %u/%u/%u wday %u %u:%02u:%02u.%03u\n",
+ st->wDay, st->wMonth, st->wYear, st->wDayOfWeek,
+ st->wHour, st->wMinute, st->wSecond, st->wMilliseconds);
+}
+
+static void trigger_add_ms(TASK_TRIGGER *data, DWORD ms, SYSTEMTIME *ret)
+{
+ SYSTEMTIME st;
+
+ st.wYear = data->wBeginYear;
+ st.wMonth = data->wBeginMonth;
+ st.wDayOfWeek = 0;
+ st.wDay = data->wBeginDay;
+ st.wHour = data->wStartHour;
+ st.wMinute = data->wStartMinute;
+ st.wSecond = 0;
+ st.wMilliseconds = 0;
+
+ time_add_ms(&st, ms);
+
+ data->wBeginYear = st.wYear;
+ data->wBeginMonth = st.wMonth;
+ data->wBeginDay = st.wDay;
+ data->wStartHour = st.wHour;
+ data->wStartMinute = st.wMinute;
+
+ *ret = st;
+}
+
static void test_GetNextRunTime(void)
{
static const WCHAR task_name[] = { 'T','e','s','t','i','n','g',0 };
@@ -429,8 +476,9 @@ static void test_GetNextRunTime(void)
HRESULT hr;
ITask *task;
ITaskTrigger *trigger;
+ TASK_TRIGGER data;
WORD idx;
- SYSTEMTIME st;
+ SYSTEMTIME st, cmp;
hr = ITaskScheduler_NewWorkItem(test_task_scheduler, task_name, &CLSID_CTask,
&IID_ITask, (IUnknown **)&task);
@@ -442,9 +490,9 @@ static void test_GetNextRunTime(void)
memset(&st, 0xff, sizeof(st));
hr = ITask_GetNextRunTime(task, &st);
ok(hr == SCHED_S_TASK_NO_VALID_TRIGGERS, "got %#x\n", hr);
- ok(!memcmp(&st, &st_empty, sizeof(st)), "got %d/%d/%d wday %d %d:%d:%d.%03d\n",
+ ok(!memcmp(&st, &st_empty, 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, st.wMilliseconds);
+ st.wHour, st.wMinute, st.wSecond);
hr = ITask_CreateTrigger(task, &idx, &trigger);
ok(hr == S_OK, "got %#x\n", hr);
@@ -452,9 +500,32 @@ static void test_GetNextRunTime(void)
memset(&st, 0xff, sizeof(st));
hr = ITask_GetNextRunTime(task, &st);
ok(hr == SCHED_S_TASK_NO_VALID_TRIGGERS, "got %#x\n", hr);
- ok(!memcmp(&st, &st_empty, sizeof(st)), "got %d/%d/%d wday %d %d:%d:%d.%03d\n",
+ ok(!memcmp(&st, &st_empty, 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, st.wMilliseconds);
+ st.wHour, st.wMinute, st.wSecond);
+
+ /* TASK_TIME_TRIGGER_ONCE */
+
+ hr = ITaskTrigger_GetTrigger(trigger, &data);
+ ok(hr == S_OK, "got %#x\n", hr);
+ data.rgFlags &= ~TASK_TRIGGER_FLAG_DISABLED;
+ data.TriggerType = TASK_TIME_TRIGGER_ONCE;
+ /* add 5 minutes to avoid races */
+ trigger_add_ms(&data, 5 * 60 * 1000, &cmp);
+ 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_DAILY */
+ /* FIXME: TASK_TIME_TRIGGER_WEEKLY */
+ /* FIXME: TASK_TIME_TRIGGER_MONTHLYDATE */
+ /* FIXME: TASK_TIME_TRIGGER_MONTHLYDOW */
ITaskTrigger_Release(trigger);
ITask_Release(task);
More information about the wine-cvs
mailing list