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 if (pTrigger
->MinutesDuration
> 0 && pTrigger
->MinutesInterval
== 0)
143 tmp_trigger_cond
.MinutesDuration
= pTrigger
->MinutesDuration
;
144 tmp_trigger_cond
.MinutesInterval
= pTrigger
->MinutesInterval
;
146 /* Copy over flags */
147 tmp_trigger_cond
.rgFlags
= pTrigger
->rgFlags
;
149 /* Set TriggerType dependent fields of Type union */
150 tmp_trigger_cond
.TriggerType
= pTrigger
->TriggerType
;
151 switch (pTrigger
->TriggerType
)
153 case TASK_TIME_TRIGGER_DAILY
:
154 tmp_trigger_cond
.Type
.Daily
.DaysInterval
=
155 pTrigger
->Type
.Daily
.DaysInterval
;
157 case TASK_TIME_TRIGGER_WEEKLY
:
158 tmp_trigger_cond
.Type
.Weekly
.WeeksInterval
=
159 pTrigger
->Type
.Weekly
.WeeksInterval
;
160 tmp_trigger_cond
.Type
.Weekly
.rgfDaysOfTheWeek
=
161 pTrigger
->Type
.Weekly
.rgfDaysOfTheWeek
;
163 case TASK_TIME_TRIGGER_MONTHLYDATE
:
164 tmp_trigger_cond
.Type
.MonthlyDate
.rgfDays
=
165 pTrigger
->Type
.MonthlyDate
.rgfDays
;
166 tmp_trigger_cond
.Type
.MonthlyDate
.rgfMonths
=
167 pTrigger
->Type
.MonthlyDate
.rgfMonths
;
169 case TASK_TIME_TRIGGER_MONTHLYDOW
:
170 tmp_trigger_cond
.Type
.MonthlyDOW
.wWhichWeek
=
171 pTrigger
->Type
.MonthlyDOW
.wWhichWeek
;
172 tmp_trigger_cond
.Type
.MonthlyDOW
.rgfDaysOfTheWeek
=
173 pTrigger
->Type
.MonthlyDOW
.rgfDaysOfTheWeek
;
174 tmp_trigger_cond
.Type
.MonthlyDOW
.rgfMonths
=
175 pTrigger
->Type
.MonthlyDOW
.rgfMonths
;
177 case TASK_TIME_TRIGGER_ONCE
:
178 case TASK_EVENT_TRIGGER_ON_IDLE
:
179 case TASK_EVENT_TRIGGER_AT_SYSTEMSTART
:
180 case TASK_EVENT_TRIGGER_AT_LOGON
:
182 tmp_trigger_cond
.Type
= This
->triggerCond
.Type
;
186 /* Reserved field must be zero */
187 tmp_trigger_cond
.Reserved2
= 0;
189 /* wRandomMinutesInterval not currently used and is initialized to zero */
190 tmp_trigger_cond
.wRandomMinutesInterval
= 0;
192 /* Update object copy of triggerCond */
193 This
->triggerCond
= tmp_trigger_cond
;
198 static HRESULT WINAPI
MSTASK_ITaskTrigger_GetTrigger(
200 PTASK_TRIGGER pTrigger
)
202 TaskTriggerImpl
* This
= impl_from_ITaskTrigger(iface
);
204 TRACE("(%p, %p)\n", iface
, pTrigger
);
206 /* Native implementation doesn't verify equivalent cbTriggerSize fields */
208 /* Copy relevant fields of the structure */
209 pTrigger
->cbTriggerSize
= This
->triggerCond
.cbTriggerSize
;
210 pTrigger
->Reserved1
= 0;
211 pTrigger
->wBeginYear
= This
->triggerCond
.wBeginYear
;
212 pTrigger
->wBeginMonth
= This
->triggerCond
.wBeginMonth
;
213 pTrigger
->wBeginDay
= This
->triggerCond
.wBeginDay
;
214 pTrigger
->wEndYear
= This
->triggerCond
.wEndYear
;
215 pTrigger
->wEndMonth
= This
->triggerCond
.wEndMonth
;
216 pTrigger
->wEndDay
= This
->triggerCond
.wEndDay
;
217 pTrigger
->wStartHour
= This
->triggerCond
.wStartHour
;
218 pTrigger
->wStartMinute
= This
->triggerCond
.wStartMinute
;
219 pTrigger
->MinutesDuration
= This
->triggerCond
.MinutesDuration
;
220 pTrigger
->MinutesInterval
= This
->triggerCond
.MinutesInterval
;
221 pTrigger
->rgFlags
= This
->triggerCond
.rgFlags
;
222 pTrigger
->TriggerType
= This
->triggerCond
.TriggerType
;
223 switch (This
->triggerCond
.TriggerType
)
225 case TASK_TIME_TRIGGER_DAILY
:
226 pTrigger
->Type
.Daily
.DaysInterval
=
227 This
->triggerCond
.Type
.Daily
.DaysInterval
;
229 case TASK_TIME_TRIGGER_WEEKLY
:
230 pTrigger
->Type
.Weekly
.WeeksInterval
=
231 This
->triggerCond
.Type
.Weekly
.WeeksInterval
;
232 pTrigger
->Type
.Weekly
.rgfDaysOfTheWeek
=
233 This
->triggerCond
.Type
.Weekly
.rgfDaysOfTheWeek
;
235 case TASK_TIME_TRIGGER_MONTHLYDATE
:
236 pTrigger
->Type
.MonthlyDate
.rgfDays
=
237 This
->triggerCond
.Type
.MonthlyDate
.rgfDays
;
238 pTrigger
->Type
.MonthlyDate
.rgfMonths
=
239 This
->triggerCond
.Type
.MonthlyDate
.rgfMonths
;
241 case TASK_TIME_TRIGGER_MONTHLYDOW
:
242 pTrigger
->Type
.MonthlyDOW
.wWhichWeek
=
243 This
->triggerCond
.Type
.MonthlyDOW
.wWhichWeek
;
244 pTrigger
->Type
.MonthlyDOW
.rgfDaysOfTheWeek
=
245 This
->triggerCond
.Type
.MonthlyDOW
.rgfDaysOfTheWeek
;
246 pTrigger
->Type
.MonthlyDOW
.rgfMonths
=
247 This
->triggerCond
.Type
.MonthlyDOW
.rgfMonths
;
249 case TASK_TIME_TRIGGER_ONCE
:
250 case TASK_EVENT_TRIGGER_ON_IDLE
:
251 case TASK_EVENT_TRIGGER_AT_SYSTEMSTART
:
252 case TASK_EVENT_TRIGGER_AT_LOGON
:
256 pTrigger
->Reserved2
= 0;
257 pTrigger
->wRandomMinutesInterval
= 0;
261 static HRESULT WINAPI
MSTASK_ITaskTrigger_GetTriggerString(
263 LPWSTR
*ppwszTrigger
)
265 FIXME("Not implemented\n");
269 static const ITaskTriggerVtbl MSTASK_ITaskTriggerVtbl
=
271 MSTASK_ITaskTrigger_QueryInterface
,
272 MSTASK_ITaskTrigger_AddRef
,
273 MSTASK_ITaskTrigger_Release
,
274 MSTASK_ITaskTrigger_SetTrigger
,
275 MSTASK_ITaskTrigger_GetTrigger
,
276 MSTASK_ITaskTrigger_GetTriggerString
279 HRESULT
TaskTriggerConstructor(LPVOID
*ppObj
)
281 TaskTriggerImpl
*This
;
283 TRACE("(%p)\n", ppObj
);
285 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
287 return E_OUTOFMEMORY
;
289 This
->ITaskTrigger_iface
.lpVtbl
= &MSTASK_ITaskTriggerVtbl
;
292 /* Most fields of triggerCond default to zero. Initialize other
293 * fields to default values. */
294 memset(&This
->triggerCond
, 0, sizeof(TASK_TRIGGER
));
296 This
->triggerCond
.cbTriggerSize
= sizeof(This
->triggerCond
);
297 This
->triggerCond
.wBeginYear
= time
.wYear
;
298 This
->triggerCond
.wBeginMonth
= time
.wMonth
;
299 This
->triggerCond
.wBeginDay
= time
.wDay
;
300 This
->triggerCond
.wStartHour
= time
.wHour
;
301 This
->triggerCond
.wStartMinute
= time
.wMinute
;
302 This
->triggerCond
.rgFlags
= TASK_TRIGGER_FLAG_DISABLED
;
303 This
->triggerCond
.TriggerType
= TASK_TIME_TRIGGER_DAILY
,
304 This
->triggerCond
.Type
.Daily
.DaysInterval
= 1;
306 *ppObj
= &This
->ITaskTrigger_iface
;
307 InterlockedIncrement(&dll_ref
);