oleaut32: Fix a typo in a documentation comment.
[wine.git] / dlls / mstask / task_trigger.c
blob307a60540b5ce61d114786eb1265d93b87080adc
1 /*
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
19 #include <stdarg.h>
20 #include "winternl.h"
21 #include "mstask_private.h"
22 #include "wine/debug.h"
24 WINE_DEFAULT_DEBUG_CHANNEL(mstask);
26 typedef struct
28 ITaskTrigger ITaskTrigger_iface;
29 LONG ref;
30 TASK_TRIGGER triggerCond;
31 } TaskTriggerImpl;
33 static inline TaskTriggerImpl *impl_from_ITaskTrigger(ITaskTrigger *iface)
35 return CONTAINING_RECORD(iface, TaskTriggerImpl, ITaskTrigger_iface);
38 static HRESULT WINAPI MSTASK_ITaskTrigger_QueryInterface(
39 ITaskTrigger* iface,
40 REFIID riid,
41 void **ppvObject)
43 TaskTriggerImpl *This = impl_from_ITaskTrigger(iface);
45 TRACE("IID: %s\n", debugstr_guid(riid));
46 if (ppvObject == NULL)
47 return E_POINTER;
49 if (IsEqualGUID(riid, &IID_IUnknown) ||
50 IsEqualGUID(riid, &IID_ITaskTrigger))
52 *ppvObject = &This->ITaskTrigger_iface;
53 ITaskTrigger_AddRef(iface);
54 return S_OK;
57 WARN("Unknown interface: %s\n", debugstr_guid(riid));
58 *ppvObject = NULL;
59 return E_NOINTERFACE;
62 static ULONG WINAPI MSTASK_ITaskTrigger_AddRef(
63 ITaskTrigger* iface)
65 TaskTriggerImpl *This = impl_from_ITaskTrigger(iface);
66 ULONG ref;
67 TRACE("\n");
68 ref = InterlockedIncrement(&This->ref);
69 return ref;
72 static ULONG WINAPI MSTASK_ITaskTrigger_Release(
73 ITaskTrigger* iface)
75 TaskTriggerImpl *This = impl_from_ITaskTrigger(iface);
76 ULONG ref;
77 TRACE("\n");
78 ref = InterlockedDecrement(&This->ref);
79 if (ref == 0)
81 HeapFree(GetProcessHeap(), 0, This);
82 InterlockedDecrement(&dll_ref);
84 return ref;
87 static HRESULT WINAPI MSTASK_ITaskTrigger_SetTrigger(
88 ITaskTrigger* iface,
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))
100 return E_INVALIDARG;
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))
114 return E_INVALIDARG;
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))
129 return E_INVALIDARG;
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)
140 return E_INVALIDARG;
141 if (pTrigger->MinutesDuration > 0 && pTrigger->MinutesInterval == 0)
142 return E_INVALIDARG;
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;
156 break;
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;
162 break;
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;
168 break;
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;
176 break;
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:
181 default:
182 tmp_trigger_cond.Type = This->triggerCond.Type;
183 break;
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;
195 return S_OK;
198 static HRESULT WINAPI MSTASK_ITaskTrigger_GetTrigger(
199 ITaskTrigger* iface,
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;
228 break;
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;
234 break;
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;
240 break;
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;
248 break;
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:
253 default:
254 break;
256 pTrigger->Reserved2 = 0;
257 pTrigger->wRandomMinutesInterval = 0;
258 return S_OK;
261 static HRESULT WINAPI MSTASK_ITaskTrigger_GetTriggerString(
262 ITaskTrigger* iface,
263 LPWSTR *ppwszTrigger)
265 FIXME("Not implemented\n");
266 return E_NOTIMPL;
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;
282 SYSTEMTIME time;
283 TRACE("(%p)\n", ppObj);
285 This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
286 if (!This)
287 return E_OUTOFMEMORY;
289 This->ITaskTrigger_iface.lpVtbl = &MSTASK_ITaskTriggerVtbl;
290 This->ref = 1;
292 /* Most fields of triggerCond default to zero. Initialize other
293 * fields to default values. */
294 memset(&This->triggerCond, 0, sizeof(TASK_TRIGGER));
295 GetLocalTime(&time);
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);
308 return S_OK;