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
29 #include "mstask_private.h"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(mstask
);
36 ITaskTrigger ITaskTrigger_iface
;
38 TASK_TRIGGER triggerCond
;
41 static inline TaskTriggerImpl
*impl_from_ITaskTrigger(ITaskTrigger
*iface
)
43 return CONTAINING_RECORD(iface
, TaskTriggerImpl
, ITaskTrigger_iface
);
46 static HRESULT WINAPI
MSTASK_ITaskTrigger_QueryInterface(
51 TaskTriggerImpl
*This
= impl_from_ITaskTrigger(iface
);
53 TRACE("IID: %s\n", debugstr_guid(riid
));
54 if (ppvObject
== NULL
)
57 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
58 IsEqualGUID(riid
, &IID_ITaskTrigger
))
60 *ppvObject
= &This
->ITaskTrigger_iface
;
61 ITaskTrigger_AddRef(iface
);
65 WARN("Unknown interface: %s\n", debugstr_guid(riid
));
70 static ULONG WINAPI
MSTASK_ITaskTrigger_AddRef(
73 TaskTriggerImpl
*This
= impl_from_ITaskTrigger(iface
);
76 ref
= InterlockedIncrement(&This
->ref
);
80 static ULONG WINAPI
MSTASK_ITaskTrigger_Release(
83 TaskTriggerImpl
*This
= impl_from_ITaskTrigger(iface
);
86 ref
= InterlockedDecrement(&This
->ref
);
89 HeapFree(GetProcessHeap(), 0, This
);
90 InterlockedDecrement(&dll_ref
);
95 static HRESULT WINAPI
MSTASK_ITaskTrigger_SetTrigger(
97 const PTASK_TRIGGER pTrigger
)
99 TaskTriggerImpl
* This
= impl_from_ITaskTrigger(iface
);
100 TIME_FIELDS field_time
;
101 LARGE_INTEGER sys_time
;
102 TASK_TRIGGER tmp_trigger_cond
;
104 TRACE("(%p, %p)\n", iface
, pTrigger
);
106 /* Verify valid structure size */
107 if (pTrigger
->cbTriggerSize
!= sizeof(*pTrigger
))
109 tmp_trigger_cond
.cbTriggerSize
= pTrigger
->cbTriggerSize
;
111 /* Reserved field must be zero */
112 tmp_trigger_cond
.Reserved1
= 0;
114 /* Verify and set valid start date and time */
115 memset(&field_time
, 0, sizeof(field_time
));
116 field_time
.Year
= pTrigger
->wBeginYear
;
117 field_time
.Month
= pTrigger
->wBeginMonth
;
118 field_time
.Day
= pTrigger
->wBeginDay
;
119 field_time
.Hour
= pTrigger
->wStartHour
;
120 field_time
.Minute
= pTrigger
->wStartMinute
;
121 if (!RtlTimeFieldsToTime(&field_time
, &sys_time
))
123 tmp_trigger_cond
.wBeginYear
= pTrigger
->wBeginYear
;
124 tmp_trigger_cond
.wBeginMonth
= pTrigger
->wBeginMonth
;
125 tmp_trigger_cond
.wBeginDay
= pTrigger
->wBeginDay
;
126 tmp_trigger_cond
.wStartHour
= pTrigger
->wStartHour
;
127 tmp_trigger_cond
.wStartMinute
= pTrigger
->wStartMinute
;
129 /* Verify valid end date if TASK_TRIGGER_FLAG_HAS_END_DATE flag is set */
130 if (pTrigger
->rgFlags
& TASK_TRIGGER_FLAG_HAS_END_DATE
)
132 memset(&field_time
, 0, sizeof(field_time
));
133 field_time
.Year
= pTrigger
->wEndYear
;
134 field_time
.Month
= pTrigger
->wEndMonth
;
135 field_time
.Day
= pTrigger
->wEndDay
;
136 if (!RtlTimeFieldsToTime(&field_time
, &sys_time
))
140 /* Set valid end date independent of TASK_TRIGGER_FLAG_HAS_END_DATE flag */
141 tmp_trigger_cond
.wEndYear
= pTrigger
->wEndYear
;
142 tmp_trigger_cond
.wEndMonth
= pTrigger
->wEndMonth
;
143 tmp_trigger_cond
.wEndDay
= pTrigger
->wEndDay
;
145 /* Verify duration and interval pair */
146 if (pTrigger
->MinutesDuration
<= pTrigger
->MinutesInterval
&&
147 pTrigger
->MinutesInterval
> 0)
149 tmp_trigger_cond
.MinutesDuration
= pTrigger
->MinutesDuration
;
150 tmp_trigger_cond
.MinutesInterval
= pTrigger
->MinutesInterval
;
152 /* Copy over flags */
153 tmp_trigger_cond
.rgFlags
= pTrigger
->rgFlags
;
155 /* Set TriggerType dependent fields of Type union */
156 tmp_trigger_cond
.TriggerType
= pTrigger
->TriggerType
;
157 switch (pTrigger
->TriggerType
)
159 case TASK_TIME_TRIGGER_DAILY
:
160 tmp_trigger_cond
.Type
.Daily
.DaysInterval
=
161 pTrigger
->Type
.Daily
.DaysInterval
;
163 case TASK_TIME_TRIGGER_WEEKLY
:
164 tmp_trigger_cond
.Type
.Weekly
.WeeksInterval
=
165 pTrigger
->Type
.Weekly
.WeeksInterval
;
166 tmp_trigger_cond
.Type
.Weekly
.rgfDaysOfTheWeek
=
167 pTrigger
->Type
.Weekly
.rgfDaysOfTheWeek
;
169 case TASK_TIME_TRIGGER_MONTHLYDATE
:
170 tmp_trigger_cond
.Type
.MonthlyDate
.rgfDays
=
171 pTrigger
->Type
.MonthlyDate
.rgfDays
;
172 tmp_trigger_cond
.Type
.MonthlyDate
.rgfMonths
=
173 pTrigger
->Type
.MonthlyDate
.rgfMonths
;
175 case TASK_TIME_TRIGGER_MONTHLYDOW
:
176 tmp_trigger_cond
.Type
.MonthlyDOW
.wWhichWeek
=
177 pTrigger
->Type
.MonthlyDOW
.wWhichWeek
;
178 tmp_trigger_cond
.Type
.MonthlyDOW
.rgfDaysOfTheWeek
=
179 pTrigger
->Type
.MonthlyDOW
.rgfDaysOfTheWeek
;
180 tmp_trigger_cond
.Type
.MonthlyDOW
.rgfMonths
=
181 pTrigger
->Type
.MonthlyDOW
.rgfMonths
;
183 case TASK_TIME_TRIGGER_ONCE
:
184 case TASK_EVENT_TRIGGER_ON_IDLE
:
185 case TASK_EVENT_TRIGGER_AT_SYSTEMSTART
:
186 case TASK_EVENT_TRIGGER_AT_LOGON
:
188 tmp_trigger_cond
.Type
= This
->triggerCond
.Type
;
192 /* Reserved field must be zero */
193 tmp_trigger_cond
.Reserved2
= 0;
195 /* wRandomMinutesInterval not currently used and is initialized to zero */
196 tmp_trigger_cond
.wRandomMinutesInterval
= 0;
198 /* Update object copy of triggerCond */
199 This
->triggerCond
= tmp_trigger_cond
;
204 static HRESULT WINAPI
MSTASK_ITaskTrigger_GetTrigger(
206 PTASK_TRIGGER pTrigger
)
208 TaskTriggerImpl
* This
= impl_from_ITaskTrigger(iface
);
210 TRACE("(%p, %p)\n", iface
, pTrigger
);
212 /* Native implementation doesn't verify equivalent cbTriggerSize fields */
214 /* Copy relevant fields of the structure */
215 pTrigger
->cbTriggerSize
= This
->triggerCond
.cbTriggerSize
;
216 pTrigger
->Reserved1
= 0;
217 pTrigger
->wBeginYear
= This
->triggerCond
.wBeginYear
;
218 pTrigger
->wBeginMonth
= This
->triggerCond
.wBeginMonth
;
219 pTrigger
->wBeginDay
= This
->triggerCond
.wBeginDay
;
220 pTrigger
->wEndYear
= This
->triggerCond
.wEndYear
;
221 pTrigger
->wEndMonth
= This
->triggerCond
.wEndMonth
;
222 pTrigger
->wEndDay
= This
->triggerCond
.wEndDay
;
223 pTrigger
->wStartHour
= This
->triggerCond
.wStartHour
;
224 pTrigger
->wStartMinute
= This
->triggerCond
.wStartMinute
;
225 pTrigger
->MinutesDuration
= This
->triggerCond
.MinutesDuration
;
226 pTrigger
->MinutesInterval
= This
->triggerCond
.MinutesInterval
;
227 pTrigger
->rgFlags
= This
->triggerCond
.rgFlags
;
228 pTrigger
->TriggerType
= This
->triggerCond
.TriggerType
;
229 switch (This
->triggerCond
.TriggerType
)
231 case TASK_TIME_TRIGGER_DAILY
:
232 pTrigger
->Type
.Daily
.DaysInterval
=
233 This
->triggerCond
.Type
.Daily
.DaysInterval
;
235 case TASK_TIME_TRIGGER_WEEKLY
:
236 pTrigger
->Type
.Weekly
.WeeksInterval
=
237 This
->triggerCond
.Type
.Weekly
.WeeksInterval
;
238 pTrigger
->Type
.Weekly
.rgfDaysOfTheWeek
=
239 This
->triggerCond
.Type
.Weekly
.rgfDaysOfTheWeek
;
241 case TASK_TIME_TRIGGER_MONTHLYDATE
:
242 pTrigger
->Type
.MonthlyDate
.rgfDays
=
243 This
->triggerCond
.Type
.MonthlyDate
.rgfDays
;
244 pTrigger
->Type
.MonthlyDate
.rgfMonths
=
245 This
->triggerCond
.Type
.MonthlyDate
.rgfMonths
;
247 case TASK_TIME_TRIGGER_MONTHLYDOW
:
248 pTrigger
->Type
.MonthlyDOW
.wWhichWeek
=
249 This
->triggerCond
.Type
.MonthlyDOW
.wWhichWeek
;
250 pTrigger
->Type
.MonthlyDOW
.rgfDaysOfTheWeek
=
251 This
->triggerCond
.Type
.MonthlyDOW
.rgfDaysOfTheWeek
;
252 pTrigger
->Type
.MonthlyDOW
.rgfMonths
=
253 This
->triggerCond
.Type
.MonthlyDOW
.rgfMonths
;
255 case TASK_TIME_TRIGGER_ONCE
:
256 case TASK_EVENT_TRIGGER_ON_IDLE
:
257 case TASK_EVENT_TRIGGER_AT_SYSTEMSTART
:
258 case TASK_EVENT_TRIGGER_AT_LOGON
:
262 pTrigger
->Reserved2
= 0;
263 pTrigger
->wRandomMinutesInterval
= 0;
267 static HRESULT WINAPI
MSTASK_ITaskTrigger_GetTriggerString(
269 LPWSTR
*ppwszTrigger
)
271 FIXME("Not implemented\n");
275 static const ITaskTriggerVtbl MSTASK_ITaskTriggerVtbl
=
277 MSTASK_ITaskTrigger_QueryInterface
,
278 MSTASK_ITaskTrigger_AddRef
,
279 MSTASK_ITaskTrigger_Release
,
280 MSTASK_ITaskTrigger_SetTrigger
,
281 MSTASK_ITaskTrigger_GetTrigger
,
282 MSTASK_ITaskTrigger_GetTriggerString
285 HRESULT
TaskTriggerConstructor(LPVOID
*ppObj
)
287 TaskTriggerImpl
*This
;
289 TRACE("(%p)\n", ppObj
);
291 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
293 return E_OUTOFMEMORY
;
295 This
->ITaskTrigger_iface
.lpVtbl
= &MSTASK_ITaskTriggerVtbl
;
298 /* Most fields of triggerCond default to zero. Initialize other
299 * fields to default values. */
300 memset(&This
->triggerCond
, 0, sizeof(TASK_TRIGGER
));
302 This
->triggerCond
.cbTriggerSize
= sizeof(This
->triggerCond
);
303 This
->triggerCond
.wBeginYear
= time
.wYear
;
304 This
->triggerCond
.wBeginMonth
= time
.wMonth
;
305 This
->triggerCond
.wBeginDay
= time
.wDay
;
306 This
->triggerCond
.wStartHour
= time
.wHour
;
307 This
->triggerCond
.wStartMinute
= time
.wMinute
;
308 This
->triggerCond
.rgFlags
= TASK_TRIGGER_FLAG_DISABLED
;
309 This
->triggerCond
.TriggerType
= TASK_TIME_TRIGGER_DAILY
,
310 This
->triggerCond
.Type
.Daily
.DaysInterval
= 1;
312 *ppObj
= &This
->ITaskTrigger_iface
;
313 InterlockedIncrement(&dll_ref
);