2 * Copyright (C) 2008 Google (Roy Shea)
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "mstask_private.h"
22 #include "wine/debug.h"
24 WINE_DEFAULT_DEBUG_CHANNEL(mstask
);
28 ITaskTrigger ITaskTrigger_iface
;
30 TASK_TRIGGER triggerCond
;
33 static inline TaskTriggerImpl
*impl_from_ITaskTrigger(ITaskTrigger
*iface
)
35 return CONTAINING_RECORD(iface
, TaskTriggerImpl
, ITaskTrigger_iface
);
38 static HRESULT WINAPI
MSTASK_ITaskTrigger_QueryInterface(
43 TaskTriggerImpl
*This
= impl_from_ITaskTrigger(iface
);
45 TRACE("IID: %s\n", debugstr_guid(riid
));
46 if (ppvObject
== NULL
)
49 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
50 IsEqualGUID(riid
, &IID_ITaskTrigger
))
52 *ppvObject
= &This
->ITaskTrigger_iface
;
53 ITaskTrigger_AddRef(iface
);
57 WARN("Unknown interface: %s\n", debugstr_guid(riid
));
62 static ULONG WINAPI
MSTASK_ITaskTrigger_AddRef(
65 TaskTriggerImpl
*This
= impl_from_ITaskTrigger(iface
);
68 ref
= InterlockedIncrement(&This
->ref
);
72 static ULONG WINAPI
MSTASK_ITaskTrigger_Release(
75 TaskTriggerImpl
*This
= impl_from_ITaskTrigger(iface
);
78 ref
= InterlockedDecrement(&This
->ref
);
81 HeapFree(GetProcessHeap(), 0, This
);
82 InterlockedDecrement(&dll_ref
);
87 static HRESULT WINAPI
MSTASK_ITaskTrigger_SetTrigger(
89 const PTASK_TRIGGER pTrigger
)
91 TaskTriggerImpl
* This
= impl_from_ITaskTrigger(iface
);
92 TIME_FIELDS field_time
;
93 LARGE_INTEGER sys_time
;
94 TASK_TRIGGER tmp_trigger_cond
;
96 TRACE("(%p, %p)\n", iface
, pTrigger
);
98 /* Verify valid structure size */
99 if (pTrigger
->cbTriggerSize
!= sizeof(*pTrigger
))
101 tmp_trigger_cond
.cbTriggerSize
= pTrigger
->cbTriggerSize
;
103 /* Reserved field must be zero */
104 tmp_trigger_cond
.Reserved1
= 0;
106 /* Verify and set valid start date and time */
107 memset(&field_time
, 0, sizeof(field_time
));
108 field_time
.Year
= pTrigger
->wBeginYear
;
109 field_time
.Month
= pTrigger
->wBeginMonth
;
110 field_time
.Day
= pTrigger
->wBeginDay
;
111 field_time
.Hour
= pTrigger
->wStartHour
;
112 field_time
.Minute
= pTrigger
->wStartMinute
;
113 if (!RtlTimeFieldsToTime(&field_time
, &sys_time
))
115 tmp_trigger_cond
.wBeginYear
= pTrigger
->wBeginYear
;
116 tmp_trigger_cond
.wBeginMonth
= pTrigger
->wBeginMonth
;
117 tmp_trigger_cond
.wBeginDay
= pTrigger
->wBeginDay
;
118 tmp_trigger_cond
.wStartHour
= pTrigger
->wStartHour
;
119 tmp_trigger_cond
.wStartMinute
= pTrigger
->wStartMinute
;
121 /* Verify valid end date if TASK_TRIGGER_FLAG_HAS_END_DATE flag is set */
122 if (pTrigger
->rgFlags
& TASK_TRIGGER_FLAG_HAS_END_DATE
)
124 memset(&field_time
, 0, sizeof(field_time
));
125 field_time
.Year
= pTrigger
->wEndYear
;
126 field_time
.Month
= pTrigger
->wEndMonth
;
127 field_time
.Day
= pTrigger
->wEndDay
;
128 if (!RtlTimeFieldsToTime(&field_time
, &sys_time
))
132 /* Set valid end date independent of TASK_TRIGGER_FLAG_HAS_END_DATE flag */
133 tmp_trigger_cond
.wEndYear
= pTrigger
->wEndYear
;
134 tmp_trigger_cond
.wEndMonth
= pTrigger
->wEndMonth
;
135 tmp_trigger_cond
.wEndDay
= pTrigger
->wEndDay
;
137 /* Verify duration and interval pair */
138 if (pTrigger
->MinutesDuration
<= pTrigger
->MinutesInterval
&&
139 pTrigger
->MinutesInterval
> 0)
141 tmp_trigger_cond
.MinutesDuration
= pTrigger
->MinutesDuration
;
142 tmp_trigger_cond
.MinutesInterval
= pTrigger
->MinutesInterval
;
144 /* Copy over flags */
145 tmp_trigger_cond
.rgFlags
= pTrigger
->rgFlags
;
147 /* Set TriggerType dependent fields of Type union */
148 tmp_trigger_cond
.TriggerType
= pTrigger
->TriggerType
;
149 switch (pTrigger
->TriggerType
)
151 case TASK_TIME_TRIGGER_DAILY
:
152 tmp_trigger_cond
.Type
.Daily
.DaysInterval
=
153 pTrigger
->Type
.Daily
.DaysInterval
;
155 case TASK_TIME_TRIGGER_WEEKLY
:
156 tmp_trigger_cond
.Type
.Weekly
.WeeksInterval
=
157 pTrigger
->Type
.Weekly
.WeeksInterval
;
158 tmp_trigger_cond
.Type
.Weekly
.rgfDaysOfTheWeek
=
159 pTrigger
->Type
.Weekly
.rgfDaysOfTheWeek
;
161 case TASK_TIME_TRIGGER_MONTHLYDATE
:
162 tmp_trigger_cond
.Type
.MonthlyDate
.rgfDays
=
163 pTrigger
->Type
.MonthlyDate
.rgfDays
;
164 tmp_trigger_cond
.Type
.MonthlyDate
.rgfMonths
=
165 pTrigger
->Type
.MonthlyDate
.rgfMonths
;
167 case TASK_TIME_TRIGGER_MONTHLYDOW
:
168 tmp_trigger_cond
.Type
.MonthlyDOW
.wWhichWeek
=
169 pTrigger
->Type
.MonthlyDOW
.wWhichWeek
;
170 tmp_trigger_cond
.Type
.MonthlyDOW
.rgfDaysOfTheWeek
=
171 pTrigger
->Type
.MonthlyDOW
.rgfDaysOfTheWeek
;
172 tmp_trigger_cond
.Type
.MonthlyDOW
.rgfMonths
=
173 pTrigger
->Type
.MonthlyDOW
.rgfMonths
;
175 case TASK_TIME_TRIGGER_ONCE
:
176 case TASK_EVENT_TRIGGER_ON_IDLE
:
177 case TASK_EVENT_TRIGGER_AT_SYSTEMSTART
:
178 case TASK_EVENT_TRIGGER_AT_LOGON
:
180 tmp_trigger_cond
.Type
= This
->triggerCond
.Type
;
184 /* Reserved field must be zero */
185 tmp_trigger_cond
.Reserved2
= 0;
187 /* wRandomMinutesInterval not currently used and is initialized to zero */
188 tmp_trigger_cond
.wRandomMinutesInterval
= 0;
190 /* Update object copy of triggerCond */
191 This
->triggerCond
= tmp_trigger_cond
;
196 static HRESULT WINAPI
MSTASK_ITaskTrigger_GetTrigger(
198 PTASK_TRIGGER pTrigger
)
200 TaskTriggerImpl
* This
= impl_from_ITaskTrigger(iface
);
202 TRACE("(%p, %p)\n", iface
, pTrigger
);
204 /* Native implementation doesn't verify equivalent cbTriggerSize fields */
206 /* Copy relevant fields of the structure */
207 pTrigger
->cbTriggerSize
= This
->triggerCond
.cbTriggerSize
;
208 pTrigger
->Reserved1
= 0;
209 pTrigger
->wBeginYear
= This
->triggerCond
.wBeginYear
;
210 pTrigger
->wBeginMonth
= This
->triggerCond
.wBeginMonth
;
211 pTrigger
->wBeginDay
= This
->triggerCond
.wBeginDay
;
212 pTrigger
->wEndYear
= This
->triggerCond
.wEndYear
;
213 pTrigger
->wEndMonth
= This
->triggerCond
.wEndMonth
;
214 pTrigger
->wEndDay
= This
->triggerCond
.wEndDay
;
215 pTrigger
->wStartHour
= This
->triggerCond
.wStartHour
;
216 pTrigger
->wStartMinute
= This
->triggerCond
.wStartMinute
;
217 pTrigger
->MinutesDuration
= This
->triggerCond
.MinutesDuration
;
218 pTrigger
->MinutesInterval
= This
->triggerCond
.MinutesInterval
;
219 pTrigger
->rgFlags
= This
->triggerCond
.rgFlags
;
220 pTrigger
->TriggerType
= This
->triggerCond
.TriggerType
;
221 switch (This
->triggerCond
.TriggerType
)
223 case TASK_TIME_TRIGGER_DAILY
:
224 pTrigger
->Type
.Daily
.DaysInterval
=
225 This
->triggerCond
.Type
.Daily
.DaysInterval
;
227 case TASK_TIME_TRIGGER_WEEKLY
:
228 pTrigger
->Type
.Weekly
.WeeksInterval
=
229 This
->triggerCond
.Type
.Weekly
.WeeksInterval
;
230 pTrigger
->Type
.Weekly
.rgfDaysOfTheWeek
=
231 This
->triggerCond
.Type
.Weekly
.rgfDaysOfTheWeek
;
233 case TASK_TIME_TRIGGER_MONTHLYDATE
:
234 pTrigger
->Type
.MonthlyDate
.rgfDays
=
235 This
->triggerCond
.Type
.MonthlyDate
.rgfDays
;
236 pTrigger
->Type
.MonthlyDate
.rgfMonths
=
237 This
->triggerCond
.Type
.MonthlyDate
.rgfMonths
;
239 case TASK_TIME_TRIGGER_MONTHLYDOW
:
240 pTrigger
->Type
.MonthlyDOW
.wWhichWeek
=
241 This
->triggerCond
.Type
.MonthlyDOW
.wWhichWeek
;
242 pTrigger
->Type
.MonthlyDOW
.rgfDaysOfTheWeek
=
243 This
->triggerCond
.Type
.MonthlyDOW
.rgfDaysOfTheWeek
;
244 pTrigger
->Type
.MonthlyDOW
.rgfMonths
=
245 This
->triggerCond
.Type
.MonthlyDOW
.rgfMonths
;
247 case TASK_TIME_TRIGGER_ONCE
:
248 case TASK_EVENT_TRIGGER_ON_IDLE
:
249 case TASK_EVENT_TRIGGER_AT_SYSTEMSTART
:
250 case TASK_EVENT_TRIGGER_AT_LOGON
:
254 pTrigger
->Reserved2
= 0;
255 pTrigger
->wRandomMinutesInterval
= 0;
259 static HRESULT WINAPI
MSTASK_ITaskTrigger_GetTriggerString(
261 LPWSTR
*ppwszTrigger
)
263 FIXME("Not implemented\n");
267 static const ITaskTriggerVtbl MSTASK_ITaskTriggerVtbl
=
269 MSTASK_ITaskTrigger_QueryInterface
,
270 MSTASK_ITaskTrigger_AddRef
,
271 MSTASK_ITaskTrigger_Release
,
272 MSTASK_ITaskTrigger_SetTrigger
,
273 MSTASK_ITaskTrigger_GetTrigger
,
274 MSTASK_ITaskTrigger_GetTriggerString
277 HRESULT
TaskTriggerConstructor(LPVOID
*ppObj
)
279 TaskTriggerImpl
*This
;
281 TRACE("(%p)\n", ppObj
);
283 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
285 return E_OUTOFMEMORY
;
287 This
->ITaskTrigger_iface
.lpVtbl
= &MSTASK_ITaskTriggerVtbl
;
290 /* Most fields of triggerCond default to zero. Initialize other
291 * fields to default values. */
292 memset(&This
->triggerCond
, 0, sizeof(TASK_TRIGGER
));
294 This
->triggerCond
.cbTriggerSize
= sizeof(This
->triggerCond
);
295 This
->triggerCond
.wBeginYear
= time
.wYear
;
296 This
->triggerCond
.wBeginMonth
= time
.wMonth
;
297 This
->triggerCond
.wBeginDay
= time
.wDay
;
298 This
->triggerCond
.wStartHour
= time
.wHour
;
299 This
->triggerCond
.wStartMinute
= time
.wMinute
;
300 This
->triggerCond
.rgFlags
= TASK_TRIGGER_FLAG_DISABLED
;
301 This
->triggerCond
.TriggerType
= TASK_TIME_TRIGGER_DAILY
,
302 This
->triggerCond
.Type
.Daily
.DaysInterval
= 1;
304 *ppObj
= &This
->ITaskTrigger_iface
;
305 InterlockedIncrement(&dll_ref
);