gdi32: Pre-allocate the points array in CreatePolyPolygonRgn.
[wine.git] / dlls / mstask / task_trigger.c
blob56bfbed54f854e922dbf18522e634d597e003e67
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>
21 #define COBJMACROS
23 #include "windef.h"
24 #include "winbase.h"
25 #include "objbase.h"
26 #include "winternl.h"
27 #include "taskschd.h"
28 #include "mstask.h"
29 #include "mstask_private.h"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(mstask);
34 typedef struct
36 ITaskTrigger ITaskTrigger_iface;
37 LONG ref;
38 TASK_TRIGGER triggerCond;
39 } TaskTriggerImpl;
41 static inline TaskTriggerImpl *impl_from_ITaskTrigger(ITaskTrigger *iface)
43 return CONTAINING_RECORD(iface, TaskTriggerImpl, ITaskTrigger_iface);
46 static HRESULT WINAPI MSTASK_ITaskTrigger_QueryInterface(
47 ITaskTrigger* iface,
48 REFIID riid,
49 void **ppvObject)
51 TaskTriggerImpl *This = impl_from_ITaskTrigger(iface);
53 TRACE("IID: %s\n", debugstr_guid(riid));
54 if (ppvObject == NULL)
55 return E_POINTER;
57 if (IsEqualGUID(riid, &IID_IUnknown) ||
58 IsEqualGUID(riid, &IID_ITaskTrigger))
60 *ppvObject = &This->ITaskTrigger_iface;
61 ITaskTrigger_AddRef(iface);
62 return S_OK;
65 WARN("Unknown interface: %s\n", debugstr_guid(riid));
66 *ppvObject = NULL;
67 return E_NOINTERFACE;
70 static ULONG WINAPI MSTASK_ITaskTrigger_AddRef(
71 ITaskTrigger* iface)
73 TaskTriggerImpl *This = impl_from_ITaskTrigger(iface);
74 ULONG ref;
75 TRACE("\n");
76 ref = InterlockedIncrement(&This->ref);
77 return ref;
80 static ULONG WINAPI MSTASK_ITaskTrigger_Release(
81 ITaskTrigger* iface)
83 TaskTriggerImpl *This = impl_from_ITaskTrigger(iface);
84 ULONG ref;
85 TRACE("\n");
86 ref = InterlockedDecrement(&This->ref);
87 if (ref == 0)
89 HeapFree(GetProcessHeap(), 0, This);
90 InterlockedDecrement(&dll_ref);
92 return ref;
95 static HRESULT WINAPI MSTASK_ITaskTrigger_SetTrigger(
96 ITaskTrigger* iface,
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))
108 return E_INVALIDARG;
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))
122 return E_INVALIDARG;
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))
137 return E_INVALIDARG;
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)
148 return E_INVALIDARG;
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;
162 break;
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;
168 break;
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;
174 break;
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;
182 break;
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:
187 default:
188 tmp_trigger_cond.Type = This->triggerCond.Type;
189 break;
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;
201 return S_OK;
204 static HRESULT WINAPI MSTASK_ITaskTrigger_GetTrigger(
205 ITaskTrigger* iface,
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;
234 break;
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;
240 break;
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;
246 break;
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;
254 break;
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:
259 default:
260 break;
262 pTrigger->Reserved2 = 0;
263 pTrigger->wRandomMinutesInterval = 0;
264 return S_OK;
267 static HRESULT WINAPI MSTASK_ITaskTrigger_GetTriggerString(
268 ITaskTrigger* iface,
269 LPWSTR *ppwszTrigger)
271 FIXME("Not implemented\n");
272 return E_NOTIMPL;
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;
288 SYSTEMTIME time;
289 TRACE("(%p)\n", ppObj);
291 This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
292 if (!This)
293 return E_OUTOFMEMORY;
295 This->ITaskTrigger_iface.lpVtbl = &MSTASK_ITaskTriggerVtbl;
296 This->ref = 1;
298 /* Most fields of triggerCond default to zero. Initialize other
299 * fields to default values. */
300 memset(&This->triggerCond, 0, sizeof(TASK_TRIGGER));
301 GetLocalTime(&time);
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);
314 return S_OK;